Commit Graph

11306 Commits

Author SHA1 Message Date
can1357 4bad9b481d Merge PR #6973: fix(coding-agent): share parent local:// root with /tan clone (@roboomp) 2026-07-29 23:08:44 +02:00
roboomp bbf3d78c7e fix(coding-agent): keyed tan local root on session-manager id
Snapshot this.ctx.sessionManager.getSessionId() for the tan clone's local://
mapping instead of session.sessionId. The two diverge after /fresh or a
provider session override, and the Windows short-root fallback keys
%TEMP%/omp-local/<id> off the session-manager id used by the parent's
large-paste writes and '/data/workspaces/can1357__oh-my-pi__6971/.omp-session/2026-07-29T06-08-45-283Z_019fac7d-5ee3-7000-a7aa-16fe9394fdc9/local' reads, so the mismatched id left attachments
unreachable.

Diverge the mocked session id from the manager id in the regression test so
it pins the session-manager id.

Fixes #6971

(cherry picked from commit 1efcd22326d76fdb8b50c0977a836c892e80ab76)
2026-07-29 23:08:44 +02:00
roboomp dd4985f31e fix(coding-agent): scoped subagent local root overrides
Keep subagent localProtocolOptions on their ToolSession instead of installing
them as the process-global LocalProtocolHandler override. No-context URL
consumers therefore retain the active top-level session's mapping while tan
and task subagents continue to resolve through their caller context.

Add SDK regression coverage proving subagent creation preserves an existing
global mapping.

Fixes #6971

(cherry picked from commit a02eef174b03036dc960c842a0901d22333ad9cd)
2026-07-29 23:08:44 +02:00
roboomp fb4393ae16 fix(coding-agent): snapshotted tan parent local root
Capture the parent artifacts directory and session ID when /tan dispatches
instead of resolving them through the mutable interactive SessionManager.
This keeps background tan '/data/workspaces/can1357__oh-my-pi__6971/.omp-session/2026-07-29T06-08-45-283Z_019fac7d-5ee3-7000-a7aa-16fe9394fdc9/local' reads pinned to the dispatching transcript
after the user switches or resumes another session.

Extend the regression test to switch the mocked interactive session before
the background job starts and assert the original local mapping is retained.

Fixes #6971

(cherry picked from commit e05db428eabd5087e4b2b4a462f47927c0628e72)
2026-07-29 23:08:43 +02:00
roboomp d933cfbe05 fix(coding-agent): shared parent local root with tan clone
TanCommandController.start nests the tan clone at
<parent-artifacts>/Tan-<id>.jsonl, so the clone's session manager derived
its own artifacts dir and hence local root <parent-artifacts>/Tan-<id>/local.
Its sdk.createAgentSession call omitted localProtocolOptions, unlike the
task-subagent path which inherits the parent's mapping, so parent-session
'/data/workspaces/can1357__oh-my-pi__6971/.omp-session/2026-07-29T06-08-45-283Z_019fac7d-5ee3-7000-a7aa-16fe9394fdc9/local' attachments (pasted files, generated references) were unreadable.

Thread the parent session manager's localProtocolOptions into the tan clone
so local:// resolves against <parent-artifacts>/local.

Fixes #6971

