@autohq/cli 0.1.102 → 0.1.104

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({
@@ -18483,6 +18483,73 @@ var init_src = __esm({
18483
18483
  }
18484
18484
  });
18485
18485
 
18486
+ // package.json
18487
+ var package_default;
18488
+ var init_package = __esm({
18489
+ "package.json"() {
18490
+ package_default = {
18491
+ name: "@autohq/cli",
18492
+ version: "0.1.104",
18493
+ license: "SEE LICENSE IN README.md",
18494
+ publishConfig: {
18495
+ access: "public"
18496
+ },
18497
+ repository: {
18498
+ type: "git",
18499
+ url: "git+https://github.com/fractal-works/auto.git",
18500
+ directory: "apps/cli"
18501
+ },
18502
+ engines: {
18503
+ node: ">=20"
18504
+ },
18505
+ type: "module",
18506
+ bin: {
18507
+ auto: "./dist/index.js"
18508
+ },
18509
+ files: ["dist"],
18510
+ scripts: {
18511
+ build: "tsup",
18512
+ dev: "tsx src/main.ts",
18513
+ "dev:tui": "node ../../scripts/cli-tui-dev-watch.mjs",
18514
+ "skill:generate": "tsx scripts/generate-skill-content.ts",
18515
+ test: "npm run test:unit",
18516
+ "test:unit": 'tsx --test "test/**/*.unit.test.ts"',
18517
+ typecheck: "tsc --noEmit"
18518
+ },
18519
+ dependencies: {
18520
+ "@anthropic-ai/claude-agent-sdk": "^0.3.153",
18521
+ "@inkjs/ui": "^2.0.0",
18522
+ "@tanstack/react-query": "^5.100.14",
18523
+ chalk: "^5.3.0",
18524
+ commander: "^14.0.2",
18525
+ ink: "^7",
18526
+ "ink-text-input": "^6.0.0",
18527
+ jose: "^5.9.6",
18528
+ marked: "^15.0.12",
18529
+ react: "^19",
18530
+ "socket.io-client": "^4.8.3",
18531
+ yaml: "^2.9.0"
18532
+ },
18533
+ devDependencies: {
18534
+ "@auto/protocol": "*",
18535
+ "@auto/schemas": "*",
18536
+ "@types/react": "^19",
18537
+ tsup: "^8.5.1"
18538
+ }
18539
+ };
18540
+ }
18541
+ });
18542
+
18543
+ // src/cli/version.ts
18544
+ var cliVersion;
18545
+ var init_version = __esm({
18546
+ "src/cli/version.ts"() {
18547
+ "use strict";
18548
+ init_package();
18549
+ cliVersion = package_default.version;
18550
+ }
18551
+ });
18552
+
18486
18553
  // src/lib/auth/tokens.ts
18487
18554
  function accessTokenExpiresAt(token2) {
18488
18555
  if (!token2.access_token) {
@@ -20371,6 +20438,47 @@ var init_client = __esm({
20371
20438
  }
20372
20439
  });
20373
20440
 
20441
+ // src/lib/output/style.ts
20442
+ import { Chalk } from "chalk";
20443
+ function createStyle(flags) {
20444
+ const textual = flags.outputMode === "text" || flags.outputMode === "tui";
20445
+ if (!textual || flags.noColor || !flags.isTTY) {
20446
+ return plainStyle;
20447
+ }
20448
+ const chalk2 = new Chalk({ level: 1 });
20449
+ return {
20450
+ enabled: true,
20451
+ success: (text) => chalk2.green(text),
20452
+ warn: (text) => chalk2.yellow(text),
20453
+ error: (text) => chalk2.red(text),
20454
+ heading: (text) => chalk2.bold.underline(text),
20455
+ label: (text) => chalk2.bold(text),
20456
+ id: (text) => chalk2.cyan(text),
20457
+ url: (text) => chalk2.cyan.underline(text),
20458
+ dim: (text) => chalk2.dim(text)
20459
+ };
20460
+ }
20461
+ function identity(text) {
20462
+ return text;
20463
+ }
20464
+ var plainStyle;
20465
+ var init_style = __esm({
20466
+ "src/lib/output/style.ts"() {
20467
+ "use strict";
20468
+ plainStyle = {
20469
+ enabled: false,
20470
+ success: identity,
20471
+ warn: identity,
20472
+ error: identity,
20473
+ heading: identity,
20474
+ label: identity,
20475
+ id: identity,
20476
+ url: identity,
20477
+ dim: identity
20478
+ };
20479
+ }
20480
+ });
20481
+
20374
20482
  // src/lib/browser.ts
20375
20483
  import { spawn } from "child_process";
20376
20484
  function openBrowser(url2) {
@@ -21165,10 +21273,12 @@ async function applyResource(input) {
21165
21273
  },
21166
21274
  client: input.client,
21167
21275
  request,
21168
- writeOutput: input.writeOutput
21276
+ writeOutput: input.writeOutput,
21277
+ style: input.style
21169
21278
  });
21170
21279
  }
