Commit Graph
1063 Commits
Author SHA1 Message Date
Brit a8dabe2cf8 fix(tui): deferred native scrollback rebuilds 2026-05-28 15:45:33 +02:00
can1357 5053a6a4d3 fix(coding-agent): corrected coding-agent incomplete stop recovery logic
- Handled "incomplete" stop reasons in session recovery and auto-compaction workflows.
- Dropped the prior assistant turn before attempting recovery on incomplete-length stops.
- Expanded auto-compaction reason types and triggers to include "incomplete".
- Updated internal URLs parsing internals, export order, tests, and Obsidian URI prompt docs.
2026-05-28 10:10:34 +02:00
can1357 c1fa0e9f50 refactor(agent): replaced keepalive utility with disposable EventLoopKeepalive
- Replaced the `keepaliveWhile` Promise wrapper with a new `EventLoopKeepalive` class that registers and disposes an interval timer through `Symbol.dispose`.
- Updated `Agent` to instantiate `EventLoopKeepalive` via `using` during prompt execution instead of manually managing an interval.
- Wrapped interactive mode's await path with the new helper and removed redundant `keepaliveWhile` usage from the CLI entrypoint.
2026-05-28 09:51:57 +02:00
can1357 7dd00c015b feat: hashline improvements for spark
- Redesigned hashline patch syntax from anchor-based (`A-B:`) to hunk-header format (`@@ A..B @@`) with unified-diff compatibility.
- Removed `autoDropPureInsertDuplicates` option and simplified apply behavior to preserve duplicated boundary and context lines.
- Changed repeat operator from `^A-B` to `&A..B` and range separator from `-` to `..` for consistency with hunk-header syntax.
- Added image resizing and dimension notes to eval tool output; improved write tool hashline header sanitation for legacy formats.
- Removed 521 lines of boundary-duplicate absorption code and simplified parser to auto-convert bare body rows and unified-diff contamination.
2026-05-28 03:06:52 +02:00
can1357 7c64576524 feat(hashline): replaced file-hash anchors with opaque snapshot-store tags
- Replaced 4-hex content-derived file hashes with 3-hex opaque tags minted by InMemorySnapshotStore, making tags session-bound pointers rather than content fingerprints.
- Removed lru-cache dependency; replaced LRU-bounded per-path rings with a flat 4096-slot global ring using a scrambled permutation to prevent LLM tag extrapolation.
- Made SnapshotStore required in Patcher (was optional); tag resolution now drives stale-anchor detection instead of recomputing hashes at apply time.
- Changed literal payload sigil from `|` to `+` and accepted `^A` shorthand for `^A-A`; added lenient recovery for bare bodies, lone `-` rows, and overlapping bare/concrete block pairs.
2026-05-28 01:00:23 +02:00
metaphorics b76f39d3a6 fix(coding-agent): reopen approved plan on plan-mode reentry
Patch axis: extend

Displacement: net-zero; reuses existing plan reference state instead of adding persistence or overwriting approved artifacts

Rule violations averted: no approved-plan overwrite, no transcript format migration, no public CLI/API expansion

