@starlight-ai/discord-waifus 0.2.1 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -36,15 +36,15 @@ waifus
36
36
  waifus open
37
37
  ```
38
38
 
39
- On first run, `waifus` downloads the GitHub repository archive into `~/Discord-Waifus`, saves that directory as the default project root, runs `pnpm install`, builds the app if needed, initializes local runtime files, and starts the local stack.
39
+ On first run, `waifus` downloads the latest GitHub Release bundle into `~/Discord-Waifus`, saves that directory as the default project root, runs `pnpm install --prod --frozen-lockfile`, initializes local runtime files, and starts the local stack.
40
40
 
41
- ### Refresh an existing archive install
41
+ ### Refresh an existing release-bundle install
42
42
 
43
43
  ```bash
44
44
  waifus update
45
45
  ```
46
46
 
47
- `waifus update` downloads the latest GitHub archive into the existing project root, preserves local runtime data such as `.waifus/`, reinstalls dependencies, rebuilds the app, and restarts the stack if it was already running.
47
+ `waifus update` downloads the latest GitHub Release bundle into the existing project root, preserves local runtime data such as `.waifus/`, reinstalls runtime dependencies, and restarts the stack if it was already running.
48
48
 
49
49
  ### Download from GitHub into a custom directory
50
50
 
@@ -54,6 +54,12 @@ waifus start
54
54
  waifus open
55
55
  ```
56
56
 
57
+ You can also pin a specific GitHub Release:
58
+
59
+ ```bash
60
+ waifus init ~/Discord-Waifus --release app-v0.3.0
61
+ ```
62
+
57
63
  ## Runtime Model
58
64
 
59
65
  - committed defaults live in `defaults/`
package/dist/index.js CHANGED
@@ -1128,46 +1128,57 @@ function resolvePm2Bin() {
1128
1128
  return require3.resolve(path7.join("pm2", "bin", "pm2"));
1129
1129
  }
1130
1130
 
1131
- // src/repo-bootstrap.ts
1131
+ // src/release-bootstrap.ts
1132
+ import { createHash } from "crypto";
1132
1133
  import { promises as fs6 } from "fs";
1133
1134
  import os2 from "os";
1134
1135
  import path8 from "path";
1135
1136
  import { spawn as spawn3 } from "child_process";
