@kitman-sh/cli 0.9.0 → 0.10.53

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/dist/chunk-11p4wf6n.js +3551 -0
  2. package/dist/chunk-1mc9vgcr.js +39 -0
  3. package/dist/chunk-30397r95.js +30 -0
  4. package/dist/chunk-3bj7sc3v.js +389 -0
  5. package/dist/chunk-6vns3ej0.js +23 -0
  6. package/dist/chunk-7thnf14y.js +936 -0
  7. package/dist/chunk-arvwar2c.js +141 -0
  8. package/dist/chunk-b6thzgc9.js +32 -0
  9. package/dist/{chunk-8bvf4fh4.js → chunk-ctasxxz5.js} +26 -11
  10. package/dist/{chunk-5gjpv3ax.js → chunk-dzh9e6n2.js} +824 -651
  11. package/dist/{chunk-snn0e1qb.js → chunk-eg8f5ncv.js} +7 -3
  12. package/dist/chunk-g5bs3f6z.js +173 -0
  13. package/dist/chunk-jafetf7z.js +109 -0
  14. package/dist/chunk-jagzz148.js +527 -0
  15. package/dist/{chunk-1d4316hp.js → chunk-jfvq7s24.js} +38 -25
  16. package/dist/chunk-mbctzx7e.js +11436 -0
  17. package/dist/chunk-mej2bx5n.js +100 -0
  18. package/dist/chunk-p6spvbwq.js +6305 -0
  19. package/dist/chunk-pp1p3g6e.js +133 -0
  20. package/dist/chunk-r8p3nxcp.js +231 -0
  21. package/dist/chunk-txwt6r25.js +1731 -0
  22. package/dist/chunk-v290mf51.js +5242 -0
  23. package/dist/chunk-vjmz23rs.js +13 -0
  24. package/dist/chunk-vyv0p5eq.js +3183 -0
  25. package/dist/chunk-wh1pa2aa.js +15322 -0
  26. package/dist/chunk-x0b92bjb.js +222 -0
  27. package/dist/{chunk-8z5b6fpd.js → chunk-x9dhxfts.js} +216 -152
  28. package/dist/chunk-z821b2gp.js +164 -0
  29. package/dist/index.js +13 -5738
  30. package/dist/opencode-reader.main.ts +4 -0
  31. package/package.json +6 -5
  32. package/dist/chunk-3gxahgnq.js +0 -28495
  33. package/dist/chunk-ehzbtavj.js +0 -247
  34. package/dist/chunk-f5z8tgss.js +0 -1214
  35. package/dist/chunk-kdb1cbnx.js +0 -1273
  36. package/dist/chunk-ke1w0hx7.js +0 -5771
  37. package/dist/chunk-z6hc4ew9.js +0 -13
