stitchkit 0.101.3 → 0.103.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/CHANGELOG.md +64 -0
- package/dist/application/diagnostic-journal-contract.d.ts +46 -7
- package/dist/application/diagnostic-journal-contract.d.ts.map +1 -1
- package/dist/application/diagnostic-journal-frame.d.ts +9 -0
- package/dist/application/diagnostic-journal-frame.d.ts.map +1 -0
- package/dist/application/diagnostic-journal-manager.d.ts.map +1 -1
- package/dist/application/diagnostic-journal-read-contract.d.ts +110 -0
- package/dist/application/diagnostic-journal-read-contract.d.ts.map +1 -0
- package/dist/application/diagnostic-journal-reader.d.ts +13 -0
- package/dist/application/diagnostic-journal-reader.d.ts.map +1 -0
- package/dist/application/diagnostic-journal-recovery.d.ts +4 -0
- package/dist/application/diagnostic-journal-recovery.d.ts.map +1 -0
- package/dist/application/diagnostic-journal-storage.d.ts +2 -0
- package/dist/application/diagnostic-journal-storage.d.ts.map +1 -1
- package/dist/entrypoints/application/diagnostic-journal.d.ts +1 -0
- package/dist/entrypoints/application/diagnostic-journal.d.ts.map +1 -1
- package/dist/entrypoints/application/diagnostic-journal.js +213 -19
- package/dist/entrypoints/application.d.ts +1 -0
- package/dist/entrypoints/application.d.ts.map +1 -1
- package/dist/entrypoints/application.js +10 -2
- package/dist/entrypoints/tools/contract.js +1 -1
- package/dist/entrypoints/tools.js +4 -3
- package/dist/index-z94wht4y.js +156 -0
- package/dist/{index-5107q189.js → index-zax7resm.js} +13 -1
- package/dist/tools/transfer/view-file-contract.d.ts.map +1 -1
- package/dist/tools/transfer/view-file.d.ts.map +1 -1
- package/llms/application-diagnostic-journal.txt +2 -0
- package/llms/application.2.txt +157 -267
- package/llms/application.3.txt +278 -0
- package/llms/application.txt +43 -158
- package/llms/stitchkit.txt +4 -4
- package/llms/tools.2.txt +9 -0
- package/llms/tools.3.txt +1 -1
- package/llms/{upgrading-0.61.0-0.73.0.txt → upgrading-0.61.0-0.74.0.txt} +64 -3
- package/llms/{upgrading-0.74.0-0.101.0.txt → upgrading-0.75.0-0.103.0.txt} +56 -64
- package/llms/upgrading.txt +2 -2
- package/llms-full.txt +115 -9
- package/llms.txt +6 -6
- package/package.json +1 -1
- package/dist/index-h124epcf.js +0 -103
|
@@ -1,14 +1,75 @@
|
|
|
1
|
-
# Upgrading 0.61.0 → 0.
|
|
1
|
+
# Upgrading 0.61.0 → 0.74.0 — stitchkit docs slice
|
|
2
2
|
|
|
3
3
|
> Generated from the `docs/` tree by `bun run gen:llms`. The index of all slices is
|
|
4
4
|
> `llms.txt` in this package.
|
|
5
5
|
|
|
6
|
-
Contains: Guide: Upgrading, 0.61.0 → 0.
|
|
6
|
+
Contains: Guide: Upgrading, 0.61.0 → 0.74.0 (docs/guide/upgrading.md)
|
|
7
7
|
|
|
8
8
|
==============================================================================
|
|
9
|
-
# Guide: Upgrading, 0.61.0 → 0.
|
|
9
|
+
# Guide: Upgrading, 0.61.0 → 0.74.0 (docs/guide/upgrading.md)
|
|
10
10
|
==============================================================================
|
|
11
11
|
|
|
12
|
+
## Released migration: 0.74.0
|
|
13
|
+
|
|
14
|
+
One change, and it only reaches you if you catch a refusal the **client** raised — one it made while
|
|
15
|
+
planning the request, before anything was sent. A server refusal is unchanged.
|
|
16
|
+
|
|
17
|
+
### If you match on the text of a client-side refusal
|
|
18
|
+
|
|
19
|
+
A missing path param, a missing scoped prefix key, a non-flat field in a `GET` input, a missing or
|
|
20
|
+
invalid multipart file: each used to arrive as a plain `Error` carrying only a sentence. They now
|
|
21
|
+
arrive as an `ApiError` in the same shape a server validation failure uses.
|
|
22
|
+
|
|
23
|
+
```ts
|
|
24
|
+
// before
|
|
25
|
+
catch (e) {
|
|
26
|
+
if (/Missing path param/.test(e.message)) …
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// after
|
|
30
|
+
catch (e) {
|
|
31
|
+
if (e.code === 'VALIDATION_ERROR' && e.status === 0) … // refused here, nothing was sent
|
|
32
|
+
}
|
|
33
|
+
// e.details.issues[0].path === 'id'
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
`status` is what separates the two worlds, and it is not new — `0` has always meant *this never
|
|
37
|
+
reached the server*, as `REQUEST_ABORTED` and `REQUEST_TIMEOUT` already used it:
|
|
38
|
+
|
|
39
|
+
| | `code` | `status` |
|
|
40
|
+
|---|---|---|
|
|
41
|
+
| the client refused your arguments | `VALIDATION_ERROR` | `0` |
|
|
42
|
+
| the server refused your arguments | `VALIDATION_ERROR` | `400` |
|
|
43
|
+
|
|
44
|
+
`details.issues` is the same `{ path, code, message }` array on both, so one rendering serves both —
|
|
45
|
+
and `zodIssues` / `ZodIssueSummary` are now importable from `stitchkit` itself, not only from
|
|
46
|
+
`stitchkit/server`.
|
|
47
|
+
|
|
48
|
+
### If you are on `createHttpClient` and your call site relied on a synchronous throw
|
|
49
|
+
|
|
50
|
+
This is the sharp one, because it is invisible in a diff. Those refusals used to be thrown
|
|
51
|
+
**synchronously** on the Ky-backed client — before the call returned a promise — so
|
|
52
|
+
`api.upload({}).catch(handler)` never reached the handler, while the same mistake on the bare-fetch
|
|
53
|
+
client rejected normally. They now reject on both.
|
|
54
|
+
|
|
55
|
+
```ts
|
|
56
|
+
// before, on createHttpClient only
|
|
57
|
+
try {
|
|
58
|
+
api.upload({}) // threw here
|
|
59
|
+
} catch (e) { … }
|
|
60
|
+
|
|
61
|
+
// after, on both transports
|
|
62
|
+
await api.upload({}).catch(handler)
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
A `try/catch` around an `await`ed call keeps working. A `try/catch` around an un-awaited call no
|
|
66
|
+
longer catches anything — which was already true on the other transport.
|
|
67
|
+
|
|
68
|
+
Not a migration, but worth knowing: a missing multipart file used to be reported as
|
|
69
|
+
`UNKNOWN_ERROR`, the code that means *this client cannot tell you what happened*, on the one refusal
|
|
70
|
+
where it is certain nothing was sent. → ADR 0148 carries the reasoning, including why argument
|
|
71
|
+
validation stays on the server.
|
|
72
|
+
|
|
12
73
|
## Released migration: 0.73.0
|
|
13
74
|
|
|
14
75
|
Two breaking changes. Nothing you send to a server changed, and only one of these
|
|
@@ -1,14 +1,67 @@
|
|
|
1
|
-
# Upgrading 0.
|
|
1
|
+
# Upgrading 0.75.0 → 0.103.0 — stitchkit docs slice
|
|
2
2
|
|
|
3
3
|
> Generated from the `docs/` tree by `bun run gen:llms`. The index of all slices is
|
|
4
4
|
> `llms.txt` in this package.
|
|
5
5
|
|
|
6
|
-
Contains: Guide: Upgrading, 0.
|
|
6
|
+
Contains: Guide: Upgrading, 0.75.0 → 0.103.0 (docs/guide/upgrading.md)
|
|
7
7
|
|
|
8
8
|
==============================================================================
|
|
9
|
-
# Guide: Upgrading, 0.
|
|
9
|
+
# Guide: Upgrading, 0.75.0 → 0.103.0 (docs/guide/upgrading.md)
|
|
10
10
|
==============================================================================
|
|
11
11
|
|
|
12
|
+
## Released migration: 0.103.0
|
|
13
|
+
|
|
14
|
+
### Diagnostic journal startup preserves torn evidence and inspects archives
|
|
15
|
+
|
|
16
|
+
**Who must act:** operators using `maxFiles: 1` who can encounter a torn active
|
|
17
|
+
file, or whose retained files are unreadable by the writer. Clean single-file
|
|
18
|
+
journals continue to work; successful startup now requires read access to every
|
|
19
|
+
retained generation.
|
|
20
|
+
|
|
21
|
+
```ts
|
|
22
|
+
import { createDiagnosticJournal } from 'stitchkit/application/diagnostic-journal'
|
|
23
|
+
|
|
24
|
+
// Before: a torn active file could be discarded during startup.
|
|
25
|
+
await createDiagnosticJournal({ ...config, limits: { ...config.limits, maxFiles: 1 } })
|
|
26
|
+
// After: retain the torn file while the fresh writer starts in a new active file.
|
|
27
|
+
await createDiagnosticJournal({ ...config, limits: { ...config.limits, maxFiles: 2 } })
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
With single-file retention, a torn active file throws `DiagnosticJournalRecoveryError`
|
|
31
|
+
from `stitchkit/application`, carrying `recovery` observations and releasing its lock
|
|
32
|
+
without deleting evidence. Inspection I/O errors also fail startup and release the
|
|
33
|
+
lock; restore filesystem access rather than treating that failure as a bad JSON row.
|
|
34
|
+
Normal rotation retains the configured finite eviction policy.
|
|
35
|
+
|
|
36
|
+
For archive inspection, replace ad hoc line parsing with `readDiagnosticJournal`
|
|
37
|
+
from the same filesystem leaf. Handle its `frame | anomaly` stream explicitly;
|
|
38
|
+
missing files, permissions and unsafe paths still throw. See the
|
|
39
|
+
[journal guide](application-kernel.md#bounded-local-diagnostic-journal).
|
|
40
|
+
|
|
41
|
+
## Released migration: 0.102.0
|
|
42
|
+
|
|
43
|
+
### `view_file` receives an array, not an array encoded as text
|
|
44
|
+
|
|
45
|
+
**Who must act:** callers sending `paths` as a JSON-encoded array string, or
|
|
46
|
+
matching the former media-extension refusal for that input. Managed MCP,
|
|
47
|
+
Agent and CLI surfaces now reject it as `VALIDATION_ERROR` before IO; raw MCP
|
|
48
|
+
reports an input-validation error. Correct single paths and arrays need no change.
|
|
49
|
+
|
|
50
|
+
```ts
|
|
51
|
+
// Before
|
|
52
|
+
{ paths: '["image.png"]' }
|
|
53
|
+
// After
|
|
54
|
+
{ paths: ['image.png'] }
|
|
55
|
+
// One file may also be a string
|
|
56
|
+
{ paths: 'image.png' }
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
The same rule applies to an array element containing another encoded array.
|
|
60
|
+
Do not change generic string-union coercion: path strings remain strings.
|
|
61
|
+
A legitimate filename such as `[preview].PNG` is still accepted. Local
|
|
62
|
+
unsupported-extension errors now include the caller's path and extension;
|
|
63
|
+
match the error code rather than the former generic message.
|
|
64
|
+
|
|
12
65
|
## Released migration: 0.101.0
|
|
13
66
|
|
|
14
67
|
### `TelegramInitDataUser` is `TelegramUser`
|
|
@@ -1062,64 +1115,3 @@ schema.
|
|
|
1062
1115
|
`stitchkit/live`, the watch hub, the keyspace and the trust fence are all
|
|
1063
1116
|
additive. Adopt them when you want them; the guide is
|
|
1064
1117
|
[Live data](./live.md).
|
|
1065
|
-
|
|
1066
|
-
## Released migration: 0.74.0
|
|
1067
|
-
|
|
1068
|
-
One change, and it only reaches you if you catch a refusal the **client** raised — one it made while
|
|
1069
|
-
planning the request, before anything was sent. A server refusal is unchanged.
|
|
1070
|
-
|
|
1071
|
-
### If you match on the text of a client-side refusal
|
|
1072
|
-
|
|
1073
|
-
A missing path param, a missing scoped prefix key, a non-flat field in a `GET` input, a missing or
|
|
1074
|
-
invalid multipart file: each used to arrive as a plain `Error` carrying only a sentence. They now
|
|
1075
|
-
arrive as an `ApiError` in the same shape a server validation failure uses.
|
|
1076
|
-
|
|
1077
|
-
```ts
|
|
1078
|
-
// before
|
|
1079
|
-
catch (e) {
|
|
1080
|
-
if (/Missing path param/.test(e.message)) …
|
|
1081
|
-
}
|
|
1082
|
-
|
|
1083
|
-
// after
|
|
1084
|
-
catch (e) {
|
|
1085
|
-
if (e.code === 'VALIDATION_ERROR' && e.status === 0) … // refused here, nothing was sent
|
|
1086
|
-
}
|
|
1087
|
-
// e.details.issues[0].path === 'id'
|
|
1088
|
-
```
|
|
1089
|
-
|
|
1090
|
-
`status` is what separates the two worlds, and it is not new — `0` has always meant *this never
|
|
1091
|
-
reached the server*, as `REQUEST_ABORTED` and `REQUEST_TIMEOUT` already used it:
|
|
1092
|
-
|
|
1093
|
-
| | `code` | `status` |
|
|
1094
|
-
|---|---|---|
|
|
1095
|
-
| the client refused your arguments | `VALIDATION_ERROR` | `0` |
|
|
1096
|
-
| the server refused your arguments | `VALIDATION_ERROR` | `400` |
|
|
1097
|
-
|
|
1098
|
-
`details.issues` is the same `{ path, code, message }` array on both, so one rendering serves both —
|
|
1099
|
-
and `zodIssues` / `ZodIssueSummary` are now importable from `stitchkit` itself, not only from
|
|
1100
|
-
`stitchkit/server`.
|
|
1101
|
-
|
|
1102
|
-
### If you are on `createHttpClient` and your call site relied on a synchronous throw
|
|
1103
|
-
|
|
1104
|
-
This is the sharp one, because it is invisible in a diff. Those refusals used to be thrown
|
|
1105
|
-
**synchronously** on the Ky-backed client — before the call returned a promise — so
|
|
1106
|
-
`api.upload({}).catch(handler)` never reached the handler, while the same mistake on the bare-fetch
|
|
1107
|
-
client rejected normally. They now reject on both.
|
|
1108
|
-
|
|
1109
|
-
```ts
|
|
1110
|
-
// before, on createHttpClient only
|
|
1111
|
-
try {
|
|
1112
|
-
api.upload({}) // threw here
|
|
1113
|
-
} catch (e) { … }
|
|
1114
|
-
|
|
1115
|
-
// after, on both transports
|
|
1116
|
-
await api.upload({}).catch(handler)
|
|
1117
|
-
```
|
|
1118
|
-
|
|
1119
|
-
A `try/catch` around an `await`ed call keeps working. A `try/catch` around an un-awaited call no
|
|
1120
|
-
longer catches anything — which was already true on the other transport.
|
|
1121
|
-
|
|
1122
|
-
Not a migration, but worth knowing: a missing multipart file used to be reported as
|
|
1123
|
-
`UNKNOWN_ERROR`, the code that means *this client cannot tell you what happened*, on the one refusal
|
|
1124
|
-
where it is certain nothing was sent. → ADR 0148 carries the reasoning, including why argument
|
|
1125
|
-
validation stays on the server.
|
package/llms/upgrading.txt
CHANGED
|
@@ -11,8 +11,8 @@ Contains: Guide: Upgrading, general (docs/guide/upgrading.md)
|
|
|
11
11
|
|
|
12
12
|
Load this slice, then every range slice between your installed version and the target:
|
|
13
13
|
|
|
14
|
-
- 0.
|
|
15
|
-
- 0.61.0 → 0.
|
|
14
|
+
- 0.75.0 → 0.103.0: `llms/upgrading-0.75.0-0.103.0.txt`
|
|
15
|
+
- 0.61.0 → 0.74.0: `llms/upgrading-0.61.0-0.74.0.txt`
|
|
16
16
|
- 0.44.0 → 0.60.0: `llms/upgrading-0.44.0-0.60.0.txt`
|
|
17
17
|
- 0.37.0 → 0.37.0: `llms/upgrading-0.37.0.txt`
|
|
18
18
|
|
package/llms-full.txt
CHANGED
|
@@ -70,12 +70,12 @@ own, recorded as an ADR.
|
|
|
70
70
|
| `stitchkit/geo` | server (Bun or Node) | evolving | managed GeoIP reader generations, last-known-good reload and the optional MaxMind adapter |
|
|
71
71
|
| `stitchkit/oauth` | browser **and** server | evolving | provider-neutral Authorization Code + PKCE request and one-shot callback transaction mechanics |
|
|
72
72
|
| `stitchkit/google` | server (Bun or Node) | evolving | optional Google code exchange and verified OIDC identity adapter |
|
|
73
|
-
| `stitchkit/observability` | server | stable<br>_redefined in 2 of the
|
|
73
|
+
| `stitchkit/observability` | server | stable<br>_redefined in 2 of the 48 minors since 0.56.2, most recently 0.92.0_ | request/tool event projections — `createObservability`, trace context, sanitisation |
|
|
74
74
|
| `stitchkit/testing` | tests on Bun or Node | stable | in-process generated clients over a real Fetch handler, plus the managed-resource conformance kit |
|
|
75
75
|
| `stitchkit/declaration` | browser + build and deployment tooling (Bun or Node) | evolving | `ProjectDeclarationSchema` — the one machine-readable statement a repository makes about itself |
|
|
76
76
|
| `stitchkit/react` | browser + server rendering | stable | `createCursorQuery`, `createCacheBridge`, QueryClient and `ApiError` retry policy |
|
|
77
77
|
| `stitchkit/react/keyboard` | browser | evolving | which part of a screen gets a key — ordered layers, one Escape per level, list zones with real focus; see [keyboard guide](keyboard.md) |
|
|
78
|
-
| `stitchkit/agent-runtime` | server | evolving<br>_redefined in 22 of the
|
|
78
|
+
| `stitchkit/agent-runtime` | server | evolving<br>_redefined in 22 of the 48 minors since 0.56.2, most recently 0.97.0_ | optional durable conversation/run loop, history, models, prompts, fencing and events |
|
|
79
79
|
| `stitchkit/agent-runtime/sandbox` | server | evolving | optional Linux Bubblewrap sessions, durable workspaces and a host HTTP credential gateway; see [sandbox guide](sandbox.md) |
|
|
80
80
|
| `stitchkit/agent-runtime/testing` | tests on Bun or Node | evolving | credential-free replay, scripted provider faults, deterministic race controls and the agent-store conformance kit |
|
|
81
81
|
| `stitchkit/agent-runtime/harness` | server | evolving | resource-aware process-local facade over the canonical Agent runtime; supervision stays outside |
|
|
@@ -85,11 +85,11 @@ own, recorded as an ADR.
|
|
|
85
85
|
| `stitchkit/agent-runtime/sqlite/bun` | server (Bun) | evolving | durable built-in SQLite store for the agent runtime |
|
|
86
86
|
| `stitchkit/agent-runtime/sqlite/node` | server (Node ≥ 22.5) | evolving | durable built-in SQLite store for the agent runtime |
|
|
87
87
|
| `stitchkit-tui` | terminal (Bun) | evolving | optional official OpenTUI host over a caller-composed headless runtime |
|
|
88
|
-
| `stitchkit/application` | browser + server | evolving<br>_redefined in
|
|
88
|
+
| `stitchkit/application` | browser + server | evolving<br>_redefined in 11 of the 48 minors since 0.56.2, most recently 0.103.0_ | managed resource graph, readiness, admission, schedules, subtree restart and bounded shutdown |
|
|
89
89
|
| `stitchkit/application/grammy` | server | evolving | a grammY bot as application resources — configuration, then polling with updates admitted by batch — and the webhook adapter |
|
|
90
90
|
| `stitchkit/application/opentelemetry` | server | evolving | maps application snapshots onto an injected OpenTelemetry `Meter` |
|
|
91
91
|
| `stitchkit/application/schemas` | browser + server | evolving | the application's snapshot, health and shutdown schemas alone, without the kernel |
|
|
92
|
-
| `stitchkit/application/diagnostic-journal` | server | evolving | the local diagnostic journal —
|
|
92
|
+
| `stitchkit/application/diagnostic-journal` | server | evolving | the local diagnostic journal — an exclusive bounded writer and snapshot reader with explicit anomalies |
|
|
93
93
|
| `stitchkit/application/directory-inbox` | server | evolving | the directory inbox — entries another program drops into a directory, delivered to the application at least once |
|
|
94
94
|
|
|
95
95
|
Rule of thumb: browser code imports `stitchkit` and `stitchkit/react`; server
|
|
@@ -4777,6 +4777,15 @@ multimodal content beside structured per-item `errors`, and charges every item
|
|
|
4777
4777
|
to one total 20 MB batch budget. Its MCP and Agent presenters are built in;
|
|
4778
4778
|
remote fetch cancellation follows the active call signal.
|
|
4779
4779
|
|
|
4780
|
+
`paths` is one path/URL string or an actual array of strings (at most 20).
|
|
4781
|
+
Pass `{ paths: ['image.png'] }`, not `{ paths: '["image.png"]' }`: a JSON
|
|
4782
|
+
array written as text fails input validation before any file or network access,
|
|
4783
|
+
with the hint `paths is a list written as text — pass an array of paths or one
|
|
4784
|
+
path`. The same rule applies to array items and the raw `mountViewFile` input.
|
|
4785
|
+
Ordinary file names containing brackets, such as `[preview].png`, remain valid.
|
|
4786
|
+
A local file with an unsupported extension is refused before reading; its
|
|
4787
|
+
per-item error identifies the caller's path and the extension it saw.
|
|
4788
|
+
|
|
4780
4789
|
The older `mountWait`, `mountDownload`, `mountUpload` and `mountViewFile`
|
|
4781
4790
|
functions remain
|
|
4782
4791
|
intentional raw MCP adapters with their text-envelope behavior. Use them under
|
|
@@ -6613,7 +6622,7 @@ description: Compose process-local resources, schedules, readiness, drain and op
|
|
|
6613
6622
|
type: architecture
|
|
6614
6623
|
status: active
|
|
6615
6624
|
created: 2026-08-23
|
|
6616
|
-
updated: 2026-09-
|
|
6625
|
+
updated: 2026-09-30 17:41 +07:00
|
|
6617
6626
|
---
|
|
6618
6627
|
|
|
6619
6628
|
# Managed application kernel
|
|
@@ -7260,10 +7269,47 @@ short-lived reclaim guard.
|
|
|
7260
7269
|
|
|
7261
7270
|
`flush()` means every accepted append through that call's boundary settled. It is not `fsync`, a
|
|
7262
7271
|
durable receipt, exactly-once execution or remote delivery. Timeout/cancellation bound only the
|
|
7263
|
-
waiter; the writer retains physical capacity until settlement. There is no
|
|
7264
|
-
Use a durable application store or deployment-owned log collector when restart recovery, replay or
|
|
7272
|
+
waiter; the writer retains physical capacity until settlement. There is no upload or managed replay API.
|
|
7273
|
+
Use a durable application store or deployment-owned log collector when durable restart recovery, replay or
|
|
7265
7274
|
aggregation is required. → [ADR 0134](../decisions/0134-diagnostic-journal-is-bounded-local-evidence.md).
|
|
7266
7275
|
|
|
7276
|
+
For finite inspection, use the shared reader with an explicit oldest-to-newest list of existing
|
|
7277
|
+
files. Keep anomaly reporting outside the journal being inspected:
|
|
7278
|
+
|
|
7279
|
+
```ts
|
|
7280
|
+
import { readDiagnosticJournal } from 'stitchkit/application/diagnostic-journal'
|
|
7281
|
+
import { z } from 'zod'
|
|
7282
|
+
|
|
7283
|
+
const eventSchema = z.object({
|
|
7284
|
+
kind: z.enum(['resource_failed', 'recovery_started']),
|
|
7285
|
+
resource: z.string().max(80),
|
|
7286
|
+
}).strict()
|
|
7287
|
+
|
|
7288
|
+
for await (const row of readDiagnosticJournal({
|
|
7289
|
+
paths: ['/var/lib/example/diagnostic.jsonl.1', '/var/lib/example/diagnostic.jsonl'],
|
|
7290
|
+
eventSchema,
|
|
7291
|
+
maxLineBytes: 4 * 1024,
|
|
7292
|
+
})) {
|
|
7293
|
+
if (row.type === 'anomaly') internalLogger.warn(row.anomaly)
|
|
7294
|
+
else inspectEvent(row.frame.event)
|
|
7295
|
+
}
|
|
7296
|
+
```
|
|
7297
|
+
|
|
7298
|
+
The reader bounds memory by line size plus a fixed chunk, skips oversized/damaged rows with
|
|
7299
|
+
explicit anomalies, and still returns valid rows before and after them. `offset` is zero-based
|
|
7300
|
+
bytes; `line` is one-based. `position` distinguishes the file's tail from interior damage.
|
|
7301
|
+
A valid frame lacking its final LF yields a warning with `skippedBytes: 0` and its frame.
|
|
7302
|
+
Each file's size is captured at open; concurrent appends are excluded. Missing files, permissions,
|
|
7303
|
+
symlinks, non-regular files and mid-read truncation throw rather than masquerading as bad data.
|
|
7304
|
+
The caller owns file selection and coordination with an active rotator.
|
|
7305
|
+
|
|
7306
|
+
Writer startup inspects retained and active files under its lock. On damage,
|
|
7307
|
+
`journal.getStatus().recovery` contains counts and first/last anomaly locations, reconstructed
|
|
7308
|
+
again on restart from the preserved bytes. This describes startup observations, not live
|
|
7309
|
+
continuous inspection. `maxFiles: 1` cannot preserve a torn active file by rotation and throws
|
|
7310
|
+
`DiagnosticJournalRecoveryError` before removing any evidence; configure at least two slots.
|
|
7311
|
+
Normal rotation retains the existing finite eviction policy. → [ADR 0219](../decisions/0219-journal-damage-is-data-and-io-failure-is-failure.md).
|
|
7312
|
+
|
|
7267
7313
|
Shutdown performs one phase barrier at a time: stop admission everywhere,
|
|
7268
7314
|
cancel future schedules, drain admitted work, then close in reverse stable
|
|
7269
7315
|
topological order. Every hook shares the same grace deadline. Forced cleanup
|
|
@@ -14229,6 +14275,60 @@ analytics policy belong to the application.
|
|
|
14229
14275
|
|
|
14230
14276
|
# Upgrading stitchkit
|
|
14231
14277
|
|
|
14278
|
+
## Released migration: 0.103.0
|
|
14279
|
+
|
|
14280
|
+
### Diagnostic journal startup preserves torn evidence and inspects archives
|
|
14281
|
+
|
|
14282
|
+
**Who must act:** operators using `maxFiles: 1` who can encounter a torn active
|
|
14283
|
+
file, or whose retained files are unreadable by the writer. Clean single-file
|
|
14284
|
+
journals continue to work; successful startup now requires read access to every
|
|
14285
|
+
retained generation.
|
|
14286
|
+
|
|
14287
|
+
```ts
|
|
14288
|
+
import { createDiagnosticJournal } from 'stitchkit/application/diagnostic-journal'
|
|
14289
|
+
|
|
14290
|
+
// Before: a torn active file could be discarded during startup.
|
|
14291
|
+
await createDiagnosticJournal({ ...config, limits: { ...config.limits, maxFiles: 1 } })
|
|
14292
|
+
// After: retain the torn file while the fresh writer starts in a new active file.
|
|
14293
|
+
await createDiagnosticJournal({ ...config, limits: { ...config.limits, maxFiles: 2 } })
|
|
14294
|
+
```
|
|
14295
|
+
|
|
14296
|
+
With single-file retention, a torn active file throws `DiagnosticJournalRecoveryError`
|
|
14297
|
+
from `stitchkit/application`, carrying `recovery` observations and releasing its lock
|
|
14298
|
+
without deleting evidence. Inspection I/O errors also fail startup and release the
|
|
14299
|
+
lock; restore filesystem access rather than treating that failure as a bad JSON row.
|
|
14300
|
+
Normal rotation retains the configured finite eviction policy.
|
|
14301
|
+
|
|
14302
|
+
For archive inspection, replace ad hoc line parsing with `readDiagnosticJournal`
|
|
14303
|
+
from the same filesystem leaf. Handle its `frame | anomaly` stream explicitly;
|
|
14304
|
+
missing files, permissions and unsafe paths still throw. See the
|
|
14305
|
+
[journal guide](application-kernel.md#bounded-local-diagnostic-journal).
|
|
14306
|
+
|
|
14307
|
+
## Released migration: 0.102.0
|
|
14308
|
+
|
|
14309
|
+
### `view_file` receives an array, not an array encoded as text
|
|
14310
|
+
|
|
14311
|
+
**Who must act:** callers sending `paths` as a JSON-encoded array string, or
|
|
14312
|
+
matching the former media-extension refusal for that input. Managed MCP,
|
|
14313
|
+
Agent and CLI surfaces now reject it as `VALIDATION_ERROR` before IO; raw MCP
|
|
14314
|
+
reports an input-validation error. Correct single paths and arrays need no change.
|
|
14315
|
+
|
|
14316
|
+
```ts
|
|
14317
|
+
// Before
|
|
14318
|
+
{ paths: '["image.png"]' }
|
|
14319
|
+
// After
|
|
14320
|
+
{ paths: ['image.png'] }
|
|
14321
|
+
// One file may also be a string
|
|
14322
|
+
{ paths: 'image.png' }
|
|
14323
|
+
```
|
|
14324
|
+
|
|
14325
|
+
The same rule applies to an array element containing another encoded array.
|
|
14326
|
+
Do not change generic string-union coercion: path strings remain strings.
|
|
14327
|
+
A legitimate filename such as `[preview].PNG` is still accepted. Local
|
|
14328
|
+
unsupported-extension errors now include the caller's path and extension;
|
|
14329
|
+
match the error code rather than the former generic message.
|
|
14330
|
+
|
|
14331
|
+
|
|
14232
14332
|
## Released migration: 0.101.0
|
|
14233
14333
|
|
|
14234
14334
|
### `TelegramInitDataUser` is `TelegramUser`
|
|
@@ -18882,9 +18982,13 @@ cutovers are covered by the executable
|
|
|
18882
18982
|
| `DiagnosticJournalRefusalReasonSchema` / `DiagnosticJournalRefusalReason` | schema / _type_ | `closed \| failed \| invalid \| oversized \| item-capacity \| byte-capacity` |
|
|
18883
18983
|
| `DiagnosticJournalFailurePhaseSchema` / `DiagnosticJournalFailurePhase` | schema / _type_ | internal `write \| rotation \| close` failure phase exposed only to status and the isolated observer |
|
|
18884
18984
|
| `DiagnosticJournalWaitOptions` / `DiagnosticJournalFailure` | _type_ | caller wait signal/timeout and isolated internal failure callback record |
|
|
18985
|
+
| `DiagnosticJournalAnomalySchema` / `DiagnosticJournalAnomaly` | schema / _type_ | corrupt-row reason, file, zero-based byte offset, one-based line, tail/interior position and skipped bytes |
|
|
18986
|
+
| `createDiagnosticJournalReadResultSchema` / `DiagnosticJournalReadResult` | function / _type_ | owner-schema frame output or explicit anomaly; retains transformed event output types |
|
|
18987
|
+
| `DiagnosticJournalRecoveryStatusSchema` / `DiagnosticJournalRecoveryStatus` | schema / _type_ | bounded startup inspection counts and first/last anomaly locations |
|
|
18988
|
+
| `DiagnosticJournalRecoveryError` | class | torn single-file startup refusal carrying recovery observations, preserving evidence and releasing its lock |
|
|
18885
18989
|
|
|
18886
18990
|
`accepted` is bounded in-memory admission and `written` is completed append, not `fsync` or durable
|
|
18887
|
-
delivery.
|
|
18991
|
+
delivery. Its filesystem reader is in the diagnostic-journal leaf; there is no managed replay/upload API. See the
|
|
18888
18992
|
[guide](../guide/application-kernel.md#bounded-local-diagnostic-journal),
|
|
18889
18993
|
[architecture](../architecture/diagnostic-journal.md) and [ADR
|
|
18890
18994
|
0134](../decisions/0134-diagnostic-journal-is-bounded-local-evidence.md).
|
|
@@ -19059,6 +19163,8 @@ snapshots; the adapter owns no SDK lifecycle, polling or delta state.
|
|
|
19059
19163
|
| Export | Kind | Summary |
|
|
19060
19164
|
|--------|------|---------|
|
|
19061
19165
|
| `createDiagnosticJournal` | function | the bounded local journal: a file lock, a spawn to diagnose a stale one, and framed writes |
|
|
19166
|
+
| `readDiagnosticJournal` | function | bounded async stream of validated frames and explicit anomalies from finite snapshots of caller-selected files; I/O failures throw |
|
|
19167
|
+
| `DiagnosticJournalReaderConfig` | _type_ | normalized absolute `paths`, owner `eventSchema`, positive safe-integer `maxLineBytes` and optional cancellation `signal` |
|
|
19062
19168
|
|
|
19063
19169
|
Its own entrypoint because of what it reaches — `node:child_process`,
|
|
19064
19170
|
`node:fs`, `node:os`, `node:util` — with `promisify(execFile)` evaluated while
|
|
@@ -19769,7 +19875,7 @@ payload.
|
|
|
19769
19875
|
| `ToolCallContext` | _type_ | the context every tool hook receives — `{ source, mcp? }` plus whatever the mount's `context` added |
|
|
19770
19876
|
| `ViewFileOptions` | _type_ | shared URL/managed-file-boundary policy for `defineViewFileTool`, `mountViewFile` and `resolveMedia` |
|
|
19771
19877
|
| `ViewFileOutput` | _type_ | neutral managed batch result with multimodal `content` and per-item `errors` |
|
|
19772
|
-
| `ViewFileInputSchema` | constant |
|
|
19878
|
+
| `ViewFileInputSchema` | constant | one media path/URL or an array of at most 20; rejects a JSON array written as text, including in array items, before IO |
|
|
19773
19879
|
| `ViewFileOutputSchema` | constant | Zod schema for the neutral managed view-file batch result |
|
|
19774
19880
|
| `ViewFileErrorSchema` | constant | Zod schema for one structured per-item view failure |
|
|
19775
19881
|
| `McpAnnotations` | _type_ | MCP annotations on a media result |
|
package/llms.txt
CHANGED
|
@@ -9,11 +9,11 @@ Build with stitchkit: define a contract once, then `implement` it and serve it (
|
|
|
9
9
|
Load the slice for each entrypoint your code imports — `import … from 'stitchkit/server'` → `llms/server.txt`; the root `stitchkit` import → `llms/stitchkit.txt`. A slice holds that entrypoint's API reference section and the guide pages whose home it is; every guide lives in exactly one slice, and a slice that needs another's guide names it under "Also read". Each file is at most 50.0 KB; a longer one continues in numbered parts, each naming the next at its top. Moving across versions: load `llms/upgrading.txt` and the range slices it lists between your version and the target. `llms-full.txt` inlines everything; it is far larger than a context window, so do not read it whole.
|
|
10
10
|
|
|
11
11
|
## Entrypoint slices
|
|
12
|
-
- **stitchkit**: [llms/stitchkit.txt](llms/stitchkit.txt) 16.
|
|
12
|
+
- **stitchkit**: [llms/stitchkit.txt](llms/stitchkit.txt) 16.6 KB → [llms/stitchkit.2.txt](llms/stitchkit.2.txt) 45.2 KB → [llms/stitchkit.3.txt](llms/stitchkit.3.txt) 17.1 KB
|
|
13
13
|
- **stitchkit/live**: [llms/live.txt](llms/live.txt) 21.6 KB
|
|
14
14
|
- **stitchkit/react**: [llms/react.txt](llms/react.txt) 9.0 KB
|
|
15
15
|
- **stitchkit/react/keyboard**: [llms/react-keyboard.txt](llms/react-keyboard.txt) 9.4 KB
|
|
16
|
-
- **stitchkit/tools**: [llms/tools.txt](llms/tools.txt) 45.0 KB → [llms/tools.2.txt](llms/tools.2.txt) 26.
|
|
16
|
+
- **stitchkit/tools**: [llms/tools.txt](llms/tools.txt) 45.0 KB → [llms/tools.2.txt](llms/tools.2.txt) 26.9 KB → [llms/tools.3.txt](llms/tools.3.txt) 25.4 KB
|
|
17
17
|
- **stitchkit/tools/contract**: [llms/tools-contract.txt](llms/tools-contract.txt) 0.2 KB
|
|
18
18
|
- **stitchkit/tools/invoker**: [llms/tools-invoker.txt](llms/tools-invoker.txt) 0.2 KB
|
|
19
19
|
- **stitchkit/tools/connections**: [llms/tools-connections.txt](llms/tools-connections.txt) 3.1 KB
|
|
@@ -31,11 +31,11 @@ Load the slice for each entrypoint your code imports — `import … from 'stitc
|
|
|
31
31
|
- **stitchkit/agent-runtime/openrouter**: [llms/agent-runtime-openrouter.txt](llms/agent-runtime-openrouter.txt) 1.1 KB
|
|
32
32
|
- **stitchkit/agent-runtime/sqlite/bun**: [llms/agent-runtime-sqlite-bun.txt](llms/agent-runtime-sqlite-bun.txt) 1.8 KB
|
|
33
33
|
- **stitchkit/agent-runtime/sqlite/node**: [llms/agent-runtime-sqlite-node.txt](llms/agent-runtime-sqlite-node.txt) 1.7 KB
|
|
34
|
-
- **stitchkit/application**: [llms/application.txt](llms/application.txt)
|
|
34
|
+
- **stitchkit/application**: [llms/application.txt](llms/application.txt) 37.9 KB → [llms/application.2.txt](llms/application.2.txt) 24.1 KB → [llms/application.3.txt](llms/application.3.txt) 27.3 KB
|
|
35
35
|
- **stitchkit/application/grammy**: [llms/application-grammy.txt](llms/application-grammy.txt) 2.3 KB
|
|
36
36
|
- **stitchkit/application/opentelemetry**: [llms/application-opentelemetry.txt](llms/application-opentelemetry.txt) 1.6 KB
|
|
37
37
|
- **stitchkit/application/directory-inbox**: [llms/application-directory-inbox.txt](llms/application-directory-inbox.txt) 0.3 KB
|
|
38
|
-
- **stitchkit/application/diagnostic-journal**: [llms/application-diagnostic-journal.txt](llms/application-diagnostic-journal.txt) 1.
|
|
38
|
+
- **stitchkit/application/diagnostic-journal**: [llms/application-diagnostic-journal.txt](llms/application-diagnostic-journal.txt) 1.8 KB
|
|
39
39
|
- **stitchkit/application/schemas**: [llms/application-schemas.txt](llms/application-schemas.txt) 1.8 KB
|
|
40
40
|
- **stitchkit/testing**: [llms/testing.txt](llms/testing.txt) 30.8 KB
|
|
41
41
|
- **stitchkit/agent-runtime/sandbox**: [llms/agent-runtime-sandbox.txt](llms/agent-runtime-sandbox.txt) 8.1 KB
|
|
@@ -55,8 +55,8 @@ Load the slice for each entrypoint your code imports — `import … from 'stitc
|
|
|
55
55
|
|
|
56
56
|
## Upgrading slices
|
|
57
57
|
- **Upgrading — how to move across versions**: [llms/upgrading.txt](llms/upgrading.txt) 10.3 KB
|
|
58
|
-
- **Upgrading 0.
|
|
59
|
-
- **Upgrading 0.61.0 → 0.
|
|
58
|
+
- **Upgrading 0.75.0 → 0.103.0**: [llms/upgrading-0.75.0-0.103.0.txt](llms/upgrading-0.75.0-0.103.0.txt) 46.3 KB
|
|
59
|
+
- **Upgrading 0.61.0 → 0.74.0**: [llms/upgrading-0.61.0-0.74.0.txt](llms/upgrading-0.61.0-0.74.0.txt) 43.5 KB
|
|
60
60
|
- **Upgrading 0.44.0 → 0.60.0**: [llms/upgrading-0.44.0-0.60.0.txt](llms/upgrading-0.44.0-0.60.0.txt) 43.9 KB
|
|
61
61
|
- **Upgrading 0.37.0 → 0.37.0**: [llms/upgrading-0.37.0.txt](llms/upgrading-0.37.0.txt) 6.2 KB
|
|
62
62
|
|
package/package.json
CHANGED
package/dist/index-h124epcf.js
DELETED
|
@@ -1,103 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
isRecord
|
|
3
|
-
} from "./index-9jfdm5tg.js";
|
|
4
|
-
|
|
5
|
-
// src/application/diagnostic-journal-contract.ts
|
|
6
|
-
import { z } from "zod";
|
|
7
|
-
var PositiveSafeIntegerSchema = z.number().int().positive().safe();
|
|
8
|
-
var FileModeSchema = z.number().int().min(0).max(511);
|
|
9
|
-
var DiagnosticJournalLimitsSchema2 = z.object({
|
|
10
|
-
maxEventBytes: PositiveSafeIntegerSchema,
|
|
11
|
-
maxPendingItems: PositiveSafeIntegerSchema,
|
|
12
|
-
maxPendingBytes: PositiveSafeIntegerSchema,
|
|
13
|
-
maxFileBytes: PositiveSafeIntegerSchema,
|
|
14
|
-
maxFiles: PositiveSafeIntegerSchema
|
|
15
|
-
}).strict().readonly();
|
|
16
|
-
var DiagnosticJournalLockPolicySchema2 = z.enum(["refuse", "reclaim-stale"]);
|
|
17
|
-
var DiagnosticJournalStateSchema2 = z.enum(["open", "draining", "closed", "failed"]);
|
|
18
|
-
var DiagnosticJournalRefusalReasonSchema2 = z.enum([
|
|
19
|
-
"closed",
|
|
20
|
-
"failed",
|
|
21
|
-
"invalid",
|
|
22
|
-
"oversized",
|
|
23
|
-
"item-capacity",
|
|
24
|
-
"byte-capacity"
|
|
25
|
-
]);
|
|
26
|
-
var DiagnosticJournalRefusalCountersSchema = z.object({
|
|
27
|
-
closed: z.number().int().nonnegative(),
|
|
28
|
-
failed: z.number().int().nonnegative(),
|
|
29
|
-
invalid: z.number().int().nonnegative(),
|
|
30
|
-
oversized: z.number().int().nonnegative(),
|
|
31
|
-
"item-capacity": z.number().int().nonnegative(),
|
|
32
|
-
"byte-capacity": z.number().int().nonnegative()
|
|
33
|
-
}).strict().readonly();
|
|
34
|
-
var DiagnosticJournalFailurePhaseSchema2 = z.enum(["write", "rotation", "close"]);
|
|
35
|
-
var DiagnosticJournalStatusSchema2 = z.object({
|
|
36
|
-
state: DiagnosticJournalStateSchema2,
|
|
37
|
-
epoch: z.uuid(),
|
|
38
|
-
limits: DiagnosticJournalLimitsSchema2,
|
|
39
|
-
lock: z.object({
|
|
40
|
-
policy: DiagnosticJournalLockPolicySchema2,
|
|
41
|
-
reclaimedStale: z.boolean()
|
|
42
|
-
}).strict().readonly(),
|
|
43
|
-
received: z.number().int().nonnegative(),
|
|
44
|
-
accepted: z.number().int().nonnegative(),
|
|
45
|
-
refused: z.number().int().nonnegative(),
|
|
46
|
-
refusals: DiagnosticJournalRefusalCountersSchema,
|
|
47
|
-
written: z.number().int().nonnegative(),
|
|
48
|
-
failedRecords: z.number().int().nonnegative(),
|
|
49
|
-
pendingItems: z.number().int().nonnegative(),
|
|
50
|
-
pendingBytes: z.number().int().nonnegative(),
|
|
51
|
-
inFlight: z.boolean(),
|
|
52
|
-
rotations: z.number().int().nonnegative(),
|
|
53
|
-
rotationFailures: z.number().int().nonnegative(),
|
|
54
|
-
partialTails: z.number().int().nonnegative(),
|
|
55
|
-
currentFileBytes: z.number().int().nonnegative(),
|
|
56
|
-
retainedFiles: z.number().int().nonnegative(),
|
|
57
|
-
lastAcceptedSequence: z.number().int().positive().optional(),
|
|
58
|
-
lastWrittenSequence: z.number().int().positive().optional(),
|
|
59
|
-
lastSettledSequence: z.number().int().positive().optional(),
|
|
60
|
-
lastFailure: z.object({
|
|
61
|
-
phase: DiagnosticJournalFailurePhaseSchema2,
|
|
62
|
-
sequence: z.number().int().positive().optional()
|
|
63
|
-
}).strict().readonly().optional()
|
|
64
|
-
}).strict().readonly();
|
|
65
|
-
var DiagnosticJournalSubmitResultSchema2 = z.discriminatedUnion("outcome", [
|
|
66
|
-
z.object({
|
|
67
|
-
outcome: z.literal("accepted"),
|
|
68
|
-
epoch: z.uuid(),
|
|
69
|
-
sequence: z.number().int().positive()
|
|
70
|
-
}).strict().readonly(),
|
|
71
|
-
z.object({
|
|
72
|
-
outcome: z.literal("refused"),
|
|
73
|
-
reason: DiagnosticJournalRefusalReasonSchema2
|
|
74
|
-
}).strict().readonly()
|
|
75
|
-
]);
|
|
76
|
-
var DiagnosticJournalWaitResultSchema2 = z.object({
|
|
77
|
-
outcome: z.enum(["settled", "timed-out", "cancelled"]),
|
|
78
|
-
state: DiagnosticJournalStateSchema2,
|
|
79
|
-
throughSequence: z.number().int().nonnegative(),
|
|
80
|
-
settledSequence: z.number().int().nonnegative()
|
|
81
|
-
}).strict().readonly();
|
|
82
|
-
var DiagnosticJournalCloseResultSchema2 = z.object({
|
|
83
|
-
outcome: z.enum(["closed", "timed-out", "cancelled"]),
|
|
84
|
-
state: DiagnosticJournalStateSchema2,
|
|
85
|
-
pendingItems: z.number().int().nonnegative()
|
|
86
|
-
}).strict().readonly();
|
|
87
|
-
var DiagnosticJournalFrameSchema2 = z.object({
|
|
88
|
-
schemaVersion: z.literal(1),
|
|
89
|
-
epoch: z.uuid(),
|
|
90
|
-
sequence: z.number().int().positive(),
|
|
91
|
-
event: z.json()
|
|
92
|
-
}).strict().readonly();
|
|
93
|
-
function parseDiagnosticJournalMode(mode) {
|
|
94
|
-
return FileModeSchema.parse(mode ?? 384);
|
|
95
|
-
}
|
|
96
|
-
function readDiagnosticJournalLockDiagnosis2(error) {
|
|
97
|
-
if (!isRecord(error))
|
|
98
|
-
return;
|
|
99
|
-
const diagnosis = error.journalLock;
|
|
100
|
-
return isRecord(diagnosis) ? diagnosis : undefined;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
export { DiagnosticJournalLimitsSchema2, DiagnosticJournalLockPolicySchema2, DiagnosticJournalStateSchema2, DiagnosticJournalRefusalReasonSchema2, DiagnosticJournalFailurePhaseSchema2, DiagnosticJournalStatusSchema2, DiagnosticJournalSubmitResultSchema2, DiagnosticJournalWaitResultSchema2, DiagnosticJournalCloseResultSchema2, DiagnosticJournalFrameSchema2, parseDiagnosticJournalMode, readDiagnosticJournalLockDiagnosis2 };
|