stitchkit 0.104.0 → 0.104.1
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 +25 -0
- package/darwin-native.cjs +1 -3
- package/dist/entrypoints/contract.js +1 -1
- package/dist/entrypoints/files/packaging.d.ts +3 -0
- package/dist/entrypoints/files/packaging.d.ts.map +1 -0
- package/dist/entrypoints/files/packaging.js +133 -0
- package/dist/entrypoints/index.js +1 -1
- package/dist/entrypoints/node.js +1 -1
- package/dist/entrypoints/server.js +4 -4
- package/dist/files/native-packaging-layout.d.ts +12 -0
- package/dist/files/native-packaging-layout.d.ts.map +1 -0
- package/dist/files/native-packaging.d.ts +72 -0
- package/dist/files/native-packaging.d.ts.map +1 -0
- package/llms/files-packaging.txt +27 -0
- package/llms/process.txt +63 -1
- package/llms/stitchkit.txt +1 -0
- package/llms/{upgrading-0.62.0-0.79.0.txt → upgrading-0.62.0-0.80.0.txt} +49 -3
- package/llms/{upgrading-0.80.0-0.104.0.txt → upgrading-0.81.0-0.104.0.txt} +37 -49
- package/llms/upgrading.txt +2 -2
- package/llms-full.txt +112 -1
- package/llms.txt +5 -4
- package/native-assets.json +8 -0
- package/package.json +8 -3
- /package/dist/{index-22rhg58f.js → index-hp9d77wk.js} +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -15,6 +15,21 @@ additive**; the first breaking change landed in 0.10.0. Grep the file for
|
|
|
15
15
|
|
|
16
16
|
## [Unreleased]
|
|
17
17
|
|
|
18
|
+
## [0.104.1] - 2026-10-04
|
|
19
|
+
|
|
20
|
+
### Added
|
|
21
|
+
|
|
22
|
+
- `stitchkit/files/packaging` — evolving build-only `createNativePackaging` resolves the
|
|
23
|
+
installed target addon, original SHA256 and a Bun-compatible plugin for custom companion
|
|
24
|
+
placement or embedded standalone delivery. Runtime leaves keep the same native owner;
|
|
25
|
+
archives, signing and installation policy remain application-owned. → ADR 0233
|
|
26
|
+
|
|
27
|
+
### Documentation
|
|
28
|
+
|
|
29
|
+
- The JS native-asset delivery migration first affected in 0.103.13 is explicit in the
|
|
30
|
+
[upgrade guide](docs/guide/upgrading.md#released-migration-010313), including single-file
|
|
31
|
+
packaging, complete output graphs and the distinct npm/JS/compiled delivery paths.
|
|
32
|
+
|
|
18
33
|
## [0.104.0] - 2026-10-04
|
|
19
34
|
|
|
20
35
|
### ⚠️ Breaking changes
|
|
@@ -112,6 +127,16 @@ native CLI commands and ordinary one-argument state transitions remain valid.
|
|
|
112
127
|
|
|
113
128
|
## [0.103.13] - 2026-10-04
|
|
114
129
|
|
|
130
|
+
### ⚠️ Delivery migration
|
|
131
|
+
|
|
132
|
+
- `stitchkit/process`, `stitchkit/files` and contained-file tools in Bun JS distributions:
|
|
133
|
+
the static Darwin addon graph adds companion assets. This delivery change was published
|
|
134
|
+
as a patch, although packagers assuming one output must migrate:
|
|
135
|
+
`--outfile=dist/native.js` → `--outdir=dist --entry-naming=native.js` and retain all outputs.
|
|
136
|
+
Ordinary npm imports keep their package assets; Bun compiled executables embed them.
|
|
137
|
+
**Who must act:** custom JS packagers and installers, including single-archive delivery.
|
|
138
|
+
[Migration](docs/guide/upgrading.md#released-migration-010313).
|
|
139
|
+
|
|
115
140
|
### Fixed
|
|
116
141
|
|
|
117
142
|
- Darwin native process and contained-file backends retain a static addon dependency through
|
package/darwin-native.cjs
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
/**
|
|
1
|
+
/** Generated from the owning native asset graph. Loading remains lazy. */
|
|
2
2
|
module.exports = function loadDarwinAddon() {
|
|
3
|
-
// The catch also keeps non-Darwin builds independent of unavailable slices.
|
|
4
|
-
// Bun compile selects its target architecture and embeds that literal addon.
|
|
5
3
|
try {
|
|
6
4
|
if (process.arch === 'arm64') return require('./native/darwin-arm64.node');
|
|
7
5
|
if (process.arch === 'x64') return require('./native/darwin-x64.node');
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"packaging.d.ts","sourceRoot":"","sources":["../../../src/entrypoints/files/packaging.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,oBAAoB,EACpB,sBAAsB,EACtB,qBAAqB,EACrB,qBAAqB,GACtB,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAC"}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
// src/files/native-packaging.ts
|
|
2
|
+
import { createHash } from "node:crypto";
|
|
3
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
4
|
+
import { dirname, relative, resolve } from "node:path";
|
|
5
|
+
import { fileURLToPath } from "node:url";
|
|
6
|
+
import { z as z2 } from "zod";
|
|
7
|
+
|
|
8
|
+
// src/files/native-packaging-layout.ts
|
|
9
|
+
import { z } from "zod";
|
|
10
|
+
var PackagePathSchema = z.string().min(1).refine((value) => !value.startsWith("/") && !/^[a-z]:/i.test(value) && !value.includes("\\") && value.split("/").every((part) => part !== ".." && part !== "." && part.length > 0), "Expected a relative package path without traversal");
|
|
11
|
+
var NativeLayoutSchema = z.object({
|
|
12
|
+
formatVersion: z.literal(1),
|
|
13
|
+
loader: PackagePathSchema,
|
|
14
|
+
assets: z.object({ arm64: PackagePathSchema, x64: PackagePathSchema })
|
|
15
|
+
});
|
|
16
|
+
function nativeLoaderSource(assets) {
|
|
17
|
+
const quote = (value) => `'${JSON.stringify(value).slice(1, -1).replaceAll("'", "\\'")}'`;
|
|
18
|
+
const branches = Object.entries(assets).map(([architecture, asset]) => ` if (process.arch === ${quote(architecture)}) return require(${quote(asset)});`);
|
|
19
|
+
return [
|
|
20
|
+
"/** Generated from the owning native asset graph. Loading remains lazy. */",
|
|
21
|
+
"module.exports = function loadDarwinAddon() {",
|
|
22
|
+
" try {",
|
|
23
|
+
...branches,
|
|
24
|
+
" throw new Error('Unsupported Darwin addon architecture');",
|
|
25
|
+
" } catch (cause) {",
|
|
26
|
+
" throw new Error('Darwin addon loading failed', { cause });",
|
|
27
|
+
" }",
|
|
28
|
+
"};",
|
|
29
|
+
""
|
|
30
|
+
].join(`
|
|
31
|
+
`);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// src/files/native-packaging.ts
|
|
35
|
+
var OutputPathSchema = z2.string().min(1).refine((value) => !value.startsWith("/") && !/^[a-z]:/i.test(value) && !value.includes("\\") && value.split("/").every((part) => part !== ".." && part !== "." && part.length > 0), "Expected a relative output path without traversal");
|
|
36
|
+
var OptionsSchema = z2.object({
|
|
37
|
+
platform: z2.string().min(1),
|
|
38
|
+
architecture: z2.string().min(1),
|
|
39
|
+
delivery: z2.enum(["companion", "embedded"]),
|
|
40
|
+
entryPath: OutputPathSchema.refine((value) => !value.includes("[") && !value.includes("]"), "Expected a fixed entry path without Bun naming templates"),
|
|
41
|
+
assetPath: OutputPathSchema
|
|
42
|
+
}).refine((input) => input.entryPath !== input.assetPath && !input.entryPath.startsWith(`${input.assetPath}/`) && !input.assetPath.startsWith(`${input.entryPath}/`), "Entry and addon must have non-overlapping paths");
|
|
43
|
+
var AssetSchema = z2.object({
|
|
44
|
+
sourcePath: z2.string(),
|
|
45
|
+
outputPath: z2.string(),
|
|
46
|
+
sha256: z2.string().regex(/^[a-f0-9]{64}$/)
|
|
47
|
+
});
|
|
48
|
+
var RefusalSchema = z2.object({
|
|
49
|
+
state: z2.enum(["unsupported", "missing"]),
|
|
50
|
+
platform: z2.string(),
|
|
51
|
+
architecture: z2.string(),
|
|
52
|
+
code: z2.enum(["NATIVE_TARGET_UNSUPPORTED", "NATIVE_ASSET_MISSING"])
|
|
53
|
+
});
|
|
54
|
+
function installedPackageRoot() {
|
|
55
|
+
let directory = dirname(fileURLToPath(import.meta.url));
|
|
56
|
+
for (let depth = 0;depth < 64; depth++) {
|
|
57
|
+
if (existsSync(resolve(directory, "native-assets.json")))
|
|
58
|
+
return directory;
|
|
59
|
+
const parent = dirname(directory);
|
|
60
|
+
if (parent === directory)
|
|
61
|
+
break;
|
|
62
|
+
directory = parent;
|
|
63
|
+
}
|
|
64
|
+
throw new Error("Native packaging must run from its installed Stitchkit package");
|
|
65
|
+
}
|
|
66
|
+
function createNativePackaging(options) {
|
|
67
|
+
const input = OptionsSchema.parse(options);
|
|
68
|
+
if (input.platform !== "darwin" || input.architecture !== "arm64" && input.architecture !== "x64") {
|
|
69
|
+
return {
|
|
70
|
+
state: "unsupported",
|
|
71
|
+
platform: input.platform,
|
|
72
|
+
architecture: input.architecture,
|
|
73
|
+
code: "NATIVE_TARGET_UNSUPPORTED"
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
const root = installedPackageRoot();
|
|
77
|
+
const layout = NativeLayoutSchema.parse(JSON.parse(readFileSync(resolve(root, "native-assets.json"), "utf8")));
|
|
78
|
+
const manifest = z2.object({ name: z2.literal("stitchkit"), version: z2.string().min(1) }).parse(JSON.parse(readFileSync(resolve(root, "package.json"), "utf8")));
|
|
79
|
+
const loaderPath = resolve(root, layout.loader);
|
|
80
|
+
const sourcePath = resolve(root, layout.assets[input.architecture]);
|
|
81
|
+
let bytes;
|
|
82
|
+
try {
|
|
83
|
+
bytes = readFileSync(sourcePath);
|
|
84
|
+
} catch (cause) {
|
|
85
|
+
if (cause instanceof Error && "code" in cause && cause.code === "ENOENT") {
|
|
86
|
+
return {
|
|
87
|
+
state: "missing",
|
|
88
|
+
platform: input.platform,
|
|
89
|
+
architecture: input.architecture,
|
|
90
|
+
code: "NATIVE_ASSET_MISSING"
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
throw cause;
|
|
94
|
+
}
|
|
95
|
+
const outputSpecifier = relative(dirname(input.entryPath), input.assetPath).split("\\").join("/");
|
|
96
|
+
const specifier = input.delivery === "embedded" ? sourcePath : outputSpecifier.startsWith(".") ? outputSpecifier : `./${outputSpecifier}`;
|
|
97
|
+
const contents = nativeLoaderSource({ [input.architecture]: specifier });
|
|
98
|
+
return {
|
|
99
|
+
state: "ready",
|
|
100
|
+
platform: "darwin",
|
|
101
|
+
architecture: input.architecture,
|
|
102
|
+
packageVersion: manifest.version,
|
|
103
|
+
assets: [
|
|
104
|
+
{
|
|
105
|
+
sourcePath,
|
|
106
|
+
outputPath: input.assetPath,
|
|
107
|
+
sha256: createHash("sha256").update(bytes).digest("hex")
|
|
108
|
+
}
|
|
109
|
+
],
|
|
110
|
+
plugin: {
|
|
111
|
+
name: "stitchkit-native-packaging",
|
|
112
|
+
setup(build) {
|
|
113
|
+
if (input.delivery === "companion") {
|
|
114
|
+
if (build.config.entrypoints.length !== 1)
|
|
115
|
+
throw new Error("Native companion packaging requires exactly one entrypoint");
|
|
116
|
+
if (build.config.splitting)
|
|
117
|
+
throw new Error("Native companion packaging requires splitting: false");
|
|
118
|
+
const naming = build.config.naming;
|
|
119
|
+
const entry = typeof naming === "string" ? naming : naming?.entry;
|
|
120
|
+
if (entry !== input.entryPath)
|
|
121
|
+
throw new Error("Native companion packaging naming.entry must match entryPath");
|
|
122
|
+
}
|
|
123
|
+
build.onLoad({ filter: /\.[cm]?js$/ }, (args) => args.path === loaderPath ? { contents, loader: "js" } : undefined);
|
|
124
|
+
if (input.delivery === "companion") {
|
|
125
|
+
build.onResolve({ filter: /./ }, (args) => args.importer === loaderPath && args.path === specifier ? { path: specifier, external: true } : undefined);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
export {
|
|
132
|
+
createNativePackaging
|
|
133
|
+
};
|
package/dist/entrypoints/node.js
CHANGED
|
@@ -33,7 +33,7 @@ import"../index-1bx1xv1k.js";
|
|
|
33
33
|
import"../index-43p08g7t.js";
|
|
34
34
|
import"../index-4s0fep5q.js";
|
|
35
35
|
import"../index-ck71tbcf.js";
|
|
36
|
-
import"../index-
|
|
36
|
+
import"../index-hp9d77wk.js";
|
|
37
37
|
import"../index-xqhede6x.js";
|
|
38
38
|
import {
|
|
39
39
|
bindRealtimeServer2
|
|
@@ -61,7 +61,7 @@ import {
|
|
|
61
61
|
import"../index-43p08g7t.js";
|
|
62
62
|
import"../index-4s0fep5q.js";
|
|
63
63
|
import"../index-ck71tbcf.js";
|
|
64
|
-
import"../index-
|
|
64
|
+
import"../index-hp9d77wk.js";
|
|
65
65
|
import"../index-xqhede6x.js";
|
|
66
66
|
import {
|
|
67
67
|
createFileStateStore2
|
|
@@ -81,9 +81,6 @@ import {
|
|
|
81
81
|
signJwt2,
|
|
82
82
|
verifyPkce2
|
|
83
83
|
} from "../index-wh0ecvyk.js";
|
|
84
|
-
import {
|
|
85
|
-
deriveCodeChallenge2
|
|
86
|
-
} from "../index-ap3gqe56.js";
|
|
87
84
|
import {
|
|
88
85
|
defineMultipartStream2,
|
|
89
86
|
createMultipartStream2,
|
|
@@ -91,6 +88,9 @@ import {
|
|
|
91
88
|
createImplement2,
|
|
92
89
|
createScopedImplement2
|
|
93
90
|
} from "../index-g2j7pnak.js";
|
|
91
|
+
import {
|
|
92
|
+
deriveCodeChallenge2
|
|
93
|
+
} from "../index-ap3gqe56.js";
|
|
94
94
|
import {
|
|
95
95
|
isWithinDir2,
|
|
96
96
|
realPathWithinDir
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export declare const NativeLayoutSchema: z.ZodObject<{
|
|
3
|
+
formatVersion: z.ZodLiteral<1>;
|
|
4
|
+
loader: z.ZodString;
|
|
5
|
+
assets: z.ZodObject<{
|
|
6
|
+
arm64: z.ZodString;
|
|
7
|
+
x64: z.ZodString;
|
|
8
|
+
}, z.core.$strip>;
|
|
9
|
+
}, z.core.$strip>;
|
|
10
|
+
/** One lazy loader for package, companion and embedded delivery. */
|
|
11
|
+
export declare function nativeLoaderSource(assets: Readonly<Record<string, string>>): string;
|
|
12
|
+
//# sourceMappingURL=native-packaging-layout.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"native-packaging-layout.d.ts","sourceRoot":"","sources":["../../src/files/native-packaging-layout.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAcxB,eAAO,MAAM,kBAAkB;;;;;;;iBAI7B,CAAC;AAEH,oEAAoE;AACpE,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,GAAG,MAAM,CAmBnF"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
declare const OptionsSchema: z.ZodObject<{
|
|
3
|
+
platform: z.ZodString;
|
|
4
|
+
architecture: z.ZodString;
|
|
5
|
+
delivery: z.ZodEnum<{
|
|
6
|
+
companion: "companion";
|
|
7
|
+
embedded: "embedded";
|
|
8
|
+
}>;
|
|
9
|
+
entryPath: z.ZodString;
|
|
10
|
+
assetPath: z.ZodString;
|
|
11
|
+
}, z.core.$strip>;
|
|
12
|
+
declare const AssetSchema: z.ZodObject<{
|
|
13
|
+
sourcePath: z.ZodString;
|
|
14
|
+
outputPath: z.ZodString;
|
|
15
|
+
sha256: z.ZodString;
|
|
16
|
+
}, z.core.$strip>;
|
|
17
|
+
declare const RefusalSchema: z.ZodObject<{
|
|
18
|
+
state: z.ZodEnum<{
|
|
19
|
+
missing: "missing";
|
|
20
|
+
unsupported: "unsupported";
|
|
21
|
+
}>;
|
|
22
|
+
platform: z.ZodString;
|
|
23
|
+
architecture: z.ZodString;
|
|
24
|
+
code: z.ZodEnum<{
|
|
25
|
+
NATIVE_ASSET_MISSING: "NATIVE_ASSET_MISSING";
|
|
26
|
+
NATIVE_TARGET_UNSUPPORTED: "NATIVE_TARGET_UNSUPPORTED";
|
|
27
|
+
}>;
|
|
28
|
+
}, z.core.$strip>;
|
|
29
|
+
export type NativePackagingOptions = z.input<typeof OptionsSchema>;
|
|
30
|
+
export type NativePackagingAsset = z.infer<typeof AssetSchema>;
|
|
31
|
+
/** Structural Bun plugin protocol: declarations need no Bun runtime or ambient types. */
|
|
32
|
+
export type NativePackagingPlugin = {
|
|
33
|
+
name: string;
|
|
34
|
+
setup: (build: {
|
|
35
|
+
config: {
|
|
36
|
+
splitting?: boolean;
|
|
37
|
+
naming?: string | {
|
|
38
|
+
entry?: string;
|
|
39
|
+
};
|
|
40
|
+
entrypoints: string[];
|
|
41
|
+
};
|
|
42
|
+
onLoad: (options: {
|
|
43
|
+
filter: RegExp;
|
|
44
|
+
}, callback: (args: {
|
|
45
|
+
path: string;
|
|
46
|
+
}) => {
|
|
47
|
+
contents: string;
|
|
48
|
+
loader: 'js';
|
|
49
|
+
} | undefined) => unknown;
|
|
50
|
+
onResolve: (options: {
|
|
51
|
+
filter: RegExp;
|
|
52
|
+
}, callback: (args: {
|
|
53
|
+
path: string;
|
|
54
|
+
importer: string;
|
|
55
|
+
}) => {
|
|
56
|
+
path: string;
|
|
57
|
+
external: boolean;
|
|
58
|
+
} | undefined) => unknown;
|
|
59
|
+
}) => void;
|
|
60
|
+
};
|
|
61
|
+
export type NativePackagingResult = z.infer<typeof RefusalSchema> | {
|
|
62
|
+
state: 'ready';
|
|
63
|
+
platform: 'darwin';
|
|
64
|
+
architecture: 'arm64' | 'x64';
|
|
65
|
+
packageVersion: string;
|
|
66
|
+
assets: NativePackagingAsset[];
|
|
67
|
+
plugin: NativePackagingPlugin;
|
|
68
|
+
};
|
|
69
|
+
/** Resolve this installed package's asset graph, without parsing downstream loader text. */
|
|
70
|
+
export declare function createNativePackaging(options: NativePackagingOptions): NativePackagingResult;
|
|
71
|
+
export {};
|
|
72
|
+
//# sourceMappingURL=native-packaging.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"native-packaging.d.ts","sourceRoot":"","sources":["../../src/files/native-packaging.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAcxB,QAAA,MAAM,aAAa;;;;;;;;;iBAiBhB,CAAC;AACJ,QAAA,MAAM,WAAW;;;;iBAIf,CAAC;AACH,QAAA,MAAM,aAAa;;;;;;;;;;;iBAKjB,CAAC;AAEH,MAAM,MAAM,sBAAsB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,aAAa,CAAC,CAAC;AACnE,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC,CAAC;AAE/D,yFAAyF;AACzF,MAAM,MAAM,qBAAqB,GAAG;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,CAAC,KAAK,EAAE;QACb,MAAM,EAAE;YACN,SAAS,CAAC,EAAE,OAAO,CAAC;YACpB,MAAM,CAAC,EAAE,MAAM,GAAG;gBAAE,KAAK,CAAC,EAAE,MAAM,CAAA;aAAE,CAAC;YACrC,WAAW,EAAE,MAAM,EAAE,CAAC;SACvB,CAAC;QACF,MAAM,EAAE,CACN,OAAO,EAAE;YAAE,MAAM,EAAE,MAAM,CAAA;SAAE,EAC3B,QAAQ,EAAE,CAAC,IAAI,EAAE;YAAE,IAAI,EAAE,MAAM,CAAA;SAAE,KAAK;YAAE,QAAQ,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,IAAI,CAAA;SAAE,GAAG,SAAS,KACjF,OAAO,CAAC;QACb,SAAS,EAAE,CACT,OAAO,EAAE;YAAE,MAAM,EAAE,MAAM,CAAA;SAAE,EAC3B,QAAQ,EAAE,CAAC,IAAI,EAAE;YACf,IAAI,EAAE,MAAM,CAAC;YACb,QAAQ,EAAE,MAAM,CAAC;SAClB,KAAK;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,QAAQ,EAAE,OAAO,CAAA;SAAE,GAAG,SAAS,KAClD,OAAO,CAAC;KACd,KAAK,IAAI,CAAC;CACZ,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAC7B,CAAC,CAAC,KAAK,CAAC,OAAO,aAAa,CAAC,GAC7B;IACE,KAAK,EAAE,OAAO,CAAC;IACf,QAAQ,EAAE,QAAQ,CAAC;IACnB,YAAY,EAAE,OAAO,GAAG,KAAK,CAAC;IAC9B,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE,oBAAoB,EAAE,CAAC;IAC/B,MAAM,EAAE,qBAAqB,CAAC;CAC/B,CAAC;AAaN,4FAA4F;AAC5F,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,sBAAsB,GAAG,qBAAqB,CAoF5F"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# stitchkit/files/packaging — 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/files/packaging` (docs/api/reference.md)
|
|
7
|
+
|
|
8
|
+
Also read:
|
|
9
|
+
- see `llms/process.txt` for the Native IO guide
|
|
10
|
+
|
|
11
|
+
==============================================================================
|
|
12
|
+
# API reference: `stitchkit/files/packaging` (docs/api/reference.md)
|
|
13
|
+
==============================================================================
|
|
14
|
+
|
|
15
|
+
## `stitchkit/files/packaging`
|
|
16
|
+
|
|
17
|
+
`stitchkit/files/packaging` owns `createNativePackaging` and the types
|
|
18
|
+
`NativePackagingOptions`, `NativePackagingAsset`, `NativePackagingPlugin`, `NativePackagingResult`.
|
|
19
|
+
It resolves the installed package's target/version and original addon SHA256.
|
|
20
|
+
`platform`, `architecture`, `delivery`, `entryPath` and `assetPath` are explicit public inputs.
|
|
21
|
+
The result is `ready` with assets and a structural Bun plugin, or `unsupported`/`missing` with a safe code.
|
|
22
|
+
Malformed options/metadata and other filesystem errors fail rather than masquerade as missing.
|
|
23
|
+
Companion mode places an external addon relative to the emitted entry; embedded mode lets
|
|
24
|
+
Bun compile retain the matching addon. Keep JS builds without splitting, preserve every output,
|
|
25
|
+
and copy each original asset to its `outputPath` after verifying `sha256`.
|
|
26
|
+
This evolving entrypoint is a build dependency; runtime imports do not reach it.
|
|
27
|
+
The detailed recipe is in [native IO](../guide/native-io.md#public-native-packaging).
|
package/llms/process.txt
CHANGED
|
@@ -15,7 +15,7 @@ description: Native IO для Bun и Node, с явно выбранной durabi
|
|
|
15
15
|
type: guide
|
|
16
16
|
status: active
|
|
17
17
|
created: 2026-10-01 20:44 +07:00
|
|
18
|
-
updated: 2026-10-04
|
|
18
|
+
updated: 2026-10-04 20:04 +07:00
|
|
19
19
|
participants:
|
|
20
20
|
- role: authored
|
|
21
21
|
harness: Codex
|
|
@@ -293,6 +293,68 @@ no recognized native error code, the stage stays `load`; the loader never infers
|
|
|
293
293
|
This delivery removes a runtime kernel installation; it does not remove the build-time
|
|
294
294
|
Stitchkit installation or create an independent lightweight npm package.
|
|
295
295
|
|
|
296
|
+
## Public native packaging
|
|
297
|
+
|
|
298
|
+
Custom archives and installers use `stitchkit/files/packaging` at **build time**.
|
|
299
|
+
`createNativePackaging` resolves the installed version and target addon with its original SHA256;
|
|
300
|
+
its Bun-compatible plugin integrates that asset with the same lazy native loader.
|
|
301
|
+
The leaf is evolving. It requires no optional peer or Bun ambient declarations for Node imports.
|
|
302
|
+
It must run unbundled from its installed package, never from an application's runtime artifact.
|
|
303
|
+
This contract is available from 0.104.1; versions 0.103.13–0.104.0 use the complete-output recipe
|
|
304
|
+
in the previous section.
|
|
305
|
+
|
|
306
|
+
```ts
|
|
307
|
+
import { createNativePackaging } from 'stitchkit/files/packaging'
|
|
308
|
+
import { createHash } from 'node:crypto'
|
|
309
|
+
import { copyFileSync, mkdirSync, readFileSync } from 'node:fs'
|
|
310
|
+
import { dirname, join } from 'node:path'
|
|
311
|
+
|
|
312
|
+
const native = createNativePackaging({
|
|
313
|
+
platform: 'darwin', architecture: 'arm64', delivery: 'companion',
|
|
314
|
+
entryPath: 'app/native.js', assetPath: 'addons/owner.node',
|
|
315
|
+
})
|
|
316
|
+
if (native.state !== 'ready') throw new Error(native.code)
|
|
317
|
+
const result = await Bun.build({
|
|
318
|
+
entrypoints: ['src/native.ts'], target: 'node', format: 'esm',
|
|
319
|
+
outdir: 'dist', naming: { entry: 'app/native.js' }, splitting: false,
|
|
320
|
+
plugins: [native.plugin],
|
|
321
|
+
})
|
|
322
|
+
if (!result.success) throw new AggregateError(result.logs, 'Build failed')
|
|
323
|
+
// Preserve every result.outputs file under dist, then add the selected companion.
|
|
324
|
+
for (const asset of native.assets) {
|
|
325
|
+
const bytes = readFileSync(asset.sourcePath)
|
|
326
|
+
if (createHash('sha256').update(bytes).digest('hex') !== asset.sha256)
|
|
327
|
+
throw new Error('Native asset changed during build')
|
|
328
|
+
const destination = join('dist', asset.outputPath)
|
|
329
|
+
mkdirSync(dirname(destination), { recursive: true })
|
|
330
|
+
copyFileSync(asset.sourcePath, destination)
|
|
331
|
+
}
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
`entryPath` and `assetPath` are relative paths inside the application's output root, without
|
|
335
|
+
absolute paths, traversal or overlapping file/directory paths. `entryPath` is fixed, without
|
|
336
|
+
Bun naming templates such as `[dir]` or `[name]`. Companion JS builds require one entry, no splitting,
|
|
337
|
+
and `naming.entry` exactly matching `entryPath`; the plugin rejects a mismatching layout.
|
|
338
|
+
Choose any application layout; the framework does not prescribe an app directory or installer.
|
|
339
|
+
Keep every bundler output, then verify copied addon bytes against the original SHA256.
|
|
340
|
+
Archive the complete output directory with an integrity manifest, unpack to a clean directory,
|
|
341
|
+
verify the same hashes there, and run offline without the build tree or `node_modules`.
|
|
342
|
+
A digest provides integrity, not authenticity: signature and trust policy remain application-owned.
|
|
343
|
+
|
|
344
|
+
For a standalone executable use `delivery: 'embedded'` and the same plugin in `Bun.build`
|
|
345
|
+
with `compile: { outfile: ... }`. Bun embeds the selected addon; `assets` identifies its
|
|
346
|
+
original bytes for qualification, not a companion that must be installed beside the executable.
|
|
347
|
+
Cross-builds must select the requested architecture explicitly; the artifact must run on that target.
|
|
348
|
+
The installed package must contain that target's addon. No automatic fallback/downgrade occurs.
|
|
349
|
+
|
|
350
|
+
The API returns `unsupported` / `NATIVE_TARGET_UNSUPPORTED` for non-Darwin or unsupported
|
|
351
|
+
architectures, and `missing` / `NATIVE_ASSET_MISSING` for a missing addon. Portable Linux libraries
|
|
352
|
+
use their normal build, without a Darwin plugin; merely importing the build leaf loads no addon.
|
|
353
|
+
Malformed inputs, unsupported metadata versions and other IO errors throw before packaging.
|
|
354
|
+
Runtime missing/corrupt companions preserve the native `unavailable` result and safe stage/code
|
|
355
|
+
from the existing observer; they never certify a dead owner. Preserve the raw cause internally.
|
|
356
|
+
The plugin does not parse consumer JS or establish a second runtime native implementation.
|
|
357
|
+
|
|
296
358
|
## Qualification boundaries
|
|
297
359
|
|
|
298
360
|
Native command cleanup owns the child before launch subscriptions are installed. Setup
|
package/llms/stitchkit.txt
CHANGED
|
@@ -70,6 +70,7 @@ own, recorded as an ADR.
|
|
|
70
70
|
| `stitchkit/cli` | server | stable | `createCli` / `createCliInvoker` — runtime and strict NodeNext declarations without MCP SDK / `ai` |
|
|
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 and process-group cancellation |
|
|
73
|
+
| `stitchkit/files/packaging` | build time (Bun or Node) | evolving | installed native asset graph, integrity and Bun packaging plugin; no runtime install policy |
|
|
73
74
|
| `stitchkit/files` | server (Bun or Node) | stable | peer-free managed local-file boundary |
|
|
74
75
|
| `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, local Bot API files, webhook ownership and durable webhook update intake |
|
|
75
76
|
| `stitchkit/telegram/html` | browser and server | evolving | Telegram's HTML as a tree — clean any markup to what Telegram accepts, cut long text into valid parts by what the reader sees, check markup before it is sent |
|
|
@@ -1,14 +1,60 @@
|
|
|
1
|
-
# Upgrading 0.62.0 → 0.
|
|
1
|
+
# Upgrading 0.62.0 → 0.80.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.62.0 → 0.
|
|
6
|
+
Contains: Guide: Upgrading, 0.62.0 → 0.80.0 (docs/guide/upgrading.md)
|
|
7
7
|
|
|
8
8
|
==============================================================================
|
|
9
|
-
# Guide: Upgrading, 0.62.0 → 0.
|
|
9
|
+
# Guide: Upgrading, 0.62.0 → 0.80.0 (docs/guide/upgrading.md)
|
|
10
10
|
==============================================================================
|
|
11
11
|
|
|
12
|
+
## Released migration: 0.80.0
|
|
13
|
+
|
|
14
|
+
One thing, and only if you parse an async-operation snapshot.
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
rg -n "createAsyncOperationSnapshotSchema"
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
`progress` on a parsed snapshot used to be `unknown`. The factory built its
|
|
21
|
+
object shapes with a conditional spread, and the narrowing inside it widened
|
|
22
|
+
your schema back to a bare `ZodType`, so the emitted declaration threw the type
|
|
23
|
+
argument away. It is now the output of the schema you configured.
|
|
24
|
+
|
|
25
|
+
```ts
|
|
26
|
+
const schema = createAsyncOperationSnapshotSchema({
|
|
27
|
+
progress: z.object({ done: z.number(), total: z.number() }),
|
|
28
|
+
failure: z.object({ code: z.string() }),
|
|
29
|
+
})
|
|
30
|
+
const snap = schema.parse(body)
|
|
31
|
+
if (snap.phase === 'running') {
|
|
32
|
+
// before: `snap.progress` was `unknown` — this needed a cast or a narrow
|
|
33
|
+
// after: it is `{ done: number; total: number } | undefined`
|
|
34
|
+
console.log(snap.progress?.done)
|
|
35
|
+
}
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
**If you cast it**, delete the cast — it was working around the erased type.
|
|
39
|
+
**If you assigned something else to it**, the compiler now refuses, and it was
|
|
40
|
+
already a value the schema rejected at run time.
|
|
41
|
+
|
|
42
|
+
**If you pass explicit type arguments**, the no-progress form takes one now, not
|
|
43
|
+
two: the factory is two overloads. Pass none.
|
|
44
|
+
|
|
45
|
+
```ts
|
|
46
|
+
// before: createAsyncOperationSnapshotSchema<undefined, typeof Failure>({ failure: Failure })
|
|
47
|
+
// after: createAsyncOperationSnapshotSchema({ failure: Failure })
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Nothing about parsing moves. A snapshot configured without `progress` still
|
|
51
|
+
strips an unexpected `progress` rather than refusing it — that behaviour is why
|
|
52
|
+
this is overloads and not one normalised key.
|
|
53
|
+
|
|
54
|
+
**If you compile with `skipLibCheck: false`**, this is also the release that
|
|
55
|
+
makes `stitchkit/tools/contract` compile at all: it carried five `TS2344`
|
|
56
|
+
errors, one per phase, from the same conditional spread.
|
|
57
|
+
|
|
12
58
|
## Released migration: 0.79.0
|
|
13
59
|
|
|
14
60
|
One thing, and only if you assert on the whole snapshot.
|
|
@@ -1,16 +1,20 @@
|
|
|
1
|
-
# Upgrading 0.
|
|
1
|
+
# Upgrading 0.81.0 → 0.104.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.81.0 → 0.104.0 (docs/guide/upgrading.md)
|
|
7
7
|
|
|
8
8
|
==============================================================================
|
|
9
|
-
# Guide: Upgrading, 0.
|
|
9
|
+
# Guide: Upgrading, 0.81.0 → 0.104.0 (docs/guide/upgrading.md)
|
|
10
10
|
==============================================================================
|
|
11
11
|
|
|
12
12
|
## Released migration: 0.104.0
|
|
13
13
|
|
|
14
|
+
JS bundles carrying Darwin native capabilities also need the
|
|
15
|
+
[delivery migration first affected in 0.103.13](#released-migration-010313).
|
|
16
|
+
Consumers upgrading from 0.103.12 or earlier must apply it even if their TypeScript API is unchanged.
|
|
17
|
+
|
|
14
18
|
### CLI runtime-tool construction
|
|
15
19
|
|
|
16
20
|
**Who must act:** callers writing a schema-dependent handler or MCP/AI `present` directly
|
|
@@ -126,6 +130,36 @@ signals to `createCli` / `createCliInvoker` and cooperative handlers observe `ct
|
|
|
126
130
|
an origin ignoring cancellation or an external provider stopped; keep resource leases until
|
|
127
131
|
that work actually completes.
|
|
128
132
|
|
|
133
|
+
## Released migration: 0.103.13
|
|
134
|
+
|
|
135
|
+
### Darwin native assets in JS distributions
|
|
136
|
+
|
|
137
|
+
**Who must act:** Bun JS builds using `--outfile`, copying only `outputs[0]`, custom
|
|
138
|
+
single-file/archive packagers and installers delivering native process/files capabilities.
|
|
139
|
+
First affected publication: **0.103.13**. It shipped as a patch; its changed delivery graph
|
|
140
|
+
requires this migration despite unchanged API signatures.
|
|
141
|
+
|
|
142
|
+
```sh
|
|
143
|
+
# Before: one JS file was assumed to be the entire distribution.
|
|
144
|
+
bun build src/native.ts --target=bun --outfile=dist/native.js
|
|
145
|
+
# After: retain every output, with its relative path.
|
|
146
|
+
bun build src/native.ts --target=bun --outdir=dist --entry-naming=native.js
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
For `Bun.build`, copy **all** `result.outputs`, not just the JS entry or `outputs[0]`.
|
|
150
|
+
A single-file JS distribution cannot embed a native `.node` addon automatically.
|
|
151
|
+
An archive may contain JS plus companion assets, materialized together before execution.
|
|
152
|
+
Custom output layout uses the evolving build-only packaging contract in the
|
|
153
|
+
[native IO guide](native-io.md#public-native-packaging).
|
|
154
|
+
|
|
155
|
+
Three deliveries have different rules: an ordinary npm install retains the package's
|
|
156
|
+
native assets; a JS distribution must ship its complete output graph; a Bun compiled
|
|
157
|
+
executable embeds the matching addon and may still use `--outfile`.
|
|
158
|
+
The [native IO guide](native-io.md#libraries-with-a-zod-only-runtime) is the canonical recipe.
|
|
159
|
+
Check the resulting artifact offline outside the build tree and `node_modules`, including
|
|
160
|
+
process identity, live-owner lock refusal, dead-owner recovery and contained IO.
|
|
161
|
+
A missing or corrupt addon remains `unavailable`, never evidence that an owner died.
|
|
162
|
+
|
|
129
163
|
## Released migration: 0.103.0
|
|
130
164
|
|
|
131
165
|
### Diagnostic journal startup preserves torn evidence and inspects archives
|
|
@@ -1018,49 +1052,3 @@ compile error instead of building a URL with an unresolved segment. Measured
|
|
|
1018
1052
|
across three consuming applications before release (373 endpoints with path
|
|
1019
1053
|
segments), no explicit schema missed a field: the migration is deleting
|
|
1020
1054
|
schemas that only repeated the path, or nothing.
|
|
1021
|
-
|
|
1022
|
-
## Released migration: 0.80.0
|
|
1023
|
-
|
|
1024
|
-
One thing, and only if you parse an async-operation snapshot.
|
|
1025
|
-
|
|
1026
|
-
```bash
|
|
1027
|
-
rg -n "createAsyncOperationSnapshotSchema"
|
|
1028
|
-
```
|
|
1029
|
-
|
|
1030
|
-
`progress` on a parsed snapshot used to be `unknown`. The factory built its
|
|
1031
|
-
object shapes with a conditional spread, and the narrowing inside it widened
|
|
1032
|
-
your schema back to a bare `ZodType`, so the emitted declaration threw the type
|
|
1033
|
-
argument away. It is now the output of the schema you configured.
|
|
1034
|
-
|
|
1035
|
-
```ts
|
|
1036
|
-
const schema = createAsyncOperationSnapshotSchema({
|
|
1037
|
-
progress: z.object({ done: z.number(), total: z.number() }),
|
|
1038
|
-
failure: z.object({ code: z.string() }),
|
|
1039
|
-
})
|
|
1040
|
-
const snap = schema.parse(body)
|
|
1041
|
-
if (snap.phase === 'running') {
|
|
1042
|
-
// before: `snap.progress` was `unknown` — this needed a cast or a narrow
|
|
1043
|
-
// after: it is `{ done: number; total: number } | undefined`
|
|
1044
|
-
console.log(snap.progress?.done)
|
|
1045
|
-
}
|
|
1046
|
-
```
|
|
1047
|
-
|
|
1048
|
-
**If you cast it**, delete the cast — it was working around the erased type.
|
|
1049
|
-
**If you assigned something else to it**, the compiler now refuses, and it was
|
|
1050
|
-
already a value the schema rejected at run time.
|
|
1051
|
-
|
|
1052
|
-
**If you pass explicit type arguments**, the no-progress form takes one now, not
|
|
1053
|
-
two: the factory is two overloads. Pass none.
|
|
1054
|
-
|
|
1055
|
-
```ts
|
|
1056
|
-
// before: createAsyncOperationSnapshotSchema<undefined, typeof Failure>({ failure: Failure })
|
|
1057
|
-
// after: createAsyncOperationSnapshotSchema({ failure: Failure })
|
|
1058
|
-
```
|
|
1059
|
-
|
|
1060
|
-
Nothing about parsing moves. A snapshot configured without `progress` still
|
|
1061
|
-
strips an unexpected `progress` rather than refusing it — that behaviour is why
|
|
1062
|
-
this is overloads and not one normalised key.
|
|
1063
|
-
|
|
1064
|
-
**If you compile with `skipLibCheck: false`**, this is also the release that
|
|
1065
|
-
makes `stitchkit/tools/contract` compile at all: it carried five `TS2344`
|
|
1066
|
-
errors, one per phase, from the same conditional spread.
|
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.62.0 → 0.
|
|
14
|
+
- 0.81.0 → 0.104.0: `llms/upgrading-0.81.0-0.104.0.txt`
|
|
15
|
+
- 0.62.0 → 0.80.0: `llms/upgrading-0.62.0-0.80.0.txt`
|
|
16
16
|
- 0.44.0 → 0.61.0: `llms/upgrading-0.44.0-0.61.0.txt`
|
|
17
17
|
- 0.37.0 → 0.44.0: `llms/upgrading-0.37.0-0.44.0.txt`
|
|
18
18
|
|
package/llms-full.txt
CHANGED
|
@@ -61,6 +61,7 @@ own, recorded as an ADR.
|
|
|
61
61
|
| `stitchkit/cli` | server | stable | `createCli` / `createCliInvoker` — runtime and strict NodeNext declarations without MCP SDK / `ai` |
|
|
62
62
|
| `stitchkit/remote` | browser **and** server | stable | peer-free `implementRemote` for thin HTTP proxy processes |
|
|
63
63
|
| `stitchkit/process` | server (Bun or Node, POSIX) | evolving | finite native commands, byte sinks, bounded capture and process-group cancellation |
|
|
64
|
+
| `stitchkit/files/packaging` | build time (Bun or Node) | evolving | installed native asset graph, integrity and Bun packaging plugin; no runtime install policy |
|
|
64
65
|
| `stitchkit/files` | server (Bun or Node) | stable | peer-free managed local-file boundary |
|
|
65
66
|
| `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, local Bot API files, webhook ownership and durable webhook update intake |
|
|
66
67
|
| `stitchkit/telegram/html` | browser and server | evolving | Telegram's HTML as a tree — clean any markup to what Telegram accepts, cut long text into valid parts by what the reader sees, check markup before it is sent |
|
|
@@ -8130,7 +8131,7 @@ description: Native IO для Bun и Node, с явно выбранной durabi
|
|
|
8130
8131
|
type: guide
|
|
8131
8132
|
status: active
|
|
8132
8133
|
created: 2026-10-01 20:44 +07:00
|
|
8133
|
-
updated: 2026-10-04
|
|
8134
|
+
updated: 2026-10-04 20:04 +07:00
|
|
8134
8135
|
participants:
|
|
8135
8136
|
- role: authored
|
|
8136
8137
|
harness: Codex
|
|
@@ -8408,6 +8409,68 @@ no recognized native error code, the stage stays `load`; the loader never infers
|
|
|
8408
8409
|
This delivery removes a runtime kernel installation; it does not remove the build-time
|
|
8409
8410
|
Stitchkit installation or create an independent lightweight npm package.
|
|
8410
8411
|
|
|
8412
|
+
## Public native packaging
|
|
8413
|
+
|
|
8414
|
+
Custom archives and installers use `stitchkit/files/packaging` at **build time**.
|
|
8415
|
+
`createNativePackaging` resolves the installed version and target addon with its original SHA256;
|
|
8416
|
+
its Bun-compatible plugin integrates that asset with the same lazy native loader.
|
|
8417
|
+
The leaf is evolving. It requires no optional peer or Bun ambient declarations for Node imports.
|
|
8418
|
+
It must run unbundled from its installed package, never from an application's runtime artifact.
|
|
8419
|
+
This contract is available from 0.104.1; versions 0.103.13–0.104.0 use the complete-output recipe
|
|
8420
|
+
in the previous section.
|
|
8421
|
+
|
|
8422
|
+
```ts
|
|
8423
|
+
import { createNativePackaging } from 'stitchkit/files/packaging'
|
|
8424
|
+
import { createHash } from 'node:crypto'
|
|
8425
|
+
import { copyFileSync, mkdirSync, readFileSync } from 'node:fs'
|
|
8426
|
+
import { dirname, join } from 'node:path'
|
|
8427
|
+
|
|
8428
|
+
const native = createNativePackaging({
|
|
8429
|
+
platform: 'darwin', architecture: 'arm64', delivery: 'companion',
|
|
8430
|
+
entryPath: 'app/native.js', assetPath: 'addons/owner.node',
|
|
8431
|
+
})
|
|
8432
|
+
if (native.state !== 'ready') throw new Error(native.code)
|
|
8433
|
+
const result = await Bun.build({
|
|
8434
|
+
entrypoints: ['src/native.ts'], target: 'node', format: 'esm',
|
|
8435
|
+
outdir: 'dist', naming: { entry: 'app/native.js' }, splitting: false,
|
|
8436
|
+
plugins: [native.plugin],
|
|
8437
|
+
})
|
|
8438
|
+
if (!result.success) throw new AggregateError(result.logs, 'Build failed')
|
|
8439
|
+
// Preserve every result.outputs file under dist, then add the selected companion.
|
|
8440
|
+
for (const asset of native.assets) {
|
|
8441
|
+
const bytes = readFileSync(asset.sourcePath)
|
|
8442
|
+
if (createHash('sha256').update(bytes).digest('hex') !== asset.sha256)
|
|
8443
|
+
throw new Error('Native asset changed during build')
|
|
8444
|
+
const destination = join('dist', asset.outputPath)
|
|
8445
|
+
mkdirSync(dirname(destination), { recursive: true })
|
|
8446
|
+
copyFileSync(asset.sourcePath, destination)
|
|
8447
|
+
}
|
|
8448
|
+
```
|
|
8449
|
+
|
|
8450
|
+
`entryPath` and `assetPath` are relative paths inside the application's output root, without
|
|
8451
|
+
absolute paths, traversal or overlapping file/directory paths. `entryPath` is fixed, without
|
|
8452
|
+
Bun naming templates such as `[dir]` or `[name]`. Companion JS builds require one entry, no splitting,
|
|
8453
|
+
and `naming.entry` exactly matching `entryPath`; the plugin rejects a mismatching layout.
|
|
8454
|
+
Choose any application layout; the framework does not prescribe an app directory or installer.
|
|
8455
|
+
Keep every bundler output, then verify copied addon bytes against the original SHA256.
|
|
8456
|
+
Archive the complete output directory with an integrity manifest, unpack to a clean directory,
|
|
8457
|
+
verify the same hashes there, and run offline without the build tree or `node_modules`.
|
|
8458
|
+
A digest provides integrity, not authenticity: signature and trust policy remain application-owned.
|
|
8459
|
+
|
|
8460
|
+
For a standalone executable use `delivery: 'embedded'` and the same plugin in `Bun.build`
|
|
8461
|
+
with `compile: { outfile: ... }`. Bun embeds the selected addon; `assets` identifies its
|
|
8462
|
+
original bytes for qualification, not a companion that must be installed beside the executable.
|
|
8463
|
+
Cross-builds must select the requested architecture explicitly; the artifact must run on that target.
|
|
8464
|
+
The installed package must contain that target's addon. No automatic fallback/downgrade occurs.
|
|
8465
|
+
|
|
8466
|
+
The API returns `unsupported` / `NATIVE_TARGET_UNSUPPORTED` for non-Darwin or unsupported
|
|
8467
|
+
architectures, and `missing` / `NATIVE_ASSET_MISSING` for a missing addon. Portable Linux libraries
|
|
8468
|
+
use their normal build, without a Darwin plugin; merely importing the build leaf loads no addon.
|
|
8469
|
+
Malformed inputs, unsupported metadata versions and other IO errors throw before packaging.
|
|
8470
|
+
Runtime missing/corrupt companions preserve the native `unavailable` result and safe stage/code
|
|
8471
|
+
from the existing observer; they never certify a dead owner. Preserve the raw cause internally.
|
|
8472
|
+
The plugin does not parse consumer JS or establish a second runtime native implementation.
|
|
8473
|
+
|
|
8411
8474
|
## Qualification boundaries
|
|
8412
8475
|
|
|
8413
8476
|
Native command cleanup owns the child before launch subscriptions are installed. Setup
|
|
@@ -15258,6 +15321,10 @@ analytics policy belong to the application.
|
|
|
15258
15321
|
|
|
15259
15322
|
## Released migration: 0.104.0
|
|
15260
15323
|
|
|
15324
|
+
JS bundles carrying Darwin native capabilities also need the
|
|
15325
|
+
[delivery migration first affected in 0.103.13](#released-migration-010313).
|
|
15326
|
+
Consumers upgrading from 0.103.12 or earlier must apply it even if their TypeScript API is unchanged.
|
|
15327
|
+
|
|
15261
15328
|
### CLI runtime-tool construction
|
|
15262
15329
|
|
|
15263
15330
|
**Who must act:** callers writing a schema-dependent handler or MCP/AI `present` directly
|
|
@@ -15373,6 +15440,36 @@ signals to `createCli` / `createCliInvoker` and cooperative handlers observe `ct
|
|
|
15373
15440
|
an origin ignoring cancellation or an external provider stopped; keep resource leases until
|
|
15374
15441
|
that work actually completes.
|
|
15375
15442
|
|
|
15443
|
+
## Released migration: 0.103.13
|
|
15444
|
+
|
|
15445
|
+
### Darwin native assets in JS distributions
|
|
15446
|
+
|
|
15447
|
+
**Who must act:** Bun JS builds using `--outfile`, copying only `outputs[0]`, custom
|
|
15448
|
+
single-file/archive packagers and installers delivering native process/files capabilities.
|
|
15449
|
+
First affected publication: **0.103.13**. It shipped as a patch; its changed delivery graph
|
|
15450
|
+
requires this migration despite unchanged API signatures.
|
|
15451
|
+
|
|
15452
|
+
```sh
|
|
15453
|
+
# Before: one JS file was assumed to be the entire distribution.
|
|
15454
|
+
bun build src/native.ts --target=bun --outfile=dist/native.js
|
|
15455
|
+
# After: retain every output, with its relative path.
|
|
15456
|
+
bun build src/native.ts --target=bun --outdir=dist --entry-naming=native.js
|
|
15457
|
+
```
|
|
15458
|
+
|
|
15459
|
+
For `Bun.build`, copy **all** `result.outputs`, not just the JS entry or `outputs[0]`.
|
|
15460
|
+
A single-file JS distribution cannot embed a native `.node` addon automatically.
|
|
15461
|
+
An archive may contain JS plus companion assets, materialized together before execution.
|
|
15462
|
+
Custom output layout uses the evolving build-only packaging contract in the
|
|
15463
|
+
[native IO guide](native-io.md#public-native-packaging).
|
|
15464
|
+
|
|
15465
|
+
Three deliveries have different rules: an ordinary npm install retains the package's
|
|
15466
|
+
native assets; a JS distribution must ship its complete output graph; a Bun compiled
|
|
15467
|
+
executable embeds the matching addon and may still use `--outfile`.
|
|
15468
|
+
The [native IO guide](native-io.md#libraries-with-a-zod-only-runtime) is the canonical recipe.
|
|
15469
|
+
Check the resulting artifact offline outside the build tree and `node_modules`, including
|
|
15470
|
+
process identity, live-owner lock refusal, dead-owner recovery and contained IO.
|
|
15471
|
+
A missing or corrupt addon remains `unavailable`, never evidence that an owner died.
|
|
15472
|
+
|
|
15376
15473
|
## Released migration: 0.103.0
|
|
15377
15474
|
|
|
15378
15475
|
### Diagnostic journal startup preserves torn evidence and inspects archives
|
|
@@ -21887,3 +21984,17 @@ Native POSIX Bun/Node one-shot command execution. See [native IO](../guide/nativ
|
|
|
21887
21984
|
| `observeProcessInstance` / `ProcessInstanceObservation` | function / type | Linux/Darwin lifetime observation; observed identity or unavailable with its original cause, never guessed absence |
|
|
21888
21985
|
| `ProcessInstanceSchema` / `ProcessInstance` | schema / type | platform, boot ID, namespace and process start identity from the shared native reader |
|
|
21889
21986
|
| `probeProcessOwner` / `ProcessOwnerEvidence` | function / type | compare lifetimes on one caller-established machine; matched, boot change, reused PID, gone, legacy or unavailable with cause |
|
|
21987
|
+
|
|
21988
|
+
## `stitchkit/files/packaging`
|
|
21989
|
+
|
|
21990
|
+
`stitchkit/files/packaging` owns `createNativePackaging` and the types
|
|
21991
|
+
`NativePackagingOptions`, `NativePackagingAsset`, `NativePackagingPlugin`, `NativePackagingResult`.
|
|
21992
|
+
It resolves the installed package's target/version and original addon SHA256.
|
|
21993
|
+
`platform`, `architecture`, `delivery`, `entryPath` and `assetPath` are explicit public inputs.
|
|
21994
|
+
The result is `ready` with assets and a structural Bun plugin, or `unsupported`/`missing` with a safe code.
|
|
21995
|
+
Malformed options/metadata and other filesystem errors fail rather than masquerade as missing.
|
|
21996
|
+
Companion mode places an external addon relative to the emitted entry; embedded mode lets
|
|
21997
|
+
Bun compile retain the matching addon. Keep JS builds without splitting, preserve every output,
|
|
21998
|
+
and copy each original asset to its `outputPath` after verifying `sha256`.
|
|
21999
|
+
This evolving entrypoint is a build dependency; runtime imports do not reach it.
|
|
22000
|
+
The detailed recipe is in [native IO](../guide/native-io.md#public-native-packaging).
|
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) 17.
|
|
12
|
+
- **stitchkit**: [llms/stitchkit.txt](llms/stitchkit.txt) 17.6 KB → [llms/stitchkit.2.txt](llms/stitchkit.2.txt) 46.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
|
|
@@ -56,12 +56,13 @@ Load the slice for each entrypoint your code imports — `import … from 'stitc
|
|
|
56
56
|
- **stitchkit/agent-runtime/react**: [llms/agent-runtime-react.txt](llms/agent-runtime-react.txt) 1.0 KB
|
|
57
57
|
- **stitchkit/agent-runtime/realtime**: [llms/agent-runtime-realtime.txt](llms/agent-runtime-realtime.txt) 1.8 KB
|
|
58
58
|
- **stitchkit/agent-runtime/harness-tools**: [llms/agent-runtime-harness-tools.txt](llms/agent-runtime-harness-tools.txt) 1.3 KB
|
|
59
|
-
- **stitchkit/process**: [llms/process.txt](llms/process.txt)
|
|
59
|
+
- **stitchkit/process**: [llms/process.txt](llms/process.txt) 25.4 KB
|
|
60
|
+
- **stitchkit/files/packaging**: [llms/files-packaging.txt](llms/files-packaging.txt) 1.5 KB
|
|
60
61
|
|
|
61
62
|
## Upgrading slices
|
|
62
63
|
- **Upgrading — how to move across versions**: [llms/upgrading.txt](llms/upgrading.txt) 10.3 KB
|
|
63
|
-
- **Upgrading 0.
|
|
64
|
-
- **Upgrading 0.62.0 → 0.
|
|
64
|
+
- **Upgrading 0.81.0 → 0.104.0**: [llms/upgrading-0.81.0-0.104.0.txt](llms/upgrading-0.81.0-0.104.0.txt) 46.8 KB
|
|
65
|
+
- **Upgrading 0.62.0 → 0.80.0**: [llms/upgrading-0.62.0-0.80.0.txt](llms/upgrading-0.62.0-0.80.0.txt) 45.4 KB
|
|
65
66
|
- **Upgrading 0.44.0 → 0.61.0**: [llms/upgrading-0.44.0-0.61.0.txt](llms/upgrading-0.44.0-0.61.0.txt) 41.4 KB
|
|
66
67
|
- **Upgrading 0.37.0 → 0.44.0**: [llms/upgrading-0.37.0-0.44.0.txt](llms/upgrading-0.37.0-0.44.0.txt) 14.7 KB
|
|
67
68
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "stitchkit",
|
|
3
|
-
"version": "0.104.
|
|
3
|
+
"version": "0.104.1",
|
|
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",
|
|
@@ -49,7 +49,8 @@
|
|
|
49
49
|
"llms",
|
|
50
50
|
"README.md",
|
|
51
51
|
"CHANGELOG.md",
|
|
52
|
-
"LICENSE"
|
|
52
|
+
"LICENSE",
|
|
53
|
+
"native-assets.json"
|
|
53
54
|
],
|
|
54
55
|
"imports": {
|
|
55
56
|
"#stitchkit-darwin-native": "./darwin-native.cjs"
|
|
@@ -246,6 +247,10 @@
|
|
|
246
247
|
"./process": {
|
|
247
248
|
"types": "./dist/entrypoints/process.d.ts",
|
|
248
249
|
"import": "./dist/entrypoints/process.js"
|
|
250
|
+
},
|
|
251
|
+
"./files/packaging": {
|
|
252
|
+
"types": "./dist/entrypoints/files/packaging.d.ts",
|
|
253
|
+
"import": "./dist/entrypoints/files/packaging.js"
|
|
249
254
|
}
|
|
250
255
|
},
|
|
251
256
|
"publishConfig": {
|
|
@@ -266,7 +271,7 @@
|
|
|
266
271
|
"consumer-lane": "bun scripts/consumer-lane/run.mjs",
|
|
267
272
|
"bench:mcp-preparation": "bun scripts/benchmark-mcp-preparation.ts",
|
|
268
273
|
"bench:durable-store": "bun scripts/bench-durable-store.ts",
|
|
269
|
-
"build:entrypoints": "bun scripts/build-entrypoints.mjs"
|
|
274
|
+
"build:entrypoints": "bun scripts/generate-native-loader.ts && bun scripts/build-entrypoints.mjs"
|
|
270
275
|
},
|
|
271
276
|
"peerDependencies": {
|
|
272
277
|
"@modelcontextprotocol/ext-apps": "^1.7.2 || ^2.0.0",
|
|
File without changes
|