Commit Graph

263 Commits

Author SHA1 Message Date
can1357 21a7693dd7 fix(hashline): prevented exposing terminal newline as an addressable row
- Added `splitAddressableFileLines` to strip terminal newlines from line addressability without removing genuine blank lines.
- Updated coding-agent read tool context parsing to use addressable file lines.
2026-08-12 03:22:01 +02:00
can1357 7454b6e78f refactor(coding-agent): split read tool into per-source modules
- ReadTool mixed plain-file reading with archive, sqlite, pdf-image, summary,
  selector, formatting and renderer concerns in one 3763-line module.
- Each now owns a sibling module; read.ts drops to 2020 lines and keeps its
  public exports, including the readToolRenderer re-export required because
  tools/index.ts star-exports ./read through the explicit ./tools entry.
- The pdfImageExtractions map and summaryParseCaches WeakMap stay single
  instances; execute() was deliberately left intact.
2026-08-08 06:32:01 +02:00
can1357 b50b05ee39 Merge PR #7790: fix(read): normalize recovery paths (@roboomp) 2026-08-07 13:39:52 +02:00
roboomp bfd1e64bf6 fix(read): normalized recovery paths
Used the resolved cwd-relative path in summary recovery selectors, PDF image handles, and notebook diagnostics.

Fixes #7788
2026-08-06 03:40:10 +00:00
can1357 ae84aff853 Merge PR #7675: fix(memory): hide disabled memory protocol (@roboomp) 2026-08-05 22:16:28 +02:00
can1357 c01d18eb57 Merge PR #7657: fix(read): split semicolon-delimited internal URLs (@revofusion) 2026-08-05 21:50:25 +02:00
can1357 e9888367d1 refactor: migrated packages to internal utility modules and removed external dependencies
- Implemented in-house, zero-dependency utility modules in `pi-utils` covering DOM manipulation, markdown parsing, templating, browser automation helpers, and terminal buffers.
- Migrated packages across the repository to consume the new internal utilities and `omptype` schema validators instead of external dependencies.
- Removed multiple external runtime and development dependencies including Zod, Marked, LRU cache, Turndown, and Puppeteer browser packages.
2026-08-05 13:39:09 +02:00
roboomp 619412c987 fix(memory): hid disabled memory protocol
Made the Read schema session-aware and rejected memory URLs when the calling session has memory disabled.

Fixes #7673
2026-08-05 04:07:40 +00:00
can1357 abc628b63c fix(read): expose artifact source line totals 2026-08-05 01:11:59 +02:00
Revofusion 84c4c58063 fix(read): preserve literal routed URL semicolons 2026-08-04 15:53:58 -06:00
Revofusion 3d6ecf9237 fix(read): split semicolon-delimited internal URLs 2026-08-04 15:41:45 -06:00
roboomp 9be8d797fc fix(cursor): corrected inline read range metadata
Detected path-embedded OMP line selectors when reporting Cursor read results and stopped treating ranged payload lengths as whole-file totals.

Exposed exact source line counts from EOF-reaching read results and covered both the wire response and read metadata contracts.

Fixes #7590
2026-08-04 04:13:35 +00:00
can1357 bc39ffa265 feat: introduced omptype validation package and migrated workspace dependencies
- Introduce `@oh-my-pi/omptype` as a new ArkType-compatible schema validation package featuring a lazy JIT runtime, JSON Schema emission, and compatibility adapters.
- Replace `arktype` across workspace packages and test utilities with `@oh-my-pi/omptype`.
- Add benchmark suites, tests, and documentation for the new validation engine and adapters.
- Update workspace build, test runner, and release configurations to include the new package.
2026-08-03 21:56:48 +02:00
can1357 34d7f2fb38 fix(cursor): reported full file size for ranged reads 2026-07-30 01:45:41 +02:00
can1357 21b3764b08 refactor(coding-agent): replaced xdevregistry with state interface and helpers
- Replaced the `XdevRegistry` class with the `XdevState` interface and pure helper functions across core and session tools.
- Updated session configurations, tool execution, and renderers to utilize canonical tool map initialization and sharing.
- Adapted unit tests and mocks to use `XdevState` and associated helper functions for permission and dispatch verification.
2026-07-28 03:34:36 +02:00
can1357 392aac4e49 fix(coding-agent): resolved third review pass on inspect_image vision mode
- read now treats an xd://-mounted inspect_image as available (top-level
  predicate OR mounted device gated by the effective mode), so default
  xdev sessions with a text-only model keep metadata-guidance reads
  instead of inlining images the provider boundary would scrub
