package.json: the three root scripts that fan out to workspaces stop passing workspace flags after the script name.testandcleanmove the flags before the script name (npm run --workspaces --if-present <script>), andevalmoves its flag beforerun(npm --workspace=@code-yeongyu/senpi-evals run eval --). npm behavior is unchanged in all three cases.scripts/root-workspace-scripts.test.mjs(new): parses the root manifest and fails a root script for either recursion-prone shape — a workspace flag after the script name, or a singular--workspaceon annpm runcall (which bun ignores, re-entering the root script). Both shipped shapes are covered; a mutation check confirms revertingevaltonpm run --workspace=<name> evalfails the guard.
- Bun rewrites
npm run <name>tobun run <name>inside script text, and bun appends flags placed after the script name to the script itself instead of parsing them.npm run test --workspaces --if-presenttherefore re-invoked the ROOT script with an ever-growing flag suffix (bun run test --workspaces --if-present --workspaces --if-present ...) and spun forever instead of running the workspace suites — it never failed, so it read as a slow suite.cleanandevalhad the same defect. Verified in a throwaway fixture: the flag-before form fans out under both npm and bun, while the singular--workspace=<name>form still recurses under bun (bun does not recognize it), which is whyevalneeds the flag beforerunso nonpm runsubstring remains to rewrite.
- These are root package manifest scripts consumed by the release gate (
scripts/release.mjs,scripts/local-release.mjsrunCI=1 npm test) and by contributors directly; no extension surface exists above the package manager.
- LOW: the
test,clean, andevallines in the rootpackage.jsonscripts block.
Shared socket clients now register rendered_components through additive set_client_info capabilities. Factory-rendered component records are filtered per connection, including capability-aware snapshot replay. Capabilities remain connection-wide across sessions and are cleared only on socket release; explicit close removes only the closing width. Shared bindings retain factories while disposing live renderers and footer providers when no capable connection remains, recreating them for later capable joiners.
Root tracker for repository-level divergence from upstream badlogic/pi-mono.
Owns every audited production path whose nearest tracker is the repository root.
biome.jsondrops the!!**/.codegraphignore entry.
- The omo product removed its CodeGraph integration, so nothing writes a
.codegraphdirectory anymore. An ignore entry for a directory that is never created is dead configuration that implies the integration still exists. - The matching
EXCLUDED_ROOT_PATHSchange inpackages/coding-agent/src/beta/omo-local-update-fingerprint.tsis recorded inpackages/coding-agent/src/changes.md, that path's nearest ancestor tracker.
- The biome ignore list is fork-owned: it is an omo-specific surface that upstream
badlogic/pi-monodoes not carry.
- LOW:
biome.jsonignore list ordering during upstream syncs.
package.jsonbumps the pinned@anthropic-ai/sdkfrom0.91.1to0.120.0so the pin satisfies@anthropic-ai/claude-agent-sdk@0.3.241's>=0.93.0peer range.
- Every bun install printed
warn: incorrect peer dependency "@anthropic-ai/sdk@0.91.1"; the SDK floor moved to 0.93.0 when the agent SDK gained its credentials subsystem.
- The root pin set is fork-owned dependency policy; upstream does not pin these packages together.
- LOW:
package.jsonroot dependency pins during upstream syncs.
biome.jsonkeeps the fork lint surface: schema2.5.10,preset: "recommended"syntax, and the**/api/cursor-agent/genand**/.codegraphexclusions.packages/agent/package.jsonkeeps the senpi calver (2026.8.24),tscbuild (upstream usestsgo), and the fork dependency set (diff9,typebox1.3.18, calver workspace ranges).packages/session-backends/sqlite-node/package.jsonkeeps the fork package name@earendil-works/pi-storage-sqlite-node,tscbuild, and vitest4.1.11.packages/telemetry/package.jsonkeeps calver,@types/node26, vitest4.1.11, andprivate: true.packages/tui/package.jsonkeeps calver,tscbuild, the--import tsx+ multiplexer-env test loader, node>=24,marked18.0.10, and thebench:frame-costscript.
These are fork-owned product surfaces (senpi branding, provider wire behavior, fork runtime features) that upstream does not carry; the sync must re-assert them on top of upstream's tree.
The divergence lives in core wiring, package identity, or build plumbing that executes before any extension loads, so no extension hook can express it.
- Version/name/scripts blocks of every listed
package.jsonon each upstream release bump;biome.jsonwhenever upstream migrates Biome versions.
vitest.base.ts: added a resolve alias mapping@earendil-works/pi-ai/auth/*topackages/ai/src/auth/*.tsso vitest resolves the newauth/pool/slotssubpath to source during tests.
- Workspace tests import
@earendil-works/pi-ai/auth/pool/slots; without a source alias vitest resolves to the builtdist, which does not exist for the new module, breaking test runs.
- Test runner aliasing is repository-level tooling configuration.
- LOW: single additive alias line in
vitest.base.ts.
package.json:@biomejs/biome2.5.9 -> 2.5.10.packages/agent/package.json:typebox1.3.16 -> 1.3.18.packages/ai/package.json:typebox1.3.16 -> 1.3.18.packages/coding-agent/package.json:typebox1.3.16 -> 1.3.18.packages/protocol/package.json:typebox1.3.16 -> 1.3.18.packages/senpi-codemode/package.json:typebox1.3.16 -> 1.3.18.packages/{ai,coding-agent}/package.json:@aws-sdk/client-bedrock-runtime3.1115.0 -> 3.1116.0.packages/coding-agent/package.json:@anthropic-ai/claude-agent-sdk0.3.238 -> 0.3.241.- Root and generated release locks were regenerated from those exact pins.
- These are the repository-audited patch-level or same-line upgrades available for the 2026.8.24 release. TypeBox must remain single-instanced across the shared protocol/runtime packages, and the Bedrock pin must remain identical in
aiandcoding-agent. The Claude Agent SDK update also requires regenerating its platform lock and the published/install dependency closures. @anthropic-ai/sdkremains at 0.91.1 because the minimum peer-compatible 0.93.0 still introduces browser-breaking credential-chain imports, while 0.120.0 is likewise unsafe. Deliberate breaking holds remain unchanged foropenai6.26.0 andsignal-exit3.0.7.
- Dependency resolution, exact pins, generated release locks, and platform-package selection happen before the runtime and extension system load.
- HIGH: root and coding-agent dependency blocks and generated lock artifacts.
- MEDIUM: the shared TypeBox pins across five package manifests.
package.json: root devDependencies bumpedesbuild0.28.1 -> 0.28.2 andtsx4.23.1 -> 4.23.12; declaredconcurrently10.0.5 (the rootdevscript invoked it while it was undeclared and absent from the lock); dropped the unused@anthropic-ai/sandbox-runtimeandjitidevDependencies and the unusedget-east-asian-widthdependency. Overrides bumped@hono/node-server2.0.10 -> 2.1.1,postcss8.5.18 -> 8.5.26,brace-expansion5.0.8 -> 5.0.9,esbuild0.28.1 -> 0.28.2,rimraf6.1.2 -> 6.1.3 (including the nestedgaxios.rimrafpin),shell-quote1.9.0 -> 1.10.0,vite8.0.16 -> 8.2.2, andws8.21.1 -> 8.21.3, whilefast-uristays on 3.x andprotobufjson 7.x and@anthropic-ai/sdkstays pinned at 0.91.1..npmrc: rewrote themin-release-ageexemption list as package-name patterns (@hono/node-server,@anthropic-ai/claude-agent-sdk,@aws-sdk/*,@google/genai,@smithy/*,typebox,vite) so the freshly published target versions resolve under the repository's two-day supply-chain window.packages/agent/package.json,packages/protocol/package.json:typeboxmoved to 1.3.16 (from 1.3.8 and from the inconsistent 1.3.7).packages/telemetry/package.json:@types/node24.12.4 -> 26.2.0, matching the rest of the repository.packages/tui/package.json:marked18.0.7 -> 18.0.10.crates/senpi-pty/Cargo.toml,crates/senpi-pty/package.json, and the workspaceCargo.tomlpins:libc=0.2.174 -> =0.2.189,napi=3.10.3 -> =3.12.1,napi-derive=3.5.9 -> =3.6.3,napi-build=2.3.2 -> =2.4.1,@napi-rs/cli3.7.2 -> 3.8.6.scripts/rolldown-platform-lock.test.mjs: the asserted Rolldown binding version tracks 1.0.3 -> 1.2.4, which is whatvite8.2.2 resolves.
- These pins had drifted behind their current releases while the repository enforces exact pins through
npm run check:pinned-deps, so refreshing them in one pass keeps every workspace on one resolved version and keeps the sharedtypeboxidentity single-instanced. The removals delete manifest entries with zero source references, and declaringconcurrentlymakes the root manifest truthful about whatnpm run devactually needs.@anthropic-ai/sdkis deliberately held at 0.91.1 because 0.120.0 adds credential-chain modules whosenode:fsandnode:pathimports break the browser-bundle invariant enforced byscripts/check-browser-smoke.mjs. The.npmrcrewrite fixes an exemption list that could never match: npm compares these patterns against the package name only, so the previousname@versionstring was inert.
- Dependency resolution, override pinning, the supply-chain age gate, and Cargo pin selection are all performed by the package managers before any runtime exists, so no extension can influence which versions get installed or locked.
- HIGH: the
overridesanddevDependenciesblocks inpackage.json, which upstream edits on nearly every release. - MEDIUM: the per-package
typebox/@types/nodepins and the workspaceCargo.tomldependency table. - LOW:
.npmrcand the Rolldown binding version constant.
Canonical backfill seeded from the pre-backfill audit report under
local-ignore/qa-evidence/20260817-changes-md-audit/pre-backfill-audit.json
(upstream pin badlogic/pi-mono v0.84.2, 914cf1472e715297caa30db4b9535d534a9eb718).
Every remaining audited production path with no nearer tracker than the root:
.npmrc: addsmin-release-age-exclude=@hono/node-server@2.0.10on top of the upstream min-release-age supply-chain policy.biome.json: biome schema2.3.5->2.5.5,recommended: truemigrated topreset: "recommended", and extended ignore sets for generated and tool-owned trees (!**/api/cursor-agent/gen,!!**/.codegraph).package.json: monorepo renamedpi-monorepo->senpi-monorepo,packages/ptyjoined the workspace, chained-cdbuild scripts replaced byscripts/build-all.mjswithbuild:npm/build:bun/build:pnpmentry points, rootcheckswappedtsgo --noEmitfortsc --noEmitand addedcheck:claude-sdk-platform-lockplus script-based browser smoke, and fork-onlyverify:pmsorchestration was added.pnpm-workspace.yaml: mirrors the root npm workspace's nestedpackages/session-backends/*glob so the pnpm parity build installs and links the sqlite session backend's workspace dependencies beforescripts/build-all.mjsbuilds it.tsconfig.base.json:target/libraised fromES2022toES2024.tsconfig.json: reformatted to the fork's biome multi-line layout; workspace path mappings are semantically unchanged.vitest.base.ts: added the workspace source alias mapping@earendil-works/pi-ai/utils/*topackages/ai/src/utils/*so shared test configs resolve utils from source.packages/agent/package.json: private CalVer2026.8.16,tsgo->tscbuild/typecheck, fork dependency pins (@earendil-works/pi-ai/pi-telemetry^2026.8.16,diff9.0.0,ignore7.0.6).packages/client/package.json: CalVer2026.8.16,tsgo->tsc,@earendil-works/pi-protocolpinned exactly to2026.8.16.packages/client/src/unix.ts: typed the socketdatacallback chunk asBuffer.packages/protocol/package.json: CalVer2026.8.16,tsgo->tsc.packages/session-backends/sqlite-node/package.json: renamed@earendil-works/pi-session-backend-sqlite-node->@earendil-works/pi-storage-sqlite-node, made private and independently versioned at0.83.0,tsgo->tsc, and keeps its runtimepi-agent-core/pi-aidependencies on lockstep semver ranges so npm, Bun, and pnpm all link the live workspace packages.packages/session-backends/sqlite-node/src/sqlite/repo.ts: optional-chaining refactor of the message-target guard.packages/telemetry/package.json: private CalVer2026.8.16.packages/telemetry/src/index.ts: type-layout reformat under the fork's biome/TypeScript settings; no contract change.packages/tui/package.json: private CalVer2026.8.16,tsgo->tsc, tests run undertsxwithtest/setup-multiplexer-env.mjs, addedbench:frame-cost, Node engine>=24.0.0, pinned bumps (marked18.0.7)..pi/extensions/prompt-url-widget.ts: deleted; relocated into global builtins (see the focused section below)..pi/extensions/tps.ts: deleted; relocated into global builtins (see the focused section below).
- Senpi is a fork with its own identity, CalVer release trains, and an npm/bun/pnpm install
matrix; root manifests, compiler settings, and lint configuration carry that policy, so they
intentionally diverge from the upstream npm-only
0.xlayout. - Non-published support packages (
agent,telemetry,tui, sqlite storage backend) are private and lockstep-versioned or independently pinned per AGENTS dependency policy, which shows up as manifest-level divergence with no deeper tracker of its own. - The two deleted
.pi/extensions/*files were repository-local development extensions that the fork promoted into shipped product behavior; the deletion itself is the audited divergence and is recorded here because.pi/has no tracker of its own.
- Every path in this section is repository, build, toolchain, or non-coding-agent package metadata that executes before any Senpi session, extension loader, or runtime exists. Extensions load inside a coding-agent session and cannot rename a monorepo, retarget compilers, reshape git hooks, reversion packages, or alter dependency policy.
- HIGH: root
package.jsonscripts/workspaces andpackages/*/package.jsonversion blocks on every upstream sync; upstream0.xbumps must be reconciled into CalVer deliberately. - MEDIUM:
biome.json,tsconfig.base.json,tsconfig.json, andvitest.base.tswhenever upstream bumps toolchain majors or adds workspaces. - MEDIUM:
.pi/extensions/prompt-url-widget.tsand.pi/extensions/tps.ts— upstream still owns these files, so syncs will propose edits to deleted paths; resolve to the deletion and re-port any upstream improvement into the builtin copies.
- Deleted
.pi/extensions/prompt-url-widget.tsand.pi/extensions/tps.ts, which the upstream pin still ships as repository-local dev extensions. - Relocated their functionality into always-on global builtins at
packages/coding-agent/src/core/extensions/builtin/prompt-url-widget.tsandpackages/coding-agent/src/core/extensions/builtin/tps.ts, registered with the other fork builtins and covered bypackages/coding-agent/src/core/extensions/builtin/changes.md. - Subsequent fork releases hardened the TPS builtin (monotonic timing in
7f6097bf3, cache-hit notice inc7874fda3) with regression coverage inpackages/coding-agent/test/suite/tps-extension.test.ts. - Context: sibling
.pi/extensions/import-repro.tsand.pi/extensions/redraws.tsmoved the same way and are rename-tracked under the builtin tracker, so they do not appear in the canonical audit list above.
- Repository-local
.pi/extensionsonly load for sessions started inside this clone and require per-repo wiring. Senpi ships the URL prompt widget and tokens-per-second notice as product affordances for every user and session, versioned, registered, and tested together with the coding agent instead of living in an unaudied dot-directory.
- Remaining a repo-local extension is exactly what this change removed: an extension cannot distribute itself to other clones or sessions. Promoting the behavior into the builtin set is the mechanism; there is no extension-side equivalent of "ship enabled-by-default for all users".
- Upstream-side edits to the deleted
.pi/extensions/prompt-url-widget.tsand.pi/extensions/tps.tson every sync (resolve to deletion, re-port improvements). - Builtin registration and widget internals under
packages/coding-agent/src/core/extensions/builtin/if upstream reworks extension loading or adds overlapping notices.
pnpm-workspace.yamlnow includespackages/session-backends/*, matching the root npm workspace and the package set explicitly built byscripts/build-all.mjs.packages/session-backends/sqlite-node/package.jsondeclares its shippedpi-agent-core/pi-aiimports as lockstep runtime dependencies instead of packedfile:dev dependencies.scripts/sync-versions.jskeeps the backend's own0.83.0version independent while synchronizing those lockstep dependency ranges during Senpi releases.
- The release pre-commit gate verifies npm, Bun, and pnpm. Pnpm previously excluded the
nested backend from its workspace and then, once included, packed its
file:dependencies before their declarations were built. The ordered build therefore reached the backend with unresolvedpi-agent-core/pi-aitypes even though npm and Bun passed.
- This is package-manager workspace topology and release-version synchronization. Runtime extensions load only after packages install and build, so they cannot repair missing workspace membership, dependency links, or manifest pins.
- Upstream changes to the SQLite backend's dependency placement or independent-version policy.
- Future workspace additions under nested
packages/*/*paths, which must remain aligned across root npm workspaces,pnpm-workspace.yaml, andscripts/build-all.mjs.