@useorgx/openclaw-plugin 0.4.9 → 0.7.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 (222) hide show
  1. package/README.md +35 -0
  2. package/dashboard/dist/assets/BJgZIVUQ.js +53 -0
  3. package/dashboard/dist/assets/BJgZIVUQ.js.br +0 -0
  4. package/dashboard/dist/assets/BJgZIVUQ.js.gz +0 -0
  5. package/dashboard/dist/assets/BXWDRGm-.js +1 -0
  6. package/dashboard/dist/assets/BXWDRGm-.js.br +0 -0
  7. package/dashboard/dist/assets/BXWDRGm-.js.gz +0 -0
  8. package/dashboard/dist/assets/BgOYB78t.js +4 -0
  9. package/dashboard/dist/assets/BgOYB78t.js.br +0 -0
  10. package/dashboard/dist/assets/BgOYB78t.js.gz +0 -0
  11. package/dashboard/dist/assets/C-KIc3Wc.js.br +0 -0
  12. package/dashboard/dist/assets/C-KIc3Wc.js.gz +0 -0
  13. package/dashboard/dist/assets/CE38zU4U.js +1 -0
  14. package/dashboard/dist/assets/CE38zU4U.js.br +0 -0
  15. package/dashboard/dist/assets/CE38zU4U.js.gz +0 -0
  16. package/dashboard/dist/assets/CFGKRAzG.js +1 -0
  17. package/dashboard/dist/assets/CFGKRAzG.js.br +0 -0
  18. package/dashboard/dist/assets/CFGKRAzG.js.gz +0 -0
  19. package/dashboard/dist/assets/CGGR2GZh.js +1 -0
  20. package/dashboard/dist/assets/CGGR2GZh.js.br +0 -0
  21. package/dashboard/dist/assets/CGGR2GZh.js.gz +0 -0
  22. package/dashboard/dist/assets/CL_wXqR7.js +1 -0
  23. package/dashboard/dist/assets/CL_wXqR7.js.br +0 -0
  24. package/dashboard/dist/assets/CL_wXqR7.js.gz +0 -0
  25. package/dashboard/dist/assets/CPFiTmlw.js +8 -0
  26. package/dashboard/dist/assets/CPFiTmlw.js.br +0 -0
  27. package/dashboard/dist/assets/CPFiTmlw.js.gz +0 -0
  28. package/dashboard/dist/assets/CZZTvkQZ.js +1 -0
  29. package/dashboard/dist/assets/CZZTvkQZ.js.br +0 -0
  30. package/dashboard/dist/assets/CZZTvkQZ.js.gz +0 -0
  31. package/dashboard/dist/assets/{CpJsfbXo.js → CxQ08qFN.js} +2 -2
  32. package/dashboard/dist/assets/CxQ08qFN.js.br +0 -0
  33. package/dashboard/dist/assets/CxQ08qFN.js.gz +0 -0
  34. package/dashboard/dist/assets/D-bf6hEI.js +213 -0
  35. package/dashboard/dist/assets/D-bf6hEI.js.br +0 -0
  36. package/dashboard/dist/assets/D-bf6hEI.js.gz +0 -0
  37. package/dashboard/dist/assets/DG6y9wJI.js +2 -0
  38. package/dashboard/dist/assets/DG6y9wJI.js.br +0 -0
  39. package/dashboard/dist/assets/DG6y9wJI.js.gz +0 -0
  40. package/dashboard/dist/assets/DNxKz-GV.js +1 -0
  41. package/dashboard/dist/assets/DNxKz-GV.js.br +0 -0
  42. package/dashboard/dist/assets/DNxKz-GV.js.gz +0 -0
  43. package/dashboard/dist/assets/DW_rKUic.js +11 -0
  44. package/dashboard/dist/assets/DW_rKUic.js.br +0 -0
  45. package/dashboard/dist/assets/DW_rKUic.js.gz +0 -0
  46. package/dashboard/dist/assets/DbNoijHm.js +1 -0
  47. package/dashboard/dist/assets/DbNoijHm.js.br +0 -0
  48. package/dashboard/dist/assets/DbNoijHm.js.gz +0 -0
  49. package/dashboard/dist/assets/DjcdE6jC.js +2 -0
  50. package/dashboard/dist/assets/DjcdE6jC.js.br +0 -0
  51. package/dashboard/dist/assets/DjcdE6jC.js.gz +0 -0
  52. package/dashboard/dist/assets/FZYuCDnt.js +1 -0
  53. package/dashboard/dist/assets/FZYuCDnt.js.br +0 -0
  54. package/dashboard/dist/assets/FZYuCDnt.js.gz +0 -0
  55. package/dashboard/dist/assets/PAUiij_z.js +1 -0
  56. package/dashboard/dist/assets/PAUiij_z.js.br +0 -0
  57. package/dashboard/dist/assets/PAUiij_z.js.gz +0 -0
  58. package/dashboard/dist/assets/cNrhgGc1.js +8 -0
  59. package/dashboard/dist/assets/cNrhgGc1.js.br +0 -0
  60. package/dashboard/dist/assets/cNrhgGc1.js.gz +0 -0
  61. package/dashboard/dist/assets/h5biQs2I.css +1 -0
  62. package/dashboard/dist/assets/h5biQs2I.css.br +0 -0
  63. package/dashboard/dist/assets/h5biQs2I.css.gz +0 -0
  64. package/dashboard/dist/assets/ic2FaMnh.js +1 -0
  65. package/dashboard/dist/assets/ic2FaMnh.js.br +0 -0
  66. package/dashboard/dist/assets/ic2FaMnh.js.gz +0 -0
  67. package/dashboard/dist/assets/nByHNHoW.js +1 -0
  68. package/dashboard/dist/assets/nByHNHoW.js.br +0 -0
  69. package/dashboard/dist/assets/nByHNHoW.js.gz +0 -0
  70. package/dashboard/dist/assets/qm8xLgv-.css +1 -0
  71. package/dashboard/dist/assets/qm8xLgv-.css.br +0 -0
  72. package/dashboard/dist/assets/qm8xLgv-.css.gz +0 -0
  73. package/dashboard/dist/assets/tS9mbYZi.js +1 -0
  74. package/dashboard/dist/assets/tS9mbYZi.js.br +0 -0
  75. package/dashboard/dist/assets/tS9mbYZi.js.gz +0 -0
  76. package/dashboard/dist/brand/anthropic-mark.svg.br +0 -0
  77. package/dashboard/dist/brand/anthropic-mark.svg.gz +0 -0
  78. package/dashboard/dist/brand/openai-mark.svg.br +0 -0
  79. package/dashboard/dist/brand/openai-mark.svg.gz +0 -0
  80. package/dashboard/dist/brand/openclaw-mark.svg.br +0 -0
  81. package/dashboard/dist/brand/openclaw-mark.svg.gz +0 -0
  82. package/dashboard/dist/brand/xandy-orchestrator.png +0 -0
  83. package/dashboard/dist/index.html +7 -5
  84. package/dashboard/dist/index.html.br +0 -0
  85. package/dashboard/dist/index.html.gz +0 -0
  86. package/dist/activity-actor-fields.js +26 -4
  87. package/dist/activity-store.js +34 -8
  88. package/dist/agent-context-store.js +79 -17
  89. package/dist/agent-run-store.js +44 -3
  90. package/dist/agent-suite.d.ts +9 -0
  91. package/dist/agent-suite.js +149 -9
  92. package/dist/artifacts/artifact-domain-schemas.d.ts +66 -0
  93. package/dist/artifacts/artifact-domain-schemas.js +357 -0
  94. package/dist/artifacts/register-artifact.d.ts +4 -3
  95. package/dist/artifacts/register-artifact.js +170 -57
  96. package/dist/chat-store.d.ts +157 -0
  97. package/dist/chat-store.js +586 -0
  98. package/dist/cli/orgx.js +11 -0
  99. package/dist/contracts/client.d.ts +43 -3
  100. package/dist/contracts/client.js +159 -30
  101. package/dist/contracts/retro-schema.d.ts +81 -0
  102. package/dist/contracts/retro-schema.js +80 -0
  103. package/dist/contracts/shared-types.d.ts +159 -0
  104. package/dist/contracts/shared-types.js +177 -1
  105. package/dist/contracts/skill-pack-schema.d.ts +192 -0
  106. package/dist/contracts/skill-pack-schema.js +180 -0
  107. package/dist/contracts/types.d.ts +227 -2
  108. package/dist/entities/auto-assignment.js +43 -17
  109. package/dist/event-sanitization.d.ts +11 -0
  110. package/dist/event-sanitization.js +113 -0
  111. package/dist/fs-utils.js +13 -1
  112. package/dist/gateway-watchdog.d.ts +5 -0
  113. package/dist/gateway-watchdog.js +50 -0
  114. package/dist/hooks/post-reporting-event.mjs +1 -5
  115. package/dist/http/helpers/activity-headline.js +13 -132
  116. package/dist/http/helpers/auto-continue-engine.d.ts +198 -10
  117. package/dist/http/helpers/auto-continue-engine.js +2531 -186
  118. package/dist/http/helpers/autopilot-operations.d.ts +19 -0
  119. package/dist/http/helpers/autopilot-operations.js +182 -31
  120. package/dist/http/helpers/autopilot-runtime.d.ts +1 -0
  121. package/dist/http/helpers/autopilot-runtime.js +308 -20
  122. package/dist/http/helpers/autopilot-slice-utils.d.ts +18 -0
  123. package/dist/http/helpers/autopilot-slice-utils.js +516 -93
  124. package/dist/http/helpers/decision-mapper.d.ts +40 -0
  125. package/dist/http/helpers/decision-mapper.js +223 -7
  126. package/dist/http/helpers/dispatch-lifecycle.d.ts +19 -2
  127. package/dist/http/helpers/dispatch-lifecycle.js +242 -37
  128. package/dist/http/helpers/kickoff-context.js +74 -0
  129. package/dist/http/helpers/llm-client.d.ts +47 -0
  130. package/dist/http/helpers/llm-client.js +256 -0
  131. package/dist/http/helpers/mission-control.d.ts +102 -3
  132. package/dist/http/helpers/mission-control.js +498 -9
  133. package/dist/http/helpers/sentinel-catalog.d.ts +23 -0
  134. package/dist/http/helpers/sentinel-catalog.js +193 -0
  135. package/dist/http/helpers/session-classification.d.ts +9 -0
  136. package/dist/http/helpers/session-classification.js +564 -0
  137. package/dist/http/helpers/slice-experience-v2.d.ts +137 -0
  138. package/dist/http/helpers/slice-experience-v2.js +677 -0
  139. package/dist/http/helpers/slice-run-projections.d.ts +72 -0
  140. package/dist/http/helpers/slice-run-projections.js +860 -0
  141. package/dist/http/helpers/triage-mapper.d.ts +43 -0
  142. package/dist/http/helpers/triage-mapper.js +549 -0
  143. package/dist/http/helpers/value-utils.js +7 -2
  144. package/dist/http/helpers/workspace-scope.d.ts +15 -0
  145. package/dist/http/helpers/workspace-scope.js +170 -0
  146. package/dist/http/index.js +1354 -97
  147. package/dist/http/routes/agent-suite.d.ts +9 -0
  148. package/dist/http/routes/agent-suite.js +207 -8
  149. package/dist/http/routes/agents-catalog.js +64 -19
  150. package/dist/http/routes/chat.d.ts +19 -0
  151. package/dist/http/routes/chat.js +522 -0
  152. package/dist/http/routes/decision-actions.d.ts +8 -1
  153. package/dist/http/routes/decision-actions.js +42 -5
  154. package/dist/http/routes/dispatch-gateway-envelope.d.ts +25 -0
  155. package/dist/http/routes/dispatch-gateway-envelope.js +26 -0
  156. package/dist/http/routes/entities.d.ts +16 -0
  157. package/dist/http/routes/entities.js +294 -6
  158. package/dist/http/routes/live-legacy.d.ts +5 -0
  159. package/dist/http/routes/live-legacy.js +23 -509
  160. package/dist/http/routes/live-misc.d.ts +12 -0
  161. package/dist/http/routes/live-misc.js +251 -31
  162. package/dist/http/routes/live-snapshot.d.ts +48 -2
  163. package/dist/http/routes/live-snapshot.js +638 -19
  164. package/dist/http/routes/live-terminal.d.ts +11 -0
  165. package/dist/http/routes/live-terminal.js +261 -0
  166. package/dist/http/routes/live-triage.d.ts +61 -0
  167. package/dist/http/routes/live-triage.js +248 -0
  168. package/dist/http/routes/mission-control-actions.d.ts +49 -1
  169. package/dist/http/routes/mission-control-actions.js +1334 -84
  170. package/dist/http/routes/mission-control-read.d.ts +48 -3
  171. package/dist/http/routes/mission-control-read.js +1593 -20
  172. package/dist/http/routes/realtime-orchestrator.d.ts +10 -0
  173. package/dist/http/routes/realtime-orchestrator.js +74 -0
  174. package/dist/http/routes/run-control.d.ts +5 -2
  175. package/dist/http/routes/run-control.js +10 -0
  176. package/dist/http/routes/sentinels-catalog.d.ts +7 -0
  177. package/dist/http/routes/sentinels-catalog.js +24 -0
  178. package/dist/http/routes/summary.js +10 -3
  179. package/dist/http/routes/usage.d.ts +24 -0
  180. package/dist/http/routes/usage.js +362 -0
  181. package/dist/http/routes/work-artifacts.js +28 -9
  182. package/dist/index.js +165 -27
  183. package/dist/local-openclaw.js +29 -6
  184. package/dist/mcp-client-setup.js +3 -3
  185. package/dist/mcp-http-handler.js +33 -59
  186. package/dist/next-up-queue-store.d.ts +16 -1
  187. package/dist/next-up-queue-store.js +89 -7
  188. package/dist/outbox.d.ts +5 -0
  189. package/dist/outbox.js +113 -9
  190. package/dist/paths.js +24 -5
  191. package/dist/reporting/rollups.d.ts +53 -0
  192. package/dist/reporting/rollups.js +148 -0
  193. package/dist/retro/domain-templates.d.ts +45 -0
  194. package/dist/retro/domain-templates.js +297 -0
  195. package/dist/retro/quality-rubric.d.ts +33 -0
  196. package/dist/retro/quality-rubric.js +213 -0
  197. package/dist/runtime-cleanup.d.ts +18 -0
  198. package/dist/runtime-cleanup.js +87 -0
  199. package/dist/services/background.d.ts +11 -0
  200. package/dist/services/background.js +22 -0
  201. package/dist/services/experiment-randomization.d.ts +21 -0
  202. package/dist/services/experiment-randomization.js +63 -0
  203. package/dist/skill-pack-state.d.ts +36 -5
  204. package/dist/skill-pack-state.js +273 -29
  205. package/dist/sync/local-agent-telemetry.d.ts +13 -0
  206. package/dist/sync/local-agent-telemetry.js +128 -0
  207. package/dist/sync/outbox-replay.js +131 -24
  208. package/dist/team-context-store.d.ts +23 -0
  209. package/dist/team-context-store.js +116 -0
  210. package/dist/telemetry/posthog.js +4 -2
  211. package/dist/tools/core-tools.d.ts +10 -14
  212. package/dist/tools/core-tools.js +1289 -24
  213. package/dist/types.d.ts +2 -0
  214. package/dist/types.js +2 -0
  215. package/dist/worker-supervisor.js +23 -0
  216. package/package.json +14 -4
  217. package/dashboard/dist/assets/B3ziCA02.js +0 -8
  218. package/dashboard/dist/assets/B5NEElEI.css +0 -1
  219. package/dashboard/dist/assets/BhapSNAs.js +0 -215
  220. package/dashboard/dist/assets/iFdvE7lx.js +0 -1
  221. package/dashboard/dist/assets/jRJsmpYM.js +0 -1
  222. package/dashboard/dist/assets/sAhvFnpk.js +0 -4
