kennel 0.2.44 → 0.2.45

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.
Files changed (85) hide show
  1. package/dist/core/api-client.d.ts +1 -1
  2. package/dist/core/api-client.js +35 -2
  3. package/dist/core/runtime.js +548 -99
  4. package/dist/llm/worker.js +11 -2
  5. package/dist/notes/command.js +20 -4
  6. package/dist/package/preview.d.ts +1 -1
  7. package/dist/package/preview.js +760 -495
  8. package/dist/site/hot-viewer.js +4 -4
  9. package/dist/site/server-plugins.js +468 -30
  10. package/dist/site/viewer.d.ts +0 -3
  11. package/dist/site/viewer.js +11 -41
  12. package/dist/tui/launcher.d.ts +11 -0
  13. package/dist/{site/terminal.js → tui/launcher.js} +60 -15
  14. package/package.json +2 -2
  15. package/web/assets/{abnfDiagram-VRR7QNED-ooA_TyhC.js → abnfDiagram-VRR7QNED-D8mHNUwf.js} +1 -1
  16. package/web/assets/{arc-DqQkY48J.js → arc-DORR-Lbn.js} +1 -1
  17. package/web/assets/{architectureDiagram-ZJ3FMSHR-DaXzRGP0.js → architectureDiagram-ZJ3FMSHR-CnmL2DAX.js} +1 -1
  18. package/web/assets/ask-tray-KUTWZ4MV-VQJJAsDn.js +1 -0
  19. package/web/assets/{blockDiagram-677ZJIJ3-Br5Y_dbP.js → blockDiagram-677ZJIJ3-_SWUT5nP.js} +1 -1
  20. package/web/assets/{c4Diagram-LMCZKHZV-CWIy0S0N.js → c4Diagram-LMCZKHZV-r7ghc180.js} +1 -1
  21. package/web/assets/channel-r9-1szjb.js +1 -0
  22. package/web/assets/{chunk-2Q5K7J3B-8dxcuNwr.js → chunk-2Q5K7J3B-D_LeMwFJ.js} +1 -1
  23. package/web/assets/{chunk-32BRIVSS-DB27hz0Y.js → chunk-32BRIVSS-AeVZw1It.js} +1 -1
  24. package/web/assets/{chunk-5VM5RSS4-CTNxGtbA.js → chunk-5VM5RSS4-Bp_epQ8r.js} +1 -1
  25. package/web/assets/{chunk-EX3LRPZG-oKNLktOC.js → chunk-EX3LRPZG-Dz4n-DeM.js} +1 -1
  26. package/web/assets/{chunk-JWPE2WC7-DeQNmWoS.js → chunk-JWPE2WC7-B0MQp8TQ.js} +1 -1
  27. package/web/assets/{chunk-MOJQB5TN-BrW33Mrb.js → chunk-MOJQB5TN-Bkomqk1x.js} +1 -1
  28. package/web/assets/{chunk-RYQCIY6F-DEkTU6j-.js → chunk-RYQCIY6F-B0F7WMyE.js} +1 -1
  29. package/web/assets/{chunk-V7JOEXUC-BuDLgwdB.js → chunk-V7JOEXUC-BDifU9oY.js} +1 -1
  30. package/web/assets/{chunk-VR4S4FIN-BsNgrrKe.js → chunk-VR4S4FIN-Bgd4HCG_.js} +1 -1
  31. package/web/assets/{chunk-XXDRQBXY-DjT1Bydl.js → chunk-XXDRQBXY-BK8FhRs4.js} +1 -1
  32. package/web/assets/classDiagram-OUVF2IWQ-L_jmDmNd.js +1 -0
  33. package/web/assets/classDiagram-v2-EOCWNBFH-L_jmDmNd.js +1 -0
  34. package/web/assets/client-5Q4VI7ZT-BkTtFalV.js +52 -0
  35. package/web/assets/{cose-bilkent-JH36ORCC-BtAklxrd.js → cose-bilkent-JH36ORCC-Dm3k2U47.js} +1 -1
  36. package/web/assets/{cynefin-VYW2F7L2-DabtZWZy.js → cynefin-VYW2F7L2-DCnilF1f.js} +1 -1
  37. package/web/assets/{cynefinDiagram-TSTJHNR4-DVk8uQ8L.js → cynefinDiagram-TSTJHNR4-BrulEEQ9.js} +1 -1
  38. package/web/assets/{dagre-VKFMJZFB-CiAbBCor.js → dagre-VKFMJZFB-Dda61i4h.js} +1 -1
  39. package/web/assets/{diagram-FQU43EPY-DWp-OzJz.js → diagram-FQU43EPY-sTmDEDMM.js} +1 -1
  40. package/web/assets/{diagram-G47NLZAW-YDllS_1P.js → diagram-G47NLZAW-d-KQnPrm.js} +1 -1
  41. package/web/assets/{diagram-NH7WQ7WH-BH3l4yRj.js → diagram-NH7WQ7WH-DcRxa_ps.js} +1 -1
  42. package/web/assets/{diagram-OA4YK3LP-CszBvxdr.js → diagram-OA4YK3LP-CYzWtWvV.js} +1 -1
  43. package/web/assets/{diagram-WEI45ONY-bEhZeER6.js → diagram-WEI45ONY-FI3V_N07.js} +1 -1
  44. package/web/assets/document-view-TGFRNHKS-VSJS3BGw.js +24 -0
  45. package/web/assets/{ebnfDiagram-CCIWWBDH-DlpoUUO5.js → ebnfDiagram-CCIWWBDH-DcvVmQhu.js} +1 -1
  46. package/web/assets/{entity-search-page-YP4SPMBC-WryWZNPk.js → entity-search-page-RIYQYIJJ-Bed3y-5Q.js} +5 -5
  47. package/web/assets/{erDiagram-Q63AITRT-DROgehIM.js → erDiagram-Q63AITRT-DI5DBlBp.js} +1 -1
  48. package/web/assets/{flowDiagram-23GEKE2U-63pYiBzl.js → flowDiagram-23GEKE2U-Bz1AbRxB.js} +1 -1
  49. package/web/assets/{ganttDiagram-NO4QXBWP-tc34wKHJ.js → ganttDiagram-NO4QXBWP-ChKlhxeo.js} +1 -1
  50. package/web/assets/{gitGraphDiagram-IHSO6WYX-GOjqt583.js → gitGraphDiagram-IHSO6WYX-BtTqLSyY.js} +1 -1
  51. package/web/assets/{index-qmu99cjp.js → index-CDAH4UPU.js} +157 -157
  52. package/web/assets/{infoDiagram-FWYZ7A6U-CD5BwkLQ.js → infoDiagram-FWYZ7A6U-COpIz9uZ.js} +1 -1
  53. package/web/assets/{ishikawaDiagram-FXEZZL3T-yIweY6wR.js → ishikawaDiagram-FXEZZL3T-CB7Bdsfr.js} +1 -1
  54. package/web/assets/{journeyDiagram-5HDEW3XC-D3MeUGvn.js → journeyDiagram-5HDEW3XC-BMytnJBE.js} +1 -1
  55. package/web/assets/{kanban-definition-HUTT4EX6-CnZ5N79y.js → kanban-definition-HUTT4EX6-BFS4G0g-.js} +1 -1
  56. package/web/assets/{linear-s5G6iOMz.js → linear-DMUO2qBp.js} +1 -1
  57. package/web/assets/{linked-session-header-DOEX4FYM-CtTOXcZn.js → linked-session-header-7BUTWROP-DzEcA4Fq.js} +1 -1
  58. package/web/assets/{mermaid.core-BpUKp9r_.js → mermaid.core-BAj-Ltr-.js} +4 -4
  59. package/web/assets/{mindmap-definition-LN4V7U3C-Bp2QH5sN.js → mindmap-definition-LN4V7U3C-CjymOEvH.js} +1 -1
  60. package/web/assets/{pegDiagram-2B236MQR-lx1jDUmt.js → pegDiagram-2B236MQR-D64jiUPu.js} +1 -1
  61. package/web/assets/{pieDiagram-ENE6RG2P--kf2YNbw.js → pieDiagram-ENE6RG2P-CCbI5U6o.js} +1 -1
  62. package/web/assets/{plugin-host-modules-BKbxlu7U.js → plugin-host-modules-D7pHtNJn.js} +2 -2
  63. package/web/assets/{project-search-page-TZG7AZBQ-3W40ayYn.js → project-search-page-O6YRLDGU-1bPrifgb.js} +2 -2
  64. package/web/assets/{quadrantDiagram-ABIIQ3AL-Vr7zWQYV.js → quadrantDiagram-ABIIQ3AL-B7dN_Kn5.js} +1 -1
  65. package/web/assets/{railroadDiagram-RFXS5EU6-CqWD8KUC.js → railroadDiagram-RFXS5EU6-BPjAzqcL.js} +1 -1
  66. package/web/assets/{requirementDiagram-TGXJPOKE-BHUBdOVh.js → requirementDiagram-TGXJPOKE-BFhnnUWa.js} +1 -1
  67. package/web/assets/{sankeyDiagram-HTMAVEWB-Cw_ZddWI.js → sankeyDiagram-HTMAVEWB-W2UguUjW.js} +1 -1
  68. package/web/assets/{selection-popup-ABYH3A27-Gc-RFSWj.js → selection-popup-ABYH3A27-DsiLbG7S.js} +4 -4
  69. package/web/assets/{sequenceDiagram-DBY2YBRQ-CyCbkAfM.js → sequenceDiagram-DBY2YBRQ-DcOakOD4.js} +1 -1
  70. package/web/assets/{sizeCapture-X5ZJPWSS-BG6RM8rb.js → sizeCapture-X5ZJPWSS-D3N248Z6.js} +1 -1
  71. package/web/assets/{stateDiagram-2N3HPSRC-DKpZl5UU.js → stateDiagram-2N3HPSRC-Cir3yiDe.js} +1 -1
  72. package/web/assets/{stateDiagram-v2-6OUMAXLB-DHUy-0iS.js → stateDiagram-v2-6OUMAXLB-BwL0KYLn.js} +1 -1
  73. package/web/assets/{swimlanes-5IMT3BWC-D14uyHMH.js → swimlanes-5IMT3BWC-Dhq7FmZr.js} +2 -2
  74. package/web/assets/swimlanesDiagram-G3AALYLV-D4q-nPpB.js +8 -0
  75. package/web/assets/{timeline-definition-FHXFAJF6-f4WPhEXS.js → timeline-definition-FHXFAJF6-CMa1wjsI.js} +1 -1
  76. package/web/assets/{vennDiagram-L72KCM5P-lr4A8guw.js → vennDiagram-L72KCM5P-DvglazwQ.js} +1 -1
  77. package/web/assets/{wardleyDiagram-EHGQE667-CR-Im585.js → wardleyDiagram-EHGQE667-DcogrL32.js} +1 -1
  78. package/web/assets/{xychartDiagram-FW5EYKEG-DeNQfP7k.js → xychartDiagram-FW5EYKEG-BlsDcr_U.js} +1 -1
  79. package/web/index.html +1 -1
  80. package/dist/site/terminal.d.ts +0 -14
  81. package/web/assets/ask-tray-KUTWZ4MV-Ckn1y1Zw.js +0 -24
  82. package/web/assets/channel-BQxXBpeY.js +0 -1
  83. package/web/assets/classDiagram-OUVF2IWQ-BT1TSwZs.js +0 -1
  84. package/web/assets/classDiagram-v2-EOCWNBFH-BT1TSwZs.js +0 -1
  85. package/web/assets/swimlanesDiagram-G3AALYLV-C5riej52.js +0 -8
