@devlitusp/opencode-agent 0.0.1 → 0.0.3

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/README.md CHANGED
@@ -13,14 +13,14 @@ This single command:
13
13
  2. Configures pnpm to allow the postinstall script
14
14
  3. Installs the package and runs the setup automatically
15
15
 
16
- Then set your API key:
16
+ Then set your API key and open OpenCode:
17
17
 
18
18
  ```bash
19
- export MINIMAX_API_KEY=your_key_here
19
+ export MINIMAX_API_KEY=your_key_here # MiniMax (default)
20
+ # or
21
+ export GITHUB_TOKEN=your_token_here # GitHub Copilot
20
22
  ```
21
23
 
22
- Open OpenCode in your project and use the **orchestrator** agent to start.
23
-
24
24
  ## What gets created
25
25
 
26
26
  ```
@@ -33,7 +33,7 @@ Open OpenCode in your project and use the **orchestrator** agent to start.
33
33
  security.md ← vulnerability scanning (OWASP Top 10)
34
34
  docs-writer.md ← JSDoc, README, documentation
35
35
 
36
- opencode.json ← MiniMax provider config + default_agent
36
+ opencode.json ← provider config + default_agent
37
37
  ```
38
38
 
39
39
  ## Agents
@@ -56,6 +56,34 @@ The orchestrator follows this sequence automatically:
56
56
  investigate → plan → security (pre) → build → QA → security (post) → docs
57
57
  ```
58
58
 
59
+ ## Providers
60
+
61
+ Two providers are supported out of the box:
62
+
63
+ | Provider | Flag | Model | Env var |
64
+ |----------|------|-------|---------|
65
+ | [MiniMax](https://platform.minimax.io) | `minimax` *(default)* | `MiniMax-M2.7` | `MINIMAX_API_KEY` |
66
+ | [GitHub Copilot](https://github.com/features/copilot) | `github-copilot` | `gpt-4o` | `GITHUB_TOKEN` |
67
+
68
+ Pass `--provider` to choose:
69
+
70
+ ```bash
71
+ opencode-agent inject --provider github-copilot
72
+ opencode-agent inject --provider minimax
73
+ ```
74
+
75
+ GitHub Copilot also exposes `gpt-4o-mini`, `o3-mini`, `claude-sonnet-4-5`, and `claude-3-5-haiku` in `opencode.json` for manual selection.
76
+
77
+ ## CLI
78
+
79
+ ```bash
80
+ opencode-agent init # full project setup
81
+ opencode-agent inject # inject with MiniMax (default)
82
+ opencode-agent inject --provider github-copilot # inject with GitHub Copilot
83
+ opencode-agent inject -f # overwrite existing agent files
84
+ opencode-agent list # list available agents
85
+ ```
86
+
59
87
  ## Manual install (npm / yarn / bun)
60
88
 
61
89
  ```bash
@@ -73,25 +101,8 @@ Then run:
73
101
 
