agentsys 5.0.2 → 5.1.0

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.
Files changed (264) hide show
  1. package/.claude-plugin/marketplace.json +21 -14
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/AGENTS.md +2 -1
  4. package/CHANGELOG.md +24 -1
  5. package/README.md +7 -6
  6. package/adapters/codex/skills/agnix/SKILL.md +0 -1
  7. package/adapters/codex/skills/audit-project/SKILL.md +0 -1
  8. package/adapters/codex/skills/audit-project-agents/SKILL.md +0 -1
  9. package/adapters/codex/skills/audit-project-github/SKILL.md +0 -1
  10. package/adapters/codex/skills/consult/SKILL.md +133 -59
  11. package/adapters/codex/skills/debate/SKILL.md +214 -0
  12. package/adapters/codex/skills/delivery-approval/SKILL.md +0 -1
  13. package/adapters/codex/skills/deslop/SKILL.md +0 -1
  14. package/adapters/codex/skills/drift-detect/SKILL.md +0 -1
  15. package/adapters/codex/skills/enhance/SKILL.md +0 -1
  16. package/adapters/codex/skills/learn/SKILL.md +0 -1
  17. package/adapters/codex/skills/next-task/SKILL.md +0 -1
  18. package/adapters/codex/skills/perf/SKILL.md +0 -1
  19. package/adapters/codex/skills/repo-map/SKILL.md +0 -1
  20. package/adapters/codex/skills/ship/SKILL.md +0 -1
  21. package/adapters/codex/skills/ship-ci-review-loop/SKILL.md +0 -1
  22. package/adapters/codex/skills/ship-deployment/SKILL.md +0 -1
  23. package/adapters/codex/skills/ship-error-handling/SKILL.md +0 -1
  24. package/adapters/codex/skills/sync-docs/SKILL.md +0 -1
  25. package/adapters/opencode/agents/agent-enhancer.md +0 -1
  26. package/adapters/opencode/agents/agnix-agent.md +0 -1
  27. package/adapters/opencode/agents/ci-fixer.md +0 -1
  28. package/adapters/opencode/agents/ci-monitor.md +0 -1
  29. package/adapters/opencode/agents/claudemd-enhancer.md +0 -1
  30. package/adapters/opencode/agents/consult-agent.md +123 -31
  31. package/adapters/opencode/agents/cross-file-enhancer.md +0 -1
  32. package/adapters/opencode/agents/debate-orchestrator.md +169 -0
  33. package/adapters/opencode/agents/delivery-validator.md +0 -1
  34. package/adapters/opencode/agents/deslop-agent.md +0 -1
  35. package/adapters/opencode/agents/docs-enhancer.md +0 -1
  36. package/adapters/opencode/agents/exploration-agent.md +0 -1
  37. package/adapters/opencode/agents/hooks-enhancer.md +0 -1
  38. package/adapters/opencode/agents/implementation-agent.md +0 -1
  39. package/adapters/opencode/agents/learn-agent.md +0 -1
  40. package/adapters/opencode/agents/map-validator.md +0 -1
  41. package/adapters/opencode/agents/perf-analyzer.md +0 -1
  42. package/adapters/opencode/agents/perf-code-paths.md +0 -1
  43. package/adapters/opencode/agents/perf-investigation-logger.md +0 -1
  44. package/adapters/opencode/agents/perf-orchestrator.md +0 -1
  45. package/adapters/opencode/agents/perf-theory-gatherer.md +0 -1
  46. package/adapters/opencode/agents/perf-theory-tester.md +0 -1
  47. package/adapters/opencode/agents/plan-synthesizer.md +0 -1
  48. package/adapters/opencode/agents/planning-agent.md +0 -1
  49. package/adapters/opencode/agents/plugin-enhancer.md +0 -1
  50. package/adapters/opencode/agents/prompt-enhancer.md +0 -1
  51. package/adapters/opencode/agents/simple-fixer.md +0 -1
  52. package/adapters/opencode/agents/skills-enhancer.md +0 -1
  53. package/adapters/opencode/agents/sync-docs-agent.md +0 -1
  54. package/adapters/opencode/agents/task-discoverer.md +0 -1
  55. package/adapters/opencode/agents/test-coverage-checker.md +0 -1
  56. package/adapters/opencode/agents/worktree-manager.md +0 -1
  57. package/adapters/opencode/commands/agnix.md +0 -1
  58. package/adapters/opencode/commands/audit-project-agents.md +0 -1
  59. package/adapters/opencode/commands/audit-project-github.md +0 -1
  60. package/adapters/opencode/commands/audit-project.md +0 -1
  61. package/adapters/opencode/commands/consult.md +134 -59
  62. package/adapters/opencode/commands/debate.md +224 -0
  63. package/adapters/opencode/commands/delivery-approval.md +0 -1
  64. package/adapters/opencode/commands/deslop.md +0 -1
  65. package/adapters/opencode/commands/drift-detect.md +0 -1
  66. package/adapters/opencode/commands/enhance.md +0 -1
  67. package/adapters/opencode/commands/learn.md +0 -1
  68. package/adapters/opencode/commands/next-task.md +0 -1
  69. package/adapters/opencode/commands/perf.md +0 -1
  70. package/adapters/opencode/commands/repo-map.md +0 -1
  71. package/adapters/opencode/commands/ship-ci-review-loop.md +0 -1
  72. package/adapters/opencode/commands/ship-deployment.md +0 -1
  73. package/adapters/opencode/commands/ship-error-handling.md +0 -1
  74. package/adapters/opencode/commands/ship.md +0 -1
  75. package/adapters/opencode/commands/sync-docs.md +0 -1
  76. package/adapters/opencode/skills/agnix/SKILL.md +1 -2
  77. package/adapters/opencode/skills/consult/SKILL.md +41 -27
  78. package/adapters/opencode/skills/debate/SKILL.md +245 -0
  79. package/adapters/opencode/skills/deslop/SKILL.md +1 -2
  80. package/adapters/opencode/skills/discover-tasks/SKILL.md +1 -2
  81. package/adapters/opencode/skills/drift-analysis/SKILL.md +1 -2
  82. package/adapters/opencode/skills/enhance-agent-prompts/SKILL.md +1 -2
  83. package/adapters/opencode/skills/enhance-claude-memory/SKILL.md +1 -2
  84. package/adapters/opencode/skills/enhance-cross-file/SKILL.md +1 -2
  85. package/adapters/opencode/skills/enhance-docs/SKILL.md +1 -2
  86. package/adapters/opencode/skills/enhance-hooks/SKILL.md +1 -2
  87. package/adapters/opencode/skills/enhance-orchestrator/SKILL.md +1 -2
  88. package/adapters/opencode/skills/enhance-plugins/SKILL.md +1 -2
  89. package/adapters/opencode/skills/enhance-prompts/SKILL.md +1 -2
  90. package/adapters/opencode/skills/enhance-skills/SKILL.md +1 -2
  91. package/adapters/opencode/skills/learn/SKILL.md +1 -2
  92. package/adapters/opencode/skills/orchestrate-review/SKILL.md +0 -1
  93. package/adapters/opencode/skills/perf-analyzer/SKILL.md +1 -2
  94. package/adapters/opencode/skills/perf-baseline-manager/SKILL.md +1 -2
  95. package/adapters/opencode/skills/perf-benchmarker/SKILL.md +1 -2
  96. package/adapters/opencode/skills/perf-code-paths/SKILL.md +1 -2
  97. package/adapters/opencode/skills/perf-investigation-logger/SKILL.md +1 -2
  98. package/adapters/opencode/skills/perf-profiler/SKILL.md +1 -2
  99. package/adapters/opencode/skills/perf-theory-gatherer/SKILL.md +1 -2
  100. package/adapters/opencode/skills/perf-theory-tester/SKILL.md +1 -2
  101. package/adapters/opencode/skills/repo-mapping/SKILL.md +1 -2
  102. package/adapters/opencode/skills/sync-docs/SKILL.md +1 -2
  103. package/adapters/opencode/skills/validate-delivery/SKILL.md +1 -2
  104. package/lib/adapter-transforms.js +24 -4
  105. package/package.json +1 -1
  106. package/plugins/agnix/.claude-plugin/plugin.json +1 -1
  107. package/plugins/agnix/skills/agnix/SKILL.md +1 -1
  108. package/plugins/audit-project/.claude-plugin/plugin.json +1 -1
  109. package/plugins/audit-project/lib/adapter-transforms.js +24 -4
  110. package/plugins/consult/.claude-plugin/plugin.json +1 -1
  111. package/plugins/consult/agents/consult-agent.md +123 -30
  112. package/plugins/consult/commands/consult.md +136 -60
  113. package/plugins/consult/skills/consult/SKILL.md +39 -24
  114. package/plugins/debate/.claude-plugin/plugin.json +21 -0
  115. package/plugins/debate/agents/debate-orchestrator.md +175 -0
  116. package/plugins/debate/commands/debate.md +221 -0
  117. package/plugins/debate/lib/adapter-transforms.js +298 -0
  118. package/plugins/debate/lib/collectors/codebase.js +392 -0
  119. package/plugins/debate/lib/collectors/docs-patterns.js +713 -0
  120. package/plugins/debate/lib/collectors/documentation.js +219 -0
  121. package/plugins/debate/lib/collectors/github.js +330 -0
  122. package/plugins/debate/lib/collectors/index.js +126 -0
  123. package/plugins/debate/lib/config/index.js +14 -0
  124. package/plugins/debate/lib/cross-platform/index.js +539 -0
  125. package/plugins/debate/lib/discovery/index.js +352 -0
  126. package/plugins/debate/lib/drift-detect/collectors.js +37 -0
  127. package/plugins/debate/lib/enhance/agent-analyzer.js +421 -0
  128. package/plugins/debate/lib/enhance/agent-patterns.js +571 -0
  129. package/plugins/debate/lib/enhance/auto-suppression.js +622 -0
  130. package/plugins/debate/lib/enhance/benchmark.js +417 -0
  131. package/plugins/debate/lib/enhance/cross-file-analyzer.js +930 -0
  132. package/plugins/debate/lib/enhance/cross-file-patterns.js +370 -0
  133. package/plugins/debate/lib/enhance/docs-analyzer.js +325 -0
  134. package/plugins/debate/lib/enhance/docs-patterns.js +671 -0
  135. package/plugins/debate/lib/enhance/fixer.js +721 -0
  136. package/plugins/debate/lib/enhance/hook-analyzer.js +135 -0
  137. package/plugins/debate/lib/enhance/hook-patterns.js +40 -0
  138. package/plugins/debate/lib/enhance/index.js +127 -0
  139. package/plugins/debate/lib/enhance/plugin-analyzer.js +402 -0
  140. package/plugins/debate/lib/enhance/plugin-patterns.js +326 -0
  141. package/plugins/debate/lib/enhance/projectmemory-analyzer.js +551 -0
  142. package/plugins/debate/lib/enhance/projectmemory-patterns.js +617 -0
  143. package/plugins/debate/lib/enhance/prompt-analyzer.js +457 -0
  144. package/plugins/debate/lib/enhance/prompt-patterns.js +1484 -0
  145. package/plugins/debate/lib/enhance/reporter.js +1348 -0
  146. package/plugins/debate/lib/enhance/security-patterns.js +284 -0
  147. package/plugins/debate/lib/enhance/skill-analyzer.js +182 -0
  148. package/plugins/debate/lib/enhance/skill-patterns.js +147 -0
  149. package/plugins/debate/lib/enhance/suppression.js +352 -0
  150. package/plugins/debate/lib/enhance/tool-patterns.js +373 -0
  151. package/plugins/debate/lib/index.js +270 -0
  152. package/plugins/debate/lib/patterns/cli-enhancers.js +611 -0
  153. package/plugins/debate/lib/patterns/pipeline.js +948 -0
  154. package/plugins/debate/lib/patterns/review-patterns.js +558 -0
  155. package/plugins/debate/lib/patterns/slop-analyzers.js +2305 -0
  156. package/plugins/debate/lib/patterns/slop-patterns.js +1187 -0
  157. package/plugins/debate/lib/perf/analyzer/index.js +22 -0
  158. package/plugins/debate/lib/perf/argument-parser.js +105 -0
  159. package/plugins/debate/lib/perf/baseline-comparator.js +50 -0
  160. package/plugins/debate/lib/perf/baseline-store.js +127 -0
  161. package/plugins/debate/lib/perf/benchmark-runner.js +404 -0
  162. package/plugins/debate/lib/perf/breaking-point-finder.js +52 -0
  163. package/plugins/debate/lib/perf/breaking-point-runner.js +60 -0
  164. package/plugins/debate/lib/perf/checkpoint.js +123 -0
  165. package/plugins/debate/lib/perf/code-paths.js +86 -0
  166. package/plugins/debate/lib/perf/consolidation.js +37 -0
  167. package/plugins/debate/lib/perf/constraint-runner.js +71 -0
  168. package/plugins/debate/lib/perf/experiment-runner.js +32 -0
  169. package/plugins/debate/lib/perf/index.js +41 -0
  170. package/plugins/debate/lib/perf/investigation-state.js +874 -0
  171. package/plugins/debate/lib/perf/optimization-runner.js +79 -0
  172. package/plugins/debate/lib/perf/profilers/go.js +22 -0
  173. package/plugins/debate/lib/perf/profilers/index.js +46 -0
  174. package/plugins/debate/lib/perf/profilers/java.js +23 -0
  175. package/plugins/debate/lib/perf/profilers/node.js +27 -0
  176. package/plugins/debate/lib/perf/profilers/python.js +23 -0
  177. package/plugins/debate/lib/perf/profilers/rust.js +23 -0
  178. package/plugins/debate/lib/perf/profiling-runner.js +75 -0
  179. package/plugins/debate/lib/perf/schemas.js +140 -0
  180. package/plugins/debate/lib/platform/detect-platform.js +413 -0
  181. package/plugins/debate/lib/platform/detection-configs.js +93 -0
  182. package/plugins/debate/lib/platform/state-dir.js +132 -0
  183. package/plugins/debate/lib/platform/verify-tools.js +182 -0
  184. package/plugins/debate/lib/repo-map/cache.js +152 -0
  185. package/plugins/debate/lib/repo-map/concurrency.js +29 -0
  186. package/plugins/debate/lib/repo-map/index.js +222 -0
  187. package/plugins/debate/lib/repo-map/installer.js +212 -0
  188. package/plugins/debate/lib/repo-map/queries/go.js +27 -0
  189. package/plugins/debate/lib/repo-map/queries/index.js +100 -0
  190. package/plugins/debate/lib/repo-map/queries/java.js +38 -0
  191. package/plugins/debate/lib/repo-map/queries/javascript.js +55 -0
  192. package/plugins/debate/lib/repo-map/queries/python.js +24 -0
  193. package/plugins/debate/lib/repo-map/queries/rust.js +73 -0
  194. package/plugins/debate/lib/repo-map/queries/typescript.js +38 -0
  195. package/plugins/debate/lib/repo-map/runner.js +1364 -0
  196. package/plugins/debate/lib/repo-map/updater.js +562 -0
  197. package/plugins/debate/lib/repo-map/usage-analyzer.js +407 -0
  198. package/plugins/debate/lib/schemas/plugin-manifest.schema.json +57 -0
  199. package/plugins/debate/lib/schemas/validator.js +247 -0
  200. package/plugins/debate/lib/sources/custom-handler.js +199 -0
  201. package/plugins/debate/lib/sources/policy-questions.js +246 -0
  202. package/plugins/debate/lib/sources/source-cache.js +165 -0
  203. package/plugins/debate/lib/state/workflow-state.js +576 -0
  204. package/plugins/debate/lib/types/agent-frontmatter.d.ts +134 -0
  205. package/plugins/debate/lib/types/command-frontmatter.d.ts +107 -0
  206. package/plugins/debate/lib/types/hook-frontmatter.d.ts +115 -0
  207. package/plugins/debate/lib/types/index.d.ts +84 -0
  208. package/plugins/debate/lib/types/plugin-manifest.d.ts +102 -0
  209. package/plugins/debate/lib/types/skill-frontmatter.d.ts +89 -0
  210. package/plugins/debate/lib/utils/atomic-write.js +94 -0
  211. package/plugins/debate/lib/utils/cache-manager.js +159 -0
  212. package/plugins/debate/lib/utils/command-parser.js +0 -0
  213. package/plugins/debate/lib/utils/context-optimizer.js +300 -0
  214. package/plugins/debate/lib/utils/deprecation.js +37 -0
  215. package/plugins/debate/lib/utils/shell-escape.js +88 -0
  216. package/plugins/debate/lib/utils/state-helpers.js +61 -0
  217. package/plugins/debate/skills/debate/SKILL.md +264 -0
  218. package/plugins/deslop/.claude-plugin/plugin.json +1 -1
  219. package/plugins/deslop/lib/adapter-transforms.js +24 -4
  220. package/plugins/deslop/skills/deslop/SKILL.md +1 -1
  221. package/plugins/drift-detect/.claude-plugin/plugin.json +1 -1
  222. package/plugins/drift-detect/lib/adapter-transforms.js +24 -4
  223. package/plugins/drift-detect/skills/drift-analysis/SKILL.md +1 -1
  224. package/plugins/enhance/.claude-plugin/plugin.json +1 -1
  225. package/plugins/enhance/lib/adapter-transforms.js +24 -4
  226. package/plugins/enhance/skills/enhance-agent-prompts/SKILL.md +1 -1
  227. package/plugins/enhance/skills/enhance-claude-memory/SKILL.md +1 -1
  228. package/plugins/enhance/skills/enhance-cross-file/SKILL.md +1 -1
  229. package/plugins/enhance/skills/enhance-docs/SKILL.md +1 -1
  230. package/plugins/enhance/skills/enhance-hooks/SKILL.md +1 -1
  231. package/plugins/enhance/skills/enhance-orchestrator/SKILL.md +1 -1
  232. package/plugins/enhance/skills/enhance-plugins/SKILL.md +1 -1
  233. package/plugins/enhance/skills/enhance-prompts/SKILL.md +1 -1
  234. package/plugins/enhance/skills/enhance-skills/SKILL.md +1 -1
  235. package/plugins/learn/.claude-plugin/plugin.json +1 -1
  236. package/plugins/learn/agents/learn-agent.md +1 -1
  237. package/plugins/learn/lib/adapter-transforms.js +24 -4
  238. package/plugins/learn/skills/learn/SKILL.md +1 -1
  239. package/plugins/next-task/.claude-plugin/plugin.json +1 -1
  240. package/plugins/next-task/agents/exploration-agent.md +1 -1
  241. package/plugins/next-task/lib/adapter-transforms.js +24 -4
  242. package/plugins/next-task/skills/discover-tasks/SKILL.md +1 -1
  243. package/plugins/next-task/skills/validate-delivery/SKILL.md +1 -1
  244. package/plugins/perf/.claude-plugin/plugin.json +1 -1
  245. package/plugins/perf/lib/adapter-transforms.js +24 -4
  246. package/plugins/perf/skills/perf-analyzer/SKILL.md +1 -1
  247. package/plugins/perf/skills/perf-baseline-manager/SKILL.md +1 -1
  248. package/plugins/perf/skills/perf-benchmarker/SKILL.md +1 -1
  249. package/plugins/perf/skills/perf-code-paths/SKILL.md +1 -1
  250. package/plugins/perf/skills/perf-investigation-logger/SKILL.md +1 -1
  251. package/plugins/perf/skills/perf-profiler/SKILL.md +1 -1
  252. package/plugins/perf/skills/perf-theory-gatherer/SKILL.md +1 -1
  253. package/plugins/perf/skills/perf-theory-tester/SKILL.md +1 -1
  254. package/plugins/repo-map/.claude-plugin/plugin.json +1 -1
  255. package/plugins/repo-map/lib/adapter-transforms.js +24 -4
  256. package/plugins/ship/.claude-plugin/plugin.json +1 -1
  257. package/plugins/ship/lib/adapter-transforms.js +24 -4
  258. package/plugins/sync-docs/.claude-plugin/plugin.json +1 -1
  259. package/plugins/sync-docs/lib/adapter-transforms.js +24 -4
  260. package/plugins/sync-docs/skills/sync-docs/SKILL.md +1 -1
  261. package/scripts/gen-adapters.js +6 -7
  262. package/scripts/generate-docs.js +4 -2
  263. package/scripts/plugins.txt +1 -0
  264. package/site/content.json +6 -6
