@superdoc/sdk 2.5.0 → 2.7.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 (55) hide show
  1. package/dist/agent/actions.cjs +1869 -160
  2. package/dist/agent/actions.d.ts +77 -10
  3. package/dist/agent/actions.js +1870 -161
  4. package/dist/agent/catalog.cjs +102 -9
  5. package/dist/agent/catalog.d.ts +243 -0
  6. package/dist/agent/catalog.js +99 -9
  7. package/dist/agent/doc-snapshot.cjs +200 -2
  8. package/dist/agent/doc-snapshot.d.ts +91 -0
  9. package/dist/agent/doc-snapshot.js +199 -2
  10. package/dist/agent/runtime.cjs +9 -1
  11. package/dist/agent/runtime.d.ts +8 -0
  12. package/dist/agent/runtime.js +9 -1
  13. package/dist/embedded-tools.generated.cjs +5 -5
  14. package/dist/embedded-tools.generated.js +5 -5
  15. package/dist/generated/client.cjs +754 -770
  16. package/dist/generated/client.d.ts +14 -9
  17. package/dist/generated/client.js +754 -770
  18. package/dist/generated/contract.cjs +16207 -274
  19. package/dist/generated/contract.d.ts +38 -0
  20. package/dist/generated/contract.js +17443 -1503
  21. package/dist/index.cjs +5 -4
  22. package/dist/index.d.ts +2 -2
  23. package/dist/index.js +5 -4
  24. package/dist/introspection.cjs +59 -0
  25. package/dist/introspection.d.ts +3 -0
  26. package/dist/introspection.js +53 -0
  27. package/dist/runtime/document-rpc.cjs +328 -0
  28. package/dist/runtime/document-rpc.d.ts +24 -0
  29. package/dist/runtime/document-rpc.js +312 -0
  30. package/dist/runtime/embedded-cli.cjs +5 -68
  31. package/dist/runtime/embedded-cli.js +5 -67
  32. package/dist/runtime/embedded-document-host.cjs +28 -0
  33. package/dist/runtime/embedded-document-host.d.ts +1 -0
  34. package/dist/runtime/embedded-document-host.js +23 -0
  35. package/dist/runtime/embedded-platform.cjs +102 -0
  36. package/dist/runtime/embedded-platform.d.ts +5 -0
  37. package/dist/runtime/embedded-platform.js +93 -0
  38. package/dist/runtime/host.cjs +128 -16
  39. package/dist/runtime/host.d.ts +11 -5
  40. package/dist/runtime/host.js +126 -16
  41. package/dist/runtime/process.cjs +34 -5
  42. package/dist/runtime/process.d.ts +12 -3
  43. package/dist/runtime/process.js +33 -5
  44. package/dist/runtime/transport-common.cjs +1 -0
  45. package/dist/runtime/transport-common.d.ts +28 -10
  46. package/dist/runtime/transport-common.js +1 -1
  47. package/package.json +7 -6
  48. package/tools/__pycache__/__init__.cpython-311.pyc +0 -0
  49. package/tools/__pycache__/intent_dispatch_generated.cpython-311.pyc +0 -0
  50. package/tools/catalog.json +2 -2
  51. package/tools/tools-policy.json +1 -1
  52. package/tools/tools.anthropic.json +2 -2
  53. package/tools/tools.generic.json +2 -2
  54. package/tools/tools.openai.json +2 -2
  55. package/tools/tools.vercel.json +2 -2
