Commit Graph
425 Commits
Author SHA1 Message Date
can1357 7de519eabc Merge PR #5499: fix(plugins): preserve native CommonJS helper loading (@roboomp) 2026-07-14 23:11:10 +02:00
can1357 55ad1ff1bc Merge PR #5505: fix(plugins): refresh stale Bun git cache before reinstall (@roboomp) 2026-07-14 23:11:07 +02:00
can1357 1e1569d58e Merge PR #5465: fix(extensions): let tool_result rewrite thrown failure content (@roboomp) 2026-07-14 22:58:48 +02:00
roboomp 2439f77e70 fix(plugins): refreshed stale bun git cache before reinstall
Fetched current heads and tags into Bun's matching cached bare clone before running bun update.

Added an isolated HTTP git regression covering a moved branch with a stale cache.

Fixes #5401
2026-07-14 19:37:06 +00:00
roboomp 7881fce976 fix(plugins): preserved native commonjs helper loading
Kept synchronous require() targets on Bun’s native loader while retaining hooks for native-addon rewrites.

Added regression coverage for ESM extensions loading CommonJS helper files.

Fixes #5373
2026-07-14 19:22:00 +00:00
roboomp 5303c3852e fix(extensions): let tool_result rewrite thrown failure content
ExtensionToolWrapper caught a thrown tool exception, emitted tool_result
with the modifiable result, then rethrew the original executionError whenever
the effective error state stayed true. This discarded any replacement content
or details a handler returned, so an extension could only surface modified
content by returning isError: false, which wrongly converted the failure into
a success.

Return the (possibly modified) result carrying isError instead of rethrowing.
The agent loop already honors AgentToolResult.isError (coerceToolResult) and
surfaces it as a tool error on the wire, so replacement failure content now
reaches the model while the call remains an error. No-modification, error->success, and success->error paths keep their existing semantics.

Fixes #5302
2026-07-14 18:01:02 +00:00
can1357 edc0511433 Merge PR #4967: fix(plugin): handle pinned git source replacements (@roboomp) 2026-07-14 18:45:31 +02:00
can1357 4b5c32a092 Merge PR #4950: fix(mcp): resolve local image paths for tool calls (@roboomp) 2026-07-14 18:45:22 +02:00
can1357 f9f6ed9e8d feat(coding-agent): replaced legacy pi/ role alias prefix with
- Replaced legacy `pi/` role alias prefix with canonical `@` syntax across model resolution, documentation, and tests.
- Added support for bare `*` default alias and multiple alias prefix detection with custom role resolution in `resolveConfiguredRolePattern()`.
- Enhanced thinking suffix parsing to accept unambiguous abbreviations (minimum 2 characters) for effort and level selectors.
- Extended `resolveCliModel()` and `filterAvailableModelsByEnabledPatterns()` to accept settings parameter for role alias resolution from `--model` flag.
2026-07-13 23:26:33 +02:00
roboomp 459682cc63 fix(plugins): skipped invalid custom tool entries
Validated custom tool factory results before registering plugin-provided tools so one malformed feature entry is reported and skipped instead of crashing startup.

Added regression coverage for null entries and mixed valid/null factory arrays.

Fixes #5189
2026-07-11 14:31:07 +00:00
can1357 6f65a58d1b merge PR #4375: feat(ask): add rich interactive dialog
Closes #4375
2026-07-11 14:15:55 +02:00
can1357 d469064d1a fix: handle stale tests 2026-07-11 07:54:19 +02:00
can1357 33c161d9dd refactor(coding-agent): restructured plugin system and build logic
- Migrated legacy static bundled-module registry to a dynamic Bun-based in-memory plugin system.
- Removed over 4,000 lines of manually maintained registry files to reduce maintenance overhead.
- Implemented CJS absolute path rewriting and native-addon load hooks to improve FFI dependency resolution.
- Standardized binary build processes by centralizing compilation logic into shared utilities.
2026-07-11 07:33:22 +02:00
roboomp bc9f4c4be6 fix(coding-agent): armed ask timeout for legacy ui
Added an explicit timeout presentation capability so interactive queued dialogs defer the fallback while older UI implementations still get an immediate tool-owned timeout.

Refs #4995
2026-07-10 04:13:18 +00:00
roboomp fcf389ae72 fix(coding-agent): deferred ask timeout until display
Started the ask tool fallback timeout from the selector presentation callback so queued dialogs do not consume the user's response window.

Refs #4995
2026-07-10 02:49:33 +00:00
roboomp facfb3c35a fix(coding-agent): synced ask fallback timeout resets
Reset the ask tool fallback timeout whenever the interactive selector resets its UI countdown, preventing late keypresses from falling back to the original recommended option.

