@superdoc-dev/sdk 1.0.0-alpha.4 → 1.0.0-alpha.41

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 (43) hide show
  1. package/README.md +124 -0
  2. package/dist/generated/client.cjs +479 -0
  3. package/dist/generated/client.d.ts +11940 -1167
  4. package/dist/generated/client.d.ts.map +1 -1
  5. package/dist/generated/client.js +433 -25
  6. package/dist/generated/contract.cjs +123158 -0
  7. package/dist/generated/contract.d.ts +30 -13672
  8. package/dist/generated/contract.d.ts.map +1 -1
  9. package/dist/generated/contract.js +116698 -11334
  10. package/dist/helpers/format.d.ts +79 -0
  11. package/dist/helpers/format.d.ts.map +1 -0
  12. package/dist/helpers/format.js +121 -0
  13. package/dist/index.cjs +45 -0
  14. package/dist/index.d.ts +3 -3
  15. package/dist/index.d.ts.map +1 -1
  16. package/dist/index.js +1 -1
  17. package/dist/runtime/embedded-cli.cjs +100 -0
  18. package/dist/runtime/errors.cjs +22 -0
  19. package/dist/runtime/host.cjs +352 -0
  20. package/dist/runtime/host.d.ts +2 -1
  21. package/dist/runtime/host.d.ts.map +1 -1
  22. package/dist/runtime/host.js +3 -1
  23. package/dist/runtime/process.cjs +32 -0
  24. package/dist/runtime/process.d.ts +1 -1
  25. package/dist/runtime/process.d.ts.map +1 -1
  26. package/dist/runtime/transport-common.cjs +79 -0
  27. package/dist/runtime/transport-common.d.ts +6 -1
  28. package/dist/runtime/transport-common.d.ts.map +1 -1
  29. package/dist/runtime/transport-common.js +13 -4
  30. package/dist/skills.cjs +148 -0
  31. package/dist/tools.cjs +312 -0
  32. package/dist/tools.d.ts +42 -65
  33. package/dist/tools.d.ts.map +1 -1
  34. package/dist/tools.js +75 -134
  35. package/package.json +15 -14
  36. package/skills/editing-docx.md +31 -0
  37. package/tools/catalog.json +59826 -15216
  38. package/tools/tool-name-map.json +300 -71
  39. package/tools/tools-policy.json +79 -82
  40. package/tools/tools.anthropic.json +25742 -2983
  41. package/tools/tools.generic.json +58182 -15148
  42. package/tools/tools.openai.json +26715 -3266
  43. package/tools/tools.vercel.json +26715 -3266
