Commit Graph

494 Commits

Author SHA1 Message Date
can1357 da636e3f51 feat(coding-agent): enabled clickable image and path links across chat and tools
- Added image-reference rendering to make `[Image #N]` placeholders clickable in chat.
- Added MIME-aware image blob materialization with extensioned sidecar paths.
- Added clickable path, line, and URL hyperlinks for read, search, and fetch outputs.
- Hardened OSC8 hyperlink emission with URI validation and control-byte/idempotency checks.
2026-06-05 23:38:22 +02:00
roboomp 7a76333d93 style: bun run fix 2026-06-05 18:14:45 +00:00
roboomp bc55af78ad fix(github): revalidated cwd repo before trusting run_watch head
The no-selector run_watch guard was using resolveDefaultRepoMemoized via tryResolveCurrentRepo, so a long-lived process could validate against a stale cwd-to-repo cache entry after the checkout or GitHub remote at that path changed. That allowed the guard to trust the current HEAD for an explicit repo based on the old cached repository.

Add a fresh best-effort cwd repo lookup for safety checks and use it before deriving branch/HEAD. Cached lookup remains for search default scoping where stale data only affects a convenience fallback. Added a regression test that populates the cache, changes the mocked repo at the same cwd, and asserts run_watch rejects before issuing API calls.

Refs #1949 #1951
2026-06-05 18:14:40 +00:00
roboomp c46cfb252a style: bun run fix 2026-06-05 18:10:23 +00:00
roboomp c10809faec fix(github): accepted case-only run url repo matches
resolveGitHubRepo rejected calls that supplied both an explicit repo and a full Actions run URL when the two owner/repo slugs differed only by casing. GitHub repository paths are case-insensitive, so this was the same class of false mismatch as the cwd guard fixed earlier.

Compare repo slugs through a shared ASCII case-insensitive helper and use it for both the run-URL consistency check and the cwd guard. Added a regression test for repo=cagedbird043/cxf with a run URL under CagedBird043/CXF.

Refs #1949 #1951
2026-06-05 18:10:18 +00:00
roboomp 1f32b8aaf9 fix(github): compared run_watch repo guard case-insensitively
GitHub owner/repo slugs are case-insensitive; `gh repo view` returns
the canonical casing while callers may pass any casing. The new guard
used strict equality, so a caller in the correct repo who typed
`owner/repo` while the canonical form was `Owner/Repo` was forced to
pass a redundant `branch`/`run` selector. Normalize both sides via
toLowerCase() before deciding the cwd is a different repository.

Regression test covers the casing-only match.

Refs #1949 #1951
2026-06-05 18:06:39 +00:00
roboomp 8135c91f3d style: bun run fix 2026-06-05 18:02:51 +00:00
roboomp 31950067f1 fix(github): honored explicit repo in run_watch instead of falling back to cwd
executeRunWatch passed undefined for the explicit `repo` to
resolveGitHubRepo, so a call like
`{op: "run_watch", repo: "owner/cxf", branch: "main"}` from a nested
or umbrella workspace silently fell through to `gh repo view` in cwd
and streamed `watching <sha> on <cwd-repo>` against the wrong
repository.

Route params.repo through resolveGitHubRepo so the explicit owner/repo
wins over both cwd inference and run-URL inference. When no `branch`
or `run` selector is given, refuse to derive the watched commit from
`git HEAD` unless the cwd actually points at the resolved repo —
otherwise raise a ToolError telling the caller to pass `branch` or
`run` instead of silently rebinding to an unrelated commit.

Also deduped resolveSearchRepoScope's best-effort cwd resolution into a
shared tryResolveCurrentRepo helper used by the new guard.

