stitchkit 0.77.0 → 0.78.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. package/dist/agent-runtime-coding-tools.js +1 -1
  2. package/dist/agent-runtime-harness.js +6 -6
  3. package/dist/agent-runtime.js +11 -11
  4. package/dist/application/decisions.d.ts +28 -25
  5. package/dist/application/decisions.d.ts.map +1 -1
  6. package/dist/application/kernel.d.ts +2 -0
  7. package/dist/application/kernel.d.ts.map +1 -1
  8. package/dist/application/keyspace.d.ts +11 -1
  9. package/dist/application/keyspace.d.ts.map +1 -1
  10. package/dist/application/schedule.d.ts.map +1 -1
  11. package/dist/application/server-resource.d.ts.map +1 -1
  12. package/dist/application-diagnostic-journal.d.ts +21 -0
  13. package/dist/application-diagnostic-journal.d.ts.map +1 -0
  14. package/dist/application-diagnostic-journal.js +714 -0
  15. package/dist/application-opentelemetry.js +92 -5
  16. package/dist/application-schemas.js +13 -98
  17. package/dist/application.d.ts +1 -2
  18. package/dist/application.d.ts.map +1 -1
  19. package/dist/application.js +1775 -858
  20. package/dist/cli.js +7 -7
  21. package/dist/contract/index.js +9 -7
  22. package/dist/files/boundary.d.ts.map +1 -1
  23. package/dist/files.js +1 -1
  24. package/dist/{index-3z73fh2c.js → index-1ckavx4h.js} +49 -1
  25. package/dist/{index-s2rchahr.js → index-31k1ns1s.js} +4 -4
  26. package/dist/{index-m668wzyc.js → index-4ntp63ps.js} +4 -4
  27. package/dist/{index-1rxswfbv.js → index-56fm73re.js} +1 -1
  28. package/dist/{index-ezmn6ac6.js → index-5r0ak8fr.js} +3 -3
  29. package/dist/{index-f6n5n7nz.js → index-7z69kyrh.js} +10 -87
  30. package/dist/{index-k2zczx1g.js → index-93xp5tgg.js} +1 -1
  31. package/dist/{index-bfcpjw20.js → index-actkayzn.js} +7 -3
  32. package/dist/index-anyqnqcv.js +79 -0
  33. package/dist/{index-7qy2ex0m.js → index-cwp38wxn.js} +1 -1
  34. package/dist/{index-35z5h2ty.js → index-dmfn9m4x.js} +125 -4
  35. package/dist/index-h4pj6fta.js +87 -0
  36. package/dist/{index-jqtsc9mj.js → index-j6mfaw26.js} +2 -2
  37. package/dist/{index-58jzmnn4.js → index-k45qqrdh.js} +513 -39
  38. package/dist/{index-8eywc9zv.js → index-kw12fsbc.js} +0 -1
  39. package/dist/index-n1g2xm6a.js +203 -0
  40. package/dist/{index-t8qyvrvg.js → index-n7apa6sy.js} +12 -12
  41. package/dist/{index-s4c8wy8m.js → index-qaajjfp6.js} +8 -8
  42. package/dist/{index-nemjkxjp.js → index-s5tn4kdv.js} +14 -10
  43. package/dist/index-wfq8zerm.js +92 -0
  44. package/dist/index.js +53 -1215
  45. package/dist/internal/deadline.d.ts +17 -0
  46. package/dist/internal/deadline.d.ts.map +1 -0
  47. package/dist/live.js +12 -89
  48. package/dist/node.js +5 -6
  49. package/dist/observability/context.d.ts.map +1 -1
  50. package/dist/observability/index.js +3 -3
  51. package/dist/primitives.js +2 -1
  52. package/dist/remote.js +3 -6
  53. package/dist/server/event-bus.d.ts.map +1 -1
  54. package/dist/server/index.js +31 -30
  55. package/dist/testing.js +1562 -87
  56. package/dist/tool-invoker.js +6 -6
  57. package/dist/tools.js +66 -23
  58. package/llms-full.txt +110 -13
  59. package/package.json +8 -4
  60. package/dist/index-3cwck0rm.js +0 -897
  61. package/dist/index-7b188kmz.js +0 -49
  62. package/dist/index-a916km3r.js +0 -45
  63. package/dist/index-vc1b0b1b.js +0 -825
  64. package/dist/{index-da1aqnhb.js → index-aewy3x5j.js} +3 -3
  65. package/dist/{index-nt1mp8km.js → index-efm026pw.js} +3 -3