@@ -0,0 +1,352 @@
1
+ 'use strict';
2
+
3
+ var node_child_process = require('node:child_process');
4
+ var node_readline = require('node:readline');
5
+ var transportCommon = require('./transport-common.cjs');
6
+ var errors = require('./errors.cjs');
7
+
8
+ const HOST_PROTOCOL_VERSION = '1.0';
9
+ const REQUIRED_FEATURES = ['cli.invoke', 'host.shutdown'];
10
+ const CHANGE_MODES = ['direct', 'tracked'];
11
+ const JSON_RPC_TIMEOUT_CODE = -32011;
12
+ /**
13
+ * Transport that communicates with a long-lived CLI host process over JSON-RPC stdio.
14
+ */
15
+ class HostTransport {
16
+ cliBin;
17
+ env;
18
+ startupTimeoutMs;
19
+ shutdownTimeoutMs;
20
+ requestTimeoutMs;
21
+ watchdogTimeoutMs;
22
+ maxQueueDepth;
23
+ defaultChangeMode;
24
+ user;
25
+ child = null;
26
+ stdoutReader = null;
27
+ pending = new Map();
28
+ nextRequestId = 1;
29
+ connecting = null;
30
+ stopping = false;
31
+ constructor(options) {
32
+ this.cliBin = options.cliBin;
33
+ this.env = options.env;
34
+ this.startupTimeoutMs = options.startupTimeoutMs ?? 5_000;
35
+ this.shutdownTimeoutMs = options.shutdownTimeoutMs ?? 5_000;
36
+ this.requestTimeoutMs = options.requestTimeoutMs;
37
+ this.watchdogTimeoutMs = options.watchdogTimeoutMs ?? 30_000;
38
+ this.maxQueueDepth = options.maxQueueDepth ?? 100;
39
+ if (options.defaultChangeMode != null && !CHANGE_MODES.includes(options.defaultChangeMode)) {
40
+ throw new errors.SuperDocCliError('defaultChangeMode must be "direct" or "tracked".', {
41
+ code: 'INVALID_ARGUMENT',
42
+ details: { defaultChangeMode: options.defaultChangeMode },
43
+ });
44
+ }
45
+ this.defaultChangeMode = options.defaultChangeMode;
46
+ this.user = options.user;
47
+ }
48
+ async connect() {
49
+ await this.ensureConnected();
50
+ }
51
+ async dispose() {
52
+ if (!this.child)
53
+ return;
54
+ this.stopping = true;
55
+ const child = this.child;
56
+ try {
57
+ await this.sendJsonRpcRequest('host.shutdown', {}, this.shutdownTimeoutMs);
58
+ }
59
+ catch {
60
+ // ignore and force shutdown below
61
+ }
62
+ await new Promise((resolve) => {
63
+ const timer = setTimeout(() => {
64
+ child.kill('SIGKILL');
65
+ resolve();
66
+ }, this.shutdownTimeoutMs);
67
+ child.once('close', () => {
68
+ clearTimeout(timer);
69
+ resolve();
70
+ });
71
+ });
72
+ this.cleanupProcess(null);
73
+ this.stopping = false;
74
+ }
75
+ async invoke(operation, params = {}, options = {}) {
76
+ await this.ensureConnected();
77
+ const argv = transportCommon.buildOperationArgv(operation, params, options, this.requestTimeoutMs, this.defaultChangeMode, this.user);
78
+ const stdinBase64 = options.stdinBytes ? Buffer.from(options.stdinBytes).toString('base64') : '';
79
+ const watchdogTimeout = this.resolveWatchdogTimeout(options.timeoutMs);
80
+ const response = await this.sendJsonRpcRequest('cli.invoke', {
81
+ argv,
82
+ stdinBase64,
83
+ }, watchdogTimeout);
84
+ if (typeof response !== 'object' || response == null || Array.isArray(response)) {
85
+ throw new errors.SuperDocCliError('Host returned invalid cli.invoke result.', {
86
+ code: 'HOST_PROTOCOL_ERROR',
87
+ details: { result: response },
88
+ });
89
+ }
90
+ const resultRecord = response;
91
+ return resultRecord.data;
92
+ }
93
+ async ensureConnected() {
94
+ if (this.child && !this.child.killed) {
95
+ return;
96
+ }
97
+ if (this.connecting) {
98
+ await this.connecting;
99
+ return;
100
+ }
101
+ this.connecting = this.startHostProcess();
102
+ try {
103
+ await this.connecting;
104
+ }
105
+ finally {
106
+ this.connecting = null;
107
+ }
108
+ }
109
+ async startHostProcess() {
110
+ const { command, prefixArgs } = transportCommon.resolveInvocation(this.cliBin);
111
+ const args = [...prefixArgs, 'host', '--stdio'];
112
+ const child = node_child_process.spawn(command, args, {
113
+ env: {
114
+ ...process.env,
115
+ ...(this.env ?? {}),
116
+ },
117
+ stdio: ['pipe', 'pipe', 'pipe'],
118
+ });
119
+ this.child = child;
120
+ const stdoutReader = node_readline.createInterface({
121
+ input: child.stdout,
122
+ crlfDelay: Number.POSITIVE_INFINITY,
123
+ });
124
+ this.stdoutReader = stdoutReader;
125
+ stdoutReader.on('line', (line) => {
126
+ this.onStdoutLine(line);
127
+ });
128
+ child.stderr.on('data', () => {
129
+ // stderr intentionally ignored in host mode
130
+ });
131
+ child.on('error', (error) => {
132
+ this.handleDisconnect(new errors.SuperDocCliError('Host process failed.', {
133
+ code: 'HOST_DISCONNECTED',
134
+ details: {
135
+ message: error instanceof Error ? error.message : String(error),
136
+ },
137
+ }));
138
+ });
139
+ child.on('close', (code, signal) => {
140
+ if (this.stopping) {
141
+ this.cleanupProcess(null);
142
+ return;
143
+ }
144
+ this.handleDisconnect(new errors.SuperDocCliError('Host process disconnected.', {
145
+ code: 'HOST_DISCONNECTED',
146
+ details: { exitCode: code, signal },
147
+ }));
148
+ });
149
+ try {
150
+ const capabilities = await this.sendJsonRpcRequest('host.capabilities', {}, this.startupTimeoutMs);
151
+ this.assertCapabilities(capabilities);
152
+ }
153
+ catch (error) {
154
+ const normalized = error instanceof errors.SuperDocCliError
155
+ ? error
156
+ : new errors.SuperDocCliError('Host handshake failed.', {
157
+ code: 'HOST_HANDSHAKE_FAILED',
158
+ details: {
159
+ message: error instanceof Error ? error.message : String(error),
160
+ },
161
+ });
162
+ this.handleDisconnect(normalized);
163
+ throw normalized;
164
+ }
165
+ }
166
+ assertCapabilities(response) {
167
+ if (typeof response !== 'object' || response == null || Array.isArray(response)) {
168
+ throw new errors.SuperDocCliError('Host capabilities response is invalid.', {
169
+ code: 'HOST_HANDSHAKE_FAILED',
170
+ details: { response },
171
+ });
172
+ }
173
+ const record = response;
174
+ const protocolVersion = record.protocolVersion;
175
+ const features = record.features;
176
+ if (protocolVersion !== HOST_PROTOCOL_VERSION) {
177
+ throw new errors.SuperDocCliError('Host protocol version is unsupported.', {
178
+ code: 'HOST_HANDSHAKE_FAILED',
179
+ details: {
180
+ expected: HOST_PROTOCOL_VERSION,
181
+ actual: protocolVersion,
182
+ },
183
+ });
184
+ }
185
+ if (!Array.isArray(features) || features.some((f) => typeof f !== 'string')) {
186
+ throw new errors.SuperDocCliError('Host capabilities.features must be a string array.', {
187
+ code: 'HOST_HANDSHAKE_FAILED',
188
+ details: { features },
189
+ });
190
+ }
191
+ for (const requiredFeature of REQUIRED_FEATURES) {
192
+ if (!features.includes(requiredFeature)) {
193
+ throw new errors.SuperDocCliError(`Host does not support required feature: ${requiredFeature}`, {
194
+ code: 'HOST_HANDSHAKE_FAILED',
195
+ details: { features },
196
+ });
197
+ }
198
+ }
199
+ }
200
+ resolveWatchdogTimeout(timeoutMsOverride) {
201
+ if (timeoutMsOverride != null) {
202
+ return Math.max(this.watchdogTimeoutMs, timeoutMsOverride + 1_000);
203
+ }
204
+ if (this.requestTimeoutMs != null) {
205
+ return Math.max(this.watchdogTimeoutMs, this.requestTimeoutMs + 1_000);
206
+ }
207
+ return this.watchdogTimeoutMs;
208
+ }
209
+ async sendJsonRpcRequest(method, params, watchdogTimeoutMs) {
210
+ const child = this.child;
211
+ if (!child || !child.stdin.writable) {
212
+ throw new errors.SuperDocCliError('Host process is not available.', {
213
+ code: 'HOST_DISCONNECTED',
214
+ });
215
+ }
216
+ if (this.pending.size >= this.maxQueueDepth) {
217
+ throw new errors.SuperDocCliError('Host request queue is full.', {
218
+ code: 'HOST_QUEUE_FULL',
219
+ details: { maxQueueDepth: this.maxQueueDepth },
220
+ });
221
+ }
222
+ const id = this.nextRequestId;
223
+ this.nextRequestId += 1;
224
+ const payload = JSON.stringify({
225
+ jsonrpc: '2.0',
226
+ id,
227
+ method,
228
+ params,
229
+ });
230
+ const promise = new Promise((resolve, reject) => {
231
+ const timer = setTimeout(() => {
232
+ this.pending.delete(id);
233
+ reject(new errors.SuperDocCliError(`Host watchdog timed out waiting for ${method}.`, {
234
+ code: 'HOST_TIMEOUT',
235
+ details: { method, timeoutMs: watchdogTimeoutMs },
236
+ }));
237
+ this.handleDisconnect(new errors.SuperDocCliError('Host watchdog timeout; host process will be restarted on next request.', {
238
+ code: 'HOST_DISCONNECTED',
239
+ details: { method, timeoutMs: watchdogTimeoutMs },
240
+ }));
241
+ }, watchdogTimeoutMs);
242
+ this.pending.set(id, { resolve, reject, timer });
243
+ child.stdin.write(`${payload}\n`, (error) => {
244
+ if (!error)
245
+ return;
246
+ const pending = this.pending.get(id);
247
+ if (!pending)
248
+ return;
249
+ clearTimeout(pending.timer);
250
+ this.pending.delete(id);
251
+ reject(new errors.SuperDocCliError('Failed to write request to host process.', {
252
+ code: 'HOST_DISCONNECTED',
253
+ details: { method, message: error.message },
254
+ }));
255
+ });
256
+ });
257
+ return promise;
258
+ }
259
+ onStdoutLine(line) {
260
+ let parsed;
261
+ try {
262
+ parsed = JSON.parse(line);
263
+ }
264
+ catch {
265
+ return;
266
+ }
267
+ if (typeof parsed !== 'object' || parsed == null || Array.isArray(parsed)) {
268
+ return;
269
+ }
270
+ const record = parsed;
271
+ if (record.jsonrpc !== '2.0') {
272
+ return;
273
+ }
274
+ // Notification (no id) — reserved for future eventing
275
+ if ('method' in record && !('id' in record)) {
276
+ return;
277
+ }
278
+ const idRaw = record.id;
279
+ if (typeof idRaw !== 'number') {
280
+ return;
281
+ }
282
+ const pending = this.pending.get(idRaw);
283
+ if (!pending) {
284
+ return;
285
+ }
286
+ clearTimeout(pending.timer);
287
+ this.pending.delete(idRaw);
288
+ if ('error' in record) {
289
+ pending.reject(this.mapJsonRpcError(record.error));
290
+ return;
291
+ }
292
+ pending.resolve(record.result);
293
+ }
294
+ mapJsonRpcError(rawError) {
295
+ if (typeof rawError !== 'object' || rawError == null || Array.isArray(rawError)) {
296
+ return new errors.SuperDocCliError('Host returned an unknown JSON-RPC error.', {
297
+ code: 'HOST_PROTOCOL_ERROR',
298
+ details: { error: rawError },
299
+ });
300
+ }
301
+ const error = rawError;
302
+ const data = error.data;
303
+ const cliCode = typeof data?.cliCode === 'string' ? data.cliCode : undefined;
304
+ const cliMessage = typeof data?.message === 'string' ? data.message : undefined;
305
+ const exitCode = typeof data?.exitCode === 'number' ? data.exitCode : undefined;
306
+ if (cliCode) {
307
+ return new errors.SuperDocCliError(cliMessage ?? error.message ?? 'Command failed.', {
308
+ code: cliCode,
309
+ details: data?.details,
310
+ exitCode,
311
+ });
312
+ }
313
+ if (error.code === JSON_RPC_TIMEOUT_CODE) {
314
+ return new errors.SuperDocCliError(error.message, {
315
+ code: 'TIMEOUT',
316
+ details: data,
317
+ });
318
+ }
319
+ return new errors.SuperDocCliError(error.message, {
320
+ code: 'COMMAND_FAILED',
321
+ details: data,
322
+ });
323
+ }
324
+ handleDisconnect(error) {
325
+ this.cleanupProcess(error);
326
+ }
327
+ cleanupProcess(error) {
328
+ const child = this.child;
329
+ if (child) {
330
+ child.removeAllListeners();
331
+ child.kill('SIGKILL');
332
+ }
333
+ this.child = null;
334
+ if (this.stdoutReader) {
335
+ this.stdoutReader.removeAllListeners();
336
+ this.stdoutReader.close();
337
+ this.stdoutReader = null;
338
+ }
339
+ const pendingEntries = Array.from(this.pending.values());
340
+ this.pending.clear();
341
+ const rejection = error ??
342
+ new errors.SuperDocCliError('Host process was disposed while request was in flight.', {
343
+ code: 'HOST_DISCONNECTED',
344
+ });
345
+ for (const pending of pendingEntries) {
346
+ clearTimeout(pending.timer);
347
+ pending.reject(rejection);
348
+ }
349
+ }
350
+ }
351
+
352
+ exports.HostTransport = HostTransport;
@@ -11,6 +11,7 @@ export declare class HostTransport {
11
11
  private readonly watchdogTimeoutMs;
12
12
  private readonly maxQueueDepth;
13
13
  private readonly defaultChangeMode?;
14
+ private readonly user?;
14
15
  private child;
15
16
  private stdoutReader;
16
17
  private readonly pending;
@@ -22,7 +23,7 @@ export declare class HostTransport {
22
23
  } & SuperDocClientOptions);
