Commit Graph
3770 Commits
Author SHA1 Message Date
can1357 2ae3a4b111 refactor(hashline): removed inline modify edit kind
- Dropped the `modify` edit type and its `< ANCHORTEXT` / `+ ANCHORTEXT` syntax.
- Removed associated parser rules, regex patterns, apply logic, and tests.
- Deleted the "Append WITHIN a line" example from the prompt docs.
2026-05-10 07:56:29 +02:00
can1357 3ae1d1a8dc fix(coding-agent-extensibility): patched extension handler timeout logic
- Added a 30s timeout for extension handlers in runner.ts so stalled callbacks now emit warnings and stop.
- Consolidated duplicated extension handler error handling by routing calls through #runHandlerWithTimeout.
2026-05-10 07:46:01 +02:00
can1357 7dec6953ac fix(coding-agent/task): skipped refreshing modelRegistry when inherited from parent
- Introduced a flag to detect when an explicit modelRegistry was supplied to runSubprocess.
- Skipped modelRegistry.refresh() when reusing the parent registry and retained refresh when creating a new one.
- Added a debug log to indicate when a parent modelRegistry is reused and refresh is bypassed.
2026-05-10 07:19:26 +02:00
can1357 4a6c56772f fix(coding-agent/mcp): fixed SSE parsing by draining the stream in a single pass
- Refactored SSE response parsing to read the stream with a single in-progress drain loop.
- Resolved the matching request promise when the expected JSON-RPC result or error arrives and continued dispatching remaining SSE messages on the same stream.
- Adjusted error handling to reject on abort/timeout or missing response and clear the timeout when stream parsing completes.
2026-05-10 06:47:19 +02:00
can1357 5d830a5453 fix(task): fixed task renderer handling of missing tasks arrays during streaming
- Updated task call rendering to use `args.tasks?.length ?? 0` when displaying agent counts.
- Prevented runtime warnings in streaming task calls when the `tasks` array was still undefined.
2026-05-10 06:45:02 +02:00
can1357 b1a898f18c docs(coding-agent/prompts): documented anchor behavior for stacked patch edit operations
- Updated the hashline prompt to clarify that anchors must use the file state from the most recent read.
- Added guidance warning not to renumber line references when stacking multiple patch operations.
2026-05-10 06:34:15 +02:00
can1357 e973081a13 chore: bump version to 14.9.1 2026-05-10 05:31:37 +02:00
can1357 b12bb9653e chore: bump version to 14.9.0 2026-05-10 05:18:32 +02:00
can1357 e17e64004d fix(coding-agent/task): fall back to parent active model when subagent model has no auth
Reporter screenshot showed a parent session on DeepSeek V4 Pro dispatching
a task subagent that resolved to `qwen3.6-plus-free` — an opencode-zen
model the user had no working credentials for. The dispatch hit a
provider that could not serve the model and surfaced a confusing API
rejection instead of using the parent's already-authenticated model.

Adds `resolveModelOverrideWithAuthFallback`, an auth-aware wrapper
around `resolveModelOverride` that checks the resolved subagent model's
credentials via `modelRegistry.getApiKey` + `isAuthenticated` and
falls back to the parent session's active model pattern when the
primary has no working auth. The parent's active model is plumbed
through `ExecutorOptions.parentActiveModelPattern` from `TaskTool`
into `runSubprocess`. If neither has working auth (or they resolve to
the same model), the primary resolution is preserved so the existing
error path still surfaces a meaningful failure downstream.

Fixes #985
2026-05-10 05:17:39 +02:00
can1357 f74120b2b7 fix(coding-agent): strict provider routing + compaction auth fallback
- Model resolver: provider-prefixed `<provider>/<id>` selectors are now
  strict. If the provider is known and the exact pair does not resolve,
  return undefined instead of silently crossing provider boundaries
  (e.g. routing `anthropic/claude-3-7-sonnet` to amazon-bedrock when
  the user only has Anthropic auth). Unqualified resolution is unchanged.

