oh-my-opencode 5.0.0-beta.8 → 5.0.0-beta.9

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 (114) hide show
  1. package/.agents/command/publish.md +44 -16
  2. package/.agents/skills/publish/SKILL.md +44 -16
  3. package/.opencode/command/publish.md +44 -16
  4. package/dist/agents/atlas/agent.d.ts +0 -1
  5. package/dist/cli/index.js +34 -31
  6. package/dist/cli/run/on-complete-hook.d.ts +2 -0
  7. package/dist/cli-node/index.js +34 -31
  8. package/dist/hooks/atlas/final-wave-approval-gate.test-support.d.ts +50 -0
  9. package/dist/hooks/atlas/system-reminder-templates.d.ts +0 -1
  10. package/dist/index.js +25 -24
  11. package/dist/shared/shell-env.d.ts +1 -1
  12. package/dist/skills/ultimate-browsing/ATTRIBUTION.md +35 -8
  13. package/dist/skills/ultimate-browsing/engine/AGENTS.md +110 -0
  14. package/dist/tui.js +2 -2
  15. package/package.json +15 -14
  16. package/packages/omo-codex/plugin/.codex-plugin/plugin.json +1 -1
  17. package/packages/omo-codex/plugin/components/bootstrap/hooks/hooks.json +1 -1
  18. package/packages/omo-codex/plugin/components/bootstrap/package.json +1 -1
  19. package/packages/omo-codex/plugin/components/codegraph/dist/cli.js +2 -2
  20. package/packages/omo-codex/plugin/components/codegraph/dist/serve.js +2 -2
  21. package/packages/omo-codex/plugin/components/codegraph/package.json +1 -1
  22. package/packages/omo-codex/plugin/components/comment-checker/hooks/hooks.json +1 -1
  23. package/packages/omo-codex/plugin/components/comment-checker/package.json +1 -1
  24. package/packages/omo-codex/plugin/components/git-bash/hooks/hooks.json +2 -2
  25. package/packages/omo-codex/plugin/components/git-bash/package.json +1 -1
  26. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/hooks/hooks.json +1 -1
  27. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/package.json +1 -1
  28. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/test/codex-hook.test.ts +3 -17
  29. package/packages/omo-codex/plugin/components/lsp/dist/.omo-runtime-manifest.json +2 -2
  30. package/packages/omo-codex/plugin/components/lsp/hooks/hooks.json +2 -2
  31. package/packages/omo-codex/plugin/components/lsp/package.json +1 -1
  32. package/packages/omo-codex/plugin/components/rules/hooks/hooks.json +4 -4
  33. package/packages/omo-codex/plugin/components/rules/package.json +1 -1
  34. package/packages/omo-codex/plugin/components/rules/test/bundled-rules-priority.test.ts +11 -16
  35. package/packages/omo-codex/plugin/components/rules/test/bundled-rules.test.ts +16 -23
  36. package/packages/omo-codex/plugin/components/rules/test/codex-hook-post-compact-budget.test.ts +9 -7
  37. package/packages/omo-codex/plugin/components/rules/test/codex-hook-post-compact-context.test.ts +0 -6
  38. package/packages/omo-codex/plugin/components/rules/test/codex-hook-post-compact-dedup.test.ts +6 -4
  39. package/packages/omo-codex/plugin/components/rules/test/codex-hook-post-compact-directive.test.ts +12 -9
  40. package/packages/omo-codex/plugin/components/rules/test/codex-hook.test.ts +28 -37
  41. package/packages/omo-codex/plugin/components/rules/test/formatter.test.ts +37 -69
  42. package/packages/omo-codex/plugin/components/rules/test/hook-output.test.ts +2 -3
  43. package/packages/omo-codex/plugin/components/rules/test/windows-git-bash-bundled-rule.test.ts +1 -15
  44. package/packages/omo-codex/plugin/components/start-work-continuation/hooks/hooks.json +2 -2
  45. package/packages/omo-codex/plugin/components/start-work-continuation/package.json +1 -1
  46. package/packages/omo-codex/plugin/components/start-work-continuation/test/cli.test.ts +0 -3
  47. package/packages/omo-codex/plugin/components/start-work-continuation/test/codex-hook.test.ts +2 -16
  48. package/packages/omo-codex/plugin/components/teammode/hooks/hooks.json +1 -1
  49. package/packages/omo-codex/plugin/components/teammode/package.json +1 -1
  50. package/packages/omo-codex/plugin/components/teammode/test/thread-title-hook.test.ts +3 -9
  51. package/packages/omo-codex/plugin/components/telemetry/hooks/hooks.json +1 -1
  52. package/packages/omo-codex/plugin/components/telemetry/package.json +1 -1
  53. package/packages/omo-codex/plugin/components/ultrawork/hooks/hooks.json +1 -1
  54. package/packages/omo-codex/plugin/components/ultrawork/package.json +1 -1
  55. package/packages/omo-codex/plugin/components/ultrawork/test/codex-hook.test.ts +0 -136
  56. package/packages/omo-codex/plugin/components/ultrawork/test/skill-pointer.test.ts +0 -2
  57. package/packages/omo-codex/plugin/components/ulw-loop/hooks/hooks.json +4 -4
  58. package/packages/omo-codex/plugin/components/ulw-loop/package.json +1 -1
  59. package/packages/omo-codex/plugin/components/ulw-loop/test/checkpoint-continuation.test.ts +0 -1
  60. package/packages/omo-codex/plugin/components/ulw-loop/test/codex-goal-instruction.test.ts +2 -2
  61. package/packages/omo-codex/plugin/components/ulw-loop/test/codex-hook.test.ts +0 -3
  62. package/packages/omo-codex/plugin/components/ulw-loop/test/package-smoke.test.ts +2 -35
  63. package/packages/omo-codex/plugin/components/ulw-loop/test/ultrawork-directive.test.ts +4 -5
  64. package/packages/omo-codex/plugin/hooks/post-compact-resetting-git-bash-mcp-reminder.json +1 -1
  65. package/packages/omo-codex/plugin/hooks/post-compact-resetting-lsp-diagnostics-cache.json +1 -1
  66. package/packages/omo-codex/plugin/hooks/post-compact-resetting-project-rule-cache.json +1 -1
  67. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-codegraph-init-guidance.json +1 -1
  68. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-comments.json +1 -1
  69. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-lsp-diagnostics.json +1 -1
  70. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-thread-title-hygiene.json +1 -1
  71. package/packages/omo-codex/plugin/hooks/post-tool-use-matching-project-rules.json +1 -1
  72. package/packages/omo-codex/plugin/hooks/pre-tool-use-enforcing-unlimited-goal-budget.json +1 -1
  73. package/packages/omo-codex/plugin/hooks/pre-tool-use-guarding-ulw-loop-spawns.json +1 -1
  74. package/packages/omo-codex/plugin/hooks/pre-tool-use-recommending-git-bash-mcp.json +1 -1
  75. package/packages/omo-codex/plugin/hooks/session-start-checking-auto-update.json +1 -1
  76. package/packages/omo-codex/plugin/hooks/session-start-checking-bootstrap-provisioning.json +1 -1
  77. package/packages/omo-codex/plugin/hooks/session-start-checking-codegraph-bootstrap.json +1 -1
  78. package/packages/omo-codex/plugin/hooks/session-start-loading-project-rules.json +1 -1
  79. package/packages/omo-codex/plugin/hooks/session-start-recording-session-telemetry.json +1 -1
  80. package/packages/omo-codex/plugin/hooks/stop-checking-start-work-continuation.json +1 -1
  81. package/packages/omo-codex/plugin/hooks/stop-checking-ulw-loop-resume.json +1 -1
  82. package/packages/omo-codex/plugin/hooks/subagent-stop-checking-start-work-continuation.json +1 -1
  83. package/packages/omo-codex/plugin/hooks/subagent-stop-verifying-lazycodex-executor-evidence.json +1 -1
  84. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ultrawork-trigger.json +1 -1
  85. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ulw-loop-steering.json +1 -1
  86. package/packages/omo-codex/plugin/hooks/user-prompt-submit-loading-project-rules.json +1 -1
  87. package/packages/omo-codex/plugin/package-lock.json +20 -20
  88. package/packages/omo-codex/plugin/package.json +1 -1
  89. package/packages/omo-codex/plugin/skills/ultimate-browsing/ATTRIBUTION.md +35 -8
  90. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/AGENTS.md +110 -0
  91. package/packages/omo-codex/plugin/test/aggregate-agents.test.mjs +19 -173
  92. package/packages/omo-codex/plugin/test/aggregate-hooks.test.mjs +4 -24
  93. package/packages/omo-codex/plugin/test/aggregate-plugin-fixture.mjs +175 -13
  94. package/packages/omo-codex/plugin/test/aggregate.test.mjs +78 -2
  95. package/packages/omo-codex/plugin/test/auto-update-release-notes.test.mjs +19 -33
  96. package/packages/omo-codex/plugin/test/lcx-contribute-bug-fix-template.test.mjs +21 -27
  97. package/packages/omo-codex/plugin/test/scaffold-plan.test.mjs +0 -36
  98. package/packages/omo-codex/plugin/test/sync-skills-codex-compatibility.test.mjs +101 -0
  99. package/packages/omo-codex/plugin/test/sync-skills.test.mjs +1 -119
  100. package/packages/omo-codex/plugin/test/teammode-archive-ambiguity.test.mjs +0 -40
  101. package/packages/omo-codex/plugin/test/teammode-communication.test.mjs +6 -62
  102. package/packages/omo-codex/plugin/test/teammode-thread-links.test.mjs +3 -36
  103. package/packages/omo-codex/plugin/test/teammode-transport.test.mjs +0 -44
  104. package/packages/omo-codex/plugin/test/teammode-worktree.test.mjs +2 -6
  105. package/packages/omo-codex/plugin/test/ultrawork-skill-pointer.test.mjs +0 -3
  106. package/packages/omo-codex/plugin/test/ulw-plan-review-state-contract.test.mjs +0 -3
  107. package/packages/omo-codex/scripts/install-dist/install-local.mjs +2 -2
  108. package/packages/omo-codex/scripts/install-lazycodex-version-stamp.test.mjs +7 -2
  109. package/packages/shared-skills/skills/ultimate-browsing/ATTRIBUTION.md +35 -8
  110. package/packages/shared-skills/skills/ultimate-browsing/engine/AGENTS.md +110 -0
  111. package/dist/tools/call-omo-agent/background-agent-executor.d.ts +0 -5
  112. package/packages/omo-codex/plugin/test/aggregate-skills.test.mjs +0 -92
  113. package/packages/omo-codex/plugin/test/sync-skills-orchestration.test.mjs +0 -314
  114. package/packages/omo-codex/plugin/test/ulw-plan-scope-contract.test.mjs +0 -24