(cherry picked from commit 1ded46e182fc24f9f57d8e9a907aaad58f790783)
2026-07-29 23:08:43 +02:00
can1357 756e872f64 Merge PR #6946: fix(tui): nest usage metrics in grouped reads (@joshrzemien) 2026-07-29 23:08:42 +02:00
joshrzemien daf1557b3d fix(tui): seal mixed read groups before usage
(cherry picked from commit 576b950b80583d8fd028edd08967b537f4eb18f0)
2026-07-29 23:08:42 +02:00
joshrzemien 4b753597fd docs(coding-agent): add grouped read changelog
(cherry picked from commit f23d576925906e6a39bfab44d421a52494a8f20b)
2026-07-29 23:08:42 +02:00
joshrzemien 57cb290fef fix(tui): preserve grouped read request order
(cherry picked from commit eb6767e3248ad0fe3ea371e5226a4af6e0b8f97b)
2026-07-29 23:08:42 +02:00
joshrzemien a3e90b3d95 fix(tui): nest usage metrics in read groups
(cherry picked from commit 101268adc632e80bb3f8304b95497ac7bd884131)
2026-07-29 23:08:41 +02:00
can1357 c6db470db5 test(coding-agent): cover drifted ACP write snapshot
(cherry picked from commit a8ef3465929e0ebdc026e0b6f94ea65d491946c8)
2026-07-29 23:08:39 +02:00
can1357 4cc259f6cf Merge PR #6934: fix(hashline,coding-agent): key snapshot tag on actually-persisted content after ACP bridge writes (@marton78) 2026-07-29 23:08:39 +02:00
Márton Danóczy 5c0b52a141 test(coding-agent): use declared AgentToolResult type in ACP bridge test
Replaces `Awaited<ReturnType<typeof executeHashlineSingle>>` with the
function's declared `AgentToolResult<EditToolDetails, typeof
hashlineEditParamsSchema>` return type. AGENTS.md bans ReturnType<>.

Review: https://github.com/can1357/oh-my-pi/pull/6934
(cherry picked from commit 59dbc5b79f8857bab67559656eae96cf7dfb6ac0)
2026-07-29 23:08:39 +02:00
can1357 d2283dd301 fix(model-registry): isolate modifier record mutations
(cherry picked from commit 3941103443576a6c8ab91a52e7da4ba1d8521d69)
2026-07-29 23:08:38 +02:00
Márton Danóczy a5d01deb85 test(coding-agent): hoist hashline import to module scope in ACP bridge test
Replaces three inline `await import("@oh-my-pi/hashline")` calls with a
single top-level `computeFileHash` import. AGENTS.md forbids dynamic
imports.

Review: https://github.com/can1357/oh-my-pi/pull/6934
(cherry picked from commit 9ffda46c94de0146a8e77ec816640918a565a0ea)
2026-07-29 23:08:38 +02:00
can1357 75b77c08b5 Merge PR #6930: fix(model-registry): preserve oauth.modifyModels projection across reloads (@abhishekbiyala) 2026-07-29 23:08:38 +02:00
Márton Danóczy 7708f372b5 fix(hashline,coding-agent): key snapshot tag on actually-persisted content after ACP bridge writes
Root cause of the reported "edit tool silently reformats the whole
file" corruption: fs/write_text_file has no verbatim guarantee. When
an ACP client (e.g. Zed with format_on_save: on) reformats a buffer
on save, routeWriteThroughBridge reported the pre-write content as
successfully written, and Patcher.commit keyed the returned snapshot
tag on that same pre-write text instead of what actually landed on
disk. The next edit anchored on that tag then resolved hunks against
a baseline the file had already drifted away from, which is what
produced whole-file "corruption" from single-line hunks -- reproduced
live in this session against real Swift/JSON/TypeScript files with
Zed as the ACP client.

- routeWriteThroughBridge reads the file back after the bridge write
  and returns the verified content plus a drift flag (best-effort:
  ACP defines no ordering between the client acking the write and its
  own async format-on-save settling, so this degrades gracefully to
  the old stale-tag-on-next-read failure mode, never to corruption).
- HashlineFilesystem.writeText propagates that verified content in
  view-space (the same space readText returns -- e.g. a notebook's
  editable cell text, not its raw JSON), not storage-space, so tag
  validation on the next edit compares like with like.
- Patcher.commit keys fileHash/header/snapshot on the verified
  post-write content (normalized, so BOM/line-ending restoration never
  produces a false "drift") when it diverges from what was sent, and
  appends a warning naming the drift -- but deliberately leaves the
  returned `after` (and therefore the model-visible diff) scoped to
  the intended hunk. Diffing against the full drifted file would
  balloon the tool response to span every reformatted line (measured
  ~6.8x inflation on a 245-line file with one touched line); the
  warning is the correct O(1) channel for "your editor reformatted
  this," not an O(file-size) diff.
- write.ts keys its own snapshot header on the verified bridge content
  too (no diff-size concern there since write always replaces the
  whole file).

Caught via code review (dispatched against the first pass of this
fix): a naive "just use the verified content everywhere" fix broke
.ipynb editing outright (write-space vs read-space content mismatch,
tag invalid on every notebook edit) and would have inflated every
drifted edit response by ~6.8x. Both are now covered by regression
tests that fail against the pre-fix code and pass against this one.

(cherry picked from commit 35ab80e43be5800b2f48728e4400eb9fd7f7f7d2)
2026-07-29 23:08:38 +02:00
Abhishek Sharma c7a113c9cb refactor(model-registry): derive projected catalog from an unprojected snapshot
The previous commits patched each rebuild path individually to avoid feeding a
modifyModels hook its own output. That left the invariant implicit and the
provider-scoped path applying only a subset of hooks, which is wrong for a hook
that inspects or suppresses another provider's models.

Keep #unprojectedModels as the canonical pre-projection catalog and derive
#models from it at every mutation point, so projections are always a pure
function of the unprojected base:

- #composeUnprojectedStaticModels builds the catalog; #composeStaticModels
  projects it. A scoped lookup with modifiers registered composes and projects
  the whole catalog before narrowing, matching getAll() followed by a filter.
  Providers without modifiers keep the cheap filtered path.
- Discovery completion, registerProvider, and runtime transport overrides
  update the unprojected snapshot and reproject, instead of mutating an
  already-projected array.
- Runtime metadata patches apply to the unprojected model, then reproject, so
  a later registration cannot discard them.
- Provider lookup snapshots are invalidated wherever the projection changes.

Hooks no longer take a providerFilter: a modifier is a whole-catalog transform
and every rebuild now runs the full ordered set exactly once.

(cherry picked from commit e5d2e9eac7c371cc196e9b362f77d3a5d7bdf507)
2026-07-29 23:08:37 +02:00
Abhishek Sharma e73ab518a0 fix(model-registry): scope registration-time projection to the new provider
registerProvider composed nextModels from the already-projected #models,
stripping only the incoming provider, then reran every stored modifier over
it. Loaders drain registrations one at a time, so the previously registered
provider's projection was fed back into its own hook — an append-style hook
compounded on each subsequent registration.

Apply only the incoming provider's hook. Every other provider's projection is
already present exactly once, and full rebuilds still go through
#composeStaticModels.

(cherry picked from commit b16db642b08cc223b062c0c556f00d46fda2520a)
2026-07-29 23:08:37 +02:00
Abhishek Sharma 88c8c13b6a fix(model-registry): log projection failures and rebuild unprojected before rerunning hooks
Review follow-up on two defects in the original change:

- The throwing-hook fallback wrote to #lastDiscoveryWarnings, which is only
  ever read to dedup a logger.warn inside #warnProviderDiscoveryFailure. No
  log line was emitted, so a broken extension degraded invisibly, and the
  shared key could mask a later discovery failure for the same provider. Log
  via logger.warn with its own dedup map.

- #refreshRuntimeDiscoveries starts from the already-projected #models, and
  the overlay merge only replaces matching provider+id pairs, so a hook's
  projection-only entries survived and were fed back into it. An append-style
  hook duplicated its output on every refresh. Drop each modifier provider
  before the merge so it re-seeds from the unprojected overlays.

(cherry picked from commit b6f841e080d4882a08b8d713de009461b6acc6fe)
2026-07-29 23:08:37 +02:00
Abhishek Sharma a8c2feb6b1 docs(coding-agent): note extension provider model projection fix in changelog
(cherry picked from commit d82747b036515d3e6d9182ddccb519c59b766e94)
2026-07-29 23:08:37 +02:00
Abhishek Sharma d10906c9a8 fix(model-registry): preserve oauth.modifyModels projection across reloads
`registerProvider` applies `oauth.modifyModels` once and assigns the result
straight to `#models`, but only the pre-projection definitions are persisted
in `#runtimeModelOverlays`. Any subsequent static reload rebuilds `#models`
from those overlays and silently drops the projection.

