Commit Graph
4275 Commits
Author SHA1 Message Date
can1357 319909c0ee chore: reformat 2026-05-21 15:52:55 +09:00
Can Bölük 68dc6e3ace Merge remote-tracking branch 'origin/farm/ebb932bf/emit-osc-8-hyperlinks-around-file-paths-' 2026-05-21 15:50:56 +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 eb314025f7 fix(tui): hyperlinks for fs-backed internal URLs and root-level grouped files 2026-05-21 06:44:58 +00:00
Can Bölük 4c0e70da03 Merge remote-tracking branch 'origin/farm/061c0c9d/goal-behavior-is-erratic' 2026-05-21 15:29:24 +09:00
can1357andCan Bölük a00d3f5c9f revert(coding-agent): remove leaked search.ts redaction wiring
Cleanup tail of 2817c582a — the search archive commit (78841798f) had
inadvertently included the redaction.ts import and wiring in
search.ts. That ad-hoc redactor was already reverted; this drops the
matching call sites so the file no longer references the deleted
module. SecretObfuscator (gated on `secrets.enabled`) is the supported
path for redaction.
2026-05-21 15:22:46 +09:00
can1357andCan Bölük 8fa46f0182 Revert "feat(coding-agent): redact secret-shaped values in tool output"
This reverts commit 3d1f2f877359f374d43e1590580be6ec8e99ea60.
2026-05-21 15:22:46 +09:00
can1357andCan Bölük 66d954ed7a feat(coding-agent): redact secret-shaped values in tool output
Adds a focused redaction utility that targets well-known token shapes
(AWS, GitHub PATs/tokens, Slack, OpenAI-style sk-, JWT) plus a
key/value heuristic for env-style lines whose key contains SECRET /
TOKEN / PASSWORD / API_KEY / PRIVATE_KEY, plus Bearer/Basic Authorization
header values. Replacements are tagged `#REDACTED:<hint>#` so callers
can tell why each value was scrubbed.

Wired into read, search and ssh tool outputs. Each call site appends a
`[redacted N secret-like values]` footer when at least one value was
scrubbed so the model knows the output was modified.

Gated behind a new `tools.redactSecrets` boolean setting (default true).
Sandboxed tests that intentionally surface secret-shaped fixtures can
disable it via Settings.isolated({ "tools.redactSecrets": false }).
2026-05-21 15:22:46 +09:00
can1357andCan Bölük 027dbb4900 fix(coding-agent): interrupt cell on timeout instead of killing kernel
A per-cell timeout used to kill the persistent Python kernel, losing
all session state. The kernel.ts timeout path now sends SIGINT first
(letting the cell raise KeyboardInterrupt) and only escalates to
shutdown after a 5s grace window if the interrupt is ignored.

KernelExecuteResult gains an optional kernelKilled flag (defaulting to
false, propagated by the escalation timer and the unexpected-exit
handler). executor.ts formats two distinct timeout annotations: one
that says the kernel is still alive and reset:true would clear state,
one that says the kernel was killed and will be recreated.
2026-05-21 15:22:46 +09:00
can1357andCan Bölük fd42c8da26 fix(coding-agent): stop mutating todo state via timer-based autoclear
#scheduleTodoAutoClear / #runTodoAutoClear used to splice completed and
abandoned tasks out of #todoPhases on a 60s (later 30min) timer. The
mutation made earlier completions vanish from phase counts ("5 tasks"
dropped to 4) and contradicted the model's own claim of progress.

The autoclear path is removed entirely. Canonical #todoPhases is only
mutated by explicit todo_write calls. formatSummary's denominator
(`current.tasks.length`) now stays stable across tool calls, so phase
counts include completed tasks until the model explicitly removes them.

