Commit Graph

841 Commits

Author SHA1 Message Date
YeonGyu-Kim 52ba1257b6 Merge branch 'fix/pre-publish-blockers-v4.5.0'
Pre-publish blockers for v4.5.0:
- fix(runtime-fallback): gate retryable signal on status-code allowlist (f05e0cbe9)
- fix(parent-wake): bound assistant-text defer to escape stuck sessions (69c955f61)
- fix(ralph-loop): time-bound oracle dispatch wait to prevent stall (14b3523af)
- test(dist-bundle): assert inlined prompt content survives bundling (3e0a975d1)
- fix(package): block internal-only assets from publish payload (8e28e29c2)

Verified via publish-debate-vortex hyperultradebate (6 hostile agents, 3 rounds).
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-05-26 16:44:50 +09:00
YeonGyu-Kim a5cee76961 fix(prompt-async-gate): retry object-form path on runtime type error (#4417)
Atlas task() with run_in_background=false crashed with 'The "path" property must be of type string, got object' from Node's path.isAbsolute validation upstream of the SDK.

All callers (sync-prompt-sender, boulder-continuation-injector, idle-event, session-route, model-suggestion-retry) already route through dispatchInternalPrompt, so centralizing the compatibility shim in prompt-async-gate.ts covers every Bug 1 site without touching individual hooks.

On TypeError matching the object-path signature, retry once with path collapsed to its id string. Types broaden PromptSessionPath to string | { id }.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-05-25 17:48:14 +09:00
YeonGyu-Kim 3e0a975d1f test(dist-bundle): assert inlined prompt content survives bundling
After the prompts-core migration the TypeScript prompt sources were
deleted; the only mechanism delivering markdown prompts to npm users
is bun build inlining via bunfig.toml [loader] ".md" = "text"
and import attributes. bun test runs from src/index.ts, not from
dist/index.js, so a future Bun upgrade that silently regresses
markdown inlining would pass source tests green while the published
bundle is broken with Cannot find module ../prompts/atlas/default.md
at first agent load.

Add a smoke test that scans the built dist/index.js for unique
signature strings from each migrated prompt file (15 signatures:
3 ultrawork + 5 atlas + 3 prometheus + 4 mode prompts). Skips
gracefully if dist/index.js does not exist (local bun test before
build). Wire into the existing CI Verify dist bundle tests step in
.github/workflows/ci.yml so the regression catches in CI build.

Closes pre-publish blocker V1 and V33.
2026-05-25 01:33:06 +09:00
YeonGyu-Kim 3d0b4c4aac fix(parent-wake): block unfinished assistant wakes 2026-05-24 19:02:13 +09:00
Yeachan-Heo 6c691a1afa fix(grep): probe OpenCode cache-backed bin for auto-downloaded rg (#3805)
Upstream OpenCode's Global.Path.bin resolves to ~/.cache/opencode/bin
(XDG cache), where its ripgrep auto-installer and many LSP servers land.
OMO's getOpenCodeBundledRg only checked the data-dir variant
(~/.local/share/opencode/bin), so when OpenCode had already downloaded
rg into its cache directory OMO would skip it and either redownload via
its own fallback installer or fall back to system grep.

Probe the cache-backed bin path first so OMO reuses tools OpenCode has
already installed.
2026-05-24 02:02:31 +09:00
YeonGyu-Kim f511b4bc15 Merge pull request #4263 from YOMXXX/fix/gpt-5-3-codex-migration
fix(migration): stop rewriting explicit gpt-5.3-codex to gpt-5.4 (#3777)
2026-05-23 01:54:10 +09:00
YeonGyu-Kim 9da3009574 Merge pull request #4279 from MoerAI/fix/migrate-orphan-lsp-config-key
fix(migration): drop orphan 'lsp' config key so users see LSP moved to .opencode/lsp.json (fixes #4225)
2026-05-23 01:53:24 +09:00
YeonGyu-Kim 6cac80fe87 Merge pull request #4290 from SpencerJung/fix/issue-4170-cjk-agent-header
fix(cli): preserve CJK agent header text
2026-05-23 01:51:18 +09:00
YeonGyu-Kim aded57ff1f fix(shared): harden ripgrep-cli, zip-extractor, binary-downloader subprocess paths
Same Web-Response-on-Node hazard existed in ripgrep auto-download flow,
zip extraction helpers, and binary downloader streams. Switch to the new
Node-safe reader and ensure no spawn path escapes as unhandledRejection.

Related to #3919.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-05-22 20:40:24 +09:00
YeonGyu-Kim 4ea7562f50 feat(shared): add Node-safe process stream reader and search output collector
Introduces:
- src/shared/process-stream-reader.ts: Buffer-concat stream reader compatible with both Bun and Node ChildProcess stdout (replaces Web Response API usage)
- src/tools/shared/search-process-output.ts: structured subprocess output collector with timeout, kill, and rejection cleanup
- bun-spawn-shim hardened: Node path forces windowsHide: true; spawn errors no longer escape as unhandledRejection

Foundation for #3919 fix.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-05-22 20:39:52 +09:00
MoerAI 6062df8262 fix(migration): make 'lsp' migration guidance self-contained and update stale docs (addresses codex P2 on #4279)
The migration log message previously pointed users to docs/reference/configuration.md for the new LSP config location, but that doc section still showed the obsolete plugin-level 'lsp' block. A user following the guidance would re-add the same 'lsp' key, see it stripped again on next startup, and never reach a usable config.\n\nFix both sides: rewrite the log message so it is self-contained (states the new path .opencode/lsp.json and the consumer directly) and rewrite the LSP section in docs/reference/configuration.md to describe the actual current architecture (LSP served by the 'lsp' MCP server, reading server map from .opencode/lsp.json via LSP_TOOLS_MCP_PROJECT_CONFIG, schema lives in packages/lsp-tools-mcp).\n\nVerification: bun test src/shared/migration/ -> 26/26 pass. bun run typecheck -> exit 0. Manual probe -> migration still strips lsp from both in-memory and persisted file.
2026-05-22 18:10:12 +09:00
SpencerJung ed4c04e575 fix(cli): preserve CJK agent header text
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-05-22 16:40:24 +09:00
MoerAI a7429cc223 fix(migration): drop orphan 'lsp' config key so users see LSP moved to .opencode/lsp.json (fixes #4225)
The lsp config block was removed from OhMyOpenCodeConfigSchema when LSP tools were migrated from native plugin tools to the lsp tier-1 MCP server (packages/lsp-tools-mcp). Zod v4 strips unknown keys silently on safeParse, so a v3-era oh-my-opencode.jsonc with 'lsp': { typescript: { command: ... } } continues to live in the file unchanged while doing absolutely nothing. The user reporting #4225 saw their custom LSP servers stop working with zero indication that the configuration site moved.\n\nAdd a migrator that removes the orphan lsp key during migrateConfigFile, mirroring the existing omo_agent -> sisyphus_agent migration immediately above and the 'Removed obsolete hooks from disabled_hooks' precedent below. A single log line records the configPath and the list of dropped server keys so the user has a paper trail in oh-my-opencode.log, and needsWrite is flipped so the cleanup persists to disk (with a timestamped backup) the next time the plugin loads.\n\nReproduction (clean upstream/dev, BEFORE fix):\n  needsWrite=false\n  inMemory.lsp=<original block, kept>\n  persisted.lsp=<original block, kept>\n\nVerification (AFTER fix):\n  needsWrite=true\n  inMemory.lsp=undefined\n  persisted.lsp=undefined\n\nbun test src/shared/migration/ -> 26/26 pass (24/24 pre-existing + 2 new regression tests). bun run typecheck -> exit 0.
2026-05-22 16:06:19 +09:00
李冠辰 d788c3d1a9 fix(migration): stop rewriting explicit gpt-5.3-codex to gpt-5.4 (#3777)
`openai/gpt-5.3-codex` is the codex-series powerhouse still recommended
in docs/guide/agent-model-matching.md and listed in the default
fallback chain in docs/reference/configuration.md, not a deprecated
alias for `gpt-5.4`. The migration entry silently rewrote any user
config that picked `gpt-5.3-codex` for its token efficiency, sending
agents to a non-codex model on every startup.

Drop the bogus mapping from MODEL_VERSION_MAP and add a regression
test that explicit `gpt-5.3-codex` selections (including in nested
fallback_models) survive `migrateModelVersions`. Users already
auto-migrated previously can revert to `gpt-5.3-codex` by hand and it
will now stick on subsequent loads regardless of the sidecar history.
2026-05-22 11:36:22 +08:00
YeonGyu-Kim 2e2e33cfc0 test: fix stale imports after prompt-async-gate and model-core refactors
- prompt-async-gate.test.ts: refactor ced36bffc removed
  promptAsyncAfterSessionIdle in favor of the unified
  dispatchInternalPrompt({ mode: 'async', ... }). One call site at
  line 1441 was left behind. Replace it with the current API and pass
  the explicit dispatchTimeoutMs so the status-timeout semantics are
  preserved. Also switch the surrounding tests to the third-argument
  timeout form so Bun's typings stay happy.
- runtime-model-readers.test.ts: implementation moved to
  packages/model-core during the layering refactor; the orphaned test
  still pointed at './runtime-model-readers'. Switch to the package
  export via getModelCapabilities and keep the modality-reader
  coverage by deriving keys through the package API.
2026-05-22 00:07:46 +09:00
YeonGyu-Kim 9624914c25 test(disabled-providers): drop logger mock to fix global mock-module leakage
mock.restore() in afterAll is global in Bun, so the previous attempt to
satisfy mock-module-lifecycle-audit by pairing mock.module('./logger')
with afterAll(() => mock.restore()) tore down mocks owned by other
tests. Concretely, running this file before src/hooks/runtime-fallback
produced 42 cascading fallback test failures.

The logger mock was decorative - tests do not assert log calls, and the
real logger only writes to oh-my-opencode.log in the OS temp dir. Drop
the mock entirely so the audit has nothing to score and other tests
keep their mocks intact.
2026-05-22 00:07:46 +09:00
YeonGyu-Kim bc0da0fad3 test: fix prometheus-prompt syntax + sync display name casing to lowercase
- prometheus-prompt.test.ts: close missing }) on the OpenSpec expanded
  commands describe block (introduced by d66b6bcbf, parse error).
- agent-sort-shim/agent-config-integration/continuation-injection/
  unstable-agent-babysitter/subagent-resolver/sync-executor/
  resolve-caller-team-lead tests: expect 'Sisyphus - ultraworker'
  (lowercase) to match production after cd39f8858, which lowercased the
  display name to dodge a TUI ZWSP rendering glitch. Legacy uppercase
  inputs that exercise the normalization path are preserved.
- sync-executor.ts + resolve-caller-team-lead.ts: route legacy display
  name inputs through normalizeAgentForPrompt so prompt agent names and
  caller team lead lookups produce the canonical lowercase form.
2026-05-22 00:07:46 +09:00
YeonGyu-Kim edaa95fec0 refactor(model-core): host snapshot fetcher, suggestion parser, and context-limit resolver
Move three pure helpers from src/shared/ into @oh-my-opencode/model-core so the package can stand alone without depending on plugin internals:

- buildModelCapabilitiesSnapshotFromModelsDev + fetchModelCapabilitiesSnapshot (models.dev normalization)
- parseModelSuggestion (cross-provider ProviderModelNotFoundError suggestion extraction)
- resolveActualContextLimit (Anthropic GA 1M context override)

Split provider-model-id-transform into two variants exposed by model-core:

- transformModelForProvider keeps the runtime dash to dot Anthropic rewrite used by the SDK
- transformModelForProviderDisplay preserves hyphenated Anthropic IDs so the installer writes registry-compatible model strings, fixing the ProviderModelNotFoundError fresh installs hit when the dotted form leaks into the config

src/shared/* and src/cli/provider-model-id-transform.ts collapse to re-export shims that point at the new core modules. Stale src/shared/{known-variants,model-capability-aliases,model-capability-guardrails,model-capability-heuristics}.ts re-export files plus the duplicated context-limit-resolver test are removed in favor of the canonical model-core copies.

Tests: bun test packages/model-core src/shared/model-capabilities-cache.test.ts src/cli/provider-model-id-transform.test.ts
2026-05-21 16:19:38 +09:00
YeonGyu-Kim d78ebc1280 Merge pull request #3370 from Zireael/fix/git-bash-shell-detection-on-windows
fix: detect Git Bash/WSL/MSYS2 shell on Windows (non-interactive-env hook)
2026-05-21 12:58:48 +09:00
YeonGyu-Kim 6678c2ae04 Merge pull request #3884 from leeyazhou/i18n
feat(i18n): add toast i18n with en/zh locale and plugin config support
2026-05-21 12:58:45 +09:00
YeonGyu-Kim c5f8fd4060 Merge pull request #4031 from PeterPonyu/feat/config-disabled-providers
feat(config): add disabled_providers schema + helper
2026-05-21 12:58:42 +09:00
YeonGyu-Kim 9cca6848c9 Merge pull request #4081 from PeterPonyu/feat/4004-agent-display-name-i18n
feat(agents): support per-agent displayName for i18n (#4004)
2026-05-21 12:58:21 +09:00
YeonGyu-Kim ba5bc0ef4f Merge pull request #4092 from code-yeongyu/fix/status-timeout-hang
fix(shared): add timeout to isSessionActive to prevent infinite hang
2026-05-21 12:58:14 +09:00
YeonGyu-Kim bd61479315 Merge pull request #4227 from code-yeongyu/fix/post-4106-cleanup-20260521
fix: clean up post-4106 prompt gate artifacts
2026-05-21 12:53:17 +09:00
YeonGyu-Kim f6a2ff3541 test(coupling-audit): allowlist dual-runtime spawn shims 2026-05-21 12:50:10 +09:00
YeonGyu-Kim e15461febc refactor(model-core): inject bundled capabilities snapshot from harness
- remove bundled snapshot dependency on src/generated in model-core

- make shared harness provide runtime bundled snapshot

- update guardrail and capability tests to pass explicit snapshot

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-05-21 12:50:10 +09:00
YeonGyu-Kim 2462d7af29 refactor(model-core): remove src back-imports via core utilities and adapter
- move fuzzyMatchModel and transformModelForProvider into model-core

- replace connected-providers re-export with adapter contract

- route shared wrappers through model-core exports

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-05-21 12:50:10 +09:00
YeonGyu-Kim 819bf0d11f chore: update meta-audits + add opencode coupling grep gate 2026-05-21 12:50:10 +09:00
YeonGyu-Kim 2748009ff2 refactor(packages): extract model-core package 2026-05-21 12:49:50 +09:00
YeonGyu-Kim a5c1d71001 refactor(packages): extract utils package 2026-05-21 12:48:43 +09:00
YeonGyu-Kim ced36bffc1 refactor: split prompt async gate modules
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-05-21 12:00:01 +09:00
YeonGyu-Kim db4c9f49e3 Merge pull request #3316 from ahuangsnail/fix/max-output-tokens-zero-fallback
fix: treat zero limit.output as unknown to enable fallback to bundled…
2026-05-21 00:59:05 +09:00
YeonGyu-Kim d0719ff7b7 Merge pull request #3875 from jollyxenon/fix/3846-opencode-config-dir-additive
fix(config): align OPENCODE_CONFIG_DIR with additive OpenCode semantics
2026-05-21 00:48:00 +09:00
YeonGyu-Kim b18963b0a9 Merge pull request #3868 from MoerAI/fix/openai-server-error-retryable
fix(model-error-classifier): mark OpenAI server_error patterns as retryable (fixes #3799)
2026-05-21 00:46:16 +09:00
YeonGyu-Kim 7651c856aa Merge pull request #3944 from survivor998/fix/ultraworker-display-name-zwsp
fix(display): lowercase ultraworker to avoid ZWSP rendering glitch
2026-05-21 00:45:07 +09:00
YeonGyu-Kim aa3187bfbb Merge pull request #4180 from JacobZyy/fix/plugin-hooks-merge 2026-05-21 00:14:58 +09:00
YeonGyu-Kim 12ed091e93 Merge pull request #4101 from sjawhar/fix/modalities-object-shape
fix(model-capabilities): handle object-shaped modalities in readModalityKeys
2026-05-21 00:10:29 +09:00
JacobZyy 33f121b113 fix: add PATH to restricted hook env, protect HOME/CLAUDE_PROJECT_DIR from allowlist override, reset plugin hooks state in tests
- P1: When allowedEnvVars is provided, PATH was missing from the base
  restricted env, causing non-builtin commands to fail at exec time
- P2: Allowlisted HOME/CLAUDE_PROJECT_DIR could overwrite normalized
  values from getHomeDirectory()/cwd with ambient process.env values
- P2: Test suite mutated shared pluginHooksState singleton without
  resetting it in afterEach, causing cross-test state leaks
2026-05-20 22:49:05 +08:00
YeonGyu-Kim 791825fc20 Merge pull request #4153 from MoerAI/fix/fallback-model-string-guard
fix(shared,delegate-task,claude-code-agent-loader): guard model parsers against non-string input (fixes #4145)
2026-05-20 23:40:33 +09:00
JacobZyy 0a20844bd4 fix: address PR #4180 review - security, typing, and test coverage
- Apply mcp_env_allowlist to plugin hooks: intersect HTTP allowedEnvVars
  with MCP allowlist, set command allowedEnvVars to full MCP allowlist
- Scrub process.env in executeHookCommand when allowedEnvVars provided
- Add PluginHooksState class with per-directory Map storage
- Add PluginHooksConfig interface for typed boundary layer
- Pass directory context through hook-config-handler
- Add 16 tests across 4 files (40 assertions) covering allowlist
  filtering, env scrubbing, directory isolation, and edge cases
- Remove unnecessary 'as' type assertions, use discriminated union
  narrowing instead
2026-05-20 22:30:25 +08:00
YeonGyu-Kim 32f0e1e0af Merge pull request #4186 from lang-911/feat/grok-reasoning-effort
fix(model-heuristics): register Grok family so reasoningEffort survives on @ai-sdk/openai
2026-05-20 22:05:22 +09:00
MoerAI c85d2f9bc8 fix(model-error-classifier): mark OpenAI server_error patterns as retryable (fixes #3799)
OpenAI streaming responses can surface mid-stream errors with type
'server_error' or with the prose message 'An error occurred while processing
your request'. Neither matched any entry in RETRYABLE_MESSAGE_PATTERNS, so
shouldRetryError returned false and the runtime-fallback / fallback-retry
code paths skipped retry. The result was that GPT-5.5 subagent (and main)
turns silently stalled until the stale timeout fired.

The maintainer's diagnosis on issue #3799 explicitly recommends adding
these two patterns to model-error-classifier.ts; this commit does exactly
that and adds two regression tests covering the JSON envelope and the
prose form.
2026-05-20 19:11:54 +09:00
YeonGyu-Kim 330e437f08 docs(agents): regenerate hierarchical AGENTS.md for 2026-05-20
Sync the AGENTS.md hierarchy to current code state:

Drift fixes in 11 existing files
- Root: 2026-05-20 commit 39aadbf9f, ~2167 TS files, 120 barrel index.ts,
  57 src/hooks dirs, 297 (179 non-test) src/shared files, 11 OpenCode hook
  handlers in plugin-interface.ts, packages list adds ast-grep-mcp + rules-core,
  first-prompt-watchdog 206 LOC, parent-wake-notifier 587 LOC
- src/AGENTS.md: file counts, plugin-interface handler count
- src/shared/AGENTS.md: title + counts 278/170 -> 297/179
- src/hooks/AGENTS.md: 57 dirs, note unwired WIP (task-reminder,
  hashline-edit-diff-enhancer)
- src/features/AGENTS.md: module map with NON-TEST counts + sub-AGENTS.md
  column, 7 modules without sub-doc
- src/features/background-agent/AGENTS.md: add 12 newer files (parent-wake-
  notifier 587 LOC, loop-detector, error-classifier, fallback-retry-handler,
  process-cleanup, subagent-spawn-limits, session-status-classifier,
  compaction-aware-message-resolver, etc.)
- src/plugin/AGENTS.md: 11 handlers, add system-transform.ts + command-
  execute-before.ts + build-team-idle-wake-hint-client.ts
- src/config/AGENTS.md: note schema/internal/permission.ts
- src/cli/AGENTS.md: 8 commands including 'version'
- src/plugin-handlers/AGENTS.md, packages/web/AGENTS.md: date bump

New AGENTS.md in 4 directories
- packages/AGENTS.md: index of 15 packages (11 platform binaries + 2 MCP
  packages + rules-core + web), role map, conventions
- docs/AGENTS.md: WHERE TO LOOK table for 19 docs across 6 subdirs
- .opencode/AGENTS.md: 5 skills + 4 slash commands + relationship to .agents/
- .agents/AGENTS.md: superset migration target (9 skills + 4 commands)
2026-05-20 17:18:44 +09:00
YeonGyu-Kim f8f4b572dc fix(runtime-fallback,prompt-gate): recognize all OpenCode progress event shapes and boolean/completed finish markers
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-05-20 13:12:06 +09:00
YeonGyu-Kim d3e218f912 fix(prompt): treat post-dispatch failures as accepted 2026-05-20 11:42:32 +09:00
Sami Jawhar 94e71936fb fix(model-capabilities): handle object-shaped modalities in readModalityKeys 2026-05-19 12:24:59 +00:00
YeonGyu-Kim b2918fd4db fix(team-mode): close peer message delivery races 2026-05-19 19:18:13 +09:00
YeonGyu-Kim bcea4a9d28 fix(prompt-gate): harden sync and team prompt dispatch 2026-05-19 19:18:13 +09:00
YeonGyu-Kim 1492bffd20 fix(prompt-gate): harden internal prompt dispatch 2026-05-19 19:18:13 +09:00
lang-911 8b097f2c3b fix(model-heuristics): register Grok family with reasoningEffort support
Grok model IDs (e.g. `grok-4.3`, `grok-3-mini`) were missing from `HEURISTIC_MODEL_FAMILY_REGISTRY`, so `resolveCompatibleModelSettings` returned an "unknown family" result for them.

The `chat.params` hook treats unknown families as "no reasoning support" and deletes `output.options.reasoningEffort` before the request leaves the plugin, so users routing Grok via OpenAI-compatible endpoints never saw their reasoning effort forwarded — even with `forceReasoning: true`.

Add a `grok` family entry that includes any model ID containing "grok", exposes `low | medium | high` variants, and sets `reasoningEfforts` so the heuristic surfaces the same capability flag used by the `chat.params` hook. Extend the family table-driven test in `model-settings-compatibility.test.ts` to cover `grok-4.3`.
2026-05-19 02:44:38 -07:00