Repository navigation
fix(store): record cwd for live Claude Code 2.1.283 proxy traffic - #640
Merged
Merged
Conversation
Claude Code 2.1.283 still sends a top-level `system` on context_management requests, but the env block with "Primary working directory:" moved to a role:'system' message. extractCwd returned null as soon as `system` lacked the env line, so the live proxy recorded cwd: null on every Claude entry and session. #637 was validated against _req.json files, which store `system` only as sysHash, so the saved bodies took the context_management branch and looked fixed. extractCwd now falls through to the existing messages / safeguards scan when a context_management request's `system` has no env line. A `system` that names the directory still wins. role:'system' messages are read before messages[0], because on 2.1.283 messages[0] embeds CLAUDE.md and other <system-reminder> text that can quote an env line of its own. Subagent classification is unchanged: without context_management a cwd-less `system` still yields null, so title-generation requests and subagent kickoffs keep "no cwd"; isAnthropicSubagent and isLikelySubagent already return early on context_management. A title-generation entry takes the session's already-known cwd, as before. New e2e test drives the real proxy path with a mock upstream and checks index.ndjson (main turn cwd, title-gen isSubagent and inherited cwd) and sessions.json after shutdown. Old code: 0/3 e2e and the new unit tests fail; new code: all pass. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
4 tasks done
lis186
added a commit
that referenced
this pull request
Sep 27, 2026
…lers (#641) The project row and the star badge built their onclick source with JSON.stringify(value).replace(/"/g, '"'). JSON.stringify does not escape `&`, and the browser decodes the attribute before compiling it as JS, so a literal `"` in the data became a real quote and escaped the string: a directory named `p");alert(1);("` ran code when its project row or star was clicked. Session ids are just as exposed, because metadata.session_id is accepted verbatim. #640 made the path easier to reach by recording cwd for live Claude traffic again. Both values now travel in data-* attributes (escapeHtml'd), and the handlers are fixed strings that read this.dataset, following the existing data-sid / data-resume convention. keyboard-nav.js read project names back by parsing the onclick source; it now reads data-project, which also fixes arrow-key navigation skipping a project whose name JSON.parse could not recover. An audit of every inline on*= handler under public/ found no other site that splices a data-controlled string: the rest use constants, numeric indexes, ccxray-generated entry ids, hex hashes, server-derived agent keys, or the data-* pattern already. There are no javascript: URLs. New puppeteer e2e (test/dashboard-xss-e2e.test.js) clicks the project row, the project star, the session star and the derived-star chip for a payload name and session id, and checks keyboard navigation. Old code: 5 of 6 fail; new code: all pass. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
lis186
added a commit
that referenced
this pull request
Sep 27, 2026
The re-verification showed transcript-only reporting misses about 12% of an interactive host (prompt suggestions and title generation never reach the transcript), so the MVP now reads merged proxy + import data and labels each Ask complete / partial proxy coverage / transcripts only. Records that proxy index lines and their imported twins are pruned after 14 days, splits A1 into a terminal-only A1a and a persistence A1b behind a pricing prerequisite, and updates the #640 cwd gap. Revised after a threeways review. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
lis186
added a commit
that referenced
this pull request
Sep 28, 2026
The re-verification showed transcript-only reporting misses about 12% of an interactive host (prompt suggestions and title generation never reach the transcript), so the MVP now reads merged proxy + import data and labels each Ask complete / partial proxy coverage / transcripts only. Records that proxy index lines and their imported twins are pruned after 14 days, splits A1 into a terminal-only A1a and a persistence A1b behind a pricing prerequisite, and updates the #640 cwd gap. Revised after a threeways review. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
lis186
added a commit
that referenced
this pull request
Sep 28, 2026
* docs: ccxray × agentflow integration spec (draft) Transcript-first per-Ask usage reports for agentflow notebooks (phase A, no agentflow change), and two tool-neutral upstream proposals (phase B: worker run ledger, close-time usage reporter). Records the 2026-09-26 evidence behind PR #637. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * docs(agentflow): dashboard hides imported turns by design; adapter reads the index Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * docs(agentflow): revise spec after adversarial review (GPT-6 Astra, Fable 5.1) - Ask windows: Reply stamp is the end (close commit only a cross-check); start is the host user message matching the Ask body; empty scaffolds, idle gaps, overlaps, retried closes and reopened rounds defined - External workers join host-authored dispatch records first; clone path plus time bound; B1 becomes 'make the dispatch record a contract' - Codex has no responseId: one source per Codex session until a tested key - Reports default to the ccxray data dir; --beside uses the git common dir exclude and is refused in stream worktrees (agentflow cleanup rejects unknown ignored files) - Claude transcripts default to 30-day retention: snapshots move into A1; settled is decided from on-disk data with source fingerprints - B2 block is writer-owned like the stamp, generated once, reused on retry - Corrected stamp format, close semantics, archive naming, workspace-dir; added privacy rules and background-agent rows Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * docs(agentflow): record re-verification on merged main e1b882c - Interactive hosts: ~12% proxy-only traffic (prompt suggestions, titles); transcript-only host rows are lower bounds and labelled as such - Claude proxy+import merge verified at read time; index holds both rows, hideImported is presence-based; Codex double-counting verified - Dispatch join verified 18/18; match on recorded cwd, effort from the top-level field, dedupe usage by message.id - Ask start by first bullet, window tail after the Reply stamp, setup row, host session from the matched message - New A1 prerequisites: live proxy cwd still null on CC 2.1.283, pricing differs across proxy/import/reload paths, prompt-suggestion executor kind Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * docs(agentflow): put the proxy in the MVP; split A1 into A1a/A1b The re-verification showed transcript-only reporting misses about 12% of an interactive host (prompt suggestions and title generation never reach the transcript), so the MVP now reads merged proxy + import data and labels each Ask complete / partial proxy coverage / transcripts only. Records that proxy index lines and their imported twins are pruned after 14 days, splits A1 into a terminal-only A1a and a persistence A1b behind a pricing prerequisite, and updates the #640 cwd gap. Revised after a threeways review. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(agentflow): record owner decisions on completeness and A1a acceptance Three completeness labels and the per-turn-twin rule for complete are decided; A1a does not require exact executor time. A-001..A-008 never went through the proxy, so A1a acceptance expects transcripts only for all of them and the complete/partial paths need a later proxied Ask or fixtures; listed as a known gap. Notes that runner truncation of the captured report does not affect the dispatch fields attribution uses. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
摘要
修正即時 proxy 流量的 Claude cwd 仍然是 null 的問題。
index.ndjson和sessions.json裡的 cwd 還是全部是 null,所有新版 Claude Code 流量的專案歸屬都受影響。system,只是 cwd 那一行搬到了role: system的訊息裡;extractCwd在system裡找不到就直接回傳 null。_req.json不存system(只存 hash),所以拿存下來的請求檔驗證時,走的是另一條程式路徑,看起來是好的。Details
system(starting withx-anthropic-billing-header: cc_version=2.1.283…, about 27 KB) that has noPrimary working directory:line. The env block moved to arole: 'system'message.store.extractCwd'ssystembranch returnednullwithout looking further._req.jsonkeepssysHashinstead ofsystem, so the stored-body analysis behindc4f293ftook thecontext_managementbranch and looked correct. After re-attachingshared/sys_<hash>.jsonandshared/tools_<hash>.jsonto the 22 stored requests from the re-verification run, 0/22 yielded a cwd; stored bodies alone gave 20/22.server/store.js): whensystemhas no cwd line, requests carryingcontext_managementcontinue to the role-system messages, thenmessages[0], thensafeguards[].classifier_context.live_cwd.messages[0], because 2.1.283'smessages[0]embeds CLAUDE.md<system-reminder>text that may quote an unrelatedPrimary working directory:line. The security scan flagged this ordering (F1).context_management(title generation, subagent kickoff) still returnnullas before, soisAnthropicSubagent/isLikelySubagentclassification is unchanged.sessionMetapath, and staysisSubagent: true.test/live-proxy-cwd.e2e.test.jsdrives a real proxy against a mock upstream with a 2.1.283-shaped main turn and a same-session title request. It checks the index cwd, the title request'sisSubagentand cwd inheritance, andsessions.jsonafter shutdown. Unit cases were added totest/store.test.js.docs/wire-protocol-reference.mdgains a changelog entry and a corrected Claude cwd detection description.Verification
CCXRAY_HOME=$(mktemp -d) CCXRAY_EXPORT_DISABLE=1 npm test: 2645/2646. The one failure,hub-owned config status divergence("row 2: local agent-port refusal reaches stdout", timed out), is unrelated. It fails identically with the pre-fixserver/store.json this machine and passes in CI onmain(fix(cli): print --help and reject unknown options before booting #639). The real~/.ccxraywas untouched during the run.test/store.test.jsplustest/live-proxy-cwd.e2e.test.jsagainst the pre-fixstore.jsfail 5 of 72, allactual: null; with the fix, 72/72 pass.claude -p --effort lowwith a general-purpose subagent, through an isolated proxy. All 5 entries andsessions.jsonrecorded the working directory. SubagentagentKey/isSubagentwere unchanged from the pre-fix run.Not verified:
onclickDOM XSS on project names (public/miller-columns.js:1858). It is easier to reach now that cwd is recorded, and it is the next fix in the queue.repoRoot()withoutsanitizeName().🤖 Generated with Claude Code