stitchkit 0.108.2 → 0.108.4
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 +24 -0
- package/dist/agent-runtime/coding-tool-search-patch.d.ts.map +1 -1
- package/dist/entrypoints/agent-runtime/coding-tools.js +3 -2
- package/dist/entrypoints/agent-runtime/sandbox.js +5 -3
- package/dist/entrypoints/cli.js +1 -1
- package/dist/entrypoints/contract.js +1 -1
- package/dist/entrypoints/index.js +1 -1
- package/dist/entrypoints/node.js +1 -1
- package/dist/entrypoints/process/owner-loss.d.ts +3 -0
- package/dist/entrypoints/process/owner-loss.d.ts.map +1 -0
- package/dist/entrypoints/process/owner-loss.js +6 -0
- package/dist/entrypoints/process.js +4 -2
- package/dist/entrypoints/server.js +1 -1
- package/dist/entrypoints/tools.js +1 -1
- package/dist/{index-k0kzhdw9.js → index-dasy32c8.js} +23 -634
- package/dist/index-dj1aycxw.js +639 -0
- package/dist/{index-4qh90tyw.js → index-fgq4w9bf.js} +23 -1
- package/dist/{index-vyaehh67.js → index-sjntc4az.js} +8 -5
- package/dist/process/owner-loss-guard.d.ts +9 -0
- package/dist/process/owner-loss-guard.d.ts.map +1 -1
- package/dist/tools/cli/args-fields.d.ts.map +1 -1
- package/llms/agent-runtime-coding-tools.txt +1 -1
- package/llms/agent-runtime.txt +3 -2
- package/llms/cli.2.txt +107 -0
- package/llms/cli.txt +8 -107
- package/llms/process-owner-loss.txt +18 -0
- package/llms/process.txt +18 -0
- package/llms/stitchkit.txt +1 -0
- package/llms-full.txt +39 -3
- package/llms.txt +6 -5
- package/package.json +5 -1
- /package/dist/{index-q4hjtyye.js → index-qd8x73e8.js} +0 -0
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bootstrap the private owner-loss service before an application's own argv dispatcher.
|
|
3
|
+
*
|
|
4
|
+
* Call this once before routing argv in a single-file application that lazy-imports
|
|
5
|
+
* `stitchkit/process`. `false` means the application owns this invocation and may dispatch it;
|
|
6
|
+
* `true` means the package guard owns it and the application must skip its dispatcher. The guard's
|
|
7
|
+
* child and control channel keep the process alive for exactly their own lifetime.
|
|
8
|
+
*/
|
|
9
|
+
export declare function bootstrapNativeCommandOwnerLoss(): boolean;
|
|
1
10
|
/** The built or source module that executes the guard protocol when launched directly. */
|
|
2
11
|
export declare function ownerLossGuardEntry(): string;
|
|
3
12
|
//# sourceMappingURL=owner-loss-guard.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"owner-loss-guard.d.ts","sourceRoot":"","sources":["../../src/process/owner-loss-guard.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"owner-loss-guard.d.ts","sourceRoot":"","sources":["../../src/process/owner-loss-guard.ts"],"names":[],"mappings":"AAyLA;;;;;;;GAOG;AACH,wBAAgB,+BAA+B,IAAI,OAAO,CAEzD;AAED,0FAA0F;AAC1F,wBAAgB,mBAAmB,IAAI,MAAM,CAE5C"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"args-fields.d.ts","sourceRoot":"","sources":["../../../src/tools/cli/args-fields.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAKxB,MAAM,MAAM,SAAS,GACjB,SAAS,GACT,QAAQ,GACR,QAAQ,GACR,MAAM,GACN,QAAQ,GACR,MAAM,GACN,OAAO,GACP,QAAQ,GACR,OAAO,CAAC;AAEZ,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,SAAS,CAAC;IAChB,uEAAuE;IACvE,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB,iFAAiF;IACjF,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,4EAA4E;AAC5E,wBAAgB,oBAAoB,CAClC,GAAG,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,EAC1B,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,SAAS,GAAG,SAAS,GAC1B,IAAI,CAaN;
|
|
1
|
+
{"version":3,"file":"args-fields.d.ts","sourceRoot":"","sources":["../../../src/tools/cli/args-fields.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAKxB,MAAM,MAAM,SAAS,GACjB,SAAS,GACT,QAAQ,GACR,QAAQ,GACR,MAAM,GACN,QAAQ,GACR,MAAM,GACN,OAAO,GACP,QAAQ,GACR,OAAO,CAAC;AAEZ,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,SAAS,CAAC;IAChB,uEAAuE;IACvE,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB,iFAAiF;IACjF,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,4EAA4E;AAC5E,wBAAgB,oBAAoB,CAClC,GAAG,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,EAC1B,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,SAAS,GAAG,SAAS,GAC1B,IAAI,CAaN;AAwGD;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,GAAG,SAAS,GAAG,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,CAI1F;AAKD,4GAA4G;AAC5G;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,CAI/E;AAED,oEAAoE;AACpE,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAGzD;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAKtE;AA8BD,qFAAqF;AACrF,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAKlD;AAuCD,gFAAgF;AAChF,wBAAgB,WAAW,CACzB,IAAI,EAAE,SAAS,GAAG,SAAS,EAC3B,MAAM,EAAE,MAAM,EAAE,EAChB,KAAK,EAAE,MAAM,GACZ,OAAO,CAaT;AAED,wBAAgB,SAAS,CACvB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,IAAI,EAAE,MAAM,EAAE,EACd,KAAK,EAAE,OAAO,GACb,IAAI,CAsBN"}
|
|
@@ -21,7 +21,7 @@ artifact store is supplied, `read_output`.
|
|
|
21
21
|
|
|
22
22
|
| Export | Kind | Summary |
|
|
23
23
|
|--------|------|---------|
|
|
24
|
-
| `createAgentCodingTools` | function | construct direct host-authorized bounded file, listing, glob, search, exact-snippet edit, shell and artifact runtime-tool definitions; every ordinary refusal is a typed code with an instructive `hint`, and filesystem operations use Linux `/proc/self/fd` or the packaged macOS Node-API backend and otherwise fail closed |
|
|
24
|
+
| `createAgentCodingTools` | function | construct direct host-authorized bounded file, listing, glob, search, exact-snippet edit, shell and artifact runtime-tool definitions; `edit_file` inserts `newText` literally in both single and `replaceAll` modes; every ordinary refusal is a typed code with an instructive `hint`, and filesystem operations use Linux `/proc/self/fd` or the packaged macOS Node-API backend and otherwise fail closed |
|
|
25
25
|
| `AGENT_CODING_TOOL_NAMES` | const | the mounted tool names — `read_file`, `write_file`, `edit_file`, `list_directory`, `glob`, `search_files`, `run_command`, `read_output` |
|
|
26
26
|
| `AgentCodingToolDefinition` | _type_ | peer-free structural direct-tool shape accepted by the canonical runtime-tool surface |
|
|
27
27
|
| `AgentCodingToolConfig` | _type_ | absolute root, required operation authorization, optional async/sync `authorizePath({ path })` shared by direct file effects and discovery, finite executable alias map, exact child environment and optional limits |
|
package/llms/agent-runtime.txt
CHANGED
|
@@ -322,8 +322,9 @@ includes the exact workspace-relative `recoveryPath`; an absolute path outside t
|
|
|
322
322
|
suggested replacement. Applying the suggestion still passes the same descriptor-relative
|
|
323
323
|
containment and symlink checks.
|
|
324
324
|
|
|
325
|
-
`edit_file` replaces one exact snippet. `
|
|
326
|
-
|
|
325
|
+
`edit_file` replaces one exact snippet. It inserts `newText` literally in both single and
|
|
326
|
+
`replaceAll` modes, including JavaScript replacement tokens such as `$$`, `$&`, `` $` `` and `$'`.
|
|
327
|
+
`oldText` is itself the freshness guard for the region it changes, so the digest is the optional `expectedSha256` and an edit is one call; pass the digest
|
|
327
328
|
`read_file` returned when you want the whole-file guarantee, and read the `sha256` it returns to
|
|
328
329
|
chain the next edit without re-reading. The read, the occurrence count and the construction of the
|
|
329
330
|
new content all happen inside one per-target lock, so two concurrent edits of different snippets in
|
package/llms/cli.2.txt
CHANGED
|
@@ -11,6 +11,113 @@ Parts of this slice:
|
|
|
11
11
|
# Guide: CLI (docs/guide/cli.md) (continued)
|
|
12
12
|
==============================================================================
|
|
13
13
|
|
|
14
|
+
## One operation per line — `createCliInvoker`
|
|
15
|
+
|
|
16
|
+
The most common way an agent drives a CLI is not one command: it is a stream —
|
|
17
|
+
a JSON line per operation, an answer per line — and a resumable batch of the
|
|
18
|
+
same. The mechanics contain nothing product-specific, and until now the
|
|
19
|
+
framework left the one piece that cannot be written outside it: running an
|
|
20
|
+
already-parsed call.
|
|
21
|
+
|
|
22
|
+
```ts
|
|
23
|
+
import { createCliInvoker, defineCliStreamCommand, defineCliBatchCommand } from 'stitchkit/cli'
|
|
24
|
+
|
|
25
|
+
const invoker = await createCliInvoker({ name: 'myapp', services })
|
|
26
|
+
|
|
27
|
+
const outcome = await invoker.invoke('create_item', { title: 'hello', tags: ['a'] })
|
|
28
|
+
// { ok: true, exitCode: 0, data: { … } } — nothing written, nothing exited
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
`invoke` runs the same pipeline a typed command runs — the same validation, the
|
|
32
|
+
same `lifecycle` gate, the same hooks — and returns the handler's validated
|
|
33
|
+
output with **the exit code the printed path would give**, from the same table.
|
|
34
|
+
`data` is typed `unknown`: the surface is resolved at run time from services and
|
|
35
|
+
runtime tools, so there is no compile-time name to key a result type on. Narrow
|
|
36
|
+
it with the contract's own output schema. That table used to
|
|
37
|
+
live inside the function that prints, so the only way to learn a code was to
|
|
38
|
+
print it.
|
|
39
|
+
|
|
40
|
+
Without this, a stream loop had to re-spawn the binary per line: arguments
|
|
41
|
+
serialised back into `--flag value` strings, nested objects pushed through
|
|
42
|
+
`JSON.stringify` into one argv slot and parsed again on the other side, the
|
|
43
|
+
result read back out of stdout text. Three conversions of data the framework was
|
|
44
|
+
already holding, plus a process start measured at 0.15 s — thirty seconds for a
|
|
45
|
+
two-hundred-line manifest before any work begins. The ban on nesting one stream
|
|
46
|
+
inside another was a consequence of that child process, not a rule anyone wanted.
|
|
47
|
+
|
|
48
|
+
### Native commands in the stream
|
|
49
|
+
|
|
50
|
+
A native command is in the invoker's surface when — and only when — it declares
|
|
51
|
+
`output`:
|
|
52
|
+
|
|
53
|
+
```ts
|
|
54
|
+
const describe = defineCliCommand({
|
|
55
|
+
name: 'describe', description: 'Describe the catalogue',
|
|
56
|
+
input: z.object({ model: z.string() }),
|
|
57
|
+
output: z.object({ model: z.string(), ratios: z.array(z.string()) }),
|
|
58
|
+
handler: ({ input }) => ({ model: input.model, ratios: ['1:1', '16:9'] }),
|
|
59
|
+
})
|
|
60
|
+
|
|
61
|
+
await createCliInvoker({ name: 'myapp', services, commands: [describe] })
|
|
62
|
+
// invoke('describe', { model: 'flux' }) → { ok: true, exitCode: 0, data: { … } }
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
A command that declares `output?: never` prints itself and returns nothing, so
|
|
66
|
+
there is no result to hand back; it answers `NOT_FOUND` and stays on the command
|
|
67
|
+
line, where stdout exists. Your stream command is one of these, which is why a
|
|
68
|
+
stream still cannot invoke itself.
|
|
69
|
+
|
|
70
|
+
On this path `present` is not called — it is stdout formatting, and there is no
|
|
71
|
+
stdout — while `exitCode` is applied through the same function the command line
|
|
72
|
+
uses, so a script branching on the code sees one answer from both. Anything the
|
|
73
|
+
handler writes comes back as `written` rather than interleaving with your own
|
|
74
|
+
output:
|
|
75
|
+
|
|
76
|
+
```ts
|
|
77
|
+
const outcome = await invoker.invoke('describe', { model: 'flux' })
|
|
78
|
+
outcome.written // { stderr: 'warming the cache\n' } — absent when nothing was written
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### Mounting the loop
|
|
82
|
+
|
|
83
|
+
```ts
|
|
84
|
+
await createCli({
|
|
85
|
+
name: 'myapp', version, services,
|
|
86
|
+
commands: [
|
|
87
|
+
defineCliStreamCommand({ name: 'jsonl', invoker }),
|
|
88
|
+
defineCliBatchCommand({ name: 'batch', invoker, checkpointPath: '.myapp-batch.json' }),
|
|
89
|
+
],
|
|
90
|
+
})
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
They are factories, not framework-owned names. Reserving `jsonl` and `batch`
|
|
94
|
+
would take two names out of a namespace that belongs to the application — one
|
|
95
|
+
that already has a `batch` command would either fail at startup or find its own
|
|
96
|
+
command silently shadowed — so you mount them under whatever you call them, like
|
|
97
|
+
any other command of yours.
|
|
98
|
+
|
|
99
|
+
Each line is `{ id, command, args }`; each answer is the invocation result plus
|
|
100
|
+
that `id`. A line that is not JSON, or has no `id`, is **answered** and the
|
|
101
|
+
stream continues: a stream that goes quiet on one line leaves its consumer
|
|
102
|
+
unable to tell which request it lost. Answers go to stdout, one object per line,
|
|
103
|
+
and nothing else does.
|
|
104
|
+
|
|
105
|
+
### Resuming a batch
|
|
106
|
+
|
|
107
|
+
The checkpoint records, per id, a digest of the line that produced the recorded
|
|
108
|
+
answer, and is written after **every** line by atomic rename — a checkpoint that
|
|
109
|
+
only survives a clean finish protects against exactly the case that does not
|
|
110
|
+
happen.
|
|
111
|
+
|
|
112
|
+
A re-run replays what already ran. A line whose content changed under the same
|
|
113
|
+
id is **refused**: replaying it would report success for an operation nobody
|
|
114
|
+
ran, and re-running it would repeat a paid call. Both answer a question nobody
|
|
115
|
+
asked.
|
|
116
|
+
|
|
117
|
+
What stays yours: what makes a repeat safe (an idempotency key derived from the
|
|
118
|
+
line id), which operations a batch may contain, and how much of it runs at once.
|
|
119
|
+
That is product knowledge, and the framework has no business guessing it.
|
|
120
|
+
|
|
14
121
|
## Commands discovered from a running server
|
|
15
122
|
|
|
16
123
|
A CLI compiled from contracts carries the surface of the build it was compiled
|
package/llms/cli.txt
CHANGED
|
@@ -238,11 +238,19 @@ string, the schema says what it should be:
|
|
|
238
238
|
| `z.string()` | `--name "box"` or a positional |
|
|
239
239
|
| `z.number()` | `--count 3` → `3` |
|
|
240
240
|
| `z.boolean()` | `--active` (presence) / `--active false` / `--no-active` |
|
|
241
|
+
| `z.literal(1)` / `z.literal([1, 2])` | `--level 1` → `1` |
|
|
242
|
+
| `z.literal(true)` | `--enabled` / `--no-enabled` |
|
|
243
|
+
| `z.literal('007')` | `--code 007` → `"007"` |
|
|
241
244
|
| `z.enum([...])` | `--size large` |
|
|
242
245
|
| `z.array(z.string())`| `--tag a --tag b` → `["a","b"]` |
|
|
243
246
|
| `z.object({...})` | `--opts '{"k":"v"}'` (JSON) or `--opts.k v` |
|
|
244
247
|
| `.optional()` / `.default()` | not required |
|
|
245
248
|
|
|
249
|
+
Primitive literals use the same coercion through optional, nullable and default wrappers and as
|
|
250
|
+
array elements. A literal set whose members have different primitive types stays lexical because
|
|
251
|
+
argv has no type tag: for `z.literal([7, '007'])`, `--value 007` remains the string `"007"` rather
|
|
252
|
+
than being guessed as the number `7`. The unchanged Zod schema makes the final admission decision.
|
|
253
|
+
|
|
246
254
|
After a bare boolean flag, the next token is its value when it is exactly
|
|
247
255
|
`true` or `false` — `--active false` turns it off, as it reads. Any other word
|
|
248
256
|
there stays a positional, and `--` makes a literal `false` one too. The same
|
|
@@ -916,110 +924,3 @@ asset's address comes from the manifest, and the manifest's address belongs to
|
|
|
916
924
|
your server. A channel is two documents at two addresses — which of them a build
|
|
917
925
|
consults is your decision, and `assertCliPublishable` is told about all of them
|
|
918
926
|
rather than taught the shape of any.
|
|
919
|
-
|
|
920
|
-
## One operation per line — `createCliInvoker`
|
|
921
|
-
|
|
922
|
-
The most common way an agent drives a CLI is not one command: it is a stream —
|
|
923
|
-
a JSON line per operation, an answer per line — and a resumable batch of the
|
|
924
|
-
same. The mechanics contain nothing product-specific, and until now the
|
|
925
|
-
framework left the one piece that cannot be written outside it: running an
|
|
926
|
-
already-parsed call.
|
|
927
|
-
|
|
928
|
-
```ts
|
|
929
|
-
import { createCliInvoker, defineCliStreamCommand, defineCliBatchCommand } from 'stitchkit/cli'
|
|
930
|
-
|
|
931
|
-
const invoker = await createCliInvoker({ name: 'myapp', services })
|
|
932
|
-
|
|
933
|
-
const outcome = await invoker.invoke('create_item', { title: 'hello', tags: ['a'] })
|
|
934
|
-
// { ok: true, exitCode: 0, data: { … } } — nothing written, nothing exited
|
|
935
|
-
```
|
|
936
|
-
|
|
937
|
-
`invoke` runs the same pipeline a typed command runs — the same validation, the
|
|
938
|
-
same `lifecycle` gate, the same hooks — and returns the handler's validated
|
|
939
|
-
output with **the exit code the printed path would give**, from the same table.
|
|
940
|
-
`data` is typed `unknown`: the surface is resolved at run time from services and
|
|
941
|
-
runtime tools, so there is no compile-time name to key a result type on. Narrow
|
|
942
|
-
it with the contract's own output schema. That table used to
|
|
943
|
-
live inside the function that prints, so the only way to learn a code was to
|
|
944
|
-
print it.
|
|
945
|
-
|
|
946
|
-
Without this, a stream loop had to re-spawn the binary per line: arguments
|
|
947
|
-
serialised back into `--flag value` strings, nested objects pushed through
|
|
948
|
-
`JSON.stringify` into one argv slot and parsed again on the other side, the
|
|
949
|
-
result read back out of stdout text. Three conversions of data the framework was
|
|
950
|
-
already holding, plus a process start measured at 0.15 s — thirty seconds for a
|
|
951
|
-
two-hundred-line manifest before any work begins. The ban on nesting one stream
|
|
952
|
-
inside another was a consequence of that child process, not a rule anyone wanted.
|
|
953
|
-
|
|
954
|
-
### Native commands in the stream
|
|
955
|
-
|
|
956
|
-
A native command is in the invoker's surface when — and only when — it declares
|
|
957
|
-
`output`:
|
|
958
|
-
|
|
959
|
-
```ts
|
|
960
|
-
const describe = defineCliCommand({
|
|
961
|
-
name: 'describe', description: 'Describe the catalogue',
|
|
962
|
-
input: z.object({ model: z.string() }),
|
|
963
|
-
output: z.object({ model: z.string(), ratios: z.array(z.string()) }),
|
|
964
|
-
handler: ({ input }) => ({ model: input.model, ratios: ['1:1', '16:9'] }),
|
|
965
|
-
})
|
|
966
|
-
|
|
967
|
-
await createCliInvoker({ name: 'myapp', services, commands: [describe] })
|
|
968
|
-
// invoke('describe', { model: 'flux' }) → { ok: true, exitCode: 0, data: { … } }
|
|
969
|
-
```
|
|
970
|
-
|
|
971
|
-
A command that declares `output?: never` prints itself and returns nothing, so
|
|
972
|
-
there is no result to hand back; it answers `NOT_FOUND` and stays on the command
|
|
973
|
-
line, where stdout exists. Your stream command is one of these, which is why a
|
|
974
|
-
stream still cannot invoke itself.
|
|
975
|
-
|
|
976
|
-
On this path `present` is not called — it is stdout formatting, and there is no
|
|
977
|
-
stdout — while `exitCode` is applied through the same function the command line
|
|
978
|
-
uses, so a script branching on the code sees one answer from both. Anything the
|
|
979
|
-
handler writes comes back as `written` rather than interleaving with your own
|
|
980
|
-
output:
|
|
981
|
-
|
|
982
|
-
```ts
|
|
983
|
-
const outcome = await invoker.invoke('describe', { model: 'flux' })
|
|
984
|
-
outcome.written // { stderr: 'warming the cache\n' } — absent when nothing was written
|
|
985
|
-
```
|
|
986
|
-
|
|
987
|
-
### Mounting the loop
|
|
988
|
-
|
|
989
|
-
```ts
|
|
990
|
-
await createCli({
|
|
991
|
-
name: 'myapp', version, services,
|
|
992
|
-
commands: [
|
|
993
|
-
defineCliStreamCommand({ name: 'jsonl', invoker }),
|
|
994
|
-
defineCliBatchCommand({ name: 'batch', invoker, checkpointPath: '.myapp-batch.json' }),
|
|
995
|
-
],
|
|
996
|
-
})
|
|
997
|
-
```
|
|
998
|
-
|
|
999
|
-
They are factories, not framework-owned names. Reserving `jsonl` and `batch`
|
|
1000
|
-
would take two names out of a namespace that belongs to the application — one
|
|
1001
|
-
that already has a `batch` command would either fail at startup or find its own
|
|
1002
|
-
command silently shadowed — so you mount them under whatever you call them, like
|
|
1003
|
-
any other command of yours.
|
|
1004
|
-
|
|
1005
|
-
Each line is `{ id, command, args }`; each answer is the invocation result plus
|
|
1006
|
-
that `id`. A line that is not JSON, or has no `id`, is **answered** and the
|
|
1007
|
-
stream continues: a stream that goes quiet on one line leaves its consumer
|
|
1008
|
-
unable to tell which request it lost. Answers go to stdout, one object per line,
|
|
1009
|
-
and nothing else does.
|
|
1010
|
-
|
|
1011
|
-
### Resuming a batch
|
|
1012
|
-
|
|
1013
|
-
The checkpoint records, per id, a digest of the line that produced the recorded
|
|
1014
|
-
answer, and is written after **every** line by atomic rename — a checkpoint that
|
|
1015
|
-
only survives a clean finish protects against exactly the case that does not
|
|
1016
|
-
happen.
|
|
1017
|
-
|
|
1018
|
-
A re-run replays what already ran. A line whose content changed under the same
|
|
1019
|
-
id is **refused**: replaying it would report success for an operation nobody
|
|
1020
|
-
ran, and re-running it would repeat a paid call. Both answer a question nobody
|
|
1021
|
-
asked.
|
|
1022
|
-
|
|
1023
|
-
What stays yours: what makes a repeat safe (an idempotency key derived from the
|
|
1024
|
-
line id), which operations a batch may contain, and how much of it runs at once.
|
|
1025
|
-
That is product knowledge, and the framework has no business guessing it.
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# stitchkit/process/owner-loss — stitchkit docs slice
|
|
2
|
+
|
|
3
|
+
> Generated from the `docs/` tree by `bun run gen:llms`. The index of all slices is
|
|
4
|
+
> `llms.txt` in this package.
|
|
5
|
+
|
|
6
|
+
Contains: API reference: `stitchkit/process/owner-loss` (docs/api/reference.md)
|
|
7
|
+
|
|
8
|
+
==============================================================================
|
|
9
|
+
# API reference: `stitchkit/process/owner-loss` (docs/api/reference.md)
|
|
10
|
+
==============================================================================
|
|
11
|
+
|
|
12
|
+
## `stitchkit/process/owner-loss`
|
|
13
|
+
|
|
14
|
+
Narrow startup entry for single-file applications that lazy-import `stitchkit/process`.
|
|
15
|
+
|
|
16
|
+
| Export | Kind | Purpose |
|
|
17
|
+
|---|---|---|
|
|
18
|
+
| `bootstrapNativeCommandOwnerLoss` | function | call before application argv routing; returns `true` only when the package guard owns this invocation, so the application skips its dispatcher while preserving a lazy import of the full command runner |
|
package/llms/process.txt
CHANGED
|
@@ -213,6 +213,24 @@ and Darwin under Bun and Node, requires `group: 'own'`, and other platforms refu
|
|
|
213
213
|
is opt-in. `onLeaderStarted({ pid })` reports the guard/group leader with this option; output, stdin,
|
|
214
214
|
exit status, deadlines, cancellation and `onLeaderSettled` retain the requested command's behaviour.
|
|
215
215
|
|
|
216
|
+
An unbundled application already launches the package's own guard module. A single-file bundle
|
|
217
|
+
whose application entry also owns argv routing must load the narrow bootstrap before its dispatcher
|
|
218
|
+
and skip dispatch when it claims the private guard invocation. This is especially relevant when the
|
|
219
|
+
full command runner stays behind a dynamic import:
|
|
220
|
+
|
|
221
|
+
```ts
|
|
222
|
+
import { bootstrapNativeCommandOwnerLoss } from 'stitchkit/process/owner-loss'
|
|
223
|
+
|
|
224
|
+
if (!bootstrapNativeCommandOwnerLoss()) {
|
|
225
|
+
await dispatch(process.argv.slice(2)) // may lazy-import `stitchkit/process`
|
|
226
|
+
}
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
The bootstrap carries the package-owned guard into the bundle. It returns `false` for application
|
|
230
|
+
argv and `true` only for the private child started by `runNativeCommand`, so the application does
|
|
231
|
+
not read a guard flag or filename. The built file is self-contained; no installed `node_modules`
|
|
232
|
+
is needed beside it.
|
|
233
|
+
|
|
216
234
|
### Stopping a command: the `stop` policy
|
|
217
235
|
|
|
218
236
|
A caller abort, the `timeoutMs` deadline, an exceeded output budget and a failing sink all stop the
|
package/llms/stitchkit.txt
CHANGED
|
@@ -70,6 +70,7 @@ own, recorded as an ADR.
|
|
|
70
70
|
| `stitchkit/cli/publish` | build and release tooling (Bun or Node, POSIX) | evolving | `publishCli` — commit a verified CLI distribution and move its public manifest last; see [CLI guide](cli.md#publishing-a-complete-version) |
|
|
71
71
|
| `stitchkit/remote` | browser **and** server | stable | peer-free `implementRemote` for thin HTTP proxy processes |
|
|
72
72
|
| `stitchkit/process` | server (Bun or Node, POSIX) | evolving | finite native commands, byte sinks, bounded capture, process-group cancellation and opt-in Linux/Darwin owner-loss cleanup |
|
|
73
|
+
| `stitchkit/process/owner-loss` | bundled server entry (Bun, POSIX) | evolving | narrow bootstrap that keeps the process runner lazy while carrying its owner-loss guard in a single-file bundle |
|
|
73
74
|
| `stitchkit/files/packaging` | build time (Bun or Node) | evolving | installed native asset graph, integrity, Bun packaging plugin and the artifact loader check; no runtime install policy |
|
|
74
75
|
| `stitchkit/files` | server (Bun or Node) | stable | peer-free managed local-file boundary |
|
|
75
76
|
| `stitchkit/telegram` | server (Bun or Node) | evolving | peer-free Telegram platform primitives — Mini App `initData` verification, send-failure classification, resumable broadcasts, the operator channel with dedupe, a Bot API transport that separates a request that never left from an unknown outcome, local Bot API files, webhook ownership and durable webhook update intake |
|
package/llms-full.txt
CHANGED
|
@@ -62,6 +62,7 @@ own, recorded as an ADR.
|
|
|
62
62
|
| `stitchkit/cli/publish` | build and release tooling (Bun or Node, POSIX) | evolving | `publishCli` — commit a verified CLI distribution and move its public manifest last; see [CLI guide](cli.md#publishing-a-complete-version) |
|
|
63
63
|
| `stitchkit/remote` | browser **and** server | stable | peer-free `implementRemote` for thin HTTP proxy processes |
|
|
64
64
|
| `stitchkit/process` | server (Bun or Node, POSIX) | evolving | finite native commands, byte sinks, bounded capture, process-group cancellation and opt-in Linux/Darwin owner-loss cleanup |
|
|
65
|
+
| `stitchkit/process/owner-loss` | bundled server entry (Bun, POSIX) | evolving | narrow bootstrap that keeps the process runner lazy while carrying its owner-loss guard in a single-file bundle |
|
|
65
66
|
| `stitchkit/files/packaging` | build time (Bun or Node) | evolving | installed native asset graph, integrity, Bun packaging plugin and the artifact loader check; no runtime install policy |
|
|
66
67
|
| `stitchkit/files` | server (Bun or Node) | stable | peer-free managed local-file boundary |
|
|
67
68
|
| `stitchkit/telegram` | server (Bun or Node) | evolving | peer-free Telegram platform primitives — Mini App `initData` verification, send-failure classification, resumable broadcasts, the operator channel with dedupe, a Bot API transport that separates a request that never left from an unknown outcome, local Bot API files, webhook ownership and durable webhook update intake |
|
|
@@ -5510,8 +5511,9 @@ includes the exact workspace-relative `recoveryPath`; an absolute path outside t
|
|
|
5510
5511
|
suggested replacement. Applying the suggestion still passes the same descriptor-relative
|
|
5511
5512
|
containment and symlink checks.
|
|
5512
5513
|
|
|
5513
|
-
`edit_file` replaces one exact snippet. `
|
|
5514
|
-
|
|
5514
|
+
`edit_file` replaces one exact snippet. It inserts `newText` literally in both single and
|
|
5515
|
+
`replaceAll` modes, including JavaScript replacement tokens such as `$$`, `$&`, `` $` `` and `$'`.
|
|
5516
|
+
`oldText` is itself the freshness guard for the region it changes, so the digest is the optional `expectedSha256` and an edit is one call; pass the digest
|
|
5515
5517
|
`read_file` returned when you want the whole-file guarantee, and read the `sha256` it returns to
|
|
5516
5518
|
chain the next edit without re-reading. The read, the occurrence count and the construction of the
|
|
5517
5519
|
new content all happen inside one per-target lock, so two concurrent edits of different snippets in
|
|
@@ -8396,6 +8398,24 @@ and Darwin under Bun and Node, requires `group: 'own'`, and other platforms refu
|
|
|
8396
8398
|
is opt-in. `onLeaderStarted({ pid })` reports the guard/group leader with this option; output, stdin,
|
|
8397
8399
|
exit status, deadlines, cancellation and `onLeaderSettled` retain the requested command's behaviour.
|
|
8398
8400
|
|
|
8401
|
+
An unbundled application already launches the package's own guard module. A single-file bundle
|
|
8402
|
+
whose application entry also owns argv routing must load the narrow bootstrap before its dispatcher
|
|
8403
|
+
and skip dispatch when it claims the private guard invocation. This is especially relevant when the
|
|
8404
|
+
full command runner stays behind a dynamic import:
|
|
8405
|
+
|
|
8406
|
+
```ts
|
|
8407
|
+
import { bootstrapNativeCommandOwnerLoss } from 'stitchkit/process/owner-loss'
|
|
8408
|
+
|
|
8409
|
+
if (!bootstrapNativeCommandOwnerLoss()) {
|
|
8410
|
+
await dispatch(process.argv.slice(2)) // may lazy-import `stitchkit/process`
|
|
8411
|
+
}
|
|
8412
|
+
```
|
|
8413
|
+
|
|
8414
|
+
The bootstrap carries the package-owned guard into the bundle. It returns `false` for application
|
|
8415
|
+
argv and `true` only for the private child started by `runNativeCommand`, so the application does
|
|
8416
|
+
not read a guard flag or filename. The built file is self-contained; no installed `node_modules`
|
|
8417
|
+
is needed beside it.
|
|
8418
|
+
|
|
8399
8419
|
### Stopping a command: the `stop` policy
|
|
8400
8420
|
|
|
8401
8421
|
A caller abort, the `timeoutMs` deadline, an exceeded output budget and a failing sink all stop the
|
|
@@ -9622,11 +9642,19 @@ string, the schema says what it should be:
|
|
|
9622
9642
|
| `z.string()` | `--name "box"` or a positional |
|
|
9623
9643
|
| `z.number()` | `--count 3` → `3` |
|
|
9624
9644
|
| `z.boolean()` | `--active` (presence) / `--active false` / `--no-active` |
|
|
9645
|
+
| `z.literal(1)` / `z.literal([1, 2])` | `--level 1` → `1` |
|
|
9646
|
+
| `z.literal(true)` | `--enabled` / `--no-enabled` |
|
|
9647
|
+
| `z.literal('007')` | `--code 007` → `"007"` |
|
|
9625
9648
|
| `z.enum([...])` | `--size large` |
|
|
9626
9649
|
| `z.array(z.string())`| `--tag a --tag b` → `["a","b"]` |
|
|
9627
9650
|
| `z.object({...})` | `--opts '{"k":"v"}'` (JSON) or `--opts.k v` |
|
|
9628
9651
|
| `.optional()` / `.default()` | not required |
|
|
9629
9652
|
|
|
9653
|
+
Primitive literals use the same coercion through optional, nullable and default wrappers and as
|
|
9654
|
+
array elements. A literal set whose members have different primitive types stays lexical because
|
|
9655
|
+
argv has no type tag: for `z.literal([7, '007'])`, `--value 007` remains the string `"007"` rather
|
|
9656
|
+
than being guessed as the number `7`. The unchanged Zod schema makes the final admission decision.
|
|
9657
|
+
|
|
9630
9658
|
After a bare boolean flag, the next token is its value when it is exactly
|
|
9631
9659
|
`true` or `false` — `--active false` turns it off, as it reads. Any other word
|
|
9632
9660
|
there stays a positional, and `--` makes a literal `false` one too. The same
|
|
@@ -21816,7 +21844,7 @@ artifact store is supplied, `read_output`.
|
|
|
21816
21844
|
|
|
21817
21845
|
| Export | Kind | Summary |
|
|
21818
21846
|
|--------|------|---------|
|
|
21819
|
-
| `createAgentCodingTools` | function | construct direct host-authorized bounded file, listing, glob, search, exact-snippet edit, shell and artifact runtime-tool definitions; every ordinary refusal is a typed code with an instructive `hint`, and filesystem operations use Linux `/proc/self/fd` or the packaged macOS Node-API backend and otherwise fail closed |
|
|
21847
|
+
| `createAgentCodingTools` | function | construct direct host-authorized bounded file, listing, glob, search, exact-snippet edit, shell and artifact runtime-tool definitions; `edit_file` inserts `newText` literally in both single and `replaceAll` modes; every ordinary refusal is a typed code with an instructive `hint`, and filesystem operations use Linux `/proc/self/fd` or the packaged macOS Node-API backend and otherwise fail closed |
|
|
21820
21848
|
| `AGENT_CODING_TOOL_NAMES` | const | the mounted tool names — `read_file`, `write_file`, `edit_file`, `list_directory`, `glob`, `search_files`, `run_command`, `read_output` |
|
|
21821
21849
|
| `AgentCodingToolDefinition` | _type_ | peer-free structural direct-tool shape accepted by the canonical runtime-tool surface |
|
|
21822
21850
|
| `AgentCodingToolConfig` | _type_ | absolute root, required operation authorization, optional async/sync `authorizePath({ path })` shared by direct file effects and discovery, finite executable alias map, exact child environment and optional limits |
|
|
@@ -23069,6 +23097,14 @@ Native POSIX Bun/Node one-shot command execution. See [native IO](../guide/nativ
|
|
|
23069
23097
|
| `ProcessInstanceSchema` / `ProcessInstance` | schema / type | platform, boot ID, namespace and process start identity from the shared native reader |
|
|
23070
23098
|
| `probeProcessOwner` / `ProcessOwnerEvidence` | function / type | compare lifetimes on one caller-established machine; matched, boot change, reused PID, gone, legacy or unavailable with cause |
|
|
23071
23099
|
|
|
23100
|
+
## `stitchkit/process/owner-loss`
|
|
23101
|
+
|
|
23102
|
+
Narrow startup entry for single-file applications that lazy-import `stitchkit/process`.
|
|
23103
|
+
|
|
23104
|
+
| Export | Kind | Purpose |
|
|
23105
|
+
|---|---|---|
|
|
23106
|
+
| `bootstrapNativeCommandOwnerLoss` | function | call before application argv routing; returns `true` only when the package guard owns this invocation, so the application skips its dispatcher while preserving a lazy import of the full command runner |
|
|
23107
|
+
|
|
23072
23108
|
## `stitchkit/files/packaging`
|
|
23073
23109
|
|
|
23074
23110
|
`stitchkit/files/packaging` owns `createNativePackaging` and the types
|
package/llms.txt
CHANGED
|
@@ -9,7 +9,7 @@ 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) 46.
|
|
12
|
+
- **stitchkit**: [llms/stitchkit.txt](llms/stitchkit.txt) 46.7 KB → [llms/stitchkit.2.txt](llms/stitchkit.2.txt) 36.5 KB
|
|
13
13
|
- **stitchkit/live**: [llms/live.txt](llms/live.txt) 21.2 KB
|
|
14
14
|
- **stitchkit/react**: [llms/react.txt](llms/react.txt) 8.6 KB
|
|
15
15
|
- **stitchkit/react/keyboard**: [llms/react-keyboard.txt](llms/react-keyboard.txt) 9.2 KB
|
|
@@ -18,17 +18,17 @@ Load the slice for each entrypoint your code imports — `import … from 'stitc
|
|
|
18
18
|
- **stitchkit/tools/contract**: [llms/tools-contract.txt](llms/tools-contract.txt) 0.2 KB
|
|
19
19
|
- **stitchkit/tools/invoker**: [llms/tools-invoker.txt](llms/tools-invoker.txt) 0.2 KB
|
|
20
20
|
- **stitchkit/tools/connections**: [llms/tools-connections.txt](llms/tools-connections.txt) 3.7 KB
|
|
21
|
-
- **stitchkit/cli**: [llms/cli.txt](llms/cli.txt)
|
|
21
|
+
- **stitchkit/cli**: [llms/cli.txt](llms/cli.txt) 42.8 KB → [llms/cli.2.txt](llms/cli.2.txt) 20.1 KB
|
|
22
22
|
- **stitchkit/cli/publish**: [llms/cli-publish.txt](llms/cli-publish.txt) 1.5 KB
|
|
23
23
|
- **stitchkit/remote**: [llms/remote.txt](llms/remote.txt) 1.0 KB
|
|
24
24
|
- **stitchkit/contract**: [llms/contract.txt](llms/contract.txt) 31.9 KB
|
|
25
25
|
- **stitchkit/primitives**: [llms/primitives.txt](llms/primitives.txt) 11.7 KB
|
|
26
26
|
- **stitchkit/server**: [llms/server.txt](llms/server.txt) 45.3 KB → [llms/server.2.txt](llms/server.2.txt) 14.6 KB → [llms/server.3.txt](llms/server.3.txt) 45.6 KB → [llms/server.4.txt](llms/server.4.txt) 38.3 KB → [llms/server.5.txt](llms/server.5.txt) 22.1 KB
|
|
27
27
|
- **stitchkit/observability**: [llms/observability.txt](llms/observability.txt) 45.9 KB
|
|
28
|
-
- **stitchkit/agent-runtime**: [llms/agent-runtime.txt](llms/agent-runtime.txt) 37.
|
|
28
|
+
- **stitchkit/agent-runtime**: [llms/agent-runtime.txt](llms/agent-runtime.txt) 37.1 KB → [llms/agent-runtime.2.txt](llms/agent-runtime.2.txt) 46.7 KB → [llms/agent-runtime.3.txt](llms/agent-runtime.3.txt) 34.7 KB
|
|
29
29
|
- **stitchkit/agent-runtime/testing**: [llms/agent-runtime-testing.txt](llms/agent-runtime-testing.txt) 2.6 KB
|
|
30
30
|
- **stitchkit/agent-runtime/harness**: [llms/agent-runtime-harness.txt](llms/agent-runtime-harness.txt) 11.0 KB
|
|
31
|
-
- **stitchkit/agent-runtime/coding-tools**: [llms/agent-runtime-coding-tools.txt](llms/agent-runtime-coding-tools.txt)
|
|
31
|
+
- **stitchkit/agent-runtime/coding-tools**: [llms/agent-runtime-coding-tools.txt](llms/agent-runtime-coding-tools.txt) 5.0 KB
|
|
32
32
|
- **stitchkit/agent-runtime/browser**: [llms/agent-runtime-browser.txt](llms/agent-runtime-browser.txt) 3.8 KB
|
|
33
33
|
- **stitchkit/agent-runtime/openrouter**: [llms/agent-runtime-openrouter.txt](llms/agent-runtime-openrouter.txt) 1.1 KB
|
|
34
34
|
- **stitchkit/agent-runtime/sqlite/bun**: [llms/agent-runtime-sqlite-bun.txt](llms/agent-runtime-sqlite-bun.txt) 1.8 KB
|
|
@@ -56,7 +56,8 @@ Load the slice for each entrypoint your code imports — `import … from 'stitc
|
|
|
56
56
|
- **stitchkit/node**: [llms/node.txt](llms/node.txt) 3.1 KB
|
|
57
57
|
- **stitchkit/agent-runtime/react**: [llms/agent-runtime-react.txt](llms/agent-runtime-react.txt) 1.0 KB
|
|
58
58
|
- **stitchkit/agent-runtime/realtime**: [llms/agent-runtime-realtime.txt](llms/agent-runtime-realtime.txt) 2.6 KB
|
|
59
|
-
- **stitchkit/process**: [llms/process.txt](llms/process.txt)
|
|
59
|
+
- **stitchkit/process**: [llms/process.txt](llms/process.txt) 45.8 KB
|
|
60
|
+
- **stitchkit/process/owner-loss**: [llms/process-owner-loss.txt](llms/process-owner-loss.txt) 0.9 KB
|
|
60
61
|
- **stitchkit/files/packaging**: [llms/files-packaging.txt](llms/files-packaging.txt) 3.5 KB
|
|
61
62
|
|
|
62
63
|
## Upgrading slices
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "stitchkit",
|
|
3
|
-
"version": "0.108.
|
|
3
|
+
"version": "0.108.4",
|
|
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",
|
|
@@ -249,6 +249,10 @@
|
|
|
249
249
|
"types": "./dist/entrypoints/process.d.ts",
|
|
250
250
|
"import": "./dist/entrypoints/process.js"
|
|
251
251
|
},
|
|
252
|
+
"./process/owner-loss": {
|
|
253
|
+
"types": "./dist/entrypoints/process/owner-loss.d.ts",
|
|
254
|
+
"import": "./dist/entrypoints/process/owner-loss.js"
|
|
255
|
+
},
|
|
252
256
|
"./files/packaging": {
|
|
253
257
|
"types": "./dist/entrypoints/files/packaging.d.ts",
|
|
254
258
|
"import": "./dist/entrypoints/files/packaging.js"
|
|
File without changes
|