PASS/FAIL: PASS after plan-mode focused tests and package check. Note: system-prompt-templates has an unrelated HOME=/tmp path-shortening expectation failure.
2026-05-27 16:32:40 +00:00
can1357 ff94f91104 feat: added extraBody support, xAI fixes, and image provider updates
- Added `extraBody` merging into OpenAI Responses request params.
- Fixed xAI OAuth redirect URI to fail fast on port conflicts.
- Exposed `antigravity` and `xai` as explicit `providers.image` options.
- Added `isImageProviderPreference` guard, replacing inline string checks.
- Fixed TTS tool to resolve output path relative to cwd and require write approval.
2026-05-27 15:20:55 +02:00
can1357 6643178d6a refactor: replaced instanceof Promise checks with isPromise utility
- Imported isPromise from node:util/types in four modules.
- Replaced four instanceof Promise checks with isPromise calls for more reliable promise detection.
2026-05-27 13:02:52 +02:00
can1357 6f33af09b8 fix(coding-agent/modes): resorted filtered model matches by MRU ordering
- Added optional skipRoleRank controls to model and canonical-model sort helpers to make role ranking conditional.
- Re-sorted fuzzy-filtered model and canonical model results with role rank skipped so stronger query matches are not outranked by weak default-role matches.
2026-05-26 22:50:38 +02:00
can1357 39299597f2 fix(coding-agent/modes): preserved fuzzy relevance ordering when filtering models
- Removed post-filter re-sorting for canonical model matches so fuzzyFilter's relevance order is preserved.
- Stopped reapplying role, MRU, and version sorting after fuzzy filtering canonical and non-canonical models.
- Documented the stable-sort rationale so fuzzy text relevance remains the primary ordering.
2026-05-26 21:56:09 +02:00
Can BölükandGitHub 8448a67602 Merge pull request #1374 from superhedge22/fix-review-enter-submit
Fix /review custom instructions submission
2026-05-26 21:40:15 +03:00
can1357 8a32eceb53 fix(utils): clamped usage durations to suppress stale negative reset countdowns
- Clamped `formatDuration` to return `0ms` for non-positive, NaN, or infinite inputs.
- Updated usage report rendering to suppress reset countdowns when `resetsAt` is absent or no longer in the future.
- Added unit tests for `formatDuration` covering clamped values and standard duration formatting.
2026-05-26 20:22:25 +02:00
Can BölükandGitHub 0e1807a49c Merge pull request #1407 from faizhasim/oauth-path-prefix-fix
feat(coding-agent): support OAuth discovery for path-prefixed auth servers behind gateways
2026-05-26 21:20:29 +03:00
Brit 884980bafa feat(settings): highlighted changed settings 2026-05-26 17:40:19 +02:00
Mohd Faiz Hasim 96d4a4ce3b Merge branch 'main' of github.com:can1357/oh-my-pi into oauth-path-prefix-fix 2026-05-26 22:53:11 +08:00
Mohd Faiz Hasim 5be0f01a91 feat(coding-agent): support OAuth discovery for path-prefixed auth servers behind gateways
- Extract resource_metadata URL from WWW-Authenticate and follow RFC 9728 chain
- Add buildWellKnownUrls with path-prefixed well-known fallback for gateways
- Fix resolveRegistrationEndpoint to try path-prefixed well-known (was missing await)
- Support relative Mcp-Auth-Server URL resolution against server URL
- Pass resourceMetadataUrl through all discoverOAuthEndpoints call sites
- Add comprehensive tests for path-prefixed, resource_metadata, and relative URL flows
2026-05-26 22:50:32 +08:00
can1357 796c437dc1 feat: overhauled stream timeout and eval session management
- Replaced external watchdog timers with per-request SDK timeouts for first-event budget across OpenAI, Anthropic, and Azure providers.
- Keyed Python shared kernels by (sessionId, cwd) to prevent cross-directory state bleed.
- Deduplicated concurrent cold-start session acquisition for JS and Python executors.
- Moved `isOpenAIResponsesProgressEvent` to shared module and scoped display output routing per run for interleaved async cells.
2026-05-26 16:49:11 +02:00
can1357 5364a9bfd0 refactor(tool-discovery): simplified tool discovery API by removing MCP-specific shims
- Removed deprecated MCP-specific type aliases and functions from tool-discovery module, consolidating to unified generic tool discovery API.
- Migrated session and SDK code to use generic filterBySource() and collectDiscoverableTools() instead of MCP-specific variants.
- Removed deprecated interface members including hasQueuedMessages(), FocusPane, AcpBuiltinCommandRuntime, and legacy settings methods.
- Updated test suites to use renamed generic discovery methods and removed back-compat test coverage for legacy MCP shapes.
2026-05-26 15:27:05 +02:00
roboomp e6a88fa9c0 fix(tui): cleared history after slash new
Avoid rendering the pre-reset transcript during /new and force the final new-session frame through the clear-scrollback path so the cursor and prompt land with the replacement transcript.

Fixes #1295
2026-05-25 18:54:22 +00:00
SuperHedge 70e873aa8d Fix review custom instructions submission 2026-05-25 20:48:46 +02:00
roboomp aec33a2f7b fix(tui): cleared history on session replacement
Add an explicit clear-scrollback render option for intentional transcript replacement and use it when switching, branching, reloading, or creating sessions. Regular active redraws continue to preserve terminal scrollback.

