@rudderhq/cli 0.3.4-canary.12 → 0.3.4-canary.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -11023,12 +11023,327 @@ var AGENT_CLI_CAPABILITIES = [
11023
11023
  requiresAgentId: false,
11024
11024
  requiresRunId: false,
11025
11025
  attachesRunIdWhenAvailable: true
11026
+ },
11027
+ {
11028
+ id: "automation.list",
11029
+ command: "rudder automation list --org-id <id>",
11030
+ category: "automation",
11031
+ description: "List automations for an organization with compact local filters.",
11032
+ mutating: false,
11033
+ contract: "agent-v1",
11034
+ requiresOrgId: true,
11035
+ requiresAgentId: false,
11036
+ requiresRunId: false,
11037
+ attachesRunIdWhenAvailable: false
11038
+ },
11039
+ {
11040
+ id: "automation.get",
11041
+ command: "rudder automation get <automation-id>",
11042
+ category: "automation",
11043
+ description: "Read one automation detail including triggers and recent runs.",
11044
+ mutating: false,
11045
+ contract: "agent-v1",
11046
+ requiresOrgId: false,
11047
+ requiresAgentId: false,
11048
+ requiresRunId: false,
11049
+ attachesRunIdWhenAvailable: false
11050
+ },
11051
+ {
11052
+ id: "automation.runs",
11053
+ command: "rudder automation runs <automation-id>",
11054
+ category: "automation",
11055
+ description: "List recent runs for one automation.",
11056
+ mutating: false,
11057
+ contract: "agent-v1",
11058
+ requiresOrgId: false,
11059
+ requiresAgentId: false,
11060
+ requiresRunId: false,
11061
+ attachesRunIdWhenAvailable: false
11062
+ },
11063
+ {
11064
+ id: "automation.triggers.list",
11065
+ command: "rudder automation triggers list <automation-id>",
11066
+ category: "automation",
11067
+ description: "List triggers configured for one automation.",
11068
+ mutating: false,
11069
+ contract: "agent-v1",
11070
+ requiresOrgId: false,
11071
+ requiresAgentId: false,
11072
+ requiresRunId: false,
11073
+ attachesRunIdWhenAvailable: false
11074
+ },
11075
+ {
11076
+ id: "automation.create",
11077
+ command: "rudder automation create --org-id <id> --title <title> --assignee-agent-id <id>",
11078
+ category: "automation",
11079
+ description: "Create an automation through the governed automation API.",
11080
+ mutating: true,
11081
+ contract: "agent-v1",
11082
+ requiresOrgId: true,
11083
+ requiresAgentId: false,
11084
+ requiresRunId: false,
11085
+ attachesRunIdWhenAvailable: true
11086
+ },
11087
+ {
11088
+ id: "automation.update",
11089
+ command: "rudder automation update <automation-id>",
11090
+ category: "automation",
11091
+ description: "Update automation fields through the governed automation API.",
11092
+ mutating: true,
11093
+ contract: "agent-v1",
11094
+ requiresOrgId: false,
11095
+ requiresAgentId: false,
11096
+ requiresRunId: false,
11097
+ attachesRunIdWhenAvailable: true
11098
+ },
11099
+ {
11100
+ id: "automation.enable",
11101
+ command: "rudder automation enable <automation-id>",
11102
+ category: "automation",
11103
+ description: "Enable an automation by setting status to active.",
11104
+ mutating: true,
11105
+ contract: "agent-v1",
11106
+ requiresOrgId: false,
11107
+ requiresAgentId: false,
11108
+ requiresRunId: false,
11109
+ attachesRunIdWhenAvailable: true
11110
+ },
11111
+ {
11112
+ id: "automation.disable",
11113
+ command: "rudder automation disable <automation-id>",
11114
+ category: "automation",
11115
+ description: "Disable an automation by setting status to paused.",
11116
+ mutating: true,
11117
+ contract: "agent-v1",
11118
+ requiresOrgId: false,
11119
+ requiresAgentId: false,
11120
+ requiresRunId: false,
11121
+ attachesRunIdWhenAvailable: true
11122
+ },
11123
+ {
11124
+ id: "automation.run",
11125
+ command: "rudder automation run <automation-id>",
11126
+ category: "automation",
11127
+ description: "Trigger a manual automation run.",
11128
+ mutating: true,
11129
+ contract: "agent-v1",
11130
+ requiresOrgId: false,
11131
+ requiresAgentId: false,
11132
+ requiresRunId: false,
11133
+ attachesRunIdWhenAvailable: true
11134
+ },
11135
+ {
11136
+ id: "chat.list",
11137
+ command: "rudder chat list --org-id <id>",
11138
+ category: "chat",
11139
+ description: "List chat conversations without dumping full message history.",
11140
+ mutating: false,
11141
+ contract: "agent-v1",
11142
+ requiresOrgId: true,
11143
+ requiresAgentId: false,
11144
+ requiresRunId: false,
11145
+ attachesRunIdWhenAvailable: false
11146
+ },
11147
+ {
11148
+ id: "chat.search",
11149
+ command: "rudder chat search <query> --org-id <id>",
11150
+ category: "chat",
11151
+ description: "Search chats with bounded snippets and optional scope filtering.",
11152
+ mutating: false,
11153
+ contract: "agent-v1",
11154
+ requiresOrgId: true,
11155
+ requiresAgentId: false,
11156
+ requiresRunId: false,
11157
+ attachesRunIdWhenAvailable: false
11158
+ },
11159
+ {
11160
+ id: "chat.get",
11161
+ command: "rudder chat get <chat-id>",
11162
+ category: "chat",
11163
+ description: "Read one chat conversation record.",
11164
+ mutating: false,
11165
+ contract: "agent-v1",
11166
+ requiresOrgId: false,
11167
+ requiresAgentId: false,
11168
+ requiresRunId: false,
11169
+ attachesRunIdWhenAvailable: false
11170
+ },
11171
+ {
11172
+ id: "chat.messages",
11173
+ command: "rudder chat messages <chat-id> [--limit <n>] [--cursor <cursor>] [--include-transcript]",
11174
+ category: "chat",
11175
+ description: "Read bounded chat messages with page cursors; transcript output is omitted unless requested.",
11176
+ mutating: false,
11177
+ contract: "agent-v1",
11178
+ requiresOrgId: false,
11179
+ requiresAgentId: false,
11180
+ requiresRunId: false,
11181
+ attachesRunIdWhenAvailable: false
11182
+ },
11183
+ {
11184
+ id: "chat.transcript",
11185
+ command: "rudder chat transcript <chat-id> [--limit <n>] [--cursor <cursor>] [--max-output-chars <n>]",
11186
+ category: "chat",
11187
+ description: "Read paginated chat messages with assistant transcript entries clipped in human output.",
11188
+ mutating: false,
11189
+ contract: "agent-v1",
11190
+ requiresOrgId: false,
11191
+ requiresAgentId: false,
11192
+ requiresRunId: false,
11193
+ attachesRunIdWhenAvailable: false
11194
+ },
11195
+ {
11196
+ id: "chat.read",
11197
+ command: "rudder chat read <chat-id> [--turn-limit <n>] [--cursor <cursor>] [--include-output]",
11198
+ category: "chat",
11199
+ description: "Read a bounded recent-message snapshot for one chat with page cursors.",
11200
+ mutating: false,
11201
+ contract: "agent-v1",
11202
+ requiresOrgId: false,
11203
+ requiresAgentId: false,
11204
+ requiresRunId: false,
11205
+ attachesRunIdWhenAvailable: false
11206
+ },
11207
+ {
11208
+ id: "chat.create",
11209
+ command: "rudder chat create --org-id <id>",
11210
+ category: "chat",
11211
+ description: "Create a chat conversation.",
11212
+ mutating: true,
11213
+ contract: "agent-v1",
11214
+ requiresOrgId: true,
11215
+ requiresAgentId: false,
11216
+ requiresRunId: false,
11217
+ attachesRunIdWhenAvailable: true
11218
+ },
11219
+ {
11220
+ id: "chat.send",
11221
+ command: "rudder chat send <chat-id> --body <text>",
11222
+ category: "chat",
11223
+ description: "Send a chat message and persist the assistant reply through the server.",
11224
+ mutating: true,
11225
+ contract: "agent-v1",
11226
+ requiresOrgId: false,
11227
+ requiresAgentId: false,
11228
+ requiresRunId: false,
11229
+ attachesRunIdWhenAvailable: true
11230
+ },
11231
+ {
11232
+ id: "chat.archive",
11233
+ command: "rudder chat archive <chat-id>",
11234
+ category: "chat",
11235
+ description: "Archive a chat conversation without deleting it.",
11236
+ mutating: true,
11237
+ contract: "agent-v1",
11238
+ requiresOrgId: false,
11239
+ requiresAgentId: false,
11240
+ requiresRunId: false,
11241
+ attachesRunIdWhenAvailable: true
11242
+ },
11243
+ {
11244
+ id: "runs.list",
11245
+ command: "rudder runs list --org-id <id>",
11246
+ category: "runs",
11247
+ description: "List observed agent runs with filters for status, agent, issue, runtime, and time.",
11248
+ mutating: false,
11249
+ contract: "agent-v1",
11250
+ requiresOrgId: true,
11251
+ requiresAgentId: false,
11252
+ requiresRunId: false,
11253
+ attachesRunIdWhenAvailable: false
11254
+ },
11255
+ {
11256
+ id: "runs.get",
11257
+ command: "rudder runs get <run-id>",
11258
+ category: "runs",
11259
+ description: "Read one observed run detail.",
11260
+ mutating: false,
11261
+ contract: "agent-v1",
11262
+ requiresOrgId: false,
11263
+ requiresAgentId: false,
11264
+ requiresRunId: false,
11265
+ attachesRunIdWhenAvailable: false
11266
+ },
11267
+ {
11268
+ id: "runs.events",
11269
+ command: "rudder runs events <run-id>",
11270
+ category: "runs",
11271
+ description: "List persisted run events.",
11272
+ mutating: false,
11273
+ contract: "agent-v1",
11274
+ requiresOrgId: false,
11275
+ requiresAgentId: false,
11276
+ requiresRunId: false,
11277
+ attachesRunIdWhenAvailable: false
11278
+ },
11279
+ {
11280
+ id: "runs.log",
11281
+ command: "rudder runs log <run-id>",
11282
+ category: "runs",
11283
+ description: "Read stored run log content with clipped human output.",
11284
+ mutating: false,
11285
+ contract: "agent-v1",
11286
+ requiresOrgId: false,
11287
+ requiresAgentId: false,
11288
+ requiresRunId: false,
11289
+ attachesRunIdWhenAvailable: false
11290
+ },
11291
+ {
11292
+ id: "runs.transcript",
11293
+ command: "rudder runs transcript <run-id> [--turn-limit <n>] [--cursor <cursor>] [--include-output]",
11294
+ category: "runs",
11295
+ description: "Read the server-normalized run transcript; human output is compact and JSON includes full entries.",
11296
+ mutating: false,
11297
+ contract: "agent-v1",
11298
+ requiresOrgId: false,
11299
+ requiresAgentId: false,
11300
+ requiresRunId: false,
11301
+ attachesRunIdWhenAvailable: false
11302
+ },
11303
+ {
11304
+ id: "runs.errors",
11305
+ command: "rudder runs errors <run-id>",
11306
+ category: "runs",
11307
+ description: "List failed tool calls, stderr, runtime failures, and jump-to-context commands.",
11308
+ mutating: false,
11309
+ contract: "agent-v1",
11310
+ requiresOrgId: false,
11311
+ requiresAgentId: false,
11312
+ requiresRunId: false,
11313
+ attachesRunIdWhenAvailable: false
11314
+ },
11315
+ {
11316
+ id: "runs.cancel",
11317
+ command: "rudder runs cancel <run-id>",
11318
+ category: "runs",
11319
+ description: "Cancel a heartbeat run through the governed server route.",
11320
+ mutating: true,
11321
+ contract: "agent-v1",
11322
+ requiresOrgId: false,
11323
+ requiresAgentId: false,
11324
+ requiresRunId: false,
11325
+ attachesRunIdWhenAvailable: true
11326
+ },
11327
+ {
11328
+ id: "runs.retry",
11329
+ command: "rudder runs retry <run-id>",
11330
+ category: "runs",
11331
+ description: "Retry a failed, timed out, or cancelled run through the governed server route.",
11332
+ mutating: true,
11333
+ contract: "agent-v1",
11334
+ requiresOrgId: false,
11335
+ requiresAgentId: false,
11336
+ requiresRunId: false,
11337
+ attachesRunIdWhenAvailable: true
11026
11338
  }
