@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/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(
|
|
149
|
-
return
|
|
149
|
+
async describe(_params = {}, _options) {
|
|
150
|
+
return introspection.describeContract();
|
|
150
151
|
}
|
|
151
|
-
async describeCommand(params,
|
|
152
|
-
return
|
|
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(
|
|
78
|
-
describeCommand(params: DocDescribeCommandParams,
|
|
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(
|
|
141
|
-
return
|
|
141
|
+
async describe(_params = {}, _options) {
|
|
142
|
+
return describeContract();
|
|
142
143
|
}
|
|
143
|
-
async describeCommand(params,
|
|
144
|
-
return
|
|
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,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
|
+
}
|
|
@@ -0,0 +1,328 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var node_crypto = require('node:crypto');
|
|
4
|
+
var errors = require('./errors.cjs');
|
|
5
|
+
var transportCommon = require('./transport-common.cjs');
|
|
6
|
+
|
|
7
|
+
const DOCUMENT_RPC_FEATURES = ['document.open', 'document.invoke', 'document.save', 'document.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';
|
|
11
|
+
const DOCUMENT_RPC_OPEN_FIELDS = new Set(['doc', 'sessionId', 'runtime']);
|
|
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
|
+
]);
|
|
19
|
+
function unsupported(message, operationId) {
|
|
20
|
+
return new errors.SuperDocCliError(message, {
|
|
21
|
+
code: 'DOCUMENT_RPC_INPUT_UNSUPPORTED',
|
|
22
|
+
...(operationId === undefined ? {} : { details: { operationId } }),
|
|
23
|
+
});
|
|
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
|
+
}
|
|
49
|
+
function documentRpcEnabled(env) {
|
|
50
|
+
return (env?.SUPERDOC_SDK_DOCUMENT_RPC ?? process.env.SUPERDOC_SDK_DOCUMENT_RPC) === '1';
|
|
51
|
+
}
|
|
52
|
+
function supportsDocumentRpc(features) {
|
|
53
|
+
return DOCUMENT_RPC_FEATURES.every((feature) => features.has(feature));
|
|
54
|
+
}
|
|
55
|
+
function canOpenWithDocumentRpc(params, options) {
|
|
56
|
+
if (options.stdinBytes !== undefined)
|
|
57
|
+
return false;
|
|
58
|
+
if (options.dryRun !== undefined || options.expectedRevision !== undefined || options.changeMode !== undefined) {
|
|
59
|
+
return false;
|
|
60
|
+
}
|
|
61
|
+
if (typeof params.doc !== 'string' || params.doc.trim().length === 0 || params.doc === '-')
|
|
62
|
+
return false;
|
|
63
|
+
if (params.runtime !== undefined && params.runtime !== 'v2')
|
|
64
|
+
return false;
|
|
65
|
+
if (params.sessionId !== undefined && (typeof params.sessionId !== 'string' || params.sessionId.length === 0)) {
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
68
|
+
return Object.entries(params).every(([key, value]) => value === undefined || DOCUMENT_RPC_OPEN_FIELDS.has(key));
|
|
69
|
+
}
|
|
70
|
+
function buildDocumentOpenParams(params, user, defaultChangeMode) {
|
|
71
|
+
const sessionId = typeof params.sessionId === 'string' && params.sessionId.length > 0 ? params.sessionId : node_crypto.randomUUID();
|
|
72
|
+
const author = buildDocumentAuthor(user);
|
|
73
|
+
return {
|
|
74
|
+
sessionId,
|
|
75
|
+
params: {
|
|
76
|
+
sessionId,
|
|
77
|
+
path: params.doc,
|
|
78
|
+
...(author === undefined ? {} : { author }),
|
|
79
|
+
...(defaultChangeMode == null ? {} : { defaultChangeMode }),
|
|
80
|
+
},
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
function mapDocumentOpenResult(response, sessionId, path) {
|
|
84
|
+
if (typeof response !== 'object' || response == null || Array.isArray(response)) {
|
|
85
|
+
throw new errors.SuperDocCliError('Host returned invalid document.open result.', {
|
|
86
|
+
code: 'HOST_PROTOCOL_ERROR',
|
|
87
|
+
details: { result: response },
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
const record = response;
|
|
91
|
+
if (record.sessionId !== sessionId || typeof record.byteLength !== 'number') {
|
|
92
|
+
throw new errors.SuperDocCliError('Host returned invalid document.open session metadata.', {
|
|
93
|
+
code: 'HOST_PROTOCOL_ERROR',
|
|
94
|
+
details: { result: response },
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
return {
|
|
98
|
+
active: true,
|
|
99
|
+
contextId: sessionId,
|
|
100
|
+
runtime: 'v2',
|
|
101
|
+
sessionType: 'local',
|
|
102
|
+
document: { path, source: 'path', byteLength: record.byteLength, revision: 0 },
|
|
103
|
+
dirty: false,
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
function supportsTrackedMode(operation) {
|
|
107
|
+
return operation.supportsTrackedMode === true || operation.supportsConditionalTrackedMode === true;
|
|
108
|
+
}
|
|
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);
|
|
139
|
+
}
|
|
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;
|
|
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) {
|
|
180
|
+
if (operation.operationId === 'doc.save') {
|
|
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);
|
|
202
|
+
}
|
|
203
|
+
return {
|
|
204
|
+
method: 'document.save',
|
|
205
|
+
params: {
|
|
206
|
+
sessionId,
|
|
207
|
+
...(params.out === undefined ? {} : { path: params.out }),
|
|
208
|
+
...(params.force === true ? { overwrite: true } : {}),
|
|
209
|
+
...(params.mode === undefined ? {} : { mode: params.mode }),
|
|
210
|
+
},
|
|
211
|
+
};
|
|
212
|
+
}
|
|
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
|
+
}
|
|
220
|
+
return {
|
|
221
|
+
method: 'document.close',
|
|
222
|
+
params: {
|
|
223
|
+
sessionId,
|
|
224
|
+
...(params.discard === undefined ? {} : { discard: params.discard }),
|
|
225
|
+
},
|
|
226
|
+
};
|
|
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);
|
|
234
|
+
return {
|
|
235
|
+
method: 'document.invoke',
|
|
236
|
+
params: {
|
|
237
|
+
sessionId,
|
|
238
|
+
operationId: documentOperation.documentApiOperationId,
|
|
239
|
+
input: payload.input,
|
|
240
|
+
...(payload.options === undefined ? {} : { options: payload.options }),
|
|
241
|
+
},
|
|
242
|
+
};
|
|
243
|
+
}
|
|
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) {
|
|
262
|
+
if (operationId !== 'doc.save' && operationId !== 'doc.close')
|
|
263
|
+
return response;
|
|
264
|
+
if (typeof response !== 'object' || response == null || Array.isArray(response)) {
|
|
265
|
+
throw new errors.SuperDocCliError(`Host returned invalid ${operationId.slice('doc.'.length)} result.`, {
|
|
266
|
+
code: 'HOST_PROTOCOL_ERROR',
|
|
267
|
+
details: { result: response },
|
|
268
|
+
});
|
|
269
|
+
}
|
|
270
|
+
const record = response;
|
|
271
|
+
if (record.sessionId !== sessionId) {
|
|
272
|
+
throw new errors.SuperDocCliError('Host returned a result for the wrong document session.', {
|
|
273
|
+
code: 'HOST_PROTOCOL_ERROR',
|
|
274
|
+
details: { expectedSessionId: sessionId, result: response },
|
|
275
|
+
});
|
|
276
|
+
}
|
|
277
|
+
if (operationId === 'doc.close') {
|
|
278
|
+
if (record.closed !== true || typeof record.discarded !== 'boolean') {
|
|
279
|
+
throw new errors.SuperDocCliError('Host returned invalid document.close result.', {
|
|
280
|
+
code: 'HOST_PROTOCOL_ERROR',
|
|
281
|
+
details: { result: response },
|
|
282
|
+
});
|
|
283
|
+
}
|
|
284
|
+
return {
|
|
285
|
+
contextId: sessionId,
|
|
286
|
+
runtime: 'v2',
|
|
287
|
+
closed: true,
|
|
288
|
+
saved: false,
|
|
289
|
+
discarded: record.discarded,
|
|
290
|
+
defaultSessionCleared: false,
|
|
291
|
+
};
|
|
292
|
+
}
|
|
293
|
+
const output = record.output;
|
|
294
|
+
if (record.saved !== true ||
|
|
295
|
+
(typeof record.inPlace !== 'boolean' && !(record.inPlace === undefined && expectedInPlace === false)) ||
|
|
296
|
+
typeof output !== 'object' ||
|
|
297
|
+
output == null ||
|
|
298
|
+
Array.isArray(output) ||
|
|
299
|
+
typeof output.path !== 'string' ||
|
|
300
|
+
typeof output.byteLength !== 'number') {
|
|
301
|
+
throw new errors.SuperDocCliError('Host returned invalid document.save result.', {
|
|
302
|
+
code: 'HOST_PROTOCOL_ERROR',
|
|
303
|
+
details: { result: response },
|
|
304
|
+
});
|
|
305
|
+
}
|
|
306
|
+
return {
|
|
307
|
+
contextId: sessionId,
|
|
308
|
+
runtime: 'v2',
|
|
309
|
+
saved: true,
|
|
310
|
+
inPlace: record.inPlace ?? false,
|
|
311
|
+
mode: record.mode,
|
|
312
|
+
output,
|
|
313
|
+
report: record.report,
|
|
314
|
+
};
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
exports.DOCUMENT_RPC_DEFAULT_CHANGE_MODE_FEATURE = DOCUMENT_RPC_DEFAULT_CHANGE_MODE_FEATURE;
|
|
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;
|
|
321
|
+
exports.buildDocumentInvokeParams = buildDocumentInvokeParams;
|
|
322
|
+
exports.buildDocumentOpenParams = buildDocumentOpenParams;
|
|
323
|
+
exports.canOpenWithDocumentRpc = canOpenWithDocumentRpc;
|
|
324
|
+
exports.documentRpcEnabled = documentRpcEnabled;
|
|
325
|
+
exports.documentRpcRequestSupportsResponseTimeout = documentRpcRequestSupportsResponseTimeout;
|
|
326
|
+
exports.mapDocumentLifecycleResult = mapDocumentLifecycleResult;
|
|
327
|
+
exports.mapDocumentOpenResult = mapDocumentOpenResult;
|
|
328
|
+
exports.supportsDocumentRpc = supportsDocumentRpc;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { type ChangeMode, type InvokeOptions, type OperationSpec, type UserIdentity } from './transport-common.js';
|
|
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
|
+
};
|
|
10
|
+
export declare function documentRpcEnabled(env: Record<string, string | undefined> | undefined): boolean;
|
|
11
|
+
export declare function supportsDocumentRpc(features: ReadonlySet<string>): boolean;
|
|
12
|
+
export declare function canOpenWithDocumentRpc(params: Record<string, unknown>, options: InvokeOptions): boolean;
|
|
13
|
+
export declare function buildDocumentOpenParams(params: Record<string, unknown>, user?: UserIdentity, defaultChangeMode?: ChangeMode): {
|
|
14
|
+
readonly sessionId: string;
|
|
15
|
+
readonly params: Record<string, unknown>;
|
|
16
|
+
};
|
|
17
|
+
export declare function mapDocumentOpenResult(response: unknown, sessionId: string, path: string): Record<string, unknown>;
|
|
18
|
+
export declare function buildDocumentInvokeParams(sessionId: string, operation: OperationSpec, params: Record<string, unknown>, options: InvokeOptions, hostFeatures?: ReadonlySet<string>): {
|
|
19
|
+
readonly method: string;
|
|
20
|
+
readonly params: Record<string, unknown>;
|
|
21
|
+
};
|
|
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 {};
|