23
24
  connect(): Promise<void>;
24
25
  dispose(): Promise<void>;
25
- invoke<TData extends Record<string, unknown>>(operation: OperationSpec, params?: Record<string, unknown>, options?: InvokeOptions): Promise<TData>;
26
+ invoke<TData = unknown>(operation: OperationSpec, params?: Record<string, unknown>, options?: InvokeOptions): Promise<TData>;
26
27
  private ensureConnected;
27
28
  private startHostProcess;
28
29
  private assertCapabilities;
@@ -1 +1 @@
1
- {"version":3,"file":"host.d.ts","sourceRoot":"","sources":["../../src/runtime/host.ts"],"names":[],"mappings":"AAEA,OAAO,EAIL,KAAK,aAAa,EAClB,KAAK,aAAa,EAClB,KAAK,qBAAqB,EAC3B,MAAM,uBAAuB,CAAC;AA4B/B;;GAEG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAqC;IAC1D,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAS;IAC1C,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAS;IAC3C,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAAS;IAC3C,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAS;IAC3C,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAC,CAAa;IAEhD,OAAO,CAAC,KAAK,CAA+C;IAC5D,OAAO,CAAC,YAAY,CAAkC;IACtD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAqC;IAC7D,OAAO,CAAC,aAAa,CAAK;IAC1B,OAAO,CAAC,UAAU,CAA8B;IAChD,OAAO,CAAC,QAAQ,CAAS;gBAEb,OAAO,EAAE;QAAE,MAAM,EAAE,MAAM,CAAA;KAAE,GAAG,qBAAqB;IAkBzD,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAIxB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IA4BxB,MAAM,CAAC,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChD,SAAS,EAAE,aAAa,EACxB,MAAM,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,EACpC,OAAO,GAAE,aAAkB,GAC1B,OAAO,CAAC,KAAK,CAAC;YA2BH,eAAe;YAkBf,gBAAgB;IAuE9B,OAAO,CAAC,kBAAkB;IAuC1B,OAAO,CAAC,sBAAsB;YAYhB,kBAAkB;IAkEhC,OAAO,CAAC,YAAY;IA2CpB,OAAO,CAAC,eAAe;IAmCvB,OAAO,CAAC,gBAAgB;IAIxB,OAAO,CAAC,cAAc;CA6BvB"}
1
+ {"version":3,"file":"host.d.ts","sourceRoot":"","sources":["../../src/runtime/host.ts"],"names":[],"mappings":"AAEA,OAAO,EAIL,KAAK,aAAa,EAClB,KAAK,aAAa,EAClB,KAAK,qBAAqB,EAE3B,MAAM,uBAAuB,CAAC;AA4B/B;;GAEG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAqC;IAC1D,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAS;IAC1C,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAS;IAC3C,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAAS;IAC3C,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAS;IAC3C,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAC,CAAa;IAChD,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAe;IAErC,OAAO,CAAC,KAAK,CAA+C;IAC5D,OAAO,CAAC,YAAY,CAAkC;IACtD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAqC;IAC7D,OAAO,CAAC,aAAa,CAAK;IAC1B,OAAO,CAAC,UAAU,CAA8B;IAChD,OAAO,CAAC,QAAQ,CAAS;gBAEb,OAAO,EAAE;QAAE,MAAM,EAAE,MAAM,CAAA;KAAE,GAAG,qBAAqB;IAmBzD,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAIxB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IA4BxB,MAAM,CAAC,KAAK,GAAG,OAAO,EAC1B,SAAS,EAAE,aAAa,EACxB,MAAM,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,EACpC,OAAO,GAAE,aAAkB,GAC1B,OAAO,CAAC,KAAK,CAAC;YAkCH,eAAe;YAkBf,gBAAgB;IAuE9B,OAAO,CAAC,kBAAkB;IAuC1B,OAAO,CAAC,sBAAsB;YAYhB,kBAAkB;IAkEhC,OAAO,CAAC,YAAY;IA2CpB,OAAO,CAAC,eAAe;IAmCvB,OAAO,CAAC,gBAAgB;IAIxB,OAAO,CAAC,cAAc;CA6BvB"}
@@ -18,6 +18,7 @@ export class HostTransport {
18
18
  watchdogTimeoutMs;
19
19
  maxQueueDepth;
20
20
  defaultChangeMode;
21
+ user;
21
22
  child = null;
22
23
  stdoutReader = null;
23
24
  pending = new Map();
@@ -39,6 +40,7 @@ export class HostTransport {
39
40
  });
