@wrongstack/cli 1.1.4 → 1.1.6

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 (103) hide show
  1. package/dist/{acp-MZ5MQBFN.js → acp-CZBSFQB7.js} +6 -5
  2. package/dist/acp-leader/acp-leader-confirm.d.ts +2 -0
  3. package/dist/acp-leader/acp-leader-host-binding.d.ts +1 -0
  4. package/dist/acp-leader/acp-leader-host.d.ts +9 -0
  5. package/dist/acp-leader/acp-leader-picker.d.ts +6 -3
  6. package/dist/acp-leader/acp-leader-provider.d.ts +10 -0
  7. package/dist/acp-leader/acp-leader-skills.d.ts +5 -0
  8. package/dist/acp-leader/acp-leader-stream.d.ts +9 -0
  9. package/dist/{auth-IHQS6AFW.js → auth-2ZG5DBHS.js} +4 -4
  10. package/dist/boot/launch-menu-arrow.d.ts +20 -0
  11. package/dist/boot/launch-menu-types.d.ts +36 -0
  12. package/dist/boot/launch-menu.d.ts +1 -57
  13. package/dist/boot/tui-session-resume-rollback.d.ts +31 -0
  14. package/dist/{boot-auto-thin-7D4OVEWA.js → boot-auto-thin-N2CIGTXE.js} +3 -3
  15. package/dist/{chunk-TZPKOS5G.js → chunk-2XQ6SRKG.js} +2 -2
  16. package/dist/{chunk-3EXRPTAU.js → chunk-5TQ65PXQ.js} +17 -17
  17. package/dist/{chunk-VAQXOZKP.js → chunk-AJM4EFCM.js} +139 -136
  18. package/dist/{chunk-C2BBH4S4.js → chunk-E3MJFAFR.js} +2 -2
  19. package/dist/{chunk-COGI7EQU.js → chunk-EAATL6FL.js} +713 -21
  20. package/dist/{chunk-AWRZWPJ3.js → chunk-FWUIKCCO.js} +152 -123
  21. package/dist/{chunk-TAE3EGBM.js → chunk-H5DCQFUI.js} +5 -5
  22. package/dist/{chunk-BIGSVBPI.js → chunk-KNYIEQAY.js} +64 -61
  23. package/dist/chunk-LYWOV4OX.js +252 -0
  24. package/dist/{chunk-75OLD563.js → chunk-M7PSENGF.js} +3 -1
  25. package/dist/{chunk-I5LJLKA3.js → chunk-MKMM5RIW.js} +12 -5
  26. package/dist/{chunk-ZF4HRR5F.js → chunk-P7MEEUGT.js} +275 -250
  27. package/dist/chunk-PGC44T7N.js +255 -0
  28. package/dist/chunk-QLYPIJ7X.js +258 -0
  29. package/dist/{chunk-JKTJSLUT.js → chunk-QRWXHGLB.js} +242 -18
  30. package/dist/chunk-RN5CFAVQ.js +292 -0
  31. package/dist/{chunk-WDXNBYGD.js → chunk-TDP7CZGE.js} +6 -1
  32. package/dist/{chunk-6VPWQ4TG.js → chunk-UROB7MK5.js} +2 -1
  33. package/dist/{chunk-IJLIAPCW.js → chunk-VPSAKGLK.js} +47 -47
  34. package/dist/{chunk-2LTHDKZX.js → chunk-W7X23HI6.js} +18 -18
  35. package/dist/{chunk-GKGWPFW2.js → chunk-X4DEQLAZ.js} +1 -1
  36. package/dist/{cli-context-E44HQ4ZO.js → cli-context-6KS3HV5R.js} +247 -236
  37. package/dist/{cli-main-OT63I2FX.js → cli-main-NF3YGDME.js} +1779 -1494
  38. package/dist/cli-main-boot.d.ts +1 -1
  39. package/dist/config-doctor-known-keys.d.ts +33 -0
  40. package/dist/config-doctor.d.ts +2 -47
  41. package/dist/config-history-support.d.ts +36 -0
  42. package/dist/config-history.d.ts +1 -1
  43. package/dist/{config-transfer-Y7XJMJRN.js → config-transfer-B4GOZTFC.js} +2 -2
  44. package/dist/{execution-OK34CJKJ.js → execution-RVDUXLNT.js} +6522 -6426
  45. package/dist/execution-tui.d.ts +30 -0
  46. package/dist/fleet/acp-wrongstack-bridge.d.ts +11 -3
  47. package/dist/fleet/host-acp.d.ts +3 -0
  48. package/dist/fleet/wrongforge-client.d.ts +116 -0
  49. package/dist/fleet/wrongforge-gateway.d.ts +20 -0
  50. package/dist/fleet/wrongforge-info.d.ts +32 -0
  51. package/dist/fleet/wrongforge-quota.d.ts +10 -0
  52. package/dist/fleet/wrongforge-runner.d.ts +37 -0
  53. package/dist/fleet/wrongforge-runtime.d.ts +10 -0
  54. package/dist/{hq-JD5AZVMG.js → hq-V2M4IYCI.js} +320 -306
  55. package/dist/hq-server/login-attempt-store.d.ts +2 -0
  56. package/dist/hq-server/sweeps.d.ts +28 -0
  57. package/dist/{hq-server-BI23EPM7.js → hq-server-QM7EIVGJ.js} +3 -3
  58. package/dist/index.js +5 -5
  59. package/dist/mcp-22CFBX4H.js +236 -0
  60. package/dist/mcp-serve.d.ts +0 -63
  61. package/dist/{modeldiag-HDIKG37X.js → modeldiag-5PBB777J.js} +4 -4
  62. package/dist/{per-subcommand-help-4GYSCMLU.js → per-subcommand-help-MQGERD4E.js} +2 -2
  63. package/dist/plugin-llm-command.d.ts +9 -0
  64. package/dist/{plugin-usage-TYF5HY4K.js → plugin-usage-UWKYMNQU.js} +3 -3
  65. package/dist/{plugins-XGAXDLPT.js → plugins-VP7JQH47.js} +4 -4
  66. package/dist/{sdd-runtime-6MFUXWJK.js → sdd-runtime-HIJ4Z5TF.js} +2 -2
  67. package/dist/services/sdd/state.d.ts +2 -0
  68. package/dist/session-event-wiring-types.d.ts +62 -0
  69. package/dist/session-event-wiring.d.ts +2 -52
  70. package/dist/{sessions-config-SJVQXCIE.js → sessions-config-7MK742OW.js} +2 -2
  71. package/dist/short-circuit-flags-276OLPIN.js +11 -0
  72. package/dist/slash-commands/command-context-fleet.d.ts +187 -0
  73. package/dist/slash-commands/command-context-sdd-goal.d.ts +102 -0
  74. package/dist/slash-commands/command-context.d.ts +3 -282
  75. package/dist/slash-commands/project-switch-interactive.d.ts +11 -0
  76. package/dist/slash-commands/setmodel-helpers.d.ts +36 -0
  77. package/dist/subcommands/handlers/hq-token.d.ts +3 -0
  78. package/dist/subcommands/handlers/hq.d.ts +0 -21
  79. package/dist/subcommands/handlers/per-subcommand-help-operations.d.ts +8 -0
  80. package/dist/subcommands/handlers/tools-cli-args.d.ts +57 -0
  81. package/dist/subcommands/handlers/tools-cli.d.ts +5 -0
  82. package/dist/subcommands/handlers/tools-serve.d.ts +4 -0
  83. package/dist/{subcommands-YADUV7IJ.js → subcommands-SKJPUJ7N.js} +2 -2
  84. package/dist/tool-gateway-http.d.ts +30 -0
  85. package/dist/tool-gateway.d.ts +185 -0
  86. package/dist/tools-cli-44MLIUQO.js +509 -0
  87. package/dist/tools-serve-TRCET2M7.js +102 -0
  88. package/dist/{tools-skills-55QVTMSK.js → tools-skills-WDTMCE46.js} +7 -2
  89. package/dist/tuneup-runtime-checks.d.ts +7 -0
  90. package/dist/tuneup-types.d.ts +118 -0
  91. package/dist/tuneup.d.ts +3 -122
  92. package/dist/{typesafe-YBEADNAH.js → typesafe-QLSMFU7J.js} +1 -1
  93. package/dist/{version-help-RBZC5GZZ.js → version-help-X6CC4CFY.js} +2 -2
  94. package/dist/{webui-server-CB64CFDG.js → webui-server-6I6QOECV.js} +44 -6
  95. package/dist/wiring/provider-runtime-setup.d.ts +3 -1
  96. package/dist/wiring/session-runtime.d.ts +1 -1
  97. package/dist/wrongforge-gateway-UOFBK56J.js +92 -0
  98. package/dist/wrongforge-leader/wrongforge-leader-gateway.d.ts +9 -0
  99. package/dist/wrongforge-leader/wrongforge-leader-picker.d.ts +12 -0
  100. package/dist/wrongforge-leader/wrongforge-leader-provider.d.ts +56 -0
  101. package/package.json +1 -1
  102. package/dist/mcp-W7A5HUXV.js +0 -560
  103. package/dist/short-circuit-flags-QEXUS3BY.js +0 -11