@@ -28,7 +28,6 @@ describe("codex ultrawork hook", () => {
28
28
  // then
29
29
  expect(parsed.hookSpecificOutput.hookEventName).toBe("UserPromptSubmit");
30
30
  expect(parsed.hookSpecificOutput.additionalContext).toMatch(/^<ultrawork-mode>/);
31
- expect(parsed.hookSpecificOutput.additionalContext).toMatch(/First user-visible line this turn MUST be exactly:/);
32
31
  });
33
32
 
34
33
  it("#given Windows cwd #when hook sees ultrawork prompt #then emits directive as Codex hook JSON", () => {
@@ -174,139 +173,4 @@ describe("codex ultrawork hook", () => {
174
173
  // then
175
174
  expect(outputs).toEqual(["", "", ""]);
176
175
  });
177
-
178
- it("#given directive #when inspected #then keeps manual QA and cleanup invariants", () => {
179
- // given
180
- const payload = {
181
- hook_event_name: "UserPromptSubmit",
182
- prompt: "ulw",
183
- };
184
-
185
- // when
186
- const output = runUserPromptSubmitHook(payload, { skillFilePath: null });
187
- const parsed = parseHookOutput(output);
188
-
189
- // then
190
- expect(parsed.hookSpecificOutput.additionalContext).toMatch(/# Manual-QA channels/);
191
- expect(parsed.hookSpecificOutput.additionalContext).toMatch(/TESTS ALONE NEVER PROVE DONE/);
192
- expect(parsed.hookSpecificOutput.additionalContext).toMatch(/1\. HTTP call/);
193
- expect(parsed.hookSpecificOutput.additionalContext).toMatch(/2\. Terminal \/ TUI/);
194
- expect(parsed.hookSpecificOutput.additionalContext).toMatch(/3\. Browser use/);
195
- expect(parsed.hookSpecificOutput.additionalContext).toMatch(/4\. Computer use/);
196
- expect(parsed.hookSpecificOutput.additionalContext).toMatch(/CLEANUP \(PAIRED/);
197
- expect(parsed.hookSpecificOutput.additionalContext).toMatch(/refresh current branch\/PR\/issue state/);
198
- expect(parsed.hookSpecificOutput.additionalContext).toMatch(/preserve existing ordering\/policy/);
199
- expect(parsed.hookSpecificOutput.additionalContext).toMatch(
200
- /separate compatibility detection from policy changes/,
201
- );
202
- });
203
-
204
- it("#given directive #when inspected #then avoids context-expensive agent polling", () => {
205
- // given
206
- const payload = {
207
- hook_event_name: "UserPromptSubmit",
208
- prompt: "ulw",
209
- };
210
-
211
- // when
212
- const output = runUserPromptSubmitHook(payload, { skillFilePath: null });
213
- const parsed = parseHookOutput(output);
214
-
215
- // then
216
- const directive = parsed.hookSpecificOutput.additionalContext;
217
- expect(directive).toMatch(/multi_agent_v1\.wait_agent/);
218
- expect(directive).toMatch(/Track spawned agent names locally/);
219
- expect(directive).toMatch(/wait_agent[\s\S]*mailbox/);
220
- expect(directive).toMatch(/WORKING:/);
221
- expect(directive).toMatch(/TASK STILL ACTIVE/);
222
- expect(directive).toMatch(/Treat child status as a progress signal/);
223
- });
224
-
225
- it("#given directive #when inspected #then hardens Codex subagent assignment ambiguity", () => {
226
- // given
227
- const payload = {
228
- hook_event_name: "UserPromptSubmit",
229
- prompt: "ulw",
230
- };
231
-
232
- // when
233
- const output = runUserPromptSubmitHook(payload, { skillFilePath: null });
234
- const parsed = parseHookOutput(output);
235
-
236
- // then
237
- const directive = parsed.hookSpecificOutput.additionalContext;
238
- expect(directive).toMatch(/TASK:/);
239
- expect(directive).toMatch(/fork_context:\s*false/);
240
- expect(directive).toMatch(/wait_agent[\s\S]*mailbox/);
241
- expect(directive).toMatch(/TASK STILL ACTIVE/);
242
- expect(directive).toMatch(/respawn.*smaller/);
243
- expect(directive).toMatch(/timeout only means no new mailbox update arrived/i);
244
- expect(directive).toMatch(/WORKING:/);
245
- });
246
-
247
- it("#given directive #when inspected #then blocks dependent work until spawned planners finish", () => {
248
- // given
249
- const payload = {
250
- hook_event_name: "UserPromptSubmit",
251
- prompt: "ulw",
252
- };
253
-
254
- // when
255
- const output = runUserPromptSubmitHook(payload, { skillFilePath: null });
256
- const parsed = parseHookOutput(output);
257
-
258
- // then
259
- const directive = parsed.hookSpecificOutput.additionalContext;
260
- expect(directive).toMatch(/Subagent-dependent transition barrier/);
261
- expect(directive).toMatch(/Spawn every independent child for the current wave first/);
262
- expect(directive).toMatch(/After the wave\s+is launched[\s\S]{0,240}wait_agent[\s\S]{0,240}terminal status/);
263
- expect(directive).not.toMatch(/Immediately after any `multi_agent_v1\.spawn_agent`/);
264
- expect(directive).toMatch(/Do not start dependent implementation/);
265
- expect(directive).toMatch(/Do not mark an `update_plan` step `completed`/);
266
- });
267
-
268
- it("#given directive #when inspected #then keeps impact-proportional sizing invariants", () => {
269
- // given
270
- const payload = {
271
- hook_event_name: "UserPromptSubmit",
272
- prompt: "ulw",
273
- };
274
-
275
- // when
276
- const output = runUserPromptSubmitHook(payload, { skillFilePath: null });
277
- const parsed = parseHookOutput(output);
278
-
279
- // then
280
- const directive = parsed.hookSpecificOutput.additionalContext;
281
- expect(directive).toMatch(/# Tier triage/);
282
- expect(directive).toMatch(/Default is LIGHT/);
283
- expect(directive).toMatch(/Take HEAVY/);
284
- expect(directive).toMatch(/ratchet up only/i);
285
- expect(directive).toMatch(/`plan` agent/);
286
- });
287
-
288
- it("#given directive #when discovery leaves known execution steps #then planning stays direct unless design uncertainty remains", () => {
289
- // given
290
- const payload = {
291
- hook_event_name: "UserPromptSubmit",
292
- prompt: "ulw",
293
- };
294
-
295
- // when
296
- const output = runUserPromptSubmitHook(payload, { skillFilePath: null });
297
- const parsed = parseHookOutput(output);
298
-
299
- // then
300
- const directive = parsed.hookSpecificOutput.additionalContext;
301
- const discoveryIndex = directive.search(/fire the first discovery wave/i);
302
- const uncertaintyIndex = directive.search(/what the wave left UNDECIDED/i);
303
- const directPlanIndex = directive.search(/known procedure[\s\S]*plan directly/i);
304
- expect(discoveryIndex).toBeGreaterThanOrEqual(0);
305
- expect(uncertaintyIndex).toBeGreaterThan(discoveryIndex);
306
- expect(directPlanIndex).toBeGreaterThan(uncertaintyIndex);
307
- expect(directive).toMatch(/unclear module boundaries[\s\S]*viable decompositions[\s\S]*dependency order/i);
308
- expect(directive).toMatch(/A known procedure.*however many steps.*never justify a planner/is);
309
- expect(directive).toMatch(/[Nn]ever spawn `plan` before the discovery wave/);
310
- expect(directive).toMatch(/tier sizes\s+evidence and review, never who plans/i);
311
- });
312
176
  });
@@ -42,9 +42,7 @@ describe("ultrawork skill pointer", () => {
42
42
  expect(context).toBe(buildUltraworkSkillPointer(skillFilePath));
43
43
  expect(context.startsWith("<ultrawork-mode>")).toBe(true);
44
44
  expect(context).toContain(skillFilePath);
45
- expect(context).toContain("First user-visible line this turn MUST be exactly:");
46
45
  expect(context).toContain("create_goal");
47
- expect(context).not.toContain("Tier triage");
48
46
  expect(Buffer.byteLength(context, "utf8")).toBeLessThan(POINTER_MAX_BYTES);
49
47
  });
50
48
 
@@ -7,7 +7,7 @@
7
7
  "type": "command",
8
8
  "command": "node \"${PLUGIN_ROOT}/dist/cli.js\" hook user-prompt-submit --with-ultrawork",
9
9
  "timeout": 10,
10
- "statusMessage": "(OmO 5.0.0-beta.8) Checking Ulw-Loop Steering"
10
+ "statusMessage": "(OmO 5.0.0-beta.9) Checking Ulw-Loop Steering"
11
11
  }
12
12
  ]
13
13
  }