- advisor tool session stops inheriting the primary's isToolActive and
  xdevRegistry: advisors cannot execute xd:// devices, so their reads
  inline images again
- setModelWithProviderSessionReset is now async and awaited at every
  callsite, so retry-fallback model switches cannot race the
  inspect_image tool-slate reconcile
- regression tests for both xd:// availability directions
2026-07-27 23:07:26 +02:00
alexis@epsilver.xyz b58a943a8e fix(coding-agent): address second codex pass on vision mode
- read now derives its image behavior from actual tool availability
  (session.isToolActive) with the mode computation as fallback, so
  restricted sessions whose explicit slate omits inspect_image (e.g.
  subagents) never get metadata-only reads pointing at an absent tool
- reconcile passes the post-change availability into the read
  description sync, keeping the advertised prompt correct across flips
  in both directions and when tool construction fails
- flat quoted-dotted inspect_image.mode is normalized into the nested
  target during migration instead of being silently dropped when a
  legacy flat enabled key is present
- regression tests for all three: availability-driven read behavior,
  flat+flat migration, description advertising
2026-07-27 16:24:02 -04:00
alexis@epsilver.xyz 3854c1c3b1 fix(coding-agent): address codex review on vision mode
- Reconcile inspect_image centrally from setModelWithProviderSessionReset
  so retry-fallback model changes (turn-recovery.ts) that bypass
  syncAfterModelChange cannot leave a stale tool set
- Apply persisted inspect_image.mode changes immediately from the
  settings selector via a new handleSettingChange branch
- Refresh the read tool's advertised description during reconciliation,
  before applyActiveToolsByName rebuilds the prompt, instead of only
  lazily on the next image read
- Fix the flat (quoted-dotted) enabled->mode migration to write the
  nested target form the resolver actually reads
- Add committed regression tests: tri-state x capability matrix,
  override precedence, and enabled->mode migration (nested, flat, and
  explicit-mode-wins)
2026-07-27 16:24:02 -04:00
alexis@epsilver.xyz c33b98e260 feat(coding-agent): capability-aware inspect_image with tri-state mode and /vision toggle
Replace the inspect_image.enabled boolean with inspect_image.mode
(auto|on|off, default auto). In auto the tool is registered only when
the active model lacks native image input, so vision-capable models
(e.g. kimi-code/k3) read images inline with their own capabilities
instead of delegating to a separate vision model. on/off force
registration regardless of model capability.

- New utils/inspect-image-mode.ts resolves the effective state from the
  /vision session override, the persisted setting, and model capability
- read tool re-evaluates the effective state per image read and
  re-renders its description, so it returns decoded image blocks again
  whenever inspect_image is hidden
- /vision [on|off|auto|status] slash command (modeled on /computer)
  overrides the mode for the current session only
- Tool set is reconciled on model switch with a status notice when
  inspect_image appears/disappears