Fixes #1949
2026-06-05 18:02:45 +00:00
can1357 26ea8202ec Merge remote-tracking branch 'origin/farm/6449817e/package-omp-docs' 2026-06-05 11:44:34 +02:00
can1357 9151ce9623 Merge remote-tracking branch 'origin/farm/9e76efd7/task-fallback-sync-no-async-manager' 2026-06-05 11:43:28 +02:00
can1357 88703a4ebb feat(dry-balance): added live bench mode for OAuth accounts
- Added `getOAuthAccesses` to resolve each stored credential once.
- Sent one live request per account, reporting TTFT and TPS.
- Streamed per-account progress with interactive status lines.
2026-06-05 11:41:07 +02:00
roboomp de21a28e43 fix(task): fallback to sync when AsyncJobManager is unavailable
When `async.enabled` is true but `AsyncJobManager.instance()` returns
`undefined` (orphaned-session state, host that never wired one up, etc.),
the `task` tool was returning a hard error and was unusable for the rest
of the session — even though the existing sync codepath (`#executeSync`,
which still parallelizes via `mapWithConcurrencyLimit`) was right there.

Fall back to `#executeSync` instead and emit a `logger.warn` so the
missing-manager state stays diagnosable. Background/job-poll semantics
are lost in this degraded mode, but the tool keeps working.

Fixes #1922
2026-06-05 08:54:49 +00:00
roboomp 61c26af62a fix(coding-agent): expanded omp docs search alias
Handled omp://docs as an embedded documentation search root alongside omp://.

Added regression coverage for searching embedded docs through the docs alias.

Fixes #1898
2026-06-05 03:44:50 +00:00
roboomp aacf29e1de fix(coding-agent): kept exa mcp fallback out of auto chain
Reviewer noted that an unconditional ExaProvider.isAvailable steered the auto chain into the public MCP fallback before any later-configured provider could run. Restored the credential-gated isAvailable, then split out isExplicitlyAvailable so resolveProviderChain still routes an explicit Exa selection through MCP without affecting other providers.\n\nRefs #1860
2026-06-04 13:28:14 +00:00
roboomp cb2d5b859a fix(coding-agent): restored exa mcp fallback
Restored Exa's unauthenticated MCP fallback when neither auth storage nor EXA_API_KEY provides credentials. Preserved API-key search ordering and bounded the MCP request with the web-search hard timeout. Updated provider copy and regression coverage for the no-key path.\n\nFixes #1860
2026-06-04 13:18:08 +00:00
roboomp 7a1280784e fix(tools/ssh): rendered multiline remote commands in a framed body block
The SSH tool renderer fed the raw command into renderStatusLine's
description, so any newline in the remote command expanded the
single-line tool header — the bordered output block then opened
mid-command and the rest of the SSH cell rendered against a broken
frame.

The renderer now keeps only [host] in the header and renders the
full command (with a dim $ prefix and tab sanitization) as its own
framed section above Output, matching the bash renderer's shape.

renderStatusLine also flattens CR/LF in title, description, meta,
and badge labels so no future caller can accidentally produce a
multiline tool header.

Covered by:
- test/tools/ssh-render.test.ts: multiline command stays out of
  the header and every command line is present in the body, for
  both renderCall and renderResult.
- test/tui/status-line-newline-guard.test.ts: embedded LF, CRLF,
  and lone CR in description/meta are flattened to spaces.

Fixes #1828
2026-06-04 07:44:52 +00:00
Can Bölük 8596f08af0 Merge pull request #1808 from GratefulDave/fix/search-optional-paths
fix(search): default paths to workspace root instead of hard-failing
2026-06-04 06:07:03 +03:00
can1357 7f271f9b9d feat(coding-agent): added native selection markers to ask dialogs
- Added `selectionMarker`, `checkedIndices`, and `markableCount` options to render radio/checkbox glyphs per row.
- Moved checkbox rendering from inline label prefixes into the selector component.
- Kept trailing control rows like "Other"/"Done" on the plain cursor.
2026-06-04 03:43:17 +02:00
can1357 bc5eeef398 feat(coding-agent): tagged read-only agents in task tool description
- Added `isReadOnlyAgent` and `READ_ONLY_TOOL_NAMES` to classify agents.
- Marked read-only agents and forbade edits, commands, and reasoning offload.
- Added tests for capability classification and description rendering.
2026-06-04 03:24:41 +02:00
David Andrews (LexGenius.ai) 89a60a6613 fix(search): default paths to workspace root instead of hard-failing
The `search` tool required `paths` via a strict `union([string,
array.min(1)])`, so any call that omitted `paths` (or passed an empty
array) was rejected at schema validation with `paths: Invalid input`
and never ran — turning a recoverable "no scope given" into a fatal
tool-call failure.

