@kitman-sh/sdk 0.6.0 → 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.
- package/dist/build/index.js +2 -2
- package/dist/{chunk-f3d6cvkg.js → chunk-7hwhxthh.js} +103 -6
- package/dist/{chunk-jnxc0c54.js → chunk-zp7s46pz.js} +639 -636
- package/dist/loop/index.js +1 -1
- package/dist/program/index.js +9 -3
- package/package.json +1 -1
- package/types/packages/core/src/agent-capabilities.d.ts +10 -0
- package/types/packages/core/src/agent-sandbox-policy.d.ts +2 -0
- package/types/packages/core/src/enterprise-code-host.d.ts +2 -5
- package/types/packages/core/src/integration.d.ts +129 -11
- package/types/packages/core/src/package-declarations.d.ts +8 -0
- package/types/packages/core/src/project.d.ts +3 -1
- package/types/packages/core/src/repo-binding.d.ts +8 -0
- package/types/packages/core/src/runner-eligibility.d.ts +5 -1
- package/types/packages/core/src/runner.d.ts +78 -0
- package/types/packages/core/src/work-unit.d.ts +15 -0
- package/types/packages/core/src/workspace.d.ts +46 -0
- package/types/packages/live/src/rpc/runner-client.d.ts +10 -1
- package/types/packages/live/src/rpc/runner-group.d.ts +263 -260
- package/types/packages/sdk/src/loop/define.d.ts +7 -0
- package/types/packages/sdk/src/program/host.d.ts +22 -0
package/dist/build/index.js
CHANGED
|
@@ -4,12 +4,12 @@ import {
|
|
|
4
4
|
KitInstallationDeclaration,
|
|
5
5
|
KitAssignmentDeclaration,
|
|
6
6
|
PackageDeclarations
|
|
7
|
-
} from "../chunk-
|
|
7
|
+
} from "../chunk-zp7s46pz.js";
|
|
8
8
|
import {
|
|
9
9
|
RunnerRpcProtocolVersion,
|
|
10
10
|
describeFlag2,
|
|
11
11
|
Described2
|
|
12
|
-
} from "../chunk-
|
|
12
|
+
} from "../chunk-7hwhxthh.js";
|
|
13
13
|
|
|
14
14
|
// packages/core/src/crypto.ts
|
|
15
15
|
import { createHash, createHmac, createSign, randomBytes, timingSafeEqual } from "crypto";
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
// @bun
|
|
2
2
|
import {
|
|
3
|
+
AgentSandboxNetwork,
|
|
3
4
|
guard,
|
|
4
5
|
Id,
|
|
5
6
|
Timestamp,
|
|
6
|
-
AgentSandboxNetwork,
|
|
7
7
|
LoopStepOutput,
|
|
8
8
|
StepBrief,
|
|
9
9
|
LoopManifest,
|
|
@@ -19,7 +19,7 @@ import {
|
|
|
19
19
|
executeLoop2,
|
|
20
20
|
LoopCheckError2,
|
|
21
21
|
checkLoop2
|
|
22
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-zp7s46pz.js";
|
|
23
23
|
// packages/core/src/repo-binding.ts
|
|
24
24
|
import * as Schema from "effect/Schema";
|
|
25
25
|
var RepoBindingPathPrefixPattern = "^(?!/)(?!.*\\\\)(?!.*(?:^|/)\\.\\.?(?:/|$))(?!.*//)\\S+$";
|
|
@@ -64,6 +64,10 @@ var RepoBinding = Schema.Struct({
|
|
|
64
64
|
expectedCommitSha: Schema.optionalKey(Schema.String.check(Schema.isMinLength(1))),
|
|
65
65
|
credentialRefs: Schema.Array(RepoBindingCredentialRef),
|
|
66
66
|
status: RepoBindingStatus,
|
|
67
|
+
webhook: Schema.optionalKey(Schema.Struct({
|
|
68
|
+
status: Schema.Literals(["active", "missing"]),
|
|
69
|
+
message: Schema.optionalKey(Schema.String.check(Schema.isMaxLength(240)))
|
|
70
|
+
})),
|
|
67
71
|
createdAt: Timestamp,
|
|
68
72
|
updatedAt: Timestamp
|
|
69
73
|
});
|
|
@@ -171,6 +175,7 @@ var OrchestrationWorkUnit = Schema2.Struct({
|
|
|
171
175
|
granted: Schema2.Array(Schema2.String),
|
|
172
176
|
lease: WorkUnitLease,
|
|
173
177
|
journal: RunJournal,
|
|
178
|
+
network: Schema2.optionalKey(AgentSandboxNetwork),
|
|
174
179
|
program: Schema2.Struct({
|
|
175
180
|
loopId: Schema2.String.check(Schema2.isMinLength(1)),
|
|
176
181
|
credential: Schema2.String.check(Schema2.isMinLength(1))
|
|
@@ -837,7 +842,11 @@ import * as Layer2 from "effect/Layer";
|
|
|
837
842
|
import * as Stream from "effect/Stream";
|
|
838
843
|
import { RpcClient, RpcSerialization } from "effect/rpc";
|
|
839
844
|
import * as Socket from "effect/socket/Socket";
|
|
840
|
-
var
|
|
845
|
+
var proxiedWebSocket = (proxy) => Layer2.succeed(Socket.WebSocketConstructor)((target) => {
|
|
846
|
+
const options = { proxy };
|
|
847
|
+
return Reflect.construct(globalThis.WebSocket, [target, options]);
|
|
848
|
+
});
|
|
849
|
+
var runnerWebSocketProtocol = (url, options = {}) => RpcClient.layerProtocolSocket({ retryTransientErrors: true }).pipe(Layer2.provide(Socket.layerWebSocket(url)), Layer2.provide(options.proxy === undefined ? Socket.layerWebSocketConstructorGlobal : proxiedWebSocket(options.proxy)), Layer2.provide(RpcSerialization.layerJson));
|
|
841
850
|
function runnerRpcUrl(apiUrl) {
|
|
842
851
|
const url = new URL("/v1/runners/rpc", apiUrl);
|
|
843
852
|
url.protocol = url.protocol === "https:" ? "wss:" : "ws:";
|
|
@@ -915,6 +924,81 @@ var programSecrets2 = (rpc, lease) => rpc.programSecrets({ lease }).pipe(Effect4
|
|
|
915
924
|
lease,
|
|
916
925
|
outcome: { status: "failed", failureSummary: `Kitman refused the Loop its Secrets: ${error.message}` }
|
|
917
926
|
}), Option2.none())));
|
|
927
|
+
var programHostsEnv2 = "KITMAN_PROGRAM_HOSTS";
|
|
928
|
+
var undeclaredHostsEnv2 = "KITMAN_UNDECLARED_HOSTS";
|
|
929
|
+
var allows = (hosts, host) => hosts.some((entry) => entry === host || entry.startsWith("*.") && host.endsWith(entry.slice(1)));
|
|
930
|
+
var redirectStatuses = new Set([301, 302, 303, 307, 308]);
|
|
931
|
+
var maxRedirects = 20;
|
|
932
|
+
var requestBodyHeaders = [
|
|
933
|
+
"content-type",
|
|
934
|
+
"content-length",
|
|
935
|
+
"content-encoding",
|
|
936
|
+
"content-language",
|
|
937
|
+
"content-location"
|
|
938
|
+
];
|
|
939
|
+
var credentialHeaders = ["authorization", "cookie", "proxy-authorization"];
|
|
940
|
+
var networkGuard2 = (input) => {
|
|
941
|
+
const warned = new Set;
|
|
942
|
+
let refused;
|
|
943
|
+
const refusalOf = (host) => {
|
|
944
|
+
if (allows(input.hosts, host))
|
|
945
|
+
return;
|
|
946
|
+
const undeclared = `The program called ${host}, a host its Loop does not declare. Add it to \`network\` in defineLoop`;
|
|
947
|
+
if (input.undeclared === "fail") {
|
|
948
|
+
refused ??= `${undeclared}.`;
|
|
949
|
+
return new Error(`${undeclared}.`);
|
|
950
|
+
}
|
|
951
|
+
if (!warned.has(host))
|
|
952
|
+
input.warn(`${undeclared}; a shared Runner refuses it.`);
|
|
953
|
+
warned.add(host);
|
|
954
|
+
return;
|
|
955
|
+
};
|
|
956
|
+
const follow = (first) => Effect4.gen(function* () {
|
|
957
|
+
let request = first;
|
|
958
|
+
for (let hops = 0;; hops++) {
|
|
959
|
+
const refusal = refusalOf(new URL(request.url).hostname);
|
|
960
|
+
if (refusal !== undefined)
|
|
961
|
+
return yield* Effect4.die(refusal);
|
|
962
|
+
const sent = request;
|
|
963
|
+
if (sent.redirect !== "follow")
|
|
964
|
+
return yield* Effect4.promise(() => input.fetch(sent));
|
|
965
|
+
const resend = sent.clone();
|
|
966
|
+
const response = yield* Effect4.promise(() => input.fetch(sent, { redirect: "manual" }));
|
|
967
|
+
const location = response.headers.get("location");
|
|
968
|
+
if (!redirectStatuses.has(response.status) || location === null)
|
|
969
|
+
return response;
|
|
970
|
+
if (hops === maxRedirects)
|
|
971
|
+
return yield* Effect4.die(new TypeError("The program followed too many redirects."));
|
|
972
|
+
response.body?.cancel();
|
|
973
|
+
const url = new URL(location, sent.url);
|
|
974
|
+
const asGet = response.status === 303 && sent.method !== "HEAD" || (response.status === 301 || response.status === 302) && sent.method === "POST";
|
|
975
|
+
const headers = new Headers(Array.from(resend.headers));
|
|
976
|
+
if (asGet)
|
|
977
|
+
for (const name of requestBodyHeaders)
|
|
978
|
+
headers.delete(name);
|
|
979
|
+
if (url.origin !== new URL(sent.url).origin)
|
|
980
|
+
for (const name of credentialHeaders)
|
|
981
|
+
headers.delete(name);
|
|
982
|
+
request = new Request(url.href, {
|
|
983
|
+
method: asGet ? "GET" : resend.method,
|
|
984
|
+
headers,
|
|
985
|
+
body: asGet || resend.body === null ? null : yield* Effect4.promise(() => resend.arrayBuffer()),
|
|
986
|
+
signal: sent.signal
|
|
987
|
+
});
|
|
988
|
+
}
|
|
989
|
+
});
|
|
990
|
+
const fetch = (resource, init) => Effect4.runPromise(Effect4.suspend(() => follow(resource instanceof Request ? new Request(resource, init) : new Request(resource instanceof URL ? resource.href : resource, init))));
|
|
991
|
+
const refusal = () => refused === undefined ? undefined : { status: "failed", failureSummary: refused };
|
|
992
|
+
const journal = (journal) => ({
|
|
993
|
+
...journal,
|
|
994
|
+
suspend: Effect4.suspend(() => {
|
|
995
|
+
const failed = refusal();
|
|
996
|
+
return failed === undefined ? journal.suspend : journal.finish(failed);
|
|
997
|
+
}),
|
|
998
|
+
finish: (outcome) => Effect4.suspend(() => journal.finish(refusal() ?? outcome))
|
|
999
|
+
});
|
|
1000
|
+
return { fetch, journal };
|
|
1001
|
+
};
|
|
918
1002
|
var describe = (config) => Effect4.gen(function* () {
|
|
919
1003
|
const loops = yield* Effect4.forEach(config.loops, loopManifest2);
|
|
920
1004
|
for (const loop of config.loops)
|
|
@@ -940,19 +1024,32 @@ var host = (config) => Effect4.gen(function* () {
|
|
|
940
1024
|
const loop = config.loops.find((candidate) => candidate.id === loopId);
|
|
941
1025
|
if (loop === undefined)
|
|
942
1026
|
return yield* new ProgramRefused({ reason: `The Package declares no Loop "${loopId}"` });
|
|
1027
|
+
const hosts = yield* Config.option(Config.String(programHostsEnv2));
|
|
1028
|
+
const undeclared = yield* Config.option(Config.Literals(["fail", "warn"], undeclaredHostsEnv2));
|
|
1029
|
+
const proxy = yield* Config.option(Config.String("HTTPS_PROXY"));
|
|
943
1030
|
const rpc = yield* makeRunnerRpcClient({
|
|
944
1031
|
runnerId: work.lease.leaseOwnerId,
|
|
945
1032
|
bearer: Effect4.sync(() => Redacted2.value(credential)),
|
|
946
|
-
protocol: runnerWebSocketProtocol(runnerRpcUrl(apiUrl))
|
|
1033
|
+
protocol: runnerWebSocketProtocol(runnerRpcUrl(apiUrl), Option2.isSome(proxy) ? { proxy: proxy.value } : {})
|
|
947
1034
|
});
|
|
948
1035
|
const secrets = (loop.secrets ?? []).length === 0 ? Option2.some({}) : yield* programSecrets2(rpc, programLease2(work));
|
|
949
1036
|
if (Option2.isNone(secrets))
|
|
950
1037
|
return 0;
|
|
951
|
-
|
|
1038
|
+
const guard = Option2.isNone(hosts) ? undefined : networkGuard2({
|
|
1039
|
+
hosts: hosts.value.split(",").filter((host) => host.length > 0),
|
|
1040
|
+
undeclared: Option2.getOrElse(undeclared, () => "warn"),
|
|
1041
|
+
fetch: globalThis.fetch,
|
|
1042
|
+
warn: (line) => void process.stderr.write(`${line}
|
|
1043
|
+
`)
|
|
1044
|
+
});
|
|
1045
|
+
if (guard !== undefined)
|
|
1046
|
+
globalThis.fetch = Object.assign(guard.fetch, { preconnect: globalThis.fetch.preconnect });
|
|
1047
|
+
const journal = rpcProgramJournal2(rpc, work);
|
|
1048
|
+
return yield* runProgram2(loop, work, guard === undefined ? journal : guard.journal(journal)).pipe(Effect4.provideService(ConfigProvider.ConfigProvider, ConfigProvider.fromUnknown(secrets.value)), Effect4.as(0), Effect4.catchTag("JournalWriteFailed", (error) => Effect4.as(Effect4.logError(error.message), 1)));
|
|
952
1049
|
}).pipe(Effect4.scoped, Effect4.catch((error) => Effect4.as(Effect4.logError(error.message), 2)));
|
|
953
1050
|
var runPackage2 = (config) => {
|
|
954
1051
|
const program = process.argv.includes(describeFlag2) ? describe(config) : host(config);
|
|
955
1052
|
BunRuntime.runMain(program.pipe(Effect4.flatMap((code) => Effect4.sync(() => process.exit(code)))));
|
|
956
1053
|
};
|
|
957
1054
|
|
|
958
|
-
export { RunnerRpcProtocolVersion, JournalWriteFailed2, refusedStep2, runProgram2, programLease2, rpcProgramJournal2, describeFlag2, Described2, programSecrets2, runPackage2 };
|
|
1055
|
+
export { RunnerRpcProtocolVersion, JournalWriteFailed2, refusedStep2, runProgram2, programLease2, rpcProgramJournal2, describeFlag2, Described2, programSecrets2, programHostsEnv2, undeclaredHostsEnv2, networkGuard2, runPackage2 };
|