@junghanacs/entwurf 0.31.0 → 0.33.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/AGENTS.md +3 -2
- package/CHANGELOG.md +128 -0
- package/README.md +62 -117
- package/VERIFY.md +40 -21
- package/demo/README.md +1 -1
- package/docs/acp-backend-rail.md +1 -1
- package/docs/setup-clean-host.md +112 -95
- package/mcp/entwurf-bridge/dist/mcp/entwurf-bridge/src/index.js +1 -1
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/fresh-call-composition.js +1 -1
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/mux-fresh-call.js +8 -10
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/pi-durable-fresh-preflight.js +3 -3
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/pi-durable-runtime.js +153 -205
- package/mcp/entwurf-bridge/dist/pi-extensions/meta-bridge-pi-durable.js +6 -4
- package/mcp/entwurf-bridge/src/index.ts +1 -1
- package/package.json +14 -17
- package/pi/pi-durable/bootstrap.mjs +142 -19
- package/pi/pi-durable/carrier/LICENSE +21 -0
- package/pi/pi-durable/carrier/harness-setup.js +123 -0
- package/pi/pi-durable/carrier/prompt.js +74 -0
- package/pi/pi-durable/carrier/runtime.js +402 -0
- package/pi/pi-durable/carrier/sessions.js +56 -0
- package/pi/pi-durable/carrier/subagent.js +55 -0
- package/pi/pi-durable/carrier/tui.js +655 -0
- package/pi/pi-durable/carrier-relocation.mjs +160 -0
- package/pi/pi-durable/carrier-resolver.mjs +38 -0
- package/pi/pi-durable/overlay/upstream-pin.json +103 -11
- package/pi-extensions/lib/fresh-call-composition.ts +1 -1
- package/pi-extensions/lib/mux-fresh-call.ts +8 -10
- package/pi-extensions/lib/pi-durable-fresh-preflight.ts +3 -3
- package/pi-extensions/lib/pi-durable-runtime.ts +197 -263
- package/pi-extensions/meta-bridge-pi-durable.ts +13 -7
- package/run.sh +519 -248
- package/scripts/check-entwurf-bridge-pi-free.ts +7 -5
- package/scripts/check-fresh-call-dispatch.ts +1 -1
- package/scripts/check-gate-qualification.ts +86 -34
- package/scripts/check-herdr-activation.ts +5 -4
- package/scripts/check-pi-durable-contact.ts +26 -93
- package/scripts/check-pi-durable-receive.ts +22 -59
- package/scripts/check-pi-durable-send.ts +235 -75
- package/scripts/check-release-gate-outcomes.ts +21 -17
- package/scripts/emit-pi-durable-carrier.ts +355 -0
- package/scripts/lib/mutation-qualify.ts +21 -45
- package/scripts/lib/pi-durable-operator-guard.ts +89 -0
- package/scripts/lib/qualification-receipt.ts +7 -11
- package/scripts/mutants/control-send-receipt.json +1 -1
- package/scripts/mutants/gate-qualification.json +13 -0
- package/scripts/mutants/mux-fresh-call.json +13 -13
- package/scripts/mutants/pack-install.json +3 -3
- package/scripts/mutants/pi-durable.json +442 -109
- package/scripts/mutants/pi-floor.json +24 -2
- package/scripts/mutants/release-gate.json +5 -3
- package/scripts/pi-durable-contact-host.mjs +3 -3
- package/scripts/pi-durable-receive-host.mjs +3 -3
- package/scripts/pi-durable-send-host.mjs +76 -5
- package/scripts/smoke-herdr-raw-install-live.sh +1 -1
- package/scripts/smoke-pi-durable-fresh-live.ts +3 -3
- package/scripts/smoke-setup-verdict.sh +15 -15
- package/scripts/smoke-user-scope-citizen.sh +1 -1
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
// The pi-durable carrier's ONE relocation grammar (#130), shared by the maintainer emitter
|
|
2
|
+
// (scripts/emit-pi-durable-carrier.ts) and the runtime resolver (./carrier-resolver.mjs), so the
|
|
3
|
+
// rewrite the emitter performs and the resolution the runtime accepts cannot drift apart.
|
|
4
|
+
//
|
|
5
|
+
// The durable app is source-only upstream: published `@earendil-works/pi-coding-agent` ships no
|
|
6
|
+
// `dist/experimental`, and its exports map exposes no deep `dist/` path. The carrier is the pinned
|
|
7
|
+
// upstream app files, type-stripped, with exactly two rewrites:
|
|
8
|
+
//
|
|
9
|
+
// "./<sibling>.ts" → "./<sibling>.js" a carrier file importing another carrier file
|
|
10
|
+
// "../../<path>.ts" → entwurf-pi-dist:<path>.js the app importing a pi-coding-agent internal
|
|
11
|
+
//
|
|
12
|
+
// Every other specifier — `@earendil-works/*`, `proper-lockfile`, `node:*` — is left untouched and
|
|
13
|
+
// resolves by Node's own rules from where the carrier is installed. The reserved scheme is chosen so
|
|
14
|
+
// that a carrier loaded WITHOUT the resolver fails by name (Node refuses an unknown URL scheme) rather
|
|
15
|
+
// than quietly resolving `../../` inside this package. The resolver accepts the scheme only from a
|
|
16
|
+
// declared carrier file and only for a declared target, and maps it to that file under the PHYSICAL
|
|
17
|
+
// root of the pi-coding-agent the carrier itself resolves — never through the exports map.
|
|
18
|
+
//
|
|
19
|
+
// Plain JS on purpose: the resolver is preloaded with `node --import` from an installed package,
|
|
20
|
+
// where Node does not strip types, and it must not depend on the compiled bridge closure.
|
|
21
|
+
|
|
22
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
23
|
+
import path from "node:path";
|
|
24
|
+
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
25
|
+
|
|
26
|
+
export const CARRIER_SCHEME = "entwurf-pi-dist:";
|
|
27
|
+
export const CODING_AGENT = "@earendil-works/pi-coding-agent";
|
|
28
|
+
|
|
29
|
+
/** A refusal with a stable name first, as the bootstrap's. */
|
|
30
|
+
function refuse(reason, detail) {
|
|
31
|
+
return Object.assign(new Error(`${reason}: ${detail}`), { reason });
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/** A static import, export-from or side-effect import statement as upstream writes them: double quotes,
|
|
35
|
+
* the statement ending its line. A multi-line `import {` … `} from "x";` matches from its `import`. */
|
|
36
|
+
const STATEMENT = /^(\s*(?:import|export|\})[^;]*?\bfrom\s*")([^"]+)(";[ \t]*)$|^(\s*import\s*")([^"]+)(";[ \t]*)$/gm;
|
|
37
|
+
/** Every place a module specifier can begin — the statements above, and anything they would miss. */
|
|
38
|
+
const ANY_SPECIFIER = /\b(?:from|import)\s*["'(]/g;
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Rewrite one type-stripped carrier source. `siblings` are the carrier file names (`runtime.js` …),
|
|
42
|
+
* `targets` the declared pi-coding-agent dist paths (`core/model-runtime.js` …). Throws by name on a
|
|
43
|
+
* relative specifier outside those two rules, a dynamic import, or a specifier the statement grammar
|
|
44
|
+
* did not recognize. Returns the rewritten code and the targets it used.
|
|
45
|
+
*
|
|
46
|
+
* @param {string} file
|
|
47
|
+
* @param {string} code
|
|
48
|
+
* @param {{ siblings: readonly string[], targets: readonly string[] }} declared
|
|
49
|
+
* @returns {{ code: string, used: string[] }}
|
|
50
|
+
*/
|
|
51
|
+
export function relocateCarrierSource(file, code, { siblings, targets }) {
|
|
52
|
+
const used = new Set();
|
|
53
|
+
let statements = 0;
|
|
54
|
+
const rewrite = (spec) => {
|
|
55
|
+
if (spec.startsWith("./")) {
|
|
56
|
+
const name = `${spec.slice(2, -3)}.js`;
|
|
57
|
+
if (!spec.endsWith(".ts") || !siblings.includes(name)) {
|
|
58
|
+
throw refuse("carrier-relocation-unknown-sibling", `${file} imports ${spec}`);
|
|
59
|
+
}
|
|
60
|
+
return `./${name}`;
|
|
61
|
+
}
|
|
62
|
+
if (spec.startsWith("../../")) {
|
|
63
|
+
const target = `${spec.slice(6, -3)}.js`;
|
|
64
|
+
if (!spec.endsWith(".ts") || !targets.includes(target)) {
|
|
65
|
+
throw refuse("carrier-relocation-unknown-target", `${file} imports ${spec}`);
|
|
66
|
+
}
|
|
67
|
+
used.add(target);
|
|
68
|
+
return `${CARRIER_SCHEME}${target}`;
|
|
69
|
+
}
|
|
70
|
+
if (spec.startsWith(".") || spec.startsWith("/") || spec.startsWith(CARRIER_SCHEME)) {
|
|
71
|
+
throw refuse("carrier-relocation-unknown-relative", `${file} imports ${spec}`);
|
|
72
|
+
}
|
|
73
|
+
return spec;
|
|
74
|
+
};
|
|
75
|
+
const out = code.replace(STATEMENT, (_all, headA, specA, tailA, headB, specB, tailB) => {
|
|
76
|
+
statements++;
|
|
77
|
+
return headA !== undefined ? `${headA}${rewrite(specA)}${tailA}` : `${headB}${rewrite(specB)}${tailB}`;
|
|
78
|
+
});
|
|
79
|
+
const begun = (code.match(ANY_SPECIFIER) ?? []).length;
|
|
80
|
+
if (begun !== statements) {
|
|
81
|
+
throw refuse(
|
|
82
|
+
"carrier-relocation-unrecognized-import",
|
|
83
|
+
`${file}: ${begun} specifier openings, ${statements} recognized statements (a dynamic import, a single-quoted or mid-line import)`,
|
|
84
|
+
);
|
|
85
|
+
}
|
|
86
|
+
return { code: out, used: [...used].sort() };
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* The carrier section of the packaged pin, validated. A malformed pin throws (crash, don't warn).
|
|
91
|
+
*
|
|
92
|
+
* @param {URL | string} pinPath
|
|
93
|
+
* @returns {{ files: string[], targets: string[] }}
|
|
94
|
+
*/
|
|
95
|
+
export function readCarrierDeclaration(pinPath) {
|
|
96
|
+
const pin = JSON.parse(readFileSync(pinPath, "utf8"));
|
|
97
|
+
const carrier = pin?.carrier;
|
|
98
|
+
const names = Array.isArray(carrier?.files) ? carrier.files.map((f) => f?.name) : undefined;
|
|
99
|
+
const targets = carrier?.distTargets;
|
|
100
|
+
const plain = (s) => typeof s === "string" && /^[a-z0-9-]+(?:\/[a-z0-9-]+)*\.js$/.test(s);
|
|
101
|
+
if (!names?.every(plain) || names.length === 0 || names.some((n) => n.includes("/"))) {
|
|
102
|
+
throw refuse("pi-durable-carrier-pin-malformed", "carrier.files must name plain carrier .js files");
|
|
103
|
+
}
|
|
104
|
+
if (!Array.isArray(targets) || targets.length === 0 || !targets.every(plain)) {
|
|
105
|
+
throw refuse("pi-durable-carrier-pin-malformed", "carrier.distTargets must list relative dist .js paths");
|
|
106
|
+
}
|
|
107
|
+
return { files: names, targets };
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* The PHYSICAL `dist/` directory of the pi-coding-agent the carrier resolves, from the URL its root
|
|
112
|
+
* export resolved to (`<root>/dist/index.js`). Refuses by name when that is not the package root.
|
|
113
|
+
*
|
|
114
|
+
* @param {string} rootExportUrl
|
|
115
|
+
*/
|
|
116
|
+
export function codingAgentDistFrom(rootExportUrl) {
|
|
117
|
+
const entry = rootExportUrl.startsWith("file:") ? fileURLToPath(rootExportUrl) : "";
|
|
118
|
+
const dist = path.dirname(entry);
|
|
119
|
+
const root = path.dirname(dist);
|
|
120
|
+
const manifest = path.join(root, "package.json");
|
|
121
|
+
if (path.basename(entry) !== "index.js" || path.basename(dist) !== "dist" || !existsSync(manifest)) {
|
|
122
|
+
throw refuse(
|
|
123
|
+
"pi-durable-carrier-host-root",
|
|
124
|
+
`${CODING_AGENT} resolved to ${rootExportUrl}, not <root>/dist/index.js`,
|
|
125
|
+
);
|
|
126
|
+
}
|
|
127
|
+
const name = JSON.parse(readFileSync(manifest, "utf8")).name;
|
|
128
|
+
if (name !== CODING_AGENT) {
|
|
129
|
+
throw refuse("pi-durable-carrier-host-root", `${manifest} names ${JSON.stringify(name)}, not ${CODING_AGENT}`);
|
|
130
|
+
}
|
|
131
|
+
return dist;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Resolve one reserved specifier. Only a declared carrier file may ask, only for a declared target,
|
|
136
|
+
* and the target file must exist. Returns the file URL; everything else throws by name.
|
|
137
|
+
*
|
|
138
|
+
* @param {string} specifier begins with CARRIER_SCHEME
|
|
139
|
+
* @param {string | undefined} parentURL
|
|
140
|
+
* @param {{ carrierDirUrl: string, files: readonly string[], targets: readonly string[], dist: () => string }} declared
|
|
141
|
+
*/
|
|
142
|
+
export function resolveCarrierSpecifier(specifier, parentURL, { carrierDirUrl, files, targets, dist }) {
|
|
143
|
+
const parent =
|
|
144
|
+
typeof parentURL === "string" && parentURL.startsWith(carrierDirUrl) ? parentURL.slice(carrierDirUrl.length) : "";
|
|
145
|
+
if (!files.includes(parent)) {
|
|
146
|
+
throw refuse(
|
|
147
|
+
"pi-durable-carrier-specifier-origin",
|
|
148
|
+
`${specifier} asked from ${parentURL ?? "no parent"}, not a carrier file`,
|
|
149
|
+
);
|
|
150
|
+
}
|
|
151
|
+
const target = specifier.slice(CARRIER_SCHEME.length);
|
|
152
|
+
if (!targets.includes(target)) {
|
|
153
|
+
throw refuse("pi-durable-carrier-specifier-unknown", `${specifier} (from ${parent}) is not a declared target`);
|
|
154
|
+
}
|
|
155
|
+
const file = path.join(dist(), target);
|
|
156
|
+
if (!existsSync(file)) {
|
|
157
|
+
throw refuse("pi-durable-carrier-target-missing", `${specifier} → ${file} does not exist`);
|
|
158
|
+
}
|
|
159
|
+
return pathToFileURL(file).href;
|
|
160
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
// The pi-durable carrier's resolver (#130): preloaded as `node --import <this file>` before the
|
|
2
|
+
// packaged bootstrap. It registers ONE synchronous resolve hook that answers only the carrier's
|
|
3
|
+
// reserved entwurf-pi-dist: specifiers (grammar and refusals: ./carrier-relocation.mjs) and hands
|
|
4
|
+
// every other specifier to Node unchanged. It is not a source/TypeScript resolver and it never reads
|
|
5
|
+
// a checkout, a runtime directory or an environment variable: the pi-coding-agent it maps into is the
|
|
6
|
+
// one the carrier itself resolves from where this package is installed.
|
|
7
|
+
|
|
8
|
+
import { registerHooks } from "node:module";
|
|
9
|
+
import {
|
|
10
|
+
CARRIER_SCHEME,
|
|
11
|
+
CODING_AGENT,
|
|
12
|
+
codingAgentDistFrom,
|
|
13
|
+
readCarrierDeclaration,
|
|
14
|
+
resolveCarrierSpecifier,
|
|
15
|
+
} from "./carrier-relocation.mjs";
|
|
16
|
+
|
|
17
|
+
const { files, targets } = readCarrierDeclaration(new URL("./overlay/upstream-pin.json", import.meta.url));
|
|
18
|
+
const carrierDirUrl = new URL("./carrier/", import.meta.url).href;
|
|
19
|
+
let dist;
|
|
20
|
+
|
|
21
|
+
registerHooks({
|
|
22
|
+
resolve(specifier, context, nextResolve) {
|
|
23
|
+
if (!specifier.startsWith(CARRIER_SCHEME)) return nextResolve(specifier, context);
|
|
24
|
+
const url = resolveCarrierSpecifier(specifier, context.parentURL, {
|
|
25
|
+
carrierDirUrl,
|
|
26
|
+
files,
|
|
27
|
+
targets,
|
|
28
|
+
// From a carrier file, as the carrier's own bare imports resolve — never the exports map.
|
|
29
|
+
dist: () => {
|
|
30
|
+
dist ??= codingAgentDistFrom(
|
|
31
|
+
nextResolve(CODING_AGENT, { ...context, parentURL: `${carrierDirUrl}${files[0]}` }).url,
|
|
32
|
+
);
|
|
33
|
+
return dist;
|
|
34
|
+
},
|
|
35
|
+
});
|
|
36
|
+
return { url, shortCircuit: true };
|
|
37
|
+
},
|
|
38
|
+
});
|
|
@@ -1,16 +1,108 @@
|
|
|
1
1
|
{
|
|
2
|
-
"schemaVersion":
|
|
3
|
-
"comment": "The one upstream commit
|
|
2
|
+
"schemaVersion": 2,
|
|
3
|
+
"comment": "The one upstream commit the pi-durable carrier is emitted from, the patch it applies, the emitted files and the published SDK set they run against. The experimental durable app is source-only upstream (published pi-coding-agent ships no dist/experimental), so Entwurf ships it as a CARRIER: the pinned app files, type-stripped, with the relocation in pi/pi-durable/carrier-relocation.mjs. scripts/emit-pi-durable-carrier.ts is the only writer of the generated fields (blob, sha256, emitter.node) and the only reader of upstream source; an installed package never reads source. Model data rides the published @earendil-works/pi-ai.",
|
|
4
4
|
"repository": "https://github.com/earendil-works/pi",
|
|
5
|
-
"
|
|
5
|
+
"tag": "v1.1.0",
|
|
6
|
+
"commit": "abe508e1b89912adde45528136c3221eb69acdd7",
|
|
6
7
|
"patches": ["runtime-contacts.patch"],
|
|
7
|
-
"
|
|
8
|
-
"comment": "
|
|
9
|
-
"
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
"
|
|
8
|
+
"carrier": {
|
|
9
|
+
"comment": "files: the six app files bootstrap.mjs needs (main.ts is replaced by the bootstrap). distTargets: every pi-coding-agent internal the stripped files import, as paths under the published dist/; the emitter refuses a set that differs and the resolver answers no other.",
|
|
10
|
+
"emitter": {
|
|
11
|
+
"tool": "node:module.stripTypeScriptTypes",
|
|
12
|
+
"mode": "strip",
|
|
13
|
+
"node": "v24.18.1"
|
|
14
|
+
},
|
|
15
|
+
"license": {
|
|
16
|
+
"source": "LICENSE",
|
|
17
|
+
"blob": "b0a8e9b81083294360c69b4ec45d3d39a2b28197",
|
|
18
|
+
"sha256": "0457f5bcec3b3b211605dfb5d1a49042fd638f3686a410fe099c24a25af13c48"
|
|
19
|
+
},
|
|
20
|
+
"files": [
|
|
21
|
+
{
|
|
22
|
+
"name": "runtime.js",
|
|
23
|
+
"source": "packages/coding-agent/src/experimental/durable/runtime.ts",
|
|
24
|
+
"patched": true,
|
|
25
|
+
"blob": "fcd6e5239e999ebf17dea0335fb3dc9cd7f7ce45",
|
|
26
|
+
"sha256": "ca0ee10dc904a57d46bb33b37fcc4efe48dfa08b2f0d10e79e7bc22136871f0a"
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"name": "tui.js",
|
|
30
|
+
"source": "packages/coding-agent/src/experimental/durable/tui.ts",
|
|
31
|
+
"patched": false,
|
|
32
|
+
"blob": "397b276cbeb1c90e1fbc96c3cc59e6a25f92dad7",
|
|
33
|
+
"sha256": "bef1ea4bd6e8ab150273752a9b94552d8ce672b518ba3d1ed1a209b8405be1b3"
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
"name": "harness-setup.js",
|
|
37
|
+
"source": "packages/coding-agent/src/experimental/durable/harness-setup.ts",
|
|
38
|
+
"patched": false,
|
|
39
|
+
"blob": "4d6a4be5333ebb8e0f17eac1987f18ea35a91fc7",
|
|
40
|
+
"sha256": "712b630145dc6f5c655a85b01b1e20299c962542e63c5494d2202bb7bf414a15"
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
"name": "prompt.js",
|
|
44
|
+
"source": "packages/coding-agent/src/experimental/durable/prompt.ts",
|
|
45
|
+
"patched": false,
|
|
46
|
+
"blob": "8e2f5d5273fba58da8b314766956ed62951c3814",
|
|
47
|
+
"sha256": "ff1ff765fa313e5cb1c3d7537c901c23adb0562ee433bd050fd35eb3d892134c"
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
"name": "sessions.js",
|
|
51
|
+
"source": "packages/coding-agent/src/experimental/durable/sessions.ts",
|
|
52
|
+
"patched": false,
|
|
53
|
+
"blob": "34f9ceeeaeaf874f7478d56115da2e4f726c6a85",
|
|
54
|
+
"sha256": "1bd1a04ece66f5ab3ca22860c64dba9abc848334d11a27a9afe543f1365c7254"
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
"name": "subagent.js",
|
|
58
|
+
"source": "packages/coding-agent/src/experimental/durable/subagent.ts",
|
|
59
|
+
"patched": false,
|
|
60
|
+
"blob": "e767d54e0bf2908e0f4f41c6933b55c00562eb25",
|
|
61
|
+
"sha256": "8a75d934ef87efbb0bb2006a2141f1ea932560851f1718b991ed947d6efdb54c"
|
|
62
|
+
}
|
|
63
|
+
],
|
|
64
|
+
"distTargets": [
|
|
65
|
+
"config.js",
|
|
66
|
+
"core/http-dispatcher.js",
|
|
67
|
+
"core/keybindings.js",
|
|
68
|
+
"core/model-resolver.js",
|
|
69
|
+
"core/model-runtime.js",
|
|
70
|
+
"core/resource-loader.js",
|
|
71
|
+
"core/settings-manager.js",
|
|
72
|
+
"core/skills.js",
|
|
73
|
+
"core/system-prompt.js",
|
|
74
|
+
"core/tools/bash.js",
|
|
75
|
+
"core/tools/edit.js",
|
|
76
|
+
"core/tools/read.js",
|
|
77
|
+
"core/tools/renderers/index.js",
|
|
78
|
+
"core/tools/write.js",
|
|
79
|
+
"modes/interactive/components/assistant-message.js",
|
|
80
|
+
"modes/interactive/components/custom-editor.js",
|
|
81
|
+
"modes/interactive/components/dynamic-border.js",
|
|
82
|
+
"modes/interactive/components/footer.js",
|
|
83
|
+
"modes/interactive/components/keybinding-hints.js",
|
|
84
|
+
"modes/interactive/components/status-indicator.js",
|
|
85
|
+
"modes/interactive/components/tool-execution.js",
|
|
86
|
+
"modes/interactive/components/user-message.js",
|
|
87
|
+
"modes/interactive/theme/theme-controller.js",
|
|
88
|
+
"modes/interactive/theme/theme.js"
|
|
89
|
+
]
|
|
90
|
+
},
|
|
91
|
+
"sdk": {
|
|
92
|
+
"comment": "The published library set the carrier runs against, derived from the 1.1.0 declarations. members: the @earendil-works packages the carrier imports and every @earendil-works package those declare. direct: a third-party package a carrier file imports itself (sessions.ts: proper-lockfile, at the version pi-coding-agent 1.1.0 pins). Each is an exact production dependency in package.json; the members' own edges are caret ranges, so the installed physical edges, not semver, are what must equal these versions.",
|
|
93
|
+
"members": {
|
|
94
|
+
"@earendil-works/chord": "1.1.0",
|
|
95
|
+
"@earendil-works/pi-agent-core": "1.1.0",
|
|
96
|
+
"@earendil-works/pi-ai": "1.1.0",
|
|
97
|
+
"@earendil-works/pi-codemode": "1.1.0",
|
|
98
|
+
"@earendil-works/pi-coding-agent": "1.1.0",
|
|
99
|
+
"@earendil-works/pi-durable": "1.1.0",
|
|
100
|
+
"@earendil-works/pi-mcp": "1.1.0",
|
|
101
|
+
"@earendil-works/pi-telemetry": "1.1.0",
|
|
102
|
+
"@earendil-works/pi-tui": "1.1.0"
|
|
103
|
+
},
|
|
104
|
+
"direct": {
|
|
105
|
+
"proper-lockfile": "4.1.2"
|
|
106
|
+
}
|
|
15
107
|
}
|
|
16
108
|
}
|
|
@@ -27,7 +27,7 @@ import { randomBytes } from "node:crypto";
|
|
|
27
27
|
/** The backends this rail can open. Fixed set, not a profile — a further one is a decision,
|
|
28
28
|
* not a config entry. `copilot` was added by #82 RAIL 9, `omp` by #87 Bundle C, `codex`
|
|
29
29
|
* by #95 after its system birth and app-server rails were measured, and `pi-durable` by #129
|
|
30
|
-
* (the
|
|
30
|
+
* (the durable app this package carries, through the managed `entwurf pi-durable`). The set is joined to the
|
|
31
31
|
* citizen backends by `check-harness-admission-parity`: a harness that mints records but is
|
|
32
32
|
* missing HERE is not an unwired convenience, it is a release blocker. */
|
|
33
33
|
export const FRESH_CALL_BACKENDS = ["pi", "claude-code", "copilot", "omp", "codex", "pi-durable"] as const;
|
|
@@ -244,9 +244,9 @@ export const FRESH_CALL_RUNTIME: Record<FreshCallBackend, string> = {
|
|
|
244
244
|
copilot: "entwurf",
|
|
245
245
|
omp: "omp",
|
|
246
246
|
codex: "codex",
|
|
247
|
-
// #129: like copilot, a MANAGED verb and never the bare app. The durable app is
|
|
248
|
-
// and runs under the
|
|
249
|
-
//
|
|
247
|
+
// #129/#130: like copilot, a MANAGED verb and never the bare app. The durable app is this
|
|
248
|
+
// package's carrier and runs under the carrier's resolver; `entwurf pi-durable` is the one fixed
|
|
249
|
+
// invocation that verifies the carrier and its SDK set and execs the packaged bootstrap.
|
|
250
250
|
"pi-durable": "entwurf",
|
|
251
251
|
};
|
|
252
252
|
|
|
@@ -519,15 +519,13 @@ export function freshCall(
|
|
|
519
519
|
}
|
|
520
520
|
if (params.backend === "pi-durable") {
|
|
521
521
|
// The framed first input is computed here only to MEASURE it against the bootstrap payload
|
|
522
|
-
// cap; the same pure function composes it again below. The
|
|
523
|
-
//
|
|
524
|
-
//
|
|
525
|
-
//
|
|
526
|
-
// The managed verb re-verifies with its own env before it execs anything, so the window never
|
|
527
|
-
// runs an unverified runtime — but when HOME/XDG_DATA_HOME or the package closure differ, this
|
|
522
|
+
// cap; the same pure function composes it again below. The carrier is verified from THIS
|
|
523
|
+
// process's package closure, before anything is placed. The window runs whatever `entwurf`
|
|
524
|
+
// PATH names, and the managed verb re-verifies its own package before it execs anything, so
|
|
525
|
+
// the window never runs an unverified carrier — but when the two package closures differ, this
|
|
528
526
|
// verdict and the window's can disagree, and the window is left showing its own refusal.
|
|
529
527
|
const layout = piDurablePackageLayout();
|
|
530
|
-
const runtime = layout === null ? null : checkPiDurableRuntime(
|
|
528
|
+
const runtime = layout === null ? null : checkPiDurableRuntime(layout);
|
|
531
529
|
const missing = piDurableFreshPreflight({
|
|
532
530
|
model,
|
|
533
531
|
firstInput: buildFreshCallPrompt({ backend: params.backend, task, callerGardenId, nonce }),
|
|
@@ -19,9 +19,9 @@
|
|
|
19
19
|
* `{v:2,task}` payload, whose decoder caps `task` at 16000 characters. A framed
|
|
20
20
|
* task over that cap would open a window whose bootstrap refuses its own argv.
|
|
21
21
|
*
|
|
22
|
-
* ── Then the
|
|
22
|
+
* ── Then the carrier, then the four units ──
|
|
23
23
|
*
|
|
24
|
-
*
|
|
24
|
+
* carrier the package's own pi-durable carrier and its declared SDK set, verified
|
|
25
25
|
* (`pi-durable-runtime.ts`); passed in as that check's verdict.
|
|
26
26
|
* birth the compiled contact in this package's closure — it mints the record.
|
|
27
27
|
* MCP hand the compiled entwurf-bridge entry in the same closure — the contact spawns it.
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
*
|
|
33
33
|
* ── What this deliberately does NOT claim ──
|
|
34
34
|
*
|
|
35
|
-
* Filesystem truth about ONE package closure and
|
|
35
|
+
* Filesystem truth about ONE package closure and the SDK it resolves. It does not prove the durable
|
|
36
36
|
* app opens, the bridge connects, the doorbell arms or a garden id renders — that is runtime truth for
|
|
37
37
|
* the clause 7 LIVE receipt. No spawn, no network, no mutation; every path arrives as an argument, so
|
|
38
38
|
* this leaf imports nothing but types.
|