@gitroll/tacitt-cli 0.1.0 → 0.2.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 (50) hide show
  1. package/dist/{agent-setup-B85GaVIz.mjs → agent-setup-B8DAiQ6Z.mjs} +2 -2
  2. package/dist/agent-setup-worker.mjs +5 -5
  3. package/dist/cli.mjs +108 -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 +4 -4
  7. package/dist/{frame-D1j9R8xX.mjs → frame-waS5FnN5.mjs} +1 -1
  8. package/dist/{heap-tfU61Ehy.mjs → heap-BHcvxWCw.mjs} +20 -8
  9. package/dist/inspection-worker.mjs +57 -0
  10. package/dist/{job--TceKk0l.mjs → job-J3NFw3MH.mjs} +2 -2
  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-BJdTLNjT.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-BA0XCwnR.mjs} +486 -128
  18. package/dist/{run-CCATsHS2.mjs → run-BeLHsZWb.mjs} +4 -4
  19. package/dist/{src-DynBRDBc.mjs → src-B5SArpVY.mjs} +20 -9
  20. package/dist/{src-CPPjOyHZ.mjs → src-CC95LYYp.mjs} +271 -68
  21. package/dist/{src-BngGpFKd.mjs → src-k0Ya1Bri.mjs} +13 -7
  22. package/dist/store-database-worker.mjs +1 -1
  23. package/dist/web/assets/index-Bjos73wK.js +67 -0
  24. package/dist/web/assets/index-Bl4C2b2_.css +1 -0
  25. package/dist/web/index.html +2 -2
  26. package/package.json +1 -1
  27. package/skills/tacitt/SKILL.md +13 -11
  28. package/skills/tacitt/references/b-method.md +1 -1
  29. package/skills/tacitt/references/classification.md +3 -3
  30. package/skills/tacitt/references/commands.md +6 -6
  31. package/skills/tacitt/references/journey.md +13 -11
  32. package/skills/tacitt/references/parallel-review.md +3 -3
  33. package/skills/tacitt/references/send.md +5 -5
  34. package/skills/tacitt/scripts/answer.mjs +29 -8
  35. package/skills/tacitt/scripts/journey-card-consolidation.d.mts +13 -4
  36. package/skills/tacitt/scripts/journey-card-consolidation.mjs +81 -18
  37. package/skills/tacitt/scripts/journey-classification-progress.mjs +2 -1
  38. package/skills/tacitt/scripts/journey-classification-validation.mjs +49 -28
  39. package/skills/tacitt/scripts/journey-consolidation-submit.mjs +42 -5
  40. package/skills/tacitt/scripts/journey-consolidation.d.mts +5 -0
  41. package/skills/tacitt/scripts/journey-consolidation.mjs +4 -1
  42. package/skills/tacitt/scripts/journey-state.d.mts +1 -0
  43. package/skills/tacitt/scripts/journey-state.mjs +29 -3
  44. package/skills/tacitt/scripts/journey-tasks.mjs +4 -2
  45. package/skills/tacitt/scripts/journey.d.mts +2 -0
  46. package/skills/tacitt/scripts/journey.mjs +154 -13
  47. package/skills/tacitt/scripts/privacy-validator.mjs +25 -6
  48. package/skills/tacitt/scripts/review.mjs +24 -3
  49. package/dist/web/assets/index-CWQ05PFl.js +0 -67
  50. package/dist/web/assets/index-J-AWt_cW.css +0 -1
@@ -1,5 +1,5 @@
1
- import "./locate-Bn32k2se.mjs";
2
- import "./src-CPPjOyHZ.mjs";
1
+ import "./locate-U3-nkird.mjs";
2
+ import "./src-CC95LYYp.mjs";
3
3
  import { z } from "zod";
4
4
  import { Worker } from "node:worker_threads";
5
5
  //#region apps/cli/src/agent-setup/index.ts
@@ -1,8 +1,8 @@
1
- import { q as listAgentSetup } from "./src-BngGpFKd.mjs";
2
- import { rn as workspaceSchema, tn as sessionSchema, yn as createStaticProcessor } from "./locate-Bn32k2se.mjs";
3
- import { l as createNativeAdapters, u as createGitNameSeedProvider } from "./src-DynBRDBc.mjs";
4
- import { Qr as effectiveTreatmentSchema, ot as maximumAgentSetupSessions } from "./src-CPPjOyHZ.mjs";
5
- import "./agent-setup-B85GaVIz.mjs";
1
+ import { q as listAgentSetup } from "./src-k0Ya1Bri.mjs";
2
+ import { rn as workspaceSchema, tn as sessionSchema, yn as createStaticProcessor } from "./locate-U3-nkird.mjs";
3
+ import { l as createNativeAdapters, u as createGitNameSeedProvider } from "./src-B5SArpVY.mjs";
4
+ import { ct as maximumAgentSetupSessions, ni as effectiveTreatmentSchema } from "./src-CC95LYYp.mjs";
5
+ import "./agent-setup-B8DAiQ6Z.mjs";
6
6
  import { z } from "zod";
7
7
  import { parentPort, workerData } from "node:worker_threads";
8
8
  //#region apps/cli/src/agent-setup/worker.ts
package/dist/cli.mjs CHANGED
@@ -1,9 +1,9 @@
1
1
  #!/usr/bin/env node