74
102
  ```bash
75
103
  opencode-agent inject
76
- ```
77
-
78
- ## CLI
79
-
80
- ```bash
81
- opencode-agent init # full project setup
82
- opencode-agent inject # inject agents into opencode.json
83
- opencode-agent inject -f # overwrite existing agent files
84
- opencode-agent list # list available agents
85
- ```
86
-
87
- ## Provider
88
-
89
- Uses [MiniMax](https://platform.minimax.io) with model `MiniMax-M2.7` via OpenAI-compatible API.
90
-
91
- Set your API key before opening OpenCode:
92
-
93
- ```bash
94
- export MINIMAX_API_KEY=your_key_here
104
+ # or with GitHub Copilot:
105
+ opencode-agent inject --provider github-copilot
95
106
  ```
96
107
 
97
108
  ## License
@@ -10,7 +10,9 @@ var orchestrator = {
10
10
  model: "minimax/MiniMax-M2.7",
11
11
  description: "Lead coordinator that orchestrates the full development workflow",
12
12
  mode: "primary",
13
- steps: 50
13
+ temperature: 0.2,
14
+ steps: 50,
15
+ tools: { computer: false }
14
16
  },
15
17
  prompt: `You are the lead developer orchestrator for a multi-agent software development team. Your role is to coordinate all development activities by delegating tasks to specialized subagents in the correct order.
16
18
 
@@ -59,8 +61,9 @@ var investigator = {
59
61
  model: "minimax/MiniMax-M2.7",
60
62
  description: "Analyzes codebases and researches requirements to produce technical findings",
61
63
  mode: "subagent",
64
+ temperature: 0.2,
62
65
  steps: 20,
63
- tools: { write: false }
66
+ tools: { write: false, edit: false, task: false, webfetch: false, websearch: false, computer: false }
64
67
  },
65
68
  prompt: `You are a senior software engineer specialized in technical investigation and codebase analysis. Your output feeds directly into the planning phase, so accuracy and completeness matter more than speed.
66
69
 
@@ -113,8 +116,9 @@ var planner = {
113
116
  model: "minimax/MiniMax-M2.7",
114
117
  description: "Creates detailed, actionable implementation plans from investigation findings",
115
118
  mode: "subagent",
119
+ temperature: 0.3,
116
120
  steps: 15,
117
- tools: { write: false, bash: false }
121
+ tools: { write: false, edit: false, bash: false, task: false, webfetch: false, websearch: false, computer: false }
118
122
  },
119
123
  prompt: `You are a software architect specialized in creating precise, actionable implementation plans. Your plan will be handed directly to a builder agent — clarity and completeness prevent wasted work.
120
124
 
@@ -182,7 +186,9 @@ var builder = {
182
186
  model: "minimax/MiniMax-M2.7",
183
187
  description: "Implements production-quality code following the plan precisely",
184
188
  mode: "subagent",
185
- steps: 30
189
+ temperature: 0.1,
190
+ steps: 30,
191
+ tools: { task: false, webfetch: false, websearch: false, computer: false }
186
192
  },
187
193
  prompt: `You are a senior software engineer specialized in clean, production-quality implementation. You receive a plan and execute it precisely — no more, no less.
188
194
 
@@ -219,7 +225,9 @@ var qa = {
219
225
  model: "minimax/MiniMax-M2.7",
220
226
  description: "Reviews code quality, writes tests, and verifies implementations against requirements",
221
227
  mode: "subagent",
222
- steps: 25
228
+ temperature: 0.2,
229
+ steps: 25,
230
+ tools: { task: false, webfetch: false, websearch: false, computer: false }
223
231
  },
224
232
  prompt: `You are a QA engineer specialized in software quality assurance and testing. Your job is to verify that the implementation is correct, complete, and robust.
225
233
 
@@ -296,8 +304,9 @@ var security = {
296
304
  model: "minimax/MiniMax-M2.7",
297
305
  description: "Identifies security vulnerabilities and provides remediation guidance",
298
306
  mode: "subagent",
307
+ temperature: 0.1,
299
308
  steps: 20,
300
- tools: { write: false }
309
+ tools: { write: false, edit: false, bash: false, task: false, webfetch: false, websearch: false, computer: false }
301
310
  },
302
311
  prompt: `You are a security engineer specialized in identifying and remediating application security vulnerabilities. You are called twice: once before the build (to identify security requirements) and once after (to scan the implementation).
303
312
 
@@ -359,7 +368,9 @@ var docsWriter = {
359
368
  model: "minimax/MiniMax-M2.7",
360
369
  description: "Creates JSDoc comments, README sections, and developer documentation",
361
370
  mode: "subagent",
362
- steps: 15
371
+ temperature: 0.3,
372
+ steps: 15,
373
+ tools: { bash: false, task: false, webfetch: false, websearch: false, computer: false }
363
374
  },
364
375
  prompt: `You are a technical writer specialized in developer-facing documentation. You write documentation that helps developers understand, use, and maintain code — not documentation that just restates what the code does.
365
376
 
@@ -432,6 +443,7 @@ var ALL_AGENTS = [
432
443
  ];
433
444
 
434
445
  // src/inject.ts
446
+ var MINIMAX_PROVIDER_KEY = "minimax";
435
447
  var MINIMAX_PROVIDER = {
436
448
  npm: "@ai-sdk/openai-compatible",
437
449
  name: "MiniMax",
@@ -443,13 +455,49 @@ var MINIMAX_PROVIDER = {
443
455
  "MiniMax-M2.7": { name: "MiniMax-M2.7" }
444
456
  }
445
457
  };
446
- function toMarkdown(agent) {
447
- const fm = agent.frontmatter;
458
+ var GITHUB_COPILOT_PROVIDER_KEY = "github-copilot";
459
+ var GITHUB_COPILOT_PROVIDER = {
460
+ npm: "@ai-sdk/openai-compatible",
461
+ name: "GitHub Copilot",
462
+ options: {
463
+ baseURL: "https://api.githubcopilot.com",
464
+ apiKey: "{env:GITHUB_TOKEN}"
465
+ },
466
+ models: {
467
+ "gpt-4o": { name: "gpt-4o" },
468
+ "gpt-4o-mini": { name: "gpt-4o-mini" },
469
+ "o3-mini": { name: "o3-mini" },
470
+ "claude-sonnet-4-5": { name: "claude-sonnet-4-5" },
471
+ "claude-3-5-haiku": { name: "claude-3-5-haiku" }
472
+ }
473
+ };
474
+ var PROVIDERS = {
475
+ minimax: {
476
+ key: MINIMAX_PROVIDER_KEY,
477
+ provider: MINIMAX_PROVIDER,
478
+ defaultModel: `${MINIMAX_PROVIDER_KEY}/MiniMax-M2.7`,
479
+ envVar: "MINIMAX_API_KEY"
480
+ },
481
+ "github-copilot": {
482
+ key: GITHUB_COPILOT_PROVIDER_KEY,
483
+ provider: GITHUB_COPILOT_PROVIDER,
484
+ defaultModel: `${GITHUB_COPILOT_PROVIDER_KEY}/gpt-4o`,
485
+ envVar: "GITHUB_TOKEN"
486
+ }
487
+ };
488
+ function toMarkdown(agent, modelOverride) {
489
+ const base = agent.frontmatter;
490
+ const fm = modelOverride ? { ...base, model: modelOverride } : base;
448
491
  const lines = ["---"];
449
492
  for (const [key, value] of Object.entries(fm)) {
450
493
  if (value === undefined)
451
494
  continue;
452
- if (typeof value === "object") {
495
+ if (Array.isArray(value)) {
496
+ lines.push(`${key}:`);
497
+ for (const item of value) {
498
+ lines.push(` - ${item}`);
499
+ }
500
+ } else if (typeof value === "object") {
453
501
  lines.push(`${key}:`);
454
502
  for (const [k, v] of Object.entries(value)) {
455
503
  lines.push(` ${k}: ${v}`);
@@ -485,6 +533,7 @@ function inject(options = {}) {
485
533
  const cwd = options.cwd ?? process.cwd();
486
534
  const force = options.force ?? false;
487
535
  const verbose = options.verbose ?? false;
536
+ const providerConfig = PROVIDERS[options.provider ?? "minimax"];
488
537
  const log = (msg) => verbose && console.log(` ${msg}`);
489
538
  const agentsDir = join(cwd, ".opencode", "agents");
490
539
  if (!existsSync(agentsDir)) {
@@ -497,7 +546,7 @@ function inject(options = {}) {
497
546
  log(`Skipped ${agent.name}.md (already exists — use --force to overwrite)`);
498
547
  continue;
499
548
  }
500
- writeFileSync(agentPath, toMarkdown(agent), "utf-8");
549
+ writeFileSync(agentPath, toMarkdown(agent, providerConfig.defaultModel), "utf-8");
501
550
  log(`Wrote ${agent.name}.md`);
502
551
  }
503
552
  const configPath = join(cwd, "opencode.json");
@@ -514,10 +563,10 @@ function inject(options = {}) {
514
563
  }
515
564
  if (!config.provider)
516
565
  config.provider = {};
517
- if (!config.provider["minimax"] || force) {
518
- config.provider["minimax"] = MINIMAX_PROVIDER;
566
+ if (!config.provider[providerConfig.key] || force) {
567
+ config.provider[providerConfig.key] = providerConfig.provider;
519
568
  changed = true;
520
- log(`Added minimax provider`);
569
+ log(`Added ${providerConfig.key} provider`);
521
570
  }
522
571
  if (changed) {
523
572
  writeOpenCodeConfig(configPath, config);
@@ -535,7 +584,7 @@ function inject(options = {}) {
535
584
  }
536
585
  const scripts = pkg["scripts"] ?? {};
537
586
  if (!scripts["prepare"] || force) {
538
- scripts["prepare"] = "dev-agents inject";
587
+ scripts["prepare"] = "opencode-agent inject";
539
588
  pkg["scripts"] = scripts;
540
589
  writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + `
541
590
  `, "utf-8");
@@ -615,7 +664,7 @@ function detectPackageManager(cwd) {
615
664
  }
616
665
  function getOwnVersion() {
617
666
  try {
618
- const selfPkg = join2(import.meta.dirname ?? ".", "..", "package.json");
667
+ const selfPkg = join2(import.meta.dirname ?? ".", "..", "..", "package.json");
619
668
  if (existsSync2(selfPkg)) {
620
669
  const p = JSON.parse(readFileSync2(selfPkg, "utf-8"));
621
670
  return p.version;
@@ -640,6 +689,10 @@ function buildInstallCommand(pm, version, _cwd) {
640
689
  // bin/dev-agents.ts
641
690
  var args = process.argv.slice(2);
642
691
  var command = args[0];
692
+ var providerIdx = Math.max(args.indexOf("--provider"), args.indexOf("-p"));
693
+ var rawProvider = providerIdx !== -1 ? args[providerIdx + 1] : undefined;
694
+ var VALID_PROVIDERS = ["minimax", "github-copilot"];
695
+ var provider = rawProvider && VALID_PROVIDERS.includes(rawProvider) ? rawProvider : undefined;
643
696
  var flags = {
644
697
  force: args.includes("--force") || args.includes("-f"),
645
698
  verbose: args.includes("--verbose") || args.includes("-v"),
@@ -650,24 +703,36 @@ function printHelp() {
650
703
  @devlitusp/opencode-agent — multi-agent dev team for OpenCode CLI
651
704
 
652
705
  Usage:
653
- pnpm dlx @devlitusp/opencode-agent init Setup project (recommended)
654
- opencode-agent inject [options] Inject agents into current project
655
- opencode-agent list List all available agents
706
+ pnpm dlx @devlitusp/opencode-agent init Setup project (recommended)
707
+ opencode-agent inject [options] Inject agents into current project
708
+ opencode-agent list List all available agents
656
709
 
657
710
  Options:
658
- -f, --force Overwrite existing agent files and config entries
659
- -v, --verbose Show detailed output
660
- -h, --help Show this help message
661
-
662
- Quick start:
663
- pnpm dlx @devlitusp/opencode-agent init
664
- export MINIMAX_API_KEY=your_key_here
711
+ -p, --provider <name> AI provider to use: minimax (default) | github-copilot
712
+ -f, --force Overwrite existing agent files and config entries
713
+ -v, --verbose Show detailed output
714
+ -h, --help Show this help message
715
+
716
+ Examples:
717
+ opencode-agent inject
718
+ opencode-agent inject --provider github-copilot
719
+ opencode-agent inject --provider minimax --force
720
+
721
+ Environment variables:
722
+ MINIMAX_API_KEY Required when using the minimax provider
723
+ GITHUB_TOKEN Required when using the github-copilot provider
665
724
  `);