The model selector reloads on every open (`refresh("offline")`), so an
extension provider that projects a credential-aware catalog shows its
correct models everywhere except the picker — the one place users look.
`refreshProvider()` and online discovery completion had the same hole.

Persist the hook per provider and re-apply it wherever `#models` is
recomposed, honouring the `providerFilter` used by scoped lookups. A hook
that throws now degrades to that provider's unprojected catalog instead of
failing the whole composition, so one broken extension cannot empty the
registry.

(cherry picked from commit 33b7c72f225b4253b68bb71ecb3a9186151b18b3)
2026-07-29 23:08:37 +02:00
can1357 7d29a65b1c Merge PR #6923: fix(coding-agent): sync WezTerm theme changes on macOS (@Sairen777) 2026-07-29 23:08:35 +02:00
can1357 d5457eba24 fix(session): reset announced mounts after changed reload
(cherry picked from commit f7ec56c1c8b73476322904666d560492a6027ef7)
2026-07-29 23:08:34 +02:00
Alex Jaden 070ff41f4c fix(coding-agent): sync WezTerm theme changes on macOS
(cherry picked from commit fa70be267daa6f98cf18e2f257041f4e6e68a61d)
2026-07-29 23:08:34 +02:00
can1357 a73cd40c8f Merge PR #6922: fix(session): gate xd:// mount notices against announced history (@roboomp) 2026-07-29 23:08:33 +02:00
roboomp 359dfb5b8f fix(session): keep pending xd mount delta on transcript reset
The previous reset dropped #pendingXdevMountDelta alongside the announced
baseline. Unlike /new and different-session switchSession, branch() does
not rebuild the base system prompt afterward, and because the device is
already in mountedNames no later refresh re-queues an add delta. Dropping
the undelivered delta therefore left the branched transcript unaware of a
still-mounted discoverable device.

