opencode-orchestrator 0.5.8 → 0.5.16

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
@@ -16,6 +16,7 @@
16
16
  Tested GLM-4, got disappointed. Built this to make mid-tier models work like premium ones through structured orchestration.
17
17
 
18
18
  ### Key Features
19
+
19
20
  - **🎯 Autonomous Loop** — Commander runs until the mission is complete
20
21
  - **🔍 Environment Scan** — Analyzes Infra, Stack, and Domain before coding
21
22
  - **🔨 Smart Implementation** — Matches existing codebase patterns
@@ -42,6 +43,14 @@ Restart OpenCode after installation.
42
43
 
43
44
  Press `Tab` in OpenCode → Select **Commander** → Type your mission!
44
45
 
46
+ <div align="center">
47
+ <img src="assets/tui_image.png" alt="Commander TUI" width="600" />
48
+ <p><sub><b>Commander</b> agent selection interface in OpenCode (TUI)</sub></p>
49
+
50
+ <br/> <img src="assets/window_image.png" alt="Commander Windows" width="600" />
51
+ <p><sub>Execution of <b>Commander</b> agent on Windows environment</sub></p>
52
+ </div>
53
+
45
54
  ```
46
55
  "Fix the login bug in the docker-compose environment"
47
56
  ```
@@ -58,13 +67,13 @@ Press `Tab` in OpenCode → Select **Commander** → Type your mission!
58
67
 
59
68
  ## The 5 Agents
60
69
 
61
- | Agent | Role | Responsibility |
62
- | :--- | :--- | :--- |
70
+ | Agent | Role | Responsibility |
71
+ | :--------------- | :----------- | :------------------------- |
63
72
  | **Commander** 🎯 | Orchestrator | Autonomous mission control |
64
- | **Architect** 🏗️ | Planner | Task decomposition |
65
- | **Builder** 🔨 | Developer | Full-stack implementation |
66
- | **Inspector** 🔍 | Quality | Audit & auto-fix |
67
- | **Recorder** 💾 | Context | Progress tracking |
73
+ | **Architect** 🏗️ | Planner | Task decomposition |
74
+ | **Builder** 🔨 | Developer | Full-stack implementation |
75
+ | **Inspector** 🔍 | Quality | Audit & auto-fix |
76
+ | **Recorder** 💾 | Context | Progress tracking |
68
77
 
69
78
  ---
70
79
 
package/dist/index.js CHANGED
@@ -22,12 +22,11 @@ You are Commander. Complete missions autonomously. Never stop until done.
22
22
  </role>
23
23
 
24
24
  <core_rules>
25
- 1. LANGUAGE: ALL output MUST be in English only. No exceptions. No other languages.
26
- 2. Never stop until "\u2705 MISSION COMPLETE"
27
- 3. Never wait for user during execution
28
- 4. Never stop because agent returned nothing
29
- 5. Always survey environment & codebase BEFORE coding
30
- 6. Always verify with evidence based on runtime context
25
+ 1. Never stop until "\u2705 MISSION COMPLETE"
26
+ 2. Never wait for user during execution
27
+ 3. Never stop because agent returned nothing
28
+ 4. Always survey environment & codebase BEFORE coding
29
+ 5. Always verify with evidence based on runtime context
31
30
  </core_rules>
32
31
 
33
32
  <phase_0 name="TRIAGE">
@@ -217,8 +216,7 @@ You are Architect. Break complex tasks into atomic pieces.
217
216
  </role>
218
217
 
219
218
  <constraints>
220
- 1. LANGUAGE: ALL output MUST be in English only. No exceptions. No other languages.
221
- 2. If your reasoning collapses into gibberish, stop and output "ERROR: REASONING_COLLAPSE".
219
+ 1. If your reasoning collapses into gibberish, stop and output "ERROR: REASONING_COLLAPSE".
222
220
  </constraints>
223
221
 
224
222
  <scalable_planning>
@@ -279,8 +277,7 @@ You are Builder. Write code that works.
279
277
  </role>
280
278
 
281
279
  <constraints>
