@superdoc/sdk 2.6.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 (48) 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/generated/client.cjs +754 -770
  14. package/dist/generated/client.d.ts +9 -9
  15. package/dist/generated/client.js +754 -770
  16. package/dist/generated/contract.cjs +16170 -272
  17. package/dist/generated/contract.d.ts +38 -0
  18. package/dist/generated/contract.js +17411 -1510
  19. package/dist/index.cjs +5 -4
  20. package/dist/index.d.ts +2 -2
  21. package/dist/index.js +5 -4
  22. package/dist/introspection.cjs +59 -0
  23. package/dist/introspection.d.ts +3 -0
  24. package/dist/introspection.js +53 -0
  25. package/dist/runtime/document-rpc.cjs +179 -40
  26. package/dist/runtime/document-rpc.d.ts +13 -4
  27. package/dist/runtime/document-rpc.js +175 -40
  28. package/dist/runtime/embedded-cli.cjs +5 -68
  29. package/dist/runtime/embedded-cli.js +5 -67
  30. package/dist/runtime/embedded-document-host.cjs +28 -0
  31. package/dist/runtime/embedded-document-host.d.ts +1 -0
  32. package/dist/runtime/embedded-document-host.js +23 -0
  33. package/dist/runtime/embedded-platform.cjs +102 -0
  34. package/dist/runtime/embedded-platform.d.ts +5 -0
  35. package/dist/runtime/embedded-platform.js +93 -0
  36. package/dist/runtime/host.cjs +70 -19
  37. package/dist/runtime/host.d.ts +2 -0
  38. package/dist/runtime/host.js +70 -20
  39. package/dist/runtime/process.cjs +30 -9
  40. package/dist/runtime/process.d.ts +9 -0
  41. package/dist/runtime/process.js +29 -9
  42. package/dist/runtime/transport-common.cjs +1 -0
  43. package/dist/runtime/transport-common.d.ts +28 -10
  44. package/dist/runtime/transport-common.js +1 -1
  45. package/package.json +6 -6
  46. package/tools/__pycache__/__init__.cpython-311.pyc +0 -0
  47. package/tools/__pycache__/intent_dispatch_generated.cpython-311.pyc +0 -0
  48. package/tools/tools-policy.json +1 -1
package/dist/index.cjs CHANGED
@@ -4,6 +4,7 @@ var client = require('./generated/client.cjs');
4
4
  var contract = require('./generated/contract.cjs');
5
5
  var process = require('./runtime/process.cjs');
6
6
  var errors = require('./runtime/errors.cjs');
7
+ var introspection = require('./introspection.cjs');
7
8
  var skills = require('./skills.cjs');
8
9
  var tools = require('./tools.cjs');
9
10
  var intentDispatch_generated = require('./generated/intent-dispatch.generated.cjs');
@@ -145,11 +146,11 @@ class SuperDocClient {
145
146
  this.handles.set(contextId, handle);
146
147
  return handle;
147
148
  }
