@drewpayment/mink 0.10.1 → 0.11.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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 +1406 -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 +404 -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 +142 -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 → WDjkNLHEd_wI-oOzLyblH}/_buildManifest.js +0 -0
  53. /package/dashboard/out/_next/static/{e0QWU9rPMeSlJJLTwij89 → WDjkNLHEd_wI-oOzLyblH}/_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) {
627
+ const mode = 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,208 @@ function projectNeedsMigration(projDir) {
1876
2175
  function listProjectsNeedingMigration() {
1877
2176
  return listProjects().filter(projectNeedsMigration);
1878
2177
  }
2178
+ function planIdentityMigration() {
2179
+ const plan = [];
2180
+ if (resolveConfigValue("projects.identity").value !== "git-remote") {
2181
+ return plan;
2182
+ }
2183
+ const projectsRoot = join8(minkRoot(), "projects");
2184
+ if (!existsSync10(projectsRoot))
2185
+ return plan;
2186
+ let entries;
2187
+ try {
2188
+ entries = readdirSync3(projectsRoot);
2189
+ } catch {
2190
+ return plan;
2191
+ }
2192
+ for (const oldId of entries) {
2193
+ const oldProjDir = join8(projectsRoot, oldId);
2194
+ try {
2195
+ if (!statSync2(oldProjDir).isDirectory())
2196
+ continue;
2197
+ } catch {
2198
+ continue;
2199
+ }
2200
+ const meta = getProjectMeta(oldProjDir);
2201
+ if (!meta)
2202
+ continue;
2203
+ if (!existsSync10(meta.cwd)) {
2204
+ plan.push({
2205
+ oldId,
2206
+ newId: null,
2207
+ cwd: meta.cwd,
2208
+ action: "skip-no-cwd",
2209
+ reason: "working-copy path not reachable on this device"
2210
+ });
2211
+ continue;
2212
+ }
2213
+ let newId;
2214
+ try {
2215
+ newId = resolveProjectIdentity(meta.cwd).id;
2216
+ } catch {
2217
+ continue;
2218
+ }
2219
+ if (newId === oldId) {
2220
+ plan.push({ oldId, newId, cwd: meta.cwd, action: "skip-unchanged" });
2221
+ continue;
2222
+ }
2223
+ const newProjDir = join8(projectsRoot, newId);
2224
+ if (existsSync10(newProjDir)) {
2225
+ plan.push({
2226
+ oldId,
2227
+ newId,
2228
+ cwd: meta.cwd,
2229
+ action: "skip-converged",
2230
+ reason: "destination already exists (from sync); alias-only update"
2231
+ });
2232
+ continue;
2233
+ }
2234
+ plan.push({ oldId, newId, cwd: meta.cwd, action: "rename" });
2235
+ }
2236
+ return plan;
2237
+ }
2238
+ function identityBackupRoot(timestamp) {
2239
+ return join8(minkRoot(), IDENTITY_BACKUP_DIRNAME, timestamp);
2240
+ }
2241
+ function ensureIdentityBackupTimestamp() {
2242
+ const now = new Date;
2243
+ 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")}`;
2244
+ }
2245
+ function backupProjectForRollback(srcDir, backupDir) {
2246
+ try {
2247
+ mkdirSync4(backupDir, { recursive: true });
2248
+ copyDirRecursive(srcDir, backupDir, new Set(["backups"]));
2249
+ return backupDir;
2250
+ } catch {
2251
+ return null;
2252
+ }
2253
+ }
2254
+ function copyDirRecursive(src, dest, excludeNames) {
2255
+ mkdirSync4(dest, { recursive: true });
2256
+ const entries = readdirSync3(src, { withFileTypes: true });
2257
+ for (const entry of entries) {
2258
+ if (excludeNames.has(entry.name))
2259
+ continue;
2260
+ const srcPath = join8(src, entry.name);
2261
+ const destPath = join8(dest, entry.name);
2262
+ if (entry.isDirectory()) {
2263
+ copyDirRecursive(srcPath, destPath, excludeNames);
2264
+ } else if (entry.isFile()) {
2265
+ writeFileSync4(destPath, readFileSync7(srcPath));
2266
+ }
2267
+ }
2268
+ }
2269
+ function migrateProjectIdentities(deviceId) {
2270
+ if (resolveConfigValue("projects.identity").value !== "git-remote") {
2271
+ return { renamed: 0, visited: 0, backupDir: null };
2272
+ }
2273
+ const plan = planIdentityMigration();
2274
+ const willRename = plan.filter((p) => p.action === "rename");
2275
+ let backupRoot = null;
2276
+ if (willRename.length > 0) {
2277
+ backupRoot = identityBackupRoot(ensureIdentityBackupTimestamp());
2278
+ }
2279
+ let renamed = 0;
2280
+ let visited = plan.length;
2281
+ const projectsRoot = join8(minkRoot(), "projects");
2282
+ for (const entry of plan) {
2283
+ const oldProjDir = join8(projectsRoot, entry.oldId);
2284
+ if (entry.cwd && entry.action !== "skip-no-cwd") {
2285
+ try {
2286
+ setProjectPathForDevice(oldProjDir, deviceId, entry.cwd);
2287
+ } catch {}
2288
+ }
2289
+ if (entry.action === "skip-converged" && entry.newId) {
2290
+ const newProjDir2 = join8(projectsRoot, entry.newId);
2291
+ try {
2292
+ addProjectAlias(newProjDir2, entry.oldId);
2293
+ if (entry.cwd) {
2294
+ setProjectPathForDevice(newProjDir2, deviceId, entry.cwd);
2295
+ }
2296
+ } catch {}
2297
+ continue;
2298
+ }
2299
+ if (entry.action !== "rename" || !entry.newId)
2300
+ continue;
2301
+ if (backupRoot) {
2302
+ backupProjectForRollback(oldProjDir, join8(backupRoot, entry.oldId));
2303
+ }
2304
+ const newProjDir = join8(projectsRoot, entry.newId);
2305
+ const moved = gitSafe3(`mv "${oldProjDir}" "${newProjDir}"`) !== null || (() => {
2306
+ try {
2307
+ renameSync2(oldProjDir, newProjDir);
2308
+ return true;
2309
+ } catch {
2310
+ return false;
2311
+ }
2312
+ })();
2313
+ if (!moved)
2314
+ continue;
2315
+ try {
2316
+ addProjectAlias(newProjDir, entry.oldId);
2317
+ if (entry.cwd) {
2318
+ setProjectPathForDevice(newProjDir, deviceId, entry.cwd);
2319
+ }
2320
+ } catch {}
2321
+ renamed++;
2322
+ }
2323
+ return { renamed, visited, backupDir: backupRoot };
2324
+ }
2325
+ function rollbackProjectIdentities() {
2326
+ const results = [];
2327
+ const projectsRoot = join8(minkRoot(), "projects");
2328
+ if (!existsSync10(projectsRoot))
2329
+ return results;
2330
+ let entries;
2331
+ try {
2332
+ entries = readdirSync3(projectsRoot);
2333
+ } catch {
2334
+ return results;
2335
+ }
2336
+ for (const currentId of entries) {
2337
+ const projDir = join8(projectsRoot, currentId);
2338
+ try {
2339
+ if (!statSync2(projDir).isDirectory())
2340
+ continue;
2341
+ } catch {
2342
+ continue;
2343
+ }
2344
+ const meta = getProjectMeta(projDir);
2345
+ if (!meta || !meta.aliases || meta.aliases.length === 0)
2346
+ continue;
2347
+ const restoredId = meta.aliases[meta.aliases.length - 1];
2348
+ const targetDir = join8(projectsRoot, restoredId);
2349
+ if (existsSync10(targetDir)) {
2350
+ results.push({ currentId, restoredId, ok: false });
2351
+ continue;
2352
+ }
2353
+ const remainingAliases = meta.aliases.slice(0, -1);
2354
+ const metaPath = join8(projDir, "project-meta.json");
2355
+ try {
2356
+ const raw = safeReadJson(metaPath);
2357
+ if (raw && typeof raw === "object" && !Array.isArray(raw)) {
2358
+ const obj = raw;
2359
+ obj.aliases = remainingAliases;
2360
+ atomicWriteJson(metaPath, obj);
2361
+ }
2362
+ } catch {}
2363
+ const moved = gitSafe3(`mv "${projDir}" "${targetDir}"`) !== null || (() => {
2364
+ try {
2365
+ renameSync2(projDir, targetDir);
2366
+ return true;
2367
+ } catch {
2368
+ return false;
2369
+ }
2370
+ })();
2371
+ results.push({ currentId, restoredId, ok: moved });
2372
+ }
2373
+ return results;
2374
+ }
1879
2375
  function migrateSyncLayout() {
1880
2376
  const fromVersion = readSyncVersion();
1881
2377
  const pending = listProjectsNeedingMigration();
1882
- if (fromVersion >= MINK_SYNC_VERSION && pending.length === 0) {
2378
+ const identityMode = resolveConfigValue("projects.identity").value;
2379
+ if (fromVersion >= MINK_SYNC_VERSION && pending.length === 0 && identityMode !== "git-remote") {
1883
2380
  return {
1884
2381
  ranMigration: false,
1885
2382
  fromVersion,
@@ -1924,13 +2421,18 @@ function migrateSyncLayout() {
1924
2421
  processed++;
1925
2422
  } catch {}
1926
2423
  }
2424
+ let identity = { renamed: 0, visited: 0 };
2425
+ try {
2426
+ identity = migrateProjectIdentities(deviceId);
2427
+ } catch {}
1927
2428
  if (remaining === 0 && listProjectsNeedingMigration().length === 0) {
1928
2429
  writeSyncVersion(MINK_SYNC_VERSION);
1929
2430
  }
1930
- if (isSyncInitialized() && processed > 0) {
2431
+ if (isSyncInitialized() && (processed > 0 || identity.renamed > 0)) {
1931
2432
  gitSafe3("add -A");
1932
2433
  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)"`);
2434
+ const summary = identity.renamed > 0 ? `${processed} projects, ${identity.renamed} renamed for identity v3` : `${processed} projects`;
2435
+ gitSafe3(`commit -m "mink: migrate sync layout v${fromVersion} -> v${MINK_SYNC_VERSION} (device ${deviceId.slice(0, 8)}, ${summary})"`);
1934
2436
  }
1935
2437
  if (stashed) {
1936
2438
  gitSafe3("stash pop");
@@ -1944,7 +2446,56 @@ function migrateSyncLayout() {
1944
2446
  releaseLock();
1945
2447
  }
1946
2448
  }
1947
- function syncMigrateCommand() {
2449
+ function syncMigrateCommand(args = []) {
2450
+ const dryRun = args.includes("--dry-run");
2451
+ const rollback = args.includes("--rollback");
2452
+ if (rollback && dryRun) {
2453
+ console.error("[mink] --rollback and --dry-run cannot be combined");
2454
+ process.exit(1);
2455
+ }
2456
+ if (dryRun) {
2457
+ const plan = planIdentityMigration();
2458
+ if (plan.length === 0) {
2459
+ console.log("[mink] sync migrate --dry-run: no projects to rename (flag is off or no projects on disk)");
2460
+ return;
2461
+ }
2462
+ const renames = plan.filter((p) => p.action === "rename");
2463
+ const converged = plan.filter((p) => p.action === "skip-converged");
2464
+ const skippedNoCwd = plan.filter((p) => p.action === "skip-no-cwd");
2465
+ const unchanged = plan.filter((p) => p.action === "skip-unchanged");
2466
+ console.log(`[mink] sync migrate --dry-run: ${renames.length} rename(s), ${converged.length} alias-only, ${skippedNoCwd.length} skipped (no cwd), ${unchanged.length} unchanged`);
2467
+ for (const p of renames) {
2468
+ console.log(` rename: ${p.oldId} → ${p.newId}`);
2469
+ }
2470
+ for (const p of converged) {
2471
+ console.log(` alias: ${p.oldId} → ${p.newId} (already on disk)`);
2472
+ }
2473
+ for (const p of skippedNoCwd) {
2474
+ console.log(` skip: ${p.oldId} — ${p.reason}`);
2475
+ }
2476
+ return;
2477
+ }
2478
+ if (rollback) {
2479
+ const results = rollbackProjectIdentities();
2480
+ if (results.length === 0) {
2481
+ console.log("[mink] sync migrate --rollback: nothing to roll back");
2482
+ return;
2483
+ }
2484
+ const ok = results.filter((r) => r.ok);
2485
+ const failed = results.filter((r) => !r.ok);
2486
+ console.log(`[mink] sync migrate --rollback: ${ok.length} restored, ${failed.length} failed`);
2487
+ for (const r of ok) {
2488
+ console.log(` restored: ${r.currentId} → ${r.restoredId}`);
2489
+ }
2490
+ for (const r of failed) {
2491
+ console.log(` failed: ${r.currentId} → ${r.restoredId} (destination already exists or rename blocked)`);
2492
+ }
2493
+ if (ok.length > 0) {
2494
+ console.log(`
2495
+ [mink] tip: set projects.identity=path-derived to prevent the next session-start from re-migrating`);
2496
+ }
2497
+ return;
2498
+ }
1948
2499
  const result = migrateSyncLayout();
1949
2500
  if (!result.ranMigration) {
1950
2501
  console.log(`[mink] sync migrate: ${result.message ?? "no-op"}`);
@@ -1952,12 +2503,15 @@ function syncMigrateCommand() {
1952
2503
  }
1953
2504
  console.log(`[mink] sync migrate: v${result.fromVersion} → v${result.toVersion} complete`);
1954
2505
  }
1955
- var MIGRATE_LOCK = ".sync-migrate.lock", MIGRATE_LOCK_STALE_MS = 300000, MIGRATE_BUDGET_MS = 5000;
2506
+ var MIGRATE_LOCK = ".sync-migrate.lock", MIGRATE_LOCK_STALE_MS = 300000, MIGRATE_BUDGET_MS = 5000, IDENTITY_BACKUP_DIRNAME = ".identity-rollback";
1956
2507
  var init_sync_migrate = __esm(() => {
1957
2508
  init_paths();
1958
2509
  init_sync();
1959
2510
  init_device();
1960
2511
  init_fs_utils();
2512
+ init_project_id();
2513
+ init_project_registry();
2514
+ init_global_config();
1961
2515
  });
1962
2516
 
1963
2517
  // src/core/note-linker.ts
@@ -1968,8 +2522,8 @@ __export(exports_note_linker, {
1968
2522
  extractWikilinks: () => extractWikilinks,
1969
2523
  addBacklink: () => addBacklink
1970
2524
  });
1971
- import { join as join7 } from "path";
1972
- import { existsSync as existsSync7, readFileSync as readFileSync7, readdirSync as readdirSync3, statSync as statSync3 } from "fs";
2525
+ import { join as join9 } from "path";
2526
+ import { existsSync as existsSync11, readFileSync as readFileSync8, readdirSync as readdirSync4, statSync as statSync3 } from "fs";
1973
2527
  function extractWikilinks(content) {
1974
2528
  const links = [];
1975
2529
  let match;
@@ -1995,9 +2549,9 @@ function insertWikilinks(content, targets) {
1995
2549
  return result;
1996
2550
  }
1997
2551
  function addBacklink(targetNotePath, sourceTitle) {
1998
- if (!existsSync7(targetNotePath))
2552
+ if (!existsSync11(targetNotePath))
1999
2553
  return;
2000
- const content = readFileSync7(targetNotePath, "utf-8");
2554
+ const content = readFileSync8(targetNotePath, "utf-8");
2001
2555
  if (content.includes(`[[${sourceTitle}]]`))
2002
2556
  return;
2003
2557
  const backlinkSection = `
@@ -2039,8 +2593,8 @@ function updateMasterIndex(vaultRootPath) {
2039
2593
  { name: "Patterns", dir: "patterns", emoji: "" }
2040
2594
  ];
2041
2595
  for (const cat of categories) {
2042
- const dirPath = join7(vaultRootPath, cat.dir);
2043
- if (!existsSync7(dirPath))
2596
+ const dirPath = join9(vaultRootPath, cat.dir);
2597
+ if (!existsSync11(dirPath))
2044
2598
  continue;
2045
2599
  const files = collectMarkdownFiles(dirPath, vaultRootPath);
2046
2600
  if (files.length === 0 && cat.dir !== "inbox")
@@ -2067,9 +2621,9 @@ function updateMasterIndex(vaultRootPath) {
2067
2621
  function collectMarkdownFiles(dirPath, rootPath) {
2068
2622
  const files = [];
2069
2623
  try {
2070
- const entries = readdirSync3(dirPath, { withFileTypes: true });
2624
+ const entries = readdirSync4(dirPath, { withFileTypes: true });
2071
2625
  for (const entry of entries) {
2072
- const fullPath = join7(dirPath, entry.name);
2626
+ const fullPath = join9(dirPath, entry.name);
2073
2627
  if (entry.isDirectory()) {
2074
2628
  files.push(...collectMarkdownFiles(fullPath, rootPath));
2075
2629
  } else if (entry.name.endsWith(".md") && !entry.name.startsWith("_")) {
@@ -2202,7 +2756,7 @@ var init_learning_memory = __esm(() => {
2202
2756
  });
2203
2757
 
2204
2758
  // src/core/token-ledger.ts
2205
- import { join as join8 } from "path";
2759
+ import { join as join10 } from "path";
2206
2760
  function addToLifetime(lifetime, session) {
2207
2761
  lifetime.totalTokens += session.totals.estimatedTokens;
2208
2762
  lifetime.totalReads += session.totals.readCount;
@@ -2333,13 +2887,13 @@ function createLedgerFinalizer(projectDir2, deviceIdOrThreshold, archiveThreshol
2333
2887
  let archivePath;
2334
2888
  let threshold;
2335
2889
  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");
2890
+ const shardDir = join10(projectDir2, "state", deviceIdOrThreshold);
2891
+ ledgerPath = join10(shardDir, "token-ledger.json");
2892
+ archivePath = join10(shardDir, "token-ledger-archive.json");
2339
2893
  threshold = archiveThreshold;
2340
2894
  } else {
2341
- ledgerPath = join8(projectDir2, "token-ledger.json");
2342
- archivePath = join8(projectDir2, "token-ledger-archive.json");
2895
+ ledgerPath = join10(projectDir2, "token-ledger.json");
2896
+ archivePath = join10(projectDir2, "token-ledger-archive.json");
2343
2897
  threshold = deviceIdOrThreshold ?? archiveThreshold;
2344
2898
  }
2345
2899
  return {
@@ -2479,16 +3033,16 @@ var init_bug_memory = __esm(() => {
2479
3033
  });
2480
3034
 
2481
3035
  // 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";
3036
+ import { existsSync as existsSync12, readdirSync as readdirSync5, readFileSync as readFileSync9, statSync as statSync4 } from "fs";
3037
+ import { join as join11 } from "path";
2484
3038
  function listDeviceShardsAt(projDir) {
2485
- const stateDir = join9(projDir, "state");
2486
- if (!existsSync8(stateDir))
3039
+ const stateDir = join11(projDir, "state");
3040
+ if (!existsSync12(stateDir))
2487
3041
  return [];
2488
3042
  try {
2489
- return readdirSync4(stateDir).filter((name) => {
3043
+ return readdirSync5(stateDir).filter((name) => {
2490
3044
  try {
2491
- return statSync4(join9(stateDir, name)).isDirectory();
3045
+ return statSync4(join11(stateDir, name)).isDirectory();
2492
3046
  } catch {
2493
3047
  return false;
2494
3048
  }
@@ -2498,16 +3052,16 @@ function listDeviceShardsAt(projDir) {
2498
3052
  }
2499
3053
  }
2500
3054
  function listLearningMemorySidecarPathsAt(projDir) {
2501
- if (!existsSync8(projDir))
3055
+ if (!existsSync12(projDir))
2502
3056
  return [];
2503
3057
  try {
2504
- return readdirSync4(projDir).filter((f) => SIDECAR_RE.test(f)).map((f) => join9(projDir, f));
3058
+ return readdirSync5(projDir).filter((f) => SIDECAR_RE.test(f)).map((f) => join11(projDir, f));
2505
3059
  } catch {
2506
3060
  return [];
2507
3061
  }
2508
3062
  }
2509
3063
  function shardPath(projDir, deviceId, file) {
2510
- return join9(projDir, "state", deviceId, file);
3064
+ return join11(projDir, "state", deviceId, file);
2511
3065
  }
2512
3066
  function addLifetime(target, source) {
2513
3067
  target.totalTokens += source.totalTokens;
@@ -2524,12 +3078,12 @@ function aggregateTokenLedgerAt(projDir) {
2524
3078
  const seenSessions = new Set;
2525
3079
  const sources = [
2526
3080
  ...listDeviceShardsAt(projDir).map((id) => shardPath(projDir, id, "token-ledger.json")),
2527
- join9(projDir, "token-ledger.json")
3081
+ join11(projDir, "token-ledger.json")
2528
3082
  ];
2529
3083
  const seenFlagKeys = new Set;
2530
3084
  const wasteFlags = [];
2531
3085
  for (const path of sources) {
2532
- if (!existsSync8(path))
3086
+ if (!existsSync12(path))
2533
3087
  continue;
2534
3088
  const ledger = loadLedger(path);
2535
3089
  addLifetime(merged.lifetime, ledger.lifetime);
@@ -2563,10 +3117,10 @@ function aggregateBugMemoryAt(projDir) {
2563
3117
  let maxNextId = 1;
2564
3118
  const sources = [
2565
3119
  ...listDeviceShardsAt(projDir).map((id) => shardPath(projDir, id, "bug-memory.json")),
2566
- join9(projDir, "bug-memory.json")
3120
+ join11(projDir, "bug-memory.json")
2567
3121
  ];
2568
3122
  for (const path of sources) {
2569
- if (!existsSync8(path))
3123
+ if (!existsSync12(path))
2570
3124
  continue;
2571
3125
  const mem = loadBugMemory(path);
2572
3126
  if (mem.nextId > maxNextId)
@@ -2606,10 +3160,10 @@ function aggregateActionLogAt(projDir) {
2606
3160
  let order = 0;
2607
3161
  const sources = [
2608
3162
  ...listDeviceShardsAt(projDir).map((id) => shardPath(projDir, id, "action-log.md")),
2609
- join9(projDir, "action-log.md")
3163
+ join11(projDir, "action-log.md")
2610
3164
  ];
2611
3165
  for (const path of sources) {
2612
- if (!existsSync8(path))
3166
+ if (!existsSync12(path))
2613
3167
  continue;
2614
3168
  const content = safeReadLog(path);
2615
3169
  if (!content)
@@ -2634,11 +3188,11 @@ function aggregateActionLog(cwd) {
2634
3188
  return aggregateActionLogAt(projectDir(cwd));
2635
3189
  }
2636
3190
  function aggregateLearningMemoryAt(projDir) {
2637
- const canonicalPath = join9(projDir, "learning-memory.md");
3191
+ const canonicalPath = join11(projDir, "learning-memory.md");
2638
3192
  let merged;
2639
- if (existsSync8(canonicalPath)) {
3193
+ if (existsSync12(canonicalPath)) {
2640
3194
  try {
2641
- merged = parseLearningMemory(readFileSync8(canonicalPath, "utf-8"));
3195
+ merged = parseLearningMemory(readFileSync9(canonicalPath, "utf-8"));
2642
3196
  } catch {
2643
3197
  merged = createEmptyLearningMemory("unknown");
2644
3198
  }
@@ -2648,7 +3202,7 @@ function aggregateLearningMemoryAt(projDir) {
2648
3202
  for (const sidecarPath of listLearningMemorySidecarPathsAt(projDir)) {
2649
3203
  let sidecar;
2650
3204
  try {
2651
- sidecar = parseLearningMemory(readFileSync8(sidecarPath, "utf-8"));
3205
+ sidecar = parseLearningMemory(readFileSync9(sidecarPath, "utf-8"));
2652
3206
  } catch {
2653
3207
  continue;
2654
3208
  }
@@ -2955,12 +3509,12 @@ var exports_reflect = {};
2955
3509
  __export(exports_reflect, {
2956
3510
  reflect: () => reflect
2957
3511
  });
2958
- import { existsSync as existsSync9 } from "fs";
3512
+ import { existsSync as existsSync13 } from "fs";
2959
3513
  import { dirname as dirname3 } from "path";
2960
3514
  function reflect(_cwd, memoryPath, configPath2) {
2961
3515
  const projDir = dirname3(memoryPath);
2962
3516
  const mem = aggregateLearningMemoryAt(projDir);
2963
- if (totalEntryCount(mem) === 0 && !existsSync9(memoryPath)) {
3517
+ if (totalEntryCount(mem) === 0 && !existsSync13(memoryPath)) {
2964
3518
  console.log("[mink] no learning memory found");
2965
3519
  return null;
2966
3520
  }
@@ -3019,10 +3573,11 @@ __export(exports_paths2, {
3019
3573
  actionLogShardPath: () => actionLogShardPath2,
3020
3574
  actionLogPath: () => actionLogPath2
3021
3575
  });
3022
- import { join as join11 } from "path";
3576
+ import { join as join13 } from "path";
3577
+ import { existsSync as existsSync15 } from "fs";
3023
3578
  import { homedir as homedir3 } from "os";
3024
3579
  function resolveMinkRoot2() {
3025
- return process.env.MINK_ROOT_OVERRIDE || join11(homedir3(), ".mink");
3580
+ return process.env.MINK_ROOT_OVERRIDE || join13(homedir3(), ".mink");
3026
3581
  }
3027
3582
  function minkRoot2() {
3028
3583
  if (process.env.MINK_ROOT_OVERRIDE) {
@@ -3031,104 +3586,113 @@ function minkRoot2() {
3031
3586
  return MINK_ROOT2;
3032
3587
  }
3033
3588
  function projectDir2(cwd) {
3034
- const id = generateProjectId(cwd);
3035
- return join11(minkRoot2(), "projects", id);
3589
+ const id = projectIdFor(cwd);
3590
+ const primary = join13(minkRoot2(), "projects", id);
3591
+ if (existsSync15(primary))
3592
+ return primary;
3593
+ try {
3594
+ const { findProjectDirByIdOrAlias: findProjectDirByIdOrAlias2 } = (init_project_registry(), __toCommonJS(exports_project_registry));
3595
+ const aliased = findProjectDirByIdOrAlias2(id);
3596
+ if (aliased)
3597
+ return aliased;
3598
+ } catch {}
3599
+ return primary;
3036
3600
  }
3037
3601
  function sessionPath2(cwd) {
3038
- return join11(projectDir2(cwd), "session.json");
3602
+ return join13(projectDir2(cwd), "session.json");
3039
3603
  }
3040
3604
  function fileIndexPath2(cwd) {
3041
- return join11(projectDir2(cwd), "file-index.json");
3605
+ return join13(projectDir2(cwd), "file-index.json");
3042
3606
  }
3043
3607
  function configPath2(cwd) {
3044
- return join11(projectDir2(cwd), "config.json");
3608
+ return join13(projectDir2(cwd), "config.json");
3045
3609
  }
3046
3610
  function learningMemoryPath2(cwd) {
3047
- return join11(projectDir2(cwd), "learning-memory.md");
3611
+ return join13(projectDir2(cwd), "learning-memory.md");
3048
3612
  }
3049
3613
  function tokenLedgerPath2(cwd) {
3050
- return join11(projectDir2(cwd), "token-ledger.json");
3614
+ return join13(projectDir2(cwd), "token-ledger.json");
3051
3615
  }
3052
3616
  function tokenLedgerArchivePath2(cwd) {
3053
- return join11(projectDir2(cwd), "token-ledger-archive.json");
3617
+ return join13(projectDir2(cwd), "token-ledger-archive.json");
3054
3618
  }
3055
3619
  function bugMemoryPath2(cwd) {
3056
- return join11(projectDir2(cwd), "bug-memory.json");
3620
+ return join13(projectDir2(cwd), "bug-memory.json");
3057
3621
  }
3058
3622
  function actionLogPath2(cwd) {
3059
- return join11(projectDir2(cwd), "action-log.md");
3623
+ return join13(projectDir2(cwd), "action-log.md");
3060
3624
  }
3061
3625
  function schedulerPidPath2() {
3062
- return join11(minkRoot2(), "scheduler.pid");
3626
+ return join13(minkRoot2(), "scheduler.pid");
3063
3627
  }
3064
3628
  function schedulerLogPath2() {
3065
- return join11(minkRoot2(), "scheduler.log");
3629
+ return join13(minkRoot2(), "scheduler.log");
3066
3630
  }
3067
3631
  function schedulerManifestPath2(cwd) {
3068
- return join11(projectDir2(cwd), "scheduler-manifest.json");
3632
+ return join13(projectDir2(cwd), "scheduler-manifest.json");
3069
3633
  }
3070
3634
  function channelPidPath2() {
3071
- return join11(minkRoot2(), "channel.pid");
3635
+ return join13(minkRoot2(), "channel.pid");
3072
3636
  }
3073
3637
  function channelLogPath2() {
3074
- return join11(minkRoot2(), "channel.log");
3638
+ return join13(minkRoot2(), "channel.log");
3075
3639
  }
3076
3640
  function globalConfigPath2() {
3077
- return join11(minkRoot2(), "config");
3641
+ return join13(minkRoot2(), "config");
3078
3642
  }
3079
3643
  function localConfigPath2() {
3080
- return join11(minkRoot2(), "config.local");
3644
+ return join13(minkRoot2(), "config.local");
3081
3645
  }
3082
3646
  function deviceIdPath2() {
3083
- return join11(minkRoot2(), "device-id");
3647
+ return join13(minkRoot2(), "device-id");
3084
3648
  }
3085
3649
  function deviceRegistryPath2() {
3086
- return join11(minkRoot2(), "devices.json");
3650
+ return join13(minkRoot2(), "devices.json");
3087
3651
  }
3088
3652
  function projectMetaPath2(cwd) {
3089
- return join11(projectDir2(cwd), "project-meta.json");
3653
+ return join13(projectDir2(cwd), "project-meta.json");
3090
3654
  }
3091
3655
  function backupDirPath2(cwd) {
3092
- return join11(projectDir2(cwd), "backups");
3656
+ return join13(projectDir2(cwd), "backups");
3093
3657
  }
3094
3658
  function syncVersionPath2() {
3095
- return join11(minkRoot2(), ".mink-sync-version");
3659
+ return join13(minkRoot2(), ".mink-sync-version");
3096
3660
  }
3097
3661
  function projectStateDir2(cwd) {
3098
- return join11(projectDir2(cwd), "state");
3662
+ return join13(projectDir2(cwd), "state");
3099
3663
  }
3100
3664
  function deviceShardDir2(cwd, deviceId) {
3101
- return join11(projectStateDir2(cwd), deviceId);
3665
+ return join13(projectStateDir2(cwd), deviceId);
3102
3666
  }
3103
3667
  function tokenLedgerShardPath2(cwd, deviceId) {
3104
- return join11(deviceShardDir2(cwd, deviceId), "token-ledger.json");
3668
+ return join13(deviceShardDir2(cwd, deviceId), "token-ledger.json");
3105
3669
  }
3106
3670
  function tokenLedgerArchiveShardPath2(cwd, deviceId) {
3107
- return join11(deviceShardDir2(cwd, deviceId), "token-ledger-archive.json");
3671
+ return join13(deviceShardDir2(cwd, deviceId), "token-ledger-archive.json");
3108
3672
  }
3109
3673
  function bugMemoryShardPath2(cwd, deviceId) {
3110
- return join11(deviceShardDir2(cwd, deviceId), "bug-memory.json");
3674
+ return join13(deviceShardDir2(cwd, deviceId), "bug-memory.json");
3111
3675
  }
3112
3676
  function actionLogShardPath2(cwd, deviceId) {
3113
- return join11(deviceShardDir2(cwd, deviceId), "action-log.md");
3677
+ return join13(deviceShardDir2(cwd, deviceId), "action-log.md");
3114
3678
  }
3115
3679
  function learningMemorySidecarPath2(cwd, deviceId) {
3116
- return join11(projectDir2(cwd), `learning-memory.${deviceId}.md`);
3680
+ return join13(projectDir2(cwd), `learning-memory.${deviceId}.md`);
3117
3681
  }
3118
3682
  function fileIndexCountersPath3(cwd) {
3119
- return join11(projectDir2(cwd), ".mink-state-counters.json");
3683
+ return join13(projectDir2(cwd), ".mink-state-counters.json");
3120
3684
  }
3121
3685
  function designCapturesDir2(cwd) {
3122
- return join11(projectDir2(cwd), "design-captures");
3686
+ return join13(projectDir2(cwd), "design-captures");
3123
3687
  }
3124
3688
  function designReportPath2(cwd) {
3125
- return join11(projectDir2(cwd), "design-report.json");
3689
+ return join13(projectDir2(cwd), "design-report.json");
3126
3690
  }
3127
3691
  function frameworkAdvisorPath2(cwd) {
3128
- return join11(projectDir2(cwd), "framework-advisor.md");
3692
+ return join13(projectDir2(cwd), "framework-advisor.md");
3129
3693
  }
3130
3694
  function frameworkAdvisorJsonPath2(cwd) {
3131
- return join11(projectDir2(cwd), "framework-advisor.json");
3695
+ return join13(projectDir2(cwd), "framework-advisor.json");
3132
3696
  }
3133
3697
  var MINK_ROOT2;
3134
3698
  var init_paths2 = __esm(() => {
@@ -3145,13 +3709,13 @@ __export(exports_backup, {
3145
3709
  });
3146
3710
  import {
3147
3711
  mkdirSync as mkdirSync6,
3148
- readdirSync as readdirSync5,
3149
- readFileSync as readFileSync10,
3712
+ readdirSync as readdirSync6,
3713
+ readFileSync as readFileSync11,
3150
3714
  writeFileSync as writeFileSync5,
3151
- existsSync as existsSync11,
3715
+ existsSync as existsSync16,
3152
3716
  statSync as statSync6
3153
3717
  } from "fs";
3154
- import { join as join12 } from "path";
3718
+ import { join as join14 } from "path";
3155
3719
  function formatTimestamp(date) {
3156
3720
  const y = date.getFullYear();
3157
3721
  const mo = String(date.getMonth() + 1).padStart(2, "0");
@@ -3164,14 +3728,14 @@ function formatTimestamp(date) {
3164
3728
  }
3165
3729
  function copyDirectoryFiles(srcDir, destDir, excludeDirs) {
3166
3730
  mkdirSync6(destDir, { recursive: true });
3167
- const entries = readdirSync5(srcDir, { withFileTypes: true });
3731
+ const entries = readdirSync6(srcDir, { withFileTypes: true });
3168
3732
  for (const entry of entries) {
3169
3733
  if (entry.isDirectory()) {
3170
3734
  if (excludeDirs.includes(entry.name))
3171
3735
  continue;
3172
- copyDirectoryFiles(join12(srcDir, entry.name), join12(destDir, entry.name), excludeDirs);
3736
+ copyDirectoryFiles(join14(srcDir, entry.name), join14(destDir, entry.name), excludeDirs);
3173
3737
  } else if (entry.isFile()) {
3174
- writeFileSync5(join12(destDir, entry.name), readFileSync10(join12(srcDir, entry.name)));
3738
+ writeFileSync5(join14(destDir, entry.name), readFileSync11(join14(srcDir, entry.name)));
3175
3739
  }
3176
3740
  }
3177
3741
  }
@@ -3180,25 +3744,25 @@ function createBackup(cwd) {
3180
3744
  const dir = backupDirPath(cwd);
3181
3745
  let name = base;
3182
3746
  let suffix = 1;
3183
- while (existsSync11(join12(dir, name))) {
3747
+ while (existsSync16(join14(dir, name))) {
3184
3748
  name = `${base}-${suffix}`;
3185
3749
  suffix++;
3186
3750
  }
3187
3751
  const src = projectDir(cwd);
3188
- const dest = join12(dir, name);
3752
+ const dest = join14(dir, name);
3189
3753
  copyDirectoryFiles(src, dest, ["backups"]);
3190
3754
  return name;
3191
3755
  }
3192
3756
  function listBackups(cwd) {
3193
3757
  const dir = backupDirPath(cwd);
3194
- if (!existsSync11(dir))
3758
+ if (!existsSync16(dir))
3195
3759
  return [];
3196
- const entries = readdirSync5(dir, { withFileTypes: true });
3760
+ const entries = readdirSync6(dir, { withFileTypes: true });
3197
3761
  const backups = [];
3198
3762
  for (const entry of entries) {
3199
3763
  if (!entry.isDirectory() || !entry.name.startsWith("backup-"))
3200
3764
  continue;
3201
- const backupPath = join12(dir, entry.name);
3765
+ const backupPath = join14(dir, entry.name);
3202
3766
  const match = entry.name.match(/^backup-(\d{4})(\d{2})(\d{2})-(\d{2})(\d{2})(\d{2})(\d{3})?(?:-\d+)?$/);
3203
3767
  let timestamp;
3204
3768
  if (match) {
@@ -3208,7 +3772,7 @@ function listBackups(cwd) {
3208
3772
  }
3209
3773
  let fileCount = 0;
3210
3774
  try {
3211
- fileCount = readdirSync5(backupPath).length;
3775
+ fileCount = readdirSync6(backupPath).length;
3212
3776
  } catch {}
3213
3777
  backups.push({ name: entry.name, timestamp, path: backupPath, fileCount });
3214
3778
  }
@@ -3221,8 +3785,8 @@ function listBackups(cwd) {
3221
3785
  return backups;
3222
3786
  }
3223
3787
  function restoreBackup(cwd, backupName) {
3224
- const backupPath = join12(backupDirPath(cwd), backupName);
3225
- if (!existsSync11(backupPath)) {
3788
+ const backupPath = join14(backupDirPath(cwd), backupName);
3789
+ if (!existsSync16(backupPath)) {
3226
3790
  throw new Error(`backup not found: ${backupName}`);
3227
3791
  }
3228
3792
  createBackup(cwd);
@@ -3233,8 +3797,8 @@ var init_backup = __esm(() => {
3233
3797
  });
3234
3798
 
3235
3799
  // src/core/scanner.ts
3236
- import { readdirSync as readdirSync6, statSync as statSync7 } from "fs";
3237
- import { join as join13, relative } from "path";
3800
+ import { readdirSync as readdirSync7, statSync as statSync7 } from "fs";
3801
+ import { join as join15, relative } from "path";
3238
3802
  function matchesPattern(name, pattern) {
3239
3803
  if (pattern.includes("*")) {
3240
3804
  const regex = new RegExp("^" + pattern.replace(/\./g, "\\.").replace(/\*/g, ".*") + "$");
@@ -3248,7 +3812,7 @@ function isExcluded(name, excludes) {
3248
3812
  function walkDirectory(dir, projectRoot, excludes, results) {
3249
3813
  let entries;
3250
3814
  try {
3251
- entries = readdirSync6(dir, { withFileTypes: true });
3815
+ entries = readdirSync7(dir, { withFileTypes: true });
3252
3816
  } catch {
3253
3817
  return;
3254
3818
  }
@@ -3258,14 +3822,14 @@ function walkDirectory(dir, projectRoot, excludes, results) {
3258
3822
  if (entry.isDirectory()) {
3259
3823
  if (isExcluded(entry.name, excludes))
3260
3824
  continue;
3261
- walkDirectory(join13(dir, entry.name), projectRoot, excludes, results);
3825
+ walkDirectory(join15(dir, entry.name), projectRoot, excludes, results);
3262
3826
  continue;
3263
3827
  }
3264
3828
  if (entry.isFile()) {
3265
3829
  if (isExcluded(entry.name, excludes))
3266
3830
  continue;
3267
3831
  try {
3268
- const fullPath = join13(dir, entry.name);
3832
+ const fullPath = join15(dir, entry.name);
3269
3833
  const stat = statSync7(fullPath);
3270
3834
  results.push({
3271
3835
  relativePath: relative(projectRoot, fullPath),
@@ -3591,8 +4155,8 @@ var exports_scan = {};
3591
4155
  __export(exports_scan, {
3592
4156
  scan: () => scan
3593
4157
  });
3594
- import { readFileSync as readFileSync11 } from "fs";
3595
- import { join as join14, relative as relative2 } from "path";
4158
+ import { readFileSync as readFileSync12 } from "fs";
4159
+ import { join as join16, relative as relative2 } from "path";
3596
4160
  function configRelativePath(cfgPath, cwd) {
3597
4161
  const rel = relative2(cwd, cfgPath);
3598
4162
  return rel.startsWith("..") ? cfgPath : rel;
@@ -3647,10 +4211,10 @@ function scan(cwd, options) {
3647
4211
  newIndex.header.lifetimeHits = index.header.lifetimeHits;
3648
4212
  newIndex.header.lifetimeMisses = index.header.lifetimeMisses;
3649
4213
  for (const file of scanned) {
3650
- const fullPath = join14(cwd, file.relativePath);
4214
+ const fullPath = join16(cwd, file.relativePath);
3651
4215
  let content;
3652
4216
  try {
3653
- content = readFileSync11(fullPath, "utf-8");
4217
+ content = readFileSync12(fullPath, "utf-8");
3654
4218
  } catch {
3655
4219
  continue;
3656
4220
  }
@@ -3691,13 +4255,13 @@ __export(exports_seed, {
3691
4255
  parseGoMod: () => parseGoMod,
3692
4256
  parseCargoToml: () => parseCargoToml
3693
4257
  });
3694
- import { basename as basename4, join as join15 } from "path";
3695
- import { readFileSync as readFileSync12, existsSync as existsSync12 } from "fs";
4258
+ import { basename as basename4, join as join17 } from "path";
4259
+ import { readFileSync as readFileSync13, existsSync as existsSync17 } from "fs";
3696
4260
  function readFile(filePath) {
3697
- if (!existsSync12(filePath))
4261
+ if (!existsSync17(filePath))
3698
4262
  return null;
3699
4263
  try {
3700
- return readFileSync12(filePath, "utf-8");
4264
+ return readFileSync13(filePath, "utf-8");
3701
4265
  } catch {
3702
4266
  return null;
3703
4267
  }
@@ -3787,10 +4351,10 @@ function parseGoMod(filePath) {
3787
4351
  }
3788
4352
  function seedLearningMemory(projectRoot) {
3789
4353
  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"))
4354
+ () => parsePackageJson(join17(projectRoot, "package.json")),
4355
+ () => parsePyprojectToml(join17(projectRoot, "pyproject.toml")),
4356
+ () => parseCargoToml(join17(projectRoot, "Cargo.toml")),
4357
+ () => parseGoMod(join17(projectRoot, "go.mod"))
3794
4358
  ];
3795
4359
  const infos = parsers.map((fn) => fn()).filter((info) => info !== null);
3796
4360
  const projectName = infos.find((i) => i.projectName)?.projectName ?? basename4(projectRoot);
@@ -3874,12 +4438,12 @@ __export(exports_init, {
3874
4438
  detectRuntime: () => detectRuntime,
3875
4439
  buildHooksConfig: () => buildHooksConfig
3876
4440
  });
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";
4441
+ import { execSync as execSync5 } from "child_process";
4442
+ import { mkdirSync as mkdirSync7, existsSync as existsSync18 } from "fs";
4443
+ import { resolve as resolve2, dirname as dirname5, basename as basename5, join as join18 } from "path";
3880
4444
  function detectRuntime() {
3881
4445
  try {
3882
- execSync4("bun --version", { stdio: "ignore" });
4446
+ execSync5("bun --version", { stdio: "ignore" });
3883
4447
  return "bun";
3884
4448
  } catch {
3885
4449
  return "node";
@@ -3892,8 +4456,8 @@ function resolveCliPath() {
3892
4456
  return selfPath;
3893
4457
  }
3894
4458
  const projectRoot = resolve2(selfDir, "../..");
3895
- const distPath = join16(projectRoot, "dist", "cli.js");
3896
- if (existsSync13(distPath))
4459
+ const distPath = join18(projectRoot, "dist", "cli.js");
4460
+ if (existsSync18(distPath))
3897
4461
  return distPath;
3898
4462
  return resolve2(selfDir, "../cli.ts");
3899
4463
  }
@@ -3953,9 +4517,9 @@ function mergeHooksIntoSettings(settingsPath, newHooks) {
3953
4517
  }
3954
4518
  function isExistingInstallation(cwd) {
3955
4519
  const dir = projectDir(cwd);
3956
- if (!existsSync13(dir))
4520
+ if (!existsSync18(dir))
3957
4521
  return false;
3958
- return existsSync13(join16(dir, "file-index.json"));
4522
+ return existsSync18(join18(dir, "file-index.json"));
3959
4523
  }
3960
4524
  async function init(cwd) {
3961
4525
  const runtime = detectRuntime();
@@ -3973,16 +4537,20 @@ async function init(cwd) {
3973
4537
  mergeHooksIntoSettings(settingsPath, hooks);
3974
4538
  const rulePath = writeMinkRule(cwd);
3975
4539
  mkdirSync7(dir, { recursive: true });
3976
- const projectId = generateProjectId(cwd);
4540
+ const identity = resolveProjectIdentity(cwd);
4541
+ const projectId = identity.id;
3977
4542
  const isNotesProject = isWikiEnabled() && isVaultInitialized() && isInsideVault(cwd);
3978
4543
  const metaPath = projectMetaPath(cwd);
3979
4544
  const existingMeta = safeReadJson(metaPath);
4545
+ const deviceId = getOrCreateDeviceId();
4546
+ const existingPathsByDevice = existingMeta?.pathsByDevice && typeof existingMeta.pathsByDevice === "object" && !Array.isArray(existingMeta.pathsByDevice) ? existingMeta.pathsByDevice : {};
3980
4547
  atomicWriteJson(metaPath, {
3981
4548
  ...existingMeta ?? {},
3982
4549
  cwd,
3983
4550
  name: basename5(cwd),
3984
4551
  initTimestamp: existingMeta?.initTimestamp ?? new Date().toISOString(),
3985
4552
  version: "0.1.0",
4553
+ pathsByDevice: { ...existingPathsByDevice, [deviceId]: cwd },
3986
4554
  ...isNotesProject ? { projectType: "notes" } : {}
3987
4555
  });
3988
4556
  if (upgrading) {
@@ -3992,17 +4560,23 @@ async function init(cwd) {
3992
4560
  console.log(` rule: ${rulePath}`);
3993
4561
  } else {
3994
4562
  console.log(`[mink] initialized`);
3995
- console.log(` project: ${projectId}`);
4563
+ console.log(` project: ${projectId} (${identity.source})`);
3996
4564
  console.log(` state: ${dir}`);
3997
4565
  console.log(` runtime: ${runtime}`);
3998
4566
  console.log(` hooks: ${settingsPath}`);
3999
4567
  console.log(` rule: ${rulePath}`);
4000
4568
  }
4569
+ if (identity.source === "path-derived") {
4570
+ const root = getRepoRoot(cwd);
4571
+ if (root && !getRepoRemote(cwd)) {
4572
+ 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\`.`);
4573
+ }
4574
+ }
4001
4575
  const { scan: scan2 } = await Promise.resolve().then(() => (init_scan(), exports_scan));
4002
4576
  scan2(cwd, { check: false });
4003
4577
  const { learningMemoryPath: learningMemoryPath3 } = await Promise.resolve().then(() => (init_paths(), exports_paths));
4004
4578
  const memPath = learningMemoryPath3(cwd);
4005
- if (!existsSync13(memPath)) {
4579
+ if (!existsSync18(memPath)) {
4006
4580
  const { seedLearningMemory: seedLearningMemory2 } = await Promise.resolve().then(() => (init_seed(), exports_seed));
4007
4581
  const { serializeLearningMemory: serializeLearningMemory2 } = await Promise.resolve().then(() => (init_learning_memory(), exports_learning_memory));
4008
4582
  const mem = seedLearningMemory2(cwd);
@@ -4011,8 +4585,8 @@ async function init(cwd) {
4011
4585
  if (isWikiEnabled() && isVaultInitialized() && !isNotesProject) {
4012
4586
  try {
4013
4587
  const projectSlug = basename5(cwd);
4014
- const overviewPath = join16(vaultProjects(projectSlug), "overview.md");
4015
- if (!existsSync13(overviewPath)) {
4588
+ const overviewPath = join18(vaultProjects(projectSlug), "overview.md");
4589
+ if (!existsSync18(overviewPath)) {
4016
4590
  const now = new Date().toISOString();
4017
4591
  const overview = [
4018
4592
  `---`,
@@ -4061,6 +4635,8 @@ var init_init = __esm(() => {
4061
4635
  init_paths();
4062
4636
  init_project_id();
4063
4637
  init_fs_utils();
4638
+ init_device();
4639
+ init_git_identity();
4064
4640
  init_vault();
4065
4641
  });
4066
4642
 
@@ -4099,12 +4675,12 @@ var init_state_counters = __esm(() => {
4099
4675
  });
4100
4676
 
4101
4677
  // 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";
4678
+ import { join as join19 } from "path";
4679
+ import { existsSync as existsSync19, writeFileSync as writeFileSync6, mkdirSync as mkdirSync8 } from "fs";
4104
4680
  function writeCompanionClaudeMd(vaultPath, overwrite = false) {
4105
4681
  mkdirSync8(vaultPath, { recursive: true });
4106
- const claudeMdPath = join17(vaultPath, "CLAUDE.md");
4107
- if (existsSync14(claudeMdPath) && !overwrite) {
4682
+ const claudeMdPath = join19(vaultPath, "CLAUDE.md");
4683
+ if (existsSync19(claudeMdPath) && !overwrite) {
4108
4684
  return false;
4109
4685
  }
4110
4686
  writeFileSync6(claudeMdPath, COMPANION_CLAUDE_MD);
@@ -4256,12 +4832,12 @@ mink wiki rebuild-index
4256
4832
  var init_channel_templates = () => {};
4257
4833
 
4258
4834
  // 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";
4835
+ import { readFileSync as readFileSync14, writeFileSync as writeFileSync7, unlinkSync as unlinkSync3, mkdirSync as mkdirSync9, existsSync as existsSync20 } from "fs";
4836
+ import { dirname as dirname6, join as join20 } from "path";
4261
4837
  import { spawnSync } from "child_process";
4262
4838
  function readChannelPidFile() {
4263
4839
  try {
4264
- const raw = readFileSync13(channelPidPath(), "utf-8");
4840
+ const raw = readFileSync14(channelPidPath(), "utf-8");
4265
4841
  const data = JSON.parse(raw);
4266
4842
  if (data && typeof data.session === "string" && typeof data.platform === "string" && typeof data.startedAt === "string" && typeof data.vaultPath === "string") {
4267
4843
  return data;
@@ -4403,18 +4979,18 @@ function getChannelLogs() {
4403
4979
  return null;
4404
4980
  if (!screenSessionExists(pidData.session))
4405
4981
  return null;
4406
- const tmpPath = join18(minkRoot(), `.channel-capture-${Date.now()}-${process.pid}.txt`);
4982
+ const tmpPath = join20(minkRoot(), `.channel-capture-${Date.now()}-${process.pid}.txt`);
4407
4983
  const result = spawnSync("screen", ["-S", pidData.session, "-X", "hardcopy", "-h", tmpPath], { stdio: "ignore" });
4408
4984
  if (result.status !== 0)
4409
4985
  return null;
4410
4986
  for (let i = 0;i < 20; i++) {
4411
- if (existsSync15(tmpPath))
4987
+ if (existsSync20(tmpPath))
4412
4988
  break;
4413
4989
  const delayUntil = Date.now() + 50;
4414
4990
  while (Date.now() < delayUntil) {}
4415
4991
  }
4416
4992
  try {
4417
- const content = readFileSync13(tmpPath, "utf-8");
4993
+ const content = readFileSync14(tmpPath, "utf-8");
4418
4994
  try {
4419
4995
  unlinkSync3(tmpPath);
4420
4996
  } catch {}
@@ -4588,12 +5164,12 @@ var init_runtime = __esm(() => {
4588
5164
  });
4589
5165
 
4590
5166
  // src/core/daemon.ts
4591
- import { readFileSync as readFileSync14, writeFileSync as writeFileSync8, unlinkSync as unlinkSync4, openSync } from "fs";
5167
+ import { readFileSync as readFileSync15, writeFileSync as writeFileSync8, unlinkSync as unlinkSync4, openSync } from "fs";
4592
5168
  import { mkdirSync as mkdirSync10 } from "fs";
4593
5169
  import { dirname as dirname7, resolve as resolve3 } from "path";
4594
5170
  function readPidFile() {
4595
5171
  try {
4596
- const raw = readFileSync14(schedulerPidPath(), "utf-8");
5172
+ const raw = readFileSync15(schedulerPidPath(), "utf-8");
4597
5173
  const data = JSON.parse(raw);
4598
5174
  if (data && typeof data.pid === "number" && typeof data.startedAt === "string" && typeof data.projectCwd === "string") {
4599
5175
  return data;
@@ -4747,9 +5323,9 @@ var exports_status = {};
4747
5323
  __export(exports_status, {
4748
5324
  status: () => status
4749
5325
  });
4750
- import { existsSync as existsSync17, readFileSync as readFileSync15, statSync as statSync8 } from "fs";
5326
+ import { existsSync as existsSync22, readFileSync as readFileSync16, statSync as statSync8 } from "fs";
4751
5327
  function checkJsonFile(name, filePath, validator) {
4752
- if (!existsSync17(filePath))
5328
+ if (!existsSync22(filePath))
4753
5329
  return { name, path: filePath, status: "missing" };
4754
5330
  const data = safeReadJson(filePath);
4755
5331
  if (data === null)
@@ -4759,10 +5335,10 @@ function checkJsonFile(name, filePath, validator) {
4759
5335
  return { name, path: filePath, status: "ok" };
4760
5336
  }
4761
5337
  function checkTextFile(name, filePath) {
4762
- if (!existsSync17(filePath))
5338
+ if (!existsSync22(filePath))
4763
5339
  return { name, path: filePath, status: "missing" };
4764
5340
  try {
4765
- readFileSync15(filePath, "utf-8");
5341
+ readFileSync16(filePath, "utf-8");
4766
5342
  return { name, path: filePath, status: "ok" };
4767
5343
  } catch {
4768
5344
  return { name, path: filePath, status: "corrupt" };
@@ -4836,7 +5412,7 @@ function status(cwd) {
4836
5412
  console.log(` Decision Log: ${mem.sections["Decision Log"].length}`);
4837
5413
  console.log(` Total entries: ${total}`);
4838
5414
  const memPath = learningMemoryPath(cwd);
4839
- if (existsSync17(memPath)) {
5415
+ if (existsSync22(memPath)) {
4840
5416
  const mtime = statSync8(memPath).mtime;
4841
5417
  console.log(` Canonical last modified: ${mtime.toISOString()}`);
4842
5418
  }
@@ -4881,8 +5457,8 @@ var exports_scan2 = {};
4881
5457
  __export(exports_scan2, {
4882
5458
  scan: () => scan2
4883
5459
  });
4884
- import { readFileSync as readFileSync16 } from "fs";
4885
- import { join as join19, relative as relative3 } from "path";
5460
+ import { readFileSync as readFileSync17 } from "fs";
5461
+ import { join as join21, relative as relative3 } from "path";
4886
5462
  function configRelativePath2(cfgPath, cwd) {
4887
5463
  const rel = relative3(cwd, cfgPath);
4888
5464
  return rel.startsWith("..") ? cfgPath : rel;
@@ -4937,10 +5513,10 @@ function scan2(cwd, options) {
4937
5513
  newIndex.header.lifetimeHits = index.header.lifetimeHits;
4938
5514
  newIndex.header.lifetimeMisses = index.header.lifetimeMisses;
4939
5515
  for (const file of scanned) {
4940
- const fullPath = join19(cwd, file.relativePath);
5516
+ const fullPath = join21(cwd, file.relativePath);
4941
5517
  let content;
4942
5518
  try {
4943
- content = readFileSync16(fullPath, "utf-8");
5519
+ content = readFileSync17(fullPath, "utf-8");
4944
5520
  } catch {
4945
5521
  continue;
4946
5522
  }
@@ -4977,12 +5553,12 @@ var exports_reflect2 = {};
4977
5553
  __export(exports_reflect2, {
4978
5554
  reflect: () => reflect2
4979
5555
  });
4980
- import { existsSync as existsSync18 } from "fs";
5556
+ import { existsSync as existsSync23 } from "fs";
4981
5557
  import { dirname as dirname8 } from "path";
4982
5558
  function reflect2(_cwd, memoryPath, configPath3) {
4983
5559
  const projDir = dirname8(memoryPath);
4984
5560
  const mem = aggregateLearningMemoryAt(projDir);
4985
- if (totalEntryCount(mem) === 0 && !existsSync18(memoryPath)) {
5561
+ if (totalEntryCount(mem) === 0 && !existsSync23(memoryPath)) {
4986
5562
  console.log("[mink] no learning memory found");
4987
5563
  return null;
4988
5564
  }
@@ -5380,7 +5956,7 @@ __export(exports_post_write, {
5380
5956
  analyzePostWrite: () => analyzePostWrite
5381
5957
  });
5382
5958
  import { relative as relative7 } from "path";
5383
- import { readFileSync as readFileSync17 } from "fs";
5959
+ import { readFileSync as readFileSync18 } from "fs";
5384
5960
  function analyzePostWrite(filePath, fileContent, index) {
5385
5961
  if (isWriteExcluded(filePath)) {
5386
5962
  return {
@@ -5444,7 +6020,7 @@ async function postWrite(cwd) {
5444
6020
  const filePath = relative7(cwd, absolutePath);
5445
6021
  let fileContent = null;
5446
6022
  try {
5447
- fileContent = readFileSync17(absolutePath, "utf-8");
6023
+ fileContent = readFileSync18(absolutePath, "utf-8");
5448
6024
  } catch {}
5449
6025
  const rawState = safeReadJson(sessionPath(cwd));
5450
6026
  const state = isSessionState(rawState) ? rawState : createSessionState();
@@ -5806,9 +6382,9 @@ __export(exports_self_update, {
5806
6382
  PACKAGE_NAME: () => PACKAGE_NAME
5807
6383
  });
5808
6384
  import { spawnSync as spawnSync2 } from "child_process";
5809
- import { existsSync as existsSync19, readFileSync as readFileSync18 } from "fs";
6385
+ import { existsSync as existsSync24, readFileSync as readFileSync19 } from "fs";
5810
6386
  import { dirname as dirname9 } from "path";
5811
- import { join as join20 } from "path";
6387
+ import { join as join22 } from "path";
5812
6388
  function parseSemver(input) {
5813
6389
  const trimmed = input.trim().replace(/^v/, "");
5814
6390
  if (!trimmed)
@@ -5858,8 +6434,8 @@ function getInstallInfo() {
5858
6434
  let dir = dirname9(selfPath);
5859
6435
  let packageJsonPath = null;
5860
6436
  for (let i = 0;i < 10; i++) {
5861
- const candidate = join20(dir, "package.json");
5862
- if (existsSync19(candidate)) {
6437
+ const candidate = join22(dir, "package.json");
6438
+ if (existsSync24(candidate)) {
5863
6439
  packageJsonPath = candidate;
5864
6440
  break;
5865
6441
  }
@@ -5873,7 +6449,7 @@ function getInstallInfo() {
5873
6449
  }
5874
6450
  let currentVersion = "0.0.0";
5875
6451
  try {
5876
- const pkg = JSON.parse(readFileSync18(packageJsonPath, "utf-8"));
6452
+ const pkg = JSON.parse(readFileSync19(packageJsonPath, "utf-8"));
5877
6453
  if (typeof pkg.version === "string")
5878
6454
  currentVersion = pkg.version;
5879
6455
  } catch {}
@@ -5933,7 +6509,7 @@ function buildInstallCommand(pm, version) {
5933
6509
  return ["npm", "install", "-g", ref];
5934
6510
  }
5935
6511
  function selfUpdateLogPath() {
5936
- return join20(minkRoot(), "self-update.log");
6512
+ return join22(minkRoot(), "self-update.log");
5937
6513
  }
5938
6514
  function appendLogEntry(entry) {
5939
6515
  const path = selfUpdateLogPath();
@@ -5946,7 +6522,7 @@ function appendLogEntry(entry) {
5946
6522
  }
5947
6523
  function rotateLogIfNeeded(path) {
5948
6524
  try {
5949
- const content = readFileSync18(path, "utf-8");
6525
+ const content = readFileSync19(path, "utf-8");
5950
6526
  const lines = content.split(`
5951
6527
  `);
5952
6528
  if (lines.length <= LOG_MAX_LINES + 1)
@@ -6049,7 +6625,7 @@ async function runSelfUpgradeInner(opts) {
6049
6625
  }
6050
6626
  let verifiedVersion = latest;
6051
6627
  try {
6052
- const pkg = JSON.parse(readFileSync18(info.packageJsonPath, "utf-8"));
6628
+ const pkg = JSON.parse(readFileSync19(info.packageJsonPath, "utf-8"));
6053
6629
  if (typeof pkg.version === "string")
6054
6630
  verifiedVersion = pkg.version;
6055
6631
  } catch {}
@@ -6155,10 +6731,10 @@ async function executeTask(taskId, projectCwd) {
6155
6731
  if (task.actionType === "ai-cli") {
6156
6732
  try {
6157
6733
  const { learningMemoryPath: learningMemoryPath5 } = await Promise.resolve().then(() => (init_paths(), exports_paths));
6158
- const { readFileSync: readFileSync19 } = await import("fs");
6734
+ const { readFileSync: readFileSync20 } = await import("fs");
6159
6735
  let memoryContent;
6160
6736
  try {
6161
- memoryContent = readFileSync19(learningMemoryPath5(projectCwd), "utf-8");
6737
+ memoryContent = readFileSync20(learningMemoryPath5(projectCwd), "utf-8");
6162
6738
  } catch {
6163
6739
  console.log("[mink] no learning memory found, skipping reflection");
6164
6740
  return;
@@ -6722,22 +7298,22 @@ var init_cron = __esm(() => {
6722
7298
  });
6723
7299
 
6724
7300
  // 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";
7301
+ import { join as join23 } from "path";
7302
+ import { existsSync as existsSync25, writeFileSync as writeFileSync9, readFileSync as readFileSync20, mkdirSync as mkdirSync11 } from "fs";
6727
7303
  function seedTemplates(templatesDir) {
6728
7304
  mkdirSync11(templatesDir, { recursive: true });
6729
7305
  for (const [name, content] of Object.entries(DEFAULT_TEMPLATES)) {
6730
- const filePath = join21(templatesDir, `${name}.md`);
6731
- if (!existsSync20(filePath)) {
7306
+ const filePath = join23(templatesDir, `${name}.md`);
7307
+ if (!existsSync25(filePath)) {
6732
7308
  writeFileSync9(filePath, content);
6733
7309
  }
6734
7310
  }
6735
7311
  }
6736
7312
  function loadTemplate(templatesDir, templateName, vars) {
6737
- const filePath = join21(templatesDir, `${templateName}.md`);
7313
+ const filePath = join23(templatesDir, `${templateName}.md`);
6738
7314
  let content;
6739
- if (existsSync20(filePath)) {
6740
- content = readFileSync19(filePath, "utf-8");
7315
+ if (existsSync25(filePath)) {
7316
+ content = readFileSync20(filePath, "utf-8");
6741
7317
  } else if (DEFAULT_TEMPLATES[templateName]) {
6742
7318
  content = DEFAULT_TEMPLATES[templateName];
6743
7319
  } else {
@@ -6890,33 +7466,33 @@ category: resources
6890
7466
  });
6891
7467
 
6892
7468
  // src/core/note-writer.ts
6893
- import { join as join22 } from "path";
6894
- import { existsSync as existsSync21, readFileSync as readFileSync20 } from "fs";
7469
+ import { join as join24 } from "path";
7470
+ import { existsSync as existsSync26, readFileSync as readFileSync21 } from "fs";
6895
7471
  import { createHash as createHash2 } from "crypto";
6896
7472
  function sha256(content) {
6897
7473
  return createHash2("sha256").update(content).digest("hex");
6898
7474
  }
6899
7475
  function resolveUniqueNotePath(dir, baseSlug, content) {
6900
7476
  const targetHash = sha256(content);
6901
- const primary = join22(dir, `${baseSlug}.md`);
6902
- if (!existsSync21(primary))
7477
+ const primary = join24(dir, `${baseSlug}.md`);
7478
+ if (!existsSync26(primary))
6903
7479
  return primary;
6904
7480
  if (sameContent(primary, targetHash))
6905
7481
  return primary;
6906
7482
  const dev4 = getOrCreateDeviceId().replace(/-/g, "").slice(0, 4);
6907
7483
  for (let i = 0;i < MAX_COLLISION_ATTEMPTS; i++) {
6908
7484
  const suffix = i === 0 ? dev4 : `${dev4}-${i + 1}`;
6909
- const candidate = join22(dir, `${baseSlug}-${suffix}.md`);
6910
- if (!existsSync21(candidate))
7485
+ const candidate = join24(dir, `${baseSlug}-${suffix}.md`);
7486
+ if (!existsSync26(candidate))
6911
7487
  return candidate;
6912
7488
  if (sameContent(candidate, targetHash))
6913
7489
  return candidate;
6914
7490
  }
6915
- return join22(dir, `${baseSlug}-${Date.now()}.md`);
7491
+ return join24(dir, `${baseSlug}-${Date.now()}.md`);
6916
7492
  }
6917
7493
  function sameContent(filePath, expectedHash) {
6918
7494
  try {
6919
- return sha256(readFileSync20(filePath, "utf-8")) === expectedHash;
7495
+ return sha256(readFileSync21(filePath, "utf-8")) === expectedHash;
6920
7496
  } catch {
6921
7497
  return false;
6922
7498
  }
@@ -6987,8 +7563,8 @@ ${meta.body}
6987
7563
  }
6988
7564
  function appendToDaily(date, content) {
6989
7565
  const dir = vaultDailyDir();
6990
- const filePath = join22(dir, `${date}.md`);
6991
- if (existsSync21(filePath)) {
7566
+ const filePath = join24(dir, `${date}.md`);
7567
+ if (existsSync26(filePath)) {
6992
7568
  const timestamp = new Date().toLocaleTimeString("en-US", {
6993
7569
  hour: "2-digit",
6994
7570
  minute: "2-digit",
@@ -7025,7 +7601,7 @@ ${content}
7025
7601
  return filePath;
7026
7602
  }
7027
7603
  function ingestFile(sourcePath, meta) {
7028
- const raw = readFileSync20(sourcePath, "utf-8");
7604
+ const raw = readFileSync21(sourcePath, "utf-8");
7029
7605
  const now = new Date().toISOString();
7030
7606
  const headingMatch = raw.match(/^#\s+(.+)$/m);
7031
7607
  const title = headingMatch?.[1] ?? sourcePath.split("/").pop().replace(/\.md$/, "");
@@ -7097,10 +7673,10 @@ var init_design_eval = __esm(() => {
7097
7673
  });
7098
7674
 
7099
7675
  // 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";
7676
+ import { existsSync as existsSync27, readFileSync as readFileSync22 } from "fs";
7677
+ import { readdirSync as readdirSync8, readFileSync as readFileSyncFS, existsSync as fsExistsSync } from "fs";
7678
+ import { join as join25, resolve as resolve5, normalize, sep } from "path";
7679
+ import { execSync as execSync6 } from "child_process";
7104
7680
  function isSecretKey(key) {
7105
7681
  return SECRET_KEY_PATTERNS.some((re) => re.test(key));
7106
7682
  }
@@ -7112,7 +7688,7 @@ function maskSecret(value, showLast = 4) {
7112
7688
  return "••••" + value.slice(-showLast);
7113
7689
  }
7114
7690
  function checkJsonFile2(name, filePath, validator) {
7115
- if (!existsSync22(filePath))
7691
+ if (!existsSync27(filePath))
7116
7692
  return { name, status: "missing" };
7117
7693
  const data = safeReadJson(filePath);
7118
7694
  if (data === null)
@@ -7122,10 +7698,10 @@ function checkJsonFile2(name, filePath, validator) {
7122
7698
  return { name, status: "ok" };
7123
7699
  }
7124
7700
  function checkTextFile2(name, filePath) {
7125
- if (!existsSync22(filePath))
7701
+ if (!existsSync27(filePath))
7126
7702
  return { name, status: "missing" };
7127
7703
  try {
7128
- readFileSync21(filePath, "utf-8");
7704
+ readFileSync22(filePath, "utf-8");
7129
7705
  return { name, status: "ok" };
7130
7706
  } catch {
7131
7707
  return { name, status: "corrupt" };
@@ -7297,7 +7873,7 @@ function getAheadBehind(branch) {
7297
7873
  if (!branch)
7298
7874
  return { ahead: 0, behind: 0 };
7299
7875
  try {
7300
- const raw = execSync5(`git rev-list --left-right --count origin/${branch}...${branch}`, { cwd: minkRoot(), timeout: 5000, stdio: ["pipe", "pipe", "pipe"] }).toString().trim();
7876
+ const raw = execSync6(`git rev-list --left-right --count origin/${branch}...${branch}`, { cwd: minkRoot(), timeout: 5000, stdio: ["pipe", "pipe", "pipe"] }).toString().trim();
7301
7877
  const [behindStr, aheadStr] = raw.split(/\s+/);
7302
7878
  return {
7303
7879
  behind: Number(behindStr) || 0,
@@ -7309,7 +7885,7 @@ function getAheadBehind(branch) {
7309
7885
  }
7310
7886
  function getPendingChanges() {
7311
7887
  try {
7312
- const raw = execSync5("git status --porcelain", {
7888
+ const raw = execSync6("git status --porcelain", {
7313
7889
  cwd: minkRoot(),
7314
7890
  timeout: 5000,
7315
7891
  stdio: ["pipe", "pipe", "pipe"]
@@ -7378,10 +7954,10 @@ function loadChannelPanel() {
7378
7954
  function countMarkdownIn(dir) {
7379
7955
  let count = 0;
7380
7956
  try {
7381
- for (const entry of readdirSync7(dir, { withFileTypes: true })) {
7957
+ for (const entry of readdirSync8(dir, { withFileTypes: true })) {
7382
7958
  if (WIKI_TREE_EXCLUDES.has(entry.name) || entry.name.startsWith("."))
7383
7959
  continue;
7384
- const fullPath = join23(dir, entry.name);
7960
+ const fullPath = join25(dir, entry.name);
7385
7961
  if (entry.isDirectory()) {
7386
7962
  count += countMarkdownIn(fullPath);
7387
7963
  } else if (entry.name.endsWith(".md") && !entry.name.startsWith("_")) {
@@ -7398,7 +7974,7 @@ function buildVaultTree(root) {
7398
7974
  return;
7399
7975
  let entries = [];
7400
7976
  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() }));
7977
+ 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
7978
  } catch {
7403
7979
  return;
7404
7980
  }
@@ -7410,7 +7986,7 @@ function buildVaultTree(root) {
7410
7986
  for (const entry of entries) {
7411
7987
  if (!entry.isDir)
7412
7988
  continue;
7413
- const fullPath = join23(dir, entry.name);
7989
+ const fullPath = join25(dir, entry.name);
7414
7990
  const relPath = fullPath.slice(root.length + 1);
7415
7991
  const count = countMarkdownIn(fullPath);
7416
7992
  nodes.push({ name: entry.name, path: relPath, count, depth });
@@ -7833,7 +8409,7 @@ async function triggerIngestFile(sourcePath, category, tags, dedupKey) {
7833
8409
  if (!isValidCategory(category)) {
7834
8410
  return { success: false, error: `Invalid category: ${category}` };
7835
8411
  }
7836
- const expanded = sourcePath.startsWith("~/") ? join23(process.env.HOME ?? "", sourcePath.slice(2)) : sourcePath;
8412
+ const expanded = sourcePath.startsWith("~/") ? join25(process.env.HOME ?? "", sourcePath.slice(2)) : sourcePath;
7837
8413
  if (!fsExistsSync(expanded)) {
7838
8414
  return { success: false, error: `Source file not found: ${sourcePath}` };
7839
8415
  }
@@ -7912,61 +8488,14 @@ var init_dashboard_api = __esm(() => {
7912
8488
  dedupCache = new Map;
7913
8489
  });
7914
8490
 
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
8491
  // src/core/dashboard-server.ts
7963
8492
  var exports_dashboard_server = {};
7964
8493
  __export(exports_dashboard_server, {
7965
8494
  startDashboardServer: () => startDashboardServer
7966
8495
  });
7967
8496
  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";
8497
+ import { existsSync as existsSync28 } from "fs";
8498
+ import { basename as basename7, dirname as dirname10, join as join26, extname as extname2 } from "path";
7970
8499
 
7971
8500
  class SSEManager {
7972
8501
  clients = new Map;
@@ -8027,18 +8556,18 @@ function resolveProjectCwd(url, defaultCwd) {
8027
8556
  const projectId = url.searchParams.get("project");
8028
8557
  if (!projectId)
8029
8558
  return defaultCwd;
8030
- if (projectId === generateProjectId(defaultCwd))
8559
+ if (projectId === projectIdFor(defaultCwd))
8031
8560
  return defaultCwd;
8032
8561
  const projects = listRegisteredProjects();
8033
- const match = projects.find((p) => p.id === projectId);
8562
+ const match = projects.find((p) => p.id === projectId) ?? projects.find((p) => p.aliases.includes(projectId));
8034
8563
  if (!match)
8035
8564
  return null;
8036
8565
  return match.cwd;
8037
8566
  }
8038
8567
  function getProjectsList(startupCwd, activeCwd) {
8039
- const activeId = generateProjectId(activeCwd);
8568
+ const activeId = projectIdFor(activeCwd);
8040
8569
  const registered = listRegisteredProjects();
8041
- const startupId = generateProjectId(startupCwd);
8570
+ const startupId = projectIdFor(startupCwd);
8042
8571
  const hasStartup = registered.some((p) => p.id === startupId);
8043
8572
  if (!hasStartup) {
8044
8573
  const meta = getProjectMeta(projectDir(startupCwd));
@@ -8046,7 +8575,9 @@ function getProjectsList(startupCwd, activeCwd) {
8046
8575
  id: startupId,
8047
8576
  cwd: startupCwd,
8048
8577
  name: meta?.name ?? basename7(startupCwd),
8049
- version: meta?.version ?? "0.1.0"
8578
+ version: meta?.version ?? "0.1.0",
8579
+ aliases: meta?.aliases ?? [],
8580
+ pathsByDevice: meta?.pathsByDevice ?? {}
8050
8581
  });
8051
8582
  }
8052
8583
  if (activeId !== startupId) {
@@ -8057,7 +8588,9 @@ function getProjectsList(startupCwd, activeCwd) {
8057
8588
  id: activeId,
8058
8589
  cwd: activeCwd,
8059
8590
  name: meta?.name ?? basename7(activeCwd),
8060
- version: meta?.version ?? "0.1.0"
8591
+ version: meta?.version ?? "0.1.0",
8592
+ aliases: meta?.aliases ?? [],
8593
+ pathsByDevice: meta?.pathsByDevice ?? {}
8061
8594
  });
8062
8595
  }
8063
8596
  }
@@ -8142,12 +8675,12 @@ async function startDashboardServer(cwd, options = {}) {
8142
8675
  const __dir = dirname10(new URL(import.meta.url).pathname);
8143
8676
  let pkgRoot = __dir;
8144
8677
  while (pkgRoot !== dirname10(pkgRoot)) {
8145
- if (existsSync24(join25(pkgRoot, "package.json")))
8678
+ if (existsSync28(join26(pkgRoot, "package.json")))
8146
8679
  break;
8147
8680
  pkgRoot = dirname10(pkgRoot);
8148
8681
  }
8149
- const dashboardOutDir = join25(pkgRoot, "dashboard", "out");
8150
- const dashboardBuilt = existsSync24(join25(dashboardOutDir, "index.html"));
8682
+ const dashboardOutDir = join26(pkgRoot, "dashboard", "out");
8683
+ const dashboardBuilt = existsSync28(join26(dashboardOutDir, "index.html"));
8151
8684
  let clientIdCounter = 0;
8152
8685
  if (!dashboardBuilt) {
8153
8686
  console.warn("[mink] dashboard not built. Run: cd dashboard && bun run build");
@@ -8177,9 +8710,9 @@ async function startDashboardServer(cwd, options = {}) {
8177
8710
  } else {
8178
8711
  let filePath;
8179
8712
  if (pathname === "/") {
8180
- filePath = join25(dashboardOutDir, "index.html");
8713
+ filePath = join26(dashboardOutDir, "index.html");
8181
8714
  } else {
8182
- filePath = join25(dashboardOutDir, pathname);
8715
+ filePath = join26(dashboardOutDir, pathname);
8183
8716
  }
8184
8717
  if (!filePath.startsWith(dashboardOutDir)) {
8185
8718
  return jsonResponse({ error: "Forbidden" }, 403);
@@ -8192,7 +8725,7 @@ async function startDashboardServer(cwd, options = {}) {
8192
8725
  const htmlServed = await serveFile(filePath + ".html", "text/html; charset=utf-8");
8193
8726
  if (htmlServed)
8194
8727
  return htmlServed;
8195
- const indexServed = await serveFile(join25(dashboardOutDir, "index.html"), "text/html; charset=utf-8");
8728
+ const indexServed = await serveFile(join26(dashboardOutDir, "index.html"), "text/html; charset=utf-8");
8196
8729
  if (indexServed)
8197
8730
  return indexServed;
8198
8731
  }
@@ -8301,7 +8834,7 @@ retry: 3000
8301
8834
  if (!filename || filename.includes("..") || filename.includes("/")) {
8302
8835
  return jsonResponse({ error: "Invalid filename" }, 400);
8303
8836
  }
8304
- const imgPath = join25(designCapturesDir(resolvedCwd), filename);
8837
+ const imgPath = join26(designCapturesDir(resolvedCwd), filename);
8305
8838
  const served = await serveFile(imgPath, "image/jpeg");
8306
8839
  if (served) {
8307
8840
  served.headers.set("Cache-Control", "public, max-age=60");
@@ -8535,9 +9068,9 @@ var exports_dashboard = {};
8535
9068
  __export(exports_dashboard, {
8536
9069
  dashboard: () => dashboard
8537
9070
  });
8538
- import { existsSync as existsSync25 } from "fs";
9071
+ import { existsSync as existsSync29 } from "fs";
8539
9072
  async function dashboard(cwd, args) {
8540
- if (!existsSync25(projectDir(cwd))) {
9073
+ if (!existsSync29(projectDir(cwd))) {
8541
9074
  console.error("[mink] project not initialized. Run: mink init");
8542
9075
  process.exit(1);
8543
9076
  }
@@ -8555,8 +9088,8 @@ var init_dashboard = __esm(() => {
8555
9088
  });
8556
9089
 
8557
9090
  // 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";
9091
+ import { mkdirSync as mkdirSync12, existsSync as existsSync30 } from "fs";
9092
+ import { resolve as resolve6, dirname as dirname11, basename as basename8, join as join27 } from "path";
8560
9093
  function resolveCliPath2() {
8561
9094
  const selfPath = new URL(import.meta.url).pathname;
8562
9095
  const selfDir = dirname11(selfPath);
@@ -8564,8 +9097,8 @@ function resolveCliPath2() {
8564
9097
  return selfPath;
8565
9098
  }
8566
9099
  const projectRoot = resolve6(selfDir, "../..");
8567
- const distPath = join26(projectRoot, "dist", "cli.js");
8568
- if (existsSync26(distPath))
9100
+ const distPath = join27(projectRoot, "dist", "cli.js");
9101
+ if (existsSync30(distPath))
8569
9102
  return distPath;
8570
9103
  return resolve6(selfDir, "../cli.ts");
8571
9104
  }
@@ -8621,14 +9154,16 @@ var init_init2 = __esm(() => {
8621
9154
  init_paths();
8622
9155
  init_project_id();
8623
9156
  init_fs_utils();
9157
+ init_device();
9158
+ init_git_identity();
8624
9159
  init_vault();
8625
9160
  });
8626
9161
 
8627
9162
  // 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";
9163
+ import { execSync as execSync7 } from "child_process";
9164
+ import { existsSync as existsSync31, mkdirSync as mkdirSync13, unlinkSync as unlinkSync5, writeFileSync as writeFileSync10 } from "fs";
8630
9165
  import { homedir as homedir4 } from "os";
8631
- import { dirname as dirname12, join as join27 } from "path";
9166
+ import { dirname as dirname12, join as join28 } from "path";
8632
9167
  function detectPlatform() {
8633
9168
  if (process.platform === "linux")
8634
9169
  return "systemd";
@@ -8638,7 +9173,7 @@ function detectPlatform() {
8638
9173
  }
8639
9174
  function resolveServiceInvocation() {
8640
9175
  const entry = process.argv[1];
8641
- if (entry && !/\.(js|ts|mjs|cjs)$/.test(entry) && existsSync27(entry)) {
9176
+ if (entry && !/\.(js|ts|mjs|cjs)$/.test(entry) && existsSync31(entry)) {
8642
9177
  return {
8643
9178
  executable: entry,
8644
9179
  args: ["daemon", "start"],
@@ -8656,11 +9191,11 @@ function resolveServiceInvocation() {
8656
9191
  function servicePaths(platform2) {
8657
9192
  const home = homedir4();
8658
9193
  if (platform2 === "systemd") {
8659
- const unitDir2 = join27(home, ".config", "systemd", "user");
8660
- return { unitDir: unitDir2, unitFile: join27(unitDir2, "mink-daemon.service") };
9194
+ const unitDir2 = join28(home, ".config", "systemd", "user");
9195
+ return { unitDir: unitDir2, unitFile: join28(unitDir2, "mink-daemon.service") };
8661
9196
  }
8662
- const unitDir = join27(home, "Library", "LaunchAgents");
8663
- return { unitDir, unitFile: join27(unitDir, "com.mink.daemon.plist") };
9197
+ const unitDir = join28(home, "Library", "LaunchAgents");
9198
+ return { unitDir, unitFile: join28(unitDir, "com.mink.daemon.plist") };
8664
9199
  }
8665
9200
  function renderSystemdUnit(inv) {
8666
9201
  const execStart = [inv.executable, ...inv.args].join(" ");
@@ -8734,7 +9269,7 @@ function installService(options = {}) {
8734
9269
  process.exit(1);
8735
9270
  }
8736
9271
  const paths = servicePaths(platform2);
8737
- if (existsSync27(paths.unitFile) && !options.force) {
9272
+ if (existsSync31(paths.unitFile) && !options.force) {
8738
9273
  console.error(`[mink] unit file already exists: ${paths.unitFile}`);
8739
9274
  console.error(" re-run with --force to overwrite, or run `mink daemon uninstall` first");
8740
9275
  process.exit(1);
@@ -8744,7 +9279,7 @@ function installService(options = {}) {
8744
9279
  if (platform2 === "systemd") {
8745
9280
  writeFileSync10(paths.unitFile, renderSystemdUnit(inv));
8746
9281
  try {
8747
- execSync6("systemctl --user daemon-reload", { stdio: "ignore" });
9282
+ execSync7("systemctl --user daemon-reload", { stdio: "ignore" });
8748
9283
  } catch {}
8749
9284
  console.log(`[mink] wrote ${paths.unitFile}`);
8750
9285
  console.log("[mink] next steps:");
@@ -8767,24 +9302,24 @@ function uninstallService() {
8767
9302
  process.exit(1);
8768
9303
  }
8769
9304
  const paths = servicePaths(platform2);
8770
- if (!existsSync27(paths.unitFile)) {
9305
+ if (!existsSync31(paths.unitFile)) {
8771
9306
  console.log(`[mink] no unit file at ${paths.unitFile} — nothing to uninstall`);
8772
9307
  return;
8773
9308
  }
8774
9309
  if (platform2 === "systemd") {
8775
9310
  try {
8776
- execSync6("systemctl --user disable --now mink-daemon.service", {
9311
+ execSync7("systemctl --user disable --now mink-daemon.service", {
8777
9312
  stdio: "ignore"
8778
9313
  });
8779
9314
  } catch {}
8780
9315
  unlinkSync5(paths.unitFile);
8781
9316
  try {
8782
- execSync6("systemctl --user daemon-reload", { stdio: "ignore" });
9317
+ execSync7("systemctl --user daemon-reload", { stdio: "ignore" });
8783
9318
  } catch {}
8784
9319
  console.log(`[mink] removed ${paths.unitFile}`);
8785
9320
  } else {
8786
9321
  try {
8787
- execSync6(`launchctl unload -w ${paths.unitFile}`, { stdio: "ignore" });
9322
+ execSync7(`launchctl unload -w ${paths.unitFile}`, { stdio: "ignore" });
8788
9323
  } catch {}
8789
9324
  unlinkSync5(paths.unitFile);
8790
9325
  console.log(`[mink] removed ${paths.unitFile}`);
@@ -8799,7 +9334,7 @@ var exports_daemon = {};
8799
9334
  __export(exports_daemon, {
8800
9335
  daemon: () => daemon
8801
9336
  });
8802
- import { readFileSync as readFileSync22, existsSync as existsSync28 } from "fs";
9337
+ import { readFileSync as readFileSync23, existsSync as existsSync32 } from "fs";
8803
9338
  async function daemon(cwd, args) {
8804
9339
  const subcommand = args[0];
8805
9340
  switch (subcommand) {
@@ -8815,12 +9350,12 @@ async function daemon(cwd, args) {
8815
9350
  break;
8816
9351
  case "logs": {
8817
9352
  const logPath = schedulerLogPath();
8818
- if (!existsSync28(logPath)) {
9353
+ if (!existsSync32(logPath)) {
8819
9354
  console.log("[mink] no log file found");
8820
9355
  return;
8821
9356
  }
8822
9357
  try {
8823
- const content = readFileSync22(logPath, "utf-8");
9358
+ const content = readFileSync23(logPath, "utf-8");
8824
9359
  const lines = content.split(`
8825
9360
  `);
8826
9361
  const tail = lines.slice(-50).join(`
@@ -9401,8 +9936,8 @@ var init_restore = __esm(() => {
9401
9936
  });
9402
9937
 
9403
9938
  // src/core/design-eval/server-detect.ts
9404
- import { readFileSync as readFileSync23 } from "fs";
9405
- import { join as join28 } from "path";
9939
+ import { readFileSync as readFileSync24 } from "fs";
9940
+ import { join as join29 } from "path";
9406
9941
  async function probePort(port) {
9407
9942
  try {
9408
9943
  const controller = new AbortController;
@@ -9424,7 +9959,7 @@ async function findRunningServer(ports = DEFAULT_PROBE_PORTS) {
9424
9959
  }
9425
9960
  function detectDevCommand(cwd) {
9426
9961
  try {
9427
- const raw = readFileSync23(join28(cwd, "package.json"), "utf-8");
9962
+ const raw = readFileSync24(join29(cwd, "package.json"), "utf-8");
9428
9963
  const pkg = JSON.parse(raw);
9429
9964
  const scripts = pkg.scripts;
9430
9965
  if (!scripts || typeof scripts !== "object")
@@ -9444,10 +9979,10 @@ var init_server_detect = __esm(() => {
9444
9979
  });
9445
9980
 
9446
9981
  // 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";
9982
+ import { existsSync as existsSync33, readdirSync as readdirSync9, statSync as statSync11 } from "fs";
9983
+ import { join as join30, relative as relative8, sep as sep2 } from "path";
9449
9984
  function detectFramework(cwd) {
9450
- const has = (name) => ["js", "mjs", "ts", "cjs"].some((ext) => existsSync29(join29(cwd, `${name}.${ext}`))) || existsSync29(join29(cwd, name));
9985
+ const has = (name) => ["js", "mjs", "ts", "cjs"].some((ext) => existsSync33(join30(cwd, `${name}.${ext}`))) || existsSync33(join30(cwd, name));
9451
9986
  if (has("next.config"))
9452
9987
  return "nextjs";
9453
9988
  if (has("svelte.config"))
@@ -9472,8 +10007,8 @@ function detectRoutes(cwd) {
9472
10007
  }
9473
10008
  function detectNextRoutes(cwd) {
9474
10009
  const routes = [];
9475
- const appDir = join29(cwd, "app");
9476
- if (existsSync29(appDir)) {
10010
+ const appDir = join30(cwd, "app");
10011
+ if (existsSync33(appDir)) {
9477
10012
  const pageFiles = findFiles(appDir, /^page\.(tsx?|jsx?)$/);
9478
10013
  for (const file of pageFiles) {
9479
10014
  const rel = relative8(appDir, file);
@@ -9484,8 +10019,8 @@ function detectNextRoutes(cwd) {
9484
10019
  routes.push(route);
9485
10020
  }
9486
10021
  }
9487
- const pagesDir = join29(cwd, "pages");
9488
- if (existsSync29(pagesDir)) {
10022
+ const pagesDir = join30(cwd, "pages");
10023
+ if (existsSync33(pagesDir)) {
9489
10024
  const pageFiles = findFiles(pagesDir, /\.(tsx?|jsx?)$/);
9490
10025
  for (const file of pageFiles) {
9491
10026
  const rel = relative8(pagesDir, file);
@@ -9504,8 +10039,8 @@ function detectNextRoutes(cwd) {
9504
10039
  return unique.length > 0 ? unique.sort() : ["/"];
9505
10040
  }
9506
10041
  function detectSvelteKitRoutes(cwd) {
9507
- const routesDir = join29(cwd, "src", "routes");
9508
- if (!existsSync29(routesDir))
10042
+ const routesDir = join30(cwd, "src", "routes");
10043
+ if (!existsSync33(routesDir))
9509
10044
  return ["/"];
9510
10045
  const routes = [];
9511
10046
  const pageFiles = findFiles(routesDir, /^\+page\.svelte$/);
@@ -9520,8 +10055,8 @@ function detectSvelteKitRoutes(cwd) {
9520
10055
  return routes.length > 0 ? routes.sort() : ["/"];
9521
10056
  }
9522
10057
  function detectNuxtRoutes(cwd) {
9523
- const pagesDir = join29(cwd, "pages");
9524
- if (!existsSync29(pagesDir))
10058
+ const pagesDir = join30(cwd, "pages");
10059
+ if (!existsSync33(pagesDir))
9525
10060
  return ["/"];
9526
10061
  const routes = [];
9527
10062
  const vueFiles = findFiles(pagesDir, /\.vue$/);
@@ -9547,7 +10082,7 @@ function findFiles(dir, pattern) {
9547
10082
  for (const entry of entries) {
9548
10083
  if (entry.startsWith(".") || entry === "node_modules")
9549
10084
  continue;
9550
- const full = join29(current, entry);
10085
+ const full = join30(current, entry);
9551
10086
  try {
9552
10087
  const stat2 = statSync11(full);
9553
10088
  if (stat2.isDirectory()) {
@@ -58251,7 +58786,7 @@ var require_util2 = __commonJS((exports) => {
58251
58786
  return path;
58252
58787
  }
58253
58788
  exports.normalize = normalize2;
58254
- function join30(aRoot, aPath) {
58789
+ function join31(aRoot, aPath) {
58255
58790
  if (aRoot === "") {
58256
58791
  aRoot = ".";
58257
58792
  }
@@ -58283,7 +58818,7 @@ var require_util2 = __commonJS((exports) => {
58283
58818
  }
58284
58819
  return joined;
58285
58820
  }
58286
- exports.join = join30;
58821
+ exports.join = join31;
58287
58822
  exports.isAbsolute = function(aPath) {
58288
58823
  return aPath.charAt(0) === "/" || urlRegexp.test(aPath);
58289
58824
  };
@@ -58456,7 +58991,7 @@ var require_util2 = __commonJS((exports) => {
58456
58991
  parsed.path = parsed.path.substring(0, index + 1);
58457
58992
  }
58458
58993
  }
58459
- sourceURL = join30(urlGenerate(parsed), sourceURL);
58994
+ sourceURL = join31(urlGenerate(parsed), sourceURL);
58460
58995
  }
58461
58996
  return normalize2(sourceURL);
58462
58997
  }
@@ -60188,7 +60723,7 @@ var require_escodegen = __commonJS((exports) => {
60188
60723
  function noEmptySpace() {
60189
60724
  return space ? space : " ";
60190
60725
  }
60191
- function join30(left, right) {
60726
+ function join31(left, right) {
60192
60727
  var leftSource, rightSource, leftCharCode, rightCharCode;
60193
60728
  leftSource = toSourceNodeWhenNeeded(left).toString();
60194
60729
  if (leftSource.length === 0) {
@@ -60529,8 +61064,8 @@ var require_escodegen = __commonJS((exports) => {
60529
61064
  } else {
60530
61065
  result.push(that.generateExpression(stmt.left, Precedence.Call, E_TTT));
60531
61066
  }
60532
- result = join30(result, operator);
60533
- result = [join30(result, that.generateExpression(stmt.right, Precedence.Assignment, E_TTT)), ")"];
61067
+ result = join31(result, operator);
61068
+ result = [join31(result, that.generateExpression(stmt.right, Precedence.Assignment, E_TTT)), ")"];
60534
61069
  });
60535
61070
  result.push(this.maybeBlock(stmt.body, flags));
60536
61071
  return result;
@@ -60668,11 +61203,11 @@ var require_escodegen = __commonJS((exports) => {
60668
61203
  var result, fragment;
60669
61204
  result = ["class"];
60670
61205
  if (stmt.id) {
60671
- result = join30(result, this.generateExpression(stmt.id, Precedence.Sequence, E_TTT));
61206
+ result = join31(result, this.generateExpression(stmt.id, Precedence.Sequence, E_TTT));
60672
61207
  }
60673
61208
  if (stmt.superClass) {
60674
- fragment = join30("extends", this.generateExpression(stmt.superClass, Precedence.Unary, E_TTT));
60675
- result = join30(result, fragment);
61209
+ fragment = join31("extends", this.generateExpression(stmt.superClass, Precedence.Unary, E_TTT));
61210
+ result = join31(result, fragment);
60676
61211
  }
60677
61212
  result.push(space);
60678
61213
  result.push(this.generateStatement(stmt.body, S_TFFT));
@@ -60685,9 +61220,9 @@ var require_escodegen = __commonJS((exports) => {
60685
61220
  return escapeDirective(stmt.directive) + this.semicolon(flags);
60686
61221
  },
60687
61222
  DoWhileStatement: function(stmt, flags) {
60688
- var result = join30("do", this.maybeBlock(stmt.body, S_TFFF));
61223
+ var result = join31("do", this.maybeBlock(stmt.body, S_TFFF));
60689
61224
  result = this.maybeBlockSuffix(stmt.body, result);
60690
- return join30(result, [
61225
+ return join31(result, [
60691
61226
  "while" + space + "(",
60692
61227
  this.generateExpression(stmt.test, Precedence.Sequence, E_TTT),
60693
61228
  ")" + this.semicolon(flags)
@@ -60723,11 +61258,11 @@ var require_escodegen = __commonJS((exports) => {
60723
61258
  ExportDefaultDeclaration: function(stmt, flags) {
60724
61259
  var result = ["export"], bodyFlags;
60725
61260
  bodyFlags = flags & F_SEMICOLON_OPT ? S_TFFT : S_TFFF;
60726
- result = join30(result, "default");
61261
+ result = join31(result, "default");
60727
61262
  if (isStatement(stmt.declaration)) {
60728
- result = join30(result, this.generateStatement(stmt.declaration, bodyFlags));
61263
+ result = join31(result, this.generateStatement(stmt.declaration, bodyFlags));
60729
61264
  } else {
60730
- result = join30(result, this.generateExpression(stmt.declaration, Precedence.Assignment, E_TTT) + this.semicolon(flags));
61265
+ result = join31(result, this.generateExpression(stmt.declaration, Precedence.Assignment, E_TTT) + this.semicolon(flags));
60731
61266
  }
60732
61267
  return result;
60733
61268
  },
@@ -60735,15 +61270,15 @@ var require_escodegen = __commonJS((exports) => {
60735
61270
  var result = ["export"], bodyFlags, that = this;
60736
61271
  bodyFlags = flags & F_SEMICOLON_OPT ? S_TFFT : S_TFFF;
60737
61272
  if (stmt.declaration) {
60738
- return join30(result, this.generateStatement(stmt.declaration, bodyFlags));
61273
+ return join31(result, this.generateStatement(stmt.declaration, bodyFlags));
60739
61274
  }
60740
61275
  if (stmt.specifiers) {
60741
61276
  if (stmt.specifiers.length === 0) {
60742
- result = join30(result, "{" + space + "}");
61277
+ result = join31(result, "{" + space + "}");
60743
61278
  } else if (stmt.specifiers[0].type === Syntax.ExportBatchSpecifier) {
60744
- result = join30(result, this.generateExpression(stmt.specifiers[0], Precedence.Sequence, E_TTT));
61279
+ result = join31(result, this.generateExpression(stmt.specifiers[0], Precedence.Sequence, E_TTT));
60745
61280
  } else {
60746
- result = join30(result, "{");
61281
+ result = join31(result, "{");
60747
61282
  withIndent(function(indent2) {
60748
61283
  var i, iz;
60749
61284
  result.push(newline);
@@ -60761,7 +61296,7 @@ var require_escodegen = __commonJS((exports) => {
60761
61296
  result.push(base + "}");
60762
61297
  }
60763
61298
  if (stmt.source) {
60764
- result = join30(result, [
61299
+ result = join31(result, [
60765
61300
  "from" + space,
60766
61301
  this.generateExpression(stmt.source, Precedence.Sequence, E_TTT),
60767
61302
  this.semicolon(flags)
@@ -60845,7 +61380,7 @@ var require_escodegen = __commonJS((exports) => {
60845
61380
  ];
60846
61381
  cursor = 0;
60847
61382
  if (stmt.specifiers[cursor].type === Syntax.ImportDefaultSpecifier) {
60848
- result = join30(result, [
61383
+ result = join31(result, [
60849
61384
  this.generateExpression(stmt.specifiers[cursor], Precedence.Sequence, E_TTT)
60850
61385
  ]);
60851
61386
  ++cursor;
@@ -60855,7 +61390,7 @@ var require_escodegen = __commonJS((exports) => {
60855
61390
  result.push(",");
60856
61391
  }
60857
61392
  if (stmt.specifiers[cursor].type === Syntax.ImportNamespaceSpecifier) {
60858
- result = join30(result, [
61393
+ result = join31(result, [
60859
61394
  space,
60860
61395
  this.generateExpression(stmt.specifiers[cursor], Precedence.Sequence, E_TTT)
60861
61396
  ]);
@@ -60884,7 +61419,7 @@ var require_escodegen = __commonJS((exports) => {
60884
61419
  }
60885
61420
  }
60886
61421
  }
60887
- result = join30(result, [
61422
+ result = join31(result, [
60888
61423
  "from" + space,
60889
61424
  this.generateExpression(stmt.source, Precedence.Sequence, E_TTT),
60890
61425
  this.semicolon(flags)
@@ -60938,7 +61473,7 @@ var require_escodegen = __commonJS((exports) => {
60938
61473
  return result;
60939
61474
  },
60940
61475
  ThrowStatement: function(stmt, flags) {
60941
- return [join30("throw", this.generateExpression(stmt.argument, Precedence.Sequence, E_TTT)), this.semicolon(flags)];
61476
+ return [join31("throw", this.generateExpression(stmt.argument, Precedence.Sequence, E_TTT)), this.semicolon(flags)];
60942
61477
  },
60943
61478
  TryStatement: function(stmt, flags) {
60944
61479
  var result, i, iz, guardedHandlers;
@@ -60946,7 +61481,7 @@ var require_escodegen = __commonJS((exports) => {
60946
61481
  result = this.maybeBlockSuffix(stmt.block, result);
60947
61482
  if (stmt.handlers) {
60948
61483
  for (i = 0, iz = stmt.handlers.length;i < iz; ++i) {
60949
- result = join30(result, this.generateStatement(stmt.handlers[i], S_TFFF));
61484
+ result = join31(result, this.generateStatement(stmt.handlers[i], S_TFFF));
60950
61485
  if (stmt.finalizer || i + 1 !== iz) {
60951
61486
  result = this.maybeBlockSuffix(stmt.handlers[i].body, result);
60952
61487
  }
@@ -60954,7 +61489,7 @@ var require_escodegen = __commonJS((exports) => {
60954
61489
  } else {
60955
61490
  guardedHandlers = stmt.guardedHandlers || [];
60956
61491
  for (i = 0, iz = guardedHandlers.length;i < iz; ++i) {
60957
- result = join30(result, this.generateStatement(guardedHandlers[i], S_TFFF));
61492
+ result = join31(result, this.generateStatement(guardedHandlers[i], S_TFFF));
60958
61493
  if (stmt.finalizer || i + 1 !== iz) {
60959
61494
  result = this.maybeBlockSuffix(guardedHandlers[i].body, result);
60960
61495
  }
@@ -60962,13 +61497,13 @@ var require_escodegen = __commonJS((exports) => {
60962
61497
  if (stmt.handler) {
60963
61498
  if (Array.isArray(stmt.handler)) {
60964
61499
  for (i = 0, iz = stmt.handler.length;i < iz; ++i) {
60965
- result = join30(result, this.generateStatement(stmt.handler[i], S_TFFF));
61500
+ result = join31(result, this.generateStatement(stmt.handler[i], S_TFFF));
60966
61501
  if (stmt.finalizer || i + 1 !== iz) {
60967
61502
  result = this.maybeBlockSuffix(stmt.handler[i].body, result);
60968
61503
  }
60969
61504
  }
60970
61505
  } else {
60971
- result = join30(result, this.generateStatement(stmt.handler, S_TFFF));
61506
+ result = join31(result, this.generateStatement(stmt.handler, S_TFFF));
60972
61507
  if (stmt.finalizer) {
60973
61508
  result = this.maybeBlockSuffix(stmt.handler.body, result);
60974
61509
  }
@@ -60976,7 +61511,7 @@ var require_escodegen = __commonJS((exports) => {
60976
61511
  }
60977
61512
  }
60978
61513
  if (stmt.finalizer) {
60979
- result = join30(result, ["finally", this.maybeBlock(stmt.finalizer, S_TFFF)]);
61514
+ result = join31(result, ["finally", this.maybeBlock(stmt.finalizer, S_TFFF)]);
60980
61515
  }
60981
61516
  return result;
60982
61517
  },
@@ -61010,7 +61545,7 @@ var require_escodegen = __commonJS((exports) => {
61010
61545
  withIndent(function() {
61011
61546
  if (stmt.test) {
61012
61547
  result = [
61013
- join30("case", that.generateExpression(stmt.test, Precedence.Sequence, E_TTT)),
61548
+ join31("case", that.generateExpression(stmt.test, Precedence.Sequence, E_TTT)),
61014
61549
  ":"
61015
61550
  ];
61016
61551
  } else {
@@ -61058,9 +61593,9 @@ var require_escodegen = __commonJS((exports) => {
61058
61593
  result.push(this.maybeBlock(stmt.consequent, S_TFFF));
61059
61594
  result = this.maybeBlockSuffix(stmt.consequent, result);
61060
61595
  if (stmt.alternate.type === Syntax.IfStatement) {
61061
- result = join30(result, ["else ", this.generateStatement(stmt.alternate, bodyFlags)]);
61596
+ result = join31(result, ["else ", this.generateStatement(stmt.alternate, bodyFlags)]);
61062
61597
  } else {
61063
- result = join30(result, join30("else", this.maybeBlock(stmt.alternate, bodyFlags)));
61598
+ result = join31(result, join31("else", this.maybeBlock(stmt.alternate, bodyFlags)));
61064
61599
  }
61065
61600
  } else {
61066
61601
  result.push(this.maybeBlock(stmt.consequent, bodyFlags));
@@ -61162,7 +61697,7 @@ var require_escodegen = __commonJS((exports) => {
61162
61697
  },
61163
61698
  ReturnStatement: function(stmt, flags) {
61164
61699
  if (stmt.argument) {
61165
- return [join30("return", this.generateExpression(stmt.argument, Precedence.Sequence, E_TTT)), this.semicolon(flags)];
61700
+ return [join31("return", this.generateExpression(stmt.argument, Precedence.Sequence, E_TTT)), this.semicolon(flags)];
61166
61701
  }
61167
61702
  return ["return" + this.semicolon(flags)];
61168
61703
  },
@@ -61244,14 +61779,14 @@ var require_escodegen = __commonJS((exports) => {
61244
61779
  if (leftSource.charCodeAt(leftSource.length - 1) === 47 && esutils.code.isIdentifierPartES5(expr.operator.charCodeAt(0))) {
61245
61780
  result = [fragment, noEmptySpace(), expr.operator];
61246
61781
  } else {
61247
- result = join30(fragment, expr.operator);
61782
+ result = join31(fragment, expr.operator);
61248
61783
  }
61249
61784
  fragment = this.generateExpression(expr.right, rightPrecedence, flags);
61250
61785
  if (expr.operator === "/" && fragment.toString().charAt(0) === "/" || expr.operator.slice(-1) === "<" && fragment.toString().slice(0, 3) === "!--") {
61251
61786
  result.push(noEmptySpace());
61252
61787
  result.push(fragment);
61253
61788
  } else {
61254
- result = join30(result, fragment);
61789
+ result = join31(result, fragment);
61255
61790
  }
61256
61791
  if (expr.operator === "in" && !(flags & F_ALLOW_IN)) {
61257
61792
  return ["(", result, ")"];
@@ -61291,7 +61826,7 @@ var require_escodegen = __commonJS((exports) => {
61291
61826
  var result, length, i, iz, itemFlags;
61292
61827
  length = expr["arguments"].length;
61293
61828
  itemFlags = flags & F_ALLOW_UNPARATH_NEW && !parentheses && length === 0 ? E_TFT : E_TFF;
61294
- result = join30("new", this.generateExpression(expr.callee, Precedence.New, itemFlags));
61829
+ result = join31("new", this.generateExpression(expr.callee, Precedence.New, itemFlags));
61295
61830
  if (!(flags & F_ALLOW_UNPARATH_NEW) || parentheses || length > 0) {
61296
61831
  result.push("(");
61297
61832
  for (i = 0, iz = length;i < iz; ++i) {
@@ -61338,11 +61873,11 @@ var require_escodegen = __commonJS((exports) => {
61338
61873
  var result, fragment, rightCharCode, leftSource, leftCharCode;
61339
61874
  fragment = this.generateExpression(expr.argument, Precedence.Unary, E_TTT);
61340
61875
  if (space === "") {
61341
- result = join30(expr.operator, fragment);
61876
+ result = join31(expr.operator, fragment);
61342
61877
  } else {
61343
61878
  result = [expr.operator];
61344
61879
  if (expr.operator.length > 2) {
61345
- result = join30(result, fragment);
61880
+ result = join31(result, fragment);
61346
61881
  } else {
61347
61882
  leftSource = toSourceNodeWhenNeeded(result).toString();
61348
61883
  leftCharCode = leftSource.charCodeAt(leftSource.length - 1);
@@ -61365,12 +61900,12 @@ var require_escodegen = __commonJS((exports) => {
61365
61900
  result = "yield";
61366
61901
  }
61367
61902
  if (expr.argument) {
61368
- result = join30(result, this.generateExpression(expr.argument, Precedence.Yield, E_TTT));
61903
+ result = join31(result, this.generateExpression(expr.argument, Precedence.Yield, E_TTT));
61369
61904
  }
61370
61905
  return parenthesize(result, Precedence.Yield, precedence);
61371
61906
  },
61372
61907
  AwaitExpression: function(expr, precedence, flags) {
61373
- var result = join30(expr.all ? "await*" : "await", this.generateExpression(expr.argument, Precedence.Await, E_TTT));
61908
+ var result = join31(expr.all ? "await*" : "await", this.generateExpression(expr.argument, Precedence.Await, E_TTT));
61374
61909
  return parenthesize(result, Precedence.Await, precedence);
61375
61910
  },
61376
61911
  UpdateExpression: function(expr, precedence, flags) {
@@ -61442,11 +61977,11 @@ var require_escodegen = __commonJS((exports) => {
61442
61977
  var result, fragment;
61443
61978
  result = ["class"];
61444
61979
  if (expr.id) {
61445
- result = join30(result, this.generateExpression(expr.id, Precedence.Sequence, E_TTT));
61980
+ result = join31(result, this.generateExpression(expr.id, Precedence.Sequence, E_TTT));
61446
61981
  }
61447
61982
  if (expr.superClass) {
61448
- fragment = join30("extends", this.generateExpression(expr.superClass, Precedence.Unary, E_TTT));
61449
- result = join30(result, fragment);
61983
+ fragment = join31("extends", this.generateExpression(expr.superClass, Precedence.Unary, E_TTT));
61984
+ result = join31(result, fragment);
61450
61985
  }
61451
61986
  result.push(space);
61452
61987
  result.push(this.generateStatement(expr.body, S_TFFT));
@@ -61461,7 +61996,7 @@ var require_escodegen = __commonJS((exports) => {
61461
61996
  }
61462
61997
  if (expr.kind === "get" || expr.kind === "set") {
61463
61998
  fragment = [
61464
- join30(expr.kind, this.generatePropertyKey(expr.key, expr.computed)),
61999
+ join31(expr.kind, this.generatePropertyKey(expr.key, expr.computed)),
61465
62000
  this.generateFunctionBody(expr.value)
61466
62001
  ];
61467
62002
  } else {
@@ -61471,7 +62006,7 @@ var require_escodegen = __commonJS((exports) => {
61471
62006
  this.generateFunctionBody(expr.value)
61472
62007
  ];
61473
62008
  }
61474
- return join30(result, fragment);
62009
+ return join31(result, fragment);
61475
62010
  },
61476
62011
  Property: function(expr, precedence, flags) {
61477
62012
  if (expr.kind === "get" || expr.kind === "set") {
@@ -61665,7 +62200,7 @@ var require_escodegen = __commonJS((exports) => {
61665
62200
  for (i = 0, iz = expr.blocks.length;i < iz; ++i) {
61666
62201
  fragment = that.generateExpression(expr.blocks[i], Precedence.Sequence, E_TTT);
61667
62202
  if (i > 0 || extra.moz.comprehensionExpressionStartsWithAssignment) {
61668
- result = join30(result, fragment);
62203
+ result = join31(result, fragment);
61669
62204
  } else {
61670
62205
  result.push(fragment);
61671
62206
  }
@@ -61673,13 +62208,13 @@ var require_escodegen = __commonJS((exports) => {
61673
62208
  });
61674
62209
  }
61675
62210
  if (expr.filter) {
61676
- result = join30(result, "if" + space);
62211
+ result = join31(result, "if" + space);
61677
62212
  fragment = this.generateExpression(expr.filter, Precedence.Sequence, E_TTT);
61678
- result = join30(result, ["(", fragment, ")"]);
62213
+ result = join31(result, ["(", fragment, ")"]);
61679
62214
  }
61680
62215
  if (!extra.moz.comprehensionExpressionStartsWithAssignment) {
61681
62216
  fragment = this.generateExpression(expr.body, Precedence.Assignment, E_TTT);
61682
- result = join30(result, fragment);
62217
+ result = join31(result, fragment);
61683
62218
  }
61684
62219
  result.push(expr.type === Syntax.GeneratorExpression ? ")" : "]");
61685
62220
  return result;
@@ -61695,8 +62230,8 @@ var require_escodegen = __commonJS((exports) => {
61695
62230
  } else {
61696
62231
  fragment = this.generateExpression(expr.left, Precedence.Call, E_TTT);
61697
62232
  }
61698
- fragment = join30(fragment, expr.of ? "of" : "in");
61699
- fragment = join30(fragment, this.generateExpression(expr.right, Precedence.Sequence, E_TTT));
62233
+ fragment = join31(fragment, expr.of ? "of" : "in");
62234
+ fragment = join31(fragment, this.generateExpression(expr.right, Precedence.Sequence, E_TTT));
61700
62235
  return ["for" + space + "(", fragment, ")"];
61701
62236
  },
61702
62237
  SpreadElement: function(expr, precedence, flags) {
@@ -75401,7 +75936,7 @@ var init_httpUtil = __esm(() => {
75401
75936
  });
75402
75937
 
75403
75938
  // node_modules/@puppeteer/browsers/lib/esm/browser-data/chrome.js
75404
- import { execSync as execSync7 } from "node:child_process";
75939
+ import { execSync as execSync8 } from "node:child_process";
75405
75940
  import os from "node:os";
75406
75941
  import path from "node:path";
75407
75942
  function folder(platform2) {
@@ -75491,7 +76026,7 @@ function getChromeWindowsLocation(channel2, locationsPrefixes) {
75491
76026
  }
75492
76027
  function getWslVariable(variable) {
75493
76028
  try {
75494
- const result = execSync7(`cmd.exe /c echo %${variable.toLocaleUpperCase()}%`, {
76029
+ const result = execSync8(`cmd.exe /c echo %${variable.toLocaleUpperCase()}%`, {
75495
76030
  stdio: ["ignore", "pipe", "ignore"],
75496
76031
  encoding: "utf-8"
75497
76032
  }).trim();
@@ -75502,7 +76037,7 @@ function getWslVariable(variable) {
75502
76037
  return;
75503
76038
  }
75504
76039
  function getWslLocation(channel2) {
75505
- const wslVersion = execSync7("wslinfo --version", {
76040
+ const wslVersion = execSync8("wslinfo --version", {
75506
76041
  stdio: ["ignore", "pipe", "ignore"],
75507
76042
  encoding: "utf-8"
75508
76043
  }).trim();
@@ -75518,7 +76053,7 @@ function getWslLocation(channel2) {
75518
76053
  }
75519
76054
  const windowsPath = getChromeWindowsLocation(channel2, wslPrefixes);
75520
76055
  return windowsPath.map((path2) => {
75521
- return execSync7(`wslpath "${path2}"`).toString().trim();
76056
+ return execSync8(`wslpath "${path2}"`).toString().trim();
75522
76057
  });
75523
76058
  }
75524
76059
  function getChromeLinuxOrWslLocation(channel2) {
@@ -81793,7 +82328,7 @@ var init_fileUtil = __esm(() => {
81793
82328
  // node_modules/@puppeteer/browsers/lib/esm/install.js
81794
82329
  import assert2 from "node:assert";
81795
82330
  import { spawnSync as spawnSync4 } from "node:child_process";
81796
- import { existsSync as existsSync30, readFileSync as readFileSync24 } from "node:fs";
82331
+ import { existsSync as existsSync34, readFileSync as readFileSync25 } from "node:fs";
81797
82332
  import { mkdir as mkdir2, unlink } from "node:fs/promises";
81798
82333
  import os5 from "node:os";
81799
82334
  import path8 from "node:path";
@@ -81846,7 +82381,7 @@ async function installWithProviders(options) {
81846
82381
  continue;
81847
82382
  }
81848
82383
  debugInstall(`Successfully got URL from ${provider.getName()}: ${url}`);
81849
- if (!existsSync30(browserRoot)) {
82384
+ if (!existsSync34(browserRoot)) {
81850
82385
  await mkdir2(browserRoot, { recursive: true });
81851
82386
  }
81852
82387
  return await installUrl(url, options, provider);
@@ -81879,11 +82414,11 @@ async function installDeps(installedBrowser) {
81879
82414
  return;
81880
82415
  }
81881
82416
  const depsPath = path8.join(path8.dirname(installedBrowser.executablePath), "deb.deps");
81882
- if (!existsSync30(depsPath)) {
82417
+ if (!existsSync34(depsPath)) {
81883
82418
  debugInstall(`deb.deps file was not found at ${depsPath}`);
81884
82419
  return;
81885
82420
  }
81886
- const data = readFileSync24(depsPath, "utf-8").split(`
82421
+ const data = readFileSync25(depsPath, "utf-8").split(`
81887
82422
  `).join(",");
81888
82423
  if (process.getuid?.() !== 0) {
81889
82424
  throw new Error("Installing system dependencies requires root privileges");
@@ -81921,11 +82456,11 @@ async function installUrl(url, options, provider) {
81921
82456
  const cache = new Cache(options.cacheDir);
81922
82457
  const browserRoot = cache.browserRoot(options.browser);
81923
82458
  const archivePath = path8.join(browserRoot, `${options.buildId}-${fileName}`);
81924
- if (!existsSync30(browserRoot)) {
82459
+ if (!existsSync34(browserRoot)) {
81925
82460
  await mkdir2(browserRoot, { recursive: true });
81926
82461
  }
81927
82462
  if (!options.unpack) {
81928
- if (existsSync30(archivePath)) {
82463
+ if (existsSync34(archivePath)) {
81929
82464
  return archivePath;
81930
82465
  }
81931
82466
  debugInstall(`Downloading binary from ${url}`);
@@ -81946,8 +82481,8 @@ async function installUrl(url, options, provider) {
81946
82481
  cache.writeExecutablePath(options.browser, options.platform, options.buildId, relativeExecutablePath6);
81947
82482
  }
81948
82483
  try {
81949
- if (existsSync30(outputPath)) {
81950
- if (!existsSync30(installedBrowser.executablePath)) {
82484
+ if (existsSync34(outputPath)) {
82485
+ if (!existsSync34(installedBrowser.executablePath)) {
81951
82486
  throw new Error(`The browser folder (${outputPath}) exists but the executable (${installedBrowser.executablePath}) is missing`);
81952
82487
  }
81953
82488
  await runSetup(installedBrowser);
@@ -81956,7 +82491,7 @@ async function installUrl(url, options, provider) {
81956
82491
  }
81957
82492
  return installedBrowser;
81958
82493
  }
81959
- if (!existsSync30(archivePath)) {
82494
+ if (!existsSync34(archivePath)) {
81960
82495
  debugInstall(`Downloading binary from ${url}`);
81961
82496
  try {
81962
82497
  debugTime("download");
@@ -81985,7 +82520,7 @@ async function installUrl(url, options, provider) {
81985
82520
  }
81986
82521
  return installedBrowser;
81987
82522
  } finally {
81988
- if (existsSync30(archivePath)) {
82523
+ if (existsSync34(archivePath)) {
81989
82524
  await unlink(archivePath);
81990
82525
  }
81991
82526
  }
@@ -81996,7 +82531,7 @@ async function runSetup(installedBrowser) {
81996
82531
  debugTime("permissions");
81997
82532
  const browserDir = path8.dirname(installedBrowser.executablePath);
81998
82533
  const setupExePath = path8.join(browserDir, "setup.exe");
81999
- if (!existsSync30(setupExePath)) {
82534
+ if (!existsSync34(setupExePath)) {
82000
82535
  return;
82001
82536
  }
82002
82537
  spawnSync4(path8.join(browserDir, "setup.exe"), [`--configure-browser-in-directory=` + browserDir], {
@@ -83408,14 +83943,14 @@ var init_yerror = __esm(() => {
83408
83943
  });
83409
83944
 
83410
83945
  // node_modules/y18n/build/lib/platform-shims/node.js
83411
- import { readFileSync as readFileSync25, statSync as statSync13, writeFile } from "fs";
83946
+ import { readFileSync as readFileSync26, statSync as statSync13, writeFile } from "fs";
83412
83947
  import { format as format2 } from "util";
83413
83948
  import { resolve as resolve12 } from "path";
83414
83949
  var node_default;
83415
83950
  var init_node = __esm(() => {
83416
83951
  node_default = {
83417
83952
  fs: {
83418
- readFileSync: readFileSync25,
83953
+ readFileSync: readFileSync26,
83419
83954
  writeFile
83420
83955
  },
83421
83956
  format: format2,
@@ -83600,7 +84135,7 @@ var init_y18n = __esm(() => {
83600
84135
  // node_modules/yargs/lib/platform-shims/esm.mjs
83601
84136
  import { notStrictEqual, strictEqual } from "assert";
83602
84137
  import { inspect } from "util";
83603
- import { readFileSync as readFileSync26 } from "fs";
84138
+ import { readFileSync as readFileSync27 } from "fs";
83604
84139
  import { fileURLToPath } from "url";
83605
84140
  import { basename as basename9, dirname as dirname14, extname as extname3, relative as relative9, resolve as resolve13 } from "path";
83606
84141
  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 +84184,7 @@ var init_esm = __esm(() => {
83649
84184
  nextTick: process.nextTick,
83650
84185
  stdColumns: typeof process.stdout.columns !== "undefined" ? process.stdout.columns : null
83651
84186
  },
83652
- readFileSync: readFileSync26,
84187
+ readFileSync: readFileSync27,
83653
84188
  require: () => {
83654
84189
  throw new YError(REQUIRE_ERROR);
83655
84190
  },
@@ -87348,9 +87883,9 @@ async function getConnectionTransport(options) {
87348
87883
  throw new Error("Could not detect required browser platform");
87349
87884
  }
87350
87885
  const { convertPuppeteerChannelToBrowsersChannel: convertPuppeteerChannelToBrowsersChannel2 } = await Promise.resolve().then(() => (init_LaunchOptions(), exports_LaunchOptions));
87351
- const { join: join31 } = await import("node:path");
87886
+ const { join: join32 } = await import("node:path");
87352
87887
  const userDataDir = resolveDefaultUserDataDir3(Browser7.CHROME, platform2, convertPuppeteerChannelToBrowsersChannel2(options.channel));
87353
- const portPath = join31(userDataDir, "DevToolsActivePort");
87888
+ const portPath = join32(userDataDir, "DevToolsActivePort");
87354
87889
  try {
87355
87890
  const fileContent = await environment.value.fs.promises.readFile(portPath, "ascii");
87356
87891
  const [rawPort, rawPath] = fileContent.split(`
@@ -87574,9 +88109,9 @@ var init_PipeTransport = __esm(() => {
87574
88109
  });
87575
88110
 
87576
88111
  // node_modules/puppeteer-core/lib/esm/puppeteer/node/BrowserLauncher.js
87577
- import { existsSync as existsSync31 } from "node:fs";
88112
+ import { existsSync as existsSync35 } from "node:fs";
87578
88113
  import { tmpdir } from "node:os";
87579
- import { join as join31 } from "node:path";
88114
+ import { join as join32 } from "node:path";
87580
88115
 
87581
88116
  class BrowserLauncher {
87582
88117
  #browser;
@@ -87601,7 +88136,7 @@ class BrowserLauncher {
87601
88136
  ...options,
87602
88137
  protocol
87603
88138
  });
87604
- if (!existsSync31(launchArgs.executablePath)) {
88139
+ if (!existsSync35(launchArgs.executablePath)) {
87605
88140
  throw new Error(`Browser was not found at the configured executablePath (${launchArgs.executablePath})`);
87606
88141
  }
87607
88142
  const usePipe = launchArgs.args.includes("--remote-debugging-pipe");
@@ -87676,7 +88211,7 @@ class BrowserLauncher {
87676
88211
  browserCloseCallback();
87677
88212
  const logs = browserProcess.getRecentLogs().join(`
87678
88213
  `);
87679
- if (logs.includes("Failed to create a ProcessSingleton for your profile directory") || process.platform === "win32" && existsSync31(join31(launchArgs.userDataDir, "lockfile"))) {
88214
+ if (logs.includes("Failed to create a ProcessSingleton for your profile directory") || process.platform === "win32" && existsSync35(join32(launchArgs.userDataDir, "lockfile"))) {
87680
88215
  throw new Error(`The browser is already running for ${launchArgs.userDataDir}. Use a different \`userDataDir\` or stop the running browser first.`);
87681
88216
  }
87682
88217
  if (logs.includes("Missing X server") && options.headless === false) {
@@ -87766,12 +88301,12 @@ class BrowserLauncher {
87766
88301
  });
87767
88302
  }
87768
88303
  getProfilePath() {
87769
- return join31(this.puppeteer.configuration.temporaryDirectory ?? tmpdir(), `puppeteer_dev_${this.browser}_profile-`);
88304
+ return join32(this.puppeteer.configuration.temporaryDirectory ?? tmpdir(), `puppeteer_dev_${this.browser}_profile-`);
87770
88305
  }
87771
88306
  resolveExecutablePath(headless, validatePath = true) {
87772
88307
  let executablePath = this.puppeteer.configuration.executablePath;
87773
88308
  if (executablePath) {
87774
- if (validatePath && !existsSync31(executablePath)) {
88309
+ if (validatePath && !existsSync35(executablePath)) {
87775
88310
  throw new Error(`Tried to find the browser at the configured path (${executablePath}), but no executable was found.`);
87776
88311
  }
87777
88312
  return executablePath;
@@ -87794,7 +88329,7 @@ class BrowserLauncher {
87794
88329
  browser: browserType,
87795
88330
  buildId: this.puppeteer.browserVersion
87796
88331
  });
87797
- if (validatePath && !existsSync31(executablePath)) {
88332
+ if (validatePath && !existsSync35(executablePath)) {
87798
88333
  const configVersion = this.puppeteer.configuration?.[this.browser]?.version;
87799
88334
  if (configVersion) {
87800
88335
  throw new Error(`Tried to find the browser at the configured path (${executablePath}) for version ${configVersion}, but no executable was found.`);
@@ -88609,17 +89144,17 @@ var init_puppeteer_core = __esm(() => {
88609
89144
  });
88610
89145
 
88611
89146
  // 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";
89147
+ import { mkdirSync as mkdirSync14, statSync as statSync14, existsSync as existsSync36 } from "fs";
89148
+ import { join as join33 } from "path";
88614
89149
  function findBrowser() {
88615
89150
  const platform2 = process.platform;
88616
89151
  const paths = CHROME_PATHS[platform2] ?? [];
88617
89152
  for (const p of paths) {
88618
- if (existsSync32(p))
89153
+ if (existsSync36(p))
88619
89154
  return p;
88620
89155
  }
88621
- const minkBrowsers = join32(minkRoot(), "browsers");
88622
- if (existsSync32(minkBrowsers)) {
89156
+ const minkBrowsers = join33(minkRoot(), "browsers");
89157
+ if (existsSync36(minkBrowsers)) {
88623
89158
  const found = findChromeInDir(minkBrowsers);
88624
89159
  if (found)
88625
89160
  return found;
@@ -88640,7 +89175,7 @@ function findChromeInDir(dir) {
88640
89175
  try {
88641
89176
  const entries = readdirSync11(dir);
88642
89177
  for (const entry of entries) {
88643
- const full = join32(dir, entry);
89178
+ const full = join33(dir, entry);
88644
89179
  try {
88645
89180
  const stat2 = statSync15(full);
88646
89181
  if (stat2.isDirectory()) {
@@ -88688,7 +89223,7 @@ async function captureRoute(page, route, baseUrl, viewport, options) {
88688
89223
  const y = section * viewport.height;
88689
89224
  const clipHeight = Math.min(viewport.height, pageHeight - y);
88690
89225
  const fileName = `${prefix}-${viewport.name}-${section}.jpg`;
88691
- const filePath = join32(options.outputDir, fileName);
89226
+ const filePath = join33(options.outputDir, fileName);
88692
89227
  await page.screenshot({
88693
89228
  path: filePath,
88694
89229
  type: "jpeg",
@@ -90152,7 +90687,7 @@ var exports_wiki = {};
90152
90687
  __export(exports_wiki, {
90153
90688
  wiki: () => wiki
90154
90689
  });
90155
- import { existsSync as existsSync33, statSync as statSync15 } from "fs";
90690
+ import { existsSync as existsSync37, statSync as statSync15 } from "fs";
90156
90691
  import { resolve as resolve14 } from "path";
90157
90692
  import { homedir as homedir5 } from "os";
90158
90693
  async function wiki(_cwd, args) {
@@ -90210,7 +90745,7 @@ async function wikiInit(args) {
90210
90745
  console.log(`[mink] initializing vault at ${targetPath}`);
90211
90746
  console.log(" (set a custom path with: mink wiki init /path/to/vault)");
90212
90747
  }
90213
- const isExisting = existsSync33(targetPath) && statSync15(targetPath).isDirectory();
90748
+ const isExisting = existsSync37(targetPath) && statSync15(targetPath).isDirectory();
90214
90749
  setConfigValue("wiki.path", targetPath);
90215
90750
  ensureVaultStructure();
90216
90751
  seedTemplates(vaultTemplates());
@@ -90439,7 +90974,7 @@ __export(exports_note, {
90439
90974
  note: () => note
90440
90975
  });
90441
90976
  import { resolve as resolve15 } from "path";
90442
- import { existsSync as existsSync34, readFileSync as readFileSync27 } from "fs";
90977
+ import { existsSync as existsSync38, readFileSync as readFileSync28 } from "fs";
90443
90978
  async function note(cwd, args) {
90444
90979
  if (!isWikiEnabled()) {
90445
90980
  console.error("[mink] wiki feature is disabled");
@@ -90464,13 +90999,13 @@ async function note(cwd, args) {
90464
90999
  const date = new Date().toISOString().split("T")[0];
90465
91000
  const content = parsed.positional || parsed.body || "";
90466
91001
  const filePath = appendToDaily(date, content);
90467
- updateVaultIndexForFile(filePath, readFileSync27(filePath, "utf-8"));
91002
+ updateVaultIndexForFile(filePath, readFileSync28(filePath, "utf-8"));
90468
91003
  console.log(`[mink] daily note: ${filePath}`);
90469
91004
  return;
90470
91005
  }
90471
91006
  if (parsed.file) {
90472
91007
  const sourcePath = resolve15(cwd, parsed.file);
90473
- if (!existsSync34(sourcePath)) {
91008
+ if (!existsSync38(sourcePath)) {
90474
91009
  console.error(`[mink] file not found: ${sourcePath}`);
90475
91010
  process.exit(1);
90476
91011
  }
@@ -90552,7 +91087,7 @@ function detectSourceProject(cwd) {
90552
91087
  const vaultPath = resolveVaultPath();
90553
91088
  if (cwd.startsWith(vaultPath))
90554
91089
  return;
90555
- return generateProjectId(cwd);
91090
+ return projectIdFor(cwd);
90556
91091
  } catch {
90557
91092
  return;
90558
91093
  }
@@ -90631,10 +91166,10 @@ var exports_skill = {};
90631
91166
  __export(exports_skill, {
90632
91167
  skill: () => skill
90633
91168
  });
90634
- import { join as join33, resolve as resolve16, dirname as dirname16 } from "path";
91169
+ import { join as join34, resolve as resolve16, dirname as dirname16 } from "path";
90635
91170
  import { homedir as homedir6 } from "os";
90636
91171
  import {
90637
- existsSync as existsSync35,
91172
+ existsSync as existsSync39,
90638
91173
  mkdirSync as mkdirSync15,
90639
91174
  copyFileSync,
90640
91175
  unlinkSync as unlinkSync6,
@@ -90646,8 +91181,8 @@ import {
90646
91181
  function getSkillsSourceDir() {
90647
91182
  let dir = dirname16(new URL(import.meta.url).pathname);
90648
91183
  while (true) {
90649
- if (existsSync35(join33(dir, "package.json")) && existsSync35(join33(dir, "skills"))) {
90650
- return join33(dir, "skills");
91184
+ if (existsSync39(join34(dir, "package.json")) && existsSync39(join34(dir, "skills"))) {
91185
+ return join34(dir, "skills");
90651
91186
  }
90652
91187
  const parent = dirname16(dir);
90653
91188
  if (parent === dir)
@@ -90658,12 +91193,12 @@ function getSkillsSourceDir() {
90658
91193
  }
90659
91194
  function getAvailableSkills() {
90660
91195
  const dir = getSkillsSourceDir();
90661
- if (!existsSync35(dir))
91196
+ if (!existsSync39(dir))
90662
91197
  return [];
90663
- return readdirSync11(dir, { withFileTypes: true }).filter((d) => d.isDirectory() && existsSync35(join33(dir, d.name, "SKILL.md"))).map((d) => d.name);
91198
+ return readdirSync11(dir, { withFileTypes: true }).filter((d) => d.isDirectory() && existsSync39(join34(dir, d.name, "SKILL.md"))).map((d) => d.name);
90664
91199
  }
90665
91200
  function isInstalled(skillName) {
90666
- return existsSync35(join33(AGENTS_SKILLS_DIR, skillName, "SKILL.md"));
91201
+ return existsSync39(join34(AGENTS_SKILLS_DIR, skillName, "SKILL.md"));
90667
91202
  }
90668
91203
  async function skill(args) {
90669
91204
  const sub = args[0];
@@ -90699,26 +91234,26 @@ function skillInstall(name) {
90699
91234
  }
90700
91235
  mkdirSync15(AGENTS_SKILLS_DIR, { recursive: true });
90701
91236
  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)) {
91237
+ const srcDir = join34(sourceDir, skillName);
91238
+ const srcFile = join34(srcDir, "SKILL.md");
91239
+ const destDir = join34(AGENTS_SKILLS_DIR, skillName);
91240
+ if (!existsSync39(srcFile)) {
90706
91241
  console.error(`[mink] skill not found: ${skillName}`);
90707
91242
  continue;
90708
91243
  }
90709
91244
  mkdirSync15(destDir, { recursive: true });
90710
- copyDirRecursive(srcDir, destDir);
91245
+ copyDirRecursive2(srcDir, destDir);
90711
91246
  mkdirSync15(CLAUDE_SKILLS_DIR, { recursive: true });
90712
- const symlink = join33(CLAUDE_SKILLS_DIR, skillName);
91247
+ const symlink = join34(CLAUDE_SKILLS_DIR, skillName);
90713
91248
  try {
90714
- if (existsSync35(symlink)) {
91249
+ if (existsSync39(symlink)) {
90715
91250
  if (lstatSync2(symlink).isSymbolicLink() || lstatSync2(symlink).isFile()) {
90716
91251
  unlinkSync6(symlink);
90717
91252
  } else {
90718
91253
  rmSync(symlink, { recursive: true, force: true });
90719
91254
  }
90720
91255
  }
90721
- const relativeTarget = join33("..", "..", ".agents", "skills", skillName);
91256
+ const relativeTarget = join34("..", "..", ".agents", "skills", skillName);
90722
91257
  symlinkSync2(relativeTarget, symlink);
90723
91258
  } catch {}
90724
91259
  console.log(`[mink] installed: ${skillName} -> ${destDir}`);
@@ -90729,15 +91264,15 @@ function skillInstall(name) {
90729
91264
  function skillUninstall(name) {
90730
91265
  const skills = name ? [name] : getAvailableSkills();
90731
91266
  for (const skillName of skills) {
90732
- const destDir = join33(AGENTS_SKILLS_DIR, skillName);
90733
- if (!existsSync35(destDir)) {
91267
+ const destDir = join34(AGENTS_SKILLS_DIR, skillName);
91268
+ if (!existsSync39(destDir)) {
90734
91269
  console.log(`[mink] not installed: ${skillName}`);
90735
91270
  continue;
90736
91271
  }
90737
91272
  rmSync(destDir, { recursive: true, force: true });
90738
- const symlink = join33(CLAUDE_SKILLS_DIR, skillName);
91273
+ const symlink = join34(CLAUDE_SKILLS_DIR, skillName);
90739
91274
  try {
90740
- if (existsSync35(symlink))
91275
+ if (existsSync39(symlink))
90741
91276
  unlinkSync6(symlink);
90742
91277
  } catch {}
90743
91278
  console.log(`[mink] uninstalled: ${skillName}`);
@@ -90752,7 +91287,7 @@ function skillList() {
90752
91287
  if (installed.length > 0) {
90753
91288
  console.log(" Installed:");
90754
91289
  for (const s of installed) {
90755
- console.log(` ${s} (${join33(AGENTS_SKILLS_DIR, s)})`);
91290
+ console.log(` ${s} (${join34(AGENTS_SKILLS_DIR, s)})`);
90756
91291
  }
90757
91292
  }
90758
91293
  if (notInstalled.length > 0) {
@@ -90768,14 +91303,14 @@ function skillList() {
90768
91303
  console.log(" Install with: mink skill install");
90769
91304
  console.log(" Or via skills CLI: npx skills add drewpayment/mink");
90770
91305
  }
90771
- function copyDirRecursive(src, dest) {
91306
+ function copyDirRecursive2(src, dest) {
90772
91307
  const entries = readdirSync11(src, { withFileTypes: true });
90773
91308
  for (const entry of entries) {
90774
- const srcPath = join33(src, entry.name);
90775
- const destPath = join33(dest, entry.name);
91309
+ const srcPath = join34(src, entry.name);
91310
+ const destPath = join34(dest, entry.name);
90776
91311
  if (entry.isDirectory()) {
90777
91312
  mkdirSync15(destPath, { recursive: true });
90778
- copyDirRecursive(srcPath, destPath);
91313
+ copyDirRecursive2(srcPath, destPath);
90779
91314
  } else {
90780
91315
  copyFileSync(srcPath, destPath);
90781
91316
  }
@@ -90783,8 +91318,8 @@ function copyDirRecursive(src, dest) {
90783
91318
  }
90784
91319
  var AGENTS_SKILLS_DIR, CLAUDE_SKILLS_DIR;
90785
91320
  var init_skill = __esm(() => {
90786
- AGENTS_SKILLS_DIR = join33(homedir6(), ".agents", "skills");
90787
- CLAUDE_SKILLS_DIR = join33(homedir6(), ".claude", "skills");
91321
+ AGENTS_SKILLS_DIR = join34(homedir6(), ".agents", "skills");
91322
+ CLAUDE_SKILLS_DIR = join34(homedir6(), ".claude", "skills");
90788
91323
  });
90789
91324
 
90790
91325
  // src/commands/agent.ts
@@ -90792,12 +91327,12 @@ var exports_agent = {};
90792
91327
  __export(exports_agent, {
90793
91328
  agent: () => agent
90794
91329
  });
90795
- import { join as join34, resolve as resolve17, dirname as dirname17 } from "path";
91330
+ import { join as join35, resolve as resolve17, dirname as dirname17 } from "path";
90796
91331
  import { homedir as homedir7 } from "os";
90797
91332
  import {
90798
- existsSync as existsSync36,
91333
+ existsSync as existsSync40,
90799
91334
  mkdirSync as mkdirSync16,
90800
- readFileSync as readFileSync28,
91335
+ readFileSync as readFileSync29,
90801
91336
  writeFileSync as writeFileSync11
90802
91337
  } from "fs";
90803
91338
  import { createHash as createHash3 } from "crypto";
@@ -90805,8 +91340,8 @@ import { spawnSync as spawnSync6 } from "child_process";
90805
91340
  function getAgentTemplatePath() {
90806
91341
  let dir = dirname17(new URL(import.meta.url).pathname);
90807
91342
  while (true) {
90808
- if (existsSync36(join34(dir, "package.json")) && existsSync36(join34(dir, "agents", TEMPLATE_FILE))) {
90809
- return join34(dir, "agents", TEMPLATE_FILE);
91343
+ if (existsSync40(join35(dir, "package.json")) && existsSync40(join35(dir, "agents", TEMPLATE_FILE))) {
91344
+ return join35(dir, "agents", TEMPLATE_FILE);
90810
91345
  }
90811
91346
  const parent = dirname17(dir);
90812
91347
  if (parent === dir)
@@ -90818,10 +91353,10 @@ function getAgentTemplatePath() {
90818
91353
  function getMinkVersion() {
90819
91354
  let dir = dirname17(new URL(import.meta.url).pathname);
90820
91355
  while (true) {
90821
- const pkgPath = join34(dir, "package.json");
90822
- if (existsSync36(pkgPath)) {
91356
+ const pkgPath = join35(dir, "package.json");
91357
+ if (existsSync40(pkgPath)) {
90823
91358
  try {
90824
- const pkg = JSON.parse(readFileSync28(pkgPath, "utf-8"));
91359
+ const pkg = JSON.parse(readFileSync29(pkgPath, "utf-8"));
90825
91360
  if (pkg.name && pkg.version)
90826
91361
  return pkg.version;
90827
91362
  } catch {}
@@ -90844,30 +91379,30 @@ function sha2562(text) {
90844
91379
  return createHash3("sha256").update(text).digest("hex");
90845
91380
  }
90846
91381
  function claudeAgentsDir() {
90847
- return join34(homedir7(), ".claude", "agents");
91382
+ return join35(homedir7(), ".claude", "agents");
90848
91383
  }
90849
91384
  function installedAgentPath() {
90850
- return join34(claudeAgentsDir(), INSTALLED_FILE);
91385
+ return join35(claudeAgentsDir(), INSTALLED_FILE);
90851
91386
  }
90852
91387
  function installAgentDefinition(opts) {
90853
91388
  const templatePath = getAgentTemplatePath();
90854
- if (!existsSync36(templatePath)) {
91389
+ if (!existsSync40(templatePath)) {
90855
91390
  throw new Error(`[mink agent] bundled agent template not found at ${templatePath}
90856
91391
  ` + " This usually means the package was installed without bundled assets.");
90857
91392
  }
90858
91393
  const installed = installedAgentPath();
90859
- if (opts.skip && existsSync36(installed)) {
91394
+ if (opts.skip && existsSync40(installed)) {
90860
91395
  return { action: "skipped", path: installed };
90861
91396
  }
90862
- const template = readFileSync28(templatePath, "utf-8");
91397
+ const template = readFileSync29(templatePath, "utf-8");
90863
91398
  const rendered = renderTemplate(template, {
90864
91399
  MINK_ROOT: minkRoot(),
90865
91400
  VAULT_PATH: resolveVaultPath(),
90866
91401
  MINK_VERSION: getMinkVersion()
90867
91402
  });
90868
- const exists = existsSync36(installed);
91403
+ const exists = existsSync40(installed);
90869
91404
  if (!opts.force && exists) {
90870
- const current = readFileSync28(installed, "utf-8");
91405
+ const current = readFileSync29(installed, "utf-8");
90871
91406
  if (sha2562(current) === sha2562(rendered)) {
90872
91407
  return { action: "unchanged", path: installed };
90873
91408
  }
@@ -90943,7 +91478,7 @@ async function agent(_cwd, rawArgs) {
90943
91478
  }
90944
91479
  const skipUpdate = args.noUpdate || process.env.MINK_AGENT_NO_UPDATE === "1";
90945
91480
  const root = minkRoot();
90946
- if (!existsSync36(root)) {
91481
+ if (!existsSync40(root)) {
90947
91482
  mkdirSync16(root, { recursive: true });
90948
91483
  }
90949
91484
  let result;
@@ -90995,25 +91530,25 @@ var init_agent = __esm(() => {
90995
91530
  });
90996
91531
 
90997
91532
  // 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";
91533
+ import { readFileSync as readFileSync30, writeFileSync as writeFileSync12, appendFileSync as appendFileSync2 } from "fs";
91534
+ import { join as join36 } from "path";
91000
91535
  function logWarning(driver, args, err) {
91001
91536
  try {
91002
91537
  const line = `[${new Date().toISOString()}] ${driver} fallback for ${args.filePath}: ${err instanceof Error ? err.message : String(err)}
91003
91538
  `;
91004
- appendFileSync2(join35(minkRoot(), "sync-warnings.log"), line);
91539
+ appendFileSync2(join36(minkRoot(), "sync-warnings.log"), line);
91005
91540
  } catch {}
91006
91541
  }
91007
91542
  function readJsonOrNull(path12) {
91008
91543
  try {
91009
- return JSON.parse(readFileSync29(path12, "utf-8"));
91544
+ return JSON.parse(readFileSync30(path12, "utf-8"));
91010
91545
  } catch {
91011
91546
  return null;
91012
91547
  }
91013
91548
  }
91014
91549
  function readTextOrEmpty(path12) {
91015
91550
  try {
91016
- return readFileSync29(path12, "utf-8");
91551
+ return readFileSync30(path12, "utf-8");
91017
91552
  } catch {
91018
91553
  return "";
91019
91554
  }
@@ -91187,12 +91722,13 @@ async function sync(args) {
91187
91722
  return handleReconcile(args.slice(1));
91188
91723
  case "migrate": {
91189
91724
  const { syncMigrateCommand: syncMigrateCommand2 } = await Promise.resolve().then(() => (init_sync_migrate(), exports_sync_migrate));
91190
- syncMigrateCommand2();
91725
+ syncMigrateCommand2(args.slice(1));
91191
91726
  return;
91192
91727
  }
91193
91728
  default:
91194
91729
  console.error(`[mink] unknown sync subcommand: ${subcommand}`);
91195
- console.error("Usage: mink sync [init|status|push|pull|pause|resume|disconnect|reconcile|migrate|merge-driver]");
91730
+ console.error("Usage: mink sync [init|status|push|pull|pause|resume|disconnect|reconcile|merge-driver]");
91731
+ console.error(" mink sync migrate [--dry-run|--rollback]");
91196
91732
  process.exit(1);
91197
91733
  }
91198
91734
  }
@@ -91414,7 +91950,9 @@ function sessionStart(cwd) {
91414
91950
  } catch {}
91415
91951
  try {
91416
91952
  const { readSyncVersion: readSyncVersion2, MINK_SYNC_VERSION: MINK_SYNC_VERSION2 } = (init_sync(), __toCommonJS(exports_sync));
91417
- if (readSyncVersion2() < MINK_SYNC_VERSION2) {
91953
+ const { resolveConfigValue: resolveConfigValue2 } = (init_global_config(), __toCommonJS(exports_global_config));
91954
+ const identityOn = resolveConfigValue2("projects.identity").value === "git-remote";
91955
+ if (readSyncVersion2() < MINK_SYNC_VERSION2 || identityOn) {
91418
91956
  const { migrateSyncLayout: migrateSyncLayout2 } = (init_sync_migrate(), __toCommonJS(exports_sync_migrate));
91419
91957
  migrateSyncLayout2();
91420
91958
  }
@@ -91438,13 +91976,13 @@ function sessionStart(cwd) {
91438
91976
  const index = loadVaultIndex();
91439
91977
  const inboxCount = Object.values(index.entries).filter((e) => e.category === "inbox").length;
91440
91978
  try {
91441
- const { join: join8 } = __require("path");
91442
- const { existsSync: existsSync8 } = __require("fs");
91979
+ const { join: join10 } = __require("path");
91980
+ const { existsSync: existsSync12 } = __require("fs");
91443
91981
  const { resolveVaultPath: resolveVaultPath2 } = (init_vault(), __toCommonJS(exports_vault));
91444
91982
  const { updateMasterIndex: updateMasterIndex2 } = (init_note_linker(), __toCommonJS(exports_note_linker));
91445
91983
  const vaultPath = resolveVaultPath2();
91446
- const masterIndexPath = join8(vaultPath, "_index.md");
91447
- if (!existsSync8(masterIndexPath)) {
91984
+ const masterIndexPath = join10(vaultPath, "_index.md");
91985
+ if (!existsSync12(masterIndexPath)) {
91448
91986
  updateMasterIndex2(vaultPath);
91449
91987
  }
91450
91988
  } catch {}
@@ -91468,8 +92006,8 @@ init_state_aggregator();
91468
92006
  init_action_log();
91469
92007
  init_device();
91470
92008
  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";
92009
+ import { statSync as statSync5, existsSync as existsSync14, readFileSync as readFileSync10 } from "fs";
92010
+ import { join as join12, dirname as dirname4 } from "path";
91473
92011
  function hasActivity(state) {
91474
92012
  return Object.keys(state.reads).length > 0 || state.writes.length > 0;
91475
92013
  }
@@ -91511,10 +92049,10 @@ function sessionStop(sessionFile, finalizer, onReminder = (msg) => console.error
91511
92049
  effectiveFinalizer.updateSession(summary);
91512
92050
  }
91513
92051
  try {
91514
- const logPath = join10(projDir, "state", deviceId, "action-log.md");
92052
+ const logPath = join12(projDir, "state", deviceId, "action-log.md");
91515
92053
  const logWriter = createActionLogWriter(logPath);
91516
92054
  logWriter.appendSessionEnd(summary);
91517
- const cfgRaw = safeReadJson(join10(projDir, "config.json"));
92055
+ const cfgRaw = safeReadJson(join12(projDir, "config.json"));
91518
92056
  consolidateLog(logPath, {
91519
92057
  maxEntries: cfgRaw?.actionLogMaxEntries ?? 200,
91520
92058
  retentionDays: cfgRaw?.actionLogRetentionDays ?? 7
@@ -91531,9 +92069,9 @@ function sessionStop(sessionFile, finalizer, onReminder = (msg) => console.error
91531
92069
  }
91532
92070
  }
91533
92071
  }
91534
- const memoryPath = join10(projDir, "learning-memory.md");
91535
- const cfgPath = join10(projDir, "config.json");
91536
- if (existsSync10(memoryPath)) {
92072
+ const memoryPath = join12(projDir, "learning-memory.md");
92073
+ const cfgPath = join12(projDir, "config.json");
92074
+ if (existsSync14(memoryPath)) {
91537
92075
  reflect(projDir, memoryPath, cfgPath);
91538
92076
  }
91539
92077
  if (isLearningMemoryStale(memoryPath)) {
@@ -91553,13 +92091,13 @@ function sessionStop(sessionFile, finalizer, onReminder = (msg) => console.error
91553
92091
  atomicWriteJson(sessionFile, state);
91554
92092
  }
91555
92093
  function writeSessionToWiki(state, projDir) {
91556
- const metaRaw = safeReadJson(join10(projDir, "project-meta.json"));
92094
+ const metaRaw = safeReadJson(join12(projDir, "project-meta.json"));
91557
92095
  const projectName = metaRaw?.name ?? "unknown";
91558
92096
  const date = new Date().toISOString().split("T")[0];
91559
92097
  const readCount = Object.keys(state.reads).length;
91560
92098
  const writeCount = state.writes.length;
91561
- const sessionDir = join10(vaultProjects(projectName), "sessions");
91562
- const sessionFile = join10(sessionDir, `${date}.md`);
92099
+ const sessionDir = join12(vaultProjects(projectName), "sessions");
92100
+ const sessionFile = join12(sessionDir, `${date}.md`);
91563
92101
  const timestamp = new Date().toLocaleTimeString("en-US", {
91564
92102
  hour: "2-digit",
91565
92103
  minute: "2-digit",
@@ -91584,8 +92122,8 @@ function writeSessionToWiki(state, projDir) {
91584
92122
  }
91585
92123
  }
91586
92124
  entry.push("");
91587
- if (existsSync10(sessionFile)) {
91588
- const existing = readFileSync9(sessionFile, "utf-8");
92125
+ if (existsSync14(sessionFile)) {
92126
+ const existing = readFileSync10(sessionFile, "utf-8");
91589
92127
  atomicWriteText(sessionFile, existing.trimEnd() + `
91590
92128
  ` + entry.join(`
91591
92129
  `));
@@ -91766,9 +92304,9 @@ switch (command2) {
91766
92304
  case "-v": {
91767
92305
  const { resolve: resolve18, dirname: dirname18 } = await import("path");
91768
92306
  const cliPath = resolve18(dirname18(new URL(import.meta.url).pathname));
91769
- const { readFileSync: readFileSync30 } = await import("fs");
92307
+ const { readFileSync: readFileSync31 } = await import("fs");
91770
92308
  try {
91771
- const pkg = JSON.parse(readFileSync30(resolve18(cliPath, "../package.json"), "utf-8"));
92309
+ const pkg = JSON.parse(readFileSync31(resolve18(cliPath, "../package.json"), "utf-8"));
91772
92310
  console.log(`mink ${pkg.version}`);
91773
92311
  } catch {
91774
92312
  console.log("mink (unknown version)");