@@ -20,7 +20,7 @@
20
20
  "type": "command",
21
21
  "command": "node \"${PLUGIN_ROOT}/dist/cli.js\" hook pre-tool-use",
22
22
  "timeout": 5,
23
- "statusMessage": "(OmO 5.0.0-beta.8) Enforcing Unlimited Ulw-Loop Budget"
23
+ "statusMessage": "(OmO 5.0.0-beta.9) Enforcing Unlimited Ulw-Loop Budget"
24
24
  }
25
25
  ]
26
26
  },
@@ -31,7 +31,7 @@
31
31
  "type": "command",
32
32
  "command": "node \"${PLUGIN_ROOT}/dist/cli.js\" hook pre-tool-use-spawn",
33
33
  "timeout": 5,
34
- "statusMessage": "(OmO 5.0.0-beta.8) Guarding Ulw-Loop Spawns"
34
+ "statusMessage": "(OmO 5.0.0-beta.9) Guarding Ulw-Loop Spawns"
35
35
  }
36
36
  ]
37
37
  }
@@ -43,7 +43,7 @@
43
43
  "type": "command",
44
44
  "command": "node \"${PLUGIN_ROOT}/dist/cli.js\" hook stop",
45
45
  "timeout": 10,
46
- "statusMessage": "(OmO 5.0.0-beta.8) Checking Ulw-Loop Resume"
46
+ "statusMessage": "(OmO 5.0.0-beta.9) Checking Ulw-Loop Resume"
47
47
  }