@@ -0,0 +1,312 @@
1
+ import { randomUUID } from 'node:crypto';
2
+ import { SuperDocCliError } from './errors.js';
3
+ import { applyOperationParamAliases, } from './transport-common.js';
4
+ export const DOCUMENT_RPC_FEATURES = ['document.open', 'document.invoke', 'document.save', 'document.close'];
5
+ export const DOCUMENT_RPC_DEFAULT_CHANGE_MODE_FEATURE = 'document.open.defaultChangeMode';
6
+ export const DOCUMENT_RPC_SOURCE_SAVE_FEATURE = 'document.save.source';
7
+ export const DOCUMENT_RPC_REQUEST_TIMEOUT_FEATURE = 'host.request.timeoutMs';
8
+ const DOCUMENT_RPC_OPEN_FIELDS = new Set(['doc', 'sessionId', 'runtime']);
9
+ const DOCUMENT_RPC_SAVE_FIELDS = new Set(['sessionId', 'out', 'force', 'mode', 'inPlace']);
10
+ const DOCUMENT_API_OPTION_FIELDS = new Set(['expectedRevision', 'changeMode', 'dryRun', 'supportCheck']);
11
+ const DOCUMENT_API_REVISION_PREFLIGHT_OPERATIONS = new Set([
12
+ 'doc.history.redo',
13
+ 'doc.history.undo',
14
+ 'doc.plan.execute',
15
+ ]);
16
+ function unsupported(message, operationId) {
17
+ return new SuperDocCliError(message, {
18
+ code: 'DOCUMENT_RPC_INPUT_UNSUPPORTED',
19
+ ...(operationId === undefined ? {} : { details: { operationId } }),
20
+ });
21
+ }
22
+ function buildDocumentAuthor(user) {
23
+ if (user === undefined)
24
+ return undefined;
25
+ if (typeof user !== 'object' || user === null || Array.isArray(user)) {
26
+ throw new SuperDocCliError('user must be an object with a non-empty name.', {
27
+ code: 'INVALID_ARGUMENT',
28
+ });
29
+ }
30
+ const record = user;
31
+ if (typeof record.name !== 'string' || record.name.trim().length === 0) {
32
+ throw new SuperDocCliError('user.name must be a non-empty string.', {
33
+ code: 'INVALID_ARGUMENT',
34
+ });
35
+ }
36
+ if (record.email !== undefined && typeof record.email !== 'string') {
37
+ throw new SuperDocCliError('user.email must be a string.', {
38
+ code: 'INVALID_ARGUMENT',
39
+ });
40
+ }
41
+ return {
42
+ name: record.name,
43
+ ...(record.email === undefined ? {} : { email: record.email }),
44
+ };
45
+ }
46
+ export function documentRpcEnabled(env) {
47
+ return (env?.SUPERDOC_SDK_DOCUMENT_RPC ?? process.env.SUPERDOC_SDK_DOCUMENT_RPC) === '1';
48
+ }
49
+ export function supportsDocumentRpc(features) {
50
+ return DOCUMENT_RPC_FEATURES.every((feature) => features.has(feature));
51
+ }
52
+ export function canOpenWithDocumentRpc(params, options) {
53
+ if (options.stdinBytes !== undefined)
54
+ return false;
55
+ if (options.dryRun !== undefined || options.expectedRevision !== undefined || options.changeMode !== undefined) {
56
+ return false;
57
+ }
58
+ if (typeof params.doc !== 'string' || params.doc.trim().length === 0 || params.doc === '-')
59
+ return false;
60
+ if (params.runtime !== undefined && params.runtime !== 'v2')
61
+ return false;
62
+ if (params.sessionId !== undefined && (typeof params.sessionId !== 'string' || params.sessionId.length === 0)) {
63
+ return false;
64
+ }
65
+ return Object.entries(params).every(([key, value]) => value === undefined || DOCUMENT_RPC_OPEN_FIELDS.has(key));
66
+ }
67
+ export function buildDocumentOpenParams(params, user, defaultChangeMode) {
68
+ const sessionId = typeof params.sessionId === 'string' && params.sessionId.length > 0 ? params.sessionId : randomUUID();
69
+ const author = buildDocumentAuthor(user);
70
+ return {
71
+ sessionId,
72
+ params: {
73
+ sessionId,
74
+ path: params.doc,
75
+ ...(author === undefined ? {} : { author }),
76
+ ...(defaultChangeMode == null ? {} : { defaultChangeMode }),
77
+ },
78
+ };
79
+ }
80
+ export function mapDocumentOpenResult(response, sessionId, path) {
81
+ if (typeof response !== 'object' || response == null || Array.isArray(response)) {
82
+ throw new SuperDocCliError('Host returned invalid document.open result.', {
83
+ code: 'HOST_PROTOCOL_ERROR',
84
+ details: { result: response },
85
+ });
86
+ }
87
+ const record = response;
88
+ if (record.sessionId !== sessionId || typeof record.byteLength !== 'number') {
89
+ throw new SuperDocCliError('Host returned invalid document.open session metadata.', {
90
+ code: 'HOST_PROTOCOL_ERROR',
91
+ details: { result: response },
92
+ });
93
+ }
94
+ return {
95
+ active: true,
96
+ contextId: sessionId,
97
+ runtime: 'v2',
98
+ sessionType: 'local',
99
+ document: { path, source: 'path', byteLength: record.byteLength, revision: 0 },
100
+ dirty: false,
101
+ };
102
+ }
103
+ function supportsTrackedMode(operation) {
104
+ return operation.supportsTrackedMode === true || operation.supportsConditionalTrackedMode === true;
105
+ }
106
+ function documentInvokePayload(operation, params, invokeOptions) {
107
+ const normalizedParams = applyOperationParamAliases(operation, params);
108
+ if (invokeOptions.stdinBytes !== undefined) {
109
+ throw unsupported('Structured document RPC does not support stdinBytes.', operation.operationId);
110
+ }
111
+ if (typeof normalizedParams.out === 'string' && normalizedParams.out.length > 0) {
112
+ throw unsupported('Structured document RPC does not support per-operation output paths.', operation.operationId);
113
+ }
114
+ if (normalizedParams.force === true) {
115
+ throw unsupported('Structured document RPC does not support per-operation force.', operation.operationId);
116
+ }
117
+ const input = {};
118
+ const options = {};
119
+ const paramsByName = new Map(operation.params.map((param) => [param.name, param]));
120
+ for (const [name, value] of Object.entries(normalizedParams)) {
121
+ if (value === undefined || name === 'doc' || name === 'sessionId' || name === 'out' || name === 'force')
122
+ continue;
123
+ const param = paramsByName.get(name);
124
+ if (!param) {
125
+ throw unsupported(`Structured document RPC does not support ${operation.operationId} field ${name}.`, operation.operationId);
126
+ }
127
+ if (typeof param.documentApiInputName === 'string' && param.documentApiInputName.length > 0) {
128
+ input[param.documentApiInputName] = value;
129
+ continue;
130
+ }
131
+ if (DOCUMENT_API_OPTION_FIELDS.has(name)) {
132
+ options[name] = value;
133
+ continue;
134
+ }
135
+ throw unsupported(`Structured document RPC does not support ${operation.operationId} field ${name}.`, operation.operationId);
136
+ }
137
+ for (const name of ['expectedRevision', 'changeMode', 'dryRun']) {
138
+ const value = invokeOptions[name];
139
+ if (value === undefined || normalizedParams[name] !== undefined)
140
+ continue;
141
+ const projectedValue = name === 'expectedRevision' ? String(value) : value;
142
+ const param = paramsByName.get(name);
143
+ if (typeof param?.documentApiInputName === 'string' && param.documentApiInputName.length > 0) {
144
+ input[param.documentApiInputName] = projectedValue;
145
+ }
146
+ else {
147
+ options[name] = projectedValue;
148
+ }
149
+ }
150
+ if (options.changeMode !== undefined && !supportsTrackedMode(operation)) {
151
+ if (options.changeMode === 'tracked') {
152
+ throw unsupported(`Structured document RPC does not support tracked mode for ${operation.operationId}.`, operation.operationId);
153
+ }
154
+ if (options.changeMode !== 'direct') {
155
+ throw unsupported(`Structured document RPC received an invalid change mode for ${operation.operationId}.`, operation.operationId);
156
+ }
157
+ delete options.changeMode;
158
+ }
159
+ if (options.dryRun !== undefined && operation.supportsDryRun !== true) {
160
+ if (options.dryRun === true) {
161
+ throw unsupported(`Structured document RPC does not support dry run for ${operation.operationId}.`, operation.operationId);
162
+ }
163
+ delete options.dryRun;
164
+ }
165
+ if (options.expectedRevision !== undefined && DOCUMENT_API_REVISION_PREFLIGHT_OPERATIONS.has(operation.operationId)) {
166
+ throw unsupported(`Structured document RPC does not yet support expectedRevision for ${operation.operationId}.`, operation.operationId);
167
+ }
168
+ if (options.expectedRevision !== undefined && operation.mutates !== true) {
169
+ throw unsupported(`Structured document RPC does not support expectedRevision for ${operation.operationId}.`, operation.operationId);
170
+ }
171
+ return {
172
+ input,
173
+ ...(Object.keys(options).length === 0 ? {} : { options }),
174
+ };
175
+ }
176
+ export function buildDocumentInvokeParams(sessionId, operation, params, options, hostFeatures) {
177
+ if (operation.operationId === 'doc.save') {
178
+ if (options.stdinBytes !== undefined ||
179
+ options.dryRun !== undefined ||
180
+ options.expectedRevision !== undefined ||
181
+ options.changeMode !== undefined) {
182
+ throw unsupported('Structured document RPC does not support document.save invoke options.', operation.operationId);
183
+ }
184
+ const unknownField = Object.entries(params).find(([name, value]) => value !== undefined && !DOCUMENT_RPC_SAVE_FIELDS.has(name))?.[0];
185
+ if (unknownField !== undefined) {
186
+ throw unsupported(`Structured document RPC does not support doc.save field ${unknownField}.`, operation.operationId);
187
+ }
188
+ if (params.inPlace !== undefined && typeof params.inPlace !== 'boolean') {
189
+ throw unsupported('Structured document RPC requires inPlace to be a boolean.', operation.operationId);
190
+ }
191
+ if (params.inPlace === true && params.out !== undefined) {
192
+ throw unsupported('Structured document RPC requires either inPlace or out, not both.', operation.operationId);
193
+ }
194
+ if (params.out !== undefined && (typeof params.out !== 'string' || params.out.length === 0)) {
195
+ throw unsupported('Structured document RPC requires out to be a non-empty path.', operation.operationId);
196
+ }
197
+ if (params.out === undefined && hostFeatures?.has(DOCUMENT_RPC_SOURCE_SAVE_FEATURE) !== true) {
198
+ throw unsupported('Structured document RPC host does not support source saves.', operation.operationId);
199
+ }
200
+ return {
201
+ method: 'document.save',
202
+ params: {
203
+ sessionId,
204
+ ...(params.out === undefined ? {} : { path: params.out }),
205
+ ...(params.force === true ? { overwrite: true } : {}),
206
+ ...(params.mode === undefined ? {} : { mode: params.mode }),
207
+ },
208
+ };
209
+ }
210
+ if (operation.operationId === 'doc.close') {
211
+ if (options.stdinBytes !== undefined ||
212
+ options.dryRun !== undefined ||
213
+ options.expectedRevision !== undefined ||
214
+ options.changeMode !== undefined) {
215
+ throw unsupported('Structured document RPC does not support document.close invoke options.', operation.operationId);
216
+ }
217
+ return {
218
+ method: 'document.close',
219
+ params: {
220
+ sessionId,
221
+ ...(params.discard === undefined ? {} : { discard: params.discard }),
222
+ },
223
+ };
224
+ }
225
+ const documentOperation = operation;
226
+ if (typeof documentOperation.documentApiOperationId !== 'string' ||
227
+ documentOperation.documentApiOperationId.length === 0) {
228
+ throw unsupported(`Structured document RPC does not support ${operation.operationId}.`, operation.operationId);
229
+ }
230
+ const payload = documentInvokePayload(documentOperation, params, options);
231
+ return {
232
+ method: 'document.invoke',
233
+ params: {
234
+ sessionId,
235
+ operationId: documentOperation.documentApiOperationId,
236
+ input: payload.input,
237
+ ...(payload.options === undefined ? {} : { options: payload.options }),
238
+ },
239
+ };
240
+ }
241
+ export function documentRpcRequestSupportsResponseTimeout(operation, request) {
242
+ if (request.method === 'document.save')
243
+ return false;
244
+ if (request.method !== 'document.invoke')
245
+ return true;
246
+ const documentOperation = operation;
247
+ const requestOptions = typeof request.params.options === 'object' &&
248
+ request.params.options !== null &&
249
+ !Array.isArray(request.params.options)
250
+ ? request.params.options
251
+ : undefined;
252
+ if (requestOptions?.dryRun === true)
253
+ return true;
254
+ if (documentOperation.mutates === false)
255
+ return true;
256
+ return documentOperation.idempotency === 'idempotent';
257
+ }
258
+ export function mapDocumentLifecycleResult(operationId, response, sessionId, expectedInPlace) {
259
+ if (operationId !== 'doc.save' && operationId !== 'doc.close')
260
+ return response;
261
+ if (typeof response !== 'object' || response == null || Array.isArray(response)) {
262
+ throw new SuperDocCliError(`Host returned invalid ${operationId.slice('doc.'.length)} result.`, {
263
+ code: 'HOST_PROTOCOL_ERROR',
264
+ details: { result: response },
265
+ });
266
+ }
267
+ const record = response;
268
+ if (record.sessionId !== sessionId) {
269
+ throw new SuperDocCliError('Host returned a result for the wrong document session.', {
270
+ code: 'HOST_PROTOCOL_ERROR',
271
+ details: { expectedSessionId: sessionId, result: response },
272
+ });
273
+ }
274
+ if (operationId === 'doc.close') {
275
+ if (record.closed !== true || typeof record.discarded !== 'boolean') {
276
+ throw new SuperDocCliError('Host returned invalid document.close result.', {
277
+ code: 'HOST_PROTOCOL_ERROR',
278
+ details: { result: response },
279
+ });
280
+ }
281
+ return {
282
+ contextId: sessionId,
283
+ runtime: 'v2',
284
+ closed: true,
285
+ saved: false,
286
+ discarded: record.discarded,
287
+ defaultSessionCleared: false,
288
+ };
289
+ }
290
+ const output = record.output;
291
+ if (record.saved !== true ||
292
+ (typeof record.inPlace !== 'boolean' && !(record.inPlace === undefined && expectedInPlace === false)) ||
293
+ typeof output !== 'object' ||
294
+ output == null ||
295
+ Array.isArray(output) ||
296
+ typeof output.path !== 'string' ||
297
+ typeof output.byteLength !== 'number') {
298
+ throw new SuperDocCliError('Host returned invalid document.save result.', {
299
+ code: 'HOST_PROTOCOL_ERROR',
300
+ details: { result: response },
301
+ });
302
+ }
303
+ return {
304
+ contextId: sessionId,
305
+ runtime: 'v2',
306
+ saved: true,
307
+ inPlace: record.inPlace ?? false,
308
+ mode: record.mode,
309
+ output,
310
+ report: record.report,
311
+ };
312
+ }
@@ -1,78 +1,16 @@
1
1
  'use strict';
