stitchkit 0.78.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.
Files changed (84) hide show
  1. package/dist/agent-runtime-browser.js +53 -581
  2. package/dist/agent-runtime-coding-tools.js +6 -5
  3. package/dist/agent-runtime-harness.js +21 -94
  4. package/dist/agent-runtime-openrouter.js +1 -1
  5. package/dist/agent-runtime.js +68 -64
  6. package/dist/application/kernel.d.ts.map +1 -1
  7. package/dist/application/schemas.d.ts +2 -0
  8. package/dist/application/schemas.d.ts.map +1 -1
  9. package/dist/application/watch-hub.d.ts.map +1 -1
  10. package/dist/application-diagnostic-journal.js +14 -96
  11. package/dist/application-opentelemetry.js +6 -92
  12. package/dist/application-schemas.js +2 -1
  13. package/dist/application.js +158 -1802
  14. package/dist/cli.js +13 -11
  15. package/dist/contract/index.js +7 -4
  16. package/dist/index-2qzskm8h.js +63 -0
  17. package/dist/{index-93xp5tgg.js → index-2rwwmr7v.js} +3 -3
  18. package/dist/{index-kw12fsbc.js → index-3gye9wzb.js} +7 -3
  19. package/dist/{index-1ckavx4h.js → index-3z73fh2c.js} +1 -49
  20. package/dist/index-4fpa9dy2.js +51 -0
  21. package/dist/{index-cwp38wxn.js → index-5mtc969c.js} +2 -2
  22. package/dist/index-5s3zajp8.js +192 -0
  23. package/dist/index-6s7n2v50.js +583 -0
  24. package/dist/{index-qaajjfp6.js → index-758zx2ha.js} +15 -94
  25. package/dist/{index-qyrqwr4c.js → index-77fekveh.js} +4 -1
  26. package/dist/{index-k45qqrdh.js → index-7ag81v2f.js} +13 -166
  27. package/dist/{index-n1g2xm6a.js → index-7gnkny4z.js} +124 -1
  28. package/dist/index-7zbps32p.js +89 -0
  29. package/dist/index-85vfqd7m.js +135 -0
  30. package/dist/{index-4ntp63ps.js → index-9s6z8vgf.js} +18 -142
  31. package/dist/index-a916km3r.js +45 -0
  32. package/dist/index-b9aefrqd.js +20 -0
  33. package/dist/index-dre2ywck.js +48 -0
  34. package/dist/{index-s5tn4kdv.js → index-dwf1f2ap.js} +3 -3
  35. package/dist/{index-wwst0td5.js → index-dx9xehwt.js} +1 -1
  36. package/dist/{index-5r0ak8fr.js → index-dxesg10d.js} +4 -4
  37. package/dist/{index-aczggrty.js → index-dxjjv399.js} +2 -2
  38. package/dist/{index-j6mfaw26.js → index-egaabxkz.js} +3 -3
  39. package/dist/index-evcnmsc3.js +866 -0
  40. package/dist/{index-efm026pw.js → index-fxz0v7vg.js} +86 -86
  41. package/dist/{index-56fm73re.js → index-hb5pf3s4.js} +1 -1
  42. package/dist/{index-n7apa6sy.js → index-k9ay6v6d.js} +24 -275
  43. package/dist/index-kzfs85xp.js +9 -0
  44. package/dist/{index-vbf2p6me.js → index-m9kzax52.js} +91 -89
  45. package/dist/{index-22by16v6.js → index-mgtxfe6b.js} +1 -1
  46. package/dist/index-p7hgdyhb.js +22 -0
  47. package/dist/index-pq95qkbf.js +0 -0
  48. package/dist/index-t0z5p5w6.js +318 -0
  49. package/dist/{index-31k1ns1s.js → index-vwp69871.js} +13 -11
  50. package/dist/index-wc4x00bn.js +103 -0
  51. package/dist/{index-aewy3x5j.js → index-xcetq6j3.js} +10 -8
  52. package/dist/{index-7z69kyrh.js → index-y01f4223.js} +24 -40
  53. package/dist/{index-dmfn9m4x.js → index-ywd0y6m1.js} +20 -341
  54. package/dist/index.js +46 -407
  55. package/dist/live.js +6 -3
  56. package/dist/node.js +17 -14
  57. package/dist/observability/index.js +8 -7
  58. package/dist/primitives.js +4 -2
  59. package/dist/react.js +1 -1
  60. package/dist/remote.js +7 -3
  61. package/dist/server/index.js +32 -45
  62. package/dist/telegram.js +1 -1
  63. package/dist/testing.js +90 -1576
  64. package/dist/tool-invoker.js +11 -9
  65. package/dist/tools/async-operation-contract.d.ts +61 -0
  66. package/dist/tools/async-operation-contract.d.ts.map +1 -0
  67. package/dist/tools/async-operation.d.ts +2 -47
  68. package/dist/tools/async-operation.d.ts.map +1 -1
  69. package/dist/tools/view-file-contract.d.ts +98 -0
  70. package/dist/tools/view-file-contract.d.ts.map +1 -0
  71. package/dist/tools/view-file.d.ts +4 -83
  72. package/dist/tools/view-file.d.ts.map +1 -1
  73. package/dist/tools-contract.d.ts +29 -0
  74. package/dist/tools-contract.d.ts.map +1 -0
  75. package/dist/tools-contract.js +24 -0
  76. package/dist/tools.d.ts +3 -3
  77. package/dist/tools.d.ts.map +1 -1
  78. package/dist/tools.js +61 -140
  79. package/llms-full.txt +38 -3
  80. package/package.json +9 -6
  81. package/dist/index-anyqnqcv.js +0 -79
  82. package/dist/index-ksp6e2ye.js +0 -24
  83. package/dist/index-vj3vvpaa.js +0 -307
  84. package/dist/index-wfq8zerm.js +0 -92