21171
21280
  async function applyProjectInput(input) {
21281
+ const style = input.style ?? plainStyle;
21172
21282
  const response = await input.client.applyProjectResources(
21173
21283
  {
21174
21284
  ...input.request.delete.length > 0 ? { delete: input.request.delete } : {},
@@ -21194,7 +21304,10 @@ async function applyProjectInput(input) {
21194
21304
  );
21195
21305
  for (const item of response.plan) {
21196
21306
  input.writeOutput(
21197
- `${item.action.padEnd(actionWidth + 2)}${item.kind}/${item.name}`
21307
+ `${planActionStyle(
21308
+ style,
21309
+ item.action
21310
+ )(item.action.padEnd(actionWidth + 2))}${item.kind}/${item.name}`
21198
21311
  );
21199
21312
  }
21200
21313
  if (input.commandOptions.connect) {
@@ -21202,30 +21315,42 @@ async function applyProjectInput(input) {
21202
21315
  input.request
21203
21316
  )) {
21204
21317
  input.writeOutput(
21205
- `would connect tool/${item.tool} connection/${item.connection}`
21318
+ style.dim(
21319
+ `would connect tool/${item.tool} connection/${item.connection}`
21320
+ )
21206
21321
  );
21207
21322
  }
21208
21323
  }
21209
- writeDiagnostics(response.diagnostics, input.writeOutput);
21324
+ writeDiagnostics(response.diagnostics, input.writeOutput, style);
21210
21325
  return;
21211
21326
  }
21212
21327
  for (const { kind, resource } of resources) {
21213
- input.writeOutput(`kind ${kind}`);
21214
- input.writeOutput(`name ${resource.metadata.name}`);
21215
- input.writeOutput(`uid ${resource.metadata.uid}`);
21216
- input.writeOutput(`generation ${resource.metadata.generation}`);
21217
- input.writeOutput(`resource_version ${resource.metadata.resourceVersion}`);
21328
+ input.writeOutput(`${style.label("kind")} ${kind}`);
21329
+ input.writeOutput(`${style.label("name")} ${resource.metadata.name}`);
21330
+ input.writeOutput(
21331
+ `${style.label("uid")} ${style.id(resource.metadata.uid)}`
21332
+ );
21333
+ input.writeOutput(
21334
+ `${style.label("generation")} ${resource.metadata.generation}`
21335
+ );
21336
+ input.writeOutput(
21337
+ `${style.label("resource_version")} ${resource.metadata.resourceVersion}`
21338
+ );
21218
21339
  }
21219
21340
  for (const trigger of response.triggers) {
21220
- input.writeOutput(`webhook_event ${trigger.event}`);
21221
- input.writeOutput(`webhook_endpoint ${trigger.endpoint}`);
21222
- input.writeOutput(`webhook_ingest_url ${trigger.ingestUrl}`);
21223
- input.writeOutput(`webhook_status ${trigger.status}`);
21341
+ input.writeOutput(`${style.label("webhook_event")} ${trigger.event}`);
21342
+ input.writeOutput(`${style.label("webhook_endpoint")} ${trigger.endpoint}`);
21343
+ input.writeOutput(
21344
+ `${style.label("webhook_ingest_url")} ${style.url(trigger.ingestUrl)}`
21345
+ );
21346
+ input.writeOutput(`${style.label("webhook_status")} ${trigger.status}`);
21224
21347
  }
21225
21348
  for (const resource of response.pruned) {
21226
- input.writeOutput(`pruned ${resource.kind}/${resource.name}`);
21349
+ input.writeOutput(
21350
+ `${style.warn("pruned")} ${resource.kind}/${resource.name}`
21351
+ );
21227
21352
  }
21228
- writeDiagnostics(response.diagnostics, input.writeOutput);
21353
+ writeDiagnostics(response.diagnostics, input.writeOutput, style);
21229
21354
  if (input.commandOptions.connect) {
21230
21355
  const connections = mcpOAuthToolConnectionsFromAppliedResources(resources);
21231
21356
  for (const item of connections) {
@@ -21239,16 +21364,32 @@ async function applyProjectInput(input) {
21239
21364
  }
21240
21365
  }
21241
21366
  }
21242
- function writeDiagnostics(diagnostics, writeOutput) {
21367
+ function writeDiagnostics(diagnostics, writeOutput, style) {
21243
21368
  for (const diagnostic of diagnostics) {
21369
+ const severity = diagnostic.severity === "error" ? style.error(diagnostic.severity) : style.warn(diagnostic.severity);
21244
21370
  writeOutput(
21245
- `${diagnostic.severity} ${diagnostic.kind}/${diagnostic.name}: ${diagnostic.message}`
21371
+ `${severity} ${diagnostic.kind}/${diagnostic.name}: ${diagnostic.message}`
21246
21372
  );
21247
21373
  }
21248
21374
  }
21375
+ function planActionStyle(style, action) {
21376
+ switch (action) {
21377
+ case "create":
21378
+ return style.success;
21379
+ case "update":
21380
+ return style.warn;
21381
+ case "archive":
21382
+ return style.error;
21383
+ case "unchanged":
21384
+ return style.dim;
21385
+ default:
21386
+ return (text) => text;
21387
+ }
21388
+ }
21249
21389
  var init_actions = __esm({
21250
21390
  "src/commands/apply/actions.ts"() {
21251
21391
  "use strict";
21392
+ init_style();
21252
21393
  init_connect();
21253
21394
  init_files();
21254
21395
  }
@@ -21306,6 +21447,7 @@ var init_pkce = __esm({
21306
21447
 
21307
21448
  // src/commands/auth/login.ts
21308
21449
  async function login(input) {
21450
+ const style = input.style ?? plainStyle;
21309
21451
  const serverUrl = resolveApiBaseUrl({ explicit: input.options.apiUrl });
21310
21452
  if (input.options.device) {
21311
21453
  const device = await postJson(
@@ -21314,9 +21456,13 @@ async function login(input) {
21314
21456
  {}
21315
21457
  );
21316
21458
  input.writeOutput(
21317
- `Open ${device.verification_uri} and enter ${device.user_code}`
21459
+ `Open ${style.url(device.verification_uri)} and enter ${style.label(
21460
+ device.user_code
21461
+ )}`
21462
+ );
21463
+ input.writeOutput(
21464
+ `${style.label("Device code:")} ${style.id(device.device_code)}`
21318
21465
  );
21319
- input.writeOutput(`Device code: ${device.device_code}`);
21320
21466
  const deadline = Date.now() + device.expires_in * 1e3;
21321
21467
  let firstAttempt = true;
21322
21468
  while (Date.now() < deadline) {
@@ -21345,7 +21491,8 @@ async function login(input) {
21345
21491
  serverUrl,
21346
21492
  fetch: input.fetch,
21347
21493
  configPath: input.configPath,
21348
- writeOutput: input.writeOutput
21494
+ writeOutput: input.writeOutput,
21495
+ style
21349
21496
  });
21350
21497
  return;
21351
21498
  }
@@ -21373,8 +21520,8 @@ async function login(input) {
21373
21520
  const authorizeUrl = new URL("/auth/cli", serverUrl);
21374
21521
  authorizeUrl.searchParams.set("pkce_challenge", pkceChallenge(verifier));
21375
21522
  authorizeUrl.searchParams.set("redirect_uri", callback.redirectUri);
21376
- input.writeOutput(`Opening ${authorizeUrl.toString()}`);
21377
- input.writeOutput("Waiting for browser authorization...");
21523
+ input.writeOutput(`Opening ${style.url(authorizeUrl.toString())}`);
21524
+ input.writeOutput(style.dim("Waiting for browser authorization..."));
21378
21525
  openBrowser(authorizeUrl.toString());
21379
21526
  const { code } = await callback.result;
21380
21527
  const token3 = await exchangeAuthorizationCode({
@@ -21389,7 +21536,8 @@ async function login(input) {
21389
21536
  serverUrl,
21390
21537
  fetch: input.fetch,
21391
21538
  configPath: input.configPath,
21392
- writeOutput: input.writeOutput
21539
+ writeOutput: input.writeOutput,
21540
+ style
21393
21541
  });
21394
21542
  return;
21395
21543
  } finally {
@@ -21408,7 +21556,8 @@ async function login(input) {
21408
21556
  serverUrl,
21409
21557
  fetch: input.fetch,
21410
21558
  configPath: input.configPath,
21411
- writeOutput: input.writeOutput
21559
+ writeOutput: input.writeOutput,
21560
+ style
21412
21561
  });
21413
21562
  }
21414
21563
  async function exchangeAuthorizationCode(input) {
@@ -21468,13 +21617,17 @@ async function finishLogin(input) {
21468
21617
  };
21469
21618
  } catch {
21470
21619
  input.writeOutput(
21471
- "The saved organization/project selection is not available for this account; run `auto orgs list` to pick a new one."
21620
+ input.style.warn(
21621
+ "The saved organization/project selection is not available for this account; run `auto orgs list` to pick a new one."
21622
+ )
21472
21623
  );
21473
21624
  }
21474
21625
  }
21475
21626
  writeConfig(config2, input.configPath);
21476
21627
  input.writeOutput(
21477
- token2.user ? `Logged in as ${token2.user.email}.` : "Logged in."
21628
+ input.style.success(
21629
+ token2.user ? `Logged in as ${token2.user.email}.` : "Logged in."
21630
+ )
21478
21631
  );
21479
21632
  }
21480
21633
  async function sleep(ms) {
@@ -21490,6 +21643,7 @@ var init_login = __esm({
21490
21643
  init_file();
21491
21644
  init_profiles2();
21492
21645
  init_loopback();
21646
+ init_style();
21493
21647
  init_pkce();
21494
21648
  }
21495
21649
  });
@@ -21765,73 +21919,6 @@ var init_conversation2 = __esm({
21765
21919
  }
21766
21920
  });
21767
21921
 
21768
- // package.json
21769
- var package_default;
21770
- var init_package = __esm({
21771
- "package.json"() {
21772
- package_default = {
21773
- name: "@autohq/cli",
21774
- version: "0.1.102",
21775
- license: "SEE LICENSE IN README.md",
21776
- publishConfig: {
21777
- access: "public"
21778
- },
21779
- repository: {
21780
- type: "git",
21781
- url: "git+https://github.com/fractal-works/auto.git",
21782
- directory: "apps/cli"
21783
- },
21784
- engines: {
21785
- node: ">=20"
21786
- },
21787
- type: "module",
21788
- bin: {
21789
- auto: "./dist/index.js"
21790
- },
21791
- files: ["dist"],
21792
- scripts: {
21793
- build: "tsup",
21794
- dev: "tsx src/main.ts",
21795
- "dev:tui": "node ../../scripts/cli-tui-dev-watch.mjs",
21796
- "skill:generate": "tsx scripts/generate-skill-content.ts",
21797
- test: "npm run test:unit",
21798
- "test:unit": 'tsx --test "test/**/*.unit.test.ts"',
21799
- typecheck: "tsc --noEmit"
21800
- },
21801
- dependencies: {
21802
- "@anthropic-ai/claude-agent-sdk": "^0.3.153",
21803
- "@inkjs/ui": "^2.0.0",
21804
- "@tanstack/react-query": "^5.100.14",
21805
- chalk: "^5.3.0",
21806
- commander: "^14.0.2",
21807
- ink: "^7",
21808
- "ink-text-input": "^6.0.0",
21809
- jose: "^5.9.6",
21810
- marked: "^15.0.12",
21811
- react: "^19",
21812
- "socket.io-client": "^4.8.3",
21813
- yaml: "^2.9.0"
21814
- },
21815
- devDependencies: {
21816
- "@auto/protocol": "*",
21817
- "@auto/schemas": "*",
21818
- "@types/react": "^19",
21819
- tsup: "^8.5.1"
21820
- }
21821
- };
21822
- }
21823
- });
21824
-
21825
- // src/cli/version.ts
21826
- var cliVersion;
21827
- var init_version = __esm({
21828
- "src/cli/version.ts"() {
21829
- "use strict";
21830
- init_package();
21831
- cliVersion = package_default.version;
21832
- }
21833
- });
21834
-
21835
21922
  // src/tui/ApiClientContext.ts
21836
21923
  import { createContext, useContext } from "react";
21837
21924
  function useApiClient() {
@@ -27180,7 +27267,17 @@ var RuntimeBridgeBootstrapEnvelopeSchema = external_exports.object({
27180
27267
  var RuntimeBridgeBootstrapAckSchema = external_exports.object({
27181
27268
  status: external_exports.enum(["ready", "failed"]),
27182
27269
  error: external_exports.string().trim().min(1).optional(),
27183
- at: external_exports.string().datetime()
27270
+ at: external_exports.string().datetime(),
27271
+ // The sandbox-baked CLI's own release version (e.g. "0.1.95"), so the
27272
+ // bridge can tag bootstrap observability with the runtime version that is
27273
+ // actually live. Optional because runtimes older than the field predate
27274
+ // reporting it; the bridge logs those as "unknown" instead of failing.
27275
+ cliVersion: external_exports.string().trim().min(1).optional(),
27276
+ // Top-level bootstrap plaintext fields the runtime's tolerant parse
27277
+ // stripped because its schema does not know them yet (worker-ahead skew).
27278
+ // Reported so the bridge can log the degradation instead of it staying
27279
+ // silent.
27280
+ ignoredBootstrapKeys: external_exports.array(external_exports.string().trim().min(1)).optional()
27184
27281
  });
27185
27282
  var RuntimeBridgeConnectedPayloadSchema = external_exports.object({
27186
27283
  runId: SessionRunIdSchema,
@@ -27296,6 +27393,7 @@ function now() {
27296
27393
  }
27297
27394
 
27298
27395
  // ../../packages/protocol/src/bootstrap-crypto.ts
27396
+ init_zod();
27299
27397
  import {
27300
27398
  createCipheriv,
27301
27399
  createDecipheriv,
@@ -27325,7 +27423,16 @@ function decryptRuntimeBridgeBootstrap(input) {
27325
27423
  decipher.update(Buffer.from(envelope.bootstrap.ciphertext, "base64")),
27326
27424
  decipher.final()
27327
27425
  ]).toString("utf8");
27328
- return RuntimeBridgeBootstrapPlaintextSchema.parse(JSON.parse(plaintext));
27426
+ const raw = JSON.parse(plaintext);
27427
+ const bootstrap = RuntimeBridgeBootstrapPlaintextSchema.parse(raw);
27428
+ return { bootstrap, ignoredKeys: ignoredPlaintextKeys(raw) };
27429
+ }
27430
+ function ignoredPlaintextKeys(raw) {
27431
+ const record2 = external_exports.record(external_exports.string(), external_exports.unknown()).parse(raw);
27432
+ const knownKeys = new Set(
27433
+ Object.keys(RuntimeBridgeBootstrapPlaintextSchema.shape)
27434
+ );
27435
+ return Object.keys(record2).filter((key) => !knownKeys.has(key));
27329
27436
  }
27330
27437
  function deriveBootstrapKey(accessToken, salt) {
27331
27438
  return Buffer.from(
@@ -27346,6 +27453,7 @@ function bootstrapAdditionalData(input) {
27346
27453
  }
27347
27454
 
27348
27455
  // src/commands/agent-bridge/socket.ts
27456
+ init_version();
27349
27457
  import { io } from "socket.io-client";
27350
27458
  async function runAgentBridgeSocket(options) {
27351
27459
  const socket = io(`${options.bridgeUrl}${RUNTIME_BRIDGE_NAMESPACE}`, {
@@ -27481,13 +27589,18 @@ function createRuntimeBridgeBootstrapListener(input) {
27481
27589
  bridgeLeaseId: envelope.bridgeLeaseId
27482
27590
  });
27483
27591
  const decryptStartedAt = Date.now();
27484
- const bootstrap = decryptRuntimeBridgeBootstrap({
27592
+ const { bootstrap, ignoredKeys } = decryptRuntimeBridgeBootstrap({
27485
27593
  accessToken: input.token,
27486
27594
  envelope
27487
27595
  });
27488
27596
  input.writeOutput?.(
27489
27597
  `agent_bridge_bootstrap_decrypted duration_ms=${Date.now() - decryptStartedAt}`
27490
27598
  );
27599
+ if (ignoredKeys.length > 0) {
27600
+ input.writeOutput?.(
27601
+ `agent_bridge_bootstrap_ignored_keys cli_version=${cliVersion} keys=${ignoredKeys.join(",")}`
27602
+ );
27603
+ }
27491
27604
  await input.onBootstrap?.(bootstrap);
27492
27605
  let handler = input.getHandler();
27493
27606
  if (!handler) {
@@ -27503,7 +27616,9 @@ function createRuntimeBridgeBootstrapListener(input) {
27503
27616
  ack?.(
27504
27617
  RuntimeBridgeBootstrapAckSchema.parse({
27505
27618
  status: "ready",
27506
- at: (/* @__PURE__ */ new Date()).toISOString()
27619
+ at: (/* @__PURE__ */ new Date()).toISOString(),
27620
+ cliVersion,
27621
+ ignoredBootstrapKeys: ignoredKeys.length > 0 ? ignoredKeys : void 0
27507
27622
  })
27508
27623
  );
27509
27624
  prepare?.then(
@@ -27529,7 +27644,10 @@ function createRuntimeBridgeBootstrapListener(input) {
27529
27644
  RuntimeBridgeBootstrapAckSchema.parse({
27530
27645
  status: "failed",
27531
27646
  error: message,
27532
- at: (/* @__PURE__ */ new Date()).toISOString()
27647
+ at: (/* @__PURE__ */ new Date()).toISOString(),
27648
+ // Version skew is a leading cause of bootstrap failure, so failed
27649
+ // acks carry the version that could not bootstrap.
27650
+ cliVersion
27533
27651
  })
27534
27652
  );
27535
27653
  input.onBootstrapError(error51);
@@ -28824,7 +28942,8 @@ function registerApplyCommands(program, context) {
28824
28942
  apiBaseUrl: apiUrlFromOptions(context, commandOptions)
28825
28943
  },
28826
28944
  client: createContextApiClient(context),
28827
- writeOutput: context.writeOutput
28945
+ writeOutput: context.writeOutput,
28946
+ style: context.io.style
28828
28947
  });
28829
28948
  });
28830
28949
  }
@@ -28858,7 +28977,7 @@ function logout(context) {
28858
28977
  },
28859
28978
  context.configPath
28860
28979
  );
28861
- context.writeOutput("Logged out.");
28980
+ context.writeOutput(context.io.style.success("Logged out."));
28862
28981
  }
28863
28982
  function switchAccount(context, accountEmail, options = {}) {
28864
28983
  const profiles = listProfiles(context.configPath);
@@ -28868,7 +28987,9 @@ function switchAccount(context, accountEmail, options = {}) {
28868
28987
  const active = readConfig(context.configPath);
28869
28988
  if (!accountEmail) {
28870
28989
  for (const profile of profiles) {
28871
- context.writeOutput(accountLine(profile.config, active));
28990
+ context.writeOutput(
28991
+ accountLine(profile.config, active, context.io.style)
28992
+ );
28872
28993
  }
28873
28994
  return;
28874
28995
  }
@@ -28889,20 +29010,26 @@ function switchAccount(context, accountEmail, options = {}) {
28889
29010
  );
28890
29011
  }
28891
29012
  writeConfig(match, context.configPath);
28892
- context.writeOutput(`Switched to ${match.userEmail} (${match.serverUrl}).`);
29013
+ context.writeOutput(
29014
+ context.io.style.success(
29015
+ `Switched to ${match.userEmail} (${match.serverUrl}).`
29016
+ )
29017
+ );
28893
29018
  if (!match.refreshToken) {
28894
29019
  context.writeOutput(
28895
- "This account has no stored credentials; run `auto auth login`."
29020
+ context.io.style.warn(
29021
+ "This account has no stored credentials; run `auto auth login`."
29022
+ )
28896
29023
  );
28897
29024
  }
28898
29025
  }
28899
- function accountLine(config2, active) {
29026
+ function accountLine(config2, active, style) {
28900
29027
  const isActive = Boolean(config2.userEmail) && config2.userEmail === active.userEmail && config2.serverUrl === active.serverUrl;
28901
29028
  return [
28902
29029
  config2.userEmail,
28903
- `server=${config2.serverUrl ?? "(unset)"}`,
28904
- config2.refreshToken ? void 0 : "logged_out",
28905
- isActive ? "(active)" : void 0
29030
+ style.dim(`server=${config2.serverUrl ?? "(unset)"}`),
29031
+ config2.refreshToken ? void 0 : style.warn("logged_out"),
29032
+ isActive ? style.success("(active)") : void 0
28906
29033
  ].filter(Boolean).join(" ");
28907
29034
  }
28908
29035
  async function fetchAuthStatus(context) {
@@ -28951,47 +29078,68 @@ async function fetchAuthStatus(context) {
28951
29078
  return { ...base, token: { state: "invalid", error: message } };
28952
29079
  }
28953
29080
  }
28954
- function formatAuthStatusText(result, writeLine) {
28955
- writeLine(`server: ${result.serverUrl ?? "(unset)"}`);
29081
+ function formatAuthStatusText(result, writeLine, style) {
29082
+ const unset = style.dim("(unset)");
29083
+ writeLine(
29084
+ `${style.label("server:")} ${result.serverUrl ? style.url(result.serverUrl) : unset}`
29085
+ );
28956
29086
  if (result.account) {
28957
- writeLine(`account: ${result.account}`);
29087
+ writeLine(`${style.label("account:")} ${result.account}`);
28958
29088
  }
28959
- writeLine(`organization: ${result.organizationId ?? "(unset)"}`);
28960
- writeLine(`project: ${result.projectId ?? "(unset)"}`);
28961
29089
  writeLine(
28962
- `auth: ${result.authSource === "unset" ? "(unset)" : result.authSource}`
29090
+ `${style.label("organization:")} ${result.organizationId ? style.id(result.organizationId) : unset}`
29091
+ );
29092
+ writeLine(
29093
+ `${style.label("project:")} ${result.projectId ? style.id(result.projectId) : unset}`
29094
+ );
29095
+ writeLine(
29096
+ `${style.label("auth:")} ${result.authSource === "unset" ? unset : result.authSource}`
28963
29097
  );
28964
29098
  switch (result.token.state) {
28965
29099
  case "unset":
28966
29100
  return;
28967
29101
  case "not_validated":
28968
- writeLine(`token: not validated (${result.token.reason})`);
29102
+ writeLine(
29103
+ `${style.label("token:")} ${style.warn(`not validated (${result.token.reason})`)}`
29104
+ );
28969
29105
  return;
28970
29106
  case "valid":
28971
- writeLine("token: valid");
29107
+ writeLine(`${style.label("token:")} ${style.success("valid")}`);
28972
29108
  return;
28973
29109
  case "invalid":
28974
- writeLine(`token: invalid \u2014 ${result.token.error}`);
28975
- writeLine("hint: run `auto auth login` to refresh credentials");
29110
+ writeLine(
29111
+ `${style.label("token:")} ${style.error(`invalid \u2014 ${result.token.error}`)}`
29112
+ );
29113
+ writeLine(
29114
+ style.dim("hint: run `auto auth login` to refresh credentials")
29115
+ );
28976
29116
  return;
28977
29117
  }
28978
29118
  }
28979
- function formatWhoamiText(whoami, writeLine) {
28980
- writeLine(`actor: ${actorLabel(whoami)}`);
29119
+ function formatWhoamiText(whoami, writeLine, style) {
29120
+ writeLine(`${style.label("actor:")} ${actorLabel(whoami)}`);
28981
29121
  if (whoami.serviceAccount) {
28982
- writeLine(`service_account: ${whoami.serviceAccount.name}`);
29122
+ writeLine(
29123
+ `${style.label("service_account:")} ${style.id(whoami.serviceAccount.name)}`
29124
+ );
28983
29125
  }
28984
- writeLine(`organization: ${whoami.organizationId}`);
28985
- writeLine(`project: ${whoami.projectId ?? "(unset)"}`);
29126
+ writeLine(
29127
+ `${style.label("organization:")} ${style.id(whoami.organizationId)}`
29128
+ );
29129
+ writeLine(
29130
+ `${style.label("project:")} ${whoami.projectId ? style.id(whoami.projectId) : style.dim("(unset)")}`
29131
+ );
28986
29132
  const organizationName = whoami.organizationName ?? whoami.serviceAccount?.organization.name;
28987
29133
  const projectName = whoami.projectName ?? whoami.serviceAccount?.project.name;
28988
29134
  if (organizationName) {
28989
- writeLine(`organization_name: ${organizationName}`);
29135
+ writeLine(`${style.label("organization_name:")} ${organizationName}`);
28990
29136
  }
28991
29137
  if (projectName) {
28992
- writeLine(`project_name: ${projectName}`);
29138
+ writeLine(`${style.label("project_name:")} ${projectName}`);
28993
29139
  }
28994
- writeLine(`scopes: ${formatScopes(whoami.scopes)}`);
29140
+ writeLine(
29141
+ `${style.label("scopes:")} ${style.dim(formatScopes(whoami.scopes))}`
29142
+ );
28995
29143
  }
28996
29144
  function actorLabel(whoami) {
28997
29145
  const { principal } = whoami.actor;
@@ -29056,7 +29204,8 @@ function registerAuthCommands(program, context) {
29056
29204
  fetch: context.fetch,
29057
29205
  configPath: context.configPath,
29058
29206
  writeOutput: context.writeOutput,
29059
- writeError: context.writeError
29207
+ writeError: context.writeError,
29208
+ style: context.io.style
29060
29209
  });
29061
29210
  });
29062
29211
  auth.command("status").description(
@@ -29108,7 +29257,7 @@ async function confirmDestructiveAction(context, input) {
29108
29257
  }
29109
29258
 
29110
29259
  // src/commands/connections/format.ts
29111
- function connectionRows(connections) {
29260
+ function connectionRows(connections, style) {
29112
29261
  const rows = connections.flatMap(
29113
29262
  (connection) => connection.grants.map((grant) => ({
29114
29263
  provider: connection.provider,
@@ -29124,7 +29273,7 @@ function connectionRows(connections) {
29124
29273
  }))
29125
29274
  );
29126
29275
  if (rows.length === 0) {
29127
- return ["No connections found."];
29276
+ return [style.dim("No connections found.")];
29128
29277
  }
29129
29278
  const headers = {
29130
29279
  provider: "provider",
@@ -29142,18 +29291,25 @@ function connectionRows(connections) {
29142
29291
  )
29143
29292
  ])
29144
29293
  );
29294
+ const headerLine = [
29295
+ headers.provider.padEnd(widths.provider),
29296
+ headers.account.padEnd(widths.account),
29297
+ headers.grant.padEnd(widths.grant),
29298
+ headers.status.padEnd(widths.status),
29299
+ headers.projects
29300
+ ].join(" ");
29145
29301
  const format = (row) => [
29146
29302
  row.provider.padEnd(widths.provider),
29147
29303
  row.account.padEnd(widths.account),
29148
- row.grant.padEnd(widths.grant),
29149
- row.status.padEnd(widths.status),
29150
- row.projects
29304
+ style.id(row.grant.padEnd(widths.grant)),
29305
+ grantStatusStyle(style, row.status)(row.status.padEnd(widths.status)),
29306
+ style.dim(row.projects)
29151
29307
  ].join(" ");
29152
- return [format(headers), ...rows.map(format)];
29308
+ return [style.heading(headerLine), ...rows.map(format)];
29153
29309
  }
29154
- function providerRows(providers) {
29310
+ function providerRows(providers, style) {
29155
29311
  if (providers.length === 0) {
29156
- return ["No connection providers found."];
29312
+ return [style.dim("No connection providers found.")];
29157
29313
  }
29158
29314
  const rows = providers.map((provider) => ({
29159
29315
  provider: provider.provider,
@@ -29177,9 +29333,26 @@ function providerRows(providers) {
29177
29333
  const format = (row) => [
29178
29334
  row.provider.padEnd(widths.provider),
29179
29335
  row.name.padEnd(widths.name),
29180
- row.credential
29336
+ style.dim(row.credential)
29337
+ ].join(" ");
29338
+ const headerLine = [
29339
+ headers.provider.padEnd(widths.provider),
29340
+ headers.name.padEnd(widths.name),
29341
+ headers.credential
29181
29342
  ].join(" ");
29182
- return [format(headers), ...rows.map(format)];
29343
+ return [style.heading(headerLine), ...rows.map(format)];
29344
+ }
29345
+ function grantStatusStyle(style, status) {
29346
+ switch (status) {
29347
+ case "active":
29348
+ return style.success;
29349
+ case "error":
29350
+ return style.error;
29351
+ case "revoked":
29352
+ return style.dim;
29353
+ default:
29354
+ return (text) => text;
29355
+ }
29183
29356
  }
29184
29357
  function projectSummary(connection) {
29185
29358
  const projectIds = [
@@ -29591,7 +29764,7 @@ async function listConnectionsAction(context, commandOptions) {
29591
29764
  ).listConnectionProviders({
29592
29765
  apiBaseUrl
29593
29766
  });
29594
- for (const row of providerRows(result2.providers)) {
29767
+ for (const row of providerRows(result2.providers, context.io.style)) {
29595
29768
  context.writeOutput(row);
29596
29769
  }
29597
29770
  return;
@@ -29600,7 +29773,7 @@ async function listConnectionsAction(context, commandOptions) {
29600
29773
  provider: commandOptions.provider,
29601
29774
  apiBaseUrl
29602
29775
  });
29603
- for (const row of connectionRows(result.connections)) {
29776
+ for (const row of connectionRows(result.connections, context.io.style)) {
29604
29777
  context.writeOutput(row);
29605
29778
  }
29606
29779
  }
@@ -29647,11 +29820,14 @@ async function connectProviderAction(context, provider, commandOptions) {
29647
29820
  allowProjectId: commandOptions.allow,
29648
29821
  apiBaseUrl
29649
29822
  });
29823
+ const style = context.io.style;
29650
29824
  context.writeOutput(result.message);
29651
29825
  if (!result.authorizationUrl) {
29652
29826
  return;
29653
29827
  }
29654
- context.writeOutput(`authorization_url ${result.authorizationUrl}`);
29828
+ context.writeOutput(
29829
+ `${style.label("authorization_url")} ${style.url(result.authorizationUrl)}`
29830
+ );
29655
29831
  const connected = await finishConnectionAuthorization({
29656
29832
  apiBaseUrl,
29657
29833
  authorizationUrl: result.authorizationUrl,
@@ -29675,7 +29851,9 @@ async function connectProviderAction(context, provider, commandOptions) {
29675
29851
  apiBaseUrl
29676
29852
  });
29677
29853
  context.writeOutput(
29678
- `registered slack config token connection/${registered.connection} workspace/${registered.workspace}`
29854
+ style.success(
29855
+ `registered slack config token connection/${registered.connection} workspace/${registered.workspace}`
29856
+ )
29679
29857
  );
29680
29858
  }
29681
29859
  }
@@ -29701,10 +29879,15 @@ async function registerConfigTokenAction(context, provider, commandOptions) {
29701
29879
  refreshToken,
29702
29880
  apiBaseUrl: apiUrlFromOptions(context, commandOptions)
29703
29881
  });
29882
+ const style = context.io.style;
29883
+ context.writeOutput(
29884
+ style.success(
29885
+ `registered slack config token connection/${result.connection} workspace/${result.workspace}`
29886
+ )
29887
+ );
29704
29888
  context.writeOutput(
29705
- `registered slack config token connection/${result.connection} workspace/${result.workspace}`
29889
+ `${style.label("expires_at")} ${style.dim(result.expiresAt)}`
29706
29890
  );
29707
- context.writeOutput(`expires_at ${result.expiresAt}`);
29708
29891
  }
29709
29892
  async function readTrimmedStream(stream) {
29710
29893
  const chunks = [];
@@ -29759,7 +29942,11 @@ async function replaceConnectionAction(context, provider, commandOptions) {
29759
29942
  if (!result.authorizationUrl) {
29760
29943
  return;
29761
29944
  }
29762
- context.writeOutput(`authorization_url ${result.authorizationUrl}`);
29945
+ context.writeOutput(
29946
+ `${context.io.style.label("authorization_url")} ${context.io.style.url(
29947
+ result.authorizationUrl
29948
+ )}`
29949
+ );
29763
29950
  await finishConnectionAuthorization({
29764
29951
  apiBaseUrl,
29765
29952
  authorizationUrl: result.authorizationUrl,
@@ -29922,11 +30109,17 @@ init_file();
29922
30109
  function createDirectoryClient(context) {
29923
30110
  return createContextApiClient(context);
29924
30111
  }
29925
- function organizationLine(organization) {
29926
- return `${organization.organizationName} (${organization.organizationSlug}) role=${organization.role}`;
30112
+ function organizationLine(organization, style) {
30113
+ return `${organization.organizationName} ${style.id(
30114
+ `(${organization.organizationSlug})`
30115
+ )} ${style.dim(`role=${organization.role}`)}`;
29927
30116
  }
29928
- function projectLine(project) {
29929
- return `${project.organizationName} (${project.organizationSlug}) / ${project.projectName} (${project.projectSlug}) role=${project.role}`;
30117
+ function projectLine(project, style) {
30118
+ return `${project.organizationName} ${style.id(
30119
+ `(${project.organizationSlug})`
30120
+ )} / ${project.projectName} ${style.id(`(${project.projectSlug})`)} ${style.dim(
30121
+ `role=${project.role}`
30122
+ )}`;
29930
30123
  }
29931
30124
  function setActiveOrganization(context, organizationId) {
29932
30125
  persistActiveOrganization(context.configPath, organizationId);
@@ -30083,10 +30276,13 @@ function registerOrganizationCommands(program, context) {
30083
30276
  const orgs = program.command("orgs").description("Manage the active organization.");
30084
30277
  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(
30085
30278
  async (organizationIdentifier, options) => {
30279
+ const style = context.io.style;
30086
30280
  if (organizationIdentifier.startsWith("org_")) {
30087
30281
  setActiveOrganization(context, organizationIdentifier);
30088
30282
  context.writeOutput(
30089
- `Active organization set to ${organizationIdentifier}`
30283
+ style.success(
30284
+ `Active organization set to ${organizationIdentifier}`
30285
+ )
30090
30286
  );
30091
30287
  return;
30092
30288
  }
@@ -30097,7 +30293,9 @@ function registerOrganizationCommands(program, context) {
30097
30293
  });
30098
30294
  setActiveOrganization(context, organization.organizationId);
30099
30295
  context.writeOutput(
30100
- `Active organization set to ${organization.organizationName}`
30296
+ style.success(
30297
+ `Active organization set to ${organization.organizationName}`
30298
+ )
30101
30299
  );
30102
30300
  }
30103
30301
  );
@@ -30106,22 +30304,23 @@ function registerOrganizationCommands(program, context) {
30106
30304
  apiBaseUrl: apiUrlFromOptions(context, options)
30107
30305
  });
30108
30306
  if (response.organizations.length === 0) {
30109
- context.writeOutput("No organizations found.");
30307
+ context.writeOutput(context.io.style.dim("No organizations found."));
30110
30308
  return;
30111
30309
  }
30112
30310
  for (const organization of response.organizations) {
30113
- context.writeOutput(organizationLine(organization));
30311
+ context.writeOutput(organizationLine(organization, context.io.style));
30114
30312
  }
30115
30313
  });
30116
30314
  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) => {
30315
+ const style = context.io.style;
30117
30316
  const response = await createDirectoryClient(context).createOrganization({
30118
30317
  organizationName: options.name,
30119
30318
  projectName: options.projectName,
30120
30319
  apiBaseUrl: apiUrlFromOptions(context, options)
30121
30320
  });
30122
- context.writeOutput(organizationLine(response.organization));
30321
+ context.writeOutput(organizationLine(response.organization, style));
30123
30322
  if (response.project) {
30124
- context.writeOutput(projectLine(response.project));
30323
+ context.writeOutput(projectLine(response.project, style));
30125
30324
  }
30126
30325
  if (options.use) {
30127
30326
  if (response.project) {
@@ -30130,11 +30329,15 @@ function registerOrganizationCommands(program, context) {
30130
30329
  setActiveOrganization(context, response.organization.organizationId);
30131
30330
  }
30132
30331
  context.writeOutput(
30133
- `Active organization set to ${response.organization.organizationName}`
30332
+ style.success(
30333
+ `Active organization set to ${response.organization.organizationName}`
30334
+ )
30134
30335
  );
30135
30336
  if (response.project) {
30136
30337
  context.writeOutput(
30137
- `Active project set to ${response.project.projectName}`
30338
+ style.success(
30339
+ `Active project set to ${response.project.projectName}`
30340
+ )
30138
30341
  );
30139
30342
  }
30140
30343
  }
@@ -30149,9 +30352,12 @@ function registerOrganizationCommands(program, context) {
30149
30352
  role: options.role,
30150
30353
  apiBaseUrl: apiUrlFromOptions(context, options)
30151
30354
  });
30152
- const status = response.created === false ? "Invitation already pending" : "Invited";
30355
+ const style = context.io.style;
30356
+ const status = response.created === false ? style.warn("Invitation already pending") : style.success("Invited");
30153
30357
  context.writeOutput(
30154
- `${status} ${response.invitation.targetEmail} to ${response.invitation.organizationName} role=${response.invitation.role}`
30358
+ `${status} ${response.invitation.targetEmail} to ${response.invitation.organizationName} ${style.dim(
30359
+ `role=${response.invitation.role}`
30360
+ )}`
30155
30361
  );
30156
30362
  });
30157
30363
  const members = orgs.command("members").description("Manage active organization members.");
@@ -30162,11 +30368,13 @@ function registerOrganizationCommands(program, context) {
30162
30368
  apiBaseUrl: apiUrlFromOptions(context, options)
30163
30369
  });
30164
30370
  if (response.memberships.length === 0) {
30165
- context.writeOutput("No organization members found.");
30371
+ context.writeOutput(
30372
+ context.io.style.dim("No organization members found.")
30373
+ );
30166
30374
  return;
30167
30375
  }
30168
30376
  for (const member of response.memberships) {
30169
- context.writeOutput(memberLine(member));
30377
+ context.writeOutput(memberLine(member, context.io.style));
30170
30378
  }
30171
30379
  });
30172
30380
  members.command("add").description("Invite a user to the active organization by email.").requiredOption("--email <email>", "Email address to invite").addOption(
@@ -30179,9 +30387,12 @@ function registerOrganizationCommands(program, context) {
30179
30387
  role: options.role,
30180
30388
  apiBaseUrl: apiUrlFromOptions(context, options)
30181
30389
  });
30182
- const status = response.created === false ? "Invitation already pending" : "Invited";
30390
+ const style = context.io.style;
30391
+ const status = response.created === false ? style.warn("Invitation already pending") : style.success("Invited");
30183
30392
  context.writeOutput(
30184
- `${status} ${response.invitation.targetEmail} to ${response.invitation.organizationName} role=${response.invitation.role}`
30393
+ `${status} ${response.invitation.targetEmail} to ${response.invitation.organizationName} ${style.dim(
30394
+ `role=${response.invitation.role}`
30395
+ )}`
30185
30396
  );
30186
30397
  });
30187
30398
  members.command("set-role").description("Set an existing active organization member's role.").requiredOption("--email <email>", "Email address of an existing member").addOption(
@@ -30194,9 +30405,12 @@ function registerOrganizationCommands(program, context) {
30194
30405
  role: options.role,
30195
30406
  apiBaseUrl: apiUrlFromOptions(context, options)
30196
30407
  });
30197
- const status = response.updated ? "Updated" : "Unchanged";
30408
+ const style = context.io.style;
30409
+ const status = response.updated ? style.success("Updated") : style.dim("Unchanged");
30198
30410
  context.writeOutput(
30199
- `${status} ${options.email} in ${response.membership.organizationName} role=${response.previousRole}->${response.membership.role}`
30411
+ `${status} ${options.email} in ${response.membership.organizationName} ${style.dim(
30412
+ `role=${response.previousRole}->${response.membership.role}`
30413
+ )}`
30200
30414
  );
30201
30415
  });
30202
30416
  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) => {
@@ -30210,17 +30424,20 @@ function registerOrganizationCommands(program, context) {
30210
30424
  email: options.email,
30211
30425
  apiBaseUrl: apiUrlFromOptions(context, options)
30212
30426
  });
30427
+ const style = context.io.style;
30213
30428
  context.writeOutput(
30214
- `Removed ${options.email} from ${response.membership.organizationName} role=${response.previousRole} project_memberships=${response.removedProjectMemberships ?? 0}`
30429
+ `${style.success("Removed")} ${options.email} from ${response.membership.organizationName} ${style.dim(
30430
+ `role=${response.previousRole} project_memberships=${response.removedProjectMemberships ?? 0}`
30431
+ )}`
30215
30432
  );
30216
30433
  });
30217
30434
  }
30218
- function memberLine(member) {
30435
+ function memberLine(member, style) {
30219
30436
  return [
30220
30437
  member.primaryEmail,
30221
- `role=${member.role}`,
30222
- member.displayName ? `name=${member.displayName}` : void 0,
30223
- member.disabledAt ? `disabled_at=${member.disabledAt}` : void 0
30438
+ style.dim(`role=${member.role}`),
30439
+ member.displayName ? style.dim(`name=${member.displayName}`) : void 0,
30440
+ member.disabledAt ? style.warn(`disabled_at=${member.disabledAt}`) : void 0
30224
30441
  ].filter(Boolean).join(" ");
30225
30442
  }
30226
30443
 
@@ -30241,15 +30458,13 @@ async function fetchProjects(context, options) {
30241
30458
  });
30242
30459
  return { projects: response.projects };
30243
30460
  }
30244
- function formatProjectsText(result, writeLine) {
30461
+ function formatProjectsText(result, writeLine, style) {
30245
30462
  if (result.projects.length === 0) {
30246
- writeLine("No projects found.");
30463
+ writeLine(style.dim("No projects found."));
30247
30464
  return;
30248
30465
  }
30249
30466
  for (const project of result.projects) {
30250
- writeLine(
30251
- `${project.organizationName} (${project.organizationSlug}) / ${project.projectName} (${project.projectSlug}) role=${project.role}`
30252
- );
30467
+ writeLine(projectLine(project, style));
30253
30468
  }
30254
30469
  }
30255
30470
 
@@ -30258,13 +30473,16 @@ function registerProjectCommands(program, context) {
30258
30473
  const projects = program.command("projects").description("List, create, and select Auto projects.");
30259
30474
  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(
30260
30475
  async (projectIdentifier, options) => {
30476
+ const style = context.io.style;
30261
30477
  if (projectIdentifier.startsWith("proj_")) {
30262
30478
  const config2 = readConfig(context.configPath);
30263
30479
  writeConfig(
30264
30480
  clearAccessToken({ ...config2, projectId: projectIdentifier }),
30265
30481
  context.configPath
30266
30482
  );
30267
- context.writeOutput(`Active project set to ${projectIdentifier}`);
30483
+ context.writeOutput(
30484
+ style.success(`Active project set to ${projectIdentifier}`)
30485
+ );
30268
30486
  return;
30269
30487
  }
30270
30488
  const project = await resolveProject({
@@ -30275,9 +30493,13 @@ function registerProjectCommands(program, context) {
30275
30493
  });
30276
30494
  setActiveProject(context, project);
30277
30495
  context.writeOutput(
30278
- `Active organization set to ${project.organizationName}`
30496
+ style.success(
30497
+ `Active organization set to ${project.organizationName}`
30498
+ )
30499
+ );
30500
+ context.writeOutput(
30501
+ style.success(`Active project set to ${project.projectName}`)
30279
30502
  );
30280
- context.writeOutput(`Active project set to ${project.projectName}`);
30281
30503
  }
30282
30504
  );
30283
30505
  projects.command("list").description(
@@ -30286,18 +30508,23 @@ function registerProjectCommands(program, context) {
30286
30508
  await handleProjectsList(context, options);
30287
30509
  });
30288
30510
  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) => {
30511
+ const style = context.io.style;
30289
30512
  const response = await createDirectoryClient(context).createProject({
30290
30513
  projectName: options.name,
30291
30514
  apiBaseUrl: apiUrlFromOptions(context, options)
30292
30515
  });
30293
- context.writeOutput(projectLine(response.project));
30516
+ context.writeOutput(projectLine(response.project, style));
30294
30517
  if (options.use) {
30295
30518
  setActiveProject(context, response.project);
30296
30519
  context.writeOutput(
30297
- `Active organization set to ${response.project.organizationName}`
30520
+ style.success(
30521
+ `Active organization set to ${response.project.organizationName}`
30522
+ )
30298
30523
  );
30299
30524
  context.writeOutput(
30300
- `Active project set to ${response.project.projectName}`
30525
+ style.success(
30526
+ `Active project set to ${response.project.projectName}`
30527
+ )
30301
30528
  );
30302
30529
  }
30303
30530
  });
@@ -30311,9 +30538,12 @@ function registerProjectCommands(program, context) {
30311
30538
  apiBaseUrl: apiUrlFromOptions(context, options)
30312
30539
  }
30313
30540
  );
30314
- const status = response.created === false ? "Invitation already pending" : "Invited";
30541
+ const style = context.io.style;
30542
+ const status = response.created === false ? style.warn("Invitation already pending") : style.success("Invited");
30315
30543
  context.writeOutput(
30316
- `${status} ${response.invitation.targetEmail} to ${response.invitation.projectName} role=${response.invitation.role}`
30544
+ `${status} ${response.invitation.targetEmail} to ${response.invitation.projectName} ${style.dim(
30545
+ `role=${response.invitation.role}`
30546
+ )}`
30317
30547
  );
30318
30548
  });
30319
30549
  const members = projects.command("members").description("Manage active project members.");
@@ -30322,11 +30552,11 @@ function registerProjectCommands(program, context) {
30322
30552
  apiBaseUrl: apiUrlFromOptions(context, options)
30323
30553
  });
30324
30554
  if (response.memberships.length === 0) {
30325
- context.writeOutput("No project members found.");
30555
+ context.writeOutput(context.io.style.dim("No project members found."));
30326
30556
  return;
30327
30557
  }
30328
30558
  for (const member of response.memberships) {
30329
- context.writeOutput(memberLine2(member));
30559
+ context.writeOutput(memberLine2(member, context.io.style));
30330
30560
  }
30331
30561
  });
30332
30562
  members.command("add").description("Invite a user to the active project by email.").requiredOption("--email <email>", "Email address to invite").addOption(
@@ -30337,9 +30567,12 @@ function registerProjectCommands(program, context) {
30337
30567
  role: options.role,
30338
30568
  apiBaseUrl: apiUrlFromOptions(context, options)
30339
30569
  });
30340
- const status = response.created === false ? "Invitation already pending" : "Invited";
30570
+ const style = context.io.style;
30571
+ const status = response.created === false ? style.warn("Invitation already pending") : style.success("Invited");
30341
30572
  context.writeOutput(
30342
- `${status} ${response.invitation.targetEmail} to ${response.invitation.projectName} role=${response.invitation.role}`
30573
+ `${status} ${response.invitation.targetEmail} to ${response.invitation.projectName} ${style.dim(
30574
+ `role=${response.invitation.role}`
30575
+ )}`
30343
30576
  );
30344
30577
  });