Make `paths` optional and default an omitted/empty value to the
workspace root (`.`), matching the documented prompt contract. Behavior
is unchanged when paths are supplied. Adds regression coverage for the
omitted and empty-array cases.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-03 20:59:43 -04:00
can1357 dc4aeb7b88 refactor(coding-agent): renamed todo_write tool to todo
- Renamed `TodoWriteTool` to `TodoTool` and its source/prompt files.
- Updated tool registration, schema, renderers, and gating to `todo`.
- Adjusted cursor provider native tool names and tests to match.
- Renamed strike-animation constants and `todo-error-reminder` type.
2026-06-04 02:45:30 +02:00
can1357 b1b4b0c0ed feat(coding-agent/tools): allowed .. aliases for line range selectors
- Extended line selector parsing in path-utils to accept `..` as a forgiving alias for `-`, with `..` normalized during chunk parsing.
- Updated selector-matching regexes for file selectors and internal URL selectors to recognize alias-style ranges in single chunks and comma-separated lists.
- Added tests covering `N..M`, `N..`, mixed separators, inverted-range errors, and path-splitting behavior with `:N..M` selectors and `foo:../bar.ts` paths.
2026-06-04 01:35:39 +02:00
can1357 ea105b4211 refactor(packages/coding-agent): reorganized notification flow and tests
- Updated completion and ask notifications to pass structured payloads.
- Updated completion and ask notifications to include explicit message metadata fields.
- Adjusted abort-guard and retry-capability tests for the new notification/options behavior.
2026-06-04 00:59:59 +02:00
can1357 8647ab6883 fix(fetch): repaired collapsed URL scheme from path normalization
- Restored `https:/` → `https://` before URL parsing and detection.
- Prevented path-normalized URLs from falling through to filesystem lookup.
2026-06-03 23:03:44 +02:00
can1357 9a544b6ee0 feat(coding-agent): added radio markers for single-choice ask options
- Rendered single-choice questions with circular radio glyphs instead of checkboxes.
- Kept rectangular checkboxes for multi-select questions.
- Added radio.selected/unselected symbols to unicode, nerd-font, and ASCII presets.
2026-06-03 22:21:06 +02:00
zolszabo 55f0d97f0b feat(coding-agent): name discoverable built-in tools in search_tool_bm25 description
Surface the hidden discoverable built-in tool names (write, find, search, lsp, task, ...) in the search_tool_bm25 description when tools.discoveryMode is "all", so a model can form a targeted BM25 query by name instead of guessing or falling back to shell. mcp-only mode is unchanged (no built-ins advertised) and the total-tools count still includes them.
2026-06-02 17:55:28 +02:00
can1357 fbed7d1787 fix: expanded tool argument parsing to accept delimiter-separated paths
- Expanded path parsing to split top-level comma, semicolon, and whitespace entries.
- Updated find/search and scope resolution to apply delimiter expansion before path-spec validation.
- Updated read tool fallback to try split path parts before raising missing-path errors.
- Coerced bare string arguments into singleton arrays for array-typed schemas.
2026-06-02 11:14:02 +02:00
roboomp b3bcf966ee fix(coding-agent): resolve exa credentials through auth storage
ExaProvider.isAvailable() and searchExa() now consult AuthStorage so Exa credentials configured through the broker/credential store work alongside EXA_API_KEY, matching the other API-key search providers.

Refs #1695
2026-06-02 08:00:35 +00:00
roboomp 963bdebf53 fix(coding-agent): require exa api key for web search
Exa web search no longer advertises availability without EXA_API_KEY and searchExa fails before attempting unauthenticated MCP.

Fixes #1695
2026-06-02 07:54:19 +00:00
Can Bölük 9488cb52fe Merge branch 'main' into main 2026-06-02 09:28:09 +03:00
can1357 1a1c473e7f refactor(web-search): fold Kagi V1 into the kagi provider
Replace the sunset V0 Search API with V1 (POST /api/v1/search) under the
existing `kagi` provider id instead of shipping a parallel `kagi-v1`
provider. Credentials still resolve through the shared AuthStorage broker
(Bearer token, KAGI_API_KEY, /login kagi), and recency now maps to a
UTC-deterministic filters.after date.