48
48
  ]
49
49
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@code-yeongyu/codex-ulw-loop",
3
- "version": "5.0.0-beta.8",
3
+ "version": "5.0.0-beta.9",
4
4
  "description": "Codex plugin: durable repo-native multi-goal orchestration with embedded success criteria and observable evidence audit.",
5
5
  "type": "module",
6
6
  "packageManager": "npm@11.12.1",
@@ -31,7 +31,6 @@ describe("checkpointAndContinue", () => {
31
31
  });
32
32
 
33
33
  expect(result.next).toMatchObject({ resumed: false, goal: { id: "G002", status: "in_progress" } });
34
- expect(result.next && "instruction" in result.next ? result.next.instruction.text : "").toContain("Goal: G002");
35
34
  expect((await readUlwLoopPlan(repo)).activeGoalId).toBe("G002");
36
35
  });
37
36
 
@@ -113,9 +113,9 @@ describe("buildCodexGoalInstruction aggregate mode", () => {
113
113
 
114
114
  describe("buildCodexGoalInstruction per_story mode", () => {
115
115
  it("uses the goal's own objective for create_goal", () => {
116
- const goal = makeGoal({ objective: "Build the auth service" });
116
+ const goal = makeGoal({ objective: "per-story-objective-sentinel" });
117
117
  const { text } = buildCodexGoalInstruction({ plan: makePlan({ codexGoalMode: "per_story" }), goal });
118
- expect(text).toContain("Build the auth service");
118
+ expect(text).toContain("per-story-objective-sentinel");
119
119
  });
120
120
  });
121
121
 
@@ -242,7 +242,6 @@ describe("applyPreToolUseGoalBudgetGuard", () => {
242
242
  permissionDecision: "deny",
243
243
  },
244
244
  });
245
- expect(parsed.hookSpecificOutput.permissionDecisionReason).toContain("objective only");
246
245
  expect(parsed.hookSpecificOutput.permissionDecisionReason).toContain("token_budget");
247
246
  expect(parsed.hookSpecificOutput.permissionDecisionReason).toContain("unlimited");
248
247
  expect(parsed.hookSpecificOutput.permissionDecisionReason).toContain("update_goal");
@@ -258,7 +257,6 @@ describe("applyPreToolUseGoalBudgetGuard", () => {
258
257
  // then
259
258
  const parsed = JSON.parse(output);
260
259
  expect(parsed.hookSpecificOutput.permissionDecision).toBe("deny");
261
- expect(parsed.hookSpecificOutput.permissionDecisionReason).toContain("objective only");
262
260
  expect(parsed.hookSpecificOutput.permissionDecisionReason).toContain("update_goal");
263
261
  });
264
262
 
@@ -272,7 +270,6 @@ describe("applyPreToolUseGoalBudgetGuard", () => {
272
270
  // then
273
271
  const parsed = JSON.parse(output);
274
272
  expect(parsed.hookSpecificOutput.permissionDecision).toBe("deny");
275
- expect(parsed.hookSpecificOutput.permissionDecisionReason).toContain("objective only");
276
273
  });
277
274
 
278
275
  it("#given create_goal omits token_budget #when PreToolUse runs #then it stays silent", () => {
@@ -24,9 +24,7 @@ type ShellResult = {
24
24
  };
25
25
 
26
26
  function bootstrapScriptFrom(text: string): string {
27
- const heading = text.indexOf("### 1. Create goals from the brief");
28
- expect(heading).toBeGreaterThanOrEqual(0);
29
- const blockStart = text.indexOf("```sh\n", heading);
27
+ const blockStart = text.indexOf("```sh\n");
30
28
  expect(blockStart).toBeGreaterThanOrEqual(0);
31
29
  const codeStart = blockStart + "```sh\n".length;
32
30
  const blockEnd = text.indexOf("\n```", codeStart);
@@ -129,9 +127,7 @@ describe("skills/ulw-loop/SKILL.md", () => {
129
127
  const text = await readText("skills/ulw-loop/agents/openai.yaml");
130
128
 
131
129
  expect(text).toContain('display_name: "(OmO) ulw-loop"');
132
- expect(text).not.toContain("ulw-loop / ulw-loop");
133
130
  expect(text).toContain('short_description: "Goal-like ultrawork loop for systematic decomposition"');
134
- expect(text).toContain("Use $ulw-loop");
135
131
  });
136
132
 
137
133
  it("#given Codex dollar hinting #when querying ulw-loop #then ulw-loop remains discoverable as an alias", async () => {
@@ -181,7 +177,6 @@ describe("skills/ulw-loop/SKILL.md", () => {
181
177
 
182
178
  expect(result.code).toBe(0);
183
179
  expect(result.stdout).toContain('"source":"cached-ulw-loop"');
184
- expect(result.stderr).not.toContain("unknown command");
185
180
  } finally {
186
181
  await rm(root, { recursive: true, force: true });
187
182
  }
@@ -189,27 +184,7 @@ describe("skills/ulw-loop/SKILL.md", () => {
189
184
 
190
185
  });
191
186
 
192
- describe("source LOC budget", () => {
193
- it("every source file stays at or under 250 pure LOC", async () => {
194
- const files = [
195
- "src/types.ts", "src/paths.ts", "src/plan-io.ts", "src/plan-crud.ts", "src/goal-status.ts",
196
- "src/evidence.ts", "src/quality-gate.ts", "src/quality-gate-verdicts.ts", "src/checkpoint.ts", "src/review-blockers.ts",
197
- "src/stop-resume-hook.ts", "src/spawn-guard.ts",
198
- "src/steering.ts", "src/codex-goal-instruction.ts", "src/codex-goal-snapshot.ts", "src/codex-hook.ts",
199
- "src/cli.ts", "src/cli-arg-parser.ts", "src/cli-output.ts", "src/cli-steering.ts", "src/cli-commands.ts",
200
- ];
201
- for (const file of files) {
202
- const text = await readText(file);
203
- const pure = text.split("\n").filter((line) => {
204
- const trimmed = line.trim();
205
- return trimmed.length > 0 && !trimmed.startsWith("//");
206
- }).length;
207
- expect(pure, `${file} pure LOC`).toBeLessThanOrEqual(250);
208
- }
209
- });
210
- });
211
-
212
- describe("README implementation contract", () => {
187
+ describe("README implementation contract", () => {
213
188
  it("#given the README #when subcommands are inspected #then every implemented CLI subcommand is documented", async () => {
214
189
  const readme = await readText("README.md");
215
190
 
@@ -218,14 +193,6 @@ describe("README implementation contract", () => {
218
193
  }
219
194
  });
220
195
 
221
- it("#given the README #when stale scaffold language is checked #then it is absent", async () => {
222
- const readme = await readText("README.md");
223
-
224
- expect(readme).not.toMatch(/scaffold only/i);
225
- expect(readme).not.toMatch(/Wave 1/i);
226
- expect(readme).not.toMatch(/lands in later waves/i);
227
- });
228
-
229
196
  it("#given the README #when hooks are described #then both hook channels are documented", async () => {
230
197
  const readme = await readText("README.md");
231
198
 
@@ -5,6 +5,7 @@ import { join } from "node:path";
5
5
  import { describe, expect, it } from "vitest";
6
6
 
7
7
  import { applyUserPromptUlwLoopSteering, type UserPromptSubmitPayload } from "../src/codex-hook.js";
8
+ import { buildUltraworkSkillPointer } from "../src/ultrawork-skill-pointer.js";
8
9
 
9
10
  const DEFAULT_SESSION_ID = "s1";
10
11
 
@@ -76,10 +77,7 @@ describe("standalone ultrawork directive injection", () => {
76
77
  const parsed = JSON.parse(output);
77
78
  const context = parsed.hookSpecificOutput.additionalContext;
78
79
 
79
- expect(context).toMatch(/^<ultrawork-mode>/);
80
- expect(context).toContain(skillFilePath);
81
- expect(context).toContain("create_goal");
82
- expect(context).not.toContain("Tier triage");
80
+ expect(context).toBe(buildUltraworkSkillPointer(skillFilePath).trim());
83
81
  });
84
82
 
85
83
  it("#given a missing ultrawork skill file #when standalone injection runs #then falls back to the full directive", async () => {
@@ -90,8 +88,9 @@ describe("standalone ultrawork directive injection", () => {
90
88
  ultraworkSkillFilePath: missingSkillFilePath,
91
89
  });
92
90
  const parsed = JSON.parse(output);
91
+ const directive = await readFile(new URL("../directive.md", import.meta.url), "utf8");
93
92
 
94
- expect(parsed.hookSpecificOutput.additionalContext).toContain("Tier triage");
93
+ expect(parsed.hookSpecificOutput.additionalContext).toBe(directive.trim());
95
94
  });
96
95
 
97
96
  it("#given the ulw-loop pointer template #when compared to ultrawork #then the copy stays byte-identical", async () => {
@@ -7,7 +7,7 @@
7
7
  "type": "command",
8
8
  "command": "node \"${PLUGIN_ROOT}/components/git-bash/dist/cli.js\" hook post-compact",
9
9
  "timeout": 5,
10
- "statusMessage": "(OmO 5.0.0-beta.8) Resetting Git Bash MCP Reminder",
10
+ "statusMessage": "(OmO 5.0.0-beta.9) Resetting Git Bash MCP Reminder",
11
11
  "commandWindows": "powershell -NoProfile -ExecutionPolicy Bypass -File \"${PLUGIN_ROOT}\\components\\bootstrap\\scripts\\node-dispatch.ps1\" \"${PLUGIN_ROOT}\\components\\git-bash\\dist\\cli.js\" hook post-compact"
12
12
  }
13
13
  ],
@@ -7,7 +7,7 @@
7
7
  "type": "command",
8
8
  "command": "node \"${PLUGIN_ROOT}/components/lsp/dist/cli.js\" hook post-compact",
9
9
  "timeout": 5,
10
- "statusMessage": "(OmO 5.0.0-beta.8) Resetting LSP Diagnostics Cache",
10
+ "statusMessage": "(OmO 5.0.0-beta.9) Resetting LSP Diagnostics Cache",
11
11
  "commandWindows": "powershell -NoProfile -ExecutionPolicy Bypass -File \"${PLUGIN_ROOT}\\components\\bootstrap\\scripts\\node-dispatch.ps1\" \"${PLUGIN_ROOT}\\components\\lsp\\dist\\cli.js\" hook post-compact"
12
12
  }
13
13
  ],
@@ -7,7 +7,7 @@
7
7
  "type": "command",
8
8
  "command": "node \"${PLUGIN_ROOT}/components/rules/dist/cli.js\" hook post-compact",
9
9
  "timeout": 10,
10
- "statusMessage": "(OmO 5.0.0-beta.8) Resetting Project Rule Cache",
10
+ "statusMessage": "(OmO 5.0.0-beta.9) Resetting Project Rule Cache",
11
11
  "commandWindows": "powershell -NoProfile -ExecutionPolicy Bypass -File \"${PLUGIN_ROOT}\\components\\bootstrap\\scripts\\node-dispatch.ps1\" \"${PLUGIN_ROOT}\\components\\rules\\dist\\cli.js\" hook post-compact"
12
12
  }
13
13
  ],
@@ -7,7 +7,7 @@
7
7
  "type": "command",
8
8
  "command": "node \"${PLUGIN_ROOT}/components/codegraph/dist/cli.js\" hook post-tool-use",
9
9
  "timeout": 5,
10
- "statusMessage": "(OmO 5.0.0-beta.8) Checking CodeGraph Init Guidance",
10
+ "statusMessage": "(OmO 5.0.0-beta.9) Checking CodeGraph Init Guidance",
11
11
  "commandWindows": "powershell -NoProfile -ExecutionPolicy Bypass -File \"${PLUGIN_ROOT}\\components\\bootstrap\\scripts\\node-dispatch.ps1\" \"${PLUGIN_ROOT}\\components\\codegraph\\dist\\cli.js\" hook post-tool-use"
12
12
  }
13
13
  ],
@@ -7,7 +7,7 @@
7
7
  "type": "command",
8
8
  "command": "node \"${PLUGIN_ROOT}/components/comment-checker/dist/cli.js\" hook post-tool-use",
9
9
  "timeout": 30,
10
- "statusMessage": "(OmO 5.0.0-beta.8) Checking Comments",
10
+ "statusMessage": "(OmO 5.0.0-beta.9) Checking Comments",
11
11
  "commandWindows": "powershell -NoProfile -ExecutionPolicy Bypass -File \"${PLUGIN_ROOT}\\components\\bootstrap\\scripts\\node-dispatch.ps1\" \"${PLUGIN_ROOT}\\components\\comment-checker\\dist\\cli.js\" hook post-tool-use"
12
12
  }
13
13
  ],
@@ -7,7 +7,7 @@
7
7
  "type": "command",
8
8
  "command": "node \"${PLUGIN_ROOT}/components/lsp/dist/cli.js\" hook post-tool-use",
9
9
  "timeout": 60,
10
- "statusMessage": "(OmO 5.0.0-beta.8) Checking LSP Diagnostics",
10
+ "statusMessage": "(OmO 5.0.0-beta.9) Checking LSP Diagnostics",
11
11
  "commandWindows": "powershell -NoProfile -ExecutionPolicy Bypass -File \"${PLUGIN_ROOT}\\components\\bootstrap\\scripts\\node-dispatch.ps1\" \"${PLUGIN_ROOT}\\components\\lsp\\dist\\cli.js\" hook post-tool-use"
12
12
  }
13
13
  ],
@@ -8,7 +8,7 @@
8
8
  "type": "command",
9
9
  "command": "node \"${PLUGIN_ROOT}/components/teammode/dist/cli.js\" hook post-tool-use",
10
10
  "timeout": 10,
11
- "statusMessage": "(OmO 5.0.0-beta.8) Checking Thread Title Hygiene",
11
+ "statusMessage": "(OmO 5.0.0-beta.9) Checking Thread Title Hygiene",
12
12
  "commandWindows": "powershell -NoProfile -ExecutionPolicy Bypass -File \"${PLUGIN_ROOT}\\components\\bootstrap\\scripts\\node-dispatch.ps1\" \"${PLUGIN_ROOT}\\components\\teammode\\dist\\cli.js\" hook post-tool-use"
13
13
  }
14
14
  ]
@@ -7,7 +7,7 @@
7
7
  "type": "command",
8
8
  "command": "node \"${PLUGIN_ROOT}/components/rules/dist/cli.js\" hook post-tool-use",
9
9
  "timeout": 10,
10
- "statusMessage": "(OmO 5.0.0-beta.8) Matching Project Rules",
10
+ "statusMessage": "(OmO 5.0.0-beta.9) Matching Project Rules",
11
11
  "commandWindows": "powershell -NoProfile -ExecutionPolicy Bypass -File \"${PLUGIN_ROOT}\\components\\bootstrap\\scripts\\node-dispatch.ps1\" \"${PLUGIN_ROOT}\\components\\rules\\dist\\cli.js\" hook post-tool-use"
12
12
  }
13
13
  ],
