@skj1724/oh-my-opencode 3.18.5 → 3.18.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli/index.js CHANGED
@@ -53770,7 +53770,7 @@ var {
53770
53770
  // package.json
53771
53771
  var package_default = {
53772
53772
  name: "@skj1724/oh-my-opencode",
53773
- version: "3.18.5",
53773
+ version: "3.18.7",
53774
53774
  description: "The Best AI Agent Harness - Batteries-Included OpenCode Plugin with Multi-Model Orchestration, Parallel Background Agents, and Crafted LSP/AST Tools",
53775
53775
  main: "./dist/index.js",
53776
53776
  types: "dist/index.d.ts",
@@ -1 +1 @@
1
- export declare const GIT_MASTER_COMMIT_WORKFLOW_SECTION = "## PHASE 0: Parallel Context Gathering (MANDATORY FIRST STEP)\n\n<parallel_analysis>\n**Execute ALL of the following commands IN PARALLEL to minimize latency:**\n\n```bash\n# Group 1: Current state\ngit status\ngit diff --staged --stat\ngit diff --stat\n\n# Group 2: History context \ngit log -30 --oneline\ngit log -30 --pretty=format:\"%s\"\n\n# Group 3: Branch context\ngit branch --show-current\ngit merge-base HEAD main 2>/dev/null || git merge-base HEAD master 2>/dev/null\ngit rev-parse --abbrev-ref @{upstream} 2>/dev/null || echo \"NO_UPSTREAM\"\ngit log --oneline $(git merge-base HEAD main 2>/dev/null || git merge-base HEAD master 2>/dev/null)..HEAD 2>/dev/null\n```\n\n**Capture these data points simultaneously:**\n1. What files changed (staged vs unstaged)\n2. Recent 30 commit messages for style detection\n3. Branch position relative to main/master\n4. Whether branch has upstream tracking\n5. Commits that would go in PR (local only)\n</parallel_analysis>\n\n---\n\n## PHASE 1: Style Detection (BLOCKING - MUST OUTPUT BEFORE PROCEEDING)\n\n<style_detection>\n**THIS PHASE HAS MANDATORY OUTPUT** - You MUST print the analysis result before moving to Phase 2.\n\n### 1.1 Language Detection\n\n```\nCount from git log -30:\n- Korean characters: N commits\n- English only: M commits\n- Mixed: K commits\n\nDECISION:\n- If Korean >= 50% -> KOREAN\n- If English >= 50% -> ENGLISH \n- If Mixed -> Use MAJORITY language\n```\n\n### 1.2 Commit Style Classification\n\n| Style | Pattern | Example | Detection Regex |\n|-------|---------|---------|-----------------|\n| `SEMANTIC` | `type: message` or `type(scope): message` | `feat: add login` | `/^(feat\\|fix\\|chore\\|refactor\\|docs\\|test\\|ci\\|style\\|perf\\|build)(\\(.+\\))?:/` |\n| `PLAIN` | Just description, no prefix | `Add login feature` | No conventional prefix, >3 words |\n| `SENTENCE` | Full sentence style | `Implemented the new login flow` | Complete grammatical sentence |\n| `SHORT` | Minimal keywords | `format`, `lint` | 1-3 words only |\n\n**Detection Algorithm:**\n```\nsemantic_count = commits matching semantic regex\nplain_count = non-semantic commits with >3 words\nshort_count = commits with <=3 words\n\nIF semantic_count >= 15 (50%): STYLE = SEMANTIC\nELSE IF plain_count >= 15: STYLE = PLAIN \nELSE IF short_count >= 10: STYLE = SHORT\nELSE: STYLE = PLAIN (safe default)\n```\n\n### 1.3 MANDATORY OUTPUT (BLOCKING)\n\n**You MUST output this block before proceeding to Phase 2. NO EXCEPTIONS.**\n\n```\nSTYLE DETECTION RESULT\n======================\nAnalyzed: 30 commits from git log\n\nLanguage: [KOREAN | ENGLISH]\n - Korean commits: N (X%)\n - English commits: M (Y%)\n\nStyle: [SEMANTIC | PLAIN | SENTENCE | SHORT]\n - Semantic (feat:, fix:, etc): N (X%)\n - Plain: M (Y%)\n - Short: K (Z%)\n\nReference examples from repo:\n 1. \"actual commit message from log\"\n 2. \"actual commit message from log\"\n 3. \"actual commit message from log\"\n\nAll commits will follow: [LANGUAGE] + [STYLE]\n```\n\n**IF YOU SKIP THIS OUTPUT, YOUR COMMITS WILL BE WRONG. STOP AND REDO.**\n</style_detection>\n\n---\n\n## PHASE 2: Branch Context Analysis\n\n<branch_analysis>\n### 2.1 Determine Branch State\n\n```\nBRANCH_STATE:\n current_branch: <name>\n has_upstream: true | false\n commits_ahead: N # Local-only commits\n merge_base: <hash>\n \nREWRITE_SAFETY:\n - If has_upstream AND commits_ahead > 0 AND already pushed:\n -> WARN before force push\n - If no upstream OR all commits local:\n -> Safe for aggressive rewrite (fixup, reset, rebase)\n - If on main/master:\n -> NEVER rewrite, only new commits\n```\n\n### 2.2 History Rewrite Strategy Decision\n\n```\nIF current_branch == main OR current_branch == master:\n -> STRATEGY = NEW_COMMITS_ONLY\n -> Never fixup, never rebase\n\nELSE IF commits_ahead == 0:\n -> STRATEGY = NEW_COMMITS_ONLY\n -> No history to rewrite\n\nELSE IF all commits are local (not pushed):\n -> STRATEGY = AGGRESSIVE_REWRITE\n -> Fixup freely, reset if needed, rebase to clean\n\nELSE IF pushed but not merged:\n -> STRATEGY = CAREFUL_REWRITE \n -> Fixup OK but warn about force push\n```\n</branch_analysis>\n\n---\n\n## PHASE 3: Atomic Unit Planning (BLOCKING - MUST OUTPUT BEFORE PROCEEDING)\n\n<atomic_planning>\n**THIS PHASE HAS MANDATORY OUTPUT** - You MUST print the commit plan before moving to Phase 4.\n\n### 3.0 Calculate Minimum Commit Count FIRST\n\n```\nFORMULA: min_commits = ceil(file_count / 3)\n\n 3 files -> min 1 commit\n 5 files -> min 2 commits\n 9 files -> min 3 commits\n15 files -> min 5 commits\n```\n\n**If your planned commit count < min_commits -> WRONG. SPLIT MORE.**\n\n### 3.1 Split by Directory/Module FIRST (Primary Split)\n\n**RULE: Different directories = Different commits (almost always)**\n\n```\nExample: 8 changed files\n - app/[locale]/page.tsx\n - app/[locale]/layout.tsx\n - components/demo/browser-frame.tsx\n - components/demo/shopify-full-site.tsx\n - components/pricing/pricing-table.tsx\n - e2e/navbar.spec.ts\n - messages/en.json\n - messages/ko.json\n\nWRONG: 1 commit \"Update landing page\" (LAZY, WRONG)\nWRONG: 2 commits (still too few)\n\nCORRECT: Split by directory/concern:\n - Commit 1: app/[locale]/page.tsx + layout.tsx (app layer)\n - Commit 2: components/demo/* (demo components)\n - Commit 3: components/pricing/* (pricing components)\n - Commit 4: e2e/* (tests)\n - Commit 5: messages/* (i18n)\n = 5 commits from 8 files (CORRECT)\n```\n\n### 3.2 Split by Concern SECOND (Secondary Split)\n\n**Within same directory, split by logical concern:**\n\n```\nExample: components/demo/ has 4 files\n - browser-frame.tsx (UI frame)\n - shopify-full-site.tsx (specific demo)\n - review-dashboard.tsx (NEW - specific demo)\n - tone-settings.tsx (NEW - specific demo)\n\nOption A (acceptable): 1 commit if ALL tightly coupled\nOption B (preferred): 2 commits\n - Commit: \"Update existing demo components\" (browser-frame, shopify)\n - Commit: \"Add new demo components\" (review-dashboard, tone-settings)\n```\n\n### 3.3 NEVER Do This (Anti-Pattern Examples)\n\n```\nWRONG: \"Refactor entire landing page\" - 1 commit with 15 files\nWRONG: \"Update components and tests\" - 1 commit mixing concerns\nWRONG: \"Big update\" - Any commit touching 5+ unrelated files\n\nRIGHT: Multiple focused commits, each 1-4 files max\nRIGHT: Each commit message describes ONE specific change\nRIGHT: A reviewer can understand each commit in 30 seconds\n```\n\n### 3.4 Implementation + Test Pairing (MANDATORY)\n\n```\nRULE: Test files MUST be in same commit as implementation\n\nTest patterns to match:\n- test_*.py <-> *.py\n- *_test.py <-> *.py\n- *.test.ts <-> *.ts\n- *.spec.ts <-> *.ts\n- __tests__/*.ts <-> *.ts\n- tests/*.py <-> src/*.py\n```\n\n### 3.5 MANDATORY JUSTIFICATION (Before Creating Commit Plan)\n\n**NON-NEGOTIABLE: Before finalizing your commit plan, you MUST:**\n\n```\nFOR EACH planned commit with 3+ files:\n 1. List all files in this commit\n 2. Write ONE sentence explaining why they MUST be together\n 3. If you can't write that sentence -> SPLIT\n \nTEMPLATE:\n\"Commit N contains [files] because [specific reason they are inseparable].\"\n\nVALID reasons:\n VALID: \"implementation file + its direct test file\"\n VALID: \"type definition + the only file that uses it\"\n VALID: \"migration + model change (would break without both)\"\n \nINVALID reasons (MUST SPLIT instead):\n INVALID: \"all related to feature X\" (too vague)\n INVALID: \"part of the same PR\" (not a reason)\n INVALID: \"they were changed together\" (not a reason)\n INVALID: \"makes sense to group\" (not a reason)\n```\n\n**OUTPUT THIS JUSTIFICATION in your analysis before executing commits.**\n\n### 3.7 Dependency Ordering\n\n```\nLevel 0: Utilities, constants, type definitions\nLevel 1: Models, schemas, interfaces\nLevel 2: Services, business logic\nLevel 3: API endpoints, controllers\nLevel 4: Configuration, infrastructure\n\nCOMMIT ORDER: Level 0 -> Level 1 -> Level 2 -> Level 3 -> Level 4\n```\n\n### 3.8 Create Commit Groups\n\nFor each logical feature/change:\n```yaml\n- group_id: 1\n feature: \"Add Shopify discount deletion\"\n files:\n - errors/shopify_error.py\n - types/delete_input.py\n - mutations/update_contract.py\n - tests/test_update_contract.py\n dependency_level: 2\n target_commit: null | <existing-hash> # null = new, hash = fixup\n```\n\n### 3.9 MANDATORY OUTPUT (BLOCKING)\n\n**You MUST output this block before proceeding to Phase 4. NO EXCEPTIONS.**\n\n```\nCOMMIT PLAN\n===========\nFiles changed: N\nMinimum commits required: ceil(N/3) = M\nPlanned commits: K\nStatus: K >= M (PASS) | K < M (FAIL - must split more)\n\nCOMMIT 1: [message in detected style]\n - path/to/file1.py\n - path/to/file1_test.py\n Justification: implementation + its test\n\nCOMMIT 2: [message in detected style]\n - path/to/file2.py\n Justification: independent utility function\n\nCOMMIT 3: [message in detected style]\n - config/settings.py\n - config/constants.py\n Justification: tightly coupled config changes\n\nExecution order: Commit 1 -> Commit 2 -> Commit 3\n(follows dependency: Level 0 -> Level 1 -> Level 2 -> ...)\n```\n\n**VALIDATION BEFORE EXECUTION:**\n- Each commit has <=4 files (or justified)\n- Each commit message matches detected STYLE + LANGUAGE\n- Test files paired with implementation\n- Different directories = different commits (or justified)\n- Total commits >= min_commits\n\n**IF ANY CHECK FAILS, DO NOT PROCEED. REPLAN.**\n</atomic_planning>\n\n---\n\n## PHASE 4: Commit Strategy Decision\n\n<strategy_decision>\n### 4.1 For Each Commit Group, Decide:\n\n```\nFIXUP if:\n - Change complements existing commit's intent\n - Same feature, fixing bugs or adding missing parts\n - Review feedback incorporation\n - Target commit exists in local history\n\nNEW COMMIT if:\n - New feature or capability\n - Independent logical unit\n - Different issue/ticket\n - No suitable target commit exists\n```\n\n### 4.2 History Rebuild Decision (Aggressive Option)\n\n```\nCONSIDER RESET & REBUILD when:\n - History is messy (many small fixups already)\n - Commits are not atomic (mixed concerns)\n - Dependency order is wrong\n \nRESET WORKFLOW:\n 1. git reset --soft $(git merge-base HEAD main)\n 2. All changes now staged\n 3. Re-commit in proper atomic units\n 4. Clean history from scratch\n \nONLY IF:\n - All commits are local (not pushed)\n - User explicitly allows OR branch is clearly WIP\n```\n\n### 4.3 Final Plan Summary\n\n```yaml\nEXECUTION_PLAN:\n strategy: FIXUP_THEN_NEW | NEW_ONLY | RESET_REBUILD\n fixup_commits:\n - files: [...]\n target: <hash>\n new_commits:\n - files: [...]\n message: \"...\"\n level: N\n requires_force_push: true | false\n```\n</strategy_decision>\n\n---\n\n## PHASE 5: Commit Execution\n\n<execution>\n### 5.1 Register TODO Items\n\nUse TodoWrite to register each commit as a trackable item:\n```\n- [ ] Fixup: <description> -> <target-hash>\n- [ ] New: <description>\n- [ ] Rebase autosquash\n- [ ] Final verification\n```\n\n### 5.2 Fixup Commits (If Any)\n\n```bash\n# Stage files for each fixup\ngit add <files>\ngit commit --fixup=<target-hash>\n\n# Repeat for all fixups...\n\n# Single autosquash rebase at the end\nMERGE_BASE=$(git merge-base HEAD main 2>/dev/null || git merge-base HEAD master)\nGIT_SEQUENCE_EDITOR=: git rebase -i --autosquash $MERGE_BASE\n```\n\n### 5.3 New Commits (After Fixups)\n\nFor each new commit group, in dependency order:\n\n```bash\n# Stage files\ngit add <file1> <file2> ...\n\n# Verify staging\ngit diff --staged --stat\n\n# Commit with detected style\ngit commit -m \"<message-matching-COMMIT_CONFIG>\"\n\n# Verify\ngit log -1 --oneline\n```\n\n### 5.4 Commit Message Generation\n\n**Based on COMMIT_CONFIG from Phase 1:**\n\n```\nIF style == SEMANTIC AND language == KOREAN:\n -> \"feat: \uB85C\uADF8\uC778 \uAE30\uB2A5 \uCD94\uAC00\"\n \nIF style == SEMANTIC AND language == ENGLISH:\n -> \"feat: add login feature\"\n \nIF style == PLAIN AND language == KOREAN:\n -> \"\uB85C\uADF8\uC778 \uAE30\uB2A5 \uCD94\uAC00\"\n \nIF style == PLAIN AND language == ENGLISH:\n -> \"Add login feature\"\n \nIF style == SHORT:\n -> \"format\" / \"type fix\" / \"lint\"\n```\n\n**VALIDATION before each commit:**\n1. Does message match detected style?\n2. Does language match detected language?\n3. Is it similar to examples from git log?\n\nIf ANY check fails -> REWRITE message.\n```\n</execution>\n\n---\n\n## PHASE 6: Verification & Cleanup\n\n<verification>\n### 6.1 Post-Commit Verification\n\n```bash\n# Check working directory clean\ngit status\n\n# Review new history\ngit log --oneline $(git merge-base HEAD main 2>/dev/null || git merge-base HEAD master)..HEAD\n\n# Verify each commit is atomic\n# (mentally check: can each be reverted independently?)\n```\n\n### 6.2 Force Push Decision\n\n```\nIF fixup was used AND branch has upstream:\n -> Requires: git push --force-with-lease\n -> WARN user about force push implications\n \nIF only new commits:\n -> Regular: git push\n```\n\n### 6.3 Final Report\n\n```\nCOMMIT SUMMARY:\n Strategy: <what was done>\n Commits created: N\n Fixups merged: M\n \nHISTORY:\n <hash1> <message1>\n <hash2> <message2>\n ...\n\nNEXT STEPS:\n - git push [--force-with-lease]\n - Create PR if ready\n```\n</verification>";
1
+ export declare const GIT_MASTER_COMMIT_WORKFLOW_SECTION = "## PHASE 0: Parallel Context Gathering (MANDATORY FIRST STEP)\n\n<parallel_analysis>\n**Execute ALL of the following commands IN PARALLEL to minimize latency:**\n\n```bash\n# Group 1: Current state\ngit status\ngit diff --staged --stat\ngit diff --stat\n\n# Group 2: History context \ngit log -30 --oneline\ngit log -30 --pretty=format:\"%s\"\n\n# Group 3: Branch context\ngit branch --show-current\ngit merge-base HEAD main 2>/dev/null || git merge-base HEAD master 2>/dev/null\ngit rev-parse --abbrev-ref @{upstream} 2>/dev/null || echo \"NO_UPSTREAM\"\ngit log --oneline $(git merge-base HEAD main 2>/dev/null || git merge-base HEAD master 2>/dev/null)..HEAD 2>/dev/null\n```\n\n**Capture these data points simultaneously:**\n1. What files changed (staged vs unstaged)\n2. Recent 30 commit messages for style detection\n3. Branch position relative to main/master\n4. Whether branch has upstream tracking\n5. Commits that would go in PR (local only)\n</parallel_analysis>\n\n---\n\n## PHASE 1: Style Detection (BLOCKING - MUST OUTPUT BEFORE PROCEEDING)\n\n<style_detection>\n**THIS PHASE HAS MANDATORY OUTPUT** - You MUST print the analysis result before moving to Phase 2.\n\n### 1.1 Language Detection\n\n```\nCount from git log -30:\n- Chinese characters (\\u4e00-\\u9fff): N commits\n- English only: K commits\n- Mixed: L commits\n\nDECISION:\n- If Chinese >= 50% -> CHINESE\n- If English >= 50% -> ENGLISH\n- If Mixed -> Use MAJORITY language\n```\n\n### 1.2 Commit Style Classification\n\n| Style | Pattern | Example | Detection Regex |\n|-------|---------|---------|-----------------|\n| `SEMANTIC` | `type: message` or `type(scope): message` | `feat: add login` | `/^(feat\\|fix\\|chore\\|refactor\\|docs\\|test\\|ci\\|style\\|perf\\|build)(\\(.+\\))?:/` |\n| `PLAIN` | Just description, no prefix | `Add login feature` | No conventional prefix, >3 words |\n| `SENTENCE` | Full sentence style | `Implemented the new login flow` | Complete grammatical sentence |\n| `SHORT` | Minimal keywords | `format`, `lint` | 1-3 words only |\n\n**Detection Algorithm:**\n```\nsemantic_count = commits matching semantic regex\nplain_count = non-semantic commits with >3 words\nshort_count = commits with <=3 words\n\nIF semantic_count >= 15 (50%): STYLE = SEMANTIC\nELSE IF plain_count >= 15: STYLE = PLAIN \nELSE IF short_count >= 10: STYLE = SHORT\nELSE: STYLE = PLAIN (safe default)\n```\n\n### 1.3 MANDATORY OUTPUT (BLOCKING)\n\n**You MUST output this block before proceeding to Phase 2. NO EXCEPTIONS.**\n\n```\nSTYLE DETECTION RESULT\n======================\nAnalyzed: 30 commits from git log\n\nLanguage: [CHINESE | ENGLISH]\n - Chinese commits: N (X%)\n - English commits: K (Z%)\n\nStyle: [SEMANTIC | PLAIN | SENTENCE | SHORT]\n - Semantic (feat:, fix:, etc): N (X%)\n - Plain: M (Y%)\n - Short: K (Z%)\n\nReference examples from repo:\n 1. \"actual commit message from log\"\n 2. \"actual commit message from log\"\n 3. \"actual commit message from log\"\n\nAll commits will follow: [LANGUAGE] + [STYLE]\n```\n\n**IF YOU SKIP THIS OUTPUT, YOUR COMMITS WILL BE WRONG. STOP AND REDO.**\n</style_detection>\n\n---\n\n## PHASE 2: Branch Context Analysis\n\n<branch_analysis>\n### 2.1 Determine Branch State\n\n```\nBRANCH_STATE:\n current_branch: <name>\n has_upstream: true | false\n commits_ahead: N # Local-only commits\n merge_base: <hash>\n \nREWRITE_SAFETY:\n - If has_upstream AND commits_ahead > 0 AND already pushed:\n -> WARN before force push\n - If no upstream OR all commits local:\n -> Safe for aggressive rewrite (fixup, reset, rebase)\n - If on main/master:\n -> NEVER rewrite, only new commits\n```\n\n### 2.2 History Rewrite Strategy Decision\n\n```\nIF current_branch == main OR current_branch == master:\n -> STRATEGY = NEW_COMMITS_ONLY\n -> Never fixup, never rebase\n\nELSE IF commits_ahead == 0:\n -> STRATEGY = NEW_COMMITS_ONLY\n -> No history to rewrite\n\nELSE IF all commits are local (not pushed):\n -> STRATEGY = AGGRESSIVE_REWRITE\n -> Fixup freely, reset if needed, rebase to clean\n\nELSE IF pushed but not merged:\n -> STRATEGY = CAREFUL_REWRITE \n -> Fixup OK but warn about force push\n```\n</branch_analysis>\n\n---\n\n## PHASE 3: Atomic Unit Planning (BLOCKING - MUST OUTPUT BEFORE PROCEEDING)\n\n<atomic_planning>\n**THIS PHASE HAS MANDATORY OUTPUT** - You MUST print the commit plan before moving to Phase 4.\n\n### 3.0 Calculate Minimum Commit Count FIRST\n\n```\nFORMULA: min_commits = ceil(file_count / 3)\n\n 3 files -> min 1 commit\n 5 files -> min 2 commits\n 9 files -> min 3 commits\n15 files -> min 5 commits\n```\n\n**If your planned commit count < min_commits -> WRONG. SPLIT MORE.**\n\n### 3.1 Split by Directory/Module FIRST (Primary Split)\n\n**RULE: Different directories = Different commits (almost always)**\n\n```\nExample: 8 changed files\n - app/[locale]/page.tsx\n - app/[locale]/layout.tsx\n - components/demo/browser-frame.tsx\n - components/demo/shopify-full-site.tsx\n - components/pricing/pricing-table.tsx\n - e2e/navbar.spec.ts\n - messages/en.json\n - messages/ko.json\n\nWRONG: 1 commit \"Update landing page\" (LAZY, WRONG)\nWRONG: 2 commits (still too few)\n\nCORRECT: Split by directory/concern:\n - Commit 1: app/[locale]/page.tsx + layout.tsx (app layer)\n - Commit 2: components/demo/* (demo components)\n - Commit 3: components/pricing/* (pricing components)\n - Commit 4: e2e/* (tests)\n - Commit 5: messages/* (i18n)\n = 5 commits from 8 files (CORRECT)\n```\n\n### 3.2 Split by Concern SECOND (Secondary Split)\n\n**Within same directory, split by logical concern:**\n\n```\nExample: components/demo/ has 4 files\n - browser-frame.tsx (UI frame)\n - shopify-full-site.tsx (specific demo)\n - review-dashboard.tsx (NEW - specific demo)\n - tone-settings.tsx (NEW - specific demo)\n\nOption A (acceptable): 1 commit if ALL tightly coupled\nOption B (preferred): 2 commits\n - Commit: \"Update existing demo components\" (browser-frame, shopify)\n - Commit: \"Add new demo components\" (review-dashboard, tone-settings)\n```\n\n### 3.3 NEVER Do This (Anti-Pattern Examples)\n\n```\nWRONG: \"Refactor entire landing page\" - 1 commit with 15 files\nWRONG: \"Update components and tests\" - 1 commit mixing concerns\nWRONG: \"Big update\" - Any commit touching 5+ unrelated files\n\nRIGHT: Multiple focused commits, each 1-4 files max\nRIGHT: Each commit message describes ONE specific change\nRIGHT: A reviewer can understand each commit in 30 seconds\n```\n\n### 3.4 Implementation + Test Pairing (MANDATORY)\n\n```\nRULE: Test files MUST be in same commit as implementation\n\nTest patterns to match:\n- test_*.py <-> *.py\n- *_test.py <-> *.py\n- *.test.ts <-> *.ts\n- *.spec.ts <-> *.ts\n- __tests__/*.ts <-> *.ts\n- tests/*.py <-> src/*.py\n```\n\n### 3.5 MANDATORY JUSTIFICATION (Before Creating Commit Plan)\n\n**NON-NEGOTIABLE: Before finalizing your commit plan, you MUST:**\n\n```\nFOR EACH planned commit with 3+ files:\n 1. List all files in this commit\n 2. Write ONE sentence explaining why they MUST be together\n 3. If you can't write that sentence -> SPLIT\n \nTEMPLATE:\n\"Commit N contains [files] because [specific reason they are inseparable].\"\n\nVALID reasons:\n VALID: \"implementation file + its direct test file\"\n VALID: \"type definition + the only file that uses it\"\n VALID: \"migration + model change (would break without both)\"\n \nINVALID reasons (MUST SPLIT instead):\n INVALID: \"all related to feature X\" (too vague)\n INVALID: \"part of the same PR\" (not a reason)\n INVALID: \"they were changed together\" (not a reason)\n INVALID: \"makes sense to group\" (not a reason)\n```\n\n**OUTPUT THIS JUSTIFICATION in your analysis before executing commits.**\n\n### 3.7 Dependency Ordering\n\n```\nLevel 0: Utilities, constants, type definitions\nLevel 1: Models, schemas, interfaces\nLevel 2: Services, business logic\nLevel 3: API endpoints, controllers\nLevel 4: Configuration, infrastructure\n\nCOMMIT ORDER: Level 0 -> Level 1 -> Level 2 -> Level 3 -> Level 4\n```\n\n### 3.8 Create Commit Groups\n\nFor each logical feature/change:\n```yaml\n- group_id: 1\n feature: \"Add Shopify discount deletion\"\n files:\n - errors/shopify_error.py\n - types/delete_input.py\n - mutations/update_contract.py\n - tests/test_update_contract.py\n dependency_level: 2\n target_commit: null | <existing-hash> # null = new, hash = fixup\n```\n\n### 3.9 MANDATORY OUTPUT (BLOCKING)\n\n**You MUST output this block before proceeding to Phase 4. NO EXCEPTIONS.**\n\n```\nCOMMIT PLAN\n===========\nFiles changed: N\nMinimum commits required: ceil(N/3) = M\nPlanned commits: K\nStatus: K >= M (PASS) | K < M (FAIL - must split more)\n\nCOMMIT 1: [message in detected style]\n - path/to/file1.py\n - path/to/file1_test.py\n Justification: implementation + its test\n\nCOMMIT 2: [message in detected style]\n - path/to/file2.py\n Justification: independent utility function\n\nCOMMIT 3: [message in detected style]\n - config/settings.py\n - config/constants.py\n Justification: tightly coupled config changes\n\nExecution order: Commit 1 -> Commit 2 -> Commit 3\n(follows dependency: Level 0 -> Level 1 -> Level 2 -> ...)\n```\n\n**VALIDATION BEFORE EXECUTION:**\n- Each commit has <=4 files (or justified)\n- Each commit message matches detected STYLE + LANGUAGE\n- Test files paired with implementation\n- Different directories = different commits (or justified)\n- Total commits >= min_commits\n\n**IF ANY CHECK FAILS, DO NOT PROCEED. REPLAN.**\n</atomic_planning>\n\n---\n\n## PHASE 4: Commit Strategy Decision\n\n<strategy_decision>\n### 4.1 For Each Commit Group, Decide:\n\n```\nFIXUP if:\n - Change complements existing commit's intent\n - Same feature, fixing bugs or adding missing parts\n - Review feedback incorporation\n - Target commit exists in local history\n\nNEW COMMIT if:\n - New feature or capability\n - Independent logical unit\n - Different issue/ticket\n - No suitable target commit exists\n```\n\n### 4.2 History Rebuild Decision (Aggressive Option)\n\n```\nCONSIDER RESET & REBUILD when:\n - History is messy (many small fixups already)\n - Commits are not atomic (mixed concerns)\n - Dependency order is wrong\n \nRESET WORKFLOW:\n 1. git reset --soft $(git merge-base HEAD main)\n 2. All changes now staged\n 3. Re-commit in proper atomic units\n 4. Clean history from scratch\n \nONLY IF:\n - All commits are local (not pushed)\n - User explicitly allows OR branch is clearly WIP\n```\n\n### 4.3 Final Plan Summary\n\n```yaml\nEXECUTION_PLAN:\n strategy: FIXUP_THEN_NEW | NEW_ONLY | RESET_REBUILD\n fixup_commits:\n - files: [...]\n target: <hash>\n new_commits:\n - files: [...]\n message: \"...\"\n level: N\n requires_force_push: true | false\n```\n</strategy_decision>\n\n---\n\n## PHASE 5: Commit Execution\n\n<execution>\n### 5.1 Register TODO Items\n\nUse TodoWrite to register each commit as a trackable item:\n```\n- [ ] Fixup: <description> -> <target-hash>\n- [ ] New: <description>\n- [ ] Rebase autosquash\n- [ ] Final verification\n```\n\n### 5.2 Fixup Commits (If Any)\n\n```bash\n# Stage files for each fixup\ngit add <files>\ngit commit --fixup=<target-hash>\n\n# Repeat for all fixups...\n\n# Single autosquash rebase at the end\nMERGE_BASE=$(git merge-base HEAD main 2>/dev/null || git merge-base HEAD master)\nGIT_SEQUENCE_EDITOR=: git rebase -i --autosquash $MERGE_BASE\n```\n\n### 5.3 New Commits (After Fixups)\n\nFor each new commit group, in dependency order:\n\n```bash\n# Stage files\ngit add <file1> <file2> ...\n\n# Verify staging\ngit diff --staged --stat\n\n# Commit with detected style\ngit commit -m \"<message-matching-COMMIT_CONFIG>\"\n\n# Verify\ngit log -1 --oneline\n```\n\n### 5.4 Commit Message Generation\n\n**Based on COMMIT_CONFIG from Phase 1:**\n\n```\nIF style == SEMANTIC AND language == CHINESE:\n -> \"feat: \u6DFB\u52A0\u767B\u5F55\u529F\u80FD\"\n \nIF style == SEMANTIC AND language == ENGLISH:\n -> \"feat: add login feature\"\n\nIF style == PLAIN AND language == CHINESE:\n -> \"\u6DFB\u52A0\u767B\u5F55\u529F\u80FD\"\n\nIF style == PLAIN AND language == ENGLISH:\n -> \"Add login feature\"\n\nIF style == SHORT:\n -> \"format\" / \"type fix\" / \"lint\"\n```\n\n**VALIDATION before each commit:**\n1. Does message match detected style?\n2. Does language match detected language?\n3. Is it similar to examples from git log?\n\nIf ANY check fails -> REWRITE message.\n```\n</execution>\n\n---\n\n## PHASE 6: Verification & Cleanup\n\n<verification>\n### 6.1 Post-Commit Verification\n\n```bash\n# Check working directory clean\ngit status\n\n# Review new history\ngit log --oneline $(git merge-base HEAD main 2>/dev/null || git merge-base HEAD master)..HEAD\n\n# Verify each commit is atomic\n# (mentally check: can each be reverted independently?)\n```\n\n### 6.2 Force Push Decision\n\n```\nIF fixup was used AND branch has upstream:\n -> Requires: git push --force-with-lease\n -> WARN user about force push implications\n \nIF only new commits:\n -> Regular: git push\n```\n\n### 6.3 Final Report\n\n```\nCOMMIT SUMMARY:\n Strategy: <what was done>\n Commits created: N\n Fixups merged: M\n \nHISTORY:\n <hash1> <message1>\n <hash2> <message2>\n ...\n\nNEXT STEPS:\n - git push [--force-with-lease]\n - Create PR if ready\n```\n</verification>";
@@ -14,5 +14,4 @@ export declare function injectBoulderContinuation(input: {
14
14
  preferredTaskTitle?: string;
15
15
  backgroundManager?: BackgroundManager;
16
16
  sessionState: SessionState;
17
- language?: string;
18
17
  }): Promise<BoulderContinuationResult>;
@@ -7,5 +7,4 @@ export declare function createToolExecuteAfterHandler(input: {
7
7
  pendingTaskRefs: Map<string, PendingTaskRef>;
8
8
  autoCommit: boolean;
9
9
  getState: (sessionID: string) => SessionState;
10
- language?: string;
11
10
  }): (toolInput: ToolExecuteAfterInput, toolOutput: ToolExecuteAfterOutput) => Promise<void>;
@@ -4,7 +4,6 @@ export declare function createToolExecuteBeforeHandler(input: {
4
4
  ctx: PluginInput;
5
5
  pendingFilePaths: Map<string, string>;
6
6
  pendingTaskRefs: Map<string, PendingTaskRef>;
7
- language?: string;
8
7
  }): (toolInput: {
9
8
  tool: string;
10
9
  sessionID?: string;
@@ -11,8 +11,8 @@ export interface AtlasHookOptions {
11
11
  backgroundManager?: BackgroundManager;
12
12
  isContinuationStopped?: (sessionID: string) => boolean;
13
13
  agentOverrides?: AgentOverrides;
14
+ /** Enable auto-commit after each atomic task completion (default: true) */
14
15
  autoCommit?: boolean;
15
- language?: string;
16
16
  }
17
17
  export interface ToolExecuteAfterInput {
18
18
  tool: string;
@@ -3,5 +3,4 @@ import type { CompactionContextClient, CompactionContextInjector } from "./types
3
3
  export declare function createCompactionContextInjector(options?: {
4
4
  ctx?: CompactionContextClient;
5
5
  backgroundManager?: BackgroundManager;
6
- language?: string;
7
6
  }): CompactionContextInjector;
@@ -1,6 +1,6 @@
1
1
  import type { PluginInput } from "@opencode-ai/plugin";
2
2
  import { type ContextLimitModelCacheState } from "../shared/context-limit-resolver";
3
- export declare function createContextWindowMonitorHook(_ctx: PluginInput, modelCacheState?: ContextLimitModelCacheState, language?: string): {
3
+ export declare function createContextWindowMonitorHook(_ctx: PluginInput, modelCacheState?: ContextLimitModelCacheState): {
4
4
  "tool.execute.after": (input: {
5
5
  tool: string;
6
6
  sessionID: string;
@@ -1,5 +1,5 @@
1
1
  import type { PluginInput } from "@opencode-ai/plugin";
2
- export declare function createPrometheusMdOnlyHook(ctx: PluginInput, language?: string): {
2
+ export declare function createPrometheusMdOnlyHook(ctx: PluginInput): {
3
3
  "tool.execute.before": (input: {
4
4
  tool: string;
5
5
  sessionID: string;
@@ -10,5 +10,4 @@ export declare function injectContinuation(args: {
10
10
  resolvedInfo?: ResolvedMessageInfo;
11
11
  sessionStateStore: SessionStateStore;
12
12
  isContinuationStopped?: (sessionID: string) => boolean;
13
- language?: string;
14
13
  }): Promise<void>;
@@ -12,5 +12,4 @@ export declare function startCountdown(args: {
12
12
  skipAgents: string[];
13
13
  sessionStateStore: SessionStateStore;
14
14
  isContinuationStopped?: (sessionID: string) => boolean;
15
- language?: string;
16
15
  }): void;
@@ -7,7 +7,6 @@ export declare function createTodoContinuationHandler(args: {
7
7
  backgroundManager?: BackgroundManager;
8
8
  skipAgents?: string[];
9
9
  isContinuationStopped?: (sessionID: string) => boolean;
10
- language?: string;
11
10
  }): (input: {
12
11
  event: {
13
12
  type: string;
@@ -8,5 +8,4 @@ export declare function handleSessionIdle(args: {
8
8
  backgroundManager?: BackgroundManager;
9
9
  skipAgents?: string[];
10
10
  isContinuationStopped?: (sessionID: string) => boolean;
11
- language?: string;
12
11
  }): Promise<void>;
@@ -4,7 +4,6 @@ export interface TodoContinuationEnforcerOptions {
4
4
  backgroundManager?: BackgroundManager;
5
5
  skipAgents?: string[];
6
6
  isContinuationStopped?: (sessionID: string) => boolean;
7
- language?: string;
8
7
  }
9
8
  export interface TodoContinuationEnforcer {
10
9
  handler: (input: {
package/dist/index.js CHANGED
@@ -66321,7 +66321,7 @@ async function injectContinuation(args) {
66321
66321
  const incompleteTodos = todos.filter((todo) => todo.status !== "completed" && todo.status !== "cancelled");
66322
66322
  const todoList = incompleteTodos.map((todo) => `- [${todo.status}] ${todo.content}`).join(`
66323
66323
  `);
66324
- const prompt = `${getContinuationPrompt(args.language)}
66324
+ const prompt = `${getContinuationPrompt()}
66325
66325
 
66326
66326
  [Status: ${todos.length - freshIncompleteCount}/${todos.length} completed, ${freshIncompleteCount} remaining]
66327
66327
 
@@ -66420,8 +66420,7 @@ function startCountdown(args) {
66420
66420
  skipAgents,
66421
66421
  resolvedInfo,
66422
66422
  sessionStateStore,
66423
- isContinuationStopped,
66424
- language: args.language
66423
+ isContinuationStopped
66425
66424
  });
66426
66425
  }, COUNTDOWN_SECONDS * 1000);
66427
66426
  log(`[${HOOK_NAME}] Countdown started`, {
@@ -66445,8 +66444,7 @@ async function handleSessionIdle(args) {
66445
66444
  sessionStateStore,
66446
66445
  backgroundManager,
66447
66446
  skipAgents = DEFAULT_SKIP_AGENTS,
66448
- isContinuationStopped,
66449
- language
66447
+ isContinuationStopped
66450
66448
  } = args;
66451
66449
  log(`[${HOOK_NAME}] session.idle`, { sessionID });
66452
66450
  const state2 = sessionStateStore.getState(sessionID);
@@ -66593,8 +66591,7 @@ async function handleSessionIdle(args) {
66593
66591
  backgroundManager,
66594
66592
  skipAgents,
66595
66593
  sessionStateStore,
66596
- isContinuationStopped,
66597
- language
66594
+ isContinuationStopped
66598
66595
  });
66599
66596
  }
66600
66597
 
@@ -66735,8 +66732,7 @@ function createTodoContinuationHandler(args) {
66735
66732
  sessionStateStore,
66736
66733
  backgroundManager,
66737
66734
  skipAgents,
66738
- isContinuationStopped,
66739
- language: args.language
66735
+ isContinuationStopped
66740
66736
  });
66741
66737
  return;
66742
66738
  }
@@ -66970,8 +66966,7 @@ function createTodoContinuationEnforcer(ctx, options = {}) {
66970
66966
  const {
66971
66967
  backgroundManager,
66972
66968
  skipAgents = DEFAULT_SKIP_AGENTS,
66973
- isContinuationStopped,
66974
- language
66969
+ isContinuationStopped
66975
66970
  } = options;
66976
66971
  const sessionStateStore = createSessionStateStore();
66977
66972
  const markRecovering = (sessionID) => {
@@ -66992,8 +66987,7 @@ function createTodoContinuationEnforcer(ctx, options = {}) {
66992
66987
  sessionStateStore,
66993
66988
  backgroundManager,
66994
66989
  skipAgents,
66995
- isContinuationStopped,
66996
- language
66990
+ isContinuationStopped
66997
66991
  });
66998
66992
  const cancelAllCountdowns = () => {
66999
66993
  sessionStateStore.cancelAllCountdowns();
@@ -67024,7 +67018,7 @@ Complete your work thoroughly and methodically.`;
67024
67018
 
67025
67019
  ${reminderText}`;
67026
67020
  }
67027
- function createContextWindowMonitorHook(_ctx, modelCacheState, language) {
67021
+ function createContextWindowMonitorHook(_ctx, modelCacheState) {
67028
67022
  const remindedSessions = new Set;
67029
67023
  const tokenCache = new Map;
67030
67024
  const toolExecuteAfter = async (input, output) => {
@@ -67049,7 +67043,7 @@ function createContextWindowMonitorHook(_ctx, modelCacheState, language) {
67049
67043
  const limitTokens = actualLimit.toLocaleString();
67050
67044
  output.output += `
67051
67045
 
67052
- ${createContextReminder(actualLimit, language)}
67046
+ ${createContextReminder(actualLimit)}
67053
67047
  [Context Status: ${usedPct}% used (${usedTokens}/${limitTokens} tokens), ${remainingPct}% remaining]`;
67054
67048
  };
67055
67049
  const eventHandler = async ({ event }) => {
@@ -71155,6 +71149,7 @@ function createAnthropicContextWindowLimitRecoveryHook(ctx, options) {
71155
71149
  }
71156
71150
  // src/hooks/think-mode/detector.ts
71157
71151
  var MULTILINGUAL_KEYWORDS = [
71152
+ "\u6DF1\u601D\u719F\u8651",
71158
71153
  "\uC0DD\uAC01",
71159
71154
  "\uAC80\uD1A0",
71160
71155
  "\uC81C\uB300\uB85C",
@@ -79518,13 +79513,13 @@ git log --oneline $(git merge-base HEAD main 2>/dev/null || git merge-base HEAD
79518
79513
 
79519
79514
  \`\`\`
79520
79515
  Count from git log -30:
79521
- - Korean characters: N commits
79522
- - English only: M commits
79523
- - Mixed: K commits
79516
+ - Chinese characters (\\u4e00-\\u9fff): N commits
79517
+ - English only: K commits
79518
+ - Mixed: L commits
79524
79519
 
79525
79520
  DECISION:
79526
- - If Korean >= 50% -> KOREAN
79527
- - If English >= 50% -> ENGLISH
79521
+ - If Chinese >= 50% -> CHINESE
79522
+ - If English >= 50% -> ENGLISH
79528
79523
  - If Mixed -> Use MAJORITY language
79529
79524
  \`\`\`
79530
79525
 
@@ -79558,9 +79553,9 @@ STYLE DETECTION RESULT
79558
79553
  ======================
79559
79554
  Analyzed: 30 commits from git log
79560
79555
 
79561
- Language: [KOREAN | ENGLISH]
79562
- - Korean commits: N (X%)
79563
- - English commits: M (Y%)
79556
+ Language: [CHINESE | ENGLISH]
79557
+ - Chinese commits: N (X%)
79558
+ - English commits: K (Z%)
79564
79559
 
79565
79560
  Style: [SEMANTIC | PLAIN | SENTENCE | SHORT]
79566
79561
  - Semantic (feat:, fix:, etc): N (X%)
@@ -79914,18 +79909,18 @@ git log -1 --oneline
79914
79909
  **Based on COMMIT_CONFIG from Phase 1:**
79915
79910
 
79916
79911
  \`\`\`
79917
- IF style == SEMANTIC AND language == KOREAN:
79918
- -> "feat: \uB85C\uADF8\uC778 \uAE30\uB2A5 \uCD94\uAC00"
79912
+ IF style == SEMANTIC AND language == CHINESE:
79913
+ -> "feat: \u6DFB\u52A0\u767B\u5F55\u529F\u80FD"
79919
79914
 
79920
79915
  IF style == SEMANTIC AND language == ENGLISH:
79921
79916
  -> "feat: add login feature"
79922
-
79923
- IF style == PLAIN AND language == KOREAN:
79924
- -> "\uB85C\uADF8\uC778 \uAE30\uB2A5 \uCD94\uAC00"
79925
-
79917
+
79918
+ IF style == PLAIN AND language == CHINESE:
79919
+ -> "\u6DFB\u52A0\u767B\u5F55\u529F\u80FD"
79920
+
79926
79921
  IF style == PLAIN AND language == ENGLISH:
79927
79922
  -> "Add login feature"
79928
-
79923
+
79929
79924
  IF style == SHORT:
79930
79925
  -> "format" / "type fix" / "lint"
79931
79926
  \`\`\`
@@ -84959,7 +84954,7 @@ function isAllowedFile(filePath, workspaceRoot) {
84959
84954
 
84960
84955
  // src/hooks/prometheus-md-only/hook.ts
84961
84956
  var TASK_TOOLS = ["task", "call_omo_agent"];
84962
- function createPrometheusMdOnlyHook(ctx, language) {
84957
+ function createPrometheusMdOnlyHook(ctx) {
84963
84958
  return {
84964
84959
  "tool.execute.before": async (input, output) => {
84965
84960
  const agentName = await getAgentFromSession(input.sessionID, ctx.directory, ctx.client);
@@ -84970,7 +84965,7 @@ function createPrometheusMdOnlyHook(ctx, language) {
84970
84965
  if (TASK_TOOLS.includes(toolName)) {
84971
84966
  const prompt = output.args.prompt;
84972
84967
  if (prompt && !prompt.includes(SYSTEM_DIRECTIVE_PREFIX)) {
84973
- output.args.prompt = getPlanningConsultWarning(language) + prompt;
84968
+ output.args.prompt = getPlanningConsultWarning() + prompt;
84974
84969
  log(`[${HOOK_NAME4}] Injected planning warning to ${toolName}`, {
84975
84970
  sessionID: input.sessionID,
84976
84971
  tool: toolName,
@@ -85003,7 +84998,7 @@ function createPrometheusMdOnlyHook(ctx, language) {
85003
84998
  filePath,
85004
84999
  agent: agentName
85005
85000
  });
85006
- output.message = (output.message || "") + getPrometheusWorkflowReminder(language);
85001
+ output.message = (output.message || "") + getPrometheusWorkflowReminder();
85007
85002
  }
85008
85003
  log(`[${HOOK_NAME4}] Allowed: .sisyphus/*.md write permitted`, {
85009
85004
  sessionID: input.sessionID,
@@ -85963,7 +85958,7 @@ async function injectBoulderContinuation(input) {
85963
85958
  const preferredSessionContext = preferredTaskSessionId ? `
85964
85959
 
85965
85960
  [Preferred reuse session for current top-level plan task${preferredTaskTitle ? `: ${preferredTaskTitle}` : ""}: ${preferredTaskSessionId}]` : "";
85966
- const prompt = getBoulderContinuationPrompt(input.language).replace(/{PLAN_NAME}/g, planName) + `
85961
+ const prompt = getBoulderContinuationPrompt().replace(/{PLAN_NAME}/g, planName) + `
85967
85962
 
85968
85963
  [Status: ${total - remaining}/${total} completed, ${remaining} remaining]` + preferredSessionContext + worktreeContext;
85969
85964
  const continuationAgent = resolveRegisteredAgentName(agent ?? (isAgentRegistered("atlas") ? "atlas" : undefined));
@@ -86075,8 +86070,7 @@ async function injectContinuation2(input) {
86075
86070
  preferredTaskSessionId: preferredTaskSession?.session_id,
86076
86071
  preferredTaskTitle: preferredTaskSession?.task_title,
86077
86072
  backgroundManager: input.options?.backgroundManager,
86078
- sessionState: input.sessionState,
86079
- language: input.options?.language
86073
+ sessionState: input.sessionState
86080
86074
  });
86081
86075
  if (result === "injected") {
86082
86076
  if (input.sessionState.pendingRetryTimer) {
@@ -86772,7 +86766,7 @@ function createToolExecuteAfterHandler2(input) {
86772
86766
  filePath = toolOutput.metadata?.filePath;
86773
86767
  }
86774
86768
  if (filePath && !isSisyphusPath(filePath)) {
86775
- toolOutput.output = (toolOutput.output || "") + getDirectWorkReminder(input.language);
86769
+ toolOutput.output = (toolOutput.output || "") + getDirectWorkReminder();
86776
86770
  log(`[${HOOK_NAME7}] Direct work reminder appended`, {
86777
86771
  sessionID: toolInput.sessionID,
86778
86772
  tool: toolInput.tool,
@@ -86914,7 +86908,7 @@ function createToolExecuteBeforeHandler2(input) {
86914
86908
  if (toolInput.callID) {
86915
86909
  pendingFilePaths.set(toolInput.callID, filePath);
86916
86910
  }
86917
- const warning = getOrchestratorDelegationRequired(input.language).replace("$FILE_PATH", filePath);
86911
+ const warning = getOrchestratorDelegationRequired().replace("$FILE_PATH", filePath);
86918
86912
  toolOutput.message = (toolOutput.message || "") + warning;
86919
86913
  log(`[${HOOK_NAME7}] Injected delegation warning for direct file modification`, {
86920
86914
  sessionID: toolInput.sessionID,
@@ -86961,7 +86955,7 @@ function createToolExecuteBeforeHandler2(input) {
86961
86955
  }
86962
86956
  const prompt = toolOutput.args.prompt;
86963
86957
  if (prompt && !prompt.includes(SYSTEM_DIRECTIVE_PREFIX)) {
86964
- toolOutput.args.prompt = `<system-reminder>${getSingleTaskDirective(input.language)}</system-reminder>
86958
+ toolOutput.args.prompt = `<system-reminder>${getSingleTaskDirective()}</system-reminder>
86965
86959
  ` + prompt;
86966
86960
  log(`[${HOOK_NAME7}] Injected single-task directive to task`, {
86967
86961
  sessionID: toolInput.sessionID
@@ -86987,8 +86981,8 @@ function createAtlasHook(ctx, options) {
86987
86981
  }
86988
86982
  return {
86989
86983
  handler: createAtlasEventHandler({ ctx, options, sessions, getState }),
86990
- "tool.execute.before": createToolExecuteBeforeHandler2({ ctx, pendingFilePaths, pendingTaskRefs, language: options?.language }),
86991
- "tool.execute.after": createToolExecuteAfterHandler2({ ctx, pendingFilePaths, pendingTaskRefs, autoCommit, getState, language: options?.language })
86984
+ "tool.execute.before": createToolExecuteBeforeHandler2({ ctx, pendingFilePaths, pendingTaskRefs }),
86985
+ "tool.execute.after": createToolExecuteAfterHandler2({ ctx, pendingFilePaths, pendingTaskRefs, autoCommit, getState })
86992
86986
  };
86993
86987
  }
86994
86988
  // src/hooks/delegate-task-retry/patterns.ts
@@ -87652,7 +87646,6 @@ function createRecoveryLogic(ctx, getTailState) {
87652
87646
  function createCompactionContextInjector(options) {
87653
87647
  const ctx = options?.ctx;
87654
87648
  const backgroundManager = options?.backgroundManager;
87655
- const language = options?.language;
87656
87649
  const tailStates = new Map;
87657
87650
  const getTailState = (sessionID) => {
87658
87651
  const existing = tailStates.get(sessionID);
@@ -87684,7 +87677,7 @@ function createCompactionContextInjector(options) {
87684
87677
  });
87685
87678
  };
87686
87679
  const inject = (sessionID) => {
87687
- let prompt = getCompactionContextPrompt(language);
87680
+ let prompt = getCompactionContextPrompt();
87688
87681
  if (backgroundManager && sessionID) {
87689
87682
  const history = backgroundManager.taskHistory.formatForCompaction(sessionID);
87690
87683
  if (history) {
@@ -96888,14 +96881,14 @@ var ALLOWED_AGENTS = [
96888
96881
  "momus",
96889
96882
  "multimodal-looker"
96890
96883
  ];
96891
- var CALL_OMO_AGENT_DESCRIPTION = `Spawn explore/librarian agent or custom agents. run_in_background REQUIRED (true=async with task_id, false=sync).
96884
+ var CALL_OMO_AGENT_DESCRIPTION = `\u542F\u52A8 explore/librarian \u4EE3\u7406\u6216\u81EA\u5B9A\u4E49\u4EE3\u7406\u3002\u5FC5\u987B\u63D0\u4F9B run_in_background (true=\u5F02\u6B65\u8FD4\u56DE task_id, false=\u540C\u6B65)\u3002
96892
96885
 
96893
- Built-in agents:
96886
+ \u5185\u7F6E\u4EE3\u7406:
96894
96887
  {agents}
96895
96888
 
96896
- Custom agents registered via user or project agent directories are also supported.
96889
+ \u4E5F\u652F\u6301\u901A\u8FC7\u7528\u6237\u6216\u9879\u76EE\u4EE3\u7406\u76EE\u5F55\u6CE8\u518C\u7684\u81EA\u5B9A\u4E49\u4EE3\u7406\u3002
96897
96890
 
96898
- Pass \`session_id=<id>\` to continue previous agent with full context. Nested subagent depth is tracked automatically and blocked past the configured limit. Prompts MUST be in English. Use \`background_output\` for async results.`;
96891
+ \u4F20\u9012 \`session_id=<id>\` \u53EF\u7EE7\u7EED\u4E4B\u524D\u7684\u4EE3\u7406\u5E76\u4FDD\u7559\u5B8C\u6574\u4E0A\u4E0B\u6587\u3002\u5D4C\u5957 subagent \u6DF1\u5EA6\u81EA\u52A8\u8FFD\u8E2A\uFF0C\u8D85\u8FC7\u914D\u7F6E\u9650\u5236\u540E\u4F1A\u88AB\u963B\u6B62\u3002\u4F7F\u7528 \`background_output\` \u83B7\u53D6\u5F02\u6B65\u7ED3\u679C\u3002**\u63D0\u793A\u8BCD\u5FC5\u987B\u4F7F\u7528\u4E2D\u6587,\u4E0D\u5F97\u4F7F\u7528\u5176\u4ED6\u8BED\u8A00\u3002**`;
96899
96892
  // src/tools/call-omo-agent/tools.ts
96900
96893
  init_agent_display_names();
96901
96894
 
@@ -98194,10 +98187,10 @@ var FREE_OR_LOCAL_PROMPT_TOKEN_LIMIT = 24000;
98194
98187
  var PLAN_AGENT_PROMPT_BASE = `
98195
98188
 
98196
98189
  Additional requirements for this planning request:
98197
- - Answer in English.
98198
- - Write the plan in English.
98199
- - Plan well for ultrawork execution.
98200
- - Include a clear atomic commit strategy.`;
98190
+ - \u4F7F\u7528\u4E2D\u6587\u56DE\u7B54\u3002
98191
+ - \u4F7F\u7528\u4E2D\u6587\u64B0\u5199\u8BA1\u5212\u3002
98192
+ - \u4E3A\u9AD8\u6548\u5DE5\u4F5C\u505A\u597D\u89C4\u5212\u3002
98193
+ - \u5305\u542B\u6E05\u6670\u7684\u539F\u5B50\u5316\u63D0\u4EA4\u7B56\u7565\u3002`;
98201
98194
  var TDD_LINE = "- Use TDD-oriented planning.";
98202
98195
  function buildPlanAgentPromptAppend(tddEnabled) {
98203
98196
  if (tddEnabled) {
@@ -100612,46 +100605,46 @@ function createDelegateTaskPresentation(options) {
100612
100605
  return description2 ? ` - ${name}: ${description2}` : ` - ${name}`;
100613
100606
  }).join(`
100614
100607
  `);
100615
- const description = `Spawn agent task with category-based or direct agent selection.
100616
-
100617
- \u26A0\uFE0F CRITICAL: You MUST provide EITHER category OR subagent_type. Omitting BOTH will FAIL.
100618
-
100619
- **COMMON MISTAKE (DO NOT DO THIS):**
100608
+ const description = `\u57FA\u4E8E\u5206\u7C7B\u6216\u76F4\u63A5\u4EE3\u7406\u9009\u62E9\u7684\u4EFB\u52A1\u521B\u5EFA\u3002
100609
+
100610
+ \u26A0\uFE0F \u91CD\u8981: \u5FC5\u987B\u63D0\u4F9B category \u6216 subagent_type \u4E4B\u4E00\u3002\u4E24\u8005\u90FD\u7701\u7565\u5C06\u5BFC\u81F4\u5931\u8D25\u3002
100611
+
100612
+ **\u5E38\u89C1\u9519\u8BEF (\u8BF7\u52FF\u8FD9\u6837\u505A):**
100620
100613
  \`\`\`
100621
- task(description="...", prompt="...", run_in_background=false) // \u274C FAILS - missing category AND subagent_type
100614
+ task(description="...", prompt="...", run_in_background=false) // \u274C \u5931\u8D25 - \u7F3A\u5C11 category \u548C subagent_type
100622
100615
  \`\`\`
100623
-
100624
- **CORRECT - Using category:**
100616
+
100617
+ **\u6B63\u786E\u7528\u6CD5 - \u4F7F\u7528 category:**
100625
100618
  \`\`\`
100626
- task(category="quick", load_skills=[], description="Fix type error", prompt="...", run_in_background=false)
100619
+ task(category="quick", load_skills=[], description="\u4FEE\u590D\u7C7B\u578B\u9519\u8BEF", prompt="...", run_in_background=false)
100627
100620
  \`\`\`
100628
-
100629
- **CORRECT - Using subagent_type:**
100621
+
100622
+ **\u6B63\u786E\u7528\u6CD5 - \u4F7F\u7528 subagent_type:**
100630
100623
  \`\`\`
100631
- task(subagent_type="explore", load_skills=[], description="Find patterns", prompt="...", run_in_background=true)
100624
+ task(subagent_type="explore", load_skills=[], description="\u67E5\u627E\u6A21\u5F0F", prompt="...", run_in_background=true)
100632
100625
  \`\`\`
100633
-
100634
- REQUIRED: Provide ONE of:
100635
- - category: For task delegation (uses Sisyphus-Junior with category-optimized model)
100636
- - subagent_type: For direct agent invocation (explore, librarian, oracle, etc.)
100637
-
100638
- **DO NOT provide both.** If category is provided, subagent_type is ignored.
100639
-
100640
- - load_skills: ALWAYS REQUIRED. Pass [] if no skills needed, or ["skill-1", "skill-2"] for category tasks.
100641
- - category: Use predefined category \u2192 Spawns Sisyphus-Junior with category config
100642
- Available categories:
100626
+
100627
+ \u5FC5\u987B\u63D0\u4F9B\u4EE5\u4E0B\u4E4B\u4E00:
100628
+ - category: \u4EFB\u52A1\u59D4\u6258 (\u4F7F\u7528 Sisyphus-Junior \u53CA\u5206\u7C7B\u4F18\u5316\u6A21\u578B)
100629
+ - subagent_type: \u76F4\u63A5\u8C03\u7528\u4EE3\u7406 (explore, librarian, oracle \u7B49)
100630
+
100631
+ **\u4E0D\u8981\u540C\u65F6\u63D0\u4F9B\u4E24\u8005\u3002** \u5982\u679C\u63D0\u4F9B\u4E86 category\uFF0C\u5219 subagent_type \u4F1A\u88AB\u5FFD\u7565\u3002
100632
+
100633
+ - load_skills: \u59CB\u7EC8\u5FC5\u987B\u3002\u65E0\u9700\u6280\u80FD\u65F6\u4F20\u9012 []\uFF0C\u5206\u7C7B\u4EFB\u52A1\u53EF\u4F20\u9012 ["skill-1", "skill-2"]\u3002
100634
+ - category: \u4F7F\u7528\u9884\u5B9A\u4E49\u5206\u7C7B \u2192 \u542F\u52A8 Sisyphus-Junior \u5E76\u5E94\u7528\u5206\u7C7B\u914D\u7F6E
100635
+ \u53EF\u7528\u5206\u7C7B:
100643
100636
  ${categoryList}
100644
- - subagent_type: Use specific agent directly (explore, librarian, oracle, metis, momus)
100645
- - run_in_background: REQUIRED. true=async (returns task_id), false=sync (waits). Use background=true ONLY for parallel exploration with 5+ independent queries.
100646
- - task_id: Existing task to continue (from previous task output). Continues the same subagent session with FULL CONTEXT PRESERVED.
100647
- - command: The command that triggered this task (optional, for slash command tracking).
100648
-
100649
- **WHEN TO USE task_id:**
100650
- - Task failed/incomplete \u2192 task_id with "fix: [specific issue]"
100651
- - Need follow-up on previous result \u2192 task_id with additional question
100652
- - Multi-turn conversation with same agent \u2192 always task_id instead of new task
100653
-
100654
- Prompts MUST be in English.`;
100637
+ - subagent_type: \u76F4\u63A5\u4F7F\u7528\u6307\u5B9A\u4EE3\u7406 (explore, librarian, oracle, metis, momus)
100638
+ - run_in_background: \u5FC5\u987B\u63D0\u4F9B\u3002true=\u5F02\u6B65 (\u8FD4\u56DE task_id), false=\u540C\u6B65 (\u7B49\u5F85\u7ED3\u679C)\u3002\u4EC5\u5728\u5E76\u884C\u63A2\u7D22 (5+ \u4E2A\u72EC\u7ACB\u67E5\u8BE2) \u65F6\u4F7F\u7528 background=true\u3002
100639
+ - task_id: \u7EE7\u7EED\u73B0\u6709\u4EFB\u52A1 (\u6765\u81EA\u4E4B\u524D\u7684\u4EFB\u52A1\u8F93\u51FA)\u3002\u7EE7\u7EED\u540C\u4E00 subagent \u4F1A\u8BDD\uFF0C\u5B8C\u6574\u4FDD\u7559\u4E0A\u4E0B\u6587\u3002
100640
+ - command: \u89E6\u53D1\u6B64\u4EFB\u52A1\u7684\u547D\u4EE4 (\u53EF\u9009\uFF0C\u7528\u4E8E\u659C\u6760\u547D\u4EE4\u8FFD\u8E2A)\u3002
100641
+
100642
+ **\u4F55\u65F6\u4F7F\u7528 task_id:**
100643
+ - \u4EFB\u52A1\u5931\u8D25/\u4E0D\u5B8C\u6574 \u2192 \u4F7F\u7528 task_id \u5E76\u9644\u5E26 "fix: [\u5177\u4F53\u95EE\u9898]"
100644
+ - \u9700\u8981\u8DDF\u8FDB\u4E4B\u524D\u7684\u7ED3\u679C \u2192 \u4F7F\u7528 task_id \u5E76\u63D0\u51FA\u989D\u5916\u95EE\u9898
100645
+ - \u4E0E\u540C\u4E00\u4EE3\u7406\u7684\u591A\u8F6E\u5BF9\u8BDD \u2192 \u59CB\u7EC8\u4F7F\u7528 task_id \u800C\u975E\u65B0\u5EFA\u4EFB\u52A1
100646
+
100647
+ **\u63D0\u793A\u8BCD\u5FC5\u987B\u4F7F\u7528\u4E2D\u6587,\u4E0D\u8981\u4F7F\u7528\u5176\u4ED6\u8BED\u8A00\u3002**`;
100655
100648
  return {
100656
100649
  availableCategories,
100657
100650
  availableSkills,
@@ -102939,7 +102932,7 @@ function createRuntimeTmuxConfig(pluginConfig) {
102939
102932
  function createSessionHooks(args) {
102940
102933
  const { ctx, pluginConfig, modelCacheState, modelFallbackControllerAccessor, isHookEnabled, safeHookEnabled } = args;
102941
102934
  const safeHook = (hookName, factory) => safeCreateHook(hookName, factory, { enabled: safeHookEnabled });
102942
- const contextWindowMonitor = isHookEnabled("context-window-monitor") ? safeHook("context-window-monitor", () => createContextWindowMonitorHook(ctx, modelCacheState, pluginConfig.i18n?.language)) : null;
102935
+ const contextWindowMonitor = isHookEnabled("context-window-monitor") ? safeHook("context-window-monitor", () => createContextWindowMonitorHook(ctx, modelCacheState)) : null;
102943
102936
  const preemptiveCompaction = isHookEnabled("preemptive-compaction") && pluginConfig.experimental?.preemptive_compaction ? safeHook("preemptive-compaction", () => createPreemptiveCompactionHook(ctx, pluginConfig, modelCacheState)) : null;
102944
102937
  const sessionRecovery = isHookEnabled("session-recovery") ? safeHook("session-recovery", () => createSessionRecoveryHook(ctx, { experimental: pluginConfig.experimental })) : null;
102945
102938
  let sessionNotification = null;
@@ -103020,7 +103013,7 @@ function createSessionHooks(args) {
103020
103013
  const editErrorRecovery = isHookEnabled("edit-error-recovery") ? safeHook("edit-error-recovery", () => createEditErrorRecoveryHook(ctx)) : null;
103021
103014
  const delegateTaskRetry = isHookEnabled("delegate-task-retry") ? safeHook("delegate-task-retry", () => createDelegateTaskRetryHook(ctx)) : null;
103022
103015
  const startWork = isHookEnabled("start-work") ? safeHook("start-work", () => createStartWorkHook(ctx)) : null;
103023
- const prometheusMdOnly = isHookEnabled("prometheus-md-only") ? safeHook("prometheus-md-only", () => createPrometheusMdOnlyHook(ctx, pluginConfig.i18n?.language)) : null;
103016
+ const prometheusMdOnly = isHookEnabled("prometheus-md-only") ? safeHook("prometheus-md-only", () => createPrometheusMdOnlyHook(ctx)) : null;
103024
103017
  const sisyphusJuniorNotepad = isHookEnabled("sisyphus-junior-notepad") ? safeHook("sisyphus-junior-notepad", () => createSisyphusJuniorNotepadHook(ctx)) : null;
103025
103018
  const noSisyphusGpt = isHookEnabled("no-sisyphus-gpt") ? safeHook("no-sisyphus-gpt", () => createNoSisyphusGptHook(ctx)) : null;
103026
103019
  const noHephaestusNonGpt = isHookEnabled("no-hephaestus-non-gpt") ? safeHook("no-hephaestus-non-gpt", () => createNoHephaestusNonGptHook(ctx, {
@@ -103360,12 +103353,11 @@ function createContinuationHooks(args) {
103360
103353
  const stopContinuationGuard = isHookEnabled("stop-continuation-guard") ? safeHook("stop-continuation-guard", () => createStopContinuationGuardHook(ctx, {
103361
103354
  backgroundManager
103362
103355
  })) : null;
103363
- const compactionContextInjector = isHookEnabled("compaction-context-injector") ? safeHook("compaction-context-injector", () => createCompactionContextInjector({ ctx, backgroundManager, language: pluginConfig.i18n?.language })) : null;
103356
+ const compactionContextInjector = isHookEnabled("compaction-context-injector") ? safeHook("compaction-context-injector", () => createCompactionContextInjector({ ctx, backgroundManager })) : null;
103364
103357
  const compactionTodoPreserver = isHookEnabled("compaction-todo-preserver") ? safeHook("compaction-todo-preserver", () => createCompactionTodoPreserverHook(ctx)) : null;
103365
103358
  const todoContinuationEnforcer = isHookEnabled("todo-continuation-enforcer") ? safeHook("todo-continuation-enforcer", () => createTodoContinuationEnforcer(ctx, {
103366
103359
  backgroundManager,
103367
- isContinuationStopped: stopContinuationGuard?.isStopped,
103368
- language: pluginConfig.i18n?.language
103360
+ isContinuationStopped: stopContinuationGuard?.isStopped
103369
103361
  })) : null;
103370
103362
  const unstableAgentBabysitter = isHookEnabled("unstable-agent-babysitter") ? safeHook("unstable-agent-babysitter", () => createUnstableAgentBabysitter({ ctx, backgroundManager, pluginConfig })) : null;
103371
103363
  if (sessionRecovery) {
@@ -103394,8 +103386,7 @@ function createContinuationHooks(args) {
103394
103386
  backgroundManager,
103395
103387
  isContinuationStopped: (sessionID) => stopContinuationGuard?.isStopped(sessionID) ?? false,
103396
103388
  agentOverrides: pluginConfig.agents,
103397
- autoCommit: pluginConfig.start_work?.auto_commit,
103398
- language: pluginConfig.i18n?.language
103389
+ autoCommit: pluginConfig.start_work?.auto_commit
103399
103390
  })) : null;
103400
103391
  return {
103401
103392
  stopContinuationGuard,
@@ -130774,7 +130765,7 @@ class PostHog extends PostHogBackendClient {
130774
130765
  // package.json
130775
130766
  var package_default = {
130776
130767
  name: "@skj1724/oh-my-opencode",
130777
- version: "3.18.5",
130768
+ version: "3.18.7",
130778
130769
  description: "The Best AI Agent Harness - Batteries-Included OpenCode Plugin with Multi-Model Orchestration, Parallel Background Agents, and Crafted LSP/AST Tools",
130779
130770
  main: "./dist/index.js",
130780
130771
  types: "dist/index.d.ts",
@@ -1,2 +1,2 @@
1
1
  export declare const ALLOWED_AGENTS: readonly ["explore", "librarian", "oracle", "hephaestus", "metis", "momus", "multimodal-looker"];
2
- export declare const CALL_OMO_AGENT_DESCRIPTION = "Spawn explore/librarian agent or custom agents. run_in_background REQUIRED (true=async with task_id, false=sync).\n\nBuilt-in agents:\n{agents}\n\nCustom agents registered via user or project agent directories are also supported.\n\nPass `session_id=<id>` to continue previous agent with full context. Nested subagent depth is tracked automatically and blocked past the configured limit. Prompts MUST be in English. Use `background_output` for async results.";
2
+ export declare const CALL_OMO_AGENT_DESCRIPTION = "\u542F\u52A8 explore/librarian \u4EE3\u7406\u6216\u81EA\u5B9A\u4E49\u4EE3\u7406\u3002\u5FC5\u987B\u63D0\u4F9B run_in_background (true=\u5F02\u6B65\u8FD4\u56DE task_id, false=\u540C\u6B65)\u3002\n\n\u5185\u7F6E\u4EE3\u7406:\n{agents}\n\n\u4E5F\u652F\u6301\u901A\u8FC7\u7528\u6237\u6216\u9879\u76EE\u4EE3\u7406\u76EE\u5F55\u6CE8\u518C\u7684\u81EA\u5B9A\u4E49\u4EE3\u7406\u3002\n\n\u4F20\u9012 `session_id=<id>` \u53EF\u7EE7\u7EED\u4E4B\u524D\u7684\u4EE3\u7406\u5E76\u4FDD\u7559\u5B8C\u6574\u4E0A\u4E0B\u6587\u3002\u5D4C\u5957 subagent \u6DF1\u5EA6\u81EA\u52A8\u8FFD\u8E2A\uFF0C\u8D85\u8FC7\u914D\u7F6E\u9650\u5236\u540E\u4F1A\u88AB\u963B\u6B62\u3002\u4F7F\u7528 `background_output` \u83B7\u53D6\u5F02\u6B65\u7ED3\u679C\u3002**\u63D0\u793A\u8BCD\u5FC5\u987B\u4F7F\u7528\u4E2D\u6587,\u4E0D\u5F97\u4F7F\u7528\u5176\u4ED6\u8BED\u8A00\u3002**";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@skj1724/oh-my-opencode",
3
- "version": "3.18.5",
3
+ "version": "3.18.7",
4
4
  "description": "The Best AI Agent Harness - Batteries-Included OpenCode Plugin with Multi-Model Orchestration, Parallel Background Agents, and Crafted LSP/AST Tools",
5
5
  "main": "./dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -1,5 +0,0 @@
1
- /**
2
- * Chinese (Simplified) locale for System Directives.
3
- * Provides localized headers and prompt content for zh-CN language.
4
- */
5
- export declare const systemDirectiveLocale_zh_CN: Record<string, string>;