@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/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.1",
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 rm(directory, { recursive: true, force: true }).then(() => error && error.code !== "ERR_SERVER_NOT_RUNNING" ? reject(error) : resolve10(), reject);
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 { leases, revoked, cloudCredential, deviceCommands } = await link.heartbeat(deviceId, {
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.1",
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.1",
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