@@ -0,0 +1,527 @@
1
+ // @bun
2
+ import {
3
+ isString2,
4
+ hasProperty,
5
+ isTagged,
6
+ Reference,
7
+ all3,
8
+ forEach,
9
+ succeed6,
10
+ gen,
11
+ fail7,
12
+ flatMap3,
13
+ map8,
14
+ catchTags,
15
+ mapError2,
16
+ orDie,
17
+ ignore,
18
+ orElseSucceed,
19
+ provide3,
20
+ scoped,
21
+ acquireRelease,
22
+ encode2,
23
+ decodeUnknownEffect2,
24
+ decodeEffect,
25
+ optionalKey,
26
+ String4,
27
+ Struct,
28
+ Record,
29
+ Union,
30
+ fromJsonString,
31
+ TaggedError2,
32
+ toCodecJson,
33
+ Json,
34
+ encodePrettyJsonString
35
+ } from "./chunk-mbctzx7e.js";
36
+ import"./chunk-arvwar2c.js";
37
+ import {
38
+ canonicalJson,
39
+ digestSha256,
40
+ schemaBodyJson,
41
+ filterStatusOk,
42
+ get2,
43
+ layer2,
44
+ kitmanMcpServer,
45
+ RunnerRpcProtocolVersion
46
+ } from "./chunk-wh1pa2aa.js";
47
+ import {
48
+ decodeText,
49
+ mkString,
50
+ FileSystem,
51
+ Path,
52
+ withDefault,
53
+ String2
54
+ } from "./chunk-11p4wf6n.js";
55
+ import {
56
+ Packument,
57
+ tarballMatches
58
+ } from "./chunk-g5bs3f6z.js";
59
+ import"./chunk-pp1p3g6e.js";
60
+ import"./chunk-ctasxxz5.js";
61
+ import {
62
+ AgentDeclaration,
63
+ KitDeclarations
64
+ } from "./chunk-txwt6r25.js";
65
+ import {
66
+ describeFlag,
67
+ Described
68
+ } from "./chunk-jfvq7s24.js";
69
+ import"./chunk-x9dhxfts.js";
70
+ import {
71
+ ChildProcessSpawner,
72
+ make7
73
+ } from "./chunk-3bj7sc3v.js";
74
+ import"./chunk-1mc9vgcr.js";
75
+ import"./chunk-z821b2gp.js";
76
+
77
+ // packages/sdk/src/build/index.ts
78
+ class DependencyInstallFailed extends TaggedError2()("DependencyInstallFailed", {
79
+ reason: String4
80
+ }) {
81
+ get message() {
82
+ return `Dependencies do not install from the lockfile: ${this.reason}`;
83
+ }
84
+ }
85
+
86
+ class BundleFailed extends TaggedError2()("BundleFailed", { reason: String4 }) {
87
+ get message() {
88
+ return `The Kit does not bundle: ${this.reason}`;
89
+ }
90
+ }
91
+
92
+ class DeclarationsInvalid extends TaggedError2()("DeclarationsInvalid", {
93
+ reason: String4
94
+ }) {
95
+ get message() {
96
+ return `The Kit's declarations are invalid: ${this.reason}`;
97
+ }
98
+ }
99
+
100
+ class SourceFetchFailed extends TaggedError2()("SourceFetchFailed", {
101
+ reason: String4
102
+ }) {
103
+ get message() {
104
+ return `A setup source does not fetch: ${this.reason}`;
105
+ }
106
+ }
107
+ var RepositoryText = Union([String4, Struct({ file: String4 })]);
108
+ var ConfigAgents = Record(String4, Struct({
109
+ ...AgentDeclaration.fields,
110
+ instructions: optionalKey(RepositoryText)
111
+ }));
112
+ var run = (command, args, cwd) => gen(function* () {
113
+ const spawner = yield* ChildProcessSpawner;
114
+ const handle = yield* spawner.spawn(make7(command, args, { cwd, stdin: "ignore" }));
115
+ const [stdout, stderr, exitCode] = yield* all3([
116
+ mkString(decodeText(handle.stdout)),
117
+ mkString(decodeText(handle.stderr)),
118
+ handle.exitCode
119
+ ], { concurrency: 3 });
120
+ return { stdout, stderr, ok: exitCode === 0 };
121
+ }).pipe(scoped);
122
+ var failure = (result) => (result.stderr.trim() || result.stdout.trim()).slice(-2000);
123
+ var provenance = (directory) => gen(function* () {
124
+ const git = (...args) => run("git", args, directory).pipe(map8((result) => result.ok ? result.stdout.trim() : undefined), orElseSucceed(() => {
125
+ return;
126
+ }));
127
+ const repository = yield* git("remote", "get-url", "origin");
128
+ const commit = yield* git("rev-parse", "HEAD");
129
+ const status = yield* git("status", "--porcelain");
130
+ return {
131
+ ...repository ? { repository } : undefined,
132
+ ...commit ? { commit } : undefined,
133
+ clean: commit !== undefined && status === ""
134
+ };
135
+ });
136
+ var inKit = (directory, file, what) => gen(function* () {
137
+ const path = yield* Path;
138
+ const resolved = path.resolve(directory, file);
139
+ if (path.relative(directory, resolved).startsWith(".."))
140
+ return yield* new DeclarationsInvalid({ reason: `${what} ${file} is outside the Kit` });
141
+ return resolved;
142
+ });
143
+ var readText = (directory, text, what) => gen(function* () {
144
+ if (isString2(text))
145
+ return text;
146
+ const fs = yield* FileSystem;
147
+ const file = yield* inKit(directory, text.file, what);
148
+ return yield* fs.readFileString(file).pipe(mapError2(() => new DeclarationsInvalid({ reason: `${what} ${text.file} does not read` })));
149
+ });
150
+ var readAgents = (directory, agents) => forEach(Object.entries(agents), ([id, { instructions, ...agent }]) => instructions === undefined ? succeed6([id, agent]) : map8(readText(directory, instructions, `Agent "${id}" instructions`), (text) => [id, { ...agent, instructions: text.trim() }])).pipe(map8(Object.fromEntries));
151
+ var utf8 = new TextDecoder("utf-8", { fatal: true });
152
+ var setupFile = (bytes) => {
153
+ try {
154
+ const text = utf8.decode(bytes);
155
+ return text.includes("\x00") ? { base64: encode2(bytes) } : { utf8: text };
156
+ } catch {
157
+ return { base64: encode2(bytes) };
158
+ }
159
+ };
160
+ var confined = (boundary, file, what) => gen(function* () {
161
+ const fs = yield* FileSystem;
162
+ const path = yield* Path;
163
+ const unreadable = () => new DeclarationsInvalid({ reason: `${what} does not read` });
164
+ const real = yield* fs.realPath(path.join(boundary, file)).pipe(mapError2(unreadable));
165
+ if (path.relative(yield* fs.realPath(boundary).pipe(mapError2(unreadable)), real).startsWith(".."))
166
+ return yield* new DeclarationsInvalid({ reason: `${what}: ${file} links outside its source` });
167
+ return real;
168
+ });
169
+ var readTree = (root, what, fetched = false) => gen(function* () {
170
+ const fs = yield* FileSystem;
171
+ const path = yield* Path;
172
+ const unreadable = () => new DeclarationsInvalid({ reason: `${what} does not read` });
173
+ const entries = yield* fs.readDirectory(root, { recursive: true }).pipe(mapError2(unreadable));
174
+ const files = {};
175
+ for (const entry of entries.toSorted()) {
176
+ const relative = entry.split(path.sep).join("/");
177
+ if (relative === ".git" || relative.startsWith(".git/"))
178
+ continue;
179
+ const file = fetched ? yield* confined(root, entry, what) : path.join(root, entry);
180
+ if ((yield* fs.stat(file).pipe(mapError2(unreadable))).type !== "File")
181
+ continue;
182
+ files[relative] = yield* fs.readFile(file).pipe(mapError2(unreadable));
183
+ }
184
+ return files;
185
+ });
186
+ var licenseFiles = ["LICENSE", "LICENSE.md", "LICENSE.txt", "COPYING"];
187
+ var fetchedTree = (root, path, what) => gen(function* () {
188
+ const fs = yield* FileSystem;
189
+ const paths = yield* Path;
190
+ const tree = yield* readTree(path === undefined ? root : yield* confined(root, path, what), what, true);
191
+ if (path === undefined)
192
+ return tree;
193
+ for (const license of licenseFiles)
194
+ if (tree[license] === undefined && (yield* fs.exists(paths.join(root, license))))
195
+ return { ...tree, [license]: yield* fs.readFile(yield* confined(root, license, what)).pipe(orDie) };
196
+ return tree;
197
+ });
198
+ var GitSourceLocation = Reference("kitman/sdk/build/GitSourceLocation", { defaultValue: () => (declared) => declared });
199
+ var fetchGit = (declared, what) => gen(function* () {
200
+ const fs = yield* FileSystem;
201
+ const { url, ref } = (yield* GitSourceLocation)(declared);
202
+ const checkout = yield* fs.makeTempDirectoryScoped({ prefix: "kitman-git-" });
203
+ for (const args of [
204
+ ["init", "--quiet"],
205
+ ["fetch", "--quiet", "--depth", "1", "--", url, ref ?? "HEAD"],
206
+ ["checkout", "--quiet", "FETCH_HEAD"]
207
+ ]) {
208
+ const result = yield* run("git", args, checkout);
209
+ if (!result.ok)
210
+ return yield* new SourceFetchFailed({
211
+ reason: `${what}: git ${url}${ref === undefined ? "" : ` at ${ref}`}: ${failure(result)}`
212
+ });
213
+ }
214
+ return checkout;
215
+ });
216
+ var fetchNpm = (name, wanted, what) => gen(function* () {
217
+ const fs = yield* FileSystem;
218
+ const path = yield* Path;
219
+ const registry = yield* String2("NPM_CONFIG_REGISTRY").pipe(withDefault("https://registry.npmjs.org"), orDie);
220
+ const failed = (reason) => new SourceFetchFailed({ reason: `${what}: npm ${name}@${wanted}: ${reason}` });
221
+ const packument = yield* get2(`${registry.replace(/\/+$/, "")}/${name.replace("/", "%2F")}`).pipe(flatMap3(filterStatusOk), flatMap3(schemaBodyJson(Packument)), mapError2((error) => failed(error.message)));
222
+ const dist = packument.versions[packument["dist-tags"][wanted] ?? wanted]?.dist;
223
+ if (dist === undefined)
224
+ return yield* failed("npm has no such version or dist-tag");
225
+ const tarball = yield* get2(dist.tarball).pipe(flatMap3(filterStatusOk), flatMap3((response) => response.arrayBuffer), map8((buffer) => new Uint8Array(buffer)), mapError2((error) => failed(error.message)));
226
+ if (!tarballMatches(tarball, dist))
227
+ return yield* failed(`the tarball does not match its integrity ${dist.integrity ?? `sha1 ${dist.shasum}`}`);
228
+ const directory = yield* fs.makeTempDirectoryScoped({ prefix: "kitman-npm-" });
229
+ yield* fs.writeFile(path.join(directory, "package.tgz"), tarball).pipe(orDie);
230
+ const extracted = yield* run("tar", ["-xzf", "package.tgz"], directory);
231
+ if (!extracted.ok)
232
+ return yield* failed(`the tarball does not extract: ${failure(extracted)}`);
233
+ return yield* confined(directory, "package", what);
234
+ }).pipe(provide3(layer2));
235
+ var sourceTree = (directory, source, what, checkouts) => gen(function* () {
236
+ switch (source.kind) {
237
+ case "local_path":
238
+ return yield* readTree(yield* inKit(directory, source.path, what), what);
239
+ case "git": {
240
+ const key = `${source.url}#${source.ref ?? ""}`;
241
+ const checkout = checkouts.get(key) ?? (yield* fetchGit({ url: source.url, ref: source.ref }, what));
242
+ checkouts.set(key, checkout);
243
+ return yield* fetchedTree(checkout, "path" in source ? source.path : undefined, what);
244
+ }
245
+ case "package":
246
+ return yield* fetchedTree(yield* fetchNpm(source.packageName, source.version ?? "latest", what), "path" in source ? source.path : undefined, what);
247
+ default:
248
+ return yield* new DeclarationsInvalid({
249
+ reason: `${what} comes from a ${source.kind} source, which a build cannot copy in; use a local path, git or npm`
250
+ });
251
+ }
252
+ });
253
+ var setupArchive = (directory, kit, setup, checkouts) => gen(function* () {
254
+ const fs = yield* FileSystem;
255
+ const files = {};
256
+ const place = (prefix, tree) => {
257
+ for (const [file, bytes] of Object.entries(tree))
258
+ files[`${prefix}/${file}`] = setupFile(bytes);
259
+ return { kind: "local_path", path: prefix };
260
+ };
261
+ if (setup.instructions !== undefined) {
262
+ const what = `Kit ${kit} instructions`;
263
+ const file = yield* inKit(directory, setup.instructions, what);
264
+ files["instructions.md"] = setupFile(yield* fs.readFile(file).pipe(mapError2(() => new DeclarationsInvalid({ reason: `${what} do not read` }))));
265
+ }
266
+ const skills = setup.skills === undefined ? undefined : yield* forEach(setup.skills, (skill) => map8(sourceTree(directory, skill.source, `Kit ${kit} skill ${skill.name}`, checkouts), (tree) => ({
267
+ ...skill,
268
+ source: place(`skills/${skill.name}`, tree)
269
+ })));
270
+ const plugins = setup.plugins === undefined ? undefined : yield* forEach(setup.plugins, (plugin) => map8(sourceTree(directory, plugin.sources[0], `Kit ${kit} plugin ${plugin.name}`, checkouts), (tree) => ({
271
+ ...plugin,
272
+ sources: [place(`plugins/${plugin.name}`, tree)]
273
+ })));
274
+ const archive = {
275
+ setup: {
276
+ ...setup,
277
+ ...setup.instructions === undefined ? undefined : { instructions: "instructions.md" },
278
+ ...skills === undefined ? undefined : { skills },
279
+ ...plugins === undefined ? undefined : { plugins }
280
+ },
281
+ files
282
+ };
283
+ const bytes = new TextEncoder().encode(canonicalJson(archive));
284
+ return { digest: digestSha256(bytes, "hex"), archive: bytes };
285
+ });
286
+ var PackageJson = fromJsonString(Struct({
287
+ name: String4,
288
+ version: optionalKey(String4),
289
+ dependencies: optionalKey(Record(String4, String4))
290
+ }));
291
+ var readPackageJson = (directory) => gen(function* () {
292
+ const fs = yield* FileSystem;
293
+ const path = yield* Path;
294
+ return yield* fs.readFileString(path.join(directory, "package.json")).pipe(flatMap3(decodeEffect(PackageJson)), mapError2(() => new DeclarationsInvalid({ reason: `${directory}/package.json has no name` })));
295
+ });
296
+ var identityOf = (manifest) => ({
297
+ name: manifest.name,
298
+ version: manifest.version ?? "0.0.0"
299
+ });
300
+ var installedPackage = (name, directory) => gen(function* () {
301
+ const fs = yield* FileSystem;
302
+ const path = yield* Path;
303
+ for (let at = directory;; at = path.dirname(at)) {
304
+ const candidate = path.join(at, "node_modules", name);
305
+ if (yield* fs.exists(path.join(candidate, "package.json")))
306
+ return yield* fs.realPath(candidate);
307
+ if (path.dirname(at) === at)
308
+ return;
309
+ }
310
+ });
311
+ var importedFile = (file, specifier) => gen(function* () {
312
+ const fs = yield* FileSystem;
313
+ const path = yield* Path;
314
+ const target = path.resolve(path.dirname(file), specifier);
315
+ for (const candidate of [target, `${target}.ts`, path.join(target, "kitman.config.ts")])
316
+ if (yield* fs.stat(candidate).pipe(map8((info) => info.type === "File"), orElseSucceed(() => false)))
317
+ return candidate;
318
+ return;
319
+ });
320
+ var packageDirectory = (file) => gen(function* () {
321
+ const fs = yield* FileSystem;
322
+ const path = yield* Path;
323
+ for (let at = path.dirname(file);; at = path.dirname(at)) {
324
+ if (yield* fs.exists(path.join(at, "package.json")).pipe(orElseSucceed(() => false)))
325
+ return at;
326
+ if (path.dirname(at) === at)
327
+ return;
328
+ }
329
+ });
330
+ var kitModules = (root) => gen(function* () {
331
+ const fs = yield* FileSystem;
332
+ const path = yield* Path;
333
+ const found = [];
334
+ const visited = new Set;
335
+ const packages = new Set([root]);
336
+ const known = (directory) => packages.has(directory);
337
+ const visitPackage = (directory) => gen(function* () {
338
+ for (const name of Object.keys((yield* readPackageJson(directory)).dependencies ?? {})) {
339
+ const installed = yield* installedPackage(name, directory).pipe(orElseSucceed(() => {
340
+ return;
341
+ }));
342
+ const module = installed === undefined ? undefined : path.join(installed, "kitman.config.ts");
343
+ if (installed === undefined || module === undefined || known(installed))
344
+ continue;
345
+ if (!(yield* fs.exists(module).pipe(orElseSucceed(() => false))))
346
+ continue;
347
+ packages.add(installed);
348
+ found.push({ directory: installed, module, identity: identityOf(yield* readPackageJson(installed)) });
349
+ yield* visitPackage(installed);
350
+ yield* visitImports(module);
351
+ }
352
+ });
353
+ const visitImports = (file) => gen(function* () {
354
+ if (visited.has(file))
355
+ return;
356
+ visited.add(file);
357
+ const transpiled = yield* run("bun", ["build", "--no-bundle", file], root).pipe(map8((result) => result.ok ? result.stdout : ""), orElseSucceed(() => ""));
358
+ for (const [, specifier] of transpiled.matchAll(/\b(?:from|import)\s*"(\.{1,2}\/[^"]+)"/gu)) {
359
+ const module = specifier === undefined ? undefined : yield* importedFile(file, specifier);
360
+ if (module === undefined || visited.has(module))
361
+ continue;
362
+ const directory = yield* packageDirectory(module);
363
+ if (directory !== undefined && directory !== root) {
364
+ found.push({ directory, module, identity: identityOf(yield* readPackageJson(directory)) });
365
+ if (!known(directory)) {
366
+ packages.add(directory);
367
+ yield* visitPackage(directory);
368
+ }
369
+ }
370
+ yield* visitImports(module);
371
+ }
372
+ });
373
+ yield* visitPackage(root);
374
+ yield* visitImports(path.join(root, "kitman.config.ts"));
375
+ return found;
376
+ });
377
+ var buildEntry = (identity, modules) => [
378
+ "import config from './kitman.config.ts'",
379
+ "import { runKit } from '@kitman-sh/sdk/program'",
380
+ ...modules.map((kit, index) => `import * as kit${index} from ${JSON.stringify(kit.module)}`),
381
+ "",
382
+ `runKit(config, ${JSON.stringify(identity)}, [${modules.map((kit, index) => `[kit${index}.default, ${JSON.stringify(kit.identity)}]`).join(", ")}])`,
383
+ ""
384
+ ].join(`
385
+ `);
386
+ var renamedKey = (declarations, what, from, to) => {
387
+ const key = Object.keys(declarations ?? {}).find((key) => hasProperty(declarations?.[key], from));
388
+ return key === undefined ? undefined : new DeclarationsInvalid({ reason: `${what} "${key}" names \`${from}\`, which is now \`${to}\`` });
389
+ };
390
+ var resolveNames = (names) => {
391
+ const winners = new Map;
392
+ const overrides = [];
393
+ for (const named of names) {
394
+ const key = `${named.what}\x00${named.name}`;
395
+ const winner = winners.get(key);
396
+ if (winner === undefined)
397
+ winners.set(key, named.kit);
398
+ else if (winner === named.kit)
399
+ return new DeclarationsInvalid({ reason: `Kit ${named.kit} names ${named.what} ${named.name} twice` });
400
+ else
401
+ overrides.push({ what: named.what, name: named.name, winner, replaced: named.kit });
402
+ }
403
+ return { wins: (named) => winners.get(`${named.what}\x00${named.name}`) === named.kit, overrides };
404
+ };
405
+ var buildKit = (directory, options = {}) => gen(function* () {
406
+ const fs = yield* FileSystem;
407
+ const path = yield* Path;
408
+ const root = path.resolve(directory);
409
+ const source = yield* provenance(root);
410
+ const identity = { ...identityOf(yield* readPackageJson(root)), ...options };
411
+ const installed = yield* run("bun", ["install", "--frozen-lockfile", "--ignore-scripts"], root).pipe(mapError2((error) => new DependencyInstallFailed({ reason: error.message })));
412
+ if (!installed.ok)
413
+ return yield* new DependencyInstallFailed({ reason: failure(installed) });
414
+ const packages = yield* kitModules(root);
415
+ const entry = path.join(root, ".kitman-build-entry.ts");
416
+ yield* acquireRelease(fs.writeFileString(entry, buildEntry(identity, packages)), () => ignore(fs.remove(entry)));
417
+ const out = yield* fs.makeTempDirectoryScoped({ prefix: "kitman-kit-" });
418
+ const bundleFile = path.join(out, "bundle.js");
419
+ const bundled = yield* run("bun", ["build", entry, "--target=bun", "--format=esm", "--outfile", bundleFile], root);
420
+ if (!bundled.ok)
421
+ return yield* failure(bundled).includes('"defineConfig"') ? new DeclarationsInvalid({
422
+ reason: "defineConfig is now defineKit; import defineKit from @kitman-sh/sdk/loop"
423
+ }) : new BundleFailed({ reason: failure(bundled) });
424
+ const described = yield* run("bun", [bundleFile, describeFlag], out);
425
+ if (!described.ok)
426
+ return yield* new BundleFailed({ reason: `the bundle does not load: ${failure(described)}` });
427
+ const result = yield* decodeEffect(fromJsonString(toCodecJson(Described)))(described.stdout).pipe(mapError2((error) => new BundleFailed({ reason: `the bundle described itself wrongly: ${error.message}` })));
428
+ if (isTagged(result, "Refused"))
429
+ return yield* result.error;
430
+ const [own] = result.kits;
431
+ if (own === undefined)
432
+ return yield* new BundleFailed({ reason: "the bundle described no Kit" });
433
+ const renamed = renamedKey(own.schedules, "Schedule", "project", "team") ?? renamedKey(own.schedules, "Schedule", "codebase", "team");
434
+ if (renamed !== undefined)
435
+ return yield* renamed;
436
+ const directories = new Map([
437
+ [`${identity.name}@${identity.version}`, root],
438
+ ...packages.map((kit) => [`${kit.identity.name}@${kit.identity.version}`, kit.directory])
439
+ ]);
440
+ const kits = yield* forEach(result.kits, (kit) => gen(function* () {
441
+ const at = directories.get(`${kit.name}@${kit.version}`) ?? root;
442
+ const invalid = (error) => new DeclarationsInvalid({ reason: `Kit ${kit.name}: ${error.message}` });
443
+ const agents = yield* decodeUnknownEffect2(ConfigAgents)(kit.agents).pipe(mapError2(invalid));
444
+ return { ...kit, directory: at, agents: yield* readAgents(at, agents), setup: kit.setup ?? {} };
445
+ }));
446
+ const named = kits.flatMap((kit) => [
447
+ ...kit.loops.map((loop) => ({ kit: kit.name, what: "Loop", name: loop.id })),
448
+ ...Object.keys(kit.agents).map((agent) => ({ kit: kit.name, what: "Agent", name: agent })),
449
+ ...(kit.setup.skills ?? []).map((skill) => ({ kit: kit.name, what: "skill", name: skill.name })),
450
+ ...(kit.setup.plugins ?? []).map((plugin) => ({ kit: kit.name, what: "plugin", name: plugin.name })),
451
+ ...(kit.setup.mcpServers ?? []).map((server) => ({ kit: kit.name, what: "MCP server", name: server.name }))
452
+ ]);
453
+ const kitman = named.find((entry) => entry.what === "MCP server" && entry.name === kitmanMcpServer);
454
+ if (kitman !== undefined)
455
+ return yield* new DeclarationsInvalid({
456
+ reason: `Kit ${kitman.kit} declares an MCP server named ${kitmanMcpServer}, which Kitman provides`
457
+ });
458
+ const names = resolveNames(named);
459
+ if (isTagged(names, "DeclarationsInvalid"))
460
+ return yield* names;
461
+ const winning = kits.map((kit) => ({
462
+ ...kit,
463
+ loops: kit.loops.filter((loop) => names.wins({ kit: kit.name, what: "Loop", name: loop.id })),
464
+ agents: Object.fromEntries(Object.entries(kit.agents).filter(([agent]) => names.wins({ kit: kit.name, what: "Agent", name: agent })))
465
+ }));
466
+ const checkouts = new Map;
467
+ const archives = yield* forEach(kits, (kit) => setupArchive(kit.directory, kit.name, kit.setup, checkouts));
468
+ const carried = winning.map((kit, index) => ({
469
+ name: kit.name,
470
+ version: kit.version,
471
+ setup: archives[index]?.digest ?? "",
472
+ loops: kit.loops.map((loop) => loop.id),
473
+ agents: Object.keys(kit.agents)
474
+ }));
475
+ const declarations = yield* decodeUnknownEffect2(KitDeclarations)({
476
+ loops: winning.flatMap((kit) => kit.loops),
477
+ agents: Object.assign({}, ...winning.map((kit) => kit.agents)),
478
+ ...own.schedules === undefined ? undefined : { schedules: own.schedules },
479
+ carried
480
+ }).pipe(mapError2((error) => new DeclarationsInvalid({ reason: error.message })));
481
+ const bundle = yield* fs.readFile(bundleFile).pipe(mapError2((error) => new BundleFailed({ reason: error.message })));
482
+ return {
483
+ ...identity,
484
+ bundle,
485
+ digest: digestSha256(bundle, "hex"),
486
+ declarations,
487
+ setupArchives: archives,
488
+ protocolVersion: RunnerRpcProtocolVersion,
489
+ provenance: source,
490
+ overrides: names.overrides
491
+ };
492
+ }).pipe(scoped, catchTags({
493
+ PlatformError: (error) => fail7(new BundleFailed({ reason: error.message }))
494
+ }));
495
+ var writeKit = (directory, built, out) => gen(function* () {
496
+ const fs = yield* FileSystem;
497
+ const path = yield* Path;
498
+ const inKit = (file) => path.relative(directory, path.join(out, file));
499
+ const setup = {};
500
+ yield* fs.makeDirectory(path.join(out, "setup"), { recursive: true });
501
+ yield* fs.writeFile(path.join(out, "bundle.js"), built.bundle);
502
+ yield* fs.writeFileString(path.join(out, "declarations.json"), yield* encodePrettyJsonString(built.declarations));
503
+ for (const { digest, archive } of built.setupArchives) {
504
+ yield* fs.writeFile(path.join(out, "setup", `${digest}.json`), archive);
505
+ setup[digest] = inKit(`setup/${digest}.json`);
506
+ }
507
+ const manifestPath = path.join(directory, "package.json");
508
+ const manifest = yield* fs.readFileString(manifestPath).pipe(flatMap3(decodeEffect(fromJsonString(Record(String4, Json)))));
509
+ const kitman = {
510
+ bundle: inKit("bundle.js"),
511
+ digest: built.digest,
512
+ protocolVersion: built.protocolVersion,
513
+ declarations: inKit("declarations.json"),
514
+ setup
515
+ };
516
+ yield* fs.writeFileString(manifestPath, `${yield* encodePrettyJsonString({ ...manifest, kitman })}
517
+ `);
518
+ });
519
+ export {
520
+ BundleFailed,
521
+ DeclarationsInvalid,
522
+ DependencyInstallFailed,
523
+ GitSourceLocation,
524
+ SourceFetchFailed,
525
+ buildKit,
526
+ writeKit
527
+ };
@@ -2,21 +2,20 @@
2
2
  import {
3
3
  getOrElse,
4
4
  TaggedError,
5
- currentTimeMillis,
6
5
  forEach,
7
6
  tryPromise,
8
- sync,
7
+ sync2,
9
8
  gen,
10
- flatMap2,
11
- andThen,
12
- map3,
9
+ flatMap3,
10
+ andThen2,
11
+ map8,
13
12
  scoped,
14
- runForEach,
15
- FileSystem,
13
+ makeFormatterStandardSchemaV1,
16
14
  is,
17
15
  encodeEffect,
18
16
  optionalKey,
19
- String2,
17
+ String4,
18
+ Struct,
20
19
  Record,
21
20
  ArraySchema,
22
21
  Union,
@@ -24,8 +23,10 @@ import {
24
23
  fromJsonString,
25
24
  TaggedError2,
26
25
  toCodecJson,
27
- Json,
28
- guard,
26
+ Json
27
+ } from "./chunk-mbctzx7e.js";
28
+ import {
29
+ currentTimeMillis,
29
30
  ProgramWorkUnit,
30
31
  RunFileRefused,
31
32
  runFileContentType,
@@ -35,15 +36,23 @@ import {
35
36
  bodyUint8Array,
36
37
  filterStatusOk,
37
38
  HttpClient,
39
+ KitSetup,
38
40
  RunnerRpcError
39
- } from "./chunk-3gxahgnq.js";
41
+ } from "./chunk-wh1pa2aa.js";
42
+ import {
43
+ guard
44
+ } from "./chunk-pp1p3g6e.js";
45
+ import {
46
+ runForEach,
47
+ FileSystem
48
+ } from "./chunk-11p4wf6n.js";
40
49
  import {
41
50
  LoopManifest,
42
51
  ManifestInvalid,
43
- make,
52
+ make14,
44
53
  Suspended,
45
54
  LoopCheckError
46
- } from "./chunk-kdb1cbnx.js";
55
+ } from "./chunk-txwt6r25.js";
47
56
 
