Commit Graph

4038 Commits

Author SHA1 Message Date
Can Bölük 7cc7282034 Merge branch 'main' into fix/retry-model-fallback-toggle 2026-06-06 13:47:25 +02:00
Can Bölük e8f1cbb7d3 Merge branch 'main' into fix/ttsr-enabled-1767 2026-06-06 13:45:30 +02:00
can1357 52c1f62028 Merge remote-tracking branch 'origin/farm/75ea0bb0/fix-review-render-yield-non-array' 2026-06-06 13:38:59 +02:00
can1357 f7974e0f23 Merge remote-tracking branch 'origin/farm/f646bd45/fix-windows-ctrl-enter-followup' 2026-06-06 13:38:52 +02:00
can1357 604cf9fae6 Merge remote-tracking branch 'origin/farm/fd5abf01/support-rust-analyzer' 2026-06-06 13:38:37 +02:00
can1357 577b72b5a1 Merge remote-tracking branch 'origin/farm/7fc89500/resume-input-invisible' 2026-06-06 13:38:18 +02:00
roboomp 1ffa6dc6fb fix(coding-agent): guarded task renderer against non-array yield slot
renderAgentResult and the live-progress sibling cast
extractedToolData?.yield to Array<{ data }> and called ?.map without
checking the actual runtime shape. Optional chaining only short-circuits
on null/undefined, so any stray non-array value (a single yield object
landing in the slot) made .map undefined and threw
TypeError: completeData?.map is not a function — taking down every
`review` task render.

Both sites now route through a new normalizeYieldData helper (next to
normalizeReportFindings) that returns an array of yield records: it
preserves arrays unchanged, wraps a single object as a 1-element array
so the verdict still renders, and drops primitives. Added a regression
test exercising the result branch, the progress branch, the primitive
fall-through, and the canonical array shape — all of the failing-branch
ones reproduce the crash on the pre-fix renderer.

Fixes #1987
2026-06-06 11:16:44 +00:00
QianYan-Art 55c4efec4e fix(coding-agent): honor ttsr.enabled: false in TtsrManager
`TtsrManager` previously ignored the `ttsr.enabled: false` toggle:
- `addRule()` still registered rules, so `bucketRules` demoted them
  to the TTSR bucket and dropped the rulebook/alwaysApply fallback
- `hasRules()` still returned true, so `AgentSession` entered the
  TTSR matching path on every message_update
- `checkDelta` / `checkSnapshot` (via `#matchBuffer`) still matched
  patterns and could abort the stream and inject system reminders

Gate all three public-ish entry points on `#settings.enabled` so
disabling TTSR short-circuits the whole path. Condition rules fall
through to the rulebook bucket in `bucketRules` instead of being
silently swallowed.

Closes #1767
2026-06-06 04:05:04 -07:00
roboomp 09c8bf0f9a fix(keybindings): ignored stale Ctrl+Q config claims
The Ctrl+Q follow-up fallback should only be removed when a recognized
keybinding action claims that chord. Unknown or stale config entries are
ignored by the keybinding manager and should not suppress a working
follow-up default.

Addresses code review on #1905.
2026-06-06 08:39:05 +00:00
roboomp 9c8a6d208f fix(lsp): handled workspace/workspaceFolders requests
Returned the current workspace folder list when a server queried workspace/workspaceFolders after initialization so advertising the capability no longer left late requests answered with -32601.
2026-06-06 06:38:27 +00:00
roboomp cdcf74bb07 fix(lsp): opened rust analyzer files before workspace wait
Ensured rust-analyzer textDocument/didOpen ran before workspace readiness polling so the server could discover the file's Cargo workspace, and skipped the readiness wait entirely for standalone .rs files outside any Cargo workspace ancestor.
2026-06-06 06:32:41 +00:00
roboomp 17089d1702 fix(lsp): retried rust analyzer status timeouts
Continued rust-analyzer workspace readiness polling across transient analyzerStatus request timeouts while preserving early exit for unsupported methods and server failures.
2026-06-06 06:23:00 +00:00
roboomp e3107fa7b4 fix(lsp): supported rust analyzer workspaces
Advertised workspace folder support during LSP initialization and waited for rust-analyzer to finish loading Cargo workspaces before opening project-indexed files.

