Resolve built-in local MCP runtime executables before handing command arrays to OpenCode so lsp and ast_grep do not depend on a bare node or bun lookup in the host PATH.
Keep source, dist, bootstrap, workspace-safety, and disabled_mcps behavior covered by focused tests and real OpenCode MCP status QA.
Plan: plans/fix-built-in-mcp-runtime-executables.md
Todo continuation could reinject with a lowercase built-in config key such as hephaestus when no registered alias was available. OpenCode prompt dispatch expects the prompt-facing agent name, so the continuation failed with an agent-not-found error.
Normalize the dispatch fallback through the existing prompt agent display-name resolver and pin the lowercase Hephaestus regression.
Gate idle ready notifications on the existing background-task continuation marker so cmux does not receive premature ready alerts while delegated work is still active.
Constraint: Reuse marker state from background task lifecycle without adding new notification config
Rejected: Patch cmux directly | notification readiness belongs upstream in OMO
Confidence: high
Scope-risk: narrow
- CHANGELOG: detail BUG-A/B (team-mode delivery), BUG-C/D
(runtime-fallback event/finish blind spots), BUG-E (parent-wake
same-source reservation), BUG-F (markerless workspace rules); the
packages/rules-core and packages/ast-grep-mcp extractions; the
prompt-async-gate hold default change; the new symlink-escape security
fix; the rules-core isolation note; and the v4.3.0 deferred items
(prompt-async-gate.ts split, @ast-grep/napi stale dep cleanup).
- README.ru.md: add the OmO logo block so the Russian README matches
README.md / README.ja.md / README.ko.md / README.zh-cn.md.
The hold default jumped 8x in v4.2.3 to absorb slower-provider
session.error arrivals before reservation release. Update the RFC code
block, the prose default callout, and the retry-latency note so the
documented default matches src/shared/prompt-async-gate.ts.
- Drop the back-import of src/shared/logger so @oh-my-opencode/rules-core
stays free of host-adapter dependencies (ROADMAP package layering
invariant). Expose setSisyphusRuleDeprecationLogger(logger) for hosts to
inject their own logger; default is a noop.
- Wire the host injection in src/hooks/rules-injector/rule-file-finder.ts
as a module-level side effect so existing behavior is preserved.
- Add realpath boundary check to findRuleFilesRecursive and
validFileRealPath. Project rule scanners now refuse entries whose
realpath escapes the rule-source root, closing the symlink-escape
vector where a malicious repo could point .github/copilot-instructions.md
(or any .omo/rules/* entry) at ~/.ssh/id_rsa and have the rule injector
pull the secret into model context.
Accept apply_patch edits from nested result/metadata file lists and from raw patchText args when OpenCode does not provide direct metadata.files.
Forward tool args through the after-hook pipeline so comment-checker can inspect raw apply_patch inputs while preserving existing write, edit, and multiedit routing.
Tests: bun test src/hooks/comment-checker/hook.apply-patch.test.ts src/hooks/comment-checker/hook.before-after.test.ts src/plugin/tool-execute-after.test.ts
Tests: bun test src/hooks/comment-checker
Tests: bun run typecheck
Tests: bun run build
PR #4202 introduced dynamic OG via app/opengraph-image.tsx + app/twitter-image.tsx
using next/og ImageResponse. Build succeeds, but deploy to Cloudflare Workers
fails:
✘ [ERROR] Unable to extract npm package name from
.open-next/server-functions/default/node_modules/next/dist/compiled/
@vercel/og/yoga.wasm?module
[plugin wrangler-module-collector]
##[error]The process '/home/runner/.bun/bin/bunx' failed with exit code 1
Root cause: wrangler-module-collector can't resolve @vercel/og's bundled
yoga.wasm import from the OpenNext server-functions output. Known regression
in @opennextjs/cloudflare interop with @vercel/og (related to issue #1163 +
PRs #1169/#1176 in opennextjs/opennextjs-cloudflare, plus newer bundling
discussion in #1221).
Fix: switch to Next.js file convention static OG images. Place
app/opengraph-image.png + app/twitter-image.png (the same 1200x630
PNG that was being rendered dynamically). Next.js auto-emits og:image +
twitter:image metadata pointing at these routes, with correct
og:image:width/height/type tags. No @vercel/og, no WASM, no edge runtime.
The static PNGs were generated from PR #4202's dynamic ImageResponse during
local QA - identical visual output: dark #0a0a0a background, cyan
#00d4ff brand wordmark, headline, install command pill, terminal cursor.
Build verified: /opengraph-image.png and /twitter-image.png now show as
static routes (0 B route handler size). First-load JS unchanged.
Future-revisit: re-enable dynamic OG when @opennextjs/cloudflare ships the
fixes from PRs #1169/#1176/#1221 stable for Next 15.x deploys.
LocalizedPageShell at app/_components/localized-page-shell.tsx:34
already renders <main className='flex-1'>{children}</main> as the
page landmark. The manifesto/page.tsx shell was wrapping that with
its own <main>, producing nested main landmarks (axe-core:
landmark-no-duplicate-main + landmark-main-is-top-level).
Switch outer wrapper to <div>; keep styling (bg-background,
text-foreground, min-h-screen, overflow-x-hidden) intact. The
inner <main> from the shell remains the canonical landmark.
Pre-existing on origin/dev (the pre-decomposition manifesto/page.tsx
also had a top-level <main>), surfaced by PR #4202 hands-on QA
via axe-core run on /ko/manifesto.
Get Started button previously linked to /docs (root), landing users on
Overview. Issue #3848 reporter and concurrent PR #3948 asked for a
deeper link straight to Installation.
lib/docs-sections.ts declares 'installation' as a stable section id
rendered via <section id={section.id}> in app/[locale]/docs/page.tsx,
so /docs#installation is a valid deep link.
This also supersedes the in-flight PR #3948 (which targets the
pre-decomposition landing-page.tsx).
The full Bun suite can remove the shared rules-injector storage directory between a parent-directory check and the file write. Save operations now create the directory immediately before writing and retry once if ENOENT still wins the race.
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
OpenCode now treats session.status idle as the durable completion boundary, but the plugin only dispatched the synthetic session.idle through the main hook chain. Idle-only side effects such as tmux forwarding and team member idle continuations were skipped.
Route synthetic idle through the same idle-only hook path used by real session.idle events and pin the behavior with a regression test.
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
e2e/responsive.spec.ts (new):
- 6 viewports: iPhone SE (375x667), iPhone 14 Pro (390x844),
iPad mini (768x1024), iPad Pro (1024x1366), laptop (1280x800),
desktop (1920x1080)
- 4 locales: en, ko, ja, zh
- 2 pages: landing /, manifesto /manifesto
- Checks: no horizontal scroll, no overflow-x, primary CTA visible,
hero headline visible, nav button hit target (44x44 mobile / 32x32
desktop)
48 tests total. All pass against current build.
/docs has pre-existing horizontal overflow at 1024px viewport
(fixed-width sidebar interacting with code blocks). Intentionally
out of scope for this PR — commented in the spec, tracked as
follow-up.