11027
11339
  ];
11028
11340
  var CATEGORY_TITLES = {
11029
11341
  agent: "Agent",
11030
11342
  issue: "Issue",
11031
11343
  project: "Project",
11344
+ automation: "Automation",
11345
+ chat: "Chat",
11346
+ runs: "Runs",
11032
11347
  approval: "Approval",
11033
11348
  skill: "Skill",
11034
11349
  library: "Library"
@@ -12917,6 +13232,664 @@ async function readStdinText3() {
12917
13232
  return Buffer.concat(chunks).toString("utf8");
12918
13233
  }
12919
13234
 
13235
+ // src/commands/client/automation.ts
13236
+ init_dist();
13237
+ function registerAutomationCommands(program) {
13238
+ const automation = program.command("automation").description("Automation operations");
13239
+ addCommonClientOptions(
13240
+ automation.command("list").description(getAgentCliCapabilityById("automation.list").description).option("-O, --org-id <id>", "Organization ID").option("--status <status>", "Filter by automation status").option("--assignee-agent-id <id>", "Filter by assignee agent ID").option("--project-id <id>", "Filter by project ID").option("--output-mode <mode>", "Filter by output mode").action(async (opts) => {
13241
+ try {
13242
+ const ctx = resolveCommandContext(opts, { requireCompany: true });
13243
+ const rows = await ctx.api.get(`/api/orgs/${ctx.orgId}/automations`) ?? [];
13244
+ const filtered = rows.filter(
13245
+ (row) => (!opts.status || row.status === opts.status) && (!opts.assigneeAgentId || row.assigneeAgentId === opts.assigneeAgentId) && (!opts.projectId || row.projectId === opts.projectId) && (!opts.outputMode || row.outputMode === opts.outputMode)
13246
+ );
13247
+ printOutput(ctx.json ? filtered : filtered.map(formatAutomationListItem), { json: ctx.json });
13248
+ } catch (err) {
13249
+ handleCommandError(err);
13250
+ }
13251
+ }),
13252
+ { includeCompany: false }
13253
+ );
13254
+ addCommonClientOptions(
13255
+ automation.command("get").description(getAgentCliCapabilityById("automation.get").description).argument("<automationId>", "Automation ID").action(async (automationId, opts) => {
13256
+ try {
13257
+ const ctx = resolveCommandContext(opts);
13258
+ const row = await ctx.api.get(`/api/automations/${encodeURIComponent(automationId)}`);
13259
+ printOutput(row, { json: ctx.json });
13260
+ } catch (err) {
13261
+ handleCommandError(err);
13262
+ }
13263
+ })
13264
+ );
13265
+ addCommonClientOptions(
13266
+ automation.command("runs").description(getAgentCliCapabilityById("automation.runs").description).argument("<automationId>", "Automation ID").option("--limit <n>", "Maximum runs to return", "50").action(async (automationId, opts) => {
13267
+ try {
13268
+ const ctx = resolveCommandContext(opts);
13269
+ const params = new URLSearchParams();
13270
+ if (opts.limit) params.set("limit", opts.limit);
13271
+ const rows = await ctx.api.get(
13272
+ `/api/automations/${encodeURIComponent(automationId)}/runs?${params.toString()}`
13273
+ ) ?? [];
13274
+ printOutput(ctx.json ? rows : rows.map(formatAutomationRun), { json: ctx.json });
13275
+ } catch (err) {
13276
+ handleCommandError(err);
13277
+ }
13278
+ })
13279
+ );
13280
+ addCommonClientOptions(
13281
+ automation.command("triggers").description("Automation trigger operations").command("list").description(getAgentCliCapabilityById("automation.triggers.list").description).argument("<automationId>", "Automation ID").action(async (automationId, opts) => {
13282
+ try {
13283
+ const ctx = resolveCommandContext(opts);
13284
+ const row = await ctx.api.get(`/api/automations/${encodeURIComponent(automationId)}`);
13285
+ const triggers = row?.triggers ?? [];
13286
+ printOutput(triggers, { json: ctx.json });
13287
+ } catch (err) {
13288
+ handleCommandError(err);
13289
+ }
13290
+ })
13291
+ );
13292
+ addCommonClientOptions(
13293
+ automation.command("create").description(getAgentCliCapabilityById("automation.create").description).option("-O, --org-id <id>", "Organization ID").option("--payload <json>", "Raw automation create payload JSON").option("--title <title>", "Automation title").option("--description <text>", "Automation description").option("--assignee-agent-id <id>", "Assignee agent ID").option("--project-id <id>", "Project ID").option("--goal-id <id>", "Goal ID").option("--parent-issue-id <id>", "Parent issue ID").option("--priority <priority>", "Issue priority for tracked output").option("--status <status>", "Automation status").option("--output-mode <mode>", "Automation output mode").option("--concurrency-policy <policy>", "Automation concurrency policy").option("--catch-up-policy <policy>", "Automation catch-up policy").option("--notify-on-issue-created", "Notify when tracked issue output is created").action(async (opts) => {
13294
+ try {
13295
+ const ctx = resolveCommandContext(opts, { requireCompany: true });
13296
+ const payload = createAutomationSchema.parse(buildAutomationPayload(opts));
13297
+ const created = await ctx.api.post(`/api/orgs/${ctx.orgId}/automations`, payload);
13298
+ printOutput(created, { json: ctx.json });
13299
+ } catch (err) {
13300
+ handleCommandError(err);
13301
+ }
13302
+ }),
13303
+ { includeCompany: false }
13304
+ );
13305
+ addCommonClientOptions(
13306
+ automation.command("update").description(getAgentCliCapabilityById("automation.update").description).argument("<automationId>", "Automation ID").option("--payload <json>", "Raw automation update payload JSON").option("--title <title>", "Automation title").option("--description <text>", "Automation description").option("--assignee-agent-id <id>", "Assignee agent ID").option("--project-id <id>", "Project ID").option("--goal-id <id>", "Goal ID").option("--parent-issue-id <id>", "Parent issue ID").option("--priority <priority>", "Issue priority for tracked output").option("--status <status>", "Automation status").option("--output-mode <mode>", "Automation output mode").option("--concurrency-policy <policy>", "Automation concurrency policy").option("--catch-up-policy <policy>", "Automation catch-up policy").option("--notify-on-issue-created", "Notify when tracked issue output is created").action(async (automationId, opts) => {
13307
+ try {
13308
+ const ctx = resolveCommandContext(opts);
13309
+ const payload = updateAutomationSchema.parse(buildAutomationPayload(opts));
13310
+ const updated = await ctx.api.patch(`/api/automations/${encodeURIComponent(automationId)}`, payload);
13311
+ printOutput(updated, { json: ctx.json });
13312
+ } catch (err) {
13313
+ handleCommandError(err);
13314
+ }
13315
+ })
13316
+ );
13317
+ addCommonClientOptions(
13318
+ automation.command("enable").description(getAgentCliCapabilityById("automation.enable").description).argument("<automationId>", "Automation ID").action(async (automationId, opts) => {
13319
+ try {
13320
+ const ctx = resolveCommandContext(opts);
13321
+ const updated = await ctx.api.patch(`/api/automations/${encodeURIComponent(automationId)}`, {
13322
+ status: "active"
13323
+ });
13324
+ printOutput(updated, { json: ctx.json });
13325
+ } catch (err) {
13326
+ handleCommandError(err);
13327
+ }
13328
+ })
13329
+ );
13330
+ addCommonClientOptions(
13331
+ automation.command("disable").description(getAgentCliCapabilityById("automation.disable").description).argument("<automationId>", "Automation ID").action(async (automationId, opts) => {
13332
+ try {
13333
+ const ctx = resolveCommandContext(opts);
13334
+ const updated = await ctx.api.patch(`/api/automations/${encodeURIComponent(automationId)}`, {
13335
+ status: "paused"
13336
+ });
13337
+ printOutput(updated, { json: ctx.json });
13338
+ } catch (err) {
13339
+ handleCommandError(err);
13340
+ }
13341
+ })
13342
+ );
13343
+ addCommonClientOptions(
13344
+ automation.command("run").description(getAgentCliCapabilityById("automation.run").description).argument("<automationId>", "Automation ID").option("--trigger-id <id>", "Trigger ID").option("--payload <json>", "Manual run payload JSON").option("--idempotency-key <key>", "Idempotency key").option("--source <source>", "Run source", "manual").action(async (automationId, opts) => {
13345
+ try {
13346
+ const ctx = resolveCommandContext(opts);
13347
+ const payload = runAutomationSchema.parse({
13348
+ triggerId: opts.triggerId,
13349
+ payload: opts.payload ? parseJsonOption(opts.payload, "--payload") : void 0,
13350
+ idempotencyKey: opts.idempotencyKey,
13351
+ source: opts.source
13352
+ });
13353
+ const run = await ctx.api.post(`/api/automations/${encodeURIComponent(automationId)}/run`, payload);
13354
+ printOutput(run, { json: ctx.json });
13355
+ } catch (err) {
13356
+ handleCommandError(err);
13357
+ }
13358
+ })
13359
+ );
13360
+ }
13361
+ function buildAutomationPayload(opts) {
13362
+ return {
13363
+ ...parseJsonObjectOption(opts.payload, "--payload"),
13364
+ ...definedRecord({
13365
+ title: opts.title,
13366
+ description: opts.description,
13367
+ assigneeAgentId: opts.assigneeAgentId,
13368
+ projectId: opts.projectId,
13369
+ goalId: opts.goalId,
13370
+ parentIssueId: opts.parentIssueId,
13371
+ priority: opts.priority,
13372
+ status: opts.status,
13373
+ outputMode: opts.outputMode,
13374
+ concurrencyPolicy: opts.concurrencyPolicy,
13375
+ catchUpPolicy: opts.catchUpPolicy,
13376
+ notifyOnIssueCreated: opts.notifyOnIssueCreated
13377
+ })
13378
+ };
13379
+ }
13380
+ function definedRecord(record) {
13381
+ return Object.fromEntries(Object.entries(record).filter(([, value]) => value !== void 0));
13382
+ }
13383
+ function parseJsonOption(value, label) {
13384
+ try {
13385
+ return JSON.parse(value);
13386
+ } catch (error) {
13387
+ throw new Error(`${label} must be valid JSON`);
13388
+ }
13389
+ }
13390
+ function parseJsonObjectOption(value, label) {
13391
+ if (!value) return {};
13392
+ const parsed = parseJsonOption(value, label);
13393
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
13394
+ throw new Error(`${label} must be a JSON object`);
13395
+ }
13396
+ return parsed;
13397
+ }
13398
+ function formatAutomationListItem(row) {
13399
+ const nextRunAt = row.triggers.map((trigger) => trigger.nextRunAt).filter(Boolean).sort()[0] ?? null;
13400
+ return {
13401
+ id: row.id,
13402
+ title: row.title,
13403
+ status: row.status,
13404
+ assigneeAgentId: row.assigneeAgentId,
13405
+ outputMode: row.outputMode,
13406
+ lastRun: row.lastRun?.status ?? "-",
13407
+ nextRunAt
13408
+ };
13409
+ }
13410
+ function formatAutomationRun(row) {
13411
+ return {
13412
+ id: row.id,
13413
+ status: row.status,
13414
+ source: row.source,
13415
+ triggeredAt: row.triggeredAt,
13416
+ linkedIssue: row.linkedIssue?.identifier ?? row.linkedIssueId ?? "-",
13417
+ linkedChatConversationId: row.linkedChatConversationId ?? "-",
13418
+ failureReason: row.failureReason ?? "-"
13419
+ };
13420
+ }
13421
+
13422
+ // src/commands/client/chat.ts
13423
+ init_dist();
13424
+ function registerChatCommands(program) {
13425
+ const chat = program.command("chat").description("Chat operations");
13426
+ addCommonClientOptions(
13427
+ chat.command("list").description(getAgentCliCapabilityById("chat.list").description).option("-O, --org-id <id>", "Organization ID").option("--status <status>", "active, resolved, archived, or all", "active").option("--query <text>", "Server-side chat search query").option("--limit <n>", "Maximum rows to print").action(async (opts) => {
13428
+ try {
13429
+ const ctx = resolveCommandContext(opts, { requireCompany: true });
13430
+ const rows = await listChats(ctx, opts);
13431
+ printOutput(ctx.json ? rows : rows.map(formatChatConversation), { json: ctx.json });
13432
+ } catch (err) {
13433
+ handleCommandError(err);
13434
+ }
13435
+ }),
13436
+ { includeCompany: false }
13437
+ );
13438
+ addCommonClientOptions(
13439
+ chat.command("search").description(getAgentCliCapabilityById("chat.search").description).argument("<query>", "Search query").option("-O, --org-id <id>", "Organization ID").option("--status <status>", "active, resolved, archived, or all", "all").option("--scope <scope>", "Search scope: all, title, summary, messages", "all").option("--limit <n>", "Maximum rows to print", "20").option("--snippet-chars <n>", "Maximum snippet characters", "220").action(async (query, opts) => {
13440
+ try {
13441
+ const ctx = resolveCommandContext(opts, { requireCompany: true });
13442
+ const rows = await listChats(ctx, { ...opts, query });
13443
+ const filtered = filterChatSearchRows(rows, query, opts.scope ?? "all").slice(0, parseLimit(opts.limit, rows.length));
13444
+ const snippetChars = parseLimit(opts.snippetChars, 220);
13445
+ printOutput(
13446
+ ctx.json ? filtered : filtered.map((row) => formatChatSearchResult(row, snippetChars)),
13447
+ { json: ctx.json }
13448
+ );
13449
+ } catch (err) {
13450
+ handleCommandError(err);
13451
+ }
13452
+ }),
13453
+ { includeCompany: false }
13454
+ );
13455
+ addCommonClientOptions(
13456
+ chat.command("get").description(getAgentCliCapabilityById("chat.get").description).argument("<chatId>", "Chat conversation ID").action(async (chatId, opts) => {
13457
+ try {
13458
+ const ctx = resolveCommandContext(opts);
13459
+ const row = await ctx.api.get(`/api/chats/${encodeURIComponent(chatId)}`);
13460
+ printOutput(row, { json: ctx.json });
13461
+ } catch (err) {
13462
+ handleCommandError(err);
13463
+ }
13464
+ })
13465
+ );
13466
+ addCommonClientOptions(
13467
+ chat.command("messages").description(getAgentCliCapabilityById("chat.messages").description).argument("<chatId>", "Chat conversation ID").option("--include-transcript", "Include assistant transcript entries").option("--include-output", "Alias for --include-transcript").option("--include-outputs", "Alias for --include-transcript").option("--limit <n>", "Maximum messages to print").option("--cursor <cursor>", "Stable message cursor returned in page.nextCursor").option("--max-output-chars <n>", "Maximum transcript output chars for human output", "1200").action(async (chatId, opts) => {
13468
+ try {
13469
+ const ctx = resolveCommandContext(opts);
13470
+ const page = await getChatMessagesPage(ctx, chatId, {
13471
+ includeTranscript: includesChatTranscript(opts),
13472
+ limit: opts.limit,
13473
+ cursor: opts.cursor
13474
+ });
13475
+ printOutput(
13476
+ ctx.json ? page : page.messages.map((message) => formatChatMessage(message, parseLimit(opts.maxOutputChars, 1200))),
13477
+ { json: ctx.json }
13478
+ );
13479
+ } catch (err) {
13480
+ handleCommandError(err);
13481
+ }
13482
+ })
13483
+ );
13484
+ addCommonClientOptions(
13485
+ chat.command("transcript").description(getAgentCliCapabilityById("chat.transcript").description).argument("<chatId>", "Chat conversation ID").option("--limit <n>", "Maximum messages to print").option("--cursor <cursor>", "Stable message cursor returned in page.nextCursor").option("--max-chars <n>", "Maximum transcript chars per message", "1200").option("--max-output-chars <n>", "Alias for --max-chars").action(async (chatId, opts) => {
13486
+ try {
13487
+ const ctx = resolveCommandContext(opts);
13488
+ const page = await getChatMessagesPage(ctx, chatId, {
13489
+ includeTranscript: true,
13490
+ limit: opts.limit,
13491
+ cursor: opts.cursor
13492
+ });
13493
+ const maxChars = parseLimit(opts.maxOutputChars ?? opts.maxChars, 1200);
13494
+ printOutput(
13495
+ ctx.json ? page : page.messages.flatMap((message) => formatChatTranscriptMessage(message, maxChars)),
13496
+ { json: ctx.json }
13497
+ );
13498
+ } catch (err) {
13499
+ handleCommandError(err);
13500
+ }
13501
+ })
13502
+ );
13503
+ addCommonClientOptions(
13504
+ chat.command("read").description(getAgentCliCapabilityById("chat.read").description).argument("<chatId>", "Chat conversation ID").option("--include-transcript", "Include assistant transcript entries").option("--include-output", "Alias for --include-transcript").option("--include-outputs", "Alias for --include-transcript").option("--limit <n>", "Maximum recent messages", "20").option("--turn-limit <n>", "Alias for --limit for chat turn snapshots").option("--cursor <cursor>", "Stable message cursor returned in page.nextCursor").option("--max-output-chars <n>", "Maximum transcript output chars for human output", "1200").action(async (chatId, opts) => {
13505
+ try {
13506
+ const ctx = resolveCommandContext(opts);
13507
+ const [conversation, page] = await Promise.all([
13508
+ ctx.api.get(`/api/chats/${encodeURIComponent(chatId)}`),
13509
+ getChatMessagesPage(ctx, chatId, {
13510
+ includeTranscript: includesChatTranscript(opts),
13511
+ limit: opts.turnLimit ?? opts.limit,
13512
+ cursor: opts.cursor
13513
+ })
13514
+ ]);
13515
+ const payload = {
13516
+ conversation,
13517
+ messages: page.messages,
13518
+ page: page.page
13519
+ };
13520
+ printOutput(
13521
+ ctx.json ? payload : page.messages.map((message) => formatChatMessage(message, parseLimit(opts.maxOutputChars, 1200))),
13522
+ { json: ctx.json }
13523
+ );
13524
+ } catch (err) {
13525
+ handleCommandError(err);
13526
+ }
13527
+ })
13528
+ );
13529
+ addCommonClientOptions(
13530
+ chat.command("create").description(getAgentCliCapabilityById("chat.create").description).option("-O, --org-id <id>", "Organization ID").option("--payload <json>", "Raw chat create payload JSON").option("--title <title>", "Chat title").option("--summary <text>", "Chat summary").option("--preferred-agent-id <id>", "Preferred agent ID").option("--issue-creation-mode <mode>", "Issue creation mode").option("--plan-mode", "Create a plan-mode chat").action(async (opts) => {
13531
+ try {
13532
+ const ctx = resolveCommandContext(opts, { requireCompany: true });
13533
+ const payload = createChatConversationSchema.parse({
13534
+ ...parseJsonObjectOption2(opts.payload, "--payload"),
13535
+ ...definedRecord2({
13536
+ title: opts.title,
13537
+ summary: opts.summary,
13538
+ preferredAgentId: opts.preferredAgentId,
13539
+ issueCreationMode: opts.issueCreationMode,
13540
+ planMode: opts.planMode
13541
+ })
13542
+ });
13543
+ const created = await ctx.api.post(`/api/orgs/${ctx.orgId}/chats`, payload);
13544
+ printOutput(created, { json: ctx.json });
13545
+ } catch (err) {
13546
+ handleCommandError(err);
13547
+ }
13548
+ }),
13549
+ { includeCompany: false }
13550
+ );
13551
+ addCommonClientOptions(
13552
+ chat.command("send").description(getAgentCliCapabilityById("chat.send").description).argument("<chatId>", "Chat conversation ID").option("--body <text>", "Message body").option("--edit-user-message-id <id>", "Regenerate/edit from a prior user message").action(async (chatId, opts) => {
13553
+ try {
13554
+ const ctx = resolveCommandContext(opts);
13555
+ const body = opts.body ?? await readStdin();
13556
+ const payload = addChatMessageSchema.parse({
13557
+ body,
13558
+ editUserMessageId: opts.editUserMessageId
13559
+ });
13560
+ const result = await ctx.api.post(`/api/chats/${encodeURIComponent(chatId)}/messages`, payload);
13561
+ printOutput(result, { json: ctx.json });
13562
+ } catch (err) {
13563
+ handleCommandError(err);
13564
+ }
13565
+ })
13566
+ );
13567
+ addCommonClientOptions(
13568
+ chat.command("archive").description(getAgentCliCapabilityById("chat.archive").description).argument("<chatId>", "Chat conversation ID").action(async (chatId, opts) => {
13569
+ try {
13570
+ const ctx = resolveCommandContext(opts);
13571
+ const payload = updateChatConversationSchema.parse({ status: "archived" });
13572
+ const updated = await ctx.api.patch(`/api/chats/${encodeURIComponent(chatId)}`, payload);
13573
+ printOutput(updated, { json: ctx.json });
13574
+ } catch (err) {
13575
+ handleCommandError(err);
13576
+ }
13577
+ })
13578
+ );
13579
+ }
13580
+ async function listChats(ctx, opts) {
13581
+ const params = new URLSearchParams();
13582
+ if (opts.status) params.set("status", opts.status);
13583
+ if (opts.query) params.set("q", opts.query);
13584
+ const rows = await ctx.api.get(`/api/orgs/${ctx.orgId}/chats?${params.toString()}`) ?? [];
13585
+ return rows.slice(0, parseLimit(opts.limit, rows.length));
13586
+ }
13587
+ async function getChatMessagesPage(ctx, chatId, opts) {
13588
+ const params = new URLSearchParams();
13589
+ params.set("envelope", "true");
13590
+ params.set("order", "newest");
13591
+ params.set("limit", String(parseLimit(opts.limit, 50)));
13592
+ if (opts.cursor) params.set("cursor", opts.cursor);
13593
+ if (opts.includeTranscript) params.set("includeTranscript", "true");
13594
+ const page = await ctx.api.get(`/api/chats/${encodeURIComponent(chatId)}/messages?${params.toString()}`);
13595
+ if (!page) {
13596
+ throw new Error("Chat messages response was empty");
13597
+ }
13598
+ return page;
13599
+ }
13600
+ function filterChatSearchRows(rows, query, scope) {
13601
+ const normalized = query.toLowerCase();
13602
+ if (scope === "all") return rows;
13603
+ return rows.filter((row) => {
13604
+ if (scope === "title") return row.title.toLowerCase().includes(normalized);
13605
+ if (scope === "summary") return Boolean(row.summary?.toLowerCase().includes(normalized));
13606
+ if (scope === "messages") return Boolean(row.searchPreview?.toLowerCase().includes(normalized));
13607
+ return true;
13608
+ });
13609
+ }
13610
+ function formatChatConversation(row) {
13611
+ return {
13612
+ id: row.id,
13613
+ title: row.title,
13614
+ status: row.status,
13615
+ preferredAgentId: row.preferredAgentId ?? "-",
13616
+ unread: row.unreadCount,
13617
+ lastMessageAt: row.lastMessageAt ?? "-",
13618
+ preview: row.latestReplyPreview ?? row.latestUserMessagePreview ?? "-"
13619
+ };
13620
+ }
13621
+ function formatChatSearchResult(row, maxChars) {
13622
+ return {
13623
+ id: row.id,
13624
+ title: row.title,
13625
+ status: row.status,
13626
+ lastMessageAt: row.lastMessageAt ?? "-",
13627
+ snippet: clip(row.searchPreview ?? row.latestReplyPreview ?? row.latestUserMessagePreview ?? row.summary ?? "", maxChars)
13628
+ };
13629
+ }
13630
+ function formatChatMessage(row, maxOutputChars = 1200) {
13631
+ return {
13632
+ id: row.id,
13633
+ role: row.role,
13634
+ kind: row.kind,
13635
+ status: row.status,
13636
+ createdAt: row.createdAt,
13637
+ body: clip(row.body, 220),
13638
+ transcriptEntries: row.transcriptSummary?.entryCount ?? row.transcript?.length ?? 0,
13639
+ ...row.transcript?.length ? { transcriptPreview: clip(row.transcript.map((entry) => formatTranscriptEntry(entry, maxOutputChars)).join(" "), maxOutputChars) } : {}
13640
+ };
13641
+ }
13642
+ function formatChatTranscriptMessage(row, maxChars) {
13643
+ const header = {
13644
+ id: row.id,
13645
+ role: row.role,
13646
+ kind: row.kind,
13647
+ status: row.status,
13648
+ createdAt: row.createdAt,
13649
+ body: clip(row.body, 220)
13650
+ };
13651
+ const transcriptRows = (row.transcript ?? []).map((entry, index) => ({
13652
+ id: `${row.id}:entry-${index + 1}`,
13653
+ messageId: row.id,
13654
+ role: row.role,
13655
+ entry: formatTranscriptEntry(entry, maxChars)
13656
+ }));
13657
+ return transcriptRows.length > 0 ? [header, ...transcriptRows] : [header];
13658
+ }
13659
+ function formatTranscriptEntry(entry, maxChars) {
13660
+ if (entry.kind === "tool_call") return `${entry.ts} tool_call ${entry.name} ${clip(JSON.stringify(entry.input), maxChars)}`;
13661
+ if (entry.kind === "tool_result") return `${entry.ts} tool_result ${entry.toolName ?? entry.toolUseId} ${entry.isError ? "ERROR " : ""}${clip(entry.content, maxChars)}`;
13662
+ if (entry.kind === "result") return `${entry.ts} result ${entry.isError ? "ERROR " : ""}${clip(entry.text || entry.errors.join("; "), maxChars)}`;
13663
+ if ("text" in entry) return `${entry.ts} ${entry.kind} ${clip(entry.text, maxChars)}`;
13664
+ return `${entry.ts} ${entry.kind}`;
13665
+ }
13666
+ function parseLimit(value, fallback) {
13667
+ const parsed = Number(value ?? fallback);
13668
+ if (!Number.isFinite(parsed) || parsed <= 0) return fallback;
13669
+ return Math.floor(parsed);
13670
+ }
13671
+ function includesChatTranscript(opts) {
13672
+ return Boolean(opts.includeTranscript || opts.includeOutput || opts.includeOutputs);
13673
+ }
13674
+ function clip(value, maxChars) {
13675
+ const text6 = value.replace(/\s+/g, " ").trim();
13676
+ if (text6.length <= maxChars) return text6;
13677
+ return `${text6.slice(0, Math.max(0, maxChars - 1))}\u2026`;
13678
+ }
13679
+ function parseJsonObjectOption2(value, label) {
13680
+ if (!value) return {};
13681
+ try {
13682
+ const parsed = JSON.parse(value);
13683
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
13684
+ throw new Error(`${label} must be a JSON object`);
13685
+ }
13686
+ return parsed;
13687
+ } catch (error) {
13688
+ if (error instanceof Error && error.message.includes("JSON object")) throw error;
13689
+ throw new Error(`${label} must be valid JSON`);
13690
+ }
13691
+ }
13692
+ function definedRecord2(record) {
13693
+ return Object.fromEntries(Object.entries(record).filter(([, value]) => value !== void 0));
13694
+ }
13695
+ async function readStdin() {
13696
+ const chunks = [];
13697
+ for await (const chunk of process.stdin) {
13698
+ chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
13699
+ }
13700
+ return Buffer.concat(chunks).toString("utf8");
13701
+ }
13702
+
13703
+ // src/commands/client/runs.ts
13704
+ function registerRunsCommands(program) {
13705
+ const runs = program.command("runs").description("Run debugging operations");
13706
+ addCommonClientOptions(
13707
+ runs.command("list").description(getAgentCliCapabilityById("runs.list").description).option("-O, --org-id <id>", "Organization ID").option("--updated-after <iso>", "Only runs updated after this timestamp").option("--run-id-prefix <prefix>", "Filter by run ID prefix").option("--agent-id <id>", "Filter by agent ID").option("--status <status>", "Filter by run status").option("--runtime <type>", "Filter by runtime type").option("--issue-id <id>", "Filter by linked issue ID").option("--created-before <iso>", "Only runs created before this timestamp").option("--limit <n>", "Maximum rows", "200").action(async (opts) => {
13708
+ try {
13709
+ const ctx = resolveCommandContext(opts, { requireCompany: true });
13710
+ const rows = await ctx.api.get(`/api/run-intelligence/orgs/${ctx.orgId}/runs?${buildRunsListQuery(opts)}`) ?? [];
13711
+ printOutput(ctx.json ? rows : rows.map(formatRunListRow), { json: ctx.json });
13712
+ } catch (err) {
13713
+ handleCommandError(err);
13714
+ }
13715
+ }),
13716
+ { includeCompany: false }
13717
+ );
13718
+ addCommonClientOptions(
13719
+ runs.command("get").description(getAgentCliCapabilityById("runs.get").description).argument("<runId>", "Run ID").action(async (runId, opts) => {
13720
+ try {
13721
+ const ctx = resolveCommandContext(opts);
13722
+ const row = await ctx.api.get(`/api/run-intelligence/runs/${encodeURIComponent(runId)}`);
13723
+ printOutput(row, { json: ctx.json });
13724
+ } catch (err) {
13725
+ handleCommandError(err);
13726
+ }
13727
+ })
13728
+ );
13729
+ addCommonClientOptions(
13730
+ runs.command("events").description(getAgentCliCapabilityById("runs.events").description).argument("<runId>", "Run ID").action(async (runId, opts) => {
13731
+ try {
13732
+ const ctx = resolveCommandContext(opts);
13733
+ const rows = await ctx.api.get(`/api/run-intelligence/runs/${encodeURIComponent(runId)}/events`) ?? [];
13734
+ printOutput(ctx.json ? rows : rows.map(formatRunEvent), { json: ctx.json });
13735
+ } catch (err) {
13736
+ handleCommandError(err);
13737
+ }
13738
+ })
13739
+ );
13740
+ addCommonClientOptions(
13741
+ runs.command("log").description(getAgentCliCapabilityById("runs.log").description).argument("<runId>", "Run ID").option("--max-chars <n>", "Maximum log characters for human output", "12000").action(async (runId, opts) => {
13742
+ try {
13743
+ const ctx = resolveCommandContext(opts);
13744
+ const row = await ctx.api.get(`/api/run-intelligence/runs/${encodeURIComponent(runId)}/log`);
13745
+ if (ctx.json) {
13746
+ printOutput(row, { json: true });
13747
+ } else {
13748
+ process.stdout.write(clip2(row?.content ?? "", parseLimit2(opts.maxChars, 12e3)) + "\n");
13749
+ }
13750
+ } catch (err) {
13751
+ handleCommandError(err);
13752
+ }
13753
+ })
13754
+ );
13755
+ addCommonClientOptions(
13756
+ runs.command("transcript").description(getAgentCliCapabilityById("runs.transcript").description).argument("<runId>", "Run ID").option("--errors-only", "Show only error transcript rows").option("--around-error <id>", "Show context around a run error id such as step-12").option("--context-turns <n>", "Turns around --around-error", "1").option("--cursor <cursor>", "Stable transcript cursor returned in page.nextCursor").option("--turn-limit <n>", "Maximum turns to return", "20").option("--chronological", "Show oldest-first instead of default newest-first").option("--narrative", "Use a narrative human layout").option("--max-chars <n>", "Maximum output characters per row", "1200").option("--max-output-chars <n>", "Alias for --max-chars").option("--include-output", "Include row output in compact human transcript rows").option("--include-outputs", "Alias for --include-output").action(async (runId, opts) => {
13757
+ try {
13758
+ const ctx = resolveCommandContext(opts);
13759
+ const payload = await ctx.api.get(
13760
+ `/api/run-intelligence/runs/${encodeURIComponent(runId)}/transcript?${buildTranscriptQuery(opts, { json: ctx.json })}`
13761
+ );
13762
+ if (ctx.json) {
13763
+ printOutput(payload, { json: true });
13764
+ } else if (opts.narrative) {
13765
+ printOutput((payload?.rows ?? []).map(formatRunTranscriptNarrative), { json: false });
13766
+ } else {
13767
+ printOutput((payload?.rows ?? []).map(formatRunTranscriptRow), { json: false });
13768
+ }
13769
+ } catch (err) {
13770
+ handleCommandError(err);
13771
+ }
13772
+ })
13773
+ );
13774
+ addCommonClientOptions(
13775
+ runs.command("errors").description(getAgentCliCapabilityById("runs.errors").description).argument("<runId>", "Run ID").option("--max-chars <n>", "Maximum output characters per error", "1200").action(async (runId, opts) => {
13776
+ try {
13777
+ const ctx = resolveCommandContext(opts);
13778
+ const params = new URLSearchParams();
13779
+ params.set("maxChars", String(parseLimit2(opts.maxChars, 1200)));
13780
+ const payload = await ctx.api.get(
13781
+ `/api/run-intelligence/runs/${encodeURIComponent(runId)}/errors?${params.toString()}`
13782
+ );
13783
+ printOutput(ctx.json ? payload : (payload?.errors ?? []).map(formatRunError), { json: ctx.json });
13784
+ } catch (err) {
13785
+ handleCommandError(err);
13786
+ }
13787
+ })
13788
+ );
13789
+ addCommonClientOptions(
13790
+ runs.command("cancel").description(getAgentCliCapabilityById("runs.cancel").description).argument("<runId>", "Run ID").action(async (runId, opts) => {
13791
+ try {
13792
+ const ctx = resolveCommandContext(opts);
13793
+ const row = await ctx.api.post(`/api/heartbeat-runs/${encodeURIComponent(runId)}/cancel`, {});
13794
+ printOutput(row, { json: ctx.json });
13795
+ } catch (err) {
13796
+ handleCommandError(err);
13797
+ }
13798
+ })
13799
+ );
13800
+ addCommonClientOptions(
13801
+ runs.command("retry").description(getAgentCliCapabilityById("runs.retry").description).argument("<runId>", "Run ID").action(async (runId, opts) => {
13802
+ try {
13803
+ const ctx = resolveCommandContext(opts);
13804
+ const row = await ctx.api.post(`/api/heartbeat-runs/${encodeURIComponent(runId)}/retry`, {});
13805
+ printOutput(row, { json: ctx.json });
13806
+ } catch (err) {
13807
+ handleCommandError(err);
13808
+ }
13809
+ })
13810
+ );
13811
+ }
13812
+ function buildRunsListQuery(opts) {
13813
+ const params = new URLSearchParams();
13814
+ if (opts.updatedAfter) params.set("updatedAfter", opts.updatedAfter);
13815
+ if (opts.runIdPrefix) params.set("runIdPrefix", opts.runIdPrefix);
13816
+ if (opts.agentId) params.set("agentId", opts.agentId);
13817
+ if (opts.status) params.set("status", opts.status);
13818
+ if (opts.runtime) params.set("runtime", opts.runtime);
13819
+ if (opts.issueId) params.set("issueId", opts.issueId);
13820
+ if (opts.createdBefore) params.set("createdBefore", opts.createdBefore);
13821
+ if (opts.limit) params.set("limit", opts.limit);
13822
+ return params.toString();
13823
+ }
13824
+ function buildTranscriptQuery(opts, output) {
13825
+ const params = new URLSearchParams();
13826
+ if (opts.errorsOnly) params.set("errorsOnly", "true");
13827
+ if (opts.aroundError) params.set("aroundError", opts.aroundError);
13828
+ if (opts.cursor) params.set("cursor", opts.cursor);
13829
+ if (opts.turnLimit) params.set("turnLimit", String(parseLimit2(opts.turnLimit, 20)));
13830
+ params.set("contextTurns", String(parseLimit2(opts.contextTurns, 1)));
13831
+ params.set("order", opts.chronological || opts.narrative ? "oldest" : "newest");
13832
+ params.set("output", output.json ? "full" : "compact");
13833
+ const includeOutputs = output.json || Boolean(opts.includeOutput || opts.includeOutputs || opts.narrative);
13834
+ params.set("includeOutputs", includeOutputs ? "true" : "false");
13835
+ params.set("maxChars", String(parseLimit2(opts.maxOutputChars ?? opts.maxChars, 1200)));
13836
+ return params.toString();
13837
+ }
13838
+ function formatRunListRow(row) {
13839
+ return {
13840
+ id: row.run.id,
13841
+ status: row.run.status,
13842
+ agent: row.agentName ?? row.run.agentId,
13843
+ runtime: row.bundle.agentRuntimeType,
13844
+ issue: row.issue?.identifier ?? row.issue?.id ?? "-",
13845
+ updatedAt: row.run.updatedAt
13846
+ };
13847
+ }
13848
+ function formatRunEvent(row) {
13849
+ return {
13850
+ seq: row.seq,
13851
+ level: row.level,
13852
+ stream: row.stream,
13853
+ message: row.message,
13854
+ createdAt: row.createdAt
13855
+ };
13856
+ }
13857
+ function formatRunTranscriptRow(row) {
13858
+ return {
13859
+ id: row.id,
13860
+ turn: row.turnIndex ?? "-",
13861
+ kind: row.kind,
13862
+ ts: row.ts,
13863
+ error: row.isError ? "yes" : "no",
13864
+ preview: row.preview || row.detailPreview,
13865
+ ...row.output ? { output: row.output.text } : {}
13866
+ };
13867
+ }
13868
+ function formatRunTranscriptNarrative(row) {
13869
+ const marker = row.isError ? "ERROR " : "";
13870
+ return `${row.id} ${row.ts} ${marker}${row.kind}: ${row.preview || row.detailPreview}${row.output ? `
13871
+ ${row.output.text}` : ""}`;
13872
+ }
13873
+ function formatRunError(row) {
13874
+ return {
13875
+ id: row.id,
13876
+ type: row.type,
13877
+ turn: row.turnIndex ?? "-",
13878
+ summary: row.summary,
13879
+ output: row.output.text,
13880
+ context: row.transcriptContext?.command ?? "-"
13881
+ };
13882
+ }
13883
+ function parseLimit2(value, fallback) {
13884
+ const parsed = Number(value ?? fallback);
13885
+ if (!Number.isFinite(parsed) || parsed <= 0) return fallback;
13886
+ return Math.floor(parsed);
13887
+ }
13888
+ function clip2(value, maxChars) {
13889
+ if (value.length <= maxChars) return value;
13890
+ return `${value.slice(0, Math.max(0, maxChars - 1))}\u2026`;
13891
+ }
13892
+
12920
13893
  // src/config/data-dir.ts
12921
13894
  init_home();
12922
13895
  import path21 from "node:path";
@@ -13297,6 +14270,9 @@ function createProgram() {
13297
14270
  registerDashboardCommands(program);
13298
14271
  registerSkillCommands(program);
13299
14272
  registerLibraryCommands(program);
14273
+ registerAutomationCommands(program);
14274
+ registerChatCommands(program);
14275
+ registerRunsCommands(program);
13300
14276
  registerLazyWorktreeCommands(program);
13301
14277
  registerPluginCommands(program);
13302
14278
  registerLazyBenchmarkCommands(program);