Commit Graph

3998 Commits

Author SHA1 Message Date
can1357 1a77322a4d fix(hashline): adjusted hashline anchor rejection messaging and guidance
- Updated the hashline mismatch error to describe anchor mismatches against the current file.
- Rewrote hashline tool instructions to clarify insert payload rules, anchor usage, and avoidance of fabricated hashes.
- Expanded stale-edit detection and tests to recognize the revised anchor-mismatch rejection wording.
2026-05-14 07:06:42 +02:00
can1357 b9b2c381f0 fix(coding-agent/goals): skipped goal accounting operations when accounting state was absent
- Added an internal accounting-state guard and used it to skip goal usage flushing when accounting was inactive.
- Updated goal abort handling to return early unless accounting or pause logic was required, then paused only a cloned active goal state before committing.
- Aligned related tests/types by tightening OpenAI helper typing and using Tool typings for the goal tool registry.
2026-05-14 06:53:21 +02:00
can1357 a086d0b98d docs(coding-agent): added bash tool restrictions for coreutils and I/O redirection
- Discouraged coreutils in favor of dedicated read/search/find/edit/write tools.
- Prohibited pipe truncation via head/tail since artifacts handle full output.
- Prohibited stderr redirection since stdout and stderr are already merged.
2026-05-14 06:53:21 +02:00
can1357 12115e4cdf fix(utils): excluded ASCII replacements inside HTML comments
- Added an HTML comment state tracker to prompt formatting.
- Updated ASCII symbol replacement to skip substitutions inside `<!-- ... -->` comment blocks across lines.
- Added tests that preserved comment text while converting symbols outside comments.
2026-05-14 06:40:50 +02:00
can1357 933058a241 feat(goals): added per-session goal mode with token budget tracking
- Added GoalRuntime with wall-clock and token accounting, budget steering, and lifecycle operations (create, pause, resume, drop, complete).
- Exposed goal tool as a hidden agent tool, activated only when goal mode is enabled.
- Integrated goal continuation loop in InteractiveMode with auto-submit between turns.
- Added status line segment and theme icons for goal mode state.
2026-05-14 06:40:41 +02:00
can1357 88e486be29 fix(coding-agent/modes): hardened context breakdown against absent session fields
- Hardened context usage accounting to tolerate missing session fields by defaulting skills and tools to empty arrays.
- Guarded message and system-prompt token counting with presence checks to avoid access errors on partial session objects.
2026-05-14 06:37:25 +02:00
can1357 6d00cc1f08 test(ai): added reasoning model helper for OpenAI response history tests
- Added getOpenAIReasoningModel to wrap the bundled gpt-5-mini model with a non-gpt-5 name in tests.
- Replaced all OpenAI responses test model constructions using gpt-5-mini with the new helper to bypass reasoning-model branching during payload assertions.
2026-05-14 06:23:55 +02:00
can1357 ad2e5c0578 refactor(coding-agent/exa): renamed tool detail field from response to raw
- Updated the Exa tool factory to emit details using a raw field rather than response.
- Updated the MCP wrapped Exa tool to emit details using a raw field rather than response.
2026-05-14 06:16:31 +02:00
can1357 71f3997afa fix(session): resolved session persistence flow to use sync write/read APIs
- Added sync truncation helpers to recursively prepare session entries and externalize image data.
- Reworked session persistence to use synchronous preparation plus `writeSync` with close-state checks.
- Added synchronous session-storage APIs and rerouted write paths to `writeLineSync`/`readTextSync`.
- Added `BlobStore.putSync`, migrated hashing to `Bun.SHA256`, and updated hash tests accordingly.
2026-05-14 06:12:41 +02:00
can1357 cf627d5577 docs(coding-agent/prompts): updated hashline prompt to clarify delta-only payloads
- Expanded the hashline tool rules to state that patch payloads should only contain newly added lines and must not duplicate existing content.
- Clarified that insertion and replacement operations affect only their specified targets, with adjacent lines remaining unchanged.
- Reinforced widening edits to self-contained syntactic units before selecting the smallest patch operation.
2026-05-14 05:58:25 +02:00
can1357 8fc5b78f30 feat(read): added comma-separated scatter gather line selector support
- Extended selector regex and parser to accept ranges like `:5-16,960-973`.
- Ranges are sorted and merged automatically before reading.
- Out-of-bounds ranges surface as inline notices instead of errors.
- Added `#readLocalFileMultiRange` and `#buildInMemoryMultiRangeResult` for file, archive, notebook, and internal URL targets.
2026-05-14 05:58:25 +02:00
can1357 cf4173a100 feat(exa): replaced raw JSON responses with human-readable formatting
- Added formatGenericResponse to handle objects, arrays, MCP content blocks, and primitives.
- Applied formatted output to MCPWrappedTool, createExaTool, and propose-changelog tool.
- Replaced raw response in details field with structured response object.
2026-05-14 05:58:25 +02:00
can1357 fe7b3d7005 refactor(coding-agent): removed intent property from WriteTool 2026-05-14 05:58:25 +02:00
can1357 3592865fe1 fix: plan mode types 2026-05-14 05:38:09 +02:00
can1357 786c25e6c7 fix(coding-agent): resolved coding-agent cli --help startup init cycle
- Fixed root `cli --help` startup by preventing the config/model-registry initialization cycle.
- Extracted config validation, migration, and loading logic from config.ts into config/config-file.ts.
- Added ConfigFile helpers for migration, validated JSON/JSONC/YAML loading, status caching, and reset.
- Added a regression test that runs `cli.ts --help` with temp HOME/XDG env paths and expects exit code 0.
2026-05-14 05:35:16 +02:00
can1357 ef5cbef51f feat(coding-agent): added resolve-based plan approval flow in coding-agent
- Removed ExitPlanModeTool and deleted exit-plan-mode docs/tests, dropping the old approval contract outputs.
- Replaced plan-mode approval flow from exit_plan_mode to resolve across session, SDK, controllers, and discovery.
- Added standing resolve handler accessors and updated resolve routing for queued or standing approval handlers.
- Added PlanApprovalDetails and enforced normalized, validated approval titles with readable plan-file requirements.
- Extended resolve schema and invocation signatures with optional extra metadata and reason trimming behavior updates.
- Updated plan and resolve prompts and changelog guidance to require resolve action, reason, and extra.title for apply/discard.
2026-05-14 05:33:30 +02:00
can1357 0b62f2971b fix(ci): restore @napi-rs/cli dep and align tests with current types
The earlier exports/cleanup refactor removed @napi-rs/cli from
packages/natives devDeps, breaking every native job. It also left two
test files calling private symbols and a stale KeyId literal:

