orizu 0.5.20 → 0.5.21

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 (260) hide show
  1. package/dist/archive-artifacts-cli.d.ts +50 -0
  2. package/dist/archive-artifacts-cli.d.ts.map +1 -0
  3. package/dist/artifact-archive.d.ts +48 -0
  4. package/dist/artifact-archive.d.ts.map +1 -0
  5. package/dist/artifact-pull.d.ts +22 -0
  6. package/dist/artifact-pull.d.ts.map +1 -0
  7. package/dist/banner.d.ts +3 -0
  8. package/dist/banner.d.ts.map +1 -0
  9. package/dist/connectors-cli.d.ts +31 -0
  10. package/dist/connectors-cli.d.ts.map +1 -0
  11. package/dist/credentials.d.ts +46 -0
  12. package/dist/credentials.d.ts.map +1 -0
  13. package/dist/csv.d.ts +49 -0
  14. package/dist/csv.d.ts.map +1 -0
  15. package/dist/dataset-download.d.ts +6 -0
  16. package/dist/dataset-download.d.ts.map +1 -0
  17. package/dist/dataset-edit-rows.d.ts +10 -0
  18. package/dist/dataset-edit-rows.d.ts.map +1 -0
  19. package/dist/dataset-upload-snapshot.d.ts +13 -0
  20. package/dist/dataset-upload-snapshot.d.ts.map +1 -0
  21. package/dist/daytona-slice-rehearsal.d.ts +89 -0
  22. package/dist/daytona-slice-rehearsal.d.ts.map +1 -0
  23. package/dist/daytona-slice.d.ts +106 -0
  24. package/dist/daytona-slice.d.ts.map +1 -0
  25. package/dist/deploy-key-merge-core.d.ts +121 -0
  26. package/dist/deploy-key-merge-core.d.ts.map +1 -0
  27. package/dist/diff-comments-cli.d.ts +12 -0
  28. package/dist/diff-comments-cli.d.ts.map +1 -0
  29. package/dist/diff-comments-cli.js +3 -0
  30. package/dist/egress-allowlist-cli.d.ts +23 -0
  31. package/dist/egress-allowlist-cli.d.ts.map +1 -0
  32. package/dist/egress-policy.d.ts +108 -0
  33. package/dist/egress-policy.d.ts.map +1 -0
  34. package/dist/error-response.d.ts +9 -0
  35. package/dist/error-response.d.ts.map +1 -0
  36. package/dist/file-parser.d.ts +5 -0
  37. package/dist/file-parser.d.ts.map +1 -0
  38. package/dist/gepa-engine-dispatch.d.ts +9 -0
  39. package/dist/gepa-engine-dispatch.d.ts.map +1 -0
  40. package/dist/gepa-engine-dispatch.js +48 -2
  41. package/dist/gepa-python-command.d.ts +6 -0
  42. package/dist/gepa-python-command.d.ts.map +1 -0
  43. package/dist/gepa-python-paths.d.ts +6 -0
  44. package/dist/gepa-python-paths.d.ts.map +1 -0
  45. package/dist/gepa-python-paths.js +6 -3
  46. package/dist/git-credential.d.ts +69 -0
  47. package/dist/git-credential.d.ts.map +1 -0
  48. package/dist/git-recovery-environment.d.ts +31 -0
  49. package/dist/git-recovery-environment.d.ts.map +1 -0
  50. package/dist/github-setup.d.ts +122 -0
  51. package/dist/github-setup.d.ts.map +1 -0
  52. package/dist/global-flags.d.ts +12 -0
  53. package/dist/global-flags.d.ts.map +1 -0
  54. package/dist/help.d.ts +46 -0
  55. package/dist/help.d.ts.map +1 -0
  56. package/dist/help.js +91 -23
  57. package/dist/hosted-boot.d.ts +273 -0
  58. package/dist/hosted-boot.d.ts.map +1 -0
  59. package/dist/hosted-bootstrap-rehearsal.d.ts +86 -0
  60. package/dist/hosted-bootstrap-rehearsal.d.ts.map +1 -0
  61. package/dist/hosted-bootstrap.d.ts +188 -0
  62. package/dist/hosted-bootstrap.d.ts.map +1 -0
  63. package/dist/hosted-broker-server.d.ts +50 -0
  64. package/dist/hosted-broker-server.d.ts.map +1 -0
  65. package/dist/hosted-git-http-server.d.ts +36 -0
  66. package/dist/hosted-git-http-server.d.ts.map +1 -0
  67. package/dist/hosted-harness-claude.d.ts +195 -0
  68. package/dist/hosted-harness-claude.d.ts.map +1 -0
  69. package/dist/hosted-harness-opencode.d.ts +227 -0
  70. package/dist/hosted-harness-opencode.d.ts.map +1 -0
  71. package/dist/hosted-harness.d.ts +118 -0
  72. package/dist/hosted-harness.d.ts.map +1 -0
  73. package/dist/hosted-harvest.d.ts +68 -0
  74. package/dist/hosted-harvest.d.ts.map +1 -0
  75. package/dist/hosted-headless.d.ts +72 -0
  76. package/dist/hosted-headless.d.ts.map +1 -0
  77. package/dist/hosted-loop-lifecycle.d.ts +206 -0
  78. package/dist/hosted-loop-lifecycle.d.ts.map +1 -0
  79. package/dist/hosted-loop.d.ts +170 -0
  80. package/dist/hosted-loop.d.ts.map +1 -0
  81. package/dist/hosted-run-event-sink.d.ts +222 -0
  82. package/dist/hosted-run-event-sink.d.ts.map +1 -0
  83. package/dist/hosted-runtime-assets.d.ts +186 -0
  84. package/dist/hosted-runtime-assets.d.ts.map +1 -0
  85. package/dist/hosted-session-cli.d.ts +258 -0
  86. package/dist/hosted-session-cli.d.ts.map +1 -0
  87. package/dist/hosted-skill-staging.d.ts +73 -0
  88. package/dist/hosted-skill-staging.d.ts.map +1 -0
  89. package/dist/http.d.ts +8 -0
  90. package/dist/http.d.ts.map +1 -0
  91. package/dist/index.d.ts +22 -0
  92. package/dist/index.d.ts.map +1 -0
  93. package/dist/index.js +88 -92
  94. package/dist/instruction-set-gepa-launch.d.ts +3 -0
  95. package/dist/instruction-set-gepa-launch.d.ts.map +1 -0
  96. package/dist/instruction-set-gepa-launch.js +15 -0
  97. package/dist/instruction-set-loader.d.ts +6 -0
  98. package/dist/instruction-set-loader.d.ts.map +1 -0
  99. package/dist/instruction-set-loader.js +59 -0
  100. package/dist/instruction-set-manifest.d.ts +14 -0
  101. package/dist/instruction-set-manifest.d.ts.map +1 -0
  102. package/dist/instruction-set-manifest.js +162 -0
  103. package/dist/instruction-sets-cli.d.ts +40 -0
  104. package/dist/instruction-sets-cli.d.ts.map +1 -0
  105. package/dist/instruction-sets-cli.js +361 -0
  106. package/dist/json-response.d.ts +4 -0
  107. package/dist/json-response.d.ts.map +1 -0
  108. package/dist/jsonl-stream.d.ts +8 -0
  109. package/dist/jsonl-stream.d.ts.map +1 -0
  110. package/dist/kill-switch-cli.d.ts +30 -0
  111. package/dist/kill-switch-cli.d.ts.map +1 -0
  112. package/dist/loopback-serve.d.ts +25 -0
  113. package/dist/loopback-serve.d.ts.map +1 -0
  114. package/dist/manifests-cli.d.ts +22 -0
  115. package/dist/manifests-cli.d.ts.map +1 -0
  116. package/dist/markdown-report-input.d.ts +7 -0
  117. package/dist/markdown-report-input.d.ts.map +1 -0
  118. package/dist/merge-job.d.ts +155 -0
  119. package/dist/merge-job.d.ts.map +1 -0
  120. package/dist/model-configs-cli.d.ts +19 -0
  121. package/dist/model-configs-cli.d.ts.map +1 -0
  122. package/dist/model-configs-cli.js +104 -0
  123. package/dist/optimization-export-cli.d.ts +19 -0
  124. package/dist/optimization-export-cli.d.ts.map +1 -0
  125. package/dist/optimizations-list-cli.d.ts +20 -0
  126. package/dist/optimizations-list-cli.d.ts.map +1 -0
  127. package/dist/optimizations-promote-cli.d.ts +8 -0
  128. package/dist/optimizations-promote-cli.d.ts.map +1 -0
  129. package/dist/optimizations-promote-cli.js +34 -0
  130. package/dist/option-validation.d.ts +15 -0
  131. package/dist/option-validation.d.ts.map +1 -0
  132. package/dist/preview-runtime.d.ts +63 -0
  133. package/dist/preview-runtime.d.ts.map +1 -0
  134. package/dist/prompt-draft-push.d.ts +60 -0
  135. package/dist/prompt-draft-push.d.ts.map +1 -0
  136. package/dist/prompt-label-cli.d.ts +11 -0
  137. package/dist/prompt-label-cli.d.ts.map +1 -0
  138. package/dist/prompt-label-cli.js +29 -0
  139. package/dist/prompt-length-wire.d.ts +28 -0
  140. package/dist/prompt-length-wire.d.ts.map +1 -0
  141. package/dist/prompt-report-cli.d.ts +10 -0
  142. package/dist/prompt-report-cli.d.ts.map +1 -0
  143. package/dist/prompt-summary-table.d.ts +15 -0
  144. package/dist/prompt-summary-table.d.ts.map +1 -0
  145. package/dist/prompt-summary-table.js +6 -0
  146. package/dist/registration-tag-warning.d.ts +32 -0
  147. package/dist/registration-tag-warning.d.ts.map +1 -0
  148. package/dist/report-comments-cli.d.ts +16 -0
  149. package/dist/report-comments-cli.d.ts.map +1 -0
  150. package/dist/report-markdown-blankness.d.ts +2 -0
  151. package/dist/report-markdown-blankness.d.ts.map +1 -0
  152. package/dist/report-replacement-warning.d.ts +17 -0
  153. package/dist/report-replacement-warning.d.ts.map +1 -0
  154. package/dist/repository-backup-core.d.ts +225 -0
  155. package/dist/repository-backup-core.d.ts.map +1 -0
  156. package/dist/repository-recovery-manifest.d.ts +83 -0
  157. package/dist/repository-recovery-manifest.d.ts.map +1 -0
  158. package/dist/run-event-digest.d.ts +74 -0
  159. package/dist/run-event-digest.d.ts.map +1 -0
  160. package/dist/runner-dir-verify.d.ts +66 -0
  161. package/dist/runner-dir-verify.d.ts.map +1 -0
  162. package/dist/runner-instruction-set-contract.d.ts +24 -0
  163. package/dist/runner-instruction-set-contract.d.ts.map +1 -0
  164. package/dist/runner-instruction-set-contract.js +50 -0
  165. package/dist/sandbox-hygiene.d.ts +45 -0
  166. package/dist/sandbox-hygiene.d.ts.map +1 -0
  167. package/dist/sandbox-provider.d.ts +193 -0
  168. package/dist/sandbox-provider.d.ts.map +1 -0
  169. package/dist/scorer-draft-push.d.ts +50 -0
  170. package/dist/scorer-draft-push.d.ts.map +1 -0
  171. package/dist/scorers-cli.d.ts +20 -0
  172. package/dist/scorers-cli.d.ts.map +1 -0
  173. package/dist/scorers-cli.js +22 -0
  174. package/dist/scorers-verify-parity-bridge.d.ts +16 -0
  175. package/dist/scorers-verify-parity-bridge.d.ts.map +1 -0
  176. package/dist/scorers-verify-parity-bridge.js +90 -0
  177. package/dist/scorers-verify-parity.d.ts +81 -0
  178. package/dist/scorers-verify-parity.d.ts.map +1 -0
  179. package/dist/scorers-verify-parity.js +502 -0
  180. package/dist/scores-accept-cli.d.ts +21 -0
  181. package/dist/scores-accept-cli.d.ts.map +1 -0
  182. package/dist/secret-redaction.d.ts +47 -0
  183. package/dist/secret-redaction.d.ts.map +1 -0
  184. package/dist/session-timeline.d.ts +54 -0
  185. package/dist/session-timeline.d.ts.map +1 -0
  186. package/dist/setup-prompt.d.ts +5 -0
  187. package/dist/setup-prompt.d.ts.map +1 -0
  188. package/dist/skill-installer.d.ts +68 -0
  189. package/dist/skill-installer.d.ts.map +1 -0
  190. package/dist/skilled-proposer-launch.d.ts +7 -0
  191. package/dist/skilled-proposer-launch.d.ts.map +1 -0
  192. package/dist/skilled-proposer-launch.js +60 -0
  193. package/dist/smoke.d.ts +102 -0
  194. package/dist/smoke.d.ts.map +1 -0
  195. package/dist/start-intent.d.ts +12 -0
  196. package/dist/start-intent.d.ts.map +1 -0
  197. package/dist/task-assignment-manifest.d.ts +15 -0
  198. package/dist/task-assignment-manifest.d.ts.map +1 -0
  199. package/dist/task-create-error.d.ts +18 -0
  200. package/dist/task-create-error.d.ts.map +1 -0
  201. package/dist/team-connectors-cli.d.ts +29 -0
  202. package/dist/team-connectors-cli.d.ts.map +1 -0
  203. package/dist/types.d.ts +39 -0
  204. package/dist/types.d.ts.map +1 -0
  205. package/dist/vercel-sandbox-provider.d.ts +156 -0
  206. package/dist/vercel-sandbox-provider.d.ts.map +1 -0
  207. package/dist/workbench-cli.d.ts +233 -0
  208. package/dist/workbench-cli.d.ts.map +1 -0
  209. package/dist/workspace-sync.d.ts +207 -0
  210. package/dist/workspace-sync.d.ts.map +1 -0
  211. package/dist/workspace.d.ts +92 -0
  212. package/dist/workspace.d.ts.map +1 -0
  213. package/dist/zip-draft-push.d.ts +55 -0
  214. package/dist/zip-draft-push.d.ts.map +1 -0
  215. package/package.json +14 -1
  216. package/requirements/README.md +138 -0
  217. package/requirements/skilled-proposer.in +66 -0
  218. package/requirements/skilled-proposer.lock +265 -0
  219. package/scripts/ensure-skilled-proposer-venv.mjs +5 -0
  220. package/scripts/refresh-skilled-proposer-lock.mjs +256 -0
  221. package/src/diff-comments-cli.ts +4 -0
  222. package/src/gepa-engine-dispatch.ts +42 -2
  223. package/src/gepa-python-paths.ts +6 -3
  224. package/src/help.ts +93 -23
  225. package/src/index.ts +99 -126
  226. package/src/instruction-set-gepa-launch.ts +28 -0
  227. package/src/instruction-set-loader.ts +37 -0
  228. package/src/instruction-set-manifest.ts +120 -0
  229. package/src/instruction-sets-cli.ts +306 -0
  230. package/src/model-configs-cli.ts +119 -0
  231. package/src/optimizations-promote-cli.ts +41 -0
  232. package/src/prompt-label-cli.ts +55 -0
  233. package/src/prompt-summary-table.ts +12 -0
  234. package/src/runner-instruction-set-contract.ts +64 -0
  235. package/src/scorers-cli.ts +40 -0
  236. package/src/scorers-verify-parity-bridge.ts +90 -0
  237. package/src/scorers-verify-parity.ts +564 -0
  238. package/src/skilled-proposer-launch.ts +89 -0
  239. package/src/skilled-proposer-venv-manager.mjs +757 -0
  240. package/tsconfig.json +2 -0
  241. package/vendor/orizu-gepa/src/orizu_gepa_connector/__init__.py +2 -1
  242. package/vendor/orizu-gepa/src/orizu_gepa_connector/adapter.py +8 -2
  243. package/vendor/orizu-gepa/src/orizu_gepa_connector/callbacks.py +17 -3
  244. package/vendor/orizu-gepa/src/orizu_gepa_connector/engine.py +100 -8
  245. package/vendor/orizu-gepa/src/orizu_gepa_connector/instruction_set_loader.py +52 -0
  246. package/vendor/orizu-gepa/src/orizu_gepa_connector/reflection.py +92 -12
  247. package/vendor/orizu-gepa/src/orizu_gepa_connector/runtime.py +100 -22
  248. package/vendor/orizu-gepa/src/orizu_gepa_connector/skilled_proposer_bridge.py +381 -0
  249. package/vendor/orizu-gepa/src/orizu_gepa_connector/stop_conditions.py +17 -0
  250. package/vendor/orizu-gepa/src/orizu_gepa_connector/translator.py +2 -1
  251. package/vendor/orizu-gepa-python/src/orizu_gepa/client.py +52 -7
  252. package/vendor/orizu-gepa-python/src/orizu_gepa/local_log.py +4 -1
  253. package/vendor/orizu-gepa-python/src/orizu_gepa/optimizer.py +10 -5
  254. package/vendor/orizu-gepa-python/src/orizu_gepa/reflection.py +323 -68
  255. package/vendor/orizu-gepa-python/src/orizu_gepa/runner.py +207 -13
  256. package/vendor/skills/orizu-cli/SKILL.md +2 -0
  257. package/vendor/skills/orizu-cli/references/cli-reference.md +85 -1
  258. package/vendor/skills/orizu-cli/references/migrate-existing-gepa-setup.md +303 -0
  259. package/vendor/skills/orizu-cli/references/optimization-with-gepa.md +25 -0
  260. package/vendor/skills/orizu-cli/references/prompt-control-plane.md +108 -8
