@gitroll/tacitt-cli 0.0.0-stage → 0.1.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 (140) hide show
  1. package/README.md +84 -2
  2. package/bin/INDEX.md +9 -0
  3. package/bin/tacitt.cjs +16 -0
  4. package/dist/agent-setup-B85GaVIz.mjs +71 -0
  5. package/dist/agent-setup-worker.mjs +56 -0
  6. package/dist/cli.mjs +1343 -0
  7. package/dist/codex-title-worker.mjs +215 -0
  8. package/dist/configured-preview-worker.mjs +133 -0
  9. package/dist/configured-session-worker.mjs +117 -0
  10. package/dist/frame-D1j9R8xX.mjs +84 -0
  11. package/dist/heap-1FYhGds4.mjs +75 -0
  12. package/dist/heap-tfU61Ehy.mjs +7253 -0
  13. package/dist/job--TceKk0l.mjs +194 -0
  14. package/dist/locate-Bn32k2se.mjs +10647 -0
  15. package/dist/model-7Nu7szNP.mjs +41 -0
  16. package/dist/operation-executor.mjs +181 -0
  17. package/dist/preview-worker.mjs +22 -0
  18. package/dist/privacy-validator.mjs +46 -0
  19. package/dist/query-Da-KDbSV.mjs +14511 -0
  20. package/dist/run-CCATsHS2.mjs +916 -0
  21. package/dist/session-process.mjs +90 -0
  22. package/dist/src-BngGpFKd.mjs +16416 -0
  23. package/dist/src-CPPjOyHZ.mjs +12782 -0
  24. package/dist/src-DynBRDBc.mjs +6590 -0
  25. package/dist/store-database-worker.mjs +14 -0
  26. package/dist/web/THIRD_PARTY_LICENSES.md +388 -0
  27. package/dist/web/assets/ibm-plex-mono-cyrillic-400-normal-BSMlKf0J.woff2 +0 -0
  28. package/dist/web/assets/ibm-plex-mono-cyrillic-400-normal-CEL4l2ZJ.woff +0 -0
  29. package/dist/web/assets/ibm-plex-mono-cyrillic-500-normal-Ael50iVv.woff +0 -0
  30. package/dist/web/assets/ibm-plex-mono-cyrillic-500-normal-Bq9vWWag.woff2 +0 -0
  31. package/dist/web/assets/ibm-plex-mono-cyrillic-ext-400-normal-DMdlQ8Kv.woff +0 -0
  32. package/dist/web/assets/ibm-plex-mono-cyrillic-ext-400-normal-xuaO2J-f.woff2 +0 -0
  33. package/dist/web/assets/ibm-plex-mono-cyrillic-ext-500-normal-BIfNGwUT.woff +0 -0
  34. package/dist/web/assets/ibm-plex-mono-cyrillic-ext-500-normal-BqneJy0T.woff2 +0 -0
  35. package/dist/web/assets/ibm-plex-mono-latin-400-normal-CvHOgSBP.woff +0 -0
  36. package/dist/web/assets/ibm-plex-mono-latin-400-normal-DMJ8VG8y.woff2 +0 -0
  37. package/dist/web/assets/ibm-plex-mono-latin-500-normal-CB9ihrfo.woff +0 -0
  38. package/dist/web/assets/ibm-plex-mono-latin-500-normal-DSY6xOcd.woff2 +0 -0
  39. package/dist/web/assets/ibm-plex-mono-latin-ext-400-normal-BmRBH3aV.woff2 +0 -0
  40. package/dist/web/assets/ibm-plex-mono-latin-ext-400-normal-D3D2R8hC.woff +0 -0
  41. package/dist/web/assets/ibm-plex-mono-latin-ext-500-normal-CAhNIIs5.woff2 +0 -0
  42. package/dist/web/assets/ibm-plex-mono-latin-ext-500-normal-CZ70TYgx.woff +0 -0
  43. package/dist/web/assets/ibm-plex-mono-vietnamese-400-normal-BulugwFq.woff2 +0 -0
  44. package/dist/web/assets/ibm-plex-mono-vietnamese-400-normal-DDuiU_S-.woff +0 -0
  45. package/dist/web/assets/ibm-plex-mono-vietnamese-500-normal-C8zxqsMH.woff +0 -0
  46. package/dist/web/assets/ibm-plex-mono-vietnamese-500-normal-DZ4AoWbu.woff2 +0 -0
  47. package/dist/web/assets/ibm-plex-sans-cyrillic-400-normal-BTotfTJu.woff +0 -0
  48. package/dist/web/assets/ibm-plex-sans-cyrillic-400-normal-DZqxrq2p.woff2 +0 -0
  49. package/dist/web/assets/ibm-plex-sans-cyrillic-500-normal-ByOcLdNv.woff +0 -0
  50. package/dist/web/assets/ibm-plex-sans-cyrillic-500-normal-CocWQlwt.woff2 +0 -0
  51. package/dist/web/assets/ibm-plex-sans-cyrillic-600-normal-71GNu3SW.woff2 +0 -0
  52. package/dist/web/assets/ibm-plex-sans-cyrillic-600-normal-BGq0mW3O.woff +0 -0
  53. package/dist/web/assets/ibm-plex-sans-cyrillic-700-normal-D_uavGvn.woff2 +0 -0
  54. package/dist/web/assets/ibm-plex-sans-cyrillic-700-normal-RFb1v-CK.woff +0 -0
  55. package/dist/web/assets/ibm-plex-sans-cyrillic-ext-400-normal-Dsrv2Tcn.woff +0 -0
  56. package/dist/web/assets/ibm-plex-sans-cyrillic-ext-400-normal-g30qAdWV.woff2 +0 -0
  57. package/dist/web/assets/ibm-plex-sans-cyrillic-ext-500-normal-Cs5J6C77.woff2 +0 -0
  58. package/dist/web/assets/ibm-plex-sans-cyrillic-ext-500-normal-DB5PtV2g.woff +0 -0
  59. package/dist/web/assets/ibm-plex-sans-cyrillic-ext-600-normal-Bz0x94Yp.woff +0 -0
  60. package/dist/web/assets/ibm-plex-sans-cyrillic-ext-600-normal-DUMzJB7m.woff2 +0 -0
  61. package/dist/web/assets/ibm-plex-sans-cyrillic-ext-700-normal-BmRLXWpJ.woff2 +0 -0
  62. package/dist/web/assets/ibm-plex-sans-cyrillic-ext-700-normal-DCQwxkRk.woff +0 -0
  63. package/dist/web/assets/ibm-plex-sans-greek-400-normal-D9ESIMu3.woff +0 -0
  64. package/dist/web/assets/ibm-plex-sans-greek-400-normal-_efipK4i.woff2 +0 -0
  65. package/dist/web/assets/ibm-plex-sans-greek-500-normal-CuWXN6rf.woff +0 -0
  66. package/dist/web/assets/ibm-plex-sans-greek-500-normal-JMMifIXV.woff2 +0 -0
  67. package/dist/web/assets/ibm-plex-sans-greek-600-normal-D-CqTdkO.woff +0 -0
  68. package/dist/web/assets/ibm-plex-sans-greek-600-normal-DzTrcv_p.woff2 +0 -0
  69. package/dist/web/assets/ibm-plex-sans-greek-700-normal-CkZN0sRy.woff +0 -0
  70. package/dist/web/assets/ibm-plex-sans-greek-700-normal-wyJ6jzdA.woff2 +0 -0
  71. package/dist/web/assets/ibm-plex-sans-latin-400-normal-CDDApCn2.woff2 +0 -0
  72. package/dist/web/assets/ibm-plex-sans-latin-400-normal-CYLoc0-x.woff +0 -0
  73. package/dist/web/assets/ibm-plex-sans-latin-500-normal-6ng42L7E.woff2 +0 -0
  74. package/dist/web/assets/ibm-plex-sans-latin-500-normal-BgVn5rGT.woff +0 -0
  75. package/dist/web/assets/ibm-plex-sans-latin-600-normal-Cu4Hd6ag.woff +0 -0
  76. package/dist/web/assets/ibm-plex-sans-latin-600-normal-CuJfVYMP.woff2 +0 -0
  77. package/dist/web/assets/ibm-plex-sans-latin-700-normal-Bth3BMcD.woff +0 -0
  78. package/dist/web/assets/ibm-plex-sans-latin-700-normal-Bxkt5Cjx.woff2 +0 -0
  79. package/dist/web/assets/ibm-plex-sans-latin-ext-400-normal-C5H60-Va.woff2 +0 -0
  80. package/dist/web/assets/ibm-plex-sans-latin-ext-400-normal-RBey6euL.woff +0 -0
  81. package/dist/web/assets/ibm-plex-sans-latin-ext-500-normal-D0aIdm-b.woff +0 -0
  82. package/dist/web/assets/ibm-plex-sans-latin-ext-500-normal-DakdToA3.woff2 +0 -0
  83. package/dist/web/assets/ibm-plex-sans-latin-ext-600-normal-DIrixKbi.woff +0 -0
  84. package/dist/web/assets/ibm-plex-sans-latin-ext-600-normal-DOrvGEcy.woff2 +0 -0
  85. package/dist/web/assets/ibm-plex-sans-latin-ext-700-normal-DZH6Xh-4.woff +0 -0
  86. package/dist/web/assets/ibm-plex-sans-latin-ext-700-normal-aMgXseD4.woff2 +0 -0
  87. package/dist/web/assets/ibm-plex-sans-vietnamese-400-normal-DG4YqDda.woff2 +0 -0
  88. package/dist/web/assets/ibm-plex-sans-vietnamese-400-normal-fK1oJ5dG.woff +0 -0
  89. package/dist/web/assets/ibm-plex-sans-vietnamese-500-normal-BEb3_waV.woff +0 -0
  90. package/dist/web/assets/ibm-plex-sans-vietnamese-500-normal-e4dixQRQ.woff2 +0 -0
  91. package/dist/web/assets/ibm-plex-sans-vietnamese-600-normal-DgdngZtN.woff +0 -0
  92. package/dist/web/assets/ibm-plex-sans-vietnamese-600-normal-DpPYBSTl.woff2 +0 -0
  93. package/dist/web/assets/ibm-plex-sans-vietnamese-700-normal-BV5B8Are.woff +0 -0
  94. package/dist/web/assets/ibm-plex-sans-vietnamese-700-normal-CkEo6LDy.woff2 +0 -0
  95. package/dist/web/assets/index-CWQ05PFl.js +67 -0
  96. package/dist/web/assets/index-J-AWt_cW.css +1 -0
  97. package/dist/web/index.html +14 -0
  98. package/package.json +56 -3
  99. package/skills/INDEX.md +9 -0
  100. package/skills/tacitt/INDEX.md +11 -0
  101. package/skills/tacitt/SKILL.md +42 -0
  102. package/skills/tacitt/references/INDEX.md +15 -0
  103. package/skills/tacitt/references/b-method.md +22 -0
  104. package/skills/tacitt/references/bootstrap.md +109 -0
  105. package/skills/tacitt/references/classification.md +83 -0
  106. package/skills/tacitt/references/commands.md +147 -0
  107. package/skills/tacitt/references/journey.md +52 -0
  108. package/skills/tacitt/references/parallel-review.md +64 -0
  109. package/skills/tacitt/references/send.md +30 -0
  110. package/skills/tacitt/scripts/INDEX.md +43 -0
  111. package/skills/tacitt/scripts/answer.mjs +257 -0
  112. package/skills/tacitt/scripts/describe.mjs +55 -0
  113. package/skills/tacitt/scripts/journey-card-consolidation.d.mts +8 -0
  114. package/skills/tacitt/scripts/journey-card-consolidation.mjs +146 -0
  115. package/skills/tacitt/scripts/journey-classification-metadata.d.mts +16 -0
  116. package/skills/tacitt/scripts/journey-classification-metadata.mjs +111 -0
  117. package/skills/tacitt/scripts/journey-classification-progress.mjs +194 -0
  118. package/skills/tacitt/scripts/journey-classification-tasks.d.mts +18 -0
  119. package/skills/tacitt/scripts/journey-classification-tasks.mjs +345 -0
  120. package/skills/tacitt/scripts/journey-classification-validation.d.mts +20 -0
  121. package/skills/tacitt/scripts/journey-classification-validation.mjs +219 -0
  122. package/skills/tacitt/scripts/journey-classification.mjs +145 -0
  123. package/skills/tacitt/scripts/journey-consolidation-submit.mjs +190 -0
  124. package/skills/tacitt/scripts/journey-consolidation.d.mts +9 -0
  125. package/skills/tacitt/scripts/journey-consolidation.mjs +224 -0
  126. package/skills/tacitt/scripts/journey-scan-timing.mjs +143 -0
  127. package/skills/tacitt/scripts/journey-state.d.mts +42 -0
  128. package/skills/tacitt/scripts/journey-state.mjs +268 -0
  129. package/skills/tacitt/scripts/journey-tasks.d.mts +26 -0
  130. package/skills/tacitt/scripts/journey-tasks.mjs +183 -0
  131. package/skills/tacitt/scripts/journey.d.mts +38 -0
  132. package/skills/tacitt/scripts/journey.mjs +451 -0
  133. package/skills/tacitt/scripts/local-cli.d.mts +18 -0
  134. package/skills/tacitt/scripts/local-cli.mjs +116 -0
  135. package/skills/tacitt/scripts/privacy-validator.mjs +10350 -0
  136. package/skills/tacitt/scripts/review-stream-client.d.mts +22 -0
  137. package/skills/tacitt/scripts/review-stream-client.mjs +194 -0
  138. package/skills/tacitt/scripts/review.d.mts +87 -0
  139. package/skills/tacitt/scripts/review.mjs +1589 -0
  140. package/skills/tacitt/scripts/verify-cli.mjs +10 -0
