Skip to content

Commit 0e83223

Browse files
committed
Merge main for workflow delivery
2 parents d77c7b4 + b5e22db commit 0e83223

7 files changed

Lines changed: 2734 additions & 2674 deletions

File tree

‎packages/acp/tests/adapter-protocol.test.ts‎

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -524,6 +524,39 @@ describe("Tier EA — the embedded adapters' prompt-response metadata", () => {
524524
});
525525
}
526526

527+
it("HC Claude refuses conflicting confirmation during optional setup", function* () {
528+
let root: string | undefined;
529+
yield* ensure(function* () {
530+
if (root !== undefined) {
531+
yield* rm(root, { recursive: true, force: true });
532+
}
533+
});
534+
root = yield* until(mkdtemp(join(tmpdir(), "xmd startup conflict ")));
535+
const adapter = yield* useAdapter("claude", {
536+
...CLAUDE_ENV,
537+
CLAUDE_CONFIG_DIR: root,
538+
ANTHROPIC_MODEL: "",
539+
FAKE_CLAUDE_CONFIRMATION: "conflicting",
540+
FAKE_CLAUDE_CONFLICT_AT: "context-request",
541+
});
542+
yield* initialize(adapter);
543+
let failure;
544+
try {
545+
yield* adapter.request("session/resume", {
546+
sessionId: "11111111-1111-4111-8111-111111111111",
547+
cwd: root,
548+
mcpServers: [],
549+
});
550+
} catch (error) {
551+
failure = String(error);
552+
}
553+
const log = yield* readTextFile(adapter.log);
554+
expect(log).toContain('"event":"conflict-at-context-request"');
555+
expect(failure).toContain("Claude SessionStart identity confirmation failed");
556+
expect(acceptances(adapter)).toEqual([]);
557+
expect(log).not.toContain('"type":"user"');
558+
});
559+
527560
it("HC Claude cancellation joins the held startup Query with no late response", function* () {
528561
let adapter: Adapter | undefined;
529562
let answered = false;

‎packages/acp/tests/fixtures/fake-claude-cli.cjs‎

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ function confirm() {
9292
uuid: crypto.randomUUID(),
9393
session_id: confirmation === "mismatch" ? "other-conversation" : SESSION,
9494
});
95-
if (confirmation === "conflicting") {
95+
if (confirmation === "conflicting" && process.env.FAKE_CLAUDE_CONFLICT_AT !== "context-request") {
9696
emit({
9797
type: "system",
9898
subtype: "hook_response",
@@ -142,6 +142,29 @@ process.stdin.on("data", (chunk) => {
142142
// The SDK opens with a control handshake and will not send a turn until it
143143
// is answered.
144144
if (message.type === "control_request") {
145+
if (
146+
confirmation === "conflicting" &&
147+
process.env.FAKE_CLAUDE_CONFLICT_AT === "context-request" &&
148+
message.request?.subtype === "get_context_usage"
149+
) {
150+
log({ event: "conflict-at-context-request" });
151+
emit({
152+
type: "system",
153+
subtype: "hook_response",
154+
hook_id: "internal",
155+
hook_name: "opaque",
156+
hook_event: "SessionStart",
157+
stdout: "",
158+
stderr: "",
159+
output: "",
160+
exit_code: 0,
161+
outcome: "success",
162+
uuid: crypto.randomUUID(),
163+
session_id: "other-conversation",
164+
});
165+
// Only Query failure releases this lookup, so setup cannot outrun the contradiction.
166+
continue;
167+
}
145168
emit({
146169
type: "control_response",
147170
response: {

‎packages/acp/vendor/adapters/MANIFEST.json‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,14 +32,14 @@
3232
"tarball": "claude/agentclientprotocol-claude-agent-acp-0.70.0.tgz",
3333
"repository": "https://github.com/agentclientprotocol/claude-agent-acp",
3434
"upstreamBase": "8710ce1cbccf562cb04b4bcc30e053e960aee05f",
35-
"patchedCommit": "54df80cbb41f2aa56195fd56b4dc2a88295049af",
35+
"patchedCommit": "bea799c86d16ed2b1bf1cfe8d7fd6e22e6525b56",
3636
"pullRequest": "https://github.com/agentclientprotocol/claude-agent-acp/pull/1047",
3737
"buildCommand": "npm run build && npm pack",
3838
"license": "Apache-2.0",
3939
"contract": "_meta.claudeCode.assistantMessageUuid",
4040
"materializationContract": "session_info_update _meta[executablemd.session-materialization/v1]",
41-
"byteLength": 195701,
42-
"sha256": "a62d36d02a3e3e5cc896d5467ad8026a59e7d5e5a1940068aebae5f03f469488",
41+
"byteLength": 195823,
42+
"sha256": "6490fb5dccf0273720587bf0a2e2d5940d4afb73119b82011e9cedf6ffe9be8f",
4343
"files": [
4444
"package/LICENSE",
4545
"package/README.md",

‎packages/acp/vendor/adapters/PROVENANCE.md‎

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,13 +71,16 @@ owned SDK Query supplies a successful SessionStart lifecycle response with that
7171
exact `session_id`. One fixed no-op command hook, using the adapter's own Node
7272
runtime, is composed into settings before startup or resume. Deliberate settings
7373
and hooks survive; disabled, absent, failed, conflicting or mismatched
74-
confirmation refuses. One owned reader buffers early unrelated messages and
74+
confirmation refuses. The reader records identity refusal before closing its SDK
75+
iterator, whose cleanup can release pending setup lookups. Session publication
76+
rechecks reader failure and disposal after optional SDK setup, before registering
77+
or answering success. One owned reader buffers early unrelated messages and
7578
retains the explicit acceptance and exact completed-prompt checkpoint handling.
7679
Fresh confirmation stays provisional until acceptance and the asserting save.
7780
Native Claude allocation remains client-allocated, independently of metadata.
7881

7982
The Claude source revision recorded in MANIFEST.json extends the retained patch
80-
at `beba04dc177ba09bcc9fa10b56e9ded7f219513e`; its local source patch and build
83+
at `54df80cbb41f2aa56195fd56b4dc2a88295049af`; its local source patch and build
8184
receipt are supplied with the implementation evidence. The pin records source
8285
identity, not an unperformed independent review.
8386

Binary file not shown.

0 commit comments

Comments
 (0)