@@ -0,0 +1,361 @@
1
+ import { authedFetch } from './http.js';
2
+ import { loadInstructionSetManifest, MAX_INSTRUCTION_SET_COMPONENT_BYTES } from './instruction-set-manifest.js';
3
+ import { sanitizeHumanInlineText, sanitizeTerminalText } from './json-response.js';
4
+ import { existsSync, mkdirSync, readFileSync, renameSync, rmSync, statSync, writeFileSync } from 'node:fs';
5
+ import { join } from 'node:path';
6
+ import { createHash, randomUUID } from 'node:crypto';
7
+ function positionalArgs(args) {
8
+ const values = [];
9
+ for (let index = 0; index < args.length; index += 1) {
10
+ const value = args[index];
11
+ if (value.startsWith('--')) {
12
+ if (argValue(args, value) !== null)
13
+ index += 1;
14
+ continue;
15
+ }
16
+ values.push(value);
17
+ }
18
+ return values;
19
+ }
20
+ function argValue(args, flag) {
21
+ const index = args.indexOf(flag);
22
+ return index === -1 || !args[index + 1] || args[index + 1].startsWith('--')
23
+ ? null
24
+ : args[index + 1];
25
+ }
26
+ async function responsePayload(response, action) {
27
+ const payload = await response.json().catch(() => ({}));
28
+ if (!response.ok) {
29
+ throw new Error(`${action} failed (${response.status}): ${typeof payload.error === 'string' ? payload.error : response.statusText}`);
30
+ }
31
+ return payload;
32
+ }
33
+ const SAFE_SEGMENT = /^[A-Za-z0-9._-]+$/u;
34
+ function safeSegment(value) { if (!SAFE_SEGMENT.test(value) || value === '.' || value === '..' || value.startsWith('.'))
35
+ throw new Error('instruction_set_path_unsafe'); }
36
+ function slug(identity) { return identity.replaceAll('/', '__').replace(/[^A-Za-z0-9._-]/gu, '_'); }
37
+ function stable(value) { return `${JSON.stringify(value, null, 2)}\n`; }
38
+ function sha256(value) { return createHash('sha256').update(value, 'utf8').digest('hex'); }
39
+ function writeMaterial(root, material, shape, manifestRoot, fileOps = { writeFileSync }) {
40
+ const files = {};
41
+ const syncedContentSha256 = {};
42
+ const pinnedComponents = {};
43
+ for (const key of [...shape].sort()) {
44
+ safeSegment(key);
45
+ const component = material.components[key];
46
+ if (typeof component?.body === 'string') {
47
+ const relative = `${manifestRoot}/${key}.md`;
48
+ files[key] = relative;
49
+ const target = join(root, ...relative.split('/'));
50
+ mkdirSync(join(target, '..'), { recursive: true });
51
+ fileOps.writeFileSync(target, component.body);
52
+ syncedContentSha256[key] = sha256(component.body);
53
+ }
54
+ else if (component?.repoPath && component?.contentSha && component?.commitSha)
55
+ pinnedComponents[key] = { repoPath: component.repoPath, contentSha: component.contentSha, commitSha: component.commitSha };
56
+ else
57
+ throw new Error('instruction_set_unresolvable');
58
+ }
59
+ return { profileVersionId: material.profileVersionId, versionNumber: material.versionNumber, modelConfigIdentity: material.modelConfigIdentity, resolvedFrom: material.resolvedFrom, files, syncedContentSha256, ...(Object.keys(pinnedComponents).length ? { pinnedComponents } : {}) };
60
+ }
61
+ // Only the scratch paths THIS run created are ever removed; a user's own
62
+ // `.<set>.*.bak` in --out is never touched (PR #1668 review).
63
+ function removeOwnScratch(paths) {
64
+ for (const path of paths)
65
+ if (path && existsSync(path))
66
+ rmSync(path, { recursive: true, force: true });
67
+ }
68
+ function existingDestinationIsSynced(destination, name) {
69
+ try {
70
+ if (!statSync(destination).isDirectory())
71
+ return false;
72
+ const manifest = JSON.parse(readFileSync(join(destination, 'manifest.json'), 'utf8'));
73
+ return manifest.manifestVersion === 1 && manifest.name === name;
74
+ }
75
+ catch {
76
+ return false;
77
+ }
78
+ }
79
+ export function syncToDisk(out, set, fileOps = { writeFileSync }) {
80
+ safeSegment(set.name);
81
+ for (const key of set.shape)
82
+ safeSegment(key);
83
+ const profileSlugs = new Set();
84
+ for (const profile of set.profiles) {
85
+ const value = slug(profile.modelConfigIdentity);
86
+ safeSegment(value);
87
+ if (profileSlugs.has(value))
88
+ throw new Error('instruction_set_slug_collision');
89
+ profileSlugs.add(value);
90
+ }
91
+ mkdirSync(out, { recursive: true });
92
+ const destination = join(out, set.name);
93
+ if (existsSync(destination) && !existingDestinationIsSynced(destination, set.name))
94
+ throw new Error('instruction_set_sync_destination_not_synced');
95
+ const temp = join(out, `.${set.name}.${randomUUID()}.tmp`);
96
+ const move = fileOps.renameSync || renameSync;
97
+ let backup = null;
98
+ mkdirSync(temp);
99
+ try {
100
+ const defaultMaterial = writeMaterial(temp, set.default, set.shape, 'default', fileOps);
101
+ const profiles = set.profiles.map(profile => ({
102
+ modelConfigIdentity: profile.modelConfigIdentity, slug: slug(profile.modelConfigIdentity), resolvedFrom: profile.resolvedFrom,
103
+ production: profile.production ? writeMaterial(temp, profile.production, set.shape, `profiles/${slug(profile.modelConfigIdentity)}`, fileOps) : null,
104
+ })).sort((a, b) => a.modelConfigIdentity.localeCompare(b.modelConfigIdentity));
105
+ const components = [
106
+ ...Object.entries(defaultMaterial.files).map(([key, path]) => ({ key, path, syncedContentSha256: defaultMaterial.syncedContentSha256[key] })),
107
+ ...profiles.flatMap(profile => profile.production
108
+ ? Object.entries(profile.production.files).map(([key, path]) => ({ key, modelConfig: profile.modelConfigIdentity, path, syncedContentSha256: profile.production.syncedContentSha256[key] }))
109
+ : []),
110
+ ];
111
+ const manifest = { manifestVersion: 1, name: set.name, ...(Object.hasOwn(set, 'description') ? { description: set.description ?? null } : {}), shape: set.shape, components, default: defaultMaterial, profiles, ...(set.filteredTo ? { filteredTo: [...set.filteredTo].sort() } : {}) };
112
+ fileOps.writeFileSync(join(temp, 'manifest.json'), stable(manifest));
113
+ backup = join(out, `.${set.name}.${randomUUID()}.bak`);
114
+ if (existsSync(destination))
115
+ move(destination, backup);
116
+ try {
117
+ move(temp, destination);
118
+ }
119
+ catch (error) {
120
+ if (existsSync(backup))
121
+ move(backup, destination);
122
+ throw error;
123
+ }
124
+ removeOwnScratch([backup]);
125
+ }
126
+ catch (error) {
127
+ removeOwnScratch([temp]);
128
+ if (backup && existsSync(backup) && !existsSync(destination))
129
+ move(backup, destination);
130
+ removeOwnScratch([backup]);
131
+ throw error;
132
+ }
133
+ }
134
+ export async function instructionSetsCommand(args, io) {
135
+ const positionals = positionalArgs(args);
136
+ const [subcommand, reference] = positionals;
137
+ if (subcommand === 'default' && reference === 'move') {
138
+ const version = argValue(args, '--version');
139
+ if (!version || !/^[0-9]+$/u.test(version) || Number(version) < 1)
140
+ throw new Error('--version must be a positive integer');
141
+ }
142
+ let writeManifest;
143
+ if (subcommand === 'create' || subcommand === 'push') {
144
+ if (!reference || reference.startsWith('--'))
145
+ throw new Error(subcommand === 'create'
146
+ ? 'Usage: orizu instructions create <manifest> --project <team/project> [--runner-version <id>] [--model-config <identity>] [--json]'
147
+ : 'Usage: orizu instructions push <manifest> --project <team/project> [--set <slug-or-exact-name>] [--runner-version <id>] [--json]');
148
+ writeManifest = loadInstructionSetManifest(reference);
149
+ }
150
+ const project = await io.resolveProjectSlug(argValue(args, '--project'));
151
+ if (subcommand === 'default') {
152
+ const operation = reference;
153
+ const set = positionals[2];
154
+ const identity = argValue(args, '--model-config');
155
+ const version = argValue(args, '--version');
156
+ if ((operation !== 'show' && operation !== 'move') || !set)
157
+ throw new Error('Usage: orizu instructions default show|move <set> --project <team/project> [--model-config <identity> --version <n>] [--json]');
158
+ if (operation === 'move' && (!identity || !version || !/^[0-9]+$/u.test(version) || Number(version) < 1))
159
+ throw new Error('--version must be a positive integer');
160
+ const path = `/api/cli/instruction-sets/${encodeURIComponent(set)}/default?project=${encodeURIComponent(project)}`;
161
+ if (operation === 'show') {
162
+ const payload = await responsePayload(await authedFetch(path, { method: 'GET' }), 'Instruction sets default show');
163
+ if (io.json)
164
+ io.print(JSON.stringify(payload));
165
+ else
166
+ io.print(`Default: v${payload.default?.versionNumber ?? '?'}`);
167
+ return 0;
168
+ }
169
+ if (!io.json) {
170
+ const impact = await responsePayload(await authedFetch(path, { method: 'GET' }), 'Instruction sets default show');
171
+ const resolvesToDefault = Array.isArray(impact.resolvesToDefault) ? impact.resolvesToDefault.filter((item) => typeof item === 'string') : [];
172
+ io.print(`These model configs resolve to the default: ${resolvesToDefault.join(', ')}`);
173
+ }
174
+ const payload = await responsePayload(await authedFetch(path, { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ modelConfigIdentity: identity, versionNumber: Number(version) }) }), 'Instruction sets default move');
175
+ if (io.json)
176
+ io.print(JSON.stringify(payload));
177
+ else
178
+ io.print(`Default moved to ${identity} v${version}`);
179
+ return 0;
180
+ }
181
+ if (subcommand === 'shape') {
182
+ const operation = reference;
183
+ const set = positionals[2];
184
+ const key = argValue(args, '--key');
185
+ const from = argValue(args, '--from');
186
+ if ((operation !== 'add' && operation !== 'remove') || !set || !key || (operation === 'add' && !from))
187
+ throw new Error('Usage: orizu instructions shape add|remove <set> --project <team/project> --key <key> [--from <manifest>] [--json]');
188
+ let component;
189
+ if (operation === 'add') {
190
+ let manifest;
191
+ try {
192
+ manifest = JSON.parse(readFileSync(from, 'utf8'));
193
+ }
194
+ catch {
195
+ throw new Error('instruction_set_manifest_invalid_json');
196
+ }
197
+ const source = manifest && typeof manifest === 'object' && Array.isArray(manifest.components)
198
+ ? manifest.components.find((item) => Boolean(item && typeof item === 'object' && item.key === key))
199
+ : undefined;
200
+ if (!source || typeof source.text !== 'string' || Buffer.byteLength(source.text, 'utf8') > MAX_INSTRUCTION_SET_COMPONENT_BYTES)
201
+ throw new Error(`Instruction set manifest has no component for key: ${key}`);
202
+ component = { body: source.text };
203
+ }
204
+ const payload = await responsePayload(await authedFetch(`/api/cli/instruction-sets/${encodeURIComponent(set)}/shape?project=${encodeURIComponent(project)}`, { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ operation, key, ...(component ? { component } : {}) }) }), `Instruction sets shape ${operation}`);
205
+ if (io.json)
206
+ io.print(JSON.stringify(payload));
207
+ else {
208
+ io.print(`Shape ${operation === 'add' ? 'added' : 'removed'}: ${key}`);
209
+ const affected = Array.isArray(payload.affected) ? payload.affected : [];
210
+ const identities = [...new Set(affected.flatMap(pointer => pointer && typeof pointer === 'object' && typeof pointer.modelConfigIdentity === 'string' ? [pointer.modelConfigIdentity] : []))];
211
+ if (identities.length)
212
+ io.print(`${set} does not resolve for these model configs until the pointers move: ${identities.join(', ')}`);
213
+ for (const pointer of affected)
214
+ if (pointer && typeof pointer === 'object') {
215
+ const item = pointer;
216
+ if (typeof item.modelConfigIdentity === 'string' && (item.pointer === 'production' || item.pointer === 'default') && typeof item.headVersionNumber === 'number') {
217
+ const command = item.pointer === 'production' ? 'profiles promote' : 'default move';
218
+ const operatorAction = item.pointer === 'production' ? 'promote' : 'default move';
219
+ if (typeof item.stalePointerVersionNumber === 'number' && typeof item.branchedFromVersionNumber === 'number' && item.branchedFromVersionNumber !== item.stalePointerVersionNumber)
220
+ io.print(`${operatorAction} would move ${item.pointer} from v${item.stalePointerVersionNumber}'s text to v${item.headVersionNumber} = v${item.branchedFromVersionNumber}'s text + ${key}`);
221
+ io.print(`Follow up: instructions ${command} ${set} --project ${project} --model-config ${item.modelConfigIdentity} --version ${item.headVersionNumber}`);
222
+ }
223
+ }
224
+ }
225
+ return 0;
226
+ }
227
+ if (subcommand === 'profiles') {
228
+ const operation = reference;
229
+ const set = positionals[2];
230
+ const identity = argValue(args, '--model-config');
231
+ if ((operation !== 'new' && operation !== 'promote' && operation !== 'rollback') || !set || !identity)
232
+ throw new Error('Usage: orizu instructions profiles new|promote|rollback <set> --project <team/project> --model-config <identity> [--version <n>|--to <n>] [--json]');
233
+ const encodedSet = encodeURIComponent(set);
234
+ const encodedIdentity = encodeURIComponent(identity);
235
+ const version = argValue(args, '--version');
236
+ const to = argValue(args, '--to');
237
+ if ((operation === 'promote' && (!version || !/^[0-9]+$/u.test(version) || Number(version) < 1)) || (operation === 'rollback' && (!to || !/^[0-9]+$/u.test(to) || Number(to) < 1)))
238
+ throw new Error(operation === 'promote' ? '--version must be a positive integer' : '--to must be a positive integer');
239
+ const path = operation === 'new' ? `/api/cli/instruction-sets/${encodedSet}/profiles` : operation === 'promote' ? `/api/cli/instruction-sets/${encodedSet}/profiles/${encodedIdentity}/label` : `/api/cli/instruction-sets/${encodedSet}/profiles/${encodedIdentity}/rollback`;
240
+ const body = operation === 'new' ? { modelConfigIdentity: identity } : operation === 'promote' ? { versionNumber: Number(version) } : { to: Number(to) };
241
+ const payload = await responsePayload(await authedFetch(`${path}?project=${encodeURIComponent(project)}`, { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify(body) }), `Instruction sets profiles ${operation}`);
242
+ if (io.json)
243
+ io.print(JSON.stringify(payload));
244
+ else {
245
+ const profile = payload.profile;
246
+ io.print(`${profile?.modelConfigIdentity || identity}: v${profile?.versionNumber ?? '?'} ${operation === 'new' ? 'created' : operation === 'promote' ? 'promoted' : 'rolled back'}`);
247
+ const mirrored = payload.mirroredPromptLabel;
248
+ if (mirrored && (typeof mirrored.promptName === 'string' || typeof mirrored.promptId === 'string'))
249
+ io.print(`also moved production for prompt ${typeof mirrored.promptName === 'string' ? mirrored.promptName : mirrored.promptId} (default profile → prompt label)`);
250
+ }
251
+ return 0;
252
+ }
253
+ if (subcommand === 'create' || subcommand === 'push') {
254
+ const manifest = writeManifest;
255
+ const modelConfig = argValue(args, '--model-config');
256
+ const runnerVersion = argValue(args, '--runner-version');
257
+ const setReference = argValue(args, '--set') || manifest.name;
258
+ const path = subcommand === 'create' ? '/api/cli/instruction-sets' : `/api/cli/instruction-sets/${encodeURIComponent(setReference)}/versions`;
259
+ const body = subcommand === 'create'
260
+ ? { ...manifest, ...(modelConfig ? { modelConfigIdentity: modelConfig } : {}), ...(runnerVersion ? { runnerVersionId: runnerVersion } : {}) }
261
+ : { shape: manifest.shape, components: manifest.components, ...(Object.hasOwn(manifest, 'description') ? { description: manifest.description } : {}), ...(runnerVersion ? { runnerVersionId: runnerVersion } : {}) };
262
+ const payload = await responsePayload(await authedFetch(`${path}?project=${encodeURIComponent(project)}`, { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify(body) }), `Instruction sets ${subcommand}`);
263
+ if (io.json)
264
+ io.print(JSON.stringify(payload));
265
+ else {
266
+ const set = payload.instructionSet;
267
+ const pushed = Array.isArray(payload.pushed) ? payload.pushed : [];
268
+ const unchanged = Array.isArray(payload.unchanged) ? payload.unchanged : [];
269
+ const skipped = Array.isArray(payload.skipped) ? payload.skipped : [];
270
+ if (subcommand === 'create') {
271
+ const profiles = Array.isArray(set?.profiles) ? set.profiles : [];
272
+ io.print(`${set?.name || manifest.name}: ${profiles.length} profile(s) created`);
273
+ }
274
+ else {
275
+ const describe = (value) => {
276
+ if (typeof value === 'string')
277
+ return value;
278
+ if (value && typeof value === 'object') {
279
+ const row = value;
280
+ return `${typeof row.modelConfigIdentity === 'string' ? row.modelConfigIdentity : 'unknown'}${typeof row.versionNumber === 'number' ? ` v${row.versionNumber}` : ''}`;
281
+ }
282
+ return 'unknown';
283
+ };
284
+ io.print(`${set?.name || manifest.name}: pushed ${pushed.map(describe).join(', ') || 'none'}; unchanged ${unchanged.map(describe).join(', ') || 'none'}; skipped ${skipped.map(describe).join(', ') || 'none'}`);
285
+ }
286
+ }
287
+ return 0;
288
+ }
289
+ if (subcommand === 'archive' || subcommand === 'restore') {
290
+ if (!reference || reference.startsWith('--'))
291
+ throw new Error(`Usage: orizu instructions ${subcommand} <slug-or-exact-name> --project <team/project> [--json]`);
292
+ const archived = subcommand === 'archive';
293
+ const payload = await responsePayload(await authedFetch(`/api/cli/instruction-sets/${encodeURIComponent(reference)}?project=${encodeURIComponent(project)}`, {
294
+ method: 'PATCH',
295
+ headers: { 'content-type': 'application/json' },
296
+ body: JSON.stringify({ archived }),
297
+ }), `Instructions ${subcommand}`);
298
+ if (io.json)
299
+ io.print(JSON.stringify(payload));
300
+ else {
301
+ const set = payload.instructionSet;
302
+ const identity = set?.slug && set.slug !== set.name ? `${set.name || reference} (${set.slug})` : set?.name || set?.slug || reference;
303
+ io.print(`${archived ? 'Archived' : 'Restored'} instruction set ${identity}`);
304
+ }
305
+ return 0;
306
+ }
307
+ const status = argValue(args, '--status') || 'active';
308
+ if (subcommand !== 'list' && subcommand !== 'show' && subcommand !== 'sync')
309
+ throw new Error('Usage: orizu instructions list|show|sync|archive|restore');
310
+ if (subcommand === 'sync') {
311
+ const output = argValue(args, '--out');
312
+ if (!reference || !output)
313
+ throw new Error('Usage: orizu instructions sync <set> --out <dir> --project <team/project> [--model-config <identity>] [--json]');
314
+ const modelConfig = argValue(args, '--model-config');
315
+ const path = `/api/cli/instruction-sets/${encodeURIComponent(reference)}/sync?project=${encodeURIComponent(project)}${modelConfig ? `&modelConfig=${encodeURIComponent(modelConfig)}` : ''}`;
316
+ const payload = await responsePayload(await authedFetch(path, { method: 'GET' }), 'Instruction sets sync');
317
+ const set = payload.instructionSet;
318
+ if (!set || (set.slug !== reference && set.name !== reference) || (modelConfig && (!Array.isArray(set.filteredTo) || set.filteredTo.length !== 1 || set.filteredTo[0] !== modelConfig))) {
319
+ throw new Error('instruction_set_sync_response_mismatch');
320
+ }
321
+ syncToDisk(output, set);
322
+ if (io.json)
323
+ io.print(JSON.stringify(payload));
324
+ else
325
+ io.print(`Synced ${set.name} to ${join(output, set.name)}`);
326
+ return 0;
327
+ }
328
+ if (subcommand === 'show' && (!reference || reference.startsWith('--')))
329
+ throw new Error('Instruction set name is required');
330
+ if (status !== 'active' && status !== 'archived' && status !== 'all')
331
+ throw new Error('--status must be active, archived, or all');
332
+ const query = `project=${encodeURIComponent(project)}&status=${encodeURIComponent(status)}`;
333
+ const path = subcommand === 'list'
334
+ ? `/api/cli/instruction-sets?${query}`
335
+ : `/api/cli/instruction-sets/${encodeURIComponent(reference)}?${query}`;
336
+ const payload = await responsePayload(await authedFetch(path, { method: 'GET' }), `Instruction sets ${subcommand}`);
337
+ if (io.json) {
338
+ io.print(JSON.stringify(payload));
339
+ return 0;
340
+ }
341
+ if (subcommand === 'list') {
342
+ const sets = Array.isArray(payload.instructionSets) ? payload.instructionSets : [];
343
+ for (const item of sets) {
344
+ const set = item;
345
+ io.print(`${set.name || 'unnamed'}${set.slug ? ` [${set.slug}]` : ''}${set.status === 'archived' ? ' [archived]' : ''}${set.shape ? ` (${set.shape.join(', ')})` : ''}`);
346
+ if (set.description)
347
+ io.print(` ${sanitizeHumanInlineText(sanitizeTerminalText, set.description)}`);
348
+ }
349
+ return 0;
350
+ }
351
+ const set = payload.instructionSet;
352
+ io.print(`${set?.name || reference}${set?.status === 'archived' ? ' [archived]' : ''}: ${set?.shape?.join(', ') || ''}`);
353
+ if (set?.description)
354
+ io.print(`Description: ${sanitizeHumanInlineText(sanitizeTerminalText, set.description)}`);
355
+ if (set?.default)
356
+ io.print(`Default: v${set.default.versionNumber ?? '?'}`);
357
+ for (const profile of set?.profiles || []) {
358
+ io.print(`${profile.modelConfigIdentity || 'unspecified'}: production ${profile.production ? `v${profile.production.versionNumber}` : '—'}, latest ${profile.latestVersionNumber ?? '—'}`);
359
+ }
360
+ return 0;
361
+ }
@@ -0,0 +1,4 @@
1
+ export declare function sanitizeTerminalText(value: unknown): string;
2
+ export declare function sanitizeHumanInlineText(sanitizer: (value: unknown) => string, value: unknown): string;
3
+ export declare function parseJsonResponse<T>(response: Response, context: string): Promise<T>;
4
+ //# sourceMappingURL=json-response.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"json-response.d.ts","sourceRoot":"","sources":["../src/json-response.ts"],"names":[],"mappings":"AAAA,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAK3D;AAED,wBAAgB,uBAAuB,CACrC,SAAS,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,MAAM,EACrC,KAAK,EAAE,OAAO,GACb,MAAM,CAER;AAED,wBAAsB,iBAAiB,CAAC,CAAC,EACvC,QAAQ,EAAE,QAAQ,EAClB,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,CAAC,CAAC,CAmBZ"}
@@ -0,0 +1,8 @@
1
+ export declare const JSONL_UPLOAD_CHUNK_MAX_BYTES: number;
2
+ interface JsonlChunkOptions {
3
+ maxPayloadBytes?: number;
4
+ }
5
+ export declare function estimateRowsPayloadByteLength(rows: Array<Record<string, unknown>>): number;
6
+ export declare function streamJsonlRowChunks(filePath: string, options?: JsonlChunkOptions): AsyncGenerator<Array<Record<string, unknown>>>;
7
+ export {};
8
+ //# sourceMappingURL=jsonl-stream.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jsonl-stream.d.ts","sourceRoot":"","sources":["../src/jsonl-stream.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,4BAA4B,QAAkB,CAAA;AAE3D,UAAU,iBAAiB;IACzB,eAAe,CAAC,EAAE,MAAM,CAAA;CACzB;AA2CD,wBAAgB,6BAA6B,CAAC,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAAG,MAAM,CAM1F;AAED,wBAAuB,oBAAoB,CACzC,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,iBAAsB,GAC9B,cAAc,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,CAqEhD"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Per-team agent kill switch CLI (ALI-1007 / G6):
3
+ * orizu team kill-agents <team> [--reason <text>]
4
+ * orizu team release-agents <team>
5
+ *
6
+ * `kill-agents` ENGAGES the switch — ends every active session of the team and
7
+ * revokes its agent tokens "in seconds"; `release-agents` re-enables minting
8
+ * (killed sessions stay ended). Human ADMIN only: the server rejects agent
9
+ * bearers and non-admins. Pure command logic with an injected fetcher so the
10
+ * entry point owns argument parsing and human/JSON output.
11
+ *
12
+ * Containment (ALI-1166): the guarantee is session-end + per-request
13
+ * verification + token-row revocation at engage — a bearer bound to an ended
14
+ * session can never verify again, and ended sessions are terminal
15
+ * (DB-enforced; no post-kill resurrection).
16
+ * `tokensRevoked` in the summary counts the persisted agent token rows the
17
+ * engage revoked (trigger cascade + belt, one transaction); it may include
18
+ * expired or already-ended-session stragglers that were never live bearers at
19
+ * kill time. `--json` output is the server's summary passed through, including
20
+ * `containment: "session-end"`.
21
+ */
22
+ export type CliFetcher = (path: string, init?: RequestInit) => Promise<Response>;
23
+ export interface KillSwitchCommandIo {
24
+ json: boolean;
25
+ print: (line: string) => void;
26
+ printErr?: (line: string) => void;
27
+ fetcher?: CliFetcher;
28
+ }
29
+ export declare function killSwitchCommand(args: string[], io: KillSwitchCommandIo): Promise<number>;
30
+ //# sourceMappingURL=kill-switch-cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kill-switch-cli.d.ts","sourceRoot":"","sources":["../src/kill-switch-cli.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAIH,MAAM,MAAM,UAAU,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAA;AAEhF,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,OAAO,CAAA;IACb,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;IAC7B,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;IACjC,OAAO,CAAC,EAAE,UAAU,CAAA;CACrB;AA8CD,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,mBAAmB,GAAG,OAAO,CAAC,MAAM,CAAC,CA6ChG"}
@@ -0,0 +1,25 @@
1
+ export interface LoopbackServer {
2
+ port: number;
3
+ stop: (force?: boolean) => void;
4
+ }
5
+ interface LoopbackServeOptions {
6
+ port: number;
7
+ hostname: '127.0.0.1';
8
+ fetch: (request: Request) => Promise<Response> | Response;
9
+ }
10
+ export interface LoopbackServeRuntime {
11
+ serve: (options: LoopbackServeOptions) => {
12
+ port?: number;
13
+ stop: (force?: boolean) => void;
14
+ };
15
+ }
16
+ /**
17
+ * Bind a separate-process test server to loopback.
18
+ *
19
+ * The full parallel suite exposed intermittent Bun `port: 0` startup failures,
20
+ * so these fixtures use explicit high-port candidates. `serve()` still performs
21
+ * the atomic bind; a collision retries only when Bun reports `EADDRINUSE`.
22
+ */
23
+ export declare function serveOnLoopback(runtime: LoopbackServeRuntime, requestedPort: number | undefined, fetch: (request: Request) => Promise<Response> | Response, serverName: string): LoopbackServer;
24
+ export {};
25
+ //# sourceMappingURL=loopback-serve.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loopback-serve.d.ts","sourceRoot":"","sources":["../src/loopback-serve.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,CAAC,KAAK,CAAC,EAAE,OAAO,KAAK,IAAI,CAAA;CAChC;AAED,UAAU,oBAAoB;IAC5B,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,WAAW,CAAA;IACrB,KAAK,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC,GAAG,QAAQ,CAAA;CAC1D;AAED,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,CAAC,OAAO,EAAE,oBAAoB,KAAK;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,CAAC,KAAK,CAAC,EAAE,OAAO,KAAK,IAAI,CAAA;KAAE,CAAA;CAC7F;AAgBD;;;;;;GAMG;AACH,wBAAgB,eAAe,CAC7B,OAAO,EAAE,oBAAoB,EAC7B,aAAa,EAAE,MAAM,GAAG,SAAS,EACjC,KAAK,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC,GAAG,QAAQ,EACzD,UAAU,EAAE,MAAM,GACjB,cAAc,CAahB"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Promotion manifests CLI (ALI-907): list | show | approve | reject | apply.
3
+ * Pure command logic with an injected fetcher and project resolver; the entry
4
+ * point owns argument parsing and human/JSON output. apply is idempotent on the
5
+ * server — re-applying returns the stored outcome.
6
+ *
7
+ * Every id-taking subcommand accepts a short-id PREFIX (ALI-1038/ALI-1092): a
8
+ * leading hex slice of the manifest UUID is resolved CLI-side against the
9
+ * project's manifest list — unique match wins, none/ambiguous is a clear error,
10
+ * never a server 500.
11
+ */
12
+ export type CliFetcher = (path: string, init?: RequestInit) => Promise<Response>;
13
+ export interface ManifestsCommandIo {
14
+ json: boolean;
15
+ print: (line: string) => void;
16
+ fetcher?: CliFetcher;
17
+ resolveProjectSlug?: (arg: string | null) => Promise<string>;
18
+ /** Injectable sleeper for the apply auto-retry loop (tests). */
19
+ sleep?: (ms: number) => Promise<void>;
20
+ }
21
+ export declare function manifestsCommand(args: string[], io: ManifestsCommandIo): Promise<number>;
22
+ //# sourceMappingURL=manifests-cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manifests-cli.d.ts","sourceRoot":"","sources":["../src/manifests-cli.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH,MAAM,MAAM,UAAU,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAA;AAEhF,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,OAAO,CAAA;IACb,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;IAC7B,OAAO,CAAC,EAAE,UAAU,CAAA;IACpB,kBAAkB,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,KAAK,OAAO,CAAC,MAAM,CAAC,CAAA;IAC5D,gEAAgE;IAChE,KAAK,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;CACtC;AA0PD,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,kBAAkB,GAAG,OAAO,CAAC,MAAM,CAAC,CAkG9F"}
@@ -0,0 +1,7 @@
1
+ export declare const MARKDOWN_REPORT_MAX_BYTES: number;
2
+ export interface MarkdownReportInput {
3
+ markdown: string;
4
+ sourceName: string | null;
5
+ }
6
+ export declare function readMarkdownReportInput(args: readonly string[], reportLabel: 'Optimization' | 'Prompt' | 'Task'): MarkdownReportInput | null;
7
+ //# sourceMappingURL=markdown-report-input.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"markdown-report-input.d.ts","sourceRoot":"","sources":["../src/markdown-report-input.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,yBAAyB,QAAkB,CAAA;AAsCxD,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,MAAM,CAAA;IAChB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;CAC1B;AAED,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,WAAW,EAAE,cAAc,GAAG,QAAQ,GAAG,MAAM,GAC9C,mBAAmB,GAAG,IAAI,CA8C5B"}
@@ -0,0 +1,155 @@
1
+ /**
2
+ * `orizu internal merge-job` — the one-shot merge sandbox ENTRYPOINT
3
+ * (ALI-1084, merge-sandbox-job Phase 2). The MergeJobCoordinator DO launches
4
+ * this inside a minimal, AGENT-FREE sandbox booted from the hosted snapshot;
5
+ * from here the sandbox pulls its own credentials under the established
6
+ * boot-secret PULL model and runs the SHARED merge core
7
+ * (deploy-key-merge-core.ts — the exact code the server path runs; no forked
8
+ * merge logic).
9
+ *
10
+ * FLOW (plan §2.2 step 4):
11
+ * a. exchange ORIZU_BOOT_SECRET at the DO for a single-use JOB TOKEN
12
+ * (`GET {coordinator}/merge-jobs/:jobKey/job-token`) — the token transits
13
+ * Cloudflare; the DEPLOY KEY never does;
14
+ * b. pull `{spec, privateKeyPem}` DIRECTLY from the control plane
15
+ * (`GET {orizu}/api/coordinator/merge-jobs/:jobId/payload`, job-token
16
+ * auth) — single-use, audited server-side before the key is returned;
17
+ * c. run the shared merge core (tmp worktree, 0600 key file, pinned GitHub
18
+ * host keys, expected-head verification, argv-asserted --no-ff merge)
19
+ * with the D8 PRE-PUSH GATE wired in: immediately before `git push` the
20
+ * core calls `GET .../gate`; `proceed: false` aborts WITHOUT pushing
21
+ * (terminal `superseded`). An UNREACHABLE gate also refuses the push
22
+ * (fail closed) but reports `failed` (retryable) — "unknown" is not
23
+ * "rejected";
24
+ * d. POST the terminal result to the DO (boot-secret auth). Reporting the
25
+ * terminal state — not the merge outcome — is this command's success:
26
+ * exit 0 on ANY reported terminal (conflict/superseded included), exit 1
27
+ * only when the env is invalid or the report itself failed.
28
+ *
29
+ * FROZEN ENV CONTRACT (the DO's merge-job sandbox env plan):
30
+ * ORIZU_BOOT_SECRET per-sandbox durable bootstrap secret;
31
+ * ORIZU_MERGE_JOB_ID the job's DO addressing key
32
+ * (`merge:<manifestId>:<expectedHeadSha>` — the
33
+ * control-plane job uuid rides the token response);
34
+ * ORIZU_COORDINATOR_URL the coordinator Worker origin;
35
+ * ORIZU_BASE_URL the Orizu control-plane origin.
36
+ *
37
+ * REDACTION: every reported detail passes through `redactSecrets` with the
38
+ * boot secret, the job token, and the private key PEM on the exact-match list
39
+ * (plus the shape-pattern net). Nothing here ever logs a secret.
40
+ */
41
+ import { type DeployKeyMergeResult, type GitCommandRunner } from './deploy-key-merge-core.js';
42
+ export type MergeJobFetch = (url: string, init?: RequestInit) => Promise<Response>;
43
+ export declare const REQUIRED_MERGE_JOB_ENV_VARS: readonly ["ORIZU_BOOT_SECRET", "ORIZU_MERGE_JOB_ID", "ORIZU_COORDINATOR_URL", "ORIZU_BASE_URL"];
44
+ export interface MergeJobEnv {
45
+ bootSecret: string;
46
+ /** The DO addressing key (`merge:<manifestId>:<expectedHeadSha>`). */
47
+ jobKey: string;
48
+ coordinatorUrl: string;
49
+ baseUrl: string;
50
+ }
51
+ export declare function resolveMergeJobEnv(env: Record<string, string | undefined>): {
52
+ ok: true;
53
+ value: MergeJobEnv;
54
+ } | {
55
+ ok: false;
56
+ missing: string[];
57
+ invalid: string[];
58
+ };
59
+ export type MergeJobTerminalStatus = 'succeeded' | 'conflict' | 'superseded' | 'failed';
60
+ export interface MergeJobReport {
61
+ status: MergeJobTerminalStatus;
62
+ result: {
63
+ merged: boolean;
64
+ sha: string | null;
65
+ alreadyMerged: boolean;
66
+ conflict: boolean;
67
+ } | null;
68
+ errorDetail: string | null;
69
+ }
70
+ /** Map the shared core's outcome to the job's terminal status. */
71
+ export declare function terminalFromMergeResult(result: DeployKeyMergeResult): MergeJobReport;
72
+ export interface ExchangedJobToken {
73
+ token: string;
74
+ /** The control-plane job id (merge_jobs uuid) — payload/gate URLs use it. */
75
+ jobId: string;
76
+ }
77
+ export declare function exchangeJobToken(opts: {
78
+ coordinatorUrl: string;
79
+ jobKey: string;
80
+ bootSecret: string;
81
+ fetchImpl: MergeJobFetch;
82
+ attempts?: number;
83
+ backoffMs?: number;
84
+ sleep?: (ms: number) => Promise<void>;
85
+ log?: (line: string) => void;
86
+ }): Promise<ExchangedJobToken>;
87
+ export interface MergeJobSpec {
88
+ op: 'merge';
89
+ jobId: string;
90
+ manifestId: string;
91
+ workspaceId: string;
92
+ repoFullName: string;
93
+ base: string;
94
+ sourceBranch: string;
95
+ expectedHeadSha: string;
96
+ commitMessage: string;
97
+ }
98
+ export interface MergeJobPayload {
99
+ spec: MergeJobSpec;
100
+ privateKeyPem: string;
101
+ }
102
+ export declare function fetchMergeJobPayload(opts: {
103
+ baseUrl: string;
104
+ jobId: string;
105
+ token: string;
106
+ fetchImpl: MergeJobFetch;
107
+ }): Promise<MergeJobPayload>;
108
+ export type GateOutcome = 'proceed' | 'superseded' | 'unavailable';
109
+ export declare function checkPrePushGate(opts: {
110
+ baseUrl: string;
111
+ jobId: string;
112
+ token: string;
113
+ fetchImpl: MergeJobFetch;
114
+ }): Promise<GateOutcome>;
115
+ export declare function postMergeJobResult(opts: {
116
+ coordinatorUrl: string;
117
+ jobKey: string;
118
+ bootSecret: string;
119
+ report: MergeJobReport;
120
+ fetchImpl: MergeJobFetch;
121
+ attempts?: number;
122
+ sleep?: (ms: number) => Promise<void>;
123
+ log?: (line: string) => void;
124
+ }): Promise<boolean>;
125
+ export interface RunMergeJobOptions {
126
+ env: MergeJobEnv;
127
+ fetchImpl?: MergeJobFetch;
128
+ /** Injectable git runner (tests). Default: the core's real spawn. */
129
+ runGit?: GitCommandRunner;
130
+ sleep?: (ms: number) => Promise<void>;
131
+ log?: (line: string) => void;
132
+ tokenAttempts?: number;
133
+ tokenBackoffMs?: number;
134
+ }
135
+ export interface MergeJobRunResult {
136
+ /** Whether the terminal state reached the DO — the command's success bar. */
137
+ reported: boolean;
138
+ status: MergeJobTerminalStatus;
139
+ detail: string | null;
140
+ }
141
+ export declare function runMergeJob(opts: RunMergeJobOptions): Promise<MergeJobRunResult>;
142
+ export interface MergeJobCommandIo {
143
+ print: (line: string) => void;
144
+ printErr?: (line: string) => void;
145
+ json?: boolean;
146
+ }
147
+ /**
148
+ * Read the frozen env contract and run the job. Exit 0 on ANY reported
149
+ * terminal outcome (the REPORT, not the merge, is the command's success —
150
+ * a conflict is a correctly-completed job); exit 1 when the env is invalid
151
+ * or the terminal report never reached the DO (the DO's job wall is the
152
+ * backstop then).
153
+ */
154
+ export declare function mergeJobCommand(io: MergeJobCommandIo): Promise<number>;
155
+ //# sourceMappingURL=merge-job.d.ts.map