@clawops/cli 2.2.1 → 2.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/README.md +63 -4
  2. package/dist/{apply-F5SQ2ZOS.js → apply-TXPUNOGW.js} +9 -9
  3. package/dist/{automation-NBYQ6MFZ.js → automation-VDKLZMJI.js} +1 -1
  4. package/dist/{backup-flows-NDP5JTR3.js → backup-flows-THPX2D7S.js} +1 -1
  5. package/dist/{bootstrap-32TZXVDF.js → bootstrap-L3P5E4D7.js} +2 -2
  6. package/dist/{chunk-PASAVVNS.js → chunk-47CGHUVT.js} +1 -1
  7. package/dist/{chunk-E6BRQK67.js → chunk-4SEFKZRL.js} +1 -1
  8. package/dist/{chunk-PCSX6Y3U.js → chunk-66CUJFXK.js} +2 -2
  9. package/dist/{chunk-AX65JMDZ.js → chunk-7LLVIQ7G.js} +12 -9
  10. package/dist/{chunk-55UMO37O.js → chunk-CHPMOE4T.js} +1 -1
  11. package/dist/{chunk-LV7UO5CG.js → chunk-G2ROJXYJ.js} +2 -2
  12. package/dist/{chunk-GFIR2IIJ.js → chunk-GYMAC4MW.js} +47 -28
  13. package/dist/{chunk-T6OCPTTR.js → chunk-LIAXA43Z.js} +14 -8
  14. package/dist/{chunk-Y3N63PDS.js → chunk-ORBZGTNX.js} +93 -60
  15. package/dist/{chunk-OUQVKIIA.js → chunk-PNRFFYOA.js} +14 -14
  16. package/dist/{chunk-755X5OGS.js → chunk-Q56AM57B.js} +4 -1
  17. package/dist/{chunk-4MHDW2NB.js → chunk-QRF4OWG4.js} +1 -1
  18. package/dist/{chunk-AVERNLUY.js → chunk-SQPHNVCF.js} +6 -6
  19. package/dist/{chunk-RDUKRIRC.js → chunk-U3NRKBDW.js} +1 -1
  20. package/dist/cli.js +111 -72
  21. package/dist/{context-EHSLWKSH.js → context-4KTM4DKH.js} +5 -5
  22. package/dist/{flows-6B2I6TRW.js → flows-6YEJGHCK.js} +7 -7
  23. package/dist/{generate-4JWTMOLQ.js → generate-XJWEQKT6.js} +9 -7
  24. package/dist/{harden-UHAOVQMZ.js → harden-7O553IOK.js} +5 -5
  25. package/dist/{init-HOPXDNWY.js → init-DYOLZX65.js} +2 -2
  26. package/dist/{mcp-wire-7MGEAMZH.js → mcp-wire-NAKI2WME.js} +21 -21
  27. package/dist/{migrate-flow-24XA4GZL.js → migrate-flow-4XQUUFMH.js} +2 -2
  28. package/dist/{package-ESYPCIES.js → package-HRMX7K3C.js} +1 -1
  29. package/dist/policy-AZGFCQNV.js +42 -0
  30. package/dist/{remote-config-OZYBMBSK.js → remote-config-V2WXIXIF.js} +1 -1
  31. package/dist/{server-Y2EDRUDL.js → server-FR5LUAOI.js} +21 -21
  32. package/dist/setup-policy-HTO2KSZR.js +90 -0
  33. package/dist/{stack-config-ICQ5YHUL.js → stack-config-3E7KWFPI.js} +2 -2
  34. package/dist/{stack-delete-NTIGKWUF.js → stack-delete-SNPMLWMD.js} +2 -2
  35. package/dist/{state-AKZP2S4T.js → state-KG6K5QZC.js} +2 -2
  36. package/dist/{store-YOLQYXMB.js → store-BTQOOIJH.js} +1 -1
  37. package/dist/{tailscale-cutover-V42HO5UM.js → tailscale-cutover-XTMGDM5H.js} +2 -2
  38. package/dist/{validate-DZE6LFEB.js → validate-CRXX7OYF.js} +1 -1
  39. package/package.json +1 -1
  40. package/spec/errors.yaml +5 -3
  41. package/spec/mcp-tools.yaml +4 -3
  42. package/dist/{chunk-UAJJEDCJ.js → chunk-AGSNTIYZ.js} +0 -0
  43. package/dist/{chunk-YPVWF7IA.js → chunk-HSGKK3RF.js} +3 -3
  44. package/dist/{ready-IJEUBFVX.js → ready-4H3NNEYQ.js} +3 -3
