@namzu/cli 0.7.6 → 1.0.0
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/__tests__/environment-reaches-the-turn.test.d.ts +17 -0
- package/dist/__tests__/environment-reaches-the-turn.test.d.ts.map +1 -0
- package/dist/__tests__/environment-reaches-the-turn.test.js +128 -0
- package/dist/__tests__/environment-reaches-the-turn.test.js.map +1 -0
- package/dist/__tests__/headless-trust-gate.test.d.ts +23 -0
- package/dist/__tests__/headless-trust-gate.test.d.ts.map +1 -0
- package/dist/__tests__/headless-trust-gate.test.js +227 -0
- package/dist/__tests__/headless-trust-gate.test.js.map +1 -0
- package/dist/__tests__/mcp-servers-reach-the-session.test.d.ts +17 -0
- package/dist/__tests__/mcp-servers-reach-the-session.test.d.ts.map +1 -0
- package/dist/__tests__/mcp-servers-reach-the-session.test.js +171 -0
- package/dist/__tests__/mcp-servers-reach-the-session.test.js.map +1 -0
- package/dist/__tests__/project-instructions-reach-the-turn.test.d.ts +24 -0
- package/dist/__tests__/project-instructions-reach-the-turn.test.d.ts.map +1 -0
- package/dist/__tests__/project-instructions-reach-the-turn.test.js +153 -0
- package/dist/__tests__/project-instructions-reach-the-turn.test.js.map +1 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +1 -0
- package/dist/cli.js.map +1 -1
- package/dist/commands/__tests__/run-exit-code.test.js +16 -0
- package/dist/commands/__tests__/run-exit-code.test.js.map +1 -1
- package/dist/commands/__tests__/run-flags.test.js +50 -1
- package/dist/commands/__tests__/run-flags.test.js.map +1 -1
- package/dist/commands/__tests__/run-stream-flags.test.js +16 -0
- package/dist/commands/__tests__/run-stream-flags.test.js.map +1 -1
- package/dist/commands/run-flags.d.ts +11 -0
- package/dist/commands/run-flags.d.ts.map +1 -1
- package/dist/commands/run-flags.js +5 -0
- package/dist/commands/run-flags.js.map +1 -1
- package/dist/commands/run-stream.d.ts +7 -0
- package/dist/commands/run-stream.d.ts.map +1 -1
- package/dist/commands/run-stream.js +49 -1
- package/dist/commands/run-stream.js.map +1 -1
- package/dist/commands/run.d.ts.map +1 -1
- package/dist/commands/run.js +64 -2
- package/dist/commands/run.js.map +1 -1
- package/dist/config/load.d.ts.map +1 -1
- package/dist/config/load.js +5 -0
- package/dist/config/load.js.map +1 -1
- package/dist/config/schema.d.ts +9 -0
- package/dist/config/schema.d.ts.map +1 -1
- package/dist/config/schema.js.map +1 -1
- package/dist/context/__tests__/environment.test.d.ts +10 -0
- package/dist/context/__tests__/environment.test.d.ts.map +1 -0
- package/dist/context/__tests__/environment.test.js +84 -0
- package/dist/context/__tests__/environment.test.js.map +1 -0
- package/dist/context/__tests__/project.test.d.ts +12 -0
- package/dist/context/__tests__/project.test.d.ts.map +1 -0
- package/dist/context/__tests__/project.test.js +201 -0
- package/dist/context/__tests__/project.test.js.map +1 -0
- package/dist/context/environment.d.ts +54 -0
- package/dist/context/environment.d.ts.map +1 -0
- package/dist/context/environment.js +97 -0
- package/dist/context/environment.js.map +1 -0
- package/dist/context/project.d.ts +132 -0
- package/dist/context/project.d.ts.map +1 -0
- package/dist/context/project.js +256 -0
- package/dist/context/project.js.map +1 -0
- package/dist/exit-codes.d.ts +11 -1
- package/dist/exit-codes.d.ts.map +1 -1
- package/dist/exit-codes.js +10 -0
- package/dist/exit-codes.js.map +1 -1
- package/dist/integrations/mcp/__tests__/connect.test.d.ts +11 -0
- package/dist/integrations/mcp/__tests__/connect.test.d.ts.map +1 -0
- package/dist/integrations/mcp/__tests__/connect.test.js +231 -0
- package/dist/integrations/mcp/__tests__/connect.test.js.map +1 -0
- package/dist/integrations/mcp/servers.d.ts +101 -0
- package/dist/integrations/mcp/servers.d.ts.map +1 -0
- package/dist/integrations/mcp/servers.js +160 -0
- package/dist/integrations/mcp/servers.js.map +1 -0
- package/dist/integrations/sessions/__tests__/archived-workspace.test.d.ts +21 -0
- package/dist/integrations/sessions/__tests__/archived-workspace.test.d.ts.map +1 -0
- package/dist/integrations/sessions/__tests__/archived-workspace.test.js +62 -0
- package/dist/integrations/sessions/__tests__/archived-workspace.test.js.map +1 -0
- package/dist/integrations/sessions/store.d.ts +15 -1
- package/dist/integrations/sessions/store.d.ts.map +1 -1
- package/dist/integrations/sessions/store.js +17 -2
- package/dist/integrations/sessions/store.js.map +1 -1
- package/dist/integrations/subagents/__tests__/delegation-trace.test.js +48 -3
- package/dist/integrations/subagents/__tests__/delegation-trace.test.js.map +1 -1
- package/dist/integrations/subagents/runtime.d.ts +21 -0
- package/dist/integrations/subagents/runtime.d.ts.map +1 -1
- package/dist/integrations/subagents/runtime.js +37 -11
- package/dist/integrations/subagents/runtime.js.map +1 -1
- package/dist/permissions/headless-trust.d.ts +60 -0
- package/dist/permissions/headless-trust.d.ts.map +1 -0
- package/dist/permissions/headless-trust.js +72 -0
- package/dist/permissions/headless-trust.js.map +1 -0
- package/dist/tui/App.d.ts.map +1 -1
- package/dist/tui/App.js +33 -0
- package/dist/tui/App.js.map +1 -1
- package/dist/tui/agent.d.ts +46 -0
- package/dist/tui/agent.d.ts.map +1 -1
- package/dist/tui/agent.js +64 -2
- package/dist/tui/agent.js.map +1 -1
- package/dist/tui/types.d.ts +7 -0
- package/dist/tui/types.d.ts.map +1 -1
- package/package.json +3 -3
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* External tool servers an operator declares in their config.
|
|
3
|
+
*
|
|
4
|
+
* The kernel has spoken this protocol for a long time — `MCPClient`,
|
|
5
|
+
* `StdioTransport`, `StreamableHttpTransport` and the tool adapter are all
|
|
6
|
+
* exported from `@namzu/sdk`. `packages/cli` imported none of them, so the
|
|
7
|
+
* capability existed and was unreachable from the product: a namzu user could
|
|
8
|
+
* not connect an external tool server at all, whatever the kernel could do.
|
|
9
|
+
*
|
|
10
|
+
* A server is declared by name under `mcpServers` in `namzu.config.json`:
|
|
11
|
+
*
|
|
12
|
+
* "mcpServers": {
|
|
13
|
+
* "tickets": { "command": "node", "args": ["./tickets-server.js"] },
|
|
14
|
+
* "search": { "url": "https://tools.example.internal/mcp" }
|
|
15
|
+
* }
|
|
16
|
+
*
|
|
17
|
+
* Its tools arrive prefixed with the server's name (`mcp_tickets_create`), so
|
|
18
|
+
* two servers offering `search` do not collide and the transcript says where a
|
|
19
|
+
* call went.
|
|
20
|
+
*
|
|
21
|
+
* ## Every failure is named
|
|
22
|
+
*
|
|
23
|
+
* A server that does not start, a spec that names neither a command nor a URL,
|
|
24
|
+
* a handshake that never answers — each becomes an entry in `failed` with a
|
|
25
|
+
* reason, never an absence. The whole hazard of this feature is the operator
|
|
26
|
+
* who configures a server, watches the agent run without its tools, and
|
|
27
|
+
* concludes the model is bad at the task.
|
|
28
|
+
*
|
|
29
|
+
* What to DO about a failure is not decided here, because the answer differs
|
|
30
|
+
* by surface: a person watching the TUI can read the line and fix their config,
|
|
31
|
+
* and a headless run has nobody to read anything, so it refuses. This module
|
|
32
|
+
* reports; the callers decide.
|
|
33
|
+
*/
|
|
34
|
+
import { type MCPTransportUnion, type ToolDefinition } from '@namzu/sdk';
|
|
35
|
+
/**
|
|
36
|
+
* How long a single server gets to connect, hand shake and list its tools.
|
|
37
|
+
*
|
|
38
|
+
* The client's own `requestTimeoutMs` bounds one round trip; it cannot bound a
|
|
39
|
+
* process that spawns and never speaks. Without this, one wedged server holds
|
|
40
|
+
* the whole session open before the first turn — no error, no failure, just a
|
|
41
|
+
* namzu that does not start.
|
|
42
|
+
*/
|
|
43
|
+
export declare const CONNECT_TIMEOUT_MS = 10000;
|
|
44
|
+
/**
|
|
45
|
+
* How long shutting one server down may take before it is given up on.
|
|
46
|
+
*
|
|
47
|
+
* Shorter than the connect bound because nothing waits on the answer: a
|
|
48
|
+
* one-shot is exiting and a TUI is replacing the session. What this prevents
|
|
49
|
+
* is the opposite of a leak — a `close()` that never resolves, holding the
|
|
50
|
+
* command open past the work it was asked to do.
|
|
51
|
+
*/
|
|
52
|
+
export declare const CLOSE_TIMEOUT_MS = 2000;
|
|
53
|
+
/** A single entry under `mcpServers`. Either a command or a URL, never both. */
|
|
54
|
+
export interface McpServerSpec {
|
|
55
|
+
/** Stdio: the executable to run. */
|
|
56
|
+
readonly command?: string;
|
|
57
|
+
readonly args?: readonly string[];
|
|
58
|
+
readonly env?: Readonly<Record<string, string>>;
|
|
59
|
+
/** Working directory for the child. Defaults to the agent's. */
|
|
60
|
+
readonly cwd?: string;
|
|
61
|
+
/** HTTP: the server's endpoint. */
|
|
62
|
+
readonly url?: string;
|
|
63
|
+
readonly headers?: Readonly<Record<string, string>>;
|
|
64
|
+
}
|
|
65
|
+
export type McpServersConfig = Readonly<Record<string, McpServerSpec>>;
|
|
66
|
+
export interface ConnectedMcpServer {
|
|
67
|
+
readonly name: string;
|
|
68
|
+
readonly toolCount: number;
|
|
69
|
+
}
|
|
70
|
+
export interface FailedMcpServer {
|
|
71
|
+
readonly name: string;
|
|
72
|
+
/** Phrased for one line in front of a person who has to fix it. */
|
|
73
|
+
readonly reason: string;
|
|
74
|
+
}
|
|
75
|
+
export interface McpConnection {
|
|
76
|
+
/** Adapted tools from every server that connected, ready to register. */
|
|
77
|
+
readonly tools: readonly ToolDefinition[];
|
|
78
|
+
readonly connected: readonly ConnectedMcpServer[];
|
|
79
|
+
readonly failed: readonly FailedMcpServer[];
|
|
80
|
+
/**
|
|
81
|
+
* Shut every connected server down.
|
|
82
|
+
*
|
|
83
|
+
* A stdio server is a CHILD PROCESS. Nothing else in this package owns one,
|
|
84
|
+
* which is why the session had no shutdown path before: without this, a TUI
|
|
85
|
+
* session that ends leaves the child running, and a long-lived host that
|
|
86
|
+
* opens sessions leaks one per session.
|
|
87
|
+
*/
|
|
88
|
+
close(): Promise<void>;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Turn one spec into a transport, or say why it is not one.
|
|
92
|
+
*
|
|
93
|
+
* Refused rather than guessed. A spec with both a command and a URL is an
|
|
94
|
+
* operator who edited one into a file that already had the other, and picking
|
|
95
|
+
* either would run something they did not mean to run.
|
|
96
|
+
*/
|
|
97
|
+
export declare function transportFor(spec: McpServerSpec, defaultCwd: string): MCPTransportUnion | string;
|
|
98
|
+
export declare function connectMcpServers(config: McpServersConfig | undefined, options: {
|
|
99
|
+
readonly cwd: string;
|
|
100
|
+
}): Promise<McpConnection>;
|
|
101
|
+
//# sourceMappingURL=servers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"servers.d.ts","sourceRoot":"","sources":["../../../src/integrations/mcp/servers.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAEH,OAAO,EAEN,KAAK,iBAAiB,EACtB,KAAK,cAAc,EAEnB,MAAM,YAAY,CAAA;AAEnB;;;;;;;GAOG;AACH,eAAO,MAAM,kBAAkB,QAAS,CAAA;AAExC;;;;;;;GAOG;AACH,eAAO,MAAM,gBAAgB,OAAQ,CAAA;AAErC,gFAAgF;AAChF,MAAM,WAAW,aAAa;IAC7B,oCAAoC;IACpC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,IAAI,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IACjC,QAAQ,CAAC,GAAG,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA;IAC/C,gEAAgE;IAChE,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAA;IACrB,mCAAmC;IACnC,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,OAAO,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA;CACnD;AAED,MAAM,MAAM,gBAAgB,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC,CAAA;AAEtE,MAAM,WAAW,kBAAkB;IAClC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;CAC1B;AAED,MAAM,WAAW,eAAe;IAC/B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,mEAAmE;IACnE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CACvB;AAED,MAAM,WAAW,aAAa;IAC7B,yEAAyE;IACzE,QAAQ,CAAC,KAAK,EAAE,SAAS,cAAc,EAAE,CAAA;IACzC,QAAQ,CAAC,SAAS,EAAE,SAAS,kBAAkB,EAAE,CAAA;IACjD,QAAQ,CAAC,MAAM,EAAE,SAAS,eAAe,EAAE,CAAA;IAC3C;;;;;;;OAOG;IACH,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;CACtB;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,GAAG,iBAAiB,GAAG,MAAM,CAuBhG;AAkBD,wBAAsB,iBAAiB,CACtC,MAAM,EAAE,gBAAgB,GAAG,SAAS,EACpC,OAAO,EAAE;IAAE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GAC/B,OAAO,CAAC,aAAa,CAAC,CAmExB"}
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* External tool servers an operator declares in their config.
|
|
3
|
+
*
|
|
4
|
+
* The kernel has spoken this protocol for a long time — `MCPClient`,
|
|
5
|
+
* `StdioTransport`, `StreamableHttpTransport` and the tool adapter are all
|
|
6
|
+
* exported from `@namzu/sdk`. `packages/cli` imported none of them, so the
|
|
7
|
+
* capability existed and was unreachable from the product: a namzu user could
|
|
8
|
+
* not connect an external tool server at all, whatever the kernel could do.
|
|
9
|
+
*
|
|
10
|
+
* A server is declared by name under `mcpServers` in `namzu.config.json`:
|
|
11
|
+
*
|
|
12
|
+
* "mcpServers": {
|
|
13
|
+
* "tickets": { "command": "node", "args": ["./tickets-server.js"] },
|
|
14
|
+
* "search": { "url": "https://tools.example.internal/mcp" }
|
|
15
|
+
* }
|
|
16
|
+
*
|
|
17
|
+
* Its tools arrive prefixed with the server's name (`mcp_tickets_create`), so
|
|
18
|
+
* two servers offering `search` do not collide and the transcript says where a
|
|
19
|
+
* call went.
|
|
20
|
+
*
|
|
21
|
+
* ## Every failure is named
|
|
22
|
+
*
|
|
23
|
+
* A server that does not start, a spec that names neither a command nor a URL,
|
|
24
|
+
* a handshake that never answers — each becomes an entry in `failed` with a
|
|
25
|
+
* reason, never an absence. The whole hazard of this feature is the operator
|
|
26
|
+
* who configures a server, watches the agent run without its tools, and
|
|
27
|
+
* concludes the model is bad at the task.
|
|
28
|
+
*
|
|
29
|
+
* What to DO about a failure is not decided here, because the answer differs
|
|
30
|
+
* by surface: a person watching the TUI can read the line and fix their config,
|
|
31
|
+
* and a headless run has nobody to read anything, so it refuses. This module
|
|
32
|
+
* reports; the callers decide.
|
|
33
|
+
*/
|
|
34
|
+
import { MCPClient, mcpToolToToolDefinition, } from '@namzu/sdk';
|
|
35
|
+
/**
|
|
36
|
+
* How long a single server gets to connect, hand shake and list its tools.
|
|
37
|
+
*
|
|
38
|
+
* The client's own `requestTimeoutMs` bounds one round trip; it cannot bound a
|
|
39
|
+
* process that spawns and never speaks. Without this, one wedged server holds
|
|
40
|
+
* the whole session open before the first turn — no error, no failure, just a
|
|
41
|
+
* namzu that does not start.
|
|
42
|
+
*/
|
|
43
|
+
export const CONNECT_TIMEOUT_MS = 10_000;
|
|
44
|
+
/**
|
|
45
|
+
* How long shutting one server down may take before it is given up on.
|
|
46
|
+
*
|
|
47
|
+
* Shorter than the connect bound because nothing waits on the answer: a
|
|
48
|
+
* one-shot is exiting and a TUI is replacing the session. What this prevents
|
|
49
|
+
* is the opposite of a leak — a `close()` that never resolves, holding the
|
|
50
|
+
* command open past the work it was asked to do.
|
|
51
|
+
*/
|
|
52
|
+
export const CLOSE_TIMEOUT_MS = 2_000;
|
|
53
|
+
/**
|
|
54
|
+
* Turn one spec into a transport, or say why it is not one.
|
|
55
|
+
*
|
|
56
|
+
* Refused rather than guessed. A spec with both a command and a URL is an
|
|
57
|
+
* operator who edited one into a file that already had the other, and picking
|
|
58
|
+
* either would run something they did not mean to run.
|
|
59
|
+
*/
|
|
60
|
+
export function transportFor(spec, defaultCwd) {
|
|
61
|
+
const hasCommand = typeof spec.command === 'string' && spec.command.trim().length > 0;
|
|
62
|
+
const hasUrl = typeof spec.url === 'string' && spec.url.trim().length > 0;
|
|
63
|
+
if (hasCommand && hasUrl) {
|
|
64
|
+
return 'it declares both a command and a url — pick one';
|
|
65
|
+
}
|
|
66
|
+
if (hasCommand) {
|
|
67
|
+
return {
|
|
68
|
+
type: 'stdio',
|
|
69
|
+
command: spec.command,
|
|
70
|
+
...(spec.args ? { args: [...spec.args] } : {}),
|
|
71
|
+
...(spec.env ? { env: { ...spec.env } } : {}),
|
|
72
|
+
cwd: spec.cwd ?? defaultCwd,
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
if (hasUrl) {
|
|
76
|
+
return {
|
|
77
|
+
type: 'streamable-http',
|
|
78
|
+
url: spec.url,
|
|
79
|
+
...(spec.headers ? { headers: { ...spec.headers } } : {}),
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
return 'it declares neither a command nor a url';
|
|
83
|
+
}
|
|
84
|
+
async function withDeadline(work, ms, what) {
|
|
85
|
+
let timer;
|
|
86
|
+
try {
|
|
87
|
+
return await Promise.race([
|
|
88
|
+
work,
|
|
89
|
+
new Promise((_, reject) => {
|
|
90
|
+
timer = setTimeout(() => reject(new Error(`${what} did not answer within ${ms}ms`)), ms);
|
|
91
|
+
}),
|
|
92
|
+
]);
|
|
93
|
+
}
|
|
94
|
+
finally {
|
|
95
|
+
if (timer)
|
|
96
|
+
clearTimeout(timer);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
const reasonOf = (err) => (err instanceof Error ? err.message : String(err));
|
|
100
|
+
export async function connectMcpServers(config, options) {
|
|
101
|
+
const entries = Object.entries(config ?? {});
|
|
102
|
+
const tools = [];
|
|
103
|
+
const connected = [];
|
|
104
|
+
const failed = [];
|
|
105
|
+
const clients = [];
|
|
106
|
+
// Sequential, not parallel. Each server may spawn a process and each is
|
|
107
|
+
// bounded separately; a parallel fan-out would make the worst case the sum
|
|
108
|
+
// of nothing and the failure output arrive interleaved, for a saving that
|
|
109
|
+
// matters only to someone running many servers, who has other problems.
|
|
110
|
+
for (const [name, spec] of entries) {
|
|
111
|
+
const transport = transportFor(spec, options.cwd);
|
|
112
|
+
if (typeof transport === 'string') {
|
|
113
|
+
failed.push({ name, reason: transport });
|
|
114
|
+
continue;
|
|
115
|
+
}
|
|
116
|
+
const client = new MCPClient({ serverName: name, transport });
|
|
117
|
+
try {
|
|
118
|
+
await withDeadline(client.connect(), CONNECT_TIMEOUT_MS, `server "${name}"`);
|
|
119
|
+
const listed = await withDeadline(client.listTools(), CONNECT_TIMEOUT_MS, `server "${name}" listing its tools`);
|
|
120
|
+
for (const tool of listed) {
|
|
121
|
+
tools.push(mcpToolToToolDefinition(tool, client, name));
|
|
122
|
+
}
|
|
123
|
+
connected.push({ name, toolCount: listed.length });
|
|
124
|
+
clients.push(client);
|
|
125
|
+
}
|
|
126
|
+
catch (err) {
|
|
127
|
+
failed.push({ name, reason: reasonOf(err) });
|
|
128
|
+
// A half-connected client still owns a child process. Tearing it down
|
|
129
|
+
// here is the difference between a failed server and a leaked one.
|
|
130
|
+
//
|
|
131
|
+
// Bounded, and deliberately not dependent on what a transport does
|
|
132
|
+
// when it is closed having never connected — the shipped transports
|
|
133
|
+
// disagree about that (one returns early, one notifies), the
|
|
134
|
+
// divergence is a known one, and a shutdown path that only works
|
|
135
|
+
// under one of the two answers is a shutdown path waiting to hang.
|
|
136
|
+
// Nothing here reads the client's state afterwards either.
|
|
137
|
+
try {
|
|
138
|
+
await withDeadline(client.disconnect(), CLOSE_TIMEOUT_MS, `closing "${name}"`);
|
|
139
|
+
}
|
|
140
|
+
catch {
|
|
141
|
+
// Already gone, never started, or refusing to answer. The failure is
|
|
142
|
+
// already recorded and there is nothing further to do about it.
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
return {
|
|
147
|
+
tools,
|
|
148
|
+
connected,
|
|
149
|
+
failed,
|
|
150
|
+
close: async () => {
|
|
151
|
+
await Promise.all(clients.map((c) => withDeadline(c.disconnect(), CLOSE_TIMEOUT_MS, 'closing a tool server').catch(() => {
|
|
152
|
+
// Shutting down is best effort by definition: the process may
|
|
153
|
+
// already be gone, and nothing useful follows from saying so.
|
|
154
|
+
// Bounded so a server that will not close cannot hold the
|
|
155
|
+
// command open past the work it was asked to do.
|
|
156
|
+
})));
|
|
157
|
+
},
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
//# sourceMappingURL=servers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"servers.js","sourceRoot":"","sources":["../../../src/integrations/mcp/servers.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A closed workspace takes no new conversation from the CLI either.
|
|
3
|
+
*
|
|
4
|
+
* The kernel gained a workspace-closed gate and it was applied to the SDK's own
|
|
5
|
+
* ingress paths. `startConversation` calls `createSession` on the store
|
|
6
|
+
* DIRECTLY, and a store deliberately holds no view of workspace status, so the
|
|
7
|
+
* invariant did not reach here.
|
|
8
|
+
*
|
|
9
|
+
* Whether that mattered turned on one question a grep cannot answer: does the
|
|
10
|
+
* CLI ever reach a project it did not just create? It does. `openSessions`
|
|
11
|
+
* reads the project id back out of `.namzu/cli.json` and creates a new project
|
|
12
|
+
* only when the pointer is missing or stale — so every run after the first
|
|
13
|
+
* attaches to a project that already existed and may since have been closed.
|
|
14
|
+
*
|
|
15
|
+
* That is why this test archives a project created by an EARLIER `openSessions`
|
|
16
|
+
* and then reopens the same directory. A test that archived a project it made
|
|
17
|
+
* itself, in one call, would pass against the first-run case the gate can never
|
|
18
|
+
* fire on.
|
|
19
|
+
*/
|
|
20
|
+
export {};
|
|
21
|
+
//# sourceMappingURL=archived-workspace.test.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"archived-workspace.test.d.ts","sourceRoot":"","sources":["../../../../src/integrations/sessions/__tests__/archived-workspace.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A closed workspace takes no new conversation from the CLI either.
|
|
3
|
+
*
|
|
4
|
+
* The kernel gained a workspace-closed gate and it was applied to the SDK's own
|
|
5
|
+
* ingress paths. `startConversation` calls `createSession` on the store
|
|
6
|
+
* DIRECTLY, and a store deliberately holds no view of workspace status, so the
|
|
7
|
+
* invariant did not reach here.
|
|
8
|
+
*
|
|
9
|
+
* Whether that mattered turned on one question a grep cannot answer: does the
|
|
10
|
+
* CLI ever reach a project it did not just create? It does. `openSessions`
|
|
11
|
+
* reads the project id back out of `.namzu/cli.json` and creates a new project
|
|
12
|
+
* only when the pointer is missing or stale — so every run after the first
|
|
13
|
+
* attaches to a project that already existed and may since have been closed.
|
|
14
|
+
*
|
|
15
|
+
* That is why this test archives a project created by an EARLIER `openSessions`
|
|
16
|
+
* and then reopens the same directory. A test that archived a project it made
|
|
17
|
+
* itself, in one call, would pass against the first-run case the gate can never
|
|
18
|
+
* fire on.
|
|
19
|
+
*/
|
|
20
|
+
import { mkdtempSync, rmSync } from 'node:fs';
|
|
21
|
+
import { tmpdir } from 'node:os';
|
|
22
|
+
import { join } from 'node:path';
|
|
23
|
+
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
|
|
24
|
+
import { ProjectManager, UNKNOWN_TENANT_ID } from '@namzu/sdk';
|
|
25
|
+
import { openSessions, startConversation } from '../store.js';
|
|
26
|
+
let cwd;
|
|
27
|
+
beforeEach(() => {
|
|
28
|
+
cwd = mkdtempSync(join(tmpdir(), 'namzu-archived-'));
|
|
29
|
+
});
|
|
30
|
+
afterEach(() => {
|
|
31
|
+
rmSync(cwd, { recursive: true, force: true });
|
|
32
|
+
});
|
|
33
|
+
describe('a workspace its owner has closed', () => {
|
|
34
|
+
it('refuses a new conversation, instead of quietly accepting work', async () => {
|
|
35
|
+
// First run: creates the project and writes the pointer.
|
|
36
|
+
const first = await openSessions(cwd);
|
|
37
|
+
await new ProjectManager({ store: first.store }).archive(first.projectId, UNKNOWN_TENANT_ID);
|
|
38
|
+
// A later run in the same directory reaches the SAME project through the
|
|
39
|
+
// pointer — the case that exists only from the second run onward.
|
|
40
|
+
const later = await openSessions(cwd);
|
|
41
|
+
expect(later.projectId, 'the pointer has to be what makes this reachable').toBe(first.projectId);
|
|
42
|
+
await expect(startConversation(later)).rejects.toThrow(/archiv|closed/i);
|
|
43
|
+
});
|
|
44
|
+
it('still starts a conversation in an open one', async () => {
|
|
45
|
+
// The other half. A gate nothing can get past has broken the product,
|
|
46
|
+
// and this is the assertion that would catch a `requireOpenProject` call
|
|
47
|
+
// wired to the wrong project id.
|
|
48
|
+
const sessions = await openSessions(cwd);
|
|
49
|
+
const id = await startConversation(sessions);
|
|
50
|
+
expect(typeof id).toBe('string');
|
|
51
|
+
expect(id.length).toBeGreaterThan(0);
|
|
52
|
+
});
|
|
53
|
+
it('names the workspace in the refusal', async () => {
|
|
54
|
+
// A refusal that does not say which workspace sends the reader nowhere:
|
|
55
|
+
// the whole point is that an owner closed this one on purpose.
|
|
56
|
+
const first = await openSessions(cwd);
|
|
57
|
+
await new ProjectManager({ store: first.store }).archive(first.projectId, UNKNOWN_TENANT_ID);
|
|
58
|
+
const later = await openSessions(cwd);
|
|
59
|
+
await expect(startConversation(later)).rejects.toThrow(new RegExp(later.projectId));
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
//# sourceMappingURL=archived-workspace.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"archived-workspace.test.js","sourceRoot":"","sources":["../../../../src/integrations/sessions/__tests__/archived-workspace.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,SAAS,CAAA;AAC7C,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAA;AAChC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAChC,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAA;AAEpE,OAAO,EAAE,cAAc,EAAiB,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAE7E,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AAE7D,IAAI,GAAW,CAAA;AAEf,UAAU,CAAC,GAAG,EAAE;IACf,GAAG,GAAG,WAAW,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,iBAAiB,CAAC,CAAC,CAAA;AACrD,CAAC,CAAC,CAAA;AAEF,SAAS,CAAC,GAAG,EAAE;IACd,MAAM,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAA;AAC9C,CAAC,CAAC,CAAA;AAEF,QAAQ,CAAC,kCAAkC,EAAE,GAAG,EAAE;IACjD,EAAE,CAAC,+DAA+D,EAAE,KAAK,IAAI,EAAE;QAC9E,yDAAyD;QACzD,MAAM,KAAK,GAAG,MAAM,YAAY,CAAC,GAAG,CAAC,CAAA;QACrC,MAAM,IAAI,cAAc,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,OAAO,CACvD,KAAK,CAAC,SAAS,EACf,iBAA6B,CAC7B,CAAA;QAED,yEAAyE;QACzE,kEAAkE;QAClE,MAAM,KAAK,GAAG,MAAM,YAAY,CAAC,GAAG,CAAC,CAAA;QACrC,MAAM,CAAC,KAAK,CAAC,SAAS,EAAE,iDAAiD,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAA;QAEhG,MAAM,MAAM,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAA;IACzE,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,4CAA4C,EAAE,KAAK,IAAI,EAAE;QAC3D,sEAAsE;QACtE,yEAAyE;QACzE,iCAAiC;QACjC,MAAM,QAAQ,GAAG,MAAM,YAAY,CAAC,GAAG,CAAC,CAAA;QAExC,MAAM,EAAE,GAAG,MAAM,iBAAiB,CAAC,QAAQ,CAAC,CAAA;QAE5C,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;QAChC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAA;IACrC,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,oCAAoC,EAAE,KAAK,IAAI,EAAE;QACnD,wEAAwE;QACxE,+DAA+D;QAC/D,MAAM,KAAK,GAAG,MAAM,YAAY,CAAC,GAAG,CAAC,CAAA;QACrC,MAAM,IAAI,cAAc,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,OAAO,CACvD,KAAK,CAAC,SAAS,EACf,iBAA6B,CAC7B,CAAA;QAED,MAAM,KAAK,GAAG,MAAM,YAAY,CAAC,GAAG,CAAC,CAAA;QAErC,MAAM,MAAM,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAA;IACpF,CAAC,CAAC,CAAA;AACH,CAAC,CAAC,CAAA"}
|
|
@@ -38,7 +38,21 @@ export declare function openSessions(cwd: string): Promise<CliSessions>;
|
|
|
38
38
|
* the mapped id was wiped.
|
|
39
39
|
*/
|
|
40
40
|
export declare function resolveConversation(s: CliSessions, key: string): Promise<SessionId>;
|
|
41
|
-
/**
|
|
41
|
+
/**
|
|
42
|
+
* Start a fresh conversation; returns its session id.
|
|
43
|
+
*
|
|
44
|
+
* The workspace gate runs HERE rather than being assumed from the caller,
|
|
45
|
+
* because this is a store call and a store deliberately holds no view of
|
|
46
|
+
* workspace status — the SDK's own note says a direct store caller bypasses
|
|
47
|
+
* the invariant, and this was such a caller.
|
|
48
|
+
*
|
|
49
|
+
* It is not ceremony, and the difference is `openSessions` above: the project
|
|
50
|
+
* id is read back out of `.namzu/cli.json` and a new project is created only
|
|
51
|
+
* when the pointer is missing or stale. So on every run after the first, this
|
|
52
|
+
* attaches a session to a project it did NOT just create — one an owner may
|
|
53
|
+
* since have closed. A freshly created project is always open, which is why
|
|
54
|
+
* the first run could never have shown this.
|
|
55
|
+
*/
|
|
42
56
|
export declare function startConversation(s: CliSessions): Promise<SessionId>;
|
|
43
57
|
/** Append messages (in order) to a conversation. */
|
|
44
58
|
export declare function appendMessages(s: CliSessions, sessionId: SessionId, messages: readonly Message[]): Promise<void>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../../src/integrations/sessions/store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAIH,OAAO,EACN,gBAAgB,EAChB,KAAK,OAAO,EACZ,KAAK,SAAS,EACd,KAAK,SAAS,EACd,KAAK,QAAQ,EACb,KAAK,QAAQ,
|
|
1
|
+
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../../src/integrations/sessions/store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAIH,OAAO,EACN,gBAAgB,EAChB,KAAK,OAAO,EACZ,KAAK,SAAS,EACd,KAAK,SAAS,EACd,KAAK,QAAQ,EACb,KAAK,QAAQ,EAGb,MAAM,YAAY,CAAA;AAKnB,MAAM,WAAW,WAAW;IAC3B,QAAQ,CAAC,KAAK,EAAE,gBAAgB,CAAA;IAChC,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAA;IAC7B,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAA;IAC3B,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAA;IAC3B,sEAAsE;IACtE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CACrB;AAED,MAAM,WAAW,kBAAkB;IAClC,QAAQ,CAAC,EAAE,EAAE,SAAS,CAAA;IACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CACtB;AAED;;;;GAIG;AACH,wBAAsB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAsBpE;AAgBD;;;;;GAKG;AACH,wBAAsB,mBAAmB,CAAC,CAAC,EAAE,WAAW,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC,CAWzF;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,iBAAiB,CAAC,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,SAAS,CAAC,CAO1E;AAED,oDAAoD;AACpD,wBAAsB,cAAc,CACnC,CAAC,EAAE,WAAW,EACd,SAAS,EAAE,SAAS,EACpB,QAAQ,EAAE,SAAS,OAAO,EAAE,GAC1B,OAAO,CAAC,IAAI,CAAC,CAIf;AAED,kDAAkD;AAClD,wBAAsB,gBAAgB,CAAC,CAAC,EAAE,WAAW,EAAE,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CAE/F;AAED,6EAA6E;AAC7E,wBAAsB,UAAU,CAAC,CAAC,EAAE,WAAW,EAAE,KAAK,SAAK,GAAG,OAAO,CAAC,kBAAkB,EAAE,CAAC,CAc1F"}
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
*/
|
|
13
13
|
import { mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
14
14
|
import { join } from 'node:path';
|
|
15
|
-
import { DiskSessionStore, UNKNOWN_TENANT_ID, } from '@namzu/sdk';
|
|
15
|
+
import { DiskSessionStore, UNKNOWN_TENANT_ID, requireOpenProject, } from '@namzu/sdk';
|
|
16
16
|
const TENANT = UNKNOWN_TENANT_ID;
|
|
17
17
|
const THREAD = 'thd_namzu-cli';
|
|
18
18
|
/**
|
|
@@ -75,8 +75,23 @@ export async function resolveConversation(s, key) {
|
|
|
75
75
|
writeFileSync(join(s.root, DESKTOP_MAP), `${JSON.stringify(map, null, 2)}\n`, { mode: 0o600 });
|
|
76
76
|
return id;
|
|
77
77
|
}
|
|
78
|
-
/**
|
|
78
|
+
/**
|
|
79
|
+
* Start a fresh conversation; returns its session id.
|
|
80
|
+
*
|
|
81
|
+
* The workspace gate runs HERE rather than being assumed from the caller,
|
|
82
|
+
* because this is a store call and a store deliberately holds no view of
|
|
83
|
+
* workspace status — the SDK's own note says a direct store caller bypasses
|
|
84
|
+
* the invariant, and this was such a caller.
|
|
85
|
+
*
|
|
86
|
+
* It is not ceremony, and the difference is `openSessions` above: the project
|
|
87
|
+
* id is read back out of `.namzu/cli.json` and a new project is created only
|
|
88
|
+
* when the pointer is missing or stale. So on every run after the first, this
|
|
89
|
+
* attaches a session to a project it did NOT just create — one an owner may
|
|
90
|
+
* since have closed. A freshly created project is always open, which is why
|
|
91
|
+
* the first run could never have shown this.
|
|
92
|
+
*/
|
|
79
93
|
export async function startConversation(s) {
|
|
94
|
+
await requireOpenProject(s.store, s.projectId, s.tenantId, 'cli-session');
|
|
80
95
|
const session = await s.store.createSession({ threadId: s.threadId, projectId: s.projectId, currentActor: null }, s.tenantId);
|
|
81
96
|
return session.id;
|
|
82
97
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"store.js","sourceRoot":"","sources":["../../../src/integrations/sessions/store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAA;AAChE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAChC,OAAO,EACN,gBAAgB,EAMhB,iBAAiB,
|
|
1
|
+
{"version":3,"file":"store.js","sourceRoot":"","sources":["../../../src/integrations/sessions/store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAA;AAChE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAChC,OAAO,EACN,gBAAgB,EAMhB,iBAAiB,EACjB,kBAAkB,GAClB,MAAM,YAAY,CAAA;AAEnB,MAAM,MAAM,GAAG,iBAA6B,CAAA;AAC5C,MAAM,MAAM,GAAG,eAA2B,CAAA;AAkB1C;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,GAAW;IAC7C,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAA;IAChC,MAAM,KAAK,GAAG,IAAI,gBAAgB,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAA;IACrD,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,EAAE,UAAU,CAAC,CAAA;IAE1C,IAAI,SAAgC,CAAA;IACpC,IAAI,CAAC;QACJ,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,WAAW,EAAE,MAAM,CAAC,CAA2B,CAAA;QACnF,IAAI,OAAO,GAAG,CAAC,SAAS,KAAK,QAAQ;YAAE,SAAS,GAAG,GAAG,CAAC,SAAsB,CAAA;IAC9E,CAAC;IAAC,MAAM,CAAC;QACR,iBAAiB;IAClB,CAAC;IACD,IAAI,SAAS,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,UAAU,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC,EAAE,CAAC;QAC/D,SAAS,GAAG,SAAS,CAAA,CAAC,+BAA+B;IACtD,CAAC;IACD,IAAI,CAAC,SAAS,EAAE,CAAC;QAChB,MAAM,OAAO,GAAG,MAAM,KAAK,CAAC,aAAa,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,EAAE,MAAM,CAAC,CAAA;QAC1F,SAAS,GAAG,OAAO,CAAC,EAAE,CAAA;QACtB,SAAS,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;QACpC,aAAa,CAAC,WAAW,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,EAAE,SAAS,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAA;IAC3F,CAAC;IACD,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,CAAA;AACtE,CAAC;AAED,uEAAuE;AACvE,oEAAoE;AACpE,4DAA4D;AAC5D,MAAM,WAAW,GAAG,uBAAuB,CAAA;AAE3C,SAAS,cAAc,CAAC,IAAY;IACnC,IAAI,CAAC;QACJ,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,WAAW,CAAC,EAAE,MAAM,CAAC,CAAC,CAAA;QACrE,OAAO,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAE,GAA8B,CAAC,CAAC,CAAC,EAAE,CAAA;IAC7E,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,EAAE,CAAA;IACV,CAAC;AACF,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,CAAc,EAAE,GAAW;IACpE,MAAM,GAAG,GAAG,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,CAAA;IAClC,MAAM,QAAQ,GAAG,GAAG,CAAC,GAAG,CAAC,CAAA;IACzB,IAAI,QAAQ,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,UAAU,CAAC,QAAqB,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC;QAC/E,OAAO,QAAqB,CAAA;IAC7B,CAAC;IACD,MAAM,EAAE,GAAG,MAAM,iBAAiB,CAAC,CAAC,CAAC,CAAA;IACrC,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,CAAA;IACb,SAAS,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;IACtC,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,WAAW,CAAC,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAA;IAC9F,OAAO,EAAE,CAAA;AACV,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,CAAc;IACrD,MAAM,kBAAkB,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAA;IACzE,MAAM,OAAO,GAAG,MAAM,CAAC,CAAC,KAAK,CAAC,aAAa,CAC1C,EAAE,QAAQ,EAAE,CAAC,CAAC,QAAQ,EAAE,SAAS,EAAE,CAAC,CAAC,SAAS,EAAE,YAAY,EAAE,IAAI,EAAE,EACpE,CAAC,CAAC,QAAQ,CACV,CAAA;IACD,OAAO,OAAO,CAAC,EAAE,CAAA;AAClB,CAAC;AAED,oDAAoD;AACpD,MAAM,CAAC,KAAK,UAAU,cAAc,CACnC,CAAc,EACd,SAAoB,EACpB,QAA4B;IAE5B,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;QAC1B,MAAM,CAAC,CAAC,KAAK,CAAC,aAAa,CAAC,SAAS,EAAE,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAA;IACtD,CAAC;AACF,CAAC;AAED,kDAAkD;AAClD,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,CAAc,EAAE,SAAoB;IAC1E,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,YAAY,CAAC,SAAS,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAA;AAChE,CAAC;AAED,6EAA6E;AAC7E,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,CAAc,EAAE,KAAK,GAAG,EAAE;IAC1D,MAAM,QAAQ,GAAG,MAAM,CAAC,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAA;IACnE,MAAM,GAAG,GAAyB,EAAE,CAAA;IACpC,KAAK,MAAM,IAAI,IAAI,QAAQ,EAAE,CAAC;QAC7B,MAAM,QAAQ,GAAG,MAAM,CAAC,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAA;QAChE,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;YAAE,SAAQ;QACnC,GAAG,CAAC,IAAI,CAAC;YACR,EAAE,EAAE,IAAI,CAAC,EAAE;YACX,KAAK,EAAE,iBAAiB,CAAC,QAAQ,CAAC;YAClC,SAAS,EAAE,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC;YAChC,KAAK,EAAE,QAAQ,CAAC,MAAM;SACtB,CAAC,CAAA;IACH,CAAC;IACD,OAAO,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAA;AAClF,CAAC;AAED,SAAS,iBAAiB,CAAC,QAA4B;IACtD,MAAM,SAAS,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC,CAAA;IACzD,MAAM,GAAG,GAAG,OAAO,SAAS,EAAE,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,cAAc,CAAA;IACvF,MAAM,IAAI,GAAG,GAAG,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAA;IAC5C,OAAO,IAAI,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,IAAI,cAAc,CAAA;AAC3E,CAAC;AAED,SAAS,KAAK,CAAC,KAAc;IAC5B,IAAI,KAAK,YAAY,IAAI;QAAE,OAAO,KAAK,CAAC,WAAW,EAAE,CAAA;IACrD,OAAO,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAA;AACrE,CAAC"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { afterEach, describe, expect, it, vi } from 'vitest';
|
|
2
|
-
import { LocalTaskGateway } from '@namzu/sdk';
|
|
2
|
+
import { AgentRegistry, LocalTaskGateway, } from '@namzu/sdk';
|
|
3
3
|
import { createSubagentRuntime } from '../runtime.js';
|
|
4
4
|
/**
|
|
5
5
|
* A delegated run belongs inside the turn that asked for it.
|
|
@@ -20,8 +20,13 @@ const fakeSpan = { __brand: 'span' };
|
|
|
20
20
|
function toolContext(parentSpan) {
|
|
21
21
|
return { runId: 'run_test', ...(parentSpan ? { parentSpan } : {}) };
|
|
22
22
|
}
|
|
23
|
-
async function buildAgentTool() {
|
|
23
|
+
async function buildAgentTool(extra = {}) {
|
|
24
24
|
const created = [];
|
|
25
|
+
const registered = [];
|
|
26
|
+
vi.spyOn(AgentRegistry.prototype, 'register').mockImplementation((def) => {
|
|
27
|
+
for (const d of Array.isArray(def) ? def : [def])
|
|
28
|
+
registered.push(d);
|
|
29
|
+
});
|
|
25
30
|
vi.spyOn(LocalTaskGateway.prototype, 'createTask').mockImplementation(async (options) => {
|
|
26
31
|
created.push(options);
|
|
27
32
|
return { taskId: 'tsk_1' };
|
|
@@ -35,8 +40,9 @@ async function buildAgentTool() {
|
|
|
35
40
|
model: 'test-model',
|
|
36
41
|
buildProvider: () => ({}),
|
|
37
42
|
buildTools: () => ({}),
|
|
43
|
+
...extra,
|
|
38
44
|
});
|
|
39
|
-
return { agentTool: runtime.agentTool, created };
|
|
45
|
+
return { agentTool: runtime.agentTool, created, registered };
|
|
40
46
|
}
|
|
41
47
|
afterEach(() => {
|
|
42
48
|
vi.restoreAllMocks();
|
|
@@ -66,4 +72,43 @@ describe('the Agent tool parents a delegated run to the turn that asked for it',
|
|
|
66
72
|
expect(created[0]?.parentSpan).toBe(fakeSpan);
|
|
67
73
|
});
|
|
68
74
|
});
|
|
75
|
+
/**
|
|
76
|
+
* The project's standing instructions bind a specialist the model invents at
|
|
77
|
+
* call time, not only the pre-registered general-purpose sub-agent.
|
|
78
|
+
*
|
|
79
|
+
* `role` is a SECOND registration path to the same definition builder, and one
|
|
80
|
+
* of two paths carrying a signal is how this class of defect survives a green
|
|
81
|
+
* suite: the delegation everyone tests would honour the project's rules and
|
|
82
|
+
* the one the model actually reaches for — a named specialist — would not.
|
|
83
|
+
*/
|
|
84
|
+
describe('a sub-agent is bound by the project it works in', () => {
|
|
85
|
+
const INSTRUCTIONS = '## Project instructions\n\nNever use a default export.';
|
|
86
|
+
it('gives the general-purpose sub-agent the block', async () => {
|
|
87
|
+
const { registered } = await buildAgentTool({ projectInstructions: INSTRUCTIONS });
|
|
88
|
+
const general = registered.find((d) => d.info.id === 'general-purpose');
|
|
89
|
+
const config = (await general?.configBuilder?.({}));
|
|
90
|
+
expect(config?.systemPrompt).toContain('Never use a default export.');
|
|
91
|
+
});
|
|
92
|
+
it('gives a specialist defined at call time the same block', async () => {
|
|
93
|
+
const { agentTool, registered } = await buildAgentTool({ projectInstructions: INSTRUCTIONS });
|
|
94
|
+
await agentTool.execute({ description: 'audit', prompt: 'do a thing', role: 'You are a security auditor' }, toolContext());
|
|
95
|
+
const specialist = registered.find((d) => d.info.id.startsWith('dyn-'));
|
|
96
|
+
if (!specialist?.configBuilder) {
|
|
97
|
+
throw new Error('no dynamic specialist was registered — this test proves nothing');
|
|
98
|
+
}
|
|
99
|
+
const prompt = String((await specialist.configBuilder({})).systemPrompt ?? '');
|
|
100
|
+
expect(prompt).toContain('You are a security auditor');
|
|
101
|
+
expect(prompt).toContain('Never fabricate.');
|
|
102
|
+
expect(prompt).toContain('Never use a default export.');
|
|
103
|
+
// Order is the containment: a persona and a project file are both text
|
|
104
|
+
// the model can influence, and both sit after the guardrails.
|
|
105
|
+
expect(prompt.indexOf('Never fabricate.')).toBeLessThan(prompt.indexOf('Never use a default export.'));
|
|
106
|
+
});
|
|
107
|
+
it('adds nothing when the project declares none', async () => {
|
|
108
|
+
const { registered } = await buildAgentTool();
|
|
109
|
+
const general = registered.find((d) => d.info.id === 'general-purpose');
|
|
110
|
+
const config = (await general?.configBuilder?.({}));
|
|
111
|
+
expect(config?.systemPrompt).not.toContain('Project instructions');
|
|
112
|
+
});
|
|
113
|
+
});
|
|
69
114
|
//# sourceMappingURL=delegation-trace.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"delegation-trace.test.js","sourceRoot":"","sources":["../../../../src/integrations/subagents/__tests__/delegation-trace.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAA;AAE5D,OAAO,
|
|
1
|
+
{"version":3,"file":"delegation-trace.test.js","sourceRoot":"","sources":["../../../../src/integrations/subagents/__tests__/delegation-trace.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -21,6 +21,27 @@ export interface SubagentRuntimeOptions {
|
|
|
21
21
|
/** Build the sub-agent's tool registry (its own working set). */
|
|
22
22
|
readonly buildTools: () => ToolRegistryContract;
|
|
23
23
|
readonly verificationGate?: VerificationGateConfig;
|
|
24
|
+
/**
|
|
25
|
+
* The project's own instruction block, already composed, or absent when the
|
|
26
|
+
* working directory declares none.
|
|
27
|
+
*
|
|
28
|
+
* A sub-agent runs in the same directory and writes the same code as the
|
|
29
|
+
* parent that dispatched it, so the project's standing policy applies to it
|
|
30
|
+
* identically. Omitting it would produce the shape where the rules hold
|
|
31
|
+
* until the moment work is delegated, and the delegating turn cannot tell:
|
|
32
|
+
* the child reports success either way.
|
|
33
|
+
*/
|
|
34
|
+
readonly projectInstructions?: string;
|
|
35
|
+
/**
|
|
36
|
+
* Produces the "where and when" block for a child, at the moment the child
|
|
37
|
+
* is built rather than once for the session.
|
|
38
|
+
*
|
|
39
|
+
* A function because both facts it carries can change while the parent runs:
|
|
40
|
+
* a long session crosses midnight, and the parent may itself have checked
|
|
41
|
+
* out a branch since it started. A string captured at startup would hand
|
|
42
|
+
* every later sub-agent a confident, stale answer.
|
|
43
|
+
*/
|
|
44
|
+
readonly readEnvironment?: () => Promise<string>;
|
|
24
45
|
/** Receives the child's RunEvents (lineage-stamped) — for the tree view. */
|
|
25
46
|
readonly onEvent?: (event: RunEvent) => void;
|
|
26
47
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../../src/integrations/subagents/runtime.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAYN,KAAK,WAAW,EAIhB,KAAK,QAAQ,EAIb,KAAK,WAAW,EAGhB,KAAK,cAAc,EACnB,KAAK,oBAAoB,EAEzB,KAAK,sBAAsB,EAI3B,MAAM,YAAY,CAAA;AAEnB,eAAO,MAAM,wBAAwB,oBAAoB,CAAA;AAczD,MAAM,WAAW,sBAAsB;IACtC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,yEAAyE;IACzE,QAAQ,CAAC,aAAa,EAAE,MAAM,WAAW,CAAA;IACzC,iEAAiE;IACjE,QAAQ,CAAC,UAAU,EAAE,MAAM,oBAAoB,CAAA;IAC/C,QAAQ,CAAC,gBAAgB,CAAC,EAAE,sBAAsB,CAAA;IAClD,4EAA4E;IAC5E,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,QAAQ,KAAK,IAAI,CAAA;CAC5C;AAED,MAAM,WAAW,eAAe;IAC/B,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAA;IAC7B,QAAQ,CAAC,SAAS,EAAE,cAAc,CAAA;IAClC,QAAQ,CAAC,eAAe,EAAE,SAAS,MAAM,EAAE,CAAA;CAC3C;AAED;;;GAGG;AACH,wBAAsB,qBAAqB,CAC1C,IAAI,EAAE,sBAAsB,GAC1B,OAAO,CAAC,eAAe,CAAC,
|
|
1
|
+
{"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../../src/integrations/subagents/runtime.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAYN,KAAK,WAAW,EAIhB,KAAK,QAAQ,EAIb,KAAK,WAAW,EAGhB,KAAK,cAAc,EACnB,KAAK,oBAAoB,EAEzB,KAAK,sBAAsB,EAI3B,MAAM,YAAY,CAAA;AAEnB,eAAO,MAAM,wBAAwB,oBAAoB,CAAA;AAczD,MAAM,WAAW,sBAAsB;IACtC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,yEAAyE;IACzE,QAAQ,CAAC,aAAa,EAAE,MAAM,WAAW,CAAA;IACzC,iEAAiE;IACjE,QAAQ,CAAC,UAAU,EAAE,MAAM,oBAAoB,CAAA;IAC/C,QAAQ,CAAC,gBAAgB,CAAC,EAAE,sBAAsB,CAAA;IAClD;;;;;;;;;OASG;IACH,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,CAAA;IACrC;;;;;;;;OAQG;IACH,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAA;IAChD,4EAA4E;IAC5E,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,QAAQ,KAAK,IAAI,CAAA;CAC5C;AAED,MAAM,WAAW,eAAe;IAC/B,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAA;IAC7B,QAAQ,CAAC,SAAS,EAAE,cAAc,CAAA;IAClC,QAAQ,CAAC,eAAe,EAAE,SAAS,MAAM,EAAE,CAAA;CAC3C;AAED;;;GAGG;AACH,wBAAsB,qBAAqB,CAC1C,IAAI,EAAE,sBAAsB,GAC1B,OAAO,CAAC,eAAe,CAAC,CA4J1B"}
|