opencode-agent-skill 11.0.0 → 13.0.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/CHANGELOG.md +55 -0
  2. package/README.md +119 -14
  3. package/bin/ocskill.mjs +416 -83
  4. package/docs/DETERMINISTIC-TOOLS.md +1 -1
  5. package/docs/ENGINEERING-DESIGN.md +4 -4
  6. package/docs/EVALS.md +3 -3
  7. package/docs/GITHUB-RULESET.md +50 -0
  8. package/docs/NPM-PUBLISH.md +22 -8
  9. package/docs/OPENCODE-COMPAT.md +14 -4
  10. package/docs/TRACE-SCHEMA.md +1 -1
  11. package/docs/V11-PERCEPTION-ADAPTIVE.md +2 -2
  12. package/docs/V12-WEAK-MODEL-INTELLIGENCE.md +27 -0
  13. package/docs/V13-PARALLEL-WEAK-MODEL-RUNTIME.md +75 -0
  14. package/evals/repo-scale/tasks.json +62 -0
  15. package/global-config/AGENTS.md +4 -0
  16. package/global-config/commands/resume.md +4 -1
  17. package/global-config/commands/run.md +9 -7
  18. package/global-config/plugins/ues-router/capabilities.js +1 -0
  19. package/global-config/plugins/ues-router/command-runtime.js +79 -0
  20. package/global-config/plugins/ues-router/index.js +364 -43
  21. package/global-config/plugins/ues-router/parallel-runtime.js +271 -0
  22. package/global-config/plugins/ues-router/text-runtime.js +115 -0
  23. package/global-config/plugins/ues-router/verifier-runtime.js +33 -0
  24. package/global-config/skills/dynamic-workflow/SKILL.md +7 -6
  25. package/global-config/skills/dynamic-workflow/references/workflow.md +8 -6
  26. package/global-config/skills/engineering-orchestrator/references/long-horizon.md +7 -5
  27. package/lib/cli-utils.mjs +17 -4
  28. package/lib/context-engine-v11.mjs +4 -0
  29. package/lib/context-quality.mjs +59 -0
  30. package/lib/decision-policy.mjs +23 -0
  31. package/lib/installer.mjs +49 -16
  32. package/lib/model-config.mjs +13 -1
  33. package/lib/model-performance.mjs +113 -0
  34. package/lib/model-policy.mjs +9 -2
  35. package/lib/repo-scale-fixture.mjs +45 -0
  36. package/lib/task-engine.mjs +36 -12
  37. package/lib/task-graph.mjs +32 -0
  38. package/lib/text-encoding.mjs +74 -0
  39. package/lib/work-plan-scope.mjs +49 -0
  40. package/lib/worktree-sandbox.mjs +141 -12
  41. package/package.json +8 -4
  42. package/scripts/check-release-consistency.mjs +260 -0
  43. package/scripts/smoke-packed-install.mjs +39 -3
  44. package/scripts/smoke-plain-install.mjs +27 -7
  45. package/scripts/validate-repo-scale-suite.mjs +27 -0
  46. package/scripts/validate-v12-foundation.mjs +24 -0
  47. package/scripts/validate.mjs +18 -1