Refs #4995
2026-07-09 23:37:50 +00:00
roboomp 63adfeece5 fix(plugin): handled pinned git source replacements
- Removed the stale pinned dependency edge before invoking Bun for same-repository git source replacements so Bun does not construct a dependency loop.

- Added a regression test for the pinned-to-unpinned GitHub plugin replacement path.

Fixes #4960
2026-07-09 18:35:43 +00:00
roboomp 3ebcb36901 fix(mcp): threaded local roots through startup tools
- Copied localProtocolOptions through SDK-created custom tool contexts so startup MCP tools resolve '/data/workspaces/can1357__oh-my-pi__4946/.omp-session/2026-07-09T16-06-43-993Z_019f47a1-a619-7000-9062-5f5d863afa45/local' against the active session.
- Exposed localProtocolOptions on extension contexts and covered the runner propagation path.

Fixes #4946
2026-07-09 17:17:27 +00:00
roboomp b097019fef fix(mcp): resolved local image paths for tool calls
- Resolved session '/data/workspaces/can1357__oh-my-pi__4946/.omp-session/2026-07-09T16-06-43-993Z_019f47a1-a619-7000-9062-5f5d863afa45/local' file arguments before forwarding MCP tools/call requests to external servers.
- Threaded local protocol options into custom MCP tool context and added focused coverage for image_path attachments.

Fixes #4946
2026-07-09 16:38:24 +00:00
can1357 c944870566 fix(coding-agent): implemented pi's ui.addAutocompleteProvider API
Extensions calling ctx.ui.addAutocompleteProvider (e.g. @ff-labs/pi-fff)
crashed at load with 'TypeError: ... is not a function' because omp's
ExtensionAPI.ui omitted pi's autocomplete-provider API; the throw also
aborted the rest of a try/catch-guarded session_start init.

ExtensionUIContext now declares addAutocompleteProvider(factory).
Interactive mode stacks each factory on the built-in editor provider in
registration order, re-applies the stack on every slash-command refresh,
and skips throwing/malformed factories; RPC, ACP, and headless contexts
accept the factory as a no-op, matching upstream pi's RPC behavior.

Fixes #4919
2026-07-09 18:27:23 +02:00
e429166673 fix(coding-agent): queued extension sendUserMessage as steer while streaming
Extension sendUserMessage() without deliverAs fell through to prompt(),
which throws AgentBusyError during an active stream; the message was
dropped and surfaced as 'Extension sendUserMessage failed'. Route the
omitted-deliverAs path through prompt() with streamingBehavior 'steer'
so streaming queues a steer with normal prompt-flow side effects
(keyword notices, advisor auto-resume reset) and idle still starts a
turn.

ACP skill-command prompts now pass streamingBehavior 'steer'; the RPC
skill fast-path honors the prompt command's streamingBehavior field
(default steer) like the plain-prompt path already did. Documented the
extension-facing delivery semantics.

Synthesized from PR #4942 (prompt-flow steer routing, docs, tests) and
PR #4922 (RPC streamingBehavior threading, steer regression test);
dropped PR #4942's unrelated workflow-notice.md ellipsis churn.

Fixes #4923

Co-authored-by: roboomp <omp@can.ac>
Co-authored-by: metaphorics <metaphorics@users.noreply.github.com>
2026-07-09 18:27:22 +02:00
can1357 74385fcbfb merge PR #4435: fix(agent): emit session_switch for handoff 2026-07-08 15:19:38 +02:00
can1357 d03ecad0bc merge PR #4690: fix(coding-agent): handle JSON imports in legacy plugin validator 2026-07-08 15:19:37 +02:00
roboomp f44fcdfb7d fix(coding-agent): hid marketplace clone temp paths
Displayed cloned marketplace catalog validation errors with repository-relative catalog paths and the original source identifier.

Fixes #4702
2026-07-06 11:05:50 +00:00
roboomp 47c172c70a fix(coding-agent): handled json imports in plugin validator
- Left JSON files imported with import attributes on Bun's native loader instead of registering them with the legacy source rewrite hook.
- Added a regression test for loadLegacyPiModule loading a JSON import-attribute target.

Fixes #4687
2026-07-06 08:17:32 +00:00
roboomp dd3375981f fix(coding-agent): preserved enabled duplicate skills
Applied source toggles before skill-name dedup so disabled higher-priority providers no longer hide enabled lower-priority authored skills.

Added regression coverage for disabled claude versus enabled agents duplicate names and managed dead-last behavior.

