@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.
- package/dist/chunk-11p4wf6n.js +3551 -0
- package/dist/chunk-1mc9vgcr.js +39 -0
- package/dist/chunk-30397r95.js +30 -0
- package/dist/chunk-3bj7sc3v.js +389 -0
- package/dist/chunk-6vns3ej0.js +23 -0
- package/dist/chunk-7thnf14y.js +936 -0
- package/dist/chunk-arvwar2c.js +141 -0
- package/dist/chunk-b6thzgc9.js +32 -0
- package/dist/{chunk-8bvf4fh4.js → chunk-ctasxxz5.js} +26 -11
- package/dist/{chunk-5gjpv3ax.js → chunk-dzh9e6n2.js} +824 -651
- package/dist/{chunk-snn0e1qb.js → chunk-eg8f5ncv.js} +7 -3
- package/dist/chunk-g5bs3f6z.js +173 -0
- package/dist/chunk-jafetf7z.js +109 -0
- package/dist/chunk-jagzz148.js +527 -0
- package/dist/{chunk-1d4316hp.js → chunk-jfvq7s24.js} +38 -25
- package/dist/chunk-mbctzx7e.js +11436 -0
- package/dist/chunk-mej2bx5n.js +100 -0
- package/dist/chunk-p6spvbwq.js +6305 -0
- package/dist/chunk-pp1p3g6e.js +133 -0
- package/dist/chunk-r8p3nxcp.js +231 -0
- package/dist/chunk-txwt6r25.js +1731 -0
- package/dist/chunk-v290mf51.js +5242 -0
- package/dist/chunk-vjmz23rs.js +13 -0
- package/dist/chunk-vyv0p5eq.js +3183 -0
- package/dist/chunk-wh1pa2aa.js +15322 -0
- package/dist/chunk-x0b92bjb.js +222 -0
- package/dist/{chunk-8z5b6fpd.js → chunk-x9dhxfts.js} +216 -152
- package/dist/chunk-z821b2gp.js +164 -0
- package/dist/index.js +13 -5738
- package/dist/opencode-reader.main.ts +4 -0
- package/package.json +6 -5
- package/dist/chunk-3gxahgnq.js +0 -28495
- package/dist/chunk-ehzbtavj.js +0 -247
- package/dist/chunk-f5z8tgss.js +0 -1214
- package/dist/chunk-kdb1cbnx.js +0 -1273
- package/dist/chunk-ke1w0hx7.js +0 -5771
- package/dist/chunk-z6hc4ew9.js +0 -13
|
@@ -4,9 +4,13 @@ import {
|
|
|
4
4
|
runnerRpcUrl2,
|
|
5
5
|
makeRunnerRpcClient2,
|
|
6
6
|
makeProgramRpcClient2
|
|
7
|
-
} from "./chunk-
|
|
8
|
-
import"./chunk-
|
|
9
|
-
import"./chunk-
|
|
7
|
+
} from "./chunk-ctasxxz5.js";
|
|
8
|
+
import"./chunk-x9dhxfts.js";
|
|
9
|
+
import"./chunk-wh1pa2aa.js";
|
|
10
|
+
import"./chunk-11p4wf6n.js";
|
|
11
|
+
import"./chunk-pp1p3g6e.js";
|
|
12
|
+
import"./chunk-arvwar2c.js";
|
|
13
|
+
import"./chunk-mbctzx7e.js";
|
|
10
14
|
export {
|
|
11
15
|
makeProgramRpcClient2 as makeProgramRpcClient,
|
|
12
16
|
makeRunnerRpcClient2 as makeRunnerRpcClient,
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import {
|
|
3
|
+
isString2,
|
|
4
|
+
isNone,
|
|
5
|
+
match,
|
|
6
|
+
fromUndefinedOr,
|
|
7
|
+
flatMap,
|
|
8
|
+
Reference,
|
|
9
|
+
TaggedError,
|
|
10
|
+
tryPromise,
|
|
11
|
+
succeed6,
|
|
12
|
+
gen,
|
|
13
|
+
fail7,
|
|
14
|
+
flatMap3,
|
|
15
|
+
map8,
|
|
16
|
+
mapError2,
|
|
17
|
+
orDie,
|
|
18
|
+
provide3,
|
|
19
|
+
decodeUnknownOption,
|
|
20
|
+
optionalKey,
|
|
21
|
+
Unknown,
|
|
22
|
+
String4,
|
|
23
|
+
Struct,
|
|
24
|
+
Record,
|
|
25
|
+
Int,
|
|
26
|
+
fromJsonString
|
|
27
|
+
} from "./chunk-mbctzx7e.js";
|
|
28
|
+
import {
|
|
29
|
+
withDefault,
|
|
30
|
+
String2
|
|
31
|
+
} from "./chunk-11p4wf6n.js";
|
|
32
|
+
import {
|
|
33
|
+
digestSha256,
|
|
34
|
+
digestSha512,
|
|
35
|
+
digestWith,
|
|
36
|
+
schemaBodyJson,
|
|
37
|
+
filterStatusOk,
|
|
38
|
+
get2,
|
|
39
|
+
layer2
|
|
40
|
+
} from "./chunk-wh1pa2aa.js";
|
|
41
|
+
import {
|
|
42
|
+
KitDigest
|
|
43
|
+
} from "./chunk-z821b2gp.js";
|
|
44
|
+
|
|
45
|
+
// packages/core/src/npm-registry.ts
|
|
46
|
+
var KitManifest = Struct({
|
|
47
|
+
bundle: String4,
|
|
48
|
+
digest: KitDigest,
|
|
49
|
+
protocolVersion: Int,
|
|
50
|
+
declarations: String4,
|
|
51
|
+
setup: Record(KitDigest, String4)
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
class NpmRegistryError extends TaggedError("NpmRegistryError") {
|
|
55
|
+
}
|
|
56
|
+
var Dist = Struct({
|
|
57
|
+
tarball: String4,
|
|
58
|
+
integrity: optionalKey(String4),
|
|
59
|
+
shasum: optionalKey(String4)
|
|
60
|
+
});
|
|
61
|
+
var Packument = Struct({
|
|
62
|
+
"dist-tags": Record(String4, String4),
|
|
63
|
+
versions: Record(String4, Struct({ dist: Dist }))
|
|
64
|
+
});
|
|
65
|
+
var integrityAlgorithms = ["sha512", "sha384", "sha256", "sha1"];
|
|
66
|
+
var tarballMatches = (tarball, dist) => {
|
|
67
|
+
if (dist.integrity === undefined)
|
|
68
|
+
return dist.shasum === digestWith("sha1", tarball, "hex");
|
|
69
|
+
const hashes = dist.integrity.split(/\s+/u).map((hash) => /^([^-]+)-([^?]+)/u.exec(hash));
|
|
70
|
+
const algorithm = integrityAlgorithms.find((candidate) => hashes.some((hash) => hash?.[1] === candidate));
|
|
71
|
+
return algorithm !== undefined && hashes.some((hash) => hash?.[1] === algorithm && hash[2] === digestWith(algorithm, tarball, "base64"));
|
|
72
|
+
};
|
|
73
|
+
var PackageJson = Struct({ kitman: optionalKey(Unknown) });
|
|
74
|
+
var decodePackageJson = decodeUnknownOption(fromJsonString(PackageJson));
|
|
75
|
+
var decodeManifest = decodeUnknownOption(KitManifest);
|
|
76
|
+
var decodeJson = decodeUnknownOption(fromJsonString(Unknown));
|
|
77
|
+
var gunzip = (bytes) => tryPromise(() => new Response(new Blob([new Uint8Array(bytes)]).stream().pipeThrough(new DecompressionStream("gzip"))).arrayBuffer()).pipe(map8((buffer) => new Uint8Array(buffer)));
|
|
78
|
+
var text = (bytes) => new TextDecoder().decode(bytes).replace(/\0.*$/su, "");
|
|
79
|
+
var untar = (tar) => {
|
|
80
|
+
const files = new Map;
|
|
81
|
+
let longName;
|
|
82
|
+
for (let offset = 0;offset + 512 <= tar.length; ) {
|
|
83
|
+
const header = tar.subarray(offset, offset + 512);
|
|
84
|
+
if (header.every((byte) => byte === 0))
|
|
85
|
+
break;
|
|
86
|
+
const size = Number.parseInt(text(header.subarray(124, 136)).trim() || "0", 8);
|
|
87
|
+
if (!Number.isSafeInteger(size) || size < 0 || offset + 512 + size > tar.length)
|
|
88
|
+
return;
|
|
89
|
+
const type = String.fromCharCode(header[156] ?? 0);
|
|
90
|
+
const prefix = text(header.subarray(345, 500));
|
|
91
|
+
const body = tar.subarray(offset + 512, offset + 512 + size);
|
|
92
|
+
const name = longName ?? (prefix === "" ? text(header.subarray(0, 100)) : `${prefix}/${text(header.subarray(0, 100))}`);
|
|
93
|
+
longName = undefined;
|
|
94
|
+
if (type === "x")
|
|
95
|
+
longName = /(?:^|\n)\d+ path=([^\n]*)\n/u.exec(new TextDecoder().decode(body))?.[1];
|
|
96
|
+
else if (type === "L")
|
|
97
|
+
longName = text(body);
|
|
98
|
+
else if (type === "0" || type === "\x00")
|
|
99
|
+
files.set(name.replace(/^[^/]*\//u, ""), body);
|
|
100
|
+
offset += 512 + Math.ceil(size / 512) * 512;
|
|
101
|
+
}
|
|
102
|
+
return files;
|
|
103
|
+
};
|
|
104
|
+
var registryUrl = String2("NPM_CONFIG_REGISTRY").pipe(withDefault("https://registry.npmjs.org"));
|
|
105
|
+
var npmRegistryAt = (url = registryUrl) => {
|
|
106
|
+
const base = (isString2(url) ? succeed6(url) : orDie(url)).pipe(map8((value) => value.replace(/\/+$/u, "")));
|
|
107
|
+
const unreachable = (name, version) => (error) => new NpmRegistryError({
|
|
108
|
+
kind: "unreachable",
|
|
109
|
+
message: `npm did not answer for ${name}@${version}: ${error.message}; try again`
|
|
110
|
+
});
|
|
111
|
+
const packument = (name, version) => gen(function* () {
|
|
112
|
+
const response = yield* get2(`${yield* base}/${name.replace("/", "%2F")}`).pipe(mapError2(unreachable(name, version)), provide3(layer2));
|
|
113
|
+
if (response.status === 404)
|
|
114
|
+
return yield* new NpmRegistryError({ kind: "not_found", message: `npm has no package ${name}` });
|
|
115
|
+
return yield* filterStatusOk(response).pipe(flatMap3(schemaBodyJson(Packument)), mapError2(unreachable(name, version)));
|
|
116
|
+
});
|
|
117
|
+
return {
|
|
118
|
+
latest: (name) => flatMap3(packument(name, "latest"), (found) => {
|
|
119
|
+
const latest = found["dist-tags"].latest;
|
|
120
|
+
return latest === undefined ? fail7(new NpmRegistryError({ kind: "not_found", message: `npm has no latest ${name}` })) : succeed6(latest);
|
|
121
|
+
}),
|
|
122
|
+
kit: (name, wanted) => gen(function* () {
|
|
123
|
+
const found = yield* packument(name, wanted);
|
|
124
|
+
const version = found["dist-tags"][wanted] ?? wanted;
|
|
125
|
+
const dist = found.versions[version]?.dist;
|
|
126
|
+
if (dist === undefined)
|
|
127
|
+
return yield* new NpmRegistryError({ kind: "not_found", message: `npm has no ${name}@${wanted}` });
|
|
128
|
+
const tarball = yield* get2(dist.tarball).pipe(flatMap3(filterStatusOk), flatMap3((response) => response.arrayBuffer), map8((buffer) => new Uint8Array(buffer)), mapError2(unreachable(name, version)), provide3(layer2));
|
|
129
|
+
if (!tarballMatches(tarball, dist))
|
|
130
|
+
return yield* new NpmRegistryError({
|
|
131
|
+
kind: "integrity",
|
|
132
|
+
message: `${name}@${version}'s tarball does not match npm's integrity: expected ${dist.integrity ?? `sha1 ${dist.shasum}`}, got sha512-${digestSha512(tarball, "base64")}; its publisher must publish a new version`
|
|
133
|
+
});
|
|
134
|
+
const notAKit = new NpmRegistryError({
|
|
135
|
+
kind: "not_a_kit",
|
|
136
|
+
message: `${name}@${version} is not a Kitman Kit: add \`kitman kit build\` to its prepack and publish again`
|
|
137
|
+
});
|
|
138
|
+
const files = untar(yield* gunzip(tarball).pipe(mapError2(() => notAKit)));
|
|
139
|
+
if (files === undefined)
|
|
140
|
+
return yield* notAKit;
|
|
141
|
+
const file = (path) => fromUndefinedOr(files.get(path.replace(/^\.\//u, "")));
|
|
142
|
+
const manifest = flatMap(file("package.json"), (bytes) => flatMap(decodePackageJson(new TextDecoder().decode(bytes)), (json) => decodeManifest(json.kitman)));
|
|
143
|
+
if (isNone(manifest))
|
|
144
|
+
return yield* notAKit;
|
|
145
|
+
const bundle = file(manifest.value.bundle);
|
|
146
|
+
const declarations = file(manifest.value.declarations);
|
|
147
|
+
const setupArchives = Object.entries(manifest.value.setup).flatMap(([digest, path]) => match(file(path), {
|
|
148
|
+
onNone: () => [],
|
|
149
|
+
onSome: (archive) => digestSha256(archive, "hex") === digest ? [{ digest, archive }] : []
|
|
150
|
+
}));
|
|
151
|
+
if (isNone(bundle) || isNone(declarations) || digestSha256(bundle.value, "hex") !== manifest.value.digest || setupArchives.length !== Object.keys(manifest.value.setup).length)
|
|
152
|
+
return yield* notAKit;
|
|
153
|
+
const parsed = decodeJson(new TextDecoder().decode(declarations.value));
|
|
154
|
+
if (isNone(parsed))
|
|
155
|
+
return yield* notAKit;
|
|
156
|
+
return {
|
|
157
|
+
name,
|
|
158
|
+
version,
|
|
159
|
+
integrity: dist.integrity ?? `sha1-${digestWith("sha1", tarball, "base64")}`,
|
|
160
|
+
bundle: bundle.value,
|
|
161
|
+
digest: manifest.value.digest,
|
|
162
|
+
protocolVersion: manifest.value.protocolVersion,
|
|
163
|
+
declarations: parsed.value,
|
|
164
|
+
setupArchives
|
|
165
|
+
};
|
|
166
|
+
})
|
|
167
|
+
};
|
|
168
|
+
};
|
|
169
|
+
var NpmRegistry = Reference("kitman/core/NpmRegistry", {
|
|
170
|
+
defaultValue: () => npmRegistryAt()
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
export { Packument, tarballMatches, NpmRegistry };
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import {
|
|
3
|
+
getOrUndefined,
|
|
4
|
+
flatMap,
|
|
5
|
+
toArray,
|
|
6
|
+
decodeUnknownOption,
|
|
7
|
+
optionalKey,
|
|
8
|
+
String4,
|
|
9
|
+
Struct,
|
|
10
|
+
Record,
|
|
11
|
+
ArraySchema,
|
|
12
|
+
decodeJsonStringOption,
|
|
13
|
+
encodeUnknownJsonStringSync
|
|
14
|
+
} from "./chunk-mbctzx7e.js";
|
|
15
|
+
import {
|
|
16
|
+
replaceSecretReferences,
|
|
17
|
+
secretReferencesIn
|
|
18
|
+
} from "./chunk-pp1p3g6e.js";
|
|
19
|
+
|
|
20
|
+
// packages/agent-runtime/src/secret-proxy.ts
|
|
21
|
+
import { appendFileSync, readFileSync, renameSync, writeFileSync } from "fs";
|
|
22
|
+
|
|
23
|
+
// packages/agent-runtime/src/egress-proxy.ts
|
|
24
|
+
var egressAllowed = (hosts, host, port) => {
|
|
25
|
+
const target = host.toLowerCase();
|
|
26
|
+
return hosts.some((entry) => {
|
|
27
|
+
const [name = "", entryPort] = entry.toLowerCase().split(":");
|
|
28
|
+
if (entryPort !== undefined && Number(entryPort) !== port)
|
|
29
|
+
return false;
|
|
30
|
+
return name.startsWith("*.") ? target.endsWith(name.slice(1)) : target === name;
|
|
31
|
+
});
|
|
32
|
+
};
|
|
33
|
+
if (false)
|
|
34
|
+
;
|
|
35
|
+
|
|
36
|
+
// packages/agent-runtime/src/secret-proxy.ts
|
|
37
|
+
var basicPrefix = /^basic\s+/i;
|
|
38
|
+
var basicCredential = (value) => {
|
|
39
|
+
if (!basicPrefix.test(value))
|
|
40
|
+
return;
|
|
41
|
+
const decoded = Buffer.from(value.replace(basicPrefix, ""), "base64").toString("utf8");
|
|
42
|
+
return secretReferencesIn(decoded).length === 0 ? undefined : decoded;
|
|
43
|
+
};
|
|
44
|
+
var referencesInHeader = (value) => [
|
|
45
|
+
...new Set([...secretReferencesIn(value), ...secretReferencesIn(basicCredential(value) ?? "")])
|
|
46
|
+
];
|
|
47
|
+
var swapped = (value, registry) => {
|
|
48
|
+
const swap = (reference) => registry[reference]?.value ?? reference;
|
|
49
|
+
const basic = basicCredential(value);
|
|
50
|
+
return basic === undefined ? replaceSecretReferences(value, swap) : `Basic ${Buffer.from(replaceSecretReferences(basic, swap)).toString("base64")}`;
|
|
51
|
+
};
|
|
52
|
+
var decideSecretRequest = (request, readRegistry) => {
|
|
53
|
+
const carrying = request.headers.flatMap(([name, value]) => {
|
|
54
|
+
const references = referencesInHeader(value);
|
|
55
|
+
return references.length === 0 ? [] : [{ name, value, references }];
|
|
56
|
+
});
|
|
57
|
+
const inTarget = secretReferencesIn(request.target);
|
|
58
|
+
if (carrying.length === 0 && inTarget.length === 0)
|
|
59
|
+
return { action: "allow" };
|
|
60
|
+
const registry = readRegistry();
|
|
61
|
+
const refusals = [
|
|
62
|
+
...inTarget.map((reference) => ({
|
|
63
|
+
reference,
|
|
64
|
+
host: request.host,
|
|
65
|
+
reason: "A reference is swapped only in a header, never in a URL."
|
|
66
|
+
})),
|
|
67
|
+
...[...new Set(carrying.flatMap((header) => header.references))].flatMap((reference) => {
|
|
68
|
+
const entry = registry?.[reference];
|
|
69
|
+
const reason = entry === undefined ? "The reference is unknown or revoked." : request.scheme !== "https" ? "A reference is swapped only over HTTPS." : !egressAllowed(entry.hosts, request.host, request.port) ? `The Secret may be sent only to ${entry.hosts.join(", ")}.` : undefined;
|
|
70
|
+
return reason === undefined ? [] : [{ reference, host: request.host, reason }];
|
|
71
|
+
})
|
|
72
|
+
];
|
|
73
|
+
if (refusals.length > 0)
|
|
74
|
+
return {
|
|
75
|
+
action: "deny",
|
|
76
|
+
reason: `Kitman refused this request: ${refusals.map((refusal) => `${refusal.reference}: ${refusal.reason}`).join(" ")}`,
|
|
77
|
+
refusals
|
|
78
|
+
};
|
|
79
|
+
const names = new Set(carrying.map((header) => header.name.toLowerCase()));
|
|
80
|
+
return {
|
|
81
|
+
action: "allow",
|
|
82
|
+
setHeaders: request.headers.filter(([name]) => names.has(name.toLowerCase())).map(([name, value]) => [name, registry === undefined ? value : swapped(value, registry)])
|
|
83
|
+
};
|
|
84
|
+
};
|
|
85
|
+
var Registry = Record(String4, Struct({ value: String4, hosts: ArraySchema(String4) }));
|
|
86
|
+
var Refusal = Struct({
|
|
87
|
+
reference: optionalKey(String4),
|
|
88
|
+
host: String4,
|
|
89
|
+
reason: String4
|
|
90
|
+
});
|
|
91
|
+
var readSecretRegistry = (file) => {
|
|
92
|
+
try {
|
|
93
|
+
return getOrUndefined(flatMap(decodeJsonStringOption(readFileSync(file, "utf8")), decodeUnknownOption(Registry)));
|
|
94
|
+
} catch {
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
};
|
|
98
|
+
var writeSecretRegistry = (file, registry) => {
|
|
99
|
+
const next = `${file}.next`;
|
|
100
|
+
writeFileSync(next, encodeUnknownJsonStringSync(registry), { mode: 384 });
|
|
101
|
+
renameSync(next, file);
|
|
102
|
+
};
|
|
103
|
+
var secretRefusalLog = (registryFile) => `${registryFile}.refused`;
|
|
104
|
+
var appendSecretRefusals = (registryFile, refusals) => appendFileSync(secretRefusalLog(registryFile), refusals.map((refusal) => `${encodeUnknownJsonStringSync(refusal)}
|
|
105
|
+
`).join(""), { mode: 384 });
|
|
106
|
+
var parseSecretRefusals = (text) => text.split(`
|
|
107
|
+
`).flatMap((line) => toArray(flatMap(decodeJsonStringOption(line), decodeUnknownOption(Refusal))));
|
|
108
|
+
|
|
109
|
+
export { decideSecretRequest, readSecretRegistry, writeSecretRegistry, secretRefusalLog, appendSecretRefusals, parseSecretRefusals };
|