148
- async describe(params = {}, options) {
149
- return this.rawApi.describe(params, options);
149
+ async describe(_params = {}, _options) {
150
+ return introspection.describeContract();
150
151
  }
151
- async describeCommand(params, options) {
152
- return this.rawApi.describeCommand(params, options);
152
+ async describeCommand(params, _options) {
153
+ return introspection.describeContractOperation(params);
153
154
  }
154
155
  async dispose() {
155
156
  for (const handle of this.handles.values()) {
package/dist/index.d.ts CHANGED
@@ -74,8 +74,8 @@ export declare class SuperDocClient {
74
74
  * different session ids (useful for diff workflows).
75
75
  */
76
76
  open(params: DocOpenParams, options?: InvokeOptions): Promise<SuperDocDocument>;
77
- describe(params?: Record<string, unknown>, options?: InvokeOptions): Promise<unknown>;
78
- describeCommand(params: DocDescribeCommandParams, options?: InvokeOptions): Promise<unknown>;
77
+ describe(_params?: Record<string, unknown>, _options?: InvokeOptions): Promise<unknown>;
78
+ describeCommand(params: DocDescribeCommandParams, _options?: InvokeOptions): Promise<unknown>;
79
79
  dispose(): Promise<void>;
80
80
  /** @internal */
81
81
  removeHandle(sessionId: string): void;
package/dist/index.js CHANGED
@@ -2,6 +2,7 @@ import { createDocApi, createBoundDocApi, } from './generated/client.js';
2
2
  import { CONTRACT } from './generated/contract.js';
3
3
  import { SuperDocRuntime, } from './runtime/process.js';
4
4
  import { SuperDocCliError } from './runtime/errors.js';
5
+ import { describeContract, describeContractOperation } from './introspection.js';
5
6
  // ---------------------------------------------------------------------------
6
7
  // Session-bound runtime wrapper
7
8
  // ---------------------------------------------------------------------------
@@ -137,11 +138,11 @@ export class SuperDocClient {
137
138
  this.handles.set(contextId, handle);
138
139
  return handle;
139
140
  }
140
- async describe(params = {}, options) {
141
- return this.rawApi.describe(params, options);
141
+ async describe(_params = {}, _options) {
142
+ return describeContract();
142
143
  }
143
- async describeCommand(params, options) {
144
- return this.rawApi.describeCommand(params, options);
144
+ async describeCommand(params, _options) {
145
+ return describeContractOperation(params);
145
146
  }
146
147
  async dispose() {
147
148
  for (const handle of this.handles.values()) {
@@ -0,0 +1,59 @@
1
+ 'use strict';
2
+
3
+ var contract = require('./generated/contract.cjs');
4
+ var errors = require('./runtime/errors.cjs');
5
+
6
+ function cloneJson(value) {
7
+ return JSON.parse(JSON.stringify(value));
8
+ }
9
+ function detailParam(param) {
10
+ return {
11
+ name: param.name,
12
+ kind: param.kind,
13
+ ...(Object.prototype.hasOwnProperty.call(param, 'flag') ? { flag: param.flag } : {}),
14
+ type: param.type,
15
+ ...(Object.prototype.hasOwnProperty.call(param, 'required') ? { required: param.required } : {}),
16
+ ...(Object.prototype.hasOwnProperty.call(param, 'schema') ? { schema: param.schema } : {}),
17
+ };
18
+ }
19
+ function describeContract() {
20
+ return cloneJson(contract.CONTRACT.introspection.overview);
21
+ }
22
+ function describeContractOperation(params) {
23
+ const rawQuery = params?.operationId;
24
+ if (rawQuery == null || String(rawQuery).length === 0) {
25
+ throw new errors.SuperDocCliError('describe command: missing required input.operationId.', {
26
+ code: 'MISSING_REQUIRED',
27
+ exitCode: 1,
28
+ });
29
+ }
30
+ const query = String(rawQuery);
31
+ const normalizedQuery = query.trim().toLowerCase();
32
+ const index = Object.prototype.hasOwnProperty.call(contract.CONTRACT.introspection.lookup, normalizedQuery)
33
+ ? contract.CONTRACT.introspection.lookup[normalizedQuery]
34
+ : undefined;
35
+ if (typeof index !== 'number' ||
36
+ !Number.isInteger(index) ||
37
+ index < 0 ||
38
+ index >= contract.CONTRACT.introspection.overview.operations.length) {
39
+ throw new errors.SuperDocCliError(`Unknown operation: ${query}`, {
40
+ code: 'TARGET_NOT_FOUND',
41
+ details: { query },
42
+ exitCode: 1,
43
+ });
44
+ }
45
+ const summary = contract.CONTRACT.introspection.overview.operations[index];
46
+ const operation = contract.CONTRACT.operations[summary.id];
47
+ return cloneJson({
48
+ contractVersion: contract.CONTRACT.contractVersion,
49
+ query,
50
+ operation: {
51
+ ...summary,
52
+ params: operation.params.map(detailParam),
53
+ constraints: operation.constraints ?? null,
54
+ },
55
+ });
56
+ }
57
+
58
+ exports.describeContract = describeContract;
59
+ exports.describeContractOperation = describeContractOperation;
@@ -0,0 +1,3 @@
1
+ import { type ContractOverview } from './generated/contract.js';
2
+ export declare function describeContract(): ContractOverview;
3
+ export declare function describeContractOperation(params?: Record<string, unknown> | null): unknown;
@@ -0,0 +1,53 @@
1
+ import { CONTRACT } from './generated/contract.js';
2
+ import { SuperDocCliError } from './runtime/errors.js';
3
+ function cloneJson(value) {
4
+ return JSON.parse(JSON.stringify(value));
5
+ }
6
+ function detailParam(param) {
7
+ return {
8
+ name: param.name,
9
+ kind: param.kind,
10
+ ...(Object.prototype.hasOwnProperty.call(param, 'flag') ? { flag: param.flag } : {}),
11
+ type: param.type,
12
+ ...(Object.prototype.hasOwnProperty.call(param, 'required') ? { required: param.required } : {}),
13
+ ...(Object.prototype.hasOwnProperty.call(param, 'schema') ? { schema: param.schema } : {}),
14
+ };
15
+ }
16
+ export function describeContract() {
17
+ return cloneJson(CONTRACT.introspection.overview);
18
+ }
19
+ export function describeContractOperation(params) {
20
+ const rawQuery = params?.operationId;
21
+ if (rawQuery == null || String(rawQuery).length === 0) {
22
+ throw new SuperDocCliError('describe command: missing required input.operationId.', {
23
+ code: 'MISSING_REQUIRED',
24
+ exitCode: 1,
25
+ });
26
+ }
27
+ const query = String(rawQuery);
28
+ const normalizedQuery = query.trim().toLowerCase();
29
+ const index = Object.prototype.hasOwnProperty.call(CONTRACT.introspection.lookup, normalizedQuery)
30
+ ? CONTRACT.introspection.lookup[normalizedQuery]
31
+ : undefined;
32
+ if (typeof index !== 'number' ||
33
+ !Number.isInteger(index) ||
34
+ index < 0 ||
35
+ index >= CONTRACT.introspection.overview.operations.length) {
36
+ throw new SuperDocCliError(`Unknown operation: ${query}`, {
37
+ code: 'TARGET_NOT_FOUND',
38
+ details: { query },
39
+ exitCode: 1,
40
+ });
41
+ }
42
+ const summary = CONTRACT.introspection.overview.operations[index];
43
+ const operation = CONTRACT.operations[summary.id];
44
+ return cloneJson({
45
+ contractVersion: CONTRACT.contractVersion,
46
+ query,
47
+ operation: {
48
+ ...summary,
49
+ params: operation.params.map(detailParam),
50
+ constraints: operation.constraints ?? null,
51
+ },
52
+ });
53
+ }
@@ -2,19 +2,19 @@
2
2
 
3
3
  var node_crypto = require('node:crypto');
4
4
  var errors = require('./errors.cjs');
5
+ var transportCommon = require('./transport-common.cjs');
5
6
 
6
7
  const DOCUMENT_RPC_FEATURES = ['document.open', 'document.invoke', 'document.save', 'document.close'];
7
- const DOCUMENT_RPC_V0_OPERATIONS = new Set(['doc.getText', 'doc.insert', 'doc.save', 'doc.close']);
8
+ const DOCUMENT_RPC_DEFAULT_CHANGE_MODE_FEATURE = 'document.open.defaultChangeMode';
9
+ const DOCUMENT_RPC_SOURCE_SAVE_FEATURE = 'document.save.source';
10
+ const DOCUMENT_RPC_REQUEST_TIMEOUT_FEATURE = 'host.request.timeoutMs';
8
11
  const DOCUMENT_RPC_OPEN_FIELDS = new Set(['doc', 'sessionId', 'runtime']);
9
- const DOCUMENT_RPC_INSERT_FIELDS = new Set([
10
- 'value',
11
- 'type',
12
- 'target',
13
- 'ref',
14
- 'in',
15
- 'placement',
16
- 'content',
17
- 'nestingPolicy',
12
+ const DOCUMENT_RPC_SAVE_FIELDS = new Set(['sessionId', 'out', 'force', 'mode', 'inPlace']);
13
+ const DOCUMENT_API_OPTION_FIELDS = new Set(['expectedRevision', 'changeMode', 'dryRun', 'supportCheck']);
14
+ const DOCUMENT_API_REVISION_PREFLIGHT_OPERATIONS = new Set([
15
+ 'doc.history.redo',
16
+ 'doc.history.undo',
17
+ 'doc.plan.execute',
18
18
  ]);
19
19
  function unsupported(message, operationId) {
20
20
  return new errors.SuperDocCliError(message, {
@@ -22,21 +22,42 @@ function unsupported(message, operationId) {
22
22
  ...(operationId === undefined ? {} : { details: { operationId } }),
23
23
  });
24
24
  }
25
+ function buildDocumentAuthor(user) {
26
+ if (user === undefined)
27
+ return undefined;
28
+ if (typeof user !== 'object' || user === null || Array.isArray(user)) {
29
+ throw new errors.SuperDocCliError('user must be an object with a non-empty name.', {
30
+ code: 'INVALID_ARGUMENT',
31
+ });
32
+ }
33
+ const record = user;
34
+ if (typeof record.name !== 'string' || record.name.trim().length === 0) {
35
+ throw new errors.SuperDocCliError('user.name must be a non-empty string.', {
36
+ code: 'INVALID_ARGUMENT',
37
+ });
38
+ }
39
+ if (record.email !== undefined && typeof record.email !== 'string') {
40
+ throw new errors.SuperDocCliError('user.email must be a string.', {
41
+ code: 'INVALID_ARGUMENT',
42
+ });
43
+ }
44
+ return {
45
+ name: record.name,
46
+ ...(record.email === undefined ? {} : { email: record.email }),
47
+ };
48
+ }
25
49
  function documentRpcEnabled(env) {
26
50
  return (env?.SUPERDOC_SDK_DOCUMENT_RPC ?? process.env.SUPERDOC_SDK_DOCUMENT_RPC) === '1';
27
51
  }
28
52
  function supportsDocumentRpc(features) {
29
53
  return DOCUMENT_RPC_FEATURES.every((feature) => features.has(feature));
30
54
  }
31
- function hasUnsupportedInvokeOptions(options) {
32
- return (options.stdinBytes !== undefined ||
33
- options.dryRun !== undefined ||
34
- options.expectedRevision !== undefined ||
35
- options.changeMode !== undefined);
36
- }
37
55
  function canOpenWithDocumentRpc(params, options) {
38
- if (hasUnsupportedInvokeOptions(options))
56
+ if (options.stdinBytes !== undefined)
57
+ return false;
58
+ if (options.dryRun !== undefined || options.expectedRevision !== undefined || options.changeMode !== undefined) {
39
59
  return false;
60
+ }
40
61
  if (typeof params.doc !== 'string' || params.doc.trim().length === 0 || params.doc === '-')
41
62
  return false;
42
63
  if (params.runtime !== undefined && params.runtime !== 'v2')
@@ -46,11 +67,17 @@ function canOpenWithDocumentRpc(params, options) {
46
67
  }
47
68
  return Object.entries(params).every(([key, value]) => value === undefined || DOCUMENT_RPC_OPEN_FIELDS.has(key));
48
69
  }
49
- function buildDocumentOpenParams(params) {
70
+ function buildDocumentOpenParams(params, user, defaultChangeMode) {
50
71
  const sessionId = typeof params.sessionId === 'string' && params.sessionId.length > 0 ? params.sessionId : node_crypto.randomUUID();
72
+ const author = buildDocumentAuthor(user);
51
73
  return {
52
74
  sessionId,
53
- params: { sessionId, path: params.doc },
75
+ params: {
76
+ sessionId,
77
+ path: params.doc,
78
+ ...(author === undefined ? {} : { author }),
79
+ ...(defaultChangeMode == null ? {} : { defaultChangeMode }),
80
+ },
54
81
  };
55
82
  }
56
83
  function mapDocumentOpenResult(response, sessionId, path) {
@@ -76,37 +103,120 @@ function mapDocumentOpenResult(response, sessionId, path) {
76
103
  dirty: false,
77
104
  };
78
105
  }
79
- function documentInvokeInput(operationId, params) {
80
- const allowedFields = operationId === 'doc.getText' ? new Set(['in']) : DOCUMENT_RPC_INSERT_FIELDS;
81
- const input = Object.fromEntries(Object.entries(params).filter(([key, value]) => value !== undefined && key !== 'doc' && key !== 'sessionId'));
82
- const unsupportedField = Object.keys(input).find((key) => !allowedFields.has(key));
83
- if (unsupportedField) {
84
- throw unsupported(`Structured document RPC v0 does not support ${operationId} field ${unsupportedField}.`, operationId);
85
- }
86
- return input;
106
+ function supportsTrackedMode(operation) {
107
+ return operation.supportsTrackedMode === true || operation.supportsConditionalTrackedMode === true;
87
108
  }
88
- function buildDocumentInvokeParams(sessionId, operation, params, options) {
89
- if (!DOCUMENT_RPC_V0_OPERATIONS.has(operation.operationId)) {
90
- throw unsupported(`Structured document RPC does not support ${operation.operationId} in v0.`, operation.operationId);
109
+ function documentInvokePayload(operation, params, invokeOptions) {
110
+ const normalizedParams = transportCommon.applyOperationParamAliases(operation, params);
111
+ if (invokeOptions.stdinBytes !== undefined) {
112
+ throw unsupported('Structured document RPC does not support stdinBytes.', operation.operationId);
113
+ }
114
+ if (typeof normalizedParams.out === 'string' && normalizedParams.out.length > 0) {
115
+ throw unsupported('Structured document RPC does not support per-operation output paths.', operation.operationId);
116
+ }
117
+ if (normalizedParams.force === true) {
118
+ throw unsupported('Structured document RPC does not support per-operation force.', operation.operationId);
119
+ }
120
+ const input = {};
121
+ const options = {};
122
+ const paramsByName = new Map(operation.params.map((param) => [param.name, param]));
123
+ for (const [name, value] of Object.entries(normalizedParams)) {
124
+ if (value === undefined || name === 'doc' || name === 'sessionId' || name === 'out' || name === 'force')
125
+ continue;
126
+ const param = paramsByName.get(name);
127
+ if (!param) {
128
+ throw unsupported(`Structured document RPC does not support ${operation.operationId} field ${name}.`, operation.operationId);
129
+ }
130
+ if (typeof param.documentApiInputName === 'string' && param.documentApiInputName.length > 0) {
131
+ input[param.documentApiInputName] = value;
132
+ continue;
133
+ }
134
+ if (DOCUMENT_API_OPTION_FIELDS.has(name)) {
135
+ options[name] = value;
136
+ continue;
137
+ }
138
+ throw unsupported(`Structured document RPC does not support ${operation.operationId} field ${name}.`, operation.operationId);
91
139
  }
92
- if (hasUnsupportedInvokeOptions(options)) {
93
- throw unsupported('Structured document RPC v0 does not support document mutation options.', operation.operationId);
140
+ for (const name of ['expectedRevision', 'changeMode', 'dryRun']) {
141
+ const value = invokeOptions[name];
142
+ if (value === undefined || normalizedParams[name] !== undefined)
143
+ continue;
144
+ const projectedValue = name === 'expectedRevision' ? String(value) : value;
145
+ const param = paramsByName.get(name);
146
+ if (typeof param?.documentApiInputName === 'string' && param.documentApiInputName.length > 0) {
147
+ input[param.documentApiInputName] = projectedValue;
148
+ }
149
+ else {
150
+ options[name] = projectedValue;
151
+ }
152
+ }
153
+ if (options.changeMode !== undefined && !supportsTrackedMode(operation)) {
154
+ if (options.changeMode === 'tracked') {
155
+ throw unsupported(`Structured document RPC does not support tracked mode for ${operation.operationId}.`, operation.operationId);
156
+ }
157
+ if (options.changeMode !== 'direct') {
158
+ throw unsupported(`Structured document RPC received an invalid change mode for ${operation.operationId}.`, operation.operationId);
159
+ }
160
+ delete options.changeMode;
94
161
  }
162
+ if (options.dryRun !== undefined && operation.supportsDryRun !== true) {
163
+ if (options.dryRun === true) {
164
+ throw unsupported(`Structured document RPC does not support dry run for ${operation.operationId}.`, operation.operationId);
165
+ }
166
+ delete options.dryRun;
167
+ }
168
+ if (options.expectedRevision !== undefined && DOCUMENT_API_REVISION_PREFLIGHT_OPERATIONS.has(operation.operationId)) {
169
+ throw unsupported(`Structured document RPC does not yet support expectedRevision for ${operation.operationId}.`, operation.operationId);
170
+ }
171
+ if (options.expectedRevision !== undefined && operation.mutates !== true) {
172
+ throw unsupported(`Structured document RPC does not support expectedRevision for ${operation.operationId}.`, operation.operationId);
173
+ }
174
+ return {
175
+ input,
176
+ ...(Object.keys(options).length === 0 ? {} : { options }),
177
+ };
178
+ }
179
+ function buildDocumentInvokeParams(sessionId, operation, params, options, hostFeatures) {
95
180
  if (operation.operationId === 'doc.save') {
96
- if (params.inPlace === true || typeof params.out !== 'string' || params.out.length === 0) {
97
- throw unsupported('Structured document RPC v0 requires doc.save({ out }) and does not support inPlace.', operation.operationId);
181
+ if (options.stdinBytes !== undefined ||
182
+ options.dryRun !== undefined ||
183
+ options.expectedRevision !== undefined ||
184
+ options.changeMode !== undefined) {
185
+ throw unsupported('Structured document RPC does not support document.save invoke options.', operation.operationId);
186
+ }
187
+ const unknownField = Object.entries(params).find(([name, value]) => value !== undefined && !DOCUMENT_RPC_SAVE_FIELDS.has(name))?.[0];
188
+ if (unknownField !== undefined) {
189
+ throw unsupported(`Structured document RPC does not support doc.save field ${unknownField}.`, operation.operationId);
190
+ }
191
+ if (params.inPlace !== undefined && typeof params.inPlace !== 'boolean') {
192
+ throw unsupported('Structured document RPC requires inPlace to be a boolean.', operation.operationId);
193
+ }
194
+ if (params.inPlace === true && params.out !== undefined) {
195
+ throw unsupported('Structured document RPC requires either inPlace or out, not both.', operation.operationId);
196
+ }
197
+ if (params.out !== undefined && (typeof params.out !== 'string' || params.out.length === 0)) {
198
+ throw unsupported('Structured document RPC requires out to be a non-empty path.', operation.operationId);
199
+ }
200
+ if (params.out === undefined && hostFeatures?.has(DOCUMENT_RPC_SOURCE_SAVE_FEATURE) !== true) {
201
+ throw unsupported('Structured document RPC host does not support source saves.', operation.operationId);
98
202
  }
99
203
  return {
100
204
  method: 'document.save',
101
205
  params: {
102
206
  sessionId,
103
- path: params.out,
104
- overwrite: params.force === true,
207
+ ...(params.out === undefined ? {} : { path: params.out }),
208
+ ...(params.force === true ? { overwrite: true } : {}),
105
209
  ...(params.mode === undefined ? {} : { mode: params.mode }),
106
210
  },
107
211
  };
108
212
  }
109
213
  if (operation.operationId === 'doc.close') {
214
+ if (options.stdinBytes !== undefined ||
215
+ options.dryRun !== undefined ||
216
+ options.expectedRevision !== undefined ||
217
+ options.changeMode !== undefined) {
218
+ throw unsupported('Structured document RPC does not support document.close invoke options.', operation.operationId);
219
+ }
110
220
  return {
111
221
  method: 'document.close',
112
222
  params: {
@@ -115,16 +225,40 @@ function buildDocumentInvokeParams(sessionId, operation, params, options) {
115
225
  },
116
226
  };
117
227
  }
228
+ const documentOperation = operation;
229
+ if (typeof documentOperation.documentApiOperationId !== 'string' ||
230
+ documentOperation.documentApiOperationId.length === 0) {
231
+ throw unsupported(`Structured document RPC does not support ${operation.operationId}.`, operation.operationId);
232
+ }
233
+ const payload = documentInvokePayload(documentOperation, params, options);
118
234
  return {
119
235
  method: 'document.invoke',
120
236
  params: {
121
237
  sessionId,
122
- operationId: operation.operationId.slice('doc.'.length),
123
- input: documentInvokeInput(operation.operationId, params),
238
+ operationId: documentOperation.documentApiOperationId,
239
+ input: payload.input,
240
+ ...(payload.options === undefined ? {} : { options: payload.options }),
124
241
  },
125
242
  };
126
243
  }
127
- function mapDocumentLifecycleResult(operationId, response, sessionId) {
244
+ function documentRpcRequestSupportsResponseTimeout(operation, request) {
245
+ if (request.method === 'document.save')
246
+ return false;
247
+ if (request.method !== 'document.invoke')
248
+ return true;
249
+ const documentOperation = operation;
250
+ const requestOptions = typeof request.params.options === 'object' &&
251
+ request.params.options !== null &&
252
+ !Array.isArray(request.params.options)
253
+ ? request.params.options
254
+ : undefined;
255
+ if (requestOptions?.dryRun === true)
256
+ return true;
257
+ if (documentOperation.mutates === false)
258
+ return true;
259
+ return documentOperation.idempotency === 'idempotent';
260
+ }
261
+ function mapDocumentLifecycleResult(operationId, response, sessionId, expectedInPlace) {
128
262
  if (operationId !== 'doc.save' && operationId !== 'doc.close')
129
263
  return response;
130
264
  if (typeof response !== 'object' || response == null || Array.isArray(response)) {
@@ -158,6 +292,7 @@ function mapDocumentLifecycleResult(operationId, response, sessionId) {
158
292
  }
159
293
  const output = record.output;
160
294
  if (record.saved !== true ||
295
+ (typeof record.inPlace !== 'boolean' && !(record.inPlace === undefined && expectedInPlace === false)) ||
161
296
  typeof output !== 'object' ||
162
297
  output == null ||
163
298
  Array.isArray(output) ||
@@ -172,18 +307,22 @@ function mapDocumentLifecycleResult(operationId, response, sessionId) {
172
307
  contextId: sessionId,
173
308
  runtime: 'v2',
174
309
  saved: true,
175
- inPlace: false,
310
+ inPlace: record.inPlace ?? false,
176
311
  mode: record.mode,
177
312
  output,
178
313
  report: record.report,
179
314
  };
180
315
  }
181
316
 
317
+ exports.DOCUMENT_RPC_DEFAULT_CHANGE_MODE_FEATURE = DOCUMENT_RPC_DEFAULT_CHANGE_MODE_FEATURE;
182
318
  exports.DOCUMENT_RPC_FEATURES = DOCUMENT_RPC_FEATURES;
319
+ exports.DOCUMENT_RPC_REQUEST_TIMEOUT_FEATURE = DOCUMENT_RPC_REQUEST_TIMEOUT_FEATURE;
320
+ exports.DOCUMENT_RPC_SOURCE_SAVE_FEATURE = DOCUMENT_RPC_SOURCE_SAVE_FEATURE;
183
321
  exports.buildDocumentInvokeParams = buildDocumentInvokeParams;
184
322
  exports.buildDocumentOpenParams = buildDocumentOpenParams;
185
323
  exports.canOpenWithDocumentRpc = canOpenWithDocumentRpc;
186
324
  exports.documentRpcEnabled = documentRpcEnabled;
325
+ exports.documentRpcRequestSupportsResponseTimeout = documentRpcRequestSupportsResponseTimeout;
187
326
  exports.mapDocumentLifecycleResult = mapDocumentLifecycleResult;
188
327
  exports.mapDocumentOpenResult = mapDocumentOpenResult;
189
328
  exports.supportsDocumentRpc = supportsDocumentRpc;
@@ -1,15 +1,24 @@
1
- import type { InvokeOptions, OperationSpec } from './transport-common.js';
1
+ import { type ChangeMode, type InvokeOptions, type OperationSpec, type UserIdentity } from './transport-common.js';
2
2
  export declare const DOCUMENT_RPC_FEATURES: readonly ["document.open", "document.invoke", "document.save", "document.close"];
3
+ export declare const DOCUMENT_RPC_DEFAULT_CHANGE_MODE_FEATURE = "document.open.defaultChangeMode";
4
+ export declare const DOCUMENT_RPC_SOURCE_SAVE_FEATURE = "document.save.source";
5
+ export declare const DOCUMENT_RPC_REQUEST_TIMEOUT_FEATURE = "host.request.timeoutMs";
6
+ type DocumentRpcRequest = {
7
+ readonly method: string;
8
+ readonly params: Record<string, unknown>;
9
+ };
3
10
  export declare function documentRpcEnabled(env: Record<string, string | undefined> | undefined): boolean;
4
11
  export declare function supportsDocumentRpc(features: ReadonlySet<string>): boolean;
5
12
  export declare function canOpenWithDocumentRpc(params: Record<string, unknown>, options: InvokeOptions): boolean;
6
- export declare function buildDocumentOpenParams(params: Record<string, unknown>): {
13
+ export declare function buildDocumentOpenParams(params: Record<string, unknown>, user?: UserIdentity, defaultChangeMode?: ChangeMode): {
7
14
  readonly sessionId: string;
8
15
  readonly params: Record<string, unknown>;
9
16
  };
10
17
  export declare function mapDocumentOpenResult(response: unknown, sessionId: string, path: string): Record<string, unknown>;
11
- export declare function buildDocumentInvokeParams(sessionId: string, operation: OperationSpec, params: Record<string, unknown>, options: InvokeOptions): {
18
+ export declare function buildDocumentInvokeParams(sessionId: string, operation: OperationSpec, params: Record<string, unknown>, options: InvokeOptions, hostFeatures?: ReadonlySet<string>): {
12
19
  readonly method: string;
13
20
  readonly params: Record<string, unknown>;
14
21
  };
15
- export declare function mapDocumentLifecycleResult(operationId: string, response: unknown, sessionId: string): unknown;
22
+ export declare function documentRpcRequestSupportsResponseTimeout(operation: OperationSpec, request: DocumentRpcRequest): boolean;
23
+ export declare function mapDocumentLifecycleResult(operationId: string, response: unknown, sessionId: string, expectedInPlace?: boolean): unknown;
24
+ export {};