Commit Graph

183 Commits

Author SHA1 Message Date
roboomp 4bc71bdafc fix(tui): defer large command panels during streaming to stop scrollback dupes
/usage, /session, /advisor status, /jobs, /changelog, /context, and
/memory view mounted their finalized panel immediately via ctx.present()
instead of ctx.presentCommandOutput(), the streaming-deferral path added in
#5427 for /tools and /mcp. When invoked mid-turn, the panel landed above a
still-growing live block and the append-only scrollback contract recommitted
it lower down, so it appeared twice in native scrollback.

Route all six large command panels through presentCommandOutput() so they
defer until agent_end, matching /tools and /mcp.

Fixes #6767
2026-07-27 05:49:42 +00:00
Brent 0bfb0bd1e3 feat(coding-agent): add usage-aware model fallback 2026-07-24 02:23:51 +02:00
can1357 5d66eb7f2a Merge PR #5464: fix(coding-agent): persist vibe sessions across restarts (@roboomp) 2026-07-23 18:06:11 +02:00
can1357 1435f8dbce perf: restored lazy export-module loading by splitting /export arg parsing into export/html/args.ts 2026-07-23 17:30:33 +02:00
can1357 c76221095f Merge PR #6349: support light, dark, and system themes in HTML exports (@anatoli-tsinovoy) 2026-07-23 17:30:32 +02:00
LunarECL e7fdc99afd feat(ai): report Anthropic extra usage 2026-07-23 21:25:15 +09:00
Gareth-Rouse e2839d1288 feat(ai): added Synthetic usage provider
/usage and omp usage now report Synthetic (synthetic.new) quota state
via GET /v2/quotas (free, does not consume quota): the rolling 5-hour
request limit with per-tick regeneration rate, and the weekly credit
quota in USD. Applies to API-key credentials for the synthetic
provider; every payload section is parsed defensively since only
subscription is documented.
2026-07-23 08:46:18 +01:00
Anatoli Tsinovoy 159bdd8b42 Add light and system themes to HTML exports 2026-07-23 09:48:37 +03:00
can1357 d4219e6d0b Merge PR #6207: fix(usage): align multi-account /usage columns across windows (@roboomp) 2026-07-22 21:13:19 +02:00
can1357 e1173b8aeb Merge PR #6199: fix(tui): reuse settled components after compaction (@roboomp) 2026-07-22 21:13:17 +02:00
roboomp 4fd9dd5722 fix(usage): align multi-account /usage columns across windows
The TUI /usage matrix sorted each quota window's account columns
independently by used fraction, so the positional `account N` labels
denoted different credentials on each row. An account exhausted on one
window but light on another (e.g. a Kimi Code account's 5h limit)
rendered its exhausted bar under a sibling that still had quota, making
the section `% free` and capacity numbers look wrong.

Order account columns once per provider (worst-first) and hold that
order stable across every window row.

Fixes #6067
2026-07-21 20:48:12 +00:00
roboomp 13039b7bdf fix(tui): reused settled components after compaction
Preserved settled user and assistant component instances during compaction-only transcript rebuilds so warmed Markdown and layout caches remain valid.

Covered both manual and automatic compaction paths with focused regression tests.

Fixes #6033
2026-07-21 20:25:35 +00:00
Jeff Scott Ward 3e24087111 fix(coding-agent): persist bash shortcut cwd changes 2026-07-17 16:58:32 -04:00
can1357 eac51b6a04 Merge: darkphilosophy/feat/advisor-per-agent-toggle
Brings the per-advisor toggle, status-line glyphs, quota display, and the
failing-advisor stall/abort fix (f4c8143) onto main's rewritten advisor
runtime. Conflict reconciliation kept main's architecture (fingerprint
prefix reconciliation, host-level onTurnError recovery + fallback chains,
terminal-failure classification) and ported the branch semantics onto it:

- #failing latch: waitForCatchup resolves immediately while an advisor is
  mid-failure; parked waiters wake the moment a turn fails, before any
  async hook or retry sleep.
- Turn-end render containment: a formatter bug restores the cursor/prefix/
  dedup snapshot and never propagates into the primary's turn-end callback
  (per-advisor try/catch boundary in AgentSession).