Fixes #4648
2026-07-06 00:51:24 +00:00
roboomp b0a84847b7 fix(agent): emitted handoff session switch hook
Fixes #4434
2026-07-05 19:19:02 +00:00
can1357 734aed4c03 Merge PR #4382: fix(compaction): keep plan-mode guidance off the session_before_compact hook (@roboomp) 2026-07-05 13:25:28 +02:00
can1357 8ec34a7662 Merge PR #4349: fix(session): handle malformed custom messages (@roboomp) 2026-07-05 13:25:24 +02:00
can1357 3e1808e2b5 fix(agent): handle installed legacy dependency reloads 2026-07-05 12:44:17 +02:00
can1357 b3ee269e4e Merge PR #4568: fix(agent): reload edited legacy Pi modules (@roboomp) 2026-07-05 12:44:17 +02:00
can1357 4225f4bc44 fix legacy resource loader forwarding 2026-07-05 12:44:16 +02:00
can1357 dec882a766 Merge PR #4569: fix(agent): restore legacy DefaultResourceLoader shim (@roboomp) 2026-07-05 12:44:16 +02:00
can1357 2eb5995bc5 fix(coding-agent): complete legacy pi-ai catalog re-exports 2026-07-05 12:44:16 +02:00
roboomp 4f8b0394ca fix(agent): restored legacy DefaultResourceLoader shim
Added a DefaultResourceLoader compatibility adapter for legacy pi package-root imports and translated resourceLoader into OMP session discovery options so noExtensions/noSkills are preserved for subagents.

Added a regression test covering the loader snapshot and createAgentSession translation path.

Fixes #4567
2026-07-05 02:57:52 +00:00
roboomp 45deb2098d fix(agent): reloaded legacy bare dependency children
Included ESM extension-local bare dependency entries in the legacy extension graph so their relative children receive the same mtime cache-bust rewrite as extension source modules.

Skipped CommonJS dependency entries to preserve native Bun CJS default import behavior.

Added a regression test for a local node_modules ESM dependency whose unchanged entry re-exports an edited helper.

Fixes #4565
2026-07-05 02:53:28 +00:00
roboomp 5203fce696 fix(coding-agent): re-exported relocated catalog symbols from legacy pi-ai shim
`calculateCost`, `modelsAreEqual`, and `getBundledProviders` moved from the
`@oh-my-pi/pi-ai` barrel to `@oh-my-pi/pi-catalog/models` in the catalog
split (1b9d9d0851). The legacy-extension pi-ai root shim already bridged
`getBundledModel`/`getBundledModels` back under their old `getModel`/
`getModels` names but never re-exported the other relocated symbols, so any
legacy extension importing `calculateCost` from `@oh-my-pi/pi-ai` failed
plugin validation at install time with `Export named 'calculateCost' not
found in module '.../legacy-pi-ai-shim.ts'`.

Bridge all three symbols through the shim so pre-split legacy extensions
load again. Add regression tests that load fixtures importing
`calculateCost`, `modelsAreEqual`, and `getBundledProviders` from
`@oh-my-pi/pi-ai` and assert identity against the catalog implementations.

Fixes #4584
2026-07-05 02:03:41 +00:00
roboomp 65cd063d90 fix(agent): refreshed legacy pi graph hooks
Collected the current extension graph on every load and registered supplemental Bun hooks for modules added after the first import.

Preserved exact-path filters by tracking covered realpaths per entry instead of widening hooks to unrelated files.

Added a regression test for an entry-only extension that later adds helper and leaf modules, then reloads an edited leaf.

Fixes #4565
2026-07-04 20:56:38 +00:00
roboomp 2049c72b94 fix(agent): propagated mtime through legacy extension graph
Threaded the current load's mtime tag through rewriteExtensionPackageImports, rewriteExtensionBareImports, and a new relative-graph pass so ./helper.ts, #alias/*, and extension-local bare deps all rekey per reload.

Added a toGraphImportSpecifier helper that emits bare POSIX paths with ?mtime on POSIX and keeps file:// URLs on Windows/bundled targets, matching the entry loader.

Added a regression test covering same-process relative-helper reload freshness through the public loader.

Fixes #4565
2026-07-04 20:44:56 +00:00
roboomp d510851593 fix(agent): reloaded edited legacy pi modules
Loaded legacy Pi extension entries through raw POSIX filesystem specifiers so Bun keys the cache-busting mtime query.

Allowed the extension graph onLoad hook to match and normalize the mtime query before rewriting source.

Added a regression test covering same-process reload freshness and clean fileURLToPath-derived paths.

Fixes #4565
2026-07-04 20:26:27 +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
metaphorics 48b2a742c8 fix(ask): distinct chat redirect result, row-specific note prefill
Op: correct
Restores: review:4375

- Widen ExtensionAskDialogResult to a union with { kind: "chat" } variant
  so AskTool can distinguish chat handoff from cancel (undefined).
- AskDialogComponent.#finishChat passes { kind: "chat" } via onChat.
- Controller settles { kind: "chat" } locally and propagates a "chat"
  sentinel through the guest/collab path instead of returning undefined.
- AskTool returns a chat-redirect AgentToolResult (chatRedirect details)
  instead of aborting with ToolAbortError.
