@wrongstack/cli 1.0.24 → 1.0.27

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 (146) hide show
  1. package/data/providers.json +44 -0
  2. package/dist/{acp-AJWSKWE5.js → acp-M4565YUW.js} +33 -20
  3. package/dist/ascii-mode-SG4PRNLP.js +7 -0
  4. package/dist/{auth-GRBZ7Y3D.js → auth-TE55JF4Z.js} +14 -14
  5. package/dist/{bench-N5K7Z5O3.js → bench-GTLPM22B.js} +2 -2
  6. package/dist/boot/append-system-prompt.d.ts +10 -0
  7. package/dist/boot/ascii-mode.d.ts +12 -0
  8. package/dist/boot/container-wiring.d.ts +4 -2
  9. package/dist/boot/dispatch-singleshot.d.ts +12 -1
  10. package/dist/boot/dispatch-webui.d.ts +2 -0
  11. package/dist/boot/goal-tui-default.d.ts +10 -0
  12. package/dist/boot/mcp-config-flag.d.ts +22 -0
  13. package/dist/boot/piped-stdin.d.ts +40 -0
  14. package/dist/boot/restricted-mode.d.ts +15 -0
  15. package/dist/boot/safe-mode.d.ts +30 -0
  16. package/dist/boot/single-shot-budget.d.ts +30 -0
  17. package/dist/boot/stream-json.d.ts +36 -0
  18. package/dist/boot/structured-output.d.ts +16 -0
  19. package/dist/boot/system-prompt-builder.d.ts +2 -0
  20. package/dist/boot/tool-restriction-flags.d.ts +36 -0
  21. package/dist/boot/worktree-sessions.d.ts +21 -0
  22. package/dist/boot-provider-selection.d.ts +67 -0
  23. package/dist/boot.d.ts +1 -38
  24. package/dist/{chunk-LFMVHT3R.js → chunk-2ERX3RPN.js} +11 -13
  25. package/dist/chunk-4TVYGG6G.js +62 -0
  26. package/dist/chunk-5JYDKG5B.js +154 -0
  27. package/dist/{chunk-3VXYY5JC.js → chunk-5UZBUV2H.js} +3 -19
  28. package/dist/chunk-CZTXF6HY.js +140 -0
  29. package/dist/{chunk-DRM7PSW7.js → chunk-ENRYW73H.js} +527 -381
  30. package/dist/{chunk-SKPDE62W.js → chunk-EPR42SWM.js} +36 -6
  31. package/dist/{chunk-YBUCXXYZ.js → chunk-F5DCFAKI.js} +1 -1
  32. package/dist/chunk-HDMFKTT3.js +157 -0
  33. package/dist/{chunk-PGKJ2OQP.js → chunk-HFZH2XJN.js} +5 -5
  34. package/dist/chunk-HLSHFXTO.js +97 -0
  35. package/dist/{chunk-QFPQXKCG.js → chunk-KOEO4CJG.js} +21 -6
  36. package/dist/chunk-LBPLTTZ6.js +105 -0
  37. package/dist/{chunk-3OCUS3VN.js → chunk-LDCGZJTC.js} +4 -4
  38. package/dist/chunk-LKPEBZBE.js +143 -0
  39. package/dist/chunk-N57IU5FG.js +58 -0
  40. package/dist/{chunk-2EBVTYJR.js → chunk-NRXWOMK7.js} +17 -3
  41. package/dist/chunk-PZQBGUVZ.js +18 -0
  42. package/dist/{chunk-MHEBWVXL.js → chunk-Q4INH2DG.js} +46 -2
  43. package/dist/{chunk-5SEYGOCH.js → chunk-RDGGWMTI.js} +2 -2
  44. package/dist/{chunk-BLD5DSVA.js → chunk-RGFWGUAB.js} +27 -15
  45. package/dist/{chunk-ZZRSG7VK.js → chunk-RZ4ZDRYA.js} +3 -3
  46. package/dist/{chunk-S4FFHDJG.js → chunk-SDJCLEK6.js} +6 -2
  47. package/dist/{chunk-U46QR4WR.js → chunk-TI7KLHYX.js} +132 -3
  48. package/dist/chunk-X756ZS72.js +329 -0
  49. package/dist/{chunk-JF2MULWF.js → chunk-YHYINL47.js} +47 -15
  50. package/dist/{cli-context-34Q5IJRA.js → cli-context-C7RBSWHF.js} +434 -327
  51. package/dist/{cli-main-AELJDBGU.js → cli-main-TQTH73ZK.js} +2948 -2315
  52. package/dist/cli-update-notice.d.ts +2 -1
  53. package/dist/config-doctor.d.ts +1 -1
  54. package/dist/{diag-doctor-WIFJH3XH.js → diag-doctor-BIZAFIAT.js} +2 -2
  55. package/dist/{execution-PYC5FCS4.js → execution-3STBD2U7.js} +2167 -1831
  56. package/dist/execution-chimera-review.d.ts +18 -1
  57. package/dist/fleet/host-types.d.ts +3 -1
  58. package/dist/goal-commands.d.ts +47 -0
  59. package/dist/goal-host.d.ts +1 -14
  60. package/dist/{hq-JTUTFI4L.js → hq-44F4OQH2.js} +9 -8
  61. package/dist/hq-fleet-control.d.ts +36 -0
  62. package/dist/hq-live-status.d.ts +22 -0
  63. package/dist/hq-publisher.d.ts +18 -0
  64. package/dist/hq-server/routes/command-handlers.d.ts +12 -1
  65. package/dist/hq-server/routes/data-handlers.d.ts +1 -1
  66. package/dist/hq-server/socket-credentials.d.ts +63 -0
  67. package/dist/hq-server/upgrade-handler.d.ts +2 -0
  68. package/dist/hq-server/ws.d.ts +24 -0
  69. package/dist/{hq-server-PC7GZMPT.js → hq-server-UIB24LU6.js} +2 -2
  70. package/dist/{hq-service-NW56MUP2.js → hq-service-BMMJAHRT.js} +4 -4
  71. package/dist/import-claude-code-AYG24RG2.js +268 -0
  72. package/dist/index.js +12 -8
  73. package/dist/live-settings-input.d.ts +1 -0
  74. package/dist/{mailbox-serve-WDOCH6KR.js → mailbox-serve-GNGXEQ2R.js} +3 -3
  75. package/dist/{modeldiag-36OGAL5C.js → modeldiag-W7XAE625.js} +9 -9
  76. package/dist/{per-subcommand-help-XE77MTGJ.js → per-subcommand-help-QDAQASPZ.js} +2 -2
  77. package/dist/permission-prompt.d.ts +14 -0
  78. package/dist/permission-rules-view.d.ts +18 -0
  79. package/dist/{permissions-CFDLXETM.js → permissions-PL27UHYD.js} +67 -45
  80. package/dist/{plugin-usage-S5LVGMBW.js → plugin-usage-CIGOOTX3.js} +2 -2
  81. package/dist/{plugins-RHBIVLI7.js → plugins-HQTXUD6A.js} +4 -2
  82. package/dist/preflight.d.ts +1 -1
  83. package/dist/{projects-LMNAGGEU.js → projects-T4CZCA25.js} +3 -6
  84. package/dist/provider-helpers.d.ts +7 -11
  85. package/dist/{providers-models-2CFG46RD.js → providers-models-5Z2PJTEW.js} +5 -5
  86. package/dist/release-asset-download.d.ts +10 -0
  87. package/dist/release-attestation.d.ts +28 -0
  88. package/dist/remote/remote-session.d.ts +64 -0
  89. package/dist/remote/remote-target.d.ts +69 -0
  90. package/dist/remote-GB5VXCCT.js +576 -0
  91. package/dist/{replay-Z3FTJEMM.js → replay-DEI566CW.js} +2 -2
  92. package/dist/services/commit-message.d.ts +2 -1
  93. package/dist/session-move-P2EC2COA.js +44 -0
  94. package/dist/session-move.d.ts +20 -0
  95. package/dist/session-stats.d.ts +10 -0
  96. package/dist/{sessions-config-IQUH2GXT.js → sessions-config-XHLXJ5C3.js} +109 -10
  97. package/dist/short-circuit-flags-5TNTJPQR.js +10 -0
  98. package/dist/slash-commands/command-context.d.ts +15 -5
  99. package/dist/slash-commands/goal-refiner.d.ts +4 -49
  100. package/dist/slash-commands/mcp.d.ts +2 -1
  101. package/dist/slash-commands/permissions.d.ts +4 -0
  102. package/dist/slash-commands/settings-context-mutations.d.ts +5 -0
  103. package/dist/slash-commands/settings-limits-mutations.d.ts +12 -0
  104. package/dist/slash-commands/theme.d.ts +15 -1
  105. package/dist/standalone-auto-update-TOTRGCSA.js +249 -0
  106. package/dist/standalone-auto-update.d.ts +65 -0
  107. package/dist/standalone-update-LZO3MNLH.js +24 -0
  108. package/dist/standalone-update.d.ts +37 -1
  109. package/dist/subcommands/handlers/import-claude-code.d.ts +52 -0
  110. package/dist/subcommands/handlers/permissions.d.ts +9 -3
  111. package/dist/subcommands/handlers/remote.d.ts +6 -0
  112. package/dist/subcommands/handlers/sessions-fleet.d.ts +0 -12
  113. package/dist/subcommands/handlers/version-help.d.ts +5 -0
  114. package/dist/{subcommands-ZTSIN7LG.js → subcommands-BHQYLDSD.js} +2 -2
  115. package/dist/tui-resume-callback.d.ts +18 -0
  116. package/dist/{typesafe-HVEVPA6R.js → typesafe-U7YB2RRV.js} +5 -5
  117. package/dist/{typesafe-topic-replay-4W73BOLV.js → typesafe-topic-replay-ZILIU3WS.js} +18 -2
  118. package/dist/{update-7XIOEXTD.js → update-TDZX4IL2.js} +4 -4
  119. package/dist/{update-check-2POMBHFB.js → update-check-J5ZVKS73.js} +3 -3
  120. package/dist/version-JB2UAV2A.js +11 -0
  121. package/dist/version-help-XJJQ7YSH.js +10 -0
  122. package/dist/webui-server/route-contexts.d.ts +1 -1
  123. package/dist/webui-server/session-start-payload.d.ts +5 -1
  124. package/dist/{webui-server-L2SICPTB.js → webui-server-GCXIO3JY.js} +515 -365
  125. package/dist/webui-server-lifecycle.d.ts +57 -0
  126. package/dist/webui-server-options.d.ts +10 -0
  127. package/dist/webui-server.d.ts +0 -14
  128. package/dist/wiring/brain-and-orchestration.d.ts +3 -1
  129. package/dist/wiring/cli-prompt-and-tools-setup.d.ts +9 -0
  130. package/dist/wiring/cli-slash-commands-setup.d.ts +1 -0
  131. package/dist/wiring/command-host-state.d.ts +2 -0
  132. package/dist/wiring/hq-telemetry.d.ts +12 -0
  133. package/dist/wiring/lifecycle-plugins.d.ts +4 -2
  134. package/dist/wiring/metrics.d.ts +9 -1
  135. package/dist/wiring/pipeline.d.ts +2 -7
  136. package/dist/wiring/plugins.d.ts +3 -0
  137. package/dist/wiring/provider-status.d.ts +1 -0
  138. package/dist/wiring/provider-utility-tools.d.ts +3 -1
  139. package/package.json +29 -28
  140. package/dist/chunk-2BKFWIER.js +0 -98
  141. package/dist/chunk-424ORSE7.js +0 -56
  142. package/dist/chunk-OWNC7LMD.js +0 -78
  143. package/dist/chunk-QBBF7GIK.js +0 -65
  144. package/dist/short-circuit-flags-SDT53OML.js +0 -10
  145. package/dist/standalone-update-MW47J3AK.js +0 -164
  146. package/dist/version-help-WZ623NWM.js +0 -10
