@gitroll/tacitt-cli 0.1.0 → 0.3.0

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 (59) hide show
  1. package/dist/{agent-setup-B85GaVIz.mjs → agent-setup-CLXdKr2I.mjs} +2 -2
  2. package/dist/agent-setup-worker.mjs +5 -5
  3. package/dist/cli.mjs +165 -9
  4. package/dist/codex-title-worker.mjs +1 -1
  5. package/dist/configured-preview-worker.mjs +5 -5
  6. package/dist/configured-session-worker.mjs +25 -4
  7. package/dist/{frame-D1j9R8xX.mjs → frame-waS5FnN5.mjs} +1 -1
  8. package/dist/{heap-tfU61Ehy.mjs → heap-eO_uWpD1.mjs} +63 -9
  9. package/dist/inspection-worker.mjs +57 -0
  10. package/dist/job-rK-Ho9OD.mjs +613 -0
  11. package/dist/{locate-Bn32k2se.mjs → locate-U3-nkird.mjs} +29 -6
  12. package/dist/messages-D3m3bhva.mjs +40 -0
  13. package/dist/{model-7Nu7szNP.mjs → model-BBAnsFAx.mjs} +1 -1
  14. package/dist/operation-executor.mjs +3 -3
  15. package/dist/preview-worker.mjs +1 -1
  16. package/dist/privacy-validator.mjs +1 -1
  17. package/dist/{query-Da-KDbSV.mjs → query-DN99jiRc.mjs} +710 -630
  18. package/dist/{run-CCATsHS2.mjs → run-4G_CvdDj.mjs} +4 -4
  19. package/dist/session-process.mjs +6 -1
  20. package/dist/{src-CPPjOyHZ.mjs → src-B4R5XMEP.mjs} +621 -224
  21. package/dist/{src-BngGpFKd.mjs → src-CPbdnGrk.mjs} +130 -53
  22. package/dist/{src-DynBRDBc.mjs → src-qoLRvX-A.mjs} +34 -11
  23. package/dist/store-database-worker.mjs +1 -1
  24. package/dist/web/assets/index-BkuUI3Eu.js +67 -0
  25. package/dist/web/assets/index-Clg6Pfv_.css +1 -0
  26. package/dist/web/index.html +2 -2
  27. package/package.json +1 -1
  28. package/skills/tacitt/SKILL.md +15 -11
  29. package/skills/tacitt/references/b-method.md +1 -1
  30. package/skills/tacitt/references/classification.md +3 -3
  31. package/skills/tacitt/references/commands.md +19 -14
  32. package/skills/tacitt/references/journey.md +17 -11
  33. package/skills/tacitt/references/parallel-review.md +3 -3
  34. package/skills/tacitt/references/send.md +5 -5
  35. package/skills/tacitt/scripts/INDEX.md +6 -2
  36. package/skills/tacitt/scripts/answer.mjs +29 -8
  37. package/skills/tacitt/scripts/journey-card-consolidation.d.mts +13 -4
  38. package/skills/tacitt/scripts/journey-card-consolidation.mjs +170 -21
  39. package/skills/tacitt/scripts/journey-card-values.d.mts +17 -0
  40. package/skills/tacitt/scripts/journey-card-values.mjs +116 -0
  41. package/skills/tacitt/scripts/journey-classification-progress.mjs +2 -1
  42. package/skills/tacitt/scripts/journey-classification-validation.mjs +49 -28
  43. package/skills/tacitt/scripts/journey-classification.mjs +6 -2
  44. package/skills/tacitt/scripts/journey-consolidation-submit.mjs +42 -5
  45. package/skills/tacitt/scripts/journey-consolidation.d.mts +5 -0
  46. package/skills/tacitt/scripts/journey-consolidation.mjs +4 -1
  47. package/skills/tacitt/scripts/journey-panel-host.d.mts +9 -0
  48. package/skills/tacitt/scripts/journey-panel-host.mjs +56 -0
  49. package/skills/tacitt/scripts/journey-state.d.mts +1 -0
  50. package/skills/tacitt/scripts/journey-state.mjs +38 -6
  51. package/skills/tacitt/scripts/journey-tasks.mjs +5 -3
  52. package/skills/tacitt/scripts/journey.d.mts +4 -0
  53. package/skills/tacitt/scripts/journey.mjs +249 -41
  54. package/skills/tacitt/scripts/privacy-validator.mjs +25 -6
  55. package/skills/tacitt/scripts/review-stream-client.mjs +1 -1
  56. package/skills/tacitt/scripts/review.mjs +24 -3
  57. package/dist/job--TceKk0l.mjs +0 -194
  58. package/dist/web/assets/index-CWQ05PFl.js +0 -67
  59. package/dist/web/assets/index-J-AWt_cW.css +0 -1
