@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,5 +1,5 @@
1
- import "./locate-Bn32k2se.mjs";
2
- import "./src-CPPjOyHZ.mjs";
1
+ import "./locate-U3-nkird.mjs";
2
+ import "./src-B4R5XMEP.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-CPbdnGrk.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-qoLRvX-A.mjs";
4
+ import { ai as effectiveTreatmentSchema, at as maximumAgentSetupSessions } from "./src-B4R5XMEP.mjs";
5
+ import "./agent-setup-CLXdKr2I.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-DN99jiRc.mjs";
3
+ import { nt as openPrivateFile, tt as makePrivateDirectory } from "./src-CPbdnGrk.mjs";
4
+ import { Gt as safeField, Ht as ApplicationError, Wt as safeCode } from "./locate-U3-nkird.mjs";
5
+ import { et as readWorkspaceOutcomes, rr as reviewTransportBytes, st as resolveFailureLocation, ti as stateSchema } from "./src-B4R5XMEP.mjs";
6
+ import { _t as isCoordinationBusy } from "./heap-eO_uWpD1.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,152 @@ 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
+ const recordSchema = z.object({
935
+ url: z.string(),
936
+ journeyId: z.string(),
937
+ pid: z.number().int().positive(),
938
+ log: z.string()
939
+ });
940
+ const recordPath = (directory, journeyId) => join(directory, `${journeyId}.host.json`);
941
+ function running(pid) {
942
+ try {
943
+ process.kill(pid, 0);
944
+ return true;
945
+ } catch {
946
+ return false;
947
+ }
948
+ }
949
+ /**
950
+ * The detached host this state directory recorded for the journey, while its process runs and
951
+ * its URL answers; a stale record (a stopped host, a reused pid) is ignored.
952
+ */
953
+ async function liveHost(directory, journeyId) {
954
+ let record;
955
+ try {
956
+ const parsed = recordSchema.safeParse(JSON.parse(await readFile(recordPath(directory, journeyId), "utf8")));
957
+ if (!parsed.success || parsed.data.journeyId !== journeyId) return null;
958
+ record = parsed.data;
959
+ } catch {
960
+ return null;
961
+ }
962
+ if (!running(record.pid)) return null;
963
+ try {
964
+ await fetch(record.url, { signal: AbortSignal.timeout(2e3) });
965
+ return record;
966
+ } catch {
967
+ return null;
968
+ }
969
+ }
970
+ /** The same CLI arguments without `--detach` and with the journey read from `input`. */
971
+ function hostArguments(args, input) {
972
+ const kept = [];
973
+ for (let index = 0; index < args.length; index += 1) {
974
+ const arg = args[index];
975
+ if (arg === void 0 || arg === "--detach" || arg.startsWith("--input=")) continue;
976
+ if (arg === "--input") {
977
+ index += 1;
978
+ continue;
979
+ }
980
+ kept.push(arg);
981
+ }
982
+ return [
983
+ ...kept,
984
+ "--input",
985
+ input
986
+ ];
987
+ }
988
+ /**
989
+ * Starts `journey.serve` in its own process group, outside the agent tool that ran this command,
990
+ * so an agent host's limit on background tasks does not stop the panel mid-Send (BL-210). The
991
+ * host's output goes to an owner-only log; this command prints its readiness with the pid.
992
+ * A detached host already serving the journey is reused (`reused: true`), so the Skill helper can
993
+ * ensure one owns the panel before the agent's turn ends (ADR 0227).
994
+ */
995
+ async function serveDetached(args, stateDir, journeyId) {
996
+ const directory = join(stateDir, "serve");
997
+ await mkdir(directory, {
998
+ recursive: true,
999
+ mode: 448
1000
+ });
1001
+ const existing = await liveHost(directory, journeyId);
1002
+ if (existing) {
1003
+ process.stdout.write(`${JSON.stringify({
1004
+ ok: true,
1005
+ event: "ready",
1006
+ result: {
1007
+ ...existing,
1008
+ reused: true
1009
+ }
1010
+ })}\n`);
1011
+ return;
1012
+ }
1013
+ const id = randomUUID();
1014
+ const input = join(directory, `${id}.json`);
1015
+ const log = join(directory, `${id}.log`);
1016
+ await writeFile(input, JSON.stringify({ journeyId }), { mode: 384 });
1017
+ const output = await open(log, "w", 384);
1018
+ const entry = process.argv[1];
1019
+ if (!entry) throw new Error("INVALID_ARGUMENTS");
1020
+ const child = spawn(process.execPath, [
1021
+ ...process.execArgv,
1022
+ entry,
1023
+ ...hostArguments(args, input)
1024
+ ], {
1025
+ detached: true,
1026
+ stdio: [
1027
+ "ignore",
1028
+ output.fd,
1029
+ output.fd
1030
+ ]
1031
+ });
1032
+ let exited = null;
1033
+ child.once("exit", (code) => exited = code ?? 1);
1034
+ child.unref();
1035
+ await output.close();
1036
+ for (let waited = 0; waited < 6e4; waited += 100) {
1037
+ const ready = (await readFile(log, "utf8")).split("\n").flatMap((line) => {
1038
+ try {
1039
+ const value = readySchema.safeParse(JSON.parse(line));
1040
+ return value.success ? [value.data.result] : [];
1041
+ } catch {
1042
+ return [];
1043
+ }
1044
+ })[0];
1045
+ if (ready && child.pid !== void 0) {
1046
+ const record = {
1047
+ ...ready,
1048
+ pid: child.pid,
1049
+ log
1050
+ };
1051
+ const temporary = `${recordPath(directory, journeyId)}.${id}.tmp`;
1052
+ await writeFile(temporary, JSON.stringify(record), { mode: 384 });
1053
+ await rename(temporary, recordPath(directory, journeyId));
1054
+ process.stdout.write(`${JSON.stringify({
1055
+ ok: true,
1056
+ event: "ready",
1057
+ result: {
1058
+ ...record,
1059
+ reused: false
1060
+ }
1061
+ })}\n`);
1062
+ return;
1063
+ }
1064
+ if (exited !== null) break;
1065
+ await setTimeout$1(100);
1066
+ }
1067
+ if (exited === null) child.kill();
1068
+ process.stderr.write(`The panel host did not start. Its output is in ${log}.\n`);
1069
+ process.exitCode = 1;
1070
+ }
1071
+ //#endregion
917
1072
  //#region apps/cli/src/business-input.ts
