stitchkit 0.77.0 → 0.79.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-runtime-browser.js +53 -581
- package/dist/agent-runtime-coding-tools.js +6 -5
- package/dist/agent-runtime-harness.js +20 -93
- package/dist/agent-runtime-openrouter.js +1 -1
- package/dist/agent-runtime.js +65 -61
- package/dist/application/decisions.d.ts +28 -25
- package/dist/application/decisions.d.ts.map +1 -1
- package/dist/application/kernel.d.ts +2 -0
- package/dist/application/kernel.d.ts.map +1 -1
- package/dist/application/keyspace.d.ts +11 -1
- package/dist/application/keyspace.d.ts.map +1 -1
- package/dist/application/schedule.d.ts.map +1 -1
- package/dist/application/schemas.d.ts +2 -0
- package/dist/application/schemas.d.ts.map +1 -1
- package/dist/application/server-resource.d.ts.map +1 -1
- package/dist/application/watch-hub.d.ts.map +1 -1
- package/dist/application-diagnostic-journal.d.ts +21 -0
- package/dist/application-diagnostic-journal.d.ts.map +1 -0
- package/dist/application-diagnostic-journal.js +632 -0
- package/dist/application-opentelemetry.js +3 -2
- package/dist/application-schemas.js +14 -98
- package/dist/application.d.ts +1 -2
- package/dist/application.d.ts.map +1 -1
- package/dist/application.js +155 -882
- package/dist/cli.js +13 -11
- package/dist/contract/index.js +15 -10
- package/dist/files/boundary.d.ts.map +1 -1
- package/dist/files.js +1 -1
- package/dist/{index-7b188kmz.js → index-2qzskm8h.js} +15 -1
- package/dist/{index-k2zczx1g.js → index-2rwwmr7v.js} +3 -3
- package/dist/{index-8eywc9zv.js → index-3gye9wzb.js} +6 -3
- package/dist/index-4fpa9dy2.js +51 -0
- package/dist/{index-7qy2ex0m.js → index-5mtc969c.js} +2 -2
- package/dist/index-5s3zajp8.js +192 -0
- package/dist/{index-3cwck0rm.js → index-6s7n2v50.js} +60 -374
- package/dist/{index-s4c8wy8m.js → index-758zx2ha.js} +11 -90
- package/dist/{index-qyrqwr4c.js → index-77fekveh.js} +4 -1
- package/dist/{index-58jzmnn4.js → index-7ag81v2f.js} +355 -34
- package/dist/index-7gnkny4z.js +326 -0
- package/dist/index-7zbps32p.js +89 -0
- package/dist/index-85vfqd7m.js +135 -0
- package/dist/{index-m668wzyc.js → index-9s6z8vgf.js} +17 -141
- package/dist/{index-bfcpjw20.js → index-actkayzn.js} +7 -3
- package/dist/index-b9aefrqd.js +20 -0
- package/dist/index-dre2ywck.js +48 -0
- package/dist/{index-nemjkxjp.js → index-dwf1f2ap.js} +16 -12
- package/dist/{index-wwst0td5.js → index-dx9xehwt.js} +1 -1
- package/dist/{index-ezmn6ac6.js → index-dxesg10d.js} +4 -4
- package/dist/{index-aczggrty.js → index-dxjjv399.js} +2 -2
- package/dist/{index-jqtsc9mj.js → index-egaabxkz.js} +3 -3
- package/dist/{index-vc1b0b1b.js → index-evcnmsc3.js} +49 -8
- package/dist/{index-nt1mp8km.js → index-fxz0v7vg.js} +84 -84
- package/dist/index-h4pj6fta.js +87 -0
- package/dist/{index-1rxswfbv.js → index-hb5pf3s4.js} +1 -1
- package/dist/{index-t8qyvrvg.js → index-k9ay6v6d.js} +21 -272
- package/dist/index-kzfs85xp.js +9 -0
- package/dist/{index-vbf2p6me.js → index-m9kzax52.js} +91 -89
- package/dist/{index-22by16v6.js → index-mgtxfe6b.js} +1 -1
- package/dist/index-p7hgdyhb.js +22 -0
- package/dist/index-pq95qkbf.js +0 -0
- package/dist/index-t0z5p5w6.js +318 -0
- package/dist/{index-s2rchahr.js → index-vwp69871.js} +13 -11
- package/dist/index-wc4x00bn.js +103 -0
- package/dist/{index-da1aqnhb.js → index-xcetq6j3.js} +8 -6
- package/dist/{index-f6n5n7nz.js → index-y01f4223.js} +33 -126
- package/dist/{index-35z5h2ty.js → index-ywd0y6m1.js} +18 -218
- package/dist/index.js +65 -1588
- package/dist/internal/deadline.d.ts +17 -0
- package/dist/internal/deadline.d.ts.map +1 -0
- package/dist/live.js +15 -89
- package/dist/node.js +17 -15
- package/dist/observability/context.d.ts.map +1 -1
- package/dist/observability/index.js +7 -6
- package/dist/primitives.js +5 -2
- package/dist/react.js +1 -1
- package/dist/remote.js +7 -6
- package/dist/server/event-bus.d.ts.map +1 -1
- package/dist/server/index.js +26 -38
- package/dist/telegram.js +1 -1
- package/dist/testing.js +86 -97
- package/dist/tool-invoker.js +11 -9
- package/dist/tools/async-operation-contract.d.ts +61 -0
- package/dist/tools/async-operation-contract.d.ts.map +1 -0
- package/dist/tools/async-operation.d.ts +2 -47
- package/dist/tools/async-operation.d.ts.map +1 -1
- package/dist/tools/view-file-contract.d.ts +98 -0
- package/dist/tools/view-file-contract.d.ts.map +1 -0
- package/dist/tools/view-file.d.ts +4 -83
- package/dist/tools/view-file.d.ts.map +1 -1
- package/dist/tools-contract.d.ts +29 -0
- package/dist/tools-contract.d.ts.map +1 -0
- package/dist/tools-contract.js +24 -0
- package/dist/tools.d.ts +3 -3
- package/dist/tools.d.ts.map +1 -1
- package/dist/tools.js +59 -95
- package/llms-full.txt +146 -14
- package/package.json +14 -7
- package/dist/index-ksp6e2ye.js +0 -24
- package/dist/index-vj3vvpaa.js +0 -307
|
@@ -1,69 +1,15 @@
|
|
|
1
1
|
import {
|
|
2
|
-
isUnsafeKey,
|
|
3
2
|
mergeMeta
|
|
4
|
-
} from "./index-
|
|
3
|
+
} from "./index-y01f4223.js";
|
|
4
|
+
import {
|
|
5
|
+
isUnsafeKey
|
|
6
|
+
} from "./index-kzfs85xp.js";
|
|
5
7
|
import {
|
|
6
8
|
callRuntimeHandler,
|
|
7
9
|
isRecord,
|
|
8
10
|
transportResult,
|
|
9
11
|
typedEntries
|
|
10
|
-
} from "./index-
|
|
11
|
-
|
|
12
|
-
// src/server/middleware/cors.ts
|
|
13
|
-
var DEFAULT_CORS_ALLOW_HEADERS = "Content-Type, Authorization, X-Trace-Id, traceparent, tracestate";
|
|
14
|
-
var DEFAULT_CORS_EXPOSE_HEADERS = "Content-Disposition, Content-Length, Content-Range, Accept-Ranges, ETag, Last-Modified, X-Request-Id";
|
|
15
|
-
function assertCorsConfig(config) {
|
|
16
|
-
if (config.credentials && (config.origin === undefined || config.origin === "*")) {
|
|
17
|
-
throw new Error("[stitchkit] cors: `credentials: true` cannot be combined with a wildcard origin. " + "Set `origin` to an explicit string or list.");
|
|
18
|
-
}
|
|
19
|
-
if (config.origin === undefined) {
|
|
20
|
-
throw new Error("[stitchkit] cors: `origin` is required. Pass an explicit origin (or list), or '*' to deliberately allow every origin — omit `cors` entirely to emit no CORS headers.");
|
|
21
|
-
}
|
|
22
|
-
if (Array.isArray(config.origin) && config.origin.length === 0) {
|
|
23
|
-
throw new Error("[stitchkit] cors: `origin` cannot be an empty list. Pass explicit origins, or '*' to deliberately allow every origin.");
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
function resolveOrigin(config, requestOrigin) {
|
|
27
|
-
if (config.origin === undefined)
|
|
28
|
-
return;
|
|
29
|
-
if (config.origin === "*") {
|
|
30
|
-
return "*";
|
|
31
|
-
}
|
|
32
|
-
if (Array.isArray(config.origin)) {
|
|
33
|
-
if (!requestOrigin)
|
|
34
|
-
return;
|
|
35
|
-
const lower = requestOrigin.toLowerCase();
|
|
36
|
-
return config.origin.some((o) => o.toLowerCase() === lower) ? requestOrigin : undefined;
|
|
37
|
-
}
|
|
38
|
-
return config.origin;
|
|
39
|
-
}
|
|
40
|
-
function corsHeaders(config, requestOrigin) {
|
|
41
|
-
const allowOrigin = resolveOrigin(config, requestOrigin);
|
|
42
|
-
const headers = {
|
|
43
|
-
"Access-Control-Allow-Methods": config.methods ?? "GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS",
|
|
44
|
-
"Access-Control-Allow-Headers": config.headers ?? DEFAULT_CORS_ALLOW_HEADERS
|
|
45
|
-
};
|
|
46
|
-
const expose = Array.isArray(config.exposeHeaders) ? config.exposeHeaders.join(", ") : config.exposeHeaders ?? DEFAULT_CORS_EXPOSE_HEADERS;
|
|
47
|
-
if (expose !== "") {
|
|
48
|
-
headers["Access-Control-Expose-Headers"] = expose;
|
|
49
|
-
}
|
|
50
|
-
if (allowOrigin !== undefined) {
|
|
51
|
-
headers["Access-Control-Allow-Origin"] = allowOrigin;
|
|
52
|
-
if (config.credentials) {
|
|
53
|
-
headers["Access-Control-Allow-Credentials"] = "true";
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
if (Array.isArray(config.origin)) {
|
|
57
|
-
headers.Vary = "Origin";
|
|
58
|
-
}
|
|
59
|
-
return headers;
|
|
60
|
-
}
|
|
61
|
-
function corsPreflightResponse(config, req) {
|
|
62
|
-
return new Response(null, {
|
|
63
|
-
status: 204,
|
|
64
|
-
headers: corsHeaders(config, req.headers.get("origin"))
|
|
65
|
-
});
|
|
66
|
-
}
|
|
12
|
+
} from "./index-77fekveh.js";
|
|
67
13
|
|
|
68
14
|
// src/server/implement.ts
|
|
69
15
|
function isStreamingImplementation(value) {
|
|
@@ -248,6 +194,91 @@ function createImplementRegistry() {
|
|
|
248
194
|
return (contracts, handlers) => transportResult(bindRegistry(contracts, handlers));
|
|
249
195
|
}
|
|
250
196
|
|
|
197
|
+
// src/server/middleware/cors.ts
|
|
198
|
+
var DEFAULT_CORS_ALLOW_HEADERS = "Content-Type, Authorization, X-Trace-Id, traceparent, tracestate";
|
|
199
|
+
var DEFAULT_CORS_EXPOSE_HEADERS = "Content-Disposition, Content-Length, Content-Range, Accept-Ranges, ETag, Last-Modified, X-Request-Id";
|
|
200
|
+
function assertCorsConfig(config) {
|
|
201
|
+
if (config.credentials && (config.origin === undefined || config.origin === "*")) {
|
|
202
|
+
throw new Error("[stitchkit] cors: `credentials: true` cannot be combined with a wildcard origin. " + "Set `origin` to an explicit string or list.");
|
|
203
|
+
}
|
|
204
|
+
if (config.origin === undefined) {
|
|
205
|
+
throw new Error("[stitchkit] cors: `origin` is required. Pass an explicit origin (or list), or '*' to deliberately allow every origin — omit `cors` entirely to emit no CORS headers.");
|
|
206
|
+
}
|
|
207
|
+
if (Array.isArray(config.origin) && config.origin.length === 0) {
|
|
208
|
+
throw new Error("[stitchkit] cors: `origin` cannot be an empty list. Pass explicit origins, or '*' to deliberately allow every origin.");
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
function resolveOrigin(config, requestOrigin) {
|
|
212
|
+
if (config.origin === undefined)
|
|
213
|
+
return;
|
|
214
|
+
if (config.origin === "*") {
|
|
215
|
+
return "*";
|
|
216
|
+
}
|
|
217
|
+
if (Array.isArray(config.origin)) {
|
|
218
|
+
if (!requestOrigin)
|
|
219
|
+
return;
|
|
220
|
+
const lower = requestOrigin.toLowerCase();
|
|
221
|
+
return config.origin.some((o) => o.toLowerCase() === lower) ? requestOrigin : undefined;
|
|
222
|
+
}
|
|
223
|
+
return config.origin;
|
|
224
|
+
}
|
|
225
|
+
function corsHeaders(config, requestOrigin) {
|
|
226
|
+
const allowOrigin = resolveOrigin(config, requestOrigin);
|
|
227
|
+
const headers = {
|
|
228
|
+
"Access-Control-Allow-Methods": config.methods ?? "GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS",
|
|
229
|
+
"Access-Control-Allow-Headers": config.headers ?? DEFAULT_CORS_ALLOW_HEADERS
|
|
230
|
+
};
|
|
231
|
+
const expose = Array.isArray(config.exposeHeaders) ? config.exposeHeaders.join(", ") : config.exposeHeaders ?? DEFAULT_CORS_EXPOSE_HEADERS;
|
|
232
|
+
if (expose !== "") {
|
|
233
|
+
headers["Access-Control-Expose-Headers"] = expose;
|
|
234
|
+
}
|
|
235
|
+
if (allowOrigin !== undefined) {
|
|
236
|
+
headers["Access-Control-Allow-Origin"] = allowOrigin;
|
|
237
|
+
if (config.credentials) {
|
|
238
|
+
headers["Access-Control-Allow-Credentials"] = "true";
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
if (Array.isArray(config.origin)) {
|
|
242
|
+
headers.Vary = "Origin";
|
|
243
|
+
}
|
|
244
|
+
return headers;
|
|
245
|
+
}
|
|
246
|
+
function corsPreflightResponse(config, req) {
|
|
247
|
+
return new Response(null, {
|
|
248
|
+
status: 204,
|
|
249
|
+
headers: corsHeaders(config, req.headers.get("origin"))
|
|
250
|
+
});
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
// src/server/process-signal-common.ts
|
|
254
|
+
var DEFAULT_PROCESS_SIGNALS = ["SIGINT", "SIGTERM"];
|
|
255
|
+
var defaultSignalSource = {
|
|
256
|
+
on: (signal, handler) => {
|
|
257
|
+
process.on(signal, handler);
|
|
258
|
+
},
|
|
259
|
+
off: (signal, handler) => {
|
|
260
|
+
process.off(signal, handler);
|
|
261
|
+
},
|
|
262
|
+
raiseDefault: (signal) => {
|
|
263
|
+
if (process.listenerCount(signal) > 0)
|
|
264
|
+
return false;
|
|
265
|
+
process.kill(process.pid, signal);
|
|
266
|
+
return true;
|
|
267
|
+
}
|
|
268
|
+
};
|
|
269
|
+
function reportSignalError(phase, error, onError) {
|
|
270
|
+
try {
|
|
271
|
+
onError?.(phase, error);
|
|
272
|
+
} catch {}
|
|
273
|
+
}
|
|
274
|
+
function guardSignalCallback(run, phase, onError) {
|
|
275
|
+
try {
|
|
276
|
+
run();
|
|
277
|
+
} catch (error) {
|
|
278
|
+
reportSignalError(phase, error, onError);
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
|
|
251
282
|
// src/server/context-contribution.ts
|
|
252
283
|
var RUNTIME_CONTEXT_RESERVED_KEYS = new Set([
|
|
253
284
|
"params",
|
|
@@ -342,33 +373,4 @@ function mergeContextContribution(ctx, value, scope) {
|
|
|
342
373
|
Object.assign(ctx, prepareContextContribution(value, scope));
|
|
343
374
|
}
|
|
344
375
|
|
|
345
|
-
|
|
346
|
-
var DEFAULT_PROCESS_SIGNALS = ["SIGINT", "SIGTERM"];
|
|
347
|
-
var defaultSignalSource = {
|
|
348
|
-
on: (signal, handler) => {
|
|
349
|
-
process.on(signal, handler);
|
|
350
|
-
},
|
|
351
|
-
off: (signal, handler) => {
|
|
352
|
-
process.off(signal, handler);
|
|
353
|
-
},
|
|
354
|
-
raiseDefault: (signal) => {
|
|
355
|
-
if (process.listenerCount(signal) > 0)
|
|
356
|
-
return false;
|
|
357
|
-
process.kill(process.pid, signal);
|
|
358
|
-
return true;
|
|
359
|
-
}
|
|
360
|
-
};
|
|
361
|
-
function reportSignalError(phase, error, onError) {
|
|
362
|
-
try {
|
|
363
|
-
onError?.(phase, error);
|
|
364
|
-
} catch {}
|
|
365
|
-
}
|
|
366
|
-
function guardSignalCallback(run, phase, onError) {
|
|
367
|
-
try {
|
|
368
|
-
run();
|
|
369
|
-
} catch (error) {
|
|
370
|
-
reportSignalError(phase, error, onError);
|
|
371
|
-
}
|
|
372
|
-
}
|
|
373
|
-
|
|
374
|
-
export { RUNTIME_CONTEXT_RESERVED_KEYS, contextContributionDelta, prepareContextContribution, mergeContextContribution, DEFAULT_CORS_ALLOW_HEADERS, DEFAULT_CORS_EXPOSE_HEADERS, assertCorsConfig, corsHeaders, corsPreflightResponse, defineMultipartStream, createMultipartStream, contractOnlyService, implement, createImplement, createScopedImplement, createScopedImplementRegistry, implementRegistry, createImplementRegistry, DEFAULT_PROCESS_SIGNALS, defaultSignalSource, reportSignalError, guardSignalCallback };
|
|
376
|
+
export { defineMultipartStream, createMultipartStream, contractOnlyService, implement, createImplement, createScopedImplement, createScopedImplementRegistry, implementRegistry, createImplementRegistry, DEFAULT_CORS_ALLOW_HEADERS, DEFAULT_CORS_EXPOSE_HEADERS, assertCorsConfig, corsHeaders, corsPreflightResponse, DEFAULT_PROCESS_SIGNALS, defaultSignalSource, reportSignalError, guardSignalCallback, RUNTIME_CONTEXT_RESERVED_KEYS, contextContributionDelta, prepareContextContribution, mergeContextContribution };
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
// src/realtime/contract.ts
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
function defineRealtimeContract(contract) {
|
|
4
|
+
return contract;
|
|
5
|
+
}
|
|
6
|
+
var RealtimeRejectDirectionSchema = z.enum([
|
|
7
|
+
"client-inbound",
|
|
8
|
+
"client-outbound",
|
|
9
|
+
"server-inbound",
|
|
10
|
+
"server-outbound"
|
|
11
|
+
]);
|
|
12
|
+
var RealtimeRejectPhaseSchema = z.enum(["arguments", "acknowledgement"]);
|
|
13
|
+
var RealtimeRejectReasonSchema = z.enum([
|
|
14
|
+
"unknown-event",
|
|
15
|
+
"invalid-arguments",
|
|
16
|
+
"invalid-acknowledgement-value",
|
|
17
|
+
"missing-acknowledgement",
|
|
18
|
+
"rejected-by-peer"
|
|
19
|
+
]);
|
|
20
|
+
var RealtimeRejectFaultSchema = z.enum(["peer", "local"]);
|
|
21
|
+
|
|
22
|
+
export { defineRealtimeContract, RealtimeRejectDirectionSchema, RealtimeRejectPhaseSchema, RealtimeRejectReasonSchema, RealtimeRejectFaultSchema };
|
|
File without changes
|
|
@@ -0,0 +1,318 @@
|
|
|
1
|
+
import {
|
|
2
|
+
RealtimeRequestInvalidAcknowledgementError,
|
|
3
|
+
RealtimeRequestRejectedError
|
|
4
|
+
} from "./index-2qzskm8h.js";
|
|
5
|
+
import {
|
|
6
|
+
zodIssues
|
|
7
|
+
} from "./index-fxz0v7vg.js";
|
|
8
|
+
import {
|
|
9
|
+
AppError
|
|
10
|
+
} from "./index-0w9abg87.js";
|
|
11
|
+
|
|
12
|
+
// src/realtime/rejected-frame.ts
|
|
13
|
+
var REALTIME_REJECTION_KEY = "@stitchkit/realtime-rejected";
|
|
14
|
+
var MAX_REJECTION_ISSUES = 20;
|
|
15
|
+
function realtimeRejectionEnvelope(report) {
|
|
16
|
+
return { [REALTIME_REJECTION_KEY]: report };
|
|
17
|
+
}
|
|
18
|
+
function asRealtimeRejection(value) {
|
|
19
|
+
if (typeof value !== "object" || value === null)
|
|
20
|
+
return null;
|
|
21
|
+
const report = Reflect.get(value, REALTIME_REJECTION_KEY);
|
|
22
|
+
if (typeof report !== "object" || report === null)
|
|
23
|
+
return null;
|
|
24
|
+
const event = Reflect.get(report, "event");
|
|
25
|
+
const reason = Reflect.get(report, "reason");
|
|
26
|
+
const message = Reflect.get(report, "message");
|
|
27
|
+
if (typeof event !== "string" || typeof reason !== "string" || typeof message !== "string") {
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
if (reason.length === 0)
|
|
31
|
+
return null;
|
|
32
|
+
const issues = parseIssues(Reflect.get(report, "issues"));
|
|
33
|
+
return { event, reason, message, ...issues !== undefined && { issues } };
|
|
34
|
+
}
|
|
35
|
+
function parseIssues(value) {
|
|
36
|
+
if (!Array.isArray(value))
|
|
37
|
+
return;
|
|
38
|
+
const issues = [];
|
|
39
|
+
for (const entry of value.slice(0, MAX_REJECTION_ISSUES)) {
|
|
40
|
+
if (typeof entry !== "object" || entry === null)
|
|
41
|
+
continue;
|
|
42
|
+
const path = Reflect.get(entry, "path");
|
|
43
|
+
const code = Reflect.get(entry, "code");
|
|
44
|
+
const message = Reflect.get(entry, "message");
|
|
45
|
+
if (typeof path === "string" && typeof code === "string" && typeof message === "string") {
|
|
46
|
+
issues.push({ path, code, message });
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return issues.length > 0 ? issues : undefined;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// src/internal/optional-peer.ts
|
|
53
|
+
function isModuleNotFound(error) {
|
|
54
|
+
if (typeof error !== "object" || error === null)
|
|
55
|
+
return false;
|
|
56
|
+
const code = "code" in error ? error.code : undefined;
|
|
57
|
+
const message = "message" in error && typeof error.message === "string" ? error.message : "";
|
|
58
|
+
return code === "ERR_MODULE_NOT_FOUND" || code === "MODULE_NOT_FOUND" || message.includes("Cannot find module") || message.includes("Cannot find package");
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// src/realtime/rejection.ts
|
|
62
|
+
import { z } from "zod";
|
|
63
|
+
function realtimeContractViolation(options) {
|
|
64
|
+
const issues = options.cause instanceof z.ZodError ? zodIssues(options.cause) : undefined;
|
|
65
|
+
const reason = options.reason.replaceAll("-", " ");
|
|
66
|
+
const error = new AppError("REALTIME_CONTRACT_VIOLATION", `Realtime event "${options.event}" (${options.direction}, ${options.phase}): ${reason}`, 500, {
|
|
67
|
+
event: options.event,
|
|
68
|
+
direction: options.direction,
|
|
69
|
+
phase: options.phase,
|
|
70
|
+
reason: options.reason,
|
|
71
|
+
fault: options.fault,
|
|
72
|
+
...issues !== undefined && { issues }
|
|
73
|
+
});
|
|
74
|
+
if (options.cause !== undefined)
|
|
75
|
+
error.cause = options.cause;
|
|
76
|
+
return { ...options, error };
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// src/realtime/socket.ts
|
|
80
|
+
function method(target, name) {
|
|
81
|
+
const value = Reflect.get(target, name);
|
|
82
|
+
if (typeof value !== "function") {
|
|
83
|
+
throw new Error(`Realtime target does not implement ${name}()`);
|
|
84
|
+
}
|
|
85
|
+
return (...args) => Reflect.apply(value, target, args);
|
|
86
|
+
}
|
|
87
|
+
function splitWireArguments(definition, args) {
|
|
88
|
+
const trailing = args.at(-1);
|
|
89
|
+
const replyTo = typeof trailing === "function" ? (...callbackArgs) => Reflect.apply(trailing, undefined, callbackArgs) : undefined;
|
|
90
|
+
if (!definition.ack || !replyTo)
|
|
91
|
+
return { values: args, ...replyTo && { replyTo } };
|
|
92
|
+
return { values: args.slice(0, -1), acknowledgement: replyTo, replyTo };
|
|
93
|
+
}
|
|
94
|
+
function eventDefinition(registry, event, direction) {
|
|
95
|
+
const definition = registry[event];
|
|
96
|
+
if (!definition) {
|
|
97
|
+
throw realtimeContractViolation({
|
|
98
|
+
event,
|
|
99
|
+
direction,
|
|
100
|
+
phase: "arguments",
|
|
101
|
+
reason: "unknown-event",
|
|
102
|
+
fault: "local"
|
|
103
|
+
}).error;
|
|
104
|
+
}
|
|
105
|
+
return definition;
|
|
106
|
+
}
|
|
107
|
+
function reportRejected(rejected, hook, logger) {
|
|
108
|
+
if (!hook) {
|
|
109
|
+
if (logger) {
|
|
110
|
+
logger.warn(rejected.error.message, rejected.error.details);
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
console.warn(`[stitchkit] rejected realtime ${rejected.direction} event "${rejected.event}" (${rejected.phase})`, rejected.error);
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
Promise.resolve(hook(rejected)).catch((error) => {
|
|
117
|
+
console.error("[stitchkit] realtime rejection hook failed", error);
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
function answerWithRejection(acknowledgement, report, logger) {
|
|
121
|
+
if (!acknowledgement)
|
|
122
|
+
return;
|
|
123
|
+
try {
|
|
124
|
+
acknowledgement(realtimeRejectionEnvelope(report));
|
|
125
|
+
} catch (error) {
|
|
126
|
+
const message = "[stitchkit] could not answer a rejected realtime frame";
|
|
127
|
+
if (logger)
|
|
128
|
+
logger.warn(message, { error });
|
|
129
|
+
else
|
|
130
|
+
console.warn(message, error);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
function parseRealtimeRequestArguments(registry, event, direction, args) {
|
|
134
|
+
const definition = eventDefinition(registry, event, direction);
|
|
135
|
+
const parsed = definition.args.safeParse(args);
|
|
136
|
+
if (!parsed.success) {
|
|
137
|
+
throw realtimeContractViolation({
|
|
138
|
+
event,
|
|
139
|
+
direction,
|
|
140
|
+
phase: "arguments",
|
|
141
|
+
reason: "invalid-arguments",
|
|
142
|
+
fault: "local",
|
|
143
|
+
cause: parsed.error
|
|
144
|
+
}).error;
|
|
145
|
+
}
|
|
146
|
+
if (!definition.ack) {
|
|
147
|
+
throw realtimeContractViolation({
|
|
148
|
+
event,
|
|
149
|
+
direction,
|
|
150
|
+
phase: "acknowledgement",
|
|
151
|
+
reason: "missing-acknowledgement",
|
|
152
|
+
fault: "local"
|
|
153
|
+
}).error;
|
|
154
|
+
}
|
|
155
|
+
return parsed.data;
|
|
156
|
+
}
|
|
157
|
+
function parseRealtimeRequestAcknowledgement(schema, event, direction, value, hook, logger) {
|
|
158
|
+
const refusal = asRealtimeRejection(value);
|
|
159
|
+
if (refusal) {
|
|
160
|
+
reportRejected(realtimeContractViolation({
|
|
161
|
+
event,
|
|
162
|
+
direction,
|
|
163
|
+
phase: "arguments",
|
|
164
|
+
reason: "rejected-by-peer",
|
|
165
|
+
fault: "local"
|
|
166
|
+
}), hook, logger);
|
|
167
|
+
throw new RealtimeRequestRejectedError(event, refusal.reason, refusal.message, refusal.issues);
|
|
168
|
+
}
|
|
169
|
+
const parsed = schema.safeParse(value);
|
|
170
|
+
if (parsed.success)
|
|
171
|
+
return parsed.data;
|
|
172
|
+
const rejected = realtimeContractViolation({
|
|
173
|
+
event,
|
|
174
|
+
direction,
|
|
175
|
+
phase: "acknowledgement",
|
|
176
|
+
reason: "invalid-acknowledgement-value",
|
|
177
|
+
fault: "peer",
|
|
178
|
+
cause: parsed.error
|
|
179
|
+
});
|
|
180
|
+
reportRejected(rejected, hook, logger);
|
|
181
|
+
throw new RealtimeRequestInvalidAcknowledgementError(event, rejected.error);
|
|
182
|
+
}
|
|
183
|
+
function createValidatedRealtimeSocket({
|
|
184
|
+
target,
|
|
185
|
+
inbound,
|
|
186
|
+
outbound,
|
|
187
|
+
inboundDirection,
|
|
188
|
+
outboundDirection,
|
|
189
|
+
onRejected,
|
|
190
|
+
logger,
|
|
191
|
+
subscribe
|
|
192
|
+
}) {
|
|
193
|
+
const emitTarget = method(target, "emit");
|
|
194
|
+
return {
|
|
195
|
+
on: (event, handler) => {
|
|
196
|
+
const definition = eventDefinition(inbound, event, inboundDirection);
|
|
197
|
+
const wrapped = (...wireArgs) => {
|
|
198
|
+
const { values, acknowledgement, replyTo } = splitWireArguments(definition, wireArgs);
|
|
199
|
+
const parsed = definition.args.safeParse(values);
|
|
200
|
+
if (!parsed.success) {
|
|
201
|
+
const rejected = realtimeContractViolation({
|
|
202
|
+
event,
|
|
203
|
+
direction: inboundDirection,
|
|
204
|
+
phase: "arguments",
|
|
205
|
+
reason: "invalid-arguments",
|
|
206
|
+
fault: "peer",
|
|
207
|
+
cause: parsed.error
|
|
208
|
+
});
|
|
209
|
+
reportRejected(rejected, onRejected, logger);
|
|
210
|
+
answerWithRejection(replyTo, {
|
|
211
|
+
event,
|
|
212
|
+
reason: "invalid-arguments",
|
|
213
|
+
message: rejected.error.message,
|
|
214
|
+
issues: zodIssues(parsed.error).slice(0, MAX_REJECTION_ISSUES)
|
|
215
|
+
}, logger);
|
|
216
|
+
return;
|
|
217
|
+
}
|
|
218
|
+
if (definition.ack && !acknowledgement) {
|
|
219
|
+
reportRejected(realtimeContractViolation({
|
|
220
|
+
event,
|
|
221
|
+
direction: inboundDirection,
|
|
222
|
+
phase: "acknowledgement",
|
|
223
|
+
reason: "missing-acknowledgement",
|
|
224
|
+
fault: "peer"
|
|
225
|
+
}), onRejected, logger);
|
|
226
|
+
return;
|
|
227
|
+
}
|
|
228
|
+
const applicationArgs = [...parsed.data];
|
|
229
|
+
if (definition.ack) {
|
|
230
|
+
applicationArgs.push((value) => {
|
|
231
|
+
const ack = definition.ack?.safeParse(value);
|
|
232
|
+
if (!ack?.success) {
|
|
233
|
+
if (ack) {
|
|
234
|
+
reportRejected(realtimeContractViolation({
|
|
235
|
+
event,
|
|
236
|
+
direction: outboundDirection,
|
|
237
|
+
phase: "acknowledgement",
|
|
238
|
+
reason: "invalid-acknowledgement-value",
|
|
239
|
+
fault: "local",
|
|
240
|
+
cause: ack.error
|
|
241
|
+
}), onRejected, logger);
|
|
242
|
+
}
|
|
243
|
+
return;
|
|
244
|
+
}
|
|
245
|
+
acknowledgement?.(ack.data);
|
|
246
|
+
});
|
|
247
|
+
}
|
|
248
|
+
Reflect.apply(handler, undefined, applicationArgs);
|
|
249
|
+
};
|
|
250
|
+
if (subscribe)
|
|
251
|
+
return subscribe(event, wrapped);
|
|
252
|
+
const onTarget = method(target, "on");
|
|
253
|
+
const offTarget = method(target, "off");
|
|
254
|
+
onTarget(event, wrapped);
|
|
255
|
+
return () => {
|
|
256
|
+
offTarget(event, wrapped);
|
|
257
|
+
};
|
|
258
|
+
},
|
|
259
|
+
emit: (event, ...args) => {
|
|
260
|
+
const definition = eventDefinition(outbound, event, outboundDirection);
|
|
261
|
+
const { values, acknowledgement } = splitWireArguments(definition, args);
|
|
262
|
+
const parsed = definition.args.safeParse(values);
|
|
263
|
+
if (!parsed.success) {
|
|
264
|
+
throw realtimeContractViolation({
|
|
265
|
+
event,
|
|
266
|
+
direction: outboundDirection,
|
|
267
|
+
phase: "arguments",
|
|
268
|
+
reason: "invalid-arguments",
|
|
269
|
+
fault: "local",
|
|
270
|
+
cause: parsed.error
|
|
271
|
+
}).error;
|
|
272
|
+
}
|
|
273
|
+
if (definition.ack && !acknowledgement) {
|
|
274
|
+
throw realtimeContractViolation({
|
|
275
|
+
event,
|
|
276
|
+
direction: outboundDirection,
|
|
277
|
+
phase: "acknowledgement",
|
|
278
|
+
reason: "missing-acknowledgement",
|
|
279
|
+
fault: "local"
|
|
280
|
+
}).error;
|
|
281
|
+
}
|
|
282
|
+
const wireArgs = [...parsed.data];
|
|
283
|
+
if (definition.ack && acknowledgement) {
|
|
284
|
+
wireArgs.push((value) => {
|
|
285
|
+
const refusal = asRealtimeRejection(value);
|
|
286
|
+
if (refusal) {
|
|
287
|
+
reportRejected(realtimeContractViolation({
|
|
288
|
+
event,
|
|
289
|
+
direction: outboundDirection,
|
|
290
|
+
phase: "arguments",
|
|
291
|
+
reason: "rejected-by-peer",
|
|
292
|
+
fault: "local"
|
|
293
|
+
}), onRejected, logger);
|
|
294
|
+
return;
|
|
295
|
+
}
|
|
296
|
+
const ack = definition.ack?.safeParse(value);
|
|
297
|
+
if (!ack?.success) {
|
|
298
|
+
if (ack) {
|
|
299
|
+
reportRejected(realtimeContractViolation({
|
|
300
|
+
event,
|
|
301
|
+
direction: inboundDirection,
|
|
302
|
+
phase: "acknowledgement",
|
|
303
|
+
reason: "invalid-acknowledgement-value",
|
|
304
|
+
fault: "peer",
|
|
305
|
+
cause: ack.error
|
|
306
|
+
}), onRejected, logger);
|
|
307
|
+
}
|
|
308
|
+
return;
|
|
309
|
+
}
|
|
310
|
+
acknowledgement(ack.data);
|
|
311
|
+
});
|
|
312
|
+
}
|
|
313
|
+
return emitTarget(event, ...wireArgs) !== false;
|
|
314
|
+
}
|
|
315
|
+
};
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
export { isModuleNotFound, REALTIME_REJECTION_KEY, asRealtimeRejection, parseRealtimeRequestArguments, parseRealtimeRequestAcknowledgement, createValidatedRealtimeSocket };
|
|
@@ -1,36 +1,38 @@
|
|
|
1
|
+
import {
|
|
2
|
+
isWithinDir
|
|
3
|
+
} from "./index-sbdmyz75.js";
|
|
1
4
|
import {
|
|
2
5
|
collectToolSurface
|
|
3
|
-
} from "./index-
|
|
6
|
+
} from "./index-2rwwmr7v.js";
|
|
4
7
|
import {
|
|
5
8
|
createToolRunner,
|
|
6
9
|
formatToolError
|
|
7
|
-
} from "./index-
|
|
10
|
+
} from "./index-5mtc969c.js";
|
|
8
11
|
import {
|
|
9
|
-
coerceJsonArgs,
|
|
10
12
|
toolResultFromError
|
|
11
|
-
} from "./index-
|
|
12
|
-
import {
|
|
13
|
-
isWithinDir
|
|
14
|
-
} from "./index-sbdmyz75.js";
|
|
13
|
+
} from "./index-758zx2ha.js";
|
|
15
14
|
import {
|
|
16
15
|
assertUniqueToolName,
|
|
17
16
|
buildToolPresentationSchema,
|
|
18
17
|
objectShapeKeys
|
|
19
|
-
} from "./index-
|
|
18
|
+
} from "./index-mgtxfe6b.js";
|
|
20
19
|
import {
|
|
21
20
|
jsonSchemaFields
|
|
22
21
|
} from "./index-cby4ar3v.js";
|
|
22
|
+
import {
|
|
23
|
+
coerceJsonArgs
|
|
24
|
+
} from "./index-7zbps32p.js";
|
|
23
25
|
import {
|
|
24
26
|
formatZodError,
|
|
25
27
|
validateDeclaredOutput
|
|
26
|
-
} from "./index-
|
|
28
|
+
} from "./index-fxz0v7vg.js";
|
|
27
29
|
import {
|
|
28
30
|
isUnsafeKey,
|
|
29
31
|
safeJsonParse
|
|
30
|
-
} from "./index-
|
|
32
|
+
} from "./index-kzfs85xp.js";
|
|
31
33
|
import {
|
|
32
34
|
isRecord
|
|
33
|
-
} from "./index-
|
|
35
|
+
} from "./index-77fekveh.js";
|
|
34
36
|
|
|
35
37
|
// src/tools/cli-args.ts
|
|
36
38
|
import { z } from "zod";
|