Commit Graph

1706 Commits

Author SHA1 Message Date
YeonGyu-Kim 733f141bb5 fix(thinking-blocks): preserve latest assistant thinking 2026-05-30 17:27:03 +09:00
YeonGyu-Kim 0a18ceee20 fix(todo): normalize continuation agent names 2026-05-28 18:14:30 +09:00
YeonGyu-Kim 8ca9b5acfe fix(todo): skip unsafe continuation tails 2026-05-28 18:14:22 +09:00
YeonGyu-Kim 4bb4acf09a fix(prompt-gate): fail closed on unsafe tails 2026-05-28 18:14:09 +09:00
YeonGyu-Kim 77a268f91e fix: skip claude hook injection for internal prompts 2026-05-27 14:17:46 +09:00
ToToKr eaa73e9d08 Merge pull request #4245 from MoerAI/fix/runtime-fallback-zai-limit-exhausted
fix(runtime-fallback): match ZAI 'Limit Exhausted' quota errors (fixes #4207)
2026-05-27 13:38:43 +09:00
YeonGyu-Kim 03396344f9 Merge pull request #4469 from SoShymKing/add-support-tool-result
Add support for OpenCode 1.15 DB
2026-05-26 18:45:21 +09:00
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 ec552bcf34 fix(ralph-loop): stop loop when latest assistant turn made no model progress
Add no-progress turn detector that inspects the most recent assistant
message: if finish is 'unknown', all token counts are zero, and there
is no meaningful content beyond step-start/step-finish markers, the
turn is classified as no-progress.

Integrate the check at all three idle/completion/error continuation
points in the event handler so the loop stops cleanly with a warning
toast instead of injecting another internal prompt.
2026-05-26 14:28:35 +09:00
YeonGyu-Kim e443e86d61 fix(thinking-block-validator): avoid duplicate thinking prepends
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-05-26 01:29:23 +09:00
YeonGyu-Kim 58025f9ba4 fix(team-mode): wake leaders on unread mailbox messages (#4464)
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-05-26 00:59:38 +09:00
soshymking aa97341cc9 Add support for OpenCode 1.15 DB 2026-05-25 20:12:22 +09:00
YeonGyu-Kim 28efc4e81f fix(continuation): resolve registered agent name before dispatching prompt (#4417)
/start-work was unresponsive under Atlas because ralph-loop and todo-continuation-enforcer normalized the inherited agent to a config key (e.g. 'atlas') while OpenCode only accepts the registered display name (e.g. 'Atlas (Plan Executor)'), producing 'Agent not found' on dispatch.

Prefer resolveRegisteredAgentName(agent) and fall back to normalizeAgentForPromptKey only when no registration exists, mirroring the start-work hook's resolution chain.

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

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-05-25 17:48:32 +09:00
YeonGyu-Kim 14b3523af6 fix(ralph-loop): time-bound oracle dispatch wait to prevent stall
The double-fire race fix (#4256) had handlePendingVerification return
early when verification_attempt_id was set but verification_session_id
was not, since the oracle dispatch is still in flight. That guard
introduced a permanent-stall failure mode: if tool-execute-after never
runs (oracle session hangs, crashes, OOM-killed, or tmux killed
externally), verification_session_id stays undefined forever and the
ralph-loop never escapes the pending-verification state.

Track verification_attempt_started_at as a state field, clear it on
restart/clear/setVerificationSessionID, and fall through to
handleFailedVerification when the attempt has been pending past
STUCK_VERIFICATION_TIMEOUT_MS (30 minutes). Legacy persisted states
without the timestamp continue to defer (no timeout to evaluate),
matching pre-fix behavior for that edge case.

Closes pre-publish blocker V25.
2026-05-25 01:32:49 +09:00
YeonGyu-Kim f05e0cbe99 fix(runtime-fallback): gate retryable signal on status-code allowlist
extractRetryableSignal returns the raw isRetryable hint from up to 5
nested AI SDK error paths. isRetryableError previously trusted any
true result blindly, which would burn every configured fallback model
in an infinite loop if a provider mis-tagged a 401, 403, or other
non-transient 4xx as retryable.

Honor the signal only when the status code is absent, in the configured
retry_on_errors list, in 5xx, or in {408, 425, 429}. Reject the signal
when the status code is a non-transient 4xx and log the rejection so
operators can debug provider mis-classifications.

Closes pre-publish blocker V8.
2026-05-25 01:32:23 +09:00
YeonGyu-Kim 222adeb606 fix(runtime-fallback): honor retryable signal 2026-05-25 00:03:29 +09:00
YeonGyu-Kim d18cadb1ab test(ultrawork): add byte-exact characterization test
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-05-24 19:16:03 +09:00
YeonGyu-Kim 9d204250ee docs(keyword-detector): rewrite AGENTS.md for prompts-core migration
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-05-24 19:16:02 +09:00
YeonGyu-Kim 803f030b5b Merge remote-tracking branch 'origin/dev' into refactor/mode-prompts-to-prompts-core
# Conflicts:
#	packages/prompts-core/src/index.ts
2026-05-24 18:35:36 +09:00
YeonGyu-Kim 2c8e2dac41 refactor(mode-prompts): migrate hyperplan prompt
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-05-24 18:32:45 +09:00
YeonGyu-Kim e79baf5910 refactor(mode-prompts): migrate team prompt
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-05-24 18:32:35 +09:00
YeonGyu-Kim 3b7f51d568 refactor(mode-prompts): migrate analyze prompt
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-05-24 18:32:19 +09:00
YeonGyu-Kim 5cefbdbb6d refactor(mode-prompts): migrate search prompt
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-05-24 18:31:17 +09:00
YeonGyu-Kim c187dba56b test(keyword-detector): capture mode prompt baselines
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-05-24 18:30:53 +09:00
YeonGyu-Kim e772c46819 refactor(ultrawork): move planner prompt to prompts-core
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-05-24 18:20:18 +09:00
YeonGyu-Kim e51acd0ad3 refactor(ultrawork): move gemini prompt to prompts-core
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-05-24 18:20:11 +09:00
YeonGyu-Kim a818bbd99c refactor(ultrawork): move gpt prompt to prompts-core
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-05-24 18:20:04 +09:00
YeonGyu-Kim 9c366cce3a refactor(ultrawork): move default prompt to prompts-core
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-05-24 18:19:56 +09:00
YeonGyu-Kim e1e9f348f0 Merge pull request #4382 from code-yeongyu/feat/ultrawork-prompt-tdd-evidence-tightening
feat(ultrawork): enforce TDD, scenario contract, durable notepad, reviewer gate
2026-05-24 15:55:43 +09:00
YeonGyu-Kim d073bf1bdf feat(ultrawork): enforce TDD, scenario contract, durable notepad, reviewer gate
Closes five gaps in the ultrawork prompt versus codex-plugins' parallel
directive, applied to all three model variants (default/Claude, GPT, Gemini)
with prompt-engineering entropy gate (each addition encodes a distinct
binding boolean, not narrative reinforcement):

1. TDD-MANDATORY (was conditional "when test infrastructure exists"):
   every production change follows RED -> GREEN -> SURFACE. Failing test
   first, capture assertion msg, smallest change to flip green, exercise
   real surface, capture artifact. Exemption whitelist: formatting /
   comment-only / version bump / rename-only, each must be justified
   in writing; unjustified exemption = rejection.

2. Scenario contract (was free-form Test Plan Template): require 3+
   scenarios upfront covering happy path, edge (boundary / empty /
   malformed / concurrent), adjacent-surface regression. Each scenario
   binds a binary pass condition, a real-surface artifact source, and
   a test file + test id written test-first.

3. RED->GREEN evidence capture (was "all tests pass"): every scenario
   requires TWO captured artifacts -- RED assertion msg before the
   change AND GREEN assertion msg after -- alongside the real-surface
   artifact (tmux / curl / browser / Playwright / computer-use /
   CLI stdout / parsed config / DB diff). Tests are the floor (always
   required); surface artifact is the ceiling (also required).

4. Durable notepad: mktemp -t ulw-*.md with append-only sections
   (Plan, Scenarios, Now, Todo, Findings, Learnings). Survives context
   loss; resume by re-reading.

5. Reviewer gate: trigger when user said strictly / rigorously /
   "deeply", or task touches 3+ files / 20+ turns / 30+ min, or it is
   refactor / migration / perf / security work. Reviewer verdict is
   binding ("looks good but..." = rejection). Loop until unconditional
   approval.

Plus: TODO format upgraded from vague "track every step" to atomic
`path: <action> for <scenario-id> -- verify by <check>` with a GOOD
test-first / impl pair example and a BAD list including
"production code before its failing test".

Per-variant adaptation:
- default.ts (Claude): full structured sections.
- gpt.ts (GPT-5.x): outcome-first prose, shorter prose per gpt-5.5 guide.
- gemini.ts: explicit enforcement framing + anti-optimism checkpoint
  upgraded with a TDD-violation question (#7).

Verified by:
- bun test src/hooks/keyword-detector/ (119 pass / 0 fail).
- lsp_diagnostics clean on all three files.
- Module-load smoke test confirms each exported message string parses
  and contains the new section anchors (TDD MANDATORY, SCENARIO
  CONTRACT, DURABLE NOTEPAD, REVIEWER GATE).

Char deltas (directive body only):
- default 13646 -> 17144 (+26%)
- gpt     6740  -> 9215  (+37%, was the leanest start)
- gemini  14196 -> 16136 (+14%)

Existing tests only assert presence of "ULTRAWORK MODE ENABLED!" which
is preserved verbatim in every variant.
2026-05-24 15:48:59 +09:00
YeonGyu-Kim 39a549a3df Merge pull request #4381 from code-yeongyu/fix/team-mode-closure-prompts
fix(team-mode): make lead close teams on its own initiative
2026-05-24 15:37:28 +09:00
YeonGyu-Kim 5f1fb0c52a fix(team-mode): make lead close teams on its own initiative
The lead currently leaves teams alive after the task list drains because
none of the prompt surfaces tell it WHEN to close or HOW. omx-style
'self-closing' behavior was missing for four reasons (diagnosed via
prompt-engineering A/B/C: wrong / misframed / missing):

1. builtin team-mode skill 'Lifecycle' (B+C): 'phase ends / shape
   outgrown' is qualitative, so the model maps it to 'wait for user'.
   Step 6 jumped to team_delete without the request/approve pair the
   tool contract requires. Replaced with a 'Closure Contract' (a
   computable predicate over team_task_list + team_status) and an
   explicit 'Closure Sequence' (request -> approve -> delete, with
   force=true reserved for unrecoverable paths only).

2. TEAM_MESSAGE keyword injection (C): spent 100%% of its one-shot
   budget on routing ('do not substitute delegate_task'), 0%% on
   closure. Added the same closure rule in compressed form. Kept the
   'NEVER substitute with delegate_task' literal that
   keyword-detector/index.test.ts depends on.

3. team-mode-status-injector body (C): the only per-session injection
   for team mode had no closure obligation. Replaced the optional
   'load the team-mode skill ... otherwise use the team_* tools'
   sentence with a 'Closure invariant' clause that ties the check to
   every team_task_update.

4. member-guidance Wrap-up (A+B): step 3 said 'so the lead can decide
   whether to request shutdown', but team_shutdown_request is
   lead-only - members cannot initiate it. Step ordering also placed
   the completion message before team_task_update, so the lead's
   closable check would see stale data. Reordered to
   task_update -> check task_list for new work -> if nothing left,
   send a single 'closure-ready' message and idle. Test assertion
   updated to match the new accurate contract.

Also: stripped Korean alternation from TEAM_PATTERN per directive
('절대로 코드 내에 한국어 적지 마라'). Pattern is now
/\\bteam[\\s_-]?mode\\b/i. Removed 4 Korean test cases
(2 positive triggers + 2 false-positive guards) that the pattern no
longer needs to defend, and updated the keyword-detector AGENTS.md
row.

Net: -71 lines across prompt surfaces. The Closure Contract is the
only addition; everything else tightened.

Tests: 428/428 pass across src/features/team-mode/,
src/features/builtin-skills/, src/hooks/keyword-detector/,
src/hooks/team-mode-status-injector/, src/hooks/team-mailbox-injector/,
src/hooks/team-tool-gating/, src/hooks/team-session-events/.
LSP: no errors introduced (one pre-existing error in
keyword-detector/index.test.ts confirmed pre-existing on dev).
2026-05-24 15:21:24 +09:00
YeonGyu-Kim 9a1dd75608 fix(ralph-loop): skip handleFailedVerification when oracle dispatch is in flight (#4256)
When verification_pending is true and the agent has dispatched an Oracle
verification (verification_attempt_id is set), session.idle events that
arrive before tool-execute-after stores the Oracle session ID
(verification_session_id still undefined) caused handlePendingVerification
to fall through to handleFailedVerification. This injected a duplicate
'verification failed' continuation prompt, spawning a second Oracle.

The fix adds a guard in handlePendingVerification: when
verification_attempt_id is set but verification_session_id is not, Oracle
dispatch is in flight and the handler returns early instead of declaring
failure. The pending wake will retry on the next session.idle.

Regression test added in given/when/then style proving the race sequence:
  1. ULW loop detects DONE, enters verification_pending
  2. Oracle dispatch stamps verification_attempt_id (tool-execute-before)
  3. Second session.idle fires before tool-execute-after stores session ID
  4. Handler must NOT call handleFailedVerification

RED (before fix): 2 prompt injections (duplicate Oracle)
GREEN (after fix): 1 prompt injection (correct)

Fixes #4256
Fixes #4019
2026-05-24 15:00:26 +09:00
YeonGyu-Kim 74db81dfeb Merge pull request #4285 from SpencerJung/fix/issue-4123-tool-pair-retrigger
fix(tool-pair-validator): continue after synthetic repairs
2026-05-23 01:51:37 +09:00
YeonGyu-Kim 12d7d1045b Merge pull request #4282 from SpencerJung/fix/issue-4149-terminal-continuation-guard
fix(atlas): honor stopped continuation after boulder completion
2026-05-23 01:51:01 +09:00
YeonGyu-Kim e7120f6ad4 Merge pull request #4295 from vanhci/fix/issue-4292-comment-checker-deadloop
fix(comment-checker): skip modified-existing comments and dedupe per-session (issue #4292)
2026-05-22 22:04:58 +09:00
YeonGyu-Kim bc8c462d28 fix(session-notification-sender): guard ctx.$ with execFile fallback for Desktop sidecar (#4128, #4061)
OpenCode Desktop's Electron sidecar runtime can omit Bun's ctx.$ helper.
The sender previously called ctx.$ unconditionally, throwing
TypeError: ctx.$ is not a function as unhandledRejection and crashing
the sidecar with exit code 1.

Add a runtime guard at every call site, falling back to Node.js
child_process.execFile (with windowsHide: true) when ctx.$ is missing.
The Bun ctx.$ path remains preferred when available. Every notification
path is wrapped in try/catch so no failure escapes as unhandledRejection.

Fixes #4128
Fixes #4061
2026-05-22 20:39:33 +09:00
Vanhci 4cf391b7ff fix(comment-checker): skip modified-existing comments and dedupe per-session (issue #4292)
Issue 1: hasNewCommentsOnly() now returns false when oldString and newString
both contain comment syntax and the new lines are a subset of old lines —
preventing the hook from firing on comment-only modifications.

Issue 2: Per-session deduplication via sessionLastWarning Map with a 30s
window (DEDUP_WINDOW_MS). At most one warning fires per session per
response turn, breaking the deadloop on consecutive edits.
2026-05-22 16:06:09 +08:00
SpencerJung 28569307eb fix(tool-pair-validator): continue after synthetic repairs
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-05-22 16:36:12 +09:00
SpencerJung 7dae2711fc fix(atlas): honor stopped continuation after boulder completion
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-05-22 16:20:39 +09:00
YeonGyu-Kim 7cce0ad230 fix(notepad-guard,start-work): wire dispatch and match .omo paths
notepad-write-guard:
- The hook was created by create-tool-guard-hooks but tool-execute-before
  never invoked it, so the guard was inert.
- It also only matched .sisyphus/notepads, missing the current
  .omo/notepads layout introduced by the workspace migration.
- Add the dispatch call alongside writeExistingFileGuard, and extend
  NOTEPAD_ROOTS to cover both paths via normalize() + sep. New
  integration test pins the wire and the .omo block; the existing unit
  test now asserts both paths.

start-work session-plan-affinity:
- PLAN_PATH_PATTERN only matched .sisyphus/plans, so sessions referring
  to plans under .omo/plans returned null and start-work missed the
  current session's own plan.
- Extend the regex to .(sisyphus|omo)/plans and add findPrometheusPlans
  in packages/boulder-state to scan both directories during the
  transition. New regression test pins .omo/plans matching; legacy
  .sisyphus/plans coverage preserved.
2026-05-22 00:07:46 +09: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 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
MoerAI 3513c45a02 fix(runtime-fallback): match ZAI 'Limit Exhausted' quota errors (fixes #4207)
The ZAI (Zhipu) provider emits 'Weekly/Monthly Limit Exhausted. Your limit will reset at YYYY-MM-DD HH:MM:SS' when the coding-plan subscription quota is hit. None of the existing quota regex patterns (/quota.?exceeded/, /usage\s+limit/, /exhausted\s+your\s+capacity/, /credit\s+balance.*too\s+low/, etc.) match the 'Limit Exhausted' phrasing, so the runtime-fallback never fires and the user is stuck on the dead model.

Add /limit\s+exhausted/i to both pattern lists that gate fallback dispatch:
- RETRYABLE_ERROR_PATTERNS in constants.ts (text-pattern path used by extractStatusCode + retryable scan)
- classifyErrorType quota_exceeded branch in error-classifier.ts (typed classification path used by isRetryableError)

The pattern is intentionally narrow: it requires the literal token 'Limit' followed by whitespace then 'Exhausted'. It matches the ZAI weekly, monthly, and combined Weekly/Monthly variants but does not collide with unrelated phrases such as 'context limit' or 'rate limit' that already have their own dedicated patterns.

Regression coverage added to quota-error-classifier.regression.test.ts:
- 'Weekly/Monthly Limit Exhausted. Your limit will reset at 2026-05-20 15:43:27' -> quota_exceeded + retryable=true
- 'Weekly Limit Exhausted. Your limit will reset at 2026-05-28 10:30:00' -> quota_exceeded + retryable=true

Verification: 11/11 quota-error-classifier.regression.test.ts pass (was 9 pass + 2 fail pre-fix). Broader runtime-fallback suite goes from 135/196 pass to 137/198 pass (the 61 pre-existing failures are unrelated to this change and reproduce on a clean upstream/dev checkout). bun run typecheck clean.
2026-05-21 18:39:51 +09:00
YeonGyu-Kim f1bf61efb9 fix: resolve duplicate ANALYZE_MESSAGE/ANALYZE_PATTERN identifiers in keyword-detector constants 2026-05-21 17:26:19 +09:00
YeonGyu-Kim 8a5811bf84 chore(comment-checker): drop dead apply-patch-edits re-export shim
src/hooks/comment-checker/apply-patch-edits.ts was already a pure re-export over @oh-my-opencode/comment-checker-core after the core extraction landed. Every importer now reaches into the package directly, so the shim has no remaining call sites and can be removed.

Verified: rg "comment-checker/apply-patch-edits" src/ packages/ returns no matches.
2026-05-21 16:19:38 +09:00
YeonGyu-Kim 7c66aae0b8 refactor(rules-engine): centralize rule constants and AGENTS.md walk-up
Promote the project-rule constants (PROJECT_MARKERS, PROJECT_RULE_SUBDIRS, PROJECT_RULE_FILES, OPENCODE_USER_RULE_DIRS, USER_RULE_DIR, GITHUB_INSTRUCTIONS_PATTERN, RULE_EXTENSIONS, AGENTS_FILENAME, etc.) and the findAgentsMdUp walk-up helper out of the agents-md-core and rules-injector adapters and into @oh-my-opencode/rules-engine, the single owner of rule discovery.

- packages/agents-md-core/ drops the findAgentsMdUp/AgentsMdDiscoveryInput wrappers (now sourced directly from rules-engine) and its constants module re-exports AGENTS_FILENAME from rules-engine instead of duplicating it.
- src/hooks/directory-agents-injector/finder.ts pulls findAgentsMdUp from rules-engine directly while still re-exporting resolveFilePath from agents-md-core.
- src/hooks/rules-injector/constants.ts becomes a pure re-export shim over the rules-engine constants.

Add packages/agents-md-core/src/injector.test.ts to lock the root-skipping AGENTS.md injection order so future changes to findAgentsMdUp cannot silently regress the [Directory Context: ...] block format the injector emits.

Tests: bun test packages/agents-md-core packages/rules-engine src/hooks/directory-agents-injector src/hooks/rules-injector
2026-05-21 16:19:38 +09:00
YeonGyu-Kim bd1a6e3d3b fix(background-agent): forward session stream activity 2026-05-21 15:49:58 +09:00
MoerAI 61b812ffa9 fix(keyword-detector): stop hyperplan firing on '.hpp' C++ header paths (fixes #4215)
The hyperplan trigger \b(hyperplan|hpp)\b/i matched 'hpp' inside common C++ header references like 'check interface.hpp' or 'open buffer.hpp'. The leading '.' is a non-word character, so \b is already satisfied and the false positive fires the hyperplan-mode prompt on routine code questions.

Split the alternation so 'hpp' additionally requires that the preceding character is neither a word character nor a '.'. This preserves every existing trigger ('hpp do this', '/hpp ...', mid-sentence usage, mixed case) while rejecting filename uses of the .hpp extension. The longer 'hyperplan' keyword keeps the original \b boundary semantics.

Reproduction (added regression tests):
- 'please help to check interface.hpp' must NOT fire
- 'open src/include/audio/buffer.hpp and fix the leak' must NOT fire

All 14 cases in hyperplan.test.ts pass (12 existing + 2 new), broader keyword-detector suite stays green (92 pass), typecheck clean.
2026-05-21 13:39:34 +09:00
YeonGyu-Kim 735b4d2997 Merge pull request #4070 from PeterPonyu/fix/4036-prompt-shield-system-directive-marker
fix(prometheus-md-only): replace SYSTEM DIRECTIVE marker with XML tag in external prompts (#4036)
2026-05-21 12:58:36 +09:00