dsh-claude-slides 2.7.1 → 2.7.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,14 +1,14 @@
1
1
  #!/usr/bin/env node
2
2
  // claude-slides: local editor server (prebuilt; do not edit).
3
3
 
4
- import fs11 from "node:fs";
5
- import path11 from "node:path";
4
+ import fs12 from "node:fs";
5
+ import path12 from "node:path";
6
6
 
7
7
  import { createHash as createHash3, randomBytes as randomBytes2, randomUUID } from "node:crypto";
8
- import fs10 from "node:fs";
8
+ import fs11 from "node:fs";
9
9
  import fsp4 from "node:fs/promises";
10
10
  import http from "node:http";
11
- import path10 from "node:path";
11
+ import path11 from "node:path";
12
12
  import { fileURLToPath, pathToFileURL } from "node:url";
13
13
 
14
14
  import { spawn } from "node:child_process";
@@ -1496,9 +1496,155 @@ ${sections || '<p class="muted">This copy has no tokens, components or guide.</p
1496
1496
  `;
1497
1497
  }
1498
1498
 
1499
- import { createHash, randomBytes } from "node:crypto";
1500
1499
  import fs5 from "node:fs";
1501
1500
  import path5 from "node:path";
1501
+ var FOLDER2 = /^[a-z0-9][a-z0-9_-]{0,63}$/;
1502
+ var MAX_FILES = 2e3;
1503
+ var MAX_FILE_BYTES2 = 64 * 1024 * 1024;
1504
+ var DESIGN_SYSTEM_FILE = "design-system.json";
1505
+ function readRecords(project, indexFile) {
1506
+ let index;
1507
+ try {
1508
+ index = JSON.parse(fs5.readFileSync(path5.join(project, indexFile), "utf8"));
1509
+ } catch {
1510
+ return [];
1511
+ }
1512
+ const list = index?.designSystems;
1513
+ const records = Array.isArray(list) ? list : list && typeof list === "object" ? Object.values(list) : [];
1514
+ const out = [];
1515
+ for (const raw of records) {
1516
+ const r = raw;
1517
+ if (typeof r?.namespace !== "string" || !FOLDER2.test(r.namespace)) continue;
1518
+ out.push({
1519
+ namespace: r.namespace,
1520
+ title: typeof r.title === "string" ? r.title : r.namespace,
1521
+ artifact: typeof r.artifact === "string" ? r.artifact : ""
1522
+ });
1523
+ }
1524
+ return out;
1525
+ }
1526
+ function plain(p, want) {
1527
+ const stat = fs5.lstatSync(p, { throwIfNoEntry: false });
1528
+ return Boolean(stat && !stat.isSymbolicLink() && (want === "file" ? stat.isFile() : stat.isDirectory()));
1529
+ }
1530
+ function walk(dir, prefix = "", out = []) {
1531
+ for (const entry of fs5.readdirSync(path5.join(dir, prefix), { withFileTypes: true })) {
1532
+ if (out.length >= MAX_FILES) break;
1533
+ const rel = prefix ? `${prefix}/${entry.name}` : entry.name;
1534
+ if (entry.isDirectory()) walk(dir, rel, out);
1535
+ else if (entry.isFile()) out.push(rel);
1536
+ }
1537
+ return out;
1538
+ }
1539
+ var projectOf = (candidate) => path5.basename(candidate) === "project" ? candidate : path5.join(candidate, "project");
1540
+ function sourceProject(artifact, root, from) {
1541
+ const given = from ?? artifact;
1542
+ if (!given) return { reason: "the record names no source folder", kind: "none" };
1543
+ if (!from && /^[a-z][a-z0-9+.-]*:\/\//i.test(given)) return { reason: `its source is ${given}, which is not a folder on this machine`, kind: "remote" };
1544
+ const candidates = path5.isAbsolute(given) ? [given] : [path5.resolve(given), path5.resolve(root, given), path5.resolve(root, "..", given)];
1545
+ for (const candidate of candidates) {
1546
+ const project = projectOf(candidate);
1547
+ if (plain(project, "dir")) return { project };
1548
+ }
1549
+ if (!from && !path5.isAbsolute(given)) {
1550
+ let dir = path5.resolve(root, "..");
1551
+ for (let up = path5.dirname(dir); up !== dir; up = path5.dirname(dir)) {
1552
+ dir = up;
1553
+ const project = projectOf(path5.resolve(dir, given));
1554
+ if (plain(path5.join(project, DESIGN_SYSTEM_FILE), "file")) return { project };
1555
+ }
1556
+ }
1557
+ return { reason: `its source folder ${given} was not found${from ? "" : ` (tried from ${process.cwd()} and the folders above the artifact); pass --from <folder>`}`, kind: "not-found" };
1558
+ }
1559
+ function compareSystem(project, root, record, from) {
1560
+ const diff = { namespace: record.namespace, title: record.title, changed: [], removed: [] };
1561
+ const found = sourceProject(record.artifact, root, from);
1562
+ if (!found.project) return { ...diff, skipped: found.reason, skippedKind: found.kind };
1563
+ diff.source = path5.dirname(found.project);
1564
+ const copy = path5.join(project, "ds", record.namespace);
1565
+ if (!plain(copy, "dir")) return { ...diff, missing: true };
1566
+ for (const rel of walk(copy)) {
1567
+ const mine = path5.join(copy, rel);
1568
+ const theirs = path5.join(found.project, rel);
1569
+ if (!plain(mine, "file")) continue;
1570
+ if (!plain(theirs, "file")) {
1571
+ diff.removed.push(rel);
1572
+ continue;
1573
+ }
1574
+ const a = fs5.statSync(mine);
1575
+ const b = fs5.statSync(theirs);
1576
+ if (a.size > MAX_FILE_BYTES2 || b.size > MAX_FILE_BYTES2) continue;
1577
+ if (a.size !== b.size || !fs5.readFileSync(mine).equals(fs5.readFileSync(theirs))) diff.changed.push(rel);
1578
+ }
1579
+ return diff;
1580
+ }
1581
+ function systemStatus(project, root, indexFile, namespace) {
1582
+ const record = readRecords(project, indexFile).find((r) => r.namespace === namespace);
1583
+ if (!record) return null;
1584
+ const diff = compareSystem(project, root, record);
1585
+ if (diff.skippedKind) return { state: "unknown", changed: 0, removed: 0, reason: diff.skippedKind };
1586
+ if (diff.missing) return { state: "unknown", changed: 0, removed: 0, reason: "missing" };
1587
+ return { state: diff.changed.length > 0 ? "behind" : "current", changed: diff.changed.length, removed: diff.removed.length };
1588
+ }
1589
+ var DS_SYNC = /^__ds-sync\/([a-z0-9][a-z0-9_-]{0,63})$/;
1590
+ function pick(records, namespace) {
1591
+ if (namespace === void 0) return records;
1592
+ const one = records.filter((r) => r.namespace === namespace);
1593
+ if (one.length === 0) {
1594
+ const names = records.map((r) => r.namespace);
1595
+ throw new Error(`No designSystems record has namespace ${JSON.stringify(namespace)}${names.length ? ` (it has: ${names.join(", ")})` : ""}.`);
1596
+ }
1597
+ return one;
1598
+ }
1599
+ function compareSystems(project, root, indexFile, namespace, from) {
1600
+ return pick(readRecords(project, indexFile), namespace).map((r) => compareSystem(project, root, r, from));
1601
+ }
1602
+ function stamp(project, indexFile, namespaces, now) {
1603
+ const file = path5.join(project, indexFile);
1604
+ const text = fs5.readFileSync(file, "utf8");
1605
+ const index = JSON.parse(text);
1606
+ const list = index.designSystems;
1607
+ const records = Array.isArray(list) ? list : list && typeof list === "object" ? Object.values(list) : [];
1608
+ for (const r of records) {
1609
+ const record = r;
1610
+ if (record && typeof record.namespace === "string" && namespaces.has(record.namespace)) record.copiedAt = now;
1611
+ }
1612
+ const indent = /^\{\n/.test(text) ? /\n( +|\t)"/.exec(text)?.[1] ?? 2 : void 0;
1613
+ const out = JSON.stringify(index, null, indent);
1614
+ const tmp = `${file}.${process.pid}.tmp`;
1615
+ fs5.writeFileSync(tmp, text.endsWith("\n") ? `${out}
1616
+ ` : out);
1617
+ fs5.renameSync(tmp, file);
1618
+ }
1619
+ function syncSystems(project, root, indexFile, opts) {
1620
+ const diffs = compareSystems(project, root, indexFile, opts.namespace, opts.from);
1621
+ const results = [];
1622
+ const synced = /* @__PURE__ */ new Set();
1623
+ const now = (/* @__PURE__ */ new Date()).toISOString().replace(/\.\d{3}Z$/, "Z");
1624
+ for (const diff of diffs) {
1625
+ const result = { ...diff, copied: [] };
1626
+ if (!opts.check && diff.source && !diff.missing) {
1627
+ for (const rel of diff.changed) {
1628
+ const target = path5.join(project, "ds", diff.namespace, rel);
1629
+ const tmp = `${target}.${process.pid}.tmp`;
1630
+ fs5.copyFileSync(path5.join(diff.source, "project", rel), tmp);
1631
+ fs5.renameSync(tmp, target);
1632
+ result.copied.push(rel);
1633
+ }
1634
+ if (diff.changed.length > 0) synced.add(diff.namespace);
1635
+ }
1636
+ results.push(result);
1637
+ }
1638
+ if (synced.size > 0) {
1639
+ stamp(project, indexFile, synced, now);
1640
+ for (const r of results) if (synced.has(r.namespace)) r.copiedAt = now;
1641
+ }
1642
+ return results;
1643
+ }
1644
+
1645
+ import { createHash, randomBytes } from "node:crypto";
1646
+ import fs6 from "node:fs";
1647
+ import path6 from "node:path";
1502
1648
  var HISTORY_DIR = "history";
1503
1649
  var INDEX = "index.json";
1504
1650
  var OBJECTS = "objects";
@@ -1513,13 +1659,13 @@ var sha256 = (bytes) => createHash("sha256").update(bytes).digest("hex");
1513
1659
  var SHA = /^[0-9a-f]{64}$/;
1514
1660
  var isRecord2 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
1515
1661
  function writeAtomic2(file, data) {
1516
- fs5.mkdirSync(path5.dirname(file), { recursive: true });
1517
- const tmp = path5.join(path5.dirname(file), `.${path5.basename(file)}.${process.pid}.${randomBytes(4).toString("hex")}.tmp`);
1662
+ fs6.mkdirSync(path6.dirname(file), { recursive: true });
1663
+ const tmp = path6.join(path6.dirname(file), `.${path6.basename(file)}.${process.pid}.${randomBytes(4).toString("hex")}.tmp`);
1518
1664
  try {
1519
- fs5.writeFileSync(tmp, data);
1520
- fs5.renameSync(tmp, file);
1665
+ fs6.writeFileSync(tmp, data);
1666
+ fs6.renameSync(tmp, file);
1521
1667
  } catch (error) {
1522
- fs5.rmSync(tmp, { force: true });
1668
+ fs6.rmSync(tmp, { force: true });
1523
1669
  throw error;
1524
1670
  }
1525
1671
  }
@@ -1600,10 +1746,10 @@ var History = class {
1600
1746
  /** path → sha: what the files hold after the newest version. */
1601
1747
  headState;
1602
1748
  constructor(root) {
1603
- this.dir = path5.join(root, HISTORY_DIR);
1749
+ this.dir = path6.join(root, HISTORY_DIR);
1604
1750
  let raw = null;
1605
1751
  try {
1606
- raw = JSON.parse(fs5.readFileSync(path5.join(this.dir, INDEX), "utf8"));
1752
+ raw = JSON.parse(fs6.readFileSync(path6.join(this.dir, INDEX), "utf8"));
1607
1753
  } catch {
1608
1754
  }
1609
1755
  this.index = parseIndex(raw);
@@ -1647,7 +1793,7 @@ var History = class {
1647
1793
  read(sha) {
1648
1794
  if (!SHA.test(sha)) return null;
1649
1795
  try {
1650
- return fs5.readFileSync(path5.join(this.dir, OBJECTS, sha));
1796
+ return fs6.readFileSync(path6.join(this.dir, OBJECTS, sha));
1651
1797
  } catch {
1652
1798
  return null;
1653
1799
  }
@@ -1661,7 +1807,7 @@ var History = class {
1661
1807
  size(sha) {
1662
1808
  if (!SHA.test(sha)) return null;
1663
1809
  try {
1664
- return fs5.statSync(path5.join(this.dir, OBJECTS, sha)).size;
1810
+ return fs6.statSync(path6.join(this.dir, OBJECTS, sha)).size;
1665
1811
  } catch {
1666
1812
  return null;
1667
1813
  }
@@ -1795,8 +1941,8 @@ var History = class {
1795
1941
  return out;
1796
1942
  }
1797
1943
  putObject(sha, bytes) {
1798
- const file = path5.join(this.dir, OBJECTS, sha);
1799
- if (fs5.existsSync(file)) return;
1944
+ const file = path6.join(this.dir, OBJECTS, sha);
1945
+ if (fs6.existsSync(file)) return;
1800
1946
  writeAtomic2(file, bytes);
1801
1947
  }
1802
1948
  /** Past MAX_VERSIONS the oldest fold into the base; old notices go; contents no one holds are removed. */
@@ -1833,14 +1979,14 @@ var History = class {
1833
1979
  }
1834
1980
  let names;
1835
1981
  try {
1836
- names = fs5.readdirSync(path5.join(this.dir, OBJECTS));
1982
+ names = fs6.readdirSync(path6.join(this.dir, OBJECTS));
1837
1983
  } catch {
1838
1984
  return;
1839
1985
  }
1840
- for (const name of names) if (SHA.test(name) && !keep.has(name)) fs5.rmSync(path5.join(this.dir, OBJECTS, name), { force: true });
1986
+ for (const name of names) if (SHA.test(name) && !keep.has(name)) fs6.rmSync(path6.join(this.dir, OBJECTS, name), { force: true });
1841
1987
  }
1842
1988
  save() {
1843
- writeAtomic2(path5.join(this.dir, INDEX), `${JSON.stringify(this.index)}
1989
+ writeAtomic2(path6.join(this.dir, INDEX), `${JSON.stringify(this.index)}
1844
1990
  `);
1845
1991
  }