30345
30578
  members.command("set-role").description("Set an existing active project member's role.").requiredOption("--email <email>", "Email address of an existing member").addOption(
@@ -30352,9 +30585,12 @@ function registerProjectCommands(program, context) {
30352
30585
  role: options.role,
30353
30586
  apiBaseUrl: apiUrlFromOptions(context, options)
30354
30587
  });
30355
- const status = response.updated ? "Updated" : "Unchanged";
30588
+ const style = context.io.style;
30589
+ const status = response.updated ? style.success("Updated") : style.dim("Unchanged");
30356
30590
  context.writeOutput(
30357
- `${status} ${options.email} in ${response.membership.projectName} role=${response.previousRole}->${response.membership.role}`
30591
+ `${status} ${options.email} in ${response.membership.projectName} ${style.dim(
30592
+ `role=${response.previousRole}->${response.membership.role}`
30593
+ )}`
30358
30594
  );
30359
30595
  });
30360
30596
  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) => {
@@ -30368,17 +30604,20 @@ function registerProjectCommands(program, context) {
30368
30604
  apiBaseUrl: apiUrlFromOptions(context, options)
30369
30605
  }
30370
30606
  );
30607
+ const style = context.io.style;
30371
30608
  context.writeOutput(
30372
- `Removed ${options.email} from ${response.membership.projectName} role=${response.previousRole}`
30609
+ `${style.success("Removed")} ${options.email} from ${response.membership.projectName} ${style.dim(
30610
+ `role=${response.previousRole}`
30611
+ )}`
30373
30612
  );
