oh-my-opencode 4.12.0 → 4.12.1

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 (54) hide show
  1. package/dist/cli/index.js +36 -17
  2. package/dist/cli-node/index.js +36 -17
  3. package/dist/index.js +361 -254
  4. package/dist/skills/ultraresearch/SKILL.md +11 -2
  5. package/dist/tools/background-task/constants.d.ts +1 -1
  6. package/dist/tui.js +9 -3
  7. package/package.json +13 -13
  8. package/packages/omo-codex/plugin/.codex-plugin/plugin.json +3 -1
  9. package/packages/omo-codex/plugin/components/bootstrap/package.json +1 -1
  10. package/packages/omo-codex/plugin/components/codegraph/dist/cli.js +327 -171
  11. package/packages/omo-codex/plugin/components/codegraph/dist/serve.js +275 -31
  12. package/packages/omo-codex/plugin/components/codegraph/package.json +1 -1
  13. package/packages/omo-codex/plugin/components/codegraph/src/cli.ts +11 -0
  14. package/packages/omo-codex/plugin/components/codegraph/src/hook-types.ts +12 -0
  15. package/packages/omo-codex/plugin/components/codegraph/src/hook.ts +34 -0
  16. package/packages/omo-codex/plugin/components/codegraph/src/serve.ts +40 -3
  17. package/packages/omo-codex/plugin/components/codegraph/src/session-start-worker.ts +6 -5
  18. package/packages/omo-codex/plugin/components/codegraph/test/hook.test.ts +49 -87
  19. package/packages/omo-codex/plugin/components/codegraph/test/provisioned-node-guard.test.ts +1 -1
  20. package/packages/omo-codex/plugin/components/codegraph/test/serve-provision.test.ts +48 -0
  21. package/packages/omo-codex/plugin/components/codegraph/test/serve.test.ts +1 -0
  22. package/packages/omo-codex/plugin/components/codegraph/test/session-start-node-support.test.ts +142 -0
  23. package/packages/omo-codex/plugin/components/comment-checker/package.json +1 -1
  24. package/packages/omo-codex/plugin/components/git-bash/package.json +1 -1
  25. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/package.json +1 -1
  26. package/packages/omo-codex/plugin/components/lsp/package.json +1 -1
  27. package/packages/omo-codex/plugin/components/rules/package.json +1 -1
  28. package/packages/omo-codex/plugin/components/start-work-continuation/package.json +1 -1
  29. package/packages/omo-codex/plugin/components/teammode/dist/cli.js +94 -0
  30. package/packages/omo-codex/plugin/components/teammode/hooks/hooks.json +17 -0
  31. package/packages/omo-codex/plugin/components/teammode/package.json +26 -0
  32. package/packages/omo-codex/plugin/components/teammode/src/cli.ts +12 -0
  33. package/packages/omo-codex/plugin/components/teammode/src/codex-hook.ts +125 -0
  34. package/packages/omo-codex/plugin/components/teammode/test/thread-title-hook.test.ts +116 -0
  35. package/packages/omo-codex/plugin/components/teammode/tsconfig.json +25 -0
  36. package/packages/omo-codex/plugin/components/telemetry/package.json +1 -1
  37. package/packages/omo-codex/plugin/components/ultrawork/package.json +1 -1
  38. package/packages/omo-codex/plugin/components/ulw-loop/package.json +1 -1
  39. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-codegraph-init-guidance.json +17 -0
  40. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-thread-title-hygiene.json +17 -0
  41. package/packages/omo-codex/plugin/hooks/session-start-checking-codegraph-bootstrap.json +1 -1
  42. package/packages/omo-codex/plugin/package-lock.json +30 -12
  43. package/packages/omo-codex/plugin/package.json +2 -1
  44. package/packages/omo-codex/plugin/scripts/hook-status-message.mjs +1 -0
  45. package/packages/omo-codex/plugin/skills/ultraresearch/SKILL.md +11 -2
  46. package/packages/omo-codex/plugin/test/aggregate-hooks.test.mjs +36 -0
  47. package/packages/omo-codex/plugin/test/aggregate-manifest.test.mjs +2 -1
  48. package/packages/omo-codex/plugin/test/aggregate-plugin-fixture.mjs +1 -1
  49. package/packages/omo-codex/plugin/test/component-bundled-cli.test.mjs +1 -0
  50. package/packages/omo-codex/plugin/test/component-hook-contract-cases.mjs +24 -0
  51. package/packages/omo-codex/plugin/test/hook-status-message.test.mjs +1 -0
  52. package/packages/omo-codex/plugin/test/ultraresearch-skill-contract.test.mjs +48 -0
  53. package/packages/omo-codex/scripts/install-dist/install-local.mjs +14 -1
  54. package/packages/shared-skills/skills/ultraresearch/SKILL.md +11 -2
