@numa-tech/numa 1.20.2 → 1.20.4

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 +13 -1
  2. package/dist/application-onboarding/schemas.d.ts +24 -0
  3. package/dist/application-onboarding/schemas.js +4 -0
  4. package/dist/application-onboarding/schemas.js.map +1 -1
  5. package/dist/application-onboarding/tui-model.d.ts +1 -0
  6. package/dist/application-onboarding/tui-model.js +10 -0
  7. package/dist/application-onboarding/tui-model.js.map +1 -1
  8. package/dist/application-onboarding/tui.js +1 -1
  9. package/dist/application-onboarding/tui.js.map +1 -1
  10. package/dist/authorization/application-client.d.ts +46 -5
  11. package/dist/authorization/application-client.js +21 -4
  12. package/dist/authorization/application-client.js.map +1 -1
  13. package/dist/authorization/application-commands.js +10 -3
  14. package/dist/authorization/application-commands.js.map +1 -1
  15. package/dist/authorization/application-schemas.d.ts +52 -6
  16. package/dist/authorization/application-schemas.js +25 -3
  17. package/dist/authorization/application-schemas.js.map +1 -1
  18. package/dist/business-issuer.js +8 -0
  19. package/dist/business-issuer.js.map +1 -1
  20. package/dist/cli.js +49 -31
  21. package/dist/cli.js.map +1 -1
  22. package/dist/command-catalog.js +9 -0
  23. package/dist/command-catalog.js.map +1 -1
  24. package/dist/kb/catalog.d.ts +2 -0
  25. package/dist/kb/catalog.js +14 -0
  26. package/dist/kb/catalog.js.map +1 -0
  27. package/dist/kb/client.d.ts +46 -0
  28. package/dist/kb/client.js +272 -0
  29. package/dist/kb/client.js.map +1 -0
  30. package/dist/kb/commands.d.ts +14 -0
  31. package/dist/kb/commands.js +121 -0
  32. package/dist/kb/commands.js.map +1 -0
  33. package/dist/kb/config.d.ts +15 -0
  34. package/dist/kb/config.js +76 -0
  35. package/dist/kb/config.js.map +1 -0
  36. package/dist/kb/errors.d.ts +9 -0
  37. package/dist/kb/errors.js +31 -0
  38. package/dist/kb/errors.js.map +1 -0
  39. package/dist/kb/transfers.d.ts +67 -0
  40. package/dist/kb/transfers.js +257 -0
  41. package/dist/kb/transfers.js.map +1 -0
  42. package/dist/kb/types.d.ts +81 -0
  43. package/dist/kb/types.js +2 -0
  44. package/dist/kb/types.js.map +1 -0
  45. package/dist/kb/upload-state.d.ts +20 -0
  46. package/dist/kb/upload-state.js +135 -0
  47. package/dist/kb/upload-state.js.map +1 -0
  48. package/dist/login-recovery.js +15 -1
  49. package/dist/login-recovery.js.map +1 -1
  50. package/dist/maintenance/modules.js +1 -1
  51. package/dist/maintenance/modules.js.map +1 -1
  52. package/dist/mcp/catalog.js +6 -1
  53. package/dist/mcp/catalog.js.map +1 -1
  54. package/dist/oss/file-operations.d.ts +8 -0
  55. package/dist/oss/file-operations.js +48 -6
  56. package/dist/oss/file-operations.js.map +1 -1
  57. package/dist/oss/signed-url-transfers.d.ts +41 -0
  58. package/dist/oss/signed-url-transfers.js +207 -0
  59. package/dist/oss/signed-url-transfers.js.map +1 -0
  60. package/dist/oss/transfer-pool.d.ts +2 -0
  61. package/dist/oss/transfer-pool.js +27 -0
  62. package/dist/oss/transfer-pool.js.map +1 -0
  63. package/dist/oss/transfer-worker.js +8 -17
  64. package/dist/oss/transfer-worker.js.map +1 -1
  65. package/dist/oss/web-page.js +48 -8
  66. package/dist/oss/web-page.js.map +1 -1
  67. package/dist/platform-profile.d.ts +1 -1
  68. package/dist/server.d.ts +2 -0
  69. package/dist/server.js +2 -0
  70. package/dist/server.js.map +1 -1
  71. package/dist/tasks/commands.d.ts +9 -0
  72. package/dist/tasks/commands.js +60 -0
  73. package/dist/tasks/commands.js.map +1 -0
  74. package/dist/tasks/oss-query.d.ts +56 -0
  75. package/dist/tasks/oss-query.js +125 -0
  76. package/dist/tasks/oss-query.js.map +1 -0
  77. package/dist/tasks/runtime.d.ts +151 -0
  78. package/dist/tasks/runtime.js +71 -0
  79. package/dist/tasks/runtime.js.map +1 -0
  80. package/dist/tasks/tools.d.ts +3 -0
  81. package/dist/tasks/tools.js +16 -0
  82. package/dist/tasks/tools.js.map +1 -0
  83. package/dist/tasks/types.d.ts +14 -0
  84. package/dist/tasks/types.js +4 -0
  85. package/dist/tasks/types.js.map +1 -0
  86. package/dist/tasks/wecom-notify.d.ts +26 -0
  87. package/dist/tasks/wecom-notify.js +150 -0
  88. package/dist/tasks/wecom-notify.js.map +1 -0
  89. package/docs/agent-tasks.md +97 -0
  90. package/docs/application-default-groups.md +36 -0
  91. package/docs/design/kb-cli.md +94 -0
  92. package/docs/kb-access.md +85 -0
  93. package/package.json +12 -6
  94. package/scripts/export-kb-contract.py +158 -0
  95. package/skills/numa-ai-registry/SKILL.md +2 -2
  96. package/skills/numa-cli/SKILL.md +24 -9
  97. package/skills/numa-cli/agents/openai.yaml +2 -2
  98. package/skills/numa-cli/evals/evals.json +13 -1
  99. package/skills/numa-cli/numa-skill.json +1 -1
  100. package/skills/numa-cli/references/cli-bootstrap.md +8 -8
  101. package/skills/numa-cli/references/cli-mcp.md +28 -20
  102. package/skills/numa-cli/references/pipeline-release.md +9 -9
  103. package/skills/numa-cli/references/skills-command-contract.md +40 -40
  104. package/skills/numa-cli/references/skills-updates.md +13 -13
  105. package/skills/numa-cli/references/skills-workflows.md +4 -4
  106. package/skills/numa-create-application/SKILL.md +1 -1
  107. package/skills/numa-create-application/numa-skill.json +2 -2
  108. package/skills/numa-create-application/references/cli-bootstrap.md +3 -3
  109. package/skills/numa-create-application/references/numa-cli.md +16 -16
  110. package/skills/numa-jenkins-deployment/SKILL.md +8 -8
  111. package/skills/numa-jenkins-deployment/numa-skill.json +2 -2
  112. package/skills/numa-jenkins-deployment/references/cli-bootstrap.md +3 -3
  113. package/skills/numa-jenkins-deployment/references/cli-contract.md +7 -7
  114. package/skills/numa-jenkins-deployment/references/diagnostics.md +2 -2
  115. package/skills/numa-local-flux-deploy/SKILL.md +1 -1
  116. package/skills/numa-local-flux-deploy/numa-skill.json +2 -2
  117. package/skills/numa-local-flux-deploy/references/cli-bootstrap.md +3 -3
  118. package/skills/numa-nacos/SKILL.md +4 -4
  119. package/skills/numa-nacos/numa-skill.json +2 -2
  120. package/skills/numa-nacos/references/cli-bootstrap.md +3 -3
  121. package/skills/numa-nacos/references/command-contract.md +17 -17
  122. package/skills/numa-notion/SKILL.md +4 -4
  123. package/skills/numa-notion/numa-skill.json +2 -2
  124. package/skills/numa-notion/references/agents-automation.md +2 -2
  125. package/skills/numa-notion/references/cli-bootstrap.md +3 -3
  126. package/skills/numa-notion/references/cli.md +17 -17
  127. package/skills/numa-oss-access/SKILL.md +27 -81
  128. package/skills/numa-oss-access/agents/openai.yaml +2 -2
  129. package/skills/numa-oss-access/evals/evals.json +12 -0
  130. package/skills/numa-oss-access/numa-skill.json +2 -2
  131. package/skills/numa-oss-access/references/cli-bootstrap.md +5 -5
  132. package/skills/numa-oss-access/references/object-operations.md +95 -0
  133. package/skills/numa-oss-access/references/search-and-mcp.md +12 -11
  134. package/skills/numa-wecom/SKILL.md +27 -62
  135. package/skills/numa-wecom/agents/openai.yaml +2 -2
  136. package/skills/numa-wecom/evals/evals.json +25 -0
  137. package/skills/numa-wecom/numa-skill.json +2 -2
  138. package/skills/numa-wecom/references/cli-bootstrap.md +5 -5
  139. package/skills/numa-wecom/references/legacy-operations.md +71 -0
  140. package/skills/numa-wecom/references/machine-auth.md +7 -7
  141. package/skills/numa-wecom/references/mcp.md +9 -8
  142. package/src/kb/openapi-contract.json +1432 -0