@@ -1,6 +1,6 @@
1
- import { Bn as validatePlan, Cn as sessionNonce, Dn as entityDictionaryVersion, En as cleanupImplementationVersion, Fn as frameRecords, Gn as detectStatic, H as codePointLength, Hn as defaultLimits, Ht as ApplicationError, In as retainedMainTextNodes, Jn as jsonSpans, Jt as reviewFamilies, Ln as validateProfile, Nn as nativeText, On as nativeParserVersion, Pn as transformRecords, Qt as sourceSnapshotId, Sn as createReplacementKey, Tn as parseNativeRecord, Un as recordPointerLimits, V as bDigest, Wn as resolveLimits, Wt as safeCode, Xn as createEntityMatcher, Xt as sourceKey, Yn as agentContextLocation, an as withMandatoryCustomTerms, c as textDigest, cn as mainReviewRole, dn as renderNative, fn as createSessionPreparation, gn as createDetectionSummary, in as nativeSourceIdentitySchema, ir as isProcessingCode, j as bDuplicateShift, jn as nativeField, k as bBindingCap, kn as redactionImplementationVersion, ln as reviewRoles, nr as ProcessingError, o as reviewDigest, on as processNativeRecord, pn as bindInspection, qt as familySelected, rr as fail$1, sn as projectNativeReviewInput, tr as defaultDetectionLimits, un as createSentenceContext, vn as walkNativeFields, wn as projectNativeRecord, x as createBAnalysisUnits, zn as buildPlan } from "./locate-Bn32k2se.mjs";
2
- import { t as createZstdFrameCheck } from "./frame-D1j9R8xX.mjs";
3
- import { Fn as bWordBounded, I as sourceIdentityEvidence, L as withSourceEvidence, Mn as bExceptionRanges, Pt as metadataProcessingVersion, R as agentSetupKey, Yr as sourceChangePolicy, Zr as approvedTreatmentSchema, at as defaultAgentSetupInclusion, dr as resolveSourceSelection, it as classifyAgentSetup, jn as bContainment, ni as staticCatalogRef } from "./src-CPPjOyHZ.mjs";
1
+ import { Bn as validatePlan, Cn as sessionNonce, Dn as entityDictionaryVersion, En as cleanupImplementationVersion, Fn as frameRecords, Gn as detectStatic, H as codePointLength, Hn as defaultLimits, Ht as ApplicationError, In as retainedMainTextNodes, Jn as jsonSpans, Jt as reviewFamilies, Ln as validateProfile, Nn as nativeText, On as nativeParserVersion, Pn as transformRecords, Qt as sourceSnapshotId, Sn as createReplacementKey, Tn as parseNativeRecord, Un as recordPointerLimits, V as bDigest, Wn as resolveLimits, Wt as safeCode, Xn as createEntityMatcher, Xt as sourceKey, Yn as agentContextLocation, an as withMandatoryCustomTerms, c as textDigest, cn as mainReviewRole, dn as renderNative, fn as createSessionPreparation, gn as createDetectionSummary, in as nativeSourceIdentitySchema, ir as isProcessingCode, j as bDuplicateShift, jn as nativeField, k as bBindingCap, kn as redactionImplementationVersion, ln as reviewRoles, nr as ProcessingError, o as reviewDigest, on as processNativeRecord, pn as bindInspection, qt as familySelected, rr as fail$1, sn as projectNativeReviewInput, tr as defaultDetectionLimits, un as createSentenceContext, vn as walkNativeFields, wn as projectNativeRecord, x as createBAnalysisUnits, zn as buildPlan } from "./locate-U3-nkird.mjs";
2
+ import { t as createZstdFrameCheck } from "./frame-waS5FnN5.mjs";
3
+ import { Bn as bWordBounded, F as withSourceEvidence, I as agentSetupKey, In as bContainment, Ln as bExceptionRanges, Nt as metadataProcessingVersion, P as sourceIdentityEvidence, gr as resolveSourceSelection, ii as approvedTreatmentSchema, it as defaultAgentSetupInclusion, li as staticCatalogRef, ni as sourceChangePolicy, rt as classifyAgentSetup } from "./src-B4R5XMEP.mjs";
4
4
  import { constants } from "node:fs";
5
5
  import { link, lstat, mkdir, open, readFile, readdir, realpath, rm, rmdir, stat, unlink } from "node:fs/promises";
6
6
  import { execFile, fork, spawn } from "node:child_process";
@@ -678,10 +678,16 @@ const chooseFinal = async (directory, start = 0) => {
678
678
  }
679
679
  return fail("ARTIFACT_LIMIT");
680
680
  };