@@ -0,0 +1,143 @@
1
+
2
+ // src/boot/stream-json.ts
3
+ function parseOutputFormat(value) {
4
+ if (value === void 0) return void 0;
5
+ if (value === "text" || value === "json" || value === "stream-json") return value;
6
+ throw new Error(
7
+ `--output-format must be text, json or stream-json (got ${value === true ? "nothing" : `"${value}"`})`
8
+ );
9
+ }
10
+ var LEADER = "leader";
11
+ function isLeader(agentId) {
12
+ return agentId === void 0 || agentId === LEADER;
13
+ }
14
+ function simplifyBlocks(content) {
15
+ const out = [];
16
+ for (const block of content ?? []) {
17
+ if (block.type === "text") out.push({ type: "text", text: block.text });
18
+ else if (block.type === "tool_use") {
19
+ out.push({ type: "tool_use", id: block.id, name: block.name, input: block.input });
20
+ }
21
+ }
22
+ return out;
23
+ }
24
+ function startStreamJson(opts) {
25
+ const emit = (payload) => {
26
+ opts.write(`${JSON.stringify(payload)}
27
+ `);
28
+ };
29
+ const offs = [];
30
+ if (opts.includePartialMessages) {
31
+ offs.push(
32
+ opts.events.on("provider.text_delta", (e) => {
33
+ if (isLeader(e.ctx?.agentId)) emit({ type: "text_delta", text: e.text });
34
+ })
35
+ );
36
+ }
37
+ offs.push(
38
+ opts.events.on("provider.response", (e) => {
39
+ if (!isLeader(e.ctx?.agentId)) return;
40
+ emit({
41
+ type: "assistant",
42
+ model: e.model,
43
+ content: simplifyBlocks(e.content),
44
+ stopReason: e.stopReason,
45
+ usage: e.usage
46
+ });
47
+ })
48
+ );
49
+ offs.push(
50
+ opts.events.on("tool.executed", (e) => {
51
+ if (!isLeader(e.agentId)) return;
52
+ emit({
53
+ type: "tool_result",
54
+ id: e.id ?? null,
55
+ name: e.name,
56
+ ok: e.ok,
57
+ durationMs: e.durationMs,
58
+ output: e.output ?? null,
59
+ outputBytes: e.outputBytes ?? null
60
+ });
61
+ })
62
+ );
63
+ return () => {
64
+ for (const off of offs) off();
65
+ };
66
+ }
67
+ function streamJsonInit(info) {
68
+ return `${JSON.stringify({ type: "init", ...info })}
69
+ `;
70
+ }
71
+
72
+ // src/boot/structured-output.ts
73
+ import * as fs from "node:fs/promises";
74
+ import * as path from "node:path";
75
+ import { validateAgainstSchema } from "@wrongstack/core/utils";
76
+ async function resolveJsonSchemaFlag(value, cwd) {
77
+ if (value === void 0) return void 0;
78
+ if (typeof value !== "string" || !value.trim()) {
79
+ throw new Error("--json-schema needs a JSON Schema file path or an inline JSON object");
80
+ }
81
+ const trimmed = value.trim();
82
+ let text = trimmed;
83
+ let source = "inline JSON";
84
+ if (!trimmed.startsWith("{")) {
85
+ const file = path.resolve(cwd, trimmed);
86
+ source = file;
87
+ try {
88
+ text = await fs.readFile(file, "utf8");
89
+ } catch (err) {
90
+ const reason = err.code ?? String(err);
91
+ throw new Error(`--json-schema: cannot read ${file} (${reason})`);
92
+ }
93
+ }
94
+ let schema;
95
+ try {
96
+ schema = JSON.parse(text);
97
+ } catch (err) {
98
+ throw new Error(`--json-schema: ${source} is not valid JSON (${err.message})`);
99
+ }
100
+ if (typeof schema !== "object" || schema === null || Array.isArray(schema)) {
101
+ throw new Error(`--json-schema: ${source} must be a JSON Schema object`);
102
+ }
103
+ return schema;
104
+ }
105
+ function withSchemaInstruction(query, schema) {
106
+ return `${query}
107
+
108
+ When you are done, reply with ONLY a JSON value that validates against this JSON Schema \u2014 no prose, no code fence:
109
+ ${JSON.stringify(schema)}`;
110
+ }
111
+ function checkStructuredAnswer(text, schema) {
112
+ if (!text?.trim()) return { ok: false, errors: ["the answer was empty"] };
113
+ const fenced = text.trim().match(/^```(?:json)?\s*\n([\s\S]*?)\n?```$/);
114
+ const body = (fenced?.[1] ?? text).trim();
115
+ let value;
116
+ try {
117
+ value = JSON.parse(body);
118
+ } catch (err) {
119
+ return { ok: false, errors: [`not valid JSON (${err.message})`] };
120
+ }
121
+ const result = validateAgainstSchema(value, schema);
122
+ if (result.ok) return { ok: true, value };
123
+ return {
124
+ ok: false,
125
+ errors: result.errors.map((e) => `${e.path || "(root)"}: ${e.message}`)
126
+ };
127
+ }
128
+ function repairPrompt(errors) {
129
+ return `Your last answer did not validate against the JSON Schema:
130
+ ${errors.map((e) => `- ${e}`).join("\n")}
131
+ Reply with ONLY the corrected JSON value.`;
132
+ }
133
+
134
+ export {
135
+ parseOutputFormat,
136
+ startStreamJson,
137
+ streamJsonInit,
138
+ resolveJsonSchemaFlag,
139
+ withSchemaInstruction,
140
+ checkStructuredAnswer,
141
+ repairPrompt
142
+ };
143
+ //# sourceMappingURL=chunk-LKPEBZBE.js.map
@@ -0,0 +1,58 @@
1
+
2
+ // src/subcommands/index.ts
3
+ var loaders = {
4
+ acp: async () => (await import("./acp-M4565YUW.js")).acpCmd,
5
+ init: async () => (await import("./init-DRMMFG2G.js")).initCmd,
6
+ auth: async () => (await import("./auth-TE55JF4Z.js")).authCmd,
7
+ update: async () => (await import("./update-TDZX4IL2.js")).updateCmd,
8
+ remote: async () => (await import("./remote-GB5VXCCT.js")).remoteCmd,
9
+ sessions: async () => (await import("./sessions-config-XHLXJ5C3.js")).sessionsCmd,
10
+ config: async () => (await import("./sessions-config-XHLXJ5C3.js")).configCmd,
11
+ "config-export": async () => (await import("./config-transfer-RUWLDCNK.js")).configExportCmd,
12
+ "config-import": async () => (await import("./config-transfer-RUWLDCNK.js")).configImportCmd,
13
+ rewind: async () => (await import("./rewind-JA3ZLCNM.js")).rewindCmd,
14
+ replay: async () => (await import("./replay-JJ2NOWD6.js")).replayCmd,
15
+ audit: async () => (await import("./audit-46YK5DSC.js")).auditCmd,
16
+ tools: async () => (await import("./tools-skills-GH24UCBY.js")).toolsCmd,
17
+ skills: async () => (await import("./tools-skills-GH24UCBY.js")).skillsCmd,
18
+ "skill-suggest": async () => (await import("./skill-suggest-L2EVWB6R.js")).skillSuggestCmd,
19
+ typesafe: async () => (await import("./typesafe-U7YB2RRV.js")).typesafeCmd,
20
+ providers: async () => (await import("./providers-models-5Z2PJTEW.js")).providersCmd,
21
+ models: async () => (await import("./providers-models-5Z2PJTEW.js")).modelsCmd,
22
+ mcp: async () => (await import("./mcp-LBS45HWZ.js")).mcpCmd,
23
+ plugin: async () => (await import("./plugin-usage-CIGOOTX3.js")).pluginCmd,
24
+ plugins: async () => (await import("./plugin-usage-CIGOOTX3.js")).pluginCmd,
25
+ diag: async () => (await import("./diag-doctor-BIZAFIAT.js")).diagCmd,
26
+ doctor: async () => (await import("./diag-doctor-BIZAFIAT.js")).doctorCmd,
27
+ "proxy-status": async () => (await import("./diag-doctor-BIZAFIAT.js")).proxyCmd,
28
+ export: async () => (await import("./export-VVRIOWFV.js")).exportCmd,
29
+ usage: async () => (await import("./plugin-usage-CIGOOTX3.js")).usageCmd,
30
+ version: async () => (await import("./version-help-XJJQ7YSH.js")).versionCmd,
31
+ help: async () => (await import("./version-help-XJJQ7YSH.js")).helpCmd,
32
+ projects: async () => (await import("./projects-T4CZCA25.js")).projectsCmd,
33
+ modeldiag: async () => (await import("./modeldiag-W7XAE625.js")).modeldiagCmd,
34
+ quick: async () => (await import("./quick-CNB4Z3HS.js")).quickCmd,
35
+ bench: async () => (await import("./bench-GTLPM22B.js")).benchCmd,
36
+ chronicle: async () => (await import("./chronicle-UTFETHP6.js")).chronicleCmd,
37
+ hq: async () => (await import("./hq-44F4OQH2.js")).hqCmd,
38
+ mailbox: async () => (await import("./mailbox-serve-GNGXEQ2R.js")).mailboxServeCmd,
39
+ permissions: async () => (await import("./permissions-PL27UHYD.js")).permissionsCmd,
40
+ project: async () => (await import("./project-AOQI5XTK.js")).projectCmd,
41
+ governance: async () => (await import("./governance-RYSHV675.js")).governanceCmd,
42
+ "import-claude-code": async () => (await import("./import-claude-code-AYG24RG2.js")).importClaudeCodeCmd
43
+ };
44
+ var subcommands = Object.fromEntries(
45
+ Object.entries(loaders).map(
46
+ ([name, load]) => [
47
+ name,
48
+ async (args, deps) => (await load())(args, deps)
49
+ ]
50
+ )
51
+ );
52
+ var subcommandNames = Object.keys(loaders);
53
+
54
+ export {
55
+ subcommands,
56
+ subcommandNames
57
+ };
58
+ //# sourceMappingURL=chunk-N57IU5FG.js.map
@@ -172,14 +172,28 @@ async function dispatch(controller, commandId, type, payload) {
172
172
  };