@@ -7,7 +7,7 @@
7
7
  "type": "command",
8
8
  "command": "node \"${PLUGIN_ROOT}/components/ulw-loop/dist/cli.js\" hook pre-tool-use",
9
9
  "timeout": 5,
10
- "statusMessage": "(OmO 5.0.0-beta.8) Enforcing Unlimited Goal Budget",
10
+ "statusMessage": "(OmO 5.0.0-beta.9) Enforcing Unlimited Goal Budget",
11
11
  "commandWindows": "powershell -NoProfile -ExecutionPolicy Bypass -File \"${PLUGIN_ROOT}\\components\\bootstrap\\scripts\\node-dispatch.ps1\" \"${PLUGIN_ROOT}\\components\\ulw-loop\\dist\\cli.js\" hook pre-tool-use"
12
12
  }
13
13
  ],
@@ -8,7 +8,7 @@
8
8
  "type": "command",
9
9
  "command": "node \"${PLUGIN_ROOT}/components/ulw-loop/dist/cli.js\" hook pre-tool-use-spawn",
10
10
  "timeout": 5,
11
- "statusMessage": "(OmO 5.0.0-beta.8) Guarding Ulw-Loop Spawns",
11
+ "statusMessage": "(OmO 5.0.0-beta.9) Guarding Ulw-Loop Spawns",
12
12
  "commandWindows": "powershell -NoProfile -ExecutionPolicy Bypass -File \"${PLUGIN_ROOT}\\components\\bootstrap\\scripts\\node-dispatch.ps1\" \"${PLUGIN_ROOT}\\components\\ulw-loop\\dist\\cli.js\" hook pre-tool-use-spawn"
