@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.
- package/dashboard/out/404.html +1 -1
- package/dashboard/out/action-log.html +1 -1
- package/dashboard/out/action-log.txt +1 -1
- package/dashboard/out/activity.html +1 -1
- package/dashboard/out/activity.txt +1 -1
- package/dashboard/out/bugs.html +1 -1
- package/dashboard/out/bugs.txt +1 -1
- package/dashboard/out/capture.html +1 -1
- package/dashboard/out/capture.txt +1 -1
- package/dashboard/out/config.html +1 -1
- package/dashboard/out/config.txt +1 -1
- package/dashboard/out/daemon.html +1 -1
- package/dashboard/out/daemon.txt +1 -1
- package/dashboard/out/design.html +1 -1
- package/dashboard/out/design.txt +1 -1
- package/dashboard/out/discord.html +1 -1
- package/dashboard/out/discord.txt +1 -1
- package/dashboard/out/file-index.html +1 -1
- package/dashboard/out/file-index.txt +1 -1
- package/dashboard/out/index.html +1 -1
- package/dashboard/out/index.txt +1 -1
- package/dashboard/out/insights.html +1 -1
- package/dashboard/out/insights.txt +1 -1
- package/dashboard/out/learning.html +1 -1
- package/dashboard/out/learning.txt +1 -1
- package/dashboard/out/overview.html +1 -1
- package/dashboard/out/overview.txt +1 -1
- package/dashboard/out/scheduler.html +1 -1
- package/dashboard/out/scheduler.txt +1 -1
- package/dashboard/out/sync.html +1 -1
- package/dashboard/out/sync.txt +1 -1
- package/dashboard/out/tokens.html +1 -1
- package/dashboard/out/tokens.txt +1 -1
- package/dashboard/out/waste.html +1 -1
- package/dashboard/out/waste.txt +1 -1
- package/dashboard/out/wiki.html +1 -1
- package/dashboard/out/wiki.txt +1 -1
- package/dist/cli.js +1406 -868
- package/package.json +1 -1
- package/src/commands/init.ts +29 -4
- package/src/commands/note.ts +2 -2
- package/src/commands/session-start.ts +8 -2
- package/src/commands/sync-migrate.ts +404 -7
- package/src/commands/sync.ts +5 -2
- package/src/core/dashboard-server.ts +13 -5
- package/src/core/git-identity.ts +120 -0
- package/src/core/paths.ts +19 -3
- package/src/core/project-id.ts +142 -5
- package/src/core/project-registry.ts +122 -13
- package/src/core/sync.ts +7 -1
- package/src/types/config.ts +9 -0
- /package/dashboard/out/_next/static/{e0QWU9rPMeSlJJLTwij89 → WDjkNLHEd_wI-oOzLyblH}/_buildManifest.js +0 -0
- /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 =
|
|
560
|
+
const hash = shortHash(normalized);
|
|
176
561
|
return `${slug}-${hash}`;
|
|
177
562
|
}
|
|
178
|
-
|
|
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 ||
|
|
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 =
|
|
231
|
-
|
|
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
|
|
823
|
+
return join3(projectDir(cwd), "session.json");
|
|
235
824
|
}
|
|
236
825
|
function fileIndexPath(cwd) {
|
|
237
|
-
return
|
|
826
|
+
return join3(projectDir(cwd), "file-index.json");
|
|
238
827
|
}
|
|
239
828
|
function configPath(cwd) {
|
|
240
|
-
return
|
|
829
|
+
return join3(projectDir(cwd), "config.json");
|
|
241
830
|
}
|
|
242
831
|
function learningMemoryPath(cwd) {
|
|
243
|
-
return
|
|
832
|
+
return join3(projectDir(cwd), "learning-memory.md");
|
|
244
833
|
}
|
|
245
834
|
function tokenLedgerPath(cwd) {
|
|
246
|
-
return
|
|
835
|
+
return join3(projectDir(cwd), "token-ledger.json");
|
|
247
836
|
}
|
|
248
837
|
function tokenLedgerArchivePath(cwd) {
|
|
249
|
-
return
|
|
838
|
+
return join3(projectDir(cwd), "token-ledger-archive.json");
|
|
250
839
|
}
|
|
251
840
|
function bugMemoryPath(cwd) {
|
|
252
|
-
return
|
|
841
|
+
return join3(projectDir(cwd), "bug-memory.json");
|
|
253
842
|
}
|
|
254
843
|
function actionLogPath(cwd) {
|
|
255
|
-
return
|
|
844
|
+
return join3(projectDir(cwd), "action-log.md");
|
|
256
845
|
}
|
|
257
846
|
function schedulerPidPath() {
|
|
258
|
-
return
|
|
847
|
+
return join3(minkRoot(), "scheduler.pid");
|
|
259
848
|
}
|
|
260
849
|
function schedulerLogPath() {
|
|
261
|
-
return
|
|
850
|
+
return join3(minkRoot(), "scheduler.log");
|
|
262
851
|
}
|
|
263
852
|
function schedulerManifestPath(cwd) {
|
|
264
|
-
return
|
|
853
|
+
return join3(projectDir(cwd), "scheduler-manifest.json");
|
|
265
854
|
}
|
|
266
855
|
function channelPidPath() {
|
|
267
|
-
return
|
|
856
|
+
return join3(minkRoot(), "channel.pid");
|
|
268
857
|
}
|
|
269
858
|
function channelLogPath() {
|
|
270
|
-
return
|
|
859
|
+
return join3(minkRoot(), "channel.log");
|
|
271
860
|
}
|
|
272
861
|
function globalConfigPath() {
|
|
273
|
-
return
|
|
862
|
+
return join3(minkRoot(), "config");
|
|
274
863
|
}
|
|
275
864
|
function localConfigPath() {
|
|
276
|
-
return
|
|
865
|
+
return join3(minkRoot(), "config.local");
|
|
277
866
|
}
|
|
278
867
|
function deviceIdPath() {
|
|
279
|
-
return
|
|
868
|
+
return join3(minkRoot(), "device-id");
|
|
280
869
|
}
|
|
281
870
|
function deviceRegistryPath() {
|
|
282
|
-
return
|
|
871
|
+
return join3(minkRoot(), "devices.json");
|
|
283
872
|
}
|
|
284
873
|
function projectMetaPath(cwd) {
|
|
285
|
-
return
|
|
874
|
+
return join3(projectDir(cwd), "project-meta.json");
|
|
286
875
|
}
|
|
287
876
|
function backupDirPath(cwd) {
|
|
288
|
-
return
|
|
877
|
+
return join3(projectDir(cwd), "backups");
|
|
289
878
|
}
|
|
290
879
|
function syncVersionPath() {
|
|
291
|
-
return
|
|
880
|
+
return join3(minkRoot(), ".mink-sync-version");
|
|
292
881
|
}
|
|
293
882
|
function projectStateDir(cwd) {
|
|
294
|
-
return
|
|
883
|
+
return join3(projectDir(cwd), "state");
|
|
295
884
|
}
|
|
296
885
|
function deviceShardDir(cwd, deviceId) {
|
|
297
|
-
return
|
|
886
|
+
return join3(projectStateDir(cwd), deviceId);
|
|
298
887
|
}
|
|
299
888
|
function tokenLedgerShardPath(cwd, deviceId) {
|
|
300
|
-
return
|
|
889
|
+
return join3(deviceShardDir(cwd, deviceId), "token-ledger.json");
|
|
301
890
|
}
|
|
302
891
|
function tokenLedgerArchiveShardPath(cwd, deviceId) {
|
|
303
|
-
return
|
|
892
|
+
return join3(deviceShardDir(cwd, deviceId), "token-ledger-archive.json");
|
|
304
893
|
}
|
|
305
894
|
function bugMemoryShardPath(cwd, deviceId) {
|
|
306
|
-
return
|
|
895
|
+
return join3(deviceShardDir(cwd, deviceId), "bug-memory.json");
|
|
307
896
|
}
|
|
308
897
|
function actionLogShardPath(cwd, deviceId) {
|
|
309
|
-
return
|
|
898
|
+
return join3(deviceShardDir(cwd, deviceId), "action-log.md");
|
|
310
899
|
}
|
|
311
900
|
function learningMemorySidecarPath(cwd, deviceId) {
|
|
312
|
-
return
|
|
901
|
+
return join3(projectDir(cwd), `learning-memory.${deviceId}.md`);
|
|
313
902
|
}
|
|
314
903
|
function fileIndexCountersPath(cwd) {
|
|
315
|
-
return
|
|
904
|
+
return join3(projectDir(cwd), ".mink-state-counters.json");
|
|
316
905
|
}
|
|
317
906
|
function designCapturesDir(cwd) {
|
|
318
|
-
return
|
|
907
|
+
return join3(projectDir(cwd), "design-captures");
|
|
319
908
|
}
|
|
320
909
|
function designReportPath(cwd) {
|
|
321
|
-
return
|
|
910
|
+
return join3(projectDir(cwd), "design-report.json");
|
|
322
911
|
}
|
|
323
912
|
function frameworkAdvisorPath(cwd) {
|
|
324
|
-
return
|
|
913
|
+
return join3(projectDir(cwd), "framework-advisor.md");
|
|
325
914
|
}
|
|
326
915
|
function frameworkAdvisorJsonPath(cwd) {
|
|
327
|
-
return
|
|
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
|
|
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
|
|
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
|
|
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 (
|
|
628
|
-
return
|
|
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
|
|
1265
|
+
import { join as join4, basename as basename2, resolve } from "path";
|
|
970
1266
|
import { homedir as homedir2 } from "os";
|
|
971
|
-
import { existsSync as
|
|
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("~/") ?
|
|
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
|
|
1278
|
+
return join4(resolveVaultPath(), "inbox");
|
|
983
1279
|
}
|
|
984
1280
|
function vaultProjects(slug) {
|
|
985
|
-
const base =
|
|
986
|
-
return slug ?
|
|
1281
|
+
const base = join4(resolveVaultPath(), "projects");
|
|
1282
|
+
return slug ? join4(base, slug) : base;
|
|
987
1283
|
}
|
|
988
1284
|
function vaultAreas() {
|
|
989
|
-
return
|
|
1285
|
+
return join4(resolveVaultPath(), "areas");
|
|
990
1286
|
}
|
|
991
1287
|
function vaultDailyDir() {
|
|
992
|
-
return
|
|
1288
|
+
return join4(resolveVaultPath(), "areas", "daily");
|
|
993
1289
|
}
|
|
994
1290
|
function vaultResources() {
|
|
995
|
-
return
|
|
1291
|
+
return join4(resolveVaultPath(), "resources");
|
|
996
1292
|
}
|
|
997
1293
|
function vaultArchives() {
|
|
998
|
-
return
|
|
1294
|
+
return join4(resolveVaultPath(), "archives");
|
|
999
1295
|
}
|
|
1000
1296
|
function vaultTemplates() {
|
|
1001
|
-
return
|
|
1297
|
+
return join4(resolveVaultPath(), "templates");
|
|
1002
1298
|
}
|
|
1003
1299
|
function vaultPatterns() {
|
|
1004
|
-
return
|
|
1300
|
+
return join4(resolveVaultPath(), "patterns");
|
|
1005
1301
|
}
|
|
1006
1302
|
function vaultManifestPath() {
|
|
1007
|
-
return
|
|
1303
|
+
return join4(resolveVaultPath(), ".mink-vault.json");
|
|
1008
1304
|
}
|
|
1009
1305
|
function vaultIndexPath() {
|
|
1010
|
-
return
|
|
1306
|
+
return join4(resolveVaultPath(), ".mink-index.json");
|
|
1011
1307
|
}
|
|
1012
1308
|
function vaultMasterIndexPath() {
|
|
1013
|
-
return
|
|
1309
|
+
return join4(resolveVaultPath(), "_index.md");
|
|
1014
1310
|
}
|
|
1015
1311
|
function isVaultInitialized() {
|
|
1016
|
-
return
|
|
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(
|
|
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 ?
|
|
1340
|
+
return projectSlug ? join4(root, "projects", projectSlug) : join4(root, "projects");
|
|
1045
1341
|
case "areas":
|
|
1046
|
-
return
|
|
1342
|
+
return join4(root, "areas");
|
|
1047
1343
|
case "resources":
|
|
1048
|
-
return
|
|
1344
|
+
return join4(root, "resources");
|
|
1049
1345
|
case "archives":
|
|
1050
|
-
return
|
|
1346
|
+
return join4(root, "archives");
|
|
1051
1347
|
case "inbox":
|
|
1052
1348
|
default:
|
|
1053
|
-
return
|
|
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("~/") ?
|
|
1062
|
-
if (!
|
|
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 =
|
|
1070
|
-
if (
|
|
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 =
|
|
1093
|
-
if (!
|
|
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 =
|
|
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
|
|
1132
|
-
import { readFileSync as
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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
|
|
1362
|
-
import { join as
|
|
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
|
|
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 =
|
|
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
|
|
1437
|
-
import { join as
|
|
1438
|
-
import { execSync as
|
|
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 =
|
|
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
|
|
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
|
|
1766
|
+
return existsSync9(join7(minkRoot(), ".git"));
|
|
1471
1767
|
}
|
|
1472
1768
|
function ensureGitignore() {
|
|
1473
|
-
const gitignorePath =
|
|
1769
|
+
const gitignorePath = join7(minkRoot(), ".gitignore");
|
|
1474
1770
|
writeFileSync3(gitignorePath, GITIGNORE_CONTENTS);
|
|
1475
1771
|
}
|
|
1476
1772
|
function ensureGitAttributes() {
|
|
1477
|
-
const path =
|
|
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 =
|
|
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 =
|
|
1518
|
-
if (
|
|
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 =
|
|
1660
|
-
if (!
|
|
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 =
|
|
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
|
|
1736
|
-
readdirSync as
|
|
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
|
|
1744
|
-
import { execSync as
|
|
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
|
|
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 =
|
|
1758
|
-
if (
|
|
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(
|
|
2074
|
+
unlinkSync2(join8(minkRoot(), MIGRATE_LOCK));
|
|
1776
2075
|
} catch {}
|
|
1777
2076
|
}
|
|
1778
2077
|
function migrateFile(from, to) {
|
|
1779
|
-
if (!
|
|
2078
|
+
if (!existsSync10(from))
|
|
1780
2079
|
return true;
|
|
1781
|
-
mkdirSync4(
|
|
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 =
|
|
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 =
|
|
1801
|
-
const shard =
|
|
1802
|
-
if (
|
|
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 =
|
|
1807
|
-
if (!
|
|
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 (
|
|
1814
|
-
gitSafe3(`rm --cached "${
|
|
2112
|
+
if (existsSync10(join8(projDir, f))) {
|
|
2113
|
+
gitSafe3(`rm --cached "${join8(projDir, f)}"`);
|
|
1815
2114
|
}
|
|
1816
2115
|
}
|
|
1817
|
-
const indexPath =
|
|
1818
|
-
if (
|
|
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
|
|
2131
|
+
return join8(projDir, ".mink-state-counters.json");
|
|
1833
2132
|
}
|
|
1834
2133
|
function listProjects() {
|
|
1835
|
-
const projectsRoot =
|
|
1836
|
-
if (!
|
|
2134
|
+
const projectsRoot = join8(minkRoot(), "projects");
|
|
2135
|
+
if (!existsSync10(projectsRoot))
|
|
1837
2136
|
return [];
|
|
1838
2137
|
try {
|
|
1839
|
-
return
|
|
2138
|
+
return readdirSync3(projectsRoot).filter((name) => {
|
|
1840
2139
|
try {
|
|
1841
|
-
return statSync2(
|
|
2140
|
+
return statSync2(join8(projectsRoot, name)).isDirectory();
|
|
1842
2141
|
} catch {
|
|
1843
2142
|
return false;
|
|
1844
2143
|
}
|
|
1845
|
-
}).map((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 =
|
|
1852
|
-
if (
|
|
2150
|
+
const stateDir = join8(projDir, "state");
|
|
2151
|
+
if (existsSync10(stateDir)) {
|
|
1853
2152
|
try {
|
|
1854
|
-
const shards =
|
|
2153
|
+
const shards = readdirSync3(stateDir).filter((d) => {
|
|
1855
2154
|
try {
|
|
1856
|
-
return statSync2(
|
|
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 (
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
1972
|
-
import { existsSync as
|
|
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 (!
|
|
2552
|
+
if (!existsSync11(targetNotePath))
|
|
1999
2553
|
return;
|
|
2000
|
-
const content =
|
|
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 =
|
|
2043
|
-
if (!
|
|
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 =
|
|
2624
|
+
const entries = readdirSync4(dirPath, { withFileTypes: true });
|
|
2071
2625
|
for (const entry of entries) {
|
|
2072
|
-
const fullPath =
|
|
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
|
|
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 =
|
|
2337
|
-
ledgerPath =
|
|
2338
|
-
archivePath =
|
|
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 =
|
|
2342
|
-
archivePath =
|
|
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
|
|
2483
|
-
import { join as
|
|
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 =
|
|
2486
|
-
if (!
|
|
3039
|
+
const stateDir = join11(projDir, "state");
|
|
3040
|
+
if (!existsSync12(stateDir))
|
|
2487
3041
|
return [];
|
|
2488
3042
|
try {
|
|
2489
|
-
return
|
|
3043
|
+
return readdirSync5(stateDir).filter((name) => {
|
|
2490
3044
|
try {
|
|
2491
|
-
return statSync4(
|
|
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 (!
|
|
3055
|
+
if (!existsSync12(projDir))
|
|
2502
3056
|
return [];
|
|
2503
3057
|
try {
|
|
2504
|
-
return
|
|
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
|
|
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
|
-
|
|
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 (!
|
|
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
|
-
|
|
3120
|
+
join11(projDir, "bug-memory.json")
|
|
2567
3121
|
];
|
|
2568
3122
|
for (const path of sources) {
|
|
2569
|
-
if (!
|
|
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
|
-
|
|
3163
|
+
join11(projDir, "action-log.md")
|
|
2610
3164
|
];
|
|
2611
3165
|
for (const path of sources) {
|
|
2612
|
-
if (!
|
|
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 =
|
|
3191
|
+
const canonicalPath = join11(projDir, "learning-memory.md");
|
|
2638
3192
|
let merged;
|
|
2639
|
-
if (
|
|
3193
|
+
if (existsSync12(canonicalPath)) {
|
|
2640
3194
|
try {
|
|
2641
|
-
merged = parseLearningMemory(
|
|
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(
|
|
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
|
|
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 && !
|
|
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
|
|
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 ||
|
|
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 =
|
|
3035
|
-
|
|
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
|
|
3602
|
+
return join13(projectDir2(cwd), "session.json");
|
|
3039
3603
|
}
|
|
3040
3604
|
function fileIndexPath2(cwd) {
|
|
3041
|
-
return
|
|
3605
|
+
return join13(projectDir2(cwd), "file-index.json");
|
|
3042
3606
|
}
|
|
3043
3607
|
function configPath2(cwd) {
|
|
3044
|
-
return
|
|
3608
|
+
return join13(projectDir2(cwd), "config.json");
|
|
3045
3609
|
}
|
|
3046
3610
|
function learningMemoryPath2(cwd) {
|
|
3047
|
-
return
|
|
3611
|
+
return join13(projectDir2(cwd), "learning-memory.md");
|
|
3048
3612
|
}
|
|
3049
3613
|
function tokenLedgerPath2(cwd) {
|
|
3050
|
-
return
|
|
3614
|
+
return join13(projectDir2(cwd), "token-ledger.json");
|
|
3051
3615
|
}
|
|
3052
3616
|
function tokenLedgerArchivePath2(cwd) {
|
|
3053
|
-
return
|
|
3617
|
+
return join13(projectDir2(cwd), "token-ledger-archive.json");
|
|
3054
3618
|
}
|
|
3055
3619
|
function bugMemoryPath2(cwd) {
|
|
3056
|
-
return
|
|
3620
|
+
return join13(projectDir2(cwd), "bug-memory.json");
|
|
3057
3621
|
}
|
|
3058
3622
|
function actionLogPath2(cwd) {
|
|
3059
|
-
return
|
|
3623
|
+
return join13(projectDir2(cwd), "action-log.md");
|
|
3060
3624
|
}
|
|
3061
3625
|
function schedulerPidPath2() {
|
|
3062
|
-
return
|
|
3626
|
+
return join13(minkRoot2(), "scheduler.pid");
|
|
3063
3627
|
}
|
|
3064
3628
|
function schedulerLogPath2() {
|
|
3065
|
-
return
|
|
3629
|
+
return join13(minkRoot2(), "scheduler.log");
|
|
3066
3630
|
}
|
|
3067
3631
|
function schedulerManifestPath2(cwd) {
|
|
3068
|
-
return
|
|
3632
|
+
return join13(projectDir2(cwd), "scheduler-manifest.json");
|
|
3069
3633
|
}
|
|
3070
3634
|
function channelPidPath2() {
|
|
3071
|
-
return
|
|
3635
|
+
return join13(minkRoot2(), "channel.pid");
|
|
3072
3636
|
}
|
|
3073
3637
|
function channelLogPath2() {
|
|
3074
|
-
return
|
|
3638
|
+
return join13(minkRoot2(), "channel.log");
|
|
3075
3639
|
}
|
|
3076
3640
|
function globalConfigPath2() {
|
|
3077
|
-
return
|
|
3641
|
+
return join13(minkRoot2(), "config");
|
|
3078
3642
|
}
|
|
3079
3643
|
function localConfigPath2() {
|
|
3080
|
-
return
|
|
3644
|
+
return join13(minkRoot2(), "config.local");
|
|
3081
3645
|
}
|
|
3082
3646
|
function deviceIdPath2() {
|
|
3083
|
-
return
|
|
3647
|
+
return join13(minkRoot2(), "device-id");
|
|
3084
3648
|
}
|
|
3085
3649
|
function deviceRegistryPath2() {
|
|
3086
|
-
return
|
|
3650
|
+
return join13(minkRoot2(), "devices.json");
|
|
3087
3651
|
}
|
|
3088
3652
|
function projectMetaPath2(cwd) {
|
|
3089
|
-
return
|
|
3653
|
+
return join13(projectDir2(cwd), "project-meta.json");
|
|
3090
3654
|
}
|
|
3091
3655
|
function backupDirPath2(cwd) {
|
|
3092
|
-
return
|
|
3656
|
+
return join13(projectDir2(cwd), "backups");
|
|
3093
3657
|
}
|
|
3094
3658
|
function syncVersionPath2() {
|
|
3095
|
-
return
|
|
3659
|
+
return join13(minkRoot2(), ".mink-sync-version");
|
|
3096
3660
|
}
|
|
3097
3661
|
function projectStateDir2(cwd) {
|
|
3098
|
-
return
|
|
3662
|
+
return join13(projectDir2(cwd), "state");
|
|
3099
3663
|
}
|
|
3100
3664
|
function deviceShardDir2(cwd, deviceId) {
|
|
3101
|
-
return
|
|
3665
|
+
return join13(projectStateDir2(cwd), deviceId);
|
|
3102
3666
|
}
|
|
3103
3667
|
function tokenLedgerShardPath2(cwd, deviceId) {
|
|
3104
|
-
return
|
|
3668
|
+
return join13(deviceShardDir2(cwd, deviceId), "token-ledger.json");
|
|
3105
3669
|
}
|
|
3106
3670
|
function tokenLedgerArchiveShardPath2(cwd, deviceId) {
|
|
3107
|
-
return
|
|
3671
|
+
return join13(deviceShardDir2(cwd, deviceId), "token-ledger-archive.json");
|
|
3108
3672
|
}
|
|
3109
3673
|
function bugMemoryShardPath2(cwd, deviceId) {
|
|
3110
|
-
return
|
|
3674
|
+
return join13(deviceShardDir2(cwd, deviceId), "bug-memory.json");
|
|
3111
3675
|
}
|
|
3112
3676
|
function actionLogShardPath2(cwd, deviceId) {
|
|
3113
|
-
return
|
|
3677
|
+
return join13(deviceShardDir2(cwd, deviceId), "action-log.md");
|
|
3114
3678
|
}
|
|
3115
3679
|
function learningMemorySidecarPath2(cwd, deviceId) {
|
|
3116
|
-
return
|
|
3680
|
+
return join13(projectDir2(cwd), `learning-memory.${deviceId}.md`);
|
|
3117
3681
|
}
|
|
3118
3682
|
function fileIndexCountersPath3(cwd) {
|
|
3119
|
-
return
|
|
3683
|
+
return join13(projectDir2(cwd), ".mink-state-counters.json");
|
|
3120
3684
|
}
|
|
3121
3685
|
function designCapturesDir2(cwd) {
|
|
3122
|
-
return
|
|
3686
|
+
return join13(projectDir2(cwd), "design-captures");
|
|
3123
3687
|
}
|
|
3124
3688
|
function designReportPath2(cwd) {
|
|
3125
|
-
return
|
|
3689
|
+
return join13(projectDir2(cwd), "design-report.json");
|
|
3126
3690
|
}
|
|
3127
3691
|
function frameworkAdvisorPath2(cwd) {
|
|
3128
|
-
return
|
|
3692
|
+
return join13(projectDir2(cwd), "framework-advisor.md");
|
|
3129
3693
|
}
|
|
3130
3694
|
function frameworkAdvisorJsonPath2(cwd) {
|
|
3131
|
-
return
|
|
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
|
|
3149
|
-
readFileSync as
|
|
3712
|
+
readdirSync as readdirSync6,
|
|
3713
|
+
readFileSync as readFileSync11,
|
|
3150
3714
|
writeFileSync as writeFileSync5,
|
|
3151
|
-
existsSync as
|
|
3715
|
+
existsSync as existsSync16,
|
|
3152
3716
|
statSync as statSync6
|
|
3153
3717
|
} from "fs";
|
|
3154
|
-
import { join as
|
|
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 =
|
|
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(
|
|
3736
|
+
copyDirectoryFiles(join14(srcDir, entry.name), join14(destDir, entry.name), excludeDirs);
|
|
3173
3737
|
} else if (entry.isFile()) {
|
|
3174
|
-
writeFileSync5(
|
|
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 (
|
|
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 =
|
|
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 (!
|
|
3758
|
+
if (!existsSync16(dir))
|
|
3195
3759
|
return [];
|
|
3196
|
-
const entries =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
3225
|
-
if (!
|
|
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
|
|
3237
|
-
import { join as
|
|
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 =
|
|
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(
|
|
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 =
|
|
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
|
|
3595
|
-
import { join as
|
|
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 =
|
|
4214
|
+
const fullPath = join16(cwd, file.relativePath);
|
|
3651
4215
|
let content;
|
|
3652
4216
|
try {
|
|
3653
|
-
content =
|
|
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
|
|
3695
|
-
import { readFileSync as
|
|
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 (!
|
|
4261
|
+
if (!existsSync17(filePath))
|
|
3698
4262
|
return null;
|
|
3699
4263
|
try {
|
|
3700
|
-
return
|
|
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(
|
|
3791
|
-
() => parsePyprojectToml(
|
|
3792
|
-
() => parseCargoToml(
|
|
3793
|
-
() => parseGoMod(
|
|
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
|
|
3878
|
-
import { mkdirSync as mkdirSync7, existsSync as
|
|
3879
|
-
import { resolve as resolve2, dirname as dirname5, basename as basename5, join as
|
|
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
|
-
|
|
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 =
|
|
3896
|
-
if (
|
|
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 (!
|
|
4520
|
+
if (!existsSync18(dir))
|
|
3957
4521
|
return false;
|
|
3958
|
-
return
|
|
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
|
|
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 (!
|
|
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 =
|
|
4015
|
-
if (!
|
|
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
|
|
4103
|
-
import { existsSync as
|
|
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 =
|
|
4107
|
-
if (
|
|
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
|
|
4260
|
-
import { dirname as dirname6, join as
|
|
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 =
|
|
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 =
|
|
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 (
|
|
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 =
|
|
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
|
|
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 =
|
|
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
|
|
5326
|
+
import { existsSync as existsSync22, readFileSync as readFileSync16, statSync as statSync8 } from "fs";
|
|
4751
5327
|
function checkJsonFile(name, filePath, validator) {
|
|
4752
|
-
if (!
|
|
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 (!
|
|
5338
|
+
if (!existsSync22(filePath))
|
|
4763
5339
|
return { name, path: filePath, status: "missing" };
|
|
4764
5340
|
try {
|
|
4765
|
-
|
|
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 (
|
|
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
|
|
4885
|
-
import { join as
|
|
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 =
|
|
5516
|
+
const fullPath = join21(cwd, file.relativePath);
|
|
4941
5517
|
let content;
|
|
4942
5518
|
try {
|
|
4943
|
-
content =
|
|
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
|
|
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 && !
|
|
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
|
|
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 =
|
|
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
|
|
6385
|
+
import { existsSync as existsSync24, readFileSync as readFileSync19 } from "fs";
|
|
5810
6386
|
import { dirname as dirname9 } from "path";
|
|
5811
|
-
import { join as
|
|
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 =
|
|
5862
|
-
if (
|
|
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(
|
|
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
|
|
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 =
|
|
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(
|
|
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:
|
|
6734
|
+
const { readFileSync: readFileSync20 } = await import("fs");
|
|
6159
6735
|
let memoryContent;
|
|
6160
6736
|
try {
|
|
6161
|
-
memoryContent =
|
|
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
|
|
6726
|
-
import { existsSync as
|
|
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 =
|
|
6731
|
-
if (!
|
|
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 =
|
|
7313
|
+
const filePath = join23(templatesDir, `${templateName}.md`);
|
|
6738
7314
|
let content;
|
|
6739
|
-
if (
|
|
6740
|
-
content =
|
|
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
|
|
6894
|
-
import { existsSync as
|
|
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 =
|
|
6902
|
-
if (!
|
|
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 =
|
|
6910
|
-
if (!
|
|
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
|
|
7491
|
+
return join24(dir, `${baseSlug}-${Date.now()}.md`);
|
|
6916
7492
|
}
|
|
6917
7493
|
function sameContent(filePath, expectedHash) {
|
|
6918
7494
|
try {
|
|
6919
|
-
return sha256(
|
|
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 =
|
|
6991
|
-
if (
|
|
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 =
|
|
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
|
|
7101
|
-
import { readdirSync as
|
|
7102
|
-
import { join as
|
|
7103
|
-
import { execSync as
|
|
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 (!
|
|
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 (!
|
|
7701
|
+
if (!existsSync27(filePath))
|
|
7126
7702
|
return { name, status: "missing" };
|
|
7127
7703
|
try {
|
|
7128
|
-
|
|
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 =
|
|
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 =
|
|
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
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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("~/") ?
|
|
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
|
|
7969
|
-
import { basename as basename7, dirname as dirname10, join as
|
|
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 ===
|
|
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 =
|
|
8568
|
+
const activeId = projectIdFor(activeCwd);
|
|
8040
8569
|
const registered = listRegisteredProjects();
|
|
8041
|
-
const startupId =
|
|
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 (
|
|
8678
|
+
if (existsSync28(join26(pkgRoot, "package.json")))
|
|
8146
8679
|
break;
|
|
8147
8680
|
pkgRoot = dirname10(pkgRoot);
|
|
8148
8681
|
}
|
|
8149
|
-
const dashboardOutDir =
|
|
8150
|
-
const dashboardBuilt =
|
|
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 =
|
|
8713
|
+
filePath = join26(dashboardOutDir, "index.html");
|
|
8181
8714
|
} else {
|
|
8182
|
-
filePath =
|
|
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(
|
|
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 =
|
|
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
|
|
9071
|
+
import { existsSync as existsSync29 } from "fs";
|
|
8539
9072
|
async function dashboard(cwd, args) {
|
|
8540
|
-
if (!
|
|
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
|
|
8559
|
-
import { resolve as resolve6, dirname as dirname11, basename as basename8, join as
|
|
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 =
|
|
8568
|
-
if (
|
|
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
|
|
8629
|
-
import { existsSync as
|
|
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
|
|
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) &&
|
|
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 =
|
|
8660
|
-
return { unitDir: unitDir2, unitFile:
|
|
9194
|
+
const unitDir2 = join28(home, ".config", "systemd", "user");
|
|
9195
|
+
return { unitDir: unitDir2, unitFile: join28(unitDir2, "mink-daemon.service") };
|
|
8661
9196
|
}
|
|
8662
|
-
const unitDir =
|
|
8663
|
-
return { unitDir, unitFile:
|
|
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 (
|
|
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
|
-
|
|
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 (!
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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 (!
|
|
9353
|
+
if (!existsSync32(logPath)) {
|
|
8819
9354
|
console.log("[mink] no log file found");
|
|
8820
9355
|
return;
|
|
8821
9356
|
}
|
|
8822
9357
|
try {
|
|
8823
|
-
const content =
|
|
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
|
|
9405
|
-
import { join as
|
|
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 =
|
|
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
|
|
9448
|
-
import { join as
|
|
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) =>
|
|
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 =
|
|
9476
|
-
if (
|
|
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 =
|
|
9488
|
-
if (
|
|
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 =
|
|
9508
|
-
if (!
|
|
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 =
|
|
9524
|
-
if (!
|
|
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 =
|
|
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
|
|
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 =
|
|
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 =
|
|
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
|
|
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 =
|
|
60533
|
-
result = [
|
|
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 =
|
|
61206
|
+
result = join31(result, this.generateExpression(stmt.id, Precedence.Sequence, E_TTT));
|
|
60672
61207
|
}
|
|
60673
61208
|
if (stmt.superClass) {
|
|
60674
|
-
fragment =
|
|
60675
|
-
result =
|
|
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 =
|
|
61223
|
+
var result = join31("do", this.maybeBlock(stmt.body, S_TFFF));
|
|
60689
61224
|
result = this.maybeBlockSuffix(stmt.body, result);
|
|
60690
|
-
return
|
|
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 =
|
|
61261
|
+
result = join31(result, "default");
|
|
60727
61262
|
if (isStatement(stmt.declaration)) {
|
|
60728
|
-
result =
|
|
61263
|
+
result = join31(result, this.generateStatement(stmt.declaration, bodyFlags));
|
|
60729
61264
|
} else {
|
|
60730
|
-
result =
|
|
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
|
|
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 =
|
|
61277
|
+
result = join31(result, "{" + space + "}");
|
|
60743
61278
|
} else if (stmt.specifiers[0].type === Syntax.ExportBatchSpecifier) {
|
|
60744
|
-
result =
|
|
61279
|
+
result = join31(result, this.generateExpression(stmt.specifiers[0], Precedence.Sequence, E_TTT));
|
|
60745
61280
|
} else {
|
|
60746
|
-
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 [
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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
|
-
|
|
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 =
|
|
61596
|
+
result = join31(result, ["else ", this.generateStatement(stmt.alternate, bodyFlags)]);
|
|
61062
61597
|
} else {
|
|
61063
|
-
result =
|
|
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 [
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
61876
|
+
result = join31(expr.operator, fragment);
|
|
61342
61877
|
} else {
|
|
61343
61878
|
result = [expr.operator];
|
|
61344
61879
|
if (expr.operator.length > 2) {
|
|
61345
|
-
result =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
61980
|
+
result = join31(result, this.generateExpression(expr.id, Precedence.Sequence, E_TTT));
|
|
61446
61981
|
}
|
|
61447
61982
|
if (expr.superClass) {
|
|
61448
|
-
fragment =
|
|
61449
|
-
result =
|
|
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
|
-
|
|
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
|
|
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 =
|
|
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 =
|
|
62211
|
+
result = join31(result, "if" + space);
|
|
61677
62212
|
fragment = this.generateExpression(expr.filter, Precedence.Sequence, E_TTT);
|
|
61678
|
-
result =
|
|
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 =
|
|
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 =
|
|
61699
|
-
fragment =
|
|
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
|
|
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 =
|
|
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 =
|
|
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
|
|
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
|
|
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 (!
|
|
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 (!
|
|
82417
|
+
if (!existsSync34(depsPath)) {
|
|
81883
82418
|
debugInstall(`deb.deps file was not found at ${depsPath}`);
|
|
81884
82419
|
return;
|
|
81885
82420
|
}
|
|
81886
|
-
const data =
|
|
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 (!
|
|
82459
|
+
if (!existsSync34(browserRoot)) {
|
|
81925
82460
|
await mkdir2(browserRoot, { recursive: true });
|
|
81926
82461
|
}
|
|
81927
82462
|
if (!options.unpack) {
|
|
81928
|
-
if (
|
|
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 (
|
|
81950
|
-
if (!
|
|
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 (!
|
|
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 (
|
|
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 (!
|
|
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
|
|
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:
|
|
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
|
|
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:
|
|
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:
|
|
87886
|
+
const { join: join32 } = await import("node:path");
|
|
87352
87887
|
const userDataDir = resolveDefaultUserDataDir3(Browser7.CHROME, platform2, convertPuppeteerChannelToBrowsersChannel2(options.channel));
|
|
87353
|
-
const portPath =
|
|
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
|
|
88112
|
+
import { existsSync as existsSync35 } from "node:fs";
|
|
87578
88113
|
import { tmpdir } from "node:os";
|
|
87579
|
-
import { join as
|
|
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 (!
|
|
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" &&
|
|
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
|
|
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 && !
|
|
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 && !
|
|
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
|
|
88613
|
-
import { join as
|
|
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 (
|
|
89153
|
+
if (existsSync36(p))
|
|
88619
89154
|
return p;
|
|
88620
89155
|
}
|
|
88621
|
-
const minkBrowsers =
|
|
88622
|
-
if (
|
|
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 =
|
|
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 =
|
|
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
|
|
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 =
|
|
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
|
|
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,
|
|
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 (!
|
|
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
|
|
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
|
|
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
|
|
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 (
|
|
90650
|
-
return
|
|
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 (!
|
|
91196
|
+
if (!existsSync39(dir))
|
|
90662
91197
|
return [];
|
|
90663
|
-
return readdirSync11(dir, { withFileTypes: true }).filter((d) => d.isDirectory() &&
|
|
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
|
|
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 =
|
|
90703
|
-
const srcFile =
|
|
90704
|
-
const destDir =
|
|
90705
|
-
if (!
|
|
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
|
-
|
|
91245
|
+
copyDirRecursive2(srcDir, destDir);
|
|
90711
91246
|
mkdirSync15(CLAUDE_SKILLS_DIR, { recursive: true });
|
|
90712
|
-
const symlink =
|
|
91247
|
+
const symlink = join34(CLAUDE_SKILLS_DIR, skillName);
|
|
90713
91248
|
try {
|
|
90714
|
-
if (
|
|
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 =
|
|
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 =
|
|
90733
|
-
if (!
|
|
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 =
|
|
91273
|
+
const symlink = join34(CLAUDE_SKILLS_DIR, skillName);
|
|
90739
91274
|
try {
|
|
90740
|
-
if (
|
|
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} (${
|
|
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
|
|
91306
|
+
function copyDirRecursive2(src, dest) {
|
|
90772
91307
|
const entries = readdirSync11(src, { withFileTypes: true });
|
|
90773
91308
|
for (const entry of entries) {
|
|
90774
|
-
const srcPath =
|
|
90775
|
-
const destPath =
|
|
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
|
-
|
|
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 =
|
|
90787
|
-
CLAUDE_SKILLS_DIR =
|
|
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
|
|
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
|
|
91333
|
+
existsSync as existsSync40,
|
|
90799
91334
|
mkdirSync as mkdirSync16,
|
|
90800
|
-
readFileSync as
|
|
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 (
|
|
90809
|
-
return
|
|
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 =
|
|
90822
|
-
if (
|
|
91356
|
+
const pkgPath = join35(dir, "package.json");
|
|
91357
|
+
if (existsSync40(pkgPath)) {
|
|
90823
91358
|
try {
|
|
90824
|
-
const pkg = JSON.parse(
|
|
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
|
|
91382
|
+
return join35(homedir7(), ".claude", "agents");
|
|
90848
91383
|
}
|
|
90849
91384
|
function installedAgentPath() {
|
|
90850
|
-
return
|
|
91385
|
+
return join35(claudeAgentsDir(), INSTALLED_FILE);
|
|
90851
91386
|
}
|
|
90852
91387
|
function installAgentDefinition(opts) {
|
|
90853
91388
|
const templatePath = getAgentTemplatePath();
|
|
90854
|
-
if (!
|
|
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 &&
|
|
91394
|
+
if (opts.skip && existsSync40(installed)) {
|
|
90860
91395
|
return { action: "skipped", path: installed };
|
|
90861
91396
|
}
|
|
90862
|
-
const template =
|
|
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 =
|
|
91403
|
+
const exists = existsSync40(installed);
|
|
90869
91404
|
if (!opts.force && exists) {
|
|
90870
|
-
const current =
|
|
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 (!
|
|
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
|
|
90999
|
-
import { join as
|
|
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(
|
|
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(
|
|
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
|
|
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|
|
|
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
|
-
|
|
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:
|
|
91442
|
-
const { existsSync:
|
|
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 =
|
|
91447
|
-
if (!
|
|
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
|
|
91472
|
-
import { join as
|
|
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 =
|
|
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(
|
|
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 =
|
|
91535
|
-
const cfgPath =
|
|
91536
|
-
if (
|
|
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(
|
|
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 =
|
|
91562
|
-
const sessionFile =
|
|
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 (
|
|
91588
|
-
const existing =
|
|
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:
|
|
92307
|
+
const { readFileSync: readFileSync31 } = await import("fs");
|
|
91770
92308
|
try {
|
|
91771
|
-
const pkg = JSON.parse(
|
|
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)");
|