Leaves the `tasks.todoClearDelay` setting in place (inert) to avoid
changing the schema in this patch.
2026-05-21 15:22:46 +09:00
can1357andCan Bölük 0d57ad586d fix(coding-agent): support searching inside zip/tar archive members
`read` accepts `archive.zip:member` selectors but `search` previously
ignored them, returning zero matches even when the member's text
contained the query. resolveArchiveSearchPaths now detects archive
selectors, opens the archive via the shared archive-reader, decodes
UTF-8 members into a scratch tmpdir, and rewrites match paths back to
the original selector before returning. Binary, non-UTF-8, missing
members and unreadable archives surface as a structured error or a
per-archive footer note. Scratch dir is cleaned up in finally.
2026-05-21 15:22:46 +09:00
can1357andCan Bölük 0d80a01280 fix(coding-agent): drop hash anchor when a displayed line was truncated
The read renderer was emitting `LINE+HASH|content` for lines whose
content had been column-truncated for display, but `computeLineHash`
is content-only and recomputes against the disk line. The model copied
the displayed anchor, edit rejected it as mismatched, even though the
underlying file had not changed.

formatTextWithMode now accepts an optional truncatedLines set; in
hashLines mode those lines emit as `LINE|content` (no hash) so the
verifier never tries to recompute against truncated text. Multi-range
and single-range read paths both populate the set when truncateLine
flips wasTruncated.
2026-05-21 15:22:46 +09:00
can1357andCan Bölük 6b671ff1c5 fix(coding-agent): enforce subagent output schema on yield
buildOutputValidator already exists in task/executor.ts but only ran on
the fallback JSON parse path. Subagents that called yield directly with
a data payload skipped validation entirely, so a schema-conforming-
empty-object (e.g. `{}` against a schema requiring `findings`) was
returned as a successful task.

finalizeSubprocessOutput now invokes the validator on every yield path
and on the fallback completion path. On failure the result carries
error="schema_violation", a typed message, the missing required field
list, and a truncated preview of the offending data. exitCode=1 and
isError=true so existing consumers in task/index.ts surface it as a
failed task without code changes.
2026-05-21 15:22:46 +09:00
can1357andCan Bölük 50958aa6fa fix(coding-agent): classify credit/quota/auth errors for web_search chain advance
Adds a shared classifyProviderHttpError helper that maps the well-known
failure shapes (status 401/402/403 and bodies matching credits / quota
/ insufficient) into compact SearchProviderError messages so the
orchestrator advances to the next provider instead of bailing.

