Commit Graph
5955 Commits
Author SHA1 Message Date
Tommaso Fontana 7c9342bee4 fix(omp): run virtual/remote search with the native RE2 dialect (#3553 review)
searchVirtualResources matched with JS RegExp, so an ssh:// (or other virtual) search diverged from local search for RE2-valid but JS-invalid patterns (e.g. (?i)x, [[:digit:]]) — throwing 'Invalid regex' or returning different matches even when local grep had already validated the pattern in a mixed scope. It now detects matched line numbers with native grep (the same RE2 matcher local search uses) and rebuilds the existing forward-only, range-trimmed context windows via buildVirtualMatches, so virtual/remote and local search share one dialect. Removed the now-dead JS-regex helpers (probeRegexDialect, compileVirtualRegex, searchVirtualResource{Lines,Multiline}, findLineIndex).
2026-06-26 20:41:36 +02:00
Tommaso Fontana da2bccfdf9 fix(omp): reject ssh:// URL passwords and empty userinfo (#3553 review)
resolveTarget now rejects a non-empty password (ssh://user:pass@host, ssh://:pw@host) since ssh:// uses key/agent auth (BatchMode), and a literal empty username (ssh://@host) that previously fell through to the bare-host fallback and could match a configured host. Both use the same decoded-authority comparison as the empty-port guard, so a percent-encoded alias like %40prod (decodes to @prod) is still matched.
2026-06-26 20:41:36 +02:00
Tommaso Fontana 36e82776cf fix(omp): let IPv6 ssh:// URLs reach the resolver in search (#3553 review)
search's generic glob-char guard saw the [ ] of an IPv6 authority (ssh://[::1]/etc/hosts) and threw 'Glob patterns are not supported' before the SSH handler could strip the brackets. The check now runs only on the path portion for ssh:// URLs, so IPv6 literals resolve while a glob in the remote path (ssh://host/p*) still rejects.
2026-06-26 20:41:36 +02:00
Tommaso Fontana 33a435af67 fix(omp): stat ssh:// targets before reading to reject special files (#3553 review)
resolve() ran readRemoteFile (head) before any classification, so a FIFO with no writer blocked until the 30s timeout and a device like /dev/zero streamed the whole probe. It now stats first: directory -> listing, special file (other) -> fast refusal, regular file -> read. missing/stat-failure still falls through to the read so the original remote stderr surfaces.
2026-06-26 20:41:35 +02:00
Tommaso Fontana a7d2fb3b21 fix(omp): reject ssh:// overrides on encoded configured aliases (#3553 review)
The override-rejection compared the still-encoded url.hostname, so a user/port override on a reserved-char alias (configured alice@prod addressed as ssh://bob@alice%40prod/) slipped through to the opaque target (bob@alice@prod). The guard now also compares the decoded bare host; the error names the decoded host while suggesting the correct encoded URL.
2026-06-26 20:41:35 +02:00
Tommaso Fontana ceefaf4f6b fix(omp): decode percent-encoded ssh:// username and host for the connection target (#3553 review)
The override path stored url.username/url.hostname verbatim, so ssh://user%40corp@host/ reached OpenSSH as user%40corp@host (wrong user). Decode both before building the SSHConnectionTarget. Decoding happens before buildSshTarget's leading-dash guard, so an encoded %2DoProxyCommand now decodes to -oProxyCommand and is rejected.
2026-06-26 20:41:35 +02:00
Tommaso Fontana 04bc70a8ad fix(omp): reject encoded empty ssh:// port authorities (#3553 review)
The empty-port guard compared decoded url.rawHost against the percent-encoded url.hostname/username, so ssh://prod%2Dblue:/ and ssh://u%2Dname@prod:/ slipped through. Decode both sides before comparing; a %3A alias (decoded host already ends in ':') reconstructs to 'prod::' and is still left alone.
2026-06-26 20:41:35 +02:00
Tommaso Fontana 12b966f90a fix(omp): reject empty ssh:// port (#3553 review)
An empty port (ssh://host:/path) parses with url.port === "" and slipped past the malformed-authority guard as "no port", silently using the default/configured target. resolveTarget now rejects it (raw authority retains the trailing colon; percent-encoded aliases like prod%3A keep %3A in hostname and are unaffected).
2026-06-26 20:41:35 +02:00
Tommaso Fontana f7ff11b15b fix(omp): address #3553 round-2 review feedback
- strip IPv6 URL brackets before invoking ssh (ssh://[::1]/ -> ::1)
- reject malformed/out-of-range ssh:// ports before connecting (prod:abc, host:65536)
- search requests directory metadata only (skipDirectoryListing) instead of draining a remote ls it always rejects
2026-06-26 20:41:35 +02:00
Tommaso Fontana 73c1b33fd9 fix(omp): address #3553 review feedback
- reject explicit ssh:// port 0 before connecting (Codex P2)
- keep a path-less ssh://host:port authority port out of selector peeling
- restore ResolveContext on ProtocolHandler.complete (symmetry with resolve/write)
- clarify search/read selector-parity docs + add read-side regression
2026-06-26 20:41:35 +02:00
Tommaso Fontana 3028bc4ef0 feat(omp): autocomplete ssh:// hosts and list them on bare read
- ssh handler complete() suggests the configured hosts; bare `read ssh://` resolves to an immutable host index (markdown links per host)
- thread a minimal cwd through the completion pipeline (provider basePath -> getInternalUrlSuggestions -> router.complete -> handler.complete) so project-scoped ssh.json hosts resolve like the cwd-aware bare-read path
- scoped to configured SSH-capability hosts; opaque ~/.ssh/config aliases stay usable at ssh://alias/path but are not enumerated
- local handler complete() signature updated to match (behavior preserved; the router never threaded context to it)
2026-06-26 20:41:35 +02:00
Tommaso Fontana e4ceebb258 feat(omp): list ssh:// directories via read
- `read ssh://host/dir` lists a remote directory one level deep; `ssh://host/` lists the remote root
- add statRemotePath + listRemoteDir; resolve reads first and classifies on error (directory -> one-level listing, dirs-first, dotfiles included)
- directory resources carry isDirectory + immutable and expose no sourcePath
- search refuses a virtual (no-sourcePath) directory resource instead of grepping the listing text
- writeRemoteFile refuses a directory destination and cleans up its temp on that path
2026-06-26 20:41:35 +02:00
Tommaso Fontana f9ece90853 fix(omp): harden ssh:// URL handler per PR review
- buildSshTarget rejects destinations beginning with "-" (SSH argument-injection / local RCE guard)
- gate ssh:// read/search/write at the exec approval tier; substring scan covers search's pre-expansion delimited paths and write's hashline-wrapped paths
- validate the entire materialized buffer as UTF-8 instead of only the first 8 KiB prefix
- write peels read selectors (raw/conflicts) so it targets the same file read does, and rejects line-range/malformed selectors instead of silently stripping them
- write to a uniquely named remote temp; document symlink-replacement on write as a v1 limit
2026-06-26 20:41:35 +02:00
Tommaso Fontana c63171b909 feat(omp): add ssh:// URL support to read, search, and write 2026-06-26 20:41:35 +02:00
can1357 52b8fb1565 feat(coding-agent): improved session title casing logic
- Updated `normalizeGeneratedTitle` to reconcile model-generated titles against the user's input instead of forcing title-case.
- Added logic to restore distinctive proper-noun casing (e.g., `TinyVMM`) and flatten model-generated camelCase artifacts (e.g., `dAemon`) that do not appear in the user's message.
- Ensured model-cased proper nouns that are not in the source message (e.g., `GitHub`) are preserved.
2026-06-26 20:27:40 +02:00
can1357 5d4203d52b fix(coding-agent): preserved resume scoping after PR merges 2026-06-26 17:17:43 +02:00
can1357 d07d03d2af Merge PR #3565: compact long tool loops mid-turn (@riverpilot) 2026-06-26 17:12:09 +02:00
can1357 b6b0379a3b Merge PR #3540: manual coding-agent GC command (@Kenmege)
# Conflicts:
#	packages/coding-agent/test/issue-3461-repro.test.ts
2026-06-26 17:09:24 +02:00
can1357 80c6528c93 fix(coding-agent): resolved PR 3562 merge fallout 2026-06-26 17:08:53 +02:00
can1357 40e56a6318 Merge PR #3562: resume by ID, Nix/Mermaid highlighting (@arg3t)
# Conflicts:
#	packages/coding-agent/test/issue-3461-repro.test.ts
2026-06-26 17:07:48 +02:00
Alexander Kirilin e9530895a1 Merge remote-tracking branch 'origin/main' into fix/mid-turn-auto-compaction-3525 2026-06-26 11:02:40 -04:00
Alexander Kirilin d2b6bde571 fix(agent): preserve mid-turn tool persistence order 2026-06-26 10:57:36 -04:00
can1357 55b02a568d feat(coding-agent): improved local artifact sandbox handling and path recovery
- Enabled tag-based path recovery for artifacts within the session `local://` sandbox.
- Restructured `hashline` path recovery logic to ensure preflight validation runs on resolved paths.
- Prevented ACP editor buffer routing for session `local://` sandbox artifacts.
- Added comprehensive tests covering sandbox target identification and recovery for bare file names.
2026-06-26 16:39:48 +02:00
can1357 bf110f9a18 feat(coding-agent): updated plan-mode guidance for block-level edits
- Added instructions for writing sections as cohesive multi-line blocks when performing edit operations.
- Clarified that block operations require multi-line sections to avoid falling back to standard editing behavior.
2026-06-26 16:20:05 +02:00
can1357 cf7894ffa1 Merge remote-tracking branch 'origin/farm/2a4ef5fb/use-default-role-for-fresh-startup' 2026-06-26 16:14:50 +02:00
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
roboomp aad2a0fa49 fix(coding-agent): honored modelRoles.default for extension-provided models on fresh launch
The createAgentSession default-role resolution ran before extension
factories registered their providers, so a default role pointing at an
extension-provided model (e.g. an openai-compat plugin's
posthog/claude-opus-4-8) returned undefined there. On a fresh launch
(no -c/--resume) the post-extension fallback went straight to
pickDefaultAvailableModel and replaced the user's configured default
with the first bundled provider default that had auth — commonly
openai/gpt-5.5 when OPENAI_API_KEY was set.

The fallback now retries resolveModelRoleValue against the
post-extension allowed-model set before pickDefaultAvailableModel, and
re-applies the role's explicit thinking selector / model host
preconnect.

Fixes #3569
2026-06-26 14:08:12 +00: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
Alexander Kirilin ab513757f8 fix(agent): preserve tool turn before mid-run compaction 2026-06-26 09:35:24 -04:00
Alexander Kirilin e99b8c4128 docs(agent): clarify mid-turn continuation hook 2026-06-26 09:17:07 -04:00
Alexander Kirilinandcoderred bbe3d98375 fix(agent): compact long tool loops mid-turn
Co-authored-by: coderred <coderredlab@gmail.com>
2026-06-26 09:05:11 -04:00
arg3t b10cea54d7 Merge branch 'main' of https://github.com/can1357/oh-my-pi into lsp-reload-nix-highlight
# Conflicts:
#	packages/coding-agent/src/lsp/index.ts
2026-06-26 06:03:33 -07: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ükandGitHub 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
Dr Kennedy Umege 5ea467aa3c fix: address gc review edge cases 2026-06-26 12:58:30 +01:00
arg3t e7cbe0a9fe fix(coding-agent): resolve slash resume across cwd sessions 2026-06-26 04:51:45 -07:00
arg3t 599874e255 feat(coding-agent): support resume by session id 2026-06-26 04:34:44 -07:00
arg3t e894753603 feat(tui): add mermaid rendering toggle 2026-06-26 04:34:44 -07: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
Dr Kennedy Umege 1912cf93ab fix: align gc dry-run and wal failures 2026-06-26 11:53:44 +01:00
can1357 68d7593244 chore: reorg 2026-06-26 12:24:42 +02:00
Dr Kennedy Umege 087a0a4be0 fix: tighten gc dry-run and failure status 2026-06-26 11:23:33 +01: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 ff573585dc Merge branch 'farm/f9c014e9/fix-plan-approval-model-slider' 2026-06-26 12:03:24 +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
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
arg3t 5ea20952bd fix(coding-agent): rediscover LSPs on workspace reload 2026-06-26 02:33:20 -07:00