- packages/natives: re-add @napi-rs/cli (catalog) so node_modules/.bin/napi
  exists for build-native.ts.
- test/acp-agent.test.ts: import ACP_BOOTSTRAP_RACE_GUARD_MS from
  modes/acp/acp-agent (previously implicit via mass-export refactor).
- test/silent-abort-overlay-render.test.ts: lowercase 'Ctrl+S' -> 'ctrl+s'
  to match the KeyId union.
2026-05-14 05:12:07 +02:00
can1357 1fb59df0bb fix(edit): stripped all leading @ prefixes from hashline input headers
- Updated parseHashlineInputPreviewHeader to strip all leading "@" markers before resolving the preview path, matching existing parser behavior.
- Added a regression test in edit renderer tests confirming both canonical "@@" and longer "@" runs render as clean file paths without extra "@" characters in titles.
2026-05-14 05:06:00 +02:00
can1357 ba47b0e32f fix(tools): recovered malformed conflict:// paths during write conflict resolution
- Updated conflict URI parsing to accept `path:conflict://N` and record the removed prefix in `recoveredPrefix`.
- Updated write conflict handling to resolve single or wildcard IDs through shared helpers and append a recovery note when a malformed prefix was stripped.
- Added regression tests for recovered prefixes and end-to-end write-path recovery and documented the change in the changelog.
2026-05-14 05:03:04 +02:00
Can Bölük 4de99a481b Merge pull request #1063 from chuaaron/fix/edit-format-reminder
fix(edit): add format reminder to hashline prompt
2026-05-14 05:02:52 +02:00
can1357 d62480dc65 fix(edit): slim format-reminder and use configured separator
- Drop duplicated op listing from the reminder; <ops> already defines
  the four shapes one block above.