Fixes #1976
2026-06-06 06:17:39 +00:00
roboomp 4a83507408 fix(tui): honored resume clear replay before initial paint
Fixes #1972
2026-06-06 05:00:03 +00:00
roboomp 867ee74a3b fix(eval): probed Win32 console directly instead of inferring from stdio
The TTY-OR heuristic still mis-classifies the all-stdio-redirected case:
`omp -p "..." < in.txt > out.txt 2> err.log` from a real Windows Terminal
session has `stdin.isTTY === stdout.isTTY === stderr.isTTY === false`,
but the host process can still own a console that the kernel could
inherit. The TTY signals reflect handle redirection, not console
attachment — `GetConsoleWindow()` is the authoritative Win32 signal.

`spawn-options.ts` now:

- Calls `kernel32!GetConsoleWindow()` via `bun:ffi` on Windows. A non-NULL
  HWND means the host has a console regardless of how the standard
  streams are wired, so `windowsHide` stays `false` and the kernel
  inherits the console — which is what fixes the #1960
  numpy/pandas `LoadLibraryExW` hang and lets SIGINT recover via
  `GenerateConsoleCtrlEvent`.
- Falls back to the TTY-OR heuristic when the FFI probe is unavailable
  or off-Windows. That keeps the predicate working on non-Bun-FFI
  runtimes and on POSIX, where `windowsHide` is a no-op anyway.
- Caches the probe result; console attachment is stable for the host's
  lifetime in practice, and dlopening kernel32 on every kernel spawn
  would be wasteful.

The pure helpers (`shouldHideKernelWindow`, `consoleAttachedViaTTY`)
stay separately exported so they remain unit-testable. The integration
boundary `hostHasInheritableConsole()` is what the kernel spawn site
calls, and its return is asserted to be a concrete boolean (kernel spawn
must commit to a `windowsHide` value).
2026-06-06 01:04:13 +00:00
roboomp 69ffc80368 style: bun run fix 2026-06-06 00:59:23 +00:00
roboomp 8a89ce7de3 fix(eval): widened Python kernel console detection beyond stdout TTY
Stand-alone `process.stdout.isTTY` mis-classifies any partial stdio
redirection — `omp -p "..." > out.txt` reports `stdout.isTTY === false`
even though the parent still owns a console via stdin/stderr. With the
previous check the kernel would have been spawned with `CREATE_NO_WINDOW`
in that scenario and re-hit the #1960 numpy/pandas `LoadLibraryExW` hang
and broken SIGINT.

The host owns a console it can share with the child whenever ANY of
stdin / stdout / stderr is still a TTY; only a fully detached launch
(true service / daemon, or `< in > out 2> err`) has nothing to inherit.

Renamed the predicate parameter to `hostHasInheritableConsole` so the
contract is unambiguous, and added five regression tests covering the
realistic shell redirection combinations.
2026-06-06 00:59:19 +00:00
roboomp 718c8b299b fix(eval): stopped detaching the Python kernel's console on Windows
`PythonKernel.start()` spawned the runner with `windowsHide: true`, which
in Bun maps to the Win32 `CREATE_NO_WINDOW` flag — that detaches the
long-lived child from any inherited console. Two consequences for OMP's
Python eval on Windows:

1. Native extensions that probe the console at init (e.g. NumPy's
   `_core/_multiarray_umath.pyd` plus its bundled OpenBLAS/SLEEF
   thread-pool init) can deadlock inside `LoadLibraryExW`, so the very
   first `import pandas` / `import numpy` after a cold kernel never
   returned. The reporter's faulthandler stack pinned the hang to
   `_bootstrap_external.create_module` → `numpy/_core/multiarray.py:11`.
2. SIGINT cannot be delivered to a console-less process via
   `GenerateConsoleCtrlEvent`, so the host's `proc.kill("SIGINT")`
   silently no-ops — matching the reporter's "kernel unresponsive to
   interrupt" log line. The 5s escalation then hard-kills the kernel.

Plain `python.exe -u -c "import pandas"` from the same venv inherits the
terminal's console and runs to completion, which is the contract this
change restores. The Python kernel now hides its window only when the
host itself has no console to share (service / piped launch); an
interactive TUI launch lets the kernel inherit the parent's console —
analogous to `python.exe` invoked from `cmd.exe`.

The `shouldHideKernelWindow` predicate lives in its own module so it can
be unit-tested without dragging in the kernel's runtime dependencies.
Short-lived helper subprocesses elsewhere (LSP probes, git, plugin
installs) intentionally keep `windowsHide: true` — they don't load
complex native modules and a brief console flash would be user-visible
noise.

