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
package/dist/index.js CHANGED
@@ -28,11 +28,15 @@ import { formatTaskCreateError } from './task-create-error.js';
28
28
  import { renderAgentSetupPrompt } from './setup-prompt.js';
29
29
  import { getWorkspaceRoot, initOrizuWorkspace, workspaceExists, } from './workspace.js';
30
30
  import { connectorsCommand } from './connectors-cli.js';
31
+ import { modelConfigsCommand } from './model-configs-cli.js';
31
32
  import { ARTIFACT_MAX_BYTES, runnerOptimizerCommand } from './artifact-pull.js';
32
33
  import { killSwitchCommand } from './kill-switch-cli.js';
33
34
  import { egressAllowlistCommand } from './egress-allowlist-cli.js';
34
35
  import { acceptScoreRunCommand } from './scores-accept-cli.js';
35
36
  import { listOptimizationRunsCommand } from './optimizations-list-cli.js';
37
+ import { promoteOptimizationCommand } from './optimizations-promote-cli.js';
38
+ import { scorersCommand } from './scorers-cli.js';
39
+ import { verifyScorerParityCommand } from './scorers-verify-parity.js';
36
40
  import { archiveArtifactCommand, listAssignmentsCommand, printAppSummaries, printDatasetSummaries, printScorerSummaries, printTaskSummaries, } from './archive-artifacts-cli.js';
37
41
  import { teamConnectorsCommand } from './team-connectors-cli.js';
38
42
  import { manifestsCommand } from './manifests-cli.js';
@@ -40,9 +44,13 @@ import { workbenchCommand } from './workbench-cli.js';
40
44
  import { hostedCommand } from './hosted-session-cli.js';
41
45
  import { workspaceSyncCommand } from './workspace-sync.js';
42
46
  import { runGitCredentialInvocation } from './git-credential.js';
47
+ import { instructionSetsCommand, syncToDisk } from './instruction-sets-cli.js';
48
+ export { loadInstructionSet } from './instruction-set-loader.js';
49
+ import { runnerInputInstructionSet, runnerInputPrompt, runnerInstructionSetSyncSet } from './runner-instruction-set-contract.js';
43
50
  import { pushPromptDraft } from './prompt-draft-push.js';
44
51
  import { readMarkdownReportInput } from './markdown-report-input.js';
45
52
  import { promptPushErrorMessage, promptReportCommand } from './prompt-report-cli.js';
53
+ import { setPromptLabel } from './prompt-label-cli.js';
46
54
  import { printPromptSummaryTable } from './prompt-summary-table.js';
47
55
  import { assertSnapshotManifestConfined, verifyGepaRunnerDirsFromArgs, verifyRunnerDirRegistered } from './runner-dir-verify.js';
48
56
  import { runScorersRegister } from './scorer-draft-push.js';
@@ -54,8 +62,10 @@ import { reportCommentsCommand, throwDeprecatedPromptCommentsCommand, } from './
54
62
  import { diffCommentsCommand } from './diff-comments-cli.js';
55
63
  import { exportOptimizationRunCommand } from './optimization-export-cli.js';
56
64
  import { dispatchGepaEngine } from './gepa-engine-dispatch.js';
65
+ import { resolveGepaInstructionSetProfileVersion } from './instruction-set-gepa-launch.js';
57
66
  import { getGepaPythonCommand } from './gepa-python-command.js';
58
67
  import { getGepaPythonPathEntries } from './gepa-python-paths.js';
68
+ import { prepareSkilledProposerLaunch } from './skilled-proposer-launch.js';
59
69
  export { parseJsonResponse, sanitizeTerminalText } from './json-response.js';
60
70
  function getErrorMessage(error) {
61
71
  return error instanceof Error ? error.message : String(error);
@@ -1174,6 +1184,7 @@ async function pullPromptArtifact(kind) {
1174
1184
  scorer_version_id: data.scorerVersionId || undefined,
1175
1185
  scorer_version_ids: scorerVersions.map(item => item.id),
1176
1186
  path: targetDir,
1187
+ owner: data.owner || undefined,
1177
1188
  });
1178
1189
  return;
1179
1190
  }