13
13
  }
14
14
  ]
@@ -7,7 +7,7 @@
7
7
  "type": "command",
8
8
  "command": "node \"${PLUGIN_ROOT}/components/git-bash/dist/cli.js\" hook pre-tool-use",
9
9
  "timeout": 5,
10
- "statusMessage": "(OmO 5.0.0-beta.8) Recommending Git Bash MCP",
10
+ "statusMessage": "(OmO 5.0.0-beta.9) Recommending Git Bash MCP",
11
11
  "commandWindows": "powershell -NoProfile -ExecutionPolicy Bypass -File \"${PLUGIN_ROOT}\\components\\bootstrap\\scripts\\node-dispatch.ps1\" \"${PLUGIN_ROOT}\\components\\git-bash\\dist\\cli.js\" hook pre-tool-use"
12
12
  }
13
13
  ],
@@ -7,7 +7,7 @@
7
7
  "type": "command",
8
8
  "command": "node \"${PLUGIN_ROOT}/scripts/auto-update.mjs\" hook session-start",
9
9
  "timeout": 15,
10
- "statusMessage": "(OmO 5.0.0-beta.8) Checking Auto Update",
10
+ "statusMessage": "(OmO 5.0.0-beta.9) Checking Auto Update",
11
11
  "commandWindows": "powershell -NoProfile -ExecutionPolicy Bypass -File \"${PLUGIN_ROOT}\\components\\bootstrap\\scripts\\node-dispatch.ps1\" \"${PLUGIN_ROOT}\\scripts\\auto-update.mjs\" hook session-start"