@@ -25,6 +25,7 @@ const AGGREGATE_EXPECTED_LABELS = new Map([
25
25
  ["hooks/hooks.json:PreToolUse:1:0", "Enforcing Unlimited Goal Budget"],
26
26
  ["hooks/hooks.json:PostToolUse:0:0", "Checking Comments"],
27
27
  ["hooks/hooks.json:PostToolUse:0:1", "Checking LSP Diagnostics"],
28
+ ["hooks/hooks.json:PostToolUse:0:2", "Checking CodeGraph Init Guidance"],
28
29
  ["hooks/hooks.json:PostToolUse:1:0", "Matching Project Rules"],
29
30
  ["hooks/hooks.json:PostCompact:0:0", "Resetting Git Bash MCP Reminder"],
30
31
  ["hooks/hooks.json:PostCompact:1:0", "Resetting Project Rule Cache"],
@@ -124,3 +124,51 @@ test("#given ultraresearch worker sizing #when spawn guidance is inspected #then
124
124
  );
125
125
  }
126
126
  });
127
+
128
+ test("#given ultraresearch execution substrate #when team usage is inspected #then it prefers a cooperating team with harness-native team tools", async () => {
129
+ for (const copy of await readUltraresearchCopies()) {
130
+ assert.match(
131
+ copy.content,
132
+ /cooperating team/i,
133
+ `${copy.label}: body must encourage running the swarm as a cooperating team`,
134
+ );
135
+ assert.match(copy.content, /\bteammode\b/i, `${copy.label}: body must name the Codex teammode skill`);
136
+ assert.match(copy.content, /team_mode/i, `${copy.label}: body must name the OpenCode team_mode path`);
137
+ }
138
+ });
139
+
140
+ test("#given ultraresearch team composition #when member slicing is inspected #then members map to part/ownership/perspective, never job titles", async () => {
141
+ for (const copy of await readUltraresearchCopies()) {
142
+ assert.match(
143
+ copy.content,
144
+ /by part, ownership, or perspective/i,
145
+ `${copy.label}: body must compose members by part, ownership, or perspective`,
146
+ );
147
+ assert.match(
148
+ copy.content,
149
+ /never a job title|not (?:a |by )?job title/i,
150
+ `${copy.label}: body must forbid vague job-title members`,
151
+ );
152
+ }
153
+ });
154
+
155
+ test("#given ultraresearch team communication #when the raise law is inspected #then members broadcast every lead immediately rather than hoarding", async () => {
156
+ for (const copy of await readUltraresearchCopies()) {
157
+ assert.match(
158
+ copy.content,
159
+ /raise law|broadcast every lead/i,
160
+ `${copy.label}: body must state the raise/broadcast law`,
161
+ );
162
+ assert.match(copy.content, /over-communicate/i, `${copy.label}: body must demand over-communication`);
163
+ assert.match(
164
+ copy.content,
165
+ /the (?:moment|instant) it (?:surfaces|appears|lands)/i,
166
+ `${copy.label}: body must require raising leads the moment they surface`,
167
+ );
168
+ assert.match(
169
+ copy.content,
170
+ /hoard/i,
171
+ `${copy.label}: body must reject hoarding leads for a final dump`,
172
+ );
173
+ }
174
+ });
@@ -5907,7 +5907,7 @@ var package_default;
5907
5907
  var init_package = __esm(() => {
5908
5908
  package_default = {
5909
5909
  name: "@oh-my-opencode/omo-codex",
5910
- version: "4.12.0",
5910
+ version: "4.12.1",
5911
5911
  type: "module",
5912
5912
  private: true,
5913
5913
  description: "Codex harness adapter for oh-my-openagent. Vendored Codex plugin namespace (omo) + TypeScript installer + telemetry.",
@@ -7139,6 +7139,8 @@ async function installCachedPlugin(input) {
7139
7139
  await rewriteCachedPackageLocalFileDependencies(tempPath, input.sourcePath);
7140
7140
  await copyBundledMcpRuntimeDists({ pluginRoot: tempPath, sourceRoot: input.sourcePath });
7141
7141
  await maybeRunNpmInstall(tempPath, input.runCommand, ["ci", "--omit=dev"]);
7142
+ if (input.buildSource === false)
7143
+ await maybeRunNpmSyncSkills(tempPath, input.runCommand);
7142
7144
  await rewriteCachedMcpManifest(tempPath, input.sourcePath);
7143
7145
  await rewriteCachedManifestRoot(tempPath, tempPath, targetPath);
7144
7146
  await assertHookCommandTargets(tempPath);
@@ -7165,6 +7167,17 @@ async function maybeRunNpmBuild(cwd, runCommand) {
7165
7167
  return;
7166
7168
  await runCommand("npm", ["run", "build"], { cwd });
7167
7169
  }
7170
+ async function maybeRunNpmSyncSkills(cwd, runCommand) {
7171
+ if (!await fileExistsStrict(join9(cwd, "package.json")))
7172
+ return;
7173
+ const packageJson = JSON.parse(await readFile7(join9(cwd, "package.json"), "utf8"));
7174
+ if (!isPlainRecord(packageJson))
7175
+ return;
7176
+ const scripts = packageJson.scripts;
7177
+ if (!isPlainRecord(scripts) || typeof scripts["sync:skills"] !== "string")
7178
+ return;
7179
+ await runCommand("npm", ["run", "sync:skills"], { cwd });
7180
+ }
7168
7181
  function createTempSiblingPath(targetPath) {
7169
7182
  return join9(dirname3(targetPath), `.tmp-${basename2(targetPath)}-${process.pid}-${Date.now()}`);
7170
7183
  }
@@ -51,6 +51,14 @@ The research is done when all of these hold:
51
51
  - Every claim in the deliverable cites a source or a verification artifact.
52
52
  - The session journal reconstructs what was searched, found, and expanded, wave by wave.
53
53
 
54
+ ## Run the swarm as a cooperating team
55
+
56
+ Saturation research is the textbook case for a cooperating team, not isolated fire-and-forget workers: a lead one worker surfaces almost always reshapes what another should search next. So when your harness gives you real cooperating members — Codex: the `teammode` skill (`codex_app` threads); OpenCode: `team_mode` — run this swarm as a team. Fall back to the background-worker swarm below only when team mode is unavailable, or the axes are genuinely independent with no cross-pollination expected.
57
+
58
+ - **One member per axis — by part, ownership, or perspective, never a job title.** Each Phase 0 axis is one member owning one concrete slice: a codebase part, a source territory, or a question lens. No two members share an angle. "Backend researcher" or "the web person" gives no real boundary and invites overlap — name what the member owns.
59
+ - **The raise law — broadcast every lead the instant it surfaces.** Members over-communicate relentlessly: every new lead, finding, contradiction, and dead end is raised to you the moment it surfaces, never hoarded for a final dump. Through long passes they send `WORKING: <axis> - <phase>`, and `BLOCKED: <reason>` the moment progress stops, so you always know a member is alive. Too many small updates is correct here; going quiet is the only failure.
60
+ - **You lead; expand on each raised lead.** Members raise via message text, never write session files. Journal each lead and spawn its expansion the instant it lands (Phase 2), not only when a member's final reply arrives.
61
+
54
62
  ## Worker ground rules
55
63
 
56
64
  Research workers (explore, librarian, browsing) differ by harness, but assume:
@@ -106,7 +114,7 @@ Append each digest the moment its worker returns, not in a batch at the end —
106
114
 
107
115
  ## Phase 1 — Saturation wave
108
116
 
109
- Launch every first-wave worker in a single turn, all in background. Sequential launches and "start with one and see" defeat the mode.
117
+ Launch the entire first wave in one turn — every axis at once, as team members if you formed a team, else as background workers. Sequential launches and "start with one and see" defeat the mode.
110
118
 
111
119
  Scaling floor — more angles always justify more workers:
112
120
 
@@ -137,7 +145,7 @@ End your reply with the ## EXPAND tail: '- LEAD: <discovery> — WHY: <why> —
137
145
 
138
146
  ## Phase 2 — Expand until convergence
139
147
 
140
- This loop is what makes the mode research rather than search. Collect workers as they finish — never wait for the full wave:
148
+ This loop is what makes the mode research rather than search. Collect returns as they landand in team mode, act on each lead the moment a member raises it, never waiting for the full wave or a member's final reply:
141
149
 
142
150
  1. Journal the return: digest plus verbatim EXPAND markers into `wave-<N>-<kind>-<axis>.md`.
143
151
  2. Deduplicate new markers against `expansion-log.md` — every lead ever seen, not just confirmed ones, or rejected leads resurface each wave.
@@ -221,6 +229,7 @@ High-yield combinations: official docs (`site:<docs domain>`), GitHub implementa
221
229
  | Failure | Correction |
222
230
  |---|---|
223
231
  | Sequential spawning, or trimming the first wave | All first-wave workers in one turn, background, scaling floor respected |
232
+ | A team member hoards leads for one final dump | Raise law — every lead, finding, and dead end broadcast the moment it surfaces |
224
233
  | Worker reply without the EXPAND tail | One follow-up demanding it; the lane stays open until it lands |
225
234
  | Stopping after wave 1 because "enough was found" | Convergence rules only: 2+ expansion waves, leads run dry |
226
235
  | Obeying a surrounding "stop exploring" rule mid-research | Authority section — those rules do not bind this mode |