@@ -1185,55 +1196,14 @@ async function pullPromptArtifact(kind) {
1185
1196
  else if (!data.scorerVersionId && kind === 'judge') {
1186
1197
  printLine(`Warning: prompt version ${sanitizeTerminalText(data.version.id)} does not map to an executable scorer version.`);
1187
1198
  }
1188
- }
1189
- async function setPromptLabel() {
1190
- const promptName = getPositionalArg(3);
1191
- const label = getPositionalArg(4);
1192
- const project = getArg('--project') || await resolveProjectSlug(null);
1193
- const promptVersionId = getArg('--version');
1194
- if (!promptName || !label || !promptVersionId) {
1195
- throw new Error('Usage: orizu prompts labels set <prompt-name> <label> --version <prompt-version-id> [--project <team/project>] [--json]');
1196
- }
1197
- const response = await authedFetch(`/api/cli/prompts/labels?project=${encodeURIComponent(project)}`, {
1198
- method: 'POST',
1199
- headers: { 'Content-Type': 'application/json' },
1200
- body: JSON.stringify({
1201
- promptName,
1202
- label,
1203
- promptVersionId,
1204
- }),
1205
- });
1206
- if (!response.ok) {
1207
- throw new Error(`Failed to set prompt label: ${await response.text()}`);
1208
- }
1209
- const data = await parseJsonResponse(response, 'Prompt label set');
1210
- if (hasJsonFlag()) {
1211
- printJson(data);
1212
- return;
1199
+ if (kind === 'prompt' && data.owner) {
1200
+ printLine(`Owner: ${sanitizeTerminalText(data.prompt.name)} (${sanitizeTerminalText(data.prompt.id)}) -> ` +
1201
+ `${sanitizeTerminalText(data.owner.instructionSetSlug)} / ${sanitizeTerminalText(data.owner.componentKey)}`);
1213
1202
  }
1214
- printLine(`Moved ${sanitizeTerminalText(label)} to ${sanitizeTerminalText(promptVersionId)}`);
1215
1203
  }
1216
- async function setPromptArchivedState(archived) {
1217
- const promptRef = getPositionalArg(2);
1218
- const project = getArg('--project') || await resolveProjectSlug(null);
1219
- const command = archived ? 'archive' : 'restore';
1220
- if (!promptRef) {
1221
- throw new Error(`Usage: orizu prompts ${command} <prompt-id-or-name> --project <team/project> [--json]`);
1222
- }
1223
- const response = await authedFetch(`/api/cli/prompts/${encodeURIComponent(promptRef)}?project=${encodeURIComponent(project)}`, {
1224
- method: 'PATCH',
1225
- headers: { 'Content-Type': 'application/json' },
1226
- body: JSON.stringify({ archived }),
1227
- });
1228
- if (!response.ok) {
1229
- throw new Error(`Failed to ${command} prompt: ${await response.text()}`);
1230
- }
1231
- const data = await parseJsonResponse(response, `Prompt ${command}`);
1232
- if (hasJsonFlag()) {
1233
- printJson(data);
1234
- return;
1235
- }
1236
- printLine(`${archived ? 'Archived' : 'Restored'} prompt ${sanitizeTerminalText(data.prompt.name)} (${sanitizeTerminalText(data.prompt.id)})`);
1204
+ function refusePromptMutation(replacement) {
1205
+ process.exitCode = 1;
1206
+ throw new Error(`Use: orizu instructions ${replacement}`);
1237
1207
  }
1238
1208
  async function bindPromptScorer(role) {
1239
1209
  const promptId = getPositionalArg(3);
@@ -1263,6 +1233,10 @@ async function bindPromptScorer(role) {
1263
1233
  return;
1264
1234
  }
1265
1235
  printLine(`${role === 'headline' ? 'Set headline' : 'Added'} scorer ${sanitizeTerminalText(scorerVersionId)} for ${sanitizeTerminalText(promptId)}`);
1236
+ if (data.owner) {
1237
+ printLine(`Owner: ${sanitizeTerminalText(promptId)} -> ` +
1238
+ `${sanitizeTerminalText(data.owner.instructionSetSlug)} / ${sanitizeTerminalText(data.owner.componentKey)}`);
1239
+ }
1266
1240
  }
1267
1241
  function getPositionalArg(index) {
1268
1242
  const value = cliArgs[index];
@@ -1845,11 +1819,15 @@ async function runGepaOptimization() {
1845
1819
  PYTHONPATH: getGepaPythonPathEntries(process.env.PYTHONPATH).join(delimiter),
1846
1820
  PYTHONUNBUFFERED: process.env.PYTHONUNBUFFERED || '1',
1847
1821
  });
1822
+ const instructionSetName = dispatch.environment.ORIZU_INSTRUCTION_SET_NAME;
1823
+ const modelConfigIdentity = dispatch.environment.ORIZU_MODEL_CONFIG_IDENTITY;
1824
+ const instructionSetProfileVersionId = instructionSetName && modelConfigIdentity
1825
+ ? await resolveGepaInstructionSetProfileVersion(instructionSetName, modelConfigIdentity, project) : undefined;
1826
+ if (instructionSetProfileVersionId)
1827
+ dispatch.environment.ORIZU_INSTRUCTION_SET_PROFILE_VERSION_ID = instructionSetProfileVersionId;
1848
1828
  selectedEngine = dispatch.engine;
1849
- result = spawnSync(python, ['-m', dispatch.module, ...dispatch.args], {
1850
- stdio: 'inherit',
1851
- env: dispatch.environment,
1852
- });
1829
+ const launch = prepareSkilledProposerLaunch(python, dispatch.engine, dispatch.environment);
1830
+ result = spawnSync(launch.python, ['-m', dispatch.module, ...dispatch.args], { stdio: 'inherit', env: launch.environment });
1853
1831
  }
1854
1832
  finally {
1855
1833
  verified.cleanup();
@@ -4453,7 +4431,7 @@ async function downloadAnnotations() {
4453
4431
  }
4454
4432
  printLine(`Saved ${format.toUpperCase()} export to ${sanitizeTerminalText(filename)}`);
4455
4433
  }
4456
- function readRunnerManifest(runnerDir) {
4434
+ export function readRunnerManifest(runnerDir) {
4457
4435
  const manifestPath = join(runnerDir, 'manifest.json');
4458
4436
  const raw = readSourceFile(manifestPath);
4459
4437
  const manifest = JSON.parse(raw);
@@ -4471,9 +4449,9 @@ function readRunnerManifest(runnerDir) {
4471
4449
  supports_body_kind: supportedBodyKinds,
4472
4450
  };
4473
4451
  }
4474
- const RUNNER_TIMEOUT_MS = 120_000;
4475
- const RUNNER_OUTPUT_MAX_BYTES = 2 * 1024 * 1024;
4476
- const RUNNER_ENV_ALLOWLIST = new Set([
4452
+ export const RUNNER_TIMEOUT_MS = 120_000;
4453
+ export const RUNNER_OUTPUT_MAX_BYTES = 2 * 1024 * 1024;
4454
+ export const RUNNER_ENV_ALLOWLIST = new Set([
4477
4455
  'PATH',
4478
4456
  'SystemRoot',
4479
4457
  'WINDIR',
@@ -4490,7 +4468,7 @@ const RUNNER_ENV_ALLOWLIST = new Set([
4490
4468
  'GEMINI_API_KEY',
4491
4469
  'GOOGLE_API_KEY',
4492
4470
  ]);
4493
- function runnerSubprocessEnv(inputPath, outputPath) {
4471
+ export function runnerSubprocessEnv(inputPath, outputPath, instructionSetDir) {
4494
4472
  const env = {};
4495
4473
  for (const key of RUNNER_ENV_ALLOWLIST) {
4496
4474
  const value = process.env[key];
@@ -4500,6 +4478,9 @@ function runnerSubprocessEnv(inputPath, outputPath) {
4500
4478
  }
4501
4479
  env.ORIZU_RUNNER_INPUT_PATH = inputPath;
4502
4480
  env.ORIZU_RUNNER_OUTPUT_PATH = outputPath;
4481
+ delete env.ORIZU_INSTRUCTION_SET_DIR;
4482
+ if (instructionSetDir)
4483
+ env.ORIZU_INSTRUCTION_SET_DIR = instructionSetDir;
4503
4484
  return env;
4504
4485
  }
4505
4486
  function boundedRunnerOutput(value) {
@@ -4511,7 +4492,7 @@ function boundedRunnerOutput(value) {
4511
4492
  }
4512
4493
  return `${buffer.subarray(0, RUNNER_OUTPUT_MAX_BYTES).toString('utf8')}\n[truncated]`;
4513
4494
  }
4514
- async function materializeRunnerVersion(runnerVersionId) {
4495
+ export async function materializeRunnerVersion(runnerVersionId) {
4515
4496
  const response = await authedFetch(`/api/cli/runner-versions/${encodeURIComponent(runnerVersionId)}/download`);
4516
4497
  if (!response.ok) {
4517
4498
  throw new Error(`Failed to download runner version: ${await response.text()}`);
@@ -4608,15 +4589,15 @@ async function runnersExec() {
4608
4589
  const tempDir = mkdtempSync(join(tmpdir(), 'orizu-runner-'));
4609
4590
  const inputPath = join(tempDir, 'input.json');
4610
4591
  const outputPath = join(tempDir, 'output.json');
4592
+ const instructionSetDir = context.instructionSet ? join(tempDir, 'instruction-set') : undefined;
4611
4593
  try {
4612
4594
  const modelOutput = row.row.model_output ?? row.row.modelOutput ?? row.row.output ?? null;
4595
+ if (instructionSetDir && context.instructionSet)
4596
+ syncToDisk(instructionSetDir, runnerInstructionSetSyncSet(context.instructionSet));
4613
4597
  writeFileSync(inputPath, JSON.stringify({
4614
4598
  row: row.row,
4615
- prompt: {
4616
- body: context.prompt.body,
4617
- body_kind: context.prompt.bodyKind,
4618
- provider_settings: context.prompt.providerSettings,
4619
- },
4599
+ prompt: runnerInputPrompt(context.prompt),
4600
+ ...(context.instructionSet ? { instruction_set: runnerInputInstructionSet(context.instructionSet) } : {}),
4620
4601
  subject: scorerVersion
4621
4602
  ? {
4622
4603
  type: 'scorer_row',
@@ -4643,7 +4624,7 @@ async function runnersExec() {
4643
4624
  }));
4644
4625
  const result = spawnSync(manifest.command[0], manifest.command.slice(1), {
4645
4626
  cwd: runnerDir,
4646
- env: runnerSubprocessEnv(inputPath, outputPath),
4627
+ env: runnerSubprocessEnv(inputPath, outputPath, instructionSetDir),
4647
4628
  encoding: 'utf8',
4648
4629
  maxBuffer: RUNNER_OUTPUT_MAX_BYTES,
4649
4630
  timeout: RUNNER_TIMEOUT_MS,
@@ -4839,8 +4820,11 @@ export async function main(rawArgs = process.argv.slice(2)) {
4839
4820
  return;
4840
4821
  }
4841
4822
  if (command === 'prompts' && subcommand === 'push') {
4842
- await pushPromptArtifact('prompt');
4843
- return;
4823
+ if (getArg('--session')) {
4824
+ await pushPromptArtifact('prompt');
4825
+ return;
4826
+ }
4827
+ refusePromptMutation('push <manifest> --project <team/project>');
4844
4828
  }
4845
4829
  if (command === 'prompts' && subcommand === 'report' &&
4846
4830
  (cliArgs[2] === 'set' || cliArgs[2] === 'upload')) {
@@ -4850,15 +4834,23 @@ export async function main(rawArgs = process.argv.slice(2)) {
4850
4834
  return;
4851
4835
  }
4852
4836
  if (command === 'prompts' && subcommand === 'archive') {
4853
- await setPromptArchivedState(true);
4854
- return;
4837
+ refusePromptMutation('archive <slug-or-exact-name> --project <team/project>');
4855
4838
  }
4856
4839
  if (command === 'prompts' && subcommand === 'restore') {
4857
- await setPromptArchivedState(false);
4858
- return;
4840
+ refusePromptMutation('restore <slug-or-exact-name> --project <team/project>');
4859
4841
  }
4860
4842
  if (command === 'prompts' && subcommand === 'labels' && cliArgs[2] === 'set') {
4861
- await setPromptLabel();
4843
+ if (getPositionalArg(4) === 'production') {
4844
+ refusePromptMutation('profiles promote <set> --project <team/project> --model-config <identity> --version <n>');
4845
+ }
4846
+ await setPromptLabel({
4847
+ getArg,
4848
+ getPositionalArg,
4849
+ json: hasJsonFlag(),
4850
+ printJson,
4851
+ printLine,
4852
+ resolveProjectSlug,
4853
+ });
4862
4854
  return;
4863
4855
  }
4864
4856
  if (command === 'prompts' && subcommand === 'scorers' && cliArgs[2] === 'set-headline') {
@@ -4899,25 +4891,20 @@ export async function main(rawArgs = process.argv.slice(2)) {
4899
4891
  });
4900
4892
  return;
4901
4893
  }
4902
- if (command === 'scorers' && subcommand === 'list') {
4903
- await listScorers();
4904
- return;
4905
- }
4906
- if (command === 'scorers' && subcommand === 'register') {
4907
- await registerScorer();
4908
- return;
4909
- }
4910
- if (command === 'scorers' && subcommand === 'detail') {
4911
- await showScorerDetail();
4912
- return;
4913
- }
4914
- if (command === 'scorers' && subcommand === 'labels' && cliArgs[2] === 'set') {
4915
- await setScorerLabel();
4916
- return;
4917
- }
4918
- if (command === 'scorers' && subcommand === 'exec') {
4919
- await execScorer();
4920
- return;
4894
+ if (command === 'scorers') {
4895
+ const scorersExit = await scorersCommand(cliArgs, {
4896
+ list: listScorers, register: registerScorer, detail: showScorerDetail,
4897
+ labelsSet: setScorerLabel, exec: execScorer,
4898
+ verifyParity: args => verifyScorerParityCommand(args, {
4899
+ json: hasJsonFlag(), print: printLine, printErr: printError,
4900
+ materializeRunnerVersion, readRunnerManifest, runnerSubprocessEnv,
4901
+ timeoutMs: RUNNER_TIMEOUT_MS, maxOutputBytes: RUNNER_OUTPUT_MAX_BYTES,
4902
+ }),
4903
+ });
4904
+ if (scorersExit !== null) {
4905
+ process.exitCode = scorersExit;
4906
+ return;
4907
+ }
4921
4908
  }
4922
4909
  if ((command === 'runners' || command === 'optimizers') && subcommand === 'push') {
4923
4910
  await pushRunnerArtifact(command === 'runners' ? 'runner' : 'optimizer');
@@ -4969,6 +4956,12 @@ export async function main(rawArgs = process.argv.slice(2)) {
4969
4956
  await listOptimizationRunsCommand(cliArgs.slice(2), { json: hasJsonFlag(), print: printLine, resolveProjectSlug });
4970
4957
  return;
4971
4958
  }
4959
+ if (command === 'optimizations' && subcommand === 'promote') {
4960
+ await promoteOptimizationCommand(cliArgs.slice(2), {
4961
+ json: hasJsonFlag(), print: printLine, resolveProjectSlug, fetcher: authedFetch,
4962
+ });
4963
+ return;
4964
+ }
4972
4965
  if (command === 'optimizations' &&
4973
4966
  (subcommand === 'pause' ||
4974
4967
  subcommand === 'resume' ||
@@ -5135,9 +5128,12 @@ export async function main(rawArgs = process.argv.slice(2)) {
5135
5128
  await runGithubLink(team, { print: printLine, fetcher: authedFetch, openUrl: openInBrowser, confirm: (org) => askYesNo(`Connect this team to GitHub org '${org}'?`, true) });
5136
5129
  return;
5137
5130
  }
5138
- if (command === 'connectors' || command === 'manifests') {
5139
- const moduleCommand = command === 'connectors' ? connectorsCommand : manifestsCommand;
5140
- process.exitCode = await moduleCommand(cliArgs.slice(1), { json: hasJsonFlag(), print: printLine, resolveProjectSlug });
5131
+ if (command === 'connectors' || command === 'manifests' || command === 'model-configs') {
5132
+ process.exitCode = await (command === 'connectors' ? connectorsCommand : command === 'manifests' ? manifestsCommand : modelConfigsCommand)(cliArgs.slice(1), { json: hasJsonFlag(), print: printLine, resolveProjectSlug });
5133
+ return;
5134
+ }
5135
+ if (command === 'instructions' || command === 'instruction-sets') {
5136
+ process.exitCode = await instructionSetsCommand(cliArgs.slice(1), { json: hasJsonFlag(), print: printLine, resolveProjectSlug });
5141
5137
  return;
5142
5138
  }
5143
5139
  if (command === 'team' && (subcommand === 'kill-agents' || subcommand === 'release-agents')) {
@@ -0,0 +1,3 @@
1
+ /** Resolve the same production-or-default tuple served for a model identity. */
2
+ export declare function resolveGepaInstructionSetProfileVersion(instructionSetName: string, modelConfigIdentity: string, project: string): Promise<string>;
3
+ //# sourceMappingURL=instruction-set-gepa-launch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"instruction-set-gepa-launch.d.ts","sourceRoot":"","sources":["../src/instruction-set-gepa-launch.ts"],"names":[],"mappings":"AAaA,gFAAgF;AAChF,wBAAsB,uCAAuC,CAC3D,kBAAkB,EAAE,MAAM,EAC1B,mBAAmB,EAAE,MAAM,EAC3B,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,MAAM,CAAC,CASjB"}
@@ -0,0 +1,15 @@
1
+ import { authedFetch } from './http.js';
2
+ import { parseJsonResponse } from './json-response.js';
3
+ /** Resolve the same production-or-default tuple served for a model identity. */
4
+ export async function resolveGepaInstructionSetProfileVersion(instructionSetName, modelConfigIdentity, project) {
5
+ const response = await authedFetch(`/api/cli/instruction-sets/${encodeURIComponent(instructionSetName)}?project=${encodeURIComponent(project)}`);
6
+ if (!response.ok)
7
+ throw new Error(`Instruction set resolution failed: ${await response.text()}`);
8
+ const payload = await parseJsonResponse(response, 'Instruction set resolution');
9
+ const instructionSet = payload.instructionSet;
10
+ const profile = instructionSet?.profiles?.find(candidate => candidate.modelConfigIdentity === modelConfigIdentity);
11
+ const profileVersionId = profile?.production?.profileVersionId || instructionSet?.default?.profileVersionId;
12
+ if (!profileVersionId)
13
+ throw new Error('instruction_set_profile_version_unresolvable');
14
+ return profileVersionId;
15
+ }
@@ -0,0 +1,6 @@
1
+ export declare class InstructionSetLoaderError extends Error {
2
+ readonly code: string;
3
+ constructor(code: string);
4
+ }
5
+ export declare function loadInstructionSet(directory: string, name: string, modelConfigIdentity: string): Record<string, string>;
6
+ //# sourceMappingURL=instruction-set-loader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"instruction-set-loader.d.ts","sourceRoot":"","sources":["../src/instruction-set-loader.ts"],"names":[],"mappings":"AAGA,qBAAa,yBAA0B,SAAQ,KAAK;IACtC,QAAQ,CAAC,IAAI,EAAE,MAAM;gBAAZ,IAAI,EAAE,MAAM;CAClC;AAOD,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,mBAAmB,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAwBvH"}
@@ -0,0 +1,59 @@
1
+ import { existsSync, realpathSync, readFileSync, statSync } from 'node:fs';
2
+ import { resolve, sep } from 'node:path';
3
+ export class InstructionSetLoaderError extends Error {
4
+ code;
5
+ constructor(code) {
6
+ super(code);
7
+ this.code = code;
8
+ this.name = 'InstructionSetLoaderError';
9
+ }
10
+ }
11
+ function inside(root, candidate) { return candidate === root || candidate.startsWith(`${root}${sep}`); }
12
+ export function loadInstructionSet(directory, name, modelConfigIdentity) {
13
+ const unresolvedRoot = resolve(directory, name);
14
+ if (!existsSync(unresolvedRoot) || !statSync(unresolvedRoot).isDirectory())
15
+ throw new InstructionSetLoaderError('instruction_set_not_synced');
16
+ const setRoot = realpathSync(unresolvedRoot);
17
+ const manifestPath = resolve(setRoot, 'manifest.json');
18
+ if (!existsSync(manifestPath))
19
+ throw new InstructionSetLoaderError('instruction_set_manifest_missing');
20
+ let manifest;
21
+ try {
22
+ manifest = JSON.parse(readFileSync(manifestPath, 'utf8'));
23
+ }
24
+ catch {
25
+ throw new InstructionSetLoaderError('instruction_set_manifest_missing');
26
+ }
27
+ if (manifest.manifestVersion !== 1)
28
+ throw new InstructionSetLoaderError('instruction_set_manifest_version_unsupported');
29
+ if (manifest.filteredTo && !manifest.filteredTo.includes(modelConfigIdentity))
30
+ throw new InstructionSetLoaderError('instruction_set_profile_not_synced');
31
+ const selected = manifest.profiles.find(profile => profile.modelConfigIdentity === modelConfigIdentity)?.production || manifest.default;
32
+ const result = {};
33
+ for (const key of manifest.shape) {
34
+ if (selected.pinnedComponents?.[key])
35
+ throw new InstructionSetLoaderError('instruction_set_component_unavailable');
36
+ const relativePath = selected.files?.[key];
37
+ if (!relativePath)
38
+ throw new InstructionSetLoaderError('instruction_set_profile_key_missing');
39
+ const unresolvedPath = resolve(setRoot, relativePath);
40
+ if (!inside(setRoot, unresolvedPath))
41
+ throw new InstructionSetLoaderError('instruction_set_path_unsafe');
42
+ let path;
43
+ try {
44
+ path = realpathSync(unresolvedPath);
45
+ }
46
+ catch {
47
+ throw new InstructionSetLoaderError('instruction_set_component_unreadable');
48
+ }
49
+ if (!inside(setRoot, path))
50
+ throw new InstructionSetLoaderError('instruction_set_path_unsafe');
51
+ try {
52
+ result[key] = readFileSync(path, 'utf8');
53
+ }
54
+ catch {
55
+ throw new InstructionSetLoaderError('instruction_set_component_unreadable');
56
+ }
57
+ }
58
+ return result;
59
+ }
@@ -0,0 +1,14 @@
1
+ export interface InstructionSetComponent {
2
+ key: string;
3
+ modelConfig?: string;
4
+ text: string;
5
+ }
6
+ export interface InstructionSetManifest {
7
+ name: string;
8
+ description?: string | null;
9
+ shape: string[];
10
+ components: InstructionSetComponent[];
11
+ }
12
+ export declare const MAX_INSTRUCTION_SET_COMPONENT_BYTES: number;
13
+ export declare function loadInstructionSetManifest(path: string): InstructionSetManifest;
14
+ //# sourceMappingURL=instruction-set-manifest.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"instruction-set-manifest.d.ts","sourceRoot":"","sources":["../src/instruction-set-manifest.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,uBAAuB;IAAG,GAAG,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE;AAC5F,MAAM,WAAW,sBAAsB;IAAG,IAAI,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,KAAK,EAAE,MAAM,EAAE,CAAC;IAAC,UAAU,EAAE,uBAAuB,EAAE,CAAA;CAAE;AAI7I,eAAO,MAAM,mCAAmC,QAAa,CAAA;AAW7D,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,MAAM,GAAG,sBAAsB,CAmG/E"}
@@ -0,0 +1,162 @@
1
+ import { existsSync, readFileSync, realpathSync } from 'node:fs';
2
+ import { dirname, isAbsolute, relative, resolve } from 'node:path';
3
+ import { createHash } from 'node:crypto';
4
+ // Keep file-backed component reads within the same text budget used by prompt
5
+ // tooling; request assembly never asks Node to allocate an unbounded body.
6
+ export const MAX_INSTRUCTION_SET_COMPONENT_BYTES = 512 * 1024;
7
+ const fail = (code) => { throw new Error(code); };
8
+ const sha256 = (value) => createHash('sha256').update(value, 'utf8').digest('hex');
9
+ function hasPinnedComponents(material) {
10
+ if (!material || typeof material !== 'object')
11
+ return false;
12
+ const pinned = material.pinnedComponents;
13
+ return Boolean(pinned && typeof pinned === 'object' && Object.keys(pinned).length > 0);
14
+ }
15
+ export function loadInstructionSetManifest(path) {
16
+ let value;
17
+ let source;
18
+ try {
19
+ source = readFileSync(path, 'utf8');
20
+ }
21
+ catch {
22
+ return fail('instruction_set_path_not_found');
23
+ }
24
+ try {
25
+ value = JSON.parse(source);
26
+ }
27
+ catch {
28
+ return fail('instruction_set_manifest_invalid_json');
29
+ }
30
+ if (!value || typeof value !== 'object')
31
+ return fail('instruction_set_manifest_invalid');
32
+ const input = value;
33
+ if (typeof input.name !== 'string' || input.name.trim() === '')
34
+ return fail('instruction_set_manifest_invalid_name');
35
+ const hasDescription = Object.hasOwn(input, 'description');
36
+ if (hasDescription && input.description !== null && typeof input.description !== 'string')
37
+ return fail('instruction_set_manifest_invalid_description');
38
+ const description = hasDescription
39
+ ? input.description === '' ? null : input.description
40
+ : undefined;
41
+ if (hasPinnedComponents(input.default))
42
+ return fail('instruction_set_component_unavailable');
43
+ if (!Array.isArray(input.shape) || input.shape.length === 0 || input.shape.some(key => typeof key !== 'string' || key === '') || new Set(input.shape).size !== input.shape.length)
44
+ return fail('instruction_set_manifest_invalid_shape');
45
+ if (!Array.isArray(input.components))
46
+ return fail('instruction_set_manifest_invalid_components');
47
+ let root;
48
+ try {
49
+ root = realpathSync(dirname(path));
50
+ }
51
+ catch {
52
+ return fail('instruction_set_path_not_found');
53
+ }
54
+ const seen = new Set();
55
+ const loadedComponents = [];
56
+ for (const raw of input.components) {
57
+ if (!raw || typeof raw !== 'object')
58
+ return fail('instruction_set_manifest_invalid_component');
59
+ const component = raw;
60
+ if (typeof component.key !== 'string' || component.key === '' || !input.shape.includes(component.key))
61
+ return fail(component.key && !input.shape.includes(component.key) ? 'instruction_set_key_outside_shape' : 'instruction_set_manifest_invalid_component');
62
+ const modelConfig = component.modelConfig === undefined ? undefined : component.modelConfig;
63
+ if (modelConfig !== undefined && (typeof modelConfig !== 'string' || modelConfig === ''))
64
+ return fail('instruction_set_manifest_invalid_component');
65
+ const identity = `${component.key}\u0000${modelConfig ?? ''}`;
66
+ if (seen.has(identity))
67
+ return fail('instruction_set_duplicate_component');
68
+ seen.add(identity);
69
+ let text;
70
+ if (typeof component.text === 'string' && component.path === undefined)
71
+ text = component.text;
72
+ else if (typeof component.path === 'string' && component.text === undefined) {
73
+ if (isAbsolute(component.path))
74
+ return fail('instruction_set_path_escape');
75
+ const candidate = resolve(root, component.path);
76
+ if (relative(root, candidate).startsWith('..'))
77
+ return fail('instruction_set_path_escape');
78
+ if (!existsSync(candidate))
79
+ return fail('instruction_set_path_not_found');
80
+ let target;
81
+ try {
82
+ target = realpathSync(candidate);
83
+ }
84
+ catch {
85
+ return fail('instruction_set_path_not_found');
86
+ }
87
+ if (relative(root, target).startsWith('..'))
88
+ return fail('instruction_set_path_escape');
89
+ try {
90
+ text = readFileSync(target, 'utf8');
91
+ }
92
+ catch {
93
+ return fail('instruction_set_path_not_found');
94
+ }
95
+ if (Buffer.byteLength(text, 'utf8') > MAX_INSTRUCTION_SET_COMPONENT_BYTES)
96
+ return fail('instruction_set_component_too_large');
97
+ }
98
+ else
99
+ return fail('instruction_set_manifest_invalid_component');
100
+ if (Buffer.byteLength(text, 'utf8') > MAX_INSTRUCTION_SET_COMPONENT_BYTES)
101
+ return fail('instruction_set_component_too_large');
102
+ const hasSyncBaseline = typeof component.syncedContentSha256 === 'string';
103
+ if (component.syncedContentSha256 !== undefined && (!hasSyncBaseline || !/^[a-f0-9]{64}$/u.test(component.syncedContentSha256)))
104
+ return fail('instruction_set_manifest_invalid_component');
105
+ loadedComponents.push({
106
+ key: component.key,
107
+ ...(modelConfig === undefined ? {} : { modelConfig }),
108
+ text,
109
+ hasSyncBaseline,
110
+ changedSinceSync: hasSyncBaseline && sha256(text) !== component.syncedContentSha256,
111
+ });
112
+ }
113
+ for (const key of input.shape)
114
+ if (!loadedComponents.some(component => component.key === key))
115
+ return fail('instruction_set_missing_shape_key');
116
+ const defaultIdentity = input.default && typeof input.default === 'object'
117
+ && typeof input.default.modelConfigIdentity === 'string'
118
+ ? input.default.modelConfigIdentity
119
+ : null;
120
+ let components = loadedComponents;
121
+ if (defaultIdentity) {
122
+ if (input.manifestVersion === 1 && input.shape.some(key => {
123
+ const bare = loadedComponents.find(component => component.key === key && component.modelConfig === undefined);
124
+ const tagged = loadedComponents.find(component => component.key === key && component.modelConfig === defaultIdentity);
125
+ return bare && tagged && (!bare.hasSyncBaseline || !tagged.hasSyncBaseline);
126
+ }))
127
+ return fail('instruction_set_sync_baseline_missing');
128
+ const changedDefaultKeys = new Set(loadedComponents.flatMap(component => (component.modelConfig === undefined && component.hasSyncBaseline && component.changedSinceSync
129
+ ? [component.key]
130
+ : [])));
131
+ const changedSameIdentityKeys = new Set(loadedComponents.flatMap(component => (component.modelConfig === defaultIdentity && component.hasSyncBaseline && component.changedSinceSync
132
+ ? [component.key]
133
+ : [])));
134
+ if ([...changedDefaultKeys].some(key => changedSameIdentityKeys.has(key)))
135
+ return fail('instruction_set_conflicting_synced_edits');
136
+ if (changedDefaultKeys.size > 0) {
137
+ components = loadedComponents.filter(component => (component.modelConfig !== defaultIdentity || !changedDefaultKeys.has(component.key)));
138
+ }
139
+ }
140
+ const namedProfiles = new Set([
141
+ ...(components.some(component => component.modelConfig === undefined) && defaultIdentity
142
+ ? [defaultIdentity]
143
+ : []),
144
+ ...components.flatMap(component => component.modelConfig ? [component.modelConfig] : []),
145
+ ]);
146
+ const namedProfileHasPins = Array.isArray(input.profiles) && input.profiles.some(profile => {
147
+ if (!profile || typeof profile !== 'object')
148
+ return false;
149
+ const value = profile;
150
+ return typeof value.modelConfigIdentity === 'string'
151
+ && namedProfiles.has(value.modelConfigIdentity)
152
+ && hasPinnedComponents(value.production);
153
+ });
154
+ if (namedProfileHasPins)
155
+ return fail('instruction_set_component_unavailable');
156
+ return {
157
+ name: input.name,
158
+ ...(hasDescription ? { description } : {}),
159
+ shape: input.shape,
160
+ components: components.map(({ key, modelConfig, text }) => ({ key, ...(modelConfig === undefined ? {} : { modelConfig }), text })),
161
+ };
162
+ }
@@ -0,0 +1,40 @@
1
+ import { renameSync, writeFileSync } from 'node:fs';
2
+ export interface InstructionSetsCommandIo {
3
+ json: boolean;
4
+ print: (line: string) => void;
5
+ resolveProjectSlug: (provided: string | null) => Promise<string>;
6
+ }
7
+ export interface SyncComponent {
8
+ body?: string;
9
+ repoPath?: string;
10
+ contentSha?: string;
11
+ commitSha?: string;
12
+ }
13
+ export interface SyncMaterial {
14
+ profileVersionId: string;
15
+ versionNumber: number;
16
+ modelConfigIdentity: string;
17
+ resolvedFrom: string;
18
+ components: Record<string, SyncComponent>;
19
+ }
20
+ export interface SyncProfile {
21
+ modelConfigIdentity: string;
22
+ resolvedFrom: string;
23
+ production: SyncMaterial | null;
24
+ }
25
+ export interface SyncSet {
26
+ name: string;
27
+ slug?: string;
28
+ description?: string | null;
29
+ shape: string[];
30
+ default: SyncMaterial;
31
+ profiles: SyncProfile[];
32
+ filteredTo?: string[];
33
+ }
34
+ export interface SyncFileOps {
35
+ writeFileSync: typeof writeFileSync;
36
+ renameSync?: typeof renameSync;
37
+ }
38
+ export declare function syncToDisk(out: string, set: SyncSet, fileOps?: SyncFileOps): void;
39
+ export declare function instructionSetsCommand(args: string[], io: InstructionSetsCommandIo): Promise<number>;
40
+ //# sourceMappingURL=instruction-sets-cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"instruction-sets-cli.d.ts","sourceRoot":"","sources":["../src/instruction-sets-cli.ts"],"names":[],"mappings":"AAGA,OAAO,EAAuC,UAAU,EAAoB,aAAa,EAAE,MAAM,SAAS,CAAA;AAI1G,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,OAAO,CAAA;IACb,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;IAC7B,kBAAkB,EAAE,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,KAAK,OAAO,CAAC,MAAM,CAAC,CAAA;CACjE;AA+BD,MAAM,WAAW,aAAa;IAAG,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE;AAC5G,MAAM,WAAW,YAAY;IAAG,gBAAgB,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAC;IAAC,mBAAmB,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAA;CAAE;AAC/K,MAAM,WAAW,WAAW;IAAG,mBAAmB,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,YAAY,GAAG,IAAI,CAAA;CAAE;AACnH,MAAM,WAAW,OAAO;IAAG,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,KAAK,EAAE,MAAM,EAAE,CAAC;IAAC,OAAO,EAAE,YAAY,CAAC;IAAC,QAAQ,EAAE,WAAW,EAAE,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,EAAE,CAAA;CAAE;AAM7K,MAAM,WAAW,WAAW;IAAG,aAAa,EAAE,OAAO,aAAa,CAAC;IAAC,UAAU,CAAC,EAAE,OAAO,UAAU,CAAA;CAAE;AAoCpG,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,OAAO,GAAE,WAA+B,QAyC7F;AAED,wBAAsB,sBAAsB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,wBAAwB,GAAG,OAAO,CAAC,MAAM,CAAC,CA+K1G"}