@kitman-sh/cli 0.6.0 → 0.7.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/dist/{chunk-brp7cekg.js → chunk-1d2e4je3.js} +1 -1
- package/dist/chunk-23ch5vdv.js +78 -0
- package/dist/{chunk-fc0v325q.js → chunk-2vcae278.js} +9 -10
- package/dist/{chunk-h8ctzn91.js → chunk-50w9z6we.js} +9 -12
- package/dist/{chunk-txyq8r41.js → chunk-5rp5hvc0.js} +1177 -250
- package/dist/{chunk-hw7qkap1.js → chunk-9bje6bm0.js} +22 -361
- package/dist/{chunk-tfr74ays.js → chunk-eynqc0vm.js} +142 -33
- package/dist/{chunk-3j7sewn0.js → chunk-f1f60hgt.js} +782 -615
- package/dist/{chunk-dsefng1v.js → chunk-gj8pz39x.js} +5 -6
- package/dist/{chunk-6h8ghah0.js → chunk-mx1x1b6a.js} +3 -4
- package/dist/{chunk-n32jhswz.js → chunk-tkk2synn.js} +21 -23
- package/dist/index.js +165 -78
- package/package.json +1 -1
- package/dist/chunk-hrvcz0m4.js +0 -211
- package/dist/chunk-xdk488qp.js +0 -364
package/dist/index.js
CHANGED
|
@@ -18,7 +18,7 @@ import {
|
|
|
18
18
|
getOrElse,
|
|
19
19
|
fromUndefinedOr,
|
|
20
20
|
getOrUndefined,
|
|
21
|
-
|
|
21
|
+
Service,
|
|
22
22
|
Reference,
|
|
23
23
|
of,
|
|
24
24
|
toMillis,
|
|
@@ -29,7 +29,7 @@ import {
|
|
|
29
29
|
UnknownError,
|
|
30
30
|
succeed2,
|
|
31
31
|
fail2,
|
|
32
|
-
|
|
32
|
+
makeUnsafe,
|
|
33
33
|
_await,
|
|
34
34
|
isDone,
|
|
35
35
|
isDoneUnsafe,
|
|
@@ -86,9 +86,9 @@ import {
|
|
|
86
86
|
runMain,
|
|
87
87
|
systemError,
|
|
88
88
|
badArgument,
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
89
|
+
makeUnsafe3,
|
|
90
|
+
make7,
|
|
91
|
+
make8,
|
|
92
92
|
offerUnsafe,
|
|
93
93
|
endUnsafe,
|
|
94
94
|
take,
|
|
@@ -98,7 +98,7 @@ import {
|
|
|
98
98
|
isSink,
|
|
99
99
|
fromChannel,
|
|
100
100
|
drain,
|
|
101
|
-
|
|
101
|
+
make9,
|
|
102
102
|
get2,
|
|
103
103
|
isStream,
|
|
104
104
|
fromChannel2,
|
|
@@ -115,9 +115,9 @@ import {
|
|
|
115
115
|
ExitCode,
|
|
116
116
|
ProcessId,
|
|
117
117
|
makeHandle,
|
|
118
|
-
|
|
118
|
+
make11,
|
|
119
119
|
ChildProcessSpawner,
|
|
120
|
-
|
|
120
|
+
make12,
|
|
121
121
|
parseFdName,
|
|
122
122
|
fdName,
|
|
123
123
|
handleErrnoException,
|
|
@@ -158,6 +158,7 @@ import {
|
|
|
158
158
|
isSyncKitSafe,
|
|
159
159
|
resolveSyncKit,
|
|
160
160
|
decodeJsonString,
|
|
161
|
+
decodeJsonStringOption,
|
|
161
162
|
encodeJsonStringSync,
|
|
162
163
|
encodePrettyJsonString,
|
|
163
164
|
encodeUnknownJsonStringSync,
|
|
@@ -182,11 +183,13 @@ import {
|
|
|
182
183
|
agentCredentialForApi,
|
|
183
184
|
storeAgentCredential,
|
|
184
185
|
raw,
|
|
185
|
-
|
|
186
|
+
make13,
|
|
186
187
|
get3,
|
|
187
188
|
put,
|
|
188
189
|
execute,
|
|
190
|
+
Fetch,
|
|
189
191
|
layer4,
|
|
192
|
+
KitmanEffectClient,
|
|
190
193
|
digestSha256,
|
|
191
194
|
parseCallbackUrl,
|
|
192
195
|
revokeToken,
|
|
@@ -198,11 +201,13 @@ import {
|
|
|
198
201
|
refreshSession,
|
|
199
202
|
createAgentAuthBearerToken,
|
|
200
203
|
createAgentAuthSignedFetch,
|
|
204
|
+
RunnerHeaders,
|
|
201
205
|
setupMcpAgentCredential,
|
|
202
206
|
generateAgentKeyPair,
|
|
203
207
|
runCommand2,
|
|
204
|
-
|
|
205
|
-
|
|
208
|
+
detectHarnesses2,
|
|
209
|
+
herdrRunnerCapabilities2
|
|
210
|
+
} from "./chunk-5rp5hvc0.js";
|
|
206
211
|
|
|
207
212
|
// node_modules/.bun/@effect+platform-node-shared@4.0.4+b8cbb99ebc524863/node_modules/@effect/platform-node-shared/dist/NodeChildProcessSpawner.js
|
|
208
213
|
import * as NodeChildProcess from "child_process";
|
|
@@ -290,8 +295,8 @@ var fromReadableChannel = (options) => fromTransform((_, scope) => readableToPul
|
|
|
290
295
|
var readableToPullUnsafe = (options) => {
|
|
291
296
|
const readable = options.readable;
|
|
292
297
|
const closeOnDone = options.closeOnDone ?? true;
|
|
293
|
-
const exit = options.exit ??
|
|
294
|
-
const latch = options.latch ??
|
|
298
|
+
const exit = options.exit ?? make7(undefined);
|
|
299
|
+
const latch = options.latch ?? makeUnsafe3(false);
|
|
295
300
|
function onReadable() {
|
|
296
301
|
latch.openUnsafe();
|
|
297
302
|
}
|
|
@@ -582,7 +587,7 @@ var make = /* @__PURE__ */ gen(function* () {
|
|
|
582
587
|
};
|
|
583
588
|
};
|
|
584
589
|
const spawn2 = (command, spawnOptions) => callback((resume) => {
|
|
585
|
-
const deferred =
|
|
590
|
+
const deferred = makeUnsafe();
|
|
586
591
|
const handle = NodeChildProcess.spawn(command.command, command.args, spawnOptions);
|
|
587
592
|
handle.on("error", (error) => {
|
|
588
593
|
resume(fail4(toPlatformError("spawn", error, command)));
|
|
@@ -782,7 +787,7 @@ var make = /* @__PURE__ */ gen(function* () {
|
|
|
782
787
|
const sourceStream = unwrap(succeed5(getSourceStream(handles[handles.length - 1], options.from)));
|
|
783
788
|
const toOption = options.to ?? "stdin";
|
|
784
789
|
if (toOption === "stdin") {
|
|
785
|
-
handles.push(yield* spawnCommand(
|
|
790
|
+
handles.push(yield* spawnCommand(make12(command.command, command.args, {
|
|
786
791
|
...command.options,
|
|
787
792
|
stdin: {
|
|
788
793
|
...stdinConfig,
|
|
@@ -794,7 +799,7 @@ var make = /* @__PURE__ */ gen(function* () {
|
|
|
794
799
|
if (isNotUndefined(fd)) {
|
|
795
800
|
const fdName2 = fdName(fd);
|
|
796
801
|
const existingFds = command.options.additionalFds ?? {};
|
|
797
|
-
handles.push(yield* spawnCommand(
|
|
802
|
+
handles.push(yield* spawnCommand(make12(command.command, command.args, {
|
|
798
803
|
...command.options,
|
|
799
804
|
additionalFds: {
|
|
800
805
|
...existingFds,
|
|
@@ -805,7 +810,7 @@ var make = /* @__PURE__ */ gen(function* () {
|
|
|
805
810
|
}
|
|
806
811
|
})));
|
|
807
812
|
} else {
|
|
808
|
-
handles.push(yield* spawnCommand(
|
|
813
|
+
handles.push(yield* spawnCommand(make12(command.command, command.args, {
|
|
809
814
|
...command.options,
|
|
810
815
|
stdin: {
|
|
811
816
|
...stdinConfig,
|
|
@@ -844,7 +849,7 @@ var make = /* @__PURE__ */ gen(function* () {
|
|
|
844
849
|
}
|
|
845
850
|
}
|
|
846
851
|
});
|
|
847
|
-
return
|
|
852
|
+
return make11(spawnCommand);
|
|
848
853
|
});
|
|
849
854
|
var layer5 = /* @__PURE__ */ effect(ChildProcessSpawner, make);
|
|
850
855
|
var flattenCommand = (command) => {
|
|
@@ -878,7 +883,7 @@ var flattenCommand = (command) => {
|
|
|
878
883
|
|
|
879
884
|
// node_modules/.bun/effect@4.0.4/node_modules/effect/dist/Stdio.js
|
|
880
885
|
var TypeId = "~effect/Stdio";
|
|
881
|
-
var Stdio = /* @__PURE__ */
|
|
886
|
+
var Stdio = /* @__PURE__ */ Service(TypeId);
|
|
882
887
|
var make2 = (options) => ({
|
|
883
888
|
[TypeId]: TypeId,
|
|
884
889
|
stdinIsTerminal: succeed5(false),
|
|
@@ -937,7 +942,7 @@ class QuitError extends (/* @__PURE__ */ Error2("QuitError")({
|
|
|
937
942
|
})) {
|
|
938
943
|
[QuitErrorTypeId] = QuitErrorTypeId;
|
|
939
944
|
}
|
|
940
|
-
var Terminal = /* @__PURE__ */
|
|
945
|
+
var Terminal = /* @__PURE__ */ Service("effect/Terminal");
|
|
941
946
|
var make3 = (impl) => Terminal.of({
|
|
942
947
|
...impl,
|
|
943
948
|
[TypeId2]: TypeId2
|
|
@@ -948,7 +953,7 @@ import * as readline from "readline";
|
|
|
948
953
|
var make4 = /* @__PURE__ */ fnUntraced(function* (shouldQuit = defaultShouldQuit) {
|
|
949
954
|
const stdin = process.stdin;
|
|
950
955
|
const stdout = process.stdout;
|
|
951
|
-
const lines = yield*
|
|
956
|
+
const lines = yield* make8();
|
|
952
957
|
let inputEnded = stdin.readableEnded;
|
|
953
958
|
let readlineActive = false;
|
|
954
959
|
const onStdinEnd = () => {
|
|
@@ -959,7 +964,7 @@ var make4 = /* @__PURE__ */ fnUntraced(function* (shouldQuit = defaultShouldQuit
|
|
|
959
964
|
};
|
|
960
965
|
stdin.once("end", onStdinEnd);
|
|
961
966
|
yield* addFinalizer2(() => sync(() => stdin.off("end", onStdinEnd)));
|
|
962
|
-
const rlRef = yield*
|
|
967
|
+
const rlRef = yield* make9({
|
|
963
968
|
acquire: acquireRelease(sync(() => {
|
|
964
969
|
const rl = readline.createInterface({
|
|
965
970
|
input: stdin,
|
|
@@ -1003,7 +1008,7 @@ var make4 = /* @__PURE__ */ fnUntraced(function* (shouldQuit = defaultShouldQuit
|
|
|
1003
1008
|
const columns = sync(() => stdout.columns ?? 0);
|
|
1004
1009
|
const rows = sync(() => stdout.rows ?? 0);
|
|
1005
1010
|
const readInput = gen(function* () {
|
|
1006
|
-
const queue = yield*
|
|
1011
|
+
const queue = yield* make8();
|
|
1007
1012
|
const handleKeypress = (s, k) => {
|
|
1008
1013
|
const userInput = {
|
|
1009
1014
|
input: fromUndefinedOr(s),
|
|
@@ -1105,9 +1110,14 @@ function createHerdrRunnerClient(input) {
|
|
|
1105
1110
|
credential,
|
|
1106
1111
|
...input.fetch === undefined ? undefined : { fetch: input.fetch }
|
|
1107
1112
|
});
|
|
1113
|
+
const runnerFetch = (requestInput, init) => {
|
|
1114
|
+
const request = new Request(requestInput, init);
|
|
1115
|
+
request.headers.set(RunnerHeaders.runnerId, input.runnerId);
|
|
1116
|
+
return signedFetch(request);
|
|
1117
|
+
};
|
|
1108
1118
|
const client = yield* createSdkClient({
|
|
1109
1119
|
apiUrl: input.apiUrl,
|
|
1110
|
-
fetch:
|
|
1120
|
+
fetch: runnerFetch,
|
|
1111
1121
|
session: { accessToken: "runner-agent-auth" }
|
|
1112
1122
|
});
|
|
1113
1123
|
const rpcBearer = createAgentAuthBearerToken({
|
|
@@ -1341,6 +1351,16 @@ function queryString(query) {
|
|
|
1341
1351
|
return query.size === 0 ? "" : `?${query.toString()}`;
|
|
1342
1352
|
}
|
|
1343
1353
|
|
|
1354
|
+
// packages/core/src/check-scripts.ts
|
|
1355
|
+
var verificationScripts = ["typecheck", "type-check", "lint", "test", "check"];
|
|
1356
|
+
function declaredChecks(manifest, rootFiles) {
|
|
1357
|
+
const value = manifest === undefined ? undefined : getOrUndefined(decodeJsonStringOption(manifest));
|
|
1358
|
+
const scripts = isJsonObject(value) && isJsonObject(value.scripts) ? value.scripts : {};
|
|
1359
|
+
const has = (file) => rootFiles.includes(file);
|
|
1360
|
+
const runner = has("bun.lock") || has("bun.lockb") ? "bun run" : has("pnpm-lock.yaml") ? "pnpm run" : has("yarn.lock") ? "yarn" : "npm run";
|
|
1361
|
+
return verificationScripts.flatMap((name) => (name in scripts) ? [{ name, command: `${runner} ${name}` }] : []);
|
|
1362
|
+
}
|
|
1363
|
+
|
|
1344
1364
|
// apps/cli/src/init.ts
|
|
1345
1365
|
import { hostname } from "os";
|
|
1346
1366
|
|
|
@@ -1455,11 +1475,12 @@ function stripPathSuffix(value) {
|
|
|
1455
1475
|
}
|
|
1456
1476
|
|
|
1457
1477
|
// apps/cli/src/init.ts
|
|
1458
|
-
var
|
|
1478
|
+
var ServiceManager = Reference("kitman/cli/ServiceManager", {
|
|
1479
|
+
defaultValue: () => ({ platform: process.platform, run: (command, args) => runCommand2(command, args) })
|
|
1480
|
+
});
|
|
1459
1481
|
var Login = Reference("kitman/cli/Login", {
|
|
1460
1482
|
defaultValue: () => browserSession
|
|
1461
1483
|
});
|
|
1462
|
-
var verificationScripts = ["typecheck", "type-check", "lint", "test", "check"];
|
|
1463
1484
|
var outcomeLabel = {
|
|
1464
1485
|
set_up: "set up",
|
|
1465
1486
|
already: "already set up",
|
|
@@ -1515,6 +1536,34 @@ function initCommand(args) {
|
|
|
1515
1536
|
yield* log(changed.length === 0 ? "Nothing to change: Kitman is already set up here." : `Set up ${changed.map((entry) => entry.name).join(", ")}. Start work with kitman run start build "<what to build>".`);
|
|
1516
1537
|
});
|
|
1517
1538
|
}
|
|
1539
|
+
function pairCommand(args) {
|
|
1540
|
+
return gen(function* () {
|
|
1541
|
+
const [code, ...rest] = args;
|
|
1542
|
+
if (code === undefined || code.startsWith("-"))
|
|
1543
|
+
return yield* new CliError({ message: "Usage: kitman pair <pairing code> [--api-url <url>]" });
|
|
1544
|
+
const flags = parseInitFlags(rest);
|
|
1545
|
+
const apiUrl = yield* resolveApiUrl(flags.apiUrl);
|
|
1546
|
+
const step = (name, outcome, detail) => log(`${name}: ${outcomeLabel[outcome]} (${detail})`);
|
|
1547
|
+
const anonymous = new KitmanEffectClient({ baseUrl: apiUrl, fetch: yield* Fetch });
|
|
1548
|
+
const credentials = yield* anonymous.redeemPairingCode({ code });
|
|
1549
|
+
const session = toStoredSession({
|
|
1550
|
+
access_token: credentials.accessToken,
|
|
1551
|
+
...credentials.refreshToken === undefined ? undefined : { refresh_token: credentials.refreshToken },
|
|
1552
|
+
...credentials.expiresIn === undefined ? undefined : { expires_in: credentials.expiresIn }
|
|
1553
|
+
});
|
|
1554
|
+
yield* storeSession(apiUrl, session);
|
|
1555
|
+
yield* writeUserConfig({ ...yield* readUserConfig(), apiUrl, activeWorkspaceId: credentials.workspaceId });
|
|
1556
|
+
yield* step("Login", "set_up", apiUrl);
|
|
1557
|
+
const client = yield* clientFor(apiUrl, session);
|
|
1558
|
+
yield* runnerStep(client, { apiUrl, session, workspaceId: credentials.workspaceId, userId: credentials.userId }, step);
|
|
1559
|
+
const detected = yield* detectHarnesses2;
|
|
1560
|
+
if (detected.harnesses.length === 0)
|
|
1561
|
+
return yield* step("Harness", "skipped", `none logged in: ${detected.unavailable.map((harness) => harness.missing.join(", ")).join("; ")}`);
|
|
1562
|
+
const harnesses = detected.harnesses.map((harness) => harness === "claude" ? "claude-code" : harness);
|
|
1563
|
+
yield* harnessSync(["sync", ...harnesses]);
|
|
1564
|
+
yield* step("Harness", "set_up", `${harnesses.join(", ")} synced`);
|
|
1565
|
+
});
|
|
1566
|
+
}
|
|
1518
1567
|
var parseInitFlags = (args) => {
|
|
1519
1568
|
const flags = { yes: false };
|
|
1520
1569
|
for (let index = 0;index < args.length; index += 1) {
|
|
@@ -1558,7 +1607,7 @@ var runnerStep = (client, input, step) => gen(function* () {
|
|
|
1558
1607
|
const existing = runners.find((runner) => runner.ownership.kind === "personal" && runner.ownership.ownerUserId === input.userId && runner.name === name && runner.status === "active");
|
|
1559
1608
|
const runner = existing ?? (yield* client.registerRunner(input.workspaceId, {
|
|
1560
1609
|
name,
|
|
1561
|
-
capabilities:
|
|
1610
|
+
capabilities: herdrRunnerCapabilities2({ harnesses: yield* detectHarnesses2 }),
|
|
1562
1611
|
labels: ["kitman-runner", "kitman-loop", "herdr"]
|
|
1563
1612
|
})).runner;
|
|
1564
1613
|
const credentialMissing = agentCredentialForApi(yield* readAuthStore(), input.apiUrl, `herdr-runner:${runner.id}`) === undefined;
|
|
@@ -1566,8 +1615,8 @@ var runnerStep = (client, input, step) => gen(function* () {
|
|
|
1566
1615
|
yield* ensureHerdrRunnerCredential({ apiUrl: input.apiUrl, accessToken: input.session.accessToken, runner });
|
|
1567
1616
|
yield* step("Runner", existing === undefined ? "set_up" : credentialMissing ? "repaired" : "already", `${name}${credentialMissing && existing !== undefined ? ", credential restored" : ""}`);
|
|
1568
1617
|
const home = yield* String3("HOME");
|
|
1569
|
-
const service = yield* (
|
|
1570
|
-
name:
|
|
1618
|
+
const service = yield* runnerService({
|
|
1619
|
+
name: runnerServiceName(runner.id),
|
|
1571
1620
|
command: [...kitmanCommand(), "runner", "start", runner.id, "--api-url", input.apiUrl],
|
|
1572
1621
|
workingDirectory: home,
|
|
1573
1622
|
path: getOrElse(yield* option2(String3("PATH")), () => "/usr/local/bin:/usr/bin:/bin")
|
|
@@ -1603,14 +1652,8 @@ var scriptChecks = gen(function* () {
|
|
|
1603
1652
|
const path = yield* Path;
|
|
1604
1653
|
const top = yield* (yield* Git)(["rev-parse", "--show-toplevel"]).pipe(orElseSucceed(() => ""));
|
|
1605
1654
|
const root = top === "" ? path.resolve(".") : top;
|
|
1606
|
-
const
|
|
1607
|
-
|
|
1608
|
-
return;
|
|
1609
|
-
}));
|
|
1610
|
-
const scripts = isJsonObject(parsed) && isJsonObject(parsed.scripts) ? parsed.scripts : {};
|
|
1611
|
-
const has = (file) => fs.exists(path.join(root, file));
|
|
1612
|
-
const runner = (yield* has("bun.lock")) || (yield* has("bun.lockb")) ? "bun run" : (yield* has("pnpm-lock.yaml")) ? "pnpm run" : (yield* has("yarn.lock")) ? "yarn" : "npm run";
|
|
1613
|
-
return verificationScripts.flatMap((name) => (name in scripts) ? [{ name, command: `${runner} ${name}` }] : []);
|
|
1655
|
+
const rootFiles = yield* fs.readDirectory(root).pipe(orElseSucceed(() => []));
|
|
1656
|
+
return declaredChecks(yield* readText(path.join(root, "package.json")), rootFiles);
|
|
1614
1657
|
});
|
|
1615
1658
|
var systemdUnit = (spec) => [
|
|
1616
1659
|
"[Unit]",
|
|
@@ -1644,12 +1687,28 @@ var launchdPlist = (label, spec) => [
|
|
|
1644
1687
|
].join(`
|
|
1645
1688
|
`);
|
|
1646
1689
|
var escapeXml = (text) => text.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
1647
|
-
|
|
1690
|
+
var runnerServiceName = (runnerId) => `kitman-runner-${runnerId}`;
|
|
1691
|
+
var launchdLabel = (name) => `dev.kitman.${name}`;
|
|
1692
|
+
var launchdDomain = gen(function* () {
|
|
1693
|
+
const manager = yield* ServiceManager;
|
|
1694
|
+
return `gui/${(yield* manager.run("id", ["-u"])).trim()}`;
|
|
1695
|
+
});
|
|
1696
|
+
function runnerServiceState(name) {
|
|
1697
|
+
return gen(function* () {
|
|
1698
|
+
const manager = yield* ServiceManager;
|
|
1699
|
+
if (manager.platform === "linux")
|
|
1700
|
+
return yield* manager.run("systemctl", ["--user", "is-active", `${name}.service`]).pipe(map3((state) => `systemd: ${state.trim()}`), orElseSucceed(() => "systemd: not running"));
|
|
1701
|
+
if (manager.platform === "darwin")
|
|
1702
|
+
return yield* manager.run("launchctl", ["print", `${yield* launchdDomain}/${launchdLabel(name)}`]).pipe(map3((printed) => `launchd: ${/^\s*state = (\S+)/mu.exec(printed)?.[1] ?? "loaded"}`), orElseSucceed(() => "launchd: not installed"));
|
|
1703
|
+
return;
|
|
1704
|
+
});
|
|
1705
|
+
}
|
|
1706
|
+
function runnerService(spec) {
|
|
1648
1707
|
return gen(function* () {
|
|
1649
1708
|
const fs = yield* FileSystem;
|
|
1650
1709
|
const path = yield* Path;
|
|
1710
|
+
const manager = yield* ServiceManager;
|
|
1651
1711
|
const home = yield* String3("HOME");
|
|
1652
|
-
const succeeded = (command, args) => runCommand2(command, args).pipe(as(true), orElseSucceed(() => false));
|
|
1653
1712
|
const define = (file, content) => gen(function* () {
|
|
1654
1713
|
if ((yield* readText(file)) === content)
|
|
1655
1714
|
return false;
|
|
@@ -1657,25 +1716,25 @@ function userService(spec) {
|
|
|
1657
1716
|
yield* fs.writeFileString(file, content);
|
|
1658
1717
|
return true;
|
|
1659
1718
|
});
|
|
1660
|
-
if (
|
|
1719
|
+
if (manager.platform === "linux") {
|
|
1661
1720
|
const unit = `${spec.name}.service`;
|
|
1662
1721
|
const changed = yield* define(path.join(home, ".config", "systemd", "user", unit), systemdUnit(spec));
|
|
1663
|
-
if (!changed && (yield*
|
|
1722
|
+
if (!changed && (yield* runnerServiceState(spec.name)) === "systemd: active")
|
|
1664
1723
|
return "running";
|
|
1665
|
-
yield*
|
|
1666
|
-
yield*
|
|
1667
|
-
yield*
|
|
1724
|
+
yield* manager.run("systemctl", ["--user", "daemon-reload"]);
|
|
1725
|
+
yield* manager.run("systemctl", ["--user", "enable", unit]);
|
|
1726
|
+
yield* manager.run("systemctl", ["--user", "restart", unit]);
|
|
1668
1727
|
return changed ? "installed" : "started";
|
|
1669
1728
|
}
|
|
1670
|
-
if (
|
|
1671
|
-
const label =
|
|
1729
|
+
if (manager.platform === "darwin") {
|
|
1730
|
+
const label = launchdLabel(spec.name);
|
|
1672
1731
|
const file = path.join(home, "Library", "LaunchAgents", `${label}.plist`);
|
|
1673
1732
|
const changed = yield* define(file, launchdPlist(label, spec));
|
|
1674
|
-
|
|
1675
|
-
if (!changed && (yield* succeeded("launchctl", ["print", `${domain}/${label}`])))
|
|
1733
|
+
if (!changed && (yield* runnerServiceState(spec.name)) === "launchd: running")
|
|
1676
1734
|
return "running";
|
|
1677
|
-
yield*
|
|
1678
|
-
yield*
|
|
1735
|
+
const domain = yield* launchdDomain;
|
|
1736
|
+
yield* ignore(manager.run("launchctl", ["bootout", `${domain}/${label}`]));
|
|
1737
|
+
yield* manager.run("launchctl", ["bootstrap", domain, file]);
|
|
1679
1738
|
return changed ? "installed" : "started";
|
|
1680
1739
|
}
|
|
1681
1740
|
return "unsupported";
|
|
@@ -1711,7 +1770,7 @@ var package_default = {
|
|
|
1711
1770
|
};
|
|
1712
1771
|
|
|
1713
1772
|
// apps/cli/src/scaffold.ts
|
|
1714
|
-
var cliVersion = "0.
|
|
1773
|
+
var cliVersion = "0.7.1";
|
|
1715
1774
|
var packageJson = (name, scaffold) => `${JSON.stringify({
|
|
1716
1775
|
name,
|
|
1717
1776
|
private: true,
|
|
@@ -1831,7 +1890,7 @@ var scaffoldPackage = (directory, scaffold = {}) => gen(function* () {
|
|
|
1831
1890
|
const path = yield* Path;
|
|
1832
1891
|
const root = path.resolve(directory);
|
|
1833
1892
|
if (scaffold.fork !== undefined) {
|
|
1834
|
-
const { shippedLoops } = yield* promise(() => import("./chunk-
|
|
1893
|
+
const { shippedLoops } = yield* promise(() => import("./chunk-gj8pz39x.js"));
|
|
1835
1894
|
if (!(scaffold.fork in shippedLoops))
|
|
1836
1895
|
return yield* new CliError({
|
|
1837
1896
|
message: `Kitman ships no Loop ${scaffold.fork}; fork one of ${Object.keys(shippedLoops).join(", ")}`
|
|
@@ -1863,10 +1922,11 @@ var scaffoldPackage = (directory, scaffold = {}) => gen(function* () {
|
|
|
1863
1922
|
// apps/cli/src/commands.ts
|
|
1864
1923
|
var ClientId = "kitman-cli";
|
|
1865
1924
|
var Usage = [
|
|
1866
|
-
"Usage: kitman <init|run|inbox|loop|agent|deploy|package|verify|secret|constraint|mcp|sync|whoami|config|kit|task|memory|proposal|decision|context|schedule|delivery|reconcile|lifecycle|logout> [options]",
|
|
1925
|
+
"Usage: kitman <init|pair|run|inbox|loop|agent|deploy|package|verify|secret|constraint|mcp|sync|whoami|config|kit|task|memory|proposal|decision|context|schedule|delivery|reconcile|lifecycle|logout> [options]",
|
|
1867
1926
|
"",
|
|
1868
1927
|
"Set up, in a repository (run it again to repair what is missing):",
|
|
1869
1928
|
" kitman init [--yes] [--api-url <url>]",
|
|
1929
|
+
" kitman pair <pairing code> [--api-url <url>] (what the command the web shows runs)",
|
|
1870
1930
|
"",
|
|
1871
1931
|
"Runs:",
|
|
1872
1932
|
' kitman run start <loop> "<words>" [--input <json>] [--project <project>] [--type <task type>] [--constraint <text>]...',
|
|
@@ -1924,7 +1984,7 @@ var Usage = [
|
|
|
1924
1984
|
`);
|
|
1925
1985
|
var KitCreateValidator = guard(KitCreate);
|
|
1926
1986
|
var KitUpdateValidator = guard(KitUpdate);
|
|
1927
|
-
var agentRuntime = promise(() => import("./chunk-
|
|
1987
|
+
var agentRuntime = promise(() => import("./chunk-f1f60hgt.js"));
|
|
1928
1988
|
var TuiLauncher = Reference("kitman/cli/TuiLauncher", {
|
|
1929
1989
|
defaultValue: () => gen(function* () {
|
|
1930
1990
|
const tui = yield* tryPromise({
|
|
@@ -1951,6 +2011,8 @@ function runEffect(args) {
|
|
|
1951
2011
|
return yield* scaffoldPackage(rest[1] ?? ".");
|
|
1952
2012
|
if (command === "init")
|
|
1953
2013
|
return yield* initCommand(rest);
|
|
2014
|
+
if (command === "pair")
|
|
2015
|
+
return yield* pairCommand(rest);
|
|
1954
2016
|
if (command === "login")
|
|
1955
2017
|
return yield* login(rest);
|
|
1956
2018
|
if (command === "logout")
|
|
@@ -3108,7 +3170,7 @@ function runnerCommand(args) {
|
|
|
3108
3170
|
...command.flags.agentIdentityId === undefined ? undefined : { agentIdentityId: command.flags.agentIdentityId },
|
|
3109
3171
|
...ownership === undefined ? undefined : { ownership },
|
|
3110
3172
|
...command.flags.project === undefined ? undefined : { projectId: command.flags.project },
|
|
3111
|
-
capabilities: herdr ? (yield* agentRuntime).
|
|
3173
|
+
capabilities: herdr ? (yield* agentRuntime).herdrRunnerCapabilities({ harnesses: yield* (yield* agentRuntime).detectHarnesses }) : loopRunnerCapabilities(),
|
|
3112
3174
|
labels: herdr ? ["kitman-runner", "kitman-loop", "herdr"] : ["kitman-runner", "kitman-loop"]
|
|
3113
3175
|
});
|
|
3114
3176
|
const setup = response.setup;
|
|
@@ -3154,7 +3216,7 @@ function runnerCommand(args) {
|
|
|
3154
3216
|
if (command.action === "doctor") {
|
|
3155
3217
|
const runners = yield* client.listRunners(workspaceId);
|
|
3156
3218
|
if (command.flags.runnerId === undefined && command.args.length === 0 && command.flags.backend === undefined)
|
|
3157
|
-
return yield* runners.items.length === 0 ? printRows([{ status: "no_runners", workspaceId, message: "No Runner registered for workspace." }], command.flags.json) : printRows(runners.items
|
|
3219
|
+
return yield* runners.items.length === 0 ? printRows([{ status: "no_runners", workspaceId, message: "No Runner registered for workspace." }], command.flags.json) : printRows(yield* forEach(runners.items, runnerDoctorRowHere), command.flags.json);
|
|
3158
3220
|
const runner = command.flags.runnerId === undefined && command.args.length === 0 ? runners.items.find((item) => item.status === "active") ?? runners.items[0] : resolveRunnerRef(runners.items, command.flags.runnerId ?? command.args.join(" "));
|
|
3159
3221
|
if (runner === undefined) {
|
|
3160
3222
|
const rows = [{ status: "no_runners", workspaceId, message: "No Runner registered for workspace." }];
|
|
@@ -3166,7 +3228,7 @@ function runnerCommand(args) {
|
|
|
3166
3228
|
const readiness = yield* checkHerdrRunnerReadiness(runner);
|
|
3167
3229
|
return yield* printRows([readiness], command.flags.json);
|
|
3168
3230
|
}
|
|
3169
|
-
return yield* printRows([
|
|
3231
|
+
return yield* printRows([yield* runnerDoctorRowHere(runner)], command.flags.json);
|
|
3170
3232
|
}
|
|
3171
3233
|
return yield* new CliError({ message: `Unknown command: ${args.join(" ")}` });
|
|
3172
3234
|
});
|
|
@@ -3207,12 +3269,14 @@ function startCanonicalHerdrRunnerCommand(input) {
|
|
|
3207
3269
|
agentStepExecutor,
|
|
3208
3270
|
agentStepSandboxPolicy,
|
|
3209
3271
|
assertHerdrRunnerCapability,
|
|
3272
|
+
bundleCacheDir,
|
|
3210
3273
|
dockerContainerRunner,
|
|
3211
3274
|
herdrAgentBackendLayer,
|
|
3212
3275
|
herdrExecutorSurface,
|
|
3213
3276
|
herdrHarnessLayer,
|
|
3214
|
-
|
|
3215
|
-
|
|
3277
|
+
detectHarnesses,
|
|
3278
|
+
herdrRunnerCapabilities,
|
|
3279
|
+
herdrRunnerCapabilitiesForRepoBinding,
|
|
3216
3280
|
kitmanBundles,
|
|
3217
3281
|
kitmanMcpPreflight,
|
|
3218
3282
|
listenForSignals,
|
|
@@ -3226,7 +3290,7 @@ function startCanonicalHerdrRunnerCommand(input) {
|
|
|
3226
3290
|
superviseReplica,
|
|
3227
3291
|
verificationExecutor
|
|
3228
3292
|
} = yield* agentRuntime;
|
|
3229
|
-
const { makeRunnerRpcClient, runnerRpcUrl, runnerWebSocketProtocol } = yield* promise(() => import("./chunk-
|
|
3293
|
+
const { makeRunnerRpcClient, runnerRpcUrl, runnerWebSocketProtocol } = yield* promise(() => import("./chunk-mx1x1b6a.js"));
|
|
3230
3294
|
const settings = yield* runnerSettings;
|
|
3231
3295
|
const { concurrency, fullAccess, sshAgentAvailable } = settings;
|
|
3232
3296
|
const personal = input.runner.ownership.kind === "personal";
|
|
@@ -3237,7 +3301,9 @@ function startCanonicalHerdrRunnerCommand(input) {
|
|
|
3237
3301
|
message: `\`${sandbox}\` is not available on this host (${host.unavailable.find((entry) => entry.backend === sandbox)?.missing.join("; ") ?? "unsupported"}); unset KITMAN_RUNNER_SANDBOX to run agents on the host.`
|
|
3238
3302
|
});
|
|
3239
3303
|
const repoBinding = input.projectId === undefined ? undefined : (yield* input.client.listRepoBindings(input.projectId)).items.find((binding) => binding.status === "active");
|
|
3240
|
-
const
|
|
3304
|
+
const harnesses = yield* detectHarnesses;
|
|
3305
|
+
const advertisedCapabilities = repoBinding === undefined ? herdrRunnerCapabilities({ harnesses, fullAccess, sandbox: host, shared: !personal }) : herdrRunnerCapabilitiesForRepoBinding(repoBinding, {
|
|
3306
|
+
harnesses,
|
|
3241
3307
|
fullAccess,
|
|
3242
3308
|
sandbox: host,
|
|
3243
3309
|
shared: !personal,
|
|
@@ -3253,11 +3319,12 @@ function startCanonicalHerdrRunnerCommand(input) {
|
|
|
3253
3319
|
accessToken: input.accessToken,
|
|
3254
3320
|
runner: input.runner
|
|
3255
3321
|
});
|
|
3256
|
-
const controlPlane = yield* createHerdrRunnerClient({ apiUrl: input.apiUrl, credential });
|
|
3322
|
+
const controlPlane = yield* createHerdrRunnerClient({ apiUrl: input.apiUrl, runnerId: input.runner.id, credential });
|
|
3257
3323
|
const fs = yield* FileSystem;
|
|
3258
3324
|
const path = yield* Path;
|
|
3259
3325
|
const runnerRootDir = yield* herdrRunnerRootDir;
|
|
3260
3326
|
yield* fs.makeDirectory(path.join(runnerRootDir, ".kitman", "worktrees"), { recursive: true });
|
|
3327
|
+
yield* fs.makeDirectory(bundleCacheDir, { recursive: true });
|
|
3261
3328
|
const replica = yield* controlPlane.client.registerRunnerReplica(input.runner.id, {
|
|
3262
3329
|
name: `replica-${createId()}`,
|
|
3263
3330
|
capacity: { maxConcurrentRuns: concurrency },
|
|
@@ -3266,17 +3333,15 @@ function startCanonicalHerdrRunnerCommand(input) {
|
|
|
3266
3333
|
const backend = herdrExecutorSurface({ runnerId: input.runner.id, session: personal ? "default" : "own" });
|
|
3267
3334
|
const uid = process.getuid?.();
|
|
3268
3335
|
const gid = process.getgid?.();
|
|
3336
|
+
const docker = host.backends.includes("docker") && settings.dockerImage !== undefined ? {
|
|
3337
|
+
containers: yield* dockerContainerRunner,
|
|
3338
|
+
image: settings.dockerImage,
|
|
3339
|
+
...uid === undefined || gid === undefined ? undefined : { user: `${uid}:${gid}` }
|
|
3340
|
+
} : undefined;
|
|
3269
3341
|
const root = herdrAgentBackendLayer({
|
|
3270
3342
|
client: () => backend.executionClient,
|
|
3271
3343
|
sandboxBackends: host.backends,
|
|
3272
|
-
...
|
|
3273
|
-
docker: {
|
|
3274
|
-
containers: yield* dockerContainerRunner,
|
|
3275
|
-
image: settings.dockerImage,
|
|
3276
|
-
runnerId: input.runner.id,
|
|
3277
|
-
...uid === undefined || gid === undefined ? undefined : { user: `${uid}:${gid}` }
|
|
3278
|
-
}
|
|
3279
|
-
} : undefined
|
|
3344
|
+
...docker === undefined ? undefined : { docker: { ...docker, runnerId: input.runner.id } }
|
|
3280
3345
|
}).pipe(provide2(herdrHarnessLayer({ client: () => backend.executionClient })), provide2(layer10));
|
|
3281
3346
|
const activeSlots = new Set;
|
|
3282
3347
|
return yield* gen(function* () {
|
|
@@ -3303,7 +3368,6 @@ function startCanonicalHerdrRunnerCommand(input) {
|
|
|
3303
3368
|
const bundles = yield* kitmanBundles({
|
|
3304
3369
|
fetch: (digest) => rpc.bundle(digest).pipe(map3((found) => found.bundle))
|
|
3305
3370
|
});
|
|
3306
|
-
const runPackageProgram = programProcessExecutor({ bundles, apiUrl: input.apiUrl });
|
|
3307
3371
|
const checkouts = runCheckouts(path.join(runnerRootDir, ".kitman"));
|
|
3308
3372
|
const platform = yield* context();
|
|
3309
3373
|
yield* listenForSignals({
|
|
@@ -3314,6 +3378,21 @@ function startCanonicalHerdrRunnerCommand(input) {
|
|
|
3314
3378
|
reconnectAfter: "2 seconds"
|
|
3315
3379
|
}).pipe(forkScoped);
|
|
3316
3380
|
const authStore = yield* userAuthPath;
|
|
3381
|
+
const runnerState = {
|
|
3382
|
+
workRoot: path.join(runnerRootDir, ".kitman"),
|
|
3383
|
+
bundleCache: path.resolve(bundleCacheDir),
|
|
3384
|
+
kitmanConfigDir: path.dirname(authStore),
|
|
3385
|
+
authStore
|
|
3386
|
+
};
|
|
3387
|
+
const sharedSandbox = personal ? undefined : {
|
|
3388
|
+
runner: runnerState,
|
|
3389
|
+
...docker !== undefined ? { backend: "docker", docker, runnerId: input.runner.id } : { backend: host.backends.includes("srt") ? "srt" : undefined }
|
|
3390
|
+
};
|
|
3391
|
+
const runPackageProgram = programProcessExecutor({
|
|
3392
|
+
bundles,
|
|
3393
|
+
apiUrl: input.apiUrl,
|
|
3394
|
+
...sharedSandbox === undefined ? undefined : { sandbox: sharedSandbox }
|
|
3395
|
+
});
|
|
3317
3396
|
const agentLaunch = (brief, stepCredential) => ({
|
|
3318
3397
|
brief,
|
|
3319
3398
|
stepCredential,
|
|
@@ -3338,7 +3417,7 @@ function startCanonicalHerdrRunnerCommand(input) {
|
|
|
3338
3417
|
},
|
|
3339
3418
|
sandbox: {
|
|
3340
3419
|
backend: work.sandbox ?? sandbox,
|
|
3341
|
-
policy: agentStepSandboxPolicy(work, input.apiUrl,
|
|
3420
|
+
policy: agentStepSandboxPolicy(work, input.apiUrl, runnerState)
|
|
3342
3421
|
},
|
|
3343
3422
|
settled: heartbeatOf(work).pipe(map3((state) => state.settled || state.outputSubmitted === true)),
|
|
3344
3423
|
steering: {
|
|
@@ -3349,7 +3428,8 @@ function startCanonicalHerdrRunnerCommand(input) {
|
|
|
3349
3428
|
});
|
|
3350
3429
|
const runVerification = verificationExecutor({
|
|
3351
3430
|
rootDir: path.join(runnerRootDir, ".kitman"),
|
|
3352
|
-
known: rpcKnownEvidence(rpc)
|
|
3431
|
+
known: rpcKnownEvidence(rpc),
|
|
3432
|
+
...sharedSandbox === undefined ? undefined : { sandbox: { ...sharedSandbox, apiUrl: input.apiUrl } }
|
|
3353
3433
|
});
|
|
3354
3434
|
yield* acquireRelease(backend.start(), () => backend.stop());
|
|
3355
3435
|
const control = (capacitySlot) => ({
|
|
@@ -3414,8 +3494,7 @@ function checkHerdrRunnerReadiness(runner) {
|
|
|
3414
3494
|
function herdrReadinessCode(error) {
|
|
3415
3495
|
const message = error instanceof Error ? error.message : "";
|
|
3416
3496
|
const known = new Set([
|
|
3417
|
-
"
|
|
3418
|
-
"herdr_pi_unavailable",
|
|
3497
|
+
"herdr_platform_unsupported",
|
|
3419
3498
|
"herdr_protocol_mismatch",
|
|
3420
3499
|
"herdr_readiness_timeout",
|
|
3421
3500
|
"herdr_socket_ownership_unknown",
|
|
@@ -3429,7 +3508,7 @@ function mcpCommand(args) {
|
|
|
3429
3508
|
if (command.action === "run") {
|
|
3430
3509
|
if (command.args.length > 0)
|
|
3431
3510
|
return yield* new CliError({ message: `Unknown command: ${args.join(" ")}` });
|
|
3432
|
-
const { runMcpServerCommand } = yield* promise(() => import("./chunk-
|
|
3511
|
+
const { runMcpServerCommand } = yield* promise(() => import("./chunk-eynqc0vm.js"));
|
|
3433
3512
|
return yield* runMcpServerCommand({ flags: command.flags });
|
|
3434
3513
|
}
|
|
3435
3514
|
if (command.action !== "setup")
|
|
@@ -4449,7 +4528,7 @@ function secretCommand(args) {
|
|
|
4449
4528
|
});
|
|
4450
4529
|
}
|
|
4451
4530
|
var PackageBuilder = Reference("kitman/cli/PackageBuilder", {
|
|
4452
|
-
defaultValue: () => (directory) => flatMap(promise(() => import("./chunk-
|
|
4531
|
+
defaultValue: () => (directory) => flatMap(promise(() => import("./chunk-50w9z6we.js")), (build) => build.buildPackage(directory))
|
|
4453
4532
|
});
|
|
4454
4533
|
var optionalEnv = (name) => String3(name).pipe(option2, map3(getOrUndefined));
|
|
4455
4534
|
var ciIdToken = (apiUrl) => gen(function* () {
|
|
@@ -5225,6 +5304,8 @@ function runnerRow(runner) {
|
|
|
5225
5304
|
health: runner.healthStatus,
|
|
5226
5305
|
agentIdentityId: runner.agentIdentityId,
|
|
5227
5306
|
harnesses: runner.capabilities.harnesses.join(","),
|
|
5307
|
+
defaultHarness: runner.capabilities.defaultHarness ?? "",
|
|
5308
|
+
unavailableHarnesses: (runner.capabilities.harnessUnavailable ?? []).map((entry) => `${entry.harness}: ${entry.missing.join(", ")}`).join("; "),
|
|
5228
5309
|
executionBackends: runner.capabilities.executionBackends?.join(",") ?? "",
|
|
5229
5310
|
sandboxes: runner.capabilities.sandboxBackends.join(","),
|
|
5230
5311
|
labels: runner.labels.join(","),
|
|
@@ -5258,6 +5339,8 @@ function runnerDoctorRow(runner) {
|
|
|
5258
5339
|
health: runner.healthStatus,
|
|
5259
5340
|
runs: runner.capabilities.runs?.supported === true,
|
|
5260
5341
|
harnesses: runner.capabilities.harnesses.join(","),
|
|
5342
|
+
defaultHarness: runner.capabilities.defaultHarness ?? "",
|
|
5343
|
+
unavailableHarnesses: (runner.capabilities.harnessUnavailable ?? []).map((entry) => `${entry.harness}: ${entry.missing.join(", ")}`).join("; "),
|
|
5261
5344
|
executionBackends: runner.capabilities.executionBackends?.join(",") ?? "",
|
|
5262
5345
|
sandboxes: runner.capabilities.sandboxBackends.join(","),
|
|
5263
5346
|
agentSteps: runner.capabilities.runs?.stepKinds.includes("agent") === true,
|
|
@@ -5265,6 +5348,10 @@ function runnerDoctorRow(runner) {
|
|
|
5265
5348
|
maxConcurrentRuns: runner.capabilities.resourceLimits?.maxConcurrentRuns
|
|
5266
5349
|
};
|
|
5267
5350
|
}
|
|
5351
|
+
var runnerDoctorRowHere = (runner) => map3(runnerServiceState(runnerServiceName(runner.id)), (service) => ({
|
|
5352
|
+
...runnerDoctorRow(runner),
|
|
5353
|
+
...service === undefined ? undefined : { service }
|
|
5354
|
+
}));
|
|
5268
5355
|
function taskRow(task) {
|
|
5269
5356
|
return {
|
|
5270
5357
|
id: task.id,
|
|
@@ -5342,7 +5429,7 @@ function downloadPresignedAsset(download, outputPath) {
|
|
|
5342
5429
|
return gen(function* () {
|
|
5343
5430
|
const fs = yield* FileSystem;
|
|
5344
5431
|
const failed = (cause) => new CliError({ message: `Asset download failed: ${String(cause)}` });
|
|
5345
|
-
const response = yield* send(
|
|
5432
|
+
const response = yield* send(make13(download.method)(download.url), failed);
|
|
5346
5433
|
if (response.status < 200 || response.status >= 300)
|
|
5347
5434
|
return yield* new CliError({ message: `Asset download failed with ${response.status}` });
|
|
5348
5435
|
const body = yield* response.arrayBuffer.pipe(mapError((error) => failed(error.message)));
|