- Merge V1 client into src/web/kagi.ts (categorized result buckets, direct
  answer, related/adjacent questions)
- Keep classifyProviderHttpError mapping for auth/quota signals
- Drop the kagi-v1 entries from the provider registry, order, type union,
  and settings schema
- Consolidate tests into web-search-kagi.test.ts
2026-06-02 08:26:55 +02:00
can1357 b522fde56d perf(sqlite-reader): replaced full COUNT(*) scan with bounded row probing
- Added ROW_COUNT_PROBE_CAP to limit rows scanned when counting tables, preventing JS thread freezes on large databases.
- Used sqlite_stat1 estimates for tables exceeding the cap; exact counts only for provably small tables.
- Introduced TableRowCount type with exact/estimate/atLeast variants reflected in rendered output.
2026-06-02 05:24:21 +02:00
can1357 fbdc064186 feat(lsp): added session-scoped LSP diagnostics deduplication
- Added `DiagnosticsLedger` to track diagnostics already surfaced per file, suppressing repeats within a session.
- Wired dedup into both edit and write tools via a `transformDiagnostics` hook on the writethrough pipeline.
- Added `lsp.diagnosticsDeduplicate` setting (default: true) to control the behavior.
2026-06-01 18:04:05 +02:00
can1357 dbd9489010 refactor(eval): changed timeout from inactivity to wall-clock budget
- Only bridge heartbeats (`agent()`/`llm()`) now re-arm the watchdog; compute, stdout, `log()`/`phase()`, and ordinary tool calls count against the budget.
- Emitted an immediate heartbeat at bridge call start to avoid early abort near budget edge.
- Removed `idle` flag and "of inactivity" suffix from timeout annotation strings.
- Updated docs, prompts, and comments to reflect the new wall-clock semantics.
2026-06-01 17:17:00 +02:00
Can Bölük 890d63fdb1 Merge branch 'main' into fix-ask-option-descriptions 2026-06-01 18:14:42 +03:00
can1357 6a63b17711 Merge remote-tracking branch 'origin/farm/cdb7e4ab/fix-find-renderer-string-paths' 2026-06-01 14:36:57 +02:00
rimless-casualty 3c7d50d292 Improve ask option rendering 2026-06-01 17:37:26 +08:00
roboomp 8580ba248c fix(tool): handled string paths in find renderer
Guarded find renderer path summaries so raw pre-validation string paths render instead of throwing. Added coverage for pending, fallback, empty, and detailed result render paths.\n\nFixes #1622
2026-06-01 06:22:27 +00:00
can1357 7e11bea8f4 fix(coding-agent): repaired per-field double-encoded JSON in task tool
- Added `repairDoubleEncodedJsonString` to unescape fields double-encoded by the model (e.g. literal `\n`, `\"`, `\uXXXX` in `context`/`assignment`/`description`).
- Scoped repair to natural-language fields only, leaving code-bearing tools untouched.
- Applied repair on both render and execution paths in `TaskTool`.
2026-05-31 20:17:38 +02:00
roboomp f4ed2698dd fix(lsp): shut down servers with exit notification
Send the LSP exit notification after a successful shutdown response before falling back to process termination. Add a regression test that fails when a server receives shutdown but not exit.\n\nFixes #1593
2026-05-31 15:26:13 +00:00
can1357 a8d50879df chore: reformat 2026-05-31 13:22:50 +02:00
can1357 d016150d01 fix(ai): prevented provider retry after streaming unsafe content
- Added `!streamedReplayUnsafeContent` guard to `canRetryProviderFailure` to avoid replaying unsafe content on retry.
- Updated test fixtures to supply a required `workspaceTree` parameter via a shared `emptyWorkspaceTree` helper.
2026-05-31 13:21:15 +02:00
can1357 9fabd5e4d5 feat(coding-agent): added onStatus in eval backends for status streams
- Added optional `onStatus` callback wiring across eval backends and JS/Python executors for live status streams.
- Added collectDisplay-based forwarding so `emitStatus` and `onDisplay` route status outputs consistently.
- Expanded agent status payloads with preview/model/token-cost context and kept completion updates single-pass.
- Added status upsert and render adjustments in `tools/eval.ts` to coalesce agent events with progress stats.
- Added status/progress test coverage for running/completed agent events, final metric retention, and parallel placement.
- Updated CHANGELOG Unreleased notes to record live progress updates and completion-status metric fixes.
2026-05-31 08:45:12 +02:00
can1357 59c8749ad7 fix(tui): resolved tui status footer truncation using VT stripping
- Replaced ad-hoc ANSI/VT stripping regexes with `stripVTControlCharacters` in status text handling and related tests.
- Updated status footer rendering to truncate using `truncateToWidth` and visible width after VT stripping.
- Extended tui cursor handling and rendering to strip markers from all lines and fit repaint/append-tail lines to width.
- Expanded deterministic render tests with overlay-aware assertions and recorded the truncation/cursor-marker behavior in changelogs.
2026-05-31 07:54:23 +02:00
oldschoola cd578a86d1 fix(coding-agent,ai): file-lock race + render-utils sanitization + google named-tool routing
F1 (coding-agent): close the withFileLock mkdir-vs-writeLockInfo race that
let a losing contender wipe the winner's freshly-created lock directory.
Every lock now carries a per-process UUID token; releaseLock verifies the
token before fs.rm, and isLockStale no longer treats an info-less but
fresh dir (or a dir that vanished mid-check) as stale.