@@ -0,0 +1,203 @@
1
+ // src/application/channel.ts
2
+ import { z } from "zod";
3
+ var PositiveSafeIntegerSchema = z.number().int().positive().safe();
4
+ var BoundedChannelPolicySchema = z.enum(["ordered", "latest"]);
5
+ var BoundedChannelStateSchema = z.enum(["open", "draining", "closed", "failed"]);
6
+ var BoundedChannelSnapshotSchema = z.object({
7
+ state: BoundedChannelStateSchema,
8
+ policy: BoundedChannelPolicySchema,
9
+ queuedItems: z.number().int().nonnegative(),
10
+ queuedBytes: z.number().int().nonnegative(),
11
+ waitingReader: z.boolean(),
12
+ offered: z.number().int().nonnegative(),
13
+ delivered: z.number().int().nonnegative(),
14
+ queued: z.number().int().nonnegative(),
15
+ coalesced: z.number().int().nonnegative(),
16
+ refused: z.number().int().nonnegative(),
17
+ discarded: z.number().int().nonnegative()
18
+ }).strict().readonly();
19
+
20
+ class BoundedChannelReaderError extends Error {
21
+ constructor() {
22
+ super("A bounded channel permits only one pending next() call");
23
+ this.name = "BoundedChannelReaderError";
24
+ }
25
+ }
26
+ function createBoundedChannel(config) {
27
+ const policy = BoundedChannelPolicySchema.parse(config.policy);
28
+ const maxItems = PositiveSafeIntegerSchema.parse(config.maxItems);
29
+ const maxBytes = PositiveSafeIntegerSchema.parse(config.maxBytes);
30
+ const queue = [];
31
+ let state = "open";
32
+ let queuedBytes = 0;
33
+ let waiting;
34
+ let failure;
35
+ let hasFailure = false;
36
+ let offered = 0;
37
+ let delivered = 0;
38
+ let queued = 0;
39
+ let coalesced = 0;
40
+ let refused = 0;
41
+ let discarded = 0;
42
+ const removeAbortListener = () => {
43
+ config.signal?.removeEventListener("abort", abortChannel);
44
+ };
45
+ const snapshot = () => BoundedChannelSnapshotSchema.parse({
46
+ state,
47
+ policy,
48
+ queuedItems: queue.length,
49
+ queuedBytes,
50
+ waitingReader: waiting !== undefined,
51
+ offered,
52
+ delivered,
53
+ queued,
54
+ coalesced,
55
+ refused,
56
+ discarded
57
+ });
58
+ const clearQueue = () => {
59
+ discarded += queue.length;
60
+ queue.length = 0;
61
+ queuedBytes = 0;
62
+ };
63
+ const settleClosed = () => {
64
+ if (state !== "draining" || queue.length > 0)
65
+ return;
66
+ state = "closed";
67
+ removeAbortListener();
68
+ const reader = waiting;
69
+ waiting = undefined;
70
+ reader?.resolve({ done: true, value: undefined });
71
+ };
72
+ const close = (options = {}) => {
73
+ if (state === "closed" || state === "failed")
74
+ return snapshot();
75
+ const mode = options.mode ?? "drain";
76
+ if (mode !== "drain" && mode !== "discard") {
77
+ throw new TypeError("Bounded channel close mode must be drain or discard");
78
+ }
79
+ if (mode === "discard") {
80
+ clearQueue();
81
+ state = "closed";
82
+ removeAbortListener();
83
+ const reader = waiting;
84
+ waiting = undefined;
85
+ reader?.resolve({ done: true, value: undefined });
86
+ return snapshot();
87
+ }
88
+ state = "draining";
89
+ settleClosed();
90
+ return snapshot();
91
+ };
92
+ function abortChannel() {
93
+ close({ mode: "discard" });
94
+ }
95
+ const channel = {
96
+ [Symbol.asyncIterator]() {
97
+ return channel;
98
+ },
99
+ offer(value) {
100
+ offered += 1;
101
+ if (state !== "open") {
102
+ refused += 1;
103
+ return { outcome: "refused", reason: "not-open" };
104
+ }
105
+ const bytes = config.sizeOf(value);
106
+ if (!Number.isSafeInteger(bytes) || bytes < 0) {
107
+ throw new TypeError("Bounded channel sizeOf() must return a non-negative safe integer");
108
+ }
109
+ if (bytes > maxBytes) {
110
+ refused += 1;
111
+ return { outcome: "refused", reason: "item-too-large" };
112
+ }
113
+ const reader = waiting;
114
+ if (reader) {
115
+ waiting = undefined;
116
+ delivered += 1;
117
+ reader.resolve({ done: false, value });
118
+ return { outcome: "delivered" };
119
+ }
120
+ if (policy === "latest" && queue.length > 0) {
121
+ const previous = queue[0];
122
+ if (!previous)
123
+ throw new Error("Bounded latest channel lost its pending value");
124
+ queue[0] = { value, bytes };
125
+ queuedBytes += bytes - previous.bytes;
126
+ coalesced += 1;
127
+ return { outcome: "coalesced", replaced: 1 };
128
+ }
129
+ if (queue.length >= maxItems) {
130
+ refused += 1;
131
+ return { outcome: "refused", reason: "item-capacity" };
132
+ }
133
+ if (queuedBytes + bytes > maxBytes) {
134
+ refused += 1;
135
+ return { outcome: "refused", reason: "byte-capacity" };
136
+ }
137
+ queue.push({ value, bytes });
138
+ queuedBytes += bytes;
139
+ queued += 1;
140
+ return { outcome: "queued" };
141
+ },
142
+ next() {
143
+ if (hasFailure)
144
+ return Promise.reject(failure);
145
+ const next = queue.shift();
146
+ if (next) {
147
+ queuedBytes -= next.bytes;
148
+ delivered += 1;
149
+ settleClosed();
150
+ return Promise.resolve({ done: false, value: next.value });
151
+ }
152
+ if (state === "closed" || state === "draining") {
153
+ settleClosed();
154
+ return Promise.resolve({ done: true, value: undefined });
155
+ }
156
+ if (waiting)
157
+ return Promise.reject(new BoundedChannelReaderError);
158
+ return new Promise((resolve, reject) => {
159
+ waiting = { resolve, reject };
160
+ });
161
+ },
162
+ return() {
163
+ close({ mode: "discard" });
164
+ return Promise.resolve({ done: true, value: undefined });
165
+ },
166
+ throw(error) {
167
+ channel.fail(error);
168
+ return Promise.reject(error);
169
+ },
170
+ close,
171
+ fail(error) {
172
+ if (state === "closed" || state === "failed")
173
+ return snapshot();
174
+ failure = error;
175
+ hasFailure = true;
176
+ state = "failed";
177
+ clearQueue();
178
+ removeAbortListener();
179
+ const reader = waiting;
180
+ waiting = undefined;
181
+ reader?.reject(error);
182
+ return snapshot();
183
+ },
184
+ getSnapshot: snapshot
185
+ };
186
+ if (config.signal?.aborted)
187
+ abortChannel();
188
+ else
189
+ config.signal?.addEventListener("abort", abortChannel, { once: true });
190
+ return channel;
191
+ }
192
+ var CreditWindowSnapshotSchema = z.object({
193
+ state: z.enum(["open", "closed"]),
194
+ capacityBytes: PositiveSafeIntegerSchema,
195
+ availableBytes: z.number().int().nonnegative(),
196
+ leasedBytes: z.number().int().nonnegative(),
197
+ acquired: z.number().int().nonnegative(),
198
+ refused: z.number().int().nonnegative(),
199
+ replenishedBytes: z.number().int().nonnegative(),
200
+ waiting: z.number().int().nonnegative()
201
+ }).strict().readonly();
202
+
203
+ export { createBoundedChannel };
@@ -8,6 +8,12 @@ import {
8
8
  guardSignalCallback,
9
9
  reportSignalError
10
10
  } from "./index-vbf2p6me.js";