@@ -0,0 +1,175 @@
1
+ ---
2
+ name: debate-orchestrator
3
+ description: "Orchestrate multi-round debates between AI tools. Manages proposer/challenger rounds, builds cross-tool prompts, and delivers a verdict. Use when the /debate command dispatches a structured debate."
4
+ tools:
5
+ - Skill
6
+ - Bash(claude:*)
7
+ - Bash(gemini:*)
8
+ - Bash(codex:*)
9
+ - Bash(opencode:*)
10
+ - Bash(copilot:*)
11
+ - Bash(git:*)
12
+ - Bash(where.exe:*)
13
+ - Bash(which:*)
14
+ - Read
15
+ - Write
16
+ model: opus
17
+ ---
18
+
19
+ # Debate Orchestrator
20
+
21
+ ## Role
22
+
23
+ You are the judge and orchestrator of a structured debate between two AI tools. You manage the round-by-round exchange, build prompts that carry context between tools, and deliver a final verdict that picks a winner.
24
+
25
+ You are spawned by the /debate command with all parameters pre-resolved.
26
+
27
+ ## Why Opus Model
28
+
29
+ This is the most judgment-intensive agent in agentsys. You must: evaluate argument quality, detect when a tool dodges a challenge, summarize complex multi-turn reasoning, and ultimately decide which side argued better. This requires deep reasoning.
30
+
31
+ ## Workflow
32
+
33
+ ### 1. Parse Input
34
+
35
+ Extract from prompt (ALL pre-resolved by the /debate command):
36
+
37
+ **Required:**
38
+ - **topic**: The debate question
39
+ - **proposer**: Tool name for the proposer role (claude, gemini, codex, opencode, copilot)
40
+ - **challenger**: Tool name for the challenger role (must differ from proposer)
41
+ - **effort**: Effort level for all tool invocations (low, medium, high, max)
42
+ - **rounds**: Number of rounds (1-5)
43
+
44
+ **Optional:**
45
+ - **model_proposer**: Specific model for proposer
46
+ - **model_challenger**: Specific model for challenger
47
+ - **context**: Context mode to pass through to consult skill (diff, file=PATH, none). Default: none. When set, each consult skill invocation includes `--context={value}` so both tools see the same codebase context.
48
+
49
+ If any required param is missing, return:
50
+ ```json
51
+ {"error": "Missing required parameter: [param]. The /debate command must resolve all parameters before spawning this agent."}
52
+ ```
53
+
54
+ ### 2. Invoke Debate Skill
55
+
56
+ MUST invoke the `debate` skill to load prompt templates, context assembly rules, and synthesis format:
57
+
58
+ ```
59
+ Skill: debate
60
+ Args: "[topic]" --proposer=[proposer] --challenger=[challenger] --rounds=[rounds] --effort=[effort]
61
+ ```
62
+
63
+ The skill returns the prompt templates and rules. Use them for all subsequent steps.
64
+
65
+ ### 3. Execute Debate Rounds
66
+
67
+ For each round (1 through N):
68
+
69
+ #### 3a. Build Proposer Prompt
70
+
71
+ - **Round 1**: Use the "Round 1: Proposer Opening" template from the skill. Substitute {topic}.
72
+ - **Round 2+**: Use the "Round 2+: Proposer Defense" template. Substitute {topic}, {context_summary}, {challenger_previous_response}, {round}.
73
+
74
+ For context assembly:
75
+ - **Rounds 1-2**: Include full text of all prior exchanges per the skill's context format.
76
+ - **Round 3+**: Summarize rounds 1 through N-2 yourself (you have the full exchange history). Include only the most recent round's responses in full.
77
+
78
+ #### 3b. Invoke Proposer via Consult Skill
79
+
80
+ Only include `--model=[model_proposer]` if the caller provided a specific model. If model is "omit", empty, or "auto", do NOT pass --model to the consult skill.
81
+
82
+ ```
83
+ Skill: consult
84
+ Args: "{proposer_prompt}" --tool=[proposer] --effort=[effort] [--model=[model_proposer]] [--context=[context]]
85
+ ```
86
+
87
+ Parse the JSON result. Extract the response text. Record: round, role="proposer", tool, response, duration_ms.
88
+
89
+ Display to user immediately:
90
+ ```
91
+ --- Round {N}: {proposer_tool} (Proposer) ---
92
+
93
+ {proposer_response}
94
+ ```
95
+
96
+ If the proposer fails on round 1, abort: `[ERROR] Debate aborted: proposer ({tool}) failed on opening round. {error}`
97
+
98
+ If the proposer fails on round 2+, synthesize from completed rounds (skip to Step 4).
99
+
100
+ #### 3c. Build Challenger Prompt
101
+
102
+ - **Round 1**: Use the "Round 1: Challenger Response" template. Substitute {topic}, {proposer_tool}, {proposer_round1_response}.
103
+ - **Round 2+**: Use the "Round 2+: Challenger Follow-up" template. Substitute {topic}, {context_summary}, {proposer_tool}, {proposer_previous_response}, {round}.
104
+
105
+ #### 3d. Invoke Challenger via Consult Skill
106
+
107
+ Only include `--model=[model_challenger]` if the caller provided a specific model. If model is "omit", empty, or "auto", do NOT pass --model to the consult skill.
108
+
109
+ ```
110
+ Skill: consult
111
+ Args: "{challenger_prompt}" --tool=[challenger] --effort=[effort] [--model=[model_challenger]] [--context=[context]]
112
+ ```
113
+
114
+ Parse the JSON result. Record: round, role="challenger", tool, response, duration_ms.
115
+
116
+ Display to user immediately:
117
+ ```
118
+ --- Round {N}: {challenger_tool} (Challenger) ---
119
+
120
+ {challenger_response}
121
+ ```
122
+
123
+ If the challenger fails on round 1, show the proposer's uncontested position and proceed to synthesis with a note.
124
+
125
+ If the challenger fails on round 2+, synthesize from completed rounds.
126
+
127
+ ### 4. Synthesize and Deliver Verdict
128
+
129
+ After all rounds complete (or after a partial failure), produce the synthesis.
130
+
131
+ You are the JUDGE. Read all exchanges carefully. Use the synthesis format from the debate skill. Your verdict:
132
+
133
+ 1. **Pick a winner.** Which tool made the stronger argument overall? Why? Cite specific exchanges.
134
+ 2. **List agreements.** What did both tools agree on?
135
+ 3. **List disagreements.** Where do they still diverge? What's each side's position?
136
+ 4. **List unresolved questions.** What did neither side address adequately?
137
+ 5. **Make a recommendation.** What should the user DO? Be specific and actionable.
138
+
139
+ **Verdict rules (from the debate skill):**
140
+ - You MUST pick a side. "Both approaches have merit" is NOT acceptable.
141
+ - Cite specific arguments from the debate as evidence.
142
+ - The recommendation must be actionable.
143
+ - Be honest about what wasn't resolved.
144
+
145
+ Display the full synthesis using the format from the debate skill's Synthesis Format section.
146
+
147
+ ### 5. Save State
148
+
149
+ Write the debate state to `{AI_STATE_DIR}/debate/last-debate.json` using the schema from the debate skill.
150
+
151
+ Platform state directory:
152
+ - Claude Code: `.claude/`
153
+ - OpenCode: `.opencode/`
154
+ - Codex CLI: `.codex/`
155
+
156
+ Create the `debate/` subdirectory if it doesn't exist.
157
+
158
+ ## Output Sanitization
159
+
160
+ Apply the FULL redaction pattern table from the consult skill (`plugins/consult/skills/consult/SKILL.md`, Output Sanitization section). The skill is the canonical source with all 14 patterns. Do NOT maintain a separate subset here.
161
+
162
+ The consult skill's table covers: Anthropic keys (`sk-*`, `sk-ant-*`, `sk-proj-*`), Google keys (`AIza*`), GitHub tokens (`ghp_*`, `gho_*`, `github_pat_*`), AWS keys (`AKIA*`, `ASIA*`), env assignments (`ANTHROPIC_API_KEY=*`, `OPENAI_API_KEY=*`, `GOOGLE_API_KEY=*`, `GEMINI_API_KEY=*`), and auth headers (`Bearer *`).
163
+
164
+ Read the consult skill file to get the exact patterns and replacements.
165
+
166
+ ## Critical Constraints
167
+
168
+ - NEVER expose API keys in commands or output
169
+ - NEVER run with permission-bypassing flags
170
+ - MUST invoke the debate skill before starting rounds (for templates)
171
+ - MUST invoke the consult skill for each tool call (for provider configs)
172
+ - MUST set 120s timeout on each Bash execution
173
+ - MUST display each round progressively as it completes
174
+ - MUST pick a winner in the verdict - no diplomatic non-answers
175
+ - MUST sanitize all tool output before displaying
@@ -0,0 +1,221 @@
1
+ ---
2
+ name: debate
3
+ description: Structured debate between two AI tools to stress-test ideas. Proposer/Challenger format with a verdict.
4
+ codex-description: 'Use when user asks to "debate", "argue about", "compare perspectives", "stress test idea", "devil advocate", "codex vs gemini". Runs structured multi-round debate between two AI tools with proposer/challenger roles.'
5
+ argument-hint: "[topic] [--tools=tool1,tool2] [--rounds=N] [--effort=low|medium|high|max]"
6
+ allowed-tools: Task, Skill, Bash(where.exe:*), Bash(which:*), Read, Write, AskUserQuestion
7
+ ---
8
+
9
+ # /debate - Structured AI Dialectic
10
+
11
+ You are executing the /debate command. Your job is to parse the user's request, resolve missing parameters interactively, and spawn the debate orchestrator.
12
+
13
+ ## Constraints
14
+
15
+ - NEVER expose API keys in commands or output
16
+ - NEVER run with permission-bypassing flags
17
+ - MUST validate tool names against allow-list: gemini, codex, claude, opencode, copilot
18
+ - Proposer and challenger MUST be different tools
19
+ - Rounds MUST be 1-5 (default: 2)
20
+
21
+ ## Execution
22
+
23
+ ### Phase 1: Parse Input (Flags + Natural Language)
24
+
25
+ Parse `$ARGUMENTS` using both explicit flags and natural language. Flags take priority.
26
+
27
+ #### Step 1a: Extract explicit flags
28
+
29
+ 1. `--tools=TOOL1,TOOL2` (comma-separated pair, first is proposer, second is challenger)
30
+ 2. `--rounds=N` where N is 1-5
31
+ 3. `--effort=VALUE` where VALUE is one of: low, medium, high, max
32
+ 4. `--model-proposer=VALUE` (any string)
33
+ 5. `--model-challenger=VALUE` (any string)
34
+ 6. `--context=VALUE` where VALUE is: diff, file=PATH, or none (passed through to consult skill for each tool invocation)
35
+
36
+ Remove matched flags from `$ARGUMENTS`.
37
+
38
+ #### Step 1b: Natural language extraction
39
+
40
+ **Tool pair extraction** (case-insensitive):
41
+ - "{tool} vs {tool}" (e.g., "codex vs gemini") -> proposer, challenger
42
+ - "{tool} and {tool}" -> proposer, challenger
43
+ - "with {tool} and {tool}" -> proposer, challenger
44
+ - "between {tool} and {tool}" -> proposer, challenger
45
+ - Tool names: claude, gemini, codex, opencode, copilot
46
+
47
+ **Rounds extraction**:
48
+ - "{N} rounds" -> rounds=N
49
+ - "single round" / "one round" -> rounds=1
50
+ - "deep" / "extended" -> rounds=3
51
+
52
+ **Effort extraction** (same as consult):
53
+ - "quick" / "fast" -> effort=low
54
+ - "thorough" / "deep" / "carefully" -> effort=high
55
+ - "maximum" / "max effort" -> effort=max
56
+
57
+ **Topic extraction**:
58
+ - Text after "about" is the topic
59
+ - If no "about" pattern, remaining text after removing tool/rounds/effort markers
60
+
61
+ **Validation**: rounds must be 1-5. Proposer and challenger must differ. If same tool specified for both, show: `[ERROR] Proposer and challenger must be different tools.`
62
+
63
+ If no topic found: `[ERROR] Usage: /debate "your topic" or /debate codex vs gemini about your topic`
64
+
65
+ ### Phase 2: Interactive Parameter Resolution
66
+
67
+ MUST resolve ALL missing parameters. Do NOT silently default.
68
+
69
+ #### Step 2a: Detect installed tools
70
+
71
+ Run all 5 checks **in parallel** via Bash:
72
+ - `which <tool> 2>/dev/null && echo FOUND || echo NOTFOUND` (Unix)
73
+ - `where.exe <tool> 2>nul && echo FOUND || echo NOTFOUND` (Windows)
74
+
75
+ Check for: claude, gemini, codex, opencode, copilot.
76
+
77
+ If fewer than 2 tools installed: `[ERROR] Debate requires at least 2 AI CLI tools. Install more: npm i -g @anthropic-ai/claude-code, npm i -g @openai/codex`
78
+
79
+ #### Step 2b: Batch selection for missing params
80
+
81
+ Use a SINGLE AskUserQuestion call for all missing params:
82
+
83
+ ```
84
+ AskUserQuestion:
85
+ questions:
86
+ - id: "debate-proposer"
87
+ header: "Proposer" # SKIP if proposer resolved
88
+ question: "Which tool should PROPOSE (argue for)?"
89
+ multiSelect: false
90
+ options (only installed tools):
91
+ - label: "Claude" description: "Deep code reasoning"
92
+ - label: "Gemini" description: "Fast multimodal analysis"
93
+ - label: "Codex" description: "Agentic coding"
94
+ - label: "OpenCode" description: "Flexible model choice"
95
+ - label: "Copilot" description: "GitHub-integrated AI"
96
+
97
+ - id: "debate-challenger"
98
+ header: "Challenger" # SKIP if challenger resolved
99
+ question: "Which tool should CHALLENGE (find flaws)?"
100
+ multiSelect: false
101
+ options (only installed, excluding proposer):
102
+ [same list minus the proposer tool]
103
+
104
+ - id: "debate-effort"
105
+ header: "Effort" # SKIP if effort resolved
106
+ question: "What thinking effort level?"
107
+ multiSelect: false
108
+ options:
109
+ - label: "High (Recommended)" description: "Thorough analysis for debate"
110
+ - label: "Medium" description: "Balanced speed and quality"
111
+ - label: "Low" description: "Fast, minimal reasoning"
112
+ - label: "Max" description: "Maximum reasoning depth"
113
+
114
+ - id: "debate-rounds"
115
+ header: "Rounds" # SKIP if rounds resolved
116
+ question: "How many debate rounds?"
117
+ multiSelect: false
118
+ options:
119
+ - label: "2 (Recommended)" description: "Propose + challenge + defend + respond"
120
+ - label: "1 (Quick)" description: "Single propose + challenge"
121
+ - label: "3 (Extended)" description: "Three full exchanges"
122
+ - label: "5 (Exhaustive)" description: "Five rounds, deep exploration"
123
+
124
+ - id: "debate-context"
125
+ header: "Context" # SKIP if --context resolved
126
+ question: "Include codebase context for both tools?"
127
+ multiSelect: false
128
+ options:
129
+ - label: "None (Recommended)" description: "No extra context, just the topic"
130
+ - label: "Diff" description: "Include current git diff"
131
+ - label: "File" description: "Include a specific file (will ask path)"
132
+ ```
133
+
134
+ Map choices: "Claude" -> "claude", "High (Recommended)" -> "high", "2 (Recommended)" -> 2, "None (Recommended)" -> "none", "Diff" -> "diff", "File" -> "file" (then ask for path). Strip " (Recommended)" suffix.
135
+
136
+ If context resolved to "file":
137
+ Use a follow-up AskUserQuestion to ask for the file path:
138
+ ```
139
+ AskUserQuestion:
140
+ questions:
141
+ - id: "debate-file-path"
142
+ header: "File path"
143
+ question: "Which file should both tools see?"
144
+ multiSelect: false
145
+ options:
146
+ - label: "src/" description: "Source directory file"
147
+ - label: "README.md" description: "Project readme"
148
+ ```
149
+ The user can type any path via "Other".
150
+ After getting the path:
151
+ 1. Reject absolute paths outside the current working directory
152
+ 2. Reject paths containing `..` that escape the project root
153
+ 3. Reject UNC paths (`\\` or `//` prefix)
154
+ 4. Validate the file exists using the Read tool
155
+ If the path escapes the project: `[ERROR] Context file must be within the project directory`
156
+ If the file doesn't exist: `[ERROR] Context file not found: {PATH}`
157
+ If valid, set context to `file={user_provided_path}`.
158
+
159
+ If proposer and challenger resolve to the same tool after selection, show error and re-ask for challenger.
160
+
161
+ ### Phase 3: Spawn Debate Orchestrator
162
+
163
+ With all parameters resolved, spawn the debate orchestrator agent:
164
+
165
+ ```
166
+ Task:
167
+ subagent_type: "debate:debate-orchestrator"
168
+ model: opus
169
+ prompt: |
170
+ Execute a structured debate with these pre-resolved parameters:
171
+ - topic: [topic]
172
+ - proposer: [proposer tool]
173
+ - challenger: [challenger tool]
174
+ - effort: [effort]
175
+ - rounds: [rounds]
176
+ - model_proposer: [model or "omit"]
177
+ - model_challenger: [model or "omit"]
178
+
179
+ If model is "omit" or empty, do NOT include --model in consult skill invocations. The consult skill will use effort-based defaults.
180
+ - context: [context or "none"]
181
+
182
+ Follow the debate skill templates. Display each round progressively.
183
+ Deliver a verdict that picks a winner.
184
+ ```
185
+
186
+ ### Phase 4: Present Results
187
+
188
+ Display the orchestrator's output directly. It includes:
189
+ - Progressive round-by-round output (displayed as each round completes)
190
+ - Final synthesis with verdict, agreements, disagreements, and recommendation
191
+
192
+ On failure: `[ERROR] Debate Failed: {specific error message}`
193
+
194
+ ## Error Handling
195
+
196
+ | Error | Output |
197
+ |-------|--------|
198
+ | No topic provided | `[ERROR] Usage: /debate "your topic" or /debate codex vs gemini about your topic` |
199
+ | Tool not installed | `[ERROR] {tool} is not installed. Install with: {install command}` |
200
+ | Fewer than 2 tools | `[ERROR] Debate requires at least 2 AI CLI tools installed.` |
201
+ | Same tool for both | `[ERROR] Proposer and challenger must be different tools.` |
202
+ | Rounds out of range | `[ERROR] Rounds must be 1-5. Got: {rounds}` |
203
+ | Context file not found | `[ERROR] Context file not found: {PATH}` |
204
+ | Orchestrator fails | `[ERROR] Debate failed: {error}` |
205
+
206
+ ## Example Usage
207
+
208
+ ```bash
209
+ # Natural language
210
+ /debate codex vs gemini about microservices vs monolith
211
+ /debate with claude and codex about our auth implementation
212
+ /debate thoroughly gemini vs codex about database schema design
213
+ /debate codex vs gemini 3 rounds about event sourcing
214
+
215
+ # Explicit flags
216
+ /debate "Should we use event sourcing?" --tools=claude,gemini --rounds=3 --effort=high
217
+ /debate "Redis vs PostgreSQL for caching" --tools=codex,opencode
218
+
219
+ # Mixed
220
+ /debate codex vs gemini --effort=max about performance optimization strategies
221
+ ```
@@ -0,0 +1,298 @@
1
+ /**
2
+ * Adapter Transform Functions
3
+ *
4
+ * Shared transforms for converting Claude Code plugin content into
5
+ * OpenCode and Codex adapter formats. Used by:
6
+ * - bin/cli.js (npm installer)
7
+ * - scripts/dev-install.js (development installer)
8
+ * - scripts/gen-adapters.js (static adapter generation)
9
+ *
10
+ * @module adapter-transforms
11
+ * @author Avi Fenesh
12
+ * @license MIT
13
+ */
14
+
15
+ const discovery = require('./discovery');
16
+
17
+ function transformBodyForOpenCode(content, repoRoot) {
18
+ content = content.replace(/\$\{CLAUDE_PLUGIN_ROOT\}/g, '${PLUGIN_ROOT}');
19
+ content = content.replace(/\$CLAUDE_PLUGIN_ROOT/g, '$PLUGIN_ROOT');
20
+
21
+ // Replace .claude/ paths with .opencode/ but preserve platform documentation lists
22
+ // that enumerate all three platforms (Claude Code: .claude/, OpenCode: .opencode/, Codex: .codex/)
23
+ // Also preserve {AI_STATE_DIR} references which are platform-agnostic
24
+ content = content.replace(/\.claude\//g, (match, offset) => {
25
+ const context = content.substring(Math.max(0, offset - 60), offset + match.length + 10);
26
+ // Skip if inside a platform enumeration (e.g., "Claude Code: `.claude/`")
27
+ if (/Claude Code:/.test(context)) return match;
28
+ return '.opencode/';
29
+ });
30
+ content = content.replace(/\.claude'/g, (match, offset) => {
31
+ const context = content.substring(Math.max(0, offset - 60), offset + match.length + 10);
32
+ if (/Claude Code:/.test(context)) return match;
33
+ return ".opencode'";
34
+ });
35
+ content = content.replace(/\.claude"/g, (match, offset) => {
36
+ const context = content.substring(Math.max(0, offset - 60), offset + match.length + 10);
37
+ if (/Claude Code:/.test(context)) return match;
38
+ return '.opencode"';
39
+ });
40
+ content = content.replace(/\.claude`/g, (match, offset) => {
41
+ const context = content.substring(Math.max(0, offset - 60), offset + match.length + 10);
42
+ if (/Claude Code:/.test(context)) return match;
43
+ return '.opencode`';
44
+ });
45
+
46
+ const plugins = discovery.discoverPlugins(repoRoot);
47
+ if (plugins.length > 0) {
48
+ const pluginNames = plugins.join('|');
49
+ content = content.replace(new RegExp('`(' + pluginNames + '):([a-z-]+)`', 'g'), '`$2`');
50
+ content = content.replace(new RegExp('(' + pluginNames + '):([a-z-]+)', 'g'), '$2');
51
+ }
52
+
53
+ content = content.replace(
54
+ /```(\w*)\n([\s\S]*?)```/g,
55
+ (match, lang, code) => {
56
+ const langLower = (lang || '').toLowerCase();
57
+
58
+ if (langLower === 'bash' || langLower === 'shell' || langLower === 'sh') {
59
+ if (code.includes('node -e') && code.includes('require(')) {
60
+ return '*(Bash command with Node.js require - adapt for OpenCode)*';
61
+ }
62
+ return match;
63
+ }
64
+
65
+ if (!lang && (code.trim().startsWith('gh ') || code.trim().startsWith('glab ') ||
66
+ code.trim().startsWith('git ') || code.trim().startsWith('#!'))) {
67
+ return match;
68
+ }
69
+
70
+ if (code.includes('require(') || code.includes('Task(') ||
71
+ code.includes('const ') || code.includes('let ') ||
72
+ code.includes('function ') || code.includes('=>') ||
73
+ code.includes('async ') || code.includes('await ')) {
74
+
75
+ let instructions = '';
76
+
77
+ const taskMatches = [...code.matchAll(/(?:await\s+)?Task\s*\(\s*\{[^}]*subagent_type:\s*["'](?:[^"':]+:)?([^"']+)["'][^}]*\}\s*\)/gs)];
78
+ for (const taskMatch of taskMatches) {
79
+ const agent = taskMatch[1];
80
+ instructions += `- Invoke \`@${agent}\` agent\n`;
81
+ }
82
+
83
+ const phaseMatches = code.match(/startPhase\s*\(\s*['"]([^'"]+)['"]\s*\)/g);
84
+ if (phaseMatches) {
85
+ for (const pm of phaseMatches) {
86
+ const phase = pm.match(/['"]([^'"]+)['"]/)[1];
87
+ instructions += `- Phase: ${phase}\n`;
88
+ }
89
+ }
90
+
91
+ if (code.includes('AskUserQuestion')) {
92
+ instructions += '- Use AskUserQuestion tool for user input\n';
93
+ }
94
+
95
+ if (code.includes('EnterPlanMode')) {
96
+ instructions += '- Use EnterPlanMode for user approval\n';
97
+ }
98
+
99
+ if (instructions) {
100
+ return instructions;
101
+ }
102
+
103
+ return '*(JavaScript reference - not executable in OpenCode)*';
104
+ }
105
+
106
+ return match;
107
+ }
108
+ );
109
+
110
+ content = content.replace(/\*\(Reference - adapt for OpenCode\)\*/g, '');
111
+
112
+ content = content.replace(/await\s+Task\s*\(\s*\{[\s\S]*?\}\s*\);?/g, (match) => {
113
+ const agentMatch = match.match(/subagent_type:\s*["'](?:[^"':]+:)?([^"']+)["']/);
114
+ if (agentMatch) {
115
+ return `Invoke \`@${agentMatch[1]}\` agent`;
116
+ }
117
+ return '*(Task call - use @agent-name syntax)*';
118
+ });
119
+
120
+ content = content.replace(/(?:const|let|var)\s+\{?[^}=\n]+\}?\s*=\s*require\s*\([^)]+\);?/g, '');
121
+ content = content.replace(/require\s*\(['"][^'"]+['"]\)/g, '');
122
+
123
+ if (content.includes('agent')) {
124
+ const note = `
125
+ > **OpenCode Note**: Invoke agents using \`@agent-name\` syntax.
126
+ > Available agents: task-discoverer, exploration-agent, planning-agent,
127
+ > implementation-agent, deslop-agent, delivery-validator, sync-docs-agent, consult-agent
128
+ > Example: \`@exploration-agent analyze the codebase\`
129
+
130
+ `;
131
+ content = content.replace(/^(---\n[\s\S]*?---\n)/, `$1${note}`);
132
+ }
133
+
134
+ if (content.includes('Master Workflow Orchestrator') && content.includes('No Shortcuts Policy')) {
135
+ const policySection = `
136
+ ## Phase 1: Policy Selection (Built-in Options)
137
+
138
+ Ask the user these questions using AskUserQuestion:
139
+
140
+ **Question 1 - Source**: "Where should I look for tasks?"
141
+ - GitHub Issues - Use \`gh issue list\` to find issues
142
+ - GitLab Issues - Use \`glab issue list\` to find issues
143
+ - Local tasks.md - Read from PLAN.md, tasks.md, or TODO.md in the repo
144
+ - Custom - User specifies their own source
145
+ - Other - User describes source, you figure it out
146
+
147
+ **Question 2 - Priority**: "What type of tasks to prioritize?"
148
+ - All - Consider all tasks, pick by score
149
+ - Bugs - Focus on bug fixes
150
+ - Security - Security issues first
151
+ - Features - New feature development
152
+
153
+ **Question 3 - Stop Point**: "How far should I take this task?"
154
+ - Merged - Until PR is merged to main
155
+ - PR Created - Stop after creating PR
156
+ - Implemented - Stop after local implementation
157
+ - Deployed - Deploy to staging
158
+ - Production - Full production deployment
159
+
160
+ After user answers, proceed to Phase 2 with the selected policy.
161
+
162
+ `;
163
+ if (content.includes('OpenCode Note')) {
164
+ content = content.replace(/(Example:.*analyze the codebase\`\n\n)/, `$1${policySection}`);
165
+ }
166
+ }
167
+
168
+ return content;
169
+ }
170
+
171
+ function transformCommandFrontmatterForOpenCode(content) {
172
+ return content.replace(
173
+ /^---\n([\s\S]*?)^---/m,
174
+ (match, frontmatter) => {
175
+ // Parse existing frontmatter
176
+ const lines = frontmatter.trim().split('\n');
177
+ const parsed = {};
178
+ for (const line of lines) {
179
+ const colonIdx = line.indexOf(':');
180
+ if (colonIdx > 0) {
181
+ const key = line.substring(0, colonIdx).trim();
182
+ const value = line.substring(colonIdx + 1).trim();
183
+ parsed[key] = value;
184
+ }
185
+ }
186
+
187
+ // Build OpenCode command frontmatter
188
+ let opencodeFrontmatter = '---\n';
189
+ if (parsed.description) opencodeFrontmatter += `description: ${parsed.description}\n`;
190
+ opencodeFrontmatter += 'agent: general\n';
191
+ // Don't include argument-hint or allowed-tools (not supported)
192
+ opencodeFrontmatter += '---';
193
+ return opencodeFrontmatter;
194
+ }
195
+ );
196
+ }
197
+
198
+ function transformAgentFrontmatterForOpenCode(content, options) {
199
+ const { stripModels = true } = options || {};
200
+
201
+ return content.replace(
202
+ /^---\n([\s\S]*?)^---/m,
203
+ (match, frontmatter) => {
204
+ // Parse existing frontmatter
205
+ const lines = frontmatter.trim().split('\n');
206
+ const parsed = {};
207
+ for (const line of lines) {
208
+ const colonIdx = line.indexOf(':');
209
+ if (colonIdx > 0) {
210
+ const key = line.substring(0, colonIdx).trim();
211
+ const value = line.substring(colonIdx + 1).trim();
212
+ parsed[key] = value;
213
+ }
214
+ }
215
+
216
+ // Build OpenCode frontmatter
217
+ let opencodeFrontmatter = '---\n';
218
+ if (parsed.name) opencodeFrontmatter += `name: ${parsed.name}\n`;
219
+ if (parsed.description) opencodeFrontmatter += `description: ${parsed.description}\n`;
220
+ opencodeFrontmatter += 'mode: subagent\n';
221
+
222
+ // Map model names - only include if NOT stripping
223
+ if (parsed.model && !stripModels) {
224
+ const modelMap = {
225
+ 'sonnet': 'anthropic/claude-sonnet-4',
226
+ 'opus': 'anthropic/claude-opus-4',
227
+ 'haiku': 'anthropic/claude-haiku-3-5'
228
+ };
229
+ opencodeFrontmatter += `model: ${modelMap[parsed.model] || parsed.model}\n`;
230
+ }
231
+
232
+ // Convert tools to permissions
233
+ if (parsed.tools) {
234
+ opencodeFrontmatter += 'permission:\n';
235
+ const tools = parsed.tools.toLowerCase();
236
+ opencodeFrontmatter += ` read: ${tools.includes('read') ? 'allow' : 'deny'}\n`;
237
+ opencodeFrontmatter += ` edit: ${tools.includes('edit') || tools.includes('write') ? 'allow' : 'deny'}\n`;
238
+ opencodeFrontmatter += ` bash: ${tools.includes('bash') ? 'allow' : 'ask'}\n`;
239
+ opencodeFrontmatter += ` glob: ${tools.includes('glob') ? 'allow' : 'deny'}\n`;
240
+ opencodeFrontmatter += ` grep: ${tools.includes('grep') ? 'allow' : 'deny'}\n`;
241
+ }
242
+
243
+ opencodeFrontmatter += '---';
244
+ return opencodeFrontmatter;
245
+ }
246
+ );
247
+ }
248
+
249
+ function transformSkillBodyForOpenCode(content, repoRoot) {
250
+ return transformBodyForOpenCode(content, repoRoot);
251
+ }
252
+
253
+ function transformForCodex(content, options) {
254
+ const { skillName, description, pluginInstallPath } = options;
255
+
256
+ // Escape description for YAML: wrap in double quotes, escape backslashes and internal quotes
257
+ const escapedDescription = description.replace(/\\/g, '\\\\').replace(/"/g, '\\"');
258
+ const yamlDescription = `"${escapedDescription}"`;
259
+
260
+ if (content.startsWith('---')) {
261
+ // Replace existing frontmatter with Codex-compatible format
262
+ content = content.replace(
263
+ /^---\n[\s\S]*?\n---\n/,
264
+ `---\nname: ${skillName}\ndescription: ${yamlDescription}\n---\n`
265
+ );
266
+ } else {
267
+ // Add new frontmatter
268
+ content = `---\nname: ${skillName}\ndescription: ${yamlDescription}\n---\n\n${content}`;
269
+ }
270
+
271
+ // Transform PLUGIN_ROOT to actual installed path (or placeholder) for Codex
272
+ content = content.replace(/\$\{CLAUDE_PLUGIN_ROOT\}/g, pluginInstallPath);
273
+ content = content.replace(/\$CLAUDE_PLUGIN_ROOT/g, pluginInstallPath);
274
+ content = content.replace(/\$\{PLUGIN_ROOT\}/g, pluginInstallPath);
275
+ content = content.replace(/\$PLUGIN_ROOT/g, pluginInstallPath);
276
+
277
+ // Transform AskUserQuestion → request_user_input for Codex native tool
278
+ content = content.replace(/AskUserQuestion/g, 'request_user_input');
279
+
280
+ // Remove multiSelect lines (not supported in Codex)
281
+ content = content.replace(/^[ \t]*multiSelect:.*\n?/gm, '');
282
+
283
+ // Inject Codex note about required id field after request_user_input blocks
284
+ content = content.replace(
285
+ /^([ \t]*request_user_input:\s*)$/gm,
286
+ '$1\n> **Codex**: Each question MUST include a unique `id` field (e.g., `id: "q1"`).'
287
+ );
288
+
289
+ return content;
290
+ }
291
+
292
+ module.exports = {
293
+ transformBodyForOpenCode,
294
+ transformCommandFrontmatterForOpenCode,
295
+ transformAgentFrontmatterForOpenCode,
296
+ transformSkillBodyForOpenCode,
297
+ transformForCodex
298
+ };