2
2
 
3
- var node_fs = require('node:fs');
4
- var node_module = require('node:module');
5
- var path = require('node:path');
6
- var node_url = require('node:url');
7
3
  var errors = require('./errors.cjs');
4
+ var embeddedPlatform = require('./embedded-platform.cjs');
8
5
 
9
- var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
10
- const require$1 = node_module.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('runtime/embedded-cli.cjs', document.baseURI).href)));
11
- const TARGET_TO_PACKAGE = {
12
- 'darwin-arm64': '@superdoc/sdk-darwin-arm64',
13
- 'darwin-x64': '@superdoc/sdk-darwin-x64',
14
- 'linux-x64': '@superdoc/sdk-linux-x64',
15
- 'linux-arm64': '@superdoc/sdk-linux-arm64',
16
- 'windows-x64': '@superdoc/sdk-windows-x64',
17
- };
18
- const TARGET_TO_DIR = {
19
- 'darwin-arm64': 'sdk-darwin-arm64',
20
- 'darwin-x64': 'sdk-darwin-x64',
21
- 'linux-x64': 'sdk-linux-x64',
22
- 'linux-arm64': 'sdk-linux-arm64',
23
- 'windows-x64': 'sdk-windows-x64',
24
- };
25
- function resolveTarget() {
26
- const platform = process.platform;
27
- const arch = process.arch;
28
- if (platform === 'darwin' && arch === 'arm64')
29
- return 'darwin-arm64';
30
- if (platform === 'darwin' && arch === 'x64')
31
- return 'darwin-x64';
32
- if (platform === 'linux' && arch === 'x64')
33
- return 'linux-x64';
34
- if (platform === 'linux' && arch === 'arm64')
35
- return 'linux-arm64';
36
- if (platform === 'win32' && arch === 'x64')
37
- return 'windows-x64';
38
- return null;
39
- }
40
6
  function binaryNameForTarget(target) {
41
7
  return target === 'windows-x64' ? 'superdoc.exe' : 'superdoc';
42
8
  }
