@fitlab-ai/agent-infra 0.12.1 → 0.12.2

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 (303) hide show
  1. package/README.md +0 -2
  2. package/README.zh-CN.md +0 -2
  3. package/dist/bin/internal-cli.js +2 -17
  4. package/dist/lib/agent-clients/adapter.js +0 -13
  5. package/dist/lib/agent-clients/adapters/antigravity-cli.js +0 -5
  6. package/dist/lib/agent-clients/adapters/claude-code-credentials.js +0 -17
  7. package/dist/lib/agent-clients/adapters/claude-code.js +0 -9
  8. package/dist/lib/agent-clients/adapters/codex.js +0 -52
  9. package/dist/lib/agent-clients/adapters/opencode.js +0 -5
  10. package/dist/lib/agent-clients/adapters/traecli.js +0 -5
  11. package/dist/lib/agent-clients/config.js +19 -54
  12. package/dist/lib/agent-clients/registry.js +1 -12
  13. package/dist/lib/agent-clients/schema.js +0 -18
  14. package/dist/lib/agent-clients/tokens.js +1 -2
  15. package/dist/lib/agent-clients/types.js +0 -1
  16. package/dist/lib/decide.js +2 -0
  17. package/dist/lib/git/worktree-identity.js +1 -9
  18. package/dist/lib/internal/agent-client.js +2 -62
  19. package/dist/lib/internal/cli-route-inventory.js +1 -5
  20. package/dist/lib/internal/manual-validation.js +18 -10
  21. package/dist/lib/internal/task-create.js +1 -1
  22. package/dist/lib/internal/task-event.js +1 -8
  23. package/dist/lib/internal/task-finalization.js +0 -1
  24. package/dist/lib/internal/task-lifecycle.js +2 -2
  25. package/dist/lib/internal/task-operation-registry.js +4 -20
  26. package/dist/lib/internal/task-review.js +4 -4
  27. package/dist/lib/platform/comment-safety.js +1 -7
  28. package/dist/lib/platform/in-label-sync.js +1 -14
  29. package/dist/lib/platform/issue-comments.js +1 -16
  30. package/dist/lib/platform/issues.js +1 -1
  31. package/dist/lib/platform/operation-coordinator.js +4 -2
  32. package/dist/lib/platform/pr-change-report.js +1 -4
  33. package/dist/lib/platform/pr-checks.js +2 -8
  34. package/dist/lib/platform/provider-validation.js +0 -20
  35. package/dist/lib/platform/pull-requests.js +73 -84
  36. package/dist/lib/platform/releases.js +1 -43
  37. package/dist/lib/platform/verification-required.js +0 -2
  38. package/dist/lib/platform/verification-sync.js +1 -79
  39. package/dist/lib/process-data/normalize.js +1 -185
  40. package/dist/lib/process-data/privacy.js +1 -16
  41. package/dist/lib/process-data/sources.js +2 -279
  42. package/dist/lib/render.js +0 -12
  43. package/dist/lib/run/index.js +15 -10
  44. package/dist/lib/run/skills.js +0 -3
  45. package/dist/lib/sandbox/commands/create.js +40 -53
  46. package/dist/lib/sandbox/commands/list-running.js +0 -18
  47. package/dist/lib/sandbox/commands/start.js +7 -8
  48. package/dist/lib/sandbox/constants.js +0 -6
  49. package/dist/lib/sandbox/control/client.js +0 -1
  50. package/dist/lib/sandbox/control/container-identity.js +1 -16
  51. package/dist/lib/sandbox/control/executor.js +0 -4
  52. package/dist/lib/sandbox/control/identity-sentinel.js +0 -7
  53. package/dist/lib/sandbox/control/lifecycle.js +21 -37
  54. package/dist/lib/sandbox/control/native-file-lock.js +0 -3
  55. package/dist/lib/sandbox/control/server.js +18 -38
  56. package/dist/lib/sandbox/control/state.js +1 -9
  57. package/dist/lib/sandbox/dockerfile.js +0 -6
  58. package/dist/lib/sandbox/engine.js +0 -14
  59. package/dist/lib/sandbox/engines/docker-exact-discovery.js +1 -4
  60. package/dist/lib/sandbox/engines/wsl2-paths.js +0 -3
  61. package/dist/lib/sandbox/recovery.js +24 -26
  62. package/dist/lib/sandbox/removal.js +11 -519
  63. package/dist/lib/sandbox/task-resolver.js +0 -41
  64. package/dist/lib/sandbox/tools.js +1 -4
  65. package/dist/lib/sandbox/workspace-view.js +1 -2
  66. package/dist/lib/server/display.js +0 -6
  67. package/dist/lib/task/activity-intent.js +45 -40
  68. package/dist/lib/task/activity-log.js +9 -16
  69. package/dist/lib/task/artifact-command.js +1 -1
  70. package/dist/lib/task/artifact-lifecycle.js +61 -63
  71. package/dist/lib/task/artifact-name.js +0 -6
  72. package/dist/lib/task/artifact-operations.js +3 -3
  73. package/dist/lib/task/capabilities.js +4 -5
  74. package/dist/lib/task/commands/log.js +0 -6
  75. package/dist/lib/task/commands/status.js +17 -60
  76. package/dist/lib/task/commit-operation.js +28 -39
  77. package/dist/lib/task/completion-facts.js +56 -43
  78. package/dist/lib/task/control-authority.js +23 -256
  79. package/dist/lib/task/control-recovery.js +3 -5
  80. package/dist/lib/task/create.js +2 -4
  81. package/dist/lib/task/decision-intents.js +8 -9
  82. package/dist/lib/task/delivery-target.js +1 -40
  83. package/dist/lib/task/events.js +84 -107
  84. package/dist/lib/task/finalization.js +44 -8
  85. package/dist/lib/task/ledger-intents.js +1 -1
  86. package/dist/lib/task/lifecycle-execution.js +38 -33
  87. package/dist/lib/task/lifecycle.js +49 -41
  88. package/dist/lib/task/local-artifact-finalization.js +1 -4
  89. package/dist/lib/task/manual-validation-evidence.js +1 -37
  90. package/dist/lib/task/platform-operation-recovery.js +67 -24
  91. package/dist/lib/task/pr-delivery-fact.js +2 -5
  92. package/dist/lib/task/qualification-confirmation.js +5 -7
  93. package/dist/lib/task/resolve-ref.js +1 -25
  94. package/dist/lib/task/review-command.js +2 -2
  95. package/dist/lib/task/review-finalization.js +1 -21
  96. package/dist/lib/task/review-fingerprint.js +0 -4
  97. package/dist/lib/task/secure-fs.js +0 -56
  98. package/dist/lib/task/short-id.js +1 -39
  99. package/dist/lib/task/skill-scope.js +0 -1
  100. package/dist/lib/task/verification-engine.js +58 -282
  101. package/dist/lib/task/verification.js +6 -3
  102. package/dist/lib/task/write.js +11 -1
  103. package/lib/agent-clients/adapter.ts +0 -76
  104. package/lib/agent-clients/adapters/antigravity-cli.ts +0 -5
  105. package/lib/agent-clients/adapters/claude-code-credentials.ts +0 -19
  106. package/lib/agent-clients/adapters/claude-code.ts +0 -9
  107. package/lib/agent-clients/adapters/codex.ts +0 -56
  108. package/lib/agent-clients/adapters/opencode.ts +0 -5
  109. package/lib/agent-clients/adapters/traecli.ts +0 -5
  110. package/lib/agent-clients/config.ts +20 -61
  111. package/lib/agent-clients/registry.ts +1 -34
  112. package/lib/agent-clients/schema.ts +0 -18
  113. package/lib/agent-clients/tokens.ts +1 -2
  114. package/lib/agent-clients/types.ts +0 -15
  115. package/lib/decide.ts +1 -0
  116. package/lib/git/worktree-identity.ts +0 -10
  117. package/lib/internal/agent-client.ts +2 -70
  118. package/lib/internal/cli-route-inventory.ts +1 -4
  119. package/lib/internal/manual-validation.ts +16 -9
  120. package/lib/internal/task-create.ts +0 -1
  121. package/lib/internal/task-event.ts +1 -5
  122. package/lib/internal/task-finalization.ts +0 -1
  123. package/lib/internal/task-lifecycle.ts +3 -5
  124. package/lib/internal/task-operation-registry.ts +3 -19
  125. package/lib/internal/task-review.ts +4 -4
  126. package/lib/platform/comment-safety.ts +0 -10
  127. package/lib/platform/github-provider.ts +0 -2
  128. package/lib/platform/in-label-sync.ts +0 -16
  129. package/lib/platform/issue-comments.ts +0 -21
  130. package/lib/platform/issues.ts +0 -2
  131. package/lib/platform/operation-coordinator.ts +4 -2
  132. package/lib/platform/pr-change-report.ts +0 -5
  133. package/lib/platform/pr-checks.ts +1 -10
  134. package/lib/platform/pr-review.ts +1 -1
  135. package/lib/platform/provider-bridge.ts +0 -1
  136. package/lib/platform/provider-loader.ts +1 -5
  137. package/lib/platform/provider-validation.ts +1 -49
  138. package/lib/platform/pull-requests.ts +64 -99
  139. package/lib/platform/releases.ts +1 -40
  140. package/lib/platform/verification-required.ts +0 -2
  141. package/lib/platform/verification-sync.ts +0 -94
  142. package/lib/process-data/normalize.ts +1 -186
  143. package/lib/process-data/privacy.ts +2 -19
  144. package/lib/process-data/sources.ts +3 -283
  145. package/lib/render.ts +0 -15
  146. package/lib/run/index.ts +13 -7
  147. package/lib/run/skills.ts +0 -4
  148. package/lib/sandbox/commands/create.ts +37 -74
  149. package/lib/sandbox/commands/list-running.ts +0 -19
  150. package/lib/sandbox/commands/start.ts +7 -10
  151. package/lib/sandbox/constants.ts +0 -8
  152. package/lib/sandbox/control/client.ts +0 -1
  153. package/lib/sandbox/control/container-identity.ts +1 -16
  154. package/lib/sandbox/control/executor.ts +1 -5
  155. package/lib/sandbox/control/identity-sentinel.ts +0 -8
  156. package/lib/sandbox/control/lifecycle.ts +18 -51
  157. package/lib/sandbox/control/native-file-lock.ts +0 -8
  158. package/lib/sandbox/control/protocol.ts +0 -2
  159. package/lib/sandbox/control/server.ts +13 -39
  160. package/lib/sandbox/control/state.ts +1 -10
  161. package/lib/sandbox/dockerfile.ts +0 -11
  162. package/lib/sandbox/engine.ts +0 -17
  163. package/lib/sandbox/engines/docker-exact-discovery.ts +1 -5
  164. package/lib/sandbox/engines/wsl2-paths.ts +0 -4
  165. package/lib/sandbox/recovery.ts +24 -26
  166. package/lib/sandbox/removal.ts +11 -696
  167. package/lib/sandbox/shell.ts +1 -1
  168. package/lib/sandbox/task-resolver.ts +0 -48
  169. package/lib/sandbox/tools.ts +1 -5
  170. package/lib/sandbox/workspace-view.ts +2 -4
  171. package/lib/server/display.ts +0 -14
  172. package/lib/server/process-control.ts +1 -1
  173. package/lib/task/activity-intent.ts +36 -44
  174. package/lib/task/activity-log.ts +9 -22
  175. package/lib/task/artifact-command.ts +1 -1
  176. package/lib/task/artifact-lifecycle.ts +58 -67
  177. package/lib/task/artifact-name.ts +0 -7
  178. package/lib/task/artifact-operations.ts +3 -3
  179. package/lib/task/capabilities.ts +5 -6
  180. package/lib/task/commands/log.ts +0 -7
  181. package/lib/task/commands/status.ts +14 -79
  182. package/lib/task/commit-operation.ts +29 -51
  183. package/lib/task/completion-facts.ts +45 -42
  184. package/lib/task/control-authority.ts +27 -317
  185. package/lib/task/control-recovery.ts +2 -5
  186. package/lib/task/create.ts +2 -5
  187. package/lib/task/decision-intents.ts +5 -5
  188. package/lib/task/delivery-target.ts +0 -40
  189. package/lib/task/events.ts +89 -123
  190. package/lib/task/finalization.ts +41 -9
  191. package/lib/task/ledger-intents.ts +1 -1
  192. package/lib/task/lifecycle-execution.ts +37 -89
  193. package/lib/task/lifecycle.ts +48 -44
  194. package/lib/task/local-artifact-finalization.ts +0 -7
  195. package/lib/task/manual-validation-evidence.ts +1 -47
  196. package/lib/task/platform-operation-recovery.ts +50 -26
  197. package/lib/task/pr-delivery-fact.ts +2 -11
  198. package/lib/task/qualification-confirmation.ts +6 -6
  199. package/lib/task/resolve-ref.ts +0 -23
  200. package/lib/task/review-command.ts +2 -2
  201. package/lib/task/review-finalization.ts +1 -27
  202. package/lib/task/review-fingerprint.ts +0 -8
  203. package/lib/task/secure-fs.ts +0 -42
  204. package/lib/task/short-id.ts +0 -43
  205. package/lib/task/skill-scope.ts +0 -1
  206. package/lib/task/verification-engine.ts +56 -287
  207. package/lib/task/verification.ts +5 -5
  208. package/lib/task/write.ts +12 -1
  209. package/package.json +2 -2
  210. package/templates/.agents/README.en.md +1 -3
  211. package/templates/.agents/README.zh-CN.md +0 -2
  212. package/templates/.agents/rules/README.en.md +0 -1
  213. package/templates/.agents/rules/README.zh-CN.md +0 -1
  214. package/templates/.agents/rules/commit-and-pr.en.md +1 -1
  215. package/templates/.agents/rules/commit-and-pr.zh-CN.md +1 -1
  216. package/templates/.agents/rules/no-mid-flow-questions.en.md +0 -10
  217. package/templates/.agents/rules/no-mid-flow-questions.zh-CN.md +0 -10
  218. package/templates/.agents/rules/pr-sync.en.md +1 -1
  219. package/templates/.agents/rules/pr-sync.zh-CN.md +1 -1
  220. package/templates/.agents/rules/task-management.en.md +3 -3
  221. package/templates/.agents/rules/task-management.zh-CN.md +3 -3
  222. package/templates/.agents/skills/analyze-task/SKILL.en.md +3 -3
  223. package/templates/.agents/skills/analyze-task/SKILL.zh-CN.md +3 -3
  224. package/templates/.agents/skills/cancel-task/SKILL.en.md +2 -2
  225. package/templates/.agents/skills/cancel-task/SKILL.zh-CN.md +2 -2
  226. package/templates/.agents/skills/code-task/SKILL.en.md +2 -2
  227. package/templates/.agents/skills/code-task/SKILL.zh-CN.md +4 -4
  228. package/templates/.agents/skills/commit/SKILL.en.md +2 -2
  229. package/templates/.agents/skills/commit/SKILL.zh-CN.md +2 -2
  230. package/templates/.agents/skills/commit/reference/commit-orchestration.en.md +6 -6
  231. package/templates/.agents/skills/commit/reference/commit-orchestration.zh-CN.md +6 -6
  232. package/templates/.agents/skills/plan-task/SKILL.en.md +2 -2
  233. package/templates/.agents/skills/plan-task/SKILL.zh-CN.md +2 -2
  234. package/templates/.agents/skills/review-analysis/SKILL.en.md +3 -3
  235. package/templates/.agents/skills/review-analysis/SKILL.zh-CN.md +3 -3
  236. package/templates/.agents/skills/review-code/SKILL.en.md +5 -5
  237. package/templates/.agents/skills/review-code/SKILL.zh-CN.md +5 -5
  238. package/templates/.agents/skills/review-plan/SKILL.en.md +3 -3
  239. package/templates/.agents/skills/review-plan/SKILL.zh-CN.md +3 -3
  240. package/templates/.agents/skills/review-pr/SKILL.en.md +4 -4
  241. package/templates/.agents/skills/review-pr/SKILL.zh-CN.md +4 -4
  242. package/templates/.agents/skills/run-manual-validation/SKILL.en.md +1 -1
  243. package/templates/.agents/skills/run-manual-validation/SKILL.zh-CN.md +1 -1
  244. package/templates/.agents/skills/update-agent-infra/scripts/sync-templates.js +3 -75
  245. package/templates/.agents/templates/task.en.md +1 -0
  246. package/templates/.agents/templates/task.zh-CN.md +1 -0
  247. package/templates/.claude/settings.json +0 -24
  248. package/templates/.codex/hooks.json +0 -50
  249. package/dist/lib/agent-clients/adapters/codex-lifecycle/app-server.js +0 -582
  250. package/dist/lib/agent-clients/adapters/codex-lifecycle/binding.js +0 -114
  251. package/dist/lib/agent-clients/adapters/codex-lifecycle/build-identity.js +0 -237
  252. package/dist/lib/agent-clients/adapters/codex-lifecycle/cli.js +0 -443
  253. package/dist/lib/agent-clients/adapters/codex-lifecycle/evidence.js +0 -236
  254. package/dist/lib/agent-clients/adapters/codex-lifecycle/recovery.js +0 -292
  255. package/dist/lib/agent-clients/adapters/codex-lifecycle/store.js +0 -267
  256. package/dist/lib/agent-clients/adapters/codex-orchestration.js +0 -466
  257. package/dist/lib/internal/task-orchestration.js +0 -71
  258. package/dist/lib/platform/verification.js +0 -6
  259. package/dist/lib/run/prompt.js +0 -2
  260. package/dist/lib/sandbox/engines/authority.js +0 -289
  261. package/dist/lib/task/delegation-receipts.js +0 -410
  262. package/dist/lib/task/orchestration.js +0 -1233
  263. package/dist/lib/task/verification-checks.js +0 -9
  264. package/dist/lib/task/workspace-snapshot.js +0 -121
  265. package/dist/lifecycle-build-manifest.json +0 -6
  266. package/lib/agent-clients/adapters/codex-lifecycle/app-server.ts +0 -688
  267. package/lib/agent-clients/adapters/codex-lifecycle/binding.ts +0 -147
  268. package/lib/agent-clients/adapters/codex-lifecycle/build-identity.ts +0 -349
  269. package/lib/agent-clients/adapters/codex-lifecycle/cli.ts +0 -506
  270. package/lib/agent-clients/adapters/codex-lifecycle/evidence.ts +0 -385
  271. package/lib/agent-clients/adapters/codex-lifecycle/manifest-files.json +0 -41
  272. package/lib/agent-clients/adapters/codex-lifecycle/recovery.ts +0 -418
  273. package/lib/agent-clients/adapters/codex-lifecycle/store.ts +0 -354
  274. package/lib/agent-clients/adapters/codex-orchestration.ts +0 -630
  275. package/lib/internal/task-orchestration.ts +0 -74
  276. package/lib/platform/verification.ts +0 -11
  277. package/lib/run/prompt.ts +0 -1
  278. package/lib/sandbox/engines/authority.ts +0 -365
  279. package/lib/task/delegation-receipts.ts +0 -547
  280. package/lib/task/orchestration.ts +0 -1651
  281. package/lib/task/verification-checks.ts +0 -10
  282. package/lib/task/workspace-snapshot.ts +0 -144
  283. package/templates/.agents/hooks/lifecycle-delegation.js +0 -140
  284. package/templates/.agents/rules/lifecycle-orchestration.en.md +0 -44
  285. package/templates/.agents/rules/lifecycle-orchestration.zh-CN.md +0 -44
  286. package/templates/.agents/skills/run-task/SKILL.en.md +0 -29
  287. package/templates/.agents/skills/run-task/SKILL.zh-CN.md +0 -29
  288. package/templates/.agents/skills/run-task/config/verify.en.json +0 -10
  289. package/templates/.agents/skills/run-task/config/verify.zh-CN.json +0 -10
  290. package/templates/.agents/skills/run-task/reference/host-validation.en.md +0 -24
  291. package/templates/.agents/skills/run-task/reference/host-validation.zh-CN.md +0 -24
  292. package/templates/.claude/agents/agent-infra-lifecycle-executor.en.md +0 -6
  293. package/templates/.claude/agents/agent-infra-lifecycle-executor.zh-CN.md +0 -6
  294. package/templates/.claude/agents/agent-infra-lifecycle-reviewer.en.md +0 -6
  295. package/templates/.claude/agents/agent-infra-lifecycle-reviewer.zh-CN.md +0 -6
  296. package/templates/.claude/commands/run-task.en.md +0 -8
  297. package/templates/.claude/commands/run-task.zh-CN.md +0 -8
  298. package/templates/.codex/agents/agent-infra-lifecycle-executor.en.toml +0 -3
  299. package/templates/.codex/agents/agent-infra-lifecycle-executor.zh-CN.toml +0 -3
  300. package/templates/.codex/agents/agent-infra-lifecycle-reviewer.en.toml +0 -3
  301. package/templates/.codex/agents/agent-infra-lifecycle-reviewer.zh-CN.toml +0 -3
  302. package/templates/.opencode/commands/run-task.en.md +0 -11
  303. package/templates/.opencode/commands/run-task.zh-CN.md +0 -11