- Replace hardcoded `~` with the {{hsep}} helper so the reminder
  tracks PI_HL_SEP / HL_EDIT_SEP overrides, matching the rest of
  hashline.md and addressing Codex review on #1063.
- Shrink the WRONG/RIGHT example (smaller anchor, no padding runs)
  since the reminder's only job is contrasting on-line vs next-line
  payload placement.
2026-05-14 05:01:55 +02:00
Can Bölük 8f1d98fa38 Merge branch 'main' into fix/skill-chip-and-silent-abort 2026-05-14 04:51:41 +02:00
Can Bölük 57ce77fa79 Merge pull request #1042 from tsagi2045/fix/status-line-context-pct
fix(coding-agent): align status-line context% with /context command output
2026-05-14 04:49:11 +02:00
Can Bölük ed88f0f90d Merge branch 'main' into fix/context-window-fallback 2026-05-14 04:48:16 +02:00
Can Bölük 26931fe8ce Merge pull request #1055 from jiwangyihao/fix/browser-worker-startup-errors
fix(browser): surface tab worker startup errors
2026-05-14 04:47:31 +02:00
Can Bölük 3d2bbe5e8f Merge branch 'main' into fix/browser-stealth-target-setup 2026-05-14 04:46:30 +02:00
Can Bölük 7a50b9ed58 Merge branch 'main' into fix/token-display-exclude-cache-read 2026-05-14 04:45:05 +02:00
Can Bölük 3ad9255b18 Merge branch 'main' into dmarsh/acp-thinking-level-push 2026-05-14 04:43:55 +02:00
Can Bölük 9530f94a36 Merge pull request #1061 from ldx/fix/mcp-oauth-persist-dynamic-client
fix(coding-agent): persist dynamically registered MCP OAuth client_id
2026-05-14 04:43:08 +02:00
Can Bölük 38255a4e6e Merge pull request #1062 from enieuwy/fix/copy-handoff-context
Fix /copy fallback for handoff context
2026-05-14 04:42:53 +02:00
can1357 1ea87b26bc feat(coding-agent): added hidden skill flag for system prompt filtering
- Added optional `hide` metadata to skill capabilities so `SKILL.md` frontmatter intent is preserved when skills are loaded.
- Filtered system prompt skill rendering to exclude `hide: true` skills from the `<skills>` listing while keeping them loadable.
2026-05-14 04:38:14 +02:00
can1357 f1f6516056 refactor: reorganized exports and removed obsolete helper branches
- Removed export leakage by demoting many helper and const symbols to module-local scope.
- Renamed underscore-prefixed internals and cache fields, then updated related references and `satisfies never` checks.
- Deleted obsolete logic branches and helpers, including harmony-stream interruption flow and unused benchmark runtime helpers.
- Updated Biome config and manifests by broadening lint coverage and removing an unused `@napi-rs/cli` dev dependency.
- Adjusted tests and utilities to use renamed test helpers and remove redundant private test-only helpers/locals.
2026-05-14 04:36:19 +02:00
Aaron Z 58d7723c79 fix(coding-agent/edit): add format reminder to hashline prompt to prevent anchor+content on same line
Models frequently write '+ ANCHOR| CONTENT' instead of '+ ANCHOR'
followed by '~CONTENT' on the next line. Add a compact FORMAT block
between </ops> and <rules> with a WRONG/RIGHT example that directly
addresses this failure mode.
2026-05-14 10:03:33 +08:00
enieuwy fa1d83e527 Fix copy fallback for handoff context 2026-05-14 09:41:06 +08:00
can1357 6b6cc417f2 test(coding-agent/acp): bumped ACP stdout-hygiene timeout to 60s for slow CI runners 2026-05-14 03:26:25 +02:00
cognitive c118eacdaa fix: gate SILENT_ABORT_MARKER at three unguarded render sites
Codex review flagged that the silent-abort sentinel
("__omp.silent_abort__") persists into AssistantMessage.errorMessage
but three downstream consumers render errorMessage verbatim:

- session-observer-overlay.ts: renders "✗ Error: __omp.silent_abort__"
  when content is empty (confirmed user-visible today)
- print-mode.ts: writes marker to stderr and exits non-zero (latent;
  plan-mode→compact not reachable from print mode today, but unguarded)
- acp-agent.ts: emits marker as agent_message_chunk text to ACP
  clients when message has no other notifications (latent)

Add isSilentAbort() guard at each site. Extend the SILENT_ABORT_MARKER
consumer list in messages.ts doc comment to include all six consumers.
Add regression tests: overlay (2 tests), print-mode (2 tests), ACP
replay (1 test).

Op: correct
Restores: spec:silent-abort-marker-never-surfaces
2026-05-13 23:58:13 +00:00
Vilmos Nebehaj a7f73ee645 fix(coding-agent): persist dynamically registered MCP OAuth client_id
When an MCP server uses OAuth Dynamic Client Registration (RFC 7591) and
no client_id is pre-configured, MCPOAuthFlow registers a fresh public
PKCE client on each authorize, captures the issued client_id into a
private field, then discards it once the flow object goes out of scope.
At refresh time, MCPManager#resolveAuthConfig calls refreshMCPOAuthToken
with auth.clientId from mcp.json — which is empty for these servers —
so providers that require client_id on the refresh grant (e.g. Linear at
mcp.linear.app/token) reject with HTTP 401 invalid_client. The user is
forced to /mcp reauth manually every time the access token expires.

This change threads the resolved/registered client credentials back out
of the OAuth flow and persists them into mcp.json so refresh has what
it needs indefinitely:

- MCPOAuthFlow exposes resolvedClientId / registeredClientSecret getters.
- MCPCommandController#handleOAuthFlow returns OAuthFlowResult with
  credentialId + clientId + clientSecret, populated from the flow's
  post-login state.
- The initial-connect non-wizard path and /mcp reauth path persist the
  returned client credentials into both auth.{clientId,clientSecret}
  (used at refresh) and oauth.{clientId,clientSecret} (used by future
  /mcp reauth to skip re-registration).
- The wizard's onOAuth callback signature now returns the same shape;
  #launchOAuthFlow folds the registered credentials into wizard state so
  the final mcp.json entry built by #buildServerConfigWithAuth includes
  them under auth.{clientId,clientSecret}.

Servers that configure a static oauth.clientId in mcp.json (Notion,
Slack, Datadog) are unaffected: #tryRegisterClient short-circuits, the
returned clientId equals the configured one, and the write-back is a
no-op.

Adds two MCPOAuthFlow unit tests covering both paths.
2026-05-13 15:39:04 -07:00
David Marshall b626609314 refactor(coding-agent/acp): extracted ACP_BOOTSTRAP_RACE_GUARD_MS and consolidated race notes
/simplify pass on 4882d1e38. Three small cleanups, no behavior change.

* Extracted the inline 50ms bootstrap-race guard into an exported
  ACP_BOOTSTRAP_RACE_GUARD_MS constant at the top of acp-agent.ts.
  Source uses it in the #scheduleBootstrapUpdates setTimeout. Tests import
  it and call a new waitForBootstrapGuard() helper (constant + 30ms slack
  for setTimeout drift) instead of three hardcoded Bun.sleep(80) sites —
  tests now bind to the source-of-truth instead of dueling magic numbers.
* Consolidated four block comments that all narrated the same race story
  into one canonical explanation at the install site (#scheduleBootstrapUpdates).
  Field declaration, #registerPreparedSession, and the setSessionConfigOption
  handler keep brief one/two-line pointers. Net change is roughly 30 lines
  of comments removed without losing the diagnosis.
* Trimmed the handler-site thinkingHandledBySubscription comment from six
  lines to three; the local-variable name carries the intent.

Verified:
* bun test test/acp-agent.test.ts: 11/11 pass
* biome check on touched files: clean
* No behavior change (no test had to be updated)

Co-Authored-By: omp <noreply@oh-my-pi.dev>
2026-05-13 16:43:45 -05:00
David Marshall 4882d1e386 fix(coding-agent/acp): deferred thinking-level lifetime subscription until after bootstrap-guard
Addresses codex review on #1060: an extension session_start handler that
calls setThinkingLevel via the exposed extension action (line 1541) would
have run BEFORE #registerPreparedSession set the record into #sessions and
BEFORE the session/new response was delivered to the client, causing
config_option_update to be pushed for a session id the client did not yet
know about. This is the exact race that #scheduleBootstrapUpdates already
documents and guards for available_commands_update / session_info_update
(Zed's 'Received session notification for unknown session' drop).

Moved the session.subscribe(...) installation out of #registerPreparedSession
and into #scheduleBootstrapUpdates's 50ms timer callback so the lifetime
subscription shares the same response-delivery guard as the existing
bootstrap notifications. The pre-bootstrap thinking level is still
communicated to the client through the response payload's configOptions
(newSession / loadSession / resumeSession / unstable_forkSession all return
it), so no state is lost; it is only the notification that is deferred.

For client-driven setSessionConfigOption({thinking}) the handler now only
skips its own push when the lifetime subscription is already installed.
Pre-bootstrap the handler keeps pushing (the client knows the session id
because they passed it in), post-bootstrap the subscription pushes
exactly once. No double-push, no missing pre-bootstrap notification.

Tests:
- updated existing pushes-config-option-update test to await past the 50ms
  bootstrap timer before driving the internal setThinkingLevel
- updated the single-config_option_update-per-setSessionConfigOption test
  the same way
- added 'suppresses lifetime config_option_update during the bootstrap
  window' regression that drives setThinkingLevel synchronously after
  newSession and asserts zero notifications, then asserts notifications
  resume after the bootstrap timer fires
- bun test test/acp-agent.test.ts: 11/11 pass

Co-Authored-By: omp <noreply@oh-my-pi.dev>
2026-05-13 16:34:54 -05:00
David Marshall c7722838b7 fix(coding-agent/acp): pushed config_option_update on every thinking-level change
ACP clients (Zed, etc.) only received `config_option_update` notifications
when they themselves drove the change via `session/set_session_config_option`.
Internal thinking-level updates (slash commands, automatic model-driven
adjustments, extension UI) bypassed the notification path, so client config
panels went stale until the next user-initiated change.

AgentSession now emits a `thinking_level_changed` event from
`setThinkingLevel`, and AcpAgent installs a session-lifetime subscription on
each managed session that pushes a fresh `config_option_update` whenever the
event fires — independent of prompt-turn lifecycle. The
`session/set_session_config_option` handler no longer pushes its own
notification for the `thinking` config (lifetime subscription covers it);
the response still returns fresh `configOptions` so callers see the new
state synchronously. Subscriptions are released in `#disposeSessionRecord`.

Also consolidated four duplicate `config_option_update` send sites into a
new `#pushConfigOptionUpdate(record)` helper.

Tests: added two cases to `test/acp-agent.test.ts` — one verifying internal
`setThinkingLevel` calls produce a `config_option_update` and a no-op
re-set produces none, and one verifying client-driven
`setSessionConfigOption(thinking, …)` produces exactly one notification.

Co-Authored-By: omp <noreply@oh-my-pi.dev>
2026-05-13 16:14:18 -05:00
can1357 453071d34d fix(coding-agent): restored coordinate-mapping dimension note and made bash SGR test color-mode agnostic
- Restored formatDimensionNote bracket form '[Image: original WxH, displayed at WxH. Multiply coordinates by S to map to original image.]' that tests assert. The Bun 1.3.14 refactor regressed it to a less informative 'Image resized from …' line.
- Broadened bash-sixel-render multi-line styling assertion to accept both truecolor (38;2;) and 256-color (38;5;) SGR runs so CI runners with TERM=dumb don't fail. The contract being tested — every line carries its own SGR — is independent of color depth.
2026-05-13 20:43:03 +02:00
Miroslav Drbal 8c77d2b15a fix(coding-agent): copy cost into async task progress on completion
The async job completion path copied durationMs, tokens, and extractedToolData
from SingleResult back into the AgentProgress object, but missed cost.
Add progress.cost = singleResult?.usage?.cost.total ?? 0 to the same block.
2026-05-13 20:19:53 +02:00
Miroslav Drbal 5cc8095cd1 refactor(coding-agent): extract appendAgentStats helper in render.ts
Eliminates the three-way duplication of toolCount/tokens/cost stat
appending across renderAgentProgress (running), renderAgentProgress
(completed), and renderAgentResult.
2026-05-13 20:07:09 +02:00
Miroslav Drbal 08551b83a5 fix(coding-agent): show cost in final subagent result line
renderAgentResult (rendered after the task tool resolves) was missing the
cost display present in renderAgentProgress. Read cost directly from
result.usage?.cost.total which is already available on SingleResult.
2026-05-13 20:04:55 +02:00
Miroslav Drbal 084488b680 fix(coding-agent): exclude cacheRead from token display, add per-subagent cost
Token counter (token_total status-line segment, subagent progress tree,
session-observer stats line) previously included cacheRead in its cumulative
sum. With Anthropic prompt caching, cacheRead per turn equals the full cached
context, so summing across N turns gives N*context_size -- a session with a 1M
context and 5 turns showed ~5M tokens despite no compaction occurring.

Fix: display shows input + output + cacheWrite per turn. cacheWrite is kept
because each byte is written once; cacheRead re-reads the same context every
turn. Dedicated cache_read/cache_write status-line segments still show cache
activity; billing cost is unaffected.

Also adds per-subagent cost display (dollar amount, statusLineCost color)
accumulated incrementally from message_end events. Hidden when cost is zero
(subscription/OAuth providers). Brings token and cost display in line with
what Claude Code shows per-agent.
2026-05-13 19:26:38 +02:00
can1357 c7d04f3a13 fix(coding-agent): constrained bash cwd auto-detect regex to single-line cd commands
- Updated BashTool's leading `cd` regex to stop matching newline characters so cwd extraction only applies to a single-line `cd ... &&` prefix.
- Added a regression test for multiline commands with a later-line `&&` to ensure each line of the script executes normally.
2026-05-13 19:19:50 +02:00
jiwangyihao 11a19eb8d4 fix(browser): bound stealth target setup during tab open
Keep the active page stealth setup synchronous, but make the broader CDP target UA override sweep selective and best-effort. Non-page or ephemeral Chrome targets can otherwise block worker initialization long enough for browser.open to hit the tool timeout before the tab worker sends ready.

Fixes #1053
2026-05-14 01:19:01 +08:00
cognitive e6cce9147c Merge branch 'main' into fix/skill-chip-and-silent-abort 2026-05-14 02:08:45 +09:00
jiwangyihao 8830b2e367 fix(browser): surface tab worker startup errors
Forward worker error and messageerror events while acquireTab waits for the initial ready/init-failed response. This prevents async worker module-load or early startup failures from being reported only as a generic tab worker init timeout.
2026-05-14 00:34:55 +08:00
can1357 7fd2a7b309 fix(coding-agent/tools): highlighted multi-line bash commands in result rendering
- Added a new formatBashCommandLines helper that syntax-highlighted each command line and applied the dim prefix only to the first line.
- Updated the shell renderer to emit command output as line-based entries instead of a single dimmed string.
- Extended the bash renderer test to verify multi-line commands keep ANSI styling on every rendered line.
2026-05-13 18:15:57 +02:00