@gitroll/tacitt-cli 0.0.0-stage → 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 (142) 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-B8DAiQ6Z.mjs +71 -0
  5. package/dist/agent-setup-worker.mjs +56 -0
  6. package/dist/cli.mjs +1442 -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-waS5FnN5.mjs +84 -0
  11. package/dist/heap-1FYhGds4.mjs +75 -0
  12. package/dist/heap-BHcvxWCw.mjs +7265 -0
  13. package/dist/inspection-worker.mjs +57 -0
  14. package/dist/job-J3NFw3MH.mjs +194 -0
  15. package/dist/locate-U3-nkird.mjs +10670 -0
  16. package/dist/messages-D3m3bhva.mjs +40 -0
  17. package/dist/model-BJdTLNjT.mjs +41 -0
  18. package/dist/operation-executor.mjs +181 -0
  19. package/dist/preview-worker.mjs +22 -0
  20. package/dist/privacy-validator.mjs +46 -0
  21. package/dist/query-BA0XCwnR.mjs +14869 -0
  22. package/dist/run-BeLHsZWb.mjs +916 -0
  23. package/dist/session-process.mjs +90 -0
  24. package/dist/src-B5SArpVY.mjs +6601 -0
  25. package/dist/src-CC95LYYp.mjs +12985 -0
  26. package/dist/src-k0Ya1Bri.mjs +16422 -0
  27. package/dist/store-database-worker.mjs +14 -0
  28. package/dist/web/THIRD_PARTY_LICENSES.md +388 -0
  29. package/dist/web/assets/ibm-plex-mono-cyrillic-400-normal-BSMlKf0J.woff2 +0 -0
  30. package/dist/web/assets/ibm-plex-mono-cyrillic-400-normal-CEL4l2ZJ.woff +0 -0
  31. package/dist/web/assets/ibm-plex-mono-cyrillic-500-normal-Ael50iVv.woff +0 -0
  32. package/dist/web/assets/ibm-plex-mono-cyrillic-500-normal-Bq9vWWag.woff2 +0 -0
  33. package/dist/web/assets/ibm-plex-mono-cyrillic-ext-400-normal-DMdlQ8Kv.woff +0 -0
  34. package/dist/web/assets/ibm-plex-mono-cyrillic-ext-400-normal-xuaO2J-f.woff2 +0 -0
  35. package/dist/web/assets/ibm-plex-mono-cyrillic-ext-500-normal-BIfNGwUT.woff +0 -0
  36. package/dist/web/assets/ibm-plex-mono-cyrillic-ext-500-normal-BqneJy0T.woff2 +0 -0
  37. package/dist/web/assets/ibm-plex-mono-latin-400-normal-CvHOgSBP.woff +0 -0
  38. package/dist/web/assets/ibm-plex-mono-latin-400-normal-DMJ8VG8y.woff2 +0 -0
  39. package/dist/web/assets/ibm-plex-mono-latin-500-normal-CB9ihrfo.woff +0 -0
  40. package/dist/web/assets/ibm-plex-mono-latin-500-normal-DSY6xOcd.woff2 +0 -0
  41. package/dist/web/assets/ibm-plex-mono-latin-ext-400-normal-BmRBH3aV.woff2 +0 -0
  42. package/dist/web/assets/ibm-plex-mono-latin-ext-400-normal-D3D2R8hC.woff +0 -0
  43. package/dist/web/assets/ibm-plex-mono-latin-ext-500-normal-CAhNIIs5.woff2 +0 -0
  44. package/dist/web/assets/ibm-plex-mono-latin-ext-500-normal-CZ70TYgx.woff +0 -0
  45. package/dist/web/assets/ibm-plex-mono-vietnamese-400-normal-BulugwFq.woff2 +0 -0
  46. package/dist/web/assets/ibm-plex-mono-vietnamese-400-normal-DDuiU_S-.woff +0 -0
  47. package/dist/web/assets/ibm-plex-mono-vietnamese-500-normal-C8zxqsMH.woff +0 -0
  48. package/dist/web/assets/ibm-plex-mono-vietnamese-500-normal-DZ4AoWbu.woff2 +0 -0
  49. package/dist/web/assets/ibm-plex-sans-cyrillic-400-normal-BTotfTJu.woff +0 -0
  50. package/dist/web/assets/ibm-plex-sans-cyrillic-400-normal-DZqxrq2p.woff2 +0 -0
  51. package/dist/web/assets/ibm-plex-sans-cyrillic-500-normal-ByOcLdNv.woff +0 -0
  52. package/dist/web/assets/ibm-plex-sans-cyrillic-500-normal-CocWQlwt.woff2 +0 -0
  53. package/dist/web/assets/ibm-plex-sans-cyrillic-600-normal-71GNu3SW.woff2 +0 -0
  54. package/dist/web/assets/ibm-plex-sans-cyrillic-600-normal-BGq0mW3O.woff +0 -0
  55. package/dist/web/assets/ibm-plex-sans-cyrillic-700-normal-D_uavGvn.woff2 +0 -0
  56. package/dist/web/assets/ibm-plex-sans-cyrillic-700-normal-RFb1v-CK.woff +0 -0
  57. package/dist/web/assets/ibm-plex-sans-cyrillic-ext-400-normal-Dsrv2Tcn.woff +0 -0
  58. package/dist/web/assets/ibm-plex-sans-cyrillic-ext-400-normal-g30qAdWV.woff2 +0 -0
  59. package/dist/web/assets/ibm-plex-sans-cyrillic-ext-500-normal-Cs5J6C77.woff2 +0 -0
  60. package/dist/web/assets/ibm-plex-sans-cyrillic-ext-500-normal-DB5PtV2g.woff +0 -0
  61. package/dist/web/assets/ibm-plex-sans-cyrillic-ext-600-normal-Bz0x94Yp.woff +0 -0
  62. package/dist/web/assets/ibm-plex-sans-cyrillic-ext-600-normal-DUMzJB7m.woff2 +0 -0
  63. package/dist/web/assets/ibm-plex-sans-cyrillic-ext-700-normal-BmRLXWpJ.woff2 +0 -0
  64. package/dist/web/assets/ibm-plex-sans-cyrillic-ext-700-normal-DCQwxkRk.woff +0 -0
  65. package/dist/web/assets/ibm-plex-sans-greek-400-normal-D9ESIMu3.woff +0 -0
  66. package/dist/web/assets/ibm-plex-sans-greek-400-normal-_efipK4i.woff2 +0 -0
  67. package/dist/web/assets/ibm-plex-sans-greek-500-normal-CuWXN6rf.woff +0 -0
  68. package/dist/web/assets/ibm-plex-sans-greek-500-normal-JMMifIXV.woff2 +0 -0
  69. package/dist/web/assets/ibm-plex-sans-greek-600-normal-D-CqTdkO.woff +0 -0
  70. package/dist/web/assets/ibm-plex-sans-greek-600-normal-DzTrcv_p.woff2 +0 -0
  71. package/dist/web/assets/ibm-plex-sans-greek-700-normal-CkZN0sRy.woff +0 -0
  72. package/dist/web/assets/ibm-plex-sans-greek-700-normal-wyJ6jzdA.woff2 +0 -0
  73. package/dist/web/assets/ibm-plex-sans-latin-400-normal-CDDApCn2.woff2 +0 -0
  74. package/dist/web/assets/ibm-plex-sans-latin-400-normal-CYLoc0-x.woff +0 -0
  75. package/dist/web/assets/ibm-plex-sans-latin-500-normal-6ng42L7E.woff2 +0 -0
  76. package/dist/web/assets/ibm-plex-sans-latin-500-normal-BgVn5rGT.woff +0 -0
  77. package/dist/web/assets/ibm-plex-sans-latin-600-normal-Cu4Hd6ag.woff +0 -0
  78. package/dist/web/assets/ibm-plex-sans-latin-600-normal-CuJfVYMP.woff2 +0 -0
  79. package/dist/web/assets/ibm-plex-sans-latin-700-normal-Bth3BMcD.woff +0 -0
  80. package/dist/web/assets/ibm-plex-sans-latin-700-normal-Bxkt5Cjx.woff2 +0 -0
  81. package/dist/web/assets/ibm-plex-sans-latin-ext-400-normal-C5H60-Va.woff2 +0 -0
  82. package/dist/web/assets/ibm-plex-sans-latin-ext-400-normal-RBey6euL.woff +0 -0
  83. package/dist/web/assets/ibm-plex-sans-latin-ext-500-normal-D0aIdm-b.woff +0 -0
  84. package/dist/web/assets/ibm-plex-sans-latin-ext-500-normal-DakdToA3.woff2 +0 -0
  85. package/dist/web/assets/ibm-plex-sans-latin-ext-600-normal-DIrixKbi.woff +0 -0
  86. package/dist/web/assets/ibm-plex-sans-latin-ext-600-normal-DOrvGEcy.woff2 +0 -0
  87. package/dist/web/assets/ibm-plex-sans-latin-ext-700-normal-DZH6Xh-4.woff +0 -0
  88. package/dist/web/assets/ibm-plex-sans-latin-ext-700-normal-aMgXseD4.woff2 +0 -0
  89. package/dist/web/assets/ibm-plex-sans-vietnamese-400-normal-DG4YqDda.woff2 +0 -0
  90. package/dist/web/assets/ibm-plex-sans-vietnamese-400-normal-fK1oJ5dG.woff +0 -0
  91. package/dist/web/assets/ibm-plex-sans-vietnamese-500-normal-BEb3_waV.woff +0 -0
  92. package/dist/web/assets/ibm-plex-sans-vietnamese-500-normal-e4dixQRQ.woff2 +0 -0
  93. package/dist/web/assets/ibm-plex-sans-vietnamese-600-normal-DgdngZtN.woff +0 -0
  94. package/dist/web/assets/ibm-plex-sans-vietnamese-600-normal-DpPYBSTl.woff2 +0 -0
  95. package/dist/web/assets/ibm-plex-sans-vietnamese-700-normal-BV5B8Are.woff +0 -0
  96. package/dist/web/assets/ibm-plex-sans-vietnamese-700-normal-CkEo6LDy.woff2 +0 -0
  97. package/dist/web/assets/index-Bjos73wK.js +67 -0
  98. package/dist/web/assets/index-Bl4C2b2_.css +1 -0
  99. package/dist/web/index.html +14 -0
  100. package/package.json +56 -3
  101. package/skills/INDEX.md +9 -0
  102. package/skills/tacitt/INDEX.md +11 -0
  103. package/skills/tacitt/SKILL.md +44 -0
  104. package/skills/tacitt/references/INDEX.md +15 -0
  105. package/skills/tacitt/references/b-method.md +22 -0
  106. package/skills/tacitt/references/bootstrap.md +109 -0
  107. package/skills/tacitt/references/classification.md +83 -0
  108. package/skills/tacitt/references/commands.md +147 -0
  109. package/skills/tacitt/references/journey.md +54 -0
  110. package/skills/tacitt/references/parallel-review.md +64 -0
  111. package/skills/tacitt/references/send.md +30 -0
  112. package/skills/tacitt/scripts/INDEX.md +43 -0
  113. package/skills/tacitt/scripts/answer.mjs +278 -0
  114. package/skills/tacitt/scripts/describe.mjs +55 -0
  115. package/skills/tacitt/scripts/journey-card-consolidation.d.mts +17 -0
  116. package/skills/tacitt/scripts/journey-card-consolidation.mjs +209 -0
  117. package/skills/tacitt/scripts/journey-classification-metadata.d.mts +16 -0
  118. package/skills/tacitt/scripts/journey-classification-metadata.mjs +111 -0
  119. package/skills/tacitt/scripts/journey-classification-progress.mjs +195 -0
  120. package/skills/tacitt/scripts/journey-classification-tasks.d.mts +18 -0
  121. package/skills/tacitt/scripts/journey-classification-tasks.mjs +345 -0
  122. package/skills/tacitt/scripts/journey-classification-validation.d.mts +20 -0
  123. package/skills/tacitt/scripts/journey-classification-validation.mjs +240 -0
  124. package/skills/tacitt/scripts/journey-classification.mjs +145 -0
  125. package/skills/tacitt/scripts/journey-consolidation-submit.mjs +227 -0
  126. package/skills/tacitt/scripts/journey-consolidation.d.mts +14 -0
  127. package/skills/tacitt/scripts/journey-consolidation.mjs +227 -0
  128. package/skills/tacitt/scripts/journey-scan-timing.mjs +143 -0
  129. package/skills/tacitt/scripts/journey-state.d.mts +43 -0
  130. package/skills/tacitt/scripts/journey-state.mjs +294 -0
  131. package/skills/tacitt/scripts/journey-tasks.d.mts +26 -0
  132. package/skills/tacitt/scripts/journey-tasks.mjs +185 -0
  133. package/skills/tacitt/scripts/journey.d.mts +40 -0
  134. package/skills/tacitt/scripts/journey.mjs +592 -0
  135. package/skills/tacitt/scripts/local-cli.d.mts +18 -0
  136. package/skills/tacitt/scripts/local-cli.mjs +116 -0
  137. package/skills/tacitt/scripts/privacy-validator.mjs +10369 -0
  138. package/skills/tacitt/scripts/review-stream-client.d.mts +22 -0
  139. package/skills/tacitt/scripts/review-stream-client.mjs +194 -0
  140. package/skills/tacitt/scripts/review.d.mts +87 -0
  141. package/skills/tacitt/scripts/review.mjs +1610 -0
  142. package/skills/tacitt/scripts/verify-cli.mjs +10 -0
