Commit Graph

4088 Commits

Author SHA1 Message Date
can1357 7282d92bf4 fix: normalized line-ending handling for text and TUI output flows
- Unified line-ending normalization to `replace(/\r\n?/g, "\\n")` in editor, scraper, benchmark, and utils modules.
- Added terminal-aware line sanitization in code-cell rendering to collapse inline carriage returns and avoid overwrite corruption.
- Tightened editor and paste sanitizers to trim control characters consistently after CR normalization.
2026-05-15 23:46:23 +02:00
can1357 2e6d96d3bc feat(coding-agent/tools): added open-ended line range shorthand for read selectors
- Updated read-line selector parsing to accept line-range selectors ending with a trailing dash.
- Mapped selectors with a trailing dash to open-ended ranges that read from the start line onward without requiring an explicit end.
- Updated read tool documentation to document `:50-` as the shorthand for reading from line 50 onward.
2026-05-15 23:46:23 +02:00
can1357 0d00f015ec feat(ai): added 2020-12 schema migration to ai strict validation
- Added draft-07-to-2020-12 schema upgrade logic for `$schema`, `definitions`, `$ref`, tuple, and nullable mapping.
- Integrated `upgradeJsonSchemaTo202012` into strict adaptation, validation, strict-mode, sanitizer, and wire/dereference flows.
- Replaced set-based traversal helpers with record maps, `for...in` loops, and epoch/`once` cycle guards.
- Added unreleased changelog entries and tests for schema normalization, `oneOf` to `anyOf`, and tuple validation edge cases.
2026-05-15 23:46:23 +02:00
can1357 09303733d5 docs(coding-agent/prompts): added hashline restriction against code reformatting
- Updated the hashline prompt to state the tool should never be used for code reformatting tasks.
- Added guidance to run the project's formatter for whitespace, indentation, and style-only edits.
2026-05-15 23:46:23 +02:00
can1357 4b1a68570d fix(coding-agent/hashline): handled CRLF line endings in hashline parsing
- Replaced per-line carriage-return stripping with CRLF-aware line splitting in hashline input and parser paths.
- Adjusted payload collection to trim trailing whitespace from edit separator lines and handle line matching without extra normalization.
- Removed the now-unused hashline utils module and stopped exporting it from the hashline index barrel.
2026-05-15 23:46:23 +02:00
can1357 5c7c5eccb8 fix(ai): corrected AI schema normalization to draft-2020-12 prefixItems
- Adopted draft-2020-12 tuple validation with `prefixItems`, rejecting array-valued `items`.
- Expanded strict-mode handling to recurse `prefixItems` entries and infer `array` when tuple prefixes exist.
- Normalized Anthropic schemas through `prefixItems`, keeping supported tuple constraints and dropping unsupported fields.
- Updated coding-agent schema metadata and tests to draft-2020-12 `$schema` targets, including MCP/theme fixtures.
- Added `trimTrailingWhitespace()` to strip trailing spaces/tabs and keep the original line when none exist.
2026-05-15 23:46:23 +02:00
roboomp 13d77ad6ee fix(coding-agent): disable interactive pty on windows
Fixes #1103
2026-05-15 21:41:11 +00:00
can1357 0bfea39f3c chore: bump version to 15.1.1 2026-05-15 21:22:43 +02:00
can1357 2f2e72c5ac fix: updated metadata URLs and Bun WebSocket types
- Added homepage metadata entries to the Rust and Python package manifests.
- Replaced OpenRouter HTTP-Referer values with https://omp.sh/ in completion and image requests.
- Updated Codex WebSocket typing and construction to use Bun.WebSocket for handshake header capture.
Fixes #1102
2026-05-15 21:22:03 +02:00
can1357 06aadd08f2 chore: bump version to 15.1.0 2026-05-15 19:16:17 +02:00
can1357 37eed1bd33 fix(coding-agent): prevented startup scan timeout warning when work completed first
- Updated `raceWithDeadline` to track whether the timeout branch won the race before logging.
- Deferred the startup scan timeout warning until after the race completed with a deferred result.
2026-05-15 19:09:17 +02:00
can1357 8b1364d4c2 feat(coding-agent): implemented one-shot generateHandoff in coding-agent
- Replaced event-driven handoff with one-shot `generateHandoff(...)` via `completeSimple`.
- Added cancellable `/handoff` command handling with a loader and Escape-to-abort flow.
- Removed legacy `compaction/handoff.ts` exports and added `generateHandoff(messages, model, apiKey, options)`.
- Fixed pre-cancelled handoff behavior to return `Handoff cancelled` and propagate abort signals.
- Updated handoff tests/mocks to assert `generateHandoff` invocation details and `AgentSession.handoff()` options.
2026-05-15 18:49:53 +02:00
can1357 e1aaf78874 refactor(compaction): moved compaction APIs to @oh-my-pi/pi-agent-core
- Relocated compaction, branch-summarization, pruning, and utils from coding-agent to packages/agent/src/compaction.
- Moved OpenAI remote compaction helpers from packages/ai to the new compaction module.
- Added handoff.ts with extractHandoffDocument, createHandoffContext, and renderHandoffPrompt helpers.
- Exposed new entries.ts with standalone SessionEntry types so coding-agent no longer owns them.
2026-05-15 18:31:12 +02:00
can1357 03f09e7ee9 fix(coding-agent/tools): ignore literal refs when scanning yield schemas
YieldTool's unresolved-ref fallback now skips literal-value positions such as const, enum, default, and examples when looking for unresolved schema refs. Valid schemas containing data literals like { "": "literal" } no longer degrade to the loose schema and still reject invalid yield payloads.
2026-05-15 18:31:12 +02:00
can1357 88e5e8a9a2 fix(coding-agent/task): make subagent runtime timeout sticky and abortable through setup
- Runtime-limit timeout is now tracked with a sticky runtimeLimitExceeded flag, so later caller aborts during teardown cannot downgrade the timeout state and let a late yield report success.
- Awaited setup operations before the first prompt are now raced against the subagent abort signal, including auth discovery, model refresh, model resolution, session open, session creation, extension session_start, prompt, and waitForIdle.
2026-05-15 18:31:12 +02:00
can1357 188711b858 fix(coding-agent/eval): close remaining Python dispose races
- disposeAllKernelSessions removes sessions from the registry before awaiting shutdown, preventing queued work from seeing a registered-but-disposing session and spawning a replacement kernel.
- replaceSessionKernel re-checks registry membership after old-kernel shutdown and after starting a replacement, shutting the replacement down if the session was disposed mid-replace.
- owner-scoped disposal now preserves ownerIds when shutdown is unconfirmed so a later disposeKernelSessionsByOwner(ownerId) can retry.
2026-05-15 18:31:12 +02:00
can1357 110a6a3244 fix(coding-agent): persisted bindings from async-wrapped cells via globalThis publish
- Detected async wrapper need via AST traversal instead of regex, enabling pre-demote analysis.
- Published demoted var bindings back to `this` (worker global) when inside the async wrapper, preventing function-scope from hiding them across cells.
- Added `collectBindingNames`/`getLexicalBindingNames` to extract names from destructured patterns.
2026-05-15 18:31:12 +02:00
can1357 ef72d90f2b fix(coding-agent/extensibility): restored TypeBox shim string-format and additionalProperties parity
- Type.String({ format, minLength, maxLength, pattern }) no longer drops the length/pattern constraints when a format selects a Zod format-specific schema (z.email, z.url, z.uuid, …). The instanceof z.ZodString guard never matched those subclasses; constraints are now applied via the shared _ZodString base so all format variants honor them.
- Type.Object without explicit additionalProperties now installs .loose() (matching TypeBox's preserve-extras default) instead of stripping unknown keys. additionalProperties: false continues to install .strict(); a schema value installs .catchall(schemaToZod(schema)).
2026-05-15 17:49:35 +02:00
can1357 46cff37ce4 fix(coding-agent/tools): yield falls back to loose schema on unresolved $ref
dereferenceJsonSchema leaves $ref strings in place when references are unresolvable (external URLs, missing definitions, certain cycles). The new yield-parameters builder now walks the resolved schema for any remaining $ref strings before installing validation; if any are found, it throws so the existing catch branch swaps in looseRecordSchema and disables strict validation. Previously YieldTool installed a validator that rejected every success payload with an unresolved-reference error.
2026-05-15 17:49:23 +02:00
can1357 b489200933 fix(coding-agent/modes): gated scratch folder icon on stripWorkPrefix
The status-line path segment was selecting theme.icon.scratchFolder for scratch directories regardless of opts.stripWorkPrefix, while the CHANGELOG promised both behaviors honor the option. Icon selection now uses the same opts.stripWorkPrefix !== false gate as the scratch path stripping, so disabling stripWorkPrefix keeps the regular folder icon even when the project directory is inside a scratch root.
2026-05-15 17:49:14 +02:00
can1357 c4672f11af fix(coding-agent/task): plugged wall-clock timer holes and propagated context stats
- Added defensive abort re-check after registering the abortSignal listener plus a checkAbort() immediately before await session.prompt(...), so a wall-clock timer that fires during pre-prompt setup is no longer lost between listener registration and the prompt call.
- Late yield events arriving after a wall-clock timeout no longer flip the result to success: a runtimeLimitExceeded flag derived from the internal abortReason forces wasAborted=true and exitCode=1 regardless of hasYield, while yield payloads remain captured in extractedToolData.
- Async task progress now copies contextTokens and contextWindow from the completed SingleResult onto AgentProgress, so backgrounded tasks still surface their context gauge to the UI.
2026-05-15 17:49:00 +02:00
can1357 dad6149393 fix(coding-agent/eval): fenced disposed Python sessions from queued work
- executeOnSession's runQueued callback now re-checks sessions.get(sessionId) === session at slot entry and before the dead-kernel replace retry; if the session was removed by disposeAllKernelSessions / disposeKernelSessionsByOwner / resetSession during the queue wait, the queued caller now rejects with PythonExecutionCancelledError instead of spawning an untracked replacement kernel on a stale session object.
- Both dispose paths now inspect KernelShutdownResult.confirmed and retain (or re-insert) sessions whose shutdown was unconfirmed or rejected, logging a warn so a later dispose can retry the kernel instead of orphaning the subprocess.
2026-05-15 17:48:36 +02:00
can1357 9ca04c9e8c fix(ai): preserved custom tool calls and threaded abort signal in remote compaction
- buildOpenAiNativeHistory now emits custom_tool_call / custom_tool_call_output for blocks with customWireName (apply_patch and other freeform tools), matching the normal Responses replay path; previously demoted to function_call which broke remote-compaction replay or mismatched the original call.
- requestOpenAiRemoteCompaction and requestRemoteCompaction accept an optional AbortSignal; the coding-agent compaction caller forwards the existing signal so cancellation now terminates the in-flight fetch instead of stranding the session in the compacting state until the server replies.
2026-05-15 17:47:32 +02:00
can1357 7c9641c27a fix(coding-agent): cast validated bash args to BashToolInput in test 2026-05-15 17:01:51 +02:00
can1357 35beac2972 fix(coding-agent): defer persist when writer is mid-close
`SessionManager.close()` queues `#closePersistWriterInternal()` on the
persist chain. The task awaits `#persistWriter.close()`, which flips
`#closing = true` synchronously before yielding on its inner writer
`close()`. A concurrent `appendMessage()` landing in that yield window
hit the hot path, got the still-cached (but closing) writer back from
`#ensurePersistWriter()`, and threw `Error("Writer closed")` from
`writeSync`. The throw was stashed into `#persistError`; the next async
caller (`flush()` or a later `appendMessage()`) re-threw it as an
unhandled rejection with the original line-1282 stack.

Expose `NdjsonFileWriter.isOpen()` and treat a mid-close cached writer
as a miss in `#ensurePersistWriter()`. `_persist` now falls back to the
async `#rewriteFile()` cold path so the entry — already in
`#fileEntries` — still lands on disk once the close drains.
2026-05-15 17:00:18 +02:00
can1357 43ed173e2e fix(coding-agent/extensibility): added remap for bare @sinclair/typebox imports to shim
- Added a dedicated `@sinclair/typebox` specifier remap path and routed bare legacy imports to the in-repo shim during extension rewriting and module resolution.
- Added resolve hooks for both `file` and legacy-file namespaces so legacy extensions load the shim consistently at runtime.
2026-05-15 15:26:44 +02:00
can1357 45fe4df39e fix(ai): corrected AI tool handling via JSON-schema validation flow
- Replaced fromTypeBox conversion with a JSON-schema validator flow in ai tool handling and execution paths.
- Added recursive schema validation and expanded TypeBox checks for refs, enums, uniqueItems, and constraint keywords.
- Sanitized Azure/CCA tool schemas by dropping unsupported fields and rewriting oneOf tool branches as anyOf.
- Tightened argument and model-config validation, preserving unknown tool fields and adding apiKey plus compatibility flags.
2026-05-15 15:16:50 +02:00
can1357 2867e1f4e3 feat(deps): added pi.zod exports and removed TypeBox package exports
- Added canonical `pi.zod` schema API exports and removed TypeBox package exports/imports.
- Migrated Tool schema typing from TypeBox to shared `TSchema`/Zod flow with legacy TypeBox compatibility.
- Updated AI provider adapters and MCP/agent builders to convert tool params through `toolWireSchema()`.
- Reworked schema validation from AJV to Zod-safe parsing with `fromTypeBox`, `toolWireSchema`, and meta schema checks.
2026-05-15 14:46:54 +02:00
can1357 9a755822eb fix(coding-agent): resolved coding-agent SIGINT shutdown escalation path
- Added bounded SIGINT escalation with `requestCancel()` to force kernel shutdown after 2s.
- Removed executor idle-timeout, max-session, heartbeat, and deferred disposal-retry logic.
- Added per-session `runQueued()` execution and dead-kernel restart retry flow for owned sessions.
- Replaced kernel session tracking with reusable `sessions` map and `acquireSession()` ownership registration.
- Removed obsolete owner-cleanup session-capacity tests and updated dead-session mocks to resolver-based flow.
2026-05-15 14:46:54 +02:00
can1357 005c3cd81a feat(coding-agent/task): added subagent runtime timeout and context-window progress reporting
- Added a task.maxRuntimeMs setting with a default disabled state for per-subagent runtime limits.
- Updated subprocess execution to enforce the configured wall-clock timeout, mark timeouts as aborts, and include timeout-specific abort messaging.
- Tracked per-turn context size and context window through task progress/results and updated UI renderers to display current context against window with cumulative tokens rendered separately.
2026-05-15 14:46:54 +02:00
can1357 1e601b9094 test(agent): replaced agent stream mocks with createMockModel responses
- Replaced custom MockAssistantStream helpers with createMockModel streams across agent tests.
- Removed manual queueMicrotask stream-event scripting in favor of scripted mock responses.
- Consolidated helper fixtures by deleting local aliases and reusing shared user-message/model helpers.
- Updated test assertions to use mock.calls and mock.model metadata for call and context validation.
2026-05-15 14:46:54 +02:00
can1357 361a40dc43 refactor(coding-agent): replaced reverse/find usage with last-item array helpers
- Updated plan-mode and hindsight session state lookups to use Array.findLast for selecting the latest assistant or user message.
- Updated postmortem callback iteration to use Array.toReversed before mapping cleanup callbacks.
2026-05-15 14:46:54 +02:00
can1357 ea76fae05f feat: added OpenAI remote-compaction provider endpoint gating support
- Added OpenAI remote-compaction API support with provider-specific endpoint gating.
- Added buildOpenAiNativeHistory, token-budget estimation, and message trimming for remote-compaction.
- Added helpers to preserve and validate remote-compaction metadata in request/response handling.
- Refactored coding-agent compaction to consume pi-ai remote-compaction helpers with converted message history.
- Exported remote-compaction from ai index and documented the new APIs in CHANGELOG.
2026-05-15 14:46:54 +02:00
can1357 e4e2389f83 refactor(agent): converted GenAI telemetry attributes to a const enum
- Replaced `GenAIAttr` with an `export const enum` in telemetry while preserving all GenAI attribute constants.
- Updated the OTEL stream test fixture to emit an `error` event with an `error` payload instead of a `done` event.
- Added runSubprocess telemetry propagation tests for inheriting parent telemetry and handling missing parent telemetry.
2026-05-15 14:46:54 +02:00
can1357 b642607ea9 feat(coding-agent/task): added telemetry propagation for subagent task handoffs
- Task tool sessions now expose and forward parent OpenTelemetry config when creating subagent tasks.
- Subprocess execution now derives child telemetry from the parent config with the subagent identity and child session conversation handling.
- Subagent creation now records a handoff span using the resolved parent telemetry handle before running the child loop.
2026-05-15 14:46:54 +02:00
can1357 2a1052ea9f fix(coding-agent): aligned output counters after sink replacement
- Adjusted OutputSink to disable head retention after replace(), resetting counters so later pushes append to the tail and do not trigger stale middle-elision in dump().
- Refined artifact link emission to insert a newline separator only when the minimized output lacked one.
- Added a regression test for replace-plus-push ordering that verifies no elision marker and aligned byte counts.
2026-05-15 14:46:54 +02:00
can1357 4679789cf1 feat(agent): added OTEL spans for agent invoke/chat/tool flows
- Added opt-in telemetry configuration to Agent and session APIs, including Agent#setTelemetry mutator.
- Implemented OpenTelemetry spans for invoke_agent, chat, execute_tool, and handoff paths with metadata and step tracking.
- Added a telemetry helper module, OpenTelemetry request/usage types, and dependency wiring with no-op behavior when tracer SDK is absent.
- Added OTEL end-to-end tests and fixed coding-agent OutputSink realignment and artifact-link newline output issues.
2026-05-15 14:46:53 +02:00
Can Bölük 7d02e4d86b Merge pull request #1094 from oldschoola/fix/legacy-pi-windows-drive-letter
fix(extensibility): treat Windows drive-letter paths as filesystem in legacy-pi mirror
2026-05-15 14:46:33 +02:00
roboomp 94d3cb37cc fix(sdk): write service_tier_change entry on new-session startup
When initialServiceTier is resolved from settings (e.g. the user has
serviceTier: priority configured as a default), sdk.ts wrote model_change
and thinking_level_change entries for the new session but omitted
service_tier_change. The stats parser derives priority-tier premium counts
from service_tier_change entries, so sessions started in fast mode without
an explicit /fast toggle had no tier entry and were undercounted in omp-stats.

Mirror the thinking_level_change pattern: write service_tier_change
alongside the other initial entries when initialServiceTier is set.
2026-05-15 11:11:54 +00:00
oldschoola 69043d3071 fix(extensibility): treat Windows drive-letter paths as filesystem in legacy-pi mirror
isUrlLikeSpecifier matched Windows absolute paths (e.g. `C:\foo`) because the URL-scheme regex `^[A-Za-z][A-Za-z\d+.-]*:` happily eats a single drive letter. When a legacy plugin extension imported a bare-specifier dep from its own `node_modules`, rewriteBareImportsForLegacyExtension resolved it to an absolute path, then toRewrittenImportSpecifier short-circuited pathToFileURL and embedded the raw Windows path into the mirrored TS source.

The TS string-literal parser then ate \n, \U, \y and friends, producing nonsense package specifiers like `C:Usersjames.ompagentextensionssupipowers\node_modulesyamldistindex.js` that Bun rejected with `Cannot find package …`. Net effect: every legacy extension that pulls in any node_modules dep failed to load on Windows.

Fix: reject `^[A-Za-z]:[\\/]` in isUrlLikeSpecifier before the URL-scheme test so drive-letter paths flow through pathToFileURL and reach the mirror as proper `file:///C:/...` URLs.
2026-05-15 02:44:49 -07:00
can1357 e56e091b8a fix(extensibility): added centralized session slash command discovery for extensions
- Added a shared session command helper that aggregates extension, prompt, and skill slash commands.
- Updated ACP, extension UI, runtime-init, and task executor extension contexts to return session command data instead of empty arrays.
2026-05-15 10:21:12 +02:00
can1357 cb6c085a41 fix(coding-agent/lsp): fixed root marker glob detection and marksman warmup timeout
- Updated root marker detection to read the directory once and match glob markers against top-level entries, preventing recursive scans when checking project roots.
- Adjusted root-marker glob error handling to warn on directory listing failures and treat the marker set as absent when unreadable.
- Reduced marksman's configured warmup timeout from 15,000 ms to 2,000 ms in LSP defaults.
2026-05-15 10:20:44 +02:00
Parsifa1 cf22f02584 fix(coding-agent): add CONDA_PREFIX for python venv 2026-05-15 07:57:59 +00:00
can1357 1b9e585ed8 fix(hashline): accepted bare blank payload lines for required payload ops
- Updated collectPayload to accept intervening blank lines as empty payload when requirePayload is true and no payload has been collected yet.
- Added a fallback path alongside the HL_EDIT_SEP check so blank insertions without a separator are tolerated as required-payload op payload lines.
2026-05-15 09:50:07 +02:00
can1357 0f1df8b2e2 test(coding-agent): updated edit-diff guards to provide non-empty hashline bodies
Commit d43655541 made splitHashlineInputs silently drop sections whose
body has no operations, so '@<path>\n' alone now yields zero sections
and trips the 'exactly one hashline section' guard before reaching the
no-op or local-URL checks the tests intended to exercise.

- 'returns no-op error for unchanged content' now uses '= 1<hash>..1<hash>'
  with the existing line as payload (true no-op via formatLineHash).
- 'returns a handled error when the source path is a local URL' appends
  '+ EOF\n' so the section is emitted and resolveToCwd surfaces the
  internal-scheme rejection.
2026-05-15 09:37:24 +02:00
can1357 fe6b5b42b4 chore: bump version to 15.0.2 2026-05-15 09:18:53 +02:00
can1357 3b1a714a01 chore: update homepage 2026-05-15 09:18:41 +02:00
can1357 d436555419 fix(coding-agent/core): dropped hashline sections without intermediate operations
- Updated hashline splitting to skip emitting a section when a path header has no following operations.
- Added a trimmed non-empty check so only sections with diff content are returned.
- Added tests for duplicate and trailing headers to ensure empty header-only chunks are silently dropped.
2026-05-15 09:02:55 +02:00
can1357 d4f9b5d497 Merge remote-tracking branch 'origin/farm/d3b4991c/fix-windows-env-colon-vars' 2026-05-15 07:05:42 +02:00
roboomp 737288676c fix(pi-shell): preserved $env:VAR refs through brush expansion
Brush-core applied POSIX parameter expansion to $env before dispatching a command, mangling PowerShell references like Write-Host $env:SystemRoot to :SystemRoot. Move the fix down to env-var application: every brush session now defines env=$env as an internal (non-exported) shell variable, so the bash expansion of $env yields the literal $env and PowerShell tokens reach the child intact. User assignments (env=prod; echo "$env:8080") still shadow the fallback in their command scope, so the POSIX bash contract is preserved.

Fixes #1079
2026-05-15 03:50:51 +00:00