@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.
- package/dist/agent/actions.cjs +1869 -160
- package/dist/agent/actions.d.ts +77 -10
- package/dist/agent/actions.js +1870 -161
- package/dist/agent/catalog.cjs +102 -9
- package/dist/agent/catalog.d.ts +243 -0
- package/dist/agent/catalog.js +99 -9
- package/dist/agent/doc-snapshot.cjs +200 -2
- package/dist/agent/doc-snapshot.d.ts +91 -0
- package/dist/agent/doc-snapshot.js +199 -2
- package/dist/agent/runtime.cjs +9 -1
- package/dist/agent/runtime.d.ts +8 -0
- package/dist/agent/runtime.js +9 -1
- package/dist/embedded-tools.generated.cjs +5 -5
- package/dist/embedded-tools.generated.js +5 -5
- package/dist/generated/client.cjs +754 -770
- package/dist/generated/client.d.ts +14 -9
- package/dist/generated/client.js +754 -770
- package/dist/generated/contract.cjs +16207 -274
- package/dist/generated/contract.d.ts +38 -0
- package/dist/generated/contract.js +17443 -1503
- package/dist/index.cjs +5 -4
- package/dist/index.d.ts +2 -2
- package/dist/index.js +5 -4
- package/dist/introspection.cjs +59 -0
- package/dist/introspection.d.ts +3 -0
- package/dist/introspection.js +53 -0
- package/dist/runtime/document-rpc.cjs +328 -0
- package/dist/runtime/document-rpc.d.ts +24 -0
- package/dist/runtime/document-rpc.js +312 -0
- package/dist/runtime/embedded-cli.cjs +5 -68
- package/dist/runtime/embedded-cli.js +5 -67
- package/dist/runtime/embedded-document-host.cjs +28 -0
- package/dist/runtime/embedded-document-host.d.ts +1 -0
- package/dist/runtime/embedded-document-host.js +23 -0
- package/dist/runtime/embedded-platform.cjs +102 -0
- package/dist/runtime/embedded-platform.d.ts +5 -0
- package/dist/runtime/embedded-platform.js +93 -0
- package/dist/runtime/host.cjs +128 -16
- package/dist/runtime/host.d.ts +11 -5
- package/dist/runtime/host.js +126 -16
- package/dist/runtime/process.cjs +34 -5
- package/dist/runtime/process.d.ts +12 -3
- package/dist/runtime/process.js +33 -5
- package/dist/runtime/transport-common.cjs +1 -0
- package/dist/runtime/transport-common.d.ts +28 -10
- package/dist/runtime/transport-common.js +1 -1
- package/package.json +7 -6
- package/tools/__pycache__/__init__.cpython-311.pyc +0 -0
- package/tools/__pycache__/intent_dispatch_generated.cpython-311.pyc +0 -0
- package/tools/catalog.json +2 -2
- package/tools/tools-policy.json +1 -1
- package/tools/tools.anthropic.json +2 -2
- package/tools/tools.generic.json +2 -2
- package/tools/tools.openai.json +2 -2
- package/tools/tools.vercel.json +2 -2
package/dist/runtime/host.js
CHANGED
|
@@ -2,8 +2,10 @@ import { spawn } from 'node:child_process';
|
|
|
2
2
|
import { createInterface } from 'node:readline';
|
|
3
3
|
import { buildOperationArgv, resolveInvocation, } from './transport-common.js';
|
|
4
4
|
import { SuperDocCliError } from './errors.js';
|
|
5
|
+
import { DOCUMENT_RPC_FEATURES, DOCUMENT_RPC_DEFAULT_CHANGE_MODE_FEATURE, DOCUMENT_RPC_REQUEST_TIMEOUT_FEATURE, buildDocumentInvokeParams, buildDocumentOpenParams, canOpenWithDocumentRpc, documentRpcRequestSupportsResponseTimeout, documentRpcEnabled, mapDocumentLifecycleResult, mapDocumentOpenResult, supportsDocumentRpc, } from './document-rpc.js';
|
|
5
6
|
const HOST_PROTOCOL_VERSION = '1.0';
|
|
6
|
-
const
|
|
7
|
+
const CLI_HOST_REQUIRED_FEATURES = ['cli.invoke', 'host.shutdown'];
|
|
8
|
+
const DOCUMENT_HOST_REQUIRED_FEATURES = [...DOCUMENT_RPC_FEATURES, 'host.shutdown'];
|
|
7
9
|
const CHANGE_MODES = ['direct', 'tracked'];
|
|
8
10
|
const FORWARD_HOST_STDERR = typeof process !== 'undefined' && typeof process.env?.SUPERDOC_DEBUG_TEXT_REWRITE === 'string'
|
|
9
11
|
? process.env.SUPERDOC_DEBUG_TEXT_REWRITE === '1'
|
|
@@ -18,6 +20,21 @@ const HOST_DEFAULT_REQUEST_TIMEOUT_MS = 30_000;
|
|
|
18
20
|
// abort. The buffer absorbs JSON-RPC serialization, stdio drain, and event-
|
|
19
21
|
// loop latency.
|
|
20
22
|
const WATCHDOG_HEADROOM_MS = 5_000;
|
|
23
|
+
export function mapCliInvocationResult(operation, value) {
|
|
24
|
+
const envelopeKey = operation.responseEnvelopeKey;
|
|
25
|
+
if (envelopeKey === null || envelopeKey === undefined)
|
|
26
|
+
return value;
|
|
27
|
+
if (typeof envelopeKey !== 'string' || envelopeKey.length === 0) {
|
|
28
|
+
throw new SuperDocCliError('Generated operation has invalid response envelope metadata.', {
|
|
29
|
+
code: 'HOST_PROTOCOL_ERROR',
|
|
30
|
+
details: { operationId: operation.operationId, responseEnvelopeKey: envelopeKey },
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
if (typeof value !== 'object' || value === null || Array.isArray(value))
|
|
34
|
+
return value;
|
|
35
|
+
const extracted = value[envelopeKey];
|
|
36
|
+
return extracted === undefined ? value : extracted;
|
|
37
|
+
}
|
|
21
38
|
/**
|
|
22
39
|
* Builds the argv passed to `spawn` for `superdoc host --stdio`. Propagates
|
|
23
40
|
* `requestTimeoutMs` to the host via `--request-timeout-ms`, since the SDK
|
|
@@ -32,6 +49,9 @@ export function buildHostSpawnArgs(prefixArgs, options) {
|
|
|
32
49
|
}
|
|
33
50
|
return args;
|
|
34
51
|
}
|
|
52
|
+
export function buildDocumentHostSpawnArgs(prefixArgs) {
|
|
53
|
+
return [...prefixArgs];
|
|
54
|
+
}
|
|
35
55
|
/**
|
|
36
56
|
* Computes the JS-side watchdog timeout for a single JSON-RPC request.
|
|
37
57
|
*
|
|
@@ -57,11 +77,10 @@ export function resolveJsWatchdogTimeout(watchdogTimeoutMs, requestTimeoutMs, ti
|
|
|
57
77
|
}
|
|
58
78
|
return Math.max(watchdogTimeoutMs, HOST_DEFAULT_REQUEST_TIMEOUT_MS + WATCHDOG_HEADROOM_MS);
|
|
59
79
|
}
|
|
60
|
-
/**
|
|
61
|
-
* Transport that communicates with a long-lived CLI host process over JSON-RPC stdio.
|
|
62
|
-
*/
|
|
80
|
+
/** Transport for the legacy CLI host or the structured document host. */
|
|
63
81
|
export class HostTransport {
|
|
64
|
-
|
|
82
|
+
hostBin;
|
|
83
|
+
processMode;
|
|
65
84
|
env;
|
|
66
85
|
startupTimeoutMs;
|
|
67
86
|
shutdownTimeoutMs;
|
|
@@ -70,14 +89,18 @@ export class HostTransport {
|
|
|
70
89
|
maxQueueDepth;
|
|
71
90
|
defaultChangeMode;
|
|
72
91
|
user;
|
|
92
|
+
documentRpcEnabled;
|
|
73
93
|
child = null;
|
|
74
94
|
stdoutReader = null;
|
|
75
95
|
pending = new Map();
|
|
76
96
|
nextRequestId = 1;
|
|
77
97
|
connecting = null;
|
|
78
98
|
stopping = false;
|
|
99
|
+
hostFeatures = new Set();
|
|
100
|
+
documentRpcSessions = new Set();
|
|
79
101
|
constructor(options) {
|
|
80
|
-
this.
|
|
102
|
+
this.hostBin = options.hostBin;
|
|
103
|
+
this.processMode = options.processMode ?? 'cli';
|
|
81
104
|
this.env = options.env;
|
|
82
105
|
this.startupTimeoutMs = options.startupTimeoutMs ?? 5_000;
|
|
83
106
|
this.shutdownTimeoutMs = options.shutdownTimeoutMs ?? 5_000;
|
|
@@ -90,8 +113,9 @@ export class HostTransport {
|
|
|
90
113
|
details: { defaultChangeMode: options.defaultChangeMode },
|
|
91
114
|
});
|
|
92
115
|
}
|
|
93
|
-
this.defaultChangeMode = options.defaultChangeMode;
|
|
116
|
+
this.defaultChangeMode = options.defaultChangeMode ?? undefined;
|
|
94
117
|
this.user = options.user;
|
|
118
|
+
this.documentRpcEnabled = this.processMode === 'document' || documentRpcEnabled(options.env);
|
|
95
119
|
}
|
|
96
120
|
async connect() {
|
|
97
121
|
await this.ensureConnected();
|
|
@@ -122,6 +146,53 @@ export class HostTransport {
|
|
|
122
146
|
}
|
|
123
147
|
async invoke(operation, params = {}, options = {}) {
|
|
124
148
|
await this.ensureConnected();
|
|
149
|
+
const shouldOpenThroughCliTimeoutFallback = this.processMode === 'cli' &&
|
|
150
|
+
(this.requestTimeoutMs !== undefined ||
|
|
151
|
+
(options.timeoutMs !== undefined && !this.hostFeatures.has(DOCUMENT_RPC_REQUEST_TIMEOUT_FEATURE)));
|
|
152
|
+
if (this.documentRpcEnabled &&
|
|
153
|
+
supportsDocumentRpc(this.hostFeatures) &&
|
|
154
|
+
(this.defaultChangeMode === undefined || this.hostFeatures.has(DOCUMENT_RPC_DEFAULT_CHANGE_MODE_FEATURE)) &&
|
|
155
|
+
operation.operationId === 'doc.open' &&
|
|
156
|
+
canOpenWithDocumentRpc(params, options) &&
|
|
157
|
+
!shouldOpenThroughCliTimeoutFallback) {
|
|
158
|
+
const opened = buildDocumentOpenParams(params, this.user, this.defaultChangeMode);
|
|
159
|
+
const requestTimeoutMs = this.resolveDocumentRequestTimeout(options.timeoutMs);
|
|
160
|
+
const response = await this.sendJsonRpcRequest('document.open', opened.params, this.resolveWatchdogTimeout(options.timeoutMs), { requestTimeoutMs });
|
|
161
|
+
const result = mapDocumentOpenResult(response, opened.sessionId, params.doc);
|
|
162
|
+
this.documentRpcSessions.add(opened.sessionId);
|
|
163
|
+
return result;
|
|
164
|
+
}
|
|
165
|
+
const sessionId = typeof params.sessionId === 'string' ? params.sessionId : undefined;
|
|
166
|
+
if (sessionId !== undefined && this.documentRpcSessions.has(sessionId)) {
|
|
167
|
+
const request = buildDocumentInvokeParams(sessionId, operation, params, options, this.hostFeatures);
|
|
168
|
+
const supportsResponseTimeout = documentRpcRequestSupportsResponseTimeout(operation, request);
|
|
169
|
+
const requestTimeoutMs = supportsResponseTimeout
|
|
170
|
+
? this.resolveDocumentRequestTimeout(options.timeoutMs)
|
|
171
|
+
: undefined;
|
|
172
|
+
const response = await this.sendJsonRpcRequest(request.method, request.params, this.resolveWatchdogTimeout(options.timeoutMs), { requestTimeoutMs });
|
|
173
|
+
const result = mapDocumentLifecycleResult(operation.operationId, response, sessionId, operation.operationId === 'doc.save' ? request.params.path === undefined : undefined);
|
|
174
|
+
if (operation.operationId === 'doc.close')
|
|
175
|
+
this.documentRpcSessions.delete(sessionId);
|
|
176
|
+
return result;
|
|
177
|
+
}
|
|
178
|
+
if (this.processMode === 'document') {
|
|
179
|
+
throw new SuperDocCliError(`Standalone document host does not support ${operation.operationId} through structured RPC v0.`, {
|
|
180
|
+
code: 'DOCUMENT_RPC_INPUT_UNSUPPORTED',
|
|
181
|
+
details: { operationId: operation.operationId },
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
const cliHostRequestTimeoutMs = this.requestTimeoutMs ?? HOST_DEFAULT_REQUEST_TIMEOUT_MS;
|
|
185
|
+
if (options.timeoutMs !== undefined && options.timeoutMs > cliHostRequestTimeoutMs) {
|
|
186
|
+
throw new SuperDocCliError(`CLI host cannot honor timeoutMs=${options.timeoutMs} above its ${cliHostRequestTimeoutMs}ms request ceiling.`, {
|
|
187
|
+
code: 'DOCUMENT_RPC_INPUT_UNSUPPORTED',
|
|
188
|
+
details: {
|
|
189
|
+
feature: DOCUMENT_RPC_REQUEST_TIMEOUT_FEATURE,
|
|
190
|
+
operationId: operation.operationId,
|
|
191
|
+
timeoutMs: options.timeoutMs,
|
|
192
|
+
hostRequestTimeoutMs: cliHostRequestTimeoutMs,
|
|
193
|
+
},
|
|
194
|
+
});
|
|
195
|
+
}
|
|
125
196
|
const argv = buildOperationArgv(operation, params, options, this.requestTimeoutMs, this.defaultChangeMode, this.user);
|
|
126
197
|
const stdinBase64 = options.stdinBytes ? Buffer.from(options.stdinBytes).toString('base64') : '';
|
|
127
198
|
const watchdogTimeout = this.resolveWatchdogTimeout(options.timeoutMs);
|
|
@@ -136,16 +207,16 @@ export class HostTransport {
|
|
|
136
207
|
});
|
|
137
208
|
}
|
|
138
209
|
const resultRecord = response;
|
|
139
|
-
return resultRecord.data;
|
|
210
|
+
return mapCliInvocationResult(operation, resultRecord.data);
|
|
140
211
|
}
|
|
141
212
|
async ensureConnected() {
|
|
142
|
-
if (this.child && !this.child.killed) {
|
|
143
|
-
return;
|
|
144
|
-
}
|
|
145
213
|
if (this.connecting) {
|
|
146
214
|
await this.connecting;
|
|
147
215
|
return;
|
|
148
216
|
}
|
|
217
|
+
if (this.child && !this.child.killed) {
|
|
218
|
+
return;
|
|
219
|
+
}
|
|
149
220
|
this.connecting = this.startHostProcess();
|
|
150
221
|
try {
|
|
151
222
|
await this.connecting;
|
|
@@ -155,12 +226,14 @@ export class HostTransport {
|
|
|
155
226
|
}
|
|
156
227
|
}
|
|
157
228
|
async startHostProcess() {
|
|
158
|
-
const { command, prefixArgs } = resolveInvocation(this.
|
|
159
|
-
const args =
|
|
229
|
+
const { command, prefixArgs } = resolveInvocation(this.hostBin);
|
|
230
|
+
const args = this.processMode === 'document'
|
|
231
|
+
? buildDocumentHostSpawnArgs(prefixArgs)
|
|
232
|
+
: buildHostSpawnArgs(prefixArgs, { requestTimeoutMs: this.requestTimeoutMs });
|
|
160
233
|
const child = spawn(command, args, {
|
|
161
234
|
env: {
|
|
162
235
|
...process.env,
|
|
163
|
-
...
|
|
236
|
+
...this.env,
|
|
164
237
|
},
|
|
165
238
|
stdio: ['pipe', 'pipe', 'pipe'],
|
|
166
239
|
});
|
|
@@ -239,7 +312,14 @@ export class HostTransport {
|
|
|
239
312
|
details: { features },
|
|
240
313
|
});
|
|
241
314
|
}
|
|
242
|
-
|
|
315
|
+
const requiredFeatures = this.processMode === 'document'
|
|
316
|
+
? [
|
|
317
|
+
...DOCUMENT_HOST_REQUIRED_FEATURES,
|
|
318
|
+
...(this.defaultChangeMode === undefined ? [] : [DOCUMENT_RPC_DEFAULT_CHANGE_MODE_FEATURE]),
|
|
319
|
+
...(this.requestTimeoutMs === undefined ? [] : [DOCUMENT_RPC_REQUEST_TIMEOUT_FEATURE]),
|
|
320
|
+
]
|
|
321
|
+
: CLI_HOST_REQUIRED_FEATURES;
|
|
322
|
+
for (const requiredFeature of requiredFeatures) {
|
|
243
323
|
if (!features.includes(requiredFeature)) {
|
|
244
324
|
throw new SuperDocCliError(`Host does not support required feature: ${requiredFeature}`, {
|
|
245
325
|
code: 'HOST_HANDSHAKE_FAILED',
|
|
@@ -247,11 +327,27 @@ export class HostTransport {
|
|
|
247
327
|
});
|
|
248
328
|
}
|
|
249
329
|
}
|
|
330
|
+
this.hostFeatures.clear();
|
|
331
|
+
for (const feature of features)
|
|
332
|
+
this.hostFeatures.add(feature);
|
|
250
333
|
}
|
|
251
334
|
resolveWatchdogTimeout(timeoutMsOverride) {
|
|
252
335
|
return resolveJsWatchdogTimeout(this.watchdogTimeoutMs, this.requestTimeoutMs, timeoutMsOverride);
|
|
253
336
|
}
|
|
254
|
-
|
|
337
|
+
resolveDocumentRequestTimeout(timeoutMsOverride) {
|
|
338
|
+
const requestTimeoutMs = timeoutMsOverride ?? this.requestTimeoutMs;
|
|
339
|
+
if (requestTimeoutMs === undefined)
|
|
340
|
+
return undefined;
|
|
341
|
+
if (this.hostFeatures.has(DOCUMENT_RPC_REQUEST_TIMEOUT_FEATURE))
|
|
342
|
+
return requestTimeoutMs;
|
|
343
|
+
if (this.processMode === 'cli' && timeoutMsOverride === undefined)
|
|
344
|
+
return undefined;
|
|
345
|
+
throw new SuperDocCliError(`Structured document RPC host does not support ${DOCUMENT_RPC_REQUEST_TIMEOUT_FEATURE}.`, {
|
|
346
|
+
code: 'DOCUMENT_RPC_INPUT_UNSUPPORTED',
|
|
347
|
+
details: { feature: DOCUMENT_RPC_REQUEST_TIMEOUT_FEATURE },
|
|
348
|
+
});
|
|
349
|
+
}
|
|
350
|
+
async sendJsonRpcRequest(method, params, watchdogTimeoutMs, metadata = {}) {
|
|
255
351
|
const child = this.child;
|
|
256
352
|
if (!child || !child.stdin.writable) {
|
|
257
353
|
throw new SuperDocCliError('Host process is not available.', {
|
|
@@ -271,6 +367,7 @@ export class HostTransport {
|
|
|
271
367
|
id,
|
|
272
368
|
method,
|
|
273
369
|
params,
|
|
370
|
+
...(metadata.requestTimeoutMs === undefined ? {} : { requestTimeoutMs: metadata.requestTimeoutMs }),
|
|
274
371
|
});
|
|
275
372
|
const promise = new Promise((resolve, reject) => {
|
|
276
373
|
const timer = setTimeout(() => {
|
|
@@ -346,6 +443,7 @@ export class HostTransport {
|
|
|
346
443
|
const error = rawError;
|
|
347
444
|
const data = error.data;
|
|
348
445
|
const cliCode = typeof data?.cliCode === 'string' ? data.cliCode : undefined;
|
|
446
|
+
const domainCode = typeof data?.domainCode === 'string' ? data.domainCode : undefined;
|
|
349
447
|
const cliMessage = typeof data?.message === 'string' ? data.message : undefined;
|
|
350
448
|
const exitCode = typeof data?.exitCode === 'number' ? data.exitCode : undefined;
|
|
351
449
|
if (cliCode) {
|
|
@@ -355,6 +453,16 @@ export class HostTransport {
|
|
|
355
453
|
exitCode,
|
|
356
454
|
});
|
|
357
455
|
}
|
|
456
|
+
if (domainCode) {
|
|
457
|
+
return new SuperDocCliError(error.message, {
|
|
458
|
+
code: domainCode,
|
|
459
|
+
details: {
|
|
460
|
+
...(data?.details === undefined ? {} : { domainDetails: data.details }),
|
|
461
|
+
...(data?.stage === undefined ? {} : { stage: data.stage }),
|
|
462
|
+
...(data?.byteLength === undefined ? {} : { byteLength: data.byteLength }),
|
|
463
|
+
},
|
|
464
|
+
});
|
|
465
|
+
}
|
|
358
466
|
if (error.code === JSON_RPC_TIMEOUT_CODE) {
|
|
359
467
|
return new SuperDocCliError(error.message, {
|
|
360
468
|
code: 'TIMEOUT',
|
|
@@ -370,6 +478,8 @@ export class HostTransport {
|
|
|
370
478
|
this.cleanupProcess(error);
|
|
371
479
|
}
|
|
372
480
|
cleanupProcess(error) {
|
|
481
|
+
this.hostFeatures.clear();
|
|
482
|
+
this.documentRpcSessions.clear();
|
|
373
483
|
const child = this.child;
|
|
374
484
|
if (child) {
|
|
375
485
|
child.removeAllListeners();
|
package/dist/runtime/process.cjs
CHANGED
|
@@ -2,21 +2,49 @@
|
|
|
2
2
|
|
|
3
3
|
var host = require('./host.cjs');
|
|
4
4
|
var embeddedCli = require('./embedded-cli.cjs');
|
|
5
|
+
var embeddedDocumentHost = require('./embedded-document-host.cjs');
|
|
5
6
|
var debugTrace = require('./debug-trace.cjs');
|
|
7
|
+
var errors = require('./errors.cjs');
|
|
6
8
|
|
|
9
|
+
function resolveRuntimeProcess(options = {}, embedded = {
|
|
10
|
+
cli: embeddedCli.resolveEmbeddedCliBinary,
|
|
11
|
+
documentHost: embeddedDocumentHost.resolveEmbeddedDocumentHostBinary,
|
|
12
|
+
}) {
|
|
13
|
+
const configuredDocumentHostPath = options.documentHostPath;
|
|
14
|
+
if (configuredDocumentHostPath !== undefined && configuredDocumentHostPath.trim().length === 0) {
|
|
15
|
+
throw new errors.SuperDocCliError('documentHostPath must be a non-empty path.', {
|
|
16
|
+
code: 'INVALID_ARGUMENT',
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
const configuredDocumentHostBin = options.env?.SUPERDOC_SDK_DOCUMENT_HOST_BIN ?? process.env.SUPERDOC_SDK_DOCUMENT_HOST_BIN;
|
|
20
|
+
const documentHostBin = configuredDocumentHostPath ??
|
|
21
|
+
(configuredDocumentHostBin === 'embedded' ? embedded.documentHost() : configuredDocumentHostBin);
|
|
22
|
+
if (documentHostBin !== undefined && documentHostBin.trim().length === 0) {
|
|
23
|
+
throw new errors.SuperDocCliError('SUPERDOC_SDK_DOCUMENT_HOST_BIN must be a non-empty path.', {
|
|
24
|
+
code: 'INVALID_ARGUMENT',
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
if (documentHostBin !== undefined) {
|
|
28
|
+
return { hostBin: documentHostBin, processMode: 'document' };
|
|
29
|
+
}
|
|
30
|
+
return {
|
|
31
|
+
hostBin: options.env?.SUPERDOC_CLI_BIN ?? process.env.SUPERDOC_CLI_BIN ?? embedded.cli(),
|
|
32
|
+
processMode: 'cli',
|
|
33
|
+
};
|
|
34
|
+
}
|
|
7
35
|
/**
|
|
8
|
-
* Internal runtime that delegates
|
|
36
|
+
* Internal runtime that delegates operations to a persistent host transport.
|
|
9
37
|
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
38
|
+
* Uses the standalone document host when explicitly configured. Otherwise it
|
|
39
|
+
* preserves the embedded CLI compatibility path.
|
|
12
40
|
*/
|
|
13
41
|
class SuperDocRuntime {
|
|
14
42
|
transport;
|
|
15
43
|
constructor(options = {}) {
|
|
16
|
-
const
|
|
44
|
+
const runtimeProcess = resolveRuntimeProcess(options);
|
|
17
45
|
this.transport = new host.HostTransport({
|
|
18
|
-
cliBin,
|
|
19
46
|
...options,
|
|
47
|
+
...runtimeProcess,
|
|
20
48
|
});
|
|
21
49
|
}
|
|
22
50
|
async connect() {
|
|
@@ -59,3 +87,4 @@ class SuperDocRuntime {
|
|
|
59
87
|
}
|
|
60
88
|
|
|
61
89
|
exports.SuperDocRuntime = SuperDocRuntime;
|
|
90
|
+
exports.resolveRuntimeProcess = resolveRuntimeProcess;
|
|
@@ -1,9 +1,18 @@
|
|
|
1
1
|
import type { DocumentRuntimeKind, InvokeOptions, OperationParamSpec, OperationSpec, RuntimeInvoker, SuperDocClientOptions } from './transport-common.js';
|
|
2
|
+
type RuntimeProcessResolution = {
|
|
3
|
+
hostBin: string;
|
|
4
|
+
processMode: 'cli' | 'document';
|
|
5
|
+
};
|
|
6
|
+
type EmbeddedRuntimeResolvers = {
|
|
7
|
+
cli: () => string;
|
|
8
|
+
documentHost: () => string;
|
|
9
|
+
};
|
|
10
|
+
export declare function resolveRuntimeProcess(options?: SuperDocClientOptions, embedded?: EmbeddedRuntimeResolvers): RuntimeProcessResolution;
|
|
2
11
|
/**
|
|
3
|
-
* Internal runtime that delegates
|
|
12
|
+
* Internal runtime that delegates operations to a persistent host transport.
|
|
4
13
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
14
|
+
* Uses the standalone document host when explicitly configured. Otherwise it
|
|
15
|
+
* preserves the embedded CLI compatibility path.
|
|
7
16
|
*/
|
|
8
17
|
export declare class SuperDocRuntime {
|
|
9
18
|
private readonly transport;
|
package/dist/runtime/process.js
CHANGED
|
@@ -1,19 +1,47 @@
|
|
|
1
1
|
import { HostTransport } from './host.js';
|
|
2
2
|
import { resolveEmbeddedCliBinary } from './embedded-cli.js';
|
|
3
|
+
import { resolveEmbeddedDocumentHostBinary } from './embedded-document-host.js';
|
|
3
4
|
import { writeSdkDebugTrace } from './debug-trace.js';
|
|
5
|
+
import { SuperDocCliError } from './errors.js';
|
|
6
|
+
export function resolveRuntimeProcess(options = {}, embedded = {
|
|
7
|
+
cli: resolveEmbeddedCliBinary,
|
|
8
|
+
documentHost: resolveEmbeddedDocumentHostBinary,
|
|
9
|
+
}) {
|
|
10
|
+
const configuredDocumentHostPath = options.documentHostPath;
|
|
11
|
+
if (configuredDocumentHostPath !== undefined && configuredDocumentHostPath.trim().length === 0) {
|
|
12
|
+
throw new SuperDocCliError('documentHostPath must be a non-empty path.', {
|
|
13
|
+
code: 'INVALID_ARGUMENT',
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
const configuredDocumentHostBin = options.env?.SUPERDOC_SDK_DOCUMENT_HOST_BIN ?? process.env.SUPERDOC_SDK_DOCUMENT_HOST_BIN;
|
|
17
|
+
const documentHostBin = configuredDocumentHostPath ??
|
|
18
|
+
(configuredDocumentHostBin === 'embedded' ? embedded.documentHost() : configuredDocumentHostBin);
|
|
19
|
+
if (documentHostBin !== undefined && documentHostBin.trim().length === 0) {
|
|
20
|
+
throw new SuperDocCliError('SUPERDOC_SDK_DOCUMENT_HOST_BIN must be a non-empty path.', {
|
|
21
|
+
code: 'INVALID_ARGUMENT',
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
if (documentHostBin !== undefined) {
|
|
25
|
+
return { hostBin: documentHostBin, processMode: 'document' };
|
|
26
|
+
}
|
|
27
|
+
return {
|
|
28
|
+
hostBin: options.env?.SUPERDOC_CLI_BIN ?? process.env.SUPERDOC_CLI_BIN ?? embedded.cli(),
|
|
29
|
+
processMode: 'cli',
|
|
30
|
+
};
|
|
31
|
+
}
|
|
4
32
|
/**
|
|
5
|
-
* Internal runtime that delegates
|
|
33
|
+
* Internal runtime that delegates operations to a persistent host transport.
|
|
6
34
|
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
35
|
+
* Uses the standalone document host when explicitly configured. Otherwise it
|
|
36
|
+
* preserves the embedded CLI compatibility path.
|
|
9
37
|
*/
|
|
10
38
|
export class SuperDocRuntime {
|
|
11
39
|
transport;
|
|
12
40
|
constructor(options = {}) {
|
|
13
|
-
const
|
|
41
|
+
const runtimeProcess = resolveRuntimeProcess(options);
|
|
14
42
|
this.transport = new HostTransport({
|
|
15
|
-
cliBin,
|
|
16
43
|
...options,
|
|
44
|
+
...runtimeProcess,
|
|
17
45
|
});
|
|
18
46
|
}
|
|
19
47
|
async connect() {
|
|
@@ -163,5 +163,6 @@ function buildOperationArgv(operation, params, options, runtimeTimeoutMs, defaul
|
|
|
163
163
|
return argv;
|
|
164
164
|
}
|
|
165
165
|
|
|
166
|
+
exports.applyOperationParamAliases = applyOperationParamAliases;
|
|
166
167
|
exports.buildOperationArgv = buildOperationArgv;
|
|
167
168
|
exports.resolveInvocation = resolveInvocation;
|
|
@@ -34,6 +34,14 @@ export interface UserIdentity {
|
|
|
34
34
|
}
|
|
35
35
|
export interface SuperDocClientOptions {
|
|
36
36
|
env?: Record<string, string | undefined>;
|
|
37
|
+
/**
|
|
38
|
+
* Standalone document-host entry to use instead of the embedded CLI.
|
|
39
|
+
*
|
|
40
|
+
* The host-only path supports local lifecycle methods and generated Document
|
|
41
|
+
* API operations through structured RPC. Interface-only conveniences fail
|
|
42
|
+
* without CLI fallback.
|
|
43
|
+
*/
|
|
44
|
+
documentHostPath?: string;
|
|
37
45
|
/**
|
|
38
46
|
* Default document engine for `client.open(...)`. Explicit `runtime` on an
|
|
39
47
|
* individual open call takes precedence.
|
|
@@ -42,11 +50,13 @@ export interface SuperDocClientOptions {
|
|
|
42
50
|
startupTimeoutMs?: number;
|
|
43
51
|
shutdownTimeoutMs?: number;
|
|
44
52
|
/**
|
|
45
|
-
* Upper bound (ms) on how long the host process may spend on a
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
*
|
|
49
|
-
*
|
|
53
|
+
* Upper bound (ms) on how long the host process may spend on a request
|
|
54
|
+
* before it returns a `RequestTimeout` error. Retry-safe structured document
|
|
55
|
+
* requests carry this budget as transport metadata; requests that may apply
|
|
56
|
+
* non-idempotent side effects await a definitive result instead. CLI-host
|
|
57
|
+
* requests also receive the budget through `--request-timeout-ms` at spawn.
|
|
58
|
+
* Raise this for documents that legitimately need more than 30s to process;
|
|
59
|
+
* the SDK widens its own JSON-RPC watchdog to match.
|
|
50
60
|
*
|
|
51
61
|
* Defaults to the host's own default (30s) when unset.
|
|
52
62
|
*/
|
|
@@ -54,11 +64,13 @@ export interface SuperDocClientOptions {
|
|
|
54
64
|
/**
|
|
55
65
|
* JS-side watchdog (ms) the SDK waits for a host reply before giving up.
|
|
56
66
|
* Independent of {@link requestTimeoutMs} (which controls the host-side
|
|
57
|
-
* operation budget).
|
|
58
|
-
*
|
|
59
|
-
*
|
|
60
|
-
*
|
|
61
|
-
*
|
|
67
|
+
* operation budget). Structured requests that may apply non-idempotent side
|
|
68
|
+
* effects wait for a definitive host result instead of applying an unsafe
|
|
69
|
+
* response deadline. Most callers should leave this at its default and use
|
|
70
|
+
* {@link requestTimeoutMs} as the single timeout knob for retry-safe work —
|
|
71
|
+
* `resolveWatchdogTimeout` already widens the watchdog above the host ceiling
|
|
72
|
+
* automatically. Override only when you need to detect a hung or crashed host
|
|
73
|
+
* faster than the operation budget allows.
|
|
62
74
|
*/
|
|
63
75
|
watchdogTimeoutMs?: number;
|
|
64
76
|
maxQueueDepth?: number;
|
|
@@ -70,6 +82,12 @@ export interface CliInvocation {
|
|
|
70
82
|
prefixArgs: string[];
|
|
71
83
|
}
|
|
72
84
|
export declare function resolveInvocation(cliBin: string): CliInvocation;
|
|
85
|
+
/**
|
|
86
|
+
* Resolve contract-shaped param aliases onto their canonical generated names.
|
|
87
|
+
* Returns the same object when no alias applies. Throws on a conflicting
|
|
88
|
+
* canonical/alias pair so divergent values can never be silently coalesced.
|
|
89
|
+
*/
|
|
90
|
+
export declare function applyOperationParamAliases(operation: OperationSpec, params: Record<string, unknown>): Record<string, unknown>;
|
|
73
91
|
/**
|
|
74
92
|
* Build the CLI argument vector for an operation invocation.
|
|
75
93
|
*
|
|
@@ -54,7 +54,7 @@ function assertKnownTemplatesApplyParams(operation, params) {
|
|
|
54
54
|
* Returns the same object when no alias applies. Throws on a conflicting
|
|
55
55
|
* canonical/alias pair so divergent values can never be silently coalesced.
|
|
56
56
|
*/
|
|
57
|
-
function applyOperationParamAliases(operation, params) {
|
|
57
|
+
export function applyOperationParamAliases(operation, params) {
|
|
58
58
|
const aliasMap = OPERATION_PARAM_ALIASES[operation.operationId];
|
|
59
59
|
if (!aliasMap)
|
|
60
60
|
return params;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@superdoc/sdk",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.7.0",
|
|
4
4
|
"description": "Node SDK for SuperDoc, wrapping the SuperDoc CLI to read and edit .docx files from JavaScript and TypeScript.",
|
|
5
5
|
"private": false,
|
|
6
6
|
"license": "AGPL-3.0",
|
|
@@ -37,11 +37,11 @@
|
|
|
37
37
|
"typescript": "^5.9.2"
|
|
38
38
|
},
|
|
39
39
|
"optionalDependencies": {
|
|
40
|
-
"@superdoc/sdk-darwin-arm64": "2.
|
|
41
|
-
"@superdoc/sdk-
|
|
42
|
-
"@superdoc/sdk-linux-
|
|
43
|
-
"@superdoc/sdk-
|
|
44
|
-
"@superdoc/sdk-windows-x64": "2.
|
|
40
|
+
"@superdoc/sdk-darwin-arm64": "2.7.0",
|
|
41
|
+
"@superdoc/sdk-darwin-x64": "2.7.0",
|
|
42
|
+
"@superdoc/sdk-linux-x64": "2.7.0",
|
|
43
|
+
"@superdoc/sdk-linux-arm64": "2.7.0",
|
|
44
|
+
"@superdoc/sdk-windows-x64": "2.7.0"
|
|
45
45
|
},
|
|
46
46
|
"publishConfig": {
|
|
47
47
|
"access": "public"
|
|
@@ -50,6 +50,7 @@
|
|
|
50
50
|
"build": "rm -rf dist && node scripts/embed-prompts.mjs && node scripts/embed-tools.mjs && tsc && rollup -c rollup.cjs.config.mjs && rm -rf dist/prompts && mkdir -p dist/prompts && cp src/prompts/*.md dist/prompts/ && pnpm run audit:publish",
|
|
51
51
|
"audit:publish": "node ../../../../scripts/audit-publish-artifact.mjs dist --label sdk-node-dist",
|
|
52
52
|
"typecheck": "tsc --noEmit",
|
|
53
|
+
"test:document-host": "bun test src/runtime/__tests__/host-spawn-args.test.ts src/runtime/__tests__/document-rpc.test.ts src/__tests__/structured-document-rpc.e2e.test.ts src/__tests__/request-timeout-ms.e2e.test.ts",
|
|
53
54
|
"smoke:product-action": "node scripts/product-action-smoke.mjs"
|
|
54
55
|
}
|
|
55
56
|
}
|
|
Binary file
|
|
Binary file
|
package/tools/catalog.json
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
"tools": [
|
|
6
6
|
{
|
|
7
7
|
"toolName": "superdoc_get_content",
|
|
8
|
-
"description": "Read document content in various formats. Call this first in any workflow to understand document structure before making edits. Action \"blocks\" returns structured block data with nodeId, nodeType, textPreview, optional full text when includeText:true, formatting properties (fontFamily, fontSize, color, bold, underline, alignment), and ref handles for immediate use with superdoc_edit or superdoc_format. When you need to evaluate or rewrite existing paragraphs or clauses, prefer action \"blocks\" with includeText:true so you can identify the correct block and then target it by nodeId. Actions \"text\", \"markdown\", and \"html\" return compact strings. Actions \"markdown_projection\" and \"html_projection\" return detailed async projections with review modes, scopes, diagnostics, annotations, block maps, and optional source maps. Projection source targets use tracked coordinates and are valid only at evaluatedRevision; after any mutation, reproject before using them. Treat omitted or partially emitted annotations according to their status instead of guessing an anchor from rendered text. Action \"info\" returns document metadata: word count, paragraph count, page count, outline, available styles, and capability flags. The \"blocks\" action supports pagination via \"offset\" and \"limit\",
|
|
8
|
+
"description": "Read document content in various formats. Call this first in any workflow to understand document structure before making edits. Action \"blocks\" returns structured block data with nodeId, nodeType, textPreview, optional full text when includeText:true, formatting properties (fontFamily, fontSize, color, bold, underline, alignment), and ref handles for immediate use with superdoc_edit or superdoc_format. Its optional reviewMode selects final, original, or redline numbering metadata without filtering blocks. When you need to evaluate or rewrite existing paragraphs or clauses, prefer action \"blocks\" with includeText:true so you can identify the correct block and then target it by nodeId. Actions \"text\", \"markdown\", and \"html\" return compact strings. Actions \"markdown_projection\" and \"html_projection\" return detailed async projections with review modes, scopes, diagnostics, annotations, block maps, and optional source maps. Projection source targets use tracked coordinates and are valid only at evaluatedRevision; after any mutation, reproject before using them. Treat omitted or partially emitted annotations according to their status instead of guessing an anchor from rendered text. Action \"info\" returns document metadata: word count, paragraph count, page count, outline, available styles, and capability flags. The \"blocks\" action supports pagination via \"offset\" and \"limit\", filtering via \"nodeTypes\", and numbering projection via \"reviewMode\". Other actions ignore pagination and filtering parameters. This tool never modifies the document. Do NOT call superdoc_edit or superdoc_format without first reading blocks to get valid refs and formatting reference values.\n\nEXAMPLES:\n 1. {\"action\":\"blocks\"}\n 2. {\"action\":\"blocks\",\"includeText\":true,\"offset\":0,\"limit\":20,\"reviewMode\":\"final\"}\n 3. {\"action\":\"blocks\",\"offset\":0,\"limit\":20,\"nodeTypes\":[\"heading\",\"paragraph\"]}\n 4. {\"action\":\"text\"}\n 5. {\"action\":\"info\"}\n 6. {\"action\":\"html_projection\",\"reviewMode\":\"redline\",\"includeSourceMap\":true}\n 7. {\"action\":\"markdown_projection\",\"reviewMode\":\"original\",\"scope\":{\"kind\":\"block\",\"nodeType\":\"paragraph\",\"nodeId\":\"paragraph-id\"},\"includeSourceMap\":true}",
|
|
9
9
|
"inputSchema": {
|
|
10
10
|
"type": "object",
|
|
11
11
|
"properties": {
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
},
|
|
34
34
|
"reviewMode": {
|
|
35
35
|
"$ref": "#/$defs/SDProjectionReviewMode",
|
|
36
|
-
"description": "Only for actions 'markdown_projection', 'html_projection'. Omit for other actions."
|
|
36
|
+
"description": "Only for actions 'markdown_projection', 'html_projection', 'blocks'. Omit for other actions."
|
|
37
37
|
},
|
|
38
38
|
"scope": {
|
|
39
39
|
"$ref": "#/$defs/SDProjectionScope",
|
package/tools/tools-policy.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"tools": [
|
|
4
4
|
{
|
|
5
5
|
"name": "superdoc_get_content",
|
|
6
|
-
"description": "Read document content in various formats. Call this first in any workflow to understand document structure before making edits. Action \"blocks\" returns structured block data with nodeId, nodeType, textPreview, optional full text when includeText:true, formatting properties (fontFamily, fontSize, color, bold, underline, alignment), and ref handles for immediate use with superdoc_edit or superdoc_format. When you need to evaluate or rewrite existing paragraphs or clauses, prefer action \"blocks\" with includeText:true so you can identify the correct block and then target it by nodeId. Actions \"text\", \"markdown\", and \"html\" return compact strings. Actions \"markdown_projection\" and \"html_projection\" return detailed async projections with review modes, scopes, diagnostics, annotations, block maps, and optional source maps. Projection source targets use tracked coordinates and are valid only at evaluatedRevision; after any mutation, reproject before using them. Treat omitted or partially emitted annotations according to their status instead of guessing an anchor from rendered text. Action \"info\" returns document metadata: word count, paragraph count, page count, outline, available styles, and capability flags. The \"blocks\" action supports pagination via \"offset\" and \"limit\",
|
|
6
|
+
"description": "Read document content in various formats. Call this first in any workflow to understand document structure before making edits. Action \"blocks\" returns structured block data with nodeId, nodeType, textPreview, optional full text when includeText:true, formatting properties (fontFamily, fontSize, color, bold, underline, alignment), and ref handles for immediate use with superdoc_edit or superdoc_format. Its optional reviewMode selects final, original, or redline numbering metadata without filtering blocks. When you need to evaluate or rewrite existing paragraphs or clauses, prefer action \"blocks\" with includeText:true so you can identify the correct block and then target it by nodeId. Actions \"text\", \"markdown\", and \"html\" return compact strings. Actions \"markdown_projection\" and \"html_projection\" return detailed async projections with review modes, scopes, diagnostics, annotations, block maps, and optional source maps. Projection source targets use tracked coordinates and are valid only at evaluatedRevision; after any mutation, reproject before using them. Treat omitted or partially emitted annotations according to their status instead of guessing an anchor from rendered text. Action \"info\" returns document metadata: word count, paragraph count, page count, outline, available styles, and capability flags. The \"blocks\" action supports pagination via \"offset\" and \"limit\", filtering via \"nodeTypes\", and numbering projection via \"reviewMode\". Other actions ignore pagination and filtering parameters. This tool never modifies the document. Do NOT call superdoc_edit or superdoc_format without first reading blocks to get valid refs and formatting reference values.\n\nEXAMPLES:\n 1. {\"action\":\"blocks\"}\n 2. {\"action\":\"blocks\",\"includeText\":true,\"offset\":0,\"limit\":20,\"reviewMode\":\"final\"}\n 3. {\"action\":\"blocks\",\"offset\":0,\"limit\":20,\"nodeTypes\":[\"heading\",\"paragraph\"]}\n 4. {\"action\":\"text\"}\n 5. {\"action\":\"info\"}\n 6. {\"action\":\"html_projection\",\"reviewMode\":\"redline\",\"includeSourceMap\":true}\n 7. {\"action\":\"markdown_projection\",\"reviewMode\":\"original\",\"scope\":{\"kind\":\"block\",\"nodeType\":\"paragraph\",\"nodeId\":\"paragraph-id\"},\"includeSourceMap\":true}",
|
|
7
7
|
"input_schema": {
|
|
8
8
|
"type": "object",
|
|
9
9
|
"properties": {
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
},
|
|
32
32
|
"reviewMode": {
|
|
33
33
|
"$ref": "#/$defs/SDProjectionReviewMode",
|
|
34
|
-
"description": "Only for actions 'markdown_projection', 'html_projection'. Omit for other actions."
|
|
34
|
+
"description": "Only for actions 'markdown_projection', 'html_projection', 'blocks'. Omit for other actions."
|
|
35
35
|
},
|
|
36
36
|
"scope": {
|
|
37
37
|
"$ref": "#/$defs/SDProjectionScope",
|
package/tools/tools.generic.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"tools": [
|
|
4
4
|
{
|
|
5
5
|
"name": "superdoc_get_content",
|
|
6
|
-
"description": "Read document content in various formats. Call this first in any workflow to understand document structure before making edits. Action \"blocks\" returns structured block data with nodeId, nodeType, textPreview, optional full text when includeText:true, formatting properties (fontFamily, fontSize, color, bold, underline, alignment), and ref handles for immediate use with superdoc_edit or superdoc_format. When you need to evaluate or rewrite existing paragraphs or clauses, prefer action \"blocks\" with includeText:true so you can identify the correct block and then target it by nodeId. Actions \"text\", \"markdown\", and \"html\" return compact strings. Actions \"markdown_projection\" and \"html_projection\" return detailed async projections with review modes, scopes, diagnostics, annotations, block maps, and optional source maps. Projection source targets use tracked coordinates and are valid only at evaluatedRevision; after any mutation, reproject before using them. Treat omitted or partially emitted annotations according to their status instead of guessing an anchor from rendered text. Action \"info\" returns document metadata: word count, paragraph count, page count, outline, available styles, and capability flags. The \"blocks\" action supports pagination via \"offset\" and \"limit\",
|
|
6
|
+
"description": "Read document content in various formats. Call this first in any workflow to understand document structure before making edits. Action \"blocks\" returns structured block data with nodeId, nodeType, textPreview, optional full text when includeText:true, formatting properties (fontFamily, fontSize, color, bold, underline, alignment), and ref handles for immediate use with superdoc_edit or superdoc_format. Its optional reviewMode selects final, original, or redline numbering metadata without filtering blocks. When you need to evaluate or rewrite existing paragraphs or clauses, prefer action \"blocks\" with includeText:true so you can identify the correct block and then target it by nodeId. Actions \"text\", \"markdown\", and \"html\" return compact strings. Actions \"markdown_projection\" and \"html_projection\" return detailed async projections with review modes, scopes, diagnostics, annotations, block maps, and optional source maps. Projection source targets use tracked coordinates and are valid only at evaluatedRevision; after any mutation, reproject before using them. Treat omitted or partially emitted annotations according to their status instead of guessing an anchor from rendered text. Action \"info\" returns document metadata: word count, paragraph count, page count, outline, available styles, and capability flags. The \"blocks\" action supports pagination via \"offset\" and \"limit\", filtering via \"nodeTypes\", and numbering projection via \"reviewMode\". Other actions ignore pagination and filtering parameters. This tool never modifies the document. Do NOT call superdoc_edit or superdoc_format without first reading blocks to get valid refs and formatting reference values.\n\nEXAMPLES:\n 1. {\"action\":\"blocks\"}\n 2. {\"action\":\"blocks\",\"includeText\":true,\"offset\":0,\"limit\":20,\"reviewMode\":\"final\"}\n 3. {\"action\":\"blocks\",\"offset\":0,\"limit\":20,\"nodeTypes\":[\"heading\",\"paragraph\"]}\n 4. {\"action\":\"text\"}\n 5. {\"action\":\"info\"}\n 6. {\"action\":\"html_projection\",\"reviewMode\":\"redline\",\"includeSourceMap\":true}\n 7. {\"action\":\"markdown_projection\",\"reviewMode\":\"original\",\"scope\":{\"kind\":\"block\",\"nodeType\":\"paragraph\",\"nodeId\":\"paragraph-id\"},\"includeSourceMap\":true}",
|
|
7
7
|
"parameters": {
|
|
8
8
|
"type": "object",
|
|
9
9
|
"properties": {
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
},
|
|
32
32
|
"reviewMode": {
|
|
33
33
|
"$ref": "#/$defs/SDProjectionReviewMode",
|
|
34
|
-
"description": "Only for actions 'markdown_projection', 'html_projection'. Omit for other actions."
|
|
34
|
+
"description": "Only for actions 'markdown_projection', 'html_projection', 'blocks'. Omit for other actions."
|
|
35
35
|
},
|
|
36
36
|
"scope": {
|
|
37
37
|
"$ref": "#/$defs/SDProjectionScope",
|