Commit Graph

10726 Commits

Author SHA1 Message Date
can1357 02f870fb20 feat: supported markdown section operations for block edits
- Added tree-sitter markdown support to resolve headings into full sections in `pi-ast`.
- Enabled block operations (`SWAP.BLK`, `DEL.BLK`, `INS.BLK.POST`) on markdown headings so they encompass the entire section, including nested deeper headings.
- Updated system prompt to guide agents in using structured markdown heading edits for plans.
- Fixed `plan-mode-guard` to correctly resolve local protocol options for subagents.
2026-06-26 16:14:23 +02:00
can1357 6ecdb5637d Merge remote-tracking branch 'origin/farm/c4e0cc3d/fix-windows-mcp-conhost-windows' 2026-06-26 15:56:22 +02:00
roboomp 52d1a04652 fix(mcp): reused attached windows console for stdio wrappers
Detected whether the OMP host already owns an inheritable Windows console before resolving stdio MCP spawn flags.

Skipped CREATE_NO_WINDOW for console-attached MCP wrapper chains so cmd.exe and PowerShell grandchildren reuse the existing terminal instead of allocating visible conhost windows.

Fixes #3567
2026-06-26 13:54:10 +00:00
can1357 44368e3459 test(coding-agent): removed tests using source-grep patterns
- Removed multiple test files and cases that relied on brittle source string matching for validation.
- Updated project architecture documentation to explicitly prohibit source-grep style testing patterns.
- Eliminated legacy reproduction tests for issues that reached project maturity.
2026-06-26 15:51:34 +02:00
can1357 c39b655ae7 feat: implemented -q and -x flags for in-process grep
- Added support for `--quiet` (`-q`) and `--line-regexp` (`-x`) to the `grep` builtin.
- Enabled short-circuiting behavior for `-q` to suppress output and return early on the first match.
- Configured exit status logic to prioritize successful matches over error states when using `-q`.
- Added integration tests to verify correct exit status codes and line anchoring behavior.
2026-06-26 15:47:24 +02:00
can1357 683877f924 build(vendor/uu-find): disabled unit tests for uu-find crate
- Disabled unit tests for the uu-find crate by setting test to false.
- Added a note explaining that the tests depend on missing vendored fixtures.
2026-06-26 14:41:01 +02:00
can1357 415099c420 fix: stripped stale snapcompact archive state during compaction strategy migration
- Fixed stale `preserveData.snapcompact` frames leaking into context-full compaction after switching from `snapcompact` to `context-full` strategy, which inflated context usage and made sessions appear to compact prematurely.
- Added secret redaction for migrated snapcompact archive plaintext (`text`/`textHead`/`textTail`) during the snapcompact->context-full transition, while preserving opaque provider-replay state byte-identical.
- Added `archiveSourceText()` and `stripPreservedArchive()` utilities to snapcompact module for archive extraction and cleanup.
2026-06-26 14:31:50 +02:00
can1357 93b80e5b1b refactor: consolidated duplicate
- Consolidated duplicate `stripSnapcompactPreserveData` functions into `snapcompact.stripPreservedArchive`.
- Added unit tests to verify archive removal and empty state collapse behavior.
2026-06-26 14:28:49 +02:00
Can Bölük 13100cbade Merge pull request #3561 from serverinspector/fix/snapcompact-context-full-transition
fix(agent): stop stale snapcompact state leaking into context-full
2026-06-26 14:21:24 +02:00
can1357 1be061a052 chore: added arg3t to vouched list
- Added arg3t to the .github/VOUCHED.td file.
2026-06-26 14:17:45 +02:00
can1357 ac904fc70c fix: patched Kimi model edit mode fallback
- Added a fallback from `hashline` to `replace` mode for Kimi-family models to resolve compatibility issues.
- Introduced `PI_STRICT_EDIT_MODE` environment variable to bypass automatic model-specific edit-mode fallbacks.
- Updated `getEditVariantForModel` to perform case-insensitive matching for model variant configurations.
- Added comprehensive unit tests for edit mode resolution and settings configuration.
2026-06-26 13:17:35 +02:00
can1357 9751886e90 Merge remote-tracking branch 'origin/farm/9a8c4588/hide-colab-advisory-tags' 2026-06-26 13:05:12 +02:00
roboomp c58cef161b fix(collab): hid advisory tags in transcript markdown
Stripped advisory wrapper tags in the collab web Markdown renderer while preserving escaped advisory content and existing raw HTML escaping.