@@ -1,8 +1,142 @@
1
- import { chmodSync, createWriteStream, mkdirSync, writeFileSync, } from "node:fs";
1
+ import { chmodSync, createWriteStream, existsSync, mkdtempSync, mkdirSync, readFileSync, writeFileSync, } from "node:fs";
2
2
  import { spawn } from "node:child_process";
3
- import { dirname, resolve, sep } from "node:path";
3
+ import { homedir, tmpdir } from "node:os";
4
+ import { dirname, join, resolve, sep } from "node:path";
5
+ import { getOrgxPluginConfigDir } from "../../paths.js";
4
6
  import { normalizeCodexArgs } from "./autopilot-slice-utils.js";
5
7
  export function createAutopilotRuntime(deps) {
8
+ function hasExplicitCodexSubcommand(args) {
9
+ const first = (args[0] ?? "").trim();
10
+ if (!first || first.startsWith("-"))
11
+ return false;
12
+ return true;
13
+ }
14
+ function envFlag(name, defaultValue) {
15
+ const raw = (process.env[name] ?? "").trim().toLowerCase();
16
+ if (!raw)
17
+ return defaultValue;
18
+ return !(raw === "0" || raw === "false" || raw === "no" || raw === "off");
19
+ }
20
+ function readFirstExisting(paths) {
21
+ for (const pathname of paths) {
22
+ if (!pathname)
23
+ continue;
24
+ try {
25
+ if (!existsSync(pathname))
26
+ continue;
27
+ return readFileSync(pathname, "utf8");
28
+ }
29
+ catch {
30
+ // continue
31
+ }
32
+ }
33
+ return null;
34
+ }
35
+ function extractOrgxOpenclawUrl(configToml) {
36
+ if (!configToml)
37
+ return null;
38
+ const lines = configToml.split(/\r?\n/);
39
+ let inTargetSection = false;
40
+ for (const rawLine of lines) {
41
+ const line = rawLine.trim();
42
+ if (!line)
43
+ continue;
44
+ if (/^\[mcp_servers\.(?:"orgx-openclaw"|orgx-openclaw)\]\s*$/i.test(line)) {
45
+ inTargetSection = true;
46
+ continue;
47
+ }
48
+ if (inTargetSection && line.startsWith("[")) {
49
+ break;
50
+ }
51
+ if (!inTargetSection)
52
+ continue;
53
+ const urlMatch = line.match(/^url\s*=\s*"([^"]+)"\s*$/i);
54
+ if (!urlMatch)
55
+ continue;
56
+ const rawUrl = (urlMatch[1] ?? "").trim();
57
+ if (rawUrl.length > 0)
58
+ return rawUrl;
59
+ }
60
+ return null;
61
+ }
62
+ function prepareAutopilotCodexHome() {
63
+ const configuredHome = (process.env.ORGX_AUTOPILOT_CODEX_HOME ?? "").trim();
64
+ const preferredHome = configuredHome.length > 0
65
+ ? configuredHome
66
+ : join(getOrgxPluginConfigDir(), "codex-autopilot-home");
67
+ const sourceHome = (process.env.CODEX_HOME ?? "").trim() || join(homedir(), ".codex");
68
+ const sourceConfigCandidates = [
69
+ join(sourceHome, "config.toml"),
70
+ join(homedir(), ".codex", "config.toml"),
71
+ join(homedir(), ".config", "codex", "config.toml"),
72
+ ];
73
+ const mcpModeRaw = (process.env.ORGX_AUTOPILOT_CODEX_MCP_MODE ?? "").trim().toLowerCase();
74
+ const mcpMode = mcpModeRaw.length > 0 ? mcpModeRaw : "orgx-openclaw";
75
+ const sourceConfig = readFirstExisting(sourceConfigCandidates);
76
+ const extractedOrgxOpenclawUrl = extractOrgxOpenclawUrl(sourceConfig);
77
+ const defaultOrgxOpenclawUrl = (process.env.ORGX_AUTOPILOT_ORGX_MCP_URL ?? "").trim() ||
78
+ extractedOrgxOpenclawUrl ||
79
+ "http://127.0.0.1:18789/orgx/mcp";
80
+ const configLines = [
81
+ "# Autogenerated by OrgX autopilot runtime. This isolates codex slices",
82
+ "# from broken or noisy global MCP entries in ~/.codex/config.toml.",
83
+ "",
84
+ ];
85
+ if (mcpMode === "none") {
86
+ configLines.push("mcp_servers = {}", "");
87
+ }
88
+ else {
89
+ configLines.push('[mcp_servers."orgx-openclaw"]', `url = ${JSON.stringify(defaultOrgxOpenclawUrl)}`, "");
90
+ }
91
+ const writeAutopilotHome = (targetHome) => {
92
+ try {
93
+ mkdirSync(targetHome, { recursive: true, mode: 0o700 });
94
+ try {
95
+ chmodSync(targetHome, 0o700);
96
+ }
97
+ catch {
98
+ // best effort
99
+ }
100
+ }
101
+ catch {
102
+ return false;
103
+ }
104
+ const sourceAuthPath = join(sourceHome, "auth.json");
105
+ const targetAuthPath = join(targetHome, "auth.json");
106
+ try {
107
+ if (existsSync(sourceAuthPath)) {
108
+ const authRaw = readFileSync(sourceAuthPath, "utf8");
109
+ writeFileSync(targetAuthPath, authRaw, { encoding: "utf8", mode: 0o600 });
110
+ }
111
+ }
112
+ catch {
113
+ // best effort
114
+ }
115
+ try {
116
+ writeFileSync(join(targetHome, "config.toml"), `${configLines.join("\n")}\n`, {
117
+ encoding: "utf8",
118
+ mode: 0o600,
119
+ });
120
+ }
121
+ catch {
122
+ return false;
123
+ }
124
+ return true;
125
+ };
126
+ if (writeAutopilotHome(preferredHome))
127
+ return preferredHome;
128
+ // Hard fallback: use an ephemeral isolated CODEX_HOME so slices do not
129
+ // inherit potentially broken global MCP config.
130
+ try {
131
+ const fallbackHome = mkdtempSync(join(tmpdir(), "orgx-autopilot-codex-home-"));
132
+ if (writeAutopilotHome(fallbackHome))
133
+ return fallbackHome;
134
+ }
135
+ catch {
136
+ // best effort
137
+ }
138
+ return null;
139
+ }
6
140
  function ensurePrivateDirForFile(pathname) {
7
141
  const dir = dirname(pathname);
8
142
  mkdirSync(dir, { recursive: true, mode: 0o700 });
@@ -13,6 +147,34 @@ export function createAutopilotRuntime(deps) {
13
147
  // best effort
14
148
  }
15
149
  }