@@ -0,0 +1,41 @@
1
+ import "./src-CPPjOyHZ.mjs";
2
+ //#region packages/harnesses/src/discovery/model.ts
3
+ const discoveryBounds = {
4
+ entries: 1e5,
5
+ depth: 32,
6
+ parsers: 2,
7
+ metadataBytes: 262144,
8
+ journalBytes: 16777216,
9
+ chunkBytes: 65536,
10
+ headChunkBytes: 16384,
11
+ tailBytes: 16384,
12
+ warnings: 200
13
+ };
14
+ const errorCode = (error) => typeof error === "object" && error !== null && "code" in error && typeof error.code === "string" ? error.code : void 0;
15
+ const isRecord = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
16
+ const checkDiscoveryAbort = (signal) => {
17
+ if (signal?.aborted) throw new Error("DISCOVERY_CANCELED");
18
+ };
19
+ function unresolvedMetadata(harness, warning) {
20
+ return {
21
+ path: null,
22
+ title: `Unresolved workspace (${harness})`,
23
+ sourceSessionId: null,
24
+ createdAt: null,
25
+ lastInteractionAt: null,
26
+ warnings: ["UNRESOLVED_WORKSPACE", warning],
27
+ decodedBytes: 0,
28
+ decodedDigest: null
29
+ };
30
+ }
31
+ var DiscoveryWarnings = class {
32
+ counts = /* @__PURE__ */ new Map();
33
+ add(code, count = 1) {
34
+ this.counts.set(code, (this.counts.get(code) ?? 0) + count);
35
+ }
36
+ list() {
37
+ return [...this.counts].sort(([left], [right]) => left.localeCompare(right)).slice(0, discoveryBounds.warnings).map(([code, count]) => `${code}:${count}`);
38
+ }
39
+ };
40
+ //#endregion
41
+ export { isRecord as a, errorCode as i, checkDiscoveryAbort as n, unresolvedMetadata as o, discoveryBounds as r, DiscoveryWarnings as t };
@@ -0,0 +1,181 @@
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";
4
+ import { z } from "zod";
5
+ import { setTimeout } from "node:timers/promises";
6
+ //#region apps/cli/src/operation/executor.ts
7
+ process.umask(63);
8
+ let runtime;
9
+ let detached = false;
10
+ let started = false;
11
+ let operationId;
12
+ let stopRequested = false;
13
+ let stopping;
14
+ const stop = () => {
15
+ stopRequested = true;
16
+ return stopping ??= runtime?.close() ?? Promise.resolve();
17
+ };
18
+ const send = (event) => new Promise((resolve, reject) => {
19
+ if (!process.connected) {
20
+ if (detached) resolve();
21
+ else reject(new ApplicationError("OPERATION_CANCELED"));
22
+ return;
23
+ }
24
+ process.send?.(event, (error) => error ? reject(error) : resolve());
25
+ });
26
+ const parentLost = () => {
27
+ if (!detached) stop().catch(() => {
28
+ process.exitCode = 1;
29
+ });
30
+ };
31
+ process.on("disconnect", parentLost);
32
+ process.on("SIGINT", () => {
33
+ detached = false;
34
+ parentLost();
35
+ });
36
+ process.on("SIGTERM", () => {
37
+ detached = false;
38
+ parentLost();
39
+ });
40
+ process.on("message", (message) => {
41
+ if (typeof message === "object" && message !== null && "detach" in message && message.detach === true) {
42
+ if (!operationId) return;
43
+ detached = true;
44
+ send({
45
+ event: "detached",
46
+ operationId
47
+ }).then(() => {
48
+ if (process.connected) process.disconnect?.();
49
+ }).catch((error) => {
50
+ try {
51
+ runtime?.diagnostics.onFailure("detach-ack", error, operationId);
52
+ } catch {
53
+ try {
54
+ process.stderr.write("LOCAL_DIAGNOSTICS_UNAVAILABLE: detach acknowledgement diagnostic failed.\n");
55
+ } catch {}
56
+ } finally {
57
+ detached = false;
58
+ parentLost();
59
+ }
60
+ });
61
+ return;
62
+ }
63
+ if (started) return;
64
+ started = true;
65
+ execute(message);
66
+ });
67
+ async function execute(message) {
68
+ try {
69
+ const request = executorRequestSchema.parse(message);
70
+ if (!longCommands.has(request.command)) throw new ApplicationError("INVALID_ARGUMENTS");
71
+ let diagnosticCount = 0;
72
+ runtime = await createRuntime(parseOptions(request.args), {
73
+ getOperationId: () => operationId,
74
+ onSafeDiagnostic: (diagnostic) => {
75
+ if (diagnosticCount++ >= 32 || !process.connected) return;
76
+ send({
77
+ event: "diagnostic",
78
+ ...diagnostic
79
+ }).catch((error) => {
80
+ process.stderr.write(`${safeCode(error)}: diagnostic transport failed.\n`);
81
+ });
82
+ }
83
+ });
84
+ if (stopRequested || !process.connected && !detached) throw new ApplicationError("OPERATION_CANCELED");
85
+ const result = await invoke(runtime, request.command, request.input);
86
+ const record = z.record(z.string(), z.unknown()).nullable().parse(result);
87
+ const packagingId = z.object({ id: z.string() }).nullable().parse(record?.["operation"] ?? null)?.id;
88
+ const discoveryId = z.object({ id: z.string() }).nullable().parse(record?.["discoveryOperation"] ?? null)?.id;
89
+ const id = request.command === "account.signIn" ? record?.["operationId"] : request.command === "inspection.start" ? record?.["scanId"] : request.command === "workflow.package" ? packagingId : request.command === "workflow.resume" && record?.["phase"] === "packaging" ? packagingId : discoveryId;
90
+ if (typeof id !== "string") {
91
+ if (request.command === "account.signIn" && record?.["state"] === "signed-in") {
92
+ await runtime.close();
93
+ await send({
94
+ event: "completed",
95
+ operationId: "",
96
+ result
97
+ });
98
+ return;
99
+ }
100
+ throw new ApplicationError("INVALID_OPERATION");
101
+ }
102
+ operationId = id;
103
+ await send({
104
+ event: "started",
105
+ operationId,
106
+ result
107
+ });
108
+ await runtime.application.settle();
109
+ if (request.command === "account.signIn") {
110
+ let settled = false;
111
+ let failure;
112
+ const authorization = runtime.account.settle().then(() => {
113
+ settled = true;
114
+ }, (error) => {
115
+ failure = error;
116
+ settled = true;
117
+ });
118
+ let previous = "";
119
+ while (!settled && !stopRequested) {
120
+ const account = await runtime.account.status();
121
+ const serialized = JSON.stringify(account);
122
+ if (account.state === "authorizing" && serialized !== previous) {
123
+ await send({
124
+ event: "progress",
125
+ operationId,
126
+ result: account
127
+ });
128
+ previous = serialized;
129
+ }
130
+ await setTimeout(200);
131
+ }
132
+ await authorization;
133
+ if (failure !== void 0) throw failure;
134
+ }
135
+ let final = await readOperation(runtime, operationId);
136
+ while (final.status === "running" && !stopRequested) final = (await waitOperation(runtime, operationId, 3e4)).operation;
137
+ await runtime.close();
138
+ await send({
139
+ event: "completed",
140
+ operationId,
141
+ result: final
142
+ });
143
+ } catch (error) {
144
+ const code = error instanceof z.ZodError ? "INVALID_ARGUMENTS" : safeCode(error);
145
+ runtime?.diagnostics.onFailure("execution", error, operationId);
146
+ process.stderr.write(`${JSON.stringify({
147
+ event: "executor.failed",
148
+ code,
149
+ stage: "execution",
150
+ operationId
151
+ })}\n`);
152
+ await send({
153
+ event: "error",
154
+ code,
155
+ field: safeField(error),
156
+ detail: startupFailure(error instanceof z.ZodError ? new ApplicationError("INVALID_ARGUMENTS", void 0, { cause: error }) : error).trim().slice(0, 2048),
157
+ ...operationId ? { operationId } : {}
158
+ }).catch((sendError) => {
159
+ process.stderr.write(`${JSON.stringify({
160
+ event: "executor.failed",
161
+ code: safeCode(sendError),
162
+ stage: "error-response",
163
+ operationId
164
+ })}\n`);
165
+ });
166
+ process.exitCode = 1;
167
+ } finally {
168
+ await runtime?.close().catch((error) => {
169
+ process.stderr.write(`${JSON.stringify({
170
+ event: "executor.failed",
171
+ code: safeCode(error),
172
+ stage: "cleanup",
173
+ operationId
174
+ })}\n`);
175
+ process.exitCode = 1;
176
+ });
177
+ if (process.connected) process.disconnect?.();
178
+ }
179
+ }
180
+ //#endregion
181
+ export {};
@@ -0,0 +1,22 @@
1
+ import { n as assertPreviewHeap, o as previewInputSchema, t as runPreview } from "./run-CCATsHS2.mjs";
2
+ import { parentPort, workerData } from "node:worker_threads";
3
+ //#region packages/harnesses/src/preview/worker/index.ts
4
+ function notify(message) {
5
+ parentPort?.postMessage(message);
6
+ }
7
+ assertPreviewHeap();
8
+ try {
9
+ const input = workerData;
10
+ const { session, cursor } = previewInputSchema.parse(input);
11
+ notify({
12
+ kind: "result",
13
+ page: await runPreview(session, cursor, notify)
14
+ });
15
+ } catch (error) {
16
+ notify({
17
+ kind: "error",
18
+ code: error instanceof Error && (error.message === "SOURCE_CHANGED" || error.message === "INVALID_PREVIEW_CURSOR") ? error.message : "PREVIEW_WITHHELD"
19
+ });
20
+ }
21
+ //#endregion
22
+ export {};
@@ -0,0 +1,46 @@
1
+ import { Dt as privacyResolveSchema, Ot as privacyTermKey, t as locateTerms, wt as decisionCardInputSchema } from "./locate-Bn32k2se.mjs";
2
+ import { z } from "zod";
3
+ //#region apps/cli/src/skill-install/privacy-validator.ts
4
+ const suppliedTerms = z.array(z.object({
5
+ key: z.string(),
6
+ type: z.string(),
7
+ value: z.string()
8
+ }));
9
+ /** Task-local validation; authoritative application ingestion still owns current state. */
10
+ function validateStageAnswer(input, answer) {
11
+ const task = z.object({
12
+ terms: suppliedTerms.optional(),
13
+ card: z.unknown().optional()
14
+ }).parse(input);
15
+ if (!task.terms) throw new Error("TASK_INPUT");
16
+ const expected = new Set(task.terms.map((term) => term.key));
17
+ const keys = [];
18
+ if (task.card !== void 0) {
19
+ const value = z.object({ resolutions: privacyResolveSchema.shape.resolutions }).strict().parse(answer);
20
+ keys.push(...value.resolutions.map(privacyTermKey));
21
+ } else {
22
+ const value = z.object({ cards: z.array(decisionCardInputSchema).min(1) }).strict().parse(answer);
23
+ if (new Set(value.cards.map((card) => card.id)).size !== value.cards.length) throw new Error("INVALID_SELECTION");
24
+ keys.push(...value.cards.flatMap((card) => card.termKeys));
25
+ }
26
+ const received = new Set(keys);
27
+ if (keys.length !== expected.size || received.size !== keys.length || keys.some((key) => !expected.has(key))) {
28
+ const error = /* @__PURE__ */ new Error("INVALID_SELECTION");
29
+ if (task.card !== void 0) throw error;
30
+ const seen = /* @__PURE__ */ new Set();
31
+ const duplicates = /* @__PURE__ */ new Set();
32
+ for (const key of keys) {
33
+ if (seen.has(key)) duplicates.add(key);
34
+ seen.add(key);
35
+ }
36
+ throw Object.assign(error, { issues: [{
37
+ code: "exact_key_coverage",
38
+ path: ["cards"],
39
+ missing: [...expected].filter((key) => !received.has(key)),
40
+ extra: [...received].filter((key) => !expected.has(key)),
41
+ duplicate: [...duplicates]
42
+ }] });
43
+ }
44
+ }
45
+ //#endregion
46
+ export { locateTerms, validateStageAnswer };