- Quota pause: when host recovery declines a usage-limit failure, the
  runtime latches quotaExhausted, requeues the batch, and notifies —
  cleared only by an explicit reset.
- Hard halt after a permanent rejection or three backlog-drop cycles.
- #recoverAdvisorTurn also marks usage limits for structural errors thrown
  before any assistant turn is recorded.
2026-07-17 07:37:29 +02:00
can1357 8bdb69254b merge PR #5596 via eval/pr-5596: feat(coding-agent): support per-project model roles
Combined #5586's role-tag precedence with #5596's scope labels in the
selector status messages.
2026-07-17 05:23:49 +02:00
DarkPhilosophy 1b4c292f8f Merge remote-tracking branch 'can1357/main' into feat/advisor-per-agent-toggle 2026-07-17 05:47:09 +03:00
can1357 99f2ffa033 merge PR #5703 via eval/pr-5703: fix(tui): preserved organization suffixes in usage panel 2026-07-17 04:39:14 +02:00
Gerben Meijer 1e083eb832 feat(coding-agent): support per-project model roles 2026-07-17 01:22:23 +04:00
roboomp 5fe9bb92d8 fix(tui): preserved organization suffixes in usage panel
Removed the 24-column cap from account cells so wide terminals can show full disambiguating labels.

Kept usage bars independently capped and added regression coverage for same-email organization accounts.

Fixes #5701
2026-07-16 13:25:20 +00:00
roboomp dc372c67d6 fix(usage): org-qualified session marker for same-email accounts
The /usage show "in use by this session:" marker took only the bare
email from OAuthAccountIdentity, so two same-email Anthropic credentials
in different orgs were indistinguishable. Route the label through a
shared formatActiveAccountLabel that suffixes the active org, matching
the account list and login-success surfaces.

Fixes #5691
2026-07-16 11:09:05 +00:00
can1357 e0c717e07f merged PR #5427: fix(tui): defer command output during streaming 2026-07-16 03:32:03 +02:00
DarkPhilosophy 081ce322ef Merge remote-tracking branch 'can1357/main' into feat/advisor-per-agent-toggle 2026-07-16 02:30:12 +03:00
can1357 5ff277349c refactor(coding-agent): consolidated tool surface onto xd:// devices and hub
- Added the `xd://` virtual device protocol (`internal-urls/xd-protocol.ts`, `tools/xdev.ts`): tools declaring `loadMode: "discoverable"` are unmounted from the request tools array and driven via `read xd://` (list/docs+schema) and `write xd://<tool>` (execute), gated by the `tools.xdev` setting (default on) and inlined into the system prompt.
- Merged the `irc`, `job`, and `launch` tools into a single `hub` tool (`tools/hub/`, `async/job-manager.ts`): messaging keeps `send`/`inbox`/`list`, job control maps to `wait`/`cancel`/`jobs`, process supervision keeps `start`/`logs`/`stop`/`restart`/`describe` with `ps`, and the unified `wait` races background jobs against peer messages; SDK `IrcTool`/`JobTool`/`LaunchTool` are replaced by `HubTool`.
- Removed the hidden `resolve` tool in favor of the `xd://resolve`/`xd://reject`/`xd://propose` resolution devices, auto-including `write` whenever a deferrable tool or plan mode is present.
- Removed the BM25 tool-discovery system: the `search_tool_bm25` tool, the `tool-discovery` module, the `tools.discoveryMode`/`mcp.discoveryMode`/`mcp.discoveryDefaultServers`/`tools.essentialOverride` settings, per-tool MCP selection, and the `mcp_tool_selection` message type.
- Unified tool presentation on `ToolLoadMode` (`essential`|`discoverable`), replacing the custom-tool `xdev?: boolean` opt-out; custom, extension, MCP, RPC host, image-generation, and TTS tools now default to `discoverable`, and added a `satisfies` predicate to `SoftToolRequirement`.
- Removed the standalone `ssh` command tool and `ssh/ssh-executor` (the `ssh://` read/write/search protocol stays), and made `--tools` address hidden built-ins.
- Updated collab-web to render `xd://` dispatches and `hub` op families, dropped the `search_tool_bm25`/`ssh`/`report-finding` renderers, refreshed tool docs and prompts, and migrated the affected tests and changelogs.
2026-07-15 15:16:29 +02:00
DarkPhilosophy 0a9a5aa186 Merge remote-tracking branch 'can1357/main' into feat/advisor-per-agent-toggle
# Conflicts:
#	packages/coding-agent/src/advisor/runtime.ts
2026-07-15 03:32:11 +03:00
roboomp 4bc68b45e2 fix(coding-agent): persisted vibe sessions across restarts
Vibe worker roster lived only in a process-local Map, so a resumed parent
session started with an empty registry and vibe_send failed with
"Unknown vibe session". Persist a versioned, parent-scoped lifecycle
journal (spawn/turn/tombstone events), rehydrate validated idle workers
through the persisted-subagent reviver on resume, and gate the flow with
generation/CAS protection so stale finalizers cannot clobber a
replacement worker. Killed transcripts stay readable but non-revivable;
mode-exit commits tombstones atomically with the mode change and rolls
back cleanly on storage failure.