Fixes #1960
2026-06-06 00:53:45 +00:00
can1357 2e425b7b65 docs(coding-agent): documented auto discovery mode behavior
- Described "auto" default gating MCP tools past 40-tool threshold.
- Noted late resolution in createAgentSession after registry exists.
- Updated legacy mcp.discoveryMode mapping to MCP-only.
2026-06-06 01:14:14 +02:00
can1357 06eeda029d feat(coding-agent): added atomic branch+tag push to green command
- Resolved current branch and push remote for ci-green context.
- Updated prompt to push branch and tag together via git push --atomic.
2026-06-06 01:12:39 +02:00
can1357 f5a938f859 feat(coding-agent): added auto tool discovery mode
- Made "auto" the default, hiding MCP tools past 40-tool threshold.
- Centralized discovery mode resolution in shared mode helper.
- Activated search tool in createAgentSession once full registry exists.
2026-06-06 01:12:26 +02:00
can1357 efd6703580 fix: fixed native scrollback behavior for append-only assistant streams
- Fixed assistant transcript blocks to expose append-only commit-safe boundaries.
- Updated TUI live-region commit and pinned-paint logic to clamp commit-safe ends.
- Fixed long streamed assistant replies to remain in native scrollback on overflow.
2026-06-06 00:43:16 +02:00
can1357 ca143a4e08 feat(coding-agent): pinned turn-ending provider errors above editor
- Added a persistent error banner so stream errors survive transcript scroll.
- Cleared the banner when the next turn starts.
- Skipped pinning for aborts and normal stops.
2026-06-06 00:23:07 +02:00
can1357 340ac31122 fix(coding-agent): appended queued image messages synchronously
- Removed async image-link materialization between user message_start and addMessageToChat.
- Fixed steering bubbles rendering below the tool output they were sent to steer.
- Materialized clickable image links via synchronous blob-store fallback instead.
2026-06-05 23:57:01 +02:00
can1357 388e6462c3 fix(coding-agent): fixed cold-launch scrollback and frozen abort labels
- Cleared native scrollback on `omp`/`omp -c` so the resumed transcript no longer stacks on the prior run's welcome screen.
- Tracked assistant block finalization so aborted streaming messages stay repaintable when status rows land beneath them on ED3-risk terminals.
2026-06-05 23:50:49 +02:00
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
can1357 70c94efabe fix(coding-agent): froze live region by block finalization state
- Replaced bottom-most-block liveness with a finalization check so the live region spans every still-mutating block.
- Kept unfinalized tools repaintable when out-of-band inserts append finalized blocks below them.
- Recomputed blocks as they cross out of the live region to seal their final content.
2026-06-05 23:34:05 +02:00
can1357 9114607ce6 feat(coding-agent): surfaced active model in system prompt
- Rendered the active model identifier into the project prompt.
- Rebuilt the cached base prompt on model switch to avoid staleness.
2026-06-05 23:08:44 +02:00
can1357 78700a2c77 feat(ollama): added OLLAMA_HOST and OLLAMA_CONTEXT_LENGTH support
- Used OLLAMA_HOST for implicit discovery when OLLAMA_BASE_URL is unset.
- Applied OLLAMA_CONTEXT_LENGTH override to discovered context budgeting.
2026-06-05 22:47:40 +02:00
can1357 510f3ad33f fix(web-search): rendered full markdown answer when expanded
- Stopped capping the synthesized answer at 12 lines while sources expanded in full.
- Rendered the answer through Markdown so headings, bold, lists, and code display formatted.
- Added regression tests for expanded/collapsed answer rendering.
2026-06-05 21:57:20 +02:00
can1357 5868b9b076 Merge remote-tracking branch 'origin/farm/b61bffd8/plugin-install-local-path' 2026-06-05 20:43:15 +02:00
can1357 45d2baa5c5 Merge remote-tracking branch 'origin/farm/7f076fbd/bound-local-model-memory' 2026-06-05 20:43:11 +02:00
can1357 19f7858cab Merge remote-tracking branch 'origin/farm/db4fe133/run-watch-honor-explicit-repo' 2026-06-05 20:42:49 +02:00
can1357 5184b565e1 fix(eval): kept Python kernel alive when parallel() cell interrupted
- Resolved in-flight bridge calls the instant the cell's signal aborts.
- Let the kernel unwind via KeyboardInterrupt instead of being hard-killed.
- Preserved persistent session state across wide subagent fan-out teardown.
2026-06-05 20:42:29 +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 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
roboomp 7b488b5675 fix(cli): routed plugin install local paths through link instead of npm
`omp plugin install .` (and any cwd-relative, absolute, or tilde-prefixed
spec) failed with `Invalid package name: .` because
`classifyInstallTarget` only emitted `marketplace` / `npm`, so local paths
fell through to `validatePackageName`, which rejects every non-npm name.

