@drewpayment/mink 0.10.0 → 0.11.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +62 -1
- 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 +1505 -896
- package/package.json +1 -1
- package/src/cli.ts +1 -1
- package/src/commands/init.ts +29 -4
- package/src/commands/note.ts +2 -2
- package/src/commands/scan.ts +29 -6
- package/src/commands/session-start.ts +8 -2
- package/src/commands/sync-migrate.ts +404 -7
- package/src/commands/sync.ts +5 -2
- package/src/commands/wiki.ts +19 -3
- package/src/core/dashboard-server.ts +13 -5
- package/src/core/git-identity.ts +120 -0
- package/src/core/note-index.ts +50 -1
- package/src/core/paths.ts +19 -3
- package/src/core/project-id.ts +142 -5
- package/src/core/project-registry.ts +122 -13
- package/src/core/scanner.ts +19 -3
- package/src/core/sync.ts +7 -1
- package/src/types/config.ts +9 -0
- package/src/types/note.ts +1 -0
- /package/dashboard/out/_next/static/{frTrvF6NV-Xl2bLk21NkY → WDjkNLHEd_wI-oOzLyblH}/_buildManifest.js +0 -0
- /package/dashboard/out/_next/static/{frTrvF6NV-Xl2bLk21NkY → WDjkNLHEd_wI-oOzLyblH}/_ssgManifest.js +0 -0
package/dist/cli.js
CHANGED
|
@@ -163,19 +163,598 @@ function isSessionState(value) {
|
|
|
163
163
|
}
|
|
164
164
|
var init_session = () => {};
|
|
165
165
|
|
|
166
|
+
// src/core/git-identity.ts
|
|
167
|
+
import { execSync } from "child_process";
|
|
168
|
+
import { existsSync, realpathSync } from "fs";
|
|
169
|
+
function gitOut(cwd, args) {
|
|
170
|
+
if (!existsSync(cwd))
|
|
171
|
+
return null;
|
|
172
|
+
try {
|
|
173
|
+
return execSync(`git ${args}`, {
|
|
174
|
+
cwd,
|
|
175
|
+
timeout: GIT_TIMEOUT_MS,
|
|
176
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
177
|
+
}).toString().trim();
|
|
178
|
+
} catch {
|
|
179
|
+
return null;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
function canonicalCwd(cwd) {
|
|
183
|
+
try {
|
|
184
|
+
return realpathSync(cwd);
|
|
185
|
+
} catch {
|
|
186
|
+
return cwd;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
function getRepoRoot(cwd) {
|
|
190
|
+
const root = gitOut(canonicalCwd(cwd), "rev-parse --show-toplevel");
|
|
191
|
+
return root && root.length > 0 ? root : null;
|
|
192
|
+
}
|
|
193
|
+
function getRepoSubpath(cwd) {
|
|
194
|
+
const prefix = gitOut(canonicalCwd(cwd), "rev-parse --show-prefix");
|
|
195
|
+
if (prefix === null)
|
|
196
|
+
return "";
|
|
197
|
+
return prefix.replace(/\\/g, "/").replace(/\/+$/, "").replace(/^\/+/, "");
|
|
198
|
+
}
|
|
199
|
+
function getRepoRemote(cwd) {
|
|
200
|
+
const c = canonicalCwd(cwd);
|
|
201
|
+
const origin = gitOut(c, "config --get remote.origin.url");
|
|
202
|
+
if (origin && origin.length > 0)
|
|
203
|
+
return origin;
|
|
204
|
+
const list = gitOut(c, "remote");
|
|
205
|
+
if (!list)
|
|
206
|
+
return null;
|
|
207
|
+
const remotes = list.split(`
|
|
208
|
+
`).map((s) => s.trim()).filter((s) => s.length > 0).sort();
|
|
209
|
+
if (remotes.length === 0)
|
|
210
|
+
return null;
|
|
211
|
+
const url = gitOut(c, `config --get remote.${remotes[0]}.url`);
|
|
212
|
+
return url && url.length > 0 ? url : null;
|
|
213
|
+
}
|
|
214
|
+
function normalizeRemoteUrl(url) {
|
|
215
|
+
if (!url)
|
|
216
|
+
return "";
|
|
217
|
+
let s = url.trim();
|
|
218
|
+
if (s.length === 0)
|
|
219
|
+
return "";
|
|
220
|
+
if (/^(file:|\.\.?\/|\/)/i.test(s))
|
|
221
|
+
return "";
|
|
222
|
+
const scp = s.match(/^([^@\s]+)@([^:\s]+):(.+)$/);
|
|
223
|
+
if (scp) {
|
|
224
|
+
s = `ssh://${scp[1]}@${scp[2]}/${scp[3]}`;
|
|
225
|
+
}
|
|
226
|
+
s = s.replace(/^[a-z][a-z0-9+.-]*:\/\//i, "");
|
|
227
|
+
s = s.replace(/^[^@/]*@/, "");
|
|
228
|
+
s = s.replace(/\/+$/, "").replace(/\.git$/i, "");
|
|
229
|
+
return s.toLowerCase();
|
|
230
|
+
}
|
|
231
|
+
function deriveGitIdentity(cwd) {
|
|
232
|
+
const root = getRepoRoot(cwd);
|
|
233
|
+
if (!root)
|
|
234
|
+
return null;
|
|
235
|
+
const remoteRaw = getRepoRemote(cwd);
|
|
236
|
+
if (!remoteRaw)
|
|
237
|
+
return null;
|
|
238
|
+
const remote = normalizeRemoteUrl(remoteRaw);
|
|
239
|
+
if (!remote)
|
|
240
|
+
return null;
|
|
241
|
+
const subpath = getRepoSubpath(cwd);
|
|
242
|
+
return { remote, subpath };
|
|
243
|
+
}
|
|
244
|
+
var GIT_TIMEOUT_MS = 2000;
|
|
245
|
+
var init_git_identity = () => {};
|
|
246
|
+
|
|
247
|
+
// src/core/fs-utils.ts
|
|
248
|
+
var exports_fs_utils = {};
|
|
249
|
+
__export(exports_fs_utils, {
|
|
250
|
+
safeReadJson: () => safeReadJson,
|
|
251
|
+
safeAppendText: () => safeAppendText,
|
|
252
|
+
atomicWriteText: () => atomicWriteText,
|
|
253
|
+
atomicWriteJson: () => atomicWriteJson
|
|
254
|
+
});
|
|
255
|
+
import { writeFileSync, readFileSync, appendFileSync, renameSync, mkdirSync } from "fs";
|
|
256
|
+
import { dirname } from "path";
|
|
257
|
+
function atomicWriteJson(filePath, data) {
|
|
258
|
+
const tmp = filePath + ".tmp";
|
|
259
|
+
mkdirSync(dirname(filePath), { recursive: true });
|
|
260
|
+
writeFileSync(tmp, JSON.stringify(data, null, 2));
|
|
261
|
+
renameSync(tmp, filePath);
|
|
262
|
+
}
|
|
263
|
+
function atomicWriteText(filePath, content) {
|
|
264
|
+
const tmp = filePath + ".tmp";
|
|
265
|
+
mkdirSync(dirname(filePath), { recursive: true });
|
|
266
|
+
writeFileSync(tmp, content);
|
|
267
|
+
renameSync(tmp, filePath);
|
|
268
|
+
}
|
|
269
|
+
function safeAppendText(filePath, content) {
|
|
270
|
+
mkdirSync(dirname(filePath), { recursive: true });
|
|
271
|
+
appendFileSync(filePath, content);
|
|
272
|
+
}
|
|
273
|
+
function safeReadJson(filePath) {
|
|
274
|
+
try {
|
|
275
|
+
const raw = readFileSync(filePath, "utf-8");
|
|
276
|
+
return JSON.parse(raw);
|
|
277
|
+
} catch {
|
|
278
|
+
return null;
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
var init_fs_utils = () => {};
|
|
282
|
+
|
|
283
|
+
// src/types/config.ts
|
|
284
|
+
function isValidConfigKey(key) {
|
|
285
|
+
return VALID_KEYS.has(key);
|
|
286
|
+
}
|
|
287
|
+
function getConfigKeyMeta(key) {
|
|
288
|
+
return CONFIG_KEYS.find((k) => k.key === key);
|
|
289
|
+
}
|
|
290
|
+
var CONFIG_KEYS, VALID_KEYS;
|
|
291
|
+
var init_config = __esm(() => {
|
|
292
|
+
CONFIG_KEYS = [
|
|
293
|
+
{
|
|
294
|
+
key: "wiki.path",
|
|
295
|
+
default: "~/.mink/wiki",
|
|
296
|
+
envVar: "MINK_WIKI_PATH",
|
|
297
|
+
description: "Wiki vault location",
|
|
298
|
+
scope: "local"
|
|
299
|
+
},
|
|
300
|
+
{
|
|
301
|
+
key: "wiki.enabled",
|
|
302
|
+
default: "true",
|
|
303
|
+
envVar: "MINK_WIKI_ENABLED",
|
|
304
|
+
description: "Enable/disable the wiki feature",
|
|
305
|
+
scope: "shared"
|
|
306
|
+
},
|
|
307
|
+
{
|
|
308
|
+
key: "wiki.sync-mode",
|
|
309
|
+
default: "immediate",
|
|
310
|
+
envVar: "MINK_WIKI_SYNC_MODE",
|
|
311
|
+
description: "Sync mode: immediate or batched",
|
|
312
|
+
scope: "shared"
|
|
313
|
+
},
|
|
314
|
+
{
|
|
315
|
+
key: "wiki.git-backup",
|
|
316
|
+
default: "false",
|
|
317
|
+
envVar: "MINK_WIKI_GIT_BACKUP",
|
|
318
|
+
description: "Deprecated: use sync.enabled instead",
|
|
319
|
+
scope: "shared"
|
|
320
|
+
},
|
|
321
|
+
{
|
|
322
|
+
key: "wiki.git-remote",
|
|
323
|
+
default: "origin",
|
|
324
|
+
envVar: "MINK_WIKI_GIT_REMOTE",
|
|
325
|
+
description: "Deprecated: use sync.remote-url instead",
|
|
326
|
+
scope: "shared"
|
|
327
|
+
},
|
|
328
|
+
{
|
|
329
|
+
key: "notes.default-category",
|
|
330
|
+
default: "inbox",
|
|
331
|
+
envVar: "MINK_NOTES_DEFAULT_CATEGORY",
|
|
332
|
+
description: "Default category for notes captured via CLI",
|
|
333
|
+
scope: "shared"
|
|
334
|
+
},
|
|
335
|
+
{
|
|
336
|
+
key: "sync.enabled",
|
|
337
|
+
default: "false",
|
|
338
|
+
envVar: "MINK_SYNC_ENABLED",
|
|
339
|
+
description: "Enable/disable automatic git sync of ~/.mink",
|
|
340
|
+
scope: "shared"
|
|
341
|
+
},
|
|
342
|
+
{
|
|
343
|
+
key: "sync.remote-url",
|
|
344
|
+
default: "",
|
|
345
|
+
envVar: "MINK_SYNC_REMOTE_URL",
|
|
346
|
+
description: "Git remote URL for ~/.mink sync",
|
|
347
|
+
scope: "shared"
|
|
348
|
+
},
|
|
349
|
+
{
|
|
350
|
+
key: "sync.last-push",
|
|
351
|
+
default: "",
|
|
352
|
+
envVar: "MINK_SYNC_LAST_PUSH",
|
|
353
|
+
description: "ISO timestamp of last successful sync push",
|
|
354
|
+
scope: "local"
|
|
355
|
+
},
|
|
356
|
+
{
|
|
357
|
+
key: "sync.last-pull",
|
|
358
|
+
default: "",
|
|
359
|
+
envVar: "MINK_SYNC_LAST_PULL",
|
|
360
|
+
description: "ISO timestamp of last successful sync pull",
|
|
361
|
+
scope: "local"
|
|
362
|
+
},
|
|
363
|
+
{
|
|
364
|
+
key: "channel.discord.bot-token",
|
|
365
|
+
default: "",
|
|
366
|
+
envVar: "MINK_CHANNEL_DISCORD_BOT_TOKEN",
|
|
367
|
+
description: "Discord bot token for Claude Code Channels",
|
|
368
|
+
scope: "local"
|
|
369
|
+
},
|
|
370
|
+
{
|
|
371
|
+
key: "channel.discord.enabled",
|
|
372
|
+
default: "false",
|
|
373
|
+
envVar: "MINK_CHANNEL_DISCORD_ENABLED",
|
|
374
|
+
description: "Auto-start Discord channel when daemon starts",
|
|
375
|
+
scope: "local"
|
|
376
|
+
},
|
|
377
|
+
{
|
|
378
|
+
key: "channel.discord.allowlist",
|
|
379
|
+
default: "",
|
|
380
|
+
envVar: "MINK_CHANNEL_DISCORD_ALLOWLIST",
|
|
381
|
+
description: "Comma-separated list of Discord user IDs permitted to DM the bot",
|
|
382
|
+
scope: "local"
|
|
383
|
+
},
|
|
384
|
+
{
|
|
385
|
+
key: "channel.default-platform",
|
|
386
|
+
default: "discord",
|
|
387
|
+
envVar: "MINK_CHANNEL_DEFAULT_PLATFORM",
|
|
388
|
+
description: "Default platform for mink channel start",
|
|
389
|
+
scope: "shared"
|
|
390
|
+
},
|
|
391
|
+
{
|
|
392
|
+
key: "channel.skip-permissions",
|
|
393
|
+
default: "true",
|
|
394
|
+
envVar: "MINK_CHANNEL_SKIP_PERMISSIONS",
|
|
395
|
+
description: "Pass --dangerously-skip-permissions so the channel can run without terminal prompts",
|
|
396
|
+
scope: "shared"
|
|
397
|
+
},
|
|
398
|
+
{
|
|
399
|
+
key: "cli.auto-update",
|
|
400
|
+
default: "false",
|
|
401
|
+
envVar: "MINK_CLI_AUTO_UPDATE",
|
|
402
|
+
description: "Auto-upgrade the mink CLI on schedule via the background scheduler",
|
|
403
|
+
scope: "shared"
|
|
404
|
+
},
|
|
405
|
+
{
|
|
406
|
+
key: "cli.auto-update-schedule",
|
|
407
|
+
default: "0 4 * * *",
|
|
408
|
+
envVar: "MINK_CLI_AUTO_UPDATE_SCHEDULE",
|
|
409
|
+
description: "Cron expression governing the cli-self-update scheduled task",
|
|
410
|
+
scope: "shared"
|
|
411
|
+
},
|
|
412
|
+
{
|
|
413
|
+
key: "cli.auto-update-package-manager",
|
|
414
|
+
default: "auto",
|
|
415
|
+
envVar: "MINK_CLI_AUTO_UPDATE_PACKAGE_MANAGER",
|
|
416
|
+
description: "Force a package manager (auto|npm|bun) for self-upgrade installs",
|
|
417
|
+
scope: "local"
|
|
418
|
+
},
|
|
419
|
+
{
|
|
420
|
+
key: "projects.identity",
|
|
421
|
+
default: "path-derived",
|
|
422
|
+
envVar: "MINK_PROJECTS_IDENTITY",
|
|
423
|
+
description: "Project identity strategy: path-derived (legacy) or git-remote (stable across machines)",
|
|
424
|
+
scope: "shared"
|
|
425
|
+
}
|
|
426
|
+
];
|
|
427
|
+
VALID_KEYS = new Set(CONFIG_KEYS.map((k) => k.key));
|
|
428
|
+
});
|
|
429
|
+
|
|
430
|
+
// src/core/global-config.ts
|
|
431
|
+
var exports_global_config = {};
|
|
432
|
+
__export(exports_global_config, {
|
|
433
|
+
setConfigValue: () => setConfigValue,
|
|
434
|
+
saveLocalConfig: () => saveLocalConfig,
|
|
435
|
+
saveGlobalConfig: () => saveGlobalConfig,
|
|
436
|
+
resolveConfigValue: () => resolveConfigValue,
|
|
437
|
+
resolveAllConfig: () => resolveAllConfig,
|
|
438
|
+
resetConfigKey: () => resetConfigKey,
|
|
439
|
+
resetAllConfig: () => resetAllConfig,
|
|
440
|
+
migrateConfigIfNeeded: () => migrateConfigIfNeeded,
|
|
441
|
+
loadLocalConfig: () => loadLocalConfig,
|
|
442
|
+
loadGlobalConfig: () => loadGlobalConfig
|
|
443
|
+
});
|
|
444
|
+
function loadConfigFile(path) {
|
|
445
|
+
const raw = safeReadJson(path);
|
|
446
|
+
if (raw === null)
|
|
447
|
+
return {};
|
|
448
|
+
if (typeof raw !== "object" || Array.isArray(raw)) {
|
|
449
|
+
console.warn("[mink] warning: corrupt config file at " + path);
|
|
450
|
+
return {};
|
|
451
|
+
}
|
|
452
|
+
return raw;
|
|
453
|
+
}
|
|
454
|
+
function loadGlobalConfig() {
|
|
455
|
+
return loadConfigFile(globalConfigPath());
|
|
456
|
+
}
|
|
457
|
+
function saveGlobalConfig(config) {
|
|
458
|
+
atomicWriteJson(globalConfigPath(), config);
|
|
459
|
+
}
|
|
460
|
+
function loadLocalConfig() {
|
|
461
|
+
return loadConfigFile(localConfigPath());
|
|
462
|
+
}
|
|
463
|
+
function saveLocalConfig(config) {
|
|
464
|
+
atomicWriteJson(localConfigPath(), config);
|
|
465
|
+
}
|
|
466
|
+
function loadConfigForScope(scope) {
|
|
467
|
+
return scope === "local" ? loadLocalConfig() : loadGlobalConfig();
|
|
468
|
+
}
|
|
469
|
+
function saveConfigForScope(scope, config) {
|
|
470
|
+
if (scope === "local") {
|
|
471
|
+
saveLocalConfig(config);
|
|
472
|
+
} else {
|
|
473
|
+
saveGlobalConfig(config);
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
function resolveConfigValue(key) {
|
|
477
|
+
const meta = getConfigKeyMeta(key);
|
|
478
|
+
const config = loadConfigForScope(meta.scope);
|
|
479
|
+
const envValue = process.env[meta.envVar];
|
|
480
|
+
const fileValue = config[key];
|
|
481
|
+
if (envValue !== undefined && envValue !== "") {
|
|
482
|
+
return {
|
|
483
|
+
value: envValue,
|
|
484
|
+
source: "environment variable",
|
|
485
|
+
scope: meta.scope,
|
|
486
|
+
configFileValue: fileValue
|
|
487
|
+
};
|
|
488
|
+
}
|
|
489
|
+
if (fileValue !== undefined) {
|
|
490
|
+
return { value: fileValue, source: "config file", scope: meta.scope };
|
|
491
|
+
}
|
|
492
|
+
return { value: meta.default, source: "default", scope: meta.scope };
|
|
493
|
+
}
|
|
494
|
+
function resolveAllConfig() {
|
|
495
|
+
return CONFIG_KEYS.map((meta) => ({
|
|
496
|
+
key: meta.key,
|
|
497
|
+
...resolveConfigValue(meta.key)
|
|
498
|
+
}));
|
|
499
|
+
}
|
|
500
|
+
function setConfigValue(key, value) {
|
|
501
|
+
const meta = getConfigKeyMeta(key);
|
|
502
|
+
const config = loadConfigForScope(meta.scope);
|
|
503
|
+
config[key] = value;
|
|
504
|
+
saveConfigForScope(meta.scope, config);
|
|
505
|
+
}
|
|
506
|
+
function resetConfigKey(key) {
|
|
507
|
+
const meta = getConfigKeyMeta(key);
|
|
508
|
+
const config = loadConfigForScope(meta.scope);
|
|
509
|
+
delete config[key];
|
|
510
|
+
saveConfigForScope(meta.scope, config);
|
|
511
|
+
}
|
|
512
|
+
function resetAllConfig() {
|
|
513
|
+
saveGlobalConfig({});
|
|
514
|
+
saveLocalConfig({});
|
|
515
|
+
}
|
|
516
|
+
function migrateConfigIfNeeded() {
|
|
517
|
+
if (migrationRan)
|
|
518
|
+
return;
|
|
519
|
+
migrationRan = true;
|
|
520
|
+
const { existsSync: existsSync2 } = __require("fs");
|
|
521
|
+
if (existsSync2(localConfigPath()))
|
|
522
|
+
return;
|
|
523
|
+
const shared = loadGlobalConfig();
|
|
524
|
+
const localKeys = CONFIG_KEYS.filter((k) => k.scope === "local");
|
|
525
|
+
const localConfig = {};
|
|
526
|
+
let hasLocal = false;
|
|
527
|
+
for (const meta of localKeys) {
|
|
528
|
+
const val = shared[meta.key];
|
|
529
|
+
if (val !== undefined) {
|
|
530
|
+
localConfig[meta.key] = val;
|
|
531
|
+
delete shared[meta.key];
|
|
532
|
+
hasLocal = true;
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
if (hasLocal) {
|
|
536
|
+
saveLocalConfig(localConfig);
|
|
537
|
+
saveGlobalConfig(shared);
|
|
538
|
+
}
|
|
539
|
+
}
|
|
540
|
+
var migrationRan = false;
|
|
541
|
+
var init_global_config = __esm(() => {
|
|
542
|
+
init_paths();
|
|
543
|
+
init_fs_utils();
|
|
544
|
+
init_config();
|
|
545
|
+
});
|
|
546
|
+
|
|
166
547
|
// src/core/project-id.ts
|
|
167
548
|
import { createHash } from "crypto";
|
|
168
|
-
import { basename } from "path";
|
|
549
|
+
import { basename, join } from "path";
|
|
550
|
+
import { existsSync as existsSync2, readFileSync as readFileSync2 } from "fs";
|
|
169
551
|
function slugify(name) {
|
|
170
552
|
return name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
|
|
171
553
|
}
|
|
554
|
+
function shortHash(input) {
|
|
555
|
+
return createHash("sha256").update(input).digest("hex").slice(0, 6);
|
|
556
|
+
}
|
|
172
557
|
function generateProjectId(absolutePath) {
|
|
173
558
|
const normalized = absolutePath.replace(/\/+$/, "");
|
|
174
559
|
const slug = slugify(basename(normalized));
|
|
175
|
-
const hash =
|
|
560
|
+
const hash = shortHash(normalized);
|
|
176
561
|
return `${slug}-${hash}`;
|
|
177
562
|
}
|
|
178
|
-
|
|
563
|
+
function validateProjectIdentifier(id) {
|
|
564
|
+
return typeof id === "string" && IDENTIFIER_PATTERN.test(id);
|
|
565
|
+
}
|
|
566
|
+
function readProjectOverride(cwd) {
|
|
567
|
+
const root = getRepoRoot(cwd) ?? cwd;
|
|
568
|
+
const overridePath = join(root, OVERRIDE_RELATIVE_PATH);
|
|
569
|
+
if (!existsSync2(overridePath))
|
|
570
|
+
return null;
|
|
571
|
+
let raw;
|
|
572
|
+
try {
|
|
573
|
+
raw = readFileSync2(overridePath, "utf-8");
|
|
574
|
+
} catch {
|
|
575
|
+
return null;
|
|
576
|
+
}
|
|
577
|
+
let parsed;
|
|
578
|
+
try {
|
|
579
|
+
parsed = JSON.parse(raw);
|
|
580
|
+
} catch {
|
|
581
|
+
warnInvalidOverride(overridePath, "file is not valid JSON");
|
|
582
|
+
return null;
|
|
583
|
+
}
|
|
584
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
585
|
+
warnInvalidOverride(overridePath, "expected a JSON object");
|
|
586
|
+
return null;
|
|
587
|
+
}
|
|
588
|
+
const id = parsed.projectId;
|
|
589
|
+
if (id === undefined)
|
|
590
|
+
return null;
|
|
591
|
+
if (!validateProjectIdentifier(id)) {
|
|
592
|
+
warnInvalidOverride(overridePath, "projectId must start with a letter or digit, contain only [a-z0-9._-], and be 1–128 characters");
|
|
593
|
+
return null;
|
|
594
|
+
}
|
|
595
|
+
return id;
|
|
596
|
+
}
|
|
597
|
+
function warnInvalidOverride(path, reason) {
|
|
598
|
+
if (warnedOverrides.has(path))
|
|
599
|
+
return;
|
|
600
|
+
warnedOverrides.add(path);
|
|
601
|
+
console.warn(`[mink] ignoring ${path}: ${reason}`);
|
|
602
|
+
}
|
|
603
|
+
function gitDerivedIdentity(cwd) {
|
|
604
|
+
const components = deriveGitIdentity(cwd);
|
|
605
|
+
if (!components)
|
|
606
|
+
return null;
|
|
607
|
+
const remoteLeaf = components.remote.split("/").filter((p) => p).pop();
|
|
608
|
+
const slugSource = components.subpath ? components.subpath.split("/").pop() : remoteLeaf ?? "project";
|
|
609
|
+
const slug = slugify(slugSource);
|
|
610
|
+
const hash = shortHash(`git:${components.remote}:${components.subpath}`);
|
|
611
|
+
return `${slug}-${hash}`;
|
|
612
|
+
}
|
|
613
|
+
function readIdentityMode() {
|
|
614
|
+
const envOverride = process.env.MINK_PROJECTS_IDENTITY;
|
|
615
|
+
if (envOverride === "git-remote" || envOverride === "path-derived") {
|
|
616
|
+
return envOverride;
|
|
617
|
+
}
|
|
618
|
+
try {
|
|
619
|
+
const { resolveConfigValue: resolveConfigValue2 } = (init_global_config(), __toCommonJS(exports_global_config));
|
|
620
|
+
const v = resolveConfigValue2("projects.identity").value;
|
|
621
|
+
if (v === "git-remote")
|
|
622
|
+
return "git-remote";
|
|
623
|
+
} catch {}
|
|
624
|
+
return "path-derived";
|
|
625
|
+
}
|
|
626
|
+
function resolveProjectIdentity(cwd) {
|
|
627
|
+
const mode = readIdentityMode();
|
|
628
|
+
if (mode === "path-derived") {
|
|
629
|
+
return { id: generateProjectId(cwd), source: "path-derived" };
|
|
630
|
+
}
|
|
631
|
+
const override = readProjectOverride(cwd);
|
|
632
|
+
if (override)
|
|
633
|
+
return { id: override, source: "override" };
|
|
634
|
+
const git = gitDerivedIdentity(cwd);
|
|
635
|
+
if (git)
|
|
636
|
+
return { id: git, source: "git-remote" };
|
|
637
|
+
return { id: generateProjectId(cwd), source: "path-derived" };
|
|
638
|
+
}
|
|
639
|
+
function projectIdFor(cwd) {
|
|
640
|
+
return resolveProjectIdentity(cwd).id;
|
|
641
|
+
}
|
|
642
|
+
var IDENTIFIER_PATTERN, OVERRIDE_RELATIVE_PATH = ".mink/project.json", warnedOverrides;
|
|
643
|
+
var init_project_id = __esm(() => {
|
|
644
|
+
init_git_identity();
|
|
645
|
+
IDENTIFIER_PATTERN = /^[a-z0-9][a-z0-9._-]{0,127}$/;
|
|
646
|
+
warnedOverrides = new Set;
|
|
647
|
+
});
|
|
648
|
+
|
|
649
|
+
// src/core/project-registry.ts
|
|
650
|
+
var exports_project_registry = {};
|
|
651
|
+
__export(exports_project_registry, {
|
|
652
|
+
setProjectPathForDevice: () => setProjectPathForDevice,
|
|
653
|
+
listRegisteredProjects: () => listRegisteredProjects,
|
|
654
|
+
getProjectMeta: () => getProjectMeta,
|
|
655
|
+
findProjectDirByIdOrAlias: () => findProjectDirByIdOrAlias,
|
|
656
|
+
addProjectAlias: () => addProjectAlias
|
|
657
|
+
});
|
|
658
|
+
import { readdirSync, existsSync as existsSync3 } from "fs";
|
|
659
|
+
import { join as join2 } from "path";
|
|
660
|
+
function projectMetaFilePath(projDir) {
|
|
661
|
+
return join2(projDir, "project-meta.json");
|
|
662
|
+
}
|
|
663
|
+
function getProjectMeta(projDir) {
|
|
664
|
+
const raw = safeReadJson(projectMetaFilePath(projDir));
|
|
665
|
+
if (raw === null || typeof raw !== "object" || Array.isArray(raw))
|
|
666
|
+
return null;
|
|
667
|
+
const obj = raw;
|
|
668
|
+
if (typeof obj.cwd !== "string" || typeof obj.name !== "string")
|
|
669
|
+
return null;
|
|
670
|
+
const aliases = Array.isArray(obj.aliases) ? obj.aliases.filter((s) => typeof s === "string") : undefined;
|
|
671
|
+
const pathsByDevice = obj.pathsByDevice && typeof obj.pathsByDevice === "object" && !Array.isArray(obj.pathsByDevice) ? Object.fromEntries(Object.entries(obj.pathsByDevice).filter(([, v]) => typeof v === "string")) : undefined;
|
|
672
|
+
return {
|
|
673
|
+
cwd: obj.cwd,
|
|
674
|
+
name: obj.name,
|
|
675
|
+
initTimestamp: obj.initTimestamp ?? "",
|
|
676
|
+
version: obj.version ?? "0.1.0",
|
|
677
|
+
aliases,
|
|
678
|
+
pathsByDevice
|
|
679
|
+
};
|
|
680
|
+
}
|
|
681
|
+
function addProjectAlias(projDir, aliasId) {
|
|
682
|
+
const path = projectMetaFilePath(projDir);
|
|
683
|
+
const raw = safeReadJson(path);
|
|
684
|
+
if (raw === null || typeof raw !== "object" || Array.isArray(raw))
|
|
685
|
+
return false;
|
|
686
|
+
const obj = raw;
|
|
687
|
+
const existing = Array.isArray(obj.aliases) ? obj.aliases.filter((s) => typeof s === "string") : [];
|
|
688
|
+
if (existing.includes(aliasId))
|
|
689
|
+
return false;
|
|
690
|
+
obj.aliases = [...existing, aliasId];
|
|
691
|
+
atomicWriteJson(path, obj);
|
|
692
|
+
return true;
|
|
693
|
+
}
|
|
694
|
+
function setProjectPathForDevice(projDir, deviceId, cwd) {
|
|
695
|
+
const path = projectMetaFilePath(projDir);
|
|
696
|
+
const raw = safeReadJson(path);
|
|
697
|
+
if (raw === null || typeof raw !== "object" || Array.isArray(raw))
|
|
698
|
+
return;
|
|
699
|
+
const obj = raw;
|
|
700
|
+
const existing = obj.pathsByDevice && typeof obj.pathsByDevice === "object" && !Array.isArray(obj.pathsByDevice) ? { ...obj.pathsByDevice } : {};
|
|
701
|
+
if (Object.keys(existing).length === 0 && typeof obj.cwd === "string" && obj.cwd !== cwd) {
|
|
702
|
+
existing[deviceId] = obj.cwd;
|
|
703
|
+
}
|
|
704
|
+
existing[deviceId] = cwd;
|
|
705
|
+
obj.pathsByDevice = existing;
|
|
706
|
+
obj.cwd = cwd;
|
|
707
|
+
atomicWriteJson(path, obj);
|
|
708
|
+
}
|
|
709
|
+
function listRegisteredProjects() {
|
|
710
|
+
const projectsDir = join2(minkRoot(), "projects");
|
|
711
|
+
if (!existsSync3(projectsDir))
|
|
712
|
+
return [];
|
|
713
|
+
const entries = readdirSync(projectsDir, { withFileTypes: true });
|
|
714
|
+
const projects = [];
|
|
715
|
+
for (const entry of entries) {
|
|
716
|
+
if (!entry.isDirectory())
|
|
717
|
+
continue;
|
|
718
|
+
const projDir = join2(projectsDir, entry.name);
|
|
719
|
+
const meta = getProjectMeta(projDir);
|
|
720
|
+
if (meta) {
|
|
721
|
+
projects.push({
|
|
722
|
+
id: entry.name,
|
|
723
|
+
cwd: meta.cwd,
|
|
724
|
+
name: meta.name,
|
|
725
|
+
version: meta.version,
|
|
726
|
+
aliases: meta.aliases ?? [],
|
|
727
|
+
pathsByDevice: meta.pathsByDevice ?? {}
|
|
728
|
+
});
|
|
729
|
+
}
|
|
730
|
+
}
|
|
731
|
+
return projects;
|
|
732
|
+
}
|
|
733
|
+
function findProjectDirByIdOrAlias(id) {
|
|
734
|
+
const projectsDir = join2(minkRoot(), "projects");
|
|
735
|
+
if (!existsSync3(projectsDir))
|
|
736
|
+
return null;
|
|
737
|
+
const primary = join2(projectsDir, id);
|
|
738
|
+
if (existsSync3(primary))
|
|
739
|
+
return primary;
|
|
740
|
+
let entries;
|
|
741
|
+
try {
|
|
742
|
+
entries = readdirSync(projectsDir);
|
|
743
|
+
} catch {
|
|
744
|
+
return null;
|
|
745
|
+
}
|
|
746
|
+
for (const name of entries) {
|
|
747
|
+
const projDir = join2(projectsDir, name);
|
|
748
|
+
const meta = getProjectMeta(projDir);
|
|
749
|
+
if (meta?.aliases?.includes(id))
|
|
750
|
+
return projDir;
|
|
751
|
+
}
|
|
752
|
+
return null;
|
|
753
|
+
}
|
|
754
|
+
var init_project_registry = __esm(() => {
|
|
755
|
+
init_paths();
|
|
756
|
+
init_fs_utils();
|
|
757
|
+
});
|
|
179
758
|
|
|
180
759
|
// src/core/paths.ts
|
|
181
760
|
var exports_paths = {};
|
|
@@ -215,10 +794,11 @@ __export(exports_paths, {
|
|
|
215
794
|
actionLogShardPath: () => actionLogShardPath,
|
|
216
795
|
actionLogPath: () => actionLogPath
|
|
217
796
|
});
|
|
218
|
-
import { join } from "path";
|
|
797
|
+
import { join as join3 } from "path";
|
|
798
|
+
import { existsSync as existsSync4 } from "fs";
|
|
219
799
|
import { homedir } from "os";
|
|
220
800
|
function resolveMinkRoot() {
|
|
221
|
-
return process.env.MINK_ROOT_OVERRIDE ||
|
|
801
|
+
return process.env.MINK_ROOT_OVERRIDE || join3(homedir(), ".mink");
|
|
222
802
|
}
|
|
223
803
|
function minkRoot() {
|
|
224
804
|
if (process.env.MINK_ROOT_OVERRIDE) {
|
|
@@ -227,104 +807,113 @@ function minkRoot() {
|
|
|
227
807
|
return MINK_ROOT;
|
|
228
808
|
}
|
|
229
809
|
function projectDir(cwd) {
|
|
230
|
-
const id =
|
|
231
|
-
|
|
810
|
+
const id = projectIdFor(cwd);
|
|
811
|
+
const primary = join3(minkRoot(), "projects", id);
|
|
812
|
+
if (existsSync4(primary))
|
|
813
|
+
return primary;
|
|
814
|
+
try {
|
|
815
|
+
const { findProjectDirByIdOrAlias: findProjectDirByIdOrAlias2 } = (init_project_registry(), __toCommonJS(exports_project_registry));
|
|
816
|
+
const aliased = findProjectDirByIdOrAlias2(id);
|
|
817
|
+
if (aliased)
|
|
818
|
+
return aliased;
|
|
819
|
+
} catch {}
|
|
820
|
+
return primary;
|
|
232
821
|
}
|
|
233
822
|
function sessionPath(cwd) {
|
|
234
|
-
return
|
|
823
|
+
return join3(projectDir(cwd), "session.json");
|
|
235
824
|
}
|
|
236
825
|
function fileIndexPath(cwd) {
|
|
237
|
-
return
|
|
826
|
+
return join3(projectDir(cwd), "file-index.json");
|
|
238
827
|
}
|
|
239
828
|
function configPath(cwd) {
|
|
240
|
-
return
|
|
829
|
+
return join3(projectDir(cwd), "config.json");
|
|
241
830
|
}
|
|
242
831
|
function learningMemoryPath(cwd) {
|
|
243
|
-
return
|
|
832
|
+
return join3(projectDir(cwd), "learning-memory.md");
|
|
244
833
|
}
|
|
245
834
|
function tokenLedgerPath(cwd) {
|
|
246
|
-
return
|
|
835
|
+
return join3(projectDir(cwd), "token-ledger.json");
|
|
247
836
|
}
|
|
248
837
|
function tokenLedgerArchivePath(cwd) {
|
|
249
|
-
return
|
|
838
|
+
return join3(projectDir(cwd), "token-ledger-archive.json");
|
|
250
839
|
}
|
|
251
840
|
function bugMemoryPath(cwd) {
|
|
252
|
-
return
|
|
841
|
+
return join3(projectDir(cwd), "bug-memory.json");
|
|
253
842
|
}
|
|
254
843
|
function actionLogPath(cwd) {
|
|
255
|
-
return
|
|
844
|
+
return join3(projectDir(cwd), "action-log.md");
|
|
256
845
|
}
|
|
257
846
|
function schedulerPidPath() {
|
|
258
|
-
return
|
|
847
|
+
return join3(minkRoot(), "scheduler.pid");
|
|
259
848
|
}
|
|
260
849
|
function schedulerLogPath() {
|
|
261
|
-
return
|
|
850
|
+
return join3(minkRoot(), "scheduler.log");
|
|
262
851
|
}
|
|
263
852
|
function schedulerManifestPath(cwd) {
|
|
264
|
-
return
|
|
853
|
+
return join3(projectDir(cwd), "scheduler-manifest.json");
|
|
265
854
|
}
|
|
266
855
|
function channelPidPath() {
|
|
267
|
-
return
|
|
856
|
+
return join3(minkRoot(), "channel.pid");
|
|
268
857
|
}
|
|
269
858
|
function channelLogPath() {
|
|
270
|
-
return
|
|
859
|
+
return join3(minkRoot(), "channel.log");
|
|
271
860
|
}
|
|
272
861
|
function globalConfigPath() {
|
|
273
|
-
return
|
|
862
|
+
return join3(minkRoot(), "config");
|
|
274
863
|
}
|
|
275
864
|
function localConfigPath() {
|
|
276
|
-
return
|
|
865
|
+
return join3(minkRoot(), "config.local");
|
|
277
866
|
}
|
|
278
867
|
function deviceIdPath() {
|
|
279
|
-
return
|
|
868
|
+
return join3(minkRoot(), "device-id");
|
|
280
869
|
}
|
|
281
870
|
function deviceRegistryPath() {
|
|
282
|
-
return
|
|
871
|
+
return join3(minkRoot(), "devices.json");
|
|
283
872
|
}
|
|
284
873
|
function projectMetaPath(cwd) {
|
|
285
|
-
return
|
|
874
|
+
return join3(projectDir(cwd), "project-meta.json");
|
|
286
875
|
}
|
|
287
876
|
function backupDirPath(cwd) {
|
|
288
|
-
return
|
|
877
|
+
return join3(projectDir(cwd), "backups");
|
|
289
878
|
}
|
|
290
879
|
function syncVersionPath() {
|
|
291
|
-
return
|
|
880
|
+
return join3(minkRoot(), ".mink-sync-version");
|
|
292
881
|
}
|
|
293
882
|
function projectStateDir(cwd) {
|
|
294
|
-
return
|
|
883
|
+
return join3(projectDir(cwd), "state");
|
|
295
884
|
}
|
|
296
885
|
function deviceShardDir(cwd, deviceId) {
|
|
297
|
-
return
|
|
886
|
+
return join3(projectStateDir(cwd), deviceId);
|
|
298
887
|
}
|
|
299
888
|
function tokenLedgerShardPath(cwd, deviceId) {
|
|
300
|
-
return
|
|
889
|
+
return join3(deviceShardDir(cwd, deviceId), "token-ledger.json");
|
|
301
890
|
}
|
|
302
891
|
function tokenLedgerArchiveShardPath(cwd, deviceId) {
|
|
303
|
-
return
|
|
892
|
+
return join3(deviceShardDir(cwd, deviceId), "token-ledger-archive.json");
|
|
304
893
|
}
|
|
305
894
|
function bugMemoryShardPath(cwd, deviceId) {
|
|
306
|
-
return
|
|
895
|
+
return join3(deviceShardDir(cwd, deviceId), "bug-memory.json");
|
|
307
896
|
}
|
|
308
897
|
function actionLogShardPath(cwd, deviceId) {
|
|
309
|
-
return
|
|
898
|
+
return join3(deviceShardDir(cwd, deviceId), "action-log.md");
|
|
310
899
|
}
|
|
311
900
|
function learningMemorySidecarPath(cwd, deviceId) {
|
|
312
|
-
return
|
|
901
|
+
return join3(projectDir(cwd), `learning-memory.${deviceId}.md`);
|
|
313
902
|
}
|
|
314
903
|
function fileIndexCountersPath(cwd) {
|
|
315
|
-
return
|
|
904
|
+
return join3(projectDir(cwd), ".mink-state-counters.json");
|
|
316
905
|
}
|
|
317
906
|
function designCapturesDir(cwd) {
|
|
318
|
-
return
|
|
907
|
+
return join3(projectDir(cwd), "design-captures");
|
|
319
908
|
}
|
|
320
909
|
function designReportPath(cwd) {
|
|
321
|
-
return
|
|
910
|
+
return join3(projectDir(cwd), "design-report.json");
|
|
322
911
|
}
|
|
323
912
|
function frameworkAdvisorPath(cwd) {
|
|
324
|
-
return
|
|
913
|
+
return join3(projectDir(cwd), "framework-advisor.md");
|
|
325
914
|
}
|
|
326
915
|
function frameworkAdvisorJsonPath(cwd) {
|
|
327
|
-
return
|
|
916
|
+
return join3(projectDir(cwd), "framework-advisor.json");
|
|
328
917
|
}
|
|
329
918
|
var MINK_ROOT;
|
|
330
919
|
var init_paths = __esm(() => {
|
|
@@ -332,42 +921,6 @@ var init_paths = __esm(() => {
|
|
|
332
921
|
MINK_ROOT = resolveMinkRoot();
|
|
333
922
|
});
|
|
334
923
|
|
|
335
|
-
// src/core/fs-utils.ts
|
|
336
|
-
var exports_fs_utils = {};
|
|
337
|
-
__export(exports_fs_utils, {
|
|
338
|
-
safeReadJson: () => safeReadJson,
|
|
339
|
-
safeAppendText: () => safeAppendText,
|
|
340
|
-
atomicWriteText: () => atomicWriteText,
|
|
341
|
-
atomicWriteJson: () => atomicWriteJson
|
|
342
|
-
});
|
|
343
|
-
import { writeFileSync, readFileSync, appendFileSync, renameSync, mkdirSync } from "fs";
|
|
344
|
-
import { dirname } from "path";
|
|
345
|
-
function atomicWriteJson(filePath, data) {
|
|
346
|
-
const tmp = filePath + ".tmp";
|
|
347
|
-
mkdirSync(dirname(filePath), { recursive: true });
|
|
348
|
-
writeFileSync(tmp, JSON.stringify(data, null, 2));
|
|
349
|
-
renameSync(tmp, filePath);
|
|
350
|
-
}
|
|
351
|
-
function atomicWriteText(filePath, content) {
|
|
352
|
-
const tmp = filePath + ".tmp";
|
|
353
|
-
mkdirSync(dirname(filePath), { recursive: true });
|
|
354
|
-
writeFileSync(tmp, content);
|
|
355
|
-
renameSync(tmp, filePath);
|
|
356
|
-
}
|
|
357
|
-
function safeAppendText(filePath, content) {
|
|
358
|
-
mkdirSync(dirname(filePath), { recursive: true });
|
|
359
|
-
appendFileSync(filePath, content);
|
|
360
|
-
}
|
|
361
|
-
function safeReadJson(filePath) {
|
|
362
|
-
try {
|
|
363
|
-
const raw = readFileSync(filePath, "utf-8");
|
|
364
|
-
return JSON.parse(raw);
|
|
365
|
-
} catch {
|
|
366
|
-
return null;
|
|
367
|
-
}
|
|
368
|
-
}
|
|
369
|
-
var init_fs_utils = () => {};
|
|
370
|
-
|
|
371
924
|
// src/core/action-log.ts
|
|
372
925
|
var exports_action_log = {};
|
|
373
926
|
__export(exports_action_log, {
|
|
@@ -386,7 +939,7 @@ __export(exports_action_log, {
|
|
|
386
939
|
consolidateLog: () => consolidateLog,
|
|
387
940
|
appendToLog: () => appendToLog
|
|
388
941
|
});
|
|
389
|
-
import { readFileSync as
|
|
942
|
+
import { readFileSync as readFileSync3 } from "fs";
|
|
390
943
|
function truncatePath(filePath, maxLen = 60) {
|
|
391
944
|
if (filePath.length <= maxLen)
|
|
392
945
|
return filePath;
|
|
@@ -473,7 +1026,7 @@ function appendToLog(logPath, text) {
|
|
|
473
1026
|
}
|
|
474
1027
|
function safeReadLog(logPath) {
|
|
475
1028
|
try {
|
|
476
|
-
return
|
|
1029
|
+
return readFileSync3(logPath, "utf-8");
|
|
477
1030
|
} catch {
|
|
478
1031
|
return "";
|
|
479
1032
|
}
|
|
@@ -618,14 +1171,14 @@ __export(exports_device, {
|
|
|
618
1171
|
listDevices: () => listDevices,
|
|
619
1172
|
getOrCreateDeviceId: () => getOrCreateDeviceId
|
|
620
1173
|
});
|
|
621
|
-
import { existsSync, readFileSync as
|
|
1174
|
+
import { existsSync as existsSync5, readFileSync as readFileSync4, writeFileSync as writeFileSync2, mkdirSync as mkdirSync2 } from "fs";
|
|
622
1175
|
import { dirname as dirname2 } from "path";
|
|
623
1176
|
import { hostname, platform } from "os";
|
|
624
1177
|
import { randomUUID } from "crypto";
|
|
625
1178
|
function getOrCreateDeviceId() {
|
|
626
1179
|
const idPath = deviceIdPath();
|
|
627
|
-
if (
|
|
628
|
-
return
|
|
1180
|
+
if (existsSync5(idPath)) {
|
|
1181
|
+
return readFileSync4(idPath, "utf-8").trim();
|
|
629
1182
|
}
|
|
630
1183
|
const id = randomUUID();
|
|
631
1184
|
mkdirSync2(dirname2(idPath), { recursive: true });
|
|
@@ -683,263 +1236,6 @@ var init_device = __esm(() => {
|
|
|
683
1236
|
init_fs_utils();
|
|
684
1237
|
});
|
|
685
1238
|
|
|
686
|
-
// src/types/config.ts
|
|
687
|
-
function isValidConfigKey(key) {
|
|
688
|
-
return VALID_KEYS.has(key);
|
|
689
|
-
}
|
|
690
|
-
function getConfigKeyMeta(key) {
|
|
691
|
-
return CONFIG_KEYS.find((k) => k.key === key);
|
|
692
|
-
}
|
|
693
|
-
var CONFIG_KEYS, VALID_KEYS;
|
|
694
|
-
var init_config = __esm(() => {
|
|
695
|
-
CONFIG_KEYS = [
|
|
696
|
-
{
|
|
697
|
-
key: "wiki.path",
|
|
698
|
-
default: "~/.mink/wiki",
|
|
699
|
-
envVar: "MINK_WIKI_PATH",
|
|
700
|
-
description: "Wiki vault location",
|
|
701
|
-
scope: "local"
|
|
702
|
-
},
|
|
703
|
-
{
|
|
704
|
-
key: "wiki.enabled",
|
|
705
|
-
default: "true",
|
|
706
|
-
envVar: "MINK_WIKI_ENABLED",
|
|
707
|
-
description: "Enable/disable the wiki feature",
|
|
708
|
-
scope: "shared"
|
|
709
|
-
},
|
|
710
|
-
{
|
|
711
|
-
key: "wiki.sync-mode",
|
|
712
|
-
default: "immediate",
|
|
713
|
-
envVar: "MINK_WIKI_SYNC_MODE",
|
|
714
|
-
description: "Sync mode: immediate or batched",
|
|
715
|
-
scope: "shared"
|
|
716
|
-
},
|
|
717
|
-
{
|
|
718
|
-
key: "wiki.git-backup",
|
|
719
|
-
default: "false",
|
|
720
|
-
envVar: "MINK_WIKI_GIT_BACKUP",
|
|
721
|
-
description: "Deprecated: use sync.enabled instead",
|
|
722
|
-
scope: "shared"
|
|
723
|
-
},
|
|
724
|
-
{
|
|
725
|
-
key: "wiki.git-remote",
|
|
726
|
-
default: "origin",
|
|
727
|
-
envVar: "MINK_WIKI_GIT_REMOTE",
|
|
728
|
-
description: "Deprecated: use sync.remote-url instead",
|
|
729
|
-
scope: "shared"
|
|
730
|
-
},
|
|
731
|
-
{
|
|
732
|
-
key: "notes.default-category",
|
|
733
|
-
default: "inbox",
|
|
734
|
-
envVar: "MINK_NOTES_DEFAULT_CATEGORY",
|
|
735
|
-
description: "Default category for notes captured via CLI",
|
|
736
|
-
scope: "shared"
|
|
737
|
-
},
|
|
738
|
-
{
|
|
739
|
-
key: "sync.enabled",
|
|
740
|
-
default: "false",
|
|
741
|
-
envVar: "MINK_SYNC_ENABLED",
|
|
742
|
-
description: "Enable/disable automatic git sync of ~/.mink",
|
|
743
|
-
scope: "shared"
|
|
744
|
-
},
|
|
745
|
-
{
|
|
746
|
-
key: "sync.remote-url",
|
|
747
|
-
default: "",
|
|
748
|
-
envVar: "MINK_SYNC_REMOTE_URL",
|
|
749
|
-
description: "Git remote URL for ~/.mink sync",
|
|
750
|
-
scope: "shared"
|
|
751
|
-
},
|
|
752
|
-
{
|
|
753
|
-
key: "sync.last-push",
|
|
754
|
-
default: "",
|
|
755
|
-
envVar: "MINK_SYNC_LAST_PUSH",
|
|
756
|
-
description: "ISO timestamp of last successful sync push",
|
|
757
|
-
scope: "local"
|
|
758
|
-
},
|
|
759
|
-
{
|
|
760
|
-
key: "sync.last-pull",
|
|
761
|
-
default: "",
|
|
762
|
-
envVar: "MINK_SYNC_LAST_PULL",
|
|
763
|
-
description: "ISO timestamp of last successful sync pull",
|
|
764
|
-
scope: "local"
|
|
765
|
-
},
|
|
766
|
-
{
|
|
767
|
-
key: "channel.discord.bot-token",
|
|
768
|
-
default: "",
|
|
769
|
-
envVar: "MINK_CHANNEL_DISCORD_BOT_TOKEN",
|
|
770
|
-
description: "Discord bot token for Claude Code Channels",
|
|
771
|
-
scope: "local"
|
|
772
|
-
},
|
|
773
|
-
{
|
|
774
|
-
key: "channel.discord.enabled",
|
|
775
|
-
default: "false",
|
|
776
|
-
envVar: "MINK_CHANNEL_DISCORD_ENABLED",
|
|
777
|
-
description: "Auto-start Discord channel when daemon starts",
|
|
778
|
-
scope: "local"
|
|
779
|
-
},
|
|
780
|
-
{
|
|
781
|
-
key: "channel.discord.allowlist",
|
|
782
|
-
default: "",
|
|
783
|
-
envVar: "MINK_CHANNEL_DISCORD_ALLOWLIST",
|
|
784
|
-
description: "Comma-separated list of Discord user IDs permitted to DM the bot",
|
|
785
|
-
scope: "local"
|
|
786
|
-
},
|
|
787
|
-
{
|
|
788
|
-
key: "channel.default-platform",
|
|
789
|
-
default: "discord",
|
|
790
|
-
envVar: "MINK_CHANNEL_DEFAULT_PLATFORM",
|
|
791
|
-
description: "Default platform for mink channel start",
|
|
792
|
-
scope: "shared"
|
|
793
|
-
},
|
|
794
|
-
{
|
|
795
|
-
key: "channel.skip-permissions",
|
|
796
|
-
default: "true",
|
|
797
|
-
envVar: "MINK_CHANNEL_SKIP_PERMISSIONS",
|
|
798
|
-
description: "Pass --dangerously-skip-permissions so the channel can run without terminal prompts",
|
|
799
|
-
scope: "shared"
|
|
800
|
-
},
|
|
801
|
-
{
|
|
802
|
-
key: "cli.auto-update",
|
|
803
|
-
default: "false",
|
|
804
|
-
envVar: "MINK_CLI_AUTO_UPDATE",
|
|
805
|
-
description: "Auto-upgrade the mink CLI on schedule via the background scheduler",
|
|
806
|
-
scope: "shared"
|
|
807
|
-
},
|
|
808
|
-
{
|
|
809
|
-
key: "cli.auto-update-schedule",
|
|
810
|
-
default: "0 4 * * *",
|
|
811
|
-
envVar: "MINK_CLI_AUTO_UPDATE_SCHEDULE",
|
|
812
|
-
description: "Cron expression governing the cli-self-update scheduled task",
|
|
813
|
-
scope: "shared"
|
|
814
|
-
},
|
|
815
|
-
{
|
|
816
|
-
key: "cli.auto-update-package-manager",
|
|
817
|
-
default: "auto",
|
|
818
|
-
envVar: "MINK_CLI_AUTO_UPDATE_PACKAGE_MANAGER",
|
|
819
|
-
description: "Force a package manager (auto|npm|bun) for self-upgrade installs",
|
|
820
|
-
scope: "local"
|
|
821
|
-
}
|
|
822
|
-
];
|
|
823
|
-
VALID_KEYS = new Set(CONFIG_KEYS.map((k) => k.key));
|
|
824
|
-
});
|
|
825
|
-
|
|
826
|
-
// src/core/global-config.ts
|
|
827
|
-
var exports_global_config = {};
|
|
828
|
-
__export(exports_global_config, {
|
|
829
|
-
setConfigValue: () => setConfigValue,
|
|
830
|
-
saveLocalConfig: () => saveLocalConfig,
|
|
831
|
-
saveGlobalConfig: () => saveGlobalConfig,
|
|
832
|
-
resolveConfigValue: () => resolveConfigValue,
|
|
833
|
-
resolveAllConfig: () => resolveAllConfig,
|
|
834
|
-
resetConfigKey: () => resetConfigKey,
|
|
835
|
-
resetAllConfig: () => resetAllConfig,
|
|
836
|
-
migrateConfigIfNeeded: () => migrateConfigIfNeeded,
|
|
837
|
-
loadLocalConfig: () => loadLocalConfig,
|
|
838
|
-
loadGlobalConfig: () => loadGlobalConfig
|
|
839
|
-
});
|
|
840
|
-
function loadConfigFile(path) {
|
|
841
|
-
const raw = safeReadJson(path);
|
|
842
|
-
if (raw === null)
|
|
843
|
-
return {};
|
|
844
|
-
if (typeof raw !== "object" || Array.isArray(raw)) {
|
|
845
|
-
console.warn("[mink] warning: corrupt config file at " + path);
|
|
846
|
-
return {};
|
|
847
|
-
}
|
|
848
|
-
return raw;
|
|
849
|
-
}
|
|
850
|
-
function loadGlobalConfig() {
|
|
851
|
-
return loadConfigFile(globalConfigPath());
|
|
852
|
-
}
|
|
853
|
-
function saveGlobalConfig(config) {
|
|
854
|
-
atomicWriteJson(globalConfigPath(), config);
|
|
855
|
-
}
|
|
856
|
-
function loadLocalConfig() {
|
|
857
|
-
return loadConfigFile(localConfigPath());
|
|
858
|
-
}
|
|
859
|
-
function saveLocalConfig(config) {
|
|
860
|
-
atomicWriteJson(localConfigPath(), config);
|
|
861
|
-
}
|
|
862
|
-
function loadConfigForScope(scope) {
|
|
863
|
-
return scope === "local" ? loadLocalConfig() : loadGlobalConfig();
|
|
864
|
-
}
|
|
865
|
-
function saveConfigForScope(scope, config) {
|
|
866
|
-
if (scope === "local") {
|
|
867
|
-
saveLocalConfig(config);
|
|
868
|
-
} else {
|
|
869
|
-
saveGlobalConfig(config);
|
|
870
|
-
}
|
|
871
|
-
}
|
|
872
|
-
function resolveConfigValue(key) {
|
|
873
|
-
const meta = getConfigKeyMeta(key);
|
|
874
|
-
const config = loadConfigForScope(meta.scope);
|
|
875
|
-
const envValue = process.env[meta.envVar];
|
|
876
|
-
const fileValue = config[key];
|
|
877
|
-
if (envValue !== undefined && envValue !== "") {
|
|
878
|
-
return {
|
|
879
|
-
value: envValue,
|
|
880
|
-
source: "environment variable",
|
|
881
|
-
scope: meta.scope,
|
|
882
|
-
configFileValue: fileValue
|
|
883
|
-
};
|
|
884
|
-
}
|
|
885
|
-
if (fileValue !== undefined) {
|
|
886
|
-
return { value: fileValue, source: "config file", scope: meta.scope };
|
|
887
|
-
}
|
|
888
|
-
return { value: meta.default, source: "default", scope: meta.scope };
|
|
889
|
-
}
|
|
890
|
-
function resolveAllConfig() {
|
|
891
|
-
return CONFIG_KEYS.map((meta) => ({
|
|
892
|
-
key: meta.key,
|
|
893
|
-
...resolveConfigValue(meta.key)
|
|
894
|
-
}));
|
|
895
|
-
}
|
|
896
|
-
function setConfigValue(key, value) {
|
|
897
|
-
const meta = getConfigKeyMeta(key);
|
|
898
|
-
const config = loadConfigForScope(meta.scope);
|
|
899
|
-
config[key] = value;
|
|
900
|
-
saveConfigForScope(meta.scope, config);
|
|
901
|
-
}
|
|
902
|
-
function resetConfigKey(key) {
|
|
903
|
-
const meta = getConfigKeyMeta(key);
|
|
904
|
-
const config = loadConfigForScope(meta.scope);
|
|
905
|
-
delete config[key];
|
|
906
|
-
saveConfigForScope(meta.scope, config);
|
|
907
|
-
}
|
|
908
|
-
function resetAllConfig() {
|
|
909
|
-
saveGlobalConfig({});
|
|
910
|
-
saveLocalConfig({});
|
|
911
|
-
}
|
|
912
|
-
function migrateConfigIfNeeded() {
|
|
913
|
-
if (migrationRan)
|
|
914
|
-
return;
|
|
915
|
-
migrationRan = true;
|
|
916
|
-
const { existsSync: existsSync2 } = __require("fs");
|
|
917
|
-
if (existsSync2(localConfigPath()))
|
|
918
|
-
return;
|
|
919
|
-
const shared = loadGlobalConfig();
|
|
920
|
-
const localKeys = CONFIG_KEYS.filter((k) => k.scope === "local");
|
|
921
|
-
const localConfig = {};
|
|
922
|
-
let hasLocal = false;
|
|
923
|
-
for (const meta of localKeys) {
|
|
924
|
-
const val = shared[meta.key];
|
|
925
|
-
if (val !== undefined) {
|
|
926
|
-
localConfig[meta.key] = val;
|
|
927
|
-
delete shared[meta.key];
|
|
928
|
-
hasLocal = true;
|
|
929
|
-
}
|
|
930
|
-
}
|
|
931
|
-
if (hasLocal) {
|
|
932
|
-
saveLocalConfig(localConfig);
|
|
933
|
-
saveGlobalConfig(shared);
|
|
934
|
-
}
|
|
935
|
-
}
|
|
936
|
-
var migrationRan = false;
|
|
937
|
-
var init_global_config = __esm(() => {
|
|
938
|
-
init_paths();
|
|
939
|
-
init_fs_utils();
|
|
940
|
-
init_config();
|
|
941
|
-
});
|
|
942
|
-
|
|
943
1239
|
// src/core/vault.ts
|
|
944
1240
|
var exports_vault = {};
|
|
945
1241
|
__export(exports_vault, {
|
|
@@ -966,54 +1262,54 @@ __export(exports_vault, {
|
|
|
966
1262
|
ensureVaultStructure: () => ensureVaultStructure,
|
|
967
1263
|
categoryToDir: () => categoryToDir
|
|
968
1264
|
});
|
|
969
|
-
import { join as
|
|
1265
|
+
import { join as join4, basename as basename2, resolve } from "path";
|
|
970
1266
|
import { homedir as homedir2 } from "os";
|
|
971
|
-
import { existsSync as
|
|
1267
|
+
import { existsSync as existsSync6, mkdirSync as mkdirSync3, symlinkSync, unlinkSync, lstatSync, readlinkSync } from "fs";
|
|
972
1268
|
function resolveVaultPath() {
|
|
973
1269
|
const resolved = resolveConfigValue("wiki.path");
|
|
974
1270
|
const raw = resolved.value;
|
|
975
|
-
const expanded = raw.startsWith("~/") ?
|
|
1271
|
+
const expanded = raw.startsWith("~/") ? join4(homedir2(), raw.slice(2)) : raw;
|
|
976
1272
|
return resolve(expanded);
|
|
977
1273
|
}
|
|
978
1274
|
function vaultRoot() {
|
|
979
1275
|
return resolveVaultPath();
|
|
980
1276
|
}
|
|
981
1277
|
function vaultInbox() {
|
|
982
|
-
return
|
|
1278
|
+
return join4(resolveVaultPath(), "inbox");
|
|
983
1279
|
}
|
|
984
1280
|
function vaultProjects(slug) {
|
|
985
|
-
const base =
|
|
986
|
-
return slug ?
|
|
1281
|
+
const base = join4(resolveVaultPath(), "projects");
|
|
1282
|
+
return slug ? join4(base, slug) : base;
|
|
987
1283
|
}
|
|
988
1284
|
function vaultAreas() {
|
|
989
|
-
return
|
|
1285
|
+
return join4(resolveVaultPath(), "areas");
|
|
990
1286
|
}
|
|
991
1287
|
function vaultDailyDir() {
|
|
992
|
-
return
|
|
1288
|
+
return join4(resolveVaultPath(), "areas", "daily");
|
|
993
1289
|
}
|
|
994
1290
|
function vaultResources() {
|
|
995
|
-
return
|
|
1291
|
+
return join4(resolveVaultPath(), "resources");
|
|
996
1292
|
}
|
|
997
1293
|
function vaultArchives() {
|
|
998
|
-
return
|
|
1294
|
+
return join4(resolveVaultPath(), "archives");
|
|
999
1295
|
}
|
|
1000
1296
|
function vaultTemplates() {
|
|
1001
|
-
return
|
|
1297
|
+
return join4(resolveVaultPath(), "templates");
|
|
1002
1298
|
}
|
|
1003
1299
|
function vaultPatterns() {
|
|
1004
|
-
return
|
|
1300
|
+
return join4(resolveVaultPath(), "patterns");
|
|
1005
1301
|
}
|
|
1006
1302
|
function vaultManifestPath() {
|
|
1007
|
-
return
|
|
1303
|
+
return join4(resolveVaultPath(), ".mink-vault.json");
|
|
1008
1304
|
}
|
|
1009
1305
|
function vaultIndexPath() {
|
|
1010
|
-
return
|
|
1306
|
+
return join4(resolveVaultPath(), ".mink-index.json");
|
|
1011
1307
|
}
|
|
1012
1308
|
function vaultMasterIndexPath() {
|
|
1013
|
-
return
|
|
1309
|
+
return join4(resolveVaultPath(), "_index.md");
|
|
1014
1310
|
}
|
|
1015
1311
|
function isVaultInitialized() {
|
|
1016
|
-
return
|
|
1312
|
+
return existsSync6(vaultManifestPath());
|
|
1017
1313
|
}
|
|
1018
1314
|
function isInsideVault(cwd) {
|
|
1019
1315
|
const vault = resolveVaultPath();
|
|
@@ -1034,23 +1330,23 @@ function loadVaultManifest() {
|
|
|
1034
1330
|
function ensureVaultStructure() {
|
|
1035
1331
|
const root = resolveVaultPath();
|
|
1036
1332
|
for (const dir of VAULT_DIRS) {
|
|
1037
|
-
mkdirSync3(
|
|
1333
|
+
mkdirSync3(join4(root, dir), { recursive: true });
|
|
1038
1334
|
}
|
|
1039
1335
|
}
|
|
1040
1336
|
function categoryToDir(category, projectSlug) {
|
|
1041
1337
|
const root = resolveVaultPath();
|
|
1042
1338
|
switch (category) {
|
|
1043
1339
|
case "projects":
|
|
1044
|
-
return projectSlug ?
|
|
1340
|
+
return projectSlug ? join4(root, "projects", projectSlug) : join4(root, "projects");
|
|
1045
1341
|
case "areas":
|
|
1046
|
-
return
|
|
1342
|
+
return join4(root, "areas");
|
|
1047
1343
|
case "resources":
|
|
1048
|
-
return
|
|
1344
|
+
return join4(root, "resources");
|
|
1049
1345
|
case "archives":
|
|
1050
|
-
return
|
|
1346
|
+
return join4(root, "archives");
|
|
1051
1347
|
case "inbox":
|
|
1052
1348
|
default:
|
|
1053
|
-
return
|
|
1349
|
+
return join4(root, "inbox");
|
|
1054
1350
|
}
|
|
1055
1351
|
}
|
|
1056
1352
|
function saveManifest(manifest) {
|
|
@@ -1058,16 +1354,16 @@ function saveManifest(manifest) {
|
|
|
1058
1354
|
}
|
|
1059
1355
|
function linkExternal(targetPath, name) {
|
|
1060
1356
|
const root = resolveVaultPath();
|
|
1061
|
-
const absTarget = targetPath.startsWith("~/") ?
|
|
1062
|
-
if (!
|
|
1357
|
+
const absTarget = targetPath.startsWith("~/") ? join4(homedir2(), targetPath.slice(2)) : resolve(targetPath);
|
|
1358
|
+
if (!existsSync6(absTarget)) {
|
|
1063
1359
|
return { ok: false, error: `target does not exist: ${absTarget}` };
|
|
1064
1360
|
}
|
|
1065
1361
|
if (!lstatSync(absTarget).isDirectory()) {
|
|
1066
1362
|
return { ok: false, error: `target is not a directory: ${absTarget}` };
|
|
1067
1363
|
}
|
|
1068
1364
|
const linkName = name ?? basename2(absTarget);
|
|
1069
|
-
const linkPath =
|
|
1070
|
-
if (
|
|
1365
|
+
const linkPath = join4(root, linkName);
|
|
1366
|
+
if (existsSync6(linkPath)) {
|
|
1071
1367
|
if (lstatSync(linkPath).isSymbolicLink()) {
|
|
1072
1368
|
const existing = readlinkSync(linkPath);
|
|
1073
1369
|
if (existing === absTarget) {
|
|
@@ -1089,8 +1385,8 @@ function linkExternal(targetPath, name) {
|
|
|
1089
1385
|
}
|
|
1090
1386
|
function unlinkExternal(name) {
|
|
1091
1387
|
const root = resolveVaultPath();
|
|
1092
|
-
const linkPath =
|
|
1093
|
-
if (!
|
|
1388
|
+
const linkPath = join4(root, name);
|
|
1389
|
+
if (!existsSync6(linkPath)) {
|
|
1094
1390
|
return { ok: false, error: `no link named "${name}" in the vault` };
|
|
1095
1391
|
}
|
|
1096
1392
|
if (!lstatSync(linkPath).isSymbolicLink()) {
|
|
@@ -1113,7 +1409,7 @@ var init_vault = __esm(() => {
|
|
|
1113
1409
|
init_global_config();
|
|
1114
1410
|
init_fs_utils();
|
|
1115
1411
|
init_fs_utils();
|
|
1116
|
-
DEFAULT_VAULT_PATH =
|
|
1412
|
+
DEFAULT_VAULT_PATH = join4(homedir2(), ".mink", "wiki");
|
|
1117
1413
|
VAULT_DIRS = [
|
|
1118
1414
|
"",
|
|
1119
1415
|
"inbox",
|
|
@@ -1128,11 +1424,12 @@ 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: "",
|
|
1432
|
+
lastFullScanTimestamp: "",
|
|
1136
1433
|
totalNotes: 0,
|
|
1137
1434
|
entries: {}
|
|
1138
1435
|
};
|
|
@@ -1261,12 +1558,14 @@ function rebuildVaultIndex() {
|
|
|
1261
1558
|
const files = collectAllMarkdown(root);
|
|
1262
1559
|
for (const file of files) {
|
|
1263
1560
|
try {
|
|
1264
|
-
const content =
|
|
1561
|
+
const content = readFileSync5(file.absolutePath, "utf-8");
|
|
1265
1562
|
const entry = buildEntryFromContent(file.relativePath, content, new Date(file.mtimeMs).toISOString());
|
|
1266
1563
|
updateVaultEntry(index, entry);
|
|
1267
1564
|
} catch {}
|
|
1268
1565
|
}
|
|
1269
|
-
|
|
1566
|
+
const now = new Date().toISOString();
|
|
1567
|
+
index.lastScanTimestamp = now;
|
|
1568
|
+
index.lastFullScanTimestamp = now;
|
|
1270
1569
|
saveVaultIndex(index);
|
|
1271
1570
|
return index;
|
|
1272
1571
|
}
|
|
@@ -1279,17 +1578,51 @@ function getRecentNotes(n) {
|
|
|
1279
1578
|
const index = loadVaultIndex();
|
|
1280
1579
|
return Object.values(index.entries).sort((a, b) => b.lastModified.localeCompare(a.lastModified)).slice(0, n);
|
|
1281
1580
|
}
|
|
1581
|
+
function vaultIndexStaleness() {
|
|
1582
|
+
const index = loadVaultIndex();
|
|
1583
|
+
const root = resolveVaultPath();
|
|
1584
|
+
const diskCount = collectAllMarkdown(root).length;
|
|
1585
|
+
const indexCount = Object.keys(index.entries).length;
|
|
1586
|
+
const lastFullScan = index.lastFullScanTimestamp || null;
|
|
1587
|
+
if (!lastFullScan) {
|
|
1588
|
+
return {
|
|
1589
|
+
isStale: true,
|
|
1590
|
+
reason: "no full scan on record",
|
|
1591
|
+
diskCount,
|
|
1592
|
+
indexCount,
|
|
1593
|
+
lastFullScan: null
|
|
1594
|
+
};
|
|
1595
|
+
}
|
|
1596
|
+
const delta = Math.abs(diskCount - indexCount);
|
|
1597
|
+
const threshold = Math.max(5, Math.floor(diskCount * 0.05));
|
|
1598
|
+
if (delta >= threshold) {
|
|
1599
|
+
return {
|
|
1600
|
+
isStale: true,
|
|
1601
|
+
reason: `${diskCount} files on disk but ${indexCount} in index`,
|
|
1602
|
+
diskCount,
|
|
1603
|
+
indexCount,
|
|
1604
|
+
lastFullScan
|
|
1605
|
+
};
|
|
1606
|
+
}
|
|
1607
|
+
return {
|
|
1608
|
+
isStale: false,
|
|
1609
|
+
reason: null,
|
|
1610
|
+
diskCount,
|
|
1611
|
+
indexCount,
|
|
1612
|
+
lastFullScan
|
|
1613
|
+
};
|
|
1614
|
+
}
|
|
1282
1615
|
function collectAllMarkdown(rootPath) {
|
|
1283
1616
|
const files = [];
|
|
1284
1617
|
function walk(dir) {
|
|
1285
1618
|
try {
|
|
1286
|
-
const entries =
|
|
1619
|
+
const entries = readdirSync2(dir, { withFileTypes: true });
|
|
1287
1620
|
for (const entry of entries) {
|
|
1288
1621
|
if (VAULT_EXCLUDES.has(entry.name))
|
|
1289
1622
|
continue;
|
|
1290
1623
|
if (entry.name.startsWith("."))
|
|
1291
1624
|
continue;
|
|
1292
|
-
const fullPath =
|
|
1625
|
+
const fullPath = join5(dir, entry.name);
|
|
1293
1626
|
if (entry.isDirectory()) {
|
|
1294
1627
|
walk(fullPath);
|
|
1295
1628
|
} else if (entry.name.endsWith(".md")) {
|
|
@@ -1320,11 +1653,11 @@ var init_note_index = __esm(() => {
|
|
|
1320
1653
|
});
|
|
1321
1654
|
|
|
1322
1655
|
// src/core/conflict-park.ts
|
|
1323
|
-
import { execSync } from "child_process";
|
|
1324
|
-
import { existsSync as
|
|
1325
|
-
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";
|
|
1326
1659
|
function git(args) {
|
|
1327
|
-
return
|
|
1660
|
+
return execSync2(`git ${args}`, {
|
|
1328
1661
|
cwd: minkRoot(),
|
|
1329
1662
|
timeout: GIT_TIMEOUT,
|
|
1330
1663
|
stdio: ["pipe", "pipe", "pipe"]
|
|
@@ -1339,7 +1672,7 @@ function gitSafe(args) {
|
|
|
1339
1672
|
}
|
|
1340
1673
|
function parkConflictingState(reason) {
|
|
1341
1674
|
const root = minkRoot();
|
|
1342
|
-
const inMerge =
|
|
1675
|
+
const inMerge = existsSync8(join6(root, ".git", "MERGE_HEAD")) || existsSync8(join6(root, ".git", "rebase-merge")) || existsSync8(join6(root, ".git", "rebase-apply"));
|
|
1343
1676
|
if (inMerge) {
|
|
1344
1677
|
gitSafe("merge --abort");
|
|
1345
1678
|
gitSafe("rebase --abort");
|
|
@@ -1396,12 +1729,12 @@ __export(exports_sync, {
|
|
|
1396
1729
|
disconnectSync: () => disconnectSync,
|
|
1397
1730
|
MINK_SYNC_VERSION: () => MINK_SYNC_VERSION
|
|
1398
1731
|
});
|
|
1399
|
-
import { existsSync as
|
|
1400
|
-
import { join as
|
|
1401
|
-
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";
|
|
1402
1735
|
function readSyncVersion() {
|
|
1403
1736
|
try {
|
|
1404
|
-
const raw =
|
|
1737
|
+
const raw = readFileSync6(syncVersionPath(), "utf-8").trim();
|
|
1405
1738
|
const n = parseInt(raw, 10);
|
|
1406
1739
|
return Number.isFinite(n) && n > 0 ? n : 1;
|
|
1407
1740
|
} catch {
|
|
@@ -1413,7 +1746,7 @@ function writeSyncVersion(version) {
|
|
|
1413
1746
|
`);
|
|
1414
1747
|
}
|
|
1415
1748
|
function git2(args, timeoutMs = GIT_TIMEOUT2) {
|
|
1416
|
-
return
|
|
1749
|
+
return execSync3(`git ${args}`, {
|
|
1417
1750
|
cwd: minkRoot(),
|
|
1418
1751
|
timeout: timeoutMs,
|
|
1419
1752
|
stdio: ["pipe", "pipe", "pipe"]
|
|
@@ -1430,14 +1763,14 @@ function isSyncInitialized() {
|
|
|
1430
1763
|
const enabled = resolveConfigValue("sync.enabled").value;
|
|
1431
1764
|
if (enabled !== "true")
|
|
1432
1765
|
return false;
|
|
1433
|
-
return
|
|
1766
|
+
return existsSync9(join7(minkRoot(), ".git"));
|
|
1434
1767
|
}
|
|
1435
1768
|
function ensureGitignore() {
|
|
1436
|
-
const gitignorePath =
|
|
1769
|
+
const gitignorePath = join7(minkRoot(), ".gitignore");
|
|
1437
1770
|
writeFileSync3(gitignorePath, GITIGNORE_CONTENTS);
|
|
1438
1771
|
}
|
|
1439
1772
|
function ensureGitAttributes() {
|
|
1440
|
-
const path =
|
|
1773
|
+
const path = join7(minkRoot(), ".gitattributes");
|
|
1441
1774
|
writeFileSync3(path, GITATTRIBUTES_CONTENTS);
|
|
1442
1775
|
}
|
|
1443
1776
|
function ensureMergeDriversRegistered() {
|
|
@@ -1451,7 +1784,7 @@ function ensureMergeDriversRegistered() {
|
|
|
1451
1784
|
}
|
|
1452
1785
|
function getSyncStatus() {
|
|
1453
1786
|
const enabled = resolveConfigValue("sync.enabled").value === "true";
|
|
1454
|
-
const gitInitialized =
|
|
1787
|
+
const gitInitialized = existsSync9(join7(minkRoot(), ".git"));
|
|
1455
1788
|
const remoteUrl = resolveConfigValue("sync.remote-url").value;
|
|
1456
1789
|
const lastPush = resolveConfigValue("sync.last-push").value;
|
|
1457
1790
|
const lastPull = resolveConfigValue("sync.last-pull").value;
|
|
@@ -1477,8 +1810,8 @@ function getSyncStatus() {
|
|
|
1477
1810
|
}
|
|
1478
1811
|
function initSync(remoteUrl) {
|
|
1479
1812
|
const root = minkRoot();
|
|
1480
|
-
const gitDir =
|
|
1481
|
-
if (
|
|
1813
|
+
const gitDir = join7(root, ".git");
|
|
1814
|
+
if (existsSync9(gitDir)) {
|
|
1482
1815
|
console.log("[mink] sync is already initialized in " + root);
|
|
1483
1816
|
console.log("[mink] run 'mink sync disconnect' first to reinitialize");
|
|
1484
1817
|
return;
|
|
@@ -1619,8 +1952,8 @@ function syncPush(onMessage = (msg) => console.error(msg)) {
|
|
|
1619
1952
|
}
|
|
1620
1953
|
function disconnectSync() {
|
|
1621
1954
|
const root = minkRoot();
|
|
1622
|
-
const gitDir =
|
|
1623
|
-
if (!
|
|
1955
|
+
const gitDir = join7(root, ".git");
|
|
1956
|
+
if (!existsSync9(gitDir)) {
|
|
1624
1957
|
console.log("[mink] sync is not initialized — nothing to disconnect");
|
|
1625
1958
|
return;
|
|
1626
1959
|
}
|
|
@@ -1642,7 +1975,7 @@ function detectRemoteDefaultBranch() {
|
|
|
1642
1975
|
`).map((b) => b.trim()).filter((b) => b.startsWith("origin/") && !b.includes("HEAD")).map((b) => b.replace("origin/", ""))[0];
|
|
1643
1976
|
return first ?? "main";
|
|
1644
1977
|
}
|
|
1645
|
-
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
|
|
1646
1979
|
scheduler.pid
|
|
1647
1980
|
scheduler.log
|
|
1648
1981
|
channel.pid
|
|
@@ -1692,22 +2025,25 @@ var init_sync = __esm(() => {
|
|
|
1692
2025
|
var exports_sync_migrate = {};
|
|
1693
2026
|
__export(exports_sync_migrate, {
|
|
1694
2027
|
syncMigrateCommand: () => syncMigrateCommand,
|
|
2028
|
+
rollbackProjectIdentities: () => rollbackProjectIdentities,
|
|
2029
|
+
planIdentityMigration: () => planIdentityMigration,
|
|
1695
2030
|
migrateSyncLayout: () => migrateSyncLayout
|
|
1696
2031
|
});
|
|
1697
2032
|
import {
|
|
1698
|
-
existsSync as
|
|
1699
|
-
readdirSync as
|
|
2033
|
+
existsSync as existsSync10,
|
|
2034
|
+
readdirSync as readdirSync3,
|
|
1700
2035
|
statSync as statSync2,
|
|
1701
2036
|
mkdirSync as mkdirSync4,
|
|
1702
2037
|
writeFileSync as writeFileSync4,
|
|
2038
|
+
readFileSync as readFileSync7,
|
|
1703
2039
|
renameSync as renameSync2,
|
|
1704
2040
|
unlinkSync as unlinkSync2
|
|
1705
2041
|
} from "fs";
|
|
1706
|
-
import { join as
|
|
1707
|
-
import { execSync as
|
|
2042
|
+
import { join as join8 } from "path";
|
|
2043
|
+
import { execSync as execSync4 } from "child_process";
|
|
1708
2044
|
function gitSafe3(args, timeoutMs = 5000) {
|
|
1709
2045
|
try {
|
|
1710
|
-
return
|
|
2046
|
+
return execSync4(`git ${args}`, {
|
|
1711
2047
|
cwd: minkRoot(),
|
|
1712
2048
|
timeout: timeoutMs,
|
|
1713
2049
|
stdio: ["pipe", "pipe", "pipe"]
|
|
@@ -1717,8 +2053,8 @@ function gitSafe3(args, timeoutMs = 5000) {
|
|
|
1717
2053
|
}
|
|
1718
2054
|
}
|
|
1719
2055
|
function acquireLock() {
|
|
1720
|
-
const path =
|
|
1721
|
-
if (
|
|
2056
|
+
const path = join8(minkRoot(), MIGRATE_LOCK);
|
|
2057
|
+
if (existsSync10(path)) {
|
|
1722
2058
|
try {
|
|
1723
2059
|
const ageMs = Date.now() - statSync2(path).mtimeMs;
|
|
1724
2060
|
if (ageMs < MIGRATE_LOCK_STALE_MS)
|
|
@@ -1735,13 +2071,13 @@ function acquireLock() {
|
|
|
1735
2071
|
}
|
|
1736
2072
|
function releaseLock() {
|
|
1737
2073
|
try {
|
|
1738
|
-
unlinkSync2(
|
|
2074
|
+
unlinkSync2(join8(minkRoot(), MIGRATE_LOCK));
|
|
1739
2075
|
} catch {}
|
|
1740
2076
|
}
|
|
1741
2077
|
function migrateFile(from, to) {
|
|
1742
|
-
if (!
|
|
2078
|
+
if (!existsSync10(from))
|
|
1743
2079
|
return true;
|
|
1744
|
-
mkdirSync4(
|
|
2080
|
+
mkdirSync4(join8(to, ".."), { recursive: true });
|
|
1745
2081
|
if (gitSafe3(`mv "${from}" "${to}"`) !== null)
|
|
1746
2082
|
return true;
|
|
1747
2083
|
try {
|
|
@@ -1752,7 +2088,7 @@ function migrateFile(from, to) {
|
|
|
1752
2088
|
}
|
|
1753
2089
|
}
|
|
1754
2090
|
function migrateProject(projDir, deviceId) {
|
|
1755
|
-
const shardDir =
|
|
2091
|
+
const shardDir = join8(projDir, "state", deviceId);
|
|
1756
2092
|
mkdirSync4(shardDir, { recursive: true });
|
|
1757
2093
|
for (const file of [
|
|
1758
2094
|
"token-ledger.json",
|
|
@@ -1760,25 +2096,25 @@ function migrateProject(projDir, deviceId) {
|
|
|
1760
2096
|
"bug-memory.json",
|
|
1761
2097
|
"action-log.md"
|
|
1762
2098
|
]) {
|
|
1763
|
-
const legacy =
|
|
1764
|
-
const shard =
|
|
1765
|
-
if (
|
|
2099
|
+
const legacy = join8(projDir, file);
|
|
2100
|
+
const shard = join8(shardDir, file);
|
|
2101
|
+
if (existsSync10(shard))
|
|
1766
2102
|
continue;
|
|
1767
2103
|
migrateFile(legacy, shard);
|
|
1768
2104
|
}
|
|
1769
|
-
const sidecar =
|
|
1770
|
-
if (!
|
|
2105
|
+
const sidecar = join8(projDir, `learning-memory.${deviceId}.md`);
|
|
2106
|
+
if (!existsSync10(sidecar)) {
|
|
1771
2107
|
try {
|
|
1772
2108
|
writeFileSync4(sidecar, "");
|
|
1773
2109
|
} catch {}
|
|
1774
2110
|
}
|
|
1775
2111
|
for (const f of ["session.json", "scheduler-manifest.json"]) {
|
|
1776
|
-
if (
|
|
1777
|
-
gitSafe3(`rm --cached "${
|
|
2112
|
+
if (existsSync10(join8(projDir, f))) {
|
|
2113
|
+
gitSafe3(`rm --cached "${join8(projDir, f)}"`);
|
|
1778
2114
|
}
|
|
1779
2115
|
}
|
|
1780
|
-
const indexPath =
|
|
1781
|
-
if (
|
|
2116
|
+
const indexPath = join8(projDir, "file-index.json");
|
|
2117
|
+
if (existsSync10(indexPath)) {
|
|
1782
2118
|
const raw = safeReadJson(indexPath);
|
|
1783
2119
|
if (raw && typeof raw.header === "object" && raw.header !== null && (raw.header.lifetimeHits > 0 || raw.header.lifetimeMisses > 0)) {
|
|
1784
2120
|
atomicWriteJson(fileIndexCountersPathFor(projDir), {
|
|
@@ -1792,31 +2128,31 @@ function migrateProject(projDir, deviceId) {
|
|
|
1792
2128
|
}
|
|
1793
2129
|
}
|
|
1794
2130
|
function fileIndexCountersPathFor(projDir) {
|
|
1795
|
-
return
|
|
2131
|
+
return join8(projDir, ".mink-state-counters.json");
|
|
1796
2132
|
}
|
|
1797
2133
|
function listProjects() {
|
|
1798
|
-
const projectsRoot =
|
|
1799
|
-
if (!
|
|
2134
|
+
const projectsRoot = join8(minkRoot(), "projects");
|
|
2135
|
+
if (!existsSync10(projectsRoot))
|
|
1800
2136
|
return [];
|
|
1801
2137
|
try {
|
|
1802
|
-
return
|
|
2138
|
+
return readdirSync3(projectsRoot).filter((name) => {
|
|
1803
2139
|
try {
|
|
1804
|
-
return statSync2(
|
|
2140
|
+
return statSync2(join8(projectsRoot, name)).isDirectory();
|
|
1805
2141
|
} catch {
|
|
1806
2142
|
return false;
|
|
1807
2143
|
}
|
|
1808
|
-
}).map((name) =>
|
|
2144
|
+
}).map((name) => join8(projectsRoot, name));
|
|
1809
2145
|
} catch {
|
|
1810
2146
|
return [];
|
|
1811
2147
|
}
|
|
1812
2148
|
}
|
|
1813
2149
|
function projectNeedsMigration(projDir) {
|
|
1814
|
-
const stateDir =
|
|
1815
|
-
if (
|
|
2150
|
+
const stateDir = join8(projDir, "state");
|
|
2151
|
+
if (existsSync10(stateDir)) {
|
|
1816
2152
|
try {
|
|
1817
|
-
const shards =
|
|
2153
|
+
const shards = readdirSync3(stateDir).filter((d) => {
|
|
1818
2154
|
try {
|
|
1819
|
-
return statSync2(
|
|
2155
|
+
return statSync2(join8(stateDir, d)).isDirectory();
|
|
1820
2156
|
} catch {
|
|
1821
2157
|
return false;
|
|
1822
2158
|
}
|
|
@@ -1831,7 +2167,7 @@ function projectNeedsMigration(projDir) {
|
|
|
1831
2167
|
"bug-memory.json",
|
|
1832
2168
|
"action-log.md"
|
|
1833
2169
|
]) {
|
|
1834
|
-
if (
|
|
2170
|
+
if (existsSync10(join8(projDir, f)))
|
|
1835
2171
|
return true;
|
|
1836
2172
|
}
|
|
1837
2173
|
return false;
|
|
@@ -1839,10 +2175,208 @@ function projectNeedsMigration(projDir) {
|
|
|
1839
2175
|
function listProjectsNeedingMigration() {
|
|
1840
2176
|
return listProjects().filter(projectNeedsMigration);
|
|
1841
2177
|
}
|
|
2178
|
+
function planIdentityMigration() {
|
|
2179
|
+
const plan = [];
|
|
2180
|
+
if (resolveConfigValue("projects.identity").value !== "git-remote") {
|
|
2181
|
+
return plan;
|
|
2182
|
+
}
|
|
2183
|
+
const projectsRoot = join8(minkRoot(), "projects");
|
|
2184
|
+
if (!existsSync10(projectsRoot))
|
|
2185
|
+
return plan;
|
|
2186
|
+
let entries;
|
|
2187
|
+
try {
|
|
2188
|
+
entries = readdirSync3(projectsRoot);
|
|
2189
|
+
} catch {
|
|
2190
|
+
return plan;
|
|
2191
|
+
}
|
|
2192
|
+
for (const oldId of entries) {
|
|
2193
|
+
const oldProjDir = join8(projectsRoot, oldId);
|
|
2194
|
+
try {
|
|
2195
|
+
if (!statSync2(oldProjDir).isDirectory())
|
|
2196
|
+
continue;
|
|
2197
|
+
} catch {
|
|
2198
|
+
continue;
|
|
2199
|
+
}
|
|
2200
|
+
const meta = getProjectMeta(oldProjDir);
|
|
2201
|
+
if (!meta)
|
|
2202
|
+
continue;
|
|
2203
|
+
if (!existsSync10(meta.cwd)) {
|
|
2204
|
+
plan.push({
|
|
2205
|
+
oldId,
|
|
2206
|
+
newId: null,
|
|
2207
|
+
cwd: meta.cwd,
|
|
2208
|
+
action: "skip-no-cwd",
|
|
2209
|
+
reason: "working-copy path not reachable on this device"
|
|
2210
|
+
});
|
|
2211
|
+
continue;
|
|
2212
|
+
}
|
|
2213
|
+
let newId;
|
|
2214
|
+
try {
|
|
2215
|
+
newId = resolveProjectIdentity(meta.cwd).id;
|
|
2216
|
+
} catch {
|
|
2217
|
+
continue;
|
|
2218
|
+
}
|
|
2219
|
+
if (newId === oldId) {
|
|
2220
|
+
plan.push({ oldId, newId, cwd: meta.cwd, action: "skip-unchanged" });
|
|
2221
|
+
continue;
|
|
2222
|
+
}
|
|
2223
|
+
const newProjDir = join8(projectsRoot, newId);
|
|
2224
|
+
if (existsSync10(newProjDir)) {
|
|
2225
|
+
plan.push({
|
|
2226
|
+
oldId,
|
|
2227
|
+
newId,
|
|
2228
|
+
cwd: meta.cwd,
|
|
2229
|
+
action: "skip-converged",
|
|
2230
|
+
reason: "destination already exists (from sync); alias-only update"
|
|
2231
|
+
});
|
|
2232
|
+
continue;
|
|
2233
|
+
}
|
|
2234
|
+
plan.push({ oldId, newId, cwd: meta.cwd, action: "rename" });
|
|
2235
|
+
}
|
|
2236
|
+
return plan;
|
|
2237
|
+
}
|
|
2238
|
+
function identityBackupRoot(timestamp) {
|
|
2239
|
+
return join8(minkRoot(), IDENTITY_BACKUP_DIRNAME, timestamp);
|
|
2240
|
+
}
|
|
2241
|
+
function ensureIdentityBackupTimestamp() {
|
|
2242
|
+
const now = new Date;
|
|
2243
|
+
return `${now.getUTCFullYear()}${String(now.getUTCMonth() + 1).padStart(2, "0")}${String(now.getUTCDate()).padStart(2, "0")}-${String(now.getUTCHours()).padStart(2, "0")}${String(now.getUTCMinutes()).padStart(2, "0")}${String(now.getUTCSeconds()).padStart(2, "0")}`;
|
|
2244
|
+
}
|
|
2245
|
+
function backupProjectForRollback(srcDir, backupDir) {
|
|
2246
|
+
try {
|
|
2247
|
+
mkdirSync4(backupDir, { recursive: true });
|
|
2248
|
+
copyDirRecursive(srcDir, backupDir, new Set(["backups"]));
|
|
2249
|
+
return backupDir;
|
|
2250
|
+
} catch {
|
|
2251
|
+
return null;
|
|
2252
|
+
}
|
|
2253
|
+
}
|
|
2254
|
+
function copyDirRecursive(src, dest, excludeNames) {
|
|
2255
|
+
mkdirSync4(dest, { recursive: true });
|
|
2256
|
+
const entries = readdirSync3(src, { withFileTypes: true });
|
|
2257
|
+
for (const entry of entries) {
|
|
2258
|
+
if (excludeNames.has(entry.name))
|
|
2259
|
+
continue;
|
|
2260
|
+
const srcPath = join8(src, entry.name);
|
|
2261
|
+
const destPath = join8(dest, entry.name);
|
|
2262
|
+
if (entry.isDirectory()) {
|
|
2263
|
+
copyDirRecursive(srcPath, destPath, excludeNames);
|
|
2264
|
+
} else if (entry.isFile()) {
|
|
2265
|
+
writeFileSync4(destPath, readFileSync7(srcPath));
|
|
2266
|
+
}
|
|
2267
|
+
}
|
|
2268
|
+
}
|
|
2269
|
+
function migrateProjectIdentities(deviceId) {
|
|
2270
|
+
if (resolveConfigValue("projects.identity").value !== "git-remote") {
|
|
2271
|
+
return { renamed: 0, visited: 0, backupDir: null };
|
|
2272
|
+
}
|
|
2273
|
+
const plan = planIdentityMigration();
|
|
2274
|
+
const willRename = plan.filter((p) => p.action === "rename");
|
|
2275
|
+
let backupRoot = null;
|
|
2276
|
+
if (willRename.length > 0) {
|
|
2277
|
+
backupRoot = identityBackupRoot(ensureIdentityBackupTimestamp());
|
|
2278
|
+
}
|
|
2279
|
+
let renamed = 0;
|
|
2280
|
+
let visited = plan.length;
|
|
2281
|
+
const projectsRoot = join8(minkRoot(), "projects");
|
|
2282
|
+
for (const entry of plan) {
|
|
2283
|
+
const oldProjDir = join8(projectsRoot, entry.oldId);
|
|
2284
|
+
if (entry.cwd && entry.action !== "skip-no-cwd") {
|
|
2285
|
+
try {
|
|
2286
|
+
setProjectPathForDevice(oldProjDir, deviceId, entry.cwd);
|
|
2287
|
+
} catch {}
|
|
2288
|
+
}
|
|
2289
|
+
if (entry.action === "skip-converged" && entry.newId) {
|
|
2290
|
+
const newProjDir2 = join8(projectsRoot, entry.newId);
|
|
2291
|
+
try {
|
|
2292
|
+
addProjectAlias(newProjDir2, entry.oldId);
|
|
2293
|
+
if (entry.cwd) {
|
|
2294
|
+
setProjectPathForDevice(newProjDir2, deviceId, entry.cwd);
|
|
2295
|
+
}
|
|
2296
|
+
} catch {}
|
|
2297
|
+
continue;
|
|
2298
|
+
}
|
|
2299
|
+
if (entry.action !== "rename" || !entry.newId)
|
|
2300
|
+
continue;
|
|
2301
|
+
if (backupRoot) {
|
|
2302
|
+
backupProjectForRollback(oldProjDir, join8(backupRoot, entry.oldId));
|
|
2303
|
+
}
|
|
2304
|
+
const newProjDir = join8(projectsRoot, entry.newId);
|
|
2305
|
+
const moved = gitSafe3(`mv "${oldProjDir}" "${newProjDir}"`) !== null || (() => {
|
|
2306
|
+
try {
|
|
2307
|
+
renameSync2(oldProjDir, newProjDir);
|
|
2308
|
+
return true;
|
|
2309
|
+
} catch {
|
|
2310
|
+
return false;
|
|
2311
|
+
}
|
|
2312
|
+
})();
|
|
2313
|
+
if (!moved)
|
|
2314
|
+
continue;
|
|
2315
|
+
try {
|
|
2316
|
+
addProjectAlias(newProjDir, entry.oldId);
|
|
2317
|
+
if (entry.cwd) {
|
|
2318
|
+
setProjectPathForDevice(newProjDir, deviceId, entry.cwd);
|
|
2319
|
+
}
|
|
2320
|
+
} catch {}
|
|
2321
|
+
renamed++;
|
|
2322
|
+
}
|
|
2323
|
+
return { renamed, visited, backupDir: backupRoot };
|
|
2324
|
+
}
|
|
2325
|
+
function rollbackProjectIdentities() {
|
|
2326
|
+
const results = [];
|
|
2327
|
+
const projectsRoot = join8(minkRoot(), "projects");
|
|
2328
|
+
if (!existsSync10(projectsRoot))
|
|
2329
|
+
return results;
|
|
2330
|
+
let entries;
|
|
2331
|
+
try {
|
|
2332
|
+
entries = readdirSync3(projectsRoot);
|
|
2333
|
+
} catch {
|
|
2334
|
+
return results;
|
|
2335
|
+
}
|
|
2336
|
+
for (const currentId of entries) {
|
|
2337
|
+
const projDir = join8(projectsRoot, currentId);
|
|
2338
|
+
try {
|
|
2339
|
+
if (!statSync2(projDir).isDirectory())
|
|
2340
|
+
continue;
|
|
2341
|
+
} catch {
|
|
2342
|
+
continue;
|
|
2343
|
+
}
|
|
2344
|
+
const meta = getProjectMeta(projDir);
|
|
2345
|
+
if (!meta || !meta.aliases || meta.aliases.length === 0)
|
|
2346
|
+
continue;
|
|
2347
|
+
const restoredId = meta.aliases[meta.aliases.length - 1];
|
|
2348
|
+
const targetDir = join8(projectsRoot, restoredId);
|
|
2349
|
+
if (existsSync10(targetDir)) {
|
|
2350
|
+
results.push({ currentId, restoredId, ok: false });
|
|
2351
|
+
continue;
|
|
2352
|
+
}
|
|
2353
|
+
const remainingAliases = meta.aliases.slice(0, -1);
|
|
2354
|
+
const metaPath = join8(projDir, "project-meta.json");
|
|
2355
|
+
try {
|
|
2356
|
+
const raw = safeReadJson(metaPath);
|
|
2357
|
+
if (raw && typeof raw === "object" && !Array.isArray(raw)) {
|
|
2358
|
+
const obj = raw;
|
|
2359
|
+
obj.aliases = remainingAliases;
|
|
2360
|
+
atomicWriteJson(metaPath, obj);
|
|
2361
|
+
}
|
|
2362
|
+
} catch {}
|
|
2363
|
+
const moved = gitSafe3(`mv "${projDir}" "${targetDir}"`) !== null || (() => {
|
|
2364
|
+
try {
|
|
2365
|
+
renameSync2(projDir, targetDir);
|
|
2366
|
+
return true;
|
|
2367
|
+
} catch {
|
|
2368
|
+
return false;
|
|
2369
|
+
}
|
|
2370
|
+
})();
|
|
2371
|
+
results.push({ currentId, restoredId, ok: moved });
|
|
2372
|
+
}
|
|
2373
|
+
return results;
|
|
2374
|
+
}
|
|
1842
2375
|
function migrateSyncLayout() {
|
|
1843
2376
|
const fromVersion = readSyncVersion();
|
|
1844
2377
|
const pending = listProjectsNeedingMigration();
|
|
1845
|
-
|
|
2378
|
+
const identityMode = resolveConfigValue("projects.identity").value;
|
|
2379
|
+
if (fromVersion >= MINK_SYNC_VERSION && pending.length === 0 && identityMode !== "git-remote") {
|
|
1846
2380
|
return {
|
|
1847
2381
|
ranMigration: false,
|
|
1848
2382
|
fromVersion,
|
|
@@ -1887,13 +2421,18 @@ function migrateSyncLayout() {
|
|
|
1887
2421
|
processed++;
|
|
1888
2422
|
} catch {}
|
|
1889
2423
|
}
|
|
2424
|
+
let identity = { renamed: 0, visited: 0 };
|
|
2425
|
+
try {
|
|
2426
|
+
identity = migrateProjectIdentities(deviceId);
|
|
2427
|
+
} catch {}
|
|
1890
2428
|
if (remaining === 0 && listProjectsNeedingMigration().length === 0) {
|
|
1891
2429
|
writeSyncVersion(MINK_SYNC_VERSION);
|
|
1892
2430
|
}
|
|
1893
|
-
if (isSyncInitialized() && processed > 0) {
|
|
2431
|
+
if (isSyncInitialized() && (processed > 0 || identity.renamed > 0)) {
|
|
1894
2432
|
gitSafe3("add -A");
|
|
1895
2433
|
gitSafe3(`reset HEAD ".sync-migrate.lock"`);
|
|
1896
|
-
|
|
2434
|
+
const summary = identity.renamed > 0 ? `${processed} projects, ${identity.renamed} renamed for identity v3` : `${processed} projects`;
|
|
2435
|
+
gitSafe3(`commit -m "mink: migrate sync layout v${fromVersion} -> v${MINK_SYNC_VERSION} (device ${deviceId.slice(0, 8)}, ${summary})"`);
|
|
1897
2436
|
}
|
|
1898
2437
|
if (stashed) {
|
|
1899
2438
|
gitSafe3("stash pop");
|
|
@@ -1907,7 +2446,56 @@ function migrateSyncLayout() {
|
|
|
1907
2446
|
releaseLock();
|
|
1908
2447
|
}
|
|
1909
2448
|
}
|
|
1910
|
-
function syncMigrateCommand() {
|
|
2449
|
+
function syncMigrateCommand(args = []) {
|
|
2450
|
+
const dryRun = args.includes("--dry-run");
|
|
2451
|
+
const rollback = args.includes("--rollback");
|
|
2452
|
+
if (rollback && dryRun) {
|
|
2453
|
+
console.error("[mink] --rollback and --dry-run cannot be combined");
|
|
2454
|
+
process.exit(1);
|
|
2455
|
+
}
|
|
2456
|
+
if (dryRun) {
|
|
2457
|
+
const plan = planIdentityMigration();
|
|
2458
|
+
if (plan.length === 0) {
|
|
2459
|
+
console.log("[mink] sync migrate --dry-run: no projects to rename (flag is off or no projects on disk)");
|
|
2460
|
+
return;
|
|
2461
|
+
}
|
|
2462
|
+
const renames = plan.filter((p) => p.action === "rename");
|
|
2463
|
+
const converged = plan.filter((p) => p.action === "skip-converged");
|
|
2464
|
+
const skippedNoCwd = plan.filter((p) => p.action === "skip-no-cwd");
|
|
2465
|
+
const unchanged = plan.filter((p) => p.action === "skip-unchanged");
|
|
2466
|
+
console.log(`[mink] sync migrate --dry-run: ${renames.length} rename(s), ${converged.length} alias-only, ${skippedNoCwd.length} skipped (no cwd), ${unchanged.length} unchanged`);
|
|
2467
|
+
for (const p of renames) {
|
|
2468
|
+
console.log(` rename: ${p.oldId} → ${p.newId}`);
|
|
2469
|
+
}
|
|
2470
|
+
for (const p of converged) {
|
|
2471
|
+
console.log(` alias: ${p.oldId} → ${p.newId} (already on disk)`);
|
|
2472
|
+
}
|
|
2473
|
+
for (const p of skippedNoCwd) {
|
|
2474
|
+
console.log(` skip: ${p.oldId} — ${p.reason}`);
|
|
2475
|
+
}
|
|
2476
|
+
return;
|
|
2477
|
+
}
|
|
2478
|
+
if (rollback) {
|
|
2479
|
+
const results = rollbackProjectIdentities();
|
|
2480
|
+
if (results.length === 0) {
|
|
2481
|
+
console.log("[mink] sync migrate --rollback: nothing to roll back");
|
|
2482
|
+
return;
|
|
2483
|
+
}
|
|
2484
|
+
const ok = results.filter((r) => r.ok);
|
|
2485
|
+
const failed = results.filter((r) => !r.ok);
|
|
2486
|
+
console.log(`[mink] sync migrate --rollback: ${ok.length} restored, ${failed.length} failed`);
|
|
2487
|
+
for (const r of ok) {
|
|
2488
|
+
console.log(` restored: ${r.currentId} → ${r.restoredId}`);
|
|
2489
|
+
}
|
|
2490
|
+
for (const r of failed) {
|
|
2491
|
+
console.log(` failed: ${r.currentId} → ${r.restoredId} (destination already exists or rename blocked)`);
|
|
2492
|
+
}
|
|
2493
|
+
if (ok.length > 0) {
|
|
2494
|
+
console.log(`
|
|
2495
|
+
[mink] tip: set projects.identity=path-derived to prevent the next session-start from re-migrating`);
|
|
2496
|
+
}
|
|
2497
|
+
return;
|
|
2498
|
+
}
|
|
1911
2499
|
const result = migrateSyncLayout();
|
|
1912
2500
|
if (!result.ranMigration) {
|
|
1913
2501
|
console.log(`[mink] sync migrate: ${result.message ?? "no-op"}`);
|
|
@@ -1915,12 +2503,15 @@ function syncMigrateCommand() {
|
|
|
1915
2503
|
}
|
|
1916
2504
|
console.log(`[mink] sync migrate: v${result.fromVersion} → v${result.toVersion} complete`);
|
|
1917
2505
|
}
|
|
1918
|
-
var MIGRATE_LOCK = ".sync-migrate.lock", MIGRATE_LOCK_STALE_MS = 300000, MIGRATE_BUDGET_MS = 5000;
|
|
2506
|
+
var MIGRATE_LOCK = ".sync-migrate.lock", MIGRATE_LOCK_STALE_MS = 300000, MIGRATE_BUDGET_MS = 5000, IDENTITY_BACKUP_DIRNAME = ".identity-rollback";
|
|
1919
2507
|
var init_sync_migrate = __esm(() => {
|
|
1920
2508
|
init_paths();
|
|
1921
2509
|
init_sync();
|
|
1922
2510
|
init_device();
|
|
1923
2511
|
init_fs_utils();
|
|
2512
|
+
init_project_id();
|
|
2513
|
+
init_project_registry();
|
|
2514
|
+
init_global_config();
|
|
1924
2515
|
});
|
|
1925
2516
|
|
|
1926
2517
|
// src/core/note-linker.ts
|
|
@@ -1931,8 +2522,8 @@ __export(exports_note_linker, {
|
|
|
1931
2522
|
extractWikilinks: () => extractWikilinks,
|
|
1932
2523
|
addBacklink: () => addBacklink
|
|
1933
2524
|
});
|
|
1934
|
-
import { join as
|
|
1935
|
-
import { existsSync as
|
|
2525
|
+
import { join as join9 } from "path";
|
|
2526
|
+
import { existsSync as existsSync11, readFileSync as readFileSync8, readdirSync as readdirSync4, statSync as statSync3 } from "fs";
|
|
1936
2527
|
function extractWikilinks(content) {
|
|
1937
2528
|
const links = [];
|
|
1938
2529
|
let match;
|
|
@@ -1958,9 +2549,9 @@ function insertWikilinks(content, targets) {
|
|
|
1958
2549
|
return result;
|
|
1959
2550
|
}
|
|
1960
2551
|
function addBacklink(targetNotePath, sourceTitle) {
|
|
1961
|
-
if (!
|
|
2552
|
+
if (!existsSync11(targetNotePath))
|
|
1962
2553
|
return;
|
|
1963
|
-
const content =
|
|
2554
|
+
const content = readFileSync8(targetNotePath, "utf-8");
|
|
1964
2555
|
if (content.includes(`[[${sourceTitle}]]`))
|
|
1965
2556
|
return;
|
|
1966
2557
|
const backlinkSection = `
|
|
@@ -2002,8 +2593,8 @@ function updateMasterIndex(vaultRootPath) {
|
|
|
2002
2593
|
{ name: "Patterns", dir: "patterns", emoji: "" }
|
|
2003
2594
|
];
|
|
2004
2595
|
for (const cat of categories) {
|
|
2005
|
-
const dirPath =
|
|
2006
|
-
if (!
|
|
2596
|
+
const dirPath = join9(vaultRootPath, cat.dir);
|
|
2597
|
+
if (!existsSync11(dirPath))
|
|
2007
2598
|
continue;
|
|
2008
2599
|
const files = collectMarkdownFiles(dirPath, vaultRootPath);
|
|
2009
2600
|
if (files.length === 0 && cat.dir !== "inbox")
|
|
@@ -2030,9 +2621,9 @@ function updateMasterIndex(vaultRootPath) {
|
|
|
2030
2621
|
function collectMarkdownFiles(dirPath, rootPath) {
|
|
2031
2622
|
const files = [];
|
|
2032
2623
|
try {
|
|
2033
|
-
const entries =
|
|
2624
|
+
const entries = readdirSync4(dirPath, { withFileTypes: true });
|
|
2034
2625
|
for (const entry of entries) {
|
|
2035
|
-
const fullPath =
|
|
2626
|
+
const fullPath = join9(dirPath, entry.name);
|
|
2036
2627
|
if (entry.isDirectory()) {
|
|
2037
2628
|
files.push(...collectMarkdownFiles(fullPath, rootPath));
|
|
2038
2629
|
} else if (entry.name.endsWith(".md") && !entry.name.startsWith("_")) {
|
|
@@ -2165,7 +2756,7 @@ var init_learning_memory = __esm(() => {
|
|
|
2165
2756
|
});
|
|
2166
2757
|
|
|
2167
2758
|
// src/core/token-ledger.ts
|
|
2168
|
-
import { join as
|
|
2759
|
+
import { join as join10 } from "path";
|
|
2169
2760
|
function addToLifetime(lifetime, session) {
|
|
2170
2761
|
lifetime.totalTokens += session.totals.estimatedTokens;
|
|
2171
2762
|
lifetime.totalReads += session.totals.readCount;
|
|
@@ -2296,13 +2887,13 @@ function createLedgerFinalizer(projectDir2, deviceIdOrThreshold, archiveThreshol
|
|
|
2296
2887
|
let archivePath;
|
|
2297
2888
|
let threshold;
|
|
2298
2889
|
if (typeof deviceIdOrThreshold === "string") {
|
|
2299
|
-
const shardDir =
|
|
2300
|
-
ledgerPath =
|
|
2301
|
-
archivePath =
|
|
2890
|
+
const shardDir = join10(projectDir2, "state", deviceIdOrThreshold);
|
|
2891
|
+
ledgerPath = join10(shardDir, "token-ledger.json");
|
|
2892
|
+
archivePath = join10(shardDir, "token-ledger-archive.json");
|
|
2302
2893
|
threshold = archiveThreshold;
|
|
2303
2894
|
} else {
|
|
2304
|
-
ledgerPath =
|
|
2305
|
-
archivePath =
|
|
2895
|
+
ledgerPath = join10(projectDir2, "token-ledger.json");
|
|
2896
|
+
archivePath = join10(projectDir2, "token-ledger-archive.json");
|
|
2306
2897
|
threshold = deviceIdOrThreshold ?? archiveThreshold;
|
|
2307
2898
|
}
|
|
2308
2899
|
return {
|
|
@@ -2442,16 +3033,16 @@ var init_bug_memory = __esm(() => {
|
|
|
2442
3033
|
});
|
|
2443
3034
|
|
|
2444
3035
|
// src/core/state-aggregator.ts
|
|
2445
|
-
import { existsSync as
|
|
2446
|
-
import { join as
|
|
3036
|
+
import { existsSync as existsSync12, readdirSync as readdirSync5, readFileSync as readFileSync9, statSync as statSync4 } from "fs";
|
|
3037
|
+
import { join as join11 } from "path";
|
|
2447
3038
|
function listDeviceShardsAt(projDir) {
|
|
2448
|
-
const stateDir =
|
|
2449
|
-
if (!
|
|
3039
|
+
const stateDir = join11(projDir, "state");
|
|
3040
|
+
if (!existsSync12(stateDir))
|
|
2450
3041
|
return [];
|
|
2451
3042
|
try {
|
|
2452
|
-
return
|
|
3043
|
+
return readdirSync5(stateDir).filter((name) => {
|
|
2453
3044
|
try {
|
|
2454
|
-
return statSync4(
|
|
3045
|
+
return statSync4(join11(stateDir, name)).isDirectory();
|
|
2455
3046
|
} catch {
|
|
2456
3047
|
return false;
|
|
2457
3048
|
}
|
|
@@ -2461,16 +3052,16 @@ function listDeviceShardsAt(projDir) {
|
|
|
2461
3052
|
}
|
|
2462
3053
|
}
|
|
2463
3054
|
function listLearningMemorySidecarPathsAt(projDir) {
|
|
2464
|
-
if (!
|
|
3055
|
+
if (!existsSync12(projDir))
|
|
2465
3056
|
return [];
|
|
2466
3057
|
try {
|
|
2467
|
-
return
|
|
3058
|
+
return readdirSync5(projDir).filter((f) => SIDECAR_RE.test(f)).map((f) => join11(projDir, f));
|
|
2468
3059
|
} catch {
|
|
2469
3060
|
return [];
|
|
2470
3061
|
}
|
|
2471
3062
|
}
|
|
2472
3063
|
function shardPath(projDir, deviceId, file) {
|
|
2473
|
-
return
|
|
3064
|
+
return join11(projDir, "state", deviceId, file);
|
|
2474
3065
|
}
|
|
2475
3066
|
function addLifetime(target, source) {
|
|
2476
3067
|
target.totalTokens += source.totalTokens;
|
|
@@ -2487,12 +3078,12 @@ function aggregateTokenLedgerAt(projDir) {
|
|
|
2487
3078
|
const seenSessions = new Set;
|
|
2488
3079
|
const sources = [
|
|
2489
3080
|
...listDeviceShardsAt(projDir).map((id) => shardPath(projDir, id, "token-ledger.json")),
|
|
2490
|
-
|
|
3081
|
+
join11(projDir, "token-ledger.json")
|
|
2491
3082
|
];
|
|
2492
3083
|
const seenFlagKeys = new Set;
|
|
2493
3084
|
const wasteFlags = [];
|
|
2494
3085
|
for (const path of sources) {
|
|
2495
|
-
if (!
|
|
3086
|
+
if (!existsSync12(path))
|
|
2496
3087
|
continue;
|
|
2497
3088
|
const ledger = loadLedger(path);
|
|
2498
3089
|
addLifetime(merged.lifetime, ledger.lifetime);
|
|
@@ -2526,10 +3117,10 @@ function aggregateBugMemoryAt(projDir) {
|
|
|
2526
3117
|
let maxNextId = 1;
|
|
2527
3118
|
const sources = [
|
|
2528
3119
|
...listDeviceShardsAt(projDir).map((id) => shardPath(projDir, id, "bug-memory.json")),
|
|
2529
|
-
|
|
3120
|
+
join11(projDir, "bug-memory.json")
|
|
2530
3121
|
];
|
|
2531
3122
|
for (const path of sources) {
|
|
2532
|
-
if (!
|
|
3123
|
+
if (!existsSync12(path))
|
|
2533
3124
|
continue;
|
|
2534
3125
|
const mem = loadBugMemory(path);
|
|
2535
3126
|
if (mem.nextId > maxNextId)
|
|
@@ -2569,10 +3160,10 @@ function aggregateActionLogAt(projDir) {
|
|
|
2569
3160
|
let order = 0;
|
|
2570
3161
|
const sources = [
|
|
2571
3162
|
...listDeviceShardsAt(projDir).map((id) => shardPath(projDir, id, "action-log.md")),
|
|
2572
|
-
|
|
3163
|
+
join11(projDir, "action-log.md")
|
|
2573
3164
|
];
|
|
2574
3165
|
for (const path of sources) {
|
|
2575
|
-
if (!
|
|
3166
|
+
if (!existsSync12(path))
|
|
2576
3167
|
continue;
|
|
2577
3168
|
const content = safeReadLog(path);
|
|
2578
3169
|
if (!content)
|
|
@@ -2597,11 +3188,11 @@ function aggregateActionLog(cwd) {
|
|
|
2597
3188
|
return aggregateActionLogAt(projectDir(cwd));
|
|
2598
3189
|
}
|
|
2599
3190
|
function aggregateLearningMemoryAt(projDir) {
|
|
2600
|
-
const canonicalPath =
|
|
3191
|
+
const canonicalPath = join11(projDir, "learning-memory.md");
|
|
2601
3192
|
let merged;
|
|
2602
|
-
if (
|
|
3193
|
+
if (existsSync12(canonicalPath)) {
|
|
2603
3194
|
try {
|
|
2604
|
-
merged = parseLearningMemory(
|
|
3195
|
+
merged = parseLearningMemory(readFileSync9(canonicalPath, "utf-8"));
|
|
2605
3196
|
} catch {
|
|
2606
3197
|
merged = createEmptyLearningMemory("unknown");
|
|
2607
3198
|
}
|
|
@@ -2611,7 +3202,7 @@ function aggregateLearningMemoryAt(projDir) {
|
|
|
2611
3202
|
for (const sidecarPath of listLearningMemorySidecarPathsAt(projDir)) {
|
|
2612
3203
|
let sidecar;
|
|
2613
3204
|
try {
|
|
2614
|
-
sidecar = parseLearningMemory(
|
|
3205
|
+
sidecar = parseLearningMemory(readFileSync9(sidecarPath, "utf-8"));
|
|
2615
3206
|
} catch {
|
|
2616
3207
|
continue;
|
|
2617
3208
|
}
|
|
@@ -2918,12 +3509,12 @@ var exports_reflect = {};
|
|
|
2918
3509
|
__export(exports_reflect, {
|
|
2919
3510
|
reflect: () => reflect
|
|
2920
3511
|
});
|
|
2921
|
-
import { existsSync as
|
|
3512
|
+
import { existsSync as existsSync13 } from "fs";
|
|
2922
3513
|
import { dirname as dirname3 } from "path";
|
|
2923
3514
|
function reflect(_cwd, memoryPath, configPath2) {
|
|
2924
3515
|
const projDir = dirname3(memoryPath);
|
|
2925
3516
|
const mem = aggregateLearningMemoryAt(projDir);
|
|
2926
|
-
if (totalEntryCount(mem) === 0 && !
|
|
3517
|
+
if (totalEntryCount(mem) === 0 && !existsSync13(memoryPath)) {
|
|
2927
3518
|
console.log("[mink] no learning memory found");
|
|
2928
3519
|
return null;
|
|
2929
3520
|
}
|
|
@@ -2982,10 +3573,11 @@ __export(exports_paths2, {
|
|
|
2982
3573
|
actionLogShardPath: () => actionLogShardPath2,
|
|
2983
3574
|
actionLogPath: () => actionLogPath2
|
|
2984
3575
|
});
|
|
2985
|
-
import { join as
|
|
3576
|
+
import { join as join13 } from "path";
|
|
3577
|
+
import { existsSync as existsSync15 } from "fs";
|
|
2986
3578
|
import { homedir as homedir3 } from "os";
|
|
2987
3579
|
function resolveMinkRoot2() {
|
|
2988
|
-
return process.env.MINK_ROOT_OVERRIDE ||
|
|
3580
|
+
return process.env.MINK_ROOT_OVERRIDE || join13(homedir3(), ".mink");
|
|
2989
3581
|
}
|
|
2990
3582
|
function minkRoot2() {
|
|
2991
3583
|
if (process.env.MINK_ROOT_OVERRIDE) {
|
|
@@ -2994,104 +3586,113 @@ function minkRoot2() {
|
|
|
2994
3586
|
return MINK_ROOT2;
|
|
2995
3587
|
}
|
|
2996
3588
|
function projectDir2(cwd) {
|
|
2997
|
-
const id =
|
|
2998
|
-
|
|
3589
|
+
const id = projectIdFor(cwd);
|
|
3590
|
+
const primary = join13(minkRoot2(), "projects", id);
|
|
3591
|
+
if (existsSync15(primary))
|
|
3592
|
+
return primary;
|
|
3593
|
+
try {
|
|
3594
|
+
const { findProjectDirByIdOrAlias: findProjectDirByIdOrAlias2 } = (init_project_registry(), __toCommonJS(exports_project_registry));
|
|
3595
|
+
const aliased = findProjectDirByIdOrAlias2(id);
|
|
3596
|
+
if (aliased)
|
|
3597
|
+
return aliased;
|
|
3598
|
+
} catch {}
|
|
3599
|
+
return primary;
|
|
2999
3600
|
}
|
|
3000
3601
|
function sessionPath2(cwd) {
|
|
3001
|
-
return
|
|
3602
|
+
return join13(projectDir2(cwd), "session.json");
|
|
3002
3603
|
}
|
|
3003
3604
|
function fileIndexPath2(cwd) {
|
|
3004
|
-
return
|
|
3605
|
+
return join13(projectDir2(cwd), "file-index.json");
|
|
3005
3606
|
}
|
|
3006
3607
|
function configPath2(cwd) {
|
|
3007
|
-
return
|
|
3608
|
+
return join13(projectDir2(cwd), "config.json");
|
|
3008
3609
|
}
|
|
3009
3610
|
function learningMemoryPath2(cwd) {
|
|
3010
|
-
return
|
|
3611
|
+
return join13(projectDir2(cwd), "learning-memory.md");
|
|
3011
3612
|
}
|
|
3012
3613
|
function tokenLedgerPath2(cwd) {
|
|
3013
|
-
return
|
|
3614
|
+
return join13(projectDir2(cwd), "token-ledger.json");
|
|
3014
3615
|
}
|
|
3015
3616
|
function tokenLedgerArchivePath2(cwd) {
|
|
3016
|
-
return
|
|
3617
|
+
return join13(projectDir2(cwd), "token-ledger-archive.json");
|
|
3017
3618
|
}
|
|
3018
3619
|
function bugMemoryPath2(cwd) {
|
|
3019
|
-
return
|
|
3620
|
+
return join13(projectDir2(cwd), "bug-memory.json");
|
|
3020
3621
|
}
|
|
3021
3622
|
function actionLogPath2(cwd) {
|
|
3022
|
-
return
|
|
3623
|
+
return join13(projectDir2(cwd), "action-log.md");
|
|
3023
3624
|
}
|
|
3024
3625
|
function schedulerPidPath2() {
|
|
3025
|
-
return
|
|
3626
|
+
return join13(minkRoot2(), "scheduler.pid");
|
|
3026
3627
|
}
|
|
3027
3628
|
function schedulerLogPath2() {
|
|
3028
|
-
return
|
|
3629
|
+
return join13(minkRoot2(), "scheduler.log");
|
|
3029
3630
|
}
|
|
3030
3631
|
function schedulerManifestPath2(cwd) {
|
|
3031
|
-
return
|
|
3632
|
+
return join13(projectDir2(cwd), "scheduler-manifest.json");
|
|
3032
3633
|
}
|
|
3033
3634
|
function channelPidPath2() {
|
|
3034
|
-
return
|
|
3635
|
+
return join13(minkRoot2(), "channel.pid");
|
|
3035
3636
|
}
|
|
3036
3637
|
function channelLogPath2() {
|
|
3037
|
-
return
|
|
3638
|
+
return join13(minkRoot2(), "channel.log");
|
|
3038
3639
|
}
|
|
3039
3640
|
function globalConfigPath2() {
|
|
3040
|
-
return
|
|
3641
|
+
return join13(minkRoot2(), "config");
|
|
3041
3642
|
}
|
|
3042
3643
|
function localConfigPath2() {
|
|
3043
|
-
return
|
|
3644
|
+
return join13(minkRoot2(), "config.local");
|
|
3044
3645
|
}
|
|
3045
3646
|
function deviceIdPath2() {
|
|
3046
|
-
return
|
|
3647
|
+
return join13(minkRoot2(), "device-id");
|
|
3047
3648
|
}
|
|
3048
3649
|
function deviceRegistryPath2() {
|
|
3049
|
-
return
|
|
3650
|
+
return join13(minkRoot2(), "devices.json");
|
|
3050
3651
|
}
|
|
3051
3652
|
function projectMetaPath2(cwd) {
|
|
3052
|
-
return
|
|
3653
|
+
return join13(projectDir2(cwd), "project-meta.json");
|
|
3053
3654
|
}
|
|
3054
3655
|
function backupDirPath2(cwd) {
|
|
3055
|
-
return
|
|
3656
|
+
return join13(projectDir2(cwd), "backups");
|
|
3056
3657
|
}
|
|
3057
3658
|
function syncVersionPath2() {
|
|
3058
|
-
return
|
|
3659
|
+
return join13(minkRoot2(), ".mink-sync-version");
|
|
3059
3660
|
}
|
|
3060
3661
|
function projectStateDir2(cwd) {
|
|
3061
|
-
return
|
|
3662
|
+
return join13(projectDir2(cwd), "state");
|
|
3062
3663
|
}
|
|
3063
3664
|
function deviceShardDir2(cwd, deviceId) {
|
|
3064
|
-
return
|
|
3665
|
+
return join13(projectStateDir2(cwd), deviceId);
|
|
3065
3666
|
}
|
|
3066
3667
|
function tokenLedgerShardPath2(cwd, deviceId) {
|
|
3067
|
-
return
|
|
3668
|
+
return join13(deviceShardDir2(cwd, deviceId), "token-ledger.json");
|
|
3068
3669
|
}
|
|
3069
3670
|
function tokenLedgerArchiveShardPath2(cwd, deviceId) {
|
|
3070
|
-
return
|
|
3671
|
+
return join13(deviceShardDir2(cwd, deviceId), "token-ledger-archive.json");
|
|
3071
3672
|
}
|
|
3072
3673
|
function bugMemoryShardPath2(cwd, deviceId) {
|
|
3073
|
-
return
|
|
3674
|
+
return join13(deviceShardDir2(cwd, deviceId), "bug-memory.json");
|
|
3074
3675
|
}
|
|
3075
3676
|
function actionLogShardPath2(cwd, deviceId) {
|
|
3076
|
-
return
|
|
3677
|
+
return join13(deviceShardDir2(cwd, deviceId), "action-log.md");
|
|
3077
3678
|
}
|
|
3078
3679
|
function learningMemorySidecarPath2(cwd, deviceId) {
|
|
3079
|
-
return
|
|
3680
|
+
return join13(projectDir2(cwd), `learning-memory.${deviceId}.md`);
|
|
3080
3681
|
}
|
|
3081
3682
|
function fileIndexCountersPath3(cwd) {
|
|
3082
|
-
return
|
|
3683
|
+
return join13(projectDir2(cwd), ".mink-state-counters.json");
|
|
3083
3684
|
}
|
|
3084
3685
|
function designCapturesDir2(cwd) {
|
|
3085
|
-
return
|
|
3686
|
+
return join13(projectDir2(cwd), "design-captures");
|
|
3086
3687
|
}
|
|
3087
3688
|
function designReportPath2(cwd) {
|
|
3088
|
-
return
|
|
3689
|
+
return join13(projectDir2(cwd), "design-report.json");
|
|
3089
3690
|
}
|
|
3090
3691
|
function frameworkAdvisorPath2(cwd) {
|
|
3091
|
-
return
|
|
3692
|
+
return join13(projectDir2(cwd), "framework-advisor.md");
|
|
3092
3693
|
}
|
|
3093
3694
|
function frameworkAdvisorJsonPath2(cwd) {
|
|
3094
|
-
return
|
|
3695
|
+
return join13(projectDir2(cwd), "framework-advisor.json");
|
|
3095
3696
|
}
|
|
3096
3697
|
var MINK_ROOT2;
|
|
3097
3698
|
var init_paths2 = __esm(() => {
|
|
@@ -3108,13 +3709,13 @@ __export(exports_backup, {
|
|
|
3108
3709
|
});
|
|
3109
3710
|
import {
|
|
3110
3711
|
mkdirSync as mkdirSync6,
|
|
3111
|
-
readdirSync as
|
|
3112
|
-
readFileSync as
|
|
3712
|
+
readdirSync as readdirSync6,
|
|
3713
|
+
readFileSync as readFileSync11,
|
|
3113
3714
|
writeFileSync as writeFileSync5,
|
|
3114
|
-
existsSync as
|
|
3715
|
+
existsSync as existsSync16,
|
|
3115
3716
|
statSync as statSync6
|
|
3116
3717
|
} from "fs";
|
|
3117
|
-
import { join as
|
|
3718
|
+
import { join as join14 } from "path";
|
|
3118
3719
|
function formatTimestamp(date) {
|
|
3119
3720
|
const y = date.getFullYear();
|
|
3120
3721
|
const mo = String(date.getMonth() + 1).padStart(2, "0");
|
|
@@ -3127,14 +3728,14 @@ function formatTimestamp(date) {
|
|
|
3127
3728
|
}
|
|
3128
3729
|
function copyDirectoryFiles(srcDir, destDir, excludeDirs) {
|
|
3129
3730
|
mkdirSync6(destDir, { recursive: true });
|
|
3130
|
-
const entries =
|
|
3731
|
+
const entries = readdirSync6(srcDir, { withFileTypes: true });
|
|
3131
3732
|
for (const entry of entries) {
|
|
3132
3733
|
if (entry.isDirectory()) {
|
|
3133
3734
|
if (excludeDirs.includes(entry.name))
|
|
3134
3735
|
continue;
|
|
3135
|
-
copyDirectoryFiles(
|
|
3736
|
+
copyDirectoryFiles(join14(srcDir, entry.name), join14(destDir, entry.name), excludeDirs);
|
|
3136
3737
|
} else if (entry.isFile()) {
|
|
3137
|
-
writeFileSync5(
|
|
3738
|
+
writeFileSync5(join14(destDir, entry.name), readFileSync11(join14(srcDir, entry.name)));
|
|
3138
3739
|
}
|
|
3139
3740
|
}
|
|
3140
3741
|
}
|
|
@@ -3143,25 +3744,25 @@ function createBackup(cwd) {
|
|
|
3143
3744
|
const dir = backupDirPath(cwd);
|
|
3144
3745
|
let name = base;
|
|
3145
3746
|
let suffix = 1;
|
|
3146
|
-
while (
|
|
3747
|
+
while (existsSync16(join14(dir, name))) {
|
|
3147
3748
|
name = `${base}-${suffix}`;
|
|
3148
3749
|
suffix++;
|
|
3149
3750
|
}
|
|
3150
3751
|
const src = projectDir(cwd);
|
|
3151
|
-
const dest =
|
|
3752
|
+
const dest = join14(dir, name);
|
|
3152
3753
|
copyDirectoryFiles(src, dest, ["backups"]);
|
|
3153
3754
|
return name;
|
|
3154
3755
|
}
|
|
3155
3756
|
function listBackups(cwd) {
|
|
3156
3757
|
const dir = backupDirPath(cwd);
|
|
3157
|
-
if (!
|
|
3758
|
+
if (!existsSync16(dir))
|
|
3158
3759
|
return [];
|
|
3159
|
-
const entries =
|
|
3760
|
+
const entries = readdirSync6(dir, { withFileTypes: true });
|
|
3160
3761
|
const backups = [];
|
|
3161
3762
|
for (const entry of entries) {
|
|
3162
3763
|
if (!entry.isDirectory() || !entry.name.startsWith("backup-"))
|
|
3163
3764
|
continue;
|
|
3164
|
-
const backupPath =
|
|
3765
|
+
const backupPath = join14(dir, entry.name);
|
|
3165
3766
|
const match = entry.name.match(/^backup-(\d{4})(\d{2})(\d{2})-(\d{2})(\d{2})(\d{2})(\d{3})?(?:-\d+)?$/);
|
|
3166
3767
|
let timestamp;
|
|
3167
3768
|
if (match) {
|
|
@@ -3171,7 +3772,7 @@ function listBackups(cwd) {
|
|
|
3171
3772
|
}
|
|
3172
3773
|
let fileCount = 0;
|
|
3173
3774
|
try {
|
|
3174
|
-
fileCount =
|
|
3775
|
+
fileCount = readdirSync6(backupPath).length;
|
|
3175
3776
|
} catch {}
|
|
3176
3777
|
backups.push({ name: entry.name, timestamp, path: backupPath, fileCount });
|
|
3177
3778
|
}
|
|
@@ -3184,8 +3785,8 @@ function listBackups(cwd) {
|
|
|
3184
3785
|
return backups;
|
|
3185
3786
|
}
|
|
3186
3787
|
function restoreBackup(cwd, backupName) {
|
|
3187
|
-
const backupPath =
|
|
3188
|
-
if (!
|
|
3788
|
+
const backupPath = join14(backupDirPath(cwd), backupName);
|
|
3789
|
+
if (!existsSync16(backupPath)) {
|
|
3189
3790
|
throw new Error(`backup not found: ${backupName}`);
|
|
3190
3791
|
}
|
|
3191
3792
|
createBackup(cwd);
|
|
@@ -3196,8 +3797,8 @@ var init_backup = __esm(() => {
|
|
|
3196
3797
|
});
|
|
3197
3798
|
|
|
3198
3799
|
// src/core/scanner.ts
|
|
3199
|
-
import { readdirSync as
|
|
3200
|
-
import { join as
|
|
3800
|
+
import { readdirSync as readdirSync7, statSync as statSync7 } from "fs";
|
|
3801
|
+
import { join as join15, relative } from "path";
|
|
3201
3802
|
function matchesPattern(name, pattern) {
|
|
3202
3803
|
if (pattern.includes("*")) {
|
|
3203
3804
|
const regex = new RegExp("^" + pattern.replace(/\./g, "\\.").replace(/\*/g, ".*") + "$");
|
|
@@ -3211,7 +3812,7 @@ function isExcluded(name, excludes) {
|
|
|
3211
3812
|
function walkDirectory(dir, projectRoot, excludes, results) {
|
|
3212
3813
|
let entries;
|
|
3213
3814
|
try {
|
|
3214
|
-
entries =
|
|
3815
|
+
entries = readdirSync7(dir, { withFileTypes: true });
|
|
3215
3816
|
} catch {
|
|
3216
3817
|
return;
|
|
3217
3818
|
}
|
|
@@ -3221,14 +3822,14 @@ function walkDirectory(dir, projectRoot, excludes, results) {
|
|
|
3221
3822
|
if (entry.isDirectory()) {
|
|
3222
3823
|
if (isExcluded(entry.name, excludes))
|
|
3223
3824
|
continue;
|
|
3224
|
-
walkDirectory(
|
|
3825
|
+
walkDirectory(join15(dir, entry.name), projectRoot, excludes, results);
|
|
3225
3826
|
continue;
|
|
3226
3827
|
}
|
|
3227
3828
|
if (entry.isFile()) {
|
|
3228
3829
|
if (isExcluded(entry.name, excludes))
|
|
3229
3830
|
continue;
|
|
3230
3831
|
try {
|
|
3231
|
-
const fullPath =
|
|
3832
|
+
const fullPath = join15(dir, entry.name);
|
|
3232
3833
|
const stat = statSync7(fullPath);
|
|
3233
3834
|
results.push({
|
|
3234
3835
|
relativePath: relative(projectRoot, fullPath),
|
|
@@ -3247,11 +3848,16 @@ function loadConfig(configPath3) {
|
|
|
3247
3848
|
function getExcludes(config) {
|
|
3248
3849
|
return [...DEFAULT_EXCLUDES, ...config.excludePatterns ?? []];
|
|
3249
3850
|
}
|
|
3250
|
-
function
|
|
3851
|
+
function scanProjectWithStats(projectRoot, excludes, maxFiles = DEFAULT_MAX_FILES) {
|
|
3251
3852
|
const results = [];
|
|
3252
3853
|
walkDirectory(projectRoot, projectRoot, excludes, results);
|
|
3253
3854
|
results.sort((a, b) => b.mtimeMs - a.mtimeMs);
|
|
3254
|
-
|
|
3855
|
+
const totalScanned = results.length;
|
|
3856
|
+
const files = results.slice(0, maxFiles);
|
|
3857
|
+
return { files, totalScanned, truncated: totalScanned - files.length };
|
|
3858
|
+
}
|
|
3859
|
+
function scanProject(projectRoot, excludes, maxFiles = DEFAULT_MAX_FILES) {
|
|
3860
|
+
return scanProjectWithStats(projectRoot, excludes, maxFiles).files;
|
|
3255
3861
|
}
|
|
3256
3862
|
var DEFAULT_EXCLUDES, DEFAULT_MAX_FILES = 500;
|
|
3257
3863
|
var init_scanner = __esm(() => {
|
|
@@ -3549,8 +4155,12 @@ var exports_scan = {};
|
|
|
3549
4155
|
__export(exports_scan, {
|
|
3550
4156
|
scan: () => scan
|
|
3551
4157
|
});
|
|
3552
|
-
import { readFileSync as
|
|
3553
|
-
import { join as
|
|
4158
|
+
import { readFileSync as readFileSync12 } from "fs";
|
|
4159
|
+
import { join as join16, relative as relative2 } from "path";
|
|
4160
|
+
function configRelativePath(cfgPath, cwd) {
|
|
4161
|
+
const rel = relative2(cwd, cfgPath);
|
|
4162
|
+
return rel.startsWith("..") ? cfgPath : rel;
|
|
4163
|
+
}
|
|
3554
4164
|
function loadExistingIndex(indexPath) {
|
|
3555
4165
|
const raw = safeReadJson(indexPath);
|
|
3556
4166
|
if (isFileIndex(raw))
|
|
@@ -3595,15 +4205,16 @@ function scan(cwd, options) {
|
|
|
3595
4205
|
}
|
|
3596
4206
|
const start = Date.now();
|
|
3597
4207
|
const index = loadExistingIndex(idxPath);
|
|
3598
|
-
const
|
|
4208
|
+
const stats = scanProjectWithStats(cwd, excludes, maxFiles);
|
|
4209
|
+
const scanned = stats.files;
|
|
3599
4210
|
const newIndex = createEmptyIndex();
|
|
3600
4211
|
newIndex.header.lifetimeHits = index.header.lifetimeHits;
|
|
3601
4212
|
newIndex.header.lifetimeMisses = index.header.lifetimeMisses;
|
|
3602
4213
|
for (const file of scanned) {
|
|
3603
|
-
const fullPath =
|
|
4214
|
+
const fullPath = join16(cwd, file.relativePath);
|
|
3604
4215
|
let content;
|
|
3605
4216
|
try {
|
|
3606
|
-
content =
|
|
4217
|
+
content = readFileSync12(fullPath, "utf-8");
|
|
3607
4218
|
} catch {
|
|
3608
4219
|
continue;
|
|
3609
4220
|
}
|
|
@@ -3619,7 +4230,13 @@ function scan(cwd, options) {
|
|
|
3619
4230
|
newIndex.header.lastScanTimestamp = new Date().toISOString();
|
|
3620
4231
|
atomicWriteJson(idxPath, newIndex);
|
|
3621
4232
|
const elapsed = Date.now() - start;
|
|
3622
|
-
|
|
4233
|
+
if (stats.truncated > 0) {
|
|
4234
|
+
console.log(`[mink] scanned ${stats.totalScanned} files; indexed ${newIndex.header.totalFiles} most recent in ${elapsed}ms`);
|
|
4235
|
+
console.log(` ${stats.truncated} files past maxFiles=${maxFiles} were not indexed`);
|
|
4236
|
+
console.log(` raise the cap by setting "maxFiles" in ${configRelativePath(cfgPath, cwd)}`);
|
|
4237
|
+
} else {
|
|
4238
|
+
console.log(`[mink] indexed ${newIndex.header.totalFiles} files in ${elapsed}ms`);
|
|
4239
|
+
}
|
|
3623
4240
|
}
|
|
3624
4241
|
var init_scan = __esm(() => {
|
|
3625
4242
|
init_paths();
|
|
@@ -3638,13 +4255,13 @@ __export(exports_seed, {
|
|
|
3638
4255
|
parseGoMod: () => parseGoMod,
|
|
3639
4256
|
parseCargoToml: () => parseCargoToml
|
|
3640
4257
|
});
|
|
3641
|
-
import { basename as basename4, join as
|
|
3642
|
-
import { readFileSync as
|
|
4258
|
+
import { basename as basename4, join as join17 } from "path";
|
|
4259
|
+
import { readFileSync as readFileSync13, existsSync as existsSync17 } from "fs";
|
|
3643
4260
|
function readFile(filePath) {
|
|
3644
|
-
if (!
|
|
4261
|
+
if (!existsSync17(filePath))
|
|
3645
4262
|
return null;
|
|
3646
4263
|
try {
|
|
3647
|
-
return
|
|
4264
|
+
return readFileSync13(filePath, "utf-8");
|
|
3648
4265
|
} catch {
|
|
3649
4266
|
return null;
|
|
3650
4267
|
}
|
|
@@ -3734,10 +4351,10 @@ function parseGoMod(filePath) {
|
|
|
3734
4351
|
}
|
|
3735
4352
|
function seedLearningMemory(projectRoot) {
|
|
3736
4353
|
const parsers = [
|
|
3737
|
-
() => parsePackageJson(
|
|
3738
|
-
() => parsePyprojectToml(
|
|
3739
|
-
() => parseCargoToml(
|
|
3740
|
-
() => parseGoMod(
|
|
4354
|
+
() => parsePackageJson(join17(projectRoot, "package.json")),
|
|
4355
|
+
() => parsePyprojectToml(join17(projectRoot, "pyproject.toml")),
|
|
4356
|
+
() => parseCargoToml(join17(projectRoot, "Cargo.toml")),
|
|
4357
|
+
() => parseGoMod(join17(projectRoot, "go.mod"))
|
|
3741
4358
|
];
|
|
3742
4359
|
const infos = parsers.map((fn) => fn()).filter((info) => info !== null);
|
|
3743
4360
|
const projectName = infos.find((i) => i.projectName)?.projectName ?? basename4(projectRoot);
|
|
@@ -3821,12 +4438,12 @@ __export(exports_init, {
|
|
|
3821
4438
|
detectRuntime: () => detectRuntime,
|
|
3822
4439
|
buildHooksConfig: () => buildHooksConfig
|
|
3823
4440
|
});
|
|
3824
|
-
import { execSync as
|
|
3825
|
-
import { mkdirSync as mkdirSync7, existsSync as
|
|
3826
|
-
import { resolve as resolve2, dirname as dirname5, basename as basename5, join as
|
|
4441
|
+
import { execSync as execSync5 } from "child_process";
|
|
4442
|
+
import { mkdirSync as mkdirSync7, existsSync as existsSync18 } from "fs";
|
|
4443
|
+
import { resolve as resolve2, dirname as dirname5, basename as basename5, join as join18 } from "path";
|
|
3827
4444
|
function detectRuntime() {
|
|
3828
4445
|
try {
|
|
3829
|
-
|
|
4446
|
+
execSync5("bun --version", { stdio: "ignore" });
|
|
3830
4447
|
return "bun";
|
|
3831
4448
|
} catch {
|
|
3832
4449
|
return "node";
|
|
@@ -3839,8 +4456,8 @@ function resolveCliPath() {
|
|
|
3839
4456
|
return selfPath;
|
|
3840
4457
|
}
|
|
3841
4458
|
const projectRoot = resolve2(selfDir, "../..");
|
|
3842
|
-
const distPath =
|
|
3843
|
-
if (
|
|
4459
|
+
const distPath = join18(projectRoot, "dist", "cli.js");
|
|
4460
|
+
if (existsSync18(distPath))
|
|
3844
4461
|
return distPath;
|
|
3845
4462
|
return resolve2(selfDir, "../cli.ts");
|
|
3846
4463
|
}
|
|
@@ -3900,9 +4517,9 @@ function mergeHooksIntoSettings(settingsPath, newHooks) {
|
|
|
3900
4517
|
}
|
|
3901
4518
|
function isExistingInstallation(cwd) {
|
|
3902
4519
|
const dir = projectDir(cwd);
|
|
3903
|
-
if (!
|
|
4520
|
+
if (!existsSync18(dir))
|
|
3904
4521
|
return false;
|
|
3905
|
-
return
|
|
4522
|
+
return existsSync18(join18(dir, "file-index.json"));
|
|
3906
4523
|
}
|
|
3907
4524
|
async function init(cwd) {
|
|
3908
4525
|
const runtime = detectRuntime();
|
|
@@ -3920,16 +4537,20 @@ async function init(cwd) {
|
|
|
3920
4537
|
mergeHooksIntoSettings(settingsPath, hooks);
|
|
3921
4538
|
const rulePath = writeMinkRule(cwd);
|
|
3922
4539
|
mkdirSync7(dir, { recursive: true });
|
|
3923
|
-
const
|
|
4540
|
+
const identity = resolveProjectIdentity(cwd);
|
|
4541
|
+
const projectId = identity.id;
|
|
3924
4542
|
const isNotesProject = isWikiEnabled() && isVaultInitialized() && isInsideVault(cwd);
|
|
3925
4543
|
const metaPath = projectMetaPath(cwd);
|
|
3926
4544
|
const existingMeta = safeReadJson(metaPath);
|
|
4545
|
+
const deviceId = getOrCreateDeviceId();
|
|
4546
|
+
const existingPathsByDevice = existingMeta?.pathsByDevice && typeof existingMeta.pathsByDevice === "object" && !Array.isArray(existingMeta.pathsByDevice) ? existingMeta.pathsByDevice : {};
|
|
3927
4547
|
atomicWriteJson(metaPath, {
|
|
3928
4548
|
...existingMeta ?? {},
|
|
3929
4549
|
cwd,
|
|
3930
4550
|
name: basename5(cwd),
|
|
3931
4551
|
initTimestamp: existingMeta?.initTimestamp ?? new Date().toISOString(),
|
|
3932
4552
|
version: "0.1.0",
|
|
4553
|
+
pathsByDevice: { ...existingPathsByDevice, [deviceId]: cwd },
|
|
3933
4554
|
...isNotesProject ? { projectType: "notes" } : {}
|
|
3934
4555
|
});
|
|
3935
4556
|
if (upgrading) {
|
|
@@ -3939,17 +4560,23 @@ async function init(cwd) {
|
|
|
3939
4560
|
console.log(` rule: ${rulePath}`);
|
|
3940
4561
|
} else {
|
|
3941
4562
|
console.log(`[mink] initialized`);
|
|
3942
|
-
console.log(` project: ${projectId}`);
|
|
4563
|
+
console.log(` project: ${projectId} (${identity.source})`);
|
|
3943
4564
|
console.log(` state: ${dir}`);
|
|
3944
4565
|
console.log(` runtime: ${runtime}`);
|
|
3945
4566
|
console.log(` hooks: ${settingsPath}`);
|
|
3946
4567
|
console.log(` rule: ${rulePath}`);
|
|
3947
4568
|
}
|
|
4569
|
+
if (identity.source === "path-derived") {
|
|
4570
|
+
const root = getRepoRoot(cwd);
|
|
4571
|
+
if (root && !getRepoRemote(cwd)) {
|
|
4572
|
+
console.log(` note: this repo has no remote configured. Project state will not unify across machines until you add one and run \`mink config projects.identity git-remote\`.`);
|
|
4573
|
+
}
|
|
4574
|
+
}
|
|
3948
4575
|
const { scan: scan2 } = await Promise.resolve().then(() => (init_scan(), exports_scan));
|
|
3949
4576
|
scan2(cwd, { check: false });
|
|
3950
4577
|
const { learningMemoryPath: learningMemoryPath3 } = await Promise.resolve().then(() => (init_paths(), exports_paths));
|
|
3951
4578
|
const memPath = learningMemoryPath3(cwd);
|
|
3952
|
-
if (!
|
|
4579
|
+
if (!existsSync18(memPath)) {
|
|
3953
4580
|
const { seedLearningMemory: seedLearningMemory2 } = await Promise.resolve().then(() => (init_seed(), exports_seed));
|
|
3954
4581
|
const { serializeLearningMemory: serializeLearningMemory2 } = await Promise.resolve().then(() => (init_learning_memory(), exports_learning_memory));
|
|
3955
4582
|
const mem = seedLearningMemory2(cwd);
|
|
@@ -3958,8 +4585,8 @@ async function init(cwd) {
|
|
|
3958
4585
|
if (isWikiEnabled() && isVaultInitialized() && !isNotesProject) {
|
|
3959
4586
|
try {
|
|
3960
4587
|
const projectSlug = basename5(cwd);
|
|
3961
|
-
const overviewPath =
|
|
3962
|
-
if (!
|
|
4588
|
+
const overviewPath = join18(vaultProjects(projectSlug), "overview.md");
|
|
4589
|
+
if (!existsSync18(overviewPath)) {
|
|
3963
4590
|
const now = new Date().toISOString();
|
|
3964
4591
|
const overview = [
|
|
3965
4592
|
`---`,
|
|
@@ -4008,6 +4635,8 @@ var init_init = __esm(() => {
|
|
|
4008
4635
|
init_paths();
|
|
4009
4636
|
init_project_id();
|
|
4010
4637
|
init_fs_utils();
|
|
4638
|
+
init_device();
|
|
4639
|
+
init_git_identity();
|
|
4011
4640
|
init_vault();
|
|
4012
4641
|
});
|
|
4013
4642
|
|
|
@@ -4046,12 +4675,12 @@ var init_state_counters = __esm(() => {
|
|
|
4046
4675
|
});
|
|
4047
4676
|
|
|
4048
4677
|
// src/core/channel-templates.ts
|
|
4049
|
-
import { join as
|
|
4050
|
-
import { existsSync as
|
|
4678
|
+
import { join as join19 } from "path";
|
|
4679
|
+
import { existsSync as existsSync19, writeFileSync as writeFileSync6, mkdirSync as mkdirSync8 } from "fs";
|
|
4051
4680
|
function writeCompanionClaudeMd(vaultPath, overwrite = false) {
|
|
4052
4681
|
mkdirSync8(vaultPath, { recursive: true });
|
|
4053
|
-
const claudeMdPath =
|
|
4054
|
-
if (
|
|
4682
|
+
const claudeMdPath = join19(vaultPath, "CLAUDE.md");
|
|
4683
|
+
if (existsSync19(claudeMdPath) && !overwrite) {
|
|
4055
4684
|
return false;
|
|
4056
4685
|
}
|
|
4057
4686
|
writeFileSync6(claudeMdPath, COMPANION_CLAUDE_MD);
|
|
@@ -4203,12 +4832,12 @@ mink wiki rebuild-index
|
|
|
4203
4832
|
var init_channel_templates = () => {};
|
|
4204
4833
|
|
|
4205
4834
|
// src/core/channel-process.ts
|
|
4206
|
-
import { readFileSync as
|
|
4207
|
-
import { dirname as dirname6, join as
|
|
4835
|
+
import { readFileSync as readFileSync14, writeFileSync as writeFileSync7, unlinkSync as unlinkSync3, mkdirSync as mkdirSync9, existsSync as existsSync20 } from "fs";
|
|
4836
|
+
import { dirname as dirname6, join as join20 } from "path";
|
|
4208
4837
|
import { spawnSync } from "child_process";
|
|
4209
4838
|
function readChannelPidFile() {
|
|
4210
4839
|
try {
|
|
4211
|
-
const raw =
|
|
4840
|
+
const raw = readFileSync14(channelPidPath(), "utf-8");
|
|
4212
4841
|
const data = JSON.parse(raw);
|
|
4213
4842
|
if (data && typeof data.session === "string" && typeof data.platform === "string" && typeof data.startedAt === "string" && typeof data.vaultPath === "string") {
|
|
4214
4843
|
return data;
|
|
@@ -4350,18 +4979,18 @@ function getChannelLogs() {
|
|
|
4350
4979
|
return null;
|
|
4351
4980
|
if (!screenSessionExists(pidData.session))
|
|
4352
4981
|
return null;
|
|
4353
|
-
const tmpPath =
|
|
4982
|
+
const tmpPath = join20(minkRoot(), `.channel-capture-${Date.now()}-${process.pid}.txt`);
|
|
4354
4983
|
const result = spawnSync("screen", ["-S", pidData.session, "-X", "hardcopy", "-h", tmpPath], { stdio: "ignore" });
|
|
4355
4984
|
if (result.status !== 0)
|
|
4356
4985
|
return null;
|
|
4357
4986
|
for (let i = 0;i < 20; i++) {
|
|
4358
|
-
if (
|
|
4987
|
+
if (existsSync20(tmpPath))
|
|
4359
4988
|
break;
|
|
4360
4989
|
const delayUntil = Date.now() + 50;
|
|
4361
4990
|
while (Date.now() < delayUntil) {}
|
|
4362
4991
|
}
|
|
4363
4992
|
try {
|
|
4364
|
-
const content =
|
|
4993
|
+
const content = readFileSync14(tmpPath, "utf-8");
|
|
4365
4994
|
try {
|
|
4366
4995
|
unlinkSync3(tmpPath);
|
|
4367
4996
|
} catch {}
|
|
@@ -4535,12 +5164,12 @@ var init_runtime = __esm(() => {
|
|
|
4535
5164
|
});
|
|
4536
5165
|
|
|
4537
5166
|
// src/core/daemon.ts
|
|
4538
|
-
import { readFileSync as
|
|
5167
|
+
import { readFileSync as readFileSync15, writeFileSync as writeFileSync8, unlinkSync as unlinkSync4, openSync } from "fs";
|
|
4539
5168
|
import { mkdirSync as mkdirSync10 } from "fs";
|
|
4540
5169
|
import { dirname as dirname7, resolve as resolve3 } from "path";
|
|
4541
5170
|
function readPidFile() {
|
|
4542
5171
|
try {
|
|
4543
|
-
const raw =
|
|
5172
|
+
const raw = readFileSync15(schedulerPidPath(), "utf-8");
|
|
4544
5173
|
const data = JSON.parse(raw);
|
|
4545
5174
|
if (data && typeof data.pid === "number" && typeof data.startedAt === "string" && typeof data.projectCwd === "string") {
|
|
4546
5175
|
return data;
|
|
@@ -4694,9 +5323,9 @@ var exports_status = {};
|
|
|
4694
5323
|
__export(exports_status, {
|
|
4695
5324
|
status: () => status
|
|
4696
5325
|
});
|
|
4697
|
-
import { existsSync as
|
|
5326
|
+
import { existsSync as existsSync22, readFileSync as readFileSync16, statSync as statSync8 } from "fs";
|
|
4698
5327
|
function checkJsonFile(name, filePath, validator) {
|
|
4699
|
-
if (!
|
|
5328
|
+
if (!existsSync22(filePath))
|
|
4700
5329
|
return { name, path: filePath, status: "missing" };
|
|
4701
5330
|
const data = safeReadJson(filePath);
|
|
4702
5331
|
if (data === null)
|
|
@@ -4706,10 +5335,10 @@ function checkJsonFile(name, filePath, validator) {
|
|
|
4706
5335
|
return { name, path: filePath, status: "ok" };
|
|
4707
5336
|
}
|
|
4708
5337
|
function checkTextFile(name, filePath) {
|
|
4709
|
-
if (!
|
|
5338
|
+
if (!existsSync22(filePath))
|
|
4710
5339
|
return { name, path: filePath, status: "missing" };
|
|
4711
5340
|
try {
|
|
4712
|
-
|
|
5341
|
+
readFileSync16(filePath, "utf-8");
|
|
4713
5342
|
return { name, path: filePath, status: "ok" };
|
|
4714
5343
|
} catch {
|
|
4715
5344
|
return { name, path: filePath, status: "corrupt" };
|
|
@@ -4783,7 +5412,7 @@ function status(cwd) {
|
|
|
4783
5412
|
console.log(` Decision Log: ${mem.sections["Decision Log"].length}`);
|
|
4784
5413
|
console.log(` Total entries: ${total}`);
|
|
4785
5414
|
const memPath = learningMemoryPath(cwd);
|
|
4786
|
-
if (
|
|
5415
|
+
if (existsSync22(memPath)) {
|
|
4787
5416
|
const mtime = statSync8(memPath).mtime;
|
|
4788
5417
|
console.log(` Canonical last modified: ${mtime.toISOString()}`);
|
|
4789
5418
|
}
|
|
@@ -4828,8 +5457,12 @@ var exports_scan2 = {};
|
|
|
4828
5457
|
__export(exports_scan2, {
|
|
4829
5458
|
scan: () => scan2
|
|
4830
5459
|
});
|
|
4831
|
-
import { readFileSync as
|
|
4832
|
-
import { join as
|
|
5460
|
+
import { readFileSync as readFileSync17 } from "fs";
|
|
5461
|
+
import { join as join21, relative as relative3 } from "path";
|
|
5462
|
+
function configRelativePath2(cfgPath, cwd) {
|
|
5463
|
+
const rel = relative3(cwd, cfgPath);
|
|
5464
|
+
return rel.startsWith("..") ? cfgPath : rel;
|
|
5465
|
+
}
|
|
4833
5466
|
function loadExistingIndex2(indexPath) {
|
|
4834
5467
|
const raw = safeReadJson(indexPath);
|
|
4835
5468
|
if (isFileIndex(raw))
|
|
@@ -4874,15 +5507,16 @@ function scan2(cwd, options) {
|
|
|
4874
5507
|
}
|
|
4875
5508
|
const start = Date.now();
|
|
4876
5509
|
const index = loadExistingIndex2(idxPath);
|
|
4877
|
-
const
|
|
5510
|
+
const stats = scanProjectWithStats(cwd, excludes, maxFiles);
|
|
5511
|
+
const scanned = stats.files;
|
|
4878
5512
|
const newIndex = createEmptyIndex();
|
|
4879
5513
|
newIndex.header.lifetimeHits = index.header.lifetimeHits;
|
|
4880
5514
|
newIndex.header.lifetimeMisses = index.header.lifetimeMisses;
|
|
4881
5515
|
for (const file of scanned) {
|
|
4882
|
-
const fullPath =
|
|
5516
|
+
const fullPath = join21(cwd, file.relativePath);
|
|
4883
5517
|
let content;
|
|
4884
5518
|
try {
|
|
4885
|
-
content =
|
|
5519
|
+
content = readFileSync17(fullPath, "utf-8");
|
|
4886
5520
|
} catch {
|
|
4887
5521
|
continue;
|
|
4888
5522
|
}
|
|
@@ -4898,7 +5532,13 @@ function scan2(cwd, options) {
|
|
|
4898
5532
|
newIndex.header.lastScanTimestamp = new Date().toISOString();
|
|
4899
5533
|
atomicWriteJson(idxPath, newIndex);
|
|
4900
5534
|
const elapsed = Date.now() - start;
|
|
4901
|
-
|
|
5535
|
+
if (stats.truncated > 0) {
|
|
5536
|
+
console.log(`[mink] scanned ${stats.totalScanned} files; indexed ${newIndex.header.totalFiles} most recent in ${elapsed}ms`);
|
|
5537
|
+
console.log(` ${stats.truncated} files past maxFiles=${maxFiles} were not indexed`);
|
|
5538
|
+
console.log(` raise the cap by setting "maxFiles" in ${configRelativePath2(cfgPath, cwd)}`);
|
|
5539
|
+
} else {
|
|
5540
|
+
console.log(`[mink] indexed ${newIndex.header.totalFiles} files in ${elapsed}ms`);
|
|
5541
|
+
}
|
|
4902
5542
|
}
|
|
4903
5543
|
var init_scan2 = __esm(() => {
|
|
4904
5544
|
init_paths();
|
|
@@ -4913,12 +5553,12 @@ var exports_reflect2 = {};
|
|
|
4913
5553
|
__export(exports_reflect2, {
|
|
4914
5554
|
reflect: () => reflect2
|
|
4915
5555
|
});
|
|
4916
|
-
import { existsSync as
|
|
5556
|
+
import { existsSync as existsSync23 } from "fs";
|
|
4917
5557
|
import { dirname as dirname8 } from "path";
|
|
4918
5558
|
function reflect2(_cwd, memoryPath, configPath3) {
|
|
4919
5559
|
const projDir = dirname8(memoryPath);
|
|
4920
5560
|
const mem = aggregateLearningMemoryAt(projDir);
|
|
4921
|
-
if (totalEntryCount(mem) === 0 && !
|
|
5561
|
+
if (totalEntryCount(mem) === 0 && !existsSync23(memoryPath)) {
|
|
4922
5562
|
console.log("[mink] no learning memory found");
|
|
4923
5563
|
return null;
|
|
4924
5564
|
}
|
|
@@ -4961,7 +5601,7 @@ __export(exports_pre_read, {
|
|
|
4961
5601
|
preRead: () => preRead,
|
|
4962
5602
|
analyzePreRead: () => analyzePreRead
|
|
4963
5603
|
});
|
|
4964
|
-
import { relative as
|
|
5604
|
+
import { relative as relative4 } from "path";
|
|
4965
5605
|
function analyzePreRead(filePath, state, index) {
|
|
4966
5606
|
const warnings = [];
|
|
4967
5607
|
let repeatedRead = false;
|
|
@@ -5003,7 +5643,7 @@ async function preRead(cwd) {
|
|
|
5003
5643
|
const absolutePath = input.tool_input.file_path;
|
|
5004
5644
|
if (!absolutePath)
|
|
5005
5645
|
return;
|
|
5006
|
-
const filePath =
|
|
5646
|
+
const filePath = relative4(cwd, absolutePath);
|
|
5007
5647
|
const rawState = safeReadJson(sessionPath(cwd));
|
|
5008
5648
|
const state = isSessionState(rawState) ? rawState : createSessionState();
|
|
5009
5649
|
const rawIndex = safeReadJson(fileIndexPath(cwd));
|
|
@@ -5039,7 +5679,7 @@ __export(exports_post_read, {
|
|
|
5039
5679
|
postRead: () => postRead,
|
|
5040
5680
|
analyzePostRead: () => analyzePostRead
|
|
5041
5681
|
});
|
|
5042
|
-
import { relative as
|
|
5682
|
+
import { relative as relative5 } from "path";
|
|
5043
5683
|
function analyzePostRead(filePath, content, index) {
|
|
5044
5684
|
if (isBinaryFile(filePath, content ?? undefined)) {
|
|
5045
5685
|
const entry = index ? lookupEntry(index, filePath) : null;
|
|
@@ -5094,7 +5734,7 @@ async function postRead(cwd) {
|
|
|
5094
5734
|
const absolutePath = input.tool_input.file_path;
|
|
5095
5735
|
if (!absolutePath)
|
|
5096
5736
|
return;
|
|
5097
|
-
const filePath =
|
|
5737
|
+
const filePath = relative5(cwd, absolutePath);
|
|
5098
5738
|
const rawState = safeReadJson(sessionPath(cwd));
|
|
5099
5739
|
const state = isSessionState(rawState) ? rawState : createSessionState();
|
|
5100
5740
|
const rawIndex = safeReadJson(fileIndexPath(cwd));
|
|
@@ -5205,7 +5845,7 @@ __export(exports_pre_write, {
|
|
|
5205
5845
|
preWrite: () => preWrite,
|
|
5206
5846
|
analyzePreWrite: () => analyzePreWrite
|
|
5207
5847
|
});
|
|
5208
|
-
import { relative as
|
|
5848
|
+
import { relative as relative6 } from "path";
|
|
5209
5849
|
function analyzePreWrite(filePath, writeContent, doNotRepeatEntries, bugMemory) {
|
|
5210
5850
|
const warnings = [];
|
|
5211
5851
|
const allMatches = [];
|
|
@@ -5255,7 +5895,7 @@ async function preWrite(cwd) {
|
|
|
5255
5895
|
const absolutePath = input.tool_input.file_path;
|
|
5256
5896
|
if (!absolutePath)
|
|
5257
5897
|
return;
|
|
5258
|
-
const filePath =
|
|
5898
|
+
const filePath = relative6(cwd, absolutePath);
|
|
5259
5899
|
const writeContent = extractWriteContent(input);
|
|
5260
5900
|
let doNotRepeatEntries = [];
|
|
5261
5901
|
try {
|
|
@@ -5315,8 +5955,8 @@ __export(exports_post_write, {
|
|
|
5315
5955
|
postWrite: () => postWrite,
|
|
5316
5956
|
analyzePostWrite: () => analyzePostWrite
|
|
5317
5957
|
});
|
|
5318
|
-
import { relative as
|
|
5319
|
-
import { readFileSync as
|
|
5958
|
+
import { relative as relative7 } from "path";
|
|
5959
|
+
import { readFileSync as readFileSync18 } from "fs";
|
|
5320
5960
|
function analyzePostWrite(filePath, fileContent, index) {
|
|
5321
5961
|
if (isWriteExcluded(filePath)) {
|
|
5322
5962
|
return {
|
|
@@ -5377,10 +6017,10 @@ async function postWrite(cwd) {
|
|
|
5377
6017
|
const absolutePath = input.tool_input.file_path;
|
|
5378
6018
|
if (!absolutePath)
|
|
5379
6019
|
return;
|
|
5380
|
-
const filePath =
|
|
6020
|
+
const filePath = relative7(cwd, absolutePath);
|
|
5381
6021
|
let fileContent = null;
|
|
5382
6022
|
try {
|
|
5383
|
-
fileContent =
|
|
6023
|
+
fileContent = readFileSync18(absolutePath, "utf-8");
|
|
5384
6024
|
} catch {}
|
|
5385
6025
|
const rawState = safeReadJson(sessionPath(cwd));
|
|
5386
6026
|
const state = isSessionState(rawState) ? rawState : createSessionState();
|
|
@@ -5742,9 +6382,9 @@ __export(exports_self_update, {
|
|
|
5742
6382
|
PACKAGE_NAME: () => PACKAGE_NAME
|
|
5743
6383
|
});
|
|
5744
6384
|
import { spawnSync as spawnSync2 } from "child_process";
|
|
5745
|
-
import { existsSync as
|
|
6385
|
+
import { existsSync as existsSync24, readFileSync as readFileSync19 } from "fs";
|
|
5746
6386
|
import { dirname as dirname9 } from "path";
|
|
5747
|
-
import { join as
|
|
6387
|
+
import { join as join22 } from "path";
|
|
5748
6388
|
function parseSemver(input) {
|
|
5749
6389
|
const trimmed = input.trim().replace(/^v/, "");
|
|
5750
6390
|
if (!trimmed)
|
|
@@ -5794,8 +6434,8 @@ function getInstallInfo() {
|
|
|
5794
6434
|
let dir = dirname9(selfPath);
|
|
5795
6435
|
let packageJsonPath = null;
|
|
5796
6436
|
for (let i = 0;i < 10; i++) {
|
|
5797
|
-
const candidate =
|
|
5798
|
-
if (
|
|
6437
|
+
const candidate = join22(dir, "package.json");
|
|
6438
|
+
if (existsSync24(candidate)) {
|
|
5799
6439
|
packageJsonPath = candidate;
|
|
5800
6440
|
break;
|
|
5801
6441
|
}
|
|
@@ -5809,7 +6449,7 @@ function getInstallInfo() {
|
|
|
5809
6449
|
}
|
|
5810
6450
|
let currentVersion = "0.0.0";
|
|
5811
6451
|
try {
|
|
5812
|
-
const pkg = JSON.parse(
|
|
6452
|
+
const pkg = JSON.parse(readFileSync19(packageJsonPath, "utf-8"));
|
|
5813
6453
|
if (typeof pkg.version === "string")
|
|
5814
6454
|
currentVersion = pkg.version;
|
|
5815
6455
|
} catch {}
|
|
@@ -5869,7 +6509,7 @@ function buildInstallCommand(pm, version) {
|
|
|
5869
6509
|
return ["npm", "install", "-g", ref];
|
|
5870
6510
|
}
|
|
5871
6511
|
function selfUpdateLogPath() {
|
|
5872
|
-
return
|
|
6512
|
+
return join22(minkRoot(), "self-update.log");
|
|
5873
6513
|
}
|
|
5874
6514
|
function appendLogEntry(entry) {
|
|
5875
6515
|
const path = selfUpdateLogPath();
|
|
@@ -5882,7 +6522,7 @@ function appendLogEntry(entry) {
|
|
|
5882
6522
|
}
|
|
5883
6523
|
function rotateLogIfNeeded(path) {
|
|
5884
6524
|
try {
|
|
5885
|
-
const content =
|
|
6525
|
+
const content = readFileSync19(path, "utf-8");
|
|
5886
6526
|
const lines = content.split(`
|
|
5887
6527
|
`);
|
|
5888
6528
|
if (lines.length <= LOG_MAX_LINES + 1)
|
|
@@ -5985,7 +6625,7 @@ async function runSelfUpgradeInner(opts) {
|
|
|
5985
6625
|
}
|
|
5986
6626
|
let verifiedVersion = latest;
|
|
5987
6627
|
try {
|
|
5988
|
-
const pkg = JSON.parse(
|
|
6628
|
+
const pkg = JSON.parse(readFileSync19(info.packageJsonPath, "utf-8"));
|
|
5989
6629
|
if (typeof pkg.version === "string")
|
|
5990
6630
|
verifiedVersion = pkg.version;
|
|
5991
6631
|
} catch {}
|
|
@@ -6091,10 +6731,10 @@ async function executeTask(taskId, projectCwd) {
|
|
|
6091
6731
|
if (task.actionType === "ai-cli") {
|
|
6092
6732
|
try {
|
|
6093
6733
|
const { learningMemoryPath: learningMemoryPath5 } = await Promise.resolve().then(() => (init_paths(), exports_paths));
|
|
6094
|
-
const { readFileSync:
|
|
6734
|
+
const { readFileSync: readFileSync20 } = await import("fs");
|
|
6095
6735
|
let memoryContent;
|
|
6096
6736
|
try {
|
|
6097
|
-
memoryContent =
|
|
6737
|
+
memoryContent = readFileSync20(learningMemoryPath5(projectCwd), "utf-8");
|
|
6098
6738
|
} catch {
|
|
6099
6739
|
console.log("[mink] no learning memory found, skipping reflection");
|
|
6100
6740
|
return;
|
|
@@ -6658,22 +7298,22 @@ var init_cron = __esm(() => {
|
|
|
6658
7298
|
});
|
|
6659
7299
|
|
|
6660
7300
|
// src/core/vault-templates.ts
|
|
6661
|
-
import { join as
|
|
6662
|
-
import { existsSync as
|
|
7301
|
+
import { join as join23 } from "path";
|
|
7302
|
+
import { existsSync as existsSync25, writeFileSync as writeFileSync9, readFileSync as readFileSync20, mkdirSync as mkdirSync11 } from "fs";
|
|
6663
7303
|
function seedTemplates(templatesDir) {
|
|
6664
7304
|
mkdirSync11(templatesDir, { recursive: true });
|
|
6665
7305
|
for (const [name, content] of Object.entries(DEFAULT_TEMPLATES)) {
|
|
6666
|
-
const filePath =
|
|
6667
|
-
if (!
|
|
7306
|
+
const filePath = join23(templatesDir, `${name}.md`);
|
|
7307
|
+
if (!existsSync25(filePath)) {
|
|
6668
7308
|
writeFileSync9(filePath, content);
|
|
6669
7309
|
}
|
|
6670
7310
|
}
|
|
6671
7311
|
}
|
|
6672
7312
|
function loadTemplate(templatesDir, templateName, vars) {
|
|
6673
|
-
const filePath =
|
|
7313
|
+
const filePath = join23(templatesDir, `${templateName}.md`);
|
|
6674
7314
|
let content;
|
|
6675
|
-
if (
|
|
6676
|
-
content =
|
|
7315
|
+
if (existsSync25(filePath)) {
|
|
7316
|
+
content = readFileSync20(filePath, "utf-8");
|
|
6677
7317
|
} else if (DEFAULT_TEMPLATES[templateName]) {
|
|
6678
7318
|
content = DEFAULT_TEMPLATES[templateName];
|
|
6679
7319
|
} else {
|
|
@@ -6826,33 +7466,33 @@ category: resources
|
|
|
6826
7466
|
});
|
|
6827
7467
|
|
|
6828
7468
|
// src/core/note-writer.ts
|
|
6829
|
-
import { join as
|
|
6830
|
-
import { existsSync as
|
|
7469
|
+
import { join as join24 } from "path";
|
|
7470
|
+
import { existsSync as existsSync26, readFileSync as readFileSync21 } from "fs";
|
|
6831
7471
|
import { createHash as createHash2 } from "crypto";
|
|
6832
7472
|
function sha256(content) {
|
|
6833
7473
|
return createHash2("sha256").update(content).digest("hex");
|
|
6834
7474
|
}
|
|
6835
7475
|
function resolveUniqueNotePath(dir, baseSlug, content) {
|
|
6836
7476
|
const targetHash = sha256(content);
|
|
6837
|
-
const primary =
|
|
6838
|
-
if (!
|
|
7477
|
+
const primary = join24(dir, `${baseSlug}.md`);
|
|
7478
|
+
if (!existsSync26(primary))
|
|
6839
7479
|
return primary;
|
|
6840
7480
|
if (sameContent(primary, targetHash))
|
|
6841
7481
|
return primary;
|
|
6842
7482
|
const dev4 = getOrCreateDeviceId().replace(/-/g, "").slice(0, 4);
|
|
6843
7483
|
for (let i = 0;i < MAX_COLLISION_ATTEMPTS; i++) {
|
|
6844
7484
|
const suffix = i === 0 ? dev4 : `${dev4}-${i + 1}`;
|
|
6845
|
-
const candidate =
|
|
6846
|
-
if (!
|
|
7485
|
+
const candidate = join24(dir, `${baseSlug}-${suffix}.md`);
|
|
7486
|
+
if (!existsSync26(candidate))
|
|
6847
7487
|
return candidate;
|
|
6848
7488
|
if (sameContent(candidate, targetHash))
|
|
6849
7489
|
return candidate;
|
|
6850
7490
|
}
|
|
6851
|
-
return
|
|
7491
|
+
return join24(dir, `${baseSlug}-${Date.now()}.md`);
|
|
6852
7492
|
}
|
|
6853
7493
|
function sameContent(filePath, expectedHash) {
|
|
6854
7494
|
try {
|
|
6855
|
-
return sha256(
|
|
7495
|
+
return sha256(readFileSync21(filePath, "utf-8")) === expectedHash;
|
|
6856
7496
|
} catch {
|
|
6857
7497
|
return false;
|
|
6858
7498
|
}
|
|
@@ -6923,8 +7563,8 @@ ${meta.body}
|
|
|
6923
7563
|
}
|
|
6924
7564
|
function appendToDaily(date, content) {
|
|
6925
7565
|
const dir = vaultDailyDir();
|
|
6926
|
-
const filePath =
|
|
6927
|
-
if (
|
|
7566
|
+
const filePath = join24(dir, `${date}.md`);
|
|
7567
|
+
if (existsSync26(filePath)) {
|
|
6928
7568
|
const timestamp = new Date().toLocaleTimeString("en-US", {
|
|
6929
7569
|
hour: "2-digit",
|
|
6930
7570
|
minute: "2-digit",
|
|
@@ -6961,7 +7601,7 @@ ${content}
|
|
|
6961
7601
|
return filePath;
|
|
6962
7602
|
}
|
|
6963
7603
|
function ingestFile(sourcePath, meta) {
|
|
6964
|
-
const raw =
|
|
7604
|
+
const raw = readFileSync21(sourcePath, "utf-8");
|
|
6965
7605
|
const now = new Date().toISOString();
|
|
6966
7606
|
const headingMatch = raw.match(/^#\s+(.+)$/m);
|
|
6967
7607
|
const title = headingMatch?.[1] ?? sourcePath.split("/").pop().replace(/\.md$/, "");
|
|
@@ -7033,10 +7673,10 @@ var init_design_eval = __esm(() => {
|
|
|
7033
7673
|
});
|
|
7034
7674
|
|
|
7035
7675
|
// src/core/dashboard-api.ts
|
|
7036
|
-
import { existsSync as
|
|
7037
|
-
import { readdirSync as
|
|
7038
|
-
import { join as
|
|
7039
|
-
import { execSync as
|
|
7676
|
+
import { existsSync as existsSync27, readFileSync as readFileSync22 } from "fs";
|
|
7677
|
+
import { readdirSync as readdirSync8, readFileSync as readFileSyncFS, existsSync as fsExistsSync } from "fs";
|
|
7678
|
+
import { join as join25, resolve as resolve5, normalize, sep } from "path";
|
|
7679
|
+
import { execSync as execSync6 } from "child_process";
|
|
7040
7680
|
function isSecretKey(key) {
|
|
7041
7681
|
return SECRET_KEY_PATTERNS.some((re) => re.test(key));
|
|
7042
7682
|
}
|
|
@@ -7048,7 +7688,7 @@ function maskSecret(value, showLast = 4) {
|
|
|
7048
7688
|
return "••••" + value.slice(-showLast);
|
|
7049
7689
|
}
|
|
7050
7690
|
function checkJsonFile2(name, filePath, validator) {
|
|
7051
|
-
if (!
|
|
7691
|
+
if (!existsSync27(filePath))
|
|
7052
7692
|
return { name, status: "missing" };
|
|
7053
7693
|
const data = safeReadJson(filePath);
|
|
7054
7694
|
if (data === null)
|
|
@@ -7058,10 +7698,10 @@ function checkJsonFile2(name, filePath, validator) {
|
|
|
7058
7698
|
return { name, status: "ok" };
|
|
7059
7699
|
}
|
|
7060
7700
|
function checkTextFile2(name, filePath) {
|
|
7061
|
-
if (!
|
|
7701
|
+
if (!existsSync27(filePath))
|
|
7062
7702
|
return { name, status: "missing" };
|
|
7063
7703
|
try {
|
|
7064
|
-
|
|
7704
|
+
readFileSync22(filePath, "utf-8");
|
|
7065
7705
|
return { name, status: "ok" };
|
|
7066
7706
|
} catch {
|
|
7067
7707
|
return { name, status: "corrupt" };
|
|
@@ -7233,7 +7873,7 @@ function getAheadBehind(branch) {
|
|
|
7233
7873
|
if (!branch)
|
|
7234
7874
|
return { ahead: 0, behind: 0 };
|
|
7235
7875
|
try {
|
|
7236
|
-
const raw =
|
|
7876
|
+
const raw = execSync6(`git rev-list --left-right --count origin/${branch}...${branch}`, { cwd: minkRoot(), timeout: 5000, stdio: ["pipe", "pipe", "pipe"] }).toString().trim();
|
|
7237
7877
|
const [behindStr, aheadStr] = raw.split(/\s+/);
|
|
7238
7878
|
return {
|
|
7239
7879
|
behind: Number(behindStr) || 0,
|
|
@@ -7245,7 +7885,7 @@ function getAheadBehind(branch) {
|
|
|
7245
7885
|
}
|
|
7246
7886
|
function getPendingChanges() {
|
|
7247
7887
|
try {
|
|
7248
|
-
const raw =
|
|
7888
|
+
const raw = execSync6("git status --porcelain", {
|
|
7249
7889
|
cwd: minkRoot(),
|
|
7250
7890
|
timeout: 5000,
|
|
7251
7891
|
stdio: ["pipe", "pipe", "pipe"]
|
|
@@ -7314,10 +7954,10 @@ function loadChannelPanel() {
|
|
|
7314
7954
|
function countMarkdownIn(dir) {
|
|
7315
7955
|
let count = 0;
|
|
7316
7956
|
try {
|
|
7317
|
-
for (const entry of
|
|
7957
|
+
for (const entry of readdirSync8(dir, { withFileTypes: true })) {
|
|
7318
7958
|
if (WIKI_TREE_EXCLUDES.has(entry.name) || entry.name.startsWith("."))
|
|
7319
7959
|
continue;
|
|
7320
|
-
const fullPath =
|
|
7960
|
+
const fullPath = join25(dir, entry.name);
|
|
7321
7961
|
if (entry.isDirectory()) {
|
|
7322
7962
|
count += countMarkdownIn(fullPath);
|
|
7323
7963
|
} else if (entry.name.endsWith(".md") && !entry.name.startsWith("_")) {
|
|
@@ -7334,7 +7974,7 @@ function buildVaultTree(root) {
|
|
|
7334
7974
|
return;
|
|
7335
7975
|
let entries = [];
|
|
7336
7976
|
try {
|
|
7337
|
-
entries =
|
|
7977
|
+
entries = readdirSync8(dir, { withFileTypes: true }).filter((e) => !WIKI_TREE_EXCLUDES.has(e.name) && !e.name.startsWith(".")).map((e) => ({ name: e.name, isDir: e.isDirectory() }));
|
|
7338
7978
|
} catch {
|
|
7339
7979
|
return;
|
|
7340
7980
|
}
|
|
@@ -7346,7 +7986,7 @@ function buildVaultTree(root) {
|
|
|
7346
7986
|
for (const entry of entries) {
|
|
7347
7987
|
if (!entry.isDir)
|
|
7348
7988
|
continue;
|
|
7349
|
-
const fullPath =
|
|
7989
|
+
const fullPath = join25(dir, entry.name);
|
|
7350
7990
|
const relPath = fullPath.slice(root.length + 1);
|
|
7351
7991
|
const count = countMarkdownIn(fullPath);
|
|
7352
7992
|
nodes.push({ name: entry.name, path: relPath, count, depth });
|
|
@@ -7769,7 +8409,7 @@ async function triggerIngestFile(sourcePath, category, tags, dedupKey) {
|
|
|
7769
8409
|
if (!isValidCategory(category)) {
|
|
7770
8410
|
return { success: false, error: `Invalid category: ${category}` };
|
|
7771
8411
|
}
|
|
7772
|
-
const expanded = sourcePath.startsWith("~/") ?
|
|
8412
|
+
const expanded = sourcePath.startsWith("~/") ? join25(process.env.HOME ?? "", sourcePath.slice(2)) : sourcePath;
|
|
7773
8413
|
if (!fsExistsSync(expanded)) {
|
|
7774
8414
|
return { success: false, error: `Source file not found: ${sourcePath}` };
|
|
7775
8415
|
}
|
|
@@ -7848,61 +8488,14 @@ var init_dashboard_api = __esm(() => {
|
|
|
7848
8488
|
dedupCache = new Map;
|
|
7849
8489
|
});
|
|
7850
8490
|
|
|
7851
|
-
// src/core/project-registry.ts
|
|
7852
|
-
import { readdirSync as readdirSync8, existsSync as existsSync23 } from "fs";
|
|
7853
|
-
import { join as join24 } from "path";
|
|
7854
|
-
function getProjectMeta(projDir) {
|
|
7855
|
-
const metaPath = join24(projDir, "project-meta.json");
|
|
7856
|
-
const raw = safeReadJson(metaPath);
|
|
7857
|
-
if (raw === null || typeof raw !== "object" || Array.isArray(raw)) {
|
|
7858
|
-
return null;
|
|
7859
|
-
}
|
|
7860
|
-
const obj = raw;
|
|
7861
|
-
if (typeof obj.cwd !== "string" || typeof obj.name !== "string") {
|
|
7862
|
-
return null;
|
|
7863
|
-
}
|
|
7864
|
-
return {
|
|
7865
|
-
cwd: obj.cwd,
|
|
7866
|
-
name: obj.name,
|
|
7867
|
-
initTimestamp: obj.initTimestamp ?? "",
|
|
7868
|
-
version: obj.version ?? "0.1.0"
|
|
7869
|
-
};
|
|
7870
|
-
}
|
|
7871
|
-
function listRegisteredProjects() {
|
|
7872
|
-
const projectsDir = join24(minkRoot(), "projects");
|
|
7873
|
-
if (!existsSync23(projectsDir))
|
|
7874
|
-
return [];
|
|
7875
|
-
const entries = readdirSync8(projectsDir, { withFileTypes: true });
|
|
7876
|
-
const projects = [];
|
|
7877
|
-
for (const entry of entries) {
|
|
7878
|
-
if (!entry.isDirectory())
|
|
7879
|
-
continue;
|
|
7880
|
-
const projDir = join24(projectsDir, entry.name);
|
|
7881
|
-
const meta = getProjectMeta(projDir);
|
|
7882
|
-
if (meta) {
|
|
7883
|
-
projects.push({
|
|
7884
|
-
id: entry.name,
|
|
7885
|
-
cwd: meta.cwd,
|
|
7886
|
-
name: meta.name,
|
|
7887
|
-
version: meta.version
|
|
7888
|
-
});
|
|
7889
|
-
}
|
|
7890
|
-
}
|
|
7891
|
-
return projects;
|
|
7892
|
-
}
|
|
7893
|
-
var init_project_registry = __esm(() => {
|
|
7894
|
-
init_paths();
|
|
7895
|
-
init_fs_utils();
|
|
7896
|
-
});
|
|
7897
|
-
|
|
7898
8491
|
// src/core/dashboard-server.ts
|
|
7899
8492
|
var exports_dashboard_server = {};
|
|
7900
8493
|
__export(exports_dashboard_server, {
|
|
7901
8494
|
startDashboardServer: () => startDashboardServer
|
|
7902
8495
|
});
|
|
7903
8496
|
import { watch } from "fs";
|
|
7904
|
-
import { existsSync as
|
|
7905
|
-
import { basename as basename7, dirname as dirname10, join as
|
|
8497
|
+
import { existsSync as existsSync28 } from "fs";
|
|
8498
|
+
import { basename as basename7, dirname as dirname10, join as join26, extname as extname2 } from "path";
|
|
7906
8499
|
|
|
7907
8500
|
class SSEManager {
|
|
7908
8501
|
clients = new Map;
|
|
@@ -7963,18 +8556,18 @@ function resolveProjectCwd(url, defaultCwd) {
|
|
|
7963
8556
|
const projectId = url.searchParams.get("project");
|
|
7964
8557
|
if (!projectId)
|
|
7965
8558
|
return defaultCwd;
|
|
7966
|
-
if (projectId ===
|
|
8559
|
+
if (projectId === projectIdFor(defaultCwd))
|
|
7967
8560
|
return defaultCwd;
|
|
7968
8561
|
const projects = listRegisteredProjects();
|
|
7969
|
-
const match = projects.find((p) => p.id === projectId);
|
|
8562
|
+
const match = projects.find((p) => p.id === projectId) ?? projects.find((p) => p.aliases.includes(projectId));
|
|
7970
8563
|
if (!match)
|
|
7971
8564
|
return null;
|
|
7972
8565
|
return match.cwd;
|
|
7973
8566
|
}
|
|
7974
8567
|
function getProjectsList(startupCwd, activeCwd) {
|
|
7975
|
-
const activeId =
|
|
8568
|
+
const activeId = projectIdFor(activeCwd);
|
|
7976
8569
|
const registered = listRegisteredProjects();
|
|
7977
|
-
const startupId =
|
|
8570
|
+
const startupId = projectIdFor(startupCwd);
|
|
7978
8571
|
const hasStartup = registered.some((p) => p.id === startupId);
|
|
7979
8572
|
if (!hasStartup) {
|
|
7980
8573
|
const meta = getProjectMeta(projectDir(startupCwd));
|
|
@@ -7982,7 +8575,9 @@ function getProjectsList(startupCwd, activeCwd) {
|
|
|
7982
8575
|
id: startupId,
|
|
7983
8576
|
cwd: startupCwd,
|
|
7984
8577
|
name: meta?.name ?? basename7(startupCwd),
|
|
7985
|
-
version: meta?.version ?? "0.1.0"
|
|
8578
|
+
version: meta?.version ?? "0.1.0",
|
|
8579
|
+
aliases: meta?.aliases ?? [],
|
|
8580
|
+
pathsByDevice: meta?.pathsByDevice ?? {}
|
|
7986
8581
|
});
|
|
7987
8582
|
}
|
|
7988
8583
|
if (activeId !== startupId) {
|
|
@@ -7993,7 +8588,9 @@ function getProjectsList(startupCwd, activeCwd) {
|
|
|
7993
8588
|
id: activeId,
|
|
7994
8589
|
cwd: activeCwd,
|
|
7995
8590
|
name: meta?.name ?? basename7(activeCwd),
|
|
7996
|
-
version: meta?.version ?? "0.1.0"
|
|
8591
|
+
version: meta?.version ?? "0.1.0",
|
|
8592
|
+
aliases: meta?.aliases ?? [],
|
|
8593
|
+
pathsByDevice: meta?.pathsByDevice ?? {}
|
|
7997
8594
|
});
|
|
7998
8595
|
}
|
|
7999
8596
|
}
|
|
@@ -8078,12 +8675,12 @@ async function startDashboardServer(cwd, options = {}) {
|
|
|
8078
8675
|
const __dir = dirname10(new URL(import.meta.url).pathname);
|
|
8079
8676
|
let pkgRoot = __dir;
|
|
8080
8677
|
while (pkgRoot !== dirname10(pkgRoot)) {
|
|
8081
|
-
if (
|
|
8678
|
+
if (existsSync28(join26(pkgRoot, "package.json")))
|
|
8082
8679
|
break;
|
|
8083
8680
|
pkgRoot = dirname10(pkgRoot);
|
|
8084
8681
|
}
|
|
8085
|
-
const dashboardOutDir =
|
|
8086
|
-
const dashboardBuilt =
|
|
8682
|
+
const dashboardOutDir = join26(pkgRoot, "dashboard", "out");
|
|
8683
|
+
const dashboardBuilt = existsSync28(join26(dashboardOutDir, "index.html"));
|
|
8087
8684
|
let clientIdCounter = 0;
|
|
8088
8685
|
if (!dashboardBuilt) {
|
|
8089
8686
|
console.warn("[mink] dashboard not built. Run: cd dashboard && bun run build");
|
|
@@ -8113,9 +8710,9 @@ async function startDashboardServer(cwd, options = {}) {
|
|
|
8113
8710
|
} else {
|
|
8114
8711
|
let filePath;
|
|
8115
8712
|
if (pathname === "/") {
|
|
8116
|
-
filePath =
|
|
8713
|
+
filePath = join26(dashboardOutDir, "index.html");
|
|
8117
8714
|
} else {
|
|
8118
|
-
filePath =
|
|
8715
|
+
filePath = join26(dashboardOutDir, pathname);
|
|
8119
8716
|
}
|
|
8120
8717
|
if (!filePath.startsWith(dashboardOutDir)) {
|
|
8121
8718
|
return jsonResponse({ error: "Forbidden" }, 403);
|
|
@@ -8128,7 +8725,7 @@ async function startDashboardServer(cwd, options = {}) {
|
|
|
8128
8725
|
const htmlServed = await serveFile(filePath + ".html", "text/html; charset=utf-8");
|
|
8129
8726
|
if (htmlServed)
|
|
8130
8727
|
return htmlServed;
|
|
8131
|
-
const indexServed = await serveFile(
|
|
8728
|
+
const indexServed = await serveFile(join26(dashboardOutDir, "index.html"), "text/html; charset=utf-8");
|
|
8132
8729
|
if (indexServed)
|
|
8133
8730
|
return indexServed;
|
|
8134
8731
|
}
|
|
@@ -8237,7 +8834,7 @@ retry: 3000
|
|
|
8237
8834
|
if (!filename || filename.includes("..") || filename.includes("/")) {
|
|
8238
8835
|
return jsonResponse({ error: "Invalid filename" }, 400);
|
|
8239
8836
|
}
|
|
8240
|
-
const imgPath =
|
|
8837
|
+
const imgPath = join26(designCapturesDir(resolvedCwd), filename);
|
|
8241
8838
|
const served = await serveFile(imgPath, "image/jpeg");
|
|
8242
8839
|
if (served) {
|
|
8243
8840
|
served.headers.set("Cache-Control", "public, max-age=60");
|
|
@@ -8471,9 +9068,9 @@ var exports_dashboard = {};
|
|
|
8471
9068
|
__export(exports_dashboard, {
|
|
8472
9069
|
dashboard: () => dashboard
|
|
8473
9070
|
});
|
|
8474
|
-
import { existsSync as
|
|
9071
|
+
import { existsSync as existsSync29 } from "fs";
|
|
8475
9072
|
async function dashboard(cwd, args) {
|
|
8476
|
-
if (!
|
|
9073
|
+
if (!existsSync29(projectDir(cwd))) {
|
|
8477
9074
|
console.error("[mink] project not initialized. Run: mink init");
|
|
8478
9075
|
process.exit(1);
|
|
8479
9076
|
}
|
|
@@ -8491,8 +9088,8 @@ var init_dashboard = __esm(() => {
|
|
|
8491
9088
|
});
|
|
8492
9089
|
|
|
8493
9090
|
// src/commands/init.ts
|
|
8494
|
-
import { mkdirSync as mkdirSync12, existsSync as
|
|
8495
|
-
import { resolve as resolve6, dirname as dirname11, basename as basename8, join as
|
|
9091
|
+
import { mkdirSync as mkdirSync12, existsSync as existsSync30 } from "fs";
|
|
9092
|
+
import { resolve as resolve6, dirname as dirname11, basename as basename8, join as join27 } from "path";
|
|
8496
9093
|
function resolveCliPath2() {
|
|
8497
9094
|
const selfPath = new URL(import.meta.url).pathname;
|
|
8498
9095
|
const selfDir = dirname11(selfPath);
|
|
@@ -8500,8 +9097,8 @@ function resolveCliPath2() {
|
|
|
8500
9097
|
return selfPath;
|
|
8501
9098
|
}
|
|
8502
9099
|
const projectRoot = resolve6(selfDir, "../..");
|
|
8503
|
-
const distPath =
|
|
8504
|
-
if (
|
|
9100
|
+
const distPath = join27(projectRoot, "dist", "cli.js");
|
|
9101
|
+
if (existsSync30(distPath))
|
|
8505
9102
|
return distPath;
|
|
8506
9103
|
return resolve6(selfDir, "../cli.ts");
|
|
8507
9104
|
}
|
|
@@ -8557,14 +9154,16 @@ var init_init2 = __esm(() => {
|
|
|
8557
9154
|
init_paths();
|
|
8558
9155
|
init_project_id();
|
|
8559
9156
|
init_fs_utils();
|
|
9157
|
+
init_device();
|
|
9158
|
+
init_git_identity();
|
|
8560
9159
|
init_vault();
|
|
8561
9160
|
});
|
|
8562
9161
|
|
|
8563
9162
|
// src/core/daemon-service.ts
|
|
8564
|
-
import { execSync as
|
|
8565
|
-
import { existsSync as
|
|
9163
|
+
import { execSync as execSync7 } from "child_process";
|
|
9164
|
+
import { existsSync as existsSync31, mkdirSync as mkdirSync13, unlinkSync as unlinkSync5, writeFileSync as writeFileSync10 } from "fs";
|
|
8566
9165
|
import { homedir as homedir4 } from "os";
|
|
8567
|
-
import { dirname as dirname12, join as
|
|
9166
|
+
import { dirname as dirname12, join as join28 } from "path";
|
|
8568
9167
|
function detectPlatform() {
|
|
8569
9168
|
if (process.platform === "linux")
|
|
8570
9169
|
return "systemd";
|
|
@@ -8574,7 +9173,7 @@ function detectPlatform() {
|
|
|
8574
9173
|
}
|
|
8575
9174
|
function resolveServiceInvocation() {
|
|
8576
9175
|
const entry = process.argv[1];
|
|
8577
|
-
if (entry && !/\.(js|ts|mjs|cjs)$/.test(entry) &&
|
|
9176
|
+
if (entry && !/\.(js|ts|mjs|cjs)$/.test(entry) && existsSync31(entry)) {
|
|
8578
9177
|
return {
|
|
8579
9178
|
executable: entry,
|
|
8580
9179
|
args: ["daemon", "start"],
|
|
@@ -8592,11 +9191,11 @@ function resolveServiceInvocation() {
|
|
|
8592
9191
|
function servicePaths(platform2) {
|
|
8593
9192
|
const home = homedir4();
|
|
8594
9193
|
if (platform2 === "systemd") {
|
|
8595
|
-
const unitDir2 =
|
|
8596
|
-
return { unitDir: unitDir2, unitFile:
|
|
9194
|
+
const unitDir2 = join28(home, ".config", "systemd", "user");
|
|
9195
|
+
return { unitDir: unitDir2, unitFile: join28(unitDir2, "mink-daemon.service") };
|
|
8597
9196
|
}
|
|
8598
|
-
const unitDir =
|
|
8599
|
-
return { unitDir, unitFile:
|
|
9197
|
+
const unitDir = join28(home, "Library", "LaunchAgents");
|
|
9198
|
+
return { unitDir, unitFile: join28(unitDir, "com.mink.daemon.plist") };
|
|
8600
9199
|
}
|
|
8601
9200
|
function renderSystemdUnit(inv) {
|
|
8602
9201
|
const execStart = [inv.executable, ...inv.args].join(" ");
|
|
@@ -8670,7 +9269,7 @@ function installService(options = {}) {
|
|
|
8670
9269
|
process.exit(1);
|
|
8671
9270
|
}
|
|
8672
9271
|
const paths = servicePaths(platform2);
|
|
8673
|
-
if (
|
|
9272
|
+
if (existsSync31(paths.unitFile) && !options.force) {
|
|
8674
9273
|
console.error(`[mink] unit file already exists: ${paths.unitFile}`);
|
|
8675
9274
|
console.error(" re-run with --force to overwrite, or run `mink daemon uninstall` first");
|
|
8676
9275
|
process.exit(1);
|
|
@@ -8680,7 +9279,7 @@ function installService(options = {}) {
|
|
|
8680
9279
|
if (platform2 === "systemd") {
|
|
8681
9280
|
writeFileSync10(paths.unitFile, renderSystemdUnit(inv));
|
|
8682
9281
|
try {
|
|
8683
|
-
|
|
9282
|
+
execSync7("systemctl --user daemon-reload", { stdio: "ignore" });
|
|
8684
9283
|
} catch {}
|
|
8685
9284
|
console.log(`[mink] wrote ${paths.unitFile}`);
|
|
8686
9285
|
console.log("[mink] next steps:");
|
|
@@ -8703,24 +9302,24 @@ function uninstallService() {
|
|
|
8703
9302
|
process.exit(1);
|
|
8704
9303
|
}
|
|
8705
9304
|
const paths = servicePaths(platform2);
|
|
8706
|
-
if (!
|
|
9305
|
+
if (!existsSync31(paths.unitFile)) {
|
|
8707
9306
|
console.log(`[mink] no unit file at ${paths.unitFile} — nothing to uninstall`);
|
|
8708
9307
|
return;
|
|
8709
9308
|
}
|
|
8710
9309
|
if (platform2 === "systemd") {
|
|
8711
9310
|
try {
|
|
8712
|
-
|
|
9311
|
+
execSync7("systemctl --user disable --now mink-daemon.service", {
|
|
8713
9312
|
stdio: "ignore"
|
|
8714
9313
|
});
|
|
8715
9314
|
} catch {}
|
|
8716
9315
|
unlinkSync5(paths.unitFile);
|
|
8717
9316
|
try {
|
|
8718
|
-
|
|
9317
|
+
execSync7("systemctl --user daemon-reload", { stdio: "ignore" });
|
|
8719
9318
|
} catch {}
|
|
8720
9319
|
console.log(`[mink] removed ${paths.unitFile}`);
|
|
8721
9320
|
} else {
|
|
8722
9321
|
try {
|
|
8723
|
-
|
|
9322
|
+
execSync7(`launchctl unload -w ${paths.unitFile}`, { stdio: "ignore" });
|
|
8724
9323
|
} catch {}
|
|
8725
9324
|
unlinkSync5(paths.unitFile);
|
|
8726
9325
|
console.log(`[mink] removed ${paths.unitFile}`);
|
|
@@ -8735,7 +9334,7 @@ var exports_daemon = {};
|
|
|
8735
9334
|
__export(exports_daemon, {
|
|
8736
9335
|
daemon: () => daemon
|
|
8737
9336
|
});
|
|
8738
|
-
import { readFileSync as
|
|
9337
|
+
import { readFileSync as readFileSync23, existsSync as existsSync32 } from "fs";
|
|
8739
9338
|
async function daemon(cwd, args) {
|
|
8740
9339
|
const subcommand = args[0];
|
|
8741
9340
|
switch (subcommand) {
|
|
@@ -8751,12 +9350,12 @@ async function daemon(cwd, args) {
|
|
|
8751
9350
|
break;
|
|
8752
9351
|
case "logs": {
|
|
8753
9352
|
const logPath = schedulerLogPath();
|
|
8754
|
-
if (!
|
|
9353
|
+
if (!existsSync32(logPath)) {
|
|
8755
9354
|
console.log("[mink] no log file found");
|
|
8756
9355
|
return;
|
|
8757
9356
|
}
|
|
8758
9357
|
try {
|
|
8759
|
-
const content =
|
|
9358
|
+
const content = readFileSync23(logPath, "utf-8");
|
|
8760
9359
|
const lines = content.split(`
|
|
8761
9360
|
`);
|
|
8762
9361
|
const tail = lines.slice(-50).join(`
|
|
@@ -9337,8 +9936,8 @@ var init_restore = __esm(() => {
|
|
|
9337
9936
|
});
|
|
9338
9937
|
|
|
9339
9938
|
// src/core/design-eval/server-detect.ts
|
|
9340
|
-
import { readFileSync as
|
|
9341
|
-
import { join as
|
|
9939
|
+
import { readFileSync as readFileSync24 } from "fs";
|
|
9940
|
+
import { join as join29 } from "path";
|
|
9342
9941
|
async function probePort(port) {
|
|
9343
9942
|
try {
|
|
9344
9943
|
const controller = new AbortController;
|
|
@@ -9360,7 +9959,7 @@ async function findRunningServer(ports = DEFAULT_PROBE_PORTS) {
|
|
|
9360
9959
|
}
|
|
9361
9960
|
function detectDevCommand(cwd) {
|
|
9362
9961
|
try {
|
|
9363
|
-
const raw =
|
|
9962
|
+
const raw = readFileSync24(join29(cwd, "package.json"), "utf-8");
|
|
9364
9963
|
const pkg = JSON.parse(raw);
|
|
9365
9964
|
const scripts = pkg.scripts;
|
|
9366
9965
|
if (!scripts || typeof scripts !== "object")
|
|
@@ -9380,10 +9979,10 @@ var init_server_detect = __esm(() => {
|
|
|
9380
9979
|
});
|
|
9381
9980
|
|
|
9382
9981
|
// src/core/design-eval/route-detect.ts
|
|
9383
|
-
import { existsSync as
|
|
9384
|
-
import { join as
|
|
9982
|
+
import { existsSync as existsSync33, readdirSync as readdirSync9, statSync as statSync11 } from "fs";
|
|
9983
|
+
import { join as join30, relative as relative8, sep as sep2 } from "path";
|
|
9385
9984
|
function detectFramework(cwd) {
|
|
9386
|
-
const has = (name) => ["js", "mjs", "ts", "cjs"].some((ext) =>
|
|
9985
|
+
const has = (name) => ["js", "mjs", "ts", "cjs"].some((ext) => existsSync33(join30(cwd, `${name}.${ext}`))) || existsSync33(join30(cwd, name));
|
|
9387
9986
|
if (has("next.config"))
|
|
9388
9987
|
return "nextjs";
|
|
9389
9988
|
if (has("svelte.config"))
|
|
@@ -9408,11 +10007,11 @@ function detectRoutes(cwd) {
|
|
|
9408
10007
|
}
|
|
9409
10008
|
function detectNextRoutes(cwd) {
|
|
9410
10009
|
const routes = [];
|
|
9411
|
-
const appDir =
|
|
9412
|
-
if (
|
|
10010
|
+
const appDir = join30(cwd, "app");
|
|
10011
|
+
if (existsSync33(appDir)) {
|
|
9413
10012
|
const pageFiles = findFiles(appDir, /^page\.(tsx?|jsx?)$/);
|
|
9414
10013
|
for (const file of pageFiles) {
|
|
9415
|
-
const rel =
|
|
10014
|
+
const rel = relative8(appDir, file);
|
|
9416
10015
|
const dir = rel.replace(/([/\\])?page\.(tsx?|jsx?)$/, "");
|
|
9417
10016
|
const route = dir === "" ? "/" : `/${dir.split(sep2).join("/")}`;
|
|
9418
10017
|
if (/\[|@|\(/.test(route))
|
|
@@ -9420,11 +10019,11 @@ function detectNextRoutes(cwd) {
|
|
|
9420
10019
|
routes.push(route);
|
|
9421
10020
|
}
|
|
9422
10021
|
}
|
|
9423
|
-
const pagesDir =
|
|
9424
|
-
if (
|
|
10022
|
+
const pagesDir = join30(cwd, "pages");
|
|
10023
|
+
if (existsSync33(pagesDir)) {
|
|
9425
10024
|
const pageFiles = findFiles(pagesDir, /\.(tsx?|jsx?)$/);
|
|
9426
10025
|
for (const file of pageFiles) {
|
|
9427
|
-
const rel =
|
|
10026
|
+
const rel = relative8(pagesDir, file);
|
|
9428
10027
|
const name = rel.replace(/\.(tsx?|jsx?)$/, "");
|
|
9429
10028
|
if (/^_(app|document|error)/.test(name))
|
|
9430
10029
|
continue;
|
|
@@ -9440,13 +10039,13 @@ function detectNextRoutes(cwd) {
|
|
|
9440
10039
|
return unique.length > 0 ? unique.sort() : ["/"];
|
|
9441
10040
|
}
|
|
9442
10041
|
function detectSvelteKitRoutes(cwd) {
|
|
9443
|
-
const routesDir =
|
|
9444
|
-
if (!
|
|
10042
|
+
const routesDir = join30(cwd, "src", "routes");
|
|
10043
|
+
if (!existsSync33(routesDir))
|
|
9445
10044
|
return ["/"];
|
|
9446
10045
|
const routes = [];
|
|
9447
10046
|
const pageFiles = findFiles(routesDir, /^\+page\.svelte$/);
|
|
9448
10047
|
for (const file of pageFiles) {
|
|
9449
|
-
const rel =
|
|
10048
|
+
const rel = relative8(routesDir, file);
|
|
9450
10049
|
const dir = rel.replace(/([/\\])?\+page\.svelte$/, "");
|
|
9451
10050
|
const route = dir === "" ? "/" : `/${dir.split(sep2).join("/")}`;
|
|
9452
10051
|
if (/\[|\(/.test(route))
|
|
@@ -9456,13 +10055,13 @@ function detectSvelteKitRoutes(cwd) {
|
|
|
9456
10055
|
return routes.length > 0 ? routes.sort() : ["/"];
|
|
9457
10056
|
}
|
|
9458
10057
|
function detectNuxtRoutes(cwd) {
|
|
9459
|
-
const pagesDir =
|
|
9460
|
-
if (!
|
|
10058
|
+
const pagesDir = join30(cwd, "pages");
|
|
10059
|
+
if (!existsSync33(pagesDir))
|
|
9461
10060
|
return ["/"];
|
|
9462
10061
|
const routes = [];
|
|
9463
10062
|
const vueFiles = findFiles(pagesDir, /\.vue$/);
|
|
9464
10063
|
for (const file of vueFiles) {
|
|
9465
|
-
const rel =
|
|
10064
|
+
const rel = relative8(pagesDir, file);
|
|
9466
10065
|
const name = rel.replace(/\.vue$/, "");
|
|
9467
10066
|
if (/\[/.test(name))
|
|
9468
10067
|
continue;
|
|
@@ -9483,7 +10082,7 @@ function findFiles(dir, pattern) {
|
|
|
9483
10082
|
for (const entry of entries) {
|
|
9484
10083
|
if (entry.startsWith(".") || entry === "node_modules")
|
|
9485
10084
|
continue;
|
|
9486
|
-
const full =
|
|
10085
|
+
const full = join30(current, entry);
|
|
9487
10086
|
try {
|
|
9488
10087
|
const stat2 = statSync11(full);
|
|
9489
10088
|
if (stat2.isDirectory()) {
|
|
@@ -58187,7 +58786,7 @@ var require_util2 = __commonJS((exports) => {
|
|
|
58187
58786
|
return path;
|
|
58188
58787
|
}
|
|
58189
58788
|
exports.normalize = normalize2;
|
|
58190
|
-
function
|
|
58789
|
+
function join31(aRoot, aPath) {
|
|
58191
58790
|
if (aRoot === "") {
|
|
58192
58791
|
aRoot = ".";
|
|
58193
58792
|
}
|
|
@@ -58219,11 +58818,11 @@ var require_util2 = __commonJS((exports) => {
|
|
|
58219
58818
|
}
|
|
58220
58819
|
return joined;
|
|
58221
58820
|
}
|
|
58222
|
-
exports.join =
|
|
58821
|
+
exports.join = join31;
|
|
58223
58822
|
exports.isAbsolute = function(aPath) {
|
|
58224
58823
|
return aPath.charAt(0) === "/" || urlRegexp.test(aPath);
|
|
58225
58824
|
};
|
|
58226
|
-
function
|
|
58825
|
+
function relative9(aRoot, aPath) {
|
|
58227
58826
|
if (aRoot === "") {
|
|
58228
58827
|
aRoot = ".";
|
|
58229
58828
|
}
|
|
@@ -58242,7 +58841,7 @@ var require_util2 = __commonJS((exports) => {
|
|
|
58242
58841
|
}
|
|
58243
58842
|
return Array(level + 1).join("../") + aPath.substr(aRoot.length + 1);
|
|
58244
58843
|
}
|
|
58245
|
-
exports.relative =
|
|
58844
|
+
exports.relative = relative9;
|
|
58246
58845
|
var supportsNullProto = function() {
|
|
58247
58846
|
var obj = Object.create(null);
|
|
58248
58847
|
return !("__proto__" in obj);
|
|
@@ -58392,7 +58991,7 @@ var require_util2 = __commonJS((exports) => {
|
|
|
58392
58991
|
parsed.path = parsed.path.substring(0, index + 1);
|
|
58393
58992
|
}
|
|
58394
58993
|
}
|
|
58395
|
-
sourceURL =
|
|
58994
|
+
sourceURL = join31(urlGenerate(parsed), sourceURL);
|
|
58396
58995
|
}
|
|
58397
58996
|
return normalize2(sourceURL);
|
|
58398
58997
|
}
|
|
@@ -60124,7 +60723,7 @@ var require_escodegen = __commonJS((exports) => {
|
|
|
60124
60723
|
function noEmptySpace() {
|
|
60125
60724
|
return space ? space : " ";
|
|
60126
60725
|
}
|
|
60127
|
-
function
|
|
60726
|
+
function join31(left, right) {
|
|
60128
60727
|
var leftSource, rightSource, leftCharCode, rightCharCode;
|
|
60129
60728
|
leftSource = toSourceNodeWhenNeeded(left).toString();
|
|
60130
60729
|
if (leftSource.length === 0) {
|
|
@@ -60465,8 +61064,8 @@ var require_escodegen = __commonJS((exports) => {
|
|
|
60465
61064
|
} else {
|
|
60466
61065
|
result.push(that.generateExpression(stmt.left, Precedence.Call, E_TTT));
|
|
60467
61066
|
}
|
|
60468
|
-
result =
|
|
60469
|
-
result = [
|
|
61067
|
+
result = join31(result, operator);
|
|
61068
|
+
result = [join31(result, that.generateExpression(stmt.right, Precedence.Assignment, E_TTT)), ")"];
|
|
60470
61069
|
});
|
|
60471
61070
|
result.push(this.maybeBlock(stmt.body, flags));
|
|
60472
61071
|
return result;
|
|
@@ -60604,11 +61203,11 @@ var require_escodegen = __commonJS((exports) => {
|
|
|
60604
61203
|
var result, fragment;
|
|
60605
61204
|
result = ["class"];
|
|
60606
61205
|
if (stmt.id) {
|
|
60607
|
-
result =
|
|
61206
|
+
result = join31(result, this.generateExpression(stmt.id, Precedence.Sequence, E_TTT));
|
|
60608
61207
|
}
|
|
60609
61208
|
if (stmt.superClass) {
|
|
60610
|
-
fragment =
|
|
60611
|
-
result =
|
|
61209
|
+
fragment = join31("extends", this.generateExpression(stmt.superClass, Precedence.Unary, E_TTT));
|
|
61210
|
+
result = join31(result, fragment);
|
|
60612
61211
|
}
|
|
60613
61212
|
result.push(space);
|
|
60614
61213
|
result.push(this.generateStatement(stmt.body, S_TFFT));
|
|
@@ -60621,9 +61220,9 @@ var require_escodegen = __commonJS((exports) => {
|
|
|
60621
61220
|
return escapeDirective(stmt.directive) + this.semicolon(flags);
|
|
60622
61221
|
},
|
|
60623
61222
|
DoWhileStatement: function(stmt, flags) {
|
|
60624
|
-
var result =
|
|
61223
|
+
var result = join31("do", this.maybeBlock(stmt.body, S_TFFF));
|
|
60625
61224
|
result = this.maybeBlockSuffix(stmt.body, result);
|
|
60626
|
-
return
|
|
61225
|
+
return join31(result, [
|
|
60627
61226
|
"while" + space + "(",
|
|
60628
61227
|
this.generateExpression(stmt.test, Precedence.Sequence, E_TTT),
|
|
60629
61228
|
")" + this.semicolon(flags)
|
|
@@ -60659,11 +61258,11 @@ var require_escodegen = __commonJS((exports) => {
|
|
|
60659
61258
|
ExportDefaultDeclaration: function(stmt, flags) {
|
|
60660
61259
|
var result = ["export"], bodyFlags;
|
|
60661
61260
|
bodyFlags = flags & F_SEMICOLON_OPT ? S_TFFT : S_TFFF;
|
|
60662
|
-
result =
|
|
61261
|
+
result = join31(result, "default");
|
|
60663
61262
|
if (isStatement(stmt.declaration)) {
|
|
60664
|
-
result =
|
|
61263
|
+
result = join31(result, this.generateStatement(stmt.declaration, bodyFlags));
|
|
60665
61264
|
} else {
|
|
60666
|
-
result =
|
|
61265
|
+
result = join31(result, this.generateExpression(stmt.declaration, Precedence.Assignment, E_TTT) + this.semicolon(flags));
|
|
60667
61266
|
}
|
|
60668
61267
|
return result;
|
|
60669
61268
|
},
|
|
@@ -60671,15 +61270,15 @@ var require_escodegen = __commonJS((exports) => {
|
|
|
60671
61270
|
var result = ["export"], bodyFlags, that = this;
|
|
60672
61271
|
bodyFlags = flags & F_SEMICOLON_OPT ? S_TFFT : S_TFFF;
|
|
60673
61272
|
if (stmt.declaration) {
|
|
60674
|
-
return
|
|
61273
|
+
return join31(result, this.generateStatement(stmt.declaration, bodyFlags));
|
|
60675
61274
|
}
|
|
60676
61275
|
if (stmt.specifiers) {
|
|
60677
61276
|
if (stmt.specifiers.length === 0) {
|
|
60678
|
-
result =
|
|
61277
|
+
result = join31(result, "{" + space + "}");
|
|
60679
61278
|
} else if (stmt.specifiers[0].type === Syntax.ExportBatchSpecifier) {
|
|
60680
|
-
result =
|
|
61279
|
+
result = join31(result, this.generateExpression(stmt.specifiers[0], Precedence.Sequence, E_TTT));
|
|
60681
61280
|
} else {
|
|
60682
|
-
result =
|
|
61281
|
+
result = join31(result, "{");
|
|
60683
61282
|
withIndent(function(indent2) {
|
|
60684
61283
|
var i, iz;
|
|
60685
61284
|
result.push(newline);
|
|
@@ -60697,7 +61296,7 @@ var require_escodegen = __commonJS((exports) => {
|
|
|
60697
61296
|
result.push(base + "}");
|
|
60698
61297
|
}
|
|
60699
61298
|
if (stmt.source) {
|
|
60700
|
-
result =
|
|
61299
|
+
result = join31(result, [
|
|
60701
61300
|
"from" + space,
|
|
60702
61301
|
this.generateExpression(stmt.source, Precedence.Sequence, E_TTT),
|
|
60703
61302
|
this.semicolon(flags)
|
|
@@ -60781,7 +61380,7 @@ var require_escodegen = __commonJS((exports) => {
|
|
|
60781
61380
|
];
|
|
60782
61381
|
cursor = 0;
|
|
60783
61382
|
if (stmt.specifiers[cursor].type === Syntax.ImportDefaultSpecifier) {
|
|
60784
|
-
result =
|
|
61383
|
+
result = join31(result, [
|
|
60785
61384
|
this.generateExpression(stmt.specifiers[cursor], Precedence.Sequence, E_TTT)
|
|
60786
61385
|
]);
|
|
60787
61386
|
++cursor;
|
|
@@ -60791,7 +61390,7 @@ var require_escodegen = __commonJS((exports) => {
|
|
|
60791
61390
|
result.push(",");
|
|
60792
61391
|
}
|
|
60793
61392
|
if (stmt.specifiers[cursor].type === Syntax.ImportNamespaceSpecifier) {
|
|
60794
|
-
result =
|
|
61393
|
+
result = join31(result, [
|
|
60795
61394
|
space,
|
|
60796
61395
|
this.generateExpression(stmt.specifiers[cursor], Precedence.Sequence, E_TTT)
|
|
60797
61396
|
]);
|
|
@@ -60820,7 +61419,7 @@ var require_escodegen = __commonJS((exports) => {
|
|
|
60820
61419
|
}
|
|
60821
61420
|
}
|
|
60822
61421
|
}
|
|
60823
|
-
result =
|
|
61422
|
+
result = join31(result, [
|
|
60824
61423
|
"from" + space,
|
|
60825
61424
|
this.generateExpression(stmt.source, Precedence.Sequence, E_TTT),
|
|
60826
61425
|
this.semicolon(flags)
|
|
@@ -60874,7 +61473,7 @@ var require_escodegen = __commonJS((exports) => {
|
|
|
60874
61473
|
return result;
|
|
60875
61474
|
},
|
|
60876
61475
|
ThrowStatement: function(stmt, flags) {
|
|
60877
|
-
return [
|
|
61476
|
+
return [join31("throw", this.generateExpression(stmt.argument, Precedence.Sequence, E_TTT)), this.semicolon(flags)];
|
|
60878
61477
|
},
|
|
60879
61478
|
TryStatement: function(stmt, flags) {
|
|
60880
61479
|
var result, i, iz, guardedHandlers;
|
|
@@ -60882,7 +61481,7 @@ var require_escodegen = __commonJS((exports) => {
|
|
|
60882
61481
|
result = this.maybeBlockSuffix(stmt.block, result);
|
|
60883
61482
|
if (stmt.handlers) {
|
|
60884
61483
|
for (i = 0, iz = stmt.handlers.length;i < iz; ++i) {
|
|
60885
|
-
result =
|
|
61484
|
+
result = join31(result, this.generateStatement(stmt.handlers[i], S_TFFF));
|
|
60886
61485
|
if (stmt.finalizer || i + 1 !== iz) {
|
|
60887
61486
|
result = this.maybeBlockSuffix(stmt.handlers[i].body, result);
|
|
60888
61487
|
}
|
|
@@ -60890,7 +61489,7 @@ var require_escodegen = __commonJS((exports) => {
|
|
|
60890
61489
|
} else {
|
|
60891
61490
|
guardedHandlers = stmt.guardedHandlers || [];
|
|
60892
61491
|
for (i = 0, iz = guardedHandlers.length;i < iz; ++i) {
|
|
60893
|
-
result =
|
|
61492
|
+
result = join31(result, this.generateStatement(guardedHandlers[i], S_TFFF));
|
|
60894
61493
|
if (stmt.finalizer || i + 1 !== iz) {
|
|
60895
61494
|
result = this.maybeBlockSuffix(guardedHandlers[i].body, result);
|
|
60896
61495
|
}
|
|
@@ -60898,13 +61497,13 @@ var require_escodegen = __commonJS((exports) => {
|
|
|
60898
61497
|
if (stmt.handler) {
|
|
60899
61498
|
if (Array.isArray(stmt.handler)) {
|
|
60900
61499
|
for (i = 0, iz = stmt.handler.length;i < iz; ++i) {
|
|
60901
|
-
result =
|
|
61500
|
+
result = join31(result, this.generateStatement(stmt.handler[i], S_TFFF));
|
|
60902
61501
|
if (stmt.finalizer || i + 1 !== iz) {
|
|
60903
61502
|
result = this.maybeBlockSuffix(stmt.handler[i].body, result);
|
|
60904
61503
|
}
|
|
60905
61504
|
}
|
|
60906
61505
|
} else {
|
|
60907
|
-
result =
|
|
61506
|
+
result = join31(result, this.generateStatement(stmt.handler, S_TFFF));
|
|
60908
61507
|
if (stmt.finalizer) {
|
|
60909
61508
|
result = this.maybeBlockSuffix(stmt.handler.body, result);
|
|
60910
61509
|
}
|
|
@@ -60912,7 +61511,7 @@ var require_escodegen = __commonJS((exports) => {
|
|
|
60912
61511
|
}
|
|
60913
61512
|
}
|
|
60914
61513
|
if (stmt.finalizer) {
|
|
60915
|
-
result =
|
|
61514
|
+
result = join31(result, ["finally", this.maybeBlock(stmt.finalizer, S_TFFF)]);
|
|
60916
61515
|
}
|
|
60917
61516
|
return result;
|
|
60918
61517
|
},
|
|
@@ -60946,7 +61545,7 @@ var require_escodegen = __commonJS((exports) => {
|
|
|
60946
61545
|
withIndent(function() {
|
|
60947
61546
|
if (stmt.test) {
|
|
60948
61547
|
result = [
|
|
60949
|
-
|
|
61548
|
+
join31("case", that.generateExpression(stmt.test, Precedence.Sequence, E_TTT)),
|
|
60950
61549
|
":"
|
|
60951
61550
|
];
|
|
60952
61551
|
} else {
|
|
@@ -60994,9 +61593,9 @@ var require_escodegen = __commonJS((exports) => {
|
|
|
60994
61593
|
result.push(this.maybeBlock(stmt.consequent, S_TFFF));
|
|
60995
61594
|
result = this.maybeBlockSuffix(stmt.consequent, result);
|
|
60996
61595
|
if (stmt.alternate.type === Syntax.IfStatement) {
|
|
60997
|
-
result =
|
|
61596
|
+
result = join31(result, ["else ", this.generateStatement(stmt.alternate, bodyFlags)]);
|
|
60998
61597
|
} else {
|
|
60999
|
-
result =
|
|
61598
|
+
result = join31(result, join31("else", this.maybeBlock(stmt.alternate, bodyFlags)));
|
|
61000
61599
|
}
|
|
61001
61600
|
} else {
|
|
61002
61601
|
result.push(this.maybeBlock(stmt.consequent, bodyFlags));
|
|
@@ -61098,7 +61697,7 @@ var require_escodegen = __commonJS((exports) => {
|
|
|
61098
61697
|
},
|
|
61099
61698
|
ReturnStatement: function(stmt, flags) {
|
|
61100
61699
|
if (stmt.argument) {
|
|
61101
|
-
return [
|
|
61700
|
+
return [join31("return", this.generateExpression(stmt.argument, Precedence.Sequence, E_TTT)), this.semicolon(flags)];
|
|
61102
61701
|
}
|
|
61103
61702
|
return ["return" + this.semicolon(flags)];
|
|
61104
61703
|
},
|
|
@@ -61180,14 +61779,14 @@ var require_escodegen = __commonJS((exports) => {
|
|
|
61180
61779
|
if (leftSource.charCodeAt(leftSource.length - 1) === 47 && esutils.code.isIdentifierPartES5(expr.operator.charCodeAt(0))) {
|
|
61181
61780
|
result = [fragment, noEmptySpace(), expr.operator];
|
|
61182
61781
|
} else {
|
|
61183
|
-
result =
|
|
61782
|
+
result = join31(fragment, expr.operator);
|
|
61184
61783
|
}
|
|
61185
61784
|
fragment = this.generateExpression(expr.right, rightPrecedence, flags);
|
|
61186
61785
|
if (expr.operator === "/" && fragment.toString().charAt(0) === "/" || expr.operator.slice(-1) === "<" && fragment.toString().slice(0, 3) === "!--") {
|
|
61187
61786
|
result.push(noEmptySpace());
|
|
61188
61787
|
result.push(fragment);
|
|
61189
61788
|
} else {
|
|
61190
|
-
result =
|
|
61789
|
+
result = join31(result, fragment);
|
|
61191
61790
|
}
|
|
61192
61791
|
if (expr.operator === "in" && !(flags & F_ALLOW_IN)) {
|
|
61193
61792
|
return ["(", result, ")"];
|
|
@@ -61227,7 +61826,7 @@ var require_escodegen = __commonJS((exports) => {
|
|
|
61227
61826
|
var result, length, i, iz, itemFlags;
|
|
61228
61827
|
length = expr["arguments"].length;
|
|
61229
61828
|
itemFlags = flags & F_ALLOW_UNPARATH_NEW && !parentheses && length === 0 ? E_TFT : E_TFF;
|
|
61230
|
-
result =
|
|
61829
|
+
result = join31("new", this.generateExpression(expr.callee, Precedence.New, itemFlags));
|
|
61231
61830
|
if (!(flags & F_ALLOW_UNPARATH_NEW) || parentheses || length > 0) {
|
|
61232
61831
|
result.push("(");
|
|
61233
61832
|
for (i = 0, iz = length;i < iz; ++i) {
|
|
@@ -61274,11 +61873,11 @@ var require_escodegen = __commonJS((exports) => {
|
|
|
61274
61873
|
var result, fragment, rightCharCode, leftSource, leftCharCode;
|
|
61275
61874
|
fragment = this.generateExpression(expr.argument, Precedence.Unary, E_TTT);
|
|
61276
61875
|
if (space === "") {
|
|
61277
|
-
result =
|
|
61876
|
+
result = join31(expr.operator, fragment);
|
|
61278
61877
|
} else {
|
|
61279
61878
|
result = [expr.operator];
|
|
61280
61879
|
if (expr.operator.length > 2) {
|
|
61281
|
-
result =
|
|
61880
|
+
result = join31(result, fragment);
|
|
61282
61881
|
} else {
|
|
61283
61882
|
leftSource = toSourceNodeWhenNeeded(result).toString();
|
|
61284
61883
|
leftCharCode = leftSource.charCodeAt(leftSource.length - 1);
|
|
@@ -61301,12 +61900,12 @@ var require_escodegen = __commonJS((exports) => {
|
|
|
61301
61900
|
result = "yield";
|
|
61302
61901
|
}
|
|
61303
61902
|
if (expr.argument) {
|
|
61304
|
-
result =
|
|
61903
|
+
result = join31(result, this.generateExpression(expr.argument, Precedence.Yield, E_TTT));
|
|
61305
61904
|
}
|
|
61306
61905
|
return parenthesize(result, Precedence.Yield, precedence);
|
|
61307
61906
|
},
|
|
61308
61907
|
AwaitExpression: function(expr, precedence, flags) {
|
|
61309
|
-
var result =
|
|
61908
|
+
var result = join31(expr.all ? "await*" : "await", this.generateExpression(expr.argument, Precedence.Await, E_TTT));
|
|
61310
61909
|
return parenthesize(result, Precedence.Await, precedence);
|
|
61311
61910
|
},
|
|
61312
61911
|
UpdateExpression: function(expr, precedence, flags) {
|
|
@@ -61378,11 +61977,11 @@ var require_escodegen = __commonJS((exports) => {
|
|
|
61378
61977
|
var result, fragment;
|
|
61379
61978
|
result = ["class"];
|
|
61380
61979
|
if (expr.id) {
|
|
61381
|
-
result =
|
|
61980
|
+
result = join31(result, this.generateExpression(expr.id, Precedence.Sequence, E_TTT));
|
|
61382
61981
|
}
|
|
61383
61982
|
if (expr.superClass) {
|
|
61384
|
-
fragment =
|
|
61385
|
-
result =
|
|
61983
|
+
fragment = join31("extends", this.generateExpression(expr.superClass, Precedence.Unary, E_TTT));
|
|
61984
|
+
result = join31(result, fragment);
|
|
61386
61985
|
}
|
|
61387
61986
|
result.push(space);
|
|
61388
61987
|
result.push(this.generateStatement(expr.body, S_TFFT));
|
|
@@ -61397,7 +61996,7 @@ var require_escodegen = __commonJS((exports) => {
|
|
|
61397
61996
|
}
|
|
61398
61997
|
if (expr.kind === "get" || expr.kind === "set") {
|
|
61399
61998
|
fragment = [
|
|
61400
|
-
|
|
61999
|
+
join31(expr.kind, this.generatePropertyKey(expr.key, expr.computed)),
|
|
61401
62000
|
this.generateFunctionBody(expr.value)
|
|
61402
62001
|
];
|
|
61403
62002
|
} else {
|
|
@@ -61407,7 +62006,7 @@ var require_escodegen = __commonJS((exports) => {
|
|
|
61407
62006
|
this.generateFunctionBody(expr.value)
|
|
61408
62007
|
];
|
|
61409
62008
|
}
|
|
61410
|
-
return
|
|
62009
|
+
return join31(result, fragment);
|
|
61411
62010
|
},
|
|
61412
62011
|
Property: function(expr, precedence, flags) {
|
|
61413
62012
|
if (expr.kind === "get" || expr.kind === "set") {
|
|
@@ -61601,7 +62200,7 @@ var require_escodegen = __commonJS((exports) => {
|
|
|
61601
62200
|
for (i = 0, iz = expr.blocks.length;i < iz; ++i) {
|
|
61602
62201
|
fragment = that.generateExpression(expr.blocks[i], Precedence.Sequence, E_TTT);
|
|
61603
62202
|
if (i > 0 || extra.moz.comprehensionExpressionStartsWithAssignment) {
|
|
61604
|
-
result =
|
|
62203
|
+
result = join31(result, fragment);
|
|
61605
62204
|
} else {
|
|
61606
62205
|
result.push(fragment);
|
|
61607
62206
|
}
|
|
@@ -61609,13 +62208,13 @@ var require_escodegen = __commonJS((exports) => {
|
|
|
61609
62208
|
});
|
|
61610
62209
|
}
|
|
61611
62210
|
if (expr.filter) {
|
|
61612
|
-
result =
|
|
62211
|
+
result = join31(result, "if" + space);
|
|
61613
62212
|
fragment = this.generateExpression(expr.filter, Precedence.Sequence, E_TTT);
|
|
61614
|
-
result =
|
|
62213
|
+
result = join31(result, ["(", fragment, ")"]);
|
|
61615
62214
|
}
|
|
61616
62215
|
if (!extra.moz.comprehensionExpressionStartsWithAssignment) {
|
|
61617
62216
|
fragment = this.generateExpression(expr.body, Precedence.Assignment, E_TTT);
|
|
61618
|
-
result =
|
|
62217
|
+
result = join31(result, fragment);
|
|
61619
62218
|
}
|
|
61620
62219
|
result.push(expr.type === Syntax.GeneratorExpression ? ")" : "]");
|
|
61621
62220
|
return result;
|
|
@@ -61631,8 +62230,8 @@ var require_escodegen = __commonJS((exports) => {
|
|
|
61631
62230
|
} else {
|
|
61632
62231
|
fragment = this.generateExpression(expr.left, Precedence.Call, E_TTT);
|
|
61633
62232
|
}
|
|
61634
|
-
fragment =
|
|
61635
|
-
fragment =
|
|
62233
|
+
fragment = join31(fragment, expr.of ? "of" : "in");
|
|
62234
|
+
fragment = join31(fragment, this.generateExpression(expr.right, Precedence.Sequence, E_TTT));
|
|
61636
62235
|
return ["for" + space + "(", fragment, ")"];
|
|
61637
62236
|
},
|
|
61638
62237
|
SpreadElement: function(expr, precedence, flags) {
|
|
@@ -75337,7 +75936,7 @@ var init_httpUtil = __esm(() => {
|
|
|
75337
75936
|
});
|
|
75338
75937
|
|
|
75339
75938
|
// node_modules/@puppeteer/browsers/lib/esm/browser-data/chrome.js
|
|
75340
|
-
import { execSync as
|
|
75939
|
+
import { execSync as execSync8 } from "node:child_process";
|
|
75341
75940
|
import os from "node:os";
|
|
75342
75941
|
import path from "node:path";
|
|
75343
75942
|
function folder(platform2) {
|
|
@@ -75427,7 +76026,7 @@ function getChromeWindowsLocation(channel2, locationsPrefixes) {
|
|
|
75427
76026
|
}
|
|
75428
76027
|
function getWslVariable(variable) {
|
|
75429
76028
|
try {
|
|
75430
|
-
const result =
|
|
76029
|
+
const result = execSync8(`cmd.exe /c echo %${variable.toLocaleUpperCase()}%`, {
|
|
75431
76030
|
stdio: ["ignore", "pipe", "ignore"],
|
|
75432
76031
|
encoding: "utf-8"
|
|
75433
76032
|
}).trim();
|
|
@@ -75438,7 +76037,7 @@ function getWslVariable(variable) {
|
|
|
75438
76037
|
return;
|
|
75439
76038
|
}
|
|
75440
76039
|
function getWslLocation(channel2) {
|
|
75441
|
-
const wslVersion =
|
|
76040
|
+
const wslVersion = execSync8("wslinfo --version", {
|
|
75442
76041
|
stdio: ["ignore", "pipe", "ignore"],
|
|
75443
76042
|
encoding: "utf-8"
|
|
75444
76043
|
}).trim();
|
|
@@ -75454,7 +76053,7 @@ function getWslLocation(channel2) {
|
|
|
75454
76053
|
}
|
|
75455
76054
|
const windowsPath = getChromeWindowsLocation(channel2, wslPrefixes);
|
|
75456
76055
|
return windowsPath.map((path2) => {
|
|
75457
|
-
return
|
|
76056
|
+
return execSync8(`wslpath "${path2}"`).toString().trim();
|
|
75458
76057
|
});
|
|
75459
76058
|
}
|
|
75460
76059
|
function getChromeLinuxOrWslLocation(channel2) {
|
|
@@ -81729,7 +82328,7 @@ var init_fileUtil = __esm(() => {
|
|
|
81729
82328
|
// node_modules/@puppeteer/browsers/lib/esm/install.js
|
|
81730
82329
|
import assert2 from "node:assert";
|
|
81731
82330
|
import { spawnSync as spawnSync4 } from "node:child_process";
|
|
81732
|
-
import { existsSync as
|
|
82331
|
+
import { existsSync as existsSync34, readFileSync as readFileSync25 } from "node:fs";
|
|
81733
82332
|
import { mkdir as mkdir2, unlink } from "node:fs/promises";
|
|
81734
82333
|
import os5 from "node:os";
|
|
81735
82334
|
import path8 from "node:path";
|
|
@@ -81782,7 +82381,7 @@ async function installWithProviders(options) {
|
|
|
81782
82381
|
continue;
|
|
81783
82382
|
}
|
|
81784
82383
|
debugInstall(`Successfully got URL from ${provider.getName()}: ${url}`);
|
|
81785
|
-
if (!
|
|
82384
|
+
if (!existsSync34(browserRoot)) {
|
|
81786
82385
|
await mkdir2(browserRoot, { recursive: true });
|
|
81787
82386
|
}
|
|
81788
82387
|
return await installUrl(url, options, provider);
|
|
@@ -81815,11 +82414,11 @@ async function installDeps(installedBrowser) {
|
|
|
81815
82414
|
return;
|
|
81816
82415
|
}
|
|
81817
82416
|
const depsPath = path8.join(path8.dirname(installedBrowser.executablePath), "deb.deps");
|
|
81818
|
-
if (!
|
|
82417
|
+
if (!existsSync34(depsPath)) {
|
|
81819
82418
|
debugInstall(`deb.deps file was not found at ${depsPath}`);
|
|
81820
82419
|
return;
|
|
81821
82420
|
}
|
|
81822
|
-
const data =
|
|
82421
|
+
const data = readFileSync25(depsPath, "utf-8").split(`
|
|
81823
82422
|
`).join(",");
|
|
81824
82423
|
if (process.getuid?.() !== 0) {
|
|
81825
82424
|
throw new Error("Installing system dependencies requires root privileges");
|
|
@@ -81857,11 +82456,11 @@ async function installUrl(url, options, provider) {
|
|
|
81857
82456
|
const cache = new Cache(options.cacheDir);
|
|
81858
82457
|
const browserRoot = cache.browserRoot(options.browser);
|
|
81859
82458
|
const archivePath = path8.join(browserRoot, `${options.buildId}-${fileName}`);
|
|
81860
|
-
if (!
|
|
82459
|
+
if (!existsSync34(browserRoot)) {
|
|
81861
82460
|
await mkdir2(browserRoot, { recursive: true });
|
|
81862
82461
|
}
|
|
81863
82462
|
if (!options.unpack) {
|
|
81864
|
-
if (
|
|
82463
|
+
if (existsSync34(archivePath)) {
|
|
81865
82464
|
return archivePath;
|
|
81866
82465
|
}
|
|
81867
82466
|
debugInstall(`Downloading binary from ${url}`);
|
|
@@ -81882,8 +82481,8 @@ async function installUrl(url, options, provider) {
|
|
|
81882
82481
|
cache.writeExecutablePath(options.browser, options.platform, options.buildId, relativeExecutablePath6);
|
|
81883
82482
|
}
|
|
81884
82483
|
try {
|
|
81885
|
-
if (
|
|
81886
|
-
if (!
|
|
82484
|
+
if (existsSync34(outputPath)) {
|
|
82485
|
+
if (!existsSync34(installedBrowser.executablePath)) {
|
|
81887
82486
|
throw new Error(`The browser folder (${outputPath}) exists but the executable (${installedBrowser.executablePath}) is missing`);
|
|
81888
82487
|
}
|
|
81889
82488
|
await runSetup(installedBrowser);
|
|
@@ -81892,7 +82491,7 @@ async function installUrl(url, options, provider) {
|
|
|
81892
82491
|
}
|
|
81893
82492
|
return installedBrowser;
|
|
81894
82493
|
}
|
|
81895
|
-
if (!
|
|
82494
|
+
if (!existsSync34(archivePath)) {
|
|
81896
82495
|
debugInstall(`Downloading binary from ${url}`);
|
|
81897
82496
|
try {
|
|
81898
82497
|
debugTime("download");
|
|
@@ -81921,7 +82520,7 @@ async function installUrl(url, options, provider) {
|
|
|
81921
82520
|
}
|
|
81922
82521
|
return installedBrowser;
|
|
81923
82522
|
} finally {
|
|
81924
|
-
if (
|
|
82523
|
+
if (existsSync34(archivePath)) {
|
|
81925
82524
|
await unlink(archivePath);
|
|
81926
82525
|
}
|
|
81927
82526
|
}
|
|
@@ -81932,7 +82531,7 @@ async function runSetup(installedBrowser) {
|
|
|
81932
82531
|
debugTime("permissions");
|
|
81933
82532
|
const browserDir = path8.dirname(installedBrowser.executablePath);
|
|
81934
82533
|
const setupExePath = path8.join(browserDir, "setup.exe");
|
|
81935
|
-
if (!
|
|
82534
|
+
if (!existsSync34(setupExePath)) {
|
|
81936
82535
|
return;
|
|
81937
82536
|
}
|
|
81938
82537
|
spawnSync4(path8.join(browserDir, "setup.exe"), [`--configure-browser-in-directory=` + browserDir], {
|
|
@@ -83298,8 +83897,7 @@ var init_lib2 = __esm(() => {
|
|
|
83298
83897
|
require: (path9) => {
|
|
83299
83898
|
if (true) {
|
|
83300
83899
|
return __require(path9);
|
|
83301
|
-
}
|
|
83302
|
-
;
|
|
83900
|
+
}
|
|
83303
83901
|
}
|
|
83304
83902
|
});
|
|
83305
83903
|
yargsParser.detailed = function(args, opts) {
|
|
@@ -83345,14 +83943,14 @@ var init_yerror = __esm(() => {
|
|
|
83345
83943
|
});
|
|
83346
83944
|
|
|
83347
83945
|
// node_modules/y18n/build/lib/platform-shims/node.js
|
|
83348
|
-
import { readFileSync as
|
|
83946
|
+
import { readFileSync as readFileSync26, statSync as statSync13, writeFile } from "fs";
|
|
83349
83947
|
import { format as format2 } from "util";
|
|
83350
83948
|
import { resolve as resolve12 } from "path";
|
|
83351
83949
|
var node_default;
|
|
83352
83950
|
var init_node = __esm(() => {
|
|
83353
83951
|
node_default = {
|
|
83354
83952
|
fs: {
|
|
83355
|
-
readFileSync:
|
|
83953
|
+
readFileSync: readFileSync26,
|
|
83356
83954
|
writeFile
|
|
83357
83955
|
},
|
|
83358
83956
|
format: format2,
|
|
@@ -83537,9 +84135,9 @@ var init_y18n = __esm(() => {
|
|
|
83537
84135
|
// node_modules/yargs/lib/platform-shims/esm.mjs
|
|
83538
84136
|
import { notStrictEqual, strictEqual } from "assert";
|
|
83539
84137
|
import { inspect } from "util";
|
|
83540
|
-
import { readFileSync as
|
|
84138
|
+
import { readFileSync as readFileSync27 } from "fs";
|
|
83541
84139
|
import { fileURLToPath } from "url";
|
|
83542
|
-
import { basename as basename9, dirname as dirname14, extname as extname3, relative as
|
|
84140
|
+
import { basename as basename9, dirname as dirname14, extname as extname3, relative as relative9, resolve as resolve13 } from "path";
|
|
83543
84141
|
var REQUIRE_ERROR = "require is not supported by ESM", REQUIRE_DIRECTORY_ERROR = "loading a directory of commands is not supported yet for ESM", __dirname2, mainFilename, esm_default;
|
|
83544
84142
|
var init_esm = __esm(() => {
|
|
83545
84143
|
init_cliui();
|
|
@@ -83574,7 +84172,7 @@ var init_esm = __esm(() => {
|
|
|
83574
84172
|
basename: basename9,
|
|
83575
84173
|
dirname: dirname14,
|
|
83576
84174
|
extname: extname3,
|
|
83577
|
-
relative:
|
|
84175
|
+
relative: relative9,
|
|
83578
84176
|
resolve: resolve13
|
|
83579
84177
|
},
|
|
83580
84178
|
process: {
|
|
@@ -83586,7 +84184,7 @@ var init_esm = __esm(() => {
|
|
|
83586
84184
|
nextTick: process.nextTick,
|
|
83587
84185
|
stdColumns: typeof process.stdout.columns !== "undefined" ? process.stdout.columns : null
|
|
83588
84186
|
},
|
|
83589
|
-
readFileSync:
|
|
84187
|
+
readFileSync: readFileSync27,
|
|
83590
84188
|
require: () => {
|
|
83591
84189
|
throw new YError(REQUIRE_ERROR);
|
|
83592
84190
|
},
|
|
@@ -87285,9 +87883,9 @@ async function getConnectionTransport(options) {
|
|
|
87285
87883
|
throw new Error("Could not detect required browser platform");
|
|
87286
87884
|
}
|
|
87287
87885
|
const { convertPuppeteerChannelToBrowsersChannel: convertPuppeteerChannelToBrowsersChannel2 } = await Promise.resolve().then(() => (init_LaunchOptions(), exports_LaunchOptions));
|
|
87288
|
-
const { join:
|
|
87886
|
+
const { join: join32 } = await import("node:path");
|
|
87289
87887
|
const userDataDir = resolveDefaultUserDataDir3(Browser7.CHROME, platform2, convertPuppeteerChannelToBrowsersChannel2(options.channel));
|
|
87290
|
-
const portPath =
|
|
87888
|
+
const portPath = join32(userDataDir, "DevToolsActivePort");
|
|
87291
87889
|
try {
|
|
87292
87890
|
const fileContent = await environment.value.fs.promises.readFile(portPath, "ascii");
|
|
87293
87891
|
const [rawPort, rawPath] = fileContent.split(`
|
|
@@ -87511,9 +88109,9 @@ var init_PipeTransport = __esm(() => {
|
|
|
87511
88109
|
});
|
|
87512
88110
|
|
|
87513
88111
|
// node_modules/puppeteer-core/lib/esm/puppeteer/node/BrowserLauncher.js
|
|
87514
|
-
import { existsSync as
|
|
88112
|
+
import { existsSync as existsSync35 } from "node:fs";
|
|
87515
88113
|
import { tmpdir } from "node:os";
|
|
87516
|
-
import { join as
|
|
88114
|
+
import { join as join32 } from "node:path";
|
|
87517
88115
|
|
|
87518
88116
|
class BrowserLauncher {
|
|
87519
88117
|
#browser;
|
|
@@ -87538,7 +88136,7 @@ class BrowserLauncher {
|
|
|
87538
88136
|
...options,
|
|
87539
88137
|
protocol
|
|
87540
88138
|
});
|
|
87541
|
-
if (!
|
|
88139
|
+
if (!existsSync35(launchArgs.executablePath)) {
|
|
87542
88140
|
throw new Error(`Browser was not found at the configured executablePath (${launchArgs.executablePath})`);
|
|
87543
88141
|
}
|
|
87544
88142
|
const usePipe = launchArgs.args.includes("--remote-debugging-pipe");
|
|
@@ -87613,7 +88211,7 @@ class BrowserLauncher {
|
|
|
87613
88211
|
browserCloseCallback();
|
|
87614
88212
|
const logs = browserProcess.getRecentLogs().join(`
|
|
87615
88213
|
`);
|
|
87616
|
-
if (logs.includes("Failed to create a ProcessSingleton for your profile directory") || process.platform === "win32" &&
|
|
88214
|
+
if (logs.includes("Failed to create a ProcessSingleton for your profile directory") || process.platform === "win32" && existsSync35(join32(launchArgs.userDataDir, "lockfile"))) {
|
|
87617
88215
|
throw new Error(`The browser is already running for ${launchArgs.userDataDir}. Use a different \`userDataDir\` or stop the running browser first.`);
|
|
87618
88216
|
}
|
|
87619
88217
|
if (logs.includes("Missing X server") && options.headless === false) {
|
|
@@ -87703,12 +88301,12 @@ class BrowserLauncher {
|
|
|
87703
88301
|
});
|
|
87704
88302
|
}
|
|
87705
88303
|
getProfilePath() {
|
|
87706
|
-
return
|
|
88304
|
+
return join32(this.puppeteer.configuration.temporaryDirectory ?? tmpdir(), `puppeteer_dev_${this.browser}_profile-`);
|
|
87707
88305
|
}
|
|
87708
88306
|
resolveExecutablePath(headless, validatePath = true) {
|
|
87709
88307
|
let executablePath = this.puppeteer.configuration.executablePath;
|
|
87710
88308
|
if (executablePath) {
|
|
87711
|
-
if (validatePath && !
|
|
88309
|
+
if (validatePath && !existsSync35(executablePath)) {
|
|
87712
88310
|
throw new Error(`Tried to find the browser at the configured path (${executablePath}), but no executable was found.`);
|
|
87713
88311
|
}
|
|
87714
88312
|
return executablePath;
|
|
@@ -87731,7 +88329,7 @@ class BrowserLauncher {
|
|
|
87731
88329
|
browser: browserType,
|
|
87732
88330
|
buildId: this.puppeteer.browserVersion
|
|
87733
88331
|
});
|
|
87734
|
-
if (validatePath && !
|
|
88332
|
+
if (validatePath && !existsSync35(executablePath)) {
|
|
87735
88333
|
const configVersion = this.puppeteer.configuration?.[this.browser]?.version;
|
|
87736
88334
|
if (configVersion) {
|
|
87737
88335
|
throw new Error(`Tried to find the browser at the configured path (${executablePath}) for version ${configVersion}, but no executable was found.`);
|
|
@@ -88546,17 +89144,17 @@ var init_puppeteer_core = __esm(() => {
|
|
|
88546
89144
|
});
|
|
88547
89145
|
|
|
88548
89146
|
// src/core/design-eval/capture.ts
|
|
88549
|
-
import { mkdirSync as mkdirSync14, statSync as statSync14, existsSync as
|
|
88550
|
-
import { join as
|
|
89147
|
+
import { mkdirSync as mkdirSync14, statSync as statSync14, existsSync as existsSync36 } from "fs";
|
|
89148
|
+
import { join as join33 } from "path";
|
|
88551
89149
|
function findBrowser() {
|
|
88552
89150
|
const platform2 = process.platform;
|
|
88553
89151
|
const paths = CHROME_PATHS[platform2] ?? [];
|
|
88554
89152
|
for (const p of paths) {
|
|
88555
|
-
if (
|
|
89153
|
+
if (existsSync36(p))
|
|
88556
89154
|
return p;
|
|
88557
89155
|
}
|
|
88558
|
-
const minkBrowsers =
|
|
88559
|
-
if (
|
|
89156
|
+
const minkBrowsers = join33(minkRoot(), "browsers");
|
|
89157
|
+
if (existsSync36(minkBrowsers)) {
|
|
88560
89158
|
const found = findChromeInDir(minkBrowsers);
|
|
88561
89159
|
if (found)
|
|
88562
89160
|
return found;
|
|
@@ -88577,7 +89175,7 @@ function findChromeInDir(dir) {
|
|
|
88577
89175
|
try {
|
|
88578
89176
|
const entries = readdirSync11(dir);
|
|
88579
89177
|
for (const entry of entries) {
|
|
88580
|
-
const full =
|
|
89178
|
+
const full = join33(dir, entry);
|
|
88581
89179
|
try {
|
|
88582
89180
|
const stat2 = statSync15(full);
|
|
88583
89181
|
if (stat2.isDirectory()) {
|
|
@@ -88625,7 +89223,7 @@ async function captureRoute(page, route, baseUrl, viewport, options) {
|
|
|
88625
89223
|
const y = section * viewport.height;
|
|
88626
89224
|
const clipHeight = Math.min(viewport.height, pageHeight - y);
|
|
88627
89225
|
const fileName = `${prefix}-${viewport.name}-${section}.jpg`;
|
|
88628
|
-
const filePath =
|
|
89226
|
+
const filePath = join33(options.outputDir, fileName);
|
|
88629
89227
|
await page.screenshot({
|
|
88630
89228
|
path: filePath,
|
|
88631
89229
|
type: "jpeg",
|
|
@@ -90089,7 +90687,7 @@ var exports_wiki = {};
|
|
|
90089
90687
|
__export(exports_wiki, {
|
|
90090
90688
|
wiki: () => wiki
|
|
90091
90689
|
});
|
|
90092
|
-
import { existsSync as
|
|
90690
|
+
import { existsSync as existsSync37, statSync as statSync15 } from "fs";
|
|
90093
90691
|
import { resolve as resolve14 } from "path";
|
|
90094
90692
|
import { homedir as homedir5 } from "os";
|
|
90095
90693
|
async function wiki(_cwd, args) {
|
|
@@ -90102,6 +90700,7 @@ async function wiki(_cwd, args) {
|
|
|
90102
90700
|
wikiStatus();
|
|
90103
90701
|
break;
|
|
90104
90702
|
case "rebuild-index":
|
|
90703
|
+
case "scan":
|
|
90105
90704
|
wikiRebuildIndex();
|
|
90106
90705
|
break;
|
|
90107
90706
|
case "organize":
|
|
@@ -90121,7 +90720,8 @@ async function wiki(_cwd, args) {
|
|
|
90121
90720
|
console.log();
|
|
90122
90721
|
console.log(" init Initialize the notes/wiki vault");
|
|
90123
90722
|
console.log(" status Show vault statistics");
|
|
90124
|
-
console.log(" rebuild-index Full rescan and reindex of vault");
|
|
90723
|
+
console.log(" rebuild-index Full rescan and reindex of vault (alias: scan)");
|
|
90724
|
+
console.log(" scan Alias for rebuild-index");
|
|
90125
90725
|
console.log(" organize List inbox notes needing categorization");
|
|
90126
90726
|
console.log(" link <path> [name] Symlink external notes into the vault");
|
|
90127
90727
|
console.log(" unlink <name> Remove a symlinked directory from the vault");
|
|
@@ -90145,7 +90745,7 @@ async function wikiInit(args) {
|
|
|
90145
90745
|
console.log(`[mink] initializing vault at ${targetPath}`);
|
|
90146
90746
|
console.log(" (set a custom path with: mink wiki init /path/to/vault)");
|
|
90147
90747
|
}
|
|
90148
|
-
const isExisting =
|
|
90748
|
+
const isExisting = existsSync37(targetPath) && statSync15(targetPath).isDirectory();
|
|
90149
90749
|
setConfigValue("wiki.path", targetPath);
|
|
90150
90750
|
ensureVaultStructure();
|
|
90151
90751
|
seedTemplates(vaultTemplates());
|
|
@@ -90210,6 +90810,11 @@ function wikiStatus() {
|
|
|
90210
90810
|
return;
|
|
90211
90811
|
}
|
|
90212
90812
|
const vaultPath = resolveVaultPath();
|
|
90813
|
+
const staleness = vaultIndexStaleness();
|
|
90814
|
+
if (staleness.isStale) {
|
|
90815
|
+
console.log(`[mink] vault index is stale (${staleness.reason}) — rebuilding...`);
|
|
90816
|
+
rebuildVaultIndex();
|
|
90817
|
+
}
|
|
90213
90818
|
const index = loadVaultIndex();
|
|
90214
90819
|
const categoryCounts = {
|
|
90215
90820
|
inbox: 0,
|
|
@@ -90232,7 +90837,8 @@ function wikiStatus() {
|
|
|
90232
90837
|
console.log(` ${cat.padEnd(12)} ${count}`);
|
|
90233
90838
|
}
|
|
90234
90839
|
console.log();
|
|
90235
|
-
console.log(` last
|
|
90840
|
+
console.log(` last full scan: ${index.lastFullScanTimestamp || "never"}`);
|
|
90841
|
+
console.log(` last update: ${index.lastScanTimestamp || "never"}`);
|
|
90236
90842
|
const links = listLinks();
|
|
90237
90843
|
if (links.length > 0) {
|
|
90238
90844
|
console.log();
|
|
@@ -90368,7 +90974,7 @@ __export(exports_note, {
|
|
|
90368
90974
|
note: () => note
|
|
90369
90975
|
});
|
|
90370
90976
|
import { resolve as resolve15 } from "path";
|
|
90371
|
-
import { existsSync as
|
|
90977
|
+
import { existsSync as existsSync38, readFileSync as readFileSync28 } from "fs";
|
|
90372
90978
|
async function note(cwd, args) {
|
|
90373
90979
|
if (!isWikiEnabled()) {
|
|
90374
90980
|
console.error("[mink] wiki feature is disabled");
|
|
@@ -90393,13 +90999,13 @@ async function note(cwd, args) {
|
|
|
90393
90999
|
const date = new Date().toISOString().split("T")[0];
|
|
90394
91000
|
const content = parsed.positional || parsed.body || "";
|
|
90395
91001
|
const filePath = appendToDaily(date, content);
|
|
90396
|
-
updateVaultIndexForFile(filePath,
|
|
91002
|
+
updateVaultIndexForFile(filePath, readFileSync28(filePath, "utf-8"));
|
|
90397
91003
|
console.log(`[mink] daily note: ${filePath}`);
|
|
90398
91004
|
return;
|
|
90399
91005
|
}
|
|
90400
91006
|
if (parsed.file) {
|
|
90401
91007
|
const sourcePath = resolve15(cwd, parsed.file);
|
|
90402
|
-
if (!
|
|
91008
|
+
if (!existsSync38(sourcePath)) {
|
|
90403
91009
|
console.error(`[mink] file not found: ${sourcePath}`);
|
|
90404
91010
|
process.exit(1);
|
|
90405
91011
|
}
|
|
@@ -90481,7 +91087,7 @@ function detectSourceProject(cwd) {
|
|
|
90481
91087
|
const vaultPath = resolveVaultPath();
|
|
90482
91088
|
if (cwd.startsWith(vaultPath))
|
|
90483
91089
|
return;
|
|
90484
|
-
return
|
|
91090
|
+
return projectIdFor(cwd);
|
|
90485
91091
|
} catch {
|
|
90486
91092
|
return;
|
|
90487
91093
|
}
|
|
@@ -90560,10 +91166,10 @@ var exports_skill = {};
|
|
|
90560
91166
|
__export(exports_skill, {
|
|
90561
91167
|
skill: () => skill
|
|
90562
91168
|
});
|
|
90563
|
-
import { join as
|
|
91169
|
+
import { join as join34, resolve as resolve16, dirname as dirname16 } from "path";
|
|
90564
91170
|
import { homedir as homedir6 } from "os";
|
|
90565
91171
|
import {
|
|
90566
|
-
existsSync as
|
|
91172
|
+
existsSync as existsSync39,
|
|
90567
91173
|
mkdirSync as mkdirSync15,
|
|
90568
91174
|
copyFileSync,
|
|
90569
91175
|
unlinkSync as unlinkSync6,
|
|
@@ -90575,8 +91181,8 @@ import {
|
|
|
90575
91181
|
function getSkillsSourceDir() {
|
|
90576
91182
|
let dir = dirname16(new URL(import.meta.url).pathname);
|
|
90577
91183
|
while (true) {
|
|
90578
|
-
if (
|
|
90579
|
-
return
|
|
91184
|
+
if (existsSync39(join34(dir, "package.json")) && existsSync39(join34(dir, "skills"))) {
|
|
91185
|
+
return join34(dir, "skills");
|
|
90580
91186
|
}
|
|
90581
91187
|
const parent = dirname16(dir);
|
|
90582
91188
|
if (parent === dir)
|
|
@@ -90587,12 +91193,12 @@ function getSkillsSourceDir() {
|
|
|
90587
91193
|
}
|
|
90588
91194
|
function getAvailableSkills() {
|
|
90589
91195
|
const dir = getSkillsSourceDir();
|
|
90590
|
-
if (!
|
|
91196
|
+
if (!existsSync39(dir))
|
|
90591
91197
|
return [];
|
|
90592
|
-
return readdirSync11(dir, { withFileTypes: true }).filter((d) => d.isDirectory() &&
|
|
91198
|
+
return readdirSync11(dir, { withFileTypes: true }).filter((d) => d.isDirectory() && existsSync39(join34(dir, d.name, "SKILL.md"))).map((d) => d.name);
|
|
90593
91199
|
}
|
|
90594
91200
|
function isInstalled(skillName) {
|
|
90595
|
-
return
|
|
91201
|
+
return existsSync39(join34(AGENTS_SKILLS_DIR, skillName, "SKILL.md"));
|
|
90596
91202
|
}
|
|
90597
91203
|
async function skill(args) {
|
|
90598
91204
|
const sub = args[0];
|
|
@@ -90628,26 +91234,26 @@ function skillInstall(name) {
|
|
|
90628
91234
|
}
|
|
90629
91235
|
mkdirSync15(AGENTS_SKILLS_DIR, { recursive: true });
|
|
90630
91236
|
for (const skillName of skills) {
|
|
90631
|
-
const srcDir =
|
|
90632
|
-
const srcFile =
|
|
90633
|
-
const destDir =
|
|
90634
|
-
if (!
|
|
91237
|
+
const srcDir = join34(sourceDir, skillName);
|
|
91238
|
+
const srcFile = join34(srcDir, "SKILL.md");
|
|
91239
|
+
const destDir = join34(AGENTS_SKILLS_DIR, skillName);
|
|
91240
|
+
if (!existsSync39(srcFile)) {
|
|
90635
91241
|
console.error(`[mink] skill not found: ${skillName}`);
|
|
90636
91242
|
continue;
|
|
90637
91243
|
}
|
|
90638
91244
|
mkdirSync15(destDir, { recursive: true });
|
|
90639
|
-
|
|
91245
|
+
copyDirRecursive2(srcDir, destDir);
|
|
90640
91246
|
mkdirSync15(CLAUDE_SKILLS_DIR, { recursive: true });
|
|
90641
|
-
const symlink =
|
|
91247
|
+
const symlink = join34(CLAUDE_SKILLS_DIR, skillName);
|
|
90642
91248
|
try {
|
|
90643
|
-
if (
|
|
91249
|
+
if (existsSync39(symlink)) {
|
|
90644
91250
|
if (lstatSync2(symlink).isSymbolicLink() || lstatSync2(symlink).isFile()) {
|
|
90645
91251
|
unlinkSync6(symlink);
|
|
90646
91252
|
} else {
|
|
90647
91253
|
rmSync(symlink, { recursive: true, force: true });
|
|
90648
91254
|
}
|
|
90649
91255
|
}
|
|
90650
|
-
const relativeTarget =
|
|
91256
|
+
const relativeTarget = join34("..", "..", ".agents", "skills", skillName);
|
|
90651
91257
|
symlinkSync2(relativeTarget, symlink);
|
|
90652
91258
|
} catch {}
|
|
90653
91259
|
console.log(`[mink] installed: ${skillName} -> ${destDir}`);
|
|
@@ -90658,15 +91264,15 @@ function skillInstall(name) {
|
|
|
90658
91264
|
function skillUninstall(name) {
|
|
90659
91265
|
const skills = name ? [name] : getAvailableSkills();
|
|
90660
91266
|
for (const skillName of skills) {
|
|
90661
|
-
const destDir =
|
|
90662
|
-
if (!
|
|
91267
|
+
const destDir = join34(AGENTS_SKILLS_DIR, skillName);
|
|
91268
|
+
if (!existsSync39(destDir)) {
|
|
90663
91269
|
console.log(`[mink] not installed: ${skillName}`);
|
|
90664
91270
|
continue;
|
|
90665
91271
|
}
|
|
90666
91272
|
rmSync(destDir, { recursive: true, force: true });
|
|
90667
|
-
const symlink =
|
|
91273
|
+
const symlink = join34(CLAUDE_SKILLS_DIR, skillName);
|
|
90668
91274
|
try {
|
|
90669
|
-
if (
|
|
91275
|
+
if (existsSync39(symlink))
|
|
90670
91276
|
unlinkSync6(symlink);
|
|
90671
91277
|
} catch {}
|
|
90672
91278
|
console.log(`[mink] uninstalled: ${skillName}`);
|
|
@@ -90681,7 +91287,7 @@ function skillList() {
|
|
|
90681
91287
|
if (installed.length > 0) {
|
|
90682
91288
|
console.log(" Installed:");
|
|
90683
91289
|
for (const s of installed) {
|
|
90684
|
-
console.log(` ${s} (${
|
|
91290
|
+
console.log(` ${s} (${join34(AGENTS_SKILLS_DIR, s)})`);
|
|
90685
91291
|
}
|
|
90686
91292
|
}
|
|
90687
91293
|
if (notInstalled.length > 0) {
|
|
@@ -90697,14 +91303,14 @@ function skillList() {
|
|
|
90697
91303
|
console.log(" Install with: mink skill install");
|
|
90698
91304
|
console.log(" Or via skills CLI: npx skills add drewpayment/mink");
|
|
90699
91305
|
}
|
|
90700
|
-
function
|
|
91306
|
+
function copyDirRecursive2(src, dest) {
|
|
90701
91307
|
const entries = readdirSync11(src, { withFileTypes: true });
|
|
90702
91308
|
for (const entry of entries) {
|
|
90703
|
-
const srcPath =
|
|
90704
|
-
const destPath =
|
|
91309
|
+
const srcPath = join34(src, entry.name);
|
|
91310
|
+
const destPath = join34(dest, entry.name);
|
|
90705
91311
|
if (entry.isDirectory()) {
|
|
90706
91312
|
mkdirSync15(destPath, { recursive: true });
|
|
90707
|
-
|
|
91313
|
+
copyDirRecursive2(srcPath, destPath);
|
|
90708
91314
|
} else {
|
|
90709
91315
|
copyFileSync(srcPath, destPath);
|
|
90710
91316
|
}
|
|
@@ -90712,8 +91318,8 @@ function copyDirRecursive(src, dest) {
|
|
|
90712
91318
|
}
|
|
90713
91319
|
var AGENTS_SKILLS_DIR, CLAUDE_SKILLS_DIR;
|
|
90714
91320
|
var init_skill = __esm(() => {
|
|
90715
|
-
AGENTS_SKILLS_DIR =
|
|
90716
|
-
CLAUDE_SKILLS_DIR =
|
|
91321
|
+
AGENTS_SKILLS_DIR = join34(homedir6(), ".agents", "skills");
|
|
91322
|
+
CLAUDE_SKILLS_DIR = join34(homedir6(), ".claude", "skills");
|
|
90717
91323
|
});
|
|
90718
91324
|
|
|
90719
91325
|
// src/commands/agent.ts
|
|
@@ -90721,12 +91327,12 @@ var exports_agent = {};
|
|
|
90721
91327
|
__export(exports_agent, {
|
|
90722
91328
|
agent: () => agent
|
|
90723
91329
|
});
|
|
90724
|
-
import { join as
|
|
91330
|
+
import { join as join35, resolve as resolve17, dirname as dirname17 } from "path";
|
|
90725
91331
|
import { homedir as homedir7 } from "os";
|
|
90726
91332
|
import {
|
|
90727
|
-
existsSync as
|
|
91333
|
+
existsSync as existsSync40,
|
|
90728
91334
|
mkdirSync as mkdirSync16,
|
|
90729
|
-
readFileSync as
|
|
91335
|
+
readFileSync as readFileSync29,
|
|
90730
91336
|
writeFileSync as writeFileSync11
|
|
90731
91337
|
} from "fs";
|
|
90732
91338
|
import { createHash as createHash3 } from "crypto";
|
|
@@ -90734,8 +91340,8 @@ import { spawnSync as spawnSync6 } from "child_process";
|
|
|
90734
91340
|
function getAgentTemplatePath() {
|
|
90735
91341
|
let dir = dirname17(new URL(import.meta.url).pathname);
|
|
90736
91342
|
while (true) {
|
|
90737
|
-
if (
|
|
90738
|
-
return
|
|
91343
|
+
if (existsSync40(join35(dir, "package.json")) && existsSync40(join35(dir, "agents", TEMPLATE_FILE))) {
|
|
91344
|
+
return join35(dir, "agents", TEMPLATE_FILE);
|
|
90739
91345
|
}
|
|
90740
91346
|
const parent = dirname17(dir);
|
|
90741
91347
|
if (parent === dir)
|
|
@@ -90747,10 +91353,10 @@ function getAgentTemplatePath() {
|
|
|
90747
91353
|
function getMinkVersion() {
|
|
90748
91354
|
let dir = dirname17(new URL(import.meta.url).pathname);
|
|
90749
91355
|
while (true) {
|
|
90750
|
-
const pkgPath =
|
|
90751
|
-
if (
|
|
91356
|
+
const pkgPath = join35(dir, "package.json");
|
|
91357
|
+
if (existsSync40(pkgPath)) {
|
|
90752
91358
|
try {
|
|
90753
|
-
const pkg = JSON.parse(
|
|
91359
|
+
const pkg = JSON.parse(readFileSync29(pkgPath, "utf-8"));
|
|
90754
91360
|
if (pkg.name && pkg.version)
|
|
90755
91361
|
return pkg.version;
|
|
90756
91362
|
} catch {}
|
|
@@ -90773,30 +91379,30 @@ function sha2562(text) {
|
|
|
90773
91379
|
return createHash3("sha256").update(text).digest("hex");
|
|
90774
91380
|
}
|
|
90775
91381
|
function claudeAgentsDir() {
|
|
90776
|
-
return
|
|
91382
|
+
return join35(homedir7(), ".claude", "agents");
|
|
90777
91383
|
}
|
|
90778
91384
|
function installedAgentPath() {
|
|
90779
|
-
return
|
|
91385
|
+
return join35(claudeAgentsDir(), INSTALLED_FILE);
|
|
90780
91386
|
}
|
|
90781
91387
|
function installAgentDefinition(opts) {
|
|
90782
91388
|
const templatePath = getAgentTemplatePath();
|
|
90783
|
-
if (!
|
|
91389
|
+
if (!existsSync40(templatePath)) {
|
|
90784
91390
|
throw new Error(`[mink agent] bundled agent template not found at ${templatePath}
|
|
90785
91391
|
` + " This usually means the package was installed without bundled assets.");
|
|
90786
91392
|
}
|
|
90787
91393
|
const installed = installedAgentPath();
|
|
90788
|
-
if (opts.skip &&
|
|
91394
|
+
if (opts.skip && existsSync40(installed)) {
|
|
90789
91395
|
return { action: "skipped", path: installed };
|
|
90790
91396
|
}
|
|
90791
|
-
const template =
|
|
91397
|
+
const template = readFileSync29(templatePath, "utf-8");
|
|
90792
91398
|
const rendered = renderTemplate(template, {
|
|
90793
91399
|
MINK_ROOT: minkRoot(),
|
|
90794
91400
|
VAULT_PATH: resolveVaultPath(),
|
|
90795
91401
|
MINK_VERSION: getMinkVersion()
|
|
90796
91402
|
});
|
|
90797
|
-
const exists =
|
|
91403
|
+
const exists = existsSync40(installed);
|
|
90798
91404
|
if (!opts.force && exists) {
|
|
90799
|
-
const current =
|
|
91405
|
+
const current = readFileSync29(installed, "utf-8");
|
|
90800
91406
|
if (sha2562(current) === sha2562(rendered)) {
|
|
90801
91407
|
return { action: "unchanged", path: installed };
|
|
90802
91408
|
}
|
|
@@ -90872,7 +91478,7 @@ async function agent(_cwd, rawArgs) {
|
|
|
90872
91478
|
}
|
|
90873
91479
|
const skipUpdate = args.noUpdate || process.env.MINK_AGENT_NO_UPDATE === "1";
|
|
90874
91480
|
const root = minkRoot();
|
|
90875
|
-
if (!
|
|
91481
|
+
if (!existsSync40(root)) {
|
|
90876
91482
|
mkdirSync16(root, { recursive: true });
|
|
90877
91483
|
}
|
|
90878
91484
|
let result;
|
|
@@ -90924,25 +91530,25 @@ var init_agent = __esm(() => {
|
|
|
90924
91530
|
});
|
|
90925
91531
|
|
|
90926
91532
|
// src/core/sync-merge-drivers.ts
|
|
90927
|
-
import { readFileSync as
|
|
90928
|
-
import { join as
|
|
91533
|
+
import { readFileSync as readFileSync30, writeFileSync as writeFileSync12, appendFileSync as appendFileSync2 } from "fs";
|
|
91534
|
+
import { join as join36 } from "path";
|
|
90929
91535
|
function logWarning(driver, args, err) {
|
|
90930
91536
|
try {
|
|
90931
91537
|
const line = `[${new Date().toISOString()}] ${driver} fallback for ${args.filePath}: ${err instanceof Error ? err.message : String(err)}
|
|
90932
91538
|
`;
|
|
90933
|
-
appendFileSync2(
|
|
91539
|
+
appendFileSync2(join36(minkRoot(), "sync-warnings.log"), line);
|
|
90934
91540
|
} catch {}
|
|
90935
91541
|
}
|
|
90936
91542
|
function readJsonOrNull(path12) {
|
|
90937
91543
|
try {
|
|
90938
|
-
return JSON.parse(
|
|
91544
|
+
return JSON.parse(readFileSync30(path12, "utf-8"));
|
|
90939
91545
|
} catch {
|
|
90940
91546
|
return null;
|
|
90941
91547
|
}
|
|
90942
91548
|
}
|
|
90943
91549
|
function readTextOrEmpty(path12) {
|
|
90944
91550
|
try {
|
|
90945
|
-
return
|
|
91551
|
+
return readFileSync30(path12, "utf-8");
|
|
90946
91552
|
} catch {
|
|
90947
91553
|
return "";
|
|
90948
91554
|
}
|
|
@@ -91116,12 +91722,13 @@ async function sync(args) {
|
|
|
91116
91722
|
return handleReconcile(args.slice(1));
|
|
91117
91723
|
case "migrate": {
|
|
91118
91724
|
const { syncMigrateCommand: syncMigrateCommand2 } = await Promise.resolve().then(() => (init_sync_migrate(), exports_sync_migrate));
|
|
91119
|
-
syncMigrateCommand2();
|
|
91725
|
+
syncMigrateCommand2(args.slice(1));
|
|
91120
91726
|
return;
|
|
91121
91727
|
}
|
|
91122
91728
|
default:
|
|
91123
91729
|
console.error(`[mink] unknown sync subcommand: ${subcommand}`);
|
|
91124
|
-
console.error("Usage: mink sync [init|status|push|pull|pause|resume|disconnect|reconcile|
|
|
91730
|
+
console.error("Usage: mink sync [init|status|push|pull|pause|resume|disconnect|reconcile|merge-driver]");
|
|
91731
|
+
console.error(" mink sync migrate [--dry-run|--rollback]");
|
|
91125
91732
|
process.exit(1);
|
|
91126
91733
|
}
|
|
91127
91734
|
}
|
|
@@ -91343,7 +91950,9 @@ function sessionStart(cwd) {
|
|
|
91343
91950
|
} catch {}
|
|
91344
91951
|
try {
|
|
91345
91952
|
const { readSyncVersion: readSyncVersion2, MINK_SYNC_VERSION: MINK_SYNC_VERSION2 } = (init_sync(), __toCommonJS(exports_sync));
|
|
91346
|
-
|
|
91953
|
+
const { resolveConfigValue: resolveConfigValue2 } = (init_global_config(), __toCommonJS(exports_global_config));
|
|
91954
|
+
const identityOn = resolveConfigValue2("projects.identity").value === "git-remote";
|
|
91955
|
+
if (readSyncVersion2() < MINK_SYNC_VERSION2 || identityOn) {
|
|
91347
91956
|
const { migrateSyncLayout: migrateSyncLayout2 } = (init_sync_migrate(), __toCommonJS(exports_sync_migrate));
|
|
91348
91957
|
migrateSyncLayout2();
|
|
91349
91958
|
}
|
|
@@ -91367,13 +91976,13 @@ function sessionStart(cwd) {
|
|
|
91367
91976
|
const index = loadVaultIndex();
|
|
91368
91977
|
const inboxCount = Object.values(index.entries).filter((e) => e.category === "inbox").length;
|
|
91369
91978
|
try {
|
|
91370
|
-
const { join:
|
|
91371
|
-
const { existsSync:
|
|
91979
|
+
const { join: join10 } = __require("path");
|
|
91980
|
+
const { existsSync: existsSync12 } = __require("fs");
|
|
91372
91981
|
const { resolveVaultPath: resolveVaultPath2 } = (init_vault(), __toCommonJS(exports_vault));
|
|
91373
91982
|
const { updateMasterIndex: updateMasterIndex2 } = (init_note_linker(), __toCommonJS(exports_note_linker));
|
|
91374
91983
|
const vaultPath = resolveVaultPath2();
|
|
91375
|
-
const masterIndexPath =
|
|
91376
|
-
if (!
|
|
91984
|
+
const masterIndexPath = join10(vaultPath, "_index.md");
|
|
91985
|
+
if (!existsSync12(masterIndexPath)) {
|
|
91377
91986
|
updateMasterIndex2(vaultPath);
|
|
91378
91987
|
}
|
|
91379
91988
|
} catch {}
|
|
@@ -91397,8 +92006,8 @@ init_state_aggregator();
|
|
|
91397
92006
|
init_action_log();
|
|
91398
92007
|
init_device();
|
|
91399
92008
|
init_vault();
|
|
91400
|
-
import { statSync as statSync5, existsSync as
|
|
91401
|
-
import { join as
|
|
92009
|
+
import { statSync as statSync5, existsSync as existsSync14, readFileSync as readFileSync10 } from "fs";
|
|
92010
|
+
import { join as join12, dirname as dirname4 } from "path";
|
|
91402
92011
|
function hasActivity(state) {
|
|
91403
92012
|
return Object.keys(state.reads).length > 0 || state.writes.length > 0;
|
|
91404
92013
|
}
|
|
@@ -91440,10 +92049,10 @@ function sessionStop(sessionFile, finalizer, onReminder = (msg) => console.error
|
|
|
91440
92049
|
effectiveFinalizer.updateSession(summary);
|
|
91441
92050
|
}
|
|
91442
92051
|
try {
|
|
91443
|
-
const logPath =
|
|
92052
|
+
const logPath = join12(projDir, "state", deviceId, "action-log.md");
|
|
91444
92053
|
const logWriter = createActionLogWriter(logPath);
|
|
91445
92054
|
logWriter.appendSessionEnd(summary);
|
|
91446
|
-
const cfgRaw = safeReadJson(
|
|
92055
|
+
const cfgRaw = safeReadJson(join12(projDir, "config.json"));
|
|
91447
92056
|
consolidateLog(logPath, {
|
|
91448
92057
|
maxEntries: cfgRaw?.actionLogMaxEntries ?? 200,
|
|
91449
92058
|
retentionDays: cfgRaw?.actionLogRetentionDays ?? 7
|
|
@@ -91460,9 +92069,9 @@ function sessionStop(sessionFile, finalizer, onReminder = (msg) => console.error
|
|
|
91460
92069
|
}
|
|
91461
92070
|
}
|
|
91462
92071
|
}
|
|
91463
|
-
const memoryPath =
|
|
91464
|
-
const cfgPath =
|
|
91465
|
-
if (
|
|
92072
|
+
const memoryPath = join12(projDir, "learning-memory.md");
|
|
92073
|
+
const cfgPath = join12(projDir, "config.json");
|
|
92074
|
+
if (existsSync14(memoryPath)) {
|
|
91466
92075
|
reflect(projDir, memoryPath, cfgPath);
|
|
91467
92076
|
}
|
|
91468
92077
|
if (isLearningMemoryStale(memoryPath)) {
|
|
@@ -91482,13 +92091,13 @@ function sessionStop(sessionFile, finalizer, onReminder = (msg) => console.error
|
|
|
91482
92091
|
atomicWriteJson(sessionFile, state);
|
|
91483
92092
|
}
|
|
91484
92093
|
function writeSessionToWiki(state, projDir) {
|
|
91485
|
-
const metaRaw = safeReadJson(
|
|
92094
|
+
const metaRaw = safeReadJson(join12(projDir, "project-meta.json"));
|
|
91486
92095
|
const projectName = metaRaw?.name ?? "unknown";
|
|
91487
92096
|
const date = new Date().toISOString().split("T")[0];
|
|
91488
92097
|
const readCount = Object.keys(state.reads).length;
|
|
91489
92098
|
const writeCount = state.writes.length;
|
|
91490
|
-
const sessionDir =
|
|
91491
|
-
const sessionFile =
|
|
92099
|
+
const sessionDir = join12(vaultProjects(projectName), "sessions");
|
|
92100
|
+
const sessionFile = join12(sessionDir, `${date}.md`);
|
|
91492
92101
|
const timestamp = new Date().toLocaleTimeString("en-US", {
|
|
91493
92102
|
hour: "2-digit",
|
|
91494
92103
|
minute: "2-digit",
|
|
@@ -91513,8 +92122,8 @@ function writeSessionToWiki(state, projDir) {
|
|
|
91513
92122
|
}
|
|
91514
92123
|
}
|
|
91515
92124
|
entry.push("");
|
|
91516
|
-
if (
|
|
91517
|
-
const existing =
|
|
92125
|
+
if (existsSync14(sessionFile)) {
|
|
92126
|
+
const existing = readFileSync10(sessionFile, "utf-8");
|
|
91518
92127
|
atomicWriteText(sessionFile, existing.trimEnd() + `
|
|
91519
92128
|
` + entry.join(`
|
|
91520
92129
|
`));
|
|
@@ -91695,9 +92304,9 @@ switch (command2) {
|
|
|
91695
92304
|
case "-v": {
|
|
91696
92305
|
const { resolve: resolve18, dirname: dirname18 } = await import("path");
|
|
91697
92306
|
const cliPath = resolve18(dirname18(new URL(import.meta.url).pathname));
|
|
91698
|
-
const { readFileSync:
|
|
92307
|
+
const { readFileSync: readFileSync31 } = await import("fs");
|
|
91699
92308
|
try {
|
|
91700
|
-
const pkg = JSON.parse(
|
|
92309
|
+
const pkg = JSON.parse(readFileSync31(resolve18(cliPath, "../package.json"), "utf-8"));
|
|
91701
92310
|
console.log(`mink ${pkg.version}`);
|
|
91702
92311
|
} catch {
|
|
91703
92312
|
console.log("mink (unknown version)");
|
|
@@ -91719,7 +92328,7 @@ switch (command2) {
|
|
|
91719
92328
|
console.log(" config [key] [value] Manage global user settings");
|
|
91720
92329
|
console.log();
|
|
91721
92330
|
console.log("Notes & Wiki:");
|
|
91722
|
-
console.log(" wiki <cmd> Manage the notes/wiki vault (init|status|link|unlink|links|rebuild-index|organize)");
|
|
92331
|
+
console.log(" wiki <cmd> Manage the notes/wiki vault (init|status|link|unlink|links|rebuild-index|scan|organize)");
|
|
91723
92332
|
console.log(' note "text" Capture a note to the vault');
|
|
91724
92333
|
console.log(" note --daily [text] Create or append to today's daily note");
|
|
91725
92334
|
console.log(" note list [filters] List notes (--category, --tag, --recent)");
|