package/dist/tools.js CHANGED
@@ -1,12 +1,10 @@
1
1
  import {
2
- buildToolManifest,
3
- mountAgent
4
- } from "./index-5r0ak8fr.js";
5
- import"./index-3xnq72rz.js";
2
+ ManagedFileError
3
+ } from "./index-actkayzn.js";
6
4
  import {
7
5
  signJwt,
8
6
  verifyPkce
9
- } from "./index-aewy3x5j.js";
7
+ } from "./index-xcetq6j3.js";
10
8
  import {
11
9
  DEFAULT_CORS_ALLOW_HEADERS,
12
10
  DEFAULT_PROCESS_SIGNALS,
@@ -14,10 +12,30 @@ import {
14
12
  defaultSignalSource,
15
13
  guardSignalCallback,
16
14
  reportSignalError
17
- } from "./index-vbf2p6me.js";
15
+ } from "./index-m9kzax52.js";
16
+ import {
17
+ redact
18
+ } from "./index-dxjjv399.js";
19
+ import {
20
+ buildToolManifest,
21
+ mountAgent
22
+ } from "./index-dxesg10d.js";
23
+ import"./index-3xnq72rz.js";
24
+ import {
25
+ argumentsDigest
26
+ } from "./index-a916km3r.js";
27
+ import {
28
+ AsyncOperationCancelResultSchema,
29
+ McpAnnotationsSchema,
30
+ McpMediaContentSchema,
31
+ ViewFileErrorSchema,
32
+ ViewFileInputSchema,
33
+ ViewFileOutputSchema,
34
+ createAsyncOperationSnapshotSchema
35
+ } from "./index-4fpa9dy2.js";
18
36
  import {
19
37
  createToolInvoker
20
- } from "./index-j6mfaw26.js";
38
+ } from "./index-egaabxkz.js";
21
39
  import {
22
40
  WaitTimeoutError,
23
41
  createCli,
@@ -26,30 +44,31 @@ import {
26
44
  fetchPinnedDocument,
27
45
  readCapped,
28
46
  runWaitOperation
29
- } from "./index-31k1ns1s.js";
47
+ } from "./index-vwp69871.js";
48
+ import"./index-sbdmyz75.js";
30
49
  import {
31
50
  collectToolSurface
32
- } from "./index-93xp5tgg.js";
51
+ } from "./index-2rwwmr7v.js";
33
52
  import {
34
53
  createRuntimeToolFactory,
35
54
  defineRuntimeTool
36
- } from "./index-wwst0td5.js";
55
+ } from "./index-dx9xehwt.js";
37
56
  import {
38
57
  collectTools,
39
58
  createToolRunner,
40
59
  formatToolError
41
- } from "./index-cwp38wxn.js";
60
+ } from "./index-5mtc969c.js";
42
61
  import {
43
62
  ToolExecutionControlError,
44
- coerceJsonArgs,
45
63
  executeToolMethod,
46
64
  isToolExecutionControlError,
47
65
  toolResultFromError
48
- } from "./index-qaajjfp6.js";
66
+ } from "./index-758zx2ha.js";
49
67
  import {
50
- ManagedFileError
51
- } from "./index-actkayzn.js";
52
- import"./index-sbdmyz75.js";
68
+ getRequestContext,
69
+ getTraceId,
70
+ runWithRequestContext
71
+ } from "./index-dwf1f2ap.js";
53
72
  import {
54
73
  PORTABLE_JSON_SCHEMA_FORMATS,
55
74
  assertToolName,
@@ -60,37 +79,32 @@ import {
60
79
  prepareProjectedMcpTools,
61
80
  presentationMetadata,
62
81
  validateMcpRoundPolicy
63
- } from "./index-22by16v6.js";
82
+ } from "./index-mgtxfe6b.js";
64
83
  import"./index-cby4ar3v.js";