@@ -1,147 +0,0 @@
1
- import { managedDelegationRole } from '../../../task/delegation-receipts.ts';
2
-
3
- const MARKER_PREFIX = '__agent_infra_binding_';
4
- const BASE32_ALPHABET = 'abcdefghijklmnopqrstuvwxyz234567';
5
- const TASK_ID_PATTERN = /^TASK-[0-9]{8}-[0-9]{6}$/u;
6
- const SAFE_LABEL_PATTERN = /^[a-z0-9_]{1,80}$/u;
7
- const SAFE_ID_PATTERN = /^[A-Za-z0-9_-]{1,128}$/u;
8
-
9
- type CodexLifecycleTaskBinding = Readonly<{
10
- taskId: string;
11
- runId: string;
12
- receiptId: string;
13
- }>;
14
-
15
- function assertSafeTaskName(taskName: string): void {
16
- if (Buffer.byteLength(taskName, 'utf8') > 255 || !/^[a-z0-9_]+$/u.test(taskName)) {
17
- throw new Error('Codex task_name must use lowercase letters, digits, and underscores within 255 bytes');
18
- }
19
- }
20
-
21
- function encodeTaskNamePayload(value: string): string {
22
- let buffer = 0;
23
- let bits = 0;
24
- let encoded = '';
25
- for (const byte of Buffer.from(value, 'utf8')) {
26
- buffer = (buffer << 8) | byte;
27
- bits += 8;
28
- while (bits >= 5) {
29
- encoded += BASE32_ALPHABET[(buffer >>> (bits - 5)) & 31];
30
- bits -= 5;
31
- }
32
- }
33
- if (bits) encoded += BASE32_ALPHABET[(buffer << (5 - bits)) & 31];
34
- return encoded;
35
- }
36
-
37
- function decodeTaskNamePayload(encoded: string): string | null {
38
- let buffer = 0;
39
- let bits = 0;
40
- const bytes: number[] = [];
41
- for (const character of encoded) {
42
- const value = BASE32_ALPHABET.indexOf(character);
43
- if (value < 0) return null;
44
- buffer = (buffer << 5) | value;
45
- bits += 5;
46
- if (bits >= 8) {
47
- bytes.push((buffer >>> (bits - 8)) & 255);
48
- bits -= 8;
49
- }
50
- }
51
- if (bits && (buffer & ((1 << bits) - 1)) !== 0) return null;
52
- const decoded = Buffer.from(bytes).toString('utf8');
53
- return encodeTaskNamePayload(decoded) === encoded ? decoded : null;
54
- }
55
-
56
- function encodeCodexLifecycleBinding(binding: CodexLifecycleTaskBinding): string {
57
- if (!TASK_ID_PATTERN.test(binding.taskId)
58
- || !SAFE_ID_PATTERN.test(binding.runId)
59
- || !SAFE_ID_PATTERN.test(binding.receiptId)) {
60
- throw new Error('Codex lifecycle task binding is invalid');
61
- }
62
- return `${MARKER_PREFIX}${encodeTaskNamePayload(JSON.stringify(binding))}`;
63
- }
64
-
65
- function appendCodexLifecycleBinding(label: string, binding: CodexLifecycleTaskBinding): string {
66
- if (!SAFE_LABEL_PATTERN.test(label)) throw new Error('Codex task_name label is invalid');
67
- const taskName = `${label}${encodeCodexLifecycleBinding(binding)}`;
68
- assertSafeTaskName(taskName);
69
- return taskName;
70
- }
71
-
72
- function parseCodexLifecycleBinding(taskName: string): Readonly<{
73
- taskName: string;
74
- label: string;
75
- binding: CodexLifecycleTaskBinding;
76
- }> | null {
77
- assertSafeTaskName(taskName);
78
- const markerIndex = taskName.lastIndexOf(MARKER_PREFIX);
79
- if (markerIndex < 1) return null;
80
- const label = taskName.slice(0, markerIndex);
81
- const encoded = taskName.slice(markerIndex + MARKER_PREFIX.length);
82
- if (!SAFE_LABEL_PATTERN.test(label) || !/^[a-z2-7]+$/u.test(encoded)) return null;
83
- try {
84
- const decoded = decodeTaskNamePayload(encoded);
85
- if (!decoded) return null;
86
- const value = JSON.parse(decoded) as Record<string, unknown>;
87
- if (Object.keys(value).sort().join(',') !== 'receiptId,runId,taskId'
88
- || typeof value.taskId !== 'string' || !TASK_ID_PATTERN.test(value.taskId)
89
- || typeof value.runId !== 'string' || !SAFE_ID_PATTERN.test(value.runId)
90
- || typeof value.receiptId !== 'string' || !SAFE_ID_PATTERN.test(value.receiptId)) return null;
91
- return Object.freeze({
92
- taskName,
93
- label,
94
- binding: Object.freeze({ taskId: value.taskId, runId: value.runId, receiptId: value.receiptId })
95
- });
96
- } catch {
97
- return null;
98
- }
99
- }
100
-
101
- function verifyCodexLifecycleTaskBinding(
102
- binding: CodexLifecycleTaskBinding,
103
- run: Readonly<{ taskId: string; runId: string; status: string; pendingDelegation: Readonly<{
104
- id: string; taskId: string; runId: string; client: string; role: string; status: string;
105
- requestedModel: string | null; requestedReasoningEffort: string | null;
106
- }> | null }>,
107
- nativeAgent: string,
108
- expected: Readonly<{ requestedModel?: string; requestedReasoningEffort?: string }> = {}
109
- ): void {
110
- if (!codexReceiptMatchesBinding(binding, run, nativeAgent, expected)) {
111
- throw new Error('Codex lifecycle task binding does not match the current pending receipt');
112
- }
113
- }
114
-
115
- function codexReceiptMatchesBinding(
116
- binding: CodexLifecycleTaskBinding,
117
- run: Parameters<typeof verifyCodexLifecycleTaskBinding>[1],
118
- nativeAgent: string,
119
- expected: Readonly<{ requestedModel?: string; requestedReasoningEffort?: string }>
120
- ): boolean {
121
- const receipt = run.pendingDelegation;
122
- return Boolean(receipt)
123
- && run.status === 'running'
124
- && run.runId === binding.runId
125
- && receipt!.runId === binding.runId
126
- && receipt!.id === binding.receiptId
127
- && receipt!.client === 'codex'
128
- && receipt!.status === 'prepared'
129
- && managedDelegationRole(nativeAgent) === receipt!.role
130
- && requestedBindingMatches(receipt!, expected);
131
- }
132
-
133
- function requestedBindingMatches(
134
- receipt: NonNullable<Parameters<typeof verifyCodexLifecycleTaskBinding>[1]['pendingDelegation']>,
135
- expected: Readonly<{ requestedModel?: string; requestedReasoningEffort?: string }>
136
- ): boolean {
137
- return (!expected.requestedModel || receipt.requestedModel === expected.requestedModel)
138
- && (!expected.requestedReasoningEffort || receipt.requestedReasoningEffort === expected.requestedReasoningEffort);
139
- }
140
-
141
- export {
142
- appendCodexLifecycleBinding,
143
- encodeCodexLifecycleBinding,
144
- parseCodexLifecycleBinding,
145
- verifyCodexLifecycleTaskBinding
146
- };
147
- export type { CodexLifecycleTaskBinding };
@@ -1,349 +0,0 @@
1
- import crypto from 'node:crypto';
2
- import fs from 'node:fs';
3
- import path from 'node:path';
4
- import { fileURLToPath } from 'node:url';
5
-
6
- import semver from 'semver';
7
-
8
- const LIFECYCLE_PROTOCOL_VERSION = 3;
9
-
10
- type LifecycleBuildIdentity = Readonly<{
11
- protocolVersion: 3;
12
- packageVersion: string;
13
- internalExecutableBuildHash: string;
14
- lifecycleContractHash: string;
15
- }>;
16
-
17
- type LifecycleBuildIdentityOptions = Readonly<{
18
- executableFiles?: readonly string[];
19
- contractFiles?: readonly string[];
20
- }>;
21
-
22
- type LifecycleManifestFiles = Readonly<{
23
- executableFiles: readonly string[];
24
- contractFiles: readonly string[];
25
- launcherShebang: LifecycleLauncherShebang;
26
- }>;
27
-
28
- type LifecycleLauncherShebang = Readonly<{
29
- sourceFile: string;
30
- compiledFile: string;
31
- canonicalLine: string;
32
- acceptedLines: readonly string[];
33
- }>;
34
-
35
- type IdentityVerification = Readonly<{
36
- ok: boolean;
37
- code: string | null;
38
- message: string | null;
39
- warnings: readonly LifecycleIdentityWarning[];
40
- }>;
41
-
42
- type LifecycleIdentityWarning = Readonly<{
43
- code: 'CODEX_LIFECYCLE_BUILD_MISMATCH' | 'CODEX_LIFECYCLE_CONTRACT_MISMATCH';
44
- message: string;
45
- action: 'rebuild-sandbox';
46
- }>;
47
-
48
- function exactText(value: unknown): value is string {
49
- return typeof value === 'string' && value.trim() === value && value.length > 0;
50
- }
51
-
52
- function isCanonicalLifecyclePackageVersion(value: unknown): value is string {
53
- return typeof value === 'string' && semver.valid(value) === value;
54
- }
55
-
56
- function isLifecycleProtocolVersion(value: unknown): value is typeof LIFECYCLE_PROTOCOL_VERSION {
57
- return value === LIFECYCLE_PROTOCOL_VERSION;
58
- }
59
-
60
- function normalizeRelativePath(value: string): string {
61
- return value.replaceAll('\\', '/');
62
- }
63
-
64
- function isSafeLifecyclePath(value: unknown): value is string {
65
- return exactText(value)
66
- && value === normalizeRelativePath(value)
67
- && !path.isAbsolute(value)
68
- && !/^[A-Za-z]:[\\/]/u.test(value)
69
- && !value.split('/').includes('..');
70
- }
71
-
72
- function isLifecycleLauncherLine(value: unknown): value is string {
73
- return typeof value === 'string'
74
- && value.length > 1
75
- && value.slice(0, -1).trim() === value.slice(0, -1)
76
- && value.startsWith('#!')
77
- && value.endsWith('\n')
78
- && value.indexOf('\n') === value.length - 1
79
- && !value.includes('\r');
80
- }
81
-
82
- function readLifecycleLauncherShebang(
83
- value: unknown,
84
- executableFiles: readonly string[]
85
- ): LifecycleLauncherShebang {
86
- if (!value || typeof value !== 'object' || Array.isArray(value)) {
87
- throw new Error('Lifecycle manifest launcher shebang policy is invalid');
88
- }
89
- const policy = value as Record<string, unknown>;
90
- if (!isSafeLifecyclePath(policy.sourceFile)
91
- || !isSafeLifecyclePath(policy.compiledFile)
92
- || !isLifecycleLauncherLine(policy.canonicalLine)
93
- || !Array.isArray(policy.acceptedLines)
94
- || !policy.acceptedLines.every(isLifecycleLauncherLine)
95
- || new Set(policy.acceptedLines).size !== policy.acceptedLines.length
96
- || !policy.acceptedLines.includes(policy.canonicalLine)
97
- || !executableFiles.includes(policy.sourceFile)
98
- || policy.compiledFile !== normalizeRelativePath(path.join(
99
- 'dist',
100
- policy.sourceFile.endsWith('.ts')
101
- ? policy.sourceFile.replace(/\.ts$/u, '.js')
102
- : policy.sourceFile
103
- ))) {
104
- throw new Error('Lifecycle manifest launcher shebang policy is invalid');
105
- }
106
- return Object.freeze({
107
- sourceFile: policy.sourceFile,
108
- compiledFile: policy.compiledFile,
109
- canonicalLine: policy.canonicalLine,
110
- acceptedLines: Object.freeze([...policy.acceptedLines])
111
- });
112
- }
113
-
114
- function readLifecycleManifestFiles(packageRoot: string): LifecycleManifestFiles {
115
- const file = path.join(
116
- packageRoot,
117
- 'lib',
118
- 'agent-clients',
119
- 'adapters',
120
- 'codex-lifecycle',
121
- 'manifest-files.json'
122
- );
123
- const value = JSON.parse(fs.readFileSync(file, 'utf8')) as {
124
- executableFiles?: unknown;
125
- contractFiles?: unknown;
126
- launcherShebang?: unknown;
127
- };
128
- if (!Array.isArray(value.executableFiles)
129
- || !Array.isArray(value.contractFiles)
130
- || !value.executableFiles.every(isSafeLifecyclePath)
131
- || !value.contractFiles.every(isSafeLifecyclePath)
132
- || new Set(value.executableFiles).size !== value.executableFiles.length
133
- || new Set(value.contractFiles).size !== value.contractFiles.length) {
134
- throw new Error('Lifecycle manifest file list is invalid');
135
- }
136
- const executableFiles = Object.freeze([...value.executableFiles] as string[]);
137
- return Object.freeze({
138
- executableFiles,
139
- contractFiles: Object.freeze([...value.contractFiles] as string[]),
140
- launcherShebang: readLifecycleLauncherShebang(value.launcherShebang, executableFiles)
141
- });
142
- }
143
-
144
- function executablePackageRoot(): string {
145
- let current = path.dirname(fileURLToPath(import.meta.url));
146
- while (true) {
147
- const candidate = path.join(current, 'package.json');
148
- if (fs.existsSync(candidate)) {
149
- const value = JSON.parse(fs.readFileSync(candidate, 'utf8')) as { name?: unknown };
150
- if (value.name === '@fitlab-ai/agent-infra') return current;
151
- }
152
- const parent = path.dirname(current);
153
- if (parent === current) throw new Error('Lifecycle executable package root is unavailable');
154
- current = parent;
155
- }
156
- }
157
-
158
- function normalizeLifecycleLauncherBytes(
159
- relative: string,
160
- content: Buffer,
161
- policy: LifecycleLauncherShebang
162
- ): Buffer {
163
- const normalized = normalizeRelativePath(relative);
164
- if (normalized !== policy.sourceFile && normalized !== policy.compiledFile) return content;
165
- const lineEnd = content.indexOf(0x0a);
166
- if (lineEnd < 0) return content;
167
- const firstLine = content.subarray(0, lineEnd + 1);
168
- if (!policy.acceptedLines.some((line) => Buffer.from(line).equals(firstLine))) return content;
169
- return Buffer.concat([
170
- Buffer.from(policy.canonicalLine),
171
- content.subarray(lineEnd + 1)
172
- ]);
173
- }
174
-
175
- function hashFiles(
176
- root: string,
177
- files: readonly string[],
178
- launcherShebang?: LifecycleLauncherShebang
179
- ): string {
180
- const hash = crypto.createHash('sha256');
181
- for (const relative of [...new Set(files.map(normalizeRelativePath))].sort()) {
182
- if (path.isAbsolute(relative) || relative.split(/[\\/]/u).includes('..')) {
183
- throw new Error(`Lifecycle manifest path '${relative}' is unsafe`);
184
- }
185
- const file = path.join(root, relative);
186
- const stat = fs.lstatSync(file);
187
- if (!stat.isFile() || stat.isSymbolicLink()) {
188
- throw new Error(`Lifecycle manifest entry '${relative}' must be a regular file`);
189
- }
190
- hash.update(relative);
191
- hash.update('\0');
192
- const content = fs.readFileSync(file);
193
- hash.update(launcherShebang
194
- ? normalizeLifecycleLauncherBytes(relative, content, launcherShebang)
195
- : content);
196
- hash.update('\0');
197
- }
198
- return hash.digest('hex');
199
- }
200
-
201
- function resolveLifecycleExecutableFiles(root: string, entries: readonly string[]): string[] {
202
- const pending = [...entries];
203
- const resolved = new Set<string>();
204
- while (pending.length > 0) {
205
- const relative = normalizeRelativePath(pending.pop()!);
206
- if (resolved.has(relative)) continue;
207
- resolved.add(relative);
208
- if (!/\.[cm]?[jt]s$/u.test(relative)) continue;
209
- const file = path.join(root, relative);
210
- const source = fs.readFileSync(file, 'utf8');
211
- const imports = source.matchAll(/(?:\bfrom\s*|\bimport\s*(?:\(\s*)?)["'](\.[^"']+)["']/gu);
212
- for (const match of imports) {
213
- const requested = match[1]!;
214
- const base = path.resolve(path.dirname(file), requested);
215
- const candidates = [
216
- base,
217
- `${base}.ts`, `${base}.js`,
218
- path.join(base, 'index.ts'), path.join(base, 'index.js')
219
- ];
220
- const dependency = candidates.find((candidate) => fs.existsSync(candidate) && fs.lstatSync(candidate).isFile());
221
- if (!dependency) throw new Error(`Lifecycle executable dependency '${requested}' from '${relative}' is unavailable`);
222
- const dependencyRelative = path.relative(root, dependency);
223
- if (dependencyRelative.startsWith('..') || path.isAbsolute(dependencyRelative)) {
224
- throw new Error(`Lifecycle executable dependency '${requested}' escapes the package root`);
225
- }
226
- pending.push(normalizeRelativePath(dependencyRelative));
227
- }
228
- }
229
- return [...resolved].sort();
230
- }
231
-
232
- function computeLifecycleBuildIdentity(
233
- repoRoot: string,
234
- options: LifecycleBuildIdentityOptions = {}
235
- ): LifecycleBuildIdentity {
236
- const packageRoot = executablePackageRoot();
237
- const executableRoot = options.executableFiles ? repoRoot : packageRoot;
238
- const defaults = readLifecycleManifestFiles(packageRoot);
239
- const packageJson = JSON.parse(fs.readFileSync(path.join(executableRoot, 'package.json'), 'utf8')) as {
240
- version?: unknown;
241
- };
242
- if (!exactText(packageJson.version)) throw new Error('Lifecycle package version is invalid');
243
- let internalExecutableBuildHash: string;
244
- if (options.executableFiles) {
245
- internalExecutableBuildHash = hashFiles(repoRoot, options.executableFiles, defaults.launcherShebang);
246
- } else {
247
- const manifestFile = path.join(executableRoot, 'dist', 'lifecycle-build-manifest.json');
248
- if (fs.existsSync(manifestFile)) {
249
- const manifest = JSON.parse(fs.readFileSync(manifestFile, 'utf8')) as {
250
- protocolVersion?: unknown;
251
- packageVersion?: unknown;
252
- sourceInputHash?: unknown;
253
- internalExecutableBuildHash?: unknown;
254
- };
255
- if (manifest.protocolVersion !== LIFECYCLE_PROTOCOL_VERSION
256
- || manifest.packageVersion !== packageJson.version
257
- || !exactText(manifest.sourceInputHash)
258
- || !exactText(manifest.internalExecutableBuildHash)) {
259
- throw new Error('Lifecycle executable build manifest is stale or invalid');
260
- }
261
- if (fileURLToPath(import.meta.url).split(path.sep).includes('dist')) {
262
- const compiledFiles = defaults.executableFiles.map((file) =>
263
- file.endsWith('.ts') ? path.join('dist', file.replace(/\.ts$/u, '.js')) : file
264
- );
265
- if (hashFiles(
266
- executableRoot,
267
- resolveLifecycleExecutableFiles(executableRoot, compiledFiles),
268
- defaults.launcherShebang
269
- ) !== manifest.internalExecutableBuildHash) {
270
- throw new Error('Lifecycle compiled executable build does not match its manifest');
271
- }
272
- } else if (hashFiles(
273
- executableRoot,
274
- resolveLifecycleExecutableFiles(executableRoot, defaults.executableFiles),
275
- defaults.launcherShebang
276
- ) !== manifest.sourceInputHash) {
277
- throw new Error('Lifecycle executable build manifest is stale or invalid');
278
- }
279
- internalExecutableBuildHash = manifest.internalExecutableBuildHash;
280
- } else internalExecutableBuildHash = hashFiles(
281
- executableRoot,
282
- resolveLifecycleExecutableFiles(executableRoot, defaults.executableFiles),
283
- defaults.launcherShebang
284
- );
285
- }
286
- return Object.freeze({
287
- protocolVersion: LIFECYCLE_PROTOCOL_VERSION,
288
- packageVersion: packageJson.version,
289
- internalExecutableBuildHash,
290
- lifecycleContractHash: hashFiles(
291
- repoRoot,
292
- options.contractFiles ?? defaults.contractFiles
293
- )
294
- });
295
- }
296
-
297
- function verifyLifecycleBuildIdentity(
298
- expected: LifecycleBuildIdentity,
299
- actual: LifecycleBuildIdentity
300
- ): IdentityVerification {
301
- if (actual.protocolVersion !== expected.protocolVersion) {
302
- return {
303
- ok: false,
304
- code: 'CODEX_LIFECYCLE_PROTOCOL_MISMATCH',
305
- message: 'Codex lifecycle protocol version does not match',
306
- warnings: []
307
- };
308
- }
309
- const warnings: LifecycleIdentityWarning[] = [];
310
- if (actual.packageVersion !== expected.packageVersion
311
- || actual.internalExecutableBuildHash !== expected.internalExecutableBuildHash) {
312
- warnings.push({
313
- code: 'CODEX_LIFECYCLE_BUILD_MISMATCH',
314
- message: 'Codex lifecycle executable build identity differs; rebuild the sandbox if the runtime is stale',
315
- action: 'rebuild-sandbox'
316
- });
317
- }
318
- if (actual.lifecycleContractHash !== expected.lifecycleContractHash) {
319
- warnings.push({
320
- code: 'CODEX_LIFECYCLE_CONTRACT_MISMATCH',
321
- message: 'Codex lifecycle contract identity differs; rebuild the sandbox if the runtime is stale',
322
- action: 'rebuild-sandbox'
323
- });
324
- }
325
- return {
326
- ok: true,
327
- code: null,
328
- message: null,
329
- warnings: Object.freeze(warnings)
330
- };
331
- }
332
-
333
- export {
334
- LIFECYCLE_PROTOCOL_VERSION,
335
- computeLifecycleBuildIdentity,
336
- isCanonicalLifecyclePackageVersion,
337
- isLifecycleProtocolVersion,
338
- readLifecycleManifestFiles,
339
- resolveLifecycleExecutableFiles,
340
- verifyLifecycleBuildIdentity
341
- };
342
- export type {
343
- IdentityVerification,
344
- LifecycleIdentityWarning,
345
- LifecycleBuildIdentity,
346
- LifecycleLauncherShebang,
347
- LifecycleManifestFiles,
348
- LifecycleBuildIdentityOptions
349
- };