1136
- async function bootstrapRepoFromGitHubArchive(targetDir, options = {}) {
1137
+ var APP_RELEASE_ASSET_NAME = "discord-waifus-app.tar.gz";
1138
+ var APP_RELEASE_CHECKSUM_ASSET_NAME = "discord-waifus-app.sha256";
1139
+ var INSTALLED_RELEASE_METADATA = ".waifus-release.json";
1140
+ async function bootstrapReleaseBundleFromGitHub(targetDir, options = {}) {
1137
1141
  const projectRoot = path8.resolve(targetDir);
1138
1142
  await ensureTargetDirectoryIsEmpty(projectRoot);
1139
- const snapshot = await prepareRepoSnapshot(options);
1143
+ const snapshot = await prepareReleaseSnapshot(options);
1140
1144
  try {
1141
1145
  await fs6.mkdir(projectRoot, { recursive: true });
1142
1146
  await copyDirectoryContents(snapshot.extractedRoot, projectRoot);
1143
- return {
1144
- projectRoot,
1145
- sourceRepo: snapshot.sourceRepo,
1146
- sourceRef: snapshot.sourceRef
1147
- };
1147
+ return snapshot.result(projectRoot);
1148
1148
  } finally {
1149
1149
  await snapshot.cleanup();
1150
1150
  }
1151
1151
  }
1152
- async function updateRepoFromGitHubArchive(targetDir, options = {}, updateOptions = {}) {
1152
+ async function updateReleaseBundleFromGitHub(targetDir, options = {}, updateOptions = {}) {
1153
1153
  const projectRoot = path8.resolve(targetDir);
1154
1154
  const stats = await fs6.stat(projectRoot).catch(() => null);
1155
1155
  if (!stats?.isDirectory()) {
1156
1156
  throw new Error(`Project directory does not exist: ${projectRoot}`);
1157
1157
  }
1158
- const snapshot = await prepareRepoSnapshot(options);
1158
+ const snapshot = await prepareReleaseSnapshot(options);
1159
1159
  const preserveEntries = new Set((updateOptions.preserveEntries ?? []).map((entry) => entry.trim()).filter(Boolean));
1160
1160
  try {
1161
1161
  await replaceProjectContents(projectRoot, snapshot.extractedRoot, preserveEntries);
1162
- return {
1163
- projectRoot,
1164
- sourceRepo: snapshot.sourceRepo,
1165
- sourceRef: snapshot.sourceRef
1166
- };
1162
+ return snapshot.result(projectRoot);
1167
1163
  } finally {
1168
1164
  await snapshot.cleanup();
1169
1165
  }
1170
1166
  }
1167
+ async function readInstalledReleaseMetadata(projectRoot) {
1168
+ try {
1169
+ const raw = JSON.parse(
1170
+ await fs6.readFile(path8.join(projectRoot, INSTALLED_RELEASE_METADATA), "utf8")
1171
+ );
1172
+ return {
1173
+ bundleVersion: typeof raw.bundleVersion === "string" && raw.bundleVersion.trim() ? raw.bundleVersion.trim() : null,
1174
+ sourceCommit: typeof raw.sourceCommit === "string" && raw.sourceCommit.trim() ? raw.sourceCommit.trim() : null,
1175
+ generatedAt: typeof raw.generatedAt === "string" && raw.generatedAt.trim() ? raw.generatedAt.trim() : null,
1176
+ repository: typeof raw.repository === "string" && raw.repository.trim() ? raw.repository.trim() : null
1177
+ };
1178
+ } catch {
1179
+ return null;
1180
+ }
1181
+ }
1171
1182
  async function ensureTargetDirectoryIsEmpty(targetDir) {
1172
1183
  try {
1173
1184
  const stats = await fs6.stat(targetDir);
@@ -1186,7 +1197,7 @@ async function ensureTargetDirectoryIsEmpty(targetDir) {
1186
1197
  throw error;
1187
1198
  }
1188
1199
  }
1189
- async function prepareRepoSnapshot(options) {
1200
+ async function prepareReleaseSnapshot(options) {
1190
1201
  const repositoryUrl = options.repo?.trim() || await resolveRepositoryFromPackageMetadata();
1191
1202
  if (!repositoryUrl) {
1192
1203
  throw new Error(
@@ -1200,20 +1211,50 @@ async function prepareRepoSnapshot(options) {
1200
1211
  Only GitHub repositories are supported by waifus init.`
1201
1212
  );
1202
1213
  }
1203
- const ref = options.ref?.trim() || null;
1204
- const archiveUrl = buildGitHubArchiveUrl(githubRepo.owner, githubRepo.repo, ref);
1205
- const tempRoot = await fs6.mkdtemp(path8.join(os2.tmpdir(), "waifus-init-"));
1206
- const archivePath = path8.join(tempRoot, "repo.tar.gz");
1214
+ const releaseTag = options.release?.trim() || null;
1215
+ const release = await fetchGitHubRelease(githubRepo.owner, githubRepo.repo, releaseTag);
1216
+ const assets = Array.isArray(release.assets) ? release.assets : [];
1217
+ const bundleAsset = assets.find((asset) => asset.name === APP_RELEASE_ASSET_NAME);
1218
+ if (!bundleAsset?.browser_download_url) {
1219
+ throw new Error(
1220
+ `GitHub release ${release.tag_name ?? releaseTag ?? "latest"} is missing ${APP_RELEASE_ASSET_NAME}.`
1221
+ );
1222
+ }
1223
+ const checksumAsset = assets.find((asset) => asset.name === APP_RELEASE_CHECKSUM_ASSET_NAME);
1224
+ const tempRoot = await fs6.mkdtemp(path8.join(os2.tmpdir(), "waifus-release-"));
1225
+ const archivePath = path8.join(tempRoot, APP_RELEASE_ASSET_NAME);
1207
1226
  const extractRoot = path8.join(tempRoot, "extract");
1208
1227
  try {
1209
1228
  await fs6.mkdir(extractRoot, { recursive: true });
1210
- await downloadFile(archiveUrl, archivePath);
1229
+ await downloadFile(bundleAsset.browser_download_url, archivePath);
1230
+ if (checksumAsset?.browser_download_url) {
1231
+ const checksumText = await downloadTextFile(checksumAsset.browser_download_url);
1232
+ const expectedChecksum = parseChecksum(checksumText);
1233
+ const actualChecksum = await computeSha256(archivePath);
1234
+ if (expectedChecksum !== actualChecksum) {
1235
+ throw new Error(
1236
+ `Release asset checksum mismatch for ${APP_RELEASE_ASSET_NAME}. Expected ${expectedChecksum}, got ${actualChecksum}.`
1237
+ );
1238
+ }
1239
+ }
1211
1240
  await extractTarGz(archivePath, extractRoot);
1212
1241
  const extractedRoot = await findSingleExtractedRoot(extractRoot);
1242
+ const installedMetadata = await readInstalledReleaseMetadata(extractedRoot);
1243
+ const tagName = typeof release.tag_name === "string" && release.tag_name.trim() ? release.tag_name.trim() : releaseTag ?? "latest";
1244
+ const releaseName = typeof release.name === "string" && release.name.trim() ? release.name.trim() : null;
1245
+ const publishedAt = typeof release.published_at === "string" && release.published_at.trim() ? release.published_at.trim() : null;
1246
+ const sourceRepo = `https://github.com/${githubRepo.owner}/${githubRepo.repo}`;
1213
1247
  return {
1214
1248
  extractedRoot,
1215
- sourceRepo: `https://github.com/${githubRepo.owner}/${githubRepo.repo}`,
1216
- sourceRef: ref,
1249
+ result: (projectRoot) => ({
1250
+ projectRoot,
1251
+ sourceRepo,
1252
+ releaseTag: tagName,
1253
+ releaseName,
1254
+ publishedAt,
1255
+ assetName: APP_RELEASE_ASSET_NAME,
1256
+ bundleVersion: installedMetadata?.bundleVersion ?? null
1257
+ }),
1217
1258
  cleanup: async () => {
1218
1259
  await fs6.rm(tempRoot, { recursive: true, force: true });
1219
1260
  }
@@ -1262,9 +1303,22 @@ function parseGitHubRepository(value) {
1262
1303
  return null;
1263
1304
  }
1264
1305
  }
1265
- function buildGitHubArchiveUrl(owner, repo, ref) {
1266
- const encodedRef = ref ? `/${encodeURIComponent(ref)}` : "";
1267
- return `https://api.github.com/repos/${owner}/${repo}/tarball${encodedRef}`;
1306
+ async function fetchGitHubRelease(owner, repo, releaseTag) {
1307
+ const releasePath = releaseTag ? `releases/tags/${encodeURIComponent(releaseTag)}` : "releases/latest";
1308
+ const response = await fetch(`https://api.github.com/repos/${owner}/${repo}/${releasePath}`, {
1309
+ headers: {
1310
+ Accept: "application/vnd.github+json",
1311
+ "User-Agent": "@starlight-ai/discord-waifus"
1312
+ },
1313
+ redirect: "follow"
1314
+ });
1315
+ if (!response.ok) {
1316
+ if (response.status === 404 && releaseTag) {
1317
+ throw new Error(`GitHub release tag not found: ${releaseTag}`);
1318
+ }
1319
+ throw new Error(`Failed to resolve GitHub release metadata: HTTP ${response.status}`);
1320
+ }
1321
+ return await response.json();
1268
1322
  }
1269
1323
  async function downloadFile(url, destinationPath) {
1270
1324
  const response = await fetch(url, {
@@ -1274,11 +1328,34 @@ async function downloadFile(url, destinationPath) {
1274
1328
  redirect: "follow"
1275
1329
  });
1276
1330
  if (!response.ok) {
1277
- throw new Error(`Failed to download repository archive: HTTP ${response.status}`);
1331
+ throw new Error(`Failed to download release asset: HTTP ${response.status}`);
1278
1332
  }
1279
1333
  const buffer = Buffer.from(await response.arrayBuffer());
1280
1334
  await fs6.writeFile(destinationPath, buffer);
1281
1335
  }
1336
+ async function downloadTextFile(url) {
1337
+ const response = await fetch(url, {
1338
+ headers: {
1339
+ "User-Agent": "@starlight-ai/discord-waifus"
1340
+ },
1341
+ redirect: "follow"
1342
+ });
1343
+ if (!response.ok) {
1344
+ throw new Error(`Failed to download release checksum asset: HTTP ${response.status}`);
1345
+ }
1346
+ return await response.text();
1347
+ }
1348
+ function parseChecksum(value) {
1349
+ const match = value.trim().match(/^([a-f0-9]{64})\b/i);
1350
+ if (!match) {
1351
+ throw new Error(`Invalid checksum format in ${APP_RELEASE_CHECKSUM_ASSET_NAME}.`);
1352
+ }
1353
+ return match[1].toLowerCase();
1354
+ }
1355
+ async function computeSha256(filePath) {
1356
+ const buffer = await fs6.readFile(filePath);
1357
+ return createHash("sha256").update(buffer).digest("hex");
1358
+ }
1282
1359
  async function extractTarGz(archivePath, extractRoot) {
1283
1360
  await spawnQuiet("tar", ["-xzf", archivePath, "-C", extractRoot]);
1284
1361
  }
@@ -1286,7 +1363,7 @@ async function findSingleExtractedRoot(extractRoot) {
1286
1363
  const entries = await fs6.readdir(extractRoot, { withFileTypes: true });
1287
1364
  const directories = entries.filter((entry) => entry.isDirectory());
1288
1365
  if (directories.length !== 1) {
1289
- throw new Error("Repository archive extraction did not produce a single root directory.");
1366
+ throw new Error("Release asset extraction did not produce a single root directory.");
1290
1367
  }
1291
1368
  return path8.join(extractRoot, directories[0].name);
1292
1369
  }
@@ -1419,6 +1496,9 @@ var PNPM_BIN2 = resolveBundledPnpmBin();
1419
1496
  async function spawnPnpm(args, cwd, envOverrides = {}) {
1420
1497
  await spawnPassthrough(process4.execPath, [PNPM_BIN2, ...args], cwd, envOverrides);
1421
1498
  }
1499
+ async function installRuntimeDependencies(projectRoot) {
1500
+ await spawnPnpm(["install", "--prod", "--frozen-lockfile"], projectRoot);
1501
+ }
1422
1502
  cli.option("--project <path>", "Override the project root for this command");
1423
1503
  cli.command("use <projectPath>", "Store the default Discord Waifus project root for future commands").action(async (projectPath) => {
1424
1504
  try {
@@ -1429,26 +1509,25 @@ cli.command("use <projectPath>", "Store the default Discord Waifus project root
1429
1509
  fail(error);
1430
1510
  }
1431
1511
  });
1432
- cli.command("init <targetDir>", "Download the Discord Waifus repo into a target directory and register it").option("--repo <repo>", "GitHub repo URL or owner/repo slug. If omitted, uses the package repository when available.").option("--ref <ref>", "Git ref, branch, or tag to download. Defaults to the repo default branch.").option("--no-install", "Skip pnpm install after download").action(async (targetDir, options) => {
1512
+ cli.command("init <targetDir>", "Download the Discord Waifus release bundle into a target directory and register it").option("--repo <repo>", "GitHub repo URL or owner/repo slug. If omitted, uses the package repository when available.").option("--release <tag>", "GitHub release tag to download. Defaults to the latest GitHub release.").option("--ref <tag>", "Deprecated alias for --release.").option("--no-install", "Skip pnpm install after download").action(async (targetDir, options) => {
1433
1513
  try {
1434
- const result = await bootstrapRepoFromGitHubArchive(targetDir, {
1514
+ const result = await bootstrapReleaseBundleFromGitHub(targetDir, {
1435
1515
  repo: options.repo ?? null,
1436
- ref: options.ref ?? null
1516
+ release: options.release ?? options.ref ?? null
1437
1517
  });
1438
1518
  await assertProjectRoot(result.projectRoot);
1439
1519
  success(`Downloaded project into ${result.projectRoot}`);
1440
- info(`Source: ${result.sourceRepo}${result.sourceRef ? ` @ ${result.sourceRef}` : ""}`);
1520
+ info(formatInstalledRelease(result));
1441
1521
  await saveCliConfig({ defaultProjectRoot: result.projectRoot });
1442
1522
  success(`Default project root saved: ${result.projectRoot}`);
1443
1523
  if (options.install !== false) {
1444
- info("Installing project dependencies with pnpm...");
1445
- await spawnPnpm(["install"], result.projectRoot);
1524
+ info("Installing runtime dependencies with pnpm...");
1525
+ await installRuntimeDependencies(result.projectRoot);
1446
1526
  success("Dependencies installed.");
1447
1527
  } else {
1448
- warn("Skipped pnpm install. Run `pnpm install` inside the project before building.");
1528
+ warn("Skipped pnpm install. Run `pnpm install --prod --frozen-lockfile` inside the project before starting.");
1449
1529
  }
1450
1530
  info("Next steps:");
1451
- info(`- waifus build`);
1452
1531
  info(`- waifus init-config`);
1453
1532
  info(`- waifus start`);
1454
1533
  info(`- waifus update`);
@@ -1456,8 +1535,9 @@ cli.command("init <targetDir>", "Download the Discord Waifus repo into a target
1456
1535
  fail(error);
1457
1536
  }
1458
1537
  });
1459
- cli.command("update", "Refresh the downloaded Discord Waifus project from GitHub and preserve local runtime").option("--repo <repo>", "GitHub repo URL or owner/repo slug. If omitted, uses the package repository when available.").option("--ref <ref>", "Git ref, branch, or tag to download. Defaults to the repo default branch.").action(async (options) => {
1538
+ cli.command("update", "Refresh the downloaded Discord Waifus release bundle from GitHub Releases and preserve local runtime").option("--repo <repo>", "GitHub repo URL or owner/repo slug. If omitted, uses the package repository when available.").option("--release <tag>", "GitHub release tag to download. Defaults to the latest GitHub release.").option("--ref <tag>", "Deprecated alias for --release.").action(async (options) => {
1460
1539
  try {
1540
+ const projectRoot = await requireProjectRoot(cli.options);
1461
1541
  const didSelfUpdate = await maybeSelfUpdateCli({
1462
1542
  packageName: CLI_PACKAGE_NAME,
1463
1543
  currentVersion: CLI_VERSION,
@@ -1469,12 +1549,16 @@ cli.command("update", "Refresh the downloaded Discord Waifus project from GitHub
1469
1549
  });
1470
1550
  if (didSelfUpdate) {
1471
1551
  info("Restarting waifus update with the newly installed CLI...");
1472
- await spawnPassthrough("waifus", process4.argv.slice(2), process4.cwd(), {
1473
- [SKIP_SELF_UPDATE_ENV]: "1"
1474
- });
1552
+ await spawnPassthrough(
1553
+ "waifus",
1554
+ ["--project", projectRoot, ...process4.argv.slice(2)],
1555
+ process4.cwd(),
1556
+ {
1557
+ [SKIP_SELF_UPDATE_ENV]: "1"
1558
+ }
1559
+ );
1475
1560
  return;
1476
1561
  }
1477
- const projectRoot = await requireProjectRoot(cli.options);
1478
1562
  if (await fileExists2(path9.join(projectRoot, ".git"))) {
1479
1563
  throw new Error(
1480
1564
  "This project root is a git clone.\nUse your normal git workflow here instead of `waifus update`."
@@ -1488,24 +1572,21 @@ cli.command("update", "Refresh the downloaded Discord Waifus project from GitHub
1488
1572
  info("Stopping managed services before update...");
1489
1573
  await stopServices();
1490
1574
  }
1491
- const result = await updateRepoFromGitHubArchive(
1575
+ const result = await updateReleaseBundleFromGitHub(
1492
1576
  projectRoot,
1493
1577
  {
1494
1578
  repo: options.repo ?? null,
1495
- ref: options.ref ?? null
1579
+ release: options.release ?? options.ref ?? null
1496
1580
  },
1497
1581
  {
1498
1582
  preserveEntries: [".waifus", "config", "data"]
1499
1583
  }
1500
1584
  );
1501
1585
  success(`Updated project in ${result.projectRoot}`);
1502
- info(`Source: ${result.sourceRepo}${result.sourceRef ? ` @ ${result.sourceRef}` : ""}`);
1503
- info("Installing project dependencies with pnpm...");
1504
- await spawnPnpm(["install"], result.projectRoot);
1586
+ info(formatInstalledRelease(result));
1587
+ info("Installing runtime dependencies with pnpm...");
1588
+ await installRuntimeDependencies(result.projectRoot);
1505
1589
  success("Dependencies installed.");
1506
- info("Building the project...");
1507
- await spawnPnpm(["build"], result.projectRoot);
1508
- success("Build completed.");
1509
1590
  if (hadRunningServices) {
1510
1591
  await startManagedServices(result.projectRoot);
1511
1592
  } else {
@@ -1523,8 +1604,12 @@ cli.command("doctor", "Validate the local setup").action(async () => {
1523
1604
  const configFiles = runtimeConfigFiles(projectRoot);
1524
1605
  const artifactFiles = requiredBuildArtifacts(projectRoot);
1525
1606
  const runtimeState = await inspectRuntimeState(projectRoot);
1607
+ const installedRelease = await readInstalledReleaseMetadata(projectRoot);
1526
1608
  console.log(pc2.bold("waifus doctor"));
1527
1609
  info(`Project root: ${projectRoot}`);
1610
+ if (installedRelease?.bundleVersion) {
1611
+ info(`Installed app release: ${installedRelease.bundleVersion}`);
1612
+ }
1528
1613
  if (Number.isFinite(nodeMajor) && nodeMajor >= 20) {
1529
1614
  success(`Node.js ${process4.versions.node}`);
1530
1615
  } else {
@@ -1601,9 +1686,10 @@ cli.command("doctor", "Validate the local setup").action(async () => {
1601
1686
  fail(error);
1602
1687
  }
1603
1688
  });
1604
- cli.command("build", "Build backend, dashboard, and CLI").action(async () => {
1689
+ cli.command("build", "Build backend and dashboard from source").action(async () => {
1605
1690
  try {
1606
1691
  const projectRoot = await requireProjectRoot(cli.options);
1692
+ await assertBuildableProjectRoot(projectRoot);
1607
1693
  await spawnPnpm(["build"], projectRoot);
1608
1694
  } catch (error) {
1609
1695
  fail(error);
@@ -1857,14 +1943,14 @@ async function runDefaultCommand() {
1857
1943
  async function bootstrapDefaultProjectRoot() {
1858
1944
  const targetDir = path9.join(process4.env.HOME ?? process4.cwd(), DEFAULT_PROJECT_DIRNAME);
1859
1945
  info(`No project configured. Bootstrapping into ${targetDir}`);
1860
- const result = await bootstrapRepoFromGitHubArchive(targetDir, {});
1946
+ const result = await bootstrapReleaseBundleFromGitHub(targetDir, {});
1861
1947
  await assertProjectRoot(result.projectRoot);
1862
1948
  await saveCliConfig({ defaultProjectRoot: result.projectRoot });
1863
1949
  success(`Downloaded project into ${result.projectRoot}`);
1864
- info(`Source: ${result.sourceRepo}${result.sourceRef ? ` @ ${result.sourceRef}` : ""}`);
1950
+ info(formatInstalledRelease(result));
1865
1951
  success(`Default project root saved: ${result.projectRoot}`);
1866
- info("Installing project dependencies with pnpm...");
1867
- await spawnPnpm(["install"], result.projectRoot);
1952
+ info("Installing runtime dependencies with pnpm...");
1953
+ await installRuntimeDependencies(result.projectRoot);
1868
1954
  success("Dependencies installed.");
1869
1955
  return result.projectRoot;
1870
1956
  }
@@ -1882,9 +1968,26 @@ async function ensureBuildArtifacts(projectRoot) {
1882
1968
  if (missingArtifacts.length === 0) {
1883
1969
  return;
1884
1970
  }
1971
+ if (!await hasBuildSources(projectRoot)) {
1972
+ throw new Error(
1973
+ `Missing build artifact(s): ${missingArtifacts.join(", ")}
1974
+ This install uses a prebuilt release bundle. Run: waifus update`
1975
+ );
1976
+ }
1885
1977
  info("Build artifacts missing. Running `waifus build` automatically...");
1886
1978
  await spawnPnpm(["build"], projectRoot);
1887
1979
  }
1980
+ async function hasBuildSources(projectRoot) {
1981
+ return await fileExists2(path9.join(projectRoot, "packages", "backend", "src", "index.ts")) && await fileExists2(path9.join(projectRoot, "packages", "dashboard", "src", "app", "layout.tsx"));
1982
+ }
1983
+ async function assertBuildableProjectRoot(projectRoot) {
1984
+ if (await hasBuildSources(projectRoot)) {
1985
+ return;
1986
+ }
1987
+ throw new Error(
1988
+ "This install is a prebuilt GitHub Release bundle and does not include source code.\nUse: waifus update"
1989
+ );
1990
+ }
1888
1991
  async function startManagedServices(projectRoot) {
1889
1992
  await startServices(projectRoot);
1890
1993
  success("Started waifus-backend and waifus-dashboard through PM2.");
@@ -1893,6 +1996,16 @@ async function startManagedServices(projectRoot) {
1893
1996
  warn("These services are local to this machine.");
1894
1997
  info("If you edit config on disk, apply it with: waifus restart");
1895
1998
  }
1999
+ function formatInstalledRelease(result) {
2000
+ const details = [`Release: ${result.sourceRepo} @ ${result.releaseTag}`];
2001
+ if (result.bundleVersion) {
2002
+ details.push(`bundle ${result.bundleVersion}`);
2003
+ }
2004
+ if (result.publishedAt) {
2005
+ details.push(`published ${result.publishedAt}`);
2006
+ }
2007
+ return details.join(" | ");
2008
+ }
1896
2009
  function findEnvReferences(value) {
1897
2010
  const references = [];
1898
2011
  visit(value, (candidate) => {
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/config-store.ts","../src/project-root.ts","../src/command-utils.ts","../src/runtime-layout.ts","../src/open-url.ts","../src/local-config-migrator.ts","../src/pm2-manager.ts","../src/pnpm-bin.ts","../src/service-env.ts","../src/repo-bootstrap.ts","../src/cli-self-update.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport path from \"node:path\";\nimport process from \"node:process\";\nimport { spawnSync } from \"node:child_process\";\nimport { promises as fs } from \"node:fs\";\nimport { createRequire } from \"node:module\";\nimport { cac } from \"cac\";\nimport { parse as parseToml } from \"smol-toml\";\nimport pc from \"picocolors\";\nimport { saveCliConfig } from \"./config-store.js\";\nimport { assertProjectRoot, resolveProjectRoot } from \"./project-root.js\";\nimport {\n fileExists,\n GlobalOptions,\n info,\n readJsonFile,\n requiredBuildArtifacts,\n requireProjectRoot,\n runtimeConfigFiles,\n spawnPassthrough,\n success,\n warn\n} from \"./command-utils.js\";\nimport { openUrl } from \"./open-url.js\";\nimport {\n bootstrapLocalRuntime,\n getRuntimeLayoutPaths,\n hasLegacyLiveConfig,\n inspectRuntimeState,\n localRuntimeFiles\n} from \"./runtime-layout.js\";\nimport { migrateLocalConfig } from \"./local-config-migrator.js\";\nimport {\n getPm2LogCommand,\n listManagedServices,\n restartServices,\n startServices,\n stopServices\n} from \"./pm2-manager.js\";\nimport { bootstrapRepoFromGitHubArchive, updateRepoFromGitHubArchive } from \"./repo-bootstrap.js\";\nimport { resolveBundledPnpmBin } from \"./pnpm-bin.js\";\nimport { getServiceEnv } from \"./service-env.js\";\nimport { maybeSelfUpdateCli } from \"./cli-self-update.js\";\n\nconst cli = cac(\"waifus\");\nconst DEFAULT_PROJECT_DIRNAME = \"Discord-Waifus\";\nconst require = createRequire(import.meta.url);\nconst packageJson = require(\"../package.json\") as { name?: string; version?: string };\nconst CLI_PACKAGE_NAME = packageJson.name ?? \"@starlight-ai/discord-waifus\";\nconst CLI_VERSION = packageJson.version ?? \"0.0.0\";\nconst SKIP_SELF_UPDATE_ENV = \"WAIFUS_SKIP_SELF_UPDATE\";\n\n// Resolve the pnpm bundled as a dependency of this CLI so users don't need it\n// globally on their PATH. We resolve pnpm's exported package entry first and\n// then derive the bin path to avoid Node 25+ export-subpath restrictions.\nconst PNPM_BIN = resolveBundledPnpmBin();\n\nasync function spawnPnpm(\n args: string[],\n cwd: string,\n envOverrides: Record<string, string> = {}\n): Promise<void> {\n await spawnPassthrough(process.execPath, [PNPM_BIN, ...args], cwd, envOverrides);\n}\n\ncli.option(\"--project <path>\", \"Override the project root for this command\");\n\ncli\n .command(\"use <projectPath>\", \"Store the default Discord Waifus project root for future commands\")\n .action(async (projectPath: string) => {\n try {\n const resolvedRoot = await assertProjectRoot(projectPath);\n await saveCliConfig({ defaultProjectRoot: resolvedRoot });\n console.log(pc.green(`Default project root saved: ${resolvedRoot}`));\n } catch (error) {\n fail(error);\n }\n });\n\ncli\n .command(\"init <targetDir>\", \"Download the Discord Waifus repo into a target directory and register it\")\n .option(\"--repo <repo>\", \"GitHub repo URL or owner/repo slug. If omitted, uses the package repository when available.\")\n .option(\"--ref <ref>\", \"Git ref, branch, or tag to download. Defaults to the repo default branch.\")\n .option(\"--no-install\", \"Skip pnpm install after download\")\n .action(async (targetDir: string, options: { repo?: string; ref?: string; install?: boolean }) => {\n try {\n const result = await bootstrapRepoFromGitHubArchive(targetDir, {\n repo: options.repo ?? null,\n ref: options.ref ?? null\n });\n await assertProjectRoot(result.projectRoot);\n\n success(`Downloaded project into ${result.projectRoot}`);\n info(`Source: ${result.sourceRepo}${result.sourceRef ? ` @ ${result.sourceRef}` : \"\"}`);\n\n await saveCliConfig({ defaultProjectRoot: result.projectRoot });\n success(`Default project root saved: ${result.projectRoot}`);\n\n if (options.install !== false) {\n info(\"Installing project dependencies with pnpm...\");\n await spawnPnpm([\"install\"], result.projectRoot);\n success(\"Dependencies installed.\");\n } else {\n warn(\"Skipped pnpm install. Run `pnpm install` inside the project before building.\");\n }\n\n info(\"Next steps:\");\n info(`- waifus build`);\n info(`- waifus init-config`);\n info(`- waifus start`);\n info(`- waifus update`);\n } catch (error) {\n fail(error);\n }\n });\n\ncli\n .command(\"update\", \"Refresh the downloaded Discord Waifus project from GitHub and preserve local runtime\")\n .option(\"--repo <repo>\", \"GitHub repo URL or owner/repo slug. If omitted, uses the package repository when available.\")\n .option(\"--ref <ref>\", \"Git ref, branch, or tag to download. Defaults to the repo default branch.\")\n .action(async (options: { repo?: string; ref?: string }) => {\n try {\n const didSelfUpdate = await maybeSelfUpdateCli({\n packageName: CLI_PACKAGE_NAME,\n currentVersion: CLI_VERSION,\n cwd: process.cwd(),\n info,\n success,\n warn,\n skip: process.env[SKIP_SELF_UPDATE_ENV] === \"1\"\n });\n\n if (didSelfUpdate) {\n info(\"Restarting waifus update with the newly installed CLI...\");\n await spawnPassthrough(\"waifus\", process.argv.slice(2), process.cwd(), {\n [SKIP_SELF_UPDATE_ENV]: \"1\"\n });\n return;\n }\n\n const projectRoot = await requireProjectRoot(cli.options as GlobalOptions);\n\n if (await fileExists(path.join(projectRoot, \".git\"))) {\n throw new Error(\n \"This project root is a git clone.\\nUse your normal git workflow here instead of `waifus update`.\"\n );\n }\n\n const services = await listManagedServices();\n const hadRunningServices = services.some(\n (service) => service.cwd === projectRoot && service.status === \"online\"\n );\n\n if (hadRunningServices) {\n info(\"Stopping managed services before update...\");\n await stopServices();\n }\n\n const result = await updateRepoFromGitHubArchive(\n projectRoot,\n {\n repo: options.repo ?? null,\n ref: options.ref ?? null\n },\n {\n preserveEntries: [\".waifus\", \"config\", \"data\"]\n }\n );\n\n success(`Updated project in ${result.projectRoot}`);\n info(`Source: ${result.sourceRepo}${result.sourceRef ? ` @ ${result.sourceRef}` : \"\"}`);\n\n info(\"Installing project dependencies with pnpm...\");\n await spawnPnpm([\"install\"], result.projectRoot);\n success(\"Dependencies installed.\");\n\n info(\"Building the project...\");\n await spawnPnpm([\"build\"], result.projectRoot);\n success(\"Build completed.\");\n\n if (hadRunningServices) {\n await startManagedServices(result.projectRoot);\n } else {\n info(\"Run `waifus start` when you want to launch the stack.\");\n }\n } catch (error) {\n fail(error);\n }\n });\n\ncli\n .command(\"doctor\", \"Validate the local setup\")\n .action(async () => {\n try {\n const projectRoot = await requireProjectRoot(cli.options as GlobalOptions);\n const nodeMajor = Number.parseInt(process.versions.node.split(\".\")[0] ?? \"0\", 10);\n const pnpmVersion = spawnSync(process.execPath, [PNPM_BIN, \"--version\"], { encoding: \"utf8\" });\n const configFiles = runtimeConfigFiles(projectRoot);\n const artifactFiles = requiredBuildArtifacts(projectRoot);\n const runtimeState = await inspectRuntimeState(projectRoot);\n\n console.log(pc.bold(\"waifus doctor\"));\n info(`Project root: ${projectRoot}`);\n\n if (Number.isFinite(nodeMajor) && nodeMajor >= 20) {\n success(`Node.js ${process.versions.node}`);\n } else {\n warn(`Node.js ${process.versions.node} detected. Recommended: Node.js 20+`);\n }\n\n if (pnpmVersion.status === 0) {\n success(`pnpm ${pnpmVersion.stdout.trim()} (bundled)`);\n } else {\n warn(\"Bundled pnpm failed to run. Try reinstalling: npm install -g @starlight-ai/discord-waifus\");\n }\n\n if (runtimeState.isCanonicalLocalRuntime) {\n success(\"Canonical local runtime detected: .waifus/\");\n } else if (runtimeState.isMigrationPending) {\n warn(\"Migration pending: legacy config still takes precedence until import completes.\");\n } else if (runtimeState.legacyLiveExists) {\n warn(\"Legacy runtime detected. Local .waifus/ bootstrap is blocked until migration.\");\n } else {\n warn(\"Local runtime not initialized. Run: waifus init-config\");\n }\n\n for (const configFile of configFiles) {\n if (await fileExists(configFile)) {\n success(`Config present: ${path.relative(projectRoot, configFile)}`);\n } else {\n warn(`Missing config: ${path.relative(projectRoot, configFile)} (run: waifus init-config)`);\n }\n }\n\n for (const artifactFile of artifactFiles) {\n if (await fileExists(artifactFile)) {\n success(`Build artifact present: ${path.relative(projectRoot, artifactFile)}`);\n } else {\n warn(`Build artifact missing: ${path.relative(projectRoot, artifactFile)}`);\n }\n }\n\n const filesToScan =\n runtimeState.isCanonicalLocalRuntime || (runtimeState.runtimeRootExists && !runtimeState.legacyLiveExists)\n ? [\n ...localRuntimeFiles(projectRoot),\n ...(await listWaifuDocumentFiles(projectRoot))\n ]\n : [\n ...legacyConfigFiles(projectRoot)\n ];\n\n for (const configFile of filesToScan) {\n if (!(await fileExists(configFile))) {\n continue;\n }\n\n const configValue = await readConfigFile(configFile);\n if (configValue === null) {\n warn(`Could not parse config: ${path.relative(projectRoot, configFile)}`);\n continue;\n }\n\n for (const envReference of findEnvReferences(configValue)) {\n if (process.env[envReference.variableName]) {\n success(\n `Environment value resolved for ${envReference.variableName} in ${path.relative(projectRoot, configFile)}`\n );\n } else {\n warn(\n `Unresolved ${envReference.raw} in ${path.relative(projectRoot, configFile)}. Export ${envReference.variableName} before start.`\n );\n }\n }\n\n if (\n configFile.endsWith(path.join(\".waifus\", \"orchestrator.toml\")) ||\n configFile.endsWith(path.join(\"config\", \"orchestrator.json\"))\n ) {\n const orchestrator =\n \"orchestrator\" in (configValue as Record<string, unknown>)\n ? ((configValue as { orchestrator?: { providerId?: string; provider_id?: string; model?: string } }).orchestrator ?? {})\n : {};\n const providerValue =\n typeof (orchestrator as { providerId?: string }).providerId === \"string\"\n ? (orchestrator as { providerId?: string }).providerId\n : typeof (orchestrator as { provider_id?: string }).provider_id === \"string\"\n ? (orchestrator as { provider_id?: string }).provider_id\n : \"\";\n const modelValue =\n typeof (orchestrator as { model?: string }).model === \"string\"\n ? (orchestrator as { model?: string }).model\n : \"\";\n\n if (\n providerValue === \"configure-me\" ||\n providerValue === \"\" ||\n modelValue === \"configure-me\" ||\n modelValue === \"\"\n ) {\n warn(\"Orchestrator config is still unconfigured. Update it in the dashboard before relying on orchestration.\");\n }\n }\n }\n\n if (runtimeState.runtimeRootExists && runtimeState.migrationState) {\n info(`Migration state: ${runtimeState.migrationState.status}`);\n }\n\n info(\"If you edit config on disk, apply it with: waifus restart\");\n } catch (error) {\n fail(error);\n }\n });\n\ncli.command(\"build\", \"Build backend, dashboard, and CLI\").action(async () => {\n try {\n const projectRoot = await requireProjectRoot(cli.options as GlobalOptions);\n await spawnPnpm([\"build\"], projectRoot);\n } catch (error) {\n fail(error);\n }\n });\n\ncli\n .command(\"init-config\", \"Create or repair the local .waifus runtime layout from defaults/\")\n .option(\"--force\", \"Reserved for future explicit empty-bootstrap overrides\")\n .action(async () => {\n try {\n const projectRoot = await requireProjectRoot(cli.options as GlobalOptions);\n const legacyLiveExists = await hasLegacyLiveConfig(projectRoot);\n const runtimeState = await inspectRuntimeState(projectRoot);\n\n if (legacyLiveExists && runtimeState.migrationState?.status !== \"import_completed\") {\n throw new Error(\"Legacy live config still exists. Run: waifus migrate-local-config\");\n }\n\n const written = await bootstrapLocalRuntime(projectRoot);\n if (written.length === 0) {\n info(\"Local runtime layout already satisfied.\");\n } else {\n for (const filePath of written) {\n success(`Wrote ${path.relative(projectRoot, filePath)}`);\n }\n }\n\n info(\"Finish configuration in the dashboard after start.\");\n info(\"If you later edit config on disk, apply it with: waifus restart\");\n } catch (error) {\n fail(error);\n }\n });\n\ncli\n .command(\"migrate-local-config\", \"Import legacy config/*.json runtime data into the local .waifus layout\")\n .action(async () => {\n try {\n const projectRoot = await requireProjectRoot(cli.options as GlobalOptions);\n const result = await migrateLocalConfig(projectRoot);\n\n success(`Imported legacy runtime into .waifus/ (${result.written.length} files written).`);\n if (Object.keys(result.idMap).some((legacyId) => legacyId !== result.idMap[legacyId])) {\n info(\"Sanitized waifu IDs:\");\n for (const [legacyId, nextId] of Object.entries(result.idMap)) {\n if (legacyId === nextId) {\n continue;\n }\n info(`- ${legacyId} -> ${nextId}`);\n }\n }\n if (result.warningCount > 0) {\n warn(\n `Migration completed with ${result.warningCount} warning(s). Review ${path.relative(projectRoot, getRuntimeLayoutPaths(projectRoot).migrationWarningsFile)}`\n );\n } else {\n success(\"Migration warnings: none\");\n }\n info(\"Legacy files were left untouched. After reviewing the import, apply it with: waifus restart\");\n } catch (error) {\n fail(error);\n }\n });\n\ncli\n .command(\"start\", \"Start backend and dashboard under PM2\")\n .action(async () => {\n try {\n const projectRoot = await requireProjectRootForStart(cli.options as GlobalOptions);\n await assertNoPendingLegacyMigration(projectRoot);\n await ensureBuildArtifacts(projectRoot);\n await startManagedServices(projectRoot);\n } catch (error) {\n fail(error);\n }\n });\n\ncli.command(\"stop\", \"Stop PM2-managed backend and dashboard\").action(async () => {\n try {\n await requireProjectRoot(cli.options as GlobalOptions);\n await stopServices();\n success(\"Stopped waifus-backend and waifus-dashboard.\");\n } catch (error) {\n fail(error);\n }\n});\n\ncli\n .command(\"restart\", \"Restart PM2-managed backend and dashboard\")\n .action(async () => {\n try {\n const projectRoot = await requireProjectRoot(cli.options as GlobalOptions);\n await assertNoPendingLegacyMigration(projectRoot);\n for (const artifactFile of requiredBuildArtifacts(projectRoot)) {\n if (!(await fileExists(artifactFile))) {\n throw new Error(\n `Missing build artifact: ${path.relative(projectRoot, artifactFile)}\\nRun: waifus build`\n );\n }\n }\n\n await restartServices(projectRoot);\n success(\"Restarted waifus-backend and waifus-dashboard.\");\n info(\"Local dashboard: http://localhost:3000\");\n info(\"Local backend: http://127.0.0.1:4000\");\n warn(\"These services are local to this machine.\");\n info(\"Config changes on disk are now applied.\");\n } catch (error) {\n fail(error);\n }\n });\n\ncli.command(\"status\", \"Show PM2 service status\").action(async () => {\n try {\n await requireProjectRoot(cli.options as GlobalOptions);\n const services = await listManagedServices();\n\n console.log(pc.bold(\"waifus status\"));\n if (services.length === 0) {\n warn(\"No managed waifus PM2 services found.\");\n } else {\n for (const service of services) {\n console.log(\n [\n `- ${service.name}`,\n ` status: ${service.status}`,\n ` cwd: ${service.cwd ?? \"unknown\"}`,\n ` pid: ${service.pid ?? \"not running\"}`,\n ` restarts: ${service.restartCount}`,\n ` uptimeMs: ${service.uptimeMs ?? \"unknown\"}`\n ].join(\"\\n\")\n );\n }\n }\n\n try {\n const response = await fetch(\"http://127.0.0.1:4000/api/status\");\n if (response.ok) {\n const payload = (await response.json()) as { uptimeSeconds?: number };\n info(`Backend health: reachable on 127.0.0.1:4000 (uptimeSeconds=${payload.uptimeSeconds ?? \"unknown\"})`);\n } else {\n warn(`Backend health check returned HTTP ${response.status}`);\n }\n } catch {\n warn(\"Backend health: not reachable on 127.0.0.1:4000\");\n }\n\n warn(\"These services are local to this machine.\");\n } catch (error) {\n fail(error);\n }\n});\n\ncli\n .command(\"logs [service]\", \"Tail PM2 logs for backend, dashboard, or both\")\n .option(\"--lines <count>\", \"How many recent lines to include\", { default: \"100\" })\n .action(async (service: string | undefined, options: { lines: string }) => {\n try {\n await requireProjectRoot(cli.options as GlobalOptions);\n const normalizedService =\n service === \"backend\" || service === \"dashboard\" ? service : service ? null : null;\n\n if (service && !normalizedService) {\n throw new Error(\"Invalid service. Use: waifus logs | waifus logs backend | waifus logs dashboard\");\n }\n\n const lineCount = Number.parseInt(options.lines, 10);\n if (!Number.isFinite(lineCount) || lineCount <= 0) {\n throw new Error(\"Invalid --lines value. Use a positive integer.\");\n }\n\n const logCommand = getPm2LogCommand(normalizedService, lineCount);\n await spawnPassthrough(logCommand.command, logCommand.args, process.cwd());\n } catch (error) {\n fail(error);\n }\n });\n\ncli.command(\"open\", \"Open the local dashboard in the browser\").action(async () => {\n try {\n await requireProjectRoot(cli.options as GlobalOptions);\n await openUrl(\"http://localhost:3000\");\n success(\"Opened http://localhost:3000\");\n } catch (error) {\n fail(error);\n }\n});\n\ncli\n .command(\"run <service>\", \"Run backend or dashboard in the foreground\")\n .action(async (service: string) => {\n try {\n const projectRoot = await requireProjectRoot(cli.options as GlobalOptions);\n if (service !== \"backend\" && service !== \"dashboard\") {\n throw new Error(\"Invalid service. Use: waifus run backend | waifus run dashboard\");\n }\n\n const filterTarget = service === \"backend\" ? \"backend\" : \"dashboard\";\n await spawnPnpm([\"--filter\", filterTarget, \"start\"], projectRoot, getServiceEnv(service));\n } catch (error) {\n fail(error);\n }\n });\n\ncli.help();\ncli.version(CLI_VERSION);\n\nif (process.argv.length <= 2) {\n runDefaultCommand().catch(fail);\n} else {\n cli.parse(process.argv);\n}\n\nfunction fail(error: unknown): never {\n const message = error instanceof Error ? error.message : \"Unknown CLI error\";\n console.error(pc.red(message));\n process.exit(1);\n}\n\nasync function listWaifuDocumentFiles(projectRoot: string): Promise<string[]> {\n const paths = getRuntimeLayoutPaths(projectRoot);\n try {\n const entries = await fs.readdir(paths.runtimeWaifusRoot, { withFileTypes: true });\n return entries\n .filter((entry) => entry.isFile() && entry.name.endsWith(\".json\"))\n .map((entry) => path.join(paths.runtimeWaifusRoot, entry.name));\n } catch {\n return [];\n }\n}\n\nfunction legacyConfigFiles(projectRoot: string): string[] {\n const paths = getRuntimeLayoutPaths(projectRoot);\n return [\n paths.legacyWaifusFile,\n paths.legacyProvidersFile,\n paths.legacyChannelsFile,\n paths.legacyOrchestratorFile,\n paths.legacyStageManagerFile\n ];\n}\n\nasync function readConfigFile(filePath: string): Promise<unknown | null> {\n try {\n if (filePath.endsWith(\".json\")) {\n return await readJsonFile(filePath);\n }\n\n if (filePath.endsWith(\".toml\")) {\n return parseToml(await fs.readFile(filePath, \"utf8\"));\n }\n\n return null;\n } catch {\n return null;\n }\n}\n\nasync function assertNoPendingLegacyMigration(projectRoot: string): Promise<void> {\n const runtimeState = await inspectRuntimeState(projectRoot);\n if (runtimeState.legacyLiveExists && runtimeState.migrationState?.status !== \"import_completed\") {\n throw new Error(\"Legacy live config still exists. Run: waifus migrate-local-config\");\n }\n}\n\nasync function requireProjectRootForStart(options: GlobalOptions): Promise<string> {\n const resolvedProjectRoot = await resolveProjectRoot({\n cwd: process.cwd(),\n explicitProjectRoot: options.project ?? null\n });\n\n if (resolvedProjectRoot) {\n return resolvedProjectRoot;\n }\n\n if (options.project) {\n throw new Error(`No valid project root found at ${options.project}`);\n }\n\n return bootstrapDefaultProjectRoot();\n}\n\nasync function runDefaultCommand(): Promise<void> {\n const options = cli.options as GlobalOptions;\n const projectRoot = await requireProjectRootForStart(options);\n await assertNoPendingLegacyMigration(projectRoot);\n\n if (!(await hasCanonicalRuntime(projectRoot))) {\n info(\"Initializing local runtime...\");\n const written = await bootstrapLocalRuntime(projectRoot);\n if (written.length === 0) {\n info(\"Local runtime already initialized.\");\n } else {\n for (const filePath of written) {\n success(`Wrote ${path.relative(projectRoot, filePath)}`);\n }\n }\n }\n\n await ensureBuildArtifacts(projectRoot);\n await startManagedServices(projectRoot);\n}\n\nasync function bootstrapDefaultProjectRoot(): Promise<string> {\n const targetDir = path.join(process.env.HOME ?? process.cwd(), DEFAULT_PROJECT_DIRNAME);\n info(`No project configured. Bootstrapping into ${targetDir}`);\n\n const result = await bootstrapRepoFromGitHubArchive(targetDir, {});\n await assertProjectRoot(result.projectRoot);\n await saveCliConfig({ defaultProjectRoot: result.projectRoot });\n\n success(`Downloaded project into ${result.projectRoot}`);\n info(`Source: ${result.sourceRepo}${result.sourceRef ? ` @ ${result.sourceRef}` : \"\"}`);\n success(`Default project root saved: ${result.projectRoot}`);\n\n info(\"Installing project dependencies with pnpm...\");\n await spawnPnpm([\"install\"], result.projectRoot);\n success(\"Dependencies installed.\");\n\n return result.projectRoot;\n}\n\nasync function hasCanonicalRuntime(projectRoot: string): Promise<boolean> {\n const runtimeState = await inspectRuntimeState(projectRoot);\n return runtimeState.isCanonicalLocalRuntime;\n}\n\nasync function ensureBuildArtifacts(projectRoot: string): Promise<void> {\n const missingArtifacts = [];\n\n for (const artifactFile of requiredBuildArtifacts(projectRoot)) {\n if (!(await fileExists(artifactFile))) {\n missingArtifacts.push(path.relative(projectRoot, artifactFile));\n }\n }\n\n if (missingArtifacts.length === 0) {\n return;\n }\n\n info(\"Build artifacts missing. Running `waifus build` automatically...\");\n await spawnPnpm([\"build\"], projectRoot);\n}\n\nasync function startManagedServices(projectRoot: string): Promise<void> {\n await startServices(projectRoot);\n success(\"Started waifus-backend and waifus-dashboard through PM2.\");\n info(\"Local dashboard: http://localhost:3000\");\n info(\"Local backend: http://127.0.0.1:4000\");\n warn(\"These services are local to this machine.\");\n info(\"If you edit config on disk, apply it with: waifus restart\");\n}\n\nfunction findEnvReferences(value: unknown): Array<{ raw: string; variableName: string }> {\n const references: Array<{ raw: string; variableName: string }> = [];\n\n visit(value, (candidate) => {\n if (typeof candidate !== \"string\") {\n return;\n }\n\n const envPrefixMatch = candidate.match(/^env:([A-Z0-9_]+)$/i);\n if (envPrefixMatch) {\n references.push({\n raw: candidate,\n variableName: envPrefixMatch[1]\n });\n return;\n }\n\n const templateMatch = candidate.match(/^\\$\\{([A-Z0-9_]+)\\}$/i);\n if (templateMatch) {\n references.push({\n raw: candidate,\n variableName: templateMatch[1]\n });\n }\n });\n\n return references;\n}\n\nfunction visit(value: unknown, callback: (candidate: unknown) => void): void {\n callback(value);\n if (Array.isArray(value)) {\n for (const entry of value) {\n visit(entry, callback);\n }\n return;\n }\n\n if (value && typeof value === \"object\") {\n for (const entry of Object.values(value)) {\n visit(entry, callback);\n }\n }\n}\n","import { promises as fs } from \"node:fs\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport { z } from \"zod\";\n\nconst cliConfigSchema = z.object({\n defaultProjectRoot: z.string().min(1).nullable().default(null)\n});\n\nexport type CliConfig = z.infer<typeof cliConfigSchema>;\n\nexport function getCliConfigPath(): string {\n const configHome = process.env.WAIFUS_CONFIG_HOME?.trim();\n if (configHome) {\n return path.resolve(configHome, \"config.json\");\n }\n\n return path.join(os.homedir(), \".config\", \"waifus\", \"config.json\");\n}\n\nexport async function loadCliConfig(): Promise<CliConfig> {\n const filePath = getCliConfigPath();\n\n try {\n const raw = await fs.readFile(filePath, \"utf8\");\n return cliConfigSchema.parse(JSON.parse(raw));\n } catch (error) {\n const code = (error as NodeJS.ErrnoException | undefined)?.code;\n if (code === \"ENOENT\") {\n return cliConfigSchema.parse({});\n }\n throw error;\n }\n}\n\nexport async function saveCliConfig(nextConfig: CliConfig): Promise<void> {\n const filePath = getCliConfigPath();\n await fs.mkdir(path.dirname(filePath), { recursive: true });\n await fs.writeFile(filePath, `${JSON.stringify(cliConfigSchema.parse(nextConfig), null, 2)}\\n`, \"utf8\");\n}\n","import { promises as fs } from \"node:fs\";\nimport path from \"node:path\";\nimport { loadCliConfig } from \"./config-store.js\";\n\nconst projectMarkers = [\n \"package.json\",\n \"pnpm-workspace.yaml\",\n path.join(\"packages\", \"backend\"),\n path.join(\"packages\", \"dashboard\"),\n \"defaults\"\n];\n\nexport interface ResolveProjectRootOptions {\n cwd?: string;\n explicitProjectRoot?: string | null;\n}\n\nexport async function isValidProjectRoot(projectRoot: string): Promise<boolean> {\n const resolvedRoot = path.resolve(projectRoot);\n\n for (const marker of projectMarkers) {\n try {\n await fs.access(path.join(resolvedRoot, marker));\n } catch {\n return false;\n }\n }\n\n return true;\n}\n\nexport async function resolveProjectRoot(\n options: ResolveProjectRootOptions = {}\n): Promise<string | null> {\n const cwd = path.resolve(options.cwd ?? process.cwd());\n const explicitProjectRoot = options.explicitProjectRoot ? path.resolve(options.explicitProjectRoot) : null;\n\n if (explicitProjectRoot && (await isValidProjectRoot(explicitProjectRoot))) {\n return explicitProjectRoot;\n }\n\n const config = await loadCliConfig();\n if (config.defaultProjectRoot && (await isValidProjectRoot(config.defaultProjectRoot))) {\n return path.resolve(config.defaultProjectRoot);\n }\n\n for (const candidate of walkParentDirectories(cwd)) {\n if (await isValidProjectRoot(candidate)) {\n return candidate;\n }\n }\n\n return null;\n}\n\nexport async function assertProjectRoot(projectRoot: string): Promise<string> {\n const resolvedRoot = path.resolve(projectRoot);\n if (!(await isValidProjectRoot(resolvedRoot))) {\n throw new Error(\n `Invalid Discord Waifus project root: ${resolvedRoot}\\nExpected: package.json, pnpm-workspace.yaml, packages/backend/, packages/dashboard/, and defaults/`\n );\n }\n return resolvedRoot;\n}\n\nfunction* walkParentDirectories(start: string): Generator<string> {\n let current = start;\n\n while (true) {\n yield current;\n const parent = path.dirname(current);\n if (parent === current) {\n return;\n }\n current = parent;\n }\n}\n","import { promises as fs } from \"node:fs\";\nimport path from \"node:path\";\nimport process from \"node:process\";\nimport { spawn } from \"node:child_process\";\nimport pc from \"picocolors\";\nimport { resolveProjectRoot } from \"./project-root.js\";\nimport { defaultSeedFiles, localRuntimeFiles } from \"./runtime-layout.js\";\n\nexport interface GlobalOptions {\n project?: string;\n}\n\nexport async function requireProjectRoot(options: GlobalOptions): Promise<string> {\n const projectRoot = await resolveProjectRoot({\n cwd: process.cwd(),\n explicitProjectRoot: options.project ?? null\n });\n\n if (!projectRoot) {\n throw new Error(\"No project root is configured.\\nRun: waifus use /path/to/Discord-Waifus\");\n }\n\n return projectRoot;\n}\n\nexport function runtimeConfigFiles(projectRoot: string): string[] {\n return [...defaultSeedFiles(projectRoot), ...localRuntimeFiles(projectRoot)];\n}\n\nexport function requiredBuildArtifacts(projectRoot: string): string[] {\n return [\n path.join(projectRoot, \"packages\", \"backend\", \"dist\", \"index.js\"),\n path.join(projectRoot, \"packages\", \"dashboard\", \".next\", \"BUILD_ID\")\n ];\n}\n\nexport async function fileExists(filePath: string): Promise<boolean> {\n try {\n await fs.access(filePath);\n return true;\n } catch {\n return false;\n }\n}\n\nexport async function readJsonFile(filePath: string): Promise<unknown> {\n return JSON.parse(await fs.readFile(filePath, \"utf8\"));\n}\n\nexport async function spawnPassthrough(\n command: string,\n args: string[],\n cwd: string,\n envOverrides: Record<string, string> = {}\n): Promise<void> {\n await new Promise<void>((resolve, reject) => {\n const child = spawn(command, args, {\n cwd,\n stdio: \"inherit\",\n env: {\n ...process.env,\n ...envOverrides\n }\n });\n\n child.once(\"error\", reject);\n child.once(\"exit\", (code, signal) => {\n if (signal) {\n reject(new Error(`${command} exited due to signal ${signal}`));\n return;\n }\n if (code && code !== 0) {\n reject(new Error(`${command} ${args.join(\" \")} failed with exit code ${code}`));\n return;\n }\n resolve();\n });\n });\n}\n\nexport function info(message: string): void {\n console.log(pc.cyan(message));\n}\n\nexport function success(message: string): void {\n console.log(pc.green(message));\n}\n\nexport function warn(message: string): void {\n console.log(pc.yellow(message));\n}\n","import { promises as fs } from \"node:fs\";\nimport path from \"node:path\";\nimport { stringify } from \"smol-toml\";\n\nexport interface RuntimeLayoutPaths {\n defaultsRoot: string;\n runtimeRoot: string;\n runtimeConfigFile: string;\n runtimeProvidersFile: string;\n runtimeKeysFile: string;\n runtimeChannelsFile: string;\n runtimeOrchestratorFile: string;\n runtimeStageManagerFile: string;\n runtimeWaifusRoot: string;\n runtimeStageManagerDataRoot: string;\n runtimeAssetsWaifusRoot: string;\n runtimeStateRoot: string;\n migrationStateFile: string;\n migrationWarningsFile: string;\n stageManagerCheckpointsFile: string;\n defaultsConfigFile: string;\n defaultsChannelsFile: string;\n defaultsOrchestratorFile: string;\n defaultsStageManagerFile: string;\n defaultsProviderCatalogFile: string;\n defaultsWaifuTemplateFile: string;\n legacyConfigRoot: string;\n legacyDataRoot: string;\n legacyWaifusFile: string;\n legacyProvidersFile: string;\n legacyChannelsFile: string;\n legacyOrchestratorFile: string;\n legacyStageManagerFile: string;\n legacyStageManagerStateFile: string;\n}\n\nexport interface MigrationStateFile {\n schemaVersion: number;\n status: \"bootstrap_empty\" | \"import_completed\";\n createdAt: string;\n completedAt: string;\n}\n\nexport interface RuntimeStateInspection {\n paths: RuntimeLayoutPaths;\n runtimeRootExists: boolean;\n legacyLiveExists: boolean;\n migrationState: MigrationStateFile | null;\n isCanonicalLocalRuntime: boolean;\n isMigrationPending: boolean;\n}\n\nexport function getRuntimeLayoutPaths(projectRoot: string): RuntimeLayoutPaths {\n const defaultsRoot = path.join(projectRoot, \"defaults\");\n const runtimeRoot = path.join(projectRoot, \".waifus\");\n const runtimeStateRoot = path.join(runtimeRoot, \"state\");\n const legacyConfigRoot = path.join(projectRoot, \"config\");\n const legacyDataRoot = path.join(projectRoot, \"data\");\n\n return {\n defaultsRoot,\n runtimeRoot,\n runtimeConfigFile: path.join(runtimeRoot, \"config.toml\"),\n runtimeProvidersFile: path.join(runtimeRoot, \"providers.toml\"),\n runtimeKeysFile: path.join(runtimeRoot, \"keys.toml\"),\n runtimeChannelsFile: path.join(runtimeRoot, \"channels.toml\"),\n runtimeOrchestratorFile: path.join(runtimeRoot, \"orchestrator.toml\"),\n runtimeStageManagerFile: path.join(runtimeRoot, \"stage-manager.toml\"),\n runtimeWaifusRoot: path.join(runtimeRoot, \"waifus\"),\n runtimeStageManagerDataRoot: path.join(runtimeRoot, \"stage-manager-data\"),\n runtimeAssetsWaifusRoot: path.join(runtimeRoot, \"assets\", \"waifus\"),\n runtimeStateRoot,\n migrationStateFile: path.join(runtimeStateRoot, \"migration-state.json\"),\n migrationWarningsFile: path.join(runtimeStateRoot, \"migration-warnings.json\"),\n stageManagerCheckpointsFile: path.join(runtimeStateRoot, \"stage-manager-checkpoints.json\"),\n defaultsConfigFile: path.join(defaultsRoot, \"config.toml\"),\n defaultsChannelsFile: path.join(defaultsRoot, \"channels.toml\"),\n defaultsOrchestratorFile: path.join(defaultsRoot, \"orchestrator.toml\"),\n defaultsStageManagerFile: path.join(defaultsRoot, \"stage-manager.toml\"),\n defaultsProviderCatalogFile: path.join(defaultsRoot, \"providers.catalog.json\"),\n defaultsWaifuTemplateFile: path.join(defaultsRoot, \"waifus\", \"default-waifu.json\"),\n legacyConfigRoot,\n legacyDataRoot,\n legacyWaifusFile: path.join(legacyConfigRoot, \"waifus.json\"),\n legacyProvidersFile: path.join(legacyConfigRoot, \"providers.json\"),\n legacyChannelsFile: path.join(legacyConfigRoot, \"channels.json\"),\n legacyOrchestratorFile: path.join(legacyConfigRoot, \"orchestrator.json\"),\n legacyStageManagerFile: path.join(legacyConfigRoot, \"stage-manager.json\"),\n legacyStageManagerStateFile: path.join(legacyDataRoot, \"stage-manager-state.json\")\n };\n}\n\nexport async function inspectRuntimeState(projectRoot: string): Promise<RuntimeStateInspection> {\n const paths = getRuntimeLayoutPaths(projectRoot);\n const runtimeRootExists = await fileExists(paths.runtimeRoot);\n const legacyLiveExists = await hasLegacyLiveConfig(projectRoot);\n const migrationState = await readMigrationState(paths.migrationStateFile);\n const isCanonicalLocalRuntime =\n Boolean(runtimeRootExists) &&\n (\n migrationState?.status === \"import_completed\" ||\n (migrationState?.status === \"bootstrap_empty\" && !legacyLiveExists) ||\n (!migrationState && !legacyLiveExists)\n );\n\n return {\n paths,\n runtimeRootExists,\n legacyLiveExists,\n migrationState,\n isCanonicalLocalRuntime,\n isMigrationPending: Boolean(runtimeRootExists && legacyLiveExists && migrationState?.status !== \"import_completed\")\n };\n}\n\nexport async function hasLegacyLiveConfig(projectRoot: string): Promise<boolean> {\n const paths = getRuntimeLayoutPaths(projectRoot);\n const candidates = [\n paths.legacyWaifusFile,\n paths.legacyProvidersFile,\n paths.legacyChannelsFile,\n paths.legacyOrchestratorFile,\n paths.legacyStageManagerFile,\n paths.legacyStageManagerStateFile\n ];\n\n for (const candidate of candidates) {\n if (await fileExists(candidate)) {\n return true;\n }\n }\n\n return false;\n}\n\nexport async function bootstrapLocalRuntime(projectRoot: string): Promise<string[]> {\n const inspection = await inspectRuntimeState(projectRoot);\n if (inspection.legacyLiveExists && inspection.migrationState?.status !== \"import_completed\") {\n throw new Error(\"Legacy live config still exists. Run: waifus migrate-local-config\");\n }\n\n return seedLocalRuntimeFromDefaults(projectRoot, {\n writeBootstrapMigrationState: !inspection.migrationState && !inspection.legacyLiveExists\n });\n}\n\nexport async function seedLocalRuntimeFromDefaults(\n projectRoot: string,\n options: { writeBootstrapMigrationState: boolean }\n): Promise<string[]> {\n const inspection = await inspectRuntimeState(projectRoot);\n\n const paths = inspection.paths;\n const written: string[] = [];\n\n await Promise.all([\n fs.mkdir(paths.runtimeWaifusRoot, { recursive: true }),\n fs.mkdir(paths.runtimeStageManagerDataRoot, { recursive: true }),\n fs.mkdir(paths.runtimeAssetsWaifusRoot, { recursive: true }),\n fs.mkdir(paths.runtimeStateRoot, { recursive: true })\n ]);\n\n written.push(\n await ensureCopied(paths.defaultsConfigFile, paths.runtimeConfigFile),\n await ensureCopied(paths.defaultsChannelsFile, paths.runtimeChannelsFile),\n await ensureSeededProviders(paths.defaultsProviderCatalogFile, paths.runtimeProvidersFile),\n await ensureFile(paths.runtimeKeysFile, `${stringify({ provider_keys: [] })}\\n`),\n await ensureCopied(paths.defaultsOrchestratorFile, paths.runtimeOrchestratorFile),\n await ensureCopied(paths.defaultsStageManagerFile, paths.runtimeStageManagerFile),\n await ensureJsonFile(paths.stageManagerCheckpointsFile, { guilds: {} }),\n await ensureJsonFile(paths.migrationWarningsFile, {\n schemaVersion: 1,\n globalWarnings: [],\n waifuWarnings: {}\n })\n );\n\n if (options.writeBootstrapMigrationState) {\n written.push(\n await ensureJsonFile(paths.migrationStateFile, {\n schemaVersion: 1,\n status: \"bootstrap_empty\",\n createdAt: new Date().toISOString(),\n completedAt: new Date().toISOString()\n })\n );\n }\n\n return written.filter(Boolean);\n}\n\nexport function defaultSeedFiles(projectRoot: string): string[] {\n const paths = getRuntimeLayoutPaths(projectRoot);\n return [\n paths.defaultsConfigFile,\n paths.defaultsChannelsFile,\n paths.defaultsOrchestratorFile,\n paths.defaultsStageManagerFile,\n paths.defaultsProviderCatalogFile,\n paths.defaultsWaifuTemplateFile\n ];\n}\n\nexport function localRuntimeFiles(projectRoot: string): string[] {\n const paths = getRuntimeLayoutPaths(projectRoot);\n return [\n paths.runtimeConfigFile,\n paths.runtimeProvidersFile,\n paths.runtimeKeysFile,\n paths.runtimeChannelsFile,\n paths.runtimeOrchestratorFile,\n paths.runtimeStageManagerFile,\n paths.migrationStateFile,\n paths.migrationWarningsFile,\n paths.stageManagerCheckpointsFile\n ];\n}\n\nasync function ensureSeededProviders(catalogFile: string, providersFile: string): Promise<string> {\n if (await fileExists(providersFile)) {\n return \"\";\n }\n\n const catalog = JSON.parse(await fs.readFile(catalogFile, \"utf8\")) as {\n providers?: Array<{\n id: string;\n name: string;\n type: string;\n authMode?: string;\n enabledByDefault?: boolean;\n baseUrl: string;\n models?: string[];\n }>;\n };\n const tomlValue = {\n providers: (catalog.providers ?? []).map((entry) => ({\n id: entry.id,\n origin: \"built-in\",\n name: entry.name,\n type: entry.type,\n auth_mode: entry.authMode ?? \"required\",\n enabled: entry.enabledByDefault ?? false,\n base_url: entry.baseUrl,\n models: entry.models ?? []\n }))\n };\n await fs.mkdir(path.dirname(providersFile), { recursive: true });\n await fs.writeFile(providersFile, `${stringify(tomlValue)}\\n`, \"utf8\");\n return providersFile;\n}\n\nasync function ensureCopied(sourceFile: string, targetFile: string): Promise<string> {\n if (await fileExists(targetFile)) {\n return \"\";\n }\n\n const contents = await fs.readFile(sourceFile, \"utf8\");\n await fs.mkdir(path.dirname(targetFile), { recursive: true });\n await fs.writeFile(targetFile, contents, \"utf8\");\n return targetFile;\n}\n\nasync function ensureFile(targetFile: string, contents: string): Promise<string> {\n if (await fileExists(targetFile)) {\n return \"\";\n }\n\n await fs.mkdir(path.dirname(targetFile), { recursive: true });\n await fs.writeFile(targetFile, contents, \"utf8\");\n return targetFile;\n}\n\nasync function ensureJsonFile(targetFile: string, value: unknown): Promise<string> {\n return ensureFile(targetFile, `${JSON.stringify(value, null, 2)}\\n`);\n}\n\nasync function readMigrationState(filePath: string): Promise<MigrationStateFile | null> {\n try {\n return JSON.parse(await fs.readFile(filePath, \"utf8\")) as MigrationStateFile;\n } catch (error) {\n const code = (error as NodeJS.ErrnoException | undefined)?.code;\n if (code === \"ENOENT\") {\n return null;\n }\n throw error;\n }\n}\n\nasync function fileExists(filePath: string): Promise<boolean> {\n try {\n await fs.access(filePath);\n return true;\n } catch {\n return false;\n }\n}\n","import process from \"node:process\";\nimport { spawn } from \"node:child_process\";\n\nexport async function openUrl(url: string): Promise<void> {\n const platform = process.platform;\n\n if (platform === \"darwin\") {\n await spawnDetached(\"open\", [url]);\n return;\n }\n\n if (platform === \"win32\") {\n await spawnDetached(\"cmd\", [\"/c\", \"start\", \"\", url]);\n return;\n }\n\n await spawnDetached(\"xdg-open\", [url]);\n}\n\nasync function spawnDetached(command: string, args: string[]): Promise<void> {\n await new Promise<void>((resolve, reject) => {\n const child = spawn(command, args, {\n detached: true,\n stdio: \"ignore\",\n env: process.env\n });\n\n child.once(\"error\", reject);\n child.once(\"spawn\", () => {\n child.unref();\n resolve();\n });\n });\n}\n","import { promises as fs } from \"node:fs\";\nimport path from \"node:path\";\nimport { stringify } from \"smol-toml\";\nimport { getRuntimeLayoutPaths, inspectRuntimeState, seedLocalRuntimeFromDefaults } from \"./runtime-layout.js\";\n\ninterface LegacyProvider {\n id: string;\n name: string;\n type: \"openai-compatible\" | \"anthropic\";\n baseUrl: string;\n apiKey: string;\n enabled: boolean;\n models: string[];\n}\n\ninterface LegacyWaifu {\n id: string;\n name: string;\n displayName: string;\n botToken: string;\n applicationId: string;\n enabled: boolean;\n avatarPath: string | null;\n bannerPath: string | null;\n statusText: string | null;\n statusType: \"online\" | \"idle\" | \"dnd\" | \"invisible\";\n personality: {\n description: string;\n traits: string[];\n speechPatterns: string[];\n likes: string[];\n dislikes: string[];\n backstory: string;\n quirks: string[];\n relationshipsWithOtherWaifus: Record<string, string>;\n };\n schedule: {\n sleepTime: { start: string; end: string };\n busyTime: { start: string; end: string; reason: string };\n };\n ai: {\n providerId: string;\n model: string;\n temperature: number;\n repetitionPenalty: number;\n maxTokens: number;\n systemPromptOverride: string | null;\n };\n}\n\ninterface LegacyChannel {\n guildId: string;\n channelId: string;\n channelName: string;\n enabled: boolean;\n activeWaifuIds: string[];\n contextAnchorMessageId: string | null;\n contextMessageCount: number;\n idleChatterEnabled: boolean;\n idleTimerMinSeconds: number;\n idleTimerMaxSeconds: number;\n}\n\ninterface LegacyRelationshipEntry {\n targetKind: \"user\" | \"waifu\";\n targetName: string;\n targetUserId: string | null;\n targetWaifuId: string | null;\n relationship: string;\n updatedAt: string;\n}\n\ninterface LegacyMemoryNote {\n slot: number;\n note: string;\n sourceMessageIds: string[];\n updatedAt: string;\n}\n\ninterface LegacyStageManagerState {\n waifus: Record<\n string,\n {\n relationshipsByParticipant: Record<string, LegacyRelationshipEntry>;\n memories: LegacyMemoryNote[];\n }\n >;\n channels: Record<\n string,\n {\n lastProcessedMessageId: string | null;\n lastRunAt: string | null;\n }\n >;\n}\n\ninterface CatalogProvider {\n id: string;\n name: string;\n type: \"openai-compatible\" | \"anthropic\";\n authMode: \"required\" | \"none\";\n enabledByDefault: boolean;\n baseUrl: string;\n models: string[];\n}\n\ninterface MigrationWarning {\n code: string;\n field: string;\n message: string;\n legacyValue?: string;\n createdAt: string;\n}\n\ninterface MigrationWarningsFile {\n schemaVersion: number;\n globalWarnings: MigrationWarning[];\n waifuWarnings: Record<string, MigrationWarning[]>;\n}\n\nexport interface MigrationResult {\n written: string[];\n idMap: Record<string, string>;\n warningCount: number;\n}\n\nexport async function migrateLocalConfig(projectRoot: string): Promise<MigrationResult> {\n const runtimeState = await inspectRuntimeState(projectRoot);\n if (!runtimeState.legacyLiveExists) {\n throw new Error(\"No legacy runtime files found to import.\");\n }\n if (runtimeState.migrationState?.status === \"import_completed\") {\n throw new Error(\"Legacy import already completed for this project.\");\n }\n\n const paths = runtimeState.paths;\n const timestamp = new Date().toISOString();\n const warnings: MigrationWarningsFile = {\n schemaVersion: 1,\n globalWarnings: [],\n waifuWarnings: {}\n };\n\n const [legacyWaifusFile, legacyProvidersFile, legacyChannelsFile, legacyOrchestratorFile, legacyStageManagerFile, legacyStageManagerStateFile, catalogFile] =\n await Promise.all([\n readJson<{\n waifus: LegacyWaifu[];\n }>(paths.legacyWaifusFile, { waifus: [] }),\n readJson<{\n providers: LegacyProvider[];\n }>(paths.legacyProvidersFile, { providers: [] }),\n readJson<{\n channels: LegacyChannel[];\n }>(paths.legacyChannelsFile, { channels: [] }),\n readJson(paths.legacyOrchestratorFile, {\n orchestrator: {\n providerId: \"configure-me\",\n model: \"configure-me\",\n temperature: 0.7,\n maxTokens: 500\n }\n }),\n readJson(paths.legacyStageManagerFile, {\n stageManager: {\n enabled: true,\n providerId: null,\n model: null,\n temperature: 0.4,\n maxTokens: 500,\n quietPeriodSeconds: 300,\n historyLimit: 60,\n maxRelationshipsPerWaifu: 20,\n maxMemoriesPerWaifu: 8\n }\n }),\n readJson<LegacyStageManagerState>(paths.legacyStageManagerStateFile, {\n waifus: {},\n channels: {}\n }),\n readJson<{\n providers: CatalogProvider[];\n }>(paths.defaultsProviderCatalogFile, { providers: [] })\n ]);\n\n const idMap = buildWaifuIdMap(legacyWaifusFile.waifus);\n const catalogById = new Map(catalogFile.providers.map((entry) => [entry.id, entry] as const));\n const written = await seedLocalRuntimeFromDefaults(projectRoot, {\n writeBootstrapMigrationState: false\n });\n\n const migratedWaifus = await Promise.all(\n legacyWaifusFile.waifus.map(async (waifu) => {\n const nextId = idMap[waifu.id];\n const migratedAssets = await migrateWaifuAssets(\n paths,\n waifu,\n nextId,\n warnings,\n timestamp\n );\n\n if (waifu.id !== nextId) {\n addWaifuWarning(warnings, nextId, {\n code: \"legacy_id_sanitized\",\n field: \"id\",\n message: `Legacy waifu id \"${waifu.id}\" was sanitized to \"${nextId}\".`,\n legacyValue: waifu.id,\n createdAt: timestamp\n });\n }\n\n return {\n schemaVersion: 1,\n id: nextId,\n name: waifu.name,\n displayName: waifu.displayName,\n botToken: waifu.botToken,\n applicationId: waifu.applicationId,\n enabled: waifu.enabled,\n avatarPath: migratedAssets.avatarPath,\n bannerPath: migratedAssets.bannerPath,\n statusText: waifu.statusText,\n statusType: waifu.statusType,\n personality: {\n ...waifu.personality,\n relationshipsWithOtherWaifus: Object.fromEntries(\n Object.entries(waifu.personality.relationshipsWithOtherWaifus).map(([relationshipId, value]) => [\n idMap[relationshipId] ?? relationshipId,\n value\n ])\n )\n },\n schedule: waifu.schedule,\n ai: {\n ...waifu.ai,\n providerId: waifu.ai.providerId\n }\n };\n })\n );\n\n const migratedChannels = legacyChannelsFile.channels.map((channel) => ({\n guildId: channel.guildId,\n channelId: channel.channelId,\n channelName: channel.channelName,\n enabled: channel.enabled,\n activeWaifuIds: channel.activeWaifuIds.map((waifuId) => idMap[waifuId] ?? waifuId),\n contextAnchorMessageId: channel.contextAnchorMessageId ?? \"\",\n contextMessageCount: channel.contextMessageCount,\n idleChatterEnabled: channel.idleChatterEnabled,\n idleTimerMinSeconds: channel.idleTimerMinSeconds,\n idleTimerMaxSeconds: channel.idleTimerMaxSeconds\n }));\n\n const migratedProviders = legacyProvidersFile.providers.map((provider) => {\n const catalog = catalogById.get(provider.id);\n return {\n id: provider.id,\n origin: catalog ? (\"built-in\" as const) : (\"custom\" as const),\n name: provider.name,\n type: provider.type,\n authMode: catalog?.authMode ?? deriveAuthMode(provider.id),\n enabled: provider.enabled,\n baseUrl: provider.baseUrl,\n models: provider.models\n };\n });\n\n const migratedProviderKeys = legacyProvidersFile.providers\n .map((provider) => {\n const authMode = catalogById.get(provider.id)?.authMode ?? deriveAuthMode(provider.id);\n if (authMode === \"none\" || !provider.apiKey) {\n return null;\n }\n return {\n id: provider.id,\n apiKey: provider.apiKey\n };\n })\n .filter((entry): entry is { id: string; apiKey: string } => Boolean(entry));\n\n const waifuGuilds = buildWaifuGuilds(migratedChannels);\n const migratedStageManagerDocuments = Object.fromEntries(\n migratedWaifus.map((waifu) => {\n const legacyState = legacyStageManagerStateFile.waifus[findLegacyIdForNewId(idMap, waifu.id) ?? waifu.id];\n const guildIds = [...(waifuGuilds.get(waifu.id) ?? new Set<string>())];\n const guilds: Record<string, { relationshipsByParticipant: Record<string, LegacyRelationshipEntry>; memories: LegacyMemoryNote[] }> = {};\n\n if (legacyState) {\n if (guildIds.length === 0) {\n addWaifuWarning(warnings, waifu.id, {\n code: \"stage_manager_guild_missing\",\n field: \"stageManager.guilds\",\n message: \"Legacy stage-manager data could not be assigned because this waifu is not active in any migrated guild.\",\n createdAt: timestamp\n });\n }\n if (guildIds.length > 1) {\n addWaifuWarning(warnings, waifu.id, {\n code: \"stage_manager_state_duplicated\",\n field: \"stageManager.guilds\",\n message: `Legacy stage-manager state was duplicated into ${guildIds.length} guild sections during import.`,\n createdAt: timestamp\n });\n }\n }\n\n for (const guildId of guildIds) {\n guilds[guildId] = {\n relationshipsByParticipant: Object.fromEntries(\n Object.entries(legacyState?.relationshipsByParticipant ?? {}).map(([participantKey, relationship]) => {\n const targetWaifuId = relationship.targetWaifuId\n ? (idMap[relationship.targetWaifuId] ?? relationship.targetWaifuId)\n : null;\n return [\n remapParticipantKey(participantKey, idMap),\n {\n ...relationship,\n targetWaifuId,\n targetName:\n relationship.targetKind === \"waifu\" && targetWaifuId\n ? migratedWaifus.find((candidate) => candidate.id === targetWaifuId)?.name ?? relationship.targetName\n : relationship.targetName\n }\n ];\n })\n ),\n memories: [...(legacyState?.memories ?? [])]\n };\n }\n\n return [\n waifu.id,\n {\n schemaVersion: 1,\n waifuId: waifu.id,\n guilds\n }\n ] as const;\n })\n );\n\n const migratedCheckpoints = collapseLegacyCheckpoints(\n legacyStageManagerStateFile.channels,\n migratedChannels,\n warnings,\n timestamp\n );\n\n await Promise.all([\n atomicWriteFile(\n paths.runtimeProvidersFile,\n `${stringify({\n providers: migratedProviders.map((provider) => ({\n id: provider.id,\n origin: provider.origin,\n name: provider.name,\n type: provider.type,\n auth_mode: provider.authMode,\n enabled: provider.enabled,\n base_url: provider.baseUrl,\n models: provider.models\n }))\n })}\\n`\n ),\n atomicWriteFile(\n paths.runtimeKeysFile,\n `${stringify({\n provider_keys: migratedProviderKeys.map((entry) => ({\n id: entry.id,\n api_key: entry.apiKey\n }))\n })}\\n`\n ),\n atomicWriteFile(\n paths.runtimeChannelsFile,\n `${stringify({\n channels: migratedChannels.map((channel) => ({\n guild_id: channel.guildId,\n channel_id: channel.channelId,\n channel_name: channel.channelName,\n enabled: channel.enabled,\n active_waifu_ids: channel.activeWaifuIds,\n context_anchor_message_id: channel.contextAnchorMessageId,\n context_message_count: channel.contextMessageCount,\n idle_chatter_enabled: channel.idleChatterEnabled,\n idle_timer_min_seconds: channel.idleTimerMinSeconds,\n idle_timer_max_seconds: channel.idleTimerMaxSeconds\n }))\n })}\\n`\n ),\n atomicWriteFile(\n paths.runtimeOrchestratorFile,\n `${stringify({\n orchestrator: {\n provider_id: asRecord(legacyOrchestratorFile).orchestrator?.providerId ?? \"configure-me\",\n model: asRecord(legacyOrchestratorFile).orchestrator?.model ?? \"configure-me\",\n temperature: asRecord(legacyOrchestratorFile).orchestrator?.temperature ?? 0.7,\n max_tokens: asRecord(legacyOrchestratorFile).orchestrator?.maxTokens ?? 500\n }\n })}\\n`\n ),\n atomicWriteFile(\n paths.runtimeStageManagerFile,\n `${stringify({\n stage_manager: {\n enabled: asRecord(legacyStageManagerFile).stageManager?.enabled ?? true,\n provider_id: asRecord(legacyStageManagerFile).stageManager?.providerId ?? \"\",\n model: asRecord(legacyStageManagerFile).stageManager?.model ?? \"\",\n temperature: asRecord(legacyStageManagerFile).stageManager?.temperature ?? 0.4,\n max_tokens: asRecord(legacyStageManagerFile).stageManager?.maxTokens ?? 500,\n quiet_period_seconds: asRecord(legacyStageManagerFile).stageManager?.quietPeriodSeconds ?? 300,\n history_limit: asRecord(legacyStageManagerFile).stageManager?.historyLimit ?? 60,\n max_relationships_per_waifu: asRecord(legacyStageManagerFile).stageManager?.maxRelationshipsPerWaifu ?? 20,\n max_memories_per_waifu: asRecord(legacyStageManagerFile).stageManager?.maxMemoriesPerWaifu ?? 8\n }\n })}\\n`\n ),\n atomicWriteFile(\n paths.stageManagerCheckpointsFile,\n `${JSON.stringify({ guilds: migratedCheckpoints }, null, 2)}\\n`\n ),\n atomicWriteFile(\n paths.migrationWarningsFile,\n `${JSON.stringify(warnings, null, 2)}\\n`\n ),\n atomicWriteFile(\n paths.migrationStateFile,\n `${JSON.stringify(\n {\n schemaVersion: 1,\n status: \"import_completed\",\n createdAt: timestamp,\n completedAt: timestamp\n },\n null,\n 2\n )}\\n`\n )\n ]);\n\n written.push(\n paths.runtimeProvidersFile,\n paths.runtimeKeysFile,\n paths.runtimeChannelsFile,\n paths.runtimeOrchestratorFile,\n paths.runtimeStageManagerFile,\n paths.stageManagerCheckpointsFile,\n paths.migrationWarningsFile,\n paths.migrationStateFile\n );\n\n for (const waifu of migratedWaifus) {\n const waifuPath = path.join(paths.runtimeWaifusRoot, `${waifu.id}.json`);\n const stageManagerPath = path.join(paths.runtimeStageManagerDataRoot, `${waifu.id}.json`);\n await atomicWriteFile(waifuPath, `${JSON.stringify(waifu, null, 2)}\\n`);\n await atomicWriteFile(\n stageManagerPath,\n `${JSON.stringify(migratedStageManagerDocuments[waifu.id], null, 2)}\\n`\n );\n written.push(waifuPath, stageManagerPath);\n }\n\n return {\n written: [...new Set(written)],\n idMap,\n warningCount:\n warnings.globalWarnings.length +\n Object.values(warnings.waifuWarnings).reduce((count, entries) => count + entries.length, 0)\n };\n}\n\nfunction buildWaifuIdMap(waifus: LegacyWaifu[]): Record<string, string> {\n const used = new Set<string>();\n const idMap: Record<string, string> = {};\n\n for (const waifu of waifus) {\n const baseId = sanitizeWaifuId(waifu.id);\n let nextId = baseId;\n let suffix = 2;\n while (used.has(nextId)) {\n nextId = `${baseId}_${suffix}`;\n suffix += 1;\n }\n used.add(nextId);\n idMap[waifu.id] = nextId;\n }\n\n return idMap;\n}\n\nfunction sanitizeWaifuId(value: string): string {\n const sanitized = value\n .replace(/[^A-Za-z0-9_-]+/g, \"_\")\n .replace(/_+/g, \"_\")\n .replace(/^_+|_+$/g, \"\");\n return sanitized || \"Waifu_1\";\n}\n\nfunction buildWaifuGuilds(\n channels: Array<{ guildId: string; activeWaifuIds: string[] }>\n): Map<string, Set<string>> {\n const result = new Map<string, Set<string>>();\n for (const channel of channels) {\n for (const waifuId of channel.activeWaifuIds) {\n const guilds = result.get(waifuId) ?? new Set<string>();\n guilds.add(channel.guildId);\n result.set(waifuId, guilds);\n }\n }\n return result;\n}\n\nfunction collapseLegacyCheckpoints(\n checkpoints: LegacyStageManagerState[\"channels\"],\n channels: Array<{ guildId: string; channelId: string }>,\n warnings: MigrationWarningsFile,\n timestamp: string\n) {\n const guildByChannelId = new Map(channels.map((channel) => [channel.channelId, channel.guildId] as const));\n const grouped = new Map<\n string,\n Array<{ channelId: string; lastProcessedMessageId: string | null; lastRunAt: string | null }>\n >();\n\n for (const [channelId, checkpoint] of Object.entries(checkpoints)) {\n const guildId = guildByChannelId.get(channelId);\n if (!guildId) {\n warnings.globalWarnings.push({\n code: \"legacy_checkpoint_orphaned\",\n field: \"stageManager.checkpoints\",\n message: `Legacy checkpoint for channel \"${channelId}\" could not be mapped to a migrated guild.`,\n legacyValue: channelId,\n createdAt: timestamp\n });\n continue;\n }\n const entries = grouped.get(guildId) ?? [];\n entries.push({ channelId, ...checkpoint });\n grouped.set(guildId, entries);\n }\n\n return Object.fromEntries(\n [...grouped.entries()].map(([guildId, entries]) => {\n const withMessageId = entries.filter((entry) => entry.lastProcessedMessageId);\n const highestMessage = withMessageId.sort((left, right) =>\n compareMessageIds(left.lastProcessedMessageId, right.lastProcessedMessageId)\n )[withMessageId.length - 1];\n const latestRun = entries\n .filter((entry) => entry.lastRunAt)\n .sort((left, right) => String(left.lastRunAt).localeCompare(String(right.lastRunAt)))\n .at(-1);\n\n if (entries.length > 1) {\n warnings.globalWarnings.push({\n code: \"legacy_checkpoints_collapsed\",\n field: `stageManager.checkpoints.${guildId}`,\n message: `Collapsed ${entries.length} channel checkpoints into one guild checkpoint for \"${guildId}\".`,\n createdAt: timestamp\n });\n }\n\n return [\n guildId,\n {\n lastProcessedMessageId: highestMessage?.lastProcessedMessageId ?? null,\n lastRunAt: latestRun?.lastRunAt ?? null\n }\n ];\n })\n );\n}\n\nfunction compareMessageIds(left: string | null, right: string | null): number {\n if (!left && !right) {\n return 0;\n }\n if (!left) {\n return -1;\n }\n if (!right) {\n return 1;\n }\n try {\n const leftValue = BigInt(left);\n const rightValue = BigInt(right);\n return leftValue < rightValue ? -1 : leftValue > rightValue ? 1 : 0;\n } catch {\n return left.localeCompare(right);\n }\n}\n\nasync function migrateWaifuAssets(\n paths: ReturnType<typeof getRuntimeLayoutPaths>,\n waifu: LegacyWaifu,\n waifuId: string,\n warnings: MigrationWarningsFile,\n timestamp: string\n): Promise<{ avatarPath: string | null; bannerPath: string | null }> {\n return {\n avatarPath: await migrateAssetField(paths, waifu, waifuId, \"avatarPath\", \"avatar\", warnings, timestamp),\n bannerPath: await migrateAssetField(paths, waifu, waifuId, \"bannerPath\", \"banner\", warnings, timestamp)\n };\n}\n\nasync function migrateAssetField(\n paths: ReturnType<typeof getRuntimeLayoutPaths>,\n waifu: LegacyWaifu,\n waifuId: string,\n key: \"avatarPath\" | \"bannerPath\",\n stem: \"avatar\" | \"banner\",\n warnings: MigrationWarningsFile,\n timestamp: string\n): Promise<string | null> {\n const value = waifu[key];\n if (!value || !value.trim()) {\n return null;\n }\n\n const sourcePath = await resolveLegacyAssetPath(paths, value);\n if (!sourcePath) {\n addWaifuWarning(warnings, waifuId, {\n code: \"legacy_asset_unresolved\",\n field: key,\n message: `Legacy ${stem} asset could not be resolved during import.`,\n legacyValue: value,\n createdAt: timestamp\n });\n return null;\n }\n\n const extension = path.extname(sourcePath) || \".png\";\n const destinationDir = path.join(paths.runtimeAssetsWaifusRoot, waifuId);\n const destinationPath = path.join(destinationDir, `${stem}${extension}`);\n await fs.mkdir(destinationDir, { recursive: true });\n await fs.copyFile(sourcePath, destinationPath);\n return path.posix.join(\"waifus\", waifuId, `${stem}${extension}`);\n}\n\nasync function resolveLegacyAssetPath(\n paths: ReturnType<typeof getRuntimeLayoutPaths>,\n value: string\n): Promise<string | null> {\n const trimmed = value.trim();\n const candidates = [\n trimmed,\n path.join(path.dirname(paths.legacyConfigRoot), trimmed.replace(/^\\.\\//, \"\")),\n path.join(paths.legacyConfigRoot, trimmed.replace(/^\\.\\/?config\\/assets\\//, \"\").replace(/^config\\/assets\\//, \"\").replace(/^\\.\\/assets\\//, \"\").replace(/^assets\\//, \"\"))\n ];\n\n for (const candidate of candidates) {\n const resolved = path.isAbsolute(candidate) ? candidate : path.resolve(candidate);\n if (await fileExists(resolved)) {\n return resolved;\n }\n }\n\n return null;\n}\n\nfunction remapParticipantKey(value: string, idMap: Record<string, string>): string {\n const match = value.match(/^waifu:(.+)$/);\n if (!match) {\n return value;\n }\n return `waifu:${idMap[match[1]] ?? match[1]}`;\n}\n\nfunction findLegacyIdForNewId(idMap: Record<string, string>, nextId: string): string | null {\n return Object.entries(idMap).find(([, mapped]) => mapped === nextId)?.[0] ?? null;\n}\n\nfunction deriveAuthMode(providerId: string): \"required\" | \"none\" {\n return providerId === \"ollama\" || providerId === \"lmstudio\" ? \"none\" : \"required\";\n}\n\nfunction addWaifuWarning(\n warnings: MigrationWarningsFile,\n waifuId: string,\n warning: MigrationWarning\n): void {\n warnings.waifuWarnings[waifuId] = warnings.waifuWarnings[waifuId] ?? [];\n warnings.waifuWarnings[waifuId].push(warning);\n}\n\nfunction asRecord(value: unknown): Record<string, any> {\n return value && typeof value === \"object\" ? (value as Record<string, any>) : {};\n}\n\nasync function readJson<T>(filePath: string, fallback: T): Promise<T> {\n try {\n return JSON.parse(await fs.readFile(filePath, \"utf8\")) as T;\n } catch (error) {\n const code = (error as NodeJS.ErrnoException | undefined)?.code;\n if (code === \"ENOENT\") {\n return fallback;\n }\n throw error;\n }\n}\n\nasync function atomicWriteFile(filePath: string, contents: string): Promise<void> {\n await fs.mkdir(path.dirname(filePath), { recursive: true });\n const tempPath = `${filePath}.tmp`;\n await fs.writeFile(tempPath, contents, \"utf8\");\n await fs.rename(tempPath, filePath);\n}\n\nasync function fileExists(filePath: string): Promise<boolean> {\n try {\n await fs.access(filePath);\n return true;\n } catch {\n return false;\n }\n}\n","import { createRequire } from \"node:module\";\nimport path from \"node:path\";\nimport { resolveBundledPnpmBin } from \"./pnpm-bin.js\";\nimport { getServiceEnv } from \"./service-env.js\";\n\ntype PM2Runtime = typeof import(\"pm2\");\ntype StartOptions = import(\"pm2\").StartOptions;\ntype ProcessDescription = import(\"pm2\").ProcessDescription;\nconst require = createRequire(import.meta.url);\n\nexport const backendProcessName = \"waifus-backend\";\nexport const dashboardProcessName = \"waifus-dashboard\";\n\n// Resolve the pnpm bundled as a dependency of this CLI so pm2 doesn't have to\n// find pnpm on PATH. We avoid requiring an unexported subpath so this keeps\n// working on newer Node releases.\nconst PNPM_BIN = resolveBundledPnpmBin();\n\nexport interface ManagedProcessStatus {\n name: string;\n status: string;\n cwd: string | null;\n pid: number | null;\n restartCount: number;\n uptimeMs: number | null;\n}\n\nexport async function startServices(projectRoot: string): Promise<void> {\n await withPm2(async () => {\n await ensureStarted({\n name: backendProcessName,\n cwd: projectRoot,\n script: PNPM_BIN,\n args: [\"--filter\", \"backend\", \"start\"],\n env: getServiceEnv(\"backend\")\n });\n\n await ensureStarted({\n name: dashboardProcessName,\n cwd: projectRoot,\n script: PNPM_BIN,\n args: [\"--filter\", \"dashboard\", \"start\"],\n env: getServiceEnv(\"dashboard\")\n });\n });\n}\n\nexport async function stopServices(): Promise<void> {\n await withPm2(async () => {\n await stopIfPresent(backendProcessName);\n await stopIfPresent(dashboardProcessName);\n });\n}\n\nexport async function restartServices(projectRoot: string): Promise<void> {\n await withPm2(async () => {\n await restartOrStart({\n name: backendProcessName,\n cwd: projectRoot,\n script: PNPM_BIN,\n args: [\"--filter\", \"backend\", \"start\"],\n env: getServiceEnv(\"backend\")\n });\n\n await restartOrStart({\n name: dashboardProcessName,\n cwd: projectRoot,\n script: PNPM_BIN,\n args: [\"--filter\", \"dashboard\", \"start\"],\n env: getServiceEnv(\"dashboard\")\n });\n });\n}\n\nexport async function listManagedServices(): Promise<ManagedProcessStatus[]> {\n return withPm2(async () => {\n const processes = await listProcesses();\n return processes\n .filter((processDescription) =>\n [backendProcessName, dashboardProcessName].includes(processDescription.name ?? \"\")\n )\n .map((processDescription) => ({\n name: processDescription.name ?? \"unknown\",\n status: processDescription.pm2_env?.status ?? \"unknown\",\n cwd: processDescription.pm2_env?.pm_cwd ?? null,\n pid: typeof processDescription.pid === \"number\" ? processDescription.pid : null,\n restartCount: processDescription.pm2_env?.restart_time ?? 0,\n uptimeMs:\n typeof processDescription.pm2_env?.pm_uptime === \"number\"\n ? Date.now() - processDescription.pm2_env.pm_uptime\n : null\n }));\n });\n}\n\nexport function getPm2LogCommand(service: \"backend\" | \"dashboard\" | null, lines: number): {\n command: string;\n args: string[];\n} {\n const pm2Bin = resolvePm2Bin();\n const args = [\"logs\"];\n\n if (service === \"backend\") {\n args.push(backendProcessName);\n } else if (service === \"dashboard\") {\n args.push(dashboardProcessName);\n } else {\n args.push(backendProcessName, dashboardProcessName);\n }\n\n args.push(\"--lines\", String(lines));\n\n return {\n command: process.execPath,\n args: [pm2Bin, ...args]\n };\n}\n\nasync function ensureStarted(options: StartOptions): Promise<void> {\n if (await hasManagedProcess(options.name ?? \"\")) {\n await restartProcess(options.name ?? \"\");\n return;\n }\n await startProcess(options);\n}\n\nasync function restartOrStart(options: StartOptions): Promise<void> {\n if (await hasManagedProcess(options.name ?? \"\")) {\n await restartProcess(options.name ?? \"\");\n return;\n }\n await startProcess(options);\n}\n\nasync function stopIfPresent(processName: string): Promise<void> {\n if (!(await hasManagedProcess(processName))) {\n return;\n }\n await stopProcess(processName);\n}\n\nasync function withPm2<T>(callback: () => Promise<T>): Promise<T> {\n const pm2 = await loadPm2();\n await connect(pm2);\n try {\n return await callback();\n } finally {\n pm2.disconnect();\n }\n}\n\nfunction connect(pm2: PM2Runtime): Promise<void> {\n return new Promise((resolve, reject) => {\n pm2.connect((error: Error | null) => {\n if (error) {\n reject(error);\n return;\n }\n resolve();\n });\n });\n}\n\nasync function startProcess(options: StartOptions): Promise<void> {\n const pm2 = await loadPm2();\n return new Promise((resolve, reject) => {\n pm2.start(options, (error: Error | null) => {\n if (error) {\n reject(error);\n return;\n }\n resolve();\n });\n });\n}\n\nasync function restartProcess(processName: string): Promise<void> {\n const pm2 = await loadPm2();\n return new Promise((resolve, reject) => {\n pm2.restart(processName, (error: Error | null) => {\n if (error) {\n reject(error);\n return;\n }\n resolve();\n });\n });\n}\n\nasync function stopProcess(processName: string): Promise<void> {\n const pm2 = await loadPm2();\n return new Promise((resolve, reject) => {\n pm2.stop(processName, (error: Error | null) => {\n if (error) {\n reject(error);\n return;\n }\n resolve();\n });\n });\n}\n\nasync function listProcesses(): Promise<ProcessDescription[]> {\n const pm2 = await loadPm2();\n return new Promise((resolve, reject) => {\n pm2.list((error: Error | null, processDescription: ProcessDescription[]) => {\n if (error) {\n reject(error);\n return;\n }\n resolve(processDescription);\n });\n });\n}\n\nasync function hasManagedProcess(processName: string): Promise<boolean> {\n const processes = await listProcesses();\n return processes.some((processDescription) => processDescription.name === processName);\n}\n\nlet pm2Promise: Promise<PM2Runtime> | null = null;\n\nasync function loadPm2(): Promise<PM2Runtime> {\n if (!pm2Promise) {\n pm2Promise = Promise.resolve(require(\"pm2\") as PM2Runtime);\n }\n\n return pm2Promise;\n}\n\nfunction resolvePm2Bin(): string {\n return require.resolve(path.join(\"pm2\", \"bin\", \"pm2\"));\n}\n","import path from \"node:path\";\nimport { createRequire } from \"node:module\";\n\nconst require = createRequire(import.meta.url);\n\nexport function resolveBundledPnpmBin(): string {\n const pnpmPackageJson = require.resolve(\"pnpm\");\n return path.join(path.dirname(pnpmPackageJson), \"bin\", \"pnpm.cjs\");\n}\n","export type ManagedService = \"backend\" | \"dashboard\";\n\nexport function getServiceEnv(service: ManagedService): Record<string, string> {\n if (service === \"backend\") {\n return {\n NODE_ENV: \"production\"\n };\n }\n\n return {\n NODE_ENV: \"production\",\n PORT: \"3000\"\n };\n}\n","import { promises as fs } from \"node:fs\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport { spawn } from \"node:child_process\";\n\nexport interface BootstrapRepoOptions {\n repo?: string | null;\n ref?: string | null;\n}\n\nexport interface BootstrapRepoResult {\n projectRoot: string;\n sourceRepo: string;\n sourceRef: string | null;\n}\n\nexport interface UpdateRepoOptions {\n preserveEntries?: string[];\n}\n\nexport async function bootstrapRepoFromGitHubArchive(\n targetDir: string,\n options: BootstrapRepoOptions = {}\n): Promise<BootstrapRepoResult> {\n const projectRoot = path.resolve(targetDir);\n await ensureTargetDirectoryIsEmpty(projectRoot);\n const snapshot = await prepareRepoSnapshot(options);\n\n try {\n await fs.mkdir(projectRoot, { recursive: true });\n await copyDirectoryContents(snapshot.extractedRoot, projectRoot);\n\n return {\n projectRoot,\n sourceRepo: snapshot.sourceRepo,\n sourceRef: snapshot.sourceRef\n };\n } finally {\n await snapshot.cleanup();\n }\n}\n\nexport async function updateRepoFromGitHubArchive(\n targetDir: string,\n options: BootstrapRepoOptions = {},\n updateOptions: UpdateRepoOptions = {}\n): Promise<BootstrapRepoResult> {\n const projectRoot = path.resolve(targetDir);\n const stats = await fs.stat(projectRoot).catch(() => null);\n if (!stats?.isDirectory()) {\n throw new Error(`Project directory does not exist: ${projectRoot}`);\n }\n\n const snapshot = await prepareRepoSnapshot(options);\n const preserveEntries = new Set((updateOptions.preserveEntries ?? []).map((entry) => entry.trim()).filter(Boolean));\n\n try {\n await replaceProjectContents(projectRoot, snapshot.extractedRoot, preserveEntries);\n\n return {\n projectRoot,\n sourceRepo: snapshot.sourceRepo,\n sourceRef: snapshot.sourceRef\n };\n } finally {\n await snapshot.cleanup();\n }\n}\n\nasync function ensureTargetDirectoryIsEmpty(targetDir: string): Promise<void> {\n try {\n const stats = await fs.stat(targetDir);\n if (!stats.isDirectory()) {\n throw new Error(`Target path exists and is not a directory: ${targetDir}`);\n }\n\n const entries = await fs.readdir(targetDir);\n if (entries.length > 0) {\n throw new Error(`Target directory is not empty: ${targetDir}`);\n }\n } catch (error) {\n const code = (error as NodeJS.ErrnoException | undefined)?.code;\n if (code === \"ENOENT\") {\n return;\n }\n throw error;\n }\n}\n\nasync function prepareRepoSnapshot(\n options: BootstrapRepoOptions\n): Promise<{\n extractedRoot: string;\n sourceRepo: string;\n sourceRef: string | null;\n cleanup: () => Promise<void>;\n}> {\n const repositoryUrl = options.repo?.trim() || (await resolveRepositoryFromPackageMetadata());\n if (!repositoryUrl) {\n throw new Error(\n \"No GitHub repository was provided.\\nUse: waifus init <target-dir> --repo https://github.com/<owner>/<repo>\"\n );\n }\n\n const githubRepo = parseGitHubRepository(repositoryUrl);\n if (!githubRepo) {\n throw new Error(\n `Unsupported repository: ${repositoryUrl}\\nOnly GitHub repositories are supported by waifus init.`\n );\n }\n\n const ref = options.ref?.trim() || null;\n const archiveUrl = buildGitHubArchiveUrl(githubRepo.owner, githubRepo.repo, ref);\n const tempRoot = await fs.mkdtemp(path.join(os.tmpdir(), \"waifus-init-\"));\n const archivePath = path.join(tempRoot, \"repo.tar.gz\");\n const extractRoot = path.join(tempRoot, \"extract\");\n\n try {\n await fs.mkdir(extractRoot, { recursive: true });\n await downloadFile(archiveUrl, archivePath);\n await extractTarGz(archivePath, extractRoot);\n const extractedRoot = await findSingleExtractedRoot(extractRoot);\n\n return {\n extractedRoot,\n sourceRepo: `https://github.com/${githubRepo.owner}/${githubRepo.repo}`,\n sourceRef: ref,\n cleanup: async () => {\n await fs.rm(tempRoot, { recursive: true, force: true });\n }\n };\n } catch (error) {\n await fs.rm(tempRoot, { recursive: true, force: true });\n throw error;\n }\n}\n\nasync function resolveRepositoryFromPackageMetadata(): Promise<string | null> {\n try {\n const packageJsonPath = new URL(\"../package.json\", import.meta.url);\n const raw = JSON.parse(await fs.readFile(packageJsonPath, \"utf8\")) as {\n repository?: string | { url?: string };\n };\n if (typeof raw.repository === \"string\" && raw.repository.trim()) {\n return raw.repository.trim();\n }\n if (\n raw.repository &&\n typeof raw.repository === \"object\" &&\n typeof raw.repository.url === \"string\" &&\n raw.repository.url.trim()\n ) {\n return raw.repository.url.trim();\n }\n return null;\n } catch {\n return null;\n }\n}\n\nfunction parseGitHubRepository(value: string): { owner: string; repo: string } | null {\n const trimmed = value.trim();\n const normalized = trimmed\n .replace(/^git\\+/, \"\")\n .replace(/^git@github\\.com:/, \"https://github.com/\")\n .replace(/\\.git$/, \"\");\n\n const slugMatch = normalized.match(/^([A-Za-z0-9_.-]+)\\/([A-Za-z0-9_.-]+)$/);\n if (slugMatch) {\n return { owner: slugMatch[1], repo: slugMatch[2] };\n }\n\n try {\n const url = new URL(normalized);\n if (url.hostname !== \"github.com\") {\n return null;\n }\n const segments = url.pathname.replace(/^\\/+|\\/+$/g, \"\").split(\"/\");\n if (segments.length < 2 || !segments[0] || !segments[1]) {\n return null;\n }\n return {\n owner: segments[0],\n repo: segments[1]\n };\n } catch {\n return null;\n }\n}\n\nfunction buildGitHubArchiveUrl(owner: string, repo: string, ref: string | null): string {\n const encodedRef = ref ? `/${encodeURIComponent(ref)}` : \"\";\n return `https://api.github.com/repos/${owner}/${repo}/tarball${encodedRef}`;\n}\n\nasync function downloadFile(url: string, destinationPath: string): Promise<void> {\n const response = await fetch(url, {\n headers: {\n \"User-Agent\": \"@starlight-ai/discord-waifus\"\n },\n redirect: \"follow\"\n });\n\n if (!response.ok) {\n throw new Error(`Failed to download repository archive: HTTP ${response.status}`);\n }\n\n const buffer = Buffer.from(await response.arrayBuffer());\n await fs.writeFile(destinationPath, buffer);\n}\n\nasync function extractTarGz(archivePath: string, extractRoot: string): Promise<void> {\n await spawnQuiet(\"tar\", [\"-xzf\", archivePath, \"-C\", extractRoot]);\n}\n\nasync function findSingleExtractedRoot(extractRoot: string): Promise<string> {\n const entries = await fs.readdir(extractRoot, { withFileTypes: true });\n const directories = entries.filter((entry) => entry.isDirectory());\n if (directories.length !== 1) {\n throw new Error(\"Repository archive extraction did not produce a single root directory.\");\n }\n return path.join(extractRoot, directories[0].name);\n}\n\nasync function copyDirectoryContents(sourceDir: string, targetDir: string): Promise<void> {\n const entries = await fs.readdir(sourceDir);\n await Promise.all(\n entries.map((entry) =>\n fs.cp(path.join(sourceDir, entry), path.join(targetDir, entry), {\n recursive: true\n })\n )\n );\n}\n\nasync function replaceProjectContents(\n targetDir: string,\n sourceDir: string,\n preserveEntries: Set<string>\n): Promise<void> {\n const entries = await fs.readdir(targetDir, { withFileTypes: true });\n\n for (const entry of entries) {\n if (preserveEntries.has(entry.name)) {\n continue;\n }\n await fs.rm(path.join(targetDir, entry.name), { recursive: true, force: true });\n }\n\n await copyDirectoryContents(sourceDir, targetDir);\n}\n\nasync function spawnQuiet(command: string, args: string[]): Promise<void> {\n await new Promise<void>((resolve, reject) => {\n const child = spawn(command, args, {\n stdio: \"ignore\"\n });\n\n child.once(\"error\", reject);\n child.once(\"exit\", (code, signal) => {\n if (signal) {\n reject(new Error(`${command} exited due to signal ${signal}`));\n return;\n }\n if (code && code !== 0) {\n reject(new Error(`${command} ${args.join(\" \")} failed with exit code ${code}`));\n return;\n }\n resolve();\n });\n });\n}\n","import { spawnPassthrough } from \"./command-utils.js\";\n\nexport interface CliSelfUpdateOptions {\n packageName: string;\n currentVersion: string;\n cwd: string;\n info: (message: string) => void;\n success: (message: string) => void;\n warn: (message: string) => void;\n skip?: boolean;\n}\n\nexport async function maybeSelfUpdateCli(options: CliSelfUpdateOptions): Promise<boolean> {\n if (options.skip) {\n return false;\n }\n\n const latestVersion = await fetchLatestPackageVersion(options.packageName);\n if (!latestVersion) {\n options.warn(\"Could not check npm for a newer waifus CLI version. Continuing with app update.\");\n return false;\n }\n\n if (!isNewerVersion(latestVersion, options.currentVersion)) {\n return false;\n }\n\n options.info(`CLI update available: ${options.currentVersion} -> ${latestVersion}`);\n options.info(\"Updating the global waifus CLI with npm...\");\n\n try {\n await spawnPassthrough(\n \"npm\",\n [\"install\", \"-g\", `${options.packageName}@${latestVersion}`],\n options.cwd\n );\n options.success(`CLI updated to ${latestVersion}.`);\n return true;\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n options.warn(`Failed to auto-update the global CLI: ${message}`);\n options.warn(`You can update it manually with: npm install -g ${options.packageName}`);\n return false;\n }\n}\n\nasync function fetchLatestPackageVersion(packageName: string): Promise<string | null> {\n try {\n const response = await fetch(`https://registry.npmjs.org/${encodeURIComponent(packageName)}/latest`, {\n headers: {\n Accept: \"application/json\",\n \"User-Agent\": packageName\n }\n });\n\n if (!response.ok) {\n return null;\n }\n\n const payload = await response.json() as { version?: unknown };\n return typeof payload.version === \"string\" && payload.version.trim()\n ? payload.version.trim()\n : null;\n } catch {\n return null;\n }\n}\n\nfunction isNewerVersion(candidate: string, current: string): boolean {\n const parsedCandidate = parseVersion(candidate);\n const parsedCurrent = parseVersion(current);\n if (!parsedCandidate || !parsedCurrent) {\n return false;\n }\n\n for (let index = 0; index < parsedCandidate.length; index += 1) {\n if (parsedCandidate[index] > parsedCurrent[index]) {\n return true;\n }\n if (parsedCandidate[index] < parsedCurrent[index]) {\n return false;\n }\n }\n\n return false;\n}\n\nfunction parseVersion(version: string): [number, number, number] | null {\n const match = version.trim().match(/^(\\d+)\\.(\\d+)\\.(\\d+)(?:[-+].*)?$/);\n if (!match) {\n return null;\n }\n\n const major = Number.parseInt(match[1], 10);\n const minor = Number.parseInt(match[2], 10);\n const patch = Number.parseInt(match[3], 10);\n if (![major, minor, patch].every(Number.isFinite)) {\n return null;\n }\n\n return [major, minor, patch];\n}\n"],"mappings":"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","names":["path","process","fs","createRequire","pc","fs","path","path","fs","fs","path","process","fs","path","process","path","fileExists","fs","process","spawn","fs","path","stringify","stringify","path","fs","fileExists","createRequire","path","path","require","require","createRequire","path","fs","os","path","spawn","require","createRequire","PNPM_BIN","process","pc","fileExists","path","fs"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/config-store.ts","../src/project-root.ts","../src/command-utils.ts","../src/runtime-layout.ts","../src/open-url.ts","../src/local-config-migrator.ts","../src/pm2-manager.ts","../src/pnpm-bin.ts","../src/service-env.ts","../src/release-bootstrap.ts","../src/cli-self-update.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport path from \"node:path\";\nimport process from \"node:process\";\nimport { spawnSync } from \"node:child_process\";\nimport { promises as fs } from \"node:fs\";\nimport { createRequire } from \"node:module\";\nimport { cac } from \"cac\";\nimport { parse as parseToml } from \"smol-toml\";\nimport pc from \"picocolors\";\nimport { saveCliConfig } from \"./config-store.js\";\nimport { assertProjectRoot, resolveProjectRoot } from \"./project-root.js\";\nimport {\n fileExists,\n GlobalOptions,\n info,\n readJsonFile,\n requiredBuildArtifacts,\n requireProjectRoot,\n runtimeConfigFiles,\n spawnPassthrough,\n success,\n warn\n} from \"./command-utils.js\";\nimport { openUrl } from \"./open-url.js\";\nimport {\n bootstrapLocalRuntime,\n getRuntimeLayoutPaths,\n hasLegacyLiveConfig,\n inspectRuntimeState,\n localRuntimeFiles\n} from \"./runtime-layout.js\";\nimport { migrateLocalConfig } from \"./local-config-migrator.js\";\nimport {\n getPm2LogCommand,\n listManagedServices,\n restartServices,\n startServices,\n stopServices\n} from \"./pm2-manager.js\";\nimport {\n bootstrapReleaseBundleFromGitHub,\n readInstalledReleaseMetadata,\n updateReleaseBundleFromGitHub\n} from \"./release-bootstrap.js\";\nimport { resolveBundledPnpmBin } from \"./pnpm-bin.js\";\nimport { getServiceEnv } from \"./service-env.js\";\nimport { maybeSelfUpdateCli } from \"./cli-self-update.js\";\n\nconst cli = cac(\"waifus\");\nconst DEFAULT_PROJECT_DIRNAME = \"Discord-Waifus\";\nconst require = createRequire(import.meta.url);\nconst packageJson = require(\"../package.json\") as { name?: string; version?: string };\nconst CLI_PACKAGE_NAME = packageJson.name ?? \"@starlight-ai/discord-waifus\";\nconst CLI_VERSION = packageJson.version ?? \"0.0.0\";\nconst SKIP_SELF_UPDATE_ENV = \"WAIFUS_SKIP_SELF_UPDATE\";\n\n// Resolve the pnpm bundled as a dependency of this CLI so users don't need it\n// globally on their PATH. We resolve pnpm's exported package entry first and\n// then derive the bin path to avoid Node 25+ export-subpath restrictions.\nconst PNPM_BIN = resolveBundledPnpmBin();\n\nasync function spawnPnpm(\n args: string[],\n cwd: string,\n envOverrides: Record<string, string> = {}\n): Promise<void> {\n await spawnPassthrough(process.execPath, [PNPM_BIN, ...args], cwd, envOverrides);\n}\n\nasync function installRuntimeDependencies(projectRoot: string): Promise<void> {\n await spawnPnpm([\"install\", \"--prod\", \"--frozen-lockfile\"], projectRoot);\n}\n\ncli.option(\"--project <path>\", \"Override the project root for this command\");\n\ncli\n .command(\"use <projectPath>\", \"Store the default Discord Waifus project root for future commands\")\n .action(async (projectPath: string) => {\n try {\n const resolvedRoot = await assertProjectRoot(projectPath);\n await saveCliConfig({ defaultProjectRoot: resolvedRoot });\n console.log(pc.green(`Default project root saved: ${resolvedRoot}`));\n } catch (error) {\n fail(error);\n }\n });\n\ncli\n .command(\"init <targetDir>\", \"Download the Discord Waifus release bundle into a target directory and register it\")\n .option(\"--repo <repo>\", \"GitHub repo URL or owner/repo slug. If omitted, uses the package repository when available.\")\n .option(\"--release <tag>\", \"GitHub release tag to download. Defaults to the latest GitHub release.\")\n .option(\"--ref <tag>\", \"Deprecated alias for --release.\")\n .option(\"--no-install\", \"Skip pnpm install after download\")\n .action(async (targetDir: string, options: { repo?: string; release?: string; ref?: string; install?: boolean }) => {\n try {\n const result = await bootstrapReleaseBundleFromGitHub(targetDir, {\n repo: options.repo ?? null,\n release: options.release ?? options.ref ?? null\n });\n await assertProjectRoot(result.projectRoot);\n\n success(`Downloaded project into ${result.projectRoot}`);\n info(formatInstalledRelease(result));\n\n await saveCliConfig({ defaultProjectRoot: result.projectRoot });\n success(`Default project root saved: ${result.projectRoot}`);\n\n if (options.install !== false) {\n info(\"Installing runtime dependencies with pnpm...\");\n await installRuntimeDependencies(result.projectRoot);\n success(\"Dependencies installed.\");\n } else {\n warn(\"Skipped pnpm install. Run `pnpm install --prod --frozen-lockfile` inside the project before starting.\");\n }\n\n info(\"Next steps:\");\n info(`- waifus init-config`);\n info(`- waifus start`);\n info(`- waifus update`);\n } catch (error) {\n fail(error);\n }\n });\n\ncli\n .command(\"update\", \"Refresh the downloaded Discord Waifus release bundle from GitHub Releases and preserve local runtime\")\n .option(\"--repo <repo>\", \"GitHub repo URL or owner/repo slug. If omitted, uses the package repository when available.\")\n .option(\"--release <tag>\", \"GitHub release tag to download. Defaults to the latest GitHub release.\")\n .option(\"--ref <tag>\", \"Deprecated alias for --release.\")\n .action(async (options: { repo?: string; release?: string; ref?: string }) => {\n try {\n const projectRoot = await requireProjectRoot(cli.options as GlobalOptions);\n const didSelfUpdate = await maybeSelfUpdateCli({\n packageName: CLI_PACKAGE_NAME,\n currentVersion: CLI_VERSION,\n cwd: process.cwd(),\n info,\n success,\n warn,\n skip: process.env[SKIP_SELF_UPDATE_ENV] === \"1\"\n });\n\n if (didSelfUpdate) {\n info(\"Restarting waifus update with the newly installed CLI...\");\n await spawnPassthrough(\n \"waifus\",\n [\"--project\", projectRoot, ...process.argv.slice(2)],\n process.cwd(),\n {\n [SKIP_SELF_UPDATE_ENV]: \"1\"\n }\n );\n return;\n }\n\n if (await fileExists(path.join(projectRoot, \".git\"))) {\n throw new Error(\n \"This project root is a git clone.\\nUse your normal git workflow here instead of `waifus update`.\"\n );\n }\n\n const services = await listManagedServices();\n const hadRunningServices = services.some(\n (service) => service.cwd === projectRoot && service.status === \"online\"\n );\n\n if (hadRunningServices) {\n info(\"Stopping managed services before update...\");\n await stopServices();\n }\n\n const result = await updateReleaseBundleFromGitHub(\n projectRoot,\n {\n repo: options.repo ?? null,\n release: options.release ?? options.ref ?? null\n },\n {\n preserveEntries: [\".waifus\", \"config\", \"data\"]\n }\n );\n\n success(`Updated project in ${result.projectRoot}`);\n info(formatInstalledRelease(result));\n\n info(\"Installing runtime dependencies with pnpm...\");\n await installRuntimeDependencies(result.projectRoot);\n success(\"Dependencies installed.\");\n\n if (hadRunningServices) {\n await startManagedServices(result.projectRoot);\n } else {\n info(\"Run `waifus start` when you want to launch the stack.\");\n }\n } catch (error) {\n fail(error);\n }\n });\n\ncli\n .command(\"doctor\", \"Validate the local setup\")\n .action(async () => {\n try {\n const projectRoot = await requireProjectRoot(cli.options as GlobalOptions);\n const nodeMajor = Number.parseInt(process.versions.node.split(\".\")[0] ?? \"0\", 10);\n const pnpmVersion = spawnSync(process.execPath, [PNPM_BIN, \"--version\"], { encoding: \"utf8\" });\n const configFiles = runtimeConfigFiles(projectRoot);\n const artifactFiles = requiredBuildArtifacts(projectRoot);\n const runtimeState = await inspectRuntimeState(projectRoot);\n const installedRelease = await readInstalledReleaseMetadata(projectRoot);\n\n console.log(pc.bold(\"waifus doctor\"));\n info(`Project root: ${projectRoot}`);\n if (installedRelease?.bundleVersion) {\n info(`Installed app release: ${installedRelease.bundleVersion}`);\n }\n\n if (Number.isFinite(nodeMajor) && nodeMajor >= 20) {\n success(`Node.js ${process.versions.node}`);\n } else {\n warn(`Node.js ${process.versions.node} detected. Recommended: Node.js 20+`);\n }\n\n if (pnpmVersion.status === 0) {\n success(`pnpm ${pnpmVersion.stdout.trim()} (bundled)`);\n } else {\n warn(\"Bundled pnpm failed to run. Try reinstalling: npm install -g @starlight-ai/discord-waifus\");\n }\n\n if (runtimeState.isCanonicalLocalRuntime) {\n success(\"Canonical local runtime detected: .waifus/\");\n } else if (runtimeState.isMigrationPending) {\n warn(\"Migration pending: legacy config still takes precedence until import completes.\");\n } else if (runtimeState.legacyLiveExists) {\n warn(\"Legacy runtime detected. Local .waifus/ bootstrap is blocked until migration.\");\n } else {\n warn(\"Local runtime not initialized. Run: waifus init-config\");\n }\n\n for (const configFile of configFiles) {\n if (await fileExists(configFile)) {\n success(`Config present: ${path.relative(projectRoot, configFile)}`);\n } else {\n warn(`Missing config: ${path.relative(projectRoot, configFile)} (run: waifus init-config)`);\n }\n }\n\n for (const artifactFile of artifactFiles) {\n if (await fileExists(artifactFile)) {\n success(`Build artifact present: ${path.relative(projectRoot, artifactFile)}`);\n } else {\n warn(`Build artifact missing: ${path.relative(projectRoot, artifactFile)}`);\n }\n }\n\n const filesToScan =\n runtimeState.isCanonicalLocalRuntime || (runtimeState.runtimeRootExists && !runtimeState.legacyLiveExists)\n ? [\n ...localRuntimeFiles(projectRoot),\n ...(await listWaifuDocumentFiles(projectRoot))\n ]\n : [\n ...legacyConfigFiles(projectRoot)\n ];\n\n for (const configFile of filesToScan) {\n if (!(await fileExists(configFile))) {\n continue;\n }\n\n const configValue = await readConfigFile(configFile);\n if (configValue === null) {\n warn(`Could not parse config: ${path.relative(projectRoot, configFile)}`);\n continue;\n }\n\n for (const envReference of findEnvReferences(configValue)) {\n if (process.env[envReference.variableName]) {\n success(\n `Environment value resolved for ${envReference.variableName} in ${path.relative(projectRoot, configFile)}`\n );\n } else {\n warn(\n `Unresolved ${envReference.raw} in ${path.relative(projectRoot, configFile)}. Export ${envReference.variableName} before start.`\n );\n }\n }\n\n if (\n configFile.endsWith(path.join(\".waifus\", \"orchestrator.toml\")) ||\n configFile.endsWith(path.join(\"config\", \"orchestrator.json\"))\n ) {\n const orchestrator =\n \"orchestrator\" in (configValue as Record<string, unknown>)\n ? ((configValue as { orchestrator?: { providerId?: string; provider_id?: string; model?: string } }).orchestrator ?? {})\n : {};\n const providerValue =\n typeof (orchestrator as { providerId?: string }).providerId === \"string\"\n ? (orchestrator as { providerId?: string }).providerId\n : typeof (orchestrator as { provider_id?: string }).provider_id === \"string\"\n ? (orchestrator as { provider_id?: string }).provider_id\n : \"\";\n const modelValue =\n typeof (orchestrator as { model?: string }).model === \"string\"\n ? (orchestrator as { model?: string }).model\n : \"\";\n\n if (\n providerValue === \"configure-me\" ||\n providerValue === \"\" ||\n modelValue === \"configure-me\" ||\n modelValue === \"\"\n ) {\n warn(\"Orchestrator config is still unconfigured. Update it in the dashboard before relying on orchestration.\");\n }\n }\n }\n\n if (runtimeState.runtimeRootExists && runtimeState.migrationState) {\n info(`Migration state: ${runtimeState.migrationState.status}`);\n }\n\n info(\"If you edit config on disk, apply it with: waifus restart\");\n } catch (error) {\n fail(error);\n }\n });\n\ncli.command(\"build\", \"Build backend and dashboard from source\").action(async () => {\n try {\n const projectRoot = await requireProjectRoot(cli.options as GlobalOptions);\n await assertBuildableProjectRoot(projectRoot);\n await spawnPnpm([\"build\"], projectRoot);\n } catch (error) {\n fail(error);\n }\n });\n\ncli\n .command(\"init-config\", \"Create or repair the local .waifus runtime layout from defaults/\")\n .option(\"--force\", \"Reserved for future explicit empty-bootstrap overrides\")\n .action(async () => {\n try {\n const projectRoot = await requireProjectRoot(cli.options as GlobalOptions);\n const legacyLiveExists = await hasLegacyLiveConfig(projectRoot);\n const runtimeState = await inspectRuntimeState(projectRoot);\n\n if (legacyLiveExists && runtimeState.migrationState?.status !== \"import_completed\") {\n throw new Error(\"Legacy live config still exists. Run: waifus migrate-local-config\");\n }\n\n const written = await bootstrapLocalRuntime(projectRoot);\n if (written.length === 0) {\n info(\"Local runtime layout already satisfied.\");\n } else {\n for (const filePath of written) {\n success(`Wrote ${path.relative(projectRoot, filePath)}`);\n }\n }\n\n info(\"Finish configuration in the dashboard after start.\");\n info(\"If you later edit config on disk, apply it with: waifus restart\");\n } catch (error) {\n fail(error);\n }\n });\n\ncli\n .command(\"migrate-local-config\", \"Import legacy config/*.json runtime data into the local .waifus layout\")\n .action(async () => {\n try {\n const projectRoot = await requireProjectRoot(cli.options as GlobalOptions);\n const result = await migrateLocalConfig(projectRoot);\n\n success(`Imported legacy runtime into .waifus/ (${result.written.length} files written).`);\n if (Object.keys(result.idMap).some((legacyId) => legacyId !== result.idMap[legacyId])) {\n info(\"Sanitized waifu IDs:\");\n for (const [legacyId, nextId] of Object.entries(result.idMap)) {\n if (legacyId === nextId) {\n continue;\n }\n info(`- ${legacyId} -> ${nextId}`);\n }\n }\n if (result.warningCount > 0) {\n warn(\n `Migration completed with ${result.warningCount} warning(s). Review ${path.relative(projectRoot, getRuntimeLayoutPaths(projectRoot).migrationWarningsFile)}`\n );\n } else {\n success(\"Migration warnings: none\");\n }\n info(\"Legacy files were left untouched. After reviewing the import, apply it with: waifus restart\");\n } catch (error) {\n fail(error);\n }\n });\n\ncli\n .command(\"start\", \"Start backend and dashboard under PM2\")\n .action(async () => {\n try {\n const projectRoot = await requireProjectRootForStart(cli.options as GlobalOptions);\n await assertNoPendingLegacyMigration(projectRoot);\n await ensureBuildArtifacts(projectRoot);\n await startManagedServices(projectRoot);\n } catch (error) {\n fail(error);\n }\n });\n\ncli.command(\"stop\", \"Stop PM2-managed backend and dashboard\").action(async () => {\n try {\n await requireProjectRoot(cli.options as GlobalOptions);\n await stopServices();\n success(\"Stopped waifus-backend and waifus-dashboard.\");\n } catch (error) {\n fail(error);\n }\n});\n\ncli\n .command(\"restart\", \"Restart PM2-managed backend and dashboard\")\n .action(async () => {\n try {\n const projectRoot = await requireProjectRoot(cli.options as GlobalOptions);\n await assertNoPendingLegacyMigration(projectRoot);\n for (const artifactFile of requiredBuildArtifacts(projectRoot)) {\n if (!(await fileExists(artifactFile))) {\n throw new Error(\n `Missing build artifact: ${path.relative(projectRoot, artifactFile)}\\nRun: waifus build`\n );\n }\n }\n\n await restartServices(projectRoot);\n success(\"Restarted waifus-backend and waifus-dashboard.\");\n info(\"Local dashboard: http://localhost:3000\");\n info(\"Local backend: http://127.0.0.1:4000\");\n warn(\"These services are local to this machine.\");\n info(\"Config changes on disk are now applied.\");\n } catch (error) {\n fail(error);\n }\n });\n\ncli.command(\"status\", \"Show PM2 service status\").action(async () => {\n try {\n await requireProjectRoot(cli.options as GlobalOptions);\n const services = await listManagedServices();\n\n console.log(pc.bold(\"waifus status\"));\n if (services.length === 0) {\n warn(\"No managed waifus PM2 services found.\");\n } else {\n for (const service of services) {\n console.log(\n [\n `- ${service.name}`,\n ` status: ${service.status}`,\n ` cwd: ${service.cwd ?? \"unknown\"}`,\n ` pid: ${service.pid ?? \"not running\"}`,\n ` restarts: ${service.restartCount}`,\n ` uptimeMs: ${service.uptimeMs ?? \"unknown\"}`\n ].join(\"\\n\")\n );\n }\n }\n\n try {\n const response = await fetch(\"http://127.0.0.1:4000/api/status\");\n if (response.ok) {\n const payload = (await response.json()) as { uptimeSeconds?: number };\n info(`Backend health: reachable on 127.0.0.1:4000 (uptimeSeconds=${payload.uptimeSeconds ?? \"unknown\"})`);\n } else {\n warn(`Backend health check returned HTTP ${response.status}`);\n }\n } catch {\n warn(\"Backend health: not reachable on 127.0.0.1:4000\");\n }\n\n warn(\"These services are local to this machine.\");\n } catch (error) {\n fail(error);\n }\n});\n\ncli\n .command(\"logs [service]\", \"Tail PM2 logs for backend, dashboard, or both\")\n .option(\"--lines <count>\", \"How many recent lines to include\", { default: \"100\" })\n .action(async (service: string | undefined, options: { lines: string }) => {\n try {\n await requireProjectRoot(cli.options as GlobalOptions);\n const normalizedService =\n service === \"backend\" || service === \"dashboard\" ? service : service ? null : null;\n\n if (service && !normalizedService) {\n throw new Error(\"Invalid service. Use: waifus logs | waifus logs backend | waifus logs dashboard\");\n }\n\n const lineCount = Number.parseInt(options.lines, 10);\n if (!Number.isFinite(lineCount) || lineCount <= 0) {\n throw new Error(\"Invalid --lines value. Use a positive integer.\");\n }\n\n const logCommand = getPm2LogCommand(normalizedService, lineCount);\n await spawnPassthrough(logCommand.command, logCommand.args, process.cwd());\n } catch (error) {\n fail(error);\n }\n });\n\ncli.command(\"open\", \"Open the local dashboard in the browser\").action(async () => {\n try {\n await requireProjectRoot(cli.options as GlobalOptions);\n await openUrl(\"http://localhost:3000\");\n success(\"Opened http://localhost:3000\");\n } catch (error) {\n fail(error);\n }\n});\n\ncli\n .command(\"run <service>\", \"Run backend or dashboard in the foreground\")\n .action(async (service: string) => {\n try {\n const projectRoot = await requireProjectRoot(cli.options as GlobalOptions);\n if (service !== \"backend\" && service !== \"dashboard\") {\n throw new Error(\"Invalid service. Use: waifus run backend | waifus run dashboard\");\n }\n\n const filterTarget = service === \"backend\" ? \"backend\" : \"dashboard\";\n await spawnPnpm([\"--filter\", filterTarget, \"start\"], projectRoot, getServiceEnv(service));\n } catch (error) {\n fail(error);\n }\n });\n\ncli.help();\ncli.version(CLI_VERSION);\n\nif (process.argv.length <= 2) {\n runDefaultCommand().catch(fail);\n} else {\n cli.parse(process.argv);\n}\n\nfunction fail(error: unknown): never {\n const message = error instanceof Error ? error.message : \"Unknown CLI error\";\n console.error(pc.red(message));\n process.exit(1);\n}\n\nasync function listWaifuDocumentFiles(projectRoot: string): Promise<string[]> {\n const paths = getRuntimeLayoutPaths(projectRoot);\n try {\n const entries = await fs.readdir(paths.runtimeWaifusRoot, { withFileTypes: true });\n return entries\n .filter((entry) => entry.isFile() && entry.name.endsWith(\".json\"))\n .map((entry) => path.join(paths.runtimeWaifusRoot, entry.name));\n } catch {\n return [];\n }\n}\n\nfunction legacyConfigFiles(projectRoot: string): string[] {\n const paths = getRuntimeLayoutPaths(projectRoot);\n return [\n paths.legacyWaifusFile,\n paths.legacyProvidersFile,\n paths.legacyChannelsFile,\n paths.legacyOrchestratorFile,\n paths.legacyStageManagerFile\n ];\n}\n\nasync function readConfigFile(filePath: string): Promise<unknown | null> {\n try {\n if (filePath.endsWith(\".json\")) {\n return await readJsonFile(filePath);\n }\n\n if (filePath.endsWith(\".toml\")) {\n return parseToml(await fs.readFile(filePath, \"utf8\"));\n }\n\n return null;\n } catch {\n return null;\n }\n}\n\nasync function assertNoPendingLegacyMigration(projectRoot: string): Promise<void> {\n const runtimeState = await inspectRuntimeState(projectRoot);\n if (runtimeState.legacyLiveExists && runtimeState.migrationState?.status !== \"import_completed\") {\n throw new Error(\"Legacy live config still exists. Run: waifus migrate-local-config\");\n }\n}\n\nasync function requireProjectRootForStart(options: GlobalOptions): Promise<string> {\n const resolvedProjectRoot = await resolveProjectRoot({\n cwd: process.cwd(),\n explicitProjectRoot: options.project ?? null\n });\n\n if (resolvedProjectRoot) {\n return resolvedProjectRoot;\n }\n\n if (options.project) {\n throw new Error(`No valid project root found at ${options.project}`);\n }\n\n return bootstrapDefaultProjectRoot();\n}\n\nasync function runDefaultCommand(): Promise<void> {\n const options = cli.options as GlobalOptions;\n const projectRoot = await requireProjectRootForStart(options);\n await assertNoPendingLegacyMigration(projectRoot);\n\n if (!(await hasCanonicalRuntime(projectRoot))) {\n info(\"Initializing local runtime...\");\n const written = await bootstrapLocalRuntime(projectRoot);\n if (written.length === 0) {\n info(\"Local runtime already initialized.\");\n } else {\n for (const filePath of written) {\n success(`Wrote ${path.relative(projectRoot, filePath)}`);\n }\n }\n }\n\n await ensureBuildArtifacts(projectRoot);\n await startManagedServices(projectRoot);\n}\n\nasync function bootstrapDefaultProjectRoot(): Promise<string> {\n const targetDir = path.join(process.env.HOME ?? process.cwd(), DEFAULT_PROJECT_DIRNAME);\n info(`No project configured. Bootstrapping into ${targetDir}`);\n\n const result = await bootstrapReleaseBundleFromGitHub(targetDir, {});\n await assertProjectRoot(result.projectRoot);\n await saveCliConfig({ defaultProjectRoot: result.projectRoot });\n\n success(`Downloaded project into ${result.projectRoot}`);\n info(formatInstalledRelease(result));\n success(`Default project root saved: ${result.projectRoot}`);\n\n info(\"Installing runtime dependencies with pnpm...\");\n await installRuntimeDependencies(result.projectRoot);\n success(\"Dependencies installed.\");\n\n return result.projectRoot;\n}\n\nasync function hasCanonicalRuntime(projectRoot: string): Promise<boolean> {\n const runtimeState = await inspectRuntimeState(projectRoot);\n return runtimeState.isCanonicalLocalRuntime;\n}\n\nasync function ensureBuildArtifacts(projectRoot: string): Promise<void> {\n const missingArtifacts = [];\n\n for (const artifactFile of requiredBuildArtifacts(projectRoot)) {\n if (!(await fileExists(artifactFile))) {\n missingArtifacts.push(path.relative(projectRoot, artifactFile));\n }\n }\n\n if (missingArtifacts.length === 0) {\n return;\n }\n\n if (!(await hasBuildSources(projectRoot))) {\n throw new Error(\n `Missing build artifact(s): ${missingArtifacts.join(\", \")}\\nThis install uses a prebuilt release bundle. Run: waifus update`\n );\n }\n\n info(\"Build artifacts missing. Running `waifus build` automatically...\");\n await spawnPnpm([\"build\"], projectRoot);\n}\n\nasync function hasBuildSources(projectRoot: string): Promise<boolean> {\n return (\n (await fileExists(path.join(projectRoot, \"packages\", \"backend\", \"src\", \"index.ts\"))) &&\n (await fileExists(path.join(projectRoot, \"packages\", \"dashboard\", \"src\", \"app\", \"layout.tsx\")))\n );\n}\n\nasync function assertBuildableProjectRoot(projectRoot: string): Promise<void> {\n if (await hasBuildSources(projectRoot)) {\n return;\n }\n\n throw new Error(\n \"This install is a prebuilt GitHub Release bundle and does not include source code.\\nUse: waifus update\"\n );\n}\n\nasync function startManagedServices(projectRoot: string): Promise<void> {\n await startServices(projectRoot);\n success(\"Started waifus-backend and waifus-dashboard through PM2.\");\n info(\"Local dashboard: http://localhost:3000\");\n info(\"Local backend: http://127.0.0.1:4000\");\n warn(\"These services are local to this machine.\");\n info(\"If you edit config on disk, apply it with: waifus restart\");\n}\n\nfunction formatInstalledRelease(result: {\n sourceRepo: string;\n releaseTag: string;\n bundleVersion: string | null;\n publishedAt?: string | null;\n}): string {\n const details = [`Release: ${result.sourceRepo} @ ${result.releaseTag}`];\n if (result.bundleVersion) {\n details.push(`bundle ${result.bundleVersion}`);\n }\n if (result.publishedAt) {\n details.push(`published ${result.publishedAt}`);\n }\n return details.join(\" | \");\n}\n\nfunction findEnvReferences(value: unknown): Array<{ raw: string; variableName: string }> {\n const references: Array<{ raw: string; variableName: string }> = [];\n\n visit(value, (candidate) => {\n if (typeof candidate !== \"string\") {\n return;\n }\n\n const envPrefixMatch = candidate.match(/^env:([A-Z0-9_]+)$/i);\n if (envPrefixMatch) {\n references.push({\n raw: candidate,\n variableName: envPrefixMatch[1]\n });\n return;\n }\n\n const templateMatch = candidate.match(/^\\$\\{([A-Z0-9_]+)\\}$/i);\n if (templateMatch) {\n references.push({\n raw: candidate,\n variableName: templateMatch[1]\n });\n }\n });\n\n return references;\n}\n\nfunction visit(value: unknown, callback: (candidate: unknown) => void): void {\n callback(value);\n if (Array.isArray(value)) {\n for (const entry of value) {\n visit(entry, callback);\n }\n return;\n }\n\n if (value && typeof value === \"object\") {\n for (const entry of Object.values(value)) {\n visit(entry, callback);\n }\n }\n}\n","import { promises as fs } from \"node:fs\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport { z } from \"zod\";\n\nconst cliConfigSchema = z.object({\n defaultProjectRoot: z.string().min(1).nullable().default(null)\n});\n\nexport type CliConfig = z.infer<typeof cliConfigSchema>;\n\nexport function getCliConfigPath(): string {\n const configHome = process.env.WAIFUS_CONFIG_HOME?.trim();\n if (configHome) {\n return path.resolve(configHome, \"config.json\");\n }\n\n return path.join(os.homedir(), \".config\", \"waifus\", \"config.json\");\n}\n\nexport async function loadCliConfig(): Promise<CliConfig> {\n const filePath = getCliConfigPath();\n\n try {\n const raw = await fs.readFile(filePath, \"utf8\");\n return cliConfigSchema.parse(JSON.parse(raw));\n } catch (error) {\n const code = (error as NodeJS.ErrnoException | undefined)?.code;\n if (code === \"ENOENT\") {\n return cliConfigSchema.parse({});\n }\n throw error;\n }\n}\n\nexport async function saveCliConfig(nextConfig: CliConfig): Promise<void> {\n const filePath = getCliConfigPath();\n await fs.mkdir(path.dirname(filePath), { recursive: true });\n await fs.writeFile(filePath, `${JSON.stringify(cliConfigSchema.parse(nextConfig), null, 2)}\\n`, \"utf8\");\n}\n","import { promises as fs } from \"node:fs\";\nimport path from \"node:path\";\nimport { loadCliConfig } from \"./config-store.js\";\n\nconst projectMarkers = [\n \"package.json\",\n \"pnpm-workspace.yaml\",\n path.join(\"packages\", \"backend\"),\n path.join(\"packages\", \"dashboard\"),\n \"defaults\"\n];\n\nexport interface ResolveProjectRootOptions {\n cwd?: string;\n explicitProjectRoot?: string | null;\n}\n\nexport async function isValidProjectRoot(projectRoot: string): Promise<boolean> {\n const resolvedRoot = path.resolve(projectRoot);\n\n for (const marker of projectMarkers) {\n try {\n await fs.access(path.join(resolvedRoot, marker));\n } catch {\n return false;\n }\n }\n\n return true;\n}\n\nexport async function resolveProjectRoot(\n options: ResolveProjectRootOptions = {}\n): Promise<string | null> {\n const cwd = path.resolve(options.cwd ?? process.cwd());\n const explicitProjectRoot = options.explicitProjectRoot ? path.resolve(options.explicitProjectRoot) : null;\n\n if (explicitProjectRoot && (await isValidProjectRoot(explicitProjectRoot))) {\n return explicitProjectRoot;\n }\n\n const config = await loadCliConfig();\n if (config.defaultProjectRoot && (await isValidProjectRoot(config.defaultProjectRoot))) {\n return path.resolve(config.defaultProjectRoot);\n }\n\n for (const candidate of walkParentDirectories(cwd)) {\n if (await isValidProjectRoot(candidate)) {\n return candidate;\n }\n }\n\n return null;\n}\n\nexport async function assertProjectRoot(projectRoot: string): Promise<string> {\n const resolvedRoot = path.resolve(projectRoot);\n if (!(await isValidProjectRoot(resolvedRoot))) {\n throw new Error(\n `Invalid Discord Waifus project root: ${resolvedRoot}\\nExpected: package.json, pnpm-workspace.yaml, packages/backend/, packages/dashboard/, and defaults/`\n );\n }\n return resolvedRoot;\n}\n\nfunction* walkParentDirectories(start: string): Generator<string> {\n let current = start;\n\n while (true) {\n yield current;\n const parent = path.dirname(current);\n if (parent === current) {\n return;\n }\n current = parent;\n }\n}\n","import { promises as fs } from \"node:fs\";\nimport path from \"node:path\";\nimport process from \"node:process\";\nimport { spawn } from \"node:child_process\";\nimport pc from \"picocolors\";\nimport { resolveProjectRoot } from \"./project-root.js\";\nimport { defaultSeedFiles, localRuntimeFiles } from \"./runtime-layout.js\";\n\nexport interface GlobalOptions {\n project?: string;\n}\n\nexport async function requireProjectRoot(options: GlobalOptions): Promise<string> {\n const projectRoot = await resolveProjectRoot({\n cwd: process.cwd(),\n explicitProjectRoot: options.project ?? null\n });\n\n if (!projectRoot) {\n throw new Error(\"No project root is configured.\\nRun: waifus use /path/to/Discord-Waifus\");\n }\n\n return projectRoot;\n}\n\nexport function runtimeConfigFiles(projectRoot: string): string[] {\n return [...defaultSeedFiles(projectRoot), ...localRuntimeFiles(projectRoot)];\n}\n\nexport function requiredBuildArtifacts(projectRoot: string): string[] {\n return [\n path.join(projectRoot, \"packages\", \"backend\", \"dist\", \"index.js\"),\n path.join(projectRoot, \"packages\", \"dashboard\", \".next\", \"BUILD_ID\")\n ];\n}\n\nexport async function fileExists(filePath: string): Promise<boolean> {\n try {\n await fs.access(filePath);\n return true;\n } catch {\n return false;\n }\n}\n\nexport async function readJsonFile(filePath: string): Promise<unknown> {\n return JSON.parse(await fs.readFile(filePath, \"utf8\"));\n}\n\nexport async function spawnPassthrough(\n command: string,\n args: string[],\n cwd: string,\n envOverrides: Record<string, string> = {}\n): Promise<void> {\n await new Promise<void>((resolve, reject) => {\n const child = spawn(command, args, {\n cwd,\n stdio: \"inherit\",\n env: {\n ...process.env,\n ...envOverrides\n }\n });\n\n child.once(\"error\", reject);\n child.once(\"exit\", (code, signal) => {\n if (signal) {\n reject(new Error(`${command} exited due to signal ${signal}`));\n return;\n }\n if (code && code !== 0) {\n reject(new Error(`${command} ${args.join(\" \")} failed with exit code ${code}`));\n return;\n }\n resolve();\n });\n });\n}\n\nexport function info(message: string): void {\n console.log(pc.cyan(message));\n}\n\nexport function success(message: string): void {\n console.log(pc.green(message));\n}\n\nexport function warn(message: string): void {\n console.log(pc.yellow(message));\n}\n","import { promises as fs } from \"node:fs\";\nimport path from \"node:path\";\nimport { stringify } from \"smol-toml\";\n\nexport interface RuntimeLayoutPaths {\n defaultsRoot: string;\n runtimeRoot: string;\n runtimeConfigFile: string;\n runtimeProvidersFile: string;\n runtimeKeysFile: string;\n runtimeChannelsFile: string;\n runtimeOrchestratorFile: string;\n runtimeStageManagerFile: string;\n runtimeWaifusRoot: string;\n runtimeStageManagerDataRoot: string;\n runtimeAssetsWaifusRoot: string;\n runtimeStateRoot: string;\n migrationStateFile: string;\n migrationWarningsFile: string;\n stageManagerCheckpointsFile: string;\n defaultsConfigFile: string;\n defaultsChannelsFile: string;\n defaultsOrchestratorFile: string;\n defaultsStageManagerFile: string;\n defaultsProviderCatalogFile: string;\n defaultsWaifuTemplateFile: string;\n legacyConfigRoot: string;\n legacyDataRoot: string;\n legacyWaifusFile: string;\n legacyProvidersFile: string;\n legacyChannelsFile: string;\n legacyOrchestratorFile: string;\n legacyStageManagerFile: string;\n legacyStageManagerStateFile: string;\n}\n\nexport interface MigrationStateFile {\n schemaVersion: number;\n status: \"bootstrap_empty\" | \"import_completed\";\n createdAt: string;\n completedAt: string;\n}\n\nexport interface RuntimeStateInspection {\n paths: RuntimeLayoutPaths;\n runtimeRootExists: boolean;\n legacyLiveExists: boolean;\n migrationState: MigrationStateFile | null;\n isCanonicalLocalRuntime: boolean;\n isMigrationPending: boolean;\n}\n\nexport function getRuntimeLayoutPaths(projectRoot: string): RuntimeLayoutPaths {\n const defaultsRoot = path.join(projectRoot, \"defaults\");\n const runtimeRoot = path.join(projectRoot, \".waifus\");\n const runtimeStateRoot = path.join(runtimeRoot, \"state\");\n const legacyConfigRoot = path.join(projectRoot, \"config\");\n const legacyDataRoot = path.join(projectRoot, \"data\");\n\n return {\n defaultsRoot,\n runtimeRoot,\n runtimeConfigFile: path.join(runtimeRoot, \"config.toml\"),\n runtimeProvidersFile: path.join(runtimeRoot, \"providers.toml\"),\n runtimeKeysFile: path.join(runtimeRoot, \"keys.toml\"),\n runtimeChannelsFile: path.join(runtimeRoot, \"channels.toml\"),\n runtimeOrchestratorFile: path.join(runtimeRoot, \"orchestrator.toml\"),\n runtimeStageManagerFile: path.join(runtimeRoot, \"stage-manager.toml\"),\n runtimeWaifusRoot: path.join(runtimeRoot, \"waifus\"),\n runtimeStageManagerDataRoot: path.join(runtimeRoot, \"stage-manager-data\"),\n runtimeAssetsWaifusRoot: path.join(runtimeRoot, \"assets\", \"waifus\"),\n runtimeStateRoot,\n migrationStateFile: path.join(runtimeStateRoot, \"migration-state.json\"),\n migrationWarningsFile: path.join(runtimeStateRoot, \"migration-warnings.json\"),\n stageManagerCheckpointsFile: path.join(runtimeStateRoot, \"stage-manager-checkpoints.json\"),\n defaultsConfigFile: path.join(defaultsRoot, \"config.toml\"),\n defaultsChannelsFile: path.join(defaultsRoot, \"channels.toml\"),\n defaultsOrchestratorFile: path.join(defaultsRoot, \"orchestrator.toml\"),\n defaultsStageManagerFile: path.join(defaultsRoot, \"stage-manager.toml\"),\n defaultsProviderCatalogFile: path.join(defaultsRoot, \"providers.catalog.json\"),\n defaultsWaifuTemplateFile: path.join(defaultsRoot, \"waifus\", \"default-waifu.json\"),\n legacyConfigRoot,\n legacyDataRoot,\n legacyWaifusFile: path.join(legacyConfigRoot, \"waifus.json\"),\n legacyProvidersFile: path.join(legacyConfigRoot, \"providers.json\"),\n legacyChannelsFile: path.join(legacyConfigRoot, \"channels.json\"),\n legacyOrchestratorFile: path.join(legacyConfigRoot, \"orchestrator.json\"),\n legacyStageManagerFile: path.join(legacyConfigRoot, \"stage-manager.json\"),\n legacyStageManagerStateFile: path.join(legacyDataRoot, \"stage-manager-state.json\")\n };\n}\n\nexport async function inspectRuntimeState(projectRoot: string): Promise<RuntimeStateInspection> {\n const paths = getRuntimeLayoutPaths(projectRoot);\n const runtimeRootExists = await fileExists(paths.runtimeRoot);\n const legacyLiveExists = await hasLegacyLiveConfig(projectRoot);\n const migrationState = await readMigrationState(paths.migrationStateFile);\n const isCanonicalLocalRuntime =\n Boolean(runtimeRootExists) &&\n (\n migrationState?.status === \"import_completed\" ||\n (migrationState?.status === \"bootstrap_empty\" && !legacyLiveExists) ||\n (!migrationState && !legacyLiveExists)\n );\n\n return {\n paths,\n runtimeRootExists,\n legacyLiveExists,\n migrationState,\n isCanonicalLocalRuntime,\n isMigrationPending: Boolean(runtimeRootExists && legacyLiveExists && migrationState?.status !== \"import_completed\")\n };\n}\n\nexport async function hasLegacyLiveConfig(projectRoot: string): Promise<boolean> {\n const paths = getRuntimeLayoutPaths(projectRoot);\n const candidates = [\n paths.legacyWaifusFile,\n paths.legacyProvidersFile,\n paths.legacyChannelsFile,\n paths.legacyOrchestratorFile,\n paths.legacyStageManagerFile,\n paths.legacyStageManagerStateFile\n ];\n\n for (const candidate of candidates) {\n if (await fileExists(candidate)) {\n return true;\n }\n }\n\n return false;\n}\n\nexport async function bootstrapLocalRuntime(projectRoot: string): Promise<string[]> {\n const inspection = await inspectRuntimeState(projectRoot);\n if (inspection.legacyLiveExists && inspection.migrationState?.status !== \"import_completed\") {\n throw new Error(\"Legacy live config still exists. Run: waifus migrate-local-config\");\n }\n\n return seedLocalRuntimeFromDefaults(projectRoot, {\n writeBootstrapMigrationState: !inspection.migrationState && !inspection.legacyLiveExists\n });\n}\n\nexport async function seedLocalRuntimeFromDefaults(\n projectRoot: string,\n options: { writeBootstrapMigrationState: boolean }\n): Promise<string[]> {\n const inspection = await inspectRuntimeState(projectRoot);\n\n const paths = inspection.paths;\n const written: string[] = [];\n\n await Promise.all([\n fs.mkdir(paths.runtimeWaifusRoot, { recursive: true }),\n fs.mkdir(paths.runtimeStageManagerDataRoot, { recursive: true }),\n fs.mkdir(paths.runtimeAssetsWaifusRoot, { recursive: true }),\n fs.mkdir(paths.runtimeStateRoot, { recursive: true })\n ]);\n\n written.push(\n await ensureCopied(paths.defaultsConfigFile, paths.runtimeConfigFile),\n await ensureCopied(paths.defaultsChannelsFile, paths.runtimeChannelsFile),\n await ensureSeededProviders(paths.defaultsProviderCatalogFile, paths.runtimeProvidersFile),\n await ensureFile(paths.runtimeKeysFile, `${stringify({ provider_keys: [] })}\\n`),\n await ensureCopied(paths.defaultsOrchestratorFile, paths.runtimeOrchestratorFile),\n await ensureCopied(paths.defaultsStageManagerFile, paths.runtimeStageManagerFile),\n await ensureJsonFile(paths.stageManagerCheckpointsFile, { guilds: {} }),\n await ensureJsonFile(paths.migrationWarningsFile, {\n schemaVersion: 1,\n globalWarnings: [],\n waifuWarnings: {}\n })\n );\n\n if (options.writeBootstrapMigrationState) {\n written.push(\n await ensureJsonFile(paths.migrationStateFile, {\n schemaVersion: 1,\n status: \"bootstrap_empty\",\n createdAt: new Date().toISOString(),\n completedAt: new Date().toISOString()\n })\n );\n }\n\n return written.filter(Boolean);\n}\n\nexport function defaultSeedFiles(projectRoot: string): string[] {\n const paths = getRuntimeLayoutPaths(projectRoot);\n return [\n paths.defaultsConfigFile,\n paths.defaultsChannelsFile,\n paths.defaultsOrchestratorFile,\n paths.defaultsStageManagerFile,\n paths.defaultsProviderCatalogFile,\n paths.defaultsWaifuTemplateFile\n ];\n}\n\nexport function localRuntimeFiles(projectRoot: string): string[] {\n const paths = getRuntimeLayoutPaths(projectRoot);\n return [\n paths.runtimeConfigFile,\n paths.runtimeProvidersFile,\n paths.runtimeKeysFile,\n paths.runtimeChannelsFile,\n paths.runtimeOrchestratorFile,\n paths.runtimeStageManagerFile,\n paths.migrationStateFile,\n paths.migrationWarningsFile,\n paths.stageManagerCheckpointsFile\n ];\n}\n\nasync function ensureSeededProviders(catalogFile: string, providersFile: string): Promise<string> {\n if (await fileExists(providersFile)) {\n return \"\";\n }\n\n const catalog = JSON.parse(await fs.readFile(catalogFile, \"utf8\")) as {\n providers?: Array<{\n id: string;\n name: string;\n type: string;\n authMode?: string;\n enabledByDefault?: boolean;\n baseUrl: string;\n models?: string[];\n }>;\n };\n const tomlValue = {\n providers: (catalog.providers ?? []).map((entry) => ({\n id: entry.id,\n origin: \"built-in\",\n name: entry.name,\n type: entry.type,\n auth_mode: entry.authMode ?? \"required\",\n enabled: entry.enabledByDefault ?? false,\n base_url: entry.baseUrl,\n models: entry.models ?? []\n }))\n };\n await fs.mkdir(path.dirname(providersFile), { recursive: true });\n await fs.writeFile(providersFile, `${stringify(tomlValue)}\\n`, \"utf8\");\n return providersFile;\n}\n\nasync function ensureCopied(sourceFile: string, targetFile: string): Promise<string> {\n if (await fileExists(targetFile)) {\n return \"\";\n }\n\n const contents = await fs.readFile(sourceFile, \"utf8\");\n await fs.mkdir(path.dirname(targetFile), { recursive: true });\n await fs.writeFile(targetFile, contents, \"utf8\");\n return targetFile;\n}\n\nasync function ensureFile(targetFile: string, contents: string): Promise<string> {\n if (await fileExists(targetFile)) {\n return \"\";\n }\n\n await fs.mkdir(path.dirname(targetFile), { recursive: true });\n await fs.writeFile(targetFile, contents, \"utf8\");\n return targetFile;\n}\n\nasync function ensureJsonFile(targetFile: string, value: unknown): Promise<string> {\n return ensureFile(targetFile, `${JSON.stringify(value, null, 2)}\\n`);\n}\n\nasync function readMigrationState(filePath: string): Promise<MigrationStateFile | null> {\n try {\n return JSON.parse(await fs.readFile(filePath, \"utf8\")) as MigrationStateFile;\n } catch (error) {\n const code = (error as NodeJS.ErrnoException | undefined)?.code;\n if (code === \"ENOENT\") {\n return null;\n }\n throw error;\n }\n}\n\nasync function fileExists(filePath: string): Promise<boolean> {\n try {\n await fs.access(filePath);\n return true;\n } catch {\n return false;\n }\n}\n","import process from \"node:process\";\nimport { spawn } from \"node:child_process\";\n\nexport async function openUrl(url: string): Promise<void> {\n const platform = process.platform;\n\n if (platform === \"darwin\") {\n await spawnDetached(\"open\", [url]);\n return;\n }\n\n if (platform === \"win32\") {\n await spawnDetached(\"cmd\", [\"/c\", \"start\", \"\", url]);\n return;\n }\n\n await spawnDetached(\"xdg-open\", [url]);\n}\n\nasync function spawnDetached(command: string, args: string[]): Promise<void> {\n await new Promise<void>((resolve, reject) => {\n const child = spawn(command, args, {\n detached: true,\n stdio: \"ignore\",\n env: process.env\n });\n\n child.once(\"error\", reject);\n child.once(\"spawn\", () => {\n child.unref();\n resolve();\n });\n });\n}\n","import { promises as fs } from \"node:fs\";\nimport path from \"node:path\";\nimport { stringify } from \"smol-toml\";\nimport { getRuntimeLayoutPaths, inspectRuntimeState, seedLocalRuntimeFromDefaults } from \"./runtime-layout.js\";\n\ninterface LegacyProvider {\n id: string;\n name: string;\n type: \"openai-compatible\" | \"anthropic\";\n baseUrl: string;\n apiKey: string;\n enabled: boolean;\n models: string[];\n}\n\ninterface LegacyWaifu {\n id: string;\n name: string;\n displayName: string;\n botToken: string;\n applicationId: string;\n enabled: boolean;\n avatarPath: string | null;\n bannerPath: string | null;\n statusText: string | null;\n statusType: \"online\" | \"idle\" | \"dnd\" | \"invisible\";\n personality: {\n description: string;\n traits: string[];\n speechPatterns: string[];\n likes: string[];\n dislikes: string[];\n backstory: string;\n quirks: string[];\n relationshipsWithOtherWaifus: Record<string, string>;\n };\n schedule: {\n sleepTime: { start: string; end: string };\n busyTime: { start: string; end: string; reason: string };\n };\n ai: {\n providerId: string;\n model: string;\n temperature: number;\n repetitionPenalty: number;\n maxTokens: number;\n systemPromptOverride: string | null;\n };\n}\n\ninterface LegacyChannel {\n guildId: string;\n channelId: string;\n channelName: string;\n enabled: boolean;\n activeWaifuIds: string[];\n contextAnchorMessageId: string | null;\n contextMessageCount: number;\n idleChatterEnabled: boolean;\n idleTimerMinSeconds: number;\n idleTimerMaxSeconds: number;\n}\n\ninterface LegacyRelationshipEntry {\n targetKind: \"user\" | \"waifu\";\n targetName: string;\n targetUserId: string | null;\n targetWaifuId: string | null;\n relationship: string;\n updatedAt: string;\n}\n\ninterface LegacyMemoryNote {\n slot: number;\n note: string;\n sourceMessageIds: string[];\n updatedAt: string;\n}\n\ninterface LegacyStageManagerState {\n waifus: Record<\n string,\n {\n relationshipsByParticipant: Record<string, LegacyRelationshipEntry>;\n memories: LegacyMemoryNote[];\n }\n >;\n channels: Record<\n string,\n {\n lastProcessedMessageId: string | null;\n lastRunAt: string | null;\n }\n >;\n}\n\ninterface CatalogProvider {\n id: string;\n name: string;\n type: \"openai-compatible\" | \"anthropic\";\n authMode: \"required\" | \"none\";\n enabledByDefault: boolean;\n baseUrl: string;\n models: string[];\n}\n\ninterface MigrationWarning {\n code: string;\n field: string;\n message: string;\n legacyValue?: string;\n createdAt: string;\n}\n\ninterface MigrationWarningsFile {\n schemaVersion: number;\n globalWarnings: MigrationWarning[];\n waifuWarnings: Record<string, MigrationWarning[]>;\n}\n\nexport interface MigrationResult {\n written: string[];\n idMap: Record<string, string>;\n warningCount: number;\n}\n\nexport async function migrateLocalConfig(projectRoot: string): Promise<MigrationResult> {\n const runtimeState = await inspectRuntimeState(projectRoot);\n if (!runtimeState.legacyLiveExists) {\n throw new Error(\"No legacy runtime files found to import.\");\n }\n if (runtimeState.migrationState?.status === \"import_completed\") {\n throw new Error(\"Legacy import already completed for this project.\");\n }\n\n const paths = runtimeState.paths;\n const timestamp = new Date().toISOString();\n const warnings: MigrationWarningsFile = {\n schemaVersion: 1,\n globalWarnings: [],\n waifuWarnings: {}\n };\n\n const [legacyWaifusFile, legacyProvidersFile, legacyChannelsFile, legacyOrchestratorFile, legacyStageManagerFile, legacyStageManagerStateFile, catalogFile] =\n await Promise.all([\n readJson<{\n waifus: LegacyWaifu[];\n }>(paths.legacyWaifusFile, { waifus: [] }),\n readJson<{\n providers: LegacyProvider[];\n }>(paths.legacyProvidersFile, { providers: [] }),\n readJson<{\n channels: LegacyChannel[];\n }>(paths.legacyChannelsFile, { channels: [] }),\n readJson(paths.legacyOrchestratorFile, {\n orchestrator: {\n providerId: \"configure-me\",\n model: \"configure-me\",\n temperature: 0.7,\n maxTokens: 500\n }\n }),\n readJson(paths.legacyStageManagerFile, {\n stageManager: {\n enabled: true,\n providerId: null,\n model: null,\n temperature: 0.4,\n maxTokens: 500,\n quietPeriodSeconds: 300,\n historyLimit: 60,\n maxRelationshipsPerWaifu: 20,\n maxMemoriesPerWaifu: 8\n }\n }),\n readJson<LegacyStageManagerState>(paths.legacyStageManagerStateFile, {\n waifus: {},\n channels: {}\n }),\n readJson<{\n providers: CatalogProvider[];\n }>(paths.defaultsProviderCatalogFile, { providers: [] })\n ]);\n\n const idMap = buildWaifuIdMap(legacyWaifusFile.waifus);\n const catalogById = new Map(catalogFile.providers.map((entry) => [entry.id, entry] as const));\n const written = await seedLocalRuntimeFromDefaults(projectRoot, {\n writeBootstrapMigrationState: false\n });\n\n const migratedWaifus = await Promise.all(\n legacyWaifusFile.waifus.map(async (waifu) => {\n const nextId = idMap[waifu.id];\n const migratedAssets = await migrateWaifuAssets(\n paths,\n waifu,\n nextId,\n warnings,\n timestamp\n );\n\n if (waifu.id !== nextId) {\n addWaifuWarning(warnings, nextId, {\n code: \"legacy_id_sanitized\",\n field: \"id\",\n message: `Legacy waifu id \"${waifu.id}\" was sanitized to \"${nextId}\".`,\n legacyValue: waifu.id,\n createdAt: timestamp\n });\n }\n\n return {\n schemaVersion: 1,\n id: nextId,\n name: waifu.name,\n displayName: waifu.displayName,\n botToken: waifu.botToken,\n applicationId: waifu.applicationId,\n enabled: waifu.enabled,\n avatarPath: migratedAssets.avatarPath,\n bannerPath: migratedAssets.bannerPath,\n statusText: waifu.statusText,\n statusType: waifu.statusType,\n personality: {\n ...waifu.personality,\n relationshipsWithOtherWaifus: Object.fromEntries(\n Object.entries(waifu.personality.relationshipsWithOtherWaifus).map(([relationshipId, value]) => [\n idMap[relationshipId] ?? relationshipId,\n value\n ])\n )\n },\n schedule: waifu.schedule,\n ai: {\n ...waifu.ai,\n providerId: waifu.ai.providerId\n }\n };\n })\n );\n\n const migratedChannels = legacyChannelsFile.channels.map((channel) => ({\n guildId: channel.guildId,\n channelId: channel.channelId,\n channelName: channel.channelName,\n enabled: channel.enabled,\n activeWaifuIds: channel.activeWaifuIds.map((waifuId) => idMap[waifuId] ?? waifuId),\n contextAnchorMessageId: channel.contextAnchorMessageId ?? \"\",\n contextMessageCount: channel.contextMessageCount,\n idleChatterEnabled: channel.idleChatterEnabled,\n idleTimerMinSeconds: channel.idleTimerMinSeconds,\n idleTimerMaxSeconds: channel.idleTimerMaxSeconds\n }));\n\n const migratedProviders = legacyProvidersFile.providers.map((provider) => {\n const catalog = catalogById.get(provider.id);\n return {\n id: provider.id,\n origin: catalog ? (\"built-in\" as const) : (\"custom\" as const),\n name: provider.name,\n type: provider.type,\n authMode: catalog?.authMode ?? deriveAuthMode(provider.id),\n enabled: provider.enabled,\n baseUrl: provider.baseUrl,\n models: provider.models\n };\n });\n\n const migratedProviderKeys = legacyProvidersFile.providers\n .map((provider) => {\n const authMode = catalogById.get(provider.id)?.authMode ?? deriveAuthMode(provider.id);\n if (authMode === \"none\" || !provider.apiKey) {\n return null;\n }\n return {\n id: provider.id,\n apiKey: provider.apiKey\n };\n })\n .filter((entry): entry is { id: string; apiKey: string } => Boolean(entry));\n\n const waifuGuilds = buildWaifuGuilds(migratedChannels);\n const migratedStageManagerDocuments = Object.fromEntries(\n migratedWaifus.map((waifu) => {\n const legacyState = legacyStageManagerStateFile.waifus[findLegacyIdForNewId(idMap, waifu.id) ?? waifu.id];\n const guildIds = [...(waifuGuilds.get(waifu.id) ?? new Set<string>())];\n const guilds: Record<string, { relationshipsByParticipant: Record<string, LegacyRelationshipEntry>; memories: LegacyMemoryNote[] }> = {};\n\n if (legacyState) {\n if (guildIds.length === 0) {\n addWaifuWarning(warnings, waifu.id, {\n code: \"stage_manager_guild_missing\",\n field: \"stageManager.guilds\",\n message: \"Legacy stage-manager data could not be assigned because this waifu is not active in any migrated guild.\",\n createdAt: timestamp\n });\n }\n if (guildIds.length > 1) {\n addWaifuWarning(warnings, waifu.id, {\n code: \"stage_manager_state_duplicated\",\n field: \"stageManager.guilds\",\n message: `Legacy stage-manager state was duplicated into ${guildIds.length} guild sections during import.`,\n createdAt: timestamp\n });\n }\n }\n\n for (const guildId of guildIds) {\n guilds[guildId] = {\n relationshipsByParticipant: Object.fromEntries(\n Object.entries(legacyState?.relationshipsByParticipant ?? {}).map(([participantKey, relationship]) => {\n const targetWaifuId = relationship.targetWaifuId\n ? (idMap[relationship.targetWaifuId] ?? relationship.targetWaifuId)\n : null;\n return [\n remapParticipantKey(participantKey, idMap),\n {\n ...relationship,\n targetWaifuId,\n targetName:\n relationship.targetKind === \"waifu\" && targetWaifuId\n ? migratedWaifus.find((candidate) => candidate.id === targetWaifuId)?.name ?? relationship.targetName\n : relationship.targetName\n }\n ];\n })\n ),\n memories: [...(legacyState?.memories ?? [])]\n };\n }\n\n return [\n waifu.id,\n {\n schemaVersion: 1,\n waifuId: waifu.id,\n guilds\n }\n ] as const;\n })\n );\n\n const migratedCheckpoints = collapseLegacyCheckpoints(\n legacyStageManagerStateFile.channels,\n migratedChannels,\n warnings,\n timestamp\n );\n\n await Promise.all([\n atomicWriteFile(\n paths.runtimeProvidersFile,\n `${stringify({\n providers: migratedProviders.map((provider) => ({\n id: provider.id,\n origin: provider.origin,\n name: provider.name,\n type: provider.type,\n auth_mode: provider.authMode,\n enabled: provider.enabled,\n base_url: provider.baseUrl,\n models: provider.models\n }))\n })}\\n`\n ),\n atomicWriteFile(\n paths.runtimeKeysFile,\n `${stringify({\n provider_keys: migratedProviderKeys.map((entry) => ({\n id: entry.id,\n api_key: entry.apiKey\n }))\n })}\\n`\n ),\n atomicWriteFile(\n paths.runtimeChannelsFile,\n `${stringify({\n channels: migratedChannels.map((channel) => ({\n guild_id: channel.guildId,\n channel_id: channel.channelId,\n channel_name: channel.channelName,\n enabled: channel.enabled,\n active_waifu_ids: channel.activeWaifuIds,\n context_anchor_message_id: channel.contextAnchorMessageId,\n context_message_count: channel.contextMessageCount,\n idle_chatter_enabled: channel.idleChatterEnabled,\n idle_timer_min_seconds: channel.idleTimerMinSeconds,\n idle_timer_max_seconds: channel.idleTimerMaxSeconds\n }))\n })}\\n`\n ),\n atomicWriteFile(\n paths.runtimeOrchestratorFile,\n `${stringify({\n orchestrator: {\n provider_id: asRecord(legacyOrchestratorFile).orchestrator?.providerId ?? \"configure-me\",\n model: asRecord(legacyOrchestratorFile).orchestrator?.model ?? \"configure-me\",\n temperature: asRecord(legacyOrchestratorFile).orchestrator?.temperature ?? 0.7,\n max_tokens: asRecord(legacyOrchestratorFile).orchestrator?.maxTokens ?? 500\n }\n })}\\n`\n ),\n atomicWriteFile(\n paths.runtimeStageManagerFile,\n `${stringify({\n stage_manager: {\n enabled: asRecord(legacyStageManagerFile).stageManager?.enabled ?? true,\n provider_id: asRecord(legacyStageManagerFile).stageManager?.providerId ?? \"\",\n model: asRecord(legacyStageManagerFile).stageManager?.model ?? \"\",\n temperature: asRecord(legacyStageManagerFile).stageManager?.temperature ?? 0.4,\n max_tokens: asRecord(legacyStageManagerFile).stageManager?.maxTokens ?? 500,\n quiet_period_seconds: asRecord(legacyStageManagerFile).stageManager?.quietPeriodSeconds ?? 300,\n history_limit: asRecord(legacyStageManagerFile).stageManager?.historyLimit ?? 60,\n max_relationships_per_waifu: asRecord(legacyStageManagerFile).stageManager?.maxRelationshipsPerWaifu ?? 20,\n max_memories_per_waifu: asRecord(legacyStageManagerFile).stageManager?.maxMemoriesPerWaifu ?? 8\n }\n })}\\n`\n ),\n atomicWriteFile(\n paths.stageManagerCheckpointsFile,\n `${JSON.stringify({ guilds: migratedCheckpoints }, null, 2)}\\n`\n ),\n atomicWriteFile(\n paths.migrationWarningsFile,\n `${JSON.stringify(warnings, null, 2)}\\n`\n ),\n atomicWriteFile(\n paths.migrationStateFile,\n `${JSON.stringify(\n {\n schemaVersion: 1,\n status: \"import_completed\",\n createdAt: timestamp,\n completedAt: timestamp\n },\n null,\n 2\n )}\\n`\n )\n ]);\n\n written.push(\n paths.runtimeProvidersFile,\n paths.runtimeKeysFile,\n paths.runtimeChannelsFile,\n paths.runtimeOrchestratorFile,\n paths.runtimeStageManagerFile,\n paths.stageManagerCheckpointsFile,\n paths.migrationWarningsFile,\n paths.migrationStateFile\n );\n\n for (const waifu of migratedWaifus) {\n const waifuPath = path.join(paths.runtimeWaifusRoot, `${waifu.id}.json`);\n const stageManagerPath = path.join(paths.runtimeStageManagerDataRoot, `${waifu.id}.json`);\n await atomicWriteFile(waifuPath, `${JSON.stringify(waifu, null, 2)}\\n`);\n await atomicWriteFile(\n stageManagerPath,\n `${JSON.stringify(migratedStageManagerDocuments[waifu.id], null, 2)}\\n`\n );\n written.push(waifuPath, stageManagerPath);\n }\n\n return {\n written: [...new Set(written)],\n idMap,\n warningCount:\n warnings.globalWarnings.length +\n Object.values(warnings.waifuWarnings).reduce((count, entries) => count + entries.length, 0)\n };\n}\n\nfunction buildWaifuIdMap(waifus: LegacyWaifu[]): Record<string, string> {\n const used = new Set<string>();\n const idMap: Record<string, string> = {};\n\n for (const waifu of waifus) {\n const baseId = sanitizeWaifuId(waifu.id);\n let nextId = baseId;\n let suffix = 2;\n while (used.has(nextId)) {\n nextId = `${baseId}_${suffix}`;\n suffix += 1;\n }\n used.add(nextId);\n idMap[waifu.id] = nextId;\n }\n\n return idMap;\n}\n\nfunction sanitizeWaifuId(value: string): string {\n const sanitized = value\n .replace(/[^A-Za-z0-9_-]+/g, \"_\")\n .replace(/_+/g, \"_\")\n .replace(/^_+|_+$/g, \"\");\n return sanitized || \"Waifu_1\";\n}\n\nfunction buildWaifuGuilds(\n channels: Array<{ guildId: string; activeWaifuIds: string[] }>\n): Map<string, Set<string>> {\n const result = new Map<string, Set<string>>();\n for (const channel of channels) {\n for (const waifuId of channel.activeWaifuIds) {\n const guilds = result.get(waifuId) ?? new Set<string>();\n guilds.add(channel.guildId);\n result.set(waifuId, guilds);\n }\n }\n return result;\n}\n\nfunction collapseLegacyCheckpoints(\n checkpoints: LegacyStageManagerState[\"channels\"],\n channels: Array<{ guildId: string; channelId: string }>,\n warnings: MigrationWarningsFile,\n timestamp: string\n) {\n const guildByChannelId = new Map(channels.map((channel) => [channel.channelId, channel.guildId] as const));\n const grouped = new Map<\n string,\n Array<{ channelId: string; lastProcessedMessageId: string | null; lastRunAt: string | null }>\n >();\n\n for (const [channelId, checkpoint] of Object.entries(checkpoints)) {\n const guildId = guildByChannelId.get(channelId);\n if (!guildId) {\n warnings.globalWarnings.push({\n code: \"legacy_checkpoint_orphaned\",\n field: \"stageManager.checkpoints\",\n message: `Legacy checkpoint for channel \"${channelId}\" could not be mapped to a migrated guild.`,\n legacyValue: channelId,\n createdAt: timestamp\n });\n continue;\n }\n const entries = grouped.get(guildId) ?? [];\n entries.push({ channelId, ...checkpoint });\n grouped.set(guildId, entries);\n }\n\n return Object.fromEntries(\n [...grouped.entries()].map(([guildId, entries]) => {\n const withMessageId = entries.filter((entry) => entry.lastProcessedMessageId);\n const highestMessage = withMessageId.sort((left, right) =>\n compareMessageIds(left.lastProcessedMessageId, right.lastProcessedMessageId)\n )[withMessageId.length - 1];\n const latestRun = entries\n .filter((entry) => entry.lastRunAt)\n .sort((left, right) => String(left.lastRunAt).localeCompare(String(right.lastRunAt)))\n .at(-1);\n\n if (entries.length > 1) {\n warnings.globalWarnings.push({\n code: \"legacy_checkpoints_collapsed\",\n field: `stageManager.checkpoints.${guildId}`,\n message: `Collapsed ${entries.length} channel checkpoints into one guild checkpoint for \"${guildId}\".`,\n createdAt: timestamp\n });\n }\n\n return [\n guildId,\n {\n lastProcessedMessageId: highestMessage?.lastProcessedMessageId ?? null,\n lastRunAt: latestRun?.lastRunAt ?? null\n }\n ];\n })\n );\n}\n\nfunction compareMessageIds(left: string | null, right: string | null): number {\n if (!left && !right) {\n return 0;\n }\n if (!left) {\n return -1;\n }\n if (!right) {\n return 1;\n }\n try {\n const leftValue = BigInt(left);\n const rightValue = BigInt(right);\n return leftValue < rightValue ? -1 : leftValue > rightValue ? 1 : 0;\n } catch {\n return left.localeCompare(right);\n }\n}\n\nasync function migrateWaifuAssets(\n paths: ReturnType<typeof getRuntimeLayoutPaths>,\n waifu: LegacyWaifu,\n waifuId: string,\n warnings: MigrationWarningsFile,\n timestamp: string\n): Promise<{ avatarPath: string | null; bannerPath: string | null }> {\n return {\n avatarPath: await migrateAssetField(paths, waifu, waifuId, \"avatarPath\", \"avatar\", warnings, timestamp),\n bannerPath: await migrateAssetField(paths, waifu, waifuId, \"bannerPath\", \"banner\", warnings, timestamp)\n };\n}\n\nasync function migrateAssetField(\n paths: ReturnType<typeof getRuntimeLayoutPaths>,\n waifu: LegacyWaifu,\n waifuId: string,\n key: \"avatarPath\" | \"bannerPath\",\n stem: \"avatar\" | \"banner\",\n warnings: MigrationWarningsFile,\n timestamp: string\n): Promise<string | null> {\n const value = waifu[key];\n if (!value || !value.trim()) {\n return null;\n }\n\n const sourcePath = await resolveLegacyAssetPath(paths, value);\n if (!sourcePath) {\n addWaifuWarning(warnings, waifuId, {\n code: \"legacy_asset_unresolved\",\n field: key,\n message: `Legacy ${stem} asset could not be resolved during import.`,\n legacyValue: value,\n createdAt: timestamp\n });\n return null;\n }\n\n const extension = path.extname(sourcePath) || \".png\";\n const destinationDir = path.join(paths.runtimeAssetsWaifusRoot, waifuId);\n const destinationPath = path.join(destinationDir, `${stem}${extension}`);\n await fs.mkdir(destinationDir, { recursive: true });\n await fs.copyFile(sourcePath, destinationPath);\n return path.posix.join(\"waifus\", waifuId, `${stem}${extension}`);\n}\n\nasync function resolveLegacyAssetPath(\n paths: ReturnType<typeof getRuntimeLayoutPaths>,\n value: string\n): Promise<string | null> {\n const trimmed = value.trim();\n const candidates = [\n trimmed,\n path.join(path.dirname(paths.legacyConfigRoot), trimmed.replace(/^\\.\\//, \"\")),\n path.join(paths.legacyConfigRoot, trimmed.replace(/^\\.\\/?config\\/assets\\//, \"\").replace(/^config\\/assets\\//, \"\").replace(/^\\.\\/assets\\//, \"\").replace(/^assets\\//, \"\"))\n ];\n\n for (const candidate of candidates) {\n const resolved = path.isAbsolute(candidate) ? candidate : path.resolve(candidate);\n if (await fileExists(resolved)) {\n return resolved;\n }\n }\n\n return null;\n}\n\nfunction remapParticipantKey(value: string, idMap: Record<string, string>): string {\n const match = value.match(/^waifu:(.+)$/);\n if (!match) {\n return value;\n }\n return `waifu:${idMap[match[1]] ?? match[1]}`;\n}\n\nfunction findLegacyIdForNewId(idMap: Record<string, string>, nextId: string): string | null {\n return Object.entries(idMap).find(([, mapped]) => mapped === nextId)?.[0] ?? null;\n}\n\nfunction deriveAuthMode(providerId: string): \"required\" | \"none\" {\n return providerId === \"ollama\" || providerId === \"lmstudio\" ? \"none\" : \"required\";\n}\n\nfunction addWaifuWarning(\n warnings: MigrationWarningsFile,\n waifuId: string,\n warning: MigrationWarning\n): void {\n warnings.waifuWarnings[waifuId] = warnings.waifuWarnings[waifuId] ?? [];\n warnings.waifuWarnings[waifuId].push(warning);\n}\n\nfunction asRecord(value: unknown): Record<string, any> {\n return value && typeof value === \"object\" ? (value as Record<string, any>) : {};\n}\n\nasync function readJson<T>(filePath: string, fallback: T): Promise<T> {\n try {\n return JSON.parse(await fs.readFile(filePath, \"utf8\")) as T;\n } catch (error) {\n const code = (error as NodeJS.ErrnoException | undefined)?.code;\n if (code === \"ENOENT\") {\n return fallback;\n }\n throw error;\n }\n}\n\nasync function atomicWriteFile(filePath: string, contents: string): Promise<void> {\n await fs.mkdir(path.dirname(filePath), { recursive: true });\n const tempPath = `${filePath}.tmp`;\n await fs.writeFile(tempPath, contents, \"utf8\");\n await fs.rename(tempPath, filePath);\n}\n\nasync function fileExists(filePath: string): Promise<boolean> {\n try {\n await fs.access(filePath);\n return true;\n } catch {\n return false;\n }\n}\n","import { createRequire } from \"node:module\";\nimport path from \"node:path\";\nimport { resolveBundledPnpmBin } from \"./pnpm-bin.js\";\nimport { getServiceEnv } from \"./service-env.js\";\n\ntype PM2Runtime = typeof import(\"pm2\");\ntype StartOptions = import(\"pm2\").StartOptions;\ntype ProcessDescription = import(\"pm2\").ProcessDescription;\nconst require = createRequire(import.meta.url);\n\nexport const backendProcessName = \"waifus-backend\";\nexport const dashboardProcessName = \"waifus-dashboard\";\n\n// Resolve the pnpm bundled as a dependency of this CLI so pm2 doesn't have to\n// find pnpm on PATH. We avoid requiring an unexported subpath so this keeps\n// working on newer Node releases.\nconst PNPM_BIN = resolveBundledPnpmBin();\n\nexport interface ManagedProcessStatus {\n name: string;\n status: string;\n cwd: string | null;\n pid: number | null;\n restartCount: number;\n uptimeMs: number | null;\n}\n\nexport async function startServices(projectRoot: string): Promise<void> {\n await withPm2(async () => {\n await ensureStarted({\n name: backendProcessName,\n cwd: projectRoot,\n script: PNPM_BIN,\n args: [\"--filter\", \"backend\", \"start\"],\n env: getServiceEnv(\"backend\")\n });\n\n await ensureStarted({\n name: dashboardProcessName,\n cwd: projectRoot,\n script: PNPM_BIN,\n args: [\"--filter\", \"dashboard\", \"start\"],\n env: getServiceEnv(\"dashboard\")\n });\n });\n}\n\nexport async function stopServices(): Promise<void> {\n await withPm2(async () => {\n await stopIfPresent(backendProcessName);\n await stopIfPresent(dashboardProcessName);\n });\n}\n\nexport async function restartServices(projectRoot: string): Promise<void> {\n await withPm2(async () => {\n await restartOrStart({\n name: backendProcessName,\n cwd: projectRoot,\n script: PNPM_BIN,\n args: [\"--filter\", \"backend\", \"start\"],\n env: getServiceEnv(\"backend\")\n });\n\n await restartOrStart({\n name: dashboardProcessName,\n cwd: projectRoot,\n script: PNPM_BIN,\n args: [\"--filter\", \"dashboard\", \"start\"],\n env: getServiceEnv(\"dashboard\")\n });\n });\n}\n\nexport async function listManagedServices(): Promise<ManagedProcessStatus[]> {\n return withPm2(async () => {\n const processes = await listProcesses();\n return processes\n .filter((processDescription) =>\n [backendProcessName, dashboardProcessName].includes(processDescription.name ?? \"\")\n )\n .map((processDescription) => ({\n name: processDescription.name ?? \"unknown\",\n status: processDescription.pm2_env?.status ?? \"unknown\",\n cwd: processDescription.pm2_env?.pm_cwd ?? null,\n pid: typeof processDescription.pid === \"number\" ? processDescription.pid : null,\n restartCount: processDescription.pm2_env?.restart_time ?? 0,\n uptimeMs:\n typeof processDescription.pm2_env?.pm_uptime === \"number\"\n ? Date.now() - processDescription.pm2_env.pm_uptime\n : null\n }));\n });\n}\n\nexport function getPm2LogCommand(service: \"backend\" | \"dashboard\" | null, lines: number): {\n command: string;\n args: string[];\n} {\n const pm2Bin = resolvePm2Bin();\n const args = [\"logs\"];\n\n if (service === \"backend\") {\n args.push(backendProcessName);\n } else if (service === \"dashboard\") {\n args.push(dashboardProcessName);\n } else {\n args.push(backendProcessName, dashboardProcessName);\n }\n\n args.push(\"--lines\", String(lines));\n\n return {\n command: process.execPath,\n args: [pm2Bin, ...args]\n };\n}\n\nasync function ensureStarted(options: StartOptions): Promise<void> {\n if (await hasManagedProcess(options.name ?? \"\")) {\n await restartProcess(options.name ?? \"\");\n return;\n }\n await startProcess(options);\n}\n\nasync function restartOrStart(options: StartOptions): Promise<void> {\n if (await hasManagedProcess(options.name ?? \"\")) {\n await restartProcess(options.name ?? \"\");\n return;\n }\n await startProcess(options);\n}\n\nasync function stopIfPresent(processName: string): Promise<void> {\n if (!(await hasManagedProcess(processName))) {\n return;\n }\n await stopProcess(processName);\n}\n\nasync function withPm2<T>(callback: () => Promise<T>): Promise<T> {\n const pm2 = await loadPm2();\n await connect(pm2);\n try {\n return await callback();\n } finally {\n pm2.disconnect();\n }\n}\n\nfunction connect(pm2: PM2Runtime): Promise<void> {\n return new Promise((resolve, reject) => {\n pm2.connect((error: Error | null) => {\n if (error) {\n reject(error);\n return;\n }\n resolve();\n });\n });\n}\n\nasync function startProcess(options: StartOptions): Promise<void> {\n const pm2 = await loadPm2();\n return new Promise((resolve, reject) => {\n pm2.start(options, (error: Error | null) => {\n if (error) {\n reject(error);\n return;\n }\n resolve();\n });\n });\n}\n\nasync function restartProcess(processName: string): Promise<void> {\n const pm2 = await loadPm2();\n return new Promise((resolve, reject) => {\n pm2.restart(processName, (error: Error | null) => {\n if (error) {\n reject(error);\n return;\n }\n resolve();\n });\n });\n}\n\nasync function stopProcess(processName: string): Promise<void> {\n const pm2 = await loadPm2();\n return new Promise((resolve, reject) => {\n pm2.stop(processName, (error: Error | null) => {\n if (error) {\n reject(error);\n return;\n }\n resolve();\n });\n });\n}\n\nasync function listProcesses(): Promise<ProcessDescription[]> {\n const pm2 = await loadPm2();\n return new Promise((resolve, reject) => {\n pm2.list((error: Error | null, processDescription: ProcessDescription[]) => {\n if (error) {\n reject(error);\n return;\n }\n resolve(processDescription);\n });\n });\n}\n\nasync function hasManagedProcess(processName: string): Promise<boolean> {\n const processes = await listProcesses();\n return processes.some((processDescription) => processDescription.name === processName);\n}\n\nlet pm2Promise: Promise<PM2Runtime> | null = null;\n\nasync function loadPm2(): Promise<PM2Runtime> {\n if (!pm2Promise) {\n pm2Promise = Promise.resolve(require(\"pm2\") as PM2Runtime);\n }\n\n return pm2Promise;\n}\n\nfunction resolvePm2Bin(): string {\n return require.resolve(path.join(\"pm2\", \"bin\", \"pm2\"));\n}\n","import path from \"node:path\";\nimport { createRequire } from \"node:module\";\n\nconst require = createRequire(import.meta.url);\n\nexport function resolveBundledPnpmBin(): string {\n const pnpmPackageJson = require.resolve(\"pnpm\");\n return path.join(path.dirname(pnpmPackageJson), \"bin\", \"pnpm.cjs\");\n}\n","export type ManagedService = \"backend\" | \"dashboard\";\n\nexport function getServiceEnv(service: ManagedService): Record<string, string> {\n if (service === \"backend\") {\n return {\n NODE_ENV: \"production\"\n };\n }\n\n return {\n NODE_ENV: \"production\",\n PORT: \"3000\"\n };\n}\n","import { createHash } from \"node:crypto\";\nimport { promises as fs } from \"node:fs\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport { spawn } from \"node:child_process\";\n\nexport const APP_RELEASE_ASSET_NAME = \"discord-waifus-app.tar.gz\";\nexport const APP_RELEASE_CHECKSUM_ASSET_NAME = \"discord-waifus-app.sha256\";\nconst INSTALLED_RELEASE_METADATA = \".waifus-release.json\";\n\nexport interface BootstrapReleaseOptions {\n repo?: string | null;\n release?: string | null;\n}\n\nexport interface BootstrapReleaseResult {\n projectRoot: string;\n sourceRepo: string;\n releaseTag: string;\n releaseName: string | null;\n publishedAt: string | null;\n assetName: string;\n bundleVersion: string | null;\n}\n\nexport interface UpdateReleaseOptions {\n preserveEntries?: string[];\n}\n\nexport interface InstalledReleaseMetadata {\n formatVersion?: unknown;\n bundleVersion?: unknown;\n sourceCommit?: unknown;\n generatedAt?: unknown;\n repository?: unknown;\n}\n\ninterface GitHubReleaseAsset {\n name?: string;\n browser_download_url?: string;\n}\n\ninterface GitHubReleasePayload {\n tag_name?: string;\n name?: string;\n published_at?: string;\n assets?: GitHubReleaseAsset[];\n}\n\nexport async function bootstrapReleaseBundleFromGitHub(\n targetDir: string,\n options: BootstrapReleaseOptions = {}\n): Promise<BootstrapReleaseResult> {\n const projectRoot = path.resolve(targetDir);\n await ensureTargetDirectoryIsEmpty(projectRoot);\n const snapshot = await prepareReleaseSnapshot(options);\n\n try {\n await fs.mkdir(projectRoot, { recursive: true });\n await copyDirectoryContents(snapshot.extractedRoot, projectRoot);\n return snapshot.result(projectRoot);\n } finally {\n await snapshot.cleanup();\n }\n}\n\nexport async function updateReleaseBundleFromGitHub(\n targetDir: string,\n options: BootstrapReleaseOptions = {},\n updateOptions: UpdateReleaseOptions = {}\n): Promise<BootstrapReleaseResult> {\n const projectRoot = path.resolve(targetDir);\n const stats = await fs.stat(projectRoot).catch(() => null);\n if (!stats?.isDirectory()) {\n throw new Error(`Project directory does not exist: ${projectRoot}`);\n }\n\n const snapshot = await prepareReleaseSnapshot(options);\n const preserveEntries = new Set((updateOptions.preserveEntries ?? []).map((entry) => entry.trim()).filter(Boolean));\n\n try {\n await replaceProjectContents(projectRoot, snapshot.extractedRoot, preserveEntries);\n return snapshot.result(projectRoot);\n } finally {\n await snapshot.cleanup();\n }\n}\n\nexport async function readInstalledReleaseMetadata(projectRoot: string): Promise<{\n bundleVersion: string | null;\n sourceCommit: string | null;\n generatedAt: string | null;\n repository: string | null;\n} | null> {\n try {\n const raw = JSON.parse(\n await fs.readFile(path.join(projectRoot, INSTALLED_RELEASE_METADATA), \"utf8\")\n ) as InstalledReleaseMetadata;\n\n return {\n bundleVersion: typeof raw.bundleVersion === \"string\" && raw.bundleVersion.trim()\n ? raw.bundleVersion.trim()\n : null,\n sourceCommit: typeof raw.sourceCommit === \"string\" && raw.sourceCommit.trim()\n ? raw.sourceCommit.trim()\n : null,\n generatedAt: typeof raw.generatedAt === \"string\" && raw.generatedAt.trim()\n ? raw.generatedAt.trim()\n : null,\n repository: typeof raw.repository === \"string\" && raw.repository.trim()\n ? raw.repository.trim()\n : null\n };\n } catch {\n return null;\n }\n}\n\nasync function ensureTargetDirectoryIsEmpty(targetDir: string): Promise<void> {\n try {\n const stats = await fs.stat(targetDir);\n if (!stats.isDirectory()) {\n throw new Error(`Target path exists and is not a directory: ${targetDir}`);\n }\n\n const entries = await fs.readdir(targetDir);\n if (entries.length > 0) {\n throw new Error(`Target directory is not empty: ${targetDir}`);\n }\n } catch (error) {\n const code = (error as NodeJS.ErrnoException | undefined)?.code;\n if (code === \"ENOENT\") {\n return;\n }\n throw error;\n }\n}\n\nasync function prepareReleaseSnapshot(\n options: BootstrapReleaseOptions\n): Promise<{\n extractedRoot: string;\n result: (projectRoot: string) => BootstrapReleaseResult;\n cleanup: () => Promise<void>;\n}> {\n const repositoryUrl = options.repo?.trim() || (await resolveRepositoryFromPackageMetadata());\n if (!repositoryUrl) {\n throw new Error(\n \"No GitHub repository was provided.\\nUse: waifus init <target-dir> --repo https://github.com/<owner>/<repo>\"\n );\n }\n\n const githubRepo = parseGitHubRepository(repositoryUrl);\n if (!githubRepo) {\n throw new Error(\n `Unsupported repository: ${repositoryUrl}\\nOnly GitHub repositories are supported by waifus init.`\n );\n }\n\n const releaseTag = options.release?.trim() || null;\n const release = await fetchGitHubRelease(githubRepo.owner, githubRepo.repo, releaseTag);\n const assets = Array.isArray(release.assets) ? release.assets : [];\n const bundleAsset = assets.find((asset) => asset.name === APP_RELEASE_ASSET_NAME);\n if (!bundleAsset?.browser_download_url) {\n throw new Error(\n `GitHub release ${release.tag_name ?? releaseTag ?? \"latest\"} is missing ${APP_RELEASE_ASSET_NAME}.`\n );\n }\n\n const checksumAsset = assets.find((asset) => asset.name === APP_RELEASE_CHECKSUM_ASSET_NAME);\n const tempRoot = await fs.mkdtemp(path.join(os.tmpdir(), \"waifus-release-\"));\n const archivePath = path.join(tempRoot, APP_RELEASE_ASSET_NAME);\n const extractRoot = path.join(tempRoot, \"extract\");\n\n try {\n await fs.mkdir(extractRoot, { recursive: true });\n await downloadFile(bundleAsset.browser_download_url, archivePath);\n\n if (checksumAsset?.browser_download_url) {\n const checksumText = await downloadTextFile(checksumAsset.browser_download_url);\n const expectedChecksum = parseChecksum(checksumText);\n const actualChecksum = await computeSha256(archivePath);\n if (expectedChecksum !== actualChecksum) {\n throw new Error(\n `Release asset checksum mismatch for ${APP_RELEASE_ASSET_NAME}. Expected ${expectedChecksum}, got ${actualChecksum}.`\n );\n }\n }\n\n await extractTarGz(archivePath, extractRoot);\n const extractedRoot = await findSingleExtractedRoot(extractRoot);\n const installedMetadata = await readInstalledReleaseMetadata(extractedRoot);\n const tagName =\n typeof release.tag_name === \"string\" && release.tag_name.trim()\n ? release.tag_name.trim()\n : releaseTag ?? \"latest\";\n const releaseName =\n typeof release.name === \"string\" && release.name.trim()\n ? release.name.trim()\n : null;\n const publishedAt =\n typeof release.published_at === \"string\" && release.published_at.trim()\n ? release.published_at.trim()\n : null;\n const sourceRepo = `https://github.com/${githubRepo.owner}/${githubRepo.repo}`;\n\n return {\n extractedRoot,\n result: (projectRoot: string) => ({\n projectRoot,\n sourceRepo,\n releaseTag: tagName,\n releaseName,\n publishedAt,\n assetName: APP_RELEASE_ASSET_NAME,\n bundleVersion: installedMetadata?.bundleVersion ?? null\n }),\n cleanup: async () => {\n await fs.rm(tempRoot, { recursive: true, force: true });\n }\n };\n } catch (error) {\n await fs.rm(tempRoot, { recursive: true, force: true });\n throw error;\n }\n}\n\nasync function resolveRepositoryFromPackageMetadata(): Promise<string | null> {\n try {\n const packageJsonPath = new URL(\"../package.json\", import.meta.url);\n const raw = JSON.parse(await fs.readFile(packageJsonPath, \"utf8\")) as {\n repository?: string | { url?: string };\n };\n if (typeof raw.repository === \"string\" && raw.repository.trim()) {\n return raw.repository.trim();\n }\n if (\n raw.repository &&\n typeof raw.repository === \"object\" &&\n typeof raw.repository.url === \"string\" &&\n raw.repository.url.trim()\n ) {\n return raw.repository.url.trim();\n }\n return null;\n } catch {\n return null;\n }\n}\n\nfunction parseGitHubRepository(value: string): { owner: string; repo: string } | null {\n const trimmed = value.trim();\n const normalized = trimmed\n .replace(/^git\\+/, \"\")\n .replace(/^git@github\\.com:/, \"https://github.com/\")\n .replace(/\\.git$/, \"\");\n\n const slugMatch = normalized.match(/^([A-Za-z0-9_.-]+)\\/([A-Za-z0-9_.-]+)$/);\n if (slugMatch) {\n return { owner: slugMatch[1], repo: slugMatch[2] };\n }\n\n try {\n const url = new URL(normalized);\n if (url.hostname !== \"github.com\") {\n return null;\n }\n const segments = url.pathname.replace(/^\\/+|\\/+$/g, \"\").split(\"/\");\n if (segments.length < 2 || !segments[0] || !segments[1]) {\n return null;\n }\n return {\n owner: segments[0],\n repo: segments[1]\n };\n } catch {\n return null;\n }\n}\n\nasync function fetchGitHubRelease(owner: string, repo: string, releaseTag: string | null): Promise<GitHubReleasePayload> {\n const releasePath = releaseTag\n ? `releases/tags/${encodeURIComponent(releaseTag)}`\n : \"releases/latest\";\n const response = await fetch(`https://api.github.com/repos/${owner}/${repo}/${releasePath}`, {\n headers: {\n Accept: \"application/vnd.github+json\",\n \"User-Agent\": \"@starlight-ai/discord-waifus\"\n },\n redirect: \"follow\"\n });\n\n if (!response.ok) {\n if (response.status === 404 && releaseTag) {\n throw new Error(`GitHub release tag not found: ${releaseTag}`);\n }\n throw new Error(`Failed to resolve GitHub release metadata: HTTP ${response.status}`);\n }\n\n return await response.json() as GitHubReleasePayload;\n}\n\nasync function downloadFile(url: string, destinationPath: string): Promise<void> {\n const response = await fetch(url, {\n headers: {\n \"User-Agent\": \"@starlight-ai/discord-waifus\"\n },\n redirect: \"follow\"\n });\n\n if (!response.ok) {\n throw new Error(`Failed to download release asset: HTTP ${response.status}`);\n }\n\n const buffer = Buffer.from(await response.arrayBuffer());\n await fs.writeFile(destinationPath, buffer);\n}\n\nasync function downloadTextFile(url: string): Promise<string> {\n const response = await fetch(url, {\n headers: {\n \"User-Agent\": \"@starlight-ai/discord-waifus\"\n },\n redirect: \"follow\"\n });\n\n if (!response.ok) {\n throw new Error(`Failed to download release checksum asset: HTTP ${response.status}`);\n }\n\n return await response.text();\n}\n\nfunction parseChecksum(value: string): string {\n const match = value.trim().match(/^([a-f0-9]{64})\\b/i);\n if (!match) {\n throw new Error(`Invalid checksum format in ${APP_RELEASE_CHECKSUM_ASSET_NAME}.`);\n }\n return match[1].toLowerCase();\n}\n\nasync function computeSha256(filePath: string): Promise<string> {\n const buffer = await fs.readFile(filePath);\n return createHash(\"sha256\").update(buffer).digest(\"hex\");\n}\n\nasync function extractTarGz(archivePath: string, extractRoot: string): Promise<void> {\n await spawnQuiet(\"tar\", [\"-xzf\", archivePath, \"-C\", extractRoot]);\n}\n\nasync function findSingleExtractedRoot(extractRoot: string): Promise<string> {\n const entries = await fs.readdir(extractRoot, { withFileTypes: true });\n const directories = entries.filter((entry) => entry.isDirectory());\n if (directories.length !== 1) {\n throw new Error(\"Release asset extraction did not produce a single root directory.\");\n }\n return path.join(extractRoot, directories[0].name);\n}\n\nasync function copyDirectoryContents(sourceDir: string, targetDir: string): Promise<void> {\n const entries = await fs.readdir(sourceDir);\n await Promise.all(\n entries.map((entry) =>\n fs.cp(path.join(sourceDir, entry), path.join(targetDir, entry), {\n recursive: true\n })\n )\n );\n}\n\nasync function replaceProjectContents(\n targetDir: string,\n sourceDir: string,\n preserveEntries: Set<string>\n): Promise<void> {\n const entries = await fs.readdir(targetDir, { withFileTypes: true });\n\n for (const entry of entries) {\n if (preserveEntries.has(entry.name)) {\n continue;\n }\n await fs.rm(path.join(targetDir, entry.name), { recursive: true, force: true });\n }\n\n await copyDirectoryContents(sourceDir, targetDir);\n}\n\nasync function spawnQuiet(command: string, args: string[]): Promise<void> {\n await new Promise<void>((resolve, reject) => {\n const child = spawn(command, args, {\n stdio: \"ignore\"\n });\n\n child.once(\"error\", reject);\n child.once(\"exit\", (code, signal) => {\n if (signal) {\n reject(new Error(`${command} exited due to signal ${signal}`));\n return;\n }\n if (code && code !== 0) {\n reject(new Error(`${command} ${args.join(\" \")} failed with exit code ${code}`));\n return;\n }\n resolve();\n });\n });\n}\n","import { spawnPassthrough } from \"./command-utils.js\";\n\nexport interface CliSelfUpdateOptions {\n packageName: string;\n currentVersion: string;\n cwd: string;\n info: (message: string) => void;\n success: (message: string) => void;\n warn: (message: string) => void;\n skip?: boolean;\n}\n\nexport async function maybeSelfUpdateCli(options: CliSelfUpdateOptions): Promise<boolean> {\n if (options.skip) {\n return false;\n }\n\n const latestVersion = await fetchLatestPackageVersion(options.packageName);\n if (!latestVersion) {\n options.warn(\"Could not check npm for a newer waifus CLI version. Continuing with app update.\");\n return false;\n }\n\n if (!isNewerVersion(latestVersion, options.currentVersion)) {\n return false;\n }\n\n options.info(`CLI update available: ${options.currentVersion} -> ${latestVersion}`);\n options.info(\"Updating the global waifus CLI with npm...\");\n\n try {\n await spawnPassthrough(\n \"npm\",\n [\"install\", \"-g\", `${options.packageName}@${latestVersion}`],\n options.cwd\n );\n options.success(`CLI updated to ${latestVersion}.`);\n return true;\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n options.warn(`Failed to auto-update the global CLI: ${message}`);\n options.warn(`You can update it manually with: npm install -g ${options.packageName}`);\n return false;\n }\n}\n\nasync function fetchLatestPackageVersion(packageName: string): Promise<string | null> {\n try {\n const response = await fetch(`https://registry.npmjs.org/${encodeURIComponent(packageName)}/latest`, {\n headers: {\n Accept: \"application/json\",\n \"User-Agent\": packageName\n }\n });\n\n if (!response.ok) {\n return null;\n }\n\n const payload = await response.json() as { version?: unknown };\n return typeof payload.version === \"string\" && payload.version.trim()\n ? payload.version.trim()\n : null;\n } catch {\n return null;\n }\n}\n\nfunction isNewerVersion(candidate: string, current: string): boolean {\n const parsedCandidate = parseVersion(candidate);\n const parsedCurrent = parseVersion(current);\n if (!parsedCandidate || !parsedCurrent) {\n return false;\n }\n\n for (let index = 0; index < parsedCandidate.length; index += 1) {\n if (parsedCandidate[index] > parsedCurrent[index]) {\n return true;\n }\n if (parsedCandidate[index] < parsedCurrent[index]) {\n return false;\n }\n }\n\n return false;\n}\n\nfunction parseVersion(version: string): [number, number, number] | null {\n const match = version.trim().match(/^(\\d+)\\.(\\d+)\\.(\\d+)(?:[-+].*)?$/);\n if (!match) {\n return null;\n }\n\n const major = Number.parseInt(match[1], 10);\n const minor = Number.parseInt(match[2], 10);\n const patch = Number.parseInt(match[3], 10);\n if (![major, minor, patch].every(Number.isFinite)) {\n return null;\n }\n\n return [major, minor, patch];\n}\n"],"mappings":"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","names":["path","process","fs","createRequire","pc","fs","path","path","fs","fs","path","process","fs","path","process","path","fileExists","fs","process","spawn","fs","path","stringify","stringify","path","fs","fileExists","createRequire","path","path","require","require","createRequire","path","fs","os","path","spawn","require","createRequire","PNPM_BIN","process","pc","fileExists","path","fs"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@starlight-ai/discord-waifus",
3
- "version": "0.2.1",
3
+ "version": "0.3.1",
4
4
  "private": false,
5
5
  "description": "Global CLI for running the Discord Waifus local orchestration stack",
6
6
  "license": "MIT",