Ported from @mastertyko's fork branch fix/vibe-session-persistence.

Fixes #5303
2026-07-14 17:58:14 +00:00
roboomp d3f4830ceb fix(tui): deferred command output during streaming
- Queued transcript command panels until the active agent turn ends.

- Added regression coverage for slash-command output mounting exactly once.

Fixes #4806
2026-07-14 16:35:18 +00:00
can1357 7f9a2777f9 Merge PR #5170: fix(ai): scope Anthropic credential identity by organization, not just email (@chan1103) 2026-07-14 18:29:14 +02:00
DarkPhilosophy 4db2d9617b Merge remote-tracking branch 'can1357/main' into feat/advisor-per-agent-toggle 2026-07-13 23:16:26 +03:00
can1357 5c2bae47ac feat(mode): enabled conditional transcript compaction logic
- Introduced conditional scrollback clearing during UI renders when transcript compaction is enabled.
- Updated `CommandController` and `EventController` to respect the `display.collapseCompacted` setting.
- Configured `SelectorController` to trigger a chat rebuild and UI reset when the compaction setting changes.
- Updated `InteractiveMode` to dynamically toggle between collapsed and full inline history based on user settings.
2026-07-13 01:29:53 +02:00
DarkPhilosophy ca8bf8dda1 Merge remote-tracking branch 'can1357/main' into feat/advisor-per-agent-toggle
# Conflicts:
#	packages/ai/test/pi-native-client.test.ts
#	packages/coding-agent/src/modes/components/advisor-config.ts
#	packages/coding-agent/src/session/agent-session.ts
2026-07-11 22:13:08 +03:00
chan1103 044d722a36 fix(ai): scope Anthropic credential identity by organization
One Anthropic account email can hold multiple organizations (a Team seat
plus a personal Max plan), each with its own org-scoped OAuth token and
independent 5h/7d limit pools. Credentials were deduped by bare email, so
logging in with the second subscription silently replaced the first, and
usage reports from the two pools merged into one row with mixed numbers.

- capture organization uuid/name at login (token exchange response, with
  a claude_cli/bootstrap fallback); token refreshes never rewrite it
- key anthropic credential identity as email + org; a legacy email-keyed
  row is claimed in place by the first org-scoped login with the same
  email, and org-less credentials never clobber org-scoped rows
- partition usage-report dedupe and the per-credential usage cache by
  org so the two subscriptions' limit pools stay distinct for rotation
- show the organization in omp usage (redaction-safe) and name the
  stored account/org in the login success message
2026-07-11 22:49:12 +09:00
roboomp f534112957 fix(coding-agent): bound startup changelog rendering
- Treated missing or invalid changelog markers as first install and persisted the current version without replaying historical notes.
- Shared bounded changelog rendering between startup and recent changelog views, with a 64 KiB startup cap and full-history hint on truncation.
- Added marker, truncation, recent/full rendering, and PTY startup regression coverage.