- Legacy inspect_image.enabled true/false migrates to mode on/off
2026-07-27 16:24:02 -04:00
can1357 4210727227 feat(coding-agent): integrated v8 cpuprofile parsing into read tool
- Added V8 `.cpuprofile` parser and bottleneck summary generation utilities.
- Integrated profile summary rendering into the read tool execution.
- Refactored profile rendering machinery into shared tree utilities.
- Added comprehensive unit and integration tests for cpuprofile parsing and read tool dispatch.
2026-07-27 20:37:46 +02:00
can1357 7db4463da6 feat: introduced parser for macos sample reports and updated models
- Added a new parser and bottleneck summary renderer for macOS `/usr/bin/sample` reports with symbol demangling.
- Integrated automated summary parsing for sample reports into the ReadTool.
- Updated model configurations and pricing parameters across multiple providers.
- Added comprehensive unit and integration tests for sample profile parsing and ReadTool integration.
2026-07-27 20:08:30 +02:00
Dongmen Laohu 2c77c8535a fix(mcp): resolve native resource URIs 2026-07-27 18:59:12 +08:00
can1357 9c44ad185c fix(read): restored untilAborted import dropped by merge overlap of #6404 and #6417
- #6417 moved findUniqueSuffixMatch (the only prior untilAborted user) out of read.ts and removed the import; #6404 added new untilAborted callsites in regions git auto-merged without conflict.
2026-07-23 22:19:37 +02:00
can1357 a5e59a4e56 Merge PR #6417: fix(edit): align relative path resolution (@roboomp) 2026-07-23 22:15:22 +02:00
can1357 c991270145 Merge PR #6404: fix(coding-agent): make PDF image cache content-aware (@roboomp) 2026-07-23 22:15:22 +02:00
roboomp 662e4392da fix(edit): aligned relative path resolution
- Shared unique workspace suffix resolution between read and direct edit modes.

- Preserved create destinations and ambiguous-path failures while resolving existing update targets.

- Added direct replace, patch, and apply_patch regression coverage.

Fixes #6359
2026-07-23 19:14:09 +00:00
roboomp 7877df00e4 fix(coding-agent): made pdf image cache content-aware
- Snapshotted source bytes before deriving path-and-content cache generations.
- Coalesced cold extraction with independent caller cancellation and atomic publication.
- Covered replacement, mutation, concurrency, cleanup, isolation, and component limits.