150
+ function hasSliceOutput(pathname) {
151
+ try {
152
+ if (!existsSync(pathname))
153
+ return false;
154
+ const raw = readFileSync(pathname, "utf8");
155
+ return raw.trim().length > 0;
156
+ }
157
+ catch {
158
+ return false;
159
+ }
160
+ }
161
+ function writeFallbackSliceOutput(input) {
162
+ if (hasSliceOutput(input.outputPath))
163
+ return false;
164
+ try {
165
+ writeFileSync(input.outputPath, `${JSON.stringify({
166
+ status: "error",
167
+ summary: `Worker exited without structured output (${input.reason}; code=${String(input.code)}, signal=${String(input.signal)}).`,
168
+ workstream_id: input.workstreamId ?? "unknown",
169
+ workstream_title: input.workstreamTitle ?? null,
170
+ slice_id: input.runId,
171
+ }, null, 2)}\n`, { encoding: "utf8", mode: 0o600 });
172
+ return true;
173
+ }
174
+ catch {
175
+ return false;
176
+ }
177
+ }
16
178
  function spawnCodexSliceWorker(input) {
17
179
  ensurePrivateDirForFile(input.logPath);
18
180
  ensurePrivateDirForFile(input.outputPath);
@@ -64,7 +226,19 @@ export function createAutopilotRuntime(deps) {
64
226
  child.on("close", (code, signal) => {
65
227
  deps.autoContinueSliceChildren.delete(input.runId);
66
228
  const stamp = new Date().toISOString();
229
+ const wroteFallback = writeFallbackSliceOutput({
230
+ outputPath: input.outputPath,
231
+ runId: input.runId,
232
+ workstreamId: input.env.ORGX_WORKSTREAM_ID,
233
+ workstreamTitle: input.env.ORGX_WORKSTREAM_TITLE,
234
+ code,
235
+ signal,
236
+ reason: "mock worker close",
237
+ });
67
238
  try {
239
+ if (wroteFallback) {
240
+ logStream.write(`fallback output synthesized at ${input.outputPath}\n`);
241
+ }
68
242
  logStream.write(`\n==== ${stamp} :: exit code=${String(code)} signal=${String(signal)} ====\n`);
69
243
  }
70
244
  catch {
@@ -108,21 +282,91 @@ export function createAutopilotRuntime(deps) {
108
282
  return { pid: child.pid ?? null };
109
283
  }
110
284
  if (workerKind === "claude-code" || workerKind === "claude_code") {
285
+ const hasArgFlag = (args, flag) => args.includes(flag) || args.some((arg) => typeof arg === "string" && arg.startsWith(`${flag}=`));
286
+ const readArgValue = (args, flag) => {
287
+ const inline = args.find((arg) => typeof arg === "string" && arg.startsWith(`${flag}=`));
288
+ if (inline)
289
+ return inline.slice(flag.length + 1).trim() || null;
290
+ const index = args.indexOf(flag);
291
+ const next = index >= 0 ? args[index + 1] : null;
292
+ return typeof next === "string" && next.trim().length > 0 ? next.trim() : null;
293
+ };
111
294
  const claudeBin = (process.env.ORGX_CLAUDE_CODE_BIN ?? "").trim() || "claude";
112
295
  const rawArgs = (process.env.ORGX_CLAUDE_CODE_ARGS ?? "").trim();
113
296
  const args = rawArgs.length > 0 ? rawArgs.split(/\s+/).filter(Boolean) : [];
297
+ const hasPrint = hasArgFlag(args, "--print") || args.includes("-p");
298
+ const hasOutputFormat = hasArgFlag(args, "--output-format");
299
+ const hasJsonSchema = hasArgFlag(args, "--json-schema");
300
+ const hasNoSessionPersistence = hasArgFlag(args, "--no-session-persistence");
301
+ const hasPermissionMode = hasArgFlag(args, "--permission-mode");
302
+ const hasDangerousSkipPermissions = hasArgFlag(args, "--dangerously-skip-permissions");
303
+ const hasAllowDangerousSkipPermissions = hasArgFlag(args, "--allow-dangerously-skip-permissions");
304
+ const explicitOutputFormat = readArgValue(args, "--output-format");
305
+ const explicitJsonSchemaArg = readArgValue(args, "--json-schema");
306
+ const explicitPermissionMode = readArgValue(args, "--permission-mode");
307
+ let schemaArg = null;
308
+ if (input.outputSchemaPath && !hasJsonSchema) {
309
+ try {
310
+ const schemaRaw = readFileSync(input.outputSchemaPath, "utf8").trim();
311
+ if (schemaRaw.length > 0)
312
+ schemaArg = schemaRaw;
313
+ }
314
+ catch {
315
+ schemaArg = null;
316
+ }
317
+ }
318
+ const claudeExtraArgs = [];
319
+ if (!hasPrint)
320
+ claudeExtraArgs.push("--print");
321
+ if (!hasOutputFormat)
322
+ claudeExtraArgs.push("--output-format", "json");
323
+ if (!hasNoSessionPersistence)
324
+ claudeExtraArgs.push("--no-session-persistence");
325
+ if (!hasPermissionMode)
326
+ claudeExtraArgs.push("--permission-mode", "bypassPermissions");
327
+ if (!hasDangerousSkipPermissions && !hasAllowDangerousSkipPermissions) {
328
+ claudeExtraArgs.push("--dangerously-skip-permissions");
329
+ }
330
+ if (schemaArg)
331
+ claudeExtraArgs.push("--json-schema", schemaArg);
114
332
  const logStream = createWriteStream(input.logPath, { flags: "a" });
115
333
  const outStream = createWriteStream(input.outputPath, { flags: "a" });
116
334
  logStream.write(`\n==== ${new Date().toISOString()} :: claude slice ${input.runId} ====\n`);
117
- // Claude Code invocation is environment-specific; ORGX_CLAUDE_CODE_ARGS should be set to
118
- // a headless-compatible command shape. We pass the prompt as the final argument.
119
- const child = spawn(claudeBin, [...args, input.prompt], {
335
+ logStream.write(`claude_bin: ${claudeBin}\n`);
336
+ if (claudeExtraArgs.length > 0) {
337
+ const claudeArgsForLog = claudeExtraArgs.map((arg) => {
338
+ if (schemaArg && arg === schemaArg)
339
+ return "<json-schema>";
340
+ return arg.length > 160 ? `${arg.slice(0, 157)}...` : arg;
341
+ });
342
+ logStream.write(`claude_args_injected: ${claudeArgsForLog.join(" ")}\n`);
343
+ }
344
+ if (schemaArg && input.outputSchemaPath) {
345
+ logStream.write(`claude_json_schema: ${input.outputSchemaPath}\n`);
346
+ }
347
+ else if (hasJsonSchema) {
348
+ logStream.write(`claude_json_schema: ${explicitJsonSchemaArg ?? "provided-via-args"}\n`);
349
+ }
350
+ else if (input.outputSchemaPath && !hasJsonSchema) {
351
+ logStream.write(`claude_json_schema: unavailable (${input.outputSchemaPath})\n`);
352
+ }
353
+ logStream.write(`claude_output_format: ${hasOutputFormat ? explicitOutputFormat ?? "provided" : "json"}\n`);
354
+ logStream.write(`claude_permission_mode: ${hasPermissionMode ? explicitPermissionMode ?? "provided" : "bypassPermissions"}\n`);
355
+ logStream.write(`claude_skip_permissions: ${hasDangerousSkipPermissions || hasAllowDangerousSkipPermissions ? "provided" : "dangerously-skip-permissions"}\n`);
356
+ const childEnv = {
357
+ ...process.env,
358
+ ...deps.resolveByokEnvOverrides(),
359
+ ...input.env,
360
+ };
361
+ if (claudeBin.includes(sep)) {
362
+ const binDir = dirname(claudeBin);
363
+ childEnv.PATH = childEnv.PATH ? `${binDir}:${childEnv.PATH}` : binDir;
364
+ }
365
+ // Force non-interactive structured output by default for parity with codex output-schema mode.
366
+ // If callers already pass explicit print/output/schema flags, we preserve their args unchanged.
367
+ const child = spawn(claudeBin, [...args, ...claudeExtraArgs, input.prompt], {
120
368
  cwd: input.cwd,
121
- env: {
122
- ...process.env,
123
- ...deps.resolveByokEnvOverrides(),
124
- ...input.env,
125
- },
369
+ env: childEnv,
126
370
  stdio: ["ignore", "pipe", "pipe"],
127
371
  detached: true,
128
372
  });
@@ -152,7 +396,19 @@ export function createAutopilotRuntime(deps) {
152
396
  child.on("close", (code, signal) => {
153
397
  deps.autoContinueSliceChildren.delete(input.runId);
154
398
  const stamp = new Date().toISOString();
399
+ const wroteFallback = writeFallbackSliceOutput({
400
+ outputPath: input.outputPath,
401
+ runId: input.runId,
402
+ workstreamId: input.env.ORGX_WORKSTREAM_ID,
403
+ workstreamTitle: input.env.ORGX_WORKSTREAM_TITLE,
404
+ code,
405
+ signal,
406
+ reason: "claude worker close",
407
+ });
155
408
  try {
409
+ if (wroteFallback) {
410
+ logStream.write(`fallback output synthesized at ${input.outputPath}\n`);
411
+ }
156
412
  logStream.write(`\n==== ${stamp} :: exit code=${String(code)} signal=${String(signal)} ====\n`);
157
413
  }
158
414
  catch {
@@ -199,16 +455,13 @@ export function createAutopilotRuntime(deps) {
199
455
  const codexInfo = deps.resolveCodexBinInfo();
200
456
  const codexBin = codexInfo.bin;
201
457
  const rawArgs = (process.env.ORGX_CODEX_ARGS ?? "").trim();
202
- const args = normalizeCodexArgs(rawArgs.length > 0 ? rawArgs.split(/\s+/).filter(Boolean) : ["--full-auto"]);
203
- // Autopilot slices should not fail just because an unrelated MCP server is flaky.
204
- // Default: disable firecrawl unless explicitly re-enabled.
205
- const disableFirecrawlRaw = (process.env.ORGX_AUTOPILOT_DISABLE_FIRECRAWL ?? "").trim().toLowerCase();
206
- const disableFirecrawl = disableFirecrawlRaw !== "false" && disableFirecrawlRaw !== "0" && disableFirecrawlRaw !== "no";
207
- const hasFirecrawlOverride = args.some((arg) => String(arg).includes("mcp_servers.firecrawl"));
458
+ const normalizedArgs = normalizeCodexArgs(rawArgs.length > 0
459
+ ? rawArgs.split(/\s+/).filter(Boolean)
460
+ : ["exec", "--ephemeral", "--full-auto", "--skip-git-repo-check"]);
461
+ const args = hasExplicitCodexSubcommand(normalizedArgs)
462
+ ? normalizedArgs
463
+ : ["exec", ...normalizedArgs];
208
464
  const extraArgs = [];
209
- if (disableFirecrawl && !hasFirecrawlOverride) {
210
- extraArgs.push("-c", "mcp_servers.firecrawl.enabled=false");
211
- }
212
465
  const logStream = createWriteStream(input.logPath, { flags: "a" });
213
466
  logStream.write(`\n==== ${new Date().toISOString()} :: slice ${input.runId} ====\n`);
214
467
  logStream.write(`codex_bin: ${codexBin}${codexInfo.versionString ? ` (${codexInfo.versionString})` : ""}\n`);
@@ -217,6 +470,21 @@ export function createAutopilotRuntime(deps) {
217
470
  ...deps.resolveByokEnvOverrides(),
218
471
  ...input.env,
219
472
  };
473
+ const shouldIsolateCodexHome = envFlag("ORGX_AUTOPILOT_ISOLATE_CODEX_HOME", true);
474
+ const autopilotCodexHome = prepareAutopilotCodexHome();
475
+ if (autopilotCodexHome) {
476
+ childEnv.CODEX_HOME = autopilotCodexHome;
477
+ logStream.write(shouldIsolateCodexHome
478
+ ? `codex_home: ${autopilotCodexHome}\n`
479
+ : `codex_home: ${autopilotCodexHome} (forced-safe override while ORGX_AUTOPILOT_ISOLATE_CODEX_HOME=false)\n`);
480
+ }
481
+ else if (shouldIsolateCodexHome) {
482
+ delete childEnv.CODEX_HOME;
483
+ logStream.write("codex_home: isolation unavailable (default lookup)\n");
484
+ }
485
+ else {
486
+ logStream.write("codex_home: forced-safe override unavailable (inheriting global CODEX_HOME)\n");
487
+ }
220
488
  if (codexBin.includes(sep)) {
221
489
  const binDir = dirname(codexBin);
222
490
  childEnv.PATH = childEnv.PATH ? `${binDir}:${childEnv.PATH}` : binDir;
@@ -226,7 +494,15 @@ export function createAutopilotRuntime(deps) {
226
494
  const outputArgs = hasOutputLastMessage
227
495
  ? []
228
496
  : ["--output-last-message", input.outputPath];
229
- const child = spawn(codexBin, [...args, ...extraArgs, ...outputArgs, input.prompt], {
497
+ const hasOutputSchema = args.includes("--output-schema") ||
498
+ args.some((arg) => typeof arg === "string" && arg.startsWith("--output-schema="));
499
+ const outputSchemaArgs = input.outputSchemaPath && !hasOutputSchema
500
+ ? ["--output-schema", input.outputSchemaPath]
501
+ : [];
502
+ if (outputSchemaArgs.length > 0) {
503
+ logStream.write(`output_schema: ${input.outputSchemaPath}\n`);
504
+ }
505
+ const child = spawn(codexBin, [...args, ...extraArgs, ...outputArgs, ...outputSchemaArgs, input.prompt], {
230
506
  cwd: input.cwd,
231
507
  env: childEnv,
232
508
  stdio: ["ignore", "pipe", "pipe"],
@@ -252,7 +528,19 @@ export function createAutopilotRuntime(deps) {
252
528
  child.on("close", (code, signal) => {
253
529
  deps.autoContinueSliceChildren.delete(input.runId);
254
530
  const stamp = new Date().toISOString();
531
+ const wroteFallback = writeFallbackSliceOutput({
532
+ outputPath: input.outputPath,
533
+ runId: input.runId,
534
+ workstreamId: input.env.ORGX_WORKSTREAM_ID,
535
+ workstreamTitle: input.env.ORGX_WORKSTREAM_TITLE,
536
+ code,
537
+ signal,
538
+ reason: "codex worker close",
539
+ });
255
540
  try {
541
+ if (wroteFallback) {
542
+ logStream.write(`fallback output synthesized at ${input.outputPath}\n`);
543
+ }
256
544
  logStream.write(`\n==== ${stamp} :: exit code=${String(code)} signal=${String(signal)} ====\n`);
257
545
  }
258
546
  catch {
@@ -13,6 +13,11 @@ export declare function createCodexBinResolver(): {
13
13
  resolveCodexBinInfo: () => CodexBinInfo;
14
14
  getCachedCodexProbeSummary: () => string | null;
15
15
  };
16
+ export declare function buildSliceOutputInstructions(input: {
17
+ runId: string;
18
+ schemaPath: string;
19
+ requiredSkills: string[];
20
+ }): string;
16
21
  export declare function buildWorkstreamSlicePrompt(input: {
17
22
  initiativeTitle: string;
18
23
  initiativeId: string;
@@ -33,6 +38,19 @@ export declare function buildWorkstreamSlicePrompt(input: {
33
38
  domain: string;
34
39
  requiredSkills: string[];
35
40
  };
41
+ behaviorConfig?: {
42
+ configId?: string | null;
43
+ version?: string | null;
44
+ hash?: string | null;
45
+ policySource?: string | null;
46
+ context?: string | null;
47
+ } | null;
36
48
  runId: string;
37
49
  schemaPath: string;
38
50
  }): string;
51
+ export type BuildScopeDirectiveScope = "task" | "milestone" | "workstream";
52
+ export declare function buildScopeDirective(scope: BuildScopeDirectiveScope, meta: {
53
+ milestoneTitles?: string[];
54
+ workstreamTitle?: string;
55
+ taskCount: number;
56
+ }): string;