@@ -1,9 +1,13 @@
1
1
  #!/usr/bin/env node
2
+ import {
3
+ DEFAULT_AGENT_LOG_LIMIT,
4
+ readAgentActivity
5
+ } from "./chunk-27335SIH.js";
2
6
  import {
3
7
  migrationQuestion,
4
8
  prepareMigration,
5
9
  runMigration
6
- } from "./chunk-E6BRQK67.js";
10
+ } from "./chunk-4SEFKZRL.js";
7
11
  import {
8
12
  ACTIVATED,
9
13
  ARCHIVE_IS_A_CREDENTIAL,
@@ -15,43 +19,39 @@ import {
15
19
  defaultBackupFilename,
16
20
  nothingChanged,
17
21
  stageRestore
18
- } from "./chunk-PCSX6Y3U.js";
22
+ } from "./chunk-66CUJFXK.js";
19
23
  import {
20
24
  checkStackDelete,
21
25
  deleteStackFromConfig,
22
26
  forgetNotice
23
- } from "./chunk-LV7UO5CG.js";
27
+ } from "./chunk-G2ROJXYJ.js";
24
28
  import {
25
29
  applyPlan
26
- } from "./chunk-AX65JMDZ.js";
30
+ } from "./chunk-7LLVIQ7G.js";
27
31
  import {
28
32
  resolveConn
29
33
  } from "./chunk-SX75L2T3.js";
30
34
  import {
31
- DEFAULT_AGENT_LOG_LIMIT,
32
- readAgentActivity
33
- } from "./chunk-27335SIH.js";
34
- import {
35
- generatePlan
36
- } from "./chunk-T6OCPTTR.js";
35
+ acquireSession,
36
+ drainPool
37
+ } from "./chunk-TYNMOYVM.js";
37
38
  import {
38
39
  extractBaseOutputs
39
40
  } from "./chunk-3QJBNAHW.js";