Only the announced baseline is reset now; pending adds (still-live mounts
awaiting delivery) survive and announce on the next prompt in the new
transcript. Redundant on /new (the rebuilt prompt lists them too) but
harmless, and correct for branch.

Fixes #6921

(cherry picked from commit 5866440f27c15a320657e25fbfa0d2d65aad1fa2)
2026-07-29 23:08:33 +02:00
roboomp 13b1077d3e fix(session): reset announced xd mounts on transcript replace
The announced-mount baseline persisted across /new, switchSession, and
branch, which replace agent.state.messages but only clear session-scoped
tool state. A device announced in the old transcript stayed in the cache,
so reconnecting it into the fresh history was filtered as already known
and never announced, leaving the new conversation unaware of the device.

Reset the announced baseline (and any undelivered pending delta) from
#clearSessionScopedToolState, so the next notice re-seeds from the new
transcript and a reconnecting device announces again.

Fixes #6921

(cherry picked from commit d06dde02b9de4aacacd7aea5ee51edc7e524e3fb)
2026-07-29 23:08:32 +02:00
roboomp 82dc0d43ae fix(session): migrated legacy xd mount notices on resume
Replayed the stable added and removed inventory sections from legacy
xdev-mount-notice content when structured details are absent. This keeps
the first post-upgrade resume from re-announcing devices that persisted
history already introduced.

Covered both structured and legacy resume histories, including removed
devices and inline docs that must not be interpreted as inventory.

Fixes #6921

(cherry picked from commit 634a4c2de75f99e219f408c56bed83c04fe1290a)
2026-07-29 23:08:32 +02:00
roboomp ac67548bc1 fix(session): gated xd:// mount notices against announced history
Mount-notice injection diff-gated only against the in-memory mountedNames
set, which is reseeded on every process resume / host reconnect. Dynamic
devices (MCP / RPC host) already announced in persisted history therefore
re-announced, splicing a redundant developer message that busts the
provider prompt-cache prefix and re-bills the whole suffix at full price
on metered providers.

Notices now persist a structured { added, removed } payload. On the first
consumption after resume the announced-device baseline is reconstructed
from history, and only a net change relative to what the model already
knows is announced, so a resume re-establishing the same inventory emits
nothing.

Fixes #6921

(cherry picked from commit 03c2ed5189510f41431bd164fa80187a69ed8de9)
2026-07-29 23:08:32 +02:00
can1357 84af4d3f3c Merge PR #6912: fix(coding-agent): surface MCP resource templates in resource summary (@roboomp) 2026-07-29 23:08:29 +02:00
roboomp c88c59db84 fix(coding-agent): surfaced MCP resource templates in resource summary
formatAvailableResources only listed concrete resources, so the
assistant-facing summary shown on a failed mcp:// read understated the
server's contract even though template routing and /mcp resources
already handle them. Now templates are listed alongside concrete
resources.

Fixes #6911

(cherry picked from commit 254f35bb04cda8a615bbe1291d73b13cac0eabaa)
2026-07-29 23:08:28 +02:00
can1357 461971a49b test(session): cover model change event emission
(cherry picked from commit fd4b388c6947fb28539653ae56d61bf988f1b5ab)
2026-07-29 23:08:27 +02:00
can1357 0e7ae1d6ac Merge PR #6908: fix(acp): sync model status when the agent switches models internally (@marton78) 2026-07-29 23:08:27 +02:00
Márton Danóczy 9aaa455708 fix(session): defer rollback's model_changed emit until after thinking is restored
#emit's listeners (ACP's #handleLifetimeEvent -> #pushConfigOptionUpdate
-> #buildConfigOptions) run synchronously up to their first await, and
#buildConfigOptions is evaluated as a synchronous argument expression
before that await. Emitting model_changed immediately after
agent.setModel(previousModel) but before #models.restoreThinkingSnapshot
ran meant ACP could push a { previousModel, target-session-thinking }
config that was never an actual session state -- neither the failed
target nor the restored previous session.