Fixes #6368
2026-07-23 18:58:58 +00:00
can1357 9d5f158e23 fix(coding-agent): preserved default markdown rendering for internal-URL reads
Gated the read.renderMarkdown opt-in at read time (details tagging) instead
of inside the renderer. The renderer gate silently flipped every
protocol-supplied text/markdown read (skill://, pr://, issue://, history://,
rule://, omp://, agent://, vault://, local://, memory://, ssh://) from the
formatted markdown cell to the raw code cell when the setting was off, which
regressed default TUI behavior. Local file tagging now happens only when the
setting is enabled, so the default render path is byte-identical to the
pre-setting behavior while opt-in previews still work end-to-end.

Also inlined the tautological isMarkdownContentPath wrapper, pinned the
widened prose-summary bypass (.mdx stays verbatim when prose summaries are
off) with a test, and documented it under Changed in the changelog.
2026-07-23 17:30:33 +02:00
can1357 42a3da21de Merge PR #4001: feat(coding-agent): opt-in Markdown read previews (@oldschoola) 2026-07-23 17:30:33 +02:00
can1357 8f2cd23e39 Revert "Merge PR #5812: fix(read): honor exact line selector bounds (@roboomp)"
This reverts commit 58c71d5b50, reversing
changes made to 7c7227bc8e.
2026-07-18 22:04:43 +02:00
can1357 58c71d5b50 Merge PR #5812: fix(read): honor exact line selector bounds (@roboomp) 2026-07-18 20:12:46 +02:00
can1357 8c546bda77 Merge PR #5816: fix(tools): recognize zip-family archives and prune unconvertible extensions (@roboomp) 2026-07-17 21:22:07 +02:00
roboomp 22a8524058 fix(tools): recognized zip-family archives and pruned unconvertible extensions
- Treated ZIP-based .jar/.war/.ear/.apk as zip archives in archiveFormatFromPath and parseArchivePathCandidates so read/write member access works.
- Shared one archive-extension alternation between format detection and path splitting to stop them drifting.
- Derived the markit convertible-extension set from a single source of truth (utils/markit) matching the registered converters (pdf/docx/pptx/xlsx/epub), dropping legacy .doc/.ppt/.xls/.rtf that had no converter and only produced Unsupported format errors.
- Updated read/write tool prompts to document the zip-family extensions.

Fixes #5808
2026-07-17 08:04:10 +00:00
roboomp e5d5aec189 fix(read): enforced exact line selector bounds
- Removed implicit padding and syntactic boundary expansion from explicit ranges.
- Covered local, converted, multi-range, and artifact reads.

Fixes #5802
2026-07-17 07:45:39 +00:00
roboomp 33d66643d3 fix(read): refreshed URL responses on each invocation
Removed process-local URL response reuse so read and URL-backed search paths fetch current content.

Added regressions for repeated reads and searches.

Fixes #5803
2026-07-17 07:45:06 +00:00
roboomp c543ee75ec fix(read): preserved workspace suffix precedence
Tried existing unique workspace suffix matches before recovering a missing cwd path from the active approved plan. Added regression coverage for the precedence rule.
2026-07-16 14:55:17 +00:00
roboomp b01cc405fd fix(read): recovered approved plan cwd aliases
Recovered the active local plan when a model rewrites its local URL as a missing same-basename cwd-root path. Real working-tree files retain precedence.

Fixes #5704
2026-07-16 14:46:36 +00:00
can1357 5ff277349c refactor(coding-agent): consolidated tool surface onto xd:// devices and hub
- Added the `xd://` virtual device protocol (`internal-urls/xd-protocol.ts`, `tools/xdev.ts`): tools declaring `loadMode: "discoverable"` are unmounted from the request tools array and driven via `read xd://` (list/docs+schema) and `write xd://<tool>` (execute), gated by the `tools.xdev` setting (default on) and inlined into the system prompt.
- Merged the `irc`, `job`, and `launch` tools into a single `hub` tool (`tools/hub/`, `async/job-manager.ts`): messaging keeps `send`/`inbox`/`list`, job control maps to `wait`/`cancel`/`jobs`, process supervision keeps `start`/`logs`/`stop`/`restart`/`describe` with `ps`, and the unified `wait` races background jobs against peer messages; SDK `IrcTool`/`JobTool`/`LaunchTool` are replaced by `HubTool`.
- Removed the hidden `resolve` tool in favor of the `xd://resolve`/`xd://reject`/`xd://propose` resolution devices, auto-including `write` whenever a deferrable tool or plan mode is present.
- Removed the BM25 tool-discovery system: the `search_tool_bm25` tool, the `tool-discovery` module, the `tools.discoveryMode`/`mcp.discoveryMode`/`mcp.discoveryDefaultServers`/`tools.essentialOverride` settings, per-tool MCP selection, and the `mcp_tool_selection` message type.
- Unified tool presentation on `ToolLoadMode` (`essential`|`discoverable`), replacing the custom-tool `xdev?: boolean` opt-out; custom, extension, MCP, RPC host, image-generation, and TTS tools now default to `discoverable`, and added a `satisfies` predicate to `SoftToolRequirement`.
- Removed the standalone `ssh` command tool and `ssh/ssh-executor` (the `ssh://` read/write/search protocol stays), and made `--tools` address hidden built-ins.
- Updated collab-web to render `xd://` dispatches and `hub` op families, dropped the `search_tool_bm25`/`ssh`/`report-finding` renderers, refreshed tool docs and prompts, and migrated the affected tests and changelogs.
2026-07-15 15:16:29 +02:00
can1357 a9c038818d feat(tools): removed separate selector args from read and grep APIs
- Removed `selector`/`sel` arguments from read and grep tool schemas and related execution arg handling.
- Reworked read and grep path processing to parse line selectors from `path` suffixes instead of separate fields, including inline range propagation.
- Updated delegation and execution call paths (including JS/Python preludes and executor tests) to pass selectors embedded in `path`.
- Updated read/grep prompt docs and changelog for the breaking inline-selector API, and removed obsolete selector-specific tests and expectations.
2026-07-15 00:04:02 +02:00
can1357 83fbefac29 fix(coding-agent): disabled context padding for raw file reads
- Disable context expansion in raw mode to ensure verbatim content extraction.
- Enforce strict adherence to requested line ranges when raw selectors are used.
- Remove padding in range calculations to prevent indistinguishable context lines in raw output.
2026-07-11 05:47:54 +02:00
can1357 ba91877b6e fix(tui): restored read selector previews for explicit selector args
The v16.3.12 explicit `selector` field (ff3b0c795c) was consumed by the
read tool but never threaded into the TUI renderers: ReadRenderArgs in
both readToolRenderer (read.ts) and ReadToolGroupComponent only derived
selectors from path-embedded `:sel` suffixes, so split-arg calls like
{ path, selector: "2-3" } rendered bare paths without line ranges or
raw modifiers.

Joined the explicit selector (trimmed, leading colons stripped, non-string
guarded) back onto the display path in renderCall, renderResult error and
success branches, and the grouped read summary, keeping hyperlinks on the
base path only.

Adopted from PR #4904 (both commits squashed), minus its unrelated
workflow-notice.md prompt churn.

Fixes #4899
2026-07-09 18:27:21 +02:00
can1357 2553495d00 fix(tools): treated empty read/grep selector fields as omitted
Models emit optional string args as empty strings; since ff3b0c795
(#4622) read/grep rejected a present-but-empty selector as invalid
instead of behaving like an omitted one. Normalize empty and
whitespace-only selector params to undefined before validation.
Adopted from PR #4881 minus unrelated prompt churn.

Fixes #4879
2026-07-09 18:27:20 +02:00
roboomp a2e055fa9c fix(tools): closed two open literal-wins gaps flagged by codex
Two Codex bot findings from earlier PR reviews were still open.

1. local:// URL selector shadow (read.ts): the local:// branch resolved
   `local://foo:1-2` and rewrote readPath to `${localFile.path}:${sel}`,
   then let splitPathAndSelPreferringLiteral run on the synthesized
   string. A sibling literal `${localFile.path}:${sel}` file would win
   over the intended URL selector semantics. The branch now promotes the
   URL selector into the explicit-selector state and sets
   readPath = localFile.path, so downstream literal-preferring routing
   never re-splits the concatenation.

2. Delimited expansion before literal probe (path-utils.ts): grep called
   expandDelimitedPathEntries before parsePathSpecs, and
   splitDelimitedPathEntry only checked whether the peeled base of the
   entry resolved. A real POSIX file whose name contained a delimiter
   plus a selector-shaped tail (a;b:1-2) got split into ["a", "b:1-2"]
   and never reached the literal-preferring probe. splitDelimitedPathEntry
   now short-circuits on probeLiteralPathExists — "missing" is the only
   outcome that lets delimiter expansion run.

Added regressions: `read local://notes.md:1-2` still slices the base file
when a sibling `notes.md:1-2` literal exists, and grep searches a real
`a;b:1-2` file without semicolon-splitting.
2026-07-05 19:24:21 +00:00
roboomp 6c8e7625a2 fix(tools): tightened literal-path probe against stat ambiguity
resolveExistingReadPath treated any stat failure other than ENOENT/ENOTDIR as
"exists" and any other resolved path was considered a hit. That silently
reinterpreted a real literal path such as test:1-2 as test plus selector 1-2
whenever the raw path was a dangling symlink, sat under an unreadable parent,
or hit a transient I/O error.

The new probeLiteralPathExists returns "exists" / "missing" / "unknown" from
an lstat probe. splitPathAndSelPreferringLiteral now falls back to the strict
selector split only on "missing"; both "exists" and "unknown" keep the raw
path, so an unreachable literal is never reinterpreted. Grep and read use
the same probe: the explicit selector branch keeps the literal path when
existence is uncertain, and only a definitive ENOENT/ENOTDIR lets structured
archive/sqlite/pdf dispatch take over.

Added regressions covering probeLiteralPathExists exists/missing/dangling-
symlink cases and splitPathAndSelPreferringLiteral over a dangling symlink.
2026-07-05 18:17:59 +00:00
roboomp ff3b0c795c fix(tools): added explicit selector fields for read and grep
The literal-path stat fallback made selector-shaped filenames accessible, but it did not give callers a deterministic way to read or grep a range from a literal filename such as test:1-2. Encoding that as test:1-2:1-2 remained recursively ambiguous if a longer literal file later appeared.

Read now accepts an optional selector field that is parsed independently from path. When selector is present, path is treated as the exact path first, so { path: "test:1-2", selector: "1-2" } always means lines 1-2 from the literal file test:1-2. Inline :<sel> remains supported for compatibility.

Grep now accepts an optional line-range selector field with the same literal-path behavior. Explicit selectors bypass path suffix peeling, while archive/internal/URL routing still handles non-literal structured paths.

Updated read/grep tool prompts and added deterministic regressions proving that a longer literal file like test:1-2:5-6 or test:1-2:2-2 does not change the meaning of { path: "test:1-2", selector: ... }.
2026-07-05 18:09:29 +00:00
roboomp 48a6e46750 fix(tools): hoisted literal-preferring split ahead of archive/sqlite/pdf dispatch in read
The prior hunk placed the literal-preferring split after resolveArchiveReadPath,
resolveSqliteReadPath, and splitPdfImageMemberReadPath, so a real POSIX file
such as data.zip:1-2 or notes.db:1-2 still got hijacked: the archive/sqlite
resolvers matched the base extension, opened data.zip / notes.db, and errored
on the phantom :1-2 member before the literal file was ever considered.

Now the async splitter runs first. When the strict grammar would have peeled
a suffix but the literal path stats successfully, all three structured
dispatchers decline. Otherwise the ordering is unchanged, so archive/sqlite/
pdf-image reads keep working when the literal file does not exist.

Regression coverage adds `data.zip:1-2` and `notes.db:1-2` cases where the
base archive/sqlite file also exists on disk, exercising the exact ordering
bug the reviewer flagged.
2026-07-05 17:33:21 +00:00
roboomp c8df93ca31 fix(tools): preferred literal filesystem match over trailing :selector peel for read and grep
splitPathAndSel unconditionally peels a trailing :<sel> chunk whenever it
matches the read-tool selector grammar (raw, conflicts, N-M, N+K, ...). On
POSIX, filenames may legitimately contain colons, so a real file named
test:1-2 or log:raw was shredded to test/log before either read.ts or
grep.parsePathSpecs stated anything and both surfaced "Path not found".

Added splitPathAndSelPreferringLiteral(rawPath, cwd) alongside the strict
splitter: it only overrides the peel when fs.stat succeeds against the raw
path. Read (execute) and grep (parsePathSpecs) call the async variant for
non-URL paths; internal-URL splitting stays unchanged. Regression covers
splitter fallbacks, read/grep behavior on literal-colon files, and that
:1-2 selectors still work when the base file is the only real match.

Fixes #4618
2026-07-05 17:23:12 +00:00
roboomp 0b7f4865a7 fix(tui): handled invalid path render args
Validated path-like renderer inputs before calling path helpers so provider-supplied arrays or objects cannot crash TUI rendering before schema validation reports the bad tool call.

Added renderer regression coverage for read, write, and edit call/result components with array and object path arguments.

Fixes #4525
2026-07-04 15:47:52 +00:00
can1357 6e2bba871e feat(agent): implemented automated retry recovery and transcript compaction
- Introduced an automated retry recovery system to track, manage, and persist recovered error states within agent sessions.
- Enabled compact transcript rendering for recovered auto-retry errors by removing heuristic commit machinery.
- Improved raw read tracking and provenance in the ReadTool to support refined file snapshot recording and hashline editing.
- Excluded recovered assistant messages from default model context and updated event controllers to handle retry recovery life cycles.
2026-07-04 11:22:04 +02:00
roboomp 2b8c8cadfb fix(read): kept raw artifact chunks verbatim and broadened path-only resolution
Skipped the workflow notice on raw selectors so bounded raw reads stay byte-for-byte, and taught resolveToolSearchScope to request pathOnly resolution so ast_grep/ast_edit scope-only calls no longer trip the inline-content cap on large artifacts.

Fixes #4482
2026-07-03 23:36:57 +00:00