@@ -0,0 +1,67 @@
1
+ import type { BeginUploadRequest, DirectUploadSession, UploadSession, DownloadTicket, ProxyUploadRequest, KbTask, TaskKind } from './types.js';
2
+ export interface KbTransferClient {
3
+ readonly binding: string;
4
+ beginUpload(input: BeginUploadRequest): Promise<UploadSession>;
5
+ getUpload(sessionId: string, renew?: boolean): Promise<DirectUploadSession>;
6
+ completeUpload(sessionId: string): Promise<DirectUploadSession>;
7
+ proxyUpload(input: ProxyUploadRequest): Promise<KbTask>;
8
+ downloadTicket(documentId: string): Promise<DownloadTicket>;
9
+ downloadProxy(ticket: DownloadTicket, signal?: AbortSignal): Promise<Response>;
10
+ getTask(taskId: string, kind?: TaskKind): Promise<KbTask>;
11
+ }
12
+ export interface TransferProgress {
13
+ phase: string;
14
+ filename?: string;
15
+ transferred?: number;
16
+ total?: number;
17
+ taskId?: string;
18
+ status?: string;
19
+ }
20
+ export interface UploadInput {
21
+ path: string;
22
+ collectionId: string;
23
+ stateFile?: string;
24
+ resume?: boolean;
25
+ batchSize?: number;
26
+ concurrency?: number;
27
+ wait?: boolean;
28
+ timeoutMs?: number;
29
+ signal?: AbortSignal;
30
+ onProgress?: (progress: TransferProgress) => void;
31
+ }
32
+ export interface TransferDependencies {
33
+ fetchImpl?: typeof fetch;
34
+ stateRoot?: string;
35
+ pollIntervalMs?: number;
36
+ transferTimeoutMs?: number;
37
+ }
38
+ export declare function uploadToKb(client: KbTransferClient, input: UploadInput, deps?: TransferDependencies): Promise<{
39
+ state_file: string;
40
+ collection_id: string;
41
+ files: number;
42
+ batches: {
43
+ batch_id: string;
44
+ kind: TaskKind;
45
+ status: string;
46
+ }[];
47
+ tasks?: KbTask[];
48
+ }>;
49
+ export interface WaitOptions {
50
+ kind?: TaskKind;
51
+ timeoutMs?: number;
52
+ signal?: AbortSignal;
53
+ pollIntervalMs?: number;
54
+ onProgress?: (progress: TransferProgress) => void;
55
+ }
56
+ export declare function waitForTask(client: Pick<KbTransferClient, 'getTask'>, taskId: string, options?: WaitOptions): Promise<KbTask>;
57
+ export declare function downloadFromKb(client: Pick<KbTransferClient, 'downloadTicket' | 'downloadProxy'>, input: {
58
+ documentId: string;
59
+ output: string;
60
+ signal?: AbortSignal;
61
+ onProgress?: (progress: TransferProgress) => void;
62
+ }, deps?: TransferDependencies): Promise<{
63
+ output: string;
64
+ size_bytes: number;
65
+ sha256: string;
66
+ document_id: string;
67
+ }>;
@@ -0,0 +1,257 @@
1
+ import { lstat, readdir } from 'node:fs/promises';
2
+ import { basename, join, relative, resolve, isAbsolute } from 'node:path';
3
+ import { homedir } from 'node:os';
4
+ import { createHash, randomUUID } from 'node:crypto';
5
+ import { setTimeout as delay } from 'node:timers/promises';
6
+ import { runTransferPool } from '../oss/transfer-pool.js';
7
+ import { digestFile, putSignedFile, downloadSignedFile, rejectSymlinks, SignedTransferError } from '../oss/signed-url-transfers.js';
8
+ import { KbError } from './errors.js';
9
+ import { lockUploadState, readUploadState, writeUploadState } from './upload-state.js';
10
+ const fail = (message, code = 'kb_input_invalid', details) => new KbError(message, code, undefined, details);
11
+ async function scan(path, signal) {
12
+ const paths = [];
13
+ async function walk(current) {
14
+ signal?.throwIfAborted();
15
+ await rejectSymlinks(current);
16
+ const stat = await lstat(current);
17
+ if (stat.isDirectory()) {
18
+ for (const name of (await readdir(current)).sort())
19
+ await walk(join(current, name));
20
+ }
21
+ else if (stat.isFile())
22
+ paths.push(current);
23
+ else
24
+ throw fail('Only regular files and directories are accepted.');
25
+ }
26
+ await walk(resolve(path));
27
+ if (!paths.length)
28
+ throw fail('Upload directory has no files.');
29
+ const names = new Set(), result = [];
30
+ for (const path of paths.sort()) {
31
+ const filename = basename(path);
32
+ if (filename.length > 255 || /[\u0000-\u001f\u007f]/u.test(filename))
33
+ throw fail('Upload filename is invalid.');
34
+ if (names.has(filename))
35
+ throw fail('Upload contains duplicate filenames; use separate uploads for each directory.');
36
+ names.add(filename);
37
+ result.push({ ...await digestFile(path, signal), filename, content_type: 'application/octet-stream' });
38
+ }
39
+ return result;
40
+ }
41
+ function batches(files, batchSize) {
42
+ const result = [];
43
+ let indexes = [], bytes = 0;
44
+ function flush() { if (indexes.length)
45
+ result.push({ requestId: `numa-kb-${randomUUID()}`, fileIndexes: indexes }); indexes = []; bytes = 0; }
46
+ files.forEach((file, index) => { if (indexes.length >= batchSize || bytes + file.size_bytes > 1024 ** 3)
47
+ flush(); indexes.push(index); bytes += file.size_bytes; });
48
+ flush();
49
+ return result;
50
+ }
51
+ function verifySession(session, batch, state) {
52
+ if (session.collection_id !== state.collectionId || session.request_id !== batch.requestId || (batch.sessionId && session.session_id !== batch.sessionId) || (batch.batchId && session.batch_id !== batch.batchId) || session.files.length !== batch.fileIndexes.length)
53
+ throw fail('Upload session does not match the saved request.', 'kb_protocol_error');
54
+ const filenames = new Set();
55
+ for (const remote of session.files) {
56
+ const local = batch.fileIndexes.map(index => state.files[index]).find(file => file.filename === remote.filename);
57
+ if (!local || filenames.has(remote.filename) || remote.size_bytes !== local.size_bytes || remote.sha256 !== local.sha256 || remote.content_md5 !== local.content_md5 || remote.content_type !== local.content_type)
58
+ throw fail('Upload session content does not match the local manifest.', 'kb_protocol_error');
59
+ filenames.add(remote.filename);
60
+ }
61
+ if (session.status !== 'uploading' && session.status !== 'submitted')
62
+ throw fail('Upload session has expired or was cancelled; start a new upload with a new state file.', 'kb_session_unavailable');
63
+ }
64
+ export async function uploadToKb(client, input, deps = {}) {
65
+ const sourcePath = resolve(input.path), batchSize = input.batchSize ?? 50, concurrency = input.concurrency ?? 3;
66
+ if (!input.collectionId.trim() || !Number.isInteger(batchSize) || batchSize < 1 || batchSize > 50 || !Number.isInteger(concurrency) || concurrency < 1 || concurrency > 32)
67
+ throw fail('Batch size must be 1–50 and concurrency 1–32.');
68
+ const key = createHash('sha256').update(JSON.stringify([client.binding, input.collectionId, sourcePath])).digest('hex');
69
+ const stateFile = resolve(input.stateFile ?? join(deps.stateRoot ?? join(homedir(), '.numa', 'kb', 'uploads'), `${key}.json`));
70
+ const child = relative(sourcePath, stateFile);
71
+ if (!child || (!child.startsWith('..') && !isAbsolute(child)))
72
+ throw fail('Upload state must be outside the uploaded source path.');
73
+ const release = await lockUploadState(stateFile);
74
+ try {
75
+ input.signal?.throwIfAborted();
76
+ input.onProgress?.({ phase: 'scanning' });
77
+ const files = await scan(sourcePath, input.signal);
78
+ let state;
79
+ if (input.resume) {
80
+ state = await readUploadState(stateFile);
81
+ if (state.binding !== client.binding || state.collectionId !== input.collectionId || state.sourcePath !== sourcePath)
82
+ throw fail('Saved upload belongs to a different KB target or identity.', 'kb_state_binding_mismatch');
83
+ if (state.files.length !== files.length || state.files.some((saved, index) => { const current = files[index]; return saved.path !== current.path || saved.filename !== current.filename || saved.size_bytes !== current.size_bytes || saved.sha256 !== current.sha256 || saved.content_md5 !== current.content_md5 || saved.content_type !== current.content_type; }))
84
+ throw fail('Upload source differs from the saved manifest.', 'kb_source_changed');
85
+ if (state.batches.some(batch => batch.fileIndexes.reduce((sum, index) => sum + files[index].size_bytes, 0) > 1024 ** 3))
86
+ throw fail('Saved upload batch exceeds the size limit.', 'kb_state_invalid');
87
+ }
88
+ else {
89
+ try {
90
+ await lstat(stateFile);
91
+ throw fail('Upload state already exists; use --resume or choose a new --state-file.', 'kb_state_exists');
92
+ }
93
+ catch (error) {
94
+ if (error.code !== 'ENOENT')
95
+ throw error;
96
+ }
97
+ state = { version: 1, binding: client.binding, collectionId: input.collectionId, sourcePath, files, batches: batches(files, batchSize) };
98
+ await writeUploadState(stateFile, state);
99
+ }
100
+ for (const batch of state.batches) {
101
+ input.signal?.throwIfAborted();
102
+ if (batch.submitted)
103
+ continue;
104
+ const locals = batch.fileIndexes.map(index => state.files[index]);
105
+ let session = batch.sessionId ? await client.getUpload(batch.sessionId, true) : batch.transport === 'proxy' ? { transport: 'proxy' } : await client.beginUpload({ collection_id: state.collectionId, request_id: batch.requestId, files: locals.map(({ path: _path, ...metadata }) => metadata) });
106
+ input.signal?.throwIfAborted();
107
+ if (session.transport === 'proxy') {
108
+ batch.transport = 'proxy';
109
+ await writeUploadState(stateFile, state);
110
+ // Verify immediately before handing files to the multipart adapter.
111
+ for (const file of locals)
112
+ if ((await digestFile(file.path, input.signal)).sha256 !== file.sha256)
113
+ throw fail('Upload source changed.', 'kb_source_changed');
114
+ const task = await client.proxyUpload({ collectionId: state.collectionId, requestId: batch.requestId, files: locals.map(file => ({ path: file.path, filename: file.filename })), signal: input.signal });
115
+ batch.batchId = task.batch_id;
116
+ batch.submitted = true;
117
+ await writeUploadState(stateFile, state);
118
+ for (const file of locals)
119
+ if ((await digestFile(file.path, input.signal)).sha256 !== file.sha256)
120
+ throw fail('Upload source changed during proxy upload.', 'kb_source_changed');
121
+ continue;
122
+ }
123
+ verifySession(session, batch, state);
124
+ batch.transport = 'direct';
125
+ batch.sessionId = session.session_id;
126
+ batch.batchId = session.batch_id;
127
+ await writeUploadState(stateFile, state);
128
+ if (session.status !== 'submitted') {
129
+ const current = session;
130
+ await runTransferPool(current.files, concurrency, async (remote) => {
131
+ const local = locals.find(file => file.filename === remote.filename);
132
+ if (remote.object_uploaded) {
133
+ input.onProgress?.({ phase: 'uploaded', filename: local.filename, transferred: local.size_bytes, total: local.size_bytes });
134
+ return;
135
+ }
136
+ if (!remote.upload)
137
+ throw fail('Upload ticket is missing.', 'kb_protocol_error');
138
+ try {
139
+ await putSignedFile(remote.upload, local, { signal: input.signal, fetchImpl: deps.fetchImpl, timeoutMs: deps.transferTimeoutMs, onProgress: (transferred, total) => input.onProgress?.({ phase: 'uploading', filename: local.filename, transferred, total: total ?? undefined }) });
140
+ }
141
+ catch (error) {
142
+ if (input.signal?.aborted || (error instanceof SignedTransferError && error.code !== 'kb_transfer_failed'))
143
+ throw error;
144
+ // A PUT response may be lost after the object was stored. Read before retrying.
145
+ const renewed = await client.getUpload(current.session_id, true);
146
+ verifySession(renewed, batch, state);
147
+ const item = renewed.files.find(file => file.file_id === remote.file_id);
148
+ if (item?.object_uploaded || renewed.status === 'submitted')
149
+ return;
150
+ if (!item?.upload)
151
+ throw error;
152
+ await putSignedFile(item.upload, local, { signal: input.signal, fetchImpl: deps.fetchImpl, timeoutMs: deps.transferTimeoutMs });
153
+ }
154
+ }, input.signal);
155
+ // Covers skipped objects and changes between hashing and upload completion.
156
+ for (const file of locals)
157
+ if ((await digestFile(file.path, input.signal)).sha256 !== file.sha256)
158
+ throw fail('Upload source changed.', 'kb_source_changed');
159
+ input.signal?.throwIfAborted();
160
+ session = await client.completeUpload(current.session_id);
161
+ verifySession(session, batch, state);
162
+ if (session.status !== 'submitted')
163
+ throw fail('Upload completion did not submit a task.', 'kb_protocol_error');
164
+ }
165
+ batch.submitted = true;
166
+ await writeUploadState(stateFile, state);
167
+ }
168
+ const submitted = state.batches.map(batch => ({ batch_id: batch.batchId, kind: (batch.transport === 'proxy' ? 'batch' : 'archive'), status: 'submitted' }));
169
+ const tasks = [];
170
+ const waitDeadline = Date.now() + (input.timeoutMs ?? 10 * 60_000);
171
+ if (input.wait)
172
+ for (const batch of submitted) {
173
+ const remaining = waitDeadline - Date.now();
174
+ if (remaining <= 0)
175
+ throw fail('Timed out waiting for KB tasks; query the saved task IDs.', 'kb_task_timeout', { batches: submitted });
176
+ tasks.push(await waitForTask(client, batch.batch_id, { kind: batch.kind, timeoutMs: remaining, signal: input.signal, onProgress: input.onProgress, pollIntervalMs: deps.pollIntervalMs }));
177
+ }
178
+ return { state_file: stateFile, collection_id: state.collectionId, files: state.files.length, batches: submitted, ...(input.wait ? { tasks } : {}) };
179
+ }
180
+ catch (error) {
181
+ if (input.signal?.aborted)
182
+ throw fail('Upload interrupted; submission may have completed. Resume with the saved state to reconcile it.', 'kb_aborted', { state_file: stateFile });
183
+ if (error instanceof KbError)
184
+ throw new KbError(error.message, error.code, error.status, { ...error.details, state_file: stateFile });
185
+ if (error instanceof SignedTransferError)
186
+ throw fail(error.message, error.code, { state_file: stateFile });
187
+ throw fail('Upload interrupted; resume with the saved state.', 'kb_transfer_failed', { state_file: stateFile });
188
+ }
189
+ finally {
190
+ await release();
191
+ }
192
+ }
193
+ export async function waitForTask(client, taskId, options = {}) {
194
+ const timeoutMs = options.timeoutMs ?? 10 * 60_000, interval = options.pollIntervalMs ?? 1000;
195
+ if (!Number.isFinite(timeoutMs) || timeoutMs <= 0 || !Number.isFinite(interval) || interval < 1)
196
+ throw fail('Task timeout and polling interval must be positive.');
197
+ const deadline = Date.now() + timeoutMs;
198
+ while (true) {
199
+ if (options.signal?.aborted)
200
+ throw fail('Task wait interrupted.', 'kb_aborted', { task_id: taskId });
201
+ const remaining = deadline - Date.now();
202
+ if (remaining <= 0)
203
+ throw fail('Timed out waiting for KB task; query the task again.', 'kb_task_timeout', { task_id: taskId, kind: options.kind ?? 'archive' });
204
+ // The control client has its own HTTP deadline; race bounds even injected/hung clients.
205
+ let timer;
206
+ let removeAbort;
207
+ const timeout = new Promise((_, reject) => { timer = setTimeout(() => reject(fail('Timed out waiting for KB task; query the task again.', 'kb_task_timeout', { task_id: taskId })), remaining); });
208
+ const abort = new Promise((_, reject) => { const handler = () => reject(fail('Task wait interrupted.', 'kb_aborted', { task_id: taskId })); options.signal?.addEventListener('abort', handler, { once: true }); removeAbort = () => options.signal?.removeEventListener('abort', handler); });
209
+ let task;
210
+ try {
211
+ task = await Promise.race([client.getTask(taskId, options.kind), timeout, abort]);
212
+ }
213
+ finally {
214
+ if (timer)
215
+ clearTimeout(timer);
216
+ removeAbort?.();
217
+ }
218
+ const raw = typeof task.task_status === 'string' ? task.task_status : task.status;
219
+ const fileStates = task.files?.map(file => String(file.status));
220
+ const active = Number(task.pending_count ?? 0) > 0 || Number(task.processing_count ?? 0) > 0 || fileStates?.some(status => ['pending', 'processing'].includes(status));
221
+ const blocked = raw === 'needs_resolution' || (!active && fileStates?.some(status => status === 'needs_resolution'));
222
+ const cancelled = raw === 'cancelled' || (!active && fileStates?.length && fileStates.some(status => status === 'cancelled'));
223
+ options.onProgress?.({ phase: 'waiting', taskId, status: raw });
224
+ if (blocked)
225
+ throw fail('KB task needs conflict resolution.', 'kb_task_needs_resolution', { task_id: taskId, task });
226
+ if (cancelled || raw === 'failed' || (raw === 'partial_failed' && !active) || (['completed', 'archived'].includes(raw) && Number(task.failed_count ?? 0) > 0))
227
+ throw fail('KB task did not complete successfully.', 'kb_task_failed', { task_id: taskId, task });
228
+ if (['completed', 'archived'].includes(raw))
229
+ return task;
230
+ try {
231
+ await delay(Math.min(interval, Math.max(1, deadline - Date.now())), undefined, { signal: options.signal });
232
+ }
233
+ catch (error) {
234
+ if (options.signal?.aborted)
235
+ throw fail('Task wait interrupted.', 'kb_aborted', { task_id: taskId });
236
+ throw error;
237
+ }
238
+ }
239
+ }
240
+ export async function downloadFromKb(client, input, deps = {}) {
241
+ try {
242
+ input.signal?.throwIfAborted();
243
+ const ticket = await client.downloadTicket(input.documentId);
244
+ const result = await downloadSignedFile(ticket, input.output, { signal: input.signal, fetchImpl: deps.fetchImpl, timeoutMs: deps.transferTimeoutMs, response: ticket.transport === 'proxy' ? signal => client.downloadProxy(ticket, signal) : undefined, onProgress: (transferred, total) => input.onProgress?.({ phase: 'downloading', filename: ticket.filename, transferred, total: total ?? undefined }) });
245
+ return { document_id: input.documentId, ...result };
246
+ }
247
+ catch (error) {
248
+ if (input.signal?.aborted)
249
+ throw fail('Download interrupted.', 'kb_aborted');
250
+ if (error instanceof KbError)
251
+ throw error;
252
+ if (error instanceof SignedTransferError)
253
+ throw fail(error.message, error.code);
254
+ throw fail('Download failed.', 'kb_transfer_failed');
255
+ }
256
+ }
257
+ //# sourceMappingURL=transfers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transfers.js","sourceRoot":"","sources":["../../src/kb/transfers.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,81 @@
1
+ export interface UploadMetadata {
2
+ filename: string;
3
+ size_bytes: number;
4
+ sha256: string;
5
+ content_md5: string;
6
+ content_type?: string;
7
+ duplicate_action?: "" | "upload" | "new_version";
8
+ existing_document_id?: string | null;
9
+ version_reason?: string | null;
10
+ version_confirmation?: "SWITCH_CURRENT_VERSION" | null;
11
+ }
12
+ export interface UploadTicket {
13
+ method: "PUT";
14
+ url: string;
15
+ headers: Record<string, string>;
16
+ expires_at: string;
17
+ }
18
+ export interface UploadSessionFile extends UploadMetadata {
19
+ file_id: string;
20
+ content_type: string;
21
+ object_uploaded?: boolean;
22
+ upload?: UploadTicket | null;
23
+ }
24
+ export interface KbTask extends Record<string, unknown> {
25
+ batch_id: string;
26
+ status: string;
27
+ task_status?: string;
28
+ archive_id?: string;
29
+ collection_id?: string;
30
+ total_count?: number;
31
+ completed_count?: number;
32
+ failed_count?: number;
33
+ reused_count?: number;
34
+ skipped_count?: number;
35
+ needs_resolution_count?: number;
36
+ pending_count?: number;
37
+ processing_count?: number;
38
+ files?: Record<string, unknown>[];
39
+ }
40
+ export interface DirectUploadSession {
41
+ transport: "direct";
42
+ session_id: string;
43
+ batch_id: string;
44
+ collection_id: string;
45
+ request_id: string;
46
+ status: "uploading" | "submitted" | "cancelled" | "expired";
47
+ expires_at: string;
48
+ files: UploadSessionFile[];
49
+ batch?: KbTask;
50
+ }
51
+ export type UploadSession = DirectUploadSession | {
52
+ transport: "proxy";
53
+ };
54
+ export interface DownloadTicket {
55
+ transport: "oss" | "proxy";
56
+ method: "GET";
57
+ url: string;
58
+ headers: Record<string, string>;
59
+ expires_at: string | null;
60
+ filename: string;
61
+ size_bytes: number | null;
62
+ sha256: string | null;
63
+ content_type: string;
64
+ requires_api_key?: boolean;
65
+ }
66
+ export interface BeginUploadRequest {
67
+ collection_id: string;
68
+ request_id: string;
69
+ files: UploadMetadata[];
70
+ options?: Record<string, unknown>;
71
+ }
72
+ export interface ProxyUploadRequest {
73
+ collectionId: string;
74
+ requestId: string;
75
+ files: {
76
+ path: string;
77
+ filename: string;
78
+ }[];
79
+ signal?: AbortSignal;
80
+ }
81
+ export type TaskKind = "archive" | "batch";
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/kb/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,20 @@
1
+ import { type FileDigest } from '../oss/signed-url-transfers.js';
2
+ export interface UploadBatchState {
3
+ requestId: string;
4
+ fileIndexes: number[];
5
+ sessionId?: string;
6
+ batchId?: string;
7
+ transport?: 'direct' | 'proxy';
8
+ submitted?: boolean;
9
+ }
10
+ export interface UploadState {
11
+ version: 1;
12
+ binding: string;
13
+ collectionId: string;
14
+ sourcePath: string;
15
+ files: FileDigest[];
16
+ batches: UploadBatchState[];
17
+ }
18
+ export declare function lockUploadState(path: string): Promise<() => Promise<void>>;
19
+ export declare function readUploadState(path: string): Promise<UploadState>;
20
+ export declare function writeUploadState(path: string, state: UploadState): Promise<void>;
@@ -0,0 +1,135 @@
1
+ import { constants } from 'node:fs';
2
+ import { open, lstat, mkdir, rename, unlink, chmod } from 'node:fs/promises';
3
+ import { dirname, resolve } from 'node:path';
4
+ import { randomUUID } from 'node:crypto';
5
+ import { rejectSymlinks } from '../oss/signed-url-transfers.js';
6
+ import { KbError } from './errors.js';
7
+ const fail = (message, code = 'kb_state_invalid') => new KbError(message, code);
8
+ export async function lockUploadState(path) {
9
+ path = resolve(path);
10
+ await mkdir(dirname(path), { recursive: true, mode: 0o700 });
11
+ await rejectSymlinks(dirname(path));
12
+ await rejectSymlinks(path, true);
13
+ const lock = `${path}.lock`;
14
+ let handle;
15
+ for (let attempt = 0; attempt < 2; attempt++) {
16
+ try {
17
+ handle = await open(lock, constants.O_WRONLY | constants.O_CREAT | constants.O_EXCL | constants.O_NOFOLLOW, 0o600);
18
+ break;
19
+ }
20
+ catch (error) {
21
+ if (error.code !== 'EEXIST')
22
+ throw error;
23
+ const recoveryPath = `${lock}.recovery`;
24
+ const recovery = await open(recoveryPath, 'wx', 0o600).catch(() => { throw fail('Upload state recovery is active or was interrupted; inspect its recovery lock.', 'kb_state_locked'); });
25
+ try {
26
+ const existing = await open(lock, constants.O_RDONLY | constants.O_NOFOLLOW);
27
+ try {
28
+ const stat = await existing.stat();
29
+ if (!stat.isFile() || stat.size > 1024)
30
+ throw fail('Upload state is locked.', 'kb_state_locked');
31
+ const owner = JSON.parse(await existing.readFile('utf8'));
32
+ if (!Number.isSafeInteger(owner.pid) || owner.pid < 1)
33
+ throw fail('Upload state is locked.', 'kb_state_locked');
34
+ try {
35
+ process.kill(owner.pid, 0);
36
+ throw fail('Upload state is in use by another process.', 'kb_state_locked');
37
+ }
38
+ catch (probe) {
39
+ if (probe.code !== 'ESRCH')
40
+ throw probe;
41
+ }
42
+ const named = await lstat(lock);
43
+ if (named.ino !== stat.ino || named.dev !== stat.dev)
44
+ throw fail('Upload state is locked.', 'kb_state_locked');
45
+ await unlink(lock);
46
+ }
47
+ catch (error) {
48
+ if (error instanceof KbError)
49
+ throw error;
50
+ throw fail('Upload state is locked.', 'kb_state_locked');
51
+ }
52
+ finally {
53
+ await existing.close();
54
+ }
55
+ handle = await open(lock, constants.O_WRONLY | constants.O_CREAT | constants.O_EXCL | constants.O_NOFOLLOW, 0o600);
56
+ break;
57
+ }
58
+ finally {
59
+ await recovery.close();
60
+ await unlink(recoveryPath).catch(() => undefined);
61
+ }
62
+ }
63
+ }
64
+ if (!handle)
65
+ throw fail('Upload state is locked.', 'kb_state_locked');
66
+ const identity = await handle.stat();
67
+ await handle.writeFile(JSON.stringify({ pid: process.pid, id: randomUUID() }));
68
+ await handle.sync();
69
+ await handle.close();
70
+ return async () => {
71
+ const current = await lstat(lock).catch(() => undefined);
72
+ if (current?.ino === identity.ino && current.dev === identity.dev)
73
+ await unlink(lock);
74
+ };
75
+ }
76
+ export async function readUploadState(path) {
77
+ await rejectSymlinks(path);
78
+ const file = await open(path, constants.O_RDONLY | constants.O_NOFOLLOW);
79
+ try {
80
+ const stat = await file.stat();
81
+ if (!stat.isFile() || stat.size > 64 * 1024 ** 2 || (process.platform !== 'win32' && (stat.mode & 0o077) !== 0))
82
+ throw fail('Upload state must be a private regular file.');
83
+ const state = JSON.parse(await file.readFile('utf8'));
84
+ if (state.version !== 1 || typeof state.binding !== 'string' || typeof state.collectionId !== 'string' || typeof state.sourcePath !== 'string' || !Array.isArray(state.files) || !Array.isArray(state.batches) || !state.batches.length)
85
+ throw fail('Invalid upload state.');
86
+ const indexes = [];
87
+ for (const batch of state.batches) {
88
+ if (!batch || typeof batch.requestId !== 'string' || !/^[\w-]{1,200}$/u.test(batch.requestId) || !Array.isArray(batch.fileIndexes) || !batch.fileIndexes.length || batch.fileIndexes.length > 50 || (batch.transport !== undefined && !['direct', 'proxy'].includes(batch.transport)) || (batch.sessionId !== undefined && typeof batch.sessionId !== 'string') || (batch.batchId !== undefined && typeof batch.batchId !== 'string') || (batch.submitted !== undefined && typeof batch.submitted !== 'boolean') || (batch.submitted && !batch.batchId))
89
+ throw fail('Invalid upload batch state.');
90
+ indexes.push(...batch.fileIndexes);
91
+ }
92
+ if (indexes.length !== state.files.length || indexes.some((value, index) => value !== index) || new Set(state.batches.map(batch => batch.requestId)).size !== state.batches.length)
93
+ throw fail('Invalid upload file mapping.');
94
+ return state;
95
+ }
96
+ catch (error) {
97
+ if (error instanceof KbError)
98
+ throw error;
99
+ throw fail('Cannot read upload state.');
100
+ }
101
+ finally {
102
+ await file.close();
103
+ }
104
+ }
105
+ export async function writeUploadState(path, state) {
106
+ await rejectSymlinks(path, true);
107
+ const temp = `${path}.${randomUUID()}.tmp`;
108
+ const file = await open(temp, constants.O_WRONLY | constants.O_CREAT | constants.O_EXCL | constants.O_NOFOLLOW, 0o600);
109
+ try {
110
+ // Explicit allowlist keeps remote capabilities and credentials out of the manifest.
111
+ const safe = { version: 1, binding: state.binding, collectionId: state.collectionId, sourcePath: state.sourcePath,
112
+ files: state.files.map(({ path, filename, size_bytes, sha256, content_md5, content_type }) => ({ path, filename, size_bytes, sha256, content_md5, content_type })),
113
+ batches: state.batches.map(({ requestId, fileIndexes, sessionId, batchId, transport, submitted }) => ({ requestId, fileIndexes, sessionId, batchId, transport, submitted })) };
114
+ await file.writeFile(`${JSON.stringify(safe, null, 2)}\n`);
115
+ await file.sync();
116
+ await rename(temp, path);
117
+ await chmod(path, 0o600);
118
+ const directory = await open(dirname(path), constants.O_RDONLY);
119
+ try {
120
+ await directory.sync();
121
+ }
122
+ catch (error) {
123
+ if (process.platform !== 'win32')
124
+ throw error;
125
+ }
126
+ finally {
127
+ await directory.close();
128
+ }
129
+ }
130
+ finally {
131
+ await file.close();
132
+ await unlink(temp).catch(() => undefined);
133
+ }
134
+ }
135
+ //# sourceMappingURL=upload-state.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"upload-state.js","sourceRoot":"","sources":["../../src/kb/upload-state.ts"],"names":[],"mappings":"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"}