Added a regression test for assistant advisory blocks in the collab transcript renderer and documented the fix in the collab-web changelog.

Fixes #3559
2026-06-26 10:51:42 +00:00
can1357 68d7593244 chore: reorg 2026-06-26 12:24:42 +02:00
can1357 7a5930e2db Merge remote-tracking branch 'origin/farm/f9c014e9/fix-plan-approval-model-slider' 2026-06-26 12:08:44 +02:00
roboomp f6e19d258c fix(coding-agent): skipped plan execution model when slider hidden
Hidden slider means the operator made no choice; a singleton cycle built around the active plan model must not be pinned as executionModel, otherwise approval re-applies the plan model after #exitPlanMode restored the pre-plan one.

Added regression coverage for the plan-only role configuration.

Refs #3554
2026-06-26 10:05:49 +00:00
can1357 7bd326e6f4 fix(pi-shell): resolved find -exec paths against shell working directory
- Ensure `-exec` commands run in the shell current working directory rather than the host process CWD.
- Update operand path resolution in `find` matchers to use the display path, matching behavior expected by shell-integrated utilities.
- Add an integration test to verify path substitution and execution context for shell-integrated `find`.
2026-06-26 12:04:12 +02:00
can1357 ff573585dc Merge branch 'farm/f9c014e9/fix-plan-approval-model-slider' 2026-06-26 12:03:24 +02:00
can1357 b5dac65b31 feat: implemented coreutils shell builtins via in-process execution
- Introduced `pi-uutils-ctx` to manage thread-local I/O redirection, environment context, and path resolution for in-process utilities.
- Integrated a suite of vendored coreutils (cat, find, grep, head, ls, mkdir, mv, rm, sort, tail, uniq, wc) as shell builtins.
- Added infrastructure for command cancellation, streaming I/O, and locale-aware error reporting within the shell environment.
- Configured shell-side dispatch logic to route commands through the new utility context, enhancing performance and binary integration.
2026-06-26 12:00:34 +02:00
roboomp f7342a56d0 fix(coding-agent): honored role thinking in plan approval match
Same-model role with an explicit thinking suffix that differs from the pre-plan thinking now passes through applyRoleModel instead of being treated as an implicit match.

Added regression coverage for the sonnet:off vs pre-plan thinking-high case.

Refs #3554
2026-06-26 09:57:33 +00:00
roboomp bf2e752bbb fix(coding-agent): retained plan approval slider model
Compared the selected approval tier against the model restored after plan mode instead of the active plan-mode tier.

Added regression coverage for keeping the active planning model selected on approval.

Fixes #3554
2026-06-26 09:49:10 +00:00
can1357 d8d9613a6d test(ai): verified cleanup of first-item watchdog timer
- Implement `drainMicrotasksUntil` helper to manage async race conditions during tests.
- Add fake timer validation to ensure the first-item watchdog is cleared when the upstream source rejects.
- Restore real timers in `afterEach` to prevent test contamination.
2026-06-26 11:43:38 +02:00
OpenAI GPT-5.5 531faf80a5 fix(agent): strip snapcompact state on session compaction
Co-Authored-By: OpenAI GPT-5.5 <noreply@openai.com>
2026-06-26 09:43:02 +00:00
can1357 f4ea94a3ea Merge remote-tracking branch 'origin/farm/c2e2fbf1/llama-cpp-with-auto-learn-capture-at-sto' 2026-06-26 11:15:29 +02:00
can1357 de34b5806e Merge remote-tracking branch 'origin/farm/d1145a36/mcp-oauth-cross-host-issuer' 2026-06-26 11:14:55 +02:00
can1357 98292c691d Merge remote-tracking branch 'origin/farm/6e5871b1/fix-lsp-config-cache-invalidate-on-reload' 2026-06-26 11:14:50 +02:00
roboomp a39bad3ae8 fix(ai): gate top-level preserve_thinking by Qwen dialect to keep NIM happy
Review catch: the hoisted twin emit set `params.preserve_thinking = true`
unconditionally for any Qwen + local target, but NVIDIA NIM's request
schema is `additionalProperties: false` and rejects unknown top-level
fields with HTTP 400 — the same #2299 quirk the catalog already routes
around by sending `enable_thinking` only under `chat_template_kwargs` for
the `qwen-chat-template` dialect. The NIM Qwen Q on a loopback baseUrl
(qwenPreserveThinking auto-enables) would have been broken before it
reached the kwargs copy.

