zam-core 0.10.1 → 0.10.2

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/cli/app.js CHANGED
@@ -5481,20 +5481,20 @@ import { homedir as homedir5 } from "os";
5481
5481
  import { join as join8 } from "path";
5482
5482
  import { fileURLToPath } from "url";
5483
5483
  function getPackageSkillPath(agent = "default") {
5484
- const packageRoot2 = [
5484
+ const packageRoot3 = [
5485
5485
  fileURLToPath(new URL("../../..", import.meta.url)),
5486
5486
  fileURLToPath(new URL("../..", import.meta.url)),
5487
5487
  fileURLToPath(new URL("..", import.meta.url))
5488
5488
  ].find((candidate) => existsSync7(join8(candidate, "package.json"))) ?? "";
5489
- if (!packageRoot2) return "";
5489
+ if (!packageRoot3) return "";
5490
5490
  if (agent === "codex") {
5491
- const codexPath = join8(packageRoot2, ".agents", "skills", "zam", "SKILL.md");
5491
+ const codexPath = join8(packageRoot3, ".agents", "skills", "zam", "SKILL.md");
5492
5492
  if (existsSync7(codexPath)) return codexPath;
5493
5493
  return "";
5494
5494
  }
5495
5495
  if (agent === "claude") {
5496
5496
  const claudePath = join8(
5497
- packageRoot2,
5497
+ packageRoot3,
5498
5498
  ".claude",
5499
5499
  "skills",
5500
5500
  "zam",
@@ -5503,9 +5503,9 @@ function getPackageSkillPath(agent = "default") {
5503
5503
  if (existsSync7(claudePath)) return claudePath;
5504
5504
  return "";
5505
5505
  }
5506
- let path = join8(packageRoot2, ".agent", "skills", "zam", "SKILL.md");
5506
+ let path = join8(packageRoot3, ".agent", "skills", "zam", "SKILL.md");
5507
5507
  if (existsSync7(path)) return path;
5508
- path = join8(packageRoot2, ".claude", "skills", "zam", "SKILL.md");
5508
+ path = join8(packageRoot3, ".claude", "skills", "zam", "SKILL.md");
5509
5509
  if (existsSync7(path)) return path;
5510
5510
  return "";
5511
5511
  }
@@ -6808,16 +6808,16 @@ var init_kernel = __esm({
6808
6808
  });
6809
6809
 
6810
6810
  // src/cli/app.ts
6811
- import { readFileSync as readFileSync18 } from "fs";
6812
- import { dirname as dirname12, join as join27 } from "path";
6813
- import { fileURLToPath as fileURLToPath6 } from "url";
6811
+ import { readFileSync as readFileSync19 } from "fs";
6812
+ import { dirname as dirname13, join as join28 } from "path";
6813
+ import { fileURLToPath as fileURLToPath7 } from "url";
6814
6814
  import { Command as Command27 } from "commander";
6815
6815
 
6816
6816
  // src/cli/commands/agent.ts
6817
6817
  init_kernel();
6818
- import { existsSync as existsSync13, mkdirSync as mkdirSync8, writeFileSync as writeFileSync7 } from "fs";
6819
- import { homedir as homedir9 } from "os";
6820
- import { dirname as dirname5, join as join13 } from "path";
6818
+ import { existsSync as existsSync14, mkdirSync as mkdirSync9, writeFileSync as writeFileSync8 } from "fs";
6819
+ import { homedir as homedir10 } from "os";
6820
+ import { dirname as dirname6, join as join14 } from "path";
6821
6821
  import { Command } from "commander";
6822
6822
 
6823
6823
  // src/cli/agent-harness.ts
@@ -7286,8 +7286,11 @@ ${zamExtension}
7286
7286
  `;
7287
7287
  }
7288
7288
  } else if (harnessId === "copilot") {
7289
- targetPath = join12(opts.home, ".copilot", "mcp-config.json");
7290
- hint = "GitHub Copilot CLI will load the 'zam' MCP server on next session. Use '/mcp show' in Copilot CLI to verify.";
7289
+ targetPath = join12(
7290
+ opts.copilotHome ?? join12(opts.home, ".copilot"),
7291
+ "mcp-config.json"
7292
+ );
7293
+ hint = "Restart GitHub Copilot or start a new session to load the 'zam' MCP server and its Studio, Recall, Graph, and Settings canvases.";
7291
7294
  let existing = {};
7292
7295
  if (exists(targetPath)) {
7293
7296
  existing = parseMcpJsonConfig(targetPath, read(targetPath));
@@ -7311,6 +7314,121 @@ ${zamExtension}
7311
7314
  };
7312
7315
  }
7313
7316
 
7317
+ // src/cli/copilot-extension.ts
7318
+ import {
7319
+ existsSync as existsSync13,
7320
+ lstatSync,
7321
+ mkdirSync as mkdirSync8,
7322
+ readFileSync as readFileSync10,
7323
+ writeFileSync as writeFileSync7
7324
+ } from "fs";
7325
+ import { homedir as homedir9 } from "os";
7326
+ import { dirname as dirname5, join as join13, resolve as resolve3 } from "path";
7327
+ import { fileURLToPath as fileURLToPath2 } from "url";
7328
+ var EXTENSION_NAME = "zam-mcp-apps";
7329
+ var EXTENSION_FILES = [
7330
+ "extension.mjs",
7331
+ "host.bundle.js",
7332
+ "mcp-client.bundle.mjs",
7333
+ "manifest.json"
7334
+ ];
7335
+ var packageRoot = [
7336
+ fileURLToPath2(new URL("../..", import.meta.url)),
7337
+ fileURLToPath2(new URL("../../..", import.meta.url))
7338
+ ].find((candidate) => existsSync13(join13(candidate, "package.json"))) ?? fileURLToPath2(new URL("../..", import.meta.url));
7339
+ function defaultCliEntry() {
7340
+ return join13(dirname5(fileURLToPath2(import.meta.url)), "index.js");
7341
+ }
7342
+ function resolveCopilotHome(home = homedir9(), configuredHome = process.env.COPILOT_HOME) {
7343
+ return configuredHome?.trim() ? resolve3(configuredHome) : join13(home, ".copilot");
7344
+ }
7345
+ function resolveCopilotZamLaunch(zamPath, options = {}) {
7346
+ const cliEntry = options.cliEntry ?? defaultCliEntry();
7347
+ if (existsSync13(cliEntry)) {
7348
+ return {
7349
+ command: options.nodePath ?? process.execPath,
7350
+ args: [cliEntry, "mcp"]
7351
+ };
7352
+ }
7353
+ return {
7354
+ command: zamPath,
7355
+ args: ["mcp"]
7356
+ };
7357
+ }
7358
+ function planCopilotExtensionInstall(options) {
7359
+ const sourceDir = options.assetsDir ?? join13(packageRoot, "dist", "copilot-extension");
7360
+ for (const file of EXTENSION_FILES) {
7361
+ if (!existsSync13(join13(sourceDir, file))) {
7362
+ throw new Error(
7363
+ `Copilot MCP Apps asset is missing: ${join13(sourceDir, file)}. Run \`npm run build\` and retry.`
7364
+ );
7365
+ }
7366
+ }
7367
+ const manifest = JSON.parse(
7368
+ readFileSync10(join13(sourceDir, "manifest.json"), "utf8")
7369
+ );
7370
+ if (manifest.name !== EXTENSION_NAME || typeof manifest.version !== "string" || !manifest.version) {
7371
+ throw new Error(
7372
+ `Invalid Copilot MCP Apps manifest: ${join13(sourceDir, "manifest.json")}`
7373
+ );
7374
+ }
7375
+ const copilotHome = resolveCopilotHome(
7376
+ options.home,
7377
+ options.copilotHome ?? process.env.COPILOT_HOME
7378
+ );
7379
+ return {
7380
+ sourceDir,
7381
+ destinationDir: join13(copilotHome, "extensions", EXTENSION_NAME),
7382
+ launch: resolveCopilotZamLaunch(options.zamPath, options),
7383
+ files: EXTENSION_FILES
7384
+ };
7385
+ }
7386
+ function writeIfChanged(path, content) {
7387
+ const next = Buffer.isBuffer(content) ? content : Buffer.from(content);
7388
+ if (existsSync13(path) && readFileSync10(path).equals(next)) return false;
7389
+ writeFileSync7(path, next);
7390
+ return true;
7391
+ }
7392
+ function installCopilotExtension(options) {
7393
+ const plan = planCopilotExtensionInstall(options);
7394
+ if (options.dryRun) {
7395
+ return { ...plan, action: "planned", changedFiles: [] };
7396
+ }
7397
+ const destinationExisted = existsSync13(plan.destinationDir);
7398
+ if (destinationExisted && lstatSync(plan.destinationDir).isSymbolicLink()) {
7399
+ throw new Error(
7400
+ `Refusing to replace symlinked Copilot extension directory: ${plan.destinationDir}`
7401
+ );
7402
+ }
7403
+ mkdirSync8(plan.destinationDir, { recursive: true });
7404
+ const changedFiles = [];
7405
+ for (const file of plan.files) {
7406
+ const source = join13(plan.sourceDir, file);
7407
+ const destination = join13(plan.destinationDir, file);
7408
+ if (writeIfChanged(destination, readFileSync10(source))) {
7409
+ changedFiles.push(file);
7410
+ }
7411
+ }
7412
+ const launchContent = `${JSON.stringify(
7413
+ {
7414
+ schemaVersion: 1,
7415
+ command: plan.launch.command,
7416
+ args: plan.launch.args
7417
+ },
7418
+ null,
7419
+ 2
7420
+ )}
7421
+ `;
7422
+ if (writeIfChanged(join13(plan.destinationDir, "launch.json"), launchContent)) {
7423
+ changedFiles.push("launch.json");
7424
+ }
7425
+ return {
7426
+ ...plan,
7427
+ action: !destinationExisted ? "installed" : changedFiles.length > 0 ? "updated" : "unchanged",
7428
+ changedFiles
7429
+ };
7430
+ }
7431
+
7314
7432
  // src/cli/commands/agent.ts
