@drewpayment/mink 0.3.0 → 0.5.0
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 +235 -11
- package/dist/cli.js +1424 -487
- package/package.json +1 -1
- package/src/cli.ts +23 -1
- package/src/commands/channel.ts +252 -0
- package/src/commands/config.ts +1 -1
- package/src/commands/device.ts +65 -0
- package/src/commands/session-start.ts +16 -0
- package/src/core/channel-process.ts +274 -0
- package/src/core/channel-templates.ts +156 -0
- package/src/core/daemon.ts +63 -2
- package/src/core/device.ts +72 -0
- package/src/core/global-config.ts +72 -11
- package/src/core/paths.ts +20 -0
- package/src/core/sync.ts +12 -0
- package/src/types/channel.ts +16 -0
- package/src/types/config.ts +57 -0
package/dist/cli.js
CHANGED
|
@@ -189,14 +189,19 @@ __export(exports_paths, {
|
|
|
189
189
|
projectMetaPath: () => projectMetaPath,
|
|
190
190
|
projectDir: () => projectDir,
|
|
191
191
|
minkRoot: () => minkRoot,
|
|
192
|
+
localConfigPath: () => localConfigPath,
|
|
192
193
|
learningMemoryPath: () => learningMemoryPath,
|
|
193
194
|
globalConfigPath: () => globalConfigPath,
|
|
194
195
|
frameworkAdvisorPath: () => frameworkAdvisorPath,
|
|
195
196
|
frameworkAdvisorJsonPath: () => frameworkAdvisorJsonPath,
|
|
196
197
|
fileIndexPath: () => fileIndexPath,
|
|
198
|
+
deviceRegistryPath: () => deviceRegistryPath,
|
|
199
|
+
deviceIdPath: () => deviceIdPath,
|
|
197
200
|
designReportPath: () => designReportPath,
|
|
198
201
|
designCapturesDir: () => designCapturesDir,
|
|
199
202
|
configPath: () => configPath,
|
|
203
|
+
channelPidPath: () => channelPidPath,
|
|
204
|
+
channelLogPath: () => channelLogPath,
|
|
200
205
|
bugMemoryPath: () => bugMemoryPath,
|
|
201
206
|
backupDirPath: () => backupDirPath,
|
|
202
207
|
actionLogPath: () => actionLogPath
|
|
@@ -243,9 +248,24 @@ function schedulerLogPath() {
|
|
|
243
248
|
function schedulerManifestPath(cwd) {
|
|
244
249
|
return join(projectDir(cwd), "scheduler-manifest.json");
|
|
245
250
|
}
|
|
251
|
+
function channelPidPath() {
|
|
252
|
+
return join(MINK_ROOT, "channel.pid");
|
|
253
|
+
}
|
|
254
|
+
function channelLogPath() {
|
|
255
|
+
return join(MINK_ROOT, "channel.log");
|
|
256
|
+
}
|
|
246
257
|
function globalConfigPath() {
|
|
247
258
|
return join(MINK_ROOT, "config");
|
|
248
259
|
}
|
|
260
|
+
function localConfigPath() {
|
|
261
|
+
return join(MINK_ROOT, "config.local");
|
|
262
|
+
}
|
|
263
|
+
function deviceIdPath() {
|
|
264
|
+
return join(MINK_ROOT, "device-id");
|
|
265
|
+
}
|
|
266
|
+
function deviceRegistryPath() {
|
|
267
|
+
return join(MINK_ROOT, "devices.json");
|
|
268
|
+
}
|
|
249
269
|
function projectMetaPath(cwd) {
|
|
250
270
|
return join(projectDir(cwd), "project-meta.json");
|
|
251
271
|
}
|
|
@@ -560,96 +580,167 @@ var init_config = __esm(() => {
|
|
|
560
580
|
key: "wiki.path",
|
|
561
581
|
default: "~/.mink/wiki/",
|
|
562
582
|
envVar: "MINK_WIKI_PATH",
|
|
563
|
-
description: "Wiki vault location"
|
|
583
|
+
description: "Wiki vault location",
|
|
584
|
+
scope: "local"
|
|
564
585
|
},
|
|
565
586
|
{
|
|
566
587
|
key: "wiki.enabled",
|
|
567
588
|
default: "true",
|
|
568
589
|
envVar: "MINK_WIKI_ENABLED",
|
|
569
|
-
description: "Enable/disable the wiki feature"
|
|
590
|
+
description: "Enable/disable the wiki feature",
|
|
591
|
+
scope: "shared"
|
|
570
592
|
},
|
|
571
593
|
{
|
|
572
594
|
key: "wiki.sync-mode",
|
|
573
595
|
default: "immediate",
|
|
574
596
|
envVar: "MINK_WIKI_SYNC_MODE",
|
|
575
|
-
description: "Sync mode: immediate or batched"
|
|
597
|
+
description: "Sync mode: immediate or batched",
|
|
598
|
+
scope: "shared"
|
|
576
599
|
},
|
|
577
600
|
{
|
|
578
601
|
key: "wiki.git-backup",
|
|
579
602
|
default: "false",
|
|
580
603
|
envVar: "MINK_WIKI_GIT_BACKUP",
|
|
581
|
-
description: "Deprecated: use sync.enabled instead"
|
|
604
|
+
description: "Deprecated: use sync.enabled instead",
|
|
605
|
+
scope: "shared"
|
|
582
606
|
},
|
|
583
607
|
{
|
|
584
608
|
key: "wiki.git-remote",
|
|
585
609
|
default: "origin",
|
|
586
610
|
envVar: "MINK_WIKI_GIT_REMOTE",
|
|
587
|
-
description: "Deprecated: use sync.remote-url instead"
|
|
611
|
+
description: "Deprecated: use sync.remote-url instead",
|
|
612
|
+
scope: "shared"
|
|
588
613
|
},
|
|
589
614
|
{
|
|
590
615
|
key: "notes.default-category",
|
|
591
616
|
default: "inbox",
|
|
592
617
|
envVar: "MINK_NOTES_DEFAULT_CATEGORY",
|
|
593
|
-
description: "Default category for notes captured via CLI"
|
|
618
|
+
description: "Default category for notes captured via CLI",
|
|
619
|
+
scope: "shared"
|
|
594
620
|
},
|
|
595
621
|
{
|
|
596
622
|
key: "sync.enabled",
|
|
597
623
|
default: "false",
|
|
598
624
|
envVar: "MINK_SYNC_ENABLED",
|
|
599
|
-
description: "Enable/disable automatic git sync of ~/.mink"
|
|
625
|
+
description: "Enable/disable automatic git sync of ~/.mink",
|
|
626
|
+
scope: "shared"
|
|
600
627
|
},
|
|
601
628
|
{
|
|
602
629
|
key: "sync.remote-url",
|
|
603
630
|
default: "",
|
|
604
631
|
envVar: "MINK_SYNC_REMOTE_URL",
|
|
605
|
-
description: "Git remote URL for ~/.mink sync"
|
|
632
|
+
description: "Git remote URL for ~/.mink sync",
|
|
633
|
+
scope: "shared"
|
|
606
634
|
},
|
|
607
635
|
{
|
|
608
636
|
key: "sync.last-push",
|
|
609
637
|
default: "",
|
|
610
638
|
envVar: "MINK_SYNC_LAST_PUSH",
|
|
611
|
-
description: "ISO timestamp of last successful sync push"
|
|
639
|
+
description: "ISO timestamp of last successful sync push",
|
|
640
|
+
scope: "local"
|
|
612
641
|
},
|
|
613
642
|
{
|
|
614
643
|
key: "sync.last-pull",
|
|
615
644
|
default: "",
|
|
616
645
|
envVar: "MINK_SYNC_LAST_PULL",
|
|
617
|
-
description: "ISO timestamp of last successful sync pull"
|
|
646
|
+
description: "ISO timestamp of last successful sync pull",
|
|
647
|
+
scope: "local"
|
|
648
|
+
},
|
|
649
|
+
{
|
|
650
|
+
key: "channel.discord.bot-token",
|
|
651
|
+
default: "",
|
|
652
|
+
envVar: "MINK_CHANNEL_DISCORD_BOT_TOKEN",
|
|
653
|
+
description: "Discord bot token for Claude Code Channels",
|
|
654
|
+
scope: "local"
|
|
655
|
+
},
|
|
656
|
+
{
|
|
657
|
+
key: "channel.discord.enabled",
|
|
658
|
+
default: "false",
|
|
659
|
+
envVar: "MINK_CHANNEL_DISCORD_ENABLED",
|
|
660
|
+
description: "Auto-start Discord channel when daemon starts",
|
|
661
|
+
scope: "local"
|
|
662
|
+
},
|
|
663
|
+
{
|
|
664
|
+
key: "channel.default-platform",
|
|
665
|
+
default: "discord",
|
|
666
|
+
envVar: "MINK_CHANNEL_DEFAULT_PLATFORM",
|
|
667
|
+
description: "Default platform for mink channel start",
|
|
668
|
+
scope: "shared"
|
|
669
|
+
},
|
|
670
|
+
{
|
|
671
|
+
key: "channel.skip-permissions",
|
|
672
|
+
default: "true",
|
|
673
|
+
envVar: "MINK_CHANNEL_SKIP_PERMISSIONS",
|
|
674
|
+
description: "Pass --dangerously-skip-permissions so the channel can run without terminal prompts",
|
|
675
|
+
scope: "shared"
|
|
618
676
|
}
|
|
619
677
|
];
|
|
620
678
|
VALID_KEYS = new Set(CONFIG_KEYS.map((k) => k.key));
|
|
621
679
|
});
|
|
622
680
|
|
|
623
681
|
// src/core/global-config.ts
|
|
624
|
-
|
|
625
|
-
|
|
682
|
+
var exports_global_config = {};
|
|
683
|
+
__export(exports_global_config, {
|
|
684
|
+
setConfigValue: () => setConfigValue,
|
|
685
|
+
saveLocalConfig: () => saveLocalConfig,
|
|
686
|
+
saveGlobalConfig: () => saveGlobalConfig,
|
|
687
|
+
resolveConfigValue: () => resolveConfigValue,
|
|
688
|
+
resolveAllConfig: () => resolveAllConfig,
|
|
689
|
+
resetConfigKey: () => resetConfigKey,
|
|
690
|
+
resetAllConfig: () => resetAllConfig,
|
|
691
|
+
migrateConfigIfNeeded: () => migrateConfigIfNeeded,
|
|
692
|
+
loadLocalConfig: () => loadLocalConfig,
|
|
693
|
+
loadGlobalConfig: () => loadGlobalConfig
|
|
694
|
+
});
|
|
695
|
+
function loadConfigFile(path) {
|
|
696
|
+
const raw = safeReadJson(path);
|
|
626
697
|
if (raw === null)
|
|
627
698
|
return {};
|
|
628
699
|
if (typeof raw !== "object" || Array.isArray(raw)) {
|
|
629
|
-
console.warn("[mink] warning: corrupt config file at " +
|
|
700
|
+
console.warn("[mink] warning: corrupt config file at " + path);
|
|
630
701
|
return {};
|
|
631
702
|
}
|
|
632
703
|
return raw;
|
|
633
704
|
}
|
|
705
|
+
function loadGlobalConfig() {
|
|
706
|
+
return loadConfigFile(globalConfigPath());
|
|
707
|
+
}
|
|
634
708
|
function saveGlobalConfig(config) {
|
|
635
709
|
atomicWriteJson(globalConfigPath(), config);
|
|
636
710
|
}
|
|
711
|
+
function loadLocalConfig() {
|
|
712
|
+
return loadConfigFile(localConfigPath());
|
|
713
|
+
}
|
|
714
|
+
function saveLocalConfig(config) {
|
|
715
|
+
atomicWriteJson(localConfigPath(), config);
|
|
716
|
+
}
|
|
717
|
+
function loadConfigForScope(scope) {
|
|
718
|
+
return scope === "local" ? loadLocalConfig() : loadGlobalConfig();
|
|
719
|
+
}
|
|
720
|
+
function saveConfigForScope(scope, config) {
|
|
721
|
+
if (scope === "local") {
|
|
722
|
+
saveLocalConfig(config);
|
|
723
|
+
} else {
|
|
724
|
+
saveGlobalConfig(config);
|
|
725
|
+
}
|
|
726
|
+
}
|
|
637
727
|
function resolveConfigValue(key) {
|
|
638
728
|
const meta = getConfigKeyMeta(key);
|
|
639
|
-
const config =
|
|
729
|
+
const config = loadConfigForScope(meta.scope);
|
|
640
730
|
const envValue = process.env[meta.envVar];
|
|
641
731
|
const fileValue = config[key];
|
|
642
732
|
if (envValue !== undefined && envValue !== "") {
|
|
643
733
|
return {
|
|
644
734
|
value: envValue,
|
|
645
735
|
source: "environment variable",
|
|
736
|
+
scope: meta.scope,
|
|
646
737
|
configFileValue: fileValue
|
|
647
738
|
};
|
|
648
739
|
}
|
|
649
740
|
if (fileValue !== undefined) {
|
|
650
|
-
return { value: fileValue, source: "config file" };
|
|
741
|
+
return { value: fileValue, source: "config file", scope: meta.scope };
|
|
651
742
|
}
|
|
652
|
-
return { value: meta.default, source: "default" };
|
|
743
|
+
return { value: meta.default, source: "default", scope: meta.scope };
|
|
653
744
|
}
|
|
654
745
|
function resolveAllConfig() {
|
|
655
746
|
return CONFIG_KEYS.map((meta) => ({
|
|
@@ -658,18 +749,46 @@ function resolveAllConfig() {
|
|
|
658
749
|
}));
|
|
659
750
|
}
|
|
660
751
|
function setConfigValue(key, value) {
|
|
661
|
-
const
|
|
752
|
+
const meta = getConfigKeyMeta(key);
|
|
753
|
+
const config = loadConfigForScope(meta.scope);
|
|
662
754
|
config[key] = value;
|
|
663
|
-
|
|
755
|
+
saveConfigForScope(meta.scope, config);
|
|
664
756
|
}
|
|
665
757
|
function resetConfigKey(key) {
|
|
666
|
-
const
|
|
758
|
+
const meta = getConfigKeyMeta(key);
|
|
759
|
+
const config = loadConfigForScope(meta.scope);
|
|
667
760
|
delete config[key];
|
|
668
|
-
|
|
761
|
+
saveConfigForScope(meta.scope, config);
|
|
669
762
|
}
|
|
670
763
|
function resetAllConfig() {
|
|
671
764
|
saveGlobalConfig({});
|
|
765
|
+
saveLocalConfig({});
|
|
672
766
|
}
|
|
767
|
+
function migrateConfigIfNeeded() {
|
|
768
|
+
if (migrationRan)
|
|
769
|
+
return;
|
|
770
|
+
migrationRan = true;
|
|
771
|
+
const { existsSync } = __require("fs");
|
|
772
|
+
if (existsSync(localConfigPath()))
|
|
773
|
+
return;
|
|
774
|
+
const shared = loadGlobalConfig();
|
|
775
|
+
const localKeys = CONFIG_KEYS.filter((k) => k.scope === "local");
|
|
776
|
+
const localConfig = {};
|
|
777
|
+
let hasLocal = false;
|
|
778
|
+
for (const meta of localKeys) {
|
|
779
|
+
const val = shared[meta.key];
|
|
780
|
+
if (val !== undefined) {
|
|
781
|
+
localConfig[meta.key] = val;
|
|
782
|
+
delete shared[meta.key];
|
|
783
|
+
hasLocal = true;
|
|
784
|
+
}
|
|
785
|
+
}
|
|
786
|
+
if (hasLocal) {
|
|
787
|
+
saveLocalConfig(localConfig);
|
|
788
|
+
saveGlobalConfig(shared);
|
|
789
|
+
}
|
|
790
|
+
}
|
|
791
|
+
var migrationRan = false;
|
|
673
792
|
var init_global_config = __esm(() => {
|
|
674
793
|
init_paths();
|
|
675
794
|
init_fs_utils();
|
|
@@ -1010,6 +1129,81 @@ var init_note_index = __esm(() => {
|
|
|
1010
1129
|
]);
|
|
1011
1130
|
});
|
|
1012
1131
|
|
|
1132
|
+
// src/core/device.ts
|
|
1133
|
+
var exports_device = {};
|
|
1134
|
+
__export(exports_device, {
|
|
1135
|
+
updateDeviceHeartbeat: () => updateDeviceHeartbeat,
|
|
1136
|
+
setDeviceName: () => setDeviceName,
|
|
1137
|
+
saveDeviceRegistry: () => saveDeviceRegistry,
|
|
1138
|
+
loadDeviceRegistry: () => loadDeviceRegistry,
|
|
1139
|
+
listDevices: () => listDevices,
|
|
1140
|
+
getOrCreateDeviceId: () => getOrCreateDeviceId
|
|
1141
|
+
});
|
|
1142
|
+
import { existsSync as existsSync3, readFileSync as readFileSync4, writeFileSync as writeFileSync2, mkdirSync as mkdirSync3 } from "fs";
|
|
1143
|
+
import { dirname as dirname2 } from "path";
|
|
1144
|
+
import { hostname, platform } from "os";
|
|
1145
|
+
import { randomUUID } from "crypto";
|
|
1146
|
+
function getOrCreateDeviceId() {
|
|
1147
|
+
const idPath = deviceIdPath();
|
|
1148
|
+
if (existsSync3(idPath)) {
|
|
1149
|
+
return readFileSync4(idPath, "utf-8").trim();
|
|
1150
|
+
}
|
|
1151
|
+
const id = randomUUID();
|
|
1152
|
+
mkdirSync3(dirname2(idPath), { recursive: true });
|
|
1153
|
+
writeFileSync2(idPath, id + `
|
|
1154
|
+
`);
|
|
1155
|
+
return id;
|
|
1156
|
+
}
|
|
1157
|
+
function loadDeviceRegistry() {
|
|
1158
|
+
const raw = safeReadJson(deviceRegistryPath());
|
|
1159
|
+
if (raw !== null && typeof raw === "object" && !Array.isArray(raw) && "devices" in raw) {
|
|
1160
|
+
return raw;
|
|
1161
|
+
}
|
|
1162
|
+
return { devices: {} };
|
|
1163
|
+
}
|
|
1164
|
+
function saveDeviceRegistry(registry) {
|
|
1165
|
+
atomicWriteJson(deviceRegistryPath(), registry);
|
|
1166
|
+
}
|
|
1167
|
+
function updateDeviceHeartbeat() {
|
|
1168
|
+
const id = getOrCreateDeviceId();
|
|
1169
|
+
const registry = loadDeviceRegistry();
|
|
1170
|
+
const now = new Date().toISOString();
|
|
1171
|
+
const existing = registry.devices[id];
|
|
1172
|
+
registry.devices[id] = {
|
|
1173
|
+
name: existing?.name ?? hostname(),
|
|
1174
|
+
hostname: hostname(),
|
|
1175
|
+
platform: platform(),
|
|
1176
|
+
firstSeen: existing?.firstSeen ?? now,
|
|
1177
|
+
lastSeen: now
|
|
1178
|
+
};
|
|
1179
|
+
saveDeviceRegistry(registry);
|
|
1180
|
+
}
|
|
1181
|
+
function listDevices() {
|
|
1182
|
+
const registry = loadDeviceRegistry();
|
|
1183
|
+
return Object.entries(registry.devices).map(([id, info]) => ({
|
|
1184
|
+
id,
|
|
1185
|
+
...info
|
|
1186
|
+
}));
|
|
1187
|
+
}
|
|
1188
|
+
function setDeviceName(name) {
|
|
1189
|
+
const id = getOrCreateDeviceId();
|
|
1190
|
+
const registry = loadDeviceRegistry();
|
|
1191
|
+
const now = new Date().toISOString();
|
|
1192
|
+
const existing = registry.devices[id];
|
|
1193
|
+
registry.devices[id] = {
|
|
1194
|
+
name,
|
|
1195
|
+
hostname: hostname(),
|
|
1196
|
+
platform: platform(),
|
|
1197
|
+
firstSeen: existing?.firstSeen ?? now,
|
|
1198
|
+
lastSeen: now
|
|
1199
|
+
};
|
|
1200
|
+
saveDeviceRegistry(registry);
|
|
1201
|
+
}
|
|
1202
|
+
var init_device = __esm(() => {
|
|
1203
|
+
init_paths();
|
|
1204
|
+
init_fs_utils();
|
|
1205
|
+
});
|
|
1206
|
+
|
|
1013
1207
|
// src/core/sync.ts
|
|
1014
1208
|
var exports_sync = {};
|
|
1015
1209
|
__export(exports_sync, {
|
|
@@ -1021,7 +1215,7 @@ __export(exports_sync, {
|
|
|
1021
1215
|
ensureGitignore: () => ensureGitignore,
|
|
1022
1216
|
disconnectSync: () => disconnectSync
|
|
1023
1217
|
});
|
|
1024
|
-
import { existsSync as
|
|
1218
|
+
import { existsSync as existsSync4, writeFileSync as writeFileSync3 } from "fs";
|
|
1025
1219
|
import { join as join4 } from "path";
|
|
1026
1220
|
import { execSync } from "child_process";
|
|
1027
1221
|
function git(args, timeoutMs = GIT_TIMEOUT) {
|
|
@@ -1042,15 +1236,15 @@ function isSyncInitialized() {
|
|
|
1042
1236
|
const enabled = resolveConfigValue("sync.enabled").value;
|
|
1043
1237
|
if (enabled !== "true")
|
|
1044
1238
|
return false;
|
|
1045
|
-
return
|
|
1239
|
+
return existsSync4(join4(minkRoot(), ".git"));
|
|
1046
1240
|
}
|
|
1047
1241
|
function ensureGitignore() {
|
|
1048
1242
|
const gitignorePath = join4(minkRoot(), ".gitignore");
|
|
1049
|
-
|
|
1243
|
+
writeFileSync3(gitignorePath, GITIGNORE_CONTENTS);
|
|
1050
1244
|
}
|
|
1051
1245
|
function getSyncStatus() {
|
|
1052
1246
|
const enabled = resolveConfigValue("sync.enabled").value === "true";
|
|
1053
|
-
const gitInitialized =
|
|
1247
|
+
const gitInitialized = existsSync4(join4(minkRoot(), ".git"));
|
|
1054
1248
|
const remoteUrl = resolveConfigValue("sync.remote-url").value;
|
|
1055
1249
|
const lastPush = resolveConfigValue("sync.last-push").value;
|
|
1056
1250
|
const lastPull = resolveConfigValue("sync.last-pull").value;
|
|
@@ -1077,7 +1271,7 @@ function getSyncStatus() {
|
|
|
1077
1271
|
function initSync(remoteUrl) {
|
|
1078
1272
|
const root = minkRoot();
|
|
1079
1273
|
const gitDir = join4(root, ".git");
|
|
1080
|
-
if (
|
|
1274
|
+
if (existsSync4(gitDir)) {
|
|
1081
1275
|
console.log("[mink] sync is already initialized in " + root);
|
|
1082
1276
|
console.log("[mink] run 'mink sync disconnect' first to reinitialize");
|
|
1083
1277
|
return;
|
|
@@ -1129,6 +1323,7 @@ function initSync(remoteUrl) {
|
|
|
1129
1323
|
function syncPull(onMessage = (msg) => console.error(msg)) {
|
|
1130
1324
|
if (!isSyncInitialized())
|
|
1131
1325
|
return;
|
|
1326
|
+
ensureGitignore();
|
|
1132
1327
|
const root = minkRoot();
|
|
1133
1328
|
try {
|
|
1134
1329
|
const status = gitSafe("status --porcelain");
|
|
@@ -1140,7 +1335,7 @@ function syncPull(onMessage = (msg) => console.error(msg)) {
|
|
|
1140
1335
|
try {
|
|
1141
1336
|
git(`pull --rebase origin ${branch}`, FETCH_TIMEOUT);
|
|
1142
1337
|
} catch (err) {
|
|
1143
|
-
if (
|
|
1338
|
+
if (existsSync4(join4(root, ".git", "rebase-merge")) || existsSync4(join4(root, ".git", "rebase-apply"))) {
|
|
1144
1339
|
gitSafe("rebase --abort");
|
|
1145
1340
|
onMessage("[mink] sync pull: rebase conflict detected — aborted rebase, local state preserved");
|
|
1146
1341
|
onMessage("[mink] resolve manually with 'mink sync pull' or 'cd ~/.mink && git pull --rebase origin main'");
|
|
@@ -1156,6 +1351,9 @@ function syncPull(onMessage = (msg) => console.error(msg)) {
|
|
|
1156
1351
|
}
|
|
1157
1352
|
}
|
|
1158
1353
|
setConfigValue("sync.last-pull", new Date().toISOString());
|
|
1354
|
+
try {
|
|
1355
|
+
updateDeviceHeartbeat();
|
|
1356
|
+
} catch {}
|
|
1159
1357
|
} catch (err) {
|
|
1160
1358
|
onMessage(`[mink] sync pull error: ${err instanceof Error ? err.message : String(err)}`);
|
|
1161
1359
|
}
|
|
@@ -1163,6 +1361,10 @@ function syncPull(onMessage = (msg) => console.error(msg)) {
|
|
|
1163
1361
|
function syncPush(onMessage = (msg) => console.error(msg)) {
|
|
1164
1362
|
if (!isSyncInitialized())
|
|
1165
1363
|
return;
|
|
1364
|
+
ensureGitignore();
|
|
1365
|
+
try {
|
|
1366
|
+
updateDeviceHeartbeat();
|
|
1367
|
+
} catch {}
|
|
1166
1368
|
const root = minkRoot();
|
|
1167
1369
|
try {
|
|
1168
1370
|
const status = gitSafe("status --porcelain");
|
|
@@ -1182,7 +1384,7 @@ function syncPush(onMessage = (msg) => console.error(msg)) {
|
|
|
1182
1384
|
try {
|
|
1183
1385
|
git(`pull --rebase origin ${branch}`, FETCH_TIMEOUT);
|
|
1184
1386
|
} catch {
|
|
1185
|
-
if (
|
|
1387
|
+
if (existsSync4(join4(root, ".git", "rebase-merge")) || existsSync4(join4(root, ".git", "rebase-apply"))) {
|
|
1186
1388
|
gitSafe("rebase --abort");
|
|
1187
1389
|
onMessage("[mink] sync: rebase conflict during push — local commit preserved, skipping push");
|
|
1188
1390
|
onMessage("[mink] resolve manually with 'mink sync pull' then 'mink sync push'");
|
|
@@ -1202,7 +1404,7 @@ function syncPush(onMessage = (msg) => console.error(msg)) {
|
|
|
1202
1404
|
function disconnectSync() {
|
|
1203
1405
|
const root = minkRoot();
|
|
1204
1406
|
const gitDir = join4(root, ".git");
|
|
1205
|
-
if (!
|
|
1407
|
+
if (!existsSync4(gitDir)) {
|
|
1206
1408
|
console.log("[mink] sync is not initialized — nothing to disconnect");
|
|
1207
1409
|
return;
|
|
1208
1410
|
}
|
|
@@ -1228,12 +1430,17 @@ var GIT_TIMEOUT = 5000, PUSH_TIMEOUT = 1e4, FETCH_TIMEOUT = 15000, GITIGNORE_CON
|
|
|
1228
1430
|
scheduler.pid
|
|
1229
1431
|
scheduler.log
|
|
1230
1432
|
|
|
1433
|
+
# Device identity and local config — machine-specific
|
|
1434
|
+
device-id
|
|
1435
|
+
config.local
|
|
1436
|
+
|
|
1231
1437
|
# Local backups — machine-specific snapshots
|
|
1232
1438
|
projects/*/backups/
|
|
1233
1439
|
`;
|
|
1234
1440
|
var init_sync = __esm(() => {
|
|
1235
1441
|
init_paths();
|
|
1236
1442
|
init_global_config();
|
|
1443
|
+
init_device();
|
|
1237
1444
|
});
|
|
1238
1445
|
|
|
1239
1446
|
// src/core/learning-memory.ts
|
|
@@ -1611,13 +1818,13 @@ var exports_reflect = {};
|
|
|
1611
1818
|
__export(exports_reflect, {
|
|
1612
1819
|
reflect: () => reflect
|
|
1613
1820
|
});
|
|
1614
|
-
import { existsSync as
|
|
1821
|
+
import { existsSync as existsSync5, readFileSync as readFileSync6 } from "fs";
|
|
1615
1822
|
function reflect(projectDir2, memoryPath, configPath2) {
|
|
1616
|
-
if (!
|
|
1823
|
+
if (!existsSync5(memoryPath)) {
|
|
1617
1824
|
console.log("[mink] no learning memory found");
|
|
1618
1825
|
return null;
|
|
1619
1826
|
}
|
|
1620
|
-
const markdown =
|
|
1827
|
+
const markdown = readFileSync6(memoryPath, "utf-8");
|
|
1621
1828
|
const mem = parseLearningMemory(markdown);
|
|
1622
1829
|
const config = safeReadJson(configPath2);
|
|
1623
1830
|
const tokenBudget = config?.learningMemoryTokenBudget ?? DEFAULT_TOKEN_BUDGET;
|
|
@@ -1913,14 +2120,19 @@ __export(exports_paths2, {
|
|
|
1913
2120
|
projectMetaPath: () => projectMetaPath2,
|
|
1914
2121
|
projectDir: () => projectDir2,
|
|
1915
2122
|
minkRoot: () => minkRoot2,
|
|
2123
|
+
localConfigPath: () => localConfigPath2,
|
|
1916
2124
|
learningMemoryPath: () => learningMemoryPath2,
|
|
1917
2125
|
globalConfigPath: () => globalConfigPath2,
|
|
1918
2126
|
frameworkAdvisorPath: () => frameworkAdvisorPath2,
|
|
1919
2127
|
frameworkAdvisorJsonPath: () => frameworkAdvisorJsonPath2,
|
|
1920
2128
|
fileIndexPath: () => fileIndexPath2,
|
|
2129
|
+
deviceRegistryPath: () => deviceRegistryPath2,
|
|
2130
|
+
deviceIdPath: () => deviceIdPath2,
|
|
1921
2131
|
designReportPath: () => designReportPath2,
|
|
1922
2132
|
designCapturesDir: () => designCapturesDir2,
|
|
1923
2133
|
configPath: () => configPath2,
|
|
2134
|
+
channelPidPath: () => channelPidPath2,
|
|
2135
|
+
channelLogPath: () => channelLogPath2,
|
|
1924
2136
|
bugMemoryPath: () => bugMemoryPath2,
|
|
1925
2137
|
backupDirPath: () => backupDirPath2,
|
|
1926
2138
|
actionLogPath: () => actionLogPath2
|
|
@@ -1967,9 +2179,24 @@ function schedulerLogPath2() {
|
|
|
1967
2179
|
function schedulerManifestPath2(cwd) {
|
|
1968
2180
|
return join7(projectDir2(cwd), "scheduler-manifest.json");
|
|
1969
2181
|
}
|
|
2182
|
+
function channelPidPath2() {
|
|
2183
|
+
return join7(MINK_ROOT2, "channel.pid");
|
|
2184
|
+
}
|
|
2185
|
+
function channelLogPath2() {
|
|
2186
|
+
return join7(MINK_ROOT2, "channel.log");
|
|
2187
|
+
}
|
|
1970
2188
|
function globalConfigPath2() {
|
|
1971
2189
|
return join7(MINK_ROOT2, "config");
|
|
1972
2190
|
}
|
|
2191
|
+
function localConfigPath2() {
|
|
2192
|
+
return join7(MINK_ROOT2, "config.local");
|
|
2193
|
+
}
|
|
2194
|
+
function deviceIdPath2() {
|
|
2195
|
+
return join7(MINK_ROOT2, "device-id");
|
|
2196
|
+
}
|
|
2197
|
+
function deviceRegistryPath2() {
|
|
2198
|
+
return join7(MINK_ROOT2, "devices.json");
|
|
2199
|
+
}
|
|
1973
2200
|
function projectMetaPath2(cwd) {
|
|
1974
2201
|
return join7(projectDir2(cwd), "project-meta.json");
|
|
1975
2202
|
}
|
|
@@ -2002,11 +2229,11 @@ __export(exports_backup, {
|
|
|
2002
2229
|
createBackup: () => createBackup
|
|
2003
2230
|
});
|
|
2004
2231
|
import {
|
|
2005
|
-
mkdirSync as
|
|
2232
|
+
mkdirSync as mkdirSync5,
|
|
2006
2233
|
readdirSync as readdirSync2,
|
|
2007
|
-
readFileSync as
|
|
2008
|
-
writeFileSync as
|
|
2009
|
-
existsSync as
|
|
2234
|
+
readFileSync as readFileSync8,
|
|
2235
|
+
writeFileSync as writeFileSync4,
|
|
2236
|
+
existsSync as existsSync7,
|
|
2010
2237
|
statSync as statSync3
|
|
2011
2238
|
} from "fs";
|
|
2012
2239
|
import { join as join8 } from "path";
|
|
@@ -2021,7 +2248,7 @@ function formatTimestamp(date) {
|
|
|
2021
2248
|
return `${y}${mo}${d}-${h}${mi}${s}${ms}`;
|
|
2022
2249
|
}
|
|
2023
2250
|
function copyDirectoryFiles(srcDir, destDir, excludeDirs) {
|
|
2024
|
-
|
|
2251
|
+
mkdirSync5(destDir, { recursive: true });
|
|
2025
2252
|
const entries = readdirSync2(srcDir, { withFileTypes: true });
|
|
2026
2253
|
for (const entry of entries) {
|
|
2027
2254
|
if (entry.isDirectory()) {
|
|
@@ -2029,7 +2256,7 @@ function copyDirectoryFiles(srcDir, destDir, excludeDirs) {
|
|
|
2029
2256
|
continue;
|
|
2030
2257
|
copyDirectoryFiles(join8(srcDir, entry.name), join8(destDir, entry.name), excludeDirs);
|
|
2031
2258
|
} else if (entry.isFile()) {
|
|
2032
|
-
|
|
2259
|
+
writeFileSync4(join8(destDir, entry.name), readFileSync8(join8(srcDir, entry.name)));
|
|
2033
2260
|
}
|
|
2034
2261
|
}
|
|
2035
2262
|
}
|
|
@@ -2038,7 +2265,7 @@ function createBackup(cwd) {
|
|
|
2038
2265
|
const dir = backupDirPath(cwd);
|
|
2039
2266
|
let name = base;
|
|
2040
2267
|
let suffix = 1;
|
|
2041
|
-
while (
|
|
2268
|
+
while (existsSync7(join8(dir, name))) {
|
|
2042
2269
|
name = `${base}-${suffix}`;
|
|
2043
2270
|
suffix++;
|
|
2044
2271
|
}
|
|
@@ -2049,7 +2276,7 @@ function createBackup(cwd) {
|
|
|
2049
2276
|
}
|
|
2050
2277
|
function listBackups(cwd) {
|
|
2051
2278
|
const dir = backupDirPath(cwd);
|
|
2052
|
-
if (!
|
|
2279
|
+
if (!existsSync7(dir))
|
|
2053
2280
|
return [];
|
|
2054
2281
|
const entries = readdirSync2(dir, { withFileTypes: true });
|
|
2055
2282
|
const backups = [];
|
|
@@ -2080,7 +2307,7 @@ function listBackups(cwd) {
|
|
|
2080
2307
|
}
|
|
2081
2308
|
function restoreBackup(cwd, backupName) {
|
|
2082
2309
|
const backupPath = join8(backupDirPath(cwd), backupName);
|
|
2083
|
-
if (!
|
|
2310
|
+
if (!existsSync7(backupPath)) {
|
|
2084
2311
|
throw new Error(`backup not found: ${backupName}`);
|
|
2085
2312
|
}
|
|
2086
2313
|
createBackup(cwd);
|
|
@@ -2450,7 +2677,7 @@ var exports_scan = {};
|
|
|
2450
2677
|
__export(exports_scan, {
|
|
2451
2678
|
scan: () => scan
|
|
2452
2679
|
});
|
|
2453
|
-
import { readFileSync as
|
|
2680
|
+
import { readFileSync as readFileSync9 } from "fs";
|
|
2454
2681
|
import { join as join10 } from "path";
|
|
2455
2682
|
function loadExistingIndex(indexPath) {
|
|
2456
2683
|
const raw = safeReadJson(indexPath);
|
|
@@ -2504,7 +2731,7 @@ function scan(cwd, options) {
|
|
|
2504
2731
|
const fullPath = join10(cwd, file.relativePath);
|
|
2505
2732
|
let content;
|
|
2506
2733
|
try {
|
|
2507
|
-
content =
|
|
2734
|
+
content = readFileSync9(fullPath, "utf-8");
|
|
2508
2735
|
} catch {
|
|
2509
2736
|
continue;
|
|
2510
2737
|
}
|
|
@@ -2540,12 +2767,12 @@ __export(exports_seed, {
|
|
|
2540
2767
|
parseCargoToml: () => parseCargoToml
|
|
2541
2768
|
});
|
|
2542
2769
|
import { basename as basename4, join as join11 } from "path";
|
|
2543
|
-
import { readFileSync as
|
|
2770
|
+
import { readFileSync as readFileSync10, existsSync as existsSync8 } from "fs";
|
|
2544
2771
|
function readFile(filePath) {
|
|
2545
|
-
if (!
|
|
2772
|
+
if (!existsSync8(filePath))
|
|
2546
2773
|
return null;
|
|
2547
2774
|
try {
|
|
2548
|
-
return
|
|
2775
|
+
return readFileSync10(filePath, "utf-8");
|
|
2549
2776
|
} catch {
|
|
2550
2777
|
return null;
|
|
2551
2778
|
}
|
|
@@ -2722,8 +2949,8 @@ __export(exports_init, {
|
|
|
2722
2949
|
buildHooksConfig: () => buildHooksConfig
|
|
2723
2950
|
});
|
|
2724
2951
|
import { execSync as execSync2 } from "child_process";
|
|
2725
|
-
import { mkdirSync as
|
|
2726
|
-
import { resolve as resolve2, dirname as
|
|
2952
|
+
import { mkdirSync as mkdirSync6, existsSync as existsSync9 } from "fs";
|
|
2953
|
+
import { resolve as resolve2, dirname as dirname4, basename as basename5, join as join12 } from "path";
|
|
2727
2954
|
function detectRuntime() {
|
|
2728
2955
|
try {
|
|
2729
2956
|
execSync2("bun --version", { stdio: "ignore" });
|
|
@@ -2734,13 +2961,13 @@ function detectRuntime() {
|
|
|
2734
2961
|
}
|
|
2735
2962
|
function resolveCliPath() {
|
|
2736
2963
|
const selfPath = new URL(import.meta.url).pathname;
|
|
2737
|
-
const selfDir =
|
|
2964
|
+
const selfDir = dirname4(selfPath);
|
|
2738
2965
|
if (selfPath.endsWith("dist/cli.js")) {
|
|
2739
2966
|
return selfPath;
|
|
2740
2967
|
}
|
|
2741
2968
|
const projectRoot = resolve2(selfDir, "../..");
|
|
2742
2969
|
const distPath = join12(projectRoot, "dist", "cli.js");
|
|
2743
|
-
if (
|
|
2970
|
+
if (existsSync9(distPath))
|
|
2744
2971
|
return distPath;
|
|
2745
2972
|
return resolve2(selfDir, "../cli.ts");
|
|
2746
2973
|
}
|
|
@@ -2776,7 +3003,7 @@ function isMinkHook(entry) {
|
|
|
2776
3003
|
return false;
|
|
2777
3004
|
}
|
|
2778
3005
|
function mergeHooksIntoSettings(settingsPath, newHooks) {
|
|
2779
|
-
|
|
3006
|
+
mkdirSync6(dirname4(settingsPath), { recursive: true });
|
|
2780
3007
|
const existing = safeReadJson(settingsPath) ?? {};
|
|
2781
3008
|
const existingHooks = existing.hooks ?? {};
|
|
2782
3009
|
for (const [event, entries] of Object.entries(newHooks)) {
|
|
@@ -2789,9 +3016,9 @@ function mergeHooksIntoSettings(settingsPath, newHooks) {
|
|
|
2789
3016
|
}
|
|
2790
3017
|
function isExistingInstallation(cwd) {
|
|
2791
3018
|
const dir = projectDir(cwd);
|
|
2792
|
-
if (!
|
|
3019
|
+
if (!existsSync9(dir))
|
|
2793
3020
|
return false;
|
|
2794
|
-
return
|
|
3021
|
+
return existsSync9(join12(dir, "file-index.json"));
|
|
2795
3022
|
}
|
|
2796
3023
|
async function init(cwd) {
|
|
2797
3024
|
const runtime = detectRuntime();
|
|
@@ -2807,7 +3034,7 @@ async function init(cwd) {
|
|
|
2807
3034
|
console.log(` backup: ${backupName}`);
|
|
2808
3035
|
}
|
|
2809
3036
|
mergeHooksIntoSettings(settingsPath, hooks);
|
|
2810
|
-
|
|
3037
|
+
mkdirSync6(dir, { recursive: true });
|
|
2811
3038
|
const projectId = generateProjectId(cwd);
|
|
2812
3039
|
const isNotesProject = isWikiEnabled() && isVaultInitialized() && isInsideVault(cwd);
|
|
2813
3040
|
const metaPath = projectMetaPath(cwd);
|
|
@@ -2835,7 +3062,7 @@ async function init(cwd) {
|
|
|
2835
3062
|
scan2(cwd, { check: false });
|
|
2836
3063
|
const { learningMemoryPath: learningMemoryPath3 } = await Promise.resolve().then(() => (init_paths(), exports_paths));
|
|
2837
3064
|
const memPath = learningMemoryPath3(cwd);
|
|
2838
|
-
if (!
|
|
3065
|
+
if (!existsSync9(memPath)) {
|
|
2839
3066
|
const { seedLearningMemory: seedLearningMemory2 } = await Promise.resolve().then(() => (init_seed(), exports_seed));
|
|
2840
3067
|
const { serializeLearningMemory: serializeLearningMemory2 } = await Promise.resolve().then(() => (init_learning_memory(), exports_learning_memory));
|
|
2841
3068
|
const mem = seedLearningMemory2(cwd);
|
|
@@ -2845,7 +3072,7 @@ async function init(cwd) {
|
|
|
2845
3072
|
try {
|
|
2846
3073
|
const projectSlug = basename5(cwd);
|
|
2847
3074
|
const overviewPath = join12(vaultProjects(projectSlug), "overview.md");
|
|
2848
|
-
if (!
|
|
3075
|
+
if (!existsSync9(overviewPath)) {
|
|
2849
3076
|
const now = new Date().toISOString();
|
|
2850
3077
|
const overview = [
|
|
2851
3078
|
`---`,
|
|
@@ -2881,13 +3108,362 @@ var init_init = __esm(() => {
|
|
|
2881
3108
|
init_vault();
|
|
2882
3109
|
});
|
|
2883
3110
|
|
|
3111
|
+
// src/core/channel-templates.ts
|
|
3112
|
+
import { join as join13 } from "path";
|
|
3113
|
+
import { existsSync as existsSync10, writeFileSync as writeFileSync5, mkdirSync as mkdirSync7 } from "fs";
|
|
3114
|
+
function writeCompanionClaudeMd(vaultPath, overwrite = false) {
|
|
3115
|
+
mkdirSync7(vaultPath, { recursive: true });
|
|
3116
|
+
const claudeMdPath = join13(vaultPath, "CLAUDE.md");
|
|
3117
|
+
if (existsSync10(claudeMdPath) && !overwrite) {
|
|
3118
|
+
return false;
|
|
3119
|
+
}
|
|
3120
|
+
writeFileSync5(claudeMdPath, COMPANION_CLAUDE_MD);
|
|
3121
|
+
return true;
|
|
3122
|
+
}
|
|
3123
|
+
var COMPANION_CLAUDE_MD = `# Mink Knowledge Companion
|
|
3124
|
+
|
|
3125
|
+
You are **Mink**, a personal knowledge companion. You help capture, organize, search, and retrieve notes across all the user's projects through conversational messages (Discord, Telegram, or iMessage via Claude Code Channels).
|
|
3126
|
+
|
|
3127
|
+
Your home is this wiki vault — the directory you're running in. Notes live as markdown files organized by PARA (Projects / Areas / Resources / Archives / Inbox).
|
|
3128
|
+
|
|
3129
|
+
## Your Role
|
|
3130
|
+
|
|
3131
|
+
You are the **smart orchestrator**. The \`mink\` CLI is the dumb writer — it takes explicit flags and writes files. Your job:
|
|
3132
|
+
|
|
3133
|
+
1. Understand what the user wants (capture, search, organize, summarize)
|
|
3134
|
+
2. Gather vault context when useful
|
|
3135
|
+
3. Call the right \`mink\` command with good flags
|
|
3136
|
+
4. Reply briefly — the user is likely on mobile
|
|
3137
|
+
|
|
3138
|
+
## Conversational Style
|
|
3139
|
+
|
|
3140
|
+
- **Brief.** One or two sentences. The user is in a chat app, not a terminal.
|
|
3141
|
+
- **Confirm what happened.** "Saved to \`projects/auth/blocker.md\` with tags \`compliance, blocker\`." — short, specific.
|
|
3142
|
+
- **Suggest, don't interrogate.** If you're unsure about a tag, pick a reasonable default and mention it. Don't ask 3 questions before saving a note.
|
|
3143
|
+
- **Surface related work.** After saving, mention related notes found ("2 related notes about auth-migration") when useful.
|
|
3144
|
+
|
|
3145
|
+
## Capturing Notes
|
|
3146
|
+
|
|
3147
|
+
When the user's message sounds like a note ("save this...", "log that...", or just describes something factual), **capture it**. Don't ask permission.
|
|
3148
|
+
|
|
3149
|
+
### Flow
|
|
3150
|
+
|
|
3151
|
+
1. **Read the message.** Extract: what's this about? Is it project-specific?
|
|
3152
|
+
2. **Gather context briefly.** Run these when needed (not every time):
|
|
3153
|
+
- \`mink note list --recent 10\` — recent notes for continuity
|
|
3154
|
+
- \`mink wiki status\` — vault overview
|
|
3155
|
+
- Check \`.mink-index.json\` for existing tag vocabulary
|
|
3156
|
+
3. **Decide metadata:**
|
|
3157
|
+
- **Title** — clear, descriptive (becomes the filename). Not the raw text.
|
|
3158
|
+
- **Category** — one of:
|
|
3159
|
+
- \`projects\` — has a deadline, milestone, or deliverable. Use \`--project <slug>\` if it maps to a known Mink project.
|
|
3160
|
+
- \`areas\` — ongoing responsibility or recurring concern
|
|
3161
|
+
- \`resources\` — reference material, how-to, guide
|
|
3162
|
+
- \`archives\` — completed or historical
|
|
3163
|
+
- \`inbox\` — genuinely unclear (user will sort later)
|
|
3164
|
+
- **Tags** — 2–3 is usually right. **Prefer existing tags** from the vocabulary over inventing new ones. Lowercase, hyphenated.
|
|
3165
|
+
- **Wikilinks** — wrap people, projects, and concepts in \`[[double-brackets]]\` inside the body when they match existing notes.
|
|
3166
|
+
4. **Call \`mink note\`** with the flags:
|
|
3167
|
+
\`\`\`bash
|
|
3168
|
+
mink note --title "Title" --body "Body with [[wikilinks]]" --category <cat> --tags "a,b,c"
|
|
3169
|
+
# Add --project <slug> if project-linked
|
|
3170
|
+
\`\`\`
|
|
3171
|
+
5. **Reply.** One line: where it landed, category, tags. Optionally: related notes.
|
|
3172
|
+
|
|
3173
|
+
### Daily Notes
|
|
3174
|
+
|
|
3175
|
+
If the user says "add to my daily" or "daily" or "today":
|
|
3176
|
+
\`\`\`bash
|
|
3177
|
+
mink note --daily "Content to append"
|
|
3178
|
+
\`\`\`
|
|
3179
|
+
|
|
3180
|
+
### Meeting Notes
|
|
3181
|
+
|
|
3182
|
+
If the user describes a meeting (attendees, topic, discussion):
|
|
3183
|
+
\`\`\`bash
|
|
3184
|
+
mink note --template meeting --title "Meeting: Topic" --body "..." --category areas --tags "meeting,..."
|
|
3185
|
+
\`\`\`
|
|
3186
|
+
|
|
3187
|
+
## Searching and Retrieving
|
|
3188
|
+
|
|
3189
|
+
When the user asks about past work — "what did I write about X?", "show me notes from last week", "find my notes on auth" — use:
|
|
3190
|
+
|
|
3191
|
+
- \`mink note search <term>\` — full-text search (title, description, tags, path)
|
|
3192
|
+
- \`mink note list --recent N\` — recent notes
|
|
3193
|
+
- \`mink note list --category projects\` — filter by category
|
|
3194
|
+
- \`mink note list --tag auth\` — filter by tag
|
|
3195
|
+
|
|
3196
|
+
**Return results briefly.** Top 3–5 matches with one-line summaries. If there are more, say so.
|
|
3197
|
+
|
|
3198
|
+
Example reply:
|
|
3199
|
+
> Found 3 notes about auth-migration:
|
|
3200
|
+
> • \`projects/auth/compliance-blocker.md\` (today) — blocked on session token storage
|
|
3201
|
+
> • \`projects/auth/architecture.md\` (Apr 10) — middleware rewrite plan
|
|
3202
|
+
> • \`areas/daily/2026-04-12.md\` — standup update
|
|
3203
|
+
|
|
3204
|
+
## Organization
|
|
3205
|
+
|
|
3206
|
+
If the user says "move this to projects", "tag this with X", or "categorize my inbox":
|
|
3207
|
+
|
|
3208
|
+
- For a single note: read it, rewrite it in the new category with \`mink note --file\` (ingestion). The CLI doesn't have a move command — you move by rewriting.
|
|
3209
|
+
- For inbox triage: list with \`mink note list --category inbox\`, propose categorization, execute on confirmation.
|
|
3210
|
+
|
|
3211
|
+
## Daily Summaries
|
|
3212
|
+
|
|
3213
|
+
If the user asks "what did I work on today?" or "give me a summary":
|
|
3214
|
+
|
|
3215
|
+
1. Read today's daily note: \`mink note list --tag daily --recent 1\` → read the file
|
|
3216
|
+
2. Check recent notes: \`mink note list --recent 20\`
|
|
3217
|
+
3. Synthesize a short summary (3–5 bullets)
|
|
3218
|
+
|
|
3219
|
+
## Cross-Project Awareness
|
|
3220
|
+
|
|
3221
|
+
Notes may be linked to projects via \`source_project\` in frontmatter. To find notes for a specific project:
|
|
3222
|
+
\`\`\`bash
|
|
3223
|
+
mink note list --category projects
|
|
3224
|
+
mink note search <project-slug>
|
|
3225
|
+
\`\`\`
|
|
3226
|
+
|
|
3227
|
+
Use wikilinks generously: \`[[project-name]]\`, \`[[person-name]]\`, \`[[concept]]\`. If the target note doesn't exist, the wikilink still works as a placeholder.
|
|
3228
|
+
|
|
3229
|
+
## Session Kickoff
|
|
3230
|
+
|
|
3231
|
+
At the start of a fresh conversation (first user message), it's fine to silently run:
|
|
3232
|
+
\`\`\`bash
|
|
3233
|
+
mink wiki status
|
|
3234
|
+
mink note list --recent 5
|
|
3235
|
+
\`\`\`
|
|
3236
|
+
|
|
3237
|
+
Don't announce this. Just have the context.
|
|
3238
|
+
|
|
3239
|
+
## What NOT to Do
|
|
3240
|
+
|
|
3241
|
+
- Don't ask "what category should this be?" — pick one, move on.
|
|
3242
|
+
- Don't paste long output. Summarize.
|
|
3243
|
+
- Don't invent tags that exist with slight variations. Check vocabulary first.
|
|
3244
|
+
- Don't open files or directories unrelated to the vault. Stay focused on notes and wiki operations.
|
|
3245
|
+
- Don't edit source code in this vault — this is a knowledge repo, not a codebase.
|
|
3246
|
+
|
|
3247
|
+
## CLI Reference (Cheat Sheet)
|
|
3248
|
+
|
|
3249
|
+
\`\`\`bash
|
|
3250
|
+
# Capture
|
|
3251
|
+
mink note "quick thought" # inbox capture
|
|
3252
|
+
mink note --title T --body B --category areas --tags a,b
|
|
3253
|
+
mink note --daily "content" # daily note
|
|
3254
|
+
mink note --template meeting --title "..." --body "..."
|
|
3255
|
+
mink note --file ./external.md --category resources
|
|
3256
|
+
|
|
3257
|
+
# Search / list
|
|
3258
|
+
mink note search <term>
|
|
3259
|
+
mink note list [--category X] [--tag Y] [--recent N]
|
|
3260
|
+
|
|
3261
|
+
# Vault
|
|
3262
|
+
mink wiki status
|
|
3263
|
+
mink wiki rebuild-index
|
|
3264
|
+
\`\`\`
|
|
3265
|
+
`;
|
|
3266
|
+
var init_channel_templates = () => {};
|
|
3267
|
+
|
|
3268
|
+
// src/core/channel-process.ts
|
|
3269
|
+
import { readFileSync as readFileSync11, writeFileSync as writeFileSync6, unlinkSync as unlinkSync2, mkdirSync as mkdirSync8, existsSync as existsSync11 } from "fs";
|
|
3270
|
+
import { dirname as dirname5, join as join14 } from "path";
|
|
3271
|
+
import { spawnSync } from "child_process";
|
|
3272
|
+
function readChannelPidFile() {
|
|
3273
|
+
try {
|
|
3274
|
+
const raw = readFileSync11(channelPidPath(), "utf-8");
|
|
3275
|
+
const data = JSON.parse(raw);
|
|
3276
|
+
if (data && typeof data.session === "string" && typeof data.platform === "string" && typeof data.startedAt === "string" && typeof data.vaultPath === "string") {
|
|
3277
|
+
return data;
|
|
3278
|
+
}
|
|
3279
|
+
return null;
|
|
3280
|
+
} catch {
|
|
3281
|
+
return null;
|
|
3282
|
+
}
|
|
3283
|
+
}
|
|
3284
|
+
function writeChannelPidFile(data) {
|
|
3285
|
+
const pidPath = channelPidPath();
|
|
3286
|
+
mkdirSync8(dirname5(pidPath), { recursive: true });
|
|
3287
|
+
writeFileSync6(pidPath, JSON.stringify(data, null, 2));
|
|
3288
|
+
}
|
|
3289
|
+
function removeChannelPidFile() {
|
|
3290
|
+
try {
|
|
3291
|
+
unlinkSync2(channelPidPath());
|
|
3292
|
+
} catch {}
|
|
3293
|
+
}
|
|
3294
|
+
function sessionName(platform2) {
|
|
3295
|
+
return `${SESSION_PREFIX}${platform2}`;
|
|
3296
|
+
}
|
|
3297
|
+
function isScreenInstalled() {
|
|
3298
|
+
const result = spawnSync("screen", ["-ls"], { stdio: "ignore" });
|
|
3299
|
+
return !result.error;
|
|
3300
|
+
}
|
|
3301
|
+
function screenSessionExists(session) {
|
|
3302
|
+
const result = spawnSync("screen", ["-ls", session], {
|
|
3303
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
3304
|
+
encoding: "utf-8"
|
|
3305
|
+
});
|
|
3306
|
+
const output = typeof result.stdout === "string" ? result.stdout : "";
|
|
3307
|
+
return new RegExp(`\\d+\\.${session}\\b`).test(output);
|
|
3308
|
+
}
|
|
3309
|
+
function shellEscape(s) {
|
|
3310
|
+
if (/^[a-zA-Z0-9_@%+=:,./\-]+$/.test(s))
|
|
3311
|
+
return s;
|
|
3312
|
+
return "'" + s.replace(/'/g, "'\\''") + "'";
|
|
3313
|
+
}
|
|
3314
|
+
async function startChannelProcess(opts) {
|
|
3315
|
+
if (!isScreenInstalled()) {
|
|
3316
|
+
throw new Error(`GNU screen is required but was not found on PATH.
|
|
3317
|
+
` + `macOS: screen is pre-installed — check your shell environment.
|
|
3318
|
+
` + "Linux: install with `sudo apt install screen` (or your package manager).");
|
|
3319
|
+
}
|
|
3320
|
+
const session = sessionName(opts.platform);
|
|
3321
|
+
if (screenSessionExists(session)) {
|
|
3322
|
+
writeChannelPidFile({
|
|
3323
|
+
session,
|
|
3324
|
+
platform: opts.platform,
|
|
3325
|
+
startedAt: new Date().toISOString(),
|
|
3326
|
+
vaultPath: opts.vaultPath
|
|
3327
|
+
});
|
|
3328
|
+
return { session, alreadyRunning: true };
|
|
3329
|
+
}
|
|
3330
|
+
const claudeCmd = opts.claudeCommand ?? "claude";
|
|
3331
|
+
const pluginSpec = PLUGIN_SPECS[opts.platform];
|
|
3332
|
+
const tokenEnvVar = TOKEN_ENV_VARS[opts.platform];
|
|
3333
|
+
const claudeFlags = ["--channels", shellEscape(pluginSpec)];
|
|
3334
|
+
if (opts.skipPermissions) {
|
|
3335
|
+
claudeFlags.push("--dangerously-skip-permissions");
|
|
3336
|
+
}
|
|
3337
|
+
const parts = [];
|
|
3338
|
+
parts.push(`cd ${shellEscape(opts.vaultPath)}`);
|
|
3339
|
+
if (opts.token) {
|
|
3340
|
+
parts.push(`export ${tokenEnvVar}=${shellEscape(opts.token)}`);
|
|
3341
|
+
}
|
|
3342
|
+
parts.push(`exec ${shellEscape(claudeCmd)} ${claudeFlags.join(" ")}`);
|
|
3343
|
+
const innerCmd = parts.join("; ");
|
|
3344
|
+
const result = spawnSync("screen", ["-T", "screen-256color", "-dmS", session, "bash", "-c", innerCmd], { stdio: ["ignore", "pipe", "pipe"], encoding: "utf-8" });
|
|
3345
|
+
if (result.status !== 0) {
|
|
3346
|
+
const stderr = typeof result.stderr === "string" ? result.stderr : "";
|
|
3347
|
+
throw new Error(`screen failed to create session (exit ${result.status}): ${stderr || "(no output)"}`);
|
|
3348
|
+
}
|
|
3349
|
+
await new Promise((r) => setTimeout(r, 700));
|
|
3350
|
+
if (!screenSessionExists(session)) {
|
|
3351
|
+
throw new Error("channel session died immediately after starting. " + "This usually means `claude` failed to launch. Check:\n" + " • Is `claude` on your PATH? Run `which claude`.\n" + " • Have you installed the plugin? Run `claude` then `/plugin install discord@claude-plugins-official`.\n" + ` • Try running the command manually to see the error:
|
|
3352
|
+
` + ` cd ${opts.vaultPath} && claude --channels ${pluginSpec}`);
|
|
3353
|
+
}
|
|
3354
|
+
writeChannelPidFile({
|
|
3355
|
+
session,
|
|
3356
|
+
platform: opts.platform,
|
|
3357
|
+
startedAt: new Date().toISOString(),
|
|
3358
|
+
vaultPath: opts.vaultPath
|
|
3359
|
+
});
|
|
3360
|
+
return { session, alreadyRunning: false };
|
|
3361
|
+
}
|
|
3362
|
+
async function stopChannelProcess() {
|
|
3363
|
+
const pidData = readChannelPidFile();
|
|
3364
|
+
if (!pidData) {
|
|
3365
|
+
return "not-running";
|
|
3366
|
+
}
|
|
3367
|
+
if (!screenSessionExists(pidData.session)) {
|
|
3368
|
+
removeChannelPidFile();
|
|
3369
|
+
return "not-running";
|
|
3370
|
+
}
|
|
3371
|
+
spawnSync("screen", ["-S", pidData.session, "-X", "quit"], { stdio: "ignore" });
|
|
3372
|
+
for (let i = 0;i < 30; i++) {
|
|
3373
|
+
if (!screenSessionExists(pidData.session)) {
|
|
3374
|
+
removeChannelPidFile();
|
|
3375
|
+
return "stopped";
|
|
3376
|
+
}
|
|
3377
|
+
await new Promise((r) => setTimeout(r, 100));
|
|
3378
|
+
}
|
|
3379
|
+
removeChannelPidFile();
|
|
3380
|
+
return "stopped";
|
|
3381
|
+
}
|
|
3382
|
+
function isChannelRunning() {
|
|
3383
|
+
const pidData = readChannelPidFile();
|
|
3384
|
+
if (!pidData)
|
|
3385
|
+
return false;
|
|
3386
|
+
if (!screenSessionExists(pidData.session)) {
|
|
3387
|
+
removeChannelPidFile();
|
|
3388
|
+
return false;
|
|
3389
|
+
}
|
|
3390
|
+
return true;
|
|
3391
|
+
}
|
|
3392
|
+
function getChannelStatus() {
|
|
3393
|
+
const pidData = readChannelPidFile();
|
|
3394
|
+
if (!pidData)
|
|
3395
|
+
return null;
|
|
3396
|
+
if (!screenSessionExists(pidData.session)) {
|
|
3397
|
+
removeChannelPidFile();
|
|
3398
|
+
return null;
|
|
3399
|
+
}
|
|
3400
|
+
const startedMs = Date.parse(pidData.startedAt);
|
|
3401
|
+
const uptimeSec = Number.isFinite(startedMs) ? Math.max(0, Math.floor((Date.now() - startedMs) / 1000)) : 0;
|
|
3402
|
+
return {
|
|
3403
|
+
session: pidData.session,
|
|
3404
|
+
platform: pidData.platform,
|
|
3405
|
+
startedAt: pidData.startedAt,
|
|
3406
|
+
vaultPath: pidData.vaultPath,
|
|
3407
|
+
uptime: uptimeSec
|
|
3408
|
+
};
|
|
3409
|
+
}
|
|
3410
|
+
function getChannelLogs() {
|
|
3411
|
+
const pidData = readChannelPidFile();
|
|
3412
|
+
if (!pidData)
|
|
3413
|
+
return null;
|
|
3414
|
+
if (!screenSessionExists(pidData.session))
|
|
3415
|
+
return null;
|
|
3416
|
+
const tmpPath = join14(minkRoot(), `.channel-capture-${Date.now()}-${process.pid}.txt`);
|
|
3417
|
+
const result = spawnSync("screen", ["-S", pidData.session, "-X", "hardcopy", "-h", tmpPath], { stdio: "ignore" });
|
|
3418
|
+
if (result.status !== 0)
|
|
3419
|
+
return null;
|
|
3420
|
+
for (let i = 0;i < 20; i++) {
|
|
3421
|
+
if (existsSync11(tmpPath))
|
|
3422
|
+
break;
|
|
3423
|
+
const delayUntil = Date.now() + 50;
|
|
3424
|
+
while (Date.now() < delayUntil) {}
|
|
3425
|
+
}
|
|
3426
|
+
try {
|
|
3427
|
+
const content = readFileSync11(tmpPath, "utf-8");
|
|
3428
|
+
try {
|
|
3429
|
+
unlinkSync2(tmpPath);
|
|
3430
|
+
} catch {}
|
|
3431
|
+
return content;
|
|
3432
|
+
} catch {
|
|
3433
|
+
return null;
|
|
3434
|
+
}
|
|
3435
|
+
}
|
|
3436
|
+
function attachChannel() {
|
|
3437
|
+
const pidData = readChannelPidFile();
|
|
3438
|
+
if (!pidData)
|
|
3439
|
+
return "not-running";
|
|
3440
|
+
if (!screenSessionExists(pidData.session)) {
|
|
3441
|
+
removeChannelPidFile();
|
|
3442
|
+
return "not-running";
|
|
3443
|
+
}
|
|
3444
|
+
spawnSync("screen", ["-r", pidData.session], { stdio: "inherit" });
|
|
3445
|
+
return "attached";
|
|
3446
|
+
}
|
|
3447
|
+
var SESSION_PREFIX = "mink-channel-", PLUGIN_SPECS, TOKEN_ENV_VARS;
|
|
3448
|
+
var init_channel_process = __esm(() => {
|
|
3449
|
+
init_paths();
|
|
3450
|
+
PLUGIN_SPECS = {
|
|
3451
|
+
discord: "plugin:discord@claude-plugins-official",
|
|
3452
|
+
telegram: "plugin:telegram@claude-plugins-official"
|
|
3453
|
+
};
|
|
3454
|
+
TOKEN_ENV_VARS = {
|
|
3455
|
+
discord: "DISCORD_BOT_TOKEN",
|
|
3456
|
+
telegram: "TELEGRAM_BOT_TOKEN"
|
|
3457
|
+
};
|
|
3458
|
+
});
|
|
3459
|
+
|
|
2884
3460
|
// src/core/daemon.ts
|
|
2885
|
-
import { readFileSync as
|
|
2886
|
-
import { mkdirSync as
|
|
2887
|
-
import { dirname as
|
|
3461
|
+
import { readFileSync as readFileSync12, writeFileSync as writeFileSync7, unlinkSync as unlinkSync3, openSync } from "fs";
|
|
3462
|
+
import { mkdirSync as mkdirSync9 } from "fs";
|
|
3463
|
+
import { dirname as dirname6, resolve as resolve3 } from "path";
|
|
2888
3464
|
function readPidFile() {
|
|
2889
3465
|
try {
|
|
2890
|
-
const raw =
|
|
3466
|
+
const raw = readFileSync12(schedulerPidPath(), "utf-8");
|
|
2891
3467
|
const data = JSON.parse(raw);
|
|
2892
3468
|
if (data && typeof data.pid === "number" && typeof data.startedAt === "string" && typeof data.projectCwd === "string") {
|
|
2893
3469
|
return data;
|
|
@@ -2899,12 +3475,12 @@ function readPidFile() {
|
|
|
2899
3475
|
}
|
|
2900
3476
|
function writePidFile(data) {
|
|
2901
3477
|
const pidPath = schedulerPidPath();
|
|
2902
|
-
|
|
2903
|
-
|
|
3478
|
+
mkdirSync9(dirname6(pidPath), { recursive: true });
|
|
3479
|
+
writeFileSync7(pidPath, JSON.stringify(data, null, 2));
|
|
2904
3480
|
}
|
|
2905
3481
|
function removePidFile() {
|
|
2906
3482
|
try {
|
|
2907
|
-
|
|
3483
|
+
unlinkSync3(schedulerPidPath());
|
|
2908
3484
|
} catch {}
|
|
2909
3485
|
}
|
|
2910
3486
|
function isProcessAlive(pid) {
|
|
@@ -2924,10 +3500,10 @@ function startDaemon(cwd) {
|
|
|
2924
3500
|
if (existing) {
|
|
2925
3501
|
removePidFile();
|
|
2926
3502
|
}
|
|
2927
|
-
const __dir =
|
|
3503
|
+
const __dir = dirname6(new URL(import.meta.url).pathname);
|
|
2928
3504
|
const cliPath = resolve3(__dir, "../cli.ts");
|
|
2929
3505
|
const logPath = schedulerLogPath();
|
|
2930
|
-
|
|
3506
|
+
mkdirSync9(dirname6(logPath), { recursive: true });
|
|
2931
3507
|
const logFd = openSync(logPath, "a");
|
|
2932
3508
|
const proc = Bun.spawn(["bun", "run", cliPath, "cron", "__daemon"], {
|
|
2933
3509
|
cwd,
|
|
@@ -2944,8 +3520,37 @@ function startDaemon(cwd) {
|
|
|
2944
3520
|
});
|
|
2945
3521
|
console.log(`[mink] scheduler started (PID: ${proc.pid})`);
|
|
2946
3522
|
console.log(`[mink] log: ${logPath}`);
|
|
3523
|
+
maybeStartChannel().catch((err) => {
|
|
3524
|
+
console.error(`[mink] failed to start channel: ${err instanceof Error ? err.message : String(err)}`);
|
|
3525
|
+
});
|
|
3526
|
+
}
|
|
3527
|
+
async function maybeStartChannel() {
|
|
3528
|
+
const enabled = resolveConfigValue("channel.discord.enabled").value === "true";
|
|
3529
|
+
if (!enabled)
|
|
3530
|
+
return;
|
|
3531
|
+
if (!isVaultInitialized()) {
|
|
3532
|
+
console.log("[mink] channel enabled but vault not initialized — skipping channel start");
|
|
3533
|
+
return;
|
|
3534
|
+
}
|
|
3535
|
+
const token = resolveConfigValue("channel.discord.bot-token").value;
|
|
3536
|
+
if (!token) {
|
|
3537
|
+
console.log("[mink] channel enabled but no Discord bot token configured — skipping channel start");
|
|
3538
|
+
return;
|
|
3539
|
+
}
|
|
3540
|
+
if (isChannelRunning()) {
|
|
3541
|
+
return;
|
|
3542
|
+
}
|
|
3543
|
+
const platform2 = resolveConfigValue("channel.default-platform").value || "discord";
|
|
3544
|
+
const skipPermissions = resolveConfigValue("channel.skip-permissions").value === "true";
|
|
3545
|
+
const vaultPath = resolveVaultPath();
|
|
3546
|
+
writeCompanionClaudeMd(vaultPath, false);
|
|
3547
|
+
const result = await startChannelProcess({ vaultPath, platform: platform2, token, skipPermissions });
|
|
3548
|
+
if (!result.alreadyRunning) {
|
|
3549
|
+
console.log(`[mink] channel started (session: ${result.session}, platform: ${platform2})`);
|
|
3550
|
+
}
|
|
2947
3551
|
}
|
|
2948
3552
|
async function stopDaemon() {
|
|
3553
|
+
await stopChannelIfRunning();
|
|
2949
3554
|
const pidData = readPidFile();
|
|
2950
3555
|
if (!pidData) {
|
|
2951
3556
|
console.log("[mink] scheduler is not running (no PID file)");
|
|
@@ -2972,24 +3577,38 @@ async function stopDaemon() {
|
|
|
2972
3577
|
removePidFile();
|
|
2973
3578
|
console.log("[mink] scheduler force-stopped (SIGKILL)");
|
|
2974
3579
|
}
|
|
3580
|
+
async function stopChannelIfRunning() {
|
|
3581
|
+
if (!isChannelRunning())
|
|
3582
|
+
return;
|
|
3583
|
+
const result = await stopChannelProcess();
|
|
3584
|
+
if (result === "stopped") {
|
|
3585
|
+
console.log("[mink] channel stopped");
|
|
3586
|
+
}
|
|
3587
|
+
}
|
|
2975
3588
|
function getDaemonStatus(cwd) {
|
|
3589
|
+
const channel = getChannelStatus();
|
|
2976
3590
|
const pidData = readPidFile();
|
|
2977
3591
|
if (!pidData) {
|
|
2978
|
-
return { running: false };
|
|
3592
|
+
return { running: false, channel };
|
|
2979
3593
|
}
|
|
2980
3594
|
if (!isProcessAlive(pidData.pid)) {
|
|
2981
3595
|
removePidFile();
|
|
2982
|
-
return { running: false };
|
|
3596
|
+
return { running: false, channel };
|
|
2983
3597
|
}
|
|
2984
3598
|
return {
|
|
2985
3599
|
running: true,
|
|
2986
3600
|
pid: pidData.pid,
|
|
2987
3601
|
startedAt: pidData.startedAt,
|
|
2988
|
-
projectCwd: pidData.projectCwd
|
|
3602
|
+
projectCwd: pidData.projectCwd,
|
|
3603
|
+
channel
|
|
2989
3604
|
};
|
|
2990
3605
|
}
|
|
2991
3606
|
var init_daemon = __esm(() => {
|
|
2992
3607
|
init_paths();
|
|
3608
|
+
init_global_config();
|
|
3609
|
+
init_vault();
|
|
3610
|
+
init_channel_templates();
|
|
3611
|
+
init_channel_process();
|
|
2993
3612
|
});
|
|
2994
3613
|
|
|
2995
3614
|
// src/commands/status.ts
|
|
@@ -2997,9 +3616,9 @@ var exports_status = {};
|
|
|
2997
3616
|
__export(exports_status, {
|
|
2998
3617
|
status: () => status
|
|
2999
3618
|
});
|
|
3000
|
-
import { existsSync as
|
|
3619
|
+
import { existsSync as existsSync13, readFileSync as readFileSync13, statSync as statSync5 } from "fs";
|
|
3001
3620
|
function checkJsonFile(name, filePath, validator) {
|
|
3002
|
-
if (!
|
|
3621
|
+
if (!existsSync13(filePath))
|
|
3003
3622
|
return { name, path: filePath, status: "missing" };
|
|
3004
3623
|
const data = safeReadJson(filePath);
|
|
3005
3624
|
if (data === null)
|
|
@@ -3009,10 +3628,10 @@ function checkJsonFile(name, filePath, validator) {
|
|
|
3009
3628
|
return { name, path: filePath, status: "ok" };
|
|
3010
3629
|
}
|
|
3011
3630
|
function checkTextFile(name, filePath) {
|
|
3012
|
-
if (!
|
|
3631
|
+
if (!existsSync13(filePath))
|
|
3013
3632
|
return { name, path: filePath, status: "missing" };
|
|
3014
3633
|
try {
|
|
3015
|
-
|
|
3634
|
+
readFileSync13(filePath, "utf-8");
|
|
3016
3635
|
return { name, path: filePath, status: "ok" };
|
|
3017
3636
|
} catch {
|
|
3018
3637
|
return { name, path: filePath, status: "corrupt" };
|
|
@@ -3072,8 +3691,8 @@ function status(cwd) {
|
|
|
3072
3691
|
console.log();
|
|
3073
3692
|
try {
|
|
3074
3693
|
const memPath = learningMemoryPath(cwd);
|
|
3075
|
-
if (
|
|
3076
|
-
const content =
|
|
3694
|
+
if (existsSync13(memPath)) {
|
|
3695
|
+
const content = readFileSync13(memPath, "utf-8");
|
|
3077
3696
|
const mem = parseLearningMemory(content);
|
|
3078
3697
|
const total = totalEntryCount(mem);
|
|
3079
3698
|
const mtime = statSync5(memPath).mtime;
|
|
@@ -3127,8 +3746,8 @@ var exports_scan2 = {};
|
|
|
3127
3746
|
__export(exports_scan2, {
|
|
3128
3747
|
scan: () => scan2
|
|
3129
3748
|
});
|
|
3130
|
-
import { readFileSync as
|
|
3131
|
-
import { join as
|
|
3749
|
+
import { readFileSync as readFileSync14 } from "fs";
|
|
3750
|
+
import { join as join15 } from "path";
|
|
3132
3751
|
function loadExistingIndex2(indexPath) {
|
|
3133
3752
|
const raw = safeReadJson(indexPath);
|
|
3134
3753
|
if (isFileIndex(raw))
|
|
@@ -3178,10 +3797,10 @@ function scan2(cwd, options) {
|
|
|
3178
3797
|
newIndex.header.lifetimeHits = index.header.lifetimeHits;
|
|
3179
3798
|
newIndex.header.lifetimeMisses = index.header.lifetimeMisses;
|
|
3180
3799
|
for (const file of scanned) {
|
|
3181
|
-
const fullPath =
|
|
3800
|
+
const fullPath = join15(cwd, file.relativePath);
|
|
3182
3801
|
let content;
|
|
3183
3802
|
try {
|
|
3184
|
-
content =
|
|
3803
|
+
content = readFileSync14(fullPath, "utf-8");
|
|
3185
3804
|
} catch {
|
|
3186
3805
|
continue;
|
|
3187
3806
|
}
|
|
@@ -3212,13 +3831,13 @@ var exports_reflect2 = {};
|
|
|
3212
3831
|
__export(exports_reflect2, {
|
|
3213
3832
|
reflect: () => reflect2
|
|
3214
3833
|
});
|
|
3215
|
-
import { existsSync as
|
|
3834
|
+
import { existsSync as existsSync14, readFileSync as readFileSync15 } from "fs";
|
|
3216
3835
|
function reflect2(projectDir3, memoryPath, configPath3) {
|
|
3217
|
-
if (!
|
|
3836
|
+
if (!existsSync14(memoryPath)) {
|
|
3218
3837
|
console.log("[mink] no learning memory found");
|
|
3219
3838
|
return null;
|
|
3220
3839
|
}
|
|
3221
|
-
const markdown =
|
|
3840
|
+
const markdown = readFileSync15(memoryPath, "utf-8");
|
|
3222
3841
|
const mem = parseLearningMemory(markdown);
|
|
3223
3842
|
const config = safeReadJson(configPath3);
|
|
3224
3843
|
const tokenBudget = config?.learningMemoryTokenBudget ?? DEFAULT_TOKEN_BUDGET2;
|
|
@@ -3499,7 +4118,7 @@ __export(exports_pre_write, {
|
|
|
3499
4118
|
analyzePreWrite: () => analyzePreWrite
|
|
3500
4119
|
});
|
|
3501
4120
|
import { relative as relative4 } from "path";
|
|
3502
|
-
import { readFileSync as
|
|
4121
|
+
import { readFileSync as readFileSync16 } from "fs";
|
|
3503
4122
|
function analyzePreWrite(filePath, writeContent, doNotRepeatEntries, bugMemory) {
|
|
3504
4123
|
const warnings = [];
|
|
3505
4124
|
const allMatches = [];
|
|
@@ -3553,7 +4172,7 @@ async function preWrite(cwd) {
|
|
|
3553
4172
|
const writeContent = extractWriteContent(input);
|
|
3554
4173
|
let doNotRepeatEntries = [];
|
|
3555
4174
|
try {
|
|
3556
|
-
const markdown =
|
|
4175
|
+
const markdown = readFileSync16(learningMemoryPath(cwd), "utf-8");
|
|
3557
4176
|
const mem = parseLearningMemory(markdown);
|
|
3558
4177
|
doNotRepeatEntries = getEntries(mem, "Do-Not-Repeat");
|
|
3559
4178
|
} catch {}
|
|
@@ -3610,7 +4229,7 @@ __export(exports_post_write, {
|
|
|
3610
4229
|
analyzePostWrite: () => analyzePostWrite
|
|
3611
4230
|
});
|
|
3612
4231
|
import { relative as relative5 } from "path";
|
|
3613
|
-
import { readFileSync as
|
|
4232
|
+
import { readFileSync as readFileSync17 } from "fs";
|
|
3614
4233
|
function analyzePostWrite(filePath, fileContent, index) {
|
|
3615
4234
|
if (isWriteExcluded(filePath)) {
|
|
3616
4235
|
return {
|
|
@@ -3674,7 +4293,7 @@ async function postWrite(cwd) {
|
|
|
3674
4293
|
const filePath = relative5(cwd, absolutePath);
|
|
3675
4294
|
let fileContent = null;
|
|
3676
4295
|
try {
|
|
3677
|
-
fileContent =
|
|
4296
|
+
fileContent = readFileSync17(absolutePath, "utf-8");
|
|
3678
4297
|
} catch {}
|
|
3679
4298
|
const rawState = safeReadJson(sessionPath(cwd));
|
|
3680
4299
|
const state = isSessionState(rawState) ? rawState : createSessionState();
|
|
@@ -4094,10 +4713,10 @@ async function executeTask(taskId, projectCwd) {
|
|
|
4094
4713
|
if (task.actionType === "ai-cli") {
|
|
4095
4714
|
try {
|
|
4096
4715
|
const { learningMemoryPath: learningMemoryPath4 } = await Promise.resolve().then(() => (init_paths(), exports_paths));
|
|
4097
|
-
const { readFileSync:
|
|
4716
|
+
const { readFileSync: readFileSync18 } = await import("fs");
|
|
4098
4717
|
let memoryContent;
|
|
4099
4718
|
try {
|
|
4100
|
-
memoryContent =
|
|
4719
|
+
memoryContent = readFileSync18(learningMemoryPath4(projectCwd), "utf-8");
|
|
4101
4720
|
} catch {
|
|
4102
4721
|
console.log("[mink] no learning memory found, skipping reflection");
|
|
4103
4722
|
return;
|
|
@@ -4655,9 +5274,9 @@ var init_design_eval = __esm(() => {
|
|
|
4655
5274
|
});
|
|
4656
5275
|
|
|
4657
5276
|
// src/core/dashboard-api.ts
|
|
4658
|
-
import { existsSync as
|
|
5277
|
+
import { existsSync as existsSync15, readFileSync as readFileSync18 } from "fs";
|
|
4659
5278
|
function checkJsonFile2(name, filePath, validator) {
|
|
4660
|
-
if (!
|
|
5279
|
+
if (!existsSync15(filePath))
|
|
4661
5280
|
return { name, status: "missing" };
|
|
4662
5281
|
const data = safeReadJson(filePath);
|
|
4663
5282
|
if (data === null)
|
|
@@ -4667,10 +5286,10 @@ function checkJsonFile2(name, filePath, validator) {
|
|
|
4667
5286
|
return { name, status: "ok" };
|
|
4668
5287
|
}
|
|
4669
5288
|
function checkTextFile2(name, filePath) {
|
|
4670
|
-
if (!
|
|
5289
|
+
if (!existsSync15(filePath))
|
|
4671
5290
|
return { name, status: "missing" };
|
|
4672
5291
|
try {
|
|
4673
|
-
|
|
5292
|
+
readFileSync18(filePath, "utf-8");
|
|
4674
5293
|
return { name, status: "ok" };
|
|
4675
5294
|
} catch {
|
|
4676
5295
|
return { name, status: "corrupt" };
|
|
@@ -4753,7 +5372,7 @@ function loadSchedulerPanel(cwd) {
|
|
|
4753
5372
|
}
|
|
4754
5373
|
function loadLearningMemoryPanel(cwd) {
|
|
4755
5374
|
const memPath = learningMemoryPath(cwd);
|
|
4756
|
-
if (!
|
|
5375
|
+
if (!existsSync15(memPath)) {
|
|
4757
5376
|
return {
|
|
4758
5377
|
projectName: "unknown",
|
|
4759
5378
|
sections: {
|
|
@@ -4765,7 +5384,7 @@ function loadLearningMemoryPanel(cwd) {
|
|
|
4765
5384
|
};
|
|
4766
5385
|
}
|
|
4767
5386
|
try {
|
|
4768
|
-
const content =
|
|
5387
|
+
const content = readFileSync18(memPath, "utf-8");
|
|
4769
5388
|
return parseLearningMemory(content);
|
|
4770
5389
|
} catch {
|
|
4771
5390
|
return {
|
|
@@ -4867,10 +5486,10 @@ var init_dashboard_api = __esm(() => {
|
|
|
4867
5486
|
});
|
|
4868
5487
|
|
|
4869
5488
|
// src/core/project-registry.ts
|
|
4870
|
-
import { readdirSync as readdirSync4, existsSync as
|
|
4871
|
-
import { join as
|
|
5489
|
+
import { readdirSync as readdirSync4, existsSync as existsSync16 } from "fs";
|
|
5490
|
+
import { join as join16 } from "path";
|
|
4872
5491
|
function getProjectMeta(projDir) {
|
|
4873
|
-
const metaPath =
|
|
5492
|
+
const metaPath = join16(projDir, "project-meta.json");
|
|
4874
5493
|
const raw = safeReadJson(metaPath);
|
|
4875
5494
|
if (raw === null || typeof raw !== "object" || Array.isArray(raw)) {
|
|
4876
5495
|
return null;
|
|
@@ -4887,15 +5506,15 @@ function getProjectMeta(projDir) {
|
|
|
4887
5506
|
};
|
|
4888
5507
|
}
|
|
4889
5508
|
function listRegisteredProjects() {
|
|
4890
|
-
const projectsDir =
|
|
4891
|
-
if (!
|
|
5509
|
+
const projectsDir = join16(minkRoot(), "projects");
|
|
5510
|
+
if (!existsSync16(projectsDir))
|
|
4892
5511
|
return [];
|
|
4893
5512
|
const entries = readdirSync4(projectsDir, { withFileTypes: true });
|
|
4894
5513
|
const projects = [];
|
|
4895
5514
|
for (const entry of entries) {
|
|
4896
5515
|
if (!entry.isDirectory())
|
|
4897
5516
|
continue;
|
|
4898
|
-
const projDir =
|
|
5517
|
+
const projDir = join16(projectsDir, entry.name);
|
|
4899
5518
|
const meta = getProjectMeta(projDir);
|
|
4900
5519
|
if (meta) {
|
|
4901
5520
|
projects.push({
|
|
@@ -5059,8 +5678,8 @@ __export(exports_dashboard_server, {
|
|
|
5059
5678
|
startDashboardServer: () => startDashboardServer
|
|
5060
5679
|
});
|
|
5061
5680
|
import { watch } from "fs";
|
|
5062
|
-
import { existsSync as
|
|
5063
|
-
import { basename as basename7, dirname as
|
|
5681
|
+
import { existsSync as existsSync17 } from "fs";
|
|
5682
|
+
import { basename as basename7, dirname as dirname7, join as join17, extname as extname2 } from "path";
|
|
5064
5683
|
|
|
5065
5684
|
class SSEManager {
|
|
5066
5685
|
clients = new Map;
|
|
@@ -5213,7 +5832,7 @@ function extractPathParam(pathname, prefix) {
|
|
|
5213
5832
|
}
|
|
5214
5833
|
async function startDashboardServer(cwd, options = {}) {
|
|
5215
5834
|
const port = options.port ?? 4040;
|
|
5216
|
-
const
|
|
5835
|
+
const hostname2 = options.hostname ?? "127.0.0.1";
|
|
5217
5836
|
const sseManager = new SSEManager;
|
|
5218
5837
|
sseManager.start();
|
|
5219
5838
|
let activeCwd = cwd;
|
|
@@ -5233,15 +5852,15 @@ async function startDashboardServer(cwd, options = {}) {
|
|
|
5233
5852
|
timestamp: new Date().toISOString()
|
|
5234
5853
|
});
|
|
5235
5854
|
});
|
|
5236
|
-
const __dir =
|
|
5855
|
+
const __dir = dirname7(new URL(import.meta.url).pathname);
|
|
5237
5856
|
let pkgRoot = __dir;
|
|
5238
|
-
while (pkgRoot !==
|
|
5239
|
-
if (
|
|
5857
|
+
while (pkgRoot !== dirname7(pkgRoot)) {
|
|
5858
|
+
if (existsSync17(join17(pkgRoot, "package.json")))
|
|
5240
5859
|
break;
|
|
5241
|
-
pkgRoot =
|
|
5860
|
+
pkgRoot = dirname7(pkgRoot);
|
|
5242
5861
|
}
|
|
5243
|
-
const dashboardOutDir =
|
|
5244
|
-
const dashboardBuilt =
|
|
5862
|
+
const dashboardOutDir = join17(pkgRoot, "dashboard", "out");
|
|
5863
|
+
const dashboardBuilt = existsSync17(join17(dashboardOutDir, "index.html"));
|
|
5245
5864
|
let clientIdCounter = 0;
|
|
5246
5865
|
if (!dashboardBuilt) {
|
|
5247
5866
|
console.warn("[mink] dashboard not built. Run: cd dashboard && bun run build");
|
|
@@ -5257,7 +5876,7 @@ async function startDashboardServer(cwd, options = {}) {
|
|
|
5257
5876
|
}
|
|
5258
5877
|
const server = await runtimeServe({
|
|
5259
5878
|
port,
|
|
5260
|
-
hostname,
|
|
5879
|
+
hostname: hostname2,
|
|
5261
5880
|
idleTimeout: 0,
|
|
5262
5881
|
async fetch(req) {
|
|
5263
5882
|
const url = new URL(req.url);
|
|
@@ -5271,9 +5890,9 @@ async function startDashboardServer(cwd, options = {}) {
|
|
|
5271
5890
|
} else {
|
|
5272
5891
|
let filePath;
|
|
5273
5892
|
if (pathname === "/") {
|
|
5274
|
-
filePath =
|
|
5893
|
+
filePath = join17(dashboardOutDir, "index.html");
|
|
5275
5894
|
} else {
|
|
5276
|
-
filePath =
|
|
5895
|
+
filePath = join17(dashboardOutDir, pathname);
|
|
5277
5896
|
}
|
|
5278
5897
|
if (!filePath.startsWith(dashboardOutDir)) {
|
|
5279
5898
|
return jsonResponse({ error: "Forbidden" }, 403);
|
|
@@ -5286,7 +5905,7 @@ async function startDashboardServer(cwd, options = {}) {
|
|
|
5286
5905
|
const htmlServed = await serveFile(filePath + ".html", "text/html; charset=utf-8");
|
|
5287
5906
|
if (htmlServed)
|
|
5288
5907
|
return htmlServed;
|
|
5289
|
-
const indexServed = await serveFile(
|
|
5908
|
+
const indexServed = await serveFile(join17(dashboardOutDir, "index.html"), "text/html; charset=utf-8");
|
|
5290
5909
|
if (indexServed)
|
|
5291
5910
|
return indexServed;
|
|
5292
5911
|
}
|
|
@@ -5346,7 +5965,7 @@ retry: 3000
|
|
|
5346
5965
|
if (!filename || filename.includes("..") || filename.includes("/")) {
|
|
5347
5966
|
return jsonResponse({ error: "Invalid filename" }, 400);
|
|
5348
5967
|
}
|
|
5349
|
-
const imgPath =
|
|
5968
|
+
const imgPath = join17(designCapturesDir(resolvedCwd), filename);
|
|
5350
5969
|
const served = await serveFile(imgPath, "image/jpeg");
|
|
5351
5970
|
if (served) {
|
|
5352
5971
|
served.headers.set("Cache-Control", "public, max-age=60");
|
|
@@ -5420,11 +6039,11 @@ retry: 3000
|
|
|
5420
6039
|
return jsonResponse({ error: "Not found" }, 404);
|
|
5421
6040
|
}
|
|
5422
6041
|
});
|
|
5423
|
-
const serverUrl = `http://${
|
|
6042
|
+
const serverUrl = `http://${hostname2}:${server.port}`;
|
|
5424
6043
|
if (options.open !== false) {
|
|
5425
6044
|
try {
|
|
5426
|
-
const
|
|
5427
|
-
const cmd =
|
|
6045
|
+
const platform2 = process.platform;
|
|
6046
|
+
const cmd = platform2 === "darwin" ? ["open", serverUrl] : platform2 === "win32" ? ["cmd", "/c", "start", serverUrl] : ["xdg-open", serverUrl];
|
|
5428
6047
|
runtimeSpawn(cmd).unref();
|
|
5429
6048
|
} catch {}
|
|
5430
6049
|
}
|
|
@@ -5478,9 +6097,9 @@ var exports_dashboard = {};
|
|
|
5478
6097
|
__export(exports_dashboard, {
|
|
5479
6098
|
dashboard: () => dashboard
|
|
5480
6099
|
});
|
|
5481
|
-
import { existsSync as
|
|
6100
|
+
import { existsSync as existsSync18 } from "fs";
|
|
5482
6101
|
async function dashboard(cwd, args) {
|
|
5483
|
-
if (!
|
|
6102
|
+
if (!existsSync18(projectDir(cwd))) {
|
|
5484
6103
|
console.error("[mink] project not initialized. Run: mink init");
|
|
5485
6104
|
process.exit(1);
|
|
5486
6105
|
}
|
|
@@ -5502,7 +6121,7 @@ var exports_daemon = {};
|
|
|
5502
6121
|
__export(exports_daemon, {
|
|
5503
6122
|
daemon: () => daemon
|
|
5504
6123
|
});
|
|
5505
|
-
import { readFileSync as
|
|
6124
|
+
import { readFileSync as readFileSync19, existsSync as existsSync19 } from "fs";
|
|
5506
6125
|
async function daemon(cwd, args) {
|
|
5507
6126
|
const subcommand = args[0];
|
|
5508
6127
|
switch (subcommand) {
|
|
@@ -5518,12 +6137,12 @@ async function daemon(cwd, args) {
|
|
|
5518
6137
|
break;
|
|
5519
6138
|
case "logs": {
|
|
5520
6139
|
const logPath = schedulerLogPath();
|
|
5521
|
-
if (!
|
|
6140
|
+
if (!existsSync19(logPath)) {
|
|
5522
6141
|
console.log("[mink] no log file found");
|
|
5523
6142
|
return;
|
|
5524
6143
|
}
|
|
5525
6144
|
try {
|
|
5526
|
-
const content =
|
|
6145
|
+
const content = readFileSync19(logPath, "utf-8");
|
|
5527
6146
|
const lines = content.split(`
|
|
5528
6147
|
`);
|
|
5529
6148
|
const tail = lines.slice(-50).join(`
|
|
@@ -5545,6 +6164,232 @@ var init_daemon2 = __esm(() => {
|
|
|
5545
6164
|
init_paths();
|
|
5546
6165
|
});
|
|
5547
6166
|
|
|
6167
|
+
// src/commands/channel.ts
|
|
6168
|
+
var exports_channel = {};
|
|
6169
|
+
__export(exports_channel, {
|
|
6170
|
+
channel: () => channel
|
|
6171
|
+
});
|
|
6172
|
+
function parsePlatform(value) {
|
|
6173
|
+
if (!value)
|
|
6174
|
+
return null;
|
|
6175
|
+
if (SUPPORTED_PLATFORMS.includes(value)) {
|
|
6176
|
+
return value;
|
|
6177
|
+
}
|
|
6178
|
+
return null;
|
|
6179
|
+
}
|
|
6180
|
+
function extractFlag(args, flag) {
|
|
6181
|
+
const idx = args.findIndex((a) => a === flag || a.startsWith(flag + "="));
|
|
6182
|
+
if (idx === -1)
|
|
6183
|
+
return;
|
|
6184
|
+
const arg = args[idx];
|
|
6185
|
+
if (arg.includes("=")) {
|
|
6186
|
+
return arg.slice(arg.indexOf("=") + 1);
|
|
6187
|
+
}
|
|
6188
|
+
return args[idx + 1];
|
|
6189
|
+
}
|
|
6190
|
+
async function channel(args) {
|
|
6191
|
+
const subcommand = args[0];
|
|
6192
|
+
const rest = args.slice(1);
|
|
6193
|
+
switch (subcommand) {
|
|
6194
|
+
case "setup":
|
|
6195
|
+
setupChannel(rest);
|
|
6196
|
+
break;
|
|
6197
|
+
case "start":
|
|
6198
|
+
await startChannel(rest);
|
|
6199
|
+
break;
|
|
6200
|
+
case "stop":
|
|
6201
|
+
await stopChannel();
|
|
6202
|
+
break;
|
|
6203
|
+
case "status":
|
|
6204
|
+
showStatus();
|
|
6205
|
+
break;
|
|
6206
|
+
case "logs":
|
|
6207
|
+
showLogs();
|
|
6208
|
+
break;
|
|
6209
|
+
case "attach":
|
|
6210
|
+
doAttach();
|
|
6211
|
+
break;
|
|
6212
|
+
default:
|
|
6213
|
+
printUsage();
|
|
6214
|
+
process.exit(1);
|
|
6215
|
+
}
|
|
6216
|
+
}
|
|
6217
|
+
function setupChannel(args) {
|
|
6218
|
+
const platform2 = parsePlatform(args[0]);
|
|
6219
|
+
if (!platform2) {
|
|
6220
|
+
console.error("[mink] missing or invalid platform");
|
|
6221
|
+
console.error("Usage: mink channel setup <discord|telegram> --token <token>");
|
|
6222
|
+
process.exit(1);
|
|
6223
|
+
}
|
|
6224
|
+
if (platform2 === "telegram") {
|
|
6225
|
+
console.error("[mink] telegram setup is not yet supported");
|
|
6226
|
+
process.exit(1);
|
|
6227
|
+
}
|
|
6228
|
+
const token = extractFlag(args, "--token");
|
|
6229
|
+
if (!token) {
|
|
6230
|
+
console.log("[mink] Discord Channel Setup");
|
|
6231
|
+
console.log("");
|
|
6232
|
+
console.log("In the Discord Developer Portal (https://discord.com/developers/applications):");
|
|
6233
|
+
console.log("");
|
|
6234
|
+
console.log(" 1. New Application > give it a name");
|
|
6235
|
+
console.log(" 2. Bot > Reset Token > copy the token");
|
|
6236
|
+
console.log(" 3. Bot > scroll to Privileged Gateway Intents:");
|
|
6237
|
+
console.log(" - Enable MESSAGE CONTENT INTENT (required)");
|
|
6238
|
+
console.log(" 4. OAuth2 > URL Generator:");
|
|
6239
|
+
console.log(" - Integration Type: Guild Install (NOT User Install)");
|
|
6240
|
+
console.log(" - Scopes: bot");
|
|
6241
|
+
console.log(" - Bot Permissions: View Channels, Send Messages,");
|
|
6242
|
+
console.log(" Send Messages in Threads, Read Message History,");
|
|
6243
|
+
console.log(" Attach Files, Add Reactions");
|
|
6244
|
+
console.log(" 5. Open the generated URL to invite the bot to a server");
|
|
6245
|
+
console.log(" (create a personal server if you just want to DM the bot)");
|
|
6246
|
+
console.log("");
|
|
6247
|
+
console.log("Then install the channel plugin once inside Claude Code:");
|
|
6248
|
+
console.log(" claude");
|
|
6249
|
+
console.log(" /plugin install discord@claude-plugins-official");
|
|
6250
|
+
console.log(" (exit Claude Code)");
|
|
6251
|
+
console.log("");
|
|
6252
|
+
console.log("Finally, save your token:");
|
|
6253
|
+
console.log(" mink channel setup discord --token <your-token>");
|
|
6254
|
+
console.log("");
|
|
6255
|
+
console.log("Your token is stored locally in ~/.mink/config.local");
|
|
6256
|
+
console.log("and is NOT synced across machines.");
|
|
6257
|
+
return;
|
|
6258
|
+
}
|
|
6259
|
+
if (!/^[\w.-]{30,}$/.test(token)) {
|
|
6260
|
+
console.error("[mink] token format looks invalid — expected a long token string");
|
|
6261
|
+
process.exit(1);
|
|
6262
|
+
}
|
|
6263
|
+
setConfigValue("channel.discord.bot-token", token);
|
|
6264
|
+
setConfigValue("channel.discord.enabled", "true");
|
|
6265
|
+
setConfigValue("channel.default-platform", "discord");
|
|
6266
|
+
console.log("[mink] Discord bot token saved to config.local");
|
|
6267
|
+
console.log("[mink] channel.discord.enabled = true");
|
|
6268
|
+
console.log("[mink] channel.default-platform = discord");
|
|
6269
|
+
console.log("");
|
|
6270
|
+
console.log("Next: mink channel start");
|
|
6271
|
+
}
|
|
6272
|
+
async function startChannel(args) {
|
|
6273
|
+
if (!isVaultInitialized()) {
|
|
6274
|
+
console.error("[mink] wiki vault is not initialized");
|
|
6275
|
+
console.error("Run: mink wiki init");
|
|
6276
|
+
process.exit(1);
|
|
6277
|
+
}
|
|
6278
|
+
const requested = parsePlatform(args[0]);
|
|
6279
|
+
const platform2 = requested ?? parsePlatform(resolveConfigValue("channel.default-platform").value) ?? "discord";
|
|
6280
|
+
if (platform2 === "telegram") {
|
|
6281
|
+
console.error("[mink] telegram is not yet supported");
|
|
6282
|
+
process.exit(1);
|
|
6283
|
+
}
|
|
6284
|
+
const token = resolveConfigValue("channel.discord.bot-token").value;
|
|
6285
|
+
if (!token) {
|
|
6286
|
+
console.error("[mink] no Discord bot token configured");
|
|
6287
|
+
console.error("Run: mink channel setup discord --token <your-token>");
|
|
6288
|
+
process.exit(1);
|
|
6289
|
+
}
|
|
6290
|
+
const vaultPath = resolveVaultPath();
|
|
6291
|
+
const wrote = writeCompanionClaudeMd(vaultPath, false);
|
|
6292
|
+
if (wrote) {
|
|
6293
|
+
console.log(`[mink] created companion CLAUDE.md at ${vaultPath}`);
|
|
6294
|
+
}
|
|
6295
|
+
const skipPermissions = resolveConfigValue("channel.skip-permissions").value === "true";
|
|
6296
|
+
let result;
|
|
6297
|
+
try {
|
|
6298
|
+
result = await startChannelProcess({ vaultPath, platform: platform2, token, skipPermissions });
|
|
6299
|
+
} catch (err) {
|
|
6300
|
+
console.error("[mink] failed to start channel:");
|
|
6301
|
+
console.error(err instanceof Error ? err.message : String(err));
|
|
6302
|
+
process.exit(1);
|
|
6303
|
+
}
|
|
6304
|
+
if (result.alreadyRunning) {
|
|
6305
|
+
console.log(`[mink] channel is already running (screen session: ${result.session})`);
|
|
6306
|
+
return;
|
|
6307
|
+
}
|
|
6308
|
+
console.log(`[mink] channel started`);
|
|
6309
|
+
console.log(`[mink] platform: ${platform2}`);
|
|
6310
|
+
console.log(`[mink] vault: ${vaultPath}`);
|
|
6311
|
+
console.log(`[mink] session: ${result.session} (GNU screen)`);
|
|
6312
|
+
console.log("");
|
|
6313
|
+
console.log("Next:");
|
|
6314
|
+
console.log(" 1. DM your bot on Discord — it replies with a pairing code");
|
|
6315
|
+
console.log(" 2. Attach to the Claude Code session: mink channel attach");
|
|
6316
|
+
console.log(" 3. Inside the session, run: /discord:access pair <code>");
|
|
6317
|
+
console.log(" 4. Then lock down access: /discord:access policy allowlist");
|
|
6318
|
+
console.log(" 5. Detach with Ctrl-a d");
|
|
6319
|
+
console.log("");
|
|
6320
|
+
console.log("See activity: mink channel logs");
|
|
6321
|
+
}
|
|
6322
|
+
async function stopChannel() {
|
|
6323
|
+
const result = await stopChannelProcess();
|
|
6324
|
+
switch (result) {
|
|
6325
|
+
case "not-running":
|
|
6326
|
+
console.log("[mink] channel is not running");
|
|
6327
|
+
break;
|
|
6328
|
+
case "stopped":
|
|
6329
|
+
console.log("[mink] channel stopped");
|
|
6330
|
+
break;
|
|
6331
|
+
}
|
|
6332
|
+
}
|
|
6333
|
+
function showStatus() {
|
|
6334
|
+
const status2 = getChannelStatus();
|
|
6335
|
+
if (!status2) {
|
|
6336
|
+
console.log("[mink] channel is not running");
|
|
6337
|
+
return;
|
|
6338
|
+
}
|
|
6339
|
+
console.log(`running: yes`);
|
|
6340
|
+
console.log(`session: ${status2.session}`);
|
|
6341
|
+
console.log(`platform: ${status2.platform}`);
|
|
6342
|
+
console.log(`vault: ${status2.vaultPath}`);
|
|
6343
|
+
console.log(`started: ${status2.startedAt}`);
|
|
6344
|
+
console.log(`uptime: ${formatUptime(status2.uptime)}`);
|
|
6345
|
+
console.log("");
|
|
6346
|
+
console.log("Attach: mink channel attach");
|
|
6347
|
+
}
|
|
6348
|
+
function formatUptime(seconds) {
|
|
6349
|
+
if (seconds < 60)
|
|
6350
|
+
return `${seconds}s`;
|
|
6351
|
+
const mins = Math.floor(seconds / 60);
|
|
6352
|
+
if (mins < 60)
|
|
6353
|
+
return `${mins}m ${seconds % 60}s`;
|
|
6354
|
+
const hrs = Math.floor(mins / 60);
|
|
6355
|
+
return `${hrs}h ${mins % 60}m`;
|
|
6356
|
+
}
|
|
6357
|
+
function showLogs() {
|
|
6358
|
+
const content = getChannelLogs();
|
|
6359
|
+
if (content == null) {
|
|
6360
|
+
console.log("[mink] channel is not running (no logs to show)");
|
|
6361
|
+
return;
|
|
6362
|
+
}
|
|
6363
|
+
console.log(content.replace(/\n+$/, ""));
|
|
6364
|
+
}
|
|
6365
|
+
function doAttach() {
|
|
6366
|
+
const result = attachChannel();
|
|
6367
|
+
if (result === "not-running") {
|
|
6368
|
+
console.log("[mink] channel is not running");
|
|
6369
|
+
console.log("Start it with: mink channel start");
|
|
6370
|
+
}
|
|
6371
|
+
}
|
|
6372
|
+
function printUsage() {
|
|
6373
|
+
console.error("Usage: mink channel <subcommand>");
|
|
6374
|
+
console.error("");
|
|
6375
|
+
console.error("Subcommands:");
|
|
6376
|
+
console.error(" setup <platform> --token <token> Configure a channel (discord|telegram)");
|
|
6377
|
+
console.error(" start [platform] Launch channel session (in GNU screen)");
|
|
6378
|
+
console.error(" stop Stop channel session");
|
|
6379
|
+
console.error(" status Show channel status");
|
|
6380
|
+
console.error(" logs Show recent channel output");
|
|
6381
|
+
console.error(" attach Attach to the channel's Claude Code session");
|
|
6382
|
+
console.error(" (detach with Ctrl-a then d)");
|
|
6383
|
+
}
|
|
6384
|
+
var SUPPORTED_PLATFORMS;
|
|
6385
|
+
var init_channel = __esm(() => {
|
|
6386
|
+
init_global_config();
|
|
6387
|
+
init_vault();
|
|
6388
|
+
init_channel_templates();
|
|
6389
|
+
init_channel_process();
|
|
6390
|
+
SUPPORTED_PLATFORMS = ["discord", "telegram"];
|
|
6391
|
+
});
|
|
6392
|
+
|
|
5548
6393
|
// src/commands/config.ts
|
|
5549
6394
|
var exports_config = {};
|
|
5550
6395
|
__export(exports_config, {
|
|
@@ -5600,7 +6445,7 @@ async function config(args) {
|
|
|
5600
6445
|
const all = resolveAllConfig();
|
|
5601
6446
|
console.log("[mink] configuration:");
|
|
5602
6447
|
for (const entry of all) {
|
|
5603
|
-
let line2 = ` ${entry.key} = ${entry.value} (source: ${entry.source})`;
|
|
6448
|
+
let line2 = ` ${entry.key} = ${entry.value} (${entry.scope}, source: ${entry.source})`;
|
|
5604
6449
|
if (entry.source === "environment variable" && entry.configFileValue !== undefined) {
|
|
5605
6450
|
line2 += ` [config file value: ${entry.configFileValue} — overridden]`;
|
|
5606
6451
|
}
|
|
@@ -5635,8 +6480,8 @@ var init_config2 = __esm(() => {
|
|
|
5635
6480
|
|
|
5636
6481
|
// src/commands/init.ts
|
|
5637
6482
|
import { execSync as execSync3 } from "child_process";
|
|
5638
|
-
import { mkdirSync as
|
|
5639
|
-
import { resolve as resolve4, dirname as
|
|
6483
|
+
import { mkdirSync as mkdirSync10, existsSync as existsSync20 } from "fs";
|
|
6484
|
+
import { resolve as resolve4, dirname as dirname8, basename as basename8, join as join18 } from "path";
|
|
5640
6485
|
function detectRuntime2() {
|
|
5641
6486
|
try {
|
|
5642
6487
|
execSync3("bun --version", { stdio: "ignore" });
|
|
@@ -5677,7 +6522,7 @@ function isMinkHook2(entry) {
|
|
|
5677
6522
|
return false;
|
|
5678
6523
|
}
|
|
5679
6524
|
function mergeHooksIntoSettings2(settingsPath, newHooks) {
|
|
5680
|
-
|
|
6525
|
+
mkdirSync10(dirname8(settingsPath), { recursive: true });
|
|
5681
6526
|
const existing = safeReadJson(settingsPath) ?? {};
|
|
5682
6527
|
const existingHooks = existing.hooks ?? {};
|
|
5683
6528
|
for (const [event, entries] of Object.entries(newHooks)) {
|
|
@@ -5700,7 +6545,7 @@ var exports_update = {};
|
|
|
5700
6545
|
__export(exports_update, {
|
|
5701
6546
|
update: () => update
|
|
5702
6547
|
});
|
|
5703
|
-
import { resolve as resolve5, dirname as
|
|
6548
|
+
import { resolve as resolve5, dirname as dirname9 } from "path";
|
|
5704
6549
|
function parseArgs(args) {
|
|
5705
6550
|
let dryRun = false;
|
|
5706
6551
|
let project = null;
|
|
@@ -5748,7 +6593,7 @@ async function update(cwd, args) {
|
|
|
5748
6593
|
return;
|
|
5749
6594
|
}
|
|
5750
6595
|
const runtime = detectRuntime2();
|
|
5751
|
-
const cliPath = resolve5(
|
|
6596
|
+
const cliPath = resolve5(dirname9(new URL(import.meta.url).pathname), "../cli.ts");
|
|
5752
6597
|
const newHooks = buildHooksConfig2(runtime, cliPath);
|
|
5753
6598
|
for (const target of targets) {
|
|
5754
6599
|
console.log(`[mink] updating: ${target.name} (${target.id})`);
|
|
@@ -5817,8 +6662,8 @@ var init_restore = __esm(() => {
|
|
|
5817
6662
|
});
|
|
5818
6663
|
|
|
5819
6664
|
// src/core/design-eval/server-detect.ts
|
|
5820
|
-
import { readFileSync as
|
|
5821
|
-
import { join as
|
|
6665
|
+
import { readFileSync as readFileSync20 } from "fs";
|
|
6666
|
+
import { join as join19 } from "path";
|
|
5822
6667
|
async function probePort(port) {
|
|
5823
6668
|
try {
|
|
5824
6669
|
const controller = new AbortController;
|
|
@@ -5840,7 +6685,7 @@ async function findRunningServer(ports = DEFAULT_PROBE_PORTS) {
|
|
|
5840
6685
|
}
|
|
5841
6686
|
function detectDevCommand(cwd) {
|
|
5842
6687
|
try {
|
|
5843
|
-
const raw =
|
|
6688
|
+
const raw = readFileSync20(join19(cwd, "package.json"), "utf-8");
|
|
5844
6689
|
const pkg = JSON.parse(raw);
|
|
5845
6690
|
const scripts = pkg.scripts;
|
|
5846
6691
|
if (!scripts || typeof scripts !== "object")
|
|
@@ -5860,10 +6705,10 @@ var init_server_detect = __esm(() => {
|
|
|
5860
6705
|
});
|
|
5861
6706
|
|
|
5862
6707
|
// src/core/design-eval/route-detect.ts
|
|
5863
|
-
import { existsSync as
|
|
5864
|
-
import { join as
|
|
6708
|
+
import { existsSync as existsSync21, readdirSync as readdirSync5, statSync as statSync8 } from "fs";
|
|
6709
|
+
import { join as join20, relative as relative6, sep } from "path";
|
|
5865
6710
|
function detectFramework(cwd) {
|
|
5866
|
-
const has = (name) => ["js", "mjs", "ts", "cjs"].some((ext) =>
|
|
6711
|
+
const has = (name) => ["js", "mjs", "ts", "cjs"].some((ext) => existsSync21(join20(cwd, `${name}.${ext}`))) || existsSync21(join20(cwd, name));
|
|
5867
6712
|
if (has("next.config"))
|
|
5868
6713
|
return "nextjs";
|
|
5869
6714
|
if (has("svelte.config"))
|
|
@@ -5888,8 +6733,8 @@ function detectRoutes(cwd) {
|
|
|
5888
6733
|
}
|
|
5889
6734
|
function detectNextRoutes(cwd) {
|
|
5890
6735
|
const routes = [];
|
|
5891
|
-
const appDir =
|
|
5892
|
-
if (
|
|
6736
|
+
const appDir = join20(cwd, "app");
|
|
6737
|
+
if (existsSync21(appDir)) {
|
|
5893
6738
|
const pageFiles = findFiles(appDir, /^page\.(tsx?|jsx?)$/);
|
|
5894
6739
|
for (const file of pageFiles) {
|
|
5895
6740
|
const rel = relative6(appDir, file);
|
|
@@ -5900,8 +6745,8 @@ function detectNextRoutes(cwd) {
|
|
|
5900
6745
|
routes.push(route);
|
|
5901
6746
|
}
|
|
5902
6747
|
}
|
|
5903
|
-
const pagesDir =
|
|
5904
|
-
if (
|
|
6748
|
+
const pagesDir = join20(cwd, "pages");
|
|
6749
|
+
if (existsSync21(pagesDir)) {
|
|
5905
6750
|
const pageFiles = findFiles(pagesDir, /\.(tsx?|jsx?)$/);
|
|
5906
6751
|
for (const file of pageFiles) {
|
|
5907
6752
|
const rel = relative6(pagesDir, file);
|
|
@@ -5920,8 +6765,8 @@ function detectNextRoutes(cwd) {
|
|
|
5920
6765
|
return unique.length > 0 ? unique.sort() : ["/"];
|
|
5921
6766
|
}
|
|
5922
6767
|
function detectSvelteKitRoutes(cwd) {
|
|
5923
|
-
const routesDir =
|
|
5924
|
-
if (!
|
|
6768
|
+
const routesDir = join20(cwd, "src", "routes");
|
|
6769
|
+
if (!existsSync21(routesDir))
|
|
5925
6770
|
return ["/"];
|
|
5926
6771
|
const routes = [];
|
|
5927
6772
|
const pageFiles = findFiles(routesDir, /^\+page\.svelte$/);
|
|
@@ -5936,8 +6781,8 @@ function detectSvelteKitRoutes(cwd) {
|
|
|
5936
6781
|
return routes.length > 0 ? routes.sort() : ["/"];
|
|
5937
6782
|
}
|
|
5938
6783
|
function detectNuxtRoutes(cwd) {
|
|
5939
|
-
const pagesDir =
|
|
5940
|
-
if (!
|
|
6784
|
+
const pagesDir = join20(cwd, "pages");
|
|
6785
|
+
if (!existsSync21(pagesDir))
|
|
5941
6786
|
return ["/"];
|
|
5942
6787
|
const routes = [];
|
|
5943
6788
|
const vueFiles = findFiles(pagesDir, /\.vue$/);
|
|
@@ -5963,7 +6808,7 @@ function findFiles(dir, pattern) {
|
|
|
5963
6808
|
for (const entry of entries) {
|
|
5964
6809
|
if (entry.startsWith(".") || entry === "node_modules")
|
|
5965
6810
|
continue;
|
|
5966
|
-
const full =
|
|
6811
|
+
const full = join20(current, entry);
|
|
5967
6812
|
try {
|
|
5968
6813
|
const stat2 = statSync8(full);
|
|
5969
6814
|
if (stat2.isDirectory()) {
|
|
@@ -18868,10 +19713,10 @@ var init_NetworkManager = __esm(() => {
|
|
|
18868
19713
|
throw error;
|
|
18869
19714
|
}
|
|
18870
19715
|
}
|
|
18871
|
-
async setUserAgent(userAgent, userAgentMetadata,
|
|
19716
|
+
async setUserAgent(userAgent, userAgentMetadata, platform2) {
|
|
18872
19717
|
this.#userAgent = userAgent;
|
|
18873
19718
|
this.#userAgentMetadata = userAgentMetadata;
|
|
18874
|
-
this.#platform =
|
|
19719
|
+
this.#platform = platform2;
|
|
18875
19720
|
await this.#applyToAllClients(this.#applyUserAgent.bind(this));
|
|
18876
19721
|
}
|
|
18877
19722
|
async#applyUserAgent(client) {
|
|
@@ -28613,8 +29458,8 @@ var require_ChannelProxy = __commonJS((exports) => {
|
|
|
28613
29458
|
#properties;
|
|
28614
29459
|
#id = (0, uuid_js_1.uuidv4)();
|
|
28615
29460
|
#logger;
|
|
28616
|
-
constructor(
|
|
28617
|
-
this.#properties =
|
|
29461
|
+
constructor(channel2, logger) {
|
|
29462
|
+
this.#properties = channel2;
|
|
28618
29463
|
this.#logger = logger;
|
|
28619
29464
|
}
|
|
28620
29465
|
async init(realm, eventManager) {
|
|
@@ -31307,7 +32152,7 @@ var require_BrowsingContextImpl = __commonJS((exports) => {
|
|
|
31307
32152
|
const realm = new WindowRealm_js_1.WindowRealm(this.id, this.#browsingContextStorage, this.#cdpTarget.cdpClient, this.#eventManager, id, this.#logger, origin, uniqueId, this.#realmStorage, sandbox);
|
|
31308
32153
|
if (auxData.isDefault) {
|
|
31309
32154
|
this.#defaultRealmDeferred.resolve(realm);
|
|
31310
|
-
Promise.all(this.#cdpTarget.getChannels().map((
|
|
32155
|
+
Promise.all(this.#cdpTarget.getChannels().map((channel2) => channel2.startListenerFromWindow(realm, this.#eventManager)));
|
|
31311
32156
|
}
|
|
31312
32157
|
});
|
|
31313
32158
|
this.#cdpTarget.cdpClient.on("Runtime.executionContextDestroyed", (params) => {
|
|
@@ -37889,7 +38734,7 @@ var init_ExposedFunction = __esm(() => {
|
|
|
37889
38734
|
}
|
|
37890
38735
|
async#initialize() {
|
|
37891
38736
|
const connection = this.#connection;
|
|
37892
|
-
const
|
|
38737
|
+
const channel2 = {
|
|
37893
38738
|
type: "channel",
|
|
37894
38739
|
value: {
|
|
37895
38740
|
channel: this.#channel,
|
|
@@ -37916,11 +38761,11 @@ var init_ExposedFunction = __esm(() => {
|
|
|
37916
38761
|
try {
|
|
37917
38762
|
const [script] = await Promise.all([
|
|
37918
38763
|
frame.browsingContext.addPreloadScript(functionDeclaration, {
|
|
37919
|
-
arguments: [
|
|
38764
|
+
arguments: [channel2],
|
|
37920
38765
|
sandbox: realm.sandbox
|
|
37921
38766
|
}),
|
|
37922
38767
|
realm.realm.callFunction(functionDeclaration, false, {
|
|
37923
|
-
arguments: [
|
|
38768
|
+
arguments: [channel2]
|
|
37924
38769
|
})
|
|
37925
38770
|
]);
|
|
37926
38771
|
this.#scripts.push([frame, script]);
|
|
@@ -40383,22 +41228,22 @@ var init_Page3 = __esm(() => {
|
|
|
40383
41228
|
async setUserAgent(userAgentOrOptions, userAgentMetadata) {
|
|
40384
41229
|
let userAgent;
|
|
40385
41230
|
let clientHints;
|
|
40386
|
-
let
|
|
41231
|
+
let platform2;
|
|
40387
41232
|
if (typeof userAgentOrOptions === "string") {
|
|
40388
41233
|
userAgent = userAgentOrOptions;
|
|
40389
41234
|
clientHints = userAgentMetadata;
|
|
40390
41235
|
} else {
|
|
40391
41236
|
userAgent = userAgentOrOptions.userAgent ?? null;
|
|
40392
41237
|
clientHints = userAgentOrOptions.userAgentMetadata;
|
|
40393
|
-
|
|
41238
|
+
platform2 = userAgentOrOptions.platform === "" ? undefined : userAgentOrOptions.platform;
|
|
40394
41239
|
}
|
|
40395
41240
|
if (userAgent === "") {
|
|
40396
41241
|
userAgent = null;
|
|
40397
41242
|
}
|
|
40398
41243
|
await this.#frame.browsingContext.setUserAgent(userAgent);
|
|
40399
|
-
if (
|
|
41244
|
+
if (platform2 && platform2 !== "") {
|
|
40400
41245
|
clientHints = clientHints ?? {};
|
|
40401
|
-
clientHints.platform =
|
|
41246
|
+
clientHints.platform = platform2;
|
|
40402
41247
|
}
|
|
40403
41248
|
await this.#frame.browsingContext.setClientHintsOverride(clientHints ?? null);
|
|
40404
41249
|
}
|
|
@@ -48364,15 +49209,15 @@ var require_proxy_from_env = __commonJS((exports) => {
|
|
|
48364
49209
|
function getProxyForUrl(url) {
|
|
48365
49210
|
var parsedUrl = typeof url === "string" ? parseUrl(url) : url || {};
|
|
48366
49211
|
var proto = parsedUrl.protocol;
|
|
48367
|
-
var
|
|
49212
|
+
var hostname2 = parsedUrl.host;
|
|
48368
49213
|
var port = parsedUrl.port;
|
|
48369
|
-
if (typeof
|
|
49214
|
+
if (typeof hostname2 !== "string" || !hostname2 || typeof proto !== "string") {
|
|
48370
49215
|
return "";
|
|
48371
49216
|
}
|
|
48372
49217
|
proto = proto.split(":", 1)[0];
|
|
48373
|
-
|
|
49218
|
+
hostname2 = hostname2.replace(/:\d*$/, "");
|
|
48374
49219
|
port = parseInt(port) || DEFAULT_PORTS[proto] || 0;
|
|
48375
|
-
if (!shouldProxy(
|
|
49220
|
+
if (!shouldProxy(hostname2, port)) {
|
|
48376
49221
|
return "";
|
|
48377
49222
|
}
|
|
48378
49223
|
var proxy = getEnv("npm_config_" + proto + "_proxy") || getEnv(proto + "_proxy") || getEnv("npm_config_proxy") || getEnv("all_proxy");
|
|
@@ -48381,7 +49226,7 @@ var require_proxy_from_env = __commonJS((exports) => {
|
|
|
48381
49226
|
}
|
|
48382
49227
|
return proxy;
|
|
48383
49228
|
}
|
|
48384
|
-
function shouldProxy(
|
|
49229
|
+
function shouldProxy(hostname2, port) {
|
|
48385
49230
|
var NO_PROXY = (getEnv("npm_config_no_proxy") || getEnv("no_proxy")).toLowerCase();
|
|
48386
49231
|
if (!NO_PROXY) {
|
|
48387
49232
|
return true;
|
|
@@ -48400,12 +49245,12 @@ var require_proxy_from_env = __commonJS((exports) => {
|
|
|
48400
49245
|
return true;
|
|
48401
49246
|
}
|
|
48402
49247
|
if (!/^[.*]/.test(parsedProxyHostname)) {
|
|
48403
|
-
return
|
|
49248
|
+
return hostname2 !== parsedProxyHostname;
|
|
48404
49249
|
}
|
|
48405
49250
|
if (parsedProxyHostname.charAt(0) === "*") {
|
|
48406
49251
|
parsedProxyHostname = parsedProxyHostname.slice(1);
|
|
48407
49252
|
}
|
|
48408
|
-
return !stringEndsWith.call(
|
|
49253
|
+
return !stringEndsWith.call(hostname2, parsedProxyHostname);
|
|
48409
49254
|
});
|
|
48410
49255
|
}
|
|
48411
49256
|
function getEnv(key) {
|
|
@@ -48483,8 +49328,8 @@ var require_dist2 = __commonJS((exports) => {
|
|
|
48483
49328
|
setRequestProps(req, opts) {
|
|
48484
49329
|
const { proxy } = this;
|
|
48485
49330
|
const protocol = opts.secureEndpoint ? "https:" : "http:";
|
|
48486
|
-
const
|
|
48487
|
-
const base = `${protocol}//${
|
|
49331
|
+
const hostname2 = req.getHeader("host") || "localhost";
|
|
49332
|
+
const base = `${protocol}//${hostname2}`;
|
|
48488
49333
|
const url = new url_1.URL(req.path, base);
|
|
48489
49334
|
if (opts.port !== 80) {
|
|
48490
49335
|
url.port = String(opts.port);
|
|
@@ -54667,7 +55512,7 @@ var require_util2 = __commonJS((exports) => {
|
|
|
54667
55512
|
return path;
|
|
54668
55513
|
}
|
|
54669
55514
|
exports.normalize = normalize;
|
|
54670
|
-
function
|
|
55515
|
+
function join21(aRoot, aPath) {
|
|
54671
55516
|
if (aRoot === "") {
|
|
54672
55517
|
aRoot = ".";
|
|
54673
55518
|
}
|
|
@@ -54699,7 +55544,7 @@ var require_util2 = __commonJS((exports) => {
|
|
|
54699
55544
|
}
|
|
54700
55545
|
return joined;
|
|
54701
55546
|
}
|
|
54702
|
-
exports.join =
|
|
55547
|
+
exports.join = join21;
|
|
54703
55548
|
exports.isAbsolute = function(aPath) {
|
|
54704
55549
|
return aPath.charAt(0) === "/" || urlRegexp.test(aPath);
|
|
54705
55550
|
};
|
|
@@ -54872,7 +55717,7 @@ var require_util2 = __commonJS((exports) => {
|
|
|
54872
55717
|
parsed.path = parsed.path.substring(0, index + 1);
|
|
54873
55718
|
}
|
|
54874
55719
|
}
|
|
54875
|
-
sourceURL =
|
|
55720
|
+
sourceURL = join21(urlGenerate(parsed), sourceURL);
|
|
54876
55721
|
}
|
|
54877
55722
|
return normalize(sourceURL);
|
|
54878
55723
|
}
|
|
@@ -56604,7 +57449,7 @@ var require_escodegen = __commonJS((exports) => {
|
|
|
56604
57449
|
function noEmptySpace() {
|
|
56605
57450
|
return space ? space : " ";
|
|
56606
57451
|
}
|
|
56607
|
-
function
|
|
57452
|
+
function join21(left, right) {
|
|
56608
57453
|
var leftSource, rightSource, leftCharCode, rightCharCode;
|
|
56609
57454
|
leftSource = toSourceNodeWhenNeeded(left).toString();
|
|
56610
57455
|
if (leftSource.length === 0) {
|
|
@@ -56945,8 +57790,8 @@ var require_escodegen = __commonJS((exports) => {
|
|
|
56945
57790
|
} else {
|
|
56946
57791
|
result.push(that.generateExpression(stmt.left, Precedence.Call, E_TTT));
|
|
56947
57792
|
}
|
|
56948
|
-
result =
|
|
56949
|
-
result = [
|
|
57793
|
+
result = join21(result, operator);
|
|
57794
|
+
result = [join21(result, that.generateExpression(stmt.right, Precedence.Assignment, E_TTT)), ")"];
|
|
56950
57795
|
});
|
|
56951
57796
|
result.push(this.maybeBlock(stmt.body, flags));
|
|
56952
57797
|
return result;
|
|
@@ -57084,11 +57929,11 @@ var require_escodegen = __commonJS((exports) => {
|
|
|
57084
57929
|
var result, fragment;
|
|
57085
57930
|
result = ["class"];
|
|
57086
57931
|
if (stmt.id) {
|
|
57087
|
-
result =
|
|
57932
|
+
result = join21(result, this.generateExpression(stmt.id, Precedence.Sequence, E_TTT));
|
|
57088
57933
|
}
|
|
57089
57934
|
if (stmt.superClass) {
|
|
57090
|
-
fragment =
|
|
57091
|
-
result =
|
|
57935
|
+
fragment = join21("extends", this.generateExpression(stmt.superClass, Precedence.Unary, E_TTT));
|
|
57936
|
+
result = join21(result, fragment);
|
|
57092
57937
|
}
|
|
57093
57938
|
result.push(space);
|
|
57094
57939
|
result.push(this.generateStatement(stmt.body, S_TFFT));
|
|
@@ -57101,9 +57946,9 @@ var require_escodegen = __commonJS((exports) => {
|
|
|
57101
57946
|
return escapeDirective(stmt.directive) + this.semicolon(flags);
|
|
57102
57947
|
},
|
|
57103
57948
|
DoWhileStatement: function(stmt, flags) {
|
|
57104
|
-
var result =
|
|
57949
|
+
var result = join21("do", this.maybeBlock(stmt.body, S_TFFF));
|
|
57105
57950
|
result = this.maybeBlockSuffix(stmt.body, result);
|
|
57106
|
-
return
|
|
57951
|
+
return join21(result, [
|
|
57107
57952
|
"while" + space + "(",
|
|
57108
57953
|
this.generateExpression(stmt.test, Precedence.Sequence, E_TTT),
|
|
57109
57954
|
")" + this.semicolon(flags)
|
|
@@ -57139,11 +57984,11 @@ var require_escodegen = __commonJS((exports) => {
|
|
|
57139
57984
|
ExportDefaultDeclaration: function(stmt, flags) {
|
|
57140
57985
|
var result = ["export"], bodyFlags;
|
|
57141
57986
|
bodyFlags = flags & F_SEMICOLON_OPT ? S_TFFT : S_TFFF;
|
|
57142
|
-
result =
|
|
57987
|
+
result = join21(result, "default");
|
|
57143
57988
|
if (isStatement(stmt.declaration)) {
|
|
57144
|
-
result =
|
|
57989
|
+
result = join21(result, this.generateStatement(stmt.declaration, bodyFlags));
|
|
57145
57990
|
} else {
|
|
57146
|
-
result =
|
|
57991
|
+
result = join21(result, this.generateExpression(stmt.declaration, Precedence.Assignment, E_TTT) + this.semicolon(flags));
|
|
57147
57992
|
}
|
|
57148
57993
|
return result;
|
|
57149
57994
|
},
|
|
@@ -57151,15 +57996,15 @@ var require_escodegen = __commonJS((exports) => {
|
|
|
57151
57996
|
var result = ["export"], bodyFlags, that = this;
|
|
57152
57997
|
bodyFlags = flags & F_SEMICOLON_OPT ? S_TFFT : S_TFFF;
|
|
57153
57998
|
if (stmt.declaration) {
|
|
57154
|
-
return
|
|
57999
|
+
return join21(result, this.generateStatement(stmt.declaration, bodyFlags));
|
|
57155
58000
|
}
|
|
57156
58001
|
if (stmt.specifiers) {
|
|
57157
58002
|
if (stmt.specifiers.length === 0) {
|
|
57158
|
-
result =
|
|
58003
|
+
result = join21(result, "{" + space + "}");
|
|
57159
58004
|
} else if (stmt.specifiers[0].type === Syntax.ExportBatchSpecifier) {
|
|
57160
|
-
result =
|
|
58005
|
+
result = join21(result, this.generateExpression(stmt.specifiers[0], Precedence.Sequence, E_TTT));
|
|
57161
58006
|
} else {
|
|
57162
|
-
result =
|
|
58007
|
+
result = join21(result, "{");
|
|
57163
58008
|
withIndent(function(indent2) {
|
|
57164
58009
|
var i, iz;
|
|
57165
58010
|
result.push(newline);
|
|
@@ -57177,7 +58022,7 @@ var require_escodegen = __commonJS((exports) => {
|
|
|
57177
58022
|
result.push(base + "}");
|
|
57178
58023
|
}
|
|
57179
58024
|
if (stmt.source) {
|
|
57180
|
-
result =
|
|
58025
|
+
result = join21(result, [
|
|
57181
58026
|
"from" + space,
|
|
57182
58027
|
this.generateExpression(stmt.source, Precedence.Sequence, E_TTT),
|
|
57183
58028
|
this.semicolon(flags)
|
|
@@ -57261,7 +58106,7 @@ var require_escodegen = __commonJS((exports) => {
|
|
|
57261
58106
|
];
|
|
57262
58107
|
cursor = 0;
|
|
57263
58108
|
if (stmt.specifiers[cursor].type === Syntax.ImportDefaultSpecifier) {
|
|
57264
|
-
result =
|
|
58109
|
+
result = join21(result, [
|
|
57265
58110
|
this.generateExpression(stmt.specifiers[cursor], Precedence.Sequence, E_TTT)
|
|
57266
58111
|
]);
|
|
57267
58112
|
++cursor;
|
|
@@ -57271,7 +58116,7 @@ var require_escodegen = __commonJS((exports) => {
|
|
|
57271
58116
|
result.push(",");
|
|
57272
58117
|
}
|
|
57273
58118
|
if (stmt.specifiers[cursor].type === Syntax.ImportNamespaceSpecifier) {
|
|
57274
|
-
result =
|
|
58119
|
+
result = join21(result, [
|
|
57275
58120
|
space,
|
|
57276
58121
|
this.generateExpression(stmt.specifiers[cursor], Precedence.Sequence, E_TTT)
|
|
57277
58122
|
]);
|
|
@@ -57300,7 +58145,7 @@ var require_escodegen = __commonJS((exports) => {
|
|
|
57300
58145
|
}
|
|
57301
58146
|
}
|
|
57302
58147
|
}
|
|
57303
|
-
result =
|
|
58148
|
+
result = join21(result, [
|
|
57304
58149
|
"from" + space,
|
|
57305
58150
|
this.generateExpression(stmt.source, Precedence.Sequence, E_TTT),
|
|
57306
58151
|
this.semicolon(flags)
|
|
@@ -57354,7 +58199,7 @@ var require_escodegen = __commonJS((exports) => {
|
|
|
57354
58199
|
return result;
|
|
57355
58200
|
},
|
|
57356
58201
|
ThrowStatement: function(stmt, flags) {
|
|
57357
|
-
return [
|
|
58202
|
+
return [join21("throw", this.generateExpression(stmt.argument, Precedence.Sequence, E_TTT)), this.semicolon(flags)];
|
|
57358
58203
|
},
|
|
57359
58204
|
TryStatement: function(stmt, flags) {
|
|
57360
58205
|
var result, i, iz, guardedHandlers;
|
|
@@ -57362,7 +58207,7 @@ var require_escodegen = __commonJS((exports) => {
|
|
|
57362
58207
|
result = this.maybeBlockSuffix(stmt.block, result);
|
|
57363
58208
|
if (stmt.handlers) {
|
|
57364
58209
|
for (i = 0, iz = stmt.handlers.length;i < iz; ++i) {
|
|
57365
|
-
result =
|
|
58210
|
+
result = join21(result, this.generateStatement(stmt.handlers[i], S_TFFF));
|
|
57366
58211
|
if (stmt.finalizer || i + 1 !== iz) {
|
|
57367
58212
|
result = this.maybeBlockSuffix(stmt.handlers[i].body, result);
|
|
57368
58213
|
}
|
|
@@ -57370,7 +58215,7 @@ var require_escodegen = __commonJS((exports) => {
|
|
|
57370
58215
|
} else {
|
|
57371
58216
|
guardedHandlers = stmt.guardedHandlers || [];
|
|
57372
58217
|
for (i = 0, iz = guardedHandlers.length;i < iz; ++i) {
|
|
57373
|
-
result =
|
|
58218
|
+
result = join21(result, this.generateStatement(guardedHandlers[i], S_TFFF));
|
|
57374
58219
|
if (stmt.finalizer || i + 1 !== iz) {
|
|
57375
58220
|
result = this.maybeBlockSuffix(guardedHandlers[i].body, result);
|
|
57376
58221
|
}
|
|
@@ -57378,13 +58223,13 @@ var require_escodegen = __commonJS((exports) => {
|
|
|
57378
58223
|
if (stmt.handler) {
|
|
57379
58224
|
if (Array.isArray(stmt.handler)) {
|
|
57380
58225
|
for (i = 0, iz = stmt.handler.length;i < iz; ++i) {
|
|
57381
|
-
result =
|
|
58226
|
+
result = join21(result, this.generateStatement(stmt.handler[i], S_TFFF));
|
|
57382
58227
|
if (stmt.finalizer || i + 1 !== iz) {
|
|
57383
58228
|
result = this.maybeBlockSuffix(stmt.handler[i].body, result);
|
|
57384
58229
|
}
|
|
57385
58230
|
}
|
|
57386
58231
|
} else {
|
|
57387
|
-
result =
|
|
58232
|
+
result = join21(result, this.generateStatement(stmt.handler, S_TFFF));
|
|
57388
58233
|
if (stmt.finalizer) {
|
|
57389
58234
|
result = this.maybeBlockSuffix(stmt.handler.body, result);
|
|
57390
58235
|
}
|
|
@@ -57392,7 +58237,7 @@ var require_escodegen = __commonJS((exports) => {
|
|
|
57392
58237
|
}
|
|
57393
58238
|
}
|
|
57394
58239
|
if (stmt.finalizer) {
|
|
57395
|
-
result =
|
|
58240
|
+
result = join21(result, ["finally", this.maybeBlock(stmt.finalizer, S_TFFF)]);
|
|
57396
58241
|
}
|
|
57397
58242
|
return result;
|
|
57398
58243
|
},
|
|
@@ -57426,7 +58271,7 @@ var require_escodegen = __commonJS((exports) => {
|
|
|
57426
58271
|
withIndent(function() {
|
|
57427
58272
|
if (stmt.test) {
|
|
57428
58273
|
result = [
|
|
57429
|
-
|
|
58274
|
+
join21("case", that.generateExpression(stmt.test, Precedence.Sequence, E_TTT)),
|
|
57430
58275
|
":"
|
|
57431
58276
|
];
|
|
57432
58277
|
} else {
|
|
@@ -57474,9 +58319,9 @@ var require_escodegen = __commonJS((exports) => {
|
|
|
57474
58319
|
result.push(this.maybeBlock(stmt.consequent, S_TFFF));
|
|
57475
58320
|
result = this.maybeBlockSuffix(stmt.consequent, result);
|
|
57476
58321
|
if (stmt.alternate.type === Syntax.IfStatement) {
|
|
57477
|
-
result =
|
|
58322
|
+
result = join21(result, ["else ", this.generateStatement(stmt.alternate, bodyFlags)]);
|
|
57478
58323
|
} else {
|
|
57479
|
-
result =
|
|
58324
|
+
result = join21(result, join21("else", this.maybeBlock(stmt.alternate, bodyFlags)));
|
|
57480
58325
|
}
|
|
57481
58326
|
} else {
|
|
57482
58327
|
result.push(this.maybeBlock(stmt.consequent, bodyFlags));
|
|
@@ -57578,7 +58423,7 @@ var require_escodegen = __commonJS((exports) => {
|
|
|
57578
58423
|
},
|
|
57579
58424
|
ReturnStatement: function(stmt, flags) {
|
|
57580
58425
|
if (stmt.argument) {
|
|
57581
|
-
return [
|
|
58426
|
+
return [join21("return", this.generateExpression(stmt.argument, Precedence.Sequence, E_TTT)), this.semicolon(flags)];
|
|
57582
58427
|
}
|
|
57583
58428
|
return ["return" + this.semicolon(flags)];
|
|
57584
58429
|
},
|
|
@@ -57660,14 +58505,14 @@ var require_escodegen = __commonJS((exports) => {
|
|
|
57660
58505
|
if (leftSource.charCodeAt(leftSource.length - 1) === 47 && esutils.code.isIdentifierPartES5(expr.operator.charCodeAt(0))) {
|
|
57661
58506
|
result = [fragment, noEmptySpace(), expr.operator];
|
|
57662
58507
|
} else {
|
|
57663
|
-
result =
|
|
58508
|
+
result = join21(fragment, expr.operator);
|
|
57664
58509
|
}
|
|
57665
58510
|
fragment = this.generateExpression(expr.right, rightPrecedence, flags);
|
|
57666
58511
|
if (expr.operator === "/" && fragment.toString().charAt(0) === "/" || expr.operator.slice(-1) === "<" && fragment.toString().slice(0, 3) === "!--") {
|
|
57667
58512
|
result.push(noEmptySpace());
|
|
57668
58513
|
result.push(fragment);
|
|
57669
58514
|
} else {
|
|
57670
|
-
result =
|
|
58515
|
+
result = join21(result, fragment);
|
|
57671
58516
|
}
|
|
57672
58517
|
if (expr.operator === "in" && !(flags & F_ALLOW_IN)) {
|
|
57673
58518
|
return ["(", result, ")"];
|
|
@@ -57707,7 +58552,7 @@ var require_escodegen = __commonJS((exports) => {
|
|
|
57707
58552
|
var result, length, i, iz, itemFlags;
|
|
57708
58553
|
length = expr["arguments"].length;
|
|
57709
58554
|
itemFlags = flags & F_ALLOW_UNPARATH_NEW && !parentheses && length === 0 ? E_TFT : E_TFF;
|
|
57710
|
-
result =
|
|
58555
|
+
result = join21("new", this.generateExpression(expr.callee, Precedence.New, itemFlags));
|
|
57711
58556
|
if (!(flags & F_ALLOW_UNPARATH_NEW) || parentheses || length > 0) {
|
|
57712
58557
|
result.push("(");
|
|
57713
58558
|
for (i = 0, iz = length;i < iz; ++i) {
|
|
@@ -57754,11 +58599,11 @@ var require_escodegen = __commonJS((exports) => {
|
|
|
57754
58599
|
var result, fragment, rightCharCode, leftSource, leftCharCode;
|
|
57755
58600
|
fragment = this.generateExpression(expr.argument, Precedence.Unary, E_TTT);
|
|
57756
58601
|
if (space === "") {
|
|
57757
|
-
result =
|
|
58602
|
+
result = join21(expr.operator, fragment);
|
|
57758
58603
|
} else {
|
|
57759
58604
|
result = [expr.operator];
|
|
57760
58605
|
if (expr.operator.length > 2) {
|
|
57761
|
-
result =
|
|
58606
|
+
result = join21(result, fragment);
|
|
57762
58607
|
} else {
|
|
57763
58608
|
leftSource = toSourceNodeWhenNeeded(result).toString();
|
|
57764
58609
|
leftCharCode = leftSource.charCodeAt(leftSource.length - 1);
|
|
@@ -57781,12 +58626,12 @@ var require_escodegen = __commonJS((exports) => {
|
|
|
57781
58626
|
result = "yield";
|
|
57782
58627
|
}
|
|
57783
58628
|
if (expr.argument) {
|
|
57784
|
-
result =
|
|
58629
|
+
result = join21(result, this.generateExpression(expr.argument, Precedence.Yield, E_TTT));
|
|
57785
58630
|
}
|
|
57786
58631
|
return parenthesize(result, Precedence.Yield, precedence);
|
|
57787
58632
|
},
|
|
57788
58633
|
AwaitExpression: function(expr, precedence, flags) {
|
|
57789
|
-
var result =
|
|
58634
|
+
var result = join21(expr.all ? "await*" : "await", this.generateExpression(expr.argument, Precedence.Await, E_TTT));
|
|
57790
58635
|
return parenthesize(result, Precedence.Await, precedence);
|
|
57791
58636
|
},
|
|
57792
58637
|
UpdateExpression: function(expr, precedence, flags) {
|
|
@@ -57858,11 +58703,11 @@ var require_escodegen = __commonJS((exports) => {
|
|
|
57858
58703
|
var result, fragment;
|
|
57859
58704
|
result = ["class"];
|
|
57860
58705
|
if (expr.id) {
|
|
57861
|
-
result =
|
|
58706
|
+
result = join21(result, this.generateExpression(expr.id, Precedence.Sequence, E_TTT));
|
|
57862
58707
|
}
|
|
57863
58708
|
if (expr.superClass) {
|
|
57864
|
-
fragment =
|
|
57865
|
-
result =
|
|
58709
|
+
fragment = join21("extends", this.generateExpression(expr.superClass, Precedence.Unary, E_TTT));
|
|
58710
|
+
result = join21(result, fragment);
|
|
57866
58711
|
}
|
|
57867
58712
|
result.push(space);
|
|
57868
58713
|
result.push(this.generateStatement(expr.body, S_TFFT));
|
|
@@ -57877,7 +58722,7 @@ var require_escodegen = __commonJS((exports) => {
|
|
|
57877
58722
|
}
|
|
57878
58723
|
if (expr.kind === "get" || expr.kind === "set") {
|
|
57879
58724
|
fragment = [
|
|
57880
|
-
|
|
58725
|
+
join21(expr.kind, this.generatePropertyKey(expr.key, expr.computed)),
|
|
57881
58726
|
this.generateFunctionBody(expr.value)
|
|
57882
58727
|
];
|
|
57883
58728
|
} else {
|
|
@@ -57887,7 +58732,7 @@ var require_escodegen = __commonJS((exports) => {
|
|
|
57887
58732
|
this.generateFunctionBody(expr.value)
|
|
57888
58733
|
];
|
|
57889
58734
|
}
|
|
57890
|
-
return
|
|
58735
|
+
return join21(result, fragment);
|
|
57891
58736
|
},
|
|
57892
58737
|
Property: function(expr, precedence, flags) {
|
|
57893
58738
|
if (expr.kind === "get" || expr.kind === "set") {
|
|
@@ -58081,7 +58926,7 @@ var require_escodegen = __commonJS((exports) => {
|
|
|
58081
58926
|
for (i = 0, iz = expr.blocks.length;i < iz; ++i) {
|
|
58082
58927
|
fragment = that.generateExpression(expr.blocks[i], Precedence.Sequence, E_TTT);
|
|
58083
58928
|
if (i > 0 || extra.moz.comprehensionExpressionStartsWithAssignment) {
|
|
58084
|
-
result =
|
|
58929
|
+
result = join21(result, fragment);
|
|
58085
58930
|
} else {
|
|
58086
58931
|
result.push(fragment);
|
|
58087
58932
|
}
|
|
@@ -58089,13 +58934,13 @@ var require_escodegen = __commonJS((exports) => {
|
|
|
58089
58934
|
});
|
|
58090
58935
|
}
|
|
58091
58936
|
if (expr.filter) {
|
|
58092
|
-
result =
|
|
58937
|
+
result = join21(result, "if" + space);
|
|
58093
58938
|
fragment = this.generateExpression(expr.filter, Precedence.Sequence, E_TTT);
|
|
58094
|
-
result =
|
|
58939
|
+
result = join21(result, ["(", fragment, ")"]);
|
|
58095
58940
|
}
|
|
58096
58941
|
if (!extra.moz.comprehensionExpressionStartsWithAssignment) {
|
|
58097
58942
|
fragment = this.generateExpression(expr.body, Precedence.Assignment, E_TTT);
|
|
58098
|
-
result =
|
|
58943
|
+
result = join21(result, fragment);
|
|
58099
58944
|
}
|
|
58100
58945
|
result.push(expr.type === Syntax.GeneratorExpression ? ")" : "]");
|
|
58101
58946
|
return result;
|
|
@@ -58111,8 +58956,8 @@ var require_escodegen = __commonJS((exports) => {
|
|
|
58111
58956
|
} else {
|
|
58112
58957
|
fragment = this.generateExpression(expr.left, Precedence.Call, E_TTT);
|
|
58113
58958
|
}
|
|
58114
|
-
fragment =
|
|
58115
|
-
fragment =
|
|
58959
|
+
fragment = join21(fragment, expr.of ? "of" : "in");
|
|
58960
|
+
fragment = join21(fragment, this.generateExpression(expr.right, Precedence.Sequence, E_TTT));
|
|
58116
58961
|
return ["for" + space + "(", fragment, ")"];
|
|
58117
58962
|
},
|
|
58118
58963
|
SpreadElement: function(expr, precedence, flags) {
|
|
@@ -71820,8 +72665,8 @@ var init_httpUtil = __esm(() => {
|
|
|
71820
72665
|
import { execSync as execSync4 } from "node:child_process";
|
|
71821
72666
|
import os from "node:os";
|
|
71822
72667
|
import path from "node:path";
|
|
71823
|
-
function folder(
|
|
71824
|
-
switch (
|
|
72668
|
+
function folder(platform2) {
|
|
72669
|
+
switch (platform2) {
|
|
71825
72670
|
case BrowserPlatform.LINUX_ARM:
|
|
71826
72671
|
case BrowserPlatform.LINUX:
|
|
71827
72672
|
return "linux64";
|
|
@@ -71835,32 +72680,32 @@ function folder(platform) {
|
|
|
71835
72680
|
return "win64";
|
|
71836
72681
|
}
|
|
71837
72682
|
}
|
|
71838
|
-
function resolveDownloadUrl(
|
|
71839
|
-
return `${baseUrl}/${resolveDownloadPath(
|
|
72683
|
+
function resolveDownloadUrl(platform2, buildId, baseUrl = "https://storage.googleapis.com/chrome-for-testing-public") {
|
|
72684
|
+
return `${baseUrl}/${resolveDownloadPath(platform2, buildId).join("/")}`;
|
|
71840
72685
|
}
|
|
71841
|
-
function resolveDownloadPath(
|
|
71842
|
-
return [buildId, folder(
|
|
72686
|
+
function resolveDownloadPath(platform2, buildId) {
|
|
72687
|
+
return [buildId, folder(platform2), `chrome-${folder(platform2)}.zip`];
|
|
71843
72688
|
}
|
|
71844
|
-
function relativeExecutablePath(
|
|
71845
|
-
switch (
|
|
72689
|
+
function relativeExecutablePath(platform2, _buildId) {
|
|
72690
|
+
switch (platform2) {
|
|
71846
72691
|
case BrowserPlatform.MAC:
|
|
71847
72692
|
case BrowserPlatform.MAC_ARM:
|
|
71848
|
-
return path.join("chrome-" + folder(
|
|
72693
|
+
return path.join("chrome-" + folder(platform2), "Google Chrome for Testing.app", "Contents", "MacOS", "Google Chrome for Testing");
|
|
71849
72694
|
case BrowserPlatform.LINUX_ARM:
|
|
71850
72695
|
case BrowserPlatform.LINUX:
|
|
71851
72696
|
return path.join("chrome-linux64", "chrome");
|
|
71852
72697
|
case BrowserPlatform.WIN32:
|
|
71853
72698
|
case BrowserPlatform.WIN64:
|
|
71854
|
-
return path.join("chrome-" + folder(
|
|
72699
|
+
return path.join("chrome-" + folder(platform2), "chrome.exe");
|
|
71855
72700
|
}
|
|
71856
72701
|
}
|
|
71857
|
-
async function getLastKnownGoodReleaseForChannel(
|
|
72702
|
+
async function getLastKnownGoodReleaseForChannel(channel2) {
|
|
71858
72703
|
const data = await getJSON(new URL(`${baseVersionUrl}/last-known-good-versions.json`));
|
|
71859
|
-
for (const
|
|
71860
|
-
data.channels[
|
|
71861
|
-
delete data.channels[
|
|
72704
|
+
for (const channel3 of Object.keys(data.channels)) {
|
|
72705
|
+
data.channels[channel3.toLowerCase()] = data.channels[channel3];
|
|
72706
|
+
delete data.channels[channel3];
|
|
71862
72707
|
}
|
|
71863
|
-
return data.channels[
|
|
72708
|
+
return data.channels[channel2];
|
|
71864
72709
|
}
|
|
71865
72710
|
async function getLastKnownGoodReleaseForMilestone(milestone) {
|
|
71866
72711
|
const data = await getJSON(new URL(`${baseVersionUrl}/latest-versions-per-milestone.json`));
|
|
@@ -71870,24 +72715,24 @@ async function getLastKnownGoodReleaseForBuild(buildPrefix) {
|
|
|
71870
72715
|
const data = await getJSON(new URL(`${baseVersionUrl}/latest-patch-versions-per-build.json`));
|
|
71871
72716
|
return data.builds[buildPrefix];
|
|
71872
72717
|
}
|
|
71873
|
-
async function resolveBuildId(
|
|
71874
|
-
if (Object.values(ChromeReleaseChannel).includes(
|
|
71875
|
-
return (await getLastKnownGoodReleaseForChannel(
|
|
72718
|
+
async function resolveBuildId(channel2) {
|
|
72719
|
+
if (Object.values(ChromeReleaseChannel).includes(channel2)) {
|
|
72720
|
+
return (await getLastKnownGoodReleaseForChannel(channel2)).version;
|
|
71876
72721
|
}
|
|
71877
|
-
if (
|
|
71878
|
-
return (await getLastKnownGoodReleaseForMilestone(
|
|
72722
|
+
if (channel2.match(/^\d+$/)) {
|
|
72723
|
+
return (await getLastKnownGoodReleaseForMilestone(channel2))?.version;
|
|
71879
72724
|
}
|
|
71880
|
-
if (
|
|
71881
|
-
return (await getLastKnownGoodReleaseForBuild(
|
|
72725
|
+
if (channel2.match(/^\d+\.\d+\.\d+$/)) {
|
|
72726
|
+
return (await getLastKnownGoodReleaseForBuild(channel2))?.version;
|
|
71882
72727
|
}
|
|
71883
72728
|
return;
|
|
71884
72729
|
}
|
|
71885
|
-
function getChromeWindowsLocation(
|
|
72730
|
+
function getChromeWindowsLocation(channel2, locationsPrefixes) {
|
|
71886
72731
|
if (locationsPrefixes.size === 0) {
|
|
71887
72732
|
throw new Error("Non of the common Windows Env variables were set");
|
|
71888
72733
|
}
|
|
71889
72734
|
let suffix;
|
|
71890
|
-
switch (
|
|
72735
|
+
switch (channel2) {
|
|
71891
72736
|
case ChromeReleaseChannel.STABLE:
|
|
71892
72737
|
suffix = "Google\\Chrome\\Application\\chrome.exe";
|
|
71893
72738
|
break;
|
|
@@ -71917,7 +72762,7 @@ function getWslVariable(variable) {
|
|
|
71917
72762
|
} catch {}
|
|
71918
72763
|
return;
|
|
71919
72764
|
}
|
|
71920
|
-
function getWslLocation(
|
|
72765
|
+
function getWslLocation(channel2) {
|
|
71921
72766
|
const wslVersion = execSync4("wslinfo --version", {
|
|
71922
72767
|
stdio: ["ignore", "pipe", "ignore"],
|
|
71923
72768
|
encoding: "utf-8"
|
|
@@ -71932,14 +72777,14 @@ function getWslLocation(channel) {
|
|
|
71932
72777
|
wslPrefixes.add(wslPrefix);
|
|
71933
72778
|
}
|
|
71934
72779
|
}
|
|
71935
|
-
const windowsPath = getChromeWindowsLocation(
|
|
72780
|
+
const windowsPath = getChromeWindowsLocation(channel2, wslPrefixes);
|
|
71936
72781
|
return windowsPath.map((path2) => {
|
|
71937
72782
|
return execSync4(`wslpath "${path2}"`).toString().trim();
|
|
71938
72783
|
});
|
|
71939
72784
|
}
|
|
71940
|
-
function getChromeLinuxOrWslLocation(
|
|
72785
|
+
function getChromeLinuxOrWslLocation(channel2) {
|
|
71941
72786
|
const locations = [];
|
|
71942
|
-
switch (
|
|
72787
|
+
switch (channel2) {
|
|
71943
72788
|
case ChromeReleaseChannel.STABLE:
|
|
71944
72789
|
locations.push("/opt/google/chrome/chrome");
|
|
71945
72790
|
break;
|
|
@@ -71954,15 +72799,15 @@ function getChromeLinuxOrWslLocation(channel) {
|
|
|
71954
72799
|
break;
|
|
71955
72800
|
}
|
|
71956
72801
|
try {
|
|
71957
|
-
const wslPath = getWslLocation(
|
|
72802
|
+
const wslPath = getWslLocation(channel2);
|
|
71958
72803
|
if (wslPath) {
|
|
71959
72804
|
locations.push(...wslPath);
|
|
71960
72805
|
}
|
|
71961
72806
|
} catch {}
|
|
71962
72807
|
return locations;
|
|
71963
72808
|
}
|
|
71964
|
-
function resolveSystemExecutablePaths(
|
|
71965
|
-
switch (
|
|
72809
|
+
function resolveSystemExecutablePaths(platform2, channel2) {
|
|
72810
|
+
switch (platform2) {
|
|
71966
72811
|
case BrowserPlatform.WIN64:
|
|
71967
72812
|
case BrowserPlatform.WIN32:
|
|
71968
72813
|
const prefixLocation = new Set(WINDOWS_ENV_PARAM_NAMES.map((name) => {
|
|
@@ -71974,10 +72819,10 @@ function resolveSystemExecutablePaths(platform, channel) {
|
|
|
71974
72819
|
prefixLocation.add("C:\\Program Files (x86)");
|
|
71975
72820
|
prefixLocation.add("D:\\Program Files");
|
|
71976
72821
|
prefixLocation.add("D:\\Program Files (x86)");
|
|
71977
|
-
return getChromeWindowsLocation(
|
|
72822
|
+
return getChromeWindowsLocation(channel2, prefixLocation);
|
|
71978
72823
|
case BrowserPlatform.MAC_ARM:
|
|
71979
72824
|
case BrowserPlatform.MAC:
|
|
71980
|
-
switch (
|
|
72825
|
+
switch (channel2) {
|
|
71981
72826
|
case ChromeReleaseChannel.STABLE:
|
|
71982
72827
|
return [
|
|
71983
72828
|
"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome"
|
|
@@ -71997,14 +72842,14 @@ function resolveSystemExecutablePaths(platform, channel) {
|
|
|
71997
72842
|
}
|
|
71998
72843
|
case BrowserPlatform.LINUX_ARM:
|
|
71999
72844
|
case BrowserPlatform.LINUX:
|
|
72000
|
-
return getChromeLinuxOrWslLocation(
|
|
72845
|
+
return getChromeLinuxOrWslLocation(channel2);
|
|
72001
72846
|
}
|
|
72002
72847
|
}
|
|
72003
|
-
function resolveDefaultUserDataDir(
|
|
72004
|
-
switch (
|
|
72848
|
+
function resolveDefaultUserDataDir(platform2, channel2) {
|
|
72849
|
+
switch (platform2) {
|
|
72005
72850
|
case BrowserPlatform.WIN64:
|
|
72006
72851
|
case BrowserPlatform.WIN32:
|
|
72007
|
-
switch (
|
|
72852
|
+
switch (channel2) {
|
|
72008
72853
|
case ChromeReleaseChannel.STABLE:
|
|
72009
72854
|
return path.join(getLocalAppDataWin(), "Google", "Chrome", "User Data");
|
|
72010
72855
|
case ChromeReleaseChannel.BETA:
|
|
@@ -72016,7 +72861,7 @@ function resolveDefaultUserDataDir(platform, channel) {
|
|
|
72016
72861
|
}
|
|
72017
72862
|
case BrowserPlatform.MAC_ARM:
|
|
72018
72863
|
case BrowserPlatform.MAC:
|
|
72019
|
-
switch (
|
|
72864
|
+
switch (channel2) {
|
|
72020
72865
|
case ChromeReleaseChannel.STABLE:
|
|
72021
72866
|
return path.join(getBaseUserDataDirPathMac(), "Chrome");
|
|
72022
72867
|
case ChromeReleaseChannel.BETA:
|
|
@@ -72028,7 +72873,7 @@ function resolveDefaultUserDataDir(platform, channel) {
|
|
|
72028
72873
|
}
|
|
72029
72874
|
case BrowserPlatform.LINUX_ARM:
|
|
72030
72875
|
case BrowserPlatform.LINUX:
|
|
72031
|
-
switch (
|
|
72876
|
+
switch (channel2) {
|
|
72032
72877
|
case ChromeReleaseChannel.STABLE:
|
|
72033
72878
|
return path.join(getConfigHomeLinux(), "google-chrome");
|
|
72034
72879
|
case ChromeReleaseChannel.BETA:
|
|
@@ -72079,8 +72924,8 @@ var init_chrome = __esm(() => {
|
|
|
72079
72924
|
|
|
72080
72925
|
// node_modules/@puppeteer/browsers/lib/esm/browser-data/chrome-headless-shell.js
|
|
72081
72926
|
import path2 from "node:path";
|
|
72082
|
-
function folder2(
|
|
72083
|
-
switch (
|
|
72927
|
+
function folder2(platform2) {
|
|
72928
|
+
switch (platform2) {
|
|
72084
72929
|
case BrowserPlatform.LINUX_ARM:
|
|
72085
72930
|
case BrowserPlatform.LINUX:
|
|
72086
72931
|
return "linux64";
|
|
@@ -72094,27 +72939,27 @@ function folder2(platform) {
|
|
|
72094
72939
|
return "win64";
|
|
72095
72940
|
}
|
|
72096
72941
|
}
|
|
72097
|
-
function resolveDownloadUrl2(
|
|
72098
|
-
return `${baseUrl}/${resolveDownloadPath2(
|
|
72942
|
+
function resolveDownloadUrl2(platform2, buildId, baseUrl = "https://storage.googleapis.com/chrome-for-testing-public") {
|
|
72943
|
+
return `${baseUrl}/${resolveDownloadPath2(platform2, buildId).join("/")}`;
|
|
72099
72944
|
}
|
|
72100
|
-
function resolveDownloadPath2(
|
|
72945
|
+
function resolveDownloadPath2(platform2, buildId) {
|
|
72101
72946
|
return [
|
|
72102
72947
|
buildId,
|
|
72103
|
-
folder2(
|
|
72104
|
-
`chrome-headless-shell-${folder2(
|
|
72948
|
+
folder2(platform2),
|
|
72949
|
+
`chrome-headless-shell-${folder2(platform2)}.zip`
|
|
72105
72950
|
];
|
|
72106
72951
|
}
|
|
72107
|
-
function relativeExecutablePath2(
|
|
72108
|
-
switch (
|
|
72952
|
+
function relativeExecutablePath2(platform2, _buildId) {
|
|
72953
|
+
switch (platform2) {
|
|
72109
72954
|
case BrowserPlatform.MAC:
|
|
72110
72955
|
case BrowserPlatform.MAC_ARM:
|
|
72111
|
-
return path2.join("chrome-headless-shell-" + folder2(
|
|
72956
|
+
return path2.join("chrome-headless-shell-" + folder2(platform2), "chrome-headless-shell");
|
|
72112
72957
|
case BrowserPlatform.LINUX_ARM:
|
|
72113
72958
|
case BrowserPlatform.LINUX:
|
|
72114
72959
|
return path2.join("chrome-headless-shell-linux64", "chrome-headless-shell");
|
|
72115
72960
|
case BrowserPlatform.WIN32:
|
|
72116
72961
|
case BrowserPlatform.WIN64:
|
|
72117
|
-
return path2.join("chrome-headless-shell-" + folder2(
|
|
72962
|
+
return path2.join("chrome-headless-shell-" + folder2(platform2), "chrome-headless-shell.exe");
|
|
72118
72963
|
}
|
|
72119
72964
|
}
|
|
72120
72965
|
var init_chrome_headless_shell = __esm(() => {
|
|
@@ -72124,8 +72969,8 @@ var init_chrome_headless_shell = __esm(() => {
|
|
|
72124
72969
|
|
|
72125
72970
|
// node_modules/@puppeteer/browsers/lib/esm/browser-data/chromedriver.js
|
|
72126
72971
|
import path3 from "node:path";
|
|
72127
|
-
function folder3(
|
|
72128
|
-
switch (
|
|
72972
|
+
function folder3(platform2) {
|
|
72973
|
+
switch (platform2) {
|
|
72129
72974
|
case BrowserPlatform.LINUX_ARM:
|
|
72130
72975
|
case BrowserPlatform.LINUX:
|
|
72131
72976
|
return "linux64";
|
|
@@ -72139,23 +72984,23 @@ function folder3(platform) {
|
|
|
72139
72984
|
return "win64";
|
|
72140
72985
|
}
|
|
72141
72986
|
}
|
|
72142
|
-
function resolveDownloadUrl3(
|
|
72143
|
-
return `${baseUrl}/${resolveDownloadPath3(
|
|
72987
|
+
function resolveDownloadUrl3(platform2, buildId, baseUrl = "https://storage.googleapis.com/chrome-for-testing-public") {
|
|
72988
|
+
return `${baseUrl}/${resolveDownloadPath3(platform2, buildId).join("/")}`;
|
|
72144
72989
|
}
|
|
72145
|
-
function resolveDownloadPath3(
|
|
72146
|
-
return [buildId, folder3(
|
|
72990
|
+
function resolveDownloadPath3(platform2, buildId) {
|
|
72991
|
+
return [buildId, folder3(platform2), `chromedriver-${folder3(platform2)}.zip`];
|
|
72147
72992
|
}
|
|
72148
|
-
function relativeExecutablePath3(
|
|
72149
|
-
switch (
|
|
72993
|
+
function relativeExecutablePath3(platform2, _buildId) {
|
|
72994
|
+
switch (platform2) {
|
|
72150
72995
|
case BrowserPlatform.MAC:
|
|
72151
72996
|
case BrowserPlatform.MAC_ARM:
|
|
72152
|
-
return path3.join("chromedriver-" + folder3(
|
|
72997
|
+
return path3.join("chromedriver-" + folder3(platform2), "chromedriver");
|
|
72153
72998
|
case BrowserPlatform.LINUX_ARM:
|
|
72154
72999
|
case BrowserPlatform.LINUX:
|
|
72155
73000
|
return path3.join("chromedriver-linux64", "chromedriver");
|
|
72156
73001
|
case BrowserPlatform.WIN32:
|
|
72157
73002
|
case BrowserPlatform.WIN64:
|
|
72158
|
-
return path3.join("chromedriver-" + folder3(
|
|
73003
|
+
return path3.join("chromedriver-" + folder3(platform2), "chromedriver.exe");
|
|
72159
73004
|
}
|
|
72160
73005
|
}
|
|
72161
73006
|
var init_chromedriver = __esm(() => {
|
|
@@ -72165,8 +73010,8 @@ var init_chromedriver = __esm(() => {
|
|
|
72165
73010
|
|
|
72166
73011
|
// node_modules/@puppeteer/browsers/lib/esm/browser-data/chromium.js
|
|
72167
73012
|
import path4 from "node:path";
|
|
72168
|
-
function archive(
|
|
72169
|
-
switch (
|
|
73013
|
+
function archive(platform2, buildId) {
|
|
73014
|
+
switch (platform2) {
|
|
72170
73015
|
case BrowserPlatform.LINUX_ARM:
|
|
72171
73016
|
case BrowserPlatform.LINUX:
|
|
72172
73017
|
return "chrome-linux";
|
|
@@ -72178,8 +73023,8 @@ function archive(platform, buildId) {
|
|
|
72178
73023
|
return parseInt(buildId, 10) > 591479 ? "chrome-win" : "chrome-win32";
|
|
72179
73024
|
}
|
|
72180
73025
|
}
|
|
72181
|
-
function folder4(
|
|
72182
|
-
switch (
|
|
73026
|
+
function folder4(platform2) {
|
|
73027
|
+
switch (platform2) {
|
|
72183
73028
|
case BrowserPlatform.LINUX_ARM:
|
|
72184
73029
|
case BrowserPlatform.LINUX:
|
|
72185
73030
|
return "Linux_x64";
|
|
@@ -72193,14 +73038,14 @@ function folder4(platform) {
|
|
|
72193
73038
|
return "Win_x64";
|
|
72194
73039
|
}
|
|
72195
73040
|
}
|
|
72196
|
-
function resolveDownloadUrl4(
|
|
72197
|
-
return `${baseUrl}/${resolveDownloadPath4(
|
|
73041
|
+
function resolveDownloadUrl4(platform2, buildId, baseUrl = "https://storage.googleapis.com/chromium-browser-snapshots") {
|
|
73042
|
+
return `${baseUrl}/${resolveDownloadPath4(platform2, buildId).join("/")}`;
|
|
72198
73043
|
}
|
|
72199
|
-
function resolveDownloadPath4(
|
|
72200
|
-
return [folder4(
|
|
73044
|
+
function resolveDownloadPath4(platform2, buildId) {
|
|
73045
|
+
return [folder4(platform2), buildId, `${archive(platform2, buildId)}.zip`];
|
|
72201
73046
|
}
|
|
72202
|
-
function relativeExecutablePath4(
|
|
72203
|
-
switch (
|
|
73047
|
+
function relativeExecutablePath4(platform2, _buildId) {
|
|
73048
|
+
switch (platform2) {
|
|
72204
73049
|
case BrowserPlatform.MAC:
|
|
72205
73050
|
case BrowserPlatform.MAC_ARM:
|
|
72206
73051
|
return path4.join("chrome-mac", "Chromium.app", "Contents", "MacOS", "Chromium");
|
|
@@ -72212,8 +73057,8 @@ function relativeExecutablePath4(platform, _buildId) {
|
|
|
72212
73057
|
return path4.join("chrome-win", "chrome.exe");
|
|
72213
73058
|
}
|
|
72214
73059
|
}
|
|
72215
|
-
async function resolveBuildId2(
|
|
72216
|
-
return await getText(new URL(`https://storage.googleapis.com/chromium-browser-snapshots/${folder4(
|
|
73060
|
+
async function resolveBuildId2(platform2) {
|
|
73061
|
+
return await getText(new URL(`https://storage.googleapis.com/chromium-browser-snapshots/${folder4(platform2)}/LAST_CHANGE`));
|
|
72217
73062
|
}
|
|
72218
73063
|
function compareVersions2(a, b) {
|
|
72219
73064
|
return Number(a) - Number(b);
|
|
@@ -72230,8 +73075,8 @@ function getFormat(buildId) {
|
|
|
72230
73075
|
const majorVersion = Number(buildId.split(".").shift());
|
|
72231
73076
|
return majorVersion >= 135 ? "xz" : "bz2";
|
|
72232
73077
|
}
|
|
72233
|
-
function archiveNightly(
|
|
72234
|
-
switch (
|
|
73078
|
+
function archiveNightly(platform2, buildId) {
|
|
73079
|
+
switch (platform2) {
|
|
72235
73080
|
case BrowserPlatform.LINUX:
|
|
72236
73081
|
return `firefox-${buildId}.en-US.linux-x86_64.tar.${getFormat(buildId)}`;
|
|
72237
73082
|
case BrowserPlatform.LINUX_ARM:
|
|
@@ -72241,11 +73086,11 @@ function archiveNightly(platform, buildId) {
|
|
|
72241
73086
|
return `firefox-${buildId}.en-US.mac.dmg`;
|
|
72242
73087
|
case BrowserPlatform.WIN32:
|
|
72243
73088
|
case BrowserPlatform.WIN64:
|
|
72244
|
-
return `firefox-${buildId}.en-US.${
|
|
73089
|
+
return `firefox-${buildId}.en-US.${platform2}.zip`;
|
|
72245
73090
|
}
|
|
72246
73091
|
}
|
|
72247
|
-
function archive2(
|
|
72248
|
-
switch (
|
|
73092
|
+
function archive2(platform2, buildId) {
|
|
73093
|
+
switch (platform2) {
|
|
72249
73094
|
case BrowserPlatform.LINUX_ARM:
|
|
72250
73095
|
case BrowserPlatform.LINUX:
|
|
72251
73096
|
return `firefox-${buildId}.tar.${getFormat(buildId)}`;
|
|
@@ -72257,8 +73102,8 @@ function archive2(platform, buildId) {
|
|
|
72257
73102
|
return `Firefox Setup ${buildId}.exe`;
|
|
72258
73103
|
}
|
|
72259
73104
|
}
|
|
72260
|
-
function platformName(
|
|
72261
|
-
switch (
|
|
73105
|
+
function platformName(platform2) {
|
|
73106
|
+
switch (platform2) {
|
|
72262
73107
|
case BrowserPlatform.LINUX:
|
|
72263
73108
|
return `linux-x86_64`;
|
|
72264
73109
|
case BrowserPlatform.LINUX_ARM:
|
|
@@ -72268,7 +73113,7 @@ function platformName(platform) {
|
|
|
72268
73113
|
return `mac`;
|
|
72269
73114
|
case BrowserPlatform.WIN32:
|
|
72270
73115
|
case BrowserPlatform.WIN64:
|
|
72271
|
-
return
|
|
73116
|
+
return platform2;
|
|
72272
73117
|
}
|
|
72273
73118
|
}
|
|
72274
73119
|
function parseBuildId(buildId) {
|
|
@@ -72280,9 +73125,9 @@ function parseBuildId(buildId) {
|
|
|
72280
73125
|
}
|
|
72281
73126
|
return [FirefoxChannel.NIGHTLY, buildId];
|
|
72282
73127
|
}
|
|
72283
|
-
function resolveDownloadUrl5(
|
|
72284
|
-
const [
|
|
72285
|
-
switch (
|
|
73128
|
+
function resolveDownloadUrl5(platform2, buildId, baseUrl) {
|
|
73129
|
+
const [channel2] = parseBuildId(buildId);
|
|
73130
|
+
switch (channel2) {
|
|
72286
73131
|
case FirefoxChannel.NIGHTLY:
|
|
72287
73132
|
baseUrl ??= "https://archive.mozilla.org/pub/firefox/nightly/latest-mozilla-central";
|
|
72288
73133
|
break;
|
|
@@ -72295,30 +73140,30 @@ function resolveDownloadUrl5(platform, buildId, baseUrl) {
|
|
|
72295
73140
|
baseUrl ??= "https://archive.mozilla.org/pub/firefox/releases";
|
|
72296
73141
|
break;
|
|
72297
73142
|
}
|
|
72298
|
-
return `${baseUrl}/${resolveDownloadPath5(
|
|
73143
|
+
return `${baseUrl}/${resolveDownloadPath5(platform2, buildId).join("/")}`;
|
|
72299
73144
|
}
|
|
72300
|
-
function resolveDownloadPath5(
|
|
72301
|
-
const [
|
|
72302
|
-
switch (
|
|
73145
|
+
function resolveDownloadPath5(platform2, buildId) {
|
|
73146
|
+
const [channel2, resolvedBuildId] = parseBuildId(buildId);
|
|
73147
|
+
switch (channel2) {
|
|
72303
73148
|
case FirefoxChannel.NIGHTLY:
|
|
72304
|
-
return [archiveNightly(
|
|
73149
|
+
return [archiveNightly(platform2, resolvedBuildId)];
|
|
72305
73150
|
case FirefoxChannel.DEVEDITION:
|
|
72306
73151
|
case FirefoxChannel.BETA:
|
|
72307
73152
|
case FirefoxChannel.STABLE:
|
|
72308
73153
|
case FirefoxChannel.ESR:
|
|
72309
73154
|
return [
|
|
72310
73155
|
resolvedBuildId,
|
|
72311
|
-
platformName(
|
|
73156
|
+
platformName(platform2),
|
|
72312
73157
|
"en-US",
|
|
72313
|
-
archive2(
|
|
73158
|
+
archive2(platform2, resolvedBuildId)
|
|
72314
73159
|
];
|
|
72315
73160
|
}
|
|
72316
73161
|
}
|
|
72317
|
-
function relativeExecutablePath5(
|
|
72318
|
-
const [
|
|
72319
|
-
switch (
|
|
73162
|
+
function relativeExecutablePath5(platform2, buildId) {
|
|
73163
|
+
const [channel2] = parseBuildId(buildId);
|
|
73164
|
+
switch (channel2) {
|
|
72320
73165
|
case FirefoxChannel.NIGHTLY:
|
|
72321
|
-
switch (
|
|
73166
|
+
switch (platform2) {
|
|
72322
73167
|
case BrowserPlatform.MAC_ARM:
|
|
72323
73168
|
case BrowserPlatform.MAC:
|
|
72324
73169
|
return path5.join("Firefox Nightly.app", "Contents", "MacOS", "firefox");
|
|
@@ -72333,7 +73178,7 @@ function relativeExecutablePath5(platform, buildId) {
|
|
|
72333
73178
|
case FirefoxChannel.DEVEDITION:
|
|
72334
73179
|
case FirefoxChannel.ESR:
|
|
72335
73180
|
case FirefoxChannel.STABLE:
|
|
72336
|
-
switch (
|
|
73181
|
+
switch (platform2) {
|
|
72337
73182
|
case BrowserPlatform.MAC_ARM:
|
|
72338
73183
|
case BrowserPlatform.MAC:
|
|
72339
73184
|
return path5.join("Firefox.app", "Contents", "MacOS", "firefox");
|
|
@@ -72346,7 +73191,7 @@ function relativeExecutablePath5(platform, buildId) {
|
|
|
72346
73191
|
}
|
|
72347
73192
|
}
|
|
72348
73193
|
}
|
|
72349
|
-
async function resolveBuildId3(
|
|
73194
|
+
async function resolveBuildId3(channel2 = FirefoxChannel.NIGHTLY) {
|
|
72350
73195
|
const channelToVersionKey = {
|
|
72351
73196
|
[FirefoxChannel.ESR]: "FIREFOX_ESR",
|
|
72352
73197
|
[FirefoxChannel.STABLE]: "LATEST_FIREFOX_VERSION",
|
|
@@ -72355,11 +73200,11 @@ async function resolveBuildId3(channel = FirefoxChannel.NIGHTLY) {
|
|
|
72355
73200
|
[FirefoxChannel.NIGHTLY]: "FIREFOX_NIGHTLY"
|
|
72356
73201
|
};
|
|
72357
73202
|
const versions = await getJSON(new URL(`${baseVersionUrl2}/firefox_versions.json`));
|
|
72358
|
-
const version = versions[channelToVersionKey[
|
|
73203
|
+
const version = versions[channelToVersionKey[channel2]];
|
|
72359
73204
|
if (!version) {
|
|
72360
|
-
throw new Error(`Channel ${
|
|
73205
|
+
throw new Error(`Channel ${channel2} is not found.`);
|
|
72361
73206
|
}
|
|
72362
|
-
return
|
|
73207
|
+
return channel2 + "_" + version;
|
|
72363
73208
|
}
|
|
72364
73209
|
async function createProfile(options) {
|
|
72365
73210
|
if (!fs.existsSync(options.path)) {
|
|
@@ -72498,7 +73343,7 @@ var init_firefox = __esm(() => {
|
|
|
72498
73343
|
});
|
|
72499
73344
|
|
|
72500
73345
|
// node_modules/@puppeteer/browsers/lib/esm/browser-data/browser-data.js
|
|
72501
|
-
async function resolveBuildIdForBrowserTag(browser,
|
|
73346
|
+
async function resolveBuildIdForBrowserTag(browser, platform2, tag) {
|
|
72502
73347
|
switch (browser) {
|
|
72503
73348
|
case Browser6.FIREFOX:
|
|
72504
73349
|
switch (tag) {
|
|
@@ -72573,7 +73418,7 @@ async function resolveBuildIdForBrowserTag(browser, platform, tag) {
|
|
|
72573
73418
|
case Browser6.CHROMIUM:
|
|
72574
73419
|
switch (tag) {
|
|
72575
73420
|
case BrowserTag.LATEST:
|
|
72576
|
-
return await resolveBuildId2(
|
|
73421
|
+
return await resolveBuildId2(platform2);
|
|
72577
73422
|
case BrowserTag.NIGHTLY:
|
|
72578
73423
|
case BrowserTag.CANARY:
|
|
72579
73424
|
case BrowserTag.DEV:
|
|
@@ -72585,10 +73430,10 @@ async function resolveBuildIdForBrowserTag(browser, platform, tag) {
|
|
|
72585
73430
|
}
|
|
72586
73431
|
}
|
|
72587
73432
|
}
|
|
72588
|
-
async function resolveBuildId4(browser,
|
|
73433
|
+
async function resolveBuildId4(browser, platform2, tag) {
|
|
72589
73434
|
const browserTag = tag;
|
|
72590
73435
|
if (Object.values(BrowserTag).includes(browserTag)) {
|
|
72591
|
-
return await resolveBuildIdForBrowserTag(browser,
|
|
73436
|
+
return await resolveBuildIdForBrowserTag(browser, platform2, browserTag);
|
|
72592
73437
|
}
|
|
72593
73438
|
switch (browser) {
|
|
72594
73439
|
case Browser6.FIREFOX:
|
|
@@ -72624,7 +73469,7 @@ async function createProfile2(browser, opts) {
|
|
|
72624
73469
|
throw new Error(`Profile creation is not support for ${browser} yet`);
|
|
72625
73470
|
}
|
|
72626
73471
|
}
|
|
72627
|
-
function resolveDefaultUserDataDir2(browser,
|
|
73472
|
+
function resolveDefaultUserDataDir2(browser, platform2, channel2) {
|
|
72628
73473
|
switch (browser) {
|
|
72629
73474
|
case Browser6.CHROMEDRIVER:
|
|
72630
73475
|
case Browser6.CHROMEHEADLESSSHELL:
|
|
@@ -72632,10 +73477,10 @@ function resolveDefaultUserDataDir2(browser, platform, channel) {
|
|
|
72632
73477
|
case Browser6.CHROMIUM:
|
|
72633
73478
|
throw new Error(`Default user dir detection is not supported for ${browser} yet.`);
|
|
72634
73479
|
case Browser6.CHROME:
|
|
72635
|
-
return resolveDefaultUserDataDir(
|
|
73480
|
+
return resolveDefaultUserDataDir(platform2, channel2);
|
|
72636
73481
|
}
|
|
72637
73482
|
}
|
|
72638
|
-
function resolveSystemExecutablePaths2(browser,
|
|
73483
|
+
function resolveSystemExecutablePaths2(browser, platform2, channel2) {
|
|
72639
73484
|
switch (browser) {
|
|
72640
73485
|
case Browser6.CHROMEDRIVER:
|
|
72641
73486
|
case Browser6.CHROMEHEADLESSSHELL:
|
|
@@ -72643,7 +73488,7 @@ function resolveSystemExecutablePaths2(browser, platform, channel) {
|
|
|
72643
73488
|
case Browser6.CHROMIUM:
|
|
72644
73489
|
throw new Error(`System browser detection is not supported for ${browser} yet.`);
|
|
72645
73490
|
case Browser6.CHROME:
|
|
72646
|
-
return resolveSystemExecutablePaths(
|
|
73491
|
+
return resolveSystemExecutablePaths(platform2, channel2);
|
|
72647
73492
|
}
|
|
72648
73493
|
}
|
|
72649
73494
|
function getVersionComparator(browser) {
|
|
@@ -72690,9 +73535,9 @@ var init_browser_data = __esm(() => {
|
|
|
72690
73535
|
// node_modules/@puppeteer/browsers/lib/esm/detectPlatform.js
|
|
72691
73536
|
import os2 from "node:os";
|
|
72692
73537
|
function detectBrowserPlatform() {
|
|
72693
|
-
const
|
|
73538
|
+
const platform2 = os2.platform();
|
|
72694
73539
|
const arch = os2.arch();
|
|
72695
|
-
switch (
|
|
73540
|
+
switch (platform2) {
|
|
72696
73541
|
case "darwin":
|
|
72697
73542
|
return arch === "arm64" ? BrowserPlatform.MAC_ARM : BrowserPlatform.MAC;
|
|
72698
73543
|
case "linux":
|
|
@@ -72728,15 +73573,15 @@ class InstalledBrowser {
|
|
|
72728
73573
|
platform;
|
|
72729
73574
|
executablePath;
|
|
72730
73575
|
#cache;
|
|
72731
|
-
constructor(cache, browser, buildId,
|
|
73576
|
+
constructor(cache, browser, buildId, platform2) {
|
|
72732
73577
|
this.#cache = cache;
|
|
72733
73578
|
this.browser = browser;
|
|
72734
73579
|
this.buildId = buildId;
|
|
72735
|
-
this.platform =
|
|
73580
|
+
this.platform = platform2;
|
|
72736
73581
|
this.executablePath = cache.computeExecutablePath({
|
|
72737
73582
|
browser,
|
|
72738
73583
|
buildId,
|
|
72739
|
-
platform
|
|
73584
|
+
platform: platform2
|
|
72740
73585
|
});
|
|
72741
73586
|
}
|
|
72742
73587
|
get path() {
|
|
@@ -72780,17 +73625,17 @@ class Cache {
|
|
|
72780
73625
|
fs2.mkdirSync(path6.dirname(metatadaPath), { recursive: true });
|
|
72781
73626
|
fs2.writeFileSync(metatadaPath, JSON.stringify(metadata, null, 2));
|
|
72782
73627
|
}
|
|
72783
|
-
readExecutablePath(browser,
|
|
73628
|
+
readExecutablePath(browser, platform2, buildId) {
|
|
72784
73629
|
const metadata = this.readMetadata(browser);
|
|
72785
|
-
const key = `${
|
|
73630
|
+
const key = `${platform2}-${buildId}`;
|
|
72786
73631
|
return metadata.executablePaths?.[key] ?? null;
|
|
72787
73632
|
}
|
|
72788
|
-
writeExecutablePath(browser,
|
|
73633
|
+
writeExecutablePath(browser, platform2, buildId, executablePath) {
|
|
72789
73634
|
const metadata = this.readMetadata(browser);
|
|
72790
73635
|
if (!metadata.executablePaths) {
|
|
72791
73636
|
metadata.executablePaths = {};
|
|
72792
73637
|
}
|
|
72793
|
-
const key = `${
|
|
73638
|
+
const key = `${platform2}-${buildId}`;
|
|
72794
73639
|
metadata.executablePaths[key] = executablePath;
|
|
72795
73640
|
this.writeMetadata(browser, metadata);
|
|
72796
73641
|
}
|
|
@@ -72801,8 +73646,8 @@ class Cache {
|
|
|
72801
73646
|
}
|
|
72802
73647
|
return metadata.aliases[alias];
|
|
72803
73648
|
}
|
|
72804
|
-
installationDir(browser,
|
|
72805
|
-
return path6.join(this.browserRoot(browser), `${
|
|
73649
|
+
installationDir(browser, platform2, buildId) {
|
|
73650
|
+
return path6.join(this.browserRoot(browser), `${platform2}-${buildId}`);
|
|
72806
73651
|
}
|
|
72807
73652
|
clear() {
|
|
72808
73653
|
fs2.rmSync(this.#rootDir, {
|
|
@@ -72812,19 +73657,19 @@ class Cache {
|
|
|
72812
73657
|
retryDelay: 500
|
|
72813
73658
|
});
|
|
72814
73659
|
}
|
|
72815
|
-
uninstall(browser,
|
|
73660
|
+
uninstall(browser, platform2, buildId) {
|
|
72816
73661
|
const metadata = this.readMetadata(browser);
|
|
72817
73662
|
for (const alias of Object.keys(metadata.aliases)) {
|
|
72818
73663
|
if (metadata.aliases[alias] === buildId) {
|
|
72819
73664
|
delete metadata.aliases[alias];
|
|
72820
73665
|
}
|
|
72821
73666
|
}
|
|
72822
|
-
const key = `${
|
|
73667
|
+
const key = `${platform2}-${buildId}`;
|
|
72823
73668
|
if (metadata.executablePaths?.[key]) {
|
|
72824
73669
|
delete metadata.executablePaths[key];
|
|
72825
73670
|
this.writeMetadata(browser, metadata);
|
|
72826
73671
|
}
|
|
72827
|
-
fs2.rmSync(this.installationDir(browser,
|
|
73672
|
+
fs2.rmSync(this.installationDir(browser, platform2, buildId), {
|
|
72828
73673
|
force: true,
|
|
72829
73674
|
recursive: true,
|
|
72830
73675
|
maxRetries: 10,
|
|
@@ -72876,11 +73721,11 @@ function parseFolderPath(folderPath) {
|
|
|
72876
73721
|
if (splits.length !== 2) {
|
|
72877
73722
|
return;
|
|
72878
73723
|
}
|
|
72879
|
-
const [
|
|
72880
|
-
if (!buildId || !
|
|
73724
|
+
const [platform2, buildId] = splits;
|
|
73725
|
+
if (!buildId || !platform2) {
|
|
72881
73726
|
return;
|
|
72882
73727
|
}
|
|
72883
|
-
return { platform, buildId };
|
|
73728
|
+
return { platform: platform2, buildId };
|
|
72884
73729
|
}
|
|
72885
73730
|
var import_debug, debugCache;
|
|
72886
73731
|
var init_Cache = __esm(() => {
|
|
@@ -73383,8 +74228,8 @@ class DefaultProvider {
|
|
|
73383
74228
|
getDownloadUrl(options) {
|
|
73384
74229
|
return this.#getDownloadUrl(options.browser, options.platform, options.buildId);
|
|
73385
74230
|
}
|
|
73386
|
-
#getDownloadUrl(browser,
|
|
73387
|
-
return new URL(downloadUrls[browser](
|
|
74231
|
+
#getDownloadUrl(browser, platform2, buildId) {
|
|
74232
|
+
return new URL(downloadUrls[browser](platform2, buildId, this.#baseUrl));
|
|
73388
74233
|
}
|
|
73389
74234
|
getExecutablePath(options) {
|
|
73390
74235
|
return executablePathByBrowser[options.browser](options.platform, options.buildId);
|
|
@@ -78079,7 +78924,7 @@ var require_tar_fs = __commonJS((exports) => {
|
|
|
78079
78924
|
});
|
|
78080
78925
|
|
|
78081
78926
|
// node_modules/@puppeteer/browsers/lib/esm/fileUtil.js
|
|
78082
|
-
import { spawnSync, spawn } from "node:child_process";
|
|
78927
|
+
import { spawnSync as spawnSync2, spawn } from "node:child_process";
|
|
78083
78928
|
import { createReadStream } from "node:fs";
|
|
78084
78929
|
import { mkdir, readdir } from "node:fs/promises";
|
|
78085
78930
|
import * as path7 from "node:path";
|
|
@@ -78097,7 +78942,7 @@ async function unpackArchive(archivePath, folderPath) {
|
|
|
78097
78942
|
await mkdir(folderPath);
|
|
78098
78943
|
await installDMG(archivePath, folderPath);
|
|
78099
78944
|
} else if (archivePath.endsWith(".exe")) {
|
|
78100
|
-
const result =
|
|
78945
|
+
const result = spawnSync2(archivePath, [`/ExtractDir=${folderPath}`], {
|
|
78101
78946
|
env: {
|
|
78102
78947
|
__compat_layer: "RunAsInvoker"
|
|
78103
78948
|
}
|
|
@@ -78171,7 +79016,7 @@ async function extractTar(tarPath, folderPath, decompressUtilityName) {
|
|
|
78171
79016
|
});
|
|
78172
79017
|
}
|
|
78173
79018
|
async function installDMG(dmgPath, folderPath) {
|
|
78174
|
-
const { stdout } =
|
|
79019
|
+
const { stdout } = spawnSync2(`hdiutil`, [
|
|
78175
79020
|
"attach",
|
|
78176
79021
|
"-nobrowse",
|
|
78177
79022
|
"-noautoopen",
|
|
@@ -78191,9 +79036,9 @@ async function installDMG(dmgPath, folderPath) {
|
|
|
78191
79036
|
throw new Error(`Cannot find app in ${mountPath}`);
|
|
78192
79037
|
}
|
|
78193
79038
|
const mountedPath = path7.join(mountPath, appName);
|
|
78194
|
-
|
|
79039
|
+
spawnSync2("cp", ["-R", mountedPath, folderPath]);
|
|
78195
79040
|
} finally {
|
|
78196
|
-
|
|
79041
|
+
spawnSync2("hdiutil", ["detach", mountPath, "-quiet"]);
|
|
78197
79042
|
}
|
|
78198
79043
|
}
|
|
78199
79044
|
var import_debug4, debugFileUtil, internalConstantsForTesting;
|
|
@@ -78208,8 +79053,8 @@ var init_fileUtil = __esm(() => {
|
|
|
78208
79053
|
|
|
78209
79054
|
// node_modules/@puppeteer/browsers/lib/esm/install.js
|
|
78210
79055
|
import assert2 from "node:assert";
|
|
78211
|
-
import { spawnSync as
|
|
78212
|
-
import { existsSync as
|
|
79056
|
+
import { spawnSync as spawnSync3 } from "node:child_process";
|
|
79057
|
+
import { existsSync as existsSync22, readFileSync as readFileSync21 } from "node:fs";
|
|
78213
79058
|
import { mkdir as mkdir2, unlink } from "node:fs/promises";
|
|
78214
79059
|
import os5 from "node:os";
|
|
78215
79060
|
import path8 from "node:path";
|
|
@@ -78262,7 +79107,7 @@ async function installWithProviders(options) {
|
|
|
78262
79107
|
continue;
|
|
78263
79108
|
}
|
|
78264
79109
|
debugInstall(`Successfully got URL from ${provider.getName()}: ${url}`);
|
|
78265
|
-
if (!
|
|
79110
|
+
if (!existsSync22(browserRoot)) {
|
|
78266
79111
|
await mkdir2(browserRoot, { recursive: true });
|
|
78267
79112
|
}
|
|
78268
79113
|
return await installUrl(url, options, provider);
|
|
@@ -78295,21 +79140,21 @@ async function installDeps(installedBrowser) {
|
|
|
78295
79140
|
return;
|
|
78296
79141
|
}
|
|
78297
79142
|
const depsPath = path8.join(path8.dirname(installedBrowser.executablePath), "deb.deps");
|
|
78298
|
-
if (!
|
|
79143
|
+
if (!existsSync22(depsPath)) {
|
|
78299
79144
|
debugInstall(`deb.deps file was not found at ${depsPath}`);
|
|
78300
79145
|
return;
|
|
78301
79146
|
}
|
|
78302
|
-
const data =
|
|
79147
|
+
const data = readFileSync21(depsPath, "utf-8").split(`
|
|
78303
79148
|
`).join(",");
|
|
78304
79149
|
if (process.getuid?.() !== 0) {
|
|
78305
79150
|
throw new Error("Installing system dependencies requires root privileges");
|
|
78306
79151
|
}
|
|
78307
|
-
let result =
|
|
79152
|
+
let result = spawnSync3("apt-get", ["-v"]);
|
|
78308
79153
|
if (result.status !== 0) {
|
|
78309
79154
|
throw new Error("Failed to install system dependencies: apt-get does not seem to be available");
|
|
78310
79155
|
}
|
|
78311
79156
|
debugInstall(`Trying to install dependencies: ${data}`);
|
|
78312
|
-
result =
|
|
79157
|
+
result = spawnSync3("apt-get", [
|
|
78313
79158
|
"satisfy",
|
|
78314
79159
|
"-y",
|
|
78315
79160
|
data,
|
|
@@ -78337,11 +79182,11 @@ async function installUrl(url, options, provider) {
|
|
|
78337
79182
|
const cache = new Cache(options.cacheDir);
|
|
78338
79183
|
const browserRoot = cache.browserRoot(options.browser);
|
|
78339
79184
|
const archivePath = path8.join(browserRoot, `${options.buildId}-${fileName}`);
|
|
78340
|
-
if (!
|
|
79185
|
+
if (!existsSync22(browserRoot)) {
|
|
78341
79186
|
await mkdir2(browserRoot, { recursive: true });
|
|
78342
79187
|
}
|
|
78343
79188
|
if (!options.unpack) {
|
|
78344
|
-
if (
|
|
79189
|
+
if (existsSync22(archivePath)) {
|
|
78345
79190
|
return archivePath;
|
|
78346
79191
|
}
|
|
78347
79192
|
debugInstall(`Downloading binary from ${url}`);
|
|
@@ -78362,8 +79207,8 @@ async function installUrl(url, options, provider) {
|
|
|
78362
79207
|
cache.writeExecutablePath(options.browser, options.platform, options.buildId, relativeExecutablePath6);
|
|
78363
79208
|
}
|
|
78364
79209
|
try {
|
|
78365
|
-
if (
|
|
78366
|
-
if (!
|
|
79210
|
+
if (existsSync22(outputPath)) {
|
|
79211
|
+
if (!existsSync22(installedBrowser.executablePath)) {
|
|
78367
79212
|
throw new Error(`The browser folder (${outputPath}) exists but the executable (${installedBrowser.executablePath}) is missing`);
|
|
78368
79213
|
}
|
|
78369
79214
|
await runSetup(installedBrowser);
|
|
@@ -78372,7 +79217,7 @@ async function installUrl(url, options, provider) {
|
|
|
78372
79217
|
}
|
|
78373
79218
|
return installedBrowser;
|
|
78374
79219
|
}
|
|
78375
|
-
if (!
|
|
79220
|
+
if (!existsSync22(archivePath)) {
|
|
78376
79221
|
debugInstall(`Downloading binary from ${url}`);
|
|
78377
79222
|
try {
|
|
78378
79223
|
debugTime("download");
|
|
@@ -78401,7 +79246,7 @@ async function installUrl(url, options, provider) {
|
|
|
78401
79246
|
}
|
|
78402
79247
|
return installedBrowser;
|
|
78403
79248
|
} finally {
|
|
78404
|
-
if (
|
|
79249
|
+
if (existsSync22(archivePath)) {
|
|
78405
79250
|
await unlink(archivePath);
|
|
78406
79251
|
}
|
|
78407
79252
|
}
|
|
@@ -78412,10 +79257,10 @@ async function runSetup(installedBrowser) {
|
|
|
78412
79257
|
debugTime("permissions");
|
|
78413
79258
|
const browserDir = path8.dirname(installedBrowser.executablePath);
|
|
78414
79259
|
const setupExePath = path8.join(browserDir, "setup.exe");
|
|
78415
|
-
if (!
|
|
79260
|
+
if (!existsSync22(setupExePath)) {
|
|
78416
79261
|
return;
|
|
78417
79262
|
}
|
|
78418
|
-
|
|
79263
|
+
spawnSync3(path8.join(browserDir, "setup.exe"), [`--configure-browser-in-directory=` + browserDir], {
|
|
78419
79264
|
shell: true
|
|
78420
79265
|
});
|
|
78421
79266
|
} finally {
|
|
@@ -78458,8 +79303,8 @@ async function canDownload(options) {
|
|
|
78458
79303
|
}
|
|
78459
79304
|
return false;
|
|
78460
79305
|
}
|
|
78461
|
-
function getDownloadUrl(browser,
|
|
78462
|
-
return new URL(downloadUrls[browser](
|
|
79306
|
+
function getDownloadUrl(browser, platform2, buildId, baseUrl) {
|
|
79307
|
+
return new URL(downloadUrls[browser](platform2, buildId, baseUrl));
|
|
78463
79308
|
}
|
|
78464
79309
|
function makeProgressCallback(browser, buildId) {
|
|
78465
79310
|
let progressBar;
|
|
@@ -78793,19 +79638,19 @@ var init_cliui = __esm(() => {
|
|
|
78793
79638
|
});
|
|
78794
79639
|
|
|
78795
79640
|
// node_modules/escalade/sync/index.mjs
|
|
78796
|
-
import { dirname as
|
|
79641
|
+
import { dirname as dirname10, resolve as resolve7 } from "path";
|
|
78797
79642
|
import { readdirSync as readdirSync6, statSync as statSync9 } from "fs";
|
|
78798
79643
|
function sync_default(start, callback) {
|
|
78799
79644
|
let dir = resolve7(".", start);
|
|
78800
79645
|
let tmp, stats = statSync9(dir);
|
|
78801
79646
|
if (!stats.isDirectory()) {
|
|
78802
|
-
dir =
|
|
79647
|
+
dir = dirname10(dir);
|
|
78803
79648
|
}
|
|
78804
79649
|
while (true) {
|
|
78805
79650
|
tmp = callback(dir, readdirSync6(dir));
|
|
78806
79651
|
if (tmp)
|
|
78807
79652
|
return resolve7(dir, tmp);
|
|
78808
|
-
dir =
|
|
79653
|
+
dir = dirname10(tmp = dir);
|
|
78809
79654
|
if (tmp === dir)
|
|
78810
79655
|
break;
|
|
78811
79656
|
}
|
|
@@ -79825,14 +80670,14 @@ var init_yerror = __esm(() => {
|
|
|
79825
80670
|
});
|
|
79826
80671
|
|
|
79827
80672
|
// node_modules/y18n/build/lib/platform-shims/node.js
|
|
79828
|
-
import { readFileSync as
|
|
80673
|
+
import { readFileSync as readFileSync22, statSync as statSync10, writeFile } from "fs";
|
|
79829
80674
|
import { format as format2 } from "util";
|
|
79830
80675
|
import { resolve as resolve9 } from "path";
|
|
79831
80676
|
var node_default;
|
|
79832
80677
|
var init_node = __esm(() => {
|
|
79833
80678
|
node_default = {
|
|
79834
80679
|
fs: {
|
|
79835
|
-
readFileSync:
|
|
80680
|
+
readFileSync: readFileSync22,
|
|
79836
80681
|
writeFile
|
|
79837
80682
|
},
|
|
79838
80683
|
format: format2,
|
|
@@ -80017,9 +80862,9 @@ var init_y18n = __esm(() => {
|
|
|
80017
80862
|
// node_modules/yargs/lib/platform-shims/esm.mjs
|
|
80018
80863
|
import { notStrictEqual, strictEqual } from "assert";
|
|
80019
80864
|
import { inspect } from "util";
|
|
80020
|
-
import { readFileSync as
|
|
80865
|
+
import { readFileSync as readFileSync23 } from "fs";
|
|
80021
80866
|
import { fileURLToPath } from "url";
|
|
80022
|
-
import { basename as basename10, dirname as
|
|
80867
|
+
import { basename as basename10, dirname as dirname11, extname as extname3, relative as relative7, resolve as resolve10 } from "path";
|
|
80023
80868
|
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;
|
|
80024
80869
|
var init_esm = __esm(() => {
|
|
80025
80870
|
init_cliui();
|
|
@@ -80052,7 +80897,7 @@ var init_esm = __esm(() => {
|
|
|
80052
80897
|
Parser: lib_default,
|
|
80053
80898
|
path: {
|
|
80054
80899
|
basename: basename10,
|
|
80055
|
-
dirname:
|
|
80900
|
+
dirname: dirname11,
|
|
80056
80901
|
extname: extname3,
|
|
80057
80902
|
relative: relative7,
|
|
80058
80903
|
resolve: resolve10
|
|
@@ -80066,7 +80911,7 @@ var init_esm = __esm(() => {
|
|
|
80066
80911
|
nextTick: process.nextTick,
|
|
80067
80912
|
stdColumns: typeof process.stdout.columns !== "undefined" ? process.stdout.columns : null
|
|
80068
80913
|
},
|
|
80069
|
-
readFileSync:
|
|
80914
|
+
readFileSync: readFileSync23,
|
|
80070
80915
|
require: () => {
|
|
80071
80916
|
throw new YError(REQUIRE_ERROR);
|
|
80072
80917
|
},
|
|
@@ -83399,8 +84244,8 @@ import * as readline2 from "node:readline";
|
|
|
83399
84244
|
function isValidBrowser(browser) {
|
|
83400
84245
|
return Object.values(Browser6).includes(browser);
|
|
83401
84246
|
}
|
|
83402
|
-
function isValidPlatform(
|
|
83403
|
-
return Object.values(BrowserPlatform).includes(
|
|
84247
|
+
function isValidPlatform(platform2) {
|
|
84248
|
+
return Object.values(BrowserPlatform).includes(platform2);
|
|
83404
84249
|
}
|
|
83405
84250
|
|
|
83406
84251
|
class CLI {
|
|
@@ -83451,11 +84296,11 @@ class CLI {
|
|
|
83451
84296
|
desc: "Platform that the binary needs to be compatible with.",
|
|
83452
84297
|
choices: Object.values(BrowserPlatform),
|
|
83453
84298
|
default: detectBrowserPlatform(),
|
|
83454
|
-
coerce: (
|
|
83455
|
-
if (!isValidPlatform(
|
|
83456
|
-
throw new Error(`Unsupported platform '${
|
|
84299
|
+
coerce: (platform2) => {
|
|
84300
|
+
if (!isValidPlatform(platform2)) {
|
|
84301
|
+
throw new Error(`Unsupported platform '${platform2}'`);
|
|
83457
84302
|
}
|
|
83458
|
-
return
|
|
84303
|
+
return platform2;
|
|
83459
84304
|
},
|
|
83460
84305
|
defaultDescription: "Auto-detected"
|
|
83461
84306
|
});
|
|
@@ -83660,8 +84505,8 @@ var init_CLI = __esm(() => {
|
|
|
83660
84505
|
});
|
|
83661
84506
|
|
|
83662
84507
|
// node_modules/@puppeteer/browsers/lib/esm/provider.js
|
|
83663
|
-
function buildArchiveFilename(browser,
|
|
83664
|
-
return `${browser}-${
|
|
84508
|
+
function buildArchiveFilename(browser, platform2, buildId, extension2 = "zip") {
|
|
84509
|
+
return `${browser}-${platform2}-${buildId}.${extension2}`;
|
|
83665
84510
|
}
|
|
83666
84511
|
|
|
83667
84512
|
// node_modules/@puppeteer/browsers/lib/esm/main.js
|
|
@@ -83711,8 +84556,8 @@ var exports_LaunchOptions = {};
|
|
|
83711
84556
|
__export(exports_LaunchOptions, {
|
|
83712
84557
|
convertPuppeteerChannelToBrowsersChannel: () => convertPuppeteerChannelToBrowsersChannel
|
|
83713
84558
|
});
|
|
83714
|
-
function convertPuppeteerChannelToBrowsersChannel(
|
|
83715
|
-
switch (
|
|
84559
|
+
function convertPuppeteerChannelToBrowsersChannel(channel2) {
|
|
84560
|
+
switch (channel2) {
|
|
83716
84561
|
case "chrome":
|
|
83717
84562
|
return ChromeReleaseChannel.STABLE;
|
|
83718
84563
|
case "chrome-dev":
|
|
@@ -83739,8 +84584,8 @@ async function _connectToBrowser(options) {
|
|
|
83739
84584
|
}
|
|
83740
84585
|
}
|
|
83741
84586
|
async function getConnectionTransport(options) {
|
|
83742
|
-
const { browserWSEndpoint, browserURL, channel, transport, headers = {} } = options;
|
|
83743
|
-
assert(Number(!!browserWSEndpoint) + Number(!!browserURL) + Number(!!transport) + Number(!!
|
|
84587
|
+
const { browserWSEndpoint, browserURL, channel: channel2, transport, headers = {} } = options;
|
|
84588
|
+
assert(Number(!!browserWSEndpoint) + Number(!!browserURL) + Number(!!transport) + Number(!!channel2) === 1, "Exactly one of browserWSEndpoint, browserURL, transport or channel must be passed to puppeteer.connect");
|
|
83744
84589
|
if (transport) {
|
|
83745
84590
|
return { connectionTransport: transport, endpointUrl: "" };
|
|
83746
84591
|
} else if (browserWSEndpoint) {
|
|
@@ -83760,14 +84605,14 @@ async function getConnectionTransport(options) {
|
|
|
83760
84605
|
};
|
|
83761
84606
|
} else if (options.channel && isNode) {
|
|
83762
84607
|
const { detectBrowserPlatform: detectBrowserPlatform2, resolveDefaultUserDataDir: resolveDefaultUserDataDir3, Browser: Browser7 } = await Promise.resolve().then(() => (init_main(), exports_main));
|
|
83763
|
-
const
|
|
83764
|
-
if (!
|
|
84608
|
+
const platform2 = detectBrowserPlatform2();
|
|
84609
|
+
if (!platform2) {
|
|
83765
84610
|
throw new Error("Could not detect required browser platform");
|
|
83766
84611
|
}
|
|
83767
84612
|
const { convertPuppeteerChannelToBrowsersChannel: convertPuppeteerChannelToBrowsersChannel2 } = await Promise.resolve().then(() => (init_LaunchOptions(), exports_LaunchOptions));
|
|
83768
|
-
const { join:
|
|
83769
|
-
const userDataDir = resolveDefaultUserDataDir3(Browser7.CHROME,
|
|
83770
|
-
const portPath =
|
|
84613
|
+
const { join: join22 } = await import("node:path");
|
|
84614
|
+
const userDataDir = resolveDefaultUserDataDir3(Browser7.CHROME, platform2, convertPuppeteerChannelToBrowsersChannel2(options.channel));
|
|
84615
|
+
const portPath = join22(userDataDir, "DevToolsActivePort");
|
|
83771
84616
|
try {
|
|
83772
84617
|
const fileContent = await environment.value.fs.promises.readFile(portPath, "ascii");
|
|
83773
84618
|
const [rawPort, rawPath] = fileContent.split(`
|
|
@@ -83991,9 +84836,9 @@ var init_PipeTransport = __esm(() => {
|
|
|
83991
84836
|
});
|
|
83992
84837
|
|
|
83993
84838
|
// node_modules/puppeteer-core/lib/esm/puppeteer/node/BrowserLauncher.js
|
|
83994
|
-
import { existsSync as
|
|
84839
|
+
import { existsSync as existsSync23 } from "node:fs";
|
|
83995
84840
|
import { tmpdir } from "node:os";
|
|
83996
|
-
import { join as
|
|
84841
|
+
import { join as join22 } from "node:path";
|
|
83997
84842
|
|
|
83998
84843
|
class BrowserLauncher {
|
|
83999
84844
|
#browser;
|
|
@@ -84018,7 +84863,7 @@ class BrowserLauncher {
|
|
|
84018
84863
|
...options,
|
|
84019
84864
|
protocol
|
|
84020
84865
|
});
|
|
84021
|
-
if (!
|
|
84866
|
+
if (!existsSync23(launchArgs.executablePath)) {
|
|
84022
84867
|
throw new Error(`Browser was not found at the configured executablePath (${launchArgs.executablePath})`);
|
|
84023
84868
|
}
|
|
84024
84869
|
const usePipe = launchArgs.args.includes("--remote-debugging-pipe");
|
|
@@ -84093,7 +84938,7 @@ class BrowserLauncher {
|
|
|
84093
84938
|
browserCloseCallback();
|
|
84094
84939
|
const logs = browserProcess.getRecentLogs().join(`
|
|
84095
84940
|
`);
|
|
84096
|
-
if (logs.includes("Failed to create a ProcessSingleton for your profile directory") || process.platform === "win32" &&
|
|
84941
|
+
if (logs.includes("Failed to create a ProcessSingleton for your profile directory") || process.platform === "win32" && existsSync23(join22(launchArgs.userDataDir, "lockfile"))) {
|
|
84097
84942
|
throw new Error(`The browser is already running for ${launchArgs.userDataDir}. Use a different \`userDataDir\` or stop the running browser first.`);
|
|
84098
84943
|
}
|
|
84099
84944
|
if (logs.includes("Missing X server") && options.headless === false) {
|
|
@@ -84183,12 +85028,12 @@ class BrowserLauncher {
|
|
|
84183
85028
|
});
|
|
84184
85029
|
}
|
|
84185
85030
|
getProfilePath() {
|
|
84186
|
-
return
|
|
85031
|
+
return join22(this.puppeteer.configuration.temporaryDirectory ?? tmpdir(), `puppeteer_dev_${this.browser}_profile-`);
|
|
84187
85032
|
}
|
|
84188
85033
|
resolveExecutablePath(headless, validatePath = true) {
|
|
84189
85034
|
let executablePath = this.puppeteer.configuration.executablePath;
|
|
84190
85035
|
if (executablePath) {
|
|
84191
|
-
if (validatePath && !
|
|
85036
|
+
if (validatePath && !existsSync23(executablePath)) {
|
|
84192
85037
|
throw new Error(`Tried to find the browser at the configured path (${executablePath}), but no executable was found.`);
|
|
84193
85038
|
}
|
|
84194
85039
|
return executablePath;
|
|
@@ -84211,7 +85056,7 @@ class BrowserLauncher {
|
|
|
84211
85056
|
browser: browserType,
|
|
84212
85057
|
buildId: this.puppeteer.browserVersion
|
|
84213
85058
|
});
|
|
84214
|
-
if (validatePath && !
|
|
85059
|
+
if (validatePath && !existsSync23(executablePath)) {
|
|
84215
85060
|
const configVersion = this.puppeteer.configuration?.[this.browser]?.version;
|
|
84216
85061
|
if (configVersion) {
|
|
84217
85062
|
throw new Error(`Tried to find the browser at the configured path (${executablePath}) for version ${configVersion}, but no executable was found.`);
|
|
@@ -84311,7 +85156,7 @@ var init_ChromeLauncher = __esm(() => {
|
|
|
84311
85156
|
return super.launch(options);
|
|
84312
85157
|
}
|
|
84313
85158
|
async computeLaunchArguments(options = {}) {
|
|
84314
|
-
const { ignoreDefaultArgs = false, args = [], pipe: pipe2 = false, debuggingPort, channel, executablePath } = options;
|
|
85159
|
+
const { ignoreDefaultArgs = false, args = [], pipe: pipe2 = false, debuggingPort, channel: channel2, executablePath } = options;
|
|
84315
85160
|
const chromeArguments = [];
|
|
84316
85161
|
if (!ignoreDefaultArgs) {
|
|
84317
85162
|
chromeArguments.push(...this.defaultArgs(options));
|
|
@@ -84345,8 +85190,8 @@ var init_ChromeLauncher = __esm(() => {
|
|
|
84345
85190
|
assert(typeof userDataDir === "string", "`--user-data-dir` is malformed");
|
|
84346
85191
|
let chromeExecutable = executablePath;
|
|
84347
85192
|
if (!chromeExecutable) {
|
|
84348
|
-
assert(
|
|
84349
|
-
chromeExecutable =
|
|
85193
|
+
assert(channel2 || !this.puppeteer._isPuppeteerCore, `An \`executablePath\` or \`channel\` must be specified for \`puppeteer-core\``);
|
|
85194
|
+
chromeExecutable = channel2 ? this.executablePath(channel2) : this.resolveExecutablePath(options.headless ?? true);
|
|
84350
85195
|
}
|
|
84351
85196
|
return {
|
|
84352
85197
|
executablePath: chromeExecutable,
|
|
@@ -84450,11 +85295,11 @@ var init_ChromeLauncher = __esm(() => {
|
|
|
84450
85295
|
chromeArguments.push(...args);
|
|
84451
85296
|
return chromeArguments;
|
|
84452
85297
|
}
|
|
84453
|
-
executablePath(
|
|
84454
|
-
if (
|
|
85298
|
+
executablePath(channel2, validatePath = true) {
|
|
85299
|
+
if (channel2) {
|
|
84455
85300
|
return computeSystemExecutablePath({
|
|
84456
85301
|
browser: Browser6.CHROME,
|
|
84457
|
-
channel: convertPuppeteerChannelToBrowsersChannel(
|
|
85302
|
+
channel: convertPuppeteerChannelToBrowsersChannel(channel2)
|
|
84458
85303
|
});
|
|
84459
85304
|
} else {
|
|
84460
85305
|
return this.resolveExecutablePath(undefined, validatePath);
|
|
@@ -84697,8 +85542,8 @@ var init_PuppeteerNode = __esm(() => {
|
|
|
84697
85542
|
return this.#getLauncher(options.browser ?? this.lastLaunchedBrowser).defaultArgs(options);
|
|
84698
85543
|
}
|
|
84699
85544
|
async trimCache() {
|
|
84700
|
-
const
|
|
84701
|
-
if (!
|
|
85545
|
+
const platform2 = detectBrowserPlatform();
|
|
85546
|
+
if (!platform2) {
|
|
84702
85547
|
throw new Error("The current platform is not supported.");
|
|
84703
85548
|
}
|
|
84704
85549
|
const cacheDir = this.configuration.cacheDirectory;
|
|
@@ -84719,7 +85564,7 @@ var init_PuppeteerNode = __esm(() => {
|
|
|
84719
85564
|
];
|
|
84720
85565
|
await Promise.all(puppeteerBrowsers.map(async (item) => {
|
|
84721
85566
|
const tag = this.configuration?.[item.product]?.version ?? PUPPETEER_REVISIONS[item.product];
|
|
84722
|
-
item.currentBuildId = await resolveBuildId4(item.browser,
|
|
85567
|
+
item.currentBuildId = await resolveBuildId4(item.browser, platform2, tag);
|
|
84723
85568
|
}));
|
|
84724
85569
|
const currentBrowserBuilds = new Set(puppeteerBrowsers.map((browser) => {
|
|
84725
85570
|
return `${browser.browser}_${browser.currentBuildId}`;
|
|
@@ -84736,7 +85581,7 @@ var init_PuppeteerNode = __esm(() => {
|
|
|
84736
85581
|
}
|
|
84737
85582
|
await uninstall({
|
|
84738
85583
|
browser: installedBrowser.browser,
|
|
84739
|
-
platform,
|
|
85584
|
+
platform: platform2,
|
|
84740
85585
|
cacheDir,
|
|
84741
85586
|
buildId: installedBrowser.buildId
|
|
84742
85587
|
});
|
|
@@ -84746,10 +85591,10 @@ var init_PuppeteerNode = __esm(() => {
|
|
|
84746
85591
|
});
|
|
84747
85592
|
|
|
84748
85593
|
// node_modules/puppeteer-core/lib/esm/puppeteer/node/ScreenRecorder.js
|
|
84749
|
-
import { spawn as spawn2, spawnSync as
|
|
85594
|
+
import { spawn as spawn2, spawnSync as spawnSync4 } from "node:child_process";
|
|
84750
85595
|
import fs5 from "node:fs";
|
|
84751
85596
|
import os8 from "node:os";
|
|
84752
|
-
import { dirname as
|
|
85597
|
+
import { dirname as dirname12 } from "node:path";
|
|
84753
85598
|
import { PassThrough } from "node:stream";
|
|
84754
85599
|
var import_debug6, __runInitializers22 = function(thisArg, initializers, value) {
|
|
84755
85600
|
var useValue = arguments.length > 2;
|
|
@@ -84850,7 +85695,7 @@ var init_ScreenRecorder = __esm(() => {
|
|
|
84850
85695
|
colors ??= 256;
|
|
84851
85696
|
overwrite ??= true;
|
|
84852
85697
|
this.#fps = fps;
|
|
84853
|
-
const { error } =
|
|
85698
|
+
const { error } = spawnSync4(ffmpegPath);
|
|
84854
85699
|
if (error) {
|
|
84855
85700
|
throw error;
|
|
84856
85701
|
}
|
|
@@ -84873,7 +85718,7 @@ var init_ScreenRecorder = __esm(() => {
|
|
|
84873
85718
|
filters.push(formatArgs.splice(vf, 2).at(-1) ?? "");
|
|
84874
85719
|
}
|
|
84875
85720
|
if (path11) {
|
|
84876
|
-
fs5.mkdirSync(
|
|
85721
|
+
fs5.mkdirSync(dirname12(path11), { recursive: overwrite });
|
|
84877
85722
|
}
|
|
84878
85723
|
this.#process = spawn2(ffmpegPath, [
|
|
84879
85724
|
["-loglevel", "error"],
|
|
@@ -85026,17 +85871,17 @@ var init_puppeteer_core = __esm(() => {
|
|
|
85026
85871
|
});
|
|
85027
85872
|
|
|
85028
85873
|
// src/core/design-eval/capture.ts
|
|
85029
|
-
import { mkdirSync as
|
|
85030
|
-
import { join as
|
|
85874
|
+
import { mkdirSync as mkdirSync11, statSync as statSync11, existsSync as existsSync24 } from "fs";
|
|
85875
|
+
import { join as join23 } from "path";
|
|
85031
85876
|
function findBrowser() {
|
|
85032
|
-
const
|
|
85033
|
-
const paths = CHROME_PATHS[
|
|
85877
|
+
const platform2 = process.platform;
|
|
85878
|
+
const paths = CHROME_PATHS[platform2] ?? [];
|
|
85034
85879
|
for (const p of paths) {
|
|
85035
|
-
if (
|
|
85880
|
+
if (existsSync24(p))
|
|
85036
85881
|
return p;
|
|
85037
85882
|
}
|
|
85038
|
-
const minkBrowsers =
|
|
85039
|
-
if (
|
|
85883
|
+
const minkBrowsers = join23(minkRoot(), "browsers");
|
|
85884
|
+
if (existsSync24(minkBrowsers)) {
|
|
85040
85885
|
const found = findChromeInDir(minkBrowsers);
|
|
85041
85886
|
if (found)
|
|
85042
85887
|
return found;
|
|
@@ -85057,7 +85902,7 @@ function findChromeInDir(dir) {
|
|
|
85057
85902
|
try {
|
|
85058
85903
|
const entries = readdirSync7(dir);
|
|
85059
85904
|
for (const entry of entries) {
|
|
85060
|
-
const full =
|
|
85905
|
+
const full = join23(dir, entry);
|
|
85061
85906
|
try {
|
|
85062
85907
|
const stat2 = statSync12(full);
|
|
85063
85908
|
if (stat2.isDirectory()) {
|
|
@@ -85105,7 +85950,7 @@ async function captureRoute(page, route, baseUrl, viewport, options) {
|
|
|
85105
85950
|
const y = section * viewport.height;
|
|
85106
85951
|
const clipHeight = Math.min(viewport.height, pageHeight - y);
|
|
85107
85952
|
const fileName = `${prefix}-${viewport.name}-${section}.jpg`;
|
|
85108
|
-
const filePath =
|
|
85953
|
+
const filePath = join23(options.outputDir, fileName);
|
|
85109
85954
|
await page.screenshot({
|
|
85110
85955
|
path: filePath,
|
|
85111
85956
|
type: "jpeg",
|
|
@@ -85137,7 +85982,7 @@ async function captureRoute(page, route, baseUrl, viewport, options) {
|
|
|
85137
85982
|
return results;
|
|
85138
85983
|
}
|
|
85139
85984
|
async function captureAllRoutes(routes, baseUrl, viewports, options, outputDir) {
|
|
85140
|
-
|
|
85985
|
+
mkdirSync11(outputDir, { recursive: true });
|
|
85141
85986
|
const executablePath = findBrowser();
|
|
85142
85987
|
const browser = await puppeteer_core_default.launch({
|
|
85143
85988
|
executablePath,
|
|
@@ -86565,22 +87410,22 @@ var init_framework_advisor2 = __esm(() => {
|
|
|
86565
87410
|
});
|
|
86566
87411
|
|
|
86567
87412
|
// src/core/vault-templates.ts
|
|
86568
|
-
import { join as
|
|
86569
|
-
import { existsSync as
|
|
87413
|
+
import { join as join24 } from "path";
|
|
87414
|
+
import { existsSync as existsSync25, writeFileSync as writeFileSync8, readFileSync as readFileSync24, mkdirSync as mkdirSync12 } from "fs";
|
|
86570
87415
|
function seedTemplates(templatesDir) {
|
|
86571
|
-
|
|
87416
|
+
mkdirSync12(templatesDir, { recursive: true });
|
|
86572
87417
|
for (const [name, content] of Object.entries(DEFAULT_TEMPLATES)) {
|
|
86573
|
-
const filePath =
|
|
86574
|
-
if (!
|
|
86575
|
-
|
|
87418
|
+
const filePath = join24(templatesDir, `${name}.md`);
|
|
87419
|
+
if (!existsSync25(filePath)) {
|
|
87420
|
+
writeFileSync8(filePath, content);
|
|
86576
87421
|
}
|
|
86577
87422
|
}
|
|
86578
87423
|
}
|
|
86579
87424
|
function loadTemplate(templatesDir, templateName, vars) {
|
|
86580
|
-
const filePath =
|
|
87425
|
+
const filePath = join24(templatesDir, `${templateName}.md`);
|
|
86581
87426
|
let content;
|
|
86582
|
-
if (
|
|
86583
|
-
content =
|
|
87427
|
+
if (existsSync25(filePath)) {
|
|
87428
|
+
content = readFileSync24(filePath, "utf-8");
|
|
86584
87429
|
} else if (DEFAULT_TEMPLATES[templateName]) {
|
|
86585
87430
|
content = DEFAULT_TEMPLATES[templateName];
|
|
86586
87431
|
} else {
|
|
@@ -86733,8 +87578,8 @@ category: resources
|
|
|
86733
87578
|
});
|
|
86734
87579
|
|
|
86735
87580
|
// src/core/note-linker.ts
|
|
86736
|
-
import { join as
|
|
86737
|
-
import { existsSync as
|
|
87581
|
+
import { join as join25 } from "path";
|
|
87582
|
+
import { existsSync as existsSync26, readFileSync as readFileSync25, readdirSync as readdirSync7, statSync as statSync12 } from "fs";
|
|
86738
87583
|
function updateMasterIndex(vaultRootPath) {
|
|
86739
87584
|
const now = new Date().toISOString().split("T")[0];
|
|
86740
87585
|
const sections = [
|
|
@@ -86756,8 +87601,8 @@ function updateMasterIndex(vaultRootPath) {
|
|
|
86756
87601
|
{ name: "Patterns", dir: "patterns", emoji: "" }
|
|
86757
87602
|
];
|
|
86758
87603
|
for (const cat of categories) {
|
|
86759
|
-
const dirPath =
|
|
86760
|
-
if (!
|
|
87604
|
+
const dirPath = join25(vaultRootPath, cat.dir);
|
|
87605
|
+
if (!existsSync26(dirPath))
|
|
86761
87606
|
continue;
|
|
86762
87607
|
const files = collectMarkdownFiles(dirPath, vaultRootPath);
|
|
86763
87608
|
if (files.length === 0 && cat.dir !== "inbox")
|
|
@@ -86786,7 +87631,7 @@ function collectMarkdownFiles(dirPath, rootPath) {
|
|
|
86786
87631
|
try {
|
|
86787
87632
|
const entries = readdirSync7(dirPath, { withFileTypes: true });
|
|
86788
87633
|
for (const entry of entries) {
|
|
86789
|
-
const fullPath =
|
|
87634
|
+
const fullPath = join25(dirPath, entry.name);
|
|
86790
87635
|
if (entry.isDirectory()) {
|
|
86791
87636
|
files.push(...collectMarkdownFiles(fullPath, rootPath));
|
|
86792
87637
|
} else if (entry.name.endsWith(".md") && !entry.name.startsWith("_")) {
|
|
@@ -86809,7 +87654,7 @@ var exports_wiki = {};
|
|
|
86809
87654
|
__export(exports_wiki, {
|
|
86810
87655
|
wiki: () => wiki
|
|
86811
87656
|
});
|
|
86812
|
-
import { existsSync as
|
|
87657
|
+
import { existsSync as existsSync27, statSync as statSync13 } from "fs";
|
|
86813
87658
|
import { resolve as resolve11 } from "path";
|
|
86814
87659
|
import { homedir as homedir4 } from "os";
|
|
86815
87660
|
async function wiki(_cwd, args) {
|
|
@@ -86865,7 +87710,7 @@ async function wikiInit(args) {
|
|
|
86865
87710
|
console.log(`[mink] initializing vault at ${targetPath}`);
|
|
86866
87711
|
console.log(" (set a custom path with: mink wiki init /path/to/vault)");
|
|
86867
87712
|
}
|
|
86868
|
-
const isExisting =
|
|
87713
|
+
const isExisting = existsSync27(targetPath) && statSync13(targetPath).isDirectory();
|
|
86869
87714
|
setConfigValue("wiki.path", targetPath);
|
|
86870
87715
|
ensureVaultStructure();
|
|
86871
87716
|
seedTemplates(vaultTemplates());
|
|
@@ -87083,8 +87928,8 @@ var init_wiki = __esm(() => {
|
|
|
87083
87928
|
});
|
|
87084
87929
|
|
|
87085
87930
|
// src/core/note-writer.ts
|
|
87086
|
-
import { join as
|
|
87087
|
-
import { existsSync as
|
|
87931
|
+
import { join as join26 } from "path";
|
|
87932
|
+
import { existsSync as existsSync28, readFileSync as readFileSync26 } from "fs";
|
|
87088
87933
|
function slugifyTitle(title) {
|
|
87089
87934
|
return title.toLowerCase().replace(/[^a-z0-9\s-]/g, "").replace(/\s+/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "").slice(0, 80);
|
|
87090
87935
|
}
|
|
@@ -87117,7 +87962,7 @@ function createNote(meta) {
|
|
|
87117
87962
|
const now = meta.created || new Date().toISOString();
|
|
87118
87963
|
const slug = slugifyTitle(meta.title);
|
|
87119
87964
|
const dir = categoryToDir(meta.category, meta.projectSlug);
|
|
87120
|
-
const filePath =
|
|
87965
|
+
const filePath = join26(dir, `${slug}.md`);
|
|
87121
87966
|
let content;
|
|
87122
87967
|
if (meta.template) {
|
|
87123
87968
|
const rendered = loadTemplate(vaultTemplates(), meta.template, {
|
|
@@ -87151,9 +87996,9 @@ ${meta.body}
|
|
|
87151
87996
|
}
|
|
87152
87997
|
function appendToDaily(date, content) {
|
|
87153
87998
|
const dir = vaultDailyDir();
|
|
87154
|
-
const filePath =
|
|
87155
|
-
if (
|
|
87156
|
-
const existing =
|
|
87999
|
+
const filePath = join26(dir, `${date}.md`);
|
|
88000
|
+
if (existsSync28(filePath)) {
|
|
88001
|
+
const existing = readFileSync26(filePath, "utf-8");
|
|
87157
88002
|
const timestamp = new Date().toLocaleTimeString("en-US", {
|
|
87158
88003
|
hour: "2-digit",
|
|
87159
88004
|
minute: "2-digit",
|
|
@@ -87191,7 +88036,7 @@ ${content}
|
|
|
87191
88036
|
return filePath;
|
|
87192
88037
|
}
|
|
87193
88038
|
function ingestFile(sourcePath, meta) {
|
|
87194
|
-
const raw =
|
|
88039
|
+
const raw = readFileSync26(sourcePath, "utf-8");
|
|
87195
88040
|
const now = new Date().toISOString();
|
|
87196
88041
|
const headingMatch = raw.match(/^#\s+(.+)$/m);
|
|
87197
88042
|
const title = headingMatch?.[1] ?? sourcePath.split("/").pop().replace(/\.md$/, "");
|
|
@@ -87229,7 +88074,7 @@ ${raw}`;
|
|
|
87229
88074
|
}
|
|
87230
88075
|
const slug = slugifyTitle(title);
|
|
87231
88076
|
const dir = categoryToDir(meta.category, meta.projectSlug);
|
|
87232
|
-
const filePath =
|
|
88077
|
+
const filePath = join26(dir, `${slug}.md`);
|
|
87233
88078
|
atomicWriteText(filePath, content);
|
|
87234
88079
|
return { filePath, content };
|
|
87235
88080
|
}
|
|
@@ -87245,7 +88090,7 @@ __export(exports_note, {
|
|
|
87245
88090
|
note: () => note
|
|
87246
88091
|
});
|
|
87247
88092
|
import { resolve as resolve12 } from "path";
|
|
87248
|
-
import { existsSync as
|
|
88093
|
+
import { existsSync as existsSync29, readFileSync as readFileSync27 } from "fs";
|
|
87249
88094
|
async function note(cwd, args) {
|
|
87250
88095
|
if (!isWikiEnabled()) {
|
|
87251
88096
|
console.error("[mink] wiki feature is disabled");
|
|
@@ -87270,13 +88115,13 @@ async function note(cwd, args) {
|
|
|
87270
88115
|
const date = new Date().toISOString().split("T")[0];
|
|
87271
88116
|
const content = parsed.positional || parsed.body || "";
|
|
87272
88117
|
const filePath = appendToDaily(date, content);
|
|
87273
|
-
updateVaultIndexForFile(filePath,
|
|
88118
|
+
updateVaultIndexForFile(filePath, readFileSync27(filePath, "utf-8"));
|
|
87274
88119
|
console.log(`[mink] daily note: ${filePath}`);
|
|
87275
88120
|
return;
|
|
87276
88121
|
}
|
|
87277
88122
|
if (parsed.file) {
|
|
87278
88123
|
const sourcePath = resolve12(cwd, parsed.file);
|
|
87279
|
-
if (!
|
|
88124
|
+
if (!existsSync29(sourcePath)) {
|
|
87280
88125
|
console.error(`[mink] file not found: ${sourcePath}`);
|
|
87281
88126
|
process.exit(1);
|
|
87282
88127
|
}
|
|
@@ -87437,29 +88282,29 @@ var exports_skill = {};
|
|
|
87437
88282
|
__export(exports_skill, {
|
|
87438
88283
|
skill: () => skill
|
|
87439
88284
|
});
|
|
87440
|
-
import { join as
|
|
88285
|
+
import { join as join27, resolve as resolve13, dirname as dirname13 } from "path";
|
|
87441
88286
|
import { homedir as homedir5 } from "os";
|
|
87442
88287
|
import {
|
|
87443
|
-
existsSync as
|
|
87444
|
-
mkdirSync as
|
|
88288
|
+
existsSync as existsSync30,
|
|
88289
|
+
mkdirSync as mkdirSync13,
|
|
87445
88290
|
copyFileSync,
|
|
87446
|
-
unlinkSync as
|
|
88291
|
+
unlinkSync as unlinkSync4,
|
|
87447
88292
|
readdirSync as readdirSync8,
|
|
87448
88293
|
rmSync,
|
|
87449
88294
|
symlinkSync as symlinkSync2,
|
|
87450
88295
|
lstatSync as lstatSync2
|
|
87451
88296
|
} from "fs";
|
|
87452
88297
|
function getSkillsSourceDir() {
|
|
87453
|
-
return resolve13(
|
|
88298
|
+
return resolve13(dirname13(new URL(import.meta.url).pathname), "../../skills");
|
|
87454
88299
|
}
|
|
87455
88300
|
function getAvailableSkills() {
|
|
87456
88301
|
const dir = getSkillsSourceDir();
|
|
87457
|
-
if (!
|
|
88302
|
+
if (!existsSync30(dir))
|
|
87458
88303
|
return [];
|
|
87459
|
-
return readdirSync8(dir, { withFileTypes: true }).filter((d) => d.isDirectory() &&
|
|
88304
|
+
return readdirSync8(dir, { withFileTypes: true }).filter((d) => d.isDirectory() && existsSync30(join27(dir, d.name, "SKILL.md"))).map((d) => d.name);
|
|
87460
88305
|
}
|
|
87461
88306
|
function isInstalled(skillName) {
|
|
87462
|
-
return
|
|
88307
|
+
return existsSync30(join27(AGENTS_SKILLS_DIR, skillName, "SKILL.md"));
|
|
87463
88308
|
}
|
|
87464
88309
|
async function skill(args) {
|
|
87465
88310
|
const sub = args[0];
|
|
@@ -87493,28 +88338,28 @@ function skillInstall(name) {
|
|
|
87493
88338
|
console.error(" Expected skills at: " + sourceDir);
|
|
87494
88339
|
return;
|
|
87495
88340
|
}
|
|
87496
|
-
|
|
88341
|
+
mkdirSync13(AGENTS_SKILLS_DIR, { recursive: true });
|
|
87497
88342
|
for (const skillName of skills) {
|
|
87498
|
-
const srcDir =
|
|
87499
|
-
const srcFile =
|
|
87500
|
-
const destDir =
|
|
87501
|
-
if (!
|
|
88343
|
+
const srcDir = join27(sourceDir, skillName);
|
|
88344
|
+
const srcFile = join27(srcDir, "SKILL.md");
|
|
88345
|
+
const destDir = join27(AGENTS_SKILLS_DIR, skillName);
|
|
88346
|
+
if (!existsSync30(srcFile)) {
|
|
87502
88347
|
console.error(`[mink] skill not found: ${skillName}`);
|
|
87503
88348
|
continue;
|
|
87504
88349
|
}
|
|
87505
|
-
|
|
88350
|
+
mkdirSync13(destDir, { recursive: true });
|
|
87506
88351
|
copyDirRecursive(srcDir, destDir);
|
|
87507
|
-
|
|
87508
|
-
const symlink =
|
|
88352
|
+
mkdirSync13(CLAUDE_SKILLS_DIR, { recursive: true });
|
|
88353
|
+
const symlink = join27(CLAUDE_SKILLS_DIR, skillName);
|
|
87509
88354
|
try {
|
|
87510
|
-
if (
|
|
88355
|
+
if (existsSync30(symlink)) {
|
|
87511
88356
|
if (lstatSync2(symlink).isSymbolicLink() || lstatSync2(symlink).isFile()) {
|
|
87512
|
-
|
|
88357
|
+
unlinkSync4(symlink);
|
|
87513
88358
|
} else {
|
|
87514
88359
|
rmSync(symlink, { recursive: true, force: true });
|
|
87515
88360
|
}
|
|
87516
88361
|
}
|
|
87517
|
-
const relativeTarget =
|
|
88362
|
+
const relativeTarget = join27("..", "..", ".agents", "skills", skillName);
|
|
87518
88363
|
symlinkSync2(relativeTarget, symlink);
|
|
87519
88364
|
} catch {}
|
|
87520
88365
|
console.log(`[mink] installed: ${skillName} -> ${destDir}`);
|
|
@@ -87525,16 +88370,16 @@ function skillInstall(name) {
|
|
|
87525
88370
|
function skillUninstall(name) {
|
|
87526
88371
|
const skills = name ? [name] : getAvailableSkills();
|
|
87527
88372
|
for (const skillName of skills) {
|
|
87528
|
-
const destDir =
|
|
87529
|
-
if (!
|
|
88373
|
+
const destDir = join27(AGENTS_SKILLS_DIR, skillName);
|
|
88374
|
+
if (!existsSync30(destDir)) {
|
|
87530
88375
|
console.log(`[mink] not installed: ${skillName}`);
|
|
87531
88376
|
continue;
|
|
87532
88377
|
}
|
|
87533
88378
|
rmSync(destDir, { recursive: true, force: true });
|
|
87534
|
-
const symlink =
|
|
88379
|
+
const symlink = join27(CLAUDE_SKILLS_DIR, skillName);
|
|
87535
88380
|
try {
|
|
87536
|
-
if (
|
|
87537
|
-
|
|
88381
|
+
if (existsSync30(symlink))
|
|
88382
|
+
unlinkSync4(symlink);
|
|
87538
88383
|
} catch {}
|
|
87539
88384
|
console.log(`[mink] uninstalled: ${skillName}`);
|
|
87540
88385
|
}
|
|
@@ -87548,7 +88393,7 @@ function skillList() {
|
|
|
87548
88393
|
if (installed.length > 0) {
|
|
87549
88394
|
console.log(" Installed:");
|
|
87550
88395
|
for (const s of installed) {
|
|
87551
|
-
console.log(` ${s} (${
|
|
88396
|
+
console.log(` ${s} (${join27(AGENTS_SKILLS_DIR, s)})`);
|
|
87552
88397
|
}
|
|
87553
88398
|
}
|
|
87554
88399
|
if (notInstalled.length > 0) {
|
|
@@ -87567,10 +88412,10 @@ function skillList() {
|
|
|
87567
88412
|
function copyDirRecursive(src, dest) {
|
|
87568
88413
|
const entries = readdirSync8(src, { withFileTypes: true });
|
|
87569
88414
|
for (const entry of entries) {
|
|
87570
|
-
const srcPath =
|
|
87571
|
-
const destPath =
|
|
88415
|
+
const srcPath = join27(src, entry.name);
|
|
88416
|
+
const destPath = join27(dest, entry.name);
|
|
87572
88417
|
if (entry.isDirectory()) {
|
|
87573
|
-
|
|
88418
|
+
mkdirSync13(destPath, { recursive: true });
|
|
87574
88419
|
copyDirRecursive(srcPath, destPath);
|
|
87575
88420
|
} else {
|
|
87576
88421
|
copyFileSync(srcPath, destPath);
|
|
@@ -87579,8 +88424,8 @@ function copyDirRecursive(src, dest) {
|
|
|
87579
88424
|
}
|
|
87580
88425
|
var AGENTS_SKILLS_DIR, CLAUDE_SKILLS_DIR;
|
|
87581
88426
|
var init_skill = __esm(() => {
|
|
87582
|
-
AGENTS_SKILLS_DIR =
|
|
87583
|
-
CLAUDE_SKILLS_DIR =
|
|
88427
|
+
AGENTS_SKILLS_DIR = join27(homedir5(), ".agents", "skills");
|
|
88428
|
+
CLAUDE_SKILLS_DIR = join27(homedir5(), ".claude", "skills");
|
|
87584
88429
|
});
|
|
87585
88430
|
|
|
87586
88431
|
// src/commands/sync.ts
|
|
@@ -87672,6 +88517,70 @@ var init_sync3 = __esm(() => {
|
|
|
87672
88517
|
init_global_config();
|
|
87673
88518
|
});
|
|
87674
88519
|
|
|
88520
|
+
// src/commands/device.ts
|
|
88521
|
+
var exports_device2 = {};
|
|
88522
|
+
__export(exports_device2, {
|
|
88523
|
+
device: () => device
|
|
88524
|
+
});
|
|
88525
|
+
import { hostname as hostname2, platform as platform2 } from "os";
|
|
88526
|
+
function device(args) {
|
|
88527
|
+
const sub = args[0] ?? "status";
|
|
88528
|
+
switch (sub) {
|
|
88529
|
+
case "status": {
|
|
88530
|
+
const id = getOrCreateDeviceId();
|
|
88531
|
+
const devices = listDevices();
|
|
88532
|
+
const current = devices.find((d) => d.id === id);
|
|
88533
|
+
console.log("[mink] device info:");
|
|
88534
|
+
console.log(` id: ${id}`);
|
|
88535
|
+
console.log(` name: ${current?.name ?? hostname2()}`);
|
|
88536
|
+
console.log(` hostname: ${hostname2()}`);
|
|
88537
|
+
console.log(` platform: ${platform2()}`);
|
|
88538
|
+
if (current?.firstSeen) {
|
|
88539
|
+
console.log(` first seen: ${current.firstSeen}`);
|
|
88540
|
+
}
|
|
88541
|
+
if (current?.lastSeen) {
|
|
88542
|
+
console.log(` last seen: ${current.lastSeen}`);
|
|
88543
|
+
}
|
|
88544
|
+
break;
|
|
88545
|
+
}
|
|
88546
|
+
case "list": {
|
|
88547
|
+
const devices = listDevices();
|
|
88548
|
+
const currentId = getOrCreateDeviceId();
|
|
88549
|
+
if (devices.length === 0) {
|
|
88550
|
+
console.log("[mink] no devices registered yet");
|
|
88551
|
+
return;
|
|
88552
|
+
}
|
|
88553
|
+
console.log("[mink] registered devices:");
|
|
88554
|
+
for (const d of devices) {
|
|
88555
|
+
const marker = d.id === currentId ? " (this device)" : "";
|
|
88556
|
+
console.log(` ${d.name}${marker}`);
|
|
88557
|
+
console.log(` id: ${d.id}`);
|
|
88558
|
+
console.log(` hostname: ${d.hostname}`);
|
|
88559
|
+
console.log(` platform: ${d.platform}`);
|
|
88560
|
+
console.log(` last seen: ${d.lastSeen}`);
|
|
88561
|
+
}
|
|
88562
|
+
break;
|
|
88563
|
+
}
|
|
88564
|
+
case "rename": {
|
|
88565
|
+
const name = args.slice(1).join(" ");
|
|
88566
|
+
if (!name) {
|
|
88567
|
+
console.error("Usage: mink device rename <name>");
|
|
88568
|
+
process.exit(1);
|
|
88569
|
+
}
|
|
88570
|
+
setDeviceName(name);
|
|
88571
|
+
console.log(`[mink] device renamed to "${name}"`);
|
|
88572
|
+
break;
|
|
88573
|
+
}
|
|
88574
|
+
default:
|
|
88575
|
+
console.error(`[mink] unknown device subcommand: ${sub}`);
|
|
88576
|
+
console.error("Usage: mink device [status|list|rename <name>]");
|
|
88577
|
+
process.exit(1);
|
|
88578
|
+
}
|
|
88579
|
+
}
|
|
88580
|
+
var init_device2 = __esm(() => {
|
|
88581
|
+
init_device();
|
|
88582
|
+
});
|
|
88583
|
+
|
|
87675
88584
|
// src/commands/bug-search.ts
|
|
87676
88585
|
var exports_bug_search = {};
|
|
87677
88586
|
__export(exports_bug_search, {
|
|
@@ -87713,8 +88622,16 @@ init_fs_utils();
|
|
|
87713
88622
|
init_action_log();
|
|
87714
88623
|
init_vault();
|
|
87715
88624
|
init_note_index();
|
|
87716
|
-
import { mkdirSync as
|
|
88625
|
+
import { mkdirSync as mkdirSync4 } from "fs";
|
|
87717
88626
|
function sessionStart(cwd) {
|
|
88627
|
+
try {
|
|
88628
|
+
const { migrateConfigIfNeeded: migrateConfigIfNeeded2 } = (init_global_config(), __toCommonJS(exports_global_config));
|
|
88629
|
+
migrateConfigIfNeeded2();
|
|
88630
|
+
} catch {}
|
|
88631
|
+
try {
|
|
88632
|
+
const { updateDeviceHeartbeat: updateDeviceHeartbeat2 } = (init_device(), __toCommonJS(exports_device));
|
|
88633
|
+
updateDeviceHeartbeat2();
|
|
88634
|
+
} catch {}
|
|
87718
88635
|
try {
|
|
87719
88636
|
const { isSyncInitialized: isSyncInitialized2, syncPull: syncPull2 } = (init_sync(), __toCommonJS(exports_sync));
|
|
87720
88637
|
if (isSyncInitialized2()) {
|
|
@@ -87722,7 +88639,7 @@ function sessionStart(cwd) {
|
|
|
87722
88639
|
}
|
|
87723
88640
|
} catch {}
|
|
87724
88641
|
const dir = projectDir(cwd);
|
|
87725
|
-
|
|
88642
|
+
mkdirSync4(dir, { recursive: true });
|
|
87726
88643
|
const state = createSessionState();
|
|
87727
88644
|
atomicWriteJson(sessionPath(cwd), state);
|
|
87728
88645
|
try {
|
|
@@ -87751,8 +88668,8 @@ init_token_ledger();
|
|
|
87751
88668
|
init_bug_memory();
|
|
87752
88669
|
init_action_log();
|
|
87753
88670
|
init_vault();
|
|
87754
|
-
import { statSync as statSync2, existsSync as
|
|
87755
|
-
import { join as join6, dirname as
|
|
88671
|
+
import { statSync as statSync2, existsSync as existsSync6, readFileSync as readFileSync7 } from "fs";
|
|
88672
|
+
import { join as join6, dirname as dirname3 } from "path";
|
|
87756
88673
|
function hasActivity(state) {
|
|
87757
88674
|
return Object.keys(state.reads).length > 0 || state.writes.length > 0;
|
|
87758
88675
|
}
|
|
@@ -87783,7 +88700,7 @@ function sessionStop(sessionFile, finalizer, onReminder = (msg) => console.error
|
|
|
87783
88700
|
}
|
|
87784
88701
|
const state = raw;
|
|
87785
88702
|
state.stopCount++;
|
|
87786
|
-
const projDir =
|
|
88703
|
+
const projDir = dirname3(sessionFile);
|
|
87787
88704
|
const effectiveFinalizer = finalizer ?? createLedgerFinalizer(projDir);
|
|
87788
88705
|
if (hasActivity(state)) {
|
|
87789
88706
|
const summary = buildSummary(state);
|
|
@@ -87816,7 +88733,7 @@ function sessionStop(sessionFile, finalizer, onReminder = (msg) => console.error
|
|
|
87816
88733
|
}
|
|
87817
88734
|
const memoryPath = join6(projDir, "learning-memory.md");
|
|
87818
88735
|
const cfgPath = join6(projDir, "config.json");
|
|
87819
|
-
if (
|
|
88736
|
+
if (existsSync6(memoryPath)) {
|
|
87820
88737
|
reflect(projDir, memoryPath, cfgPath);
|
|
87821
88738
|
}
|
|
87822
88739
|
if (isLearningMemoryStale(memoryPath)) {
|
|
@@ -87867,8 +88784,8 @@ function writeSessionToWiki(state, projDir) {
|
|
|
87867
88784
|
}
|
|
87868
88785
|
}
|
|
87869
88786
|
entry.push("");
|
|
87870
|
-
if (
|
|
87871
|
-
const existing =
|
|
88787
|
+
if (existsSync6(sessionFile)) {
|
|
88788
|
+
const existing = readFileSync7(sessionFile, "utf-8");
|
|
87872
88789
|
atomicWriteText(sessionFile, existing.trimEnd() + `
|
|
87873
88790
|
` + entry.join(`
|
|
87874
88791
|
`));
|
|
@@ -87963,6 +88880,11 @@ switch (command2) {
|
|
|
87963
88880
|
await daemon2(cwd, process.argv.slice(3));
|
|
87964
88881
|
break;
|
|
87965
88882
|
}
|
|
88883
|
+
case "channel": {
|
|
88884
|
+
const { channel: channel2 } = await Promise.resolve().then(() => (init_channel(), exports_channel));
|
|
88885
|
+
await channel2(process.argv.slice(3));
|
|
88886
|
+
break;
|
|
88887
|
+
}
|
|
87966
88888
|
case "config": {
|
|
87967
88889
|
const { config: config3 } = await Promise.resolve().then(() => (init_config2(), exports_config));
|
|
87968
88890
|
await config3(process.argv.slice(3));
|
|
@@ -88008,6 +88930,11 @@ switch (command2) {
|
|
|
88008
88930
|
await sync2(process.argv.slice(3));
|
|
88009
88931
|
break;
|
|
88010
88932
|
}
|
|
88933
|
+
case "device": {
|
|
88934
|
+
const { device: device2 } = await Promise.resolve().then(() => (init_device2(), exports_device2));
|
|
88935
|
+
device2(process.argv.slice(3));
|
|
88936
|
+
break;
|
|
88937
|
+
}
|
|
88011
88938
|
case "bug-search": {
|
|
88012
88939
|
const { bugSearch: bugSearch2 } = await Promise.resolve().then(() => (init_bug_search(), exports_bug_search));
|
|
88013
88940
|
bugSearch2(cwd, process.argv.slice(3).join(" "));
|
|
@@ -88027,11 +88954,11 @@ switch (command2) {
|
|
|
88027
88954
|
case "version":
|
|
88028
88955
|
case "--version":
|
|
88029
88956
|
case "-v": {
|
|
88030
|
-
const { resolve: resolve14, dirname:
|
|
88031
|
-
const cliPath = resolve14(
|
|
88032
|
-
const { readFileSync:
|
|
88957
|
+
const { resolve: resolve14, dirname: dirname14 } = await import("path");
|
|
88958
|
+
const cliPath = resolve14(dirname14(new URL(import.meta.url).pathname));
|
|
88959
|
+
const { readFileSync: readFileSync28 } = await import("fs");
|
|
88033
88960
|
try {
|
|
88034
|
-
const pkg = JSON.parse(
|
|
88961
|
+
const pkg = JSON.parse(readFileSync28(resolve14(cliPath, "../package.json"), "utf-8"));
|
|
88035
88962
|
console.log(`mink ${pkg.version}`);
|
|
88036
88963
|
} catch {
|
|
88037
88964
|
console.log("mink (unknown version)");
|
|
@@ -88060,7 +88987,10 @@ switch (command2) {
|
|
|
88060
88987
|
console.log(" note search <term> Full-text search across the vault");
|
|
88061
88988
|
console.log(" skill install Install /mink:note skill for Claude Code");
|
|
88062
88989
|
console.log();
|
|
88063
|
-
console.log("Sync:");
|
|
88990
|
+
console.log("Devices & Sync:");
|
|
88991
|
+
console.log(" device Show current device info");
|
|
88992
|
+
console.log(" device list List all registered devices");
|
|
88993
|
+
console.log(" device rename <name> Set a friendly name for this device");
|
|
88064
88994
|
console.log(" sync Full manual sync (pull then push)");
|
|
88065
88995
|
console.log(" sync init <remote-url> Connect ~/.mink to a git remote for cross-device sync");
|
|
88066
88996
|
console.log(" sync status Show sync state (remote, last sync, pending changes)");
|
|
@@ -88069,6 +88999,13 @@ switch (command2) {
|
|
|
88069
88999
|
console.log(" sync pause / resume Temporarily disable/enable auto-sync");
|
|
88070
89000
|
console.log(" sync disconnect Remove git tracking (data preserved)");
|
|
88071
89001
|
console.log();
|
|
89002
|
+
console.log("Channels (conversational companion):");
|
|
89003
|
+
console.log(" channel setup discord --token <t> Configure Discord bot token");
|
|
89004
|
+
console.log(" channel start [platform] Launch a Claude Code session with --channels in the vault");
|
|
89005
|
+
console.log(" channel stop Stop the channel session");
|
|
89006
|
+
console.log(" channel status Show channel status");
|
|
89007
|
+
console.log(" channel logs Tail channel log");
|
|
89008
|
+
console.log();
|
|
88072
89009
|
console.log("Automation & Analysis:");
|
|
88073
89010
|
console.log(" dashboard [--port=N] Open the real-time web dashboard");
|
|
88074
89011
|
console.log(" daemon <cmd> Manage the background daemon (start|stop|restart|logs)");
|