Commit Graph

53 Commits

Author SHA1 Message Date
roboomp d7d94949fa fix(tts): isolated kokoro onnxruntime loading
Loaded Kokoro's side-installed transformers runtime by absolute path before requiring kokoro-js, avoiding host/workspace onnxruntime libraries in the worker process.

Kept runtime-cache bare module requests inside the registered runtime cache when the parent module is already inside that cache, and covered the resolver boundary with a regression test.

Fixes #2591
2026-06-14 21:56:50 +00:00
can1357 2b436f222a chore: update changelogs 2026-06-14 18:21:35 +02:00
can1357 63572329dd test(utils): cover TempDir retry bound and skip filters
Adds regression coverage the PR's stated 'bounded retries' contract
needs but lacked: gives up after the 4-retry bound and rethrows the
original EBUSY (no infinite loop, no masking), skips non-transient
codes, and never retries off Windows. Also adds the missing final
newline biome required on the new test file.

Addresses review feedback on #2382.
2026-06-14 17:27:15 +02:00
oldschoola 0d83a0fabc fix(utils): drop sleepSync type assertion; add EBUSY retry tests 2026-06-14 17:23:06 +02:00
can1357 b830f7912b feat: unified speech setup and introduced local STT/TTS capabilities
- Added unified `omp setup speech` flow with JSON/check modes and model picker.
- Added local STT pipeline with sherpa workers, recorder/download flow, and streaming inference.
- Added local TTS pipeline with `omp say`, backend selection, and streaming vocalization.
- Replaced legacy speech settings with unified `speech`/`speechgen` configuration keys.
2026-06-14 16:07:44 +02:00
metaphorics 2b126ffb80 feat(tui): add event-loop watchdog and phase breadcrumbs for stall diagnosis
Always-on LoopWatchdog (armed in TUI.start/stop) logs ui.loop-blocked with blockedMs and the current loop phase on the rising edge of a late probe tick. New pushLoopPhase/popLoopPhase/currentLoopPhase stack in pi-utils feeds it; breadcrumbs at in-process subagent dispatch (subagent:<id>) and the SelectList fuzzy filter (ui.select-filter) attribute residual main-thread stalls.
2026-06-14 08:23:05 +09:00
can1357 b75c7dd5f2 fix(utils): added abort propagation to createAbortableStream
- Reworked createAbortableStream to forward abort signals to the source stream reader.
- Added cleanup logic so abort/cancel/error paths release locks and emit AbortError consistently.
- Updated related tests to verify source-stream cancellation and handoff escape-handler behavior.
2026-06-13 17:56:02 +02:00
HugoAir Dev 798e28ff07 test: exercise public mermaid renderer 2026-06-13 18:33:50 +09:00
HugoAir Dev 46c68570e4 test: cover mermaid emoji label collision 2026-06-13 18:17:53 +09:00
can1357 961e7c10d3 feat(utils): added isMacosMallocStackLoggingEnvName() function
- Added isMacosMallocStackLoggingEnvName() function to identify MallocStackLogging and MallocStackLoggingNoCompact variables. Updated filterProcessEnv() and Bun.env initialization to skip these variables during environment filtering. Added test case to verify malloc stack logging toggles are dropped instead of forwarded.
2026-06-12 15:46:52 +02:00
can1357 9845ba1861 feat(deps): enabled fastembed and onnxruntime peers to install on demand
- Moved `fastembed` and `onnxruntime-node` to optional peerDependencies.
- Fixed bundled installs that could not resolve `onnxruntime_binding.node`.
- Added shared `runtime-install` utilities for on-demand module resolution.
- Added tests for runtime-resolution parsing and exact peer-version checks.
2026-06-12 14:18:58 +02:00
roboomp 2f4ba21a62 fix(lsp): resolved per-file format options from editorconfig and content
The format-on-write path sent a hardcoded {tabSize:3, insertSpaces:true}
on every textDocument/formatting request from two duplicated DEFAULT_FORMAT_OPTIONS
constants. Servers that honour tabSize for re-indent (yaml-language-server, the
common YAML/Kustomize/Flux case) reserialized 2-space files at a 3-space stride
on every write — exactly the corruption reported on Kubernetes/Flux YAML repos.

Replace both constants with a single resolveFormatOptions(filePath, content)
helper that layers, in order:
- .editorconfig (indent_style, indent_size, tab_width) via the new
  getEditorConfigFormatting() helper in pi-utils — strict, no fallback.
- Indent sniffed from the in-memory content the agent is about to write
  (first indented line decides spaces vs tabs; GCD of space-indent widths
  fixes the unit).