Move the emit after restoreThinkingSnapshot/restoreServiceTiers so it
observes fully-restored state, same as every other rollback consumer
in this catch block already does implicitly by running after both.

Found by Codex on PR #6908 (pullrequestreview-4801303428), against
a33aa07df from this same branch.

bun test test/acp-agent.test.ts (57) + agent-session-switch-prev-context,
agent-session-model-persistence, agent-session-model-switch-auth,
agent-session-openai-completions-model-switch, nonvision-model-switch
-- 90 pass, 0 fail. Workspace typecheck clean.

(cherry picked from commit 0ac190a39a1687ebf85849dde5e1af9c2f9147fc)
2026-07-29 23:08:26 +02:00
Márton Danóczy 65f4702485 fix(collab): push footer state to guests on model_changed
STATE_TRIGGER_EVENTS (host.ts) gates the debounced state broadcast
that carries CollabSessionState.model to collab guests. model_changed
was absent, so a guest's model display went stale on the same
internal switches (prewalk hand-off, retry-fallback, model cycling)
this PR fixes for ACP/RPC/TUI, until an unrelated trigger
(agent_start/message_end/...) or the 2s streaming-interval tick
happened to fire first.

#buildState() already reads session.model live, so this is purely a
trigger-registration gap -- no schema change.

Extends the PR's Unreleased changelog entry to cover the TUI render
fix, the collab fix, and the rollback corrective-event fix landed in
this branch.