2
- import { _ as startHost, a as createRuntime, c as createRenderActivity, d as businessCommands, f as longCommands, g as createExecutionPort, h as readStateDump, i as invoke, l as helpText, m as startupFailure, n as readOperation, o as executorEventSchema, p as permissionDiagnostic, r as waitOperation, t as cancelOperation, u as parseOptions, v as traceStartup } from "./query-Da-KDbSV.mjs";
3
- import { et as makePrivateDirectory, tt as openPrivateFile } from "./src-BngGpFKd.mjs";
4
- import { Gt as safeField, Ht as ApplicationError, Wt as safeCode } from "./locate-Bn32k2se.mjs";
5
- import { Jr as stateSchema, Qn as reviewTransportBytes, ct as resolveFailureLocation, tt as readWorkspaceOutcomes } from "./src-CPPjOyHZ.mjs";
6
- import { gt as isCoordinationBusy } from "./heap-tfU61Ehy.mjs";
2
+ import { _ as createExecutionPort, a as readAgentPresence, d as parseOptions, f as businessCommands, g as readStateDump, h as startupFailure, i as invoke, l as createRenderActivity, m as permissionDiagnostic, n as readOperation, o as createRuntime, p as longCommands, r as waitOperation, s as executorEventSchema, t as cancelOperation, u as helpText, v as startHost, y as traceStartup } from "./query-BA0XCwnR.mjs";
3
+ import { et as makePrivateDirectory, tt as openPrivateFile } from "./src-k0Ya1Bri.mjs";
4
+ import { Gt as safeField, Ht as ApplicationError, Wt as safeCode } from "./locate-U3-nkird.mjs";
5
+ import { Qr as stateSchema, er as reviewTransportBytes, rt as readWorkspaceOutcomes, ut as resolveFailureLocation } from "./src-CC95LYYp.mjs";
6
+ import { gt as isCoordinationBusy } from "./heap-BHcvxWCw.mjs";
7
7
  import { constants, createReadStream, write } from "node:fs";
8
8
  import { z } from "zod";
9
9
  import { lstat, mkdir, mkdtemp, open, readFile, readdir, realpath, rename, rm, writeFile } from "node:fs/promises";