30374
30613
  });
30375
30614
  }
30376
- function memberLine2(member) {
30615
+ function memberLine2(member, style) {
30377
30616
  return [
30378
30617
  member.primaryEmail,
30379
- `role=${member.role}`,
30380
- member.displayName ? `name=${member.displayName}` : void 0,
30381
- member.disabledAt ? `disabled_at=${member.disabledAt}` : void 0
30618
+ style.dim(`role=${member.role}`),
30619
+ member.displayName ? style.dim(`name=${member.displayName}`) : void 0,
30620
+ member.disabledAt ? style.warn(`disabled_at=${member.disabledAt}`) : void 0
30382
30621
  ].filter(Boolean).join(" ");
30383
30622
  }
30384
30623
 
@@ -30597,6 +30836,61 @@ function pollUntilFailed(input) {
30597
30836
  return { done, cancel };
30598
30837
  }
30599
30838
 
30839
+ // src/commands/runs/list.ts
30840
+ async function handleRunsList(context, sessionName, options = {}) {
30841
+ const result = await fetchRuns(context, sessionName, options);
30842
+ context.io.writeResult(result, formatRunsText);
30843
+ }
30844
+ async function fetchRuns(context, sessionName, options) {
30845
+ const client = createContextApiClient(context);
30846
+ const clientOptions = {
30847
+ apiBaseUrl: apiUrlFromOptions(context, options),
30848
+ includeArchived: options.includeArchived,
30849
+ statuses: options.status,
30850
+ since: options.since,
30851
+ limit: options.limit
30852
+ };
30853
+ const response = sessionName ? await client.listSessionRuns(sessionName, clientOptions) : await client.listRuns(clientOptions);
30854
+ return {
30855
+ session: sessionName ?? null,
30856
+ runs: response.runs,
30857
+ includeArchived: Boolean(options.includeArchived)
30858
+ };
30859
+ }
30860
+ function formatRunsText(result, writeLine, style) {
30861
+ if (result.runs.length === 0) {
30862
+ writeLine(
30863
+ style.dim(
30864
+ result.session ? `No runs found for session ${result.session}.` : "No runs found in the current project."
30865
+ )
30866
+ );
30867
+ return;
30868
+ }
30869
+ for (const run of result.runs) {
30870
+ const archived = run.archivedAt ? ` ${style.dim(`archived_at=${run.archivedAt}`)}` : "";
30871
+ writeLine(
30872
+ `${style.id(run.id)} ${styleRunStatus(style, run.status)} ${style.dim(
30873
+ run.createdAt
30874
+ )}${archived}`
30875
+ );
30876
+ }
30877
+ }
30878
+ function styleRunStatus(style, status) {
30879
+ switch (status) {
30880
+ case "failed":
30881
+ return style.error(status);
30882
+ case "running":
30883
+ return style.success(status);
30884
+ case "awaiting":
30885
+ return style.warn(status);
30886
+ case "stopped":
30887
+ case "queued":
30888
+ return style.dim(status);
30889
+ default:
30890
+ return status;
30891
+ }
30892
+ }
30893
+
30600
30894
  // src/commands/runs/service.ts
30601
30895
  function createRunServiceClient(context) {
30602
30896
  return createContextApiClient(context);
@@ -30611,9 +30905,14 @@ async function interactiveRunAction(context, sessionName, commandOptions) {
30611
30905
  interactive: true,
30612
30906
  apiBaseUrl
30613
30907
  });
30614
- context.writeOutput(`run_id ${created.run_id}`);
30615
- context.writeOutput(`workflow_id ${created.workflow_id}`);
30616
- context.writeOutput(`status ${created.status}`);
30908
+ const style = context.io.style;
30909
+ context.writeOutput(`${style.label("run_id")} ${style.id(created.run_id)}`);
30910
+ context.writeOutput(
30911
+ `${style.label("workflow_id")} ${style.id(created.workflow_id)}`
30912
+ );
30913
+ context.writeOutput(
30914
+ `${style.label("status")} ${styleRunStatus(style, created.status)}`
30915
+ );
30617
30916
  await runConsole({
30618
30917
  client,
30619
30918
  runId: created.run_id,
@@ -30639,35 +30938,50 @@ async function archiveRunAction(context, runId, commandOptions) {
30639
30938
  const run = await createRunServiceClient(context).archiveRun(runId, {
30640
30939
  apiBaseUrl: apiUrlFromOptions(context, commandOptions)
30641
30940
  });
30642
- context.writeOutput(`run_id ${run.id}`);
30643
- context.writeOutput(`archived_at ${run.archivedAt ?? ""}`);
30941
+ const style = context.io.style;
30942
+ context.writeOutput(`${style.label("run_id")} ${style.id(run.id)}`);
30943
+ context.writeOutput(
30944
+ `${style.label("archived_at")} ${style.dim(run.archivedAt ?? "")}`
30945
+ );
30644
30946
  }
30645
30947
  async function archiveRunsAction(context, runIds, commandOptions) {
30646
30948
  const result = await createRunServiceClient(context).archiveRuns(runIds, {
30647
30949
  apiBaseUrl: apiUrlFromOptions(context, commandOptions)
30648
30950
  });
30951
+ const style = context.io.style;
30649
30952
  for (const run of result.runs) {
30650
- context.writeOutput(`run_id ${run.id} archived_at ${run.archivedAt ?? ""}`);
30953
+ context.writeOutput(
30954
+ `${style.label("run_id")} ${style.id(run.id)} ${style.label(
30955
+ "archived_at"
30956
+ )} ${style.dim(run.archivedAt ?? "")}`
30957
+ );
30651
30958
  }
30652
30959
  }
30653
30960
  async function unarchiveRunAction(context, runId, commandOptions) {
30654
30961
  const run = await createRunServiceClient(context).unarchiveRun(runId, {
30655
30962
  apiBaseUrl: apiUrlFromOptions(context, commandOptions)
30656
30963
  });
30657
- context.writeOutput(`run_id ${run.id}`);
30658
- context.writeOutput(`archived ${Boolean(run.archivedAt)}`);
30964
+ const style = context.io.style;
30965
+ context.writeOutput(`${style.label("run_id")} ${style.id(run.id)}`);
30966
+ context.writeOutput(`${style.label("archived")} ${Boolean(run.archivedAt)}`);
30659
30967
  }
30660
30968
  async function unarchiveRunsAction(context, runIds, commandOptions) {
30661
30969
  const result = await createRunServiceClient(context).unarchiveRuns(runIds, {
30662
30970
  apiBaseUrl: apiUrlFromOptions(context, commandOptions)
30663
30971
  });
30972
+ const style = context.io.style;
30664
30973
  for (const run of result.runs) {
30665
- context.writeOutput(`run_id ${run.id} archived ${Boolean(run.archivedAt)}`);
30974
+ context.writeOutput(
30975
+ `${style.label("run_id")} ${style.id(run.id)} ${style.label(
30976
+ "archived"
30977
+ )} ${Boolean(run.archivedAt)}`
30978
+ );
30666
30979
  }
30667
30980
  }
30668
30981
  async function stopRunsAction(context, runIds, commandOptions) {
30669
30982
  const client = createRunServiceClient(context);
30670
30983
  const apiBaseUrl = apiUrlFromOptions(context, commandOptions);
30984
+ const style = context.io.style;
30671
30985
  const failedRunIds = [];
30672
30986
  for (const runId of runIds) {
30673
30987
  try {
@@ -30676,12 +30990,16 @@ async function stopRunsAction(context, runIds, commandOptions) {
30676
30990
  reason: commandOptions.reason
30677
30991
  });
30678
30992
  context.writeOutput(
30679
- `run_id ${runId} command_id ${command.command_id} status ${command.status}`
30993
+ `${style.label("run_id")} ${style.id(runId)} ${style.label(
30994
+ "command_id"
30995
+ )} ${style.id(command.command_id)} ${style.label("status")} ${command.status}`
30680
30996
  );
30681
30997
  } catch (error51) {
30682
30998
  failedRunIds.push(runId);
30683
30999
  context.writeOutput(
30684
- `run_id ${runId} error ${error51 instanceof Error ? error51.message : String(error51)}`
31000
+ `${style.label("run_id")} ${style.id(runId)} ${style.error(
31001
+ `error ${error51 instanceof Error ? error51.message : String(error51)}`
31002
+ )}`
30685
31003
  );
30686
31004
  }
30687
31005
  }
@@ -30712,8 +31030,11 @@ async function sendRunMessageAction(context, runId, message, commandOptions) {
30712
31030
  apiBaseUrl: apiUrlFromOptions(context, commandOptions)
30713
31031
  }
30714
31032
  );
30715
- context.writeOutput(`command_id ${command.command_id}`);
30716
- context.writeOutput(`status ${command.status}`);
31033
+ const style = context.io.style;
31034
+ context.writeOutput(
31035
+ `${style.label("command_id")} ${style.id(command.command_id)}`
31036
+ );
31037
+ context.writeOutput(`${style.label("status")} ${command.status}`);
30717
31038
  }
30718
31039
 
30719
31040
  // src/commands/runs/benchmark-startup.ts
@@ -30950,49 +31271,65 @@ async function handleRunsShow(context, runId, options = {}) {
30950
31271
  ]);