Mirror the dialect split that already gates `enable_thinking`:

  - thinkingFormat === 'qwen' (llama.cpp / Alibaba compatible-mode): set
    BOTH top-level `preserve_thinking` and the `chat_template_kwargs`
    mirror, like before.
  - thinkingFormat === 'qwen-chat-template' (NVIDIA NIM, vLLM/SGLang's
    chat-template-kwargs path): set ONLY
    `chat_template_kwargs.preserve_thinking`, leave the top-level field
    unset so NIM doesn't 400.

Flipped the existing NIM wire pin to assert top-level `preserve_thinking`
is undefined (and `enable_thinking` is undefined too — it was already
routed to kwargs by the catalog). Changelog reworded to document the
dialect split alongside the NIM rationale.

Verification:
  bun --cwd packages/ai test ./test/issue-3528-repro.test.ts → 26/26 pass
  bun --cwd packages/ai test ./test/issue-3434-repro.test.ts ./test/deepseek-reasoning-content.test.ts ./test/ollama-thinking-disable.test.ts ./test/openai-compat-policy.test.ts ./test/openai-completions-compat.test.ts ./test/openai-completions-tool-result-images.test.ts ./test/issue-967-vision-guard.test.ts → 111/111 pass
  bun --cwd packages/catalog test → 325/325 pass
  bun --cwd packages/ai check:types → clean
2026-06-26 09:13:52 +00:00
roboomp 30fd21a9ea style: bun run fix 2026-06-26 09:06:52 +00:00
roboomp 801022bb45 fix(auth): accepted cross-host mcp oauth issuer
Allowed resource-server fallback OAuth discovery to accept authorization-server metadata whose issuer differs from the resource URL while keeping issuer matching for advertised auth-server candidates.

Added an Atlassian-shaped regression test so the fallback path no longer returns null.