43
- function ensureExecutable(binaryPath) {
44
- if (process.platform === 'win32')
45
- return;
46
- try {
47
- node_fs.chmodSync(binaryPath, 0o755);
48
- }
49
- catch {
50
- // Non-fatal: if chmod fails, spawn() will surface the real execution error.
51
- }
52
- }
53
- function resolveFromPlatformPackage(target) {
54
- const pkg = TARGET_TO_PACKAGE[target];
55
- const binaryName = binaryNameForTarget(target);
56
- try {
57
- return require$1.resolve(`${pkg}/bin/${binaryName}`);
58
- }
59
- catch {
60
- return null;
61
- }
62
- }
63
- function resolveFromWorkspaceFallback(target) {
64
- const binaryName = binaryNameForTarget(target);
65
- const dirName = TARGET_TO_DIR[target];
66
- const filePath = path.resolve(node_url.fileURLToPath(new URL('../../platforms', (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('runtime/embedded-cli.cjs', document.baseURI).href)))), dirName, 'bin', binaryName);
67
- if (!node_fs.existsSync(filePath))
68
- return null;
69
- return filePath;
70
- }
71
9
  /**
72
10
  * Resolve the path to the embedded SuperDoc CLI binary for the current platform.
73
11
  */
74
12
  function resolveEmbeddedCliBinary() {
75
- const target = resolveTarget();
13
+ const target = embeddedPlatform.resolveEmbeddedTarget();
76
14
  if (!target) {
77
15
  throw new errors.SuperDocCliError('No embedded SuperDoc CLI binary is available for this platform.', {
78
16
  code: 'UNSUPPORTED_PLATFORM',
@@ -82,18 +20,17 @@ function resolveEmbeddedCliBinary() {
82
20
  },
83
21
  });
84
22
  }
85
- const platformPackagePath = resolveFromPlatformPackage(target);
86
- const resolvedPath = platformPackagePath ?? resolveFromWorkspaceFallback(target);
23
+ const resolvedPath = embeddedPlatform.resolveEmbeddedPlatformBinary(target, binaryNameForTarget(target));
87
24
  if (!resolvedPath) {
88
25
  throw new errors.SuperDocCliError('Embedded SuperDoc CLI binary is missing for this platform.', {
89
26
  code: 'CLI_BINARY_MISSING',
90
27
  details: {
91
28
  target,
92
- packageName: TARGET_TO_PACKAGE[target],
29
+ packageName: embeddedPlatform.embeddedPlatformPackage(target),
93
30
  },
94
31
  });
95
32
  }
96
- ensureExecutable(resolvedPath);
33
+ embeddedPlatform.ensureEmbeddedExecutable(resolvedPath);
97
34
  return resolvedPath;
98
35
  }