11
+ import {
12
+ ShutdownOptionsSchema,
13
+ isStreamCancellation,
14
+ ownHttpStream,
15
+ settleStreamCleanup
16
+ } from "./index-1ckavx4h.js";
11
17
  import {
12
18
  extractIp,
13
19
  getClientInfo,
@@ -18,13 +24,7 @@ import {
18
24
  runWithRequestContext,
19
25
  setRequestEndpoint,
20
26
  setRequestError
21
- } from "./index-nemjkxjp.js";
22
- import {
23
- ShutdownOptionsSchema,
24
- isStreamCancellation,
25
- ownHttpStream,
26
- settleStreamCleanup
27
- } from "./index-3z73fh2c.js";
27
+ } from "./index-s5tn4kdv.js";
28
28
  import {
29
29
  errorCode,
30
30
  normalizeError,
@@ -32,7 +32,7 @@ import {
32
32
  resolveTraceContext,
33
33
  validateDeclaredOutput,
34
34
  zodIssues
35
- } from "./index-nt1mp8km.js";
35
+ } from "./index-efm026pw.js";
36
36
  import {
37
37
  DEFAULT_CONTRACT_STREAM_FRAME_BYTES,
38
38
  isUnsafeKey,
@@ -40,14 +40,14 @@ import {
40
40
  parseTrailingWildcard,
41
41
  safeJsonParse
42
42
  } from "./index-vj3vvpaa.js";
43
- import {
44
- AppError,
45
- badRequest
46
- } from "./index-0w9abg87.js";
47
43
  import {
48
44
  isRecord,
49
45
  transportResult
50
46
  } from "./index-qyrqwr4c.js";
47
+ import {
48
+ AppError,
49
+ badRequest
50
+ } from "./index-0w9abg87.js";
51
51
 
52
52
  // src/server/multipart.ts
53
53
  var DEFAULT_MAX_REQUEST_BYTES = 25 * 1024 * 1024;
@@ -1,27 +1,27 @@
1
- import {
2
- getRequestContext,
3
- runWithRequestContext
4
- } from "./index-nemjkxjp.js";
5
1
  import {
6
2
  objectShapeKeys
7
3
  } from "./index-22by16v6.js";
4
+ import {
5
+ getRequestContext,
6
+ runWithRequestContext
7
+ } from "./index-s5tn4kdv.js";
8
8
  import {
9
9
  formatZodError,
10
10
  normalizeError,
11
11
  validateDeclaredOutput
12
- } from "./index-nt1mp8km.js";
12
+ } from "./index-efm026pw.js";
13
13
  import {
14
14
  isUnsafeKey,
15
15
  safeJsonParse
16
16
  } from "./index-vj3vvpaa.js";