282
- 1. LANGUAGE: ALL output MUST be in English only. No exceptions. No other languages.
283
- 2. If your reasoning collapses into gibberish, stop and output "ERROR: REASONING_COLLAPSE".
280
+ 1. If your reasoning collapses into gibberish, stop and output "ERROR: REASONING_COLLAPSE".
284
281
  </constraints>
285
282
 
286
283
  <scalable_attention>
@@ -345,8 +342,7 @@ You are Inspector. Prove failure or success with evidence.
345
342
  </role>
346
343
 
347
344
  <constraints>
348
- 1. LANGUAGE: ALL output MUST be in English only. No exceptions. No other languages.
349
- 2. If your reasoning collapses into gibberish, stop and output "ERROR: REASONING_COLLAPSE".
345
+ 1. If your reasoning collapses into gibberish, stop and output "ERROR: REASONING_COLLAPSE".
350
346
  </constraints>
351
347
 
352
348
  <scalable_audit>
@@ -412,8 +408,7 @@ You are Recorder. Save and load work progress.
412
408
  </role>
413
409
 
414
410
  <constraints>
415
- 1. LANGUAGE: ALL output MUST be in English only. No exceptions. No other languages.
416
- 2. If your reasoning collapses into gibberish, stop and output "ERROR: REASONING_COLLAPSE".
411
+ 1. If your reasoning collapses into gibberish, stop and output "ERROR: REASONING_COLLAPSE".
417
412
  </constraints>
418
413
 
419
414
  <purpose>
