oh-my-opencode 4.5.12 → 4.6.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 (147) hide show
  1. package/.agents/skills/opencode-qa/SKILL.md +194 -0
  2. package/.agents/skills/opencode-qa/references/cli-commands.md +188 -0
  3. package/.agents/skills/opencode-qa/references/db-investigation.md +197 -0
  4. package/.agents/skills/opencode-qa/references/events-hooks.md +110 -0
  5. package/.agents/skills/opencode-qa/references/sdk.md +96 -0
  6. package/.agents/skills/opencode-qa/references/server-api.md +200 -0
  7. package/.agents/skills/opencode-qa/references/testing-harness.md +218 -0
  8. package/.agents/skills/opencode-qa/references/tui-tmux.md +52 -0
  9. package/.agents/skills/opencode-qa/scripts/db-session-by-id.sh +53 -0
  10. package/.agents/skills/opencode-qa/scripts/db-session-by-name.sh +57 -0
  11. package/.agents/skills/opencode-qa/scripts/db-session-by-text.sh +158 -0
  12. package/.agents/skills/opencode-qa/scripts/export-roundtrip.sh +57 -0
  13. package/.agents/skills/opencode-qa/scripts/lib/common.sh +216 -0
  14. package/.agents/skills/opencode-qa/scripts/server-smoke.sh +64 -0
  15. package/.agents/skills/opencode-qa/scripts/sse-hook-probe.sh +106 -0
  16. package/.agents/skills/opencode-qa/scripts/tui-smoke.sh +89 -0
  17. package/README.ja.md +13 -3
  18. package/README.ko.md +13 -3
  19. package/README.md +24 -14
  20. package/README.ru.md +13 -3
  21. package/README.zh-cn.md +13 -3
  22. package/bin/oh-my-opencode.js +4 -3
  23. package/bin/oh-my-opencode.test.ts +35 -7
  24. package/bin/platform.d.ts +1 -1
  25. package/bin/platform.js +4 -4
  26. package/bin/platform.test.ts +31 -9
  27. package/dist/cli/cleanup-command.d.ts +4 -0
  28. package/dist/cli/cleanup.d.ts +11 -0
  29. package/dist/cli/cli-program.d.ts +2 -1
  30. package/dist/cli/index.js +1837 -450
  31. package/dist/cli/install-codex/codex-cache.d.ts +1 -0
  32. package/dist/cli/install-codex/codex-cleanup-config.d.ts +6 -0
  33. package/dist/cli/install-codex/codex-cleanup.d.ts +21 -0
  34. package/dist/cli/install-codex/codex-config-mcp.d.ts +1 -0
  35. package/dist/cli/install-codex/codex-config-permissions.d.ts +1 -0
  36. package/dist/cli/install-codex/codex-config-reasoning.d.ts +1 -0
  37. package/dist/cli/install-codex/codex-config-toml.d.ts +2 -1
  38. package/dist/cli/install-codex/codex-installation-detection.d.ts +36 -0
  39. package/dist/cli/install-codex/codex-package-layout.d.ts +1 -0
  40. package/dist/cli/install-codex/codex-project-local-cleanup-best-effort.d.ts +7 -0
  41. package/dist/cli/install-codex/codex-project-local-cleanup.d.ts +35 -0
  42. package/dist/cli/install-codex/git-bash.d.ts +35 -0
  43. package/dist/cli/install-codex/index.d.ts +4 -0
  44. package/dist/cli/install-codex/toml-section-editor.d.ts +2 -0
  45. package/dist/cli/install-codex/types.d.ts +20 -0
  46. package/dist/cli/run/event-state.d.ts +1 -0
  47. package/dist/cli/run/poll-for-completion.d.ts +1 -0
  48. package/dist/cli/run/prompt-start.d.ts +7 -0
  49. package/dist/cli/star-request.d.ts +9 -0
  50. package/dist/config/schema/hooks.d.ts +0 -1
  51. package/dist/create-hooks.d.ts +0 -1
  52. package/dist/features/builtin-skills/skills/debugging.d.ts +2 -0
  53. package/dist/features/builtin-skills/skills/index.d.ts +1 -0
  54. package/dist/hooks/index.d.ts +0 -1
  55. package/dist/index.js +267 -114
  56. package/dist/plugin/hooks/create-core-hooks.d.ts +0 -1
  57. package/dist/plugin/hooks/create-session-hooks.d.ts +1 -2
  58. package/dist/plugin/messages-transform.d.ts +8 -1
  59. package/dist/plugin/user-abort-interrupted-recovery-guard.d.ts +6 -0
  60. package/dist/shared/prompt-async-gate/recent-dispatches.d.ts +14 -0
  61. package/dist/shared/prompt-async-gate/semantic-dedupe.d.ts +7 -0
  62. package/dist/shared/prompt-async-gate/session-idle-dispatch.d.ts +1 -0
  63. package/dist/shared/prompt-async-gate/timing.d.ts +1 -0
  64. package/dist/shared/prompt-async-gate/types.d.ts +2 -0
  65. package/dist/shared/prompt-async-gate.d.ts +1 -1
  66. package/package.json +22 -17
  67. package/packages/git-bash-mcp/dist/cli.js +367 -0
  68. package/packages/omo-codex/plugin/.mcp.json +11 -0
  69. package/packages/omo-codex/plugin/components/comment-checker/README.md +1 -1
  70. package/packages/omo-codex/plugin/components/git-bash/hooks/hooks.json +29 -0
  71. package/packages/omo-codex/plugin/components/git-bash/package.json +23 -0
  72. package/packages/omo-codex/plugin/components/git-bash/src/cli.ts +33 -0
  73. package/packages/omo-codex/plugin/components/git-bash/src/codex-hook.ts +180 -0
  74. package/packages/omo-codex/plugin/components/git-bash/src/index.ts +10 -0
  75. package/packages/omo-codex/plugin/components/git-bash/test/codex-hook.test.ts +195 -0
  76. package/packages/omo-codex/plugin/components/git-bash/tsconfig.build.json +13 -0
  77. package/packages/omo-codex/plugin/components/git-bash/tsconfig.json +25 -0
  78. package/packages/omo-codex/plugin/components/lsp/README.md +1 -1
  79. package/packages/omo-codex/plugin/components/lsp/src/cli.ts +5 -5
  80. package/packages/omo-codex/plugin/components/lsp/src/codex-hook-cli.ts +33 -0
  81. package/packages/omo-codex/plugin/components/lsp/src/codex-hook.ts +19 -27
  82. package/packages/omo-codex/plugin/components/lsp/test/codex-hook-cli.test.ts +28 -0
  83. package/packages/omo-codex/plugin/components/lsp/test/codex-hook-errors.test.ts +55 -0
  84. package/packages/omo-codex/plugin/components/lsp/test/package-smoke.test.ts +7 -5
  85. package/packages/omo-codex/plugin/components/rules/README.md +1 -1
  86. package/packages/omo-codex/plugin/components/rules/bundled-rules/windows-git-bash.md +10 -0
  87. package/packages/omo-codex/plugin/components/rules/test/package-smoke.test.ts +3 -1
  88. package/packages/omo-codex/plugin/components/rules/test/windows-git-bash-bundled-rule.test.ts +97 -0
  89. package/packages/omo-codex/plugin/components/start-work-continuation/directive.md +5 -4
  90. package/packages/omo-codex/plugin/components/start-work-continuation/test/codex-hook.test.ts +22 -0
  91. package/packages/omo-codex/plugin/components/ultrawork/README.md +2 -2
  92. package/packages/omo-codex/plugin/components/ultrawork/agents/codex-ultrawork-reviewer.toml +1 -0
  93. package/packages/omo-codex/plugin/components/ultrawork/agents/librarian.toml +8 -7
  94. package/packages/omo-codex/plugin/components/ultrawork/agents/plan.toml +2 -1
  95. package/packages/omo-codex/plugin/components/ultrawork/directive.md +31 -5
  96. package/packages/omo-codex/plugin/components/ultrawork/test/codex-hook.test.ts +27 -4
  97. package/packages/omo-codex/plugin/components/ultrawork/test/package-smoke.test.ts +25 -0
  98. package/packages/omo-codex/plugin/components/ulw-loop/README.md +1 -1
  99. package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/SKILL.md +27 -205
  100. package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/references/full-workflow.md +230 -0
  101. package/packages/omo-codex/plugin/components/ulw-loop/test/package-smoke.test.ts +102 -5
  102. package/packages/omo-codex/plugin/hooks/hooks.json +24 -2
  103. package/packages/omo-codex/plugin/package-lock.json +19 -0
  104. package/packages/omo-codex/plugin/package.json +3 -1
  105. package/packages/omo-codex/plugin/scripts/build-bundled-mcp-runtimes.mjs +16 -1
  106. package/packages/omo-codex/plugin/scripts/build-components.mjs +2 -1
  107. package/packages/omo-codex/plugin/scripts/sync-hook-status-messages.mjs +87 -0
  108. package/packages/omo-codex/plugin/skills/review-work/SKILL.md +27 -2
  109. package/packages/omo-codex/plugin/skills/start-work/SKILL.md +20 -0
  110. package/packages/omo-codex/plugin/skills/ulw-loop/SKILL.md +27 -205
  111. package/packages/omo-codex/plugin/skills/ulw-loop/references/full-workflow.md +230 -0
  112. package/packages/omo-codex/plugin/test/aggregate.test.mjs +23 -8
  113. package/packages/omo-codex/plugin/test/hook-status-message.test.mjs +56 -11
  114. package/packages/omo-codex/plugin/test/install-time-build-runtime.test.mjs +34 -0
  115. package/packages/omo-codex/plugin/test/mcp-research-servers.test.mjs +21 -0
  116. package/packages/omo-codex/plugin/test/node-install-surface.test.mjs +48 -0
  117. package/packages/omo-codex/plugin/test/subagent-guidance.test.mjs +76 -0
  118. package/packages/omo-codex/plugin/test/sync-hook-status-messages.test.mjs +66 -0
  119. package/packages/omo-codex/plugin/test/sync-skills.test.mjs +32 -2
  120. package/packages/omo-codex/scripts/install/cache.mjs +5 -3
  121. package/packages/omo-codex/scripts/install/cli-args.mjs +112 -0
  122. package/packages/omo-codex/scripts/install/config.mjs +36 -1
  123. package/packages/omo-codex/scripts/install/delegated-command.mjs +25 -0
  124. package/packages/omo-codex/scripts/install/git-bash.mjs +99 -0
  125. package/packages/omo-codex/scripts/install/git-bash.test.mjs +174 -0
  126. package/packages/omo-codex/scripts/install/mcp-runtime-cache.mjs +5 -1
  127. package/packages/omo-codex/scripts/install/multi-agent-v2-config.mjs +7 -1
  128. package/packages/omo-codex/scripts/install/permissions.d.mts +1 -0
  129. package/packages/omo-codex/scripts/install/permissions.mjs +26 -0
  130. package/packages/omo-codex/scripts/install/project-local-cleanup.mjs +229 -0
  131. package/packages/omo-codex/scripts/install/reasoning-config.mjs +14 -0
  132. package/packages/omo-codex/scripts/install/source-package-build.mjs +20 -0
  133. package/packages/omo-codex/scripts/install/toml-editor.mjs +19 -2
  134. package/packages/omo-codex/scripts/install-cli-args.test.mjs +146 -0
  135. package/packages/omo-codex/scripts/install-config-autonomous.test.mjs +48 -0
  136. package/packages/omo-codex/scripts/install-config-reasoning.test.mjs +62 -0
  137. package/packages/omo-codex/scripts/install-config.test.mjs +206 -0
  138. package/packages/omo-codex/scripts/install-local-entrypoint.test.mjs +129 -0
  139. package/packages/omo-codex/scripts/install-local-git-bash-preflight.test.mjs +145 -0
  140. package/packages/omo-codex/scripts/install-local.mjs +91 -8
  141. package/packages/omo-codex/scripts/install-local.test.mjs +15 -0
  142. package/packages/omo-codex/scripts/install-mcp-runtime.test.mjs +60 -0
  143. package/packages/omo-codex/scripts/install-packaged-local.test.mjs +67 -0
  144. package/packages/omo-codex/scripts/install-project-local-cleanup.test.mjs +277 -0
  145. package/packages/shared-skills/skills/review-work/SKILL.md +27 -2
  146. package/packages/shared-skills/skills/start-work/SKILL.md +20 -0
  147. package/dist/hooks/context-window-monitor.d.ts +0 -19