30951
31272
  context.io.writeResult({ run, summary }, formatRunShowText);
30952
31273
  }
30953
- function formatRunShowText(result, writeLine) {
31274
+ function formatRunShowText(result, writeLine, style) {
30954
31275
  const { summary } = result;
30955
31276
  writeLine(
30956
- `${summary.run.id} ${summary.run.status} session=${summary.run.sessionName} profile=${summary.run.profileName}`
31277
+ `${style.id(summary.run.id)} ${styleRunStatus(style, summary.run.status)} ${style.dim(
31278
+ `session=${summary.run.sessionName} profile=${summary.run.profileName}`
31279
+ )}`
30957
31280
  );
30958
31281
  if (summary.run.displayTitle) {
30959
- writeLine(`title: ${summary.run.displayTitle}`);
31282
+ writeLine(`${style.label("title:")} ${summary.run.displayTitle}`);
30960
31283
  }
30961
31284
  writeLine(
30962
- `created=${summary.run.createdAt} started=${summary.run.startedAt ?? "-"} finished=${summary.run.finishedAt ?? "-"}`
31285
+ style.dim(
31286
+ `created=${summary.run.createdAt} started=${summary.run.startedAt ?? "-"} finished=${summary.run.finishedAt ?? "-"}`
31287
+ )
30963
31288
  );
30964
31289
  writeLine(
30965
- `timing: queued=${formatMs(summary.timing.queuedMs)} active=${formatMs(summary.timing.activeMs)} total=${formatMs(summary.timing.totalMs)}`
31290
+ `${style.label("timing:")} ${style.dim(
31291
+ `queued=${formatMs(summary.timing.queuedMs)} active=${formatMs(summary.timing.activeMs)} total=${formatMs(summary.timing.totalMs)}`
31292
+ )}`
30966
31293
  );
30967
31294
  writeLine(
30968
- `entries=${summary.conversation.entryCount} failed=${summary.conversation.failedEntryCount} turns=${summary.turns.length} lastSequence=${summary.conversation.lastSequence}`
31295
+ style.dim(
31296
+ `entries=${summary.conversation.entryCount} failed=${summary.conversation.failedEntryCount} turns=${summary.turns.length} lastSequence=${summary.conversation.lastSequence}`
31297
+ )
30969
31298
  );
30970
31299
  writeLine(
30971
- `trigger: spawn=${summary.trigger.spawn} signaled=${summary.trigger.signaledCount} dropped=${summary.trigger.droppedCount}`
31300
+ `${style.label("trigger:")} spawn=${summary.trigger.spawn} ${style.dim(
31301
+ `signaled=${summary.trigger.signaledCount} dropped=${summary.trigger.droppedCount}`
31302
+ )}`
30972
31303
  );
30973
31304
  if (summary.artifacts.count > 0) {
30974
31305
  writeLine(
30975
- `artifacts: ${summary.artifacts.count} (${summary.artifacts.types.join(", ")})`
31306
+ `${style.label("artifacts:")} ${summary.artifacts.count} ${style.dim(
31307
+ `(${summary.artifacts.types.join(", ")})`
31308
+ )}`
30976
31309
  );
30977
31310
  }
30978
31311
  writeLine(
30979
- `commands: ${summary.commands.total} failed=${summary.commands.failed}`
31312
+ `${style.label("commands:")} ${summary.commands.total} ${style.dim(
31313
+ `failed=${summary.commands.failed}`
31314
+ )}`
30980
31315
  );
30981
31316
  if (summary.tools.length > 0) {
30982
- writeLine("tools:");
31317
+ writeLine(style.label("tools:"));
30983
31318
  for (const tool of summary.tools) {
30984
31319
  writeLine(
30985
- ` ${tool.name} calls=${tool.calls} errors=${tool.errors} p50=${formatMs(tool.durationMs.p50)} max=${formatMs(tool.durationMs.max)}`
31320
+ ` ${tool.name} ${style.dim(
31321
+ `calls=${tool.calls} errors=${tool.errors} p50=${formatMs(tool.durationMs.p50)} max=${formatMs(tool.durationMs.max)}`
31322
+ )}`
30986
31323
  );
30987
31324
  }
30988
31325
  }
30989
31326
  for (const check2 of summary.checks) {
30990
31327
  writeLine(
30991
- `check: ${check2.name} ${check2.status}${check2.conclusion ? ` ${check2.conclusion}` : ""}`
31328
+ `${style.label("check:")} ${check2.name} ${check2.status}${check2.conclusion ? ` ${styleCheckConclusion(style, check2.conclusion)}` : ""}`
30992
31329
  );
30993
31330
  }
30994
31331
  if (summary.run.error !== null) {
30995
- writeLine(`error: ${JSON.stringify(summary.run.error)}`);
31332
+ writeLine(style.error(`error: ${JSON.stringify(summary.run.error)}`));
30996
31333
  }
30997
31334
  }
30998
31335
  async function handleRunsConversation(context, runId, options = {}) {
@@ -31019,25 +31356,31 @@ async function handleRunsConversation(context, runId, options = {}) {
31019
31356
  formatConversationText
31020
31357
  );
31021
31358
  }
31022
- function formatConversationText(result, writeLine) {
31359
+ function formatConversationText(result, writeLine, style) {
31023
31360
  if (result.events.length === 0) {
31024
- writeLine("No conversation entries.");
31361
+ writeLine(style.dim("No conversation entries."));
31025
31362
  return;
31026
31363
  }
31027
31364
  for (const event of result.events) {
31028
- const failed = event.status === "failed" ? " FAILED" : "";
31365
+ const failed = event.status === "failed" ? ` ${style.error("FAILED")}` : "";
31029
31366
  writeLine(
31030
- `${event.sequence} ${event.role}/${event.kind}${failed}: ${entryPreview(event, result.full)}`
31367
+ `${style.dim(String(event.sequence))} ${style.label(
31368
+ `${event.role}/${event.kind}`
31369
+ )}${failed}: ${entryPreview(event, result.full)}`
31031
31370
  );
31032
31371
  }
31033
31372
  if (result.hasMore) {
31034
31373
  if (result.tailMode) {
31035
31374
  const oldest = result.events[0]?.sequence;
31036
31375
  writeLine(
31037
- `(more older entries; rerun with --before ${oldest ?? "<sequence>"})`
31376
+ style.dim(
31377
+ `(more older entries; rerun with --before ${oldest ?? "<sequence>"})`
31378
+ )
31038
31379
  );
31039
31380
  } else {
31040
- writeLine(`(more entries; continue with --after ${result.cursor})`);
31381
+ writeLine(
31382
+ style.dim(`(more entries; continue with --after ${result.cursor})`)
31383
+ );
31041
31384
  }
31042
31385
  }
31043
31386
  }
@@ -31051,21 +31394,25 @@ async function handleRunsSearch(context, runId, queries, options = {}) {
31051
31394
  });
31052
31395
  context.io.writeResult({ runId, queries, ...response }, formatSearchText);
31053
31396
  }
