Skip to content

Bump the runtime-node-dependencies group in /src/cyclo/vendor_gateway/runtime_context with 2 updates - #6

Closed
dependabot[bot] wants to merge 1 commit into
mainfrom
dependabot/npm_and_yarn/src/cyclo/vendor_gateway/runtime_context/runtime-node-dependencies-23ffe9c6f1
Closed

Bump the runtime-node-dependencies group in /src/cyclo/vendor_gateway/runtime_context with 2 updates#6
dependabot[bot] wants to merge 1 commit into
mainfrom
dependabot/npm_and_yarn/src/cyclo/vendor_gateway/runtime_context/runtime-node-dependencies-23ffe9c6f1

Conversation

@dependabot

@dependabot dependabot Bot commented on behalf of github Jul 15, 2026

Copy link
Copy Markdown

Bumps the runtime-node-dependencies group in /src/cyclo/vendor_gateway/runtime_context with 2 updates: @earendil-works/pi-coding-agent and pi-lens.

Updates @earendil-works/pi-coding-agent from 0.80.6 to 0.80.7

Release notes

Sourced from @​earendil-works/pi-coding-agent's releases.

v0.80.7

Breaking Changes

  • Removed the openai-responses compat.sendSessionIdHeader flag from models.json. Session-affinity behavior is now controlled by compat.sessionAffinityFormat ("openai", "openai-nosession", or "openrouter"). Replace sendSessionIdHeader: false with sessionAffinityFormat: "openai-nosession" (#6496 by @​petrroll).

New Features

  • Cache-friendly dynamic tool loading - Extensions can add tools during execution while supported Anthropic and OpenAI Responses models preserve prompt-cache prefixes. See Dynamic Tool Loading.
  • Message copy shortcut - Ctrl+X copies the last assistant message in the transcript or the selected message in /tree, making older and branched messages directly copyable. See Display and Message Queue.
  • Fable 5 xhigh and max thinking - Native xhigh and max thinking levels are available across generated provider catalogs. See Model Options.

Added

  • Added cache-friendly dynamic tool loading for extension tools activated by tool results. Supported Anthropic and OpenAI Responses models load definitions where they become available, preserving the cached prompt prefix. See Dynamic Tool Loading (#6474).
  • Added inherited native xhigh and max thinking levels for Claude Fable 5 across all generated provider catalogs (#6490 by @​davidbrai).
  • Added Ctrl+X to copy the last assistant message, or the selected message in /tree.
  • Added inherited toolChoice support for OpenAI and Codex Responses, including required and named tool selection (#6588 by @​xl0).

Fixed

  • Fixed inherited OpenRouter model context windows to use the top provider's actual context length (#6481 by @​davidbrai).
  • Fixed inherited OpenRouter OpenAI-compatible session IDs to use the x-session-id header instead of OpenAI-specific session-affinity fields (#6496 by @​petrroll).
  • Fixed Ctrl+V to paste clipboard text when the pasteboard does not contain an image.
  • Fixed /login amazon-bedrock to prompt for and save a Bedrock API key instead of only displaying ambient AWS credential setup instructions.
  • Fixed inherited Amazon Bedrock ambient AWS credentials to keep using SigV4 authentication, including for custom model IDs (#6532 by @​ribelo).
  • Fixed inherited Cloudflare Workers AI and AI Gateway authentication to use ambient account and gateway IDs when stored credentials contain only an API key (#6292 by @​markphelps).
  • Fixed inherited legacy terminal decoding for Alt+symbol key combinations such as Alt+, and Alt+. (#6523 by @​ribelo).
  • Fixed the GitHub Copilot mai-code-1-flash-picker model to route through the /responses endpoint (#6544 by @​petrroll).
  • Fixed branch summaries to work with providers that use ambient authentication instead of API keys (#6595 by @​davidbrai).
  • Fixed inherited Amazon Bedrock errors to report unhandled provider stop reasons instead of only An unknown error occurred (#6598 by @​davidbrai).
  • Fixed npm package removal when installed packages have conflicting peer dependencies (#6604 by @​davidbrai).
  • Fixed inherited Azure OpenAI Responses reasoning replay when encrypted_content appears only in the terminal response event (#6608 by @​davidbrai).
  • Fixed inherited Anthropic-compatible proxies that omit usage from message_delta events (#6611 by @​davidbrai).
  • Fixed inherited OpenCode OpenAI Responses models to omit the unsupported session-id header while preserving other cache-affinity data (#6645 by @​davidbrai).
  • Fixed system prompt cache invalidation across dates by removing the current date from the default prompt (#6621).
Changelog

Sourced from @​earendil-works/pi-coding-agent's changelog.

[0.80.7] - 2026-07-14

Breaking Changes

  • Removed the openai-responses compat.sendSessionIdHeader flag from models.json. Session-affinity behavior is now controlled by compat.sessionAffinityFormat ("openai", "openai-nosession", or "openrouter"). Replace sendSessionIdHeader: false with sessionAffinityFormat: "openai-nosession" (#6496 by @​petrroll).

New Features

  • Cache-friendly dynamic tool loading - Extensions can add tools during execution while supported Anthropic and OpenAI Responses models preserve prompt-cache prefixes. See Dynamic Tool Loading.
  • Message copy shortcut - Ctrl+X copies the last assistant message in the transcript or the selected message in /tree, making older and branched messages directly copyable. See Display and Message Queue.
  • Fable 5 xhigh and max thinking - Native xhigh and max thinking levels are available across generated provider catalogs. See Model Options.

Added

  • Added cache-friendly dynamic tool loading for extension tools activated by tool results. Supported Anthropic and OpenAI Responses models load definitions where they become available, preserving the cached prompt prefix. See Dynamic Tool Loading (#6474).
  • Added inherited native xhigh and max thinking levels for Claude Fable 5 across all generated provider catalogs (#6490 by @​davidbrai).
  • Added Ctrl+X to copy the last assistant message, or the selected message in /tree.
  • Added inherited toolChoice support for OpenAI and Codex Responses, including required and named tool selection (#6588 by @​xl0).

Fixed

  • Fixed inherited OpenRouter model context windows to use the top provider's actual context length (#6481 by @​davidbrai).
  • Fixed inherited OpenRouter OpenAI-compatible session IDs to use the x-session-id header instead of OpenAI-specific session-affinity fields (#6496 by @​petrroll).
  • Fixed Ctrl+V to paste clipboard text when the pasteboard does not contain an image.
  • Fixed /login amazon-bedrock to prompt for and save a Bedrock API key instead of only displaying ambient AWS credential setup instructions.
  • Fixed inherited Amazon Bedrock ambient AWS credentials to keep using SigV4 authentication, including for custom model IDs (#6532 by @​ribelo).
  • Fixed inherited Cloudflare Workers AI and AI Gateway authentication to use ambient account and gateway IDs when stored credentials contain only an API key (#6292 by @​markphelps).
  • Fixed inherited legacy terminal decoding for Alt+symbol key combinations such as Alt+, and Alt+. (#6523 by @​ribelo).
  • Fixed the GitHub Copilot mai-code-1-flash-picker model to route through the /responses endpoint (#6544 by @​petrroll).
  • Fixed branch summaries to work with providers that use ambient authentication instead of API keys (#6595 by @​davidbrai).
  • Fixed inherited Amazon Bedrock errors to report unhandled provider stop reasons instead of only An unknown error occurred (#6598 by @​davidbrai).
  • Fixed npm package removal when installed packages have conflicting peer dependencies (#6604 by @​davidbrai).
  • Fixed inherited Azure OpenAI Responses reasoning replay when encrypted_content appears only in the terminal response event (#6608 by @​davidbrai).
  • Fixed inherited Anthropic-compatible proxies that omit usage from message_delta events (#6611 by @​davidbrai).
  • Fixed inherited OpenCode OpenAI Responses models to omit the unsupported session-id header while preserving other cache-affinity data (#6645 by @​davidbrai).
  • Fixed system prompt cache invalidation across dates by removing the current date from the default prompt (#6621).
Commits
  • 818d674 Release v0.80.7
  • 53a087f docs: audit unreleased changelogs
  • f4e9ca7 remove current date from system prompt
  • adfac43 fix(coding-agent): clarify login options
  • 961fa6c feat(ai): add Radius gateway support
  • b084d2f add legacy-peer-deps flag on pi uninstall when using npm (#6604)
  • 7303cba fix branch summary when using ambient auth (#6595)
  • 298665c fix(ai): support OpenRouter session affinity (#6496)
  • 4c18610 docs: audit unreleased changelogs
  • 3d8f743 feat(ai): support message-anchored tool loading (#6474)
  • Additional commits viewable in compare view

Updates pi-lens from 3.8.68 to 3.8.70

Release notes

Sourced from pi-lens's releases.

v3.8.70

Added

  • Review-graph symbols now carry an owner-qualified display name, and calls/references edges gain two more resolution tiers
  • lsp_diagnostics/lens_diagnostics sweeps now warm up the primary server once before the per-file loop starts, instead of the first few files eating cold-spawn-adjacent timeouts
  • Registry-independent backstop orphan sweep
  • Review-graph symbol-node IDs are now collision-safe
  • docs/ is now included in the published npm package
  • pi-lens can now measure its own total CPU/RAM footprint — host process, every live LSP child, and every transient analyzer spawn
  • Cross-process LSP budget — first prototype of #449 slice 2
  • lens_diagnostics mode=full breaks its confirmed/unconfirmed LSP-sweep tally down per primary server, and separates primary-vs-auxiliary findings
  • lens_diagnostics mode=full no longer renders a timed-out (or errored) per-file LSP check as false-clean
  • lsp_diagnostics directory-mode file cap raised from 50 to 100
  • lsp_diagnostics/lens_diagnostics can now render a genuinely confirmed "clean" for classic typescript-language-server, not just "unconfirmed"
  • lens_diagnostics mode=full runs gitleaks on any git repo, not only ones with an explicit gitleaks config
  • A genuine silentOnClean drift finding now files/updates a persistent tracking issue instead of only riding along in the routine docs-refresh PR
  • opengrep moved off the full-workspace LSP sweep onto a dedicated CLI extractor
  • lens_diagnostics mode=full now fetches the heavyweight project analyzers FRESH instead of reading a possibly-hours-stale cache
  • module_report flags middle-man / delegate-only classes
  • Retroactive changelog entry: runtimeInstall + canonical-bin discovery for gopls/csharp-ls/fsautocomplete (Go + .NET slice of #241)
  • Nightly compat-smoke now pins avtc-pi-subagent's env vocabulary too
  • Regression coverage for confusable-hyphen normalization in the read-guard's content comparison
  • Persistent bus-events.log for pilens:files:touched/pilens:diagnostics publish outcomes
  • MCP auto session_start is now visible and self-healing
  • read_symbol self-healing misses + doc-comment inclusion + duplicate-name disambiguation
  • Shared makeRunnerCtx() test helper for dispatch-runner tests
  • Auto-install lua-language-server via the archive-tree bundle machinery
  • lsp_diagnostics separates primary-server confirmation from auxiliary-scanner findings, plus a new serverScope param
  • lens_diagnostics mode=full/lsp_diagnostics no longer burns a full per-file wait on EVERY markdown file in a sweep
  • Test-runner support for PHPUnit and mix test (ExUnit)

Performance

  • Pinned jscpd bumped from 3.5.10 to 5.0.12
  • KnipClient.runAnalyze() now caches between runs
  • zizmor is no longer an LSP candidate for non-GitHub-Actions YAML files

Changed

  • Unify the directory-walk decision shared by the three source walkers
  • Adopt pi's dynamic tooling for situational ast-grep/lsp-navigation tools
  • Auxiliary-LSP profile lookup: shared blocking/semantic policy + memoized source lookup
  • dead-code-client.ts and knip-client.ts no longer each hand-roll their own copy of the "climb up looking for a project-root marker" loop
  • lsp_diagnostics' batch/directory scan now serializes touches within a single LSP server the same way lens_diagnostics mode=full has since #387

Fixed

  • nested-ternary/long-parameter-list/no-dupe-class-members had ZERO coverage in the ast-grep NAPI fallback runner on .ts files
  • ast-grep NAPI fallback runner no longer silently drops a rule's utils: block
  • ast-grep -js twin rules no longer double-fire on .ts files in the in-process NAPI runner

... (truncated)

Changelog

Sourced from pi-lens's changelog.

[3.8.70] - 2026-07-14

Added

  • Review-graph symbols now carry an owner-qualified display name, and calls/references edges gain two more resolution tiers (refs #655 — second, still narrowly-scoped slice; BehaviorFact extraction, SymbolMetadataVNext, and per-language behavior adapters remain untouched) — phase 1 (#659) fixed symbol-node ID collisions but deliberately left qualified ownership (ClassName.method) and call-edge resolution at just "exact"/"name-only". This slice adds both, reusing existing machinery rather than building parallel logic: (1) Qualified names: a new shared containment helper, clients/symbol-containment.ts's findOwnerName, implements the SAME strict-range-containment/smallest-span algorithm module-report.ts's outline nesting (nestEntries, #301) already uses, so a new ReviewGraphNode.qualifiedName field (e.g. UserService.run) is computed identically for tree-sitter-based languages (builder.ts's addTreeSitterFile, over the file's own deduped symbol list) and jsts (dispatch/facts/function-facts.ts's functionFactProvider, which now also collects class/interface ranges in the SAME already-parsed-tree walk and stamps each FunctionSummary.owner, since jsts graph nodes come from a different, lighter tree-sitter integration than module-report's own extractor — literally sharing one function call across the two wasn't possible, only the algorithm was factored out). module-report.ts's resolveUsedBy now renders node.qualifiedName ?? node.symbolName, so two same-file, same-named methods on different classes are distinguishable in usedBy/blastRadius output without cross-referencing line numbers — and, as a side benefit, its caller-dedup key (previously bare name) no longer risks conflating two different classes' same-named callers. Cross-tool consistency was a hard requirement: a qualified name rendered here is guaranteed to be a valid Class.method input to read_symbol's own resolver (resolveQualifiedMatch) because both derive from the same "smallest strictly-containing declaration" notion of ownership — verified by a new consistency test, not just asserted. (2) Two new resolution tiers, both computed only for jsts in this slice (the one ingestion path with import-specifier names and same-file type hints already cheaply available; other languages continue to fall back to "exact"/"name-only" — a deliberate, documented scope boundary, not an oversight): "import" narrows a bare-name callee to the specific in-project file its caller's own import { x } from "./service.js" names, via a new importHintFile edge-metadata hint threaded from addJsTsFile into resolveDeferredSymbolEdges, resolved when that ONE file has exactly one same-named symbol (falls through to the existing global-uniqueness "exact" check, then "name-only", when it doesn't uniquely narrow). "receiver-type" resolves a obj.method() call directly to a specific class's method when the receiver's type is determinable from the SAME function's tree-sitter parse — a const x = new ClassName() assignment or a typed parameter — via two new, narrowly-scoped function-facts.ts collectors (collectMemberCallSites, collectReceiverTypes) covering only the clearest common shapes (chained/computed/this.-receiver calls, cross-function flow, and generics are conservatively left as the pre-existing "external" classification, never guessed). Both tiers fail closed: an owner+name pair that's ITSELF ambiguous (e.g. two same-named methods sharing one qualified name) resolves to a dedicated qualified-name placeholder tagged "name-only" rather than picking one of the 2+ candidates, and a genuinely undeterminable receiver type keeps today's plain external classification with no resolution tag at all — never a wrong "exact"/"import"/"receiver-type" claim. Fixed as a necessary side effect (not scope creep): localImportToFile never stripped a .js/.jsx/.mjs/.cjs extension from an import specifier before trying sibling extensions, so the extremely common TS-as-ESM pattern this very codebase uses everywhere (import { x } from "./service.js" pointing at a real service.ts) silently failed to resolve to a real file — a latent gap in the existing file→file imports edge that the new "import" tier depends on directly. Investigated and confirmed UNAFFECTED: read_enclosing (clients/module-report.ts's readEnclosing) is purely positional (file + line, fresh tree-sitter extraction per call) and touches no symbol ID, resolution, or qualified-name machinery. New tests: tests/clients/review-graph/qualified-name-resolution.test.ts (qualified-name rendering for a same-file different-class collision, the read_symbol/module-report qualified-name-format consistency check, both new resolution tiers each with a positive resolving case and a case that correctly stays "name-only" rather than over-claiming); one pre-existing module-report.test.ts assertion updated from "exact" to "import" (a strictly more specific, and now correctly reported, tier for that scenario).

  • lsp_diagnostics/lens_diagnostics sweeps now warm up the primary server once before the per-file loop starts, instead of the first few files eating cold-spawn-adjacent timeouts (closes #667) — live dogfooding on a 100-file lsp_diagnostics sweep found the first 5 files touched all hit the exact 1000ms per-file timeout with serverCountReady:1, while every file from the 6th on was clean and fast (~450-500ms). serverCountReady:1 only proves the server process spawned and passed the LSP initialize handshake — it does NOT prove the server can usefully answer a diagnostics request yet; tsserver-style servers can still be loading/indexing the project internally for seconds after that, and neither sweep tool had any check for this before starting its per-file loop, so whichever files landed first paid that cost individually. New LSPService.ensureWarmForSweep (clients/lsp/index.ts) is the ONE shared fix both tools route through (they already share groupFilesByPrimaryServer/runPerServerGroups from #631): a real "has this server already answered a confirmed diagnostics touch this session" check (a new demonstratedReady key set, populated by touchFile only on a non-inconclusive diagnostics-mode result — strictly stronger than isAlive()/spawned/handshake-complete), not just a guessed delay. Cold → performs exactly one bounded warm-up touchFile round trip against one representative file from the group, with its own generous, one-time, env-tunable budget (PI_LENS_LSP_WARMUP_TIMEOUT_MS, default 20s) distinct from the per-file sweep budget — then the normal sweep proceeds from an already-demonstrated-ready server. Already-warm (from an earlier touch/sweep this session) → a no-op: no extra round trip, no added latency. Wired into runWorkspaceDiagnostics (the engine behind lens_diagnostics mode=full) per server group, ahead of the per-file pre-open/touch loop but AFTER the opt-in whole-group workspace/diagnostic pull fast path (which already gets its own generous per-server budget covering the whole group in one shot, so it doesn't need a separate warm-up); and into tools/lsp-diagnostics.ts's mapWithConcurrency (the shared batch/directory-scan primitive), called once per server group before its own per-file loop. Does NOT change the existing per-file wait budgets or confirmed/unconfirmed contract (#242/#611/#634) — purely a pre-loop addition. New tests: tests/clients/lsp/sweep-warmup.test.ts covers the pure decision logic directly against ensureWarmForSweep (a cold server performs exactly one warm-up round trip then is treated as warm; an already-warm server from a prior touchFile is a no-op) and integration-style coverage through runWorkspaceDiagnostics itself (a cold sweep pays exactly one extra warm-up round trip on top of its normal per-file touches; an already-warm sweep pays none) — guarding specifically against the warm-up regressing into a mandatory extra round trip on every sweep.

  • Registry-independent backstop orphan sweep (closes #658) — live dogfooding found 3 opengrep.exe/opengrep-core.exe process chains with confirmed-dead parents that survived every session_start sweep for ~2 days. Root cause: clients/instance-reaper.ts's existing sweepOrphans (#472) is entirely registry-driven — it only ever considers pids currently listed in some instance's lspChildren[], so once a child's registry reference is lost (a stale-heartbeat entry removal per #525's asymmetric design, or a killProcessTree call that failed silently), that child becomes permanently invisible to every future sweep; the reaper never asks "what's actually running on this machine." New sweepUntrackedOrphans runs as a strictly additive SECOND layer alongside the unchanged registry-driven sweep: it enumerates live OS processes by known pi-lens-managed binary name (MANAGED_BINARY_NAMES — ast-grep, opengrep, opengrep-core, marksman, zizmor, typos-lsp, yaml-language-server, typescript-language-server, drawn from clients/lsp/server.ts's spawn candidates) via one batched Get-CimInstance Win32_Process WQL query on Windows (reusing the same query pattern as the existing marker-search) or ps -eo pid=,ppid=,args= on POSIX, then applies a new pure decision function, decideBackstopOrphanReaping — a process is kill-eligible ONLY when it is NOT already tracked in any instance's lspChildren[] (deferred to the registry-driven reaper instead) AND its parent pid is confirmed dead via the existing identity-verified realIsPidAlive (never on an ambiguous/unresolvable parent pid, never on a live parent, never on binary name alone). Confirmed kills reuse the existing killPidTree tree-kill mechanism. Kill-attempt retry was considered per the issue's own framing: no new retry-tracking state was added — a silently-failed kill leaves the process untracked with a still-dead parent, so it stays classified as backstop-kill-eligible and the very next session_start sweep naturally retries it, with zero extra bookkeeping (documented in sweepUntrackedOrphans's doc comment; a future hardening making killPidTree return a success signal for sharper logging is a reasonable follow-up, not required for correctness). Wired into index.ts alongside the existing sweepOrphans()/registerInstance() call site — fire-and-forget, never blocks or throws into session_start. New tests in tests/clients/instance-reaper.test.ts (decideBackstopOrphanReaping) mirror the existing pure/impure split: an untracked process with a confirmed-dead parent is kill-eligible; a live parent, an already-tracked pid, an unverifiable (zero/negative/NaN) parent pid, and a malformed self-parenting row are all never kill-eligible.

  • Review-graph symbol-node IDs are now collision-safe (refs #655 — first, narrowly-scoped slice of a larger tracking issue; the rest — behavior facets, per-language adapters, SymbolMetadataVNext — is explicitly NOT part of this change) — clients/review-graph/builder.ts minted every symbol node's ID as ${file}:${name}, so an overloaded function/method, two same-named methods on different classes in the same file, or a same-named nested function all collapsed onto ONE graph node; pilens_module_report's usedBy/blastRadius sections (which read that node's incoming edges directly) could then silently merge or misattribute two genuinely different symbols' callers. Fix: a new shared helper, clients/review-graph/symbol-id.ts's buildSymbolId(file, name, kind, startLine), builds ${file}:${name}:${kind}:${startLine} — enough to give every one of those concrete collision cases a distinct ID, since they always sit on different lines. Deliberately scoped DOWN from #655's full proposed <file>:<qualified-name>:<kind>:<start-line>:<start-column> shape: no qualified ownership (e.g. ClassName.method — needs an owner-chain the extractors don't compute uniformly today, real work #655 leaves for later) and no start column (review-graph's JS/TS symbols come from a different extractor, dispatch/facts/function-facts.ts, than module-report's own outline extractor, tree-sitter-symbol-extractor.ts — the two agree on start line for every function-like declaration but can diverge by a few columns for arrow functions; line already resolves every in-scope collision case without needing column, and keeps IDs comparable across both extractors). Also fixed a related dormant bug the new ID shape surfaced: some grammars' symbol queries (e.g. python's) match one real declaration under two patterns — a class method also matches the generic top-level function_definition rule — yielding two Symbol records identical in name/line/column but differing only in kind; the old name-only ID silently collapsed these back into one node, so the new kind-qualified ID needed a same-position dedupe (dedupeSamePositionSymbols, preferring the more specific kind) to avoid manufacturing phantom duplicate graph nodes. clients/review-graph/types.ts's ReviewGraphEdge gains an optional resolution?: "exact" | "name-only" field (a narrow slice of #655's full call-edge-metadata proposal): a calls/references edge starts "name-only" (bare-name match, no scope/type info), and resolveDeferredSymbolEdges upgrades it to "exact" only when exactly one same-named real symbol exists graph-wide — otherwise it's left "name-only" so a consumer knows the target may be a name-collision guess. clients/module-report.ts's ModuleSymbolUsedBy surfaces that same resolution field, and its internal toEntry now builds its own graph-node lookup key via the same shared buildSymbolId helper (previously a separately-hand-assembled ${normalizedPath}:${sym.name} string) — with one language-specific wrinkle: for jsts, the lookup always uses kind "function" regardless of the outline's own finer-grained sym.kind ("method" etc.), because builder.ts's jsts graph nodes come from function-facts.ts, which has no method/function distinction. REVIEW_GRAPH_VERSION bumped v3v4 (same safe-rebuild mechanism as the v2→v3 #260 bump: a v3 snapshot's nodes/edges still use the old ID shape throughout, so loadPersistedGraph rejects it outright rather than merging it with newly-built v4 IDs). Architecturally, this is an IN-PLACE, versioned extension of the existing review graph — no parallel "v2 graph" — per #655's own stated decision to enrich one graph and expose projections over it rather than build a second production-code model; the existing REVIEW_GRAPH_VERSION/buildGeneration machinery already exists for exactly this kind of safe schema change. New tests: tests/clients/review-graph/symbol-id.test.ts (the old scheme's literal collision, the new scheme's disambiguation by kind+line, and an end-to-end same-file-different-class Python method case demonstrating two distinct graph nodes); tests/clients/review-graph.service.test.ts gains a v3-snapshot migration-safety test (flagged stale, blind-read rejected, a fresh build produces v4 IDs) and a resolution-confidence test (a globally-unique callee resolves "exact", an ambiguous same-named callee across two files stays "name-only"); tests/clients/module-report.test.ts gains an "exact"-resolution assertion on the existing cross-file-caller test, a jsts class-method graph-node-lookup regression test (guarding the "function" idKind mapping), and an ambiguous-same-name-across-files test asserting "name-only" is surfaced rather than a false "exact".

  • docs/ is now included in the published npm package (closes #651) — pi.dev rewrites GitHub repo links to npm-package-relative paths for its packages listing, so every docs/*.md link was a dead link there since docs/ was never in package.json's files array. Added "docs/" to files; only the 23 already git-tracked/public docs ship (a handful of untracked local scratch files like inspiration_*.md are gitignored and were never part of a real publish regardless). Package size grows ~200KB (3.0MB → 3.2MB packed) — negligible. Reported by @​eisterman.

  • pi-lens can now measure its own total CPU/RAM footprint — host process, every live LSP child, and every transient analyzer spawn (closes #620) — diagnosed during a 2026-07-13 dogfooding session where a lens_diagnostics mode=full sweep's per-file confirmation rate collapsed under real CPU contention from ~25 concurrent node.exe processes (other worktrees/sessions on the same box), a theory only confirmable after the fact via manual tasklist correlation — pi-lens had no first-class way to answer "how much CPU/RAM is pi-lens itself using right now." New clients/resource-sampler.ts wraps pidusage (chosen over hand-rolling /proc vs Windows Get-CimInstance/perf-counters — each OS exposes process CPU/RSS differently, and pidusage already abstracts that; it's a small pure-JS package with one transitive dep, safe-buffer, so it bundles like the repo's other pure-JS runtime deps rather than needing an EXTERNAL entry in scripts/bundle-dist.mjs) with two consumers: (1) long-lived processesclients/instance-registry.ts's InstanceEntry/LspChildEntry (#449) gain cpuPercent/rssBytes fields, sampled at the existing quiet-window heartbeat cadence (clients/quiet-window.ts's buildHeartbeatResourcePatch, bounded to 2s via Promise.race so a slow sample can never block the idle-window task — the per-turn-end heartbeat stays RSS-only, deliberately, since that's a much hotter path and CPU sampling there would make the measurement itself new per-turn overhead); (2) transient analyzer children (jscpd, knip, madge, gitleaks, govulncheck, trivy, opengrep, zizmor, …) — every safeSpawnAsync invocation (clients/safe-spawn.ts) is now bracketed by startSpawnUsageSampler, a 750ms poll started right after spawn() and stopped in the existing child.on("close"/"error", ...) handlers, recording peak/average CPU%+RSS into a new spawn_resource_usage phase entry in the existing latency.log (alongside the timing data already logged there) and attaching a resourceUsage field to the resolved SpawnResult. Windows-specific gotcha handled: safe-spawn.ts spawns with shell: true on Windows, so the sampled pid is cmd.exe's wrapper, not the real tool's — findDescendantPidsWindows resolves the live descendant tree via one CIM query per poll tick (pure BFS split out as walkDescendantPids for testability) so a node/npx-wrapped tool is actually captured instead of reporting cmd.exe's near-zero usage. Net query surface: clients/instance-registry.ts's new computeResourceFootprint(pure)/getResourceFootprint aggregate every registered instance's host + LSP children into total RSS/CPU/child-count across every pi-lens process on the machine, re-exported through the clients/lens-engine.ts seam and surfaced in pilens_health's existing text/JSON output (a new "Resource footprint: N pi-lens instance(s) · XMB RSS · Y% CPU · Z LSP child process(es)" line, best-effort — a footprint read failure never breaks the rest of the tool). Every sampling path is best-effort end to end (a sampling failure loses a data point, never throws into the heartbeat/spawn/turn_end path it's attached to) per this repo's existing instrumentation-must-never-fail-the-operation-it-measures convention. Deliberately out of scope (tracked separately in #650): cross-process LSP server sharing/deduplication — this issue is purely about MEASURING footprint, not reducing it. New tests: tests/clients/resource-sampler.test.ts (pure UsageAccumulator peak/average math, pure walkDescendantPids BFS including a cycle-safety guard, sampleProcesses batching/absent-pid semantics, startSpawnUsageSampler's tick/stop lifecycle — all against a mocked pidusage, no real process tables); tests/clients/instance-registry.test.ts gains coverage for updateHeartbeat's new cpuPercent/childUsage patch fields (including "untouched, never zeroed" semantics for an unsampled tick) and computeResourceFootprint/getResourceFootprint; tests/clients/safe-spawn-resource-usage.test.ts covers the safe-spawn wiring (sampler start/stop timing, resourceUsage attachment, the spawn_resource_usage log entry, and that a throwing sampler never breaks the underlying spawn) against a mocked resource-sampler.js/latency-logger.js, driving a real tiny node -e child process end to end.

  • Cross-process LSP budget — first prototype of #449 slice 2 (refs #449) — every concurrent pi-lens process (main session + subagents + concurrent worktrees) has always spawned its own independent LSP fleet with no awareness of any other instance's load; #449 slice 1 (#474/#475) made instances mutually visible via ~/.pi-lens/instances.json but changed no behavior. This is the first slice that acts on that visibility: a new clients/lsp-budget.ts sums live LSP server counts (lspChildren.length) across every registry entry whose owning pid is still alive (reusing instance-reaper.ts's existing realIsPidAlive liveness check — now exported — rather than a second one) and compares against a configurable ceiling, default 16 (DEFAULT_LSP_BUDGET_CEILING, PI_LENS_LSP_BUDGET_CEILING override) — a rough RAM-budget estimate (~250MB average per LSP child × ~4GB target machine-wide budget), not yet a measured figure (#620's CPU/RSS sampling hadn't landed as of this prototype). When the machine is at or over the ceiling, the NEW session (never an already-running one) degrades its own spawn plan for the rest of that session: it skips spawning auxiliary LSP servers (role:"auxiliary" in clients/lsp/server.ts — opengrep/ast-grep/zizmor/typos/marksman) and keeps only the primary language server per file, wired via clients/dispatch/auxiliary-lsp.ts's enabledAuxiliaryLspServerIds. This is deliberately a "position limit, not a clearinghouse" (the issue's own framing): the check (checkCrossProcessLspBudget) fires fire-and-forget from session_start alongside the existing registerInstance/sweepOrphans calls, reads the registry once, decides locally, and never blocks session start or touches another instance's live servers. Feature-flagged: PI_LENS_CROSS_PROCESS_BUDGET=0 disables the whole check (today's behavior — always spawn the full fleet). Explicitly NOT implemented in this first cut (documented follow-up): the issue's other suggested degrade mechanism (shortening this session's own idle-reaper timeout) and slice 3 (same-workspace warm attach via the MCP IPC channel) — both remain open. This is a first prototype per the issue's own "gated on registry dogfooding" framing; the ceiling number and the choice of degrade mechanism may both need tuning once real-world multi-agent data (#620) is available. New tests: tests/clients/lsp-budget.test.ts (pure decideLspBudget decision logic against fake registry data — under/at/over ceiling, dead-parent instances excluded from the live count, env-config parsing with NaN guards, module-scope cache defaults).

  • lens_diagnostics mode=full breaks its confirmed/unconfirmed LSP-sweep tally down per primary server, and separates primary-vs-auxiliary findings (closes #646) — tools/lsp-diagnostics.ts already split every file's result into "primary confirmation" (the real language server, e.g. typescript/pyright) vs "auxiliary findings" (cross-cutting scanners attached via clientScope: "all" — ast-grep, opengrep, zizmor, typos, marksman, ...) via a local primaryServerId(filePath) helper, but lens-diagnostics.ts's formatFullMode had no equivalent: its confirmedLspResults/unconfirmedLspResults tally (#630/#634) was one flat aggregate with no per-server breakdown. Concretely painful during dogfooding: a real sweep came back 34/155 files unconfirmed, and diagnosing WHICH server was responsible required manually grepping latency.log for file extensions instead of the tool just reporting it — it turned out to be 100% one push-only server (marksman). Fix: primaryServerId moved out of tools/lsp-diagnostics.ts into clients/lsp/config.ts (alongside getServersForFileWithConfig, which it already depended on) so both tools share the exact same primary/auxiliary classification instead of lens-diagnostics.ts growing a second hand-copied version — lsp-diagnostics.ts now imports the shared helper with no behavior change. formatFullMode gains tallyLspByPrimaryServer (groups the existing confirmed/unconfirmed partition by each file's primary server id) and tallyLspPrimaryVsAuxiliary (splits the raw per-file diagnostics into primary vs auxiliary counts, the same separation lsp_diagnostics already applies to its own findings rendering) — both computed from the raw LSP-sweep results, so neither disturbs the existing confirmed/unconfirmed merge into widget-state summaries or any #634 false-clean-prevention semantics. The rendered note now reads e.g. "⚠ LSP sweep: 121 file(s) confirmed via LSP, 34 unconfirmed (...) — by server: marksman: 0/34, typescript: 121/121 — NOT the same as 0 diagnostics for: ..." (breakdown clause only rendered when more than one server is involved) plus a new "LSP sweep findings: N primary (language server), M auxiliary (ast-grep/opengrep/zizmor/typos/marksman/...)" line; details gains lspServerBreakdown (always present, per-server {confirmed, total}), lspPrimaryDiagnosticsCount, and lspAuxiliaryDiagnosticsCount so a caller can check this programmatically. New tests: tests/clients/lsp/primary-server-id.test.ts (the shared helper matches the old inline lsp-diagnostics.ts implementation exactly across a plain source file, a markdown/marksman file, an unmatched extension, and an auxiliary-only case); tests/tools/lens-diagnostics.test.ts gains coverage for the per-server breakdown grouping correctly across two different primary servers (mixed confirmed/unconfirmed), the breakdown clause being omitted for a single-server sweep, and the primary/auxiliary findings split.

  • lens_diagnostics mode=full no longer renders a timed-out (or errored) per-file LSP check as false-clean (closes #630) — formatFullMode's (tools/lens-diagnostics.ts) footer-cache reconciliation already excluded timedOut/error results (#571: diagnostics is a default-EMPTY placeholder for these, not a confirmed clean — see LSPWorkspaceDiagnosticResult's doc comment in clients/lsp/index.ts), but the merge feeding the actually-rendered summary was NOT filtered the same way: the unfiltered lspResults went straight into mergeDiagnosticsWithWidgetSummaries, so a timed-out file's placeholder [] merged in and read to the agent as "0 diagnostics" — indistinguishable from a genuinely clean file. This is the exact #533/#570 false-negative class (tools/lsp-diagnostics.ts's confirmation: "clean"|"unconfirmed" machinery already protects that tool against it) that mode=full's merge path never got. Fix: lspResults is now partitioned once into confirmedLspResults/unconfirmedLspResults, both the footer write and the merge now consume only confirmedLspResults (a file already fed the footer-write filter is now also fed the render/details filter from the SAME partition, rather than two independently-maintained filters), and an unconfirmed file can still legitimately show findings from widgetSummaries/project-runner state if those independently have entries for it — only its LSP-sweep contribution is withheld. The rendered output gains a new note (mirroring the spirit, not the literal function, of lsp-diagnostics.ts's unconfirmedReasonClause/tallyConfirmation — the two tools' output shapes already differ): "⚠ LSP sweep: N file(s) confirmed via LSP, M unconfirmed (...): <paths>. NOT the same as 0 diagnostics for these files", distinguishing a timeout from a hard error same as #570 does upstream, composed alongside the existing coldNote/abortedNote/freshNote/missingNote in both the aborted and non-aborted return branches. details gains lspFilesConfirmed, lspFilesUnconfirmed, and unconfirmedLspFiles (always present, even when zero, matching the existing coldRunners-always-in-details convention) so a caller can check this programmatically without re-parsing the text. Deliberately NOT touched: the #611 tsserver-sync escape hatch (that's lsp_diagnostics-specific single/batch-check machinery; adding a second per-file round trip to a project-wide sweep here would reintroduce the extra-round-trip problem #629 is fixing on the other tool) — this fix only reclassifies/reports the EXISTING timedOut signal runWorkspaceDiagnostics already produces, no new LSP calls. New tests in tests/tools/lens-diagnostics.test.ts: a mixed confirmed-clean/confirmed-with-diagnostics/timed-out sweep result where the timed-out file is asserted to be listed as unconfirmed (not clean, not silently dropped) while the footer-write exclusion (#571) is confirmed unaffected; an errored (not timed-out) result distinguishing the note's wording; and an all-confirmed sweep confirming no unconfirmed note/zeroed details fields appear when there's nothing to report.

  • lsp_diagnostics directory-mode file cap raised from 50 to 100, matching the explicit paths batch cap (MAX_BATCH_FILES) — tools/lsp-diagnostics.ts's MAX_FILES constant now reads 100. There was no longer a reason for the two caps to diverge: dogfooding confirmed the tool's bounded-concurrency worker pool (default 8) stays fast and timeout-free at 100 files on a real ~150-file project, so directory mode was capping well below what the underlying mechanism can already handle cleanly.

  • lsp_diagnostics/lens_diagnostics can now render a genuinely confirmed "clean" for classic typescript-language-server, not just "unconfirmed" (refs #611 — read-only-diagnostics scope; the per-edit dispatch consumer is a separate follow-up, see below) — classic typescript-language-server is silentOnClean: true (clients/lsp/server-strategies.ts): on a clean file it publishes nothing at all, not even an empty confirmation, so per #533/#570 pi-lens's honest response was to render ANY empty result from it as "unconfirmed" — a single-file lsp_diagnostics <clean-file.ts> call could never say "clean," no matter how long you waited. tools/lsp-diagnostics.ts's classifyEmptyResult path now attempts one more thing before giving up: when classifyCascadeWaitTier (clients/lsp/cascade-tier.ts) says the primary server is "tier3-silent" (push-only + silentOnClean + NOT native-ts7, which already publishes on clean per #558 and never reaches this branch), it calls typescript-language-server's typescript.tsserverRequest escape hatch via the existing #237-hardened LSPService.executeCommand (allowlisted by advertisement) with semanticDiagnosticsSync/syntacticDiagnosticsSync — genuine synchronous tsserver request/response commands, not push/timing-dependent. An empty response body is now a confirmed "clean"; a non-empty body surfaces real diagnostics tsserver had already computed but never published, merged into the result rather than discarded. Verified live against the actual installed typescript-language-server/typescript@5.9.3 (this repo's own tsconfig.json as the fixture project, plus a deliberately broken scratch file): the response envelope is {executed:true, result:{seq,type:"response",command,request_seq,success,body:[...]}}, where each body entry is tsserver's NATIVE protocol diagnostic shape (message, category "error"/"warning"/"suggestion", code, startLocation/endLocation as 1-based {line,offset}) — NOT the LSP Diagnostic shape, so a new converter (tsserverSyncDiagnosticToLsp) maps it to pi-lens's 0-based LSPDiagnostic. Also verified live: a file the client never opened (outside any tsconfig project) makes executeCommand reject with a tsserver ResponseError ("No Project.") rather than a success:false response — every failure mode (command not advertised, executeCommand throwing or timing out, a malformed response shape) falls back to exactly today's "unconfirmed" behavior, fail-safe and non-throwing. New tests in tests/tools/lsp-diagnostics.test.ts ([#611](https://github.com/apmantza/pi-lens/issues/611) tsserver sync escape hatch) cover confirmed-clean via the sync path, real diagnostics surfaced via the sync path (with the 1-based→0-based location conversion asserted), fallback-to-unconfirmed on a rejected executeCommand call, fallback when the command isn't advertised, fallback when the service exposes neither method at all, and that a "waits"-tier server (covering native-ts7) never even attempts the sync path. The higher-stakes per-edit dispatch consumer (clients/dispatch/runners/lsp.ts/clientWaitForDiagnostics in clients/lsp/client.ts) is explicitly NOT touched by this change — it runs on every edit and #611 calls for its own dedicated latency verification (semanticDiagnosticsSync blocks on tsserver's real analysis queue, so a backlogged server could see no speed win, only a correctness one) before it's worth attempting there.

  • lens_diagnostics mode=full runs gitleaks on any git repo, not only ones with an explicit gitleaks config (#608, dogfooding finding) — session_start and per-edit dispatch keep #130's strict opt-in gate (GitleaksClient.hasGitleaksSignal: a .gitleaks.toml/.gitleaksignore/package.json reference/pre-commit hook) unchanged, since that issue explicitly weighed and rejected looser tiers for the routine/low-noise path. But mode=full is an explicitly-requested comprehensive review, and #130's own writeup considered — but didn't ship — a "smart-default" tier: fire on any tracked git repo, since gitleaks is cheap (~10MB binary, no external DB pull, unlike trivy's 30-200MB vuln-DB download which genuinely needs consent) and its findings are advisory-only. New GitleaksClient.hasGitRepo/hasGitRepo() (clients/gitleaks-client.ts) checks for a .git entry (file or directory, so both a normal clone and a worktree's gitdir-pointer file count); GitleaksClient.scan() gains an optional { requireSignal: false } to skip the strict gate when the c...

    Description has been truncated

Bumps the runtime-node-dependencies group in /src/cyclo/vendor_gateway/runtime_context with 2 updates: [@earendil-works/pi-coding-agent](https://github.com/earendil-works/pi/tree/HEAD/packages/coding-agent) and [pi-lens](https://github.com/apmantza/pi-lens).


Updates `@earendil-works/pi-coding-agent` from 0.80.6 to 0.80.7
- [Release notes](https://github.com/earendil-works/pi/releases)
- [Changelog](https://github.com/earendil-works/pi/blob/main/packages/coding-agent/CHANGELOG.md)
- [Commits](https://github.com/earendil-works/pi/commits/v0.80.7/packages/coding-agent)

Updates `pi-lens` from 3.8.68 to 3.8.70
- [Release notes](https://github.com/apmantza/pi-lens/releases)
- [Changelog](https://github.com/apmantza/pi-lens/blob/master/CHANGELOG.md)
- [Commits](apmantza/pi-lens@v3.8.68...v3.8.70)

---
updated-dependencies:
- dependency-name: "@earendil-works/pi-coding-agent"
  dependency-version: 0.80.7
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: runtime-node-dependencies
- dependency-name: pi-lens
  dependency-version: 3.8.70
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: runtime-node-dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>
@dependabot dependabot Bot added dependencies Pull requests that update a dependency file javascript Pull requests that update javascript code labels Jul 15, 2026
@glguida glguida closed this Jul 16, 2026
@dependabot @github

dependabot Bot commented on behalf of github Jul 16, 2026

Copy link
Copy Markdown
Author

This pull request was built based on a group rule. Closing it will not ignore any of these versions in future pull requests.

To ignore these dependencies, configure ignore rules in dependabot.yml

@dependabot
dependabot Bot deleted the dependabot/npm_and_yarn/src/cyclo/vendor_gateway/runtime_context/runtime-node-dependencies-23ffe9c6f1 branch July 16, 2026 00:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dependencies Pull requests that update a dependency file javascript Pull requests that update javascript code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant