Commit Graph
6031 Commits
Author SHA1 Message Date
can1357 ea2f4b2557 feat(coding-agent): removed vim edit mode and migrated configs to hashline
- Removed vim edit mode and automatically map existing vim configurations to hashline mode.
- Deleted VimTool class, VimEngine implementation, and all vim-specific editing logic (2409 lines).
- Removed vim mode from EditMode union type, edit tool strategies, and configuration schemas.
- Deleted vim parser, command handler, buffer manager, and renderer modules.
- Updated documentation and tests to remove vim mode references and add deprecation mapping.
2026-05-26 13:16:59 +02:00
can1357 7f0208ac83 feat(coding-agent/eval): added console.table bridge to runtime text output
- Added a `console.table` helper in the JS prelude that forwards calls to the runtime `__omp_table__` hook.
- Implemented `__omp_table__` in the runtime to render tables through `node:console.Console` and emit text via `onText`.
- Added tests verifying `console.table` produced formatted table output and respected the optional columns filter.
2026-05-26 13:16:59 +02:00
can1357 8b41c87ded fix(typescript-edit-benchmark): resolved ts-edit-benchmark exit behavior
- Handled successful `main()` resolution by calling `process.exit(0)`.
- Preserved existing benchmark failure handling by logging the error and exiting with status 1.
2026-05-26 12:31:49 +02:00
roboompandcan1357 2590bd4e28 fix(ai): ignored bedrock auth sentinel
Ignored the agent auth sentinel when selecting Bedrock bearer auth so AWS credential sources still use SigV4.

Added regression coverage for sentinel forwarding with AWS_BEARER_TOKEN_BEDROCK and static AWS credentials.

Fixes #1399
2026-05-26 11:44:31 +02:00
can1357 7bea138322 Merge remote-tracking branch 'origin/farm/1fb66ca3/bedrock-bearer-token-precedence' 2026-05-26 11:31:34 +02:00
can1357 03f44da20f fix(ai): defaulted developer-role support to OpenAI and Azure hosts
- Updated OpenAI completions compatibility to set `supportsDeveloperRole` only for OpenAI and Azure hosts.
- Added regression tests for host-specific `supportsDeveloperRole` defaults across OpenAI, Azure, and alternative providers.
- Added a Moonshot regression test confirming reasoning message conversion emits the system role.
2026-05-26 11:31:12 +02:00
roboomp 2619eb092e fix(ai): honored bedrock bearer token precedence
Bedrock now sends AWS_BEARER_TOKEN_BEDROCK as Authorization: Bearer before resolving SigV4 credentials, so failing profile credential_process hooks cannot block bearer-token requests.

Added regression coverage for a default profile credential_process failure with AWS_BEARER_TOKEN_BEDROCK set.

Fixes #1399
2026-05-26 09:29:46 +00:00
can1357 732dae7b11 chore: bump version to 15.4.0 2026-05-26 11:26:08 +02:00
can1357 0d36a08c62 fix(ai/utils): validated Moonshot API key against models endpoint during login
- Updated Moonshot login validation to use a `models-endpoint` check instead of `chat-completions`.
- Changed the Moonshot key verification target to `https://api.moonshot.ai/v1/models` to avoid model-specific chat parameter validation failures.
2026-05-26 11:21:02 +02:00
can1357 44f85beb4a feat(ai): added websocket frame forwarding for raw SSE debug events
- Added helpers to synthesize RawSseEvent records for inbound, outbound, and malformed Codex WebSocket traffic.
- Passed onSseEvent through websocket transport and stream setup so frames are forwarded to the raw-SSE debug pipeline during streaming.
- Added a stream test that verifies outbound and inbound websocket frames are emitted with SSE-style raw lines for the debug viewer.
2026-05-26 11:21:02 +02:00
can1357 f9866798c0 feat(coding-agent): added hashline grammar for anchor ranges and payload
- Updated hashline markers to `¶` headers and `^/v/->` operators across constants, prompts, docs, and tests.
- Reworked hashline grammar and parser to support `ANCHOR<SIGIL>[INLINE_PAYLOAD]` with optional inline bodies and `A-B` ranges.
- Changed range and marker syntax from `..`/`"` to `-` and suffix `^/v/->` forms like `7v` and `A->`.
- Aligned `sameLineRange()` output and BOF/EOF handling so `|TEXT` remains cosmetic and payload now follows the op line.
- Centralized op-line detection by replacing local regex helpers with `isHashlineOpLineText` for payload terminator and bad-op checks.
2026-05-26 09:51:13 +02:00
can1357 99aac72ce5 fix(tui): fixed IME cursor sticking to viewport bottom after resize
- Adjusted `#emitViewportRepaint` to use `viewportTop + height - 1` as the cursor target row instead of clamping to `lines.length - 1`.
- This kept `#cursorControlSequence` row-delta math consistent with the hardware cursor after blank padding rows, preventing the IME cursor from staying stuck at the viewport bottom on height-grow resizes.
- Added a regression test and terminal cursor accessor to verify the focused `CURSOR_MARKER` row remains active after terminal expansion.
2026-05-26 09:33:07 +02:00
can1357 7fd7397790 fix: resolved Bun HTTP/2 retry matching and thinking-only turn filtering
- Expanded transient error matching for Bun HTTP2StreamReset, RefusedStream, and EnhanceYourCalm.
- Dropped thinking-only/error/aborted turns without text/toolCall, reset aborted tool-call map, and stored timestamps.
- Updated TUI render planning to track scrollback high-water and suppress suffix-scroll artifacts in non-multiplexer sessions.
- Added regression tests and changelog notes for Bun HTTP/2 retry handling, thinking-only filtering, and scrollback regressions.
2026-05-26 08:55:57 +02:00
can1357 82b3a83dd7 fix(utils): improved logger error serialization and transient error detection
- Added a custom JSON replacer that unwraps `Error` instances in logger output, preserving name, message, stack, cause, and enumerable fields.
- Updated uncaught-exception and unhandled-rejection logging paths to pass only `{ err }`, relying on the logger serializer for full error details.
- Extended transient socket-close matching to detect HTTP2 stream reset/refused/calm errors and added regression tests for logger error serialization behavior.
2026-05-26 08:07:08 +02:00
can1357 e1af85f1e7 fix(ai): resolved duplicated ai stream timeout handling via helpers
- Added shared timeout helpers in `sdk-stream-timeout` and removed duplicated inline stream timeout logic.
- Replaced inline provider timeout math with `resolveSdkTimeoutMs` and shared request-option builders.
- Added Codex websocket first-event and idle timeout settings via env-backed options.
- Updated Codex stream polling to apply per-phase time limits, return timeout errors, and fallback to SSE.
- Expanded `abortable-iterator` tests for preflight, in-flight, and leak cases around abort handling.
- Updated `streamFirstEventTimeoutMs` docs to document provider support and deprecated `streamIdleTimeoutMs`.
2026-05-26 07:48:30 +02:00
can1357 9e25783b5c Merge remote-tracking branch 'origin/farm/f3a184c3/terminal-scroll-position-jumps-during-ac' 2026-05-26 07:33:22 +02:00
can1357 d4288225fb Merge remote-tracking branch 'origin/farm/ece8a163/restore-provider-streaming' 2026-05-26 07:32:43 +02:00
can1357 3b60edd276 refactor(coding-agent/tools): removed output schema evaluator and simplified validator handling
- Deleted the `ValidationVerdict` type and `evaluateOutputAgainstSchema` API from the output schema validator.
- Updated `yield.ts` to bind `buildOutputValidator`'s error directly to `schemaError` during validator setup.
- Removed the obsolete evaluator tests and adjusted validation success fixture to match the raw summary input shape.
2026-05-26 07:28:42 +02:00
roboomp 94cdf8057f fix(ai): preserved azure responses timeout hint
Mapped streamFirstEventTimeoutMs onto Azure OpenAI Responses request timeout options so explicit caller deadlines are not ignored after removing provider-stream watchdogs.

Fixes #1392
2026-05-26 05:18:28 +00:00
roboomp ea0ca08e89 fix(ai): preserved responses request timeout hint
Mapped streamFirstEventTimeoutMs onto OpenAI Responses request timeout options so explicit caller deadlines are not ignored after removing provider-stream watchdogs.

Fixes #1392
2026-05-26 05:11:27 +00:00
roboomp dbd7cb84d7 fix(ai): handled pre-loop stream aborts
Checked provider abort signals at the start of each iteration so aborts fired between yielded stream events cannot be missed before the next iterator wait is armed.

Fixes #1392
2026-05-26 05:02:42 +00:00
roboomp e3f9b5b773 fix(ai): restored pi-style provider streaming
Removed OMP-owned first-event and idle watchdogs from provider stream consumption while preserving caller abort handling. Updated provider stream tests to assert slow/silent streams wait for provider output or caller abort instead of surfacing watchdog errors.

Fixes #1392
2026-05-26 04:55:00 +00:00
can1357 e0eae43fde feat(tools): added shared output schema validator for YieldTool
- Unified output schema construction and validation by adding buildOutputValidator and using it in YieldTool and task executor.
- Added MAX_SCHEMA_RETRIES so YieldTool now retries schema failures three times with hints before overriding.
- Updated failure handling to use shared summarizeValidationFailure and formatters for required-field reporting.
- Added tests for output-schema-validator and YieldTool covering malformed schemas and nested-array retry edge cases.
2026-05-26 06:34:30 +02:00
roboomp 1d0f59522a fix(tui): clamped stale cursor row after height changes
Terminals clamp the hardware cursor to the visible viewport on resize, but TUI committed cursor rows from the prior geometry. Subsequent relative cursor moves (diff/shrink/append-tail) then wrote to wrong rows, producing duplicate or shifted content on screen. Clamp `prevHardwareCursorRow` to `prevViewportTop + height - 1` in each emitter that uses relative cursor math, and add a regression for height + content storms.

Fixes #1295
2026-05-26 03:36:20 +00:00
can1357 27cc5a077b fix(ai,coding-agent): close OAuth lifecycle gaps from the AuthStorage rework
Centralizing OAuth refresh in AuthStorage (e6893515) introduced five
follow-on bugs surfaced by an audit of the commit; this fixes all of
them and updates the tests that relied on the old refresh seam.