- Compaction: when the current model's provider has no credentials,
  manual compaction now retries across compaction model candidates and
  falls back to an authenticated role; if no usable fallback exists, it
  throws a clear provider-specific pre-stream error instead of bubbling
  a 503 `auth_unavailable` from the provider stream.

Fixes #986
Fixes #980
2026-05-10 05:09:29 +02:00
can1357 b989f57e66 chore: recording fix in changelog
Fixes #983
2026-05-10 04:55:43 +02:00
can1357 ce0b545147 chore: reformat 2026-05-10 04:54:07 +02:00
can1357 f10349a2f9 tweak(welcome): slim logo, diagonal gradient
- Trim logo from 14w to 12w (2-wide legs).
- Diagonal BL→TR gradient instead of per-line LTR.
- Truecolor: 3-stop magenta→violet→cyan path that skips the deep-blue valley.
- 256-color: same 6-stop ramp as fallback.
- Compute the colored logo once at module load instead of per render.
2026-05-10 04:53:53 +02:00
can1357 9f386dd6e5 feat(ai,coding-agent): raw SSE diagnostics + steady-state idle watchdog
Adds an opt-in onSseEvent callback across HTTP-streaming providers (Anthropic, OpenAI Responses/Completions, Azure OpenAI Responses, OpenAI Codex SSE, Google Gemini CLI, GitLab Duo, Kimi, Synthetic) so callers can inspect raw SSE frames without altering parsed output. Provider fetch wrapping only tees response bodies when an observer is wired; standalone packages/ai consumers without onSseEvent are not penalized.

Adds streamIdleTimeoutMs (env: PI_STREAM_IDLE_TIMEOUT_MS, with PI_OPENAI_STREAM_IDLE_TIMEOUT_MS as a backward-compatible alias). Anthropic now enforces a steady-state idle watchdog (default 120s) in addition to the first-event watchdog. OpenAI Responses, Azure Responses, and Codex (SSE + WebSocket) gain a semantic-progress predicate so response.in_progress-style keepalives no longer keep stalled tool calls alive forever.

