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,256 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { createHash, randomUUID } from "node:crypto";
4
+ import { execFileSync } from "node:child_process";
5
+ import {
6
+ closeSync,
7
+ fsyncSync,
8
+ mkdtempSync,
9
+ openSync,
10
+ readFileSync,
11
+ readdirSync,
12
+ renameSync,
13
+ rmSync,
14
+ writeFileSync,
15
+ } from "node:fs";
16
+ import { tmpdir } from "node:os";
17
+ import { dirname, join, resolve } from "node:path";
18
+ import { fileURLToPath } from "node:url";
19
+
20
+ const scriptDirectory = dirname(fileURLToPath(import.meta.url));
21
+ const cliRoot = resolve(scriptDirectory, "..");
22
+ const repositoryRoot = resolve(cliRoot, "../..");
23
+ const inputPath = join(cliRoot, "requirements", "skilled-proposer.in");
24
+ const lockPath = join(cliRoot, "requirements", "skilled-proposer.lock");
25
+
26
+ const TARGETS = [
27
+ { name: "macos-arm64", platforms: ["macosx_15_0_arm64"] },
28
+ {
29
+ name: "linux-x86_64",
30
+ platforms: ["manylinux_2_28_x86_64", "manylinux2014_x86_64"],
31
+ },
32
+ ];
33
+ const PYTHON_MINORS = ["3.10", "3.11", "3.12", "3.13", "3.14"];
34
+
35
+ function parseArguments(argv) {
36
+ const options = {
37
+ check: false,
38
+ download: false,
39
+ python: join(repositoryRoot, ".scratch-deps", "venv", "bin", "python"),
40
+ wheelRoot: join(repositoryRoot, ".scratch-deps", "wheels"),
41
+ };
42
+
43
+ for (let index = 0; index < argv.length; index += 1) {
44
+ const argument = argv[index];
45
+ if (argument === "--check") options.check = true;
46
+ else if (argument === "--download") options.download = true;
47
+ else if (argument === "--python") options.python = resolve(argv[++index]);
48
+ else if (argument === "--wheel-root") options.wheelRoot = resolve(argv[++index]);
49
+ else throw new Error(`Unknown argument: ${argument}`);
50
+ }
51
+ if (options.check && options.download) {
52
+ throw new Error("--check and --download are mutually exclusive");
53
+ }
54
+ return options;
55
+ }
56
+
57
+ function canonicalizeName(name) {
58
+ return name.toLowerCase().replace(/[._-]+/g, "-");
59
+ }
60
+
61
+ function parsePins() {
62
+ return readFileSync(inputPath, "utf8")
63
+ .split(/\r?\n/u)
64
+ .map((line) => line.trim())
65
+ .filter((line) => line && !line.startsWith("#"))
66
+ .map((line) => {
67
+ const match = /^([A-Za-z0-9._-]+)==([^ ;]+)(?:\s*;\s*(.+))?$/u.exec(line);
68
+ if (!match) throw new Error(`Invalid fully pinned requirement: ${line}`);
69
+ return {
70
+ name: canonicalizeName(match[1]),
71
+ version: match[2],
72
+ marker: match[3] ?? null,
73
+ source: line,
74
+ };
75
+ });
76
+ }
77
+
78
+ function pinApplies(pin, pythonMinor) {
79
+ if (!pin.marker) return true;
80
+ if (pin.marker === 'python_version == "3.10"') return pythonMinor === "3.10";
81
+ if (pin.marker === 'python_version >= "3.11" and python_version < "3.15"') {
82
+ return pythonMinor !== "3.10";
83
+ }
84
+ throw new Error(`Unsupported environment marker in ${pin.source}`);
85
+ }
86
+
87
+ function activePins(pins, pythonMinor) {
88
+ const active = pins.filter((pin) => pinApplies(pin, pythonMinor));
89
+ const names = new Set(active.map((pin) => pin.name));
90
+ const expectedCount = pythonMinor === "3.10" ? 60 : 58;
91
+ if (active.length !== expectedCount || names.size !== expectedCount) {
92
+ throw new Error(
93
+ `Expected ${expectedCount} unique active pins for Python ${pythonMinor}; found ${active.length}`,
94
+ );
95
+ }
96
+ return active;
97
+ }
98
+
99
+ function wheelIdentity(filename) {
100
+ const match = /^(.+?)-([^-]+)-[^-]+-[^-]+-[^-]+\.whl$/u.exec(filename);
101
+ if (!match) throw new Error(`Not a wheel filename: ${filename}`);
102
+ return { name: canonicalizeName(match[1]), version: match[2] };
103
+ }
104
+
105
+ function downloadWheelhouse(options, target, pythonMinor, pins) {
106
+ const wheelhouse = join(
107
+ options.wheelRoot,
108
+ `${target.name}-py${pythonMinor.replace(".", "")}`,
109
+ );
110
+ const temporary = mkdtempSync(join(tmpdir(), "orizu-ali-1505-pins-"));
111
+ const requirements = join(temporary, "requirements.txt");
112
+ writeFileSync(
113
+ requirements,
114
+ `${activePins(pins, pythonMinor)
115
+ .map(({ name, version }) => `${name}==${version}`)
116
+ .join("\n")}\n`,
117
+ );
118
+ const pipArguments = [
119
+ "-m",
120
+ "pip",
121
+ "download",
122
+ "--disable-pip-version-check",
123
+ "--no-deps",
124
+ "--only-binary=:all:",
125
+ "--implementation",
126
+ "cp",
127
+ "--python-version",
128
+ pythonMinor.replace(".", ""),
129
+ "--abi",
130
+ `cp${pythonMinor.replace(".", "")}`,
131
+ ];
132
+ for (const platform of target.platforms) {
133
+ pipArguments.push("--platform", platform);
134
+ }
135
+ pipArguments.push("--dest", wheelhouse, "--requirement", requirements);
136
+ try {
137
+ execFileSync(options.python, pipArguments, { stdio: "inherit", timeout: 10 * 60 * 1000 });
138
+ } finally {
139
+ rmSync(temporary, { recursive: true, force: true });
140
+ }
141
+ }
142
+
143
+ function digestWheel(path) {
144
+ return createHash("sha256").update(readFileSync(path)).digest("hex");
145
+ }
146
+
147
+ function collectWheelHashes(options, pins) {
148
+ const hashes = new Map(pins.map((pin) => [pin.source, new Set()]));
149
+
150
+ for (const target of TARGETS) {
151
+ for (const pythonMinor of PYTHON_MINORS) {
152
+ const active = activePins(pins, pythonMinor);
153
+ const activeByIdentity = new Map(
154
+ active.map((pin) => [`${pin.name}==${pin.version}`, pin]),
155
+ );
156
+ const wheelhouse = join(
157
+ options.wheelRoot,
158
+ `${target.name}-py${pythonMinor.replace(".", "")}`,
159
+ );
160
+ const files = readdirSync(wheelhouse).filter((file) => file.endsWith(".whl"));
161
+ const found = new Set();
162
+ for (const file of files) {
163
+ const identity = wheelIdentity(file);
164
+ const key = `${identity.name}==${identity.version}`;
165
+ const pin = activeByIdentity.get(key);
166
+ if (!pin) throw new Error(`Unexpected wheel in ${wheelhouse}: ${file}`);
167
+ if (found.has(pin.name)) {
168
+ throw new Error(`Multiple wheels for ${pin.name} in ${wheelhouse}`);
169
+ }
170
+ found.add(pin.name);
171
+ hashes.get(pin.source).add(digestWheel(join(wheelhouse, file)));
172
+ }
173
+ const missing = active.filter((pin) => !found.has(pin.name));
174
+ if (missing.length > 0) {
175
+ throw new Error(
176
+ `Missing wheels in ${wheelhouse}: ${missing.map((pin) => pin.source).join(", ")}`,
177
+ );
178
+ }
179
+ }
180
+ }
181
+ return hashes;
182
+ }
183
+
184
+ function renderLock(pins, hashes) {
185
+ const header = [
186
+ "# Generated by packages/cli/scripts/refresh-skilled-proposer-lock.mjs.",
187
+ "# Do not edit by hand; see packages/cli/requirements/README.md.",
188
+ "#",
189
+ "# Wheel-only coverage: CPython 3.10-3.14 on macOS 15+ arm64 and",
190
+ "# glibc-based Linux x86_64 compatible with the locked manylinux wheels.",
191
+ "# Other OS/architecture/libc combinations are intentionally not covered.",
192
+ "",
193
+ ];
194
+ const continuation = ` ${String.fromCharCode(92, 10)}`;
195
+ const requirements = [...pins]
196
+ .sort((left, right) => left.source.localeCompare(right.source))
197
+ .map((pin) => {
198
+ const pinHashes = [...hashes.get(pin.source)].sort();
199
+ if (pinHashes.length === 0) throw new Error(`No wheel hash for ${pin.source}`);
200
+ const hashLines = pinHashes
201
+ .map((hash) => ` --hash=sha256:${hash}`)
202
+ .join(continuation);
203
+ return pin.source + continuation + hashLines;
204
+ });
205
+ return `${header.join("\n")}${requirements.join("\n")}\n`;
206
+ }
207
+
208
+ function main() {
209
+ const options = parseArguments(process.argv.slice(2));
210
+ const pins = parsePins();
211
+ if (options.download) {
212
+ for (const target of TARGETS) {
213
+ for (const pythonMinor of PYTHON_MINORS) {
214
+ downloadWheelhouse(options, target, pythonMinor, pins);
215
+ }
216
+ }
217
+ }
218
+ const lock = renderLock(pins, collectWheelHashes(options, pins));
219
+ if (options.check) {
220
+ if (readFileSync(lockPath, "utf8") !== lock) {
221
+ throw new Error(`${lockPath} is stale; regenerate it from verified wheelhouses`);
222
+ }
223
+ process.stdout.write(`Verified ${lockPath}\n`);
224
+ return;
225
+ }
226
+ const temporaryLock = join(
227
+ dirname(lockPath),
228
+ `.skilled-proposer.lock-${process.pid}-${randomUUID()}.tmp`,
229
+ );
230
+ try {
231
+ const temporaryDescriptor = openSync(temporaryLock, "wx");
232
+ try {
233
+ writeFileSync(temporaryDescriptor, lock);
234
+ fsyncSync(temporaryDescriptor);
235
+ } finally {
236
+ closeSync(temporaryDescriptor);
237
+ }
238
+ renameSync(temporaryLock, lockPath);
239
+ const requirementsDescriptor = openSync(dirname(lockPath), "r");
240
+ try {
241
+ fsyncSync(requirementsDescriptor);
242
+ } finally {
243
+ closeSync(requirementsDescriptor);
244
+ }
245
+ } finally {
246
+ rmSync(temporaryLock, { force: true });
247
+ }
248
+ process.stdout.write(`Wrote ${lockPath}\n`);
249
+ }
250
+
251
+ try {
252
+ main();
253
+ } catch (error) {
254
+ process.stderr.write(`${error instanceof Error ? error.message : String(error)}\n`);
255
+ process.exitCode = 1;
256
+ }
@@ -36,6 +36,7 @@ interface DiffCommentPayloadComment {
36
36
  body: string
37
37
  author: DiffCommentAuthor
38
38
  createdAt: string
39
+ componentKey?: string | null
39
40
  anchor: { side: 'old' | 'new'; line: number }
40
41
  context: {
41
42
  lineText: string
@@ -364,6 +365,9 @@ function printDiffComments(ctx: DiffCommentsCliContext, payload: DiffCommentsPay
364
365
  `${sanitizeHumanInlineText(ctx.sanitizeTerminalText, String(comment.anchor.line + 1))}`
365
366
  )
366
367
  printHumanTextBlock(ctx, comment.body)
368
+ if (typeof comment.componentKey === 'string' && comment.componentKey) {
369
+ ctx.printLine(` Component: ${sanitizeHumanInlineText(ctx.sanitizeTerminalText, comment.componentKey)}`)
370
+ }
367
371
 
368
372
  if (comment.contextUnavailableReason) {
369
373
  ctx.printLine(
@@ -34,6 +34,8 @@ const VALUE_OPTIONS: EnvironmentOption[] = [
34
34
  { flag: '--budget', environment: 'ORIZU_BUDGET' },
35
35
  { flag: '--max-iterations', environment: 'ORIZU_MAX_ITERATIONS' },
36
36
  { flag: '--max-candidate-proposals', environment: 'ORIZU_MAX_CANDIDATE_PROPOSALS' },
37
+ { flag: '--proposal-max-calls', environment: 'ORIZU_PROPOSAL_MAX_CALLS' },
38
+ { flag: '--proposal-max-tokens', environment: 'ORIZU_PROPOSAL_MAX_TOKENS' },
37
39
  { flag: '--max-full-evals', environment: 'ORIZU_MAX_FULL_EVALS' },
38
40
  { flag: '--max-metric-calls', environment: 'ORIZU_MAX_METRIC_CALLS' },
39
41
  { flag: '--minibatch-size', environment: 'ORIZU_MINIBATCH_SIZE' },
@@ -51,6 +53,8 @@ const VALUE_OPTIONS: EnvironmentOption[] = [
51
53
  { flag: '--seed', environment: 'ORIZU_SEED' },
52
54
  { flag: '--promotion-label', environment: 'ORIZU_PROMOTION_LABEL', allowEmpty: true },
53
55
  { flag: '--log-dir', environment: 'ORIZU_LOCAL_LOG_DIR' },
56
+ { flag: '--instruction-set', environment: 'ORIZU_INSTRUCTION_SET_NAME' },
57
+ { flag: '--model-config', environment: 'ORIZU_MODEL_CONFIG_IDENTITY' },
54
58
  ]
55
59
 
56
60
  const BOOLEAN_OPTIONS = [
@@ -170,6 +174,12 @@ const CONTROLLED_ENVIRONMENT_NAMES = new Set([
170
174
  'ORIZU_SAMPLING_STRATEGY',
171
175
  'ORIZU_SELECTION_STRATEGY',
172
176
  'ORIZU_MAX_PAYLOAD_CHARS',
177
+ 'ORIZU_INSTRUCTION_SET_PROFILE_VERSION_ID',
178
+ // Candidate selection is an explicit opt-in. Clearing it before option
179
+ // translation prevents an inherited environment from selecting a proposer
180
+ // on an otherwise byte-for-byte normal official-GEPA launch.
181
+ 'ORIZU_CANDIDATE_PROPOSER',
182
+ 'ORIZU_COMPONENT_SELECTOR',
173
183
  ])
174
184
 
175
185
  function optionValueOrThrow(args: string[], index: number, flag: string, allowEmpty = false): { value: string; nextIndex: number } {
@@ -198,6 +208,8 @@ function translateOfficialOptions(args: string[], project: string, environment:
198
208
  connectorEnvironment.ORIZU_PROJECT = project
199
209
 
200
210
  let metadata: string | undefined
211
+ let hasInstructionSet = false
212
+ let hasCandidateVersion = false
201
213
  const budgetFlags: string[] = []
202
214
  for (let index = 0; index < args.length; index += 1) {
203
215
  const argument = args[index]
@@ -206,6 +218,7 @@ function translateOfficialOptions(args: string[], project: string, environment:
206
218
  }
207
219
 
208
220
  const flag = argument.includes('=') ? argument.slice(0, argument.indexOf('=')) : argument
221
+ if (flag === '--candidate-version-id') hasCandidateVersion = true
209
222
  if (flag === '--project') {
210
223
  const parsed = optionValueOrThrow(args, index, flag)
211
224
  connectorEnvironment.ORIZU_PROJECT = parsed.value
@@ -218,6 +231,15 @@ function translateOfficialOptions(args: string[], project: string, environment:
218
231
  index = parsed.nextIndex
219
232
  continue
220
233
  }
234
+ if (flag === '--candidate-proposer') {
235
+ const parsed = optionValueOrThrow(args, index, flag)
236
+ if (parsed.value !== 'skilled-proposer') {
237
+ throw new Error('--candidate-proposer must be skilled-proposer')
238
+ }
239
+ connectorEnvironment.ORIZU_CANDIDATE_PROPOSER = parsed.value
240
+ index = parsed.nextIndex
241
+ continue
242
+ }
221
243
  const option = VALUE_OPTIONS_BY_FLAG.get(flag)
222
244
  if (option) {
223
245
  const parsed = optionValueOrThrow(args, index, flag, option.allowEmpty)
@@ -239,6 +261,14 @@ function translateOfficialOptions(args: string[], project: string, environment:
239
261
  connectorEnvironment[option.environment] = option.json
240
262
  ? jsonObjectValue(parsed.value, option.flag)
241
263
  : option.readFile ? textValue(parsed.value) : parsed.value
264
+ if (flag === '--instruction-set') hasInstructionSet = true
265
+ index = parsed.nextIndex
266
+ continue
267
+ }
268
+ if (flag === '--component-selector') {
269
+ const parsed = optionValueOrThrow(args, index, flag)
270
+ if (!['round-robin', 'all'].includes(parsed.value)) throw new Error('--component-selector must be one of round-robin, all')
271
+ connectorEnvironment.ORIZU_COMPONENT_SELECTOR = parsed.value.replace('-', '_')
242
272
  index = parsed.nextIndex
243
273
  continue
244
274
  }
@@ -259,6 +289,14 @@ function translateOfficialOptions(args: string[], project: string, environment:
259
289
  if (budgetFlags.length > 1) {
260
290
  throw new Error('Budget options are mutually exclusive; choose at most one of --budget, --max-metric-calls, --max-full-evals, --max-iterations, --max-candidate-proposals')
261
291
  }
292
+ if (hasInstructionSet && hasCandidateVersion) throw new Error('--instruction-set and --candidate-version-id are mutually exclusive')
293
+ if (hasInstructionSet && connectorEnvironment.ORIZU_MODEL_CONFIG_IDENTITY === undefined) throw new Error('--instruction-set requires --model-config')
294
+ if (hasInstructionSet && connectorEnvironment.ORIZU_COMPONENT_SELECTOR === undefined) connectorEnvironment.ORIZU_COMPONENT_SELECTOR = 'round_robin'
295
+ if ((connectorEnvironment.ORIZU_PROPOSAL_MAX_CALLS !== undefined
296
+ || connectorEnvironment.ORIZU_PROPOSAL_MAX_TOKENS !== undefined)
297
+ && connectorEnvironment.ORIZU_CANDIDATE_PROPOSER !== 'skilled-proposer') {
298
+ throw new Error('--proposal-max-calls and --proposal-max-tokens require --candidate-proposer skilled-proposer')
299
+ }
262
300
 
263
301
  const reflectionModel = connectorEnvironment.ORIZU_REFLECTION_MODEL ?? 'anthropic/claude-opus-4-7'
264
302
  if (!reflectionModel.startsWith('openai/') && connectorEnvironment.ORIZU_REFLECTION_MAX_TOKENS === undefined) {
@@ -283,8 +321,10 @@ function validatedMetadata(raw: string | undefined): string {
283
321
  export function dispatchGepaEngine(args: string[], project: string, environment: NodeJS.ProcessEnv): GepaEngineDispatch {
284
322
  const selected = removeEngine(args)
285
323
  if (selected.engine === 'legacy') {
286
- if (selected.args.some(argument => argument === '--max-candidate-proposals' || argument.startsWith('--max-candidate-proposals='))) {
287
- throw new Error('--max-candidate-proposals is supported by the official GEPA engine only')
324
+ for (const flag of ['--instruction-set', '--model-config', '--component-selector', '--max-candidate-proposals', '--candidate-proposer', '--proposal-max-calls', '--proposal-max-tokens']) {
325
+ if (selected.args.some(argument => argument === flag || argument.startsWith(`${flag}=`))) {
326
+ throw new Error(`${flag} is supported by the official GEPA engine only`)
327
+ }
288
328
  }
289
329
  validateLegacyMetadata(selected.args)
290
330
  return {
@@ -34,9 +34,12 @@ export function bundledOrizuGepaConnectorPythonPath(): string | null {
34
34
  }
35
35
 
36
36
  export function bundledOfficialGepaPythonPath(): string | null {
37
- const candidates = [
38
- fileURLToPath(new URL('../vendor/gepa-python/src', import.meta.url)),
39
- ]
37
+ const sourceArchive = fileURLToPath(new URL('../gepa-python-source.zip', import.meta.url))
38
+ const vendor = fileURLToPath(new URL('../vendor/gepa-python/src', import.meta.url))
39
+ // The checked-in pinned wheel is directly importable from PYTHONPATH in a
40
+ // source checkout. Published packages intentionally omit that archive and
41
+ // must resolve only the verified tree materialized by prepack.
42
+ const candidates = prefersLiveSource() ? [sourceArchive, vendor] : [vendor]
40
43
 
41
44
  return resolveGepaPythonPath(candidates)
42
45
  }
package/src/help.ts CHANGED
@@ -35,6 +35,7 @@ const GROUPS: CliGroupDoc[] = [
35
35
  { name: 'Teams', summary: 'Manage teams and team memberships.' },
36
36
  { name: 'Projects', summary: 'Manage projects inside teams.' },
37
37
  { name: 'Prompts and judges', summary: 'Work with versioned prompt and judge artifacts.' },
38
+ { name: 'Instruction sets', summary: 'Inspect the project-scoped instruction-set control plane.' },
38
39
  { name: 'Report comments', summary: 'Review and mutate anchored report comments across prompt, optimization, and task reports.' },
39
40
  { name: 'Diff comments', summary: 'Export inline comments with recoverable prompt-diff context.' },
40
41
  { name: 'Scorers and runners', summary: 'Register scorers, push runnable artifacts, execute runners, and submit scores.' },
@@ -50,6 +51,44 @@ const GROUPS: CliGroupDoc[] = [
50
51
  ]
51
52
 
52
53
  export const COMMAND_DOCS: CliCommandDoc[] = [
54
+ { path: ['instructions', 'create'], aliases: [['instruction-sets', 'create']], usage: 'orizu instructions create <manifest> --project <team/project> [--runner-version <id>] [--model-config <identity>] [--json]', summary: 'Create an instruction set from a local manifest.', group: 'Instruction sets', options: [{ name: '--runner-version <id>', help: 'Pin the runner version for component prompt versions.' }, { name: '--model-config <identity>', help: 'Select the default model configuration.' }, { name: '--json', help: 'Print one JSON document.' }], examples: ['orizu instructions create ./orizu.instruction-set.json --project core/evals --model-config anthropic/claude-haiku'] },
55
+ { path: ['instructions', 'push'], aliases: [['instruction-sets', 'push']], usage: 'orizu instructions push <manifest> --project <team/project> [--set <slug-or-exact-name>] [--runner-version <id>] [--json]', summary: 'Push a new instruction-set profile version.', group: 'Instruction sets', options: [{ name: '--set <slug-or-exact-name>', help: 'Target the stable set handle when it differs from the manifest name.' }, { name: '--runner-version <id>', help: 'Pin the runner version for changed component prompt versions.' }, { name: '--json', help: 'Print one JSON document.' }], examples: ['orizu instructions push ./orizu.instruction-set.json --project core/evals --set planner'] },
56
+ {
57
+ path: ['instructions', 'list'],
58
+ aliases: [['instruction-sets', 'list']],
59
+ usage: 'orizu instructions list [--project <team/project>] [--status active|archived|all] [--json]',
60
+ summary: 'List instruction sets in a project.',
61
+ group: 'Instruction sets',
62
+ options: [{ name: '--project <team/project>', help: 'Project slug (defaults to configured context).' }, { name: '--status <active|archived|all>', help: 'Filter archived instruction sets.' }, { name: '--json', help: 'Print JSON.' }],
63
+ examples: ['orizu instructions list --project core/evals', 'orizu instructions list --status archived --json'],
64
+ },
65
+ {
66
+ path: ['instructions', 'show'],
67
+ aliases: [['instruction-sets', 'show']],
68
+ usage: 'orizu instructions show <set> [--project <team/project>] [--status active|archived|all] [--json]',
69
+ summary: 'Show an instruction set shape, default, and profile production state.',
70
+ group: 'Instruction sets',
71
+ options: [{ name: '--project <team/project>', help: 'Project slug (defaults to configured context).' }, { name: '--status <active|archived|all>', help: 'Filter archived instruction sets.' }, { name: '--json', help: 'Print JSON.' }],
72
+ examples: ['orizu instructions show research --project core/evals', 'orizu instructions show research --json'],
73
+ },
74
+ { path: ['instructions', 'profiles', 'new'], aliases: [['instruction-sets', 'profiles', 'new']], usage: 'orizu instructions profiles new <set> --project <team/project> --model-config <identity> [--json]', summary: 'Create a model-config profile seeded from the instruction-set default.', group: 'Instruction sets', options: [{ name: '--model-config <identity>', help: 'Model config identity for the new profile.', required: true }, { name: '--json', help: 'Print JSON.' }], examples: ['orizu instructions profiles new planner --project core/evals --model-config anthropic/claude-haiku'] },
75
+ { path: ['instructions', 'profiles', 'promote'], aliases: [['instruction-sets', 'profiles', 'promote']], usage: 'orizu instructions profiles promote <set> --project <team/project> --model-config <identity> --version <n> [--json]', summary: 'Move one profile version to production.', group: 'Instruction sets', options: [{ name: '--model-config <identity>', help: 'Profile model config.', required: true }, { name: '--version <n>', help: 'Profile version to promote.', required: true }, { name: '--json', help: 'Print JSON.' }], examples: ['orizu instructions profiles promote planner --project core/evals --model-config anthropic/claude-haiku --version 2'] },
76
+ { path: ['instructions', 'profiles', 'rollback'], aliases: [['instruction-sets', 'profiles', 'rollback']], usage: 'orizu instructions profiles rollback <set> --project <team/project> --model-config <identity> --to <n> [--json]', summary: 'Create a rollback version and move profile production to it.', group: 'Instruction sets', options: [{ name: '--model-config <identity>', help: 'Profile model config.', required: true }, { name: '--to <n>', help: 'Historical profile version to copy.', required: true }, { name: '--json', help: 'Print JSON.' }], examples: ['orizu instructions profiles rollback planner --project core/evals --model-config anthropic/claude-haiku --to 1'] },
77
+ { path: ['instructions', 'default', 'show'], aliases: [['instruction-sets', 'default', 'show']], usage: 'orizu instructions default show <set> --project <team/project> [--json]', summary: 'Show the instruction-set default and its resolution impact.', group: 'Instruction sets', options: [{ name: '--project <team/project>', help: 'Project slug.', required: true }, { name: '--json', help: 'Print JSON.' }], examples: ['orizu instructions default show planner --project core/evals'] },
78
+ { path: ['instructions', 'default', 'move'], aliases: [['instruction-sets', 'default', 'move']], usage: 'orizu instructions default move <set> --project <team/project> --model-config <identity> --version <n> [--json]', summary: 'Move the instruction-set default to a profile version.', group: 'Instruction sets', options: [{ name: '--project <team/project>', help: 'Project slug.', required: true }, { name: '--model-config <identity>', help: 'Target model config.', required: true }, { name: '--version <n>', help: 'Target profile version.', required: true }, { name: '--json', help: 'Print JSON.' }], examples: ['orizu instructions default move planner --project core/evals --model-config anthropic/claude-haiku --version 2'] },
79
+ { path: ['instructions', 'shape', 'add'], aliases: [['instruction-sets', 'shape', 'add']], usage: 'orizu instructions shape add <set> --project <team/project> --key <key> --from <manifest> [--json]', summary: 'Add one component key to every instruction-set profile.', group: 'Instruction sets', options: [{ name: '--project <team/project>', help: 'Project slug.', required: true }, { name: '--key <key>', help: 'Component key to add.', required: true }, { name: '--from <manifest>', help: 'Manifest containing the component body.', required: true }, { name: '--json', help: 'Print JSON.' }], examples: ['orizu instructions shape add planner --project core/evals --key skill --from planner.json'] },
80
+ { path: ['instructions', 'shape', 'remove'], aliases: [['instruction-sets', 'shape', 'remove']], usage: 'orizu instructions shape remove <set> --project <team/project> --key <key> [--json]', summary: 'Remove one component key from every instruction-set profile.', group: 'Instruction sets', options: [{ name: '--project <team/project>', help: 'Project slug.', required: true }, { name: '--key <key>', help: 'Component key to remove.', required: true }, { name: '--json', help: 'Print JSON.' }], examples: ['orizu instructions shape remove planner --project core/evals --key skill'] },
81
+ {
82
+ path: ['instructions', 'sync'],
83
+ aliases: [['instruction-sets', 'sync']],
84
+ usage: 'orizu instructions sync <set> --out <dir> [--model-config <identity>] [--project <team/project>] [--json]',
85
+ summary: 'Write an instruction set for offline runner loading.',
86
+ group: 'Instruction sets',
87
+ options: [{ name: '--out <dir>', help: 'Destination parent directory.', required: true }, { name: '--model-config <identity>', help: 'Sync only one profile plus default.' }, { name: '--project <team/project>', help: 'Project slug.' }, { name: '--json', help: 'Print source transport JSON.' }],
88
+ examples: ['orizu instructions sync planner --out ./instructions --project core/evals'],
89
+ },
90
+ { path: ['instructions', 'archive'], aliases: [['instruction-sets', 'archive']], usage: 'orizu instructions archive <slug-or-exact-name> --project <team/project> [--json]', summary: 'Archive an instruction set without changing resolution or sync.', group: 'Instruction sets', options: [{ name: '--project <team/project>', help: 'Project slug.', required: true }, { name: '--json', help: 'Print JSON.' }], examples: ['orizu instructions archive planner --project core/evals'] },
91
+ { path: ['instructions', 'restore'], aliases: [['instruction-sets', 'restore']], usage: 'orizu instructions restore <slug-or-exact-name> --project <team/project> [--json]', summary: 'Restore an archived instruction set.', group: 'Instruction sets', options: [{ name: '--project <team/project>', help: 'Project slug.', required: true }, { name: '--json', help: 'Print JSON.' }], examples: ['orizu instructions restore planner --project core/evals'] },
53
92
  {
54
93
  path: ['login'],
55
94
  usage: 'orizu login [--no-prompt-if-logged-in]',
@@ -342,30 +381,12 @@ export const COMMAND_DOCS: CliCommandDoc[] = [
342
381
  summary: 'List prompt artifacts in a project.',
343
382
  group: 'Prompts and judges',
344
383
  },
345
- {
346
- path: ['prompts', 'archive'],
347
- usage: 'orizu prompts archive <prompt-id-or-name> --project <team/project> [--json]',
348
- summary: 'Mark a prompt artifact as archived.',
349
- group: 'Prompts and judges',
350
- },
351
- {
352
- path: ['prompts', 'restore'],
353
- usage: 'orizu prompts restore <prompt-id-or-name> --project <team/project> [--json]',
354
- summary: 'Restore an archived prompt artifact to active status.',
355
- group: 'Prompts and judges',
356
- },
357
384
  {
358
385
  path: ['prompts', 'pull'],
359
386
  usage: 'orizu prompts pull <prompt-id-or-name> --project <team/project> --out <dir> [--label <label> | --version <id>] [--json]',
360
387
  summary: 'Pull a prompt artifact version to a local directory.',
361
388
  group: 'Prompts and judges',
362
389
  },
363
- {
364
- path: ['prompts', 'push'],
365
- usage: 'orizu prompts push <dir> [--runner-version <id>] [--project <team/project>] [--parent <version-id>] [--session <session-id>] [--report-file <path>] [--json]',
366
- summary: 'Push a local prompt artifact directory as a new version (with --session: a commit-first git draft).',
367
- group: 'Prompts and judges',
368
- },
369
390
  {
370
391
  path: ['prompts', 'report', 'set'],
371
392
  usage: 'orizu prompts report set --prompt <id-or-name> [--project <team/project>] (--version <n> | --version-id <id>) (--report <markdown|@file> | --report-file <path>) [--json]',
@@ -389,7 +410,7 @@ export const COMMAND_DOCS: CliCommandDoc[] = [
389
410
  {
390
411
  path: ['prompts', 'labels', 'set'],
391
412
  usage: 'orizu prompts labels set <prompt-name> <label> --version <version-id> [--project <team/project>] [--json]',
392
- summary: 'Move or set a prompt label to a version.',
413
+ summary: 'Move or set a non-production prompt label; use instructions profiles promote for production.',
393
414
  group: 'Prompts and judges',
394
415
  },
395
416
  {
@@ -464,6 +485,12 @@ export const COMMAND_DOCS: CliCommandDoc[] = [
464
485
  summary: 'Execute a scorer locally for a prompt version or optimization candidate.',
465
486
  group: 'Scorers and runners',
466
487
  },
488
+ {
489
+ path: ['scorers', 'verify-parity'],
490
+ usage: 'orizu scorers verify-parity --scorer-version <id> --dataset-version <id> --split-set <id> [--split <name>] --outputs <outputs.jsonl> --original <module:function> [--scorer-input-contract gepa|flat_row] [--scorer-candidate-field <row-field>] [--runner-dir <dir>] [--python <cmd>] [--tolerance <float>] [--limit <n>] [--json]',
491
+ summary: 'Prove a migrated scorer runner scores rows the same as the original Python metric.',
492
+ group: 'Scorers and runners',
493
+ },
467
494
  {
468
495
  path: ['scores', 'submit'],
469
496
  usage: 'orizu scores submit <results.jsonl|results.json> --scorer-version <id> (--subject-version <prompt-version-id> | --optimization-run <id> --candidate <id>) [--aggregate] [--dataset-version <id> --split-set <id> --split <name>] [--project <team/project>] [--json]',
@@ -536,6 +563,7 @@ export const COMMAND_DOCS: CliCommandDoc[] = [
536
563
  summary: 'List optimization runs with explicit archive visibility.',
537
564
  group: 'Optimizations',
538
565
  },
566
+ { path: ['optimizations', 'promote'], usage: 'orizu optimizations promote <run-id> --candidate <id> [--label production] [--project <team/project>] [--json]', summary: 'Promote a selected optimization candidate.', group: 'Optimizations', options: [{ name: '--candidate <id>', help: 'Candidate to promote.', required: true }, { name: '--label production', help: 'Move the new tuple profile version to production.' }, { name: '--project <team/project>', help: 'Project slug (defaults to configured context).' }, { name: '--json', help: 'Print JSON.' }], examples: ['orizu optimizations promote <run-id> --candidate candidate-2 --label production'] },
539
567
  {
540
568
  path: ['optimizations', 'archive'],
541
569
  usage: 'orizu optimizations archive <run-id> [--project <team/project>] [--json]',
@@ -550,8 +578,8 @@ export const COMMAND_DOCS: CliCommandDoc[] = [
550
578
  },
551
579
  {
552
580
  path: ['optimizations', 'run-gepa'],
553
- usage: 'orizu optimizations run-gepa --project <team/project> --optimizer-version-id <id> --candidate-version-id <id> --runner-version-id <id> --candidate-runner-dir <dir> --scorer-version-id <id> --scorer-runner-version-id <id> --scorer-runner-dir <dir> [--engine official|legacy] [--scorer-input-contract gepa|flat_row] [--scorer-candidate-field <row-field>] [--allow-degenerate-seed] --dataset-version-id <id> --split-set-id <id> [--train-split train] [--val-split validation] [--budget auto|light|medium|heavy | --max-metric-calls <n> | --max-full-evals <n> | --max-iterations <n> | --max-candidate-proposals <n>] [--num-threads auto|N] [--reflection-retry-attempts N] [--reflection-http-timeout-seconds N] [--log-dir logs]',
554
- summary: 'Run official GEPA locally and stream events; pass --engine legacy only for the frozen safety hatch. --max-candidate-proposals is official-engine-only. Validates the scorer contract on the seed before iterating; judge runners built for flat-row score runs need --scorer-input-contract flat_row (ALI-1158).',
581
+ usage: 'orizu optimizations run-gepa --project <team/project> --optimizer-version-id <id> (--candidate-version-id <id> | --instruction-set <name> --model-config <identity> [--component-selector round-robin|all]) --runner-version-id <id> --candidate-runner-dir <dir> --scorer-version-id <id> --scorer-runner-version-id <id> --scorer-runner-dir <dir> [--engine official|legacy] [--scorer-input-contract gepa|flat_row] [--scorer-candidate-field <row-field>] [--allow-degenerate-seed] --dataset-version-id <id> --split-set-id <id> [--train-split train] [--val-split validation] [--budget auto|light|medium|heavy | --max-metric-calls <n> | --max-full-evals <n> | --max-iterations <n> | --max-candidate-proposals <n>] [--num-threads auto|N] [--reflection-retry-attempts N] [--reflection-http-timeout-seconds N] [--log-dir logs]',
582
+ summary: 'Run official GEPA locally and stream events; pass --engine legacy only for the frozen safety hatch. --instruction-set requires --model-config and cannot be combined with --candidate-version-id; round-robin updates one component-map entry per round and all updates every component. --max-candidate-proposals is official-engine-only. Validates the scorer contract on the seed before iterating; judge runners built for flat-row score runs need --scorer-input-contract flat_row (ALI-1158).',
555
583
  group: 'Optimizations',
556
584
  },
557
585
  {
@@ -1057,6 +1085,46 @@ export const COMMAND_DOCS: CliCommandDoc[] = [
1057
1085
  ],
1058
1086
  examples: ['orizu connectors', 'orizu connectors status --project highlight/hip --json'],
1059
1087
  },
1088
+ {
1089
+ path: ['model-configs', 'create'],
1090
+ usage: 'orizu model-configs create <provider/model> [--settings <json|@file>] [--name <name>] [--project <team/project>] [--json]',
1091
+ summary: 'Create a provider-qualified model config with its first settings version.',
1092
+ group: 'Model configs',
1093
+ options: [{ name: '--settings <json|@file>', help: 'Optional JSON settings object or a JSON file; defaults to {}.' }, { name: '--name <name>', help: 'Optional display name.' }, { name: '--project <team/project>', help: 'Project that owns the config.' }, { name: '--json', help: 'Emit the machine-readable model config.' }],
1094
+ examples: ['orizu model-configs create azure/gpt-5.4-mini --settings @settings.json'],
1095
+ },
1096
+ {
1097
+ path: ['model-configs', 'list'],
1098
+ usage: 'orizu model-configs list [--project <team/project>] [--json]',
1099
+ summary: 'List model configs for a project.',
1100
+ group: 'Model configs',
1101
+ options: [{ name: '--project <team/project>', help: 'Project whose configs to list.' }, { name: '--json', help: 'Emit machine-readable model configs.' }],
1102
+ examples: ['orizu model-configs list --project core/evals --json'],
1103
+ },
1104
+ {
1105
+ path: ['model-configs', 'show'],
1106
+ usage: 'orizu model-configs show <provider/model> [--project <team/project>] [--json]',
1107
+ summary: 'Show a model config and its current settings version.',
1108
+ group: 'Model configs',
1109
+ options: [{ name: '--project <team/project>', help: 'Project that owns the config.' }, { name: '--json', help: 'Emit the machine-readable model config.' }],
1110
+ examples: ['orizu model-configs show openai/gpt-5.4-mini'],
1111
+ },
1112
+ {
1113
+ path: ['model-configs', 'settings', 'set'],
1114
+ usage: 'orizu model-configs settings set <provider/model> --settings <json|@file> [--project <team/project>] [--json]',
1115
+ summary: 'Add a settings version and advance the config current pointer.',
1116
+ group: 'Model configs',
1117
+ options: [{ name: '--settings <json|@file>', help: 'JSON settings object or a JSON file.', required: true }, { name: '--project <team/project>', help: 'Project that owns the config.' }, { name: '--json', help: 'Emit the machine-readable model config.' }],
1118
+ examples: ["orizu model-configs settings set openai/gpt-5.4-mini --settings '{\"temperature\":0.2}'"],
1119
+ },
1120
+ {
1121
+ path: ['model-configs', 'copy'],
1122
+ usage: 'orizu model-configs copy <provider/model> --to <provider/model> [--project <team/project>] [--json]',
1123
+ summary: 'Copy the current settings snapshot to a new provider-qualified config.',
1124
+ group: 'Model configs',
1125
+ options: [{ name: '--to <provider/model>', help: 'New provider-qualified config identity.', required: true }, { name: '--project <team/project>', help: 'Project that owns the config.' }, { name: '--json', help: 'Emit the machine-readable model config.' }],
1126
+ examples: ['orizu model-configs copy openai/gpt-5.4-mini --to azure/gpt-5.4-mini'],
1127
+ },
1060
1128
  {
1061
1129
  path: ['manifests', 'list'],
1062
1130
  usage: 'orizu manifests list [--project <team/project>] [--status <status>] [--json]',
@@ -1133,8 +1201,10 @@ export function commandDocsWithPrefix(args: string[]): CliCommandDoc[] {
1133
1201
  }
1134
1202
 
1135
1203
  return COMMAND_DOCS.filter(doc =>
1136
- args.every((part, index) => doc.path[index] === part) &&
1137
- doc.path.length > args.length
1204
+ [doc.path, ...(doc.aliases || [])].some(path =>
1205
+ args.every((part, index) => path[index] === part) &&
1206
+ path.length > args.length
1207
+ )
1138
1208
  )
1139
1209
  }
1140
1210