@@ -0,0 +1,22 @@
1
+ import { type ChildProcess, type SpawnOptions } from 'node:child_process'
2
+
3
+ export const REVIEW_STREAM_REQUEST_TIMEOUT_MS: 75_000
4
+ export const REVIEW_STREAM_SHUTDOWN_STEP_MS: 1_000
5
+
6
+ export interface ReviewStreamClient {
7
+ busy(): number
8
+ readonly retired: boolean
9
+ readonly unavailable: boolean
10
+ call(procedure: string, input: unknown): Promise<unknown>
11
+ close(): Promise<void>
12
+ }
13
+
14
+ export interface ReviewStreamOptions {
15
+ spawnChild?: (command: string, args: string[], options: SpawnOptions) => ChildProcess
16
+ onUnavailable?: () => void
17
+ onRetired?: (stream: ReviewStreamClient) => void
18
+ /** Internal deterministic timing seam for transport tests; not a user configuration surface. */
19
+ timeouts?: { requestMs?: number; shutdownStepMs?: number }
20
+ }
21
+
22
+ export function startReviewStream(cli: string[], options?: ReviewStreamOptions): ReviewStreamClient
@@ -0,0 +1,194 @@
1
+ import { spawn } from 'node:child_process'
2
+
3
+ export const REVIEW_STREAM_REQUEST_TIMEOUT_MS = 75_000
4
+ export const REVIEW_STREAM_SHUTDOWN_STEP_MS = 1_000
5
+
6
+ /** One paired CLI stream with bounded requests and bounded owned-child shutdown. */
7
+ export function startReviewStream(
8
+ cli,
9
+ { spawnChild = spawn, onUnavailable = () => {}, onRetired = () => {}, timeouts = {} } = {},
10
+ ) {
11
+ const requestTimeoutMs = timeouts.requestMs ?? REVIEW_STREAM_REQUEST_TIMEOUT_MS
12
+ const shutdownStepMs = timeouts.shutdownStepMs ?? REVIEW_STREAM_SHUTDOWN_STEP_MS
13
+ const [command, ...prefix] = cli
14
+ const shell = process.platform === 'win32' && !/\.(exe|com)$/iu.test(command)
15
+ const args = [...prefix, 'review.stream']
16
+ const child = spawnChild(command, shell ? args.map(windowsArgument) : args, {
17
+ stdio: ['pipe', 'pipe', 'ignore'],
18
+ shell,
19
+ })
20
+ const pending = new Map()
21
+ let buffer = ''
22
+ let next = 0
23
+ let retired = false
24
+ let unavailable = false
25
+ let receivedReply = false
26
+ let startupFailure = null
27
+ let closed = false
28
+ let closePromise
29
+ let retirementPromise
30
+
31
+ const settleAll = (reply) => {
32
+ for (const [id, request] of pending) {
33
+ clearTimeout(request.timer)
34
+ pending.delete(id)
35
+ request.resolve(reply)
36
+ }
37
+ }
38
+ const markUnavailable = () => {
39
+ if (unavailable) return
40
+ unavailable = true
41
+ onUnavailable()
42
+ }
43
+ const retire = (failed) => {
44
+ if (retirementPromise) return retirementPromise
45
+ if (!startupFailure && (failed || pending.size > 0)) markUnavailable()
46
+ retired = true
47
+ settleAll(startupFailure)
48
+ retirementPromise = shutdown().finally(() => {
49
+ child.stdout.off('data', onData)
50
+ child.stdout.off('error', onStdoutError)
51
+ child.stdout.on('error', ignoreError)
52
+ child.stdin.off('error', onStdinError)
53
+ child.off('close', markClosed)
54
+ child.off('error', onChildError)
55
+ child.on('error', ignoreError)
56
+ if (current) onRetired(current)
57
+ })
58
+ return retirementPromise
59
+ }
60
+ const markClosed = () => {
61
+ if (closed) return
62
+ closed = true
63
+ void retire(pending.size > 0)
64
+ }
65
+
66
+ const onData = (chunk) => {
67
+ buffer += chunk
68
+ for (let index; (index = buffer.indexOf('\n')) >= 0;) {
69
+ const line = buffer.slice(0, index)
70
+ buffer = buffer.slice(index + 1)
71
+ let reply = null
72
+ try {
73
+ reply = JSON.parse(line)
74
+ } catch {
75
+ continue
76
+ }
77
+ if (
78
+ !receivedReply &&
79
+ reply?.event === 'review.stream.startup-failed' &&
80
+ reply.ok === false &&
81
+ reply.error?.code === 'COORDINATION_BUSY'
82
+ ) {
83
+ startupFailure = { ok: false, error: { code: 'COORDINATION_BUSY' } }
84
+ void retire(false)
85
+ return
86
+ }
87
+ const request = pending.get(reply?.id)
88
+ if (!request) continue
89
+ receivedReply = true
90
+ clearTimeout(request.timer)
91
+ pending.delete(reply.id)
92
+ request.resolve(reply)
93
+ }
94
+ }
95
+ const onStdinError = () => {
96
+ void retire(true)
97
+ }
98
+ const onStdoutError = () => void retire(true)
99
+ const onChildError = () => {
100
+ if (!Number.isInteger(child.pid)) closed = true
101
+ void retire(true)
102
+ }
103
+ const ignoreError = () => {}
104
+
105
+ const current = {
106
+ busy: () => pending.size,
107
+ get unavailable() {
108
+ return unavailable
109
+ },
110
+ get retired() {
111
+ return retired
112
+ },
113
+ call(procedure, input, { timeoutMs = requestTimeoutMs } = {}) {
114
+ if (retired || unavailable) return Promise.resolve(null)
115
+ const id = next++
116
+ return new Promise((resolve) => {
117
+ const timer = setTimeout(() => {
118
+ // A request may have committed before its reply disappeared. Every waiter on this
119
+ // sequential transport is therefore unknown; later recovery must reuse durable keys.
120
+ void retire(true)
121
+ }, timeoutMs)
122
+ pending.set(id, { resolve, timer })
123
+ try {
124
+ child.stdin.write(JSON.stringify({ id, procedure, input }) + '\n', (error) => {
125
+ if (error) void retire(true)
126
+ })
127
+ } catch {
128
+ void retire(true)
129
+ }
130
+ })
131
+ },
132
+ close: () => retire(pending.size > 0),
133
+ }
134
+
135
+ child.stdout.setEncoding('utf8')
136
+ child.stdout.on('data', onData)
137
+ child.stdout.on('error', onStdoutError)
138
+ child.on('close', markClosed)
139
+ child.on('error', onChildError)
140
+ child.stdin.on('error', onStdinError)
141
+
142
+ function shutdown() {
143
+ if (closePromise) return closePromise
144
+ closePromise = (async () => {
145
+ if (closed) return
146
+ try {
147
+ child.stdin.end()
148
+ } catch {
149
+ // A closed pipe does not change the unknown-outcome handling above.
150
+ }
151
+ if (await waitForClose(child, shutdownStepMs, () => closed)) return
152
+ signalOwnedChild(child, 'SIGTERM')
153
+ if (await waitForClose(child, shutdownStepMs, () => closed)) return
154
+ signalOwnedChild(child, 'SIGKILL')
155
+ await waitForClose(child, shutdownStepMs, () => closed)
156
+ })()
157
+ return closePromise
158
+ }
159
+
160
+ return current
161
+ }
162
+
163
+ function windowsArgument(value) {
164
+ return /^[\w./:@=+-]+$/u.test(value) ? value : `"${value.replaceAll('"', '""')}"`
165
+ }
166
+
167
+ function signalOwnedChild(child, signal) {
168
+ if (!Number.isInteger(child.pid) || child.pid <= 0) return
169
+ try {
170
+ child.kill(signal)
171
+ } catch {
172
+ // The bounded close observation handles children that have already exited.
173
+ }
174
+ }
175
+
176
+ function waitForClose(child, durationMs, isClosed) {
177
+ if (isClosed()) return Promise.resolve(true)
178
+ return new Promise((resolve) => {
179
+ let settled = false
180
+ const finish = (closed) => {
181
+ if (settled) return
182
+ settled = true
183
+ clearTimeout(timer)
184
+ child.off('close', onClose)
185
+ child.off('error', onError)
186
+ resolve(closed)
187
+ }
188
+ const onClose = () => finish(true)
189
+ const onError = () => {}
190
+ const timer = setTimeout(() => finish(isClosed()), durationMs)
191
+ child.once('close', onClose)
192
+ child.once('error', onError)
193
+ })
194
+ }
@@ -0,0 +1,87 @@
1
+ export function questionsReady(view: unknown): boolean
2
+ export function parseReply(text: string): Record<string, unknown>
3
+ export function estimateTokens(text: string): number
4
+ export function readPlan(text: string, pageTokens?: number): { offset: number; limit: number }[]
5
+ export function renderGuidance(guidance: unknown): string
6
+ export function renderPackTask(
7
+ packId: string,
8
+ guidance: unknown,
9
+ units: readonly { ref: string; unit: unknown }[],
10
+ ): string
11
+ export function readAnswer(replies: readonly Record<string, unknown>[]): {
12
+ units: Map<string, { summary: string; exclude: string | null }>
13
+ terms: { type: string; value: string; disposition: string; reason: string }[]
14
+ counts: { ignored: number; retyped: number; clipped: number }
15
+ }
16
+ export function main(argv: string[]): Promise<Record<string, unknown>>
17
+
18
+ export function workProgress(view: {
19
+ snapshotId?: string | null
20
+ phase: string
21
+ privacy?: { packageApproval: string | null }
22
+ pendingHideId?: string | null
23
+ works: readonly {
24
+ id: string
25
+ access: string
26
+ rootSessionIds: readonly string[]
27
+ status: string
28
+ emptyReview?: {
29
+ snapshotId: string
30
+ inputRevision: number
31
+ rootSessionIds: readonly string[]
32
+ scanDigest: string
33
+ }
34
+ totalBatches: number
35
+ completedBatches: number
36
+ placement: string
37
+ inputRevision: number
38
+ revision: number
39
+ suggestion?: { checkpoint: string; inputRevision: number } | null
40
+ artifact?: { revision: number } | null
41
+ staticReview?: unknown
42
+ }[]
43
+ }): {
44
+ workId: string
45
+ readingComplete: boolean
46
+ needsPlacement: boolean
47
+ needsDescription: boolean
48
+ needsRender: boolean
49
+ previewReady: boolean
50
+ }[]
51
+
52
+ export interface BlockedWork {
53
+ workId: string
54
+ title: string
55
+ blockedCodes: readonly string[]
56
+ }
57
+ export function blockedWorks(view: {
58
+ works: readonly {
59
+ id: string
60
+ title: string
61
+ access: string
62
+ rootSessionIds: readonly string[]
63
+ status: string
64
+ blockedCodes?: readonly string[]
65
+ }[]
66
+ }): BlockedWork[]
67
+ export function settledNext(
68
+ view: Parameters<typeof blockedWorks>[0] & { readingComplete: boolean },
69
+ units: readonly { state: string }[],
70
+ ): string
71
+
72
+ export function validatePrivacyAnswer(answer: unknown, unitRefs: readonly string[]): void
73
+ export function writePackTask(
74
+ task: string,
75
+ text: string,
76
+ unitRefs: readonly string[],
77
+ sourceBatches?: readonly {
78
+ workId: string
79
+ chunks: readonly {
80
+ text: string
81
+ offset: number
82
+ core: boolean
83
+ fieldId: string
84
+ fieldHash: string
85
+ }[]
86
+ }[],
87
+ ): Promise<string>