Adds a coding-agent debug-panel raw SSE viewer backed by a per-session bounded buffer (1000 records / 512KB) that AgentSession populates unconditionally so users can post-hoc inspect a stuck stream from the TUI.
2026-05-10 04:53:41 +02:00
can1357 0cf851658e fix(coding-agent): required explicit hashline ranges for single-line delete and replace
- Updated the hashline grammar to require a full `LID .. LID` range for block operations.
- Enhanced `parseRange` to reject single-anchor syntax and malformed ranges, and to require duplicated anchors for one-line edits.
- Reworked hashline prompt examples/tests accordingly and added coverage for single-anchor delete/replace forms.
2026-05-10 04:53:41 +02:00
Can BölükandGitHub 3308fcbf03 Merge pull request #987 from apoc/feat/rpc-login-commands
feat(rpc): add get_login_providers and login commands
2026-05-10 04:52:52 +02:00
Can BölükandGitHub b0e70330f8 Merge pull request #988 from apoc/fix/reviewer-cross-boundary-tracing
fix(reviewer): add cross-boundary dispatch tracing obligation
2026-05-10 04:52:39 +02:00
Can BölükandGitHub 9394a169fc Merge pull request #990 from jiwangyihao/fix/windows-legacy-pi-loader
fix(plugins): load legacy Pi extensions with Windows-safe paths
2026-05-10 04:50:24 +02:00
Can BölükandGitHub 7e106c2383 Merge pull request #971 from apoc/fix/anthropic-session-id-cloaking
fix(ai): stable metadata user_id per session to prevent session count inflation
2026-05-10 04:46:18 +02:00
Can BölükandGitHub c0990c9180 Merge pull request #979 from bjin/fix/plan-review-resubmit-rendering
fix(coding-agent): append plan review previews on resubmit
2026-05-10 04:45:51 +02:00
can1357 1802de9c0a fix(coding-agent): resolved eval context import rewrite via Babel AST
- Replaced regex-based import rewriting in `rewriteStaticImports` with Babel AST parsing.
- Handled default, namespace, named, and side-effect imports, preserving `import ... with` options.
- Returned original source on no top-level imports, parse failures, or unchanged non-import regions.
- Added `@babel/parser` dependency and tests/changelog coverage for top-level static-import rewrite behavior.
2026-05-09 23:10:15 +02:00
can1357 85003caaaf feat(coding-agent): added hashline entrypoint and redirected callers
- Added `./hashline` package exports and redirected callers to the new hashline entrypoint.
- Moved hashline logic out of `edit/` to `src/hashline` and removed `edit/modes/hashline`/`edit/line-hash` paths.
- Added hashline parsers, anchors, types, and diff helpers with stricter input and mismatch validation.
- Implemented preflight and cache-recovery execution flows to reapply edits and handle stale anchor mismatches.
- Documented the hashline API relocation as breaking changes in `CHANGELOG.md`.
2026-05-09 23:10:02 +02:00
can1357 0a24c5a892 docs(coding-agent/prompts): expanded hashline guidance for self-contained multiline replacements
- Clarified the hashline guidance to select a self-contained syntactic unit before narrowing the edit operation.
- Added a multiline destructuring/call example showing the full construct replacement pattern and safer alternatives.
- Updated anti-pattern instructions to reject partial-boundary replacement payloads and continuation-fragment edits.
2026-05-09 23:09:45 +02:00
can1357 cbdd8a65e5 fix(coding-agent/edit): removed anchor auto-rebase during hashline mismatch validation
- Removed hashline anchor auto-rebase logic, including the ±5-line rebase window and `tryRebaseAnchor` fallback.
- Validation now reports hash mismatches directly as hard `HashMismatch` entries and surfaces them via `HashlineMismatchError` without mutating anchor lines.
- Updated the changelog to document anchor auto-rebase removal and the immediate re-read recovery behavior.
2026-05-09 23:09:45 +02:00
can1357 269a10bfb6 fix(lsp): updated diagnostics responses to display OK success state
- Updated LSP diagnostics output to return "OK" when no issues were found.
- Added a diagnostics-specific render case to show successful status and a success label for "OK" responses.
- Updated the regression test to expect the new "OK" diagnostics output.
2026-05-09 22:06:53 +02:00
can1357 af8504d081 feat(coding-agent/modes): converted non-PNG tool images to PNG for Kitty terminal rendering
- Added asynchronous Kitty conversion for assistant tool images using `convertToPng`, keyed per tool-call entry with cached and in-flight tracking.
- Updated assistant image rendering to prefer converted PNGs for Kitty terminals while preserving existing behavior for other protocols.
- Added a unit test that verifies WebP tool images are converted and rendered as Kitty image output instead of the raw image/webp fallback.
2026-05-09 22:01:56 +02:00
jiwangyihao a157b878f4 fix(plugins): 避免预解析动态相对导入 2026-05-10 03:35:46 +08:00
jiwangyihao 40e8b37202 fix(plugins): 保留 legacy 扩展的 Node 内置导入 2026-05-10 03:24:02 +08:00
jiwangyihao 1226d30d21 test(plugins): 将 legacy Pi 回归覆盖插件发现链路 2026-05-10 03:21:02 +08:00
jiwangyihao 7d0984f2b4 docs(changelog): 记录 legacy Pi Windows 修复 2026-05-10 03:16:56 +08:00
jiwangyihao a7fcc0f63b fix(plugins): 修复 Windows legacy Pi 扩展加载 2026-05-10 03:13:51 +08:00
Miroslav Drbal c68f90cc7d fix(rpc): give login() 10-minute client timeout vs 5-minute server window
The server-side OAuthCallbackFlow callback window is 300_000 ms, but the
client starts its #send timer before the RPC command is dispatched. By
the time the callback server actually starts, some time has already been
consumed on the client side. If the user takes the full callback window
plus token exchange, the client 300_000 ms timeout fires first, rejects
login(), cleans up the onOpenUrl listener, and the server response
arrives into a discarded pending entry.