- #promptForNote prefills with the existing note only when editing the
  same row (noteRowKey === rowItem.key), preventing cross-row note leaks.
- Add ask-dialog and ask tool tests for chat redirect and row-specific
  note prefill.
2026-07-03 11:52:51 +09:00
roboomp 72df91c3c8 fix(compaction): route plan-mode guidance via internalGuidance channel
Plan-approval's 'Approve and compact context' used to pass the rendered
plan-mode-compact-instructions prompt as the first positional argument
to handleCompactCommand -> session.compact(), which landed on the
session_before_compact extension hook as customInstructions. Extensions
treating that field as user focus (e.g. to bias a query-focused summary)
would then see plan-mode boilerplate instead of operator intent and
produce query-biased compactions.

Add CompactOptions.internalGuidance: a private summarizer-only channel.
session.compact() reads it into the fallback-model summarizer while the
session_before_compact hook payload still only carries the public
customInstructions arg (undefined for the plan-compact path). The
snapcompact-disable predicate and the /compact rejectsFocus guard cover
both fields so a directed summary is never silently downgraded.

Extend the interactive-mode handleCompactCommand facade + command
controller with a fourth internalGuidance parameter, and switch the
plan-approval callsite in interactive-mode.ts to route the plan prompt
through it.

Fixes #4359
2026-07-03 00:36:38 +00:00
metaphorics 38a5c8a893 feat(ask): add rich interactive dialog
Adds the rich TUI ask dialog, additive schema fields, ask.enabled tool gating, note/preview/header support, chat redirect, and timeout behavior that defers while nested prompts are active instead of discarding user input.

Op: extend
2026-07-03 09:20:29 +09:00
can1357 eb47ce1063 Merge remote-tracking branch 'origin/farm/a23a6b23/drain-plugin-install-pipes' 2026-07-02 23:43:11 +02:00
can1357 1c0e35f73e Merge remote-tracking branch 'origin/farm/813601d2/install-npm-pi-packages' 2026-07-02 23:43:08 +02:00
can1357 2c8daf0578 feat: implemented dynamic coercion for legacy tool argument aliases
- Added `normalizeSingleStringField` to dynamically map misplaced string inputs to required schema fields for single-argument tools.
- Integrated argument normalization into `validateToolArguments` to handle model-specific variations in JSON payloads during validation passes.
- Updated `coding-agent` streaming and rendering components to recognize `_input` as a legacy alias for `input` across various UI paths and logic flows.
- Refactored `hashlineEditParamsSchema` to strictly enforce the `input` field while maintaining support for legacy aliases via runtime coercion rather than schema definition.
- Corrected unit tests to reflect that `_input` is rejected by the strict schema but handled gracefully by the validation layer.
2026-07-02 23:32:35 +02:00
roboomp 8da17ba3b5 fix(session): handled malformed custom messages
Normalized extension custom-message payloads before session state or persistence, including bare string sendMessage shorthands. Skipped legacy bare custom_message entries during context rebuilds and dropped malformed custom/hook messages before LLM conversion. Added regression coverage for the poisoned-session resume crash.\n\nFixes #4345
2026-07-02 20:34:15 +00:00
roboomp 805b994211 fix(cli): accepted npm protocol plugin installs
Allowed npm:<package> install specs to validate against the resolved package name while still forwarding the original spec to Bun.

Added regression coverage for installing npm:pi-figma-remote-auth through PluginManager.

Fixes #4310
2026-07-02 12:08:01 +00:00
roboomp d2be57a8f7 fix(plugins): drain subprocess pipes concurrently with proc.exited
PluginManager.install (bun install + bun update), PluginManager.uninstall,
PluginManager.#fixMissingPlugin, the legacy installer.ts install/uninstall
helpers, and generate-legacy-pi-bundled-registry.ts's formatInPlace all
called Bun.spawn with stdout/stderr piped and awaited proc.exited before
touching either stream. Once a child's output exceeded the ~64 KiB OS
pipe buffer, the child would block on write(2) while the parent blocked
on exit — a classic pipe-buffer deadlock. Even where Bun's current runtime
happens to buffer eagerly, the pattern silently leaked unbounded bytes.

Each site now starts new Response(proc.stdout).text() and stderr readers
immediately after Bun.spawn and awaits them alongside proc.exited via
Promise.all. Existing error semantics are preserved: install throws with
stderr, uninstall keeps its generic error, and formatInPlace still includes
Biome's stderr in the failure message.

Adds a regression test (plugin-install-git.test.ts) that models the
OS-pipe deadlock by holding proc.exited until both mock streams are
drained — install must read them before awaiting exit, else the test hits
its 2s Promise.race timeout.

Fixes #4230
2026-07-02 08:33:32 +00:00