99
36
 
@@ -1,74 +1,13 @@
1
- import { chmodSync, existsSync } from 'node:fs';
2
- import { createRequire } from 'node:module';
3
- import path from 'node:path';
4
- import { fileURLToPath } from 'node:url';
5
1
  import { SuperDocCliError } from './errors.js';
6
- const require = createRequire(import.meta.url);
7
- const TARGET_TO_PACKAGE = {
8
- 'darwin-arm64': '@superdoc/sdk-darwin-arm64',
9
- 'darwin-x64': '@superdoc/sdk-darwin-x64',
10
- 'linux-x64': '@superdoc/sdk-linux-x64',
11
- 'linux-arm64': '@superdoc/sdk-linux-arm64',
12
- 'windows-x64': '@superdoc/sdk-windows-x64',
13
- };
14
- const TARGET_TO_DIR = {
15
- 'darwin-arm64': 'sdk-darwin-arm64',
16
- 'darwin-x64': 'sdk-darwin-x64',
17
- 'linux-x64': 'sdk-linux-x64',
18
- 'linux-arm64': 'sdk-linux-arm64',
19
- 'windows-x64': 'sdk-windows-x64',
20
- };
21
- function resolveTarget() {
22
- const platform = process.platform;
23
- const arch = process.arch;
24
- if (platform === 'darwin' && arch === 'arm64')
25
- return 'darwin-arm64';
26
- if (platform === 'darwin' && arch === 'x64')
27
- return 'darwin-x64';
28
- if (platform === 'linux' && arch === 'x64')
29
- return 'linux-x64';
30
- if (platform === 'linux' && arch === 'arm64')
31
- return 'linux-arm64';
32
- if (platform === 'win32' && arch === 'x64')
33
- return 'windows-x64';
34
- return null;
35
- }
2
+ import { embeddedPlatformPackage, ensureEmbeddedExecutable, resolveEmbeddedPlatformBinary, resolveEmbeddedTarget, } from './embedded-platform.js';
36
3
  function binaryNameForTarget(target) {
37
4
  return target === 'windows-x64' ? 'superdoc.exe' : 'superdoc';
38
5
  }