666
725
  }
667
726
  if (flags.help || !command) {
668
727
  printHelp();
669
728
  process.exit(0);
670
729
  }
730
+ if (rawProvider && !provider) {
731
+ console.error(`
732
+ Unknown provider: "${rawProvider}". Valid options: ${VALID_PROVIDERS.join(", ")}
733
+ `);
734
+ process.exit(1);
735
+ }
671
736
  switch (command) {
672
737
  case "init": {
673
738
  console.log(`
@@ -677,12 +742,14 @@ Setting up @devlitusp/opencode-agent...
677
742
  break;
678
743
  }
679
744
  case "inject": {
680
- console.log(`Injecting agents into OpenCode project config...
745
+ const selectedProvider = provider ?? "minimax";
746
+ const envVarHint = selectedProvider === "github-copilot" ? "Set GITHUB_TOKEN in your environment and open OpenCode." : "Set MINIMAX_API_KEY in your environment and open OpenCode.";
747
+ console.log(`Injecting agents into OpenCode project config (provider: ${selectedProvider})...
681
748
  `);
682
749
  try {
683
- inject({ force: flags.force, verbose: true });
750
+ inject({ force: flags.force, verbose: true, provider: selectedProvider });
684
751
  console.log(`
685
- Done! Set MINIMAX_API_KEY in your environment and open OpenCode.
752
+ Done! ${envVarHint}
686
753
  ` + `Use the orchestrator agent to start the full development workflow.
687
754
  `);
688
755
  } catch (err) {
@@ -9,7 +9,9 @@ var orchestrator = {
9
9
  model: "minimax/MiniMax-M2.7",
10
10
  description: "Lead coordinator that orchestrates the full development workflow",
11
11
  mode: "primary",
12
- steps: 50
12
+ temperature: 0.2,
13
+ steps: 50,
14
+ tools: { computer: false }
13
15
  },
14
16
  prompt: `You are the lead developer orchestrator for a multi-agent software development team. Your role is to coordinate all development activities by delegating tasks to specialized subagents in the correct order.
15
17
 
@@ -58,8 +60,9 @@ var investigator = {
58
60
  model: "minimax/MiniMax-M2.7",
59
61
  description: "Analyzes codebases and researches requirements to produce technical findings",
60
62
  mode: "subagent",
63
+ temperature: 0.2,
61
64
  steps: 20,
62
- tools: { write: false }
65
+ tools: { write: false, edit: false, task: false, webfetch: false, websearch: false, computer: false }
63
66
  },
64
67
  prompt: `You are a senior software engineer specialized in technical investigation and codebase analysis. Your output feeds directly into the planning phase, so accuracy and completeness matter more than speed.
65
68
 
@@ -112,8 +115,9 @@ var planner = {
112
115
  model: "minimax/MiniMax-M2.7",
113
116
  description: "Creates detailed, actionable implementation plans from investigation findings",
114
117
  mode: "subagent",
118
+ temperature: 0.3,
115
119
  steps: 15,
116
- tools: { write: false, bash: false }
120
+ tools: { write: false, edit: false, bash: false, task: false, webfetch: false, websearch: false, computer: false }
117
121
  },
118
122
  prompt: `You are a software architect specialized in creating precise, actionable implementation plans. Your plan will be handed directly to a builder agent — clarity and completeness prevent wasted work.
119
123
 
@@ -181,7 +185,9 @@ var builder = {
181
185
  model: "minimax/MiniMax-M2.7",
182
186
  description: "Implements production-quality code following the plan precisely",
183
187
  mode: "subagent",
184
- steps: 30
188
+ temperature: 0.1,
189
+ steps: 30,
190
+ tools: { task: false, webfetch: false, websearch: false, computer: false }
185
191
  },
186
192
  prompt: `You are a senior software engineer specialized in clean, production-quality implementation. You receive a plan and execute it precisely — no more, no less.
187
193
 
@@ -218,7 +224,9 @@ var qa = {
218
224
  model: "minimax/MiniMax-M2.7",
219
225
  description: "Reviews code quality, writes tests, and verifies implementations against requirements",
220
226
  mode: "subagent",
221
- steps: 25
227
+ temperature: 0.2,
228
+ steps: 25,
229
+ tools: { task: false, webfetch: false, websearch: false, computer: false }
222
230
  },
223
231
  prompt: `You are a QA engineer specialized in software quality assurance and testing. Your job is to verify that the implementation is correct, complete, and robust.
224
232
 
@@ -295,8 +303,9 @@ var security = {
295
303
  model: "minimax/MiniMax-M2.7",
296
304
  description: "Identifies security vulnerabilities and provides remediation guidance",
297
305
  mode: "subagent",
306
+ temperature: 0.1,
298
307
  steps: 20,
299
- tools: { write: false }
308
+ tools: { write: false, edit: false, bash: false, task: false, webfetch: false, websearch: false, computer: false }
300
309
  },
301
310
  prompt: `You are a security engineer specialized in identifying and remediating application security vulnerabilities. You are called twice: once before the build (to identify security requirements) and once after (to scan the implementation).
302
311
 
@@ -358,7 +367,9 @@ var docsWriter = {
358
367
  model: "minimax/MiniMax-M2.7",
359
368
  description: "Creates JSDoc comments, README sections, and developer documentation",
360
369
  mode: "subagent",
361
- steps: 15
370
+ temperature: 0.3,
371
+ steps: 15,
372
+ tools: { bash: false, task: false, webfetch: false, websearch: false, computer: false }
362
373
  },
363
374
  prompt: `You are a technical writer specialized in developer-facing documentation. You write documentation that helps developers understand, use, and maintain code — not documentation that just restates what the code does.
364
375
 
@@ -431,6 +442,7 @@ var ALL_AGENTS = [
431
442
  ];
432
443
 
433
444
  // src/inject.ts
445
+ var MINIMAX_PROVIDER_KEY = "minimax";
434
446
  var MINIMAX_PROVIDER = {
435
447
  npm: "@ai-sdk/openai-compatible",
436
448
  name: "MiniMax",
@@ -442,13 +454,49 @@ var MINIMAX_PROVIDER = {
442
454
  "MiniMax-M2.7": { name: "MiniMax-M2.7" }
443
455
  }
444
456
  };
445
- function toMarkdown(agent) {
446
- const fm = agent.frontmatter;
457
+ var GITHUB_COPILOT_PROVIDER_KEY = "github-copilot";
458
+ var GITHUB_COPILOT_PROVIDER = {
459
+ npm: "@ai-sdk/openai-compatible",
460
+ name: "GitHub Copilot",
461
+ options: {
462
+ baseURL: "https://api.githubcopilot.com",
463
+ apiKey: "{env:GITHUB_TOKEN}"
464
+ },
465
+ models: {
466
+ "gpt-4o": { name: "gpt-4o" },
467
+ "gpt-4o-mini": { name: "gpt-4o-mini" },
468
+ "o3-mini": { name: "o3-mini" },
469
+ "claude-sonnet-4-5": { name: "claude-sonnet-4-5" },
470
+ "claude-3-5-haiku": { name: "claude-3-5-haiku" }
471
+ }
472
+ };
473
+ var PROVIDERS = {
474
+ minimax: {
475
+ key: MINIMAX_PROVIDER_KEY,
476
+ provider: MINIMAX_PROVIDER,
477
+ defaultModel: `${MINIMAX_PROVIDER_KEY}/MiniMax-M2.7`,
478
+ envVar: "MINIMAX_API_KEY"
479
+ },
480
+ "github-copilot": {
481
+ key: GITHUB_COPILOT_PROVIDER_KEY,
482
+ provider: GITHUB_COPILOT_PROVIDER,
483
+ defaultModel: `${GITHUB_COPILOT_PROVIDER_KEY}/gpt-4o`,
484
+ envVar: "GITHUB_TOKEN"
485
+ }
486
+ };
487
+ function toMarkdown(agent, modelOverride) {
488
+ const base = agent.frontmatter;
489
+ const fm = modelOverride ? { ...base, model: modelOverride } : base;
447
490
  const lines = ["---"];
448
491
  for (const [key, value] of Object.entries(fm)) {
449
492
  if (value === undefined)
450
493
  continue;
451
- if (typeof value === "object") {
494
+ if (Array.isArray(value)) {
495
+ lines.push(`${key}:`);
496
+ for (const item of value) {
497
+ lines.push(` - ${item}`);
498
+ }
499
+ } else if (typeof value === "object") {
452
500
  lines.push(`${key}:`);
453
501
  for (const [k, v] of Object.entries(value)) {
454
502
  lines.push(` ${k}: ${v}`);
@@ -484,6 +532,7 @@ function inject(options = {}) {
484
532
  const cwd = options.cwd ?? process.cwd();
485
533
  const force = options.force ?? false;
486
534
  const verbose = options.verbose ?? false;
535
+ const providerConfig = PROVIDERS[options.provider ?? "minimax"];
487
536
  const log = (msg) => verbose && console.log(` ${msg}`);
488
537
  const agentsDir = join(cwd, ".opencode", "agents");
489
538
  if (!existsSync(agentsDir)) {
@@ -496,7 +545,7 @@ function inject(options = {}) {
496
545
  log(`Skipped ${agent.name}.md (already exists — use --force to overwrite)`);
497
546
  continue;
498
547
  }
499
- writeFileSync(agentPath, toMarkdown(agent), "utf-8");
548
+ writeFileSync(agentPath, toMarkdown(agent, providerConfig.defaultModel), "utf-8");
500
549
  log(`Wrote ${agent.name}.md`);
501
550
  }
502
551
  const configPath = join(cwd, "opencode.json");
@@ -513,10 +562,10 @@ function inject(options = {}) {
513
562
  }
514
563
  if (!config.provider)
515
564
  config.provider = {};
516
- if (!config.provider["minimax"] || force) {
517
- config.provider["minimax"] = MINIMAX_PROVIDER;
565
+ if (!config.provider[providerConfig.key] || force) {
566
+ config.provider[providerConfig.key] = providerConfig.provider;
518
567
  changed = true;
519
- log(`Added minimax provider`);
568
+ log(`Added ${providerConfig.key} provider`);
520
569
  }
521
570
  if (changed) {
522
571
  writeOpenCodeConfig(configPath, config);
@@ -534,7 +583,7 @@ function inject(options = {}) {
534
583
  }
535
584
  const scripts = pkg["scripts"] ?? {};
536
585
  if (!scripts["prepare"] || force) {
537
- scripts["prepare"] = "dev-agents inject";
586
+ scripts["prepare"] = "opencode-agent inject";
538
587
  pkg["scripts"] = scripts;
539
588
  writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + `
540
589
  `, "utf-8");
@@ -556,11 +605,18 @@ Available agents:
556
605
  }
557
606
 
558
607
  // bin/postinstall.ts
559
- var isInstalledAsDep = process.cwd().includes("node_modules");
608
+ import { readFileSync as readFileSync2 } from "fs";
609
+ import { join as join2 } from "path";
560
610
  var projectRoot = process.env["INIT_CWD"];
561
- if (!isInstalledAsDep || !projectRoot) {
611
+ if (!projectRoot) {
562
612
  process.exit(0);
563
613
  }
614
+ try {
615
+ const targetPkg = JSON.parse(readFileSync2(join2(projectRoot, "package.json"), "utf-8"));
616
+ if (targetPkg.name === "@devlitusp/opencode-agent") {
617
+ process.exit(0);
618
+ }
619
+ } catch {}
564
620
  try {
565
621
  console.log(`
566
622
  [dev-agents] Injecting OpenCode agent config...
package/package.json CHANGED
@@ -1,11 +1,18 @@
1
1
  {
2
2
  "name": "@devlitusp/opencode-agent",
3
- "version": "0.0.1",
3
+ "version": "0.0.3",
4
4
  "description": "Multi-agent development team for OpenCode CLI — orchestrator, investigator, planner, builder, QA, security & docs",
5
5
  "type": "module",
6
6
  "bin": {
7
7
  "opencode-agent": "./dist/bin/dev-agents.js"
8
8
  },
9
+ "scripts": {
10
+ "build": "bun run scripts/build.ts",
11
+ "dev": "bun run bin/dev-agents.ts",
12
+ "postinstall": "node ./dist/bin/postinstall.js",
13
+ "prepublishOnly": "pnpm run build",
14
+ "typecheck": "tsc --noEmit"
15
+ },
9
16
  "files": [
10
17
  "dist",
11
18
  "src",
@@ -39,11 +46,5 @@
39
46
  },
40
47
  "engines": {
41
48
  "node": ">=18.0.0"
42
- },
43
- "scripts": {
44
- "build": "bun run scripts/build.ts",
45
- "dev": "bun run bin/dev-agents.ts",
46
- "postinstall": "node ./dist/bin/postinstall.js",
47
- "typecheck": "tsc --noEmit"
48
49
  }
49
- }
50
+ }
@@ -6,7 +6,9 @@ export const builder: AgentDefinition = {
6
6
  model: "minimax/MiniMax-M2.7",
7
7
  description: "Implements production-quality code following the plan precisely",
8
8
  mode: "subagent",
9
+ temperature: 0.1,
9
10
  steps: 30,
11
+ tools: { task: false, webfetch: false, websearch: false, computer: false },
10
12
  },
11
13
  prompt: `You are a senior software engineer specialized in clean, production-quality implementation. You receive a plan and execute it precisely — no more, no less.
12
14
 
@@ -6,7 +6,9 @@ export const docsWriter: AgentDefinition = {
6
6
  model: "minimax/MiniMax-M2.7",
7
7
  description: "Creates JSDoc comments, README sections, and developer documentation",
8
8
  mode: "subagent",
9
+ temperature: 0.3,
9
10
  steps: 15,
11
+ tools: { bash: false, task: false, webfetch: false, websearch: false, computer: false },
10
12
  },
11
13
  prompt: `You are a technical writer specialized in developer-facing documentation. You write documentation that helps developers understand, use, and maintain code — not documentation that just restates what the code does.
12
14
 
@@ -6,8 +6,9 @@ export const investigator: AgentDefinition = {
6
6
  model: "minimax/MiniMax-M2.7",
7
7
  description: "Analyzes codebases and researches requirements to produce technical findings",
8
8
  mode: "subagent",
9
+ temperature: 0.2,
9
10
  steps: 20,
10
- tools: { write: false },
11
+ tools: { write: false, edit: false, task: false, webfetch: false, websearch: false, computer: false },
11
12
  },
12
13
  prompt: `You are a senior software engineer specialized in technical investigation and codebase analysis. Your output feeds directly into the planning phase, so accuracy and completeness matter more than speed.
13
14
 
@@ -6,7 +6,9 @@ export const orchestrator: AgentDefinition = {
6
6
  model: "minimax/MiniMax-M2.7",
7
7
  description: "Lead coordinator that orchestrates the full development workflow",
8
8
  mode: "primary",
9
+ temperature: 0.2,
9
10
  steps: 50,
11
+ tools: { computer: false },
10
12
  },
11
13
  prompt: `You are the lead developer orchestrator for a multi-agent software development team. Your role is to coordinate all development activities by delegating tasks to specialized subagents in the correct order.
12
14
 
@@ -6,8 +6,9 @@ export const planner: AgentDefinition = {
6
6
  model: "minimax/MiniMax-M2.7",
7
7
  description: "Creates detailed, actionable implementation plans from investigation findings",
8
8
  mode: "subagent",
9
+ temperature: 0.3,
9
10
  steps: 15,
10
- tools: { write: false, bash: false },
11
+ tools: { write: false, edit: false, bash: false, task: false, webfetch: false, websearch: false, computer: false },
11
12
  },
12
13
  prompt: `You are a software architect specialized in creating precise, actionable implementation plans. Your plan will be handed directly to a builder agent — clarity and completeness prevent wasted work.
13
14
 
package/src/agents/qa.ts CHANGED
@@ -6,7 +6,9 @@ export const qa: AgentDefinition = {
6
6
  model: "minimax/MiniMax-M2.7",
7
7
  description: "Reviews code quality, writes tests, and verifies implementations against requirements",
8
8
  mode: "subagent",
9
+ temperature: 0.2,
9
10
  steps: 25,
11
+ tools: { task: false, webfetch: false, websearch: false, computer: false },
10
12
  },
11
13
  prompt: `You are a QA engineer specialized in software quality assurance and testing. Your job is to verify that the implementation is correct, complete, and robust.
12
14
 
@@ -6,8 +6,9 @@ export const security: AgentDefinition = {
6
6
  model: "minimax/MiniMax-M2.7",
7
7
  description: "Identifies security vulnerabilities and provides remediation guidance",
8
8
  mode: "subagent",
9
+ temperature: 0.1,
9
10
  steps: 20,
10
- tools: { write: false },
11
+ tools: { write: false, edit: false, bash: false, task: false, webfetch: false, websearch: false, computer: false },
11
12
  },
12
13
  prompt: `You are a security engineer specialized in identifying and remediating application security vulnerabilities. You are called twice: once before the build (to identify security requirements) and once after (to scan the implementation).
13
14
 
package/src/index.ts CHANGED
@@ -1,3 +1,3 @@
1
1
  export { inject, list } from "./inject.js";
2
2
  export { ALL_AGENTS } from "./agents/index.js";
3
- export type { AgentDefinition, OpenCodeConfig, InjectOptions } from "./types.js";
3
+ export type { AgentDefinition, OpenCodeConfig, InjectOptions, ProviderName } from "./types.js";
package/src/init.ts CHANGED
@@ -66,7 +66,7 @@ function detectPackageManager(cwd: string): string {
66
66
  function getOwnVersion(): string {
67
67
  try {
68
68
  // When running via dlx, __dirname is the temp package location
69
- const selfPkg = join(import.meta.dirname ?? ".", "..", "package.json");
69
+ const selfPkg = join(import.meta.dirname ?? ".", "..", "..", "package.json");
70
70
  if (existsSync(selfPkg)) {
71
71
  const p = JSON.parse(readFileSync(selfPkg, "utf-8")) as { version: string };
72
72
  return p.version;
package/src/inject.ts CHANGED
@@ -1,9 +1,12 @@
1
1
  import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
2
2
  import { join } from "path";
3
3
  import { ALL_AGENTS } from "./agents/index.js";
4
- import type { AgentDefinition, AgentFrontmatter, InjectOptions, OpenCodeConfig } from "./types.js";
4
+ import type { AgentDefinition, AgentFrontmatter, InjectOptions, OpenCodeConfig, OpenCodeProvider, ProviderName } from "./types.js";
5
5
 
6
- const MINIMAX_PROVIDER = {
6
+ // ── Provider definitions ─────────────────────────────────────────────────────
7
+
8
+ const MINIMAX_PROVIDER_KEY = "minimax";
9
+ const MINIMAX_PROVIDER: OpenCodeProvider = {
7
10
  npm: "@ai-sdk/openai-compatible",
8
11
  name: "MiniMax",
9
12
  options: {
@@ -15,13 +18,62 @@ const MINIMAX_PROVIDER = {
15
18
  },
16
19
  };
17
20
 
18
- function toMarkdown(agent: AgentDefinition): string {
19
- const fm = agent.frontmatter as AgentFrontmatter & Record<string, unknown>;
21
+ const GITHUB_COPILOT_PROVIDER_KEY = "github-copilot";
22
+ const GITHUB_COPILOT_PROVIDER: OpenCodeProvider = {
23
+ npm: "@ai-sdk/openai-compatible",
24
+ name: "GitHub Copilot",
25
+ options: {
26
+ baseURL: "https://api.githubcopilot.com",
27
+ apiKey: "{env:GITHUB_TOKEN}",
28
+ },
29
+ models: {
30
+ "gpt-4o": { name: "gpt-4o" },
31
+ "gpt-4o-mini": { name: "gpt-4o-mini" },
32
+ "o3-mini": { name: "o3-mini" },
33
+ "claude-sonnet-4-5": { name: "claude-sonnet-4-5" },
34
+ "claude-3-5-haiku": { name: "claude-3-5-haiku" },
35
+ },
36
+ };
37
+
38
+ interface ProviderConfig {
39
+ key: string;
40
+ provider: OpenCodeProvider;
41
+ defaultModel: string;
42
+ envVar: string;
43
+ }
44
+
45
+ const PROVIDERS: Record<ProviderName, ProviderConfig> = {
46
+ minimax: {
47
+ key: MINIMAX_PROVIDER_KEY,
48
+ provider: MINIMAX_PROVIDER,
49
+ defaultModel: `${MINIMAX_PROVIDER_KEY}/MiniMax-M2.7`,
50
+ envVar: "MINIMAX_API_KEY",
51
+ },
52
+ "github-copilot": {
53
+ key: GITHUB_COPILOT_PROVIDER_KEY,
54
+ provider: GITHUB_COPILOT_PROVIDER,
55
+ defaultModel: `${GITHUB_COPILOT_PROVIDER_KEY}/gpt-4o`,
56
+ envVar: "GITHUB_TOKEN",
57
+ },
58
+ };
59
+
60
+ // ── Helpers ──────────────────────────────────────────────────────────────────
61
+
62
+ function toMarkdown(agent: AgentDefinition, modelOverride?: string): string {
63
+ const base = agent.frontmatter as AgentFrontmatter & Record<string, unknown>;
64
+ const fm: AgentFrontmatter & Record<string, unknown> = modelOverride
65
+ ? { ...base, model: modelOverride }
66
+ : base;
20
67
  const lines: string[] = ["---"];
21
68
 
22
69
  for (const [key, value] of Object.entries(fm)) {
23
70
  if (value === undefined) continue;
24
- if (typeof value === "object") {
71
+ if (Array.isArray(value)) {
72
+ lines.push(`${key}:`);
73
+ for (const item of value) {
74
+ lines.push(` - ${item}`);
75
+ }
76
+ } else if (typeof value === "object") {
25
77
  lines.push(`${key}:`);
26
78
  for (const [k, v] of Object.entries(value as Record<string, unknown>)) {
27
79
  lines.push(` ${k}: ${v}`);
@@ -56,10 +108,13 @@ function writeOpenCodeConfig(configPath: string, config: OpenCodeConfig): void {
56
108
  writeFileSync(configPath, JSON.stringify(config, null, 2) + "\n", "utf-8");
57
109
  }
58
110
 
111
+ // ── Public API ───────────────────────────────────────────────────────────────
112
+
59
113
  export function inject(options: InjectOptions = {}): void {
60
114
  const cwd = options.cwd ?? process.cwd();
61
115
  const force = options.force ?? false;
62
116
  const verbose = options.verbose ?? false;
117
+ const providerConfig = PROVIDERS[options.provider ?? "minimax"];
63
118
 
64
119
  const log = (msg: string) => verbose && console.log(` ${msg}`);
65
120
 
@@ -76,7 +131,7 @@ export function inject(options: InjectOptions = {}): void {
76
131
  log(`Skipped ${agent.name}.md (already exists — use --force to overwrite)`);
77
132
  continue;
78
133
  }
79
- writeFileSync(agentPath, toMarkdown(agent), "utf-8");
134
+ writeFileSync(agentPath, toMarkdown(agent, providerConfig.defaultModel), "utf-8");
80
135
  log(`Wrote ${agent.name}.md`);
81
136
  }
82
137
 
@@ -100,10 +155,10 @@ export function inject(options: InjectOptions = {}): void {
100
155
 
101
156
  // Provider
102
157
  if (!config.provider) config.provider = {};
103
- if (!config.provider["minimax"] || force) {
104
- config.provider["minimax"] = MINIMAX_PROVIDER;
158
+ if (!config.provider[providerConfig.key] || force) {
159
+ config.provider[providerConfig.key] = providerConfig.provider;
105
160
  changed = true;
106
- log(`Added minimax provider`);
161
+ log(`Added ${providerConfig.key} provider`);
107
162
  }
108
163
 
109
164
  if (changed) {
@@ -125,7 +180,7 @@ export function inject(options: InjectOptions = {}): void {
125
180
 
126
181
  const scripts = (pkg["scripts"] ?? {}) as Record<string, string>;
127
182
  if (!scripts["prepare"] || force) {
128
- scripts["prepare"] = "dev-agents inject";
183
+ scripts["prepare"] = "opencode-agent inject";
129
184
  pkg["scripts"] = scripts;
130
185
  writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + "\n", "utf-8");
131
186
  log(`Added "prepare": "dev-agents inject" to package.json`);
package/src/types.ts CHANGED
@@ -1,10 +1,23 @@
1
+ export type ToolName =
2
+ | "bash"
3
+ | "computer"
4
+ | "edit"
5
+ | "glob"
6
+ | "grep"
7
+ | "list"
8
+ | "read"
9
+ | "task"
10
+ | "webfetch"
11
+ | "websearch"
12
+ | "write";
13
+
1
14
  export interface AgentFrontmatter {
2
15
  model: string;
3
16
  description: string;
4
17
  mode: "primary" | "subagent" | "all";
5
18
  temperature?: number;
6
19
  steps?: number;
7
- tools?: Record<string, boolean>;
20
+ tools?: Partial<Record<ToolName, boolean>>;
8
21
  }
9
22
 
10
23
  export interface AgentDefinition {
@@ -13,7 +26,7 @@ export interface AgentDefinition {
13
26
  prompt: string;
14
27
  }
15
28
 
16
- export interface MinimaxProviderOptions {
29
+ export interface ProviderApiOptions {
17
30
  baseURL: string;
18
31
  apiKey: string;
19
32
  }
@@ -21,10 +34,12 @@ export interface MinimaxProviderOptions {
21
34
  export interface OpenCodeProvider {
22
35
  npm: string;
23
36
  name: string;
24
- options: MinimaxProviderOptions;
37
+ options: ProviderApiOptions;
25
38
  models: Record<string, { name: string }>;
26
39
  }
27
40
 
41
+ export type ProviderName = "minimax" | "github-copilot";
42
+
28
43
  export interface OpenCodeConfig {
29
44
  $schema?: string;
30
45
  default_agent?: string;
@@ -36,7 +51,7 @@ export interface OpenCodeConfig {
36
51
  temperature?: number;
37
52
  steps?: number;
38
53
  prompt?: string;
39
- tools?: Record<string, boolean>;
54
+ tools?: Partial<Record<ToolName, boolean>>;
40
55
  }>;
41
56
  [key: string]: unknown;
42
57
  }
@@ -45,4 +60,5 @@ export interface InjectOptions {
45
60
  cwd?: string;
46
61
  force?: boolean;
47
62
  verbose?: boolean;
63
+ provider?: ProviderName;
48
64
  }