Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,14 @@ Format based on [Keep a Changelog](https://keepachangelog.com/). Versioning foll

## [Unreleased]

### Removed

- **`voicethere projects errors list`** — session failures are browsed via **`projects logs list --severity error`** (or `--level error`). Errors persist in agent logs with `fields.kind = session_error`, `fields.projectId`, `fields.sessionId`, and message prefix `[CODE]`.

### Changed

- **`projects logs list`** — documents `--severity` as alias for `--level`; E2E smokes assert session errors through this filter.

## [0.8.0] - 2026-08-03

### Added
Expand Down Expand Up @@ -85,7 +93,7 @@ Format based on [Keep a Changelog](https://keepachangelog.com/). Versioning foll

### Added

- **`voicethere projects logs list`** — list searchable customer agent logs for a project or `--session` (mirrors `projects errors list`).
- **`voicethere projects logs list`** — list searchable customer agent logs for a project or `--session` (filter session failures with `--severity error`).

## [0.3.15] - 2026-07-17

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,7 @@ Example: [`.voicethere/config.json.example`](./.voicethere/config.json.example)
| `projects conversation list [--q] [--json]` | Stored voice transcripts; `--q` searches turn text or session id |
| `projects conversation get <sessionId>` | Full turn timeline for one session |
| `projects conversation search <query>` | Alias for `conversation list --q` |
| `projects errors list [--session] [--json]` | Structured session errors from dashboard API |
| `projects logs list [--session] [--level\|--severity] [--q] [--json]` | Searchable agent logs; use `--severity error` for session failures (dual-written) |
| `projects voice catalog` | show STT/TTS vendors and models |
| `build list` | Builds for the active project |
| `build validate [file]` | Sandbox verify (default bundle from config) |
Expand Down
51 changes: 20 additions & 31 deletions src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ import { runProjectsSubscriptionShow } from "./commands/projects/subscription/sh
import { runProjectsUsageShow } from "./commands/projects/usage/show.js";
import { runProjectsSessionSettingsList } from "./commands/projects/session-settings/list.js";
import { runProjectsSessionSettingsSet } from "./commands/projects/session-settings/set.js";
import { runProjectsErrorsList } from "./commands/projects/errors/list.js";
import { runProjectsLogsList } from "./commands/projects/logs/list.js";
import {
runProjectsConversationExport,
Expand Down Expand Up @@ -561,45 +560,24 @@ async function main(): Promise<void> {
},
);

const errors = projects
.command("errors")
.description("List structured session errors for the active project");

errors
.command("list")
.description("List recent session errors (default: last 20 for project)")
.option("--project <id>", "Project UUID")
.option("--limit <n>", "Max rows when listing project errors", "20")
.option("--session <id>", "Filter to one orchestrator session id")
.option("--json", "Output JSON")
.action(
async (options: {
project?: string;
limit?: string;
session?: string;
json?: boolean;
}) => {
await runProjectsErrorsList({
projectId: options.project,
limit: options.limit ? Number.parseInt(options.limit, 10) : undefined,
sessionId: options.session,
json: options.json,
});
},
);

const logs = projects
.command("logs")
.description("List structured agent logs for the active project");

logs
.command("list")
.description("List recent agent logs (default: last 20 for project)")
.description(
"List recent agent logs (default: last 20 for project). Use --severity or --level to filter; --session scopes to one conversation.",
)
.option("--project <id>", "Project UUID")
.option("--limit <n>", "Max rows when listing project logs", "20")
.option("--session <id>", "Filter to one orchestrator session id")
.option("--session <id>", "Filter to one orchestrator session id (one conversation)")
.option("--q <text>", "Search log messages")
.option("--level <level>", "Filter by level (debug|info|warn|error)")
.option(
"--severity <level>",
"Filter by severity (debug|info|warn|error); alias for --level",
)
.option("--json", "Output JSON")
.action(
async (options: {
Expand All @@ -608,6 +586,7 @@ async function main(): Promise<void> {
session?: string;
q?: string;
level?: string;
severity?: string;
json?: boolean;
}) => {
await runProjectsLogsList({
Expand All @@ -616,7 +595,17 @@ async function main(): Promise<void> {
sessionId: options.session,
q: options.q,
level: options.level as
"debug" | "info" | "warn" | "error" | undefined,
| "debug"
| "info"
| "warn"
| "error"
| undefined,
severity: options.severity as
| "debug"
| "info"
| "warn"
| "error"
| undefined,
json: options.json,
});
},
Expand Down
124 changes: 0 additions & 124 deletions src/commands/projects/errors/list.test.ts

This file was deleted.

55 changes: 0 additions & 55 deletions src/commands/projects/errors/list.ts

This file was deleted.

52 changes: 52 additions & 0 deletions src/commands/projects/logs/list.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,58 @@ describe("runProjectsLogsList", () => {
});
});

it("passes --severity as level filter to the API", async () => {
listProjectLogs.mockResolvedValue({
project_id: "proj-1",
logs: [],
});

await runProjectsLogsList({
severity: "error",
});

expect(listProjectLogs).toHaveBeenCalledWith("proj-1", {
limit: 20,
level: "error",
});
});

it("prefers --level over --severity when both are set", async () => {
listProjectLogs.mockResolvedValue({
project_id: "proj-1",
logs: [],
});

await runProjectsLogsList({
level: "warn",
severity: "error",
});

expect(listProjectLogs).toHaveBeenCalledWith("proj-1", {
limit: 20,
level: "warn",
});
});

it("passes session-scoped logs with level filter", async () => {
listSessionLogs.mockResolvedValue({
project_id: "proj-1",
orchestrator_session_id: "orch-session-abc123",
logs: [],
});

await runProjectsLogsList({
sessionId: "orch-session-abc123",
level: "debug",
});

expect(listSessionLogs).toHaveBeenCalledWith(
"proj-1",
"orch-session-abc123",
{ limit: 20, level: "debug" },
);
});

it("outputs JSON when --json is set", async () => {
listSessionLogs.mockResolvedValue({
project_id: "proj-1",
Expand Down
7 changes: 5 additions & 2 deletions src/commands/projects/logs/list.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ export interface ProjectsLogsListOptions {
sessionId?: string;
q?: string;
level?: AgentLogLevel;
/** Alias for `level` (--severity on CLI). */
severity?: AgentLogLevel;
json?: boolean;
}

Expand All @@ -22,8 +24,9 @@ function buildQuery(options: ProjectsLogsListOptions): ListAgentLogsQuery {
if (options.q?.trim()) {
query.q = options.q.trim();
}
if (options.level) {
query.level = options.level;
const level = options.level ?? options.severity;
if (level) {
query.level = level;
}
return query;
}
Expand Down
Loading
Loading