@@ -17027,8 +17027,8 @@ var require__2020 = __commonJS(function(exports, module) {
17027
17027
  import {
17028
17028
  createServer
17029
17029
  } from "node:http";
17030
- import { readFile as readFile11, realpath as realpath8, stat as stat10 } from "node:fs/promises";
17031
- import { extname as extname7, isAbsolute as isAbsolute8, relative as relative12, resolve as resolve13 } from "node:path";
17030
+ import { readFile as readFile12, realpath as realpath9, stat as stat12 } from "node:fs/promises";
17031
+ import { extname as extname7, isAbsolute as isAbsolute8, relative as relative13, resolve as resolve16 } from "node:path";
17032
17032
 
17033
17033
  // packages/api/src/server/watcher.ts
17034
17034
  import { existsSync, statSync, watch } from "node:fs";
@@ -21739,6 +21739,7 @@ var plugin = object({
21739
21739
  icon: object({ paths: array(string2().min(1)).min(1) }).optional(),
21740
21740
  id: string2(),
21741
21741
  label: string2(),
21742
+ pages: array(object({ id: string2(), label: string2() })).optional(),
21742
21743
  subpath: string2().optional()
21743
21744
  });
21744
21745
  var plugins = object({
@@ -21993,17 +21994,17 @@ function sendContract(response, url, body, headers = {}) {
21993
21994
  }
21994
21995
 
21995
21996
  // packages/api/src/server/folder-metadata-plugin.ts
21996
- import { realpathSync as realpathSync2 } from "node:fs";
21997
- import { readdir as readdir6, readFile as readFile10, realpath as realpath7, stat as stat9 } from "node:fs/promises";
21997
+ import { realpathSync as realpathSync3 } from "node:fs";
21998
+ import { readdir as readdir7, readFile as readFile11, realpath as realpath8, stat as stat11 } from "node:fs/promises";
21998
21999
  import { homedir as homedir4 } from "node:os";
21999
22000
  import {
22000
- basename as basename7,
22001
- dirname as dirname10,
22001
+ basename as basename8,
22002
+ dirname as dirname13,
22002
22003
  extname as extname6,
22003
22004
  isAbsolute as isAbsolute7,
22004
- relative as relative11,
22005
- resolve as resolve12,
22006
- sep as sep8
22005
+ relative as relative12,
22006
+ resolve as resolve15,
22007
+ sep as sep10
22007
22008
  } from "node:path";
22008
22009
 
22009
22010
  // node_modules/.bun/@raggle-ai+barkdown@0.7.1+22117d1132b05fb8/node_modules/@raggle-ai/barkdown/dist/react.js
@@ -36708,7 +36709,11 @@ var run = promisify(execFile);
36708
36709
  var REPOSITORY_ID_KEY = "kennel.repoId";
36709
36710
  var UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/u;
36710
36711
  var markdownExtensions = new Set([".md", ".markdown"]);
36711
- var caseInsensitiveHosts = new Set(["github.com", "gitlab.com", "bitbucket.org"]);
36712
+ var caseInsensitiveHosts = new Set([
36713
+ "github.com",
36714
+ "gitlab.com",
36715
+ "bitbucket.org"
36716
+ ]);
36712
36717
  class RepositoryNotesError extends Error {
36713
36718
  code;
36714
36719
  constructor(code, message) {
@@ -36789,7 +36794,12 @@ async function resolveCheckout(folder) {
36789
36794
  }
36790
36795
  let output;
36791
36796
  try {
36792
- output = await git(["rev-parse", "--path-format=absolute", "--show-toplevel", "--git-common-dir"], start);
36797
+ output = await git([
36798
+ "rev-parse",
36799
+ "--path-format=absolute",
36800
+ "--show-toplevel",
36801
+ "--git-common-dir"
36802
+ ], start);
36793
36803
  } catch (error) {
36794
36804
  if (gitExitCode(error) === 128) {
36795
36805
  throw new RepositoryNotesError("not-git", `Not a Git repository: ${start}. Repository notes need a Git checkout.`);
@@ -37388,19 +37398,457 @@ async function workspaceBreadcrumbIcons(breadcrumbs, assetFiles, assets = {}) {
37388
37398
 
37389
37399
  // packages/api/src/server/plugins.ts
37390
37400
  import { pathToFileURL } from "node:url";
37391
- import { existsSync as existsSync3 } from "node:fs";
37392
- import { mkdir as mkdir3, readFile as readFile9, stat as stat8, writeFile as writeFile5 } from "node:fs/promises";
37393
- import { dirname as dirname8, resolve as resolve11, sep as sep7 } from "node:path";
37401
+ import { existsSync as existsSync4 } from "node:fs";
37402
+ import { mkdir as mkdir3, readFile as readFile10, stat as stat10, writeFile as writeFile5 } from "node:fs/promises";
37403
+ import { dirname as dirname11, resolve as resolve14, sep as sep9 } from "node:path";
37404
+
37405
+ // packages/knl/src/server.ts
37406
+ import { stat as stat8 } from "node:fs/promises";
37407
+ import { join as join5 } from "node:path";
37408
+
37409
+ // packages/knl/src/knl.ts
37410
+ import { readdir as readdir5, stat as stat7 } from "node:fs/promises";
37411
+ import { basename as basename6, dirname as dirname10, relative as relative9, resolve as resolve12, sep as sep7 } from "node:path";
37412
+ import * as esbuild from "esbuild";
37413
+
37414
+ // packages/knl/src/folder-guard.ts
37415
+ import { existsSync as existsSync3, realpathSync as realpathSync2 } from "node:fs";
37416
+ import { realpath as realpath6 } from "node:fs/promises";
37417
+ import { dirname as dirname8, resolve as resolve10, sep as sep6 } from "node:path";
37418
+ import { fileURLToPath } from "node:url";
37419
+ var knlHostResolveDir = dirname8(fileURLToPath(import.meta.url));
37420
+ var knlHostPackageFolders = (() => {
37421
+ const folders = [];
37422
+ let current = knlHostResolveDir;
37423
+ while (true) {
37424
+ const nodeModules = resolve10(current, "node_modules");
37425
+ if (existsSync3(nodeModules))
37426
+ folders.push(nodeModules);
37427
+ const parent = dirname8(current);
37428
+ if (parent === current)
37429
+ return folders;
37430
+ current = parent;
37431
+ }
37432
+ })();
37433
+ async function knlRealRoot(owner) {
37434
+ const expected = resolve10(await realpath6(owner), "knl");
37435
+ const real = await realpath6(resolve10(owner, "knl"));
37436
+ if (real !== expected)
37437
+ throw new Error("knl/ must be a folder, not a link to another place.");
37438
+ return real;
37439
+ }
37440
+ async function knlReadRoots(owner) {
37441
+ const packages = await Promise.all(knlHostPackageFolders.map((folder) => realpath6(folder).catch(() => {
37442
+ return;
37443
+ })));
37444
+ return [
37445
+ await knlRealRoot(owner),
37446
+ ...packages.filter((folder) => Boolean(folder))
37447
+ ];
37448
+ }
37449
+ function isKnlReadable(file, roots) {
37450
+ let real;
37451
+ try {
37452
+ real = realpathSync2(file);
37453
+ } catch {
37454
+ real = resolve10(file);
37455
+ }
37456
+ return roots.some((root) => real === root || real.startsWith(`${root}${sep6}`));
37457
+ }
37458
+ function knlReadError(file) {
37459
+ return `KNL pages can only use files in knl/ and installed packages: ${file}`;
37460
+ }
37461
+ function assertKnlReadable(file, roots) {
37462
+ if (!isKnlReadable(file, roots))
37463
+ throw new Error(knlReadError(file));
37464
+ }
37465
+
37466
+ // packages/knl/src/tailwind.ts
37467
+ import { readFile as readFile9 } from "node:fs/promises";
37468
+ import { createRequire as createRequire2 } from "node:module";
37469
+ import { dirname as dirname9, resolve as resolve11 } from "node:path";
37470
+ import { compile } from "@tailwindcss/node";
37471
+ import { Scanner } from "@tailwindcss/oxide";
37472
+ var require2 = createRequire2(import.meta.url);
37473
+ function starterKnlStyles() {
37474
+ return `@layer theme, utilities;
37475
+ @import "tailwindcss/theme.css" layer(theme) prefix(knl);
37476
+ @import "tailwindcss/utilities.css" layer(utilities) source(none);
37477
+
37478
+ @theme {
37479
+ --font-sans: system-ui, sans-serif;
37480
+ }
37481
+ `;
37482
+ }
37483
+ async function compileKnlCss(js, stylesheet, roots) {
37484
+ const base = dirname9(stylesheet);
37485
+ assertKnlReadable(stylesheet, roots);
37486
+ const css = await readFile9(stylesheet, "utf8").catch((error) => {
37487
+ if (error.code === "ENOENT")
37488
+ return starterKnlStyles();
37489
+ throw error;
37490
+ });
37491
+ const compiler = await compile(css, {
37492
+ base,
37493
+ from: stylesheet,
37494
+ onDependency: (path) => assertKnlReadable(path, roots),
37495
+ customJsResolver: async (id) => {
37496
+ throw new Error(`KNL does not load Tailwind plugins or configs (${id}).`);
37497
+ },
37498
+ customCssResolver: async (id) => id === "tailwindcss" || id.startsWith("tailwindcss/") ? require2.resolve(id) : undefined
37499
+ });
37500
+ const sources = [...compiler.sources];
37501
+ if (compiler.root !== "none") {
37502
+ sources.push({
37503
+ ...compiler.root ?? { base, pattern: "**/*" },
37504
+ negated: false
37505
+ });
37506
+ }
37507
+ for (const source of sources) {
37508
+ if (source.negated)
37509
+ continue;
37510
+ const fixed = source.pattern.split("/");
37511
+ const glob = fixed.findIndex((part) => /[*?[{]/.test(part));
37512
+ assertKnlReadable(resolve11(source.base, fixed.slice(0, glob < 0 ? undefined : glob).join("/")), roots);
37513
+ }
37514
+ const scanner = new Scanner({ sources });
37515
+ const candidates = [
37516
+ ...scanner.scan(),
37517
+ ...scanner.scanFiles([{ content: js, extension: "js" }])
37518
+ ];
37519
+ return compiler.build(candidates);
37520
+ }
37521
+
37522
+ // packages/knl/src/knl.ts
37523
+ var KNK_FOLDER = "knl";
37524
+ var MAX_SOURCE_BYTES = 512 * 1024;
37525
+ var MAX_JS_BYTES = 5 * 1024 * 1024;
37526
+ var MODULE_FILES = ["index.tsx", "index.ts"];
37527
+ function sourceFor(file, knlRoot, scanRoot, owner) {
37528
+ const id = toModuleId(file, knlRoot);
37529
+ return {
37530
+ id,
37531
+ file,
37532
+ relative: relative9(scanRoot, file).split(sep7).join("/"),
37533
+ folder: dirname10(file),
37534
+ owner
37535
+ };
37536
+ }
37537
+ function toModuleId(file, knlRoot) {
37538
+ const relativeKnl = relative9(knlRoot, file).split(sep7).join("/");
37539
+ return relativeKnl.replace(/\/?index\.(tsx|ts)$/, "") || "index";
37540
+ }
37541
+ async function collectKnlSources(scanRoot, owner) {
37542
+ const knlRoot = resolve12(scanRoot, KNK_FOLDER);
37543
+ const knlEntries = await readdir5(knlRoot, { withFileTypes: true }).catch(() => []);
37544
+ const sources = [];
37545
+ const addModule = async (folder) => {
37546
+ for (const candidate of MODULE_FILES) {
37547
+ const file = resolve12(folder, candidate);
37548
+ if (await stat7(file).then((d) => d.isFile()).catch(() => false)) {
37549
+ sources.push(sourceFor(file, knlRoot, scanRoot, owner));
37550
+ return;
37551
+ }
37552
+ }
37553
+ };
37554
+ await addModule(knlRoot);
37555
+ for (const entry of knlEntries) {
37556
+ if (!entry.isDirectory())
37557
+ continue;
37558
+ if (entry.name.startsWith(".") || entry.name === "node_modules")
37559
+ continue;
37560
+ await addModule(resolve12(knlRoot, entry.name));
37561
+ }
37562
+ return sources.sort((left, right) => {
37563
+ const rank = (left.id === "index" ? 0 : 1) - (right.id === "index" ? 0 : 1);
37564
+ return rank !== 0 ? rank : left.id.localeCompare(right.id);
37565
+ });
37566
+ }
37567
+ async function loadKnlSources(viewRoot, linkedFolders = []) {
37568
+ const sources = [
37569
+ ...await collectKnlSources(viewRoot, viewRoot),
37570
+ ...(await Promise.all(linkedFolders.map(async (folder) => (await collectKnlSources(folder, folder)).map((source) => ({
37571
+ ...source,
37572
+ id: `${basename6(folder)}:${source.id}`,
37573
+ relative: `${basename6(folder)}/${source.relative}`
37574
+ }))))).flat()
37575
+ ];
37576
+ return { sources };
37577
+ }
37578
+ var MAX_CACHED_MODULES = 200;
37579
+ var compileCache = new Map;
37580
+ function knlNodePaths(knlRoot) {
37581
+ return [resolve12(knlRoot, "node_modules"), ...knlHostPackageFolders];
37582
+ }
37583
+ async function compileKnlSource(source) {
37584
+ const sourceBytes = (await stat7(source.file)).size;
37585
+ const tooLarge = (bytes, what) => ({
37586
+ id: source.id,
37587
+ relative: source.relative,
37588
+ js: "",
37589
+ css: "",
37590
+ issues: [
37591
+ {
37592
+ path: source.relative,
37593
+ message: `Module ${what} is too large (${bytes} bytes; limit ${MAX_SOURCE_BYTES}).`
37594
+ }
37595
+ ]
37596
+ });
37597
+ if (sourceBytes > MAX_SOURCE_BYTES)
37598
+ return tooLarge(sourceBytes, "source");
37599
+ const cached = compileCache.get(source.file);
37600
+ const unchanged = cached && (await Promise.all(cached.dependencies.map(async ({ file, mtimeMs }) => (await stat7(file).catch(() => {
37601
+ return;
37602
+ }))?.mtimeMs === mtimeMs))).every(Boolean);
37603
+ const knlRoot = resolve12(source.owner, KNK_FOLDER);
37604
+ let issuePath = source.relative;
37605
+ try {
37606
+ const nodePaths = knlNodePaths(knlRoot);
37607
+ const roots = await knlReadRoots(source.owner);
37608
+ assertKnlReadable(source.file, roots);
37609
+ let js;
37610
+ if (cached && unchanged) {
37611
+ js = cached.js;
37612
+ } else {
37613
+ const result = await esbuild.build({
37614
+ absWorkingDir: source.folder,
37615
+ stdin: {
37616
+ contents: `import { createElement } from "react"
37617
+ import { createRoot } from "react-dom/client"
37618
+ import Component from ${JSON.stringify(source.file)}
37619
+
37620
+ globalThis.__knlMount = (container, context, onError) => {
37621
+ const root = createRoot(container, { onUncaughtError: onError })
37622
+ root.render(createElement(Component, context))
37623
+ }
37624
+ `,
37625
+ sourcefile: `${source.file}.mount.ts`,
37626
+ loader: "ts",
37627
+ resolveDir: source.folder
37628
+ },
37629
+ bundle: true,
37630
+ format: "iife",
37631
+ target: "es2022",
37632
+ jsx: "automatic",
37633
+ platform: "browser",
37634
+ write: false,
37635
+ minify: false,
37636
+ sourcemap: false,
37637
+ logLevel: "silent",
37638
+ metafile: true,
37639
+ nodePaths,
37640
+ plugins: [readGuard(roots)]
37641
+ });
37642
+ js = result.outputFiles?.[0]?.text ?? "";
37643
+ const files = new Set([
37644
+ resolve12(knlRoot, "package.json"),
37645
+ ...Object.keys(result.metafile.inputs).map((file) => resolve12(source.folder, file)).filter((file) => file !== `${source.file}.mount.ts`)
37646
+ ]);
37647
+ const dependencies = await Promise.all([...files].map(async (file) => ({
37648
+ file,
37649
+ mtimeMs: (await stat7(file).catch(() => {
37650
+ return;
37651
+ }))?.mtimeMs
37652
+ })));
37653
+ compileCache.delete(source.file);
37654
+ compileCache.set(source.file, { js, dependencies });
37655
+ if (compileCache.size > MAX_CACHED_MODULES)
37656
+ compileCache.delete(compileCache.keys().next().value);
37657
+ }
37658
+ const stylesheet = resolve12(knlRoot, "style.css");
37659
+ issuePath = relative9(source.owner, stylesheet).split(sep7).join("/");
37660
+ const css = await compileKnlCss(js, stylesheet, roots);
37661
+ issuePath = source.relative;
37662
+ if (js.length + css.length > MAX_JS_BYTES) {
37663
+ return {
37664
+ id: source.id,
37665
+ relative: source.relative,
37666
+ js: "",
37667
+ css: "",
37668
+ issues: [
37669
+ {
37670
+ path: source.relative,
37671
+ message: `Compiled module is too large (${js.length + css.length} bytes; limit ${MAX_JS_BYTES}).`
37672
+ }
37673
+ ]
37674
+ };
37675
+ }
37676
+ return { id: source.id, relative: source.relative, js, css, issues: [] };
37677
+ } catch (error) {
37678
+ return {
37679
+ id: source.id,
37680
+ relative: source.relative,
37681
+ js: "",
37682
+ css: "",
37683
+ issues: knlBuildIssues(error, issuePath, source)
37684
+ };
37685
+ }
37686
+ }
37687
+ var guardResolve = Symbol("knl-guard");
37688
+ function readGuard(roots) {
37689
+ return {
37690
+ name: "knl-read-guard",
37691
+ setup(build) {
37692
+ build.onResolve({ filter: /.*/ }, async (args) => {
37693
+ if (args.pluginData === guardResolve)
37694
+ return;
37695
+ const resolveFrom = (resolveDir) => build.resolve(args.path, {
37696
+ importer: args.importer,
37697
+ kind: args.kind,
37698
+ pluginData: guardResolve,
37699
+ resolveDir
37700
+ });
37701
+ const readable = (result) => result.namespace !== "file" || !result.path || isKnlReadable(result.path, roots);
37702
+ let result = await resolveFrom(args.resolveDir);
37703
+ const bare = !/^(?:\.{1,2}(?:\/|$)|\/)/.test(args.path);
37704
+ if (bare && result.errors.length === 0 && !readable(result))
37705
+ result = await resolveFrom(knlHostResolveDir);
37706
+ if (result.errors.length > 0)
37707
+ return { errors: result.errors };
37708
+ if (!readable(result))
37709
+ return { errors: [{ text: knlReadError(args.path) }] };
37710
+ return result;
37711
+ });
37712
+ }
37713
+ };
37714
+ }
37715
+ function knlBuildIssues(error, relativePath, source) {
37716
+ const failures = error?.errors;
37717
+ if (Array.isArray(failures) && failures.length > 0) {
37718
+ const first = failures[0];
37719
+ const file = first?.location?.file ? relative9(source.owner, resolve12(source.folder, first.location.file)).split(sep7).join("/") : relativePath;
37720
+ const location = first?.location ? `${file}:${first.location.line ?? "?"}` : relativePath;
37721
+ return [
37722
+ { path: location, message: first?.text ?? "Module failed to compile." }
37723
+ ];
37724
+ }
37725
+ return [
37726
+ {
37727
+ path: relativePath,
37728
+ message: error instanceof Error && error.message ? error.message : "Module failed to compile."
37729
+ }
37730
+ ];
37731
+ }
37732
+ function starterKnlSource() {
37733
+ return `// knl/index.tsx — this folder's homepage (KNL folder web framework).
37734
+ // Every other page lives in its own folder: knl/<page>/index.tsx.
37735
+ import * as React from "react"
37736
+
37737
+ export default function Home() {
37738
+ return (
37739
+ <div className="knl:p-4 knl:font-sans">
37740
+ <h1 className="knl:m-0 knl:text-2xl">Home</h1>
37741
+ <p>Edit this file to build the homepage.</p>
37742
+ </div>
37743
+ )
37744
+ }
37745
+ `;
37746
+ }
37747
+
37748
+ // packages/knl/src/manifest.ts
37749
+ var knlManifest = {
37750
+ id: "knl",
37751
+ label: "KNL"
37752
+ };
37753
+
37754
+ // packages/knl/src/server.ts
37755
+ function createKnlPlugin() {
37756
+ return {
37757
+ ...knlManifest,
37758
+ async detect(context) {
37759
+ const hasKnlFolder = await stat8(join5(context.folder, KNK_FOLDER)).then((entry) => entry.isDirectory()).catch(() => false);
37760
+ if (!hasKnlFolder)
37761
+ return { status: "unavailable" };
37762
+ const { sources } = await loadKnlSources(context.folder, context.linkedFolders ?? []);
37763
+ if (!sources.some((source) => source.id === "index"))
37764
+ return { status: "unavailable" };
37765
+ return {
37766
+ count: sources.length,
37767
+ pages: sources.filter((source) => source.id !== "index" && !source.id.endsWith(":index")).map((source) => ({
37768
+ id: source.id,
37769
+ label: source.id.replaceAll(/[-_]/g, " ").replace(/^./, (letter) => letter.toUpperCase())
37770
+ })),
37771
+ status: "available"
37772
+ };
37773
+ },
37774
+ async handle(context, subpath) {
37775
+ const { sources } = await loadKnlSources(context.folder, context.linkedFolders ?? []);
37776
+ const folder = context.folder;
37777
+ if (sources.length === 0) {
37778
+ return { kind: "available", data: { folder, status: "unavailable" } };
37779
+ }
37780
+ const requested = subpath.trim() || "index";
37781
+ const selected = sources.filter((source) => source.id === requested);
37782
+ if (selected.length === 0) {
37783
+ return {
37784
+ kind: "available",
37785
+ data: {
37786
+ folder,
37787
+ status: "error",
37788
+ message: `KNL page not found: ${requested}`
37789
+ }
37790
+ };
37791
+ }
37792
+ const compiled = await Promise.all(selected.map(compileKnlSource));
37793
+ const entries = compiled.map((result) => {
37794
+ const source = sources.find((item) => item.id === result.id);
37795
+ return {
37796
+ id: result.id,
37797
+ relative: result.relative,
37798
+ ...result.js ? { js: result.js } : {},
37799
+ css: result.css,
37800
+ ...result.issues.length > 0 ? { issues: result.issues } : {},
37801
+ owner: source?.owner ?? folder
37802
+ };
37803
+ });
37804
+ const failing = entries.filter((entry) => entry.issues?.length);
37805
+ if (failing.length > 0) {
37806
+ return {
37807
+ kind: "available",
37808
+ data: {
37809
+ folder,
37810
+ status: "error",
37811
+ entries,
37812
+ issues: failing[0]?.issues
37813
+ }
37814
+ };
37815
+ }
37816
+ return {
37817
+ kind: "available",
37818
+ data: {
37819
+ folder,
37820
+ status: "available",
37821
+ entries
37822
+ }
37823
+ };
37824
+ },
37825
+ async init() {
37826
+ return {
37827
+ files: [
37828
+ { path: "knl/index.tsx", content: starterKnlSource() },
37829
+ { path: "knl/style.css", content: starterKnlStyles() },
37830
+ {
37831
+ path: "knl/package.json",
37832
+ content: `${JSON.stringify({ private: true, type: "module" }, null, 2)}
37833
+ `
37834
+ },
37835
+ { path: "knl/.gitignore", content: `node_modules/
37836
+ ` }
37837
+ ]
37838
+ };
37839
+ }
37840
+ };
37841
+ }
37394
37842
 
37395
37843
  // packages/notes/src/server.ts
37396
- import { readdir as readdir5, realpath as realpath6, stat as stat7 } from "node:fs/promises";
37844
+ import { readdir as readdir6, realpath as realpath7, stat as stat9 } from "node:fs/promises";
37397
37845
  import {
37398
- basename as basename6,
37846
+ basename as basename7,
37399
37847
  extname as extname5,
37400
37848
  isAbsolute as isAbsolute6,
37401
- relative as relative9,
37402
- resolve as resolve10,
37403
- sep as sep6
37849
+ relative as relative10,
37850
+ resolve as resolve13,
37851
+ sep as sep8
37404
37852
  } from "node:path";
37405
37853
 
37406
37854
  // packages/notes/src/manifest.ts
@@ -37422,11 +37870,11 @@ var llmNoteLimit = 20;
37422
37870
  async function listMarkdownFiles(folder) {
37423
37871
  const files = [];
37424
37872
  const visit = async (current) => {
37425
- const entries = await readdir5(current, { withFileTypes: true }).catch(() => []);
37873
+ const entries = await readdir6(current, { withFileTypes: true }).catch(() => []);
37426
37874
  for (const entry of entries) {
37427
37875
  if (entry.name === "node_modules" || entry.name.startsWith("."))
37428
37876
  continue;
37429
- const path = resolve10(current, entry.name);
37877
+ const path = resolve13(current, entry.name);
37430
37878
  if (entry.isDirectory()) {
37431
37879
  await visit(path);
37432
37880
  continue;
@@ -37434,22 +37882,22 @@ async function listMarkdownFiles(folder) {
37434
37882
  if (!entry.isFile() || !markdownExtensions2.has(extname5(entry.name))) {
37435
37883
  continue;
37436
37884
  }
37437
- const details = await stat7(path).catch(() => {
37885
+ const details = await stat9(path).catch(() => {
37438
37886
  return;
37439
37887
  });
37440
37888
  files.push({
37441
37889
  activityAt: details?.mtimeMs ?? 0,
37442
- name: basename6(entry.name, extname5(entry.name)),
37443
- relativePath: relative9(folder, path).split(sep6).join("/")
37890
+ name: basename7(entry.name, extname5(entry.name)),
37891
+ relativePath: relative10(folder, path).split(sep8).join("/")
37444
37892
  });
37445
37893
  }
37446
37894
  };
37447
37895
  await visit(folder);
37448
37896
  return files.sort((left, right) => right.activityAt - left.activityAt);
37449
37897
  }
37450
- var canonical = (path) => realpath6(path).catch(() => path);
37898
+ var canonical = (path) => realpath7(path).catch(() => path);
37451
37899
  function inside5(path, root) {
37452
- const local = relative9(root, path);
37900
+ const local = relative10(root, path);
37453
37901
  return local === "" || !local.startsWith("..") && !isAbsolute6(local);
37454
37902
  }
37455
37903
  async function withoutManaged(groups, managedRoots) {
@@ -37461,7 +37909,7 @@ async function withoutManaged(groups, managedRoots) {
37461
37909
  return { ...group, files: [] };
37462
37910
  }
37463
37911
  const files = await Promise.all(group.files.map(async (file) => {
37464
- const real = await canonical(resolve10(group.folder, file.relativePath));
37912
+ const real = await canonical(resolve13(group.folder, file.relativePath));
37465
37913
  return roots.some((root) => inside5(real, root)) ? undefined : file;
37466
37914
  }));
37467
37915
  return { ...group, files: files.filter((file) => file !== undefined) };
@@ -37511,7 +37959,7 @@ async function notesLlmSections({
37511
37959
  continue;
37512
37960
  seen.add(identity);
37513
37961
  const files = await listMarkdownFiles(source);
37514
- const paths = files.map((file) => resolve10(source, file.relativePath));
37962
+ const paths = files.map((file) => resolve13(source, file.relativePath));
37515
37963
  groups.push({ folder: source, paths });
37516
37964
  files.forEach((file, index) => notes.push({ activityAt: file.activityAt, path: paths[index] }));
37517
37965
  }
@@ -37583,14 +38031,14 @@ function parsePluginRegistryConfig(content) {
37583
38031
  };
37584
38032
  }
37585
38033
  async function nearestKennelConfig(folder) {
37586
- for (let current = folder;; current = dirname8(current)) {
37587
- const candidate = resolve11(current, "kennel.json");
37588
- const details = await stat8(candidate).catch(() => {
38034
+ for (let current = folder;; current = dirname11(current)) {
38035
+ const candidate = resolve14(current, "kennel.json");
38036
+ const details = await stat10(candidate).catch(() => {
37589
38037
  return;
37590
38038
  });
37591
38039
  if (details?.isFile())
37592
38040
  return candidate;
37593
- if (dirname8(current) === current)
38041
+ if (dirname11(current) === current)
37594
38042
  return;
37595
38043
  }
37596
38044
  }
@@ -37599,13 +38047,13 @@ async function folderPluginRegistryConfig(folder) {
37599
38047
  if (!path)
37600
38048
  return defaultPluginRegistryConfig;
37601
38049
  try {
37602
- return parsePluginRegistryConfig(await readFile9(path, "utf8"));
38050
+ return parsePluginRegistryConfig(await readFile10(path, "utf8"));
37603
38051
  } catch {
37604
38052
  return defaultPluginRegistryConfig;
37605
38053
  }
37606
38054
  }
37607
38055
  function createFolderServerPlugins() {
37608
- return [createNotesPlugin()];
38056
+ return [createNotesPlugin(), createKnlPlugin()];
37609
38057
  }
37610
38058
  function folderServerRegistry() {
37611
38059
  return new Map(createFolderServerPlugins().map((plugin) => [plugin.id, plugin]));
@@ -37647,7 +38095,7 @@ async function folderServerRegistryAsync() {
37647
38095
  ...server,
37648
38096
  async detect(context) {
37649
38097
  const detection = await server.detect(context);
37650
- if (detection.status === "unavailable" && existsSync3(resolve11(context.folder, entry.trigger))) {
38098
+ if (detection.status === "unavailable" && existsSync4(resolve14(context.folder, entry.trigger))) {
37651
38099
  return { status: "available" };
37652
38100
  }
37653
38101
  return detection;
@@ -37690,10 +38138,10 @@ import { execFile as execFile4 } from "node:child_process";
37690
38138
 
37691
38139
  // packages/api/src/server/linked-folder-discovery.ts
37692
38140
  import { execFile as execFile3 } from "node:child_process";
37693
- import { existsSync as existsSync4 } from "node:fs";
37694
- import { createRequire as createRequire2 } from "node:module";
37695
- import { dirname as dirname9, join as join5 } from "node:path";
37696
- import { fileURLToPath } from "node:url";
38141
+ import { existsSync as existsSync5 } from "node:fs";
38142
+ import { createRequire as createRequire3 } from "node:module";
38143
+ import { dirname as dirname12, join as join6 } from "node:path";
38144
+ import { fileURLToPath as fileURLToPath2 } from "node:url";
37697
38145
  var script = `
37698
38146
  const local = require(process.argv[1]);
37699
38147
  const { stat } = require('node:fs/promises');
@@ -37710,24 +38158,24 @@ const { stat } = require('node:fs/promises');
37710
38158
  })().catch(error => { console.error(error); process.exitCode = 1; });
37711
38159
  `;
37712
38160
  function resolveLocalModule(from = import.meta.url) {
37713
- const require2 = createRequire2(from);
38161
+ const require2 = createRequire3(from);
37714
38162
  const candidates = [];
37715
38163
  try {
37716
38164
  candidates.push(require2.resolve("@raggle-ai/local"));
37717
38165
  } catch {}
37718
- let directory = dirname9(fileURLToPath(from));
37719
- while (dirname9(directory) !== directory) {
37720
- if (existsSync4(join5(directory, "raggle.json"))) {
38166
+ let directory = dirname12(fileURLToPath2(from));
38167
+ while (dirname12(directory) !== directory) {
38168
+ if (existsSync5(join6(directory, "raggle.json"))) {
37721
38169
  for (const candidate of [
37722
- join5(dirname9(directory), "raggle-ai-scout", "packages", "local"),
37723
- join5(directory, "..", "..", "raggle-ai-scout", "packages", "local")
38170
+ join6(dirname12(directory), "raggle-ai-scout", "packages", "local"),
38171
+ join6(directory, "..", "..", "raggle-ai-scout", "packages", "local")
37724
38172
  ]) {
37725
38173
  if (!candidates.includes(candidate))
37726
38174
  candidates.push(candidate);
37727
38175
  }
37728
38176
  break;
37729
38177
  }
37730
- directory = dirname9(directory);
38178
+ directory = dirname12(directory);
37731
38179
  }
37732
38180
  for (const candidate of candidates) {
37733
38181
  try {
@@ -37736,7 +38184,7 @@ function resolveLocalModule(from = import.meta.url) {
37736
38184
  return candidate;
37737
38185
  } catch {}
37738
38186
  }
37739
- return candidates[0] ?? join5(dirname9(fileURLToPath(from)), "..", "..", "..", "raggle-ai-scout", "packages", "local");
38187
+ return candidates[0] ?? join6(dirname12(fileURLToPath2(from)), "..", "..", "..", "raggle-ai-scout", "packages", "local");
37740
38188
  }
37741
38189
  function discoverLinkedFolders(folder, signal, modulePath = resolveLocalModule()) {
37742
38190
  return new Promise((resolve, reject) => {
@@ -38088,10 +38536,10 @@ var metadataExtensions = new Set([
38088
38536
  ".txt"
38089
38537
  ]);
38090
38538
  function metadataFile(path, root) {
38091
- const candidate = relative11(root, path);
38539
+ const candidate = relative12(root, path);
38092
38540
  if (!candidate || candidate.startsWith("..") || isAbsolute7(candidate))
38093
38541
  return false;
38094
- const parts = candidate.split(sep8);
38542
+ const parts = candidate.split(sep10);
38095
38543
  if (parts.some((part) => part === "node_modules"))
38096
38544
  return false;
38097
38545
  return metadataExtensions.has(extname6(candidate).toLowerCase());
@@ -38102,10 +38550,10 @@ async function configuredAiInputModule(folder) {
38102
38550
  return typeof module === "string" && module.trim() ? module.trim() : null;
38103
38551
  }
38104
38552
  function folderPath(value, root, lockedRoot) {
38105
- const folder = realpathSync2(resolve12(value ?? root));
38553
+ const folder = realpathSync3(resolve15(value ?? root));
38106
38554
  if (!lockedRoot)
38107
38555
  return folder;
38108
- const path = relative11(lockedRoot, folder);
38556
+ const path = relative12(lockedRoot, folder);
38109
38557
  if (!path || !path.startsWith("..") && !isAbsolute7(path))
38110
38558
  return folder;
38111
38559
  throw new Error(`Folder is outside the viewer root: ${folder}`);
@@ -38177,15 +38625,15 @@ function unique(values) {
38177
38625
  return [...new Set(values)];
38178
38626
  }
38179
38627
  function isMachineRoot(folder) {
38180
- return folder === homedir4() || dirname10(folder) === folder;
38628
+ return folder === homedir4() || dirname13(folder) === folder;
38181
38629
  }
38182
38630
  async function shallowMetadata(folder) {
38183
- const entries = await readdir6(folder, { withFileTypes: true });
38631
+ const entries = await readdir7(folder, { withFileTypes: true });
38184
38632
  const visible = entries.filter((entry) => !entry.name.startsWith(".") && entry.name !== "node_modules");
38185
38633
  const files = await Promise.all(visible.filter((entry) => entry.isFile() && [".markdown", ".md"].includes(extname6(entry.name).toLowerCase())).map(async (entry) => {
38186
- const path = resolve12(folder, entry.name);
38187
- const details = await stat9(path);
38188
- const content = await readFile10(path, "utf8").catch(() => "");
38634
+ const path = resolve15(folder, entry.name);
38635
+ const details = await stat11(path);
38636
+ const content = await readFile11(path, "utf8").catch(() => "");
38189
38637
  const title = markdownMetadata(content).title;
38190
38638
  return {
38191
38639
  activityAt: details.mtimeMs,
@@ -38198,10 +38646,10 @@ async function shallowMetadata(folder) {
38198
38646
  };
38199
38647
  }));
38200
38648
  const projects = visible.filter((entry) => entry.isDirectory()).map((entry) => ({
38201
- id: createHash5("sha1").update(resolve12(folder, entry.name)).digest("hex"),
38649
+ id: createHash5("sha1").update(resolve15(folder, entry.name)).digest("hex"),
38202
38650
  name: entry.name,
38203
38651
  relativePath: entry.name,
38204
- worktree: resolve12(folder, entry.name)
38652
+ worktree: resolve15(folder, entry.name)
38205
38653
  })).sort((left, right) => left.name.localeCompare(right.name));
38206
38654
  return {
38207
38655
  changes: { items: [] },
@@ -38227,8 +38675,8 @@ async function loadFolderData(folder) {
38227
38675
  items: projects.map((project) => ({
38228
38676
  id: project.id,
38229
38677
  worktree: project.worktree,
38230
- name: project.name ?? basename7(project.worktree),
38231
- relativePath: relative11(folder, project.worktree)
38678
+ name: project.name ?? basename8(project.worktree),
38679
+ relativePath: relative12(folder, project.worktree)
38232
38680
  }))
38233
38681
  }
38234
38682
  };
@@ -38236,10 +38684,10 @@ async function loadFolderData(folder) {
38236
38684
  async function notesFiles(folder, files, origin) {
38237
38685
  return {
38238
38686
  items: await Promise.all(files.map(async (file) => {
38239
- const path = file.path ?? (file.relativePath ? resolve12(folder, file.relativePath) : undefined);
38687
+ const path = file.path ?? (file.relativePath ? resolve15(folder, file.relativePath) : undefined);
38240
38688
  if (!path)
38241
38689
  return origin ? { ...file, folder: origin } : file;
38242
- const content = [".markdown", ".md"].includes(extname6(path).toLowerCase()) ? await readFile10(path, "utf8").catch(() => "") : "";
38690
+ const content = [".markdown", ".md"].includes(extname6(path).toLowerCase()) ? await readFile11(path, "utf8").catch(() => "") : "";
38243
38691
  const title = content ? markdownMetadata(content).title : undefined;
38244
38692
  return {
38245
38693
  ...file,
@@ -38253,7 +38701,7 @@ async function notesFiles(folder, files, origin) {
38253
38701
  async function managedNotesFiles(directory) {
38254
38702
  const notes = await listManagedNotes(directory);
38255
38703
  return Promise.all(notes.map(async (note) => {
38256
- const content = await readFile10(note.path, "utf8").catch(() => "");
38704
+ const content = await readFile11(note.path, "utf8").catch(() => "");
38257
38705
  const title = content ? markdownMetadata(content).title : undefined;
38258
38706
  return {
38259
38707
  ...note,
@@ -38263,9 +38711,9 @@ async function managedNotesFiles(directory) {
38263
38711
  };
38264
38712
  }));
38265
38713
  }
38266
- var canonicalPath = (path) => realpath7(path).catch(() => path);
38714
+ var canonicalPath = (path) => realpath8(path).catch(() => path);
38267
38715
  function insideFolder(path, root) {
38268
- const local = relative11(root, path);
38716
+ const local = relative12(root, path);
38269
38717
  return local === "" || !local.startsWith("..") && !isAbsolute7(local);
38270
38718
  }
38271
38719
  async function withoutManagedFiles(items, managedRoot) {
@@ -38297,15 +38745,15 @@ async function localProjectSearchCache(cache) {
38297
38745
  function mediaTarget(folder, file, lockedTarget) {
38298
38746
  if (!file)
38299
38747
  return;
38300
- const rootReal = realpathSync2(resolve12(folder));
38301
- const path = resolve12(folder, file);
38748
+ const rootReal = realpathSync3(resolve15(folder));
38749
+ const path = resolve15(folder, file);
38302
38750
  let pathReal;
38303
38751
  try {
38304
- pathReal = realpathSync2(path);
38752
+ pathReal = realpathSync3(path);
38305
38753
  } catch {
38306
38754
  return;
38307
38755
  }
38308
- const rel = relative11(rootReal, pathReal);
38756
+ const rel = relative12(rootReal, pathReal);
38309
38757
  if (rel.startsWith("..") || isAbsolute7(rel))
38310
38758
  return;
38311
38759
  if (lockedTarget && pathReal !== lockedTarget)
@@ -38345,15 +38793,15 @@ function documentError(response) {
38345
38793
  function documentTarget(folder, file, lockedTarget) {
38346
38794
  if (!file)
38347
38795
  return;
38348
- const rootReal = realpathSync2(resolve12(folder));
38349
- const path = resolve12(folder, file);
38796
+ const rootReal = realpathSync3(resolve15(folder));
38797
+ const path = resolve15(folder, file);
38350
38798
  let pathReal;
38351
38799
  try {
38352
- pathReal = realpathSync2(path);
38800
+ pathReal = realpathSync3(path);
38353
38801
  } catch {
38354
38802
  return;
38355
38803
  }
38356
- const rel = relative11(rootReal, pathReal);
38804
+ const rel = relative12(rootReal, pathReal);
38357
38805
  if (rel.startsWith("..") || isAbsolute7(rel))
38358
38806
  return;
38359
38807
  if (lockedTarget && pathReal !== lockedTarget)
@@ -38411,7 +38859,8 @@ async function pluginAvailability(registry, folder, linkedFolders, configWarning
38411
38859
  error,
38412
38860
  icon: plugin.icon,
38413
38861
  id: plugin.id,
38414
- label: plugin.label
38862
+ label: plugin.label,
38863
+ ...detection.status === "available" && detection.pages ? { pages: detection.pages } : {}
38415
38864
  });
38416
38865
  }
38417
38866
  } catch {}
@@ -38426,8 +38875,8 @@ function createFolderApi({
38426
38875
  remoteAccess = false,
38427
38876
  lockedFile
38428
38877
  }) {
38429
- let lockedRoot = restrictToRoot ? realpathSync2(root) : undefined;
38430
- const lockedTarget = lockedFile ? realpathSync2(lockedFile) : undefined;
38878
+ let lockedRoot = restrictToRoot ? realpathSync3(root) : undefined;
38879
+ const lockedTarget = lockedFile ? realpathSync3(lockedFile) : undefined;
38431
38880
  let basePlugins;
38432
38881
  let baseExternalApiHandlers;
38433
38882
  const assetFiles = new Map;
@@ -38465,7 +38914,7 @@ function createFolderApi({
38465
38914
  const serverHost = server.host;
38466
38915
  const remote = remoteAccess || serverHost === true || typeof serverHost === "string" && !isLoopbackServerHost(serverHost);
38467
38916
  if (remote)
38468
- lockedRoot = lockedRoot ?? realpathSync2(root);
38917
+ lockedRoot = lockedRoot ?? realpathSync3(root);
38469
38918
  const collectionServer = createSchemaCollectionServer(server, {
38470
38919
  boundary: lockedRoot,
38471
38920
  lockedTarget
@@ -38491,7 +38940,7 @@ function createFolderApi({
38491
38940
  if (!folder)
38492
38941
  return;
38493
38942
  server.emit({
38494
- data: { path: relative11(folder, path) },
38943
+ data: { path: relative12(folder, path) },
38495
38944
  event: "kennel:metadata-changed",
38496
38945
  type: "custom"
38497
38946
  });
@@ -38574,7 +39023,7 @@ function createFolderApi({
38574
39023
  "Content-Type": asset.mediaType,
38575
39024
  ETag: `"${hash}"`
38576
39025
  });
38577
- response.end(await readFile10(asset.path));
39026
+ response.end(await readFile11(asset.path));
38578
39027
  } catch (error) {
38579
39028
  response.writeHead(404, {
38580
39029
  "Content-Type": "text/plain; charset=utf-8"
@@ -38646,14 +39095,14 @@ function createFolderApi({
38646
39095
  }
38647
39096
  if (url.pathname === "/api/documents") {
38648
39097
  const folder = folderPath(url.searchParams.get("path"), root, lockedRoot);
38649
- const target = lockedTarget ? documentTarget(folder, relative11(folder, lockedTarget), lockedTarget) : undefined;
39098
+ const target = lockedTarget ? documentTarget(folder, relative12(folder, lockedTarget), lockedTarget) : undefined;
38650
39099
  const dataset = lockedTarget ? {
38651
39100
  root: folder,
38652
39101
  documents: target ? [
38653
39102
  {
38654
- path: relative11(folder, target.path),
39103
+ path: relative12(folder, target.path),
38655
39104
  kind: target.kind,
38656
- content: previewTextKind(target.kind) ? await readFile10(target.path, "utf8") : ""
39105
+ content: previewTextKind(target.kind) ? await readFile11(target.path, "utf8") : ""
38657
39106
  }
38658
39107
  ] : []
38659
39108
  } : await readFolder(folder);
@@ -38669,7 +39118,7 @@ function createFolderApi({
38669
39118
  documentError(response);
38670
39119
  return;
38671
39120
  }
38672
- const details = await stat9(target.path);
39121
+ const details = await stat11(target.path);
38673
39122
  if (!details.isFile()) {
38674
39123
  documentError(response);
38675
39124
  return;
@@ -38681,16 +39130,16 @@ function createFolderApi({
38681
39130
  return;
38682
39131
  }
38683
39132
  watch(folder);
38684
- const content = previewTextKind(target.kind) ? await readFile10(target.path, "utf8") : "";
39133
+ const content = previewTextKind(target.kind) ? await readFile11(target.path, "utf8") : "";
38685
39134
  sendContract(response, url, {
38686
39135
  content,
38687
39136
  kind: target.kind,
38688
- path: relative11(target.root, target.path),
39137
+ path: relative12(target.root, target.path),
38689
39138
  root: folder,
38690
39139
  ...previewTextKind(target.kind) ? {} : {
38691
39140
  rawUrl: `/api/raw?${new URLSearchParams({
38692
39141
  path: folder,
38693
- file: relative11(target.root, target.path)
39142
+ file: relative12(target.root, target.path)
38694
39143
  })}`
38695
39144
  }
38696
39145
  }, {
@@ -38710,7 +39159,7 @@ function createFolderApi({
38710
39159
  documentError(response);
38711
39160
  return;
38712
39161
  }
38713
- const details = await stat9(target.path);
39162
+ const details = await stat11(target.path);
38714
39163
  if (!details.isFile()) {
38715
39164
  documentError(response);
38716
39165
  return;
@@ -38731,10 +39180,10 @@ function createFolderApi({
38731
39180
  ETag: etag,
38732
39181
  "X-Content-Type-Options": "nosniff",
38733
39182
  ...download ? {
38734
- "Content-Disposition": `attachment; filename="${basename7(target.path)}"`
39183
+ "Content-Disposition": `attachment; filename="${basename8(target.path)}"`
38735
39184
  } : {}
38736
39185
  });
38737
- response.end(await readFile10(target.path));
39186
+ response.end(await readFile11(target.path));
38738
39187
  } catch (error) {
38739
39188
  documentError(response);
38740
39189
  }
@@ -38748,7 +39197,7 @@ function createFolderApi({
38748
39197
  documentError(response);
38749
39198
  return;
38750
39199
  }
38751
- const details = await stat9(target.path);
39200
+ const details = await stat11(target.path);
38752
39201
  if (!details.isFile()) {
38753
39202
  documentError(response);
38754
39203
  return;
@@ -38760,7 +39209,7 @@ function createFolderApi({
38760
39209
  return;
38761
39210
  }
38762
39211
  watch(folder);
38763
- const data = await readFile10(target.path);
39212
+ const data = await readFile11(target.path);
38764
39213
  const baseHeaders = {
38765
39214
  "Accept-Ranges": "bytes",
38766
39215
  "Cache-Control": "private, max-age=0, must-revalidate",
@@ -38923,7 +39372,7 @@ function createFolderApi({
38923
39372
  workspace.breadcrumbs = await workspaceBreadcrumbIcons(workspace.breadcrumbs ?? [], assetFiles);
38924
39373
  const files = [
38925
39374
  workspace.configPath,
38926
- resolve12(workspace.root, "raggle.json")
39375
+ resolve15(workspace.root, "raggle.json")
38927
39376
  ].filter((path) => Boolean(path));
38928
39377
  for (const path of files)
38929
39378
  contexts.add(path);
@@ -39082,26 +39531,26 @@ var contentTypes = {
39082
39531
  ".ttf": "font/ttf"
39083
39532
  };
39084
39533
  async function sendFile(request, response, directory, pathname, fallback) {
39085
- const root = await realpath8(directory);
39534
+ const root = await realpath9(directory);
39086
39535
  const inside = (path) => {
39087
- const local = relative12(root, path);
39536
+ const local = relative13(root, path);
39088
39537
  return local !== ".." && !local.startsWith("../") && !isAbsolute8(local);
39089
39538
  };
39090
- let target = resolve13(root, `.${decodeURIComponent(pathname)}`);
39539
+ let target = resolve16(root, `.${decodeURIComponent(pathname)}`);
39091
39540
  if (!inside(target)) {
39092
39541
  response.writeHead(403);
39093
39542
  response.end();
39094
39543
  return;
39095
39544
  }
39096
- if (!(await stat10(target).catch(() => null))?.isFile()) {
39545
+ if (!(await stat12(target).catch(() => null))?.isFile()) {
39097
39546
  if (!fallback) {
39098
39547
  response.writeHead(404);
39099
39548
  response.end();
39100
39549
  return;
39101
39550
  }
39102
- target = resolve13(root, fallback);
39551
+ target = resolve16(root, fallback);
39103
39552
  }
39104
- target = await realpath8(target);
39553
+ target = await realpath9(target);
39105
39554
  if (!inside(target)) {
39106
39555
  response.writeHead(403);
39107
39556
  response.end();
@@ -39111,7 +39560,7 @@ async function sendFile(request, response, directory, pathname, fallback) {
39111
39560
  "Content-Type": contentTypes[extname7(target)] ?? "application/octet-stream",
39112
39561
  "X-Content-Type-Options": "nosniff"
39113
39562
  });
39114
- response.end(request.method === "HEAD" ? undefined : await readFile11(target));
39563
+ response.end(request.method === "HEAD" ? undefined : await readFile12(target));
39115
39564
  }
39116
39565
  function createKennelApi(options) {
39117
39566
  const remote = options.remoteAccess || !isLoopbackServerHost(options.host);