Fixes #1295
2026-05-25 18:44:22 +00:00
can1357 d6acef8b76 perf(status-line): replaced index-based token cache with message sidecar cache
- Added Symbol-keyed sidecar on each AgentMessage to memoize estimateTokens, with a cheap content fingerprint to detect in-place mutations.
- Fixed stale cache on same-length replaceMessages, post-hoc error attachment, and branch rebuild edge cases.
- Fixed usage fetch error backoff: stamped fetchedAt on failure so the 5-min TTL also gates retries during outages.
- Extracted computeNonMessageBreakdown as shared helper to prevent drift between status-line and context panel token counts.
2026-05-25 14:06:05 +02:00
can1357 1b58e484ab chore(coding-agent): remove unused status-line segment editor 2026-05-25 12:55:48 +02:00
roboompandcan1357 294f0067d0 fix(tui): refreshed model tabs by provider id
Separated model selector provider tab labels from provider ids so human-readable labels like Ollama Cloud refresh and filter the underlying ollama-cloud models.

Fixes #1153
2026-05-25 12:25:12 +02:00
can1357 8e74996513 chore: adjust tests 2026-05-25 12:22:43 +02:00
Can BölükandGitHub 1084a854f8 Merge pull request #1296 from can1357/farm/93902d04/goal-set-rejects-active-goals-but-clears
fix(cli): allow /goal set to replace active goals
2026-05-25 13:20:46 +03:00
Can BölükandGitHub e4165a41e6 Merge branch 'main' into farm/bfe680ee/ctx-ui-notify-during-session-start-is-cl 2026-05-25 13:20:04 +03:00
can1357 7484299192 refactor(coding-agent/tools): removed bash fixup warning notices from command execution flow
- Removed the exported formatBashFixupNotice helper from bash command fixup utilities.
- Removed BashTool's one-time bash-fixup notice tracking and stopped emitting those notices when fixups were applied.
2026-05-25 12:18:35 +02:00
can1357 6943b5baa3 chore: reformat 2026-05-25 12:17:30 +02:00
Leo Kimandcan1357 4eb2919674 fix(coding-agent): incremental per-message token cache for status-line context% (avoid 1.1s freeze on long sessions)
Root cause (verified on user's environment):

- User commit `296641213` swapped status-line's context% computation from cheap `calculatePromptTokens(lastAssistantMessage.usage)` to `computeContextBreakdown(session)`, which walks EVERY message and runs native `countTokens` (~0.5 ms per message).

- The 2-second TTL cache helps for steady-state idle but every cache MISS is a full sweep.

- `updateEditorTopBorder()` is invoked on EVERY agent event (event-controller.ts:163 — `agent_start`, `delta`, `agent_end`, `tool_*`). Each delta during streaming can trigger a cache miss.

- User session has 2,312 messages → each full sweep is ~1,120 ms blocking.

- During streaming the UI freezes for ~1.1 s every ~2 s, producing the user-visible 'jittery rendering' ("버벅거림") and 'status bar disappearing' symptoms.

Fix:

`StatusLineComponent.getCachedContextBreakdown()` (renamed from `#getCachedContextBreakdown` so unit tests can exercise it directly) now uses an incremental per-message token cache that exploits the append-only nature of `session.messages`:

  1. Message tokens (the dominant cost): cached per-index. New messages are tokenized as they arrive; previously-cached messages are reused. The LAST message is always recomputed because its content may still be growing during streaming. Compaction (messages.length shrinks) resets the cache.

  2. Non-message tokens (system prompt + tools + skills): cached separately, invalidated only when a cheap inputs-identity fingerprint changes (model swap, skill toggle, tool registration). These rarely change during a session.

Required exposing three helpers from `modes/utils/context-usage.ts` (`estimateSkillsTokens`, `estimateToolSchemaTokens`, `computeNonMessageTokens`) so the status-line cache can call them directly.

Performance (2,300-message synthetic session, measured on user's M-series Mac):

  - COLD warm-up call: ~75 ms (one-time, runs at OMP startup before any streaming)

  - WARM refresh, no new message: ~0.04 ms (20 calls = 0.7 ms total)

  - WARM refresh, 1 new message: ~0.02 ms

vs. prior implementation:

  - Per cache-miss call: ~1,120 ms blocking

  - 28,000× speedup on warm-state refresh

`computeContextBreakdown` itself is untouched — `/context` slash command continues to use it, and its output matches the status-line context% for the same session state (parity preserved).

Tests: 6 new cases in `packages/coding-agent/test/status-line-context-cache.test.ts` covering cold/warm/append/compaction/non-message-invalidation/zero-messages and a perf smoke test asserting 20 warm refreshes on a 200-message session complete in <100 ms.

Full suite: 3,199 tests, 26 pre-existing failures (status-line accent / log_experiment timing-flaky / skills / github tool / workspace-tree / tool path — all unrelated and baseline-confirmed). Lint: 1 pre-existing import-order issue in `event-controller-plan-ready.test.ts` unchanged.
2026-05-25 12:11:15 +02:00
Leo Kimandcan1357 8c4f7f3267 fix(coding-agent): align status-line context% with /context command output
Status-line's context_pct segment was computing tokens via
calculatePromptTokens(lastAssistantMessage.usage), which sums input +
cacheRead + cacheWrite from the Anthropic API usage object. The /context
slash command is computed by computeContextBreakdown, an offline estimate
over the live session state (systemPrompt + tools + skills + messages).

Both numbers are correct under their own definition, but they can
diverge by 2x+ on the same session when a turn rotates cache tiers
(e.g. 5m → 1h ephemeral re-cache) and cache_creation_input_tokens spikes.
Users read the two surfaces as one consistent dashboard and treat the
mismatch as a bug.

Repro: same session at the same moment reports 212K (21.2%) in /context
and 44.2%/1M in the status line — ~230K gap driven by per-turn
cache_creation on a system-prompt boundary.

This change makes status-line use the same computeContextBreakdown
source as /context so both surfaces stay consistent. The breakdown
result is cached with a 2s TTL inside the component so the per-frame
status-line render does not re-walk every message via
estimateMessagesTokens on long sessions. The Anthropic API per-turn
prompt size remains observable via existing token_in / cache_read /
cache_write / token_total segments.
2026-05-25 12:11:15 +02:00
Leo Kimandcan1357 7d0987bc61 feat(coding-agent): add status-line usage segment and thinking.max symbol
- New 'usage' status-line segment showing Anthropic 5h/7d quota
- Background refresh (5min TTL) via fetchUsageReports
- thinking.max symbol added to UNICODE_SYMBOLS

Personal patch consolidated into branch.
2026-05-25 12:11:15 +02:00
Leo Kimandcan1357 b373c54cd7 fix(coding-agent): guard sendCompletionNotification on aborted/error stopReason
Bug: Ctrl+C on the ask tool selector threw ToolAbortError, the turn
ended with stopReason === "aborted", and handleBackgroundEvent fired
sendCompletionNotification() unconditionally — producing a misleading
"Task complete" desktop toast for a turn that never actually completed.

Fix mirrors the stopReason filter already used by
#currentContextTokens, #handleMessageEnd, and the retry / TTSR /
compaction skip paths across agent-session.ts: check the most recent
assistant message via session.getLastAssistantMessage() and return
early when stopReason is "aborted" or "error".

Test coverage (event-controller-abort-guard.test.ts, 6 cases):
- aborted   -> 0 sendNotification calls
- error     -> 0 calls
- stop      -> 1 call (normal completion)
- no last assistant message -> proceeds (defensive)
- isBackgrounded=false (foreground) -> still 0
- completion.notify=off -> still 0

Matching guard applied to the standalone desktop-notify extension
(~/.omp/agent/extensions/desktop-notify/index.ts) which is currently
the live producer of completion toasts after Phase 1 of
seed_0ca7e1143ac1.
2026-05-25 12:08:36 +02:00
Can BölükandGitHub 98603c669b Merge branch 'main' into farm/7f8acce1/loop-mode-can-auto-submit-again-before-t 2026-05-25 12:58:57 +03:00
Brit 2a86049f0f feat(agent): add append-only context mode for DeepSeek prefix-cache stability
ImmutablePrefix caches system prompt + tool specs after first build()
so subsequent turns reuse identical byte sequences. AppendOnlyLog
converts messages once via syncMessages() and only appends deltas
on further turns — prior-turn bytes stay stable.

- New module: packages/agent/src/append-only-context.ts
  StablePrefix, AppendOnlyLog, AppendOnlyContextManager
- AppendOnlyContextManager added to AgentLoopConfig
- Wired into streamAssistantResponse in agent-loop.ts
- Toggleable via provider.appendOnlyContext setting (auto/on/off)
- Default auto enables for deepseek provider
- 38 tests covering prefix, log, sync, compaction handling
- /session info surfaces current active state
2026-05-24 22:08:53 +02:00
roboomp a916ae512e fix(coding-agent): preserved startup extension notifications
Keep chat notifications emitted during session_start visible after the initial transcript render rebuilds the chat container. Add regression coverage for preserving startup notifications during initial render.

Fixes #1316
2026-05-23 19:59:55 +00:00
roboomp 5573270e5e fix(loop-mode): block auto-submit while post-prompt background work is pending
When session.prompt() returns, idle-flush tasks for async-job result
deliveries are scheduled via #schedulePostPromptTask (1ms delay) and
added to #postPromptTasks immediately.  The 800ms loop timer could fire
in that window before isStreaming became true, causing the loop to
submit the next prompt while the delivery turn was still pending.  The
delivery then hit AgentBusyError and the job result was silently dropped.

Add AgentSession.hasPostPromptWork (= #postPromptTasks.size > 0) and
include it in #isLoopAutoSubmitBlocked() alongside isStreaming and
isCompacting.  Add a regression test that verifies the loop defers when
hasPostPromptWork is true and fires once it becomes false.

Fixes #1294
2026-05-22 13:41:17 +00:00
roboomp ccba77c5c7 fix(cli): allowed goal set to replace active goals
Allowed /goal set to replace the current active goal instead of rejecting and discarding the command input.

Added goal runtime and interactive-mode regression coverage for active replacements.

Fixes #1293
2026-05-22 13:23:06 +00:00
can1357andCan Bölük f29e733b67 refactor(coding-agent/modes): reorganized working-message hints in modes
- Added a shared `interruptHint()` utility in the modes shared module to generate the interrupt suffix with themed bracket glyphs.
- Replaced hardcoded working-message interrupt text in interactive and event controllers with calls to `interruptHint()`.
- Updated working-message rendering to recognize and strip the new themed hint when applying shimmer styling.
2026-05-22 17:44:20 +09:00
can1357 3e21ab8980 fix(coding-agent/modes): applied working-message accent to interactive spinner
- Updated interactive mode to render the loader spinner with the current working message accent when available.
- Added a fallback to theme accent and a reset color code when no working-message accent is provided.
2026-05-22 15:48:14 +09:00
can1357 4ada748c61 feat(modes): added ANSI-capable shimmer accents to loading messages
- Loading message rendering now derived session-specific accent colors and applied them to shimmer output when a session name was available.
- Shimmer palettes were updated to accept raw ANSI color values as well as theme color names during compilation.
- A unit test was added to confirm shimmer text rendered with a supplied ANSI crest color.
2026-05-22 15:40:58 +09:00
can1357 a13c9bf6fc feat(coding-agent): added SettingsList#setItems with clamped selection
- Added SettingsList#setItems to replace items and clamp selection to a valid index after updates.
- Updated SettingsSelector to rebuild active memory items on backend changes and skip refresh when appropriate.
- Switched MCP wizard and command spinners to theme frames with themed initial frame and 80ms updates.
- Reworked welcome intro animation for a 3-second eased sweep with optional shine blending.
- Added memory backend refresh tests and aligned package changelogs with the updated behavior.
2026-05-22 13:19:35 +09:00
can1357andCan Bölük 796f963da9 feat(coding-agent): added coding-agent follow-up queue with onBeforeYield
- Added optional `onBeforeYield` configuration and `setOnBeforeYield` in Agent, executed before follow-up checks.
- Added `YieldQueue` to `AgentSession`, with setup/teardown and streaming/idle flush via `setOnBeforeYield`.
- Replaced immediate async-result follow-up dispatch with queued batch entries, including stale-state suppression.
- Added MCP follow-up queueing in SDK, deduplicating updates by `serverName` and `uri`.
- Added changelog entries for `onBeforeYield`, async-result batching, MCP dedupe, and `display.shimmer` modes.
- Added yield queue unit tests for streaming emission, debounced idle batches, stale filtering, and error isolation.
2026-05-22 13:08:51 +09:00
can1357 e39b48c405 feat(coding-agent): added shimmer modes and tuned loader timing cadence
- Added `display.shimmer` setting (`classic`, `kitt`, `disabled`) with default `classic` and UI metadata.
- Added shimmer mode resolution with defaulting plus classic/KITT intensity tier profiles and thresholds.
- Added `getFgAnsi` handling across shimmer compilation and progress-bar themes, with fallback ANSI output defaults.
- Reworked shimmer rendering to coalesce same-tier segments, cache palettes by symbol, and map disabled mode to mid-tier.
- Tuned loader timing to a 16ms render interval and 80ms spinner stepping for smoother ~60fps updates.
2026-05-22 13:03:03 +09:00
can1357 b134d4b65c feat(coding-agent/modes): added shimmer segment rendering with palette overrides
- Added configurable shimmer palettes by introducing ShimmerPalette and ShimmerSegment types.
- Added a new shimmerSegments helper to render a single sweep across multiple text segments with optional per-segment palettes.
- Updated working-message rendering to style the interrupt hint using a separate borderAccent palette.
2026-05-21 15:57:38 +09:00
can1357 dca24b61b1 feat(coding-agent): added shimmer animations to loader and progress bars
- Added a new shimmerText helper that computes a moving accent shimmer band across characters.
- Updated the interactive mode loader and slash-command ASCII bar renderer to use shimmer styling, with interrupt hints kept dim.
- Added tests for shimmer-enabled progress rendering and verified the visible bar output remains correct.
2026-05-21 15:47:45 +09:00
roboomp 83475cf7a4 fix(goals): repair goal state machine after interrupts and reloads
- get op now returns paused goals (was returning null when enabled=false)
- complete op now works on paused goals; previously required enabled=true
  which always failed after an interrupt set enabled=false
- create op now allowed after previous goal status is 'complete'; was
  incorrectly blocked by the same guard as 'dropped' check
- goal tool is re-added to the active tool set on session reload when a
  paused/active goal is persisted to disk; sdk.ts:1599 excludes 'goal'
  from initial active tools unconditionally, so restoreModeFromSession
  now re-adds it and saves #goalModePreviousTools for later cleanup
- goal_updated event for 'dropped' status now triggers #exitGoalMode
  before clearing goalModeEnabled, ensuring the previous tool set is
  restored when the agent drops a goal via the tool
- added 'resume' and 'drop' ops to goal tool schema and execute path
- updated goal.md prompt to document new ops and the paused-goal workflow

Fixes #1249
2026-05-21 05:39:06 +00:00
can1357 1e9949bf45 fix(coding-agent): resolved streaming preview order and line trimming
- Added isStreaming-aware diff options and trimmed-input handling for streaming/non-streaming previews.
- Added helpers to trim trailing partial lines and strip unmatched trailing `-`/`@@` blocks during streaming.
- Reworked apply_patch and hashline preview builders to keep files in input order with per-line added mapping.
- Added streaming preview regression tests and Unreleased Fixed changelog notes for partial-line and ordering fixes.
2026-05-20 16:06:08 +09:00
can1357 ea1a508217 fix(coding-agent): added safeguards for loop auto-submit during streaming or compaction
- Added reusable loop auto-submit deferral and readiness helpers for loop mode.
- Updated loop iteration flow to defer next prompts while the session is streaming or compacting.
- Added tests verifying loop submissions wait until compaction/streaming completes before resolving.
2026-05-20 13:34:09 +09:00
Can Bölük 899983859e Merge remote-tracking branch 'origin/main' 2026-05-19 18:18:34 +09:00