65
84
  import {
66
- redact
67
- } from "./index-aczggrty.js";
68
- import {
69
- getRequestContext,
70
- getTraceId,
71
- runWithRequestContext
72
- } from "./index-s5tn4kdv.js";
85
+ coerceJsonArgs
86
+ } from "./index-7zbps32p.js";
73
87
  import {
74
88
  normalizeError,
75
89
  resolvePropagationContext
76
- } from "./index-efm026pw.js";
90
+ } from "./index-fxz0v7vg.js";
77
91
  import {
78
92
  defineContract
79
- } from "./index-vj3vvpaa.js";
93
+ } from "./index-y01f4223.js";
80
94
  import {
81
- isRecord
82
- } from "./index-qyrqwr4c.js";
95
+ ManagedFilePathSchema,
96
+ ManagedFileRefSchema
97
+ } from "./index-6k1937bx.js";
83
98
  import {
84
99
  AppError,
85
100
  STITCH_ERROR_STATUS
86
101
  } from "./index-0w9abg87.js";
102
+ import"./index-kzfs85xp.js";
87
103
  import {
88
- ManagedFilePathSchema,
89
- ManagedFileRefSchema
90
- } from "./index-6k1937bx.js";
104
+ isRecord
105
+ } from "./index-77fekveh.js";
91
106
  // src/tools/async-operation.ts
92
107
  import { z } from "zod";
93
-
94
108
  // src/tools/native-definition.ts