- Hardcoded 2-space fallback. The previous 3-space stride was an unusual
  default that actively damaged every file with a 2/4-space convention.

Tests cover the editorconfig and content-sniffing paths plus a direct
regression check that 2-space YAML stays 2-space (the issue's repro).

Fixes #2329
2026-06-11 21:03:49 +02:00
can1357 86195d6944 refactor(cross-cutting): moved grouped path-tree helpers into pi-utils 2026-06-10 23:13:39 +02:00
can1357 08a941a14e feat: added standalone snapcompact package and model-specific frame shaping
- Added a new @oh-my-pi/snapcompact package and redirected compaction call sites to it.
- Added provider-aware snapcompact shape resolution for model-specific mixed-frame behavior.
- Added optional image detail support by extending ImageContent and passing hints through OpenAI providers.
- Added native snapcompact render options, including 5x8/8x8 font loading and palette/geometry controls.
2026-06-10 21:50:03 +02:00
can1357 1c885471bc fix(utils): unescaped \n/\t in {{join}} prompt helper separator 2026-06-10 17:40:50 +02:00
can1357 f2137becb8 fix: fixed prompt parsing, startup tracing, and help-command behavior
- Fixed help rendering so `--help` no longer triggers unrelated command loaders.
- Fixed startup span logging to emit markers only with PI_DEBUG_STARTUP set.
- Fixed logger startup trace behavior for `:start`, `:done`, and `:fail` phases.
- Fixed prompt template processing with cached raw-template compilation and safer formatting.
- Optimized symbol and tag parsing in prompt templates via manual parsers.
2026-06-10 02:17:35 +02:00
can1357 622036cad8 perf(utils): simplified snowflake packing to single 64-bit BigInt
- Packed id via one BigInt hex format instead of four 16-bit segments (~1.7x faster).
- Extracted timestamp via exact double arithmetic, dropping BigInt round-trip.
- Lazily initialized the default source.
- Added round-trip and ordering tests across packing boundaries.
2026-06-10 02:09:29 +02:00
can1357 9d457f73d9 test: migrated test imports to package subpath exports
- Replaced relative `../src` imports with `@oh-my-pi/pi-ai` and `@oh-my-pi/pi-agent-core` subpaths.
2026-06-08 19:03:55 +02:00
can1357 52b3d90400 Merge remote-tracking branch 'origin/farm/87e6f6ee/fix-edit-renderer-enametoolong' 2026-06-04 18:35:39 +02:00
roboomp 9e3173da4e fix(utils): normalized paths before indentation length guard
- Moved the overlong-component guard to run after resolveFilePath so syntactically noisy but valid paths like long/../src/file.ts still honor editorconfig rules.
- Added a regression test that proves normalized paths with an eliminated overlong component resolve the configured tab width.

Fixes #1872
2026-06-04 16:32:02 +00:00
can1357 0ddc5b3804 Merge remote-tracking branch 'origin/farm/87e6f6ee/fix-edit-renderer-enametoolong' into main2 2026-06-04 18:31:05 +02:00
roboomp a27e0add5f fix(utils): made editorconfig discovery resilient to malformed paths
- Tightened parseCachedEditorConfig to absorb any FsError, not just
  ENOENT. Editorconfig lookup is best-effort indentation hinting; an
  unreadable .editorconfig (ENAMETOOLONG, ENOTDIR, EACCES, ELOOP,
  EINVAL, …) means "no usable config here", not a fatal condition for
  callers like the edit renderer.
- Added a path-component length gate (NAME_MAX = 255 bytes) in
  getIndentation that short-circuits to the default tab width before
  any syscall. Renderers can hand arbitrary strings into replaceTabs
  (e.g. a malformed edit tool call whose file_path is gibberish);
  attempting to open <dir>/.editorconfig for a 500-byte component
  would otherwise crash the TUI with an uncaught ENAMETOOLONG.
- Added regression tests covering both safety nets.

Fixes #1872
2026-06-04 16:27:55 +00:00
roboomp 72f41f333e fix(utils): swallow editorconfig probe errors to keep TUI rendering safe
parseCachedEditorConfig caught only ENOENT, so an oversized path segment
(e.g. a 2KiB garbage string emitted by a hallucinating model) blew up
the renderer with an uncaught ENAMETOOLONG from fs.readFileSync. The
editorconfig probe is best-effort — there is no useful difference
between 'file missing' and 'open() refused for any other reason' from
the renderer's perspective. Catch every error, cache the miss so we do
not re-probe the same bogus path on every redraw, and add a regression
test that exercises the 2KiB-segment path through getIndentation.

Fixes #1871
2026-06-04 16:24:59 +00:00
Can Bölük a6997b1b7f Merge branch 'main' into fix/session-accent-light-contrast 2026-06-04 06:28:21 +03:00
can1357 1379772628 refactor(utils): consolidate color utilities into pi-utils
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.
2026-06-04 05:27:11 +02:00
can1357 5e17edf1ec refactor(coding-agent): restructured session text slicing to use unified head/tail reads
- Replaced SessionStorage readTextPrefix/readTextSuffix with readTextSlices.
- Added peekFileEnds utility to read bounded file head/tail in one handle.
- Updated session-manager list/recent reads to consume unified head/tail slices.
- Expanded storage tests for head/tail and UTF-8-boundary slice extraction.
2026-06-04 02:07:34 +02:00
can1357 e6716d086d feat(coding-agent): added lifecycle status to session picker
- 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.
2026-06-04 01:58:25 +02:00
can1357 8a32eceb53 fix(utils): clamped usage durations to suppress stale negative reset countdowns
- 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.
2026-05-26 20:22:25 +02:00
can1357 82b3a83dd7 fix(utils): improved logger error serialization and transient error detection
- 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.
2026-05-26 08:07:08 +02:00
can1357 83b69ead9f test(ai): fixed SSE test structure and added keepalive parsing coverage
- Restructured the auth-broker `openSnapshotStream` tests to be top-level cases under the describe suite.
- Added a stream parser test asserting pure ": keepalive" lines are not included in subsequent SSE event raw output.
2026-05-25 20:29:30 +02:00
can1357 4b6be0b0df fix(utils): preserve Windows env names with parentheses
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.
2026-05-17 13:43:00 +02:00
Vilmos Nebehaj 98405e16de fix(utils): ignore unsafe dotenv entries 2026-05-17 13:43:00 +02:00
can1357 cd981ae0e6 feat(utils): install ID generation 2026-05-17 01:31:16 +02:00
can1357 39f34ada70 feat: added pure-JS sanitizeText
- Migrated sanitizeText from pi-natives to pi-utils as a pure-JS implementation, removing the native dependency across all call sites.
2026-05-16 20:12:26 +02:00
can1357 1b47cd3042 feat(ai): fetch overrides
- 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.
2026-05-15 09:16:38 +02:00
can1357 975941aba4 chore: remove garbage tests 2026-05-12 04:09:33 +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 9672139228 feat: added shared readSseEvents utility for Anthropic SSE parsing
- 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.
2026-05-07 00:08:06 +02:00
can1357 3f40cb0570 fix(coding-agent): isolate python gateway state 2026-05-06 18:14:00 +02:00
can1357 ba2affae7f fix(coding-agent): restore path alias equivalence
Fixes #935
2026-05-06 17:23:33 +02:00
can1357 a4c8586f82 fix(coding-agent): preserve junction project paths
Fixes #935
2026-05-06 17:13:11 +02:00
can1357 b60c0cc3ce refactor: migrated tab width resolution to pi-utils with EditorConfig caching
- Extracted tab width resolution from pi-natives to pi-utils with EditorConfig caching support.
- Made tabWidth parameter required in native text functions (visibleWidth, truncateToWidth, wrapTextWithAnsi, sliceWithWidth, extractSegments).
- Removed process-wide tab width state management from pi-natives text module.
- Consolidated wrapper node promotion logic in chunk classification with abbreviated string representations.
- Removed path-clean and pathdiff dependencies from pi-natives.
- Updated all consuming packages to import tab width functions from pi-utils and pass explicit tabWidth parameters.
2026-04-10 14:18:36 +02:00
can1357 3f4384f6b1 fix(auto-generated-guard): corrected file not found handling in marker detection
- Fixed file not found error handling in auto-generated marker detection to gracefully return undefined instead of propagating errors.
- Made assertEditableFileContent function synchronous to simplify API and improve error handling consistency.
- Updated test assertions to match synchronous function behavior using toThrow instead of rejects patterns.
- Removed obsolete test case for doc comment preservation during replace operations.
2026-04-08 15:06:47 +02:00
can1357 211e5369a0 refactor(coding-agent): migrated image utilities to shared pi-utils package
- Extracted image metadata detection and MIME type utilities to @oh-my-pi/pi-utils package for shared use across projects.
- Consolidated image-input.ts and mime.ts modules into image-loading.ts with simplified API removing redundant metadata parameters.
- Updated all import paths across coding-agent to use readImageMetadata from @oh-my-pi/pi-utils instead of local utilities.
- Added peek-file utility module to @oh-my-pi/pi-utils with buffer pooling for efficient file header reading.
2026-04-08 14:42:51 +02:00
can1357 9b78a6fa85 refactor(natives): migrated native bindings to NAPI-RS with auto-generated types
- Migrated native bindings from TypeScript wrappers to NAPI-RS generated modules with auto-generated type definitions and runtime enums.
- Replaced chunk tree API with stateful ChunkState class supporting render, edit, and resolve operations with improved error handling.
- Converted callback signatures to error-first pattern (error, result) for shell, PTY, glob, and grep operations.
- Introduced type-safe enums for MacOSAppearance, GrepOutputMode, KeyEventType, ImageFormat, and AstMatchStrictness replacing string literals.
- Refactored chunk tree implementation with dedicated modules for edit, indent, resolve, and state management with comprehensive validation.
- Moved clipboard utilities from native bindings to coding-agent package with improved OSC 52 and Termux compatibility.
2026-04-07 02:00:59 +02:00
can1357 4b60af5c47 feat(text-display): implemented configurable tab width
- Added a `display.tabWidth` setting to control default tab rendering.
- Integrated `.editorconfig` resolution for c ontext-aware tab indentation.
- Updated native text processing to use the resolved tab width for calculations.
- Improved tab visualization in diffs and other UI elements for consistency.
2026-02-23 15:00:06 +01:00
can1357 93e28a8029 refactor: consolidated timing instrumentation to centralized logger methods
- Migrated timing instrumentation from custom utils/timings module to centralized logger.time() and logger.timeAsync() methods across coding-agent and natives packages.
- Removed PI_DEBUG_STARTUP environment variable and debugStartup() function, consolidating debug output to logger.debug() for conditional logging.
- Replaced custom TextDecoder buffer decoding with native toString('utf-8') method in natives package for simplified string conversion.
- Added RingBuffer<T> circular buffer implementation to pi-utils with comprehensive test coverage for efficient queue operations.
- Enhanced logger interface with time() and timeAsync() methods providing unified operation timing and performance tracking across packages.
2026-02-21 22:42:18 +01:00
can1357 2e33e436b4 feat: switched to native text sanitization, removed Bun.stripANSI
- Added `sanitizeText` function to pi-natives that strips ANSI escape sequences, removes control characters and lone surrogates, and normalizes line endings.
- Moved `sanitizeText` function from `@oh-my-pi/pi-utils` to `@oh-my-pi/pi-natives` for better code organization and native performance.
- Added line length clamping (4000 characters) to bash and Python execution output to prevent excessively long lines.
- Replaced internal `#normalizeOutput` methods with `sanitizeText` utility function in bash and Python execution components.
- Fixed bash interactive tool to gracefully handle malformed output chunks by normalizing them with `sanitizeText`.
- Simplified documentation by removing WASM terminology from package descriptions and comments.
2026-02-14 03:25:13 +01:00
can1357 aa2c75d727 refactor(utils): simplified abort handling and stream parsing with inlined Promise.withResolvers and Uint8Array lookup
- Removed createAbortablePromise function and inlined Promise.withResolvers usage in untilAborted for simpler abort handling.
- Replaced Bitmap class with simpler Uint8Array lookup table for whitespace detection in SSE parsing.
- Fixed subarray calculation in ConcatSink.pullJSONL to use correct read offset instead of computed remainder.
- Simplified copyWithin call in ConcatSink.pullJSONL to use read offset directly.
- Changed String.replace with regex to replaceAll for carriage return removal in sanitizeText.
- Removed unused test utilities and test cases for TextDecoderStream.
2026-02-06 00:13:29 +01:00
can1357 0171cd7b75 refactor(utils): restructured stream utilities for improved reusability and correctness
- Extracted stream abort handling into dedicated `createAbortableStream` utility function for reuse across stream operations.
- Refactored `sanitizeBinaryOutput` to handle surrogate pairs correctly and filter additional control characters (DEL and C1 control block) with lazy array allocation.
- Simplified JSONL parsing by replacing manual buffer management with new `pullJSONL` generator method in ConcatSink class.
- Removed unused `createSanitizerStream` and `createTextDecoderStream` helper functions that are no longer needed.
- Refactored `readSseJson` to use generator-based line processing with fast-path optimization for OpenAI-style done markers.
- Updated stdio transport to use new `readJsonl` utility instead of manual JSON parsing with TextDecoder.
2026-02-05 23:39:05 +01:00