@drewpayment/mink 0.10.1 → 0.11.0-beta.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.
Files changed (53) hide show
  1. package/dashboard/out/404.html +1 -1
  2. package/dashboard/out/action-log.html +1 -1
  3. package/dashboard/out/action-log.txt +1 -1
  4. package/dashboard/out/activity.html +1 -1
  5. package/dashboard/out/activity.txt +1 -1
  6. package/dashboard/out/bugs.html +1 -1
  7. package/dashboard/out/bugs.txt +1 -1
  8. package/dashboard/out/capture.html +1 -1
  9. package/dashboard/out/capture.txt +1 -1
  10. package/dashboard/out/config.html +1 -1
  11. package/dashboard/out/config.txt +1 -1
  12. package/dashboard/out/daemon.html +1 -1
  13. package/dashboard/out/daemon.txt +1 -1
  14. package/dashboard/out/design.html +1 -1
  15. package/dashboard/out/design.txt +1 -1
  16. package/dashboard/out/discord.html +1 -1
  17. package/dashboard/out/discord.txt +1 -1
  18. package/dashboard/out/file-index.html +1 -1
  19. package/dashboard/out/file-index.txt +1 -1
  20. package/dashboard/out/index.html +1 -1
  21. package/dashboard/out/index.txt +1 -1
  22. package/dashboard/out/insights.html +1 -1
  23. package/dashboard/out/insights.txt +1 -1
  24. package/dashboard/out/learning.html +1 -1
  25. package/dashboard/out/learning.txt +1 -1
  26. package/dashboard/out/overview.html +1 -1
  27. package/dashboard/out/overview.txt +1 -1
  28. package/dashboard/out/scheduler.html +1 -1
  29. package/dashboard/out/scheduler.txt +1 -1
  30. package/dashboard/out/sync.html +1 -1
  31. package/dashboard/out/sync.txt +1 -1
  32. package/dashboard/out/tokens.html +1 -1
  33. package/dashboard/out/tokens.txt +1 -1
  34. package/dashboard/out/waste.html +1 -1
  35. package/dashboard/out/waste.txt +1 -1
  36. package/dashboard/out/wiki.html +1 -1
  37. package/dashboard/out/wiki.txt +1 -1
  38. package/dist/cli.js +1407 -868
  39. package/package.json +1 -1
  40. package/src/commands/init.ts +29 -4
  41. package/src/commands/note.ts +2 -2
  42. package/src/commands/session-start.ts +8 -2
  43. package/src/commands/sync-migrate.ts +429 -7
  44. package/src/commands/sync.ts +5 -2
  45. package/src/core/dashboard-server.ts +13 -5
  46. package/src/core/git-identity.ts +120 -0
  47. package/src/core/paths.ts +19 -3
  48. package/src/core/project-id.ts +150 -5
  49. package/src/core/project-registry.ts +122 -13
  50. package/src/core/sync.ts +7 -1
  51. package/src/types/config.ts +9 -0
  52. /package/dashboard/out/_next/static/{e0QWU9rPMeSlJJLTwij89 → WyN-sdaVY7cZaACRaK7vq}/_buildManifest.js +0 -0
  53. /package/dashboard/out/_next/static/{e0QWU9rPMeSlJJLTwij89 → WyN-sdaVY7cZaACRaK7vq}/_ssgManifest.js +0 -0
package/dist/cli.js CHANGED
@@ -163,19 +163,598 @@ function isSessionState(value) {
163
163
  }
164
164
  var init_session = () => {};
165
165
 
166
+ // src/core/git-identity.ts
167
+ import { execSync } from "child_process";
168
+ import { existsSync, realpathSync } from "fs";
169
+ function gitOut(cwd, args) {
170
+ if (!existsSync(cwd))
171
+ return null;
172
+ try {
173
+ return execSync(`git ${args}`, {
174
+ cwd,
175
+ timeout: GIT_TIMEOUT_MS,
176
+ stdio: ["pipe", "pipe", "pipe"]
177
+ }).toString().trim();
178
+ } catch {
179
+ return null;
180
+ }
181
+ }
182
+ function canonicalCwd(cwd) {
183
+ try {
184
+ return realpathSync(cwd);
185
+ } catch {
186
+ return cwd;
187
+ }
188
+ }
189
+ function getRepoRoot(cwd) {
190
+ const root = gitOut(canonicalCwd(cwd), "rev-parse --show-toplevel");
191
+ return root && root.length > 0 ? root : null;
192
+ }
193
+ function getRepoSubpath(cwd) {
194
+ const prefix = gitOut(canonicalCwd(cwd), "rev-parse --show-prefix");
195
+ if (prefix === null)
196
+ return "";
197
+ return prefix.replace(/\\/g, "/").replace(/\/+$/, "").replace(/^\/+/, "");
198
+ }
199
+ function getRepoRemote(cwd) {
200
+ const c = canonicalCwd(cwd);
201
+ const origin = gitOut(c, "config --get remote.origin.url");
202
+ if (origin && origin.length > 0)
203
+ return origin;
204
+ const list = gitOut(c, "remote");
205
+ if (!list)
206
+ return null;
207
+ const remotes = list.split(`
208
+ `).map((s) => s.trim()).filter((s) => s.length > 0).sort();
209
+ if (remotes.length === 0)
210
+ return null;
211
+ const url = gitOut(c, `config --get remote.${remotes[0]}.url`);
212
+ return url && url.length > 0 ? url : null;
213
+ }
214
+ function normalizeRemoteUrl(url) {
215
+ if (!url)
216
+ return "";
217
+ let s = url.trim();
218
+ if (s.length === 0)
219
+ return "";
220
+ if (/^(file:|\.\.?\/|\/)/i.test(s))
221
+ return "";
222
+ const scp = s.match(/^([^@\s]+)@([^:\s]+):(.+)$/);
223
+ if (scp) {
224
+ s = `ssh://${scp[1]}@${scp[2]}/${scp[3]}`;
225
+ }
226
+ s = s.replace(/^[a-z][a-z0-9+.-]*:\/\//i, "");
227
+ s = s.replace(/^[^@/]*@/, "");
228
+ s = s.replace(/\/+$/, "").replace(/\.git$/i, "");
229
+ return s.toLowerCase();
230
+ }
231
+ function deriveGitIdentity(cwd) {
232
+ const root = getRepoRoot(cwd);
233
+ if (!root)
234
+ return null;
235
+ const remoteRaw = getRepoRemote(cwd);
236
+ if (!remoteRaw)
237
+ return null;
238
+ const remote = normalizeRemoteUrl(remoteRaw);
239
+ if (!remote)
240
+ return null;
241
+ const subpath = getRepoSubpath(cwd);
242
+ return { remote, subpath };
243
+ }
244
+ var GIT_TIMEOUT_MS = 2000;
245
+ var init_git_identity = () => {};
246
+
247
+ // src/core/fs-utils.ts
248
+ var exports_fs_utils = {};
249
+ __export(exports_fs_utils, {
250
+ safeReadJson: () => safeReadJson,
251
+ safeAppendText: () => safeAppendText,
252
+ atomicWriteText: () => atomicWriteText,
253
+ atomicWriteJson: () => atomicWriteJson
254
+ });
255
+ import { writeFileSync, readFileSync, appendFileSync, renameSync, mkdirSync } from "fs";
256
+ import { dirname } from "path";
257
+ function atomicWriteJson(filePath, data) {
258
+ const tmp = filePath + ".tmp";
259
+ mkdirSync(dirname(filePath), { recursive: true });
260
+ writeFileSync(tmp, JSON.stringify(data, null, 2));
261
+ renameSync(tmp, filePath);
262
+ }
263
+ function atomicWriteText(filePath, content) {
264
+ const tmp = filePath + ".tmp";
265
+ mkdirSync(dirname(filePath), { recursive: true });
266
+ writeFileSync(tmp, content);
267
+ renameSync(tmp, filePath);
268
+ }
269
+ function safeAppendText(filePath, content) {
270
+ mkdirSync(dirname(filePath), { recursive: true });
271
+ appendFileSync(filePath, content);
272
+ }
273
+ function safeReadJson(filePath) {
274
+ try {
275
+ const raw = readFileSync(filePath, "utf-8");
276
+ return JSON.parse(raw);
277
+ } catch {
278
+ return null;
279
+ }
280
+ }
281
+ var init_fs_utils = () => {};
282
+
283
+ // src/types/config.ts
284
+ function isValidConfigKey(key) {
285
+ return VALID_KEYS.has(key);
286
+ }
287
+ function getConfigKeyMeta(key) {
288
+ return CONFIG_KEYS.find((k) => k.key === key);
289
+ }
290
+ var CONFIG_KEYS, VALID_KEYS;
291
+ var init_config = __esm(() => {
292
+ CONFIG_KEYS = [
293
+ {
294
+ key: "wiki.path",
295
+ default: "~/.mink/wiki",
296
+ envVar: "MINK_WIKI_PATH",
297
+ description: "Wiki vault location",
298
+ scope: "local"
299
+ },
300
+ {
301
+ key: "wiki.enabled",
302
+ default: "true",
303
+ envVar: "MINK_WIKI_ENABLED",
304
+ description: "Enable/disable the wiki feature",
305
+ scope: "shared"
306
+ },
307
+ {
308
+ key: "wiki.sync-mode",
309
+ default: "immediate",
310
+ envVar: "MINK_WIKI_SYNC_MODE",
311
+ description: "Sync mode: immediate or batched",
312
+ scope: "shared"
313
+ },
314
+ {
315
+ key: "wiki.git-backup",
316
+ default: "false",
317
+ envVar: "MINK_WIKI_GIT_BACKUP",
318
+ description: "Deprecated: use sync.enabled instead",
319
+ scope: "shared"
320
+ },
321
+ {
322
+ key: "wiki.git-remote",
323
+ default: "origin",
324
+ envVar: "MINK_WIKI_GIT_REMOTE",
325
+ description: "Deprecated: use sync.remote-url instead",
326
+ scope: "shared"
327
+ },
328
+ {
329
+ key: "notes.default-category",
330
+ default: "inbox",
331
+ envVar: "MINK_NOTES_DEFAULT_CATEGORY",
332
+ description: "Default category for notes captured via CLI",
333
+ scope: "shared"
334
+ },
335
+ {
336
+ key: "sync.enabled",
337
+ default: "false",
338
+ envVar: "MINK_SYNC_ENABLED",
339
+ description: "Enable/disable automatic git sync of ~/.mink",
340
+ scope: "shared"
341
+ },
342
+ {
343
+ key: "sync.remote-url",
344
+ default: "",
345
+ envVar: "MINK_SYNC_REMOTE_URL",
346
+ description: "Git remote URL for ~/.mink sync",
347
+ scope: "shared"
348
+ },
349
+ {
350
+ key: "sync.last-push",
351
+ default: "",
352
+ envVar: "MINK_SYNC_LAST_PUSH",
353
+ description: "ISO timestamp of last successful sync push",
354
+ scope: "local"
355
+ },
356
+ {
357
+ key: "sync.last-pull",
358
+ default: "",
359
+ envVar: "MINK_SYNC_LAST_PULL",
360
+ description: "ISO timestamp of last successful sync pull",
361
+ scope: "local"
362
+ },
363
+ {
364
+ key: "channel.discord.bot-token",
365
+ default: "",
366
+ envVar: "MINK_CHANNEL_DISCORD_BOT_TOKEN",
367
+ description: "Discord bot token for Claude Code Channels",
368
+ scope: "local"
369
+ },
370
+ {
371
+ key: "channel.discord.enabled",
372
+ default: "false",
373
+ envVar: "MINK_CHANNEL_DISCORD_ENABLED",
374
+ description: "Auto-start Discord channel when daemon starts",
375
+ scope: "local"
376
+ },
377
+ {
378
+ key: "channel.discord.allowlist",
379
+ default: "",
380
+ envVar: "MINK_CHANNEL_DISCORD_ALLOWLIST",
381
+ description: "Comma-separated list of Discord user IDs permitted to DM the bot",
382
+ scope: "local"
383
+ },
384
+ {
385
+ key: "channel.default-platform",
386
+ default: "discord",
387
+ envVar: "MINK_CHANNEL_DEFAULT_PLATFORM",
388
+ description: "Default platform for mink channel start",
389
+ scope: "shared"
390
+ },
391
+ {
392
+ key: "channel.skip-permissions",
393
+ default: "true",
394
+ envVar: "MINK_CHANNEL_SKIP_PERMISSIONS",
395
+ description: "Pass --dangerously-skip-permissions so the channel can run without terminal prompts",
396
+ scope: "shared"
397
+ },
398
+ {
399
+ key: "cli.auto-update",
400
+ default: "false",
401
+ envVar: "MINK_CLI_AUTO_UPDATE",
402
+ description: "Auto-upgrade the mink CLI on schedule via the background scheduler",
403
+ scope: "shared"
404
+ },
405
+ {
406
+ key: "cli.auto-update-schedule",
407
+ default: "0 4 * * *",
408
+ envVar: "MINK_CLI_AUTO_UPDATE_SCHEDULE",
409
+ description: "Cron expression governing the cli-self-update scheduled task",
410
+ scope: "shared"
411
+ },
412
+ {
413
+ key: "cli.auto-update-package-manager",
414
+ default: "auto",
415
+ envVar: "MINK_CLI_AUTO_UPDATE_PACKAGE_MANAGER",
416
+ description: "Force a package manager (auto|npm|bun) for self-upgrade installs",
417
+ scope: "local"
418
+ },
419
+ {
420
+ key: "projects.identity",
421
+ default: "path-derived",
422
+ envVar: "MINK_PROJECTS_IDENTITY",
423
+ description: "Project identity strategy: path-derived (legacy) or git-remote (stable across machines)",
424
+ scope: "shared"
425
+ }
426
+ ];
427
+ VALID_KEYS = new Set(CONFIG_KEYS.map((k) => k.key));
428
+ });
429
+
430
+ // src/core/global-config.ts
431
+ var exports_global_config = {};
432
+ __export(exports_global_config, {
433
+ setConfigValue: () => setConfigValue,
434
+ saveLocalConfig: () => saveLocalConfig,
435
+ saveGlobalConfig: () => saveGlobalConfig,
436
+ resolveConfigValue: () => resolveConfigValue,
437
+ resolveAllConfig: () => resolveAllConfig,
438
+ resetConfigKey: () => resetConfigKey,
439
+ resetAllConfig: () => resetAllConfig,
440
+ migrateConfigIfNeeded: () => migrateConfigIfNeeded,
441
+ loadLocalConfig: () => loadLocalConfig,
442
+ loadGlobalConfig: () => loadGlobalConfig
443
+ });
444
+ function loadConfigFile(path) {
445
+ const raw = safeReadJson(path);
446
+ if (raw === null)
447
+ return {};
448
+ if (typeof raw !== "object" || Array.isArray(raw)) {
449
+ console.warn("[mink] warning: corrupt config file at " + path);
450
+ return {};
451
+ }
452
+ return raw;
453
+ }
454
+ function loadGlobalConfig() {
455
+ return loadConfigFile(globalConfigPath());
456
+ }
457
+ function saveGlobalConfig(config) {
458
+ atomicWriteJson(globalConfigPath(), config);
459
+ }
460
+ function loadLocalConfig() {
461
+ return loadConfigFile(localConfigPath());
462
+ }
463
+ function saveLocalConfig(config) {
464
+ atomicWriteJson(localConfigPath(), config);
465
+ }
466
+ function loadConfigForScope(scope) {
467
+ return scope === "local" ? loadLocalConfig() : loadGlobalConfig();
468
+ }
469
+ function saveConfigForScope(scope, config) {
470
+ if (scope === "local") {
471
+ saveLocalConfig(config);
472
+ } else {
473
+ saveGlobalConfig(config);
474
+ }
475
+ }
476
+ function resolveConfigValue(key) {
477
+ const meta = getConfigKeyMeta(key);
478
+ const config = loadConfigForScope(meta.scope);
479
+ const envValue = process.env[meta.envVar];
480
+ const fileValue = config[key];
481
+ if (envValue !== undefined && envValue !== "") {
482
+ return {
483
+ value: envValue,
484
+ source: "environment variable",
485
+ scope: meta.scope,
486
+ configFileValue: fileValue
487
+ };
488
+ }
489
+ if (fileValue !== undefined) {
490
+ return { value: fileValue, source: "config file", scope: meta.scope };
491
+ }
492
+ return { value: meta.default, source: "default", scope: meta.scope };
493
+ }
494
+ function resolveAllConfig() {
495
+ return CONFIG_KEYS.map((meta) => ({
496
+ key: meta.key,
497
+ ...resolveConfigValue(meta.key)
498
+ }));
499
+ }
500
+ function setConfigValue(key, value) {
501
+ const meta = getConfigKeyMeta(key);
502
+ const config = loadConfigForScope(meta.scope);
503
+ config[key] = value;
504
+ saveConfigForScope(meta.scope, config);
505
+ }
506
+ function resetConfigKey(key) {
507
+ const meta = getConfigKeyMeta(key);
508
+ const config = loadConfigForScope(meta.scope);
509
+ delete config[key];
510
+ saveConfigForScope(meta.scope, config);
511
+ }
512
+ function resetAllConfig() {
513
+ saveGlobalConfig({});
514
+ saveLocalConfig({});
515
+ }
516
+ function migrateConfigIfNeeded() {
517
+ if (migrationRan)
518
+ return;
519
+ migrationRan = true;
520
+ const { existsSync: existsSync2 } = __require("fs");
521
+ if (existsSync2(localConfigPath()))
522
+ return;
523
+ const shared = loadGlobalConfig();
524
+ const localKeys = CONFIG_KEYS.filter((k) => k.scope === "local");
525
+ const localConfig = {};
526
+ let hasLocal = false;
527
+ for (const meta of localKeys) {
528
+ const val = shared[meta.key];
529
+ if (val !== undefined) {
530
+ localConfig[meta.key] = val;
531
+ delete shared[meta.key];
532
+ hasLocal = true;
533
+ }
534
+ }
535
+ if (hasLocal) {
536
+ saveLocalConfig(localConfig);
537
+ saveGlobalConfig(shared);
538
+ }
539
+ }
540
+ var migrationRan = false;
541
+ var init_global_config = __esm(() => {
542
+ init_paths();
543
+ init_fs_utils();
544
+ init_config();
545
+ });
546
+
166
547
  // src/core/project-id.ts
167
548
  import { createHash } from "crypto";
168
- import { basename } from "path";
549
+ import { basename, join } from "path";
550
+ import { existsSync as existsSync2, readFileSync as readFileSync2 } from "fs";
169
551
  function slugify(name) {
170
552
  return name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
171
553
  }
554
+ function shortHash(input) {
555
+ return createHash("sha256").update(input).digest("hex").slice(0, 6);
556
+ }
172
557
  function generateProjectId(absolutePath) {
173
558
  const normalized = absolutePath.replace(/\/+$/, "");
174
559
  const slug = slugify(basename(normalized));
175
- const hash = createHash("sha256").update(normalized).digest("hex").slice(0, 6);
560
+ const hash = shortHash(normalized);
176
561
  return `${slug}-${hash}`;
177
562
  }
178
- var init_project_id = () => {};
563
+ function validateProjectIdentifier(id) {
564
+ return typeof id === "string" && IDENTIFIER_PATTERN.test(id);
565
+ }
566
+ function readProjectOverride(cwd) {
567
+ const root = getRepoRoot(cwd) ?? cwd;
568
+ const overridePath = join(root, OVERRIDE_RELATIVE_PATH);
569
+ if (!existsSync2(overridePath))
570
+ return null;
571
+ let raw;
572
+ try {
573
+ raw = readFileSync2(overridePath, "utf-8");
574
+ } catch {
575
+ return null;
576
+ }
577
+ let parsed;
578
+ try {
579
+ parsed = JSON.parse(raw);
580
+ } catch {
581
+ warnInvalidOverride(overridePath, "file is not valid JSON");
582
+ return null;
583
+ }
584
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
585
+ warnInvalidOverride(overridePath, "expected a JSON object");
586
+ return null;
587
+ }
588
+ const id = parsed.projectId;
589
+ if (id === undefined)
590
+ return null;
591
+ if (!validateProjectIdentifier(id)) {
592
+ warnInvalidOverride(overridePath, "projectId must start with a letter or digit, contain only [a-z0-9._-], and be 1–128 characters");
593
+ return null;
594
+ }
595
+ return id;
596
+ }
597
+ function warnInvalidOverride(path, reason) {
598
+ if (warnedOverrides.has(path))
599
+ return;
600
+ warnedOverrides.add(path);
601
+ console.warn(`[mink] ignoring ${path}: ${reason}`);
602
+ }
603
+ function gitDerivedIdentity(cwd) {
604
+ const components = deriveGitIdentity(cwd);
605
+ if (!components)
606
+ return null;
607
+ const remoteLeaf = components.remote.split("/").filter((p) => p).pop();
608
+ const slugSource = components.subpath ? components.subpath.split("/").pop() : remoteLeaf ?? "project";
609
+ const slug = slugify(slugSource);
610
+ const hash = shortHash(`git:${components.remote}:${components.subpath}`);
611
+ return `${slug}-${hash}`;
612
+ }
613
+ function readIdentityMode() {
614
+ const envOverride = process.env.MINK_PROJECTS_IDENTITY;
615
+ if (envOverride === "git-remote" || envOverride === "path-derived") {
616
+ return envOverride;
617
+ }
618
+ try {
619
+ const { resolveConfigValue: resolveConfigValue2 } = (init_global_config(), __toCommonJS(exports_global_config));
620
+ const v = resolveConfigValue2("projects.identity").value;
621
+ if (v === "git-remote")
622
+ return "git-remote";
623
+ } catch {}
624
+ return "path-derived";
625
+ }
626
+ function resolveProjectIdentity(cwd, modeOverride) {
627
+ const mode = modeOverride ?? readIdentityMode();
628
+ if (mode === "path-derived") {
629
+ return { id: generateProjectId(cwd), source: "path-derived" };
630
+ }
631
+ const override = readProjectOverride(cwd);
632
+ if (override)
633
+ return { id: override, source: "override" };
634
+ const git = gitDerivedIdentity(cwd);
635
+ if (git)
636
+ return { id: git, source: "git-remote" };
637
+ return { id: generateProjectId(cwd), source: "path-derived" };
638
+ }
639
+ function projectIdFor(cwd) {
640
+ return resolveProjectIdentity(cwd).id;
641
+ }
642
+ var IDENTIFIER_PATTERN, OVERRIDE_RELATIVE_PATH = ".mink/project.json", warnedOverrides;
643
+ var init_project_id = __esm(() => {
644
+ init_git_identity();
645
+ IDENTIFIER_PATTERN = /^[a-z0-9][a-z0-9._-]{0,127}$/;
646
+ warnedOverrides = new Set;
647
+ });
648
+
649
+ // src/core/project-registry.ts
650
+ var exports_project_registry = {};
651
+ __export(exports_project_registry, {
652
+ setProjectPathForDevice: () => setProjectPathForDevice,
653
+ listRegisteredProjects: () => listRegisteredProjects,
654
+ getProjectMeta: () => getProjectMeta,
655
+ findProjectDirByIdOrAlias: () => findProjectDirByIdOrAlias,
656
+ addProjectAlias: () => addProjectAlias
657
+ });
658
+ import { readdirSync, existsSync as existsSync3 } from "fs";
659
+ import { join as join2 } from "path";
660
+ function projectMetaFilePath(projDir) {
661
+ return join2(projDir, "project-meta.json");
662
+ }
663
+ function getProjectMeta(projDir) {
664
+ const raw = safeReadJson(projectMetaFilePath(projDir));
665
+ if (raw === null || typeof raw !== "object" || Array.isArray(raw))
666
+ return null;
667
+ const obj = raw;
668
+ if (typeof obj.cwd !== "string" || typeof obj.name !== "string")
669
+ return null;
670
+ const aliases = Array.isArray(obj.aliases) ? obj.aliases.filter((s) => typeof s === "string") : undefined;
671
+ const pathsByDevice = obj.pathsByDevice && typeof obj.pathsByDevice === "object" && !Array.isArray(obj.pathsByDevice) ? Object.fromEntries(Object.entries(obj.pathsByDevice).filter(([, v]) => typeof v === "string")) : undefined;
672
+ return {
673
+ cwd: obj.cwd,
674
+ name: obj.name,
675
+ initTimestamp: obj.initTimestamp ?? "",
676
+ version: obj.version ?? "0.1.0",
677
+ aliases,
678
+ pathsByDevice
679
+ };
680
+ }
681
+ function addProjectAlias(projDir, aliasId) {
682
+ const path = projectMetaFilePath(projDir);
683
+ const raw = safeReadJson(path);
684
+ if (raw === null || typeof raw !== "object" || Array.isArray(raw))
685
+ return false;
686
+ const obj = raw;
687
+ const existing = Array.isArray(obj.aliases) ? obj.aliases.filter((s) => typeof s === "string") : [];
688
+ if (existing.includes(aliasId))
689
+ return false;
690
+ obj.aliases = [...existing, aliasId];
691
+ atomicWriteJson(path, obj);
692
+ return true;
693
+ }
694
+ function setProjectPathForDevice(projDir, deviceId, cwd) {
695
+ const path = projectMetaFilePath(projDir);
696
+ const raw = safeReadJson(path);
697
+ if (raw === null || typeof raw !== "object" || Array.isArray(raw))
698
+ return;
699
+ const obj = raw;
700
+ const existing = obj.pathsByDevice && typeof obj.pathsByDevice === "object" && !Array.isArray(obj.pathsByDevice) ? { ...obj.pathsByDevice } : {};
701
+ if (Object.keys(existing).length === 0 && typeof obj.cwd === "string" && obj.cwd !== cwd) {
702
+ existing[deviceId] = obj.cwd;
703
+ }
704
+ existing[deviceId] = cwd;
705
+ obj.pathsByDevice = existing;
706
+ obj.cwd = cwd;
707
+ atomicWriteJson(path, obj);
708
+ }
709
+ function listRegisteredProjects() {
710
+ const projectsDir = join2(minkRoot(), "projects");
711
+ if (!existsSync3(projectsDir))
712
+ return [];
713
+ const entries = readdirSync(projectsDir, { withFileTypes: true });
714
+ const projects = [];
715
+ for (const entry of entries) {
716
+ if (!entry.isDirectory())
717
+ continue;
718
+ const projDir = join2(projectsDir, entry.name);
719
+ const meta = getProjectMeta(projDir);
720
+ if (meta) {
721
+ projects.push({
722
+ id: entry.name,
723
+ cwd: meta.cwd,
724
+ name: meta.name,
725
+ version: meta.version,
726
+ aliases: meta.aliases ?? [],
727
+ pathsByDevice: meta.pathsByDevice ?? {}
728
+ });
729
+ }
730
+ }
731
+ return projects;
732
+ }
733
+ function findProjectDirByIdOrAlias(id) {
734
+ const projectsDir = join2(minkRoot(), "projects");
735
+ if (!existsSync3(projectsDir))
736
+ return null;
737
+ const primary = join2(projectsDir, id);
738
+ if (existsSync3(primary))
739
+ return primary;
740
+ let entries;
741
+ try {
742
+ entries = readdirSync(projectsDir);
743
+ } catch {
744
+ return null;
745
+ }
746
+ for (const name of entries) {
747
+ const projDir = join2(projectsDir, name);
748
+ const meta = getProjectMeta(projDir);
749
+ if (meta?.aliases?.includes(id))
750
+ return projDir;
751
+ }
752
+ return null;
753
+ }
754
+ var init_project_registry = __esm(() => {
755
+ init_paths();
756
+ init_fs_utils();
757
+ });
179
758
 
180
759
  // src/core/paths.ts
181
760
  var exports_paths = {};
@@ -215,10 +794,11 @@ __export(exports_paths, {
215
794
  actionLogShardPath: () => actionLogShardPath,
216
795
  actionLogPath: () => actionLogPath
217
796
  });
218
- import { join } from "path";
797
+ import { join as join3 } from "path";
798
+ import { existsSync as existsSync4 } from "fs";
219
799
  import { homedir } from "os";
220
800
  function resolveMinkRoot() {
221
- return process.env.MINK_ROOT_OVERRIDE || join(homedir(), ".mink");
801
+ return process.env.MINK_ROOT_OVERRIDE || join3(homedir(), ".mink");
222
802
  }