918
1073
  const defaultBusinessInputBytes = 1048576;
919
1074
  const reviewCommands = /* @__PURE__ */ new Set([
@@ -1142,7 +1297,8 @@ async function business(options, args) {
1142
1297
  const value = await readBusinessInput(options);
1143
1298
  if (options.command === "journey.serve") {
1144
1299
  const { journeyId } = z.object({ journeyId: z.string().uuid() }).strict().parse(value);
1145
- await serve(options, journeyId);
1300
+ if (options.detach) await serveDetached(args, options.stateDir, journeyId);
1301
+ else await serve(options, journeyId);
1146
1302
  return;
1147
1303
  }
1148
1304
  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-BBAnsFAx.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-CPbdnGrk.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-qoLRvX-A.mjs";
4
+ import { ai as effectiveTreatmentSchema } from "./src-B4R5XMEP.mjs";
5
+ import { a as classifyRecord, n as assertPreviewHeap, t as runPreview } from "./run-4G_CvdDj.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,8 @@
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 { $ as safeError, A as runConfiguredSessionJob, R as gitSeedsProvider, m as captureConfiguredSessionJob, u as runConfiguredScanJob } from "./src-CPbdnGrk.mjs";
2
+ import { Wt as safeCode, yn as createStaticProcessor } from "./locate-U3-nkird.mjs";
3
+ import { l as createNativeAdapters } from "./src-qoLRvX-A.mjs";
4
+ import "./src-B4R5XMEP.mjs";
5
+ import { d as runJourneyBaseJob, i as runJourneyOutputVerifyJob, n as runJourneyOutputJob, r as runJourneyOutputShardJob } from "./job-rK-Ho9OD.mjs";
5
6
  import { parentPort } from "node:worker_threads";
6
7
  //#region apps/cli/src/configured-session-worker.ts
7
8
  const port = parentPort;
@@ -28,6 +29,9 @@ function isJourneyOutputShardRequest(value) {
28
29
  function isJourneyOutputVerifyRequest(value) {
29
30
  return typeof value === "object" && value !== null && Reflect.get(value, "kind") === "journey-output-verify";
30
31
  }
32
+ function isJourneyBaseRequest(value) {
33
+ return typeof value === "object" && value !== null && Reflect.get(value, "kind") === "journey-base";
34
+ }
31
35
  function failureSourceId(error) {
32
36
  let current = error;
33
37
  for (let depth = 0; depth < 8 && current instanceof Error; depth++) {
@@ -82,6 +86,23 @@ port?.on("message", async (message) => {
82
86
  path
83
87
  }))
84
88
  });
89
+ else if (isJourneyBaseRequest(message)) try {
90
+ post({
91
+ kind: "result",
92
+ result: await runJourneyBaseJob(message.job, {
93
+ adapters,
94
+ processor
95
+ }, signal, (path) => post({
96
+ kind: "spool",
97
+ path
98
+ }))
99
+ });
100
+ } catch (error) {
101
+ post({
102
+ kind: "error",
103
+ code: safeCode(error)
104
+ });
105
+ }
85
106
  else if (isJourneyOutputShardRequest(message)) post({
86
107
  kind: "result",
87
108
  result: await runJourneyOutputShardJob(message.job, {
@@ -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 { b as writePrivateReviewPayload, et as exclusiveLock, it as windowsOwnerOnly, nt as openPrivateFile, rt as restrictToOwner, x as readPrivateReviewPayload } from "./src-CPbdnGrk.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 { $t as journeySearchResultSchema, An as settleConfirmedHides, At as settleCorrections, B as validateInspectionBatch, Br as isSelectedWork, Bt as journeyReviewStorageQuerySchema, Cn as journeyCommitResultSchema, Cr as preparationSettlementSchema, Dn as confirmedHideDeltaSchema, Dr as applyCardAnswers, Fr as staticSessionId, Ft as attemptBudgetCodePoints, G as validateInspectionFence, Gn as dictionaryHides, Hn as confirmedHideKey, Hr as withReadingProgress, Ht as classificationCommitSchema, It as validateAttemptAppend, J as validateInspectionQuery, Jn as syncTermGroups, Jt as journeyContextQuerySchema, K as validateInspectionHead, Kt as newJourneyWork, Lt as journeyGuidance, Mt as obsoleteJourney, Qt as hidePublishSchema, Rn as bMaskedHits, Sn as sessionUsefulnessResourceSchema, Sr as preparationBeginSchema, Tn as journeyEventSchema, Tr as validatePreparationFacts, Ur as mergePrivacyTerms, V as validateInspectionBatches, Vn as confirmedHideGroupIds, Vr as selectedWorks, Vt as applyClassificationProposal, W as validateInspectionClaim, Wn as confirmedHideTerms, X as validateDetectionSummary, Xn as workDecisionDigest, Xt as hideBeginSchema, Y as validateInspectionContribution, Yn as retireWorkDescription, Yt as journeyContextSchema, Z as inspectionInputs, Zn as workPrivacyDecisions, Zt as hideFinishSchema, _ as projectJourneyInventory, an as journeyResourceSchema, ar as mergeBRepair, b as bReviewScope, bn as sessionReviewStatusSchema, br as journeyPreparationProgressSchema, c as reconstructBFields, cn as sortingApplySchema, cr as scanCanonicalResourceSchema, dn as reviewAttemptsResultSchema, dr as scanGitSeedsId, en as journeySearchSaveSchema, er as reviewCandidateResourceSchema, gn as sessionRereadResourceSchema, h as semanticGroupKey, hr as validateScanExclusion, ht as candidateSortAvailable, in as journeyResourceQuerySchema, ir as bReviewDigest, l as reviseGroupMembership, ln as reviewAttemptResourceSchema, m as hideScopeDigest, mn as sessionReconciliationResourceSchema, nn as journeyPolicyRespondSchema, nr as reviewRepairResourceSchema, o as bRereadDigest, on as journeyIsolateSchema, pn as sessionReconcileResultSchema, pt as manualUploadSchema, q as validateInspectionInputs, qn as maskedHitsStale, rn as projectPreparationProgress, s as reconcileBSession, sn as journeyPlaceSchema, sr as scanAliasResourceSchema, t as scanBatchContextDigest, ti as stateSchema, tn as searchScopeDigest, u as resolveGroupSplit, un as reviewAttemptsQuerySchema, ur as scanSessionResourceSchema, ut as manualUploadBindingSchema, v as preparationScope, vn as sessionReviewQuerySchema, vr as journeyInventoryReadSchema, wn as journeyCommitSchema, wr as preparationStartSchema, wt as journeySendSchema, xn as sessionUsefulnessInputSchema, yn as sessionReviewResourceSchema, yr as journeyInventorySchema, zr as isReadingComplete, zt as journeyBatchReadSchema } from "./src-B4R5XMEP.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;
@@ -6210,6 +6222,43 @@ function finishStatus(db, packet) {
6210
6222
  };
6211
6223
  }
6212
6224
  //#endregion
6225
+ //#region packages/local-host/src/store/journey/classification.ts
6226
+ function classificationJourneyCommit(plan, state, expectedRevision) {
6227
+ return {
6228
+ expectedRevision,
6229
+ requestKey: plan.requestKey,
6230
+ requestHash: plan.requestHash,
6231
+ state,
6232
+ event: {
6233
+ journeyId: plan.journeyId,
6234
+ kind: "response",
6235
+ source: "conversation",
6236
+ at: plan.at
6237
+ }
6238
+ };
6239
+ }
6240
+ /**
6241
+ * BL-216: the prepared proposal is applied to the state read in this transaction, so scan writes
6242
+ * since it was prepared are kept instead of refusing it. A replay returns its receipt; a changed
6243
+ * classification, partition or scope answers stale. A change of confirmed Hide values returns
6244
+ * the proposed state so the caller can read the value change and commit it at that revision.
6245
+ */
6246
+ function commitJourneyClassification(db, plan) {
6247
+ const current = readJourney(db);
6248
+ if (!current) throw new ApplicationError("REVISION_CONFLICT");
6249
+ if (db.prepare("SELECT 1 FROM journey_receipts WHERE request_key=?").get(plan.requestKey)) return commitJourney(db, classificationJourneyCommit(plan, current, current.revision));
6250
+ const next = current.journeyId === plan.journeyId && applyClassificationProposal(current, plan);
6251
+ if (!next) return {
6252
+ status: "stale",
6253
+ state: current
6254
+ };
6255
+ const result = commitJourneyChecked(db, classificationJourneyCommit(plan, next, current.revision));
6256
+ return result.status === "hide-delta" ? {
6257
+ ...result,
6258
+ next
6259
+ } : result;
6260
+ }
6261
+ //#endregion
6213
6262
  //#region packages/local-host/src/store/inspection/claim.ts
6214
6263
  function currentInputs(db, runId) {
6215
6264
  const row = db.prepare("SELECT * FROM inspection_inputs WHERE run_id=?").get(runId);
@@ -6784,6 +6833,11 @@ const operations = {
6784
6833
  status: z.literal("hide-delta"),
6785
6834
  state: nativeJourneySchema
6786
6835
  }).strict()]).parse(value)),
6836
+ "journey.classification.commit": define(true, classificationCommitSchema, commitJourneyClassification, (value) => z.union([journeyCommitResultSchema, z.object({
6837
+ status: z.literal("hide-delta"),
6838
+ state: nativeJourneySchema,
6839
+ next: nativeJourneySchema
6840
+ }).strict()]).parse(value)),
6787
6841
  "journey.events": define(false, z.object({
6788
6842
  journeyId: z.uuid(),
6789
6843
  after: z.number().int().nonnegative(),
@@ -7250,4 +7304,4 @@ function assertStoreHeap(limitBytes = getHeapStatistics().heap_size_limit) {
7250
7304
  return limitBytes;
7251
7305
  }
7252
7306
  //#endregion
7253
- export { schemaVersion as $, inspectionQuerySchema as A, privateReviewHash as B, loadAuthenticatedReview as C, sessionUsefulnessRecommendation as D, aggregateUsefulness as E, reuseQuerySchema as F, initializeAndClaim as G, createJourneyPayloadFiles as H, batchQuery as I, withDatabase as J, ownership as K, isPrivateResourceKind as L, sameCandidateRequest as M, validateCandidateAttempt as N, sessionQuery as O, validateUnitCandidate as P, checkVersion as Q, privateResourceHeader as R, loadAcceptedReview as S, loadPrivateResource as T, validateBatchBody as U, batchHeader as V, requireActiveBatch as W, readStoredState as X, readBundleDirectory as Y, validateState as Z, loadRereadBodies as _, isSqliteCorruption as _t, decodeError as a, inspectStateFiles as at, validateSessionReconciliation as b, dropsAnchor as c, readResetMarker as ct, parseDelivery as d, syncDirectory as dt, beginReset as et, validateCandidate as f, withStateSnapshot as ft, loadReconciliation as g, isCoordinationBusy as gt, loadPreparedBodies as h, errorCode as ht, createExecutor as i, hasResetMarker as it, evaluateUnitEvidence as j, resourceSelectionQuerySchema as k, replySchema as l, recheckPrivatePath as lt, loadPreparation as m, StoreError as mt, releaseInheritedHeapFlags as n, databaseName as nt, ProtocolError as o, present as ot, loadStatus as p, withFileCheckTimings as pt, validateDatabase as q, storeHeapLimits as r, finishReset as rt, allowedReplies as s, privatePath as st, assertStoreHeap as t, createDatabaseFile as tt, operations as u, stateDirectory as ut, loadSessionBodies as v, loadBatch as w, validateSessionBindings as x, validatePreparationSelection as y, termReuseQuerySchema as z };
7307
+ export { checkVersion as $, resourceSelectionQuerySchema as A, termReuseQuerySchema as B, loadAcceptedReview as C, aggregateUsefulness as D, loadPrivateResource as E, validateUnitCandidate as F, requireActiveBatch as G, batchHeader as H, reuseQuerySchema as I, validateDatabase as J, initializeAndClaim as K, batchQuery as L, evaluateUnitEvidence as M, sameCandidateRequest as N, sessionUsefulnessRecommendation as O, validateCandidateAttempt as P, validateState as Q, isPrivateResourceKind as R, validateSessionBindings as S, loadBatch as T, createJourneyPayloadFiles as U, privateReviewHash as V, validateBatchBody as W, readBundleDirectory as X, withDatabase as Y, readStoredState as Z, loadReconciliation as _, isCoordinationBusy as _t, decodeError as a, hasResetMarker as at, validatePreparationSelection as b, dropsAnchor as c, privatePath as ct, parseDelivery as d, stateDirectory as dt, schemaVersion as et, validateCandidate as f, syncDirectory as ft, loadPreparedBodies as g, errorCode as gt, loadPreparation as h, StoreError as ht, createExecutor as i, finishReset as it, inspectionQuerySchema as j, sessionQuery as k, replySchema as l, readResetMarker as lt, loadStatus as m, withFileCheckTimings as mt, releaseInheritedHeapFlags as n, createDatabaseFile as nt, ProtocolError as o, inspectStateFiles as ot, classificationJourneyCommit as p, withStateSnapshot as pt, ownership as q, storeHeapLimits as r, databaseName as rt, allowedReplies as s, present as st, assertStoreHeap as t, beginReset as tt, operations as u, recheckPrivatePath as ut, loadRereadBodies as v, isSqliteCorruption as vt, loadAuthenticatedReview as w, validateSessionReconciliation as x, loadSessionBodies as y, privateResourceHeader as z };
@@ -0,0 +1,57 @@
1
+ import { Y as createInspectionProcessor } from "./src-CPbdnGrk.mjs";
2
+ import { yn as createStaticProcessor } from "./locate-U3-nkird.mjs";
3
+ import { l as createNativeAdapters, u as createGitNameSeedProvider } from "./src-qoLRvX-A.mjs";
4
+ import { H as validateInspectionRequest } from "./src-B4R5XMEP.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 {};