@syntropic137/cli 0.19.6 → 0.20.0

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.
Files changed (2) hide show
  1. package/dist/syn.js +159 -181
  2. package/package.json +4 -2
package/dist/syn.js CHANGED
@@ -2,12 +2,13 @@
2
2
 
3
3
  // src/config.ts
4
4
  var CLI_NAME = "syn";
5
- var CLI_VERSION = "0.18.0";
6
5
  var CLI_DESCRIPTION = "Syntropic137 - Event-sourced workflow engine for AI agents";
6
+ var CLI_VERSION = true ? "0.20.0" : "0.0.0-dev";
7
7
  var DEFAULT_TIMEOUT_MS = 3e4;
8
8
  var SSE_CONNECT_TIMEOUT_MS = 5e3;
9
9
  function getApiUrl() {
10
- return process.env["SYN_API_URL"] ?? "http://localhost:8137";
10
+ const url = process.env["SYN_API_URL"] ?? "http://localhost:8137";
11
+ return url.replace(/\/api\/v1\/*$/, "");
11
12
  }
12
13
  function getAuthHeaders() {
13
14
  const token = process.env["SYN_API_TOKEN"];
@@ -68,6 +69,7 @@ function print(message) {
68
69
  }
69
70
 
70
71
  // src/client/http.ts
72
+ var API_PREFIX = "/api/v1";
71
73
  var SynClient = class {
72
74
  baseUrl;
73
75
  timeoutMs;
@@ -128,7 +130,8 @@ var SynClient = class {
128
130
  const base = new URL(this.baseUrl);
129
131
  const basePath = base.pathname.replace(/\/+$/, "");
130
132
  const reqPath = path8.startsWith("/") ? path8 : `/${path8}`;
131
- const url = new URL(`${basePath}${reqPath}`, base);
133
+ const prefix = basePath.endsWith(API_PREFIX) ? "" : API_PREFIX;
134
+ const url = new URL(`${basePath}${prefix}${reqPath}`, base);
132
135
  if (params) {
133
136
  for (const [key, value] of Object.entries(params)) {
134
137
  if (value !== void 0) {
@@ -194,6 +197,21 @@ async function apiGetList(path8, options) {
194
197
  checkResponse(status, data, options?.expected ?? [200]);
195
198
  return data;
196
199
  }
200
+ async function apiGetPaginated(path8, key, options) {
201
+ const client = new SynClient();
202
+ const { status, data } = await safeRequest(
203
+ () => client.get(path8, options?.params)
204
+ );
205
+ checkResponse(status, data, options?.expected ?? [200]);
206
+ if (typeof data !== "object" || data === null) {
207
+ throw new CLIError(`Unexpected API response for "${path8}": expected an object containing "${key}".`);
208
+ }
209
+ const items = data[key];
210
+ if (!Array.isArray(items)) {
211
+ throw new CLIError(`Unexpected API response for "${path8}": expected "${key}" to be an array.`);
212
+ }
213
+ return items;
214
+ }
197
215
  async function apiPost(path8, options) {
198
216
  const client = new SynClient(
199
217
  options?.timeoutMs !== void 0 ? { timeoutMs: options.timeoutMs } : void 0
@@ -212,6 +230,14 @@ async function apiPut(path8, options) {
212
230
  checkResponse(status, data, options?.expected ?? [200]);
213
231
  return data;
214
232
  }
233
+ async function apiPatch(path8, options) {
234
+ const client = new SynClient();
235
+ const { status, data } = await safeRequest(
236
+ () => client.patch(path8, options?.body)
237
+ );
238
+ checkResponse(status, data, options?.expected ?? [200]);
239
+ return data;
240
+ }
215
241
  async function apiDelete(path8, options) {
216
242
  const client = new SynClient();
217
243
  const { status, data } = await safeRequest(() => client.delete(path8));
@@ -2370,56 +2396,8 @@ var marketplaceGroup = new CommandGroup(
2370
2396
  );
2371
2397
  marketplaceGroup.command(addCommand).command(listMarketplaceCommand).command(removeCommand).command(refreshCommand);
2372
2398
 
2373
- // src/commands/agent.ts
2374
- var listCommand2 = {
2375
- name: "list",
2376
- description: "List available agent providers",
2377
- handler: async () => {
2378
- const providers = await apiGetList("/agents/providers");
2379
- const table = new Table({ title: "Agent Providers" });
2380
- table.addColumn("Provider", { style: CYAN });
2381
- table.addColumn("Display Name");
2382
- table.addColumn("Available");
2383
- table.addColumn("Default Model");
2384
- for (const p of providers) {
2385
- const available = p["available"] ? style("Yes", GREEN) : style("No", "\x1B[31m");
2386
- table.addRow(
2387
- String(p["provider"] ?? ""),
2388
- String(p["display_name"] ?? ""),
2389
- available,
2390
- String(p["default_model"] ?? "")
2391
- );
2392
- }
2393
- table.print();
2394
- }
2395
- };
2396
- var testCommand = {
2397
- name: "test",
2398
- description: "Test an agent provider with a simple prompt",
2399
- options: {
2400
- provider: { type: "string", short: "p", description: "Agent provider (claude, mock)", default: "claude" },
2401
- prompt: { type: "string", description: "Test prompt", default: "Say hello in one sentence." },
2402
- model: { type: "string", short: "m", description: "Model override" }
2403
- },
2404
- handler: async (parsed) => {
2405
- const provider = parsed.values["provider"] ?? "claude";
2406
- const prompt = parsed.values["prompt"] ?? "Say hello in one sentence.";
2407
- const model = parsed.values["model"] ?? null;
2408
- const result = await apiPost("/agents/test", {
2409
- body: { provider, prompt, model },
2410
- timeoutMs: 6e4
2411
- });
2412
- print(`${style(`Response from ${String(result["provider"] ?? provider)}:`, GREEN)}`);
2413
- print(` Model: ${String(result["model"] ?? "unknown")}`);
2414
- print(` Response: ${String(result["response_text"] ?? "")}`);
2415
- print(` Tokens: ${String(result["input_tokens"] ?? 0)} in / ${String(result["output_tokens"] ?? 0)} out`);
2416
- }
2417
- };
2418
- var agentGroup = new CommandGroup("agent", "AI agent management and testing");
2419
- agentGroup.command(listCommand2).command(testCommand);
2420
-
2421
2399
  // src/commands/artifacts.ts
2422
- var listCommand3 = {
2400
+ var listCommand2 = {
2423
2401
  name: "list",
2424
2402
  description: "List artifacts",
2425
2403
  options: {
@@ -2534,63 +2512,55 @@ var createCommand2 = {
2534
2512
  }
2535
2513
  };
2536
2514
  var artifactsGroup = new CommandGroup("artifacts", "Browse and retrieve workflow artifacts");
2537
- artifactsGroup.command(listCommand3).command(showCommand2).command(contentCommand).command(createCommand2);
2515
+ artifactsGroup.command(listCommand2).command(showCommand2).command(contentCommand).command(createCommand2);
2538
2516
 
2539
2517
  // src/commands/config.ts
2540
2518
  var showCommand3 = {
2541
2519
  name: "show",
2542
- description: "Display current configuration",
2543
- options: {
2544
- "show-secrets": { type: "boolean", description: "Show secret values", default: false }
2545
- },
2546
- handler: async (parsed) => {
2547
- const showSecrets = parsed.values["show-secrets"] === true;
2548
- const snapshot = await apiGet("/config", {
2549
- params: { show_secrets: String(showSecrets) }
2550
- });
2551
- for (const section of ["app", "database", "agents", "storage"]) {
2552
- const data = snapshot[section];
2553
- if (!data) continue;
2554
- print(`
2555
- ${style(section.charAt(0).toUpperCase() + section.slice(1), BOLD)}`);
2556
- for (const [k, v] of Object.entries(data)) {
2557
- print(` ${k}: ${String(v)}`);
2558
- }
2559
- }
2520
+ description: "Display current CLI configuration",
2521
+ handler: async () => {
2522
+ const apiUrl = getApiUrl();
2523
+ const headers = getAuthHeaders();
2524
+ const hasAuth = Object.keys(headers).length > 0;
2525
+ const authType = headers["Authorization"]?.startsWith("Bearer") ? "token" : headers["Authorization"]?.startsWith("Basic") ? "basic" : "none";
2526
+ print(style("CLI Configuration", BOLD));
2527
+ print(` Version: ${CLI_VERSION}`);
2528
+ print(` API URL: ${apiUrl}`);
2529
+ print(` Auth: ${hasAuth ? style(authType, GREEN) : style("none", DIM)}`);
2530
+ print("");
2531
+ print(style("Environment Variables", BOLD));
2532
+ print(` SYN_API_URL: ${process.env["SYN_API_URL"] ?? style("(default: http://localhost:8137)", DIM)}`);
2533
+ print(` SYN_API_TOKEN: ${process.env["SYN_API_TOKEN"] ? style("set", GREEN) : style("not set", DIM)}`);
2534
+ print(` SYN_API_USER: ${process.env["SYN_API_USER"] ?? style("not set", DIM)}`);
2535
+ print(` SYN_API_PASSWORD: ${process.env["SYN_API_PASSWORD"] ? style("set", GREEN) : style("not set", DIM)}`);
2560
2536
  }
2561
2537
  };
2562
2538
  var validateCommand2 = {
2563
2539
  name: "validate",
2564
- description: "Validate configuration and show issues",
2540
+ description: "Validate CLI configuration",
2565
2541
  handler: async () => {
2566
- print("Validating configuration...\n");
2567
- const data = await apiGet("/config/validate");
2568
- const issues = data["issues"] ?? [];
2569
- if (issues.length === 0) {
2570
- print(style("No issues found.", GREEN));
2571
- return;
2542
+ const issues = [];
2543
+ const apiUrl = getApiUrl();
2544
+ if (!apiUrl.startsWith("http://") && !apiUrl.startsWith("https://")) {
2545
+ issues.push("SYN_API_URL must start with http:// or https://");
2572
2546
  }
2573
- const table = new Table({ title: "Configuration Issues" });
2574
- table.addColumn("Level");
2575
- table.addColumn("Category");
2576
- table.addColumn("Message");
2577
- const levelStyles = { error: RED, warning: YELLOW, info: BLUE };
2578
- let hasErrors = false;
2579
- for (const issue of issues) {
2580
- const level = issue["level"] ?? "info";
2581
- const levelColor = levelStyles[level];
2582
- table.addRow(
2583
- levelColor ? style(level, levelColor) : level,
2584
- issue["category"] ?? "",
2585
- issue["message"] ?? ""
2586
- );
2587
- if (level === "error") hasErrors = true;
2547
+ const headers = getAuthHeaders();
2548
+ let isLocal = false;
2549
+ try {
2550
+ const parsed = new URL(apiUrl);
2551
+ isLocal = parsed.hostname === "localhost" || parsed.hostname === "127.0.0.1";
2552
+ } catch {
2588
2553
  }
2589
- table.print();
2590
- if (hasErrors) {
2591
- print(`
2592
- ${style("Configuration has errors.", RED)}`);
2593
- throw new CLIError("Config errors", 1);
2554
+ if (Object.keys(headers).length === 0 && !isLocal) {
2555
+ issues.push("No authentication configured for non-localhost API URL");
2556
+ }
2557
+ if (issues.length === 0) {
2558
+ print(style("Configuration is valid.", GREEN));
2559
+ } else {
2560
+ for (const issue of issues) {
2561
+ print(`${style("!", RED)} ${issue}`);
2562
+ }
2563
+ throw new CLIError("Configuration has issues", 1);
2594
2564
  }
2595
2565
  }
2596
2566
  };
@@ -2598,12 +2568,22 @@ var envCommand = {
2598
2568
  name: "env",
2599
2569
  description: "Show environment variable template",
2600
2570
  handler: async () => {
2601
- const data = await apiGet("/config/env");
2602
- const template = typeof data === "string" ? data : String(data["template"] ?? JSON.stringify(data));
2603
- print(template);
2571
+ print("# Syntropic137 CLI configuration");
2572
+ print("# Copy and adjust these variables in your shell profile");
2573
+ print("");
2574
+ print("# API server URL (default: http://localhost:8137)");
2575
+ print("export SYN_API_URL=http://localhost:8137");
2576
+ print("");
2577
+ print("# Authentication (choose one):");
2578
+ print("# Option 1: Bearer token");
2579
+ print("export SYN_API_TOKEN=your-token-here");
2580
+ print("");
2581
+ print("# Option 2: Basic auth");
2582
+ print("# export SYN_API_USER=admin");
2583
+ print("# export SYN_API_PASSWORD=your-password-here");
2604
2584
  }
2605
2585
  };
2606
- var configGroup = new CommandGroup("config", "Configuration management");
2586
+ var configGroup = new CommandGroup("config", "CLI configuration");
2607
2587
  configGroup.command(showCommand3).command(validateCommand2).command(envCommand);
2608
2588
 
2609
2589
  // src/commands/control.ts
@@ -3105,7 +3085,7 @@ var eventsGroup = new CommandGroup("events", "Query domain events and session ob
3105
3085
  eventsGroup.command(recentCommand).command(sessionEventsCommand).command(timelineCommand).command(costsCommand).command(toolsCommand);
3106
3086
 
3107
3087
  // src/commands/execution.ts
3108
- var listCommand4 = {
3088
+ var listCommand3 = {
3109
3089
  name: "list",
3110
3090
  description: "List all workflow executions",
3111
3091
  options: {
@@ -3195,7 +3175,7 @@ var showCommand5 = {
3195
3175
  }
3196
3176
  };
3197
3177
  var executionGroup = new CommandGroup("execution", "List and inspect workflow executions");
3198
- executionGroup.command(listCommand4).command(showCommand5);
3178
+ executionGroup.command(listCommand3).command(showCommand5);
3199
3179
 
3200
3180
  // src/commands/insights.ts
3201
3181
  var SPARKLINE_CHARS = " \u2581\u2582\u2583\u2584\u2585\u2586\u2587\u2588";
@@ -3253,7 +3233,7 @@ var costCommand = {
3253
3233
  },
3254
3234
  handler: async (parsed) => {
3255
3235
  const days = parsed.values["days"] ?? "30";
3256
- const d = await apiGet("/insights/costs", { params: { days } });
3236
+ const d = await apiGet("/insights/cost", { params: { days } });
3257
3237
  print(style(`Cost Overview (last ${days} days)`, CYAN));
3258
3238
  print(` ${style("Total cost:", BOLD)} ${formatCost(String(d["total_cost_usd"] ?? "0"))}`);
3259
3239
  print(` ${style("Total tokens:", BOLD)} ${formatTokens(Number(d["total_tokens"] ?? 0))}`);
@@ -3294,30 +3274,24 @@ var heatmapCommand = {
3294
3274
  days: { type: "string", short: "d", description: "Number of days to show", default: "14" }
3295
3275
  },
3296
3276
  handler: async (parsed) => {
3297
- const days = parsed.values["days"] ?? "14";
3298
- const d = await apiGet("/insights/heatmap", { params: { days } });
3299
- const buckets = d["buckets"] ?? [];
3300
- if (buckets.length === 0) {
3277
+ const numDays = parseInt(parsed.values["days"] ?? "14", 10);
3278
+ const endDate = /* @__PURE__ */ new Date();
3279
+ const startDate = /* @__PURE__ */ new Date();
3280
+ startDate.setDate(endDate.getDate() - numDays);
3281
+ const fmt = (dt) => dt.toISOString().split("T")[0];
3282
+ const d = await apiGet("/insights/contribution-heatmap", {
3283
+ params: { start_date: fmt(startDate), end_date: fmt(endDate) }
3284
+ });
3285
+ const days = d["days"] ?? [];
3286
+ if (days.length === 0) {
3301
3287
  printDim("No activity data.");
3302
3288
  return;
3303
3289
  }
3304
- const values = buckets.map((b) => Number(b["count"] ?? 0));
3305
- print(style(`Activity Heatmap (last ${days} days)`, CYAN));
3290
+ const values = days.map((b) => Number(b["count"] ?? 0));
3291
+ print(style(`Activity Heatmap (last ${numDays} days)`, CYAN));
3306
3292
  print(` ${renderSparkline(values)}`);
3307
- print(style(` ${values.reduce((a, b) => a + b, 0)} total events`, DIM));
3308
- const topRepos = d["top_repos"] ?? [];
3309
- if (topRepos.length > 0) {
3310
- const table = new Table({ title: "Top Repositories" });
3311
- table.addColumn("Repository", { style: CYAN });
3312
- table.addColumn("Events", { align: "right" });
3313
- for (const r of topRepos.slice(0, 5)) {
3314
- table.addRow(
3315
- String(r["repo_name"] ?? r["repo_id"] ?? ""),
3316
- String(r["count"] ?? 0)
3317
- );
3318
- }
3319
- table.print();
3320
- }
3293
+ const total = Number(d["total"] ?? values.reduce((a, b) => a + b, 0));
3294
+ print(style(` ${total} total events`, DIM));
3321
3295
  }
3322
3296
  };