1846
1992
  };
@@ -1910,19 +2056,19 @@ function diffContents(before, after) {
1910
2056
  }
1911
2057
 
1912
2058
  import { createHash as createHash2 } from "node:crypto";
1913
- import fs9 from "node:fs";
2059
+ import fs10 from "node:fs";
1914
2060
  import os4 from "node:os";
1915
- import path9 from "node:path";
2061
+ import path10 from "node:path";
1916
2062
 
1917
- import fs7 from "node:fs";
2063
+ import fs8 from "node:fs";
1918
2064
  import fsp2 from "node:fs/promises";
1919
- import path7 from "node:path";
2065
+ import path8 from "node:path";
1920
2066
  import { promisify } from "node:util";
1921
2067
  import zlib from "node:zlib";
1922
2068
 
1923
2069
  import crypto from "node:crypto";
1924
- import fs6 from "node:fs";
1925
- import path6 from "node:path";
2070
+ import fs7 from "node:fs";
2071
+ import path7 from "node:path";
1926
2072
  var GUEST_ROLES = ["editor", "commenter", "viewer"];
1927
2073
  var isGuestRole = (value) => typeof value === "string" && GUEST_ROLES.includes(value);
1928
2074
  var SHARING_FILE = ".sharing.json";
@@ -1949,13 +2095,13 @@ var Sharing = class _Sharing {
1949
2095
  file;
1950
2096
  state;
1951
2097
  constructor(root) {
1952
- this.file = path6.join(root, SHARING_FILE);
2098
+ this.file = path7.join(root, SHARING_FILE);
1953
2099
  this.state = _Sharing.read(this.file);
1954
2100
  }
1955
2101
  static read(file) {
1956
2102
  let raw;
1957
2103
  try {
1958
- raw = JSON.parse(fs6.readFileSync(file, "utf8"));
2104
+ raw = JSON.parse(fs7.readFileSync(file, "utf8"));
1959
2105
  } catch {
1960
2106
  return fresh();
1961
2107
  }
@@ -1987,9 +2133,9 @@ var Sharing = class _Sharing {
1987
2133
  }
1988
2134
  save() {
1989
2135
  const tmp = `${this.file}.${process.pid}.tmp`;
1990
- fs6.writeFileSync(tmp, `${JSON.stringify(this.state, null, 2)}
2136
+ fs7.writeFileSync(tmp, `${JSON.stringify(this.state, null, 2)}
1991
2137
  `, { mode: 384 });
1992
- fs6.renameSync(tmp, this.file);
2138
+ fs7.renameSync(tmp, this.file);
1993
2139
  }
1994
2140
  /** The role whose link has this token, while that link is on. */
1995
2141
  linkRole(tokenGiven) {
@@ -2071,10 +2217,10 @@ var ArchiveTooLarge = class extends Error {
2071
2217
  code = "TOO_LARGE";
2072
2218
  };
2073
2219
  async function archiveEntries(root, skip = []) {
2074
- const folder = path7.basename(path7.resolve(root)) || "artifact";
2075
- const skipped = new Set(skip.map((file) => path7.resolve(file)));
2220
+ const folder = path8.basename(path8.resolve(root)) || "artifact";
2221
+ const skipped = new Set(skip.map((file) => path8.resolve(file)));
2076
2222
  const entries = [];
2077
- const walk = async (dir, rel) => {
2223
+ const walk2 = async (dir, rel) => {
2078
2224
  let names;
2079
2225
  try {
2080
2226
  names = await fsp2.readdir(dir, { withFileTypes: true });
@@ -2085,17 +2231,17 @@ async function archiveEntries(root, skip = []) {
2085
2231
  for (const dirent of names.sort((a, b) => a.name < b.name ? -1 : a.name > b.name ? 1 : 0)) {
2086
2232
  const name = dirent.name;
2087
2233
  if (JUNK_FILES.has(name) || isTemp(name) || !rel && (LOCAL_FILES.has(name) || LOCAL_DIRS.has(name) && dirent.isDirectory())) continue;
2088
- const file = path7.join(dir, name);
2234
+ const file = path8.join(dir, name);
2089
2235
  if (skipped.has(file)) continue;
2090
2236
  const inner = rel ? `${rel}/${name}` : name;
2091
- if (dirent.isDirectory()) await walk(file, inner);
2237
+ if (dirent.isDirectory()) await walk2(file, inner);
2092
2238
  else if (dirent.isFile()) {
2093
2239
  const stat = await fsp2.stat(file).catch(() => null);
2094
2240
  if (stat?.isFile()) entries.push({ name: `${folder}/${inner}`, file, size: stat.size, mode: stat.mode & 511, mtime: stat.mtime });
2095
2241
  }
2096
2242
  }
2097
2243
  };
2098
- await walk(path7.resolve(root), "");
2244
+ await walk2(path8.resolve(root), "");
2099
2245
  if (entries.length > MAX_ENTRIES) throw new ArchiveTooLarge(`The folder holds ${entries.length} files, more than a zip holds (${MAX_ENTRIES}); copy the folder itself instead.`);
2100
2246
  const bound = entries.reduce((sum, entry) => sum + entry.size + 2 * (46 + Buffer.byteLength(entry.name)), 22);
2101
2247
  if (bound > MAX_BYTES) throw new ArchiveTooLarge(`The folder holds ${(bound / 2 ** 30).toFixed(1)} GiB, more than a zip holds (4 GiB); copy the folder itself instead.`);
@@ -2144,7 +2290,7 @@ async function writeZip(entries, write) {
2144
2290
  const crc = crc32(data);
2145
2291
  let method = 0;
2146
2292
  let body = data;
2147
- if (data.length > 0 && !STORED.has(path7.extname(entry.name).toLowerCase())) {
2293
+ if (data.length > 0 && !STORED.has(path8.extname(entry.name).toLowerCase())) {
2148
2294
  const deflated = await deflateRaw(data);
2149
2295
  if (deflated.length < data.length) {
2150
2296
  method = 8;
@@ -2198,12 +2344,12 @@ async function writeZip(entries, write) {
2198
2344
  }
2199
2345
  function archiveFileName(root, now = /* @__PURE__ */ new Date()) {
2200
2346
  const day = `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, "0")}-${String(now.getDate()).padStart(2, "0")}`;
2201
- return `${path7.basename(path7.resolve(root)) || "artifact"}-${day}.zip`;
2347
+ return `${path8.basename(path8.resolve(root)) || "artifact"}-${day}.zip`;
2202
2348
  }
2203
2349
  async function writeArchive(root, out) {
2204
- const file = path7.resolve(out);
2350
+ const file = path8.resolve(out);
2205
2351
  const entries = await archiveEntries(root, [file]);
2206
- const tmp = path7.join(path7.dirname(file), `.${path7.basename(file)}.${process.pid}.tmp`);
2352
+ const tmp = path8.join(path8.dirname(file), `.${path8.basename(file)}.${process.pid}.tmp`);
2207
2353
  const handle = await fsp2.open(tmp, "w");
2208
2354
  let bytes;
2209
2355
  try {
@@ -2221,10 +2367,10 @@ async function writeArchive(root, out) {
2221
2367
  return { file, files: entries.length, bytes };
2222
2368
  }
2223
2369
  async function archiveCommand(root, out) {
2224
- const where = out ? path7.resolve(out) : path7.dirname(path7.resolve(root));
2225
- const target = fs7.statSync(where, { throwIfNoEntry: false })?.isDirectory() ? path7.join(where, archiveFileName(root)) : where;
2370
+ const where = out ? path8.resolve(out) : path8.dirname(path8.resolve(root));
2371
+ const target = fs8.statSync(where, { throwIfNoEntry: false })?.isDirectory() ? path8.join(where, archiveFileName(root)) : where;
2226
2372
  const { file, files, bytes } = await writeArchive(root, target);
2227
- return { file, folder: path7.basename(path7.resolve(root)), files, bytes, leftOut: [...LOCAL_FILES] };
2373
+ return { file, folder: path8.basename(path8.resolve(root)), files, bytes, leftOut: [...LOCAL_FILES] };
2228
2374
  }
2229
2375
  function attachment(name) {
2230
2376
  const ascii = name.replace(/[^\x20-\x7e]|["\\]/g, "_");
@@ -2272,31 +2418,31 @@ async function sendArchive(request, response, root) {
2272
2418
  }
2273
2419
  }
2274
2420
 
2275
- import fs8 from "node:fs";
2421
+ import fs9 from "node:fs";
2276
2422
  import fsp3 from "node:fs/promises";
2277
2423
  import os3 from "node:os";
2278
- import path8 from "node:path";
2424
+ import path9 from "node:path";
2279
2425
  var MAX_BYTES2 = 4294967295;
2280
2426
  function shown(file) {
2281
2427
  const home = os3.homedir();
2282
- return home && (file === home || file.startsWith(home + path8.sep)) ? `~${file.slice(home.length)}` : file;
2428
+ return home && (file === home || file.startsWith(home + path9.sep)) ? `~${file.slice(home.length)}` : file;
2283
2429
  }
2284
2430
  function saved(file, bytes) {
2285
- return { path: file, name: path8.basename(file), folder: path8.dirname(file), shown: shown(file), bytes };
2431
+ return { path: file, name: path9.basename(file), folder: path9.dirname(file), shown: shown(file), bytes };
2286
2432
  }
2287
2433
  function safeFileName(raw) {
2288
2434
  let name = (raw.replace(/\\/g, "/").split("/").pop() ?? "").replace(/[\u0000-\u001f\u007f<>:"|?*]/g, "_").replace(/^[.\s]+|[.\s]+$/g, "");
2289
2435
  if (name.length > 200) {
2290
- const ext = path8.extname(name).slice(0, 16);
2436
+ const ext = path9.extname(name).slice(0, 16);
2291
2437
  name = name.slice(0, 200 - ext.length) + ext;
2292
2438
  }
2293
2439
  return name || "download";
2294
2440
  }
2295
2441
  async function openFree(dir, name) {
2296
- const ext = path8.extname(name);
2442
+ const ext = path9.extname(name);
2297
2443
  const stem = name.slice(0, name.length - ext.length);
2298
2444
  for (let n = 0; ; n++) {
2299
- const file = path8.join(dir, n === 0 ? name : `${stem} (${n})${ext}`);
2445
+ const file = path9.join(dir, n === 0 ? name : `${stem} (${n})${ext}`);
2300
2446
  try {
2301
2447
  return { file, handle: await fsp3.open(file, "wx") };
2302
2448
  } catch (error) {
@@ -2315,7 +2461,7 @@ async function saveDownload(request, response, root) {
2315
2461
  let handle = null;
2316
2462
  let bytes = 0;
2317
2463
  try {
2318
- const dir = path8.join(root, EXPORTS_DIR);
2464
+ const dir = path9.join(root, EXPORTS_DIR);
2319
2465
  await fsp3.mkdir(dir, { recursive: true });
2320
2466
  ({ file, handle } = await openFree(dir, name));
2321
2467
  for await (const chunk of request) {
@@ -2340,7 +2486,7 @@ async function saveArchive(request, response, root) {
2340
2486
  request.resume();
2341
2487
  try {
2342
2488
  const { file } = await archiveCommand(root, void 0);
2343
- sendJson2(response, 200, saved(file, fs8.statSync(file).size));
2489
+ sendJson2(response, 200, saved(file, fs9.statSync(file).size));
2344
2490
  } catch (error) {
2345
2491
  const tooLarge = error instanceof ArchiveTooLarge;
2346
2492
  sendJson2(response, tooLarge ? 413 : 500, { code: tooLarge ? "too_large" : "upstream_error", message: error instanceof Error ? error.message : String(error) });
@@ -2381,7 +2527,7 @@ function localOwner() {
2381
2527
  }
2382
2528
  return { id: "local", name, email: `${name}@localhost` };
2383
2529
  }
2384
- var guestCookieName = (kind, root) => `${kind.replace(/-/g, "_")}_guest_${createHash2("sha256").update(path9.resolve(root)).digest("hex").slice(0, 12)}`;
2530
+ var guestCookieName = (kind, root) => `${kind.replace(/-/g, "_")}_guest_${createHash2("sha256").update(path10.resolve(root)).digest("hex").slice(0, 12)}`;
2385
2531
  var ShareHost = class {
2386
2532
  sharing;
2387
2533
  options;
@@ -2546,7 +2692,7 @@ var ShareHost = class {
2546
2692
  }
2547
2693
  if (method === "GET" && p === "/__share/invite") return sendJson2(response, 200, this.invites(viewer, request.headers.host ?? "")), true;
2548
2694
  if (method === "GET" && p === "/__share/ui.js") {
2549
- fs9.stat(this.options.uiFile, (error, stat) => {
2695
+ fs10.stat(this.options.uiFile, (error, stat) => {
2550
2696
  if (error || !stat.isFile()) return sendJson2(response, 404, { code: "not_found", message: "The Share panel is missing." });
2551
2697
  sendFile(request, response, this.options.uiFile, { "Content-Type": "text/javascript; charset=utf-8", "Content-Length": stat.size, "Cache-Control": "no-store", "X-Content-Type-Options": "nosniff" });
2552
2698
  });
@@ -2566,7 +2712,7 @@ var ShareHost = class {
2566
2712
  */
2567
2713
  headTags(_viewer, query = "") {
2568
2714
  let tags = `<script src="/__share/boot.js${query.replace(/[<>"']/g, "").replace(/&/g, "&amp;")}"></script>`;
2569
- if (fs9.existsSync(this.options.uiFile)) tags += '<script type="module" src="/__share/ui.js"></script>';
2715
+ if (fs10.existsSync(this.options.uiFile)) tags += '<script type="module" src="/__share/ui.js"></script>';
2570
2716
  return tags;
2571
2717
  }
2572
2718
  /** `html` with the head tags first in its <head>; null when it has none. */
@@ -2958,7 +3104,7 @@ function noticeView(n, label, lostAt, gone) {
2958
3104
  ...n.lost.sha === null ? { deleted: true } : {}
2959
3105
  };
2960
3106
  }