40
41
  }
41
42
  this.defaultChangeMode = options.defaultChangeMode;
43
+ this.user = options.user;
42
44
  }
43
45
  async connect() {
44
46
  await this.ensureConnected();
@@ -69,7 +71,7 @@ export class HostTransport {
69
71
  }
70
72
  async invoke(operation, params = {}, options = {}) {
71
73
  await this.ensureConnected();
72
- const argv = buildOperationArgv(operation, params, options, this.requestTimeoutMs, this.defaultChangeMode);
74
+ const argv = buildOperationArgv(operation, params, options, this.requestTimeoutMs, this.defaultChangeMode, this.user);
73
75
  const stdinBase64 = options.stdinBytes ? Buffer.from(options.stdinBytes).toString('base64') : '';
74
76
  const watchdogTimeout = this.resolveWatchdogTimeout(options.timeoutMs);
75
77
  const response = await this.sendJsonRpcRequest('cli.invoke', {
@@ -0,0 +1,32 @@
1
+ 'use strict';
2
+
3
+ var host = require('./host.cjs');
4
+ var embeddedCli = require('./embedded-cli.cjs');
5
+
6
+ /**
7
+ * Internal runtime that delegates CLI invocations to a persistent host transport.
8
+ *
9
+ * Resolves the CLI binary and creates a {@link HostTransport} that communicates
10
+ * with a long-lived `superdoc host --stdio` process.
11
+ */
12
+ class SuperDocRuntime {
13
+ transport;
14
+ constructor(options = {}) {
15
+ const cliBin = options.env?.SUPERDOC_CLI_BIN ?? process.env.SUPERDOC_CLI_BIN ?? embeddedCli.resolveEmbeddedCliBinary();
16
+ this.transport = new host.HostTransport({
17
+ cliBin,
18
+ ...options,
19
+ });
20
+ }
21
+ async connect() {
22
+ await this.transport.connect();
23
+ }
24
+ async dispose() {
25
+ await this.transport.dispose();
26
+ }
27
+ async invoke(operation, params = {}, options = {}) {
28
+ return this.transport.invoke(operation, params, options);
29
+ }
30
+ }
31
+
32
+ exports.SuperDocRuntime = SuperDocRuntime;
@@ -10,7 +10,7 @@ export declare class SuperDocRuntime {
10
10
  constructor(options?: SuperDocClientOptions);
11
11
  connect(): Promise<void>;
12
12
  dispose(): Promise<void>;
13
- invoke<TData extends Record<string, unknown>>(operation: OperationSpec, params?: Record<string, unknown>, options?: InvokeOptions): Promise<TData>;
13
+ invoke<TData = unknown>(operation: OperationSpec, params?: Record<string, unknown>, options?: InvokeOptions): Promise<TData>;
14
14
  }
15
15
  export type { InvokeOptions, OperationParamSpec, OperationSpec, SuperDocClientOptions };
16
16
  //# sourceMappingURL=process.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"process.d.ts","sourceRoot":"","sources":["../../src/runtime/process.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,aAAa,EACb,kBAAkB,EAClB,aAAa,EACb,qBAAqB,EACtB,MAAM,uBAAuB,CAAC;AAE/B;;;;;GAKG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAgB;gBAE9B,OAAO,GAAE,qBAA0B;IASzC,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAIxB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAIxB,MAAM,CAAC,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChD,SAAS,EAAE,aAAa,EACxB,MAAM,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,EACpC,OAAO,GAAE,aAAkB,GAC1B,OAAO,CAAC,KAAK,CAAC;CAGlB;AAED,YAAY,EAAE,aAAa,EAAE,kBAAkB,EAAE,aAAa,EAAE,qBAAqB,EAAE,CAAC"}
1
+ {"version":3,"file":"process.d.ts","sourceRoot":"","sources":["../../src/runtime/process.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,kBAAkB,EAAE,aAAa,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAErH;;;;;GAKG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAgB;gBAE9B,OAAO,GAAE,qBAA0B;IASzC,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAIxB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAIxB,MAAM,CAAC,KAAK,GAAG,OAAO,EAC1B,SAAS,EAAE,aAAa,EACxB,MAAM,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,EACpC,OAAO,GAAE,aAAkB,GAC1B,OAAO,CAAC,KAAK,CAAC;CAGlB;AAED,YAAY,EAAE,aAAa,EAAE,kBAAkB,EAAE,aAAa,EAAE,qBAAqB,EAAE,CAAC"}
@@ -0,0 +1,79 @@
1
+ 'use strict';
2
+
3
+ function hasExtension(filePath, extension) {
4
+ return filePath.toLowerCase().endsWith(extension);
5
+ }
6
+ function resolveInvocation(cliBin) {
7
+ if (hasExtension(cliBin, '.js')) {
8
+ return { command: 'node', prefixArgs: [cliBin] };
9
+ }
10
+ if (hasExtension(cliBin, '.ts')) {
11
+ return { command: 'bun', prefixArgs: [cliBin] };
12
+ }
13
+ return { command: cliBin, prefixArgs: [] };
14
+ }
15
+ /**
16
+ * Build the CLI argument vector for an operation invocation.
17
+ *
18
+ * Key design choices vs old SDK:
19
+ * - changeMode injection BEFORE argv loop, not after. changeMode is already a
20
+ * param in operationSpec.params (envelope param for mutations). Appending after
21
+ * the loop would duplicate it.
22
+ * - Booleans encoded as `--flag true`/`--flag false` explicitly, matching current CLI.
23
+ */
24
+ function buildOperationArgv(operation, params, options, runtimeTimeoutMs, defaultChangeMode, user) {
25
+ // Inject defaultChangeMode into params BEFORE encoding — single source of truth.
26
+ let normalizedParams = defaultChangeMode != null && params.changeMode == null && operation.params.some((p) => p.name === 'changeMode')
27
+ ? { ...params, changeMode: defaultChangeMode }
28
+ : params;
29
+ // Inject user identity for doc.open when not already specified.
30
+ if (user != null && operation.operationId === 'doc.open') {
31
+ if (normalizedParams.userName == null && user.name) {
32
+ normalizedParams = { ...normalizedParams, userName: user.name };
33
+ }
34
+ if (normalizedParams.userEmail == null && user.email) {
35
+ normalizedParams = { ...normalizedParams, userEmail: user.email };
36
+ }
37
+ }
38
+ const argv = [...operation.commandTokens];
39
+ for (const spec of operation.params) {
40
+ const value = normalizedParams[spec.name];
41
+ if (value == null)
42
+ continue;
43
+ const flag = `--${spec.flag ?? spec.name}`;
44
+ switch (spec.kind) {
45
+ case 'doc':
46
+ argv.push(String(value));
47
+ break;
48
+ case 'flag':
49
+ if (spec.type === 'boolean') {
50
+ // Explicit true/false — matches current CLI operation-executor.ts.
51
+ argv.push(flag, value === true ? 'true' : 'false');
52
+ }
53
+ else if (spec.type === 'string[]') {
54
+ if (Array.isArray(value)) {
55
+ for (const entry of value)
56
+ argv.push(flag, String(entry));
57
+ }
58
+ }
59
+ else {
60
+ argv.push(flag, String(value));
61
+ }
62
+ break;
63
+ case 'jsonFlag':
64
+ // CLI always parses --*-json values via JSON.parse, so even scalar
65
+ // strings must be serialized as JSON string literals.
66
+ argv.push(flag, JSON.stringify(value));
67
+ break;
68
+ }
69
+ }
70
+ const timeoutMs = options.timeoutMs ?? runtimeTimeoutMs;
71
+ if (timeoutMs != null) {
72
+ argv.push('--timeout-ms', String(timeoutMs));
73
+ }
74
+ argv.push('--output', 'json');
75
+ return argv;
76
+ }
77
+
78
+ exports.buildOperationArgv = buildOperationArgv;
79
+ exports.resolveInvocation = resolveInvocation;
@@ -17,6 +17,10 @@ export interface InvokeOptions {
17
17
  stdinBytes?: Uint8Array;
18
18
  }
19
19
  export type ChangeMode = 'direct' | 'tracked';
20
+ export interface UserIdentity {
21
+ name: string;
22
+ email?: string;
23
+ }
20
24
  export interface SuperDocClientOptions {
21
25
  env?: Record<string, string | undefined>;
22
26
  startupTimeoutMs?: number;
@@ -25,6 +29,7 @@ export interface SuperDocClientOptions {
25
29
  watchdogTimeoutMs?: number;
26
30
  maxQueueDepth?: number;
27
31
  defaultChangeMode?: ChangeMode;
32
+ user?: UserIdentity;
28
33
  }
29
34
  export interface CliInvocation {
30
35
  command: string;
@@ -40,5 +45,5 @@ export declare function resolveInvocation(cliBin: string): CliInvocation;
40
45
  * the loop would duplicate it.
41
46
  * - Booleans encoded as `--flag true`/`--flag false` explicitly, matching current CLI.
42
47
  */
43
- export declare function buildOperationArgv(operation: OperationSpec, params: Record<string, unknown>, options: InvokeOptions, runtimeTimeoutMs: number | undefined, defaultChangeMode?: ChangeMode): string[];
48
+ export declare function buildOperationArgv(operation: OperationSpec, params: Record<string, unknown>, options: InvokeOptions, runtimeTimeoutMs: number | undefined, defaultChangeMode?: ChangeMode, user?: UserIdentity): string[];
44
49
  //# sourceMappingURL=transport-common.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"transport-common.d.ts","sourceRoot":"","sources":["../../src/runtime/transport-common.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,SAAS,GAAG,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,MAAM,GAAG,UAAU,CAAC;AAC9E,MAAM,MAAM,SAAS,GAAG,KAAK,GAAG,MAAM,GAAG,UAAU,CAAC;AAEpD,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IACzB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IACzB,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,aAAa,EAAE,SAAS,MAAM,EAAE,CAAC;IAC1C,QAAQ,CAAC,MAAM,EAAE,SAAS,kBAAkB,EAAE,CAAC;CAChD;AAED,MAAM,WAAW,aAAa;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,UAAU,CAAC;CACzB;AAED,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,SAAS,CAAC;AAE9C,MAAM,WAAW,qBAAqB;IACpC,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;IACzC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,iBAAiB,CAAC,EAAE,UAAU,CAAC;CAChC;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,EAAE,CAAC;CACtB;AAMD,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,aAAa,CAU/D;AAED;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,aAAa,EACxB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,OAAO,EAAE,aAAa,EACtB,gBAAgB,EAAE,MAAM,GAAG,SAAS,EACpC,iBAAiB,CAAC,EAAE,UAAU,GAC7B,MAAM,EAAE,CA8CV"}
1
+ {"version":3,"file":"transport-common.d.ts","sourceRoot":"","sources":["../../src/runtime/transport-common.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,SAAS,GAAG,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,MAAM,GAAG,UAAU,CAAC;AAC9E,MAAM,MAAM,SAAS,GAAG,KAAK,GAAG,MAAM,GAAG,UAAU,CAAC;AAEpD,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IACzB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IACzB,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,aAAa,EAAE,SAAS,MAAM,EAAE,CAAC;IAC1C,QAAQ,CAAC,MAAM,EAAE,SAAS,kBAAkB,EAAE,CAAC;CAChD;AAED,MAAM,WAAW,aAAa;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,UAAU,CAAC;CACzB;AAED,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,SAAS,CAAC;AAE9C,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,qBAAqB;IACpC,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;IACzC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,iBAAiB,CAAC,EAAE,UAAU,CAAC;IAC/B,IAAI,CAAC,EAAE,YAAY,CAAC;CACrB;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,EAAE,CAAC;CACtB;AAMD,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,aAAa,CAU/D;AAED;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,aAAa,EACxB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,OAAO,EAAE,aAAa,EACtB,gBAAgB,EAAE,MAAM,GAAG,SAAS,EACpC,iBAAiB,CAAC,EAAE,UAAU,EAC9B,IAAI,CAAC,EAAE,YAAY,GAClB,MAAM,EAAE,CAwDV"}
@@ -19,13 +19,20 @@ export function resolveInvocation(cliBin) {
19
19
  * the loop would duplicate it.
20
20
  * - Booleans encoded as `--flag true`/`--flag false` explicitly, matching current CLI.
21
21
  */
22
- export function buildOperationArgv(operation, params, options, runtimeTimeoutMs, defaultChangeMode) {
22
+ export function buildOperationArgv(operation, params, options, runtimeTimeoutMs, defaultChangeMode, user) {
23
23
  // Inject defaultChangeMode into params BEFORE encoding — single source of truth.
24
- const normalizedParams = defaultChangeMode != null &&
25
- params.changeMode == null &&
26
- operation.params.some((p) => p.name === 'changeMode')
24
+ let normalizedParams = defaultChangeMode != null && params.changeMode == null && operation.params.some((p) => p.name === 'changeMode')
27
25
  ? { ...params, changeMode: defaultChangeMode }
28
26
  : params;
27
+ // Inject user identity for doc.open when not already specified.
28
+ if (user != null && operation.operationId === 'doc.open') {
29
+ if (normalizedParams.userName == null && user.name) {
30
+ normalizedParams = { ...normalizedParams, userName: user.name };
31
+ }
32
+ if (normalizedParams.userEmail == null && user.email) {
33
+ normalizedParams = { ...normalizedParams, userEmail: user.email };
34
+ }
35
+ }
29
36
  const argv = [...operation.commandTokens];
30
37
  for (const spec of operation.params) {
31
38
  const value = normalizedParams[spec.name];
@@ -52,6 +59,8 @@ export function buildOperationArgv(operation, params, options, runtimeTimeoutMs,
52
59
  }
53
60
  break;
54
61
  case 'jsonFlag':
62
+ // CLI always parses --*-json values via JSON.parse, so even scalar
63
+ // strings must be serialized as JSON string literals.
55
64
  argv.push(flag, JSON.stringify(value));
56
65
  break;
57
66
  }