17
+ import {
18
+ isRecord
19
+ } from "./index-qyrqwr4c.js";
17
20
  import {
18
21
  AppError,
19
22
  STITCH_ERROR_STATUS,
20
23
  isStitchErrorCode
21
24
  } from "./index-0w9abg87.js";
22
- import {
23
- isRecord
24
- } from "./index-qyrqwr4c.js";
25
25
 
26
26
  // src/tools/coerce.ts
27
27
  import { z } from "zod";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  resolveTraceContext
3
- } from "./index-nt1mp8km.js";
3
+ } from "./index-efm026pw.js";
4
4
  import {
5
5
  isUnsafeKey
6
6
  } from "./index-vj3vvpaa.js";
@@ -179,38 +179,42 @@ function isPublicIp(value) {
179
179
 
180
180
  // src/observability/context.ts
181
181
  import { AsyncLocalStorage } from "node:async_hooks";
182
- var storage = new AsyncLocalStorage;
182
+ var storage;
183
+ var requestStorage = () => {
184
+ storage ??= new AsyncLocalStorage;
185
+ return storage;
186
+ };
183
187
  function runWithRequestContext(ctx, fn) {
184
- return storage.run(ctx, fn);
188
+ return requestStorage().run(ctx, fn);
185
189
  }
186
190
  function getRequestContext() {
187
- return storage.getStore();
191
+ return requestStorage().getStore();
188
192
  }
189
193
  function getTraceId() {
190
- return storage.getStore()?.trace.traceId;
194
+ return requestStorage().getStore()?.trace.traceId;
191
195
  }
192
196
  function getUserId() {
193
- return storage.getStore()?.userId;
197
+ return requestStorage().getStore()?.userId;
194
198
  }
195
199
  function setRequestUser(userId) {
196
- const ctx = storage.getStore();
200
+ const ctx = requestStorage().getStore();
197
201
  if (ctx)
198
202
  ctx.userId = userId;
199
203
  }
200
204
  function setRequestEndpoint(serviceName, action) {
201
- const ctx = storage.getStore();
205
+ const ctx = requestStorage().getStore();
202
206
  if (ctx) {
203
207
  ctx.serviceName = serviceName;
204
208
  ctx.action = action;
205
209
  }
206
210
  }
207
211
  function setRequestDimensions(dimensions) {
208
- const ctx = storage.getStore();
212
+ const ctx = requestStorage().getStore();
209
213
  if (ctx)
210
214
  ctx.dimensions = { ...ctx.dimensions, ...dimensions };
211
215
  }
212
216
  function setRequestError(error) {
213
- const ctx = storage.getStore();
217
+ const ctx = requestStorage().getStore();
214
218
  if (ctx)
215
219
  ctx.error = error;
216
220
  }
@@ -0,0 +1,92 @@
1
+ import {
2
+ LiveStatePhaseSchema,
3
+ LiveStateStopReasonSchema
4
+ } from "./index-dmfn9m4x.js";
5
+
6
+ // src/live/watch-contract.ts
7
+ import { z } from "zod";
8
+ var WatchKeySchema = z.object({
9
+ service: z.string().min(1),
10
+ action: z.string().min(1),
11
+ digest: z.string().min(1)
12
+ }).strict().readonly();
13
+ var WatchOpenSchema = z.object({ key: WatchKeySchema, args: z.unknown() }).readonly();
14
+ var WatchAcceptedSchema = z.object({
15
+ accepted: z.boolean(),
16
+ reason: z.string().optional()
17
+ }).strict().readonly();
18
+ var WatchValueSchema = z.object({
19
+ key: WatchKeySchema,
20
+ revision: z.number().int().nonnegative(),
21
+ value: z.unknown()
22
+ }).readonly();
23
+ var WatchStateSchema = z.object({
24
+ key: WatchKeySchema,
25
+ phase: LiveStatePhaseSchema,
26
+ reason: LiveStateStopReasonSchema.optional(),
27
+ code: z.string().optional(),
28
+ message: z.string().optional()
29
+ }).readonly();
30
+ var WATCH_OPEN = "stitchkit.watch.open";
31
+ var WATCH_CLOSE = "stitchkit.watch.close";
32
+ var WATCH_VALUE = "stitchkit.watch.value";
33
+ var WATCH_STATE = "stitchkit.watch.state";
34
+ var watchContract = {
35
+ serverToClient: {
36
+ [WATCH_VALUE]: { args: z.tuple([WatchValueSchema]) },
37
+ [WATCH_STATE]: { args: z.tuple([WatchStateSchema]) }
38
+ },
39
+ clientToServer: {
40
+ [WATCH_OPEN]: { args: z.tuple([WatchOpenSchema]), ack: WatchAcceptedSchema },
41
+ [WATCH_CLOSE]: { args: z.tuple([z.object({ key: WatchKeySchema }).readonly()]) }
42
+ }
43
+ };
44
+ function watchKeyString(key) {
45
+ return `${key.service}/${key.action}/${key.digest}`;
46
+ }
47
+
48
+ // src/internal/stable-digest.ts
49
+ function stableValue(value) {
50
+ if (Array.isArray(value))
51
+ return value.map(stableValue);
52
+ if (value === null || typeof value !== "object")
53
+ return value;
54
+ const result = {};
55
+ for (const key of Object.keys(value).sort()) {
56
+ result[key] = stableValue(Reflect.get(value, key));
57
+ }
58
+ return result;
59
+ }
60
+ function mix128(input) {
61
+ let a = 2654435769;
62
+ let b = 2246822507;
63
+ let c = 3266489909;
64
+ let d = 668265263;
65
+ for (let index = 0;index < input.length; index += 1) {
66
+ const code = input.charCodeAt(index);
67
+ a = Math.imul(a ^ code, 2246822519);
68
+ b = Math.imul(b ^ code, 3266489917);
69
+ c = Math.imul(c ^ code, 668265263);
70
+ d = Math.imul(d ^ code, 374761393);
71
+ a = a << 13 | a >>> 19;
72
+ b = b << 17 | b >>> 15;
73
+ c = c << 7 | c >>> 25;
74
+ d = d << 11 | d >>> 21;
75
+ }
76
+ a ^= b >>> 15;
77
+ b ^= c >>> 13;
78
+ c ^= d >>> 11;
79
+ d ^= a >>> 9;
80
+ return [
81
+ Math.imul(a ^ a >>> 16, 575075507) >>> 0,
82
+ Math.imul(b ^ b >>> 13, 2654435761) >>> 0,
83
+ Math.imul(c ^ c >>> 16, 2246822507) >>> 0,
84
+ Math.imul(d ^ d >>> 15, 3266489909) >>> 0
85
+ ];
86
+ }
87
+ function argumentsDigest(args) {
88
+ const lanes = mix128(JSON.stringify(stableValue(args)) ?? "undefined");
89
+ return lanes.map((lane) => lane.toString(16).padStart(8, "0")).join("");
90
+ }
91
+
92
+ export { stableValue, argumentsDigest, WatchKeySchema, WatchValueSchema, WatchStateSchema, WATCH_OPEN, WATCH_CLOSE, WATCH_VALUE, WATCH_STATE, watchContract, watchKeyString };