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.
- package/.claude-plugin/marketplace.json +21 -14
- package/.claude-plugin/plugin.json +1 -1
- package/AGENTS.md +2 -1
- package/CHANGELOG.md +24 -1
- package/README.md +7 -6
- package/adapters/codex/skills/agnix/SKILL.md +0 -1
- package/adapters/codex/skills/audit-project/SKILL.md +0 -1
- package/adapters/codex/skills/audit-project-agents/SKILL.md +0 -1
- package/adapters/codex/skills/audit-project-github/SKILL.md +0 -1
- package/adapters/codex/skills/consult/SKILL.md +133 -59
- package/adapters/codex/skills/debate/SKILL.md +214 -0
- package/adapters/codex/skills/delivery-approval/SKILL.md +0 -1
- package/adapters/codex/skills/deslop/SKILL.md +0 -1
- package/adapters/codex/skills/drift-detect/SKILL.md +0 -1
- package/adapters/codex/skills/enhance/SKILL.md +0 -1
- package/adapters/codex/skills/learn/SKILL.md +0 -1
- package/adapters/codex/skills/next-task/SKILL.md +0 -1
- package/adapters/codex/skills/perf/SKILL.md +0 -1
- package/adapters/codex/skills/repo-map/SKILL.md +0 -1
- package/adapters/codex/skills/ship/SKILL.md +0 -1
- package/adapters/codex/skills/ship-ci-review-loop/SKILL.md +0 -1
- package/adapters/codex/skills/ship-deployment/SKILL.md +0 -1
- package/adapters/codex/skills/ship-error-handling/SKILL.md +0 -1
- package/adapters/codex/skills/sync-docs/SKILL.md +0 -1
- package/adapters/opencode/agents/agent-enhancer.md +0 -1
- package/adapters/opencode/agents/agnix-agent.md +0 -1
- package/adapters/opencode/agents/ci-fixer.md +0 -1
- package/adapters/opencode/agents/ci-monitor.md +0 -1
- package/adapters/opencode/agents/claudemd-enhancer.md +0 -1
- package/adapters/opencode/agents/consult-agent.md +123 -31
- package/adapters/opencode/agents/cross-file-enhancer.md +0 -1
- package/adapters/opencode/agents/debate-orchestrator.md +169 -0
- package/adapters/opencode/agents/delivery-validator.md +0 -1
- package/adapters/opencode/agents/deslop-agent.md +0 -1
- package/adapters/opencode/agents/docs-enhancer.md +0 -1
- package/adapters/opencode/agents/exploration-agent.md +0 -1
- package/adapters/opencode/agents/hooks-enhancer.md +0 -1
- package/adapters/opencode/agents/implementation-agent.md +0 -1
- package/adapters/opencode/agents/learn-agent.md +0 -1
- package/adapters/opencode/agents/map-validator.md +0 -1
- package/adapters/opencode/agents/perf-analyzer.md +0 -1
- package/adapters/opencode/agents/perf-code-paths.md +0 -1
- package/adapters/opencode/agents/perf-investigation-logger.md +0 -1
- package/adapters/opencode/agents/perf-orchestrator.md +0 -1
- package/adapters/opencode/agents/perf-theory-gatherer.md +0 -1
- package/adapters/opencode/agents/perf-theory-tester.md +0 -1
- package/adapters/opencode/agents/plan-synthesizer.md +0 -1
- package/adapters/opencode/agents/planning-agent.md +0 -1
- package/adapters/opencode/agents/plugin-enhancer.md +0 -1
- package/adapters/opencode/agents/prompt-enhancer.md +0 -1
- package/adapters/opencode/agents/simple-fixer.md +0 -1
- package/adapters/opencode/agents/skills-enhancer.md +0 -1
- package/adapters/opencode/agents/sync-docs-agent.md +0 -1
- package/adapters/opencode/agents/task-discoverer.md +0 -1
- package/adapters/opencode/agents/test-coverage-checker.md +0 -1
- package/adapters/opencode/agents/worktree-manager.md +0 -1
- package/adapters/opencode/commands/agnix.md +0 -1
- package/adapters/opencode/commands/audit-project-agents.md +0 -1
- package/adapters/opencode/commands/audit-project-github.md +0 -1
- package/adapters/opencode/commands/audit-project.md +0 -1
- package/adapters/opencode/commands/consult.md +134 -59
- package/adapters/opencode/commands/debate.md +224 -0
- package/adapters/opencode/commands/delivery-approval.md +0 -1
- package/adapters/opencode/commands/deslop.md +0 -1
- package/adapters/opencode/commands/drift-detect.md +0 -1
- package/adapters/opencode/commands/enhance.md +0 -1
- package/adapters/opencode/commands/learn.md +0 -1
- package/adapters/opencode/commands/next-task.md +0 -1
- package/adapters/opencode/commands/perf.md +0 -1
- package/adapters/opencode/commands/repo-map.md +0 -1
- package/adapters/opencode/commands/ship-ci-review-loop.md +0 -1
- package/adapters/opencode/commands/ship-deployment.md +0 -1
- package/adapters/opencode/commands/ship-error-handling.md +0 -1
- package/adapters/opencode/commands/ship.md +0 -1
- package/adapters/opencode/commands/sync-docs.md +0 -1
- package/adapters/opencode/skills/agnix/SKILL.md +1 -2
- package/adapters/opencode/skills/consult/SKILL.md +41 -27
- package/adapters/opencode/skills/debate/SKILL.md +245 -0
- package/adapters/opencode/skills/deslop/SKILL.md +1 -2
- package/adapters/opencode/skills/discover-tasks/SKILL.md +1 -2
- package/adapters/opencode/skills/drift-analysis/SKILL.md +1 -2
- package/adapters/opencode/skills/enhance-agent-prompts/SKILL.md +1 -2
- package/adapters/opencode/skills/enhance-claude-memory/SKILL.md +1 -2
- package/adapters/opencode/skills/enhance-cross-file/SKILL.md +1 -2
- package/adapters/opencode/skills/enhance-docs/SKILL.md +1 -2
- package/adapters/opencode/skills/enhance-hooks/SKILL.md +1 -2
- package/adapters/opencode/skills/enhance-orchestrator/SKILL.md +1 -2
- package/adapters/opencode/skills/enhance-plugins/SKILL.md +1 -2
- package/adapters/opencode/skills/enhance-prompts/SKILL.md +1 -2
- package/adapters/opencode/skills/enhance-skills/SKILL.md +1 -2
- package/adapters/opencode/skills/learn/SKILL.md +1 -2
- package/adapters/opencode/skills/orchestrate-review/SKILL.md +0 -1
- package/adapters/opencode/skills/perf-analyzer/SKILL.md +1 -2
- package/adapters/opencode/skills/perf-baseline-manager/SKILL.md +1 -2
- package/adapters/opencode/skills/perf-benchmarker/SKILL.md +1 -2
- package/adapters/opencode/skills/perf-code-paths/SKILL.md +1 -2
- package/adapters/opencode/skills/perf-investigation-logger/SKILL.md +1 -2
- package/adapters/opencode/skills/perf-profiler/SKILL.md +1 -2
- package/adapters/opencode/skills/perf-theory-gatherer/SKILL.md +1 -2
- package/adapters/opencode/skills/perf-theory-tester/SKILL.md +1 -2
- package/adapters/opencode/skills/repo-mapping/SKILL.md +1 -2
- package/adapters/opencode/skills/sync-docs/SKILL.md +1 -2
- package/adapters/opencode/skills/validate-delivery/SKILL.md +1 -2
- package/lib/adapter-transforms.js +24 -4
- package/package.json +1 -1
- package/plugins/agnix/.claude-plugin/plugin.json +1 -1
- package/plugins/agnix/skills/agnix/SKILL.md +1 -1
- package/plugins/audit-project/.claude-plugin/plugin.json +1 -1
- package/plugins/audit-project/lib/adapter-transforms.js +24 -4
- package/plugins/consult/.claude-plugin/plugin.json +1 -1
- package/plugins/consult/agents/consult-agent.md +123 -30
- package/plugins/consult/commands/consult.md +136 -60
- package/plugins/consult/skills/consult/SKILL.md +39 -24
- package/plugins/debate/.claude-plugin/plugin.json +21 -0
- package/plugins/debate/agents/debate-orchestrator.md +175 -0
- package/plugins/debate/commands/debate.md +221 -0
- package/plugins/debate/lib/adapter-transforms.js +298 -0
- package/plugins/debate/lib/collectors/codebase.js +392 -0
- package/plugins/debate/lib/collectors/docs-patterns.js +713 -0
- package/plugins/debate/lib/collectors/documentation.js +219 -0
- package/plugins/debate/lib/collectors/github.js +330 -0
- package/plugins/debate/lib/collectors/index.js +126 -0
- package/plugins/debate/lib/config/index.js +14 -0
- package/plugins/debate/lib/cross-platform/index.js +539 -0
- package/plugins/debate/lib/discovery/index.js +352 -0
- package/plugins/debate/lib/drift-detect/collectors.js +37 -0
- package/plugins/debate/lib/enhance/agent-analyzer.js +421 -0
- package/plugins/debate/lib/enhance/agent-patterns.js +571 -0
- package/plugins/debate/lib/enhance/auto-suppression.js +622 -0
- package/plugins/debate/lib/enhance/benchmark.js +417 -0
- package/plugins/debate/lib/enhance/cross-file-analyzer.js +930 -0
- package/plugins/debate/lib/enhance/cross-file-patterns.js +370 -0
- package/plugins/debate/lib/enhance/docs-analyzer.js +325 -0
- package/plugins/debate/lib/enhance/docs-patterns.js +671 -0
- package/plugins/debate/lib/enhance/fixer.js +721 -0
- package/plugins/debate/lib/enhance/hook-analyzer.js +135 -0
- package/plugins/debate/lib/enhance/hook-patterns.js +40 -0
- package/plugins/debate/lib/enhance/index.js +127 -0
- package/plugins/debate/lib/enhance/plugin-analyzer.js +402 -0
- package/plugins/debate/lib/enhance/plugin-patterns.js +326 -0
- package/plugins/debate/lib/enhance/projectmemory-analyzer.js +551 -0
- package/plugins/debate/lib/enhance/projectmemory-patterns.js +617 -0
- package/plugins/debate/lib/enhance/prompt-analyzer.js +457 -0
- package/plugins/debate/lib/enhance/prompt-patterns.js +1484 -0
- package/plugins/debate/lib/enhance/reporter.js +1348 -0
- package/plugins/debate/lib/enhance/security-patterns.js +284 -0
- package/plugins/debate/lib/enhance/skill-analyzer.js +182 -0
- package/plugins/debate/lib/enhance/skill-patterns.js +147 -0
- package/plugins/debate/lib/enhance/suppression.js +352 -0
- package/plugins/debate/lib/enhance/tool-patterns.js +373 -0
- package/plugins/debate/lib/index.js +270 -0
- package/plugins/debate/lib/patterns/cli-enhancers.js +611 -0
- package/plugins/debate/lib/patterns/pipeline.js +948 -0
- package/plugins/debate/lib/patterns/review-patterns.js +558 -0
- package/plugins/debate/lib/patterns/slop-analyzers.js +2305 -0
- package/plugins/debate/lib/patterns/slop-patterns.js +1187 -0
- package/plugins/debate/lib/perf/analyzer/index.js +22 -0
- package/plugins/debate/lib/perf/argument-parser.js +105 -0
- package/plugins/debate/lib/perf/baseline-comparator.js +50 -0
- package/plugins/debate/lib/perf/baseline-store.js +127 -0
- package/plugins/debate/lib/perf/benchmark-runner.js +404 -0
- package/plugins/debate/lib/perf/breaking-point-finder.js +52 -0
- package/plugins/debate/lib/perf/breaking-point-runner.js +60 -0
- package/plugins/debate/lib/perf/checkpoint.js +123 -0
- package/plugins/debate/lib/perf/code-paths.js +86 -0
- package/plugins/debate/lib/perf/consolidation.js +37 -0
- package/plugins/debate/lib/perf/constraint-runner.js +71 -0
- package/plugins/debate/lib/perf/experiment-runner.js +32 -0
- package/plugins/debate/lib/perf/index.js +41 -0
- package/plugins/debate/lib/perf/investigation-state.js +874 -0
- package/plugins/debate/lib/perf/optimization-runner.js +79 -0
- package/plugins/debate/lib/perf/profilers/go.js +22 -0
- package/plugins/debate/lib/perf/profilers/index.js +46 -0
- package/plugins/debate/lib/perf/profilers/java.js +23 -0
- package/plugins/debate/lib/perf/profilers/node.js +27 -0
- package/plugins/debate/lib/perf/profilers/python.js +23 -0
- package/plugins/debate/lib/perf/profilers/rust.js +23 -0
- package/plugins/debate/lib/perf/profiling-runner.js +75 -0
- package/plugins/debate/lib/perf/schemas.js +140 -0
- package/plugins/debate/lib/platform/detect-platform.js +413 -0
- package/plugins/debate/lib/platform/detection-configs.js +93 -0
- package/plugins/debate/lib/platform/state-dir.js +132 -0
- package/plugins/debate/lib/platform/verify-tools.js +182 -0
- package/plugins/debate/lib/repo-map/cache.js +152 -0
- package/plugins/debate/lib/repo-map/concurrency.js +29 -0
- package/plugins/debate/lib/repo-map/index.js +222 -0
- package/plugins/debate/lib/repo-map/installer.js +212 -0
- package/plugins/debate/lib/repo-map/queries/go.js +27 -0
- package/plugins/debate/lib/repo-map/queries/index.js +100 -0
- package/plugins/debate/lib/repo-map/queries/java.js +38 -0
- package/plugins/debate/lib/repo-map/queries/javascript.js +55 -0
- package/plugins/debate/lib/repo-map/queries/python.js +24 -0
- package/plugins/debate/lib/repo-map/queries/rust.js +73 -0
- package/plugins/debate/lib/repo-map/queries/typescript.js +38 -0
- package/plugins/debate/lib/repo-map/runner.js +1364 -0
- package/plugins/debate/lib/repo-map/updater.js +562 -0
- package/plugins/debate/lib/repo-map/usage-analyzer.js +407 -0
- package/plugins/debate/lib/schemas/plugin-manifest.schema.json +57 -0
- package/plugins/debate/lib/schemas/validator.js +247 -0
- package/plugins/debate/lib/sources/custom-handler.js +199 -0
- package/plugins/debate/lib/sources/policy-questions.js +246 -0
- package/plugins/debate/lib/sources/source-cache.js +165 -0
- package/plugins/debate/lib/state/workflow-state.js +576 -0
- package/plugins/debate/lib/types/agent-frontmatter.d.ts +134 -0
- package/plugins/debate/lib/types/command-frontmatter.d.ts +107 -0
- package/plugins/debate/lib/types/hook-frontmatter.d.ts +115 -0
- package/plugins/debate/lib/types/index.d.ts +84 -0
- package/plugins/debate/lib/types/plugin-manifest.d.ts +102 -0
- package/plugins/debate/lib/types/skill-frontmatter.d.ts +89 -0
- package/plugins/debate/lib/utils/atomic-write.js +94 -0
- package/plugins/debate/lib/utils/cache-manager.js +159 -0
- package/plugins/debate/lib/utils/command-parser.js +0 -0
- package/plugins/debate/lib/utils/context-optimizer.js +300 -0
- package/plugins/debate/lib/utils/deprecation.js +37 -0
- package/plugins/debate/lib/utils/shell-escape.js +88 -0
- package/plugins/debate/lib/utils/state-helpers.js +61 -0
- package/plugins/debate/skills/debate/SKILL.md +264 -0
- package/plugins/deslop/.claude-plugin/plugin.json +1 -1
- package/plugins/deslop/lib/adapter-transforms.js +24 -4
- package/plugins/deslop/skills/deslop/SKILL.md +1 -1
- package/plugins/drift-detect/.claude-plugin/plugin.json +1 -1
- package/plugins/drift-detect/lib/adapter-transforms.js +24 -4
- package/plugins/drift-detect/skills/drift-analysis/SKILL.md +1 -1
- package/plugins/enhance/.claude-plugin/plugin.json +1 -1
- package/plugins/enhance/lib/adapter-transforms.js +24 -4
- package/plugins/enhance/skills/enhance-agent-prompts/SKILL.md +1 -1
- package/plugins/enhance/skills/enhance-claude-memory/SKILL.md +1 -1
- package/plugins/enhance/skills/enhance-cross-file/SKILL.md +1 -1
- package/plugins/enhance/skills/enhance-docs/SKILL.md +1 -1
- package/plugins/enhance/skills/enhance-hooks/SKILL.md +1 -1
- package/plugins/enhance/skills/enhance-orchestrator/SKILL.md +1 -1
- package/plugins/enhance/skills/enhance-plugins/SKILL.md +1 -1
- package/plugins/enhance/skills/enhance-prompts/SKILL.md +1 -1
- package/plugins/enhance/skills/enhance-skills/SKILL.md +1 -1
- package/plugins/learn/.claude-plugin/plugin.json +1 -1
- package/plugins/learn/agents/learn-agent.md +1 -1
- package/plugins/learn/lib/adapter-transforms.js +24 -4
- package/plugins/learn/skills/learn/SKILL.md +1 -1
- package/plugins/next-task/.claude-plugin/plugin.json +1 -1
- package/plugins/next-task/agents/exploration-agent.md +1 -1
- package/plugins/next-task/lib/adapter-transforms.js +24 -4
- package/plugins/next-task/skills/discover-tasks/SKILL.md +1 -1
- package/plugins/next-task/skills/validate-delivery/SKILL.md +1 -1
- package/plugins/perf/.claude-plugin/plugin.json +1 -1
- package/plugins/perf/lib/adapter-transforms.js +24 -4
- package/plugins/perf/skills/perf-analyzer/SKILL.md +1 -1
- package/plugins/perf/skills/perf-baseline-manager/SKILL.md +1 -1
- package/plugins/perf/skills/perf-benchmarker/SKILL.md +1 -1
- package/plugins/perf/skills/perf-code-paths/SKILL.md +1 -1
- package/plugins/perf/skills/perf-investigation-logger/SKILL.md +1 -1
- package/plugins/perf/skills/perf-profiler/SKILL.md +1 -1
- package/plugins/perf/skills/perf-theory-gatherer/SKILL.md +1 -1
- package/plugins/perf/skills/perf-theory-tester/SKILL.md +1 -1
- package/plugins/repo-map/.claude-plugin/plugin.json +1 -1
- package/plugins/repo-map/lib/adapter-transforms.js +24 -4
- package/plugins/ship/.claude-plugin/plugin.json +1 -1
- package/plugins/ship/lib/adapter-transforms.js +24 -4
- package/plugins/sync-docs/.claude-plugin/plugin.json +1 -1
- package/plugins/sync-docs/lib/adapter-transforms.js +24 -4
- package/plugins/sync-docs/skills/sync-docs/SKILL.md +1 -1
- package/scripts/gen-adapters.js +6 -7
- package/scripts/generate-docs.js +4 -2
- package/scripts/plugins.txt +1 -0
- 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
|
+
};
|