41
+ import {
42
+ generatePlan
43
+ } from "./chunk-LIAXA43Z.js";
40
44
  import {
41
45
  atomicWriteConfig,
42
46
  readRemoteConfig,
43
47
  restartGateway
44
- } from "./chunk-UAJJEDCJ.js";
48
+ } from "./chunk-AGSNTIYZ.js";
45
49
  import {
46
50
  validatePlan
47
- } from "./chunk-PASAVVNS.js";
51
+ } from "./chunk-47CGHUVT.js";
48
52
  import {
49
53
  buildContext
50
- } from "./chunk-AVERNLUY.js";
51
- import {
52
- acquireSession,
53
- drainPool
54
- } from "./chunk-TYNMOYVM.js";
54
+ } from "./chunk-SQPHNVCF.js";
55
55
  import {
56
56
  AUDIT_CLEAN_MESSAGE,
57
57
  AUDIT_FIX_HINT,
@@ -69,7 +69,7 @@ import {
69
69
  resolveUpdateVersion,
70
70
  runDiagnostics,
71
71
  updateGateway
72
- } from "./chunk-OUQVKIIA.js";
72
+ } from "./chunk-PNRFFYOA.js";
73
73
  import {
74
74
  GATEWAY_LOGS_PROBE,
75
75
  chooseLogSource,
@@ -82,7 +82,7 @@ import {
82
82
  import {
83
83
  getConfig,
84
84
  getConfigDir
85
- } from "./chunk-GFIR2IIJ.js";
85
+ } from "./chunk-GYMAC4MW.js";
86
86
  import {
87
87
  StateError,
88
88
  UsageError
@@ -105,10 +105,42 @@ function getSessionId() {
105
105
  if (!_sessionId) _sessionId = randomUUID();
106
106
  return _sessionId;
107
107
  }
108
- var SENSITIVE_KEYS = ["token", "secret", "key", "password", "connectionstring", "authorization"];
108
+ var SENSITIVE_KEYS = ["token", "secret", "key", "password", "connectionstring", "authorization", "credential"];
109
109
  var EXEMPT_KEYS = ["keyname", "keypath", "privateKeyPath", "knownHostsPath"];
110
110
  var ARN_RE = /arn:aws:[a-z0-9\-*]+:[a-z0-9\-]*:[0-9]*:[^\s,'"]+/gi;
111
+ function isSensitiveName(name) {
112
+ const n = name.toLowerCase();
113
+ const exempt = EXEMPT_KEYS.some((e) => n === e.toLowerCase());
114
+ return !exempt && SENSITIVE_KEYS.some((s) => n.includes(s));
115
+ }
116
+ function isSecretPath(dotPath) {
117
+ return dotPath.split(".").some(isSensitiveName);
118
+ }
119
+ function redactConfigValue(dotPath, value) {
120
+ if (isSecretPath(dotPath)) return "[REDACTED]";
121
+ let parsed;
122
+ try {
123
+ parsed = JSON.parse(value);
124
+ } catch {
125
+ return value;
126
+ }
127
+ if (parsed === null || typeof parsed !== "object") return value;
128
+ return JSON.stringify(sanitizeValue(parsed));
129
+ }
130
+ function sanitizeValue(v) {
131
+ if (Array.isArray(v)) return v.map(sanitizeValue);
132
+ if (v !== null && typeof v === "object") return sanitize(v);
133
+ return v;
134
+ }
111
135
  function sanitize(args) {
136
+ if (typeof args["key"] === "string") {
137
+ const { key, value, ...rest } = args;
138
+ const out = { ...sanitize(rest), key };
139
+ if (value !== void 0) {
140
+ out["value"] = typeof value === "string" ? redactConfigValue(key, value) : "[REDACTED]";
141
+ }
142
+ return out;
143
+ }
112
144
  const result = {};
113
145
  for (const [k, v] of Object.entries(args)) {
114
146
  const kl = k.toLowerCase();
@@ -565,9 +597,10 @@ var clawops_workflow_deploy_appAnnotations = {
565
597
  var clawops_workflow_recoverSchema = z.object({
566
598
  stackName: z.string().optional().describe("Which stack to diagnose. Omitted = the default stack in ~/.clawops/config.json")
567
599
  });
568
- var clawops_workflow_recoverDescription = `Diagnostic workflow for an unhealthy stack. Internally: status check \u2192
569
- gateway logs \u2192 agent logs \u2192 systemd service status \u2192 produces a structured
570
- diagnostic report with suggested remediation.
600
+ var clawops_workflow_recoverDescription = `Diagnostic workflow for an unhealthy stack. Internally: what is deployed
601
+ (clawops_status) \u2192 the stack's failed health checks (clawops_doctor) \u2192 the
602
+ gateway's last 50 log lines (clawops_logs_tail) \u2192 a report with next steps that
603
+ name the tool for each kind of failure. Changes nothing.
571
604
 
572
605
  Use when: the user reports any "not working" symptom and you don't know
573
606
  where to start. Best entry point for troubleshooting.
@@ -835,7 +868,7 @@ async function handleConfigGet(input, _server) {
835
868
  }
836
869
  async function handleConfigSet(input, server) {
837
870
  const confirmation = await confirmDestructive(server, {
838
- message: `Set ${input.key} = ${input.value} on stack "${input.stackName ?? "default"}"?`,
871
+ message: `Set ${input.key} = ${redactConfigValue(input.key, input.value)} on stack "${input.stackName ?? "default"}"?`,
839
872
  title: "Confirm config change",
840
873
  what: "changing gateway configuration"
841
874
  });
@@ -1155,7 +1188,7 @@ async function handleUp(input, server) {
1155
1188
  );
1156
1189
  }
1157
1190
  const { localOpts } = stackConfig;
1158
- const { localBootstrap } = await import("./bootstrap-32TZXVDF.js");
1191
+ const { localBootstrap } = await import("./bootstrap-L3P5E4D7.js");
1159
1192
  const ac = new AbortController();
1160
1193
  const state = await localBootstrap({
1161
1194
  host: localOpts.host,
@@ -1178,8 +1211,8 @@ async function handleUp(input, server) {
1178
1211
  const progressToken = void 0;
1179
1212
  const emit = makeProgressEmitter(server, progressToken);
1180
1213
  startTask(taskId, `clawops_up stack=${ctx.stackName}`);
1181
- const { generatePlan: generatePlan2 } = await import("./generate-4JWTMOLQ.js");
1182
- const { applyPlan: applyPlan2 } = await import("./apply-F5SQ2ZOS.js");
1214
+ const { generatePlan: generatePlan2 } = await import("./generate-XJWEQKT6.js");
1215
+ const { applyPlan: applyPlan2 } = await import("./apply-TXPUNOGW.js");
1183
1216
  const { resolveNetworkFlags } = await import("./network-args-PYJRJBYO.js");
1184
1217
  const { detectEgressIp } = await import("./firewall-5VKZ4WBH.js");
1185
1218
  const network = await resolveNetworkFlags(
@@ -1294,7 +1327,7 @@ async function handlePlan(input, _server) {
1294
1327
  let network = resolved;
1295
1328
  if (input.privateOnly) {
1296
1329
  const { privateOnlyNetwork, assertTailnetReachable } = await import("./private-only-DIA26I2E.js");
1297
- const { probeSsh } = await import("./tailscale-cutover-V42HO5UM.js");
1330
+ const { probeSsh } = await import("./tailscale-cutover-XTMGDM5H.js");
1298
1331
  network = privateOnlyNetwork(flags, resolved, ctx.config.stacks[stackName]?.tailscale, stackName);
1299
1332
  await assertTailnetReachable(ctx, (conn) => probeSsh(conn));
1300
1333
  }
@@ -1331,7 +1364,7 @@ async function handleHarden(input, server) {
1331
1364
  "tailscale and tailscaleRevert do the opposite of each other; pass one, not both."
1332
1365
  );
1333
1366
  }
1334
- const { getConfig: getConfig2 } = await import("./store-YOLQYXMB.js");
1367
+ const { getConfig: getConfig2 } = await import("./store-BTQOOIJH.js");
1335
1368
  const config = getConfig2();
1336
1369
  if (!config) {
1337
1370
  return errText(
@@ -1350,12 +1383,12 @@ async function handleHarden(input, server) {
1350
1383
  return okText(confirmation.reason);
1351
1384
  }
1352
1385
  }
1353
- const { revertTailnet, cutOverToTailnet, connectionFor } = await import("./flows-6B2I6TRW.js");
1386
+ const { revertTailnet, cutOverToTailnet, connectionFor } = await import("./flows-6YEJGHCK.js");
1354
1387
  if (input.tailscaleRevert) {
1355
1388
  const outcome = await revertTailnet(ctx, config);
1356
1389
  return outcome.ok ? okText(outcome.message) : errText(outcome.reason);
1357
1390
  }
1358
- const { MODULE_CATALOG, resolveModules, runHardening, formatHardenSummary, makeTailscaleModule } = await import("./harden-UHAOVQMZ.js");
1391
+ const { MODULE_CATALOG, resolveModules, runHardening, formatHardenSummary, makeTailscaleModule } = await import("./harden-7O553IOK.js");
1359
1392
  const forStack = makeTailscaleModule(ctx.stackName);
1360
1393
  const resolved = resolveModules(MODULE_CATALOG, input.options, ctx.adapter.name).map(
1361
1394
  (m) => m.id === "tailscale" ? forStack : m
@@ -1399,7 +1432,7 @@ async function handleHarden(input, server) {
1399
1432
 
1400
1433
  // src/mcp/tools/cli/init.ts
1401
1434
  async function handleInit(input, _server) {
1402
- const { initStack } = await import("./init-HOPXDNWY.js");
1435
+ const { initStack } = await import("./init-DYOLZX65.js");
1403
1436
  const result = await initStack({
1404
1437
  provider: input.provider,
1405
1438
  stackName: input.stackName,
@@ -1865,39 +1898,39 @@ Changes: ${diffLine}. This will provision cloud resources and may incur costs.`,
1865
1898
  }
1866
1899
 
1867
1900
  // src/mcp/tools/workflow/recover.ts
1868
- async function handleWorkflowRecover(input, server) {
1869
- const parts = [`## Diagnostic Report \u2014 stack: ${input.stackName ?? "default"}
1870
- `];
1871
- try {
1872
- const statusResult = await handleStatus({ stackName: input.stackName }, server);
1873
- const statusText = statusResult.content.filter((c) => c.type === "text").map((c) => c.text).join("");
1874
- parts.push(`### Status
1875
- \`\`\`json
1876
- ${statusText}
1877
- \`\`\``);
1878
- } catch (err) {
1879
- parts.push(`### Status
1880
- Error: ${err instanceof Error ? err.message : String(err)}`);
1881
- }
1901
+ function textOf(result) {
1902
+ return result.content.filter((c) => c.type === "text").map((c) => c.text).join("");
1903
+ }
1904
+ async function section(title, fence, run) {
1882
1905
  try {
1883
- const logsResult = await handleLogsTail({ stackName: input.stackName, tailLines: 50 }, server);
1884
- const logsText = logsResult.content.filter((c) => c.type === "text").map((c) => c.text).join("");
1885
- parts.push(`### Recent Logs (last 50 lines)
1886
- \`\`\`
1887
- ${logsText}
1888
- \`\`\``);
1906
+ const result = await run();
1907
+ return result.isError ? `### ${title}
1908
+ Error: ${textOf(result)}` : `### ${title}
1909
+ \`\`\`${fence}
1910
+ ${textOf(result)}
1911
+ \`\`\``;
1889
1912
  } catch (err) {
1890
- parts.push(`### Recent Logs
1891
- Error: ${err instanceof Error ? err.message : String(err)}`);
1913
+ return `### ${title}
1914
+ Error: ${err instanceof Error ? err.message : String(err)}`;
1892
1915
  }
1916
+ }
1917
+ async function handleWorkflowRecover(input, server) {
1918
+ const stack = input.stackName ?? "default";
1919
+ const parts = [`## Diagnostic Report \u2014 stack: ${stack}
1920
+ `];
1921
+ parts.push(await section("Status", "json", () => handleStatus({ stackName: input.stackName }, server)));
1922
+ parts.push(await section("Failed health checks", "json", () => handleDoctor({ stackName: input.stackName, failuresOnly: true }, server)));
1923
+ parts.push(await section("Recent Logs (last 50 lines)", "", () => handleLogsTail({ stackName: input.stackName, tailLines: 50 }, server)));
1893
1924
  parts.push(
1894
1925
  `### Next Steps
1895
- - If gateway is not running: try \`clawops_gateway_restart\`
1896
- - If bootstrap failed: run \`clawops_up\` again (idempotent)
1897
- - If stack is not deployed: run \`clawops_workflow_deploy_app\`
1898
- - For Pulumi drift: run \`clawops refresh\` from the CLI`
1926
+ - Gateway not running, or not answering: \`clawops_gateway_restart\`
1927
+ - Gateway fails on its current version: \`clawops_gateway_update\` to a version that worked, or \`clawops_backup_restore\` with \`activate\` if the state is at fault
1928
+ - Host not set up, or set up only partly: \`clawops_up\` again (it is idempotent)
1929
+ - Infrastructure differs from what was deployed: \`clawops_plan\`, review, then \`clawops_apply\`
1930
+ - Nothing deployed yet: \`clawops_workflow_deploy_app\``
1899
1931
  );
1900
- return { content: [{ type: "text", text: parts.join("\n\n") }] };
1932
+ const { content } = trimForMcp(parts.join("\n\n"), stack);
1933
+ return { content: [{ type: "text", text: content }] };
1901
1934
  }
1902
1935
 
1903
1936
  // src/mcp/tools/registry.ts
@@ -2232,7 +2265,7 @@ function bearerFrom(header) {
2232
2265
  return match?.[1]?.trim();
2233
2266
  }
2234
2267
  async function serveMcp(opts) {
2235
- const { version } = await import("./package-ESYPCIES.js");
2268
+ const { version } = await import("./package-HRMX7K3C.js");
2236
2269
  const makeServer = () => {
2237
2270
  const server = new McpServer({ name: "clawops", version });
2238
2271
  registerTools(server, opts);
@@ -1,17 +1,17 @@
1
1
  #!/usr/bin/env node
2
- import {
3
- listOverlays
4
- } from "./chunk-6ZFIFDBJ.js";
5
2
  import {
6
3
  inspectContainer
7
4
  } from "./chunk-Z3XLWZWF.js";
8
5
  import {
9
- execPrivileged
10
- } from "./chunk-WPZIJONN.js";
6
+ listOverlays
7
+ } from "./chunk-6ZFIFDBJ.js";
11
8
  import {
12
9
  interpretProbe,
13
10
  probeCommand
14
11
  } from "./chunk-LT4XMO5D.js";
12
+ import {
13
+ execPrivileged
14
+ } from "./chunk-WPZIJONN.js";
15
15
  import {
16
16
  PUBLISH_INSPECT_CMD,
17
17
  STATE_DIR_CONTAINER,
@@ -158,8 +158,8 @@ function renderSnapshot(snap, opts) {
158
158
  return lines.join("\n");
159
159
  }
160
160
  async function probeEntries() {
161
- const { buildContext } = await import("./context-EHSLWKSH.js");
162
- const { getConfig } = await import("./store-YOLQYXMB.js");
161
+ const { buildContext } = await import("./context-4KTM4DKH.js");
162
+ const { getConfig } = await import("./store-BTQOOIJH.js");
163
163
  const config = getConfig();
164
164
  if (!config) return [];
165
165
  return Promise.all(
@@ -227,7 +227,7 @@ function renderMenu(entries, selectedIdx, showAll, noColor, confirmDelete) {
227
227
  return lines.join("\n");
228
228
  }
229
229
  async function deleteFromRegistry(name) {
230
- const { requireConfig, setConfig } = await import("./store-YOLQYXMB.js");
230
+ const { requireConfig, setConfig } = await import("./store-BTQOOIJH.js");
231
231
  const config = requireConfig();
232
232
  const newStacks = { ...config.stacks };
233
233
  delete newStacks[name];
@@ -385,7 +385,7 @@ var monitor_default = defineCommand({
385
385
  const tailLines = Math.max(1, parseInt(String(args.tail ?? "10"), 10) || 10);
386
386
  const isTTY = Boolean(process.stdout.isTTY);
387
387
  const noColor = Boolean(args["no-color"]) || !isTTY;
388
- const { buildContext } = await import("./context-EHSLWKSH.js");
388
+ const { buildContext } = await import("./context-4KTM4DKH.js");
389
389
  const { acquireSession, drainPool } = await import("./pool-NT4XBSUT.js");
390
390
  const ac = new AbortController();
391
391
  process.on("SIGINT", () => ac.abort());
@@ -718,7 +718,7 @@ import { accessSync, mkdirSync, readFileSync, constants } from "fs";
718
718
  import ssh2 from "ssh2";
719
719
  import path from "path";
720
720
  async function runDiagnostics(opts = {}, deps = {}) {
721
- const { getConfig, getConfigDir } = await import("./store-YOLQYXMB.js");
721
+ const { getConfig, getConfigDir } = await import("./store-BTQOOIJH.js");
722
722
  const config = getConfig();
723
723
  const sections = [];
724
724
  sections.push({ title: "Runtime", checks: await runtimeChecks(getConfigDir()) });
@@ -1018,8 +1018,8 @@ async function deployedVersionCheck(image, deployedVersion) {
1018
1018
  }
1019
1019
  async function hardeningChecks(conn, stack, signal) {
1020
1020
  try {
1021
- const { MODULE_CATALOG, resolveModules, withRemoteExec } = await import("./harden-UHAOVQMZ.js");
1022
- const { buildContext } = await import("./context-EHSLWKSH.js");
1021
+ const { MODULE_CATALOG, resolveModules, withRemoteExec } = await import("./harden-7O553IOK.js");
1022
+ const { buildContext } = await import("./context-4KTM4DKH.js");
1023
1023
  const provider = buildContext({ stack }).adapter.name;
1024
1024
  const modules = resolveModules(MODULE_CATALOG, void 0, provider);
1025
1025
  const checks = [];
@@ -1041,8 +1041,8 @@ async function hardeningChecks(conn, stack, signal) {
1041
1041
  }
1042
1042
  }
1043
1043
  async function defaultOpenSession(stack, signal) {
1044
- const { getConfig } = await import("./store-YOLQYXMB.js");
1045
- const { buildContext } = await import("./context-EHSLWKSH.js");
1044
+ const { getConfig } = await import("./store-BTQOOIJH.js");
1045
+ const { buildContext } = await import("./context-4KTM4DKH.js");
1046
1046
  const { extractBaseOutputs } = await import("./outputs-DJHBY7EE.js");
1047
1047
  const { acquireSession } = await import("./pool-NT4XBSUT.js");
1048
1048
  const config = getConfig();
@@ -3,7 +3,7 @@ import {
3
3
  getConfig,
4
4
  getConfigDir,
5
5
  setConfig
6
- } from "./chunk-GFIR2IIJ.js";
6
+ } from "./chunk-GYMAC4MW.js";
7
7
 
8
8
  // src/config/init.ts
9
9
  import { spawnSync } from "child_process";
@@ -109,6 +109,9 @@ async function initStack(opts) {
109
109
  reason: `Stack "${stackName}" already exists in ${path.join(getConfigDir(), "config.json")} (${existing.stacks[stackName].stateUrl}). Pass force to overwrite its settings, or use a different stack name to add another one.`
110
110
  };
111
111
  }
112
+ const { stackCapRefusal } = await import("./policy-AZGFCQNV.js");
113
+ const overCap = stackCapRefusal(existing, stackName);
114
+ if (overCap) return { ok: false, reason: overCap };
112
115
  const configDir = getConfigDir();
113
116
  mkdirSync(configDir, { recursive: true });
114
117
  const keyPath = opts.keyPath ?? path.join(configDir, "id_ed25519");
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  getConfigDir
4
- } from "./chunk-GFIR2IIJ.js";
4
+ } from "./chunk-GYMAC4MW.js";
5
5
 
6
6
  // src/config/secrets.ts
7
7
  import { readFileSync, existsSync } from "fs";
@@ -1,17 +1,17 @@
1
1
  #!/usr/bin/env node
2
- import {
3
- getProvider
4
- } from "./chunk-VUFMZEIM.js";
5
2
  import {
6
3
  readLocalState
7
- } from "./chunk-RDUKRIRC.js";
4
+ } from "./chunk-U3NRKBDW.js";
8
5
  import {
9
6
  getConfigDir,
10
7
  requireConfig
11
- } from "./chunk-GFIR2IIJ.js";
8
+ } from "./chunk-GYMAC4MW.js";
12
9
  import {
13
10
  UsageError
14
11
  } from "./chunk-KGXPLI7W.js";
12
+ import {
13
+ getProvider
14
+ } from "./chunk-VUFMZEIM.js";
15
15
 
16
16
  // src/cli/context.ts
17
17
  function buildContext(args) {
@@ -41,7 +41,7 @@ function buildContext(args) {
41
41
  `Stack "${stackName}" not found in config. Run \`clawops init\` or use \`--stack\` to specify a different stack.`
42
42
  );
43
43
  }
44
- const { getOrCreateStack } = await import("./automation-NBYQ6MFZ.js");
44
+ const { getOrCreateStack } = await import("./automation-VDKLZMJI.js");
45
45
  stackCache = await getOrCreateStack({
46
46
  stack: stackName,
47
47
  stateUrl: stackConfig.stateUrl,
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  getConfigDir
4
- } from "./chunk-GFIR2IIJ.js";
4
+ } from "./chunk-GYMAC4MW.js";
5
5
 
6
6
  // src/providers/local/state.ts
7
7
  import { readFileSync, writeFileSync, mkdirSync, renameSync } from "fs";