kennel 0.2.45 → 0.2.46

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 (75) hide show
  1. package/dist/core/api-client.js +34 -1
  2. package/dist/core/runtime.js +189 -129
  3. package/dist/package/preview.js +217 -141
  4. package/package.json +2 -2
  5. package/web/assets/{abnfDiagram-VRR7QNED-D8mHNUwf.js → abnfDiagram-VRR7QNED-BOm3iBSE.js} +1 -1
  6. package/web/assets/{arc-DORR-Lbn.js → arc-D_zfnjJW.js} +1 -1
  7. package/web/assets/{architectureDiagram-ZJ3FMSHR-CnmL2DAX.js → architectureDiagram-ZJ3FMSHR-CTXAbDtC.js} +1 -1
  8. package/web/assets/{ask-tray-KUTWZ4MV-VQJJAsDn.js → ask-tray-CT6DQRTC-DfTc3bnC.js} +1 -1
  9. package/web/assets/{blockDiagram-677ZJIJ3-_SWUT5nP.js → blockDiagram-677ZJIJ3-CcPWOAKO.js} +1 -1
  10. package/web/assets/{c4Diagram-LMCZKHZV-r7ghc180.js → c4Diagram-LMCZKHZV-B_eNO2-f.js} +1 -1
  11. package/web/assets/channel-Dlb_u_Yk.js +1 -0
  12. package/web/assets/{chunk-2Q5K7J3B-D_LeMwFJ.js → chunk-2Q5K7J3B-BtQX_f5i.js} +1 -1
  13. package/web/assets/{chunk-32BRIVSS-AeVZw1It.js → chunk-32BRIVSS-BBtfsm8_.js} +1 -1
  14. package/web/assets/{chunk-5VM5RSS4-Bp_epQ8r.js → chunk-5VM5RSS4-CG0bf9ML.js} +1 -1
  15. package/web/assets/{chunk-EX3LRPZG-Dz4n-DeM.js → chunk-EX3LRPZG-DS2H7ilP.js} +1 -1
  16. package/web/assets/{chunk-JWPE2WC7-B0MQp8TQ.js → chunk-JWPE2WC7-CGLMMKkr.js} +1 -1
  17. package/web/assets/{chunk-MOJQB5TN-Bkomqk1x.js → chunk-MOJQB5TN-C76lqDkU.js} +1 -1
  18. package/web/assets/{chunk-RYQCIY6F-B0F7WMyE.js → chunk-RYQCIY6F-ZY-EzC5l.js} +1 -1
  19. package/web/assets/{chunk-V7JOEXUC-BDifU9oY.js → chunk-V7JOEXUC-sBv90hIh.js} +1 -1
  20. package/web/assets/{chunk-VR4S4FIN-Bgd4HCG_.js → chunk-VR4S4FIN-jW9aFTp3.js} +1 -1
  21. package/web/assets/{chunk-XXDRQBXY-BK8FhRs4.js → chunk-XXDRQBXY-FPtE6zce.js} +1 -1
  22. package/web/assets/classDiagram-OUVF2IWQ-CinFzRGQ.js +1 -0
  23. package/web/assets/classDiagram-v2-EOCWNBFH-CinFzRGQ.js +1 -0
  24. package/web/assets/{client-5Q4VI7ZT-BkTtFalV.js → client-5Q4VI7ZT-DYH5SwVp.js} +1 -1
  25. package/web/assets/{cose-bilkent-JH36ORCC-Dm3k2U47.js → cose-bilkent-JH36ORCC-NdJGLzeJ.js} +1 -1
  26. package/web/assets/{cynefin-VYW2F7L2-DCnilF1f.js → cynefin-VYW2F7L2-D-o_obcW.js} +1 -1
  27. package/web/assets/{cynefinDiagram-TSTJHNR4-BrulEEQ9.js → cynefinDiagram-TSTJHNR4-RA4QYrtB.js} +1 -1
  28. package/web/assets/{dagre-VKFMJZFB-Dda61i4h.js → dagre-VKFMJZFB-Bq4DfO16.js} +1 -1
  29. package/web/assets/{diagram-FQU43EPY-sTmDEDMM.js → diagram-FQU43EPY-bPnACaba.js} +1 -1
  30. package/web/assets/{diagram-G47NLZAW-d-KQnPrm.js → diagram-G47NLZAW-cPca5hvp.js} +1 -1
  31. package/web/assets/{diagram-NH7WQ7WH-DcRxa_ps.js → diagram-NH7WQ7WH-DHyP34H8.js} +1 -1
  32. package/web/assets/{diagram-OA4YK3LP-CYzWtWvV.js → diagram-OA4YK3LP-hVk7mHu1.js} +1 -1
  33. package/web/assets/{diagram-WEI45ONY-FI3V_N07.js → diagram-WEI45ONY-Cd3AEJO3.js} +1 -1
  34. package/web/assets/{document-view-TGFRNHKS-VSJS3BGw.js → document-view-VX2ZTQM5-CDdtofzz.js} +8 -8
  35. package/web/assets/{ebnfDiagram-CCIWWBDH-DcvVmQhu.js → ebnfDiagram-CCIWWBDH-BxtDx2MR.js} +1 -1
  36. package/web/assets/{entity-search-page-RIYQYIJJ-Bed3y-5Q.js → entity-search-page-RIYQYIJJ-IvZzjXvt.js} +1 -1
  37. package/web/assets/{erDiagram-Q63AITRT-DI5DBlBp.js → erDiagram-Q63AITRT-CtdOkrpo.js} +1 -1
  38. package/web/assets/{flowDiagram-23GEKE2U-Bz1AbRxB.js → flowDiagram-23GEKE2U-BDHfaJo6.js} +1 -1
  39. package/web/assets/{ganttDiagram-NO4QXBWP-ChKlhxeo.js → ganttDiagram-NO4QXBWP-BhV7JFJA.js} +1 -1
  40. package/web/assets/{gitGraphDiagram-IHSO6WYX-BtTqLSyY.js → gitGraphDiagram-IHSO6WYX-BVRBRDVk.js} +1 -1
  41. package/web/assets/index-BxCXNDe6.css +1 -0
  42. package/web/assets/{index-CDAH4UPU.js → index-Cl-kcrk3.js} +191 -182
  43. package/web/assets/{infoDiagram-FWYZ7A6U-COpIz9uZ.js → infoDiagram-FWYZ7A6U-BKuFQe6t.js} +1 -1
  44. package/web/assets/{ishikawaDiagram-FXEZZL3T-CB7Bdsfr.js → ishikawaDiagram-FXEZZL3T-lNbhlHEo.js} +1 -1
  45. package/web/assets/{journeyDiagram-5HDEW3XC-BMytnJBE.js → journeyDiagram-5HDEW3XC-CoGf_pSm.js} +1 -1
  46. package/web/assets/{kanban-definition-HUTT4EX6-BFS4G0g-.js → kanban-definition-HUTT4EX6-Cgp0WGrq.js} +1 -1
  47. package/web/assets/{linear-DMUO2qBp.js → linear-B3UMk7TK.js} +1 -1
  48. package/web/assets/{linked-session-header-7BUTWROP-DzEcA4Fq.js → linked-session-header-7BUTWROP-Coqn-Dz0.js} +1 -1
  49. package/web/assets/{mermaid.core-BAj-Ltr-.js → mermaid.core-6bZ5bkAq.js} +4 -4
  50. package/web/assets/{mindmap-definition-LN4V7U3C-CjymOEvH.js → mindmap-definition-LN4V7U3C-BowQNgIG.js} +1 -1
  51. package/web/assets/{pegDiagram-2B236MQR-D64jiUPu.js → pegDiagram-2B236MQR-DrhWFvfI.js} +1 -1
  52. package/web/assets/{pieDiagram-ENE6RG2P-CCbI5U6o.js → pieDiagram-ENE6RG2P-DNOg53mu.js} +1 -1
  53. package/web/assets/{plugin-host-modules-D7pHtNJn.js → plugin-host-modules-NvyHieUX.js} +26 -26
  54. package/web/assets/{project-search-page-O6YRLDGU-1bPrifgb.js → project-search-page-O6YRLDGU-CFA4lf0c.js} +1 -1
  55. package/web/assets/{quadrantDiagram-ABIIQ3AL-B7dN_Kn5.js → quadrantDiagram-ABIIQ3AL-BOJ4UGbk.js} +1 -1
  56. package/web/assets/{railroadDiagram-RFXS5EU6-BPjAzqcL.js → railroadDiagram-RFXS5EU6-_UJ9_AEC.js} +1 -1
  57. package/web/assets/{requirementDiagram-TGXJPOKE-BFhnnUWa.js → requirementDiagram-TGXJPOKE-BFa61FSa.js} +1 -1
  58. package/web/assets/{sankeyDiagram-HTMAVEWB-W2UguUjW.js → sankeyDiagram-HTMAVEWB-V1J9w6jl.js} +1 -1
  59. package/web/assets/{selection-popup-ABYH3A27-DsiLbG7S.js → selection-popup-ZX4VUZ3A-Duh9LSP2.js} +1 -1
  60. package/web/assets/{sequenceDiagram-DBY2YBRQ-DcOakOD4.js → sequenceDiagram-DBY2YBRQ-xdS7JpTx.js} +1 -1
  61. package/web/assets/{sizeCapture-X5ZJPWSS-D3N248Z6.js → sizeCapture-X5ZJPWSS-DBULLaws.js} +1 -1
  62. package/web/assets/{stateDiagram-2N3HPSRC-Cir3yiDe.js → stateDiagram-2N3HPSRC-DfBpQAQb.js} +1 -1
  63. package/web/assets/{stateDiagram-v2-6OUMAXLB-BwL0KYLn.js → stateDiagram-v2-6OUMAXLB-C-dC_PIX.js} +1 -1
  64. package/web/assets/{swimlanes-5IMT3BWC-Dhq7FmZr.js → swimlanes-5IMT3BWC-L-RTYuhP.js} +2 -2
  65. package/web/assets/swimlanesDiagram-G3AALYLV-BErklojq.js +8 -0
  66. package/web/assets/{timeline-definition-FHXFAJF6-CMa1wjsI.js → timeline-definition-FHXFAJF6-CAEbvdzk.js} +1 -1
  67. package/web/assets/{vennDiagram-L72KCM5P-DvglazwQ.js → vennDiagram-L72KCM5P-J10bFP8c.js} +1 -1
  68. package/web/assets/{wardleyDiagram-EHGQE667-DcogrL32.js → wardleyDiagram-EHGQE667-Bm0goK-9.js} +1 -1
  69. package/web/assets/{xychartDiagram-FW5EYKEG-BlsDcr_U.js → xychartDiagram-FW5EYKEG-BAH4TTVb.js} +1 -1
  70. package/web/index.html +2 -2
  71. package/web/assets/channel-r9-1szjb.js +0 -1
  72. package/web/assets/classDiagram-OUVF2IWQ-L_jmDmNd.js +0 -1
  73. package/web/assets/classDiagram-v2-EOCWNBFH-L_jmDmNd.js +0 -1
  74. package/web/assets/index-Di6pguZz.css +0 -1
  75. package/web/assets/swimlanesDiagram-G3AALYLV-D4q-nPpB.js +0 -8
