@aspectlylabs/mikka 0.0.1 → 0.0.3
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/README.md +20 -4
- package/cli.js +70 -10
- package/client.js +10 -4
- package/http-link.js +10 -4
- package/login.js +10 -4
- package/main.js +209 -145
- package/mikka-mcp.mjs +4 -0
- package/mikka.js +70 -10
- package/package.json +2 -1
- package/paths.js +3 -2
package/mikka-mcp.mjs
CHANGED
|
@@ -137,6 +137,7 @@ const TOOLS = [
|
|
|
137
137
|
},
|
|
138
138
|
spec: SPEC_SCHEMA,
|
|
139
139
|
split: SPLIT_SCHEMA,
|
|
140
|
+
previewDatabaseBranch: { type: "string", description: "Name of the preview database branch you actually created or used; omit when none." },
|
|
140
141
|
criteria: {
|
|
141
142
|
type: "array",
|
|
142
143
|
description:
|
|
@@ -149,6 +150,8 @@ const TOOLS = [
|
|
|
149
150
|
description: "The criterion's id, as given in your brief.",
|
|
150
151
|
},
|
|
151
152
|
passed: { type: "boolean" },
|
|
153
|
+
command: { type: "string", description: "Exact command used to check this criterion, when one was run." },
|
|
154
|
+
exitCode: { type: ["integer", "null"], description: "Observed exit code of that command." },
|
|
152
155
|
evidence: {
|
|
153
156
|
type: "string",
|
|
154
157
|
description:
|
|
@@ -332,6 +335,7 @@ function record(kind, args, toolName) {
|
|
|
332
335
|
: {}),
|
|
333
336
|
...(plan ? { plan } : {}),
|
|
334
337
|
// Kept as sent; the daemon validates and trims each entry.
|
|
338
|
+
...(typeof args.previewDatabaseBranch === "string" ? { previewDatabaseBranch: args.previewDatabaseBranch } : {}),
|
|
335
339
|
...(Array.isArray(args.criteria) ? { criteria: args.criteria } : {}),
|
|
336
340
|
at: new Date().toISOString(),
|
|
337
341
|
}
|
package/mikka.js
CHANGED
|
@@ -2217,7 +2217,7 @@ function closeLogger(logger) {
|
|
|
2217
2217
|
// src/service.ts
|
|
2218
2218
|
import { execFile } from "node:child_process";
|
|
2219
2219
|
import { promisify } from "node:util";
|
|
2220
|
-
import { mkdir, writeFile } from "node:fs/promises";
|
|
2220
|
+
import { mkdir, writeFile, rm } from "node:fs/promises";
|
|
2221
2221
|
import { homedir } from "node:os";
|
|
2222
2222
|
import { dirname as dirname2, join as join2, resolve } from "node:path";
|
|
2223
2223
|
var exec = promisify(execFile);
|
|
@@ -2285,6 +2285,34 @@ async function restartService(update, beforeRestart, dependencies = {
|
|
|
2285
2285
|
beforeRestart();
|
|
2286
2286
|
dependencies.restart();
|
|
2287
2287
|
}
|
|
2288
|
+
async function uninstallService(clearCredential, dependencies = {
|
|
2289
|
+
manager: process.env.MIKKA_SERVICE,
|
|
2290
|
+
home: homedir(),
|
|
2291
|
+
uid: process.getuid?.() ?? 0,
|
|
2292
|
+
run: async (program, args) => {
|
|
2293
|
+
await exec(program, args, { timeout: 1e4 });
|
|
2294
|
+
},
|
|
2295
|
+
exit: () => {
|
|
2296
|
+
process.exit(0);
|
|
2297
|
+
}
|
|
2298
|
+
}) {
|
|
2299
|
+
try {
|
|
2300
|
+
if (dependencies.manager === "systemd") {
|
|
2301
|
+
await dependencies.run("systemctl", ["--user", "disable", "mikka-daemon.service"]);
|
|
2302
|
+
await rm(join2(dependencies.home, ".config/systemd/user/mikka-daemon.service"), { force: true });
|
|
2303
|
+
await dependencies.run("systemctl", ["--user", "daemon-reload"]);
|
|
2304
|
+
} else if (dependencies.manager === "launchd") {
|
|
2305
|
+
await rm(join2(dependencies.home, "Library/LaunchAgents", `${label}.plist`), { force: true });
|
|
2306
|
+
}
|
|
2307
|
+
} finally {
|
|
2308
|
+
clearCredential();
|
|
2309
|
+
try {
|
|
2310
|
+
if (dependencies.manager === "launchd") await dependencies.run("launchctl", ["bootout", `gui/${dependencies.uid}/${label}`]);
|
|
2311
|
+
} finally {
|
|
2312
|
+
dependencies.exit();
|
|
2313
|
+
}
|
|
2314
|
+
}
|
|
2315
|
+
}
|
|
2288
2316
|
|
|
2289
2317
|
// ../protocol/src/accounts.ts
|
|
2290
2318
|
import { z } from "zod";
|
|
@@ -2972,13 +3000,18 @@ var runReport = z9.object({
|
|
|
2972
3000
|
sha: z9.string().regex(/^[a-f0-9]{40}$/),
|
|
2973
3001
|
readOnly: z9.literal(true)
|
|
2974
3002
|
}).optional(),
|
|
3003
|
+
/** Preview branch created or used by the producing run; descriptive metadata only. */
|
|
3004
|
+
previewDatabaseBranch: z9.string().trim().min(1).max(500).optional(),
|
|
2975
3005
|
/** Acceptance criteria the agent checked, with evidence. */
|
|
2976
3006
|
criteria: z9.array(
|
|
2977
3007
|
z9.object({
|
|
2978
3008
|
criterionId: z9.uuid().optional(),
|
|
2979
3009
|
text: z9.string().max(2e3).optional(),
|
|
2980
3010
|
passed: z9.boolean(),
|
|
2981
|
-
evidence: z9.string().max(1e4).optional()
|
|
3011
|
+
evidence: z9.string().max(1e4).optional(),
|
|
3012
|
+
/** Agent-reported criterion check; the daemon-owned verify remains authoritative. */
|
|
3013
|
+
command: z9.string().trim().min(1).max(2e3).optional(),
|
|
3014
|
+
exitCode: z9.number().int().nullable().optional()
|
|
2982
3015
|
})
|
|
2983
3016
|
).max(200).optional(),
|
|
2984
3017
|
/**
|
|
@@ -3322,7 +3355,7 @@ var heartbeatRunSchema = z13.object({
|
|
|
3322
3355
|
/** Last tool call, turn boundary or file change (not raw output). */
|
|
3323
3356
|
lastProgressAt: isoTime
|
|
3324
3357
|
});
|
|
3325
|
-
var deviceManagementCommand = z13.object({ id: z13.uuid(), kind: z13.enum(["redetect", "restart", "update"]) });
|
|
3358
|
+
var deviceManagementCommand = z13.object({ id: z13.uuid(), kind: z13.enum(["redetect", "restart", "update", "uninstall"]) });
|
|
3326
3359
|
var deviceHeartbeatSchema = z13.object({
|
|
3327
3360
|
completedDeviceCommands: z13.array(z13.uuid()).max(100).optional(),
|
|
3328
3361
|
failedDeviceCommands: z13.array(z13.object({ id: z13.uuid(), error: z13.string().max(500) })).max(100).optional(),
|
|
@@ -4249,7 +4282,7 @@ import { join as join3 } from "node:path";
|
|
|
4249
4282
|
// package.json
|
|
4250
4283
|
var package_default = {
|
|
4251
4284
|
name: "@mikka/daemon",
|
|
4252
|
-
version: "0.0.
|
|
4285
|
+
version: "0.0.3",
|
|
4253
4286
|
description: "Local Mikka daemon: runs agents through the user's own CLIs",
|
|
4254
4287
|
type: "module",
|
|
4255
4288
|
private: true,
|
|
@@ -4306,7 +4339,8 @@ var package_default = {
|
|
|
4306
4339
|
},
|
|
4307
4340
|
engines: {
|
|
4308
4341
|
node: ">=24"
|
|
4309
|
-
}
|
|
4342
|
+
},
|
|
4343
|
+
gitHead: "4d1f09bda63e1b86a6cf08c4c7f4dc159b2938a2"
|
|
4310
4344
|
};
|
|
4311
4345
|
|
|
4312
4346
|
// src/paths.ts
|
|
@@ -6194,6 +6228,7 @@ var RunContext = class {
|
|
|
6194
6228
|
nextStep: file.nextStep ?? null,
|
|
6195
6229
|
...file.blockedOn ? { blockedOn: file.blockedOn } : {},
|
|
6196
6230
|
...plan ? { plan } : {},
|
|
6231
|
+
...typeof file.previewDatabaseBranch === "string" ? { previewDatabaseBranch: file.previewDatabaseBranch } : {},
|
|
6197
6232
|
...Array.isArray(file.criteria) ? { criteria: file.criteria } : {},
|
|
6198
6233
|
...runQuestion.safeParse(file.question).success ? { question: runQuestion.parse(file.question) } : {}
|
|
6199
6234
|
};
|
|
@@ -6636,6 +6671,7 @@ import {
|
|
|
6636
6671
|
existsSync as existsSync6,
|
|
6637
6672
|
mkdirSync as mkdirSync15,
|
|
6638
6673
|
readFileSync as readFileSync11,
|
|
6674
|
+
rmSync as rmSync16,
|
|
6639
6675
|
realpathSync as realpathSync11
|
|
6640
6676
|
} from "node:fs";
|
|
6641
6677
|
import { arch, hostname, platform as platform2 } from "node:os";
|
|
@@ -12606,18 +12642,21 @@ function pickAgentReport(agent) {
|
|
|
12606
12642
|
const question = runQuestion.safeParse(agent.question);
|
|
12607
12643
|
if (question.success) picked.question = question.data;
|
|
12608
12644
|
if (agent.plan) picked.plan = agent.plan;
|
|
12645
|
+
if (typeof agent.previewDatabaseBranch === "string" && agent.previewDatabaseBranch.trim())
|
|
12646
|
+
picked.previewDatabaseBranch = agent.previewDatabaseBranch.trim().slice(0, 500);
|
|
12609
12647
|
if (Array.isArray(agent.criteria)) {
|
|
12610
12648
|
const criteria = [];
|
|
12611
12649
|
for (const entry of agent.criteria) {
|
|
12612
12650
|
if (criteria.length >= MAX_REPORTED_CRITERIA) break;
|
|
12613
12651
|
if (!entry || typeof entry !== "object") continue;
|
|
12614
|
-
const { criterionId, passed, evidence } = entry;
|
|
12652
|
+
const { criterionId, passed, evidence, command, exitCode } = entry;
|
|
12615
12653
|
if (typeof criterionId !== "string" || !UUID_RE.test(criterionId))
|
|
12616
12654
|
continue;
|
|
12617
12655
|
if (typeof passed !== "boolean") continue;
|
|
12618
12656
|
criteria.push({
|
|
12619
12657
|
criterionId,
|
|
12620
12658
|
passed,
|
|
12659
|
+
...typeof command === "string" && command.trim() ? { command: command.trim().slice(0, 2e3), ...exitCode === null || typeof exitCode === "number" && Number.isSafeInteger(exitCode) ? { exitCode } : {} } : {},
|
|
12621
12660
|
...typeof evidence === "string" ? { evidence: evidence.slice(0, 1e4) } : {}
|
|
12622
12661
|
});
|
|
12623
12662
|
}
|
|
@@ -12790,7 +12829,7 @@ import { promisify as promisify4 } from "node:util";
|
|
|
12790
12829
|
|
|
12791
12830
|
// src/agents/public-egress.ts
|
|
12792
12831
|
import { lookup } from "node:dns/promises";
|
|
12793
|
-
import { chmod, mkdtemp, rm } from "node:fs/promises";
|
|
12832
|
+
import { chmod, mkdtemp, rm as rm2 } from "node:fs/promises";
|
|
12794
12833
|
import { createServer as createServer3, request as httpRequest } from "node:http";
|
|
12795
12834
|
import { connect, isIP as isIP3 } from "node:net";
|
|
12796
12835
|
import { tmpdir as tmpdir3 } from "node:os";
|
|
@@ -12972,7 +13011,7 @@ async function startPublicEgress(options) {
|
|
|
12972
13011
|
for (const socket of sockets) socket.destroy();
|
|
12973
13012
|
closing = new Promise((resolve10, reject) => server.close((error) => {
|
|
12974
13013
|
options.signal.removeEventListener("abort", onAbort);
|
|
12975
|
-
void
|
|
13014
|
+
void rm2(directory, { recursive: true, force: true }).then(() => error && error.code !== "ERR_SERVER_NOT_RUNNING" ? reject(error) : resolve10(), reject);
|
|
12976
13015
|
}));
|
|
12977
13016
|
return closing;
|
|
12978
13017
|
};
|
|
@@ -14778,7 +14817,7 @@ var Daemon = class {
|
|
|
14778
14817
|
}
|
|
14779
14818
|
const deviceId = this.device.deviceId;
|
|
14780
14819
|
const quotas = this.quota?.snapshot().quotas;
|
|
14781
|
-
const
|
|
14820
|
+
const heartbeat = {
|
|
14782
14821
|
completedDeviceCommands: this.device.completedDeviceCommands,
|
|
14783
14822
|
failedDeviceCommands: this.device.failedDeviceCommands,
|
|
14784
14823
|
harnesses: this.harnesses,
|
|
@@ -14786,7 +14825,8 @@ var Daemon = class {
|
|
|
14786
14825
|
runs: this.supervisor.heartbeatRuns(),
|
|
14787
14826
|
worktreeDiskBytes: await this.worktrees.diskUsage(),
|
|
14788
14827
|
...quotas ? { quotas } : {}
|
|
14789
|
-
}
|
|
14828
|
+
};
|
|
14829
|
+
const { leases, revoked, cloudCredential, deviceCommands } = await link.heartbeat(deviceId, heartbeat);
|
|
14790
14830
|
this.supervisor.renewLeases(leases);
|
|
14791
14831
|
if (revoked) this.supervisor.revokeLeases(revoked);
|
|
14792
14832
|
if (this.options.cloudComputer && cloudCredential && this.device.credential === credential) {
|
|
@@ -14795,6 +14835,26 @@ var Daemon = class {
|
|
|
14795
14835
|
this.registered = false;
|
|
14796
14836
|
}
|
|
14797
14837
|
const command = deviceCommands?.[0];
|
|
14838
|
+
if (command?.kind === "uninstall") {
|
|
14839
|
+
this.draining = true;
|
|
14840
|
+
if (this.supervisor.heartbeatRuns().length === 0) {
|
|
14841
|
+
this.saveDevice({ completedDeviceCommands: [command.id], failedDeviceCommands: [] });
|
|
14842
|
+
try {
|
|
14843
|
+
await link.heartbeat(deviceId, { ...heartbeat, runs: [], completedDeviceCommands: [command.id], failedDeviceCommands: [] });
|
|
14844
|
+
} catch {
|
|
14845
|
+
this.log.warn("Could not confirm uninstall receipt");
|
|
14846
|
+
}
|
|
14847
|
+
setImmediate(() => {
|
|
14848
|
+
void this.stop().then(() => uninstallService(() => {
|
|
14849
|
+
this.saveDevice({ credential: void 0 });
|
|
14850
|
+
rmSync16(this.paths.secret, { force: true });
|
|
14851
|
+
})).catch(() => {
|
|
14852
|
+
this.options.onDrained?.();
|
|
14853
|
+
});
|
|
14854
|
+
});
|
|
14855
|
+
}
|
|
14856
|
+
return;
|
|
14857
|
+
}
|
|
14798
14858
|
if (command && !this.device.completedDeviceCommands?.includes(command.id) && !this.device.failedDeviceCommands?.some((failure) => failure.id === command.id)) {
|
|
14799
14859
|
if (command.kind === "redetect" || this.supervisor.heartbeatRuns().length === 0) {
|
|
14800
14860
|
try {
|
package/package.json
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aspectlylabs/mikka",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.3",
|
|
4
4
|
"description": "Local Mikka daemon: runs agents through the user's own CLIs",
|
|
5
|
+
"gitHead": "4d1f09bda63e1b86a6cf08c4c7f4dc159b2938a2",
|
|
5
6
|
"type": "module",
|
|
6
7
|
"private": false,
|
|
7
8
|
"license": "AGPL-3.0-only",
|
package/paths.js
CHANGED
|
@@ -6,7 +6,7 @@ import { join } from "node:path";
|
|
|
6
6
|
// package.json
|
|
7
7
|
var package_default = {
|
|
8
8
|
name: "@mikka/daemon",
|
|
9
|
-
version: "0.0.
|
|
9
|
+
version: "0.0.3",
|
|
10
10
|
description: "Local Mikka daemon: runs agents through the user's own CLIs",
|
|
11
11
|
type: "module",
|
|
12
12
|
private: true,
|
|
@@ -63,7 +63,8 @@ var package_default = {
|
|
|
63
63
|
},
|
|
64
64
|
engines: {
|
|
65
65
|
node: ">=24"
|
|
66
|
-
}
|
|
66
|
+
},
|
|
67
|
+
gitHead: "4d1f09bda63e1b86a6cf08c4c7f4dc159b2938a2"
|
|
67
68
|
};
|
|
68
69
|
|
|
69
70
|
// src/paths.ts
|