95
109
  function managedNativeIdentity(identity, method) {
96
110
  return { ...identity, method };
@@ -151,21 +165,6 @@ function defineWaitTool(config) {
151
165
  }
152
166
 
153
167
  // src/tools/async-operation.ts
154
- var AsyncOperationCancelResultSchema = z.discriminatedUnion("outcome", [
155
- z.object({ outcome: z.literal("accepted") }),
156
- z.object({ outcome: z.literal("already_terminal") }),
157
- z.object({ outcome: z.literal("rejected"), reason: z.string().min(1) })
158
- ]);
159
- function createAsyncOperationSnapshotSchema(config) {
160
- const progress = config.progress ? { progress: config.progress.optional() } : {};
161
- return z.discriminatedUnion("phase", [
162
- z.object({ phase: z.literal("pending"), ...progress }),
163
- z.object({ phase: z.literal("running"), ...progress }),
164
- z.object({ phase: z.literal("succeeded"), ...progress }),
165
- z.object({ phase: z.literal("failed"), failure: config.failure, ...progress }),
166
- z.object({ phase: z.literal("cancelled"), ...progress })
167
- ]);
168
- }
169
168
  function terminal(snapshot) {
170
169
  if (typeof snapshot !== "object" || snapshot === null || !("phase" in snapshot)) {
171
170
  return false;
@@ -659,9 +658,7 @@ function defineUploadTool(config) {
659
658
  }
660
659
  // src/tools/view-file.ts
661
660
  import { extname as extname2 } from "node:path";
662
- import { z as z3 } from "zod";
663
661
  var MAX_INLINE_BYTES = 20 * 1024 * 1024;
664
- var MAX_VIEW_FILES = 20;
665
662
  var EXT_MIME = {
666
663
  ".png": "image/png",
667
664
  ".jpg": "image/jpeg",
@@ -676,33 +673,6 @@ var EXT_MIME = {
676
673
  ".webm": "video/webm",
677
674
  ".mov": "video/quicktime"
678
675
  };
679
- var McpAnnotationsSchema = z3.object({
680
- audience: z3.array(z3.enum(["user", "assistant"])).optional(),
681
- priority: z3.number().optional()
682
- });
683
- var McpMediaContentSchema = z3.discriminatedUnion("type", [
684
- z3.object({ type: z3.literal("text"), text: z3.string() }),
685
- z3.object({
686
- type: z3.literal("image"),
687
- data: z3.string(),
688
- mimeType: z3.string(),
689
- annotations: McpAnnotationsSchema.optional()
690
- }),
691
- z3.object({
692
- type: z3.literal("audio"),
693
- data: z3.string(),
694
- mimeType: z3.string(),
695
- annotations: McpAnnotationsSchema.optional()
696
- })
697
- ]);
698
- var ViewFileErrorSchema = z3.object({
699
- path: z3.string(),
700
- message: z3.string()
701
- });
702
- var ViewFileOutputSchema = z3.object({
703
- content: z3.array(McpMediaContentSchema),
704
- errors: z3.array(ViewFileErrorSchema)
705
- });
706
676
  async function fetchSource(pathOrUrl, options, maxBytes) {
707
677
  const extMime = EXT_MIME[extname2(pathOrUrl).toLowerCase()];
708
678
  if (pathOrUrl.startsWith("http://") || pathOrUrl.startsWith("https://")) {
@@ -821,9 +791,6 @@ async function resolveMediaWithinBudget(pathOrUrl, options, maxBytes) {
821
791
  async function resolveMedia(pathOrUrl, options = {}) {
822
792
  return (await resolveMediaWithinBudget(pathOrUrl, options, MAX_INLINE_BYTES)).content;
823
793
  }
824
- var ViewFileInputSchema = z3.object({
825
- paths: z3.union([z3.string(), z3.array(z3.string()).max(MAX_VIEW_FILES)]).describe("Media URL(s) or file path(s) to view")
826
- });
827
794
  async function runViewFileOperation(paths, options = {}, signal) {
828
795
  const list = Array.isArray(paths) ? paths : [paths];
829
796
  const content = [];
@@ -947,7 +914,7 @@ import {
947
914
  createRequestStateCodec,
948
915
  McpServer
949
916
  } from "@modelcontextprotocol/server";
950
- import { z as z5 } from "zod";
917
+ import { z as z4 } from "zod";
951
918
 
952
919
  // src/tools/mcp-app.ts
953
920
  import { readFileSync } from "node:fs";
@@ -1067,52 +1034,6 @@ import {
1067
1034
  inputResponse,
1068
1035
  PROTOCOL_VERSION_META_KEY
1069
1036
  } from "@modelcontextprotocol/server";
1070
-
1071
- // src/internal/stable-digest.ts
1072
- function stableValue(value) {
1073
- if (Array.isArray(value))
1074
- return value.map(stableValue);
1075
- if (value === null || typeof value !== "object")
1076
- return value;
1077
- const result = {};
1078
- for (const key of Object.keys(value).sort()) {
1079
- result[key] = stableValue(Reflect.get(value, key));
1080
- }
1081
- return result;
1082
- }
1083
- function mix128(input) {
1084
- let a = 2654435769;
1085
- let b = 2246822507;
1086
- let c = 3266489909;
1087
- let d = 668265263;
1088
- for (let index = 0;index < input.length; index += 1) {
1089
- const code = input.charCodeAt(index);
1090
- a = Math.imul(a ^ code, 2246822519);
1091
- b = Math.imul(b ^ code, 3266489917);
1092
- c = Math.imul(c ^ code, 668265263);
1093
- d = Math.imul(d ^ code, 374761393);
1094
- a = a << 13 | a >>> 19;
1095
- b = b << 17 | b >>> 15;
1096
- c = c << 7 | c >>> 25;
1097
- d = d << 11 | d >>> 21;
1098
- }
1099
- a ^= b >>> 15;
1100
- b ^= c >>> 13;
1101
- c ^= d >>> 11;
1102
- d ^= a >>> 9;
1103
- return [
1104
- Math.imul(a ^ a >>> 16, 575075507) >>> 0,
1105
- Math.imul(b ^ b >>> 13, 2654435761) >>> 0,
1106
- Math.imul(c ^ c >>> 16, 2246822507) >>> 0,
1107
- Math.imul(d ^ d >>> 15, 3266489909) >>> 0
1108
- ];
1109
- }
1110
- function argumentsDigest(args) {
1111
- const lanes = mix128(JSON.stringify(stableValue(args)) ?? "undefined");
1112
- return lanes.map((lane) => lane.toString(16).padStart(8, "0")).join("");
1113
- }
1114
-
1115
- // src/tools/mcp-round.ts
1116
1037
  function transportContext(context, toolName, outcome, round) {
1117
1038
  const protocolVersionValue = isRecord(context.mcpReq.envelope) ? Reflect.get(context.mcpReq.envelope, PROTOCOL_VERSION_META_KEY) : undefined;
1118
1039
  const protocolVersion = typeof protocolVersionValue === "string" ? protocolVersionValue : undefined;
@@ -1335,13 +1256,13 @@ function runInMcpRequestContext(context, toolName, body) {
1335
1256
  import {
1336
1257
  isCallToolResult
1337
1258
  } from "@modelcontextprotocol/server";
1338
- import { z as z4 } from "zod";
1259
+ import { z as z3 } from "zod";
1339
1260
  function mountPreparedRuntimeMcp(server, tools, config) {
1340
1261
  for (const { definition, descriptor } of tools) {
1341
1262
  const { mountable } = descriptor;
1342
1263
  const toolConfig = {
1343
1264
  description: definition.description,
1344
- inputSchema: z4.looseObject({}).meta(presentationMetadata(descriptor.inputSchema))
1265
+ inputSchema: z3.looseObject({}).meta(presentationMetadata(descriptor.inputSchema))
1345
1266
  };
1346
1267
  if (descriptor.outputSchema)
1347
1268
  toolConfig.outputSchema = descriptor.outputSchema;
@@ -1430,7 +1351,7 @@ function mountPreparedMcp(mcpServer, prepared, config = {}) {
1430
1351
  const { mountable } = descriptor;
1431
1352
  const toolConfig = {
1432
1353
  description: mountable.method.desc,
1433
- inputSchema: z5.looseObject({}).meta(presentationMetadata(descriptor.inputSchema))
1354
+ inputSchema: z4.looseObject({}).meta(presentationMetadata(descriptor.inputSchema))
1434
1355
  };
1435
1356
  if (descriptor.outputSchema)
1436
1357
  toolConfig.outputSchema = descriptor.outputSchema;
@@ -1865,7 +1786,7 @@ function bindStdioProcessSignals(handle, options = {}) {
1865
1786
  return { promise, close };
1866
1787
  }
1867
1788
  // src/tools/mount-download.ts
1868
- import { z as z6 } from "zod";
1789
+ import { z as z5 } from "zod";
1869
1790
 
1870
1791
  // src/tools/native-result.ts
1871
1792
  function textResult(text, isError = false) {
@@ -1877,7 +1798,7 @@ function textResult(text, isError = false) {
1877
1798
  function mountDownload(server, config) {
1878
1799
  const name = config.name ?? "download";
1879
1800
  assertToolName(name, "<native>", "download");
1880
- server.registerTool(name, { description: config.description, inputSchema: z6.object(config.inputSchema) }, async (rawArgs) => {
1801
+ server.registerTool(name, { description: config.description, inputSchema: z5.object(config.inputSchema) }, async (rawArgs) => {
1881
1802
  const args = isRecord(rawArgs) ? rawArgs : {};
1882
1803
  try {
1883
1804
  const url = await config.resolveUrl(args);
@@ -1925,11 +1846,11 @@ function mountUpload(server, config) {
1925
1846
  });
1926
1847
  }
1927
1848
  // src/tools/mount-wait.ts
1928
- import { z as z7 } from "zod";
1849
+ import { z as z6 } from "zod";
1929
1850
  function mountWait(server, config) {
1930
1851
  const name = config.name ?? "wait";
1931
1852
  assertToolName(name, "<native>", "wait");
1932
- server.registerTool(name, { description: config.description, inputSchema: z7.object(config.inputSchema) }, async (rawArgs) => {
1853
+ server.registerTool(name, { description: config.description, inputSchema: z6.object(config.inputSchema) }, async (rawArgs) => {
1933
1854
  const args = isRecord(rawArgs) ? rawArgs : {};
1934
1855
  try {
1935
1856
  const { state, timedOut } = await runWaitOperation({
@@ -1948,19 +1869,19 @@ function mountWait(server, config) {
1948
1869
  }
1949
1870
  // src/tools/oauth-provider.ts
1950
1871
  import { randomUUID } from "node:crypto";
1951
- import { z as z8 } from "zod";
1872
+ import { z as z7 } from "zod";
1952
1873
  function isPlainDisplayCharacter(character) {
1953
1874
  const codePoint = character.codePointAt(0);
1954
1875
  return codePoint !== undefined && codePoint >= 32 && codePoint !== 127 && character !== "<" && character !== ">";
1955
1876
  }
1956
- var CimdClientMetadataSchema = z8.object({
1957
- client_id: z8.url(),
1958
- redirect_uris: z8.array(z8.url()).min(1),
1959
- client_name: z8.string().trim().min(1).max(200).refine((value) => Array.from(value).every(isPlainDisplayCharacter), {
1877
+ var CimdClientMetadataSchema = z7.object({
1878
+ client_id: z7.url(),
1879
+ redirect_uris: z7.array(z7.url()).min(1),
1880
+ client_name: z7.string().trim().min(1).max(200).refine((value) => Array.from(value).every(isPlainDisplayCharacter), {
1960
1881
  message: "client_name must be plain display text"
1961
1882
  }),
1962
- token_endpoint_auth_method: z8.literal("none"),
1963
- application_type: z8.enum(["native", "web"]).optional()
1883
+ token_endpoint_auth_method: z7.literal("none"),
1884
+ application_type: z7.enum(["native", "web"]).optional()
1964
1885
  });
1965
1886
  function createSecureClientMetadataFetcher(policy = {}) {
1966
1887
  assertPositiveInteger("cimd.maxBytes", policy.maxBytes ?? DEFAULT_CIMD_MAX_BYTES);
package/llms-full.txt CHANGED
@@ -53,6 +53,7 @@ own, recorded as an ADR.
53
53
  | `stitchkit/server` | server (Bun) | stable | `createServer`, `implement`, hooks, auth, Socket.IO server, server primitives |
54
54
  | `stitchkit/node` | server (Node ≥ 22) | stable | `serveNode` + the runtime-agnostic core — the Node mirror of `/server` |
55
55
  | `stitchkit/tools` | server | stable | `createMcpHandler`, `mountMcp`, `mountAgent`, the OAuth provider, native tools |
56
+ | `stitchkit/tools/contract` | browser + server | evolving | the shapes a tool surface speaks — async-operation contract, snapshot and cancel schemas, view-file input/output — without the runtime that serves them |
56
57
  | `stitchkit/tools/invoker` | server | stable | peer-free `createToolInvoker` over the canonical contract tool runner |
57
58
  | `stitchkit/cli` | server | stable | `createCli` — the CLI transport, light (no MCP SDK / `ai`) |
58
59
  | `stitchkit/remote` | browser **and** server | stable | peer-free `implementRemote` for thin HTTP proxy processes |
@@ -60,9 +61,9 @@ own, recorded as an ADR.
60
61
  | `stitchkit/telegram` | server (Bun or Node) | evolving | peer-free Telegram platform primitives — Mini App `initData` verification and Bot API send-failure classification |
61
62
  | `stitchkit/observability` | server | stable | request/tool event projections — `createObservability`, trace context, sanitisation |
62
63
  | `stitchkit/testing` | tests on Bun or Node | stable | in-process generated clients over a real Fetch handler, plus the store and managed-resource conformance kits |
63
- | `stitchkit/declaration` | build and deployment tooling (Bun or Node) | evolving | `ProjectDeclarationSchema` — the one machine-readable statement a repository makes about itself |
64
+ | `stitchkit/declaration` | browser + build and deployment tooling (Bun or Node) | evolving | `ProjectDeclarationSchema` — the one machine-readable statement a repository makes about itself |
64
65
  | `stitchkit/react` | browser | stable | `createCursorQuery`, `createCacheBridge` |
65
- | `stitchkit/agent-runtime` | server | evolving<br>_redefined in 11 of the 23 minors since 0.56.2, most recently 0.75.0_ | optional durable conversation/run loop, history, models, prompts, fencing and events |
66
+ | `stitchkit/agent-runtime` | server | evolving<br>_redefined in 11 of the 24 minors since 0.56.2, most recently 0.75.0_ | optional durable conversation/run loop, history, models, prompts, fencing and events |
66
67
  | `stitchkit/agent-runtime/harness` | server | evolving | resource-aware process-local facade over the canonical Agent runtime; supervision stays outside |
67
68
  | `stitchkit/agent-runtime/coding-tools` | server (Bun or Node) | evolving | bounded host-authorized direct file and shell tools; a root boundary, not an OS sandbox |
68
69
  | `stitchkit/agent-runtime/openrouter` | server | evolving | isolated OpenRouter language-model adapter |
@@ -70,7 +71,7 @@ own, recorded as an ADR.
70
71
  | `stitchkit/agent-runtime/sqlite/bun` | server (Bun) | evolving | durable built-in SQLite store for the agent runtime |
71
72
  | `stitchkit/agent-runtime/sqlite/node` | server (Node ≥ 22.5) | evolving | durable built-in SQLite store for the agent runtime |
72
73
  | `stitchkit-tui` | terminal (Bun) | evolving | optional official OpenTUI host over a caller-composed headless runtime |
73
- | `stitchkit/application` | browser + server | evolving<br>_redefined in 5 of the 23 minors since 0.56.2, most recently 0.78.0_ | managed resource graph, readiness, admission, schedules, subtree restart and bounded shutdown |
74
+ | `stitchkit/application` | browser + server | evolving<br>_redefined in 6 of the 24 minors since 0.56.2, most recently 0.79.0_ | managed resource graph, readiness, admission, schedules, subtree restart and bounded shutdown |
74
75
  | `stitchkit/application/grammy` | server | evolving | isolated grammY polling and webhook lifecycle adapters |
75
76
  | `stitchkit/application/opentelemetry` | server | evolving | maps application snapshots onto an injected OpenTelemetry `Meter` |
76
77
  | `stitchkit/application/schemas` | browser + server | evolving | the application's snapshot, health and shutdown schemas alone, without the kernel |
@@ -10136,6 +10137,40 @@ makes one thing your job rather than the resolver's:
10136
10137
  The mechanical part is identical either way. Only the *noticing* differs, and an
10137
10138
  exact pin moves it onto you.
10138
10139
 
10140
+ ## Released migration: 0.79.0
10141
+
10142
+ One thing, and only if you assert on the whole snapshot.
10143
+
10144
+ ```bash
10145
+ rg -n "getSnapshot\(\)|projectApplicationStatus|status\(\)" --glob '*.test.ts' --glob '*.spec.ts'
10146
+ ```
10147
+
10148
+ `ApplicationSnapshot` and `ApplicationStatusProjection` each gained a
10149
+ `restarting` field — ids in the snapshot, a count in the projection. A reader
10150
+ that names the fields it wants is unaffected. A test that compares the whole
10151
+ object with `toEqual` fails until it adds the field:
10152
+
10153
+ ```ts
10154
+ // before
10155
+ expect(body).toEqual({ id, lifecycle: 'ready', /* … */ resources: { total: 1, ready: 1, degraded: 0, failed: 0 } })
10156
+ // after
10157
+ expect(body).toEqual({ id, lifecycle: 'ready', /* … */ resources: { total: 1, ready: 1, degraded: 0, failed: 0 }, restarting: 0 })
10158
+ ```
10159
+
10160
+ It is zero except while a restart is running, and then it names the subtree being
10161
+ replaced. That is the point: a snapshot taken mid-restart used to be
10162
+ indistinguishable from a resource that had failed on its own, so a dashboard read
10163
+ a planned replacement as an outage.
10164
+
10165
+ **If you watch a hub across a restart**, nothing to change, but the behaviour is
10166
+ different and better: closing a hub now tells its subscribers `unavailable` /
10167
+ `source-unavailable` instead of dropping them, so a page stops showing a value
10168
+ that will never update again.
10169
+
10170
+ **If you need a tool contract in a browser**, `stitchkit/tools/contract` now
10171
+ carries the async-operation helpers, its schemas and the view-file input/output
10172
+ without the runtime. `stitchkit/tools` still exports all of them.
10173
+
10139
10174
  ## Released migration: 0.78.0
10140
10175
 
10141
10176
  Two mechanical edits. Find them both:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "stitchkit",
3
- "version": "0.78.0",
3
+ "version": "0.79.0",
4
4
  "description": "Contract-first backend framework — one defineContract() into an HTTP API, MCP tools, AI-agent tools and a typed client. Bun and Node.",
5
5
  "keywords": [
6
6
  "bun",
@@ -61,6 +61,10 @@
61
61
  "types": "./dist/tools.d.ts",
62
62
  "import": "./dist/tools.js"
63
63
  },
64
+ "./tools/contract": {
65
+ "types": "./dist/tools-contract.d.ts",
66
+ "import": "./dist/tools-contract.js"
67
+ },
64
68
  "./tools/invoker": {
65
69
  "types": "./dist/tool-invoker.d.ts",
66
70
  "import": "./dist/tool-invoker.js"
@@ -164,18 +168,17 @@
164
168
  "scripts": {
165
169
  "build:native-contained-files": "node scripts/build-contained-files-native.mjs",
166
170
  "check": "bun x tsc --noEmit",
167
- "build:browser": "bun build src/index.ts src/live.ts src/react.ts src/contract/index.ts src/primitives.ts src/declaration.ts src/application-schemas.ts src/application.ts src/remote.ts src/agent-runtime-browser.ts --outdir dist --target node --packages external --splitting --root src",
168
- "build:server": "bun build src/server/index.ts src/node.ts src/tools.ts src/tool-invoker.ts src/cli.ts src/files.ts src/testing.ts src/observability/index.ts src/agent-runtime.ts src/agent-runtime-harness.ts src/agent-runtime-coding-tools.ts src/agent-runtime-openrouter.ts src/agent-runtime-sqlite-bun.ts src/agent-runtime-sqlite-node.ts src/application-diagnostic-journal.ts src/application-grammy.ts src/application-opentelemetry.ts src/telegram.ts --outdir dist --target node --packages external --splitting --root src",
169
- "build:js": "bun run build:browser && bun run build:server && bun scripts/preserve-webpack-ignore.mjs",
171
+ "build:js": "bun run build:entrypoints && bun scripts/preserve-webpack-ignore.mjs",
170
172
  "build:types": "bun x tsc -p tsconfig.build.json --emitDeclarationOnly && bun scripts/rewrite-declaration-specifiers.mjs",
171
173
  "build": "rm -rf dist && bun run build:js && bun run build:types && bun scripts/check-browser-clean.mjs && bun scripts/check-browser-executes.mjs && bun scripts/check-env-live.mjs && bun scripts/check-public-types.mjs",
172
- "dev": "bun run build:js -- --watch",
174
+ "dev": "bun run build:entrypoints -- --watch",
173
175
  "prepack": "cp ../../README.md ./README.md && bun ../../scripts/gen-llms.ts && bun run build",
174
176
  "test": "bun test",
175
177
  "smoke:node": "node scripts/node-smoke.mjs",
176
178
  "smoke:next-ssr": "node scripts/next-ssr-retry-smoke.mjs",
177
179
  "consumer-lane": "bun scripts/consumer-lane/run.mjs",
178
- "bench:mcp-preparation": "bun scripts/benchmark-mcp-preparation.ts"
180
+ "bench:mcp-preparation": "bun scripts/benchmark-mcp-preparation.ts",
181
+ "build:entrypoints": "bun scripts/build-entrypoints.mjs"
179
182
  },
180
183
  "peerDependencies": {
181
184
  "@modelcontextprotocol/ext-apps": "^1.7.2",
@@ -1,79 +0,0 @@
1
- // src/application/schemas.ts
2
- import { z } from "zod";
3
- var ApplicationIdSchema = z.string().min(1).max(128).regex(/^[a-zA-Z0-9][a-zA-Z0-9._:-]*$/);
4
- var ApplicationLifecycleSchema = z.enum([
5
- "created",
6
- "starting",
7
- "ready",
8
- "draining",
9
- "stopping",
10
- "stopped",
11
- "failed"
12
- ]);
13
- var ApplicationHealthSchema = z.enum(["unknown", "healthy", "degraded", "unhealthy"]);
14
- var ManagedResourceStateSchema = z.enum([
15
- "registered",
16
- "starting",
17
- "ready",
18
- "failed",
19
- "stopping",
20
- "stopped"
21
- ]);
22
- var NonNegativeIntegerSchema = z.number().int().nonnegative();
23
- var ApplicationAdmissionSnapshotSchema = z.object({
24
- accepting: z.boolean(),
25
- accepted: NonNegativeIntegerSchema,
26
- completed: NonNegativeIntegerSchema,
27
- pending: NonNegativeIntegerSchema
28
- }).readonly();
29
- var ManagedResourceSnapshotSchema = z.object({
30
- id: ApplicationIdSchema,
31
- required: z.boolean(),
32
- dependsOn: z.array(ApplicationIdSchema).readonly(),
33
- state: ManagedResourceStateSchema,
34
- health: ApplicationHealthSchema,
35
- ready: z.boolean()
36
- }).readonly();
37
- var ApplicationSnapshotSchema = z.object({
38
- id: ApplicationIdSchema,
39
- epoch: z.string().uuid(),
40
- revision: NonNegativeIntegerSchema,
41
- lifecycle: ApplicationLifecycleSchema,
42
- health: ApplicationHealthSchema,
43
- ready: z.boolean(),
44
- capturedAt: z.string().datetime({ offset: true }),
45
- changedAt: z.string().datetime({ offset: true }),
46
- admission: ApplicationAdmissionSnapshotSchema,
47
- resources: z.array(ManagedResourceSnapshotSchema).readonly()
48
- }).readonly();
49
- var ApplicationStatusProjectionSchema = z.object({
50
- id: ApplicationIdSchema,
51
- lifecycle: ApplicationLifecycleSchema,
52
- health: ApplicationHealthSchema,
53
- ready: z.boolean(),
54
- capturedAt: z.string().datetime({ offset: true }),
55
- resources: z.object({
56
- total: NonNegativeIntegerSchema,
57
- ready: NonNegativeIntegerSchema,
58
- degraded: NonNegativeIntegerSchema,
59
- failed: NonNegativeIntegerSchema
60
- }).readonly()
61
- }).readonly();
62
- var ApplicationResourceShutdownSchema = z.object({
63
- id: ApplicationIdSchema,
64
- state: z.enum(["not-started", "closed", "force-failed"]),
65
- failures: z.array(z.enum(["start", "ready", "completion", "admission", "drain", "close", "force"])).readonly()
66
- }).readonly();
67
- var ApplicationShutdownResultSchema = z.object({
68
- outcome: z.enum(["clean", "forced"]),
69
- reason: z.enum(["deadline", "signal"]).optional(),
70
- cleanupComplete: z.boolean(),
71
- acceptedOperations: NonNegativeIntegerSchema,
72
- completedOperations: NonNegativeIntegerSchema,
73
- pendingOperations: NonNegativeIntegerSchema,
74
- pendingOperationsAtForce: NonNegativeIntegerSchema,
75
- resources: z.array(ApplicationResourceShutdownSchema).readonly(),
76
- durationMs: z.number().nonnegative()
77
- }).readonly();
78
-
79
- export { ApplicationIdSchema, ApplicationSnapshotSchema, ApplicationShutdownResultSchema };
@@ -1,24 +0,0 @@
1
- // src/internal/typed.ts
2
- function typedEntries(value) {
3
- return Object.entries(value);
4
- }
5
- function isRecord(value) {
6
- return typeof value === "object" && value !== null && !Array.isArray(value);
7
- }
8
- function transportResult(value) {
9
- return value;
10
- }
11
- function mapObject(source, mapper) {
12
- const result = {};
13
- for (const [key, value] of typedEntries(source)) {
14
- const mapped = mapper(key, value);
15
- if (mapped !== undefined)
16
- result[key] = mapped;
17
- }
18
- return result;
19
- }
20
- function mapObjectTypeBoundary(source, mapper) {
21
- return mapObject(source, (key, value) => mapper(key, value));
22
- }
23
-
24
- export { typedEntries, isRecord, transportResult, mapObject, mapObjectTypeBoundary };