@prestyj/cli 5.3.0 → 5.3.1
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/app-sidecar.js +581 -55
- package/dist/app-sidecar.js.map +1 -1
- package/dist/core/agent-session-compaction.test.js +89 -0
- package/dist/core/agent-session-compaction.test.js.map +1 -1
- package/dist/core/agent-session.d.ts +71 -3
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +261 -47
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/autopilot-cycle.d.ts +69 -17
- package/dist/core/autopilot-cycle.d.ts.map +1 -1
- package/dist/core/autopilot-cycle.js +82 -13
- package/dist/core/autopilot-cycle.js.map +1 -1
- package/dist/core/autopilot-cycle.test.js +206 -10
- package/dist/core/autopilot-cycle.test.js.map +1 -1
- package/dist/core/autopilot-gate.d.ts +48 -22
- package/dist/core/autopilot-gate.d.ts.map +1 -1
- package/dist/core/autopilot-gate.js +110 -1
- package/dist/core/autopilot-gate.js.map +1 -1
- package/dist/core/autopilot-gate.test.js +139 -3
- package/dist/core/autopilot-gate.test.js.map +1 -1
- package/dist/core/autopilot-verdict.d.ts +6 -0
- package/dist/core/autopilot-verdict.d.ts.map +1 -1
- package/dist/core/autopilot-verdict.js +75 -1
- package/dist/core/autopilot-verdict.js.map +1 -1
- package/dist/core/autopilot-verdict.test.js +63 -0
- package/dist/core/autopilot-verdict.test.js.map +1 -1
- package/dist/core/bash-spawn-benchmark.d.ts +2 -0
- package/dist/core/bash-spawn-benchmark.d.ts.map +1 -0
- package/dist/core/bash-spawn-benchmark.js +139 -0
- package/dist/core/bash-spawn-benchmark.js.map +1 -0
- package/dist/core/hashline-edit-benchmark.d.ts +33 -1
- package/dist/core/hashline-edit-benchmark.d.ts.map +1 -1
- package/dist/core/hashline-edit-benchmark.js +193 -21
- package/dist/core/hashline-edit-benchmark.js.map +1 -1
- package/dist/core/hashline-edit-benchmark.test.js +51 -2
- package/dist/core/hashline-edit-benchmark.test.js.map +1 -1
- package/dist/core/mcp/deferred-catalog.d.ts +28 -0
- package/dist/core/mcp/deferred-catalog.d.ts.map +1 -0
- package/dist/core/mcp/deferred-catalog.js +72 -0
- package/dist/core/mcp/deferred-catalog.js.map +1 -0
- package/dist/core/mcp/resolve-stdio.d.ts +19 -3
- package/dist/core/mcp/resolve-stdio.d.ts.map +1 -1
- package/dist/core/mcp/resolve-stdio.js +136 -5
- package/dist/core/mcp/resolve-stdio.js.map +1 -1
- package/dist/core/mcp/resolve-stdio.test.js +82 -1
- package/dist/core/mcp/resolve-stdio.test.js.map +1 -1
- package/dist/core/nolan-context.d.ts +26 -2
- package/dist/core/nolan-context.d.ts.map +1 -1
- package/dist/core/nolan-context.js +46 -4
- package/dist/core/nolan-context.js.map +1 -1
- package/dist/core/nolan-context.test.js +53 -12
- package/dist/core/nolan-context.test.js.map +1 -1
- package/dist/core/nolan-prompt.d.ts +2 -15
- package/dist/core/nolan-prompt.d.ts.map +1 -1
- package/dist/core/nolan-prompt.js +96 -15
- package/dist/core/nolan-prompt.js.map +1 -1
- package/dist/core/nolan-prompt.test.js +102 -7
- package/dist/core/nolan-prompt.test.js.map +1 -1
- package/dist/core/persistent-shell.d.ts +27 -0
- package/dist/core/persistent-shell.d.ts.map +1 -0
- package/dist/core/persistent-shell.js +150 -0
- package/dist/core/persistent-shell.js.map +1 -0
- package/dist/core/persistent-shell.test.d.ts +2 -0
- package/dist/core/persistent-shell.test.d.ts.map +1 -0
- package/dist/core/persistent-shell.test.js +84 -0
- package/dist/core/persistent-shell.test.js.map +1 -0
- package/dist/core/process-manager-dev-server-repro.test.js +34 -6
- package/dist/core/process-manager-dev-server-repro.test.js.map +1 -1
- package/dist/core/progress/engine.d.ts +23 -0
- package/dist/core/progress/engine.d.ts.map +1 -0
- package/dist/core/progress/engine.js +131 -0
- package/dist/core/progress/engine.js.map +1 -0
- package/dist/core/progress/engine.test.d.ts +2 -0
- package/dist/core/progress/engine.test.d.ts.map +1 -0
- package/dist/core/progress/engine.test.js +136 -0
- package/dist/core/progress/engine.test.js.map +1 -0
- package/dist/core/progress/git-xp.d.ts +16 -0
- package/dist/core/progress/git-xp.d.ts.map +1 -0
- package/dist/core/progress/git-xp.js +106 -0
- package/dist/core/progress/git-xp.js.map +1 -0
- package/dist/core/progress/git-xp.test.d.ts +2 -0
- package/dist/core/progress/git-xp.test.d.ts.map +1 -0
- package/dist/core/progress/git-xp.test.js +88 -0
- package/dist/core/progress/git-xp.test.js.map +1 -0
- package/dist/core/progress/ranks.d.ts +21 -0
- package/dist/core/progress/ranks.d.ts.map +1 -0
- package/dist/core/progress/ranks.js +141 -0
- package/dist/core/progress/ranks.js.map +1 -0
- package/dist/core/progress/ranks.test.d.ts +2 -0
- package/dist/core/progress/ranks.test.d.ts.map +1 -0
- package/dist/core/progress/ranks.test.js +59 -0
- package/dist/core/progress/ranks.test.js.map +1 -0
- package/dist/core/progress/rebuild.d.ts +7 -0
- package/dist/core/progress/rebuild.d.ts.map +1 -0
- package/dist/core/progress/rebuild.js +106 -0
- package/dist/core/progress/rebuild.js.map +1 -0
- package/dist/core/progress/rebuild.test.d.ts +2 -0
- package/dist/core/progress/rebuild.test.d.ts.map +1 -0
- package/dist/core/progress/rebuild.test.js +72 -0
- package/dist/core/progress/rebuild.test.js.map +1 -0
- package/dist/core/progress/store.d.ts +35 -0
- package/dist/core/progress/store.d.ts.map +1 -0
- package/dist/core/progress/store.js +200 -0
- package/dist/core/progress/store.js.map +1 -0
- package/dist/core/progress/store.test.d.ts +2 -0
- package/dist/core/progress/store.test.d.ts.map +1 -0
- package/dist/core/progress/store.test.js +108 -0
- package/dist/core/progress/store.test.js.map +1 -0
- package/dist/core/progress/types.d.ts +108 -0
- package/dist/core/progress/types.d.ts.map +1 -0
- package/dist/core/progress/types.js +3 -0
- package/dist/core/progress/types.js.map +1 -0
- package/dist/core/project-discovery.d.ts.map +1 -1
- package/dist/core/project-discovery.js +40 -9
- package/dist/core/project-discovery.js.map +1 -1
- package/dist/core/project-discovery.test.d.ts +2 -0
- package/dist/core/project-discovery.test.d.ts.map +1 -0
- package/dist/core/project-discovery.test.js +104 -0
- package/dist/core/project-discovery.test.js.map +1 -0
- package/dist/core/session-history.d.ts +51 -0
- package/dist/core/session-history.d.ts.map +1 -0
- package/dist/core/session-history.js +156 -0
- package/dist/core/session-history.js.map +1 -0
- package/dist/core/session-history.test.d.ts +2 -0
- package/dist/core/session-history.test.d.ts.map +1 -0
- package/dist/core/session-history.test.js +101 -0
- package/dist/core/session-history.test.js.map +1 -0
- package/dist/core/session-manager.d.ts +34 -0
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +67 -0
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/session-manager.test.js +140 -1
- package/dist/core/session-manager.test.js.map +1 -1
- package/dist/core/settings-manager.d.ts +1 -0
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +4 -0
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/system-prompt.d.ts.map +1 -1
- package/dist/system-prompt.js +12 -8
- package/dist/system-prompt.js.map +1 -1
- package/dist/system-prompt.test.js +15 -20
- package/dist/system-prompt.test.js.map +1 -1
- package/dist/tools/bash.d.ts +1 -0
- package/dist/tools/bash.d.ts.map +1 -1
- package/dist/tools/bash.js +27 -2
- package/dist/tools/bash.js.map +1 -1
- package/dist/tools/edit.d.ts +9 -2
- package/dist/tools/edit.d.ts.map +1 -1
- package/dist/tools/edit.js +91 -10
- package/dist/tools/edit.js.map +1 -1
- package/dist/tools/edit.test.js +97 -0
- package/dist/tools/edit.test.js.map +1 -1
- package/dist/tools/plan-mode.test.js +25 -0
- package/dist/tools/plan-mode.test.js.map +1 -1
- package/dist/tools/prompt-hints.d.ts.map +1 -1
- package/dist/tools/prompt-hints.js +3 -0
- package/dist/tools/prompt-hints.js.map +1 -1
- package/dist/tools/subagent.d.ts.map +1 -1
- package/dist/tools/subagent.js +24 -1
- package/dist/tools/subagent.js.map +1 -1
- package/dist/tools/tool-search.d.ts +15 -0
- package/dist/tools/tool-search.d.ts.map +1 -0
- package/dist/tools/tool-search.js +35 -0
- package/dist/tools/tool-search.js.map +1 -0
- package/dist/ui/hooks/useAgentLoop.d.ts.map +1 -1
- package/dist/ui/hooks/useAgentLoop.js +22 -9
- package/dist/ui/hooks/useAgentLoop.js.map +1 -1
- package/package.json +4 -4
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Holds MCP tools OUT of the per-turn request payload until the model asks
|
|
3
|
+
* for them via `tool_search`.
|
|
4
|
+
*
|
|
5
|
+
* Benchmarked (bench/RESULTS.md, bench A): injecting every MCP tool schema
|
|
6
|
+
* eagerly cost ~33KB (~8.3k tokens) per cache-miss turn with just two MCP
|
|
7
|
+
* servers connected — 56% of all billed input tokens in a 6-turn session.
|
|
8
|
+
* Deferring keeps the tool prefix small and byte-stable; promotion is a
|
|
9
|
+
* one-time cache break paid only when a capability is actually needed.
|
|
10
|
+
*/
|
|
11
|
+
export class DeferredToolCatalog {
|
|
12
|
+
byName = new Map();
|
|
13
|
+
add(tools) {
|
|
14
|
+
for (const tool of tools)
|
|
15
|
+
this.byName.set(tool.name, tool);
|
|
16
|
+
}
|
|
17
|
+
/** Remove tools (e.g. when their MCP server is reloaded/removed). */
|
|
18
|
+
removeWhere(predicate) {
|
|
19
|
+
for (const name of [...this.byName.keys()]) {
|
|
20
|
+
if (predicate(name))
|
|
21
|
+
this.byName.delete(name);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
get size() {
|
|
25
|
+
return this.byName.size;
|
|
26
|
+
}
|
|
27
|
+
/** Names still waiting in the catalog (for "no match" tool output). */
|
|
28
|
+
names() {
|
|
29
|
+
return [...this.byName.keys()];
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Rank catalog tools against a free-text capability query.
|
|
33
|
+
* Word-overlap scoring: name hits weigh 3×, description hits 1×.
|
|
34
|
+
*/
|
|
35
|
+
search(query, limit = 5) {
|
|
36
|
+
const words = query
|
|
37
|
+
.toLowerCase()
|
|
38
|
+
.split(/[^a-z0-9]+/)
|
|
39
|
+
.filter((w) => w.length > 1);
|
|
40
|
+
if (words.length === 0)
|
|
41
|
+
return [];
|
|
42
|
+
const scored = [];
|
|
43
|
+
for (const tool of this.byName.values()) {
|
|
44
|
+
const name = tool.name.toLowerCase();
|
|
45
|
+
const desc = tool.description.toLowerCase();
|
|
46
|
+
let score = 0;
|
|
47
|
+
for (const w of words) {
|
|
48
|
+
if (name.includes(w))
|
|
49
|
+
score += 3;
|
|
50
|
+
if (desc.includes(w))
|
|
51
|
+
score += 1;
|
|
52
|
+
}
|
|
53
|
+
if (score > 0)
|
|
54
|
+
scored.push({ tool, score });
|
|
55
|
+
}
|
|
56
|
+
scored.sort((a, b) => b.score - a.score);
|
|
57
|
+
return scored.slice(0, limit).map((s) => s.tool);
|
|
58
|
+
}
|
|
59
|
+
/** Remove the named tools from the catalog and return them for activation. */
|
|
60
|
+
promote(names) {
|
|
61
|
+
const promoted = [];
|
|
62
|
+
for (const name of names) {
|
|
63
|
+
const tool = this.byName.get(name);
|
|
64
|
+
if (tool) {
|
|
65
|
+
this.byName.delete(name);
|
|
66
|
+
promoted.push(tool);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return promoted;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=deferred-catalog.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deferred-catalog.js","sourceRoot":"","sources":["../../../src/core/mcp/deferred-catalog.ts"],"names":[],"mappings":"AAEA;;;;;;;;;GASG;AACH,MAAM,OAAO,mBAAmB;IACtB,MAAM,GAAG,IAAI,GAAG,EAAqB,CAAC;IAE9C,GAAG,CAAC,KAAkB;QACpB,KAAK,MAAM,IAAI,IAAI,KAAK;YAAE,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAC7D,CAAC;IAED,qEAAqE;IACrE,WAAW,CAAC,SAAoC;QAC9C,KAAK,MAAM,IAAI,IAAI,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC;YAC3C,IAAI,SAAS,CAAC,IAAI,CAAC;gBAAE,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAChD,CAAC;IACH,CAAC;IAED,IAAI,IAAI;QACN,OAAO,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;IAC1B,CAAC;IAED,uEAAuE;IACvE,KAAK;QACH,OAAO,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;IACjC,CAAC;IAED;;;OAGG;IACH,MAAM,CAAC,KAAa,EAAE,KAAK,GAAG,CAAC;QAC7B,MAAM,KAAK,GAAG,KAAK;aAChB,WAAW,EAAE;aACb,KAAK,CAAC,YAAY,CAAC;aACnB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QAC/B,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,EAAE,CAAC;QAClC,MAAM,MAAM,GAAyC,EAAE,CAAC;QACxD,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,CAAC;YACxC,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;YACrC,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,WAAW,EAAE,CAAC;YAC5C,IAAI,KAAK,GAAG,CAAC,CAAC;YACd,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;gBACtB,IAAI,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;oBAAE,KAAK,IAAI,CAAC,CAAC;gBACjC,IAAI,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;oBAAE,KAAK,IAAI,CAAC,CAAC;YACnC,CAAC;YACD,IAAI,KAAK,GAAG,CAAC;gBAAE,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QAC9C,CAAC;QACD,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;QACzC,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IACnD,CAAC;IAED,8EAA8E;IAC9E,OAAO,CAAC,KAAe;QACrB,MAAM,QAAQ,GAAgB,EAAE,CAAC;QACjC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YACnC,IAAI,IAAI,EAAE,CAAC;gBACT,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;gBACzB,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACtB,CAAC;QACH,CAAC;QACD,OAAO,QAAQ,CAAC;IAClB,CAAC;CACF"}
|
|
@@ -13,15 +13,31 @@ export declare function findPackageBinScript(pkgName: string, binName: string, s
|
|
|
13
13
|
* stripped for resolution since the installed copy's version is authoritative.
|
|
14
14
|
*/
|
|
15
15
|
export declare function parseNpxPackage(command: string, args: readonly string[]): string | null;
|
|
16
|
+
/**
|
|
17
|
+
* Resolve a package's real bin script from npx's on-demand cache. This is where
|
|
18
|
+
* `npx -y <pkg>` installs a server on first run, so from the SECOND launch
|
|
19
|
+
* onward we can spawn the real bin directly with `process.execPath` and skip
|
|
20
|
+
* npx's ~90 MB `npm exec` wrapper — for ANY package, including user-added MCP
|
|
21
|
+
* servers we don't (and can't) bundle.
|
|
22
|
+
*
|
|
23
|
+
* `versionPin` (from a `<pkg>@x.y.z` spec) is honoured strictly: a cached copy
|
|
24
|
+
* is used only when its `package.json` version matches exactly, so a pin never
|
|
25
|
+
* silently resolves to the wrong cached version (it falls through to npx, which
|
|
26
|
+
* resolves the pin correctly). Unpinned specs take the highest cached version.
|
|
27
|
+
* Deterministic fs reads only — no resolver hooks.
|
|
28
|
+
*/
|
|
29
|
+
export declare function findNpxCachedBinScript(pkgName: string, binName: string, versionPin?: string): string | null;
|
|
16
30
|
export interface ResolvedStdioCommand {
|
|
17
31
|
command: string;
|
|
18
32
|
args: string[];
|
|
19
33
|
}
|
|
20
34
|
/**
|
|
21
35
|
* Rewrite a stdio `{ command, args }` to a direct `node <binScript>` invocation
|
|
22
|
-
* when it's an `npx`/`npm exec` of a package whose bin script is resolvable
|
|
23
|
-
* ezcoder's install
|
|
24
|
-
*
|
|
36
|
+
* when it's an `npx`/`npm exec` of a package whose bin script is resolvable
|
|
37
|
+
* either from ezcoder's install (bundled/dep) OR from npx's on-demand cache
|
|
38
|
+
* (`~/.npm/_npx/...`, populated on the package's first run). Returns the
|
|
39
|
+
* original `{ command, args }` unchanged otherwise (non-npx command, or the
|
|
40
|
+
* package isn't cached yet — the true first run, which npx then installs).
|
|
25
41
|
*/
|
|
26
42
|
export declare function resolveStdioCommand(command: string, args?: readonly string[]): ResolvedStdioCommand;
|
|
27
43
|
//# sourceMappingURL=resolve-stdio.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolve-stdio.d.ts","sourceRoot":"","sources":["../../../src/core/mcp/resolve-stdio.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"resolve-stdio.d.ts","sourceRoot":"","sources":["../../../src/core/mcp/resolve-stdio.ts"],"names":[],"mappings":"AA2CA;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,EACf,KAAK,GAAE,MAAmB,GACzB,MAAM,GAAG,IAAI,CAcf;AAuBD;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,GAAG,IAAI,CA0BvF;AAiED;;;;;;;;;;;;GAYG;AACH,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,EACf,UAAU,CAAC,EAAE,MAAM,GAClB,MAAM,GAAG,IAAI,CA8Bf;AAOD,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,EAAE,CAAC;CAChB;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,MAAM,EACf,IAAI,GAAE,SAAS,MAAM,EAAO,GAC3B,oBAAoB,CAoBtB"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
|
+
import os from "node:os";
|
|
2
3
|
import path from "node:path";
|
|
3
4
|
import { fileURLToPath } from "node:url";
|
|
4
5
|
/**
|
|
@@ -50,7 +51,7 @@ export function findPackageBinScript(pkgName, binName, start = MODULE_DIR) {
|
|
|
50
51
|
return null;
|
|
51
52
|
try {
|
|
52
53
|
const pkg = JSON.parse(fs.readFileSync(pkgJsonPath, "utf8"));
|
|
53
|
-
const bin =
|
|
54
|
+
const bin = selectBin(pkg.bin, binName);
|
|
54
55
|
if (!bin)
|
|
55
56
|
return null;
|
|
56
57
|
const script = path.join(path.dirname(pkgJsonPath), bin);
|
|
@@ -60,6 +61,26 @@ export function findPackageBinScript(pkgName, binName, start = MODULE_DIR) {
|
|
|
60
61
|
return null;
|
|
61
62
|
}
|
|
62
63
|
}
|
|
64
|
+
/**
|
|
65
|
+
* Pick a package's bin script path from its `bin` field.
|
|
66
|
+
* - string bin → that path.
|
|
67
|
+
* - object with exactly ONE entry → that entry, whatever its key. (The bin name
|
|
68
|
+
* very often differs from the unscoped package name — e.g. `@z_ai/mcp-server`
|
|
69
|
+
* exposes `zai-mcp-server` — so keying by package name would wrongly miss it.
|
|
70
|
+
* npx runs a sole bin regardless of its name; we mirror that.)
|
|
71
|
+
* - object with several entries → the one keyed by `binName` (needed to
|
|
72
|
+
* disambiguate), else null.
|
|
73
|
+
*/
|
|
74
|
+
function selectBin(bin, binName) {
|
|
75
|
+
if (!bin)
|
|
76
|
+
return undefined;
|
|
77
|
+
if (typeof bin === "string")
|
|
78
|
+
return bin;
|
|
79
|
+
const keys = Object.keys(bin);
|
|
80
|
+
if (keys.length === 1)
|
|
81
|
+
return bin[keys[0]];
|
|
82
|
+
return bin[binName];
|
|
83
|
+
}
|
|
63
84
|
/**
|
|
64
85
|
* Parse an `npx`/`npm exec` command + args into the target package spec, or null
|
|
65
86
|
* when the command isn't an npx/npm-exec invocation. Skips npx flags (`-y`,
|
|
@@ -110,15 +131,120 @@ function stripVersion(pkgSpec) {
|
|
|
110
131
|
const at = pkgSpec.indexOf("@");
|
|
111
132
|
return at === -1 ? pkgSpec : pkgSpec.slice(0, at);
|
|
112
133
|
}
|
|
134
|
+
/**
|
|
135
|
+
* Extract a trailing `@version` pin from a package spec, or `undefined` when
|
|
136
|
+
* unpinned. Complement of `stripVersion`: `@z_ai/mcp-server@1.2.3` → `"1.2.3"`,
|
|
137
|
+
* `@z_ai/mcp-server` → `undefined`, `foo@2.0.0` → `"2.0.0"`.
|
|
138
|
+
*/
|
|
139
|
+
function versionPinOf(pkgSpec) {
|
|
140
|
+
if (pkgSpec.startsWith("@")) {
|
|
141
|
+
const slash = pkgSpec.indexOf("/");
|
|
142
|
+
if (slash === -1)
|
|
143
|
+
return undefined;
|
|
144
|
+
const at = pkgSpec.indexOf("@", slash);
|
|
145
|
+
return at === -1 ? undefined : pkgSpec.slice(at + 1);
|
|
146
|
+
}
|
|
147
|
+
const at = pkgSpec.indexOf("@");
|
|
148
|
+
return at === -1 ? undefined : pkgSpec.slice(at + 1);
|
|
149
|
+
}
|
|
150
|
+
/** Compare two dotted numeric version strings (highest first via sort). Numeric
|
|
151
|
+
* segments compare numerically; non-numeric (pre-release) tiebreak lexically.
|
|
152
|
+
* Returns >0 when `a` > `b`, <0 when `a` < `b`, 0 when equal. */
|
|
153
|
+
function compareVersions(a, b) {
|
|
154
|
+
const pa = a.split(".");
|
|
155
|
+
const pb = b.split(".");
|
|
156
|
+
for (let i = 0; i < Math.max(pa.length, pb.length); i++) {
|
|
157
|
+
const na = Number.parseInt(pa[i] ?? "0", 10);
|
|
158
|
+
const nb = Number.parseInt(pb[i] ?? "0", 10);
|
|
159
|
+
if (Number.isNaN(na) || Number.isNaN(nb)) {
|
|
160
|
+
const c = (pa[i] ?? "").localeCompare(pb[i] ?? "");
|
|
161
|
+
if (c !== 0)
|
|
162
|
+
return c;
|
|
163
|
+
}
|
|
164
|
+
else if (na !== nb) {
|
|
165
|
+
return na - nb;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
return 0;
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Candidate `_npx` cache roots where `npx -y <pkg>` installs on-demand packages
|
|
172
|
+
* (`<cache>/_npx/<hash>/node_modules/<pkg>`). Ordered by trust: an explicit
|
|
173
|
+
* `npm_config_cache` first, then the POSIX/npm default (`~/.npm`), then the
|
|
174
|
+
* Windows default (`%LOCALAPPDATA%\npm-cache`). De-duplicated.
|
|
175
|
+
*/
|
|
176
|
+
function npxCacheRoots() {
|
|
177
|
+
const roots = [];
|
|
178
|
+
const envCache = process.env.npm_config_cache ?? process.env.NPM_CONFIG_CACHE;
|
|
179
|
+
if (envCache)
|
|
180
|
+
roots.push(path.join(envCache, "_npx"));
|
|
181
|
+
roots.push(path.join(os.homedir(), ".npm", "_npx"));
|
|
182
|
+
const localAppData = process.env.LOCALAPPDATA;
|
|
183
|
+
if (localAppData)
|
|
184
|
+
roots.push(path.join(localAppData, "npm-cache", "_npx"));
|
|
185
|
+
return roots.filter((r, i) => roots.indexOf(r) === i);
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Resolve a package's real bin script from npx's on-demand cache. This is where
|
|
189
|
+
* `npx -y <pkg>` installs a server on first run, so from the SECOND launch
|
|
190
|
+
* onward we can spawn the real bin directly with `process.execPath` and skip
|
|
191
|
+
* npx's ~90 MB `npm exec` wrapper — for ANY package, including user-added MCP
|
|
192
|
+
* servers we don't (and can't) bundle.
|
|
193
|
+
*
|
|
194
|
+
* `versionPin` (from a `<pkg>@x.y.z` spec) is honoured strictly: a cached copy
|
|
195
|
+
* is used only when its `package.json` version matches exactly, so a pin never
|
|
196
|
+
* silently resolves to the wrong cached version (it falls through to npx, which
|
|
197
|
+
* resolves the pin correctly). Unpinned specs take the highest cached version.
|
|
198
|
+
* Deterministic fs reads only — no resolver hooks.
|
|
199
|
+
*/
|
|
200
|
+
export function findNpxCachedBinScript(pkgName, binName, versionPin) {
|
|
201
|
+
const segs = pkgName.split("/");
|
|
202
|
+
const candidates = [];
|
|
203
|
+
for (const root of npxCacheRoots()) {
|
|
204
|
+
let hashes;
|
|
205
|
+
try {
|
|
206
|
+
hashes = fs.readdirSync(root);
|
|
207
|
+
}
|
|
208
|
+
catch {
|
|
209
|
+
continue; // this cache root doesn't exist
|
|
210
|
+
}
|
|
211
|
+
for (const hash of hashes) {
|
|
212
|
+
const pkgJsonPath = path.join(root, hash, "node_modules", ...segs, "package.json");
|
|
213
|
+
let pkg;
|
|
214
|
+
try {
|
|
215
|
+
pkg = JSON.parse(fs.readFileSync(pkgJsonPath, "utf8"));
|
|
216
|
+
}
|
|
217
|
+
catch {
|
|
218
|
+
continue; // no such cached package here
|
|
219
|
+
}
|
|
220
|
+
const version = typeof pkg.version === "string" ? pkg.version : "";
|
|
221
|
+
if (versionPin && version !== versionPin)
|
|
222
|
+
continue; // honour the pin
|
|
223
|
+
const bin = selectBin(pkg.bin, binName);
|
|
224
|
+
if (!bin)
|
|
225
|
+
continue;
|
|
226
|
+
const script = path.join(path.dirname(pkgJsonPath), bin);
|
|
227
|
+
if (fs.existsSync(script))
|
|
228
|
+
candidates.push({ version, script });
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
if (candidates.length === 0)
|
|
232
|
+
return null;
|
|
233
|
+
// Highest cached version wins — deterministic when several are cached.
|
|
234
|
+
candidates.sort((a, b) => compareVersions(b.version, a.version));
|
|
235
|
+
return candidates[0].script;
|
|
236
|
+
}
|
|
113
237
|
/** Derive the conventional bin name from a package name (drop the scope). */
|
|
114
238
|
function binNameFor(pkgName) {
|
|
115
239
|
return pkgName.startsWith("@") ? (pkgName.split("/")[1] ?? pkgName) : pkgName;
|
|
116
240
|
}
|
|
117
241
|
/**
|
|
118
242
|
* Rewrite a stdio `{ command, args }` to a direct `node <binScript>` invocation
|
|
119
|
-
* when it's an `npx`/`npm exec` of a package whose bin script is resolvable
|
|
120
|
-
* ezcoder's install
|
|
121
|
-
*
|
|
243
|
+
* when it's an `npx`/`npm exec` of a package whose bin script is resolvable
|
|
244
|
+
* either from ezcoder's install (bundled/dep) OR from npx's on-demand cache
|
|
245
|
+
* (`~/.npm/_npx/...`, populated on the package's first run). Returns the
|
|
246
|
+
* original `{ command, args }` unchanged otherwise (non-npx command, or the
|
|
247
|
+
* package isn't cached yet — the true first run, which npx then installs).
|
|
122
248
|
*/
|
|
123
249
|
export function resolveStdioCommand(command, args = []) {
|
|
124
250
|
const passthrough = { command, args: [...args] };
|
|
@@ -126,7 +252,12 @@ export function resolveStdioCommand(command, args = []) {
|
|
|
126
252
|
if (!pkgSpec)
|
|
127
253
|
return passthrough;
|
|
128
254
|
const pkgName = stripVersion(pkgSpec);
|
|
129
|
-
const
|
|
255
|
+
const binName = binNameFor(pkgName);
|
|
256
|
+
// 1) Local resolution (bundled next to the sidecar / ezcoder deps) — fastest,
|
|
257
|
+
// version-authoritative. 2) npx on-demand cache — covers non-bundled
|
|
258
|
+
// defaults (e.g. zai) and any user-added MCP once npx has cached it.
|
|
259
|
+
const binScript = findPackageBinScript(pkgName, binName) ??
|
|
260
|
+
findNpxCachedBinScript(pkgName, binName, versionPinOf(pkgSpec));
|
|
130
261
|
if (!binScript)
|
|
131
262
|
return passthrough;
|
|
132
263
|
// Drop the npx package positional + its flags; forward only the args that
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolve-stdio.js","sourceRoot":"","sources":["../../../src/core/mcp/resolve-stdio.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC;;;;;;;;;;;;;;;;GAgBG;AAEH,kFAAkF;AAClF,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAEhE;;;;;GAKG;AACH,SAAS,mBAAmB,CAAC,OAAe,EAAE,KAAa;IACzD,IAAI,GAAG,GAAG,KAAK,CAAC;IAChB,SAAS,CAAC;QACR,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,cAAc,EAAE,OAAO,CAAC,CAAC;QAC1D,IAAI,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC;YAAE,OAAO,SAAS,CAAC;QAC/C,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACjC,IAAI,MAAM,KAAK,GAAG;YAAE,OAAO,IAAI,CAAC;QAChC,GAAG,GAAG,MAAM,CAAC;IACf,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,oBAAoB,CAClC,OAAe,EACf,OAAe,EACf,QAAgB,UAAU;IAE1B,MAAM,WAAW,GAAG,mBAAmB,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,cAAc,CAAC,EAAE,KAAK,CAAC,CAAC;IACnF,IAAI,CAAC,WAAW;QAAE,OAAO,IAAI,CAAC;IAC9B,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,WAAW,EAAE,MAAM,CAAC,CAE1D,CAAC;QACF,MAAM,GAAG,GAAG,
|
|
1
|
+
{"version":3,"file":"resolve-stdio.js","sourceRoot":"","sources":["../../../src/core/mcp/resolve-stdio.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,21 @@
|
|
|
1
|
-
import { describe, it, expect } from "vitest";
|
|
1
|
+
import { afterEach, describe, it, expect } from "vitest";
|
|
2
|
+
import fs from "node:fs";
|
|
3
|
+
import os from "node:os";
|
|
4
|
+
import path from "node:path";
|
|
2
5
|
import { parseNpxPackage, findPackageBinScript, resolveStdioCommand } from "./resolve-stdio.js";
|
|
6
|
+
/** Lay out a fake npx cache entry: `<cache>/_npx/<hash>/node_modules/<pkg>`
|
|
7
|
+
* with a package.json + real bin file. Returns the cache root to point
|
|
8
|
+
* `npm_config_cache` at. */
|
|
9
|
+
function seedNpxCache(cacheRoot, hash, pkgName, version, binRel = "build/index.js") {
|
|
10
|
+
const pkgDir = path.join(cacheRoot, "_npx", hash, "node_modules", ...pkgName.split("/"));
|
|
11
|
+
fs.mkdirSync(path.join(pkgDir, path.dirname(binRel)), { recursive: true });
|
|
12
|
+
fs.writeFileSync(path.join(pkgDir, binRel), "#!/usr/bin/env node\n");
|
|
13
|
+
fs.writeFileSync(path.join(pkgDir, "package.json"), JSON.stringify({
|
|
14
|
+
name: pkgName,
|
|
15
|
+
version,
|
|
16
|
+
bin: { [pkgName.split("/").pop()]: binRel },
|
|
17
|
+
}));
|
|
18
|
+
}
|
|
3
19
|
describe("parseNpxPackage", () => {
|
|
4
20
|
it("extracts the package from `npx -y <pkg>`", () => {
|
|
5
21
|
expect(parseNpxPackage("npx", ["-y", "@kenkaiiii/kencode-search"])).toBe("@kenkaiiii/kencode-search");
|
|
@@ -60,4 +76,69 @@ describe("resolveStdioCommand", () => {
|
|
|
60
76
|
expect(out.args).toEqual(["some-mcp-server", "--port", "0"]);
|
|
61
77
|
});
|
|
62
78
|
});
|
|
79
|
+
describe("resolveStdioCommand npx-cache fallback (covers user-added MCPs)", () => {
|
|
80
|
+
let tmp;
|
|
81
|
+
const prevCache = process.env.npm_config_cache;
|
|
82
|
+
afterEach(() => {
|
|
83
|
+
if (prevCache === undefined)
|
|
84
|
+
delete process.env.npm_config_cache;
|
|
85
|
+
else
|
|
86
|
+
process.env.npm_config_cache = prevCache;
|
|
87
|
+
if (tmp)
|
|
88
|
+
fs.rmSync(tmp, { recursive: true, force: true });
|
|
89
|
+
tmp = undefined;
|
|
90
|
+
});
|
|
91
|
+
it("rewrites a non-bundled but npx-cached server to `node <binScript>`", () => {
|
|
92
|
+
tmp = fs.mkdtempSync(path.join(os.tmpdir(), "gg-npx-cache-"));
|
|
93
|
+
seedNpxCache(tmp, "hash1", "@vendor/cool-mcp", "1.0.0");
|
|
94
|
+
process.env.npm_config_cache = tmp;
|
|
95
|
+
const out = resolveStdioCommand("npx", ["-y", "@vendor/cool-mcp"]);
|
|
96
|
+
expect(out.command).toBe(process.execPath);
|
|
97
|
+
expect(out.args[0]).toMatch(/cool-mcp[/\\]build[/\\]index\.js$/);
|
|
98
|
+
});
|
|
99
|
+
it("honours a version pin: a mismatched cached version falls through to npx", () => {
|
|
100
|
+
tmp = fs.mkdtempSync(path.join(os.tmpdir(), "gg-npx-cache-"));
|
|
101
|
+
seedNpxCache(tmp, "hash1", "@vendor/cool-mcp", "1.0.0");
|
|
102
|
+
process.env.npm_config_cache = tmp;
|
|
103
|
+
// Requested @2.0.0, only 1.0.0 cached → do NOT rewrite to the wrong version.
|
|
104
|
+
const out = resolveStdioCommand("npx", ["-y", "@vendor/cool-mcp@2.0.0"]);
|
|
105
|
+
expect(out.command).toBe("npx");
|
|
106
|
+
expect(out.args).toEqual(["-y", "@vendor/cool-mcp@2.0.0"]);
|
|
107
|
+
});
|
|
108
|
+
it("uses a cached copy whose version matches the pin exactly", () => {
|
|
109
|
+
tmp = fs.mkdtempSync(path.join(os.tmpdir(), "gg-npx-cache-"));
|
|
110
|
+
seedNpxCache(tmp, "hash1", "@vendor/cool-mcp", "2.0.0");
|
|
111
|
+
process.env.npm_config_cache = tmp;
|
|
112
|
+
const out = resolveStdioCommand("npx", ["-y", "@vendor/cool-mcp@2.0.0"]);
|
|
113
|
+
expect(out.command).toBe(process.execPath);
|
|
114
|
+
expect(out.args[0]).toMatch(/cool-mcp[/\\]build[/\\]index\.js$/);
|
|
115
|
+
});
|
|
116
|
+
it("picks the highest cached version when the spec is unpinned", () => {
|
|
117
|
+
tmp = fs.mkdtempSync(path.join(os.tmpdir(), "gg-npx-cache-"));
|
|
118
|
+
seedNpxCache(tmp, "old", "@vendor/cool-mcp", "1.2.0", "build/old.js");
|
|
119
|
+
seedNpxCache(tmp, "new", "@vendor/cool-mcp", "1.10.0", "build/new.js");
|
|
120
|
+
process.env.npm_config_cache = tmp;
|
|
121
|
+
// 1.10.0 > 1.2.0 numerically (not lexically) → the newer bin wins.
|
|
122
|
+
const out = resolveStdioCommand("npx", ["-y", "@vendor/cool-mcp"]);
|
|
123
|
+
expect(out.command).toBe(process.execPath);
|
|
124
|
+
expect(out.args[0]).toMatch(/new\.js$/);
|
|
125
|
+
});
|
|
126
|
+
it("resolves a sole bin whose key differs from the package name (e.g. zai)", () => {
|
|
127
|
+
// @z_ai/mcp-server exposes bin `zai-mcp-server`, NOT `mcp-server`. A sole
|
|
128
|
+
// bin must be used regardless of its key, or the rewrite silently misses.
|
|
129
|
+
tmp = fs.mkdtempSync(path.join(os.tmpdir(), "gg-npx-cache-"));
|
|
130
|
+
const pkgDir = path.join(tmp, "_npx", "h", "node_modules", "@z_ai", "mcp-server");
|
|
131
|
+
fs.mkdirSync(path.join(pkgDir, "build"), { recursive: true });
|
|
132
|
+
fs.writeFileSync(path.join(pkgDir, "build", "index.js"), "#!/usr/bin/env node\n");
|
|
133
|
+
fs.writeFileSync(path.join(pkgDir, "package.json"), JSON.stringify({
|
|
134
|
+
name: "@z_ai/mcp-server",
|
|
135
|
+
version: "0.1.4",
|
|
136
|
+
bin: { "zai-mcp-server": "./build/index.js" },
|
|
137
|
+
}));
|
|
138
|
+
process.env.npm_config_cache = tmp;
|
|
139
|
+
const out = resolveStdioCommand("npx", ["-y", "@z_ai/mcp-server"]);
|
|
140
|
+
expect(out.command).toBe(process.execPath);
|
|
141
|
+
expect(out.args[0]).toMatch(/mcp-server[/\\]build[/\\]index\.js$/);
|
|
142
|
+
});
|
|
143
|
+
});
|
|
63
144
|
//# sourceMappingURL=resolve-stdio.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolve-stdio.test.js","sourceRoot":"","sources":["../../../src/core/mcp/resolve-stdio.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"resolve-stdio.test.js","sourceRoot":"","sources":["../../../src/core/mcp/resolve-stdio.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -9,6 +9,12 @@
|
|
|
9
9
|
*
|
|
10
10
|
* Kept pure + dependency-light so it's unit-testable without booting the sidecar
|
|
11
11
|
* (which runs `main()` at import time).
|
|
12
|
+
*
|
|
13
|
+
* NOTE: static project docs (CLAUDE.md/AGENTS.md) are NOT part of this digest
|
|
14
|
+
* — they're folded into Nolan's cached system prompt once per session
|
|
15
|
+
* (`buildNolanSystemPrompt`/`buildNolanAutopilotSystemPrompt` in nolan-prompt.ts) so
|
|
16
|
+
* they hit the provider prompt cache instead of being re-sent uncached on
|
|
17
|
+
* every `@Nolan` question and every autopilot review round.
|
|
12
18
|
*/
|
|
13
19
|
import type { Message } from "@prestyj/ai";
|
|
14
20
|
import { type WorkflowCommandSpec } from "./autopilot-gate.js";
|
|
@@ -22,8 +28,6 @@ export declare const INJECTED_PROMPT_LABEL = "**Nolan autopilot (injected):**";
|
|
|
22
28
|
export interface NolanDigestInput {
|
|
23
29
|
/** The user's `@Nolan …` text (already stripped of the mention). */
|
|
24
30
|
question: string;
|
|
25
|
-
/** `collectProjectContext(cwd)` output — CLAUDE.md/AGENTS.md up the tree. */
|
|
26
|
-
projectContext: string[];
|
|
27
31
|
cwd: string;
|
|
28
32
|
gitBranch: string | null;
|
|
29
33
|
/** Build session messages (`buildSession.getMessages()`). */
|
|
@@ -62,6 +66,26 @@ export type NolanAutopilotContextInput = Omit<NolanDigestInput, "question">;
|
|
|
62
66
|
* Nolan reviews the transcript instead of answering a user. Pure — no I/O.
|
|
63
67
|
*/
|
|
64
68
|
export declare function buildNolanAutopilotContext(input: NolanAutopilotContextInput): string;
|
|
69
|
+
/**
|
|
70
|
+
* Fixed instruction fed into the digest's `question` slot for an autopilot
|
|
71
|
+
* PLAN review. In autopilot there is no user in the loop: Nolan himself is the
|
|
72
|
+
* plan reviewer — ALL_CLEAR approves (auto-accept + implementation starts),
|
|
73
|
+
* PROMPT sends revision feedback, HUMAN is reserved for genuine user-level
|
|
74
|
+
* decisions. IGNORE is meaningless for a plan (the sidecar maps it to approve
|
|
75
|
+
* defensively), so the instruction forbids it outright.
|
|
76
|
+
*/
|
|
77
|
+
export declare const AUTOPILOT_PLAN_REVIEW_INSTRUCTION: string;
|
|
78
|
+
/**
|
|
79
|
+
* Build the autopilot PLAN-review digest: the normal autopilot digest plus a
|
|
80
|
+
* `## Plan under review` section carrying the submitted plan's markdown, with
|
|
81
|
+
* {@link AUTOPILOT_PLAN_REVIEW_INSTRUCTION} as the trailing question. Pure —
|
|
82
|
+
* the sidecar reads the plan file and passes its content. The plan section is
|
|
83
|
+
* spliced in before the trailing question so it sits closest to the
|
|
84
|
+
* instruction that references it.
|
|
85
|
+
*/
|
|
86
|
+
export declare function buildNolanAutopilotPlanContext(input: NolanAutopilotContextInput & {
|
|
87
|
+
planContent: string;
|
|
88
|
+
}): string;
|
|
65
89
|
/**
|
|
66
90
|
* Build Nolan's full context digest string. Pure — no I/O. The sidecar gathers the
|
|
67
91
|
* inputs (project context, git, messages) and calls this.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nolan-context.d.ts","sourceRoot":"","sources":["../../src/core/nolan-context.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"nolan-context.d.ts","sourceRoot":"","sources":["../../src/core/nolan-context.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,KAAK,EAAE,OAAO,EAA2B,MAAM,aAAa,CAAC;AACpE,OAAO,EAAwB,KAAK,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAErF,6EAA6E;AAC7E,eAAO,MAAM,0BAA0B,KAAK,CAAC;AAa7C;;;8EAG8E;AAC9E,eAAO,MAAM,qBAAqB,oCAAoC,CAAC;AAEvE,MAAM,WAAW,gBAAgB;IAC/B,oEAAoE;IACpE,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,6DAA6D;IAC7D,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,sDAAsD;IACtD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,+CAA+C;IAC/C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;4CAEwC;IACxC,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;qFACiF;IACjF,eAAe,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC;;4EAEwE;IACxE,gBAAgB,CAAC,EAAE,SAAS,mBAAmB,EAAE,CAAC;CACnD;AAiGD;;;;;;GAMG;AACH,eAAO,MAAM,4BAA4B,QAYyB,CAAC;AAEnE;;mCAEmC;AACnC,MAAM,MAAM,0BAA0B,GAAG,IAAI,CAAC,gBAAgB,EAAE,UAAU,CAAC,CAAC;AAE5E;;;;GAIG;AACH,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,0BAA0B,GAAG,MAAM,CAEpF;AAOD;;;;;;;GAOG;AACH,eAAO,MAAM,iCAAiC,QAOzB,CAAC;AAEtB;;;;;;;GAOG;AACH,wBAAgB,8BAA8B,CAC5C,KAAK,EAAE,0BAA0B,GAAG;IAAE,WAAW,EAAE,MAAM,CAAA;CAAE,GAC1D,MAAM,CAUR;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,gBAAgB,GAAG,MAAM,CAwEhE"}
|
|
@@ -116,8 +116,13 @@ export const AUTOPILOT_REVIEW_INSTRUCTION = "EZ Coder just finished a turn. Revi
|
|
|
116
116
|
"autopilot (injected)' are your own earlier fix prompts, NOT user asks). " +
|
|
117
117
|
"Reply with your verdict ONLY — the first line must be exactly PROMPT, " +
|
|
118
118
|
"ALL_CLEAR, IGNORE, or HUMAN, with the payload after. If EZ Coder ended by " +
|
|
119
|
-
"asking the user a question or presenting options,
|
|
120
|
-
"
|
|
119
|
+
"asking the user a question or presenting options, use HUMAN only when the " +
|
|
120
|
+
"answer requires an actual user-level decision: intent, preference, missing " +
|
|
121
|
+
"product requirement, credential/secret, external access, budget/cost, or " +
|
|
122
|
+
"destructive/irreversible approval. If the question is only permission to " +
|
|
123
|
+
"continue work that is mechanically implied by the user's original ask and " +
|
|
124
|
+
"safe for EZ Coder to do without new information, use PROMPT with the next " +
|
|
125
|
+
"concrete follow-up instead. No greetings, no mentorship prose.";
|
|
121
126
|
/**
|
|
122
127
|
* Build the autopilot-review digest: identical to a normal Nolan digest but with
|
|
123
128
|
* the fixed {@link AUTOPILOT_REVIEW_INSTRUCTION} as the trailing question, so
|
|
@@ -126,6 +131,45 @@ export const AUTOPILOT_REVIEW_INSTRUCTION = "EZ Coder just finished a turn. Revi
|
|
|
126
131
|
export function buildNolanAutopilotContext(input) {
|
|
127
132
|
return buildNolanDigest({ ...input, question: AUTOPILOT_REVIEW_INSTRUCTION });
|
|
128
133
|
}
|
|
134
|
+
/** Max chars of the inlined plan markdown in a plan-review digest. Plans are
|
|
135
|
+
* hand-written markdown, rarely near this; the cap only guards against a
|
|
136
|
+
* pathological plan blowing the reviewer's context. */
|
|
137
|
+
const PLAN_CONTENT_CAP = 8000;
|
|
138
|
+
/**
|
|
139
|
+
* Fixed instruction fed into the digest's `question` slot for an autopilot
|
|
140
|
+
* PLAN review. In autopilot there is no user in the loop: Nolan himself is the
|
|
141
|
+
* plan reviewer — ALL_CLEAR approves (auto-accept + implementation starts),
|
|
142
|
+
* PROMPT sends revision feedback, HUMAN is reserved for genuine user-level
|
|
143
|
+
* decisions. IGNORE is meaningless for a plan (the sidecar maps it to approve
|
|
144
|
+
* defensively), so the instruction forbids it outright.
|
|
145
|
+
*/
|
|
146
|
+
export const AUTOPILOT_PLAN_REVIEW_INSTRUCTION = "EZ Coder submitted an implementation plan (the 'Plan under review' section " +
|
|
147
|
+
"above). You are the reviewer — there is no user in the loop. Reply with " +
|
|
148
|
+
"your verdict ONLY — the first line must be exactly ALL_CLEAR (approve — the " +
|
|
149
|
+
"plan is sound and implementation starts immediately), PROMPT + feedback " +
|
|
150
|
+
"(send it back for revision), or HUMAN + reason (a real product/destructive " +
|
|
151
|
+
"decision only the user can make). Never IGNORE a plan. No greetings, no " +
|
|
152
|
+
"mentorship prose.";
|
|
153
|
+
/**
|
|
154
|
+
* Build the autopilot PLAN-review digest: the normal autopilot digest plus a
|
|
155
|
+
* `## Plan under review` section carrying the submitted plan's markdown, with
|
|
156
|
+
* {@link AUTOPILOT_PLAN_REVIEW_INSTRUCTION} as the trailing question. Pure —
|
|
157
|
+
* the sidecar reads the plan file and passes its content. The plan section is
|
|
158
|
+
* spliced in before the trailing question so it sits closest to the
|
|
159
|
+
* instruction that references it.
|
|
160
|
+
*/
|
|
161
|
+
export function buildNolanAutopilotPlanContext(input) {
|
|
162
|
+
const { planContent, ...rest } = input;
|
|
163
|
+
const digest = buildNolanDigest({ ...rest, question: AUTOPILOT_PLAN_REVIEW_INSTRUCTION });
|
|
164
|
+
const planSection = `## Plan under review\n${cap(planContent.trim(), PLAN_CONTENT_CAP)}`;
|
|
165
|
+
// Insert the plan section right before the final "They just asked you"
|
|
166
|
+
// section (always the last one buildNolanDigest appends).
|
|
167
|
+
const marker = "\n\n## They just asked you\n";
|
|
168
|
+
const idx = digest.lastIndexOf(marker);
|
|
169
|
+
if (idx === -1)
|
|
170
|
+
return `${digest}\n\n${planSection}`;
|
|
171
|
+
return `${digest.slice(0, idx)}\n\n${planSection}${digest.slice(idx)}`;
|
|
172
|
+
}
|
|
129
173
|
/**
|
|
130
174
|
* Build Nolan's full context digest string. Pure — no I/O. The sidecar gathers the
|
|
131
175
|
* inputs (project context, git, messages) and calls this.
|
|
@@ -161,8 +205,6 @@ export function buildNolanDigest(input) {
|
|
|
161
205
|
const sections = [];
|
|
162
206
|
sections.push(`## Who you are\nYou are Nolan Grout, mentoring the user inside EZ Coder. Your persona is in your system prompt. Below is what EZ Coder and the user are working on.`);
|
|
163
207
|
const building = [];
|
|
164
|
-
if (input.projectContext.length > 0)
|
|
165
|
-
building.push(input.projectContext.join("\n\n"));
|
|
166
208
|
building.push(`- Working directory: ${input.cwd}`, `- Platform: ${platform}`, `- Git branch: ${input.gitBranch ?? "(not a git repo / unknown)"}`);
|
|
167
209
|
sections.push(`## What they're building\n${building.join("\n")}`);
|
|
168
210
|
if (summaryText) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nolan-context.js","sourceRoot":"","sources":["../../src/core/nolan-context.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"nolan-context.js","sourceRoot":"","sources":["../../src/core/nolan-context.ts"],"names":[],"mappings":"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"}
|