2961
- var plain = (text) => ({ en: text, zh: text });
3107
+ var plain2 = (text) => ({ en: text, zh: text });
2962
3108
 
2963
3109
  var PEER_ID = /^[A-Za-z0-9_-]{8,64}$/;
2964
3110
  function agentWhere(main2, count, label) {
@@ -3266,7 +3412,7 @@ async function collectFiles(root, limit) {
3266
3412
  const seen = /* @__PURE__ */ new Set();
3267
3413
  let truncated = false;
3268
3414
  const visit = async (relDir, descend) => {
3269
- const dir = relDir === "" ? root : path10.join(root, ...relDir.split("/"));
3415
+ const dir = relDir === "" ? root : path11.join(root, ...relDir.split("/"));
3270
3416
  let entries;
3271
3417
  try {
3272
3418
  entries = await fsp4.readdir(dir, { withFileTypes: true });
@@ -3297,8 +3443,8 @@ async function collectFiles(root, limit) {
3297
3443
  return { rels, truncated };
3298
3444
  }
3299
3445
  async function writeFileAtomic(file, bytes) {
3300
- await fsp4.mkdir(path10.dirname(file), { recursive: true });
3301
- const tmp = path10.join(path10.dirname(file), `.${path10.basename(file)}.${randomUUID()}.tmp`);
3446
+ await fsp4.mkdir(path11.dirname(file), { recursive: true });
3447
+ const tmp = path11.join(path11.dirname(file), `.${path11.basename(file)}.${randomUUID()}.tmp`);
3302
3448
  try {
3303
3449
  await fsp4.writeFile(tmp, bytes);
3304
3450
  await fsp4.rename(tmp, file);
@@ -3354,11 +3500,11 @@ var Store = class {
3354
3500
  async diskPath(rel) {
3355
3501
  const realRoot = await fsp4.realpath(this.root).catch(() => null);
3356
3502
  if (realRoot === null) return null;
3357
- const file = path10.join(realRoot, ...rel.split("/"));
3358
- for (let dir = path10.dirname(file); ; dir = path10.dirname(dir)) {
3503
+ const file = path11.join(realRoot, ...rel.split("/"));
3504
+ for (let dir = path11.dirname(file); ; dir = path11.dirname(dir)) {
3359
3505
  const real = await fsp4.realpath(dir).catch(() => null);
3360
3506
  if (real === null) {
3361
- if (path10.dirname(dir) === dir) return null;
3507
+ if (path11.dirname(dir) === dir) return null;
3362
3508
  continue;
3363
3509
  }
3364
3510
  if (real !== dir) return null;
@@ -3588,7 +3734,7 @@ var Store = class {
3588
3734
  }
3589
3735
  async findBlobFile(id) {
3590
3736
  try {
3591
- const names = await fsp4.readdir(path10.join(this.root, LAYOUT.blobDir));
3737
+ const names = await fsp4.readdir(path11.join(this.root, LAYOUT.blobDir));
3592
3738
  const name = names.find((n) => n.startsWith(`${id}.`) && !n.endsWith(".tmp"));
3593
3739
  if (name === void 0) return null;
3594
3740
  const file = await this.diskPath(`${LAYOUT.blobDir}/${name}`);
@@ -3643,13 +3789,13 @@ function watchArtifact(store, onChange, onError) {
3643
3789
  const directories = /* @__PURE__ */ new Map();
3644
3790
  const visit = (rel, descend) => {
3645
3791
  if (directories.size >= maxDirectories) return;
3646
- const dir = rel === "" ? store.root : path10.join(store.root, ...rel.split("/"));
3647
- if (directories.has(dir) || !fs10.existsSync(dir)) return;
3648
- const info = fs10.lstatSync(dir);
3792
+ const dir = rel === "" ? store.root : path11.join(store.root, ...rel.split("/"));
3793
+ if (directories.has(dir) || !fs11.existsSync(dir)) return;
3794
+ const info = fs11.lstatSync(dir);
3649
3795
  if (!info.isDirectory()) return;
3650
3796
  directories.set(dir, `${info.dev}:${info.ino}`);
3651
3797
  if (!descend) return;
3652
- for (const entry of fs10.readdirSync(dir, { withFileTypes: true })) {
3798
+ for (const entry of fs11.readdirSync(dir, { withFileTypes: true })) {
3653
3799
  if (!entry.isDirectory() || entry.name.startsWith(".")) continue;
3654
3800
  const child = rel === "" ? entry.name : `${rel}/${entry.name}`;
3655
3801
  if (LAYOUT.descendInto(child)) visit(child, true);
@@ -3666,19 +3812,19 @@ function watchArtifact(store, onChange, onError) {
3666
3812
  if (watchers.has(dir)) continue;
3667
3813
  let watcher;
3668
3814
  try {
3669
- watcher = fs10.watch(dir, (event, name) => {
3815
+ watcher = fs11.watch(dir, (event, name) => {
3670
3816
  if (stopped) return;
3671
3817
  if (name) {
3672
- const changed = path10.join(dir, String(name));
3818
+ const changed = path11.join(dir, String(name));
3673
3819
  if (event === "rename" && watchers.has(changed)) {
3674
3820
  for (const [watchedDir, item] of watchers) {
3675
- if (watchedDir === changed || watchedDir.startsWith(changed + path10.sep)) {
3821
+ if (watchedDir === changed || watchedDir.startsWith(changed + path11.sep)) {
3676
3822
  item.watcher.close();
3677
3823
  watchers.delete(watchedDir);
3678
3824
  }
3679
3825
  }
3680
3826
  }
3681
- const rel = path10.relative(store.root, changed).split(path10.sep).join("/");
3827
+ const rel = path11.relative(store.root, changed).split(path11.sep).join("/");
3682
3828
  if (isIgnoredPath(rel) || !LAYOUT.watches(rel)) return;
3683
3829
  }
3684
3830
  schedule();
@@ -3714,7 +3860,7 @@ function watchArtifact(store, onChange, onError) {
3714
3860
  const { rels } = await collectFiles(store.root, LAYOUT.maxFiles);
3715
3861
  const parts = [];
3716
3862
  for (const rel of rels) {
3717
- const info = await fsp4.lstat(path10.join(store.root, ...rel.split("/"))).catch(() => null);
3863
+ const info = await fsp4.lstat(path11.join(store.root, ...rel.split("/"))).catch(() => null);
3718
3864
  parts.push(info ? `${rel}\0${info.size}\0${info.mtimeMs}\0${info.ino}` : `${rel}\0-`);
3719
3865
  }
3720
3866
  return parts.join("\n");
@@ -3745,11 +3891,11 @@ function watchArtifact(store, onChange, onError) {
3745
3891
  var publishError = (response, status, code, message) => sendJson2(response, status, { code, message });
3746
3892
  async function startServer({ root, port = DEFAULT_PORTS[KIND], host = "127.0.0.1", log = (line) => process.stderr.write(`${line}
3747
3893
  `), agentHook, lan = false, portGiven = false }) {
3748
- const project = path10.join(root, "project");
3749
- const stamp = (line) => log(`[${(/* @__PURE__ */ new Date()).toISOString()}] ${line}`);
3894
+ const project = path11.join(root, "project");
3895
+ const stamp2 = (line) => log(`[${(/* @__PURE__ */ new Date()).toISOString()}] ${line}`);
3750
3896
  const projectDir = await fsp4.realpath(project);
3751
3897
  const history = new History(root);
3752
- const store = new Store(projectDir, history, stamp);
3898
+ const store = new Store(projectDir, history, stamp2);
3753
3899
  const owner = localOwner();
3754
3900
  const share = new ShareHost({
3755
3901
  root,
@@ -3757,9 +3903,9 @@ async function startServer({ root, port = DEFAULT_PORTS[KIND], host = "127.0.0.1
3757
3903
  owner,
3758
3904
  noun: NOUNS[KIND] ?? { en: NOUN, zh: NOUN, zhThis: NOUN },
3759
3905
  title: () => artifactTitle(root, projectDir),
3760
- log: stamp,
3906
+ log: stamp2,
3761
3907
  createServer: () => http.createServer(handle),
3762
- uiFile: path10.join(EDITOR_DIR, "share-ui.js"),
3908
+ uiFile: path11.join(EDITOR_DIR, "share-ui.js"),
3763
3909
  // The History panel's address and what this person may do there; on a version's page (?at=n), which version.
3764
3910
  globals: (viewer, query) => {
3765
3911
  const at = Number(query.get("at") ?? "");
@@ -3768,7 +3914,7 @@ async function startServer({ root, port = DEFAULT_PORTS[KIND], host = "127.0.0.1
3768
3914
  });
3769
3915
  const comments = createCommentsService({
3770
3916
  root,
3771
- log: stamp,
3917
+ log: stamp2,
3772
3918
  locate: commentLocation ? (input) => commentLocation(input, projectDir) : void 0,
3773
3919
  agentHook,
3774
3920
  userName: owner.name,
@@ -3807,7 +3953,7 @@ data: ${JSON.stringify(event)}
3807
3953
  }
3808
3954
  return (p) => {
3809
3955
  const rel = p.replace(/^project\//, "");
3810
- return named?.(rel) ?? plain(rel);
3956
+ return named?.(rel) ?? plain2(rel);
3811
3957
  };
3812
3958
  };
3813
3959
  const agentWorked = (paths) => {
@@ -3838,16 +3984,16 @@ data: ${JSON.stringify(event)}
3838
3984
  // A notice whose overwrite named the version its saver's edits started from: what was lost goes back by line into
3839
3985
  // the file as it is now, the lost lines winning where both changed them; a deleted file gets all of it back.
3840
3986
  recover: (_path, base, lost, now) => now === null ? lost : mergeTextBytes(base, lost, now),
3841
- log: stamp
3987
+ log: stamp2
3842
3988
  });
3843
3989
  const stopWatch = watchArtifact(
3844
3990
  store,
3845
3991
  (event) => {
3846
- stamp(`changed on disk: ${event.paths.join(", ")}${clients.size ? "" : " (no page open)"}`);
3992
+ stamp2(`changed on disk: ${event.paths.join(", ")}${clients.size ? "" : " (no page open)"}`);
3847
3993
  changed({ ...event, by: authorOf(AGENT) });
3848
3994
  agentWorked(event.paths);
3849
3995
  },
3850
- (error) => stamp(`watching failed: ${errorText(error)}`)
3996
+ (error) => stamp2(`watching failed: ${errorText(error)}`)
3851
3997
  );
3852
3998
  const events = async (request, response, viewer) => {
3853
3999
  const given = new URL(request.url ?? "/", "http://local").searchParams.get("client") ?? "";
@@ -3910,7 +4056,7 @@ data: ${JSON.stringify(event)}
3910
4056
  const parts = rest === "" ? ["index.html"] : rest.split("/");
3911
4057
  const invalid = parts.some((p) => p === "" || p === "." || p === ".." || p.startsWith(".") || p.includes("\\")) || parts[0] === "node";
3912
4058
  const realDist = invalid ? null : await fsp4.realpath(EDITOR_DIR).catch(() => null);
3913
- const file = realDist === null ? null : path10.join(realDist, ...parts);
4059
+ const file = realDist === null ? null : path11.join(realDist, ...parts);
3914
4060
  const real = file === null ? null : await fsp4.realpath(file).catch(() => null);
3915
4061
  const info = real === null ? null : await fsp4.lstat(real).catch(() => null);
3916
4062
  if (file === null || real !== file || !info?.isFile()) {
@@ -3921,7 +4067,7 @@ data: ${JSON.stringify(event)}
3921
4067
  response.writeHead(404, { "Cache-Control": "no-store" }).end();
3922
4068
  return;
3923
4069
  }
3924
- const ext = path10.extname(file).toLowerCase();
4070
+ const ext = path11.extname(file).toLowerCase();
3925
4071
  const type = STATIC_TYPES[ext] ?? "application/octet-stream";
3926
4072
  if (ext === ".html") {
3927
4073
  const key = parts.join("/");
@@ -3976,7 +4122,7 @@ data: ${JSON.stringify(event)}
3976
4122
  const outcome = await store.publish(files, whoOf(viewer), over, merged, CLIENT_ID.test(page) ? page : "");
3977
4123
  const names = Object.keys(files).map((p) => p.replace(/^project\//, ""));
3978
4124
  const made = outcome.version ? ` as version ${outcome.version.n}` : "";
3979
- stamp(`saved from the page by ${viewer.user.name} (${outcome.status}${outcome.body.code ? ` ${outcome.body.code}` : ""})${made}: ${names.join(", ")}`);
4125
+ stamp2(`saved from the page by ${viewer.user.name} (${outcome.status}${outcome.body.code ? ` ${outcome.body.code}` : ""})${made}: ${names.join(", ")}`);
3980
4126
  sendJson2(response, outcome.status, outcome.body);
3981
4127
  if (outcome.status === 200 && clients.size > 0) {
3982
4128
  const from = String(request.headers["x-deck-client"] ?? "");
@@ -3997,7 +4143,7 @@ data: ${JSON.stringify(event)}
3997
4143
  return;
3998
4144
  }
3999
4145
  const result = await store.putBlob(bytes, contentType);
4000
- stamp(`uploaded from the page: ${result.url} (${contentType}, ${bytes.length} bytes)`);
4146
+ stamp2(`uploaded from the page: ${result.url} (${contentType}, ${bytes.length} bytes)`);
4001
4147
  sendJson2(response, 200, result);
4002
4148
  };
4003
4149
  const session = (viewer) => {
@@ -4110,6 +4256,24 @@ data: ${JSON.stringify(event)}
4110
4256
  else await upload(request, response);
4111
4257
  return;
4112
4258
  }
4259
+ const dsSync = DESIGN_SYSTEMS ? DS_SYNC.exec(rest) : null;
4260
+ if (dsSync) {
4261
+ const folder = dsSync[1];
4262
+ const status = systemStatus(projectDir, root, INDEX_FILE, folder);
4263
+ if (method === "POST") {
4264
+ request.resume();
4265
+ if (!sameOrigin(request)) return publishError(response, 403, "not_writer", "cross-origin request");
4266
+ if (viewer.guest) return publishError(response, 403, "not_owner", "Only the owner of this computer can sync a design system from its source.");
4267
+ if (status === null) return sendJson2(response, 404, { error: "not_found" });
4268
+ const [result] = syncSystems(projectDir, root, INDEX_FILE, { namespace: folder });
4269
+ return sendJson2(response, 200, { copied: result.copied.length, ...systemStatus(projectDir, root, INDEX_FILE, folder), canSync: true });
4270
+ }
4271
+ if (method !== "GET" && method !== "HEAD") {
4272
+ response.writeHead(405, { Allow: "GET, HEAD, POST" }).end();
4273
+ return;
4274
+ }
4275
+ return status === null ? sendJson2(response, 404, { error: "not_found" }, { "Cache-Control": "no-store" }) : sendJson2(response, 200, { ...status, canSync: !viewer.guest }, { "Cache-Control": "no-store" });
4276
+ }
4113
4277
  if (method !== "GET" && method !== "HEAD") {
4114
4278
  response.writeHead(405, { Allow: "GET, HEAD" }).end();
4115
4279
  return;
@@ -4165,7 +4329,7 @@ data: ${JSON.stringify(event)}
4165
4329
  if (!response.headersSent) publishError(response, 413, "too_large", "request body is too large");
4166
4330
  return;
4167
4331
  }
4168
- stamp(`request failed: ${error instanceof Error ? error.stack ?? error.message : String(error)}`);
4332
+ stamp2(`request failed: ${error instanceof Error ? error.stack ?? error.message : String(error)}`);
4169
4333
  if (!response.headersSent) publishError(response, 500, "upstream_error", "internal error");
4170
4334
  else response.destroy();
4171
4335
  }
@@ -4228,17 +4392,17 @@ data: ${JSON.stringify(event)}
4228
4392
  throw error;
4229
4393
  });
4230
4394
  const url = `${serverOrigin(host, actualPort)}${editorPath}`;
4231
- stamp(`serving ${project} at ${url}`);
4395
+ stamp2(`serving ${project} at ${url}`);
4232
4396
  const lanUrls = share.lanUrls();
4233
4397
  return { url, port: actualPort, grant, close, ...lanUrls.length ? { lan: lanUrls } : {} };
4234
4398
  }
4235
4399
  function artifactTitle(root, projectDir) {
4236
4400
  try {
4237
- const index = JSON.parse(fs10.readFileSync(path10.join(projectDir, INDEX_FILE), "utf8"));
4401
+ const index = JSON.parse(fs11.readFileSync(path11.join(projectDir, INDEX_FILE), "utf8"));
4238
4402
  for (const value of [index.title, index.name]) if (typeof value === "string" && value.trim() && value.trim() !== "project") return value.trim();
4239
4403
  } catch {
4240
4404
  }
4241
- return path10.basename(root);
4405
+ return path11.basename(root);
4242
4406
  }
4243
4407
  var runningServer2 = (root) => runningServer(root, KIND, ROUTES.session);
4244
4408
  async function serveForeground({ root, port, host, agentHook, lan, portGiven }) {
@@ -4259,18 +4423,18 @@ async function main(argv) {
4259
4423
  }
4260
4424
  if (positional.length !== 1 || flags.has("help")) {
4261
4425
  process.stderr.write(
4262
- `Usage: node ${path10.basename(SCRIPT)} <root> [--port n] [--host h] [--lan] [--agent-hook "<command>"]
4426
+ `Usage: node ${path11.basename(SCRIPT)} <root> [--port n] [--host h] [--lan] [--agent-hook "<command>"]
4263
4427
  <root> holds project/${INDEX_FILE}.
4264
4428
  `
4265
4429
  );
4266
4430
  return 2;
4267
4431
  }
4268
- let root = path10.resolve(positional[0]);
4269
- if (path10.basename(root) === "project" && fs10.existsSync(path10.join(root, INDEX_FILE)) && !fs10.existsSync(path10.join(root, "project"))) {
4270
- root = path10.dirname(root);
4432
+ let root = path11.resolve(positional[0]);
4433
+ if (path11.basename(root) === "project" && fs11.existsSync(path11.join(root, INDEX_FILE)) && !fs11.existsSync(path11.join(root, "project"))) {
4434
+ root = path11.dirname(root);
4271
4435
  }
4272
- if (!fs10.statSync(path10.join(root, "project", INDEX_FILE), { throwIfNoEntry: false })?.isFile()) {
4273
- process.stderr.write(`${JSON.stringify({ error: "NOT_FOUND", message: `${path10.join(root, "project", INDEX_FILE)} does not exist.` })}
4436
+ if (!fs11.statSync(path11.join(root, "project", INDEX_FILE), { throwIfNoEntry: false })?.isFile()) {
4437
+ process.stderr.write(`${JSON.stringify({ error: "NOT_FOUND", message: `${path11.join(root, "project", INDEX_FILE)} does not exist.` })}
4274
4438
  `);
4275
4439
  return 2;
4276
4440
  }
@@ -4294,7 +4458,7 @@ async function main(argv) {
4294
4458
  }
4295
4459
  function isMain(moduleUrl) {
4296
4460
  try {
4297
- return Boolean(process.argv[1]) && pathToFileURL(fs10.realpathSync(process.argv[1])).href === moduleUrl;
4461
+ return Boolean(process.argv[1]) && pathToFileURL(fs11.realpathSync(process.argv[1])).href === moduleUrl;
4298
4462
  } catch {
4299
4463
  return false;
4300
4464
  }
@@ -4311,7 +4475,7 @@ function createArtifactServer(kind, moduleUrl) {
4311
4475
  kindLabels = kind.labels;
4312
4476
  kindAgentContext = kind.agentContext;
4313
4477
  SCRIPT = fileURLToPath(moduleUrl);
4314
- EDITOR_DIR = path10.join(path10.dirname(SCRIPT), "editor");
4478
+ EDITOR_DIR = path11.join(path11.dirname(SCRIPT), "editor");
4315
4479
  const runIfMain = () => {
4316
4480
  if (!isMain(moduleUrl)) return;
4317
4481
  main(process.argv.slice(2)).then(
@@ -4362,19 +4526,19 @@ function commentLocation2(input, projectDir) {
4362
4526
  let slideId = match[2];
4363
4527
  if (!slideId) {
4364
4528
  try {
4365
- const order = JSON.parse(fs11.readFileSync(path11.join(projectDir, INDEX_FILE2), "utf8")).order;
4529
+ const order = JSON.parse(fs12.readFileSync(path12.join(projectDir, INDEX_FILE2), "utf8")).order;
4366
4530
  if (Array.isArray(order) && typeof order[slide - 1] === "string") slideId = order[slide - 1];
4367
4531
  } catch {
4368
4532
  }
4369
4533
  }
4370
4534
  const file = slideId ? projectFile(`slides/${slideId}.html`) : void 0;
4371
- if (slideId && file && fs11.existsSync(path11.join(projectDir, "slides", `${slideId}.html`))) return { file, slide, slideId };
4535
+ if (slideId && file && fs12.existsSync(path12.join(projectDir, "slides", `${slideId}.html`))) return { file, slide, slideId };
4372
4536
  return { file: "project/deck.json", slide };
4373
4537
  }
4374
4538
  function labels(projectDir) {
4375
4539
  let order = [];
4376
4540
  try {
4377
- const listed = JSON.parse(fs11.readFileSync(path11.join(projectDir, INDEX_FILE2), "utf8")).order;
4541
+ const listed = JSON.parse(fs12.readFileSync(path12.join(projectDir, INDEX_FILE2), "utf8")).order;
4378
4542
  if (Array.isArray(listed)) order = listed.filter((id) => typeof id === "string");
4379
4543
  } catch {
4380
4544
  }
@@ -4394,7 +4558,7 @@ function agentContext(projectDir, rels) {
4394
4558
  if (!slideId) return null;
4395
4559
  let order = [];
4396
4560
  try {
4397
- const listed = JSON.parse(fs11.readFileSync(path11.join(projectDir, INDEX_FILE2), "utf8")).order;
4561
+ const listed = JSON.parse(fs12.readFileSync(path12.join(projectDir, INDEX_FILE2), "utf8")).order;
4398
4562
  if (Array.isArray(listed)) order = listed.filter((id) => typeof id === "string");
4399
4563
  } catch {
4400
4564
  }