@@ -96,7 +96,9 @@ try {
96
96
  assert.equal(state.package, packageName)
97
97
  assert.equal(state.version, packageJson.version)
98
98
  assert.ok(state.skills.length >= 39)
99
- assert.ok(state.commands.length >= 11)
99
+ assert.deepEqual(state.commands, [])
100
+ assert.ok(state.promptAliases.length >= 11)
101
+ assert.ok(state.promptAliases.includes("ues-run"))
100
102
  assert.ok(state.agents.length >= 10)
101
103
  assert.equal(state.openCodeMajor, 2)
102
104
  assert.deepEqual(state.plugins, ["ues-router/index.js"])
@@ -106,8 +108,16 @@ try {
106
108
  assert.ok(existsSync(path.join(configDir, "plugins", "ues-router", "router.js")), "v2 router helper was not installed from packed package")
107
109
  assert.ok(existsSync(path.join(configDir, "plugins", "ues-router", "safety.js")), "v2 router safety gate was not installed from packed package")
108
110
  assert.ok(existsSync(path.join(configDir, "plugins", "ues-router", "capabilities.js")), "v8 router capability probe was not installed from packed package")
111
+ assert.ok(existsSync(path.join(configDir, "plugins", "ues-router", "parallel-runtime.js")), "v13 parallel runtime was not installed from packed package")
112
+ assert.ok(existsSync(path.join(configDir, "plugins", "ues-router", "text-runtime.js")), "v13 UTF-aware text runtime was not installed from packed package")
113
+ assert.ok(existsSync(path.join(configDir, "plugins", "ues-router", "verifier-runtime.js")), "v13 verifier runtime was not installed from packed package")
114
+ assert.ok(existsSync(path.join(configDir, "plugins", "ues-router", "command-runtime.js")), "v13 prompt alias runtime was not installed from packed package")
115
+ assert.ok(existsSync(path.join(configDir, "plugins", "ues-router", "command-templates", "run.md")), "v13 /ues-run prompt alias template was not installed from packed package")
116
+ assert.equal(existsSync(path.join(configDir, "commands", "ues-run.md")), false, "v2 install must not leave a native /ues-run custom command")
109
117
  const routerSource = await readFile(routerPlugin, "utf8")
110
118
  assert.match(routerSource, /name: "dispatch_task"/)
119
+ assert.match(routerSource, /name: "dispatch_parallel"/)
120
+ assert.match(routerSource, /name: "text_read"/)
111
121
  assert.match(routerSource, /ctx\.session\.create/)
112
122
  assert.match(routerSource, /ctx\.session\.switchAgent/)
113
123
  assert.match(routerSource, /ctx\.session\.switchModel/)
@@ -136,6 +146,32 @@ try {
136
146
  })
137
147
  requireSuccess(inspect, "ocskill inspect from packed copy")
138
148
 
149
+ const compactGraph = spawnSync(process.execPath, [cli, "repo-graph", temp, "--compact"], {
150
+ cwd: temp,
151
+ env,
152
+ encoding: "utf8",
153
+ })
154
+ requireSuccess(compactGraph, "ocskill compact repo-graph from packed copy")
155
+ const compactGraphPayload = JSON.parse(compactGraph.stdout)
156
+ assert.equal(typeof compactGraphPayload.nodeCount, "number")
157
+ assert.equal(typeof compactGraphPayload.edgeCount, "number")
158
+ assert.equal("nodes" in compactGraphPayload, false)
159
+ assert.equal("edges" in compactGraphPayload, false)
160
+
161
+ const utf16TextFile = path.join(temp, "legacy-plan.txt")
162
+ const utf16Body = "legacy UTF text from packed copy\n"
163
+ await writeFile(
164
+ utf16TextFile,
165
+ Buffer.concat([Buffer.from([0xff, 0xfe]), Buffer.from(utf16Body, "utf16le")]),
166
+ )
167
+ const textRead = spawnSync(process.execPath, [cli, "text-read", utf16TextFile, "--json"], {
168
+ cwd: temp,
169
+ env,
170
+ encoding: "utf8",
171
+ })
172
+ requireSuccess(textRead, "ocskill text-read from packed copy")
173
+ assert.equal(JSON.parse(textRead.stdout).text, utf16Body)
174
+
139
175
  const planFile = path.join(temp, "PLAN.json")
140
176
  await writeFile(planFile, JSON.stringify({
141
177
  schemaVersion: 1,
@@ -256,7 +292,7 @@ try {
256
292
  encoding: "utf8",
257
293
  })
258
294
  requireSuccess(workComplete, "ocskill work complete from packed copy")
259
- assert.match(workComplete.stdout, /"evidenceStrength": "receipt-backed"/)
295
+ assert.match(workComplete.stdout, /"evidenceStrength": "command-receipt-backed"/)
260
296
 
261
297
  const finalizeBeforeVerify = spawnSync(process.execPath, [cli, "work", "finalize", "packed-smoke", temp, "--evidence", "should fail"], {
262
298
  cwd: temp,
@@ -453,7 +489,7 @@ try {
453
489
 
454
490
  console.log(
455
491
  `One-command packed install smoke passed for ${packageName}@${packageJson.version}: ` +
456
- `${state.skills.length} skills, ${state.commands.length} commands, ${state.agents.length} subagents, ${state.plugins.length} v2 router plugin.`,
492
+ `${state.skills.length} skills, ${state.promptAliases.length} prompt aliases, ${state.agents.length} subagents, ${state.plugins.length} v2 router plugin.`,
457
493
  )
458
494
  } finally {
459
495
  await rm(temp, { recursive: true, force: true })
@@ -65,26 +65,46 @@ try {
65
65
 
66
66
  const stateFile = path.join(configDir, ".ues", "state.json")
67
67
  const autoSynced = existsSync(stateFile)
68
+ let manualSyncFallback = false
69
+ if (!autoSynced) {
70
+ // npm 11+ may block third-party lifecycle scripts until the user explicitly
71
+ // allows them. The package must still leave a usable CLI that can perform
72
+ // the documented deterministic fallback without reinstalling the package.
73
+ const sync = spawnSync(process.execPath, [cli, "install"], {
74
+ cwd: temp,
75
+ env: { ...process.env, OPENCODE_CONFIG_DIR: configDir, UES_OPENCODE_MAJOR: "2" },
76
+ encoding: "utf8",
77
+ })
78
+ requireSuccess(sync, "manual ocskill resource sync fallback")
79
+ manualSyncFallback = true
80
+ }
81
+
68
82
  assert.equal(
69
- autoSynced,
83
+ existsSync(stateFile),
70
84
  true,
71
- "plain npm install installed the CLI but did not auto-sync OpenCode resources; one-command installation is not release-safe",
85
+ "global npm install did not produce a usable resource sync path",
72
86
  )
73
-
74
87
  const state = JSON.parse(await readFile(stateFile, "utf8"))
75
88
  assert.equal(state.package, packageName)
89
+ assert.equal(state.openCodeMajor, 2)
76
90
  assert.ok(state.skills.length >= 39)
77
- assert.ok(state.commands.length >= 11)
91
+ assert.deepEqual(state.commands, [])
92
+ assert.ok(state.promptAliases.length >= 11)
93
+ assert.ok(state.promptAliases.includes("ues-run"))
78
94
  assert.ok(state.agents.length >= 10)
95
+ assert.ok(existsSync(path.join(configDir, "plugins", "ues-router", "command-runtime.js")))
96
+ assert.ok(existsSync(path.join(configDir, "plugins", "ues-router", "command-templates", "run.md")))
97
+ assert.equal(existsSync(path.join(configDir, "commands", "ues-run.md")), false)
79
98
 
80
99
  console.log(
81
100
  "Plain npm install compatibility smoke passed for " + packageName + "@" + packageJson.version +
82
101
  ": npm " + npmVersion + ", lifecycle auto-sync=" + autoSynced +
83
- ", final resources=" + state.skills.length + "/" + state.commands.length + "/" + state.agents.length + ".",
102
+ ", manual sync fallback=" + manualSyncFallback +
103
+ ", final resources=" + state.skills.length + " skills/" + state.promptAliases.length + " prompt-aliases/" + state.agents.length + " agents.",
84
104
  )
85
105
 
86
- if (Number.isFinite(npmMajor) && npmMajor >= 11) {
87
- console.warn("[smoke] npm 11+ completed the one-command install and resource auto-sync contract.")
106
+ if (Number.isFinite(npmMajor) && npmMajor >= 11 && manualSyncFallback) {
107
+ console.warn("[smoke] npm 11+ blocked lifecycle auto-sync; documented 'ocskill install' fallback succeeded.")
88
108
  }
89
109
  } finally {
90
110
  await rm(temp, { recursive: true, force: true })
@@ -0,0 +1,27 @@
1
+ #!/usr/bin/env node
2
+ import { mkdtemp, readFile, rm } from "node:fs/promises"
3
+ import os from "node:os"
4
+ import path from "node:path"
5
+ import { fileURLToPath } from "node:url"
6
+ import { generateRepoScaleFixture } from "../lib/repo-scale-fixture.mjs"
7
+
8
+ const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..")
9
+ const suite = JSON.parse(await readFile(path.join(root, "evals", "repo-scale", "tasks.json"), "utf8"))
10
+ const errors = []
11
+ if (!Array.isArray(suite.tasks) || suite.tasks.length < 4) errors.push("repo-scale suite must define at least 4 tasks")
12
+ for (const task of suite.tasks || []) {
13
+ if (!task.id || !task.objective || task.objective.length < 40) errors.push((task.id || "<missing>") + ": objective too weak")
14
+ if (!Array.isArray(task.requiredFiles) || task.requiredFiles.length < 2) errors.push((task.id || "<missing>") + ": requiredFiles must contain at least 2 paths")
15
+ if (!Array.isArray(task.acceptance) || task.acceptance.length < 2) errors.push((task.id || "<missing>") + ": acceptance must contain at least 2 checks")
16
+ }
17
+ const tmp = await mkdtemp(path.join(os.tmpdir(), "ues-repo-scale-"))
18
+ try {
19
+ const generated = await generateRepoScaleFixture(tmp)
20
+ if (generated.generatedModules < Number(suite.minimumGeneratedModules || 300)) errors.push("generated repo too small: " + generated.generatedModules + " modules")
21
+ } finally { await rm(tmp, { recursive: true, force: true }) }
22
+ if (errors.length) {
23
+ console.error("Repo-scale suite validation failed:")
24
+ for (const error of errors) console.error("- " + error)
25
+ process.exit(1)
26
+ }
27
+ console.log("Validated repo-scale suite: " + suite.tasks.length + " tasks, >=" + suite.minimumGeneratedModules + " generated modules.")
@@ -0,0 +1,24 @@
1
+ #!/usr/bin/env node
2
+ import { existsSync } from "node:fs"
3
+ import { readFile } from "node:fs/promises"
4
+ import path from "node:path"
5
+ import { fileURLToPath } from "node:url"
6
+
7
+ const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..")
8
+ const errors = []
9
+ const required = [
10
+ "lib/model-performance.mjs","lib/context-quality.mjs","lib/work-plan-scope.mjs",
11
+ "lib/decision-policy.mjs","lib/repo-scale-fixture.mjs","evals/repo-scale/tasks.json",
12
+ "scripts/validate-repo-scale-suite.mjs",
13
+ ]
14
+ for (const relative of required) if (!existsSync(path.join(root, relative))) errors.push("missing V12 foundation file: " + relative)
15
+ const pkg = JSON.parse(await readFile(path.join(root, "package.json"), "utf8"))
16
+ for (const script of ["evals:v12:validate","evals:repo-scale:validate"]) if (!pkg.scripts?.[script]) errors.push("package.json missing script " + script)
17
+ const tasks = JSON.parse(await readFile(path.join(root, "evals", "repo-scale", "tasks.json"), "utf8"))
18
+ if ((tasks.tasks || []).length < 4) errors.push("V12 repo-scale suite needs at least 4 contract tasks")
19
+ if (errors.length) {
20
+ console.error("V12 foundation validation failed:")
21
+ for (const error of errors) console.error("- " + error)
22
+ process.exit(1)
23
+ }
24
+ console.log("Validated V12 weak-model intelligence foundation files and repo-scale contracts.")
@@ -98,12 +98,25 @@ const routerIndex = path.join(pluginsRoot, "ues-router", "index.js")
98
98
  const routerCore = path.join(pluginsRoot, "ues-router", "router.js")
99
99
  const routerSafety = path.join(pluginsRoot, "ues-router", "safety.js")
100
100
  const routerCapabilities = path.join(pluginsRoot, "ues-router", "capabilities.js")
101
+ const routerParallelRuntime = path.join(pluginsRoot, "ues-router", "parallel-runtime.js")
102
+ const routerTextRuntime = path.join(pluginsRoot, "ues-router", "text-runtime.js")
103
+ const routerVerifierRuntime = path.join(pluginsRoot, "ues-router", "verifier-runtime.js")
104
+ const routerCommandRuntime = path.join(pluginsRoot, "ues-router", "command-runtime.js")
101
105
  if (!existsSync(routerIndex)) errors.push("missing OpenCode v2 router plugin entrypoint")
102
106
  if (!existsSync(routerCore)) errors.push("missing OpenCode v2 router core")
103
107
  if (!existsSync(routerSafety)) errors.push("missing OpenCode v2 safety gate")
104
108
  if (!existsSync(routerCapabilities)) errors.push("missing OpenCode v2 runtime capability probe")
109
+ if (!existsSync(routerParallelRuntime)) errors.push("missing V13 same-model parallel runtime")
110
+ if (!existsSync(routerTextRuntime)) errors.push("missing V13 UTF-aware router text runtime")
111
+ if (!existsSync(routerVerifierRuntime)) errors.push("missing V13 verifier verdict runtime")
112
+ if (!existsSync(routerCommandRuntime)) errors.push("missing V13 V2 prompt alias runtime")
105
113
  if (existsSync(routerIndex)) {
106
114
  const source = await readFile(routerIndex, "utf8")
115
+ if (source.includes("@opencode/plugin")) errors.push("v2 router plugin must be self-contained and not require @opencode/plugin at runtime")
116
+ if (!source.includes("export default {")) errors.push("v2 router plugin must export a plain default plugin definition")
117
+ if (!source.includes("function spawnHidden")) errors.push("v2 router plugin must centralize subprocesses through spawnHidden")
118
+ if (!source.includes("windowsHide: true")) errors.push("v2 router plugin must hide Windows child-process consoles")
119
+ if ((source.match(/\bspawnSync\s*\(/g) || []).length !== 1) errors.push("v2 router plugin must not call spawnSync directly outside spawnHidden")
107
120
  if (!source.includes('id: "ues-router"')) errors.push("v2 router plugin must declare stable id ues-router")
108
121
  if (!source.includes('ctx.session.hook("prompt"')) errors.push("v2 router plugin must register prompt admission hook")
109
122
  if (!source.includes('ctx.session.hook("context"')) errors.push("v2 router plugin must register context guardrail hook")
@@ -125,6 +138,10 @@ if (existsSync(routerIndex)) {
125
138
  if (!source.includes('name: "visual_geometry"')) errors.push("v11 router plugin must expose visual geometry receipts")
126
139
  if (!source.includes('name: "visual_compare"')) errors.push("v11 router plugin must expose deterministic PNG comparison")
127
140
  if (!source.includes('name: "workflow_plan"')) errors.push("v11 router plugin must expose dynamic workflow planning")
141
+ if (!source.includes('name: "dispatch_parallel"')) errors.push("v13 router plugin must expose same-model parallel dispatch")
142
+ if (!source.includes("expandUesPromptAlias")) errors.push("v13 router plugin must expand UES slash aliases through session.prompt")
143
+ if (!source.includes("command-templates")) errors.push("v13 router plugin must load managed prompt alias templates")
144
+ if (!source.includes('name: "text_read"')) errors.push("v13 router plugin must expose UTF-aware text recovery")
128
145
  if (!source.includes('name: "ui_tokens"')) errors.push("v11 router plugin must expose compact design-token extraction")
129
146
  if (!source.includes('name: "ui_layout"')) errors.push("v11 router plugin must expose responsive UI layout verification")
130
147
  if (!source.includes("ctx.session.interrupt")) errors.push("v8 task dispatch must interrupt timed-out executors")
@@ -150,7 +167,7 @@ if (existsSync(plainInstallSmoke)) {
150
167
  }
151
168
  }
152
169
 
153
- for (const name of ["process-runner.mjs","evidence-receipt.mjs","gate-receipt.mjs","runtime-events.mjs","context-manifest.mjs","orchestrator-policy.mjs","worktree-sandbox.mjs","learning-engine.mjs","hermes-bridge.mjs","control-center.mjs","evidence-store.mjs","evidence-budget.mjs","prompt-cache.mjs","capability-registry.mjs","visual-spec.mjs","png-diff.mjs","browser-adapter.mjs","browser-runtime.mjs","dynamic-workflow.mjs","skill-quality.mjs","ui-inspector.mjs","context-engine-v11.mjs","v11-metrics.mjs"]) {
170
+ for (const name of ["process-runner.mjs","evidence-receipt.mjs","gate-receipt.mjs","runtime-events.mjs","context-manifest.mjs","orchestrator-policy.mjs","worktree-sandbox.mjs","learning-engine.mjs","hermes-bridge.mjs","control-center.mjs","evidence-store.mjs","evidence-budget.mjs","prompt-cache.mjs","capability-registry.mjs","visual-spec.mjs","png-diff.mjs","browser-adapter.mjs","browser-runtime.mjs","dynamic-workflow.mjs","skill-quality.mjs","ui-inspector.mjs","context-engine-v11.mjs","v11-metrics.mjs","text-encoding.mjs"]) {
154
171
  if (!existsSync(path.join(root, "lib", name))) errors.push(`missing V8 core module ${name}`)
155
172
  }
156
173