thinkwork-cli 0.12.6 → 0.12.8

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/cli.js CHANGED
@@ -1,9 +1,28 @@
1
1
  #!/usr/bin/env node
2
- var __defProp = Object.defineProperty;
3
- var __export = (target, all) => {
4
- for (var name in all)
5
- __defProp(target, name, { get: all[name], enumerable: true });
6
- };
2
+ import {
3
+ __export,
4
+ apiFetch,
5
+ apiFetchRaw,
6
+ ensureInit,
7
+ ensureWorkspace,
8
+ getApiEndpoint,
9
+ listDeployedStages,
10
+ listEnvironments,
11
+ loadEnvironment,
12
+ printError,
13
+ printHeader,
14
+ printMissingApiSessionError,
15
+ printSuccess,
16
+ printSummary,
17
+ printTierHeader,
18
+ printWarning,
19
+ resolveApiConfig,
20
+ resolveTerraformDir,
21
+ resolveTierDir,
22
+ runTerraform,
23
+ saveEnterpriseDeployment,
24
+ saveEnvironment
25
+ } from "./chunk-34NMB5AK.js";
7
26
 
8
27
  // src/cli.ts
9
28
  import { Command } from "commander";
@@ -22,20 +41,20 @@ function getCliConfigPath(override) {
22
41
  return override ?? join(homedir(), ".thinkwork", "config.json");
23
42
  }
24
43
  function loadCliConfig(pathOverride) {
25
- const path2 = getCliConfigPath(pathOverride);
26
- if (!existsSync(path2)) return {};
44
+ const path = getCliConfigPath(pathOverride);
45
+ if (!existsSync(path)) return {};
27
46
  try {
28
- return JSON.parse(readFileSync(path2, "utf-8"));
47
+ return JSON.parse(readFileSync(path, "utf-8"));
29
48
  } catch {
30
49
  return {};
31
50
  }
32
51
  }
33
52
  function saveCliConfig(next, pathOverride) {
34
- const path2 = getCliConfigPath(pathOverride);
35
- const dir = dirname(path2);
53
+ const path = getCliConfigPath(pathOverride);
54
+ const dir = dirname(path);
36
55
  if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
37
56
  const merged = { ...loadCliConfig(pathOverride), ...next };
38
- writeFileSync(path2, JSON.stringify(merged, null, 2) + "\n");
57
+ writeFileSync(path, JSON.stringify(merged, null, 2) + "\n");
39
58
  }
40
59
  function saveStageSession(stage, session, pathOverride) {
41
60
  const current = loadCliConfig(pathOverride);
@@ -168,190 +187,9 @@ function getAwsIdentity() {
168
187
  }
169
188
  }
170
189
 