173
173
  }
174
174
  if (target === "fleet") {
175
- const killed = await controller.killFleet?.(sessionId) ?? 0;
175
+ if (controller.killFleet === void 0) {
176
+ return {
177
+ commandId,
178
+ status: "rejected",
179
+ message: "this client does not manage a fleet"
180
+ };
181
+ }
182
+ const killed = await controller.killFleet(sessionId);
176
183
  return {
177
184
  commandId,
178
185
  status: "completed",
179
186
  message: `fleet stopped (${killed} agents)`
180
187
  };
181
188
  }
182
- const terminated = await controller.terminateAgent?.(target, sessionId) ?? false;
189
+ if (controller.terminateAgent === void 0) {
190
+ return {
191
+ commandId,
192
+ status: "rejected",
193
+ message: "this client does not manage subagents"
194
+ };
195
+ }
196
+ const terminated = await controller.terminateAgent(target, sessionId);
183
197
  return {
184
198
  commandId,
185
199
  status: terminated ? "completed" : "rejected",
@@ -320,4 +334,4 @@ export {
320
334
  createProjectKanbanAssignHandler,
321
335
  createHqCommandDispatcher
322
336
  };
323
- //# sourceMappingURL=chunk-2EBVTYJR.js.map
337
+ //# sourceMappingURL=chunk-NRXWOMK7.js.map
@@ -0,0 +1,18 @@
1
+
2
+ // src/boot/ascii-mode.ts
3
+ import { installAsciiOutput, isAsciiMode } from "@wrongstack/core/utils";
4
+ var installed = false;
5
+ function applyAsciiMode(flags, env = process.env, streams = [process.stdout, process.stderr]) {
6
+ if (flags["ascii"] === true) env["WRONGSTACK_TUI_ICON_STYLE"] = "ascii";
7
+ if (!isAsciiMode(env)) return false;
8
+ if (!installed) {
9
+ installed = true;
10
+ for (const stream of streams) installAsciiOutput(stream);
11
+ }
12
+ return true;
13
+ }
14
+
15
+ export {
16
+ applyAsciiMode
17
+ };
18
+ //# sourceMappingURL=chunk-PZQBGUVZ.js.map
@@ -20,6 +20,34 @@ var BOOLEAN_FLAGS = /* @__PURE__ */ new Set([
20
20
  // Both are boolean so they cannot swallow the next positional token.
21
21
  "no-recovery",
22
22
  "recover",
23
+ // `--continue` / `-c`: resume the most recent session (same pick as a bare
24
+ // `--resume`). Boolean so `wstack -c "next step"` keeps the prompt.
25
+ "continue",
26
+ // `--fork-session` (with --resume/--continue/--recover): branch instead of reopening.
27
+ "fork-session",
28
+ // `--strict-mcp-config`: start only the `--mcp-config` servers.
29
+ "strict-mcp-config",
30
+ // `--include-partial-messages`: add text_delta events to stream-json output.
31
+ "include-partial-messages",
32
+ // `--safe-mode`: start with plugins/hooks/MCP/skills/instruction overrides off.
33
+ "safe-mode",
34
+ // `--restricted`: no code-running/network tools, project-root lock, no YOLO.
35
+ "restricted",
36
+ // `--record` is read as `=== true`; as a value flag it swallowed the task
37
+ // (`wstack --record "fix it"` recorded nothing and ran nothing).
38
+ "record",
39
+ // Same class: switches read only as `=== true` that would otherwise take the
40
+ // next token (`--vector-sync "task"`, `typesafe lint-conventions --staged x`).
41
+ "vector-sync",
42
+ "allow-all",
43
+ "no-llm",
44
+ "staged",
45
+ "sweep",
46
+ "n",
47
+ // `wstack import-claude-code` switches.
48
+ "apply",
49
+ "overwrite",
50
+ "enable-project-servers",
23
51
  "output-json",
24
52
  "metrics",
25
53
  "webui",
@@ -28,6 +56,8 @@ var BOOLEAN_FLAGS = /* @__PURE__ */ new Set([
28
56
  "full-auto",
29
57
  "desktop",
30
58
  "open",
59
+ // `wstack remote --keep`: leave the remote host running after disconnecting.
60
+ "keep",
31
61
  "webui-require-token",
32
62
  "require-token",
33
63
  "no-check",
@@ -39,6 +69,7 @@ var BOOLEAN_FLAGS = /* @__PURE__ */ new Set([
39
69
  "skip",
40
70
  "skip-index",
41
71
  "mouse",
72
+ "ascii",
42
73
  "no-interactive",
43
74
  "token-saving-mode",
44
75
  "system-lite",
@@ -139,7 +170,13 @@ function parseArgs(argv) {
139
170
  }
140
171
  } else if (a.startsWith("-") && a.length === 2) {
141
172
  const short = a.slice(1);
142
- const expand = { v: "verbose", y: "yes", h: "help" };
173
+ const expand = {
174
+ v: "verbose",
175
+ y: "yes",
176
+ h: "help",
177
+ c: "continue",
178
+ r: "resume"
179
+ };
143
180
  const name = expand[short] ?? short;
144
181
  if (!BOOLEAN_FLAGS.has(name) && i + 1 < argv.length && !(argv[i + 1] ?? "").startsWith("-")) {
145
182
  flags[name] = argv[++i] ?? "";
@@ -151,6 +188,13 @@ function parseArgs(argv) {
151
188
  }
152
189
  }
153
190
  normalizeSurfaceAliases(flags, positional);
191
+ for (const [camel, kebab] of [
192
+ ["disallowedTools", "disallowed-tools"],
193
+ ["allowedTools", "allowed-tools"]
194
+ ]) {
195
+ if (flags[camel] !== void 0 && flags[kebab] === void 0) flags[kebab] = flags[camel];
196
+ delete flags[camel];
197
+ }
154
198
  return { flags, positional };
155
199
  }
156
200
  function normalizeSurfaceAliases(flags, positional) {
@@ -262,4 +306,4 @@ export {
262
306
  parseAuthFlags,
263
307
  parseSpawnFlags
264
308
  };
265
- //# sourceMappingURL=chunk-MHEBWVXL.js.map
309
+ //# sourceMappingURL=chunk-Q4INH2DG.js.map
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  resolveProviderCfgWithProxy
3
- } from "./chunk-S4FFHDJG.js";
3
+ } from "./chunk-SDJCLEK6.js";
4
4
  import {
5
5
  fallbackCodexProviderModels,
6
6
  filterCurrentCodexModelIds,
@@ -336,4 +336,4 @@ export {
336
336
  setupProvider,
337
337
  createGracefulShutdown
338
338
  };
339
- //# sourceMappingURL=chunk-5SEYGOCH.js.map
339
+ //# sourceMappingURL=chunk-RDGGWMTI.js.map
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  CLI_VERSION
3
- } from "./chunk-YBUCXXYZ.js";
3
+ } from "./chunk-F5DCFAKI.js";
4
4
 
5
5
  // src/hq-publisher.ts
6
6
  import { createHqPublisherFromEnv, resolveHqConfig } from "@wrongstack/core/hq";
@@ -445,18 +445,15 @@ function hqExplicitlyDisabled(options) {
445
445
  return options.appConfig?.hq?.enabled === false;
446
446
  }
447
447
  function resolvedHqConnectionKey(options) {
448
- if (options.config !== void 0) {
449
- if (options.config.enabled === false) return void 0;
450
- return options.config.discover === true ? HQ_DISCOVERY_CONNECTION_KEY : `${options.config.url}
451
- ${options.config.token ?? ""}`;
452
- }
453
- const config = resolveHqConfig({ config: options.appConfig?.hq });
448
+ const config = options.config !== void 0 ? options.config.enabled === false ? void 0 : options.config : resolveHqConfig({ config: options.appConfig?.hq });
454
449
  if (config === void 0) return void 0;
455
- return config.discover === true ? HQ_DISCOVERY_CONNECTION_KEY : `${config.url}
450
+ const endpoint = config.discover === true ? HQ_DISCOVERY_CONNECTION_KEY : `${config.url}
456
451
  ${config.token ?? ""}`;
452
+ return `${endpoint}
453
+ raw=${String(config.rawContent)}`;
457
454
  }
458
455
  function startCliHqConnection(options) {
459
- const shouldOwnKanbanSync = options.onKanbanSnapshot === void 0;
456
+ const shouldOwnKanbanSync = options.ownKanbanSync !== false && options.onKanbanSnapshot === void 0;
460
457
  let kanbanSync;
461
458
  const publisherOptions = shouldOwnKanbanSync ? {
462
459
  ...options,
@@ -465,17 +462,32 @@ function startCliHqConnection(options) {
465
462
  let publisher;
466
463
  let publisherKey;
467
464
  let timer;
465
+ const liveOptions = () => options.getAppConfig === void 0 ? publisherOptions : { ...publisherOptions, appConfig: options.getAppConfig() };
466
+ const retire = () => {
467
+ if (publisher === void 0) return;
468
+ kanbanSync?.stop();
469
+ kanbanSync = void 0;
470
+ publisher.close();
471
+ publisher = void 0;
472
+ publisherKey = void 0;
473
+ options.onDisconnect?.();
474
+ };
468
475
  const tryConnect = () => {
469
- const nextKey = resolvedHqConnectionKey(options);
470
- if (nextKey === void 0) return;
476
+ const current = liveOptions();
477
+ const nextKey = resolvedHqConnectionKey(current);
478
+ if (nextKey === void 0) {
479
+ retire();
480
+ return;
481
+ }
471
482
  if (publisher !== void 0 && publisherKey === nextKey) {
472
- if (nextKey === HQ_DISCOVERY_CONNECTION_KEY) publisher.refreshEndpoint();
483
+ if (nextKey.startsWith(`${HQ_DISCOVERY_CONNECTION_KEY}
484
+ `)) publisher.refreshEndpoint();
473
485
  return;
474
486
  }
475
487
  publisher?.close();
476
488
  publisher = void 0;
477
489
  publisherKey = void 0;
478
- const next = createCliHqPublisher(publisherOptions);
490
+ const next = createCliHqPublisher(current);
479
491
  if (next === void 0) return;
480
492
  publisher = next;
481
493
  publisherKey = nextKey;
@@ -495,7 +507,7 @@ function startCliHqConnection(options) {
495
507
  options.onConnect?.(next);
496
508
  };
497
509
  tryConnect();
498
- if (!hqExplicitlyDisabled(options)) {
510
+ if (options.getAppConfig !== void 0 || !hqExplicitlyDisabled(options)) {
499
511
  timer = setInterval(tryConnect, options.retryIntervalMs ?? 2500);
500
512
  timer.unref?.();
501
513
  }
@@ -518,4 +530,4 @@ function startCliHqConnection(options) {
518
530
  export {
519
531
  startCliHqConnection
520
532
  };
521
- //# sourceMappingURL=chunk-BLD5DSVA.js.map
533
+ //# sourceMappingURL=chunk-RGFWGUAB.js.map
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  CLI_VERSION
3
- } from "./chunk-YBUCXXYZ.js";
3
+ } from "./chunk-F5DCFAKI.js";
4
4
 
5
5
  // src/update-check.ts
6
6
  import * as fs from "node:fs/promises";
@@ -144,7 +144,7 @@ async function checkForUpdate(signalOrOptions, legacyHomeFn) {
144
144
  };
145
145
  }
146
146
  try {
147
- const latest = packageName === "standalone-binary" ? await (await import("./standalone-update-MW47J3AK.js")).fetchLatestStandaloneVersion(3e3, signal) : await fetchLatestFromNpm(packageName, 3e3, signal);
147
+ const latest = packageName === "standalone-binary" ? await (await import("./standalone-update-LZO3MNLH.js")).fetchLatestStandaloneVersion(3e3, signal) : await fetchLatestFromNpm(packageName, 3e3, signal);
148
148
  await writeCache({ timestamp: Date.now(), latestVersion: latest, packageName }, hf);
149
149
  return {
150
150
  current,
@@ -183,4 +183,4 @@ export {
183
183
  checkForUpdate,
184
184
  getUpdateNotification
185
185
  };
186
- //# sourceMappingURL=chunk-ZZRSG7VK.js.map
186
+ //# sourceMappingURL=chunk-RZ4ZDRYA.js.map
@@ -12,8 +12,12 @@ function resolveRawProviderConnection(config, providerId) {
12
12
  const savedCfg = config.providers?.[providerId];
13
13
  const isAccountAlias = savedCfg?.type !== void 0 && savedCfg.type !== providerId;
14
14
  const inheritsPrimary = !isAccountAlias && (config.provider === void 0 || config.provider === providerId);
15
+ const repointed = Array.isArray(savedCfg?.envVars) && savedCfg.envVars.length === 0;
15
16
  return {
16
- apiKey: savedCfg?.apiKey ?? (inheritsPrimary ? config.apiKey : void 0),
17
+ // A repointed entry (`envVars: []` sentinel) must not inherit the legacy
18
+ // top-level key: `leader_model_set` could otherwise make it primary and
19
+ // carry that key to the new base URL (WS-2026-09-26-01).
20
+ apiKey: savedCfg?.apiKey ?? (inheritsPrimary && !repointed ? config.apiKey : void 0),
17
21
  baseUrl: savedCfg?.baseUrl ?? (inheritsPrimary ? config.baseUrl : void 0)
18
22
  };
19
23
  }
@@ -90,4 +94,4 @@ export {
90
94
  resolveProviderCfgWithProxy,
91
95
  buildProviderForId
92
96
  };
93
- //# sourceMappingURL=chunk-S4FFHDJG.js.map
97
+ //# sourceMappingURL=chunk-SDJCLEK6.js.map
@@ -2,6 +2,115 @@ import {
2
2
  theme
3
3
  } from "./chunk-QD544J2B.js";
4
4
 
5
+ // src/boot/tool-restriction-flags.ts
6
+ function parseToolList(flag, value) {
7
+ if (value === void 0) return void 0;
8
+ if (value === true || typeof value === "string" && !value.trim()) {
9
+ throw new Error(`--${flag} needs a comma-separated list of tool names`);
10
+ }
11
+ const names = String(value).split(/[\s,]+/).map((name) => name.trim()).filter(Boolean);
12
+ const scoped = names.find((name) => name.includes("("));
13
+ if (scoped) {
14
+ throw new Error(
15
+ `--${flag}: scoped rules like "${scoped}" are not supported; list whole tool names (exec policy lives in config tools.exec)`
16
+ );
17
+ }
18
+ return names;
19
+ }
20
+ function resolveLaunchAllowedTools(flags) {
21
+ return parseToolList("allowed-tools", flags["allowed-tools"]);
22
+ }
23
+ function resolveToolRestriction(flags) {
24
+ const only = parseToolList("only-tools", flags["only-tools"]);
25
+ const deny = parseToolList("disallowed-tools", flags["disallowed-tools"]);
26
+ if (only === void 0 && deny === void 0) return void 0;
27
+ return { ...only ? { only } : {}, deny: deny ?? [] };
28
+ }
29
+ function unknownRestrictedToolNames(restriction, isRegistered) {
30
+ return [...restriction.only ?? [], ...restriction.deny].filter(
31
+ (name) => !name.endsWith("*") && !name.includes("__") && !isRegistered(name)
32
+ );
33
+ }
34
+
35
+ // src/boot/restricted-mode.ts
36
+ import { lockToProjectRoot, lockYoloOff, ToolCapabilities } from "@wrongstack/core/security";
37
+ var RESTRICTED_ENV = "WRONGSTACK_RESTRICTED";
38
+ var RESTRICTED_DENY_CAPABILITIES = [
39
+ ToolCapabilities.SHELL_ARBITRARY,
40
+ ToolCapabilities.SHELL_RESTRICTED,
41
+ ToolCapabilities.SHELL_EXEC,
42
+ ToolCapabilities.NET_OUTBOUND,
43
+ ToolCapabilities.PACKAGE_INSTALL,
44
+ ToolCapabilities.CONFIG_MUTATE,
45
+ ToolCapabilities.FS_WRITE_OUTSIDE_PROJECT,
46
+ ToolCapabilities.TOOL_MUTATE_ANY,
47
+ ToolCapabilities.MCP_PROXY
48
+ ];
49
+ var CONFLICTING_FLAGS = [
50
+ "yolo",
51
+ "yolo-destructive",
52
+ "full-auto",
53
+ "mcp-config",
54
+ // Pre-approving a tool would let writes skip the prompt this mode promises.
55
+ "allowed-tools"
56
+ ];
57
+ function isRestrictedMode(flags) {
58
+ return flags["restricted"] === true || process.env[RESTRICTED_ENV] === "1";
59
+ }
60
+ function validateRestrictedMode(flags) {
61
+ if (!isRestrictedMode(flags)) return false;
62
+ const conflict = CONFLICTING_FLAGS.find(
63
+ (name) => flags[name] !== void 0 && flags[name] !== false
64
+ );
65
+ if (conflict) throw new Error(`--${conflict} cannot be combined with --restricted`);
66
+ return true;
67
+ }
68
+ function withRestrictedTools(restriction, restricted) {
69
+ if (!restricted) return restriction;
70
+ return {
71
+ ...restriction?.only ? { only: restriction.only } : {},
72
+ deny: [...restriction?.deny ?? [], "mcp__*"],
73
+ denyCapabilities: RESTRICTED_DENY_CAPABILITIES,
74
+ requireDeclaredCapabilities: true
75
+ };
76
+ }
77
+ var RESTRICTED_NOTICE = "Restricted mode: no shell, network, installs or MCP tools; files stay inside the project; YOLO is off.";
78
+ var announced = false;
79
+ function activateRestrictedMode(flags, write) {
80
+ if (!validateRestrictedMode(flags)) return false;
81
+ lockToProjectRoot();
82
+ lockYoloOff();
83
+ process.env[RESTRICTED_ENV] = "1";
84
+ if (!announced) {
85
+ announced = true;
86
+ write(`${RESTRICTED_NOTICE}
87
+ `);
88
+ }
89
+ return true;
90
+ }
91
+
92
+ // src/boot/safe-mode.ts
93
+ var SAFE_MODE_ENV = "WRONGSTACK_SAFE_MODE";
94
+ function isSafeMode(flags) {
95
+ return flags["safe-mode"] === true || process.env[SAFE_MODE_ENV] === "1";
96
+ }
97
+ function propagateSafeMode(flags) {
98
+ const on = isSafeMode(flags);
99
+ if (on) process.env[SAFE_MODE_ENV] = "1";
100
+ return on;
101
+ }
102
+ var SAFE_MODE_NOTICE = "Safe mode: third-party plugins, hooks, configured MCP servers, skills and instruction overrides are off.";
103
+ var announced2 = false;
104
+ function announceSafeMode(flags, write) {
105
+ const on = propagateSafeMode(flags);
106
+ if (on && !announced2) {
107
+ announced2 = true;
108
+ write(`${SAFE_MODE_NOTICE}
109
+ `);
110
+ }
111
+ return on;
112
+ }
113
+
5
114
  // src/diff-renderer.ts
6
115
  import { color, sanitizeTerminalText } from "@wrongstack/core/utils";
7
116
  function diffLineStyle(line) {
@@ -25,6 +134,15 @@ import {
25
134
  unifiedDiff,
26
135
  writeOut
27
136
  } from "@wrongstack/core/utils";
137
+ function makeHeadlessPromptDelegate(write = (text) => process.stderr.write(text)) {
138
+ return async (tool) => {
139
+ write(
140
+ `${theme.warn("\u26A0")} ${tool.name} needs approval but no terminal is attached to ask \u2014 denied. Grant it up front with --allowed-tools ${tool.name} or --yolo.
141
+ `
142
+ );
143
+ return "no";
144
+ };
145
+ }
28
146
  function makePromptDelegate(reader) {
29
147
  return async (tool, input, suggestedPattern, signal) => {
30
148
  if (signal?.aborted) return "no";
@@ -57,8 +175,11 @@ ${theme.warn("\u26A0 APPROVAL REQUIRED")} ${theme.primary("\u2502")} ${theme.bol
57
175
  return answer;
58
176
  };
59
177
  }
178
+ function makeStdinPromptDelegate(reader, stdinIsTTY = process.stdin.isTTY === true) {
179
+ return stdinIsTTY ? makePromptDelegate(reader) : makeHeadlessPromptDelegate();
180
+ }
60
181
  function makeConfirmAwaiter(reader) {
61
- const delegate = makePromptDelegate(reader);
182
+ const delegate = makeStdinPromptDelegate(reader);
62
183
  return async (tool, input, _toolUseId, suggestedPattern) => {
63
184
  const result = await delegate(tool, input, suggestedPattern);
64
185
  return result;
@@ -470,12 +591,20 @@ on disconnect with exponential backoff, up to 3 attempts"._
470
591
 
471
592
  export {
472
593
  renderDiff,
473
- makePromptDelegate,
594
+ makeStdinPromptDelegate,
474
595
  makeConfirmAwaiter,
596
+ resolveLaunchAllowedTools,
597
+ resolveToolRestriction,
598
+ unknownRestrictedToolNames,
599
+ isRestrictedMode,
600
+ withRestrictedTools,
601
+ activateRestrictedMode,
602
+ isSafeMode,
603
+ announceSafeMode,
475
604
  isSimpleUiFullAuto,
476
605
  applySimpleUiFullAutoProfile,
477
606
  configureSimpleUiRuntimeContext,
478
607
  detectProjectFacts,
479
608
  renderAgentsTemplate
480
609
  };
481
- //# sourceMappingURL=chunk-U46QR4WR.js.map
610
+ //# sourceMappingURL=chunk-TI7KLHYX.js.map