31054
- function formatSearchText(result, writeLine) {
31397
+ function formatSearchText(result, writeLine, style) {
31055
31398
  if (result.matches.length === 0) {
31056
- writeLine(`No matches for: ${result.queries.join(", ")}`);
31399
+ writeLine(style.dim(`No matches for: ${result.queries.join(", ")}`));
31057
31400
  return;
31058
31401
  }
31059
31402
  for (const match of result.matches) {
31060
31403
  for (const snippet of match.snippets) {
31061
31404
  writeLine(
31062
- `${match.sequence} ${match.kind} [${snippet.query}]: ${singleLine(snippet.text)}`
31405
+ `${style.dim(String(match.sequence))} ${match.kind} ${style.label(
31406
+ `[${snippet.query}]`
31407
+ )}: ${singleLine(snippet.text)}`
31063
31408
  );
31064
31409
  }
31065
31410
  }
31066
31411
  if (result.hasMore) {
31067
31412
  writeLine(
31068
- `(more scanned entries; continue with --after ${result.nextAfterSequence ?? "<sequence>"})`
31413
+ style.dim(
31414
+ `(more scanned entries; continue with --after ${result.nextAfterSequence ?? "<sequence>"})`
31415
+ )
31069
31416
  );
31070
31417
  }
31071
31418
  }
@@ -31081,29 +31428,33 @@ async function handleRunsTools(context, runId, options = {}) {
31081
31428
  });
