@junghanacs/entwurf 0.12.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 +240 -0
- package/BASELINE.md +227 -0
- package/CHANGELOG.md +1210 -0
- package/CONTRIBUTING.md +63 -0
- package/DELIVERY.md +209 -0
- package/LICENSE +21 -0
- package/README.md +504 -0
- package/VERIFY.md +260 -0
- package/demo/README.md +188 -0
- package/demo/demo-baseline.sh +156 -0
- package/demo/demo.sh +183 -0
- package/docs/assets/entwurf-demo.gif +0 -0
- package/docs/assets/entwurf-doomemacs.gif +0 -0
- package/docs/assets/entwurf-entwurf.gif +0 -0
- package/docs/assets/entwurf-hero.jpg +0 -0
- package/docs/setup-clean-host.md +305 -0
- package/mcp/entwurf-bridge/src/index.ts +513 -0
- package/mcp/entwurf-bridge/start.sh +25 -0
- package/mcp/entwurf-bridge/test.sh +54 -0
- package/mcp/tsconfig.json +29 -0
- package/package.json +130 -0
- package/pi/entwurf-capabilities.json +9 -0
- package/pi/entwurf-targets.json +20 -0
- package/pi/meta-bridge/.claude-plugin/marketplace.json +12 -0
- package/pi/meta-bridge/entwurf-meta-receive/.claude-plugin/plugin.json +5 -0
- package/pi/meta-bridge/entwurf-meta-receive/hooks/hooks.json +50 -0
- package/pi/meta-bridge/entwurf-meta-receive/scripts/doorbell.sh +54 -0
- package/pi/settings.reference.json +43 -0
- package/pi/skill-plugin-example/.claude-plugin/plugin.json +4 -0
- package/pi/skill-plugin-example/skills/hello/SKILL.md +18 -0
- package/pi-extensions/acp-provider.ts +63 -0
- package/pi-extensions/entwurf-control.ts +1692 -0
- package/pi-extensions/lib/acp/acp-client.ts +90 -0
- package/pi-extensions/lib/acp/augment.ts +238 -0
- package/pi-extensions/lib/acp/backend-adapter.ts +319 -0
- package/pi-extensions/lib/acp/backend.ts +873 -0
- package/pi-extensions/lib/acp/config.ts +552 -0
- package/pi-extensions/lib/acp/context.ts +177 -0
- package/pi-extensions/lib/acp/engraving.ts +123 -0
- package/pi-extensions/lib/acp/event-mapper.ts +339 -0
- package/pi-extensions/lib/acp/models.ts +102 -0
- package/pi-extensions/lib/acp/overlay.ts +220 -0
- package/pi-extensions/lib/acp/prompts/engraving.md +1 -0
- package/pi-extensions/lib/acp/session-store.ts +418 -0
- package/pi-extensions/lib/acp/tool-surface.ts +184 -0
- package/pi-extensions/lib/entwurf-control-rpc.ts +208 -0
- package/pi-extensions/lib/entwurf-core.ts +2033 -0
- package/pi-extensions/lib/entwurf-deliverability.ts +123 -0
- package/pi-extensions/lib/entwurf-fact-provider.ts +158 -0
- package/pi-extensions/lib/entwurf-facts.ts +251 -0
- package/pi-extensions/lib/entwurf-mailbox-guard.ts +100 -0
- package/pi-extensions/lib/entwurf-peers-render.ts +154 -0
- package/pi-extensions/lib/entwurf-preflight.ts +247 -0
- package/pi-extensions/lib/entwurf-resume-args.ts +88 -0
- package/pi-extensions/lib/entwurf-self-address.ts +117 -0
- package/pi-extensions/lib/entwurf-v2-contract.ts +427 -0
- package/pi-extensions/lib/entwurf-v2-decider.ts +441 -0
- package/pi-extensions/lib/entwurf-v2-lock.ts +412 -0
- package/pi-extensions/lib/entwurf-v2-mailbox.ts +87 -0
- package/pi-extensions/lib/entwurf-v2-production.ts +326 -0
- package/pi-extensions/lib/entwurf-v2-release.ts +149 -0
- package/pi-extensions/lib/entwurf-v2-resume-marker.ts +34 -0
- package/pi-extensions/lib/entwurf-v2-runner.ts +196 -0
- package/pi-extensions/lib/entwurf-v2-send-fallback.ts +166 -0
- package/pi-extensions/lib/entwurf-v2-send.ts +271 -0
- package/pi-extensions/lib/entwurf-v2-spawn-production.ts +337 -0
- package/pi-extensions/lib/entwurf-v2-spawn.ts +323 -0
- package/pi-extensions/lib/entwurf-v2-surface.ts +205 -0
- package/pi-extensions/lib/meta-mailbox-body.ts +80 -0
- package/pi-extensions/lib/meta-session.ts +1951 -0
- package/pi-extensions/lib/project-trust-handler.ts +154 -0
- package/pi-extensions/lib/session-id.js +57 -0
- package/pi-extensions/lib/socket-discovery.ts +346 -0
- package/pi-extensions/lib/socket-probe.ts +92 -0
- package/pi-extensions/meta-bridge-hook.ts +250 -0
- package/pi-extensions/model-lock.ts +235 -0
- package/prompts/engraving.md +27 -0
- package/protocol.js +31 -0
- package/run.sh +2832 -0
- package/scripts/check-acp-backend-preflight.ts +130 -0
- package/scripts/check-acp-carrier-augment.ts +297 -0
- package/scripts/check-acp-config.ts +322 -0
- package/scripts/check-acp-event-mapper.ts +253 -0
- package/scripts/check-acp-overlay.ts +154 -0
- package/scripts/check-acp-prompt-builder.ts +191 -0
- package/scripts/check-acp-provider-surface.ts +159 -0
- package/scripts/check-acp-sdk-surface.ts +211 -0
- package/scripts/check-acp-session-reuse.ts +756 -0
- package/scripts/check-acp-session-store.ts +387 -0
- package/scripts/check-acp-tool-surface.ts +159 -0
- package/scripts/check-entwurf-bridge-boot.ts +199 -0
- package/scripts/check-entwurf-capabilities.ts +123 -0
- package/scripts/check-entwurf-control-rpc.ts +187 -0
- package/scripts/check-entwurf-deliverability.ts +158 -0
- package/scripts/check-entwurf-fact-provider.ts +316 -0
- package/scripts/check-entwurf-facts.ts +358 -0
- package/scripts/check-entwurf-mailbox-guard.ts +264 -0
- package/scripts/check-entwurf-peers-surface.ts +235 -0
- package/scripts/check-entwurf-resume-args.ts +149 -0
- package/scripts/check-entwurf-self-address.ts +209 -0
- package/scripts/check-entwurf-session-identity.ts +703 -0
- package/scripts/check-entwurf-v2-contract.ts +536 -0
- package/scripts/check-entwurf-v2-decider.ts +795 -0
- package/scripts/check-entwurf-v2-lock.ts +368 -0
- package/scripts/check-entwurf-v2-mailbox.ts +228 -0
- package/scripts/check-entwurf-v2-matrix.ts +437 -0
- package/scripts/check-entwurf-v2-production.ts +406 -0
- package/scripts/check-entwurf-v2-release.ts +245 -0
- package/scripts/check-entwurf-v2-runner.ts +452 -0
- package/scripts/check-entwurf-v2-send-fallback.ts +371 -0
- package/scripts/check-entwurf-v2-send.ts +454 -0
- package/scripts/check-entwurf-v2-spawn-production.ts +452 -0
- package/scripts/check-entwurf-v2-spawn.ts +398 -0
- package/scripts/check-entwurf-v2-surface.ts +352 -0
- package/scripts/check-keyset-overlap.py +120 -0
- package/scripts/check-mailbox-receipt-state.ts +170 -0
- package/scripts/check-meta-capability-source.ts +112 -0
- package/scripts/check-meta-dual-consumers.ts +154 -0
- package/scripts/check-meta-dual-read.ts +158 -0
- package/scripts/check-meta-listing.ts +138 -0
- package/scripts/check-meta-mailbox-state-write.ts +135 -0
- package/scripts/check-meta-migration.ts +212 -0
- package/scripts/check-meta-receiver-marker.ts +185 -0
- package/scripts/check-meta-record-v2.ts +191 -0
- package/scripts/check-meta-session.ts +673 -0
- package/scripts/check-model-lock.ts +408 -0
- package/scripts/check-package-source-routing.ts +253 -0
- package/scripts/check-pi-preflight.ts +304 -0
- package/scripts/check-project-trust-handler.ts +265 -0
- package/scripts/check-shell-quote.ts +121 -0
- package/scripts/check-socket-discovery.ts +428 -0
- package/scripts/check-socket-probe.ts +106 -0
- package/scripts/fixtures/probe-mcp-server.ts +33 -0
- package/scripts/gnew-rpc-drive.ts +211 -0
- package/scripts/lib/acp-child-cleanup.ts +116 -0
- package/scripts/meta-bridge-doctor.sh +315 -0
- package/scripts/meta-bridge-hook-log.sh +26 -0
- package/scripts/meta-bridge-install.sh +135 -0
- package/scripts/meta-bridge-prune.ts +199 -0
- package/scripts/meta-bridge-state.py +549 -0
- package/scripts/meta-bridge-statusline.sh +192 -0
- package/scripts/meta-bridge-store-doctor.ts +64 -0
- package/scripts/meta-bridge-uninstall.sh +39 -0
- package/scripts/new-session-id.ts +25 -0
- package/scripts/postinstall-chmod.cjs +58 -0
- package/scripts/raw-async-delivery/README.md +258 -0
- package/scripts/raw-async-delivery/cc-enqueue-addressed.sh +35 -0
- package/scripts/raw-async-delivery/cc-mailbox-rewake.sh +38 -0
- package/scripts/raw-async-delivery/cc-watch-filechanged.sh +19 -0
- package/scripts/raw-async-delivery/cc-watch-sessionstart.sh +15 -0
- package/scripts/raw-async-delivery/codex-local-appserver.sh +39 -0
- package/scripts/raw-async-delivery/plugin-entwurf-receive/.claude-plugin/plugin.json +5 -0
- package/scripts/raw-async-delivery/plugin-entwurf-receive/hooks/hooks.json +28 -0
- package/scripts/raw-async-delivery/plugin-entwurf-receive/scripts/watch-filechanged.sh +28 -0
- package/scripts/raw-async-delivery/plugin-entwurf-receive/scripts/watch-sessionstart.sh +27 -0
- package/scripts/raw-async-delivery/raw-agy-send.sh +29 -0
- package/scripts/raw-async-delivery/raw-claude-enqueue.sh +30 -0
- package/scripts/raw-async-delivery/raw-codex-ws-turn-start.py +164 -0
- package/scripts/raw-async-delivery/repro-addressed-routing.sh +96 -0
- package/scripts/raw-async-delivery/repro-plugin-idle-wake.sh +104 -0
- package/scripts/resolve-acp-bridge.ts +25 -0
- package/scripts/smoke-acp-bundled-mcp-live.ts +292 -0
- package/scripts/smoke-acp-carrier-augment-live.ts +192 -0
- package/scripts/smoke-acp-mcp-live.ts +129 -0
- package/scripts/smoke-acp-memory-containment-live.ts +389 -0
- package/scripts/smoke-acp-overlay-live.ts +314 -0
- package/scripts/smoke-acp-provider-live.ts +162 -0
- package/scripts/smoke-acp-raw-turn-live.ts +261 -0
- package/scripts/smoke-acp-session-reuse-live.ts +172 -0
- package/scripts/smoke-acp-skill-live.ts +144 -0
- package/scripts/smoke-acp-socket-citizen-live.ts +168 -0
- package/scripts/smoke-claude-native-resume-live.sh +198 -0
- package/scripts/smoke-entwurf-v2-matrix-live.ts +398 -0
- package/scripts/smoke-entwurf-v2-spawn-live.ts +175 -0
- package/scripts/smoke-entwurf-v2-spawn-resume-live.ts +428 -0
- package/scripts/smoke-meta-async-drift.sh +171 -0
- package/scripts/smoke-meta-honesty.sh +147 -0
- package/scripts/smoke-meta-install-state.sh +403 -0
- package/scripts/smoke-meta-keyset-guard.sh +111 -0
- package/scripts/smoke-meta-prune.sh +174 -0
- package/scripts/smoke-resident-garden-guard.sh +433 -0
- package/scripts/smoke-session-id-name.ts +187 -0
- package/scripts/tsconfig.json +34 -0
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
// Deterministic gate for the S2a ACP SDK dependency surface.
|
|
2
|
+
//
|
|
3
|
+
// Pins the ACP runtime deps to the 0.11.0 behavior-oracle versions and locks
|
|
4
|
+
// the peer-resolution that makes the Claude ACP adapter satisfiable:
|
|
5
|
+
//
|
|
6
|
+
// @agentclientprotocol/sdk 0.29.0 wire SDK (acp-bridge import source)
|
|
7
|
+
// @agentclientprotocol/claude-agent-acp 0.50.0 Claude adapter (spawn binary)
|
|
8
|
+
// @anthropic-ai/sdk 0.100.1 peer-resolution pin ONLY (see below)
|
|
9
|
+
//
|
|
10
|
+
// 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.186's peer floor
|
|
12
|
+
// (>=0.93.0); drop it and the tree resolves a stale 0.91.1 so the peer goes
|
|
13
|
+
// unmet — a failure that would only surface at the first raw turn. 0.11.0's
|
|
14
|
+
// lockfile proves the same shape. Source-level import / API-client
|
|
15
|
+
// instantiation / credential use stays forbidden — asserted in layer (4).
|
|
16
|
+
// (GPT hard constraint 2, revised 2026-06-18: direct dep allowed ONLY as an
|
|
17
|
+
// exact peer-resolution pin; source-level use remains forbidden.)
|
|
18
|
+
//
|
|
19
|
+
// Layers:
|
|
20
|
+
// (1) package.json exact pins for all three deps;
|
|
21
|
+
// (2) pnpm-lock peer-resolution lock (adapter + claude-agent-sdk → 0.100.1);
|
|
22
|
+
// (2b) runtime peer-resolution probe (claude-agent-sdk context → 0.100.1);
|
|
23
|
+
// (3) @agentclientprotocol/sdk value-export surface (silent-rename gate);
|
|
24
|
+
// (4) no tracked source imports the anthropic SDK or builds an API client.
|
|
25
|
+
|
|
26
|
+
import { strict as assert } from "node:assert";
|
|
27
|
+
import { execFileSync } from "node:child_process";
|
|
28
|
+
import { readFileSync } from "node:fs";
|
|
29
|
+
import { createRequire } from "node:module";
|
|
30
|
+
import { dirname, resolve } from "node:path";
|
|
31
|
+
|
|
32
|
+
// Split literals so this gate's own regexes never self-match in layer (4).
|
|
33
|
+
const ANTHROPIC_SDK = `@anthropic-ai/${"sdk"}`;
|
|
34
|
+
const API_CLIENT_CLASS = `${"Anthropic"}`;
|
|
35
|
+
|
|
36
|
+
const repoRoot = resolve(import.meta.dirname, "..");
|
|
37
|
+
const read = (p: string): string => readFileSync(resolve(repoRoot, p), "utf8");
|
|
38
|
+
|
|
39
|
+
// ---------------------------------------------------------------------------
|
|
40
|
+
// (1) package.json — exact pins (no caret/range; S2a freezes the oracle set)
|
|
41
|
+
// ---------------------------------------------------------------------------
|
|
42
|
+
const pkg = JSON.parse(read("package.json")) as { dependencies?: Record<string, string> };
|
|
43
|
+
const deps = pkg.dependencies ?? {};
|
|
44
|
+
const PINS: Record<string, string> = {
|
|
45
|
+
"@agentclientprotocol/sdk": "0.29.0",
|
|
46
|
+
"@agentclientprotocol/claude-agent-acp": "0.50.0",
|
|
47
|
+
[ANTHROPIC_SDK]: "0.100.1",
|
|
48
|
+
};
|
|
49
|
+
for (const [name, ver] of Object.entries(PINS)) {
|
|
50
|
+
assert.equal(
|
|
51
|
+
deps[name],
|
|
52
|
+
ver,
|
|
53
|
+
`package.json dependencies["${name}"] must be exact "${ver}" (got "${deps[name]}") — S2a pins the 0.11.0 oracle versions`,
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// ---------------------------------------------------------------------------
|
|
58
|
+
// (2) pnpm-lock — peer-resolution lock
|
|
59
|
+
// The adapter and claude-agent-sdk MUST peer-resolve the anthropic SDK to
|
|
60
|
+
// 0.100.1; a 0.91.1 resolution means the >=0.93.0 peer is unmet (the bug
|
|
61
|
+
// this whole pin exists to prevent).
|
|
62
|
+
// ---------------------------------------------------------------------------
|
|
63
|
+
const lock = read("pnpm-lock.yaml");
|
|
64
|
+
assert.match(
|
|
65
|
+
lock,
|
|
66
|
+
/@agentclientprotocol\/claude-agent-acp@0\.50\.0\(@anthropic-ai\/sdk@0\.100\.1/,
|
|
67
|
+
"pnpm-lock: claude-agent-acp@0.50.0 must peer-resolve @anthropic-ai/sdk@0.100.1 (peer-pin), not the stale 0.91.1",
|
|
68
|
+
);
|
|
69
|
+
assert.match(
|
|
70
|
+
lock,
|
|
71
|
+
/@anthropic-ai\/claude-agent-sdk@0\.3\.186\(@anthropic-ai\/sdk@0\.100\.1/,
|
|
72
|
+
"pnpm-lock: claude-agent-sdk@0.3.186 must peer-resolve @anthropic-ai/sdk@0.100.1 — else its >=0.93.0 peer floor is unmet",
|
|
73
|
+
);
|
|
74
|
+
|
|
75
|
+
// ---------------------------------------------------------------------------
|
|
76
|
+
// (2b) runtime peer-resolution probe — the actual Node resolver, not lock text.
|
|
77
|
+
// Layer (2) freezes the publish/install floor; this probes that the
|
|
78
|
+
// claude-agent-sdk → @anthropic-ai/sdk peer edge really resolves to
|
|
79
|
+
// 0.100.1 in a live module graph. Two different failures, both needed.
|
|
80
|
+
// Note: a top-level/adapter-context resolve of the anthropic SDK may see
|
|
81
|
+
// 0.91.1 (pi's own transitive) — that is normal. The edge that must be
|
|
82
|
+
// 0.100.1 is the one *inside* claude-agent-sdk's context.
|
|
83
|
+
// ---------------------------------------------------------------------------
|
|
84
|
+
const pkgInfoFromEntry = (entryPath: string): { name: string; version: string; dir: string } => {
|
|
85
|
+
// A `<pkg>/package.json` subpath resolve can fail under "exports"; walk up
|
|
86
|
+
// from the resolved entry to the nearest package.json instead.
|
|
87
|
+
let dir = dirname(entryPath);
|
|
88
|
+
for (;;) {
|
|
89
|
+
try {
|
|
90
|
+
const pj = JSON.parse(readFileSync(resolve(dir, "package.json"), "utf8")) as {
|
|
91
|
+
name?: string;
|
|
92
|
+
version?: string;
|
|
93
|
+
};
|
|
94
|
+
if (pj.name && pj.version) return { name: pj.name, version: pj.version, dir };
|
|
95
|
+
} catch {
|
|
96
|
+
// no package.json here (or unreadable) — keep walking up.
|
|
97
|
+
}
|
|
98
|
+
const parent = dirname(dir);
|
|
99
|
+
if (parent === dir) throw new Error(`no package.json found walking up from ${entryPath}`);
|
|
100
|
+
dir = parent;
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
const rootRequire = createRequire(resolve(repoRoot, "package.json"));
|
|
105
|
+
const adapterPkgJson = rootRequire.resolve("@agentclientprotocol/claude-agent-acp/package.json");
|
|
106
|
+
const adapterRequire = createRequire(adapterPkgJson);
|
|
107
|
+
const casEntry = adapterRequire.resolve("@anthropic-ai/claude-agent-sdk");
|
|
108
|
+
const casInfo = pkgInfoFromEntry(casEntry);
|
|
109
|
+
assert.equal(
|
|
110
|
+
casInfo.version,
|
|
111
|
+
"0.3.186",
|
|
112
|
+
`@anthropic-ai/claude-agent-sdk must runtime-resolve to 0.3.186 from the adapter context (got ${casInfo.version})`,
|
|
113
|
+
);
|
|
114
|
+
const casRequire = createRequire(resolve(casInfo.dir, "package.json"));
|
|
115
|
+
const sdkEntry = casRequire.resolve(ANTHROPIC_SDK);
|
|
116
|
+
const sdkInfo = pkgInfoFromEntry(sdkEntry);
|
|
117
|
+
assert.equal(
|
|
118
|
+
sdkInfo.version,
|
|
119
|
+
"0.100.1",
|
|
120
|
+
`${ANTHROPIC_SDK} must peer-resolve to 0.100.1 from the claude-agent-sdk context (got ${sdkInfo.version}) — a 0.91.1 here means the >=0.93.0 peer is unmet and the raw turn would break`,
|
|
121
|
+
);
|
|
122
|
+
|
|
123
|
+
// ---------------------------------------------------------------------------
|
|
124
|
+
// (2c) adapter-context wire-SDK + MCP-SDK runtime resolve — the 0.50 bump's real
|
|
125
|
+
// fault surface. Lock text (layer 2) freezes the publish floor; these probe
|
|
126
|
+
// the LIVE module graph the adapter actually traverses: the adapter must SEE
|
|
127
|
+
// the same wire SDK the backend imports at root (0.29.0), and claude-agent-sdk
|
|
128
|
+
// must SEE its declared MCP peer (1.29.x). Cheap edges, both newly relevant
|
|
129
|
+
// after the 0.39→0.50 / 0.22→0.29 bump.
|
|
130
|
+
// ---------------------------------------------------------------------------
|
|
131
|
+
const wireEntry = adapterRequire.resolve("@agentclientprotocol/sdk");
|
|
132
|
+
const wireInfo = pkgInfoFromEntry(wireEntry);
|
|
133
|
+
assert.equal(
|
|
134
|
+
wireInfo.version,
|
|
135
|
+
"0.29.0",
|
|
136
|
+
`@agentclientprotocol/sdk must runtime-resolve to 0.29.0 from the adapter context (got ${wireInfo.version}) — the adapter and the backend must share one wire SDK`,
|
|
137
|
+
);
|
|
138
|
+
// @modelcontextprotocol/sdk gates its bare specifier behind "exports", so a
|
|
139
|
+
// require.resolve of the package ROOT throws (no resolvable entry) — read the
|
|
140
|
+
// installed package.json directly instead. pnpm hoists ONE mcp instance shared
|
|
141
|
+
// by our root dep, pi, and claude-agent-sdk's ^1.29.0 peer, so the installed
|
|
142
|
+
// copy IS the version the adapter/claude-agent-sdk edge resolves.
|
|
143
|
+
const mcpPkg = JSON.parse(read("node_modules/@modelcontextprotocol/sdk/package.json")) as { version?: string };
|
|
144
|
+
assert.ok(
|
|
145
|
+
typeof mcpPkg.version === "string" && mcpPkg.version.startsWith("1.29."),
|
|
146
|
+
`@modelcontextprotocol/sdk must be 1.29.x (got ${mcpPkg.version}) — claude-agent-sdk 0.3.186 declares a ^1.29.0 peer`,
|
|
147
|
+
);
|
|
148
|
+
|
|
149
|
+
// ---------------------------------------------------------------------------
|
|
150
|
+
// (3) @agentclientprotocol/sdk value-export surface (silent-rename gate)
|
|
151
|
+
// The 0.11.0 acp-bridge imports these from the wire SDK; a silent upstream
|
|
152
|
+
// rename would not fail typecheck (type-only erasure) but would break the
|
|
153
|
+
// raw turn. Assert the *value* exports exist at runtime.
|
|
154
|
+
// ---------------------------------------------------------------------------
|
|
155
|
+
// These are the value imports the real ACP code uses: the connectAcpClient
|
|
156
|
+
// adapter (acp-client.ts) drives `client` + the `AGENT_METHODS`/`CLIENT_METHODS`
|
|
157
|
+
// method tables; the backend + raw-turn smoke value-import `ndJsonStream` (the
|
|
158
|
+
// stdio transport) and `PROTOCOL_VERSION`. The deprecated `ClientSideConnection`
|
|
159
|
+
// is no longer used, so it is no longer gated. (Per GPT: gate only the value
|
|
160
|
+
// imports the real code uses — type-only imports are erased.)
|
|
161
|
+
const acpSdk = (await import("@agentclientprotocol/sdk")) as Record<string, unknown>;
|
|
162
|
+
for (const sym of ["client", "ndJsonStream", "PROTOCOL_VERSION", "AGENT_METHODS", "CLIENT_METHODS"]) {
|
|
163
|
+
assert.ok(
|
|
164
|
+
sym in acpSdk,
|
|
165
|
+
`@agentclientprotocol/sdk lost value export "${sym}" — silent upstream rename; the raw ACP turn would break`,
|
|
166
|
+
);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// ---------------------------------------------------------------------------
|
|
170
|
+
// (4) no source-level anthropic SDK import / API client
|
|
171
|
+
// peer-pin only. The credential boundary (AGENTS §Operating boundaries)
|
|
172
|
+
// forbids the bridge from importing the SDK or instantiating an API client.
|
|
173
|
+
// Line-based: only real `import ... from` / `require(...)` statements count,
|
|
174
|
+
// so this gate's own split-literal regexes above are never offenders.
|
|
175
|
+
// ---------------------------------------------------------------------------
|
|
176
|
+
const tracked = execFileSync("git", ["ls-files", "*.ts", "*.js", "*.mjs", "*.cjs"], {
|
|
177
|
+
cwd: repoRoot,
|
|
178
|
+
encoding: "utf8",
|
|
179
|
+
})
|
|
180
|
+
.split("\n")
|
|
181
|
+
.filter(Boolean);
|
|
182
|
+
|
|
183
|
+
// Specifier-shaped: any module binding to the anthropic SDK, in any of the
|
|
184
|
+
// forms a source file could reach it — static `from`, `export ... from`,
|
|
185
|
+
// side-effect `import "X"`, dynamic `import("X")`, and `require("X")`.
|
|
186
|
+
const spec = `["']${ANTHROPIC_SDK.replace("/", "\\/")}["']`;
|
|
187
|
+
const specifierPatterns: ReadonlyArray<{ re: RegExp; kind: string }> = [
|
|
188
|
+
{ re: new RegExp(String.raw`\bfrom\s+${spec}`), kind: `import/export from ${ANTHROPIC_SDK}` },
|
|
189
|
+
{ re: new RegExp(String.raw`^\s*import\s+${spec}`), kind: `side-effect import ${ANTHROPIC_SDK}` },
|
|
190
|
+
{ re: new RegExp(String.raw`\bimport\(\s*${spec}\s*\)`), kind: `dynamic import(${ANTHROPIC_SDK})` },
|
|
191
|
+
{ re: new RegExp(String.raw`\brequire\(\s*${spec}\s*\)`), kind: `require(${ANTHROPIC_SDK})` },
|
|
192
|
+
];
|
|
193
|
+
const clientRe = new RegExp(String.raw`\bnew\s+${API_CLIENT_CLASS}\s*\(`);
|
|
194
|
+
|
|
195
|
+
const offenders: string[] = [];
|
|
196
|
+
for (const f of tracked) {
|
|
197
|
+
const src = read(f);
|
|
198
|
+
for (const line of src.split("\n")) {
|
|
199
|
+
for (const { re, kind } of specifierPatterns) {
|
|
200
|
+
if (re.test(line)) offenders.push(`${f}: ${kind}`);
|
|
201
|
+
}
|
|
202
|
+
if (clientRe.test(line)) offenders.push(`${f}: new ${API_CLIENT_CLASS}() API client`);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
assert.equal(
|
|
206
|
+
offenders.length,
|
|
207
|
+
0,
|
|
208
|
+
`${ANTHROPIC_SDK} is a peer-resolution pin ONLY — no source import / API client allowed:\n ${offenders.join("\n ")}`,
|
|
209
|
+
);
|
|
210
|
+
|
|
211
|
+
console.log("[check-acp-sdk-surface] ACP dep pins + peer-resolution lock + wire-SDK export surface + no-client-use ok");
|