@@ -5655,7 +5655,7 @@ var init_contract2 = __esm(() => {
5655
5655
  });
5656
5656
 
5657
5657
  // packages/api/src/contracts/schemas.ts
5658
- var items = (item) => object({ items: array(item) }), icon, file, project, session, collectionSummary2, workspace, plugin, plugins, folder, assets, folderMetadataSchema, collection, metadataSchemas, metadataQuerySchema, documentEditSchema, document2, documentSchema, entity, projectSearchItemSchema, pathQuery, emptyQuery, routes;
5658
+ var items = (item) => object({ items: array(item) }), icon, file, project, session, collectionSummary2, workspace, plugin, plugins, folder, assets, folderMetadataSchema, collection, metadataSchemas, metadataQuerySchema, deleteNoteSchema, documentEditSchema, document2, documentSchema, entity, projectSearchItemSchema, pathQuery, emptyQuery, routes;
5659
5659
  var init_schemas3 = __esm(() => {
5660
5660
  init_contract2();
5661
5661
  init_zod();
@@ -5767,6 +5767,10 @@ var init_schemas3 = __esm(() => {
5767
5767
  sort: _enum(["alpha", "recent"]).optional(),
5768
5768
  schema: string2().optional()
5769
5769
  });
5770
+ deleteNoteSchema = object({
5771
+ folder: string2(),
5772
+ path: string2()
5773
+ });
5770
5774
  documentEditSchema = object({
5771
5775
  folder: string2(),
5772
5776
  path: string2(),
@@ -5826,7 +5830,11 @@ var init_schemas3 = __esm(() => {
5826
5830
  path: "/api/health",
5827
5831
  method: "get",
5828
5832
  query: emptyQuery,
5829
- response: object({ viewer: string2(), root: string2(), kernelKey: string2() })
5833
+ response: object({
5834
+ viewer: string2(),
5835
+ root: string2(),
5836
+ kernelKey: string2()
5837
+ })
5830
5838
  },
5831
5839
  capabilities: {
5832
5840
  path: "/api/capabilities",
@@ -5914,6 +5922,13 @@ var init_schemas3 = __esm(() => {
5914
5922
  path: "/api/open-path",
5915
5923
  method: "get",
5916
5924
  query: object({ path: string2() })
5925
+ },
5926
+ deleteNote: {
5927
+ path: "/api/delete-note",
5928
+ method: "post",
5929
+ query: emptyQuery,
5930
+ body: deleteNoteSchema,
5931
+ response: object({ deleted: literal(true) })
5917
5932
  }
5918
5933
  };
5919
5934
  });
@@ -6030,6 +6045,16 @@ function createKennelClient(options = {}) {
6030
6045
  parseAs: "text"
6031
6046
  });
6032
6047
  },
6048
+ async deleteNote(body, input = {}) {
6049
+ const response = await (options.fetch ?? globalThis.fetch)(new URL(routes.deleteNote.path, baseUrl), {
6050
+ method: "POST",
6051
+ headers: { "Content-Type": "application/json" },
6052
+ body: JSON.stringify(deleteNoteSchema.parse(body)),
6053
+ signal: input.signal
6054
+ });
6055
+ if (!response.ok)
6056
+ throw await expectedError(response);
6057
+ },
6033
6058
  async openFolder(path, input = {}) {
6034
6059
  await transport.POST(routes.openFolder.path, {
6035
6060
  params: { query: { path } },
@@ -38593,6 +38618,43 @@ var init_entity_folder = __esm(() => {
38593
38618
  ]);
38594
38619
  });
38595
38620
 
38621
+ // packages/api/src/server/api/delete-note.ts
38622
+ import { realpath as realpath5, stat as stat5, unlink as unlink2 } from "node:fs/promises";
38623
+ import { extname as extname3, isAbsolute as isAbsolute5, relative as relative9, resolve as resolve9, sep as sep5 } from "node:path";
38624
+ async function containedTarget(path, folder) {
38625
+ const target = await realpath5(resolve9(folder, path));
38626
+ const local = relative9(folder, target);
38627
+ if (!local || local === ".." || local.startsWith(`..${sep5}`) || isAbsolute5(local))
38628
+ throw apiError("forbidden", "The note must be inside its folder.");
38629
+ return target;
38630
+ }
38631
+ var markdownExtensions2, deleteNoteRoute;
38632
+ var init_delete_note = __esm(() => {
38633
+ init_schemas3();
38634
+ init_endpoint();
38635
+ markdownExtensions2 = new Set([".md", ".markdown"]);
38636
+ deleteNoteRoute = {
38637
+ method: "POST",
38638
+ maxBodyBytes: 4 * 1024,
38639
+ async handle({ body, context, response }) {
38640
+ const parsed = deleteNoteSchema.safeParse(parseJsonBody(body));
38641
+ if (!parsed.success)
38642
+ throw apiError("bad-request", "Invalid delete request.");
38643
+ const folder = context.authorize(parsed.data.folder);
38644
+ if (!markdownExtensions2.has(extname3(parsed.data.path).toLowerCase()))
38645
+ throw apiError("bad-request", "Only Markdown notes can be deleted.");
38646
+ const target = await containedTarget(parsed.data.path, folder);
38647
+ const details = await stat5(target).catch(() => {
38648
+ return;
38649
+ });
38650
+ if (!details?.isFile() || details.nlink !== 1)
38651
+ throw apiError("forbidden", "Only regular, unlinked files can be deleted.");
38652
+ await unlink2(target);
38653
+ jsonResponse(response, 200, routes.deleteNote.response.parse({ deleted: true }));
38654
+ }
38655
+ };
38656
+ });
38657
+
38596
38658
  // packages/api/src/shared/selection.ts
38597
38659
  function replaceSelection(content, start, end, replacement) {
38598
38660
  if (!Number.isInteger(start) || !Number.isInteger(end) || start < 0 || end <= start || end > content.length)
@@ -38604,30 +38666,30 @@ function replaceSelection(content, start, end, replacement) {
38604
38666
  import { randomUUID as randomUUID3 } from "node:crypto";
38605
38667
  import {
38606
38668
  readFile as readFile7,
38607
- realpath as realpath5,
38669
+ realpath as realpath6,
38608
38670
  rename as rename3,
38609
- stat as stat5,
38610
- unlink as unlink2,
38671
+ stat as stat6,
38672
+ unlink as unlink3,
38611
38673
  writeFile as writeFile4
38612
38674
  } from "node:fs/promises";
38613
38675
  import {
38614
38676
  dirname as dirname8,
38615
- extname as extname3,
38616
- isAbsolute as isAbsolute5,
38617
- relative as relative9,
38618
- resolve as resolve9,
38619
- sep as sep5
38677
+ extname as extname4,
38678
+ isAbsolute as isAbsolute6,
38679
+ relative as relative10,
38680
+ resolve as resolve10,
38681
+ sep as sep6
38620
38682
  } from "node:path";
38621
38683
  async function editDocument(folder, input) {
38622
38684
  const { path, original, start, end, replacement } = input;
38623
38685
  if (typeof path !== "string" || typeof original !== "string" || typeof replacement !== "string" || typeof start !== "number" || typeof end !== "number")
38624
38686
  throw apiError("bad-request", "Invalid document edit.");
38625
- if (![".md", ".markdown"].includes(extname3(path).toLowerCase()))
38687
+ if (![".md", ".markdown"].includes(extname4(path).toLowerCase()))
38626
38688
  throw apiError("bad-request", "Only Markdown notes can be edited.");
38627
- const root = await realpath5(folder);
38628
- const target = await realpath5(resolve9(root, path));
38629
- const local = relative9(root, target);
38630
- if (!local || local === ".." || local.startsWith(`..${sep5}`) || isAbsolute5(local))
38689
+ const root = await realpath6(folder);
38690
+ const target = await realpath6(resolve10(root, path));
38691
+ const local = relative10(root, target);
38692
+ if (!local || local === ".." || local.startsWith(`..${sep6}`) || isAbsolute6(local))
38631
38693
  throw apiError("forbidden", "The document must be inside its folder.");
38632
38694
  let content;
38633
38695
  try {
@@ -38637,12 +38699,12 @@ async function editDocument(folder, input) {
38637
38699
  }
38638
38700
  const previous = pending.get(target) ?? Promise.resolve();
38639
38701
  const operation = previous.catch(() => {}).then(async () => {
38640
- const details = await stat5(target);
38702
+ const details = await stat6(target);
38641
38703
  if (!details.isFile() || details.nlink !== 1)
38642
38704
  throw apiError("forbidden", "Only regular, unlinked files can be edited.");
38643
38705
  if (await readFile7(target, "utf8") !== original)
38644
38706
  throw apiError("conflict", "This note changed on disk. Close this preview, reload the note, and try again.");
38645
- const temporary = resolve9(dirname8(target), `.kennel-edit-${randomUUID3()}.tmp`);
38707
+ const temporary = resolve10(dirname8(target), `.kennel-edit-${randomUUID3()}.tmp`);
38646
38708
  try {
38647
38709
  await writeFile4(temporary, content, {
38648
38710
  flag: "wx",
@@ -38652,7 +38714,7 @@ async function editDocument(folder, input) {
38652
38714
  throw apiError("conflict", "This note changed on disk. Reload before applying an edit.");
38653
38715
  await rename3(temporary, target);
38654
38716
  } finally {
38655
- await unlink2(temporary).catch(() => {});
38717
+ await unlink3(temporary).catch(() => {});
38656
38718
  }
38657
38719
  return content;
38658
38720
  });
@@ -38678,7 +38740,7 @@ var init_document_edit = __esm(() => {
38678
38740
  throw apiError("bad-request", "Invalid document edit.");
38679
38741
  const input = parsed.data;
38680
38742
  const folder = context.authorize(input.folder);
38681
- if (context.lockedFile && (typeof input.path !== "string" || await realpath5(resolve9(folder, input.path)) !== context.lockedFile))
38743
+ if (context.lockedFile && (typeof input.path !== "string" || await realpath6(resolve10(folder, input.path)) !== context.lockedFile))
38682
38744
  throw apiError("forbidden", "Only the selected document can be edited.");
38683
38745
  await editDocument(folder, input);
38684
38746
  jsonResponse(response, 200, routes.documentEdit.response.parse({ saved: true }));
@@ -38688,7 +38750,7 @@ var init_document_edit = __esm(() => {
38688
38750
 
38689
38751
  // packages/api/src/server/api/create-agent-file.ts
38690
38752
  import { writeFile as writeFile5 } from "node:fs/promises";
38691
- import { resolve as resolve10 } from "node:path";
38753
+ import { resolve as resolve11 } from "node:path";
38692
38754
  var createAgentFileRoute;
38693
38755
  var init_create_agent_file = __esm(() => {
38694
38756
  init_endpoint();
@@ -38702,7 +38764,7 @@ var init_create_agent_file = __esm(() => {
38702
38764
  } catch (error) {
38703
38765
  throw apiError("not-found", error instanceof Error ? error.message : "Folder not found");
38704
38766
  }
38705
- const target = resolve10(folder, "AGENTS.md");
38767
+ const target = resolve11(folder, "AGENTS.md");
38706
38768
  try {
38707
38769
  await writeFile5(target, "", { flag: "wx" });
38708
38770
  } catch (error) {
@@ -38768,8 +38830,8 @@ var init_folder_favicon = __esm(() => {
38768
38830
 
38769
38831
  // packages/api/src/server/folder-icons.ts
38770
38832
  import { createHash as createHash4 } from "node:crypto";
38771
- import { readFile as readFile9, stat as stat6 } from "node:fs/promises";
38772
- import { extname as extname4 } from "node:path";
38833
+ import { readFile as readFile9, stat as stat7 } from "node:fs/promises";
38834
+ import { extname as extname5 } from "node:path";
38773
38835
  import { discoverFolderIcon } from "@raggle-ai/local";
38774
38836
  function assetKey(value) {
38775
38837
  return createHash4("sha256").update(value).digest("hex");
@@ -38786,8 +38848,8 @@ function iconUrl(folder, hash, mediaType) {
38786
38848
  }
38787
38849
  async function folderIcon(folder, assets, assetFiles, fallback) {
38788
38850
  const icon = discoverFolderIcon(folder);
38789
- const mediaType = icon ? iconTypes.get(extname4(icon).toLowerCase()) : null;
38790
- const details = icon && mediaType ? await stat6(icon).catch(() => {
38851
+ const mediaType = icon ? iconTypes.get(extname5(icon).toLowerCase()) : null;
38852
+ const details = icon && mediaType ? await stat7(icon).catch(() => {
38791
38853
  return;
38792
38854
  }) : undefined;
38793
38855
  if (!icon || !mediaType || !details?.size || details.size > maxIconBytes2) {
@@ -38809,10 +38871,10 @@ async function searchIconDataUrl(icon) {
38809
38871
  return;
38810
38872
  if (icon.startsWith("data:"))
38811
38873
  return icon;
38812
- const mediaType = searchIconTypes.get(extname4(icon).toLowerCase());
38874
+ const mediaType = searchIconTypes.get(extname5(icon).toLowerCase());
38813
38875
  if (!mediaType)
38814
38876
  return;
38815
- const details = await stat6(icon).catch(() => {
38877
+ const details = await stat7(icon).catch(() => {
38816
38878
  return;
38817
38879
  });
38818
38880
  if (!details?.size || details.size > maxSearchIconBytes)
@@ -38886,18 +38948,18 @@ var init_folder_icons = __esm(() => {
38886
38948
 
38887
38949
  // packages/knl/src/folder-guard.ts
38888
38950
  import { existsSync as existsSync4, realpathSync as realpathSync2 } from "node:fs";
38889
- import { realpath as realpath6 } from "node:fs/promises";
38890
- import { dirname as dirname9, resolve as resolve11, sep as sep6 } from "node:path";
38951
+ import { realpath as realpath7 } from "node:fs/promises";
38952
+ import { dirname as dirname9, resolve as resolve12, sep as sep7 } from "node:path";
38891
38953
  import { fileURLToPath as fileURLToPath2 } from "node:url";
38892
38954
  async function knlRealRoot(owner) {
38893
- const expected = resolve11(await realpath6(owner), "knl");
38894
- const real = await realpath6(resolve11(owner, "knl"));
38955
+ const expected = resolve12(await realpath7(owner), "knl");
38956
+ const real = await realpath7(resolve12(owner, "knl"));
38895
38957
  if (real !== expected)
38896
38958
  throw new Error("knl/ must be a folder, not a link to another place.");
38897
38959
  return real;
38898
38960
  }
38899
38961
  async function knlReadRoots(owner) {
38900
- const packages = await Promise.all(knlHostPackageFolders.map((folder) => realpath6(folder).catch(() => {
38962
+ const packages = await Promise.all(knlHostPackageFolders.map((folder) => realpath7(folder).catch(() => {
38901
38963
  return;
38902
38964
  })));
38903
38965
  return [
@@ -38910,9 +38972,9 @@ function isKnlReadable(file, roots) {
38910
38972
  try {
38911
38973
  real = realpathSync2(file);
38912
38974
  } catch {
38913
- real = resolve11(file);
38975
+ real = resolve12(file);
38914
38976
  }
38915
- return roots.some((root) => real === root || real.startsWith(`${root}${sep6}`));
38977
+ return roots.some((root) => real === root || real.startsWith(`${root}${sep7}`));
38916
38978
  }
38917
38979
  function knlReadError(file) {
38918
38980
  return `KNL pages can only use files in knl/ and installed packages: ${file}`;
@@ -38928,7 +38990,7 @@ var init_folder_guard = __esm(() => {
38928
38990
  const folders = [];
38929
38991
  let current = knlHostResolveDir;
38930
38992
  while (true) {
38931
- const nodeModules = resolve11(current, "node_modules");
38993
+ const nodeModules = resolve12(current, "node_modules");
38932
38994
  if (existsSync4(nodeModules))
38933
38995
  folders.push(nodeModules);
38934
38996
  const parent = dirname9(current);
@@ -38942,7 +39004,7 @@ var init_folder_guard = __esm(() => {
38942
39004
  // packages/knl/src/tailwind.ts
38943
39005
  import { readFile as readFile10 } from "node:fs/promises";
38944
39006
  import { createRequire as createRequire2 } from "node:module";
38945
- import { dirname as dirname10, resolve as resolve12 } from "node:path";
39007
+ import { dirname as dirname10, resolve as resolve13 } from "node:path";
38946
39008
  import { compile } from "@tailwindcss/node";
38947
39009
  import { Scanner } from "@tailwindcss/oxide";
38948
39010
  function starterKnlStyles() {
@@ -38984,7 +39046,7 @@ async function compileKnlCss(js, stylesheet, roots) {
38984
39046
  continue;
38985
39047
  const fixed = source.pattern.split("/");
38986
39048
  const glob = fixed.findIndex((part) => /[*?[{]/.test(part));
38987
- assertKnlReadable(resolve12(source.base, fixed.slice(0, glob < 0 ? undefined : glob).join("/")), roots);
39049
+ assertKnlReadable(resolve13(source.base, fixed.slice(0, glob < 0 ? undefined : glob).join("/")), roots);
38988
39050
  }
38989
39051
  const scanner = new Scanner({ sources });
38990
39052
  const candidates = [
@@ -39000,31 +39062,31 @@ var init_tailwind = __esm(() => {
39000
39062
  });
39001
39063
 
39002
39064
  // packages/knl/src/knl.ts
39003
- import { readdir as readdir5, stat as stat7 } from "node:fs/promises";
39004
- import { basename as basename6, dirname as dirname11, relative as relative10, resolve as resolve13, sep as sep7 } from "node:path";
39065
+ import { readdir as readdir5, stat as stat8 } from "node:fs/promises";
39066
+ import { basename as basename6, dirname as dirname11, relative as relative11, resolve as resolve14, sep as sep8 } from "node:path";
39005
39067
  import * as esbuild from "esbuild";
39006
39068
  function sourceFor(file, knlRoot, scanRoot, owner) {
39007
39069
  const id = toModuleId(file, knlRoot);
39008
39070
  return {
39009
39071
  id,
39010
39072
  file,
39011
- relative: relative10(scanRoot, file).split(sep7).join("/"),
39073
+ relative: relative11(scanRoot, file).split(sep8).join("/"),
39012
39074
  folder: dirname11(file),
39013
39075
  owner
39014
39076
  };
39015
39077
  }
39016
39078
  function toModuleId(file, knlRoot) {
39017
- const relativeKnl = relative10(knlRoot, file).split(sep7).join("/");
39079
+ const relativeKnl = relative11(knlRoot, file).split(sep8).join("/");
39018
39080
  return relativeKnl.replace(/\/?index\.(tsx|ts)$/, "") || "index";
39019
39081
  }
39020
39082
  async function collectKnlSources(scanRoot, owner) {
39021
- const knlRoot = resolve13(scanRoot, KNK_FOLDER);
39083
+ const knlRoot = resolve14(scanRoot, KNK_FOLDER);
39022
39084
  const knlEntries = await readdir5(knlRoot, { withFileTypes: true }).catch(() => []);
39023
39085
  const sources = [];
39024
39086
  const addModule = async (folder) => {
39025
39087
  for (const candidate of MODULE_FILES) {
39026
- const file = resolve13(folder, candidate);
39027
- if (await stat7(file).then((d) => d.isFile()).catch(() => false)) {
39088
+ const file = resolve14(folder, candidate);
39089
+ if (await stat8(file).then((d) => d.isFile()).catch(() => false)) {
39028
39090
  sources.push(sourceFor(file, knlRoot, scanRoot, owner));
39029
39091
  return;
39030
39092
  }
@@ -39036,7 +39098,7 @@ async function collectKnlSources(scanRoot, owner) {
39036
39098
  continue;
39037
39099
  if (entry.name.startsWith(".") || entry.name === "node_modules")
39038
39100
  continue;
39039
- await addModule(resolve13(knlRoot, entry.name));
39101
+ await addModule(resolve14(knlRoot, entry.name));
39040
39102
  }
39041
39103
  return sources.sort((left, right) => {
39042
39104
  const rank = (left.id === "index" ? 0 : 1) - (right.id === "index" ? 0 : 1);
@@ -39055,10 +39117,10 @@ async function loadKnlSources(viewRoot, linkedFolders = []) {
39055
39117
  return { sources };
39056
39118
  }
39057
39119
  function knlNodePaths(knlRoot) {
39058
- return [resolve13(knlRoot, "node_modules"), ...knlHostPackageFolders];
39120
+ return [resolve14(knlRoot, "node_modules"), ...knlHostPackageFolders];
39059
39121
  }
39060
39122
  async function compileKnlSource(source) {
39061
- const sourceBytes = (await stat7(source.file)).size;
39123
+ const sourceBytes = (await stat8(source.file)).size;
39062
39124
  const tooLarge = (bytes, what) => ({
39063
39125
  id: source.id,
39064
39126
  relative: source.relative,
@@ -39074,10 +39136,10 @@ async function compileKnlSource(source) {
39074
39136
  if (sourceBytes > MAX_SOURCE_BYTES)
39075
39137
  return tooLarge(sourceBytes, "source");
39076
39138
  const cached = compileCache.get(source.file);
39077
- const unchanged = cached && (await Promise.all(cached.dependencies.map(async ({ file, mtimeMs }) => (await stat7(file).catch(() => {
39139
+ const unchanged = cached && (await Promise.all(cached.dependencies.map(async ({ file, mtimeMs }) => (await stat8(file).catch(() => {
39078
39140
  return;
39079
39141
  }))?.mtimeMs === mtimeMs))).every(Boolean);
39080
- const knlRoot = resolve13(source.owner, KNK_FOLDER);
39142
+ const knlRoot = resolve14(source.owner, KNK_FOLDER);
39081
39143
  let issuePath = source.relative;
39082
39144
  try {
39083
39145
  const nodePaths = knlNodePaths(knlRoot);
@@ -39118,12 +39180,12 @@ globalThis.__knlMount = (container, context, onError) => {
39118
39180
  });
39119
39181
  js = result.outputFiles?.[0]?.text ?? "";
39120
39182
  const files = new Set([
39121
- resolve13(knlRoot, "package.json"),
39122
- ...Object.keys(result.metafile.inputs).map((file) => resolve13(source.folder, file)).filter((file) => file !== `${source.file}.mount.ts`)
39183
+ resolve14(knlRoot, "package.json"),
39184
+ ...Object.keys(result.metafile.inputs).map((file) => resolve14(source.folder, file)).filter((file) => file !== `${source.file}.mount.ts`)
39123
39185
  ]);
39124
39186
  const dependencies = await Promise.all([...files].map(async (file) => ({
39125
39187
  file,
39126
- mtimeMs: (await stat7(file).catch(() => {
39188
+ mtimeMs: (await stat8(file).catch(() => {
39127
39189
  return;
39128
39190
  }))?.mtimeMs
39129
39191
  })));
@@ -39132,8 +39194,8 @@ globalThis.__knlMount = (container, context, onError) => {
39132
39194
  if (compileCache.size > MAX_CACHED_MODULES)
39133
39195
  compileCache.delete(compileCache.keys().next().value);
39134
39196
  }
39135
- const stylesheet = resolve13(knlRoot, "style.css");
39136
- issuePath = relative10(source.owner, stylesheet).split(sep7).join("/");
39197
+ const stylesheet = resolve14(knlRoot, "style.css");
39198
+ issuePath = relative11(source.owner, stylesheet).split(sep8).join("/");
39137
39199
  const css = await compileKnlCss(js, stylesheet, roots);
39138
39200
  issuePath = source.relative;
39139
39201
  if (js.length + css.length > MAX_JS_BYTES) {
@@ -39192,7 +39254,7 @@ function knlBuildIssues(error, relativePath, source) {
39192
39254
  const failures = error?.errors;
39193
39255
  if (Array.isArray(failures) && failures.length > 0) {
39194
39256
  const first = failures[0];
39195
- const file = first?.location?.file ? relative10(source.owner, resolve13(source.folder, first.location.file)).split(sep7).join("/") : relativePath;
39257
+ const file = first?.location?.file ? relative11(source.owner, resolve14(source.folder, first.location.file)).split(sep8).join("/") : relativePath;
39196
39258
  const location = first?.location ? `${file}:${first.location.line ?? "?"}` : relativePath;
39197
39259
  return [
39198
39260
  { path: location, message: first?.text ?? "Module failed to compile." }
@@ -39241,13 +39303,13 @@ var init_manifest = __esm(() => {
39241
39303
  });
39242
39304
 
39243
39305
  // packages/knl/src/server.ts
39244
- import { stat as stat8 } from "node:fs/promises";
39306
+ import { stat as stat9 } from "node:fs/promises";
39245
39307
  import { join as join5 } from "node:path";
39246
39308
  function createKnlPlugin() {
39247
39309
  return {
39248
39310
  ...knlManifest,
39249
39311
  async detect(context) {
39250
- const hasKnlFolder = await stat8(join5(context.folder, KNK_FOLDER)).then((entry) => entry.isDirectory()).catch(() => false);
39312
+ const hasKnlFolder = await stat9(join5(context.folder, KNK_FOLDER)).then((entry) => entry.isDirectory()).catch(() => false);
39251
39313
  if (!hasKnlFolder)
39252
39314
  return { status: "unavailable" };
39253
39315
  const { sources } = await loadKnlSources(context.folder, context.linkedFolders ?? []);
@@ -39353,14 +39415,14 @@ var init_manifest2 = __esm(() => {
39353
39415
  });
39354
39416
 
39355
39417
  // packages/notes/src/server.ts
39356
- import { readdir as readdir6, realpath as realpath7, stat as stat9 } from "node:fs/promises";
39418
+ import { readdir as readdir6, realpath as realpath8, stat as stat10 } from "node:fs/promises";
39357
39419
  import {
39358
39420
  basename as basename7,
39359
- extname as extname5,
39360
- isAbsolute as isAbsolute6,
39361
- relative as relative11,
39362
- resolve as resolve14,
39363
- sep as sep8
39421
+ extname as extname6,
39422
+ isAbsolute as isAbsolute7,
39423
+ relative as relative12,
39424
+ resolve as resolve15,
39425
+ sep as sep9
39364
39426
  } from "node:path";
39365
39427
  async function listMarkdownFiles(folder) {
39366
39428
  const files = [];
@@ -39369,21 +39431,21 @@ async function listMarkdownFiles(folder) {
39369
39431
  for (const entry of entries) {
39370
39432
  if (entry.name === "node_modules" || entry.name.startsWith("."))
39371
39433
  continue;
39372
- const path = resolve14(current, entry.name);
39434
+ const path = resolve15(current, entry.name);
39373
39435
  if (entry.isDirectory()) {
39374
39436
  await visit(path);
39375
39437
  continue;
39376
39438
  }
39377
- if (!entry.isFile() || !markdownExtensions2.has(extname5(entry.name))) {
39439
+ if (!entry.isFile() || !markdownExtensions3.has(extname6(entry.name))) {
39378
39440
  continue;
39379
39441
  }
39380
- const details = await stat9(path).catch(() => {
39442
+ const details = await stat10(path).catch(() => {
39381
39443
  return;
39382
39444
  });
39383
39445
  files.push({
39384
39446
  activityAt: details?.mtimeMs ?? 0,
39385
- name: basename7(entry.name, extname5(entry.name)),
39386
- relativePath: relative11(folder, path).split(sep8).join("/")
39447
+ name: basename7(entry.name, extname6(entry.name)),
39448
+ relativePath: relative12(folder, path).split(sep9).join("/")
39387
39449
  });
39388
39450
  }
39389
39451
  };
@@ -39391,8 +39453,8 @@ async function listMarkdownFiles(folder) {
39391
39453
  return files.sort((left, right) => right.activityAt - left.activityAt);
39392
39454
  }
39393
39455
  function inside5(path, root) {
39394
- const local = relative11(root, path);
39395
- return local === "" || !local.startsWith("..") && !isAbsolute6(local);
39456
+ const local = relative12(root, path);
39457
+ return local === "" || !local.startsWith("..") && !isAbsolute7(local);
39396
39458
  }
39397
39459
  async function withoutManaged(groups, managedRoots) {
39398
39460
  if (!managedRoots.length)
@@ -39403,7 +39465,7 @@ async function withoutManaged(groups, managedRoots) {
39403
39465
  return { ...group, files: [] };
39404
39466
  }
39405
39467
  const files = await Promise.all(group.files.map(async (file) => {
39406
- const real = await canonical(resolve14(group.folder, file.relativePath));
39468
+ const real = await canonical(resolve15(group.folder, file.relativePath));
39407
39469
  return roots.some((root) => inside5(real, root)) ? undefined : file;
39408
39470
  }));
39409
39471
  return { ...group, files: files.filter((file) => file !== undefined) };
@@ -39453,7 +39515,7 @@ async function notesLlmSections({
39453
39515
  continue;
39454
39516
  seen.add(identity);
39455
39517
  const files = await listMarkdownFiles(source);
39456
- const paths = files.map((file) => resolve14(source, file.relativePath));
39518
+ const paths = files.map((file) => resolve15(source, file.relativePath));
39457
39519
  groups.push({ folder: source, paths });
39458
39520
  files.forEach((file, index) => notes.push({ activityAt: file.activityAt, path: paths[index] }));
39459
39521
  }
@@ -39497,17 +39559,17 @@ function createNotesPlugin() {
39497
39559
  llm: notesLlmSections
39498
39560
  };
39499
39561
  }
39500
- var markdownExtensions2, llmNoteLimit = 20, canonical = (path) => realpath7(path).catch(() => path);
39562
+ var markdownExtensions3, llmNoteLimit = 20, canonical = (path) => realpath8(path).catch(() => path);
39501
39563
  var init_server4 = __esm(() => {
39502
39564
  init_manifest2();
39503
- markdownExtensions2 = new Set([".md", ".markdown"]);
39565
+ markdownExtensions3 = new Set([".md", ".markdown"]);
39504
39566
  });
39505
39567
 
39506
39568
  // packages/api/src/server/plugins.ts
39507
39569
  import { pathToFileURL } from "node:url";
39508
39570
  import { existsSync as existsSync5 } from "node:fs";
39509
- import { mkdir as mkdir4, readFile as readFile11, stat as stat10, writeFile as writeFile6 } from "node:fs/promises";
39510
- import { dirname as dirname12, resolve as resolve15, sep as sep9 } from "node:path";
39571
+ import { mkdir as mkdir4, readFile as readFile11, stat as stat11, writeFile as writeFile6 } from "node:fs/promises";
39572
+ import { dirname as dirname12, resolve as resolve16, sep as sep10 } from "node:path";
39511
39573
  function configuredFolderServerRegistry(registry, resolvedConfig) {
39512
39574
  const disabled = new Set(resolvedConfig.plugins.disable);
39513
39575
  const orderedIds = resolvedConfig.plugins.order.filter((id) => registry.has(id) && !disabled.has(id));
@@ -39532,8 +39594,8 @@ function parsePluginRegistryConfig(content) {
39532
39594
  }
39533
39595
  async function nearestKennelConfig(folder) {
39534
39596
  for (let current = folder;; current = dirname12(current)) {
39535
- const candidate = resolve15(current, "kennel.json");
39536
- const details = await stat10(candidate).catch(() => {
39597
+ const candidate = resolve16(current, "kennel.json");
39598
+ const details = await stat11(candidate).catch(() => {
39537
39599
  return;
39538
39600
  });
39539
39601
  if (details?.isFile())
@@ -39595,7 +39657,7 @@ async function folderServerRegistryAsync() {
39595
39657
  ...server,
39596
39658
  async detect(context) {
39597
39659
  const detection = await server.detect(context);
39598
- if (detection.status === "unavailable" && existsSync5(resolve15(context.folder, entry.trigger))) {
39660
+ if (detection.status === "unavailable" && existsSync5(resolve16(context.folder, entry.trigger))) {
39599
39661
  return { status: "available" };
39600
39662
  }
39601
39663
  return detection;
@@ -39864,27 +39926,27 @@ var init_project_discovery = __esm(() => {
39864
39926
  // packages/api/src/server/folder-metadata-plugin.ts
39865
39927
  import { createHash as createHash5 } from "node:crypto";
39866
39928
  import { realpathSync as realpathSync3 } from "node:fs";
39867
- import { readdir as readdir7, readFile as readFile12, realpath as realpath8, stat as stat11 } from "node:fs/promises";
39929
+ import { readdir as readdir7, readFile as readFile12, realpath as realpath9, stat as stat12 } from "node:fs/promises";
39868
39930
  import { homedir as homedir4 } from "node:os";
39869
39931
  import {
39870
39932
  basename as basename8,
39871
39933
  dirname as dirname14,
39872
- extname as extname6,
39873
- isAbsolute as isAbsolute7,
39874
- relative as relative13,
39875
- resolve as resolve16,
39876
- sep as sep10
39934
+ extname as extname7,
39935
+ isAbsolute as isAbsolute8,
39936
+ relative as relative14,
39937
+ resolve as resolve17,
39938
+ sep as sep11
39877
39939
  } from "node:path";
39878
39940
  import { execFile as execFile6 } from "node:child_process";
39879
39941
  import local from "@raggle-ai/local";
39880
39942
  function metadataFile(path, root) {
39881
- const candidate = relative13(root, path);
39882
- if (!candidate || candidate.startsWith("..") || isAbsolute7(candidate))
39943
+ const candidate = relative14(root, path);
39944
+ if (!candidate || candidate.startsWith("..") || isAbsolute8(candidate))
39883
39945
  return false;
39884
- const parts = candidate.split(sep10);
39946
+ const parts = candidate.split(sep11);
39885
39947
  if (parts.some((part) => part === "node_modules"))
39886
39948
  return false;
39887
- return metadataExtensions.has(extname6(candidate).toLowerCase());
39949
+ return metadataExtensions.has(extname7(candidate).toLowerCase());
39888
39950
  }
39889
39951
  async function configuredAiInputModule(folder) {
39890
39952
  const config = folderWorkspace(folder).config;
@@ -39892,11 +39954,11 @@ async function configuredAiInputModule(folder) {
39892
39954
  return typeof module === "string" && module.trim() ? module.trim() : null;
39893
39955
  }
39894
39956
  function folderPath(value, root, lockedRoot) {
39895
- const folder = realpathSync3(resolve16(value ?? root));
39957
+ const folder = realpathSync3(resolve17(value ?? root));
39896
39958
  if (!lockedRoot)
39897
39959
  return folder;
39898
- const path = relative13(lockedRoot, folder);
39899
- if (!path || !path.startsWith("..") && !isAbsolute7(path))
39960
+ const path = relative14(lockedRoot, folder);
39961
+ if (!path || !path.startsWith("..") && !isAbsolute8(path))
39900
39962
  return folder;
39901
39963
  throw new Error(`Folder is outside the viewer root: ${folder}`);
39902
39964
  }
@@ -39965,9 +40027,9 @@ function isMachineRoot(folder) {
39965
40027
  async function shallowMetadata(folder) {
39966
40028
  const entries = await readdir7(folder, { withFileTypes: true });
39967
40029
  const visible = entries.filter((entry) => !entry.name.startsWith(".") && entry.name !== "node_modules");
39968
- const files = await Promise.all(visible.filter((entry) => entry.isFile() && [".markdown", ".md"].includes(extname6(entry.name).toLowerCase())).map(async (entry) => {
39969
- const path = resolve16(folder, entry.name);
39970
- const details = await stat11(path);
40030
+ const files = await Promise.all(visible.filter((entry) => entry.isFile() && [".markdown", ".md"].includes(extname7(entry.name).toLowerCase())).map(async (entry) => {
40031
+ const path = resolve17(folder, entry.name);
40032
+ const details = await stat12(path);
39971
40033
  const content = await readFile12(path, "utf8").catch(() => "");
39972
40034
  const title = markdownMetadata(content).title;
39973
40035
  return {
@@ -39981,10 +40043,10 @@ async function shallowMetadata(folder) {
39981
40043
  };
39982
40044
  }));
39983
40045
  const projects = visible.filter((entry) => entry.isDirectory()).map((entry) => ({
39984
- id: createHash5("sha1").update(resolve16(folder, entry.name)).digest("hex"),
40046
+ id: createHash5("sha1").update(resolve17(folder, entry.name)).digest("hex"),
39985
40047
  name: entry.name,
39986
40048
  relativePath: entry.name,
39987
- worktree: resolve16(folder, entry.name)
40049
+ worktree: resolve17(folder, entry.name)
39988
40050
  })).sort((left, right) => left.name.localeCompare(right.name));
39989
40051
  return {
39990
40052
  changes: { items: [] },
@@ -40011,7 +40073,7 @@ async function loadFolderData(folder) {
40011
40073
  id: project.id,
40012
40074
  worktree: project.worktree,
40013
40075
  name: project.name ?? basename8(project.worktree),
40014
- relativePath: relative13(folder, project.worktree)
40076
+ relativePath: relative14(folder, project.worktree)
40015
40077
  }))
40016
40078
  }
40017
40079
  };
@@ -40019,10 +40081,10 @@ async function loadFolderData(folder) {
40019
40081
  async function notesFiles(folder, files, origin) {
40020
40082
  return {
40021
40083
  items: await Promise.all(files.map(async (file) => {
40022
- const path = file.path ?? (file.relativePath ? resolve16(folder, file.relativePath) : undefined);
40084
+ const path = file.path ?? (file.relativePath ? resolve17(folder, file.relativePath) : undefined);
40023
40085
  if (!path)
40024
40086
  return origin ? { ...file, folder: origin } : file;
40025
- const content = [".markdown", ".md"].includes(extname6(path).toLowerCase()) ? await readFile12(path, "utf8").catch(() => "") : "";
40087
+ const content = [".markdown", ".md"].includes(extname7(path).toLowerCase()) ? await readFile12(path, "utf8").catch(() => "") : "";
40026
40088
  const title = content ? markdownMetadata(content).title : undefined;
40027
40089
  return {
40028
40090
  ...file,
@@ -40047,8 +40109,8 @@ async function managedNotesFiles(directory) {
40047
40109
  }));
40048
40110
  }
40049
40111
  function insideFolder(path, root) {
40050
- const local = relative13(root, path);
40051
- return local === "" || !local.startsWith("..") && !isAbsolute7(local);
40112
+ const local = relative14(root, path);
40113
+ return local === "" || !local.startsWith("..") && !isAbsolute8(local);
40052
40114
  }
40053
40115
  async function withoutManagedFiles(items, managedRoot) {
40054
40116
  if (!managedRoot)
@@ -40079,16 +40141,16 @@ async function localProjectSearchCache(cache) {
40079
40141
  function mediaTarget(folder, file, lockedTarget) {
40080
40142
  if (!file)
40081
40143
  return;
40082
- const rootReal = realpathSync3(resolve16(folder));
40083
- const path = resolve16(folder, file);
40144
+ const rootReal = realpathSync3(resolve17(folder));
40145
+ const path = resolve17(folder, file);
40084
40146
  let pathReal;
40085
40147
  try {
40086
40148
  pathReal = realpathSync3(path);
40087
40149
  } catch {
40088
40150
  return;
40089
40151
  }
40090
- const rel = relative13(rootReal, pathReal);
40091
- if (rel.startsWith("..") || isAbsolute7(rel))
40152
+ const rel = relative14(rootReal, pathReal);
40153
+ if (rel.startsWith("..") || isAbsolute8(rel))
40092
40154
  return;
40093
40155
  if (lockedTarget && pathReal !== lockedTarget)
40094
40156
  return;
@@ -40127,16 +40189,16 @@ function documentError(response) {
40127
40189
  function documentTarget(folder, file, lockedTarget) {
40128
40190
  if (!file)
40129
40191
  return;
40130
- const rootReal = realpathSync3(resolve16(folder));
40131
- const path = resolve16(folder, file);
40192
+ const rootReal = realpathSync3(resolve17(folder));
40193
+ const path = resolve17(folder, file);
40132
40194
  let pathReal;
40133
40195
  try {
40134
40196
  pathReal = realpathSync3(path);
40135
40197
  } catch {
40136
40198
  return;
40137
40199
  }
40138
- const rel = relative13(rootReal, pathReal);
40139
- if (rel.startsWith("..") || isAbsolute7(rel))
40200
+ const rel = relative14(rootReal, pathReal);
40201
+ if (rel.startsWith("..") || isAbsolute8(rel))
40140
40202
  return;
40141
40203
  if (lockedTarget && pathReal !== lockedTarget)
40142
40204
  return;
@@ -40274,7 +40336,7 @@ function createFolderApi({
40274
40336
  if (!folder)
40275
40337
  return;
40276
40338
  server.emit({
40277
- data: { path: relative13(folder, path) },
40339
+ data: { path: relative14(folder, path) },
40278
40340
  event: "kennel:metadata-changed",
40279
40341
  type: "custom"
40280
40342
  });
@@ -40429,12 +40491,12 @@ function createFolderApi({
40429
40491
  }
40430
40492
  if (url.pathname === "/api/documents") {
40431
40493
  const folder = folderPath(url.searchParams.get("path"), root, lockedRoot);
40432
- const target = lockedTarget ? documentTarget(folder, relative13(folder, lockedTarget), lockedTarget) : undefined;
40494
+ const target = lockedTarget ? documentTarget(folder, relative14(folder, lockedTarget), lockedTarget) : undefined;
40433
40495
  const dataset = lockedTarget ? {
40434
40496
  root: folder,
40435
40497
  documents: target ? [
40436
40498
  {
40437
- path: relative13(folder, target.path),
40499
+ path: relative14(folder, target.path),
40438
40500
  kind: target.kind,
40439
40501
  content: previewTextKind(target.kind) ? await readFile12(target.path, "utf8") : ""
40440
40502
  }
@@ -40452,7 +40514,7 @@ function createFolderApi({
40452
40514
  documentError(response);
40453
40515
  return;
40454
40516
  }
40455
- const details = await stat11(target.path);
40517
+ const details = await stat12(target.path);
40456
40518
  if (!details.isFile()) {
40457
40519
  documentError(response);
40458
40520
  return;
@@ -40468,12 +40530,12 @@ function createFolderApi({
40468
40530
  sendContract(response, url, {
40469
40531
  content,
40470
40532
  kind: target.kind,
40471
- path: relative13(target.root, target.path),
40533
+ path: relative14(target.root, target.path),
40472
40534
  root: folder,
40473
40535
  ...previewTextKind(target.kind) ? {} : {
40474
40536
  rawUrl: `/api/raw?${new URLSearchParams({
40475
40537
  path: folder,
40476
- file: relative13(target.root, target.path)
40538
+ file: relative14(target.root, target.path)
40477
40539
  })}`
40478
40540
  }
40479
40541
  }, {
@@ -40493,7 +40555,7 @@ function createFolderApi({
40493
40555
  documentError(response);
40494
40556
  return;
40495
40557
  }
40496
- const details = await stat11(target.path);
40558
+ const details = await stat12(target.path);
40497
40559
  if (!details.isFile()) {
40498
40560
  documentError(response);
40499
40561
  return;
@@ -40531,7 +40593,7 @@ function createFolderApi({
40531
40593
  documentError(response);
40532
40594
  return;
40533
40595
  }
40534
- const details = await stat11(target.path);
40596
+ const details = await stat12(target.path);
40535
40597
  if (!details.isFile()) {
40536
40598
  documentError(response);
40537
40599
  return;
@@ -40652,6 +40714,19 @@ function createFolderApi({
40652
40714
  }))
40653
40715
  return;
40654
40716
  }
40717
+ if (url.pathname === "/api/delete-note") {
40718
+ if (remote) {
40719
+ response.writeHead(403, {
40720
+ "Content-Type": "text/plain; charset=utf-8"
40721
+ });
40722
+ response.end("Host actions are disabled for remote access");
40723
+ return;
40724
+ }
40725
+ await runApiRoute(request, response, url, deleteNoteRoute, {
40726
+ authorize: (folder) => folderPath(folder, root, lockedRoot)
40727
+ });
40728
+ return;
40729
+ }
40655
40730
  if (url.pathname === "/api/create-agent-file") {
40656
40731
  if (remote) {
40657
40732
  response.writeHead(403, {
@@ -40706,7 +40781,7 @@ function createFolderApi({
40706
40781
  workspace.breadcrumbs = await workspaceBreadcrumbIcons(workspace.breadcrumbs ?? [], assetFiles);
40707
40782
  const files = [
40708
40783
  workspace.configPath,
40709
- resolve16(workspace.root, "raggle.json")
40784
+ resolve17(workspace.root, "raggle.json")
40710
40785
  ].filter((path) => Boolean(path));
40711
40786
  for (const path of files)
40712
40787
  contexts.add(path);
@@ -40847,7 +40922,7 @@ function createFolderApi({
40847
40922
  }
40848
40923
  };
40849
40924
  }
40850
- var applyProjectFavorites, buildProjectCatalog, buildProjectSearchIndex, catalogProjectToLocalProject, discoverProjectIcon, discoverProjectsUnderFolder, listLocalMarkdownFiles, projectRepositoryAccessory, projectSubtitle, projectTitle, readRaggleUserSettings, gitRemoteUrl, githubRepositoryPath, repositoryDisplayName, searchProjectIndex, sortProjectList, projectSearchCacheMs = 5000, metadataExtensions, loopbackServerHosts, canonicalPath = (path) => realpath8(path).catch(() => path);
40925
+ var applyProjectFavorites, buildProjectCatalog, buildProjectSearchIndex, catalogProjectToLocalProject, discoverProjectIcon, discoverProjectsUnderFolder, listLocalMarkdownFiles, projectRepositoryAccessory, projectSubtitle, projectTitle, readRaggleUserSettings, gitRemoteUrl, githubRepositoryPath, repositoryDisplayName, searchProjectIndex, sortProjectList, projectSearchCacheMs = 5000, metadataExtensions, loopbackServerHosts, canonicalPath = (path) => realpath9(path).catch(() => path);
40851
40926
  var init_folder_metadata_plugin = __esm(() => {
40852
40927
  init_contracts();
40853
40928
  init_markdown();
@@ -40859,6 +40934,7 @@ var init_folder_metadata_plugin = __esm(() => {
40859
40934
  init_server2();
40860
40935
  init_store();
40861
40936
  init_entity_folder();
40937
+ init_delete_note();
40862
40938
  init_document_edit();
40863
40939
  init_create_agent_file();
40864
40940
  init_open_path();
@@ -40911,36 +40987,36 @@ var init_folder_metadata_plugin = __esm(() => {
40911
40987
  import {
40912
40988
  createServer
40913
40989
  } from "node:http";
40914
- import { readFile as readFile13, realpath as realpath9, stat as stat12 } from "node:fs/promises";
40915
- import { extname as extname7, isAbsolute as isAbsolute8, relative as relative14, resolve as resolve17 } from "node:path";
40990
+ import { readFile as readFile13, realpath as realpath10, stat as stat13 } from "node:fs/promises";
40991
+ import { extname as extname8, isAbsolute as isAbsolute9, relative as relative15, resolve as resolve18 } from "node:path";
40916
40992
  async function sendFile(request, response, directory, pathname, fallback) {
40917
- const root = await realpath9(directory);
40993
+ const root = await realpath10(directory);
40918
40994
  const inside = (path) => {
40919
- const local = relative14(root, path);
40920
- return local !== ".." && !local.startsWith("../") && !isAbsolute8(local);
40995
+ const local = relative15(root, path);
40996
+ return local !== ".." && !local.startsWith("../") && !isAbsolute9(local);
40921
40997
  };
40922
- let target = resolve17(root, `.${decodeURIComponent(pathname)}`);
40998
+ let target = resolve18(root, `.${decodeURIComponent(pathname)}`);
40923
40999
  if (!inside(target)) {
40924
41000
  response.writeHead(403);
40925
41001
  response.end();
40926
41002
  return;
40927
41003
  }
40928
- if (!(await stat12(target).catch(() => null))?.isFile()) {
41004
+ if (!(await stat13(target).catch(() => null))?.isFile()) {
40929
41005
  if (!fallback) {
40930
41006
  response.writeHead(404);
40931
41007
  response.end();
40932
41008
  return;
40933
41009
  }
40934
- target = resolve17(root, fallback);
41010
+ target = resolve18(root, fallback);
40935
41011
  }
40936
- target = await realpath9(target);
41012
+ target = await realpath10(target);
40937
41013
  if (!inside(target)) {
40938
41014
  response.writeHead(403);
40939
41015
  response.end();
40940
41016
  return;
40941
41017
  }
40942
41018
  response.writeHead(200, {
40943
- "Content-Type": contentTypes[extname7(target)] ?? "application/octet-stream",
41019
+ "Content-Type": contentTypes[extname8(target)] ?? "application/octet-stream",
40944
41020
  "X-Content-Type-Options": "nosniff"
40945
41021
  });
40946
41022
  response.end(request.method === "HEAD" ? undefined : await readFile13(target));
@@ -41116,7 +41192,7 @@ var init_server5 = __esm(() => {
41116
41192
  });
41117
41193
 
41118
41194
  // packages/preview/src/share.ts
41119
- import { dirname as dirname16, resolve as resolve19, join as join7 } from "node:path";
41195
+ import { dirname as dirname16, resolve as resolve20, join as join7 } from "node:path";
41120
41196
  import { homedir as homedir5 } from "node:os";
41121
41197
  import { readFileSync as readFileSync2 } from "node:fs";
41122
41198
  import { existsSync as existsSync8, realpathSync as realpathSync5 } from "node:fs";
@@ -41129,7 +41205,7 @@ init_runtime();
41129
41205
  import { execFileSync as execFileSync2 } from "node:child_process";
41130
41206
  import { existsSync as existsSync7, realpathSync as realpathSync4, statSync as statSync3 } from "node:fs";
41131
41207
  import { createServer as createServer2 } from "node:net";
41132
- import { dirname as dirname15, isAbsolute as isAbsolute9, relative as relative15, resolve as resolve18 } from "node:path";
41208
+ import { dirname as dirname15, isAbsolute as isAbsolute10, relative as relative16, resolve as resolve19 } from "node:path";
41133
41209
  import { fileURLToPath as fileURLToPath4 } from "node:url";
41134
41210
  var loopbackHosts = new Set([
41135
41211
  "127.0.0.1",
@@ -41215,7 +41291,7 @@ function splitViewerArgs(input) {
41215
41291
  }
41216
41292
  if (arg.startsWith("-"))
41217
41293
  throw new Error(`Unknown viewer option: ${arg}`);
41218
- const candidate = resolve18(arg);
41294
+ const candidate = resolve19(arg);
41219
41295
  const isDirectory = existsSync7(candidate) && statSync3(candidate).isDirectory();
41220
41296
  if (isDirectory) {
41221
41297
  if (hasRoot)
@@ -41263,7 +41339,7 @@ function popUrl(host, port, options) {
41263
41339
  const scheme = options.tailscale ? "https" : "http";
41264
41340
  const authority = options.tailscale ? host : `${host}:${port}`;
41265
41341
  return folderUrl(`${scheme}://${authority}/`, options.root, {
41266
- document: options.target ? relative15(options.root, options.target) : undefined,
41342
+ document: options.target ? relative16(options.root, options.target) : undefined,
41267
41343
  watch: options.watch
41268
41344
  }).href;
41269
41345
  }
@@ -41273,8 +41349,8 @@ function viewerPortWasExplicit(input) {
41273
41349
  function isSameOrDescendant(parent, child) {
41274
41350
  const parentReal = realpathSync4(parent);
41275
41351
  const childReal = realpathSync4(child);
41276
- const childRelative = relative15(parentReal, childReal);
41277
- return childRelative === "" || !childRelative.startsWith("..") && !isAbsolute9(childRelative);
41352
+ const childRelative = relative16(parentReal, childReal);
41353
+ return childRelative === "" || !childRelative.startsWith("..") && !isAbsolute10(childRelative);
41278
41354
  }
41279
41355
  async function runningViewer(url) {
41280
41356
  try {
@@ -41335,8 +41411,8 @@ async function viewer(input) {
41335
41411
  await hotViewer(options);
41336
41412
  return;
41337
41413
  }
41338
- const web = resolve18(dirname15(fileURLToPath4(import.meta.url)), "../../web");
41339
- if (!existsSync7(resolve18(web, "index.html"))) {
41414
+ const web = resolve19(dirname15(fileURLToPath4(import.meta.url)), "../../web");
41415
+ if (!existsSync7(resolve19(web, "index.html"))) {
41340
41416
  throw new Error(`Kennel web app not found. Run the CLI build first.`);
41341
41417
  }
41342
41418
  const remote = options.tailscale || !isLoopbackHost(options.host);
@@ -41551,7 +41627,7 @@ function splitShareArgs(input) {
41551
41627
  if (folder && !existsSync8(folder)) {
41552
41628
  throw new Error(`Folder not found: ${folder}`);
41553
41629
  }
41554
- options.folder = folder ? resolve19(folder) : undefined;
41630
+ options.folder = folder ? resolve20(folder) : undefined;
41555
41631
  return options;
41556
41632
  }
41557
41633
  async function runningViewerRoot(port = plainViewerPort) {
@@ -41579,8 +41655,8 @@ async function startPreviewShare(target) {
41579
41655
  configuredPassword = config.linkSharing?.password === true;
41580
41656
  } catch {}
41581
41657
  const password = target.password ?? configuredPassword;
41582
- const web = resolve19(dirname16(fileURLToPath5(import.meta.url)), "../../web");
41583
- if (!existsSync8(resolve19(web, "index.html"))) {
41658
+ const web = resolve20(dirname16(fileURLToPath5(import.meta.url)), "../../web");
41659
+ if (!existsSync8(resolve20(web, "index.html"))) {
41584
41660
  throw new Error("Kennel web app not found. Run the CLI build first.");
41585
41661
  }
41586
41662
  const host = await tailscaleHostname();