orizu 0.5.52 → 0.5.53
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/dist/auth-commands.js +2 -2
- package/dist/cli-console-output.d.ts +7 -1
- package/dist/cli-console-output.d.ts.map +1 -1
- package/dist/cli-console-output.js +16 -3
- package/dist/cli-stops.d.ts +14 -0
- package/dist/cli-stops.d.ts.map +1 -0
- package/dist/cli-stops.js +22 -0
- package/dist/egress-allowlist-cli.d.ts +29 -2
- package/dist/egress-allowlist-cli.d.ts.map +1 -1
- package/dist/egress-allowlist-cli.js +16 -89
- package/dist/egress-allowlist-workflow.d.ts +17 -0
- package/dist/egress-allowlist-workflow.d.ts.map +1 -0
- package/dist/egress-allowlist-workflow.js +183 -0
- package/dist/instruction-delivery.d.ts +4 -4
- package/dist/instruction-delivery.d.ts.map +1 -1
- package/dist/instruction-delivery.js +32 -46
- package/dist/instruction-prune.d.ts +24 -0
- package/dist/instruction-prune.d.ts.map +1 -0
- package/dist/instruction-prune.js +33 -0
- package/dist/instruction-set-sync/index.d.ts +0 -2
- package/dist/instruction-set-sync/index.d.ts.map +1 -1
- package/dist/instruction-set-sync/index.js +3 -36
- package/dist/instruction-set-update/index.d.ts +41 -3
- package/dist/instruction-set-update/index.d.ts.map +1 -1
- package/dist/instruction-set-update/index.js +156 -132
- package/dist/instruction-sets-cli.d.ts.map +1 -1
- package/dist/instruction-sets-cli.js +21 -2
- package/dist/instruction-sync-lock.d.ts +9 -0
- package/dist/instruction-sync-lock.d.ts.map +1 -0
- package/dist/instruction-sync-lock.js +24 -0
- package/dist/json-output-scrub.d.ts +3 -0
- package/dist/json-output-scrub.d.ts.map +1 -0
- package/dist/json-output-scrub.js +70 -0
- package/dist/one-request-write.d.ts.map +1 -1
- package/dist/one-request-write.js +2 -9
- package/dist/workbench-cli.d.ts +2 -1
- package/dist/workbench-cli.d.ts.map +1 -1
- package/dist/workbench-cli.js +79 -593
- package/dist/workbench-workflows.d.ts +56 -0
- package/dist/workbench-workflows.d.ts.map +1 -0
- package/dist/workbench-workflows.js +665 -0
- package/dist/workspace-sync-workflow.d.ts +115 -0
- package/dist/workspace-sync-workflow.d.ts.map +1 -0
- package/dist/workspace-sync-workflow.js +642 -0
- package/dist/workspace-sync.d.ts +45 -97
- package/dist/workspace-sync.d.ts.map +1 -1
- package/dist/workspace-sync.js +53 -494
- package/package.json +1 -1
- package/src/auth-commands.ts +2 -2
- package/src/cli-console-output.ts +16 -2
- package/src/cli-stops.ts +27 -0
- package/src/egress-allowlist-cli.ts +18 -90
- package/src/egress-allowlist-workflow.ts +198 -0
- package/src/instruction-delivery.ts +31 -47
- package/src/instruction-prune.ts +59 -0
- package/src/instruction-set-sync/index.ts +3 -43
- package/src/instruction-set-update/index.ts +173 -122
- package/src/instruction-sets-cli.ts +23 -2
- package/src/instruction-sync-lock.ts +27 -0
- package/src/json-output-scrub.ts +73 -0
- package/src/one-request-write.ts +2 -10
- package/src/workbench-cli.ts +83 -684
- package/src/workbench-workflows.ts +815 -0
- package/src/workspace-sync-workflow.ts +838 -0
- package/src/workspace-sync.ts +63 -630
|
@@ -5,7 +5,7 @@ import { join, sep } from 'node:path';
|
|
|
5
5
|
import { shellQuote } from '../git-recovery-environment.js';
|
|
6
6
|
import { parseLock, parseSpecifier, serializeLock, } from '../instruction-set-lock/index.js';
|
|
7
7
|
import { assertOutputConfined, reconcileGeneratedIndex } from '../instruction-set-sync/helpers.js';
|
|
8
|
-
import { profileSlug, recordResolvedPayloadInLock
|
|
8
|
+
import { profileSlug, recordResolvedPayloadInLock } from '../instruction-set-sync/index.js';
|
|
9
9
|
import { verifyInstructionSetTree, verifyMaterializedVersionAgainstLock } from '../instruction-set-verify/index.js';
|
|
10
10
|
function appRoot(out) {
|
|
11
11
|
return join(out, 'orizu');
|
|
@@ -185,54 +185,56 @@ async function assertGeneratedModulesVerified(appRootPath, lock) {
|
|
|
185
185
|
}
|
|
186
186
|
}
|
|
187
187
|
}
|
|
188
|
-
|
|
188
|
+
/** --no-sync: records the planned Pointers in the Lock. The caller holds the folder lock. */
|
|
189
|
+
export async function publishNoSyncUpdate(out, project, plan, now = () => new Date()) {
|
|
189
190
|
const absent = [];
|
|
190
191
|
const warnings = [];
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
reconcileGeneratedIndex(out, appRootPath, lock);
|
|
216
|
-
wasReconciled = true;
|
|
217
|
-
atomicWrite(join(appRootPath, 'orizu.lock.json'), serializeLock(lock));
|
|
218
|
-
}
|
|
219
|
-
catch (error) {
|
|
220
|
-
if (wasReconciled)
|
|
221
|
-
atomicWrite(importMapPath, priorImportMap);
|
|
222
|
-
throw error;
|
|
223
|
-
}
|
|
224
|
-
return;
|
|
225
|
-
}
|
|
226
|
-
if (!hasImportMap) {
|
|
227
|
-
warnings.push('instruction_set_update_generated_index_missing; the generated index was not reconciled — run orizu instructions sync <specifier> then orizu instructions verify');
|
|
228
|
-
}
|
|
229
|
-
else if (missing.length > 0) {
|
|
230
|
-
warnings.push(`instruction_set_update_generated_index_stale:${missing[0]}; the generated index still resolves the previous Version — run orizu instructions sync <specifier> then orizu instructions verify`);
|
|
231
|
-
}
|
|
192
|
+
let lock = readUpdateLock(out, project);
|
|
193
|
+
for (const resolution of plan.resolutions) {
|
|
194
|
+
const set = resolution.payload.instructionSet;
|
|
195
|
+
const material = set.version;
|
|
196
|
+
const versionSlug = `v${material.versionNumber}`;
|
|
197
|
+
const destination = join(appRoot(out), 'instruction-sets', set.slug, set.profile.profileSlug, versionSlug);
|
|
198
|
+
lock = recordResolvedPayloadInLock(lock, resolution.payload, now);
|
|
199
|
+
if (!existsSync(join(destination, 'components.generated.ts'))) {
|
|
200
|
+
absent.push(`${set.slug}/${resolution.profileIdentity}@${versionSlug}`);
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
const appRootPath = appRoot(out);
|
|
204
|
+
const missing = missingVersionModules(appRootPath, lock);
|
|
205
|
+
const importMapPath = join(appRootPath, 'generated', 'index.ts');
|
|
206
|
+
const hasImportMap = existsSync(importMapPath);
|
|
207
|
+
if (missing.length === 0)
|
|
208
|
+
await assertGeneratedModulesVerified(appRootPath, lock);
|
|
209
|
+
if (missing.length === 0 && hasImportMap) {
|
|
210
|
+
const priorImportMap = readFileSync(importMapPath, 'utf8');
|
|
211
|
+
waitAtUpdateLockPublicationBarrierForProcessTest();
|
|
212
|
+
let wasReconciled = false;
|
|
213
|
+
try {
|
|
214
|
+
reconcileGeneratedIndex(out, appRootPath, lock);
|
|
215
|
+
wasReconciled = true;
|
|
232
216
|
atomicWrite(join(appRootPath, 'orizu.lock.json'), serializeLock(lock));
|
|
233
|
-
}
|
|
217
|
+
}
|
|
218
|
+
catch (error) {
|
|
219
|
+
if (wasReconciled)
|
|
220
|
+
atomicWrite(importMapPath, priorImportMap);
|
|
221
|
+
throw error;
|
|
222
|
+
}
|
|
234
223
|
return { absent, warnings };
|
|
235
224
|
}
|
|
225
|
+
if (!hasImportMap) {
|
|
226
|
+
warnings.push('instruction_set_update_generated_index_missing; the generated index was not reconciled — run orizu instructions sync <specifier> then orizu instructions verify');
|
|
227
|
+
}
|
|
228
|
+
else if (missing.length > 0) {
|
|
229
|
+
warnings.push(`instruction_set_update_generated_index_stale:${missing[0]}; the generated index still resolves the previous Version — run orizu instructions sync <specifier> then orizu instructions verify`);
|
|
230
|
+
}
|
|
231
|
+
atomicWrite(join(appRootPath, 'orizu.lock.json'), serializeLock(lock));
|
|
232
|
+
return { absent, warnings };
|
|
233
|
+
}
|
|
234
|
+
/** Syncs every newly referenced Version; `sync` takes the folder lock for each one. */
|
|
235
|
+
export async function applyUpdate(out, project, plan, now, sync) {
|
|
236
|
+
const absent = [];
|
|
237
|
+
const warnings = [];
|
|
236
238
|
let lock = plan.lock;
|
|
237
239
|
for (const resolution of plan.resolutions) {
|
|
238
240
|
const set = resolution.payload.instructionSet;
|
|
@@ -350,96 +352,118 @@ export async function planPrune(out, keepSpecifiers) {
|
|
|
350
352
|
}
|
|
351
353
|
return { lock, removals: removals.sort((left, right) => left.key.localeCompare(right.key)) };
|
|
352
354
|
}
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
}
|
|
385
|
-
removals = removals.filter(removal => {
|
|
386
|
-
const [setSlug, profileSlugValue] = removal.key.split('/');
|
|
387
|
-
return !unmanagedProfileKeys.has(`${setSlug}/${profileSlugValue}`);
|
|
388
|
-
});
|
|
389
|
-
const candidate = parseLock(serializeLock(currentPlan.lock));
|
|
390
|
-
const lockPath = join(appRoot(out), 'orizu.lock.json');
|
|
391
|
-
const importMapPath = join(appRoot(out), 'generated', 'index.ts');
|
|
392
|
-
const priorLock = readFileSync(lockPath, 'utf8');
|
|
393
|
-
const priorImportMap = existsSync(importMapPath) ? readFileSync(importMapPath, 'utf8') : null;
|
|
394
|
-
const stagingRoot = join(appRoot(out), `.prune-${randomUUID()}.tmp`);
|
|
395
|
-
mkdirSync(stagingRoot);
|
|
396
|
-
const staged = [];
|
|
397
|
-
try {
|
|
398
|
-
for (const [index, removal] of removals.entries()) {
|
|
399
|
-
assertOutputConfined(out, removal.path);
|
|
400
|
-
const [setSlug, profileSlugValue, versionSlug] = removal.key.split('/');
|
|
401
|
-
const manifest = JSON.parse(readFileSync(join(removal.path, 'manifest.json'), 'utf8'));
|
|
402
|
-
const stagedPath = join(stagingRoot, String(index));
|
|
403
|
-
renameSync(removal.path, stagedPath);
|
|
404
|
-
staged.push({ removal, stagedPath, specifier: `${setSlug}/${manifest.modelConfigIdentity}@${versionSlug}` });
|
|
405
|
-
const profile = candidate.instructionSets[setSlug].profiles[profileSlugValue];
|
|
406
|
-
delete profile.versions[versionSlug];
|
|
407
|
-
if (Object.keys(profile.versions).length === 0)
|
|
408
|
-
delete candidate.instructionSets[setSlug].profiles[profileSlugValue];
|
|
409
|
-
}
|
|
410
|
-
const handledProfiles = new Set();
|
|
411
|
-
for (const item of staged) {
|
|
412
|
-
const [setSlug, profileSlugValue] = item.removal.key.split('/');
|
|
413
|
-
const profilePath = join(item.removal.path, '..');
|
|
414
|
-
if (candidate.instructionSets[setSlug].profiles[profileSlugValue] || handledProfiles.has(profilePath))
|
|
355
|
+
/**
|
|
356
|
+
* Plans again under the folder lock: keeps only approved removals that are
|
|
357
|
+
* still unreferenced (never adds one) and skips profiles holding unmanaged
|
|
358
|
+
* files. Reads only.
|
|
359
|
+
*/
|
|
360
|
+
export async function selectPruneRemovals(out, plan, keepSpecifiers) {
|
|
361
|
+
const currentPlan = await planPrune(out, keepSpecifiers);
|
|
362
|
+
const currentRemovalKeys = new Set(currentPlan.removals.map(removal => removal.key));
|
|
363
|
+
let removals = plan.removals.filter(removal => currentRemovalKeys.has(removal.key));
|
|
364
|
+
const skipped = plan.removals
|
|
365
|
+
.filter(removal => !currentRemovalKeys.has(removal.key))
|
|
366
|
+
.map(removal => ({ ...removal, reason: 'became_referenced_after_planning' }));
|
|
367
|
+
const removalKeys = new Set(removals.map(removal => removal.key));
|
|
368
|
+
const unmanagedProfileKeys = new Set();
|
|
369
|
+
for (const [setSlug, set] of Object.entries(currentPlan.lock.instructionSets)) {
|
|
370
|
+
for (const [profileSlugValue, profile] of Object.entries(set.profiles)) {
|
|
371
|
+
const versionSlugs = Object.keys(profile.versions);
|
|
372
|
+
if (!versionSlugs.every(versionSlug => removalKeys.has(`${setSlug}/${profileSlugValue}/${versionSlug}`)))
|
|
373
|
+
continue;
|
|
374
|
+
const profilePath = join(appRoot(out), 'instruction-sets', setSlug, profileSlugValue);
|
|
375
|
+
assertOutputConfined(out, profilePath);
|
|
376
|
+
const lockedVersions = new Set(versionSlugs);
|
|
377
|
+
const unmanagedEntries = readdirSync(profilePath, { withFileTypes: true })
|
|
378
|
+
.filter(entry => !entry.isDirectory() || !lockedVersions.has(entry.name))
|
|
379
|
+
.map(entry => entry.name)
|
|
380
|
+
.sort();
|
|
381
|
+
if (unmanagedEntries.length === 0)
|
|
382
|
+
continue;
|
|
383
|
+
unmanagedProfileKeys.add(`${setSlug}/${profileSlugValue}`);
|
|
384
|
+
for (const removal of removals) {
|
|
385
|
+
if (!removal.key.startsWith(`${setSlug}/${profileSlugValue}/`))
|
|
415
386
|
continue;
|
|
416
|
-
|
|
417
|
-
rmdirSync(profilePath);
|
|
418
|
-
}
|
|
419
|
-
atomicWrite(lockPath, serializeLock(candidate));
|
|
420
|
-
if (existsSync(importMapPath))
|
|
421
|
-
reconcileGeneratedIndex(out, appRoot(out), candidate);
|
|
422
|
-
holdBeforePruneVerifyForProcessTest();
|
|
423
|
-
const report = await verifyInstructionSetTree(out);
|
|
424
|
-
if (!report.ok) {
|
|
425
|
-
throw new Error(`instruction_set_prune_verification_failed:${report.failures[0]?.code ?? 'unknown'}`);
|
|
426
|
-
}
|
|
427
|
-
rmSync(stagingRoot, { recursive: true, force: true });
|
|
428
|
-
return { skipped };
|
|
429
|
-
}
|
|
430
|
-
catch (error) {
|
|
431
|
-
for (const item of [...staged].reverse()) {
|
|
432
|
-
mkdirSync(join(item.removal.path, '..'), { recursive: true });
|
|
433
|
-
if (existsSync(item.stagedPath))
|
|
434
|
-
renameSync(item.stagedPath, item.removal.path);
|
|
387
|
+
skipped.push({ ...removal, reason: 'profile_directory_has_unmanaged_files', unmanagedEntries });
|
|
435
388
|
}
|
|
436
|
-
atomicWrite(lockPath, priorLock);
|
|
437
|
-
if (priorImportMap === null)
|
|
438
|
-
rmSync(importMapPath, { force: true });
|
|
439
|
-
else
|
|
440
|
-
atomicWrite(importMapPath, priorImportMap);
|
|
441
|
-
rmSync(stagingRoot, { recursive: true, force: true });
|
|
442
|
-
throw error;
|
|
443
389
|
}
|
|
390
|
+
}
|
|
391
|
+
removals = removals.filter(removal => {
|
|
392
|
+
const [setSlug, profileSlugValue] = removal.key.split('/');
|
|
393
|
+
return !unmanagedProfileKeys.has(`${setSlug}/${profileSlugValue}`);
|
|
444
394
|
});
|
|
395
|
+
return { lock: currentPlan.lock, removals, skipped };
|
|
396
|
+
}
|
|
397
|
+
export function startPrune(out) {
|
|
398
|
+
const lockPath = join(appRoot(out), 'orizu.lock.json');
|
|
399
|
+
const importMapPath = join(appRoot(out), 'generated', 'index.ts');
|
|
400
|
+
const stagingRoot = join(appRoot(out), `.prune-${randomUUID()}.tmp`);
|
|
401
|
+
const prune = {
|
|
402
|
+
lockPath,
|
|
403
|
+
importMapPath,
|
|
404
|
+
priorLock: readFileSync(lockPath, 'utf8'),
|
|
405
|
+
priorImportMap: existsSync(importMapPath) ? readFileSync(importMapPath, 'utf8') : null,
|
|
406
|
+
stagingRoot,
|
|
407
|
+
staged: [],
|
|
408
|
+
};
|
|
409
|
+
mkdirSync(stagingRoot);
|
|
410
|
+
return prune;
|
|
411
|
+
}
|
|
412
|
+
/**
|
|
413
|
+
* Moves each removal into the staging folder, then writes the new Lock and
|
|
414
|
+
* generated index. Records each move as it happens so a failure part-way can
|
|
415
|
+
* be rolled back.
|
|
416
|
+
*/
|
|
417
|
+
export function stagePruneRemovals(out, prune, selection) {
|
|
418
|
+
const candidate = parseLock(serializeLock(selection.lock));
|
|
419
|
+
for (const [index, removal] of selection.removals.entries()) {
|
|
420
|
+
assertOutputConfined(out, removal.path);
|
|
421
|
+
const [setSlug, profileSlugValue, versionSlug] = removal.key.split('/');
|
|
422
|
+
// A Version without a readable manifest stops the prune before it moves, as before.
|
|
423
|
+
JSON.parse(readFileSync(join(removal.path, 'manifest.json'), 'utf8'));
|
|
424
|
+
const stagedPath = join(prune.stagingRoot, String(index));
|
|
425
|
+
renameSync(removal.path, stagedPath);
|
|
426
|
+
prune.staged.push({ removal, stagedPath });
|
|
427
|
+
const profile = candidate.instructionSets[setSlug].profiles[profileSlugValue];
|
|
428
|
+
delete profile.versions[versionSlug];
|
|
429
|
+
if (Object.keys(profile.versions).length === 0)
|
|
430
|
+
delete candidate.instructionSets[setSlug].profiles[profileSlugValue];
|
|
431
|
+
}
|
|
432
|
+
const handledProfiles = new Set();
|
|
433
|
+
for (const item of prune.staged) {
|
|
434
|
+
const [setSlug, profileSlugValue] = item.removal.key.split('/');
|
|
435
|
+
const profilePath = join(item.removal.path, '..');
|
|
436
|
+
if (candidate.instructionSets[setSlug].profiles[profileSlugValue] || handledProfiles.has(profilePath))
|
|
437
|
+
continue;
|
|
438
|
+
handledProfiles.add(profilePath);
|
|
439
|
+
rmdirSync(profilePath);
|
|
440
|
+
}
|
|
441
|
+
atomicWrite(prune.lockPath, serializeLock(candidate));
|
|
442
|
+
if (existsSync(prune.importMapPath))
|
|
443
|
+
reconcileGeneratedIndex(out, appRoot(out), candidate);
|
|
444
|
+
holdBeforePruneVerifyForProcessTest();
|
|
445
|
+
}
|
|
446
|
+
/** Verifies the pruned tree; the error names the first failure. */
|
|
447
|
+
export async function verifyPrunedTree(out) {
|
|
448
|
+
const report = await verifyInstructionSetTree(out);
|
|
449
|
+
if (!report.ok) {
|
|
450
|
+
throw new Error(`instruction_set_prune_verification_failed:${report.failures[0]?.code ?? 'unknown'}`);
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
export function finishPrune(prune) {
|
|
454
|
+
rmSync(prune.stagingRoot, { recursive: true, force: true });
|
|
455
|
+
}
|
|
456
|
+
/** Puts back every moved folder, the prior Lock and the prior generated index. */
|
|
457
|
+
export function rollBackPrune(prune) {
|
|
458
|
+
for (const item of [...prune.staged].reverse()) {
|
|
459
|
+
mkdirSync(join(item.removal.path, '..'), { recursive: true });
|
|
460
|
+
if (existsSync(item.stagedPath))
|
|
461
|
+
renameSync(item.stagedPath, item.removal.path);
|
|
462
|
+
}
|
|
463
|
+
atomicWrite(prune.lockPath, prune.priorLock);
|
|
464
|
+
if (prune.priorImportMap === null)
|
|
465
|
+
rmSync(prune.importMapPath, { force: true });
|
|
466
|
+
else
|
|
467
|
+
atomicWrite(prune.importMapPath, prune.priorImportMap);
|
|
468
|
+
rmSync(prune.stagingRoot, { recursive: true, force: true });
|
|
445
469
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"instruction-sets-cli.d.ts","sourceRoot":"","sources":["../src/instruction-sets-cli.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"instruction-sets-cli.d.ts","sourceRoot":"","sources":["../src/instruction-sets-cli.ts"],"names":[],"mappings":"AAQA,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;AAgFD,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,CAkU1G"}
|
|
@@ -3,7 +3,7 @@ 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
4
|
import { responsePayload, sanitizeHumanInlineText, sanitizeTerminalText } from './json-response.js';
|
|
5
5
|
import { parseSyncTarget, planSyncRequest } from './instruction-set-sync/index.js';
|
|
6
|
-
import {
|
|
6
|
+
import { 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';
|
|
@@ -69,6 +69,17 @@ function lifecycleOptionValues(args, command, flag) {
|
|
|
69
69
|
function printInterrupted(io, message) {
|
|
70
70
|
io.print(io.json ? JSON.stringify({ error: message }) : message);
|
|
71
71
|
}
|
|
72
|
+
function pruneStoppedMessage(outcome) {
|
|
73
|
+
if (outcome.kind === 'removed') {
|
|
74
|
+
const versions = outcome.count === 1 ? '1 version was removed' : `${outcome.count} versions were removed`;
|
|
75
|
+
return `Instruction sets prune interrupted after it finished; ${versions}. Run orizu instructions verify.`;
|
|
76
|
+
}
|
|
77
|
+
if (outcome.kind === 'rolled back') {
|
|
78
|
+
const code = outcome.error instanceof Error ? outcome.error.message : String(outcome.error);
|
|
79
|
+
return `Instruction sets prune interrupted after it failed; the prune was rolled back and nothing was removed (${code}). Run orizu instructions verify.`;
|
|
80
|
+
}
|
|
81
|
+
return 'Instruction sets prune interrupted; nothing was removed.';
|
|
82
|
+
}
|
|
72
83
|
const SAFE_SEGMENT = /^[A-Za-z0-9._-]+$/u;
|
|
73
84
|
const WINDOWS_RESERVED_COMPONENT_KEY = /^(?:CON|PRN|AUX|NUL|COM[1-9]|LPT[1-9])(?:\.|$)/iu;
|
|
74
85
|
function safeSegment(value) {
|
|
@@ -211,6 +222,8 @@ export async function instructionSetsCommand(args, io) {
|
|
|
211
222
|
if (!subcommand || !knownSubcommands.has(subcommand)) {
|
|
212
223
|
throw new Error('Usage: orizu instructions list|show|sync|update|prune|verify|archive|restore');
|
|
213
224
|
}
|
|
225
|
+
// verify stays plain code: a local, read-only hash check with no network,
|
|
226
|
+
// lock, writes or clean-up for Effect to own (ORI-2728).
|
|
214
227
|
if (subcommand === 'verify') {
|
|
215
228
|
const report = await verifyInstructionSetTree(requiredOptionValue(args, subcommand, '--out') ?? '.');
|
|
216
229
|
printVerifyReport(report, io.json, io.print);
|
|
@@ -238,6 +251,7 @@ export async function instructionSetsCommand(args, io) {
|
|
|
238
251
|
return 1;
|
|
239
252
|
}
|
|
240
253
|
const isApproved = args.includes('--yes');
|
|
254
|
+
// Plan-only prune stays plain code: like verify, it only reads and reports (ORI-2728).
|
|
241
255
|
if (!isApproved) {
|
|
242
256
|
if (io.json)
|
|
243
257
|
io.print(JSON.stringify({ removals: plan.removals, skipped: [], applied: false }));
|
|
@@ -250,7 +264,12 @@ export async function instructionSetsCommand(args, io) {
|
|
|
250
264
|
}
|
|
251
265
|
waitAtPrunePlanBarrierForProcessTest();
|
|
252
266
|
try {
|
|
253
|
-
const
|
|
267
|
+
const { pruneInstructionSets } = await import('./instruction-prune.js');
|
|
268
|
+
const result = await pruneInstructionSets(output, plan, keepSpecifiers);
|
|
269
|
+
if ('interrupted' in result) {
|
|
270
|
+
printInterrupted(io, pruneStoppedMessage(result.outcome));
|
|
271
|
+
return result.interrupted;
|
|
272
|
+
}
|
|
254
273
|
if (io.json)
|
|
255
274
|
io.print(JSON.stringify({ removals: plan.removals, skipped: result.skipped, applied: true }));
|
|
256
275
|
else {
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Effect } from 'effect';
|
|
2
|
+
export declare const attempt: <A>(operation: () => A) => Effect.Effect<A, unknown, never>;
|
|
3
|
+
/**
|
|
4
|
+
* Runs `use` while holding the app folder's sync lock (`.orizu.lock.json.lock`).
|
|
5
|
+
* Waiting for another process's lock never blocks and is the only part a stop
|
|
6
|
+
* can interrupt: nothing is held yet. The lock is released however `use` ends.
|
|
7
|
+
*/
|
|
8
|
+
export declare function holdSyncLock<A>(appRoot: string, use: Effect.Effect<A, unknown>): Effect.Effect<A, unknown, never>;
|
|
9
|
+
//# sourceMappingURL=instruction-sync-lock.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"instruction-sync-lock.d.ts","sourceRoot":"","sources":["../src/instruction-sync-lock.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAS/B,eAAO,MAAM,OAAO,GAAI,CAAC,EAAE,WAAW,MAAM,CAAC,qCAA0D,CAAA;AAEvG;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,OAAO,CAAC,oCAU9E"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { Effect } from 'effect';
|
|
2
|
+
import { startSyncLockClaim, tryClaimSyncLock } from './instruction-set-sync/index.js';
|
|
3
|
+
// Loaded only through `await import(...)` (instruction-delivery, instruction-prune),
|
|
4
|
+
// so CLI startup and the published loader never load Effect.
|
|
5
|
+
// Existing file steps throw plain errors; keep them as the failure value so the
|
|
6
|
+
// CLI prints exactly the same message.
|
|
7
|
+
export const attempt = (operation) => Effect.try({ try: operation, catch: cause => cause });
|
|
8
|
+
/**
|
|
9
|
+
* Runs `use` while holding the app folder's sync lock (`.orizu.lock.json.lock`).
|
|
10
|
+
* Waiting for another process's lock never blocks and is the only part a stop
|
|
11
|
+
* can interrupt: nothing is held yet. The lock is released however `use` ends.
|
|
12
|
+
*/
|
|
13
|
+
export function holdSyncLock(appRoot, use) {
|
|
14
|
+
const acquire = Effect.gen(function* () {
|
|
15
|
+
const claim = yield* attempt(() => startSyncLockClaim(appRoot));
|
|
16
|
+
while (true) {
|
|
17
|
+
const claimed = yield* attempt(() => tryClaimSyncLock(claim));
|
|
18
|
+
if (typeof claimed === 'function')
|
|
19
|
+
return claimed;
|
|
20
|
+
yield* Effect.interruptible(Effect.sleep(claimed));
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
return Effect.acquireUseRelease(acquire, () => use, release => Effect.sync(release));
|
|
24
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"json-output-scrub.d.ts","sourceRoot":"","sources":["../src/json-output-scrub.ts"],"names":[],"mappings":"AAsDA,0EAA0E;AAC1E,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAiBpD"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { sanitizeTerminalText } from './json-response.js';
|
|
2
|
+
import { errorOutputSecrets } from './last-error-record.js';
|
|
3
|
+
import { redactSecrets } from './secret-redaction.js';
|
|
4
|
+
// ORI-2744: under --json, every line a command prints on stdout hides the
|
|
5
|
+
// secrets this process holds, the same ones the error line on stderr hides
|
|
6
|
+
// (#2387). A line holding none of them is printed exactly as it was.
|
|
7
|
+
// sanitizeTerminalText drops raw C0, DEL and C1 (as stderr does) but keeps
|
|
8
|
+
// tab, newline and CR, so those are dropped here, along with every control
|
|
9
|
+
// character as JSON writes it inside a string, behind one backslash or several
|
|
10
|
+
// (a JSON reply quoted inside another JSON string).
|
|
11
|
+
const CONTROLS = /[\t\n\r]|\\+u00[01][0-9a-fA-F]|\\+u007[fF]|\\+u00[89][0-9a-fA-F]|\\+[bfnrt]/g;
|
|
12
|
+
// The one control-character pass used to look for a secret and to hide it, so
|
|
13
|
+
// a secret split by any control character is found and hidden field by field,
|
|
14
|
+
// and the raw-line fallback stays a last resort.
|
|
15
|
+
const withoutControls = (text) => sanitizeTerminalText(text).replace(CONTROLS, '');
|
|
16
|
+
const holdsAny = (text, forms) => {
|
|
17
|
+
const stripped = withoutControls(text);
|
|
18
|
+
return forms.some(form => text.includes(form) || stripped.includes(form));
|
|
19
|
+
};
|
|
20
|
+
// A secret as sent, as JSON writes it inside a string, and as JSON writes that
|
|
21
|
+
// again when one JSON text is quoted inside another (a server's error body
|
|
22
|
+
// carried in an `error` string).
|
|
23
|
+
function writtenForms(secret) {
|
|
24
|
+
const once = JSON.stringify(secret).slice(1, -1);
|
|
25
|
+
return [...new Set([secret, once, JSON.stringify(once).slice(1, -1)])];
|
|
26
|
+
}
|
|
27
|
+
// The stderr rule: hide the secrets, drop control characters, hide them again.
|
|
28
|
+
// Only a string that holds a secret changes, and control characters are
|
|
29
|
+
// dropped only when one splits a secret, so other text keeps them.
|
|
30
|
+
function hideInText(text, forms) {
|
|
31
|
+
if (!holdsAny(text, forms))
|
|
32
|
+
return text;
|
|
33
|
+
const hidden = redactSecrets(text, { secrets: forms });
|
|
34
|
+
return holdsAny(hidden, forms) ? redactSecrets(withoutControls(hidden), { secrets: forms }) : hidden;
|
|
35
|
+
}
|
|
36
|
+
function hideInValue(value, forms) {
|
|
37
|
+
if (typeof value === 'string')
|
|
38
|
+
return hideInText(value, forms);
|
|
39
|
+
if (Array.isArray(value))
|
|
40
|
+
return value.map(item => hideInValue(item, forms));
|
|
41
|
+
if (value !== null && typeof value === 'object') {
|
|
42
|
+
return Object.fromEntries(Object.entries(value).map(([key, item]) => [hideInText(key, forms), hideInValue(item, forms)]));
|
|
43
|
+
}
|
|
44
|
+
return value;
|
|
45
|
+
}
|
|
46
|
+
// The last resort: hide every form in the raw line with its control
|
|
47
|
+
// characters dropped. It may no longer be valid JSON, but it holds no secret.
|
|
48
|
+
const hideInRawLine = (line, forms) => redactSecrets(withoutControls(line), { secrets: forms });
|
|
49
|
+
/** One printed --json line with the secrets this process holds hidden. */
|
|
50
|
+
export function hideHeldSecrets(line) {
|
|
51
|
+
const secrets = errorOutputSecrets();
|
|
52
|
+
if (secrets.length === 0)
|
|
53
|
+
return line;
|
|
54
|
+
const forms = secrets.flatMap(writtenForms).sort((left, right) => right.length - left.length);
|
|
55
|
+
if (!holdsAny(line, forms))
|
|
56
|
+
return line;
|
|
57
|
+
let rewritten;
|
|
58
|
+
try {
|
|
59
|
+
const parsed = JSON.parse(line);
|
|
60
|
+
// Keep a pretty-printed object's indent; anything else stays compact.
|
|
61
|
+
const indent = /^[[{]\n( +)/.exec(line)?.[1].length;
|
|
62
|
+
rewritten = JSON.stringify(hideInValue(parsed, forms), null, indent);
|
|
63
|
+
}
|
|
64
|
+
catch {
|
|
65
|
+
rewritten = hideInText(line, forms);
|
|
66
|
+
}
|
|
67
|
+
// Fail closed: a secret the rewrite missed (a number, a shape not handled
|
|
68
|
+
// above) is hidden from the raw line instead.
|
|
69
|
+
return holdsAny(rewritten, forms) ? hideInRawLine(line, forms) : rewritten;
|
|
70
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"one-request-write.d.ts","sourceRoot":"","sources":["../src/one-request-write.ts"],"names":[],"mappings":"AAAA,OAAO,EAA+B,MAAM,EAAE,MAAM,QAAQ,CAAA;
|
|
1
|
+
{"version":3,"file":"one-request-write.d.ts","sourceRoot":"","sources":["../src/one-request-write.ts"],"names":[],"mappings":"AAAA,OAAO,EAA+B,MAAM,EAAE,MAAM,QAAQ,CAAA;AAc5D,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,iBAAiB,EAAE,IAAI,CAAA;IAChC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CACxB;AAED,qDAAqD;AACrD,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAEzF;AAED,kDAAkD;AAClD,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,MAAM,GAAG,iBAAiB,CAEzE;AAED,uFAAuF;AACvF,MAAM,WAAW,qBAAqB;IACpC,0BAA0B;IAC1B,KAAK,EAAE,MAAM,CAAA;IACb,6BAA6B;IAC7B,IAAI,EAAE,MAAM,CAAA;IACZ,wFAAwF;IACxF,MAAM,EAAE,MAAM,CAAA;CACf;AAID,MAAM,WAAW,eAAe,CAAC,CAAC;IAChC,gFAAgF;IAChF,KAAK,EAAE,MAAM,CAAA;IACb,2EAA2E;IAC3E,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,MAAM,GAAG,OAAO,GAAG,QAAQ,CAAA;IACnC,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,KAAK,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAA;IACxB,iBAAiB,EAAE,qBAAqB,CAAA;IACxC;;;OAGG;IACH,aAAa,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,KAAK,OAAO,CAAC;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE;YAAE,KAAK,EAAE,MAAM,CAAA;SAAE,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,CAAC,CAAA;IACvH,IAAI,EAAE,OAAO,CAAA;IACb,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;IAC7B,0FAA0F;IAC1F,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAA;CACjE;AAED,MAAM,MAAM,sBAAsB,CAAC,CAAC,IAChC;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,CAAC,CAAA;CAAE,GAC3B;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,QAAQ,EAAE,GAAG,GAAG,GAAG,CAAA;CAAE,CAAA;AAmFhD;;;;;;GAMG;AACH,wBAAsB,mBAAmB,CAAC,CAAC,EAAE,KAAK,EAAE,eAAe,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC,CA6B1G"}
|
|
@@ -3,9 +3,7 @@ import { datasetTransferTimeoutMs } from './dataset-transfer-policy.js';
|
|
|
3
3
|
import { isJsonErrorResponsePayload } from './error-response.js';
|
|
4
4
|
import { authedFetch } from './http.js';
|
|
5
5
|
import { sanitizeTerminalText } from './json-response.js';
|
|
6
|
-
import { errorOutputSecrets } from './last-error-record.js';
|
|
7
6
|
import { unreachedCode } from './request-outcome.js';
|
|
8
|
-
import { redactSecrets } from './secret-redaction.js';
|
|
9
7
|
/** `The <thing> may already be <done>: <advice>.` */
|
|
10
8
|
export function mayAlreadyBeSavedLine(thing, done, advice) {
|
|
11
9
|
return `The ${thing} may already be ${done}: ${advice}.`;
|
|
@@ -109,11 +107,6 @@ function send(write, timeoutMs, onSent) {
|
|
|
109
107
|
});
|
|
110
108
|
});
|
|
111
109
|
}
|
|
112
|
-
// A `--json` failure object can quote the server's error text, so secrets this
|
|
113
|
-
// process holds (the bearer, a forwarded key) are hidden there as on stderr.
|
|
114
|
-
function printJson(write, value) {
|
|
115
|
-
write.print(JSON.stringify(redactSecrets(value, { secrets: errorOutputSecrets() })));
|
|
116
|
-
}
|
|
117
110
|
/**
|
|
118
111
|
* Sends one write. Ctrl-C or SIGTERM stops the wait and returns `interrupted`
|
|
119
112
|
* with the shell's usual exit code; the server may still finish on its own, so
|
|
@@ -138,7 +131,7 @@ export async function sendOneRequestWrite(write) {
|
|
|
138
131
|
const message = `${write.name} interrupted.`;
|
|
139
132
|
const unknown = sent ? mayAlreadyBeSavedFields(write.mayAlreadyBeSaved.advice) : {};
|
|
140
133
|
if (write.json)
|
|
141
|
-
|
|
134
|
+
write.print(JSON.stringify({ error: message, ...unknown }));
|
|
142
135
|
process.stderr.write(sent ? `${message}\n${noteLine(write.mayAlreadyBeSaved)}\n` : `${message}\n`);
|
|
143
136
|
return { kind: 'interrupted', exitCode: interrupted };
|
|
144
137
|
}
|
|
@@ -146,7 +139,7 @@ export async function sendOneRequestWrite(write) {
|
|
|
146
139
|
if (!(failure instanceof WriteFailure))
|
|
147
140
|
throw failure;
|
|
148
141
|
if (write.json) {
|
|
149
|
-
|
|
142
|
+
write.print(JSON.stringify({ ...failure.json, ...(failure.mayBeSaved ? mayAlreadyBeSavedFields(write.mayAlreadyBeSaved.advice) : {}) }));
|
|
150
143
|
}
|
|
151
144
|
throw new Error(failure.mayBeSaved ? `${failure.message}\n${noteLine(write.mayAlreadyBeSaved)}` : failure.message);
|
|
152
145
|
}
|
package/dist/workbench-cli.d.ts
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* do not print. The thin `workbenchCommand` entry point owns CLI argument
|
|
6
6
|
* parsing and human/JSON output.
|
|
7
7
|
*/
|
|
8
|
-
import {
|
|
8
|
+
import type { StartIntentIdGenerator } from './start-intent.js';
|
|
9
9
|
export interface WorkbenchFetcher {
|
|
10
10
|
(path: string, init?: RequestInit): Promise<Response>;
|
|
11
11
|
}
|
|
@@ -232,6 +232,7 @@ export declare function runWorkbenchRunStart(opts: WorkbenchRunStartOptions): Pr
|
|
|
232
232
|
export declare function runWorkbenchRunStatus(opts: WorkbenchRunStatusOptions): Promise<WorkbenchRunResult>;
|
|
233
233
|
export declare function runWorkbenchRunTerminal(opts: WorkbenchRunTerminalOptions): Promise<WorkbenchRunResult>;
|
|
234
234
|
export declare function tailOnce(fetcher: WorkbenchFetcher, runId: string, cursor: number, limit?: number): Promise<TailOnceResult>;
|
|
235
|
+
/** Also the hosted session CLI's attached tail: same signature, no stop handlers. */
|
|
235
236
|
export declare function tailWorkbenchRun(opts: TailWorkbenchRunOptions): Promise<TailOnceResult>;
|
|
236
237
|
export declare function workbenchCommand(args: string[], io: WorkbenchCommandIo): Promise<number>;
|
|
237
238
|
//# sourceMappingURL=workbench-cli.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workbench-cli.d.ts","sourceRoot":"","sources":["../src/workbench-cli.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;
|
|
1
|
+
{"version":3,"file":"workbench-cli.d.ts","sourceRoot":"","sources":["../src/workbench-cli.ts"],"names":[],"mappings":"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"}
|