@kitman-sh/cli 0.0.0-stage → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,13 @@
1
+ // @bun
2
+ import {
3
+ runnerWebSocketProtocol2,
4
+ runnerRpcUrl2,
5
+ makeRunnerRpcClient2
6
+ } from "./chunk-ae7gx971.js";
7
+ import"./chunk-dwgta18y.js";
8
+ import"./chunk-704ws2q7.js";
9
+ export {
10
+ makeRunnerRpcClient2 as makeRunnerRpcClient,
11
+ runnerRpcUrl2 as runnerRpcUrl,
12
+ runnerWebSocketProtocol2 as runnerWebSocketProtocol
13
+ };
@@ -0,0 +1,238 @@
1
+ // @bun
2
+ import {
3
+ isString,
4
+ isTagged,
5
+ all,
6
+ forEach,
7
+ succeed5,
8
+ gen,
9
+ fail4,
10
+ try_,
11
+ flatMap,
12
+ map3,
13
+ catchTags,
14
+ mapError,
15
+ ignore,
16
+ orElseSucceed,
17
+ scoped,
18
+ acquireRelease,
19
+ decodeText,
20
+ mkString,
21
+ FileSystem,
22
+ Path,
23
+ ChildProcessSpawner,
24
+ make11,
25
+ decodeUnknownEffect,
26
+ decodeEffect,
27
+ optionalKey,
28
+ Literal,
29
+ String2,
30
+ Struct,
31
+ Record,
32
+ ArraySchema,
33
+ Union,
34
+ Literals,
35
+ fromJsonString,
36
+ TaggedError2,
37
+ toCodecJson,
38
+ digestSha256,
39
+ AgentDeclaration,
40
+ KitInstallationDeclaration,
41
+ KitAssignmentDeclaration,
42
+ PackageDeclarations,
43
+ RunnerRpcProtocolVersion
44
+ } from "./chunk-704ws2q7.js";
45
+ import"./chunk-dwgta18y.js";
46
+ import"./chunk-ae7gx971.js";
47
+ import"./chunk-ztmwmk8t.js";
48
+ import {
49
+ describeFlag,
50
+ Described
51
+ } from "./chunk-6kdj8psf.js";
52
+
53
+ // packages/sdk/src/build/index.ts
54
+ class DependencyInstallFailed extends TaggedError2()("DependencyInstallFailed", {
55
+ reason: String2
56
+ }) {
57
+ get message() {
58
+ return `Dependencies do not install from the lockfile: ${this.reason}`;
59
+ }
60
+ }
61
+
62
+ class BundleFailed extends TaggedError2()("BundleFailed", { reason: String2 }) {
63
+ get message() {
64
+ return `The Package does not bundle: ${this.reason}`;
65
+ }
66
+ }
67
+
68
+ class DeclarationsInvalid extends TaggedError2()("DeclarationsInvalid", {
69
+ reason: String2
70
+ }) {
71
+ get message() {
72
+ return `The Package's declarations are invalid: ${this.reason}`;
73
+ }
74
+ }
75
+ var RepositoryText = Union([String2, Struct({ file: String2 })]);
76
+ var ConfigAgents = Record(String2, Struct({
77
+ extends: optionalKey(String2),
78
+ instructions: optionalKey(RepositoryText),
79
+ harness: optionalKey(String2),
80
+ model: optionalKey(String2),
81
+ effort: AgentDeclaration.fields.effort,
82
+ kits: optionalKey(ArraySchema(String2)),
83
+ network: optionalKey(Union([Struct({ hosts: ArraySchema(String2) }), Literal("open")])),
84
+ sandbox: optionalKey(Literal("docker"))
85
+ }));
86
+ var ConfigKits = Record(String2, Union([
87
+ KitInstallationDeclaration,
88
+ KitAssignmentDeclaration,
89
+ Struct({
90
+ name: String2,
91
+ kind: optionalKey(Literals(["technology", "brand", "domain", "process", "other"])),
92
+ description: optionalKey(String2),
93
+ context: RepositoryText,
94
+ skills: optionalKey(ArraySchema(String2))
95
+ })
96
+ ]));
97
+ var run = (command, args, cwd) => gen(function* () {
98
+ const spawner = yield* ChildProcessSpawner;
99
+ const handle = yield* spawner.spawn(make11(command, args, { cwd, stdin: "ignore" }));
100
+ const [stdout, stderr, exitCode] = yield* all([
101
+ mkString(decodeText(handle.stdout)),
102
+ mkString(decodeText(handle.stderr)),
103
+ handle.exitCode
104
+ ], { concurrency: 3 });
105
+ return { stdout, stderr, ok: exitCode === 0 };
106
+ }).pipe(scoped);
107
+ var failure = (result) => (result.stderr.trim() || result.stdout.trim()).slice(-2000);
108
+ var provenance = (directory) => gen(function* () {
109
+ const git = (...args) => run("git", args, directory).pipe(map3((result) => result.ok ? result.stdout.trim() : undefined), orElseSucceed(() => {
110
+ return;
111
+ }));
112
+ const repository = yield* git("remote", "get-url", "origin");
113
+ const commit = yield* git("rev-parse", "HEAD");
114
+ const status = yield* git("status", "--porcelain");
115
+ return {
116
+ ...repository ? { repository } : undefined,
117
+ ...commit ? { commit } : undefined,
118
+ clean: commit !== undefined && status === ""
119
+ };
120
+ });
121
+ var inRepository = (directory, file, what) => gen(function* () {
122
+ const path = yield* Path;
123
+ const resolved = path.resolve(directory, file);
124
+ if (path.relative(directory, resolved).startsWith(".."))
125
+ return yield* new DeclarationsInvalid({ reason: `${what} ${file} is outside the repository` });
126
+ return resolved;
127
+ });
128
+ var readText = (directory, text, what) => gen(function* () {
129
+ if (isString(text))
130
+ return text;
131
+ const fs = yield* FileSystem;
132
+ const file = yield* inRepository(directory, text.file, what);
133
+ return yield* fs.readFileString(file).pipe(mapError(() => new DeclarationsInvalid({ reason: `${what} ${text.file} does not read` })));
134
+ });
135
+ var readAgents = (directory, agents) => forEach(Object.entries(agents), ([id, { instructions, ...agent }]) => instructions === undefined ? succeed5([id, agent]) : map3(readText(directory, instructions, `Agent "${id}" instructions`), (text) => [id, { ...agent, instructions: text.trim() }])).pipe(map3(Object.fromEntries));
136
+ var utf8 = new TextDecoder("utf-8", { fatal: true });
137
+ var readSkill = (directory, skill, what) => gen(function* () {
138
+ const fs = yield* FileSystem;
139
+ const path = yield* Path;
140
+ const root = yield* inRepository(directory, skill, what);
141
+ const unreadable = () => new DeclarationsInvalid({ reason: `${what} ${skill} does not read` });
142
+ const entries = yield* fs.readDirectory(root, { recursive: true }).pipe(mapError(unreadable));
143
+ const files = {};
144
+ for (const entry of entries.toSorted()) {
145
+ const file = path.join(root, entry);
146
+ if ((yield* fs.stat(file).pipe(mapError(unreadable))).type !== "File")
147
+ continue;
148
+ const bytes = yield* fs.readFile(file).pipe(mapError(unreadable));
149
+ const text = yield* try_({
150
+ try: () => utf8.decode(bytes),
151
+ catch: () => new DeclarationsInvalid({ reason: `${what} ${skill} holds a binary file, ${entry}` })
152
+ });
153
+ if (text.includes("\x00"))
154
+ return yield* new DeclarationsInvalid({ reason: `${what} ${skill} holds a binary file, ${entry}` });
155
+ files[entry.split(path.sep).join("/")] = text;
156
+ }
157
+ if (files["SKILL.md"] === undefined)
158
+ return yield* new DeclarationsInvalid({ reason: `${what} ${skill} has no SKILL.md` });
159
+ return [path.basename(root), files];
160
+ });
161
+ var readKits = (directory, kits) => forEach(Object.entries(kits), ([key, kit]) => gen(function* () {
162
+ if (!("context" in kit))
163
+ return [key, kit];
164
+ const { context, skills, ...authored } = kit;
165
+ const what = `Kit "${key}"`;
166
+ return [
167
+ key,
168
+ {
169
+ ...authored,
170
+ context: yield* readText(directory, context, `${what} context`),
171
+ ...skills === undefined ? undefined : {
172
+ skills: Object.fromEntries(yield* forEach(skills, (skill) => readSkill(directory, skill, `${what} skill`)))
173
+ }
174
+ }
175
+ ];
176
+ })).pipe(map3(Object.fromEntries));
177
+ var PackageJson = fromJsonString(Struct({ name: String2 }));
178
+ var packageName = (root) => gen(function* () {
179
+ const fs = yield* FileSystem;
180
+ const path = yield* Path;
181
+ return yield* fs.readFileString(path.join(root, "package.json")).pipe(flatMap(decodeEffect(PackageJson)), map3((manifest) => manifest.name), mapError(() => new DeclarationsInvalid({ reason: "package.json has no name" })));
182
+ });
183
+ var duplicateLoopId = (loops) => loops.map((loop) => loop.id).find((id, index, ids) => ids.indexOf(id) !== index);
184
+ var buildPackage = (directory) => gen(function* () {
185
+ const fs = yield* FileSystem;
186
+ const path = yield* Path;
187
+ const root = path.resolve(directory);
188
+ const source = yield* provenance(root);
189
+ const name = yield* packageName(root);
190
+ const installed = yield* run("bun", ["install", "--frozen-lockfile", "--ignore-scripts"], root).pipe(mapError((error) => new DependencyInstallFailed({ reason: error.message })));
191
+ if (!installed.ok)
192
+ return yield* new DependencyInstallFailed({ reason: failure(installed) });
193
+ const entry = path.join(root, ".kitman-build-entry.ts");
194
+ yield* acquireRelease(fs.writeFileString(entry, `import config from './kitman.config.ts'
195
+ import { runPackage } from '@kitman-sh/sdk/program'
196
+
197
+ runPackage(config)
198
+ `), () => ignore(fs.remove(entry)));
199
+ const out = yield* fs.makeTempDirectoryScoped({ prefix: "kitman-package-" });
200
+ const bundleFile = path.join(out, "bundle.js");
201
+ const bundled = yield* run("bun", ["build", entry, "--target=bun", "--format=esm", "--outfile", bundleFile], root);
202
+ if (!bundled.ok)
203
+ return yield* new BundleFailed({ reason: failure(bundled) });
204
+ const described = yield* run("bun", [bundleFile, describeFlag], out);
205
+ if (!described.ok)
206
+ return yield* new BundleFailed({ reason: `the bundle does not load: ${failure(described)}` });
207
+ const result = yield* decodeEffect(fromJsonString(toCodecJson(Described)))(described.stdout).pipe(mapError((error) => new BundleFailed({ reason: `the bundle described itself wrongly: ${error.message}` })));
208
+ if (isTagged(result, "Refused"))
209
+ return yield* result.error;
210
+ const duplicate = duplicateLoopId(result.loops);
211
+ if (duplicate !== undefined)
212
+ return yield* new DeclarationsInvalid({ reason: `Loop "${duplicate}" is declared twice` });
213
+ const agents = yield* decodeUnknownEffect(ConfigAgents)(result.agents).pipe(mapError((error) => new DeclarationsInvalid({ reason: error.message })));
214
+ const kits = result.kits === undefined ? undefined : yield* decodeUnknownEffect(ConfigKits)(result.kits).pipe(mapError((error) => new DeclarationsInvalid({ reason: error.message })));
215
+ const declarations = yield* decodeUnknownEffect(PackageDeclarations)({
216
+ loops: result.loops,
217
+ agents: yield* readAgents(root, agents),
218
+ ...result.schedules === undefined ? undefined : { schedules: result.schedules },
219
+ ...kits === undefined ? undefined : { kits: yield* readKits(root, kits) }
220
+ }).pipe(mapError((error) => new DeclarationsInvalid({ reason: error.message })));
221
+ const bundle = yield* fs.readFile(bundleFile).pipe(mapError((error) => new BundleFailed({ reason: error.message })));
222
+ return {
223
+ name,
224
+ bundle,
225
+ digest: digestSha256(bundle, "hex"),
226
+ declarations,
227
+ protocolVersion: RunnerRpcProtocolVersion,
228
+ provenance: source
229
+ };
230
+ }).pipe(scoped, catchTags({
231
+ PlatformError: (error) => fail4(new BundleFailed({ reason: error.message }))
232
+ }));
233
+ export {
234
+ BundleFailed,
235
+ DeclarationsInvalid,
236
+ DependencyInstallFailed,
237
+ buildPackage
238
+ };