- Consolidated `cosineSimilarity` in `vector-math`, removed duplicate local impls, and treated mismatch/non-finite as zero.
- Switched beam, query-cache, recall, shmr, and binary-vectors to consume shared `cosineSimilarity` from `vector-math`.
- Changed embeddings to parse `$env/$flag`, return `Float32Array`, lazily import model deps, and retry via `fetchWithRetry`.
- Added `@oh-my-pi/pi-utils` and replaced hardcoded FastEmbed cache paths with `getFastembedCacheDir`.
- Expanded truthy parsing for lowercase `y`, `true`, `yes`, and `on`, then updated optional-embedding tests for cache behavior.
- Updated binary-vectors and optional-embedding tests for NaN-safe cosine, `Float32Array`, and cache-dir expectations.
- Removed `scrubProcessEnv` from procmgr and its explicit call in cli.ts.
- Scrubbing now happens automatically when `dirs.ts` is imported, eliminating the need for a manual call at startup.
- Added `providers.tinyModel` with an `online` default and UI schema metadata; documented tiny-title updates in changelogs.
- Added tiny-title system prompt and title-text helpers to truncate input, wrap `<user-message>`, and normalize output.
- Added tiny-title model registry, local model specs, key validation, and cache-path helper.
- Added tiny-title transport/client/worker flow with spawn fallback, queued requests, ping checks, and graceful close.
- Updated `generateSessionTitle` to route by tiny-title model and race local generation against delayed online fallback.
Marketplace and `omp plugin link` installs write to
`<plugins>/node_modules/` rather than to `extensions:` in settings,
so the original PR still missed their sibling skills/, hooks/,
tools/, commands/, rules/, prompts/, .mcp.json sub-trees. Wire
listOmpExtensionRoots to enumerate getEnabledPlugins(cwd, { home })
in addition to CLI-injected and settings-driven roots.
Adds an optional { home } parameter to getEnabledPlugins so the
discovery loader can pass through LoadContext.home for tempdir-rooted
tests. The getPluginsNodeModules/getPluginsPackageJson/
getPluginsLockfile helpers gain the same optional home overload so
they mirror getPluginsDir.
Per-PR review feedback: https://github.com/can1357/oh-my-pi/pull/1498
- Classified usage-limit gateway responses as `429 rate_limit_error` in auth handling paths.
- Aligned auth-gateway and pi-native key retrieval with derived `sessionId` for `getApiKey` lookups.
- Handled usage-limit auth failures by rotating credentials with retry hints and returning undefined when none available.
- Replaced stream auth checks with retryable-upstream logic for 401 and usage-limit errors before content.
- Expanded `extractRetryHint` parsing for `~`, `sec`, `ms`, and minute/hour units.
- Added coverage for classifyGatewayError, retry-hint parsing variants, and stream-auth retry edge cases.
- Imported isPromise from node:util/types in four modules.
- Replaced four instanceof Promise checks with isPromise calls for more reliable promise detection.
- Clamped `formatDuration` to return `0ms` for non-positive, NaN, or infinite inputs.
- Updated usage report rendering to suppress reset countdowns when `resetsAt` is absent or no longer in the future.
- Added unit tests for `formatDuration` covering clamped values and standard duration formatting.
- Added a custom JSON replacer that unwraps `Error` instances in logger output, preserving name, message, stack, cause, and enumerable fields.
- Updated uncaught-exception and unhandled-rejection logging paths to pass only `{ err }`, relying on the logger serializer for full error details.
- Extended transient socket-close matching to detect HTTP2 stream reset/refused/calm errors and added regression tests for logger error serialization behavior.
- AuthBrokerClient now checked the response Content-Type and rejected non-SSE responses before parsing.
- It required the first parsed SSE event to be a snapshot and treated ended or truncated streams as errors.
- Added coverage for non-SSE and missing-initial-snapshot streams, and reset raw SSE state for empty events.
The Bun.env scrub and filterProcessEnv used isValidEnvName (strict shell
identifier shape), which deleted standard Windows variables like
ProgramFiles(x86) and CommonProgramFiles(x86). procmgr.ts imports this
module before resolving the shell and reads Bun.env['ProgramFiles(x86)']
to find Git Bash under 32-bit Program Files, so installations that only
had Git there were no longer discovered and failed with 'No bash shell
found'.
The unsafe cases for native execve are '=' or NUL in names and NUL in
values, not parentheses. Introduce isSafeEnvName covering exactly those
cases and use it for the in-place Bun.env scrub and the spawn-env
filter. Keep isValidEnvName (strict) for dotenv parsing, where strict
shell-identifier shape is the right contract.
- Buffered `start` events until after the first replay-unsafe event and replayed them on auth failure.
- Retried stream requests with refreshed credentials when `onAuthError` returned a new key for gateway and pi-native.
- Added 401 error-status parsing for assistant errors and updated stream-auth tests for start+401 retry behavior.
- Added `AuthRetryFailure` helpers and status extraction types to propagate auth-retry metadata through stream attempts.
- Added a new `setTransports` logger API to swap console and file winston transports at runtime.
- Refactored logger transport creation to lazily build rotating file logs via a shared directory helper.
- Updated auth-broker serve startup/shutdown to use structured logger output and switch to console-only logs for its headless runtime.
- Added `AuthBrokerClient`, `RemoteAuthCredentialStore`, `AuthBrokerRefresher`, and `startAuthBroker` server in `packages/ai/src/auth-broker`.
- Renamed `AuthCredentialStore` class to `SqliteAuthCredentialStore`; extracted `AuthCredentialStore` as a persistence interface.
- Added `exportSnapshot`, `forceRefreshCredentialById`, `disableCredentialById`, and `upsertCredential` to `AuthStorage` for broker wire protocol.
- Added `omp auth-broker` CLI subcommand (serve, token, login, logout, import, status) and `discoverAuthStorage` broker-mode path keyed on `OMP_AUTH_BROKER_URL`.
- 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.
- 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.
- Introduced `FetchImpl` type with optional `preconnect` to accept non-Bun fetch implementations without type errors.
- Applied the new type across all providers and `StreamOptions.fetch`.
- Added tests verifying fetch override routing for openai-completions, openai-responses, and fetchWithRetry.
- Introduced a `fetch` option on `StreamOptions` and threaded it through providers to let callers supply a custom request transport.
- Updated provider clients and direct HTTP calls across Anthropic, OpenAI, Azure, Google, GitLab Duo, Gemini CLI, Ollama, and Codex flows to use the injected fetch implementation.
- Extended retry helper options to accept a fetch override and preserved preconnect support from the selected fetch function.
- Updated the hashline mismatch error to describe anchor mismatches against the current file.
- Rewrote hashline tool instructions to clarify insert payload rules, anchor usage, and avoidance of fabricated hashes.
- Expanded stale-edit detection and tests to recognize the revised anchor-mismatch rejection wording.
- Added an HTML comment state tracker to prompt formatting.
- Updated ASCII symbol replacement to skip substitutions inside `<!-- ... -->` comment blocks across lines.
- Added tests that preserved comment text while converting symbols outside comments.
- Removed local `abortableSleep` in favour of Node's built-in `scheduler.wait` from `node:timers/promises`.
- Consolidated per-provider retry/fetch loops into a shared `fetchWithRetry` utility in `packages/utils`.
- Moved `extractHttpStatusFromError`, `isRetryableError`, and related helpers out of `packages/ai` into `packages/utils`.
- Deleted `extractRetryDelay` in favour of `extractRetryHint` with unified header and body parsing.
- Added issue:// and pr:// URL handlers for single lookups and list queries with query filters.
- Added a SQLite-backed GitHub cache with soft/hard TTLs, stale hits, and background stale refresh.
- Removed issue_view and pr_view tool operations, inputs, and docs, requiring reads via issue:// and pr:// URLs.
- Added github-cache and issue-pr-protocol tests with temporary cache DB setup and OMP_GITHUB_CACHE_DB teardown.
- Standardized prompt templates across agents, tools, system, memory, and compaction to NEVER/AVOID wording.
- Reinforced policy language to ban edits/builds, state changes, and unsolicited JSON/code or filler output.
- Renamed stripRfc2119Bold to normalizeRfc2119, mapped NEVER/AVOID aliases, and skipped inline-code replacements.
- Updated the unreleased changelog to document the prompt-terminology migration.
- Replaced `with { type: "file" }` worker imports with `isCompiledBinary()` hybrid: literal string for `--compile` static analysis, `new URL(import.meta.url)` for dev portability.
- Added worker entrypoints as explicit `--compile` args in `build-binary.ts` so Bun emits them into bunfs.
- Added `smokeTestSyncWorker` and `omp --smoke-test` to catch silent worker-load failures in compiled binaries (fixes#1011, #1027).
- Added `isCompiledBinary()` utility to `@oh-my-pi/pi-utils` detecting bunfs path markers.
- Added explicit prompt markers and wrappers across system templates, including `[env]`, `[role]`, `[coop]`, `[closure]`, and `[now]`.
- Removed `renderTemplate` and `sectionSeparator` flows, deleted `task/template.ts`, and switched to per-task `renderSubagentUserPrompt` rendering.
- Updated system prompt assembly to `shortenPath`-normalize `cwd`, append rendered now metadata, and preserve trailing `[now]` blocks.
- Removed legacy template tests and added prompt-composition tests for ordered `[contract]`->`[project]`->`[now]` blocks and context-only system placement.
- Reworked shared prompt utilities by collapsing consecutive blank lines and removing obsolete `OPENING_HBS`/`LIST_ITEM` helper behavior.
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.
- Added a new `scrubProcessEnv` helper in `procmgr` to remove macOS malloc logging variables from `process.env` before spawning.
- Invoked the helper at coding-agent CLI startup so bun sub-processes no longer inherit the problematic environment.
- This prevented the recurring `MallocStackLogging` warning from appearing in child process stderr output.
- Added `readSseEvents` and `ServerSentEvent` exports in utils for reusable SSE stream parsing.
- Replaced Anthropic's local SSE parser with shared `readSseEvents(response.body, signal)` decoding.
- Updated abort handling in agent stream loop to race an `ABORTED` sentinel with `responseIterator.next()`.
- Expanded stream tests for `readSseEvents` parsing of CRLF, comments, split UTF-8 chunks, and trailing events.
listClaudePluginRoots accepts a home parameter so callers (and tests)
can override the base directory, but the OMP registry path was constructed
via getPluginsDir() which always reads the global dirs resolver anchored
to os.homedir(). This caused every test that passed a temp dir as home to
receive the real user registry alongside the test fixture, producing
length mismatches (+1 root in every assertion).
Fix: add an optional home override to getPluginsDir(). The override only
short-circuits the resolver when home differs from RESOLVER_HOME (the
os.homedir() value captured at module load, i.e. what dirs is anchored
to). Production callers that pass os.homedir() match RESOLVER_HOME and
still go through the XDG-aware resolver, preserving read/write coherence
with the marketplace writer and the cache invalidator. Tests passing a
temp HOME mismatch and short-circuit to <home>/<configDir>/plugins for
deterministic isolation.
- Updated `formatNumber` to use a helper that removes trailing `.0` for compact K/M/B values.
- Adjusted small-value branches so exact thousands and millions now format as whole units while keeping one decimal for fractional values.
- Revised the function comment examples to match the new `1K` and `1M` outputs.
- Replaced file-backed autoresearch contracts with sqlite-backed session/run storage in `~/.omp/autoresearch`.
- Added `AutoresearchStorage` and rewired `init_experiment`, `run_experiment`, and `log_experiment` to persist sessions and runs.
- Added `update_notes` tool with `body`/`append_idea` inputs and updated prompts to use active-session context.
- Removed `autoresearch.md` contract parsing and checks flow, including `runChecks`, `force`, and timeout schema options.
- Updated autoresearch state/types to persist `goal`, `notes`, `branch`, and `baselineCommit` plus run justification/flag metadata.
- Tracked `models.json` modification time in the registry to skip redundant static model reloads when unchanged.
- Reworked model overlay merges and package-runner detection to use indexed lookups plus parallel file/JSON scans instead of sequential searches.
- Cached compiled prompt templates and reduced startup work by bypassing up-to-date changelog parsing and deferring background model refresh.
- Updated AGENTS.md discovery to use glob search honoring .gitignore, depth limits, and deduped results.
- Updated eval tool flow so Python preflight runs only when needed and exec now maps to eval when available.
- Deferred canonical model-index rebuilds during refresh/rebuildProvider and replayed pending rebuilds after resume.
- Added memoized model-equivalence resolution with trailing-marker and canonical reference caches.
- Optimized frontmatter key normalization to keep unchanged keys/arrays/objects without extra cloning.
- Updated JS executor tests to use base-path concatenation for nested fixture filesystem calls.
- Documented and removed `utils/oauth` from the `ai` package entrypoint, noting it as a breaking change.
- Refactored `cli`, `auth-storage`, and `utils/oauth` to load provider modules via scoped dynamic `import()` calls.
- Removed top-level provider imports and barrel exports from `utils/oauth/index.ts`, streamlining oauth module loading.
- Consolidated OAuth symbol, type, and provider imports in coding-agent and tests to `@oh-my-pi/pi-ai/utils/oauth` modules.
- Defined `DEFAULT_LOCAL_TOKEN` locally in model-registry and removed its cross-package OAuth import usage.
- Parallelized startup by deferring plugin preload and running AGENTS.md scan plus context/template/command discovery in parallel.
- Added AgentsMdSearch exports and options so prebuilt search results were passed into system-prompt construction.
- Reworked logger timing to use AsyncLocalStorage-backed nested spans, initialize a root span, and emit hierarchical summaries.
- Added PI_TIMING-gated TS/TSX module-load timing via side-effect module-timer registration and wrapped key init/request paths with logger.time.
- Added ProcessWaitOptions-based wait APIs with timeoutMs and abort signal support.
- Changed terminate options to accept optional signal for cancellation-aware process shutdown.
- Hardened process identity handling to avoid PID-reuse errors on Linux, macOS, and Windows.
- Updated termination flow to use live descendants and escalate from graceful to hard-kill signals.
- Wrapped awaited Process.fromPid(...).waitForExit() with parentheses before ?? true fallback.
- Added `Process` class with pidfd (Linux), libproc (macOS), and handle (Windows) ownership for race-free signaling.
- Replaced `killTree`/`listDescendants` free functions with `Process.fromPid`, `fromPath`, `terminate`, and `waitForExit`.
- Added `TerminationTargets` for batching pgid+pid sets across pty and shell job teardown.
- Migrated `procmgr` and `ptree` to use the new native API, removing the `setNativeKillTree` injection pattern.
- Added support for batch PR operations by accepting `pr` as string or array and dropping `worktree` input.
- Updated `pr_view` and `pr_diff` to normalize PR IDs, process multiple PRs in parallel, and emit combined summaries.
- Refactored checkout into `checkoutPullRequest`, added repo-locking, fixed worktree paths, and summary metadata outputs.
- Updated `remote.add` handling with URL-aware idempotency and per-repo queueing for serialized git mutations.
- Added temp-home test scaffolding and expanded tests for batched PR flows and remote add conflict/no-op cases.
- Prevented template compile failures from `}}}` sequences by normalizing closing braces before `handlebars.compile`.
- Updated Unreleased `CHANGELOG.md` to describe current hashline/edit/path behavior changes.
- Standardized tool prompt example formatting by replacing `<example>` blocks with unified `<examples>` sections.
Codex code review flagged that external templates copied from pre-rename
versions of the repo still reference the misspelled SECTION_SEPERATOR
helper. Despite pi-utils compiling with `strict: false`, Handlebars
still throws "Missing helper" on unknown helpers in that mode
(verified: `strict: false` only silences missing context variables,
not missing helpers), so renaming alone would break live user configs
at render time.
Registers the legacy `SECTION_SEPERATOR` name as a second alias to the
same implementation so both spellings render identically. The canonical
spelling `SECTION_SEPARATOR` is used in all in-tree templates; the
alias exists purely for backward compatibility with external templates.