12
12
  }
13
13
  ],
@@ -8,7 +8,7 @@
8
8
  "command": "node \"${PLUGIN_ROOT}/components/bootstrap/dist/cli.js\" hook session-start",
9
9
  "commandWindows": "powershell -NoProfile -ExecutionPolicy Bypass -File \"${PLUGIN_ROOT}\\components\\bootstrap\\scripts\\bootstrap.ps1\"",
10
10
  "timeout": 30,
11
- "statusMessage": "(OmO 5.0.0-beta.8) Checking Bootstrap Provisioning"
11
+ "statusMessage": "(OmO 5.0.0-beta.9) Checking Bootstrap Provisioning"
12
12
  }
13
13
  ]
14
14
  }
@@ -7,7 +7,7 @@
7
7
  "type": "command",
8
8
  "command": "node \"${PLUGIN_ROOT}/components/codegraph/dist/cli.js\" hook session-start",
9
9
  "timeout": 15,
10
- "statusMessage": "(OmO 5.0.0-beta.8) Checking CodeGraph Bootstrap",
10
+ "statusMessage": "(OmO 5.0.0-beta.9) Checking CodeGraph Bootstrap",
11
11
  "commandWindows": "powershell -NoProfile -ExecutionPolicy Bypass -File \"${PLUGIN_ROOT}\\components\\bootstrap\\scripts\\node-dispatch.ps1\" \"${PLUGIN_ROOT}\\components\\codegraph\\dist\\cli.js\" hook session-start"
12
12
  }
13
13
  ]
@@ -7,7 +7,7 @@
7
7
  "type": "command",
8
8
  "command": "node \"${PLUGIN_ROOT}/components/rules/dist/cli.js\" hook session-start",
9
9
  "timeout": 10,
10
- "statusMessage": "(OmO 5.0.0-beta.8) Loading Project Rules",
10
+ "statusMessage": "(OmO 5.0.0-beta.9) Loading Project Rules",
11
11
  "commandWindows": "powershell -NoProfile -ExecutionPolicy Bypass -File \"${PLUGIN_ROOT}\\components\\bootstrap\\scripts\\node-dispatch.ps1\" \"${PLUGIN_ROOT}\\components\\rules\\dist\\cli.js\" hook session-start"
12
12
  }
13
13
  ]
@@ -7,7 +7,7 @@
7
7
  "type": "command",
8
8
  "command": "node \"${PLUGIN_ROOT}/components/telemetry/dist/cli.js\" hook session-start",
9
9
  "timeout": 15,
