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