Move the color math added for the session-accent fix into the shared
@oh-my-pi/pi-utils color module instead of a coding-agent-local file:
- colorLuma, relativeLuminance, and hslToHex now live in
packages/utils/src/color.ts (hslToHex lifted out of session-color.ts).
- Drop the duplicate hex parser: toRgb reuses the existing hexToRgb and
paletteToRgb returns the shared RGB type, so hex parsing lives once.
- Delete packages/coding-agent/src/utils/color.ts; theme.ts and
session-color.ts import from @oh-my-pi/pi-utils.
- Move the color unit test into the utils package; repoint session-color
test imports.
No behavior change to accent luminance capping.
- Added `loadOverallPlanReference` to resolve a session plan reference from local storage and skip empty or missing files.
- Updated task execution to read the active plan reference (except in plan mode) and pass it into each spawned subagent.
- Extended the subagent system prompt and session SDK/tools plumbing so subagents receive and render the approved plan path and contents.
- Added TranscriptContainer that snapshots non-live blocks to avoid stale scrollback duplicates.
- Thawed snapshots at prompt-submit checkpoints for reconciliation.
- Repainted eager streaming tail on overflowing shrink to unfreeze UI (issue #1682).
- Added `selectionMarker`, `checkedIndices`, and `markableCount` options to render radio/checkbox glyphs per row.
- Moved checkbox rendering from inline label prefixes into the selector component.
- Kept trailing control rows like "Other"/"Done" on the plain cursor.
- Added `isReadOnlyAgent` and `READ_ONLY_TOOL_NAMES` to classify agents.
- Marked read-only agents and forbade edits, commands, and reasoning offload.
- Added tests for capability classification and description rendering.
The `search` tool required `paths` via a strict `union([string,
array.min(1)])`, so any call that omitted `paths` (or passed an empty
array) was rejected at schema validation with `paths: Invalid input`
and never ran — turning a recoverable "no scope given" into a fatal
tool-call failure.
Make `paths` optional and default an omitted/empty value to the
workspace root (`.`), matching the documented prompt contract. Behavior
is unchanged when paths are supplied. Adds regression coverage for the
omitted and empty-array cases.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Renamed `TodoWriteTool` to `TodoTool` and its source/prompt files.
- Updated tool registration, schema, renderers, and gating to `todo`.
- Adjusted cursor provider native tool names and tests to match.
- Renamed strike-animation constants and `todo-error-reminder` type.
- Added `IndexedSessionStorage` with `SessionStorageBackend` for index-based storage reads.
- Removed `readTextSync` from the public `SessionStorage` API and sync backends.
- Changed Redis and SQL backends to warm `{size, mtimeMs}` metadata and read via `readTextSlices`.
- Added per-path write queues and `drain()` to serialize operations and surface first failures.
- Classified each session's final message as done, interrupted, aborted, error, or pending from a 32 KiB tail read.
- Rendered the status as a colored segment on the session metadata line.
- Added `peekFileTail` and `readTextSuffix` across storage backends to read file tails in one pass.
- Simplified `MemorySessionStorage` to a string array mirror with a sidecar mtime map.
- Extended line selector parsing in path-utils to accept `..` as a forgiving alias for `-`, with `..` normalized during chunk parsing.
- Updated selector-matching regexes for file selectors and internal URL selectors to recognize alias-style ranges in single chunks and comma-separated lists.
- Added tests covering `N..M`, `N..`, mixed separators, inverted-range errors, and path-splitting behavior with `:N..M` selectors and `foo:../bar.ts` paths.
- Added `textSizing` terminal capability and `tui.textSizing` setting for Kitty OSC66 scaling.
- Updated OSC66 range and visible-width handling to preserve grapheme slice behavior.
- Updated markdown rendering to apply heading text sizing only when enabled.
- Fixed DECCARA trailing-background fill tracking and DECRPM status 3/4 recognition.
- Updated completion and ask notifications to pass structured payloads.
- Updated completion and ask notifications to include explicit message metadata fields.
- Adjusted abort-guard and retry-capability tests for the new notification/options behavior.
- Added debug menu options for terminal state and protocol checks with new handlers.
- Added terminal diagnostics models and collectors to report geometry, protocol flags, and multiplexer data.
- Added protocol-probe utilities to encode RGB PNGs, generate sample content, and render test panels.
- Added support components for verbatim line rendering and OSC66-scaled text rows.
- Added tests validating image encoding, OSC66 output, and terminal state formatting.
- Updated the grammar to parse replace hunks with zero body lines.
- Changed empty replace execution to emit delete edits across the target range.
- Updated tests to verify empty replace syntax deletes lines while empty inserts still throw errors.
The Agent Skills standard (agentskills.io/specification) uses
`disable-model-invocation: true` to hide skills from auto-discovery.
OMP only recognized `hide: true`. This patch treats both as equivalent,
improving compatibility with skills authored for Pi, Claude Code, and
other harnesses following the standard.
Changes:
- Check `disableModelInvocation` (camelCase after frontmatter parsing)
in all 3 skill-loading paths
- Add `disableModelInvocation` to SkillFrontmatter type with JSDoc
- Add regression test for disable-model-invocation frontmatter
- Add changelog entry
Ref: https://agentskills.io/specification#frontmatter-required
- Rendered single-choice questions with circular radio glyphs instead of checkboxes.
- Kept rectangular checkboxes for multi-select questions.
- Added radio.selected/unselected symbols to unicode, nerd-font, and ASCII presets.
- Updated hook option rendering to support description modes for full text, bounded rows, or hidden detail output.
- Adjusted compact-mode row budgeting so list height is based on labels, preventing a single description from consuming the visible budget.
- Added pre-wrapping with ellipsis truncation for selected option descriptions and updated overflow tests to validate the collapsed label-first behavior.
When OTEL_EXPORTER_OTLP_ENDPOINT (or _TRACES_ENDPOINT) is set, register a
global OTLP/proto TracerProvider and switch on the agent loop's telemetry
so its invoke_agent / chat / execute_tool spans reach a collector instead
of a no-op tracer. Honors the standard OTEL_* env contract
(OTEL_SERVICE_NAME, OTEL_SDK_DISABLED, OTEL_TRACES_EXPORTER=none) and the
OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT capture toggle; no-op
when no endpoint is configured.
Uses the exporter-trace-otlp-proto 2.x line, which exports cleanly under
Bun (the 1.x line deadlocks). Adds a flushTelemetryExport() helper and a
periodic + signal-driven flush so long-lived processes surface spans.
This makes the existing telemetry usable from hosts that spawn omp as a
child process (e.g. an ACP harness), where an in-process provider
registered by the parent can't reach the child process.
- Detection now recognized `.jj/repo` as workspace metadata whether it is a directory or a file.
- Repository resolution followed `.jj/repo` file indirection so non-default `jj workspace add` workspaces resolved their shared store path.
- Tests were added to confirm `jj.repo.is` and `jj.repo.resolve` handle file-backed `.jj/repo` workspaces correctly.
- Added shared `getReadToolPath` API to extract paired read `path` values for protection matchers.
- Added `createPlanReadMatcher` and session wiring so compaction prune/shake keeps active plan reads intact.
- Updated `todo-write` instructions to initialize every user-supplied plan item as an individual task.
- Added compaction tests validating plan reads are protected from prune and shake while regular reads are still removable.
On Windows, Bun's FileSink surfaces a broken pipe as a *rejected Promise*
(the EPIPE arrives via a processTicksAndRejections tick), not a synchronous
throw. The sync-only `writeFrame()` from #1711 returns `true` for such a
write and lets the rejected promise float; `request()` likewise wrote stdin
without awaiting. Either path escapes as an unhandled rejection, which the
postmortem handler turns into a fatal process.exit(1) when an MCP server
exits mid-handshake.
- writeFrame: also neutralize a rejected Promise returned by write()/flush()
(covers the notify + #sendResponse paths).
- request(): await write()/flush() so the rejection lands in the existing
try/catch and rejects the request instead of floating.
- tests: cover the async-rejection path for writeFrame.
Follow-up to #1710 / #1711, which addressed only the synchronous throw. The
existing notify mid-handshake test fails on Windows without this change
because the real FileSink rejects asynchronously.
- Empty `content: []` triggered the empty-stop guard, short-circuiting the agent_end handler before compaction checks ran.
- Replaced with a minimal text turn so auto-compaction queue resume tests complete under fake timers.
- Added async `discoverLmStudioModel()` to query the OpenAI and native LM Studio APIs, resolving the actual model id, name, and context window.
- Replaced hardcoded `execSync curl` availability check with API-driven discovery controlled by `PI_LOCAL_LLM` env var.
- Simplified compaction test spy to match on provider only, removing fragile context-marker filtering.
- Added optional `AgentTool.matcherDigest(args)` hook so tools can expose plain source text instead of wire-encoded arguments to TTSR rule matchers.
- Implemented `matcherDigest` on edit (all modes: hashline, patch, apply_patch, replace) and write tools, stripping patch prefixes and JSON escaping.
- Added `TtsrManager.checkSnapshot()` to replace the scoped buffer with a tool digest rather than appending raw deltas.
- Fixed TTSR conditions never matching streamed edit/write calls whose wire format obscured real content.
- Warns against leaving `@deprecated` compatibility shims instead of finishing a refactor.
- Registered in the builtin rule index and covered by the defaults test.
- Grouped `isRepository`, `workspaceRoot`, and `clearWorkspaceRootCache` under a `repo` namespace (`repo.is`, `repo.root`, `repo.clearRootCache`).
- Promoted `diff` to a named export with a `changedFiles` sub-method via `Object.assign`.
- Added `ensureAvailable` check and `nameOnly` support to `diff`.
- Updated callers and tests to use the new API surface.
- Replaced `jj workspace root` subprocess call with a local `.jj/repo/store` directory traversal, eliminating process spawning overhead.
- Added LRU cache for resolved workspace roots to avoid redundant filesystem walks.
- Renamed internal `runCommand` helpers to `git`/`jj` for clarity.
- Replaced git subprocess setup in review test with mocked `git.status` and `git.diff` calls.
- Added Job::abort_internal_tasks to abort internal async tasks and drop their join handles.
- Updated shell cancellation paths to call this abort logic and handle mutable shell job lists before signaling remaining process groups.
- Added Rust and TypeScript tests that verify cancellation prevents background shell jobs from completing after abort.
Surface the hidden discoverable built-in tool names (write, find, search, lsp, task, ...) in the search_tool_bm25 description when tools.discoveryMode is "all", so a model can form a targeted BM25 query by name instead of guessing or falling back to shell. mcp-only mode is unchanged (no built-ins advertised) and the total-tools count still includes them.
Loaded cached startup models for special built-in providers alongside standard provider descriptors so boot-time model resolution can see cached Google Antigravity, Gemini CLI, and OpenAI Codex discoveries before refresh.\n\nFixes #1721