Use 600_000 ms (10 min) on the client — double the server window. The
server will always return an error or success response within its own
window, so this timeout is purely a safety net against server crash or
connection loss and never fires during a normal login.
2026-05-09 20:15:24 +02:00
Miroslav Drbal ad1058772c fix(rpc): detect headless-incompatible providers at runtime
Replace the static RPC_LOGIN_PROVIDERS allowlist with runtime detection
based on callback ordering.

Providers that support headless login (OAuthCallbackFlow) always call
onAuth first (emit the browser URL), then onManualCodeInput only as a
fallback for manual redirect-URL entry. Providers that require interactive
input (API-key paste, device-flow prompts, GitHub Enterprise URL) call
onPrompt before any onAuth fires.

onPrompt now branches on authEmitted:
- false (onPrompt before onAuth): reject immediately with a clear 'not
  supported in RPC mode' error. The rejection propagates through
  authStorage.login and is caught by the try/catch, returning an error
  response. No deadlock.
- true (onPrompt after onAuth, inside OAuthCallbackFlow's fallback race):
  return a never-settling promise so the race defers to the callback
  server. A rejection here would be swallowed as null by .catch() and
  spin the while(true) loop.

New providers self-classify by their actual call order with no list to
maintain.
2026-05-09 19:07:26 +02:00
Miroslav Drbal 1152191297 fix(rpc): prevent onPrompt throw from spinning login retry loop
OAuthCallbackFlow.#waitForCallback races the browser callback against
onManualCodeInput and catches any rejection as null. When onPrompt
threw, the catch turned it into null, the while(true) loop saw a
falsy result, and immediately re-invoked onManualCodeInput — a tight
spin that starved the callback server and made browser-callback logins
hang until timeout even when the user completed auth successfully.

Replace the throw with a never-resolving Promise<string>. The race
then blocks waiting for the callback server to deliver the code,
with no busy-looping. When the server-side login eventually
times out or the browser callback arrives, the pending promise is
abandoned and GC'd.

Addresses: https://github.com/can1357/oh-my-pi/pull/987#discussion_r3213450206
2026-05-09 18:50:21 +02:00
Miroslav Drbal 3222952587 fix(rpc): extend login() timeout to 5 minutes
#send uses a hard-coded 30s timeout. OAuth flows require the user
to open a browser, authenticate with the provider, and wait for the
redirect — easily 1-3 minutes. Callers would see a spurious timeout
rejection while the server-side callback server was still live and
the user was still mid-flow.

Add optional timeoutMs parameter to #send (default 30_000, all
existing callers unaffected) and pass 300_000 from login().

Addresses: https://github.com/can1357/oh-my-pi/pull/987#discussion_r3213435093
2026-05-09 18:46:54 +02:00
Miroslav Drbal 8d1189f176 fix(reviewer): add cross-boundary dispatch tracing obligation
When a patch introduces a new type that crosses a function/module
boundary (event, message, RPC frame, enum variant, etc.), the reviewer
must locate the dispatch point on the consuming side and confirm the
new type is handled. This class of bug is invisible from the diff alone
because the silent drop lives in untouched routing code.

Motivated by a missed P2 in PR #987: a new open_url extension_ui_request
was emitted by login() but RpcClient#handleLine had no case for it and
silently dropped every frame, leaving callers with no auth URL and the
command hanging until timeout.
2026-05-09 18:36:50 +02:00
Miroslav Drbal ae3aa36e3c fix(rpc): forward open_url events to RpcClient.login callers
RpcClient#handleLine was dropping extension_ui_request frames
(no isAgentEvent match → early return). Callers of login() had
no way to learn the auth URL, so the callback-server flow never
got a browser visit and the command hung until timeout.

- Add isRpcExtensionUiRequest type guard
- Add #extensionUiListeners set to RpcClient
- Dispatch extension_ui_request frames through that set in #handleLine
- login() accepts optional { onOpenUrl } callback; registers/
  deregisters a listener scoped to the command's lifetime