31082
31429
  context.io.writeResult({ runId, ...response }, formatToolsText);
31083
31430
  }
31084
- function formatToolsText(result, writeLine) {
31431
+ function formatToolsText(result, writeLine, style) {
31085
31432
  if (result.exchanges.length === 0) {
31086
- writeLine("No tool exchanges.");
31433
+ writeLine(style.dim("No tool exchanges."));
31087
31434
  return;
31088
31435
  }
31089
31436
  for (const exchange of result.exchanges) {
31090
31437
  const duration4 = exchange.durationMs === null ? "-" : `${exchange.durationMs}ms`;
31091
- const outcome = exchangeOutcome(exchange.isError);
31438
+ const outcome = exchangeOutcome(style, exchange.isError);
31092
31439
  writeLine(
31093
- `${exchange.callSequence} ${exchange.name} ${duration4} ${outcome}: ${preview(exchange.input)}`
31440
+ `${style.dim(String(exchange.callSequence))} ${style.label(
31441
+ exchange.name
31442
+ )} ${style.dim(duration4)} ${outcome}: ${preview(exchange.input)}`
31094
31443
  );
31095
31444
  }
31096
31445
  if (result.hasMore) {
31097
31446
  writeLine(
31098
- `(more exchanges; page older with --before ${result.nextBeforeSequence ?? "<sequence>"})`
31447
+ style.dim(
31448
+ `(more exchanges; page older with --before ${result.nextBeforeSequence ?? "<sequence>"})`
31449
+ )
31099
31450
  );
31100
31451
  }
31101
31452
  }
31102
- function exchangeOutcome(isError) {
31453
+ function exchangeOutcome(style, isError) {
31103
31454
  if (isError === null) {
31104
- return "pending";
31455
+ return style.dim("pending");
31105
31456
  }
31106
- return isError ? "ERR" : "ok";
31457
+ return isError ? style.error("ERR") : style.success("ok");
31107
31458
  }
31108
31459
  async function handleRunsTriggers(context, runId, options = {}) {
31109
31460
  const client = createContextApiClient(context);
@@ -31112,26 +31463,28 @@ async function handleRunsTriggers(context, runId, options = {}) {
31112
31463
  });
31113
31464
  context.io.writeResult({ runId, ...response }, formatTriggersText);
31114
31465
  }
31115
- function formatTriggersText(result, writeLine) {
31466
+ function formatTriggersText(result, writeLine, style) {
31116
31467
  if (result.spawn) {
31117
31468
  writeLine(
31118
- `spawn: ${result.spawn.eventKey} (${result.spawn.originKind}) delivered=${result.spawn.deliveredAt}`
31469
+ `${style.label("spawn:")} ${result.spawn.eventKey} ${style.dim(
31470
+ `(${result.spawn.originKind}) delivered=${result.spawn.deliveredAt}`
31471
+ )}`
31119
31472
  );
31120
31473
  } else if (result.starter) {
31121
31474
  writeLine(
31122
- `spawn: ${result.starter.principal.kind === "run" ? "agent" : "manual"} starter=${JSON.stringify(result.starter.principal)}`
31475
+ `${style.label("spawn:")} ${result.starter.principal.kind === "run" ? "agent" : "manual"} ${style.dim(`starter=${JSON.stringify(result.starter.principal)}`)}`
31123
31476
  );
31124
31477
  } else {
31125
- writeLine("spawn: manual");
31478
+ writeLine(`${style.label("spawn:")} manual`);
31126
31479
  }
31127
31480
  if (result.deliveries.length === 0) {
31128
- writeLine("No subsequent deliveries.");
31481
+ writeLine(style.dim("No subsequent deliveries."));
31129
31482
  return;
31130
31483
  }
31131
31484
  for (const delivery of result.deliveries) {
31132
- const reason = delivery.reason ? ` reason=${delivery.reason}` : "";
31485
+ const reason = delivery.reason ? ` ${style.dim(`reason=${delivery.reason}`)}` : "";
31133
31486
  writeLine(
31134
- `${delivery.deliveredAt} ${delivery.action} ${delivery.eventKey}${reason}`
31487
+ `${style.dim(delivery.deliveredAt)} ${delivery.action} ${delivery.eventKey}${reason}`
31135
31488
  );
31136
31489
  }
31137
31490
  }
@@ -31142,14 +31495,16 @@ async function handleRunsArtifacts(context, runId, options = {}) {
31142
31495
  });
31143
31496
  context.io.writeResult({ runId, ...response }, formatArtifactsText);
31144
31497
  }
31145
- function formatArtifactsText(result, writeLine) {
31498
+ function formatArtifactsText(result, writeLine, style) {
31146
31499
  if (result.artifacts.length === 0) {
31147
- writeLine("No artifacts currently owned.");
31500
+ writeLine(style.dim("No artifacts currently owned."));
31148
31501
  return;
31149
31502
  }
31150
31503
  for (const artifact of result.artifacts) {
31151
31504
  writeLine(
31152
- `${artifact.artifactType} ${artifact.externalId} recorded=${artifact.recordedAt}`
31505
+ `${style.label(artifact.artifactType)} ${style.id(artifact.externalId)} ${style.dim(
31506
+ `recorded=${artifact.recordedAt}`
31507
+ )}`
31153
31508
  );
31154
31509
  }
31155
31510
  }
@@ -31160,20 +31515,38 @@ async function handleRunsCommands(context, runId, options = {}) {
31160
31515
  });
31161
31516
  context.io.writeResult({ runId, ...response }, formatCommandsText);
31162
31517
  }
