@oeronteros-1/opencode-orchestra 1.0.22 → 1.0.24
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 +19 -5
- package/dashboard-dist/assets/index-Dc5lp8wX.js +124 -0
- package/dashboard-dist/index.html +1 -1
- package/dist/agents/build.js +4 -0
- package/dist/agents/build.js.map +1 -1
- package/dist/agents/editor.d.ts +3 -0
- package/dist/agents/editor.js +12 -0
- package/dist/agents/editor.js.map +1 -0
- package/dist/agents/integrator.d.ts +3 -0
- package/dist/agents/integrator.js +12 -0
- package/dist/agents/integrator.js.map +1 -0
- package/dist/agents/lead.js +3 -1
- package/dist/agents/lead.js.map +1 -1
- package/dist/agents/workers.js +1 -6
- package/dist/agents/workers.js.map +1 -1
- package/dist/cache-refresh.d.ts +42 -0
- package/dist/cache-refresh.js +130 -0
- package/dist/cache-refresh.js.map +1 -0
- package/dist/cli.d.ts +16 -2
- package/dist/cli.js +59 -26
- package/dist/cli.js.map +1 -1
- package/dist/config/schema.d.ts +11 -1
- package/dist/config/schema.js +30 -1
- package/dist/config/schema.js.map +1 -1
- package/dist/dashboard/server.js +2 -2
- package/dist/dashboard/server.js.map +1 -1
- package/dist/index.js +35 -12
- package/dist/index.js.map +1 -1
- package/dist/orchestration/ownership.d.ts +7 -0
- package/dist/orchestration/ownership.js +45 -0
- package/dist/orchestration/ownership.js.map +1 -0
- package/dist/orchestration/worktree-adapter.d.ts +3 -0
- package/dist/orchestration/worktree-adapter.js +45 -0
- package/dist/orchestration/worktree-adapter.js.map +1 -0
- package/dist/orchestration/worktrees.d.ts +22 -0
- package/dist/orchestration/worktrees.js +27 -0
- package/dist/orchestration/worktrees.js.map +1 -0
- package/dist/pricing/cost.d.ts +29 -0
- package/dist/pricing/cost.js +47 -0
- package/dist/pricing/cost.js.map +1 -0
- package/dist/pricing/model-match.d.ts +59 -0
- package/dist/pricing/model-match.js +134 -0
- package/dist/pricing/model-match.js.map +1 -0
- package/dist/pricing/openrouter.d.ts +60 -0
- package/dist/pricing/openrouter.js +150 -0
- package/dist/pricing/openrouter.js.map +1 -0
- package/dist/pricing/resolver.d.ts +50 -0
- package/dist/pricing/resolver.js +145 -0
- package/dist/pricing/resolver.js.map +1 -0
- package/dist/prompts/load.js +1 -1
- package/dist/prompts/load.js.map +1 -1
- package/dist/routing/planner.d.ts +14 -1
- package/dist/routing/planner.js +23 -1
- package/dist/routing/planner.js.map +1 -1
- package/dist/routing/pricing/estimate.d.ts +14 -1
- package/dist/routing/pricing/estimate.js +81 -20
- package/dist/routing/pricing/estimate.js.map +1 -1
- package/dist/telemetry/ledger.d.ts +6 -1
- package/dist/telemetry/ledger.js +15 -3
- package/dist/telemetry/ledger.js.map +1 -1
- package/dist/tools.d.ts +3 -0
- package/dist/tools.js +44 -1
- package/dist/tools.js.map +1 -1
- package/package.json +16 -2
- package/prompts/lead.md +1 -0
- package/schema/opencode-orchestra.schema.json +23 -1
- package/dashboard-dist/assets/index-BZTn_d2K.js +0 -124
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
6
|
<meta name="theme-color" content="#090b10" />
|
|
7
7
|
<title>Orchestra Control</title>
|
|
8
|
-
<script type="module" crossorigin src="/assets/index-
|
|
8
|
+
<script type="module" crossorigin src="/assets/index-Dc5lp8wX.js"></script>
|
|
9
9
|
<link rel="stylesheet" crossorigin href="/assets/index-1lUDKh9b.css">
|
|
10
10
|
</head>
|
|
11
11
|
<body>
|
package/dist/agents/build.js
CHANGED
|
@@ -2,10 +2,14 @@ import { createJudgeAgent } from "./judge.js";
|
|
|
2
2
|
import { createMergeAgent } from "./merge.js";
|
|
3
3
|
import { createLeadAgent } from "./lead.js";
|
|
4
4
|
import { createWorkerAgents } from "./workers.js";
|
|
5
|
+
import { createEditorAgent } from "./editor.js";
|
|
6
|
+
import { createIntegratorAgent } from "./integrator.js";
|
|
5
7
|
export function createAgentSet(config, prompts) {
|
|
6
8
|
const agents = {
|
|
7
9
|
"orch-lead": createLeadAgent(config, prompts.lead),
|
|
8
10
|
...createWorkerAgents(config),
|
|
11
|
+
"orch-editor": createEditorAgent(config),
|
|
12
|
+
"orch-integrator": createIntegratorAgent(config),
|
|
9
13
|
"orch-merge": createMergeAgent(config),
|
|
10
14
|
"orch-judge": createJudgeAgent(config, prompts.judge),
|
|
11
15
|
};
|
package/dist/agents/build.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"build.js","sourceRoot":"","sources":["../../src/agents/build.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AAC7C,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AAC7C,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAA;AAE3C,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAA;
|
|
1
|
+
{"version":3,"file":"build.js","sourceRoot":"","sources":["../../src/agents/build.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AAC7C,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AAC7C,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAA;AAE3C,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAA;AACjD,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AAC/C,OAAO,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAA;AAOvD,MAAM,UAAU,cAAc,CAAC,MAAuB,EAAE,OAAqB;IAC3E,MAAM,MAAM,GAAa;QACvB,WAAW,EAAE,eAAe,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,CAAC;QAClD,GAAG,kBAAkB,CAAC,MAAM,CAAC;QAC7B,aAAa,EAAE,iBAAiB,CAAC,MAAM,CAAC;QACxC,iBAAiB,EAAE,qBAAqB,CAAC,MAAM,CAAC;QAChD,YAAY,EAAE,gBAAgB,CAAC,MAAM,CAAC;QACtC,YAAY,EAAE,gBAAgB,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,CAAC;KACtD,CAAA;IACD,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;QACjE,IAAI,MAAM,CAAC,IAAI,CAAC;YAAE,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,GAAG,KAAK,CAAA;IAC9C,CAAC;IACD,OAAO,MAAM,CAAA;AACf,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { resolveModel } from "../routing/model-resolver.js";
|
|
2
|
+
export function createEditorAgent(config) {
|
|
3
|
+
const resolved = resolveModel({ pool: config.models.worker.code, capability: "code", budget: config.budget, allowPaid: config.budget === "quality" || config.budget === "ebobo", preferredCosts: config.budget === "eco" || config.budget === "balanced" ? ["free"] : [], preferredTiers: ["worker", "lead", "frontier"] });
|
|
4
|
+
return {
|
|
5
|
+
description: "Isolated implementation worker that edits only its assigned ownership partition in an OpenCode git workspace.",
|
|
6
|
+
mode: "subagent", hidden: true, temperature: 0.15,
|
|
7
|
+
prompt: "Work only inside the isolated worktree assigned by OpenCode. Edit only repository-relative paths in the explicit ownership list. Never touch the parent checkout, shared configuration, lockfiles, or files outside ownership. Run scoped verification, commit all changes, and return base revision, commit, changed files, and tests. Do not delegate. Stop on ownership ambiguity.",
|
|
8
|
+
permission: { "*": "deny", read: "allow", edit: "allow", glob: "allow", grep: "allow", list: "allow", lsp: "allow", bash: "allow", task: "deny", external_directory: "deny" },
|
|
9
|
+
...(resolved ? { model: resolved.id } : {}),
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=editor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"editor.js","sourceRoot":"","sources":["../../src/agents/editor.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAA;AAG3D,MAAM,UAAU,iBAAiB,CAAC,MAAuB;IACvD,MAAM,QAAQ,GAAG,YAAY,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,CAAC,MAAM,KAAK,SAAS,IAAI,MAAM,CAAC,MAAM,KAAK,OAAO,EAAE,cAAc,EAAE,MAAM,CAAC,MAAM,KAAK,KAAK,IAAI,MAAM,CAAC,MAAM,KAAK,UAAU,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,cAAc,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,CAAC,CAAA;IAC3T,OAAO;QACL,WAAW,EAAE,+GAA+G;QAC5H,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI;QACjD,MAAM,EAAE,uXAAuX;QAC/X,UAAU,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,kBAAkB,EAAE,MAAM,EAAE;QAC7K,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,QAAQ,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC5C,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { resolveModel } from "../routing/model-resolver.js";
|
|
2
|
+
export function createIntegratorAgent(config) {
|
|
3
|
+
const resolved = resolveModel({ pool: config.models.lead, capability: "reasoning", budget: config.budget, allowPaid: config.budget === "quality" || config.budget === "ebobo", preferredTiers: ["lead", "frontier"] });
|
|
4
|
+
return {
|
|
5
|
+
description: "Deterministic integration worker that validates ownership and integrates isolated editor commits.",
|
|
6
|
+
mode: "subagent", hidden: true, temperature: 0.1,
|
|
7
|
+
prompt: "Integrate validated editor commits in plan-node order. Before cherry-picking, derive changed paths from git and fail closed if any path is unowned, multiply owned, or outside its editor partition. Stop on conflicts; never resolve an ownership conflict autonomously. Run aggregate verification and report commits, files, tests, and retained worktrees. Do not delegate.",
|
|
8
|
+
permission: { "*": "deny", read: "allow", edit: "deny", glob: "allow", grep: "allow", list: "allow", lsp: "allow", bash: "allow", task: "deny", external_directory: "deny" },
|
|
9
|
+
...(resolved ? { model: resolved.id } : {}),
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=integrator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"integrator.js","sourceRoot":"","sources":["../../src/agents/integrator.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAA;AAG3D,MAAM,UAAU,qBAAqB,CAAC,MAAuB;IAC3D,MAAM,QAAQ,GAAG,YAAY,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,CAAC,MAAM,KAAK,SAAS,IAAI,MAAM,CAAC,MAAM,KAAK,OAAO,EAAE,cAAc,EAAE,CAAC,MAAM,EAAE,UAAU,CAAC,EAAE,CAAC,CAAA;IACtN,OAAO;QACL,WAAW,EAAE,mGAAmG;QAChH,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,GAAG;QAChD,MAAM,EAAE,iXAAiX;QACzX,UAAU,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,kBAAkB,EAAE,MAAM,EAAE;QAC5K,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,QAAQ,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC5C,CAAA;AACH,CAAC"}
|
package/dist/agents/lead.js
CHANGED
|
@@ -25,7 +25,7 @@ export function createLeadAgent(config, basePrompt) {
|
|
|
25
25
|
return {
|
|
26
26
|
description: "Primary implementation lead that classifies complex work, dispatches a small specialist team, synthesizes evidence, edits files, and verifies the result.",
|
|
27
27
|
mode: "primary",
|
|
28
|
-
prompt: `${basePrompt.trim()}\n\nExecution protocol: build a dependency DAG; dispatch every currently-ready node concurrently up to the runtime limit; wait for dependencies before releasing downstream nodes; after all evidence nodes finish, call orch-merge exactly once with every result labeled by node id and worker.\n\nEnabled profiles:\n${profileGuide}\n\nRuntime limits: dispatch at most ${config.orchestration.maxWorkers} workers total and at most ${config.orchestration.parallelWorkers} concurrently. Budget mode: ${config.budget}.${config.budget === "ebobo" ? " EBOBO MODE: dispatch the full available specialist roster in parallel, require independent evidence, and always use orch-judge for frontier arbitration." : ""}`,
|
|
28
|
+
prompt: `${basePrompt.trim()}\n\nExecution protocol: build a dependency DAG; dispatch every currently-ready node concurrently up to the runtime limit; wait for dependencies before releasing downstream nodes; after all evidence nodes finish, call orch-merge exactly once with every result labeled by node id and worker. If implementation needs parallel editors, call orchestration_prepare_edit_plan with explicit non-overlapping partitions, then call orchestration_validate_commit for every editor commit before orch-integrator. For editor partitions, resolve one base HEAD SHA, reject overlapping ownership, create one experimental git worktree per editor, dispatch orch-editor nodes only in those worktrees, validate actual git diff and ancestry before calling orch-integrator exactly once, and retain worktrees on failure. Never let parallel editors share a checkout.\n\nEnabled profiles:\n${profileGuide}\n\nRuntime limits: dispatch at most ${config.orchestration.maxWorkers} workers total and at most ${config.orchestration.parallelWorkers} concurrently. Budget mode: ${config.budget}.${config.budget === "ebobo" ? " EBOBO MODE: dispatch the full available specialist roster in parallel, require independent evidence, and always use orch-judge for frontier arbitration." : ""}`,
|
|
29
29
|
hidden: false,
|
|
30
30
|
temperature: 0.2,
|
|
31
31
|
color: "accent",
|
|
@@ -46,6 +46,8 @@ export function createLeadAgent(config, basePrompt) {
|
|
|
46
46
|
task: {
|
|
47
47
|
"*": "deny",
|
|
48
48
|
...workerPermissions,
|
|
49
|
+
"orch-editor": "allow",
|
|
50
|
+
"orch-integrator": "allow",
|
|
49
51
|
"orch-merge": "allow",
|
|
50
52
|
"orch-judge": "allow",
|
|
51
53
|
},
|
package/dist/agents/lead.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lead.js","sourceRoot":"","sources":["../../src/agents/lead.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAA;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAA;AAG3D,MAAM,UAAU,eAAe,CAAC,MAAuB,EAAE,UAAkB;IACzE,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,MAAM,CACnD,CAAC,OAAO,EAAE,EAAE,CAAC,MAAM,CAAC,aAAa,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,KAAK,CACnE,CAAA;IACD,MAAM,YAAY,GAAG,OAAO;SACzB,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,KAAK,OAAO,CAAC,IAAI,KAAK,OAAO,CAAC,OAAO,uBAAuB,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC;SAC3G,IAAI,CAAC,IAAI,CAAC,CAAA;IACb,MAAM,iBAAiB,GAAG,MAAM,CAAC,WAAW,CAC1C,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,OAAO,CAAU,CAAC,CAC/G,CAAA;IACD,MAAM,QAAQ,GAAG,YAAY,CAAC;QAC5B,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI;QACxB,UAAU,EAAE,WAAW;QACvB,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,SAAS,EAAE,MAAM,CAAC,MAAM,KAAK,SAAS,IAAI,MAAM,CAAC,MAAM,KAAK,OAAO;QACnE,cAAc,EAAE,MAAM,CAAC,MAAM,KAAK,UAAU;YAC1C,CAAC,CAAC,CAAC,cAAc,CAAC;YAClB,CAAC,CAAC,MAAM,CAAC,MAAM,KAAK,KAAK;gBACvB,CAAC,CAAC,CAAC,MAAM,CAAC;gBACV,CAAC,CAAC,EAAE;QACR,cAAc,EAAE,MAAM,CAAC,MAAM,KAAK,UAAU;YAC1C,CAAC,CAAC,CAAC,MAAM,CAAC;YACV,CAAC,CAAC,MAAM,CAAC,MAAM,KAAK,SAAS,IAAI,MAAM,CAAC,MAAM,KAAK,OAAO;gBACxD,CAAC,CAAC,CAAC,UAAU,EAAE,MAAM,CAAC;gBACtB,CAAC,CAAC,EAAE;KACT,CAAC,CAAA;IAEF,OAAO;QACL,WAAW,EAAE,2JAA2J;QACxK,IAAI,EAAE,SAAS;QACf,MAAM,EAAE,GAAG,UAAU,CAAC,IAAI,EAAE,
|
|
1
|
+
{"version":3,"file":"lead.js","sourceRoot":"","sources":["../../src/agents/lead.ts"],"names":[],"mappings":"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"}
|
package/dist/agents/workers.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workers.js","sourceRoot":"","sources":["../../src/agents/workers.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAA;AAW3D,MAAM,SAAS,GAAqC;IAClD,GAAG,EAAE,MAAM;IACX,IAAI,EAAE,OAAO;IACb,IAAI,EAAE,OAAO;IACb,IAAI,EAAE,OAAO;IACb,IAAI,EAAE,OAAO;IACb,GAAG,EAAE,OAAO;IACZ,mBAAmB,EAAE,OAAO;IAC5B,mBAAmB,EAAE,OAAO;IAC5B,uBAAuB,EAAE,OAAO;IAChC,IAAI,EAAE,MAAM;IACZ,kBAAkB,EAAE,KAAK;CAC1B,CAAA;AAED,MAAM,OAAO,GAA+B;IAC1C,WAAW,EAAE;QACX,WAAW,EAAE,4GAA4G;QACzH,MAAM,EAAE,iRAAiR;QACzR,IAAI,EAAE,MAAM;QACZ,UAAU,EAAE,MAAM;QAClB,UAAU,EAAE,SAAS;KACtB;IACD,WAAW,EAAE;QACX,WAAW,EAAE,8DAA8D;QAC3E,MAAM,EAAE,+JAA+J;QACvK,IAAI,EAAE,UAAU;QAChB,UAAU,EAAE,UAAU;QACtB,UAAU,EAAE,EAAE,GAAG,SAAS,EAAE,QAAQ,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE;KAC3F;IACD,YAAY,EAAE;QACZ,WAAW,EAAE,mGAAmG;QAChH,MAAM,EAAE,kQAAkQ;QAC1Q,IAAI,EAAE,MAAM;QACZ,UAAU,EAAE,MAAM;QAClB,UAAU,EAAE;YACV,GAAG,SAAS;YACZ,IAAI,EAAE
|
|
1
|
+
{"version":3,"file":"workers.js","sourceRoot":"","sources":["../../src/agents/workers.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
declare const PACKAGE_NAME = "@oeronteros-1/opencode-orchestra";
|
|
2
|
+
/**
|
|
3
|
+
* OpenCode resolves each plugin spec into `<cache>/opencode/packages/<spec>/`
|
|
4
|
+
* and only ever installs there once: an existing `package.json` short-circuits
|
|
5
|
+
* re-resolution. A spec like `@latest` therefore keeps loading the version it
|
|
6
|
+
* first resolved to (e.g. 1.0.8) even after newer versions are published.
|
|
7
|
+
* Exact semver pins (`@1.0.15`) can never drift, so they are not refreshed.
|
|
8
|
+
*/
|
|
9
|
+
export interface PluginCacheReport {
|
|
10
|
+
/** Mutable entries whose cached version already matches the target. */
|
|
11
|
+
upToDate: string[];
|
|
12
|
+
/** Mutable entries updated in place to the running plugin version. */
|
|
13
|
+
reinstalled: string[];
|
|
14
|
+
/** Mutable entries removed after a failed refresh; OpenCode reinstalls them on its next start. */
|
|
15
|
+
invalidated: string[];
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Installs the rewritten pin inside a cache entry directory. Returns false
|
|
19
|
+
* when no package manager succeeded so the caller can fall back to removal.
|
|
20
|
+
*/
|
|
21
|
+
export type RefreshInstaller = (directory: string) => Promise<boolean>;
|
|
22
|
+
export interface RefreshPluginCacheOptions {
|
|
23
|
+
/** The `packages` directory of OpenCode's cache (see openCodePackagesRoot). */
|
|
24
|
+
packagesRoot: string;
|
|
25
|
+
/** Version the cache should resolve to; normally the running CLI version. */
|
|
26
|
+
targetVersion: string;
|
|
27
|
+
/** Classify stale entries without writing or removing anything. */
|
|
28
|
+
dryRun?: boolean;
|
|
29
|
+
/** Test seam replacing the bun/npm installation step. */
|
|
30
|
+
runInstaller?: RefreshInstaller;
|
|
31
|
+
}
|
|
32
|
+
/** Root where OpenCode caches installed plugin packages across platforms. */
|
|
33
|
+
export declare function openCodePackagesRoot(): string;
|
|
34
|
+
/**
|
|
35
|
+
* Bring every mutable Orchestra entry in OpenCode's package cache up to
|
|
36
|
+
* `targetVersion`. Entries that cannot be updated are removed so OpenCode
|
|
37
|
+
* performs a clean install on its next start instead of loading a stale copy.
|
|
38
|
+
*/
|
|
39
|
+
export declare function refreshPluginCache(options: RefreshPluginCacheOptions): Promise<PluginCacheReport>;
|
|
40
|
+
/** Format a cache report as a single human-readable line, or undefined when there is nothing to report. */
|
|
41
|
+
export declare function formatPluginCacheReport(report: PluginCacheReport, dryRun: boolean): string | undefined;
|
|
42
|
+
export { PACKAGE_NAME };
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { spawnSync } from "node:child_process";
|
|
2
|
+
import { readFile, readdir, rm, writeFile } from "node:fs/promises";
|
|
3
|
+
import os from "node:os";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
import { compareVersions } from "./diagnostics/update.js";
|
|
6
|
+
const PACKAGE_NAME = "@oeronteros-1/opencode-orchestra";
|
|
7
|
+
/** Root where OpenCode caches installed plugin packages across platforms. */
|
|
8
|
+
export function openCodePackagesRoot() {
|
|
9
|
+
const cacheRoot = process.env.XDG_CACHE_HOME
|
|
10
|
+
?? (process.platform === "win32" ? process.env.LOCALAPPDATA : undefined)
|
|
11
|
+
?? path.join(os.homedir(), ".cache");
|
|
12
|
+
return path.join(cacheRoot, "opencode", "packages");
|
|
13
|
+
}
|
|
14
|
+
function isExactPin(spec) {
|
|
15
|
+
return /^v?\d+\.\d+\.\d+(?:[-+][\w.]+)*$/.test(spec);
|
|
16
|
+
}
|
|
17
|
+
async function readInstalledVersion(directory) {
|
|
18
|
+
try {
|
|
19
|
+
const manifest = JSON.parse(await readFile(path.join(directory, "node_modules", ...PACKAGE_NAME.split("/"), "package.json"), "utf8"));
|
|
20
|
+
return typeof manifest.version === "string" ? manifest.version : undefined;
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
return undefined;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
async function discoverEntries(packagesRoot) {
|
|
27
|
+
const entries = [];
|
|
28
|
+
// Scoped specs install under `packages/<@scope>/`, so an entry's full name
|
|
29
|
+
// joins the optional scope with the directory name ("opencode-orchestra",
|
|
30
|
+
// "opencode-orchestra@latest"). The remainder after the package name is
|
|
31
|
+
// either empty (bare spec resolves like @latest) or "@spec".
|
|
32
|
+
const consider = (scope, name, directory) => {
|
|
33
|
+
const fullName = scope ? `${scope}/${name}` : name;
|
|
34
|
+
if (!fullName.startsWith(PACKAGE_NAME))
|
|
35
|
+
return;
|
|
36
|
+
const rest = fullName.slice(PACKAGE_NAME.length);
|
|
37
|
+
if (rest !== "" && !rest.startsWith("@"))
|
|
38
|
+
return;
|
|
39
|
+
entries.push({ label: fullName, directory, spec: rest === "" ? "" : rest.slice(1) });
|
|
40
|
+
};
|
|
41
|
+
let scopes = [];
|
|
42
|
+
try {
|
|
43
|
+
scopes = await readdir(packagesRoot, { withFileTypes: true });
|
|
44
|
+
}
|
|
45
|
+
catch {
|
|
46
|
+
return entries;
|
|
47
|
+
}
|
|
48
|
+
for (const scope of scopes) {
|
|
49
|
+
if (scope.name.startsWith("@") && scope.isDirectory()) {
|
|
50
|
+
const scopeDirectory = path.join(packagesRoot, scope.name);
|
|
51
|
+
for (const child of await readdir(scopeDirectory, { withFileTypes: true })) {
|
|
52
|
+
if (child.isDirectory())
|
|
53
|
+
consider(scope.name, child.name, path.join(scopeDirectory, child.name));
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
else if (scope.isDirectory()) {
|
|
57
|
+
consider(undefined, scope.name, path.join(packagesRoot, scope.name));
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return entries.sort((a, b) => a.label.localeCompare(b.label));
|
|
61
|
+
}
|
|
62
|
+
async function reinstallInPlace(entry, version, runInstaller) {
|
|
63
|
+
await writeFile(path.join(entry.directory, "package.json"), `${JSON.stringify({ dependencies: { [PACKAGE_NAME]: version } }, null, 2)}\n`);
|
|
64
|
+
if (runInstaller)
|
|
65
|
+
return runInstaller(entry.directory);
|
|
66
|
+
// OpenCode itself installs plugins with bun; npm covers environments without it.
|
|
67
|
+
const attempts = [
|
|
68
|
+
["bun", ["install"]],
|
|
69
|
+
["npm", ["install", "--no-audit", "--no-fund"]],
|
|
70
|
+
];
|
|
71
|
+
for (const [command, args] of attempts) {
|
|
72
|
+
try {
|
|
73
|
+
const result = spawnSync(command, args, { cwd: entry.directory, stdio: "ignore", shell: process.platform === "win32" });
|
|
74
|
+
if (result.status === 0 && compareVersions((await readInstalledVersion(entry.directory)) ?? "", version) === 0) {
|
|
75
|
+
return true;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
catch {
|
|
79
|
+
// Try the next package manager.
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
return false;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Bring every mutable Orchestra entry in OpenCode's package cache up to
|
|
86
|
+
* `targetVersion`. Entries that cannot be updated are removed so OpenCode
|
|
87
|
+
* performs a clean install on its next start instead of loading a stale copy.
|
|
88
|
+
*/
|
|
89
|
+
export async function refreshPluginCache(options) {
|
|
90
|
+
const report = { upToDate: [], reinstalled: [], invalidated: [] };
|
|
91
|
+
// A source checkout without a resolvable version cannot state a target;
|
|
92
|
+
// refreshing against "unknown" would churn healthy entries.
|
|
93
|
+
if (!/^\d/.test(options.targetVersion))
|
|
94
|
+
return report;
|
|
95
|
+
const entries = await discoverEntries(options.packagesRoot);
|
|
96
|
+
for (const entry of entries) {
|
|
97
|
+
if (isExactPin(entry.spec))
|
|
98
|
+
continue;
|
|
99
|
+
const installed = await readInstalledVersion(entry.directory);
|
|
100
|
+
if (installed !== undefined && compareVersions(installed, options.targetVersion) === 0) {
|
|
101
|
+
report.upToDate.push(entry.label);
|
|
102
|
+
continue;
|
|
103
|
+
}
|
|
104
|
+
if (options.dryRun) {
|
|
105
|
+
report.reinstalled.push(entry.label);
|
|
106
|
+
continue;
|
|
107
|
+
}
|
|
108
|
+
const updated = await reinstallInPlace(entry, options.targetVersion, options.runInstaller).catch(() => false);
|
|
109
|
+
if (updated)
|
|
110
|
+
report.reinstalled.push(entry.label);
|
|
111
|
+
else {
|
|
112
|
+
await rm(entry.directory, { recursive: true, force: true }).catch(() => undefined);
|
|
113
|
+
report.invalidated.push(entry.label);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
return report;
|
|
117
|
+
}
|
|
118
|
+
/** Format a cache report as a single human-readable line, or undefined when there is nothing to report. */
|
|
119
|
+
export function formatPluginCacheReport(report, dryRun) {
|
|
120
|
+
const parts = [];
|
|
121
|
+
if (report.upToDate.length > 0)
|
|
122
|
+
parts.push(`up-to-date: ${report.upToDate.join(", ")}`);
|
|
123
|
+
if (report.reinstalled.length > 0)
|
|
124
|
+
parts.push(`${dryRun ? "stale (would reinstall)" : "reinstalled"}: ${report.reinstalled.join(", ")}`);
|
|
125
|
+
if (report.invalidated.length > 0)
|
|
126
|
+
parts.push(`invalidated: ${report.invalidated.join(", ")}`);
|
|
127
|
+
return parts.length > 0 ? parts.join("; ") : undefined;
|
|
128
|
+
}
|
|
129
|
+
export { PACKAGE_NAME };
|
|
130
|
+
//# sourceMappingURL=cache-refresh.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache-refresh.js","sourceRoot":"","sources":["../src/cache-refresh.ts"],"names":[],"mappings":"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"}
|
package/dist/cli.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import { type PluginCacheReport } from "./cache-refresh.js";
|
|
2
3
|
export interface InstallOptions {
|
|
3
4
|
configDirectory?: string;
|
|
4
5
|
context7: boolean;
|
|
@@ -11,6 +12,12 @@ export interface InstallOptions {
|
|
|
11
12
|
provisionDependencies: boolean;
|
|
12
13
|
force: boolean;
|
|
13
14
|
dryRun: boolean;
|
|
15
|
+
/**
|
|
16
|
+
* Override for OpenCode's plugin package cache (`packages` directory).
|
|
17
|
+
* Tests point this at a temporary directory so runs never touch the
|
|
18
|
+
* real per-user cache.
|
|
19
|
+
*/
|
|
20
|
+
pluginCacheDirectory?: string;
|
|
14
21
|
}
|
|
15
22
|
type DependencyStatus = "installed" | "existing" | "skipped" | "failed";
|
|
16
23
|
export interface InstallResult {
|
|
@@ -19,10 +26,17 @@ export interface InstallResult {
|
|
|
19
26
|
changed: string[];
|
|
20
27
|
preserved: string[];
|
|
21
28
|
backup?: string;
|
|
29
|
+
pluginCache: PluginCacheReport;
|
|
22
30
|
dependencies: {
|
|
23
|
-
codebaseMemory:
|
|
24
|
-
memoryGraph:
|
|
31
|
+
codebaseMemory: ProvisionedDependency;
|
|
32
|
+
memoryGraph: ProvisionedDependency;
|
|
25
33
|
};
|
|
26
34
|
}
|
|
35
|
+
interface ProvisionedDependency {
|
|
36
|
+
command: string | string[];
|
|
37
|
+
status: DependencyStatus;
|
|
38
|
+
reason?: string;
|
|
39
|
+
}
|
|
40
|
+
export declare function failureReason(error: unknown): string | undefined;
|
|
27
41
|
export declare function install(options: InstallOptions): Promise<InstallResult>;
|
|
28
42
|
export {};
|
package/dist/cli.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { spawnSync } from "node:child_process";
|
|
3
|
-
import { copyFile, mkdir, mkdtemp, readFile, realpath, rename, rm, writeFile } from "node:fs/promises";
|
|
3
|
+
import { copyFile, mkdir, mkdtemp, readdir, readFile, realpath, rename, rm, writeFile } from "node:fs/promises";
|
|
4
4
|
import os from "node:os";
|
|
5
5
|
import path from "node:path";
|
|
6
6
|
import { pathToFileURL } from "node:url";
|
|
7
7
|
import { applyEdits, modify, parse, printParseErrorCode } from "jsonc-parser";
|
|
8
|
+
import { formatPluginCacheReport, openCodePackagesRoot, refreshPluginCache } from "./cache-refresh.js";
|
|
8
9
|
import { openCodeConfigDirectory } from "./config/paths.js";
|
|
9
10
|
import { startDashboard } from "./dashboard/server.js";
|
|
10
11
|
import { completionFor, SHELL_NAMES } from "./diagnostics/completion.js";
|
|
@@ -76,10 +77,7 @@ function superPowersName(entry) {
|
|
|
76
77
|
return (hash === -1 ? name : name.slice(0, hash)).toLowerCase();
|
|
77
78
|
}
|
|
78
79
|
function superPowersSkillsPath() {
|
|
79
|
-
|
|
80
|
-
?? (process.platform === "win32" ? process.env.LOCALAPPDATA : undefined)
|
|
81
|
-
?? path.join(os.homedir(), ".cache");
|
|
82
|
-
return path.join(cacheRoot, "opencode", "packages", SUPER_POWERS_ENTRY, "node_modules", "superpowers", "skills");
|
|
80
|
+
return path.join(openCodePackagesRoot(), SUPER_POWERS_ENTRY, "node_modules", "superpowers", "skills");
|
|
83
81
|
}
|
|
84
82
|
async function existingMainConfig(configDirectory) {
|
|
85
83
|
// OpenCode loads JSONC after JSON when both files exist, so update the
|
|
@@ -131,8 +129,15 @@ function run(command, args, env) {
|
|
|
131
129
|
if (result.status !== 0)
|
|
132
130
|
throw new Error(`Command failed (${result.status ?? "unknown"}): ${command} ${args.join(" ")}`);
|
|
133
131
|
}
|
|
132
|
+
// Exported for unit tests: installer output must stay single-line and bounded.
|
|
133
|
+
export function failureReason(error) {
|
|
134
|
+
const raw = error instanceof Error ? error.message : String(error);
|
|
135
|
+
const reason = raw.replace(/[\r\n]+/g, " ").replace(/\s+/g, " ").trim().slice(0, 200);
|
|
136
|
+
return reason || undefined;
|
|
137
|
+
}
|
|
134
138
|
async function downloadScript(url, filename) {
|
|
135
|
-
|
|
139
|
+
// Bounded fetch: a hung registry mirror must not stall the whole install.
|
|
140
|
+
const response = await fetch(url, { redirect: "follow", signal: AbortSignal.timeout(30_000) });
|
|
136
141
|
if (!response.ok)
|
|
137
142
|
throw new Error(`Failed to download ${url}: HTTP ${response.status}`);
|
|
138
143
|
const directory = await mkdtemp(path.join(os.tmpdir(), "opencode-orchestra-"));
|
|
@@ -204,26 +209,42 @@ async function provisionMemoryGraph(enabled) {
|
|
|
204
209
|
const current = executable(["memorygraph", localBin("memorygraph")]);
|
|
205
210
|
if (current)
|
|
206
211
|
return { command: current, status: "existing" };
|
|
212
|
+
// uv provisioning failures abort before the try so they surface verbatim.
|
|
207
213
|
const uv = await ensureUv();
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
214
|
+
try {
|
|
215
|
+
run(uv.command, ["tool", "install", "memorygraphMCP>=0.12"]);
|
|
216
|
+
const toolBin = capture(uv.command, ["tool", "dir", "--bin"]);
|
|
217
|
+
const installed = executable([
|
|
218
|
+
...(toolBin ? [path.join(toolBin, executableName("memorygraph"))] : []),
|
|
219
|
+
localBin("memorygraph"),
|
|
220
|
+
"memorygraph",
|
|
221
|
+
]);
|
|
222
|
+
if (!installed)
|
|
223
|
+
throw new Error("memorygraphMCP installed, but its executable was not found.");
|
|
224
|
+
return { command: installed, status: "installed" };
|
|
225
|
+
}
|
|
226
|
+
catch (error) {
|
|
227
|
+
// PyPI ships a `memorygraph` launcher; fall back to an ephemeral uvx run.
|
|
228
|
+
const uvx = executable([path.join(path.dirname(uv.command), executableName("uvx")), localBin("uvx"), "uvx"]);
|
|
229
|
+
if (!uvx)
|
|
230
|
+
throw error;
|
|
231
|
+
return { command: [uvx, "memorygraph"], status: "installed" };
|
|
232
|
+
}
|
|
218
233
|
}
|
|
219
234
|
export async function install(options) {
|
|
220
235
|
const shouldProvision = options.provisionDependencies && !options.dryRun;
|
|
221
236
|
// Companion MCPs are optional: failed provisioning must not prevent plugin setup.
|
|
222
237
|
const codebase = options.codebaseMemory
|
|
223
|
-
? await provisionCodebaseMemory(shouldProvision).catch(() =>
|
|
238
|
+
? await provisionCodebaseMemory(shouldProvision).catch((error) => {
|
|
239
|
+
const reason = failureReason(error);
|
|
240
|
+
return { command: "codebase-memory-mcp", status: "failed", ...(reason ? { reason } : {}) };
|
|
241
|
+
})
|
|
224
242
|
: { command: "codebase-memory-mcp", status: "skipped" };
|
|
225
243
|
const memoryGraph = options.memoryGraph
|
|
226
|
-
? await provisionMemoryGraph(shouldProvision).catch(() =>
|
|
244
|
+
? await provisionMemoryGraph(shouldProvision).catch((error) => {
|
|
245
|
+
const reason = failureReason(error);
|
|
246
|
+
return { command: "memorygraph", status: "failed", ...(reason ? { reason } : {}) };
|
|
247
|
+
})
|
|
227
248
|
: { command: "memorygraph", status: "skipped" };
|
|
228
249
|
const configDirectory = path.resolve(options.configDirectory ?? openCodeConfigDirectory());
|
|
229
250
|
const openCodeConfig = await existingMainConfig(configDirectory);
|
|
@@ -345,18 +366,19 @@ export async function install(options) {
|
|
|
345
366
|
if (options.playwright !== false) {
|
|
346
367
|
addMcp("playwright", { type: "local", command: PLAYWRIGHT_COMMAND, enabled: true, timeout: 30_000 });
|
|
347
368
|
}
|
|
348
|
-
|
|
369
|
+
// A failed provisioning never persists an MCP entry pointing at a dead command.
|
|
370
|
+
if (options.codebaseMemory && codebase.status !== "failed") {
|
|
349
371
|
addMcp("codebase-memory", {
|
|
350
372
|
type: "local",
|
|
351
|
-
command: [codebase.command],
|
|
373
|
+
command: Array.isArray(codebase.command) ? codebase.command : [codebase.command],
|
|
352
374
|
enabled: true,
|
|
353
375
|
timeout: 30_000,
|
|
354
376
|
});
|
|
355
377
|
}
|
|
356
|
-
if (options.memoryGraph) {
|
|
378
|
+
if (options.memoryGraph && memoryGraph.status !== "failed") {
|
|
357
379
|
addMcp("memorygraph", {
|
|
358
380
|
type: "local",
|
|
359
|
-
command: [memoryGraph.command],
|
|
381
|
+
command: Array.isArray(memoryGraph.command) ? memoryGraph.command : [memoryGraph.command],
|
|
360
382
|
enabled: true,
|
|
361
383
|
timeout: 30_000,
|
|
362
384
|
});
|
|
@@ -370,6 +392,13 @@ export async function install(options) {
|
|
|
370
392
|
}
|
|
371
393
|
await atomicWrite(openCodeConfig, updated.endsWith("\n") ? updated : `${updated}\n`);
|
|
372
394
|
}
|
|
395
|
+
// Reinstalling the plugin must also refresh OpenCode's package cache:
|
|
396
|
+
// an entry like `@latest` keeps its first-resolved version until removed.
|
|
397
|
+
const pluginCache = await refreshPluginCache({
|
|
398
|
+
packagesRoot: path.resolve(options.pluginCacheDirectory ?? openCodePackagesRoot()),
|
|
399
|
+
targetVersion: await resolvePluginVersion(),
|
|
400
|
+
...(options.dryRun ? { dryRun: true } : {}),
|
|
401
|
+
});
|
|
373
402
|
try {
|
|
374
403
|
const orchestraOriginal = await readFile(orchestraConfig, "utf8");
|
|
375
404
|
parseObject(orchestraOriginal, orchestraConfig);
|
|
@@ -394,9 +423,10 @@ export async function install(options) {
|
|
|
394
423
|
changed,
|
|
395
424
|
preserved,
|
|
396
425
|
...(backup ? { backup } : {}),
|
|
426
|
+
pluginCache,
|
|
397
427
|
dependencies: {
|
|
398
|
-
codebaseMemory: codebase
|
|
399
|
-
memoryGraph: memoryGraph
|
|
428
|
+
codebaseMemory: codebase,
|
|
429
|
+
memoryGraph: memoryGraph,
|
|
400
430
|
},
|
|
401
431
|
};
|
|
402
432
|
}
|
|
@@ -578,8 +608,11 @@ async function main() {
|
|
|
578
608
|
const result = await install(parsed.options);
|
|
579
609
|
console.log(`OpenCode Orchestra configured: ${result.openCodeConfig}`);
|
|
580
610
|
console.log(`Agent settings: ${result.orchestraConfig}`);
|
|
581
|
-
|
|
582
|
-
console.log(`
|
|
611
|
+
const cacheSummary = formatPluginCacheReport(result.pluginCache, parsed.options.dryRun);
|
|
612
|
+
console.log(`OpenCode plugin cache: ${cacheSummary ?? "no cached Orchestra entries"}`);
|
|
613
|
+
const dependencyLine = ({ status, reason }) => `${status}${reason ? ` (${reason})` : ""}`;
|
|
614
|
+
console.log(`Codebase Memory: ${dependencyLine(result.dependencies.codebaseMemory)}`);
|
|
615
|
+
console.log(`MemoryGraph: ${dependencyLine(result.dependencies.memoryGraph)}`);
|
|
583
616
|
if (result.changed.length > 0)
|
|
584
617
|
console.log(`Changed: ${result.changed.join(", ")}`);
|
|
585
618
|
if (result.preserved.length > 0)
|