10
- "statusMessage": "(OmO 5.0.0-beta.8) Recording Session Telemetry",
10
+ "statusMessage": "(OmO 5.0.0-beta.9) Recording Session Telemetry",
11
11
  "commandWindows": "powershell -NoProfile -ExecutionPolicy Bypass -File \"${PLUGIN_ROOT}\\components\\bootstrap\\scripts\\node-dispatch.ps1\" \"${PLUGIN_ROOT}\\components\\telemetry\\dist\\cli.js\" hook session-start"
12
12
  }
13
13
  ]
@@ -7,7 +7,7 @@
7
7
  "type": "command",
8
8
  "command": "node \"${PLUGIN_ROOT}/components/start-work-continuation/dist/cli.js\" hook stop",
9
9
  "timeout": 10,
10
- "statusMessage": "(OmO 5.0.0-beta.8) Checking Start-Work Continuation",
10
+ "statusMessage": "(OmO 5.0.0-beta.9) Checking Start-Work Continuation",
11
11
  "commandWindows": "powershell -NoProfile -ExecutionPolicy Bypass -File \"${PLUGIN_ROOT}\\components\\bootstrap\\scripts\\node-dispatch.ps1\" \"${PLUGIN_ROOT}\\components\\start-work-continuation\\dist\\cli.js\" hook stop"
12
12
  }
13
13
  ]
@@ -7,7 +7,7 @@
7
7
  "type": "command",
8
8
  "command": "node \"${PLUGIN_ROOT}/components/ulw-loop/dist/cli.js\" hook stop",
9
9
  "timeout": 10,
10
- "statusMessage": "(OmO 5.0.0-beta.8) Checking Ulw-Loop Resume",
10
+ "statusMessage": "(OmO 5.0.0-beta.9) Checking Ulw-Loop Resume",
11
11
  "commandWindows": "powershell -NoProfile -ExecutionPolicy Bypass -File \"${PLUGIN_ROOT}\\components\\bootstrap\\scripts\\node-dispatch.ps1\" \"${PLUGIN_ROOT}\\components\\ulw-loop\\dist\\cli.js\" hook stop"
12
12
  }
13
13
  ]
@@ -7,7 +7,7 @@
7
7
  "type": "command",
8
8
  "command": "node \"${PLUGIN_ROOT}/components/start-work-continuation/dist/cli.js\" hook subagent-stop",
9
9
  "timeout": 10,
10
- "statusMessage": "(OmO 5.0.0-beta.8) Checking Start-Work Continuation",
10
+ "statusMessage": "(OmO 5.0.0-beta.9) Checking Start-Work Continuation",
11
11
  "commandWindows": "powershell -NoProfile -ExecutionPolicy Bypass -File \"${PLUGIN_ROOT}\\components\\bootstrap\\scripts\\node-dispatch.ps1\" \"${PLUGIN_ROOT}\\components\\start-work-continuation\\dist\\cli.js\" hook subagent-stop"
12
12
  }
13
13
  ]
@@ -7,7 +7,7 @@
7
7
  "type": "command",
8
8
  "command": "node \"${PLUGIN_ROOT}/components/lazycodex-executor-verify/dist/cli.js\" hook subagent-stop",
9
9
  "timeout": 10,
10
- "statusMessage": "(OmO 5.0.0-beta.8) Verifying LazyCodex Executor Evidence",
10
+ "statusMessage": "(OmO 5.0.0-beta.9) Verifying LazyCodex Executor Evidence",
11
11
  "commandWindows": "powershell -NoProfile -ExecutionPolicy Bypass -File \"${PLUGIN_ROOT}\\components\\bootstrap\\scripts\\node-dispatch.ps1\" \"${PLUGIN_ROOT}\\components\\lazycodex-executor-verify\\dist\\cli.js\" hook subagent-stop"
12
12
  }
13
13
  ],
@@ -7,7 +7,7 @@
7
7
  "type": "command",
8
8
  "command": "node \"${PLUGIN_ROOT}/components/ultrawork/dist/cli.js\" hook user-prompt-submit",
9
9
  "timeout": 5,
10
- "statusMessage": "(OmO 5.0.0-beta.8) Checking Ultrawork Trigger",
10
+ "statusMessage": "(OmO 5.0.0-beta.9) Checking Ultrawork Trigger",
11
11
  "commandWindows": "powershell -NoProfile -ExecutionPolicy Bypass -File \"${PLUGIN_ROOT}\\components\\bootstrap\\scripts\\node-dispatch.ps1\" \"${PLUGIN_ROOT}\\components\\ultrawork\\dist\\cli.js\" hook user-prompt-submit"
12
12
  }
13
13
  ]
@@ -7,7 +7,7 @@
7
7
  "type": "command",
8
8
  "command": "node \"${PLUGIN_ROOT}/components/ulw-loop/dist/cli.js\" hook user-prompt-submit",
9
9
  "timeout": 10,
10
- "statusMessage": "(OmO 5.0.0-beta.8) Checking Ulw-Loop Steering",
10
+ "statusMessage": "(OmO 5.0.0-beta.9) Checking Ulw-Loop Steering",
11
11
  "commandWindows": "powershell -NoProfile -ExecutionPolicy Bypass -File \"${PLUGIN_ROOT}\\components\\bootstrap\\scripts\\node-dispatch.ps1\" \"${PLUGIN_ROOT}\\components\\ulw-loop\\dist\\cli.js\" hook user-prompt-submit"
12
12
  }
13
13
  ]
@@ -7,7 +7,7 @@
7
7
  "type": "command",
8
8
  "command": "node \"${PLUGIN_ROOT}/components/rules/dist/cli.js\" hook user-prompt-submit",
9
9
  "timeout": 10,
10
- "statusMessage": "(OmO 5.0.0-beta.8) Loading Project Rules",
10
+ "statusMessage": "(OmO 5.0.0-beta.9) Loading Project Rules",
11
11
  "commandWindows": "powershell -NoProfile -ExecutionPolicy Bypass -File \"${PLUGIN_ROOT}\\components\\bootstrap\\scripts\\node-dispatch.ps1\" \"${PLUGIN_ROOT}\\components\\rules\\dist\\cli.js\" hook user-prompt-submit"
12
12
  }
13
13
  ]