39
- function ensureExecutable(binaryPath) {
40
- if (process.platform === 'win32')
41
- return;
42
- try {
43
- chmodSync(binaryPath, 0o755);
44
- }
45
- catch {
46
- // Non-fatal: if chmod fails, spawn() will surface the real execution error.
47
- }
48
- }
49
- function resolveFromPlatformPackage(target) {
50
- const pkg = TARGET_TO_PACKAGE[target];
51
- const binaryName = binaryNameForTarget(target);
52
- try {
53
- return require.resolve(`${pkg}/bin/${binaryName}`);
54
- }
55
- catch {
56
- return null;
57
- }
58
- }
59
- function resolveFromWorkspaceFallback(target) {
60
- const binaryName = binaryNameForTarget(target);
61
- const dirName = TARGET_TO_DIR[target];
62
- const filePath = path.resolve(fileURLToPath(new URL('../../platforms', import.meta.url)), dirName, 'bin', binaryName);
63
- if (!existsSync(filePath))
64
- return null;
65
- return filePath;
66
- }
67
6
  /**
68
7
  * Resolve the path to the embedded SuperDoc CLI binary for the current platform.
69
8
  */
70
9
  export function resolveEmbeddedCliBinary() {
71
- const target = resolveTarget();
10
+ const target = resolveEmbeddedTarget();
72
11
  if (!target) {
73
12
  throw new SuperDocCliError('No embedded SuperDoc CLI binary is available for this platform.', {
74
13
  code: 'UNSUPPORTED_PLATFORM',
@@ -78,17 +17,16 @@ export function resolveEmbeddedCliBinary() {
78
17
  },
79
18
  });
80
19
  }
81
- const platformPackagePath = resolveFromPlatformPackage(target);
82
- const resolvedPath = platformPackagePath ?? resolveFromWorkspaceFallback(target);
20
+ const resolvedPath = resolveEmbeddedPlatformBinary(target, binaryNameForTarget(target));
83
21
  if (!resolvedPath) {
84
22
  throw new SuperDocCliError('Embedded SuperDoc CLI binary is missing for this platform.', {
85
23
  code: 'CLI_BINARY_MISSING',
86
24
  details: {
87
25
  target,
88
- packageName: TARGET_TO_PACKAGE[target],
26
+ packageName: embeddedPlatformPackage(target),
89
27
  },
90
28
  });
91
29
  }
92
- ensureExecutable(resolvedPath);
30
+ ensureEmbeddedExecutable(resolvedPath);
93
31
  return resolvedPath;
94
32
  }
