From c187dba56bf123c145aff02c76d06f6c349491c0 Mon Sep 17 00:00:00 2001 From: YeonGyu-Kim Date: Sun, 24 May 2026 18:30:53 +0900 Subject: [PATCH 1/7] test(keyword-detector): capture mode prompt baselines Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus --- .../mode-prompt-baseline.test.ts | 96 +++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100644 src/hooks/keyword-detector/mode-prompt-baseline.test.ts diff --git a/src/hooks/keyword-detector/mode-prompt-baseline.test.ts b/src/hooks/keyword-detector/mode-prompt-baseline.test.ts new file mode 100644 index 000000000..f5fd70b95 --- /dev/null +++ b/src/hooks/keyword-detector/mode-prompt-baseline.test.ts @@ -0,0 +1,96 @@ +import { describe, expect, test } from "bun:test" +import { createHash } from "node:crypto" +import { dirname, join } from "node:path" +import { fileURLToPath } from "node:url" +import { ANALYZE_MESSAGE, HYPERPLAN_MESSAGE, SEARCH_MESSAGE, TEAM_MESSAGE } from "./constants" + +type PromptBaseline = { + readonly name: string + readonly message: string + readonly sha256: string + readonly byteLength: number +} + +type ShimBaseline = { + readonly name: string + readonly filePath: string +} + +const MODE_PROMPT_BASELINES: readonly PromptBaseline[] = [ + { + name: "search", + message: SEARCH_MESSAGE, + sha256: "aa38d1011edcf083394441321564330661868411ec13b575e5994812fae27f62", + byteLength: 311, + }, + { + name: "analyze", + message: ANALYZE_MESSAGE, + sha256: "63f9de6f7afb67ab68bc4abcc7e78c8450a6ce556378a7a5d2b9061a3c519d7f", + byteLength: 865, + }, + { + name: "team", + message: TEAM_MESSAGE, + sha256: "21fd4110835ce380e307cf29e132753b04a58758b86cfaaf5dda26e0e3193d69", + byteLength: 614, + }, + { + name: "hyperplan", + message: HYPERPLAN_MESSAGE, + sha256: "cea6f378370c736909be99bd9a66a06db1e4819848336dd7951298e949270ced", + byteLength: 1500, + }, +] + +const KEYWORD_DETECTOR_DIR = dirname(fileURLToPath(import.meta.url)) + +const MODE_SHIMS: readonly ShimBaseline[] = [ + { name: "search", filePath: join(KEYWORD_DETECTOR_DIR, "search", "default.ts") }, + { name: "analyze", filePath: join(KEYWORD_DETECTOR_DIR, "analyze", "default.ts") }, + { name: "team", filePath: join(KEYWORD_DETECTOR_DIR, "team", "default.ts") }, + { name: "hyperplan", filePath: join(KEYWORD_DETECTOR_DIR, "hyperplan", "default.ts") }, +] + +describe("keyword-detector mode prompt baselines", () => { + test("#given captured prompt baselines #then each mode message keeps the same bytes", () => { + for (const baseline of MODE_PROMPT_BASELINES) { + expect(hashPrompt(baseline.message), baseline.name).toBe(baseline.sha256) + expect(Buffer.byteLength(baseline.message, "utf8"), baseline.name).toBe(baseline.byteLength) + } + }) + + test("#given migrated mode shims #then each shim stays within the LOC ceiling", async () => { + for (const shim of MODE_SHIMS) { + const source = await Bun.file(shim.filePath).text() + + expect(countPureLoc(source), shim.name).toBeLessThanOrEqual(20) + } + }) +}) + +function hashPrompt(prompt: string): string { + return createHash("sha256").update(prompt, "utf8").digest("hex") +} + +function countPureLoc(source: string): number { + let pureLoc = 0 + let insideBlockComment = false + + for (const rawLine of source.split("\n")) { + const line = rawLine.trim() + if (line.length === 0) continue + if (insideBlockComment) { + insideBlockComment = !line.includes("*/") + continue + } + if (line.startsWith("/*")) { + insideBlockComment = !line.includes("*/") + continue + } + if (line.startsWith("//")) continue + pureLoc += 1 + } + + return pureLoc +} From 5cefbdbb6dbc5e9cfd3cf198694256f38913882c Mon Sep 17 00:00:00 2001 From: YeonGyu-Kim Date: Sun, 24 May 2026 18:31:17 +0900 Subject: [PATCH 2/7] refactor(mode-prompts): migrate search prompt Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus --- packages/prompts-core/prompts/mode/search.md | 6 ++++++ packages/prompts-core/src/index.ts | 1 + packages/prompts-core/src/mode-prompts.ts | 7 +++++++ src/hooks/keyword-detector/search/default.ts | 9 +++------ 4 files changed, 17 insertions(+), 6 deletions(-) create mode 100644 packages/prompts-core/prompts/mode/search.md create mode 100644 packages/prompts-core/src/mode-prompts.ts diff --git a/packages/prompts-core/prompts/mode/search.md b/packages/prompts-core/prompts/mode/search.md new file mode 100644 index 000000000..0ba054e1a --- /dev/null +++ b/packages/prompts-core/prompts/mode/search.md @@ -0,0 +1,6 @@ +[search-mode] +MAXIMIZE SEARCH EFFORT. Launch multiple background agents IN PARALLEL: +- explore agents (codebase patterns, file structures, ast-grep) +- librarian agents (remote repos, official docs, GitHub examples) +Plus direct tools: Grep, ripgrep (rg), ast-grep (sg) +NEVER stop at first result - be exhaustive. diff --git a/packages/prompts-core/src/index.ts b/packages/prompts-core/src/index.ts index 639fa86a7..1ba8cb640 100644 --- a/packages/prompts-core/src/index.ts +++ b/packages/prompts-core/src/index.ts @@ -9,3 +9,4 @@ export type { export { resolveVariant } from "./variant-resolver" export type { ResolveVariantInput } from "./variant-resolver" export { loadPrompt, PromptFileNotFoundError, PromptPathTraversalError } from "./loader" +export { SEARCH_MODE_PROMPT } from "./mode-prompts" diff --git a/packages/prompts-core/src/mode-prompts.ts b/packages/prompts-core/src/mode-prompts.ts new file mode 100644 index 000000000..1a27470b5 --- /dev/null +++ b/packages/prompts-core/src/mode-prompts.ts @@ -0,0 +1,7 @@ +import searchModePrompt from "../prompts/mode/search.md" with { type: "text" } + +export const SEARCH_MODE_PROMPT = stripFinalLineFeed(searchModePrompt) + +function stripFinalLineFeed(prompt: string): string { + return prompt.endsWith("\n") ? prompt.slice(0, -1) : prompt +} diff --git a/src/hooks/keyword-detector/search/default.ts b/src/hooks/keyword-detector/search/default.ts index 579574e18..2b999b280 100644 --- a/src/hooks/keyword-detector/search/default.ts +++ b/src/hooks/keyword-detector/search/default.ts @@ -1,3 +1,5 @@ +import { SEARCH_MODE_PROMPT } from "@oh-my-opencode/prompts-core" + /** * Search mode keyword detector. * @@ -12,9 +14,4 @@ export const SEARCH_PATTERN = /\b(search|find|locate|lookup|look\s*up|explore|discover|scan|grep|query|browse|detect|trace|seek|track|pinpoint|hunt)\b|where\s+is|show\s+me|list\s+all|검색|찾아|탐색|조회|스캔|서치|뒤져|찾기|어디|추적|탐지|찾아봐|찾아내|보여줘|목록|検索|探して|見つけて|サーチ|探索|スキャン|どこ|発見|捜索|見つけ出す|一覧|搜索|查找|寻找|查询|检索|定位|扫描|发现|在哪里|找出来|列出|tìm kiếm|tra cứu|định vị|quét|phát hiện|truy tìm|tìm ra|ở đâu|liệt kê/i -export const SEARCH_MESSAGE = `[search-mode] -MAXIMIZE SEARCH EFFORT. Launch multiple background agents IN PARALLEL: -- explore agents (codebase patterns, file structures, ast-grep) -- librarian agents (remote repos, official docs, GitHub examples) -Plus direct tools: Grep, ripgrep (rg), ast-grep (sg) -NEVER stop at first result - be exhaustive.` +export const SEARCH_MESSAGE = SEARCH_MODE_PROMPT From 3b7f51d5684a85d00e1700c61eb1439f17ec0144 Mon Sep 17 00:00:00 2001 From: YeonGyu-Kim Date: Sun, 24 May 2026 18:32:19 +0900 Subject: [PATCH 3/7] refactor(mode-prompts): migrate analyze prompt Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus --- packages/prompts-core/prompts/mode/analyze.md | 16 ++++++++++++++++ packages/prompts-core/src/index.ts | 2 +- packages/prompts-core/src/mode-prompts.ts | 2 ++ src/hooks/keyword-detector/analyze/default.ts | 19 +++---------------- 4 files changed, 22 insertions(+), 17 deletions(-) create mode 100644 packages/prompts-core/prompts/mode/analyze.md diff --git a/packages/prompts-core/prompts/mode/analyze.md b/packages/prompts-core/prompts/mode/analyze.md new file mode 100644 index 000000000..b60f9952c --- /dev/null +++ b/packages/prompts-core/prompts/mode/analyze.md @@ -0,0 +1,16 @@ +[analyze-mode] +ANALYSIS MODE. Gather context before diving deep: + +CONTEXT GATHERING (parallel): +- 1-2 explore agents (codebase patterns, implementations) +- 1-2 librarian agents (if external library involved) +- Direct tools: Grep, AST-grep, LSP for targeted searches + +IF COMPLEX - DO NOT STRUGGLE ALONE. Consult specialists: +- **Oracle**: Conventional problems (architecture, debugging, complex logic) +- **Artistry**: Non-conventional problems (different approach needed) + +SYNTHESIZE findings before proceeding. +--- +MANDATORY delegate_task params: ALWAYS include load_skills and run_in_background when calling delegate_task. Evaluate available skills before dispatch - pass task-appropriate skills when relevant, pass [] ONLY when no skill matches the task domain. +Example: delegate_task(subagent_type="explore", prompt="...", run_in_background=true, load_skills=[]) diff --git a/packages/prompts-core/src/index.ts b/packages/prompts-core/src/index.ts index 1ba8cb640..10e1a43e4 100644 --- a/packages/prompts-core/src/index.ts +++ b/packages/prompts-core/src/index.ts @@ -9,4 +9,4 @@ export type { export { resolveVariant } from "./variant-resolver" export type { ResolveVariantInput } from "./variant-resolver" export { loadPrompt, PromptFileNotFoundError, PromptPathTraversalError } from "./loader" -export { SEARCH_MODE_PROMPT } from "./mode-prompts" +export { ANALYZE_MODE_PROMPT, SEARCH_MODE_PROMPT } from "./mode-prompts" diff --git a/packages/prompts-core/src/mode-prompts.ts b/packages/prompts-core/src/mode-prompts.ts index 1a27470b5..f731e8225 100644 --- a/packages/prompts-core/src/mode-prompts.ts +++ b/packages/prompts-core/src/mode-prompts.ts @@ -1,5 +1,7 @@ +import analyzeModePrompt from "../prompts/mode/analyze.md" with { type: "text" } import searchModePrompt from "../prompts/mode/search.md" with { type: "text" } +export const ANALYZE_MODE_PROMPT = stripFinalLineFeed(analyzeModePrompt) export const SEARCH_MODE_PROMPT = stripFinalLineFeed(searchModePrompt) function stripFinalLineFeed(prompt: string): string { diff --git a/src/hooks/keyword-detector/analyze/default.ts b/src/hooks/keyword-detector/analyze/default.ts index 01a0c08d1..d1a533529 100644 --- a/src/hooks/keyword-detector/analyze/default.ts +++ b/src/hooks/keyword-detector/analyze/default.ts @@ -1,3 +1,5 @@ +import { ANALYZE_MODE_PROMPT } from "@oh-my-opencode/prompts-core" + /** * Analyze mode keyword detector. * @@ -12,19 +14,4 @@ export const ANALYZE_PATTERN = /\b(analyze|analyse|investigate|examine|research|study|deep[\s-]?dive|inspect|audit|evaluate|assess|review|diagnose|scrutinize|dissect|debug|comprehend|interpret|breakdown|understand)\b|why\s+is|how\s+does|how\s+to|분석|조사|파악|연구|검토|진단|이해|설명|원인|이유|뜯어봐|따져봐|평가|해석|디버깅|디버그|어떻게|왜|살펴|分析|調査|解析|検討|研究|診断|理解|説明|検証|精査|究明|デバッグ|なぜ|どう|仕組み|调查|检查|剖析|深入|诊断|解释|调试|为什么|原理|搞清楚|弄明白|phân tích|điều tra|nghiên cứu|kiểm tra|xem xét|chẩn đoán|giải thích|tìm hiểu|gỡ lỗi|tại sao/i -export const ANALYZE_MESSAGE = `[analyze-mode] -ANALYSIS MODE. Gather context before diving deep: - -CONTEXT GATHERING (parallel): -- 1-2 explore agents (codebase patterns, implementations) -- 1-2 librarian agents (if external library involved) -- Direct tools: Grep, AST-grep, LSP for targeted searches - -IF COMPLEX - DO NOT STRUGGLE ALONE. Consult specialists: -- **Oracle**: Conventional problems (architecture, debugging, complex logic) -- **Artistry**: Non-conventional problems (different approach needed) - -SYNTHESIZE findings before proceeding. ---- -MANDATORY delegate_task params: ALWAYS include load_skills and run_in_background when calling delegate_task. Evaluate available skills before dispatch - pass task-appropriate skills when relevant, pass [] ONLY when no skill matches the task domain. -Example: delegate_task(subagent_type="explore", prompt="...", run_in_background=true, load_skills=[])` +export const ANALYZE_MESSAGE = ANALYZE_MODE_PROMPT From e79baf5910848a1bab2967a5b9b6d96070676f83 Mon Sep 17 00:00:00 2001 From: YeonGyu-Kim Date: Sun, 24 May 2026 18:32:35 +0900 Subject: [PATCH 4/7] refactor(mode-prompts): migrate team prompt Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus --- packages/prompts-core/prompts/mode/team.md | 2 ++ packages/prompts-core/src/index.ts | 2 +- packages/prompts-core/src/mode-prompts.ts | 2 ++ src/hooks/keyword-detector/team/default.ts | 5 +++-- 4 files changed, 8 insertions(+), 3 deletions(-) create mode 100644 packages/prompts-core/prompts/mode/team.md diff --git a/packages/prompts-core/prompts/mode/team.md b/packages/prompts-core/prompts/mode/team.md new file mode 100644 index 000000000..ed90fd575 --- /dev/null +++ b/packages/prompts-core/prompts/mode/team.md @@ -0,0 +1,2 @@ +[team-mode] +Team-mode reference detected. Orchestrate via team_* tools (team_create -> team_task_create + team_send_message); NEVER substitute with delegate_task — it is not equivalent. After every team_task_update that completes or fails a task, re-check team_task_list: if every task is terminal, run the closure sequence (team_shutdown_request + team_approve_shutdown per active member, then team_delete) in the same turn. Closing the team is the lead's responsibility, not the user's. If the team_* tools are absent, team_mode is disabled — tell the user to set team_mode.enabled=true and restart opencode. diff --git a/packages/prompts-core/src/index.ts b/packages/prompts-core/src/index.ts index 10e1a43e4..d867877a5 100644 --- a/packages/prompts-core/src/index.ts +++ b/packages/prompts-core/src/index.ts @@ -9,4 +9,4 @@ export type { export { resolveVariant } from "./variant-resolver" export type { ResolveVariantInput } from "./variant-resolver" export { loadPrompt, PromptFileNotFoundError, PromptPathTraversalError } from "./loader" -export { ANALYZE_MODE_PROMPT, SEARCH_MODE_PROMPT } from "./mode-prompts" +export { ANALYZE_MODE_PROMPT, SEARCH_MODE_PROMPT, TEAM_MODE_PROMPT } from "./mode-prompts" diff --git a/packages/prompts-core/src/mode-prompts.ts b/packages/prompts-core/src/mode-prompts.ts index f731e8225..a17096ea3 100644 --- a/packages/prompts-core/src/mode-prompts.ts +++ b/packages/prompts-core/src/mode-prompts.ts @@ -1,8 +1,10 @@ import analyzeModePrompt from "../prompts/mode/analyze.md" with { type: "text" } import searchModePrompt from "../prompts/mode/search.md" with { type: "text" } +import teamModePrompt from "../prompts/mode/team.md" with { type: "text" } export const ANALYZE_MODE_PROMPT = stripFinalLineFeed(analyzeModePrompt) export const SEARCH_MODE_PROMPT = stripFinalLineFeed(searchModePrompt) +export const TEAM_MODE_PROMPT = stripFinalLineFeed(teamModePrompt) function stripFinalLineFeed(prompt: string): string { return prompt.endsWith("\n") ? prompt.slice(0, -1) : prompt diff --git a/src/hooks/keyword-detector/team/default.ts b/src/hooks/keyword-detector/team/default.ts index 43e0ce700..31a9399db 100644 --- a/src/hooks/keyword-detector/team/default.ts +++ b/src/hooks/keyword-detector/team/default.ts @@ -1,3 +1,5 @@ +import { TEAM_MODE_PROMPT } from "@oh-my-opencode/prompts-core" + /** * Team mode keyword detector. * @@ -7,5 +9,4 @@ export const TEAM_PATTERN = /\bteam[\s_-]?mode\b/i -export const TEAM_MESSAGE = `[team-mode] -Team-mode reference detected. Orchestrate via team_* tools (team_create -> team_task_create + team_send_message); NEVER substitute with delegate_task — it is not equivalent. After every team_task_update that completes or fails a task, re-check team_task_list: if every task is terminal, run the closure sequence (team_shutdown_request + team_approve_shutdown per active member, then team_delete) in the same turn. Closing the team is the lead's responsibility, not the user's. If the team_* tools are absent, team_mode is disabled — tell the user to set team_mode.enabled=true and restart opencode.` +export const TEAM_MESSAGE = TEAM_MODE_PROMPT From 2c8e2dac4185899b727eae58be551ac6a3f32400 Mon Sep 17 00:00:00 2001 From: YeonGyu-Kim Date: Sun, 24 May 2026 18:32:45 +0900 Subject: [PATCH 5/7] refactor(mode-prompts): migrate hyperplan prompt Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus --- .../prompts-core/prompts/mode/hyperplan.md | 25 +++++++++++++++++ packages/prompts-core/src/index.ts | 7 ++++- packages/prompts-core/src/mode-prompts.ts | 2 ++ .../keyword-detector/hyperplan/default.ts | 28 ++----------------- 4 files changed, 36 insertions(+), 26 deletions(-) create mode 100644 packages/prompts-core/prompts/mode/hyperplan.md diff --git a/packages/prompts-core/prompts/mode/hyperplan.md b/packages/prompts-core/prompts/mode/hyperplan.md new file mode 100644 index 000000000..bb70c4ee0 --- /dev/null +++ b/packages/prompts-core/prompts/mode/hyperplan.md @@ -0,0 +1,25 @@ + +**MANDATORY**: Say "HYPERPLAN MODE ENABLED!" as your first response, exactly once. + +The user invoked **hyperplan mode** — adversarial multi-agent planning via team-mode. + +LOAD THE HYPERPLAN SKILL IMMEDIATELY: + +``` +skill(name="hyperplan") +``` + +After loading, follow the skill's full workflow EXACTLY: +1. Acknowledge and capture the planning request +2. Spawn the adversarial team via `team_create` with category members `unspecified-low`, `unspecified-high`, `ultrabrain`, and `artistry`; include `deep` only if the category is enabled +3. Round 1 — Independent analysis (each member produces findings) +4. Round 2 — Cross-attack (each member ruthlessly attacks the other 4's findings) +5. Round 3 — Defend, refine, or concede +6. Distill defensible insights into a structured bundle (Lead does NOT write the plan) +7. MANDATORY: hand the bundle to the `plan` agent via `task(subagent_type="plan", ...)` — the plan agent owns sequencing, parallelization, and verification gates +8. Present the plan agent's output verbatim with provenance line, then clean up the team + +Do NOT improvise. Do NOT skip rounds. Do NOT write the plan yourself in step 6 — the handoff to the plan agent in step 7 is non-negotiable. Be the lead orchestrator and let the adversarial members do the cross-critique. + +If team-mode is unavailable (`team_*` tools missing), instruct the user to set `team_mode.enabled: true` in `~/.config/opencode/oh-my-opencode.jsonc` and restart opencode. + diff --git a/packages/prompts-core/src/index.ts b/packages/prompts-core/src/index.ts index d867877a5..c2e9572ea 100644 --- a/packages/prompts-core/src/index.ts +++ b/packages/prompts-core/src/index.ts @@ -9,4 +9,9 @@ export type { export { resolveVariant } from "./variant-resolver" export type { ResolveVariantInput } from "./variant-resolver" export { loadPrompt, PromptFileNotFoundError, PromptPathTraversalError } from "./loader" -export { ANALYZE_MODE_PROMPT, SEARCH_MODE_PROMPT, TEAM_MODE_PROMPT } from "./mode-prompts" +export { + ANALYZE_MODE_PROMPT, + HYPERPLAN_MODE_PROMPT, + SEARCH_MODE_PROMPT, + TEAM_MODE_PROMPT, +} from "./mode-prompts" diff --git a/packages/prompts-core/src/mode-prompts.ts b/packages/prompts-core/src/mode-prompts.ts index a17096ea3..3603e3c12 100644 --- a/packages/prompts-core/src/mode-prompts.ts +++ b/packages/prompts-core/src/mode-prompts.ts @@ -1,8 +1,10 @@ +import hyperplanModePrompt from "../prompts/mode/hyperplan.md" with { type: "text" } import analyzeModePrompt from "../prompts/mode/analyze.md" with { type: "text" } import searchModePrompt from "../prompts/mode/search.md" with { type: "text" } import teamModePrompt from "../prompts/mode/team.md" with { type: "text" } export const ANALYZE_MODE_PROMPT = stripFinalLineFeed(analyzeModePrompt) +export const HYPERPLAN_MODE_PROMPT = stripFinalLineFeed(hyperplanModePrompt) export const SEARCH_MODE_PROMPT = stripFinalLineFeed(searchModePrompt) export const TEAM_MODE_PROMPT = stripFinalLineFeed(teamModePrompt) diff --git a/src/hooks/keyword-detector/hyperplan/default.ts b/src/hooks/keyword-detector/hyperplan/default.ts index cf27e087a..e049c8c5d 100644 --- a/src/hooks/keyword-detector/hyperplan/default.ts +++ b/src/hooks/keyword-detector/hyperplan/default.ts @@ -1,3 +1,5 @@ +import { HYPERPLAN_MODE_PROMPT } from "@oh-my-opencode/prompts-core" + /** * Hyperplan keyword detector. * @@ -17,28 +19,4 @@ export const HYPERPLAN_PATTERN = /\bhyperplan\b|(? -**MANDATORY**: Say "HYPERPLAN MODE ENABLED!" as your first response, exactly once. - -The user invoked **hyperplan mode** — adversarial multi-agent planning via team-mode. - -LOAD THE HYPERPLAN SKILL IMMEDIATELY: - -\`\`\` -skill(name="hyperplan") -\`\`\` - -After loading, follow the skill's full workflow EXACTLY: -1. Acknowledge and capture the planning request -2. Spawn the adversarial team via \`team_create\` with category members \`unspecified-low\`, \`unspecified-high\`, \`ultrabrain\`, and \`artistry\`; include \`deep\` only if the category is enabled -3. Round 1 — Independent analysis (each member produces findings) -4. Round 2 — Cross-attack (each member ruthlessly attacks the other 4's findings) -5. Round 3 — Defend, refine, or concede -6. Distill defensible insights into a structured bundle (Lead does NOT write the plan) -7. MANDATORY: hand the bundle to the \`plan\` agent via \`task(subagent_type="plan", ...)\` — the plan agent owns sequencing, parallelization, and verification gates -8. Present the plan agent's output verbatim with provenance line, then clean up the team - -Do NOT improvise. Do NOT skip rounds. Do NOT write the plan yourself in step 6 — the handoff to the plan agent in step 7 is non-negotiable. Be the lead orchestrator and let the adversarial members do the cross-critique. - -If team-mode is unavailable (\`team_*\` tools missing), instruct the user to set \`team_mode.enabled: true\` in \`~/.config/opencode/oh-my-opencode.jsonc\` and restart opencode. -` +export const HYPERPLAN_MESSAGE = HYPERPLAN_MODE_PROMPT From 80361c05abcac13866e2a5b5053455b86595a3c1 Mon Sep 17 00:00:00 2001 From: YeonGyu-Kim Date: Sun, 24 May 2026 18:32:53 +0900 Subject: [PATCH 6/7] chore(prompts-core): wire markdown prompt packaging Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus --- bun.lock | 1 + package.json | 1 + packages/prompts-core/src/markdown.d.ts | 4 ++++ src/markdown.d.ts | 4 ++++ 4 files changed, 10 insertions(+) create mode 100644 packages/prompts-core/src/markdown.d.ts create mode 100644 src/markdown.d.ts diff --git a/bun.lock b/bun.lock index 04be30353..bc5578998 100644 --- a/bun.lock +++ b/bun.lock @@ -31,6 +31,7 @@ "@oh-my-opencode/comment-checker-core": "workspace:*", "@oh-my-opencode/hashline-core": "workspace:*", "@oh-my-opencode/model-core": "workspace:*", + "@oh-my-opencode/prompts-core": "workspace:*", "@oh-my-opencode/rules-engine": "workspace:*", "@oh-my-opencode/utils": "workspace:*", "@types/js-yaml": "^4.0.9", diff --git a/package.json b/package.json index 7a84c1328..5013879c8 100644 --- a/package.json +++ b/package.json @@ -101,6 +101,7 @@ "@oh-my-opencode/comment-checker-core": "workspace:*", "@oh-my-opencode/hashline-core": "workspace:*", "@oh-my-opencode/model-core": "workspace:*", + "@oh-my-opencode/prompts-core": "workspace:*", "@oh-my-opencode/rules-engine": "workspace:*", "@oh-my-opencode/utils": "workspace:*", "@typescript/native-preview": "7.0.0-dev.20260518.1", diff --git a/packages/prompts-core/src/markdown.d.ts b/packages/prompts-core/src/markdown.d.ts new file mode 100644 index 000000000..2a2a99ee8 --- /dev/null +++ b/packages/prompts-core/src/markdown.d.ts @@ -0,0 +1,4 @@ +declare module "*.md" { + const markdown: string + export default markdown +} diff --git a/src/markdown.d.ts b/src/markdown.d.ts new file mode 100644 index 000000000..2a2a99ee8 --- /dev/null +++ b/src/markdown.d.ts @@ -0,0 +1,4 @@ +declare module "*.md" { + const markdown: string + export default markdown +} From 63ef72d1b9d091139b71dd57375188b44bc15be2 Mon Sep 17 00:00:00 2001 From: YeonGyu-Kim Date: Sun, 24 May 2026 18:33:00 +0900 Subject: [PATCH 7/7] docs(agents): document prompts-core mode prompts Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus --- AGENTS.md | 4 +++- packages/AGENTS.md | 6 ++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index fcb786a5f..83834d139 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -32,13 +32,15 @@ oh-my-opencode/ │ ├── openclaw/ # Bidirectional external integration (Discord/Telegram/HTTP/shell + reply listener daemon) │ ├── generated/ # model-capabilities.generated.json (refreshed via build:model-capabilities) │ └── testing/ # Test utilities + `create-plugin-module.ts` (extracted plugin entry factory, 182 LOC) -├── packages/ # 11 platform binaries + 2 MCP packages + 7 Core packages + web +├── packages/ # 11 platform binaries + 2 MCP packages + 9 Core packages + web │ ├── utils/ # Shared utilities — deep-merge, snake-case, frontmatter, file-utils, etc. │ ├── model-core/ # Model resolution pipeline with ProviderCache DI +│ ├── prompts-core/ # Markdown prompt loading + bundled mode prompts (search/analyze/team/hyperplan) │ ├── rules-engine/ # Rule discovery + matching (renamed from rules-core) │ ├── agents-md-core/ # AGENTS.md walk-up discovery + injection │ ├── ast-grep-core/ # ast-grep types, pattern-hints, runner core with injectable spawn │ ├── comment-checker-core/ # apply-patch parser, binary runner with injectable spawn +│ ├── hashline-core/ # Hashline edit primitives and diff helpers shared by adapter shims │ ├── boulder-state/ # Work tracking state machine, split storage │ └── web/ # Marketing site (Next.js 15 + Cloudflare Workers). Independent package with own bun.lock ├── bin/ # Platform-detection JS shim (oh-my-opencode + oh-my-openagent) diff --git a/packages/AGENTS.md b/packages/AGENTS.md index 61216a27e..68eac8296 100644 --- a/packages/AGENTS.md +++ b/packages/AGENTS.md @@ -4,7 +4,7 @@ ## OVERVIEW -15 sibling packages across 4 roles. None of these are published as part of the main `oh-my-opencode` / `oh-my-openagent` npm dist (root `package.json` `files` only ships `dist/`, `bin/`, `postinstall.mjs`). They are sibling packages with their own publication / deployment targets. +23 sibling packages across 4 roles. None of these are published as part of the main `oh-my-opencode` / `oh-my-openagent` npm dist (root `package.json` `files` only ships `dist/`, `bin/`, `postinstall.mjs`). They are sibling packages with their own publication / deployment targets. ## ROLE MAP @@ -12,7 +12,7 @@ |------|-------|----------| | **Platform binaries** | 11 | One per (OS × arch × variant). Uniform layout: `bin/` + `package.json` only. Selected at install time by `bin/` shim + `postinstall.mjs`. | | **MCP packages** | 2 | `lsp-tools-mcp` (git submodule), `ast-grep-mcp` | -| **Core packages** | 7 | `utils`, `model-core`, `rules-engine` (was `rules-core`), `agents-md-core`, `ast-grep-core`, `comment-checker-core`, `boulder-state` | +| **Core packages** | 9 | `utils`, `model-core`, `prompts-core`, `rules-engine` (was `rules-core`), `agents-md-core`, `ast-grep-core`, `comment-checker-core`, `hashline-core`, `boulder-state` | | **Web** | 1 | `web` | ## PLATFORM BINARIES (11) @@ -36,10 +36,12 @@ Each contains only a `bin/` and a `package.json`. Built by [`script/buil |---------|--------|---------| | `utils/` | `src/`, `tsconfig.json` | Shared utilities: deep-merge, snake-case, frontmatter, file-utils, etc. | | `model-core/` | `src/`, `tsconfig.json` | Model resolution pipeline with ProviderCache dependency injection. | +| `prompts-core/` | `src/`, `prompts/`, `test/`, `tsconfig.json` | Harness-neutral markdown prompt loading, model-variant routing, and bundled mode prompts for search/analyze/team/hyperplan. | | `rules-engine/` | `src/`, `tsconfig.json` | Rule discovery + matching engine (renamed from `rules-core`). | | `agents-md-core/` | `src/`, `tsconfig.json` | AGENTS.md walk-up discovery and injection logic. | | `ast-grep-core/` | `src/`, `tsconfig.json` | ast-grep types, pattern-hints, and runner core with injectable spawn. | | `comment-checker-core/` | `src/`, `tsconfig.json` | apply-patch parser and binary runner with injectable spawn. | +| `hashline-core/` | `src/`, `tsconfig.json` | Hashline edit primitives and diff helpers shared by adapter shims. | | `boulder-state/` | `src/`, `tsconfig.json` | Work tracking state machine with split storage. | ## WEB