223
803
  function minkRoot() {
224
804
  if (process.env.MINK_ROOT_OVERRIDE) {
@@ -227,104 +807,113 @@ function minkRoot() {
227
807
  return MINK_ROOT;
228
808
  }
229
809
  function projectDir(cwd) {
230
- const id = generateProjectId(cwd);
231
- return join(minkRoot(), "projects", id);
810
+ const id = projectIdFor(cwd);
811
+ const primary = join3(minkRoot(), "projects", id);
812
+ if (existsSync4(primary))
813
+ return primary;
814
+ try {
815
+ const { findProjectDirByIdOrAlias: findProjectDirByIdOrAlias2 } = (init_project_registry(), __toCommonJS(exports_project_registry));
816
+ const aliased = findProjectDirByIdOrAlias2(id);
817
+ if (aliased)
818
+ return aliased;
819
+ } catch {}
820
+ return primary;
232
821
  }
233
822
  function sessionPath(cwd) {
234
- return join(projectDir(cwd), "session.json");
823
+ return join3(projectDir(cwd), "session.json");
235
824
  }
236
825
  function fileIndexPath(cwd) {
237
- return join(projectDir(cwd), "file-index.json");
826
+ return join3(projectDir(cwd), "file-index.json");
238
827
  }
239
828
  function configPath(cwd) {
240
- return join(projectDir(cwd), "config.json");
829
+ return join3(projectDir(cwd), "config.json");
241
830
  }
242
831
  function learningMemoryPath(cwd) {
243
- return join(projectDir(cwd), "learning-memory.md");
832
+ return join3(projectDir(cwd), "learning-memory.md");
244
833
  }
245
834
  function tokenLedgerPath(cwd) {
246
- return join(projectDir(cwd), "token-ledger.json");
835
+ return join3(projectDir(cwd), "token-ledger.json");
247
836
  }
248
837
  function tokenLedgerArchivePath(cwd) {
249
- return join(projectDir(cwd), "token-ledger-archive.json");
838
+ return join3(projectDir(cwd), "token-ledger-archive.json");
250
839
  }
251
840
  function bugMemoryPath(cwd) {
252
- return join(projectDir(cwd), "bug-memory.json");
841
+ return join3(projectDir(cwd), "bug-memory.json");
253
842
  }
254
843
  function actionLogPath(cwd) {
255
- return join(projectDir(cwd), "action-log.md");
844
+ return join3(projectDir(cwd), "action-log.md");
256
845
  }
257
846
  function schedulerPidPath() {
258
- return join(minkRoot(), "scheduler.pid");
847
+ return join3(minkRoot(), "scheduler.pid");
259
848
  }
260
849
  function schedulerLogPath() {
261
- return join(minkRoot(), "scheduler.log");
850
+ return join3(minkRoot(), "scheduler.log");
262
851
  }
263
852
  function schedulerManifestPath(cwd) {
264
- return join(projectDir(cwd), "scheduler-manifest.json");
853
+ return join3(projectDir(cwd), "scheduler-manifest.json");
265
854
  }
266
855
  function channelPidPath() {
267
- return join(minkRoot(), "channel.pid");
856
+ return join3(minkRoot(), "channel.pid");
268
857
  }
269
858
  function channelLogPath() {
270
- return join(minkRoot(), "channel.log");
859
+ return join3(minkRoot(), "channel.log");
271
860
  }
272
861
  function globalConfigPath() {
273
- return join(minkRoot(), "config");
862
+ return join3(minkRoot(), "config");
274
863
  }
275
864
  function localConfigPath() {
276
- return join(minkRoot(), "config.local");
865
+ return join3(minkRoot(), "config.local");
277
866
  }
278
867
  function deviceIdPath() {
279
- return join(minkRoot(), "device-id");
868
+ return join3(minkRoot(), "device-id");
280
869
  }
281
870
  function deviceRegistryPath() {
282
- return join(minkRoot(), "devices.json");
871
+ return join3(minkRoot(), "devices.json");
283
872
  }
284
873
  function projectMetaPath(cwd) {
285
- return join(projectDir(cwd), "project-meta.json");
874
+ return join3(projectDir(cwd), "project-meta.json");
286
875
  }
287
876
  function backupDirPath(cwd) {
288
- return join(projectDir(cwd), "backups");
877
+ return join3(projectDir(cwd), "backups");
289
878
  }
290
879
  function syncVersionPath() {
291
- return join(minkRoot(), ".mink-sync-version");
880
+ return join3(minkRoot(), ".mink-sync-version");
292
881
  }
293
882
  function projectStateDir(cwd) {
294
- return join(projectDir(cwd), "state");
883
+ return join3(projectDir(cwd), "state");
295
884
  }
296
885
  function deviceShardDir(cwd, deviceId) {
297
- return join(projectStateDir(cwd), deviceId);
886
+ return join3(projectStateDir(cwd), deviceId);
298
887
  }
299
888
  function tokenLedgerShardPath(cwd, deviceId) {
300
- return join(deviceShardDir(cwd, deviceId), "token-ledger.json");
889
+ return join3(deviceShardDir(cwd, deviceId), "token-ledger.json");
301
890
  }
302
891
  function tokenLedgerArchiveShardPath(cwd, deviceId) {
303
- return join(deviceShardDir(cwd, deviceId), "token-ledger-archive.json");
892
+ return join3(deviceShardDir(cwd, deviceId), "token-ledger-archive.json");
304
893
  }
305
894
  function bugMemoryShardPath(cwd, deviceId) {
306
- return join(deviceShardDir(cwd, deviceId), "bug-memory.json");
895
+ return join3(deviceShardDir(cwd, deviceId), "bug-memory.json");
307
896
  }
308
897
  function actionLogShardPath(cwd, deviceId) {
309
- return join(deviceShardDir(cwd, deviceId), "action-log.md");
898
+ return join3(deviceShardDir(cwd, deviceId), "action-log.md");
310
899
  }
311
900
  function learningMemorySidecarPath(cwd, deviceId) {
312
- return join(projectDir(cwd), `learning-memory.${deviceId}.md`);
901
+ return join3(projectDir(cwd), `learning-memory.${deviceId}.md`);
313
902
  }
314
903
  function fileIndexCountersPath(cwd) {
315
- return join(projectDir(cwd), ".mink-state-counters.json");
904
+ return join3(projectDir(cwd), ".mink-state-counters.json");
316
905
  }
317
906
  function designCapturesDir(cwd) {
318
- return join(projectDir(cwd), "design-captures");
907
+ return join3(projectDir(cwd), "design-captures");
319
908
  }
320
909
  function designReportPath(cwd) {
321
- return join(projectDir(cwd), "design-report.json");
910
+ return join3(projectDir(cwd), "design-report.json");
322
911
  }
323
912
  function frameworkAdvisorPath(cwd) {
324
- return join(projectDir(cwd), "framework-advisor.md");
913
+ return join3(projectDir(cwd), "framework-advisor.md");
325
914
  }
326
915
  function frameworkAdvisorJsonPath(cwd) {
327
- return join(projectDir(cwd), "framework-advisor.json");
916
+ return join3(projectDir(cwd), "framework-advisor.json");
328
917
  }
329
918
  var MINK_ROOT;
330
919
  var init_paths = __esm(() => {
@@ -332,42 +921,6 @@ var init_paths = __esm(() => {
332
921
  MINK_ROOT = resolveMinkRoot();
333
922
  });
334
923
 
335
- // src/core/fs-utils.ts
336
- var exports_fs_utils = {};
337
- __export(exports_fs_utils, {
338
- safeReadJson: () => safeReadJson,
339
- safeAppendText: () => safeAppendText,
340
- atomicWriteText: () => atomicWriteText,
341
- atomicWriteJson: () => atomicWriteJson
342
- });
343
- import { writeFileSync, readFileSync, appendFileSync, renameSync, mkdirSync } from "fs";
344
- import { dirname } from "path";
345
- function atomicWriteJson(filePath, data) {
346
- const tmp = filePath + ".tmp";
347
- mkdirSync(dirname(filePath), { recursive: true });
348
- writeFileSync(tmp, JSON.stringify(data, null, 2));
349
- renameSync(tmp, filePath);
350
- }
351
- function atomicWriteText(filePath, content) {
352
- const tmp = filePath + ".tmp";
353
- mkdirSync(dirname(filePath), { recursive: true });
354
- writeFileSync(tmp, content);
355
- renameSync(tmp, filePath);
356
- }
357
- function safeAppendText(filePath, content) {
358
- mkdirSync(dirname(filePath), { recursive: true });
359
- appendFileSync(filePath, content);
360
- }
361
- function safeReadJson(filePath) {
362
- try {
363
- const raw = readFileSync(filePath, "utf-8");
364
- return JSON.parse(raw);
365
- } catch {
366
- return null;
367
- }
368
- }
369
- var init_fs_utils = () => {};
370
-
371
924
  // src/core/action-log.ts
372
925
  var exports_action_log = {};
373
926
  __export(exports_action_log, {
@@ -386,7 +939,7 @@ __export(exports_action_log, {
386
939
  consolidateLog: () => consolidateLog,
387
940
  appendToLog: () => appendToLog
388
941
  });
389
- import { readFileSync as readFileSync2 } from "fs";
942
+ import { readFileSync as readFileSync3 } from "fs";
390
943
  function truncatePath(filePath, maxLen = 60) {
391
944
  if (filePath.length <= maxLen)
392
945
  return filePath;
@@ -473,7 +1026,7 @@ function appendToLog(logPath, text) {
473
1026
  }
474
1027
  function safeReadLog(logPath) {
475
1028
  try {
476
- return readFileSync2(logPath, "utf-8");
1029
+ return readFileSync3(logPath, "utf-8");
477
1030
  } catch {
478
1031
  return "";
479
1032
  }
@@ -618,14 +1171,14 @@ __export(exports_device, {
618
1171
  listDevices: () => listDevices,
619
1172
  getOrCreateDeviceId: () => getOrCreateDeviceId
620
1173
  });
621
- import { existsSync, readFileSync as readFileSync3, writeFileSync as writeFileSync2, mkdirSync as mkdirSync2 } from "fs";
1174
+ import { existsSync as existsSync5, readFileSync as readFileSync4, writeFileSync as writeFileSync2, mkdirSync as mkdirSync2 } from "fs";
622
1175
  import { dirname as dirname2 } from "path";
623
1176
  import { hostname, platform } from "os";
624
1177
  import { randomUUID } from "crypto";
625
1178
  function getOrCreateDeviceId() {
626
1179
  const idPath = deviceIdPath();
627
- if (existsSync(idPath)) {
628
- return readFileSync3(idPath, "utf-8").trim();
1180
+ if (existsSync5(idPath)) {
1181
+ return readFileSync4(idPath, "utf-8").trim();
629
1182
  }
630
1183
  const id = randomUUID();
631
1184
  mkdirSync2(dirname2(idPath), { recursive: true });
@@ -683,263 +1236,6 @@ var init_device = __esm(() => {
683
1236
  init_fs_utils();
684
1237
  });
685
1238
 
686
- // src/types/config.ts
687
- function isValidConfigKey(key) {
688
- return VALID_KEYS.has(key);
689
- }
690
- function getConfigKeyMeta(key) {
691
- return CONFIG_KEYS.find((k) => k.key === key);
692
- }
693
- var CONFIG_KEYS, VALID_KEYS;
694
- var init_config = __esm(() => {
695
- CONFIG_KEYS = [
696
- {
697
- key: "wiki.path",
698
- default: "~/.mink/wiki",
699
- envVar: "MINK_WIKI_PATH",
700
- description: "Wiki vault location",
701
- scope: "local"
702
- },
703
- {
704
- key: "wiki.enabled",
705
- default: "true",
706
- envVar: "MINK_WIKI_ENABLED",
707
- description: "Enable/disable the wiki feature",
708
- scope: "shared"
709
- },
710
- {
711
- key: "wiki.sync-mode",
712
- default: "immediate",
713
- envVar: "MINK_WIKI_SYNC_MODE",
714
- description: "Sync mode: immediate or batched",
715
- scope: "shared"
716
- },
717
- {
718
- key: "wiki.git-backup",
719
- default: "false",
720
- envVar: "MINK_WIKI_GIT_BACKUP",
721
- description: "Deprecated: use sync.enabled instead",
722
- scope: "shared"
723
- },
724
- {
725
- key: "wiki.git-remote",
726
- default: "origin",
727
- envVar: "MINK_WIKI_GIT_REMOTE",
728
- description: "Deprecated: use sync.remote-url instead",
729
- scope: "shared"
730
- },
731
- {
732
- key: "notes.default-category",
733
- default: "inbox",
734
- envVar: "MINK_NOTES_DEFAULT_CATEGORY",
735
- description: "Default category for notes captured via CLI",
736
- scope: "shared"
737
- },
738
- {
739
- key: "sync.enabled",
740
- default: "false",
741
- envVar: "MINK_SYNC_ENABLED",
742
- description: "Enable/disable automatic git sync of ~/.mink",
743
- scope: "shared"
744
- },
745
- {
746
- key: "sync.remote-url",
747
- default: "",
748
- envVar: "MINK_SYNC_REMOTE_URL",
749
- description: "Git remote URL for ~/.mink sync",
750
- scope: "shared"
751
- },
752
- {
753
- key: "sync.last-push",
754
- default: "",
755
- envVar: "MINK_SYNC_LAST_PUSH",
756
- description: "ISO timestamp of last successful sync push",
757
- scope: "local"
758
- },
759
- {
760
- key: "sync.last-pull",
761
- default: "",
762
- envVar: "MINK_SYNC_LAST_PULL",
763
- description: "ISO timestamp of last successful sync pull",
764
- scope: "local"
765
- },
766
- {
767
- key: "channel.discord.bot-token",
768
- default: "",
769
- envVar: "MINK_CHANNEL_DISCORD_BOT_TOKEN",
770
- description: "Discord bot token for Claude Code Channels",
771
- scope: "local"
772
- },
773
- {
774
- key: "channel.discord.enabled",
775
- default: "false",
776
- envVar: "MINK_CHANNEL_DISCORD_ENABLED",
777
- description: "Auto-start Discord channel when daemon starts",
778
- scope: "local"
779
- },
780
- {
781
- key: "channel.discord.allowlist",
782
- default: "",
783
- envVar: "MINK_CHANNEL_DISCORD_ALLOWLIST",
784
- description: "Comma-separated list of Discord user IDs permitted to DM the bot",
785
- scope: "local"
786
- },
787
- {
788
- key: "channel.default-platform",
789
- default: "discord",
790
- envVar: "MINK_CHANNEL_DEFAULT_PLATFORM",
791
- description: "Default platform for mink channel start",
792
- scope: "shared"
793
- },
794
- {
795
- key: "channel.skip-permissions",
796
- default: "true",
797
- envVar: "MINK_CHANNEL_SKIP_PERMISSIONS",
798
- description: "Pass --dangerously-skip-permissions so the channel can run without terminal prompts",
799
- scope: "shared"
800
- },
801
- {
802
- key: "cli.auto-update",
803
- default: "false",
804
- envVar: "MINK_CLI_AUTO_UPDATE",
805
- description: "Auto-upgrade the mink CLI on schedule via the background scheduler",
806
- scope: "shared"
807
- },
808
- {
809
- key: "cli.auto-update-schedule",
810
- default: "0 4 * * *",
811
- envVar: "MINK_CLI_AUTO_UPDATE_SCHEDULE",
812
- description: "Cron expression governing the cli-self-update scheduled task",
813
- scope: "shared"
814
- },
815
- {
816
- key: "cli.auto-update-package-manager",
817
- default: "auto",
818
- envVar: "MINK_CLI_AUTO_UPDATE_PACKAGE_MANAGER",
819
- description: "Force a package manager (auto|npm|bun) for self-upgrade installs",
820
- scope: "local"
821
- }
822
- ];
823
- VALID_KEYS = new Set(CONFIG_KEYS.map((k) => k.key));
824
- });
825
-
826
- // src/core/global-config.ts
827
- var exports_global_config = {};
828
- __export(exports_global_config, {
829
- setConfigValue: () => setConfigValue,
830
- saveLocalConfig: () => saveLocalConfig,
831
- saveGlobalConfig: () => saveGlobalConfig,
832
- resolveConfigValue: () => resolveConfigValue,
833
- resolveAllConfig: () => resolveAllConfig,
834
- resetConfigKey: () => resetConfigKey,
835
- resetAllConfig: () => resetAllConfig,
836
- migrateConfigIfNeeded: () => migrateConfigIfNeeded,
837
- loadLocalConfig: () => loadLocalConfig,
838
- loadGlobalConfig: () => loadGlobalConfig
839
- });
840
- function loadConfigFile(path) {
841
- const raw = safeReadJson(path);
842
- if (raw === null)
843
- return {};
844
- if (typeof raw !== "object" || Array.isArray(raw)) {
845
- console.warn("[mink] warning: corrupt config file at " + path);
846
- return {};
847
- }
848
- return raw;
849
- }
850
- function loadGlobalConfig() {
851
- return loadConfigFile(globalConfigPath());
852
- }
853
- function saveGlobalConfig(config) {
854
- atomicWriteJson(globalConfigPath(), config);
855
- }
856
- function loadLocalConfig() {
857
- return loadConfigFile(localConfigPath());
858
- }
859
- function saveLocalConfig(config) {
860
- atomicWriteJson(localConfigPath(), config);
861
- }
862
- function loadConfigForScope(scope) {
863
- return scope === "local" ? loadLocalConfig() : loadGlobalConfig();
864
- }
865
- function saveConfigForScope(scope, config) {
866
- if (scope === "local") {
867
- saveLocalConfig(config);
868
- } else {
869
- saveGlobalConfig(config);
870
- }
871
- }
872
- function resolveConfigValue(key) {
873
- const meta = getConfigKeyMeta(key);
874
- const config = loadConfigForScope(meta.scope);
875
- const envValue = process.env[meta.envVar];
876
- const fileValue = config[key];
877
- if (envValue !== undefined && envValue !== "") {
878
- return {
879
- value: envValue,
880
- source: "environment variable",
881
- scope: meta.scope,
882
- configFileValue: fileValue
883
- };
884
- }
885
- if (fileValue !== undefined) {
886
- return { value: fileValue, source: "config file", scope: meta.scope };
887
- }
888
- return { value: meta.default, source: "default", scope: meta.scope };
889
- }
890
- function resolveAllConfig() {
891
- return CONFIG_KEYS.map((meta) => ({
892
- key: meta.key,
893
- ...resolveConfigValue(meta.key)
894
- }));
895
- }
896
- function setConfigValue(key, value) {
897
- const meta = getConfigKeyMeta(key);
898
- const config = loadConfigForScope(meta.scope);
899
- config[key] = value;
900
- saveConfigForScope(meta.scope, config);
901
- }
902
- function resetConfigKey(key) {
903
- const meta = getConfigKeyMeta(key);
904
- const config = loadConfigForScope(meta.scope);
905
- delete config[key];
906
- saveConfigForScope(meta.scope, config);
907
- }
908
- function resetAllConfig() {
909
- saveGlobalConfig({});
910
- saveLocalConfig({});
911
- }
912
- function migrateConfigIfNeeded() {
913
- if (migrationRan)
914
- return;
915
- migrationRan = true;
916
- const { existsSync: existsSync2 } = __require("fs");
917
- if (existsSync2(localConfigPath()))
918
- return;
919
- const shared = loadGlobalConfig();
920
- const localKeys = CONFIG_KEYS.filter((k) => k.scope === "local");
921
- const localConfig = {};
922
- let hasLocal = false;
923
- for (const meta of localKeys) {
924
- const val = shared[meta.key];
925
- if (val !== undefined) {
926
- localConfig[meta.key] = val;
927
- delete shared[meta.key];
928
- hasLocal = true;
929
- }
930
- }
931
- if (hasLocal) {
932
- saveLocalConfig(localConfig);
933
- saveGlobalConfig(shared);
934
- }
935
- }
936
- var migrationRan = false;
937
- var init_global_config = __esm(() => {
938
- init_paths();
939
- init_fs_utils();
940
- init_config();
941
- });
942
-
943
1239
  // src/core/vault.ts
944
1240
  var exports_vault = {};
945
1241
  __export(exports_vault, {
@@ -966,54 +1262,54 @@ __export(exports_vault, {
966
1262
  ensureVaultStructure: () => ensureVaultStructure,
967
1263
  categoryToDir: () => categoryToDir
968
1264
  });
969
- import { join as join2, basename as basename2, resolve } from "path";
1265
+ import { join as join4, basename as basename2, resolve } from "path";
970
1266
  import { homedir as homedir2 } from "os";
971
- import { existsSync as existsSync2, mkdirSync as mkdirSync3, symlinkSync, unlinkSync, lstatSync, readlinkSync } from "fs";
1267
+ import { existsSync as existsSync6, mkdirSync as mkdirSync3, symlinkSync, unlinkSync, lstatSync, readlinkSync } from "fs";
972
1268
  function resolveVaultPath() {
973
1269
  const resolved = resolveConfigValue("wiki.path");
974
1270
  const raw = resolved.value;
975
- const expanded = raw.startsWith("~/") ? join2(homedir2(), raw.slice(2)) : raw;
1271
+ const expanded = raw.startsWith("~/") ? join4(homedir2(), raw.slice(2)) : raw;
976
1272
  return resolve(expanded);
977
1273
  }
978
1274
  function vaultRoot() {
979
1275
  return resolveVaultPath();
980
1276
  }
981
1277
  function vaultInbox() {
982
- return join2(resolveVaultPath(), "inbox");
1278
+ return join4(resolveVaultPath(), "inbox");
983
1279
  }
984
1280
  function vaultProjects(slug) {
985
- const base = join2(resolveVaultPath(), "projects");
986
- return slug ? join2(base, slug) : base;
1281
+ const base = join4(resolveVaultPath(), "projects");
1282
+ return slug ? join4(base, slug) : base;
987
1283
  }
988
1284
  function vaultAreas() {
989
- return join2(resolveVaultPath(), "areas");
1285
+ return join4(resolveVaultPath(), "areas");
990
1286
  }
991
1287
  function vaultDailyDir() {
992
- return join2(resolveVaultPath(), "areas", "daily");
1288
+ return join4(resolveVaultPath(), "areas", "daily");
993
1289
  }
994
1290
  function vaultResources() {
995
- return join2(resolveVaultPath(), "resources");
1291
+ return join4(resolveVaultPath(), "resources");
996
1292
  }
997
1293
  function vaultArchives() {
998
- return join2(resolveVaultPath(), "archives");
1294
+ return join4(resolveVaultPath(), "archives");
999
1295
  }
1000
1296
  function vaultTemplates() {
1001
- return join2(resolveVaultPath(), "templates");
1297
+ return join4(resolveVaultPath(), "templates");
1002
1298
  }
1003
1299
  function vaultPatterns() {
1004
- return join2(resolveVaultPath(), "patterns");
1300
+ return join4(resolveVaultPath(), "patterns");
1005
1301
  }
1006
1302
  function vaultManifestPath() {
1007
- return join2(resolveVaultPath(), ".mink-vault.json");
1303
+ return join4(resolveVaultPath(), ".mink-vault.json");
1008
1304
  }
1009
1305
  function vaultIndexPath() {
1010
- return join2(resolveVaultPath(), ".mink-index.json");
1306
+ return join4(resolveVaultPath(), ".mink-index.json");
1011
1307
  }
1012
1308
  function vaultMasterIndexPath() {
1013
- return join2(resolveVaultPath(), "_index.md");
1309
+ return join4(resolveVaultPath(), "_index.md");
1014
1310
  }
1015
1311
  function isVaultInitialized() {
1016
- return existsSync2(vaultManifestPath());
1312
+ return existsSync6(vaultManifestPath());
1017
1313
  }
1018
1314
  function isInsideVault(cwd) {
1019
1315
  const vault = resolveVaultPath();
@@ -1034,23 +1330,23 @@ function loadVaultManifest() {
1034
1330
  function ensureVaultStructure() {
1035
1331
  const root = resolveVaultPath();
1036
1332
  for (const dir of VAULT_DIRS) {
1037
- mkdirSync3(join2(root, dir), { recursive: true });
1333
+ mkdirSync3(join4(root, dir), { recursive: true });
1038
1334
  }
1039
1335
  }
1040
1336
  function categoryToDir(category, projectSlug) {
1041
1337
  const root = resolveVaultPath();
1042
1338
  switch (category) {
1043
1339
  case "projects":
1044
- return projectSlug ? join2(root, "projects", projectSlug) : join2(root, "projects");
1340
+ return projectSlug ? join4(root, "projects", projectSlug) : join4(root, "projects");
1045
1341
  case "areas":
1046
- return join2(root, "areas");
1342
+ return join4(root, "areas");
1047
1343
  case "resources":
1048
- return join2(root, "resources");
1344
+ return join4(root, "resources");
1049
1345
  case "archives":
1050
- return join2(root, "archives");
1346
+ return join4(root, "archives");
1051
1347
  case "inbox":
1052
1348
  default:
1053
- return join2(root, "inbox");
1349
+ return join4(root, "inbox");
1054
1350
  }
1055
1351
  }
1056
1352
  function saveManifest(manifest) {
@@ -1058,16 +1354,16 @@ function saveManifest(manifest) {
1058
1354
  }
1059
1355
  function linkExternal(targetPath, name) {
1060
1356
  const root = resolveVaultPath();
1061
- const absTarget = targetPath.startsWith("~/") ? join2(homedir2(), targetPath.slice(2)) : resolve(targetPath);
1062
- if (!existsSync2(absTarget)) {
1357
+ const absTarget = targetPath.startsWith("~/") ? join4(homedir2(), targetPath.slice(2)) : resolve(targetPath);
1358
+ if (!existsSync6(absTarget)) {
1063
1359
  return { ok: false, error: `target does not exist: ${absTarget}` };
1064
1360
  }
1065
1361
  if (!lstatSync(absTarget).isDirectory()) {
1066
1362
  return { ok: false, error: `target is not a directory: ${absTarget}` };
1067
1363
  }
1068
1364
  const linkName = name ?? basename2(absTarget);
1069
- const linkPath = join2(root, linkName);
1070
- if (existsSync2(linkPath)) {
1365
+ const linkPath = join4(root, linkName);
1366
+ if (existsSync6(linkPath)) {
1071
1367
  if (lstatSync(linkPath).isSymbolicLink()) {
1072
1368
  const existing = readlinkSync(linkPath);
1073
1369
  if (existing === absTarget) {
@@ -1089,8 +1385,8 @@ function linkExternal(targetPath, name) {
1089
1385
  }
1090
1386
  function unlinkExternal(name) {
1091
1387
  const root = resolveVaultPath();
1092
- const linkPath = join2(root, name);
1093
- if (!existsSync2(linkPath)) {
1388
+ const linkPath = join4(root, name);
1389
+ if (!existsSync6(linkPath)) {
1094
1390
  return { ok: false, error: `no link named "${name}" in the vault` };
1095
1391
  }
1096
1392
  if (!lstatSync(linkPath).isSymbolicLink()) {
@@ -1113,7 +1409,7 @@ var init_vault = __esm(() => {
1113
1409
  init_global_config();
1114
1410
  init_fs_utils();
1115
1411
  init_fs_utils();
1116
- DEFAULT_VAULT_PATH = join2(homedir2(), ".mink", "wiki");
1412
+ DEFAULT_VAULT_PATH = join4(homedir2(), ".mink", "wiki");
1117
1413
  VAULT_DIRS = [
1118
1414
  "",
1119
1415
  "inbox",
@@ -1128,8 +1424,8 @@ var init_vault = __esm(() => {
1128
1424
  });
1129
1425
 
1130
1426
  // src/core/note-index.ts
1131
- import { join as join3 } from "path";
1132
- import { readFileSync as readFileSync4, readdirSync, statSync } from "fs";
1427
+ import { join as join5 } from "path";
1428
+ import { readFileSync as readFileSync5, readdirSync as readdirSync2, statSync } from "fs";
1133
1429
  function createEmptyVaultIndex() {
1134
1430
  return {
1135
1431
  lastScanTimestamp: "",
@@ -1262,7 +1558,7 @@ function rebuildVaultIndex() {
1262
1558
  const files = collectAllMarkdown(root);
1263
1559
  for (const file of files) {
1264
1560
  try {
1265
- const content = readFileSync4(file.absolutePath, "utf-8");
1561
+ const content = readFileSync5(file.absolutePath, "utf-8");
1266
1562
  const entry = buildEntryFromContent(file.relativePath, content, new Date(file.mtimeMs).toISOString());
1267
1563
  updateVaultEntry(index, entry);
1268
1564
  } catch {}
@@ -1320,13 +1616,13 @@ function collectAllMarkdown(rootPath) {
1320
1616
  const files = [];
1321
1617
  function walk(dir) {
1322
1618
  try {
1323
- const entries = readdirSync(dir, { withFileTypes: true });
1619
+ const entries = readdirSync2(dir, { withFileTypes: true });
1324
1620
  for (const entry of entries) {
1325
1621
  if (VAULT_EXCLUDES.has(entry.name))
1326
1622
  continue;
1327
1623
  if (entry.name.startsWith("."))
1328
1624
  continue;
1329
- const fullPath = join3(dir, entry.name);
1625
+ const fullPath = join5(dir, entry.name);
1330
1626
  if (entry.isDirectory()) {
1331
1627
  walk(fullPath);
1332
1628
  } else if (entry.name.endsWith(".md")) {
@@ -1357,11 +1653,11 @@ var init_note_index = __esm(() => {
1357
1653
  });
1358
1654
 
1359
1655
  // src/core/conflict-park.ts
1360
- import { execSync } from "child_process";
1361
- import { existsSync as existsSync4 } from "fs";
1362
- import { join as join4 } from "path";
1656
+ import { execSync as execSync2 } from "child_process";
1657
+ import { existsSync as existsSync8 } from "fs";
1658
+ import { join as join6 } from "path";
1363
1659
  function git(args) {
1364
- return execSync(`git ${args}`, {
1660
+ return execSync2(`git ${args}`, {
1365
1661
  cwd: minkRoot(),
1366
1662
  timeout: GIT_TIMEOUT,
1367
1663
  stdio: ["pipe", "pipe", "pipe"]
@@ -1376,7 +1672,7 @@ function gitSafe(args) {
1376
1672
  }
1377
1673
  function parkConflictingState(reason) {
1378
1674
  const root = minkRoot();
1379
- const inMerge = existsSync4(join4(root, ".git", "MERGE_HEAD")) || existsSync4(join4(root, ".git", "rebase-merge")) || existsSync4(join4(root, ".git", "rebase-apply"));
1675
+ const inMerge = existsSync8(join6(root, ".git", "MERGE_HEAD")) || existsSync8(join6(root, ".git", "rebase-merge")) || existsSync8(join6(root, ".git", "rebase-apply"));
1380
1676
  if (inMerge) {
1381
1677
  gitSafe("merge --abort");
1382
1678
  gitSafe("rebase --abort");
@@ -1433,12 +1729,12 @@ __export(exports_sync, {
1433
1729
  disconnectSync: () => disconnectSync,
1434
1730
  MINK_SYNC_VERSION: () => MINK_SYNC_VERSION
1435
1731
  });
1436
- import { existsSync as existsSync5, writeFileSync as writeFileSync3, readFileSync as readFileSync5 } from "fs";
1437
- import { join as join5 } from "path";
1438
- import { execSync as execSync2 } from "child_process";
1732
+ import { existsSync as existsSync9, writeFileSync as writeFileSync3, readFileSync as readFileSync6 } from "fs";
1733
+ import { join as join7 } from "path";
1734
+ import { execSync as execSync3 } from "child_process";
1439
1735
  function readSyncVersion() {
1440
1736
  try {
1441
- const raw = readFileSync5(syncVersionPath(), "utf-8").trim();
1737
+ const raw = readFileSync6(syncVersionPath(), "utf-8").trim();
1442
1738
  const n = parseInt(raw, 10);
1443
1739
  return Number.isFinite(n) && n > 0 ? n : 1;
1444
1740
  } catch {
@@ -1450,7 +1746,7 @@ function writeSyncVersion(version) {
1450
1746
  `);
1451
1747
  }
1452
1748
  function git2(args, timeoutMs = GIT_TIMEOUT2) {
1453
- return execSync2(`git ${args}`, {
1749
+ return execSync3(`git ${args}`, {
1454
1750
  cwd: minkRoot(),
1455
1751
  timeout: timeoutMs,
1456
1752
  stdio: ["pipe", "pipe", "pipe"]
@@ -1467,14 +1763,14 @@ function isSyncInitialized() {
1467
1763
  const enabled = resolveConfigValue("sync.enabled").value;
1468
1764
  if (enabled !== "true")
1469
1765
  return false;
1470
- return existsSync5(join5(minkRoot(), ".git"));
1766
+ return existsSync9(join7(minkRoot(), ".git"));
1471
1767
  }
1472
1768
  function ensureGitignore() {
1473
- const gitignorePath = join5(minkRoot(), ".gitignore");
1769
+ const gitignorePath = join7(minkRoot(), ".gitignore");
1474
1770
  writeFileSync3(gitignorePath, GITIGNORE_CONTENTS);
1475
1771
  }
1476
1772
  function ensureGitAttributes() {
1477
- const path = join5(minkRoot(), ".gitattributes");
1773
+ const path = join7(minkRoot(), ".gitattributes");
1478
1774
  writeFileSync3(path, GITATTRIBUTES_CONTENTS);
1479
1775
  }
1480
1776
  function ensureMergeDriversRegistered() {
@@ -1488,7 +1784,7 @@ function ensureMergeDriversRegistered() {
1488
1784
  }
1489
1785
  function getSyncStatus() {
1490
1786
  const enabled = resolveConfigValue("sync.enabled").value === "true";
1491
- const gitInitialized = existsSync5(join5(minkRoot(), ".git"));
1787
+ const gitInitialized = existsSync9(join7(minkRoot(), ".git"));
1492
1788
  const remoteUrl = resolveConfigValue("sync.remote-url").value;
1493
1789
  const lastPush = resolveConfigValue("sync.last-push").value;
1494
1790
  const lastPull = resolveConfigValue("sync.last-pull").value;
@@ -1514,8 +1810,8 @@ function getSyncStatus() {
1514
1810
  }
1515
1811
  function initSync(remoteUrl) {
1516
1812
  const root = minkRoot();
1517
- const gitDir = join5(root, ".git");
1518
- if (existsSync5(gitDir)) {
1813
+ const gitDir = join7(root, ".git");
1814
+ if (existsSync9(gitDir)) {
1519
1815
  console.log("[mink] sync is already initialized in " + root);
1520
1816
  console.log("[mink] run 'mink sync disconnect' first to reinitialize");
1521
1817
  return;
@@ -1656,8 +1952,8 @@ function syncPush(onMessage = (msg) => console.error(msg)) {
1656
1952
  }
1657
1953
  function disconnectSync() {
1658
1954
  const root = minkRoot();
1659
- const gitDir = join5(root, ".git");
1660
- if (!existsSync5(gitDir)) {
1955
+ const gitDir = join7(root, ".git");
1956
+ if (!existsSync9(gitDir)) {
1661
1957
  console.log("[mink] sync is not initialized — nothing to disconnect");
1662
1958
  return;
1663
1959
  }
@@ -1679,7 +1975,7 @@ function detectRemoteDefaultBranch() {
1679
1975
  `).map((b) => b.trim()).filter((b) => b.startsWith("origin/") && !b.includes("HEAD")).map((b) => b.replace("origin/", ""))[0];
1680
1976
  return first ?? "main";
1681
1977
  }
1682
- var GIT_TIMEOUT2 = 5000, PUSH_TIMEOUT = 1e4, FETCH_TIMEOUT = 15000, MINK_SYNC_VERSION = 2, GITIGNORE_CONTENTS = `# Runtime state — machine-specific
1978
+ var GIT_TIMEOUT2 = 5000, PUSH_TIMEOUT = 1e4, FETCH_TIMEOUT = 15000, MINK_SYNC_VERSION = 3, GITIGNORE_CONTENTS = `# Runtime state — machine-specific
1683
1979
  scheduler.pid
1684
1980
  scheduler.log
1685
1981
  channel.pid
@@ -1729,22 +2025,25 @@ var init_sync = __esm(() => {
1729
2025
  var exports_sync_migrate = {};
1730
2026
  __export(exports_sync_migrate, {
1731
2027
  syncMigrateCommand: () => syncMigrateCommand,
2028
+ rollbackProjectIdentities: () => rollbackProjectIdentities,
2029
+ planIdentityMigration: () => planIdentityMigration,
1732
2030
  migrateSyncLayout: () => migrateSyncLayout
1733
2031
  });
1734
2032
  import {
1735
- existsSync as existsSync6,
1736
- readdirSync as readdirSync2,
2033
+ existsSync as existsSync10,
2034
+ readdirSync as readdirSync3,
1737
2035
  statSync as statSync2,
1738
2036
  mkdirSync as mkdirSync4,
1739
2037
  writeFileSync as writeFileSync4,
2038
+ readFileSync as readFileSync7,
1740
2039
  renameSync as renameSync2,
1741
2040
  unlinkSync as unlinkSync2
1742
2041
  } from "fs";
1743
- import { join as join6 } from "path";
1744
- import { execSync as execSync3 } from "child_process";
2042
+ import { join as join8 } from "path";
2043
+ import { execSync as execSync4 } from "child_process";
1745
2044
  function gitSafe3(args, timeoutMs = 5000) {
1746
2045
  try {
1747
- return execSync3(`git ${args}`, {
2046
+ return execSync4(`git ${args}`, {
1748
2047
  cwd: minkRoot(),
1749
2048
  timeout: timeoutMs,
1750
2049
  stdio: ["pipe", "pipe", "pipe"]
@@ -1754,8 +2053,8 @@ function gitSafe3(args, timeoutMs = 5000) {
1754
2053
  }
1755
2054
  }
1756
2055
  function acquireLock() {
1757
- const path = join6(minkRoot(), MIGRATE_LOCK);
1758
- if (existsSync6(path)) {
2056
+ const path = join8(minkRoot(), MIGRATE_LOCK);
2057
+ if (existsSync10(path)) {
1759
2058
  try {
1760
2059
  const ageMs = Date.now() - statSync2(path).mtimeMs;
1761
2060
  if (ageMs < MIGRATE_LOCK_STALE_MS)
@@ -1772,13 +2071,13 @@ function acquireLock() {
1772
2071
  }
1773
2072
  function releaseLock() {
1774
2073
  try {
1775
- unlinkSync2(join6(minkRoot(), MIGRATE_LOCK));
2074
+ unlinkSync2(join8(minkRoot(), MIGRATE_LOCK));
1776
2075
  } catch {}
1777
2076
  }
1778
2077
  function migrateFile(from, to) {
1779
- if (!existsSync6(from))
2078
+ if (!existsSync10(from))
1780
2079
  return true;
1781
- mkdirSync4(join6(to, ".."), { recursive: true });
2080
+ mkdirSync4(join8(to, ".."), { recursive: true });
1782
2081
  if (gitSafe3(`mv "${from}" "${to}"`) !== null)
1783
2082
  return true;
1784
2083
  try {
@@ -1789,7 +2088,7 @@ function migrateFile(from, to) {
1789
2088
  }
1790
2089
  }
1791
2090
  function migrateProject(projDir, deviceId) {
1792
- const shardDir = join6(projDir, "state", deviceId);
2091
+ const shardDir = join8(projDir, "state", deviceId);
1793
2092
  mkdirSync4(shardDir, { recursive: true });
1794
2093
  for (const file of [
1795
2094
  "token-ledger.json",
@@ -1797,25 +2096,25 @@ function migrateProject(projDir, deviceId) {
1797
2096
  "bug-memory.json",
1798
2097
  "action-log.md"
1799
2098
  ]) {
1800
- const legacy = join6(projDir, file);
1801
- const shard = join6(shardDir, file);
1802
- if (existsSync6(shard))
2099
+ const legacy = join8(projDir, file);
2100
+ const shard = join8(shardDir, file);
2101
+ if (existsSync10(shard))
1803
2102
  continue;
1804
2103
  migrateFile(legacy, shard);
1805
2104
  }
1806
- const sidecar = join6(projDir, `learning-memory.${deviceId}.md`);
1807
- if (!existsSync6(sidecar)) {
2105
+ const sidecar = join8(projDir, `learning-memory.${deviceId}.md`);
2106
+ if (!existsSync10(sidecar)) {
1808
2107
  try {
1809
2108
  writeFileSync4(sidecar, "");
1810
2109
  } catch {}
1811
2110
  }
1812
2111
  for (const f of ["session.json", "scheduler-manifest.json"]) {
1813
- if (existsSync6(join6(projDir, f))) {
1814
- gitSafe3(`rm --cached "${join6(projDir, f)}"`);
2112
+ if (existsSync10(join8(projDir, f))) {
2113
+ gitSafe3(`rm --cached "${join8(projDir, f)}"`);
1815
2114
  }
1816
2115
  }
1817
- const indexPath = join6(projDir, "file-index.json");
1818
- if (existsSync6(indexPath)) {
2116
+ const indexPath = join8(projDir, "file-index.json");
2117
+ if (existsSync10(indexPath)) {
1819
2118
  const raw = safeReadJson(indexPath);
1820
2119
  if (raw && typeof raw.header === "object" && raw.header !== null && (raw.header.lifetimeHits > 0 || raw.header.lifetimeMisses > 0)) {
1821
2120
  atomicWriteJson(fileIndexCountersPathFor(projDir), {
@@ -1829,31 +2128,31 @@ function migrateProject(projDir, deviceId) {
1829
2128
  }
1830
2129
  }
1831
2130
  function fileIndexCountersPathFor(projDir) {
1832
- return join6(projDir, ".mink-state-counters.json");
2131
+ return join8(projDir, ".mink-state-counters.json");
1833
2132
  }
1834
2133
  function listProjects() {
1835
- const projectsRoot = join6(minkRoot(), "projects");
1836
- if (!existsSync6(projectsRoot))
2134
+ const projectsRoot = join8(minkRoot(), "projects");
2135
+ if (!existsSync10(projectsRoot))
1837
2136
  return [];
1838
2137
  try {
1839
- return readdirSync2(projectsRoot).filter((name) => {
2138
+ return readdirSync3(projectsRoot).filter((name) => {
1840
2139
  try {
1841
- return statSync2(join6(projectsRoot, name)).isDirectory();
2140
+ return statSync2(join8(projectsRoot, name)).isDirectory();
1842
2141
  } catch {
1843
2142
  return false;
1844
2143
  }
1845
- }).map((name) => join6(projectsRoot, name));
2144
+ }).map((name) => join8(projectsRoot, name));
1846
2145
  } catch {
1847
2146
  return [];
1848
2147
  }
1849
2148
  }
1850
2149
  function projectNeedsMigration(projDir) {
1851
- const stateDir = join6(projDir, "state");
1852
- if (existsSync6(stateDir)) {
2150
+ const stateDir = join8(projDir, "state");
2151
+ if (existsSync10(stateDir)) {
1853
2152
  try {
1854
- const shards = readdirSync2(stateDir).filter((d) => {
2153
+ const shards = readdirSync3(stateDir).filter((d) => {
1855
2154
  try {
1856
- return statSync2(join6(stateDir, d)).isDirectory();
2155
+ return statSync2(join8(stateDir, d)).isDirectory();
1857
2156
  } catch {
1858
2157
  return false;
1859
2158
  }
@@ -1868,7 +2167,7 @@ function projectNeedsMigration(projDir) {
1868
2167
  "bug-memory.json",
1869
2168
  "action-log.md"
1870
2169
  ]) {
1871
- if (existsSync6(join6(projDir, f)))
2170
+ if (existsSync10(join8(projDir, f)))
1872
2171
  return true;
1873
2172
  }
1874
2173
  return false;
@@ -1876,10 +2175,209 @@ function projectNeedsMigration(projDir) {
1876
2175
  function listProjectsNeedingMigration() {
1877
2176
  return listProjects().filter(projectNeedsMigration);
1878
2177
  }
2178
+ function planIdentityMigration(flagOverride) {
2179
+ const plan = [];
2180
+ const flag = flagOverride ?? resolveConfigValue("projects.identity").value;
2181
+ if (flag !== "git-remote") {
2182
+ return plan;
2183
+ }
2184
+ const projectsRoot = join8(minkRoot(), "projects");
2185
+ if (!existsSync10(projectsRoot))
2186
+ return plan;
2187
+ let entries;
2188
+ try {
2189
+ entries = readdirSync3(projectsRoot);
2190
+ } catch {
2191
+ return plan;
2192
+ }
2193
+ for (const oldId of entries) {
2194
+ const oldProjDir = join8(projectsRoot, oldId);
2195
+ try {
2196
+ if (!statSync2(oldProjDir).isDirectory())
2197
+ continue;
2198
+ } catch {
2199
+ continue;
2200
+ }
2201
+ const meta = getProjectMeta(oldProjDir);
2202
+ if (!meta)
2203
+ continue;
2204
+ if (!existsSync10(meta.cwd)) {
2205
+ plan.push({
2206
+ oldId,
2207
+ newId: null,
2208
+ cwd: meta.cwd,
2209
+ action: "skip-no-cwd",
2210
+ reason: "working-copy path not reachable on this device"
2211
+ });
2212
+ continue;
2213
+ }
2214
+ let newId;
2215
+ try {
2216
+ newId = resolveProjectIdentity(meta.cwd, flag === "git-remote" || flag === "path-derived" ? flag : undefined).id;
2217
+ } catch {
2218
+ continue;
2219
+ }
2220
+ if (newId === oldId) {
2221
+ plan.push({ oldId, newId, cwd: meta.cwd, action: "skip-unchanged" });
2222
+ continue;
2223
+ }
2224
+ const newProjDir = join8(projectsRoot, newId);
2225
+ if (existsSync10(newProjDir)) {
2226
+ plan.push({
2227
+ oldId,
2228
+ newId,
2229
+ cwd: meta.cwd,
2230
+ action: "skip-converged",
2231
+ reason: "destination already exists (from sync); alias-only update"
2232
+ });
2233
+ continue;
2234
+ }
2235
+ plan.push({ oldId, newId, cwd: meta.cwd, action: "rename" });
2236
+ }
2237
+ return plan;
2238
+ }
2239
+ function identityBackupRoot(timestamp) {
2240
+ return join8(minkRoot(), IDENTITY_BACKUP_DIRNAME, timestamp);
2241
+ }
2242
+ function ensureIdentityBackupTimestamp() {
2243
+ const now = new Date;
2244
+ return `${now.getUTCFullYear()}${String(now.getUTCMonth() + 1).padStart(2, "0")}${String(now.getUTCDate()).padStart(2, "0")}-${String(now.getUTCHours()).padStart(2, "0")}${String(now.getUTCMinutes()).padStart(2, "0")}${String(now.getUTCSeconds()).padStart(2, "0")}`;
2245
+ }
2246
+ function backupProjectForRollback(srcDir, backupDir) {
2247
+ try {
2248
+ mkdirSync4(backupDir, { recursive: true });
2249
+ copyDirRecursive(srcDir, backupDir, new Set(["backups"]));
2250
+ return backupDir;
2251
+ } catch {
2252
+ return null;
2253
+ }
2254
+ }
2255
+ function copyDirRecursive(src, dest, excludeNames) {
2256
+ mkdirSync4(dest, { recursive: true });
2257
+ const entries = readdirSync3(src, { withFileTypes: true });
2258
+ for (const entry of entries) {
2259
+ if (excludeNames.has(entry.name))
2260
+ continue;
2261
+ const srcPath = join8(src, entry.name);
2262
+ const destPath = join8(dest, entry.name);
2263
+ if (entry.isDirectory()) {
2264
+ copyDirRecursive(srcPath, destPath, excludeNames);
2265
+ } else if (entry.isFile()) {
2266
+ writeFileSync4(destPath, readFileSync7(srcPath));
2267
+ }
2268
+ }
2269
+ }
2270
+ function migrateProjectIdentities(deviceId, flag = resolveConfigValue("projects.identity").value) {
2271
+ if (flag !== "git-remote") {
2272
+ return { renamed: 0, visited: 0, backupDir: null };
2273
+ }
2274
+ const plan = planIdentityMigration(flag);
2275
+ const willRename = plan.filter((p) => p.action === "rename");
2276
+ let backupRoot = null;
2277
+ if (willRename.length > 0) {
2278
+ backupRoot = identityBackupRoot(ensureIdentityBackupTimestamp());
2279
+ }
2280
+ let renamed = 0;
2281
+ let visited = plan.length;
2282
+ const projectsRoot = join8(minkRoot(), "projects");
2283
+ for (const entry of plan) {
2284
+ const oldProjDir = join8(projectsRoot, entry.oldId);
2285
+ if (entry.cwd && entry.action !== "skip-no-cwd") {
2286
+ try {
2287
+ setProjectPathForDevice(oldProjDir, deviceId, entry.cwd);
2288
+ } catch {}
2289
+ }
2290
+ if (entry.action === "skip-converged" && entry.newId) {
2291
+ const newProjDir2 = join8(projectsRoot, entry.newId);
2292
+ try {
2293
+ addProjectAlias(newProjDir2, entry.oldId);
2294
+ if (entry.cwd) {
2295
+ setProjectPathForDevice(newProjDir2, deviceId, entry.cwd);
2296
+ }
2297
+ } catch {}
2298
+ continue;
2299
+ }
2300
+ if (entry.action !== "rename" || !entry.newId)
2301
+ continue;
2302
+ if (backupRoot) {
2303
+ backupProjectForRollback(oldProjDir, join8(backupRoot, entry.oldId));
2304
+ }
2305
+ const newProjDir = join8(projectsRoot, entry.newId);
2306
+ const moved = gitSafe3(`mv "${oldProjDir}" "${newProjDir}"`) !== null || (() => {
2307
+ try {
2308
+ renameSync2(oldProjDir, newProjDir);
2309
+ return true;
2310
+ } catch {
2311
+ return false;
2312
+ }
2313
+ })();
2314
+ if (!moved)
2315
+ continue;
2316
+ try {
2317
+ addProjectAlias(newProjDir, entry.oldId);
2318
+ if (entry.cwd) {
2319
+ setProjectPathForDevice(newProjDir, deviceId, entry.cwd);
2320
+ }
2321
+ } catch {}
2322
+ renamed++;
2323
+ }
2324
+ return { renamed, visited, backupDir: backupRoot };
2325
+ }
2326
+ function rollbackProjectIdentities() {
2327
+ const results = [];
2328
+ const projectsRoot = join8(minkRoot(), "projects");
2329
+ if (!existsSync10(projectsRoot))
2330
+ return results;
2331
+ let entries;
2332
+ try {
2333
+ entries = readdirSync3(projectsRoot);
2334
+ } catch {
2335
+ return results;
2336
+ }
2337
+ for (const currentId of entries) {
2338
+ const projDir = join8(projectsRoot, currentId);
2339
+ try {
2340
+ if (!statSync2(projDir).isDirectory())
2341
+ continue;
2342
+ } catch {
2343
+ continue;
2344
+ }
2345
+ const meta = getProjectMeta(projDir);
2346
+ if (!meta || !meta.aliases || meta.aliases.length === 0)
2347
+ continue;
2348
+ const restoredId = meta.aliases[meta.aliases.length - 1];
2349
+ const targetDir = join8(projectsRoot, restoredId);
2350
+ if (existsSync10(targetDir)) {
2351
+ results.push({ currentId, restoredId, ok: false });
2352
+ continue;
2353
+ }
2354
+ const remainingAliases = meta.aliases.slice(0, -1);
2355
+ const metaPath = join8(projDir, "project-meta.json");
2356
+ try {
2357
+ const raw = safeReadJson(metaPath);
2358
+ if (raw && typeof raw === "object" && !Array.isArray(raw)) {
2359
+ const obj = raw;
2360
+ obj.aliases = remainingAliases;
2361
+ atomicWriteJson(metaPath, obj);
2362
+ }
2363
+ } catch {}
2364
+ const moved = gitSafe3(`mv "${projDir}" "${targetDir}"`) !== null || (() => {
2365
+ try {
2366
+ renameSync2(projDir, targetDir);
2367
+ return true;
2368
+ } catch {
2369
+ return false;
2370
+ }
2371
+ })();
2372
+ results.push({ currentId, restoredId, ok: moved });
2373
+ }
2374
+ return results;
2375
+ }
1879
2376
  function migrateSyncLayout() {
1880
2377
  const fromVersion = readSyncVersion();
1881
2378
  const pending = listProjectsNeedingMigration();
1882
- if (fromVersion >= MINK_SYNC_VERSION && pending.length === 0) {
2379
+ const identityMode = resolveConfigValue("projects.identity").value;
2380
+ if (fromVersion >= MINK_SYNC_VERSION && pending.length === 0 && identityMode !== "git-remote") {
1883
2381
  return {
1884
2382
  ranMigration: false,
1885
2383
  fromVersion,
@@ -1924,13 +2422,18 @@ function migrateSyncLayout() {
1924
2422
  processed++;
1925
2423
  } catch {}
1926
2424
  }
2425
+ let identity = { renamed: 0, visited: 0 };
2426
+ try {
2427
+ identity = migrateProjectIdentities(deviceId, identityMode);
2428
+ } catch {}
1927
2429
  if (remaining === 0 && listProjectsNeedingMigration().length === 0) {
1928
2430
  writeSyncVersion(MINK_SYNC_VERSION);
1929
2431
  }
1930
- if (isSyncInitialized() && processed > 0) {
2432
+ if (isSyncInitialized() && (processed > 0 || identity.renamed > 0)) {
1931
2433
  gitSafe3("add -A");
1932
2434
  gitSafe3(`reset HEAD ".sync-migrate.lock"`);
1933
- gitSafe3(`commit -m "mink: migrate sync layout v${fromVersion} -> v${MINK_SYNC_VERSION} (device ${deviceId.slice(0, 8)}, ${processed} projects)"`);
2435
+ const summary = identity.renamed > 0 ? `${processed} projects, ${identity.renamed} renamed for identity v3` : `${processed} projects`;
2436
+ gitSafe3(`commit -m "mink: migrate sync layout v${fromVersion} -> v${MINK_SYNC_VERSION} (device ${deviceId.slice(0, 8)}, ${summary})"`);
1934
2437
  }
1935
2438
  if (stashed) {
1936
2439
  gitSafe3("stash pop");
@@ -1944,7 +2447,56 @@ function migrateSyncLayout() {
1944
2447
  releaseLock();
1945
2448
  }
1946
2449
  }
1947
- function syncMigrateCommand() {
2450
+ function syncMigrateCommand(args = []) {
2451
+ const dryRun = args.includes("--dry-run");
2452
+ const rollback = args.includes("--rollback");
2453
+ if (rollback && dryRun) {
2454
+ console.error("[mink] --rollback and --dry-run cannot be combined");
2455
+ process.exit(1);
2456
+ }
2457
+ if (dryRun) {
2458
+ const plan = planIdentityMigration();
2459
+ if (plan.length === 0) {
2460
+ console.log("[mink] sync migrate --dry-run: no projects to rename (flag is off or no projects on disk)");
2461
+ return;
2462
+ }
2463
+ const renames = plan.filter((p) => p.action === "rename");
2464
+ const converged = plan.filter((p) => p.action === "skip-converged");
2465
+ const skippedNoCwd = plan.filter((p) => p.action === "skip-no-cwd");
2466
+ const unchanged = plan.filter((p) => p.action === "skip-unchanged");
2467
+ console.log(`[mink] sync migrate --dry-run: ${renames.length} rename(s), ${converged.length} alias-only, ${skippedNoCwd.length} skipped (no cwd), ${unchanged.length} unchanged`);
2468
+ for (const p of renames) {
2469
+ console.log(` rename: ${p.oldId} → ${p.newId}`);
2470
+ }
2471
+ for (const p of converged) {
2472
+ console.log(` alias: ${p.oldId} → ${p.newId} (already on disk)`);
2473
+ }
2474
+ for (const p of skippedNoCwd) {
2475
+ console.log(` skip: ${p.oldId} — ${p.reason}`);
2476
+ }
2477
+ return;
2478
+ }
2479
+ if (rollback) {
2480
+ const results = rollbackProjectIdentities();
2481
+ if (results.length === 0) {
2482
+ console.log("[mink] sync migrate --rollback: nothing to roll back");
2483
+ return;
2484
+ }
2485
+ const ok = results.filter((r) => r.ok);
2486
+ const failed = results.filter((r) => !r.ok);
2487
+ console.log(`[mink] sync migrate --rollback: ${ok.length} restored, ${failed.length} failed`);
2488
+ for (const r of ok) {
2489
+ console.log(` restored: ${r.currentId} → ${r.restoredId}`);
2490
+ }
2491
+ for (const r of failed) {
2492
+ console.log(` failed: ${r.currentId} → ${r.restoredId} (destination already exists or rename blocked)`);
2493
+ }
2494
+ if (ok.length > 0) {
2495
+ console.log(`
2496
+ [mink] tip: set projects.identity=path-derived to prevent the next session-start from re-migrating`);
2497
+ }
2498
+ return;
2499
+ }
1948
2500
  const result = migrateSyncLayout();
1949
2501
  if (!result.ranMigration) {
1950
2502
  console.log(`[mink] sync migrate: ${result.message ?? "no-op"}`);
@@ -1952,12 +2504,15 @@ function syncMigrateCommand() {
1952
2504
  }
1953
2505
  console.log(`[mink] sync migrate: v${result.fromVersion} → v${result.toVersion} complete`);
1954
2506
  }
1955
- var MIGRATE_LOCK = ".sync-migrate.lock", MIGRATE_LOCK_STALE_MS = 300000, MIGRATE_BUDGET_MS = 5000;
2507
+ var MIGRATE_LOCK = ".sync-migrate.lock", MIGRATE_LOCK_STALE_MS = 300000, MIGRATE_BUDGET_MS = 5000, IDENTITY_BACKUP_DIRNAME = ".identity-rollback";
1956
2508
  var init_sync_migrate = __esm(() => {
1957
2509
  init_paths();
1958
2510
  init_sync();
1959
2511
  init_device();
1960
2512
  init_fs_utils();
2513
+ init_project_id();
2514
+ init_project_registry();
2515
+ init_global_config();
1961
2516
  });
1962
2517
 
1963
2518
  // src/core/note-linker.ts
@@ -1968,8 +2523,8 @@ __export(exports_note_linker, {
1968
2523
  extractWikilinks: () => extractWikilinks,
1969
2524
  addBacklink: () => addBacklink
1970
2525
  });
1971
- import { join as join7 } from "path";
1972
- import { existsSync as existsSync7, readFileSync as readFileSync7, readdirSync as readdirSync3, statSync as statSync3 } from "fs";
2526
+ import { join as join9 } from "path";
2527
+ import { existsSync as existsSync11, readFileSync as readFileSync8, readdirSync as readdirSync4, statSync as statSync3 } from "fs";
1973
2528
  function extractWikilinks(content) {
1974
2529
  const links = [];
1975
2530
  let match;
@@ -1995,9 +2550,9 @@ function insertWikilinks(content, targets) {
1995
2550
  return result;
1996
2551
  }
1997
2552
  function addBacklink(targetNotePath, sourceTitle) {
1998
- if (!existsSync7(targetNotePath))
2553
+ if (!existsSync11(targetNotePath))
1999
2554
  return;
2000
- const content = readFileSync7(targetNotePath, "utf-8");
2555
+ const content = readFileSync8(targetNotePath, "utf-8");
2001
2556
  if (content.includes(`[[${sourceTitle}]]`))
2002
2557
  return;
2003
2558
  const backlinkSection = `
@@ -2039,8 +2594,8 @@ function updateMasterIndex(vaultRootPath) {
2039
2594
  { name: "Patterns", dir: "patterns", emoji: "" }
2040
2595
  ];
2041
2596
  for (const cat of categories) {
2042
- const dirPath = join7(vaultRootPath, cat.dir);
2043
- if (!existsSync7(dirPath))
2597
+ const dirPath = join9(vaultRootPath, cat.dir);
2598
+ if (!existsSync11(dirPath))
2044
2599
  continue;
2045
2600
  const files = collectMarkdownFiles(dirPath, vaultRootPath);
2046
2601
  if (files.length === 0 && cat.dir !== "inbox")
@@ -2067,9 +2622,9 @@ function updateMasterIndex(vaultRootPath) {
2067
2622
  function collectMarkdownFiles(dirPath, rootPath) {
2068
2623
  const files = [];
2069
2624
  try {
2070
- const entries = readdirSync3(dirPath, { withFileTypes: true });
2625
+ const entries = readdirSync4(dirPath, { withFileTypes: true });
2071
2626
  for (const entry of entries) {
2072
- const fullPath = join7(dirPath, entry.name);
2627
+ const fullPath = join9(dirPath, entry.name);
2073
2628
  if (entry.isDirectory()) {
2074
2629
  files.push(...collectMarkdownFiles(fullPath, rootPath));
2075
2630
  } else if (entry.name.endsWith(".md") && !entry.name.startsWith("_")) {
@@ -2202,7 +2757,7 @@ var init_learning_memory = __esm(() => {
2202
2757
  });
2203
2758
 
2204
2759
  // src/core/token-ledger.ts
2205
- import { join as join8 } from "path";
2760
+ import { join as join10 } from "path";
2206
2761
  function addToLifetime(lifetime, session) {
2207
2762
  lifetime.totalTokens += session.totals.estimatedTokens;
2208
2763
  lifetime.totalReads += session.totals.readCount;
@@ -2333,13 +2888,13 @@ function createLedgerFinalizer(projectDir2, deviceIdOrThreshold, archiveThreshol
2333
2888
  let archivePath;
2334
2889
  let threshold;
2335
2890
  if (typeof deviceIdOrThreshold === "string") {
2336
- const shardDir = join8(projectDir2, "state", deviceIdOrThreshold);
2337
- ledgerPath = join8(shardDir, "token-ledger.json");
2338
- archivePath = join8(shardDir, "token-ledger-archive.json");
2891
+ const shardDir = join10(projectDir2, "state", deviceIdOrThreshold);
2892
+ ledgerPath = join10(shardDir, "token-ledger.json");
2893
+ archivePath = join10(shardDir, "token-ledger-archive.json");
2339
2894
  threshold = archiveThreshold;
2340
2895
  } else {
2341
- ledgerPath = join8(projectDir2, "token-ledger.json");
2342
- archivePath = join8(projectDir2, "token-ledger-archive.json");
2896
+ ledgerPath = join10(projectDir2, "token-ledger.json");
2897
+ archivePath = join10(projectDir2, "token-ledger-archive.json");
2343
2898
  threshold = deviceIdOrThreshold ?? archiveThreshold;
2344
2899
  }
2345
2900
  return {
@@ -2479,16 +3034,16 @@ var init_bug_memory = __esm(() => {
2479
3034
  });
2480
3035
 
2481
3036
  // src/core/state-aggregator.ts
2482
- import { existsSync as existsSync8, readdirSync as readdirSync4, readFileSync as readFileSync8, statSync as statSync4 } from "fs";
2483
- import { join as join9 } from "path";
3037
+ import { existsSync as existsSync12, readdirSync as readdirSync5, readFileSync as readFileSync9, statSync as statSync4 } from "fs";
3038
+ import { join as join11 } from "path";
2484
3039
  function listDeviceShardsAt(projDir) {
2485
- const stateDir = join9(projDir, "state");
2486
- if (!existsSync8(stateDir))
3040
+ const stateDir = join11(projDir, "state");
3041
+ if (!existsSync12(stateDir))
2487
3042
  return [];
2488
3043
  try {
2489
- return readdirSync4(stateDir).filter((name) => {
3044
+ return readdirSync5(stateDir).filter((name) => {
2490
3045
  try {
2491
- return statSync4(join9(stateDir, name)).isDirectory();
3046
+ return statSync4(join11(stateDir, name)).isDirectory();
2492
3047
  } catch {
2493
3048
  return false;
2494
3049
  }
@@ -2498,16 +3053,16 @@ function listDeviceShardsAt(projDir) {
2498
3053
  }
2499
3054
  }
2500
3055
  function listLearningMemorySidecarPathsAt(projDir) {
2501
- if (!existsSync8(projDir))
3056
+ if (!existsSync12(projDir))
2502
3057
  return [];
2503
3058
  try {
2504
- return readdirSync4(projDir).filter((f) => SIDECAR_RE.test(f)).map((f) => join9(projDir, f));
3059
+ return readdirSync5(projDir).filter((f) => SIDECAR_RE.test(f)).map((f) => join11(projDir, f));
2505
3060
  } catch {
2506
3061
  return [];
2507
3062
  }
2508
3063
  }
2509
3064
  function shardPath(projDir, deviceId, file) {
2510
- return join9(projDir, "state", deviceId, file);
3065
+ return join11(projDir, "state", deviceId, file);
2511
3066
  }
2512
3067
  function addLifetime(target, source) {
2513
3068
  target.totalTokens += source.totalTokens;
@@ -2524,12 +3079,12 @@ function aggregateTokenLedgerAt(projDir) {
2524
3079
  const seenSessions = new Set;
2525
3080
  const sources = [
2526
3081
  ...listDeviceShardsAt(projDir).map((id) => shardPath(projDir, id, "token-ledger.json")),
2527
- join9(projDir, "token-ledger.json")
3082
+ join11(projDir, "token-ledger.json")
2528
3083
  ];
2529
3084
  const seenFlagKeys = new Set;
2530
3085
  const wasteFlags = [];
2531
3086
  for (const path of sources) {
2532
- if (!existsSync8(path))
3087
+ if (!existsSync12(path))
2533
3088
  continue;
2534
3089
  const ledger = loadLedger(path);
2535
3090
  addLifetime(merged.lifetime, ledger.lifetime);
@@ -2563,10 +3118,10 @@ function aggregateBugMemoryAt(projDir) {
2563
3118
  let maxNextId = 1;
2564
3119
  const sources = [
2565
3120
  ...listDeviceShardsAt(projDir).map((id) => shardPath(projDir, id, "bug-memory.json")),
2566
- join9(projDir, "bug-memory.json")
3121
+ join11(projDir, "bug-memory.json")
2567
3122
  ];
2568
3123
  for (const path of sources) {
2569
- if (!existsSync8(path))
3124
+ if (!existsSync12(path))
2570
3125
  continue;
2571
3126
  const mem = loadBugMemory(path);
2572
3127
  if (mem.nextId > maxNextId)
@@ -2606,10 +3161,10 @@ function aggregateActionLogAt(projDir) {
2606
3161
  let order = 0;
2607
3162
  const sources = [
2608
3163
  ...listDeviceShardsAt(projDir).map((id) => shardPath(projDir, id, "action-log.md")),
2609
- join9(projDir, "action-log.md")
3164
+ join11(projDir, "action-log.md")
2610
3165
  ];
2611
3166
  for (const path of sources) {
2612
- if (!existsSync8(path))
3167
+ if (!existsSync12(path))
2613
3168
  continue;
2614
3169
  const content = safeReadLog(path);
2615
3170
  if (!content)
@@ -2634,11 +3189,11 @@ function aggregateActionLog(cwd) {
2634
3189
  return aggregateActionLogAt(projectDir(cwd));
2635
3190
  }
2636
3191
  function aggregateLearningMemoryAt(projDir) {
2637
- const canonicalPath = join9(projDir, "learning-memory.md");
3192
+ const canonicalPath = join11(projDir, "learning-memory.md");
2638
3193
  let merged;
2639
- if (existsSync8(canonicalPath)) {
3194
+ if (existsSync12(canonicalPath)) {
2640
3195
  try {
2641
- merged = parseLearningMemory(readFileSync8(canonicalPath, "utf-8"));
3196
+ merged = parseLearningMemory(readFileSync9(canonicalPath, "utf-8"));
2642
3197
  } catch {
2643
3198
  merged = createEmptyLearningMemory("unknown");
2644
3199
  }
@@ -2648,7 +3203,7 @@ function aggregateLearningMemoryAt(projDir) {
2648
3203
  for (const sidecarPath of listLearningMemorySidecarPathsAt(projDir)) {
2649
3204
  let sidecar;
2650
3205
  try {
2651
- sidecar = parseLearningMemory(readFileSync8(sidecarPath, "utf-8"));
3206
+ sidecar = parseLearningMemory(readFileSync9(sidecarPath, "utf-8"));
2652
3207
  } catch {
2653
3208
  continue;
2654
3209
  }
@@ -2955,12 +3510,12 @@ var exports_reflect = {};
2955
3510
  __export(exports_reflect, {
2956
3511
  reflect: () => reflect
2957
3512
  });
2958
- import { existsSync as existsSync9 } from "fs";
3513
+ import { existsSync as existsSync13 } from "fs";
2959
3514
  import { dirname as dirname3 } from "path";
2960
3515
  function reflect(_cwd, memoryPath, configPath2) {
2961
3516
  const projDir = dirname3(memoryPath);
2962
3517
  const mem = aggregateLearningMemoryAt(projDir);
2963
- if (totalEntryCount(mem) === 0 && !existsSync9(memoryPath)) {
3518
+ if (totalEntryCount(mem) === 0 && !existsSync13(memoryPath)) {
2964
3519
  console.log("[mink] no learning memory found");
2965
3520
  return null;
2966
3521
  }
@@ -3019,10 +3574,11 @@ __export(exports_paths2, {
3019
3574
  actionLogShardPath: () => actionLogShardPath2,
3020
3575
  actionLogPath: () => actionLogPath2
3021
3576
  });
3022
- import { join as join11 } from "path";
3577
+ import { join as join13 } from "path";
3578
+ import { existsSync as existsSync15 } from "fs";
3023
3579
  import { homedir as homedir3 } from "os";
3024
3580
  function resolveMinkRoot2() {
3025
- return process.env.MINK_ROOT_OVERRIDE || join11(homedir3(), ".mink");
3581
+ return process.env.MINK_ROOT_OVERRIDE || join13(homedir3(), ".mink");
3026
3582
  }
3027
3583
  function minkRoot2() {
3028
3584
  if (process.env.MINK_ROOT_OVERRIDE) {
@@ -3031,104 +3587,113 @@ function minkRoot2() {
3031
3587
  return MINK_ROOT2;
3032
3588
  }
3033
3589
  function projectDir2(cwd) {
3034
- const id = generateProjectId(cwd);
3035
- return join11(minkRoot2(), "projects", id);
3590
+ const id = projectIdFor(cwd);
3591
+ const primary = join13(minkRoot2(), "projects", id);
3592
+ if (existsSync15(primary))
3593
+ return primary;
3594
+ try {
3595
+ const { findProjectDirByIdOrAlias: findProjectDirByIdOrAlias2 } = (init_project_registry(), __toCommonJS(exports_project_registry));
3596
+ const aliased = findProjectDirByIdOrAlias2(id);
3597
+ if (aliased)
3598
+ return aliased;
3599
+ } catch {}
3600
+ return primary;
3036
3601
  }
3037
3602
  function sessionPath2(cwd) {
3038
- return join11(projectDir2(cwd), "session.json");
3603
+ return join13(projectDir2(cwd), "session.json");
3039
3604
  }
3040
3605
  function fileIndexPath2(cwd) {
3041
- return join11(projectDir2(cwd), "file-index.json");
3606
+ return join13(projectDir2(cwd), "file-index.json");
3042
3607
  }
3043
3608
  function configPath2(cwd) {
3044
- return join11(projectDir2(cwd), "config.json");
3609
+ return join13(projectDir2(cwd), "config.json");
3045
3610
  }
3046
3611
  function learningMemoryPath2(cwd) {
3047
- return join11(projectDir2(cwd), "learning-memory.md");
3612
+ return join13(projectDir2(cwd), "learning-memory.md");
3048
3613
  }
3049
3614
  function tokenLedgerPath2(cwd) {
3050
- return join11(projectDir2(cwd), "token-ledger.json");
3615
+ return join13(projectDir2(cwd), "token-ledger.json");
3051
3616
  }
3052
3617
  function tokenLedgerArchivePath2(cwd) {
3053
- return join11(projectDir2(cwd), "token-ledger-archive.json");
3618
+ return join13(projectDir2(cwd), "token-ledger-archive.json");
3054
3619
  }
3055
3620
  function bugMemoryPath2(cwd) {
3056
- return join11(projectDir2(cwd), "bug-memory.json");
3621
+ return join13(projectDir2(cwd), "bug-memory.json");
3057
3622
  }
3058
3623
  function actionLogPath2(cwd) {
3059
- return join11(projectDir2(cwd), "action-log.md");
3624
+ return join13(projectDir2(cwd), "action-log.md");
3060
3625
  }
3061
3626
  function schedulerPidPath2() {
3062
- return join11(minkRoot2(), "scheduler.pid");
3627
+ return join13(minkRoot2(), "scheduler.pid");
3063
3628
  }
3064
3629
  function schedulerLogPath2() {
3065
- return join11(minkRoot2(), "scheduler.log");
3630
+ return join13(minkRoot2(), "scheduler.log");
3066
3631
  }
3067
3632
  function schedulerManifestPath2(cwd) {
3068
- return join11(projectDir2(cwd), "scheduler-manifest.json");
3633
+ return join13(projectDir2(cwd), "scheduler-manifest.json");
3069
3634
  }
3070
3635
  function channelPidPath2() {
3071
- return join11(minkRoot2(), "channel.pid");
3636
+ return join13(minkRoot2(), "channel.pid");
3072
3637
  }
3073
3638
  function channelLogPath2() {
3074
- return join11(minkRoot2(), "channel.log");
3639
+ return join13(minkRoot2(), "channel.log");
3075
3640
  }
3076
3641
  function globalConfigPath2() {
3077
- return join11(minkRoot2(), "config");
3642
+ return join13(minkRoot2(), "config");
3078
3643
  }
3079
3644
  function localConfigPath2() {
3080
- return join11(minkRoot2(), "config.local");
3645
+ return join13(minkRoot2(), "config.local");
3081
3646
  }
3082
3647
  function deviceIdPath2() {
3083
- return join11(minkRoot2(), "device-id");
3648
+ return join13(minkRoot2(), "device-id");
3084
3649
  }
3085
3650
  function deviceRegistryPath2() {
3086
- return join11(minkRoot2(), "devices.json");
3651
+ return join13(minkRoot2(), "devices.json");
3087
3652
  }
3088
3653
  function projectMetaPath2(cwd) {
3089
- return join11(projectDir2(cwd), "project-meta.json");
3654
+ return join13(projectDir2(cwd), "project-meta.json");
3090
3655
  }
3091
3656
  function backupDirPath2(cwd) {
3092
- return join11(projectDir2(cwd), "backups");
3657
+ return join13(projectDir2(cwd), "backups");
3093
3658
  }
3094
3659
  function syncVersionPath2() {
3095
- return join11(minkRoot2(), ".mink-sync-version");
3660
+ return join13(minkRoot2(), ".mink-sync-version");
3096
3661
  }
3097
3662
  function projectStateDir2(cwd) {
3098
- return join11(projectDir2(cwd), "state");
3663
+ return join13(projectDir2(cwd), "state");
3099
3664
  }
3100
3665
  function deviceShardDir2(cwd, deviceId) {
3101
- return join11(projectStateDir2(cwd), deviceId);
3666
+ return join13(projectStateDir2(cwd), deviceId);
3102
3667
  }
3103
3668
  function tokenLedgerShardPath2(cwd, deviceId) {
3104
- return join11(deviceShardDir2(cwd, deviceId), "token-ledger.json");
3669
+ return join13(deviceShardDir2(cwd, deviceId), "token-ledger.json");
3105
3670
  }
3106
3671
  function tokenLedgerArchiveShardPath2(cwd, deviceId) {
3107
- return join11(deviceShardDir2(cwd, deviceId), "token-ledger-archive.json");
3672
+ return join13(deviceShardDir2(cwd, deviceId), "token-ledger-archive.json");
3108
3673
  }
3109
3674
  function bugMemoryShardPath2(cwd, deviceId) {
3110
- return join11(deviceShardDir2(cwd, deviceId), "bug-memory.json");
3675
+ return join13(deviceShardDir2(cwd, deviceId), "bug-memory.json");
3111
3676
  }
3112
3677
  function actionLogShardPath2(cwd, deviceId) {
3113
- return join11(deviceShardDir2(cwd, deviceId), "action-log.md");
3678
+ return join13(deviceShardDir2(cwd, deviceId), "action-log.md");
3114
3679
  }
3115
3680
  function learningMemorySidecarPath2(cwd, deviceId) {
3116
- return join11(projectDir2(cwd), `learning-memory.${deviceId}.md`);
3681
+ return join13(projectDir2(cwd), `learning-memory.${deviceId}.md`);
3117
3682
  }
3118
3683
  function fileIndexCountersPath3(cwd) {
3119
- return join11(projectDir2(cwd), ".mink-state-counters.json");
3684
+ return join13(projectDir2(cwd), ".mink-state-counters.json");
3120
3685
  }
3121
3686
  function designCapturesDir2(cwd) {
3122
- return join11(projectDir2(cwd), "design-captures");
3687
+ return join13(projectDir2(cwd), "design-captures");
3123
3688
  }
3124
3689
  function designReportPath2(cwd) {
3125
- return join11(projectDir2(cwd), "design-report.json");
3690
+ return join13(projectDir2(cwd), "design-report.json");
3126
3691
  }
3127
3692
  function frameworkAdvisorPath2(cwd) {
3128
- return join11(projectDir2(cwd), "framework-advisor.md");
3693
+ return join13(projectDir2(cwd), "framework-advisor.md");
3129
3694
  }
3130
3695
  function frameworkAdvisorJsonPath2(cwd) {
3131
- return join11(projectDir2(cwd), "framework-advisor.json");
3696
+ return join13(projectDir2(cwd), "framework-advisor.json");
3132
3697
  }
3133
3698
  var MINK_ROOT2;
3134
3699
  var init_paths2 = __esm(() => {
@@ -3145,13 +3710,13 @@ __export(exports_backup, {
3145
3710
  });
3146
3711
  import {
3147
3712
  mkdirSync as mkdirSync6,
3148
- readdirSync as readdirSync5,
3149
- readFileSync as readFileSync10,
3713
+ readdirSync as readdirSync6,
3714
+ readFileSync as readFileSync11,
3150
3715
  writeFileSync as writeFileSync5,
3151
- existsSync as existsSync11,
3716
+ existsSync as existsSync16,
3152
3717
  statSync as statSync6
3153
3718
  } from "fs";
3154
- import { join as join12 } from "path";
3719
+ import { join as join14 } from "path";
3155
3720
  function formatTimestamp(date) {
3156
3721
  const y = date.getFullYear();
3157
3722
  const mo = String(date.getMonth() + 1).padStart(2, "0");
@@ -3164,14 +3729,14 @@ function formatTimestamp(date) {
3164
3729
  }
3165
3730
  function copyDirectoryFiles(srcDir, destDir, excludeDirs) {
3166
3731
  mkdirSync6(destDir, { recursive: true });
3167
- const entries = readdirSync5(srcDir, { withFileTypes: true });
3732
+ const entries = readdirSync6(srcDir, { withFileTypes: true });
3168
3733
  for (const entry of entries) {
3169
3734
  if (entry.isDirectory()) {
3170
3735
  if (excludeDirs.includes(entry.name))
3171
3736
  continue;
3172
- copyDirectoryFiles(join12(srcDir, entry.name), join12(destDir, entry.name), excludeDirs);
3737
+ copyDirectoryFiles(join14(srcDir, entry.name), join14(destDir, entry.name), excludeDirs);
3173
3738
  } else if (entry.isFile()) {
3174
- writeFileSync5(join12(destDir, entry.name), readFileSync10(join12(srcDir, entry.name)));
3739
+ writeFileSync5(join14(destDir, entry.name), readFileSync11(join14(srcDir, entry.name)));
3175
3740
  }
3176
3741
  }
3177
3742
  }
@@ -3180,25 +3745,25 @@ function createBackup(cwd) {
3180
3745
  const dir = backupDirPath(cwd);
3181
3746
  let name = base;
3182
3747
  let suffix = 1;
3183
- while (existsSync11(join12(dir, name))) {
3748
+ while (existsSync16(join14(dir, name))) {
3184
3749
  name = `${base}-${suffix}`;
3185
3750
  suffix++;
3186
3751
  }
3187
3752
  const src = projectDir(cwd);
3188
- const dest = join12(dir, name);
3753
+ const dest = join14(dir, name);
3189
3754
  copyDirectoryFiles(src, dest, ["backups"]);
3190
3755
  return name;
3191
3756
  }
3192
3757
  function listBackups(cwd) {
3193
3758
  const dir = backupDirPath(cwd);
3194
- if (!existsSync11(dir))
3759
+ if (!existsSync16(dir))
3195
3760
  return [];
3196
- const entries = readdirSync5(dir, { withFileTypes: true });
3761
+ const entries = readdirSync6(dir, { withFileTypes: true });
3197
3762
  const backups = [];
3198
3763
  for (const entry of entries) {
3199
3764
  if (!entry.isDirectory() || !entry.name.startsWith("backup-"))
3200
3765
  continue;
3201
- const backupPath = join12(dir, entry.name);
3766
+ const backupPath = join14(dir, entry.name);
3202
3767
  const match = entry.name.match(/^backup-(\d{4})(\d{2})(\d{2})-(\d{2})(\d{2})(\d{2})(\d{3})?(?:-\d+)?$/);
3203
3768
  let timestamp;
3204
3769
  if (match) {
@@ -3208,7 +3773,7 @@ function listBackups(cwd) {
3208
3773
  }
3209
3774
  let fileCount = 0;
3210
3775
  try {
3211
- fileCount = readdirSync5(backupPath).length;
3776
+ fileCount = readdirSync6(backupPath).length;
3212
3777
  } catch {}
3213
3778
  backups.push({ name: entry.name, timestamp, path: backupPath, fileCount });
3214
3779
  }
@@ -3221,8 +3786,8 @@ function listBackups(cwd) {
3221
3786
  return backups;
3222
3787
  }
3223
3788
  function restoreBackup(cwd, backupName) {
3224
- const backupPath = join12(backupDirPath(cwd), backupName);
3225
- if (!existsSync11(backupPath)) {
3789
+ const backupPath = join14(backupDirPath(cwd), backupName);
3790
+ if (!existsSync16(backupPath)) {
3226
3791
  throw new Error(`backup not found: ${backupName}`);
3227
3792
  }
3228
3793
  createBackup(cwd);
@@ -3233,8 +3798,8 @@ var init_backup = __esm(() => {
3233
3798
  });
3234
3799
 
3235
3800
  // src/core/scanner.ts
3236
- import { readdirSync as readdirSync6, statSync as statSync7 } from "fs";
3237
- import { join as join13, relative } from "path";
3801
+ import { readdirSync as readdirSync7, statSync as statSync7 } from "fs";
3802
+ import { join as join15, relative } from "path";
3238
3803
  function matchesPattern(name, pattern) {
3239
3804
  if (pattern.includes("*")) {
3240
3805
  const regex = new RegExp("^" + pattern.replace(/\./g, "\\.").replace(/\*/g, ".*") + "$");
@@ -3248,7 +3813,7 @@ function isExcluded(name, excludes) {
3248
3813
  function walkDirectory(dir, projectRoot, excludes, results) {
3249
3814
  let entries;
3250
3815
  try {
3251
- entries = readdirSync6(dir, { withFileTypes: true });
3816
+ entries = readdirSync7(dir, { withFileTypes: true });
3252
3817
  } catch {
3253
3818
  return;
3254
3819
  }
@@ -3258,14 +3823,14 @@ function walkDirectory(dir, projectRoot, excludes, results) {
3258
3823
  if (entry.isDirectory()) {
3259
3824
  if (isExcluded(entry.name, excludes))
3260
3825
  continue;
3261
- walkDirectory(join13(dir, entry.name), projectRoot, excludes, results);
3826
+ walkDirectory(join15(dir, entry.name), projectRoot, excludes, results);
3262
3827
  continue;
3263
3828
  }
3264
3829
  if (entry.isFile()) {
3265
3830
  if (isExcluded(entry.name, excludes))
3266
3831
  continue;
3267
3832
  try {
3268
- const fullPath = join13(dir, entry.name);
3833
+ const fullPath = join15(dir, entry.name);
3269
3834
  const stat = statSync7(fullPath);
3270
3835
  results.push({
3271
3836
  relativePath: relative(projectRoot, fullPath),
@@ -3591,8 +4156,8 @@ var exports_scan = {};
3591
4156
  __export(exports_scan, {
3592
4157
  scan: () => scan
3593
4158
  });
3594
- import { readFileSync as readFileSync11 } from "fs";
3595
- import { join as join14, relative as relative2 } from "path";
4159
+ import { readFileSync as readFileSync12 } from "fs";
4160
+ import { join as join16, relative as relative2 } from "path";
3596
4161
  function configRelativePath(cfgPath, cwd) {
3597
4162
  const rel = relative2(cwd, cfgPath);
3598
4163
  return rel.startsWith("..") ? cfgPath : rel;
@@ -3647,10 +4212,10 @@ function scan(cwd, options) {
3647
4212
  newIndex.header.lifetimeHits = index.header.lifetimeHits;
3648
4213
  newIndex.header.lifetimeMisses = index.header.lifetimeMisses;
3649
4214
  for (const file of scanned) {
3650
- const fullPath = join14(cwd, file.relativePath);
4215
+ const fullPath = join16(cwd, file.relativePath);
3651
4216
  let content;
3652
4217
  try {
3653
- content = readFileSync11(fullPath, "utf-8");
4218
+ content = readFileSync12(fullPath, "utf-8");
3654
4219
  } catch {
3655
4220
  continue;
3656
4221
  }
@@ -3691,13 +4256,13 @@ __export(exports_seed, {
3691
4256
  parseGoMod: () => parseGoMod,
3692
4257
  parseCargoToml: () => parseCargoToml
3693
4258
  });
3694
- import { basename as basename4, join as join15 } from "path";
3695
- import { readFileSync as readFileSync12, existsSync as existsSync12 } from "fs";
4259
+ import { basename as basename4, join as join17 } from "path";
4260
+ import { readFileSync as readFileSync13, existsSync as existsSync17 } from "fs";
3696
4261
  function readFile(filePath) {
3697
- if (!existsSync12(filePath))
4262
+ if (!existsSync17(filePath))
3698
4263
  return null;
3699
4264
  try {
3700
- return readFileSync12(filePath, "utf-8");
4265
+ return readFileSync13(filePath, "utf-8");
3701
4266
  } catch {
3702
4267
  return null;
3703
4268
  }
@@ -3787,10 +4352,10 @@ function parseGoMod(filePath) {
3787
4352
  }
3788
4353
  function seedLearningMemory(projectRoot) {
3789
4354
  const parsers = [
3790
- () => parsePackageJson(join15(projectRoot, "package.json")),
3791
- () => parsePyprojectToml(join15(projectRoot, "pyproject.toml")),
3792
- () => parseCargoToml(join15(projectRoot, "Cargo.toml")),
3793
- () => parseGoMod(join15(projectRoot, "go.mod"))
4355
+ () => parsePackageJson(join17(projectRoot, "package.json")),
4356
+ () => parsePyprojectToml(join17(projectRoot, "pyproject.toml")),
4357
+ () => parseCargoToml(join17(projectRoot, "Cargo.toml")),
4358
+ () => parseGoMod(join17(projectRoot, "go.mod"))
3794
4359
  ];
3795
4360
  const infos = parsers.map((fn) => fn()).filter((info) => info !== null);
3796
4361
  const projectName = infos.find((i) => i.projectName)?.projectName ?? basename4(projectRoot);
@@ -3874,12 +4439,12 @@ __export(exports_init, {
3874
4439
  detectRuntime: () => detectRuntime,
3875
4440
  buildHooksConfig: () => buildHooksConfig
3876
4441
  });
3877
- import { execSync as execSync4 } from "child_process";
3878
- import { mkdirSync as mkdirSync7, existsSync as existsSync13 } from "fs";
3879
- import { resolve as resolve2, dirname as dirname5, basename as basename5, join as join16 } from "path";
4442
+ import { execSync as execSync5 } from "child_process";
4443
+ import { mkdirSync as mkdirSync7, existsSync as existsSync18 } from "fs";
4444
+ import { resolve as resolve2, dirname as dirname5, basename as basename5, join as join18 } from "path";
3880
4445
  function detectRuntime() {
3881
4446
  try {
3882
- execSync4("bun --version", { stdio: "ignore" });
4447
+ execSync5("bun --version", { stdio: "ignore" });
3883
4448
  return "bun";
3884
4449
  } catch {
3885
4450
  return "node";
@@ -3892,8 +4457,8 @@ function resolveCliPath() {
3892
4457
  return selfPath;
3893
4458
  }
3894
4459
  const projectRoot = resolve2(selfDir, "../..");
3895
- const distPath = join16(projectRoot, "dist", "cli.js");
3896
- if (existsSync13(distPath))
4460
+ const distPath = join18(projectRoot, "dist", "cli.js");
4461
+ if (existsSync18(distPath))
3897
4462
  return distPath;
3898
4463
  return resolve2(selfDir, "../cli.ts");
3899
4464
  }
@@ -3953,9 +4518,9 @@ function mergeHooksIntoSettings(settingsPath, newHooks) {
3953
4518
  }
3954
4519
  function isExistingInstallation(cwd) {
3955
4520
  const dir = projectDir(cwd);
3956
- if (!existsSync13(dir))
4521
+ if (!existsSync18(dir))
3957
4522
  return false;
3958
- return existsSync13(join16(dir, "file-index.json"));
4523
+ return existsSync18(join18(dir, "file-index.json"));
3959
4524
  }
3960
4525
  async function init(cwd) {
3961
4526
  const runtime = detectRuntime();
@@ -3973,16 +4538,20 @@ async function init(cwd) {
3973
4538
  mergeHooksIntoSettings(settingsPath, hooks);
3974
4539
  const rulePath = writeMinkRule(cwd);
3975
4540
  mkdirSync7(dir, { recursive: true });
3976
- const projectId = generateProjectId(cwd);
4541
+ const identity = resolveProjectIdentity(cwd);
4542
+ const projectId = identity.id;
3977
4543
  const isNotesProject = isWikiEnabled() && isVaultInitialized() && isInsideVault(cwd);
3978
4544
  const metaPath = projectMetaPath(cwd);
3979
4545
  const existingMeta = safeReadJson(metaPath);
4546
+ const deviceId = getOrCreateDeviceId();
4547
+ const existingPathsByDevice = existingMeta?.pathsByDevice && typeof existingMeta.pathsByDevice === "object" && !Array.isArray(existingMeta.pathsByDevice) ? existingMeta.pathsByDevice : {};
3980
4548
  atomicWriteJson(metaPath, {
3981
4549
  ...existingMeta ?? {},
3982
4550
  cwd,
3983
4551
  name: basename5(cwd),
3984
4552
  initTimestamp: existingMeta?.initTimestamp ?? new Date().toISOString(),
3985
4553
  version: "0.1.0",
4554
+ pathsByDevice: { ...existingPathsByDevice, [deviceId]: cwd },
3986
4555
  ...isNotesProject ? { projectType: "notes" } : {}
3987
4556
  });
3988
4557
  if (upgrading) {
@@ -3992,17 +4561,23 @@ async function init(cwd) {
3992
4561
  console.log(` rule: ${rulePath}`);
3993
4562
  } else {
3994
4563
  console.log(`[mink] initialized`);
3995
- console.log(` project: ${projectId}`);
4564
+ console.log(` project: ${projectId} (${identity.source})`);
3996
4565
  console.log(` state: ${dir}`);
3997
4566
  console.log(` runtime: ${runtime}`);
3998
4567
  console.log(` hooks: ${settingsPath}`);
3999
4568
  console.log(` rule: ${rulePath}`);
4000
4569
  }
4570
+ if (identity.source === "path-derived") {
4571
+ const root = getRepoRoot(cwd);
4572
+ if (root && !getRepoRemote(cwd)) {
4573
+ console.log(` note: this repo has no remote configured. Project state will not unify across machines until you add one and run \`mink config projects.identity git-remote\`.`);
4574
+ }
4575
+ }
4001
4576
  const { scan: scan2 } = await Promise.resolve().then(() => (init_scan(), exports_scan));
4002
4577
  scan2(cwd, { check: false });
4003
4578
  const { learningMemoryPath: learningMemoryPath3 } = await Promise.resolve().then(() => (init_paths(), exports_paths));
4004
4579
  const memPath = learningMemoryPath3(cwd);
4005
- if (!existsSync13(memPath)) {
4580
+ if (!existsSync18(memPath)) {
4006
4581
  const { seedLearningMemory: seedLearningMemory2 } = await Promise.resolve().then(() => (init_seed(), exports_seed));
4007
4582
  const { serializeLearningMemory: serializeLearningMemory2 } = await Promise.resolve().then(() => (init_learning_memory(), exports_learning_memory));
4008
4583
  const mem = seedLearningMemory2(cwd);
@@ -4011,8 +4586,8 @@ async function init(cwd) {
4011
4586
  if (isWikiEnabled() && isVaultInitialized() && !isNotesProject) {
4012
4587
  try {
4013
4588
  const projectSlug = basename5(cwd);
4014
- const overviewPath = join16(vaultProjects(projectSlug), "overview.md");
4015
- if (!existsSync13(overviewPath)) {
4589
+ const overviewPath = join18(vaultProjects(projectSlug), "overview.md");
4590
+ if (!existsSync18(overviewPath)) {
4016
4591
  const now = new Date().toISOString();
4017
4592
  const overview = [
4018
4593
  `---`,
@@ -4061,6 +4636,8 @@ var init_init = __esm(() => {
4061
4636
  init_paths();
4062
4637
  init_project_id();
4063
4638
  init_fs_utils();
4639
+ init_device();
4640
+ init_git_identity();
4064
4641
  init_vault();
4065
4642
  });
4066
4643
 
@@ -4099,12 +4676,12 @@ var init_state_counters = __esm(() => {
4099
4676
  });
4100
4677
 
4101
4678
  // src/core/channel-templates.ts
4102
- import { join as join17 } from "path";
4103
- import { existsSync as existsSync14, writeFileSync as writeFileSync6, mkdirSync as mkdirSync8 } from "fs";
4679
+ import { join as join19 } from "path";
4680
+ import { existsSync as existsSync19, writeFileSync as writeFileSync6, mkdirSync as mkdirSync8 } from "fs";
4104
4681
  function writeCompanionClaudeMd(vaultPath, overwrite = false) {
4105
4682
  mkdirSync8(vaultPath, { recursive: true });
4106
- const claudeMdPath = join17(vaultPath, "CLAUDE.md");
4107
- if (existsSync14(claudeMdPath) && !overwrite) {
4683
+ const claudeMdPath = join19(vaultPath, "CLAUDE.md");
4684
+ if (existsSync19(claudeMdPath) && !overwrite) {
4108
4685
  return false;
4109
4686
  }
4110
4687
  writeFileSync6(claudeMdPath, COMPANION_CLAUDE_MD);
@@ -4256,12 +4833,12 @@ mink wiki rebuild-index
4256
4833
  var init_channel_templates = () => {};
4257
4834
 
4258
4835
  // src/core/channel-process.ts
4259
- import { readFileSync as readFileSync13, writeFileSync as writeFileSync7, unlinkSync as unlinkSync3, mkdirSync as mkdirSync9, existsSync as existsSync15 } from "fs";
4260
- import { dirname as dirname6, join as join18 } from "path";
4836
+ import { readFileSync as readFileSync14, writeFileSync as writeFileSync7, unlinkSync as unlinkSync3, mkdirSync as mkdirSync9, existsSync as existsSync20 } from "fs";
4837
+ import { dirname as dirname6, join as join20 } from "path";
4261
4838
  import { spawnSync } from "child_process";
4262
4839
  function readChannelPidFile() {
4263
4840
  try {
4264
- const raw = readFileSync13(channelPidPath(), "utf-8");
4841
+ const raw = readFileSync14(channelPidPath(), "utf-8");
4265
4842
  const data = JSON.parse(raw);
4266
4843
  if (data && typeof data.session === "string" && typeof data.platform === "string" && typeof data.startedAt === "string" && typeof data.vaultPath === "string") {
4267
4844
  return data;
@@ -4403,18 +4980,18 @@ function getChannelLogs() {
4403
4980
  return null;
4404
4981
  if (!screenSessionExists(pidData.session))
4405
4982
  return null;
4406
- const tmpPath = join18(minkRoot(), `.channel-capture-${Date.now()}-${process.pid}.txt`);
4983
+ const tmpPath = join20(minkRoot(), `.channel-capture-${Date.now()}-${process.pid}.txt`);
4407
4984
  const result = spawnSync("screen", ["-S", pidData.session, "-X", "hardcopy", "-h", tmpPath], { stdio: "ignore" });
4408
4985
  if (result.status !== 0)
4409
4986
  return null;
4410
4987
  for (let i = 0;i < 20; i++) {
4411
- if (existsSync15(tmpPath))
4988
+ if (existsSync20(tmpPath))
4412
4989
  break;
4413
4990
  const delayUntil = Date.now() + 50;
4414
4991
  while (Date.now() < delayUntil) {}
4415
4992
  }
4416
4993
  try {
4417
- const content = readFileSync13(tmpPath, "utf-8");
4994
+ const content = readFileSync14(tmpPath, "utf-8");
4418
4995
  try {
4419
4996
  unlinkSync3(tmpPath);
4420
4997
  } catch {}
@@ -4588,12 +5165,12 @@ var init_runtime = __esm(() => {
4588
5165
  });
4589
5166
 
4590
5167
  // src/core/daemon.ts
4591
- import { readFileSync as readFileSync14, writeFileSync as writeFileSync8, unlinkSync as unlinkSync4, openSync } from "fs";
5168
+ import { readFileSync as readFileSync15, writeFileSync as writeFileSync8, unlinkSync as unlinkSync4, openSync } from "fs";
4592
5169
  import { mkdirSync as mkdirSync10 } from "fs";
4593
5170
  import { dirname as dirname7, resolve as resolve3 } from "path";
4594
5171
  function readPidFile() {
4595
5172
  try {
4596
- const raw = readFileSync14(schedulerPidPath(), "utf-8");
5173
+ const raw = readFileSync15(schedulerPidPath(), "utf-8");
4597
5174
  const data = JSON.parse(raw);
4598
5175
  if (data && typeof data.pid === "number" && typeof data.startedAt === "string" && typeof data.projectCwd === "string") {
4599
5176
  return data;
@@ -4747,9 +5324,9 @@ var exports_status = {};
4747
5324
  __export(exports_status, {
4748
5325
  status: () => status
4749
5326
  });
4750
- import { existsSync as existsSync17, readFileSync as readFileSync15, statSync as statSync8 } from "fs";
5327
+ import { existsSync as existsSync22, readFileSync as readFileSync16, statSync as statSync8 } from "fs";
4751
5328
  function checkJsonFile(name, filePath, validator) {
4752
- if (!existsSync17(filePath))
5329
+ if (!existsSync22(filePath))
4753
5330
  return { name, path: filePath, status: "missing" };
4754
5331
  const data = safeReadJson(filePath);
4755
5332
  if (data === null)
@@ -4759,10 +5336,10 @@ function checkJsonFile(name, filePath, validator) {
4759
5336
  return { name, path: filePath, status: "ok" };
4760
5337
  }
4761
5338
  function checkTextFile(name, filePath) {
4762
- if (!existsSync17(filePath))
5339
+ if (!existsSync22(filePath))
4763
5340
  return { name, path: filePath, status: "missing" };
4764
5341
  try {
4765
- readFileSync15(filePath, "utf-8");
5342
+ readFileSync16(filePath, "utf-8");
4766
5343
  return { name, path: filePath, status: "ok" };
4767
5344
  } catch {
4768
5345
  return { name, path: filePath, status: "corrupt" };
@@ -4836,7 +5413,7 @@ function status(cwd) {
4836
5413
  console.log(` Decision Log: ${mem.sections["Decision Log"].length}`);
4837
5414
  console.log(` Total entries: ${total}`);
4838
5415
  const memPath = learningMemoryPath(cwd);
4839
- if (existsSync17(memPath)) {
5416
+ if (existsSync22(memPath)) {
4840
5417
  const mtime = statSync8(memPath).mtime;
4841
5418
  console.log(` Canonical last modified: ${mtime.toISOString()}`);
4842
5419
  }
@@ -4881,8 +5458,8 @@ var exports_scan2 = {};
4881
5458
  __export(exports_scan2, {
4882
5459
  scan: () => scan2
4883
5460
  });
4884
- import { readFileSync as readFileSync16 } from "fs";
4885
- import { join as join19, relative as relative3 } from "path";
5461
+ import { readFileSync as readFileSync17 } from "fs";
5462
+ import { join as join21, relative as relative3 } from "path";
4886
5463
  function configRelativePath2(cfgPath, cwd) {
4887
5464
  const rel = relative3(cwd, cfgPath);
4888
5465
  return rel.startsWith("..") ? cfgPath : rel;
@@ -4937,10 +5514,10 @@ function scan2(cwd, options) {
4937
5514
  newIndex.header.lifetimeHits = index.header.lifetimeHits;
4938
5515
  newIndex.header.lifetimeMisses = index.header.lifetimeMisses;
4939
5516
  for (const file of scanned) {
4940
- const fullPath = join19(cwd, file.relativePath);
5517
+ const fullPath = join21(cwd, file.relativePath);
4941
5518
  let content;
4942
5519
  try {
4943
- content = readFileSync16(fullPath, "utf-8");
5520
+ content = readFileSync17(fullPath, "utf-8");
4944
5521
  } catch {
4945
5522
  continue;
4946
5523
  }
@@ -4977,12 +5554,12 @@ var exports_reflect2 = {};
4977
5554
  __export(exports_reflect2, {
4978
5555
  reflect: () => reflect2
4979
5556
  });
4980
- import { existsSync as existsSync18 } from "fs";
5557
+ import { existsSync as existsSync23 } from "fs";
4981
5558
  import { dirname as dirname8 } from "path";
4982
5559
  function reflect2(_cwd, memoryPath, configPath3) {
4983
5560
  const projDir = dirname8(memoryPath);
4984
5561
  const mem = aggregateLearningMemoryAt(projDir);
4985
- if (totalEntryCount(mem) === 0 && !existsSync18(memoryPath)) {
5562
+ if (totalEntryCount(mem) === 0 && !existsSync23(memoryPath)) {
4986
5563
  console.log("[mink] no learning memory found");
4987
5564
  return null;
4988
5565
  }
@@ -5380,7 +5957,7 @@ __export(exports_post_write, {
5380
5957
  analyzePostWrite: () => analyzePostWrite
5381
5958
  });
5382
5959
  import { relative as relative7 } from "path";
5383
- import { readFileSync as readFileSync17 } from "fs";
5960
+ import { readFileSync as readFileSync18 } from "fs";
5384
5961
  function analyzePostWrite(filePath, fileContent, index) {
5385
5962
  if (isWriteExcluded(filePath)) {
5386
5963
  return {
@@ -5444,7 +6021,7 @@ async function postWrite(cwd) {
5444
6021
  const filePath = relative7(cwd, absolutePath);
5445
6022
  let fileContent = null;
5446
6023
  try {
5447
- fileContent = readFileSync17(absolutePath, "utf-8");
6024
+ fileContent = readFileSync18(absolutePath, "utf-8");
5448
6025
  } catch {}
5449
6026
  const rawState = safeReadJson(sessionPath(cwd));
5450
6027
  const state = isSessionState(rawState) ? rawState : createSessionState();
@@ -5806,9 +6383,9 @@ __export(exports_self_update, {
5806
6383
  PACKAGE_NAME: () => PACKAGE_NAME
5807
6384
  });
5808
6385
  import { spawnSync as spawnSync2 } from "child_process";
5809
- import { existsSync as existsSync19, readFileSync as readFileSync18 } from "fs";
6386
+ import { existsSync as existsSync24, readFileSync as readFileSync19 } from "fs";
5810
6387
  import { dirname as dirname9 } from "path";
5811
- import { join as join20 } from "path";
6388
+ import { join as join22 } from "path";
5812
6389
  function parseSemver(input) {
5813
6390
  const trimmed = input.trim().replace(/^v/, "");
5814
6391
  if (!trimmed)
@@ -5858,8 +6435,8 @@ function getInstallInfo() {
5858
6435
  let dir = dirname9(selfPath);
5859
6436
  let packageJsonPath = null;
5860
6437
  for (let i = 0;i < 10; i++) {
5861
- const candidate = join20(dir, "package.json");
5862
- if (existsSync19(candidate)) {
6438
+ const candidate = join22(dir, "package.json");
6439
+ if (existsSync24(candidate)) {
5863
6440
  packageJsonPath = candidate;
5864
6441
  break;
5865
6442
  }
@@ -5873,7 +6450,7 @@ function getInstallInfo() {
5873
6450
  }
5874
6451
  let currentVersion = "0.0.0";
5875
6452
  try {
5876
- const pkg = JSON.parse(readFileSync18(packageJsonPath, "utf-8"));
6453
+ const pkg = JSON.parse(readFileSync19(packageJsonPath, "utf-8"));
5877
6454
  if (typeof pkg.version === "string")
5878
6455
  currentVersion = pkg.version;
5879
6456
  } catch {}
@@ -5933,7 +6510,7 @@ function buildInstallCommand(pm, version) {
5933
6510
  return ["npm", "install", "-g", ref];
5934
6511
  }
5935
6512
  function selfUpdateLogPath() {
5936
- return join20(minkRoot(), "self-update.log");
6513
+ return join22(minkRoot(), "self-update.log");
5937
6514
  }
5938
6515
  function appendLogEntry(entry) {
5939
6516
  const path = selfUpdateLogPath();
@@ -5946,7 +6523,7 @@ function appendLogEntry(entry) {
5946
6523
  }
5947
6524
  function rotateLogIfNeeded(path) {
5948
6525
  try {
5949
- const content = readFileSync18(path, "utf-8");
6526
+ const content = readFileSync19(path, "utf-8");
5950
6527
  const lines = content.split(`
5951
6528
  `);
5952
6529
  if (lines.length <= LOG_MAX_LINES + 1)
@@ -6049,7 +6626,7 @@ async function runSelfUpgradeInner(opts) {
6049
6626
  }
6050
6627
  let verifiedVersion = latest;
6051
6628
  try {
6052
- const pkg = JSON.parse(readFileSync18(info.packageJsonPath, "utf-8"));
6629
+ const pkg = JSON.parse(readFileSync19(info.packageJsonPath, "utf-8"));
6053
6630
  if (typeof pkg.version === "string")
6054
6631
  verifiedVersion = pkg.version;
6055
6632
  } catch {}
@@ -6155,10 +6732,10 @@ async function executeTask(taskId, projectCwd) {
6155
6732
  if (task.actionType === "ai-cli") {
6156
6733
  try {
6157
6734
  const { learningMemoryPath: learningMemoryPath5 } = await Promise.resolve().then(() => (init_paths(), exports_paths));
6158
- const { readFileSync: readFileSync19 } = await import("fs");
6735
+ const { readFileSync: readFileSync20 } = await import("fs");
6159
6736
  let memoryContent;
6160
6737
  try {
6161
- memoryContent = readFileSync19(learningMemoryPath5(projectCwd), "utf-8");
6738
+ memoryContent = readFileSync20(learningMemoryPath5(projectCwd), "utf-8");
6162
6739
  } catch {
6163
6740
  console.log("[mink] no learning memory found, skipping reflection");
6164
6741
  return;
@@ -6722,22 +7299,22 @@ var init_cron = __esm(() => {
6722
7299
  });
6723
7300
 
6724
7301
  // src/core/vault-templates.ts
6725
- import { join as join21 } from "path";
6726
- import { existsSync as existsSync20, writeFileSync as writeFileSync9, readFileSync as readFileSync19, mkdirSync as mkdirSync11 } from "fs";
7302
+ import { join as join23 } from "path";
7303
+ import { existsSync as existsSync25, writeFileSync as writeFileSync9, readFileSync as readFileSync20, mkdirSync as mkdirSync11 } from "fs";
6727
7304
  function seedTemplates(templatesDir) {
6728
7305
  mkdirSync11(templatesDir, { recursive: true });
6729
7306
  for (const [name, content] of Object.entries(DEFAULT_TEMPLATES)) {
6730
- const filePath = join21(templatesDir, `${name}.md`);
6731
- if (!existsSync20(filePath)) {
7307
+ const filePath = join23(templatesDir, `${name}.md`);
7308
+ if (!existsSync25(filePath)) {
6732
7309
  writeFileSync9(filePath, content);
6733
7310
  }
6734
7311
  }
6735
7312
  }
6736
7313
  function loadTemplate(templatesDir, templateName, vars) {
6737
- const filePath = join21(templatesDir, `${templateName}.md`);
7314
+ const filePath = join23(templatesDir, `${templateName}.md`);
6738
7315
  let content;
6739
- if (existsSync20(filePath)) {
6740
- content = readFileSync19(filePath, "utf-8");
7316
+ if (existsSync25(filePath)) {
7317
+ content = readFileSync20(filePath, "utf-8");
6741
7318
  } else if (DEFAULT_TEMPLATES[templateName]) {
6742
7319
  content = DEFAULT_TEMPLATES[templateName];
6743
7320
  } else {
@@ -6890,33 +7467,33 @@ category: resources
6890
7467
  });
6891
7468
 
6892
7469
  // src/core/note-writer.ts
6893
- import { join as join22 } from "path";
6894
- import { existsSync as existsSync21, readFileSync as readFileSync20 } from "fs";
7470
+ import { join as join24 } from "path";
7471
+ import { existsSync as existsSync26, readFileSync as readFileSync21 } from "fs";
6895
7472
  import { createHash as createHash2 } from "crypto";
6896
7473
  function sha256(content) {
6897
7474
  return createHash2("sha256").update(content).digest("hex");
6898
7475
  }
6899
7476
  function resolveUniqueNotePath(dir, baseSlug, content) {
6900
7477
  const targetHash = sha256(content);
6901
- const primary = join22(dir, `${baseSlug}.md`);
6902
- if (!existsSync21(primary))
7478
+ const primary = join24(dir, `${baseSlug}.md`);
7479
+ if (!existsSync26(primary))
6903
7480
  return primary;
6904
7481
  if (sameContent(primary, targetHash))
6905
7482
  return primary;
6906
7483
  const dev4 = getOrCreateDeviceId().replace(/-/g, "").slice(0, 4);
6907
7484
  for (let i = 0;i < MAX_COLLISION_ATTEMPTS; i++) {
6908
7485
  const suffix = i === 0 ? dev4 : `${dev4}-${i + 1}`;
6909
- const candidate = join22(dir, `${baseSlug}-${suffix}.md`);
6910
- if (!existsSync21(candidate))
7486
+ const candidate = join24(dir, `${baseSlug}-${suffix}.md`);
7487
+ if (!existsSync26(candidate))
6911
7488
  return candidate;
6912
7489
  if (sameContent(candidate, targetHash))
6913
7490
  return candidate;
6914
7491
  }
6915
- return join22(dir, `${baseSlug}-${Date.now()}.md`);
7492
+ return join24(dir, `${baseSlug}-${Date.now()}.md`);
6916
7493
  }
6917
7494
  function sameContent(filePath, expectedHash) {
6918
7495
  try {
6919
- return sha256(readFileSync20(filePath, "utf-8")) === expectedHash;
7496
+ return sha256(readFileSync21(filePath, "utf-8")) === expectedHash;
6920
7497
  } catch {
6921
7498
  return false;
6922
7499
  }
@@ -6987,8 +7564,8 @@ ${meta.body}
6987
7564
  }
6988
7565
  function appendToDaily(date, content) {
6989
7566
  const dir = vaultDailyDir();
6990
- const filePath = join22(dir, `${date}.md`);
6991
- if (existsSync21(filePath)) {
7567
+ const filePath = join24(dir, `${date}.md`);
7568
+ if (existsSync26(filePath)) {
6992
7569
  const timestamp = new Date().toLocaleTimeString("en-US", {
6993
7570
  hour: "2-digit",
6994
7571
  minute: "2-digit",
@@ -7025,7 +7602,7 @@ ${content}
7025
7602
  return filePath;
7026
7603
  }
7027
7604
  function ingestFile(sourcePath, meta) {
7028
- const raw = readFileSync20(sourcePath, "utf-8");
7605
+ const raw = readFileSync21(sourcePath, "utf-8");
7029
7606
  const now = new Date().toISOString();
7030
7607
  const headingMatch = raw.match(/^#\s+(.+)$/m);
7031
7608
  const title = headingMatch?.[1] ?? sourcePath.split("/").pop().replace(/\.md$/, "");
@@ -7097,10 +7674,10 @@ var init_design_eval = __esm(() => {
7097
7674
  });
7098
7675
 
7099
7676
  // src/core/dashboard-api.ts
7100
- import { existsSync as existsSync22, readFileSync as readFileSync21 } from "fs";
7101
- import { readdirSync as readdirSync7, readFileSync as readFileSyncFS, existsSync as fsExistsSync } from "fs";
7102
- import { join as join23, resolve as resolve5, normalize, sep } from "path";
7103
- import { execSync as execSync5 } from "child_process";
7677
+ import { existsSync as existsSync27, readFileSync as readFileSync22 } from "fs";
7678
+ import { readdirSync as readdirSync8, readFileSync as readFileSyncFS, existsSync as fsExistsSync } from "fs";
7679
+ import { join as join25, resolve as resolve5, normalize, sep } from "path";
7680
+ import { execSync as execSync6 } from "child_process";
7104
7681
  function isSecretKey(key) {
7105
7682
  return SECRET_KEY_PATTERNS.some((re) => re.test(key));
7106
7683
  }
@@ -7112,7 +7689,7 @@ function maskSecret(value, showLast = 4) {
7112
7689
  return "••••" + value.slice(-showLast);
7113
7690
  }
7114
7691
  function checkJsonFile2(name, filePath, validator) {
7115
- if (!existsSync22(filePath))
7692
+ if (!existsSync27(filePath))
7116
7693
  return { name, status: "missing" };
7117
7694
  const data = safeReadJson(filePath);
7118
7695
  if (data === null)
@@ -7122,10 +7699,10 @@ function checkJsonFile2(name, filePath, validator) {
7122
7699
  return { name, status: "ok" };
7123
7700
  }
7124
7701
  function checkTextFile2(name, filePath) {
7125
- if (!existsSync22(filePath))
7702
+ if (!existsSync27(filePath))
7126
7703
  return { name, status: "missing" };
7127
7704
  try {
7128
- readFileSync21(filePath, "utf-8");
7705
+ readFileSync22(filePath, "utf-8");
7129
7706
  return { name, status: "ok" };
7130
7707
  } catch {
7131
7708
  return { name, status: "corrupt" };
@@ -7297,7 +7874,7 @@ function getAheadBehind(branch) {
7297
7874
  if (!branch)
7298
7875
  return { ahead: 0, behind: 0 };
7299
7876
  try {
7300
- const raw = execSync5(`git rev-list --left-right --count origin/${branch}...${branch}`, { cwd: minkRoot(), timeout: 5000, stdio: ["pipe", "pipe", "pipe"] }).toString().trim();
7877
+ const raw = execSync6(`git rev-list --left-right --count origin/${branch}...${branch}`, { cwd: minkRoot(), timeout: 5000, stdio: ["pipe", "pipe", "pipe"] }).toString().trim();
7301
7878
  const [behindStr, aheadStr] = raw.split(/\s+/);
7302
7879
  return {
7303
7880
  behind: Number(behindStr) || 0,
@@ -7309,7 +7886,7 @@ function getAheadBehind(branch) {
7309
7886
  }
7310
7887
  function getPendingChanges() {
7311
7888
  try {
7312
- const raw = execSync5("git status --porcelain", {
7889
+ const raw = execSync6("git status --porcelain", {
7313
7890
  cwd: minkRoot(),
7314
7891
  timeout: 5000,
7315
7892
  stdio: ["pipe", "pipe", "pipe"]
@@ -7378,10 +7955,10 @@ function loadChannelPanel() {
7378
7955
  function countMarkdownIn(dir) {
7379
7956
  let count = 0;
7380
7957
  try {
7381
- for (const entry of readdirSync7(dir, { withFileTypes: true })) {
7958
+ for (const entry of readdirSync8(dir, { withFileTypes: true })) {
7382
7959
  if (WIKI_TREE_EXCLUDES.has(entry.name) || entry.name.startsWith("."))
7383
7960
  continue;
7384
- const fullPath = join23(dir, entry.name);
7961
+ const fullPath = join25(dir, entry.name);
7385
7962
  if (entry.isDirectory()) {
7386
7963
  count += countMarkdownIn(fullPath);
7387
7964
  } else if (entry.name.endsWith(".md") && !entry.name.startsWith("_")) {
@@ -7398,7 +7975,7 @@ function buildVaultTree(root) {
7398
7975
  return;
7399
7976
  let entries = [];
7400
7977
  try {
7401
- entries = readdirSync7(dir, { withFileTypes: true }).filter((e) => !WIKI_TREE_EXCLUDES.has(e.name) && !e.name.startsWith(".")).map((e) => ({ name: e.name, isDir: e.isDirectory() }));
7978
+ entries = readdirSync8(dir, { withFileTypes: true }).filter((e) => !WIKI_TREE_EXCLUDES.has(e.name) && !e.name.startsWith(".")).map((e) => ({ name: e.name, isDir: e.isDirectory() }));
7402
7979
  } catch {
7403
7980
  return;
7404
7981
  }
@@ -7410,7 +7987,7 @@ function buildVaultTree(root) {
7410
7987
  for (const entry of entries) {
7411
7988
  if (!entry.isDir)
7412
7989
  continue;
7413
- const fullPath = join23(dir, entry.name);
7990
+ const fullPath = join25(dir, entry.name);
7414
7991
  const relPath = fullPath.slice(root.length + 1);
7415
7992
  const count = countMarkdownIn(fullPath);
7416
7993
  nodes.push({ name: entry.name, path: relPath, count, depth });
@@ -7833,7 +8410,7 @@ async function triggerIngestFile(sourcePath, category, tags, dedupKey) {
7833
8410
  if (!isValidCategory(category)) {
7834
8411
  return { success: false, error: `Invalid category: ${category}` };
7835
8412
  }
7836
- const expanded = sourcePath.startsWith("~/") ? join23(process.env.HOME ?? "", sourcePath.slice(2)) : sourcePath;
8413
+ const expanded = sourcePath.startsWith("~/") ? join25(process.env.HOME ?? "", sourcePath.slice(2)) : sourcePath;
7837
8414
  if (!fsExistsSync(expanded)) {
7838
8415
  return { success: false, error: `Source file not found: ${sourcePath}` };
7839
8416
  }
@@ -7912,61 +8489,14 @@ var init_dashboard_api = __esm(() => {
7912
8489
  dedupCache = new Map;
7913
8490
  });
7914
8491
 
7915
- // src/core/project-registry.ts
7916
- import { readdirSync as readdirSync8, existsSync as existsSync23 } from "fs";
7917
- import { join as join24 } from "path";
7918
- function getProjectMeta(projDir) {
7919
- const metaPath = join24(projDir, "project-meta.json");
7920
- const raw = safeReadJson(metaPath);
7921
- if (raw === null || typeof raw !== "object" || Array.isArray(raw)) {
7922
- return null;
7923
- }
7924
- const obj = raw;
7925
- if (typeof obj.cwd !== "string" || typeof obj.name !== "string") {
7926
- return null;
7927
- }
7928
- return {
7929
- cwd: obj.cwd,
7930
- name: obj.name,
7931
- initTimestamp: obj.initTimestamp ?? "",
7932
- version: obj.version ?? "0.1.0"
7933
- };
7934
- }
7935
- function listRegisteredProjects() {
7936
- const projectsDir = join24(minkRoot(), "projects");
7937
- if (!existsSync23(projectsDir))
7938
- return [];
7939
- const entries = readdirSync8(projectsDir, { withFileTypes: true });
7940
- const projects = [];
7941
- for (const entry of entries) {
7942
- if (!entry.isDirectory())
7943
- continue;
7944
- const projDir = join24(projectsDir, entry.name);
7945
- const meta = getProjectMeta(projDir);
7946
- if (meta) {
7947
- projects.push({
7948
- id: entry.name,
7949
- cwd: meta.cwd,
7950
- name: meta.name,
7951
- version: meta.version
7952
- });
7953
- }
7954
- }
7955
- return projects;
7956
- }
7957
- var init_project_registry = __esm(() => {
7958
- init_paths();
7959
- init_fs_utils();
7960
- });
7961
-
7962
8492
  // src/core/dashboard-server.ts
7963
8493
  var exports_dashboard_server = {};
7964
8494
  __export(exports_dashboard_server, {
7965
8495
  startDashboardServer: () => startDashboardServer
7966
8496
  });
7967
8497
  import { watch } from "fs";
7968
- import { existsSync as existsSync24 } from "fs";
7969
- import { basename as basename7, dirname as dirname10, join as join25, extname as extname2 } from "path";
8498
+ import { existsSync as existsSync28 } from "fs";
8499
+ import { basename as basename7, dirname as dirname10, join as join26, extname as extname2 } from "path";
7970
8500
 
7971
8501
  class SSEManager {
7972
8502
  clients = new Map;
@@ -8027,18 +8557,18 @@ function resolveProjectCwd(url, defaultCwd) {
8027
8557
  const projectId = url.searchParams.get("project");
8028
8558
  if (!projectId)
8029
8559
  return defaultCwd;
8030
- if (projectId === generateProjectId(defaultCwd))
8560
+ if (projectId === projectIdFor(defaultCwd))
8031
8561
  return defaultCwd;
8032
8562
  const projects = listRegisteredProjects();
8033
- const match = projects.find((p) => p.id === projectId);
8563
+ const match = projects.find((p) => p.id === projectId) ?? projects.find((p) => p.aliases.includes(projectId));
8034
8564
  if (!match)
8035
8565
  return null;
8036
8566
  return match.cwd;
8037
8567
  }
8038
8568
  function getProjectsList(startupCwd, activeCwd) {
8039
- const activeId = generateProjectId(activeCwd);
8569
+ const activeId = projectIdFor(activeCwd);
8040
8570
  const registered = listRegisteredProjects();
8041
- const startupId = generateProjectId(startupCwd);
8571
+ const startupId = projectIdFor(startupCwd);
8042
8572
  const hasStartup = registered.some((p) => p.id === startupId);
8043
8573
  if (!hasStartup) {
8044
8574
  const meta = getProjectMeta(projectDir(startupCwd));
@@ -8046,7 +8576,9 @@ function getProjectsList(startupCwd, activeCwd) {
8046
8576
  id: startupId,
8047
8577
  cwd: startupCwd,
8048
8578
  name: meta?.name ?? basename7(startupCwd),
8049
- version: meta?.version ?? "0.1.0"
8579
+ version: meta?.version ?? "0.1.0",
8580
+ aliases: meta?.aliases ?? [],
8581
+ pathsByDevice: meta?.pathsByDevice ?? {}
8050
8582
  });
8051
8583
  }
8052
8584
  if (activeId !== startupId) {
@@ -8057,7 +8589,9 @@ function getProjectsList(startupCwd, activeCwd) {
8057
8589
  id: activeId,
8058
8590
  cwd: activeCwd,
8059
8591
  name: meta?.name ?? basename7(activeCwd),
8060
- version: meta?.version ?? "0.1.0"
8592
+ version: meta?.version ?? "0.1.0",
8593
+ aliases: meta?.aliases ?? [],
8594
+ pathsByDevice: meta?.pathsByDevice ?? {}
8061
8595
  });
8062
8596
  }
8063
8597
  }
@@ -8142,12 +8676,12 @@ async function startDashboardServer(cwd, options = {}) {
8142
8676
  const __dir = dirname10(new URL(import.meta.url).pathname);
8143
8677
  let pkgRoot = __dir;
8144
8678
  while (pkgRoot !== dirname10(pkgRoot)) {
8145
- if (existsSync24(join25(pkgRoot, "package.json")))
8679
+ if (existsSync28(join26(pkgRoot, "package.json")))
8146
8680
  break;
8147
8681
  pkgRoot = dirname10(pkgRoot);
8148
8682
  }
8149
- const dashboardOutDir = join25(pkgRoot, "dashboard", "out");
8150
- const dashboardBuilt = existsSync24(join25(dashboardOutDir, "index.html"));
8683
+ const dashboardOutDir = join26(pkgRoot, "dashboard", "out");
8684
+ const dashboardBuilt = existsSync28(join26(dashboardOutDir, "index.html"));
8151
8685
  let clientIdCounter = 0;
8152
8686
  if (!dashboardBuilt) {
8153
8687
  console.warn("[mink] dashboard not built. Run: cd dashboard && bun run build");
@@ -8177,9 +8711,9 @@ async function startDashboardServer(cwd, options = {}) {
8177
8711
  } else {
8178
8712
  let filePath;
8179
8713
  if (pathname === "/") {
8180
- filePath = join25(dashboardOutDir, "index.html");
8714
+ filePath = join26(dashboardOutDir, "index.html");
8181
8715
  } else {
8182
- filePath = join25(dashboardOutDir, pathname);
8716
+ filePath = join26(dashboardOutDir, pathname);
8183
8717
  }
8184
8718
  if (!filePath.startsWith(dashboardOutDir)) {
8185
8719
  return jsonResponse({ error: "Forbidden" }, 403);
@@ -8192,7 +8726,7 @@ async function startDashboardServer(cwd, options = {}) {
8192
8726
  const htmlServed = await serveFile(filePath + ".html", "text/html; charset=utf-8");
8193
8727
  if (htmlServed)
8194
8728
  return htmlServed;
8195
- const indexServed = await serveFile(join25(dashboardOutDir, "index.html"), "text/html; charset=utf-8");
8729
+ const indexServed = await serveFile(join26(dashboardOutDir, "index.html"), "text/html; charset=utf-8");
8196
8730
  if (indexServed)
8197
8731
  return indexServed;
8198
8732
  }
@@ -8301,7 +8835,7 @@ retry: 3000
8301
8835
  if (!filename || filename.includes("..") || filename.includes("/")) {
8302
8836
  return jsonResponse({ error: "Invalid filename" }, 400);
8303
8837
  }
8304
- const imgPath = join25(designCapturesDir(resolvedCwd), filename);
8838
+ const imgPath = join26(designCapturesDir(resolvedCwd), filename);
8305
8839
  const served = await serveFile(imgPath, "image/jpeg");
8306
8840
  if (served) {
8307
8841
  served.headers.set("Cache-Control", "public, max-age=60");
@@ -8535,9 +9069,9 @@ var exports_dashboard = {};
8535
9069
  __export(exports_dashboard, {
8536
9070
  dashboard: () => dashboard
8537
9071
  });
8538
- import { existsSync as existsSync25 } from "fs";
9072
+ import { existsSync as existsSync29 } from "fs";
8539
9073
  async function dashboard(cwd, args) {
8540
- if (!existsSync25(projectDir(cwd))) {
9074
+ if (!existsSync29(projectDir(cwd))) {
8541
9075
  console.error("[mink] project not initialized. Run: mink init");
8542
9076
  process.exit(1);
8543
9077
  }
@@ -8555,8 +9089,8 @@ var init_dashboard = __esm(() => {
8555
9089
  });
8556
9090
 
8557
9091
  // src/commands/init.ts
8558
- import { mkdirSync as mkdirSync12, existsSync as existsSync26 } from "fs";
8559
- import { resolve as resolve6, dirname as dirname11, basename as basename8, join as join26 } from "path";
9092
+ import { mkdirSync as mkdirSync12, existsSync as existsSync30 } from "fs";
9093
+ import { resolve as resolve6, dirname as dirname11, basename as basename8, join as join27 } from "path";
8560
9094
  function resolveCliPath2() {
8561
9095
  const selfPath = new URL(import.meta.url).pathname;
8562
9096
  const selfDir = dirname11(selfPath);
@@ -8564,8 +9098,8 @@ function resolveCliPath2() {
8564
9098
  return selfPath;
8565
9099
  }
8566
9100
  const projectRoot = resolve6(selfDir, "../..");
8567
- const distPath = join26(projectRoot, "dist", "cli.js");
8568
- if (existsSync26(distPath))
9101
+ const distPath = join27(projectRoot, "dist", "cli.js");
9102
+ if (existsSync30(distPath))
8569
9103
  return distPath;
8570
9104
  return resolve6(selfDir, "../cli.ts");
8571
9105
  }
@@ -8621,14 +9155,16 @@ var init_init2 = __esm(() => {
8621
9155
  init_paths();
8622
9156
  init_project_id();
8623
9157
  init_fs_utils();
9158
+ init_device();
9159
+ init_git_identity();
8624
9160
  init_vault();
8625
9161
  });
8626
9162
 
8627
9163
  // src/core/daemon-service.ts
8628
- import { execSync as execSync6 } from "child_process";
8629
- import { existsSync as existsSync27, mkdirSync as mkdirSync13, unlinkSync as unlinkSync5, writeFileSync as writeFileSync10 } from "fs";
9164
+ import { execSync as execSync7 } from "child_process";
9165
+ import { existsSync as existsSync31, mkdirSync as mkdirSync13, unlinkSync as unlinkSync5, writeFileSync as writeFileSync10 } from "fs";
8630
9166
  import { homedir as homedir4 } from "os";
8631
- import { dirname as dirname12, join as join27 } from "path";
9167
+ import { dirname as dirname12, join as join28 } from "path";
8632
9168
  function detectPlatform() {
8633
9169
  if (process.platform === "linux")
8634
9170
  return "systemd";
@@ -8638,7 +9174,7 @@ function detectPlatform() {
8638
9174
  }
8639
9175
  function resolveServiceInvocation() {
8640
9176
  const entry = process.argv[1];
8641
- if (entry && !/\.(js|ts|mjs|cjs)$/.test(entry) && existsSync27(entry)) {
9177
+ if (entry && !/\.(js|ts|mjs|cjs)$/.test(entry) && existsSync31(entry)) {
8642
9178
  return {
8643
9179
  executable: entry,
8644
9180
  args: ["daemon", "start"],
@@ -8656,11 +9192,11 @@ function resolveServiceInvocation() {
8656
9192
  function servicePaths(platform2) {
8657
9193
  const home = homedir4();
8658
9194
  if (platform2 === "systemd") {
8659
- const unitDir2 = join27(home, ".config", "systemd", "user");
8660
- return { unitDir: unitDir2, unitFile: join27(unitDir2, "mink-daemon.service") };
9195
+ const unitDir2 = join28(home, ".config", "systemd", "user");
9196
+ return { unitDir: unitDir2, unitFile: join28(unitDir2, "mink-daemon.service") };
8661
9197
  }
8662
- const unitDir = join27(home, "Library", "LaunchAgents");
8663
- return { unitDir, unitFile: join27(unitDir, "com.mink.daemon.plist") };
9198
+ const unitDir = join28(home, "Library", "LaunchAgents");
9199
+ return { unitDir, unitFile: join28(unitDir, "com.mink.daemon.plist") };
8664
9200
  }
8665
9201
  function renderSystemdUnit(inv) {
8666
9202
  const execStart = [inv.executable, ...inv.args].join(" ");
@@ -8734,7 +9270,7 @@ function installService(options = {}) {
8734
9270
  process.exit(1);
8735
9271
  }
8736
9272
  const paths = servicePaths(platform2);
8737
- if (existsSync27(paths.unitFile) && !options.force) {
9273
+ if (existsSync31(paths.unitFile) && !options.force) {
8738
9274
  console.error(`[mink] unit file already exists: ${paths.unitFile}`);
8739
9275
  console.error(" re-run with --force to overwrite, or run `mink daemon uninstall` first");
8740
9276
  process.exit(1);
@@ -8744,7 +9280,7 @@ function installService(options = {}) {
8744
9280
  if (platform2 === "systemd") {
8745
9281
  writeFileSync10(paths.unitFile, renderSystemdUnit(inv));
8746
9282
  try {
8747
- execSync6("systemctl --user daemon-reload", { stdio: "ignore" });
9283
+ execSync7("systemctl --user daemon-reload", { stdio: "ignore" });
8748
9284
  } catch {}
8749
9285
  console.log(`[mink] wrote ${paths.unitFile}`);
8750
9286
  console.log("[mink] next steps:");
@@ -8767,24 +9303,24 @@ function uninstallService() {
8767
9303
  process.exit(1);
8768
9304
  }
8769
9305
  const paths = servicePaths(platform2);
8770
- if (!existsSync27(paths.unitFile)) {
9306
+ if (!existsSync31(paths.unitFile)) {
8771
9307
  console.log(`[mink] no unit file at ${paths.unitFile} — nothing to uninstall`);
8772
9308
  return;
8773
9309
  }
8774
9310
  if (platform2 === "systemd") {
8775
9311
  try {
8776
- execSync6("systemctl --user disable --now mink-daemon.service", {
9312
+ execSync7("systemctl --user disable --now mink-daemon.service", {
8777
9313
  stdio: "ignore"
8778
9314
  });
8779
9315
  } catch {}
8780
9316
  unlinkSync5(paths.unitFile);
8781
9317
  try {
8782
- execSync6("systemctl --user daemon-reload", { stdio: "ignore" });
9318
+ execSync7("systemctl --user daemon-reload", { stdio: "ignore" });
8783
9319
  } catch {}
8784
9320
  console.log(`[mink] removed ${paths.unitFile}`);
8785
9321
  } else {
8786
9322
  try {
8787
- execSync6(`launchctl unload -w ${paths.unitFile}`, { stdio: "ignore" });
9323
+ execSync7(`launchctl unload -w ${paths.unitFile}`, { stdio: "ignore" });
8788
9324
  } catch {}
8789
9325
  unlinkSync5(paths.unitFile);
8790
9326
  console.log(`[mink] removed ${paths.unitFile}`);
@@ -8799,7 +9335,7 @@ var exports_daemon = {};
8799
9335
  __export(exports_daemon, {
8800
9336
  daemon: () => daemon
8801
9337
  });
8802
- import { readFileSync as readFileSync22, existsSync as existsSync28 } from "fs";
9338
+ import { readFileSync as readFileSync23, existsSync as existsSync32 } from "fs";
8803
9339
  async function daemon(cwd, args) {
8804
9340
  const subcommand = args[0];
8805
9341
  switch (subcommand) {
@@ -8815,12 +9351,12 @@ async function daemon(cwd, args) {
8815
9351
  break;
8816
9352
  case "logs": {
8817
9353
  const logPath = schedulerLogPath();
8818
- if (!existsSync28(logPath)) {
9354
+ if (!existsSync32(logPath)) {
8819
9355
  console.log("[mink] no log file found");
8820
9356
  return;
8821
9357
  }
8822
9358
  try {
8823
- const content = readFileSync22(logPath, "utf-8");
9359
+ const content = readFileSync23(logPath, "utf-8");
8824
9360
  const lines = content.split(`
8825
9361
  `);
8826
9362
  const tail = lines.slice(-50).join(`
@@ -9401,8 +9937,8 @@ var init_restore = __esm(() => {
9401
9937
  });
9402
9938
 
9403
9939
  // src/core/design-eval/server-detect.ts
9404
- import { readFileSync as readFileSync23 } from "fs";
9405
- import { join as join28 } from "path";
9940
+ import { readFileSync as readFileSync24 } from "fs";
9941
+ import { join as join29 } from "path";
9406
9942
  async function probePort(port) {
9407
9943
  try {
9408
9944
  const controller = new AbortController;
@@ -9424,7 +9960,7 @@ async function findRunningServer(ports = DEFAULT_PROBE_PORTS) {
9424
9960
  }
9425
9961
  function detectDevCommand(cwd) {
9426
9962
  try {
9427
- const raw = readFileSync23(join28(cwd, "package.json"), "utf-8");
9963
+ const raw = readFileSync24(join29(cwd, "package.json"), "utf-8");
9428
9964
  const pkg = JSON.parse(raw);
9429
9965
  const scripts = pkg.scripts;
9430
9966
  if (!scripts || typeof scripts !== "object")
@@ -9444,10 +9980,10 @@ var init_server_detect = __esm(() => {
9444
9980
  });
9445
9981
 
9446
9982
  // src/core/design-eval/route-detect.ts
9447
- import { existsSync as existsSync29, readdirSync as readdirSync9, statSync as statSync11 } from "fs";
9448
- import { join as join29, relative as relative8, sep as sep2 } from "path";
9983
+ import { existsSync as existsSync33, readdirSync as readdirSync9, statSync as statSync11 } from "fs";
9984
+ import { join as join30, relative as relative8, sep as sep2 } from "path";
9449
9985
  function detectFramework(cwd) {
9450
- const has = (name) => ["js", "mjs", "ts", "cjs"].some((ext) => existsSync29(join29(cwd, `${name}.${ext}`))) || existsSync29(join29(cwd, name));
9986
+ const has = (name) => ["js", "mjs", "ts", "cjs"].some((ext) => existsSync33(join30(cwd, `${name}.${ext}`))) || existsSync33(join30(cwd, name));
9451
9987
  if (has("next.config"))
9452
9988
  return "nextjs";
9453
9989
  if (has("svelte.config"))
@@ -9472,8 +10008,8 @@ function detectRoutes(cwd) {
9472
10008
  }
9473
10009
  function detectNextRoutes(cwd) {
9474
10010
  const routes = [];
9475
- const appDir = join29(cwd, "app");
9476
- if (existsSync29(appDir)) {
10011
+ const appDir = join30(cwd, "app");
10012
+ if (existsSync33(appDir)) {
9477
10013
  const pageFiles = findFiles(appDir, /^page\.(tsx?|jsx?)$/);
9478
10014
  for (const file of pageFiles) {
9479
10015
  const rel = relative8(appDir, file);
@@ -9484,8 +10020,8 @@ function detectNextRoutes(cwd) {
9484
10020
  routes.push(route);
9485
10021
  }
9486
10022
  }
9487
- const pagesDir = join29(cwd, "pages");
9488
- if (existsSync29(pagesDir)) {
10023
+ const pagesDir = join30(cwd, "pages");
10024
+ if (existsSync33(pagesDir)) {
9489
10025
  const pageFiles = findFiles(pagesDir, /\.(tsx?|jsx?)$/);
9490
10026
  for (const file of pageFiles) {
9491
10027
  const rel = relative8(pagesDir, file);
@@ -9504,8 +10040,8 @@ function detectNextRoutes(cwd) {
9504
10040
  return unique.length > 0 ? unique.sort() : ["/"];
9505
10041
  }
9506
10042
  function detectSvelteKitRoutes(cwd) {
9507
- const routesDir = join29(cwd, "src", "routes");
9508
- if (!existsSync29(routesDir))
10043
+ const routesDir = join30(cwd, "src", "routes");
10044
+ if (!existsSync33(routesDir))
9509
10045
  return ["/"];
9510
10046
  const routes = [];
9511
10047
  const pageFiles = findFiles(routesDir, /^\+page\.svelte$/);
@@ -9520,8 +10056,8 @@ function detectSvelteKitRoutes(cwd) {
9520
10056
  return routes.length > 0 ? routes.sort() : ["/"];
9521
10057
  }
9522
10058
  function detectNuxtRoutes(cwd) {
9523
- const pagesDir = join29(cwd, "pages");
9524
- if (!existsSync29(pagesDir))
10059
+ const pagesDir = join30(cwd, "pages");
10060
+ if (!existsSync33(pagesDir))
9525
10061
  return ["/"];
9526
10062
  const routes = [];
9527
10063
  const vueFiles = findFiles(pagesDir, /\.vue$/);
@@ -9547,7 +10083,7 @@ function findFiles(dir, pattern) {
9547
10083
  for (const entry of entries) {
9548
10084
  if (entry.startsWith(".") || entry === "node_modules")
9549
10085
  continue;
9550
- const full = join29(current, entry);
10086
+ const full = join30(current, entry);
9551
10087
  try {
9552
10088
  const stat2 = statSync11(full);
9553
10089
  if (stat2.isDirectory()) {
@@ -58251,7 +58787,7 @@ var require_util2 = __commonJS((exports) => {
58251
58787
  return path;
58252
58788
  }
58253
58789
  exports.normalize = normalize2;
58254
- function join30(aRoot, aPath) {
58790
+ function join31(aRoot, aPath) {
58255
58791
  if (aRoot === "") {
58256
58792
  aRoot = ".";
58257
58793
  }
@@ -58283,7 +58819,7 @@ var require_util2 = __commonJS((exports) => {
58283
58819
  }
58284
58820
  return joined;
58285
58821
  }
58286
- exports.join = join30;
58822
+ exports.join = join31;
58287
58823
  exports.isAbsolute = function(aPath) {
58288
58824
  return aPath.charAt(0) === "/" || urlRegexp.test(aPath);
58289
58825
  };
@@ -58456,7 +58992,7 @@ var require_util2 = __commonJS((exports) => {
58456
58992
  parsed.path = parsed.path.substring(0, index + 1);
58457
58993
  }
58458
58994
  }
58459
- sourceURL = join30(urlGenerate(parsed), sourceURL);
58995
+ sourceURL = join31(urlGenerate(parsed), sourceURL);
58460
58996
  }
58461
58997
  return normalize2(sourceURL);
58462
58998
  }
@@ -60188,7 +60724,7 @@ var require_escodegen = __commonJS((exports) => {
60188
60724
  function noEmptySpace() {
60189
60725
  return space ? space : " ";
60190
60726
  }
60191
- function join30(left, right) {
60727
+ function join31(left, right) {
60192
60728
  var leftSource, rightSource, leftCharCode, rightCharCode;
60193
60729
  leftSource = toSourceNodeWhenNeeded(left).toString();
60194
60730
  if (leftSource.length === 0) {
@@ -60529,8 +61065,8 @@ var require_escodegen = __commonJS((exports) => {
60529
61065
  } else {
60530
61066
  result.push(that.generateExpression(stmt.left, Precedence.Call, E_TTT));
60531
61067
  }
60532
- result = join30(result, operator);
60533
- result = [join30(result, that.generateExpression(stmt.right, Precedence.Assignment, E_TTT)), ")"];
61068
+ result = join31(result, operator);
61069
+ result = [join31(result, that.generateExpression(stmt.right, Precedence.Assignment, E_TTT)), ")"];
60534
61070
  });
60535
61071
  result.push(this.maybeBlock(stmt.body, flags));
60536
61072
  return result;
@@ -60668,11 +61204,11 @@ var require_escodegen = __commonJS((exports) => {
60668
61204
  var result, fragment;
60669
61205
  result = ["class"];
60670
61206
  if (stmt.id) {
60671
- result = join30(result, this.generateExpression(stmt.id, Precedence.Sequence, E_TTT));
61207
+ result = join31(result, this.generateExpression(stmt.id, Precedence.Sequence, E_TTT));
60672
61208
  }
60673
61209
  if (stmt.superClass) {
60674
- fragment = join30("extends", this.generateExpression(stmt.superClass, Precedence.Unary, E_TTT));
60675
- result = join30(result, fragment);
61210
+ fragment = join31("extends", this.generateExpression(stmt.superClass, Precedence.Unary, E_TTT));
61211
+ result = join31(result, fragment);
60676
61212
  }
60677
61213
  result.push(space);
60678
61214
  result.push(this.generateStatement(stmt.body, S_TFFT));
@@ -60685,9 +61221,9 @@ var require_escodegen = __commonJS((exports) => {
60685
61221
  return escapeDirective(stmt.directive) + this.semicolon(flags);
60686
61222
  },
60687
61223
  DoWhileStatement: function(stmt, flags) {
60688
- var result = join30("do", this.maybeBlock(stmt.body, S_TFFF));
61224
+ var result = join31("do", this.maybeBlock(stmt.body, S_TFFF));
60689
61225
  result = this.maybeBlockSuffix(stmt.body, result);
60690
- return join30(result, [
61226
+ return join31(result, [
60691
61227
  "while" + space + "(",
60692
61228
  this.generateExpression(stmt.test, Precedence.Sequence, E_TTT),
60693
61229
  ")" + this.semicolon(flags)
@@ -60723,11 +61259,11 @@ var require_escodegen = __commonJS((exports) => {
60723
61259
  ExportDefaultDeclaration: function(stmt, flags) {
60724
61260
  var result = ["export"], bodyFlags;
60725
61261
  bodyFlags = flags & F_SEMICOLON_OPT ? S_TFFT : S_TFFF;
60726
- result = join30(result, "default");
61262
+ result = join31(result, "default");
60727
61263
  if (isStatement(stmt.declaration)) {
60728
- result = join30(result, this.generateStatement(stmt.declaration, bodyFlags));
61264
+ result = join31(result, this.generateStatement(stmt.declaration, bodyFlags));
60729
61265
  } else {
60730
- result = join30(result, this.generateExpression(stmt.declaration, Precedence.Assignment, E_TTT) + this.semicolon(flags));
61266
+ result = join31(result, this.generateExpression(stmt.declaration, Precedence.Assignment, E_TTT) + this.semicolon(flags));
60731
61267
  }
60732
61268
  return result;
60733
61269
  },
@@ -60735,15 +61271,15 @@ var require_escodegen = __commonJS((exports) => {
60735
61271
  var result = ["export"], bodyFlags, that = this;
60736
61272
  bodyFlags = flags & F_SEMICOLON_OPT ? S_TFFT : S_TFFF;
60737
61273
  if (stmt.declaration) {
60738
- return join30(result, this.generateStatement(stmt.declaration, bodyFlags));
61274
+ return join31(result, this.generateStatement(stmt.declaration, bodyFlags));
60739
61275
  }
60740
61276
  if (stmt.specifiers) {
60741
61277
  if (stmt.specifiers.length === 0) {
60742
- result = join30(result, "{" + space + "}");
61278
+ result = join31(result, "{" + space + "}");
60743
61279
  } else if (stmt.specifiers[0].type === Syntax.ExportBatchSpecifier) {
60744
- result = join30(result, this.generateExpression(stmt.specifiers[0], Precedence.Sequence, E_TTT));
61280
+ result = join31(result, this.generateExpression(stmt.specifiers[0], Precedence.Sequence, E_TTT));
60745
61281
  } else {
60746
- result = join30(result, "{");
61282
+ result = join31(result, "{");
60747
61283
  withIndent(function(indent2) {
60748
61284
  var i, iz;
60749
61285
  result.push(newline);
@@ -60761,7 +61297,7 @@ var require_escodegen = __commonJS((exports) => {
60761
61297
  result.push(base + "}");
60762
61298
  }
60763
61299
  if (stmt.source) {
60764
- result = join30(result, [
61300
+ result = join31(result, [
60765
61301
  "from" + space,
60766
61302
  this.generateExpression(stmt.source, Precedence.Sequence, E_TTT),
60767
61303
  this.semicolon(flags)
@@ -60845,7 +61381,7 @@ var require_escodegen = __commonJS((exports) => {
60845
61381
  ];
60846
61382
  cursor = 0;
60847
61383
  if (stmt.specifiers[cursor].type === Syntax.ImportDefaultSpecifier) {
60848
- result = join30(result, [
61384
+ result = join31(result, [
60849
61385
  this.generateExpression(stmt.specifiers[cursor], Precedence.Sequence, E_TTT)
60850
61386
  ]);
60851
61387
  ++cursor;
@@ -60855,7 +61391,7 @@ var require_escodegen = __commonJS((exports) => {
60855
61391
  result.push(",");
60856
61392
  }
60857
61393
  if (stmt.specifiers[cursor].type === Syntax.ImportNamespaceSpecifier) {
60858
- result = join30(result, [
61394
+ result = join31(result, [
60859
61395
  space,
60860
61396
  this.generateExpression(stmt.specifiers[cursor], Precedence.Sequence, E_TTT)
60861
61397
  ]);
@@ -60884,7 +61420,7 @@ var require_escodegen = __commonJS((exports) => {
60884
61420
  }
60885
61421
  }
60886
61422
  }
60887
- result = join30(result, [
61423
+ result = join31(result, [
60888
61424
  "from" + space,
60889
61425
  this.generateExpression(stmt.source, Precedence.Sequence, E_TTT),
60890
61426
  this.semicolon(flags)
@@ -60938,7 +61474,7 @@ var require_escodegen = __commonJS((exports) => {
60938
61474
  return result;
60939
61475
  },
60940
61476
  ThrowStatement: function(stmt, flags) {
60941
- return [join30("throw", this.generateExpression(stmt.argument, Precedence.Sequence, E_TTT)), this.semicolon(flags)];
61477
+ return [join31("throw", this.generateExpression(stmt.argument, Precedence.Sequence, E_TTT)), this.semicolon(flags)];
60942
61478
  },
60943
61479
  TryStatement: function(stmt, flags) {
60944
61480
  var result, i, iz, guardedHandlers;
@@ -60946,7 +61482,7 @@ var require_escodegen = __commonJS((exports) => {
60946
61482
  result = this.maybeBlockSuffix(stmt.block, result);
60947
61483
  if (stmt.handlers) {
60948
61484
  for (i = 0, iz = stmt.handlers.length;i < iz; ++i) {
60949
- result = join30(result, this.generateStatement(stmt.handlers[i], S_TFFF));
61485
+ result = join31(result, this.generateStatement(stmt.handlers[i], S_TFFF));
60950
61486
  if (stmt.finalizer || i + 1 !== iz) {
60951
61487
  result = this.maybeBlockSuffix(stmt.handlers[i].body, result);
60952
61488
  }
@@ -60954,7 +61490,7 @@ var require_escodegen = __commonJS((exports) => {
60954
61490
  } else {
60955
61491
  guardedHandlers = stmt.guardedHandlers || [];
60956
61492
  for (i = 0, iz = guardedHandlers.length;i < iz; ++i) {
60957
- result = join30(result, this.generateStatement(guardedHandlers[i], S_TFFF));
61493
+ result = join31(result, this.generateStatement(guardedHandlers[i], S_TFFF));
60958
61494
  if (stmt.finalizer || i + 1 !== iz) {
60959
61495
  result = this.maybeBlockSuffix(guardedHandlers[i].body, result);
60960
61496
  }
@@ -60962,13 +61498,13 @@ var require_escodegen = __commonJS((exports) => {
60962
61498
  if (stmt.handler) {
60963
61499
  if (Array.isArray(stmt.handler)) {
60964
61500
  for (i = 0, iz = stmt.handler.length;i < iz; ++i) {
60965
- result = join30(result, this.generateStatement(stmt.handler[i], S_TFFF));
61501
+ result = join31(result, this.generateStatement(stmt.handler[i], S_TFFF));
60966
61502
  if (stmt.finalizer || i + 1 !== iz) {
60967
61503
  result = this.maybeBlockSuffix(stmt.handler[i].body, result);
60968
61504
  }
60969
61505
  }
60970
61506
  } else {
60971
- result = join30(result, this.generateStatement(stmt.handler, S_TFFF));
61507
+ result = join31(result, this.generateStatement(stmt.handler, S_TFFF));
60972
61508
  if (stmt.finalizer) {
60973
61509
  result = this.maybeBlockSuffix(stmt.handler.body, result);
60974
61510
  }
@@ -60976,7 +61512,7 @@ var require_escodegen = __commonJS((exports) => {
60976
61512
  }
60977
61513
  }
60978
61514
  if (stmt.finalizer) {
60979
- result = join30(result, ["finally", this.maybeBlock(stmt.finalizer, S_TFFF)]);
61515
+ result = join31(result, ["finally", this.maybeBlock(stmt.finalizer, S_TFFF)]);
60980
61516
  }
60981
61517
  return result;
60982
61518
  },
@@ -61010,7 +61546,7 @@ var require_escodegen = __commonJS((exports) => {
61010
61546
  withIndent(function() {
61011
61547
  if (stmt.test) {
61012
61548
  result = [
61013
- join30("case", that.generateExpression(stmt.test, Precedence.Sequence, E_TTT)),
61549
+ join31("case", that.generateExpression(stmt.test, Precedence.Sequence, E_TTT)),
61014
61550
  ":"
61015
61551
  ];
61016
61552
  } else {
@@ -61058,9 +61594,9 @@ var require_escodegen = __commonJS((exports) => {
61058
61594
  result.push(this.maybeBlock(stmt.consequent, S_TFFF));
61059
61595
  result = this.maybeBlockSuffix(stmt.consequent, result);
61060
61596
  if (stmt.alternate.type === Syntax.IfStatement) {
61061
- result = join30(result, ["else ", this.generateStatement(stmt.alternate, bodyFlags)]);
61597
+ result = join31(result, ["else ", this.generateStatement(stmt.alternate, bodyFlags)]);
61062
61598
  } else {
61063
- result = join30(result, join30("else", this.maybeBlock(stmt.alternate, bodyFlags)));
61599
+ result = join31(result, join31("else", this.maybeBlock(stmt.alternate, bodyFlags)));
61064
61600
  }
61065
61601
  } else {
61066
61602
  result.push(this.maybeBlock(stmt.consequent, bodyFlags));
@@ -61162,7 +61698,7 @@ var require_escodegen = __commonJS((exports) => {
61162
61698
  },
61163
61699
  ReturnStatement: function(stmt, flags) {
61164
61700
  if (stmt.argument) {
61165
- return [join30("return", this.generateExpression(stmt.argument, Precedence.Sequence, E_TTT)), this.semicolon(flags)];
61701
+ return [join31("return", this.generateExpression(stmt.argument, Precedence.Sequence, E_TTT)), this.semicolon(flags)];
61166
61702
  }
61167
61703
  return ["return" + this.semicolon(flags)];
61168
61704
  },
@@ -61244,14 +61780,14 @@ var require_escodegen = __commonJS((exports) => {
61244
61780
  if (leftSource.charCodeAt(leftSource.length - 1) === 47 && esutils.code.isIdentifierPartES5(expr.operator.charCodeAt(0))) {
61245
61781
  result = [fragment, noEmptySpace(), expr.operator];
61246
61782
  } else {
61247
- result = join30(fragment, expr.operator);
61783
+ result = join31(fragment, expr.operator);
61248
61784
  }
61249
61785
  fragment = this.generateExpression(expr.right, rightPrecedence, flags);
61250
61786
  if (expr.operator === "/" && fragment.toString().charAt(0) === "/" || expr.operator.slice(-1) === "<" && fragment.toString().slice(0, 3) === "!--") {
61251
61787
  result.push(noEmptySpace());
61252
61788
  result.push(fragment);
61253
61789
  } else {
61254
- result = join30(result, fragment);
61790
+ result = join31(result, fragment);
61255
61791
  }
61256
61792
  if (expr.operator === "in" && !(flags & F_ALLOW_IN)) {
61257
61793
  return ["(", result, ")"];
@@ -61291,7 +61827,7 @@ var require_escodegen = __commonJS((exports) => {
61291
61827
  var result, length, i, iz, itemFlags;
61292
61828
  length = expr["arguments"].length;
61293
61829
  itemFlags = flags & F_ALLOW_UNPARATH_NEW && !parentheses && length === 0 ? E_TFT : E_TFF;
61294
- result = join30("new", this.generateExpression(expr.callee, Precedence.New, itemFlags));
61830
+ result = join31("new", this.generateExpression(expr.callee, Precedence.New, itemFlags));
61295
61831
  if (!(flags & F_ALLOW_UNPARATH_NEW) || parentheses || length > 0) {
61296
61832
  result.push("(");
61297
61833
  for (i = 0, iz = length;i < iz; ++i) {
@@ -61338,11 +61874,11 @@ var require_escodegen = __commonJS((exports) => {
61338
61874
  var result, fragment, rightCharCode, leftSource, leftCharCode;
61339
61875
  fragment = this.generateExpression(expr.argument, Precedence.Unary, E_TTT);
61340
61876
  if (space === "") {
61341
- result = join30(expr.operator, fragment);
61877
+ result = join31(expr.operator, fragment);
61342
61878
  } else {
61343
61879
  result = [expr.operator];
61344
61880
  if (expr.operator.length > 2) {
61345
- result = join30(result, fragment);
61881
+ result = join31(result, fragment);
61346
61882
  } else {
61347
61883
  leftSource = toSourceNodeWhenNeeded(result).toString();
61348
61884
  leftCharCode = leftSource.charCodeAt(leftSource.length - 1);
@@ -61365,12 +61901,12 @@ var require_escodegen = __commonJS((exports) => {
61365
61901
  result = "yield";
61366
61902
  }
61367
61903
  if (expr.argument) {
61368
- result = join30(result, this.generateExpression(expr.argument, Precedence.Yield, E_TTT));
61904
+ result = join31(result, this.generateExpression(expr.argument, Precedence.Yield, E_TTT));
61369
61905
  }
61370
61906
  return parenthesize(result, Precedence.Yield, precedence);
61371
61907
  },
61372
61908
  AwaitExpression: function(expr, precedence, flags) {
61373
- var result = join30(expr.all ? "await*" : "await", this.generateExpression(expr.argument, Precedence.Await, E_TTT));
61909
+ var result = join31(expr.all ? "await*" : "await", this.generateExpression(expr.argument, Precedence.Await, E_TTT));
61374
61910
  return parenthesize(result, Precedence.Await, precedence);
61375
61911
  },
61376
61912
  UpdateExpression: function(expr, precedence, flags) {
@@ -61442,11 +61978,11 @@ var require_escodegen = __commonJS((exports) => {
61442
61978
  var result, fragment;
61443
61979
  result = ["class"];
61444
61980
  if (expr.id) {
61445
- result = join30(result, this.generateExpression(expr.id, Precedence.Sequence, E_TTT));
61981
+ result = join31(result, this.generateExpression(expr.id, Precedence.Sequence, E_TTT));
61446
61982
  }
61447
61983
  if (expr.superClass) {
61448
- fragment = join30("extends", this.generateExpression(expr.superClass, Precedence.Unary, E_TTT));
61449
- result = join30(result, fragment);
61984
+ fragment = join31("extends", this.generateExpression(expr.superClass, Precedence.Unary, E_TTT));
61985
+ result = join31(result, fragment);
61450
61986
  }
61451
61987
  result.push(space);
61452
61988
  result.push(this.generateStatement(expr.body, S_TFFT));
@@ -61461,7 +61997,7 @@ var require_escodegen = __commonJS((exports) => {
61461
61997
  }
61462
61998
  if (expr.kind === "get" || expr.kind === "set") {
61463
61999
  fragment = [
61464
- join30(expr.kind, this.generatePropertyKey(expr.key, expr.computed)),
62000
+ join31(expr.kind, this.generatePropertyKey(expr.key, expr.computed)),
61465
62001
  this.generateFunctionBody(expr.value)
61466
62002
  ];
61467
62003
  } else {
@@ -61471,7 +62007,7 @@ var require_escodegen = __commonJS((exports) => {
61471
62007
  this.generateFunctionBody(expr.value)
61472
62008
  ];
61473
62009
  }
61474
- return join30(result, fragment);
62010
+ return join31(result, fragment);
61475
62011
  },
61476
62012
  Property: function(expr, precedence, flags) {
61477
62013
  if (expr.kind === "get" || expr.kind === "set") {
@@ -61665,7 +62201,7 @@ var require_escodegen = __commonJS((exports) => {
61665
62201
  for (i = 0, iz = expr.blocks.length;i < iz; ++i) {
61666
62202
  fragment = that.generateExpression(expr.blocks[i], Precedence.Sequence, E_TTT);
61667
62203
  if (i > 0 || extra.moz.comprehensionExpressionStartsWithAssignment) {
61668
- result = join30(result, fragment);
62204
+ result = join31(result, fragment);
61669
62205
  } else {
61670
62206
  result.push(fragment);
61671
62207
  }
@@ -61673,13 +62209,13 @@ var require_escodegen = __commonJS((exports) => {
61673
62209
  });
61674
62210
  }
61675
62211
  if (expr.filter) {
61676
- result = join30(result, "if" + space);
62212
+ result = join31(result, "if" + space);
61677
62213
  fragment = this.generateExpression(expr.filter, Precedence.Sequence, E_TTT);
61678
- result = join30(result, ["(", fragment, ")"]);
62214
+ result = join31(result, ["(", fragment, ")"]);
61679
62215
  }
61680
62216
  if (!extra.moz.comprehensionExpressionStartsWithAssignment) {
61681
62217
  fragment = this.generateExpression(expr.body, Precedence.Assignment, E_TTT);
61682
- result = join30(result, fragment);
62218
+ result = join31(result, fragment);
61683
62219
  }
61684
62220
  result.push(expr.type === Syntax.GeneratorExpression ? ")" : "]");
61685
62221
  return result;
@@ -61695,8 +62231,8 @@ var require_escodegen = __commonJS((exports) => {
61695
62231
  } else {
61696
62232
  fragment = this.generateExpression(expr.left, Precedence.Call, E_TTT);
61697
62233
  }
61698
- fragment = join30(fragment, expr.of ? "of" : "in");
61699
- fragment = join30(fragment, this.generateExpression(expr.right, Precedence.Sequence, E_TTT));
62234
+ fragment = join31(fragment, expr.of ? "of" : "in");
62235
+ fragment = join31(fragment, this.generateExpression(expr.right, Precedence.Sequence, E_TTT));
61700
62236
  return ["for" + space + "(", fragment, ")"];
61701
62237
  },
61702
62238
  SpreadElement: function(expr, precedence, flags) {
@@ -75401,7 +75937,7 @@ var init_httpUtil = __esm(() => {
75401
75937
  });
75402
75938
 
75403
75939
  // node_modules/@puppeteer/browsers/lib/esm/browser-data/chrome.js
75404
- import { execSync as execSync7 } from "node:child_process";
75940
+ import { execSync as execSync8 } from "node:child_process";
75405
75941
  import os from "node:os";
75406
75942
  import path from "node:path";
75407
75943
  function folder(platform2) {
@@ -75491,7 +76027,7 @@ function getChromeWindowsLocation(channel2, locationsPrefixes) {
75491
76027
  }
75492
76028
  function getWslVariable(variable) {
75493
76029
  try {
75494
- const result = execSync7(`cmd.exe /c echo %${variable.toLocaleUpperCase()}%`, {
76030
+ const result = execSync8(`cmd.exe /c echo %${variable.toLocaleUpperCase()}%`, {
75495
76031
  stdio: ["ignore", "pipe", "ignore"],
75496
76032
  encoding: "utf-8"
75497
76033
  }).trim();
@@ -75502,7 +76038,7 @@ function getWslVariable(variable) {
75502
76038
  return;
75503
76039
  }
75504
76040
  function getWslLocation(channel2) {
75505
- const wslVersion = execSync7("wslinfo --version", {
76041
+ const wslVersion = execSync8("wslinfo --version", {
75506
76042
  stdio: ["ignore", "pipe", "ignore"],
75507
76043
  encoding: "utf-8"
75508
76044
  }).trim();
@@ -75518,7 +76054,7 @@ function getWslLocation(channel2) {
75518
76054
  }
75519
76055
  const windowsPath = getChromeWindowsLocation(channel2, wslPrefixes);
75520
76056
  return windowsPath.map((path2) => {
75521
- return execSync7(`wslpath "${path2}"`).toString().trim();
76057
+ return execSync8(`wslpath "${path2}"`).toString().trim();
75522
76058
  });
75523
76059
  }
75524
76060
  function getChromeLinuxOrWslLocation(channel2) {
@@ -81793,7 +82329,7 @@ var init_fileUtil = __esm(() => {
81793
82329
  // node_modules/@puppeteer/browsers/lib/esm/install.js
81794
82330
  import assert2 from "node:assert";
81795
82331
  import { spawnSync as spawnSync4 } from "node:child_process";
81796
- import { existsSync as existsSync30, readFileSync as readFileSync24 } from "node:fs";
82332
+ import { existsSync as existsSync34, readFileSync as readFileSync25 } from "node:fs";
81797
82333
  import { mkdir as mkdir2, unlink } from "node:fs/promises";
81798
82334
  import os5 from "node:os";
81799
82335
  import path8 from "node:path";
@@ -81846,7 +82382,7 @@ async function installWithProviders(options) {
81846
82382
  continue;
81847
82383
  }
81848
82384
  debugInstall(`Successfully got URL from ${provider.getName()}: ${url}`);
81849
- if (!existsSync30(browserRoot)) {
82385
+ if (!existsSync34(browserRoot)) {
81850
82386
  await mkdir2(browserRoot, { recursive: true });
81851
82387
  }
81852
82388
  return await installUrl(url, options, provider);
@@ -81879,11 +82415,11 @@ async function installDeps(installedBrowser) {
81879
82415
  return;
81880
82416
  }
81881
82417
  const depsPath = path8.join(path8.dirname(installedBrowser.executablePath), "deb.deps");
81882
- if (!existsSync30(depsPath)) {
82418
+ if (!existsSync34(depsPath)) {
81883
82419
  debugInstall(`deb.deps file was not found at ${depsPath}`);
81884
82420
  return;
81885
82421
  }
81886
- const data = readFileSync24(depsPath, "utf-8").split(`
82422
+ const data = readFileSync25(depsPath, "utf-8").split(`
81887
82423
  `).join(",");
81888
82424
  if (process.getuid?.() !== 0) {
81889
82425
  throw new Error("Installing system dependencies requires root privileges");
@@ -81921,11 +82457,11 @@ async function installUrl(url, options, provider) {
81921
82457
  const cache = new Cache(options.cacheDir);
81922
82458
  const browserRoot = cache.browserRoot(options.browser);
81923
82459
  const archivePath = path8.join(browserRoot, `${options.buildId}-${fileName}`);
81924
- if (!existsSync30(browserRoot)) {
82460
+ if (!existsSync34(browserRoot)) {
81925
82461
  await mkdir2(browserRoot, { recursive: true });
81926
82462
  }
81927
82463
  if (!options.unpack) {
81928
- if (existsSync30(archivePath)) {
82464
+ if (existsSync34(archivePath)) {
81929
82465
  return archivePath;
81930
82466
  }
81931
82467
  debugInstall(`Downloading binary from ${url}`);
@@ -81946,8 +82482,8 @@ async function installUrl(url, options, provider) {
81946
82482
  cache.writeExecutablePath(options.browser, options.platform, options.buildId, relativeExecutablePath6);
81947
82483
  }
81948
82484
  try {
81949
- if (existsSync30(outputPath)) {
81950
- if (!existsSync30(installedBrowser.executablePath)) {
82485
+ if (existsSync34(outputPath)) {
82486
+ if (!existsSync34(installedBrowser.executablePath)) {
81951
82487
  throw new Error(`The browser folder (${outputPath}) exists but the executable (${installedBrowser.executablePath}) is missing`);
81952
82488
  }
81953
82489
  await runSetup(installedBrowser);
@@ -81956,7 +82492,7 @@ async function installUrl(url, options, provider) {
81956
82492
  }
81957
82493
  return installedBrowser;
81958
82494
  }
81959
- if (!existsSync30(archivePath)) {
82495
+ if (!existsSync34(archivePath)) {
81960
82496
  debugInstall(`Downloading binary from ${url}`);
81961
82497
  try {
81962
82498
  debugTime("download");
@@ -81985,7 +82521,7 @@ async function installUrl(url, options, provider) {
81985
82521
  }
81986
82522
  return installedBrowser;
81987
82523
  } finally {
81988
- if (existsSync30(archivePath)) {
82524
+ if (existsSync34(archivePath)) {
81989
82525
  await unlink(archivePath);
81990
82526
  }
81991
82527
  }
@@ -81996,7 +82532,7 @@ async function runSetup(installedBrowser) {
81996
82532
  debugTime("permissions");
81997
82533
  const browserDir = path8.dirname(installedBrowser.executablePath);
81998
82534
  const setupExePath = path8.join(browserDir, "setup.exe");
81999
- if (!existsSync30(setupExePath)) {
82535
+ if (!existsSync34(setupExePath)) {
82000
82536
  return;
82001
82537
  }
82002
82538
  spawnSync4(path8.join(browserDir, "setup.exe"), [`--configure-browser-in-directory=` + browserDir], {
@@ -83408,14 +83944,14 @@ var init_yerror = __esm(() => {
83408
83944
  });
83409
83945
 
83410
83946
  // node_modules/y18n/build/lib/platform-shims/node.js
83411
- import { readFileSync as readFileSync25, statSync as statSync13, writeFile } from "fs";
83947
+ import { readFileSync as readFileSync26, statSync as statSync13, writeFile } from "fs";
83412
83948
  import { format as format2 } from "util";
83413
83949
  import { resolve as resolve12 } from "path";
83414
83950
  var node_default;
83415
83951
  var init_node = __esm(() => {
83416
83952
  node_default = {
83417
83953
  fs: {
83418
- readFileSync: readFileSync25,
83954
+ readFileSync: readFileSync26,
83419
83955
  writeFile
83420
83956
  },
83421
83957
  format: format2,
@@ -83600,7 +84136,7 @@ var init_y18n = __esm(() => {
83600
84136
  // node_modules/yargs/lib/platform-shims/esm.mjs
83601
84137
  import { notStrictEqual, strictEqual } from "assert";
83602
84138
  import { inspect } from "util";
83603
- import { readFileSync as readFileSync26 } from "fs";
84139
+ import { readFileSync as readFileSync27 } from "fs";
83604
84140
  import { fileURLToPath } from "url";
83605
84141
  import { basename as basename9, dirname as dirname14, extname as extname3, relative as relative9, resolve as resolve13 } from "path";
83606
84142
  var REQUIRE_ERROR = "require is not supported by ESM", REQUIRE_DIRECTORY_ERROR = "loading a directory of commands is not supported yet for ESM", __dirname2, mainFilename, esm_default;
@@ -83649,7 +84185,7 @@ var init_esm = __esm(() => {
83649
84185
  nextTick: process.nextTick,
83650
84186
  stdColumns: typeof process.stdout.columns !== "undefined" ? process.stdout.columns : null
83651
84187
  },
83652
- readFileSync: readFileSync26,
84188
+ readFileSync: readFileSync27,
83653
84189
  require: () => {
83654
84190
  throw new YError(REQUIRE_ERROR);
83655
84191
  },
@@ -87348,9 +87884,9 @@ async function getConnectionTransport(options) {
87348
87884
  throw new Error("Could not detect required browser platform");
87349
87885
  }
87350
87886
  const { convertPuppeteerChannelToBrowsersChannel: convertPuppeteerChannelToBrowsersChannel2 } = await Promise.resolve().then(() => (init_LaunchOptions(), exports_LaunchOptions));
87351
- const { join: join31 } = await import("node:path");
87887
+ const { join: join32 } = await import("node:path");
87352
87888
  const userDataDir = resolveDefaultUserDataDir3(Browser7.CHROME, platform2, convertPuppeteerChannelToBrowsersChannel2(options.channel));
87353
- const portPath = join31(userDataDir, "DevToolsActivePort");
87889
+ const portPath = join32(userDataDir, "DevToolsActivePort");
87354
87890
  try {
87355
87891
  const fileContent = await environment.value.fs.promises.readFile(portPath, "ascii");
87356
87892
  const [rawPort, rawPath] = fileContent.split(`
@@ -87574,9 +88110,9 @@ var init_PipeTransport = __esm(() => {
87574
88110
  });
87575
88111
 
87576
88112
  // node_modules/puppeteer-core/lib/esm/puppeteer/node/BrowserLauncher.js
87577
- import { existsSync as existsSync31 } from "node:fs";
88113
+ import { existsSync as existsSync35 } from "node:fs";
87578
88114
  import { tmpdir } from "node:os";
87579
- import { join as join31 } from "node:path";
88115
+ import { join as join32 } from "node:path";
87580
88116
 
87581
88117
  class BrowserLauncher {
87582
88118
  #browser;
@@ -87601,7 +88137,7 @@ class BrowserLauncher {
87601
88137
  ...options,
87602
88138
  protocol
87603
88139
  });
87604
- if (!existsSync31(launchArgs.executablePath)) {
88140
+ if (!existsSync35(launchArgs.executablePath)) {
87605
88141
  throw new Error(`Browser was not found at the configured executablePath (${launchArgs.executablePath})`);
87606
88142
  }
87607
88143
  const usePipe = launchArgs.args.includes("--remote-debugging-pipe");
@@ -87676,7 +88212,7 @@ class BrowserLauncher {
87676
88212
  browserCloseCallback();
87677
88213
  const logs = browserProcess.getRecentLogs().join(`
87678
88214
  `);
87679
- if (logs.includes("Failed to create a ProcessSingleton for your profile directory") || process.platform === "win32" && existsSync31(join31(launchArgs.userDataDir, "lockfile"))) {
88215
+ if (logs.includes("Failed to create a ProcessSingleton for your profile directory") || process.platform === "win32" && existsSync35(join32(launchArgs.userDataDir, "lockfile"))) {
87680
88216
  throw new Error(`The browser is already running for ${launchArgs.userDataDir}. Use a different \`userDataDir\` or stop the running browser first.`);
87681
88217
  }
87682
88218
  if (logs.includes("Missing X server") && options.headless === false) {
@@ -87766,12 +88302,12 @@ class BrowserLauncher {
87766
88302
  });
87767
88303
  }
87768
88304
  getProfilePath() {
87769
- return join31(this.puppeteer.configuration.temporaryDirectory ?? tmpdir(), `puppeteer_dev_${this.browser}_profile-`);
88305
+ return join32(this.puppeteer.configuration.temporaryDirectory ?? tmpdir(), `puppeteer_dev_${this.browser}_profile-`);
87770
88306
  }
87771
88307
  resolveExecutablePath(headless, validatePath = true) {
87772
88308
  let executablePath = this.puppeteer.configuration.executablePath;
87773
88309
  if (executablePath) {
87774
- if (validatePath && !existsSync31(executablePath)) {
88310
+ if (validatePath && !existsSync35(executablePath)) {
87775
88311
  throw new Error(`Tried to find the browser at the configured path (${executablePath}), but no executable was found.`);
87776
88312
  }
87777
88313
  return executablePath;
@@ -87794,7 +88330,7 @@ class BrowserLauncher {
87794
88330
  browser: browserType,
87795
88331
  buildId: this.puppeteer.browserVersion
87796
88332
  });
87797
- if (validatePath && !existsSync31(executablePath)) {
88333
+ if (validatePath && !existsSync35(executablePath)) {
87798
88334
  const configVersion = this.puppeteer.configuration?.[this.browser]?.version;
87799
88335
  if (configVersion) {
87800
88336
  throw new Error(`Tried to find the browser at the configured path (${executablePath}) for version ${configVersion}, but no executable was found.`);
@@ -88609,17 +89145,17 @@ var init_puppeteer_core = __esm(() => {
88609
89145
  });
88610
89146
 
88611
89147
  // src/core/design-eval/capture.ts
88612
- import { mkdirSync as mkdirSync14, statSync as statSync14, existsSync as existsSync32 } from "fs";
88613
- import { join as join32 } from "path";
89148
+ import { mkdirSync as mkdirSync14, statSync as statSync14, existsSync as existsSync36 } from "fs";
89149
+ import { join as join33 } from "path";
88614
89150
  function findBrowser() {
88615
89151
  const platform2 = process.platform;
88616
89152
  const paths = CHROME_PATHS[platform2] ?? [];
88617
89153
  for (const p of paths) {
88618
- if (existsSync32(p))
89154
+ if (existsSync36(p))
88619
89155
  return p;
88620
89156
  }
88621
- const minkBrowsers = join32(minkRoot(), "browsers");
88622
- if (existsSync32(minkBrowsers)) {
89157
+ const minkBrowsers = join33(minkRoot(), "browsers");
89158
+ if (existsSync36(minkBrowsers)) {
88623
89159
  const found = findChromeInDir(minkBrowsers);
88624
89160
  if (found)
88625
89161
  return found;
@@ -88640,7 +89176,7 @@ function findChromeInDir(dir) {
88640
89176
  try {
88641
89177
  const entries = readdirSync11(dir);
88642
89178
  for (const entry of entries) {
88643
- const full = join32(dir, entry);
89179
+ const full = join33(dir, entry);
88644
89180
  try {
88645
89181
  const stat2 = statSync15(full);
88646
89182
  if (stat2.isDirectory()) {
@@ -88688,7 +89224,7 @@ async function captureRoute(page, route, baseUrl, viewport, options) {
88688
89224
  const y = section * viewport.height;
88689
89225
  const clipHeight = Math.min(viewport.height, pageHeight - y);
88690
89226
  const fileName = `${prefix}-${viewport.name}-${section}.jpg`;
88691
- const filePath = join32(options.outputDir, fileName);
89227
+ const filePath = join33(options.outputDir, fileName);
88692
89228
  await page.screenshot({
88693
89229
  path: filePath,
88694
89230
  type: "jpeg",
@@ -90152,7 +90688,7 @@ var exports_wiki = {};
90152
90688
  __export(exports_wiki, {
90153
90689
  wiki: () => wiki
90154
90690
  });
90155
- import { existsSync as existsSync33, statSync as statSync15 } from "fs";
90691
+ import { existsSync as existsSync37, statSync as statSync15 } from "fs";
90156
90692
  import { resolve as resolve14 } from "path";
90157
90693
  import { homedir as homedir5 } from "os";
90158
90694
  async function wiki(_cwd, args) {
@@ -90210,7 +90746,7 @@ async function wikiInit(args) {
90210
90746
  console.log(`[mink] initializing vault at ${targetPath}`);
90211
90747
  console.log(" (set a custom path with: mink wiki init /path/to/vault)");
90212
90748
  }
90213
- const isExisting = existsSync33(targetPath) && statSync15(targetPath).isDirectory();
90749
+ const isExisting = existsSync37(targetPath) && statSync15(targetPath).isDirectory();
90214
90750
  setConfigValue("wiki.path", targetPath);
90215
90751
  ensureVaultStructure();
90216
90752
  seedTemplates(vaultTemplates());
@@ -90439,7 +90975,7 @@ __export(exports_note, {
90439
90975
  note: () => note
90440
90976
  });
90441
90977
  import { resolve as resolve15 } from "path";
90442
- import { existsSync as existsSync34, readFileSync as readFileSync27 } from "fs";
90978
+ import { existsSync as existsSync38, readFileSync as readFileSync28 } from "fs";
90443
90979
  async function note(cwd, args) {
90444
90980
  if (!isWikiEnabled()) {
90445
90981
  console.error("[mink] wiki feature is disabled");
@@ -90464,13 +91000,13 @@ async function note(cwd, args) {
90464
91000
  const date = new Date().toISOString().split("T")[0];
90465
91001
  const content = parsed.positional || parsed.body || "";
90466
91002
  const filePath = appendToDaily(date, content);
90467
- updateVaultIndexForFile(filePath, readFileSync27(filePath, "utf-8"));
91003
+ updateVaultIndexForFile(filePath, readFileSync28(filePath, "utf-8"));
90468
91004
  console.log(`[mink] daily note: ${filePath}`);
90469
91005
  return;
90470
91006
  }
90471
91007
  if (parsed.file) {
90472
91008
  const sourcePath = resolve15(cwd, parsed.file);
90473
- if (!existsSync34(sourcePath)) {
91009
+ if (!existsSync38(sourcePath)) {
90474
91010
  console.error(`[mink] file not found: ${sourcePath}`);
90475
91011
  process.exit(1);
90476
91012
  }
@@ -90552,7 +91088,7 @@ function detectSourceProject(cwd) {
90552
91088
  const vaultPath = resolveVaultPath();
90553
91089
  if (cwd.startsWith(vaultPath))
90554
91090
  return;
90555
- return generateProjectId(cwd);
91091
+ return projectIdFor(cwd);
90556
91092
  } catch {
90557
91093
  return;
90558
91094
  }
@@ -90631,10 +91167,10 @@ var exports_skill = {};
90631
91167
  __export(exports_skill, {
90632
91168
  skill: () => skill
90633
91169
  });
90634
- import { join as join33, resolve as resolve16, dirname as dirname16 } from "path";
91170
+ import { join as join34, resolve as resolve16, dirname as dirname16 } from "path";
90635
91171
  import { homedir as homedir6 } from "os";
90636
91172
  import {
90637
- existsSync as existsSync35,
91173
+ existsSync as existsSync39,
90638
91174
  mkdirSync as mkdirSync15,
90639
91175
  copyFileSync,
90640
91176
  unlinkSync as unlinkSync6,
@@ -90646,8 +91182,8 @@ import {
90646
91182
  function getSkillsSourceDir() {
90647
91183
  let dir = dirname16(new URL(import.meta.url).pathname);
90648
91184
  while (true) {
90649
- if (existsSync35(join33(dir, "package.json")) && existsSync35(join33(dir, "skills"))) {
90650
- return join33(dir, "skills");
91185
+ if (existsSync39(join34(dir, "package.json")) && existsSync39(join34(dir, "skills"))) {
91186
+ return join34(dir, "skills");
90651
91187
  }
90652
91188
  const parent = dirname16(dir);
90653
91189
  if (parent === dir)
@@ -90658,12 +91194,12 @@ function getSkillsSourceDir() {
90658
91194
  }
90659
91195
  function getAvailableSkills() {
90660
91196
  const dir = getSkillsSourceDir();
90661
- if (!existsSync35(dir))
91197
+ if (!existsSync39(dir))
90662
91198
  return [];
90663
- return readdirSync11(dir, { withFileTypes: true }).filter((d) => d.isDirectory() && existsSync35(join33(dir, d.name, "SKILL.md"))).map((d) => d.name);
91199
+ return readdirSync11(dir, { withFileTypes: true }).filter((d) => d.isDirectory() && existsSync39(join34(dir, d.name, "SKILL.md"))).map((d) => d.name);
90664
91200
  }
90665
91201
  function isInstalled(skillName) {
90666
- return existsSync35(join33(AGENTS_SKILLS_DIR, skillName, "SKILL.md"));
91202
+ return existsSync39(join34(AGENTS_SKILLS_DIR, skillName, "SKILL.md"));
90667
91203
  }
90668
91204
  async function skill(args) {
90669
91205
  const sub = args[0];
@@ -90699,26 +91235,26 @@ function skillInstall(name) {
90699
91235
  }
90700
91236
  mkdirSync15(AGENTS_SKILLS_DIR, { recursive: true });
90701
91237
  for (const skillName of skills) {
90702
- const srcDir = join33(sourceDir, skillName);
90703
- const srcFile = join33(srcDir, "SKILL.md");
90704
- const destDir = join33(AGENTS_SKILLS_DIR, skillName);
90705
- if (!existsSync35(srcFile)) {
91238
+ const srcDir = join34(sourceDir, skillName);
91239
+ const srcFile = join34(srcDir, "SKILL.md");
91240
+ const destDir = join34(AGENTS_SKILLS_DIR, skillName);
91241
+ if (!existsSync39(srcFile)) {
90706
91242
  console.error(`[mink] skill not found: ${skillName}`);
90707
91243
  continue;
90708
91244
  }
90709
91245
  mkdirSync15(destDir, { recursive: true });
90710
- copyDirRecursive(srcDir, destDir);
91246
+ copyDirRecursive2(srcDir, destDir);
90711
91247
  mkdirSync15(CLAUDE_SKILLS_DIR, { recursive: true });
90712
- const symlink = join33(CLAUDE_SKILLS_DIR, skillName);
91248
+ const symlink = join34(CLAUDE_SKILLS_DIR, skillName);
90713
91249
  try {
90714
- if (existsSync35(symlink)) {
91250
+ if (existsSync39(symlink)) {
90715
91251
  if (lstatSync2(symlink).isSymbolicLink() || lstatSync2(symlink).isFile()) {
90716
91252
  unlinkSync6(symlink);
90717
91253
  } else {
90718
91254
  rmSync(symlink, { recursive: true, force: true });
90719
91255
  }
90720
91256
  }
90721
- const relativeTarget = join33("..", "..", ".agents", "skills", skillName);
91257
+ const relativeTarget = join34("..", "..", ".agents", "skills", skillName);
90722
91258
  symlinkSync2(relativeTarget, symlink);
90723
91259
  } catch {}
90724
91260
  console.log(`[mink] installed: ${skillName} -> ${destDir}`);
@@ -90729,15 +91265,15 @@ function skillInstall(name) {
90729
91265
  function skillUninstall(name) {
90730
91266
  const skills = name ? [name] : getAvailableSkills();
90731
91267
  for (const skillName of skills) {
90732
- const destDir = join33(AGENTS_SKILLS_DIR, skillName);
90733
- if (!existsSync35(destDir)) {
91268
+ const destDir = join34(AGENTS_SKILLS_DIR, skillName);
91269
+ if (!existsSync39(destDir)) {
90734
91270
  console.log(`[mink] not installed: ${skillName}`);
90735
91271
  continue;
90736
91272
  }
90737
91273
  rmSync(destDir, { recursive: true, force: true });
90738
- const symlink = join33(CLAUDE_SKILLS_DIR, skillName);
91274
+ const symlink = join34(CLAUDE_SKILLS_DIR, skillName);
90739
91275
  try {
90740
- if (existsSync35(symlink))
91276
+ if (existsSync39(symlink))
90741
91277
  unlinkSync6(symlink);
90742
91278
  } catch {}
90743
91279
  console.log(`[mink] uninstalled: ${skillName}`);
@@ -90752,7 +91288,7 @@ function skillList() {
90752
91288
  if (installed.length > 0) {
90753
91289
  console.log(" Installed:");
90754
91290
  for (const s of installed) {
90755
- console.log(` ${s} (${join33(AGENTS_SKILLS_DIR, s)})`);
91291
+ console.log(` ${s} (${join34(AGENTS_SKILLS_DIR, s)})`);
90756
91292
  }
90757
91293
  }
90758
91294
  if (notInstalled.length > 0) {
@@ -90768,14 +91304,14 @@ function skillList() {
90768
91304
  console.log(" Install with: mink skill install");
90769
91305
  console.log(" Or via skills CLI: npx skills add drewpayment/mink");
90770
91306
  }
90771
- function copyDirRecursive(src, dest) {
91307
+ function copyDirRecursive2(src, dest) {
90772
91308
  const entries = readdirSync11(src, { withFileTypes: true });
90773
91309
  for (const entry of entries) {
90774
- const srcPath = join33(src, entry.name);
90775
- const destPath = join33(dest, entry.name);
91310
+ const srcPath = join34(src, entry.name);
91311
+ const destPath = join34(dest, entry.name);
90776
91312
  if (entry.isDirectory()) {
90777
91313
  mkdirSync15(destPath, { recursive: true });
90778
- copyDirRecursive(srcPath, destPath);
91314
+ copyDirRecursive2(srcPath, destPath);
90779
91315
  } else {
90780
91316
  copyFileSync(srcPath, destPath);
90781
91317
  }
@@ -90783,8 +91319,8 @@ function copyDirRecursive(src, dest) {
90783
91319
  }
90784
91320
  var AGENTS_SKILLS_DIR, CLAUDE_SKILLS_DIR;
90785
91321
  var init_skill = __esm(() => {
90786
- AGENTS_SKILLS_DIR = join33(homedir6(), ".agents", "skills");
90787
- CLAUDE_SKILLS_DIR = join33(homedir6(), ".claude", "skills");
91322
+ AGENTS_SKILLS_DIR = join34(homedir6(), ".agents", "skills");
91323
+ CLAUDE_SKILLS_DIR = join34(homedir6(), ".claude", "skills");
90788
91324
  });
90789
91325
 
90790
91326
  // src/commands/agent.ts
@@ -90792,12 +91328,12 @@ var exports_agent = {};
90792
91328
  __export(exports_agent, {
90793
91329
  agent: () => agent
90794
91330
  });
90795
- import { join as join34, resolve as resolve17, dirname as dirname17 } from "path";
91331
+ import { join as join35, resolve as resolve17, dirname as dirname17 } from "path";
90796
91332
  import { homedir as homedir7 } from "os";
90797
91333
  import {
90798
- existsSync as existsSync36,
91334
+ existsSync as existsSync40,
90799
91335
  mkdirSync as mkdirSync16,
90800
- readFileSync as readFileSync28,
91336
+ readFileSync as readFileSync29,
90801
91337
  writeFileSync as writeFileSync11
90802
91338
  } from "fs";
90803
91339
  import { createHash as createHash3 } from "crypto";
@@ -90805,8 +91341,8 @@ import { spawnSync as spawnSync6 } from "child_process";
90805
91341
  function getAgentTemplatePath() {
90806
91342
  let dir = dirname17(new URL(import.meta.url).pathname);
90807
91343
  while (true) {
90808
- if (existsSync36(join34(dir, "package.json")) && existsSync36(join34(dir, "agents", TEMPLATE_FILE))) {
90809
- return join34(dir, "agents", TEMPLATE_FILE);
91344
+ if (existsSync40(join35(dir, "package.json")) && existsSync40(join35(dir, "agents", TEMPLATE_FILE))) {
91345
+ return join35(dir, "agents", TEMPLATE_FILE);
90810
91346
  }
90811
91347
  const parent = dirname17(dir);
90812
91348
  if (parent === dir)
@@ -90818,10 +91354,10 @@ function getAgentTemplatePath() {
90818
91354
  function getMinkVersion() {
90819
91355
  let dir = dirname17(new URL(import.meta.url).pathname);
90820
91356
  while (true) {
90821
- const pkgPath = join34(dir, "package.json");
90822
- if (existsSync36(pkgPath)) {
91357
+ const pkgPath = join35(dir, "package.json");
91358
+ if (existsSync40(pkgPath)) {
90823
91359
  try {
90824
- const pkg = JSON.parse(readFileSync28(pkgPath, "utf-8"));
91360
+ const pkg = JSON.parse(readFileSync29(pkgPath, "utf-8"));
90825
91361
  if (pkg.name && pkg.version)
90826
91362
  return pkg.version;
90827
91363
  } catch {}
@@ -90844,30 +91380,30 @@ function sha2562(text) {
90844
91380
  return createHash3("sha256").update(text).digest("hex");
90845
91381
  }
90846
91382
  function claudeAgentsDir() {
90847
- return join34(homedir7(), ".claude", "agents");
91383
+ return join35(homedir7(), ".claude", "agents");
90848
91384
  }
90849
91385
  function installedAgentPath() {
90850
- return join34(claudeAgentsDir(), INSTALLED_FILE);
91386
+ return join35(claudeAgentsDir(), INSTALLED_FILE);
90851
91387
  }
90852
91388
  function installAgentDefinition(opts) {
90853
91389
  const templatePath = getAgentTemplatePath();
90854
- if (!existsSync36(templatePath)) {
91390
+ if (!existsSync40(templatePath)) {
90855
91391
  throw new Error(`[mink agent] bundled agent template not found at ${templatePath}
90856
91392
  ` + " This usually means the package was installed without bundled assets.");
90857
91393
  }
90858
91394
  const installed = installedAgentPath();
90859
- if (opts.skip && existsSync36(installed)) {
91395
+ if (opts.skip && existsSync40(installed)) {
90860
91396
  return { action: "skipped", path: installed };
90861
91397
  }
90862
- const template = readFileSync28(templatePath, "utf-8");
91398
+ const template = readFileSync29(templatePath, "utf-8");
90863
91399
  const rendered = renderTemplate(template, {
90864
91400
  MINK_ROOT: minkRoot(),
90865
91401
  VAULT_PATH: resolveVaultPath(),
90866
91402
  MINK_VERSION: getMinkVersion()
90867
91403
  });
90868
- const exists = existsSync36(installed);
91404
+ const exists = existsSync40(installed);
90869
91405
  if (!opts.force && exists) {
90870
- const current = readFileSync28(installed, "utf-8");
91406
+ const current = readFileSync29(installed, "utf-8");
90871
91407
  if (sha2562(current) === sha2562(rendered)) {
90872
91408
  return { action: "unchanged", path: installed };
90873
91409
  }
@@ -90943,7 +91479,7 @@ async function agent(_cwd, rawArgs) {
90943
91479
  }
90944
91480
  const skipUpdate = args.noUpdate || process.env.MINK_AGENT_NO_UPDATE === "1";
90945
91481
  const root = minkRoot();
90946
- if (!existsSync36(root)) {
91482
+ if (!existsSync40(root)) {
90947
91483
  mkdirSync16(root, { recursive: true });
90948
91484
  }
90949
91485
  let result;
@@ -90995,25 +91531,25 @@ var init_agent = __esm(() => {
90995
91531
  });
90996
91532
 
90997
91533
  // src/core/sync-merge-drivers.ts
90998
- import { readFileSync as readFileSync29, writeFileSync as writeFileSync12, appendFileSync as appendFileSync2 } from "fs";
90999
- import { join as join35 } from "path";
91534
+ import { readFileSync as readFileSync30, writeFileSync as writeFileSync12, appendFileSync as appendFileSync2 } from "fs";
91535
+ import { join as join36 } from "path";
91000
91536
  function logWarning(driver, args, err) {
91001
91537
  try {
91002
91538
  const line = `[${new Date().toISOString()}] ${driver} fallback for ${args.filePath}: ${err instanceof Error ? err.message : String(err)}
91003
91539
  `;
91004
- appendFileSync2(join35(minkRoot(), "sync-warnings.log"), line);
91540
+ appendFileSync2(join36(minkRoot(), "sync-warnings.log"), line);
91005
91541
  } catch {}
91006
91542
  }
91007
91543
  function readJsonOrNull(path12) {
91008
91544
  try {
91009
- return JSON.parse(readFileSync29(path12, "utf-8"));
91545
+ return JSON.parse(readFileSync30(path12, "utf-8"));
91010
91546
  } catch {
91011
91547
  return null;
91012
91548
  }
91013
91549
  }
91014
91550
  function readTextOrEmpty(path12) {
91015
91551
  try {
91016
- return readFileSync29(path12, "utf-8");
91552
+ return readFileSync30(path12, "utf-8");
91017
91553
  } catch {
91018
91554
  return "";
91019
91555
  }
@@ -91187,12 +91723,13 @@ async function sync(args) {
91187
91723
  return handleReconcile(args.slice(1));
91188
91724
  case "migrate": {
91189
91725
  const { syncMigrateCommand: syncMigrateCommand2 } = await Promise.resolve().then(() => (init_sync_migrate(), exports_sync_migrate));
91190
- syncMigrateCommand2();
91726
+ syncMigrateCommand2(args.slice(1));
91191
91727
  return;
91192
91728
  }
91193
91729
  default:
91194
91730
  console.error(`[mink] unknown sync subcommand: ${subcommand}`);
91195
- console.error("Usage: mink sync [init|status|push|pull|pause|resume|disconnect|reconcile|migrate|merge-driver]");
91731
+ console.error("Usage: mink sync [init|status|push|pull|pause|resume|disconnect|reconcile|merge-driver]");
91732
+ console.error(" mink sync migrate [--dry-run|--rollback]");
91196
91733
  process.exit(1);
91197
91734
  }
91198
91735
  }
@@ -91414,7 +91951,9 @@ function sessionStart(cwd) {
91414
91951
  } catch {}
91415
91952
  try {
91416
91953
  const { readSyncVersion: readSyncVersion2, MINK_SYNC_VERSION: MINK_SYNC_VERSION2 } = (init_sync(), __toCommonJS(exports_sync));
91417
- if (readSyncVersion2() < MINK_SYNC_VERSION2) {
91954
+ const { resolveConfigValue: resolveConfigValue2 } = (init_global_config(), __toCommonJS(exports_global_config));
91955
+ const identityOn = resolveConfigValue2("projects.identity").value === "git-remote";
91956
+ if (readSyncVersion2() < MINK_SYNC_VERSION2 || identityOn) {
91418
91957
  const { migrateSyncLayout: migrateSyncLayout2 } = (init_sync_migrate(), __toCommonJS(exports_sync_migrate));
91419
91958
  migrateSyncLayout2();
91420
91959
  }
@@ -91438,13 +91977,13 @@ function sessionStart(cwd) {
91438
91977
  const index = loadVaultIndex();
91439
91978
  const inboxCount = Object.values(index.entries).filter((e) => e.category === "inbox").length;
91440
91979
  try {
91441
- const { join: join8 } = __require("path");
91442
- const { existsSync: existsSync8 } = __require("fs");
91980
+ const { join: join10 } = __require("path");
91981
+ const { existsSync: existsSync12 } = __require("fs");
91443
91982
  const { resolveVaultPath: resolveVaultPath2 } = (init_vault(), __toCommonJS(exports_vault));
91444
91983
  const { updateMasterIndex: updateMasterIndex2 } = (init_note_linker(), __toCommonJS(exports_note_linker));
91445
91984
  const vaultPath = resolveVaultPath2();
91446
- const masterIndexPath = join8(vaultPath, "_index.md");
91447
- if (!existsSync8(masterIndexPath)) {
91985
+ const masterIndexPath = join10(vaultPath, "_index.md");
91986
+ if (!existsSync12(masterIndexPath)) {
91448
91987
  updateMasterIndex2(vaultPath);
91449
91988
  }
91450
91989
  } catch {}
@@ -91468,8 +92007,8 @@ init_state_aggregator();
91468
92007
  init_action_log();
91469
92008
  init_device();
91470
92009
  init_vault();
91471
- import { statSync as statSync5, existsSync as existsSync10, readFileSync as readFileSync9 } from "fs";
91472
- import { join as join10, dirname as dirname4 } from "path";
92010
+ import { statSync as statSync5, existsSync as existsSync14, readFileSync as readFileSync10 } from "fs";
92011
+ import { join as join12, dirname as dirname4 } from "path";
91473
92012
  function hasActivity(state) {
91474
92013
  return Object.keys(state.reads).length > 0 || state.writes.length > 0;
91475
92014
  }
@@ -91511,10 +92050,10 @@ function sessionStop(sessionFile, finalizer, onReminder = (msg) => console.error
91511
92050
  effectiveFinalizer.updateSession(summary);
91512
92051
  }
91513
92052
  try {
91514
- const logPath = join10(projDir, "state", deviceId, "action-log.md");
92053
+ const logPath = join12(projDir, "state", deviceId, "action-log.md");
91515
92054
  const logWriter = createActionLogWriter(logPath);
91516
92055
  logWriter.appendSessionEnd(summary);
91517
- const cfgRaw = safeReadJson(join10(projDir, "config.json"));
92056
+ const cfgRaw = safeReadJson(join12(projDir, "config.json"));
91518
92057
  consolidateLog(logPath, {
91519
92058
  maxEntries: cfgRaw?.actionLogMaxEntries ?? 200,
91520
92059
  retentionDays: cfgRaw?.actionLogRetentionDays ?? 7
@@ -91531,9 +92070,9 @@ function sessionStop(sessionFile, finalizer, onReminder = (msg) => console.error
91531
92070
  }
91532
92071
  }
91533
92072
  }
91534
- const memoryPath = join10(projDir, "learning-memory.md");
91535
- const cfgPath = join10(projDir, "config.json");
91536
- if (existsSync10(memoryPath)) {
92073
+ const memoryPath = join12(projDir, "learning-memory.md");
92074
+ const cfgPath = join12(projDir, "config.json");
92075
+ if (existsSync14(memoryPath)) {
91537
92076
  reflect(projDir, memoryPath, cfgPath);
91538
92077
  }
91539
92078
  if (isLearningMemoryStale(memoryPath)) {
@@ -91553,13 +92092,13 @@ function sessionStop(sessionFile, finalizer, onReminder = (msg) => console.error
91553
92092
  atomicWriteJson(sessionFile, state);
91554
92093
  }
91555
92094
  function writeSessionToWiki(state, projDir) {
91556
- const metaRaw = safeReadJson(join10(projDir, "project-meta.json"));
92095
+ const metaRaw = safeReadJson(join12(projDir, "project-meta.json"));
91557
92096
  const projectName = metaRaw?.name ?? "unknown";
91558
92097
  const date = new Date().toISOString().split("T")[0];
91559
92098
  const readCount = Object.keys(state.reads).length;
91560
92099
  const writeCount = state.writes.length;
91561
- const sessionDir = join10(vaultProjects(projectName), "sessions");
91562
- const sessionFile = join10(sessionDir, `${date}.md`);
92100
+ const sessionDir = join12(vaultProjects(projectName), "sessions");
92101
+ const sessionFile = join12(sessionDir, `${date}.md`);
91563
92102
  const timestamp = new Date().toLocaleTimeString("en-US", {
91564
92103
  hour: "2-digit",
91565
92104
  minute: "2-digit",
@@ -91584,8 +92123,8 @@ function writeSessionToWiki(state, projDir) {
91584
92123
  }
91585
92124
  }
91586
92125
  entry.push("");
91587
- if (existsSync10(sessionFile)) {
91588
- const existing = readFileSync9(sessionFile, "utf-8");
92126
+ if (existsSync14(sessionFile)) {
92127
+ const existing = readFileSync10(sessionFile, "utf-8");
91589
92128
  atomicWriteText(sessionFile, existing.trimEnd() + `
91590
92129
  ` + entry.join(`
91591
92130
  `));
@@ -91766,9 +92305,9 @@ switch (command2) {
91766
92305
  case "-v": {
91767
92306
  const { resolve: resolve18, dirname: dirname18 } = await import("path");
91768
92307
  const cliPath = resolve18(dirname18(new URL(import.meta.url).pathname));
91769
- const { readFileSync: readFileSync30 } = await import("fs");
92308
+ const { readFileSync: readFileSync31 } = await import("fs");
91770
92309
  try {
91771
- const pkg = JSON.parse(readFileSync30(resolve18(cliPath, "../package.json"), "utf-8"));
92310
+ const pkg = JSON.parse(readFileSync31(resolve18(cliPath, "../package.json"), "utf-8"));
91772
92311
  console.log(`mink ${pkg.version}`);
91773
92312
  } catch {
91774
92313
  console.log("mink (unknown version)");