Wired into every HTTP-talking provider (codex, exa, gemini, anthropic,
brave, jina, kimi, perplexity, searxng, synthetic, tavily, zai) and the
two wrapped-error providers (kagi via KagiApiError, parallel via
ParallelApiError). The orchestrator now collects per-provider failures
and emits a joined summary ("exa: 403 forbidden; codex: credits
exhausted; ...") when the whole chain fails.

Test updates: web-search-{exa,tavily,kagi} message expectations now
assert the compact "<id>: <status> <reason>" form.
2026-05-21 15:22:46 +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 6c82bb3f5b fix(coding-agent/hashline): fixed hashline separator-padding warnings for indent-sensitive files
- Extended hashline parsing APIs to accept an optional target path so padding checks can be path-sensitive.
- Refined separator-padding heuristics to warn only on uniform single-space-before-content payloads while skipping those checks for indent-sensitive extensions.
- Threaded section paths through execute/diff callers and added tests covering warning behavior for both exempt and non-exempt file types.
2026-05-21 14:34:04 +09:00
roboomp fb0fcdfa7c feat(tui): added OSC 8 hyperlink support for file paths in tool output 2026-05-21 05:01:23 +00:00
can1357 fe5b96e8a1 chore: bump version to 15.1.9 2026-05-21 13:24:41 +09:00
Can Bölük 0eafc5c814 Merge remote-tracking branch 'origin/farm/8d096e89/web-search-freezes-on-windows-no-hard-ti' 2026-05-21 13:23:07 +09:00
Can Bölük 4ff735e3f2 Merge remote-tracking branch 'origin/farm/8b26bc9b/force-command-not-working' 2026-05-21 13:22:53 +09:00
Can Bölük 7cf5ad91d5 Merge remote-tracking branch 'origin/farm/fc6820eb/macos-arm64-v15-1-8-release-binary-exits' 2026-05-21 13:22:13 +09:00
Can Bölük 30e3e7f0b4 Merge remote-tracking branch 'origin/farm/22461167/acp-mode-auto-loads-host-mcp-config-and-' 2026-05-21 13:21:54 +09:00
roboomp a6279e0730 fix(cli): restored binary update rollback
Rolled back binary updater replacements when post-install version verification fails instead of deleting the previous working binary first.

Added a release workflow gate that downloads the published macOS arm64 asset and verifies codesign plus --version before npm publishing.

Fixes #1240
2026-05-21 00:09:43 +00:00
roboomp 143ba32b11 fix(coding-agent): forced ollama tool choice
Route /force through a named Ollama tool choice and scope the Ollama request tools to that selected name so local models cannot pick a different tool.\n\nFixes #1236
2026-05-20 22:28:04 +00:00
roboomp 185615497c fix(acp): disable host MCP discovery in ACP session factory
ACP clients own MCP server configuration via session/new.mcpServers and AcpAgent#configureMcpServers. The ACP session factory previously left enableMCP at its default (true), so createAgentSession ran discoverAndLoadMCPTools on every session/new and the resulting host MCP tools landed in the session tool registry alongside the client-supplied ones. search_tool_bm25 then surfaced only the host tools.

Force enableMCP: false on every session created through createAcpSessionFactory so on-disk discovery is bypassed in ACP mode. Non-ACP modes (omp interactive, print, RPC) keep auto-discovery.

Fixes #1234
2026-05-20 21:40:43 +00:00
roboomp ccc08821d5 fix(providers): skipped disabled discovery probes
Prevent disabled providers from being registered for implicit local discovery and from creating built-in model discovery managers. Added regression coverage for disabled local providers during model registry refresh.

Fixes #1232
2026-05-20 20:16:19 +00:00
can1357 d1222fd665 docs(coding-agent/prompts): expanded oracle prompt to handle delegated execution
- Updated the oracle agent description to present it as a senior engineer who can either consult or execute when delegated.
- Removed the read-only mandate and added requirements to implement changes, run checks, and report completed work in delegation mode.
- Adjusted the procedure and decision guidance to distinguish consult versus implement paths while keeping the scope limited to requested tasks.
2026-05-21 03:03:13 +09:00
roboomp 401a99dce7 fix(web-search): added hard timeout and abort propagation for stalled fetches
Bun's WinHTTP backend can ignore AbortSignal once a TCP/TLS connection
stalls (oven-sh/bun#15275, oven-sh/bun#18536), so Esc never reached the
in-flight `web_search` fetch on Windows and the session froze until
Ctrl+C. Only kimi shipped any timeout at all (server-side); every other
provider passed `signal` to `fetch` with no client-side bound.

Introduced `withHardTimeout(signal, ms=60_000)` in providers/utils and
wired it into every web-search provider's outbound fetch — anthropic,
brave, codex, exa, gemini, jina, kagi, kimi, parallel, perplexity
(api-key and oauth), searxng, synthetic, tavily, z.ai. 60s tolerates
legitimate slow LLM-mediated responses while still guaranteeing the
request settles within a minute when Bun's abort fails to propagate.

Independently, `executeSearch`'s provider-fallback loop swallowed every
`AbortError` as a regular provider error and returned
"All web search providers failed", masking cancellation on every
platform. The catch block now calls `throwIfAborted(signal)` first so a
caller-initiated cancel propagates as `ToolAbortError`.

Fixes #1221
2026-05-20 11:03:48 +00:00
can1357 e6ddfc0a8e chore: bump version to 15.1.8 2026-05-20 17:49:07 +09:00
can1357 94c3025ec8 fix(coding-agent): fixed Perplexity OAuth tokens from expiring after one hour
- Updated Perplexity JWT parsing in the ai OAuth utilities to return a far-future sentinel when `exp` is missing and use that when computing token expiry.
- Updated `getOAuthApiKey` to prefer the JWT expiry and normalized legacy one-hour `expires` values to a non-expiring value.
- Updated coding-agent web search token lookup to verify Perplexity credentials against the JWT `exp` claim and treat missing claims as non-expiring.
2026-05-20 17:48:11 +09: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
can1357 d03f1e0c79 fix(coding-agent): verify edit by content compare instead of stat
The size+mtime check from 094273df5 is unreliable on filesystems with
coarse mtime resolution: a same-length rewrite within the same tick
(e.g. "a" → "b") leaves both fields unchanged and falsely trips the
"file content did not change on disk" guard. CI on ubuntu Bun 1.3.14
hit this in the create-then-update aggregation test.

Re-read the file post-write and compare bytes to the previous content
instead — deterministic regardless of FS timestamp granularity.
2026-05-19 19:40:26 +09:00
can1357 1f1e6e3eb1 revert(coding-agent): restore opaque extra record in resolve schema
The narrowed object-with-title schema added in e26a17f3f is no longer
necessary: the upstream constrained-sampling fix lets models emit
arbitrary props on a record now, so the opaque shape no longer hides
title from discovery. Plan-approval callers still pass extra.title and
the renderer/handler logic accept it unchanged.

The companion changes from e26a17f3f (resolve.md context enumeration,
runResolveInvocation apply-throw requeue) stay intact.
2026-05-19 19:29:44 +09:00
can1357 1521cb785b chore: bump version to 15.1.7 2026-05-19 19:27:28 +09:00
can1357 9e34466795 docs(coding-agent): guard bash timeout/async section behind asyncEnabled
The timeout/async section is only meaningful when the async option is
exposed to the model. Wrap the new section in {{#if asyncEnabled}} to
match the existing async-bullet guard above.
2026-05-19 19:25:26 +09:00
can1357andCan Bölük d30dc78409 fix(coding-agent): clean up ephemeral irc reply turn
Three coordinated tweaks in runEphemeralTurn and the supporting
#buildEphemeralSnapshot so IRC reply text stops leaking tool-call
markup, duplicating verbatim, and breaking DeepSeek-class encoders:

- Drop the recipient's tools array entirely instead of relying on
  toolChoice:"none" (not every backend enforces it). The model now has
  no tool surface to emit so leaked function_call / DSML markup stops.
- Preserve thinking content blocks when snapshotting the in-flight
  streaming assistant message so the openai-completions encoder can
  re-emit reasoning_content for DeepSeek-routed recipients (10 reports
  of HTTP 400 "'reasoning_content' in thinking mode must be passed
  back").
- Collapse consecutive duplicate sentences in replyText and cap reply
  length so a looping recipient does not spam the IRC channel with the
  same line repeated N times.
2026-05-19 19:24:16 +09:00
can1357andCan Bölük 965bd095a5 fix(coding-agent): keep completed todo tasks visible for the full turn
The 60s autoclear was mutating canonical #todoPhases via setTimeout, so
earlier completions vanished from the model's view of phase progress.
Default delay bumped well above any plausible turn duration and a
dedup helper added so the canonical list remains intact until the next
explicit prompt boundary.
2026-05-19 19:24:16 +09:00
can1357andCan Bölük 3e567b1852 fix(coding-agent): stop dropping rewind checkpoint on every aborted message
The unconditional clear of #checkpointState on stopReason==="aborted"
fired on user interrupts, TTSR rule injection, streaming-edit guards,
plan-compact, and auto-compaction, silently dropping the user's
checkpoint with no signal to the model. Downstream #applyRewind already
tolerates message-count drift via its safeCount clamp, so the clear is
safe to remove. Accounts for 100% of rewind tool grievances.
2026-05-19 19:24:16 +09:00
can1357andCan Bölük 82d5b4e434 docs(coding-agent): document task background announcement and agents filter
Update task.md to reflect the new behavior: per-task jobIds in the
started-job announcement and the spawn-filtered agents listing.
2026-05-19 19:24:16 +09:00
can1357andCan Bölük 914dc0aaa1 docs(coding-agent): clarify bash timeout/async interaction and minimizer
Documents that async:true defers reporting but does not extend or
disable the timeout, so long-running daemons should pass a generous
timeout. Also notes the output minimizer may rewrite results and that
the full bytes are always available at the artifact:// footer.
2026-05-19 19:24:16 +09:00
can1357andCan Bölük e26a17f3fc fix(coding-agent): expose extra.title in resolve schema, requeue on apply throw
- The plan-approval gate required extra.title but the wire schema only
  declared an opaque additionalProperties record so codex/gpt-5.x could
  not discover the field. Schema now declares title with a description
  while still allowing passthrough for future per-context keys.
- resolve.md replaces the truncated "Schema depends on context:" line
  with the actual enumeration.
- runResolveInvocation wraps apply() in try/catch; a thrown apply (e.g.
  ast_edit overlap) requeues the resolve directive so the model can
  discard or fix-and-retry instead of losing the preview.
2026-05-19 19:24:16 +09:00
can1357andCan Bölük b191e6c5ff fix(coding-agent): reject task-N ID confusion, error on partial todo apply
- todo-write.md adds an explicit note that tasks are referenced by
  verbatim content text; the tool never emits task-N IDs.
- resolveTaskOrError rejects ^task-\d+$ inputs with a clarifying error.
- execute sets isError:true when any op failed.
- appendItems short-circuits on the first "already exists" error so the
  call no longer applies the prefix of a doomed batch.
2026-05-19 19:24:16 +09:00
can1357andCan Bölük fcd38b7143 fix(coding-agent): require symbol, distinguish timeout, coalesce lsp edits
Three independent lsp fixes that share the action dispatcher and import
graph in lsp/index.ts:

- symbol-required: project-aware references/rename/definition now reject
  an omitted symbol with a structured error pointing at symbol=<name>
  (and symbol#N for repeats). resolveSymbolColumn used to fall back to
  the first non-whitespace column and the server happily answered for
  whatever identifier sat there. findSymbolMatchIndexes also enforces
  word boundaries for bare identifiers.

- timeout-distinguish: the outer catch around dispatched LSP actions
  rethrew new ToolAbortError() for both an internal timeoutSignal abort
  and a caller signal abort, so callers got an opaque "Operation
  aborted". Timeouts now map to a ToolError that names the action and
  the elapsed budget; caller cancels stay ToolAbortError.

- edit-coalesce: rename and rename_file collected edits from every
  project-aware server and applied them sequentially, but each server
  computed positions against pre-edit text. Once server A wrote, server
  B's edits had stale offsets and produced malformed imports. Merge
  per-uri edits across servers, sort by descending position, and throw
  on overlap so the model retries instead of silently corrupting.
2026-05-19 19:24:16 +09:00
can1357andCan Bölük b3b75ff1d5 fix(coding-agent): advance web_search chain on codex image placeholder
When the Codex backend returned the literal "(see attached image)" as
the answer for a text query and streamedAnswer was empty, the wrapper
accepted the placeholder as the response and the chain never advanced.
Throw SearchProviderError so the next provider is tried.
2026-05-19 19:24:16 +09:00
can1357andCan Bölük ef505142bf fix(coding-agent): fall back to inline worker when tab worker startup errors
Worker emits BuildMessage errors via the async error event, after the
surrounding try/catch in spawnTabWorker has already resolved, so the
documented spawnInlineWorker fallback was unreachable for the very case
it was added to cover. initializeTabWorker now terminates the broken
worker and retries once via spawnInlineWorker, with the original error
attached as cause if the inline fallback also fails.
2026-05-19 19:24:16 +09:00
can1357andCan Bölük 93e74819cb fix(coding-agent): raise browser tool timeout cap from 30s to 300s
clampTimeout silently floored the caller-supplied timeout to 30s, so a
requested 120s for a slow waitForResponse came back as a 30s failure
indistinguishable from the default. Raise the cap and document the new
max in the schema field description.
2026-05-19 19:24:16 +09:00
can1357andCan Bölük d700004489 fix(coding-agent): default browser waitUntil to "load"
networkidle2 requires <=2 in-flight requests for 500ms which never
resolves on dev servers (HMR, websockets, telemetry beacons), so
browser.open and tab.goto timed out before user code ran. "load" matches
Puppeteer's documented default and works on real-world pages.
2026-05-19 19:24:16 +09:00
can1357andCan Bölük 6d1ade1200 fix(coding-agent): only claim Applied patches: yes when something applied
Both empty-patch and whitespace-only-patch branches in the isolated-task
merge unconditionally appended "Applied patches: yes". The marker now
fires only when the combined patch is non-empty AND applyText succeeded.
No-op merges report "No changes to apply.". The renderer marker matcher
accepts the new string.
2026-05-19 19:24:16 +09:00
can1357andCan Bölük be5451d5c3 fix(coding-agent): surface real jobId in background task announcement
The "Started N background task jobs" announcement listed the per-task
label (e.g. 7-MyScout) without the underlying jobId, but JobTool.execute
looks up by jobId. Append (job: ${jobId}) to each task entry and accept
the task label as a fallback alias in JobTool.execute.
2026-05-19 19:24:16 +09:00