Fixes #3551
2026-06-26 09:06:32 +00:00
roboomp 3cc61d3014 fix(ai): hoist preserve_thinking above reasoning gate for discovered local Qwen
Review catch: `applyChatCompletionsCompatPolicy` emitted preserve_thinking
only inside the `if (reasoning.enabled)` branch, so it never reached the
wire for the most common local-llama.cpp case: models built by
`discoverOpenAICompatibleModels` carry `reasoning: false` (the generic
/v1/models endpoint can't advertise the capability), `model.reasoning ===
false` short-circuits the reasoning encoder, and the request still shipped
`reasoning_content` (via replayReasoningContent, correctly ungated since
#3532's b6d81f22) for the template to strip <think> from older turns
anyway.

Hoist the emission above the early-return + reasoning-state branches so it
fires whenever `compat.qwenPreserveThinking` is set, regardless of
`reasoning.enabled` / `reasoning.disabled`. Three cases now covered that
were missed before:

  1. Discovered local Qwen (reasoning: false in spec) — the case the
     reviewer flagged.
  2. Caller-disabled reasoning (/think off) — the kwarg is a HISTORY
     rendering knob, not a per-turn switch, and the slot still holds
     <think> tokens from earlier turns. Stripping them on re-render
     invalidates the cache at the first historic <think>.
  3. Forced-tool-choice / DeepSeek-style auto-disable — same history
     reasoning as (2).

The qwen-template-false branch in the same function now spreads existing
chat_template_kwargs when setting enable_thinking: true so the
preserve_thinking entry hoisted above survives the merge (the old bare
assignment would have clobbered it).

Three new wire pins added on top of the existing five:

  - Discovered local Qwen (reasoning: false, no reasoning option):
      preserve_thinking: true rides; enable_thinking stays unset (server
      falls back to template default).
  - Discovered local Qwen + disableReasoning: preserve_thinking still
      rides — the model's reasoning gate doesn't suppress history rendering.
  - NVIDIA NIM Qwen on loopback (qwen-chat-template dialect):
      chat_template_kwargs carries both enable_thinking and
      preserve_thinking; the spread merge keeps both.

Existing "does NOT emit when disabled" pin flipped to "emits even when
disabled" to match the corrected history-knob semantics.

Verification:
  bun --cwd packages/ai test ./test/issue-3528-repro.test.ts → 26/26 pass
  bun --cwd packages/ai test ./test/issue-3434-repro.test.ts ./test/deepseek-reasoning-content.test.ts ./test/ollama-thinking-disable.test.ts ./test/openai-compat-policy.test.ts ./test/openai-completions-compat.test.ts ./test/openai-completions-tool-result-images.test.ts ./test/issue-967-vision-guard.test.ts → 111/111 pass
  bun --cwd packages/catalog test → 325/325 pass
2026-06-26 08:55:45 +00:00
roboomp b761cd0c20 test(lsp): used explicit LspConfig fixture type
The reload-cache regression fixture used ReturnType<typeof loadConfig>,
which violates the repository style rule banning ReturnType<>. Import and
use the explicit LspConfig type instead.

Fixes #3546
2026-06-26 08:53:53 +00:00
can1357 14ae777f50 Merge remote-tracking branch 'origin/farm/95813719/windows-mcp-stdio-no-detached' 2026-06-26 10:48:52 +02:00
roboomp 58af613fca fix(lsp): invalidated configCache on reload * so newly written .omp/lsp.json is observed
getConfig() in packages/coding-agent/src/lsp/index.ts cached the first
loadConfig() result per cwd permanently. If .omp/lsp.json, root markers,
or plugin LSP configs were added after the first LSP call, they stayed
invisible for the remainder of the process lifetime — even after the
user explicitly requested 'reload *' — because the reload handler
operated on the same stale config object retrieved at the top of
execute().

The reload-workspace branch now deletes the per-cwd cache entry and
re-runs getConfig() before iterating servers, so the refresh behaves as
the prompt documents. The cache is repopulated by the fresh read, so
subsequent calls still avoid the disk hit until the next 'reload *'.

Fixes #3546
2026-06-26 08:48:26 +00:00
can1357 7a06985cfa chore: added serverinspector to vouched list
- Added serverinspector to the .github/VOUCHED.td registry.
2026-06-26 10:48:24 +02:00
roboomp ac958d5905 fix(ai): emit Qwen preserve_thinking so local-server cache survives new user messages
The Qwen3 / Qwen3.6 chat template strips <think>...</think> from every
assistant turn whose loop.index0 <= ns.last_query_index, so the moment a
new user message (the user's real next prompt OR the auto-learn
capture-at-stop nudge) lands, every prior assistant turn becomes 'older'
and is re-rendered without its <think> block — diverging from the
generation tokens still in the local slot's KV cache and forcing full
prompt re-processing on SWA models.

Sending reasoning_content alone (the #3528 fix) does not help: the
template's older branch renders only `content`, never the
reasoning_content field. The official Qwen3.6 fix is
`preserve_thinking: true`, which makes the template render
<think>\n{reasoning_content}\n</think>\n\n{content} for every assistant
turn regardless of position.

- packages/catalog/src/compat/openai.ts: new qwenPreserveThinking shared
  compat flag, auto-enabled when the resolved thinkingFormat is `qwen`
  or `qwen-chat-template` AND replayReasoningContent is on (the four
  local provider ids plus loopback / RFC1918 / *.local baseUrls).
  Responses-API builder pins it false — it's a chat-template knob,
  irrelevant on the Responses surface.
- packages/ai/src/providers/openai-shared.ts: chat-completions encoder
  emits preserve_thinking: true alongside enable_thinking: true in both
  Qwen disable-mode branches (twin top-level + chat_template_kwargs
  emission so llama.cpp / vLLM / SGLang and Alibaba's compatible-mode
  wire shapes all pick it up). Stays off when thinking is disabled.
- packages/ai/test/issue-3528-repro.test.ts: nine new pins covering the
  auto-detection matrix, the wire emission on local Qwen + thinking, the
  cloud-Qwen / reasoning-disabled negative cases, and the
  explicit-override escape hatches in both directions.
- Backfilled qwenPreserveThinking: false on three hand-rolled
  ResolvedOpenAICompat fixtures so the required field stays satisfied.
- AI + catalog changelog entries under ## [Unreleased].

Verification:
  bun --cwd packages/ai test ./test/issue-3528-repro.test.ts ./test/openai-completions-compat.test.ts ./test/openai-completions-tool-result-images.test.ts ./test/issue-967-vision-guard.test.ts → 87 pass
  bun --cwd packages/ai test ./test/issue-3434-repro.test.ts ./test/deepseek-reasoning-content.test.ts ./test/ollama-thinking-disable.test.ts ./test/openai-compat-policy.test.ts → 37 pass
  bun --cwd packages/catalog test → 325/325 pass
  bun --cwd packages/ai check:types && bun --cwd packages/catalog check:types → clean

Fixes #3541
2026-06-26 08:44:28 +00:00
roboomp 6c80bf6c87 fix(mcp): stayed attached on Windows stdio so nested cmd wrappers keep stdout routed back
StdioTransport.connect() unconditionally passed detached:true to
Bun.spawn. POSIX needs this so terminal job-control signals (SIGTSTP,
SIGTTIN) cannot stop stdio servers such as chrome-devtools-mcp; Windows
has no equivalent signals, but detached:true maps to
CreateProcess(DETACHED_PROCESS), which strips the parent's inherited
console. windowsHide:true (#3536) hides the direct child's window but
nothing else — when the direct child was a hidden cmd.exe wrapper that
later spawned a console grandchild (node wrapper, npx.cmd -y mcp-remote,
similar nested shells) the grandchild allocated a brand-new visible
conhost and its stdout no longer routed through OMP's pipe. The proxy
terminal reported the MCP bridge was healthy while OMP timed out
waiting for the MCP initialize response.

Move detached into StdioSpawnCommand alongside windowsHide so every
platform-derived spawn flag is resolved in one place:
resolveStdioSpawnCommand returns detached:false on every Windows return
shape (direct .exe, cmd.exe-wrapped batch/unresolvable command, npm
cmd-shim launched through node) and detached:true on POSIX. connect()
consumes the resolved flag. Add a regression test for the reporter's
exact shape (cmd.exe /C node wrapper) and assert detached on every
existing Windows / POSIX case so the contract cannot regress per-path.

Fixes #3544
2026-06-26 08:37:32 +00:00
OpenAI GPT-5.5 d7fdeb8e2b fix(agent): use static snapcompact archive prompt
Co-Authored-By: OpenAI GPT-5.5 <noreply@openai.com>
2026-06-26 08:21:11 +00:00
OpenAI GPT-5.5 5c4e269900 fix(agent): migrate snapcompact archive on context compaction
Co-Authored-By: OpenAI GPT-5.5 <noreply@openai.com>
2026-06-26 08:15:17 +00:00
can1357 305db55cd7 fix(coding-agent/eval): surfaced the exception type and message in the
- Surface the exception type and message in the error display by prepending the formatted error string to the traceback array.
- Prevent the host from hiding the actual error by ensuring the traceback is not empty, consistent with other language runners.
2026-06-26 10:06:48 +02:00
can1357 531f4cd7e4 ux(ai/registry): applied the oh-my-pi branding identity including a
- Applied the oh-my-pi branding identity including a custom font family, dark color palette with OKLCH colors, and brand gradient wordmark.
- Replaced static background with an ascii grid pattern and radial light accents.
- Improved layout aesthetics with frosted-glass card effects, subtle drop shadows, and refined animations for success/error states.
- Updated the authentication page title and status display with improved accessibility and design coherence.
2026-06-26 09:36:00 +02:00
can1357 ff759ed850 chore: bump version to 16.1.22 2026-06-26 09:19:53 +02:00
can1357 0007489195 chore: update changelogs 2026-06-26 09:19:23 +02:00
can1357 c474c6cde4 Merge remote-tracking branch 'origin/farm/6727da85/mcp-oauth-plane-resource-strip' 2026-06-26 09:19:10 +02:00
can1357 aa6ddf85fa Merge remote-tracking branch 'origin/farm/960c6137/hide-mcp-cmd-windows' 2026-06-26 09:19:04 +02:00
can1357 55f4a08563 Merge remote-tracking branch 'origin/farm/2eab7723/fix-llamacpp-warm-prefix-autolearn-capture' 2026-06-26 09:19:00 +02:00
roboomp fcee2cb783 style: bun run fix 2026-06-26 07:09:36 +00:00
roboomp ff6e1b6e17 fix(mcp/oauth): skip discovery metadata with mismatched issuer
`discoverOAuthEndpoints` probes `/.well-known/oauth-authorization-server` at
the origin root before path-prefixed candidates and returns on the first hit.
Plane hosts a root issuer (`https://mcp.plane.so/`) at origin root and a
separate path-scoped issuer (`https://mcp.plane.so/http`) at the path-prefixed
well-known. The `/http/mcp` endpoint advertises only the path-scoped issuer
through protected-resource metadata, so discovery should follow that issuer's
metadata — instead it accepted the wrong origin-root document and routed the
grant to `https://mcp.plane.so/authorize`, which rejects every request with
`server_error=An unexpected error occurred` before the consent screen.

RFC 8414 §3.3 requires the metadata's `issuer` to equal the URL the client
used to construct the metadata URL. Validate it in the discovery loop: when
the queried well-known is the official authorization-server or OpenID Connect
document, skip metadata whose `issuer` doesn't match (after trailing-slash
normalization). Documents without an `issuer` field keep the existing
permissive behavior so legacy/nonstandard servers continue to work.