(cherry picked from commit 066ed2b7c729b7d8b3f4424b2c19f4b65d631f08)
2026-07-29 23:08:26 +02:00
Márton Danóczy 80c32cf16a fix(tui): request a render on model_changed, not just cache invalidation
handleEvent has no blanket pre-render (removed for issue #4353), so
each handler must explicitly schedule one when it changes something
visible -- every other statusLine.invalidate() call site in this file
pairs it with ui.requestRender(). The new model_changed handler only
invalidated the cache, so an internal model switch (prewalk hand-off,
retry-fallback) while the TUI was otherwise idle left the status line
showing the stale model until an unrelated event happened to render.

Flagged by @chatgpt-codex-connector on PR #6908.

(cherry picked from commit f565e3a4956bda467b6679a3c3f1e48379395a78)
2026-07-29 23:08:26 +02:00
Márton Danóczy 3c0aa19820 fix(session): emit model_changed when switchSession rollback restores the model
switchSession's success path may already have called
#setModelWithProviderSessionReset for the target session's model,
which emits model_changed for it. If a later step in the try block
then throws, the catch restores previousModel via a direct
agent.setModel(...) that bypasses that method entirely and emitted
nothing — ACP/RPC/TUI kept advertising the target model that was
never actually committed.

Emit model_changed from the rollback path too, but only when the
restore actually changes the model back (guards the common case where
switchSession never touched the model or restores the same one).

Flagged independently by @roboomp and @chatgpt-codex-connector on
PR #6908.

bun test test/acp-agent.test.ts (57), agent-session-switch-prev-context.test.ts
(3), agent-session-model-persistence.test.ts (10 files) -- 80 pass, 0 fail.

(cherry picked from commit a33aa07df6fd61508956d73cc5b5284051bbfa86)
2026-07-29 23:08:26 +02:00
Márton Danóczy 986b1a1e70 refactor(session): emit model_changed via sync #emit, not #emitSessionEvent
model_changed has no extension-facing hook (#emitExtensionEvent never
maps it), unlike message_start/tool_execution_end/etc. Routing it
through #emitSessionEvent added an await on extension delivery plus
the FIFO subscriber gate inside every model switch, including
retry-fallback on the hot error-recovery path, for zero benefit.

Match the sibling thinking_level_changed event, which already goes
through the plain synchronous #emit. ACP/RPC/TUI still receive it
identically since they subscribe via #eventListeners either way.

No observable behavior change: bun test test/acp-agent.test.ts stays
at 57 pass, dedup logic for client-initiated model changes unaffected
(push still lands during the awaited #setModelById call).

(cherry picked from commit 3edc9f8495b1b06fd990a64756d92e60354451fc)
2026-07-29 23:08:26 +02:00
can1357 e0415a9e90 test: cover legacy pi CLI exports
(cherry picked from commit a0e11651f72a69c80486dffbb8dbdd96d6a382f5)
2026-07-29 23:08:25 +02:00
Márton Danóczy 25ace63676 docs(coding-agent): note ACP model status-sync fix in changelog
(cherry picked from commit 3be1a55298f67238b91a702abaa70c0fedc4df17)
2026-07-29 23:08:25 +02:00
can1357 a97d1bdd7c Merge PR #6907: fix: forward parseArgs and CONFIG_DIR_NAME from the legacy pi shim (@Gy-Hu) 2026-07-29 23:08:25 +02:00
Márton Danóczy 0ca0739eeb fix(acp): sync model config option on internal model changes
Zed (and any other ACP client) never learned about a model switch that
happened from inside the agent loop — prewalk hand-offs, retry-fallback,
model cycling — because #pushConfigOptionUpdate was only ever wired to
the client-initiated setSessionConfigOption/setSessionMode RPCs and to
the thinking_level_changed lifetime event. The model itself did switch
correctly (subsequent requests used the new model), but the client's
model picker/status bar kept showing the session's starting model.

#handleLifetimeEvent now also reacts to the model_changed event added
in the previous commit and re-pushes config_option_update. Extend the
existing thinking-only subscription dedupe in setSessionConfigOption to
cover the model config id too, so a client-initiated model change still
produces exactly one notification once the lifetime subscription is
installed.

Regression tests mirror the existing thinking-level coverage:
- 'pushes config_option_update when the model changes internally'
- 'emits a single config_option_update per setSessionConfigOption(model) call'

Verified: bun test test/acp-agent.test.ts (57/57), plus
agent-session-prewalk.test.ts, agent-session-retry-fallback.test.ts,
retry-fallback.test.ts, model-resolver.test.ts, and the other acp-*.test.ts
files all still pass; tsgo --noEmit and biome check clean.

(cherry picked from commit f5c5081088e8cbac2650a9de89049731de1b2777)
2026-07-29 23:08:25 +02:00
Márton Danóczy bce1ff55a7 feat(session): emit model_changed event on every internal model switch
AgentSession#setModelWithProviderSessionReset is the single choke point
every model mutation runs through (explicit /model, prewalk hand-offs,
retry-fallback, model cycling). It previously changed agent.state.model
silently — no session event told subscribers (ACP, RPC, TUI) that the
active model moved.

Emit a new model_changed AgentSessionEvent from that choke point
whenever the model actually changes, and wire it into every consumer
that must exhaustively handle AgentSessionEvent: the TUI event
controller (invalidates the status line, same as thinking_level_changed)
and the RPC client's forwarded-event allowlist.

(cherry picked from commit f76325de2c7821dd7046ddb67546577c3575a263)
2026-07-29 23:08:25 +02:00
can1357 8e72d4778e test(ttsr): cover human-readable inference note
(cherry picked from commit 8867610c39cf302089b7a4203e3ff8886fb1af52)
2026-07-29 23:08:24 +02:00
can1357 ab48f43783 Merge PR #6888: fix(ttsr): flag text-source inference for unlisted file extensions (@roboomp) 2026-07-29 23:08:24 +02:00
can1357 b5ad903788 fix(ttsr): exclude deleted patch text from matcher digest
(cherry picked from commit b4812365368368a5706131c3ff1ecd52fd64662d)
2026-07-29 23:08:24 +02:00
can1357 3a61aa727f fix(coding-agent): keep Advisor retry sleep on Bun
(cherry picked from commit 31b9090f901b520b57d5dacec3f8c7dba271decc)
2026-07-29 23:08:23 +02:00
can1357 8c45df1cdd Merge PR #6883: fix(coding-agent): scope Advisor cost to the active session (@paolomazzitti) 2026-07-29 23:08:23 +02:00
can1357 7338be4d67 Merge PR #6845: fix(launch): isolate legacy xterm replay (@usr-bin-roygbiv) 2026-07-29 23:08:22 +02:00