@@ -0,0 +1,252 @@
1
+
2
+ // src/tool-gateway.ts
3
+ import { Context } from "@wrongstack/core/agent";
4
+ import { ToolExecutor } from "@wrongstack/core/execution";
5
+ import { ToolRegistry } from "@wrongstack/core/registry";
6
+ import {
7
+ AutoApprovePermissionPolicy,
8
+ DefaultSecretScrubber,
9
+ ToolCapabilities
10
+ } from "@wrongstack/core/security";
11
+ import { normalizeTokenSavingTier } from "@wrongstack/core/types";
12
+ import { toErrorMessage } from "@wrongstack/core/utils";
13
+ import { systemSessionId } from "@wrongstack/primitives";
14
+ import { wireKanbanPorts } from "@wrongstack/runtime";
15
+ import { BROWSER_TOOL_NAMES } from "@wrongstack/tools/browser";
16
+ import { runStartupIndex, shutdownCodebaseIndexHost } from "@wrongstack/tools/codebase-index";
17
+ import { registerBuiltinToolTier } from "@wrongstack/tools/tool-tier";
18
+ function resolveGatewayRegistry(existing, config) {
19
+ wireKanbanPorts();
20
+ if (existing) return existing;
21
+ const registry = new ToolRegistry();
22
+ registerBuiltinToolTier({
23
+ registry,
24
+ tier: normalizeTokenSavingTier(config.features.tokenSavingMode)
25
+ });
26
+ return registry;
27
+ }
28
+ var READ_ONLY_CAPABILITIES = [
29
+ ToolCapabilities.FS_READ,
30
+ ToolCapabilities.NET_OUTBOUND
31
+ ];
32
+ function parseCapabilityGrants(raw) {
33
+ if (raw === void 0 || raw === false) return [];
34
+ if (raw === true || raw.trim() === "") {
35
+ throw new Error(
36
+ `--allow needs a comma-separated capability list, e.g. --allow fs.write (known: ${knownCapabilities()})`
37
+ );
38
+ }
39
+ const known = new Set(Object.values(ToolCapabilities));
40
+ const grants = raw.split(",").map((s) => s.trim()).filter(Boolean);
41
+ const unknown = grants.filter((g) => !known.has(g));
42
+ if (unknown.length > 0) {
43
+ throw new Error(
44
+ `--allow: unknown capability ${unknown.map((u) => `"${u}"`).join(", ")} (known: ${knownCapabilities()})`
45
+ );
46
+ }
47
+ return [...new Set(grants)];
48
+ }
49
+ function knownCapabilities() {
50
+ return Object.values(ToolCapabilities).join(", ");
51
+ }
52
+ function yoloServePolicy(yoloPlus) {
53
+ return new AutoApprovePermissionPolicy(
54
+ Object.values(ToolCapabilities),
55
+ yoloPlus ? { yoloPlus } : void 0
56
+ );
57
+ }
58
+ function resolveServeFsRestriction(config) {
59
+ return config.tools?.restrictToProjectRoot ?? true;
60
+ }
61
+ var GATEWAY_SESSION_ID = systemSessionId("tool-gateway");
62
+ function makeServeContext(cwd, projectRoot, signal, restrictFsToRoot = true) {
63
+ const provider = {
64
+ id: "mcp-serve",
65
+ capabilities: { maxContext: 0 },
66
+ complete: async () => {
67
+ throw new Error("no model provider in tool-gateway mode");
68
+ },
69
+ stream: () => {
70
+ throw new Error("no model provider in tool-gateway mode");
71
+ }
72
+ };
73
+ const session = {
74
+ id: GATEWAY_SESSION_ID,
75
+ append: async () => {
76
+ }
77
+ };
78
+ const tokenCounter = {
79
+ account: () => {
80
+ },
81
+ total: () => ({ input: 0, output: 0 }),
82
+ estimateCost: () => ({ total: 0 })
83
+ };
84
+ return new Context({
85
+ systemPrompt: [],
86
+ provider,
87
+ session,
88
+ signal,
89
+ tokenCounter,
90
+ cwd,
91
+ projectRoot,
92
+ allowOutsideProjectRoot: !restrictFsToRoot,
93
+ model: "mcp-serve",
94
+ tools: []
95
+ });
96
+ }
97
+ async function selectExposedTools(registry, ctx, policy, whitelist) {
98
+ const allowed = [];
99
+ for (const tool of registry.list()) {
100
+ if (whitelist && !whitelist.has(tool.name)) continue;
101
+ const decision = await policy.evaluate(tool, {}, ctx);
102
+ if (decision.permission === "auto") allowed.push(tool);
103
+ }
104
+ return allowed;
105
+ }
106
+ var SESSION_BOUND_TOOL_NAMES = /* @__PURE__ */ new Set([
107
+ "clarify",
108
+ "tool_use",
109
+ "tool_script",
110
+ "tool_search",
111
+ "present_artifact",
112
+ "todo",
113
+ "plan"
114
+ ]);
115
+ var PROCESS_BOUND_TOOL_NAMES = new Set(BROWSER_TOOL_NAMES);
116
+ var INDEX_READING_TOOL_NAMES = /* @__PURE__ */ new Set([
117
+ "codebase-search",
118
+ "codebase-context",
119
+ "codebase-impact-analysis",
120
+ "codebase-incoming-calls",
121
+ "codebase-outgoing-calls",
122
+ "codebase-repo-map",
123
+ "codebase-stats"
124
+ ]);
125
+ var REMOTE_CATCH_UP_INTERVAL_MS = 1e3;
126
+ function readsCodebaseIndex(name) {
127
+ return INDEX_READING_TOOL_NAMES.has(name);
128
+ }
129
+ function oneShotWithholdReason(name) {
130
+ if (SESSION_BOUND_TOOL_NAMES.has(name)) return "session";
131
+ if (PROCESS_BOUND_TOOL_NAMES.has(name)) return "process";
132
+ return void 0;
133
+ }
134
+ function withheldReason(gateway, registry, name) {
135
+ const bound = gateway.withheldBy(name);
136
+ if (bound === "session") {
137
+ return `Tool "${name}" only works inside an agent session and is not exposed here.`;
138
+ }
139
+ if (bound === "process") {
140
+ return `Tool "${name}" keeps its state in a long-lived process; use \`wstack mcp serve\` or \`wstack tools serve\` for it.`;
141
+ }
142
+ const tool = registry.get(name);
143
+ if (!tool) return `Unknown tool "${name}". List the exposed tools first.`;
144
+ const missing = (tool.capabilities ?? []).filter((c) => !gateway.capabilities.includes(c));
145
+ return gateway.mode === "yolo" || missing.length === 0 ? `Tool "${name}" is withheld by policy.` : `Tool "${name}" is withheld: it needs ${missing.join(", ")}. Pass --allow ${missing.join(",")} (or --yolo for every capability); deleting outside the project, git-history and download-and-run commands stay refused.`;
146
+ }
147
+ async function createToolGateway(options) {
148
+ const { registry, config, cwd, projectRoot } = options;
149
+ const restrictFsToRoot = resolveServeFsRestriction(config);
150
+ const controller = new AbortController();
151
+ const grants = options.yolo ? [] : [...new Set(options.allow ?? [])];
152
+ const mode = options.yolo ? "yolo" : grants.length > 0 ? "granted" : "safe";
153
+ const capabilities = options.yolo ? Object.values(ToolCapabilities) : [.../* @__PURE__ */ new Set([...READ_ONLY_CAPABILITIES, ...grants])];
154
+ const permissionPolicy = options.yolo ? yoloServePolicy(options.yoloPlus) : new AutoApprovePermissionPolicy(capabilities);
155
+ const executor = new ToolExecutor(registry, {
156
+ permissionPolicy,
157
+ secretScrubber: new DefaultSecretScrubber(),
158
+ maxToolTimeoutMs: config.tools?.maxToolTimeoutMs ?? 3e5,
159
+ perIterationOutputCapBytes: 1e6,
160
+ // Kanban tracks work; it does not gate it. Off unless the operator opts in.
161
+ // See wiring/pipeline.ts for why all four hosts must agree.
162
+ requireKanbanGovernance: config.tools?.kanbanGovernance ?? false
163
+ });
164
+ const selectionCtx = makeServeContext(cwd, projectRoot, controller.signal, restrictFsToRoot);
165
+ const selected = await selectExposedTools(
166
+ registry,
167
+ selectionCtx,
168
+ permissionPolicy,
169
+ options.whitelist
170
+ );
171
+ const withheld = (name) => {
172
+ const reason = oneShotWithholdReason(name);
173
+ if (options.oneShot) return reason !== void 0;
174
+ if (options.remoteAgent) return reason === "session";
175
+ return false;
176
+ };
177
+ const tools = selected.filter((t) => !withheld(t.name));
178
+ const byName = new Map(tools.map((t) => [t.name, t]));
179
+ const catchUpIndex = options.catchUpIndex ?? (async (root, signal) => {
180
+ await runStartupIndex({ projectRoot: root, signal });
181
+ });
182
+ let indexCurrent = false;
183
+ let lastCatchUpAt = 0;
184
+ let catchUpInFlight;
185
+ const runCatchUp = async () => {
186
+ try {
187
+ await catchUpIndex(projectRoot, controller.signal);
188
+ } catch (err) {
189
+ options.onWarning?.(`codebase index catch-up failed: ${toErrorMessage(err)}`);
190
+ } finally {
191
+ indexCurrent = true;
192
+ lastCatchUpAt = Date.now();
193
+ catchUpInFlight = void 0;
194
+ }
195
+ };
196
+ const indexNeedsCatchUp = () => {
197
+ if (options.oneShot) return !indexCurrent;
198
+ if (options.remoteAgent) return Date.now() - lastCatchUpAt >= REMOTE_CATCH_UP_INTERVAL_MS;
199
+ return false;
200
+ };
201
+ let counter = 0;
202
+ return {
203
+ mode,
204
+ capabilities,
205
+ projectRoot,
206
+ tools,
207
+ get: (name) => byName.get(name),
208
+ withheldBy: (name) => withheld(name) ? oneShotWithholdReason(name) : void 0,
209
+ async call(name, input, callOptions) {
210
+ const tool = byName.get(name);
211
+ if (!tool) return { kind: "not_exposed" };
212
+ if (readsCodebaseIndex(name) && (catchUpInFlight || indexNeedsCatchUp())) {
213
+ catchUpInFlight ??= runCatchUp();
214
+ await catchUpInFlight;
215
+ }
216
+ if (tool.mutating) indexCurrent = false;
217
+ const use = { type: "tool_use", id: `srv_${++counter}`, name, input };
218
+ const requestCtx = makeServeContext(
219
+ callOptions?.cwd ?? cwd,
220
+ projectRoot,
221
+ controller.signal,
222
+ restrictFsToRoot
223
+ );
224
+ const batch = await executor.executeBatch([use], requestCtx, "sequential");
225
+ const output = batch.outputs[0];
226
+ const result = output?.result;
227
+ if (!output || !result || result.type === "tool_confirm_pending") {
228
+ return { kind: "confirm_required" };
229
+ }
230
+ const isError = Boolean(result.is_error);
231
+ return {
232
+ kind: "result",
233
+ content: result.content,
234
+ isError,
235
+ settlement: output.settlement ?? (isError ? "failed" : "completed"),
236
+ durationMs: output.durationMs
237
+ };
238
+ },
239
+ async close() {
240
+ controller.abort();
241
+ await shutdownCodebaseIndexHost();
242
+ }
243
+ };
244
+ }
245
+
246
+ export {
247
+ resolveGatewayRegistry,
248
+ parseCapabilityGrants,
249
+ withheldReason,
250
+ createToolGateway
251
+ };
252
+ //# sourceMappingURL=chunk-LYWOV4OX.js.map
@@ -115,6 +115,8 @@ var BOOLEAN_FLAGS = /* @__PURE__ */ new Set([
115
115
  // boolean at every call site, and leaving it out let it consume the next
116
116
  // positional — on a command whose whole purpose is to NOT delete.
117
117
  "dry-run",
118
+ // `wstack tools serve --allow-remote-callbacks`: a switch, never a value.
119
+ "allow-remote-callbacks",
118
120
  // Subcommand booleans. A boolean flag missing from this set makes `parseArgs`
119
121
  // swallow the FOLLOWING positional as its value (`rewind --all sess123` lost
120
122
  // the session id, `export --no-tools out.md` lost the output path), on top of
@@ -311,4 +313,4 @@ export {
311
313
  parseAuthFlags,
312
314
  parseSpawnFlags
313
315
  };
314
- //# sourceMappingURL=chunk-75OLD563.js.map
316
+ //# sourceMappingURL=chunk-M7PSENGF.js.map
@@ -16,7 +16,7 @@ import {
16
16
  import {
17
17
  appendHistory,
18
18
  backupCurrent
19
- } from "./chunk-BIGSVBPI.js";
19
+ } from "./chunk-KNYIEQAY.js";
20
20
  import {
21
21
  openBrowser
22
22
  } from "./chunk-BCKVNORU.js";
@@ -1854,9 +1854,16 @@ ${color9.bold("Custom provider")} ${color9.dim("\u2014 for local models or proxi
1854
1854
  type = nextCustomProviderId(Object.keys(providersNow));
1855
1855
  deps.renderer.write(` ${color9.dim("Using generated id:")} ${color9.bold(type)}
1856
1856
  `);
1857
- } else if (providersNow[type]) {
1858
- deps.renderer.writeWarning(`"${type}" already exists. Pick it from the main menu to edit.`);
1859
- return false;
1857
+ } else {
1858
+ const idError = authProfileAliasError2(type);
1859
+ if (idError) {
1860
+ deps.renderer.writeError(idError);
1861
+ return false;
1862
+ }
1863
+ if (providersNow[type]) {
1864
+ deps.renderer.writeWarning(`"${type}" already exists. Pick it from the main menu to edit.`);
1865
+ return false;
1866
+ }
1860
1867
  }
1861
1868
  const familyRaw = (await deps.reader.readLine(
1862
1869
  ` ${color9.amber("?")} Wire family ${color9.dim("(anthropic | openai | openai-compatible | google)")} ${color9.dim("(q to quit)")}: `
@@ -2025,4 +2032,4 @@ export {
2025
2032
  addCustomProvider,
2026
2033
  addKeyForProvider
2027
2034
  };
2028
- //# sourceMappingURL=chunk-I5LJLKA3.js.map
2035
+ //# sourceMappingURL=chunk-MKMM5RIW.js.map