Verified live against `https://mcp.plane.so/http/authorize` with the same
client/PKCE: pre-fix `302 -> /callback?error=server_error`, post-fix
`302 -> /http/consent?txn_id=…`. Adds an `oauth-discovery.test.ts`
regression suite covering Plane's wrong-issuer origin-root document plus
trailing-slash and no-issuer paths.

Fixes #3537
2026-06-26 07:09:24 +00:00
roboomp f6005e0d67 fix(mcp): hid stdio windows subprocess consoles
Set windowsHide for every Windows stdio MCP spawn path so direct .exe servers no longer open a visible cmd.exe window.

Added a regression test covering direct Windows executable MCP server launch options.

Fixes #3535
2026-06-26 06:58:19 +00:00
roboomp 8147503e6d style: bun run fix 2026-06-26 06:50:28 +00:00
roboomp 3ecea68688 fix(ai): bypass model.reasoning gate when compat.replayReasoningContent is set
`openAICompletionsReplaysUnsignedThinking` short-circuited to false
when `model.reasoning` was false, ahead of evaluating
`compat.replayReasoningContent`. Since `discoverLlamaCppModels` /
`discoverOpenAIModelsList` hardcode `reasoning: false`, a cross-API
switch into a discovered local llama.cpp Qwen / DeepSeek target
demoted the prior turn's thinking block to plain text, leaving
`convertMessages` nothing to surface as `reasoning_content` — exactly
the cache-stable `<think>` prefix the new compat flag is meant to
preserve.

Reorder the predicate so the local-host replay short-circuits to true
BEFORE the `model.reasoning` gate. Cloud-style flags
(`requiresReasoningContentForToolCalls`, `thinkingFormat === "zai"`)
still require `model.reasoning` — they govern provider-specific
validation that only fires in thinking-engaged requests. Add a
cross-API regression pin: Anthropic-source thinking block + opaque
continuation signature flowing into a discovered local target
(`reasoning: false`) must arrive as `reasoning_content` on the wire,
with the source signature stripped.

Addresses chatgpt-codex review on #3532.
2026-06-26 06:50:21 +00:00