@superdoc-dev/sdk 1.0.0-alpha.3 → 1.0.0-alpha.30

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 (67) hide show
  1. package/README.md +126 -0
  2. package/dist/generated/client.cjs +276 -0
  3. package/dist/generated/client.d.ts +7161 -0
  4. package/dist/generated/client.d.ts.map +1 -0
  5. package/dist/generated/client.js +271 -0
  6. package/dist/generated/contract.cjs +71828 -0
  7. package/dist/generated/contract.d.ts +34 -0
  8. package/dist/generated/contract.d.ts.map +1 -0
  9. package/dist/generated/contract.js +71843 -0
  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 +23 -0
  15. package/dist/index.d.ts.map +1 -0
  16. package/dist/index.js +29 -0
  17. package/dist/runtime/embedded-cli.cjs +100 -0
  18. package/dist/runtime/embedded-cli.d.ts +5 -0
  19. package/dist/runtime/embedded-cli.d.ts.map +1 -0
  20. package/dist/runtime/embedded-cli.js +94 -0
  21. package/dist/runtime/errors.cjs +22 -0
  22. package/dist/runtime/errors.d.ts +17 -0
  23. package/dist/runtime/errors.d.ts.map +1 -0
  24. package/dist/runtime/errors.js +18 -0
  25. package/dist/runtime/host.cjs +352 -0
  26. package/dist/runtime/host.d.ts +37 -0
  27. package/dist/runtime/host.d.ts.map +1 -0
  28. package/dist/runtime/host.js +347 -0
  29. package/dist/runtime/process.cjs +32 -0
  30. package/dist/runtime/process.d.ts +16 -0
  31. package/dist/runtime/process.d.ts.map +1 -0
  32. package/dist/runtime/process.js +27 -0
  33. package/dist/runtime/transport-common.cjs +77 -0
  34. package/dist/runtime/transport-common.d.ts +49 -0
  35. package/dist/runtime/transport-common.d.ts.map +1 -0
  36. package/dist/runtime/transport-common.js +72 -0
  37. package/dist/skills.cjs +148 -0
  38. package/dist/skills.d.ts +25 -0
  39. package/dist/skills.d.ts.map +1 -0
  40. package/dist/skills.js +140 -0
  41. package/dist/tools.cjs +378 -0
  42. package/dist/tools.d.ts +113 -0
  43. package/dist/tools.d.ts.map +1 -0
  44. package/dist/tools.js +367 -0
  45. package/package.json +21 -11
  46. package/skills/editing-docx.md +24 -150
  47. package/tools/catalog.json +75676 -0
  48. package/tools/tool-name-map.json +436 -0
  49. package/tools/tools-policy.json +100 -0
  50. package/tools/tools.anthropic.json +31001 -0
  51. package/tools/tools.generic.json +72783 -0
  52. package/tools/tools.openai.json +32303 -0
  53. package/tools/tools.vercel.json +32303 -0
  54. package/src/__tests__/skills.test.ts +0 -166
  55. package/src/__tests__/tools.test.ts +0 -96
  56. package/src/generated/client.ts +0 -3643
  57. package/src/generated/contract.ts +0 -15952
  58. package/src/index.ts +0 -87
  59. package/src/runtime/__tests__/process.test.ts +0 -38
  60. package/src/runtime/__tests__/transport-common.test.ts +0 -174
  61. package/src/runtime/embedded-cli.ts +0 -109
  62. package/src/runtime/errors.ts +0 -30
  63. package/src/runtime/host.ts +0 -481
  64. package/src/runtime/process.ts +0 -45
  65. package/src/runtime/transport-common.ts +0 -169
  66. package/src/skills.ts +0 -195
  67. package/src/tools.ts +0 -701
@@ -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;
@@ -0,0 +1,37 @@
1
+ import { type InvokeOptions, type OperationSpec, type SuperDocClientOptions } from './transport-common.js';
2
+ /**
3
+ * Transport that communicates with a long-lived CLI host process over JSON-RPC stdio.
4
+ */
5
+ export declare class HostTransport {
6
+ private readonly cliBin;
7
+ private readonly env?;
8
+ private readonly startupTimeoutMs;
9
+ private readonly shutdownTimeoutMs;
10
+ private readonly requestTimeoutMs?;
11
+ private readonly watchdogTimeoutMs;
12
+ private readonly maxQueueDepth;
13
+ private readonly defaultChangeMode?;
14
+ private readonly user?;
15
+ private child;
16
+ private stdoutReader;
17
+ private readonly pending;
18
+ private nextRequestId;
19
+ private connecting;
20
+ private stopping;
21
+ constructor(options: {
22
+ cliBin: string;
23
+ } & SuperDocClientOptions);
24
+ connect(): Promise<void>;
25
+ dispose(): Promise<void>;
26
+ invoke<TData = unknown>(operation: OperationSpec, params?: Record<string, unknown>, options?: InvokeOptions): Promise<TData>;
27
+ private ensureConnected;
28
+ private startHostProcess;
29
+ private assertCapabilities;
30
+ private resolveWatchdogTimeout;
31
+ private sendJsonRpcRequest;
32
+ private onStdoutLine;
33
+ private mapJsonRpcError;
34
+ private handleDisconnect;
35
+ private cleanupProcess;
36
+ }
37
+ //# sourceMappingURL=host.d.ts.map
@@ -0,0 +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,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"}