31163
- function formatCommandsText(result, writeLine) {
31518
+ function formatCommandsText(result, writeLine, style) {
31164
31519
  if (result.commands.length === 0) {
31165
- writeLine("No commands.");
31520
+ writeLine(style.dim("No commands."));
31166
31521
  return;
31167
31522
  }
31168
31523
  for (const command of result.commands) {
31524
+ const status = command.status === "failed" ? style.error(command.status) : command.status;
31169
31525
  writeLine(
31170
- `${command.createdAt} ${command.kind} ${command.status} sender=${command.sender.type}: ${preview(command.payload)}`
31526
+ `${style.dim(command.createdAt)} ${style.label(command.kind)} ${status} ${style.dim(
31527
+ `sender=${command.sender.type}`
31528
+ )}: ${preview(command.payload)}`
31171
31529
  );
31172
31530
  }
31173
31531
  }
31174
31532
  function formatMs(value) {
31175
31533
  return value === null ? "-" : `${value}ms`;
31176
31534
  }
31535
+ function styleCheckConclusion(style, conclusion) {
31536
+ switch (conclusion) {
31537
+ case "success":
31538
+ return style.success(conclusion);
31539
+ case "failure":
31540
+ case "timed_out":
31541
+ return style.error(conclusion);
31542
+ case "cancelled":
31543
+ case "skipped":
31544
+ case "neutral":
31545
+ return style.dim(conclusion);
31546
+ default:
31547
+ return conclusion;
31548
+ }
31549
+ }
31177
31550
  function entryPreview(event, full) {
31178
31551
  const texts = event.content.parts.map((part) => {
31179
31552
  switch (part.type) {
@@ -31205,40 +31578,6 @@ function clip(text) {
31205
31578
  return text.length > PREVIEW_CHARS ? `${text.slice(0, PREVIEW_CHARS)}\u2026` : text;
31206
31579
  }
31207
31580
 
31208
- // src/commands/runs/list.ts
31209
- async function handleRunsList(context, sessionName, options = {}) {
31210
- const result = await fetchRuns(context, sessionName, options);
31211
- context.io.writeResult(result, formatRunsText);
31212
- }
31213
- async function fetchRuns(context, sessionName, options) {
31214
- const client = createContextApiClient(context);
31215
- const clientOptions = {
31216
- apiBaseUrl: apiUrlFromOptions(context, options),
31217
- includeArchived: options.includeArchived,
31218
- statuses: options.status,
31219
- since: options.since,
31220
- limit: options.limit
31221
- };
31222
- const response = sessionName ? await client.listSessionRuns(sessionName, clientOptions) : await client.listRuns(clientOptions);
31223
- return {
31224
- session: sessionName ?? null,
31225
- runs: response.runs,
31226
- includeArchived: Boolean(options.includeArchived)
31227
- };
31228
- }
31229
- function formatRunsText(result, writeLine) {
31230
- if (result.runs.length === 0) {
31231
- writeLine(
31232
- result.session ? `No runs found for session ${result.session}.` : "No runs found in the current project."
31233
- );
31234
- return;
31235
- }
31236
- for (const run of result.runs) {
31237
- const archived = run.archivedAt ? ` archived_at=${run.archivedAt}` : "";
31238
- writeLine(`${run.id} ${run.status} ${run.createdAt}${archived}`);
31239
- }
31240
- }
31241
-
31242
31581
  // src/commands/runs/commands.ts
31243
31582
  function collect(value, previous = []) {
31244
31583
  return [...previous, value];
@@ -31675,8 +32014,8 @@ async function connectSessionPresence2(input) {
31675
32014
  const options = { apiBaseUrl: input.apiBaseUrl };
31676
32015
  const result = await connectWithConfigTokenBootstrap(input, options);
31677
32016
  input.writeOutput(result.message);
31678
- for (const identity of result.realized) {
31679
- input.writeOutput(realizedIdentityLine(input.session, identity));
32017
+ for (const identity2 of result.realized) {
32018
+ input.writeOutput(realizedIdentityLine(input.session, identity2));
31680
32019
  }
31681
32020
  if (result.pending.length === 0) {
31682
32021
  await promptForIconUploads(input, options);
@@ -31734,11 +32073,11 @@ async function connectSessionPresence2(input) {
31734
32073
  { name: input.session },
31735
32074
  options
31736
32075
  );
31737
- const identity = presence.identities.find(
32076
+ const identity2 = presence.identities.find(
31738
32077
  (entry) => entry.identityId === pending.identityId
31739
32078
  );
31740
- if (identity?.realized) {
31741
- input.writeOutput(realizedIdentityLine(input.session, identity));
32079
+ if (identity2?.realized) {
32080
+ input.writeOutput(realizedIdentityLine(input.session, identity2));
31742
32081
  realized = true;
31743
32082
  break;
31744
32083
  }
@@ -31751,9 +32090,9 @@ async function connectSessionPresence2(input) {
31751
32090
  }
31752
32091
  await promptForIconUploads(input, options);
31753
32092
  }
31754
- function realizedIdentityLine(session, identity) {
31755
- const handle = identity.botUsername ? `persona/@${identity.botUsername}` : `bot/${identity.botUserId ?? ""}`;
31756
- return `connected session/${session} workspace/${identity.workspace} ${handle}`;
32093
+ function realizedIdentityLine(session, identity2) {
32094
+ const handle = identity2.botUsername ? `persona/@${identity2.botUsername}` : `bot/${identity2.botUserId ?? ""}`;
32095
+ return `connected session/${session} workspace/${identity2.workspace} ${handle}`;
31757
32096
  }
31758
32097
  function manualGuidance(input) {
31759
32098
  if (input.allTelegram) {
@@ -31767,19 +32106,19 @@ async function promptForIconUploads(input, options) {
31767
32106
  options
31768
32107
  );
31769
32108
  const drifted = presence.identities.filter(
31770
- (identity) => identity.realized && identity.appId && identity.avatarSha256 && identity.avatarSha256 !== identity.appliedIconSha256
32109
+ (identity2) => identity2.realized && identity2.appId && identity2.avatarSha256 && identity2.avatarSha256 !== identity2.appliedIconSha256
31771
32110
  );
31772
32111
  if (drifted.length === 0) {
31773
32112
  return;
31774
32113
  }
31775
32114
  const canPrompt = Boolean(input.prompt?.io.canPrompt()) && !input.manual;
31776
- for (const identity of drifted) {
31777
- const settingsUrl = `${SLACK_APPS_URL}/${identity.appId}/general`;
32115
+ for (const identity2 of drifted) {
32116
+ const settingsUrl = `${SLACK_APPS_URL}/${identity2.appId}/general`;
31778
32117
  input.writeOutput(
31779
- `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}`
32118
+ `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}`
31780
32119
  );
31781
- if (identity.avatarUrl) {
31782
- input.writeOutput(`avatar image: ${identity.avatarUrl}`);
32120
+ if (identity2.avatarUrl) {
32121
+ input.writeOutput(`avatar image: ${identity2.avatarUrl}`);
31783
32122
  }
31784
32123
  if (!canPrompt) {
31785
32124
  input.writeOutput(
@@ -31787,8 +32126,8 @@ async function promptForIconUploads(input, options) {
31787
32126
  );
31788
32127
  continue;
31789
32128
  }
31790
- const staged = identity.avatarUrl ? await (input.stageAvatar ?? stageAvatarImage)({
31791
- avatarUrl: identity.avatarUrl,
32129
+ const staged = identity2.avatarUrl ? await (input.stageAvatar ?? stageAvatarImage)({
32130
+ avatarUrl: identity2.avatarUrl,
31792
32131
  session: input.session
31793
32132
  }) : void 0;
31794
32133
  if (staged) {
@@ -31810,20 +32149,20 @@ async function promptForIconUploads(input, options) {
31810
32149
  }
31811
32150
  if (!["y", "yes"].includes(answer.trim().toLowerCase())) {
31812
32151
  input.writeOutput(
31813
- `Skipped recording the icon for workspace "${identity.workspace}"; this prompt repeats on the next connect.`
32152
+ `Skipped recording the icon for workspace "${identity2.workspace}"; this prompt repeats on the next connect.`
31814
32153
  );
31815
32154
  continue;
31816
32155
  }
31817
32156
  const recorded = await input.client.recordSessionPresenceIcon(
31818
32157
  {
31819
32158
  name: input.session,
31820
- identityId: identity.identityId,
31821
- sha256: identity.avatarSha256
32159
+ identityId: identity2.identityId,
32160
+ sha256: identity2.avatarSha256
31822
32161
  },
31823
32162
  options
31824
32163
  );
31825
32164
  input.writeOutput(
31826
- `recorded icon session/${input.session} workspace/${identity.workspace} sha256/${recorded.appliedIconSha256.slice(0, 12)}`
32165
+ `recorded icon session/${input.session} workspace/${identity2.workspace} sha256/${recorded.appliedIconSha256.slice(0, 12)}`
31827
32166
  );
31828
32167
  }
31829
32168
  }
@@ -31907,9 +32246,16 @@ async function launchRun(input) {
31907
32246
  message: input.commandOptions.message,
31908
32247
  apiBaseUrl
31909
32248
  });
31910
- input.context.writeOutput(`run_id ${created.run_id}`);
31911
- input.context.writeOutput(`workflow_id ${created.workflow_id}`);
31912
- input.context.writeOutput(`status ${created.status}`);
32249
+ const style = input.context.io.style;
32250
+ input.context.writeOutput(
32251
+ `${style.label("run_id")} ${style.id(created.run_id)}`
32252
+ );
32253
+ input.context.writeOutput(
32254
+ `${style.label("workflow_id")} ${style.id(created.workflow_id)}`
32255
+ );
32256
+ input.context.writeOutput(
32257
+ `${style.label("status")} ${styleRunStatus(style, created.status)}`
32258
+ );
31913
32259
  if (input.commandOptions.attach) {
31914
32260
  const writeConversationEvent = createConversationStreamWriter({
31915
32261
  writeLine: input.context.writeOutput
@@ -31979,6 +32325,7 @@ function registerToolCommands(program, context) {
31979
32325
  }
31980
32326
 
31981
32327
  // src/lib/output/iostreams.ts
32328
+ init_style();
31982
32329
  function createIOStreams(flags) {
31983
32330
  const isTTY = Boolean(process.stdout.isTTY);
31984
32331
  const isCI = Boolean(process.env.CI);
@@ -31988,18 +32335,20 @@ function createIOStreams(flags) {
31988
32335
  `));
31989
32336
  const writeError = flags.writeError ?? ((text) => process.stderr.write(`${text}
31990
32337
  `));
32338
+ const style = createStyle({ isTTY, noColor, outputMode });
31991
32339
  return {
31992
32340
  isTTY,
31993
32341
  isCI,
31994
32342
  noColor,
31995
32343
  outputMode,
32344
+ style,
31996
32345
  canPrompt: () => isTTY && !isCI,
31997
32346
  writeLine,
31998
32347
  writeError,
31999
32348
  writeResult: (result, renderText) => {
32000
32349
  if (outputMode === "text" || outputMode === "tui") {
32001
32350
  if (renderText) {
32002
- renderText(result, writeLine);
32351
+ renderText(result, writeLine, style);
32003
32352
  } else {
32004
32353
  writeLine(String(result));
32005
32354
  }
@@ -32138,14 +32487,20 @@ function isCliEntrypoint(input) {
32138
32487
  }
32139
32488
 
32140
32489
  // src/entrypoints/index.ts
32490
+ init_style();
32141
32491
  function runEntrypoint(input) {
32142
32492
  if (isCliEntrypoint({
32143
32493
  moduleUrl: input.moduleUrl,
32144
32494
  entrypoint: input.argv[1] ? { kind: "path", path: input.argv[1] } : { kind: "missing" }
32145
32495
  })) {
32146
32496
  createProgram().parseAsync(input.argv).catch((err) => {
32497
+ const style = createStyle({
32498
+ isTTY: Boolean(process.stderr.isTTY),
32499
+ noColor: Boolean(process.env.NO_COLOR) || input.argv.includes("--no-color"),
32500
+ outputMode: "text"
32501
+ });
32147
32502
  process.stderr.write(
32148
- `${err instanceof Error ? err.message : String(err)}
32503
+ `${style.error(err instanceof Error ? err.message : String(err))}
32149
32504
  `
32150
32505
  );
32151
32506
  process.exit(1);