@@ -140,14 +140,13 @@ function reportOwnershipCheckDeferred() {
140
140
  })}\n`, (_error) => {});
141
141
  } catch {}
142
142
  }
143
- //#endregion
144
- //#region apps/cli/src/serve.ts
145
143
  async function serve(options, journeyId) {
146
144
  let initializing;
147
145
  let shutdownPhase = "application-and-account";
148
146
  let stopping;
149
147
  let host;
150
148
  let ownerTimer;
149
+ let finishTimer;
151
150
  let observedStore = void 0;
152
151
  const timing = process.env["CI"] ? createHostTimingSampler() : void 0;
153
152
  const timingTimer = process.env["CI"] ? setInterval(() => {
@@ -197,6 +196,7 @@ async function serve(options, journeyId) {
197
196
  process.exit(1);
198
197
  }, 5e3);
199
198
  if (ownerTimer) clearInterval(ownerTimer);
199
+ if (finishTimer) clearInterval(finishTimer);
200
200
  host?.beginStop();
201
201
  try {
202
202
  await runtime.close();
@@ -250,6 +250,7 @@ async function serve(options, journeyId) {
250
250
  application: runtime.application,
251
251
  account: runtime.account,
252
252
  nativeInspection: runtime.nativeInspection,
253
+ agentPresence: (id) => readAgentPresence(runtime.stateDir, id),
253
254
  onFatal: (code) => {
254
255
  scheduleStop(code);
255
256
  },
@@ -284,6 +285,14 @@ async function serve(options, journeyId) {
284
285
  process.on("SIGINT", onSignal);
285
286
  process.on("SIGTERM", onSignal);
286
287
  if (journeyId) {
288
+ let endedAt;
289
+ finishTimer = setInterval(() => {
290
+ runtime.application.journey?.get({ journeyId }).then((journey) => {
291
+ endedAt = journey?.phase === "completed" || journey?.abandonedAt !== void 0 ? endedAt ?? Date.now() : void 0;
292
+ if (endedAt !== void 0 && Date.now() - endedAt >= 18e5) scheduleStop();
293
+ }).catch(() => {});
294
+ }, 6e4);
295
+ finishTimer.unref();
287
296
  const url = new URL(host.url);
288
297
  url.searchParams.set("view", "skill");
289
298
  url.searchParams.set("journey", journeyId);
@@ -906,7 +915,7 @@ function writeInstallNotice(result) {
906
915
  ...result.agentConfiguration.some(({ status }) => status === "skipped") ? ["To allow configuration in a noninteractive install, rerun skill.install with --configure-agents."] : [],
907
916
  "Open a new conversation in your installed client and enter:",
908
917
  ...commands,
909
- "Your agent will guide permissions, scanning, AI privacy review, preview and local export.",
918
+ "Your agent will guide permissions, scanning, AI privacy review, preview and Send.",
910
919
  ""
911
920
  ].join("\n");
912
921
  return new Promise((resolve, reject) => {
@@ -914,6 +923,95 @@ function writeInstallNotice(result) {
914
923
  });
915
924
  }
916
925
  //#endregion
926
+ //#region apps/cli/src/serve-detach.ts
927
+ const readySchema = z.object({
928
+ event: z.literal("ready"),
929
+ result: z.object({
930
+ url: z.string(),
931
+ journeyId: z.string()
932
+ })
933
+ });
934
+ /** The same CLI arguments without `--detach` and with the journey read from `input`. */
935
+ function hostArguments(args, input) {
936
+ const kept = [];
937
+ for (let index = 0; index < args.length; index += 1) {
938
+ const arg = args[index];
939
+ if (arg === void 0 || arg === "--detach" || arg.startsWith("--input=")) continue;
940
+ if (arg === "--input") {
941
+ index += 1;
942
+ continue;
943
+ }
944
+ kept.push(arg);
945
+ }
946
+ return [
947
+ ...kept,
948
+ "--input",
949
+ input
950
+ ];
951
+ }
952
+ /**
953
+ * Starts `journey.serve` in its own process group, outside the agent tool that ran this command,
954
+ * so an agent host's limit on background tasks does not stop the panel mid-Send (BL-210). The
955
+ * host's output goes to an owner-only log; this command prints its readiness with the pid.
956
+ */
957
+ async function serveDetached(args, stateDir, journeyId) {
958
+ const directory = join(stateDir, "serve");
959
+ await mkdir(directory, {
960
+ recursive: true,
961
+ mode: 448
962
+ });
963
+ const id = randomUUID();
964
+ const input = join(directory, `${id}.json`);
965
+ const log = join(directory, `${id}.log`);
966
+ await writeFile(input, JSON.stringify({ journeyId }), { mode: 384 });
967
+ const output = await open(log, "w", 384);
968
+ const entry = process.argv[1];
969
+ if (!entry) throw new Error("INVALID_ARGUMENTS");
970
+ const child = spawn(process.execPath, [
971
+ ...process.execArgv,
972
+ entry,
973
+ ...hostArguments(args, input)
974
+ ], {
975
+ detached: true,
976
+ stdio: [
977
+ "ignore",
978
+ output.fd,
979
+ output.fd
980
+ ]
981
+ });
982
+ let exited = null;
983
+ child.once("exit", (code) => exited = code ?? 1);
984
+ child.unref();
985
+ await output.close();
986
+ for (let waited = 0; waited < 6e4; waited += 100) {
987
+ const ready = (await readFile(log, "utf8")).split("\n").flatMap((line) => {
988
+ try {
989
+ const value = readySchema.safeParse(JSON.parse(line));
990
+ return value.success ? [value.data.result] : [];
991
+ } catch {
992
+ return [];
993
+ }
994
+ })[0];
995
+ if (ready) {
996
+ process.stdout.write(`${JSON.stringify({
997
+ ok: true,
998
+ event: "ready",
999
+ result: {
1000
+ ...ready,
1001
+ pid: child.pid,
1002
+ log
1003
+ }
1004
+ })}\n`);
1005
+ return;
1006
+ }
1007
+ if (exited !== null) break;
1008
+ await setTimeout$1(100);
1009
+ }
1010
+ if (exited === null) child.kill();
1011
+ process.stderr.write(`The panel host did not start. Its output is in ${log}.\n`);
1012
+ process.exitCode = 1;
1013
+ }
1014
+ //#endregion
917
1015
  //#region apps/cli/src/business-input.ts
918
1016
  const defaultBusinessInputBytes = 1048576;
919
1017
  const reviewCommands = /* @__PURE__ */ new Set([
@@ -1142,7 +1240,8 @@ async function business(options, args) {
1142
1240
  const value = await readBusinessInput(options);
1143
1241
  if (options.command === "journey.serve") {
1144
1242
  const { journeyId } = z.object({ journeyId: z.string().uuid() }).strict().parse(value);
1145
- await serve(options, journeyId);
1243
+ if (options.detach) await serveDetached(args, options.stateDir, journeyId);
1244
+ else await serve(options, journeyId);
1146
1245
  return;
1147
1246
  }
1148
1247
  if (options.command === "skill.install") {
@@ -1,4 +1,4 @@
1
- import { i as errorCode } from "./model-7Nu7szNP.mjs";
1
+ import { i as errorCode } from "./model-BJdTLNjT.mjs";
2
2
  import { a as titleHintLimits, i as encodeTitleError, o as titleInputSchema, t as assertTitleHeap } from "./heap-1FYhGds4.mjs";
3
3
  import { stat } from "node:fs/promises";
4
4
  import { isAbsolute, join } from "node:path";
@@ -1,8 +1,8 @@
1
- import { J as createConfiguredPreviewStream } from "./src-BngGpFKd.mjs";
2
- import { rn as workspaceSchema, tn as sessionSchema, yn as createStaticProcessor } from "./locate-Bn32k2se.mjs";
3
- import { l as createNativeAdapters, u as createGitNameSeedProvider } from "./src-DynBRDBc.mjs";
4
- import { Qr as effectiveTreatmentSchema } from "./src-CPPjOyHZ.mjs";
5
- import { a as classifyRecord, n as assertPreviewHeap, t as runPreview } from "./run-CCATsHS2.mjs";
1
+ import { J as createConfiguredPreviewStream } from "./src-k0Ya1Bri.mjs";
2
+ import { rn as workspaceSchema, tn as sessionSchema, yn as createStaticProcessor } from "./locate-U3-nkird.mjs";
3
+ import { l as createNativeAdapters, u as createGitNameSeedProvider } from "./src-B5SArpVY.mjs";
4
+ import { ni as effectiveTreatmentSchema } from "./src-CC95LYYp.mjs";
5
+ import { a as classifyRecord, n as assertPreviewHeap, t as runPreview } from "./run-BeLHsZWb.mjs";
6
6
  import { z } from "zod";
7
7
  import { parentPort, workerData } from "node:worker_threads";
8
8
  //#region apps/cli/src/preview/run.ts
@@ -1,7 +1,7 @@
1
- import { A as runConfiguredSessionJob, Q as safeError, R as gitSeedsProvider, m as captureConfiguredSessionJob, u as runConfiguredScanJob } from "./src-BngGpFKd.mjs";
2
- import { yn as createStaticProcessor } from "./locate-Bn32k2se.mjs";
3
- import { l as createNativeAdapters } from "./src-DynBRDBc.mjs";
4
- import { i as runJourneyOutputVerifyJob, n as runJourneyOutputJob, r as runJourneyOutputShardJob } from "./job--TceKk0l.mjs";
1
+ import { A as runConfiguredSessionJob, Q as safeError, R as gitSeedsProvider, m as captureConfiguredSessionJob, u as runConfiguredScanJob } from "./src-k0Ya1Bri.mjs";
2
+ import { yn as createStaticProcessor } from "./locate-U3-nkird.mjs";
3
+ import { l as createNativeAdapters } from "./src-B5SArpVY.mjs";
4
+ import { i as runJourneyOutputVerifyJob, n as runJourneyOutputJob, r as runJourneyOutputShardJob } from "./job-J3NFw3MH.mjs";
5
5
  import { parentPort } from "node:worker_threads";
6
6
  //#region apps/cli/src/configured-session-worker.ts
7
7
  const port = parentPort;
@@ -1,4 +1,4 @@
1
- import { nr as ProcessingError } from "./locate-Bn32k2se.mjs";
1
+ import { nr as ProcessingError } from "./locate-U3-nkird.mjs";
2
2
  //#region packages/processing/src/compression/frame.ts
3
3
  function createZstdFrameCheck(fail = () => {
4
4
  throw new ProcessingError("PROCESSING_INVALID_RECORD");
@@ -1,6 +1,6 @@
1
- import { $ as exclusiveLock, b as writePrivateReviewPayload, nt as restrictToOwner, rt as windowsOwnerOnly, tt as openPrivateFile, x as readPrivateReviewPayload } from "./src-BngGpFKd.mjs";
2
- import { $t as fileIdentitySchema, At as journeyTermSchema, Ht as ApplicationError, It as termTypeSchema, Jt as reviewFamilies, Kn as isStaticCategory, Mt as reviewTermsResultSchema, _ as semanticFindingSchema, b as validateBReview, c as textDigest, d as reviewAlignmentAudit, dt as nativeJourneySchema, ft as journeyGuidanceSchema, g as validateReviewAlignment, gn as createDetectionSummary, gt as journeyWorkSuggestionSchema, ht as journeyDescribeSchema, i as reviewBatchSchema, it as journeyDigestSchema, jt as reviewTermsInputSchema, kt as privacyTermSchema, l as validateReview, m as reviewAlignmentSchema, o as reviewDigest, ot as journeyIdSchema, qn as staticCategories, qt as familySelected, r as reviewBatchChunks, s as reviewSubmitSchema, u as findingReferenceKey, v as bContextEvidence } from "./locate-Bn32k2se.mjs";
3
- import { $n as bReviewDigest, $t as journeyResourceQuerySchema, Bn as dictionaryHides, Bt as journeyBatchReadSchema, Fr as withReadingProgress, G as validateInspectionClaim, Gn as workDecisionDigest, Gt as hideBeginSchema, H as validateInspectionBatch, Hn as maskedHitsStale, In as confirmedHideGroupIds, Ir as mergePrivacyTerms, It as attemptBudgetCodePoints, J as validateInspectionInputs, Jr as stateSchema, Jt as journeySearchResultSchema, K as validateInspectionFence, Kn as workPrivacyDecisions, Kt as hideFinishSchema, Ln as confirmedHideKey, Lt as validateAttemptAppend, Mr as isReadingComplete, Nn as bMaskedHits, Nr as isSelectedWork, Nt as obsoleteJourney, Pr as selectedWorks, Q as inspectionInputs, Qt as projectPreparationProgress, Rt as journeyGuidance, S as bReviewScope, Sn as confirmedHideDeltaSchema, Tn as settleConfirmedHides, Tt as journeySendSchema, U as validateInspectionBatches, Un as syncTermGroups, Ut as journeyContextQuerySchema, Vt as journeyReviewStorageQuerySchema, Wn as retireWorkDescription, Wt as journeyContextSchema, X as validateInspectionContribution, Xt as searchScopeDigest, Y as validateInspectionQuery, Yn as reviewCandidateResourceSchema, Yt as journeySearchSaveSchema, Z as validateDetectionSummary, Zn as reviewRepairResourceSchema, Zt as journeyPolicyRespondSchema, _ as semanticGroupKey, _n as sessionUsefulnessResourceSchema, _r as preparationBeginSchema, an as reviewAttemptsQuerySchema, ar as scanSessionResourceSchema, b as preparationScope, bn as journeyEventSchema, br as validatePreparationFacts, c as reconcileBSession, cn as sessionReconcileResultSchema, d as reviseGroupMembership, dn as sessionRereadResourceSchema, dt as manualUploadBindingSchema, en as journeyResourceSchema, er as mergeBRepair, f as resolveGroupSplit, g as hideScopeDigest, gn as sessionUsefulnessInputSchema, gt as candidateSortAvailable, hn as sessionReviewStatusSchema, hr as journeyPreparationProgressSchema, in as reviewAttemptResourceSchema, jt as settleCorrections, kr as staticSessionId, l as reconstructBFields, ln as sessionReconciliationResourceSchema, mn as sessionReviewResourceSchema, mr as journeyInventorySchema, mt as manualUploadSchema, n as scanBatchContextDigest, nn as journeyPlaceSchema, nr as scanAliasResourceSchema, on as reviewAttemptsResultSchema, or as scanGitSeedsId, pn as sessionReviewQuerySchema, pr as journeyInventoryReadSchema, q as validateInspectionHead, qt as hidePublishSchema, rn as sortingApplySchema, rr as scanCanonicalResourceSchema, s as bRereadDigest, tn as journeyIsolateSchema, u as newJourneyWork, ur as validateScanExclusion, vn as journeyCommitResultSchema, vr as preparationSettlementSchema, y as projectJourneyInventory, yn as journeyCommitSchema, yr as preparationStartSchema, zn as confirmedHideTerms } from "./src-CPPjOyHZ.mjs";
1
+ import { $ as exclusiveLock, b as writePrivateReviewPayload, nt as restrictToOwner, rt as windowsOwnerOnly, tt as openPrivateFile, x as readPrivateReviewPayload } from "./src-k0Ya1Bri.mjs";
2
+ import { $t as fileIdentitySchema, At as journeyTermSchema, Ht as ApplicationError, It as termTypeSchema, Jt as reviewFamilies, Kn as isStaticCategory, Mt as reviewTermsResultSchema, _ as semanticFindingSchema, b as validateBReview, c as textDigest, d as reviewAlignmentAudit, dt as nativeJourneySchema, ft as journeyGuidanceSchema, g as validateReviewAlignment, gn as createDetectionSummary, gt as journeyWorkSuggestionSchema, ht as journeyDescribeSchema, i as reviewBatchSchema, it as journeyDigestSchema, jt as reviewTermsInputSchema, kt as privacyTermSchema, l as validateReview, m as reviewAlignmentSchema, o as reviewDigest, ot as journeyIdSchema, qn as staticCategories, qt as familySelected, r as reviewBatchChunks, s as reviewSubmitSchema, u as findingReferenceKey, v as bContextEvidence } from "./locate-U3-nkird.mjs";
3
+ import { $ as validateDetectionSummary, $n as reviewRepairResourceSchema, $t as journeyPolicyRespondSchema, Br as mergePrivacyTerms, Bt as journeyGuidance, C as bReviewScope, Dn as settleConfirmedHides, Dt as journeySendSchema, Fn as bMaskedHits, Ft as obsoleteJourney, Gn as syncTermGroups, Gt as journeyContextQuerySchema, Hn as dictionaryHides, Ht as journeyBatchReadSchema, Ir as isReadingComplete, J as validateInspectionFence, Jn as workPrivacyDecisions, Jt as hideFinishSchema, Kn as retireWorkDescription, Kt as journeyContextSchema, Lr as isSelectedWork, Mr as staticSessionId, Nt as settleCorrections, Q as validateInspectionContribution, Qr as stateSchema, Qt as searchScopeDigest, Rn as confirmedHideGroupIds, Rr as selectedWorks, Rt as attemptBudgetCodePoints, Sn as journeyEventSchema, Sr as validatePreparationFacts, U as validateInspectionBatch, Ut as journeyReviewStorageQuerySchema, Vn as confirmedHideTerms, W as validateInspectionBatches, Wn as maskedHitsStale, X as validateInspectionInputs, Xt as journeySearchResultSchema, Y as validateInspectionHead, Yt as hidePublishSchema, Z as validateInspectionQuery, Zn as reviewCandidateResourceSchema, Zt as journeySearchSaveSchema, _ as hideScopeDigest, _n as sessionReviewStatusSchema, _r as journeyPreparationProgressSchema, an as sortingApplySchema, ar as scanCanonicalResourceSchema, b as projectJourneyInventory, bn as journeyCommitResultSchema, br as preparationSettlementSchema, c as bRereadDigest, cn as reviewAttemptsResultSchema, cr as scanGitSeedsId, d as newJourneyWork, dn as sessionReconciliationResourceSchema, en as projectPreparationProgress, et as inspectionInputs, f as reviseGroupMembership, fr as validateScanExclusion, gn as sessionReviewResourceSchema, gr as journeyInventorySchema, gt as manualUploadSchema, hn as sessionReviewQuerySchema, hr as journeyInventoryReadSchema, in as journeyPlaceSchema, ir as scanAliasResourceSchema, l as reconcileBSession, nn as journeyResourceSchema, nr as mergeBRepair, on as reviewAttemptResourceSchema, p as resolveGroupSplit, pn as sessionRereadResourceSchema, pt as manualUploadBindingSchema, q as validateInspectionClaim, qn as workDecisionDigest, qt as hideBeginSchema, r as scanBatchContextDigest, rn as journeyIsolateSchema, sn as reviewAttemptsQuerySchema, sr as scanSessionResourceSchema, tn as journeyResourceQuerySchema, tr as bReviewDigest, u as reconstructBFields, un as sessionReconcileResultSchema, v as semanticGroupKey, vn as sessionUsefulnessInputSchema, vt as candidateSortAvailable, wn as confirmedHideDeltaSchema, wr as applyCardAnswers, x as preparationScope, xn as journeyCommitSchema, xr as preparationStartSchema, yn as sessionUsefulnessResourceSchema, yr as preparationBeginSchema, zn as confirmedHideKey, zr as withReadingProgress, zt as validateAttemptAppend } from "./src-CC95LYYp.mjs";
4
4
  import { constants } from "node:fs";
5
5
  import { z } from "zod";
6
6
  import { copyFile, link, lstat, mkdir, mkdtemp, open, readFile, realpath, rm, unlink } from "node:fs/promises";
@@ -415,9 +415,16 @@ function insertCorrectionReport(db, resource) {
415
415
  * A snapshot of an earlier release cannot render, so a new Journey may replace it, but never
416
416
  * one with a Send record or a sent Work: that Send stays for the person to finish.
417
417
  */
418
- /** An abandoned Journey gives way to a new one unless a Send started from it. */
418
+ /** Passport holds a receipt from one of this Journey's Sends, so a Work may have reached it. */
419
+ function reachedPassport(db, journeyId) {
420
+ return db.prepare("SELECT json FROM journey_sends WHERE journey_id=?").all(journeyId).some((row) => {
421
+ if (typeof row["json"] !== "string") throw new ApplicationError("CORRUPTED_STATE");
422
+ return journeySendSchema.parse(JSON.parse(row["json"])).items.some((item) => item.receipt || item.previousReceipts.length);
423
+ });
424
+ }
425
+ /** An abandoned Journey gives way to a new one unless one of its Sends reached Passport. */
419
426
  function abandoned(db, current) {
420
- return current.abandonedAt !== void 0 && !db.prepare("SELECT 1 FROM journey_sends WHERE journey_id=? LIMIT 1").get(current.journeyId);
427
+ return current.abandonedAt !== void 0 && !reachedPassport(db, current.journeyId);
421
428
  }
422
429
  function replaceable(db, current) {
423
430
  return obsoleteJourney(current) && !current.works.some((work) => work.binding) && !db.prepare("SELECT 1 FROM journey_sends WHERE journey_id=? LIMIT 1").get(current.journeyId);
@@ -496,6 +503,10 @@ function commitJourney(db, input) {
496
503
  };
497
504
  }
498
505
  if (input.state.journeyId !== input.event.journeyId) throw new ApplicationError("INVALID_ARGUMENTS");
506
+ if (input.state.abandonedAt && current?.journeyId === input.state.journeyId && !current.abandonedAt) {
507
+ if (reachedPassport(db, current.journeyId)) throw new ApplicationError("INVALID_TRANSITION");
508
+ db.prepare("DELETE FROM journey_current_send WHERE journey_id=?").run(current.journeyId);
509
+ }
499
510
  for (const term of input.terms ?? []) db.prepare("INSERT INTO journey_terms VALUES(?,?,?,0,NULL) ON CONFLICT(journey_id,type,value) DO NOTHING").run(input.state.journeyId, term.type, term.value);
500
511
  const { confirmedHideDelta, terms: _terms, ...commit } = input;
501
512
  input = {
@@ -2575,7 +2586,7 @@ function finishTerms(db, packet) {
2575
2586
  scope: state.scope,
2576
2587
  snapshotId: state.snapshotId
2577
2588
  });
2578
- const next = {
2589
+ const next = applyCardAnswers({
2579
2590
  ...state,
2580
2591
  privacy: mergePrivacyTerms({
2581
2592
  ...state,
@@ -2585,7 +2596,7 @@ function finishTerms(db, packet) {
2585
2596
  works,
2586
2597
  readingComplete,
2587
2598
  phase: readingComplete && state.phase !== "paused" ? "review" : state.phase
2588
- };
2599
+ });
2589
2600
  const hidden = dictionaryHides(next, packet.located);
2590
2601
  const delta = {
2591
2602
  ...packet.confirmedHideDelta,
@@ -4803,6 +4814,7 @@ function commitJourneySend(db, input) {
4803
4814
  ...current,
4804
4815
  status: "stale"
4805
4816
  };
4817
+ if (current.journey.abandonedAt) throw new ApplicationError("INVALID_TRANSITION");
4806
4818
  const revision = input.expectedSendRevision === null ? 0 : input.expectedSendRevision + 1;
4807
4819
  const send = journeySendSchema.parse({
4808
4820
  ...input.state,
@@ -4824,7 +4836,7 @@ function commitJourneySend(db, input) {
4824
4836
  "sending",
4825
4837
  "waiting",
4826
4838
  "sign-in"
4827
- ].includes(send.status) ? "sending" : current.journey.phase,
4839
+ ].includes(send.status) ? "sending" : send.status === "prepared" && current.journey.phase === "sending" ? "review" : current.journey.phase,
4828
4840
  works: current.journey.works.map((work) => {
4829
4841
  const item = send.items.find((candidate) => candidate.workId === work.id);
4830
4842
  const receipt = item?.receipt;
@@ -0,0 +1,57 @@
1
+ import { Y as createInspectionProcessor } from "./src-k0Ya1Bri.mjs";
2
+ import { yn as createStaticProcessor } from "./locate-U3-nkird.mjs";
3
+ import { l as createNativeAdapters, u as createGitNameSeedProvider } from "./src-B5SArpVY.mjs";
4
+ import { G as validateInspectionRequest } from "./src-CC95LYYp.mjs";
5
+ import "./messages-D3m3bhva.mjs";
6
+ import { z } from "zod";
7
+ import { parentPort, workerData } from "node:worker_threads";
8
+ //#region apps/cli/src/inspection/worker.ts
9
+ const inputSchema = z.object({
10
+ request: z.unknown(),
11
+ environment: z.object({
12
+ platform: z.enum(["posix", "windows"]),
13
+ userHome: z.string().optional(),
14
+ temporaryRoots: z.array(z.string())
15
+ })
16
+ });
17
+ function post(message) {
18
+ parentPort?.postMessage(message);
19
+ }
20
+ const input = inputSchema.parse(workerData);
21
+ const request = validateInspectionRequest(input.request);
22
+ const abort = new AbortController();
23
+ parentPort?.on("message", (message) => {
24
+ if (typeof message === "object" && message !== null && Reflect.get(message, "kind") === "abort") abort.abort();
25
+ });
26
+ const inspector = createInspectionProcessor({
27
+ adapters: createNativeAdapters(),
28
+ gitNames: createGitNameSeedProvider(),
29
+ processor: createStaticProcessor(),
30
+ environment: {
31
+ platform: input.environment.platform,
32
+ ...input.environment.userHome === void 0 ? {} : { userHome: input.environment.userHome },
33
+ temporaryRoots: input.environment.temporaryRoots
34
+ },
35
+ onAnomaly: (event) => post({
36
+ kind: "anomaly",
37
+ event
38
+ })
39
+ });
40
+ const onFailure = (stage, error) => {
41
+ const code = typeof error === "object" && error !== null ? Reflect.get(error, "code") : void 0;
42
+ const message = error instanceof Error ? error.message : "";
43
+ post({
44
+ kind: "failure",
45
+ stage,
46
+ ...typeof code === "string" && code.length <= 128 ? { code } : {},
47
+ message: /^[A-Z][A-Z0-9_]{0,127}$/u.test(message) ? message : "OPERATION_FAILED"
48
+ });
49
+ };
50
+ for await (const batch of inspector.scan(request, abort.signal, onFailure)) post({
51
+ kind: "batch",
52
+ batch
53
+ });
54
+ post({ kind: "done" });
55
+ parentPort?.close();
56
+ //#endregion
57
+ export {};
@@ -1,5 +1,5 @@
1
- import { B as writeLogicalJourneyOutput, C as readConfiguredSearchFields, R as gitSeedsProvider, U as readConfiguredOutputInfo, d as verifyOutputShard, f as writeOutputShard } from "./src-BngGpFKd.mjs";
2
- import { An as packHideIndex, Dn as addHideIndexTokens, On as hideKeyId, wn as renderedHideValue } from "./src-CPPjOyHZ.mjs";
1
+ import { B as writeLogicalJourneyOutput, C as readConfiguredSearchFields, R as gitSeedsProvider, U as readConfiguredOutputInfo, d as verifyOutputShard, f as writeOutputShard } from "./src-k0Ya1Bri.mjs";
2
+ import { An as hideKeyId, En as renderedHideValue, Mn as packHideIndex, kn as addHideIndexTokens } from "./src-CC95LYYp.mjs";
3
3
  //#region apps/cli/src/journey/hide-index.ts
4
4
  /**
5
5
  * Word pieces of render input, gathered as it is read so its texts are not held to the end.
@@ -8953,13 +8953,18 @@ const decisionCardInputSchema = z.object({
8953
8953
  id: z.enum(["hide", "keep"]),
8954
8954
  label: z.string().trim().min(1).max(240),
8955
8955
  rule: z.string().trim().min(1).max(2e3)
8956
- }).strict()).length(2).refine((options) => new Set(options.map((option) => option.id)).size === 2, { message: "Decision cards require one hide option and one keep option." })
8956
+ }).strict()).length(2).refine((options) => new Set(options.map((option) => option.id)).size === 2, { message: "Decision cards require one hide option and one keep option." }),
8957
+ suggestion: z.object({
8958
+ optionId: z.enum(["hide", "keep"]),
8959
+ source: z.string().trim().min(1).max(300)
8960
+ }).strict().optional()
8957
8961
  }).strict();
8958
8962
  const decisionCardSchema = decisionCardInputSchema.extend({ answer: z.object({
8959
8963
  optionId: z.string(),
8960
8964
  rule: z.string().max(4001),
8961
8965
  additionalRule: z.string().max(2e3),
8962
- remember: z.boolean()
8966
+ remember: z.boolean(),
8967
+ excludedTermKeys: z.array(z.string().min(1)).max(2e4).optional()
8963
8968
  }).strict().nullable() }).strict();
8964
8969
  const journeyPrivacySchema = z.object({
8965
8970
  terms: z.array(privacyTermSchema),
@@ -8983,7 +8988,18 @@ const write = z.object({
8983
8988
  expectedRevision: count$2,
8984
8989
  idempotencyKey: z.uuid()
8985
8990
  });
8986
- const cardsSubmitSchema = write.extend({ cards: z.array(decisionCardInputSchema).max(20) }).strict();
8991
+ /**
8992
+ * `append` (D3) adds a batch while scanning continues: new cards plus values added to existing
8993
+ * cards, covering only Pending values no card covers yet. `replace` republishes the whole deck.
8994
+ */
8995
+ const cardsSubmitSchema = write.extend({
8996
+ cards: z.array(decisionCardInputSchema).max(20),
8997
+ mode: z.enum(["replace", "append"]).optional(),
8998
+ extend: z.array(z.object({
8999
+ cardId: z.uuid(),
9000
+ termKeys: z.array(z.string().min(1)).min(1).max(2e4)
9001
+ }).strict()).max(20).optional()
9002
+ }).strict();
8987
9003
  const privacyResolveSchema = write.extend({
8988
9004
  answersRevision: count$2,
8989
9005
  resolutions: z.array(privacyTermSchema.omit({ sources: true }).extend({ disposition: z.enum(["hidden", "keep"]) }).strict()).min(1).max(2e4)
@@ -8993,7 +9009,8 @@ const cardAnswerActionSchema = z.object({
8993
9009
  cardId: z.uuid(),
8994
9010
  optionId: z.string().min(1),
8995
9011
  rule: z.string().max(2e3).optional(),
8996
- remember: z.boolean()
9012
+ remember: z.boolean(),
9013
+ excludedTermKeys: z.array(z.string().min(1)).max(2e4).optional()
8997
9014
  }).strict();
8998
9015
  const cardsConfirmActionSchema = z.object({
8999
9016
  kind: z.literal("cards-confirm"),
@@ -9310,7 +9327,11 @@ const journeyWorkSchema = z.object({
9310
9327
  "explicit",
9311
9328
  "delegate"
9312
9329
  ]),
9313
- placement: z.enum(["placed", "unsorted"]),
9330
+ placement: z.enum([
9331
+ "placed",
9332
+ "unsorted",
9333
+ "classifying"
9334
+ ]),
9314
9335
  suggestion: journeyWorkSuggestionSchema.nullable(),
9315
9336
  classificationRecommendation: z.object({
9316
9337
  access: journeyAccessSchema,
@@ -9357,7 +9378,9 @@ const journeyWorkSchema = z.object({
9357
9378
  staticReview: z.object({
9358
9379
  snapshotId: journeyDigestSchema,
9359
9380
  inputRevision: count$1.min(1),
9360
- digest: journeyDigestSchema
9381
+ digest: journeyDigestSchema,
9382
+ /** Images the Work's sessions leave out (D7); absent when a session receipt predates it. */
9383
+ imagesOmitted: count$1.optional()
9361
9384
  }).strict().optional(),
9362
9385
  totalBatches: count$1,
9363
9386
  completedBatches: count$1,
@@ -0,0 +1,40 @@
1
+ import { z } from "zod";
2
+ //#region apps/cli/src/inspection/messages.ts
3
+ const failureStageSchema = z.enum([
4
+ "inspection-admission",
5
+ "inspection-ancestry",
6
+ "inspection-workspace",
7
+ "inspection-session",
8
+ "inspection-scan",
9
+ "inspection-execution",
10
+ "inspection-commit-retry",
11
+ "inspection-publication",
12
+ "inspection-monitor",
13
+ "inspection-recovery",
14
+ "inspection-head",
15
+ "inspection-shutdown",
16
+ "inspection-cleanup"
17
+ ]);
18
+ /** Worker to host: batches in scan order, observer events, then exactly one `done`. */
19
+ const workerMessageSchema = z.discriminatedUnion("kind", [
20
+ z.object({
21
+ kind: z.literal("batch"),
22
+ batch: z.unknown()
23
+ }),
24
+ z.object({
25
+ kind: z.literal("anomaly"),
26
+ event: z.object({
27
+ code: z.string().max(128),
28
+ sourceId: z.string().max(256)
29
+ })
30
+ }),
31
+ z.object({
32
+ kind: z.literal("failure"),
33
+ stage: failureStageSchema,
34
+ code: z.string().max(128).optional(),
35
+ message: z.string().max(128)
36
+ }),
37
+ z.object({ kind: z.literal("done") })
38
+ ]);
39
+ //#endregion
40
+ export { workerMessageSchema as t };
@@ -1,4 +1,4 @@
1
- import "./src-CPPjOyHZ.mjs";
1
+ import "./src-CC95LYYp.mjs";
2
2
  //#region packages/harnesses/src/discovery/model.ts
3
3
  const discoveryBounds = {
4
4
  entries: 1e5,
@@ -1,6 +1,6 @@
1
- import { a as createRuntime, f as longCommands, i as invoke, m as startupFailure, n as readOperation, r as waitOperation, s as executorRequestSchema, u as parseOptions } from "./query-Da-KDbSV.mjs";
2
- import { Gt as safeField, Ht as ApplicationError, Wt as safeCode } from "./locate-Bn32k2se.mjs";
3
- import "./src-CPPjOyHZ.mjs";
1
+ import { c as executorRequestSchema, d as parseOptions, h as startupFailure, i as invoke, n as readOperation, o as createRuntime, p as longCommands, r as waitOperation } from "./query-BA0XCwnR.mjs";
2
+ import { Gt as safeField, Ht as ApplicationError, Wt as safeCode } from "./locate-U3-nkird.mjs";
3
+ import "./src-CC95LYYp.mjs";
4
4
  import { z } from "zod";
5
5
  import { setTimeout } from "node:timers/promises";
6
6
  //#region apps/cli/src/operation/executor.ts
@@ -1,4 +1,4 @@
1
- import { n as assertPreviewHeap, o as previewInputSchema, t as runPreview } from "./run-CCATsHS2.mjs";
1
+ import { n as assertPreviewHeap, o as previewInputSchema, t as runPreview } from "./run-BeLHsZWb.mjs";
2
2
  import { parentPort, workerData } from "node:worker_threads";
3
3
  //#region packages/harnesses/src/preview/worker/index.ts
4
4
  function notify(message) {
@@ -1,4 +1,4 @@
1
- import { Dt as privacyResolveSchema, Ot as privacyTermKey, t as locateTerms, wt as decisionCardInputSchema } from "./locate-Bn32k2se.mjs";
1
+ import { Dt as privacyResolveSchema, Ot as privacyTermKey, t as locateTerms, wt as decisionCardInputSchema } from "./locate-U3-nkird.mjs";
2
2
  import { z } from "zod";
3
3
  //#region apps/cli/src/skill-install/privacy-validator.ts
4
4
  const suppliedTerms = z.array(z.object({