Commit Graph

145 Commits

Author SHA1 Message Date
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 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 f1bf61efb9 fix: resolve duplicate ANALYZE_MESSAGE/ANALYZE_PATTERN identifiers in keyword-detector constants 2026-05-21 17:26:19 +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 689ad9970b Merge pull request #4079 from PeterPonyu/refactor/3694-extract-analyze-constants
refactor(keyword-detector): consolidate analyze pattern/message into analyze/default and document delegate_task params (#3694)
2026-05-21 12:58:27 +09:00
YeonGyu-Kim acedacc5e7 Merge pull request #4084 from pizzav-xyz/feature/keyword-detector-enabled-expansions
feat(keyword-detector): add enabled_expansions config for allowlist control
2026-05-21 12:58:18 +09:00
herjarsa 2f1380f52d refactor(default-mode): inject ultrawork via system prompt instead of visible text
When default_mode.ultrawork is enabled, inject the ultrawork behavioral
instructions into the system prompt (experimental.chat.system.transform)
instead of prepending them to the user's visible chat message.

- system-transform.ts: No-op handler now injects ultrawork message into
  output.system[] when defaultMode.ultrawork is active. Checks for existing
  <ultrawork-mode> tag to avoid re-injection after compaction.
- keyword-detector/hook.ts: Removes the visible text injection
  (output.parts[].text prepend) for default_mode.ultrawork path. Only
  shows the toast as the user-facing indicator.
- plugin-interface.ts: Wires getUltraworkMessage from keyword-detector
  into createSystemTransformHandler.

Result: Ultrawork mode activates silently via system prompt — the chat
stays clean, and only a toast shows 'Ultrawork Mode Active'.
2026-05-19 18:11:38 +02:00
herjarsa e5463e2db7 feat(default-mode): auto-activate ultrawork and ralph loop without commands
Add new `default_mode` config section with two boolean fields:
- `ultrawork`: Auto-inject ultrawork mode prompt on main session start
  without requiring the "ultrawork"/"ulw" keyword. Wired through the
  keyword-detector hook — injects once per session, respects existing
  guards (non-OMO agents, planner agents, subagent sessions).
- `ralph_loop`: Auto-start ralph loop on first main session message
  without requiring /ralph-loop or /ulw-loop commands. When ultrawork
  is also enabled, the loop starts in ultrawork mode.

Usage:
  ```jsonc
  {
    "default_mode": {
      "ultrawork": true,    // Always get ultrawork prompt on start
      "ralph_loop": true    // Auto-start ralph loop
    }
  }
  ```

Files: 7 modified/added, ~65 LOC added.
2026-05-19 18:11:37 +02:00
ZeyuFu 57ab749b37 refactor(keyword-detector): consolidate analyze pattern/message into analyze/default and document delegate_task params (#3694)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-16 06:50:46 -04:00
YeonGyu-Kim 36e373cdbb feat(workspace): point planning guardrails at omo 2026-05-16 17:41:35 +09:00
pizzav-xyz f152569ed4 feat(keyword-detector): add enabled_expansions config for allowlist control
Add optional enabled_expansions field to keyword_detector config schema.
When set, acts as an allowlist - only those expansion types fire.
Empty array disables all expansions. Absent field keeps all enabled (backward-compatible).
Also supports coexistence with disabled_keywords denylist for fine-grained control.

- src/config/schema/keyword-detector.ts: add enabled_expansions field
- src/hooks/keyword-detector/detector.ts: apply allowlist filter in detectKeywordsWithType
- src/hooks/keyword-detector/hook.ts: pass enabled_expansions from config
- src/hooks/keyword-detector/index.test.ts: add 4 tests for enabled_expansions behavior
- assets/oh-my-opencode.schema.json: regenerate schema
2026-05-16 02:01:29 +02:00
YeonGyu-Kim c580b8f2ce fix(session): ignore internal synthetic turns 2026-05-15 23:16:05 +09:00
YeonGyu-Kim 672f5d6e9b fix(keyword-detector): skip synthetic turns 2026-05-15 22:49:17 +09:00
YeonGyu-Kim c25cb8dcef fix(background-task): clarify task id contracts 2026-05-15 15:41:30 +09:00
YeonGyu-Kim 9f6d0d2281 docs(agents-md): refresh hierarchical knowledge base for v4.1.2
- Bump root AGENTS.md header: 2026-05-14 → 2026-05-15, commit 5ffbe0e2453a740636, release v4.1.1 → v4.1.2
- Update file counts: 2034 (1337+697) → 2041 (1340+701), LOC ~292k → ~294k
- Fix STRUCTURE: openclaw lives at src/openclaw/ (not src/features/); list more accurate feature modules in the parenthetical
- Clarify interactive_bash gate: tmux binary on PATH via isInteractiveBashEnabled() (not 'tmux enabled')
- Fix docs/reference/features.md hook counts: Tool Guard 14→16, Total base 52→54, total with team-mode 59→61
- Bump 'Generated' date on all 43 subdir AGENTS.md files to 2026-05-15
- Preserve promptAsync injection cautions verbatim (per request)
2026-05-15 13:48:11 +09:00
YeonGyu-Kim 1e7a7600a2 docs(agents-md): regenerate hierarchical AGENTS.md knowledge base for v4.1.1
Refresh all AGENTS.md files to reflect codebase state at 5ffbe0e24 (was cd31d2a1a, 197 commits behind).

Key drift corrections across 45 modified + 1 new file:

Root AGENTS.md:
- TS file counts: 1967 -> 2034 in src/ (1337 source + 697 test)
- LOC: 278k -> 292k
- Barrel index.ts: 120 -> 122
- Hook tier composition: 52/59 -> 54/61 (base/with team-mode)
- Tool Guard hooks: 14 -> 16 (add fsync-skip-warning, bash-file-read-guard)
- Add boulder feature, agent-ordering schema, .agents/ directory, v4.1.1 release tag
- Add generated/ directory entry

src/AGENTS.md:
- Subsystem inventory: agents 96->102, hooks 570->581, tools 306->314,
  features 389->400, shared 258->278, cli 150->158, plugin 55->56
- LOC totals refreshed for every subsystem
- Schema files: 32 -> 30

src/hooks/AGENTS.md:
- Tier 2 (Tool Guard): 14 -> 16 hooks, add fsyncSkipWarning row
- Total: 52 base / 59 team-mode -> 54 base / 61 team-mode
- zauc-mocks count: 7 -> 5

src/features/AGENTS.md:
- background-agent: 47 -> 57 files, mention archive fallback
- opencode-skill-loader: 33 -> 30
- tmux-subagent: 34 -> 32

src/plugin/AGENTS.md:
- Tool Guard composer count: 14 -> 16
- Aggregator total: 43 -> 45

src/cli/AGENTS.md:
- Add new boulder subcommand (BoulderState inspector)
- Command count: 6 -> 7

NEW: src/features/boulder-state/AGENTS.md
- Document the new Boulder work tracking feature
- Schema v2 with BoulderState/BoulderWorkState/TaskSessionState
- Lifecycle, storage, integration points with atlas/ralph-loop hooks

All other AGENTS.md files: Generated date 2026-05-08 -> 2026-05-14.
2026-05-14 12:57:46 +09:00
YeonGyu-Kim d5fbada13d test: make unsafe test coercion explicit
Move test coercion out of a hidden global and require each test to import the helper so review tools and runtime scripts can see the unsafe boundary.

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

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-05-12 15:51:31 +09:00
YeonGyu-Kim 23211159c9 test(hooks): remove unsafe test assertions
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-05-12 15:41:17 +09:00
YeonGyu-Kim 838b5ae216 docs(agents): refresh hierarchical AGENTS.md with team-mode coverage
Update root + 43 directory-level AGENTS.md files to reflect current state:
- Root AGENTS.md rewritten with accurate counts (1967 TS files, 1304 source +
  663 test, 278k LOC, 120 barrel index.ts), 7-step init flow, 5-tier hook
  composition, and full Team Mode section (12 team_* tools, eligibility,
  storage layout, config gate)
- src/AGENTS.md adds team-mode init step, current per-subdir file/LOC table
- src/tools/AGENTS.md documents conditional gates (team-mode +12, task
  system +4, hashline +1, interactive_bash +1, look_at +1) with always-on
  baseline of 20
- src/hooks/AGENTS.md splits into 5 tiers + 4 conditional team-mode hooks
- src/features/team-mode/AGENTS.md surfaces 12 tools, eligible agents,
  spawn-race-safe invariants, and integration points
- src/features/builtin-skills/AGENTS.md tracks 10 skills incl. team-mode
- src/agents/AGENTS.md, src/plugin/AGENTS.md, src/config/AGENTS.md updated
  for team-mode awareness, accurate counts, and current schema field list
- All other AGENTS.md files refreshed to 2026-05-08 generation date
2026-05-08 12:08:42 +09:00
YeonGyu-Kim 124845002b fix(keyword-detector): pin hyperplan roster hint
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-05-06 14:20:50 +09:00
YeonGyu-Kim f6643e7e77 fix(keyword-detector): yield to slash commands so /hyperplan executes its template
When user types /hyperplan something, two pipelines race for the message:
  1. keyword-detector hook (chat.message): the regex \b(hyperplan|hpp)\b
     matches /hyperplan because \b is satisfied by the / boundary, so the
     hook prepends <hyperplan-mode> to the text part.
  2. auto-slash-command hook (chat.message, runs immediately after):
     detectSlashCommand() checks `text.trimStart().startsWith("/")`. After
     keyword-detector's prepend, the part now starts with <hyperplan-mode>
     and the slash check fails, so the builtin command template
     (with $ARGUMENTS substituted) is never injected.

The visible symptom: /hyperplan refactor X never runs the actual
HYPERPLAN_TEMPLATE - the user sees only the keyword-detector wrapper, which
is similar but not identical, and the slash command's $ARGUMENTS payload
is silently lost.

Fix: at the top of the keyword-detector hook, after isSystemDirective() but
before any keyword scan, bail out if the prompt text starts with a slash
command (^\s*\/[a-zA-Z][\w-]*\b). Slash commands are explicit invocations
and own their own mode-injection path; the keyword detector must not race
them. Free-form mentions like "hyperplan: refactor X" still trigger
keyword detection - only the leading-slash form is suppressed.

Lock the contract with three regression tests:
  - /hyperplan refactor ... must NOT inject <hyperplan-mode>
  - /hpp investigate ... must NOT inject (shorthand slash command)
  - "hyperplan: refactor src/auth/handler.ts" still injects (free-form)

Generated with assistance of [OhMyOpenCode](https://github.com/code-yeongyu/oh-my-opencode).
2026-05-06 14:20:50 +09:00
YeonGyu-Kim 5c67482038 feat(keyword-detector): add hyperplan-ultrawork combo + tuple refactor
Adjacent "hpp ulw" or "ulw hpp" (8 form combinations: short/long, both
orders) triggers a fused mode that suppresses the standalone ultrawork
and hyperplan banners and toasts in favor of one combo banner. The
combo banner explicitly preserves hyperplan's mandatory adversarial
workflow contract (do NOT improvise, do NOT skip rounds) instead of
silently downgrading it.

Suppression runs as a named pipeline step (suppressComboStandalones)
immediately after detection and before all consumers (planner filter,
session filters, toasts, message injection), so standalone toast checks
naturally see the already-suppressed list. Combo is allowed in non-main
sessions like ultrawork, filtered for planner agents like both
standalones, and blocked in subagent sessions via the existing gate.

disabled_keywords uses the intersection rule: disabling either
"ultrawork" or "hyperplan" also disables the combo, so no flavored
content leaks via the combo embedding when either base keyword is
disabled.

Includes a same-PR refactor of KEYWORD_DETECTORS from {pattern, message}
to {type, pattern, message} tuple shape, dropping the parallel hardcoded
types array in detector.ts that previously coupled type assignment to
registry index. Future detector additions can no longer silently corrupt
DetectedKeyword.type via reorder or insertion.

10 behavioral contract tests in hyperplan-ultrawork.test.ts cover both
trigger orders, non-adjacent rejection, suppression of injection and
toast, intersection-rule disable behavior, session/agent policy, and
ultrawork variant routing through the combo. The pre-existing combined
"ultrawork hyperplan" assertion in hyperplan.test.ts is removed in
favor of the new file.

Plan distilled from a hyperplan adversarial review (5 members,
3 rounds: skeptic, validator, researcher, architect, creative).
2026-05-06 14:20:50 +09:00
YeonGyu-Kim 09fe4ca3dd fix(hyperplan): align keyword detector and command template with mandatory plan handoff
Update both injection paths to reflect the 7-phase workflow with the
mandatory plan agent handoff in step 7. The keyword detector now lists
all 8 enumerated steps including the explicit "do not write the plan
yourself" guidance, and the /hyperplan command template references the
7-phase workflow count.

Generated with assistance of [OhMyOpenCode](https://github.com/code-yeongyu/oh-my-opencode).
2026-05-06 14:20:50 +09:00
YeonGyu-Kim 3befe5fa7e feat(keyword-detector): add hyperplan toast and planner filtering to hook
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-05-06 14:20:50 +09:00
YeonGyu-Kim 65e2643757 feat(keyword-detector): add hyperplan to detector types list
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-05-06 14:20:50 +09:00
YeonGyu-Kim b32f2744a0 feat(keyword-detector): register hyperplan in keyword detectors array
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-05-06 14:20:50 +09:00
YeonGyu-Kim f025a4ca30 feat(keyword-detector): add hyperplan keyword pattern, message and test
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-05-06 14:20:50 +09:00
YeonGyu-Kim 91c0d75588 feat(keyword-detector): add per-keyword disable config
Adds keyword_detector.disabled_keywords config so users can opt out of
specific keyword detectors individually without disabling the entire
keyword-detector hook. Allowed values: 'ultrawork', 'search', 'analyze',
'team'. Default empty/missing -> all four detectors active (no behavior
change for existing configs).

Motivation: an audit revealed search and analyze patterns trigger on
~30-60% of normal conversational user messages (e.g. 'how to', 'why is',
'show me', '왜', '어떻게'). The disable list is the immediate kill switch
while the patterns themselves are tightened in a separate PR.

Schema follows the existing per-feature config block convention shared
by team_mode, ralph_loop, runtime_fallback, and comment_checker. The
KeywordType enum (z.enum) lives next to the config schema and is
re-imported by the detector to keep the union type in lockstep with the
schema.

Threading:
  pluginConfig.keyword_detector
    -> create-transform-hooks.ts (factory wiring)
    -> createKeywordDetectorHook(config)
    -> detectKeywordsWithType(text, agent, model, disabledKeywords)
    -> Set-based filter at the source-of-truth detector

Adds 8 regression tests covering per-keyword disable, multi-keyword
disable, partial disable (one keyword off, another still firing),
ultrawork toast suppression, undefined config, and empty array.
2026-05-06 14:19:40 +09:00
YeonGyu-Kim 25d9437513 feat(keyword-detector): add team mode keyword detection
Detects user invocations of team-mode work across English and Korean
('team mode', '팀 모드', '팀으로') and injects a concise English directive
instructing the LLM to orchestrate via team_* tools (team_create ->
team_task_create + team_send_message), forbidding delegate_task
substitution and fallbacks.

The Korean variants use a Hangul-syllable negative lookbehind (가-힣) so
that '스팀으로 게임 켜줘' does not falsely match '팀으로' and '스팀모드' does
not falsely match '팀모드'.

Follows the existing folder pattern (mode/default.ts + mode/index.ts)
shared by ultrawork/, search/, and analyze/. The hook orchestration in
hook.ts handles the new keyword type generically through the shared
KEYWORD_DETECTORS array, so existing guards (non-OMO agent skip,
non-main session filter, system-reminder strip, code-block strip) all
apply automatically.

Adds 7 regression tests covering English/Korean trigger forms, the
Hangul-prefix false-positive guard, the bare-'team' negative case, and
non-main-session filtering.
2026-05-06 14:19:40 +09:00
YeonGyu-Kim 0c39358ebe fix(keyword-detector): require skill evaluation in analyze mode
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-05-01 17:18:51 +09:00
YeonGyu-Kim d89e257d8a refactor(task): align continuation ids with task_id 2026-04-16 23:13:44 +09:00
YeonGyu-Kim 62c60ae9d8 fix: numeric skill names, ultrawork missing run_in_background, ZWSP agent lookups
- #3354: Coerce data.name to String in loadSkillFromPath/loadSkillFromPathAsync
  to prevent crash when YAML parses numeric skill names (e.g., name: 12306)

- #3416: Add required run_in_background parameter to all task() examples in
  ultrawork prompts (default, gpt, gemini, planner) to match tool schema

- #3379/#3417/#3418/#3337/#3335: Strip ZWSP (U+200B) before agent name
  comparisons in agent-tool-restrictions, sync-prompt-sender, tool-execute-after,
  tool-execute-before, oracle-verification-detector, call-omo-agent,
  recovery-prompt-config, and agent-variant to prevent ZWSP-prefixed display
  names from breaking exact-match lookups
2026-04-15 10:46:41 +09:00
YeonGyu-Kim 0c5cd3a1c4 chore(agents): update all AGENTS.md generation dates to 2026-04-11
🤖 Generated with OhMyOpenCode assistance
2026-04-11 22:33:22 +09:00
YeonGyu-Kim e54f747916 fix(tests): replace as any with typed PluginInput mocks 2026-04-10 18:47:17 +09:00
YeonGyu-Kim 8a4eacfd24 test(hooks): update multiple hook test suites
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-10 15:53:32 +09:00
YeonGyu-Kim e86b4f4c2b fix(keyword-detector): stop starting ralph loop for ulw
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-10 11:40:46 +09:00
YeonGyu-Kim 959229d9b7 test(keyword-detector): add plain ulw no-loop regressions
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-10 11:40:14 +09:00