@@ -0,0 +1,277 @@
1
+ import assert from "node:assert/strict";
2
+ import { lstat, mkdir, readFile, symlink, writeFile } from "node:fs/promises";
3
+ import { join } from "node:path";
4
+ import test from "node:test";
5
+
6
+ import { installMarketplaceLocally } from "./install-local.mjs";
7
+ import { repairNearestProjectLocalCodexArtifacts } from "./install/project-local-cleanup.mjs";
8
+ import { makeTempDir, writeJson, writePluginAt } from "./install-test-fixtures.mjs";
9
+
10
+ test("#given stale project-local Codex config #when Node installer runs #then repairs the local conflict", async () => {
11
+ const repoRoot = await makeTempDir();
12
+ const codexHome = await makeTempDir();
13
+ const binDir = await makeTempDir();
14
+ const projectRoot = await makeTempDir();
15
+ const projectDirectory = join(projectRoot, "nested");
16
+ const codexPackageRoot = join(repoRoot, "packages", "omo-codex");
17
+ const pluginRoot = join(codexPackageRoot, "plugin");
18
+ const projectConfigPath = join(projectRoot, ".codex", "config.toml");
19
+
20
+ await mkdir(projectDirectory, { recursive: true });
21
+ await mkdir(join(projectRoot, ".git"), { recursive: true });
22
+ await mkdir(join(projectRoot, ".codex"), { recursive: true });
23
+ await writeJson(join(codexPackageRoot, "marketplace.json"), {
24
+ name: "debug-marketplace",
25
+ plugins: [{ name: "alpha", source: "./plugin" }],
26
+ });
27
+ await writePluginAt(pluginRoot, "alpha", "1.2.3");
28
+ await writeFile(
29
+ projectConfigPath,
30
+ [
31
+ "[features.multi_agent_v2]",
32
+ "enabled = true",
33
+ "",
34
+ "[agents]",
35
+ " max_threads = 10",
36
+ "max_depth = 4",
37
+ "",
38
+ ].join("\n"),
39
+ );
40
+
41
+ const result = await installMarketplaceLocally({
42
+ repoRoot,
43
+ codexHome,
44
+ binDir,
45
+ projectDirectory,
46
+ platform: "linux",
47
+ runCommand: async (command, args, options) => {
48
+ if (command === "npm" && args.join(" ") === "run build") {
49
+ await mkdir(join(options.cwd, "dist"), { recursive: true });
50
+ await writeFile(join(options.cwd, "dist", "cli.js"), "#!/usr/bin/env node\n");
51
+ }
52
+ },
53
+ log: () => {},
54
+ });
55
+
56
+ assert.equal(result.projectCleanup.configPath, projectConfigPath);
57
+ assert.equal(result.projectCleanup.changed, true);
58
+ assert.deepEqual(result.projectCleanup.removedKeys, ["max_threads"]);
59
+ assert.equal(result.projectCleanup.configs.length, 1);
60
+ assert.match(await readFile(result.projectCleanup.backupPath, "utf8"), /max_threads = 10/);
61
+ const content = await readFile(projectConfigPath, "utf8");
62
+ assert.doesNotMatch(content, /^\s*max_threads\s*=/m);
63
+ assert.match(content, /max_depth = 4/);
64
+ });
65
+
66
+ test("#given root and nested project-local Codex configs #when script cleanup runs #then it repairs every loaded project layer", async () => {
67
+ const projectRoot = await makeTempDir();
68
+ const projectDirectory = join(projectRoot, "nested");
69
+ const rootConfigPath = join(projectRoot, ".codex", "config.toml");
70
+ const nestedConfigPath = join(projectDirectory, ".codex", "config.toml");
71
+
72
+ await mkdir(join(projectRoot, ".git"), { recursive: true });
73
+ await mkdir(join(projectRoot, ".codex"), { recursive: true });
74
+ await mkdir(join(projectDirectory, ".codex"), { recursive: true });
75
+ await mkdir(join(projectDirectory, ".omx"), { recursive: true });
76
+ await writeFile(join(projectDirectory, ".codex", "hooks.json"), "{}\n");
77
+ await writeFile(
78
+ rootConfigPath,
79
+ [
80
+ "[features.multi_agent_v2]",
81
+ "enabled = true",
82
+ "",
83
+ "[agents]",
84
+ "max_threads = 10",
85
+ "max_depth = 4",
86
+ "",
87
+ ].join("\n"),
88
+ );
89
+ await writeFile(
90
+ nestedConfigPath,
91
+ [
92
+ "[features.multi_agent_v2]",
93
+ "enabled = true",
94
+ "",
95
+ "[agents]",
96
+ "job_max_runtime_seconds = 7200",
97
+ "",
98
+ ].join("\n"),
99
+ );
100
+
101
+ const result = await repairNearestProjectLocalCodexArtifacts({
102
+ startDirectory: projectDirectory,
103
+ now: () => new Date("2026-06-01T01:02:03.004Z"),
104
+ });
105
+
106
+ assert.equal(result.projectRoot, projectRoot);
107
+ assert.equal(result.changed, true);
108
+ assert.equal(result.configPath, rootConfigPath);
109
+ assert.deepEqual(
110
+ result.configs.map((config) => config.configPath),
111
+ [rootConfigPath, nestedConfigPath],
112
+ );
113
+ assert.deepEqual(
114
+ result.configs.map((config) => config.changed),
115
+ [true, false],
116
+ );
117
+ assert.equal(result.backupPath, `${rootConfigPath}.backup-2026-06-01T01-02-03-004Z`);
118
+ const rootContent = await readFile(rootConfigPath, "utf8");
119
+ const nestedContent = await readFile(nestedConfigPath, "utf8");
120
+ assert.doesNotMatch(rootContent, /^max_threads\s*=/m);
121
+ assert.match(rootContent, /max_depth = 4/);
122
+ assert.match(nestedContent, /job_max_runtime_seconds = 7200/);
123
+ assert.deepEqual(
124
+ result.artifacts.map((artifact) => artifact.path).sort(),
125
+ [join(projectDirectory, ".codex", "hooks.json"), join(projectDirectory, ".omx")],
126
+ );
127
+ });
128
+
129
+ test("#given no project-local config and CODEX_HOME in the parent chain #when script cleanup runs #then global Codex config is not treated as project state", async () => {
130
+ const homeRoot = await makeTempDir();
131
+ const codexHome = join(homeRoot, ".codex");
132
+ const projectDirectory = join(homeRoot, "workspace", "nested");
133
+ const globalConfigPath = join(codexHome, "config.toml");
134
+
135
+ await mkdir(projectDirectory, { recursive: true });
136
+ await mkdir(codexHome, { recursive: true });
137
+ await writeFile(
138
+ globalConfigPath,
139
+ [
140
+ "[features.multi_agent_v2]",
141
+ "enabled = true",
142
+ "",
143
+ "[agents]",
144
+ "max_threads = 10",
145
+ "max_depth = 4",
146
+ "",
147
+ ].join("\n"),
148
+ );
149
+
150
+ const result = await repairNearestProjectLocalCodexArtifacts({ startDirectory: projectDirectory, codexHome });
151
+
152
+ assert.equal(result.configPath, null);
153
+ assert.equal(result.changed, false);
154
+ const content = await readFile(globalConfigPath, "utf8");
155
+ assert.match(content, /max_threads = 10/);
156
+ assert.match(content, /max_depth = 4/);
157
+ });
158
+
159
+ test("#given project-local config is a symlink to CODEX_HOME #when script cleanup runs #then it skips the link without mutating the target", async () => {
160
+ if (process.platform === "win32") return;
161
+
162
+ const codexHome = await makeTempDir();
163
+ const projectRoot = await makeTempDir();
164
+ const globalConfigPath = join(codexHome, "config.toml");
165
+ const projectConfigPath = join(projectRoot, ".codex", "config.toml");
166
+
167
+ await mkdir(join(projectRoot, ".git"), { recursive: true });
168
+ await mkdir(join(projectRoot, ".codex"), { recursive: true });
169
+ await writeFile(
170
+ globalConfigPath,
171
+ [
172
+ "[features.multi_agent_v2]",
173
+ "enabled = true",
174
+ "",
175
+ "[agents]",
176
+ "max_threads = 10",
177
+ "max_depth = 4",
178
+ "",
179
+ ].join("\n"),
180
+ );
181
+ await symlink(globalConfigPath, projectConfigPath);
182
+
183
+ const result = await repairNearestProjectLocalCodexArtifacts({
184
+ startDirectory: projectRoot,
185
+ codexHome,
186
+ now: () => new Date("2026-06-01T00:00:00Z"),
187
+ });
188
+
189
+ assert.equal(result.configPath, null);
190
+ assert.equal(result.changed, false);
191
+ assert.equal(await pathExists(`${projectConfigPath}.backup-2026-06-01T00-00-00-000Z`), false);
192
+ const content = await readFile(globalConfigPath, "utf8");
193
+ assert.match(content, /max_threads = 10/);
194
+ assert.match(content, /max_depth = 4/);
195
+ });
196
+
197
+ test("#given malformed project directory from the environment #when script cleanup runs #then it skips project-local cleanup without failing install", async () => {
198
+ const codexHome = await makeTempDir();
199
+
200
+ const result = await repairNearestProjectLocalCodexArtifacts({
201
+ startDirectory: `bad${"\0"}path`,
202
+ codexHome,
203
+ });
204
+
205
+ assert.deepEqual(result, {
206
+ projectRoot: null,
207
+ configPath: null,
208
+ changed: false,
209
+ removedKeys: [],
210
+ configs: [],
211
+ artifacts: [],
212
+ });
213
+ });
214
+
215
+ test("#given absent project directory from the script surface #when script cleanup runs #then it skips project-local cleanup without throwing", async () => {
216
+ const codexHome = await makeTempDir();
217
+
218
+ const result = await repairNearestProjectLocalCodexArtifacts({ codexHome });
219
+
220
+ assert.deepEqual(result, {
221
+ projectRoot: null,
222
+ configPath: null,
223
+ changed: false,
224
+ removedKeys: [],
225
+ configs: [],
226
+ artifacts: [],
227
+ });
228
+ });
229
+
230
+ test("#given project cleanup hits a filesystem edge #when Node installer runs #then install succeeds and reports skipped cleanup", async () => {
231
+ const repoRoot = await makeTempDir();
232
+ const codexHome = await makeTempDir();
233
+ const binDir = await makeTempDir();
234
+ const projectRoot = await makeTempDir();
235
+ const projectDirectory = join(projectRoot, "not-a-directory");
236
+ const codexPackageRoot = join(repoRoot, "packages", "omo-codex");
237
+ const pluginRoot = join(codexPackageRoot, "plugin");
238
+ const logs = [];
239
+
240
+ await writeJson(join(codexPackageRoot, "marketplace.json"), {
241
+ name: "debug-marketplace",
242
+ plugins: [{ name: "alpha", source: "./plugin" }],
243
+ });
244
+ await writePluginAt(pluginRoot, "alpha", "1.2.3");
245
+ await writeFile(projectDirectory, "file, not directory\n");
246
+
247
+ const result = await installMarketplaceLocally({
248
+ repoRoot,
249
+ codexHome,
250
+ binDir,
251
+ projectDirectory,
252
+ platform: "linux",
253
+ runCommand: async (command, args, options) => {
254
+ if (command === "npm" && args.join(" ") === "run build") {
255
+ await mkdir(join(options.cwd, "dist"), { recursive: true });
256
+ await writeFile(join(options.cwd, "dist", "cli.js"), "#!/usr/bin/env node\n");
257
+ }
258
+ },
259
+ log: (message) => logs.push(message),
260
+ });
261
+
262
+ assert.equal(result.projectCleanup.projectRoot, null);
263
+ assert.equal(result.projectCleanup.changed, false);
264
+ assert.equal(logs.some((message) => message.includes("Skipped project-local Codex cleanup")), true);
265
+ assert.equal(logs.some((message) => message.includes("not a directory")), true);
266
+ assert.equal(await pathExists(join(codexHome, "config.toml")), true);
267
+ });
268
+
269
+ async function pathExists(path) {
270
+ try {
271
+ await lstat(path);
272
+ return true;
273
+ } catch (error) {
274
+ if (error instanceof Error && "code" in error && error.code === "ENOENT") return false;
275
+ throw error;
276
+ }
277
+ }
@@ -18,6 +18,26 @@ This skill may include examples copied from the OpenCode harness. In Codex, do n
18
18
 
