@autohq/cli 0.1.101 → 0.1.103

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
@@ -17496,7 +17496,7 @@ var init_sessions = __esm({
17496
17496
  message: `description must be at most ${SESSION_IDENTITY_DESCRIPTION_MAX_LENGTH} characters as Slack counts them (a non-ASCII character like "\u2014" counts as 6)`
17497
17497
  }
17498
17498
  ).optional()
17499
- }).strict().refine((identity) => Object.keys(identity).length > 0, {
17499
+ }).strict().refine((identity2) => Object.keys(identity2).length > 0, {
17500
17500
  message: "Session identity requires at least one field"
17501
17501
  });
17502
17502
  SessionSpecSchema = external_exports.object({
@@ -17628,7 +17628,7 @@ var init_sessions = __esm({
17628
17628
  });
17629
17629
 
17630
17630
  // ../../packages/schemas/src/project-resources.ts
17631
- var EnvironmentApplyDocumentSchema, ProfileApplyDocumentSchema, ToolApplyDocumentSchema, SessionApplyDocumentSchema, ProjectApplyResourceSchema, ProjectDeleteResourceSchema, AVATAR_ASSET_CONTENT_TYPES, MAX_AVATAR_ASSET_BASE64_LENGTH, ProjectApplyAssetSchema, ProjectApplyAssetsSchema, ProjectApplyRequestSchema, ProjectApplySystemConfigSchema, ProjectAppliedResourceSchema, ProjectApplyDiagnosticSchema, ProjectApplyResponseSchema;
17631
+ var EnvironmentApplyDocumentSchema, ProfileApplyDocumentSchema, ToolApplyDocumentSchema, SessionApplyDocumentSchema, ProjectApplyResourceSchema, PROJECT_RESOURCE_KINDS, ProjectDeleteResourceSchema, AVATAR_ASSET_CONTENT_TYPES, MAX_AVATAR_ASSET_BASE64_LENGTH, ProjectApplyAssetSchema, ProjectApplyAssetsSchema, ProjectApplyRequestSchema, ProjectApplySystemConfigSchema, ProjectAppliedResourceSchema, ProjectApplyDiagnosticSchema, ProjectApplyResponseSchema;
17632
17632
  var init_project_resources = __esm({
17633
17633
  "../../packages/schemas/src/project-resources.ts"() {
17634
17634
  "use strict";
@@ -17655,13 +17655,14 @@ var init_project_resources = __esm({
17655
17655
  ToolApplyDocumentSchema,
17656
17656
  SessionApplyDocumentSchema
17657
17657
  ]);
17658
+ PROJECT_RESOURCE_KINDS = [
17659
+ RESOURCE_KIND_ENVIRONMENT,
17660
+ RESOURCE_KIND_PROFILE,
17661
+ RESOURCE_KIND_TOOL,
17662
+ RESOURCE_KIND_SESSION
17663
+ ];
17658
17664
  ProjectDeleteResourceSchema = external_exports.object({
17659
- kind: external_exports.enum([
17660
- RESOURCE_KIND_ENVIRONMENT,
17661
- RESOURCE_KIND_PROFILE,
17662
- RESOURCE_KIND_TOOL,
17663
- RESOURCE_KIND_SESSION
17664
- ]),
17665
+ kind: external_exports.enum(PROJECT_RESOURCE_KINDS),
17665
17666
  name: external_exports.string().trim().min(1)
17666
17667
  });
17667
17668
  AVATAR_ASSET_CONTENT_TYPES = ["image/png", "image/jpeg"];
@@ -20370,17 +20371,69 @@ var init_client = __esm({
20370
20371
  }
20371
20372
  });
20372
20373
 
20374
+ // src/lib/output/style.ts
20375
+ import { Chalk } from "chalk";
20376
+ function createStyle(flags) {
20377
+ const textual = flags.outputMode === "text" || flags.outputMode === "tui";
20378
+ if (!textual || flags.noColor || !flags.isTTY) {
20379
+ return plainStyle;
20380
+ }
20381
+ const chalk2 = new Chalk({ level: 1 });
20382
+ return {
20383
+ enabled: true,
20384
+ success: (text) => chalk2.green(text),
20385
+ warn: (text) => chalk2.yellow(text),
20386
+ error: (text) => chalk2.red(text),
20387
+ heading: (text) => chalk2.bold.underline(text),
20388
+ label: (text) => chalk2.bold(text),
20389
+ id: (text) => chalk2.cyan(text),
20390
+ url: (text) => chalk2.cyan.underline(text),
20391
+ dim: (text) => chalk2.dim(text)
20392
+ };
20393
+ }
20394
+ function identity(text) {
20395
+ return text;
20396
+ }
20397
+ var plainStyle;
20398
+ var init_style = __esm({
20399
+ "src/lib/output/style.ts"() {
20400
+ "use strict";
20401
+ plainStyle = {
20402
+ enabled: false,
20403
+ success: identity,
20404
+ warn: identity,
20405
+ error: identity,
20406
+ heading: identity,
20407
+ label: identity,
20408
+ id: identity,
20409
+ url: identity,
20410
+ dim: identity
20411
+ };
20412
+ }
20413
+ });
20414
+
20373
20415
  // src/lib/browser.ts
20374
20416
  import { spawn } from "child_process";
20375
20417
  function openBrowser(url2) {
20376
- const command = process.platform === "darwin" ? "open" : process.platform === "win32" ? "cmd" : "xdg-open";
20377
- const args = process.platform === "win32" ? ["/c", "start", "", url2] : [url2];
20378
- const child = spawn(command, args, {
20418
+ const child = spawn(openCommand(), openArgs(url2), {
20379
20419
  detached: true,
20380
20420
  stdio: "ignore"
20381
20421
  });
20382
20422
  child.unref();
20383
20423
  }
20424
+ function openCommand() {
20425
+ switch (process.platform) {
20426
+ case "darwin":
20427
+ return "open";
20428
+ case "win32":
20429
+ return "cmd";
20430
+ default:
20431
+ return "xdg-open";
20432
+ }
20433
+ }
20434
+ function openArgs(url2) {
20435
+ return process.platform === "win32" ? ["/c", "start", "", url2] : [url2];
20436
+ }
20384
20437
  var init_browser = __esm({
20385
20438
  "src/lib/browser.ts"() {
20386
20439
  "use strict";
@@ -21153,10 +21206,12 @@ async function applyResource(input) {
21153
21206
  },
21154
21207
  client: input.client,
21155
21208
  request,
21156
- writeOutput: input.writeOutput
21209
+ writeOutput: input.writeOutput,
21210
+ style: input.style
21157
21211
  });
21158
21212
  }
21159
21213
  async function applyProjectInput(input) {
21214
+ const style = input.style ?? plainStyle;
21160
21215
  const response = await input.client.applyProjectResources(
21161
21216
  {
21162
21217
  ...input.request.delete.length > 0 ? { delete: input.request.delete } : {},
@@ -21182,7 +21237,10 @@ async function applyProjectInput(input) {
21182
21237
  );
21183
21238
  for (const item of response.plan) {
21184
21239
  input.writeOutput(
21185
- `${item.action.padEnd(actionWidth + 2)}${item.kind}/${item.name}`
21240
+ `${planActionStyle(
21241
+ style,
21242
+ item.action
21243
+ )(item.action.padEnd(actionWidth + 2))}${item.kind}/${item.name}`
21186
21244
  );
21187
21245
  }
21188
21246
  if (input.commandOptions.connect) {
@@ -21190,30 +21248,42 @@ async function applyProjectInput(input) {
21190
21248
  input.request
21191
21249
  )) {
21192
21250
  input.writeOutput(
21193
- `would connect tool/${item.tool} connection/${item.connection}`
21251
+ style.dim(
21252
+ `would connect tool/${item.tool} connection/${item.connection}`
21253
+ )
21194
21254
  );
21195
21255
  }
21196
21256
  }
21197
- writeDiagnostics(response.diagnostics, input.writeOutput);
21257
+ writeDiagnostics(response.diagnostics, input.writeOutput, style);
21198
21258
  return;
21199
21259
  }
21200
21260
  for (const { kind, resource } of resources) {
21201
- input.writeOutput(`kind ${kind}`);
21202
- input.writeOutput(`name ${resource.metadata.name}`);
21203
- input.writeOutput(`uid ${resource.metadata.uid}`);
21204
- input.writeOutput(`generation ${resource.metadata.generation}`);
21205
- input.writeOutput(`resource_version ${resource.metadata.resourceVersion}`);
21261
+ input.writeOutput(`${style.label("kind")} ${kind}`);
21262
+ input.writeOutput(`${style.label("name")} ${resource.metadata.name}`);
21263
+ input.writeOutput(
21264
+ `${style.label("uid")} ${style.id(resource.metadata.uid)}`
21265
+ );
21266
+ input.writeOutput(
21267
+ `${style.label("generation")} ${resource.metadata.generation}`
21268
+ );
21269
+ input.writeOutput(
21270
+ `${style.label("resource_version")} ${resource.metadata.resourceVersion}`
21271
+ );
21206
21272
  }
21207
21273
  for (const trigger of response.triggers) {
21208
- input.writeOutput(`webhook_event ${trigger.event}`);
21209
- input.writeOutput(`webhook_endpoint ${trigger.endpoint}`);
21210
- input.writeOutput(`webhook_ingest_url ${trigger.ingestUrl}`);
21211
- input.writeOutput(`webhook_status ${trigger.status}`);
21274
+ input.writeOutput(`${style.label("webhook_event")} ${trigger.event}`);
21275
+ input.writeOutput(`${style.label("webhook_endpoint")} ${trigger.endpoint}`);
21276
+ input.writeOutput(
21277
+ `${style.label("webhook_ingest_url")} ${style.url(trigger.ingestUrl)}`
21278
+ );
21279
+ input.writeOutput(`${style.label("webhook_status")} ${trigger.status}`);
21212
21280
  }
21213
21281
  for (const resource of response.pruned) {
21214
- input.writeOutput(`pruned ${resource.kind}/${resource.name}`);
21282
+ input.writeOutput(
21283
+ `${style.warn("pruned")} ${resource.kind}/${resource.name}`
21284
+ );
21215
21285
  }
21216
- writeDiagnostics(response.diagnostics, input.writeOutput);
21286
+ writeDiagnostics(response.diagnostics, input.writeOutput, style);
21217
21287
  if (input.commandOptions.connect) {
21218
21288
  const connections = mcpOAuthToolConnectionsFromAppliedResources(resources);
21219
21289
  for (const item of connections) {
@@ -21227,16 +21297,32 @@ async function applyProjectInput(input) {
21227
21297
  }
21228
21298
  }
21229
21299
  }
21230
- function writeDiagnostics(diagnostics, writeOutput) {
21300
+ function writeDiagnostics(diagnostics, writeOutput, style) {
21231
21301
  for (const diagnostic of diagnostics) {
21302
+ const severity = diagnostic.severity === "error" ? style.error(diagnostic.severity) : style.warn(diagnostic.severity);
21232
21303
  writeOutput(
21233
- `${diagnostic.severity} ${diagnostic.kind}/${diagnostic.name}: ${diagnostic.message}`
21304
+ `${severity} ${diagnostic.kind}/${diagnostic.name}: ${diagnostic.message}`
21234
21305
  );
21235
21306
  }
21236
21307
  }
21308
+ function planActionStyle(style, action) {
21309
+ switch (action) {
21310
+ case "create":
21311
+ return style.success;
21312
+ case "update":
21313
+ return style.warn;
21314
+ case "archive":
21315
+ return style.error;
21316
+ case "unchanged":
21317
+ return style.dim;
21318
+ default:
21319
+ return (text) => text;
21320
+ }
21321
+ }
21237
21322
  var init_actions = __esm({
21238
21323
  "src/commands/apply/actions.ts"() {
21239
21324
  "use strict";
21325
+ init_style();
21240
21326
  init_connect();
21241
21327
  init_files();
21242
21328
  }
@@ -21294,6 +21380,7 @@ var init_pkce = __esm({
21294
21380
 
21295
21381
  // src/commands/auth/login.ts
21296
21382
  async function login(input) {
21383
+ const style = input.style ?? plainStyle;
21297
21384
  const serverUrl = resolveApiBaseUrl({ explicit: input.options.apiUrl });
21298
21385
  if (input.options.device) {
21299
21386
  const device = await postJson(
@@ -21302,9 +21389,13 @@ async function login(input) {
21302
21389
  {}
21303
21390
  );
21304
21391
  input.writeOutput(
21305
- `Open ${device.verification_uri} and enter ${device.user_code}`
21392
+ `Open ${style.url(device.verification_uri)} and enter ${style.label(
21393
+ device.user_code
21394
+ )}`
21395
+ );
21396
+ input.writeOutput(
21397
+ `${style.label("Device code:")} ${style.id(device.device_code)}`
21306
21398
  );
21307
- input.writeOutput(`Device code: ${device.device_code}`);
21308
21399
  const deadline = Date.now() + device.expires_in * 1e3;
21309
21400
  let firstAttempt = true;
21310
21401
  while (Date.now() < deadline) {
@@ -21333,7 +21424,8 @@ async function login(input) {
21333
21424
  serverUrl,
21334
21425
  fetch: input.fetch,
21335
21426
  configPath: input.configPath,
21336
- writeOutput: input.writeOutput
21427
+ writeOutput: input.writeOutput,
21428
+ style
21337
21429
  });
21338
21430
  return;
21339
21431
  }
@@ -21361,8 +21453,8 @@ async function login(input) {
21361
21453
  const authorizeUrl = new URL("/auth/cli", serverUrl);
21362
21454
  authorizeUrl.searchParams.set("pkce_challenge", pkceChallenge(verifier));
21363
21455
  authorizeUrl.searchParams.set("redirect_uri", callback.redirectUri);
21364
- input.writeOutput(`Opening ${authorizeUrl.toString()}`);
21365
- input.writeOutput("Waiting for browser authorization...");
21456
+ input.writeOutput(`Opening ${style.url(authorizeUrl.toString())}`);
21457
+ input.writeOutput(style.dim("Waiting for browser authorization..."));
21366
21458
  openBrowser(authorizeUrl.toString());
21367
21459
  const { code } = await callback.result;
21368
21460
  const token3 = await exchangeAuthorizationCode({
@@ -21377,7 +21469,8 @@ async function login(input) {
21377
21469
  serverUrl,
21378
21470
  fetch: input.fetch,
21379
21471
  configPath: input.configPath,
21380
- writeOutput: input.writeOutput
21472
+ writeOutput: input.writeOutput,
21473
+ style
21381
21474
  });
21382
21475
  return;
21383
21476
  } finally {
@@ -21396,7 +21489,8 @@ async function login(input) {
21396
21489
  serverUrl,
21397
21490
  fetch: input.fetch,
21398
21491
  configPath: input.configPath,
21399
- writeOutput: input.writeOutput
21492
+ writeOutput: input.writeOutput,
21493
+ style
21400
21494
  });
21401
21495
  }
21402
21496
  async function exchangeAuthorizationCode(input) {
@@ -21456,13 +21550,17 @@ async function finishLogin(input) {
21456
21550
  };
21457
21551
  } catch {
21458
21552
  input.writeOutput(
21459
- "The saved organization/project selection is not available for this account; run `auto orgs list` to pick a new one."
21553
+ input.style.warn(
21554
+ "The saved organization/project selection is not available for this account; run `auto orgs list` to pick a new one."
21555
+ )
21460
21556
  );
21461
21557
  }
21462
21558
  }
21463
21559
  writeConfig(config2, input.configPath);
21464
21560
  input.writeOutput(
21465
- token2.user ? `Logged in as ${token2.user.email}.` : "Logged in."
21561
+ input.style.success(
21562
+ token2.user ? `Logged in as ${token2.user.email}.` : "Logged in."
21563
+ )
21466
21564
  );
21467
21565
  }
21468
21566
  async function sleep(ms) {
@@ -21478,10 +21576,53 @@ var init_login = __esm({
21478
21576
  init_file();
21479
21577
  init_profiles2();
21480
21578
  init_loopback();
21579
+ init_style();
21481
21580
  init_pkce();
21482
21581
  }
21483
21582
  });
21484
21583
 
21584
+ // src/lib/resources.ts
21585
+ function parseProjectResourceReference(resource) {
21586
+ const [kind, name, extra] = resource.split("/");
21587
+ if (!kind || !name || extra) {
21588
+ throw new Error('Resource must be formatted as "kind/name"');
21589
+ }
21590
+ if (!PROJECT_RESOURCE_KINDS.includes(kind)) {
21591
+ throw new Error(
21592
+ `Unsupported resource kind "${kind}"; supported kinds are ${PROJECT_RESOURCE_KINDS.map((value) => `"${value}"`).join(", ")}`
21593
+ );
21594
+ }
21595
+ return { kind, name };
21596
+ }
21597
+ async function listProjectResources2(client, kind, options) {
21598
+ switch (kind) {
21599
+ case RESOURCE_KIND_ENVIRONMENT:
21600
+ return (await client.listEnvironments(options)).environments;
21601
+ case RESOURCE_KIND_PROFILE:
21602
+ return (await client.listProfiles(options)).profiles;
21603
+ case RESOURCE_KIND_TOOL:
21604
+ return (await client.listTools(options)).tools;
21605
+ case RESOURCE_KIND_SESSION:
21606
+ return (await client.listSessions(options)).sessions;
21607
+ }
21608
+ }
21609
+ async function requireProjectResource(client, reference, options) {
21610
+ const resources = await listProjectResources2(client, reference.kind, options);
21611
+ const resource = resources.find(
21612
+ (item) => item.metadata.name === reference.name
21613
+ );
21614
+ if (!resource) {
21615
+ throw new Error(`Resource not found: ${reference.kind}/${reference.name}`);
21616
+ }
21617
+ return resource;
21618
+ }
21619
+ var init_resources3 = __esm({
21620
+ "src/lib/resources.ts"() {
21621
+ "use strict";
21622
+ init_src();
21623
+ }
21624
+ });
21625
+
21485
21626
  // src/commands/edit/actions.ts
21486
21627
  import { spawn as spawn2 } from "child_process";
21487
21628
  import { mkdtempSync, readFileSync as readFileSync4, rmSync, writeFileSync as writeFileSync3 } from "fs";
@@ -21489,13 +21630,13 @@ import { tmpdir } from "os";
21489
21630
  import { join as join5 } from "path";
21490
21631
  import { parseAllDocuments as parseYamlDocuments2, stringify as stringify2 } from "yaml";
21491
21632
  async function editResource(input) {
21492
- const reference = parseEditableResource(input.resource);
21633
+ const reference = parseProjectResourceReference(input.resource);
21493
21634
  const editor = resolveEditor({
21494
21635
  canFallbackToVi: input.canFallbackToVi,
21495
21636
  env: input.env,
21496
21637
  explicit: input.commandOptions.editor
21497
21638
  });
21498
- const current = await getEditableResource(input.client, reference, {
21639
+ const current = await requireProjectResource(input.client, reference, {
21499
21640
  apiBaseUrl: input.commandOptions.apiBaseUrl
21500
21641
  });
21501
21642
  const document = editableResourceDocument(reference.kind, current);
@@ -21543,18 +21684,6 @@ Edited file retained at ${filePath}`);
21543
21684
  }
21544
21685
  }
21545
21686
  }
21546
- function parseEditableResource(resource) {
21547
- const [kind, name, extra] = resource.split("/");
21548
- if (!kind || !name || extra) {
21549
- throw new Error('Resource must be formatted as "kind/name"');
21550
- }
21551
- if (!RESOURCE_KINDS3.includes(kind)) {
21552
- throw new Error(
21553
- `Unsupported resource kind "${kind}"; supported kinds are ${RESOURCE_KINDS3.map((value) => `"${value}"`).join(", ")}`
21554
- );
21555
- }
21556
- return { kind, name };
21557
- }
21558
21687
  function resolveEditor(input) {
21559
21688
  const explicit = input.explicit?.trim();
21560
21689
  if (explicit) {
@@ -21629,44 +21758,12 @@ function editableResourceDocument(kind, resource) {
21629
21758
  spec: resource.spec
21630
21759
  };
21631
21760
  }
21632
- async function getEditableResource(client, reference, options) {
21633
- const resources = await listEditableResources(
21634
- client,
21635
- reference.kind,
21636
- options
21637
- );
21638
- const resource = resources.find(
21639
- (item) => item.metadata.name === reference.name
21640
- );
21641
- if (!resource) {
21642
- throw new Error(`Resource not found: ${reference.kind}/${reference.name}`);
21643
- }
21644
- return resource;
21645
- }
21646
- async function listEditableResources(client, kind, options) {
21647
- switch (kind) {
21648
- case RESOURCE_KIND_ENVIRONMENT:
21649
- return (await client.listEnvironments(options)).environments;
21650
- case RESOURCE_KIND_PROFILE:
21651
- return (await client.listProfiles(options)).profiles;
21652
- case RESOURCE_KIND_TOOL:
21653
- return (await client.listTools(options)).tools;
21654
- case RESOURCE_KIND_SESSION:
21655
- return (await client.listSessions(options)).sessions;
21656
- }
21657
- }
21658
- var RESOURCE_KINDS3;
21659
21761
  var init_actions2 = __esm({
21660
21762
  "src/commands/edit/actions.ts"() {
21661
21763
  "use strict";
21662
21764
  init_src();
21765
+ init_resources3();
21663
21766
  init_actions();
21664
- RESOURCE_KINDS3 = [
21665
- RESOURCE_KIND_ENVIRONMENT,
21666
- RESOURCE_KIND_PROFILE,
21667
- RESOURCE_KIND_TOOL,
21668
- RESOURCE_KIND_SESSION
21669
- ];
21670
21767
  }
21671
21768
  });
21672
21769
 
@@ -21761,7 +21858,7 @@ var init_package = __esm({
21761
21858
  "package.json"() {
21762
21859
  package_default = {
21763
21860
  name: "@autohq/cli",
21764
- version: "0.1.101",
21861
+ version: "0.1.103",
21765
21862
  license: "SEE LICENSE IN README.md",
21766
21863
  publishConfig: {
21767
21864
  access: "public"
@@ -28814,7 +28911,8 @@ function registerApplyCommands(program, context) {
28814
28911
  apiBaseUrl: apiUrlFromOptions(context, commandOptions)
28815
28912
  },
28816
28913
  client: createContextApiClient(context),
28817
- writeOutput: context.writeOutput
28914
+ writeOutput: context.writeOutput,
28915
+ style: context.io.style
28818
28916
  });
28819
28917
  });
28820
28918
  }
@@ -28848,7 +28946,7 @@ function logout(context) {
28848
28946
  },
28849
28947
  context.configPath
28850
28948
  );
28851
- context.writeOutput("Logged out.");
28949
+ context.writeOutput(context.io.style.success("Logged out."));
28852
28950
  }
28853
28951
  function switchAccount(context, accountEmail, options = {}) {
28854
28952
  const profiles = listProfiles(context.configPath);
@@ -28858,7 +28956,9 @@ function switchAccount(context, accountEmail, options = {}) {
28858
28956
  const active = readConfig(context.configPath);
28859
28957
  if (!accountEmail) {
28860
28958
  for (const profile of profiles) {
28861
- context.writeOutput(accountLine(profile.config, active));
28959
+ context.writeOutput(
28960
+ accountLine(profile.config, active, context.io.style)
28961
+ );
28862
28962
  }
28863
28963
  return;
28864
28964
  }
@@ -28879,20 +28979,26 @@ function switchAccount(context, accountEmail, options = {}) {
28879
28979
  );
28880
28980
  }
28881
28981
  writeConfig(match, context.configPath);
28882
- context.writeOutput(`Switched to ${match.userEmail} (${match.serverUrl}).`);
28982
+ context.writeOutput(
28983
+ context.io.style.success(
28984
+ `Switched to ${match.userEmail} (${match.serverUrl}).`
28985
+ )
28986
+ );
28883
28987
  if (!match.refreshToken) {
28884
28988
  context.writeOutput(
28885
- "This account has no stored credentials; run `auto auth login`."
28989
+ context.io.style.warn(
28990
+ "This account has no stored credentials; run `auto auth login`."
28991
+ )
28886
28992
  );
28887
28993
  }
28888
28994
  }
28889
- function accountLine(config2, active) {
28995
+ function accountLine(config2, active, style) {
28890
28996
  const isActive = Boolean(config2.userEmail) && config2.userEmail === active.userEmail && config2.serverUrl === active.serverUrl;
28891
28997
  return [
28892
28998
  config2.userEmail,
28893
- `server=${config2.serverUrl ?? "(unset)"}`,
28894
- config2.refreshToken ? void 0 : "logged_out",
28895
- isActive ? "(active)" : void 0
28999
+ style.dim(`server=${config2.serverUrl ?? "(unset)"}`),
29000
+ config2.refreshToken ? void 0 : style.warn("logged_out"),
29001
+ isActive ? style.success("(active)") : void 0
28896
29002
  ].filter(Boolean).join(" ");
28897
29003
  }
28898
29004
  async function fetchAuthStatus(context) {
@@ -28941,47 +29047,68 @@ async function fetchAuthStatus(context) {
28941
29047
  return { ...base, token: { state: "invalid", error: message } };
28942
29048
  }
28943
29049
  }
28944
- function formatAuthStatusText(result, writeLine) {
28945
- writeLine(`server: ${result.serverUrl ?? "(unset)"}`);
29050
+ function formatAuthStatusText(result, writeLine, style) {
29051
+ const unset = style.dim("(unset)");
29052
+ writeLine(
29053
+ `${style.label("server:")} ${result.serverUrl ? style.url(result.serverUrl) : unset}`
29054
+ );
28946
29055
  if (result.account) {
28947
- writeLine(`account: ${result.account}`);
29056
+ writeLine(`${style.label("account:")} ${result.account}`);
28948
29057
  }
28949
- writeLine(`organization: ${result.organizationId ?? "(unset)"}`);
28950
- writeLine(`project: ${result.projectId ?? "(unset)"}`);
28951
29058
  writeLine(
28952
- `auth: ${result.authSource === "unset" ? "(unset)" : result.authSource}`
29059
+ `${style.label("organization:")} ${result.organizationId ? style.id(result.organizationId) : unset}`
29060
+ );
29061
+ writeLine(
29062
+ `${style.label("project:")} ${result.projectId ? style.id(result.projectId) : unset}`
29063
+ );
29064
+ writeLine(
29065
+ `${style.label("auth:")} ${result.authSource === "unset" ? unset : result.authSource}`
28953
29066
  );
28954
29067
  switch (result.token.state) {
28955
29068
  case "unset":
28956
29069
  return;
28957
29070
  case "not_validated":
28958
- writeLine(`token: not validated (${result.token.reason})`);
29071
+ writeLine(
29072
+ `${style.label("token:")} ${style.warn(`not validated (${result.token.reason})`)}`
29073
+ );
28959
29074
  return;
28960
29075
  case "valid":
28961
- writeLine("token: valid");
29076
+ writeLine(`${style.label("token:")} ${style.success("valid")}`);
28962
29077
  return;
28963
29078
  case "invalid":
28964
- writeLine(`token: invalid \u2014 ${result.token.error}`);
28965
- writeLine("hint: run `auto auth login` to refresh credentials");
29079
+ writeLine(
29080
+ `${style.label("token:")} ${style.error(`invalid \u2014 ${result.token.error}`)}`
29081
+ );
29082
+ writeLine(
29083
+ style.dim("hint: run `auto auth login` to refresh credentials")
29084
+ );
28966
29085
  return;
28967
29086
  }
28968
29087
  }
28969
- function formatWhoamiText(whoami, writeLine) {
28970
- writeLine(`actor: ${actorLabel(whoami)}`);
29088
+ function formatWhoamiText(whoami, writeLine, style) {
29089
+ writeLine(`${style.label("actor:")} ${actorLabel(whoami)}`);
28971
29090
  if (whoami.serviceAccount) {
28972
- writeLine(`service_account: ${whoami.serviceAccount.name}`);
29091
+ writeLine(
29092
+ `${style.label("service_account:")} ${style.id(whoami.serviceAccount.name)}`
29093
+ );
28973
29094
  }
28974
- writeLine(`organization: ${whoami.organizationId}`);
28975
- writeLine(`project: ${whoami.projectId ?? "(unset)"}`);
29095
+ writeLine(
29096
+ `${style.label("organization:")} ${style.id(whoami.organizationId)}`
29097
+ );
29098
+ writeLine(
29099
+ `${style.label("project:")} ${whoami.projectId ? style.id(whoami.projectId) : style.dim("(unset)")}`
29100
+ );
28976
29101
  const organizationName = whoami.organizationName ?? whoami.serviceAccount?.organization.name;
28977
29102
  const projectName = whoami.projectName ?? whoami.serviceAccount?.project.name;
28978
29103
  if (organizationName) {
28979
- writeLine(`organization_name: ${organizationName}`);
29104
+ writeLine(`${style.label("organization_name:")} ${organizationName}`);
28980
29105
  }
28981
29106
  if (projectName) {
28982
- writeLine(`project_name: ${projectName}`);
29107
+ writeLine(`${style.label("project_name:")} ${projectName}`);
28983
29108
  }
28984
- writeLine(`scopes: ${formatScopes(whoami.scopes)}`);
29109
+ writeLine(
29110
+ `${style.label("scopes:")} ${style.dim(formatScopes(whoami.scopes))}`
29111
+ );
28985
29112
  }
28986
29113
  function actorLabel(whoami) {
28987
29114
  const { principal } = whoami.actor;
@@ -29046,7 +29173,8 @@ function registerAuthCommands(program, context) {
29046
29173
  fetch: context.fetch,
29047
29174
  configPath: context.configPath,
29048
29175
  writeOutput: context.writeOutput,
29049
- writeError: context.writeError
29176
+ writeError: context.writeError,
29177
+ style: context.io.style
29050
29178
  });
29051
29179
  });
29052
29180
  auth.command("status").description(
@@ -29098,7 +29226,7 @@ async function confirmDestructiveAction(context, input) {
29098
29226
  }
29099
29227
 
29100
29228
  // src/commands/connections/format.ts
29101
- function connectionRows(connections) {
29229
+ function connectionRows(connections, style) {
29102
29230
  const rows = connections.flatMap(
29103
29231
  (connection) => connection.grants.map((grant) => ({
29104
29232
  provider: connection.provider,
@@ -29114,7 +29242,7 @@ function connectionRows(connections) {
29114
29242
  }))
29115
29243
  );
29116
29244
  if (rows.length === 0) {
29117
- return ["No connections found."];
29245
+ return [style.dim("No connections found.")];
29118
29246
  }
29119
29247
  const headers = {
29120
29248
  provider: "provider",
@@ -29132,18 +29260,25 @@ function connectionRows(connections) {
29132
29260
  )
29133
29261
  ])
29134
29262
  );
29263
+ const headerLine = [
29264
+ headers.provider.padEnd(widths.provider),
29265
+ headers.account.padEnd(widths.account),
29266
+ headers.grant.padEnd(widths.grant),
29267
+ headers.status.padEnd(widths.status),
29268
+ headers.projects
29269
+ ].join(" ");
29135
29270
  const format = (row) => [
29136
29271
  row.provider.padEnd(widths.provider),
29137
29272
  row.account.padEnd(widths.account),
29138
- row.grant.padEnd(widths.grant),
29139
- row.status.padEnd(widths.status),
29140
- row.projects
29273
+ style.id(row.grant.padEnd(widths.grant)),
29274
+ grantStatusStyle(style, row.status)(row.status.padEnd(widths.status)),
29275
+ style.dim(row.projects)
29141
29276
  ].join(" ");
29142
- return [format(headers), ...rows.map(format)];
29277
+ return [style.heading(headerLine), ...rows.map(format)];
29143
29278
  }
29144
- function providerRows(providers) {
29279
+ function providerRows(providers, style) {
29145
29280
  if (providers.length === 0) {
29146
- return ["No connection providers found."];
29281
+ return [style.dim("No connection providers found.")];
29147
29282
  }
29148
29283
  const rows = providers.map((provider) => ({
29149
29284
  provider: provider.provider,
@@ -29167,9 +29302,26 @@ function providerRows(providers) {
29167
29302
  const format = (row) => [
29168
29303
  row.provider.padEnd(widths.provider),
29169
29304
  row.name.padEnd(widths.name),
29170
- row.credential
29305
+ style.dim(row.credential)
29171
29306
  ].join(" ");
29172
- return [format(headers), ...rows.map(format)];
29307
+ const headerLine = [
29308
+ headers.provider.padEnd(widths.provider),
29309
+ headers.name.padEnd(widths.name),
29310
+ headers.credential
29311
+ ].join(" ");
29312
+ return [style.heading(headerLine), ...rows.map(format)];
29313
+ }
29314
+ function grantStatusStyle(style, status) {
29315
+ switch (status) {
29316
+ case "active":
29317
+ return style.success;
29318
+ case "error":
29319
+ return style.error;
29320
+ case "revoked":
29321
+ return style.dim;
29322
+ default:
29323
+ return (text) => text;
29324
+ }
29173
29325
  }
29174
29326
  function projectSummary(connection) {
29175
29327
  const projectIds = [
@@ -29581,7 +29733,7 @@ async function listConnectionsAction(context, commandOptions) {
29581
29733
  ).listConnectionProviders({
29582
29734
  apiBaseUrl
29583
29735
  });
29584
- for (const row of providerRows(result2.providers)) {
29736
+ for (const row of providerRows(result2.providers, context.io.style)) {
29585
29737
  context.writeOutput(row);
29586
29738
  }
29587
29739
  return;
@@ -29590,7 +29742,7 @@ async function listConnectionsAction(context, commandOptions) {
29590
29742
  provider: commandOptions.provider,
29591
29743
  apiBaseUrl
29592
29744
  });
29593
- for (const row of connectionRows(result.connections)) {
29745
+ for (const row of connectionRows(result.connections, context.io.style)) {
29594
29746
  context.writeOutput(row);
29595
29747
  }
29596
29748
  }
@@ -29637,11 +29789,14 @@ async function connectProviderAction(context, provider, commandOptions) {
29637
29789
  allowProjectId: commandOptions.allow,
29638
29790
  apiBaseUrl
29639
29791
  });
29792
+ const style = context.io.style;
29640
29793
  context.writeOutput(result.message);
29641
29794
  if (!result.authorizationUrl) {
29642
29795
  return;
29643
29796
  }
29644
- context.writeOutput(`authorization_url ${result.authorizationUrl}`);
29797
+ context.writeOutput(
29798
+ `${style.label("authorization_url")} ${style.url(result.authorizationUrl)}`
29799
+ );
29645
29800
  const connected = await finishConnectionAuthorization({
29646
29801
  apiBaseUrl,
29647
29802
  authorizationUrl: result.authorizationUrl,
@@ -29665,7 +29820,9 @@ async function connectProviderAction(context, provider, commandOptions) {
29665
29820
  apiBaseUrl
29666
29821
  });
29667
29822
  context.writeOutput(
29668
- `registered slack config token connection/${registered.connection} workspace/${registered.workspace}`
29823
+ style.success(
29824
+ `registered slack config token connection/${registered.connection} workspace/${registered.workspace}`
29825
+ )
29669
29826
  );
29670
29827
  }
29671
29828
  }
@@ -29691,10 +29848,15 @@ async function registerConfigTokenAction(context, provider, commandOptions) {
29691
29848
  refreshToken,
29692
29849
  apiBaseUrl: apiUrlFromOptions(context, commandOptions)
29693
29850
  });
29851
+ const style = context.io.style;
29694
29852
  context.writeOutput(
29695
- `registered slack config token connection/${result.connection} workspace/${result.workspace}`
29853
+ style.success(
29854
+ `registered slack config token connection/${result.connection} workspace/${result.workspace}`
29855
+ )
29856
+ );
29857
+ context.writeOutput(
29858
+ `${style.label("expires_at")} ${style.dim(result.expiresAt)}`
29696
29859
  );
29697
- context.writeOutput(`expires_at ${result.expiresAt}`);
29698
29860
  }
29699
29861
  async function readTrimmedStream(stream) {
29700
29862
  const chunks = [];
@@ -29749,7 +29911,11 @@ async function replaceConnectionAction(context, provider, commandOptions) {
29749
29911
  if (!result.authorizationUrl) {
29750
29912
  return;
29751
29913
  }
29752
- context.writeOutput(`authorization_url ${result.authorizationUrl}`);
29914
+ context.writeOutput(
29915
+ `${context.io.style.label("authorization_url")} ${context.io.style.url(
29916
+ result.authorizationUrl
29917
+ )}`
29918
+ );
29753
29919
  await finishConnectionAuthorization({
29754
29920
  apiBaseUrl,
29755
29921
  authorizationUrl: result.authorizationUrl,
@@ -29828,15 +29994,9 @@ function registerConnectionCommands(program, context) {
29828
29994
  }
29829
29995
 
29830
29996
  // src/commands/delete/actions.ts
29831
- init_src();
29832
- var RESOURCE_KINDS = [
29833
- RESOURCE_KIND_ENVIRONMENT,
29834
- RESOURCE_KIND_PROFILE,
29835
- RESOURCE_KIND_TOOL,
29836
- RESOURCE_KIND_SESSION
29837
- ];
29997
+ init_resources3();
29838
29998
  async function deleteResource(input) {
29839
- const request = parseDeleteResource(input.resource);
29999
+ const request = parseProjectResourceReference(input.resource);
29840
30000
  const response = await input.client.deleteProjectResource(request, {
29841
30001
  apiBaseUrl: input.commandOptions.apiBaseUrl
29842
30002
  });
@@ -29848,18 +30008,6 @@ async function deleteResource(input) {
29848
30008
  `deleted ${response.deleted.kind}/${response.deleted.name}`
29849
30009
  );
29850
30010
  }
29851
- function parseDeleteResource(resource) {
29852
- const [kind, name, extra] = resource.split("/");
29853
- if (!kind || !name || extra) {
29854
- throw new Error('Resource must be formatted as "kind/name"');
29855
- }
29856
- if (!RESOURCE_KINDS.includes(kind)) {
29857
- throw new Error(
29858
- `Unsupported resource kind "${kind}"; supported kinds are ${RESOURCE_KINDS.map((value) => `"${value}"`).join(", ")}`
29859
- );
29860
- }
29861
- return { kind, name };
29862
- }
29863
30011
 
29864
30012
  // src/commands/delete/commands.ts
29865
30013
  function registerDeleteCommands(program, context) {
@@ -29881,55 +30029,15 @@ function registerDeleteCommands(program, context) {
29881
30029
  }
29882
30030
 
29883
30031
  // src/commands/describe/actions.ts
29884
- init_src();
30032
+ init_resources3();
29885
30033
  import { stringify } from "yaml";
29886
- var RESOURCE_KINDS2 = [
29887
- RESOURCE_KIND_ENVIRONMENT,
29888
- RESOURCE_KIND_PROFILE,
29889
- RESOURCE_KIND_TOOL,
29890
- RESOURCE_KIND_SESSION
29891
- ];
29892
30034
  async function inspectResource(input) {
29893
- const request = parseInspectResource(input.resource);
29894
- const resource = await getResource(input.client, request, {
30035
+ const request = parseProjectResourceReference(input.resource);
30036
+ const resource = await requireProjectResource(input.client, request, {
29895
30037
  apiBaseUrl: input.commandOptions.apiBaseUrl
29896
30038
  });
29897
30039
  input.writeOutput(stringify(resource.spec).trimEnd());
29898
30040
  }
29899
- function parseInspectResource(resource) {
29900
- const [kind, name, extra] = resource.split("/");
29901
- if (!kind || !name || extra) {
29902
- throw new Error('Resource must be formatted as "kind/name"');
29903
- }
29904
- if (!RESOURCE_KINDS2.includes(kind)) {
29905
- throw new Error(
29906
- `Unsupported resource kind "${kind}"; supported kinds are ${RESOURCE_KINDS2.map((value) => `"${value}"`).join(", ")}`
29907
- );
29908
- }
29909
- return { kind, name };
29910
- }
29911
- async function getResource(client, request, options) {
29912
- const resources = await listResources(client, request.kind, options);
29913
- const resource = resources.find(
29914
- (item) => item.metadata.name === request.name
29915
- );
29916
- if (!resource) {
29917
- throw new Error(`Resource not found: ${request.kind}/${request.name}`);
29918
- }
29919
- return resource;
29920
- }
29921
- async function listResources(client, kind, options) {
29922
- switch (kind) {
29923
- case RESOURCE_KIND_ENVIRONMENT:
29924
- return (await client.listEnvironments(options)).environments;
29925
- case RESOURCE_KIND_PROFILE:
29926
- return (await client.listProfiles(options)).profiles;
29927
- case RESOURCE_KIND_TOOL:
29928
- return (await client.listTools(options)).tools;
29929
- case RESOURCE_KIND_SESSION:
29930
- return (await client.listSessions(options)).sessions;
29931
- }
29932
- }
29933
30041
 
29934
30042
  // src/commands/describe/commands.ts
29935
30043
  function registerDescribeCommands(program, context) {
@@ -29970,11 +30078,17 @@ init_file();
29970
30078
  function createDirectoryClient(context) {
29971
30079
  return createContextApiClient(context);
29972
30080
  }
29973
- function organizationLine(organization) {
29974
- return `${organization.organizationName} (${organization.organizationSlug}) role=${organization.role}`;
30081
+ function organizationLine(organization, style) {
30082
+ return `${organization.organizationName} ${style.id(
30083
+ `(${organization.organizationSlug})`
30084
+ )} ${style.dim(`role=${organization.role}`)}`;
29975
30085
  }
29976
- function projectLine(project) {
29977
- return `${project.organizationName} (${project.organizationSlug}) / ${project.projectName} (${project.projectSlug}) role=${project.role}`;
30086
+ function projectLine(project, style) {
30087
+ return `${project.organizationName} ${style.id(
30088
+ `(${project.organizationSlug})`
30089
+ )} / ${project.projectName} ${style.id(`(${project.projectSlug})`)} ${style.dim(
30090
+ `role=${project.role}`
30091
+ )}`;
29978
30092
  }
29979
30093
  function setActiveOrganization(context, organizationId) {
29980
30094
  persistActiveOrganization(context.configPath, organizationId);
@@ -30131,10 +30245,13 @@ function registerOrganizationCommands(program, context) {
30131
30245
  const orgs = program.command("orgs").description("Manage the active organization.");
30132
30246
  orgs.command("use").argument("<organization>").option("--api-url <url>", "Auto API base URL").option("--server <url>", "Auto web server URL").description("Set the active organization.").action(
30133
30247
  async (organizationIdentifier, options) => {
30248
+ const style = context.io.style;
30134
30249
  if (organizationIdentifier.startsWith("org_")) {
30135
30250
  setActiveOrganization(context, organizationIdentifier);
30136
30251
  context.writeOutput(
30137
- `Active organization set to ${organizationIdentifier}`
30252
+ style.success(
30253
+ `Active organization set to ${organizationIdentifier}`
30254
+ )
30138
30255
  );
30139
30256
  return;
30140
30257
  }
@@ -30145,7 +30262,9 @@ function registerOrganizationCommands(program, context) {
30145
30262
  });
30146
30263
  setActiveOrganization(context, organization.organizationId);
30147
30264
  context.writeOutput(
30148
- `Active organization set to ${organization.organizationName}`
30265
+ style.success(
30266
+ `Active organization set to ${organization.organizationName}`
30267
+ )
30149
30268
  );
30150
30269
  }
30151
30270
  );
@@ -30154,22 +30273,23 @@ function registerOrganizationCommands(program, context) {
30154
30273
  apiBaseUrl: apiUrlFromOptions(context, options)
30155
30274
  });
30156
30275
  if (response.organizations.length === 0) {
30157
- context.writeOutput("No organizations found.");
30276
+ context.writeOutput(context.io.style.dim("No organizations found."));
30158
30277
  return;
30159
30278
  }
30160
30279
  for (const organization of response.organizations) {
30161
- context.writeOutput(organizationLine(organization));
30280
+ context.writeOutput(organizationLine(organization, context.io.style));
30162
30281
  }
30163
30282
  });
30164
30283
  orgs.command("create").description("Create an organization, optionally with an initial project.").requiredOption("--name <name>", "Organization name").option("--project-name <name>", "Initial project name").option("--api-url <url>", "Auto API base URL").option("--server <url>", "Auto web server URL").option("--use", "Set the new organization or project as active", true).option("--no-use", "Keep the current active organization and project").action(async (options) => {
30284
+ const style = context.io.style;
30165
30285
  const response = await createDirectoryClient(context).createOrganization({
30166
30286
  organizationName: options.name,
30167
30287
  projectName: options.projectName,
30168
30288
  apiBaseUrl: apiUrlFromOptions(context, options)
30169
30289
  });
30170
- context.writeOutput(organizationLine(response.organization));
30290
+ context.writeOutput(organizationLine(response.organization, style));
30171
30291
  if (response.project) {
30172
- context.writeOutput(projectLine(response.project));
30292
+ context.writeOutput(projectLine(response.project, style));
30173
30293
  }
30174
30294
  if (options.use) {
30175
30295
  if (response.project) {
@@ -30178,11 +30298,15 @@ function registerOrganizationCommands(program, context) {
30178
30298
  setActiveOrganization(context, response.organization.organizationId);
30179
30299
  }
30180
30300
  context.writeOutput(
30181
- `Active organization set to ${response.organization.organizationName}`
30301
+ style.success(
30302
+ `Active organization set to ${response.organization.organizationName}`
30303
+ )
30182
30304
  );
30183
30305
  if (response.project) {
30184
30306
  context.writeOutput(
30185
- `Active project set to ${response.project.projectName}`
30307
+ style.success(
30308
+ `Active project set to ${response.project.projectName}`
30309
+ )
30186
30310
  );
30187
30311
  }
30188
30312
  }
@@ -30197,9 +30321,12 @@ function registerOrganizationCommands(program, context) {
30197
30321
  role: options.role,
30198
30322
  apiBaseUrl: apiUrlFromOptions(context, options)
30199
30323
  });
30200
- const status = response.created === false ? "Invitation already pending" : "Invited";
30324
+ const style = context.io.style;
30325
+ const status = response.created === false ? style.warn("Invitation already pending") : style.success("Invited");
30201
30326
  context.writeOutput(
30202
- `${status} ${response.invitation.targetEmail} to ${response.invitation.organizationName} role=${response.invitation.role}`
30327
+ `${status} ${response.invitation.targetEmail} to ${response.invitation.organizationName} ${style.dim(
30328
+ `role=${response.invitation.role}`
30329
+ )}`
30203
30330
  );
30204
30331
  });
30205
30332
  const members = orgs.command("members").description("Manage active organization members.");
@@ -30210,11 +30337,13 @@ function registerOrganizationCommands(program, context) {
30210
30337
  apiBaseUrl: apiUrlFromOptions(context, options)
30211
30338
  });
30212
30339
  if (response.memberships.length === 0) {
30213
- context.writeOutput("No organization members found.");
30340
+ context.writeOutput(
30341
+ context.io.style.dim("No organization members found.")
30342
+ );
30214
30343
  return;
30215
30344
  }
30216
30345
  for (const member of response.memberships) {
30217
- context.writeOutput(memberLine(member));
30346
+ context.writeOutput(memberLine(member, context.io.style));
30218
30347
  }
30219
30348
  });
30220
30349
  members.command("add").description("Invite a user to the active organization by email.").requiredOption("--email <email>", "Email address to invite").addOption(
@@ -30227,9 +30356,12 @@ function registerOrganizationCommands(program, context) {
30227
30356
  role: options.role,
30228
30357
  apiBaseUrl: apiUrlFromOptions(context, options)
30229
30358
  });
30230
- const status = response.created === false ? "Invitation already pending" : "Invited";
30359
+ const style = context.io.style;
30360
+ const status = response.created === false ? style.warn("Invitation already pending") : style.success("Invited");
30231
30361
  context.writeOutput(
30232
- `${status} ${response.invitation.targetEmail} to ${response.invitation.organizationName} role=${response.invitation.role}`
30362
+ `${status} ${response.invitation.targetEmail} to ${response.invitation.organizationName} ${style.dim(
30363
+ `role=${response.invitation.role}`
30364
+ )}`
30233
30365
  );
30234
30366
  });
30235
30367
  members.command("set-role").description("Set an existing active organization member's role.").requiredOption("--email <email>", "Email address of an existing member").addOption(
@@ -30242,9 +30374,12 @@ function registerOrganizationCommands(program, context) {
30242
30374
  role: options.role,
30243
30375
  apiBaseUrl: apiUrlFromOptions(context, options)
30244
30376
  });
30245
- const status = response.updated ? "Updated" : "Unchanged";
30377
+ const style = context.io.style;
30378
+ const status = response.updated ? style.success("Updated") : style.dim("Unchanged");
30246
30379
  context.writeOutput(
30247
- `${status} ${options.email} in ${response.membership.organizationName} role=${response.previousRole}->${response.membership.role}`
30380
+ `${status} ${options.email} in ${response.membership.organizationName} ${style.dim(
30381
+ `role=${response.previousRole}->${response.membership.role}`
30382
+ )}`
30248
30383
  );
30249
30384
  });
30250
30385
  members.command("remove").description("Remove a user from the active organization.").requiredOption("--email <email>", "Email address of an existing member").option("-y, --yes", "skip confirmation prompt").option("--api-url <url>", "Auto API base URL").option("--server <url>", "Auto web server URL").action(async (options) => {
@@ -30258,17 +30393,20 @@ function registerOrganizationCommands(program, context) {
30258
30393
  email: options.email,
30259
30394
  apiBaseUrl: apiUrlFromOptions(context, options)
30260
30395
  });
30396
+ const style = context.io.style;
30261
30397
  context.writeOutput(
30262
- `Removed ${options.email} from ${response.membership.organizationName} role=${response.previousRole} project_memberships=${response.removedProjectMemberships ?? 0}`
30398
+ `${style.success("Removed")} ${options.email} from ${response.membership.organizationName} ${style.dim(
30399
+ `role=${response.previousRole} project_memberships=${response.removedProjectMemberships ?? 0}`
30400
+ )}`
30263
30401
  );
30264
30402
  });
30265
30403
  }
30266
- function memberLine(member) {
30404
+ function memberLine(member, style) {
30267
30405
  return [
30268
30406
  member.primaryEmail,
30269
- `role=${member.role}`,
30270
- member.displayName ? `name=${member.displayName}` : void 0,
30271
- member.disabledAt ? `disabled_at=${member.disabledAt}` : void 0
30407
+ style.dim(`role=${member.role}`),
30408
+ member.displayName ? style.dim(`name=${member.displayName}`) : void 0,
30409
+ member.disabledAt ? style.warn(`disabled_at=${member.disabledAt}`) : void 0
30272
30410
  ].filter(Boolean).join(" ");
30273
30411
  }
30274
30412
 
@@ -30289,15 +30427,13 @@ async function fetchProjects(context, options) {
30289
30427
  });
30290
30428
  return { projects: response.projects };
30291
30429
  }
30292
- function formatProjectsText(result, writeLine) {
30430
+ function formatProjectsText(result, writeLine, style) {
30293
30431
  if (result.projects.length === 0) {
30294
- writeLine("No projects found.");
30432
+ writeLine(style.dim("No projects found."));
30295
30433
  return;
30296
30434
  }
30297
30435
  for (const project of result.projects) {
30298
- writeLine(
30299
- `${project.organizationName} (${project.organizationSlug}) / ${project.projectName} (${project.projectSlug}) role=${project.role}`
30300
- );
30436
+ writeLine(projectLine(project, style));
30301
30437
  }
30302
30438
  }
30303
30439
 
@@ -30306,13 +30442,16 @@ function registerProjectCommands(program, context) {
30306
30442
  const projects = program.command("projects").description("List, create, and select Auto projects.");
30307
30443
  projects.command("use").argument("<project>").option("--api-url <url>", "Auto API base URL").option("--server <url>", "Auto web server URL").description("Set the active project.").action(
30308
30444
  async (projectIdentifier, options) => {
30445
+ const style = context.io.style;
30309
30446
  if (projectIdentifier.startsWith("proj_")) {
30310
30447
  const config2 = readConfig(context.configPath);
30311
30448
  writeConfig(
30312
30449
  clearAccessToken({ ...config2, projectId: projectIdentifier }),
30313
30450
  context.configPath
30314
30451
  );
30315
- context.writeOutput(`Active project set to ${projectIdentifier}`);
30452
+ context.writeOutput(
30453
+ style.success(`Active project set to ${projectIdentifier}`)
30454
+ );
30316
30455
  return;
30317
30456
  }
30318
30457
  const project = await resolveProject({
@@ -30323,9 +30462,13 @@ function registerProjectCommands(program, context) {
30323
30462
  });
30324
30463
  setActiveProject(context, project);
30325
30464
  context.writeOutput(
30326
- `Active organization set to ${project.organizationName}`
30465
+ style.success(
30466
+ `Active organization set to ${project.organizationName}`
30467
+ )
30468
+ );
30469
+ context.writeOutput(
30470
+ style.success(`Active project set to ${project.projectName}`)
30327
30471
  );
30328
- context.writeOutput(`Active project set to ${project.projectName}`);
30329
30472
  }
30330
30473
  );
30331
30474
  projects.command("list").description(
@@ -30334,18 +30477,23 @@ function registerProjectCommands(program, context) {
30334
30477
  await handleProjectsList(context, options);
30335
30478
  });
30336
30479
  projects.command("create").description("Create a project in the active organization.").requiredOption("--name <name>", "Project name").option("--api-url <url>", "Auto API base URL").option("--server <url>", "Auto web server URL").option("--use", "Set the new project as active", true).option("--no-use", "Keep the current active project").action(async (options) => {
30480
+ const style = context.io.style;
30337
30481
  const response = await createDirectoryClient(context).createProject({
30338
30482
  projectName: options.name,
30339
30483
  apiBaseUrl: apiUrlFromOptions(context, options)
30340
30484
  });
30341
- context.writeOutput(projectLine(response.project));
30485
+ context.writeOutput(projectLine(response.project, style));
30342
30486
  if (options.use) {
30343
30487
  setActiveProject(context, response.project);
30344
30488
  context.writeOutput(
30345
- `Active organization set to ${response.project.organizationName}`
30489
+ style.success(
30490
+ `Active organization set to ${response.project.organizationName}`
30491
+ )
30346
30492
  );
30347
30493
  context.writeOutput(
30348
- `Active project set to ${response.project.projectName}`
30494
+ style.success(
30495
+ `Active project set to ${response.project.projectName}`
30496
+ )
30349
30497
  );
30350
30498
  }
30351
30499
  });
@@ -30359,9 +30507,12 @@ function registerProjectCommands(program, context) {
30359
30507
  apiBaseUrl: apiUrlFromOptions(context, options)
30360
30508
  }
30361
30509
  );
30362
- const status = response.created === false ? "Invitation already pending" : "Invited";
30510
+ const style = context.io.style;
30511
+ const status = response.created === false ? style.warn("Invitation already pending") : style.success("Invited");
30363
30512
  context.writeOutput(
30364
- `${status} ${response.invitation.targetEmail} to ${response.invitation.projectName} role=${response.invitation.role}`
30513
+ `${status} ${response.invitation.targetEmail} to ${response.invitation.projectName} ${style.dim(
30514
+ `role=${response.invitation.role}`
30515
+ )}`
30365
30516
  );
30366
30517
  });
30367
30518
  const members = projects.command("members").description("Manage active project members.");
@@ -30370,11 +30521,11 @@ function registerProjectCommands(program, context) {
30370
30521
  apiBaseUrl: apiUrlFromOptions(context, options)
30371
30522
  });
30372
30523
  if (response.memberships.length === 0) {
30373
- context.writeOutput("No project members found.");
30524
+ context.writeOutput(context.io.style.dim("No project members found."));
30374
30525
  return;
30375
30526
  }
30376
30527
  for (const member of response.memberships) {
30377
- context.writeOutput(memberLine2(member));
30528
+ context.writeOutput(memberLine2(member, context.io.style));
30378
30529
  }
30379
30530
  });
30380
30531
  members.command("add").description("Invite a user to the active project by email.").requiredOption("--email <email>", "Email address to invite").addOption(
@@ -30385,9 +30536,12 @@ function registerProjectCommands(program, context) {
30385
30536
  role: options.role,
30386
30537
  apiBaseUrl: apiUrlFromOptions(context, options)
30387
30538
  });
30388
- const status = response.created === false ? "Invitation already pending" : "Invited";
30539
+ const style = context.io.style;
30540
+ const status = response.created === false ? style.warn("Invitation already pending") : style.success("Invited");
30389
30541
  context.writeOutput(
30390
- `${status} ${response.invitation.targetEmail} to ${response.invitation.projectName} role=${response.invitation.role}`
30542
+ `${status} ${response.invitation.targetEmail} to ${response.invitation.projectName} ${style.dim(
30543
+ `role=${response.invitation.role}`
30544
+ )}`
30391
30545
  );
30392
30546
  });
30393
30547
  members.command("set-role").description("Set an existing active project member's role.").requiredOption("--email <email>", "Email address of an existing member").addOption(
@@ -30400,9 +30554,12 @@ function registerProjectCommands(program, context) {
30400
30554
  role: options.role,
30401
30555
  apiBaseUrl: apiUrlFromOptions(context, options)
30402
30556
  });
30403
- const status = response.updated ? "Updated" : "Unchanged";
30557
+ const style = context.io.style;
30558
+ const status = response.updated ? style.success("Updated") : style.dim("Unchanged");
30404
30559
  context.writeOutput(
30405
- `${status} ${options.email} in ${response.membership.projectName} role=${response.previousRole}->${response.membership.role}`
30560
+ `${status} ${options.email} in ${response.membership.projectName} ${style.dim(
30561
+ `role=${response.previousRole}->${response.membership.role}`
30562
+ )}`
30406
30563
  );
30407
30564
  });
30408
30565
  members.command("remove").description("Remove a user from the active project.").requiredOption("--email <email>", "Email address of an existing member").option("-y, --yes", "skip confirmation prompt").option("--api-url <url>", "Auto API base URL").option("--server <url>", "Auto web server URL").action(async (options) => {
@@ -30416,17 +30573,20 @@ function registerProjectCommands(program, context) {
30416
30573
  apiBaseUrl: apiUrlFromOptions(context, options)
30417
30574
  }
30418
30575
  );
30576
+ const style = context.io.style;
30419
30577
  context.writeOutput(
30420
- `Removed ${options.email} from ${response.membership.projectName} role=${response.previousRole}`
30578
+ `${style.success("Removed")} ${options.email} from ${response.membership.projectName} ${style.dim(
30579
+ `role=${response.previousRole}`
30580
+ )}`
30421
30581
  );
30422
30582
  });
30423
30583
  }
30424
- function memberLine2(member) {
30584
+ function memberLine2(member, style) {
30425
30585
  return [
30426
30586
  member.primaryEmail,
30427
- `role=${member.role}`,
30428
- member.displayName ? `name=${member.displayName}` : void 0,
30429
- member.disabledAt ? `disabled_at=${member.disabledAt}` : void 0
30587
+ style.dim(`role=${member.role}`),
30588
+ member.displayName ? style.dim(`name=${member.displayName}`) : void 0,
30589
+ member.disabledAt ? style.warn(`disabled_at=${member.disabledAt}`) : void 0
30430
30590
  ].filter(Boolean).join(" ");
30431
30591
  }
30432
30592
 
@@ -30645,6 +30805,61 @@ function pollUntilFailed(input) {
30645
30805
  return { done, cancel };
30646
30806
  }
30647
30807
 
30808
+ // src/commands/runs/list.ts
30809
+ async function handleRunsList(context, sessionName, options = {}) {
30810
+ const result = await fetchRuns(context, sessionName, options);
30811
+ context.io.writeResult(result, formatRunsText);
30812
+ }
30813
+ async function fetchRuns(context, sessionName, options) {
30814
+ const client = createContextApiClient(context);
30815
+ const clientOptions = {
30816
+ apiBaseUrl: apiUrlFromOptions(context, options),
30817
+ includeArchived: options.includeArchived,
30818
+ statuses: options.status,
30819
+ since: options.since,
30820
+ limit: options.limit
30821
+ };
30822
+ const response = sessionName ? await client.listSessionRuns(sessionName, clientOptions) : await client.listRuns(clientOptions);
30823
+ return {
30824
+ session: sessionName ?? null,
30825
+ runs: response.runs,
30826
+ includeArchived: Boolean(options.includeArchived)
30827
+ };
30828
+ }
30829
+ function formatRunsText(result, writeLine, style) {
30830
+ if (result.runs.length === 0) {
30831
+ writeLine(
30832
+ style.dim(
30833
+ result.session ? `No runs found for session ${result.session}.` : "No runs found in the current project."
30834
+ )
30835
+ );
30836
+ return;
30837
+ }
30838
+ for (const run of result.runs) {
30839
+ const archived = run.archivedAt ? ` ${style.dim(`archived_at=${run.archivedAt}`)}` : "";
30840
+ writeLine(
30841
+ `${style.id(run.id)} ${styleRunStatus(style, run.status)} ${style.dim(
30842
+ run.createdAt
30843
+ )}${archived}`
30844
+ );
30845
+ }
30846
+ }
30847
+ function styleRunStatus(style, status) {
30848
+ switch (status) {
30849
+ case "failed":
30850
+ return style.error(status);
30851
+ case "running":
30852
+ return style.success(status);
30853
+ case "awaiting":
30854
+ return style.warn(status);
30855
+ case "stopped":
30856
+ case "queued":
30857
+ return style.dim(status);
30858
+ default:
30859
+ return status;
30860
+ }
30861
+ }
30862
+
30648
30863
  // src/commands/runs/service.ts
30649
30864
  function createRunServiceClient(context) {
30650
30865
  return createContextApiClient(context);
@@ -30659,9 +30874,14 @@ async function interactiveRunAction(context, sessionName, commandOptions) {
30659
30874
  interactive: true,
30660
30875
  apiBaseUrl
30661
30876
  });
30662
- context.writeOutput(`run_id ${created.run_id}`);
30663
- context.writeOutput(`workflow_id ${created.workflow_id}`);
30664
- context.writeOutput(`status ${created.status}`);
30877
+ const style = context.io.style;
30878
+ context.writeOutput(`${style.label("run_id")} ${style.id(created.run_id)}`);
30879
+ context.writeOutput(
30880
+ `${style.label("workflow_id")} ${style.id(created.workflow_id)}`
30881
+ );
30882
+ context.writeOutput(
30883
+ `${style.label("status")} ${styleRunStatus(style, created.status)}`
30884
+ );
30665
30885
  await runConsole({
30666
30886
  client,
30667
30887
  runId: created.run_id,
@@ -30687,35 +30907,50 @@ async function archiveRunAction(context, runId, commandOptions) {
30687
30907
  const run = await createRunServiceClient(context).archiveRun(runId, {
30688
30908
  apiBaseUrl: apiUrlFromOptions(context, commandOptions)
30689
30909
  });
30690
- context.writeOutput(`run_id ${run.id}`);
30691
- context.writeOutput(`archived_at ${run.archivedAt ?? ""}`);
30910
+ const style = context.io.style;
30911
+ context.writeOutput(`${style.label("run_id")} ${style.id(run.id)}`);
30912
+ context.writeOutput(
30913
+ `${style.label("archived_at")} ${style.dim(run.archivedAt ?? "")}`
30914
+ );
30692
30915
  }
30693
30916
  async function archiveRunsAction(context, runIds, commandOptions) {
30694
30917
  const result = await createRunServiceClient(context).archiveRuns(runIds, {
30695
30918
  apiBaseUrl: apiUrlFromOptions(context, commandOptions)
30696
30919
  });
30920
+ const style = context.io.style;
30697
30921
  for (const run of result.runs) {
30698
- context.writeOutput(`run_id ${run.id} archived_at ${run.archivedAt ?? ""}`);
30922
+ context.writeOutput(
30923
+ `${style.label("run_id")} ${style.id(run.id)} ${style.label(
30924
+ "archived_at"
30925
+ )} ${style.dim(run.archivedAt ?? "")}`
30926
+ );
30699
30927
  }
30700
30928
  }
30701
30929
  async function unarchiveRunAction(context, runId, commandOptions) {
30702
30930
  const run = await createRunServiceClient(context).unarchiveRun(runId, {
30703
30931
  apiBaseUrl: apiUrlFromOptions(context, commandOptions)
30704
30932
  });
30705
- context.writeOutput(`run_id ${run.id}`);
30706
- context.writeOutput(`archived ${Boolean(run.archivedAt)}`);
30933
+ const style = context.io.style;
30934
+ context.writeOutput(`${style.label("run_id")} ${style.id(run.id)}`);
30935
+ context.writeOutput(`${style.label("archived")} ${Boolean(run.archivedAt)}`);
30707
30936
  }
30708
30937
  async function unarchiveRunsAction(context, runIds, commandOptions) {
30709
30938
  const result = await createRunServiceClient(context).unarchiveRuns(runIds, {
30710
30939
  apiBaseUrl: apiUrlFromOptions(context, commandOptions)
30711
30940
  });
30941
+ const style = context.io.style;
30712
30942
  for (const run of result.runs) {
30713
- context.writeOutput(`run_id ${run.id} archived ${Boolean(run.archivedAt)}`);
30943
+ context.writeOutput(
30944
+ `${style.label("run_id")} ${style.id(run.id)} ${style.label(
30945
+ "archived"
30946
+ )} ${Boolean(run.archivedAt)}`
30947
+ );
30714
30948
  }
30715
30949
  }
30716
30950
  async function stopRunsAction(context, runIds, commandOptions) {
30717
30951
  const client = createRunServiceClient(context);
30718
30952
  const apiBaseUrl = apiUrlFromOptions(context, commandOptions);
30953
+ const style = context.io.style;
30719
30954
  const failedRunIds = [];
30720
30955
  for (const runId of runIds) {
30721
30956
  try {
@@ -30724,12 +30959,16 @@ async function stopRunsAction(context, runIds, commandOptions) {
30724
30959
  reason: commandOptions.reason
30725
30960
  });
30726
30961
  context.writeOutput(
30727
- `run_id ${runId} command_id ${command.command_id} status ${command.status}`
30962
+ `${style.label("run_id")} ${style.id(runId)} ${style.label(
30963
+ "command_id"
30964
+ )} ${style.id(command.command_id)} ${style.label("status")} ${command.status}`
30728
30965
  );
30729
30966
  } catch (error51) {
30730
30967
  failedRunIds.push(runId);
30731
30968
  context.writeOutput(
30732
- `run_id ${runId} error ${error51 instanceof Error ? error51.message : String(error51)}`
30969
+ `${style.label("run_id")} ${style.id(runId)} ${style.error(
30970
+ `error ${error51 instanceof Error ? error51.message : String(error51)}`
30971
+ )}`
30733
30972
  );
30734
30973
  }
30735
30974
  }
@@ -30760,8 +30999,11 @@ async function sendRunMessageAction(context, runId, message, commandOptions) {
30760
30999
  apiBaseUrl: apiUrlFromOptions(context, commandOptions)
30761
31000
  }
30762
31001
  );
30763
- context.writeOutput(`command_id ${command.command_id}`);
30764
- context.writeOutput(`status ${command.status}`);
31002
+ const style = context.io.style;
31003
+ context.writeOutput(
31004
+ `${style.label("command_id")} ${style.id(command.command_id)}`
31005
+ );
31006
+ context.writeOutput(`${style.label("status")} ${command.status}`);
30765
31007
  }
30766
31008
 
30767
31009
  // src/commands/runs/benchmark-startup.ts
@@ -30998,49 +31240,65 @@ async function handleRunsShow(context, runId, options = {}) {
30998
31240
  ]);
30999
31241
  context.io.writeResult({ run, summary }, formatRunShowText);
31000
31242
  }
31001
- function formatRunShowText(result, writeLine) {
31243
+ function formatRunShowText(result, writeLine, style) {
31002
31244
  const { summary } = result;
31003
31245
  writeLine(
31004
- `${summary.run.id} ${summary.run.status} session=${summary.run.sessionName} profile=${summary.run.profileName}`
31246
+ `${style.id(summary.run.id)} ${styleRunStatus(style, summary.run.status)} ${style.dim(
31247
+ `session=${summary.run.sessionName} profile=${summary.run.profileName}`
31248
+ )}`
31005
31249
  );
31006
31250
  if (summary.run.displayTitle) {
31007
- writeLine(`title: ${summary.run.displayTitle}`);
31251
+ writeLine(`${style.label("title:")} ${summary.run.displayTitle}`);
31008
31252
  }
31009
31253
  writeLine(
31010
- `created=${summary.run.createdAt} started=${summary.run.startedAt ?? "-"} finished=${summary.run.finishedAt ?? "-"}`
31254
+ style.dim(
31255
+ `created=${summary.run.createdAt} started=${summary.run.startedAt ?? "-"} finished=${summary.run.finishedAt ?? "-"}`
31256
+ )
31011
31257
  );
31012
31258
  writeLine(
31013
- `timing: queued=${formatMs(summary.timing.queuedMs)} active=${formatMs(summary.timing.activeMs)} total=${formatMs(summary.timing.totalMs)}`
31259
+ `${style.label("timing:")} ${style.dim(
31260
+ `queued=${formatMs(summary.timing.queuedMs)} active=${formatMs(summary.timing.activeMs)} total=${formatMs(summary.timing.totalMs)}`
31261
+ )}`
31014
31262
  );
31015
31263
  writeLine(
31016
- `entries=${summary.conversation.entryCount} failed=${summary.conversation.failedEntryCount} turns=${summary.turns.length} lastSequence=${summary.conversation.lastSequence}`
31264
+ style.dim(
31265
+ `entries=${summary.conversation.entryCount} failed=${summary.conversation.failedEntryCount} turns=${summary.turns.length} lastSequence=${summary.conversation.lastSequence}`
31266
+ )
31017
31267
  );
31018
31268
  writeLine(
31019
- `trigger: spawn=${summary.trigger.spawn} signaled=${summary.trigger.signaledCount} dropped=${summary.trigger.droppedCount}`
31269
+ `${style.label("trigger:")} spawn=${summary.trigger.spawn} ${style.dim(
31270
+ `signaled=${summary.trigger.signaledCount} dropped=${summary.trigger.droppedCount}`
31271
+ )}`
31020
31272
  );
31021
31273
  if (summary.artifacts.count > 0) {
31022
31274
  writeLine(
31023
- `artifacts: ${summary.artifacts.count} (${summary.artifacts.types.join(", ")})`
31275
+ `${style.label("artifacts:")} ${summary.artifacts.count} ${style.dim(
31276
+ `(${summary.artifacts.types.join(", ")})`
31277
+ )}`
31024
31278
  );
31025
31279
  }
31026
31280
  writeLine(
31027
- `commands: ${summary.commands.total} failed=${summary.commands.failed}`
31281
+ `${style.label("commands:")} ${summary.commands.total} ${style.dim(
31282
+ `failed=${summary.commands.failed}`
31283
+ )}`
31028
31284
  );
31029
31285
  if (summary.tools.length > 0) {
31030
- writeLine("tools:");
31286
+ writeLine(style.label("tools:"));
31031
31287
  for (const tool of summary.tools) {
31032
31288
  writeLine(
31033
- ` ${tool.name} calls=${tool.calls} errors=${tool.errors} p50=${formatMs(tool.durationMs.p50)} max=${formatMs(tool.durationMs.max)}`
31289
+ ` ${tool.name} ${style.dim(
31290
+ `calls=${tool.calls} errors=${tool.errors} p50=${formatMs(tool.durationMs.p50)} max=${formatMs(tool.durationMs.max)}`
31291
+ )}`
31034
31292
  );
31035
31293
  }
31036
31294
  }
31037
31295
  for (const check2 of summary.checks) {
31038
31296
  writeLine(
31039
- `check: ${check2.name} ${check2.status}${check2.conclusion ? ` ${check2.conclusion}` : ""}`
31297
+ `${style.label("check:")} ${check2.name} ${check2.status}${check2.conclusion ? ` ${styleCheckConclusion(style, check2.conclusion)}` : ""}`
31040
31298
  );
31041
31299
  }
31042
31300
  if (summary.run.error !== null) {
31043
- writeLine(`error: ${JSON.stringify(summary.run.error)}`);
31301
+ writeLine(style.error(`error: ${JSON.stringify(summary.run.error)}`));
31044
31302
  }
31045
31303
  }
31046
31304
  async function handleRunsConversation(context, runId, options = {}) {
@@ -31067,25 +31325,31 @@ async function handleRunsConversation(context, runId, options = {}) {
31067
31325
  formatConversationText
31068
31326
  );
31069
31327
  }
31070
- function formatConversationText(result, writeLine) {
31328
+ function formatConversationText(result, writeLine, style) {
31071
31329
  if (result.events.length === 0) {
31072
- writeLine("No conversation entries.");
31330
+ writeLine(style.dim("No conversation entries."));
31073
31331
  return;
31074
31332
  }
31075
31333
  for (const event of result.events) {
31076
- const failed = event.status === "failed" ? " FAILED" : "";
31334
+ const failed = event.status === "failed" ? ` ${style.error("FAILED")}` : "";
31077
31335
  writeLine(
31078
- `${event.sequence} ${event.role}/${event.kind}${failed}: ${entryPreview(event, result.full)}`
31336
+ `${style.dim(String(event.sequence))} ${style.label(
31337
+ `${event.role}/${event.kind}`
31338
+ )}${failed}: ${entryPreview(event, result.full)}`
31079
31339
  );
31080
31340
  }
31081
31341
  if (result.hasMore) {
31082
31342
  if (result.tailMode) {
31083
31343
  const oldest = result.events[0]?.sequence;
31084
31344
  writeLine(
31085
- `(more older entries; rerun with --before ${oldest ?? "<sequence>"})`
31345
+ style.dim(
31346
+ `(more older entries; rerun with --before ${oldest ?? "<sequence>"})`
31347
+ )
31086
31348
  );
31087
31349
  } else {
31088
- writeLine(`(more entries; continue with --after ${result.cursor})`);
31350
+ writeLine(
31351
+ style.dim(`(more entries; continue with --after ${result.cursor})`)
31352
+ );
31089
31353
  }
31090
31354
  }
31091
31355
  }
@@ -31099,21 +31363,25 @@ async function handleRunsSearch(context, runId, queries, options = {}) {
31099
31363
  });
31100
31364
  context.io.writeResult({ runId, queries, ...response }, formatSearchText);
31101
31365
  }
31102
- function formatSearchText(result, writeLine) {
31366
+ function formatSearchText(result, writeLine, style) {
31103
31367
  if (result.matches.length === 0) {
31104
- writeLine(`No matches for: ${result.queries.join(", ")}`);
31368
+ writeLine(style.dim(`No matches for: ${result.queries.join(", ")}`));
31105
31369
  return;
31106
31370
  }
31107
31371
  for (const match of result.matches) {
31108
31372
  for (const snippet of match.snippets) {
31109
31373
  writeLine(
31110
- `${match.sequence} ${match.kind} [${snippet.query}]: ${singleLine(snippet.text)}`
31374
+ `${style.dim(String(match.sequence))} ${match.kind} ${style.label(
31375
+ `[${snippet.query}]`
31376
+ )}: ${singleLine(snippet.text)}`
31111
31377
  );
31112
31378
  }
31113
31379
  }
31114
31380
  if (result.hasMore) {
31115
31381
  writeLine(
31116
- `(more scanned entries; continue with --after ${result.nextAfterSequence ?? "<sequence>"})`
31382
+ style.dim(
31383
+ `(more scanned entries; continue with --after ${result.nextAfterSequence ?? "<sequence>"})`
31384
+ )
31117
31385
  );
31118
31386
  }
31119
31387
  }
@@ -31129,24 +31397,34 @@ async function handleRunsTools(context, runId, options = {}) {
31129
31397
  });
31130
31398
  context.io.writeResult({ runId, ...response }, formatToolsText);
31131
31399
  }
31132
- function formatToolsText(result, writeLine) {
31400
+ function formatToolsText(result, writeLine, style) {
31133
31401
  if (result.exchanges.length === 0) {
31134
- writeLine("No tool exchanges.");
31402
+ writeLine(style.dim("No tool exchanges."));
31135
31403
  return;
31136
31404
  }
31137
31405
  for (const exchange of result.exchanges) {
31138
31406
  const duration4 = exchange.durationMs === null ? "-" : `${exchange.durationMs}ms`;
31139
- const outcome = exchange.isError === null ? "pending" : exchange.isError ? "ERR" : "ok";
31407
+ const outcome = exchangeOutcome(style, exchange.isError);
31140
31408
  writeLine(
31141
- `${exchange.callSequence} ${exchange.name} ${duration4} ${outcome}: ${preview(exchange.input)}`
31409
+ `${style.dim(String(exchange.callSequence))} ${style.label(
31410
+ exchange.name
31411
+ )} ${style.dim(duration4)} ${outcome}: ${preview(exchange.input)}`
31142
31412
  );
31143
31413
  }
31144
31414
  if (result.hasMore) {
31145
31415
  writeLine(
31146
- `(more exchanges; page older with --before ${result.nextBeforeSequence ?? "<sequence>"})`
31416
+ style.dim(
31417
+ `(more exchanges; page older with --before ${result.nextBeforeSequence ?? "<sequence>"})`
31418
+ )
31147
31419
  );
31148
31420
  }
31149
31421
  }
31422
+ function exchangeOutcome(style, isError) {
31423
+ if (isError === null) {
31424
+ return style.dim("pending");
31425
+ }
31426
+ return isError ? style.error("ERR") : style.success("ok");
31427
+ }
31150
31428
  async function handleRunsTriggers(context, runId, options = {}) {
31151
31429
  const client = createContextApiClient(context);
31152
31430
  const response = await client.listRunTriggers(runId, {
@@ -31154,26 +31432,28 @@ async function handleRunsTriggers(context, runId, options = {}) {
31154
31432
  });
31155
31433
  context.io.writeResult({ runId, ...response }, formatTriggersText);
31156
31434
  }
31157
- function formatTriggersText(result, writeLine) {
31435
+ function formatTriggersText(result, writeLine, style) {
31158
31436
  if (result.spawn) {
31159
31437
  writeLine(
31160
- `spawn: ${result.spawn.eventKey} (${result.spawn.originKind}) delivered=${result.spawn.deliveredAt}`
31438
+ `${style.label("spawn:")} ${result.spawn.eventKey} ${style.dim(
31439
+ `(${result.spawn.originKind}) delivered=${result.spawn.deliveredAt}`
31440
+ )}`
31161
31441
  );
31162
31442
  } else if (result.starter) {
31163
31443
  writeLine(
31164
- `spawn: ${result.starter.principal.kind === "run" ? "agent" : "manual"} starter=${JSON.stringify(result.starter.principal)}`
31444
+ `${style.label("spawn:")} ${result.starter.principal.kind === "run" ? "agent" : "manual"} ${style.dim(`starter=${JSON.stringify(result.starter.principal)}`)}`
31165
31445
  );
31166
31446
  } else {
31167
- writeLine("spawn: manual");
31447
+ writeLine(`${style.label("spawn:")} manual`);
31168
31448
  }
31169
31449
  if (result.deliveries.length === 0) {
31170
- writeLine("No subsequent deliveries.");
31450
+ writeLine(style.dim("No subsequent deliveries."));
31171
31451
  return;
31172
31452
  }
31173
31453
  for (const delivery of result.deliveries) {
31174
- const reason = delivery.reason ? ` reason=${delivery.reason}` : "";
31454
+ const reason = delivery.reason ? ` ${style.dim(`reason=${delivery.reason}`)}` : "";
31175
31455
  writeLine(
31176
- `${delivery.deliveredAt} ${delivery.action} ${delivery.eventKey}${reason}`
31456
+ `${style.dim(delivery.deliveredAt)} ${delivery.action} ${delivery.eventKey}${reason}`
31177
31457
  );
31178
31458
  }
31179
31459
  }
@@ -31184,14 +31464,16 @@ async function handleRunsArtifacts(context, runId, options = {}) {
31184
31464
  });
31185
31465
  context.io.writeResult({ runId, ...response }, formatArtifactsText);
31186
31466
  }
31187
- function formatArtifactsText(result, writeLine) {
31467
+ function formatArtifactsText(result, writeLine, style) {
31188
31468
  if (result.artifacts.length === 0) {
31189
- writeLine("No artifacts currently owned.");
31469
+ writeLine(style.dim("No artifacts currently owned."));
31190
31470
  return;
31191
31471
  }
31192
31472
  for (const artifact of result.artifacts) {
31193
31473
  writeLine(
31194
- `${artifact.artifactType} ${artifact.externalId} recorded=${artifact.recordedAt}`
31474
+ `${style.label(artifact.artifactType)} ${style.id(artifact.externalId)} ${style.dim(
31475
+ `recorded=${artifact.recordedAt}`
31476
+ )}`
31195
31477
  );
31196
31478
  }
31197
31479
  }
@@ -31202,20 +31484,38 @@ async function handleRunsCommands(context, runId, options = {}) {
31202
31484
  });
31203
31485
  context.io.writeResult({ runId, ...response }, formatCommandsText);
31204
31486
  }
31205
- function formatCommandsText(result, writeLine) {
31487
+ function formatCommandsText(result, writeLine, style) {
31206
31488
  if (result.commands.length === 0) {
31207
- writeLine("No commands.");
31489
+ writeLine(style.dim("No commands."));
31208
31490
  return;
31209
31491
  }
31210
31492
  for (const command of result.commands) {
31493
+ const status = command.status === "failed" ? style.error(command.status) : command.status;
31211
31494
  writeLine(
31212
- `${command.createdAt} ${command.kind} ${command.status} sender=${command.sender.type}: ${preview(command.payload)}`
31495
+ `${style.dim(command.createdAt)} ${style.label(command.kind)} ${status} ${style.dim(
31496
+ `sender=${command.sender.type}`
31497
+ )}: ${preview(command.payload)}`
31213
31498
  );
31214
31499
  }
31215
31500
  }
31216
31501
  function formatMs(value) {
31217
31502
  return value === null ? "-" : `${value}ms`;
31218
31503
  }
31504
+ function styleCheckConclusion(style, conclusion) {
31505
+ switch (conclusion) {
31506
+ case "success":
31507
+ return style.success(conclusion);
31508
+ case "failure":
31509
+ case "timed_out":
31510
+ return style.error(conclusion);
31511
+ case "cancelled":
31512
+ case "skipped":
31513
+ case "neutral":
31514
+ return style.dim(conclusion);
31515
+ default:
31516
+ return conclusion;
31517
+ }
31518
+ }
31219
31519
  function entryPreview(event, full) {
31220
31520
  const texts = event.content.parts.map((part) => {
31221
31521
  switch (part.type) {
@@ -31247,40 +31547,6 @@ function clip(text) {
31247
31547
  return text.length > PREVIEW_CHARS ? `${text.slice(0, PREVIEW_CHARS)}\u2026` : text;
31248
31548
  }
31249
31549
 
31250
- // src/commands/runs/list.ts
31251
- async function handleRunsList(context, sessionName, options = {}) {
31252
- const result = await fetchRuns(context, sessionName, options);
31253
- context.io.writeResult(result, formatRunsText);
31254
- }
31255
- async function fetchRuns(context, sessionName, options) {
31256
- const client = createContextApiClient(context);
31257
- const clientOptions = {
31258
- apiBaseUrl: apiUrlFromOptions(context, options),
31259
- includeArchived: options.includeArchived,
31260
- statuses: options.status,
31261
- since: options.since,
31262
- limit: options.limit
31263
- };
31264
- const response = sessionName ? await client.listSessionRuns(sessionName, clientOptions) : await client.listRuns(clientOptions);
31265
- return {
31266
- session: sessionName ?? null,
31267
- runs: response.runs,
31268
- includeArchived: Boolean(options.includeArchived)
31269
- };
31270
- }
31271
- function formatRunsText(result, writeLine) {
31272
- if (result.runs.length === 0) {
31273
- writeLine(
31274
- result.session ? `No runs found for session ${result.session}.` : "No runs found in the current project."
31275
- );
31276
- return;
31277
- }
31278
- for (const run of result.runs) {
31279
- const archived = run.archivedAt ? ` archived_at=${run.archivedAt}` : "";
31280
- writeLine(`${run.id} ${run.status} ${run.createdAt}${archived}`);
31281
- }
31282
- }
31283
-
31284
31550
  // src/commands/runs/commands.ts
31285
31551
  function collect(value, previous = []) {
31286
31552
  return [...previous, value];
@@ -31717,8 +31983,8 @@ async function connectSessionPresence2(input) {
31717
31983
  const options = { apiBaseUrl: input.apiBaseUrl };
31718
31984
  const result = await connectWithConfigTokenBootstrap(input, options);
31719
31985
  input.writeOutput(result.message);
31720
- for (const identity of result.realized) {
31721
- input.writeOutput(realizedIdentityLine(input.session, identity));
31986
+ for (const identity2 of result.realized) {
31987
+ input.writeOutput(realizedIdentityLine(input.session, identity2));
31722
31988
  }
31723
31989
  if (result.pending.length === 0) {
31724
31990
  await promptForIconUploads(input, options);
@@ -31776,11 +32042,11 @@ async function connectSessionPresence2(input) {
31776
32042
  { name: input.session },
31777
32043
  options
31778
32044
  );
31779
- const identity = presence.identities.find(
32045
+ const identity2 = presence.identities.find(
31780
32046
  (entry) => entry.identityId === pending.identityId
31781
32047
  );
31782
- if (identity?.realized) {
31783
- input.writeOutput(realizedIdentityLine(input.session, identity));
32048
+ if (identity2?.realized) {
32049
+ input.writeOutput(realizedIdentityLine(input.session, identity2));
31784
32050
  realized = true;
31785
32051
  break;
31786
32052
  }
@@ -31793,9 +32059,9 @@ async function connectSessionPresence2(input) {
31793
32059
  }
31794
32060
  await promptForIconUploads(input, options);
31795
32061
  }
31796
- function realizedIdentityLine(session, identity) {
31797
- const handle = identity.botUsername ? `persona/@${identity.botUsername}` : `bot/${identity.botUserId ?? ""}`;
31798
- return `connected session/${session} workspace/${identity.workspace} ${handle}`;
32062
+ function realizedIdentityLine(session, identity2) {
32063
+ const handle = identity2.botUsername ? `persona/@${identity2.botUsername}` : `bot/${identity2.botUserId ?? ""}`;
32064
+ return `connected session/${session} workspace/${identity2.workspace} ${handle}`;
31799
32065
  }
31800
32066
  function manualGuidance(input) {
31801
32067
  if (input.allTelegram) {
@@ -31809,19 +32075,19 @@ async function promptForIconUploads(input, options) {
31809
32075
  options
31810
32076
  );
31811
32077
  const drifted = presence.identities.filter(
31812
- (identity) => identity.realized && identity.appId && identity.avatarSha256 && identity.avatarSha256 !== identity.appliedIconSha256
32078
+ (identity2) => identity2.realized && identity2.appId && identity2.avatarSha256 && identity2.avatarSha256 !== identity2.appliedIconSha256
31813
32079
  );
31814
32080
  if (drifted.length === 0) {
31815
32081
  return;
31816
32082
  }
31817
32083
  const canPrompt = Boolean(input.prompt?.io.canPrompt()) && !input.manual;
31818
- for (const identity of drifted) {
31819
- const settingsUrl = `${SLACK_APPS_URL}/${identity.appId}/general`;
32084
+ for (const identity2 of drifted) {
32085
+ const settingsUrl = `${SLACK_APPS_URL}/${identity2.appId}/general`;
31820
32086
  input.writeOutput(
31821
- `Workspace "${identity.workspace}" agent app icon does not match the session avatar yet. Slack has no app-icon API; upload the avatar image once under "Display Information" at ${settingsUrl}`
32087
+ `Workspace "${identity2.workspace}" agent app icon does not match the session avatar yet. Slack has no app-icon API; upload the avatar image once under "Display Information" at ${settingsUrl}`
31822
32088
  );
31823
- if (identity.avatarUrl) {
31824
- input.writeOutput(`avatar image: ${identity.avatarUrl}`);
32089
+ if (identity2.avatarUrl) {
32090
+ input.writeOutput(`avatar image: ${identity2.avatarUrl}`);
31825
32091
  }
31826
32092
  if (!canPrompt) {
31827
32093
  input.writeOutput(
@@ -31829,8 +32095,8 @@ async function promptForIconUploads(input, options) {
31829
32095
  );
31830
32096
  continue;
31831
32097
  }
31832
- const staged = identity.avatarUrl ? await (input.stageAvatar ?? stageAvatarImage)({
31833
- avatarUrl: identity.avatarUrl,
32098
+ const staged = identity2.avatarUrl ? await (input.stageAvatar ?? stageAvatarImage)({
32099
+ avatarUrl: identity2.avatarUrl,
31834
32100
  session: input.session
31835
32101
  }) : void 0;
31836
32102
  if (staged) {
@@ -31852,20 +32118,20 @@ async function promptForIconUploads(input, options) {
31852
32118
  }
31853
32119
  if (!["y", "yes"].includes(answer.trim().toLowerCase())) {
31854
32120
  input.writeOutput(
31855
- `Skipped recording the icon for workspace "${identity.workspace}"; this prompt repeats on the next connect.`
32121
+ `Skipped recording the icon for workspace "${identity2.workspace}"; this prompt repeats on the next connect.`
31856
32122
  );
31857
32123
  continue;
31858
32124
  }
31859
32125
  const recorded = await input.client.recordSessionPresenceIcon(
31860
32126
  {
31861
32127
  name: input.session,
31862
- identityId: identity.identityId,
31863
- sha256: identity.avatarSha256
32128
+ identityId: identity2.identityId,
32129
+ sha256: identity2.avatarSha256
31864
32130
  },
31865
32131
  options
31866
32132
  );
31867
32133
  input.writeOutput(
31868
- `recorded icon session/${input.session} workspace/${identity.workspace} sha256/${recorded.appliedIconSha256.slice(0, 12)}`
32134
+ `recorded icon session/${input.session} workspace/${identity2.workspace} sha256/${recorded.appliedIconSha256.slice(0, 12)}`
31869
32135
  );
31870
32136
  }
31871
32137
  }
@@ -31949,9 +32215,16 @@ async function launchRun(input) {
31949
32215
  message: input.commandOptions.message,
31950
32216
  apiBaseUrl
31951
32217
  });
31952
- input.context.writeOutput(`run_id ${created.run_id}`);
31953
- input.context.writeOutput(`workflow_id ${created.workflow_id}`);
31954
- input.context.writeOutput(`status ${created.status}`);
32218
+ const style = input.context.io.style;
32219
+ input.context.writeOutput(
32220
+ `${style.label("run_id")} ${style.id(created.run_id)}`
32221
+ );
32222
+ input.context.writeOutput(
32223
+ `${style.label("workflow_id")} ${style.id(created.workflow_id)}`
32224
+ );
32225
+ input.context.writeOutput(
32226
+ `${style.label("status")} ${styleRunStatus(style, created.status)}`
32227
+ );
31955
32228
  if (input.commandOptions.attach) {
31956
32229
  const writeConversationEvent = createConversationStreamWriter({
31957
32230
  writeLine: input.context.writeOutput
@@ -32021,6 +32294,7 @@ function registerToolCommands(program, context) {
32021
32294
  }
32022
32295
 
32023
32296
  // src/lib/output/iostreams.ts
32297
+ init_style();
32024
32298
  function createIOStreams(flags) {
32025
32299
  const isTTY = Boolean(process.stdout.isTTY);
32026
32300
  const isCI = Boolean(process.env.CI);
@@ -32030,18 +32304,20 @@ function createIOStreams(flags) {
32030
32304
  `));
32031
32305
  const writeError = flags.writeError ?? ((text) => process.stderr.write(`${text}
32032
32306
  `));
32307
+ const style = createStyle({ isTTY, noColor, outputMode });
32033
32308
  return {
32034
32309
  isTTY,
32035
32310
  isCI,
32036
32311
  noColor,
32037
32312
  outputMode,
32313
+ style,
32038
32314
  canPrompt: () => isTTY && !isCI,
32039
32315
  writeLine,
32040
32316
  writeError,
32041
32317
  writeResult: (result, renderText) => {
32042
32318
  if (outputMode === "text" || outputMode === "tui") {
32043
32319
  if (renderText) {
32044
- renderText(result, writeLine);
32320
+ renderText(result, writeLine, style);
32045
32321
  } else {
32046
32322
  writeLine(String(result));
32047
32323
  }
@@ -32180,14 +32456,20 @@ function isCliEntrypoint(input) {
32180
32456
  }
32181
32457
 
32182
32458
  // src/entrypoints/index.ts
32459
+ init_style();
32183
32460
  function runEntrypoint(input) {
32184
32461
  if (isCliEntrypoint({
32185
32462
  moduleUrl: input.moduleUrl,
32186
32463
  entrypoint: input.argv[1] ? { kind: "path", path: input.argv[1] } : { kind: "missing" }
32187
32464
  })) {
32188
32465
  createProgram().parseAsync(input.argv).catch((err) => {
32466
+ const style = createStyle({
32467
+ isTTY: Boolean(process.stderr.isTTY),
32468
+ noColor: Boolean(process.env.NO_COLOR) || input.argv.includes("--no-color"),
32469
+ outputMode: "text"
32470
+ });
32189
32471
  process.stderr.write(
32190
- `${err instanceof Error ? err.message : String(err)}
32472
+ `${style.error(err instanceof Error ? err.message : String(err))}
32191
32473
  `
32192
32474
  );
32193
32475
  process.exit(1);