3323
3297
  var insightsGroup = new CommandGroup("insights", "Global system insights and cost analysis");
@@ -3390,7 +3364,7 @@ var toolTimelineCommand = {
3390
3364
  handler: async (parsed) => {
3391
3365
  const sid = reqSessionId2(parsed);
3392
3366
  const limit = parsed.values["limit"] ?? "100";
3393
- const entries = await apiGetList(`/observe/sessions/${sid}/tools`, { params: { limit } });
3367
+ const entries = await apiGetPaginated(`/observability/sessions/${sid}/tools`, "executions", { params: { limit } });
3394
3368
  if (entries.length === 0) {
3395
3369
  printDim("No tool timeline entries.");
3396
3370
  return;
@@ -3419,7 +3393,7 @@ var tokenMetricsCommand = {
3419
3393
  args: [{ name: "session-id", description: "Session ID", required: true }],
3420
3394
  handler: async (parsed) => {
3421
3395
  const sid = reqSessionId2(parsed);
3422
- const d = await apiGet(`/observe/sessions/${sid}/tokens`);
3396
+ const d = await apiGet(`/observability/sessions/${sid}/tokens`);
3423
3397
  print(`${style("Token Metrics:", BOLD)} ${d["session_id"] ?? sid}`);
3424
3398
  print(` Input tokens: ${Number(d["input_tokens"] ?? 0).toLocaleString()}`);
3425
3399
  print(` Output tokens: ${Number(d["output_tokens"] ?? 0).toLocaleString()}`);
@@ -3464,11 +3438,11 @@ var createCommand3 = {
3464
3438
  if (d["slug"]) print(` Slug: ${String(d["slug"])}`);
3465
3439
  }
3466
3440
  };
3467
- var listCommand5 = {
3441
+ var listCommand4 = {
3468
3442
  name: "list",
3469
3443
  description: "List all organizations",
3470
3444
  handler: async () => {
3471
- const items = await apiGetList("/organizations");
3445
+ const items = await apiGetPaginated("/organizations", "organizations");
3472
3446
  if (items.length === 0) {
3473
3447
  printDim("No organizations found.");
3474
3448
  return;
@@ -3546,7 +3520,7 @@ var deleteCommand2 = {
3546
3520
  }
3547
3521
  };
3548
3522
  var orgGroup = new CommandGroup("org", "Manage organizations");
3549
- orgGroup.command(createCommand3).command(listCommand5).command(showCommand7).command(updateCommand2).command(deleteCommand2);
3523
+ orgGroup.command(createCommand3).command(listCommand4).command(showCommand7).command(updateCommand2).command(deleteCommand2);
3550
3524
 
3551
3525
  // src/commands/repo.ts
3552
3526
  function reqRepoId(parsed) {
@@ -3578,11 +3552,11 @@ var registerCommand = {
3578
3552
  if (org) body["organization_id"] = org;
3579
3553
  const d = await apiPost("/repos", { body, expected: [200, 201] });
3580
3554
  printSuccess(`Repository registered: ${d["repo_id"] ?? ""}`);
3581
- print(` URL: ${d["repo_url"] ?? url}`);
3555
+ print(` Name: ${d["full_name"] ?? url}`);
3582
3556
  if (d["system_id"]) print(` System: ${String(d["system_id"])}`);
3583
3557
  }
3584
3558
  };
3585
- var listCommand6 = {
3559
+ var listCommand5 = {
3586
3560
  name: "list",
3587
3561
  description: "List repositories",
3588
3562
  options: {
@@ -3594,22 +3568,20 @@ var listCommand6 = {
3594
3568
  organization_id: parsed.values["org"] ?? null,
3595
3569
  system_id: parsed.values["system"] ?? null
3596
3570
  });
3597
- const items = await apiGetList("/repos", { params });
3571
+ const items = await apiGetPaginated("/repos", "repos", { params });
3598
3572
  if (items.length === 0) {
3599
3573
  printDim("No repositories found.");
3600
3574
  return;
3601
3575
  }
3602
3576
  const table = new Table({ title: "Repositories" });
3603
3577
  table.addColumn("ID", { style: CYAN });
3604
- table.addColumn("URL");
3578
+ table.addColumn("Name");
3605
3579
  table.addColumn("System", { style: DIM });
3606
- table.addColumn("Status");
3607
3580
  for (const r of items) {
3608
3581
  table.addRow(
3609
3582
  String(r["repo_id"] ?? ""),
3610
- String(r["repo_url"] ?? ""),
3611
- String(r["system_id"] ?? "\u2014"),
3612
- formatStatus(String(r["status"] ?? ""))
3583
+ String(r["full_name"] ?? ""),
3584
+ String(r["system_id"] ?? "\u2014")
3613
3585
  );
3614
3586
  }
3615
3587
  table.print();
@@ -3622,11 +3594,10 @@ var showCommand8 = {
3622
3594
  handler: async (parsed) => {
3623
3595
  const id = reqRepoId(parsed);
3624
3596
  const d = await apiGet(`/repos/${id}`);
3625
- print(`${style("Repository:", BOLD)} ${d["repo_url"] ?? id}`);
3597
+ print(`${style("Repository:", BOLD)} ${d["full_name"] ?? id}`);
3626
3598
  print(` ID: ${d["repo_id"] ?? id}`);
3627
3599
  if (d["system_id"]) print(` System: ${String(d["system_id"])}`);
3628
3600
  if (d["organization_id"]) print(` Org: ${String(d["organization_id"])}`);
3629
- print(` Status: ${formatStatus(String(d["status"] ?? ""))}`);
3630
3601
  }
3631
3602
  };
3632
3603
  var assignCommand = {
@@ -3643,7 +3614,7 @@ var assignCommand = {
3643
3614
  printError("Missing --system");
3644
3615
  throw new CLIError("Missing option", 1);
3645
3616
  }
3646
- await apiPut(`/repos/${id}/assign`, { body: { system_id: system } });
3617
+ await apiPost(`/repos/${id}/assign`, { body: { system_id: system } });
3647
3618
  printSuccess(`Repository ${id} assigned to system ${system}.`);
3648
3619
  }
3649
3620
  };
@@ -3696,7 +3667,7 @@ var costCommand2 = {
3696
3667
  args: [{ name: "repo-id", description: "Repository ID", required: true }],
3697
3668
  handler: async (parsed) => {
3698
3669
  const id = reqRepoId(parsed);
3699
- const d = await apiGet(`/repos/${id}/costs`);
3670
+ const d = await apiGet(`/repos/${id}/cost`);
3700
3671
  print(`${style("Repository Costs:", BOLD)} ${id}`);
3701
3672
  print(` Total cost: ${formatCost(String(d["total_cost_usd"] ?? "0"))}`);
3702
3673
  print(` Tokens: ${formatTokens(Number(d["total_tokens"] ?? 0))}`);
@@ -3727,7 +3698,7 @@ var activityCommand = {
3727
3698
  handler: async (parsed) => {
3728
3699
  const id = reqRepoId(parsed);
3729
3700
  const limit = parsed.values["limit"] ?? "20";
3730
- const items = await apiGetList(`/repos/${id}/activity`, { params: { limit } });
3701
+ const items = await apiGetPaginated(`/repos/${id}/activity`, "entries", { params: { limit } });
3731
3702
  if (items.length === 0) {
3732
3703
  printDim("No recent activity.");
3733
3704
  return;
@@ -3762,7 +3733,7 @@ var failuresCommand = {
3762
3733
  handler: async (parsed) => {
3763
3734
  const id = reqRepoId(parsed);
3764
3735
  const limit = parsed.values["limit"] ?? "10";
3765
- const items = await apiGetList(`/repos/${id}/failures`, { params: { limit } });
3736
+ const items = await apiGetPaginated(`/repos/${id}/failures`, "failures", { params: { limit } });
3766
3737
  if (items.length === 0) {
3767
3738
  printDim("No recent failures.");
3768
3739
  return;
@@ -3793,7 +3764,7 @@ var sessionsCommand2 = {
3793
3764
  handler: async (parsed) => {
3794
3765
  const id = reqRepoId(parsed);
3795
3766
  const limit = parsed.values["limit"] ?? "20";
3796
- const items = await apiGetList(`/repos/${id}/sessions`, { params: { limit } });
3767
+ const items = await apiGetPaginated(`/repos/${id}/sessions`, "sessions", { params: { limit } });
3797
3768
  if (items.length === 0) {
3798
3769
  printDim("No sessions found.");
3799
3770
  return;
@@ -3817,10 +3788,10 @@ var sessionsCommand2 = {
3817
3788
  }
3818
3789
  };
3819
3790
  var repoGroup = new CommandGroup("repo", "Manage repositories and view observability data");
3820
- repoGroup.command(registerCommand).command(listCommand6).command(showCommand8).command(assignCommand).command(unassignCommand).command(healthCommand2).command(costCommand2).command(activityCommand).command(failuresCommand).command(sessionsCommand2);
3791
+ repoGroup.command(registerCommand).command(listCommand5).command(showCommand8).command(assignCommand).command(unassignCommand).command(healthCommand2).command(costCommand2).command(activityCommand).command(failuresCommand).command(sessionsCommand2);
3821
3792
 
3822
3793
  // src/commands/sessions.ts
3823
- var listCommand7 = {
3794
+ var listCommand6 = {
3824
3795
  name: "list",
3825
3796
  description: "List agent sessions",
3826
3797
  options: {
@@ -3903,7 +3874,7 @@ var showCommand9 = {
3903
3874
  }
3904
3875
  };
3905
3876
  var sessionsGroup = new CommandGroup("sessions", "List and inspect agent sessions");
3906
- sessionsGroup.command(listCommand7).command(showCommand9);
3877
+ sessionsGroup.command(listCommand6).command(showCommand9);
3907
3878
 
3908
3879
  // src/commands/system.ts
3909
3880
  function reqId3(parsed) {
@@ -3938,7 +3909,7 @@ var createCommand4 = {
3938
3909
  print(` Name: ${d["name"] ?? name}`);
3939
3910
  }
3940
3911
  };
3941
- var listCommand8 = {
3912
+ var listCommand7 = {
3942
3913
  name: "list",
3943
3914
  description: "List all systems",
3944
3915
  options: {
@@ -3948,7 +3919,7 @@ var listCommand8 = {
3948
3919
  const params = buildParams({
3949
3920
  organization_id: parsed.values["org"] ?? null
3950
3921
  });
3951
- const items = await apiGetList("/systems", { params });
3922
+ const items = await apiGetPaginated("/systems", "systems", { params });
3952
3923
  if (items.length === 0) {
3953
3924
  printDim("No systems found.");
3954
3925
  return;
@@ -3958,14 +3929,12 @@ var listCommand8 = {
3958
3929
  table.addColumn("Name");
3959
3930
  table.addColumn("Org", { style: DIM });
3960
3931
  table.addColumn("Repos", { align: "right" });
3961
- table.addColumn("Status");
3962
3932
  for (const s of items) {
3963
3933
  table.addRow(
3964
3934
  String(s["system_id"] ?? ""),
3965
3935
  String(s["name"] ?? ""),
3966
3936
  String(s["organization_id"] ?? "\u2014"),
3967
- String(s["repo_count"] ?? 0),
3968
- formatStatus(String(s["status"] ?? ""))
3937
+ String(s["repo_count"] ?? 0)
3969
3938
  );
3970
3939
  }
3971
3940
  table.print();
@@ -3983,7 +3952,6 @@ var showCommand10 = {
3983
3952
  if (d["description"]) print(` Description: ${String(d["description"])}`);
3984
3953
  if (d["organization_id"]) print(` Org: ${String(d["organization_id"])}`);
3985
3954
  print(` Repos: ${d["repo_count"] ?? 0}`);
3986
- print(` Status: ${formatStatus(String(d["status"] ?? ""))}`);
3987
3955
  }
3988
3956
  };
3989
3957
  var updateCommand3 = {
@@ -4066,7 +4034,7 @@ var costCommand3 = {
4066
4034
  args: [{ name: "system-id", description: "System ID", required: true }],
4067
4035
  handler: async (parsed) => {
4068
4036
  const id = reqId3(parsed);
4069
- const d = await apiGet(`/systems/${id}/costs`);
4037
+ const d = await apiGet(`/systems/${id}/cost`);
4070
4038
  print(`${style("System Costs:", BOLD)} ${id}`);
4071
4039
  print(` Total cost: ${formatCost(String(d["total_cost_usd"] ?? "0"))}`);
4072
4040
  print(` Tokens: ${formatTokens(Number(d["total_tokens"] ?? 0))}`);
@@ -4097,7 +4065,7 @@ var activityCommand2 = {
4097
4065
  handler: async (parsed) => {
4098
4066
  const id = reqId3(parsed);
4099
4067
  const limit = parsed.values["limit"] ?? "20";
4100
- const items = await apiGetList(`/systems/${id}/activity`, { params: { limit } });
4068
+ const items = await apiGetPaginated(`/systems/${id}/activity`, "entries", { params: { limit } });
4101
4069
  if (items.length === 0) {
4102
4070
  printDim("No recent activity.");
4103
4071
  return;
@@ -4179,7 +4147,7 @@ var historyCommand = {
4179
4147
  limit: parsed.values["limit"] ?? "50",
4180
4148
  status: parsed.values["status"] ?? null
4181
4149
  });
4182
- const items = await apiGetList(`/systems/${id}/history`, { params });
4150
+ const items = await apiGetPaginated(`/systems/${id}/history`, "entries", { params });
4183
4151
  if (items.length === 0) {
4184
4152
  printDim("No execution history.");
4185
4153
  return;
@@ -4205,7 +4173,7 @@ var historyCommand = {
4205
4173
  }
4206
4174
  };
4207
4175
  var systemGroup = new CommandGroup("system", "Manage systems and view system observability");
4208
- systemGroup.command(createCommand4).command(listCommand8).command(showCommand10).command(updateCommand3).command(deleteCommand3).command(statusCommand3).command(costCommand3).command(activityCommand2).command(patternsCommand).command(historyCommand);
4176
+ systemGroup.command(createCommand4).command(listCommand7).command(showCommand10).command(updateCommand3).command(deleteCommand3).command(statusCommand3).command(costCommand3).command(activityCommand2).command(patternsCommand).command(historyCommand);
4209
4177
 
4210
4178
  // src/commands/triggers.ts
4211
4179
  function reqId4(parsed) {
@@ -4254,9 +4222,10 @@ var registerCommand2 = {
4254
4222
  const conditionStrs = parsed.values["condition"] ?? [];
4255
4223
  const conditions = conditionStrs.length > 0 ? parseConditions(conditionStrs) : [];
4256
4224
  const body = {
4257
- repo_id: repo,
4225
+ name: `${event} \u2192 ${workflow}`,
4226
+ repository: repo,
4258
4227
  workflow_id: workflow,
4259
- event_type: event,
4228
+ event,
4260
4229
  conditions,
4261
4230
  max_fires_per_period: parseInt(parsed.values["max-fires"] ?? "5", 10),
4262
4231
  cooldown_seconds: parseInt(parsed.values["cooldown"] ?? "300", 10)
@@ -4272,8 +4241,7 @@ var enablePresetCommand = {
4272
4241
  description: "Enable a built-in trigger preset",
4273
4242
  args: [{ name: "preset", description: "Preset name (self-healing, review-fix)", required: true }],
4274
4243
  options: {
4275
- repo: { type: "string", short: "r", description: "Repository ID" },
4276
- workflow: { type: "string", short: "w", description: "Workflow ID" }
4244
+ repo: { type: "string", short: "r", description: "Repository ID" }
4277
4245
  },
4278
4246
  handler: async (parsed) => {
4279
4247
  const preset = parsed.positionals[0];
@@ -4286,14 +4254,11 @@ var enablePresetCommand = {
4286
4254
  printError("Missing --repo");
4287
4255
  throw new CLIError("Missing option", 1);
4288
4256
  }
4289
- const body = { preset, repo_id: repo };
4290
- const workflow = parsed.values["workflow"];
4291
- if (workflow) body["workflow_id"] = workflow;
4292
- const d = await apiPost("/triggers/presets", { body, expected: [200, 201] });
4257
+ const d = await apiPost(`/triggers/presets/${encodeURIComponent(preset)}`, { body: { repository: repo }, expected: [200, 201] });
4293
4258
  printSuccess(`Preset "${preset}" enabled: ${d["trigger_id"] ?? ""}`);
4294
4259
  }
4295
4260
  };
4296
- var listCommand9 = {
4261
+ var listCommand8 = {
4297
4262
  name: "list",
4298
4263
  description: "List trigger rules",
4299
4264
  options: {
@@ -4302,10 +4267,10 @@ var listCommand9 = {
4302
4267
  },
4303
4268
  handler: async (parsed) => {
4304
4269
  const params = buildParams({
4305
- repo_id: parsed.values["repo"] ?? null,
4270
+ repository: parsed.values["repo"] ?? null,
4306
4271
  status: parsed.values["status"] ?? null
4307
4272
  });
4308
- const items = await apiGetList("/triggers", { params });
4273
+ const items = await apiGetPaginated("/triggers", "triggers", { params });
4309
4274
  if (items.length === 0) {
4310
4275
  printDim("No triggers found.");
4311
4276
  return;
@@ -4320,8 +4285,8 @@ var listCommand9 = {
4320
4285
  for (const t of items) {
4321
4286
  table.addRow(
4322
4287
  String(t["trigger_id"] ?? "").slice(0, 12),
4323
- String(t["event_type"] ?? ""),
4324
- String(t["repo_id"] ?? "").slice(0, 12),
4288
+ String(t["event"] ?? ""),
4289
+ String(t["repository"] ?? "").slice(0, 12),
4325
4290
  String(t["workflow_id"] ?? "").slice(0, 12),
4326
4291
  formatStatus(String(t["status"] ?? "")),
4327
4292
  String(t["fire_count"] ?? 0)
@@ -4338,8 +4303,8 @@ var showCommand11 = {
4338
4303
  const id = reqId4(parsed);
4339
4304
  const d = await apiGet(`/triggers/${id}`);
4340
4305
  print(`${style("Trigger:", BOLD)} ${d["trigger_id"] ?? id}`);
4341
- print(` Event: ${d["event_type"] ?? ""}`);
4342
- print(` Repo: ${d["repo_id"] ?? ""}`);
4306
+ print(` Event: ${d["event"] ?? ""}`);
4307
+ print(` Repo: ${d["repository"] ?? ""}`);
4343
4308
  print(` Workflow: ${d["workflow_id"] ?? ""}`);
4344
4309
  print(` Status: ${formatStatus(String(d["status"] ?? ""))}`);
4345
4310
  print(` Fires: ${d["fire_count"] ?? 0} / max ${d["max_fires_per_period"] ?? "\u2014"}`);
@@ -4365,7 +4330,7 @@ var historyCommand2 = {
4365
4330
  handler: async (parsed) => {
4366
4331
  const id = reqId4(parsed);
4367
4332
  const limit = parsed.values["limit"] ?? "20";
4368
- const items = await apiGetList(`/triggers/${id}/history`, { params: { limit } });
4333
+ const items = await apiGetPaginated(`/triggers/${id}/history`, "entries", { params: { limit } });
4369
4334
  if (items.length === 0) {
4370
4335
  printDim("No trigger history.");
4371
4336
  return;
@@ -4392,7 +4357,7 @@ var pauseCommand2 = {
4392
4357
  args: [{ name: "trigger-id", description: "Trigger ID", required: true }],
4393
4358
  handler: async (parsed) => {
4394
4359
  const id = reqId4(parsed);
4395
- await apiPost(`/triggers/${id}/pause`);
4360
+ await apiPatch(`/triggers/${id}`, { body: { action: "pause" } });
4396
4361
  printSuccess(`Trigger ${id} paused.`);
4397
4362
  }
4398
4363
  };
@@ -4402,7 +4367,7 @@ var resumeCommand2 = {
4402
4367
  args: [{ name: "trigger-id", description: "Trigger ID", required: true }],
4403
4368
  handler: async (parsed) => {
4404
4369
  const id = reqId4(parsed);
4405
- await apiPost(`/triggers/${id}/resume`);
4370
+ await apiPatch(`/triggers/${id}`, { body: { action: "resume" } });
4406
4371
  printSuccess(`Trigger ${id} resumed.`);
4407
4372
  }
4408
4373
  };
@@ -4440,12 +4405,26 @@ var disableAllCommand = {
4440
4405
  printError(`Use --force to confirm disabling all triggers for repo ${repo}`);
4441
4406
  throw new CLIError("Confirmation required", 1);
4442
4407
  }
4443
- await apiPost(`/triggers/disable-all`, { body: { repo_id: repo } });
4444
- printSuccess(`All triggers disabled for repository ${repo}.`);
4408
+ const triggers = await apiGetPaginated("/triggers", "triggers", {
4409
+ params: { repository: repo, status: "active" }
4410
+ });
4411
+ if (triggers.length === 0) {
4412
+ printDim("No active triggers found.");
4413
+ return;
4414
+ }
4415
+ let count = 0;
4416
+ for (const t of triggers) {
4417
+ const tid = String(t["trigger_id"] ?? "");
4418
+ if (tid) {
4419
+ await apiPatch(`/triggers/${tid}`, { body: { action: "pause" } });
4420
+ count++;
4421
+ }
4422
+ }
4423
+ printSuccess(`Disabled ${count} trigger(s) for repository ${repo}.`);
4445
4424
  }
4446
4425
  };
4447
4426
  var triggersGroup = new CommandGroup("triggers", "Manage self-healing trigger rules");
4448
- triggersGroup.command(registerCommand2).command(enablePresetCommand).command(listCommand9).command(showCommand11).command(historyCommand2).command(pauseCommand2).command(resumeCommand2).command(deleteCommand4).command(disableAllCommand);
4427
+ triggersGroup.command(registerCommand2).command(enablePresetCommand).command(listCommand8).command(showCommand11).command(historyCommand2).command(pauseCommand2).command(resumeCommand2).command(deleteCommand4).command(disableAllCommand);
4449
4428
 
4450
4429
  // src/client/sse.ts
4451
4430
  function parseSseLine(line) {
@@ -4534,7 +4513,7 @@ var executionCommand = {
4534
4513
  print(style(`Watching execution ${id}...`, BOLD));
4535
4514
  printDim("Press Ctrl+C to stop.\n");
4536
4515
  try {
4537
- for await (const event of streamSSE(`/watch/executions/${id}`)) {
4516
+ for await (const event of streamSSE(`/sse/executions/${id}`)) {
4538
4517
  renderEvent(event);
4539
4518
  }
4540
4519
  print(style("\nStream ended.", DIM));
@@ -4803,7 +4782,6 @@ cli.addCommand({
4803
4782
  });
4804
4783
  cli.addGroup(workflowGroup);
4805
4784
  cli.addGroup(marketplaceGroup);
4806
- cli.addGroup(agentGroup);
4807
4785
  cli.addGroup(artifactsGroup);
4808
4786
  cli.addGroup(configGroup);
4809
4787
  cli.addGroup(controlGroup);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@syntropic137/cli",
3
- "version": "0.19.6",
3
+ "version": "0.20.0",
4
4
  "description": "Syntropic137 CLI - Event-sourced workflow engine for AI agents",
5
5
  "type": "module",
6
6
  "bin": {
@@ -18,9 +18,11 @@
18
18
  "test:watch": "vitest",
19
19
  "typecheck": "tsc --noEmit",
20
20
  "generate:types": "tsx scripts/generate-types.ts",
21
- "check:api-drift": "tsx scripts/check-api-drift.ts"
21
+ "check:api-drift": "tsx scripts/check-api-drift.ts",
22
+ "generate:docs": "tsx scripts/generate-cli-docs.ts"
22
23
  },
23
24
  "dependencies": {
25
+ "openapi-fetch": "^0.17.0",
24
26
  "zod": "^3.24.0"
25
27
  },
26
28
  "devDependencies": {