@@ -0,0 +1,28 @@
1
+ 'use strict';
2
+
3
+ var embeddedPlatform = require('./embedded-platform.cjs');
4
+ var errors = require('./errors.cjs');
5
+
6
+ function binaryNameForTarget(target) {
7
+ return target === 'windows-x64' ? 'superdoc-document-host.exe' : 'superdoc-document-host';
8
+ }
9
+ function resolveEmbeddedDocumentHostBinary() {
10
+ const target = embeddedPlatform.resolveEmbeddedTarget();
11
+ if (!target) {
12
+ throw new errors.SuperDocCliError('No embedded SuperDoc document host is available for this platform.', {
13
+ code: 'UNSUPPORTED_PLATFORM',
14
+ details: { platform: process.platform, arch: process.arch },
15
+ });
16
+ }
17
+ const resolvedPath = embeddedPlatform.resolveEmbeddedPlatformBinary(target, binaryNameForTarget(target));
18
+ if (!resolvedPath) {
19
+ throw new errors.SuperDocCliError('Embedded SuperDoc document host is missing for this platform.', {
20
+ code: 'DOCUMENT_HOST_BINARY_MISSING',
21
+ details: { target, packageName: embeddedPlatform.embeddedPlatformPackage(target) },
22
+ });
23
+ }
24
+ embeddedPlatform.ensureEmbeddedExecutable(resolvedPath);
25
+ return resolvedPath;
26
+ }
27
+
28
+ exports.resolveEmbeddedDocumentHostBinary = resolveEmbeddedDocumentHostBinary;
@@ -0,0 +1 @@
1
+ export declare function resolveEmbeddedDocumentHostBinary(): string;
@@ -0,0 +1,23 @@
1
+ import { embeddedPlatformPackage, ensureEmbeddedExecutable, resolveEmbeddedPlatformBinary, resolveEmbeddedTarget, } from './embedded-platform.js';
2
+ import { SuperDocCliError } from './errors.js';
3
+ function binaryNameForTarget(target) {
4
+ return target === 'windows-x64' ? 'superdoc-document-host.exe' : 'superdoc-document-host';
5
+ }
6
+ export function resolveEmbeddedDocumentHostBinary() {
7
+ const target = resolveEmbeddedTarget();
8
+ if (!target) {
9
+ throw new SuperDocCliError('No embedded SuperDoc document host is available for this platform.', {
10
+ code: 'UNSUPPORTED_PLATFORM',
11
+ details: { platform: process.platform, arch: process.arch },
12
+ });
13
+ }
14
+ const resolvedPath = resolveEmbeddedPlatformBinary(target, binaryNameForTarget(target));
15
+ if (!resolvedPath) {
16
+ throw new SuperDocCliError('Embedded SuperDoc document host is missing for this platform.', {
17
+ code: 'DOCUMENT_HOST_BINARY_MISSING',
18
+ details: { target, packageName: embeddedPlatformPackage(target) },
19
+ });
20
+ }
21
+ ensureEmbeddedExecutable(resolvedPath);
22
+ return resolvedPath;
23
+ }
@@ -0,0 +1,102 @@
1
+ 'use strict';
2
+
3
+ var node_fs = require('node:fs');
4
+ var node_module = require('node:module');
5
+ var path = require('node:path');
6
+ var node_url = require('node:url');
7
+
8
+ var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
9
+ const require$1 = node_module.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('runtime/embedded-platform.cjs', document.baseURI).href)));
10
+ const TARGET_TO_PACKAGE = {
11
+ 'darwin-arm64': '@superdoc/sdk-darwin-arm64',
12
+ 'darwin-x64': '@superdoc/sdk-darwin-x64',
13
+ 'linux-x64': '@superdoc/sdk-linux-x64',
14
+ 'linux-arm64': '@superdoc/sdk-linux-arm64',
15
+ 'windows-x64': '@superdoc/sdk-windows-x64',
16
+ };
17
+ const TARGET_TO_DIR = {
18
+ 'darwin-arm64': 'sdk-darwin-arm64',
19
+ 'darwin-x64': 'sdk-darwin-x64',
20
+ 'linux-x64': 'sdk-linux-x64',
21
+ 'linux-arm64': 'sdk-linux-arm64',
22
+ 'windows-x64': 'sdk-windows-x64',
23
+ };
24
+ function resolveEmbeddedTarget(platform = process.platform, arch = process.arch) {
25
+ if (platform === 'darwin' && arch === 'arm64')
26
+ return 'darwin-arm64';
27
+ if (platform === 'darwin' && arch === 'x64')
28
+ return 'darwin-x64';
29
+ if (platform === 'linux' && arch === 'x64')
30
+ return 'linux-x64';
31
+ if (platform === 'linux' && arch === 'arm64')
32
+ return 'linux-arm64';
33
+ if (platform === 'win32' && arch === 'x64')
34
+ return 'windows-x64';
35
+ return null;
36
+ }
37
+ function embeddedPlatformPackage(target) {
38
+ return TARGET_TO_PACKAGE[target];
39
+ }
40
+ /**
41
+ * The binary shipped inside this package (`platforms/<target>/bin/`). A build
42
+ * that carries its own host is authoritative — it is the only copy guaranteed
43
+ * to match this SDK's code — so it is tried before any resolver lookup.
44
+ */
45
+ function resolveFromPackageLocal(target, binaryName) {
46
+ const workspacePath = path.resolve(node_url.fileURLToPath(new URL('../../platforms', (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('runtime/embedded-platform.cjs', document.baseURI).href)))), TARGET_TO_DIR[target], 'bin', binaryName);
47
+ return node_fs.existsSync(workspacePath) ? workspacePath : null;
48
+ }
49
+ /**
50
+ * Resolve the platform package through Node, and reject a version that is not
51
+ * this SDK's own.
52
+ *
53
+ * `require.resolve` falls back to NODE_PATH, which package managers set to a
54
+ * flat store directory (pnpm does it for every binary shim). A host binary from
55
+ * an unrelated SDK version installed anywhere in that store then satisfies this
56
+ * lookup, and the SDK silently drives a foreign engine: seen in the wild as an
57
+ * SDK 2.2.1 install executing a hoisted 2.0.0 host, which failed operations the
58
+ * matching host performs correctly. optionalDependencies pin the platform
59
+ * package to an exact version, so a mismatch here is never legitimate.
60
+ */
61
+ function resolveFromPlatformPackage(target, binaryName) {
62
+ const pkg = TARGET_TO_PACKAGE[target];
63
+ let binaryPath;
64
+ try {
65
+ binaryPath = require$1.resolve(`${pkg}/bin/${binaryName}`);
66
+ }
67
+ catch {
68
+ return null;
69
+ }
70
+ try {
71
+ const platformVersion = require$1(require$1.resolve(`${pkg}/package.json`)).version;
72
+ const ownVersion = require$1(node_url.fileURLToPath(new URL('../../package.json', (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('runtime/embedded-platform.cjs', document.baseURI).href))))).version;
73
+ if (platformVersion !== ownVersion)
74
+ return null;
75
+ }
76
+ catch {
77
+ // Either manifest being unreadable is itself disqualifying: an unverifiable
78
+ // host is exactly the case this guard exists to reject.
79
+ return null;
80
+ }
81
+ return binaryPath;
82
+ }
83
+ function resolveEmbeddedPlatformBinary(target, binaryName) {
84
+ // Package-local first: a self-contained build must never be overridden by
85
+ // whatever the module resolver happens to find on NODE_PATH.
86
+ return resolveFromPackageLocal(target, binaryName) ?? resolveFromPlatformPackage(target, binaryName);
87
+ }
88
+ function ensureEmbeddedExecutable(binaryPath) {
89
+ if (process.platform === 'win32')
90
+ return;
91
+ try {
92
+ node_fs.chmodSync(binaryPath, 0o755);
93
+ }
94
+ catch {
95
+ // Non-fatal: spawn() reports the actionable execution error.
96
+ }
97
+ }
98
+
99
+ exports.embeddedPlatformPackage = embeddedPlatformPackage;
100
+ exports.ensureEmbeddedExecutable = ensureEmbeddedExecutable;
101
+ exports.resolveEmbeddedPlatformBinary = resolveEmbeddedPlatformBinary;
102
+ exports.resolveEmbeddedTarget = resolveEmbeddedTarget;