7315
7433
  var C = {
7316
7434
  reset: "\x1B[0m",
@@ -7334,7 +7452,7 @@ function isConnectHarnessId(value) {
7334
7452
  return CONNECT_HARNESSES.includes(value);
7335
7453
  }
7336
7454
  function agentsMdPresent(cwd = process.cwd()) {
7337
- return existsSync13(join13(cwd, "AGENTS.md"));
7455
+ return existsSync14(join14(cwd, "AGENTS.md"));
7338
7456
  }
7339
7457
  function printStatus() {
7340
7458
  const installed = hasCommand("opencode");
@@ -7465,7 +7583,8 @@ var connectCmd = new Command("connect").description("Configure the ZAM MCP serve
7465
7583
  result = connectHarnessMcp(harnessArg, {
7466
7584
  zamPath,
7467
7585
  cwd: process.cwd(),
7468
- home: homedir9()
7586
+ home: homedir10(),
7587
+ copilotHome: process.env.COPILOT_HOME
7469
7588
  });
7470
7589
  } catch (error) {
7471
7590
  console.error(
@@ -7473,24 +7592,56 @@ var connectCmd = new Command("connect").description("Configure the ZAM MCP serve
7473
7592
  );
7474
7593
  process.exit(1);
7475
7594
  }
7595
+ let copilotExtension;
7596
+ if (harnessArg === "copilot") {
7597
+ try {
7598
+ copilotExtension = installCopilotExtension({
7599
+ home: homedir10(),
7600
+ zamPath,
7601
+ dryRun: Boolean(opts.print)
7602
+ });
7603
+ } catch (error) {
7604
+ console.error(
7605
+ `Error preparing Copilot MCP Apps extension: ${error instanceof Error ? error.message : String(error)}`
7606
+ );
7607
+ process.exit(1);
7608
+ }
7609
+ }
7476
7610
  if (opts.print) {
7477
7611
  console.log(`Path: ${result.path}`);
7478
7612
  console.log(`Content:
7479
7613
  ${result.content}`);
7614
+ if (copilotExtension) {
7615
+ console.log(`Extension: ${copilotExtension.destinationDir}`);
7616
+ console.log(
7617
+ `Launch: ${copilotExtension.launch.command} ${copilotExtension.launch.args.join(" ")}`
7618
+ );
7619
+ }
7480
7620
  return;
7481
7621
  }
7482
7622
  if (result.alreadyConfigured) {
7483
7623
  console.log(
7484
7624
  `${C.green}\u2713${C.reset} MCP server 'zam' already configured in ${result.path}`
7485
7625
  );
7626
+ if (copilotExtension) {
7627
+ console.log(
7628
+ `${C.green}\u2713${C.reset} MCP Apps extension ${copilotExtension.action} at ${copilotExtension.destinationDir}`
7629
+ );
7630
+ }
7631
+ console.log(` ${C.dim}${result.hint}${C.reset}`);
7486
7632
  return;
7487
7633
  }
7488
7634
  try {
7489
- mkdirSync8(dirname5(result.path), { recursive: true });
7490
- writeFileSync7(result.path, result.content, "utf-8");
7635
+ mkdirSync9(dirname6(result.path), { recursive: true });
7636
+ writeFileSync8(result.path, result.content, "utf-8");
7491
7637
  console.log(
7492
7638
  `${C.green}\u2713${C.reset} Wrote MCP configuration to ${result.path}`
7493
7639
  );
7640
+ if (copilotExtension) {
7641
+ console.log(
7642
+ `${C.green}\u2713${C.reset} MCP Apps extension ${copilotExtension.action} at ${copilotExtension.destinationDir}`
7643
+ );
7644
+ }
7494
7645
  console.log(` ${C.dim}${result.hint}${C.reset}`);
7495
7646
  } catch (error) {
7496
7647
  console.error(
@@ -7505,9 +7656,9 @@ var agentCommand = new Command("agent").description("Provision and inspect the a
7505
7656
  init_kernel();
7506
7657
  import { execFileSync as execFileSync3 } from "child_process";
7507
7658
  import { randomBytes as randomBytes2 } from "crypto";
7508
- import { existsSync as existsSync17, readdirSync as readdirSync2, readFileSync as readFileSync14, rmSync as rmSync3 } from "fs";
7509
- import { homedir as homedir11, tmpdir as tmpdir3 } from "os";
7510
- import { join as join20, resolve as resolve4 } from "path";
7659
+ import { existsSync as existsSync18, readdirSync as readdirSync2, readFileSync as readFileSync15, rmSync as rmSync3 } from "fs";
7660
+ import { homedir as homedir12, tmpdir as tmpdir3 } from "os";
7661
+ import { join as join21, resolve as resolve5 } from "path";
7511
7662
  import { Command as Command2 } from "commander";
7512
7663
  import { ulid as ulid9 } from "ulid";
7513
7664
 
@@ -7518,7 +7669,7 @@ import fs from "fs";
7518
7669
  // src/cli/llm/client.ts
7519
7670
  init_kernel();
7520
7671
  import { spawn as spawn2 } from "child_process";
7521
- import { existsSync as existsSync14, readFileSync as readFileSync10, statSync as statSync2 } from "fs";
7672
+ import { existsSync as existsSync15, readFileSync as readFileSync11, statSync as statSync2 } from "fs";
7522
7673
  var DEFAULT_LLM_URL = "http://localhost:8000/v1";
7523
7674
  var DEFAULT_LLM_MAX_TOKENS = 1e4;
7524
7675
  var RECALL_QUESTION_MAX_OUTPUT_TOKENS = 400;
@@ -8234,7 +8385,7 @@ async function extractTextFromScanViaLLM(db, imagePath) {
8234
8385
  "Vision role is not enabled in settings (llm.vision.enabled)"
8235
8386
  );
8236
8387
  }
8237
- if (!existsSync14(imagePath)) {
8388
+ if (!existsSync15(imagePath)) {
8238
8389
  throw new Error(`Scan file not found: ${imagePath}`);
8239
8390
  }
8240
8391
  const stat = statSync2(imagePath);
@@ -8255,7 +8406,7 @@ async function extractTextFromScanViaLLM(db, imagePath) {
8255
8406
  if (!mime) {
8256
8407
  throw new Error("Unsupported scan format; use PNG, JPEG, or WebP");
8257
8408
  }
8258
- const imageBytes = readFileSync10(imagePath);
8409
+ const imageBytes = readFileSync11(imagePath);
8259
8410
  const dataUrl = `data:${mime};base64,${imageBytes.toString("base64")}`;
8260
8411
  const visionEndpoint = await getVisionConfig(db);
8261
8412
  const langName = LANGUAGE_NAMES[p.locale] || "English";
@@ -8472,7 +8623,7 @@ async function prepareRecallChain(db, opts) {
8472
8623
  } else {
8473
8624
  spawnLocalRunner(endpoint.url, endpoint.model, endpoint.runner);
8474
8625
  while (Date.now() < deadline) {
8475
- await new Promise((resolve10) => setTimeout(resolve10, 1e3));
8626
+ await new Promise((resolve11) => setTimeout(resolve11, 1e3));
8476
8627
  if (await isLlmOnline(endpoint.url)) {
8477
8628
  online = true;
8478
8629
  break;
@@ -8687,7 +8838,7 @@ function spawnLocalRunner(url, model, hint) {
8687
8838
  const { runner, port } = detectRunner(url, model, hint);
8688
8839
  try {
8689
8840
  if (runner === "fastflowlm") {
8690
- const flmExe = existsSync14("C:\\Program Files\\flm\\flm.exe") ? "C:\\Program Files\\flm\\flm.exe" : "flm";
8841
+ const flmExe = existsSync15("C:\\Program Files\\flm\\flm.exe") ? "C:\\Program Files\\flm\\flm.exe" : "flm";
8691
8842
  if (!hasCommand("flm") && flmExe === "flm") return;
8692
8843
  spawn2(flmExe, ["serve", model, "--port", port], {
8693
8844
  detached: true,
@@ -8708,7 +8859,7 @@ function spawnLocalRunner(url, model, hint) {
8708
8859
  async function startLocalRunner(url, model, locale, hint) {
8709
8860
  const { runner, port } = detectRunner(url, model, hint);
8710
8861
  if (runner === "fastflowlm") {
8711
- const flmExe = existsSync14("C:\\Program Files\\flm\\flm.exe") ? "C:\\Program Files\\flm\\flm.exe" : "flm";
8862
+ const flmExe = existsSync15("C:\\Program Files\\flm\\flm.exe") ? "C:\\Program Files\\flm\\flm.exe" : "flm";
8712
8863
  if (!hasCommand("flm") && flmExe === "flm") {
8713
8864
  console.warn(
8714
8865
  "\x1B[31m\u2717 FastFlowLM is configured but could not be found on the system.\x1B[0m"
@@ -8765,7 +8916,7 @@ async function startLocalRunner(url, model, locale, hint) {
8765
8916
  let attempts = 0;
8766
8917
  const dotsPerLine = 30;
8767
8918
  while (true) {
8768
- await new Promise((resolve10) => setTimeout(resolve10, 500));
8919
+ await new Promise((resolve11) => setTimeout(resolve11, 500));
8769
8920
  if (await isLlmOnline(url)) {
8770
8921
  if (attempts > 0) process.stdout.write("\n");
8771
8922
  return true;
@@ -8854,8 +9005,8 @@ async function fetchWithInteractiveTimeout(url, options = {}) {
8854
9005
  const dotsPerLine = 30;
8855
9006
  while (true) {
8856
9007
  let timeoutId;
8857
- const timeoutPromise = new Promise((resolve10) => {
8858
- timeoutId = setTimeout(() => resolve10("timeout"), timeoutMs);
9008
+ const timeoutPromise = new Promise((resolve11) => {
9009
+ timeoutId = setTimeout(() => resolve11("timeout"), timeoutMs);
8859
9010
  });
8860
9011
  const dotsInterval = setInterval(() => {
8861
9012
  process.stdout.write(".");
@@ -9187,8 +9338,8 @@ async function readImageOCR(db, imagePath) {
9187
9338
 
9188
9339
  // src/cli/bridge-handlers.ts
9189
9340
  init_kernel();
9190
- import { mkdirSync as mkdirSync10, writeFileSync as writeFileSync8 } from "fs";
9191
- import { join as join16 } from "path";
9341
+ import { mkdirSync as mkdirSync11, writeFileSync as writeFileSync9 } from "fs";
9342
+ import { join as join17 } from "path";
9192
9343
 
9193
9344
  // src/cli/knowledge-contexts.ts
9194
9345
  init_kernel();
@@ -9435,16 +9586,16 @@ async function resolveSuggestMinSimilarity(db) {
9435
9586
  }
9436
9587
 
9437
9588
  // src/cli/update/latest-version.ts
9438
- import { readFileSync as readFileSync11 } from "fs";
9439
- import { dirname as dirname6, join as join14 } from "path";
9440
- import { fileURLToPath as fileURLToPath2 } from "url";
9589
+ import { readFileSync as readFileSync12 } from "fs";
9590
+ import { dirname as dirname7, join as join15 } from "path";
9591
+ import { fileURLToPath as fileURLToPath3 } from "url";
9441
9592
  var GITHUB_REPO = "zam-os/zam";
9442
9593
  function currentVersion() {
9443
- const here = dirname6(fileURLToPath2(import.meta.url));
9594
+ const here = dirname7(fileURLToPath3(import.meta.url));
9444
9595
  for (const up of ["..", "../..", "../../.."]) {
9445
9596
  try {
9446
9597
  const pkg2 = JSON.parse(
9447
- readFileSync11(join14(here, up, "package.json"), "utf-8")
9598
+ readFileSync12(join15(here, up, "package.json"), "utf-8")
9448
9599
  );
9449
9600
  if (pkg2.version) return pkg2.version;
9450
9601
  } catch {
@@ -9474,16 +9625,16 @@ async function fetchLatestVersion(repo) {
9474
9625
 
9475
9626
  // src/cli/workspaces/active.ts
9476
9627
  init_kernel();
9477
- import { existsSync as existsSync15, mkdirSync as mkdirSync9 } from "fs";
9478
- import { homedir as homedir10 } from "os";
9479
- import { basename as basename3, join as join15, resolve as resolve3 } from "path";
9628
+ import { existsSync as existsSync16, mkdirSync as mkdirSync10 } from "fs";
9629
+ import { homedir as homedir11 } from "os";
9630
+ import { basename as basename3, join as join16, resolve as resolve4 } from "path";
9480
9631
  var LEGACY_WORKSPACE_DIR_KEY = "personal.workspace_dir";
9481
9632
  var DEFAULT_WORKSPACE_ID = "personal";
9482
9633
  function defaultWorkspaceDir() {
9483
- return join15(homedir10(), "Documents", "zam");
9634
+ return join16(homedir11(), "Documents", "zam");
9484
9635
  }
9485
9636
  function normalizeWorkspacePath(path) {
9486
- const resolved = resolve3(path);
9637
+ const resolved = resolve4(path);
9487
9638
  return process.platform === "win32" ? resolved.toLowerCase() : resolved;
9488
9639
  }
9489
9640
  function sameWorkspacePath(left, right) {
@@ -9512,7 +9663,7 @@ async function clearLegacyWorkspaceDir(db) {
9512
9663
  async function migrateLegacyWorkspaceDir(db) {
9513
9664
  const legacyDir = await getSetting(db, LEGACY_WORKSPACE_DIR_KEY);
9514
9665
  if (!legacyDir) return void 0;
9515
- const path = resolve3(legacyDir);
9666
+ const path = resolve4(legacyDir);
9516
9667
  const existing = findWorkspaceByPath(path);
9517
9668
  const migrated = existing ?? {
9518
9669
  id: getConfiguredWorkspaces().some(
@@ -9535,13 +9686,13 @@ async function ensureActiveWorkspace(db) {
9535
9686
  await migrateLegacyWorkspaceDir(db);
9536
9687
  const active = getActiveWorkspace();
9537
9688
  if (active) {
9538
- mkdirSync9(active.path, { recursive: true });
9689
+ mkdirSync10(active.path, { recursive: true });
9539
9690
  return active;
9540
9691
  }
9541
9692
  const configured = getConfiguredWorkspaces()[0];
9542
9693
  if (configured) {
9543
9694
  setActiveWorkspaceId(configured.id);
9544
- mkdirSync9(configured.path, { recursive: true });
9695
+ mkdirSync10(configured.path, { recursive: true });
9545
9696
  return configured;
9546
9697
  }
9547
9698
  const workspace = {
@@ -9550,7 +9701,7 @@ async function ensureActiveWorkspace(db) {
9550
9701
  kind: "personal",
9551
9702
  path: defaultWorkspaceDir()
9552
9703
  };
9553
- mkdirSync9(workspace.path, { recursive: true });
9704
+ mkdirSync10(workspace.path, { recursive: true });
9554
9705
  upsertConfiguredWorkspace(workspace);
9555
9706
  setActiveWorkspaceId(workspace.id);
9556
9707
  await clearLegacyWorkspaceDir(db);
@@ -9564,7 +9715,7 @@ async function activateWorkspace(db, workspace) {
9564
9715
  }
9565
9716
  async function activateWorkspacePath(db, dir, opts = {}) {
9566
9717
  await migrateLegacyWorkspaceDir(db);
9567
- const path = resolve3(dir);
9718
+ const path = resolve4(dir);
9568
9719
  const existing = opts.id ? void 0 : findWorkspaceByPath(path);
9569
9720
  if (existing) {
9570
9721
  setActiveWorkspaceId(existing.id);
@@ -9589,7 +9740,7 @@ async function removeWorkspaceAndResolveActive(db, id) {
9589
9740
  };
9590
9741
  }
9591
9742
  function existingWorkspaceDirOrHome(workspace) {
9592
- return existsSync15(workspace.path) ? workspace.path : homedir10();
9743
+ return existsSync16(workspace.path) ? workspace.path : homedir11();
9593
9744
  }
9594
9745
 
9595
9746
  // src/cli/bridge-handlers.ts
@@ -10361,11 +10512,11 @@ async function backupCreate(db, params) {
10361
10512
  const targetDir = params.dir || (await ensureActiveWorkspace(db)).path;
10362
10513
  const snapshot = await exportSnapshot(db);
10363
10514
  const manifest = verifySnapshot(snapshot);
10364
- const backupDir = join16(targetDir, "zam-backups");
10365
- mkdirSync10(backupDir, { recursive: true });
10515
+ const backupDir = join17(targetDir, "zam-backups");
10516
+ mkdirSync11(backupDir, { recursive: true });
10366
10517
  const stamp = manifest.createdAt.replace(/[:.]/g, "-");
10367
- const path = join16(backupDir, `zam-snapshot-${stamp}.sql`);
10368
- writeFileSync8(path, snapshot, "utf-8");
10518
+ const path = join17(backupDir, `zam-snapshot-${stamp}.sql`);
10519
+ writeFileSync9(path, snapshot, "utf-8");
10369
10520
  return {
10370
10521
  ok: true,
10371
10522
  path,
@@ -13050,9 +13201,9 @@ function getCurriculumProvider(id) {
13050
13201
  // src/cli/llm/vision.ts
13051
13202
  init_kernel();
13052
13203
  import { randomBytes } from "crypto";
13053
- import { readFileSync as readFileSync12 } from "fs";
13204
+ import { readFileSync as readFileSync13 } from "fs";
13054
13205
  import { tmpdir as tmpdir2 } from "os";
13055
- import { basename as basename4, join as join17 } from "path";
13206
+ import { basename as basename4, join as join18 } from "path";
13056
13207
  var LANGUAGE_NAMES2 = {
13057
13208
  en: "English",
13058
13209
  de: "German",
@@ -13088,13 +13239,13 @@ async function observeUiSnapshotViaLLM(db, input8) {
13088
13239
  const imageUrls = [];
13089
13240
  const isVideo = /\.(mp4|mov|m4v|avi|mkv|webm)$/i.test(input8.imagePath);
13090
13241
  if (isVideo) {
13091
- const { mkdirSync: mkdirSync16, readdirSync: readdirSync3, rmSync: rmSync4 } = await import("fs");
13242
+ const { mkdirSync: mkdirSync17, readdirSync: readdirSync3, rmSync: rmSync4 } = await import("fs");
13092
13243
  const { execSync: execSync6 } = await import("child_process");
13093
- const tempDir = join17(
13244
+ const tempDir = join18(
13094
13245
  tmpdir2(),
13095
13246
  `zam-frames-${randomBytes(4).toString("hex")}`
13096
13247
  );
13097
- mkdirSync16(tempDir, { recursive: true });
13248
+ mkdirSync17(tempDir, { recursive: true });
13098
13249
  try {
13099
13250
  execSync6(
13100
13251
  `ffmpeg -i "${input8.imagePath}" -vf "fps=1/3,scale=1280:-1" -vsync vfr "${tempDir}/frame_%03d.png"`,
@@ -13123,7 +13274,7 @@ async function observeUiSnapshotViaLLM(db, input8) {
13123
13274
  }
13124
13275
  }
13125
13276
  for (const file of sampledFiles) {
13126
- const bytes = readFileSync12(join17(tempDir, file));
13277
+ const bytes = readFileSync13(join18(tempDir, file));
13127
13278
  imageUrls.push(`data:image/png;base64,${bytes.toString("base64")}`);
13128
13279
  }
13129
13280
  } finally {
@@ -13133,7 +13284,7 @@ async function observeUiSnapshotViaLLM(db, input8) {
13133
13284
  }
13134
13285
  }
13135
13286
  } else {
13136
- const imageBytes = readFileSync12(input8.imagePath);
13287
+ const imageBytes = readFileSync13(input8.imagePath);
13137
13288
  const ext = input8.imagePath.split(".").pop()?.toLowerCase();
13138
13289
  const mime = ext === "jpg" || ext === "jpeg" ? "image/jpeg" : "image/png";
13139
13290
  imageUrls.push(`data:${mime};base64,${imageBytes.toString("base64")}`);
@@ -13602,36 +13753,36 @@ async function withProviderScope(machine, action) {
13602
13753
 
13603
13754
  // src/cli/provisioning/index.ts
13604
13755
  import {
13605
- existsSync as existsSync16,
13606
- lstatSync,
13607
- mkdirSync as mkdirSync11,
13608
- readFileSync as readFileSync13,
13756
+ existsSync as existsSync17,
13757
+ lstatSync as lstatSync2,
13758
+ mkdirSync as mkdirSync12,
13759
+ readFileSync as readFileSync14,
13609
13760
  realpathSync,
13610
13761
  rmSync as rmSync2,
13611
13762
  symlinkSync,
13612
- writeFileSync as writeFileSync9
13763
+ writeFileSync as writeFileSync10
13613
13764
  } from "fs";
13614
- import { basename as basename5, dirname as dirname7, join as join18 } from "path";
13615
- import { fileURLToPath as fileURLToPath3 } from "url";
13616
- var packageRoot = [
13617
- fileURLToPath3(new URL("../..", import.meta.url)),
13618
- fileURLToPath3(new URL("../../..", import.meta.url))
13619
- ].find((candidate) => existsSync16(join18(candidate, "package.json"))) ?? fileURLToPath3(new URL("../..", import.meta.url));
13765
+ import { basename as basename5, dirname as dirname8, join as join19 } from "path";
13766
+ import { fileURLToPath as fileURLToPath4 } from "url";
13767
+ var packageRoot2 = [
13768
+ fileURLToPath4(new URL("../..", import.meta.url)),
13769
+ fileURLToPath4(new URL("../../..", import.meta.url))
13770
+ ].find((candidate) => existsSync17(join19(candidate, "package.json"))) ?? fileURLToPath4(new URL("../..", import.meta.url));
13620
13771
  var ALL_SETUP_AGENTS = ["claude", "copilot", "codex", "agent"];
13621
13772
  var SKILL_PAIRS = [
13622
13773
  {
13623
- from: join18(packageRoot, ".claude", "skills", "zam", "SKILL.md"),
13624
- to: join18(".claude", "skills", "zam", "SKILL.md"),
13774
+ from: join19(packageRoot2, ".claude", "skills", "zam", "SKILL.md"),
13775
+ to: join19(".claude", "skills", "zam", "SKILL.md"),
13625
13776
  agents: ["claude", "copilot"]
13626
13777
  },
13627
13778
  {
13628
- from: join18(packageRoot, ".agent", "skills", "zam", "SKILL.md"),
13629
- to: join18(".agent", "skills", "zam", "SKILL.md"),
13779
+ from: join19(packageRoot2, ".agent", "skills", "zam", "SKILL.md"),
13780
+ to: join19(".agent", "skills", "zam", "SKILL.md"),
13630
13781
  agents: ["agent"]
13631
13782
  },
13632
13783
  {
13633
- from: join18(packageRoot, ".agents", "skills", "zam", "SKILL.md"),
13634
- to: join18(".agents", "skills", "zam", "SKILL.md"),
13784
+ from: join19(packageRoot2, ".agents", "skills", "zam", "SKILL.md"),
13785
+ to: join19(".agents", "skills", "zam", "SKILL.md"),
13635
13786
  agents: ["codex"]
13636
13787
  }
13637
13788
  ];
@@ -13661,7 +13812,7 @@ function parseSetupAgents(value) {
13661
13812
  }
13662
13813
  function pathExists(path) {
13663
13814
  try {
13664
- lstatSync(path);
13815
+ lstatSync2(path);
13665
13816
  return true;
13666
13817
  } catch {
13667
13818
  return false;
@@ -13669,7 +13820,7 @@ function pathExists(path) {
13669
13820
  }
13670
13821
  function isSymbolicLink(path) {
13671
13822
  try {
13672
- return lstatSync(path).isSymbolicLink();
13823
+ return lstatSync2(path).isSymbolicLink();
13673
13824
  } catch {
13674
13825
  return false;
13675
13826
  }
@@ -13690,16 +13841,16 @@ function linkPointsTo(sourceDir, destinationDir) {
13690
13841
  }
13691
13842
  function isZamSkillCopy(destinationDir) {
13692
13843
  try {
13693
- if (!lstatSync(destinationDir).isDirectory()) return false;
13694
- const skillFile = join18(destinationDir, "SKILL.md");
13695
- if (!existsSync16(skillFile)) return false;
13696
- return /^name:\s*zam\s*$/m.test(readFileSync13(skillFile, "utf8"));
13844
+ if (!lstatSync2(destinationDir).isDirectory()) return false;
13845
+ const skillFile = join19(destinationDir, "SKILL.md");
13846
+ if (!existsSync17(skillFile)) return false;
13847
+ return /^name:\s*zam\s*$/m.test(readFileSync14(skillFile, "utf8"));
13697
13848
  } catch {
13698
13849
  return false;
13699
13850
  }
13700
13851
  }
13701
13852
  function classifySkillDestination(sourceDir, destinationDir) {
13702
- if (!existsSync16(sourceDir)) return "source-missing";
13853
+ if (!existsSync17(sourceDir)) return "source-missing";
13703
13854
  if (!isSymbolicLink(destinationDir) && pathsResolveToSameDirectory(sourceDir, destinationDir)) {
13704
13855
  return "source-directory";
13705
13856
  }
@@ -13716,9 +13867,9 @@ function wireSkills(cwd = process.cwd(), agents = parseSetupAgents(), opts = {})
13716
13867
  };
13717
13868
  for (const { from, to, agents: pairAgents } of SKILL_PAIRS) {
13718
13869
  if (!pairAgents.some((agent) => agents.has(agent))) continue;
13719
- const sourceDir = dirname7(from);
13720
- const destinationDir = dirname7(join18(cwd, to));
13721
- const label = dirname7(to);
13870
+ const sourceDir = dirname8(from);
13871
+ const destinationDir = dirname8(join19(cwd, to));
13872
+ const label = dirname8(to);
13722
13873
  const state = classifySkillDestination(sourceDir, destinationDir);
13723
13874
  if (state === "source-missing") {
13724
13875
  if (!opts.quiet) {
@@ -13775,7 +13926,7 @@ function wireSkills(cwd = process.cwd(), agents = parseSetupAgents(), opts = {})
13775
13926
  if (destinationExists) {
13776
13927
  rmSync2(destinationDir, { recursive: true, force: true });
13777
13928
  }
13778
- mkdirSync11(dirname7(destinationDir), { recursive: true });
13929
+ mkdirSync12(dirname8(destinationDir), { recursive: true });
13779
13930
  symlinkSync(
13780
13931
  sourceDir,
13781
13932
  destinationDir,
@@ -13791,8 +13942,8 @@ function inspectSkillLinks(cwd = process.cwd(), agents = parseSetupAgents()) {
13791
13942
  const results = [];
13792
13943
  for (const { from, to, agents: pairAgents } of SKILL_PAIRS) {
13793
13944
  if (!pairAgents.some((agent) => agents.has(agent))) continue;
13794
- const sourceDir = dirname7(from);
13795
- const destinationDir = dirname7(join18(cwd, to));
13945
+ const sourceDir = dirname8(from);
13946
+ const destinationDir = dirname8(join19(cwd, to));
13796
13947
  results.push({
13797
13948
  agents: pairAgents,
13798
13949
  source: sourceDir,
@@ -13818,15 +13969,15 @@ function upsertMarkedBlock(dest, blockBody, dryRun) {
13818
13969
  const block = `${ZAM_BLOCK_START}
13819
13970
  ${blockBody.trim()}
13820
13971
  ${ZAM_BLOCK_END}`;
13821
- if (!existsSync16(dest)) {
13972
+ if (!existsSync17(dest)) {
13822
13973
  if (!dryRun) {
13823
- mkdirSync11(dirname7(dest), { recursive: true });
13824
- writeFileSync9(dest, `${block}
13974
+ mkdirSync12(dirname8(dest), { recursive: true });
13975
+ writeFileSync10(dest, `${block}
13825
13976
  `, "utf8");
13826
13977
  }
13827
13978
  return "write";
13828
13979
  }
13829
- const existing = readFileSync13(dest, "utf8");
13980
+ const existing = readFileSync14(dest, "utf8");
13830
13981
  if (existing.includes(block)) return "skip";
13831
13982
  const start = existing.indexOf(ZAM_BLOCK_START);
13832
13983
  const end = existing.indexOf(ZAM_BLOCK_END);
@@ -13834,7 +13985,7 @@ ${ZAM_BLOCK_END}`;
13834
13985
 
13835
13986
  ${block}
13836
13987
  `;
13837
- if (!dryRun) writeFileSync9(dest, next, "utf8");
13988
+ if (!dryRun) writeFileSync10(dest, next, "utf8");
13838
13989
  return start >= 0 && end > start ? "update" : "write";
13839
13990
  }
13840
13991
  function logInstructionAction(action, label, dryRun) {
@@ -13846,8 +13997,8 @@ function logInstructionAction(action, label, dryRun) {
13846
13997
  }
13847
13998
  function writeClaudeMd(skipClaudeMd, cwd = process.cwd(), opts = {}) {
13848
13999
  if (skipClaudeMd) return;
13849
- const dest = join18(cwd, "CLAUDE.md");
13850
- if (existsSync16(dest)) {
14000
+ const dest = join19(cwd, "CLAUDE.md");
14001
+ if (existsSync17(dest)) {
13851
14002
  if (!opts.updateExisting) {
13852
14003
  console.log(` skip CLAUDE.md (already present)`);
13853
14004
  return;
@@ -13890,14 +14041,14 @@ Use \`zam connector setup turso\` to store cloud credentials in
13890
14041
  if (opts.dryRun) {
13891
14042
  console.log(` would write CLAUDE.md`);
13892
14043
  } else {
13893
- writeFileSync9(dest, content, "utf8");
14044
+ writeFileSync10(dest, content, "utf8");
13894
14045
  console.log(` write CLAUDE.md`);
13895
14046
  }
13896
14047
  }
13897
14048
  function writeAgentsMd(skipAgentsMd, cwd = process.cwd(), opts = {}) {
13898
14049
  if (skipAgentsMd) return;
13899
- const dest = join18(cwd, "AGENTS.md");
13900
- if (existsSync16(dest)) {
14050
+ const dest = join19(cwd, "AGENTS.md");
14051
+ if (existsSync17(dest)) {
13901
14052
  if (!opts.updateExisting) {
13902
14053
  console.log(` skip AGENTS.md (already present)`);
13903
14054
  return;
@@ -13947,12 +14098,12 @@ Codex discovers repository skills under \`.agents/skills/\`. Run
13947
14098
  if (opts.dryRun) {
13948
14099
  console.log(` would write AGENTS.md`);
13949
14100
  } else {
13950
- writeFileSync9(dest, content, "utf8");
14101
+ writeFileSync10(dest, content, "utf8");
13951
14102
  console.log(` write AGENTS.md`);
13952
14103
  }
13953
14104
  }
13954
14105
  function writeCopilotInstructions(cwd = process.cwd(), opts = {}) {
13955
- const dest = join18(cwd, ".github", "copilot-instructions.md");
14106
+ const dest = join19(cwd, ".github", "copilot-instructions.md");
13956
14107
  const action = upsertMarkedBlock(
13957
14108
  dest,
13958
14109
  `## ZAM learning sessions
@@ -13993,13 +14144,13 @@ async function resolveUser(opts, db, resolveOpts) {
13993
14144
  }
13994
14145
 
13995
14146
  // src/cli/workspaces/backup.ts
13996
- import { mkdirSync as mkdirSync12 } from "fs";
13997
- import { join as join19 } from "path";
14147
+ import { mkdirSync as mkdirSync13 } from "fs";
14148
+ import { join as join20 } from "path";
13998
14149
  async function backupDatabaseTo(db, targetDir) {
13999
- const backupDir = join19(targetDir, "zam-backups");
14000
- mkdirSync12(backupDir, { recursive: true });
14150
+ const backupDir = join20(targetDir, "zam-backups");
14151
+ mkdirSync13(backupDir, { recursive: true });
14001
14152
  const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
14002
- const dest = join19(backupDir, `zam-${stamp}.db`);
14153
+ const dest = join20(backupDir, `zam-${stamp}.db`);
14003
14154
  await db.exec(`VACUUM INTO '${dest.replace(/'/g, "''")}'`);
14004
14155
  return dest;
14005
14156
  }
@@ -14130,20 +14281,20 @@ bridgeCommand.command("workspace-info").description("Report the workspace dir, i
14130
14281
  activeWorkspace,
14131
14282
  workspaceDir: activeWorkspace.path,
14132
14283
  defaultWorkspaceDir: defaultWorkspaceDir(),
14133
- dataDir: join20(homedir11(), ".zam")
14284
+ dataDir: join21(homedir12(), ".zam")
14134
14285
  });
14135
14286
  });
14136
14287
  });
14137
14288
  function provisionConfiguredWorkspaces() {
14138
14289
  return getConfiguredWorkspaces().flatMap(
14139
- (workspace) => existsSync17(workspace.path) ? wireSkills(workspace.path, parseSetupAgents(), { quiet: true }) : []
14290
+ (workspace) => existsSync18(workspace.path) ? wireSkills(workspace.path, parseSetupAgents(), { quiet: true }) : []
14140
14291
  );
14141
14292
  }
14142
14293
  function buildWorkspaceLinkHealth(workspaces) {
14143
14294
  const agents = parseSetupAgents();
14144
14295
  const map = {};
14145
14296
  for (const workspace of workspaces) {
14146
- if (!existsSync17(workspace.path)) continue;
14297
+ if (!existsSync18(workspace.path)) continue;
14147
14298
  const links = inspectSkillLinks(workspace.path, agents);
14148
14299
  map[workspace.id] = {
14149
14300
  health: summarizeSkillLinkHealth(links),
@@ -14173,7 +14324,7 @@ bridgeCommand.command("workspace-list").description("List configured ZAM workspa
14173
14324
  activeWorkspace,
14174
14325
  workspaceDir: activeWorkspace.path,
14175
14326
  defaultWorkspaceDir: defaultWorkspaceDir(),
14176
- dataDir: join20(homedir11(), ".zam"),
14327
+ dataDir: join21(homedir12(), ".zam"),
14177
14328
  linkHealth: buildWorkspaceLinkHealth(workspaces)
14178
14329
  });
14179
14330
  });
@@ -14188,7 +14339,7 @@ bridgeCommand.command("workspace-repair-links").description(
14188
14339
  if (!id) jsonError("A non-empty --id is required");
14189
14340
  const workspace = getConfiguredWorkspaces().find((item) => item.id === id);
14190
14341
  if (!workspace) jsonError(`Workspace "${id}" is not configured`);
14191
- if (!existsSync17(workspace.path)) {
14342
+ if (!existsSync18(workspace.path)) {
14192
14343
  jsonError(`Workspace path does not exist: ${workspace.path}`);
14193
14344
  }
14194
14345
  const agents = parseSetupAgents(opts.agents);
@@ -14219,8 +14370,8 @@ function parseBridgeWorkspaceKind(value) {
14219
14370
  bridgeCommand.command("workspace-add").description("Register an existing directory as a ZAM workspace (JSON)").requiredOption("--path <dir>", "Existing workspace/repository directory").option("--id <id>", "Workspace id").option("--label <label>", "Human-readable label").option("--kind <kind>", "Workspace kind", "custom").action(async (opts) => {
14220
14371
  const raw = String(opts.path ?? "").trim();
14221
14372
  if (!raw) jsonError("A non-empty --path is required");
14222
- const path = resolve4(raw);
14223
- if (!existsSync17(path)) jsonError(`Workspace path does not exist: ${path}`);
14373
+ const path = resolve5(raw);
14374
+ if (!existsSync18(path)) jsonError(`Workspace path does not exist: ${path}`);
14224
14375
  const id = opts.id ? String(opts.id).trim() : void 0;
14225
14376
  if (opts.id && !id) jsonError("A non-empty --id is required");
14226
14377
  const kind = parseBridgeWorkspaceKind(opts.kind);
@@ -14264,8 +14415,8 @@ bridgeCommand.command("workspace-remove").description("Unregister a ZAM workspac
14264
14415
  bridgeCommand.command("set-workspace-dir").description("Set the personal workspace directory (JSON)").requiredOption("--dir <path>", "Path to the workspace directory").action(async (opts) => {
14265
14416
  const raw = String(opts.dir ?? "").trim();
14266
14417
  if (!raw) jsonError("A non-empty --dir is required");
14267
- const dir = resolve4(raw);
14268
- if (!existsSync17(dir)) jsonError(`Workspace path does not exist: ${dir}`);
14418
+ const dir = resolve5(raw);
14419
+ if (!existsSync18(dir)) jsonError(`Workspace path does not exist: ${dir}`);
14269
14420
  const skillLinks = wireSkills(dir, parseSetupAgents(), { quiet: true });
14270
14421
  await withDb2(async (db) => {
14271
14422
  const workspace = await activateWorkspacePath(db, dir);
@@ -14328,7 +14479,7 @@ bridgeCommand.command("agent-open").description("Launch an agent harness in the
14328
14479
  jsonError(`Workspace is not configured: ${opts.workspace}`);
14329
14480
  }
14330
14481
  const activeWorkspace = await ensureActiveWorkspace(db);
14331
- const workspace = opts.dir ? existsSync17(opts.dir) ? opts.dir : homedir11() : existingWorkspaceDirOrHome(configuredWorkspace ?? activeWorkspace);
14482
+ const workspace = opts.dir ? existsSync18(opts.dir) ? opts.dir : homedir12() : existingWorkspaceDirOrHome(configuredWorkspace ?? activeWorkspace);
14332
14483
  launchHarness(harness, {
14333
14484
  executable,
14334
14485
  workspace,
@@ -14700,7 +14851,7 @@ bridgeCommand.command("discover-skills").description(
14700
14851
  "20"
14701
14852
  ).action(async (opts) => {
14702
14853
  try {
14703
- const monitorDir = join20(homedir11(), ".zam", "monitor");
14854
+ const monitorDir = join21(homedir12(), ".zam", "monitor");
14704
14855
  let files;
14705
14856
  try {
14706
14857
  files = readdirSync2(monitorDir).filter((f) => f.endsWith(".jsonl"));
@@ -14713,7 +14864,7 @@ bridgeCommand.command("discover-skills").description(
14713
14864
  return;
14714
14865
  }
14715
14866
  const limit = Number(opts.limit);
14716
- const sorted = files.map((f) => ({ name: f, path: join20(monitorDir, f) })).sort((a, b) => b.name.localeCompare(a.name)).slice(0, limit);
14867
+ const sorted = files.map((f) => ({ name: f, path: join21(monitorDir, f) })).sort((a, b) => b.name.localeCompare(a.name)).slice(0, limit);
14717
14868
  const sessionCommands = /* @__PURE__ */ new Map();
14718
14869
  for (const file of sorted) {
14719
14870
  const sessionId = file.name.replace(".jsonl", "");
@@ -15215,7 +15366,7 @@ bridgeCommand.command("capture-ui").description("Capture a screenshot for agent-
15215
15366
  return;
15216
15367
  }
15217
15368
  }
15218
- const outputPath = opts.image ?? opts.output ?? join20(tmpdir3(), `zam-capture-${randomBytes2(4).toString("hex")}.png`);
15369
+ const outputPath = opts.image ?? opts.output ?? join21(tmpdir3(), `zam-capture-${randomBytes2(4).toString("hex")}.png`);
15219
15370
  const captureResult = isProvided ? { method: "provided", target: null } : captureScreenshot(outputPath, opts.hwnd, opts.processName);
15220
15371
  if (!isProvided) {
15221
15372
  const post = decidePostCapture(policy, {
@@ -15243,7 +15394,7 @@ bridgeCommand.command("capture-ui").description("Capture a screenshot for agent-
15243
15394
  return;
15244
15395
  }
15245
15396
  }
15246
- const imageBytes = readFileSync14(outputPath);
15397
+ const imageBytes = readFileSync15(outputPath);
15247
15398
  const base64 = imageBytes.toString("base64");
15248
15399
  jsonOut2({
15249
15400
  sessionId: opts.session ?? null,
@@ -15270,11 +15421,11 @@ bridgeCommand.command("start-recording").description("Start screen recording in
15270
15421
  return;
15271
15422
  }
15272
15423
  const sessionId = opts.session;
15273
- const statePath = join20(tmpdir3(), `zam-recording-${sessionId}.json`);
15424
+ const statePath = join21(tmpdir3(), `zam-recording-${sessionId}.json`);
15274
15425
  const defaultExt = platform === "win32" ? ".mkv" : ".mov";
15275
- const outputPath = opts.output ?? join20(tmpdir3(), `zam-recording-${sessionId}${defaultExt}`);
15276
- const { existsSync: existsSync26, writeFileSync: writeFileSync14, openSync, closeSync } = await import("fs");
15277
- if (existsSync26(statePath)) {
15426
+ const outputPath = opts.output ?? join21(tmpdir3(), `zam-recording-${sessionId}${defaultExt}`);
15427
+ const { existsSync: existsSync27, writeFileSync: writeFileSync15, openSync, closeSync } = await import("fs");
15428
+ if (existsSync27(statePath)) {
15278
15429
  jsonOut2({
15279
15430
  sessionId,
15280
15431
  started: false,
@@ -15282,7 +15433,7 @@ bridgeCommand.command("start-recording").description("Start screen recording in
15282
15433
  });
15283
15434
  return;
15284
15435
  }
15285
- const logPath = join20(tmpdir3(), `zam-recording-${sessionId}.log`);
15436
+ const logPath = join21(tmpdir3(), `zam-recording-${sessionId}.log`);
15286
15437
  let logFd;
15287
15438
  try {
15288
15439
  logFd = openSync(logPath, "w");
@@ -15328,7 +15479,7 @@ bridgeCommand.command("start-recording").description("Start screen recording in
15328
15479
  }
15329
15480
  child.unref();
15330
15481
  if (child.pid) {
15331
- writeFileSync14(
15482
+ writeFileSync15(
15332
15483
  statePath,
15333
15484
  JSON.stringify({
15334
15485
  pid: child.pid,
@@ -15364,9 +15515,9 @@ bridgeCommand.command("stop-recording").description(
15364
15515
  return;
15365
15516
  }
15366
15517
  const sessionId = opts.session;
15367
- const statePath = join20(tmpdir3(), `zam-recording-${sessionId}.json`);
15368
- const { existsSync: existsSync26, readFileSync: readFileSync19, rmSync: rmSync4 } = await import("fs");
15369
- if (!existsSync26(statePath)) {
15518
+ const statePath = join21(tmpdir3(), `zam-recording-${sessionId}.json`);
15519
+ const { existsSync: existsSync27, readFileSync: readFileSync20, rmSync: rmSync4 } = await import("fs");
15520
+ if (!existsSync27(statePath)) {
15370
15521
  jsonOut2({
15371
15522
  sessionId,
15372
15523
  stopped: false,
@@ -15374,7 +15525,7 @@ bridgeCommand.command("stop-recording").description(
15374
15525
  });
15375
15526
  return;
15376
15527
  }
15377
- const state = JSON.parse(readFileSync19(statePath, "utf8"));
15528
+ const state = JSON.parse(readFileSync20(statePath, "utf8"));
15378
15529
  const { pid, outputPath } = state;
15379
15530
  try {
15380
15531
  process.kill(pid, "SIGINT");
@@ -15390,7 +15541,7 @@ bridgeCommand.command("stop-recording").description(
15390
15541
  };
15391
15542
  let attempts = 0;
15392
15543
  while (isProcessRunning(pid) && attempts < 20) {
15393
- await new Promise((resolve10) => setTimeout(resolve10, 250));
15544
+ await new Promise((resolve11) => setTimeout(resolve11, 250));
15394
15545
  attempts++;
15395
15546
  }
15396
15547
  if (isProcessRunning(pid)) {
@@ -15403,7 +15554,7 @@ bridgeCommand.command("stop-recording").description(
15403
15554
  rmSync4(statePath, { force: true });
15404
15555
  } catch {
15405
15556
  }
15406
- if (!existsSync26(outputPath)) {
15557
+ if (!existsSync27(outputPath)) {
15407
15558
  jsonOut2({
15408
15559
  sessionId,
15409
15560
  stopped: false,
@@ -15640,7 +15791,7 @@ bridgeCommand.command("cloud-model-hint").description("Suggest a cloud model for
15640
15791
  });
15641
15792
  bridgeCommand.command("local-llm-hints").description("Detect installed local LLM servers and suggest defaults (JSON)").action(() => {
15642
15793
  const profile = getSystemProfile();
15643
- const flmInstalled = hasCommand("flm") || existsSync17("C:\\Program Files\\flm\\flm.exe");
15794
+ const flmInstalled = hasCommand("flm") || existsSync18("C:\\Program Files\\flm\\flm.exe");
15644
15795
  const ollamaInstalled = isOllamaInstalled();
15645
15796
  const runners = [
15646
15797
  { id: "flm", label: "FastFlowLM", installed: flmInstalled },
@@ -18190,26 +18341,26 @@ var doctorCommand = new Command5("doctor").description(
18190
18341
  // src/cli/commands/git-sync.ts
18191
18342
  init_kernel();
18192
18343
  import { execSync as execSync5 } from "child_process";
18193
- import { chmodSync as chmodSync2, existsSync as existsSync18, writeFileSync as writeFileSync10 } from "fs";
18194
- import { join as join21 } from "path";
18344
+ import { chmodSync as chmodSync2, existsSync as existsSync19, writeFileSync as writeFileSync11 } from "fs";
18345
+ import { join as join22 } from "path";
18195
18346
  import { Command as Command6 } from "commander";
18196
18347
  function installHook2() {
18197
- const gitDir = join21(process.cwd(), ".git");
18198
- if (!existsSync18(gitDir)) {
18348
+ const gitDir = join22(process.cwd(), ".git");
18349
+ if (!existsSync19(gitDir)) {
18199
18350
  console.error(
18200
18351
  "Error: Current directory is not the root of a Git repository."
18201
18352
  );
18202
18353
  process.exit(1);
18203
18354
  }
18204
- const hooksDir = join21(gitDir, "hooks");
18205
- const hookPath = join21(hooksDir, "post-commit");
18355
+ const hooksDir = join22(gitDir, "hooks");
18356
+ const hookPath = join22(hooksDir, "post-commit");
18206
18357
  const hookContent = `#!/bin/sh
18207
18358
  # ZAM Spaced Repetition Auto-Stale Hook
18208
18359
  # Triggered automatically on git commits to decay modified concept cards.
18209
18360
  zam git-sync --commit HEAD --quiet
18210
18361
  `;
18211
18362
  try {
18212
- writeFileSync10(hookPath, hookContent, { encoding: "utf-8", flag: "w" });
18363
+ writeFileSync11(hookPath, hookContent, { encoding: "utf-8", flag: "w" });
18213
18364
  try {
18214
18365
  chmodSync2(hookPath, "755");
18215
18366
  } catch (_e) {
@@ -18312,8 +18463,8 @@ ZAM Auto-Stale Complete: Scanned ${changedFiles.length} file(s).`
18312
18463
 
18313
18464
  // src/cli/commands/goal.ts
18314
18465
  init_kernel();
18315
- import { existsSync as existsSync19, mkdirSync as mkdirSync13 } from "fs";
18316
- import { resolve as resolve5 } from "path";
18466
+ import { existsSync as existsSync20, mkdirSync as mkdirSync14 } from "fs";
18467
+ import { resolve as resolve6 } from "path";
18317
18468
  import { input as input2 } from "@inquirer/prompts";
18318
18469
  import { Command as Command7 } from "commander";
18319
18470
  async function resolveGoalsDir() {
@@ -18326,7 +18477,7 @@ async function resolveGoalsDir() {
18326
18477
  } finally {
18327
18478
  await db?.close();
18328
18479
  }
18329
- return goalsDir ? resolve5(goalsDir) : resolve5("goals");
18480
+ return goalsDir ? resolve6(goalsDir) : resolve6("goals");
18330
18481
  }
18331
18482
  var goalCommand = new Command7("goal").description(
18332
18483
  "Manage learning goals (markdown files)"
@@ -18336,7 +18487,7 @@ goalCommand.command("list").description("List all goals").option(
18336
18487
  "Filter by status (active, completed, paused, abandoned)"
18337
18488
  ).option("--tree", "Show goals as a tree with parent/child relationships").option("--json", "Output as JSON").action(async (opts) => {
18338
18489
  const goalsDir = await resolveGoalsDir();
18339
- if (!existsSync19(goalsDir)) {
18490
+ if (!existsSync20(goalsDir)) {
18340
18491
  console.error(`Goals directory not found: ${goalsDir}`);
18341
18492
  console.error(
18342
18493
  "Set it with: zam settings set personal.goals_dir /path/to/goals"
@@ -18437,8 +18588,8 @@ ${"\u2500".repeat(50)}`);
18437
18588
  });
18438
18589
  goalCommand.command("create").description("Create a new goal").option("--slug <slug>", "Goal slug (used as filename)").option("--title <title>", "Goal title").option("--parent <slug>", "Parent goal slug").option("--description <text>", "Goal description").option("--json", "Output as JSON").action(async (opts) => {
18439
18590
  const goalsDir = await resolveGoalsDir();
18440
- if (!existsSync19(goalsDir)) {
18441
- mkdirSync13(goalsDir, { recursive: true });
18591
+ if (!existsSync20(goalsDir)) {
18592
+ mkdirSync14(goalsDir, { recursive: true });
18442
18593
  }
18443
18594
  let slug = opts.slug;
18444
18595
  let title = opts.title;
@@ -18498,22 +18649,22 @@ goalCommand.command("status <slug> <status>").description("Update a goal's statu
18498
18649
 
18499
18650
  // src/cli/commands/init.ts
18500
18651
  init_kernel();
18501
- import { existsSync as existsSync20, mkdirSync as mkdirSync14, writeFileSync as writeFileSync11 } from "fs";
18502
- import { homedir as homedir12 } from "os";
18503
- import { join as join22, resolve as resolve6 } from "path";
18652
+ import { existsSync as existsSync21, mkdirSync as mkdirSync15, writeFileSync as writeFileSync12 } from "fs";
18653
+ import { homedir as homedir13 } from "os";
18654
+ import { join as join23, resolve as resolve7 } from "path";
18504
18655
  import { confirm, input as input3 } from "@inquirer/prompts";
18505
18656
  import { Command as Command8 } from "commander";
18506
- var HOME2 = homedir12();
18657
+ var HOME2 = homedir13();
18507
18658
  function printLine(char = "\u2550", len = 60, color = "\x1B[36m") {
18508
18659
  console.log(`${color}${char.repeat(len)}\x1B[0m`);
18509
18660
  }
18510
18661
  function bootstrapSandboxWorkspace(workspaceDir) {
18511
- mkdirSync14(join22(workspaceDir, "beliefs"), { recursive: true });
18512
- mkdirSync14(join22(workspaceDir, "goals"), { recursive: true });
18513
- mkdirSync14(join22(workspaceDir, "skills"), { recursive: true });
18514
- const worldviewFile = join22(workspaceDir, "beliefs", "worldview.md");
18515
- if (!existsSync20(worldviewFile)) {
18516
- writeFileSync11(
18662
+ mkdirSync15(join23(workspaceDir, "beliefs"), { recursive: true });
18663
+ mkdirSync15(join23(workspaceDir, "goals"), { recursive: true });
18664
+ mkdirSync15(join23(workspaceDir, "skills"), { recursive: true });
18665
+ const worldviewFile = join23(workspaceDir, "beliefs", "worldview.md");
18666
+ if (!existsSync21(worldviewFile)) {
18667
+ writeFileSync12(
18517
18668
  worldviewFile,
18518
18669
  `# Personal Worldview
18519
18670
 
@@ -18525,9 +18676,9 @@ Here, I declare the core concepts and principles I want to master.
18525
18676
  "utf8"
18526
18677
  );
18527
18678
  }
18528
- const goalsFile = join22(workspaceDir, "goals", "goals.md");
18529
- if (!existsSync20(goalsFile)) {
18530
- writeFileSync11(
18679
+ const goalsFile = join23(workspaceDir, "goals", "goals.md");
18680
+ if (!existsSync21(goalsFile)) {
18681
+ writeFileSync12(
18531
18682
  goalsFile,
18532
18683
  `# Personal Goals
18533
18684
 
@@ -18549,8 +18700,8 @@ var initCommand = new Command8("init").description("Launch the guided interactiv
18549
18700
  );
18550
18701
  printLine();
18551
18702
  console.log("\n\x1B[1m[1/5] Setting up Local Workspace Sandbox\x1B[0m");
18552
- const defaultWorkspace = join22(HOME2, "Documents", "zam");
18553
- const workspacePath = resolve6(
18703
+ const defaultWorkspace = join23(HOME2, "Documents", "zam");
18704
+ const workspacePath = resolve7(
18554
18705
  await input3({
18555
18706
  message: "Choose your ZAM workspace directory:",
18556
18707
  default: defaultWorkspace
@@ -19751,7 +19902,7 @@ observerCommand.command("revoke <process>").description("Remove a process from o
19751
19902
 
19752
19903
  // src/cli/commands/profile.ts
19753
19904
  init_kernel();
19754
- import { dirname as dirname8, resolve as resolve7 } from "path";
19905
+ import { dirname as dirname9, resolve as resolve8 } from "path";
19755
19906
  import { Command as Command13 } from "commander";
19756
19907
  var C2 = {
19757
19908
  reset: "\x1B[0m",
@@ -19779,7 +19930,7 @@ var profileCommand = new Command13("profile").description("Show or change this m
19779
19930
  if (opts.mode) setInstallMode(opts.mode);
19780
19931
  db = await openDatabaseWithSync({ initialize: true });
19781
19932
  if (opts.dir) {
19782
- await activateWorkspacePath(db, resolve7(opts.dir), {
19933
+ await activateWorkspacePath(db, resolve8(opts.dir), {
19783
19934
  kind: "personal",
19784
19935
  label: "Personal"
19785
19936
  });
@@ -19792,7 +19943,7 @@ var profileCommand = new Command13("profile").description("Show or change this m
19792
19943
  mode: getInstallMode(),
19793
19944
  personalDir,
19794
19945
  syncProvider: detectSyncProvider(personalDir),
19795
- dataDir: dirname8(dbPath),
19946
+ dataDir: dirname9(dbPath),
19796
19947
  dbPath
19797
19948
  };
19798
19949
  if (opts.json) {
@@ -20181,7 +20332,7 @@ ${"\u2550".repeat(50)}`);
20181
20332
 
20182
20333
  // src/cli/commands/session.ts
20183
20334
  init_kernel();
20184
- import { readFileSync as readFileSync15 } from "fs";
20335
+ import { readFileSync as readFileSync16 } from "fs";
20185
20336
  import { input as input6, select as select2 } from "@inquirer/prompts";
20186
20337
  import { Command as Command16 } from "commander";
20187
20338
  var sessionCommand = new Command16("session").description(
@@ -20372,7 +20523,7 @@ function loadPatternFile(path) {
20372
20523
  if (!path) return [];
20373
20524
  let parsed;
20374
20525
  try {
20375
- parsed = JSON.parse(readFileSync15(path, "utf-8"));
20526
+ parsed = JSON.parse(readFileSync16(path, "utf-8"));
20376
20527
  } catch (err) {
20377
20528
  throw new Error(
20378
20529
  `Cannot read synthesis patterns from ${path}: ${err.message}`
@@ -20563,7 +20714,7 @@ sessionCommand.command("end").description("End a session and show summary").requ
20563
20714
 
20564
20715
  // src/cli/commands/settings.ts
20565
20716
  init_kernel();
20566
- import { existsSync as existsSync21 } from "fs";
20717
+ import { existsSync as existsSync22 } from "fs";
20567
20718
  import { Command as Command17 } from "commander";
20568
20719
  var settingsCommand = new Command17("settings").description(
20569
20720
  "Manage user settings"
@@ -20728,7 +20879,7 @@ settingsCommand.command("repos").description("Show or set Personal, Team, and Or
20728
20879
  console.log("\nValidation:");
20729
20880
  for (const [name, path] of Object.entries(paths)) {
20730
20881
  if (path) {
20731
- const exists = existsSync21(path);
20882
+ const exists = existsSync22(path);
20732
20883
  console.log(
20733
20884
  ` ${name.padEnd(9)}: ${exists ? "\x1B[32m\u2713 Valid folder\x1B[0m" : "\x1B[31m\u2717 Directory does not exist\x1B[0m"}`
20734
20885
  );
@@ -20741,7 +20892,7 @@ settingsCommand.command("repos").description("Show or set Personal, Team, and Or
20741
20892
 
20742
20893
  // src/cli/commands/setup.ts
20743
20894
  init_kernel();
20744
- import { resolve as resolve8 } from "path";
20895
+ import { resolve as resolve9 } from "path";
20745
20896
  import { Command as Command18 } from "commander";
20746
20897
  function formatDatabaseInitTarget(target) {
20747
20898
  switch (target.kind) {
@@ -20801,7 +20952,7 @@ var setupCommand = new Command18("setup").description(
20801
20952
  console.error(`Error: ${err.message}`);
20802
20953
  process.exit(1);
20803
20954
  }
20804
- const target = resolve8(opts.target ?? process.cwd());
20955
+ const target = resolve9(opts.target ?? process.cwd());
20805
20956
  const updateExistingInstructions = Boolean(opts.target) || opts.force;
20806
20957
  console.log(
20807
20958
  `Setting up ZAM in ${target}${opts.dryRun ? " (dry run)" : ""}
@@ -20925,8 +21076,8 @@ skillCommand.command("add").description("Register a new agent skill").requiredOp
20925
21076
 
20926
21077
  // src/cli/commands/snapshot.ts
20927
21078
  init_kernel();
20928
- import { existsSync as existsSync22, mkdirSync as mkdirSync15, readFileSync as readFileSync16, writeFileSync as writeFileSync12 } from "fs";
20929
- import { dirname as dirname9, join as join23 } from "path";
21079
+ import { existsSync as existsSync23, mkdirSync as mkdirSync16, readFileSync as readFileSync17, writeFileSync as writeFileSync13 } from "fs";
21080
+ import { dirname as dirname10, join as join24 } from "path";
20930
21081
  import { Command as Command20 } from "commander";
20931
21082
  function defaultOutName() {
20932
21083
  const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/\.\d+Z$/, "").replace(/:/g, "-");
@@ -20955,12 +21106,12 @@ var exportCmd = new Command20("export").description("Write a portable SQL-text s
20955
21106
  process.stdout.write(snapshot);
20956
21107
  return;
20957
21108
  }
20958
- const out = opts.out ?? join23(personalDir, "snapshots", defaultOutName());
20959
- const dir = dirname9(out);
20960
- if (dir && dir !== "." && !existsSync22(dir)) {
20961
- mkdirSync15(dir, { recursive: true });
21109
+ const out = opts.out ?? join24(personalDir, "snapshots", defaultOutName());
21110
+ const dir = dirname10(out);
21111
+ if (dir && dir !== "." && !existsSync23(dir)) {
21112
+ mkdirSync16(dir, { recursive: true });
20962
21113
  }
20963
- writeFileSync12(out, snapshot, "utf-8");
21114
+ writeFileSync13(out, snapshot, "utf-8");
20964
21115
  console.log(`Snapshot written: ${out}`);
20965
21116
  console.log(
20966
21117
  ` ${total} row(s)${nonEmpty.length ? ` \u2014 ${nonEmpty.join(", ")}` : ""}`
@@ -20974,11 +21125,11 @@ var exportCmd = new Command20("export").description("Write a portable SQL-text s
20974
21125
  var importCmd = new Command20("import").description("Restore a snapshot into the database").argument("<file>", "Snapshot file to restore").option("--force", "Overwrite a non-empty database", false).action(async (file, opts) => {
20975
21126
  let db;
20976
21127
  try {
20977
- if (!existsSync22(file)) {
21128
+ if (!existsSync23(file)) {
20978
21129
  console.error(`Error: Snapshot file not found: ${file}`);
20979
21130
  process.exit(1);
20980
21131
  }
20981
- const snapshot = readFileSync16(file, "utf-8");
21132
+ const snapshot = readFileSync17(file, "utf-8");
20982
21133
  db = await openDatabaseWithSync({ initialize: true });
20983
21134
  const result = await importSnapshot(db, snapshot, { force: opts.force });
20984
21135
  await db.close();
@@ -20996,11 +21147,11 @@ var importCmd = new Command20("import").description("Restore a snapshot into the
20996
21147
  });
20997
21148
  var verifyCmd = new Command20("verify").description("Check a snapshot's manifest and checksum without importing").argument("<file>", "Snapshot file to verify").action((file) => {
20998
21149
  try {
20999
- if (!existsSync22(file)) {
21150
+ if (!existsSync23(file)) {
21000
21151
  console.error(`Error: Snapshot file not found: ${file}`);
21001
21152
  process.exit(1);
21002
21153
  }
21003
- const manifest = verifySnapshot(readFileSync16(file, "utf-8"));
21154
+ const manifest = verifySnapshot(readFileSync17(file, "utf-8"));
21004
21155
  const { total, nonEmpty } = summarize(manifest.tables);
21005
21156
  console.log(`Valid snapshot (format v${manifest.version})`);
21006
21157
  console.log(` created: ${manifest.createdAt}`);
@@ -21549,10 +21700,10 @@ tokenCommand.command("reembed").description("Backfill or refresh semantic-search
21549
21700
  // src/cli/commands/ui.ts
21550
21701
  init_kernel();
21551
21702
  import { spawn as spawn3, spawnSync } from "child_process";
21552
- import { existsSync as existsSync23 } from "fs";
21553
- import { homedir as homedir13 } from "os";
21554
- import { dirname as dirname10, join as join24 } from "path";
21555
- import { fileURLToPath as fileURLToPath4 } from "url";
21703
+ import { existsSync as existsSync24 } from "fs";
21704
+ import { homedir as homedir14 } from "os";
21705
+ import { dirname as dirname11, join as join25 } from "path";
21706
+ import { fileURLToPath as fileURLToPath5 } from "url";
21556
21707
  import { Command as Command23 } from "commander";
21557
21708
  var C3 = {
21558
21709
  reset: "\x1B[0m",
@@ -21563,14 +21714,14 @@ var C3 = {
21563
21714
  dim: "\x1B[2m"
21564
21715
  };
21565
21716
  function findDesktopDir() {
21566
- const starts = [process.cwd(), dirname10(fileURLToPath4(import.meta.url))];
21717
+ const starts = [process.cwd(), dirname11(fileURLToPath5(import.meta.url))];
21567
21718
  for (const start of starts) {
21568
21719
  let dir = start;
21569
21720
  for (let i = 0; i < 10; i++) {
21570
- if (existsSync23(join24(dir, "desktop", "src-tauri", "tauri.conf.json"))) {
21571
- return join24(dir, "desktop");
21721
+ if (existsSync24(join25(dir, "desktop", "src-tauri", "tauri.conf.json"))) {
21722
+ return join25(dir, "desktop");
21572
21723
  }
21573
- const parent = dirname10(dir);
21724
+ const parent = dirname11(dir);
21574
21725
  if (parent === dir) break;
21575
21726
  dir = parent;
21576
21727
  }
@@ -21578,30 +21729,30 @@ function findDesktopDir() {
21578
21729
  return null;
21579
21730
  }
21580
21731
  function findBuiltApp(desktopDir) {
21581
- const releaseDir = join24(desktopDir, "src-tauri", "target", "release");
21732
+ const releaseDir = join25(desktopDir, "src-tauri", "target", "release");
21582
21733
  if (process.platform === "win32") {
21583
21734
  for (const name of ["ZAM.exe", "zam.exe", "zam-desktop.exe"]) {
21584
- const p = join24(releaseDir, name);
21585
- if (existsSync23(p)) return p;
21735
+ const p = join25(releaseDir, name);
21736
+ if (existsSync24(p)) return p;
21586
21737
  }
21587
21738
  } else if (process.platform === "darwin") {
21588
- const app = join24(releaseDir, "bundle", "macos", "ZAM.app");
21589
- if (existsSync23(app)) return app;
21739
+ const app = join25(releaseDir, "bundle", "macos", "ZAM.app");
21740
+ if (existsSync24(app)) return app;
21590
21741
  } else {
21591
21742
  for (const name of ["zam", "ZAM", "zam-desktop"]) {
21592
- const p = join24(releaseDir, name);
21593
- if (existsSync23(p)) return p;
21743
+ const p = join25(releaseDir, name);
21744
+ if (existsSync24(p)) return p;
21594
21745
  }
21595
21746
  }
21596
21747
  return null;
21597
21748
  }
21598
21749
  function findInstalledApp() {
21599
21750
  const candidates = process.platform === "win32" ? [
21600
- process.env.LOCALAPPDATA && join24(process.env.LOCALAPPDATA, "Programs", "ZAM", "ZAM.exe"),
21601
- process.env.ProgramFiles && join24(process.env.ProgramFiles, "ZAM", "ZAM.exe"),
21602
- process.env["ProgramFiles(x86)"] && join24(process.env["ProgramFiles(x86)"], "ZAM", "ZAM.exe")
21603
- ] : process.platform === "darwin" ? ["/Applications/ZAM.app", join24(homedir13(), "Applications", "ZAM.app")] : ["/opt/ZAM/zam", "/usr/bin/zam-desktop"];
21604
- return candidates.find((candidate) => candidate && existsSync23(candidate)) || null;
21751
+ process.env.LOCALAPPDATA && join25(process.env.LOCALAPPDATA, "Programs", "ZAM", "ZAM.exe"),
21752
+ process.env.ProgramFiles && join25(process.env.ProgramFiles, "ZAM", "ZAM.exe"),
21753
+ process.env["ProgramFiles(x86)"] && join25(process.env["ProgramFiles(x86)"], "ZAM", "ZAM.exe")
21754
+ ] : process.platform === "darwin" ? ["/Applications/ZAM.app", join25(homedir14(), "Applications", "ZAM.app")] : ["/opt/ZAM/zam", "/usr/bin/zam-desktop"];
21755
+ return candidates.find((candidate) => candidate && existsSync24(candidate)) || null;
21605
21756
  }
21606
21757
  function runNpm(args, opts) {
21607
21758
  const res = spawnSync("npm", args, {
@@ -21612,7 +21763,7 @@ function runNpm(args, opts) {
21612
21763
  return res.status ?? 1;
21613
21764
  }
21614
21765
  function ensureDesktopDeps(desktopDir) {
21615
- if (existsSync23(join24(desktopDir, "node_modules"))) return true;
21766
+ if (existsSync24(join25(desktopDir, "node_modules"))) return true;
21616
21767
  console.log(
21617
21768
  `${C3.cyan}Installing desktop dependencies (one-time)...${C3.reset}`
21618
21769
  );
@@ -21638,13 +21789,13 @@ function requireRust() {
21638
21789
  function hasMsvcBuildTools() {
21639
21790
  if (process.platform !== "win32") return true;
21640
21791
  const pf86 = process.env["ProgramFiles(x86)"] || "C:\\Program Files (x86)";
21641
- const vswhere = join24(
21792
+ const vswhere = join25(
21642
21793
  pf86,
21643
21794
  "Microsoft Visual Studio",
21644
21795
  "Installer",
21645
21796
  "vswhere.exe"
21646
21797
  );
21647
- if (!existsSync23(vswhere)) return false;
21798
+ if (!existsSync24(vswhere)) return false;
21648
21799
  const res = spawnSync(
21649
21800
  vswhere,
21650
21801
  [
@@ -21676,7 +21827,7 @@ function requireMsvcOnWindows() {
21676
21827
  return false;
21677
21828
  }
21678
21829
  function warnIfCliMissing(repoRoot) {
21679
- if (!existsSync23(join24(repoRoot, "dist", "cli", "index.js"))) {
21830
+ if (!existsSync24(join25(repoRoot, "dist", "cli", "index.js"))) {
21680
21831
  console.warn(
21681
21832
  `${C3.yellow}\u26A0 CLI build not found (dist/cli/index.js). The GUI bridge needs it \u2014 run 'npm run build' at the repo root.${C3.reset}`
21682
21833
  );
@@ -21739,7 +21890,7 @@ var uiCommand = new Command23("ui").description("Launch the ZAM Desktop GUI (Act
21739
21890
  ).option("--shortcut", "Create Desktop + Start-menu shortcuts to the GUI").action((opts) => {
21740
21891
  const installedApp = findInstalledApp();
21741
21892
  if (!opts.dev && !opts.build && !opts.shortcut && installedApp) {
21742
- launchApp(installedApp, homedir13());
21893
+ launchApp(installedApp, homedir14());
21743
21894
  return;
21744
21895
  }
21745
21896
  const desktopDir = findDesktopDir();
@@ -21749,7 +21900,7 @@ var uiCommand = new Command23("ui").description("Launch the ZAM Desktop GUI (Act
21749
21900
  );
21750
21901
  process.exit(1);
21751
21902
  }
21752
- const repoRoot = dirname10(desktopDir);
21903
+ const repoRoot = dirname11(desktopDir);
21753
21904
  if (opts.build) {
21754
21905
  if (!requireRust()) process.exit(1);
21755
21906
  if (!requireMsvcOnWindows()) process.exit(1);
@@ -21760,7 +21911,7 @@ var uiCommand = new Command23("ui").description("Launch the ZAM Desktop GUI (Act
21760
21911
  );
21761
21912
  const code = runNpm(["run", "tauri", "build"], { cwd: desktopDir });
21762
21913
  if (code === 0) {
21763
- const bundle = join24(
21914
+ const bundle = join25(
21764
21915
  desktopDir,
21765
21916
  "src-tauri",
21766
21917
  "target",
@@ -21800,7 +21951,7 @@ ${C3.green}\u2713 Done. Installer is in:${C3.reset}
21800
21951
  );
21801
21952
  process.exit(1);
21802
21953
  }
21803
- createShortcuts(shortcutTarget, dirname10(shortcutTarget));
21954
+ createShortcuts(shortcutTarget, dirname11(shortcutTarget));
21804
21955
  return;
21805
21956
  }
21806
21957
  if (builtApp) {
@@ -21838,9 +21989,9 @@ ${C3.dim}After that, 'zam ui' launches it directly.${C3.reset}`
21838
21989
  // src/cli/commands/update.ts
21839
21990
  init_kernel();
21840
21991
  import { spawnSync as spawnSync2 } from "child_process";
21841
- import { existsSync as existsSync24, readFileSync as readFileSync17, realpathSync as realpathSync2 } from "fs";
21842
- import { dirname as dirname11, join as join25 } from "path";
21843
- import { fileURLToPath as fileURLToPath5 } from "url";
21992
+ import { existsSync as existsSync25, readFileSync as readFileSync18, realpathSync as realpathSync2 } from "fs";
21993
+ import { dirname as dirname12, join as join26 } from "path";
21994
+ import { fileURLToPath as fileURLToPath6 } from "url";
21844
21995
  import { confirm as confirm3 } from "@inquirer/prompts";
21845
21996
  import { Command as Command24 } from "commander";
21846
21997
  var CHANNELS = [
@@ -21861,7 +22012,7 @@ var C4 = {
21861
22012
  function versionAt(dir) {
21862
22013
  try {
21863
22014
  const pkg2 = JSON.parse(
21864
- readFileSync17(join25(dir, "package.json"), "utf-8")
22015
+ readFileSync18(join26(dir, "package.json"), "utf-8")
21865
22016
  );
21866
22017
  return pkg2.version ?? "unknown";
21867
22018
  } catch {
@@ -21919,14 +22070,14 @@ var checkCmd = new Command24("check").description("Check whether a newer ZAM has
21919
22070
  }
21920
22071
  );
21921
22072
  function findSourceRepo() {
21922
- let dir = realpathSync2(dirname11(fileURLToPath5(import.meta.url)));
21923
- let parent = dirname11(dir);
22073
+ let dir = realpathSync2(dirname12(fileURLToPath6(import.meta.url)));
22074
+ let parent = dirname12(dir);
21924
22075
  while (parent !== dir) {
21925
- if (existsSync24(join25(dir, ".git"))) return dir;
22076
+ if (existsSync25(join26(dir, ".git"))) return dir;
21926
22077
  dir = parent;
21927
- parent = dirname11(dir);
22078
+ parent = dirname12(dir);
21928
22079
  }
21929
- return existsSync24(join25(dir, ".git")) ? dir : null;
22080
+ return existsSync25(join26(dir, ".git")) ? dir : null;
21930
22081
  }
21931
22082
  function runGit(cwd, args, capture) {
21932
22083
  const res = spawnSync2("git", args, {
@@ -21947,7 +22098,7 @@ function runNpm2(args, cwd) {
21947
22098
  function smokeTestBuild(src) {
21948
22099
  const res = spawnSync2(
21949
22100
  process.execPath,
21950
- [join25(src, "dist", "cli", "index.js"), "--version"],
22101
+ [join26(src, "dist", "cli", "index.js"), "--version"],
21951
22102
  {
21952
22103
  cwd: src,
21953
22104
  encoding: "utf8",
@@ -22027,7 +22178,7 @@ Fix it manually in ${src} (try \`npm ci && npm run build\`, and check your Node
22027
22178
  console.log(`${C4.dim}\u2192 zam setup --force${C4.reset}`);
22028
22179
  const setup = spawnSync2(
22029
22180
  process.execPath,
22030
- [join25(src, "dist", "cli", "index.js"), "setup", "--force"],
22181
+ [join26(src, "dist", "cli", "index.js"), "setup", "--force"],
22031
22182
  { cwd: process.cwd(), stdio: "inherit" }
22032
22183
  );
22033
22184
  if (setup.status !== 0) {
@@ -22140,9 +22291,9 @@ var whoamiCommand = new Command25("whoami").description("Show or set the default
22140
22291
  // src/cli/commands/workspace.ts
22141
22292
  init_kernel();
22142
22293
  import { execFileSync as execFileSync4 } from "child_process";
22143
- import { existsSync as existsSync25, writeFileSync as writeFileSync13 } from "fs";
22144
- import { homedir as homedir14 } from "os";
22145
- import { join as join26, resolve as resolve9 } from "path";
22294
+ import { existsSync as existsSync26, writeFileSync as writeFileSync14 } from "fs";
22295
+ import { homedir as homedir15 } from "os";
22296
+ import { join as join27, resolve as resolve10 } from "path";
22146
22297
  import { confirm as confirm4, input as input7 } from "@inquirer/prompts";
22147
22298
  import { Command as Command26 } from "commander";
22148
22299
  function runGit2(cwd, args) {
@@ -22226,7 +22377,7 @@ workspaceCommand.command("list").description("List configured ZAM workspaces").o
22226
22377
  const workspaces = getConfiguredWorkspaces();
22227
22378
  const agents = parseSetupAgents();
22228
22379
  const linkHealth = Object.fromEntries(
22229
- workspaces.filter((workspace) => existsSync25(workspace.path)).map((workspace) => [
22380
+ workspaces.filter((workspace) => existsSync26(workspace.path)).map((workspace) => [
22230
22381
  workspace.id,
22231
22382
  summarizeSkillLinkHealth(inspectSkillLinks(workspace.path, agents))
22232
22383
  ])
@@ -22268,8 +22419,8 @@ workspaceCommand.command("add <id>").description("Register an existing directory
22268
22419
  `Source-control provider (${WORKSPACE_SOURCE_CONTROLS.join(" | ")})`
22269
22420
  ).option("--scopes <list>", "Comma-separated knowledge scopes").option("--default-agent <id>", "Default agent harness for this workspace").action((id, opts) => {
22270
22421
  try {
22271
- const path = resolve9(String(opts.path));
22272
- if (!existsSync25(path)) {
22422
+ const path = resolve10(String(opts.path));
22423
+ if (!existsSync26(path)) {
22273
22424
  console.error(`Workspace path does not exist: ${path}`);
22274
22425
  process.exit(1);
22275
22426
  }
@@ -22363,7 +22514,7 @@ workspaceCommand.command("publish").description("Publish your local workspace sa
22363
22514
  );
22364
22515
  process.exit(1);
22365
22516
  }
22366
- if (!existsSync25(workspaceDir)) {
22517
+ if (!existsSync26(workspaceDir)) {
22367
22518
  console.error(
22368
22519
  `\x1B[31m\u2717 Workspace directory does not exist: ${workspaceDir}\x1B[0m`
22369
22520
  );
@@ -22377,15 +22528,15 @@ Active workspace: \x1B[36m${workspaceDir}\x1B[0m`);
22377
22528
  );
22378
22529
  process.exit(1);
22379
22530
  }
22380
- const gitignorePath = join26(workspaceDir, ".gitignore");
22381
- if (!existsSync25(gitignorePath)) {
22382
- writeFileSync13(
22531
+ const gitignorePath = join27(workspaceDir, ".gitignore");
22532
+ if (!existsSync26(gitignorePath)) {
22533
+ writeFileSync14(
22383
22534
  gitignorePath,
22384
22535
  "node_modules/\n.agent/\n.agents/\n.claude/\n.gemini/\n.goose/\n*.log\n",
22385
22536
  "utf8"
22386
22537
  );
22387
22538
  }
22388
- const hasGitRepo = existsSync25(join26(workspaceDir, ".git"));
22539
+ const hasGitRepo = existsSync26(join27(workspaceDir, ".git"));
22389
22540
  if (!hasGitRepo) {
22390
22541
  console.log("Initializing local Git repository...");
22391
22542
  runGit2(workspaceDir, ["init", "-b", "main"]);
@@ -22472,7 +22623,7 @@ Active workspace: \x1B[36m${workspaceDir}\x1B[0m`);
22472
22623
  }
22473
22624
  });
22474
22625
  workspaceCommand.command("data-dir").description("Print the ZAM data directory (database, credentials, config)").option("--json", "Output as JSON").action((opts) => {
22475
- const dir = join26(homedir14(), ".zam");
22626
+ const dir = join27(homedir15(), ".zam");
22476
22627
  console.log(opts.json ? JSON.stringify({ dataDir: dir }) : dir);
22477
22628
  });
22478
22629
  workspaceCommand.command("backup").description("Back up the local ZAM database into your workspace").option(
@@ -22513,9 +22664,9 @@ workspaceCommand.command("backup").description("Back up the local ZAM database i
22513
22664
  });
22514
22665
 
22515
22666
  // src/cli/app.ts
22516
- var __dirname = dirname12(fileURLToPath6(import.meta.url));
22667
+ var __dirname = dirname13(fileURLToPath7(import.meta.url));
22517
22668
  var pkg = JSON.parse(
22518
- readFileSync18(join27(__dirname, "..", "..", "package.json"), "utf-8")
22669
+ readFileSync19(join28(__dirname, "..", "..", "package.json"), "utf-8")
22519
22670
  );
22520
22671
  var program = new Command27();
22521
22672
  program.name("zam").description(