@wrongstack/cli 1.1.1 → 1.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{acp-HCGUTFNE.js → acp-MZ5MQBFN.js} +13 -5
- package/dist/acp-leader/acp-leader-confirm.d.ts +18 -0
- package/dist/acp-leader/acp-leader-context.d.ts +29 -0
- package/dist/acp-leader/acp-leader-fleet.d.ts +26 -0
- package/dist/acp-leader/acp-leader-host-binding.d.ts +16 -0
- package/dist/acp-leader/acp-leader-host.d.ts +80 -0
- package/dist/acp-leader/acp-leader-picker.d.ts +21 -0
- package/dist/acp-leader/acp-leader-provider.d.ts +85 -0
- package/dist/acp-leader/acp-leader-resume.d.ts +10 -0
- package/dist/acp-leader/acp-leader-stream.d.ts +82 -0
- package/dist/{auth-ANOVZVHE.js → auth-IHQS6AFW.js} +60 -64
- package/dist/auth-menu/index.d.ts +1 -2
- package/dist/boot/dispatch-webui.d.ts +16 -0
- package/dist/{chunk-GRAGMA4B.js → chunk-2LTHDKZX.js} +4 -4
- package/dist/chunk-3LEIFO5D.js +65 -0
- package/dist/chunk-COGI7EQU.js +1458 -0
- package/dist/chunk-GKGWPFW2.js +50 -0
- package/dist/{chunk-RAWHRRUJ.js → chunk-I5LJLKA3.js} +198 -197
- package/dist/{chunk-5TRZZHMN.js → chunk-JCZ2D3VV.js} +4 -65
- package/dist/{chunk-XT3NAHRX.js → chunk-JKTJSLUT.js} +192 -1
- package/dist/{chunk-NMXQFQ26.js → chunk-TAE3EGBM.js} +3 -3
- package/dist/{chunk-3R3OADC5.js → chunk-ZF4HRR5F.js} +7 -3
- package/dist/{cli-context-A6XDEXN5.js → cli-context-E44HQ4ZO.js} +17 -8
- package/dist/{cli-main-5UGSW4TO.js → cli-main-OT63I2FX.js} +490 -228
- package/dist/{execution-BAP566QC.js → execution-OK34CJKJ.js} +7 -2
- package/dist/fleet/acp-live-steer.d.ts +28 -0
- package/dist/fleet/acp-permission-bridge.d.ts +49 -0
- package/dist/fleet/acp-quota-hold.d.ts +3 -0
- package/dist/fleet/acp-quota-reading.d.ts +3 -0
- package/dist/fleet/acp-turn-reminders.d.ts +15 -0
- package/dist/fleet/acp-wrongstack-bridge.d.ts +42 -0
- package/dist/fleet/host-acp.d.ts +20 -2
- package/dist/index.js +7 -4
- package/dist/{mcp-2XWBJEQN.js → mcp-W7A5HUXV.js} +97 -1
- package/dist/mcp-serve-project.d.ts +18 -0
- package/dist/{per-subcommand-help-D6J4ZXW2.js → per-subcommand-help-4GYSCMLU.js} +2 -2
- package/dist/{short-circuit-flags-CPCT5MWB.js → short-circuit-flags-QEXUS3BY.js} +2 -2
- package/dist/{subcommands-VTMIZQBP.js → subcommands-YADUV7IJ.js} +2 -2
- package/dist/{webui-server-HIUY3RHD.js → webui-server-CB64CFDG.js} +41 -3
- package/package.json +34 -30
- package/dist/auth-menu/anthropic-oauth.d.ts +0 -43
- package/dist/chunk-ZNNFEKDZ.js +0 -319
|
@@ -61,6 +61,9 @@ import {
|
|
|
61
61
|
startCliHqConnection
|
|
62
62
|
} from "./chunk-76JE54WD.js";
|
|
63
63
|
import "./chunk-OZCYZYN2.js";
|
|
64
|
+
import {
|
|
65
|
+
confirmAcpLeaderThroughEvents
|
|
66
|
+
} from "./chunk-GKGWPFW2.js";
|
|
64
67
|
import {
|
|
65
68
|
CLI_VERSION
|
|
66
69
|
} from "./chunk-HKMOIIPQ.js";
|
|
@@ -5266,8 +5269,9 @@ async function runWebUIDispatch(ctx) {
|
|
|
5266
5269
|
const isSessionChild = Boolean(webuiSessionChild);
|
|
5267
5270
|
const isSimpleUi = !isSessionChild && flags["simpleui"] === true;
|
|
5268
5271
|
agent.disableInteractiveConfirmation();
|
|
5272
|
+
confirmAcpLeaderThroughEvents();
|
|
5269
5273
|
renderer.setSilent(true);
|
|
5270
|
-
const { runWebUI } = await import("./webui-server-
|
|
5274
|
+
const { runWebUI } = await import("./webui-server-CB64CFDG.js");
|
|
5271
5275
|
const flagValue = (names) => {
|
|
5272
5276
|
for (const name of names) {
|
|
5273
5277
|
if (!Object.hasOwn(flags, name)) continue;
|
|
@@ -7192,6 +7196,7 @@ async function execute(deps) {
|
|
|
7192
7196
|
});
|
|
7193
7197
|
} else if (executionMode === "tui") {
|
|
7194
7198
|
agent.disableInteractiveConfirmation();
|
|
7199
|
+
confirmAcpLeaderThroughEvents();
|
|
7195
7200
|
const state = {
|
|
7196
7201
|
projectRoot,
|
|
7197
7202
|
wpaths,
|
|
@@ -7579,4 +7584,4 @@ export {
|
|
|
7579
7584
|
execute,
|
|
7580
7585
|
resolveReviewerFallbackModels
|
|
7581
7586
|
};
|
|
7582
|
-
//# sourceMappingURL=execution-
|
|
7587
|
+
//# sourceMappingURL=execution-OK34CJKJ.js.map
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Live notes to a running external ACP worker.
|
|
3
|
+
*
|
|
4
|
+
* A WrongStack agent registers in the session note hub and folds notes in at
|
|
5
|
+
* its next iteration. An external agent (Claude Code over ACP) has no such
|
|
6
|
+
* loop, so while its turn runs this registers an inbox for it that injects
|
|
7
|
+
* each note into the turn through the agent's steering extension. The leader
|
|
8
|
+
* then reaches the worker with `session_note`, as it reaches its own workers.
|
|
9
|
+
*/
|
|
10
|
+
import type { AcpSteerOutcome } from '@wrongstack/acp';
|
|
11
|
+
import { type SessionNoteHub } from '@wrongstack/core/coordination';
|
|
12
|
+
import type { SubagentRunContext, TaskSpec } from '@wrongstack/core/types';
|
|
13
|
+
interface Note {
|
|
14
|
+
from: string;
|
|
15
|
+
kind: string;
|
|
16
|
+
body: string;
|
|
17
|
+
subject?: string | undefined;
|
|
18
|
+
}
|
|
19
|
+
/** The note as the worker reads it: who sent it, as what, then the text. */
|
|
20
|
+
export declare function steerMessage(note: Note): string;
|
|
21
|
+
/**
|
|
22
|
+
* Register `ctx.subagentId` (and its display name) as a live agent of the
|
|
23
|
+
* delegating session for the length of the turn. Returns the unregister, or
|
|
24
|
+
* undefined when no WrongStack session delegated the task.
|
|
25
|
+
*/
|
|
26
|
+
export declare function registerAcpSteerInbox(ctx: SubagentRunContext, _task: TaskSpec, steer: (text: string) => Promise<AcpSteerOutcome>, hub?: Pick<SessionNoteHub, 'register'>, onUndelivered?: (outcome: string) => void): (() => void) | undefined;
|
|
27
|
+
export {};
|
|
28
|
+
//# sourceMappingURL=acp-live-steer.d.ts.map
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WrongStack's permission rules for an external ACP worker.
|
|
3
|
+
*
|
|
4
|
+
* A delegated agent must not be a one-hop bypass of the user's approval
|
|
5
|
+
* system. WrongStack's own subagents run every tool call through
|
|
6
|
+
* `AutoApprovePermissionPolicy`: the user's deny rules bind them, destructive
|
|
7
|
+
* commands and credential reads are refused (a worker cannot ask), and the
|
|
8
|
+
* user's YOLO+ lifts those refusals. An ACP worker gets the same treatment:
|
|
9
|
+
* the host starts it in a mode where it asks before edits, commands and
|
|
10
|
+
* fetches, and each `session/request_permission` is translated into the
|
|
11
|
+
* matching WrongStack tool call and decided by that policy. A request it
|
|
12
|
+
* cannot evaluate — an unknown kind, a call naming no target, a tool the run
|
|
13
|
+
* does not have — is refused, never waved through.
|
|
14
|
+
*/
|
|
15
|
+
import type { PermissionPolicy as AcpPermissionPolicy } from '@wrongstack/acp';
|
|
16
|
+
import type { PermissionDecision, Tool } from '@wrongstack/core/types';
|
|
17
|
+
/** The WrongStack tool call an ACP permission request stands for. */
|
|
18
|
+
export interface WrongStackCall {
|
|
19
|
+
tool: string;
|
|
20
|
+
input: Record<string, unknown>;
|
|
21
|
+
}
|
|
22
|
+
export interface AcpPermissionBridgeOptions {
|
|
23
|
+
/** WrongStack's subagent policy (an `AutoApprovePermissionPolicy`). */
|
|
24
|
+
evaluate: (tool: Tool, input: unknown, ctx: {
|
|
25
|
+
projectRoot: string;
|
|
26
|
+
cwd: string;
|
|
27
|
+
}) => Promise<PermissionDecision>;
|
|
28
|
+
/** Resolve a WrongStack tool by name (the host's tool registry). */
|
|
29
|
+
getTool: (name: string) => Tool | undefined;
|
|
30
|
+
projectRoot: string;
|
|
31
|
+
/**
|
|
32
|
+
* Whether MCP tools may run at all. False under `--restricted`, which keeps
|
|
33
|
+
* MCP tools out of the registry and so out of a worker's reach too.
|
|
34
|
+
*/
|
|
35
|
+
allowMcp?: boolean | undefined;
|
|
36
|
+
/**
|
|
37
|
+
* Ask the user when the policy wants a question (`confirm`). A worker has
|
|
38
|
+
* no one to ask, so without this a `confirm` is refused; a leader runs in
|
|
39
|
+
* front of the user and passes the session's own confirmation prompt.
|
|
40
|
+
*/
|
|
41
|
+
confirm?: ((tool: Tool, call: WrongStackCall, request: {
|
|
42
|
+
toolCallId: string | undefined;
|
|
43
|
+
signal: AbortSignal;
|
|
44
|
+
}) => Promise<boolean>) | undefined;
|
|
45
|
+
/** Told about every refusal, for the host's log. */
|
|
46
|
+
onRefused?: ((call: WrongStackCall, reason: string) => void) | undefined;
|
|
47
|
+
}
|
|
48
|
+
export declare function wrongstackAcpPermissionPolicy(opts: AcpPermissionBridgeOptions): AcpPermissionPolicy;
|
|
49
|
+
//# sourceMappingURL=acp-permission-bridge.d.ts.map
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/** Remind an active ACP turn about local /btw notes and newly waiting mail. */
|
|
2
|
+
import { type Context } from '@wrongstack/core/agent';
|
|
3
|
+
type Steer = (text: string) => Promise<'injected' | 'promptRequired' | 'startedNewTurn' | 'unsupported'>;
|
|
4
|
+
export interface AcpTurnRemindersOptions {
|
|
5
|
+
steer: Steer;
|
|
6
|
+
context?: Context | undefined;
|
|
7
|
+
unreadCount?: (() => Promise<number>) | undefined;
|
|
8
|
+
btwPollMs?: number | undefined;
|
|
9
|
+
mailPollMs?: number | undefined;
|
|
10
|
+
}
|
|
11
|
+
/** Mailbox awareness embeds message bodies; ask ACP to read inbox instead. */
|
|
12
|
+
export declare function acpBtwBlock(notes: readonly string[]): string;
|
|
13
|
+
export declare function startAcpTurnReminders(options: AcpTurnRemindersOptions): () => void;
|
|
14
|
+
export {};
|
|
15
|
+
//# sourceMappingURL=acp-turn-reminders.d.ts.map
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { type AcpSessionSetup } from '@wrongstack/acp';
|
|
2
|
+
import type { Config, SubagentRunContext, TaskSpec } from '@wrongstack/core/types';
|
|
3
|
+
export type BridgeServer = 'sage' | 'mailbox' | 'kanban' | 'codebase-index' | 'requirement-intake';
|
|
4
|
+
export declare const DEFAULT_BRIDGE_AGENTS: readonly string[];
|
|
5
|
+
export declare const DEFAULT_BRIDGE_SERVERS: readonly BridgeServer[];
|
|
6
|
+
type BridgeConfig = NonNullable<NonNullable<Config['acp']>['bridge']>;
|
|
7
|
+
/** How to start this same `wstack`: the binary itself, or node/bun + the CLI entry. */
|
|
8
|
+
export declare function wstackLaunch(args: string[], entry?: string | undefined): {
|
|
9
|
+
command: string;
|
|
10
|
+
args: string[];
|
|
11
|
+
};
|
|
12
|
+
/** A short task-local cue: the Claude adapter gives user-turn text more immediate weight. */
|
|
13
|
+
export declare function bridgeTaskKickoff(servers: readonly BridgeServer[]): string;
|
|
14
|
+
/**
|
|
15
|
+
* The note appended to the worker's system prompt. It must not vary per task
|
|
16
|
+
* or per worker: the system prompt is the head of the agent's prompt cache, so
|
|
17
|
+
* a task id or worker id in it made every worker rewrite ~25k cached tokens
|
|
18
|
+
* (measured: $0.21 per one-line task, against $0.008 with a stable prompt).
|
|
19
|
+
* Per-worker identity lives in the MCP servers' arguments instead.
|
|
20
|
+
*/
|
|
21
|
+
export declare function bridgeNote(servers: readonly BridgeServer[], delegated?: boolean): string;
|
|
22
|
+
/**
|
|
23
|
+
* The note for an agent running as the session's LEADER: the user talks to it
|
|
24
|
+
* through WrongStack, so it answers them directly and ends a turn the way
|
|
25
|
+
* WrongStack's own leader does, with next steps the user can send back.
|
|
26
|
+
*/
|
|
27
|
+
export declare function leaderBridgeNote(servers: readonly BridgeServer[]): string;
|
|
28
|
+
/** True when `command` resolves to a file on PATH (PATHEXT-aware on Windows). */
|
|
29
|
+
export declare function onPath(command: string, env?: NodeJS.ProcessEnv, platform?: NodeJS.Platform): boolean;
|
|
30
|
+
/**
|
|
31
|
+
* Bridged agents the leader can hand a task to on this machine: listed in
|
|
32
|
+
* `acp.bridge.agents` (by catalog or registry id) and either configured by
|
|
33
|
+
* the user in `acp.agents` or with their CLI on PATH. Catalog ids, in order.
|
|
34
|
+
*/
|
|
35
|
+
export declare function installedBridgeAgents(acp: Config['acp'] | undefined, isOnPath?: (command: string) => boolean): string[];
|
|
36
|
+
/**
|
|
37
|
+
* The per-session setup for `agentId`, or undefined when the bridge does not
|
|
38
|
+
* apply to it (not listed, turned off, or no servers).
|
|
39
|
+
*/
|
|
40
|
+
export declare function wrongstackBridgeSetup(agentId: string, projectRoot: string, config: BridgeConfig | undefined, role?: 'worker' | 'leader'): ((task: TaskSpec, ctx: SubagentRunContext) => AcpSessionSetup) | undefined;
|
|
41
|
+
export {};
|
|
42
|
+
//# sourceMappingURL=acp-wrongstack-bridge.d.ts.map
|
package/dist/fleet/host-acp.d.ts
CHANGED
|
@@ -1,10 +1,28 @@
|
|
|
1
|
-
import { type ACPProgressEvent, type AcpAgentCommandOverrides, type AcpLiveCatalog } from '@wrongstack/acp';
|
|
2
|
-
import type { SubagentRunContext, SubagentRunner, TaskSpec } from '@wrongstack/core/types';
|
|
1
|
+
import { type ACPProgressEvent, type AcpAgentCommandOverrides, type AcpLiveCatalog, type PermissionPolicy as AcpPermissionPolicy } from '@wrongstack/acp';
|
|
2
|
+
import type { Config, SubagentRunContext, SubagentRunner, TaskSpec } from '@wrongstack/core/types';
|
|
3
3
|
export type AcpLivePublisher = (ctx: SubagentRunContext, task: TaskSpec, event: ACPProgressEvent) => void;
|
|
4
4
|
export interface BuildAcpSubagentRunnerOptions {
|
|
5
|
+
/**
|
|
6
|
+
* The project the worker works in: its cwd and file-access root. Without it
|
|
7
|
+
* the worker ran in the host process's cwd — a subdirectory, or another
|
|
8
|
+
* repository than the session's.
|
|
9
|
+
*/
|
|
10
|
+
projectRoot?: string | undefined;
|
|
5
11
|
overrides?: AcpAgentCommandOverrides | undefined;
|
|
6
12
|
live?: AcpLiveCatalog | undefined;
|
|
7
13
|
publishLive?: AcpLivePublisher | undefined;
|
|
14
|
+
/** Project the worker runs in, plus `acp.bridge` config: see acp-wrongstack-bridge.ts. */
|
|
15
|
+
bridge?: {
|
|
16
|
+
projectRoot: string;
|
|
17
|
+
config?: NonNullable<Config['acp']>['bridge'] | undefined;
|
|
18
|
+
} | undefined;
|
|
19
|
+
/**
|
|
20
|
+
* WrongStack's permission rules for the worker's session (see
|
|
21
|
+
* acp-permission-bridge.ts). When set, the worker is also started in its
|
|
22
|
+
* `default` mode so it asks before edits and commands, whatever mode the
|
|
23
|
+
* user runs the agent in on their own.
|
|
24
|
+
*/
|
|
25
|
+
permissions?: ((ctx: SubagentRunContext) => AcpPermissionPolicy) | undefined;
|
|
8
26
|
}
|
|
9
27
|
/**
|
|
10
28
|
* Same command resolution as `wstack acp spawn` / `/acp` — user override,
|
package/dist/index.js
CHANGED
|
@@ -6,6 +6,9 @@ import {
|
|
|
6
6
|
import {
|
|
7
7
|
parseArgs
|
|
8
8
|
} from "./chunk-75OLD563.js";
|
|
9
|
+
import {
|
|
10
|
+
closeAcpLeaderSessions
|
|
11
|
+
} from "./chunk-GKGWPFW2.js";
|
|
9
12
|
import {
|
|
10
13
|
CLI_VERSION
|
|
11
14
|
} from "./chunk-HKMOIIPQ.js";
|
|
@@ -122,7 +125,7 @@ async function main(argv) {
|
|
|
122
125
|
applyAsciiMode(earlyFlags);
|
|
123
126
|
}
|
|
124
127
|
if (earlyFlags["help"] === true || earlyFlags["version"] === true) {
|
|
125
|
-
const { handleHelpVersionShortCircuit } = await import("./short-circuit-flags-
|
|
128
|
+
const { handleHelpVersionShortCircuit } = await import("./short-circuit-flags-QEXUS3BY.js");
|
|
126
129
|
const earlyExit = await handleHelpVersionShortCircuit(argv);
|
|
127
130
|
if (earlyExit !== null) return earlyExit;
|
|
128
131
|
}
|
|
@@ -131,7 +134,7 @@ async function main(argv) {
|
|
|
131
134
|
shouldCaptureTuiStartup(parsed.flags, parsed.positional)
|
|
132
135
|
);
|
|
133
136
|
try {
|
|
134
|
-
const { initializeCli } = await import("./cli-context-
|
|
137
|
+
const { initializeCli } = await import("./cli-context-E44HQ4ZO.js");
|
|
135
138
|
const cliCtx = await initializeCli(argv, {
|
|
136
139
|
onNonTuiLaunch: () => startupOutput.stop()
|
|
137
140
|
});
|
|
@@ -141,7 +144,7 @@ async function main(argv) {
|
|
|
141
144
|
} else {
|
|
142
145
|
startupOutput.stop();
|
|
143
146
|
}
|
|
144
|
-
const { runInteractive } = await import("./cli-main-
|
|
147
|
+
const { runInteractive } = await import("./cli-main-OT63I2FX.js");
|
|
145
148
|
return await runInteractive(cliCtx);
|
|
146
149
|
} finally {
|
|
147
150
|
startupOutput.stop();
|
|
@@ -252,7 +255,7 @@ function runCliProcess(mainFn) {
|
|
|
252
255
|
mainFn(process.argv.slice(2)).then(
|
|
253
256
|
(c) => {
|
|
254
257
|
process.exitCode = c;
|
|
255
|
-
scheduleForcedExit(c);
|
|
258
|
+
void closeAcpLeaderSessions().finally(() => scheduleForcedExit(c));
|
|
256
259
|
},
|
|
257
260
|
(err) => {
|
|
258
261
|
runFatalSalvageSync();
|
|
@@ -345,12 +345,108 @@ async function serveMcpStdio(deps, positional) {
|
|
|
345
345
|
return 0;
|
|
346
346
|
}
|
|
347
347
|
|
|
348
|
+
// src/mcp-serve-project.ts
|
|
349
|
+
var PROJECT_MCP_SERVERS = [
|
|
350
|
+
"mailbox",
|
|
351
|
+
"kanban",
|
|
352
|
+
"codebase-index",
|
|
353
|
+
"requirement-intake",
|
|
354
|
+
"sage"
|
|
355
|
+
];
|
|
356
|
+
function isProjectMcpServer(value) {
|
|
357
|
+
return PROJECT_MCP_SERVERS.includes(value);
|
|
358
|
+
}
|
|
359
|
+
var SERVER_FLAGS = [
|
|
360
|
+
"project-root",
|
|
361
|
+
"actor",
|
|
362
|
+
"session-id",
|
|
363
|
+
"name",
|
|
364
|
+
"role",
|
|
365
|
+
"writable",
|
|
366
|
+
"admin",
|
|
367
|
+
"destructive",
|
|
368
|
+
"http",
|
|
369
|
+
"stdio",
|
|
370
|
+
"port",
|
|
371
|
+
"host",
|
|
372
|
+
"token",
|
|
373
|
+
"index-dir",
|
|
374
|
+
"origin",
|
|
375
|
+
"watch"
|
|
376
|
+
];
|
|
377
|
+
var SWITCHES = /* @__PURE__ */ new Set([
|
|
378
|
+
"--writable",
|
|
379
|
+
"--admin",
|
|
380
|
+
"--destructive",
|
|
381
|
+
"--http",
|
|
382
|
+
"--stdio",
|
|
383
|
+
"--watch"
|
|
384
|
+
]);
|
|
385
|
+
function normalizeSwitches(args) {
|
|
386
|
+
const out = [];
|
|
387
|
+
for (let i = 0; i < args.length; i++) {
|
|
388
|
+
const arg = args[i];
|
|
389
|
+
const eq = arg.indexOf("=");
|
|
390
|
+
const flag = eq === -1 ? arg : arg.slice(0, eq);
|
|
391
|
+
if (!SWITCHES.has(flag)) {
|
|
392
|
+
out.push(arg);
|
|
393
|
+
continue;
|
|
394
|
+
}
|
|
395
|
+
const value = eq === -1 ? void 0 : arg.slice(eq + 1);
|
|
396
|
+
if (value === "false") continue;
|
|
397
|
+
out.push(flag);
|
|
398
|
+
if (eq === -1 && args[i + 1] === "true") i++;
|
|
399
|
+
}
|
|
400
|
+
return out;
|
|
401
|
+
}
|
|
402
|
+
function optionValue(args, name) {
|
|
403
|
+
const flag = `--${name}`;
|
|
404
|
+
for (let i = 0; i < args.length; i++) {
|
|
405
|
+
const arg = args[i];
|
|
406
|
+
if (arg === flag) {
|
|
407
|
+
const next = args[i + 1];
|
|
408
|
+
return next !== void 0 && !next.startsWith("--") ? next : void 0;
|
|
409
|
+
}
|
|
410
|
+
if (arg.startsWith(`${flag}=`)) return arg.slice(flag.length + 1);
|
|
411
|
+
}
|
|
412
|
+
return void 0;
|
|
413
|
+
}
|
|
414
|
+
async function serveProjectMcp(server, rawArgs, deps) {
|
|
415
|
+
const args = normalizeSwitches(restoreFlags(rawArgs, deps, SERVER_FLAGS));
|
|
416
|
+
if (server === "sage") {
|
|
417
|
+
const { serveAttachedSageMcpStdio } = await import("@wrongstack/sage-mcp");
|
|
418
|
+
await serveAttachedSageMcpStdio({
|
|
419
|
+
// A client may start this server from any directory; an explicit root wins.
|
|
420
|
+
projectRoot: optionValue(args, "project-root") ?? deps.projectRoot,
|
|
421
|
+
directory: deps.config.Sage?.storage?.directory,
|
|
422
|
+
origin: optionValue(args, "origin")?.trim() || "mcp-client"
|
|
423
|
+
});
|
|
424
|
+
return 0;
|
|
425
|
+
}
|
|
426
|
+
const argv = optionValue(args, "project-root") === void 0 ? [...args, "--project-root", deps.projectRoot] : args;
|
|
427
|
+
if (server === "mailbox") {
|
|
428
|
+
const { runMailboxMcpServer } = await import("@wrongstack/mailbox-mcp");
|
|
429
|
+
return runMailboxMcpServer(argv);
|
|
430
|
+
}
|
|
431
|
+
if (server === "kanban") {
|
|
432
|
+
const { runKanbanMcpServer } = await import("@wrongstack/kanban-mcp");
|
|
433
|
+
return runKanbanMcpServer(argv);
|
|
434
|
+
}
|
|
435
|
+
if (server === "requirement-intake") {
|
|
436
|
+
const { runRequirementIntakeMcpServer } = await import("@wrongstack/requirement-intake-mcp");
|
|
437
|
+
return runRequirementIntakeMcpServer(argv);
|
|
438
|
+
}
|
|
439
|
+
const { runCodebaseIndexMcpServer } = await import("@wrongstack/codebase-index-mcp");
|
|
440
|
+
return runCodebaseIndexMcpServer(argv);
|
|
441
|
+
}
|
|
442
|
+
|
|
348
443
|
// src/subcommands/handlers/mcp.ts
|
|
349
444
|
var BUILT_IN_MCP = allServers();
|
|
350
445
|
var mcpCmd = async (args, deps) => {
|
|
351
446
|
args = restoreFlags(args, deps, ["enable", "e", "transport", "url", "command"]);
|
|
352
447
|
const sub = args[0];
|
|
353
448
|
if (sub === "serve") {
|
|
449
|
+
if (isProjectMcpServer(args[1])) return serveProjectMcp(args[1], args.slice(2), deps);
|
|
354
450
|
return serveMcpStdio(deps, args.slice(1));
|
|
355
451
|
}
|
|
356
452
|
if (!sub || sub === "list") {
|
|
@@ -461,4 +557,4 @@ function isRecord(value) {
|
|
|
461
557
|
export {
|
|
462
558
|
mcpCmd
|
|
463
559
|
};
|
|
464
|
-
//# sourceMappingURL=mcp-
|
|
560
|
+
//# sourceMappingURL=mcp-W7A5HUXV.js.map
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `wstack mcp serve <mailbox|kanban|codebase-index|requirement-intake|sage>` — run one of
|
|
3
|
+
* WrongStack's project MCP servers from inside `wstack` itself.
|
|
4
|
+
*
|
|
5
|
+
* Mailbox, Kanban, Codebase Index and Requirements Intake also ship as their own npm bins
|
|
6
|
+
* (`wstack-mailbox-mcp`, …), but the standalone binary carries none of them,
|
|
7
|
+
* so this is the launch path that works in every install. Each server is bound
|
|
8
|
+
* to one project: `--project-root` defaults to the project this command runs
|
|
9
|
+
* in, and every server only attaches to that project's running owner.
|
|
10
|
+
*
|
|
11
|
+
* stdout is the JSON-RPC channel; everything else goes to stderr.
|
|
12
|
+
*/
|
|
13
|
+
import type { SubcommandDeps } from './subcommands/contracts.js';
|
|
14
|
+
export declare const PROJECT_MCP_SERVERS: readonly ['mailbox', 'kanban', 'codebase-index', 'requirement-intake', 'sage'];
|
|
15
|
+
export type ProjectMcpServer = (typeof PROJECT_MCP_SERVERS)[number];
|
|
16
|
+
export declare function isProjectMcpServer(value: string | undefined): value is ProjectMcpServer;
|
|
17
|
+
export declare function serveProjectMcp(server: ProjectMcpServer, rawArgs: string[], deps: SubcommandDeps): Promise<number>;
|
|
18
|
+
//# sourceMappingURL=mcp-serve-project.d.ts.map
|
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
renderFocusedHelpToString,
|
|
8
8
|
renderGenericHelp,
|
|
9
9
|
subcommandsWithFocusedHelp
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-ZF4HRR5F.js";
|
|
11
11
|
import "./chunk-ZXX3MJRL.js";
|
|
12
12
|
import "./chunk-W23PY4IJ.js";
|
|
13
13
|
export {
|
|
@@ -20,4 +20,4 @@ export {
|
|
|
20
20
|
renderGenericHelp,
|
|
21
21
|
subcommandsWithFocusedHelp
|
|
22
22
|
};
|
|
23
|
-
//# sourceMappingURL=per-subcommand-help-
|
|
23
|
+
//# sourceMappingURL=per-subcommand-help-4GYSCMLU.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
handleHelpVersionShortCircuit
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-TAE3EGBM.js";
|
|
4
4
|
import "./chunk-75OLD563.js";
|
|
5
5
|
import "./chunk-6VPWQ4TG.js";
|
|
6
6
|
import "./chunk-HKMOIIPQ.js";
|
|
@@ -8,4 +8,4 @@ import "./chunk-W23PY4IJ.js";
|
|
|
8
8
|
export {
|
|
9
9
|
handleHelpVersionShortCircuit
|
|
10
10
|
};
|
|
11
|
-
//# sourceMappingURL=short-circuit-flags-
|
|
11
|
+
//# sourceMappingURL=short-circuit-flags-QEXUS3BY.js.map
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
subcommandNames,
|
|
3
3
|
subcommands
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-2LTHDKZX.js";
|
|
5
5
|
import "./chunk-W23PY4IJ.js";
|
|
6
6
|
export {
|
|
7
7
|
subcommandNames,
|
|
8
8
|
subcommands
|
|
9
9
|
};
|
|
10
|
-
//# sourceMappingURL=subcommands-
|
|
10
|
+
//# sourceMappingURL=subcommands-YADUV7IJ.js.map
|
|
@@ -14,14 +14,19 @@ import {
|
|
|
14
14
|
import {
|
|
15
15
|
createHqCommandDispatcher,
|
|
16
16
|
createProjectKanbanAssignHandler,
|
|
17
|
-
createProjectKanbanTransitionHandler
|
|
18
|
-
|
|
17
|
+
createProjectKanbanTransitionHandler,
|
|
18
|
+
installedBridgeAgents
|
|
19
|
+
} from "./chunk-JKTJSLUT.js";
|
|
19
20
|
import {
|
|
20
21
|
startCliHqConnection
|
|
21
22
|
} from "./chunk-76JE54WD.js";
|
|
22
23
|
import {
|
|
23
24
|
WebSocketServer
|
|
24
25
|
} from "./chunk-OZCYZYN2.js";
|
|
26
|
+
import {
|
|
27
|
+
ACP_LEADER_PROVIDER_ID,
|
|
28
|
+
setAcpLeaderSessionAgents
|
|
29
|
+
} from "./chunk-GKGWPFW2.js";
|
|
25
30
|
import {
|
|
26
31
|
CLI_VERSION
|
|
27
32
|
} from "./chunk-HKMOIIPQ.js";
|
|
@@ -1092,6 +1097,33 @@ import {
|
|
|
1092
1097
|
createEmbeddedProviderOperations
|
|
1093
1098
|
} from "@wrongstack/webui-server";
|
|
1094
1099
|
|
|
1100
|
+
// src/acp-leader/acp-leader-picker.ts
|
|
1101
|
+
import { findAgentDescriptor } from "@wrongstack/acp";
|
|
1102
|
+
function acpLeaderPickable(config) {
|
|
1103
|
+
const agents = installedBridgeAgents(config?.acp);
|
|
1104
|
+
if (agents.length === 0) return [];
|
|
1105
|
+
return [
|
|
1106
|
+
{
|
|
1107
|
+
id: ACP_LEADER_PROVIDER_ID,
|
|
1108
|
+
type: ACP_LEADER_PROVIDER_ID,
|
|
1109
|
+
models: agents.map((id) => {
|
|
1110
|
+
const descriptor = findAgentDescriptor(id);
|
|
1111
|
+
return {
|
|
1112
|
+
id,
|
|
1113
|
+
name: descriptor?.displayName ?? id,
|
|
1114
|
+
description: "ACP agent leading the session",
|
|
1115
|
+
...descriptor?.contextWindow ? { contextWindow: descriptor.contextWindow } : {}
|
|
1116
|
+
};
|
|
1117
|
+
})
|
|
1118
|
+
}
|
|
1119
|
+
];
|
|
1120
|
+
}
|
|
1121
|
+
function buildAcpLeaderProvider(registry, providerId, config) {
|
|
1122
|
+
const type = config.type ?? providerId;
|
|
1123
|
+
if (type !== ACP_LEADER_PROVIDER_ID || !registry?.has(type)) return void 0;
|
|
1124
|
+
return registry.create({ ...config, type: providerId }, type);
|
|
1125
|
+
}
|
|
1126
|
+
|
|
1095
1127
|
// src/webui-server/credential-watcher.ts
|
|
1096
1128
|
import { TOKENS } from "@wrongstack/core/kernel";
|
|
1097
1129
|
import { watchProviderConfig } from "@wrongstack/core/storage";
|
|
@@ -1175,6 +1207,9 @@ function createEmbeddedProviderPlane(input) {
|
|
|
1175
1207
|
providerAuthRegistry: opts.providerAuthRegistry,
|
|
1176
1208
|
getDisabledModels: () => opts.appConfig?.disabledModels ?? [],
|
|
1177
1209
|
getDisabledProviders: () => opts.appConfig?.disabledProviders ?? [],
|
|
1210
|
+
// `acp` with the installed ACP agents: an agent such as Claude Code can
|
|
1211
|
+
// lead a tab like a model (see docs/slash/acp.md).
|
|
1212
|
+
hostProviders: () => acpLeaderPickable(opts.appConfig),
|
|
1178
1213
|
send,
|
|
1179
1214
|
broadcast,
|
|
1180
1215
|
log: (m) => console.log(m)
|
|
@@ -1308,6 +1343,8 @@ function createWebuiRouteContexts({
|
|
|
1308
1343
|
getConfig: () => opts.appConfig,
|
|
1309
1344
|
onMaxContextResolved: opts.onModelContextResolved,
|
|
1310
1345
|
persistPrefs,
|
|
1346
|
+
// The ACP leader's factory lives in the CLI's provider registry.
|
|
1347
|
+
buildProvider: (providerId, config) => buildAcpLeaderProvider(opts.agent.providers, providerId, config),
|
|
1311
1348
|
send,
|
|
1312
1349
|
broadcast,
|
|
1313
1350
|
log: (m) => console.log(m)
|
|
@@ -2302,6 +2339,7 @@ async function runWebUI(opts) {
|
|
|
2302
2339
|
abortControllers
|
|
2303
2340
|
);
|
|
2304
2341
|
sessionAgentsRef = sessionAgents;
|
|
2342
|
+
setAcpLeaderSessionAgents((sessionId) => sessionAgents.peek(sessionId));
|
|
2305
2343
|
const autoWakeHost = opts.leaderAutoWake ? createWebuiLeaderAutoWakeHost({
|
|
2306
2344
|
controller: opts.leaderAutoWake,
|
|
2307
2345
|
events: opts.events,
|
|
@@ -2458,4 +2496,4 @@ async function runWebUI(opts) {
|
|
|
2458
2496
|
export {
|
|
2459
2497
|
runWebUI
|
|
2460
2498
|
};
|
|
2461
|
-
//# sourceMappingURL=webui-server-
|
|
2499
|
+
//# sourceMappingURL=webui-server-CB64CFDG.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wrongstack/cli",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.4",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "WrongStack CLI — terminal AI coding agent with provider catalog from models.dev. Provides `wrongstack` and `wstack` binaries.",
|
|
6
6
|
"keywords": [
|
|
@@ -48,42 +48,46 @@
|
|
|
48
48
|
"clean": "bun -e \"require('node:fs').rmSync('dist',{recursive:true,force:true})\""
|
|
49
49
|
},
|
|
50
50
|
"dependencies": {
|
|
51
|
-
"@wrongstack/acp": "1.1.
|
|
52
|
-
"@wrongstack/bench": "1.1.
|
|
53
|
-
"@wrongstack/
|
|
54
|
-
"@wrongstack/
|
|
55
|
-
"@wrongstack/
|
|
56
|
-
"@wrongstack/
|
|
57
|
-
"@wrongstack/
|
|
58
|
-
"@wrongstack/
|
|
59
|
-
"@wrongstack/
|
|
60
|
-
"@wrongstack/
|
|
61
|
-
"@wrongstack/
|
|
62
|
-
"@wrongstack/
|
|
63
|
-
"@wrongstack/
|
|
64
|
-
"@wrongstack/
|
|
65
|
-
"@wrongstack/
|
|
66
|
-
"@wrongstack/
|
|
67
|
-
"@wrongstack/
|
|
68
|
-
"@wrongstack/
|
|
69
|
-
"@wrongstack/
|
|
70
|
-
"@wrongstack/
|
|
71
|
-
"@wrongstack/
|
|
72
|
-
"@wrongstack/
|
|
73
|
-
"@wrongstack/
|
|
74
|
-
"@wrongstack/
|
|
75
|
-
"@wrongstack/
|
|
76
|
-
"@wrongstack/
|
|
77
|
-
"@wrongstack/
|
|
51
|
+
"@wrongstack/acp": "1.1.2",
|
|
52
|
+
"@wrongstack/bench": "1.1.2",
|
|
53
|
+
"@wrongstack/codebase-index-mcp": "1.1.2",
|
|
54
|
+
"@wrongstack/core": "1.1.2",
|
|
55
|
+
"@wrongstack/kanban": "1.1.2",
|
|
56
|
+
"@wrongstack/kanban-mcp": "1.1.2",
|
|
57
|
+
"@wrongstack/mailbox-mcp": "1.1.2",
|
|
58
|
+
"@wrongstack/mcp": "1.1.2",
|
|
59
|
+
"@wrongstack/persistence": "1.1.2",
|
|
60
|
+
"@wrongstack/plug-lsp": "1.1.2",
|
|
61
|
+
"@wrongstack/plugins": "1.1.2",
|
|
62
|
+
"@wrongstack/primitives": "1.1.2",
|
|
63
|
+
"@wrongstack/providers": "1.1.2",
|
|
64
|
+
"@wrongstack/requirement-intake": "1.1.2",
|
|
65
|
+
"@wrongstack/requirement-intake-mcp": "1.1.2",
|
|
66
|
+
"@wrongstack/runtime": "1.1.2",
|
|
67
|
+
"@wrongstack/sage": "1.1.2",
|
|
68
|
+
"@wrongstack/sage-mcp": "1.1.2",
|
|
69
|
+
"@wrongstack/sdd": "1.1.2",
|
|
70
|
+
"@wrongstack/security-scanner": "1.1.2",
|
|
71
|
+
"@wrongstack/simpleui": "1.1.2",
|
|
72
|
+
"@wrongstack/techstack": "1.1.2",
|
|
73
|
+
"@wrongstack/telegram": "1.1.2",
|
|
74
|
+
"@wrongstack/tools": "1.1.2",
|
|
75
|
+
"@wrongstack/tui": "1.1.2",
|
|
76
|
+
"@wrongstack/vector-memory": "1.1.2",
|
|
77
|
+
"@wrongstack/webui": "1.1.2",
|
|
78
|
+
"@wrongstack/webui-hq": "1.1.2",
|
|
79
|
+
"@wrongstack/webui-protocol": "1.1.2",
|
|
80
|
+
"@wrongstack/webui-server": "1.1.2",
|
|
81
|
+
"@wrongstack/wrongtrace": "1.1.2",
|
|
78
82
|
"ws": "^8.22.0"
|
|
79
83
|
},
|
|
80
84
|
"optionalDependencies": {
|
|
81
|
-
"@wrongstack/desktop": "1.1.
|
|
85
|
+
"@wrongstack/desktop": "1.1.2"
|
|
82
86
|
},
|
|
83
87
|
"devDependencies": {
|
|
84
88
|
"@types/node": "^26.5.1",
|
|
85
89
|
"@types/ws": "^8.18.1",
|
|
86
|
-
"@wrongstack/governance": "1.1.
|
|
90
|
+
"@wrongstack/governance": "1.1.2",
|
|
87
91
|
"jsdom": "^30.0.1",
|
|
88
92
|
"typescript": "^7.0.2"
|
|
89
93
|
},
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Anthropic "Sign in with Claude" OAuth (Authorization Code + PKCE) — Claude
|
|
3
|
-
* Pro/Max subscription login. Parallel to the Codex flow but with Anthropic's
|
|
4
|
-
* endpoints and quirks:
|
|
5
|
-
* - authorize at claude.ai/oauth/authorize (params include `code=true`),
|
|
6
|
-
* - the OAuth `state` is the PKCE verifier (Anthropic's convention),
|
|
7
|
-
* - JSON (not form) token exchange at platform.claude.com/v1/oauth/token,
|
|
8
|
-
* - loopback callback on http://localhost:53692/callback.
|
|
9
|
-
*
|
|
10
|
-
* Stored under the canonical `anthropic-oauth` provider (family `anthropic-oauth`)
|
|
11
|
-
* so it never clobbers an API-key `anthropic` provider. The provider adapter
|
|
12
|
-
* adds the Bearer + beta headers and the required Claude Code system block.
|
|
13
|
-
*/
|
|
14
|
-
import type { AuthMenuDeps } from './types.js';
|
|
15
|
-
export declare const CLAUDE_PROVIDER_ID = "anthropic-oauth";
|
|
16
|
-
export interface ClaudeTokens {
|
|
17
|
-
access: string;
|
|
18
|
-
refresh: string;
|
|
19
|
-
expires: number;
|
|
20
|
-
}
|
|
21
|
-
export declare function generatePkce(): {
|
|
22
|
-
verifier: string;
|
|
23
|
-
challenge: string;
|
|
24
|
-
};
|
|
25
|
-
/** Build the Claude authorize URL. Anthropic uses the PKCE verifier as `state`. */
|
|
26
|
-
export declare function buildAuthorizeUrl(challenge: string, verifier: string): string;
|
|
27
|
-
export declare function parseAuthorizationInput(input: string): {
|
|
28
|
-
code?: string | undefined;
|
|
29
|
-
state?: string | undefined;
|
|
30
|
-
};
|
|
31
|
-
/** Exchange an authorization code (+ verifier, reused as state) for tokens. */
|
|
32
|
-
export declare function exchangeAuthorizationCode(code: string, state: string, verifier: string, signal?: AbortSignal): Promise<ClaudeTokens>;
|
|
33
|
-
export interface ClaudeLoginOptions {
|
|
34
|
-
providerId?: string;
|
|
35
|
-
/**
|
|
36
|
-
* External cancellation signal (e.g. the TUI auth panel's Esc). When
|
|
37
|
-
* provided, the flow does NOT install its own SIGINT handler — the
|
|
38
|
-
* caller owns cancellation.
|
|
39
|
-
*/
|
|
40
|
-
signal?: AbortSignal | undefined;
|
|
41
|
-
}
|
|
42
|
-
export declare function runClaudeOAuthLogin(deps: AuthMenuDeps, opts?: ClaudeLoginOptions): Promise<number>;
|
|
43
|
-
//# sourceMappingURL=anthropic-oauth.d.ts.map
|