Addresses: https://github.com/can1357/oh-my-pi/pull/987#discussion_r3213428270
2026-05-09 18:32:18 +02:00
Miroslav Drbal 254739ce0e feat(rpc): add get_login_providers and login commands
- RpcCommand: add get_login_providers and login { providerId }
- RpcResponse: add typed responses for both commands
- RpcExtensionUIRequest: add open_url { url, instructions } event
  (fire-and-forget; host opens the URL in system browser)
- rpc-mode: handle get_login_providers (returns provider list with
  per-provider authenticated status) and login (drives authStorage.login
  using RpcExtensionUIContext for onPrompt dialogs and notify for
  onProgress; emits open_url for the auth page URL)
- rpc-client: add getLoginProviders() and login(providerId) methods
2026-05-09 18:28:00 +02:00
Miroslav Drbal 45380aecbe feat(coding-agent): derive device_id from account_uuid for Anthropic metadata
Real CC's getAPIMetadata includes device_id alongside session_id and
account_uuid. Rather than reading OS machine UUIDs (hardware fingerprinting)
or storing a random persistent ID, derive it as:

  sha256("omp-device-id-v1:" + account_uuid).hex()

Properties:
- Indistinguishable from a randomly generated device ID on the wire
- Deterministic per account — survives reinstalls, no persistent storage
- Auditable: derived solely from the OAuth UUID already shared with Anthropic
- Zero hardware access, zero extra I/O
- Omitted for API-key callers (no account_uuid → no hash)
2026-05-09 10:17:56 +02:00
Miroslav Drbal fc70a45c46 fix(ai): stable metadata.user_id per session for Anthropic OAuth
Anthropic counts sessions by metadata.user_id. Without this fix, OMP
generated fresh random entropy on every API request, inflating the
session count and preventing backend attribution to the authenticated
account.

Changes:

packages/ai:
- resolveAnthropicMetadataUserId() now accepts JSON-format user_id
  matching real Claude Code's getAPIMetadata shape
  ({ session_id, account_uuid, ... }). Previously only the legacy
  cloaking format was accepted on OAuth, causing stable caller-supplied
  values to be silently discarded.
- AnthropicOAuthFlow.exchangeToken() and refreshAnthropicToken() now
  populate OAuthCredentials.{accountId, email} from the token response
  account block, removing the need for a separate /api/oauth/profile
  round-trip.
- AuthStorage.getOAuthAccountId(provider, sessionId) returns the OAuth
  accountId for the session-sticky credential, used to build
  account_uuid in metadata.user_id. Guards against misattribution for
  API-key, runtime-override, env-key, and fallback-resolver paths that
  do not record a session credential.

packages/agent:
- Agent.metadataForProvider(provider) resolves request metadata for
  the given provider via the installed resolver, or returns the static
  metadata value. The plain metadata getter now returns only the static
  value; provider-aware resolution is explicit.
- Agent.setMetadataResolver(fn) installs a (provider: string) resolver
  evaluated per LLM request in agent-loop, after getApiKey records the
  session-sticky credential, so account_uuid reflects the credential
  actually used.
- AgentLoopConfig.metadataResolver is called with config.model.provider
  after getApiKey, overriding the static metadata field.

packages/coding-agent:
- AgentSession.#syncAgentSessionId installs a metadata resolver that
  builds { user_id: JSON.stringify({ session_id, account_uuid? }) },
  matching the Anthropic session attribution format. account_uuid is
  only included for provider="anthropic" to avoid leaking the OAuth
  identity to third-party Anthropic-format-compatible providers.
- sessionId getter prefers providerSessionId when supplied via
  AgentSessionConfig so all API paths (getApiKey, direct calls,
  metadata resolver) share the same provider-facing session ID.
- prepareSimpleStreamOptions stamps session metadata on direct calls
  (runEphemeralTurn, compaction, branch summary, title generation) so
  they share the same session bucket as Agent.prompt requests.
