orizu 0.5.39 → 0.5.41
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.
- package/README.md +77 -0
- package/dist/dataset-clone-workflow.d.ts +11 -0
- package/dist/dataset-clone-workflow.d.ts.map +1 -0
- package/dist/dataset-clone-workflow.js +100 -0
- package/dist/dataset-commands.d.ts +3 -1
- package/dist/dataset-commands.d.ts.map +1 -1
- package/dist/dataset-commands.js +107 -91
- package/dist/dataset-delete-workflow.d.ts +4 -0
- package/dist/dataset-delete-workflow.d.ts.map +1 -0
- package/dist/dataset-delete-workflow.js +75 -0
- package/dist/dataset-lock-workflow.d.ts +12 -0
- package/dist/dataset-lock-workflow.d.ts.map +1 -0
- package/dist/dataset-lock-workflow.js +76 -0
- package/dist/dataset-readme-workflow.d.ts +13 -0
- package/dist/dataset-readme-workflow.d.ts.map +1 -0
- package/dist/dataset-readme-workflow.js +82 -0
- package/dist/dataset-row-workflow.d.ts +14 -0
- package/dist/dataset-row-workflow.d.ts.map +1 -0
- package/dist/dataset-row-workflow.js +202 -0
- package/dist/dataset-split-reads.d.ts +28 -0
- package/dist/dataset-split-reads.d.ts.map +1 -0
- package/dist/dataset-split-reads.js +47 -0
- package/dist/dataset-transfer-upload.d.ts +2 -6
- package/dist/dataset-transfer-upload.d.ts.map +1 -1
- package/dist/dataset-transfer-upload.js +9 -2
- package/dist/dataset-upload-snapshot.d.ts.map +1 -1
- package/dist/dataset-upload-snapshot.js +7 -1
- package/dist/dataset-version-workflow.d.ts +24 -0
- package/dist/dataset-version-workflow.d.ts.map +1 -0
- package/dist/dataset-version-workflow.js +99 -0
- package/dist/feedback-cli.js +3 -3
- package/dist/help.d.ts.map +1 -1
- package/dist/help.js +29 -3
- package/dist/hosted-boot.d.ts +1 -0
- package/dist/hosted-boot.d.ts.map +1 -1
- package/dist/hosted-boot.js +17 -0
- package/dist/hosted-harness-opencode.d.ts +5 -6
- package/dist/hosted-harness-opencode.d.ts.map +1 -1
- package/dist/hosted-harness-opencode.js +73 -59
- package/dist/hosted-loop-lifecycle.d.ts +6 -11
- package/dist/hosted-loop-lifecycle.d.ts.map +1 -1
- package/dist/hosted-loop-lifecycle.js +6 -11
- package/dist/hosted-loop.d.ts +9 -0
- package/dist/hosted-loop.d.ts.map +1 -1
- package/dist/hosted-loop.js +19 -10
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +11 -3
- package/dist/instruction-delivery.d.ts +14 -0
- package/dist/instruction-delivery.d.ts.map +1 -0
- package/dist/instruction-delivery.js +103 -0
- package/dist/instruction-set-sync/index.d.ts +17 -0
- package/dist/instruction-set-sync/index.d.ts.map +1 -1
- package/dist/instruction-set-sync/index.js +44 -17
- package/dist/instruction-set-update/index.d.ts +2 -2
- package/dist/instruction-set-update/index.d.ts.map +1 -1
- package/dist/instruction-set-update/index.js +2 -2
- package/dist/instruction-sets-cli.d.ts.map +1 -1
- package/dist/instruction-sets-cli.js +19 -27
- package/dist/json-response.d.ts +1 -0
- package/dist/json-response.d.ts.map +1 -1
- package/dist/json-response.js +7 -0
- package/dist/last-error-record.d.ts +4 -2
- package/dist/last-error-record.d.ts.map +1 -1
- package/dist/last-error-record.js +10 -68
- package/dist/last-error-workflow.d.ts +4 -0
- package/dist/last-error-workflow.d.ts.map +1 -0
- package/dist/last-error-workflow.js +78 -0
- package/dist/preview-runtime.d.ts +2 -2
- package/dist/preview-runtime.d.ts.map +1 -1
- package/dist/preview-runtime.js +37 -7
- package/dist/task-commands.d.ts.map +1 -1
- package/dist/task-commands.js +9 -16
- package/dist/task-export-workflow.d.ts +4 -0
- package/dist/task-export-workflow.d.ts.map +1 -0
- package/dist/task-export-workflow.js +46 -0
- package/dist/task-report-workflow.d.ts +47 -0
- package/dist/task-report-workflow.d.ts.map +1 -0
- package/dist/task-report-workflow.js +160 -0
- package/dist/workbench-cli.js +1 -1
- package/package.json +1 -1
- package/src/dataset-clone-workflow.ts +100 -0
- package/src/dataset-commands.ts +95 -142
- package/src/dataset-delete-workflow.ts +72 -0
- package/src/dataset-lock-workflow.ts +74 -0
- package/src/dataset-readme-workflow.ts +80 -0
- package/src/dataset-row-workflow.ts +248 -0
- package/src/dataset-split-reads.ts +43 -0
- package/src/dataset-transfer-upload.ts +12 -5
- package/src/dataset-upload-snapshot.ts +8 -1
- package/src/dataset-version-workflow.ts +105 -0
- package/src/feedback-cli.ts +4 -4
- package/src/help.ts +29 -3
- package/src/hosted-boot.ts +16 -1
- package/src/hosted-harness-opencode.ts +74 -72
- package/src/hosted-loop-lifecycle.ts +6 -11
- package/src/hosted-loop.ts +20 -10
- package/src/hosted-model-cache.d.mts +2 -0
- package/src/hosted-model-cache.mjs +53 -0
- package/src/index.ts +12 -2
- package/src/instruction-delivery.ts +123 -0
- package/src/instruction-set-sync/index.ts +61 -14
- package/src/instruction-set-update/index.ts +4 -3
- package/src/instruction-sets-cli.ts +19 -27
- package/src/json-response.ts +8 -0
- package/src/last-error-record.ts +11 -85
- package/src/last-error-workflow.ts +121 -0
- package/src/preview-runtime.ts +40 -10
- package/src/task-commands.ts +9 -43
- package/src/task-export-workflow.ts +56 -0
- package/src/task-report-workflow.ts +179 -0
- package/src/workbench-cli.ts +1 -1
- package/vendor/skills/orizu/references/cli-reference.md +34 -0
- package/vendor/skills/orizu/references/dataset-design.md +1 -1
- package/dist/dataset-edit-rows.d.ts +0 -10
- package/dist/dataset-edit-rows.d.ts.map +0 -1
- package/dist/dataset-edit-rows.js +0 -90
- package/src/dataset-edit-rows.ts +0 -124
package/dist/hosted-loop.js
CHANGED
|
@@ -152,13 +152,21 @@ function detectLoopPrebaked(flag, markerPath) {
|
|
|
152
152
|
return flag === true || hasValidPrebakedMarker(markerPath);
|
|
153
153
|
}
|
|
154
154
|
/** Best-effort global install of the pinned opencode. Non-fatal: a failure is
|
|
155
|
-
* recorded and the run finishes cleanly when the subsequent connect fails.
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
155
|
+
* recorded and the run finishes cleanly when the subsequent connect fails.
|
|
156
|
+
* From 1.18 opencode's postinstall script writes the `opencode` command, and
|
|
157
|
+
* npm 12 blocks it unless allowed, leaving a placeholder that exits 1; so npm
|
|
158
|
+
* allows that one script and the result must print the pinned version
|
|
159
|
+
* (ORI-2523). `env` exists for tests. */
|
|
160
|
+
export function installOpenCodePinned(version, env) {
|
|
161
|
+
const command = `{ bun add -g opencode-ai@${version} >/dev/null 2>&1 || ` +
|
|
162
|
+
`npm install -g --allow-scripts=opencode-ai opencode-ai@${version} >/dev/null 2>&1; } && ` +
|
|
163
|
+
`v="$(opencode --version 2>/dev/null)" && [ "$v" = '${version}' ]`;
|
|
164
|
+
const res = spawnSync('bash', ['-c', command], { encoding: 'utf8', ...(env ? { env } : {}) });
|
|
160
165
|
const ok = (res.status ?? 1) === 0;
|
|
161
|
-
return {
|
|
166
|
+
return {
|
|
167
|
+
ok,
|
|
168
|
+
detail: ok ? `installed opencode-ai@${version}` : `install exit ${res.status ?? 'unknown'}, or opencode --version is not ${version}`,
|
|
169
|
+
};
|
|
162
170
|
}
|
|
163
171
|
/** Node child_process spawner for `opencode serve` (the sandbox runtime is
|
|
164
172
|
* node24 — Bun.spawn is not guaranteed present, so spawnOpenCode is given this
|
|
@@ -460,10 +468,9 @@ export async function runHostedLoop(opts) {
|
|
|
460
468
|
}
|
|
461
469
|
// Fail-fast model validation (ALI-1086): ask the RUNNING opencode whether
|
|
462
470
|
// the requested model is resolvable BEFORE the first prompt. The pinned
|
|
463
|
-
//
|
|
464
|
-
//
|
|
465
|
-
//
|
|
466
|
-
// stream with an opaque `run_failed: Model not found`. Now the run fails
|
|
471
|
+
// image catalog is baked and refreshed before spawn (ORI-2513). A model
|
|
472
|
+
// absent from that validated list still needs a clear error rather than
|
|
473
|
+
// dying inside the SSE stream with an opaque Model not found. The run fails
|
|
467
474
|
// immediately with a structured artifact + an error naming the requested
|
|
468
475
|
// id AND the resolvable alternatives. Fail-open on validator
|
|
469
476
|
// infrastructure: an unreachable catalog endpoint (`skipped`) proceeds
|
|
@@ -612,6 +619,8 @@ export async function runHostedLoop(opts) {
|
|
|
612
619
|
}
|
|
613
620
|
return;
|
|
614
621
|
}
|
|
622
|
+
if (event.kind !== 'question_auto_answered')
|
|
623
|
+
await opts.onProgress?.();
|
|
615
624
|
yield event;
|
|
616
625
|
}
|
|
617
626
|
// A signal already durable before prompt startup can make a driver end
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAwLA,OAAO,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAA;AAEhE,eAAO,MAAM,wBAAwB,GAAI,iBAAiB,MAAM;;;EACJ,CAAA;AAE5D,OAAO,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAA;AAC5E,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAA;AA4tCtD,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG;IAAE,OAAO,EAAE,MAAM,EAAE,CAAC;IAAC,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAA;CAAE,CA0B1G;AAED,eAAO,MAAM,iBAAiB,SAAU,CAAA;AACxC,eAAO,MAAM,uBAAuB,QAAkB,CAAA;AACtD,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,iBAAiB,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC,UAAU,CAexH;AAmMD,wBAAsB,IAAI,CAAC,OAAO,WAAwB,iBAiiBzD;AA6DD,OAAO,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAA;AAEhF,OAAO,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -52,7 +52,7 @@ import { acceptScoreRunCommand } from './scores-accept-cli.js';
|
|
|
52
52
|
import { exportOptimizationRunCommand } from './optimization-export-cli.js';
|
|
53
53
|
import { listOptimizationRunsCommand } from './optimizations-list-cli.js';
|
|
54
54
|
import { promoteOptimizationCommand } from './optimizations-promote-cli.js';
|
|
55
|
-
import { uploadDataset, listDatasets, pushDataset, downloadDataset, appendDatasetRows, setDatasetReadme, createDatasetVersion, createDatasetSplitSet, editDatasetRows, deleteDatasetRows, deleteDataset, lockDataset, cloneDataset, downloadAnnotations, } from './dataset-commands.js';
|
|
55
|
+
import { uploadDataset, listDatasets, pushDataset, downloadDataset, appendDatasetRows, setDatasetReadme, createDatasetVersion, createDatasetSplitSet, listDatasetSplitSets, showDatasetSplitSet, editDatasetRows, deleteDatasetRows, deleteDataset, lockDataset, cloneDataset, downloadAnnotations, } from './dataset-commands.js';
|
|
56
56
|
import { workbenchCommand } from './workbench-cli.js';
|
|
57
57
|
import { workspaceSyncCommand } from './workspace-sync.js';
|
|
58
58
|
import { runGitCredentialInvocation } from './git-credential.js';
|
|
@@ -1664,6 +1664,14 @@ export async function main(rawArgs = process.argv.slice(2)) {
|
|
|
1664
1664
|
await createDatasetVersion();
|
|
1665
1665
|
return;
|
|
1666
1666
|
}
|
|
1667
|
+
if (command === 'datasets' && subcommand === 'splits' && datasetsAction === 'list') {
|
|
1668
|
+
await listDatasetSplitSets();
|
|
1669
|
+
return;
|
|
1670
|
+
}
|
|
1671
|
+
if (command === 'datasets' && subcommand === 'splits' && datasetsAction === 'show') {
|
|
1672
|
+
await showDatasetSplitSet();
|
|
1673
|
+
return;
|
|
1674
|
+
}
|
|
1667
1675
|
if (command === 'datasets' && subcommand === 'splits' && datasetsAction === 'create') {
|
|
1668
1676
|
await createDatasetSplitSet();
|
|
1669
1677
|
return;
|
|
@@ -1786,10 +1794,10 @@ function isCliEntrypoint() {
|
|
|
1786
1794
|
}
|
|
1787
1795
|
if (isCliEntrypoint()) {
|
|
1788
1796
|
const rawArgs = process.argv.slice(2);
|
|
1789
|
-
withPassiveUpdateNotice(rawArgs, getCliVersion, printError, args => main(args).catch(error => {
|
|
1797
|
+
withPassiveUpdateNotice(rawArgs, getCliVersion, printError, args => main(args).catch(async (error) => {
|
|
1790
1798
|
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
1791
1799
|
// The reporter email is unknown on the failure path, so the record masks every address.
|
|
1792
|
-
writeLastErrorRecord({
|
|
1800
|
+
await writeLastErrorRecord({
|
|
1793
1801
|
argv: args,
|
|
1794
1802
|
message,
|
|
1795
1803
|
code: extractLastErrorCode(error),
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { type SyncDiskOptions, type SyncDiskResult, type SyncPayload, type SyncRequestPlan } from './instruction-set-sync/index.js';
|
|
2
|
+
import { type UpdatePlan, type UpdateResult } from './instruction-set-update/index.js';
|
|
3
|
+
export interface Interrupted {
|
|
4
|
+
interrupted: 130 | 143;
|
|
5
|
+
}
|
|
6
|
+
export declare function syncInstructionSet(out: string, project: string, plan: SyncRequestPlan, options: SyncDiskOptions): Promise<Interrupted | {
|
|
7
|
+
payload: SyncPayload;
|
|
8
|
+
result: SyncDiskResult;
|
|
9
|
+
}>;
|
|
10
|
+
export declare function updateInstructionSets(out: string, project: string, isApproved: boolean, noSync: boolean): Promise<{
|
|
11
|
+
plan: UpdatePlan;
|
|
12
|
+
result: UpdateResult;
|
|
13
|
+
} | Interrupted>;
|
|
14
|
+
//# sourceMappingURL=instruction-delivery.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"instruction-delivery.d.ts","sourceRoot":"","sources":["../src/instruction-delivery.ts"],"names":[],"mappings":"AAIA,OAAO,EAA0D,KAAK,eAAe,EAAE,KAAK,cAAc,EAAE,KAAK,WAAW,EAAE,KAAK,eAAe,EAAE,MAAM,iCAAiC,CAAA;AAC3L,OAAO,EAAsE,KAAK,UAAU,EAAE,KAAK,YAAY,EAAE,MAAM,mCAAmC,CAAA;AAK1J,MAAM,WAAW,WAAW;IAAG,WAAW,EAAE,GAAG,GAAG,GAAG,CAAA;CAAE;AAkEvD,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,eAAe,EAAE,OAAO,EAAE,eAAe;;;GAM/G;AAED,wBAAgB,qBAAqB,CACnC,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,OAAO,EACnB,MAAM,EAAE,OAAO,GACd,OAAO,CAAC;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,MAAM,EAAE,YAAY,CAAA;CAAE,GAAG,WAAW,CAAC,CAiCnE"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { Cause, Effect, Exit } from 'effect';
|
|
2
|
+
import { authedFetch } from './http.js';
|
|
3
|
+
import { responsePayload } from './json-response.js';
|
|
4
|
+
import { stageSyncPayload, startSyncLockClaim, tryClaimSyncLock } from './instruction-set-sync/index.js';
|
|
5
|
+
import { applyUpdate, lockedProfileIdentity, makeUpdatePlan, readUpdateLock } from './instruction-set-update/index.js';
|
|
6
|
+
// Existing file steps throw plain errors; keep them as the failure value so the
|
|
7
|
+
// CLI prints exactly the same message.
|
|
8
|
+
const attempt = (operation) => Effect.try({ try: operation, catch: cause => cause });
|
|
9
|
+
function readPayload(path, action) {
|
|
10
|
+
return Effect.tryPromise({
|
|
11
|
+
// The body stays unchecked here, as before: stageSyncPayload and makeUpdatePlan validate it.
|
|
12
|
+
// SAFETY: their existing error messages for malformed bodies are part of the CLI's output.
|
|
13
|
+
try: async (signal) => await responsePayload(await authedFetch(path, { method: 'GET', signal }), action),
|
|
14
|
+
catch: cause => cause,
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
// Waiting for another process's lock is the only interruptible part: nothing
|
|
18
|
+
// is held yet. Publishing runs to completion once the lock is ours.
|
|
19
|
+
function holdSyncLock(appRoot, use) {
|
|
20
|
+
const acquire = Effect.gen(function* () {
|
|
21
|
+
const claim = yield* attempt(() => startSyncLockClaim(appRoot));
|
|
22
|
+
while (true) {
|
|
23
|
+
const claimed = yield* attempt(() => tryClaimSyncLock(claim));
|
|
24
|
+
if (typeof claimed === 'function')
|
|
25
|
+
return claimed;
|
|
26
|
+
yield* Effect.interruptible(Effect.sleep(claimed));
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
return Effect.acquireUseRelease(acquire, () => use, release => Effect.sync(release));
|
|
30
|
+
}
|
|
31
|
+
// Stage the version, publish it under the lock, and always remove an
|
|
32
|
+
// unpublished stage, including after Ctrl-C or SIGTERM.
|
|
33
|
+
function deliverPayload(...args) {
|
|
34
|
+
return Effect.acquireUseRelease(attempt(() => stageSyncPayload(...args)), staged => holdSyncLock(staged.appRoot, attempt(staged.publish)).pipe(Effect.map(warnings => ({ destination: staged.destination, wasPresent: staged.wasPresent, warnings }))), staged => Effect.sync(staged.discard));
|
|
35
|
+
}
|
|
36
|
+
async function runOrThrow(program, signal) {
|
|
37
|
+
const exit = await Effect.runPromiseExit(program, { signal });
|
|
38
|
+
if (Exit.isSuccess(exit))
|
|
39
|
+
return exit.value;
|
|
40
|
+
throw Cause.squash(exit.cause);
|
|
41
|
+
}
|
|
42
|
+
// `once`: a second signal falls through to Node's default kill.
|
|
43
|
+
async function runDelivery(program) {
|
|
44
|
+
const controller = new AbortController();
|
|
45
|
+
let interrupted;
|
|
46
|
+
const handleInterrupt = () => { interrupted ??= 130; controller.abort(); };
|
|
47
|
+
const handleTerminate = () => { interrupted ??= 143; controller.abort(); };
|
|
48
|
+
process.once('SIGINT', handleInterrupt);
|
|
49
|
+
process.once('SIGTERM', handleTerminate);
|
|
50
|
+
try {
|
|
51
|
+
return await runOrThrow(program(controller.signal), controller.signal);
|
|
52
|
+
}
|
|
53
|
+
catch (error) {
|
|
54
|
+
if (interrupted !== undefined)
|
|
55
|
+
return { interrupted };
|
|
56
|
+
throw error;
|
|
57
|
+
}
|
|
58
|
+
finally {
|
|
59
|
+
process.removeListener('SIGINT', handleInterrupt);
|
|
60
|
+
process.removeListener('SIGTERM', handleTerminate);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
export function syncInstructionSet(out, project, plan, options) {
|
|
64
|
+
return runDelivery(() => Effect.gen(function* () {
|
|
65
|
+
const payload = yield* readPayload(plan.path, 'Instruction sets sync');
|
|
66
|
+
const result = yield* deliverPayload(out, project, plan, payload, options);
|
|
67
|
+
return { payload, result };
|
|
68
|
+
}));
|
|
69
|
+
}
|
|
70
|
+
export function updateInstructionSets(out, project, isApproved, noSync) {
|
|
71
|
+
const program = (signal) => Effect.gen(function* () {
|
|
72
|
+
const lock = yield* attempt(() => readUpdateLock(out, project));
|
|
73
|
+
const payloads = [];
|
|
74
|
+
for (const [setSlug, set] of Object.entries(lock.instructionSets)) {
|
|
75
|
+
const barePath = `/api/cli/instruction-sets/${encodeURIComponent(setSlug)}/sync?project=${encodeURIComponent(project)}`;
|
|
76
|
+
payloads.push(yield* readPayload(barePath, 'Instruction sets update'));
|
|
77
|
+
for (const profileSlugValue of Object.keys(set.profiles)) {
|
|
78
|
+
const identity = yield* attempt(() => lockedProfileIdentity(out, setSlug, profileSlugValue));
|
|
79
|
+
const query = new URLSearchParams({ project, profile: identity });
|
|
80
|
+
const path = `/api/cli/instruction-sets/${encodeURIComponent(setSlug)}/sync?${query.toString()}`;
|
|
81
|
+
payloads.push(yield* readPayload(path, 'Instruction sets update'));
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
const plan = yield* attempt(() => makeUpdatePlan(project, lock, payloads));
|
|
85
|
+
if (!isApproved)
|
|
86
|
+
return { plan, result: { absent: [], warnings: [] } };
|
|
87
|
+
// applyUpdate's own steps are not interruptible; each version it syncs is
|
|
88
|
+
// a nested delivery that the shared signal interrupts and cleans up.
|
|
89
|
+
const result = yield* Effect.uninterruptible(Effect.tryPromise({
|
|
90
|
+
try: () => applyUpdate(out, project, plan, noSync, undefined, (...args) => runOrThrow(deliverPayload(...args), signal)),
|
|
91
|
+
catch: cause => cause,
|
|
92
|
+
}));
|
|
93
|
+
return { plan, result };
|
|
94
|
+
});
|
|
95
|
+
// --no-sync stages nothing to clean up, so keep Node's default signal
|
|
96
|
+
// handling: a signal stops it at once instead of being held until the
|
|
97
|
+
// update has already landed.
|
|
98
|
+
if (noSync) {
|
|
99
|
+
const signal = new AbortController().signal;
|
|
100
|
+
return runOrThrow(program(signal), signal);
|
|
101
|
+
}
|
|
102
|
+
return runDelivery(program);
|
|
103
|
+
}
|
|
@@ -44,6 +44,13 @@ export declare function planSyncRequest(reference: string, versionFlag: string |
|
|
|
44
44
|
export declare function canonicalVersionDigest(components: Record<string, string>, settings: Record<string, unknown>): string;
|
|
45
45
|
export declare function recordResolvedPayloadInLock(lock: InstructionSetLockV1, payload: SyncPayload, now?: () => Date): InstructionSetLockV1;
|
|
46
46
|
export declare function renderGeneratedVersionModule(components: Record<string, string>, manifest: unknown): string;
|
|
47
|
+
export interface SyncLockClaim {
|
|
48
|
+
lockPath: string;
|
|
49
|
+
metadata: string;
|
|
50
|
+
deadline: number;
|
|
51
|
+
}
|
|
52
|
+
export declare function startSyncLockClaim(appRoot: string): SyncLockClaim;
|
|
53
|
+
export declare function tryClaimSyncLock({ lockPath, metadata, deadline }: SyncLockClaim): (() => void) | number;
|
|
47
54
|
export declare function withSyncLock<T>(appRoot: string, operation: () => T): T;
|
|
48
55
|
export interface SyncDiskResult {
|
|
49
56
|
destination: string;
|
|
@@ -57,5 +64,15 @@ export interface SyncDiskOptions {
|
|
|
57
64
|
target?: SyncTarget;
|
|
58
65
|
platform?: NodeJS.Platform;
|
|
59
66
|
}
|
|
67
|
+
export interface StagedSync {
|
|
68
|
+
appRoot: string;
|
|
69
|
+
destination: string;
|
|
70
|
+
wasPresent: boolean;
|
|
71
|
+
/** Publishes the staged version; the caller must hold the folder lock. Returns warnings. */
|
|
72
|
+
publish: () => string[];
|
|
73
|
+
/** Removes the staged version if it was not published. Safe to call more than once. */
|
|
74
|
+
discard: () => void;
|
|
75
|
+
}
|
|
60
76
|
export declare function syncPayloadToDisk(out: string, project: string, plan: SyncRequestPlan, payload: SyncPayload, options?: SyncDiskOptions): SyncDiskResult;
|
|
77
|
+
export declare function stageSyncPayload(out: string, project: string, plan: SyncRequestPlan, payload: SyncPayload, options?: SyncDiskOptions): StagedSync;
|
|
61
78
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/instruction-set-sync/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAML,KAAK,oBAAoB,EACzB,KAAK,eAAe,EACrB,MAAM,kCAAkC,CAAA;AAIzC,eAAO,MAAM,iBAAiB,OAAQ,CAAA;AAYtC,MAAM,MAAM,UAAU,GAAG,IAAI,CAAA;AAE7B,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,UAAU,CAIrE;AAED,MAAM,WAAW,eAAe;IAAG,IAAI,EAAE,MAAM,CAAA;CAAE;AACjD,MAAM,WAAW,oBAAoB;IACnC,gBAAgB,EAAE,MAAM,CAAA;IACxB,aAAa,EAAE,MAAM,CAAA;IACrB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAA;IAC3C,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IACjC,gBAAgB,CAAC,EAAE,MAAM,CAAA;CAC1B;AACD,MAAM,WAAW,WAAW;IAC1B,cAAc,EAAE;QACd,gBAAgB,EAAE,MAAM,CAAA;QACxB,IAAI,EAAE,MAAM,CAAA;QACZ,IAAI,EAAE,MAAM,CAAA;QACZ,MAAM,CAAC,EAAE,QAAQ,GAAG,UAAU,CAAA;QAC9B,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;QAC3B,cAAc,EAAE;YAAE,mBAAmB,EAAE,MAAM,CAAC;YAAC,WAAW,EAAE,MAAM,CAAA;SAAE,CAAA;QACpE,OAAO,EAAE;YAAE,mBAAmB,EAAE,MAAM,CAAC;YAAC,WAAW,EAAE,MAAM,CAAC;YAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;SAAE,CAAA;QACxF,OAAO,EAAE,oBAAoB,GAAG,IAAI,CAAA;KACrC,CAAA;CACF;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,eAAe,CAAA;IACvB,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,oBAAoB,CAAA;IAC1B,mBAAmB,EAAE,OAAO,CAAA;IAC5B,uBAAuB,CAAC,EAAE,MAAM,CAAA;IAChC,mBAAmB,CAAC,EAAE,MAAM,CAAA;CAC7B;AAQD,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAEpD;AAoFD,wBAAgB,eAAe,CAC7B,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,GAAG,IAAI,EAC1B,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,MAAM,GACd,eAAe,CAuDjB;AA+DD,wBAAgB,sBAAsB,CAAC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAQpH;AAED,wBAAgB,2BAA2B,CACzC,IAAI,EAAE,oBAAoB,EAC1B,OAAO,EAAE,WAAW,EACpB,GAAG,GAAE,MAAM,IAAuB,GACjC,oBAAoB,CAyDtB;AAkBD,wBAAgB,4BAA4B,CAAC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,QAAQ,EAAE,OAAO,GAAG,MAAM,CA6B1G;AAgHD,wBAAgB,YAAY,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,CAAC,GAAG,CAAC,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/instruction-set-sync/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -411,12 +411,18 @@ function removeObservedSyncLock(lockPath, observed) {
|
|
|
411
411
|
console.warn(`instruction_set_sync_lock_stale_removed:${lockPath}`);
|
|
412
412
|
return true;
|
|
413
413
|
}
|
|
414
|
-
export function
|
|
414
|
+
export function startSyncLockClaim(appRoot) {
|
|
415
415
|
mkdirSync(appRoot, { recursive: true });
|
|
416
|
-
const lockPath = join(appRoot, '.orizu.lock.json.lock');
|
|
417
|
-
const metadata = `${JSON.stringify({ pid: process.pid, createdAt: new Date().toISOString() })}\n`;
|
|
418
416
|
const lockWaitMs = processTestMilliseconds('ORIZU_TEST_SYNC_LOCK_WAIT_MS', 100, SYNC_LOCK_WAIT_MS) ?? SYNC_LOCK_WAIT_MS;
|
|
419
|
-
|
|
417
|
+
return {
|
|
418
|
+
lockPath: join(appRoot, '.orizu.lock.json.lock'),
|
|
419
|
+
metadata: `${JSON.stringify({ pid: process.pid, createdAt: new Date().toISOString() })}\n`,
|
|
420
|
+
deadline: Date.now() + lockWaitMs,
|
|
421
|
+
};
|
|
422
|
+
}
|
|
423
|
+
// One claim attempt: returns the release function, or how long to wait before
|
|
424
|
+
// trying again. Waiting is the caller's job so it can be blocking or not.
|
|
425
|
+
export function tryClaimSyncLock({ lockPath, metadata, deadline }) {
|
|
420
426
|
while (true) {
|
|
421
427
|
try {
|
|
422
428
|
writeFileSync(lockPath, metadata, { encoding: 'utf8', flag: 'wx', mode: 0o600 });
|
|
@@ -442,10 +448,10 @@ export function withSyncLock(appRoot, operation) {
|
|
|
442
448
|
if (Date.now() >= deadline) {
|
|
443
449
|
throw new Error(`instruction_set_sync_lock_busy${busyPid === undefined ? '' : `:${busyPid}`}`);
|
|
444
450
|
}
|
|
445
|
-
|
|
451
|
+
return Math.min(SYNC_LOCK_RETRY_MS, Math.max(1, deadline - Date.now()));
|
|
446
452
|
}
|
|
447
453
|
}
|
|
448
|
-
|
|
454
|
+
return () => {
|
|
449
455
|
try {
|
|
450
456
|
if (readFileSync(lockPath, 'utf8') === metadata)
|
|
451
457
|
rmSync(lockPath);
|
|
@@ -455,6 +461,14 @@ export function withSyncLock(appRoot, operation) {
|
|
|
455
461
|
throw error;
|
|
456
462
|
}
|
|
457
463
|
};
|
|
464
|
+
}
|
|
465
|
+
export function withSyncLock(appRoot, operation) {
|
|
466
|
+
const claim = startSyncLockClaim(appRoot);
|
|
467
|
+
let release = tryClaimSyncLock(claim);
|
|
468
|
+
while (typeof release === 'number') {
|
|
469
|
+
sleepSync(release);
|
|
470
|
+
release = tryClaimSyncLock(claim);
|
|
471
|
+
}
|
|
458
472
|
let result;
|
|
459
473
|
try {
|
|
460
474
|
result = operation();
|
|
@@ -490,6 +504,16 @@ function holdForProcessTest(name) {
|
|
|
490
504
|
sleepSync(milliseconds);
|
|
491
505
|
}
|
|
492
506
|
export function syncPayloadToDisk(out, project, plan, payload, options = {}) {
|
|
507
|
+
const staged = stageSyncPayload(out, project, plan, payload, options);
|
|
508
|
+
try {
|
|
509
|
+
const warnings = withSyncLock(staged.appRoot, staged.publish);
|
|
510
|
+
return { destination: staged.destination, wasPresent: staged.wasPresent, warnings };
|
|
511
|
+
}
|
|
512
|
+
finally {
|
|
513
|
+
staged.discard();
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
export function stageSyncPayload(out, project, plan, payload, options = {}) {
|
|
493
517
|
const target = parseSyncTarget(options.target);
|
|
494
518
|
const now = options.now ?? (() => new Date());
|
|
495
519
|
const set = payload.instructionSet;
|
|
@@ -605,9 +629,11 @@ export function syncPayloadToDisk(out, project, plan, payload, options = {}) {
|
|
|
605
629
|
else {
|
|
606
630
|
assertExistingVersionMatches(destination, componentHashes, manifestBytes, generatedBytes);
|
|
607
631
|
}
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
632
|
+
return {
|
|
633
|
+
appRoot,
|
|
634
|
+
destination,
|
|
635
|
+
wasPresent,
|
|
636
|
+
publish: () => {
|
|
611
637
|
holdForProcessTest('ORIZU_TEST_SYNC_HOLD_BEFORE_PUBLISH_MS');
|
|
612
638
|
const currentLock = readLock(appRoot, project);
|
|
613
639
|
holdForProcessTest('ORIZU_TEST_SYNC_HOLD_LOCK_MS');
|
|
@@ -671,8 +697,9 @@ export function syncPayloadToDisk(out, project, plan, payload, options = {}) {
|
|
|
671
697
|
}
|
|
672
698
|
stagedTemp = null;
|
|
673
699
|
}
|
|
674
|
-
warnings = emitManagedArtifacts(out, appRoot, currentLock, options.forceHelpers ?? false, target, journal);
|
|
700
|
+
const warnings = emitManagedArtifacts(out, appRoot, currentLock, options.forceHelpers ?? false, target, journal);
|
|
675
701
|
journal.write(join(appRoot, 'orizu.lock.json'), serializeLock(currentLock));
|
|
702
|
+
return warnings;
|
|
676
703
|
}
|
|
677
704
|
catch (error) {
|
|
678
705
|
journal.rollback();
|
|
@@ -688,11 +715,11 @@ export function syncPayloadToDisk(out, project, plan, payload, options = {}) {
|
|
|
688
715
|
}
|
|
689
716
|
throw error;
|
|
690
717
|
}
|
|
691
|
-
}
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
718
|
+
},
|
|
719
|
+
discard: () => {
|
|
720
|
+
if (stagedTemp)
|
|
721
|
+
rmSync(stagedTemp, { recursive: true, force: true });
|
|
722
|
+
stagedTemp = null;
|
|
723
|
+
},
|
|
724
|
+
};
|
|
698
725
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type InstructionSetLockV1 } from '../instruction-set-lock/index.js';
|
|
2
|
-
import { type SyncPayload } from '../instruction-set-sync/index.js';
|
|
2
|
+
import { syncPayloadToDisk, type SyncDiskResult, type SyncPayload } from '../instruction-set-sync/index.js';
|
|
3
3
|
export interface UpdateResolution {
|
|
4
4
|
payload: SyncPayload;
|
|
5
5
|
profileIdentity: string;
|
|
@@ -16,7 +16,7 @@ export interface UpdateResult {
|
|
|
16
16
|
absent: string[];
|
|
17
17
|
warnings: string[];
|
|
18
18
|
}
|
|
19
|
-
export declare function applyUpdate(out: string, project: string, plan: UpdatePlan, noSync: boolean, now?: () => Date): Promise<UpdateResult>;
|
|
19
|
+
export declare function applyUpdate(out: string, project: string, plan: UpdatePlan, noSync: boolean, now?: () => Date, sync?: (...args: Parameters<typeof syncPayloadToDisk>) => SyncDiskResult | Promise<SyncDiskResult>): Promise<UpdateResult>;
|
|
20
20
|
export interface PrunePlan {
|
|
21
21
|
lock: InstructionSetLockV1;
|
|
22
22
|
removals: Array<{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/instruction-set-update/index.ts"],"names":[],"mappings":"AAMA,OAAO,EAIL,KAAK,oBAAoB,EAC1B,MAAM,kCAAkC,CAAA;AAEzC,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/instruction-set-update/index.ts"],"names":[],"mappings":"AAMA,OAAO,EAIL,KAAK,oBAAoB,EAC1B,MAAM,kCAAkC,CAAA;AAEzC,OAAO,EAA4C,iBAAiB,EAAgB,KAAK,cAAc,EAAE,KAAK,WAAW,EAAE,MAAM,kCAAkC,CAAA;AAGnK,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,WAAW,CAAA;IACpB,eAAe,EAAE,MAAM,CAAA;CACxB;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,oBAAoB,CAAA;IAC1B,WAAW,EAAE,gBAAgB,EAAE,CAAA;IAC/B,KAAK,EAAE,MAAM,EAAE,CAAA;CAChB;AAMD,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,oBAAoB,CAIlF;AAED,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,GAAG,MAAM,CAmCpG;AAED,wBAAgB,cAAc,CAC5B,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,oBAAoB,EAC1B,QAAQ,EAAE,WAAW,EAAE,GACtB,UAAU,CAiDZ;AA8CD,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,EAAE,CAAA;IAChB,QAAQ,EAAE,MAAM,EAAE,CAAA;CACnB;AA2CD,wBAAsB,WAAW,CAC/B,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,UAAU,EAChB,MAAM,EAAE,OAAO,EACf,GAAG,GAAE,MAAM,IAAuB,EAClC,IAAI,GAAE,CAAC,GAAG,IAAI,EAAE,UAAU,CAAC,OAAO,iBAAiB,CAAC,KAAK,cAAc,GAAG,OAAO,CAAC,cAAc,CAAqB,GACpH,OAAO,CAAC,YAAY,CAAC,CA4DvB;AAMD,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,oBAAoB,CAAA;IAC1B,QAAQ,EAAE,KAAK,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC,CAAA;CAC5F;AAED,qBAAa,wBAAyB,SAAQ,KAAK;IACjD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,UAAU,EAAE,MAAM,EAAE,CAAA;gBAEjB,OAAO,EAAE,KAAK,CAAC;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,QAAQ,GAAG,UAAU,CAAA;KAAE,CAAC;CAQjF;AAyBD,wBAAsB,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,SAAS,CAAC,CAiEzF;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,SAAS,CAAC,UAAU,CAAC,CAAA;CAC/B;AAED,wBAAsB,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,cAAc,GAAE,MAAM,EAAO,GAAG,OAAO,CAAC,WAAW,CAAC,CAmFlH"}
|
|
@@ -185,7 +185,7 @@ async function assertGeneratedModulesVerified(appRootPath, lock) {
|
|
|
185
185
|
}
|
|
186
186
|
}
|
|
187
187
|
}
|
|
188
|
-
export async function applyUpdate(out, project, plan, noSync, now = () => new Date()) {
|
|
188
|
+
export async function applyUpdate(out, project, plan, noSync, now = () => new Date(), sync = syncPayloadToDisk) {
|
|
189
189
|
const absent = [];
|
|
190
190
|
const warnings = [];
|
|
191
191
|
if (noSync) {
|
|
@@ -236,7 +236,7 @@ export async function applyUpdate(out, project, plan, noSync, now = () => new Da
|
|
|
236
236
|
let lock = plan.lock;
|
|
237
237
|
for (const resolution of plan.resolutions) {
|
|
238
238
|
const set = resolution.payload.instructionSet;
|
|
239
|
-
const result =
|
|
239
|
+
const result = await sync(out, project, {
|
|
240
240
|
parsed: { set: set.slug, profile: resolution.profileIdentity },
|
|
241
241
|
path: '',
|
|
242
242
|
lock,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"instruction-sets-cli.d.ts","sourceRoot":"","sources":["../src/instruction-sets-cli.ts"],"names":[],"mappings":"AAOA,OAAO,EAAuC,UAAU,EAAE,MAAM,EAAY,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;
|
|
1
|
+
{"version":3,"file":"instruction-sets-cli.d.ts","sourceRoot":"","sources":["../src/instruction-sets-cli.ts"],"names":[],"mappings":"AAOA,OAAO,EAAuC,UAAU,EAAE,MAAM,EAAY,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;AAoED,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;IACtB,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3B,KAAK,EAAE,MAAM,EAAE,CAAA;IACf,OAAO,EAAE,YAAY,CAAA;IACrB,QAAQ,EAAE,WAAW,EAAE,CAAA;IACvB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAA;CACtB;AAkBD,MAAM,WAAW,WAAW;IAC1B,aAAa,EAAE,OAAO,aAAa,CAAA;IACnC,UAAU,CAAC,EAAE,OAAO,UAAU,CAAA;IAC9B,MAAM,CAAC,EAAE,OAAO,MAAM,CAAA;CACvB;AAuDD,wBAAgB,UAAU,CACxB,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,OAAO,EACZ,OAAO,GAAE,WAA+B,EACxC,QAAQ,GAAE,MAAM,CAAC,QAA2B,UAyE7C;AAED,wBAAsB,sBAAsB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,wBAAwB,GAAG,OAAO,CAAC,MAAM,CAAC,CA0T1G"}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { authedFetch } from './http.js';
|
|
2
2
|
import { INSTRUCTION_SET_COMPONENT_KEY } from './instruction-set-lock/index.js';
|
|
3
3
|
import { loadInstructionSetManifest, MAX_INSTRUCTION_SET_COMPONENT_BYTES } from './instruction-set-manifest.js';
|
|
4
|
-
import { sanitizeHumanInlineText, sanitizeTerminalText } from './json-response.js';
|
|
5
|
-
import { parseSyncTarget, planSyncRequest
|
|
6
|
-
import { applyPrune,
|
|
4
|
+
import { responsePayload, sanitizeHumanInlineText, sanitizeTerminalText } from './json-response.js';
|
|
5
|
+
import { parseSyncTarget, planSyncRequest } from './instruction-set-sync/index.js';
|
|
6
|
+
import { applyPrune, planPrune, PruneKeepUnresolvedError } from './instruction-set-update/index.js';
|
|
7
7
|
import { printVerifyReport, verifyInstructionSetTree } from './instruction-set-verify/index.js';
|
|
8
8
|
import { existsSync, mkdirSync, readFileSync, renameSync, rmSync, statSync, writeFileSync } from 'node:fs';
|
|
9
9
|
import { join } from 'node:path';
|
|
@@ -66,12 +66,8 @@ function lifecycleOptionValues(args, command, flag) {
|
|
|
66
66
|
}
|
|
67
67
|
return values;
|
|
68
68
|
}
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
if (!response.ok) {
|
|
72
|
-
throw new Error(`${action} failed (${response.status}): ${typeof payload.error === 'string' ? payload.error : response.statusText}`);
|
|
73
|
-
}
|
|
74
|
-
return payload;
|
|
69
|
+
function printInterrupted(io, message) {
|
|
70
|
+
io.print(io.json ? JSON.stringify({ error: message }) : message);
|
|
75
71
|
}
|
|
76
72
|
const SAFE_SEGMENT = /^[A-Za-z0-9._-]+$/u;
|
|
77
73
|
const WINDOWS_RESERVED_COMPONENT_KEY = /^(?:CON|PRN|AUX|NUL|COM[1-9]|LPT[1-9])(?:\.|$)/iu;
|
|
@@ -304,23 +300,14 @@ export async function instructionSetsCommand(args, io) {
|
|
|
304
300
|
const project = await io.resolveProjectSlug(projectOption);
|
|
305
301
|
if (subcommand === 'update') {
|
|
306
302
|
const output = lifecycleOptionValues(args, 'update', '--out')[0] ?? '.';
|
|
307
|
-
const lock = readUpdateLock(output, project);
|
|
308
|
-
const payloads = [];
|
|
309
|
-
for (const [setSlug, set] of Object.entries(lock.instructionSets)) {
|
|
310
|
-
const barePath = `/api/cli/instruction-sets/${encodeURIComponent(setSlug)}/sync?project=${encodeURIComponent(project)}`;
|
|
311
|
-
payloads.push(await responsePayload(await authedFetch(barePath, { method: 'GET' }), 'Instruction sets update'));
|
|
312
|
-
for (const profileSlugValue of Object.keys(set.profiles)) {
|
|
313
|
-
const identity = lockedProfileIdentity(output, setSlug, profileSlugValue);
|
|
314
|
-
const query = new URLSearchParams({ project, profile: identity });
|
|
315
|
-
const path = `/api/cli/instruction-sets/${encodeURIComponent(setSlug)}/sync?${query.toString()}`;
|
|
316
|
-
payloads.push(await responsePayload(await authedFetch(path, { method: 'GET' }), 'Instruction sets update'));
|
|
317
|
-
}
|
|
318
|
-
}
|
|
319
|
-
const plan = makeUpdatePlan(project, lock, payloads);
|
|
320
303
|
const isApproved = args.includes('--yes');
|
|
321
|
-
const
|
|
322
|
-
|
|
323
|
-
|
|
304
|
+
const { updateInstructionSets } = await import('./instruction-delivery.js');
|
|
305
|
+
const updated = await updateInstructionSets(output, project, isApproved, args.includes('--no-sync'));
|
|
306
|
+
if ('interrupted' in updated) {
|
|
307
|
+
printInterrupted(io, 'Instruction sets update interrupted; some sets may already be updated. Run orizu instructions update again, then orizu instructions verify.');
|
|
308
|
+
return updated.interrupted;
|
|
309
|
+
}
|
|
310
|
+
const { plan, result } = updated;
|
|
324
311
|
if (io.json)
|
|
325
312
|
io.print(JSON.stringify({ plan: plan.lines, applied: isApproved, absent: result.absent, warnings: result.warnings }));
|
|
326
313
|
else {
|
|
@@ -530,11 +517,16 @@ export async function instructionSetsCommand(args, io) {
|
|
|
530
517
|
throw new Error(`instruction_set_sync_option_unknown:${unknownOption}`);
|
|
531
518
|
const output = requiredOptionValue(args, subcommand, '--out') ?? '.';
|
|
532
519
|
const plan = planSyncRequest(reference, requiredOptionValue(args, subcommand, '--version'), output, project);
|
|
533
|
-
const
|
|
534
|
-
const
|
|
520
|
+
const { syncInstructionSet } = await import('./instruction-delivery.js');
|
|
521
|
+
const delivered = await syncInstructionSet(output, project, plan, {
|
|
535
522
|
forceHelpers: args.includes('--force-helpers'),
|
|
536
523
|
target: syncTarget,
|
|
537
524
|
});
|
|
525
|
+
if ('interrupted' in delivered) {
|
|
526
|
+
printInterrupted(io, 'Instruction set sync interrupted; any unpublished staged version was removed. Run orizu instructions sync again.');
|
|
527
|
+
return delivered.interrupted;
|
|
528
|
+
}
|
|
529
|
+
const { payload, result } = delivered;
|
|
538
530
|
if (io.json)
|
|
539
531
|
io.print(JSON.stringify({ ...payload, warnings: result.warnings }));
|
|
540
532
|
else {
|
package/dist/json-response.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export declare function sanitizeTerminalText(value: unknown): string;
|
|
2
2
|
export declare function sanitizeHumanInlineText(sanitizer: (value: unknown) => string, value: unknown): string;
|
|
3
3
|
export declare function parseJsonResponse<T>(response: Response, context: string): Promise<T>;
|
|
4
|
+
export declare function responsePayload(response: Response, action: string): Promise<Record<string, unknown>>;
|
|
4
5
|
//# sourceMappingURL=json-response.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"json-response.d.ts","sourceRoot":"","sources":["../src/json-response.ts"],"names":[],"mappings":"AAAA,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAK3D;AAED,wBAAgB,uBAAuB,CACrC,SAAS,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,MAAM,EACrC,KAAK,EAAE,OAAO,GACb,MAAM,CAER;AAED,wBAAsB,iBAAiB,CAAC,CAAC,EACvC,QAAQ,EAAE,QAAQ,EAClB,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,CAAC,CAAC,CAmBZ"}
|
|
1
|
+
{"version":3,"file":"json-response.d.ts","sourceRoot":"","sources":["../src/json-response.ts"],"names":[],"mappings":"AAAA,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAK3D;AAED,wBAAgB,uBAAuB,CACrC,SAAS,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,MAAM,EACrC,KAAK,EAAE,OAAO,GACb,MAAM,CAER;AAED,wBAAsB,iBAAiB,CAAC,CAAC,EACvC,QAAQ,EAAE,QAAQ,EAClB,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,CAAC,CAAC,CAmBZ;AAED,wBAAsB,eAAe,CAAC,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAM1G"}
|
package/dist/json-response.js
CHANGED
|
@@ -19,3 +19,10 @@ export async function parseJsonResponse(response, context) {
|
|
|
19
19
|
`Body preview: ${sanitizeTerminalText(rawBody.slice(0, 180))}`);
|
|
20
20
|
}
|
|
21
21
|
}
|
|
22
|
+
export async function responsePayload(response, action) {
|
|
23
|
+
const payload = await response.json().catch(() => ({}));
|
|
24
|
+
if (!response.ok) {
|
|
25
|
+
throw new Error(`${action} failed (${response.status}): ${typeof payload.error === 'string' ? payload.error : response.statusText}`);
|
|
26
|
+
}
|
|
27
|
+
return payload;
|
|
28
|
+
}
|
|
@@ -30,8 +30,10 @@ export interface WriteLastErrorRecordOptions {
|
|
|
30
30
|
configDir?: string;
|
|
31
31
|
}
|
|
32
32
|
export declare function extractLastErrorCode(error: unknown): string | null;
|
|
33
|
+
export declare function isStringWithinCap(value: unknown, maximumCharacters: number, wasTruncated: boolean): value is string;
|
|
34
|
+
export declare function boundedServerBaseUrl(value: string | null | undefined): string | null;
|
|
33
35
|
export declare function buildLastErrorRecord(input: LastErrorRecordInput): LastErrorRecord;
|
|
34
36
|
export declare function getLastErrorRecordPath(configDir?: string): string;
|
|
35
|
-
export declare function writeLastErrorRecord(input: LastErrorRecordInput, options?: WriteLastErrorRecordOptions): void
|
|
36
|
-
export declare function readLastErrorRecord(configDir?: string): LastErrorRecord | null
|
|
37
|
+
export declare function writeLastErrorRecord(input: LastErrorRecordInput, options?: WriteLastErrorRecordOptions): Promise<void>;
|
|
38
|
+
export declare function readLastErrorRecord(configDir?: string): Promise<LastErrorRecord | null>;
|
|
37
39
|
//# sourceMappingURL=last-error-record.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"last-error-record.d.ts","sourceRoot":"","sources":["../src/last-error-record.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"last-error-record.d.ts","sourceRoot":"","sources":["../src/last-error-record.ts"],"names":[],"mappings":"AAqBA,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,CAAC,CAAA;IACV,UAAU,EAAE,MAAM,CAAA;IAClB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;IACnB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAA;IAC5B,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;IACvB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;IACtB,IAAI,EAAE,MAAM,EAAE,CAAA;IACd,aAAa,EAAE,OAAO,CAAA;IACtB,OAAO,EAAE,MAAM,CAAA;IACf,gBAAgB,EAAE,OAAO,CAAA;CAC1B;AAED,eAAO,MAAM,yBAAyB,IAAI,CAAA;AAC1C,eAAO,MAAM,mBAAmB,oBAAoB,CAAA;AACpD,eAAO,MAAM,4BAA4B,WAAa,CAAA;AACtD,eAAO,MAAM,4BAA4B,gBAAgB,CAAA;AAezD,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,SAAS,MAAM,EAAE,CAAA;IACvB,OAAO,EAAE,MAAM,CAAA;IACf,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACpB,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC7B,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACvB,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IAC3B,GAAG,CAAC,EAAE,IAAI,CAAA;CACX;AAED,MAAM,WAAW,2BAA2B;IAC1C,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AA8ID,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAKlE;AAUD,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,OAAO,EACd,iBAAiB,EAAE,MAAM,EACzB,YAAY,EAAE,OAAO,GACpB,KAAK,IAAI,MAAM,CAMjB;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAIpF;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,oBAAoB,GAAG,eAAe,CA0DjF;AAED,wBAAgB,sBAAsB,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAEjE;AAED,wBAAsB,oBAAoB,CACxC,KAAK,EAAE,oBAAoB,EAC3B,OAAO,GAAE,2BAAgC,GACxC,OAAO,CAAC,IAAI,CAAC,CAqBf;AAED,wBAAsB,mBAAmB,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CAQ7F"}
|