Fixes #5135
2026-07-11 02:28:27 +00:00
DarkPhilosophy c93e38b145 fix(advisor): include limit identity when compacting quota windows 2026-07-08 21:33:05 +03:00
DarkPhilosophy 3d99535972 fix(advisor): address review — per-advisor account quota, status overview, no_model status fix 2026-07-08 19:13:12 +03:00
DarkPhilosophy 8b4d644b4e fix(advisor): address review — no arbitrary auto-resume, active-account quota filter, dedup imports 2026-07-08 18:33:22 +03:00
DarkPhilosophy be19be8223 Merge remote-tracking branch 'can1357/main' into feat/advisor-per-agent-toggle 2026-07-08 17:47:41 +03:00
DarkPhilosophy 3e92c6d95b fix(advisor): address review — ES private fields, restore instructions body, legacy slug 2026-07-08 17:19:22 +03:00
DarkPhilosophy b55e6b91fe fix(advisor): show all quota windows (5h + 7d) sorted by urgency 2026-07-08 17:09:44 +03:00
DarkPhilosophy 13572f308b feat(advisor): real quota display in status + config, scrollbar in editor 2026-07-08 16:46:07 +03:00
DarkPhilosophy fc0d35495f feat(advisor): scrollable instructions editor + richer /advisor status 2026-07-08 15:41:35 +03:00
DarkPhilosophy 7f0e198990 feat(advisor): per-advisor toggle, quota classification, status dots
- Add 'enabled' field to AdvisorConfig (default true, persisted in WATCHDOG.yml)
- Filter disabled advisors in #resolveAdvisorRuntimeDescriptors, keep in status map
- Classify quota/rate-limit errors separately from transient server errors
- Auto-pause advisor on quota exhaustion, auto-resume after 5min cooldown
- Add AdvisorRuntimeStatus enum (running/paused/no_model/quota_exhausted/error)
- Render per-advisor status dots in status line: ●○✕ with truncation to 4+ '+'
- Include disabled/no-model advisors in PerAdvisorStat with status field
- Add notifyQuotaExhausted host callback distinct from notifyFailure
- Tests: config round-trip for enabled field, quota classification, overloaded path
2026-07-08 15:17:40 +03:00
roboomp 568226abb9 fix(tui): disposed stale session ui renderers
Stopped new-session and session-switch UI paths from detaching active loader/render components without running their disposal hooks.

Added container and loader coverage for disposing children before destructive transcript/status replacement.

Fixes #4686
2026-07-06 08:49:02 +00:00
can1357 734aed4c03 Merge PR #4382: fix(compaction): keep plan-mode guidance off the session_before_compact hook (@roboomp) 2026-07-05 13:25:28 +02:00
can1357 10043a5990 feat(coding-agent): gated block lifecycle and state transitions
- Enforced strict history protection by gating ephemeral block removal on uncommitted state across controllers and UI components.
- Optimized settled-row calculations using explicit mermaid fence detection and improved scrollback integrity.
- Refactored transience management to target only actively streaming blocks, preventing redundant label rendering.
- Implemented persistent compaction for auto-retry errors and enabled consistent terminal title updates during session renaming.
2026-07-04 12:13:34 +02:00
roboomp 72df91c3c8 fix(compaction): route plan-mode guidance via internalGuidance channel
Plan-approval's 'Approve and compact context' used to pass the rendered
plan-mode-compact-instructions prompt as the first positional argument
to handleCompactCommand -> session.compact(), which landed on the
session_before_compact extension hook as customInstructions. Extensions
treating that field as user focus (e.g. to bias a query-focused summary)
would then see plan-mode boilerplate instead of operator intent and
produce query-biased compactions.

Add CompactOptions.internalGuidance: a private summarizer-only channel.
session.compact() reads it into the fallback-model summarizer while the
session_before_compact hook payload still only carries the public
customInstructions arg (undefined for the plan-compact path). The
snapcompact-disable predicate and the /compact rejectsFocus guard cover
both fields so a directed summary is never silently downgraded.

Extend the interactive-mode handleCompactCommand facade + command
controller with a fourth internalGuidance parameter, and switch the
plan-approval callsite in interactive-mode.ts to route the plan prompt
through it.