681
- const createTemporary = async (options) => {
681
+ /**
682
+ * `onPath` receives the temporary path before the file exists, so an owner that stops this
683
+ * process mid-call can remove it. On Windows the privacy checks after creation take ACL helper
684
+ * round trips, so a name reported only afterwards could leave an unreported file.
685
+ */
686
+ const createTemporary = async (options, onPath) => {
682
687
  const directory = await outputDirectory(options);
683
688
  const finalPath = await chooseFinal(directory);
684
689
  const tempPath = join(directory, `.sess-pilot-${randomUUID()}.part`);
690
+ onPath?.(tempPath);
685
691
  const handle = await openPrivateFile(tempPath, constants.O_CREAT | constants.O_EXCL | constants.O_RDWR | constants.O_NOFOLLOW, 384);
686
692
  try {
687
693
  const value = await handle.stat({ bigint: true });
@@ -729,6 +735,13 @@ const removeSpools = async (directory, temporary) => {
729
735
  else if (!name.endsWith(".parallel") && value.isFile()) await unlink(path);
730
736
  }
731
737
  };
738
+ /**
739
+ * Removes the `<temp>.<uuid>.<kind>` spools beside each temporary file a stopped packaging child
740
+ * named (ADR 0228); the child's own cleanup never ran. Other named files are left to their owner.
741
+ */
742
+ const removeNamedTemporarySpools = async (paths) => {
743
+ for (const path of paths) if (/\.sess-pilot-[a-f0-9-]{36}\.part$/.test(basename(path))) await removeSpools(dirname(path), { tempPath: path });
744
+ };
732
745
  //#endregion
733
746
  //#region packages/artifact/src/file/reader.ts
734
747
  var FileReader = class extends Reader {
@@ -3294,6 +3307,7 @@ async function createSessionArchiveSpool(temporary, signal, options = {}) {
3294
3307
  checkAbort(signal);
3295
3308
  const path = options.directory === void 0 ? `${temporary.tempPath}.${randomUUID()}.session` : `${options.directory}/${randomUUID()}.session`;
3296
3309
  let handle;
3310
+ if (options.keepPath === true) options.onPath?.(path);
3297
3311
  try {
3298
3312
  handle = await (options.directory === void 0 ? openPrivateFile : open)(path, constants.O_CREAT | constants.O_EXCL | constants.O_RDWR | constants.O_NOFOLLOW, 384);
3299
3313
  if (options.keepPath !== true) await unlink(path);
@@ -4025,7 +4039,7 @@ function nativeIdentityKey(value) {
4025
4039
  ]
4026
4040
  ]);
4027
4041
  }
4028
- async function prepareSources(request, owner, metadata, collect) {
4042
+ async function prepareSources(request, owner, metadata, collect, onImages) {
4029
4043
  if (request.sources.length === 0 || request.sources.length > 1e4) fail("ARTIFACT_EMPTY_SCOPE");
4030
4044
  requireCurrentCleanup(request.treatment.cleanup);
4031
4045
  const snapshots = /* @__PURE__ */ new Map();
@@ -4050,6 +4064,7 @@ async function prepareSources(request, owner, metadata, collect) {
4050
4064
  inspector.inspect(root);
4051
4065
  collect?.(root);
4052
4066
  const selection = retain(root);
4067
+ if (selection.images) onImages?.(selection.images);
4053
4068
  prepareOriginals(root, selection, adapter.annotations(root, nativeOptions, selection), owner.preparation, owner.limits, owner.signal);
4054
4069
  ordinal += 1;
4055
4070
  }
@@ -4913,7 +4928,10 @@ async function prepareConfiguredSession(request) {
4913
4928
  const metadata = metadataRoot(request, owner.limits);
4914
4929
  const gitIdentity = await prepareGit(request, owner.signal, owner.preparation);
4915
4930
  const agentSetup = request.collectAgentSetup ? createAgentSetupCollector(request) : void 0;
4916
- const snapshots = await prepareSources(request, owner, metadata, agentSetup?.add);
4931
+ let images = 0;
4932
+ const snapshots = await prepareSources(request, owner, metadata, agentSetup?.add, (count) => {
4933
+ images += count;
4934
+ });
4917
4935
  owner.seal();
4918
4936
  guardSourceIdentities(request, owner);
4919
4937
  const finished = /* @__PURE__ */ new Set();
@@ -4977,7 +4995,8 @@ async function prepareConfiguredSession(request) {
4977
4995
  metadata: processedMetadata.text,
4978
4996
  ...processedMetadata.masks === void 0 ? {} : { metadataMasks: processedMetadata.masks },
4979
4997
  sources: Object.freeze(sources),
4980
- agentSetup: Object.freeze(setup)
4998
+ agentSetup: Object.freeze(setup),
4999
+ images
4981
5000
  });
4982
5001
  await owner.close();
4983
5002
  completion = result;
@@ -8991,17 +9010,16 @@ async function privateJourneyDirectory(path) {
8991
9010
  //#region packages/artifact/src/configured/journey/output.ts
8992
9011
  /**
8993
9012
  * The same checked private publication used for bases, with a fresh immutable output ID.
8994
- * `onPath` names each file this call may leave behind: a temporary file once created, a published
8995
- * one before it is linked, so a packaging worker's owner can remove them when it stops the worker
8996
- * mid-write (ADR 0181).
9013
+ * `onPath` names each file this call may leave behind: a temporary file before it is created, a
9014
+ * published one before it is linked, so a packaging worker's owner can remove them when it stops
9015
+ * the worker mid-write (ADR 0181).
8997
9016
  */
8998
9017
  async function writeLogicalJourneyOutput(request, signal, onPath) {
8999
9018
  const directory = await privateJourneyDirectory(request.directory);
9000
9019
  const primary = await createTemporary({
9001
9020
  outputDir: directory,
9002
9021
  keepTemp: false
9003
- });
9004
- onPath?.(primary.temporary.tempPath);
9022
+ }, onPath);
9005
9023
  let companion;
9006
9024
  let masks;
9007
9025
  const cleanup = createCleanup(), linked = [];
@@ -9011,15 +9029,11 @@ async function writeLogicalJourneyOutput(request, signal, onPath) {
9011
9029
  companion = await createTemporary({
9012
9030
  outputDir: directory,
9013
9031
  keepTemp: false
9014
- });
9015
- onPath?.(companion.temporary.tempPath);
9016
- if (request.maskEvidence) {
9017
- masks = await createTemporary({
9018
- outputDir: directory,
9019
- keepTemp: false
9020
- });
9021
- onPath?.(masks.temporary.tempPath);
9022
- }
9032
+ }, onPath);
9033
+ if (request.maskEvidence) masks = await createTemporary({
9034
+ outputDir: directory,
9035
+ keepTemp: false
9036
+ }, onPath);
9023
9037
  const written = await rewriteConfiguredOutput({
9024
9038
  ...request,
9025
9039
  bundleId,
@@ -9295,6 +9309,14 @@ function isResult(value) {
9295
9309
  };
9296
9310
  return file("primary") && file("ledger") && typeof pieces === "object" && pieces !== null && Array.isArray(Reflect.get(pieces, "entries")) && Array.isArray(Reflect.get(pieces, "maskEntries")) && Array.isArray(Reflect.get(value, "tokens")) && typeof Reflect.get(value, "tokensComplete") === "boolean";
9297
9311
  }
9312
+ if (Reflect.get(value, "kind") === "journey-base") {
9313
+ const base = Reflect.get(value, "base");
9314
+ const file = (key) => {
9315
+ const item = typeof base === "object" && base !== null ? Reflect.get(base, key) : void 0;
9316
+ return typeof item === "object" && item !== null && typeof Reflect.get(item, "path") === "string";
9317
+ };
9318
+ return typeof base === "object" && base !== null && Reflect.get(base, "kind") === "base" && typeof Reflect.get(base, "bundleId") === "string" && file("primary") && file("companion") && file("maskLedger") && Array.isArray(Reflect.get(base, "sessions")) && Array.isArray(Reflect.get(base, "sourceBindings"));
9319
+ }
9298
9320
  if (Reflect.get(value, "kind") === "journey-output") {
9299
9321
  const output = Reflect.get(value, "output");
9300
9322
  return typeof output === "object" && output !== null && typeof Reflect.get(output, "bundleId") === "string" && typeof Reflect.get(output, "primary") === "object" && typeof Reflect.get(output, "companion") === "object" && Array.isArray(Reflect.get(value, "tokens")) && typeof Reflect.get(value, "tokensComplete") === "boolean";
@@ -9315,6 +9337,8 @@ function isWorkerMessage(value) {
9315
9337
  if (kind === "worker-error") return code === "ARTIFACT_WORKER_MEMORY" || code === "ARTIFACT_PROCESSING_FAILED";
9316
9338
  return kind === "error" && typeof code === "string" && code.length > 0 && (sourceId === void 0 || typeof sourceId === "string");
9317
9339
  }
9340
+ /** How long a stopped controller may take to end its Worker and flush its messages (ADR 0219). */
9341
+ const stopGraceMs = 2e3;
9318
9342
  /** One active request per process; IPC backpressure never causes a resend or another queue. */
9319
9343
  function createSessionProcess(workerUrl, heapMb, onMessage, onFailure) {
9320
9344
  const options = {
@@ -9349,7 +9373,7 @@ function createSessionProcess(workerUrl, heapMb, onMessage, onFailure) {
9349
9373
  closed.then(() => onFailure(memoryFailure ? "ARTIFACT_WORKER_MEMORY" : "ARTIFACT_PROCESSING_FAILED"));
9350
9374
  };
9351
9375
  child.on("message", (message) => {
9352
- if (!closing) onMessage(message);
9376
+ if (!closing || Reflect.get(Object(message), "kind") === "spool") onMessage(message);
9353
9377
  });
9354
9378
  child.on("error", fail);
9355
9379
  child.on("disconnect", fail);
@@ -9371,7 +9395,20 @@ function createSessionProcess(workerUrl, heapMb, onMessage, onFailure) {
9371
9395
  async close() {
9372
9396
  if (!closing) {
9373
9397
  closing = true;
9374
- if (child.exitCode === null && child.signalCode === null) child.kill("SIGKILL");
9398
+ if (child.exitCode === null && child.signalCode === null) {
9399
+ const kill = () => {
9400
+ if (child.exitCode === null && child.signalCode === null) child.kill("SIGKILL");
9401
+ };
9402
+ const timer = setTimeout(kill, stopGraceMs);
9403
+ try {
9404
+ if (child.connected) child.send({ kind: "stop" }, (error) => error && kill());
9405
+ else kill();
9406
+ } catch {
9407
+ kill();
9408
+ }
9409
+ await closed;
9410
+ clearTimeout(timer);
9411
+ }
9375
9412
  }
9376
9413
  await closed;
9377
9414
  }
@@ -9406,6 +9443,34 @@ function sessionWorkerFailure(error) {
9406
9443
  function requestKind(task) {
9407
9444
  return typeof task.message === "object" && task.message !== null ? Reflect.get(task.message, "kind") : void 0;
9408
9445
  }
9446
+ /**
9447
+ * Files one job may name: a journey output its three final files and three temporary files
9448
+ * (ADR 0181), an output shard its two archives and a shard readback none (ADR 0199).
9449
+ */
9450
+ /**
9451
+ * A journey output or base names its three final files and three temporary files (ADR 0181,
9452
+ * ADR 0228); an output shard its two archives and a shard readback none (ADR 0199).
9453
+ */
9454
+ function spoolLimit(task) {
9455
+ const kind = requestKind(task);
9456
+ return kind === "journey-output" || kind === "journey-base" ? 6 : kind === "journey-output-shard" ? 2 : kind === "journey-output-verify" ? 0 : 4;
9457
+ }
9458
+ const factsName = /^(.+)\.[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\.facts$/;
9459
+ /**
9460
+ * Best-effort removal of a stopped job's files: its named spools and the facts files created
9461
+ * beside them (`<spool>.<uuid>.facts`), which are unlinked once open but can keep their name
9462
+ * when the process stops in between; on Windows that spans two ACL helper round trips.
9463
+ */
9464
+ async function removeStoppedSpools(paths) {
9465
+ for (const [directory, spools] of Map.groupBy(paths, (path) => dirname(path))) {
9466
+ for (const path of spools) await unlink(path).catch(() => {});
9467
+ const names = new Set(spools.map((path) => basename(path)));
9468
+ for (const entry of await readdir(directory).catch(() => [])) {
9469
+ const spool = factsName.exec(entry)?.[1];
9470
+ if (spool !== void 0 && names.has(spool)) await unlink(join(directory, entry)).catch(() => {});
9471
+ }
9472
+ }
9473
+ }
9409
9474
  /** Best-effort removal of a worker spool that no longer has an owner. */
9410
9475
  function removeSpool(path) {
9411
9476
  if (path === void 0) return;
@@ -9479,7 +9544,7 @@ function createSessionWorkerPool(url, size, heapMb = workerHeapMb) {
9479
9544
  stopping = Promise.all(slots.map(async (slot) => {
9480
9545
  try {
9481
9546
  await slot.process.close();
9482
- for (const path of slot.task?.spoolPaths ?? []) await unlink(path).catch(() => {});
9547
+ if (slot.task) await removeStoppedSpools(slot.task.spoolPaths);
9483
9548
  } finally {
9484
9549
  slot.task?.reject(blame(slot));
9485
9550
  slot.task = void 0;
@@ -9494,8 +9559,11 @@ function createSessionWorkerPool(url, size, heapMb = workerHeapMb) {
9494
9559
  };
9495
9560
  const onAbort = () => stop(/* @__PURE__ */ new Error("ARTIFACT_ABORTED"));
9496
9561
  const receive = (slot, message) => {
9497
- if (closed) return;
9498
9562
  const task = slot.task;
9563
+ if (closed) {
9564
+ if (task && isWorkerMessage(message) && message.kind === "spool" && (task.spoolPaths.has(message.path) || task.spoolPaths.size < spoolLimit(task))) task.spoolPaths.add(message.path);
9565
+ return;
9566
+ }
9499
9567
  if (!isWorkerMessage(message)) {
9500
9568
  failPool(/* @__PURE__ */ new Error("ARTIFACT_PROCESSING_FAILED"), slot);
9501
9569
  return;
@@ -9511,9 +9579,7 @@ function createSessionWorkerPool(url, size, heapMb = workerHeapMb) {
9511
9579
  try {
9512
9580
  if (message.kind === "source") task.onSourceProgress?.(message.bytes);
9513
9581
  else if (message.kind === "spool") {
9514
- const kind = requestKind(task);
9515
- const spoolLimit = kind === "journey-output" ? 6 : kind === "journey-output-shard" ? 2 : kind === "journey-output-verify" ? 0 : 4;
9516
- if (!task.spoolPaths.has(message.path) && task.spoolPaths.size >= spoolLimit) {
9582
+ if (!task.spoolPaths.has(message.path) && task.spoolPaths.size >= spoolLimit(task)) {
9517
9583
  failPool(/* @__PURE__ */ new Error("ARTIFACT_PROCESSING_FAILED"), slot);
9518
9584
  return;
9519
9585
  }
@@ -9521,7 +9587,7 @@ function createSessionWorkerPool(url, size, heapMb = workerHeapMb) {
9521
9587
  task.onSpool?.(message.path);
9522
9588
  } else if (message.kind === "result") {
9523
9589
  const requestedKind = requestKind(task);
9524
- if ((requestedKind === "render" || requestedKind === "capture" || requestedKind === "scan" || requestedKind === "journey-output" || requestedKind === "journey-output-shard" || requestedKind === "journey-output-verify") && message.result.kind !== requestedKind) {
9590
+ if ((requestedKind === "render" || requestedKind === "capture" || requestedKind === "scan" || requestedKind === "journey-output" || requestedKind === "journey-output-shard" || requestedKind === "journey-output-verify" || requestedKind === "journey-base") && message.result.kind !== requestedKind) {
9525
9591
  failPool(/* @__PURE__ */ new Error("ARTIFACT_PROCESSING_FAILED"), slot);
9526
9592
  return;
9527
9593
  }
@@ -9537,6 +9603,15 @@ function createSessionWorkerPool(url, size, heapMb = workerHeapMb) {
9537
9603
  settle(slot, void 0, message.result);
9538
9604
  return;
9539
9605
  }
9606
+ if (message.result.kind === "journey-base") {
9607
+ const { primary, companion, maskLedger } = message.result.base;
9608
+ if (!task.spoolPaths.has(primary.path) || !task.spoolPaths.has(companion.path) || !task.spoolPaths.has(maskLedger.path)) {
9609
+ failPool(/* @__PURE__ */ new Error("ARTIFACT_PROCESSING_FAILED"), slot);
9610
+ return;
9611
+ }
9612
+ settle(slot, void 0, message.result);
9613
+ return;
9614
+ }
9540
9615
  if (message.result.kind === "journey-output") {
9541
9616
  if (!task.spoolPaths.has(message.result.output.primary.path) || !task.spoolPaths.has(message.result.output.companion.path)) {
9542
9617
  failPool(/* @__PURE__ */ new Error("ARTIFACT_PROCESSING_FAILED"), slot);
@@ -10944,25 +11019,18 @@ async function runConfiguredSessionJob(job, processing, signal, onSourceProgress
10944
11019
  let processingMs = 0;
10945
11020
  const spoolOptions = {
10946
11021
  keepPath: true,
11022
+ ...onSpool === void 0 ? {} : { onPath: onSpool },
10947
11023
  ...job.spoolDirectory === void 0 ? {} : { directory: job.spoolDirectory }
10948
11024
  };
10949
11025
  const spool = await createSessionArchiveSpool(job.temporary, signal, spoolOptions);
10950
- onSpool?.(spool.path);
10951
11026
  let companion;
10952
11027
  let maskSpool;
10953
11028
  let reviewSpool;
10954
11029
  let session;
10955
11030
  try {
10956
11031
  companion = await createSessionArchiveSpool(job.temporary, signal, spoolOptions);
10957
- onSpool?.(companion.path);
10958
- if (job.captureMasks) {
10959
- maskSpool = await createSessionArchiveSpool(job.temporary, signal, spoolOptions);
10960
- onSpool?.(maskSpool.path);
10961
- }
10962
- if (job.captureReview) {
10963
- reviewSpool = await createSessionArchiveSpool(job.temporary, signal, spoolOptions);
10964
- onSpool?.(reviewSpool.path);
10965
- }
11032
+ if (job.captureMasks) maskSpool = await createSessionArchiveSpool(job.temporary, signal, spoolOptions);
11033
+ if (job.captureReview) reviewSpool = await createSessionArchiveSpool(job.temporary, signal, spoolOptions);
10966
11034
  const readPass = /* @__PURE__ */ new Map();
10967
11035
  const captures = new Map((job.captures ?? []).map((capture) => [capture.partId, capture]));
10968
11036
  session = await prepareConfiguredSession({
@@ -11039,7 +11107,8 @@ async function runConfiguredSessionJob(job, processing, signal, onSourceProgress
11039
11107
  metadata: completed.metadata,
11040
11108
  parts,
11041
11109
  entries,
11042
- agentSetup: completed.agentSetup
11110
+ agentSetup: completed.agentSetup,
11111
+ images: completed.images
11043
11112
  };
11044
11113
  } catch (error) {
11045
11114
  cleanup.failed(error);
@@ -14677,13 +14746,18 @@ async function writePrivateReviewPayload(request, signal) {
14677
14746
  }
14678
14747
  //#endregion
14679
14748
  //#region packages/artifact/src/configured/journey/base.ts
14680
- /** Publish an immutable, private base pair for review/resume without a public collection index. */
14681
- async function writeLogicalJourneyBase(request, hooks) {
14749
+ /**
14750
+ * Publish an immutable, private base pair for review/resume without a public collection index.
14751
+ * `onPath` names each file this call may leave behind: a temporary file before it is created, a
14752
+ * published one before it is linked, so a packaging worker's owner can remove them when it stops
14753
+ * the worker mid-write (ADR 0228). Session spools live under `<temporary>.<uuid>.parallel`.
14754
+ */
14755
+ async function writeLogicalJourneyBase(request, hooks, onPath) {
14682
14756
  const directory = await privateJourneyDirectory(request.directory);
14683
14757
  const primary = await createTemporary({
14684
14758
  outputDir: directory,
14685
14759
  keepTemp: false
14686
- });
14760
+ }, onPath);
14687
14761
  const cleanup = createCleanup();
14688
14762
  let companion;
14689
14763
  let masks;
@@ -14704,15 +14778,15 @@ async function writeLogicalJourneyBase(request, hooks) {
14704
14778
  companion = await createTemporary({
14705
14779
  outputDir: directory,
14706
14780
  keepTemp: false
14707
- });
14781
+ }, onPath);
14708
14782
  masks = await createTemporary({
14709
14783
  outputDir: directory,
14710
14784
  keepTemp: false
14711
- });
14785
+ }, onPath);
14712
14786
  if (request.captureReview) review = await createTemporary({
14713
14787
  outputDir: directory,
14714
14788
  keepTemp: false
14715
- });
14789
+ }, onPath);
14716
14790
  const written = await writeLogicalWorkBundle({
14717
14791
  production: request.production,
14718
14792
  work: request.work,
@@ -14728,15 +14802,19 @@ async function writeLogicalJourneyBase(request, hooks) {
14728
14802
  const primaryPath = join(directory, `${bundleId}.primary.zip`);
14729
14803
  const companionPath = join(directory, `${bundleId}.companion.zip`);
14730
14804
  const maskPath = join(directory, `${bundleId}.private-masks.zip`);
14805
+ onPath?.(primaryPath);
14731
14806
  await link(primary.temporary.tempPath, primaryPath);
14732
14807
  linked.push(primaryPath);
14808
+ onPath?.(companionPath);
14733
14809
  await link(companion.temporary.tempPath, companionPath);
14734
14810
  linked.push(companionPath);
14811
+ onPath?.(maskPath);
14735
14812
  await link(masks.temporary.tempPath, maskPath);
14736
14813
  linked.push(maskPath);
14737
14814
  if (!identityMatches(await lstat(primaryPath, { bigint: true }), primary.temporary.identity) || !identityMatches(await lstat(companionPath, { bigint: true }), companion.temporary.identity) || !identityMatches(await lstat(maskPath, { bigint: true }), masks.temporary.identity)) fail("ARTIFACT_IDENTITY_MISMATCH");
14738
14815
  const reviewPath = join(directory, `${bundleId}.private-review.zip`);
14739
14816
  if (review) {
14817
+ onPath?.(reviewPath);
14740
14818
  await link(review.temporary.tempPath, reviewPath);
14741
14819
  linked.push(reviewPath);
14742
14820
  if (!identityMatches(await lstat(reviewPath, { bigint: true }), review.temporary.identity)) fail("ARTIFACT_IDENTITY_MISMATCH");
@@ -15087,16 +15165,14 @@ async function writeOutputShard(request, signal, onPath) {
15087
15165
  const output = await createTemporary({
15088
15166
  outputDir: directory,
15089
15167
  keepTemp: false
15090
- });
15091
- onPath?.(output.temporary.tempPath);
15168
+ }, onPath);
15092
15169
  created.push(output.temporary.tempPath);
15093
15170
  handles.push(output.handle);
15094
15171
  sink = fileWriter(output.handle, signal);
15095
15172
  const ledger = await createTemporary({
15096
15173
  outputDir: directory,
15097
15174
  keepTemp: false
15098
- });
15099
- onPath?.(ledger.temporary.tempPath);
15175
+ }, onPath);
15100
15176
  created.push(ledger.temporary.tempPath);
15101
15177
  handles.push(ledger.handle);
15102
15178
  masks = await createFinalMaskWriter({
@@ -15179,11 +15255,12 @@ function protectedRanges(field, host, ranges) {
15179
15255
  */
15180
15256
  async function runConfiguredScanJob(job, processing, signal, onSourceProgress, onSpool) {
15181
15257
  const directory = await privateJourneyDirectory(job.directory);
15182
- const fields = await openRowFile(join(directory, `${randomUUID()}.scan.jsonl`), signal);
15258
+ const fieldsPath = join(directory, `${randomUUID()}.scan.jsonl`);
15259
+ onSpool?.(fieldsPath);
15260
+ const fields = await openRowFile(fieldsPath, signal);
15183
15261
  const cleanup = createCleanup();
15184
15262
  let success = false;
15185
15263
  try {
15186
- onSpool?.(fields.path);
15187
15264
  const captures = new Map(job.captures.map((capture) => [capture.partId, capture]));
15188
15265
  if (captures.size !== job.captures.length || job.sources.some((source) => !captures.has(source.source.id))) fail("ARTIFACT_SOURCE_CHANGED");
15189
15266
  if (job.sources.length === 0 || job.sources.length > 1e4) fail("ARTIFACT_EMPTY_SCOPE");
@@ -16413,4 +16490,4 @@ async function verifyPreparedSessionSources(prepared, input, signal) {
16413
16490
  }
16414
16491
  }
16415
16492
  //#endregion
16416
- export { exclusiveLock as $, runConfiguredSessionJob as A, writeLogicalJourneyOutput as B, readConfiguredSearchFields as C, captureLogicalJourneySources as D, prepareCollectionProduction as E, sessionWorkerFailure as F, staticMaskCategory as G, readLogicalJourneyFinalMasks as H, privateCollectionDirectory as I, createConfiguredPreviewStream as J, readWorkspacePair as K, defaultParallelism as L, parseCollectionWorkspaceSummary as M, createSharedSessionPool as N, capturedJourneyScope as O, SessionWorkerError as P, safeError as Q, gitSeedsProvider as R, readOriginalSearchFields as S, checkReusableBundle as T, readConfiguredOutputInfo as U, privateJourneyDirectory as V, processJourneyMetadataFields as W, createTemporary as X, createInspectionProcessor as Y, createCleanup as Z, readStaticSessionMasks as _, scanReviewFields as a, windowsAclCodes as at, writePrivateReviewPayload as b, readSessionScanRecords as c, verifyOutputShard as d, makePrivateDirectory as et, writeOutputShard as f, processJourneyMetadata as g, readCapturedOriginalRows as h, buildWorkScanBatches as i, isWindowsAclFailure as it, readCollectionIndex as j, renderJobDigest as k, scanPreparedSession as l, captureConfiguredSessionJob as m, verifyPreparedSessionSources as n, restrictToOwner as nt, createWorkPieces as o, openConfiguredUpload as p, listAgentSetup as q, prepareSessionScans as r, windowsOwnerOnly as rt, readSessionScanFields as s, preparedScanConfiguration as t, openPrivateFile as tt, runConfiguredScanJob as u, staticSessionJobs as v, createCollectionArtifacts as w, readPrivateReviewPayload as x, writeLogicalJourneyBase as y, parallelismLimits as z };
16493
+ export { safeError as $, runConfiguredSessionJob as A, writeLogicalJourneyOutput as B, readConfiguredSearchFields as C, captureLogicalJourneySources as D, prepareCollectionProduction as E, sessionWorkerFailure as F, staticMaskCategory as G, readLogicalJourneyFinalMasks as H, privateCollectionDirectory as I, createConfiguredPreviewStream as J, readWorkspacePair as K, defaultParallelism as L, parseCollectionWorkspaceSummary as M, createSharedSessionPool as N, capturedJourneyScope as O, SessionWorkerError as P, createCleanup as Q, gitSeedsProvider as R, readOriginalSearchFields as S, checkReusableBundle as T, readConfiguredOutputInfo as U, privateJourneyDirectory as V, processJourneyMetadataFields as W, createTemporary as X, createInspectionProcessor as Y, removeNamedTemporarySpools as Z, readStaticSessionMasks as _, scanReviewFields as a, isWindowsAclFailure as at, writePrivateReviewPayload as b, readSessionScanRecords as c, verifyOutputShard as d, exclusiveLock as et, writeOutputShard as f, processJourneyMetadata as g, readCapturedOriginalRows as h, buildWorkScanBatches as i, windowsOwnerOnly as it, readCollectionIndex as j, renderJobDigest as k, scanPreparedSession as l, captureConfiguredSessionJob as m, verifyPreparedSessionSources as n, openPrivateFile as nt, createWorkPieces as o, windowsAclCodes as ot, openConfiguredUpload as p, listAgentSetup as q, prepareSessionScans as r, restrictToOwner as rt, readSessionScanFields as s, preparedScanConfiguration as t, makePrivateDirectory as tt, runConfiguredScanJob as u, staticSessionJobs as v, createCollectionArtifacts as w, readPrivateReviewPayload as x, writeLogicalJourneyBase as y, parallelismLimits as z };
@@ -1,7 +1,7 @@
1
- import { An as nativeBoolean, Hn as defaultLimits, In as retainedMainTextNodes, Mn as nativeItems, Nn as nativeText, Qt as sourceSnapshotId, Tn as parseNativeRecord, Zt as observeSource, jn as nativeField, nr as ProcessingError, vn as walkNativeFields } from "./locate-Bn32k2se.mjs";
2
- import { Ft as nativeAdapterVersions, Kr as gitMetadataBudgetBytes, nt as reviewInventory } from "./src-CPPjOyHZ.mjs";
3
- import { a as isRecord, i as errorCode, n as checkDiscoveryAbort, o as unresolvedMetadata, r as discoveryBounds, t as DiscoveryWarnings } from "./model-7Nu7szNP.mjs";
4
- import { c as previewLimits, d as checkOpenSource, f as checkSource, h as openSource, i as pageFits, l as previewSourceVersion, m as noSymlinks, p as fileSnapshot, r as previewHeapLimits, s as previewMessageSchema, u as createZstdFrameCheck } from "./run-CCATsHS2.mjs";
1
+ import { An as nativeBoolean, Hn as defaultLimits, In as retainedMainTextNodes, Mn as nativeItems, Nn as nativeText, Qt as sourceSnapshotId, Tn as parseNativeRecord, Zt as observeSource, jn as nativeField, nr as ProcessingError, vn as walkNativeFields } from "./locate-U3-nkird.mjs";
2
+ import { $r as gitMetadataBudgetBytes, Pt as nativeAdapterVersions, tt as reviewInventory } from "./src-B4R5XMEP.mjs";
3
+ import { a as isRecord, i as errorCode, n as checkDiscoveryAbort, o as unresolvedMetadata, r as discoveryBounds, t as DiscoveryWarnings } from "./model-BBAnsFAx.mjs";
4
+ import { c as previewLimits, d as checkOpenSource, f as checkSource, h as openSource, i as pageFits, l as previewSourceVersion, m as noSymlinks, p as fileSnapshot, r as previewHeapLimits, s as previewMessageSchema, u as createZstdFrameCheck } from "./run-4G_CvdDj.mjs";
5
5
  import { a as titleHintLimits, n as titleHeapLimits, o as titleInputSchema, r as decodeTitleError, s as titleReplySchema } from "./heap-1FYhGds4.mjs";
6
6
  import { constants } from "node:fs";
7
7
  import { lstat, open, opendir, readFile, readdir, realpath, stat } from "node:fs/promises";
@@ -363,7 +363,8 @@ function interactionTime(value, harness) {
363
363
  "permission-mode",
364
364
  "pr-link",
365
365
  "relocated",
366
- "ai-title"
366
+ "ai-title",
367
+ "tools-used"
367
368
  ].includes(String(type))) return { kind: "unknown" };
368
369
  } else if ([
369
370
  "session_meta",
@@ -376,6 +377,7 @@ function interactionTime(value, harness) {
376
377
  else if (type === "response_item" && isRecord(value["payload"])) {
377
378
  const payload = value["payload"];
378
379
  if (payload["type"] === "message" && payload["role"] === "developer") return { kind: "other" };
380
+ if (payload["type"] === "configuration_update") return { kind: "other" };
379
381
  interaction = payload["type"] === "message" && [
380
382
  "user",
381
383
  "assistant",
@@ -666,7 +668,8 @@ const excludedRecords = /* @__PURE__ */ new Set([
666
668
  "frame-link",
667
669
  "artifact-autoreact-ledger",
668
670
  "artifact-comment-monitor",
669
- "worktree-state"
671
+ "worktree-state",
672
+ "tools-used"
670
673
  ]);
671
674
  /** Prove every conversational carrier, rather than trusting a deduplicated diagnostic node. */
672
675
  function claudeMainProseComplete(root, selection) {
@@ -838,6 +841,7 @@ function codexMainProseComplete(root, selection) {
838
841
  const type = typeOf(node);
839
842
  if (type === "message") return message(node);
840
843
  if (type === "agent_message") return message(node, "assistant");
844
+ if (type === "configuration_update") return !selection.diagnostics.some((diagnostic) => diagnostic.code === "unsupported-native-shape" && diagnostic.nodeId === node.id);
841
845
  return excludedItems.has(type ?? "");
842
846
  };
843
847
  const type = typeOf(root);
@@ -1315,7 +1319,8 @@ function codexItem(context, node) {
1315
1319
  "compaction",
1316
1320
  "web_search_call",
1317
1321
  "tool_search_call",
1318
- "tool_search_output"
1322
+ "tool_search_output",
1323
+ "configuration_update"
1319
1324
  ].includes(type ?? "")) {
1320
1325
  context.claim(node, context.origin("unknown", "unknown", "unknown"));
1321
1326
  return;
@@ -1368,7 +1373,10 @@ function codexItem(context, node) {
1368
1373
  "execution",
1369
1374
  "tools"
1370
1375
  ]);
1371
- else schemaKeys(context, node, common);
1376
+ else if (type === "configuration_update") {
1377
+ schemaKeys(context, node, [...common, "reasoning"]);
1378
+ schemaKeys(context, nativeField(node, "reasoning"), ["effort"]);
1379
+ } else schemaKeys(context, node, common);
1372
1380
  protect(context, node, ["timestamp"], "timestamp");
1373
1381
  if (type === "message" || type === "agent_message") codexMessage(context, node, type === "agent_message" ? nativeText(nativeField(node, "author")) : void 0);
1374
1382
  else if ([
@@ -1833,6 +1841,7 @@ function withOutput(holder, tags, select) {
1833
1841
  var ClaudeSelection = class {
1834
1842
  edits = [];
1835
1843
  diagnostics = [];
1844
+ images = 0;
1836
1845
  /** Tags of the tool result being selected; set only while one result is processed. */
1837
1846
  output;
1838
1847
  diagnose(code, node) {
@@ -1910,10 +1919,15 @@ var ClaudeSelection = class {
1910
1919
  };
1911
1920
  }
1912
1921
  }
1922
+ /** Counts one model-facing image block; sidecar and request copies are not counted. */
1923
+ image() {
1924
+ this.images += 1;
1925
+ }
1913
1926
  result() {
1914
1927
  return {
1915
1928
  edits: this.edits,
1916
- diagnostics: this.diagnostics
1929
+ diagnostics: this.diagnostics,
1930
+ ...this.images ? { images: this.images } : {}
1917
1931
  };
1918
1932
  }
1919
1933
  };
@@ -2144,6 +2158,7 @@ function outputMedia(body, selection) {
2144
2158
  }
2145
2159
  /** Readers check image blocks by type, media type and count; the encoded image is never read. */
2146
2160
  function imageBody(block, selection) {
2161
+ selection.image();
2147
2162
  selection.unread(() => mediaBody(block, selection));
2148
2163
  }
2149
2164
  function messageText(text, selection, worker, compact, user) {
@@ -2922,6 +2937,7 @@ function content(context, node, role, mode, userAttachments = false) {
2922
2937
  "output_image",
2923
2938
  "local_image"
2924
2939
  ].includes(type ?? "")) {
2940
+ if (context.images !== void 0) context.images += 1;
2925
2941
  const from = context.edits.length;
2926
2942
  media(context, part);
2927
2943
  unread(context, from);
@@ -3309,6 +3325,11 @@ function instructions(context, node) {
3309
3325
  function sessionContext(context, payload) {
3310
3326
  for (const key of ["base_instructions", "developer_instructions"]) instructions(context, nativeField(payload, key));
3311
3327
  }
3328
+ /** A harness-authored settings change, such as a new reasoning effort, carries no prose. */
3329
+ function configurationUpdate(context, payload) {
3330
+ const reasoning = nativeField(payload, "reasoning");
3331
+ if (payload.kind !== "object" || payload.properties.some(({ key }) => key.value !== "type" && key.value !== "reasoning") || reasoning !== void 0 && (reasoning.kind !== "object" || reasoning.properties.some(({ value }) => value.kind === "array" || value.kind === "object"))) unsupported(context, payload);
3332
+ }
3312
3333
  function worldState(context, payload) {
3313
3334
  const state = nativeField(payload, "state");
3314
3335
  if (state?.kind !== "object") {
@@ -3529,6 +3550,7 @@ function nativeItem(context, node, calls) {
3529
3550
  "text",
3530
3551
  "encrypted_content"
3531
3552
  ]) selectText(context, nativeField(node, key), key === "encrypted_content" ? "ciphertext" : "compaction", "remove");
3553
+ else if (type === "configuration_update") configurationUpdate(context, node);
3532
3554
  else if (type !== "web_search_call" && type !== "tool_search_call") unsupported(context, node);
3533
3555
  }
3534
3556
  function createCodexRetention(options) {
@@ -3538,12 +3560,13 @@ function createCodexRetention(options) {
3538
3560
  const inspector = codexSourceInspector();
3539
3561
  return (root) => {
3540
3562
  inspector.inspect(root);
3563
+ const type = fieldText(root, "type");
3541
3564
  const context = {
3542
3565
  sourceRole,
3543
3566
  edits: [],
3544
- diagnostics: []
3567
+ diagnostics: [],
3568
+ ...type === "response_item" ? { images: 0 } : {}
3545
3569
  };
3546
- const type = fieldText(root, "type");
3547
3570
  const payload = nativeField(root, "payload");
3548
3571
  if (type === "session_meta" && payload?.kind === "object") {
3549
3572
  if (codexIdentity(root).role === "unknown") unsupported(context, payload);
@@ -1,4 +1,4 @@
1
- import { i as createExecutor, t as assertStoreHeap } from "./heap-tfU61Ehy.mjs";
1
+ import { i as createExecutor, t as assertStoreHeap } from "./heap-eO_uWpD1.mjs";
2
2
  import { parentPort } from "node:worker_threads";
3
3
  //#region packages/local-host/src/store/worker/entry.ts
4
4
  if (!parentPort) throw new Error("STORE_WORKER_REQUIRED");