- generateBranchSummary and generateSessionTitle accept a
  (provider: string) metadata resolver evaluated after their own
  getApiKey call for correct credential attribution.
2026-05-09 09:48:10 +02:00
can1357 5ad37428a0 chore: bump version to 14.8.1 2026-05-09 07:04:11 +02:00
can1357 e4b801590d refactor(coding-agent): tightened custom editor factory typing in interactive mode
- Updated ExtensionUIContext, InteractiveModeContext, and InteractiveMode to require editor factories to return CustomEditor instances.
- Removed the runtime compatibility guard and warning for non-CustomEditor implementations in setEditorComponent.
- Removed the test that verified rejection of non-CustomEditor factories in interactive-mode editor-component tests.
2026-05-09 07:03:37 +02:00
Can BölükandGitHub f9cc082ef2 Merge pull request #909 from quickserve-ai/fix/pi-vim-editor-component-hook
Fix ExtensionUIContext.setEditorComponent in interactive mode
2026-05-09 06:58:14 +02:00
Can BölükandGitHub abf13a8450 Merge pull request #964 from rburketaylor/fix-sync-slash-autocomplete
Fix sync slash autocomplete submission
2026-05-09 06:50:20 +02:00
Bin Jin 6218032820 fix(coding-agent): append plan review previews on resubmit
- Render each exit_plan_mode submission as a fresh plan review entry so refined plans are emitted into terminal scrollback.
- Keep external-editor edits replacing the current preview instead of adding duplicate review entries.
- Updated the plan review regression test to preserve the first preview and append the second one after intervening chat content.
2026-05-09 12:47:07 +08:00
can1357 668ab38fd4 fix(coding-agent): resolve bare imports from extension node_modules in legacy-pi shim
Files loaded via the omp-legacy-pi-file: namespace bypass Bun's normal
node_modules lookup because the importer lives in a custom namespace,
so an extension that imports its own bundled dependencies (e.g.
`import parseDuration from "local-duration-parser"`) failed with
`Cannot find package`. Pre-resolve bare specifiers in the onLoad step
against the importer's directory so extensions can ship their own
node_modules. Relative, absolute, node:, and URL specifiers are left
untouched, preserving the existing legacy @mariozechner/pi-* remap
path.
2026-05-09 06:45:44 +02:00
can1357 c06dc48b3f chore: bump version to 14.8.0 2026-05-09 05:52:26 +02:00
can1357 c267f04c00 feat(coding-agent): added cache-based hashline stale-anchor recovery fallback
- Implemented hashline stale-anchor recovery using cached reads and a 3-way merge fallback.
- Updated hashline execution and preflight checks to retry mismatched anchors through cache recovery.
- Added file-read cache support with per-session LRU snapshots and contiguous/sparse record APIs.
- Integrated read and search tools with the shared cache to record candidate lines for recovery.
- Added tests for stale-anchor recovery flows and FileReadCache session, null, overlap, and eviction behavior.
2026-05-09 05:50:09 +02:00
can1357 7223b800b0 fix(coding-agent/tools): expanded read ranges with three-line anchor context
- Expanded read tool range calculations to include optional leading and trailing context lines around user-requested offsets and limits.
- Added shared context range expansion logic so line-slice and streaming reads return anchor-safe windows while preserving existing truncation behavior.
- Updated read-tool tests to assert boundary-offset, limit, and combined offset-limit reads now include the expected ±3 lines of context.
2026-05-09 05:22:23 +02:00
can1357 ed0a5709ba docs(coding-agent/prompts): added brace-shape guidance and failure notes to hashline prompt
- Updated `hashline.md` to document brace-boundary edit patterns for block replacement, signature-only edits, and safe interior insertions.
- Added common-failure guidance on range boundaries, duplication checks, truncated anchors, and preferring narrower ops over wide replacements.
- Adjusted the anti-pattern example to match the corrected replacement range behavior.
2026-05-09 04:41:41 +02:00