F4 (coding-agent): sanitize tabs and truncate oversized error strings in
formatErrorMessage so error renderings that embed file content
(apply_patch, hashline, etc.) cannot break terminal alignment or
overflow the line width.

F7 (ai): support named-tool routing on Google providers. Widens
GoogleSharedStreamOptions.toolChoice and GoogleGeminiCliOptions.toolChoice
to accept { mode: 'ANY'; allowedFunctionNames }. mapGoogleToolChoice
now converts ToolChoice { type: 'tool'|'function', name } to the wire
shape (mirroring mapAnthropicToolChoice). buildGoogleGenerateContentParams
and the gemini-cli request serializer honor the allow-list.
2026-05-31 04:45:57 +02:00
can1357 4ab0360f65 test(coding-agent/tools): updated internal URL resolution test fixture wording
- Updated the internal URL resolution test input pattern to use a new search phrase.
- Updated the expected assertion string to match the revised phrase in command output.
2026-05-31 04:41:36 +02:00
can1357 1dba122c53 chore: updated docs 2026-05-31 04:36:14 +02:00
can1357 756f32f687 feat(coding-agent-tools): added virtual multi-file search scope expansion
- Expanded search scope handling for virtual multi-file targets and executed grep only when searchable paths existed.
- Merged `searchVirtualResources` results into main output and rendered internal URL matches as accent lines.
- Updated grouped-file output to detect URL-like paths and keep full URL headers for root grouping.
- Documented URL path/range behavior and added tests for doc routing, missing-content errors, and `omp://` expansion.
2026-05-31 04:32:35 +02:00
can1357 f21c23277a feat(coding-agent/tools): implemented internal URL routing in SearchTool
- Added virtual internal URL path resolution in `SearchTool` via `InternalUrlRouter` for in-memory search.
- Added `omp://` root expansion so `search` resolves and scans each completion target.
- Fixed `SearchTool` handling of internal URLs without `sourcePath` by returning virtual matches instead of `Path not found`.
- Extended `edit-renderer.test.ts` coverage for normalizing raw streamed text in custom text renderers.
2026-05-31 04:28:39 +02:00
can1357 ce2e8ce7cd fix(coding-agent): added raw partialJson preview support for hashline and apply_patch tools
- Added helper logic to treat raw non-JSON `__partialJson` values as edit `input` for hashline and apply_patch args.
- Updated edit argument preparation, preview generation, and streaming fallback rendering to use that derived input.
- Added renderer tests verifying raw hashline and apply_patch partial streams render target paths and patch content.
2026-05-31 04:24:40 +02:00