Commit Graph

3496 Commits

Author SHA1 Message Date
can1357 5003996a01 feat(coding-agent): added content-based todo matching for write/commands
- Removed `id` fields from todo models/fixtures and switched session clones to content-based task identity.
- Replaced `/todo_write` `replace` with `init`, updated setup schemas to `list`/`phase`, and append content-only items.
- Updated `/todo` command flows to match phases and tasks by names/content (exact/prefix/substr, case-insensitive), with no ID targeting.
- Updated rendering/output labels to `# Todos`, `formatPhaseDisplayName`, and Roman-numeral phase headings across todo views.
- Aligned prompts, changelog, and todo tests/fixtures with the new init and content-based todo-write contract.
2026-04-30 06:40:53 +02:00
can1357 0e377c4914 chore: bump version to 14.5.10 2026-04-30 06:11:29 +02:00
can1357 bbd789fe40 fix(coding-agent): added blank-line forgiveness for atom range replacements
- Added a lookahead helper to detect `\` continuation lines after blank lines during range replacements.
- Converted interior blank lines to explicit continuation-sentinel inserts when followed by a continuation, preserving open replacement state.
- Extended atom parser tests to cover implicit blank-`\` handling for range and single-anchor replacements, including trailing-blank termination.
2026-04-30 06:06:07 +02:00
can1357 4562b3f365 feat: compact diffs, remove garbage hint 2026-04-30 06:03:29 +02:00
can1357 55bdb4119f fix(coding-agent): added auto-retry handling for unexpected socket close errors
- Integrated `isUnexpectedSocketCloseMessage` into transient error detection so Bun socket-closure failures are treated as retryable.
- Added a retry fallback test that simulates a Bun socket close error and verifies the request is retried successfully with matching retry start/end events and recovered output.
2026-04-30 05:58:38 +02:00
can1357 961a7f053b fix(coding-agent/edit): extended duplicate auto-fix to remove multiple adjacent duplicate lines
- Updated adjacent-duplicate auto-fix logic to remove a line from each detected pair when bracket balance changed.
- Adjusted the validation to accept the corrected file only after all removals restore original bracket balance.
- Added a regression test for one edit creating duplicate block closers in two unrelated segments and asserting the auto-fix warning.
2026-04-30 05:58:08 +02:00
can1357 5ecd041bfe fix: patched bash interceptor, LSP shutdown, and concurrent command tracking
- Fixed bash interceptor to check both raw and cwd-normalized commands, catching commands hidden behind leading `cd ... &&` wrappers.
- Fixed LSP client shutdown to await graceful shutdown with a 5s timeout before killing the process, and parallelized `shutdownAll` via `Promise.allSettled`.
- Fixed concurrent bash command tracking by replacing a single abort controller with a Set, preventing premature cancellation of parallel commands.
- Removed `./hooks` and `./hooks/*` export entries from the coding-agent package exports map.
- Updated pinned Rust nightly toolchain from `nightly-2026-03-27` to `nightly-2026-04-29` in `rust-toolchain.toml` and CI workflow.
- Replaced custom already-published detection in `ci-release-publish.ts` with `bun publish --tolerate-republish` flag.
2026-04-30 05:51:01 +02:00
can1357 bf1faf8842 test(coding-agent): drop api filter from getOpenAICompat fixture helper
The helper guarded `model.api === "openai-completions"` and returned undefined
for openai-responses models. The discoverable-custom-compat test sets
`api: "openai-responses"` on a custom model with `compat.extraBody`, so the
post-refresh assertion saw `undefined` instead of the configured proxy hint.

The OpenAICompatSchema gates user-facing custom-model compat regardless of the
underlying api wire format, so reading the field as OpenAICompat for any api
matches what the registry actually stores.
2026-04-30 05:35:00 +02:00
can1357 fed95ce524 fix(ai,coding-agent): narrow Model.compat consumers after AnthropicCompat split
Commit a190397d8 made `Model.compat` resolve to `OpenAICompat | AnthropicCompat`
under the default `TApi = any`. The widened union broke every site that treated
`compat` as openai-shaped: model-registry deep-merge, openai-completions resolved
compat, and ~20 test fixtures. This restores the assumption locally instead of
papering over it with casts.

- getBundledModel is now generic on TApi so test fixtures that spread it into
  `Model<"openai-completions">` get the narrow compat back.
- mergeCompat is generic over TBase/TOverride; the schema-driven model-registry
  override path keeps its OpenAICompat-shaped merge fields, anthropic overrides
  pass through untouched.
- OpenAICompatSchema gains the openai-only fields it was missing
  (requiresMistralToolIds, reasoningContentField, requiresReasoningContent*,
  thinkingFormat, requiresThinkingAsText, disableReasoningOnForcedToolChoice).
- resolveOpenAICompat fills in disableReasoningOnForcedToolChoice so the
  Required<OpenAICompat> shape stays satisfied.
- Anthropic tool-result block id assignment uses the proper unknown double-cast.
- isForcedToolChoice accepts unknown so it can read `params.tool_choice` whose
  type comes from the OpenAI SDK ChatCompletionToolChoiceOption (now wider than
  our local OpenAICompletionsToolChoice).
- Test fixtures and Required<OpenAICompat> literals updated for the field set.

Fixes CI red on main.
2026-04-30 05:23:20 +02:00
can1357 03c614d767 fix(ai): drop reasoning when tool_choice is forced for kimi/anthropic on openai-completions
Mirror anthropic.ts:disableThinkingIfToolChoiceForced for backends that 400
on combined reasoning + forced tool_choice. Kimi explicitly rejects this
combination ('tool_choice specified is incompatible with thinking enabled')
on its native API, OpenCode-Go, OpenRouter, etc. Anthropic itself enforces
the same constraint, so Claude reached through OpenAI-compat proxies
(LiteLLM, Vertex chat-completions, OpenRouter) needs the same handling.

Adds disableReasoningOnForcedToolChoice compat flag, defaulted on for any
Kimi (moonshotai/kimi*, kimi-* ids) or Anthropic (provider/baseUrl/claude*
ids) model. When tool_choice resolves to anything that forces a tool call
(required, named function), reasoning_effort and the OpenRouter-shaped
nested reasoning object are dropped for that turn. The forced tool_choice
itself stays so the agent still gets the tool call.

Replaces the previous (incorrect) approach of unconditionally dropping
tool_choice for kimi reasoning models, which broke explicit tool routing.

Fixes #827
2026-04-30 04:56:47 +02:00
can1357 e39d3d9c76 fix(natives): detect compiled-binary mode via embedded-addon presence
Standalone Bun binaries on WSL (and any host where the user moves the
binary away from the build-host's checkout) failed to load
pi_natives.<platform>-<arch>*.node. The loader's isCompiledBinary
detection relied on two signals that are both false in shipped binaries:
process.env.PI_COMPILED (bun --define PI_COMPILED=true substitutes the
bare identifier, not property accesses on process.env) and
__filename.includes("$bunfs") (Bun retains the build-host absolute path
in __filename for required CJS modules — only import.meta.url is
rewritten). Detection therefore returned false, embedded-addon
extraction was skipped, and the only candidates probed were the
build-host nativeDir and execDir.

Make embedded-addon presence the authoritative compiled-mode signal
(it is null in the post-build --reset stub, populated when embed:native
ran for the standalone build), eagerly require the manifest, and
extract candidate-path computation into a pure helper covered by a
host-platform-agnostic unit test. Also fix the build-time --define so
process.env.PI_COMPILED is genuinely set at runtime as a defensive
fallback.

Fixes #823
2026-04-30 04:51:23 +02:00
can1357 d9376c5866 fix(coding-agent): keep steer preview honest when post-compaction flush hits AgentBusyError
flushCompactionQueue() fires session.prompt(text) on the first non-slash
queued message. If the session is still streaming when compaction-end
lands (race between isStreaming flipping false and the event arriving),
prompt() throws AgentBusyError, restoreQueue() dumps the message back
into compactionQueuedMessages, and it stalls there: nothing drains that
array except the next compaction-end. The user sees the steer preview
but cannot deliver the message (Alt+Up consults session.clearQueue, not
compactionQueuedMessages).

Pass streamingBehavior derived from the queued message's mode so
prompt() routes into the steer/follow-up queue when busy and runs as a
fresh prompt when idle.

Fixes #825
2026-04-30 04:51:23 +02:00
can1357 08403be71f fix(coding-agent): preserve explicit default model on session resume
buildSessionContext walked the entry path and unconditionally overwrote
models.default from every assistant message's reported model. Temporary
fallbacks (retry fallback, context promotion) and codex-side model
downgrades both produce assistant messages tagged with a different model
id, which clobbered the user's explicit /model pick on resume and made
the session silently revert to the older model.

Treat assistant-message inference as a legacy fallback that only fills
in models.default when no explicit `model_change` with role="default"
has been seen on the path.

Fixes #849
2026-04-30 04:51:23 +02:00
can1357 381f30233e fix(coding-agent): log stage1 memory job failures
Phase1 caught every per-claim failure, recorded the reason in
jobs.last_error, and surfaced only an aggregate failed count via the
phase1 completion debug line. Users hitting setup-time failures (e.g.
WSL2 stale rollout paths producing ENOENT before any LLM call) had no
diagnostic. Emit logger.error per failed claim with threadId,
rolloutPath, and reason so the actual error is visible in omp.log.

Fixes #846
2026-04-30 04:51:23 +02:00
can1357 0306f937ea feat(ai): support per-model thinking defaultLevel
Add optional defaultLevel to ThinkingConfig schema/type so models.yml can
declare a preferred starting thinking level per model. On model switch
the agent session adopts model.thinking.defaultLevel when present (with
explicit caller-supplied level still winning); otherwise current behavior
is preserved. SDK initial selection prefers the model's defaultLevel
before falling back to the global defaultThinkingLevel setting.

Fixes #775
2026-04-30 04:51:23 +02:00
can1357 895ff6f3a7 fix(coding-agent): clear pending plan-role model switch on plan-mode exit
When entering plan mode while the session is streaming, #applyPlanModeModel
defers the switch into #pendingModelSwitch and snapshots the previous model.
On exit, the snapshot was restored but the deferred switch was left queued,
so the next agent_end flush landed the session on the plan-role model after
the user had already left plan mode.

Drop the pending switch in #exitPlanMode when its target matches the
plan-role resolution; leave any other queued switch alone.

Fixes #816
2026-04-30 04:51:23 +02:00
can1357 74ce4ab33e fix(coding-agent): support flat .mcp.json shape from Claude marketplace plugins
Claude marketplace plugins (e.g. context7@claude-plugins-official) ship
.mcp.json with the server map at the top level rather than under the
mcpServers key. The loader only accepted the nested shape, so install
appeared to succeed but no MCP tools were registered. Detect both shapes
and validate that each entry declares command (stdio) or url (HTTP/SSE)
before registering.

Fixes #851
2026-04-30 04:51:23 +02:00
can1357 f5476d25b4 fix(coding-agent): stop anchoring auto-continue prompt on stale 'Next Steps'
The autoContinue post-compaction prompt echoed the summary's '## Next
Steps' heading, but that section is generated only from the compacted
tail; the kept ~20k recent tokens are not fed to the summarizer. When
the user pivoted within the kept window, 'Continue if you have next
steps.' anchored the model on the now-outdated plan instead of the
latest intent.

Move the prompt to prompts/system/auto-continue.md (per AGENTS.md
no-inline-prompts rule) and rewrite it to direct the model to re-read
the kept recent messages and follow the user's most recent request,
explicitly allowing it to stop when nothing remains.

Fixes #840
2026-04-30 04:51:19 +02:00
can1357 a2f508faac fix(coding-agent): resolve junctions/symlinks when classifying omp update target
isPathInDirectory only normalized strings via path.resolve, so on Windows
when Bun is installed via Scoop (~/.bun is a junction to scoop\persist\
Oven-sh.Bun\.bun) the omp path from $which and the bunBinDir from
'bun pm bin -g' compared as different directories, causing 'omp update'
to take the binary-swap path instead of 'bun install -g' and fail with
EPERM unlinking omp.exe.bak (Bun has the running exe open). Layer
fs.realpathSync.native on top of the existing lexical guard, resolving
the file's parent dir so non-existent target paths still fall through.

Fixes #845
2026-04-30 04:41:36 +02:00
Can Bölük 74b828e42e Merge pull request #833 from HabibPro1999/feat/provider-response-hook
Add provider response extension hook
2026-04-30 03:57:45 +02:00
HabibPro1999 e069ec0a8f feat(coding-agent): add provider response hook 2026-04-30 03:52:52 +02:00
can1357 fd44728d6e fix(coding-agent/session): resolved local:// files for streaming edit cache operations
- Added a shared session path resolver that maps local:// URLs through local-protocol options, skips other internal schemes, and returns an absolute filesystem path for real files.
- Updated streaming-edit pre-cache and post-edit cache invalidation to use the shared resolver, preventing internal-scheme assertions while keeping filesystem-based flow for local plan files.
- Extended streaming-edit tests to confirm local:// plan edits complete without panicking and that auto-generated checks receive resolved absolute paths.
2026-04-30 03:48:36 +02:00
can1357 90fabf6d4f feat(coding-agent): added batch PR handling to pr_view and pr_diff
- Added support for batch PR operations by accepting `pr` as string or array and dropping `worktree` input.
- Updated `pr_view` and `pr_diff` to normalize PR IDs, process multiple PRs in parallel, and emit combined summaries.
- Refactored checkout into `checkoutPullRequest`, added repo-locking, fixed worktree paths, and summary metadata outputs.
- Updated `remote.add` handling with URL-aware idempotency and per-repo queueing for serialized git mutations.
- Added temp-home test scaffolding and expanded tests for batched PR flows and remote add conflict/no-op cases.
2026-04-30 03:48:25 +02:00
can1357 e46b32133e refactor(tui): replaced hand-rolled LRU map with lru-cache package
- Removed custom delete-then-reinsert Map implementation.
- Added lru-cache dependency and switched to LRUCache from lru-cache/raw.
2026-04-30 03:45:55 +02:00
Can Bölük ada51dfc49 Merge pull request #819 from metaphorics/fix/precache-local-url-panic
fix(coding-agent): skip streaming pre-cache for internal-scheme URLs
2026-04-30 03:40:44 +02:00
Can Bölük 55aab2815a Merge pull request #821 from metaphorics/perf/sessiontree-dedupe-context-build
perf(coding-agent): dedupe buildSessionContext walk on session-tree navigation
2026-04-30 03:40:20 +02:00
Can Bölük 57e912e462 Merge pull request #822 from metaphorics/perf/markdown-global-render-cache
perf(tui): module-level LRU for Markdown render cache
2026-04-30 03:39:59 +02:00
Can Bölük 103baacb7d Merge pull request #824 from mouyase/feat/searxng-basic-auth
feat(coding-agent/web): support SearXNG Basic auth
2026-04-30 03:35:00 +02:00
can1357 b6bcdbf6f1 test(coding-agent): align task.simple description assertions with compressed prompt
The task description prompt was compressed in c6cab807d — the explicit 'Current input mode' and 'Every assignment must stand on its own.' phrasings are gone. Replace those literal-string assertions with checks against the rendered mode-dependent content that actually differentiates the modes ('context` or `assignment`' for schema-free, 'each `assignment`' for independent). Mode-driven schema differences remain covered by the surrounding parameter-bullet assertions.
2026-04-30 03:05:21 +02:00
can1357 49e62f117f chore: bump version to 14.5.9 2026-04-30 02:50:53 +02:00
can1357 c6cab807d5 feat: compressed prompts slightly 2026-04-30 02:50:42 +02:00
can1357 ae3417fc3b refactor(coding-agent/tools): simplified debug schema metadata definitions
- Removed example and verbose description metadata from many debug tool schema properties while preserving field types and names.
- Simplified Enum declarations for `action` and `access_type` by using direct enum lists.
- Normalized several numeric and string field definitions in the schema without changing parameter names.
2026-04-30 02:38:27 +02:00
can1357 1f2c3de38f feat(coding-agent/tools): limited recipe prompt tasks to first 20 entries
- Added a PROMPT_TASK_LIMIT constant set to 20 in the recipe runner model.
- Updated buildPromptModel to include only the first 20 tasks from each runner when generating prompt tasks.
- Added an optional hiddenTaskCount field to PromptRunnerModel to represent truncated tasks.
2026-04-30 02:38:06 +02:00
can1357 f8be2ceda5 feat(coding-agent): added /context command flow for interactive dispatch
- Added a `/context` slash command flow from registry to interactive-mode command dispatch.
- Added `handleContextCommand()` to the mode context interface and command-controller wiring.
- Added context usage breakdown utilities, cell allocation, and 20x10 usage rendering for token categories.
- Reworked compaction token estimation to use tokenizer counts, role aggregation, image token estimates, and fallback handling.
- Exported `resolveThresholdTokens()` as a public compaction helper.
2026-04-30 02:26:04 +02:00
can1357 863560ffb6 fix(coding-agent/edit): added atom range-repair and multi-section preflight checks
- Allowed bare `LidA..LidB` to recover a missing-range-delete typo and accepted `|` as a legacy range replacement separator while validating ranges and replacement text.
- Enabled indented hashline statements to parse as replacement edits and added a preflight pass that validates all atom sections before any file write occurs.
- Updated hash-mismatch messaging, prompt wording, and tests to reflect hash-only rebase candidates and the new range/section behaviors.
2026-04-30 00:43:27 +02:00
can1357 222e1cd348 feat(edit): enabled Lid= and LidA..LidB replacements to support backslash continuation
- Updated the Atom grammar to parse replacement blocks via a set block rule that no longer targets range replacements only.
- Extended continuation preprocessing to allow backslash lines after single-line replace operations (including legacy `@` and `|` forms) while preserving the active-replacement check.
- Added tests and prompt documentation for single-line continuation cases and for rejection of backslash-like text outside an active replacement.
2026-04-30 00:05:37 +02:00
can1357 c124c74b5d fix(pi-natives/shell): ensured OK output for successful empty minimization
- Added `with_text` to keep minimized output byte counters consistent when replacing output text.
- Wrapped successful pipeline and overlay minimizer results with a post-step that emits `OK\n` when the transform empties output on success.
- Added tests to confirm successful empty-output minimization becomes `OK\n` and failures keep empty output.
2026-04-30 00:01:46 +02:00
can1357 47dab9ee97 feat: added atom-mode Lid range edits and hashline shifted-hash recovery
- Added atom edit support for Lid ranges, before-anchor inserts, and no-op Lid=TEXT success handling.
- Expanded hashline recovery to scan shifted hashes, match unique alternates, and emit ±5 anchor-shift hints.
- Added edit failure categorization with per-category counts, percentages, and detailed report lines.
- Added regression coverage for shifted-hash recovery, range continuation, cursor shorthand, and split-file atom ops.
2026-04-29 23:51:22 +02:00
can1357 d2eec2e1d6 feat(coding-agent/tools): added per-task working directories to recipe command resolution
- Resolved recipe operations now return a command plus optional working directory, and the shell tool path forwards both values when executing.
- Updated the package runner to assign task-local `cwd` entries for workspace scripts instead of embedding workspace command prefixes.
- Adjusted renderer wiring and tests to use the new `cwdFromOp` helper and assert task object shapes with preserved `cwd` values.
2026-04-29 23:47:47 +02:00
can1357 cb2119ef4d feat(coding-agent/lsp): added symbol occurrence selectors via #N suffix
- Parsed symbol occurrences inline via a new `name#N` symbol spec and defaulted missing occurrences to 1.
- Updated LSP symbol column resolution to derive occurrence from the symbol spec, removing the separate occurrence argument.
- Synchronized prompts, tool schema rendering, and regression tests to document and verify `#N` occurrence selection instead of a standalone occurrence field.
2026-04-29 23:37:39 +02:00
can1357 afb5f1f8a0 refactor(coding-agent/tools): renamed run_command tool to recipe across coding-agent tools
- Updated the tool configuration key and labels from runCommand to recipe, including its settings UI schema.
- Renamed the run_command tool implementation, prompts, and test wiring to recipe and updated tool registry and renderer registrations.
- Adjusted auto-included tool behavior and availability checks to use the recipe name and recipe.enabled setting.
2026-04-29 21:54:14 +02:00
can1357 0b3c03189b feat(coding-agent/modes): enabled /loop to use the next user prompt for repeating iterations
- Updated loop command handling to toggle `/loop` without a prompt argument and prompt for the next user input to start repeating.
- Stored each user-submitted prompt as the active loop prompt while loop mode is enabled so iterations auto-resubmit that input after each yield.
- Introduced `pauseLoop` behavior to clear the captured loop prompt and cancel pending auto-submit when Escape is pressed, while `handleLoopCommand` now no longer disables mode automatically with arguments.
2026-04-29 21:42:03 +02:00
can1357 a188651f63 fix(coding-agent/session): skipped empty thinking entries when formatting session dumps
- Updated `formatSessionDumpText` to skip `thinking` entries with empty or whitespace-only content.
- Prevented empty `<thinking>` sections from being emitted in session dump output.
2026-04-29 20:43:29 +02:00
Can Bölük 6924cf67b8 fix(coding-agent): swapped atom cursor marker semantics for ^ and $
- Reversed atom mode parsing of cursor anchors so "^" now resolved to BOF and "$" to EOF.
- Updated the atom command documentation and examples to reflect the corrected BOF/EOF markers.
- Adjusted parser tests to expect prepend via "^" and append via "$" with corresponding cursor kinds.
2026-04-29 20:18:27 +02:00
can1357 e019c6aa93 chore: bump version to 14.5.8 2026-04-29 19:42:54 +02:00
can1357 5cd1f361c9 fix(coding-agent/tools): kept root package scripts un-namespaced in runner
- Root package tasks were set to use `namespaced: false` when collected.
- Updated the workspace test to expect `root` instead of `root-app/root` in the tool description.
- Added an assertion that executing `op: "root"` returns root output text directly.
2026-04-29 19:41:20 +02:00
can1357 65507f343e fix(coding-agent/modes): preserved editor drafts for local message_start deliveries
- Tracked locally submitted user signatures for both optimistic and streamed-queue submissions in interactive-mode context state.
- Updated user message_start handling to avoid re-clearing the editor and re-adding chat for locally originated messages.
- Cleared consumed local signatures on queued-message restore and added tests for queued, external, and optimistic message_start editor behavior.
2026-04-29 19:39:26 +02:00
can1357 4ed18a97cc feat(tools): introduced run_command tool API with op-based task routing
- Renamed legacy `just` tool/config wiring to `run_command` and `runCommand.enabled`, replacing the old `just` prompt.
- Added `RunCommandTool` plus prompt and renderer registration so clients use the new `run_command` API.
- Implemented `op`-based runner/task resolution with new runner metadata for Just, Package, Cargo, Make, and Task with error handling.
- Refactored Bash shell rendering helpers and added run-command tests for detection and execution routing behavior.
2026-04-29 19:38:57 +02:00
can1357 40971d9675 feat(coding-agent): marked custom Anthropic models as OAuth-shaped by default
- Added an `isOAuth` model flag and passed it through Anthropic stream calls to force OAuth-shaped request options.
- Extended model-registry config handling with an `auth: oauth` mode and default `isOAuth` resolution for `anthropic-messages` providers while allowing explicit `apiKey` auth to remain unset.
- Added tests covering OAuth defaults and opt-outs for Anthropic and non-Anthropic custom providers.
2026-04-29 19:07:53 +02:00
can1357 e097ad7dba feat(coding-agent/tools): added just tool support for project recipe execution
- Added a new `just` tool that validates availability of a `just` binary, loads a local justfile, and executes user-specified recipes.
- Registered and exposed `JustTool` through exports, the builtin tool map, and availability checks controlled by `just.enabled` setting.
- Updated tool selection to auto-include `just` when `bash` is requested and tool settings allow it.
2026-04-29 18:57:37 +02:00