@@ -13054,10 +13049,6 @@ var COMMANDS = {
13054
13049
  You are Commander. Complete this mission. Never stop until 100% done.
13055
13050
  </role>
13056
13051
 
13057
- <language_rule>
13058
- CRITICAL: ALL output MUST be in English only. No exceptions. No other languages permitted.
13059
- </language_rule>
13060
-
13061
13052
  <phase_1 name="MANDATORY_ENVIRONMENT_SCAN">
13062
13053
  Before any planning or coding, you MUST understand:
13063
13054
  1. INFRA: OS-native? Container? Docker-compose? Volume-mounted?
@@ -1,9 +1,9 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  // scripts/postinstall.ts
4
- import { existsSync, readFileSync, writeFileSync, mkdirSync } from "fs";
5
- import { join } from "path";
4
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
6
5
  import { homedir } from "os";
6
+ import { join } from "path";
7
7
  function formatError(err, context) {
8
8
  if (err instanceof Error) {
9
9
  const nodeErr = err;
@@ -29,33 +29,80 @@ function formatError(err, context) {
29
29
  }
30
30
  return `Failed to ${context}: ${String(err)}`;
31
31
  }
32
- var CONFIG_DIR = process.env.XDG_CONFIG_HOME ? join(process.env.XDG_CONFIG_HOME, "opencode") : process.platform === "win32" ? join(process.env.APPDATA || join(homedir(), "AppData", "Roaming"), "opencode") : join(homedir(), ".config", "opencode");
33
- var CONFIG_FILE = join(CONFIG_DIR, "opencode.json");
34
32
  var PLUGIN_NAME = "opencode-orchestrator";
35
- try {
36
- console.log("\u{1F3AF} OpenCode Orchestrator - Installing...");
37
- if (!existsSync(CONFIG_DIR)) {
38
- mkdirSync(CONFIG_DIR, { recursive: true });
33
+ function getConfigPaths() {
34
+ const paths = [];
35
+ if (process.env.XDG_CONFIG_HOME) {
36
+ paths.push(join(process.env.XDG_CONFIG_HOME, "opencode"));
39
37
  }
40
- let config = {};
41
- if (existsSync(CONFIG_FILE)) {
42
- try {
43
- config = JSON.parse(readFileSync(CONFIG_FILE, "utf-8"));
44
- } catch {
45
- config = {};
38
+ if (process.platform === "win32") {
39
+ const appDataPath = process.env.APPDATA || join(homedir(), "AppData", "Roaming");
40
+ paths.push(join(appDataPath, "opencode"));
41
+ const dotConfigPath = join(homedir(), ".config", "opencode");
42
+ if (!paths.includes(dotConfigPath)) {
43
+ paths.push(dotConfigPath);
46
44
  }
45
+ } else {
46
+ paths.push(join(homedir(), ".config", "opencode"));
47
47
  }
48
- if (!config.plugin) {
49
- config.plugin = [];
48
+ return paths;
49
+ }
50
+ function registerInConfig(configDir) {
51
+ const configFile = join(configDir, "opencode.json");
52
+ try {
53
+ if (!existsSync(configDir)) {
54
+ mkdirSync(configDir, { recursive: true });
55
+ }
56
+ let config = {};
57
+ if (existsSync(configFile)) {
58
+ try {
59
+ config = JSON.parse(readFileSync(configFile, "utf-8"));
60
+ } catch {
61
+ config = {};
62
+ }
63
+ }
64
+ if (!config.plugin) {
65
+ config.plugin = [];
66
+ }
67
+ const hasPlugin = config.plugin.some(
68
+ (p) => p.includes(PLUGIN_NAME)
69
+ );
70
+ if (!hasPlugin) {
71
+ config.plugin.push(PLUGIN_NAME);
72
+ writeFileSync(configFile, JSON.stringify(config, null, 2) + "\n");
73
+ return true;
74
+ }
75
+ return false;
76
+ } catch {
77
+ return false;
50
78
  }
51
- const hasPlugin = config.plugin.some((p) => p.includes(PLUGIN_NAME));
52
- if (!hasPlugin) {
53
- config.plugin.push(PLUGIN_NAME);
54
- writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2) + "\n");
55
- console.log("\u2705 Plugin registered!");
56
- console.log(` Name: ${PLUGIN_NAME}`);
57
- } else {
79
+ }
80
+ try {
81
+ console.log("\u{1F3AF} OpenCode Orchestrator - Installing...");
82
+ const configPaths = getConfigPaths();
83
+ let registered = false;
84
+ let alreadyRegistered = false;
85
+ for (const configDir of configPaths) {
86
+ const configFile = join(configDir, "opencode.json");
87
+ if (existsSync(configFile)) {
88
+ try {
89
+ const config = JSON.parse(readFileSync(configFile, "utf-8"));
90
+ if (config.plugin?.some((p) => p.includes(PLUGIN_NAME))) {
91
+ alreadyRegistered = true;
92
+ continue;
93
+ }
94
+ } catch {
95
+ }
96
+ }
97
+ if (registerInConfig(configDir)) {
98
+ console.log(`\u2705 Plugin registered: ${configFile}`);
99
+ registered = true;
100
+ }
101
+ }
102
+ if (!registered && alreadyRegistered) {
58
103
  console.log("\u2705 Plugin already registered.");
104
+ } else if (!registered) {
105
+ console.log("\u26A0\uFE0F Could not register plugin in any config location.");
59
106
  }
60
107
  console.log("");
61
108
  console.log("\u{1F680} Ready! Restart OpenCode to use.");
@@ -2,8 +2,8 @@
2
2
 
3
3
  // scripts/preuninstall.ts
4
4
  import { existsSync, readFileSync, writeFileSync } from "fs";
5
- import { join } from "path";
6
5
  import { homedir } from "os";
6
+ import { join } from "path";
7
7
  function formatError(err, context) {
8
8
  if (err instanceof Error) {
9
9
  const nodeErr = err;
@@ -29,26 +29,59 @@ function formatError(err, context) {
29
29
  }
30
30
  return `Failed to ${context}: ${String(err)}`;
31
31
  }
32
- var CONFIG_DIR = process.env.XDG_CONFIG_HOME ? join(process.env.XDG_CONFIG_HOME, "opencode") : process.platform === "win32" ? join(process.env.APPDATA || join(homedir(), "AppData", "Roaming"), "opencode") : join(homedir(), ".config", "opencode");
33
- var CONFIG_FILE = join(CONFIG_DIR, "opencode.json");
34
32
  var PLUGIN_NAME = "opencode-orchestrator";
33
+ function getConfigPaths() {
34
+ const paths = [];
35
+ if (process.env.XDG_CONFIG_HOME) {
36
+ paths.push(join(process.env.XDG_CONFIG_HOME, "opencode"));
37
+ }
38
+ if (process.platform === "win32") {
39
+ const appDataPath = process.env.APPDATA || join(homedir(), "AppData", "Roaming");
40
+ paths.push(join(appDataPath, "opencode"));
41
+ const dotConfigPath = join(homedir(), ".config", "opencode");
42
+ if (!paths.includes(dotConfigPath)) {
43
+ paths.push(dotConfigPath);
44
+ }
45
+ } else {
46
+ paths.push(join(homedir(), ".config", "opencode"));
47
+ }
48
+ return paths;
49
+ }
50
+ function removeFromConfig(configDir) {
51
+ const configFile = join(configDir, "opencode.json");
52
+ try {
53
+ if (!existsSync(configFile)) {
54
+ return false;
55
+ }
56
+ const config = JSON.parse(readFileSync(configFile, "utf-8"));
57
+ if (!config.plugin || !Array.isArray(config.plugin)) {
58
+ return false;
59
+ }
60
+ const originalLength = config.plugin.length;
61
+ config.plugin = config.plugin.filter(
62
+ (p) => !p.includes(PLUGIN_NAME)
63
+ );
64
+ if (config.plugin.length < originalLength) {
65
+ writeFileSync(configFile, JSON.stringify(config, null, 2) + "\n");
66
+ return true;
67
+ }
68
+ return false;
69
+ } catch {
70
+ return false;
71
+ }
72
+ }
35
73
  try {
36
74
  console.log("\u{1F9F9} OpenCode Orchestrator - Uninstalling...");
37
- if (!existsSync(CONFIG_FILE)) {
38
- console.log("\u2705 No config file found. Nothing to clean up.");
39
- process.exit(0);
40
- }
41
- const config = JSON.parse(readFileSync(CONFIG_FILE, "utf-8"));
42
- if (!config.plugin || !Array.isArray(config.plugin)) {
43
- console.log("\u2705 No plugins registered. Nothing to clean up.");
44
- process.exit(0);
75
+ const configPaths = getConfigPaths();
76
+ let removed = false;
77
+ for (const configDir of configPaths) {
78
+ const configFile = join(configDir, "opencode.json");
79
+ if (removeFromConfig(configDir)) {
80
+ console.log(`\u2705 Plugin removed: ${configFile}`);
81
+ removed = true;
82
+ }
45
83
  }
46
- const originalLength = config.plugin.length;
47
- config.plugin = config.plugin.filter((p) => !p.includes(PLUGIN_NAME));
48
- if (config.plugin.length < originalLength) {
49
- writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2) + "\n");
50
- console.log("\u2705 Plugin removed from OpenCode config.");
51
- } else {
84
+ if (!removed) {
52
85
  console.log("\u2705 Plugin was not registered. Nothing to clean up.");
53
86
  }
54
87
  } catch (error) {
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "opencode-orchestrator",
3
3
  "displayName": "OpenCode Orchestrator",
4
4
  "description": "Distributed Cognitive Architecture for OpenCode. Turns simple prompts into specialized multi-agent workflows (Planner, Coder, Reviewer).",
5
- "version": "0.5.8",
5
+ "version": "0.5.16",
6
6
  "author": "agnusdei1207",
7
7
  "license": "MIT",
8
8
  "repository": {
@@ -44,7 +44,7 @@
44
44
  "test:coverage": "vitest run --coverage",
45
45
  "test:unit": "vitest run tests/unit --reporter=verbose",
46
46
  "test:e2e": "vitest run tests/e2e --reporter=verbose",
47
- "test:all": "vitest run --reporter=verbose && echo ' ALL TESTS PASSED'",
47
+ "test:all": "vitest run --reporter=verbose && echo '=== ALL TESTS PASSED ==='",
48
48
  "postinstall": "node dist/scripts/postinstall.js",
49
49
  "preuninstall": "node dist/scripts/preuninstall.js",
50
50
  "prepublishOnly": "npm run build",