19
19
  When translating `load_skills=[...]`, include the requested skill names in the spawned agent's `message`. If a code block below conflicts with this section, this section wins.
20
20
 
21
+ ## Codex Subagent Reliability
22
+
23
+ Every `spawn_agent` message must be self-contained. Start with
24
+ `TASK: <imperative assignment>`, then name `DELIVERABLE`, `SCOPE`, and
25
+ `VERIFY`. State that it is an executable assignment, not a context
26
+ handoff. Role selection requires `agent_type`; `model` +
27
+ `reasoning_effort` alone creates a default agent, not a reviewer or
28
+ worker. Prefer `fork_turns: "none"` unless full history is truly
29
+ required; paste only the review context that worker needs.
30
+
31
+ Plan and reviewer agents may run for a long time; spawn them in the background, keep doing independent root work, and poll with short wait_agent cycles. Never use a single long blocking wait for them.
32
+
33
+ Use `wait_agent` for completion signals, but treat `wait_agent` as a
34
+ mailbox signal, not proof of completion, content, or errors. After two
35
+ waits with no substantive result, send one targeted followup:
36
+ `TASK STILL ACTIVE: return <deliverable> or BLOCKED: <reason>`. If the
37
+ child stays silent or ack-only, mark that review lane inconclusive, do
38
+ not count it as PASS or approval, close if safe, and respawn a smaller
39
+ `fork_turns: "none"` reviewer with the missing deliverable.
40
+
21
41
  # Review Work - 5-Agent Parallel Review Orchestrator
