@junghanacs/entwurf 0.12.8 → 0.12.10
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 +134 -248
- package/BASELINE.md +1 -1
- package/CHANGELOG.md +39 -1
- package/DELIVERY.md +5 -4
- package/README.md +148 -23
- package/VERIFY.md +3 -2
- package/demo/README.md +2 -2
- package/demo/demo.sh +7 -1
- package/docs/setup-clean-host.md +24 -7
- package/mcp/entwurf-bridge/dist/mcp/entwurf-bridge/src/index.js +168 -81
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/acp/models.js +12 -12
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/acp/overlay.js +5 -3
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-core.js +26 -9
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-deliverability.js +10 -6
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-fact-provider.js +16 -18
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-facts.js +13 -13
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-resume-args.js +31 -41
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-self-address.js +8 -9
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-v2-contract.js +32 -25
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-v2-decider.js +4 -4
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-v2-lock.js +5 -4
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-v2-production.js +14 -13
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-v2-spawn-production.js +11 -3
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/meta-sender-identity.js +15 -4
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/meta-session.js +500 -54
- package/mcp/entwurf-bridge/dist/pi-extensions/meta-bridge-hook.js +8 -3
- package/mcp/entwurf-bridge/dist/scripts/agy-imprint.js +14 -2
- package/mcp/entwurf-bridge/dist/scripts/meta-bridge-fresh-cut.js +155 -29
- package/mcp/entwurf-bridge/src/index.ts +200 -94
- package/package.json +11 -9
- package/pi-extensions/entwurf-control.ts +81 -39
- package/pi-extensions/lib/acp/models.ts +12 -12
- package/pi-extensions/lib/acp/overlay.ts +5 -3
- package/pi-extensions/lib/entwurf-core.ts +26 -9
- package/pi-extensions/lib/entwurf-deliverability.ts +10 -6
- package/pi-extensions/lib/entwurf-fact-provider.ts +24 -19
- package/pi-extensions/lib/entwurf-facts.ts +13 -13
- package/pi-extensions/lib/entwurf-resume-args.ts +40 -46
- package/pi-extensions/lib/entwurf-self-address.ts +8 -9
- package/pi-extensions/lib/entwurf-v2-contract-schema.ts +7 -2
- package/pi-extensions/lib/entwurf-v2-contract.ts +32 -25
- package/pi-extensions/lib/entwurf-v2-decider.ts +8 -8
- package/pi-extensions/lib/entwurf-v2-lock.ts +5 -4
- package/pi-extensions/lib/entwurf-v2-production.ts +22 -13
- package/pi-extensions/lib/entwurf-v2-spawn-production.ts +11 -3
- package/pi-extensions/lib/meta-sender-identity.ts +15 -5
- package/pi-extensions/lib/meta-session.ts +543 -58
- package/pi-extensions/meta-bridge-hook.ts +8 -2
- package/run.sh +78 -67
- package/scripts/agy-bridge-config.py +249 -49
- package/scripts/agy-bridge.sh +59 -14
- package/scripts/agy-imprint.ts +15 -1
- package/scripts/check-acp-carrier-augment.ts +34 -2
- package/scripts/check-acp-sdk-surface.ts +22 -11
- package/scripts/check-acp-session-reuse.ts +1 -1
- package/scripts/check-acp-session-store.ts +3 -3
- package/scripts/check-agy-permission-matrix.py +655 -0
- package/scripts/check-agy-sender-identity.ts +83 -0
- package/scripts/check-entwurf-control-rpc.ts +2 -2
- package/scripts/check-entwurf-deliverability.ts +9 -6
- package/scripts/check-entwurf-fact-provider.ts +16 -8
- package/scripts/check-entwurf-facts.ts +13 -13
- package/scripts/check-entwurf-resume-args.ts +25 -63
- package/scripts/check-entwurf-self-address.ts +187 -4
- package/scripts/check-entwurf-session-identity.ts +7 -6
- package/scripts/check-entwurf-v2-contract.ts +2 -2
- package/scripts/check-entwurf-v2-production.ts +9 -7
- package/scripts/check-entwurf-v2-spawn-production.ts +8 -4
- package/scripts/check-entwurf-v2-surface.ts +327 -14
- package/scripts/check-fresh-cut-gate.sh +305 -4
- package/scripts/check-gate-qualification.ts +785 -0
- package/scripts/check-meta-identity-consumers.ts +501 -1
- package/scripts/check-meta-listing.ts +91 -9
- package/scripts/check-meta-receiver-marker.ts +54 -0
- package/scripts/check-model-lock.ts +1 -1
- package/scripts/check-shell-quote.ts +2 -1
- package/scripts/lib/mutation-qualify.ts +794 -0
- package/scripts/meta-bridge-fresh-cut.ts +164 -28
- package/scripts/mutants/acp-augment.json +30 -0
- package/scripts/mutants/agy-permission.json +144 -0
- package/scripts/mutants/meta-identity.json +17 -0
- package/scripts/mutants/self-address.json +59 -0
- package/scripts/mutants/v2-surface.json +87 -0
- package/scripts/pi_settings_io.py +65 -0
- package/scripts/register-pi-package.py +183 -37
- package/scripts/register-pi-provider.py +68 -10
- package/scripts/smoke-acp-raw-turn-live.ts +1 -1
- package/scripts/smoke-acp-socket-citizen-live.ts +2 -2
- package/scripts/smoke-acp-v2-send-live.ts +33 -18
- package/scripts/smoke-agy-install-state.sh +205 -20
- package/scripts/smoke-entwurf-v2-matrix-live.ts +3 -2
- package/scripts/smoke-meta-install-state.sh +1 -1
- package/scripts/smoke-pi-attach.ts +7 -2
- package/scripts/smoke-user-scope-citizen.sh +177 -0
- package/pi-extensions/lib/entwurf-mailbox-guard.ts +0 -100
- package/scripts/check-entwurf-mailbox-guard.ts +0 -262
|
@@ -18,6 +18,7 @@ import { strict as assert } from "node:assert";
|
|
|
18
18
|
import { mkdtempSync, writeFileSync } from "node:fs";
|
|
19
19
|
import { tmpdir } from "node:os";
|
|
20
20
|
import { join } from "node:path";
|
|
21
|
+
import { fileURLToPath } from "node:url";
|
|
21
22
|
import type { Context } from "@earendil-works/pi-ai";
|
|
22
23
|
import {
|
|
23
24
|
buildPiContextAugment,
|
|
@@ -32,6 +33,7 @@ import { buildClaudeSessionMeta } from "../pi-extensions/lib/acp/tool-surface.ts
|
|
|
32
33
|
import { ENTWURF_PROJECT_CONTEXT_OPEN_TAG } from "../protocol.js";
|
|
33
34
|
|
|
34
35
|
const tmp = mkdtempSync(join(tmpdir(), "acp-carrier-augment-"));
|
|
36
|
+
const REPO_DIR = fileURLToPath(new URL("..", import.meta.url));
|
|
35
37
|
const BRIDGE_MARK = "operating through entwurf";
|
|
36
38
|
|
|
37
39
|
// ===========================================================================
|
|
@@ -285,7 +287,37 @@ function ctxWith(firstUser: string): Context {
|
|
|
285
287
|
writeFileSync(join(bigHome, "AGENTS.md"), "X".repeat(80 * 1024));
|
|
286
288
|
const big = buildPiContextAugment({ backend: "claude", cwd: tmp, mcpServerNames: [], homeDir: bigHome });
|
|
287
289
|
assert.ok(Buffer.byteLength(big, "utf8") <= 50 * 1024, "augment is truncated to the 50KB cap");
|
|
288
|
-
assert.match(
|
|
290
|
+
assert.match(
|
|
291
|
+
big,
|
|
292
|
+
/context augment truncated to \d+ bytes/,
|
|
293
|
+
"truncation leaves an honest marker [QK:AUGMENT-TRUNC-MARKER]",
|
|
294
|
+
);
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
// ===========================================================================
|
|
298
|
+
// 9) The shipped repo AGENTS.md fits with a realistic operator-global budget.
|
|
299
|
+
// This guards the real 2026-07-27 failure: project AGENTS.md alone exceeded
|
|
300
|
+
// the cap, tail-cutting its own later rules plus Current date/cwd. The cap
|
|
301
|
+
// remains an honest fallback; the maintained package prompt must not hit it.
|
|
302
|
+
// ===========================================================================
|
|
303
|
+
{
|
|
304
|
+
const budgetHome = mkdtempSync(join(tmpdir(), "acp-budget-home-"));
|
|
305
|
+
writeFileSync(join(budgetHome, "AGENTS.md"), "H".repeat(12 * 1024));
|
|
306
|
+
const actual = buildPiContextAugment({
|
|
307
|
+
backend: "claude",
|
|
308
|
+
cwd: REPO_DIR,
|
|
309
|
+
mcpServerNames: ["entwurf-bridge"],
|
|
310
|
+
homeDir: budgetHome,
|
|
311
|
+
});
|
|
312
|
+
assert.doesNotMatch(
|
|
313
|
+
actual,
|
|
314
|
+
/context augment truncated/,
|
|
315
|
+
"repo AGENTS.md + 12KB global baseline fits without truncation [QK:AUGMENT-BUDGET-FITS]",
|
|
316
|
+
);
|
|
317
|
+
assert.ok(
|
|
318
|
+
actual.includes(`Current working directory: ${REPO_DIR}`),
|
|
319
|
+
"non-truncated augment retains the trailing cwd fact",
|
|
320
|
+
);
|
|
289
321
|
}
|
|
290
322
|
|
|
291
323
|
console.log(
|
|
@@ -293,5 +325,5 @@ console.log(
|
|
|
293
325
|
"empty/whitespace/missing → null, shipped-default → non-empty v1 lever (preset replaced), carrier absent → no _meta.systemPrompt key, carrier change → " +
|
|
294
326
|
"signature change (stable carrier → stable signature); augment: prepended on `new` only (reuse delta has none), " +
|
|
295
327
|
"wire-only so it never enters contextMessageSignatures, entwurf cwd/AGENTS.md de-dup (present → drop only that " +
|
|
296
|
-
"section, home kept; absent → kept), day-granularity date, 50KB truncation marker",
|
|
328
|
+
"section, home kept; absent → kept), day-granularity date, 50KB truncation marker, shipped AGENTS budget",
|
|
297
329
|
);
|
|
@@ -4,12 +4,23 @@
|
|
|
4
4
|
// the peer-resolution that makes the Claude ACP adapter satisfiable:
|
|
5
5
|
//
|
|
6
6
|
// @agentclientprotocol/sdk 1.3.0 wire SDK (acp-bridge import source)
|
|
7
|
-
// @agentclientprotocol/claude-agent-acp 0.
|
|
7
|
+
// @agentclientprotocol/claude-agent-acp 0.62.0 Claude adapter (spawn binary)
|
|
8
8
|
// @anthropic-ai/sdk 0.100.1 peer-resolution pin ONLY (see below)
|
|
9
9
|
//
|
|
10
|
+
// 2026-07-27 bump 0.61.0 → 0.62.0: the adapter's own `dist/` is byte-identical
|
|
11
|
+
// across the two releases; 0.62.0 moves only its declared deps
|
|
12
|
+
// (claude-agent-sdk 0.3.217 → 0.3.219; its devDep anthropic sdk, which does not
|
|
13
|
+
// reach us). So this bump is a dependency refresh that carries NO adapter-code
|
|
14
|
+
// change — and specifically NOT a fix for the bundled-MCP readiness race
|
|
15
|
+
// (ROADMAP 🔴): 0.62.0 adds no explicit readiness fence. Effective runtime
|
|
16
|
+
// behavior is NOT claimed identical: the transitive SDK moved, and MCP startup
|
|
17
|
+
// lives inside it, so timing may differ — what is established is only that no
|
|
18
|
+
// new fence was added.
|
|
19
|
+
//
|
|
10
20
|
// The anthropic SDK is NOT an API client / auth surface here. It is a direct
|
|
11
|
-
// dep solely to satisfy @anthropic-ai/claude-agent-sdk@0.3.
|
|
12
|
-
// (>=0.93.0
|
|
21
|
+
// dep solely to satisfy @anthropic-ai/claude-agent-sdk@0.3.219's peer floor
|
|
22
|
+
// (>=0.93.0 — re-measured at 0.3.219, unchanged from 0.3.217, so the 0.100.1
|
|
23
|
+
// pin stands rather than rising mechanically); drop it and the tree resolves a stale 0.91.1 so the peer goes
|
|
13
24
|
// unmet — a failure that would only surface at the first raw turn. The
|
|
14
25
|
// lockfile proves the same shape. Source-level import / API-client
|
|
15
26
|
// instantiation / credential use stays forbidden — asserted in layer (4).
|
|
@@ -43,7 +54,7 @@ const pkg = JSON.parse(read("package.json")) as { dependencies?: Record<string,
|
|
|
43
54
|
const deps = pkg.dependencies ?? {};
|
|
44
55
|
const PINS: Record<string, string> = {
|
|
45
56
|
"@agentclientprotocol/sdk": "1.3.0",
|
|
46
|
-
"@agentclientprotocol/claude-agent-acp": "0.
|
|
57
|
+
"@agentclientprotocol/claude-agent-acp": "0.62.0",
|
|
47
58
|
[ANTHROPIC_SDK]: "0.100.1",
|
|
48
59
|
};
|
|
49
60
|
for (const [name, ver] of Object.entries(PINS)) {
|
|
@@ -63,13 +74,13 @@ for (const [name, ver] of Object.entries(PINS)) {
|
|
|
63
74
|
const lock = read("pnpm-lock.yaml");
|
|
64
75
|
assert.match(
|
|
65
76
|
lock,
|
|
66
|
-
/@agentclientprotocol\/claude-agent-acp@0\.
|
|
67
|
-
"pnpm-lock: claude-agent-acp@0.
|
|
77
|
+
/@agentclientprotocol\/claude-agent-acp@0\.62\.0\(@anthropic-ai\/sdk@0\.100\.1/,
|
|
78
|
+
"pnpm-lock: claude-agent-acp@0.62.0 must peer-resolve @anthropic-ai/sdk@0.100.1 (peer-pin), not the stale 0.91.1",
|
|
68
79
|
);
|
|
69
80
|
assert.match(
|
|
70
81
|
lock,
|
|
71
|
-
/@anthropic-ai\/claude-agent-sdk@0\.3\.
|
|
72
|
-
"pnpm-lock: claude-agent-sdk@0.3.
|
|
82
|
+
/@anthropic-ai\/claude-agent-sdk@0\.3\.219\(@anthropic-ai\/sdk@0\.100\.1/,
|
|
83
|
+
"pnpm-lock: claude-agent-sdk@0.3.219 must peer-resolve @anthropic-ai/sdk@0.100.1 — else its >=0.93.0 peer floor is unmet",
|
|
73
84
|
);
|
|
74
85
|
|
|
75
86
|
// ---------------------------------------------------------------------------
|
|
@@ -108,8 +119,8 @@ const casEntry = adapterRequire.resolve("@anthropic-ai/claude-agent-sdk");
|
|
|
108
119
|
const casInfo = pkgInfoFromEntry(casEntry);
|
|
109
120
|
assert.equal(
|
|
110
121
|
casInfo.version,
|
|
111
|
-
"0.3.
|
|
112
|
-
`@anthropic-ai/claude-agent-sdk must runtime-resolve to 0.3.
|
|
122
|
+
"0.3.219",
|
|
123
|
+
`@anthropic-ai/claude-agent-sdk must runtime-resolve to 0.3.219 from the adapter context (got ${casInfo.version})`,
|
|
113
124
|
);
|
|
114
125
|
const casRequire = createRequire(resolve(casInfo.dir, "package.json"));
|
|
115
126
|
const sdkEntry = casRequire.resolve(ANTHROPIC_SDK);
|
|
@@ -152,7 +163,7 @@ const mcpEntry = casRequire.resolve("@modelcontextprotocol/sdk/server/index.js")
|
|
|
152
163
|
const mcpInfo = pkgInfoFromEntry(mcpEntry);
|
|
153
164
|
assert.ok(
|
|
154
165
|
mcpInfo.version.startsWith("1.29."),
|
|
155
|
-
`@modelcontextprotocol/sdk must runtime-resolve to 1.29.x from the claude-agent-sdk context (got ${mcpInfo.version}) — claude-agent-sdk 0.3.
|
|
166
|
+
`@modelcontextprotocol/sdk must runtime-resolve to 1.29.x from the claude-agent-sdk context (got ${mcpInfo.version}) — claude-agent-sdk 0.3.219 declares a ^1.29.0 peer`,
|
|
156
167
|
);
|
|
157
168
|
|
|
158
169
|
// ---------------------------------------------------------------------------
|
|
@@ -33,7 +33,7 @@ import { pathToFileURL } from "node:url";
|
|
|
33
33
|
import type { Api, AssistantMessageEvent, Context, Message, Model } from "@earendil-works/pi-ai";
|
|
34
34
|
|
|
35
35
|
const sonnet = { id: "claude-sonnet-5" } as unknown as Model<Api>;
|
|
36
|
-
const opus = { id: "claude-opus-
|
|
36
|
+
const opus = { id: "claude-opus-5" } as unknown as Model<Api>;
|
|
37
37
|
|
|
38
38
|
type Stream = AsyncIterable<AssistantMessageEvent> & {
|
|
39
39
|
result: () => Promise<{ stopReason: string; errorMessage?: string }>;
|
|
@@ -85,7 +85,7 @@ const baseInput = (): BridgeConfigInput => ({
|
|
|
85
85
|
);
|
|
86
86
|
// Model drift → different signature.
|
|
87
87
|
assert.notEqual(
|
|
88
|
-
bridgeConfigSignature({ ...baseInput(), modelId: "claude-opus-
|
|
88
|
+
bridgeConfigSignature({ ...baseInput(), modelId: "claude-opus-5" }),
|
|
89
89
|
bridgeConfigSignature(baseInput()),
|
|
90
90
|
"model drift changes the signature",
|
|
91
91
|
);
|
|
@@ -186,7 +186,7 @@ const baseInput = (): BridgeConfigInput => ({
|
|
|
186
186
|
const params = facts({ contextMessageSignatures: ["user:text:a", "assistant:text:b"] });
|
|
187
187
|
assert.ok(isCompatible(facts(), params), "prefix history + same cfg → compatible");
|
|
188
188
|
assert.ok(!isCompatible(facts({ cwd: "/other" }), params), "cwd drift → incompatible");
|
|
189
|
-
assert.ok(!isCompatible(facts({ modelId: "claude-opus-
|
|
189
|
+
assert.ok(!isCompatible(facts({ modelId: "claude-opus-5" }), params), "model drift → incompatible");
|
|
190
190
|
assert.ok(!isCompatible(facts({ bridgeConfigSignature: "different" }), params), "signature drift → incompatible");
|
|
191
191
|
assert.ok(
|
|
192
192
|
!isCompatible(facts({ contextMessageSignatures: ["user:text:EDITED"] }), params),
|
|
@@ -292,7 +292,7 @@ const baseInput = (): BridgeConfigInput => ({
|
|
|
292
292
|
assert.throws(
|
|
293
293
|
() =>
|
|
294
294
|
decideBootstrap(params("process-scoped"), {
|
|
295
|
-
existing: { ...aliveCompat, modelId: "claude-opus-
|
|
295
|
+
existing: { ...aliveCompat, modelId: "claude-opus-5" },
|
|
296
296
|
}),
|
|
297
297
|
SessionModelLockedError,
|
|
298
298
|
"live model mismatch throws SessionModelLockedError",
|