The classifier now emits a third `local` arm for `.`, `..`, `./…`,
`..\…`, `~`, `~/…`, `~\…`, `/…`, `C:\…`, `C:/…`, and `\\unc` specs.
`handleInstall` dispatches that arm to `PluginManager.link()` — the same
code path as `omp plugin link <path>` — so the two verbs are
interchangeable for local plugin directories. `--dry-run` short-circuits
before any filesystem work, `--scope`/`--force` surface a warning since
they are no-ops here (link is idempotent, and scope only governs
marketplace installs).

Coverage: thirteen-case classifier matrix in `marketplace/cli.test.ts`
plus a new `plugin-install-local.test.ts` with spy-based routing checks
for `./`, `../`, `/`, `~/`, plus a real-filesystem test that stages a
plugin folder, invokes `runPluginCommand`, and verifies the resulting
symlink + lockfile entry. The new test calls `mock.restore()` in
`afterEach` so `piUtils` / `MarketplaceManager.prototype` spies do not
leak into sibling suites.

Fixes #1945
2026-06-05 17:48:54 +00:00
roboomp 6252972ab0 fix(providers): recycled failed local model workers
Hard-killed the tiny-model subprocess after worker-reported execution errors so ONNX native allocations are released before retries.

Added a fake-worker regression for the unknown-failure path and queued local completions.

Fixes #1940
2026-06-05 16:48:08 +00:00
can1357 61f11a6ce0 fix(tui): blocked destructive scrollback replay on unknown terminal viewports
- Blocked checkpoint scrollback replay unless native viewport-at-bottom proof succeeded.
- Expanded ED3-risk terminal detection to include SSH, multiplexer, WT-like, and unknown profiles.
- Added sync-output defaults with PI_TUI_SYNC_OUTPUT and PI_FORCE_SYNC_OUTPUT overrides.
- Deferred transcript thawing until native scrollback refresh returned true.
- Adjusted non-escape parsing to emit one Unicode scalar and raised timeout to 75ms.
2026-06-05 17:47:47 +02:00
can1357 492b454141 fix(archive): read zip central directory without inflating members
- Parsed zip metadata via central directory and lazy ranged reads.
- Inflated member contents only when a specific entry is read.
- Prevented large or corrupt zips from freezing directory reads.
2026-06-05 17:38:24 +02:00
can1357 1002ba0242 feat(search): accepted internal URL selectors as line filters
- Added selectorLineRanges to extract ranges from raw/conflicts selectors.
- Routed internal URLs through URL-aware splitter in content search.
- Treated display-mode selectors as whole-resource searches instead of rejecting.
2026-06-05 16:29:58 +02:00
can1357 da18b51e21 docs(rules): added exception for named non-obvious formulas
- Allowed tiny functions that name a magic-constant computation the inlined expression wouldn't explain.
2026-06-05 15:52:11 +02:00
can1357 8943fb8084 refactor(file-mentions): removed fuzzy and prefix resolution for @-mentions
- Resolved @-mentions to exact existing paths only.
- Relied on the TUI @-selector to insert complete real paths.
- Dropped candidate scanning to avoid dragging in same-named files.
2026-06-05 15:51:37 +02:00
can1357 1dfab0a883 fix(file-mentions): resolved trailing-slash mentions to directories only
- Made `@`-mention resolution directory-aware so a mention ending in `/` or `\` matches only directory candidates.
- Stopped stripping the trailing separator and fuzzy-matching an arbitrary same-named file (e.g. npm scopes like `@scope/`).
- Left non-slash mentions unchanged.
2026-06-05 15:47:53 +02:00
metaphorics af71e91a1c fix(coding-agent): allow retry without model fallback
Add retry.modelFallback so users can keep automatic retry enabled while preventing retry recovery from switching through configured fallback model chains.

The default remains enabled, preserving existing fallback behavior. When disabled, retry still honors retry-after delays and retry limits while staying on the primary model.

Op: correct

Restores: spec:retry can stay enabled without automatic model switching
2026-06-05 19:38:58 +09:00
can1357 2f9645c40d Merge remote-tracking branch 'origin/farm/b818bb5f/allow-opting-out-of-max-output-tokens-per-model' 2026-06-05 11:45:32 +02:00