Fixes #4359
2026-07-03 00:36:38 +00:00
can1357 63b812320d Merge PR #3903: fix(coding-agent): identify user-invoked skills and expose skill directory (@metaphorics)
# Conflicts:
#	packages/coding-agent/src/extensibility/skills.ts
#	packages/coding-agent/src/modes/acp/acp-agent.ts
#	packages/coding-agent/src/modes/rpc/rpc-mode.ts
#	packages/coding-agent/src/modes/skill-command.ts
2026-07-01 22:16:53 +02:00
roboomp 809a8a348d fix(tui): coalesce editor top-border rebuild to render tempo
EventController.handleEvent rebuilt the editor's status-line top border
synchronously on every session event via updateEditorTopBorder(). During
a long-running eval that fires 5-10 events/s, each rebuild ran
StatusLine.getTopBorder → #buildSegmentContext → getCachedContextBreakdown
→ session.getContextUsage → estimateTokens (with JSON.stringify per
toolCall block) — the render pipeline is throttled to ~30 fps, so most
rebuilds were dropped before painting. Combined with a scheduler that
collapsed cadenceDelay to zero whenever a frame overran the 33ms budget,
the TUI busy-looped at ~40-50% CPU.

Fix:
- Editor gains setTopBorderProvider(): a lazy builder invoked once per
  editor render. InteractiveMode installs it in the constructor and on
  setEditorComponent, so the rebuild coalesces to the render tempo
  regardless of event rate.
- Delete updateEditorTopBorder wrapper (now equivalent to
  ui.requestRender) and inline every call site.
- Add adaptive render backpressure: a frame that exceeds
  MIN_RENDER_INTERVAL_MS inflates the next scheduling delay to
  2 * last_frame_cost, capped at 200 ms, targeting a 50% render duty
  cycle instead of pinning the CPU at t=0.

New regression tests:
- editor-top-border-provider.test.ts: provider fires exactly once per
  render, wins over eager setTopBorder, falls back when cleared, gets
  the correct availableWidth.
- adaptive-render-backpressure.test.ts: cheap frames keep the 33 ms
  cadence, a slow frame idles proportionally, pathological frames are
  capped at 200 ms.

Verified with bun test packages/tui/test (all 246 relevant tests pass)
and bun test packages/coding-agent/test/modes (455 tests pass). Three
pre-existing agent-session-handoff snapcompact failures on main are
unrelated (snapcompactSupportedChars binding).

Fixes #4145
2026-07-01 13:51:43 +00:00
metaphorics fa64097992 fix(coding-agent): identify user-invoked skills and expose skill directory
User-invoked skills (typed /skill:, steered, follow-up, interrupted/
resumed via compaction, ACP, RPC) only appended a bare "Skill: <path>"
line, so the model neither learned the user had invoked that specific
skill nor where the skill directory was. Relative paths in skill bodies
(scripts/, templates/) could not be resolved.

Route all user-invoked paths through a self-identifying, baseDir-aware
prompt template; keep hidden autoload skills on the minimal non-user
format. Interactive skillCommands now carries the loaded Skill object
instead of a bare path so baseDir flows through without reconstruction.
The invocation kind defaults to "user" to keep buildSkillPromptMessage
source-compatible.

Op: correct
Restores: spec:user-invoked-skill-prompt-self-identifies-and-exposes-skill-directory
2026-06-30 23:11:05 +09:00
can1357 0ffe6c8e1f Merge PR #3675: keep moved sessions resumable (@riverpilot)
# Conflicts:
#	packages/coding-agent/src/modes/controllers/command-controller.ts
2026-06-28 18:46:19 +02:00
can1357 fbad280b57 feat: implemented multi-advisor concurrent runtime with tui management
- Introduced comprehensive support for multiple concurrent, independently-configured advisors via `WATCHDOG.yml` files.
- Implemented a full-screen TUI overlay for managing advisor rosters, models, tools, and instructions.
- Added session-wide advisor initialization, telemetry aggregation, and named transcript isolation.
- Enhanced advisor security and observability with secret redaction in tool results and secure XML attribute encoding.
2026-06-28 12:55:09 +02:00