171
- // src/terraform.ts
172
- import { spawn } from "child_process";
173
- import { existsSync as existsSync2 } from "fs";
174
- import path from "path";
175
- function resolveTierDir(terraformDir, stage, tier) {
176
- const envDir = path.join(terraformDir, "environments", stage, tier);
177
- if (existsSync2(envDir)) {
178
- return envDir;
179
- }
180
- const greenfield = path.join(terraformDir, "examples", "greenfield");
181
- if (existsSync2(greenfield)) {
182
- return greenfield;
183
- }
184
- const flat = path.join(terraformDir);
185
- if (existsSync2(path.join(flat, "main.tf"))) {
186
- return flat;
187
- }
188
- const cwdTf = path.join(process.cwd(), "terraform");
189
- if (existsSync2(path.join(cwdTf, "main.tf"))) {
190
- return cwdTf;
191
- }
192
- return terraformDir;
193
- }
194
- async function ensureWorkspace(cwd, stage) {
195
- const list = await runTerraformRaw(cwd, ["workspace", "list"]);
196
- const workspaces = list.split("\n").map((l) => l.replace("*", "").trim()).filter(Boolean);
197
- if (!workspaces.includes(stage)) {
198
- await runTerraformRaw(cwd, ["workspace", "new", stage]);
199
- } else {
200
- await runTerraformRaw(cwd, ["workspace", "select", stage]);
201
- }
202
- }
203
- function runTerraformRaw(cwd, args) {
204
- return new Promise((resolve7, reject) => {
205
- const proc = spawn("terraform", args, {
206
- cwd,
207
- stdio: ["pipe", "pipe", "pipe"]
208
- });
209
- let stdout = "";
210
- let stderr = "";
211
- proc.stdout.on("data", (d) => stdout += d);
212
- proc.stderr.on("data", (d) => stderr += d);
213
- proc.on("close", (code) => {
214
- if (code === 0) resolve7(stdout);
215
- else reject(new Error(`terraform ${args.join(" ")} failed (exit ${code}): ${stderr}`));
216
- });
217
- });
218
- }
219
- function runTerraform(cwd, args) {
220
- return new Promise((resolve7) => {
221
- console.log(`
222
- \u2192 terraform ${args.join(" ")}
223
- `);
224
- const proc = spawn("terraform", args, {
225
- cwd,
226
- stdio: "inherit"
227
- });
228
- proc.on("close", (code) => resolve7(code ?? 1));
229
- });
230
- }
231
- async function ensureInit(cwd) {
232
- const dotTerraform = path.join(cwd, ".terraform");
233
- if (!existsSync2(dotTerraform)) {
234
- const code = await runTerraform(cwd, ["init"]);
235
- if (code !== 0) {
236
- throw new Error("terraform init failed");
237
- }
238
- }
239
- }
240
-
241
- // src/ui.ts
242
- import chalk2 from "chalk";
243
- import ora from "ora";
244
- var TIER_LABELS = {
245
- foundation: "Foundation",
246
- data: "Data",
247
- app: "App"
248
- };
249
- function printHeader(command, stage, identity) {
250
- console.log("");
251
- console.log(chalk2.bold.cyan(" \u2B21 Thinkwork") + chalk2.dim(` \u2014 ${command}`));
252
- console.log(chalk2.dim(` Stage: ${chalk2.white(stage)}`));
253
- if (identity) {
254
- console.log(chalk2.dim(` AWS: ${chalk2.white(identity.account)} / ${chalk2.white(identity.region)}`));
255
- }
256
- console.log("");
257
- }
258
- function printTierHeader(tier, index, total) {
259
- const label = TIER_LABELS[tier] ?? tier;
260
- const progress = chalk2.dim(`[${index + 1}/${total}]`);
261
- console.log(` ${progress} ${chalk2.bold(label)}`);
262
- }
263
- function printSuccess(message) {
264
- console.log(`
265
- ${chalk2.green("\u2713")} ${chalk2.bold(message)}`);
266
- }
267
- function printError(message) {
268
- console.log(`
269
- ${chalk2.red("\u2717")} ${chalk2.bold.red(message)}`);
270
- }
271
- function printMissingApiSessionError(stage, hasSession) {
272
- if (!hasSession) {
273
- printError(`No API session for stage "${stage}".`);
274
- console.log("");
275
- console.log(` ${chalk2.bold("To fix:")} thinkwork login --stage ${stage}`);
276
- console.log(
277
- chalk2.dim(
278
- ` (the deploy-side \`thinkwork login\` only configures an AWS profile \u2014
279
- it does NOT open an API session.)`
280
- )
281
- );
282
- console.log("");
283
- } else {
284
- printError(`Session for stage "${stage}" has no tenant cached.`);
285
- console.log("");
286
- console.log(` ${chalk2.bold("To fix:")} thinkwork login --stage ${stage}`);
287
- console.log(
288
- chalk2.dim(
289
- ` Or pass --tenant <slug>, or set THINKWORK_TENANT.`
290
- )
291
- );
292
- console.log("");
293
- }
294
- }
295
- function printWarning(message) {
296
- console.log(` ${chalk2.yellow("\u26A0")} ${message}`);
297
- }
298
- function printSummary(command, stage, tiers, startTime) {
299
- const elapsed = ((Date.now() - startTime) / 1e3).toFixed(1);
300
- console.log("");
301
- console.log(chalk2.dim(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
302
- console.log(` ${chalk2.bold("Command:")} ${command}`);
303
- console.log(` ${chalk2.bold("Stage:")} ${stage}`);
304
- console.log(` ${chalk2.bold("Tiers:")} ${tiers.map((t) => TIER_LABELS[t] ?? t).join(" \u2192 ")}`);
305
- console.log(` ${chalk2.bold("Time:")} ${elapsed}s`);
306
- console.log(chalk2.dim(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
307
- }
308
-
309
190
  // src/lib/resolve-stage.ts
310
191
  import { select } from "@inquirer/prompts";
311
192
 
312
- // src/aws-discovery.ts
313
- import { execSync as execSync2 } from "child_process";
314
- function runAws(cmd) {
315
- try {
316
- return execSync2(`aws ${cmd}`, {
317
- encoding: "utf-8",
318
- timeout: 15e3,
319
- stdio: ["pipe", "pipe", "pipe"]
320
- }).trim();
321
- } catch {
322
- return null;
323
- }
324
- }
325
- function listDeployedStages(region) {
326
- const raw = runAws(
327
- `lambda list-functions --region ${region} --query "Functions[?starts_with(FunctionName, 'thinkwork-')].FunctionName" --output json`
328
- );
329
- if (!raw) return [];
330
- try {
331
- const functions = JSON.parse(raw);
332
- const stages = /* @__PURE__ */ new Set();
333
- for (const fn of functions) {
334
- const m = fn.match(/^thinkwork-(.+?)-api-graphql-http$/);
335
- if (m) stages.add(m[1]);
336
- }
337
- return [...stages].sort();
338
- } catch {
339
- return [];
340
- }
341
- }
342
- function getApiEndpoint(stage, region) {
343
- const raw = runAws(
344
- `apigatewayv2 get-apis --region ${region} --query "Items[?Name=='thinkwork-${stage}-api'].ApiEndpoint|[0]" --output text`
345
- );
346
- return raw && raw !== "None" ? raw : null;
347
- }
348
- function getApiAuthSecretFromLambda(stage, region) {
349
- const raw = runAws(
350
- `lambda get-function-configuration --function-name thinkwork-${stage}-api-tenants --region ${region} --query "Environment.Variables.API_AUTH_SECRET" --output text`
351
- );
352
- return raw && raw !== "None" ? raw : null;
353
- }
354
-
355
193
  // src/lib/interactive.ts
356
194
  function isCancellation(err) {
357
195
  return err instanceof Error && err.name === "ExitPromptError";
@@ -457,8 +295,8 @@ function registerPlanCommand(program2) {
457
295
  }
458
296
 
459
297
  // src/commands/deploy.ts
460
- import { spawn as spawn2 } from "child_process";
461
- import { existsSync as existsSync3 } from "fs";
298
+ import { spawn } from "child_process";
299
+ import { existsSync as existsSync2 } from "fs";
462
300
  import { dirname as dirname2, resolve as pathResolve } from "path";
463
301
  import { fileURLToPath } from "url";
464
302
 
@@ -554,7 +392,7 @@ async function runPostDeployProbe(stage) {
554
392
  return;
555
393
  }
556
394
  await new Promise((resolve7) => {
557
- const proc = spawn2("bash", [scriptPath, "--stage", stage], {
395
+ const proc = spawn("bash", [scriptPath, "--stage", stage], {
558
396
  stdio: "inherit",
559
397
  env: process.env
560
398
  });
@@ -584,7 +422,7 @@ function locatePostDeployScript() {
584
422
  )
585
423
  ];
586
424
  for (const candidate of candidates) {
587
- if (existsSync3(candidate)) return candidate;
425
+ if (existsSync2(candidate)) return candidate;
588
426
  }
589
427
  return null;
590
428
  }
@@ -650,14 +488,14 @@ function registerDestroyCommand(program2) {
650
488
  }
651
489
 
652
490
  // src/commands/doctor.ts
653
- import chalk3 from "chalk";
654
- import { execSync as execSync3 } from "child_process";
491
+ import chalk2 from "chalk";
492
+ import { execSync as execSync2 } from "child_process";
655
493
  function checkAwsCli() {
656
494
  return {
657
495
  name: "AWS CLI installed",
658
496
  run: () => {
659
497
  try {
660
- const v = execSync3("aws --version", { encoding: "utf-8", timeout: 5e3, stdio: ["pipe", "pipe", "pipe"] }).trim();
498
+ const v = execSync2("aws --version", { encoding: "utf-8", timeout: 5e3, stdio: ["pipe", "pipe", "pipe"] }).trim();
661
499
  return { pass: true, detail: v.split(" ")[0] ?? v };
662
500
  } catch {
663
501
  return { pass: false, detail: "aws CLI not found. Install: https://aws.amazon.com/cli/" };
@@ -670,7 +508,7 @@ function checkTerraformCli() {
670
508
  name: "Terraform CLI installed",
671
509
  run: () => {
672
510
  try {
673
- const v = execSync3("terraform version -json", { encoding: "utf-8", timeout: 5e3, stdio: ["pipe", "pipe", "pipe"] });
511
+ const v = execSync2("terraform version -json", { encoding: "utf-8", timeout: 5e3, stdio: ["pipe", "pipe", "pipe"] });
674
512
  const parsed = JSON.parse(v);
675
513
  return { pass: true, detail: `v${parsed.terraform_version}` };
676
514
  } catch {
@@ -696,7 +534,7 @@ function checkBedrockAccess() {
696
534
  name: "Bedrock model access",
697
535
  run: () => {
698
536
  try {
699
- execSync3(
537
+ execSync2(
700
538
  "aws bedrock get-foundation-model --model-identifier anthropic.claude-3-haiku-20240307-v1:0 --output json --region us-east-1",
701
539
  { encoding: "utf-8", timeout: 1e4, stdio: ["pipe", "pipe", "pipe"] }
702
540
  );
@@ -729,17 +567,17 @@ function registerDoctorCommand(program2) {
729
567
  let allPass = true;
730
568
  for (const check of checks) {
731
569
  const result = check.run();
732
- const icon = result.pass ? chalk3.green("\u2713") : chalk3.red("\u2717");
733
- const detail = result.pass ? chalk3.dim(result.detail) : chalk3.yellow(result.detail);
570
+ const icon = result.pass ? chalk2.green("\u2713") : chalk2.red("\u2717");
571
+ const detail = result.pass ? chalk2.dim(result.detail) : chalk2.yellow(result.detail);
734
572
  console.log(` ${icon} ${check.name} ${detail}`);
735
573
  if (!result.pass) allPass = false;
736
574
  }
737
575
  if (allPass) {
738
576
  console.log(`
739
- ${chalk3.green.bold("All checks passed.")}`);
577
+ ${chalk2.green.bold("All checks passed.")}`);
740
578
  } else {
741
579
  console.log(`
742
- ${chalk3.yellow.bold("Some checks failed.")} Fix the issues above before deploying.`);
580
+ ${chalk2.yellow.bold("Some checks failed.")} Fix the issues above before deploying.`);
743
581
  }
744
582
  process.exit(allPass ? 0 : 1);
745
583
  });
@@ -778,75 +616,11 @@ function registerOutputsCommand(program2) {
778
616
  }
779
617
 
780
618
  // src/commands/config.ts
781
- import { readFileSync as readFileSync3, writeFileSync as writeFileSync3, existsSync as existsSync5 } from "fs";
782
- import chalk4 from "chalk";
783
-
784
- // src/environments.ts
785
- import {
786
- existsSync as existsSync4,
787
- mkdirSync as mkdirSync2,
788
- writeFileSync as writeFileSync2,
789
- readFileSync as readFileSync2,
790
- readdirSync
791
- } from "fs";
792
- import { join as join2 } from "path";
793
- import { homedir as homedir2 } from "os";
794
- var THINKWORK_HOME = join2(homedir2(), ".thinkwork");
795
- var ENVIRONMENTS_DIR = join2(THINKWORK_HOME, "environments");
796
- var ENTERPRISE_DEPLOYMENTS_DIR = join2(
797
- THINKWORK_HOME,
798
- "enterprise-deployments"
799
- );
800
- function ensureDir(dir) {
801
- if (!existsSync4(dir)) mkdirSync2(dir, { recursive: true });
802
- }
803
- function saveEnvironment(config) {
804
- ensureDir(ENVIRONMENTS_DIR);
805
- const envDir = join2(ENVIRONMENTS_DIR, config.stage);
806
- ensureDir(envDir);
807
- writeFileSync2(
808
- join2(envDir, "config.json"),
809
- JSON.stringify(config, null, 2) + "\n"
810
- );
811
- }
812
- function saveEnterpriseDeployment(config) {
813
- ensureDir(ENTERPRISE_DEPLOYMENTS_DIR);
814
- writeFileSync2(
815
- join2(ENTERPRISE_DEPLOYMENTS_DIR, `${config.customerSlug}.json`),
816
- JSON.stringify(config, null, 2) + "\n"
817
- );
818
- }
819
- function loadEnvironment(stage) {
820
- const configPath = join2(ENVIRONMENTS_DIR, stage, "config.json");
821
- if (!existsSync4(configPath)) return null;
822
- return JSON.parse(readFileSync2(configPath, "utf-8"));
823
- }
824
- function listEnvironments() {
825
- if (!existsSync4(ENVIRONMENTS_DIR)) return [];
826
- return readdirSync(ENVIRONMENTS_DIR).filter((name) => {
827
- return existsSync4(join2(ENVIRONMENTS_DIR, name, "config.json"));
828
- }).map((name) => {
829
- return JSON.parse(
830
- readFileSync2(join2(ENVIRONMENTS_DIR, name, "config.json"), "utf-8")
831
- );
832
- }).sort((a, b) => a.stage.localeCompare(b.stage));
833
- }
834
- function resolveTerraformDir(stage) {
835
- const env = loadEnvironment(stage);
836
- if (env?.terraformDir && existsSync4(env.terraformDir)) {
837
- return env.terraformDir;
838
- }
839
- const envVar = process.env.THINKWORK_TERRAFORM_DIR;
840
- if (envVar && existsSync4(envVar)) return envVar;
841
- const cwdTf = join2(process.cwd(), "terraform");
842
- if (existsSync4(join2(cwdTf, "main.tf"))) return cwdTf;
843
- return null;
844
- }
845
-
846
- // src/commands/config.ts
619
+ import { readFileSync as readFileSync2, writeFileSync as writeFileSync2, existsSync as existsSync3 } from "fs";
620
+ import chalk3 from "chalk";
847
621
  function readTfVar(tfvarsPath, key) {
848
- if (!existsSync5(tfvarsPath)) return null;
849
- const content = readFileSync3(tfvarsPath, "utf-8");
622
+ if (!existsSync3(tfvarsPath)) return null;
623
+ const content = readFileSync2(tfvarsPath, "utf-8");
850
624
  const quoted = content.match(new RegExp(`^${key}\\s*=\\s*"([^"]*)"`, "m"));
851
625
  if (quoted) return quoted[1];
852
626
  const bare = content.match(new RegExp(`^${key}\\s*=\\s*([^\\s#]+)`, "m"));
@@ -854,10 +628,10 @@ function readTfVar(tfvarsPath, key) {
854
628
  }
855
629
  var BARE_KEYS = /* @__PURE__ */ new Set(["enable_hindsight"]);
856
630
  function setTfVar(tfvarsPath, key, value) {
857
- if (!existsSync5(tfvarsPath)) {
631
+ if (!existsSync3(tfvarsPath)) {
858
632
  throw new Error(`terraform.tfvars not found at ${tfvarsPath}`);
859
633
  }
860
- let content = readFileSync3(tfvarsPath, "utf-8");
634
+ let content = readFileSync2(tfvarsPath, "utf-8");
861
635
  const bare = BARE_KEYS.has(key);
862
636
  const newLine = bare ? `${key} = ${value}` : `${key} = "${value}"`;
863
637
  const existingRegex = new RegExp(`^${key}\\s*=\\s*(?:"[^"]*"|[^\\s#]+)`, "m");
@@ -868,13 +642,13 @@ function setTfVar(tfvarsPath, key, value) {
868
642
  ${newLine}
869
643
  `;
870
644
  }
871
- writeFileSync3(tfvarsPath, content);
645
+ writeFileSync2(tfvarsPath, content);
872
646
  }
873
647
  function resolveTfvarsPath(stage) {
874
648
  const tfDir = resolveTerraformDir(stage);
875
649
  if (tfDir) {
876
650
  const direct = `${tfDir}/terraform.tfvars`;
877
- if (existsSync5(direct)) return direct;
651
+ if (existsSync3(direct)) return direct;
878
652
  }
879
653
  const terraformDir = process.env.THINKWORK_TERRAFORM_DIR || process.cwd();
880
654
  const cwd = resolveTierDir(terraformDir, stage, "app");
@@ -890,21 +664,21 @@ function registerConfigCommand(program2) {
890
664
  process.exit(1);
891
665
  }
892
666
  console.log("");
893
- console.log(chalk4.bold.cyan(` \u2B21 ${env.stage}`));
894
- console.log(chalk4.dim(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
895
- console.log(` ${chalk4.bold("Region:")} ${env.region}`);
896
- console.log(` ${chalk4.bold("Account:")} ${env.accountId}`);
897
- console.log(` ${chalk4.bold("Database:")} ${env.databaseEngine}`);
898
- console.log(` ${chalk4.bold("Memory:")} managed (always on)${env.enableHindsight ? " + hindsight" : ""}`);
899
- console.log(` ${chalk4.bold("Terraform dir:")} ${env.terraformDir}`);
900
- console.log(` ${chalk4.bold("Created:")} ${env.createdAt}`);
901
- console.log(` ${chalk4.bold("Updated:")} ${env.updatedAt}`);
902
- console.log(chalk4.dim(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
667
+ console.log(chalk3.bold.cyan(` \u2B21 ${env.stage}`));
668
+ console.log(chalk3.dim(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
669
+ console.log(` ${chalk3.bold("Region:")} ${env.region}`);
670
+ console.log(` ${chalk3.bold("Account:")} ${env.accountId}`);
671
+ console.log(` ${chalk3.bold("Database:")} ${env.databaseEngine}`);
672
+ console.log(` ${chalk3.bold("Memory:")} managed (always on)${env.enableHindsight ? " + hindsight" : ""}`);
673
+ console.log(` ${chalk3.bold("Terraform dir:")} ${env.terraformDir}`);
674
+ console.log(` ${chalk3.bold("Created:")} ${env.createdAt}`);
675
+ console.log(` ${chalk3.bold("Updated:")} ${env.updatedAt}`);
676
+ console.log(chalk3.dim(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
903
677
  const tfvarsPath = `${env.terraformDir}/terraform.tfvars`;
904
- if (existsSync5(tfvarsPath)) {
678
+ if (existsSync3(tfvarsPath)) {
905
679
  console.log("");
906
- console.log(chalk4.dim(" terraform.tfvars:"));
907
- const content = readFileSync3(tfvarsPath, "utf-8");
680
+ console.log(chalk3.dim(" terraform.tfvars:"));
681
+ const content = readFileSync2(tfvarsPath, "utf-8");
908
682
  for (const line of content.split("\n")) {
909
683
  if (line.trim() && !line.trim().startsWith("#")) {
910
684
  const masked = line.replace(
@@ -917,7 +691,7 @@ function registerConfigCommand(program2) {
917
691
  /^(google_oauth_client_secret\s*=\s*)".*"/,
918
692
  '$1"********"'
919
693
  );
920
- console.log(` ${chalk4.dim(masked)}`);
694
+ console.log(` ${chalk3.dim(masked)}`);
921
695
  }
922
696
  }
923
697
  }
@@ -928,24 +702,24 @@ function registerConfigCommand(program2) {
928
702
  if (envs.length === 0) {
929
703
  console.log("");
930
704
  console.log(" No environments found.");
931
- console.log(` Run ${chalk4.cyan("thinkwork init -s <stage>")} to create one.`);
705
+ console.log(` Run ${chalk3.cyan("thinkwork init -s <stage>")} to create one.`);
932
706
  console.log("");
933
707
  return;
934
708
  }
935
709
  console.log("");
936
- console.log(chalk4.bold(" Environments"));
937
- console.log(chalk4.dim(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
710
+ console.log(chalk3.bold(" Environments"));
711
+ console.log(chalk3.dim(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
938
712
  for (const env of envs) {
939
- const memBadge = env.enableHindsight ? chalk4.magenta("managed+hindsight") : chalk4.dim("managed");
940
- const dbBadge = env.databaseEngine === "rds-postgres" ? chalk4.yellow("rds") : chalk4.dim("aurora");
713
+ const memBadge = env.enableHindsight ? chalk3.magenta("managed+hindsight") : chalk3.dim("managed");
714
+ const dbBadge = env.databaseEngine === "rds-postgres" ? chalk3.yellow("rds") : chalk3.dim("aurora");
941
715
  console.log(
942
- ` ${chalk4.bold.cyan(env.stage.padEnd(16))}${env.region.padEnd(14)}${env.accountId.padEnd(16)}${dbBadge.padEnd(20)}${memBadge}`
716
+ ` ${chalk3.bold.cyan(env.stage.padEnd(16))}${env.region.padEnd(14)}${env.accountId.padEnd(16)}${dbBadge.padEnd(20)}${memBadge}`
943
717
  );
944
718
  }
945
- console.log(chalk4.dim(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
946
- console.log(chalk4.dim(` ${envs.length} environment(s)`));
719
+ console.log(chalk3.dim(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
720
+ console.log(chalk3.dim(` ${envs.length} environment(s)`));
947
721
  console.log("");
948
- console.log(` Show details: ${chalk4.cyan("thinkwork config list -s <stage>")}`);
722
+ console.log(` Show details: ${chalk3.cyan("thinkwork config list -s <stage>")}`);
949
723
  console.log("");
950
724
  });
951
725
  config.command("get <key>").description("Get a configuration value (e.g. enable-hindsight). Prompts for stage in a TTY when omitted.").option("-s, --stage <name>", "Deployment stage").action(async (key, opts) => {
@@ -1022,11 +796,11 @@ function registerConfigCommand(program2) {
1022
796
  }
1023
797
 
1024
798
  // src/commands/bootstrap.ts
1025
- import { spawn as spawn3 } from "child_process";
799
+ import { spawn as spawn2 } from "child_process";
1026
800
  import { resolve } from "path";
1027
801
  function getTerraformOutput(cwd, key) {
1028
802
  return new Promise((resolve7, reject) => {
1029
- const proc = spawn3("terraform", ["output", "-raw", key], {
803
+ const proc = spawn2("terraform", ["output", "-raw", key], {
1030
804
  cwd,
1031
805
  stdio: ["pipe", "pipe", "pipe"]
1032
806
  });
@@ -1040,7 +814,7 @@ function getTerraformOutput(cwd, key) {
1040
814
  }
1041
815
  function runScript(scriptPath, args) {
1042
816
  return new Promise((resolve7) => {
1043
- const proc = spawn3("bash", [scriptPath, ...args], {
817
+ const proc = spawn2("bash", [scriptPath, ...args], {
1044
818
  stdio: "inherit"
1045
819
  });
1046
820
  proc.on("close", (code) => resolve7(code ?? 1));
@@ -1068,8 +842,8 @@ function registerBootstrapCommand(program2) {
1068
842
  bucket = await getTerraformOutput(cwd, "bucket_name");
1069
843
  dbEndpoint = await getTerraformOutput(cwd, "db_cluster_endpoint");
1070
844
  const secretArn = await getTerraformOutput(cwd, "db_secret_arn");
1071
- const { execSync: execSync11 } = await import("child_process");
1072
- const secretJson = execSync11(
845
+ const { execSync: execSync9 } = await import("child_process");
846
+ const secretJson = execSync9(
1073
847
  `aws secretsmanager get-secret-value --secret-id "${secretArn}" --query SecretString --output text`,
1074
848
  { encoding: "utf-8" }
1075
849
  ).trim();
@@ -1092,17 +866,17 @@ function registerBootstrapCommand(program2) {
1092
866
  }
1093
867
 
1094
868
  // src/commands/login.ts
1095
- import { execSync as execSync6 } from "child_process";
869
+ import { execSync as execSync5 } from "child_process";
1096
870
  import { createInterface as createInterface2 } from "readline";
1097
871
  import { select as select2, Separator } from "@inquirer/prompts";
1098
- import chalk7 from "chalk";
872
+ import chalk6 from "chalk";
1099
873
 
1100
874
  // src/aws-profiles.ts
1101
- import { existsSync as existsSync6, readFileSync as readFileSync4 } from "fs";
1102
- import { homedir as homedir3 } from "os";
1103
- import { join as join3 } from "path";
1104
- var CREDENTIALS_PATH = join3(homedir3(), ".aws", "credentials");
1105
- var CONFIG_PATH = join3(homedir3(), ".aws", "config");
875
+ import { existsSync as existsSync4, readFileSync as readFileSync3 } from "fs";
876
+ import { homedir as homedir2 } from "os";
877
+ import { join as join2 } from "path";
878
+ var CREDENTIALS_PATH = join2(homedir2(), ".aws", "credentials");
879
+ var CONFIG_PATH = join2(homedir2(), ".aws", "config");
1106
880
  function parseIni(content) {
1107
881
  const sections = {};
1108
882
  let current = null;
@@ -1141,8 +915,8 @@ function classify(fields) {
1141
915
  }
1142
916
  function listAwsProfiles() {
1143
917
  const byName = /* @__PURE__ */ new Map();
1144
- if (existsSync6(CREDENTIALS_PATH)) {
1145
- const sections = parseIni(readFileSync4(CREDENTIALS_PATH, "utf-8"));
918
+ if (existsSync4(CREDENTIALS_PATH)) {
919
+ const sections = parseIni(readFileSync3(CREDENTIALS_PATH, "utf-8"));
1146
920
  for (const [section, fields] of Object.entries(sections)) {
1147
921
  byName.set(section, {
1148
922
  name: section,
@@ -1151,8 +925,8 @@ function listAwsProfiles() {
1151
925
  });
1152
926
  }
1153
927
  }
1154
- if (existsSync6(CONFIG_PATH)) {
1155
- const sections = parseIni(readFileSync4(CONFIG_PATH, "utf-8"));
928
+ if (existsSync4(CONFIG_PATH)) {
929
+ const sections = parseIni(readFileSync3(CONFIG_PATH, "utf-8"));
1156
930
  for (const [section, fields] of Object.entries(sections)) {
1157
931
  const name = normalizeConfigSection(section);
1158
932
  if (!name) continue;
@@ -1174,14 +948,14 @@ function listAwsProfiles() {
1174
948
  }
1175
949
 
1176
950
  // src/prerequisites.ts
1177
- import { execSync as execSync4 } from "child_process";
1178
- import { mkdirSync as mkdirSync3, createWriteStream, chmodSync } from "fs";
1179
- import { join as join4 } from "path";
1180
- import { homedir as homedir4, platform, arch } from "os";
1181
- import chalk5 from "chalk";
951
+ import { execSync as execSync3 } from "child_process";
952
+ import { mkdirSync as mkdirSync2, createWriteStream, chmodSync } from "fs";
953
+ import { join as join3 } from "path";
954
+ import { homedir as homedir3, platform, arch } from "os";
955
+ import chalk4 from "chalk";
1182
956
  function run(cmd, opts) {
1183
957
  try {
1184
- return execSync4(cmd, {
958
+ return execSync3(cmd, {
1185
959
  encoding: "utf-8",
1186
960
  timeout: 3e4,
1187
961
  stdio: opts?.silent ? ["pipe", "pipe", "pipe"] : void 0
@@ -1198,27 +972,27 @@ function hasBrew() {
1198
972
  }
1199
973
  async function ensureAwsCli() {
1200
974
  if (isInstalled("aws")) return true;
1201
- console.log(` ${chalk5.yellow("\u2192")} AWS CLI not found. Installing...`);
975
+ console.log(` ${chalk4.yellow("\u2192")} AWS CLI not found. Installing...`);
1202
976
  const os = platform();
1203
977
  if (os === "darwin" && hasBrew()) {
1204
978
  const result = run("brew install awscli");
1205
979
  if (result !== null && isInstalled("aws")) {
1206
- console.log(` ${chalk5.green("\u2713")} AWS CLI installed via Homebrew`);
980
+ console.log(` ${chalk4.green("\u2713")} AWS CLI installed via Homebrew`);
1207
981
  return true;
1208
982
  }
1209
983
  }
1210
984
  if (os === "linux") {
1211
985
  try {
1212
- const tmpDir = join4(homedir4(), ".thinkwork", "tmp");
1213
- mkdirSync3(tmpDir, { recursive: true });
1214
- const zipPath = join4(tmpDir, "awscliv2.zip");
986
+ const tmpDir = join3(homedir3(), ".thinkwork", "tmp");
987
+ mkdirSync2(tmpDir, { recursive: true });
988
+ const zipPath = join3(tmpDir, "awscliv2.zip");
1215
989
  console.log(" Downloading AWS CLI...");
1216
990
  run(`curl -sL "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "${zipPath}"`);
1217
991
  run(`cd "${tmpDir}" && unzip -qo "${zipPath}"`);
1218
- run(`"${tmpDir}/aws/install" --install-dir "${homedir4()}/.thinkwork/aws-cli" --bin-dir "${homedir4()}/.local/bin" --update`);
1219
- process.env.PATH = `${homedir4()}/.local/bin:${process.env.PATH}`;
992
+ run(`"${tmpDir}/aws/install" --install-dir "${homedir3()}/.thinkwork/aws-cli" --bin-dir "${homedir3()}/.local/bin" --update`);
993
+ process.env.PATH = `${homedir3()}/.local/bin:${process.env.PATH}`;
1220
994
  if (isInstalled("aws")) {
1221
- console.log(` ${chalk5.green("\u2713")} AWS CLI installed to ~/.local/bin/aws`);
995
+ console.log(` ${chalk4.green("\u2713")} AWS CLI installed to ~/.local/bin/aws`);
1222
996
  return true;
1223
997
  }
1224
998
  } catch {
@@ -1226,31 +1000,31 @@ async function ensureAwsCli() {
1226
1000
  }
1227
1001
  if (os === "darwin") {
1228
1002
  try {
1229
- const tmpDir = join4(homedir4(), ".thinkwork", "tmp");
1230
- mkdirSync3(tmpDir, { recursive: true });
1231
- const pkgPath = join4(tmpDir, "AWSCLIV2.pkg");
1003
+ const tmpDir = join3(homedir3(), ".thinkwork", "tmp");
1004
+ mkdirSync2(tmpDir, { recursive: true });
1005
+ const pkgPath = join3(tmpDir, "AWSCLIV2.pkg");
1232
1006
  console.log(" Downloading AWS CLI...");
1233
1007
  run(`curl -sL "https://awscli.amazonaws.com/AWSCLIV2.pkg" -o "${pkgPath}"`);
1234
1008
  run(`installer -pkg "${pkgPath}" -target CurrentUserHomeDirectory 2>/dev/null || sudo installer -pkg "${pkgPath}" -target /`);
1235
1009
  if (isInstalled("aws")) {
1236
- console.log(` ${chalk5.green("\u2713")} AWS CLI installed`);
1010
+ console.log(` ${chalk4.green("\u2713")} AWS CLI installed`);
1237
1011
  return true;
1238
1012
  }
1239
1013
  } catch {
1240
1014
  }
1241
1015
  }
1242
- console.log(` ${chalk5.red("\u2717")} Could not auto-install AWS CLI.`);
1243
- console.log(` Install manually: ${chalk5.cyan("https://aws.amazon.com/cli/")}`);
1016
+ console.log(` ${chalk4.red("\u2717")} Could not auto-install AWS CLI.`);
1017
+ console.log(` Install manually: ${chalk4.cyan("https://aws.amazon.com/cli/")}`);
1244
1018
  return false;
1245
1019
  }
1246
1020
  async function ensureTerraform() {
1247
1021
  if (isInstalled("terraform")) return true;
1248
- console.log(` ${chalk5.yellow("\u2192")} Terraform not found. Installing...`);
1022
+ console.log(` ${chalk4.yellow("\u2192")} Terraform not found. Installing...`);
1249
1023
  const os = platform();
1250
1024
  if ((os === "darwin" || os === "linux") && hasBrew()) {
1251
1025
  const result = run("brew install hashicorp/tap/terraform");
1252
1026
  if (result !== null && isInstalled("terraform")) {
1253
- console.log(` ${chalk5.green("\u2713")} Terraform installed via Homebrew`);
1027
+ console.log(` ${chalk4.green("\u2713")} Terraform installed via Homebrew`);
1254
1028
  return true;
1255
1029
  }
1256
1030
  }
@@ -1259,30 +1033,30 @@ async function ensureTerraform() {
1259
1033
  const archName = arch() === "arm64" ? "arm64" : "amd64";
1260
1034
  const url = `https://releases.hashicorp.com/terraform/${tfVersion}/terraform_${tfVersion}_${osName}_${archName}.zip`;
1261
1035
  try {
1262
- const tmpDir = join4(homedir4(), ".thinkwork", "tmp");
1263
- const binDir = join4(homedir4(), ".local", "bin");
1264
- mkdirSync3(tmpDir, { recursive: true });
1265
- mkdirSync3(binDir, { recursive: true });
1266
- const zipPath = join4(tmpDir, "terraform.zip");
1036
+ const tmpDir = join3(homedir3(), ".thinkwork", "tmp");
1037
+ const binDir = join3(homedir3(), ".local", "bin");
1038
+ mkdirSync2(tmpDir, { recursive: true });
1039
+ mkdirSync2(binDir, { recursive: true });
1040
+ const zipPath = join3(tmpDir, "terraform.zip");
1267
1041
  console.log(` Downloading Terraform ${tfVersion}...`);
1268
1042
  run(`curl -sL "${url}" -o "${zipPath}"`);
1269
1043
  run(`unzip -qo "${zipPath}" -d "${binDir}"`);
1270
- chmodSync(join4(binDir, "terraform"), 493);
1044
+ chmodSync(join3(binDir, "terraform"), 493);
1271
1045
  if (!process.env.PATH?.includes(binDir)) {
1272
1046
  process.env.PATH = `${binDir}:${process.env.PATH}`;
1273
1047
  }
1274
1048
  if (isInstalled("terraform")) {
1275
- console.log(` ${chalk5.green("\u2713")} Terraform ${tfVersion} installed to ~/.local/bin/terraform`);
1049
+ console.log(` ${chalk4.green("\u2713")} Terraform ${tfVersion} installed to ~/.local/bin/terraform`);
1276
1050
  return true;
1277
1051
  }
1278
1052
  } catch {
1279
1053
  }
1280
- console.log(` ${chalk5.red("\u2717")} Could not auto-install Terraform.`);
1281
- console.log(` Install manually: ${chalk5.cyan("https://developer.hashicorp.com/terraform/install")}`);
1054
+ console.log(` ${chalk4.red("\u2717")} Could not auto-install Terraform.`);
1055
+ console.log(` Install manually: ${chalk4.cyan("https://developer.hashicorp.com/terraform/install")}`);
1282
1056
  return false;
1283
1057
  }
1284
1058
  async function ensurePrerequisites() {
1285
- console.log(chalk5.dim(" Checking prerequisites...\n"));
1059
+ console.log(chalk4.dim(" Checking prerequisites...\n"));
1286
1060
  const awsOk2 = await ensureAwsCli();
1287
1061
  const tfOk = await ensureTerraform();
1288
1062
  if (awsOk2 && tfOk) {
@@ -1290,15 +1064,15 @@ async function ensurePrerequisites() {
1290
1064
  return true;
1291
1065
  }
1292
1066
  console.log("");
1293
- console.log(` ${chalk5.red("Missing prerequisites.")} Install them and try again.`);
1067
+ console.log(` ${chalk4.red("Missing prerequisites.")} Install them and try again.`);
1294
1068
  return false;
1295
1069
  }
1296
1070
 
1297
1071
  // src/cognito-discovery.ts
1298
- import { execSync as execSync5 } from "child_process";
1299
- function runAws2(cmd) {
1072
+ import { execSync as execSync4 } from "child_process";
1073
+ function runAws(cmd) {
1300
1074
  try {
1301
- return execSync5(`aws ${cmd}`, {
1075
+ return execSync4(`aws ${cmd}`, {
1302
1076
  encoding: "utf-8",
1303
1077
  timeout: 15e3,
1304
1078
  stdio: ["pipe", "pipe", "pipe"]
@@ -1318,7 +1092,7 @@ function tryTerraformOutput(stage) {
1318
1092
  }
1319
1093
  const read = (key) => {
1320
1094
  try {
1321
- return execSync5(`terraform output -raw ${key}`, {
1095
+ return execSync4(`terraform output -raw ${key}`, {
1322
1096
  cwd,
1323
1097
  encoding: "utf-8",
1324
1098
  timeout: 15e3,
@@ -1334,7 +1108,7 @@ function tryTerraformOutput(stage) {
1334
1108
  return { userPoolId, clientId, domain };
1335
1109
  }
1336
1110
  function tryAwsDiscovery(stage, region) {
1337
- const listRaw = runAws2(
1111
+ const listRaw = runAws(
1338
1112
  `cognito-idp list-user-pools --max-results 60 --region ${region} --output json`
1339
1113
  );
1340
1114
  if (!listRaw) return {};
@@ -1346,7 +1120,7 @@ function tryAwsDiscovery(stage, region) {
1346
1120
  )
1347
1121
  );
1348
1122
  if (!pool) return {};
1349
- const clientsRaw = runAws2(
1123
+ const clientsRaw = runAws(
1350
1124
  `cognito-idp list-user-pool-clients --user-pool-id ${pool.Id} --region ${region} --output json`
1351
1125
  );
1352
1126
  let clientId;
@@ -1379,8 +1153,8 @@ function discoverCognitoConfig(stage, region) {
1379
1153
  // src/cognito-oauth.ts
1380
1154
  import { createServer } from "http";
1381
1155
  import { randomBytes } from "crypto";
1382
- import { spawn as spawn4 } from "child_process";
1383
- import chalk6 from "chalk";
1156
+ import { spawn as spawn3 } from "child_process";
1157
+ import chalk5 from "chalk";
1384
1158
  var CLI_LOOPBACK_PORT = 42010;
1385
1159
  var CALLBACK_PATH = "/callback";
1386
1160
  var DEFAULT_TIMEOUT_MS = 5 * 60 * 1e3;
@@ -1396,9 +1170,9 @@ async function loginWithCognito(opts) {
1396
1170
  timeoutMs,
1397
1171
  onListening: () => {
1398
1172
  logStderr("");
1399
- logStderr(` ${chalk6.cyan("Opening browser to sign in\u2026")}`);
1400
- logStderr(` ${chalk6.dim("If it doesn't open automatically, visit:")}`);
1401
- logStderr(` ${chalk6.dim(authorizeUrl)}`);
1173
+ logStderr(` ${chalk5.cyan("Opening browser to sign in\u2026")}`);
1174
+ logStderr(` ${chalk5.dim("If it doesn't open automatically, visit:")}`);
1175
+ logStderr(` ${chalk5.dim(authorizeUrl)}`);
1402
1176
  logStderr("");
1403
1177
  if (opts.openBrowser !== false) {
1404
1178
  (opts.launchBrowser ?? openInBrowser)(authorizeUrl);
@@ -1558,7 +1332,7 @@ function openInBrowser(url) {
1558
1332
  const cmd = platform2 === "darwin" ? "open" : platform2 === "win32" ? "cmd" : "xdg-open";
1559
1333
  const args = platform2 === "win32" ? ["/c", "start", "", url] : [url];
1560
1334
  try {
1561
- spawn4(cmd, args, { stdio: "ignore", detached: true }).unref();
1335
+ spawn3(cmd, args, { stdio: "ignore", detached: true }).unref();
1562
1336
  } catch {
1563
1337
  }
1564
1338
  }
@@ -1629,7 +1403,7 @@ function ask(prompt) {
1629
1403
  }
1630
1404
  function verifyProfile(profile) {
1631
1405
  try {
1632
- const raw = execSync6(
1406
+ const raw = execSync5(
1633
1407
  `aws sts get-caller-identity --profile ${profile} --output json`,
1634
1408
  { encoding: "utf-8", timeout: 15e3, stdio: ["pipe", "pipe", "pipe"] }
1635
1409
  );
@@ -1659,7 +1433,7 @@ async function pickProfile(profiles) {
1659
1433
  return { kind: "cancel" };
1660
1434
  }
1661
1435
  const choices = profiles.map((p) => ({
1662
- name: `${p.name} ${chalk7.dim(`(${describeType(p.type)})`)}`,
1436
+ name: `${p.name} ${chalk6.dim(`(${describeType(p.type)})`)}`,
1663
1437
  value: { kind: "existing", name: p.name }
1664
1438
  }));
1665
1439
  choices.push(new Separator());
@@ -1706,15 +1480,15 @@ async function runKeyEntry(targetProfile) {
1706
1480
  const region = await ask(" Default region [us-east-1]: ");
1707
1481
  const finalRegion = region || "us-east-1";
1708
1482
  try {
1709
- execSync6(
1483
+ execSync5(
1710
1484
  `aws configure set aws_access_key_id "${accessKeyId}" --profile ${targetProfile}`,
1711
1485
  { stdio: "pipe" }
1712
1486
  );
1713
- execSync6(
1487
+ execSync5(
1714
1488
  `aws configure set aws_secret_access_key "${secretAccessKey}" --profile ${targetProfile}`,
1715
1489
  { stdio: "pipe" }
1716
1490
  );
1717
- execSync6(
1491
+ execSync5(
1718
1492
  `aws configure set region "${finalRegion}" --profile ${targetProfile}`,
1719
1493
  { stdio: "pipe" }
1720
1494
  );
@@ -1728,7 +1502,7 @@ function runSsoLogin(targetProfile) {
1728
1502
  console.log(" Launching AWS SSO login...");
1729
1503
  console.log("");
1730
1504
  try {
1731
- execSync6(`aws sso login --profile ${targetProfile}`, { stdio: "inherit" });
1505
+ execSync5(`aws sso login --profile ${targetProfile}`, { stdio: "inherit" });
1732
1506
  return true;
1733
1507
  } catch {
1734
1508
  printError(
@@ -1757,7 +1531,7 @@ function finalizeAws(profile, mode) {
1757
1531
  ` (\`thinkwork list\`, \`thinkwork deploy\`, \u2026) will use it automatically.`
1758
1532
  );
1759
1533
  console.log(
1760
- chalk7.dim(
1534
+ chalk6.dim(
1761
1535
  ` Override per-command with --profile <other>, or unset with \`rm ~/.thinkwork/config.json\`.`
1762
1536
  )
1763
1537
  );
@@ -1771,10 +1545,10 @@ async function offerApiLoginChain(opts) {
1771
1545
  if (candidates.length === 0 || !isInteractive()) {
1772
1546
  console.log("");
1773
1547
  console.log(
1774
- ` ${chalk7.bold("Next:")} run ${chalk7.cyan("thinkwork login --stage <stage>")} if you also need`
1548
+ ` ${chalk6.bold("Next:")} run ${chalk6.cyan("thinkwork login --stage <stage>")} if you also need`
1775
1549
  );
1776
1550
  console.log(
1777
- ` an API session (required for ${chalk7.cyan("eval")}, ${chalk7.cyan("agent")}, ${chalk7.cyan("thread")}, etc.).`
1551
+ ` an API session (required for ${chalk6.cyan("eval")}, ${chalk6.cyan("agent")}, ${chalk6.cyan("thread")}, etc.).`
1778
1552
  );
1779
1553
  return;
1780
1554
  }
@@ -1808,8 +1582,8 @@ async function offerApiLoginChain(opts) {
1808
1582
  if (!chosen) {
1809
1583
  console.log("");
1810
1584
  console.log(
1811
- chalk7.dim(
1812
- ` Skipped. Run ${chalk7.cyan("thinkwork login --stage <stage>")} later for an API session.`
1585
+ chalk6.dim(
1586
+ ` Skipped. Run ${chalk6.cyan("thinkwork login --stage <stage>")} later for an API session.`
1813
1587
  )
1814
1588
  );
1815
1589
  return;
@@ -1906,7 +1680,7 @@ async function doCognitoLogin(opts) {
1906
1680
  }
1907
1681
  console.log("");
1908
1682
  console.log(
1909
- chalk7.dim(
1683
+ chalk6.dim(
1910
1684
  ` Token expires: ${new Date(tokens.expiresAt * 1e3).toISOString()}. Refreshed automatically.`
1911
1685
  )
1912
1686
  );
@@ -2060,9 +1834,9 @@ Registered callback URL:
2060
1834
  const profiles = listAwsProfiles();
2061
1835
  if (profiles.length === 0) {
2062
1836
  console.log("");
2063
- console.log(chalk7.dim(" No AWS profiles found in ~/.aws/."));
1837
+ console.log(chalk6.dim(" No AWS profiles found in ~/.aws/."));
2064
1838
  console.log(
2065
- chalk7.dim(" Falling through to access-key entry for a new profile.")
1839
+ chalk6.dim(" Falling through to access-key entry for a new profile.")
2066
1840
  );
2067
1841
  if (!await runKeyEntry(targetProfile)) process.exit(1);
2068
1842
  process.env.AWS_PROFILE = targetProfile;
@@ -2073,7 +1847,7 @@ Registered callback URL:
2073
1847
  const choice = await pickProfile(profiles);
2074
1848
  if (choice.kind === "cancel") {
2075
1849
  console.log("");
2076
- console.log(chalk7.dim(" Cancelled. No changes made."));
1850
+ console.log(chalk6.dim(" Cancelled. No changes made."));
2077
1851
  return;
2078
1852
  }
2079
1853
  if (choice.kind === "keys") {
@@ -2174,16 +1948,16 @@ Examples:
2174
1948
  }
2175
1949
 
2176
1950
  // src/commands/init.ts
2177
- import { existsSync as existsSync8, mkdirSync as mkdirSync4, writeFileSync as writeFileSync4, cpSync } from "fs";
2178
- import { resolve as resolve2, join as join5, dirname as dirname3 } from "path";
2179
- import { execSync as execSync7 } from "child_process";
1951
+ import { existsSync as existsSync6, mkdirSync as mkdirSync3, writeFileSync as writeFileSync3, cpSync } from "fs";
1952
+ import { resolve as resolve2, join as join4, dirname as dirname3 } from "path";
1953
+ import { execSync as execSync6 } from "child_process";
2180
1954
  import { fileURLToPath as fileURLToPath2 } from "url";
2181
1955
  import { createInterface as createInterface3 } from "readline";
2182
- import chalk8 from "chalk";
1956
+ import chalk7 from "chalk";
2183
1957
  var __dirname = dirname3(fileURLToPath2(import.meta.url));
2184
1958
  function ask2(prompt, defaultVal = "") {
2185
1959
  const rl = createInterface3({ input: process.stdin, output: process.stdout });
2186
- const suffix = defaultVal ? chalk8.dim(` [${defaultVal}]`) : "";
1960
+ const suffix = defaultVal ? chalk7.dim(` [${defaultVal}]`) : "";
2187
1961
  return new Promise((resolve7) => {
2188
1962
  rl.question(` ${prompt}${suffix}: `, (answer) => {
2189
1963
  rl.close();
@@ -2192,7 +1966,7 @@ function ask2(prompt, defaultVal = "") {
2192
1966
  });
2193
1967
  }
2194
1968
  function choose(prompt, options, defaultVal) {
2195
- const optStr = options.map((o) => o === defaultVal ? chalk8.bold(o) : chalk8.dim(o)).join(" / ");
1969
+ const optStr = options.map((o) => o === defaultVal ? chalk7.bold(o) : chalk7.dim(o)).join(" / ");
2196
1970
  return ask2(`${prompt} (${optStr})`, defaultVal);
2197
1971
  }
2198
1972
  function generateSecret(length = 32) {
@@ -2205,9 +1979,9 @@ function generateSecret(length = 32) {
2205
1979
  }
2206
1980
  function findBundledTerraform() {
2207
1981
  const bundled = resolve2(__dirname, "terraform");
2208
- if (existsSync8(join5(bundled, "modules"))) return bundled;
1982
+ if (existsSync6(join4(bundled, "modules"))) return bundled;
2209
1983
  const repoTf = resolve2(__dirname, "..", "..", "..", "terraform");
2210
- if (existsSync8(join5(repoTf, "modules"))) return repoTf;
1984
+ if (existsSync6(join4(repoTf, "modules"))) return repoTf;
2211
1985
  throw new Error(
2212
1986
  "Terraform modules not found. The CLI package may be incomplete.\nTry reinstalling: npm install -g thinkwork-cli@latest"
2213
1987
  );
@@ -2267,9 +2041,9 @@ function registerInitCommand(program2) {
2267
2041
  printError("Stage name is required. Pass -s <name> or re-run in an interactive terminal.");
2268
2042
  process.exit(1);
2269
2043
  }
2270
- const { input: input20 } = await import("@inquirer/prompts");
2044
+ const { input: input21 } = await import("@inquirer/prompts");
2271
2045
  try {
2272
- stage = await input20({
2046
+ stage = await input21({
2273
2047
  message: "Stage name (e.g. dev, staging, prod):",
2274
2048
  validate: (v) => validateStage(v).error ?? true
2275
2049
  });
@@ -2297,9 +2071,9 @@ function registerInitCommand(program2) {
2297
2071
  process.exit(1);
2298
2072
  }
2299
2073
  const targetDir = resolve2(opts.dir);
2300
- const tfDir = join5(targetDir, "terraform");
2301
- const tfvarsPath = join5(tfDir, "terraform.tfvars");
2302
- if (existsSync8(tfvarsPath)) {
2074
+ const tfDir = join4(targetDir, "terraform");
2075
+ const tfvarsPath = join4(tfDir, "terraform.tfvars");
2076
+ if (existsSync6(tfvarsPath)) {
2303
2077
  printWarning(`terraform.tfvars already exists at ${tfvarsPath}`);
2304
2078
  const overwrite = await ask2("Overwrite?", "N");
2305
2079
  if (overwrite.toLowerCase() !== "y") {
@@ -2323,21 +2097,21 @@ function registerInitCommand(program2) {
2323
2097
  config.admin_url = "http://localhost:5174";
2324
2098
  config.mobile_scheme = "thinkwork";
2325
2099
  } else {
2326
- console.log(chalk8.bold(" Configure your Thinkwork environment\n"));
2100
+ console.log(chalk7.bold(" Configure your Thinkwork environment\n"));
2327
2101
  const defaultRegion = identity.region !== "unknown" ? identity.region : "us-east-1";
2328
2102
  config.region = await ask2("AWS Region", defaultRegion);
2329
2103
  console.log("");
2330
- console.log(chalk8.dim(" \u2500\u2500 Database \u2500\u2500"));
2104
+ console.log(chalk7.dim(" \u2500\u2500 Database \u2500\u2500"));
2331
2105
  config.database_engine = await choose("Database engine", ["aurora-serverless", "rds-postgres"], "aurora-serverless");
2332
2106
  console.log("");
2333
- console.log(chalk8.dim(" \u2500\u2500 Memory \u2500\u2500"));
2334
- console.log(chalk8.dim(" AgentCore managed memory is always on (automatic retention)."));
2335
- console.log(chalk8.dim(" Hindsight is an optional add-on: ECS Fargate service for"));
2336
- console.log(chalk8.dim(" semantic + entity-graph retrieval (~$75/mo)."));
2107
+ console.log(chalk7.dim(" \u2500\u2500 Memory \u2500\u2500"));
2108
+ console.log(chalk7.dim(" AgentCore managed memory is always on (automatic retention)."));
2109
+ console.log(chalk7.dim(" Hindsight is an optional add-on: ECS Fargate service for"));
2110
+ console.log(chalk7.dim(" semantic + entity-graph retrieval (~$75/mo)."));
2337
2111
  const hindsightAnswer = await ask2("Enable Hindsight long-term memory add-on? (y/N)", "N");
2338
2112
  config.enable_hindsight = hindsightAnswer.toLowerCase() === "y" ? "true" : "false";
2339
2113
  console.log("");
2340
- console.log(chalk8.dim(" \u2500\u2500 Auth \u2500\u2500"));
2114
+ console.log(chalk7.dim(" \u2500\u2500 Auth \u2500\u2500"));
2341
2115
  const useGoogle = await ask2("Enable Google OAuth login? (y/N)", "N");
2342
2116
  if (useGoogle.toLowerCase() === "y") {
2343
2117
  config.google_oauth_client_id = await ask2("Google OAuth Client ID");
@@ -2347,13 +2121,13 @@ function registerInitCommand(program2) {
2347
2121
  config.google_oauth_client_secret = "";
2348
2122
  }
2349
2123
  console.log("");
2350
- console.log(chalk8.dim(" \u2500\u2500 Frontend URLs \u2500\u2500"));
2124
+ console.log(chalk7.dim(" \u2500\u2500 Frontend URLs \u2500\u2500"));
2351
2125
  config.admin_url = await ask2("Admin UI URL", "http://localhost:5174");
2352
2126
  config.mobile_scheme = await ask2("Mobile app URL scheme", "thinkwork");
2353
2127
  console.log("");
2354
- console.log(chalk8.dim(" \u2500\u2500 Secrets (auto-generated) \u2500\u2500"));
2355
- console.log(chalk8.dim(` DB password: ${config.db_password.slice(0, 8)}...`));
2356
- console.log(chalk8.dim(` API auth secret: ${config.api_auth_secret.slice(0, 16)}...`));
2128
+ console.log(chalk7.dim(" \u2500\u2500 Secrets (auto-generated) \u2500\u2500"));
2129
+ console.log(chalk7.dim(` DB password: ${config.db_password.slice(0, 8)}...`));
2130
+ console.log(chalk7.dim(` API auth secret: ${config.api_auth_secret.slice(0, 16)}...`));
2357
2131
  }
2358
2132
  console.log("");
2359
2133
  console.log(" Scaffolding Terraform modules...");
@@ -2364,24 +2138,24 @@ function registerInitCommand(program2) {
2364
2138
  printError(String(err));
2365
2139
  process.exit(1);
2366
2140
  }
2367
- mkdirSync4(tfDir, { recursive: true });
2141
+ mkdirSync3(tfDir, { recursive: true });
2368
2142
  const copyDirs = ["modules", "examples"];
2369
2143
  for (const dir of copyDirs) {
2370
- const src = join5(bundledTf, dir);
2371
- const dst = join5(tfDir, dir);
2372
- if (existsSync8(src) && !existsSync8(dst)) {
2144
+ const src = join4(bundledTf, dir);
2145
+ const dst = join4(tfDir, dir);
2146
+ if (existsSync6(src) && !existsSync6(dst)) {
2373
2147
  cpSync(src, dst, { recursive: true });
2374
2148
  }
2375
2149
  }
2376
- const schemaPath = join5(bundledTf, "schema.graphql");
2377
- if (existsSync8(schemaPath) && !existsSync8(join5(tfDir, "schema.graphql"))) {
2378
- cpSync(schemaPath, join5(tfDir, "schema.graphql"));
2150
+ const schemaPath = join4(bundledTf, "schema.graphql");
2151
+ if (existsSync6(schemaPath) && !existsSync6(join4(tfDir, "schema.graphql"))) {
2152
+ cpSync(schemaPath, join4(tfDir, "schema.graphql"));
2379
2153
  }
2380
2154
  const tfvars = buildTfvars(config);
2381
- writeFileSync4(tfvarsPath, tfvars);
2382
- const mainTfPath = join5(tfDir, "main.tf");
2383
- if (!existsSync8(mainTfPath)) {
2384
- writeFileSync4(mainTfPath, `################################################################################
2155
+ writeFileSync3(tfvarsPath, tfvars);
2156
+ const mainTfPath = join4(tfDir, "main.tf");
2157
+ if (!existsSync6(mainTfPath)) {
2158
+ writeFileSync3(mainTfPath, `################################################################################
2385
2159
  # Thinkwork \u2014 ${config.stage}
2386
2160
  # Generated by: thinkwork init -s ${config.stage}
2387
2161
  ################################################################################
@@ -2558,20 +2332,20 @@ output "agentcore_memory_id" {
2558
2332
  }
2559
2333
  `);
2560
2334
  }
2561
- console.log(` Wrote ${chalk8.cyan(tfDir + "/")}`);
2335
+ console.log(` Wrote ${chalk7.cyan(tfDir + "/")}`);
2562
2336
  console.log("");
2563
- console.log(chalk8.dim(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
2564
- console.log(` ${chalk8.bold("Stage:")} ${config.stage}`);
2565
- console.log(` ${chalk8.bold("Region:")} ${config.region}`);
2566
- console.log(` ${chalk8.bold("Account:")} ${config.account_id}`);
2567
- console.log(` ${chalk8.bold("Database:")} ${config.database_engine}`);
2568
- console.log(` ${chalk8.bold("Memory:")} managed (always on)${config.enable_hindsight === "true" ? " + hindsight" : ""}`);
2569
- console.log(` ${chalk8.bold("Google OAuth:")} ${config.google_oauth_client_id ? "enabled" : "disabled"}`);
2570
- console.log(` ${chalk8.bold("Directory:")} ${tfDir}`);
2571
- console.log(chalk8.dim(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
2337
+ console.log(chalk7.dim(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
2338
+ console.log(` ${chalk7.bold("Stage:")} ${config.stage}`);
2339
+ console.log(` ${chalk7.bold("Region:")} ${config.region}`);
2340
+ console.log(` ${chalk7.bold("Account:")} ${config.account_id}`);
2341
+ console.log(` ${chalk7.bold("Database:")} ${config.database_engine}`);
2342
+ console.log(` ${chalk7.bold("Memory:")} managed (always on)${config.enable_hindsight === "true" ? " + hindsight" : ""}`);
2343
+ console.log(` ${chalk7.bold("Google OAuth:")} ${config.google_oauth_client_id ? "enabled" : "disabled"}`);
2344
+ console.log(` ${chalk7.bold("Directory:")} ${tfDir}`);
2345
+ console.log(chalk7.dim(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
2572
2346
  console.log("\n Initializing Terraform...\n");
2573
2347
  try {
2574
- execSync7("terraform init", { cwd: tfDir, stdio: "inherit" });
2348
+ execSync6("terraform init", { cwd: tfDir, stdio: "inherit" });
2575
2349
  } catch {
2576
2350
  printWarning("Terraform init failed. Run `thinkwork doctor -s " + stage + "` to check prerequisites.");
2577
2351
  return;
@@ -2590,24 +2364,24 @@ output "agentcore_memory_id" {
2590
2364
  printSuccess(`Environment "${stage}" initialized`);
2591
2365
  console.log("");
2592
2366
  console.log(" Next steps:");
2593
- console.log(` ${chalk8.cyan("1.")} thinkwork plan -s ${stage} ${chalk8.dim("# Review infrastructure plan")}`);
2594
- console.log(` ${chalk8.cyan("2.")} thinkwork deploy -s ${stage} ${chalk8.dim("# Deploy to AWS (~5 min)")}`);
2595
- console.log(` ${chalk8.cyan("3.")} thinkwork bootstrap -s ${stage} ${chalk8.dim("# Seed workspace files + skills")}`);
2596
- console.log(` ${chalk8.cyan("4.")} thinkwork outputs -s ${stage} ${chalk8.dim("# Show API URL, Cognito IDs, etc.")}`);
2367
+ console.log(` ${chalk7.cyan("1.")} thinkwork plan -s ${stage} ${chalk7.dim("# Review infrastructure plan")}`);
2368
+ console.log(` ${chalk7.cyan("2.")} thinkwork deploy -s ${stage} ${chalk7.dim("# Deploy to AWS (~5 min)")}`);
2369
+ console.log(` ${chalk7.cyan("3.")} thinkwork bootstrap -s ${stage} ${chalk7.dim("# Seed workspace files + skills")}`);
2370
+ console.log(` ${chalk7.cyan("4.")} thinkwork outputs -s ${stage} ${chalk7.dim("# Show API URL, Cognito IDs, etc.")}`);
2597
2371
  console.log("");
2598
2372
  });
2599
2373
  }
2600
2374
 
2601
2375
  // src/commands/status.ts
2602
- import { execSync as execSync8 } from "child_process";
2603
- import chalk9 from "chalk";
2376
+ import { execSync as execSync7 } from "child_process";
2377
+ import chalk8 from "chalk";
2604
2378
  function link(url, label) {
2605
2379
  const text = label || url;
2606
2380
  return `\x1B]8;;${url}\x1B\\${text}\x1B]8;;\x1B\\`;
2607
2381
  }
2608
- function runAws3(cmd) {
2382
+ function runAws2(cmd) {
2609
2383
  try {
2610
- return execSync8(`aws ${cmd}`, {
2384
+ return execSync7(`aws ${cmd}`, {
2611
2385
  encoding: "utf-8",
2612
2386
  timeout: 15e3,
2613
2387
  stdio: ["pipe", "pipe", "pipe"]
@@ -2618,7 +2392,7 @@ function runAws3(cmd) {
2618
2392
  }
2619
2393
  function discoverAwsStages(region) {
2620
2394
  const stages = /* @__PURE__ */ new Map();
2621
- const raw = runAws3(
2395
+ const raw = runAws2(
2622
2396
  `lambda list-functions --region ${region} --query "Functions[?starts_with(FunctionName, 'thinkwork-')].FunctionName" --output json`
2623
2397
  );
2624
2398
  if (!raw) return stages;
@@ -2633,38 +2407,38 @@ function discoverAwsStages(region) {
2633
2407
  for (const [stage, info] of stages) {
2634
2408
  const count = functions.filter((f) => f.startsWith(`thinkwork-${stage}-`)).length;
2635
2409
  info.lambdaCount = count;
2636
- const apiRaw = runAws3(
2410
+ const apiRaw = runAws2(
2637
2411
  `apigatewayv2 get-apis --region ${region} --query "Items[?Name=='thinkwork-${stage}-api'].ApiEndpoint|[0]" --output text`
2638
2412
  );
2639
2413
  if (apiRaw && apiRaw !== "None") info.apiEndpoint = apiRaw;
2640
- const appsyncRaw = runAws3(
2414
+ const appsyncRaw = runAws2(
2641
2415
  `appsync list-graphql-apis --region ${region} --query "graphqlApis[?name=='thinkwork-${stage}-subscriptions'].uris.REALTIME|[0]" --output text`
2642
2416
  );
2643
2417
  if (appsyncRaw && appsyncRaw !== "None") info.appsyncUrl = appsyncRaw;
2644
- const appsyncApiRaw = runAws3(
2418
+ const appsyncApiRaw = runAws2(
2645
2419
  `appsync list-graphql-apis --region ${region} --query "graphqlApis[?name=='thinkwork-${stage}-subscriptions'].uris.GRAPHQL|[0]" --output text`
2646
2420
  );
2647
2421
  if (appsyncApiRaw && appsyncApiRaw !== "None") info.appsyncApiUrl = appsyncApiRaw;
2648
- const acRaw = runAws3(
2422
+ const acRaw = runAws2(
2649
2423
  `lambda get-function --function-name thinkwork-${stage}-agentcore --region ${region} --query "Configuration.State" --output text 2>/dev/null`
2650
2424
  );
2651
2425
  info.agentcoreStatus = acRaw || "not deployed";
2652
- const bucketRaw = runAws3(
2426
+ const bucketRaw = runAws2(
2653
2427
  `s3api head-bucket --bucket thinkwork-${stage}-storage --region ${region} 2>/dev/null && echo "exists"`
2654
2428
  );
2655
2429
  info.bucketName = bucketRaw ? `thinkwork-${stage}-storage` : void 0;
2656
- const ecsRaw = runAws3(
2430
+ const ecsRaw = runAws2(
2657
2431
  `ecs describe-services --cluster thinkwork-${stage}-cluster --services thinkwork-${stage}-hindsight --region ${region} --query "services[0].runningCount" --output text 2>/dev/null`
2658
2432
  );
2659
2433
  if (ecsRaw && ecsRaw !== "None" && ecsRaw !== "0") {
2660
2434
  info.hindsightEnabled = true;
2661
- const albRaw = runAws3(
2435
+ const albRaw = runAws2(
2662
2436
  `elbv2 describe-load-balancers --region ${region} --query "LoadBalancers[?contains(LoadBalancerName, 'tw-${stage}-hindsight')].DNSName|[0]" --output text`
2663
2437
  );
2664
2438
  if (albRaw && albRaw !== "None") {
2665
2439
  info.hindsightEndpoint = `http://${albRaw}`;
2666
2440
  try {
2667
- const health = execSync8(`curl -s --max-time 3 http://${albRaw}/health`, { encoding: "utf-8" }).trim();
2441
+ const health = execSync7(`curl -s --max-time 3 http://${albRaw}/health`, { encoding: "utf-8" }).trim();
2668
2442
  info.hindsightHealth = health.includes("healthy") ? "healthy" : "unhealthy";
2669
2443
  } catch {
2670
2444
  info.hindsightHealth = "unreachable";
@@ -2673,15 +2447,15 @@ function discoverAwsStages(region) {
2673
2447
  } else {
2674
2448
  info.hindsightEnabled = false;
2675
2449
  }
2676
- const dbRaw = runAws3(
2450
+ const dbRaw = runAws2(
2677
2451
  `rds describe-db-clusters --region ${region} --query "DBClusters[?starts_with(DBClusterIdentifier, 'thinkwork-${stage}')].Endpoint|[0]" --output text`
2678
2452
  );
2679
2453
  if (dbRaw && dbRaw !== "None") info.dbEndpoint = dbRaw;
2680
- const ecrRaw = runAws3(
2454
+ const ecrRaw = runAws2(
2681
2455
  `ecr describe-repositories --region ${region} --query "repositories[?repositoryName=='thinkwork-${stage}-agentcore'].repositoryUri|[0]" --output text`
2682
2456
  );
2683
2457
  if (ecrRaw && ecrRaw !== "None") info.ecrUrl = ecrRaw;
2684
- const cfJson = runAws3(
2458
+ const cfJson = runAws2(
2685
2459
  `cloudfront list-distributions --query "DistributionList.Items[?contains(Origins.Items[0].DomainName, 'thinkwork-${stage}-')].{Origin:Origins.Items[0].DomainName,Domain:DomainName}" --output json`
2686
2460
  );
2687
2461
  if (cfJson) {
@@ -2698,33 +2472,33 @@ function discoverAwsStages(region) {
2698
2472
  return stages;
2699
2473
  }
2700
2474
  function printStageDetail(info) {
2701
- console.log(chalk9.bold.cyan(` \u2B21 ${info.stage}`));
2702
- console.log(chalk9.dim(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
2703
- console.log(` ${chalk9.bold("Source:")} ${info.source === "both" ? "AWS + local config" : info.source === "aws" ? "AWS (no local config)" : "local only (not in AWS)"}`);
2704
- console.log(` ${chalk9.bold("Region:")} ${info.region}`);
2705
- console.log(` ${chalk9.bold("Account:")} ${info.accountId}`);
2706
- console.log(` ${chalk9.bold("Lambda fns:")} ${info.lambdaCount || "\u2014"}`);
2707
- console.log(` ${chalk9.bold("AgentCore:")} ${info.agentcoreStatus || "unknown"}`);
2708
- console.log(` ${chalk9.bold("Memory:")} managed (always on)`);
2475
+ console.log(chalk8.bold.cyan(` \u2B21 ${info.stage}`));
2476
+ console.log(chalk8.dim(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
2477
+ console.log(` ${chalk8.bold("Source:")} ${info.source === "both" ? "AWS + local config" : info.source === "aws" ? "AWS (no local config)" : "local only (not in AWS)"}`);
2478
+ console.log(` ${chalk8.bold("Region:")} ${info.region}`);
2479
+ console.log(` ${chalk8.bold("Account:")} ${info.accountId}`);
2480
+ console.log(` ${chalk8.bold("Lambda fns:")} ${info.lambdaCount || "\u2014"}`);
2481
+ console.log(` ${chalk8.bold("AgentCore:")} ${info.agentcoreStatus || "unknown"}`);
2482
+ console.log(` ${chalk8.bold("Memory:")} managed (always on)`);
2709
2483
  const hindsightLabel = info.hindsightEnabled === void 0 ? "unknown" : info.hindsightEnabled ? info.hindsightHealth || "running" : "disabled";
2710
- console.log(` ${chalk9.bold("Hindsight:")} ${hindsightLabel}`);
2711
- if (info.bucketName) console.log(` ${chalk9.bold("S3 bucket:")} ${info.bucketName}`);
2712
- if (info.dbEndpoint) console.log(` ${chalk9.bold("Database:")} ${info.dbEndpoint}`);
2713
- if (info.ecrUrl) console.log(` ${chalk9.bold("ECR:")} ${info.ecrUrl}`);
2484
+ console.log(` ${chalk8.bold("Hindsight:")} ${hindsightLabel}`);
2485
+ if (info.bucketName) console.log(` ${chalk8.bold("S3 bucket:")} ${info.bucketName}`);
2486
+ if (info.dbEndpoint) console.log(` ${chalk8.bold("Database:")} ${info.dbEndpoint}`);
2487
+ if (info.ecrUrl) console.log(` ${chalk8.bold("ECR:")} ${info.ecrUrl}`);
2714
2488
  console.log("");
2715
- console.log(chalk9.bold(" URLs:"));
2489
+ console.log(chalk8.bold(" URLs:"));
2716
2490
  if (info.adminUrl) console.log(` Admin: ${link(info.adminUrl)}`);
2717
2491
  if (info.docsUrl) console.log(` Docs: ${link(info.docsUrl)}`);
2718
2492
  if (info.apiEndpoint) console.log(` API: ${link(info.apiEndpoint)}`);
2719
2493
  if (info.appsyncApiUrl) console.log(` AppSync: ${link(info.appsyncApiUrl)}`);
2720
2494
  if (info.appsyncUrl) console.log(` WebSocket: ${link(info.appsyncUrl)}`);
2721
2495
  if (info.hindsightEndpoint) console.log(` Hindsight: ${link(info.hindsightEndpoint)}`);
2722
- console.log(chalk9.dim(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
2496
+ console.log(chalk8.dim(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
2723
2497
  const local = loadEnvironment(info.stage);
2724
2498
  if (local) {
2725
- console.log(chalk9.dim(` Terraform dir: ${local.terraformDir}`));
2499
+ console.log(chalk8.dim(` Terraform dir: ${local.terraformDir}`));
2726
2500
  } else {
2727
- console.log(chalk9.dim(` No local config. Run: thinkwork init -s ${info.stage}`));
2501
+ console.log(chalk8.dim(` No local config. Run: thinkwork init -s ${info.stage}`));
2728
2502
  }
2729
2503
  console.log("");
2730
2504
  }
@@ -2761,7 +2535,7 @@ and AgentCore for per-stage detail.
2761
2535
  printError("AWS credentials not configured. Run `thinkwork login` first.");
2762
2536
  process.exit(1);
2763
2537
  }
2764
- console.log(chalk9.dim(" Scanning AWS account for Thinkwork deployments...\n"));
2538
+ console.log(chalk8.dim(" Scanning AWS account for Thinkwork deployments...\n"));
2765
2539
  const awsStages = discoverAwsStages(opts.region);
2766
2540
  const localEnvs = listEnvironments();
2767
2541
  const merged = /* @__PURE__ */ new Map();
@@ -2796,7 +2570,7 @@ and AgentCore for per-stage detail.
2796
2570
  }
2797
2571
  if (merged.size === 0) {
2798
2572
  console.log(" No Thinkwork environments found.");
2799
- console.log(` Run ${chalk9.cyan("thinkwork init -s <stage>")} to create one.`);
2573
+ console.log(` Run ${chalk8.cyan("thinkwork init -s <stage>")} to create one.`);
2800
2574
  console.log("");
2801
2575
  return;
2802
2576
  }
@@ -2807,7 +2581,7 @@ and AgentCore for per-stage detail.
2807
2581
  }
2808
2582
 
2809
2583
  // src/commands/mcp.ts
2810
- import chalk10 from "chalk";
2584
+ import chalk9 from "chalk";
2811
2585
 
2812
2586
  // ../../packages/admin-ops/src/client.ts
2813
2587
  var AdminOpsError = class extends Error {
@@ -2823,7 +2597,7 @@ var AdminOpsError = class extends Error {
2823
2597
  function createClient(config) {
2824
2598
  const fetchImpl = config.fetchImpl ?? fetch;
2825
2599
  const base = config.apiUrl.replace(/\/+$/, "");
2826
- const doFetch = async (path2, init = {}) => {
2600
+ const doFetch = async (path, init = {}) => {
2827
2601
  const headers = {
2828
2602
  "Content-Type": "application/json",
2829
2603
  Authorization: `Bearer ${config.authSecret}`,
@@ -2833,7 +2607,7 @@ function createClient(config) {
2833
2607
  if (config.principalEmail) headers["x-principal-email"] = config.principalEmail;
2834
2608
  if (config.tenantId) headers["x-tenant-id"] = config.tenantId;
2835
2609
  if (config.agentId) headers["x-agent-id"] = config.agentId;
2836
- const res = await fetchImpl(`${base}${path2}`, {
2610
+ const res = await fetchImpl(`${base}${path}`, {
2837
2611
  ...init,
2838
2612
  headers: { ...headers, ...init.headers }
2839
2613
  });
@@ -2883,10 +2657,10 @@ async function getTenant(client, id) {
2883
2657
  async function getTenantBySlug(client, slug) {
2884
2658
  return client.fetch(`/api/tenants/by-slug/${encodeURIComponent(slug)}`);
2885
2659
  }
2886
- async function updateTenant(client, id, input20) {
2660
+ async function updateTenant(client, id, input21) {
2887
2661
  return client.fetch(`/api/tenants/${encodeURIComponent(id)}`, {
2888
2662
  method: "PUT",
2889
- body: JSON.stringify(input20)
2663
+ body: JSON.stringify(input21)
2890
2664
  });
2891
2665
  }
2892
2666
 
@@ -2897,12 +2671,12 @@ __export(admin_keys_exports, {
2897
2671
  listAdminKeys: () => listAdminKeys,
2898
2672
  revokeAdminKey: () => revokeAdminKey
2899
2673
  });
2900
- async function createAdminKey(client, tenantIdOrSlug, input20 = {}) {
2674
+ async function createAdminKey(client, tenantIdOrSlug, input21 = {}) {
2901
2675
  return client.fetch(
2902
2676
  `/api/tenants/${encodeURIComponent(tenantIdOrSlug)}/mcp-admin-keys`,
2903
2677
  {
2904
2678
  method: "POST",
2905
- body: JSON.stringify(input20)
2679
+ body: JSON.stringify(input21)
2906
2680
  }
2907
2681
  );
2908
2682
  }
@@ -2919,87 +2693,6 @@ async function revokeAdminKey(client, tenantIdOrSlug, keyId) {
2919
2693
  );
2920
2694
  }
2921
2695
 
2922
- // src/api-client.ts
2923
- import { readFileSync as readFileSync5, existsSync as existsSync9 } from "fs";
2924
- import { execSync as execSync9 } from "child_process";
2925
- function readTfVar2(tfvarsPath, key) {
2926
- if (!existsSync9(tfvarsPath)) return null;
2927
- const content = readFileSync5(tfvarsPath, "utf-8");
2928
- const match = content.match(new RegExp(`^${key}\\s*=\\s*"([^"]*)"`, "m"));
2929
- return match ? match[1] : null;
2930
- }
2931
- function resolveTfvarsPath2(stage) {
2932
- const tfDir = resolveTerraformDir(stage);
2933
- if (tfDir) {
2934
- const direct = `${tfDir}/terraform.tfvars`;
2935
- if (existsSync9(direct)) return direct;
2936
- }
2937
- const terraformDir = process.env.THINKWORK_TERRAFORM_DIR || process.cwd();
2938
- const cwd = resolveTierDir(terraformDir, stage, "app");
2939
- return `${cwd}/terraform.tfvars`;
2940
- }
2941
- function getApiEndpoint2(stage, region) {
2942
- try {
2943
- const raw = execSync9(
2944
- `aws apigatewayv2 get-apis --region ${region} --query "Items[?Name=='thinkwork-${stage}-api'].ApiEndpoint|[0]" --output text`,
2945
- { encoding: "utf-8", timeout: 15e3, stdio: ["pipe", "pipe", "pipe"] }
2946
- ).trim();
2947
- return raw && raw !== "None" ? raw : null;
2948
- } catch {
2949
- return null;
2950
- }
2951
- }
2952
- async function apiFetch(apiUrl, authSecret, path2, options = {}, extraHeaders = {}) {
2953
- const res = await fetch(`${apiUrl}${path2}`, {
2954
- ...options,
2955
- headers: {
2956
- "Content-Type": "application/json",
2957
- Authorization: `Bearer ${authSecret}`,
2958
- ...extraHeaders,
2959
- ...options.headers
2960
- }
2961
- });
2962
- if (!res.ok) {
2963
- const body = await res.json().catch(() => ({}));
2964
- throw new Error(body.error || `HTTP ${res.status}`);
2965
- }
2966
- return res.json();
2967
- }
2968
- async function apiFetchRaw(apiUrl, authSecret, path2, options = {}, extraHeaders = {}) {
2969
- const res = await fetch(`${apiUrl}${path2}`, {
2970
- ...options,
2971
- headers: {
2972
- "Content-Type": "application/json",
2973
- Authorization: `Bearer ${authSecret}`,
2974
- ...extraHeaders,
2975
- ...options.headers
2976
- }
2977
- });
2978
- const body = await res.json().catch(() => ({}));
2979
- return { ok: res.ok, status: res.status, body };
2980
- }
2981
- function resolveApiConfig(stage, regionOverride) {
2982
- const tfvarsPath = resolveTfvarsPath2(stage);
2983
- const tfAuthSecret = readTfVar2(tfvarsPath, "api_auth_secret");
2984
- const tfRegion = readTfVar2(tfvarsPath, "region");
2985
- const region = regionOverride || tfRegion || "us-east-1";
2986
- const apiUrl = getApiEndpoint2(stage, region);
2987
- if (!apiUrl) {
2988
- printError(
2989
- `Cannot discover API endpoint for stage "${stage}" in ${region}. Is the stack deployed?`
2990
- );
2991
- return null;
2992
- }
2993
- const authSecret = tfAuthSecret ?? getApiAuthSecretFromLambda(stage, region);
2994
- if (!authSecret) {
2995
- printError(
2996
- `Cannot read api_auth_secret. Tried terraform.tfvars at ${tfvarsPath} and the \`thinkwork-${stage}-api-tenants\` Lambda env. Deploy the stack or set --profile to a role with lambda:GetFunctionConfiguration.`
2997
- );
2998
- return null;
2999
- }
3000
- return { apiUrl, authSecret };
3001
- }
3002
-
3003
2696
  // src/lib/resolve-tenant.ts
3004
2697
  import { select as select4 } from "@inquirer/prompts";
3005
2698
  async function resolveTenant(opts) {
@@ -3173,7 +2866,7 @@ async function resolveServer(identifier, api, tenantSlug) {
3173
2866
  getId: (s) => s.id,
3174
2867
  getAliases: (s) => [s.slug, s.name],
3175
2868
  resourceLabel: "MCP server",
3176
- pickerLabel: (s) => `${s.name} ${chalk10.dim(`(${s.slug}, ${s.id})`)}`
2869
+ pickerLabel: (s) => `${s.name} ${chalk9.dim(`(${s.slug}, ${s.id})`)}`
3177
2870
  });
3178
2871
  }
3179
2872
  function formatAuth(s) {
@@ -3206,13 +2899,13 @@ Examples:
3206
2899
  { "x-tenant-slug": tenant.slug }
3207
2900
  );
3208
2901
  if (!servers || servers.length === 0) {
3209
- console.log(chalk10.dim(" No MCP servers registered."));
2902
+ console.log(chalk9.dim(" No MCP servers registered."));
3210
2903
  return;
3211
2904
  }
3212
2905
  console.log("");
3213
2906
  for (const s of servers) {
3214
- const status = s.enabled ? chalk10.green("enabled") : chalk10.dim("disabled");
3215
- console.log(` ${chalk10.bold(s.name)} ${chalk10.dim(s.slug)} ${status}`);
2907
+ const status = s.enabled ? chalk9.green("enabled") : chalk9.dim("disabled");
2908
+ console.log(` ${chalk9.bold(s.name)} ${chalk9.dim(s.slug)} ${status}`);
3216
2909
  console.log(` ID: ${s.id}`);
3217
2910
  console.log(` URL: ${s.url}`);
3218
2911
  console.log(` Transport: ${s.transport}`);
@@ -3244,7 +2937,7 @@ Examples:
3244
2937
  ).action(
3245
2938
  async (nameArg, opts) => {
3246
2939
  try {
3247
- const { input: input20 } = await import("@inquirer/prompts");
2940
+ const { input: input21 } = await import("@inquirer/prompts");
3248
2941
  const { stage, api, tenant } = await resolveMcpContext(opts);
3249
2942
  let name = nameArg;
3250
2943
  if (!name) {
@@ -3252,7 +2945,7 @@ Examples:
3252
2945
  printError("Name is required. Pass it as a positional arg.");
3253
2946
  process.exit(1);
3254
2947
  }
3255
- name = await input20({ message: "Server name:" });
2948
+ name = await input21({ message: "Server name:" });
3256
2949
  }
3257
2950
  let url = opts.url;
3258
2951
  if (!url) {
@@ -3260,7 +2953,7 @@ Examples:
3260
2953
  printError("--url is required. Pass it as a flag.");
3261
2954
  process.exit(1);
3262
2955
  }
3263
- url = await input20({
2956
+ url = await input21({
3264
2957
  message: "MCP server URL:",
3265
2958
  validate: (v) => v.startsWith("http://") || v.startsWith("https://") ? true : "URL must start with http:// or https://"
3266
2959
  });
@@ -3393,12 +3086,12 @@ Examples:
3393
3086
  if (result.ok) {
3394
3087
  printSuccess(`Connection successful: ${server.name}.`);
3395
3088
  if (result.tools?.length) {
3396
- console.log(chalk10.bold(`
3089
+ console.log(chalk9.bold(`
3397
3090
  Discovered tools (${result.tools.length}):
3398
3091
  `));
3399
3092
  for (const t of result.tools) {
3400
3093
  console.log(
3401
- ` ${chalk10.cyan(t.name)}${t.description ? chalk10.dim(` - ${t.description}`) : ""}`
3094
+ ` ${chalk9.cyan(t.name)}${t.description ? chalk9.dim(` - ${t.description}`) : ""}`
3402
3095
  );
3403
3096
  }
3404
3097
  console.log("");
@@ -3420,7 +3113,7 @@ Examples:
3420
3113
  ).option("-s, --stage <name>", "Deployment stage").option("-t, --tenant <slug>", "Tenant slug").option("--agent <id>", "Agent ID").action(
3421
3114
  async (mcpServerArg, opts) => {
3422
3115
  try {
3423
- const { input: input20 } = await import("@inquirer/prompts");
3116
+ const { input: input21 } = await import("@inquirer/prompts");
3424
3117
  const { api, tenant } = await resolveMcpContext(opts);
3425
3118
  const server = await resolveServer(mcpServerArg, api, tenant.slug);
3426
3119
  let agent = opts.agent;
@@ -3429,7 +3122,7 @@ Examples:
3429
3122
  printError("--agent is required. Pass it as a flag.");
3430
3123
  process.exit(1);
3431
3124
  }
3432
- agent = await input20({ message: "Agent ID:" });
3125
+ agent = await input21({ message: "Agent ID:" });
3433
3126
  }
3434
3127
  const result = await apiFetch(
3435
3128
  api.apiUrl,
@@ -3452,7 +3145,7 @@ Examples:
3452
3145
  ).option("-s, --stage <name>", "Deployment stage").option("-t, --tenant <slug>", "Tenant slug").option("--agent <id>", "Agent ID").action(
3453
3146
  async (mcpServerArg, opts) => {
3454
3147
  try {
3455
- const { input: input20 } = await import("@inquirer/prompts");
3148
+ const { input: input21 } = await import("@inquirer/prompts");
3456
3149
  const { api, tenant } = await resolveMcpContext(opts);
3457
3150
  const server = await resolveServer(mcpServerArg, api, tenant.slug);
3458
3151
  let agent = opts.agent;
@@ -3461,7 +3154,7 @@ Examples:
3461
3154
  printError("--agent is required. Pass it as a flag.");
3462
3155
  process.exit(1);
3463
3156
  }
3464
- agent = await input20({ message: "Agent ID:" });
3157
+ agent = await input21({ message: "Agent ID:" });
3465
3158
  }
3466
3159
  await apiFetch(
3467
3160
  api.apiUrl,
@@ -3503,8 +3196,8 @@ old one.
3503
3196
  });
3504
3197
  printJson(created);
3505
3198
  printWarning("This token will NOT be shown again. Copy it now.");
3506
- printSuccess(`MCP admin key created: ${chalk10.bold(created.name)} (${created.id})`);
3507
- console.log(` ${chalk10.dim("Token:")} ${chalk10.cyan(created.token)}`);
3199
+ printSuccess(`MCP admin key created: ${chalk9.bold(created.name)} (${created.id})`);
3200
+ console.log(` ${chalk9.dim("Token:")} ${chalk9.cyan(created.token)}`);
3508
3201
  } catch (err) {
3509
3202
  if (isCancellation(err)) return;
3510
3203
  printError(err instanceof Error ? err.message : String(err));
@@ -3650,7 +3343,7 @@ SPA (or a future \`thinkwork mcp assign\` CLI pass).
3650
3343
 
3651
3344
  // src/commands/tools.ts
3652
3345
  import { select as select6, password } from "@inquirer/prompts";
3653
- import chalk11 from "chalk";
3346
+ import chalk10 from "chalk";
3654
3347
  var TOOL_PROVIDERS = {
3655
3348
  "web-search": ["exa", "serpapi"]
3656
3349
  };
@@ -3691,16 +3384,16 @@ Examples:
3691
3384
  { "x-tenant-slug": tenant.slug }
3692
3385
  );
3693
3386
  if (!rows || rows.length === 0) {
3694
- console.log(chalk11.dim(" No built-in tools configured."));
3695
- console.log(chalk11.dim(" Try: thinkwork tools web-search set"));
3387
+ console.log(chalk10.dim(" No built-in tools configured."));
3388
+ console.log(chalk10.dim(" Try: thinkwork tools web-search set"));
3696
3389
  return;
3697
3390
  }
3698
3391
  console.log("");
3699
3392
  for (const r of rows) {
3700
- const status = r.enabled ? chalk11.green("enabled") : chalk11.dim("disabled");
3701
- const key = r.hasSecret ? chalk11.green("yes") : chalk11.red("no");
3702
- const provider = r.provider ?? chalk11.dim("\u2014");
3703
- console.log(` ${chalk11.bold(r.toolSlug)} ${status}`);
3393
+ const status = r.enabled ? chalk10.green("enabled") : chalk10.dim("disabled");
3394
+ const key = r.hasSecret ? chalk10.green("yes") : chalk10.red("no");
3395
+ const provider = r.provider ?? chalk10.dim("\u2014");
3396
+ console.log(` ${chalk10.bold(r.toolSlug)} ${status}`);
3704
3397
  console.log(` Provider: ${provider}`);
3705
3398
  console.log(` Has key: ${key}`);
3706
3399
  if (r.lastTestedAt) console.log(` Tested: ${new Date(r.lastTestedAt).toLocaleString()}`);
@@ -3831,12 +3524,12 @@ Examples:
3831
3524
  }
3832
3525
 
3833
3526
  // src/commands/update.ts
3834
- import { execSync as execSync10 } from "child_process";
3527
+ import { execSync as execSync8 } from "child_process";
3835
3528
  import { realpathSync } from "fs";
3836
- import chalk12 from "chalk";
3529
+ import chalk11 from "chalk";
3837
3530
  function getLatestVersion() {
3838
3531
  try {
3839
- return execSync10("npm view thinkwork-cli version", {
3532
+ return execSync8("npm view thinkwork-cli version", {
3840
3533
  encoding: "utf-8",
3841
3534
  timeout: 1e4,
3842
3535
  stdio: ["pipe", "pipe", "pipe"]
@@ -3847,7 +3540,7 @@ function getLatestVersion() {
3847
3540
  }
3848
3541
  function detectInstallMethod() {
3849
3542
  try {
3850
- const which = execSync10("which thinkwork", {
3543
+ const which = execSync8("which thinkwork", {
3851
3544
  encoding: "utf-8",
3852
3545
  timeout: 5e3,
3853
3546
  stdio: ["pipe", "pipe", "pipe"]
@@ -3875,28 +3568,28 @@ function compareVersions(a, b) {
3875
3568
  function registerUpdateCommand(program2) {
3876
3569
  program2.command("update").description("Check for and install CLI updates").option("--check", "Only check for updates, don't install").action(async (opts) => {
3877
3570
  printHeader("update", "", null);
3878
- console.log(` Current version: ${chalk12.bold(VERSION)}`);
3571
+ console.log(` Current version: ${chalk11.bold(VERSION)}`);
3879
3572
  const latest = getLatestVersion();
3880
3573
  if (!latest) {
3881
- console.log(chalk12.yellow(" Could not check npm registry for updates."));
3574
+ console.log(chalk11.yellow(" Could not check npm registry for updates."));
3882
3575
  return;
3883
3576
  }
3884
- console.log(` Latest version: ${chalk12.bold(latest)}`);
3577
+ console.log(` Latest version: ${chalk11.bold(latest)}`);
3885
3578
  console.log("");
3886
3579
  const cmp = compareVersions(VERSION, latest);
3887
3580
  if (cmp >= 0) {
3888
- console.log(chalk12.green(" \u2713 You're on the latest version."));
3581
+ console.log(chalk11.green(" \u2713 You're on the latest version."));
3889
3582
  console.log("");
3890
3583
  return;
3891
3584
  }
3892
- console.log(chalk12.cyan(` Update available: ${VERSION} \u2192 ${latest}`));
3585
+ console.log(chalk11.cyan(` Update available: ${VERSION} \u2192 ${latest}`));
3893
3586
  console.log("");
3894
3587
  if (opts.check) {
3895
3588
  const method2 = detectInstallMethod();
3896
3589
  if (method2 === "homebrew") {
3897
- console.log(` Run: ${chalk12.cyan("brew upgrade thinkwork-ai/tap/thinkwork")}`);
3590
+ console.log(` Run: ${chalk11.cyan("brew upgrade thinkwork-ai/tap/thinkwork")}`);
3898
3591
  } else {
3899
- console.log(` Run: ${chalk12.cyan(`npm install -g thinkwork-cli@${latest}`)}`);
3592
+ console.log(` Run: ${chalk11.cyan(`npm install -g thinkwork-cli@${latest}`)}`);
3900
3593
  }
3901
3594
  console.log("");
3902
3595
  return;
@@ -3904,27 +3597,27 @@ function registerUpdateCommand(program2) {
3904
3597
  const method = detectInstallMethod();
3905
3598
  const cmd = method === "homebrew" ? "brew upgrade thinkwork-ai/tap/thinkwork" : `npm install -g thinkwork-cli@${latest}`;
3906
3599
  console.log(` Installing via ${method}...`);
3907
- console.log(chalk12.dim(` $ ${cmd}`));
3600
+ console.log(chalk11.dim(` $ ${cmd}`));
3908
3601
  console.log("");
3909
3602
  try {
3910
- execSync10(cmd, { stdio: "inherit", timeout: 12e4 });
3603
+ execSync8(cmd, { stdio: "inherit", timeout: 12e4 });
3911
3604
  console.log("");
3912
- console.log(chalk12.green(` \u2713 Upgraded to thinkwork-cli@${latest}`));
3605
+ console.log(chalk11.green(` \u2713 Upgraded to thinkwork-cli@${latest}`));
3913
3606
  } catch {
3914
3607
  console.log("");
3915
- console.log(chalk12.red(` Failed to upgrade. Try manually:`));
3916
- console.log(` ${chalk12.cyan(cmd)}`);
3608
+ console.log(chalk11.red(` Failed to upgrade. Try manually:`));
3609
+ console.log(` ${chalk11.cyan(cmd)}`);
3917
3610
  }
3918
3611
  console.log("");
3919
3612
  });
3920
3613
  }
3921
3614
 
3922
3615
  // src/commands/user.ts
3923
- import { spawn as spawn5 } from "child_process";
3616
+ import { spawn as spawn4 } from "child_process";
3924
3617
  import { input as input2, select as select7 } from "@inquirer/prompts";
3925
3618
  function getTerraformOutput2(cwd, key) {
3926
3619
  return new Promise((resolve7, reject) => {
3927
- const proc = spawn5("terraform", ["output", "-raw", key], {
3620
+ const proc = spawn4("terraform", ["output", "-raw", key], {
3928
3621
  cwd,
3929
3622
  stdio: ["pipe", "pipe", "pipe"]
3930
3623
  });
@@ -3956,7 +3649,7 @@ function runAwsCognitoReset(userPoolId, username, region) {
3956
3649
  "json"
3957
3650
  ];
3958
3651
  if (region) args.push("--region", region);
3959
- const proc = spawn5("aws", args, { stdio: ["ignore", "pipe", "pipe"] });
3652
+ const proc = spawn4("aws", args, { stdio: ["ignore", "pipe", "pipe"] });
3960
3653
  let stdout = "";
3961
3654
  let stderr = "";
3962
3655
  proc.stdout.on("data", (d) => stdout += d);
@@ -4648,6 +4341,8 @@ var CliUpdateScheduledJobDocument = { "kind": "Document", "definitions": [{ "kin
4648
4341
  var CliSchedJobTenantBySlugDocument = { "kind": "Document", "definitions": [{ "kind": "OperationDefinition", "operation": "query", "name": { "kind": "Name", "value": "CliSchedJobTenantBySlug" }, "variableDefinitions": [{ "kind": "VariableDefinition", "variable": { "kind": "Variable", "name": { "kind": "Name", "value": "slug" } }, "type": { "kind": "NonNullType", "type": { "kind": "NamedType", "name": { "kind": "Name", "value": "String" } } } }], "selectionSet": { "kind": "SelectionSet", "selections": [{ "kind": "Field", "name": { "kind": "Name", "value": "tenantBySlug" }, "arguments": [{ "kind": "Argument", "name": { "kind": "Name", "value": "slug" }, "value": { "kind": "Variable", "name": { "kind": "Name", "value": "slug" } } }], "selectionSet": { "kind": "SelectionSet", "selections": [{ "kind": "Field", "name": { "kind": "Name", "value": "id" } }] } }] } }] };
4649
4342
  var CliSkillCatalogDocument = { "kind": "Document", "definitions": [{ "kind": "OperationDefinition", "operation": "query", "name": { "kind": "Name", "value": "CliSkillCatalog" }, "selectionSet": { "kind": "SelectionSet", "selections": [{ "kind": "Field", "name": { "kind": "Name", "value": "skillCatalog" }, "selectionSet": { "kind": "SelectionSet", "selections": [{ "kind": "Field", "name": { "kind": "Name", "value": "id" } }, { "kind": "Field", "name": { "kind": "Name", "value": "skillId" } }, { "kind": "Field", "name": { "kind": "Name", "value": "displayName" } }, { "kind": "Field", "name": { "kind": "Name", "value": "description" } }, { "kind": "Field", "name": { "kind": "Name", "value": "category" } }, { "kind": "Field", "name": { "kind": "Name", "value": "icon" } }, { "kind": "Field", "name": { "kind": "Name", "value": "source" } }, { "kind": "Field", "name": { "kind": "Name", "value": "enabled" } }] } }] } }] };
4650
4343
  var CliSkillTenantBySlugDocument = { "kind": "Document", "definitions": [{ "kind": "OperationDefinition", "operation": "query", "name": { "kind": "Name", "value": "CliSkillTenantBySlug" }, "variableDefinitions": [{ "kind": "VariableDefinition", "variable": { "kind": "Variable", "name": { "kind": "Name", "value": "slug" } }, "type": { "kind": "NonNullType", "type": { "kind": "NamedType", "name": { "kind": "Name", "value": "String" } } } }], "selectionSet": { "kind": "SelectionSet", "selections": [{ "kind": "Field", "name": { "kind": "Name", "value": "tenantBySlug" }, "arguments": [{ "kind": "Argument", "name": { "kind": "Name", "value": "slug" }, "value": { "kind": "Variable", "name": { "kind": "Name", "value": "slug" } } }], "selectionSet": { "kind": "SelectionSet", "selections": [{ "kind": "Field", "name": { "kind": "Name", "value": "id" } }] } }] } }] };
4344
+ var CliInstallSkillDocument = { "kind": "Document", "definitions": [{ "kind": "OperationDefinition", "operation": "mutation", "name": { "kind": "Name", "value": "CliInstallSkill" }, "variableDefinitions": [{ "kind": "VariableDefinition", "variable": { "kind": "Variable", "name": { "kind": "Name", "value": "input" } }, "type": { "kind": "NonNullType", "type": { "kind": "NamedType", "name": { "kind": "Name", "value": "InstallSkillInput" } } } }], "selectionSet": { "kind": "SelectionSet", "selections": [{ "kind": "Field", "name": { "kind": "Name", "value": "installSkill" }, "arguments": [{ "kind": "Argument", "name": { "kind": "Name", "value": "input" }, "value": { "kind": "Variable", "name": { "kind": "Name", "value": "input" } } }], "selectionSet": { "kind": "SelectionSet", "selections": [{ "kind": "Field", "name": { "kind": "Name", "value": "id" } }, { "kind": "Field", "name": { "kind": "Name", "value": "tenantId" } }, { "kind": "Field", "name": { "kind": "Name", "value": "skillId" } }, { "kind": "Field", "name": { "kind": "Name", "value": "source" } }, { "kind": "Field", "name": { "kind": "Name", "value": "version" } }, { "kind": "Field", "name": { "kind": "Name", "value": "catalogVersion" } }, { "kind": "Field", "name": { "kind": "Name", "value": "enabled" } }, { "kind": "Field", "name": { "kind": "Name", "value": "installedAt" } }, { "kind": "Field", "name": { "kind": "Name", "value": "updatedAt" } }] } }] } }] };
4345
+ var CliUninstallSkillDocument = { "kind": "Document", "definitions": [{ "kind": "OperationDefinition", "operation": "mutation", "name": { "kind": "Name", "value": "CliUninstallSkill" }, "variableDefinitions": [{ "kind": "VariableDefinition", "variable": { "kind": "Variable", "name": { "kind": "Name", "value": "tenantId" } }, "type": { "kind": "NonNullType", "type": { "kind": "NamedType", "name": { "kind": "Name", "value": "ID" } } } }, { "kind": "VariableDefinition", "variable": { "kind": "Variable", "name": { "kind": "Name", "value": "skillId" } }, "type": { "kind": "NonNullType", "type": { "kind": "NamedType", "name": { "kind": "Name", "value": "String" } } } }], "selectionSet": { "kind": "SelectionSet", "selections": [{ "kind": "Field", "name": { "kind": "Name", "value": "uninstallSkill" }, "arguments": [{ "kind": "Argument", "name": { "kind": "Name", "value": "tenantId" }, "value": { "kind": "Variable", "name": { "kind": "Name", "value": "tenantId" } } }, { "kind": "Argument", "name": { "kind": "Name", "value": "skillId" }, "value": { "kind": "Variable", "name": { "kind": "Name", "value": "skillId" } } }] }] } }] };
4651
4346
  var CliTeamsDocument = { "kind": "Document", "definitions": [{ "kind": "OperationDefinition", "operation": "query", "name": { "kind": "Name", "value": "CliTeams" }, "variableDefinitions": [{ "kind": "VariableDefinition", "variable": { "kind": "Variable", "name": { "kind": "Name", "value": "tenantId" } }, "type": { "kind": "NonNullType", "type": { "kind": "NamedType", "name": { "kind": "Name", "value": "ID" } } } }], "selectionSet": { "kind": "SelectionSet", "selections": [{ "kind": "Field", "name": { "kind": "Name", "value": "teams" }, "arguments": [{ "kind": "Argument", "name": { "kind": "Name", "value": "tenantId" }, "value": { "kind": "Variable", "name": { "kind": "Name", "value": "tenantId" } } }], "selectionSet": { "kind": "SelectionSet", "selections": [{ "kind": "Field", "name": { "kind": "Name", "value": "id" } }, { "kind": "Field", "name": { "kind": "Name", "value": "name" } }, { "kind": "Field", "name": { "kind": "Name", "value": "slug" } }, { "kind": "Field", "name": { "kind": "Name", "value": "type" } }, { "kind": "Field", "name": { "kind": "Name", "value": "status" } }, { "kind": "Field", "name": { "kind": "Name", "value": "budgetMonthlyCents" } }, { "kind": "Field", "name": { "kind": "Name", "value": "createdAt" } }] } }] } }] };
4652
4347
  var CliTeamDocument = { "kind": "Document", "definitions": [{ "kind": "OperationDefinition", "operation": "query", "name": { "kind": "Name", "value": "CliTeam" }, "variableDefinitions": [{ "kind": "VariableDefinition", "variable": { "kind": "Variable", "name": { "kind": "Name", "value": "id" } }, "type": { "kind": "NonNullType", "type": { "kind": "NamedType", "name": { "kind": "Name", "value": "ID" } } } }], "selectionSet": { "kind": "SelectionSet", "selections": [{ "kind": "Field", "name": { "kind": "Name", "value": "team" }, "arguments": [{ "kind": "Argument", "name": { "kind": "Name", "value": "id" }, "value": { "kind": "Variable", "name": { "kind": "Name", "value": "id" } } }], "selectionSet": { "kind": "SelectionSet", "selections": [{ "kind": "Field", "name": { "kind": "Name", "value": "id" } }, { "kind": "Field", "name": { "kind": "Name", "value": "name" } }, { "kind": "Field", "name": { "kind": "Name", "value": "slug" } }, { "kind": "Field", "name": { "kind": "Name", "value": "description" } }, { "kind": "Field", "name": { "kind": "Name", "value": "type" } }, { "kind": "Field", "name": { "kind": "Name", "value": "status" } }, { "kind": "Field", "name": { "kind": "Name", "value": "budgetMonthlyCents" } }, { "kind": "Field", "name": { "kind": "Name", "value": "createdAt" } }, { "kind": "Field", "name": { "kind": "Name", "value": "updatedAt" } }, { "kind": "Field", "name": { "kind": "Name", "value": "agents" }, "selectionSet": { "kind": "SelectionSet", "selections": [{ "kind": "Field", "name": { "kind": "Name", "value": "id" } }, { "kind": "Field", "name": { "kind": "Name", "value": "agentId" } }, { "kind": "Field", "name": { "kind": "Name", "value": "role" } }, { "kind": "Field", "name": { "kind": "Name", "value": "joinedAt" } }] } }, { "kind": "Field", "name": { "kind": "Name", "value": "users" }, "selectionSet": { "kind": "SelectionSet", "selections": [{ "kind": "Field", "name": { "kind": "Name", "value": "id" } }, { "kind": "Field", "name": { "kind": "Name", "value": "userId" } }, { "kind": "Field", "name": { "kind": "Name", "value": "role" } }, { "kind": "Field", "name": { "kind": "Name", "value": "joinedAt" } }] } }] } }] } }] };
4653
4348
  var CliCreateTeamDocument = { "kind": "Document", "definitions": [{ "kind": "OperationDefinition", "operation": "mutation", "name": { "kind": "Name", "value": "CliCreateTeam" }, "variableDefinitions": [{ "kind": "VariableDefinition", "variable": { "kind": "Variable", "name": { "kind": "Name", "value": "input" } }, "type": { "kind": "NonNullType", "type": { "kind": "NamedType", "name": { "kind": "Name", "value": "CreateTeamInput" } } } }], "selectionSet": { "kind": "SelectionSet", "selections": [{ "kind": "Field", "name": { "kind": "Name", "value": "createTeam" }, "arguments": [{ "kind": "Argument", "name": { "kind": "Name", "value": "input" }, "value": { "kind": "Variable", "name": { "kind": "Name", "value": "input" } } }], "selectionSet": { "kind": "SelectionSet", "selections": [{ "kind": "Field", "name": { "kind": "Name", "value": "id" } }, { "kind": "Field", "name": { "kind": "Name", "value": "name" } }, { "kind": "Field", "name": { "kind": "Name", "value": "type" } }, { "kind": "Field", "name": { "kind": "Name", "value": "status" } }] } }] } }] };
@@ -4704,6 +4399,8 @@ var CliUpdateWebhookDocument = { "kind": "Document", "definitions": [{ "kind": "
4704
4399
  var CliDeleteWebhookDocument = { "kind": "Document", "definitions": [{ "kind": "OperationDefinition", "operation": "mutation", "name": { "kind": "Name", "value": "CliDeleteWebhook" }, "variableDefinitions": [{ "kind": "VariableDefinition", "variable": { "kind": "Variable", "name": { "kind": "Name", "value": "id" } }, "type": { "kind": "NonNullType", "type": { "kind": "NamedType", "name": { "kind": "Name", "value": "ID" } } } }], "selectionSet": { "kind": "SelectionSet", "selections": [{ "kind": "Field", "name": { "kind": "Name", "value": "deleteWebhook" }, "arguments": [{ "kind": "Argument", "name": { "kind": "Name", "value": "id" }, "value": { "kind": "Variable", "name": { "kind": "Name", "value": "id" } } }] }] } }] };
4705
4400
  var CliRegenerateWebhookTokenDocument = { "kind": "Document", "definitions": [{ "kind": "OperationDefinition", "operation": "mutation", "name": { "kind": "Name", "value": "CliRegenerateWebhookToken" }, "variableDefinitions": [{ "kind": "VariableDefinition", "variable": { "kind": "Variable", "name": { "kind": "Name", "value": "id" } }, "type": { "kind": "NonNullType", "type": { "kind": "NamedType", "name": { "kind": "Name", "value": "ID" } } } }], "selectionSet": { "kind": "SelectionSet", "selections": [{ "kind": "Field", "name": { "kind": "Name", "value": "regenerateWebhookToken" }, "arguments": [{ "kind": "Argument", "name": { "kind": "Name", "value": "id" }, "value": { "kind": "Variable", "name": { "kind": "Name", "value": "id" } } }], "selectionSet": { "kind": "SelectionSet", "selections": [{ "kind": "Field", "name": { "kind": "Name", "value": "id" } }, { "kind": "Field", "name": { "kind": "Name", "value": "token" } }] } }] } }] };
4706
4401
  var CliWebhookDeliveriesDocument = { "kind": "Document", "definitions": [{ "kind": "OperationDefinition", "operation": "query", "name": { "kind": "Name", "value": "CliWebhookDeliveries" }, "variableDefinitions": [{ "kind": "VariableDefinition", "variable": { "kind": "Variable", "name": { "kind": "Name", "value": "webhookId" } }, "type": { "kind": "NonNullType", "type": { "kind": "NamedType", "name": { "kind": "Name", "value": "ID" } } } }, { "kind": "VariableDefinition", "variable": { "kind": "Variable", "name": { "kind": "Name", "value": "limit" } }, "type": { "kind": "NamedType", "name": { "kind": "Name", "value": "Int" } } }], "selectionSet": { "kind": "SelectionSet", "selections": [{ "kind": "Field", "name": { "kind": "Name", "value": "webhookDeliveries" }, "arguments": [{ "kind": "Argument", "name": { "kind": "Name", "value": "webhookId" }, "value": { "kind": "Variable", "name": { "kind": "Name", "value": "webhookId" } } }, { "kind": "Argument", "name": { "kind": "Name", "value": "limit" }, "value": { "kind": "Variable", "name": { "kind": "Name", "value": "limit" } } }], "selectionSet": { "kind": "SelectionSet", "selections": [{ "kind": "Field", "name": { "kind": "Name", "value": "id" } }, { "kind": "Field", "name": { "kind": "Name", "value": "providerName" } }, { "kind": "Field", "name": { "kind": "Name", "value": "providerEventId" } }, { "kind": "Field", "name": { "kind": "Name", "value": "normalizedKind" } }, { "kind": "Field", "name": { "kind": "Name", "value": "receivedAt" } }, { "kind": "Field", "name": { "kind": "Name", "value": "signatureStatus" } }, { "kind": "Field", "name": { "kind": "Name", "value": "resolutionStatus" } }, { "kind": "Field", "name": { "kind": "Name", "value": "statusCode" } }, { "kind": "Field", "name": { "kind": "Name", "value": "durationMs" } }, { "kind": "Field", "name": { "kind": "Name", "value": "threadId" } }, { "kind": "Field", "name": { "kind": "Name", "value": "threadCreated" } }, { "kind": "Field", "name": { "kind": "Name", "value": "retryCount" } }, { "kind": "Field", "name": { "kind": "Name", "value": "isReplay" } }, { "kind": "Field", "name": { "kind": "Name", "value": "errorMessage" } }] } }] } }] };
4402
+ var CliTestWebhookDocument = { "kind": "Document", "definitions": [{ "kind": "OperationDefinition", "operation": "mutation", "name": { "kind": "Name", "value": "CliTestWebhook" }, "variableDefinitions": [{ "kind": "VariableDefinition", "variable": { "kind": "Variable", "name": { "kind": "Name", "value": "id" } }, "type": { "kind": "NonNullType", "type": { "kind": "NamedType", "name": { "kind": "Name", "value": "ID" } } } }], "selectionSet": { "kind": "SelectionSet", "selections": [{ "kind": "Field", "name": { "kind": "Name", "value": "testWebhook" }, "arguments": [{ "kind": "Argument", "name": { "kind": "Name", "value": "id" }, "value": { "kind": "Variable", "name": { "kind": "Name", "value": "id" } } }], "selectionSet": { "kind": "SelectionSet", "selections": [{ "kind": "Field", "name": { "kind": "Name", "value": "id" } }, { "kind": "Field", "name": { "kind": "Name", "value": "webhookId" } }, { "kind": "Field", "name": { "kind": "Name", "value": "tenantId" } }, { "kind": "Field", "name": { "kind": "Name", "value": "receivedAt" } }, { "kind": "Field", "name": { "kind": "Name", "value": "resolutionStatus" } }, { "kind": "Field", "name": { "kind": "Name", "value": "signatureStatus" } }, { "kind": "Field", "name": { "kind": "Name", "value": "statusCode" } }, { "kind": "Field", "name": { "kind": "Name", "value": "bodyPreview" } }] } }] } }] };
4403
+ var CliWebhookForTestDocument = { "kind": "Document", "definitions": [{ "kind": "OperationDefinition", "operation": "query", "name": { "kind": "Name", "value": "CliWebhookForTest" }, "variableDefinitions": [{ "kind": "VariableDefinition", "variable": { "kind": "Variable", "name": { "kind": "Name", "value": "id" } }, "type": { "kind": "NonNullType", "type": { "kind": "NamedType", "name": { "kind": "Name", "value": "ID" } } } }], "selectionSet": { "kind": "SelectionSet", "selections": [{ "kind": "Field", "name": { "kind": "Name", "value": "webhook" }, "arguments": [{ "kind": "Argument", "name": { "kind": "Name", "value": "id" }, "value": { "kind": "Variable", "name": { "kind": "Name", "value": "id" } } }], "selectionSet": { "kind": "SelectionSet", "selections": [{ "kind": "Field", "name": { "kind": "Name", "value": "id" } }, { "kind": "Field", "name": { "kind": "Name", "value": "token" } }] } }] } }] };
4707
4404
  var CliWebhookTenantBySlugDocument = { "kind": "Document", "definitions": [{ "kind": "OperationDefinition", "operation": "query", "name": { "kind": "Name", "value": "CliWebhookTenantBySlug" }, "variableDefinitions": [{ "kind": "VariableDefinition", "variable": { "kind": "Variable", "name": { "kind": "Name", "value": "slug" } }, "type": { "kind": "NonNullType", "type": { "kind": "NamedType", "name": { "kind": "Name", "value": "String" } } } }], "selectionSet": { "kind": "SelectionSet", "selections": [{ "kind": "Field", "name": { "kind": "Name", "value": "tenantBySlug" }, "arguments": [{ "kind": "Argument", "name": { "kind": "Name", "value": "slug" }, "value": { "kind": "Variable", "name": { "kind": "Name", "value": "slug" } } }], "selectionSet": { "kind": "SelectionSet", "selections": [{ "kind": "Field", "name": { "kind": "Name", "value": "id" } }] } }] } }] };
4708
4405
  var CliWikiTenantBySlugDocument = { "kind": "Document", "definitions": [{ "kind": "OperationDefinition", "operation": "query", "name": { "kind": "Name", "value": "CliWikiTenantBySlug" }, "variableDefinitions": [{ "kind": "VariableDefinition", "variable": { "kind": "Variable", "name": { "kind": "Name", "value": "slug" } }, "type": { "kind": "NonNullType", "type": { "kind": "NamedType", "name": { "kind": "Name", "value": "String" } } } }], "selectionSet": { "kind": "SelectionSet", "selections": [{ "kind": "Field", "name": { "kind": "Name", "value": "tenantBySlug" }, "arguments": [{ "kind": "Argument", "name": { "kind": "Name", "value": "slug" }, "value": { "kind": "Variable", "name": { "kind": "Name", "value": "slug" } } }], "selectionSet": { "kind": "SelectionSet", "selections": [{ "kind": "Field", "name": { "kind": "Name", "value": "id" } }, { "kind": "Field", "name": { "kind": "Name", "value": "slug" } }, { "kind": "Field", "name": { "kind": "Name", "value": "name" } }] } }] } }] };
4709
4406
  var CliAllTenantAgentsForWikiDocument = { "kind": "Document", "definitions": [{ "kind": "OperationDefinition", "operation": "query", "name": { "kind": "Name", "value": "CliAllTenantAgentsForWiki" }, "variableDefinitions": [{ "kind": "VariableDefinition", "variable": { "kind": "Variable", "name": { "kind": "Name", "value": "tenantId" } }, "type": { "kind": "NonNullType", "type": { "kind": "NamedType", "name": { "kind": "Name", "value": "ID" } } } }], "selectionSet": { "kind": "SelectionSet", "selections": [{ "kind": "Field", "name": { "kind": "Name", "value": "allTenantAgents" }, "arguments": [{ "kind": "Argument", "name": { "kind": "Name", "value": "tenantId" }, "value": { "kind": "Variable", "name": { "kind": "Name", "value": "tenantId" } } }, { "kind": "Argument", "name": { "kind": "Name", "value": "includeSystem" }, "value": { "kind": "BooleanValue", "value": false } }, { "kind": "Argument", "name": { "kind": "Name", "value": "includeSubAgents" }, "value": { "kind": "BooleanValue", "value": false } }], "selectionSet": { "kind": "SelectionSet", "selections": [{ "kind": "Field", "name": { "kind": "Name", "value": "id" } }, { "kind": "Field", "name": { "kind": "Name", "value": "name" } }, { "kind": "Field", "name": { "kind": "Name", "value": "slug" } }, { "kind": "Field", "name": { "kind": "Name", "value": "type" } }, { "kind": "Field", "name": { "kind": "Name", "value": "status" } }] } }] } }] };
@@ -4827,6 +4524,8 @@ var documents = {
4827
4524
  "\n query CliSchedJobTenantBySlug($slug: String!) {\n tenantBySlug(slug: $slug) {\n id\n }\n }\n": CliSchedJobTenantBySlugDocument,
4828
4525
  "\n query CliSkillCatalog {\n skillCatalog {\n id\n skillId\n displayName\n description\n category\n icon\n source\n enabled\n }\n }\n": CliSkillCatalogDocument,
4829
4526
  "\n query CliSkillTenantBySlug($slug: String!) {\n tenantBySlug(slug: $slug) {\n id\n }\n }\n": CliSkillTenantBySlugDocument,
4527
+ "\n mutation CliInstallSkill($input: InstallSkillInput!) {\n installSkill(input: $input) {\n id\n tenantId\n skillId\n source\n version\n catalogVersion\n enabled\n installedAt\n updatedAt\n }\n }\n": CliInstallSkillDocument,
4528
+ "\n mutation CliUninstallSkill($tenantId: ID!, $skillId: String!) {\n uninstallSkill(tenantId: $tenantId, skillId: $skillId)\n }\n": CliUninstallSkillDocument,
4830
4529
  "\n query CliTeams($tenantId: ID!) {\n teams(tenantId: $tenantId) {\n id\n name\n slug\n type\n status\n budgetMonthlyCents\n createdAt\n }\n }\n": CliTeamsDocument,
4831
4530
  "\n query CliTeam($id: ID!) {\n team(id: $id) {\n id\n name\n slug\n description\n type\n status\n budgetMonthlyCents\n createdAt\n updatedAt\n agents {\n id\n agentId\n role\n joinedAt\n }\n users {\n id\n userId\n role\n joinedAt\n }\n }\n }\n": CliTeamDocument,
4832
4531
  "\n mutation CliCreateTeam($input: CreateTeamInput!) {\n createTeam(input: $input) {\n id\n name\n type\n status\n }\n }\n": CliCreateTeamDocument,
@@ -4883,6 +4582,8 @@ var documents = {
4883
4582
  "\n mutation CliDeleteWebhook($id: ID!) {\n deleteWebhook(id: $id)\n }\n": CliDeleteWebhookDocument,
4884
4583
  "\n mutation CliRegenerateWebhookToken($id: ID!) {\n regenerateWebhookToken(id: $id) {\n id\n token\n }\n }\n": CliRegenerateWebhookTokenDocument,
4885
4584
  "\n query CliWebhookDeliveries($webhookId: ID!, $limit: Int) {\n webhookDeliveries(webhookId: $webhookId, limit: $limit) {\n id\n providerName\n providerEventId\n normalizedKind\n receivedAt\n signatureStatus\n resolutionStatus\n statusCode\n durationMs\n threadId\n threadCreated\n retryCount\n isReplay\n errorMessage\n }\n }\n": CliWebhookDeliveriesDocument,
4585
+ "\n mutation CliTestWebhook($id: ID!) {\n testWebhook(id: $id) {\n id\n webhookId\n tenantId\n receivedAt\n resolutionStatus\n signatureStatus\n statusCode\n bodyPreview\n }\n }\n": CliTestWebhookDocument,
4586
+ "\n query CliWebhookForTest($id: ID!) {\n webhook(id: $id) {\n id\n token\n }\n }\n": CliWebhookForTestDocument,
4886
4587
  "\n query CliWebhookTenantBySlug($slug: String!) {\n tenantBySlug(slug: $slug) {\n id\n }\n }\n": CliWebhookTenantBySlugDocument,
4887
4588
  "\n query CliWikiTenantBySlug($slug: String!) {\n tenantBySlug(slug: $slug) {\n id\n slug\n name\n }\n }\n": CliWikiTenantBySlugDocument,
4888
4589
  "\n query CliAllTenantAgentsForWiki($tenantId: ID!) {\n allTenantAgents(tenantId: $tenantId, includeSystem: false, includeSubAgents: false) {\n id\n name\n slug\n type\n status\n }\n }\n": CliAllTenantAgentsForWikiDocument,
@@ -5341,15 +5042,15 @@ async function runThreadCreate(title, opts) {
5341
5042
  // src/commands/thread/update.ts
5342
5043
  async function runThreadUpdate(id, opts) {
5343
5044
  const ctx = await resolveThreadContext(opts);
5344
- const input20 = {};
5345
- if (opts.title !== void 0) input20.title = opts.title;
5346
- if (opts.assignee !== void 0) input20.assigneeId = opts.assignee;
5347
- if (opts.due !== void 0) input20.dueAt = opts.due;
5348
- if (Object.keys(input20).length === 0) {
5045
+ const input21 = {};
5046
+ if (opts.title !== void 0) input21.title = opts.title;
5047
+ if (opts.assignee !== void 0) input21.assigneeId = opts.assignee;
5048
+ if (opts.due !== void 0) input21.dueAt = opts.due;
5049
+ if (Object.keys(input21).length === 0) {
5349
5050
  printError("Nothing to update. Pass at least one of --title, --assignee, --due.");
5350
5051
  process.exit(1);
5351
5052
  }
5352
- const data = await gqlMutate(ctx.client, UpdateThreadDoc, { id, input: input20 });
5053
+ const data = await gqlMutate(ctx.client, UpdateThreadDoc, { id, input: input21 });
5353
5054
  const updated = data.updateThread;
5354
5055
  if (isJsonMode()) {
5355
5056
  printJson(updated);
@@ -5971,15 +5672,15 @@ async function runLabelCreate(name, opts) {
5971
5672
  }
5972
5673
  async function runLabelUpdate(id, opts) {
5973
5674
  const ctx = await resolveLabelContext(opts);
5974
- const input20 = {};
5975
- if (opts.name !== void 0) input20.name = opts.name;
5976
- if (opts.color !== void 0) input20.color = validateColor(opts.color);
5977
- if (opts.description !== void 0) input20.description = opts.description;
5978
- if (Object.keys(input20).length === 0) {
5675
+ const input21 = {};
5676
+ if (opts.name !== void 0) input21.name = opts.name;
5677
+ if (opts.color !== void 0) input21.color = validateColor(opts.color);
5678
+ if (opts.description !== void 0) input21.description = opts.description;
5679
+ if (Object.keys(input21).length === 0) {
5979
5680
  printError("Nothing to update. Pass at least one of --name, --color, --description.");
5980
5681
  process.exit(1);
5981
5682
  }
5982
- const data = await gqlMutate(ctx.client, UpdateThreadLabelDoc, { id, input: input20 });
5683
+ const data = await gqlMutate(ctx.client, UpdateThreadLabelDoc, { id, input: input21 });
5983
5684
  const updated = data.updateThreadLabel;
5984
5685
  if (isJsonMode()) {
5985
5686
  printJson(updated);
@@ -7017,19 +6718,19 @@ async function runAgentUpdate(id, opts) {
7017
6718
  if (!systemPrompt && opts.systemPromptFile) {
7018
6719
  systemPrompt = await readFile4(opts.systemPromptFile, "utf-8");
7019
6720
  }
7020
- const input20 = {};
7021
- if (opts.name !== void 0) input20.name = opts.name;
7022
- if (opts.role !== void 0) input20.role = opts.role;
7023
- if (opts.type !== void 0) input20.type = parseEnum(opts.type, TYPE_BY_NAME, "--type");
7024
- if (opts.parent !== void 0) input20.parentAgentId = opts.parent;
7025
- if (opts.reportsTo !== void 0) input20.reportsTo = opts.reportsTo;
7026
- if (systemPrompt !== void 0) input20.systemPrompt = systemPrompt;
7027
- if (opts.model !== void 0) input20.runtimeConfig = { model: opts.model };
7028
- if (Object.keys(input20).length === 0) {
6721
+ const input21 = {};
6722
+ if (opts.name !== void 0) input21.name = opts.name;
6723
+ if (opts.role !== void 0) input21.role = opts.role;
6724
+ if (opts.type !== void 0) input21.type = parseEnum(opts.type, TYPE_BY_NAME, "--type");
6725
+ if (opts.parent !== void 0) input21.parentAgentId = opts.parent;
6726
+ if (opts.reportsTo !== void 0) input21.reportsTo = opts.reportsTo;
6727
+ if (systemPrompt !== void 0) input21.systemPrompt = systemPrompt;
6728
+ if (opts.model !== void 0) input21.runtimeConfig = { model: opts.model };
6729
+ if (Object.keys(input21).length === 0) {
7029
6730
  printError("Nothing to update. Pass at least one field flag.");
7030
6731
  process.exit(1);
7031
6732
  }
7032
- const data = await gqlMutate(ctx.client, UpdateAgentDoc, { id, input: input20 });
6733
+ const data = await gqlMutate(ctx.client, UpdateAgentDoc, { id, input: input21 });
7033
6734
  if (isJsonMode()) {
7034
6735
  printJson(data.updateAgent);
7035
6736
  return;
@@ -7485,7 +7186,7 @@ Examples:
7485
7186
  }
7486
7187
 
7487
7188
  // src/commands/computer.ts
7488
- import chalk13 from "chalk";
7189
+ import chalk12 from "chalk";
7489
7190
  async function resolveComputerContext(opts) {
7490
7191
  const stage = await resolveStage({ flag: opts.stage });
7491
7192
  const api = resolveApiConfig(stage);
@@ -7525,7 +7226,7 @@ function printMigrationReport(response) {
7525
7226
  if (!response.report) return;
7526
7227
  const summary = response.report.summary ?? {};
7527
7228
  console.log("");
7528
- console.log(chalk13.bold(" Summary"));
7229
+ console.log(chalk12.bold(" Summary"));
7529
7230
  for (const [status, count] of Object.entries(summary)) {
7530
7231
  if (!count) continue;
7531
7232
  console.log(` ${status.padEnd(28)} ${count}`);
@@ -7606,7 +7307,7 @@ function registerComputerCommand(program2) {
7606
7307
  if (response.status === 409 && response.body.blockers) {
7607
7308
  if (!isJsonMode()) {
7608
7309
  console.log("");
7609
- console.log(chalk13.bold(" Blockers"));
7310
+ console.log(chalk12.bold(" Blockers"));
7610
7311
  console.log(JSON.stringify(response.body.blockers, null, 2));
7611
7312
  }
7612
7313
  }
@@ -7663,7 +7364,7 @@ function registerComputerCommand(program2) {
7663
7364
  const tenantId = resolveTenantId(opts);
7664
7365
  const computerId = resolveComputerId(opts);
7665
7366
  const taskType = resolveTaskType(opts);
7666
- const input20 = taskType === "workspace_file_write" ? { path: opts.path, content: opts.content } : void 0;
7367
+ const input21 = taskType === "workspace_file_write" ? { path: opts.path, content: opts.content } : void 0;
7667
7368
  if (!isJsonMode()) printHeader("computer task enqueue", stage);
7668
7369
  const response = await apiFetchRaw(
7669
7370
  api.apiUrl,
@@ -7675,7 +7376,7 @@ function registerComputerCommand(program2) {
7675
7376
  tenantId,
7676
7377
  computerId,
7677
7378
  taskType,
7678
- input: input20,
7379
+ input: input21,
7679
7380
  idempotencyKey: opts.idempotencyKey
7680
7381
  })
7681
7382
  }
@@ -7947,15 +7648,15 @@ async function runTemplateUpdate(id, opts) {
7947
7648
  "--system-prompt-file is not yet wired in the CLI \u2014 edit prompt files via the admin UI."
7948
7649
  );
7949
7650
  }
7950
- const input20 = {};
7951
- if (opts.name !== void 0) input20.name = opts.name;
7952
- if (opts.model !== void 0) input20.model = opts.model;
7953
- if (opts.description !== void 0) input20.description = opts.description;
7954
- if (Object.keys(input20).length === 0) {
7651
+ const input21 = {};
7652
+ if (opts.name !== void 0) input21.name = opts.name;
7653
+ if (opts.model !== void 0) input21.model = opts.model;
7654
+ if (opts.description !== void 0) input21.description = opts.description;
7655
+ if (Object.keys(input21).length === 0) {
7955
7656
  printError("Nothing to update. Pass at least one of --name, --model, --description.");
7956
7657
  process.exit(1);
7957
7658
  }
7958
- const data = await gqlMutate(ctx.client, UpdateAgentTemplateDoc, { id, input: input20 });
7659
+ const data = await gqlMutate(ctx.client, UpdateAgentTemplateDoc, { id, input: input21 });
7959
7660
  if (isJsonMode()) {
7960
7661
  printJson(data.updateAgentTemplate);
7961
7662
  return;
@@ -8277,15 +7978,15 @@ async function runTenantUpdate(id, opts) {
8277
7978
  printMissingApiSessionError(stage, false);
8278
7979
  process.exit(1);
8279
7980
  }
8280
- const input20 = {};
8281
- if (opts.name !== void 0) input20.name = opts.name;
8282
- if (opts.plan !== void 0) input20.plan = opts.plan;
8283
- if (opts.issuePrefix !== void 0) input20.issuePrefix = opts.issuePrefix;
8284
- if (Object.keys(input20).length === 0) {
7981
+ const input21 = {};
7982
+ if (opts.name !== void 0) input21.name = opts.name;
7983
+ if (opts.plan !== void 0) input21.plan = opts.plan;
7984
+ if (opts.issuePrefix !== void 0) input21.issuePrefix = opts.issuePrefix;
7985
+ if (Object.keys(input21).length === 0) {
8285
7986
  printError("Nothing to update. Pass at least one of --name, --plan, --issue-prefix.");
8286
7987
  process.exit(1);
8287
7988
  }
8288
- const data = await gqlMutate(client, UpdateTenantDoc, { id, input: input20 });
7989
+ const data = await gqlMutate(client, UpdateTenantDoc, { id, input: input21 });
8289
7990
  if (isJsonMode()) {
8290
7991
  printJson(data.updateTenant);
8291
7992
  return;
@@ -8323,18 +8024,18 @@ async function runTenantSettingsSet(tenantArg, opts) {
8323
8024
  stage: opts.stage,
8324
8025
  tenant: tenantArg
8325
8026
  });
8326
- const input20 = {};
8327
- if (opts.defaultModel !== void 0) input20.defaultModel = opts.defaultModel;
8027
+ const input21 = {};
8028
+ if (opts.defaultModel !== void 0) input21.defaultModel = opts.defaultModel;
8328
8029
  if (opts.monthlyBudgetUsd !== void 0) {
8329
- input20.budgetMonthlyCents = Math.round(Number.parseFloat(opts.monthlyBudgetUsd) * 100);
8030
+ input21.budgetMonthlyCents = Math.round(Number.parseFloat(opts.monthlyBudgetUsd) * 100);
8330
8031
  }
8331
- if (opts.maxAgents !== void 0) input20.maxAgents = Number.parseInt(opts.maxAgents, 10);
8032
+ if (opts.maxAgents !== void 0) input21.maxAgents = Number.parseInt(opts.maxAgents, 10);
8332
8033
  if (opts.autoCloseAfterDays !== void 0) {
8333
- input20.autoCloseThreadMinutes = Math.round(Number.parseFloat(opts.autoCloseAfterDays) * 60 * 24);
8034
+ input21.autoCloseThreadMinutes = Math.round(Number.parseFloat(opts.autoCloseAfterDays) * 60 * 24);
8334
8035
  }
8335
8036
  const features = parseFeatureFlags(opts.feature);
8336
- if (features !== void 0) input20.features = JSON.stringify(features);
8337
- if (Object.keys(input20).length === 0) {
8037
+ if (features !== void 0) input21.features = JSON.stringify(features);
8038
+ if (Object.keys(input21).length === 0) {
8338
8039
  printError(
8339
8040
  "Nothing to set. Pass at least one of --default-model, --monthly-budget-usd, --max-agents, --auto-close-after-days, --feature."
8340
8041
  );
@@ -8342,7 +8043,7 @@ async function runTenantSettingsSet(tenantArg, opts) {
8342
8043
  }
8343
8044
  const data = await gqlMutate(ctx.client, UpdateTenantSettingsDoc, {
8344
8045
  tenantId: ctx.tenantId,
8345
- input: input20
8046
+ input: input21
8346
8047
  });
8347
8048
  if (isJsonMode()) {
8348
8049
  printJson(data.updateTenantSettings);
@@ -8587,14 +8288,14 @@ async function runMemberInvite(email, opts) {
8587
8288
  }
8588
8289
  async function runMemberUpdate(memberId, opts) {
8589
8290
  const ctx = await resolveMemberContext(opts);
8590
- const input20 = {};
8591
- if (opts.role !== void 0) input20.role = opts.role;
8592
- if (opts.status !== void 0) input20.status = opts.status;
8593
- if (Object.keys(input20).length === 0) {
8291
+ const input21 = {};
8292
+ if (opts.role !== void 0) input21.role = opts.role;
8293
+ if (opts.status !== void 0) input21.status = opts.status;
8294
+ if (Object.keys(input21).length === 0) {
8594
8295
  printError("Nothing to update. Pass at least one of --role, --status.");
8595
8296
  process.exit(1);
8596
8297
  }
8597
- const data = await gqlMutate(ctx.client, UpdateTenantMemberDoc, { id: memberId, input: input20 });
8298
+ const data = await gqlMutate(ctx.client, UpdateTenantMemberDoc, { id: memberId, input: input21 });
8598
8299
  const updated = data.updateTenantMember;
8599
8300
  if (isJsonMode()) {
8600
8301
  printJson(updated);
@@ -8878,18 +8579,18 @@ async function runTeamCreate(name, opts) {
8878
8579
  }
8879
8580
  async function runTeamUpdate(id, opts) {
8880
8581
  const ctx = await resolveTeamContext(opts);
8881
- const input20 = {};
8882
- if (opts.name !== void 0) input20.name = opts.name;
8883
- if (opts.description !== void 0) input20.description = opts.description;
8884
- if (opts.status !== void 0) input20.status = opts.status;
8582
+ const input21 = {};
8583
+ if (opts.name !== void 0) input21.name = opts.name;
8584
+ if (opts.description !== void 0) input21.description = opts.description;
8585
+ if (opts.status !== void 0) input21.status = opts.status;
8885
8586
  if (opts.budgetUsd !== void 0) {
8886
- input20.budgetMonthlyCents = Math.round(Number.parseFloat(opts.budgetUsd) * 100);
8587
+ input21.budgetMonthlyCents = Math.round(Number.parseFloat(opts.budgetUsd) * 100);
8887
8588
  }
8888
- if (Object.keys(input20).length === 0) {
8589
+ if (Object.keys(input21).length === 0) {
8889
8590
  printError("Nothing to update. Pass at least one of --name, --description, --status, --budget-usd.");
8890
8591
  process.exit(1);
8891
8592
  }
8892
- const data = await gqlMutate(ctx.client, UpdateTeamDoc, { id, input: input20 });
8593
+ const data = await gqlMutate(ctx.client, UpdateTeamDoc, { id, input: input21 });
8893
8594
  if (isJsonMode()) {
8894
8595
  printJson(data.updateTeam);
8895
8596
  return;
@@ -9213,14 +8914,14 @@ async function runKbCreate(name, opts) {
9213
8914
  }
9214
8915
  async function runKbUpdate(id, opts) {
9215
8916
  const ctx = await resolveKbContext(opts);
9216
- const input20 = {};
9217
- if (opts.name !== void 0) input20.name = opts.name;
9218
- if (opts.description !== void 0) input20.description = opts.description;
9219
- if (Object.keys(input20).length === 0) {
8917
+ const input21 = {};
8918
+ if (opts.name !== void 0) input21.name = opts.name;
8919
+ if (opts.description !== void 0) input21.description = opts.description;
8920
+ if (Object.keys(input21).length === 0) {
9220
8921
  printError("Nothing to update. Pass at least one of --name, --description.");
9221
8922
  process.exit(1);
9222
8923
  }
9223
- const data = await gqlMutate(ctx.client, UpdateKBDoc, { id, input: input20 });
8924
+ const data = await gqlMutate(ctx.client, UpdateKBDoc, { id, input: input21 });
9224
8925
  if (isJsonMode()) {
9225
8926
  printJson(data.updateKnowledgeBase);
9226
8927
  return;
@@ -9669,12 +9370,12 @@ async function runRoutineCreate(name, opts) {
9669
9370
  }
9670
9371
  async function runRoutineUpdate(id, opts) {
9671
9372
  const ctx = await resolveRoutineContext(opts);
9672
- const input20 = {};
9673
- if (opts.name !== void 0) input20.name = opts.name;
9674
- if (opts.status !== void 0) input20.status = opts.status;
9675
- if (opts.agent !== void 0) input20.agentId = opts.agent;
9676
- if (opts.team !== void 0) input20.teamId = opts.team;
9677
- if (Object.keys(input20).length === 0) {
9373
+ const input21 = {};
9374
+ if (opts.name !== void 0) input21.name = opts.name;
9375
+ if (opts.status !== void 0) input21.status = opts.status;
9376
+ if (opts.agent !== void 0) input21.agentId = opts.agent;
9377
+ if (opts.team !== void 0) input21.teamId = opts.team;
9378
+ if (Object.keys(input21).length === 0) {
9678
9379
  printError("Nothing to update.");
9679
9380
  process.exit(1);
9680
9381
  }
@@ -9684,7 +9385,7 @@ async function runRoutineUpdate(id, opts) {
9684
9385
  );
9685
9386
  process.exit(1);
9686
9387
  }
9687
- const data = await gqlMutate(ctx.client, UpdateRoutineDoc, { id, input: input20 });
9388
+ const data = await gqlMutate(ctx.client, UpdateRoutineDoc, { id, input: input21 });
9688
9389
  if (isJsonMode()) {
9689
9390
  printJson(data.updateRoutine);
9690
9391
  return;
@@ -10164,18 +9865,18 @@ async function runSchedDelete(id, opts) {
10164
9865
  }
10165
9866
  async function runSchedUpdate(id, opts) {
10166
9867
  const ctx = await resolveSchedContext(opts);
10167
- const input20 = {};
10168
- if (opts.name !== void 0) input20.name = opts.name;
10169
- if (opts.description !== void 0) input20.description = opts.description;
10170
- if (opts.prompt !== void 0) input20.prompt = opts.prompt;
9868
+ const input21 = {};
9869
+ if (opts.name !== void 0) input21.name = opts.name;
9870
+ if (opts.description !== void 0) input21.description = opts.description;
9871
+ if (opts.prompt !== void 0) input21.prompt = opts.prompt;
10171
9872
  if (opts.schedule !== void 0) {
10172
- input20.scheduleExpression = opts.schedule;
10173
- input20.scheduleType = opts.schedule.trim().startsWith("cron(") ? "cron" : "rate";
9873
+ input21.scheduleExpression = opts.schedule;
9874
+ input21.scheduleType = opts.schedule.trim().startsWith("cron(") ? "cron" : "rate";
10174
9875
  }
10175
- if (opts.timezone !== void 0) input20.timezone = opts.timezone;
9876
+ if (opts.timezone !== void 0) input21.timezone = opts.timezone;
10176
9877
  if (opts.payload !== void 0) {
10177
9878
  try {
10178
- input20.config = JSON.stringify(JSON.parse(opts.payload));
9879
+ input21.config = JSON.stringify(JSON.parse(opts.payload));
10179
9880
  } catch (err) {
10180
9881
  printError(`--payload is not valid JSON: ${err.message}`);
10181
9882
  process.exit(1);
@@ -10185,9 +9886,9 @@ async function runSchedUpdate(id, opts) {
10185
9886
  printError("--enable and --disable are mutually exclusive.");
10186
9887
  process.exit(1);
10187
9888
  }
10188
- if (opts.enable) input20.enabled = true;
10189
- if (opts.disable) input20.enabled = false;
10190
- if (Object.keys(input20).length === 0) {
9889
+ if (opts.enable) input21.enabled = true;
9890
+ if (opts.disable) input21.enabled = false;
9891
+ if (Object.keys(input21).length === 0) {
10191
9892
  printError(
10192
9893
  "Nothing to update. Pass at least one of --schedule, --timezone, --payload, --enable/--disable, --name, --description, --prompt."
10193
9894
  );
@@ -10195,7 +9896,7 @@ async function runSchedUpdate(id, opts) {
10195
9896
  }
10196
9897
  const data = await gqlMutate(ctx.client, UpdateScheduledJobDoc, {
10197
9898
  id,
10198
- input: input20
9899
+ input: input21
10199
9900
  });
10200
9901
  if (isJsonMode()) {
10201
9902
  printJson(data.updateScheduledJob);
@@ -10734,6 +10435,28 @@ var WebhookDeliveriesDoc = graphql(`
10734
10435
  }
10735
10436
  }
10736
10437
  `);
10438
+ var TestWebhookDoc = graphql(`
10439
+ mutation CliTestWebhook($id: ID!) {
10440
+ testWebhook(id: $id) {
10441
+ id
10442
+ webhookId
10443
+ tenantId
10444
+ receivedAt
10445
+ resolutionStatus
10446
+ signatureStatus
10447
+ statusCode
10448
+ bodyPreview
10449
+ }
10450
+ }
10451
+ `);
10452
+ var WebhookForTestDoc = graphql(`
10453
+ query CliWebhookForTest($id: ID!) {
10454
+ webhook(id: $id) {
10455
+ id
10456
+ token
10457
+ }
10458
+ }
10459
+ `);
10737
10460
  var WebhookTenantBySlugDoc = graphql(`
10738
10461
  query CliWebhookTenantBySlug($slug: String!) {
10739
10462
  tenantBySlug(slug: $slug) {
@@ -10884,25 +10607,25 @@ async function runWebhookCreate(name, opts) {
10884
10607
  }
10885
10608
  async function runWebhookUpdate(id, opts) {
10886
10609
  const ctx = await resolveWebhookContext(opts);
10887
- const input20 = {};
10888
- if (opts.targetType !== void 0) input20.targetType = opts.targetType.toUpperCase();
10610
+ const input21 = {};
10611
+ if (opts.targetType !== void 0) input21.targetType = opts.targetType.toUpperCase();
10889
10612
  if (opts.targetId !== void 0) {
10890
10613
  const tt = (opts.targetType ?? "").toUpperCase();
10891
- if (tt === "AGENT") input20.agentId = opts.targetId;
10892
- else if (tt === "ROUTINE") input20.routineId = opts.targetId;
10614
+ if (tt === "AGENT") input21.agentId = opts.targetId;
10615
+ else if (tt === "ROUTINE") input21.routineId = opts.targetId;
10893
10616
  else {
10894
10617
  printError("--target-id requires --target-type <AGENT|ROUTINE> on the same call.");
10895
10618
  process.exit(1);
10896
10619
  }
10897
10620
  }
10898
- if (opts.rateLimit !== void 0) input20.rateLimit = Number.parseInt(opts.rateLimit, 10);
10899
- if (opts.enable) input20.enabled = true;
10900
- if (opts.disable) input20.enabled = false;
10901
- if (Object.keys(input20).length === 0) {
10621
+ if (opts.rateLimit !== void 0) input21.rateLimit = Number.parseInt(opts.rateLimit, 10);
10622
+ if (opts.enable) input21.enabled = true;
10623
+ if (opts.disable) input21.enabled = false;
10624
+ if (Object.keys(input21).length === 0) {
10902
10625
  printError("Nothing to update.");
10903
10626
  process.exit(1);
10904
10627
  }
10905
- const data = await gqlMutate(ctx.client, UpdateWebhookDoc, { id, input: input20 });
10628
+ const data = await gqlMutate(ctx.client, UpdateWebhookDoc, { id, input: input21 });
10906
10629
  if (isJsonMode()) {
10907
10630
  printJson(data.updateWebhook);
10908
10631
  return;
@@ -11011,12 +10734,39 @@ async function runWebhookDeliveries(id, opts) {
11011
10734
  ]
11012
10735
  );
11013
10736
  }
11014
- function notYetImplementedAtApi(verb) {
11015
- printError(
11016
- `\`webhook ${verb}\` is not yet implemented at the GraphQL API.
11017
- Use admin UI for now; CLI parity is tracked as a Phase-3 follow-up.`
10737
+ async function runWebhookTest(id, _opts) {
10738
+ const ctx = await resolveWebhookContext(_opts);
10739
+ const data = await gqlMutate(ctx.client, TestWebhookDoc, { id });
10740
+ const delivery = data.testWebhook;
10741
+ let curlHint = null;
10742
+ try {
10743
+ const tokenData = await gqlQuery(ctx.client, WebhookForTestDoc, { id });
10744
+ if (tokenData.webhook?.token) {
10745
+ const { resolveApiConfig: resolveApiConfig2 } = await import("./api-client-MC4NOZ4L.js");
10746
+ const api = resolveApiConfig2(ctx.stage);
10747
+ if (api?.apiUrl) {
10748
+ const base = api.apiUrl.replace(/\/$/, "");
10749
+ curlHint = `${base}/webhooks/${tokenData.webhook.token}`;
10750
+ }
10751
+ }
10752
+ } catch {
10753
+ }
10754
+ if (isJsonMode()) {
10755
+ printJson({ delivery, publicUrl: curlHint });
10756
+ return;
10757
+ }
10758
+ printSuccess(
10759
+ `Recorded synthetic delivery ${delivery.id} (resolution=${delivery.resolutionStatus}).`
11018
10760
  );
11019
- process.exit(2);
10761
+ if (curlHint) {
10762
+ console.log("");
10763
+ console.log(" For end-to-end reachability check, curl the public URL:");
10764
+ console.log(
10765
+ ` curl -X POST -H 'content-type: application/json' \\
10766
+ -d '{"hello":"world"}' \\
10767
+ ${curlHint}`
10768
+ );
10769
+ }
11020
10770
  }
11021
10771
  function registerWebhookCommand(program2) {
11022
10772
  const wh = program2.command("webhook").alias("webhooks").description("Manage inbound webhooks that dispatch to agents or routines.");
@@ -11031,16 +10781,21 @@ Examples:
11031
10781
  ).action(runWebhookCreate);
11032
10782
  wh.command("update <id>").description("Update a webhook's target, rate limit, or enabled state.").option("-s, --stage <name>", "Deployment stage").option("-t, --tenant <slug>", "Tenant slug").option("--target-type <t>").option("--target-id <id>").option("--rate-limit <rpm>").option("--allowed-ips <csv>").option("--enable").option("--disable").action(runWebhookUpdate);
11033
10783
  wh.command("delete <id>").description("Delete a webhook (its URL stops working immediately).").option("-s, --stage <name>", "Deployment stage").option("-t, --tenant <slug>", "Tenant slug").option("-y, --yes", "Skip confirmation").action(runWebhookDelete);
11034
- wh.command("test <id>").description("Send a synthetic payload to the webhook. (API surface pending.)").option("-s, --stage <name>", "Deployment stage").option("-t, --tenant <slug>", "Tenant slug").option("--payload <json>").action(() => notYetImplementedAtApi("test"));
10784
+ wh.command("test <id>").description(
10785
+ "Record a synthetic test delivery row for the webhook (visible via `webhook deliveries`). Does NOT trigger downstream dispatch; prints a curl one-liner for end-to-end reachability against the public URL."
10786
+ ).option("-s, --stage <name>", "Deployment stage").option("-t, --tenant <slug>", "Tenant slug").action(runWebhookTest);
11035
10787
  wh.command("rotate <id>").description("Generate a new token for an existing webhook.").option("-s, --stage <name>", "Deployment stage").option("-t, --tenant <slug>", "Tenant slug").option("-y, --yes", "Skip confirmation").action(runWebhookRotate);
11036
10788
  wh.command("deliveries <id>").description(
11037
10789
  "Show recent delivery attempts for a webhook (newest first). Default 25, max 500."
11038
10790
  ).option("-s, --stage <name>", "Deployment stage").option("-t, --tenant <slug>", "Tenant slug").option("--limit <n>", "Max rows (1-500)", "25").action(runWebhookDeliveries);
11039
10791
  }
11040
10792
 
10793
+ // src/commands/skill.ts
10794
+ import { input as input18 } from "@inquirer/prompts";
10795
+
11041
10796
  // src/lib/plugin-zip.ts
11042
10797
  import { createReadStream, promises as fsp, statSync } from "fs";
11043
- import { basename, join as join6, relative, resolve as resolve3, sep } from "path";
10798
+ import { basename, join as join5, relative, resolve as resolve3, sep } from "path";
11044
10799
  import JSZip from "jszip";
11045
10800
  var PluginZipError = class extends Error {
11046
10801
  constructor(message, kind) {
@@ -11067,7 +10822,7 @@ async function buildPluginZip(pluginDir) {
11067
10822
  "missing-directory"
11068
10823
  );
11069
10824
  }
11070
- const manifestPath = join6(root, "plugin.json");
10825
+ const manifestPath = join5(root, "plugin.json");
11071
10826
  let manifestRaw;
11072
10827
  try {
11073
10828
  manifestRaw = await fsp.readFile(manifestPath, "utf8");
@@ -11146,7 +10901,7 @@ async function walkDir(rootDir, currentDir) {
11146
10901
  const out = [];
11147
10902
  const dirents = await fsp.readdir(currentDir, { withFileTypes: true });
11148
10903
  for (const ent of dirents) {
11149
- const abs = join6(currentDir, ent.name);
10904
+ const abs = join5(currentDir, ent.name);
11150
10905
  const rel = relative(rootDir, abs);
11151
10906
  if (ent.name === ".git" || ent.name === ".DS_Store" || ent.name === "node_modules") {
11152
10907
  continue;
@@ -11178,12 +10933,12 @@ function hasParentSegment(relPath) {
11178
10933
  }
11179
10934
 
11180
10935
  // src/lib/plugin-push.ts
11181
- async function pushPluginZip(input20) {
11182
- const base = input20.apiUrl.replace(/\/+$/, "");
10936
+ async function pushPluginZip(input21) {
10937
+ const base = input21.apiUrl.replace(/\/+$/, "");
11183
10938
  const presignRes = await fetch(`${base}/api/plugins/presign`, {
11184
10939
  method: "POST",
11185
- headers: withJson(input20.headers),
11186
- body: JSON.stringify({ fileName: input20.fileName })
10940
+ headers: withJson(input21.headers),
10941
+ body: JSON.stringify({ fileName: input21.fileName })
11187
10942
  });
11188
10943
  if (!presignRes.ok) {
11189
10944
  throw new Error(`presign failed: ${await describeHttpError(presignRes)}`);
@@ -11197,14 +10952,14 @@ async function pushPluginZip(input20) {
11197
10952
  const putRes = await fetch(presign.uploadUrl, {
11198
10953
  method: "PUT",
11199
10954
  headers: { "Content-Type": "application/zip" },
11200
- body: new Uint8Array(input20.zipBuffer)
10955
+ body: new Uint8Array(input21.zipBuffer)
11201
10956
  });
11202
10957
  if (!putRes.ok) {
11203
10958
  throw new Error(`S3 PUT failed: HTTP ${putRes.status}`);
11204
10959
  }
11205
10960
  const installRes = await fetch(`${base}/api/plugins/upload`, {
11206
10961
  method: "POST",
11207
- headers: withJson(input20.headers),
10962
+ headers: withJson(input21.headers),
11208
10963
  body: JSON.stringify({ s3Key: presign.s3Key })
11209
10964
  });
11210
10965
  const installBody = await installRes.json().catch(() => ({}));
@@ -11267,14 +11022,59 @@ var SkillTenantBySlugDoc = graphql(`
11267
11022
  }
11268
11023
  }
11269
11024
  `);
11025
+ var InstallSkillDoc = graphql(`
11026
+ mutation CliInstallSkill($input: InstallSkillInput!) {
11027
+ installSkill(input: $input) {
11028
+ id
11029
+ tenantId
11030
+ skillId
11031
+ source
11032
+ version
11033
+ catalogVersion
11034
+ enabled
11035
+ installedAt
11036
+ updatedAt
11037
+ }
11038
+ }
11039
+ `);
11040
+ var UninstallSkillDoc = graphql(`
11041
+ mutation CliUninstallSkill($tenantId: ID!, $skillId: String!) {
11042
+ uninstallSkill(tenantId: $tenantId, skillId: $skillId)
11043
+ }
11044
+ `);
11270
11045
  async function resolveSkillContext(opts) {
11271
11046
  const region = opts.region ?? "us-east-1";
11272
11047
  const stage = await resolveStage({ flag: opts.stage, region });
11273
11048
  const session = loadStageSession(stage);
11274
- const { client } = await getGqlClient({ stage, region });
11049
+ const { client, tenantSlug: ctxSlug } = await getGqlClient({ stage, region });
11275
11050
  if (!session) {
11276
11051
  }
11277
- return { stage, region, client };
11052
+ return { stage, region, client, session, ctxSlug };
11053
+ }
11054
+ async function resolveTenantIdForSkill(ctx, tenantOpt) {
11055
+ const flagOrEnv = tenantOpt ?? process.env.THINKWORK_TENANT;
11056
+ if (flagOrEnv) {
11057
+ if (ctx.session?.tenantSlug === flagOrEnv && ctx.session.tenantId) {
11058
+ return ctx.session.tenantId;
11059
+ }
11060
+ const data = await gqlQuery(ctx.client, SkillTenantBySlugDoc, {
11061
+ slug: flagOrEnv
11062
+ });
11063
+ if (!data.tenantBySlug) {
11064
+ printError(`Tenant "${flagOrEnv}" not found.`);
11065
+ process.exit(1);
11066
+ }
11067
+ return data.tenantBySlug.id;
11068
+ }
11069
+ if (ctx.session?.tenantId) return ctx.session.tenantId;
11070
+ if (ctx.ctxSlug) {
11071
+ const data = await gqlQuery(ctx.client, SkillTenantBySlugDoc, {
11072
+ slug: ctx.ctxSlug
11073
+ });
11074
+ if (data.tenantBySlug) return data.tenantBySlug.id;
11075
+ }
11076
+ printMissingApiSessionError(ctx.stage, ctx.session !== null);
11077
+ process.exit(1);
11278
11078
  }
11279
11079
  async function runSkillCatalog(opts) {
11280
11080
  const ctx = await resolveSkillContext(opts);
@@ -11339,13 +11139,59 @@ async function runSkillList(opts) {
11339
11139
  ]
11340
11140
  );
11341
11141
  }
11342
- function notYetImplementedAtApi2(verb) {
11142
+ async function runSkillInstall(slug, opts) {
11143
+ const ctx = await resolveSkillContext(opts);
11144
+ const tenantId = await resolveTenantIdForSkill(ctx, opts.tenant);
11145
+ const data = await gqlMutate(ctx.client, InstallSkillDoc, {
11146
+ input: { tenantId, skillId: slug, version: opts.version ?? null }
11147
+ });
11148
+ if (isJsonMode()) {
11149
+ printJson(data.installSkill);
11150
+ return;
11151
+ }
11152
+ printSuccess(
11153
+ `Installed skill ${data.installSkill.skillId} (source=${data.installSkill.source}, version=${data.installSkill.version ?? "\u2014"}).`
11154
+ );
11155
+ }
11156
+ async function runSkillDelete(slug, opts) {
11157
+ const ctx = await resolveSkillContext(opts);
11158
+ const tenantId = await resolveTenantIdForSkill(ctx, opts.tenant);
11159
+ if (!opts.yes) {
11160
+ if (!isInteractive()) {
11161
+ printError(
11162
+ "Refusing to uninstall without --yes in non-interactive mode."
11163
+ );
11164
+ process.exit(1);
11165
+ }
11166
+ requireTty("confirmation");
11167
+ const answer = await promptOrExit(
11168
+ () => input18({
11169
+ message: `Uninstall skill "${slug}" from this tenant? Type "uninstall" to confirm:`
11170
+ })
11171
+ );
11172
+ if (answer.trim() !== "uninstall") {
11173
+ console.log(" Cancelled.");
11174
+ return;
11175
+ }
11176
+ }
11177
+ const data = await gqlMutate(ctx.client, UninstallSkillDoc, {
11178
+ tenantId,
11179
+ skillId: slug
11180
+ });
11181
+ if (isJsonMode()) {
11182
+ printJson({ skillId: slug, uninstalled: data.uninstallSkill });
11183
+ return;
11184
+ }
11185
+ if (data.uninstallSkill) {
11186
+ printSuccess(`Uninstalled skill ${slug} from tenant.`);
11187
+ } else {
11188
+ console.log(` Skill "${slug}" was not installed (no-op).`);
11189
+ }
11190
+ }
11191
+ function retiredVerb(verb, hint) {
11343
11192
  printError(
11344
- `\`skill ${verb}\` is not yet implemented at the GraphQL API.
11345
- The current schema exposes skillCatalog (read), per-computer enableSkill/disableSkill,
11346
- and the REST \`skill push\` upload path. Tenant-scoped install/upgrade/create/update/delete
11347
- is tracked as a Phase-3 follow-up. Use \`thinkwork skill push <folder>\` to upload custom
11348
- plugins; toggle catalog skills per-agent via \`thinkwork agent skills set\` for now.`
11193
+ `\`skill ${verb}\` was retired: ${hint}
11194
+ See \`thinkwork skill --help\` for the supported verbs.`
11349
11195
  );
11350
11196
  process.exit(2);
11351
11197
  }
@@ -11355,11 +11201,27 @@ function registerSkillCommand(program2) {
11355
11201
  );
11356
11202
  skill.command("catalog").description("Browse the skill catalog. Client-side filters --search and --tag are applied locally.").option("-s, --stage <name>", "Deployment stage").option("-t, --tenant <slug>", "Tenant slug").option("--search <q>", "Filter by keyword").option("--tag <t>", "Filter by category").action(runSkillCatalog);
11357
11203
  skill.command("list").alias("ls").description("List skills available to the tenant.").option("-s, --stage <name>", "Deployment stage").option("-t, --tenant <slug>", "Tenant slug").option("--custom-only", "Only show tenant-owned custom skills (source=tenant)").action(runSkillList);
11358
- skill.command("install <slug>").description("Install a public skill. (API surface pending \u2014 toggle per-agent via `agent skills set`.)").option("-s, --stage <name>", "Deployment stage").option("-t, --tenant <slug>", "Tenant slug").option("--version <v>", "Pin to a specific version").action(() => notYetImplementedAtApi2("install"));
11359
- skill.command("upgrade <slug>").description("Upgrade an installed skill. (API surface pending.)").option("-s, --stage <name>", "Deployment stage").option("-t, --tenant <slug>", "Tenant slug").action(() => notYetImplementedAtApi2("upgrade"));
11360
- skill.command("create [slug]").description("Publish a custom tenant-scoped skill. (Use `skill push <folder>` for now.)").option("-s, --stage <name>", "Deployment stage").option("-t, --tenant <slug>", "Tenant slug").option("--name <n>").option("--description <text>").option("--manifest-file <path>", "Path to the MCP server manifest JSON").option("--endpoint <url>", "MCP server HTTP/SSE endpoint").action(() => notYetImplementedAtApi2("create"));
11361
- skill.command("update <slug>").description("Update a custom skill. (API surface pending.)").option("-s, --stage <name>", "Deployment stage").option("-t, --tenant <slug>", "Tenant slug").option("--name <n>").option("--description <text>").option("--manifest-file <path>").option("--endpoint <url>").action(() => notYetImplementedAtApi2("update"));
11362
- skill.command("delete <slug>").description("Delete a custom skill. (API surface pending.)").option("-s, --stage <name>", "Deployment stage").option("-t, --tenant <slug>", "Tenant slug").option("-y, --yes", "Skip confirmation").action(() => notYetImplementedAtApi2("delete"));
11204
+ skill.command("install <slug>").description(
11205
+ "Install a catalog skill into the tenant (upserts tenant_skills). Idempotent \u2014 re-running bumps the version. Per-agent assignment still goes through `agent skills set`."
11206
+ ).option("-s, --stage <name>", "Deployment stage").option("-t, --tenant <slug>", "Tenant slug").option("--version <v>", "Pin to a specific version (defaults to catalog's current)").action(runSkillInstall);
11207
+ skill.command("upgrade <slug>").description(
11208
+ "Upgrade an installed skill to the catalog's current version (or to --version). Same mutation as `install`."
11209
+ ).option("-s, --stage <name>", "Deployment stage").option("-t, --tenant <slug>", "Tenant slug").option("--version <v>", "Pin to a specific version").action(runSkillInstall);
11210
+ skill.command("create [slug]").description("Retired \u2014 use `thinkwork skill push <folder>` to publish a custom skill.").action(
11211
+ () => retiredVerb(
11212
+ "create",
11213
+ "custom-skill authoring is done by uploading a folder via `thinkwork skill push <folder>`."
11214
+ )
11215
+ );
11216
+ skill.command("update <slug>").description("Retired \u2014 re-push the skill folder with `thinkwork skill push <folder>` to update.").action(
11217
+ () => retiredVerb(
11218
+ "update",
11219
+ "updates are done by re-pushing the skill folder via `thinkwork skill push <folder>`."
11220
+ )
11221
+ );
11222
+ skill.command("delete <slug>").description(
11223
+ "Uninstall a skill from the tenant (deletes the tenant_skills row). Confirms unless --yes."
11224
+ ).option("-s, --stage <name>", "Deployment stage").option("-t, --tenant <slug>", "Tenant slug").option("-y, --yes", "Skip confirmation").action(runSkillDelete);
11363
11225
  skill.command("push <folder>").description(
11364
11226
  "Zip a local plugin folder and upload it to the tenant as a pending plugin."
11365
11227
  ).option("-s, --stage <name>", "Deployment stage").option("--region <name>", "AWS region", "us-east-1").addHelpText(
@@ -11723,7 +11585,7 @@ function registerMemoryCommand(program2) {
11723
11585
  }
11724
11586
 
11725
11587
  // src/commands/recipe.ts
11726
- import { confirm as confirm15, input as input18 } from "@inquirer/prompts";
11588
+ import { confirm as confirm15, input as input19 } from "@inquirer/prompts";
11727
11589
  var RecipesDoc = graphql(`
11728
11590
  query CliRecipes($tenantId: ID!, $threadId: ID, $agentId: ID, $limit: Int, $cursor: String) {
11729
11591
  recipes(tenantId: $tenantId, threadId: $threadId, agentId: $agentId, limit: $limit, cursor: $cursor) {
@@ -11879,7 +11741,7 @@ async function runRecipeCreate(name, opts) {
11879
11741
  process.exit(1);
11880
11742
  }
11881
11743
  requireTty("Recipe name");
11882
- title = await promptOrExit(() => input18({ message: "Recipe title:" }));
11744
+ title = await promptOrExit(() => input19({ message: "Recipe title:" }));
11883
11745
  }
11884
11746
  if (!opts.tool) {
11885
11747
  printError("--tool <server/tool> is required.");
@@ -11920,22 +11782,22 @@ async function runRecipeCreate(name, opts) {
11920
11782
  }
11921
11783
  async function runRecipeUpdate(id, opts) {
11922
11784
  const ctx = await resolveRecipeContext(opts);
11923
- const input20 = {};
11924
- if (opts.title !== void 0) input20.title = opts.title;
11925
- if (opts.summary !== void 0) input20.summary = opts.summary;
11785
+ const input21 = {};
11786
+ if (opts.title !== void 0) input21.title = opts.title;
11787
+ if (opts.summary !== void 0) input21.summary = opts.summary;
11926
11788
  if (opts.params !== void 0) {
11927
11789
  try {
11928
- input20.params = JSON.parse(opts.params);
11790
+ input21.params = JSON.parse(opts.params);
11929
11791
  } catch (err) {
11930
11792
  printError(`--params is not valid JSON: ${err.message}`);
11931
11793
  process.exit(1);
11932
11794
  }
11933
11795
  }
11934
- if (Object.keys(input20).length === 0) {
11796
+ if (Object.keys(input21).length === 0) {
11935
11797
  printError("Nothing to update.");
11936
11798
  process.exit(1);
11937
11799
  }
11938
- const data = await gqlMutate(ctx.client, UpdateRecipeDoc, { id, input: input20 });
11800
+ const data = await gqlMutate(ctx.client, UpdateRecipeDoc, { id, input: input21 });
11939
11801
  if (isJsonMode()) {
11940
11802
  printJson(data.updateRecipe);
11941
11803
  return;
@@ -12789,7 +12651,7 @@ Examples:
12789
12651
 
12790
12652
  // src/commands/eval/run.ts
12791
12653
  import { checkbox, confirm as confirm17 } from "@inquirer/prompts";
12792
- import ora2 from "ora";
12654
+ import ora from "ora";
12793
12655
 
12794
12656
  // src/commands/eval/gql.ts
12795
12657
  var EvalRunsDoc = graphql(`
@@ -13174,7 +13036,7 @@ async function runEvalRun(opts) {
13174
13036
  }
13175
13037
  async function pollUntilTerminal(client, runId, intervalSec, timeoutSec) {
13176
13038
  const deadline = Date.now() + timeoutSec * 1e3;
13177
- const spinner = isJsonMode() ? null : ora2({ text: "Waiting for run to complete\u2026" }).start();
13039
+ const spinner = isJsonMode() ? null : ora({ text: "Waiting for run to complete\u2026" }).start();
13178
13040
  try {
13179
13041
  while (Date.now() < deadline) {
13180
13042
  const data = await gqlQuery(client, EvalRunDoc, { id: runId });
@@ -13304,13 +13166,13 @@ async function runEvalGet(runId, opts) {
13304
13166
  }
13305
13167
 
13306
13168
  // src/commands/eval/watch.ts
13307
- import ora3 from "ora";
13169
+ import ora2 from "ora";
13308
13170
  async function runEvalWatch(runId, opts) {
13309
13171
  const ctx = await resolveEvalContext(opts);
13310
13172
  const intervalSec = Number.parseInt(opts.interval ?? "3", 10);
13311
13173
  const timeoutSec = Number.parseInt(opts.timeout ?? "900", 10);
13312
13174
  const deadline = Date.now() + timeoutSec * 1e3;
13313
- const spinner = isJsonMode() ? null : ora3({ text: `Watching run ${runId}\u2026` }).start();
13175
+ const spinner = isJsonMode() ? null : ora2({ text: `Watching run ${runId}\u2026` }).start();
13314
13176
  try {
13315
13177
  while (Date.now() < deadline) {
13316
13178
  const data = await gqlQuery(ctx.client, EvalRunDoc, { id: runId });
@@ -13515,8 +13377,8 @@ async function runEvalTestCaseGet(id, opts) {
13515
13377
  }
13516
13378
 
13517
13379
  // src/commands/eval/test-case/create.ts
13518
- import { readFileSync as readFileSync6 } from "fs";
13519
- import { input as input19, select as select8, checkbox as checkbox2 } from "@inquirer/prompts";
13380
+ import { readFileSync as readFileSync4 } from "fs";
13381
+ import { input as input20, select as select8, checkbox as checkbox2 } from "@inquirer/prompts";
13520
13382
  var DEFAULT_EVALUATORS = [
13521
13383
  "Builtin.Helpfulness",
13522
13384
  "Builtin.Correctness",
@@ -13546,17 +13408,17 @@ async function runEvalTestCaseCreate(opts) {
13546
13408
  if (!name) {
13547
13409
  requireTty("Name");
13548
13410
  name = await promptOrExit(
13549
- () => input19({ message: "Test case name?", validate: (v) => v.trim().length > 0 || "Required" })
13411
+ () => input20({ message: "Test case name?", validate: (v) => v.trim().length > 0 || "Required" })
13550
13412
  );
13551
13413
  }
13552
13414
  if (!category) {
13553
13415
  category = await promptOrExit(
13554
- () => input19({ message: "Category (free-form label)?", validate: (v) => v.trim().length > 0 || "Required" })
13416
+ () => input20({ message: "Category (free-form label)?", validate: (v) => v.trim().length > 0 || "Required" })
13555
13417
  );
13556
13418
  }
13557
13419
  if (!query) {
13558
13420
  query = await promptOrExit(
13559
- () => input19({ message: "Query the agent under test will receive?", validate: (v) => v.trim().length > 0 || "Required" })
13421
+ () => input20({ message: "Query the agent under test will receive?", validate: (v) => v.trim().length > 0 || "Required" })
13560
13422
  );
13561
13423
  }
13562
13424
  if (interactive && agentTemplateId === null) {
@@ -13588,7 +13450,7 @@ async function runEvalTestCaseCreate(opts) {
13588
13450
  }
13589
13451
  let assertions = null;
13590
13452
  if (opts.assertionsFile) {
13591
- const parsed = JSON.parse(readFileSync6(opts.assertionsFile, "utf8"));
13453
+ const parsed = JSON.parse(readFileSync4(opts.assertionsFile, "utf8"));
13592
13454
  if (!Array.isArray(parsed)) {
13593
13455
  printError(`--assertions-file must contain a JSON array.`);
13594
13456
  process.exit(1);
@@ -13619,31 +13481,31 @@ async function runEvalTestCaseCreate(opts) {
13619
13481
  }
13620
13482
 
13621
13483
  // src/commands/eval/test-case/update.ts
13622
- import { readFileSync as readFileSync7 } from "fs";
13484
+ import { readFileSync as readFileSync5 } from "fs";
13623
13485
  async function runEvalTestCaseUpdate(id, opts) {
13624
13486
  const ctx = await resolveEvalContext(opts);
13625
- const input20 = {};
13626
- if (opts.name !== void 0) input20.name = opts.name;
13627
- if (opts.category !== void 0) input20.category = opts.category;
13628
- if (opts.query !== void 0) input20.query = opts.query;
13629
- if (opts.systemPrompt !== void 0) input20.systemPrompt = opts.systemPrompt;
13630
- if (opts.agentTemplate !== void 0) input20.agentTemplateId = opts.agentTemplate;
13631
- if (opts.evaluator !== void 0) input20.agentcoreEvaluatorIds = opts.evaluator;
13632
- if (opts.tag !== void 0) input20.tags = opts.tag;
13633
- if (opts.enabled !== void 0) input20.enabled = opts.enabled;
13487
+ const input21 = {};
13488
+ if (opts.name !== void 0) input21.name = opts.name;
13489
+ if (opts.category !== void 0) input21.category = opts.category;
13490
+ if (opts.query !== void 0) input21.query = opts.query;
13491
+ if (opts.systemPrompt !== void 0) input21.systemPrompt = opts.systemPrompt;
13492
+ if (opts.agentTemplate !== void 0) input21.agentTemplateId = opts.agentTemplate;
13493
+ if (opts.evaluator !== void 0) input21.agentcoreEvaluatorIds = opts.evaluator;
13494
+ if (opts.tag !== void 0) input21.tags = opts.tag;
13495
+ if (opts.enabled !== void 0) input21.enabled = opts.enabled;
13634
13496
  if (opts.assertionsFile) {
13635
- const parsed = JSON.parse(readFileSync7(opts.assertionsFile, "utf8"));
13497
+ const parsed = JSON.parse(readFileSync5(opts.assertionsFile, "utf8"));
13636
13498
  if (!Array.isArray(parsed)) {
13637
13499
  printError(`--assertions-file must contain a JSON array.`);
13638
13500
  process.exit(1);
13639
13501
  }
13640
- input20.assertions = parsed;
13502
+ input21.assertions = parsed;
13641
13503
  }
13642
- if (Object.keys(input20).length === 0) {
13504
+ if (Object.keys(input21).length === 0) {
13643
13505
  printError("No fields to update. Pass at least one --<field>.");
13644
13506
  process.exit(1);
13645
13507
  }
13646
- const res = await gqlMutate(ctx.client, UpdateEvalTestCaseDoc, { id, input: input20 });
13508
+ const res = await gqlMutate(ctx.client, UpdateEvalTestCaseDoc, { id, input: input21 });
13647
13509
  if (isJsonMode()) {
13648
13510
  printJson(res.updateEvalTestCase);
13649
13511
  return;
@@ -13763,7 +13625,7 @@ Examples:
13763
13625
  }
13764
13626
 
13765
13627
  // src/commands/wiki/compile.ts
13766
- import ora4 from "ora";
13628
+ import ora3 from "ora";
13767
13629
 
13768
13630
  // src/commands/wiki/gql.ts
13769
13631
  var TenantBySlugDoc2 = graphql(`
@@ -14033,7 +13895,7 @@ async function runWikiCompile(opts) {
14033
13895
  const errors = [];
14034
13896
  let forbiddenHit = false;
14035
13897
  for (const target of targets) {
14036
- const spinner = isJsonMode() || scope.mode === "all" ? null : ora4({
13898
+ const spinner = isJsonMode() || scope.mode === "all" ? null : ora3({
14037
13899
  text: `Enqueuing compile for ${target.label}\u2026`,
14038
13900
  prefixText: " "
14039
13901
  }).start();
@@ -14131,7 +13993,7 @@ async function runWikiCompile(opts) {
14131
13993
  }
14132
13994
  }
14133
13995
  async function watchSingleJob(ctx, target) {
14134
- const spinner = isJsonMode() ? null : ora4({
13996
+ const spinner = isJsonMode() ? null : ora3({
14135
13997
  text: `Watching job ${shortJobId(target.jobId)} for ${target.agentLabel}\u2026`,
14136
13998
  prefixText: " "
14137
13999
  }).start();
@@ -14180,7 +14042,7 @@ async function watchSingleJob(ctx, target) {
14180
14042
 
14181
14043
  // src/commands/wiki/rebuild.ts
14182
14044
  import { confirm as confirm20 } from "@inquirer/prompts";
14183
- import ora5 from "ora";
14045
+ import ora4 from "ora";
14184
14046
  async function runWikiRebuild(opts) {
14185
14047
  if (opts.all) {
14186
14048
  printError(
@@ -14211,7 +14073,7 @@ async function runWikiRebuild(opts) {
14211
14073
  process.exit(0);
14212
14074
  }
14213
14075
  }
14214
- const resetSpinner = isJsonMode() ? null : ora5({
14076
+ const resetSpinner = isJsonMode() ? null : ora4({
14215
14077
  text: `Archiving active pages for ${agentLabel}\u2026`,
14216
14078
  prefixText: " "
14217
14079
  }).start();
@@ -14248,7 +14110,7 @@ async function runWikiRebuild(opts) {
14248
14110
  }
14249
14111
  process.exit(1);
14250
14112
  }
14251
- const compileSpinner = isJsonMode() ? null : ora5({
14113
+ const compileSpinner = isJsonMode() ? null : ora4({
14252
14114
  text: `Enqueuing fresh compile for ${agentLabel}\u2026`,
14253
14115
  prefixText: " "
14254
14116
  }).start();
@@ -14321,7 +14183,7 @@ async function runWikiRebuild(opts) {
14321
14183
  }
14322
14184
  }
14323
14185
  async function watchRebuildJob(ctx, target) {
14324
- const spinner = isJsonMode() ? null : ora5({
14186
+ const spinner = isJsonMode() ? null : ora4({
14325
14187
  text: `Watching rebuild job ${shortJobId(target.jobId)}\u2026`,
14326
14188
  prefixText: " "
14327
14189
  }).start();
@@ -14357,7 +14219,7 @@ async function watchRebuildJob(ctx, target) {
14357
14219
  }
14358
14220
 
14359
14221
  // src/commands/wiki/status.ts
14360
- import ora6 from "ora";
14222
+ import ora5 from "ora";
14361
14223
  var DEFAULT_WATCH_INTERVAL_MS = 3e3;
14362
14224
  async function runWikiStatus(opts) {
14363
14225
  const ctx = await resolveWikiContext(opts);
@@ -14409,7 +14271,7 @@ async function runWikiStatus(opts) {
14409
14271
  process.exit(0);
14410
14272
  }
14411
14273
  const latestId = jobs[0].id;
14412
- const spinner = isJsonMode() ? null : ora6({
14274
+ const spinner = isJsonMode() ? null : ora5({
14413
14275
  text: `Watching job ${shortJobId(latestId)}\u2026`,
14414
14276
  prefixText: " "
14415
14277
  }).start();
@@ -14626,14 +14488,14 @@ import { resolve as resolve5 } from "path";
14626
14488
 
14627
14489
  // src/commands/enterprise/template.ts
14628
14490
  import {
14629
- existsSync as existsSync10,
14630
- mkdirSync as mkdirSync5,
14631
- readFileSync as readFileSync8,
14632
- readdirSync as readdirSync2,
14491
+ existsSync as existsSync7,
14492
+ mkdirSync as mkdirSync4,
14493
+ readFileSync as readFileSync6,
14494
+ readdirSync,
14633
14495
  statSync as statSync2,
14634
- writeFileSync as writeFileSync5
14496
+ writeFileSync as writeFileSync4
14635
14497
  } from "fs";
14636
- import { dirname as dirname4, join as join7, relative as relative2, resolve as resolve4 } from "path";
14498
+ import { dirname as dirname4, join as join6, relative as relative2, resolve as resolve4 } from "path";
14637
14499
  import { fileURLToPath as fileURLToPath3 } from "url";
14638
14500
  var __dirname2 = dirname4(fileURLToPath3(import.meta.url));
14639
14501
  var MANAGED_MARKER = "thinkwork-managed: enterprise-deploy-template";
@@ -14649,17 +14511,17 @@ function renderEnterpriseDeployRepoTemplate(options) {
14649
14511
  stages
14650
14512
  });
14651
14513
  const templateFiles = listTemplateFiles(templateRoot).filter(
14652
- (path2) => !relative2(templateRoot, path2).startsWith("terraform/stages/") && !/^terraform\/backend-[^.]+\.hcl$/.test(
14653
- relative2(templateRoot, path2).split("\\").join("/")
14514
+ (path) => !relative2(templateRoot, path).startsWith("terraform/stages/") && !/^terraform\/backend-[^.]+\.hcl$/.test(
14515
+ relative2(templateRoot, path).split("\\").join("/")
14654
14516
  )
14655
14517
  );
14656
14518
  const written = [];
14657
14519
  const preserved = [];
14658
14520
  for (const templatePath of templateFiles) {
14659
14521
  const relativePath = relative2(templateRoot, templatePath);
14660
- const outputPath = join7(targetDir, relativePath);
14522
+ const outputPath = join6(targetDir, relativePath);
14661
14523
  let content = applyTemplate(
14662
- readFileSync8(templatePath, "utf8"),
14524
+ readFileSync6(templatePath, "utf8"),
14663
14525
  replacements
14664
14526
  );
14665
14527
  if (relativePath.split("\\").join("/") === "customer/deployment.json") {
@@ -14667,30 +14529,30 @@ function renderEnterpriseDeployRepoTemplate(options) {
14667
14529
  }
14668
14530
  writeManagedFile(outputPath, content, written, preserved);
14669
14531
  }
14670
- const stageTemplateRoot = join7(templateRoot, "terraform", "stages");
14671
- const backendTemplatePath = join7(
14532
+ const stageTemplateRoot = join6(templateRoot, "terraform", "stages");
14533
+ const backendTemplatePath = join6(
14672
14534
  templateRoot,
14673
14535
  "terraform",
14674
14536
  "backend-dev.hcl"
14675
14537
  );
14676
14538
  for (const stage of stages) {
14677
- const explicitTemplate = join7(stageTemplateRoot, `${stage}.tfvars`);
14678
- const fallbackTemplate = join7(stageTemplateRoot, "dev.tfvars");
14679
- const templatePath = existsSync10(explicitTemplate) ? explicitTemplate : fallbackTemplate;
14680
- const outputPath = join7(
14539
+ const explicitTemplate = join6(stageTemplateRoot, `${stage}.tfvars`);
14540
+ const fallbackTemplate = join6(stageTemplateRoot, "dev.tfvars");
14541
+ const templatePath = existsSync7(explicitTemplate) ? explicitTemplate : fallbackTemplate;
14542
+ const outputPath = join6(
14681
14543
  targetDir,
14682
14544
  "terraform",
14683
14545
  "stages",
14684
14546
  `${stage}.tfvars`
14685
14547
  );
14686
- const content = applyTemplate(readFileSync8(templatePath, "utf8"), {
14548
+ const content = applyTemplate(readFileSync6(templatePath, "utf8"), {
14687
14549
  ...replacements,
14688
14550
  STAGE: stage
14689
14551
  });
14690
14552
  writeManagedFile(outputPath, content, written, preserved);
14691
- const backendPath = join7(targetDir, "terraform", `backend-${stage}.hcl`);
14553
+ const backendPath = join6(targetDir, "terraform", `backend-${stage}.hcl`);
14692
14554
  const backendContent = applyTemplate(
14693
- readFileSync8(backendTemplatePath, "utf8"),
14555
+ readFileSync6(backendTemplatePath, "utf8"),
14694
14556
  {
14695
14557
  ...replacements,
14696
14558
  STAGE: stage
@@ -14730,7 +14592,7 @@ function findEnterpriseTemplateRoot() {
14730
14592
  resolve4(__dirname2, "commands/enterprise/templates/deploy-repo")
14731
14593
  ];
14732
14594
  for (const candidate of candidates) {
14733
- if (existsSync10(join7(candidate, "thinkwork.lock"))) return candidate;
14595
+ if (existsSync7(join6(candidate, "thinkwork.lock"))) return candidate;
14734
14596
  }
14735
14597
  throw new Error(
14736
14598
  "Enterprise deployment repo template not found. The CLI package may be incomplete."
@@ -14771,13 +14633,13 @@ function renderCustomerDeploymentJson(content, customerSlug, stages) {
14771
14633
  }
14772
14634
  function listTemplateFiles(root) {
14773
14635
  const out = [];
14774
- for (const entry of readdirSync2(root)) {
14775
- const path2 = join7(root, entry);
14776
- const stat = statSync2(path2);
14636
+ for (const entry of readdirSync(root)) {
14637
+ const path = join6(root, entry);
14638
+ const stat = statSync2(path);
14777
14639
  if (stat.isDirectory()) {
14778
- out.push(...listTemplateFiles(path2));
14640
+ out.push(...listTemplateFiles(path));
14779
14641
  } else if (stat.isFile()) {
14780
- out.push(path2);
14642
+ out.push(path);
14781
14643
  }
14782
14644
  }
14783
14645
  return out.sort();
@@ -14790,24 +14652,24 @@ function applyTemplate(source, replacements) {
14790
14652
  return replacements[key];
14791
14653
  });
14792
14654
  }
14793
- function writeManagedFile(path2, content, written, preserved) {
14794
- mkdirSync5(dirname4(path2), { recursive: true });
14795
- if (existsSync10(path2)) {
14796
- const current = readFileSync8(path2, "utf8");
14655
+ function writeManagedFile(path, content, written, preserved) {
14656
+ mkdirSync4(dirname4(path), { recursive: true });
14657
+ if (existsSync7(path)) {
14658
+ const current = readFileSync6(path, "utf8");
14797
14659
  if (!current.includes(MANAGED_MARKER)) {
14798
- preserved.push(path2);
14660
+ preserved.push(path);
14799
14661
  return;
14800
14662
  }
14801
14663
  }
14802
- writeFileSync5(path2, content);
14803
- written.push(path2);
14664
+ writeFileSync4(path, content);
14665
+ written.push(path);
14804
14666
  }
14805
14667
 
14806
14668
  // src/commands/enterprise/aws-bootstrap.ts
14807
14669
  import { execFileSync } from "child_process";
14808
- import { mkdtempSync, writeFileSync as writeFileSync6 } from "fs";
14670
+ import { mkdtempSync, writeFileSync as writeFileSync5 } from "fs";
14809
14671
  import { tmpdir } from "os";
14810
- import { join as join8 } from "path";
14672
+ import { join as join7 } from "path";
14811
14673
  function buildEnterpriseAwsBootstrapPlan(config) {
14812
14674
  const oidcProviderArn = `arn:aws:iam::${config.accountId}:oidc-provider/token.actions.githubusercontent.com`;
14813
14675
  return {
@@ -15026,9 +14888,9 @@ var AwsCliEnterpriseBootstrapClient = class {
15026
14888
  message: `Deploy role ${role.roleName} already exists; updated inline deploy policy ${role.deployPolicyName}.`
15027
14889
  };
15028
14890
  }
15029
- const dir = mkdtempSync(join8(tmpdir(), "thinkwork-enterprise-role-"));
15030
- const trustPath = join8(dir, "trust.json");
15031
- writeFileSync6(trustPath, JSON.stringify(role.trustPolicy));
14891
+ const dir = mkdtempSync(join7(tmpdir(), "thinkwork-enterprise-role-"));
14892
+ const trustPath = join7(dir, "trust.json");
14893
+ writeFileSync5(trustPath, JSON.stringify(role.trustPolicy));
15032
14894
  execFileSync("aws", [
15033
14895
  "iam",
15034
14896
  "create-role",
@@ -15046,9 +14908,9 @@ var AwsCliEnterpriseBootstrapClient = class {
15046
14908
  }
15047
14909
  };
15048
14910
  function putRolePolicy(role) {
15049
- const dir = mkdtempSync(join8(tmpdir(), "thinkwork-enterprise-policy-"));
15050
- const policyPath = join8(dir, "policy.json");
15051
- writeFileSync6(policyPath, JSON.stringify(role.deployPolicy));
14911
+ const dir = mkdtempSync(join7(tmpdir(), "thinkwork-enterprise-policy-"));
14912
+ const policyPath = join7(dir, "policy.json");
14913
+ writeFileSync5(policyPath, JSON.stringify(role.deployPolicy));
15052
14914
  execFileSync("aws", [
15053
14915
  "iam",
15054
14916
  "put-role-policy",
@@ -15104,12 +14966,12 @@ function awsOk(args) {
15104
14966
 
15105
14967
  // src/commands/enterprise/github.ts
15106
14968
  import { execFileSync as execFileSync2 } from "child_process";
15107
- function parseGitHubRepository(input20) {
15108
- const trimmed = input20.trim();
14969
+ function parseGitHubRepository(input21) {
14970
+ const trimmed = input21.trim();
15109
14971
  const match = /^([A-Za-z0-9_.-]+)\/([A-Za-z0-9_.-]+)$/.exec(trimmed);
15110
14972
  if (!match) {
15111
14973
  throw new Error(
15112
- `Invalid GitHub repository "${input20}". Use owner/name, for example acme/thinkwork-deploy.`
14974
+ `Invalid GitHub repository "${input21}". Use owner/name, for example acme/thinkwork-deploy.`
15113
14975
  );
15114
14976
  }
15115
14977
  return {
@@ -15474,16 +15336,16 @@ async function resolveCustomerSlug(flag) {
15474
15336
  if (!process.stdin.isTTY) {
15475
15337
  throw new Error("Customer slug is required. Pass --customer <slug>.");
15476
15338
  }
15477
- const { input: input20 } = await import("@inquirer/prompts");
15478
- return input20({ message: "Customer slug:" });
15339
+ const { input: input21 } = await import("@inquirer/prompts");
15340
+ return input21({ message: "Customer slug:" });
15479
15341
  }
15480
15342
  async function resolveRepository(flag) {
15481
15343
  if (flag) return flag;
15482
15344
  if (!process.stdin.isTTY) {
15483
15345
  throw new Error("GitHub repository is required. Pass --repo <owner/name>.");
15484
15346
  }
15485
- const { input: input20 } = await import("@inquirer/prompts");
15486
- return input20({ message: "GitHub deployment repo (owner/name):" });
15347
+ const { input: input21 } = await import("@inquirer/prompts");
15348
+ return input21({ message: "GitHub deployment repo (owner/name):" });
15487
15349
  }
15488
15350
  function printBootstrapSummary(result) {
15489
15351
  console.log("");
@@ -15506,14 +15368,14 @@ function printBootstrapSummary(result) {
15506
15368
  import { resolve as resolve6 } from "path";
15507
15369
 
15508
15370
  // src/commands/enterprise/overlay-schema.ts
15509
- import { existsSync as existsSync11, readdirSync as readdirSync3, readFileSync as readFileSync9, statSync as statSync3 } from "fs";
15510
- import { join as join9, relative as relative3, sep as sep2 } from "path";
15371
+ import { existsSync as existsSync8, readdirSync as readdirSync2, readFileSync as readFileSync7, statSync as statSync3 } from "fs";
15372
+ import { join as join8, relative as relative3, sep as sep2 } from "path";
15511
15373
  function loadEnterpriseOverlayDefinition(repoRoot) {
15512
- const path2 = join9(repoRoot, "customer", "deployment.json");
15513
- if (!existsSync11(path2)) {
15514
- throw new Error(`Missing customer overlay definition: ${path2}`);
15374
+ const path = join8(repoRoot, "customer", "deployment.json");
15375
+ if (!existsSync8(path)) {
15376
+ throw new Error(`Missing customer overlay definition: ${path}`);
15515
15377
  }
15516
- const parsed = JSON.parse(readFileSync9(path2, "utf8"));
15378
+ const parsed = JSON.parse(readFileSync7(path, "utf8"));
15517
15379
  if (parsed.schemaVersion !== 1) {
15518
15380
  throw new Error(
15519
15381
  `Unsupported customer/deployment.json schemaVersion ${parsed.schemaVersion}`
@@ -15545,11 +15407,11 @@ function stageOverlay(definition, stage) {
15545
15407
  }
15546
15408
  function readCustomerEvalPack(repoRoot, packName) {
15547
15409
  assertPackName(packName, "eval");
15548
- const path2 = join9(repoRoot, "customer", "evals", `${packName}.json`);
15549
- if (!existsSync11(path2)) {
15550
- throw new Error(`Eval pack "${packName}" is missing: ${path2}`);
15410
+ const path = join8(repoRoot, "customer", "evals", `${packName}.json`);
15411
+ if (!existsSync8(path)) {
15412
+ throw new Error(`Eval pack "${packName}" is missing: ${path}`);
15551
15413
  }
15552
- const parsed = JSON.parse(readFileSync9(path2, "utf8"));
15414
+ const parsed = JSON.parse(readFileSync7(path, "utf8"));
15553
15415
  if (!Array.isArray(parsed)) {
15554
15416
  throw new Error(`Eval pack "${packName}" must be a JSON array`);
15555
15417
  }
@@ -15559,27 +15421,27 @@ function readCustomerEvalPack(repoRoot, packName) {
15559
15421
  }
15560
15422
  function readJsonSeedPack(repoRoot, packName) {
15561
15423
  assertPackName(packName, "seed");
15562
- const path2 = join9(repoRoot, "customer", "seeds", `${packName}.json`);
15563
- if (!existsSync11(path2)) {
15564
- throw new Error(`Seed pack "${packName}" is missing: ${path2}`);
15424
+ const path = join8(repoRoot, "customer", "seeds", `${packName}.json`);
15425
+ if (!existsSync8(path)) {
15426
+ throw new Error(`Seed pack "${packName}" is missing: ${path}`);
15565
15427
  }
15566
- return JSON.parse(readFileSync9(path2, "utf8"));
15428
+ return JSON.parse(readFileSync7(path, "utf8"));
15567
15429
  }
15568
15430
  function collectOverlayFiles(repoRoot, family, packName) {
15569
15431
  assertPackName(packName, family);
15570
- const root = join9(repoRoot, "customer", family, packName);
15571
- if (!existsSync11(root) || !statSync3(root).isDirectory()) {
15432
+ const root = join8(repoRoot, "customer", family, packName);
15433
+ if (!existsSync8(root) || !statSync3(root).isDirectory()) {
15572
15434
  throw new Error(`Overlay pack "${family}/${packName}" is missing: ${root}`);
15573
15435
  }
15574
15436
  const files = [];
15575
- walkFiles(root, (path2) => {
15576
- const relativePath = relative3(root, path2).split(sep2).join("/");
15437
+ walkFiles(root, (path) => {
15438
+ const relativePath = relative3(root, path).split(sep2).join("/");
15577
15439
  if (relativePath === ".DS_Store" || relativePath.endsWith("/.DS_Store")) {
15578
15440
  return;
15579
15441
  }
15580
15442
  files.push({
15581
15443
  relativePath,
15582
- content: readFileSync9(path2, "utf8")
15444
+ content: readFileSync7(path, "utf8")
15583
15445
  });
15584
15446
  });
15585
15447
  if (family === "skills" && !files.some((file) => file.relativePath === "SKILL.md")) {
@@ -15680,12 +15542,12 @@ function assertPackName(value, label) {
15680
15542
  }
15681
15543
  }
15682
15544
  function walkFiles(root, visit) {
15683
- for (const entry of readdirSync3(root, { withFileTypes: true })) {
15684
- const path2 = join9(root, entry.name);
15545
+ for (const entry of readdirSync2(root, { withFileTypes: true })) {
15546
+ const path = join8(root, entry.name);
15685
15547
  if (entry.isDirectory()) {
15686
- walkFiles(path2, visit);
15548
+ walkFiles(path, visit);
15687
15549
  } else if (entry.isFile()) {
15688
- visit(path2);
15550
+ visit(path);
15689
15551
  }
15690
15552
  }
15691
15553
  }
@@ -15737,7 +15599,7 @@ async function applyEnterpriseOverlay(plan, client) {
15737
15599
  skipped: 0
15738
15600
  };
15739
15601
  for (const testCase of operation.testCases) {
15740
- const input20 = withOverlayTags(
15602
+ const input21 = withOverlayTags(
15741
15603
  operation.pack,
15742
15604
  testCase,
15743
15605
  client.targetAgentTemplateId
@@ -15746,16 +15608,16 @@ async function applyEnterpriseOverlay(plan, client) {
15746
15608
  overlayKeyTag(operation.pack, testCase)
15747
15609
  );
15748
15610
  if (existingCase) {
15749
- if (sameEval(existingCase, input20)) {
15611
+ if (sameEval(existingCase, input21)) {
15750
15612
  result.evals.skipped++;
15751
15613
  packResult.skipped++;
15752
15614
  } else {
15753
- await client.updateEvalTestCase(existingCase.id, input20);
15615
+ await client.updateEvalTestCase(existingCase.id, input21);
15754
15616
  result.evals.updated++;
15755
15617
  packResult.updated++;
15756
15618
  }
15757
15619
  } else {
15758
- await client.createEvalTestCase(input20);
15620
+ await client.createEvalTestCase(input21);
15759
15621
  result.evals.inserted++;
15760
15622
  packResult.inserted++;
15761
15623
  }
@@ -15925,19 +15787,19 @@ async function createOverlayApiClient(plan, opts) {
15925
15787
  });
15926
15788
  return data.evalTestCases;
15927
15789
  },
15928
- async createEvalTestCase(input20) {
15790
+ async createEvalTestCase(input21) {
15929
15791
  await gqlMutate(ctx.client, CreateEvalTestCaseDoc, {
15930
15792
  tenantId: ctx.tenantId,
15931
- input: evalInput(input20)
15793
+ input: evalInput(input21)
15932
15794
  });
15933
15795
  },
15934
- async updateEvalTestCase(id, input20) {
15796
+ async updateEvalTestCase(id, input21) {
15935
15797
  await gqlMutate(ctx.client, UpdateEvalTestCaseDoc, {
15936
15798
  id,
15937
- input: evalInput(input20)
15799
+ input: evalInput(input21)
15938
15800
  });
15939
15801
  },
15940
- async putWorkspaceFile(input20) {
15802
+ async putWorkspaceFile(input21) {
15941
15803
  const response = await fetch(
15942
15804
  `${apiUrl.replace(/\/+$/, "")}/api/workspaces/files`,
15943
15805
  {
@@ -15950,15 +15812,15 @@ async function createOverlayApiClient(plan, opts) {
15950
15812
  body: JSON.stringify({
15951
15813
  action: "put",
15952
15814
  templateId,
15953
- path: input20.path,
15954
- content: input20.content
15815
+ path: input21.path,
15816
+ content: input21.content
15955
15817
  })
15956
15818
  }
15957
15819
  );
15958
15820
  if (!response.ok) {
15959
15821
  const text = await response.text();
15960
15822
  throw new Error(
15961
- `PUT ${input20.path} failed: ${response.status} ${text || response.statusText}`
15823
+ `PUT ${input21.path} failed: ${response.status} ${text || response.statusText}`
15962
15824
  );
15963
15825
  }
15964
15826
  }
@@ -15976,17 +15838,17 @@ async function resolveTemplateId(client, tenantId, templateSlug) {
15976
15838
  }
15977
15839
  return template.id;
15978
15840
  }
15979
- function evalInput(input20) {
15841
+ function evalInput(input21) {
15980
15842
  return {
15981
- name: input20.name,
15982
- category: input20.category,
15983
- query: input20.query,
15984
- systemPrompt: input20.systemPrompt ?? null,
15985
- agentTemplateId: input20.agentTemplateId ?? null,
15986
- assertions: input20.assertions,
15987
- agentcoreEvaluatorIds: input20.agentcoreEvaluatorIds ?? [],
15988
- tags: input20.tags ?? [],
15989
- enabled: input20.enabled ?? true
15843
+ name: input21.name,
15844
+ category: input21.category,
15845
+ query: input21.query,
15846
+ systemPrompt: input21.systemPrompt ?? null,
15847
+ agentTemplateId: input21.agentTemplateId ?? null,
15848
+ assertions: input21.assertions,
15849
+ agentcoreEvaluatorIds: input21.agentcoreEvaluatorIds ?? [],
15850
+ tags: input21.tags ?? [],
15851
+ enabled: input21.enabled ?? true
15990
15852
  };
15991
15853
  }
15992
15854
  function publicPlan(plan) {