48
57
  // packages/sdk/src/program/engine.ts
49
58
  class JournalWriteFailed extends TaggedError("JournalWriteFailed") {
@@ -51,12 +60,13 @@ class JournalWriteFailed extends TaggedError("JournalWriteFailed") {
51
60
  return `Journal write failed: ${this.cause.message}`;
52
61
  }
53
62
  }
54
- var JournalEntries = Record(String2, Json);
63
+ var JournalEntries = Record(String4, Json);
55
64
  var isSuspended = is(Suspended);
56
- var emptyWorkflow = make("kitman-loop/none", { payload: {}, idempotencyKey: () => "none" });
65
+ var emptyWorkflow = make14("kitman-loop/none", { payload: {}, idempotencyKey: () => "none" });
57
66
  var replayStatuses = new Set([401, 403, 409, 429]);
58
67
  var isRunnerRpcError = is(RunnerRpcError);
59
68
  var isRunFileRefused = is(RunFileRefused);
69
+ var issues = makeFormatterStandardSchemaV1();
60
70
  var put2 = (target, contentType, body) => gen(function* () {
61
71
  const response = yield* (yield* HttpClient).execute(put(target.url).pipe(bodyUint8Array(body, contentType), setHeaders(target.headers ?? {})));
62
72
  return (yield* filterStatusOk(response)).headers.etag ?? "";
@@ -77,7 +87,7 @@ var uploadRunFile = (files, file) => gen(function* () {
77
87
  const contentType = runFileContentType(file.name);
78
88
  const byteSize = Number((yield* fs.stat(file.path)).size);
79
89
  const hash = sha256Hasher();
80
- yield* runForEach(fs.stream(file.path), (chunk) => sync(() => hash.update(chunk)));
90
+ yield* runForEach(fs.stream(file.path), (chunk) => sync2(() => hash.update(chunk)));
81
91
  const { file: slotted, upload } = yield* files.createRunFile({
82
92
  step: file.step,
83
93
  name: file.name,
@@ -88,7 +98,7 @@ var uploadRunFile = (files, file) => gen(function* () {
88
98
  });
89
99
  if (upload === undefined)
90
100
  return slotted;
91
- return yield* upload.kind === "single" ? readRange(file.path, 0, byteSize).pipe(flatMap2((body) => put2(upload, contentType, body)), andThen(files.completeRunFile({ fileId: slotted.id }))) : flatMap2(uploadParts(files, file.path, contentType, slotted.id, upload), (parts) => files.completeRunFile({ fileId: slotted.id, parts }));
101
+ return yield* upload.kind === "single" ? readRange(file.path, 0, byteSize).pipe(flatMap3((body) => put2(upload, contentType, body)), andThen2(files.completeRunFile({ fileId: slotted.id }))) : flatMap3(uploadParts(files, file.path, contentType, slotted.id, upload), (parts) => files.completeRunFile({ fileId: slotted.id, parts }));
92
102
  });
93
103
  var programLease = (work) => ({
94
104
  workUnitId: work.id,
@@ -101,24 +111,27 @@ var programLease = (work) => ({
101
111
  });
102
112
  var rpcRunFiles = (rpc, lease) => ({
103
113
  createRunFile: (file) => rpc.createRunFile({ lease, ...file }),
104
- runFileParts: (request) => map3(rpc.runFileParts({ lease, ...request, partNumbers: [...request.partNumbers] }), ({ parts }) => parts),
114
+ runFileParts: (request) => map8(rpc.runFileParts({ lease, ...request, partNumbers: [...request.partNumbers] }), ({ parts }) => parts),
105
115
  completeRunFile: ({ parts, ...request }) => rpc.completeRunFile({ lease, ...request, ...parts === undefined ? undefined : { parts: [...parts] } })
106
116
  });
107
117
 
108
118
  // packages/sdk/src/program/host.ts
109
119
  var describeFlag = "--kitman-describe";
120
+ var DescribedKit = Struct({
121
+ name: String4,
122
+ version: String4,
123
+ loops: ArraySchema(LoopManifest),
124
+ agents: Record(String4, Json),
125
+ schedules: optionalKey(Record(String4, Json)),
126
+ setup: optionalKey(KitSetup)
127
+ });
110
128
  var Described = Union([
111
- TaggedStruct("Described", {
112
- loops: ArraySchema(LoopManifest),
113
- agents: Record(String2, Json),
114
- schedules: optionalKey(Record(String2, Json)),
115
- kits: optionalKey(Record(String2, Json))
116
- }),
129
+ TaggedStruct("Described", { kits: ArraySchema(DescribedKit) }),
117
130
  TaggedStruct("Refused", { error: Union([ManifestInvalid, LoopCheckError]) })
118
131
  ]);
119
132
  var encodeDescribed = encodeEffect(fromJsonString(toCodecJson(Described)));
120
133
 
121
- class ProgramRefused extends TaggedError2()("ProgramRefused", { reason: String2 }) {
134
+ class ProgramRefused extends TaggedError2()("ProgramRefused", { reason: String4 }) {
122
135
  get message() {
123
136
  return this.reason;
124
137
  }