1. packages/ai/src/auth-storage.ts (#tryOAuthCredential):
   For built-in providers the path went directly to `getOAuthApiKey`
   with the (possibly still-expired) selection.credential when the
   pre-refresh at line 2587 caught a transient error. `getOAuthApiKey`
   then threw the "expired … must be refreshed via AuthStorage"
   precondition error, which the disable classifier matched against
   `/expired.*refresh/` and soft-disabled the row. A single network
   blip during refresh could permanently kill a still-valid Anthropic /
   OpenAI / Gemini-CLI / Copilot credential. Built-in providers now
   route through the broker-aware single-flighted
   `#refreshOAuthCredential` first, so transient failures surface as
   network errors (5-min temp block) instead of definitive auth
   failures.

2. packages/ai/src/auth-storage.ts (#fetchUsageUncached):
   The usage refresh check only fired once `Date.now() >= expiresAt`,
   missing the 60-second skew that `getApiKey` honors. A token
   expiring inside the skew window was posted to the usage endpoint
   and 401'd mid-flight, briefly hiding quota in the UI. Aligned with
   `OAUTH_REFRESH_SKEW_MS`.

3. packages/coding-agent/src/web/search/index.ts (webSearchCustomTool):
   The CustomTool counterpart of WebSearchTool dropped sessionId so
   SDK callers that opted into `web_search` via toolNames lost
   per-session credential stickiness — multi-account users saw the
   provider round-robin between searches in the same session. Threads
   `ctx.sessionManager.getSessionId()` through to `executeSearch`.

4. packages/coding-agent/src/web/search/providers/perplexity.ts
   (findOAuthToken):
   `authStorage.getApiKey("perplexity")` returns runtime/config
   overrides, stored api_key credentials, OAuth bearers, and env keys.
   Filtering only env keys meant a config-pinned `pplx-…` API key was
   POSTed to `www.perplexity.ai/rest/sse/perplexity_ask` (the OAuth
   endpoint) instead of falling through to
   `api.perplexity.ai/chat/completions`, producing 401s. Switched to
   `getOAuthAccess` so only true OAuth bearers reach the OAuth
   branch; api_key credentials/overrides correctly fall through.

5. packages/ai/scripts/generate-models.ts:
   `getOAuthApiKey` was being called directly with possibly-expired
   credentials. The new contract throws on expired, the broad catch
   swallowed it, and the build silently fell back to bundled models
   instead of refreshing. Both helpers now route through
   AuthStorage's `getApiKey` / `getOAuthAccess`, which trigger the
   full broker-aware refresh pipeline.

Test updates:
- auth-storage-credential-disabled-event.test.ts,
  sdk-credential-disabled-bridge.test.ts: the `failOAuthRefresh`
  helper used to spy on `getOAuthApiKey` to inject invalid_grant.
  With refresh now happening before that helper, the spy never fired.
  Switched to spying on `refreshOAuthToken` so the simulated failure
  reaches the disable classifier.
- auth-storage-rotation.test.ts: stub `refreshOAuthToken` so the test
  doesn't hit a real OAuth endpoint when the seeded credential lands
  inside the 60s skew window.
2026-05-26 05:32:47 +02:00
can1357 69d73bf84f fix(ai): cast stop_reason to string for type compatibility 2026-05-26 05:30:07 +02:00
can1357 211a1aa98a fix(ai): surfaced fallback error message for Anthropic refusals without stop_details
- Handled the case where Anthropic sends a refusal/sensitive stop_reason but omits stop_details, previously falling through to a generic "unknown error."
- Added human-readable fallback messages per stop_reason type (refusal, sensitive, or raw value).
- Added test covering the null stop_details refusal scenario.
2026-05-26 05:28:37 +02:00
can1357 a6aee80fab Merge remote-tracking branch 'origin/farm/6f41b415/fix-cursor-empty-message' 2026-05-26 05:18:59 +02:00
can1357 1a23cac327 Merge remote-tracking branch 'origin/farm/0630b3aa/fix-subagent-lsp-disable' 2026-05-26 05:18:12 +02:00
can1357 eef35a1cb3 fix(ai): raised default first-event watchdog for google-gemini-cli streams
- Added optional per-provider fallback parameters to stream timeout helper functions so callers can widen default watchdog values safely.
- Threaded provider-specific lazy stream limits into stream creation and set Google Gemini CLI to a 300000ms first-event fallback by default.
- Added tests covering fallback defaults, env precedence, and global-default behavior for both idle and first-event timeouts.
2026-05-26 05:17:58 +02:00
roboomp b78d4ab11a refactor(tui): rewrote render loop around explicit intents
Split `#doRender` into a planner plus one emitter per intent: `initial`, `sessionReplace`, `historyRebuild`, `viewportRepaint` (optionally prefixed with an append-to-scrollback), `shrink`, `diff`, `noop`. Cursor, viewport, and scrollback state now flow through a single `#commit` checkpoint at the end of every emitter.

Fixes #1295
2026-05-26 03:15:52 +00:00
roboomp 0a3a48b92d fix(task): respected parent lsp disable for subagents
Combined task.enableLsp with the parent session enableLsp gate before spawning subagents, so --no-lsp remains authoritative even when subagent LSP is enabled in settings.

Fixes #1385
2026-05-26 03:13:28 +00:00
roboomp 28a0dc3ae4 feat(task): gated subagent LSP behind task.enableLsp setting
Added task.enableLsp (boolean, default false) and routed both regular and isolated subagent dispatch through it. Keeps subagents cheap by default while letting users opt in to LSP-aware delegation. Updated regression tests to cover the default-off, opt-in, plan-mode, and isolated paths.

Fixes #1385
2026-05-26 03:09:09 +00:00
roboomp 8948101e2b fix(task): forwarded parent enableLsp flag to subagents
Subagents now inherit the parent session's enableLsp value, so a top-level --no-lsp invocation propagates into spawned tasks instead of falling back to the executor's default of true.

Fixes #1385
2026-05-26 03:06:14 +00:00
roboomp 5ff1c747ce fix(task): inherited lsp for subagents
Removed the hardcoded subagent LSP disable flag so executor defaults and user settings control LSP availability. Passed the effective plan-mode agent definition into both regular and isolated subagent dispatch so plan-mode tool restrictions apply consistently.

Fixes #1385
2026-05-26 03:01:57 +00:00
can1357 d56c7fcfa8 fix(test): rewrite Kimi issue #957 test for new AuthStorage refresh flow
- packages/ai/test/issue-957-repro.test.ts now tests:
  - refreshKimiToken applies the 5-minute server-side skew (Kimi-specific)
  - AuthStorage refreshes kimi-code credentials inside its 60s skew window
- packages/ai/test/anthropic-stream-timeout.test.ts: raise the
  streamFirstEventTimeoutMs from 10ms to 5000ms so slow CI scheduling
  cannot fire the first-event watchdog before the mocked events arrive.
  The test still exercises the (1ms) idle path it was written for.

fix(web): allow Parallel extract via PARALLEL_API_KEY env var without storage

The fetch tool and YouTube scraper previously gated the Parallel extract
branch behind `storage && findParallelApiKey(storage)`. With no
AgentStorage the env key was never consulted, so callers that ran
without a per-session storage (e.g. ReadTool sessions in unit tests, and
in practice any caller that has only an env API key) silently fell back
to raw-html / no-ytdlp paths.

- findCredential/findParallelApiKey now accept null or undefined storage
  and rely solely on the env-first path when no storage is supplied.
- searchWithParallel/extractWithParallel mirror the same nullable shape.
- Drop the redundant `storage && ` guards in fetch.ts and youtube.ts;
  the inner findParallelApiKey call already returns null when no
  credential is available.
2026-05-26 04:50:01 +02:00
roboomp 1e4d5c1ae2 fix(tui): rebuilt resized history
Clear the viewport on the initial TUI paint so stale shell rows are not left onscreen. When a width change affects offscreen transcript rows, clear terminal history and replay the resized transcript so historical components do not remain in the old geometry.

Fixes #1295
2026-05-26 02:44:21 +00:00
roboomp d0dc40a19c fix(tui): preserved appends during offscreen refresh
When offscreen transcript changes require a viewport repaint in the same frame as appended output, emit the appended tail first so terminal history advances before repainting the visible rows.

Fixes #1295
2026-05-26 02:40:23 +00:00
can1357 8f6e1fa0dc Merge remote-tracking branch 'origin/farm/9ad9de48/fix-explore-agent-ref-jtd-keyword' 2026-05-26 04:36:34 +02:00
roboomp 2583d1bdbb fix(tui): replayed width reflows offscreen
Replay width-dependent offscreen changes so terminal scrollback receives resized rows, while pure appends and unchanged width resizes stay on bounded paths. Preserve multiplexer pane scrollback when callers request terminal-history replacement.

Fixes #1295
2026-05-26 02:31:39 +00:00
can1357 e689351597 fix(coding-agent): resolved OAuth token expiry flow in AuthStorage
- Centralized OAuth access lifecycle in `AuthStorage`, returning identity metadata and new access-result types.
- Added 60-second skew and strict expiry checks, returning undefined/throws for stale or expired OAuth credentials.
- Removed provider-local token refresh flows from Gemini, Gemini CLI, Antigravity, Kimi, and related OAuth helpers.
- Migrated web-search providers from `AgentStorage` to `AuthStorage` session-aware lookup with `authStorage`/`sessionId`/`signal` flow.
- Replaced `findAnthropicAuth`/DB auth lookup with `buildAnthropicAuthConfig` and explicit base-url override/env fallback ordering.
2026-05-26 03:59:13 +02:00
roboomp aa6dbc9c83 fix(coding-agent/prompts): renamed explore agent output ref field to path
`ref` is a JTD-reserved keyword (RFC 8927) used by the schema-reference
form, so the JTD-to-JSON-Schema converter on releases prior to 15.3.2
silently dropped it from the generated JSON Schema and required it at
the same time. Every explore-agent invocation then failed validation
with `schema_violation: files.0.ref: must not be present`.

The converter side was hardened in #1345 (shipped in 15.3.2). This
rename is defense-in-depth at the prompt level: the explore agent's
output contract no longer relies on the converter recognising a
user-named property that collides with a JTD keyword, and the field
name now matches what it actually carries.

Fixes #1379
2026-05-25 22:58:16 +00:00
roboomp db6c46d393 fix(ai): persisted cursor image turns in history
- Serialized image user content into Cursor root prompt history.
- Preserved image-only historical turns in Cursor conversation turn blobs.
- Added regression coverage for image-only history rebuilds.

Fixes #1376
2026-05-25 20:04:13 +00:00
roboomp 6e0df1b49a fix(ai): preserved cursor image-only turns
- Encoded image-only Cursor user turns as userMessageAction with selected image context instead of resumeAction.
- Added regression coverage for image-only Cursor payloads.

Fixes #1376
2026-05-25 19:54:40 +00:00
roboomp a3a471ecdb fix(ai): used cursor resume action for empty turns
- Sent Cursor resumeAction for empty or whitespace current user turns instead of throwing before the request was built.
- Added Cursor payload regression coverage for empty resume turns and normal user message turns.

Fixes #1376
2026-05-25 19:48:01 +00:00
can1357 cfabeeb17c feat(web): added Codex and Gemini web search providers with shared AgentStorage flow
- Added OpenAI Codex and Gemini web search provider options with updated setup/auth descriptions.
- Updated Codex OAuth flow to refresh near-expiry tokens during web_search and persist the refreshed credentials.
- Plumbed AgentStorage through search orchestrator, scrapers, and fetch paths so providers share session credentials.
- Refactored web provider and credential helpers to accept caller-provided AgentStorage and resolve keys synchronously.
2026-05-25 21:21:13 +02:00
Can BölükandGitHub fb863a5900 Merge pull request #1375 from can1357/farm/5745ef62/fix-bedrock-opus-4-7-reasoning
fix(ai): default Bedrock Claude thinking.display to summarized
2026-05-25 22:21:03 +03:00
can1357 4a44bd1e52 fix(pi-shell): added Sync bound to descendant termination helper
- Updated `terminate_new_descendants` to require the `Sync` marker on its hash-set hasher.
- This tightened async helper bounds without changing its termination-wave logic.
2026-05-25 21:20:23 +02:00
roboomp ee9deba239 fix(ai): defaulted bedrock claude thinking.display to summarized
Anthropic silently switched adaptive-thinking's display default to
"omitted" starting with Claude Opus 4.7, so the Bedrock provider
stopped surfacing any reasoning content — observed in the wild as
silent streams and timeouts on long reasoning runs.

Mirrors the existing direct-Anthropic behavior in this repo:

- For adaptive-thinking models that accept the field (Opus 4.7+),
  emit { type: "adaptive", display: "summarized" } by default.
- For older adaptive-thinking models (Opus 4.6, Sonnet 4.6+) that
  reject the field, keep emitting just { type: "adaptive" }.
- For budget-based Claude models, always set display.
- Expose BedrockOptions.thinkingDisplay ("summarized" | "omitted")
  so callers can opt out, and wire hideThinkingSummary into the
  bedrock-converse-stream case in stream.ts.

Fixes #1373
2026-05-25 19:08:00 +00:00
Can BölükandGitHub d201442a16 Merge pull request #1372 from can1357/farm/e4c67c73/fix-subagent-session-start-busy
fix(agent): prevent subagent session_start busy race
2026-05-25 21:59:38 +03:00