22
42
 
23
43
  Launch 5 specialized sub-agents in parallel to review completed implementation work from every angle. All 5 must pass for the review to pass. If even ONE fails, the review fails.
@@ -493,9 +513,12 @@ OUTPUT FORMAT:
493
513
 
494
514
  ## Phase 2: Wait & Collect
495
515
 
496
- After launching all 5 agents in one turn, **end your response**. Wait for system notifications as each agent completes.
516
+ After launching all 5 agents in one turn, wait for completions in bounded
517
+ cycles. Do not treat a timeout, ack-only reply, or empty child result as
518
+ a PASS.
497
519
 
498
- As each completes, collect via `background_output(task_id="bg_...")`. Store each verdict:
520
+ As each completes, collect via the Codex mapping above (`wait_agent`,
521
+ then the child's substantive final result). Store each verdict:
499
522
 
500
523
  | Agent | Verdict | Notes |
501
524
  |-------|---------|-------|
@@ -506,6 +529,8 @@ As each completes, collect via `background_output(task_id="bg_...")`. Store each
506
529
  | 5. Context Mining | pending | - |
507
530
 
508
531
  Do NOT deliver the final report until ALL 5 have completed.
532
+ If a lane remains silent after the reliability followup, record it as
533
+ inconclusive and respawn a smaller reviewer/worker for that exact lane.
509
534
 
510
535
  ---
511
536
 
@@ -20,6 +20,26 @@ This skill ports the OpenCode `/start-work` flow onto Codex. Any OpenCode-only t
20
20
 
21
21
  When translating `load_skills=[...]`, name the skills inside the spawned agent's `message`. If a code block below conflicts with this section, this section wins.
22
22
 
23
+ ## Codex Subagent Reliability
24
+
25
+ Every `spawn_agent` message must be self-contained. Start with
26
+ `TASK: <imperative assignment>`, then name `DELIVERABLE`, `SCOPE`, and
27
+ `VERIFY`. State that it is an executable assignment, not a context
28
+ handoff. Role selection requires `agent_type`; `model` +
29
+ `reasoning_effort` alone creates a default agent, not a reviewer or
30
+ worker. Prefer `fork_turns: "none"` unless full history is truly
31
+ required; paste only the context the child needs.
32
+
33
+ Plan and reviewer agents may run for a long time; spawn them in the background, keep doing independent root work, and poll with short wait_agent cycles. Never use a single long blocking wait for them.
34
+
35
+ Use `wait_agent` for completion signals, but treat `wait_agent` as a
36
+ mailbox signal, not proof of completion, content, or errors. After two
37
+ waits with no substantive result, send one targeted followup:
38
+ `TASK STILL ACTIVE: return <deliverable> or BLOCKED: <reason>`. If the
39
+ child stays silent or ack-only, record the result as inconclusive, do
40
+ not count it as pass/review approval, close if safe, and respawn a
41
+ smaller `fork_turns: "none"` task with the missing deliverable.
42
+
23
43
  # start-work
24
44
 
25
45
  Execute a Prometheus work plan until every top-level checkbox is complete. This skill pairs with the Codex `Stop` / `SubagentStop` continuation hook in `components/start-work-continuation`, which re-injects the next turn while `.omo/boulder.json` says the current `codex:<session_id>` still has unchecked plan work.
@@ -1,19 +0,0 @@
1
- import type { PluginInput } from "@opencode-ai/plugin";
2
- import { type ContextLimitModelCacheState } from "../shared/context-limit-resolver";
3
- export declare function createContextWindowMonitorHook(_ctx: PluginInput, modelCacheState?: ContextLimitModelCacheState): {
4
- "tool.execute.after": (input: {
5
- tool: string;
6
- sessionID: string;
7
- callID: string;
8
- }, output: {
9
- title: string;
10
- output: string;
11
- metadata: unknown;
12
- }) => Promise<void>;
13
- event: ({ event }: {
14
- event: {
15
- type: string;
16
- properties?: unknown;
17
- };
18
- }) => Promise<void>;
19
- };