@wrongstack/cli 1.1.2 → 1.1.5

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 (117) hide show
  1. package/dist/{acp-HCGUTFNE.js → acp-NKUEYJDZ.js} +14 -5
  2. package/dist/acp-leader/acp-leader-confirm.d.ts +20 -0
  3. package/dist/acp-leader/acp-leader-context.d.ts +29 -0
  4. package/dist/acp-leader/acp-leader-fleet.d.ts +26 -0
  5. package/dist/acp-leader/acp-leader-host-binding.d.ts +17 -0
  6. package/dist/acp-leader/acp-leader-host.d.ts +82 -0
  7. package/dist/acp-leader/acp-leader-picker.d.ts +24 -0
  8. package/dist/acp-leader/acp-leader-provider.d.ts +85 -0
  9. package/dist/acp-leader/acp-leader-resume.d.ts +10 -0
  10. package/dist/acp-leader/acp-leader-stream.d.ts +83 -0
  11. package/dist/{auth-ANOVZVHE.js → auth-2ZG5DBHS.js} +62 -66
  12. package/dist/auth-menu/index.d.ts +1 -2
  13. package/dist/boot/dispatch-webui.d.ts +16 -0
  14. package/dist/boot/launch-menu-arrow.d.ts +20 -0
  15. package/dist/boot/launch-menu-types.d.ts +36 -0
  16. package/dist/boot/launch-menu.d.ts +1 -57
  17. package/dist/boot/tui-session-resume-rollback.d.ts +31 -0
  18. package/dist/{boot-auto-thin-7D4OVEWA.js → boot-auto-thin-N2CIGTXE.js} +3 -3
  19. package/dist/{chunk-TZPKOS5G.js → chunk-2XQ6SRKG.js} +2 -2
  20. package/dist/chunk-3LEIFO5D.js +65 -0
  21. package/dist/chunk-5SGMUDP5.js +752 -0
  22. package/dist/{chunk-3EXRPTAU.js → chunk-5TQ65PXQ.js} +17 -17
  23. package/dist/{chunk-GRAGMA4B.js → chunk-7BM4LGKQ.js} +18 -18
  24. package/dist/{chunk-VAQXOZKP.js → chunk-AJM4EFCM.js} +139 -136
  25. package/dist/{chunk-C2BBH4S4.js → chunk-E3MJFAFR.js} +2 -2
  26. package/dist/{chunk-5TRZZHMN.js → chunk-JCZ2D3VV.js} +4 -65
  27. package/dist/{chunk-AWRZWPJ3.js → chunk-JFYQGMMM.js} +99 -75
  28. package/dist/{chunk-BIGSVBPI.js → chunk-KNYIEQAY.js} +64 -61
  29. package/dist/chunk-LUEO5HLZ.js +50 -0
  30. package/dist/chunk-LYWOV4OX.js +252 -0
  31. package/dist/chunk-M7FNHCE3.js +2070 -0
  32. package/dist/{chunk-75OLD563.js → chunk-M7PSENGF.js} +3 -1
  33. package/dist/{chunk-NMXQFQ26.js → chunk-MEBXWI7U.js} +5 -5
  34. package/dist/{chunk-RAWHRRUJ.js → chunk-MKMM5RIW.js} +209 -201
  35. package/dist/{chunk-3R3OADC5.js → chunk-P7MEEUGT.js} +281 -252
  36. package/dist/chunk-QLYPIJ7X.js +258 -0
  37. package/dist/chunk-RN5CFAVQ.js +292 -0
  38. package/dist/{chunk-WDXNBYGD.js → chunk-TDP7CZGE.js} +6 -1
  39. package/dist/{chunk-6VPWQ4TG.js → chunk-UROB7MK5.js} +2 -1
  40. package/dist/chunk-VEESMPTX.js +254 -0
  41. package/dist/{chunk-IJLIAPCW.js → chunk-VPSAKGLK.js} +47 -47
  42. package/dist/{cli-context-YIT4FEDM.js → cli-context-CQYGIWOU.js} +254 -237
  43. package/dist/{cli-main-JIADJ5OL.js → cli-main-VRUJNUBX.js} +2081 -1594
  44. package/dist/cli-main-boot.d.ts +1 -1
  45. package/dist/config-doctor-known-keys.d.ts +33 -0
  46. package/dist/config-doctor.d.ts +2 -47
  47. package/dist/config-history-support.d.ts +36 -0
  48. package/dist/config-history.d.ts +1 -1
  49. package/dist/{config-transfer-Y7XJMJRN.js → config-transfer-B4GOZTFC.js} +2 -2
  50. package/dist/{execution-BAP566QC.js → execution-IV72RUSM.js} +5354 -5258
  51. package/dist/execution-tui.d.ts +30 -0
  52. package/dist/fleet/acp-live-steer.d.ts +28 -0
  53. package/dist/fleet/acp-permission-bridge.d.ts +49 -0
  54. package/dist/fleet/acp-quota-hold.d.ts +3 -0
  55. package/dist/fleet/acp-quota-reading.d.ts +3 -0
  56. package/dist/fleet/acp-turn-reminders.d.ts +15 -0
  57. package/dist/fleet/acp-wrongstack-bridge.d.ts +50 -0
  58. package/dist/fleet/host-acp.d.ts +23 -2
  59. package/dist/fleet/wrongforge-client.d.ts +116 -0
  60. package/dist/fleet/wrongforge-gateway.d.ts +20 -0
  61. package/dist/fleet/wrongforge-info.d.ts +32 -0
  62. package/dist/fleet/wrongforge-quota.d.ts +10 -0
  63. package/dist/fleet/wrongforge-runner.d.ts +37 -0
  64. package/dist/fleet/wrongforge-runtime.d.ts +10 -0
  65. package/dist/{hq-JD5AZVMG.js → hq-54PQYR5O.js} +311 -307
  66. package/dist/hq-server/sweeps.d.ts +28 -0
  67. package/dist/{hq-server-BI23EPM7.js → hq-server-YK7FBLL6.js} +3 -3
  68. package/dist/index.js +8 -5
  69. package/dist/mcp-22CFBX4H.js +236 -0
  70. package/dist/mcp-serve-project.d.ts +18 -0
  71. package/dist/mcp-serve.d.ts +0 -63
  72. package/dist/{modeldiag-HDIKG37X.js → modeldiag-5PBB777J.js} +4 -4
  73. package/dist/{per-subcommand-help-D6J4ZXW2.js → per-subcommand-help-MQGERD4E.js} +2 -2
  74. package/dist/plugin-llm-command.d.ts +9 -0
  75. package/dist/{plugin-usage-TYF5HY4K.js → plugin-usage-UWKYMNQU.js} +3 -3
  76. package/dist/{plugins-XGAXDLPT.js → plugins-VP7JQH47.js} +4 -4
  77. package/dist/{sdd-runtime-6MFUXWJK.js → sdd-runtime-HIJ4Z5TF.js} +2 -2
  78. package/dist/services/sdd/state.d.ts +2 -0
  79. package/dist/session-event-wiring-types.d.ts +62 -0
  80. package/dist/session-event-wiring.d.ts +2 -52
  81. package/dist/{sessions-config-SJVQXCIE.js → sessions-config-7MK742OW.js} +2 -2
  82. package/dist/short-circuit-flags-AGHURHMQ.js +11 -0
  83. package/dist/slash-commands/command-context-fleet.d.ts +187 -0
  84. package/dist/slash-commands/command-context-sdd-goal.d.ts +102 -0
  85. package/dist/slash-commands/command-context.d.ts +3 -282
  86. package/dist/slash-commands/project-switch-interactive.d.ts +11 -0
  87. package/dist/slash-commands/setmodel-helpers.d.ts +36 -0
  88. package/dist/subcommands/handlers/hq-token.d.ts +3 -0
  89. package/dist/subcommands/handlers/hq.d.ts +0 -21
  90. package/dist/subcommands/handlers/per-subcommand-help-operations.d.ts +8 -0
  91. package/dist/subcommands/handlers/tools-cli-args.d.ts +57 -0
  92. package/dist/subcommands/handlers/tools-cli.d.ts +5 -0
  93. package/dist/subcommands/handlers/tools-serve.d.ts +4 -0
  94. package/dist/{subcommands-VTMIZQBP.js → subcommands-OCJNO57E.js} +2 -2
  95. package/dist/tool-gateway-http.d.ts +30 -0
  96. package/dist/tool-gateway.d.ts +185 -0
  97. package/dist/tools-cli-44MLIUQO.js +509 -0
  98. package/dist/tools-serve-TRCET2M7.js +102 -0
  99. package/dist/{tools-skills-55QVTMSK.js → tools-skills-WDTMCE46.js} +7 -2
  100. package/dist/tuneup-runtime-checks.d.ts +7 -0
  101. package/dist/tuneup-types.d.ts +118 -0
  102. package/dist/tuneup.d.ts +3 -122
  103. package/dist/{typesafe-YBEADNAH.js → typesafe-QLSMFU7J.js} +1 -1
  104. package/dist/{version-help-RBZC5GZZ.js → version-help-X6CC4CFY.js} +2 -2
  105. package/dist/{webui-server-HIUY3RHD.js → webui-server-V2R5WQUK.js} +79 -3
  106. package/dist/wiring/provider-runtime-setup.d.ts +3 -1
  107. package/dist/wiring/session-runtime.d.ts +1 -1
  108. package/dist/wrongforge-gateway-UOFBK56J.js +92 -0
  109. package/dist/wrongforge-leader/wrongforge-leader-gateway.d.ts +9 -0
  110. package/dist/wrongforge-leader/wrongforge-leader-picker.d.ts +12 -0
  111. package/dist/wrongforge-leader/wrongforge-leader-provider.d.ts +49 -0
  112. package/package.json +34 -30
  113. package/dist/auth-menu/anthropic-oauth.d.ts +0 -43
  114. package/dist/chunk-XT3NAHRX.js +0 -337
  115. package/dist/chunk-ZNNFEKDZ.js +0 -319
  116. package/dist/mcp-2XWBJEQN.js +0 -464
  117. package/dist/short-circuit-flags-CPCT5MWB.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