volute 0.40.0 → 0.40.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (164) hide show
  1. package/README.md +2 -2
  2. package/dist/{accept-AHAOUFBK.js → accept-IVHOHXQS.js} +1 -1
  3. package/dist/{activity-events-OJZ7G5CG.js → activity-events-DS4QRWBY.js} +4 -4
  4. package/dist/{ai-service-JMV4KZN4.js → ai-service-EVLKMAJD.js} +5 -5
  5. package/dist/{api-client-LC5YRA32.js → api-client-NFM6GX2N.js} +1 -1
  6. package/dist/{archive-BC2MTNPV.js → archive-UDHFZN4G.js} +4 -4
  7. package/dist/{auth-2IMZ6N5G.js → auth-X6ZITZ7D.js} +5 -5
  8. package/dist/{bridge-F3ZJEKDN.js → bridge-MSZC4HUT.js} +1 -1
  9. package/dist/{chat-O5QCGCUG.js → chat-F2EEN76G.js} +9 -9
  10. package/dist/{chunk-MHFAWJCC.js → chunk-2HZRJ35V.js} +1 -1
  11. package/dist/{chunk-B7YJUWMM.js → chunk-3Y7UDHO7.js} +3 -3
  12. package/dist/{chunk-RMZSICLS.js → chunk-42UMLIQR.js} +20 -21
  13. package/dist/{chunk-SGC6CDXB.js → chunk-4UMXOMZ6.js} +2 -2
  14. package/dist/{chunk-FBV22PFY.js → chunk-6SYHHEQ7.js} +1 -1
  15. package/dist/{chunk-3XSFMN3H.js → chunk-AEAZRTEV.js} +1 -1
  16. package/dist/{chunk-PDSA3ILI.js → chunk-B4WPXYPI.js} +1 -1
  17. package/dist/{chunk-2AQCEQYN.js → chunk-DNU6XLE2.js} +1 -1
  18. package/dist/{chunk-PHR4XQPL.js → chunk-E25SO3QW.js} +3 -3
  19. package/dist/{chunk-76Q6YLJL.js → chunk-I57LLNAQ.js} +1 -1
  20. package/dist/{chunk-HAJHDGBV.js → chunk-ITH5ZLZJ.js} +1 -1
  21. package/dist/{chunk-SOPMVTTW.js → chunk-JYQQDI3M.js} +2 -2
  22. package/dist/{chunk-PIRL2HAO.js → chunk-KMHC36CA.js} +1 -1
  23. package/dist/chunk-LMMQX4CK.js +49 -0
  24. package/dist/{chunk-FRJ73IWR.js → chunk-MNUXL4XN.js} +67 -3
  25. package/dist/{chunk-PC55DGNX.js → chunk-NERYUSER.js} +1 -1
  26. package/dist/{chunk-WGRMLXTH.js → chunk-NRJ3ZYFP.js} +10 -10
  27. package/dist/{chunk-43PVCF4V.js → chunk-PEKG3GNZ.js} +3 -3
  28. package/dist/{chunk-S4YO5OWV.js → chunk-PKGA23XM.js} +1 -1
  29. package/dist/{chunk-5VBXKFPO.js → chunk-QYI65HCL.js} +2 -2
  30. package/dist/{chunk-HEZM5GCV.js → chunk-SVXOBKQY.js} +2 -2
  31. package/dist/{chunk-PZTVQL3J.js → chunk-TOANT6FD.js} +2 -2
  32. package/dist/{chunk-T26YLQPU.js → chunk-UX7FPDDO.js} +5 -5
  33. package/dist/{chunk-JSITYTIL.js → chunk-WOWRLBL2.js} +10 -8
  34. package/dist/{chunk-DNQPHLGM.js → chunk-YHWGN4FX.js} +1 -1
  35. package/dist/chunk-YMMYN2V3.js +1212 -0
  36. package/dist/{chunk-XUJR6NZW.js → chunk-ZOI6D2YH.js} +194 -1313
  37. package/dist/{chunk-PGX52NFO.js → chunk-ZXPWTH4I.js} +43 -35
  38. package/dist/cli.js +24 -24
  39. package/dist/{clock-BMLJ2TR6.js → clock-YLDJUKBW.js} +3 -3
  40. package/dist/{cloud-sync-5JF2Z7VM.js → cloud-sync-GOSJZIHH.js} +18 -17
  41. package/dist/{config-QB7W3Z7P.js → config-PO4EZLIK.js} +4 -4
  42. package/dist/connectors/discord-bridge.js +1 -1
  43. package/dist/connectors/slack-bridge.js +1 -1
  44. package/dist/connectors/telegram-bridge.js +1 -1
  45. package/dist/{conversations-LUVHGQSS.js → conversations-AYLXPOGC.js} +5 -5
  46. package/dist/{create-TDQM3SHV.js → create-Y3RGU2GI.js} +5 -5
  47. package/dist/{create-C3BBFYV7.js → create-ZMTGINV3.js} +1 -1
  48. package/dist/{daemon-client-2MIPKY3E.js → daemon-client-H6MEKK2W.js} +1 -1
  49. package/dist/{daemon-restart-XHDJDOPQ.js → daemon-restart-FSWVXPUE.js} +9 -9
  50. package/dist/daemon.js +318 -280
  51. package/dist/{db-IJL6B26S.js → db-FSYOTHSN.js} +1 -1
  52. package/dist/db-ZEPKEJJD.js +9 -0
  53. package/dist/{delete-NLXES2C7.js → delete-TXVOH2OC.js} +3 -3
  54. package/dist/delivery-manager-3NTCDKHR.js +33 -0
  55. package/dist/{delivery-router-IU4OMVKZ.js → delivery-router-T6CYTS3M.js} +4 -4
  56. package/dist/down-6DYO2QV7.js +17 -0
  57. package/dist/echo-text-JUNRP4ER.js +32 -0
  58. package/dist/{env-IQ6Q2333.js → env-77IOWG4U.js} +1 -1
  59. package/dist/exec-5DGKQ5V3.js +17 -0
  60. package/dist/{export-RKUWSQSG.js → export-TZKOCSCE.js} +6 -6
  61. package/dist/{extension-LZYHBNLV.js → extension-35NB6GHW.js} +1 -1
  62. package/dist/{extensions-VN5SEVRP.js → extensions-MD757RFY.js} +18 -17
  63. package/dist/{files-J2CKZ6PK.js → files-WNNVJWJB.js} +4 -4
  64. package/dist/{import-KVY6BYXG.js → import-BNNFCQ7U.js} +11 -11
  65. package/dist/{isolation-MM7YHK6J.js → isolation-4Q4P7HRV.js} +4 -4
  66. package/dist/{join-6SZCA5FX.js → join-E2EJEXZO.js} +3 -3
  67. package/dist/{list-KHJZJPEJ.js → list-BYCEDASJ.js} +1 -1
  68. package/dist/{login-GYTH67ES.js → login-JNSIYFVH.js} +1 -1
  69. package/dist/{login-OHM32QVD.js → login-Y6UAYQVO.js} +3 -3
  70. package/dist/{logout-YHQLOFLR.js → logout-M6FI62BL.js} +1 -1
  71. package/dist/{logout-74WBDMOE.js → logout-VHGWVH63.js} +3 -3
  72. package/dist/message-delivery-Q7TU24IA.js +41 -0
  73. package/dist/{mind-PUPXDIYQ.js → mind-OOB2LEVC.js} +19 -19
  74. package/dist/{mind-activity-tracker-7GE24YZE.js → mind-activity-tracker-GJ5RJS32.js} +5 -5
  75. package/dist/{mind-history-WHCNZ6I5.js → mind-history-W4JPTPTV.js} +1 -1
  76. package/dist/{mind-list-H3HC2ZRG.js → mind-list-QROHCLGT.js} +1 -1
  77. package/dist/mind-manager-4NFK4GEU.js +31 -0
  78. package/dist/{mind-profile-7VYRJGFZ.js → mind-profile-3LNKXNPA.js} +2 -2
  79. package/dist/mind-service-X7FH3NA4.js +37 -0
  80. package/dist/{mind-sleep-ZL5ZXFTM.js → mind-sleep-PVCMLTAH.js} +1 -1
  81. package/dist/{mind-status-ZWULKOUO.js → mind-status-RAJFLRCN.js} +1 -1
  82. package/dist/{mind-wake-HK5ORGUK.js → mind-wake-HZUOVE7J.js} +1 -1
  83. package/dist/{package-6YPVWGD3.js → package-PPA3VWS2.js} +28 -27
  84. package/dist/{read-CP7MYMJQ.js → read-OOINVR2H.js} +1 -1
  85. package/dist/{read-stdin-4B5UYPPM.js → read-stdin-P6HCZUAA.js} +1 -1
  86. package/dist/{register-XOBFEMI4.js → register-ISOH34RF.js} +1 -1
  87. package/dist/{registry-L272BZJR.js → registry-GV35XFT7.js} +3 -3
  88. package/dist/{reject-43AGXB6B.js → reject-ZBWP62X5.js} +1 -1
  89. package/dist/{restart-O5QIYQJT.js → restart-QBJV5455.js} +1 -1
  90. package/dist/{sandbox-BQAFYHLE.js → sandbox-5R32QKWQ.js} +5 -5
  91. package/dist/scheduler-PDARH4CE.js +31 -0
  92. package/dist/{schema-HHYJDG7B.js → schema-LYQUDL7G.js} +2 -2
  93. package/dist/{seed-4V2O7FQE.js → seed-BTAHXCO5.js} +2 -2
  94. package/dist/{seed-check-HZPVFJKZ.js → seed-check-3WXXRHTC.js} +2 -2
  95. package/dist/{seed-cmd-JKDEW4MP.js → seed-cmd-VEJNJBAQ.js} +4 -4
  96. package/dist/{seed-create-EPAO3H5F.js → seed-create-LOU5RALI.js} +7 -7
  97. package/dist/{seed-sprout-EONCL4DU.js → seed-sprout-BXF5TBXD.js} +11 -11
  98. package/dist/{send-232RAHPX.js → send-WO3CVG73.js} +4 -4
  99. package/dist/{service-AG5BKRUV.js → service-WMV6R6VJ.js} +6 -6
  100. package/dist/service-install-W3FQXJKB.js +17 -0
  101. package/dist/{setup-IL7QJZN4.js → setup-OTEC3ZPM.js} +4 -4
  102. package/dist/{setup-PSA7LJ5U.js → setup-W3545462.js} +9 -9
  103. package/dist/{skill-ICN6Y2ZF.js → skill-QHACP7EU.js} +1 -1
  104. package/dist/{skills-SLEY5X6W.js → skills-3P7VQA4U.js} +7 -7
  105. package/dist/sleep-manager-TTNOLIX5.js +35 -0
  106. package/dist/{spirit-7BUHSEO2.js → spirit-T6GK5GEP.js} +9 -9
  107. package/dist/{split-5YBEQTBF.js → split-7AO4IO42.js} +3 -3
  108. package/dist/{sprout-JWQ57KF3.js → sprout-AQICF7WZ.js} +2 -2
  109. package/dist/{src-OYWRPLC6.js → src-2IMB3V27.js} +1 -1
  110. package/dist/src-OS75U2O7.js +241910 -0
  111. package/dist/{src-O4PRLMKM.js → src-XNUXP2FP.js} +1 -1
  112. package/dist/{start-LMXXRR3X.js → start-2U57BBK7.js} +1 -1
  113. package/dist/{status-6GSOSYOD.js → status-BRYYYO7C.js} +7 -7
  114. package/dist/{stop-TWDKVEUX.js → stop-QILBDUAR.js} +1 -1
  115. package/dist/system-chat-7CA2PP6A.js +35 -0
  116. package/dist/{systems-Y2WZV2K4.js → systems-3XTAHA35.js} +4 -4
  117. package/dist/{tailscale-6MHNLBAX.js → tailscale-X4HRKRTW.js} +3 -3
  118. package/dist/{template-hash-SSIBEEYK.js → template-hash-DMHSLRDX.js} +1 -1
  119. package/dist/turn-tracker-AI6WWEBA.js +35 -0
  120. package/dist/up-PKNNDN6M.js +19 -0
  121. package/dist/{update-BT2PY73H.js → update-OY2JYXYK.js} +61 -14
  122. package/dist/update-check-IUB7QHAF.js +24 -0
  123. package/dist/{upgrade-RXFZR5FI.js → upgrade-25J6AE47.js} +3 -3
  124. package/dist/{variant-HHDTW74J.js → variant-5LQOPCQA.js} +1 -1
  125. package/dist/{version-notify-NFQMI5IY.js → version-notify-DK6AHWX7.js} +19 -18
  126. package/dist/{volute-config-TS62GS6A.js → volute-config-7FO6QKWU.js} +1 -1
  127. package/dist/web-assets/assets/index-DaUp9iE2.js +79 -0
  128. package/dist/web-assets/index.html +1 -1
  129. package/package.json +27 -26
  130. package/packages/extensions/notes/dist/ui/assets/index-BbgANhFm.js +67 -0
  131. package/packages/extensions/notes/dist/ui/index.html +1 -1
  132. package/packages/extensions/pages/dist/ui/assets/index-Dxk-DYrf.js +2 -0
  133. package/packages/extensions/pages/dist/ui/index.html +1 -1
  134. package/packages/extensions/plan/dist/ui/assets/index-Cfzs-0G9.js +67 -0
  135. package/packages/extensions/plan/dist/ui/index.html +1 -1
  136. package/templates/claude/package.json.tmpl +5 -5
  137. package/templates/codex/package.json.tmpl +5 -5
  138. package/templates/pi/package.json.tmpl +7 -6
  139. package/templates/pi/src/agent.ts +3 -1
  140. package/templates/pi/src/lib/content.ts +1 -1
  141. package/templates/pi/src/lib/event-handler.ts +1 -1
  142. package/templates/pi/src/lib/reply-instructions-extension.ts +1 -1
  143. package/templates/pi/src/lib/resolve-model.ts +4 -4
  144. package/templates/pi/src/lib/subagents.ts +21 -19
  145. package/dist/chunk-K3NQKI34.js +0 -10
  146. package/dist/db-2GIS7HSG.js +0 -9
  147. package/dist/delivery-manager-L5WFP2ND.js +0 -30
  148. package/dist/down-KIJVZ3OC.js +0 -17
  149. package/dist/echo-text-TJWCUBPB.js +0 -31
  150. package/dist/exec-BGMU7VXR.js +0 -17
  151. package/dist/message-delivery-VBBAJX3J.js +0 -40
  152. package/dist/mind-manager-4Q6KGZHL.js +0 -30
  153. package/dist/mind-service-7OD4PRO5.js +0 -36
  154. package/dist/scheduler-7E22Q7IC.js +0 -30
  155. package/dist/service-install-HVAEUBAH.js +0 -17
  156. package/dist/sleep-manager-27S7MKJO.js +0 -34
  157. package/dist/src-6Z4XYDH5.js +0 -2164
  158. package/dist/system-chat-EIINIHFB.js +0 -34
  159. package/dist/up-4XS3RCPP.js +0 -19
  160. package/dist/update-check-Y3HBEMF2.js +0 -18
  161. package/dist/web-assets/assets/index-Jluza4c-.js +0 -73
  162. package/packages/extensions/notes/dist/ui/assets/index-Dsua7alJ.js +0 -61
  163. package/packages/extensions/pages/dist/ui/assets/index-BM7gRdg7.js +0 -2
  164. package/packages/extensions/plan/dist/ui/assets/index-DWiqtzBv.js +0 -61
@@ -1,2164 +0,0 @@
1
- #!/usr/bin/env node
2
- import {
3
- getAllSites,
4
- getPublishedPages,
5
- getRecentPages,
6
- getSystemPages,
7
- initDb,
8
- syncPublishedPages,
9
- syncSystemPages
10
- } from "./chunk-QHG4OMZL.js";
11
- import {
12
- createExtension
13
- } from "./chunk-RG5TOL4O.js";
14
- import "./chunk-K3NQKI34.js";
15
-
16
- // packages/extensions/pages/src/index.ts
17
- import { resolve as resolve5 } from "path";
18
-
19
- // packages/extensions/pages/src/commands.ts
20
- import { cpSync, existsSync as existsSync2, readdirSync as readdirSync2, readFileSync as readFileSync2, rmSync as rmSync2, statSync as statSync2 } from "fs";
21
- import { relative as relative2, resolve as resolve2 } from "path";
22
-
23
- // packages/extensions/pages/src/shared-pages.ts
24
- import { execFile as execFileCb } from "child_process";
25
- import {
26
- chmodSync,
27
- existsSync,
28
- mkdirSync,
29
- readdirSync,
30
- readFileSync,
31
- rmSync,
32
- statSync,
33
- writeFileSync
34
- } from "fs";
35
- import { relative, resolve } from "path";
36
- function isolationFrom(ctx) {
37
- return { isIsolationEnabled: ctx.isIsolationEnabled, getMindUser: ctx.getMindUser };
38
- }
39
- function execAsync(cmd, args) {
40
- return new Promise((resolve6, reject) => {
41
- execFileCb(cmd, args, (err) => {
42
- if (err) reject(err);
43
- else resolve6();
44
- });
45
- });
46
- }
47
- function gitExec(args, opts, isolation) {
48
- const fullArgs = isolation?.isIsolationEnabled() ? ["-c", "safe.directory=*", ...args] : args;
49
- return new Promise((resolve6, reject) => {
50
- execFileCb("git", fullArgs, { cwd: opts.cwd }, (err, stdout, stderr) => {
51
- if (err) {
52
- const e = err;
53
- e.stderr = stderr;
54
- e.stdout = stdout;
55
- reject(err);
56
- } else {
57
- resolve6(stdout);
58
- }
59
- });
60
- });
61
- }
62
- function readWorktreeGitDir(worktreePath2) {
63
- const dotGit = resolve(worktreePath2, ".git");
64
- if (!existsSync(dotGit)) return null;
65
- try {
66
- const content = readFileSync(dotGit, "utf-8").trim();
67
- const match = content.match(/^gitdir:\s*(.+)$/);
68
- return match ? match[1] : null;
69
- } catch (err) {
70
- console.warn(`[pages] failed to read .git file at ${dotGit}: ${err.message}`);
71
- return null;
72
- }
73
- }
74
- function pagesRepoDir(dataDir) {
75
- return resolve(dataDir, "repo");
76
- }
77
- function worktreePath(mindDir) {
78
- return resolve(mindDir, "home", "pages", "_system");
79
- }
80
- async function ensurePagesRepo(dataDir, isolation) {
81
- const dir = pagesRepoDir(dataDir);
82
- mkdirSync(dir, { recursive: true });
83
- if (existsSync(resolve(dir, ".git"))) {
84
- try {
85
- await gitExec(["rev-parse", "HEAD"], { cwd: dir }, isolation);
86
- return;
87
- } catch (err) {
88
- const msg = err instanceof Error ? err.message : String(err);
89
- if (msg.includes("unknown revision") || msg.includes("bad default revision")) {
90
- console.warn("[pages] repo has no commits, re-initializing");
91
- rmSync(resolve(dir, ".git"), { recursive: true, force: true });
92
- } else {
93
- throw err;
94
- }
95
- }
96
- }
97
- const isIso = isolation?.isIsolationEnabled() ?? false;
98
- const initArgs = isIso ? ["init", "--shared=group"] : ["init"];
99
- await gitExec(initArgs, { cwd: dir }, isolation);
100
- await gitExec(["checkout", "-b", "main"], { cwd: dir }, isolation);
101
- writeFileSync(resolve(dir, ".gitkeep"), "");
102
- await gitExec(["add", "-A"], { cwd: dir }, isolation);
103
- await gitExec(["commit", "-m", "init pages repo"], { cwd: dir }, isolation);
104
- if (isIso) {
105
- try {
106
- await execAsync("chgrp", ["-R", "volute", dir]);
107
- } catch {
108
- console.warn("[pages] failed to chgrp pages repo to volute group");
109
- }
110
- chmodSync(dir, 1533);
111
- }
112
- }
113
- async function addPagesWorktree(mindName, mindDir, dataDir, isolation) {
114
- const dir = pagesRepoDir(dataDir);
115
- if (!existsSync(resolve(dir, ".git"))) return;
116
- const wt = worktreePath(mindDir);
117
- if (existsSync(wt)) return;
118
- mkdirSync(resolve(mindDir, "home", "pages"), { recursive: true });
119
- let branchExists = false;
120
- try {
121
- await gitExec(["rev-parse", "--verify", mindName], { cwd: dir }, isolation);
122
- branchExists = true;
123
- } catch {
124
- }
125
- if (branchExists) {
126
- await gitExec(["worktree", "add", wt, mindName], { cwd: dir }, isolation);
127
- } else {
128
- await gitExec(["worktree", "add", "-b", mindName, wt], { cwd: dir }, isolation);
129
- }
130
- if (isolation?.isIsolationEnabled()) {
131
- const user = isolation.getMindUser(mindName);
132
- try {
133
- await execAsync("chown", ["-R", `${user}:volute`, wt]);
134
- } catch {
135
- console.warn(`[pages] failed to chown worktree for ${mindName}`);
136
- }
137
- const wtGitDir = readWorktreeGitDir(wt);
138
- if (wtGitDir) {
139
- try {
140
- await execAsync("chown", ["-R", `${user}:volute`, wtGitDir]);
141
- } catch {
142
- console.warn(`[pages] failed to chown worktree git dir for ${mindName}`);
143
- }
144
- }
145
- }
146
- }
147
- var pagesLock = Promise.resolve();
148
- async function withPagesLock(fn) {
149
- const prev = pagesLock;
150
- let resolve_;
151
- pagesLock = new Promise((r) => {
152
- resolve_ = r;
153
- });
154
- await prev;
155
- try {
156
- return await fn();
157
- } finally {
158
- resolve_();
159
- }
160
- }
161
- async function pagesPull(mindName, mindDir, isolation) {
162
- return withPagesLock(async () => {
163
- const wt = worktreePath(mindDir);
164
- const status = (await gitExec(["status", "--porcelain"], { cwd: wt }, isolation)).trim();
165
- if (status) {
166
- await gitExec(["add", "-A"], { cwd: wt }, isolation);
167
- await gitExec(
168
- ["commit", "--author", `${mindName} <${mindName}@volute>`, "-m", `wip: ${mindName}`],
169
- { cwd: wt },
170
- isolation
171
- );
172
- }
173
- try {
174
- await gitExec(["rebase", "main"], { cwd: wt }, isolation);
175
- } catch (err) {
176
- const errMsg = err instanceof Error ? err.message : String(err);
177
- const isConflict = errMsg.includes("CONFLICT") || errMsg.includes("could not apply") || errMsg.includes("merge conflict");
178
- try {
179
- await gitExec(["rebase", "--abort"], { cwd: wt }, isolation);
180
- } catch (abortErr) {
181
- console.error("[pages] rebase abort failed", abortErr);
182
- }
183
- if (isConflict) {
184
- return {
185
- ok: false,
186
- conflicts: true,
187
- message: "Pull conflicts detected \u2014 your changes conflict with main. Reconcile the conflicting files, commit, and pull again."
188
- };
189
- }
190
- console.error("[pages] pull rebase failed", err);
191
- return { ok: false, message: `Pull failed: ${errMsg}` };
192
- }
193
- if (isolation?.isIsolationEnabled()) {
194
- try {
195
- await execAsync("chown", ["-R", `${isolation.getMindUser(mindName)}:volute`, wt]);
196
- } catch {
197
- }
198
- }
199
- return { ok: true, message: "Pulled latest shared changes." };
200
- });
201
- }
202
- async function pagesPullAndMerge(mindName, mindDir, dataDir, message, isolation) {
203
- return withPagesLock(async () => {
204
- const wt = worktreePath(mindDir);
205
- const dir = pagesRepoDir(dataDir);
206
- const status = (await gitExec(["status", "--porcelain"], { cwd: wt }, isolation)).trim();
207
- if (status) {
208
- await gitExec(["add", "-A"], { cwd: wt }, isolation);
209
- await gitExec(
210
- ["commit", "--author", `${mindName} <${mindName}@volute>`, "-m", `wip: ${mindName}`],
211
- { cwd: wt },
212
- isolation
213
- );
214
- }
215
- try {
216
- await gitExec(["rebase", "main"], { cwd: wt }, isolation);
217
- } catch (err) {
218
- const errMsg = err instanceof Error ? err.message : String(err);
219
- const isConflict = errMsg.includes("CONFLICT") || errMsg.includes("could not apply") || errMsg.includes("merge conflict");
220
- try {
221
- await gitExec(["rebase", "--abort"], { cwd: wt }, isolation);
222
- } catch (abortErr) {
223
- console.error("[pages] rebase abort failed", abortErr);
224
- }
225
- if (isConflict) {
226
- return {
227
- ok: false,
228
- conflicts: true,
229
- message: "Pull conflicts detected \u2014 your changes conflict with main. Reconcile the conflicting files, commit, and try again."
230
- };
231
- }
232
- return { ok: false, message: `Pull failed: ${errMsg}` };
233
- }
234
- const diff = (await gitExec(["diff", `main...${mindName}`, "--stat"], { cwd: dir }, isolation)).trim();
235
- if (!diff) {
236
- return { ok: true, message: "Nothing to publish" };
237
- }
238
- try {
239
- await gitExec(["merge", "--squash", mindName], { cwd: dir }, isolation);
240
- } catch (err) {
241
- const errOutput = [
242
- err.message,
243
- err.stderr ?? "",
244
- err.stdout ?? ""
245
- ].join("\n");
246
- const isConflict = errOutput.includes("CONFLICT") || errOutput.includes("could not apply");
247
- try {
248
- await gitExec(["reset", "--hard", "HEAD"], { cwd: dir }, isolation);
249
- } catch (resetErr) {
250
- console.error("[pages] reset after squash conflict failed", resetErr);
251
- }
252
- if (isConflict) {
253
- return { ok: false, conflicts: true, message: "Merge conflicts detected" };
254
- }
255
- return { ok: false, message: `Merge failed: ${err.message}` };
256
- }
257
- await gitExec(
258
- ["commit", "--author", `${mindName} <${mindName}@volute>`, "-m", message],
259
- { cwd: dir },
260
- isolation
261
- );
262
- try {
263
- await gitExec(["reset", "--hard", "main"], { cwd: wt }, isolation);
264
- } catch (err) {
265
- console.error(`[pages] branch reset failed for ${mindName}`, err);
266
- return {
267
- ok: true,
268
- message: "Published to main, but branch reset failed \u2014 run 'volute pages pull' to sync"
269
- };
270
- }
271
- if (isolation?.isIsolationEnabled()) {
272
- try {
273
- await execAsync("chown", ["-R", `${isolation.getMindUser(mindName)}:volute`, wt]);
274
- } catch {
275
- }
276
- }
277
- return { ok: true };
278
- });
279
- }
280
- function collectHtmlFiles(dir) {
281
- const files = [];
282
- function walk(d) {
283
- let items;
284
- try {
285
- items = readdirSync(d);
286
- } catch (err) {
287
- if (err?.code === "ENOENT") return;
288
- throw err;
289
- }
290
- for (const item of items) {
291
- if (item.startsWith(".")) continue;
292
- const full = resolve(d, item);
293
- try {
294
- const s = statSync(full);
295
- if (s.isFile() && item.endsWith(".html")) {
296
- files.push(relative(dir, full));
297
- } else if (s.isDirectory()) {
298
- walk(full);
299
- }
300
- } catch (err) {
301
- if (err?.code === "ENOENT" || err?.code === "EACCES") continue;
302
- throw err;
303
- }
304
- }
305
- }
306
- walk(dir);
307
- return files.sort();
308
- }
309
- async function pagesStatus(mindDir, isolation) {
310
- const wt = worktreePath(mindDir);
311
- const errors = [];
312
- const [mainFiles, branchFiles, uncommitted] = await Promise.all([
313
- gitExec(["ls-tree", "-r", "--name-only", "main"], { cwd: wt }, isolation).then((s) => s.trim().split("\n").filter(Boolean)).catch((err) => {
314
- errors.push(err);
315
- return [];
316
- }),
317
- gitExec(["ls-tree", "-r", "--name-only", "HEAD"], { cwd: wt }, isolation).then((s) => s.trim().split("\n").filter(Boolean)).catch((err) => {
318
- errors.push(err);
319
- return [];
320
- }),
321
- gitExec(["status", "--porcelain"], { cwd: wt }, isolation).then((s) => s.trim()).catch((err) => {
322
- errors.push(err);
323
- return "";
324
- })
325
- ]);
326
- if (errors.length === 3) {
327
- throw new Error(`Shared pages git error: ${errors[0].message}`);
328
- }
329
- const uncommittedFiles = /* @__PURE__ */ new Set();
330
- if (uncommitted) {
331
- for (const line of uncommitted.split("\n")) {
332
- const match = line.match(/^.{2}\s+(.+)$/);
333
- if (match) uncommittedFiles.add(match[1]);
334
- }
335
- }
336
- const mainSet = new Set(mainFiles.filter((f) => f.endsWith(".html")));
337
- const allHtml = /* @__PURE__ */ new Set([
338
- ...mainFiles.filter((f) => f.endsWith(".html")),
339
- ...branchFiles.filter((f) => f.endsWith(".html")),
340
- ...[...uncommittedFiles].filter((f) => f.endsWith(".html"))
341
- ]);
342
- if (allHtml.size === 0) return "No shared pages found.";
343
- const lines = [...allHtml].sort().map((file) => {
344
- const onMain = mainSet.has(file);
345
- const isUncommitted = uncommittedFiles.has(file);
346
- let status;
347
- if (isUncommitted) {
348
- status = "uncommitted";
349
- } else if (onMain) {
350
- status = "published";
351
- } else {
352
- status = "draft";
353
- }
354
- return `${status.padEnd(13)} ${file}`;
355
- });
356
- return lines.join("\n");
357
- }
358
- async function pagesLog(mindDir, limit = 20, isolation) {
359
- const wt = worktreePath(mindDir);
360
- const output = (await gitExec(["log", "--oneline", "main", `-${limit}`], { cwd: wt }, isolation)).trim();
361
- return output || "No history.";
362
- }
363
-
364
- // packages/extensions/pages/src/commands.ts
365
- function createCommands() {
366
- return {
367
- publish: {
368
- description: "Publish all pages (copy to public snapshot)",
369
- args: [{ name: "message", description: "Commit message for shared publish" }],
370
- flags: {
371
- remote: { type: "boolean", description: "Also publish to volute.systems" },
372
- shared: { type: "boolean", description: "Publish to shared pages repository" }
373
- },
374
- handler: async ({ args, flags }, ctx) => {
375
- const mindName = ctx.mindName;
376
- if (!mindName) return { error: "No mind specified (use --mind or VOLUTE_MIND)" };
377
- if (flags.shared) {
378
- const mindDir2 = ctx.getMindDir(mindName);
379
- if (!mindDir2) return { error: `Mind not found: ${mindName}` };
380
- const message = args.message?.trim();
381
- if (!message)
382
- return { error: 'Usage: volute pages publish --shared "description of changes"' };
383
- try {
384
- const result = await pagesPullAndMerge(
385
- mindName,
386
- mindDir2,
387
- ctx.dataDir,
388
- message,
389
- isolationFrom(ctx)
390
- );
391
- if (!result.ok) {
392
- return {
393
- error: result.message || "Merge conflicts detected \u2014 pull, reconcile, and try again."
394
- };
395
- }
396
- let syncWarning = "";
397
- if (result.ok && ctx.db) {
398
- const repoDir = resolve2(ctx.dataDir, "repo");
399
- try {
400
- syncSystemPages(ctx.db, collectHtmlFiles(repoDir), mindName);
401
- } catch (err) {
402
- console.error("[pages] failed to sync system pages to DB:", err);
403
- syncWarning = "\nWarning: failed to sync pages to dashboard \u2014 they may not appear in the UI until the next daemon restart.";
404
- }
405
- }
406
- return { output: (result.message || "Published shared pages.") + syncWarning };
407
- } catch (err) {
408
- return { error: `Shared publish failed: ${err.message}` };
409
- }
410
- }
411
- const remote = flags.remote;
412
- const mindDir = ctx.getMindDir(mindName);
413
- if (!mindDir) return { error: `Mind not found: ${mindName}` };
414
- const sourceDir = resolve2(mindDir, "home", "pages");
415
- if (!existsSync2(sourceDir)) return { error: "No pages directory found (home/pages/)" };
416
- const db = ctx.db;
417
- if (!db) return { error: "Database not available" };
418
- const snapshotDir = resolve2(ctx.dataDir, "sites", mindName);
419
- try {
420
- if (existsSync2(snapshotDir)) rmSync2(snapshotDir, { recursive: true });
421
- cpSync(sourceDir, snapshotDir, {
422
- recursive: true,
423
- filter: (src) => !src.endsWith("/_system") && !src.includes("/_system/")
424
- });
425
- } catch (err) {
426
- return { error: `Failed to publish snapshot: ${err.message}` };
427
- }
428
- const pageFiles = collectFiles(snapshotDir, snapshotDir, [".html", ".md"]);
429
- let diff;
430
- try {
431
- diff = syncPublishedPages(db, mindName, pageFiles);
432
- } catch (err) {
433
- return { error: `Failed to update page database: ${err.message}` };
434
- }
435
- for (const file of diff.added) {
436
- ctx.publishActivity({
437
- type: "page_published",
438
- mind: mindName,
439
- summary: `${mindName} published ${file}`,
440
- metadata: { file, iframeUrl: `/ext/pages/public/${mindName}/${file}` }
441
- });
442
- }
443
- for (const file of diff.removed) {
444
- ctx.publishActivity({
445
- type: "page_removed",
446
- mind: mindName,
447
- summary: `${mindName} removed ${file}`,
448
- metadata: { file }
449
- });
450
- }
451
- let output = `Published ${pageFiles.length} files`;
452
- const parts = [];
453
- if (diff.added.length > 0) parts.push(`${diff.added.length} new`);
454
- if (diff.updated.length > 0) parts.push(`${diff.updated.length} updated`);
455
- if (diff.removed.length > 0) parts.push(`${diff.removed.length} removed`);
456
- if (parts.length > 0) output += ` (${parts.join(", ")})`;
457
- if (remote) {
458
- const config = ctx.getSystemsConfig();
459
- if (!config)
460
- return {
461
- error: "Not connected to volute.systems. Run volute systems register or login first."
462
- };
463
- const allFiles = collectFiles(snapshotDir, snapshotDir);
464
- const files = {};
465
- for (const f of allFiles) {
466
- const fp = resolve2(snapshotDir, f);
467
- files[f] = readFileSync2(fp).toString("base64");
468
- }
469
- try {
470
- const res = await fetch(`${config.apiUrl}/api/pages/publish/${mindName}`, {
471
- method: "PUT",
472
- headers: {
473
- "Content-Type": "application/json",
474
- Authorization: `Bearer ${config.apiKey}`
475
- },
476
- body: JSON.stringify({ files })
477
- });
478
- const data = await res.json().catch(() => ({}));
479
- if (!res.ok) {
480
- const errMsg = data.error || `HTTP ${res.status}`;
481
- output += `
482
- Warning: remote publish failed: ${errMsg}`;
483
- } else if (data.url) {
484
- output += `
485
- Remote: ${data.url}`;
486
- }
487
- } catch (err) {
488
- output += `
489
- Warning: remote publish failed: ${err.message}`;
490
- }
491
- }
492
- return { output };
493
- }
494
- },
495
- list: {
496
- description: "List pages with publish status",
497
- flags: {
498
- all: { type: "boolean", description: "Show pages from all minds" },
499
- shared: { type: "boolean", description: "Show shared pages status" }
500
- },
501
- handler: async ({ flags }, ctx) => {
502
- const db = ctx.db;
503
- if (!db) return { error: "Database not available" };
504
- const allFlag = flags.all;
505
- const port = process.env.VOLUTE_DAEMON_PORT || "1618";
506
- if (allFlag) {
507
- const { getAllSites: getAllSites2, getSystemPages: getSystemPages2 } = await import("./db-IJL6B26S.js");
508
- const sites = getAllSites2(db);
509
- const system = getSystemPages2(db);
510
- const lines2 = [];
511
- if (system) {
512
- for (const f of system.files) {
513
- const url = `http://localhost:${port}/ext/pages/public/_system/${f.file}`;
514
- const author = f.author ? ` (${f.author})` : "";
515
- lines2.push(`_system${author.padStart(10)} ${f.file.padEnd(25)} ${url}`);
516
- }
517
- }
518
- for (const site of sites) {
519
- for (const f of site.files) {
520
- const url = `http://localhost:${port}/ext/pages/public/${site.mind}/${f.file}`;
521
- lines2.push(`${site.mind.padEnd(15)} ${f.file.padEnd(25)} ${url}`);
522
- }
523
- }
524
- return { output: lines2.length > 0 ? lines2.join("\n") : "No published pages found." };
525
- }
526
- const mindName = ctx.mindName;
527
- if (!mindName) return { error: "No mind specified (use --mind or VOLUTE_MIND)" };
528
- if (flags.shared) {
529
- const mindDir2 = ctx.getMindDir(mindName);
530
- if (!mindDir2) return { error: `Mind not found: ${mindName}` };
531
- try {
532
- const status = await pagesStatus(mindDir2, isolationFrom(ctx));
533
- return { output: status };
534
- } catch (err) {
535
- return { error: `Failed to check shared status: ${err.message}` };
536
- }
537
- }
538
- const mindDir = ctx.getMindDir(mindName);
539
- if (!mindDir) return { error: `Mind not found: ${mindName}` };
540
- const sourceDir = resolve2(mindDir, "home", "pages");
541
- const published = new Set(getPublishedPages(db, mindName).map((p) => p.file));
542
- const draftFiles = existsSync2(sourceDir) ? collectFiles(sourceDir, sourceDir, [".html", ".md"]) : [];
543
- const allFiles = /* @__PURE__ */ new Set([...published, ...draftFiles]);
544
- if (allFiles.size === 0) return { output: "No pages found." };
545
- const lines = [...allFiles].sort().map((file) => {
546
- const isPublished = published.has(file);
547
- const status = isPublished ? "published" : "draft";
548
- const url = isPublished ? `http://localhost:${port}/ext/pages/public/${mindName}/${file}` : "";
549
- return `${status.padEnd(11)} ${file.padEnd(25)} ${url}`;
550
- });
551
- return { output: lines.join("\n") };
552
- }
553
- },
554
- pull: {
555
- description: "Pull latest shared page changes from other minds",
556
- handler: async (_parsed, ctx) => {
557
- const mindName = ctx.mindName;
558
- if (!mindName) return { error: "No mind specified (use --mind or VOLUTE_MIND)" };
559
- const mindDir = ctx.getMindDir(mindName);
560
- if (!mindDir) return { error: `Mind not found: ${mindName}` };
561
- try {
562
- const result = await pagesPull(mindName, mindDir, isolationFrom(ctx));
563
- if (!result.ok) {
564
- return { error: result.message || "Pull failed." };
565
- }
566
- return { output: result.message || "Pulled latest shared changes." };
567
- } catch (err) {
568
- return { error: `Pull failed: ${err.message}` };
569
- }
570
- }
571
- },
572
- log: {
573
- description: "View shared pages commit history",
574
- flags: {
575
- limit: { type: "number", description: "Max number of entries to show (default: 20)" }
576
- },
577
- handler: async ({ flags }, ctx) => {
578
- const mindName = ctx.mindName;
579
- if (!mindName) return { error: "No mind specified (use --mind or VOLUTE_MIND)" };
580
- const mindDir = ctx.getMindDir(mindName);
581
- if (!mindDir) return { error: `Mind not found: ${mindName}` };
582
- const limit = flags.limit ?? 20;
583
- try {
584
- const output = await pagesLog(mindDir, limit, isolationFrom(ctx));
585
- return { output };
586
- } catch (err) {
587
- return { error: `Failed to read shared log: ${err.message}` };
588
- }
589
- }
590
- }
591
- };
592
- }
593
- function collectFiles(dir, baseDir, ext) {
594
- const files = [];
595
- let items;
596
- try {
597
- items = readdirSync2(dir);
598
- } catch (err) {
599
- console.error(`[pages] failed to read directory ${dir}: ${err.message}`);
600
- return files;
601
- }
602
- for (const item of items) {
603
- if (item.startsWith(".")) continue;
604
- const fullPath = resolve2(dir, item);
605
- try {
606
- const s = statSync2(fullPath);
607
- const matchesExt = !ext || (Array.isArray(ext) ? ext.some((e) => item.endsWith(e)) : item.endsWith(ext));
608
- if (s.isFile() && matchesExt) {
609
- files.push(relative2(baseDir, fullPath));
610
- } else if (s.isDirectory()) {
611
- files.push(...collectFiles(fullPath, baseDir, ext));
612
- }
613
- } catch (err) {
614
- console.error(`[pages] failed to stat ${fullPath}: ${err.message}`);
615
- }
616
- }
617
- return files.sort();
618
- }
619
-
620
- // packages/extensions/pages/src/routes.ts
621
- import { readFile, stat } from "fs/promises";
622
- import { extname, resolve as resolve4 } from "path";
623
- import { Hono } from "hono";
624
-
625
- // packages/extensions/pages/src/cache.ts
626
- function mapFiles(mind, files) {
627
- return files.map((f) => ({
628
- file: f.file,
629
- modified: f.updated_at,
630
- url: `/ext/pages/public/${mind}/${f.file}`,
631
- author: f.author
632
- }));
633
- }
634
- function getSites(db) {
635
- const sites = getAllSites(db).map((site) => ({
636
- name: site.mind,
637
- label: site.mind,
638
- pages: mapFiles(site.mind, site.files)
639
- }));
640
- const system = getSystemPages(db);
641
- const systemSite = system ? { name: "_system", label: "Shared Pages", pages: mapFiles("_system", system.files) } : null;
642
- return { sites, systemSite };
643
- }
644
- function getRecentPagesList(db, opts) {
645
- const rows = getRecentPages(db, opts);
646
- return rows.map((r) => ({
647
- mind: r.mind,
648
- file: r.file,
649
- modified: r.updated_at,
650
- url: `/ext/pages/public/${r.mind}/${r.file}`,
651
- author: r.author
652
- }));
653
- }
654
-
655
- // packages/extensions/pages/src/markdown.ts
656
- import { existsSync as existsSync3 } from "fs";
657
- import { dirname, relative as relative3, resolve as resolve3 } from "path";
658
-
659
- // node_modules/marked/lib/marked.esm.js
660
- function M() {
661
- return { async: false, breaks: false, extensions: null, gfm: true, hooks: null, pedantic: false, renderer: null, silent: false, tokenizer: null, walkTokens: null };
662
- }
663
- var T = M();
664
- function G(u3) {
665
- T = u3;
666
- }
667
- var _ = { exec: () => null };
668
- function k(u3, e = "") {
669
- let t = typeof u3 == "string" ? u3 : u3.source, n = { replace: (r, i) => {
670
- let s = typeof i == "string" ? i : i.source;
671
- return s = s.replace(m.caret, "$1"), t = t.replace(r, s), n;
672
- }, getRegex: () => new RegExp(t, e) };
673
- return n;
674
- }
675
- var be = (() => {
676
- try {
677
- return !!new RegExp("(?<=1)(?<!1)");
678
- } catch {
679
- return false;
680
- }
681
- })();
682
- var m = { codeRemoveIndent: /^(?: {1,4}| {0,3}\t)/gm, outputLinkReplace: /\\([\[\]])/g, indentCodeCompensation: /^(\s+)(?:```)/, beginningSpace: /^\s+/, endingHash: /#$/, startingSpaceChar: /^ /, endingSpaceChar: / $/, nonSpaceChar: /[^ ]/, newLineCharGlobal: /\n/g, tabCharGlobal: /\t/g, multipleSpaceGlobal: /\s+/g, blankLine: /^[ \t]*$/, doubleBlankLine: /\n[ \t]*\n[ \t]*$/, blockquoteStart: /^ {0,3}>/, blockquoteSetextReplace: /\n {0,3}((?:=+|-+) *)(?=\n|$)/g, blockquoteSetextReplace2: /^ {0,3}>[ \t]?/gm, listReplaceNesting: /^ {1,4}(?=( {4})*[^ ])/g, listIsTask: /^\[[ xX]\] +\S/, listReplaceTask: /^\[[ xX]\] +/, listTaskCheckbox: /\[[ xX]\]/, anyLine: /\n.*\n/, hrefBrackets: /^<(.*)>$/, tableDelimiter: /[:|]/, tableAlignChars: /^\||\| *$/g, tableRowBlankLine: /\n[ \t]*$/, tableAlignRight: /^ *-+: *$/, tableAlignCenter: /^ *:-+: *$/, tableAlignLeft: /^ *:-+ *$/, startATag: /^<a /i, endATag: /^<\/a>/i, startPreScriptTag: /^<(pre|code|kbd|script)(\s|>)/i, endPreScriptTag: /^<\/(pre|code|kbd|script)(\s|>)/i, startAngleBracket: /^</, endAngleBracket: />$/, pedanticHrefTitle: /^([^'"]*[^\s])\s+(['"])(.*)\2/, unicodeAlphaNumeric: /[\p{L}\p{N}]/u, escapeTest: /[&<>"']/, escapeReplace: /[&<>"']/g, escapeTestNoEncode: /[<>"']|&(?!(#\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\w+);)/, escapeReplaceNoEncode: /[<>"']|&(?!(#\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\w+);)/g, caret: /(^|[^\[])\^/g, percentDecode: /%25/g, findPipe: /\|/g, splitPipe: / \|/, slashPipe: /\\\|/g, carriageReturn: /\r\n|\r/g, spaceLine: /^ +$/gm, notSpaceStart: /^\S*/, endingNewline: /\n$/, listItemRegex: (u3) => new RegExp(`^( {0,3}${u3})((?:[ ][^\\n]*)?(?:\\n|$))`), nextBulletRegex: (u3) => new RegExp(`^ {0,${Math.min(3, u3 - 1)}}(?:[*+-]|\\d{1,9}[.)])((?:[ ][^\\n]*)?(?:\\n|$))`), hrRegex: (u3) => new RegExp(`^ {0,${Math.min(3, u3 - 1)}}((?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$)`), fencesBeginRegex: (u3) => new RegExp(`^ {0,${Math.min(3, u3 - 1)}}(?:\`\`\`|~~~)`), headingBeginRegex: (u3) => new RegExp(`^ {0,${Math.min(3, u3 - 1)}}#`), htmlBeginRegex: (u3) => new RegExp(`^ {0,${Math.min(3, u3 - 1)}}<(?:[a-z].*>|!--)`, "i"), blockquoteBeginRegex: (u3) => new RegExp(`^ {0,${Math.min(3, u3 - 1)}}>`) };
683
- var Re = /^(?:[ \t]*(?:\n|$))+/;
684
- var Te = /^((?: {4}| {0,3}\t)[^\n]+(?:\n(?:[ \t]*(?:\n|$))*)?)+/;
685
- var Oe = /^ {0,3}(`{3,}(?=[^`\n]*(?:\n|$))|~{3,})([^\n]*)(?:\n|$)(?:|([\s\S]*?)(?:\n|$))(?: {0,3}\1[~`]* *(?=\n|$)|$)/;
686
- var C = /^ {0,3}((?:-[\t ]*){3,}|(?:_[ \t]*){3,}|(?:\*[ \t]*){3,})(?:\n+|$)/;
687
- var we = /^ {0,3}(#{1,6})(?=\s|$)(.*)(?:\n+|$)/;
688
- var Q = / {0,3}(?:[*+-]|\d{1,9}[.)])/;
689
- var se = /^(?!bull |blockCode|fences|blockquote|heading|html|table)((?:.|\n(?!\s*?\n|bull |blockCode|fences|blockquote|heading|html|table))+?)\n {0,3}(=+|-+) *(?:\n+|$)/;
690
- var ie = k(se).replace(/bull/g, Q).replace(/blockCode/g, /(?: {4}| {0,3}\t)/).replace(/fences/g, / {0,3}(?:`{3,}|~{3,})/).replace(/blockquote/g, / {0,3}>/).replace(/heading/g, / {0,3}#{1,6}/).replace(/html/g, / {0,3}<[^\n>]+>\n/).replace(/\|table/g, "").getRegex();
691
- var ye = k(se).replace(/bull/g, Q).replace(/blockCode/g, /(?: {4}| {0,3}\t)/).replace(/fences/g, / {0,3}(?:`{3,}|~{3,})/).replace(/blockquote/g, / {0,3}>/).replace(/heading/g, / {0,3}#{1,6}/).replace(/html/g, / {0,3}<[^\n>]+>\n/).replace(/table/g, / {0,3}\|?(?:[:\- ]*\|)+[\:\- ]*\n/).getRegex();
692
- var j = /^([^\n]+(?:\n(?!hr|heading|lheading|blockquote|fences|list|html|table| +\n)[^\n]+)*)/;
693
- var Pe = /^[^\n]+/;
694
- var F = /(?!\s*\])(?:\\[\s\S]|[^\[\]\\])+/;
695
- var Se = k(/^ {0,3}\[(label)\]: *(?:\n[ \t]*)?([^<\s][^\s]*|<.*?>)(?:(?: +(?:\n[ \t]*)?| *\n[ \t]*)(title))? *(?:\n+|$)/).replace("label", F).replace("title", /(?:"(?:\\"?|[^"\\])*"|'[^'\n]*(?:\n[^'\n]+)*\n?'|\([^()]*\))/).getRegex();
696
- var $e = k(/^(bull)([ \t][^\n]+?)?(?:\n|$)/).replace(/bull/g, Q).getRegex();
697
- var v = "address|article|aside|base|basefont|blockquote|body|caption|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption|figure|footer|form|frame|frameset|h[1-6]|head|header|hr|html|iframe|legend|li|link|main|menu|menuitem|meta|nav|noframes|ol|optgroup|option|p|param|search|section|summary|table|tbody|td|tfoot|th|thead|title|tr|track|ul";
698
- var U = /<!--(?:-?>|[\s\S]*?(?:-->|$))/;
699
- var _e = k("^ {0,3}(?:<(script|pre|style|textarea)[\\s>][\\s\\S]*?(?:</\\1>[^\\n]*\\n+|$)|comment[^\\n]*(\\n+|$)|<\\?[\\s\\S]*?(?:\\?>\\n*|$)|<![A-Z][\\s\\S]*?(?:>\\n*|$)|<!\\[CDATA\\[[\\s\\S]*?(?:\\]\\]>\\n*|$)|</?(tag)(?: +|\\n|/?>)[\\s\\S]*?(?:(?:\\n[ ]*)+\\n|$)|<(?!script|pre|style|textarea)([a-z][\\w-]*)(?:attribute)*? */?>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n[ ]*)+\\n|$)|</(?!script|pre|style|textarea)[a-z][\\w-]*\\s*>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n[ ]*)+\\n|$))", "i").replace("comment", U).replace("tag", v).replace("attribute", / +[a-zA-Z:_][\w.:-]*(?: *= *"[^"\n]*"| *= *'[^'\n]*'| *= *[^\s"'=<>`]+)?/).getRegex();
700
- var oe = k(j).replace("hr", C).replace("heading", " {0,3}#{1,6}(?:\\s|$)").replace("|lheading", "").replace("|table", "").replace("blockquote", " {0,3}>").replace("fences", " {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list", " {0,3}(?:[*+-]|1[.)])[ \\t]").replace("html", "</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag", v).getRegex();
701
- var Le = k(/^( {0,3}> ?(paragraph|[^\n]*)(?:\n|$))+/).replace("paragraph", oe).getRegex();
702
- var K = { blockquote: Le, code: Te, def: Se, fences: Oe, heading: we, hr: C, html: _e, lheading: ie, list: $e, newline: Re, paragraph: oe, table: _, text: Pe };
703
- var ne = k("^ *([^\\n ].*)\\n {0,3}((?:\\| *)?:?-+:? *(?:\\| *:?-+:? *)*(?:\\| *)?)(?:\\n((?:(?! *\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\n|$))*)\\n*|$)").replace("hr", C).replace("heading", " {0,3}#{1,6}(?:\\s|$)").replace("blockquote", " {0,3}>").replace("code", "(?: {4}| {0,3} )[^\\n]").replace("fences", " {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list", " {0,3}(?:[*+-]|1[.)])[ \\t]").replace("html", "</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag", v).getRegex();
704
- var Me = { ...K, lheading: ye, table: ne, paragraph: k(j).replace("hr", C).replace("heading", " {0,3}#{1,6}(?:\\s|$)").replace("|lheading", "").replace("table", ne).replace("blockquote", " {0,3}>").replace("fences", " {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list", " {0,3}(?:[*+-]|1[.)])[ \\t]").replace("html", "</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag", v).getRegex() };
705
- var ze = { ...K, html: k(`^ *(?:comment *(?:\\n|\\s*$)|<(tag)[\\s\\S]+?</\\1> *(?:\\n{2,}|\\s*$)|<tag(?:"[^"]*"|'[^']*'|\\s[^'"/>\\s]*)*?/?> *(?:\\n{2,}|\\s*$))`).replace("comment", U).replace(/tag/g, "(?!(?:a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)\\b)\\w+(?!:|[^\\w\\s@]*@)\\b").getRegex(), def: /^ *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +(["(][^\n]+[")]))? *(?:\n+|$)/, heading: /^(#{1,6})(.*)(?:\n+|$)/, fences: _, lheading: /^(.+?)\n {0,3}(=+|-+) *(?:\n+|$)/, paragraph: k(j).replace("hr", C).replace("heading", ` *#{1,6} *[^
706
- ]`).replace("lheading", ie).replace("|table", "").replace("blockquote", " {0,3}>").replace("|fences", "").replace("|list", "").replace("|html", "").replace("|tag", "").getRegex() };
707
- var Ee = /^\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/;
708
- var Ie = /^(`+)([^`]|[^`][\s\S]*?[^`])\1(?!`)/;
709
- var ae = /^( {2,}|\\)\n(?!\s*$)/;
710
- var Ae = /^(`+|[^`])(?:(?= {2,}\n)|[\s\S]*?(?:(?=[\\<!\[`*_]|\b_|$)|[^ ](?= {2,}\n)))/;
711
- var z = /[\p{P}\p{S}]/u;
712
- var H = /[\s\p{P}\p{S}]/u;
713
- var W = /[^\s\p{P}\p{S}]/u;
714
- var Ce = k(/^((?![*_])punctSpace)/, "u").replace(/punctSpace/g, H).getRegex();
715
- var le = /(?!~)[\p{P}\p{S}]/u;
716
- var Be = /(?!~)[\s\p{P}\p{S}]/u;
717
- var De = /(?:[^\s\p{P}\p{S}]|~)/u;
718
- var qe = k(/link|precode-code|html/, "g").replace("link", /\[(?:[^\[\]`]|(?<a>`+)[^`]+\k<a>(?!`))*?\]\((?:\\[\s\S]|[^\\\(\)]|\((?:\\[\s\S]|[^\\\(\)])*\))*\)/).replace("precode-", be ? "(?<!`)()" : "(^^|[^`])").replace("code", /(?<b>`+)[^`]+\k<b>(?!`)/).replace("html", /<(?! )[^<>]*?>/).getRegex();
719
- var ue = /^(?:\*+(?:((?!\*)punct)|([^\s*]))?)|^_+(?:((?!_)punct)|([^\s_]))?/;
720
- var ve = k(ue, "u").replace(/punct/g, z).getRegex();
721
- var He = k(ue, "u").replace(/punct/g, le).getRegex();
722
- var pe = "^[^_*]*?__[^_*]*?\\*[^_*]*?(?=__)|[^*]+(?=[^*])|(?!\\*)punct(\\*+)(?=[\\s]|$)|notPunctSpace(\\*+)(?!\\*)(?=punctSpace|$)|(?!\\*)punctSpace(\\*+)(?=notPunctSpace)|[\\s](\\*+)(?!\\*)(?=punct)|(?!\\*)punct(\\*+)(?!\\*)(?=punct)|notPunctSpace(\\*+)(?=notPunctSpace)";
723
- var Ze = k(pe, "gu").replace(/notPunctSpace/g, W).replace(/punctSpace/g, H).replace(/punct/g, z).getRegex();
724
- var Ge = k(pe, "gu").replace(/notPunctSpace/g, De).replace(/punctSpace/g, Be).replace(/punct/g, le).getRegex();
725
- var Ne = k("^[^_*]*?\\*\\*[^_*]*?_[^_*]*?(?=\\*\\*)|[^_]+(?=[^_])|(?!_)punct(_+)(?=[\\s]|$)|notPunctSpace(_+)(?!_)(?=punctSpace|$)|(?!_)punctSpace(_+)(?=notPunctSpace)|[\\s](_+)(?!_)(?=punct)|(?!_)punct(_+)(?!_)(?=punct)", "gu").replace(/notPunctSpace/g, W).replace(/punctSpace/g, H).replace(/punct/g, z).getRegex();
726
- var Qe = k(/^~~?(?:((?!~)punct)|[^\s~])/, "u").replace(/punct/g, z).getRegex();
727
- var je = "^[^~]+(?=[^~])|(?!~)punct(~~?)(?=[\\s]|$)|notPunctSpace(~~?)(?!~)(?=punctSpace|$)|(?!~)punctSpace(~~?)(?=notPunctSpace)|[\\s](~~?)(?!~)(?=punct)|(?!~)punct(~~?)(?!~)(?=punct)|notPunctSpace(~~?)(?=notPunctSpace)";
728
- var Fe = k(je, "gu").replace(/notPunctSpace/g, W).replace(/punctSpace/g, H).replace(/punct/g, z).getRegex();
729
- var Ue = k(/\\(punct)/, "gu").replace(/punct/g, z).getRegex();
730
- var Ke = k(/^<(scheme:[^\s\x00-\x1f<>]*|email)>/).replace("scheme", /[a-zA-Z][a-zA-Z0-9+.-]{1,31}/).replace("email", /[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+(@)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+(?![-_])/).getRegex();
731
- var We = k(U).replace("(?:-->|$)", "-->").getRegex();
732
- var Xe = k("^comment|^</[a-zA-Z][\\w:-]*\\s*>|^<[a-zA-Z][\\w-]*(?:attribute)*?\\s*/?>|^<\\?[\\s\\S]*?\\?>|^<![a-zA-Z]+\\s[\\s\\S]*?>|^<!\\[CDATA\\[[\\s\\S]*?\\]\\]>").replace("comment", We).replace("attribute", /\s+[a-zA-Z:_][\w.:-]*(?:\s*=\s*"[^"]*"|\s*=\s*'[^']*'|\s*=\s*[^\s"'=<>`]+)?/).getRegex();
733
- var q = /(?:\[(?:\\[\s\S]|[^\[\]\\])*\]|\\[\s\S]|`+(?!`)[^`]*?`+(?!`)|``+(?=\])|[^\[\]\\`])*?/;
734
- var Je = k(/^!?\[(label)\]\(\s*(href)(?:(?:[ \t]+(?:\n[ \t]*)?|\n[ \t]*)(title))?\s*\)/).replace("label", q).replace("href", /<(?:\\.|[^\n<>\\])+>|[^ \t\n\x00-\x1f]*/).replace("title", /"(?:\\"?|[^"\\])*"|'(?:\\'?|[^'\\])*'|\((?:\\\)?|[^)\\])*\)/).getRegex();
735
- var ce = k(/^!?\[(label)\]\[(ref)\]/).replace("label", q).replace("ref", F).getRegex();
736
- var he = k(/^!?\[(ref)\](?:\[\])?/).replace("ref", F).getRegex();
737
- var Ve = k("reflink|nolink(?!\\()", "g").replace("reflink", ce).replace("nolink", he).getRegex();
738
- var re = /[hH][tT][tT][pP][sS]?|[fF][tT][pP]/;
739
- var X = { _backpedal: _, anyPunctuation: Ue, autolink: Ke, blockSkip: qe, br: ae, code: Ie, del: _, delLDelim: _, delRDelim: _, emStrongLDelim: ve, emStrongRDelimAst: Ze, emStrongRDelimUnd: Ne, escape: Ee, link: Je, nolink: he, punctuation: Ce, reflink: ce, reflinkSearch: Ve, tag: Xe, text: Ae, url: _ };
740
- var Ye = { ...X, link: k(/^!?\[(label)\]\((.*?)\)/).replace("label", q).getRegex(), reflink: k(/^!?\[(label)\]\s*\[([^\]]*)\]/).replace("label", q).getRegex() };
741
- var N = { ...X, emStrongRDelimAst: Ge, emStrongLDelim: He, delLDelim: Qe, delRDelim: Fe, url: k(/^((?:protocol):\/\/|www\.)(?:[a-zA-Z0-9\-]+\.?)+[^\s<]*|^email/).replace("protocol", re).replace("email", /[A-Za-z0-9._+-]+(@)[a-zA-Z0-9-_]+(?:\.[a-zA-Z0-9-_]*[a-zA-Z0-9])+(?![-_])/).getRegex(), _backpedal: /(?:[^?!.,:;*_'"~()&]+|\([^)]*\)|&(?![a-zA-Z0-9]+;$)|[?!.,:;*_'"~)]+(?!$))+/, del: /^(~~?)(?=[^\s~])((?:\\[\s\S]|[^\\])*?(?:\\[\s\S]|[^\s~\\]))\1(?=[^~]|$)/, text: k(/^([`~]+|[^`~])(?:(?= {2,}\n)|(?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)|[\s\S]*?(?:(?=[\\<!\[`*~_]|\b_|protocol:\/\/|www\.|$)|[^ ](?= {2,}\n)|[^a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-](?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)))/).replace("protocol", re).getRegex() };
742
- var et = { ...N, br: k(ae).replace("{2,}", "*").getRegex(), text: k(N.text).replace("\\b_", "\\b_| {2,}\\n").replace(/\{2,\}/g, "*").getRegex() };
743
- var B = { normal: K, gfm: Me, pedantic: ze };
744
- var E = { normal: X, gfm: N, breaks: et, pedantic: Ye };
745
- var tt = { "&": "&amp;", "<": "&lt;", ">": "&gt;", '"': "&quot;", "'": "&#39;" };
746
- var ke = (u3) => tt[u3];
747
- function O(u3, e) {
748
- if (e) {
749
- if (m.escapeTest.test(u3)) return u3.replace(m.escapeReplace, ke);
750
- } else if (m.escapeTestNoEncode.test(u3)) return u3.replace(m.escapeReplaceNoEncode, ke);
751
- return u3;
752
- }
753
- function J(u3) {
754
- try {
755
- u3 = encodeURI(u3).replace(m.percentDecode, "%");
756
- } catch {
757
- return null;
758
- }
759
- return u3;
760
- }
761
- function V(u3, e) {
762
- let t = u3.replace(m.findPipe, (i, s, a) => {
763
- let o = false, l = s;
764
- for (; --l >= 0 && a[l] === "\\"; ) o = !o;
765
- return o ? "|" : " |";
766
- }), n = t.split(m.splitPipe), r = 0;
767
- if (n[0].trim() || n.shift(), n.length > 0 && !n.at(-1)?.trim() && n.pop(), e) if (n.length > e) n.splice(e);
768
- else for (; n.length < e; ) n.push("");
769
- for (; r < n.length; r++) n[r] = n[r].trim().replace(m.slashPipe, "|");
770
- return n;
771
- }
772
- function I(u3, e, t) {
773
- let n = u3.length;
774
- if (n === 0) return "";
775
- let r = 0;
776
- for (; r < n; ) {
777
- let i = u3.charAt(n - r - 1);
778
- if (i === e && !t) r++;
779
- else if (i !== e && t) r++;
780
- else break;
781
- }
782
- return u3.slice(0, n - r);
783
- }
784
- function de(u3, e) {
785
- if (u3.indexOf(e[1]) === -1) return -1;
786
- let t = 0;
787
- for (let n = 0; n < u3.length; n++) if (u3[n] === "\\") n++;
788
- else if (u3[n] === e[0]) t++;
789
- else if (u3[n] === e[1] && (t--, t < 0)) return n;
790
- return t > 0 ? -2 : -1;
791
- }
792
- function ge(u3, e = 0) {
793
- let t = e, n = "";
794
- for (let r of u3) if (r === " ") {
795
- let i = 4 - t % 4;
796
- n += " ".repeat(i), t += i;
797
- } else n += r, t++;
798
- return n;
799
- }
800
- function fe(u3, e, t, n, r) {
801
- let i = e.href, s = e.title || null, a = u3[1].replace(r.other.outputLinkReplace, "$1");
802
- n.state.inLink = true;
803
- let o = { type: u3[0].charAt(0) === "!" ? "image" : "link", raw: t, href: i, title: s, text: a, tokens: n.inlineTokens(a) };
804
- return n.state.inLink = false, o;
805
- }
806
- function nt(u3, e, t) {
807
- let n = u3.match(t.other.indentCodeCompensation);
808
- if (n === null) return e;
809
- let r = n[1];
810
- return e.split(`
811
- `).map((i) => {
812
- let s = i.match(t.other.beginningSpace);
813
- if (s === null) return i;
814
- let [a] = s;
815
- return a.length >= r.length ? i.slice(r.length) : i;
816
- }).join(`
817
- `);
818
- }
819
- var w = class {
820
- options;
821
- rules;
822
- lexer;
823
- constructor(e) {
824
- this.options = e || T;
825
- }
826
- space(e) {
827
- let t = this.rules.block.newline.exec(e);
828
- if (t && t[0].length > 0) return { type: "space", raw: t[0] };
829
- }
830
- code(e) {
831
- let t = this.rules.block.code.exec(e);
832
- if (t) {
833
- let n = t[0].replace(this.rules.other.codeRemoveIndent, "");
834
- return { type: "code", raw: t[0], codeBlockStyle: "indented", text: this.options.pedantic ? n : I(n, `
835
- `) };
836
- }
837
- }
838
- fences(e) {
839
- let t = this.rules.block.fences.exec(e);
840
- if (t) {
841
- let n = t[0], r = nt(n, t[3] || "", this.rules);
842
- return { type: "code", raw: n, lang: t[2] ? t[2].trim().replace(this.rules.inline.anyPunctuation, "$1") : t[2], text: r };
843
- }
844
- }
845
- heading(e) {
846
- let t = this.rules.block.heading.exec(e);
847
- if (t) {
848
- let n = t[2].trim();
849
- if (this.rules.other.endingHash.test(n)) {
850
- let r = I(n, "#");
851
- (this.options.pedantic || !r || this.rules.other.endingSpaceChar.test(r)) && (n = r.trim());
852
- }
853
- return { type: "heading", raw: t[0], depth: t[1].length, text: n, tokens: this.lexer.inline(n) };
854
- }
855
- }
856
- hr(e) {
857
- let t = this.rules.block.hr.exec(e);
858
- if (t) return { type: "hr", raw: I(t[0], `
859
- `) };
860
- }
861
- blockquote(e) {
862
- let t = this.rules.block.blockquote.exec(e);
863
- if (t) {
864
- let n = I(t[0], `
865
- `).split(`
866
- `), r = "", i = "", s = [];
867
- for (; n.length > 0; ) {
868
- let a = false, o = [], l;
869
- for (l = 0; l < n.length; l++) if (this.rules.other.blockquoteStart.test(n[l])) o.push(n[l]), a = true;
870
- else if (!a) o.push(n[l]);
871
- else break;
872
- n = n.slice(l);
873
- let p = o.join(`
874
- `), c = p.replace(this.rules.other.blockquoteSetextReplace, `
875
- $1`).replace(this.rules.other.blockquoteSetextReplace2, "");
876
- r = r ? `${r}
877
- ${p}` : p, i = i ? `${i}
878
- ${c}` : c;
879
- let d = this.lexer.state.top;
880
- if (this.lexer.state.top = true, this.lexer.blockTokens(c, s, true), this.lexer.state.top = d, n.length === 0) break;
881
- let h = s.at(-1);
882
- if (h?.type === "code") break;
883
- if (h?.type === "blockquote") {
884
- let R = h, f = R.raw + `
885
- ` + n.join(`
886
- `), S = this.blockquote(f);
887
- s[s.length - 1] = S, r = r.substring(0, r.length - R.raw.length) + S.raw, i = i.substring(0, i.length - R.text.length) + S.text;
888
- break;
889
- } else if (h?.type === "list") {
890
- let R = h, f = R.raw + `
891
- ` + n.join(`
892
- `), S = this.list(f);
893
- s[s.length - 1] = S, r = r.substring(0, r.length - h.raw.length) + S.raw, i = i.substring(0, i.length - R.raw.length) + S.raw, n = f.substring(s.at(-1).raw.length).split(`
894
- `);
895
- continue;
896
- }
897
- }
898
- return { type: "blockquote", raw: r, tokens: s, text: i };
899
- }
900
- }
901
- list(e) {
902
- let t = this.rules.block.list.exec(e);
903
- if (t) {
904
- let n = t[1].trim(), r = n.length > 1, i = { type: "list", raw: "", ordered: r, start: r ? +n.slice(0, -1) : "", loose: false, items: [] };
905
- n = r ? `\\d{1,9}\\${n.slice(-1)}` : `\\${n}`, this.options.pedantic && (n = r ? n : "[*+-]");
906
- let s = this.rules.other.listItemRegex(n), a = false;
907
- for (; e; ) {
908
- let l = false, p = "", c = "";
909
- if (!(t = s.exec(e)) || this.rules.block.hr.test(e)) break;
910
- p = t[0], e = e.substring(p.length);
911
- let d = ge(t[2].split(`
912
- `, 1)[0], t[1].length), h = e.split(`
913
- `, 1)[0], R = !d.trim(), f = 0;
914
- if (this.options.pedantic ? (f = 2, c = d.trimStart()) : R ? f = t[1].length + 1 : (f = d.search(this.rules.other.nonSpaceChar), f = f > 4 ? 1 : f, c = d.slice(f), f += t[1].length), R && this.rules.other.blankLine.test(h) && (p += h + `
915
- `, e = e.substring(h.length + 1), l = true), !l) {
916
- let S = this.rules.other.nextBulletRegex(f), Y = this.rules.other.hrRegex(f), ee = this.rules.other.fencesBeginRegex(f), te = this.rules.other.headingBeginRegex(f), me = this.rules.other.htmlBeginRegex(f), xe = this.rules.other.blockquoteBeginRegex(f);
917
- for (; e; ) {
918
- let Z = e.split(`
919
- `, 1)[0], A;
920
- if (h = Z, this.options.pedantic ? (h = h.replace(this.rules.other.listReplaceNesting, " "), A = h) : A = h.replace(this.rules.other.tabCharGlobal, " "), ee.test(h) || te.test(h) || me.test(h) || xe.test(h) || S.test(h) || Y.test(h)) break;
921
- if (A.search(this.rules.other.nonSpaceChar) >= f || !h.trim()) c += `
922
- ` + A.slice(f);
923
- else {
924
- if (R || d.replace(this.rules.other.tabCharGlobal, " ").search(this.rules.other.nonSpaceChar) >= 4 || ee.test(d) || te.test(d) || Y.test(d)) break;
925
- c += `
926
- ` + h;
927
- }
928
- R = !h.trim(), p += Z + `
929
- `, e = e.substring(Z.length + 1), d = A.slice(f);
930
- }
931
- }
932
- i.loose || (a ? i.loose = true : this.rules.other.doubleBlankLine.test(p) && (a = true)), i.items.push({ type: "list_item", raw: p, task: !!this.options.gfm && this.rules.other.listIsTask.test(c), loose: false, text: c, tokens: [] }), i.raw += p;
933
- }
934
- let o = i.items.at(-1);
935
- if (o) o.raw = o.raw.trimEnd(), o.text = o.text.trimEnd();
936
- else return;
937
- i.raw = i.raw.trimEnd();
938
- for (let l of i.items) {
939
- if (this.lexer.state.top = false, l.tokens = this.lexer.blockTokens(l.text, []), l.task) {
940
- if (l.text = l.text.replace(this.rules.other.listReplaceTask, ""), l.tokens[0]?.type === "text" || l.tokens[0]?.type === "paragraph") {
941
- l.tokens[0].raw = l.tokens[0].raw.replace(this.rules.other.listReplaceTask, ""), l.tokens[0].text = l.tokens[0].text.replace(this.rules.other.listReplaceTask, "");
942
- for (let c = this.lexer.inlineQueue.length - 1; c >= 0; c--) if (this.rules.other.listIsTask.test(this.lexer.inlineQueue[c].src)) {
943
- this.lexer.inlineQueue[c].src = this.lexer.inlineQueue[c].src.replace(this.rules.other.listReplaceTask, "");
944
- break;
945
- }
946
- }
947
- let p = this.rules.other.listTaskCheckbox.exec(l.raw);
948
- if (p) {
949
- let c = { type: "checkbox", raw: p[0] + " ", checked: p[0] !== "[ ]" };
950
- l.checked = c.checked, i.loose ? l.tokens[0] && ["paragraph", "text"].includes(l.tokens[0].type) && "tokens" in l.tokens[0] && l.tokens[0].tokens ? (l.tokens[0].raw = c.raw + l.tokens[0].raw, l.tokens[0].text = c.raw + l.tokens[0].text, l.tokens[0].tokens.unshift(c)) : l.tokens.unshift({ type: "paragraph", raw: c.raw, text: c.raw, tokens: [c] }) : l.tokens.unshift(c);
951
- }
952
- }
953
- if (!i.loose) {
954
- let p = l.tokens.filter((d) => d.type === "space"), c = p.length > 0 && p.some((d) => this.rules.other.anyLine.test(d.raw));
955
- i.loose = c;
956
- }
957
- }
958
- if (i.loose) for (let l of i.items) {
959
- l.loose = true;
960
- for (let p of l.tokens) p.type === "text" && (p.type = "paragraph");
961
- }
962
- return i;
963
- }
964
- }
965
- html(e) {
966
- let t = this.rules.block.html.exec(e);
967
- if (t) return { type: "html", block: true, raw: t[0], pre: t[1] === "pre" || t[1] === "script" || t[1] === "style", text: t[0] };
968
- }
969
- def(e) {
970
- let t = this.rules.block.def.exec(e);
971
- if (t) {
972
- let n = t[1].toLowerCase().replace(this.rules.other.multipleSpaceGlobal, " "), r = t[2] ? t[2].replace(this.rules.other.hrefBrackets, "$1").replace(this.rules.inline.anyPunctuation, "$1") : "", i = t[3] ? t[3].substring(1, t[3].length - 1).replace(this.rules.inline.anyPunctuation, "$1") : t[3];
973
- return { type: "def", tag: n, raw: t[0], href: r, title: i };
974
- }
975
- }
976
- table(e) {
977
- let t = this.rules.block.table.exec(e);
978
- if (!t || !this.rules.other.tableDelimiter.test(t[2])) return;
979
- let n = V(t[1]), r = t[2].replace(this.rules.other.tableAlignChars, "").split("|"), i = t[3]?.trim() ? t[3].replace(this.rules.other.tableRowBlankLine, "").split(`
980
- `) : [], s = { type: "table", raw: t[0], header: [], align: [], rows: [] };
981
- if (n.length === r.length) {
982
- for (let a of r) this.rules.other.tableAlignRight.test(a) ? s.align.push("right") : this.rules.other.tableAlignCenter.test(a) ? s.align.push("center") : this.rules.other.tableAlignLeft.test(a) ? s.align.push("left") : s.align.push(null);
983
- for (let a = 0; a < n.length; a++) s.header.push({ text: n[a], tokens: this.lexer.inline(n[a]), header: true, align: s.align[a] });
984
- for (let a of i) s.rows.push(V(a, s.header.length).map((o, l) => ({ text: o, tokens: this.lexer.inline(o), header: false, align: s.align[l] })));
985
- return s;
986
- }
987
- }
988
- lheading(e) {
989
- let t = this.rules.block.lheading.exec(e);
990
- if (t) {
991
- let n = t[1].trim();
992
- return { type: "heading", raw: t[0], depth: t[2].charAt(0) === "=" ? 1 : 2, text: n, tokens: this.lexer.inline(n) };
993
- }
994
- }
995
- paragraph(e) {
996
- let t = this.rules.block.paragraph.exec(e);
997
- if (t) {
998
- let n = t[1].charAt(t[1].length - 1) === `
999
- ` ? t[1].slice(0, -1) : t[1];
1000
- return { type: "paragraph", raw: t[0], text: n, tokens: this.lexer.inline(n) };
1001
- }
1002
- }
1003
- text(e) {
1004
- let t = this.rules.block.text.exec(e);
1005
- if (t) return { type: "text", raw: t[0], text: t[0], tokens: this.lexer.inline(t[0]) };
1006
- }
1007
- escape(e) {
1008
- let t = this.rules.inline.escape.exec(e);
1009
- if (t) return { type: "escape", raw: t[0], text: t[1] };
1010
- }
1011
- tag(e) {
1012
- let t = this.rules.inline.tag.exec(e);
1013
- if (t) return !this.lexer.state.inLink && this.rules.other.startATag.test(t[0]) ? this.lexer.state.inLink = true : this.lexer.state.inLink && this.rules.other.endATag.test(t[0]) && (this.lexer.state.inLink = false), !this.lexer.state.inRawBlock && this.rules.other.startPreScriptTag.test(t[0]) ? this.lexer.state.inRawBlock = true : this.lexer.state.inRawBlock && this.rules.other.endPreScriptTag.test(t[0]) && (this.lexer.state.inRawBlock = false), { type: "html", raw: t[0], inLink: this.lexer.state.inLink, inRawBlock: this.lexer.state.inRawBlock, block: false, text: t[0] };
1014
- }
1015
- link(e) {
1016
- let t = this.rules.inline.link.exec(e);
1017
- if (t) {
1018
- let n = t[2].trim();
1019
- if (!this.options.pedantic && this.rules.other.startAngleBracket.test(n)) {
1020
- if (!this.rules.other.endAngleBracket.test(n)) return;
1021
- let s = I(n.slice(0, -1), "\\");
1022
- if ((n.length - s.length) % 2 === 0) return;
1023
- } else {
1024
- let s = de(t[2], "()");
1025
- if (s === -2) return;
1026
- if (s > -1) {
1027
- let o = (t[0].indexOf("!") === 0 ? 5 : 4) + t[1].length + s;
1028
- t[2] = t[2].substring(0, s), t[0] = t[0].substring(0, o).trim(), t[3] = "";
1029
- }
1030
- }
1031
- let r = t[2], i = "";
1032
- if (this.options.pedantic) {
1033
- let s = this.rules.other.pedanticHrefTitle.exec(r);
1034
- s && (r = s[1], i = s[3]);
1035
- } else i = t[3] ? t[3].slice(1, -1) : "";
1036
- return r = r.trim(), this.rules.other.startAngleBracket.test(r) && (this.options.pedantic && !this.rules.other.endAngleBracket.test(n) ? r = r.slice(1) : r = r.slice(1, -1)), fe(t, { href: r && r.replace(this.rules.inline.anyPunctuation, "$1"), title: i && i.replace(this.rules.inline.anyPunctuation, "$1") }, t[0], this.lexer, this.rules);
1037
- }
1038
- }
1039
- reflink(e, t) {
1040
- let n;
1041
- if ((n = this.rules.inline.reflink.exec(e)) || (n = this.rules.inline.nolink.exec(e))) {
1042
- let r = (n[2] || n[1]).replace(this.rules.other.multipleSpaceGlobal, " "), i = t[r.toLowerCase()];
1043
- if (!i) {
1044
- let s = n[0].charAt(0);
1045
- return { type: "text", raw: s, text: s };
1046
- }
1047
- return fe(n, i, n[0], this.lexer, this.rules);
1048
- }
1049
- }
1050
- emStrong(e, t, n = "") {
1051
- let r = this.rules.inline.emStrongLDelim.exec(e);
1052
- if (!r || !r[1] && !r[2] && !r[3] && !r[4] || r[4] && n.match(this.rules.other.unicodeAlphaNumeric)) return;
1053
- if (!(r[1] || r[3] || "") || !n || this.rules.inline.punctuation.exec(n)) {
1054
- let s = [...r[0]].length - 1, a, o, l = s, p = 0, c = r[0][0] === "*" ? this.rules.inline.emStrongRDelimAst : this.rules.inline.emStrongRDelimUnd;
1055
- for (c.lastIndex = 0, t = t.slice(-1 * e.length + s); (r = c.exec(t)) != null; ) {
1056
- if (a = r[1] || r[2] || r[3] || r[4] || r[5] || r[6], !a) continue;
1057
- if (o = [...a].length, r[3] || r[4]) {
1058
- l += o;
1059
- continue;
1060
- } else if ((r[5] || r[6]) && s % 3 && !((s + o) % 3)) {
1061
- p += o;
1062
- continue;
1063
- }
1064
- if (l -= o, l > 0) continue;
1065
- o = Math.min(o, o + l + p);
1066
- let d = [...r[0]][0].length, h = e.slice(0, s + r.index + d + o);
1067
- if (Math.min(s, o) % 2) {
1068
- let f = h.slice(1, -1);
1069
- return { type: "em", raw: h, text: f, tokens: this.lexer.inlineTokens(f) };
1070
- }
1071
- let R = h.slice(2, -2);
1072
- return { type: "strong", raw: h, text: R, tokens: this.lexer.inlineTokens(R) };
1073
- }
1074
- }
1075
- }
1076
- codespan(e) {
1077
- let t = this.rules.inline.code.exec(e);
1078
- if (t) {
1079
- let n = t[2].replace(this.rules.other.newLineCharGlobal, " "), r = this.rules.other.nonSpaceChar.test(n), i = this.rules.other.startingSpaceChar.test(n) && this.rules.other.endingSpaceChar.test(n);
1080
- return r && i && (n = n.substring(1, n.length - 1)), { type: "codespan", raw: t[0], text: n };
1081
- }
1082
- }
1083
- br(e) {
1084
- let t = this.rules.inline.br.exec(e);
1085
- if (t) return { type: "br", raw: t[0] };
1086
- }
1087
- del(e, t, n = "") {
1088
- let r = this.rules.inline.delLDelim.exec(e);
1089
- if (!r) return;
1090
- if (!(r[1] || "") || !n || this.rules.inline.punctuation.exec(n)) {
1091
- let s = [...r[0]].length - 1, a, o, l = s, p = this.rules.inline.delRDelim;
1092
- for (p.lastIndex = 0, t = t.slice(-1 * e.length + s); (r = p.exec(t)) != null; ) {
1093
- if (a = r[1] || r[2] || r[3] || r[4] || r[5] || r[6], !a || (o = [...a].length, o !== s)) continue;
1094
- if (r[3] || r[4]) {
1095
- l += o;
1096
- continue;
1097
- }
1098
- if (l -= o, l > 0) continue;
1099
- o = Math.min(o, o + l);
1100
- let c = [...r[0]][0].length, d = e.slice(0, s + r.index + c + o), h = d.slice(s, -s);
1101
- return { type: "del", raw: d, text: h, tokens: this.lexer.inlineTokens(h) };
1102
- }
1103
- }
1104
- }
1105
- autolink(e) {
1106
- let t = this.rules.inline.autolink.exec(e);
1107
- if (t) {
1108
- let n, r;
1109
- return t[2] === "@" ? (n = t[1], r = "mailto:" + n) : (n = t[1], r = n), { type: "link", raw: t[0], text: n, href: r, tokens: [{ type: "text", raw: n, text: n }] };
1110
- }
1111
- }
1112
- url(e) {
1113
- let t;
1114
- if (t = this.rules.inline.url.exec(e)) {
1115
- let n, r;
1116
- if (t[2] === "@") n = t[0], r = "mailto:" + n;
1117
- else {
1118
- let i;
1119
- do
1120
- i = t[0], t[0] = this.rules.inline._backpedal.exec(t[0])?.[0] ?? "";
1121
- while (i !== t[0]);
1122
- n = t[0], t[1] === "www." ? r = "http://" + t[0] : r = t[0];
1123
- }
1124
- return { type: "link", raw: t[0], text: n, href: r, tokens: [{ type: "text", raw: n, text: n }] };
1125
- }
1126
- }
1127
- inlineText(e) {
1128
- let t = this.rules.inline.text.exec(e);
1129
- if (t) {
1130
- let n = this.lexer.state.inRawBlock;
1131
- return { type: "text", raw: t[0], text: t[0], escaped: n };
1132
- }
1133
- }
1134
- };
1135
- var x = class u {
1136
- tokens;
1137
- options;
1138
- state;
1139
- inlineQueue;
1140
- tokenizer;
1141
- constructor(e) {
1142
- this.tokens = [], this.tokens.links = /* @__PURE__ */ Object.create(null), this.options = e || T, this.options.tokenizer = this.options.tokenizer || new w(), this.tokenizer = this.options.tokenizer, this.tokenizer.options = this.options, this.tokenizer.lexer = this, this.inlineQueue = [], this.state = { inLink: false, inRawBlock: false, top: true };
1143
- let t = { other: m, block: B.normal, inline: E.normal };
1144
- this.options.pedantic ? (t.block = B.pedantic, t.inline = E.pedantic) : this.options.gfm && (t.block = B.gfm, this.options.breaks ? t.inline = E.breaks : t.inline = E.gfm), this.tokenizer.rules = t;
1145
- }
1146
- static get rules() {
1147
- return { block: B, inline: E };
1148
- }
1149
- static lex(e, t) {
1150
- return new u(t).lex(e);
1151
- }
1152
- static lexInline(e, t) {
1153
- return new u(t).inlineTokens(e);
1154
- }
1155
- lex(e) {
1156
- e = e.replace(m.carriageReturn, `
1157
- `), this.blockTokens(e, this.tokens);
1158
- for (let t = 0; t < this.inlineQueue.length; t++) {
1159
- let n = this.inlineQueue[t];
1160
- this.inlineTokens(n.src, n.tokens);
1161
- }
1162
- return this.inlineQueue = [], this.tokens;
1163
- }
1164
- blockTokens(e, t = [], n = false) {
1165
- for (this.tokenizer.lexer = this, this.options.pedantic && (e = e.replace(m.tabCharGlobal, " ").replace(m.spaceLine, "")); e; ) {
1166
- let r;
1167
- if (this.options.extensions?.block?.some((s) => (r = s.call({ lexer: this }, e, t)) ? (e = e.substring(r.raw.length), t.push(r), true) : false)) continue;
1168
- if (r = this.tokenizer.space(e)) {
1169
- e = e.substring(r.raw.length);
1170
- let s = t.at(-1);
1171
- r.raw.length === 1 && s !== void 0 ? s.raw += `
1172
- ` : t.push(r);
1173
- continue;
1174
- }
1175
- if (r = this.tokenizer.code(e)) {
1176
- e = e.substring(r.raw.length);
1177
- let s = t.at(-1);
1178
- s?.type === "paragraph" || s?.type === "text" ? (s.raw += (s.raw.endsWith(`
1179
- `) ? "" : `
1180
- `) + r.raw, s.text += `
1181
- ` + r.text, this.inlineQueue.at(-1).src = s.text) : t.push(r);
1182
- continue;
1183
- }
1184
- if (r = this.tokenizer.fences(e)) {
1185
- e = e.substring(r.raw.length), t.push(r);
1186
- continue;
1187
- }
1188
- if (r = this.tokenizer.heading(e)) {
1189
- e = e.substring(r.raw.length), t.push(r);
1190
- continue;
1191
- }
1192
- if (r = this.tokenizer.hr(e)) {
1193
- e = e.substring(r.raw.length), t.push(r);
1194
- continue;
1195
- }
1196
- if (r = this.tokenizer.blockquote(e)) {
1197
- e = e.substring(r.raw.length), t.push(r);
1198
- continue;
1199
- }
1200
- if (r = this.tokenizer.list(e)) {
1201
- e = e.substring(r.raw.length), t.push(r);
1202
- continue;
1203
- }
1204
- if (r = this.tokenizer.html(e)) {
1205
- e = e.substring(r.raw.length), t.push(r);
1206
- continue;
1207
- }
1208
- if (r = this.tokenizer.def(e)) {
1209
- e = e.substring(r.raw.length);
1210
- let s = t.at(-1);
1211
- s?.type === "paragraph" || s?.type === "text" ? (s.raw += (s.raw.endsWith(`
1212
- `) ? "" : `
1213
- `) + r.raw, s.text += `
1214
- ` + r.raw, this.inlineQueue.at(-1).src = s.text) : this.tokens.links[r.tag] || (this.tokens.links[r.tag] = { href: r.href, title: r.title }, t.push(r));
1215
- continue;
1216
- }
1217
- if (r = this.tokenizer.table(e)) {
1218
- e = e.substring(r.raw.length), t.push(r);
1219
- continue;
1220
- }
1221
- if (r = this.tokenizer.lheading(e)) {
1222
- e = e.substring(r.raw.length), t.push(r);
1223
- continue;
1224
- }
1225
- let i = e;
1226
- if (this.options.extensions?.startBlock) {
1227
- let s = 1 / 0, a = e.slice(1), o;
1228
- this.options.extensions.startBlock.forEach((l) => {
1229
- o = l.call({ lexer: this }, a), typeof o == "number" && o >= 0 && (s = Math.min(s, o));
1230
- }), s < 1 / 0 && s >= 0 && (i = e.substring(0, s + 1));
1231
- }
1232
- if (this.state.top && (r = this.tokenizer.paragraph(i))) {
1233
- let s = t.at(-1);
1234
- n && s?.type === "paragraph" ? (s.raw += (s.raw.endsWith(`
1235
- `) ? "" : `
1236
- `) + r.raw, s.text += `
1237
- ` + r.text, this.inlineQueue.pop(), this.inlineQueue.at(-1).src = s.text) : t.push(r), n = i.length !== e.length, e = e.substring(r.raw.length);
1238
- continue;
1239
- }
1240
- if (r = this.tokenizer.text(e)) {
1241
- e = e.substring(r.raw.length);
1242
- let s = t.at(-1);
1243
- s?.type === "text" ? (s.raw += (s.raw.endsWith(`
1244
- `) ? "" : `
1245
- `) + r.raw, s.text += `
1246
- ` + r.text, this.inlineQueue.pop(), this.inlineQueue.at(-1).src = s.text) : t.push(r);
1247
- continue;
1248
- }
1249
- if (e) {
1250
- let s = "Infinite loop on byte: " + e.charCodeAt(0);
1251
- if (this.options.silent) {
1252
- console.error(s);
1253
- break;
1254
- } else throw new Error(s);
1255
- }
1256
- }
1257
- return this.state.top = true, t;
1258
- }
1259
- inline(e, t = []) {
1260
- return this.inlineQueue.push({ src: e, tokens: t }), t;
1261
- }
1262
- inlineTokens(e, t = []) {
1263
- this.tokenizer.lexer = this;
1264
- let n = e, r = null;
1265
- if (this.tokens.links) {
1266
- let o = Object.keys(this.tokens.links);
1267
- if (o.length > 0) for (; (r = this.tokenizer.rules.inline.reflinkSearch.exec(n)) != null; ) o.includes(r[0].slice(r[0].lastIndexOf("[") + 1, -1)) && (n = n.slice(0, r.index) + "[" + "a".repeat(r[0].length - 2) + "]" + n.slice(this.tokenizer.rules.inline.reflinkSearch.lastIndex));
1268
- }
1269
- for (; (r = this.tokenizer.rules.inline.anyPunctuation.exec(n)) != null; ) n = n.slice(0, r.index) + "++" + n.slice(this.tokenizer.rules.inline.anyPunctuation.lastIndex);
1270
- let i;
1271
- for (; (r = this.tokenizer.rules.inline.blockSkip.exec(n)) != null; ) i = r[2] ? r[2].length : 0, n = n.slice(0, r.index + i) + "[" + "a".repeat(r[0].length - i - 2) + "]" + n.slice(this.tokenizer.rules.inline.blockSkip.lastIndex);
1272
- n = this.options.hooks?.emStrongMask?.call({ lexer: this }, n) ?? n;
1273
- let s = false, a = "";
1274
- for (; e; ) {
1275
- s || (a = ""), s = false;
1276
- let o;
1277
- if (this.options.extensions?.inline?.some((p) => (o = p.call({ lexer: this }, e, t)) ? (e = e.substring(o.raw.length), t.push(o), true) : false)) continue;
1278
- if (o = this.tokenizer.escape(e)) {
1279
- e = e.substring(o.raw.length), t.push(o);
1280
- continue;
1281
- }
1282
- if (o = this.tokenizer.tag(e)) {
1283
- e = e.substring(o.raw.length), t.push(o);
1284
- continue;
1285
- }
1286
- if (o = this.tokenizer.link(e)) {
1287
- e = e.substring(o.raw.length), t.push(o);
1288
- continue;
1289
- }
1290
- if (o = this.tokenizer.reflink(e, this.tokens.links)) {
1291
- e = e.substring(o.raw.length);
1292
- let p = t.at(-1);
1293
- o.type === "text" && p?.type === "text" ? (p.raw += o.raw, p.text += o.text) : t.push(o);
1294
- continue;
1295
- }
1296
- if (o = this.tokenizer.emStrong(e, n, a)) {
1297
- e = e.substring(o.raw.length), t.push(o);
1298
- continue;
1299
- }
1300
- if (o = this.tokenizer.codespan(e)) {
1301
- e = e.substring(o.raw.length), t.push(o);
1302
- continue;
1303
- }
1304
- if (o = this.tokenizer.br(e)) {
1305
- e = e.substring(o.raw.length), t.push(o);
1306
- continue;
1307
- }
1308
- if (o = this.tokenizer.del(e, n, a)) {
1309
- e = e.substring(o.raw.length), t.push(o);
1310
- continue;
1311
- }
1312
- if (o = this.tokenizer.autolink(e)) {
1313
- e = e.substring(o.raw.length), t.push(o);
1314
- continue;
1315
- }
1316
- if (!this.state.inLink && (o = this.tokenizer.url(e))) {
1317
- e = e.substring(o.raw.length), t.push(o);
1318
- continue;
1319
- }
1320
- let l = e;
1321
- if (this.options.extensions?.startInline) {
1322
- let p = 1 / 0, c = e.slice(1), d;
1323
- this.options.extensions.startInline.forEach((h) => {
1324
- d = h.call({ lexer: this }, c), typeof d == "number" && d >= 0 && (p = Math.min(p, d));
1325
- }), p < 1 / 0 && p >= 0 && (l = e.substring(0, p + 1));
1326
- }
1327
- if (o = this.tokenizer.inlineText(l)) {
1328
- e = e.substring(o.raw.length), o.raw.slice(-1) !== "_" && (a = o.raw.slice(-1)), s = true;
1329
- let p = t.at(-1);
1330
- p?.type === "text" ? (p.raw += o.raw, p.text += o.text) : t.push(o);
1331
- continue;
1332
- }
1333
- if (e) {
1334
- let p = "Infinite loop on byte: " + e.charCodeAt(0);
1335
- if (this.options.silent) {
1336
- console.error(p);
1337
- break;
1338
- } else throw new Error(p);
1339
- }
1340
- }
1341
- return t;
1342
- }
1343
- };
1344
- var y = class {
1345
- options;
1346
- parser;
1347
- constructor(e) {
1348
- this.options = e || T;
1349
- }
1350
- space(e) {
1351
- return "";
1352
- }
1353
- code({ text: e, lang: t, escaped: n }) {
1354
- let r = (t || "").match(m.notSpaceStart)?.[0], i = e.replace(m.endingNewline, "") + `
1355
- `;
1356
- return r ? '<pre><code class="language-' + O(r) + '">' + (n ? i : O(i, true)) + `</code></pre>
1357
- ` : "<pre><code>" + (n ? i : O(i, true)) + `</code></pre>
1358
- `;
1359
- }
1360
- blockquote({ tokens: e }) {
1361
- return `<blockquote>
1362
- ${this.parser.parse(e)}</blockquote>
1363
- `;
1364
- }
1365
- html({ text: e }) {
1366
- return e;
1367
- }
1368
- def(e) {
1369
- return "";
1370
- }
1371
- heading({ tokens: e, depth: t }) {
1372
- return `<h${t}>${this.parser.parseInline(e)}</h${t}>
1373
- `;
1374
- }
1375
- hr(e) {
1376
- return `<hr>
1377
- `;
1378
- }
1379
- list(e) {
1380
- let t = e.ordered, n = e.start, r = "";
1381
- for (let a = 0; a < e.items.length; a++) {
1382
- let o = e.items[a];
1383
- r += this.listitem(o);
1384
- }
1385
- let i = t ? "ol" : "ul", s = t && n !== 1 ? ' start="' + n + '"' : "";
1386
- return "<" + i + s + `>
1387
- ` + r + "</" + i + `>
1388
- `;
1389
- }
1390
- listitem(e) {
1391
- return `<li>${this.parser.parse(e.tokens)}</li>
1392
- `;
1393
- }
1394
- checkbox({ checked: e }) {
1395
- return "<input " + (e ? 'checked="" ' : "") + 'disabled="" type="checkbox"> ';
1396
- }
1397
- paragraph({ tokens: e }) {
1398
- return `<p>${this.parser.parseInline(e)}</p>
1399
- `;
1400
- }
1401
- table(e) {
1402
- let t = "", n = "";
1403
- for (let i = 0; i < e.header.length; i++) n += this.tablecell(e.header[i]);
1404
- t += this.tablerow({ text: n });
1405
- let r = "";
1406
- for (let i = 0; i < e.rows.length; i++) {
1407
- let s = e.rows[i];
1408
- n = "";
1409
- for (let a = 0; a < s.length; a++) n += this.tablecell(s[a]);
1410
- r += this.tablerow({ text: n });
1411
- }
1412
- return r && (r = `<tbody>${r}</tbody>`), `<table>
1413
- <thead>
1414
- ` + t + `</thead>
1415
- ` + r + `</table>
1416
- `;
1417
- }
1418
- tablerow({ text: e }) {
1419
- return `<tr>
1420
- ${e}</tr>
1421
- `;
1422
- }
1423
- tablecell(e) {
1424
- let t = this.parser.parseInline(e.tokens), n = e.header ? "th" : "td";
1425
- return (e.align ? `<${n} align="${e.align}">` : `<${n}>`) + t + `</${n}>
1426
- `;
1427
- }
1428
- strong({ tokens: e }) {
1429
- return `<strong>${this.parser.parseInline(e)}</strong>`;
1430
- }
1431
- em({ tokens: e }) {
1432
- return `<em>${this.parser.parseInline(e)}</em>`;
1433
- }
1434
- codespan({ text: e }) {
1435
- return `<code>${O(e, true)}</code>`;
1436
- }
1437
- br(e) {
1438
- return "<br>";
1439
- }
1440
- del({ tokens: e }) {
1441
- return `<del>${this.parser.parseInline(e)}</del>`;
1442
- }
1443
- link({ href: e, title: t, tokens: n }) {
1444
- let r = this.parser.parseInline(n), i = J(e);
1445
- if (i === null) return r;
1446
- e = i;
1447
- let s = '<a href="' + e + '"';
1448
- return t && (s += ' title="' + O(t) + '"'), s += ">" + r + "</a>", s;
1449
- }
1450
- image({ href: e, title: t, text: n, tokens: r }) {
1451
- r && (n = this.parser.parseInline(r, this.parser.textRenderer));
1452
- let i = J(e);
1453
- if (i === null) return O(n);
1454
- e = i;
1455
- let s = `<img src="${e}" alt="${O(n)}"`;
1456
- return t && (s += ` title="${O(t)}"`), s += ">", s;
1457
- }
1458
- text(e) {
1459
- return "tokens" in e && e.tokens ? this.parser.parseInline(e.tokens) : "escaped" in e && e.escaped ? e.text : O(e.text);
1460
- }
1461
- };
1462
- var $ = class {
1463
- strong({ text: e }) {
1464
- return e;
1465
- }
1466
- em({ text: e }) {
1467
- return e;
1468
- }
1469
- codespan({ text: e }) {
1470
- return e;
1471
- }
1472
- del({ text: e }) {
1473
- return e;
1474
- }
1475
- html({ text: e }) {
1476
- return e;
1477
- }
1478
- text({ text: e }) {
1479
- return e;
1480
- }
1481
- link({ text: e }) {
1482
- return "" + e;
1483
- }
1484
- image({ text: e }) {
1485
- return "" + e;
1486
- }
1487
- br() {
1488
- return "";
1489
- }
1490
- checkbox({ raw: e }) {
1491
- return e;
1492
- }
1493
- };
1494
- var b = class u2 {
1495
- options;
1496
- renderer;
1497
- textRenderer;
1498
- constructor(e) {
1499
- this.options = e || T, this.options.renderer = this.options.renderer || new y(), this.renderer = this.options.renderer, this.renderer.options = this.options, this.renderer.parser = this, this.textRenderer = new $();
1500
- }
1501
- static parse(e, t) {
1502
- return new u2(t).parse(e);
1503
- }
1504
- static parseInline(e, t) {
1505
- return new u2(t).parseInline(e);
1506
- }
1507
- parse(e) {
1508
- this.renderer.parser = this;
1509
- let t = "";
1510
- for (let n = 0; n < e.length; n++) {
1511
- let r = e[n];
1512
- if (this.options.extensions?.renderers?.[r.type]) {
1513
- let s = r, a = this.options.extensions.renderers[s.type].call({ parser: this }, s);
1514
- if (a !== false || !["space", "hr", "heading", "code", "table", "blockquote", "list", "html", "def", "paragraph", "text"].includes(s.type)) {
1515
- t += a || "";
1516
- continue;
1517
- }
1518
- }
1519
- let i = r;
1520
- switch (i.type) {
1521
- case "space": {
1522
- t += this.renderer.space(i);
1523
- break;
1524
- }
1525
- case "hr": {
1526
- t += this.renderer.hr(i);
1527
- break;
1528
- }
1529
- case "heading": {
1530
- t += this.renderer.heading(i);
1531
- break;
1532
- }
1533
- case "code": {
1534
- t += this.renderer.code(i);
1535
- break;
1536
- }
1537
- case "table": {
1538
- t += this.renderer.table(i);
1539
- break;
1540
- }
1541
- case "blockquote": {
1542
- t += this.renderer.blockquote(i);
1543
- break;
1544
- }
1545
- case "list": {
1546
- t += this.renderer.list(i);
1547
- break;
1548
- }
1549
- case "checkbox": {
1550
- t += this.renderer.checkbox(i);
1551
- break;
1552
- }
1553
- case "html": {
1554
- t += this.renderer.html(i);
1555
- break;
1556
- }
1557
- case "def": {
1558
- t += this.renderer.def(i);
1559
- break;
1560
- }
1561
- case "paragraph": {
1562
- t += this.renderer.paragraph(i);
1563
- break;
1564
- }
1565
- case "text": {
1566
- t += this.renderer.text(i);
1567
- break;
1568
- }
1569
- default: {
1570
- let s = 'Token with "' + i.type + '" type was not found.';
1571
- if (this.options.silent) return console.error(s), "";
1572
- throw new Error(s);
1573
- }
1574
- }
1575
- }
1576
- return t;
1577
- }
1578
- parseInline(e, t = this.renderer) {
1579
- this.renderer.parser = this;
1580
- let n = "";
1581
- for (let r = 0; r < e.length; r++) {
1582
- let i = e[r];
1583
- if (this.options.extensions?.renderers?.[i.type]) {
1584
- let a = this.options.extensions.renderers[i.type].call({ parser: this }, i);
1585
- if (a !== false || !["escape", "html", "link", "image", "strong", "em", "codespan", "br", "del", "text"].includes(i.type)) {
1586
- n += a || "";
1587
- continue;
1588
- }
1589
- }
1590
- let s = i;
1591
- switch (s.type) {
1592
- case "escape": {
1593
- n += t.text(s);
1594
- break;
1595
- }
1596
- case "html": {
1597
- n += t.html(s);
1598
- break;
1599
- }
1600
- case "link": {
1601
- n += t.link(s);
1602
- break;
1603
- }
1604
- case "image": {
1605
- n += t.image(s);
1606
- break;
1607
- }
1608
- case "checkbox": {
1609
- n += t.checkbox(s);
1610
- break;
1611
- }
1612
- case "strong": {
1613
- n += t.strong(s);
1614
- break;
1615
- }
1616
- case "em": {
1617
- n += t.em(s);
1618
- break;
1619
- }
1620
- case "codespan": {
1621
- n += t.codespan(s);
1622
- break;
1623
- }
1624
- case "br": {
1625
- n += t.br(s);
1626
- break;
1627
- }
1628
- case "del": {
1629
- n += t.del(s);
1630
- break;
1631
- }
1632
- case "text": {
1633
- n += t.text(s);
1634
- break;
1635
- }
1636
- default: {
1637
- let a = 'Token with "' + s.type + '" type was not found.';
1638
- if (this.options.silent) return console.error(a), "";
1639
- throw new Error(a);
1640
- }
1641
- }
1642
- }
1643
- return n;
1644
- }
1645
- };
1646
- var P = class {
1647
- options;
1648
- block;
1649
- constructor(e) {
1650
- this.options = e || T;
1651
- }
1652
- static passThroughHooks = /* @__PURE__ */ new Set(["preprocess", "postprocess", "processAllTokens", "emStrongMask"]);
1653
- static passThroughHooksRespectAsync = /* @__PURE__ */ new Set(["preprocess", "postprocess", "processAllTokens"]);
1654
- preprocess(e) {
1655
- return e;
1656
- }
1657
- postprocess(e) {
1658
- return e;
1659
- }
1660
- processAllTokens(e) {
1661
- return e;
1662
- }
1663
- emStrongMask(e) {
1664
- return e;
1665
- }
1666
- provideLexer() {
1667
- return this.block ? x.lex : x.lexInline;
1668
- }
1669
- provideParser() {
1670
- return this.block ? b.parse : b.parseInline;
1671
- }
1672
- };
1673
- var D = class {
1674
- defaults = M();
1675
- options = this.setOptions;
1676
- parse = this.parseMarkdown(true);
1677
- parseInline = this.parseMarkdown(false);
1678
- Parser = b;
1679
- Renderer = y;
1680
- TextRenderer = $;
1681
- Lexer = x;
1682
- Tokenizer = w;
1683
- Hooks = P;
1684
- constructor(...e) {
1685
- this.use(...e);
1686
- }
1687
- walkTokens(e, t) {
1688
- let n = [];
1689
- for (let r of e) switch (n = n.concat(t.call(this, r)), r.type) {
1690
- case "table": {
1691
- let i = r;
1692
- for (let s of i.header) n = n.concat(this.walkTokens(s.tokens, t));
1693
- for (let s of i.rows) for (let a of s) n = n.concat(this.walkTokens(a.tokens, t));
1694
- break;
1695
- }
1696
- case "list": {
1697
- let i = r;
1698
- n = n.concat(this.walkTokens(i.items, t));
1699
- break;
1700
- }
1701
- default: {
1702
- let i = r;
1703
- this.defaults.extensions?.childTokens?.[i.type] ? this.defaults.extensions.childTokens[i.type].forEach((s) => {
1704
- let a = i[s].flat(1 / 0);
1705
- n = n.concat(this.walkTokens(a, t));
1706
- }) : i.tokens && (n = n.concat(this.walkTokens(i.tokens, t)));
1707
- }
1708
- }
1709
- return n;
1710
- }
1711
- use(...e) {
1712
- let t = this.defaults.extensions || { renderers: {}, childTokens: {} };
1713
- return e.forEach((n) => {
1714
- let r = { ...n };
1715
- if (r.async = this.defaults.async || r.async || false, n.extensions && (n.extensions.forEach((i) => {
1716
- if (!i.name) throw new Error("extension name required");
1717
- if ("renderer" in i) {
1718
- let s = t.renderers[i.name];
1719
- s ? t.renderers[i.name] = function(...a) {
1720
- let o = i.renderer.apply(this, a);
1721
- return o === false && (o = s.apply(this, a)), o;
1722
- } : t.renderers[i.name] = i.renderer;
1723
- }
1724
- if ("tokenizer" in i) {
1725
- if (!i.level || i.level !== "block" && i.level !== "inline") throw new Error("extension level must be 'block' or 'inline'");
1726
- let s = t[i.level];
1727
- s ? s.unshift(i.tokenizer) : t[i.level] = [i.tokenizer], i.start && (i.level === "block" ? t.startBlock ? t.startBlock.push(i.start) : t.startBlock = [i.start] : i.level === "inline" && (t.startInline ? t.startInline.push(i.start) : t.startInline = [i.start]));
1728
- }
1729
- "childTokens" in i && i.childTokens && (t.childTokens[i.name] = i.childTokens);
1730
- }), r.extensions = t), n.renderer) {
1731
- let i = this.defaults.renderer || new y(this.defaults);
1732
- for (let s in n.renderer) {
1733
- if (!(s in i)) throw new Error(`renderer '${s}' does not exist`);
1734
- if (["options", "parser"].includes(s)) continue;
1735
- let a = s, o = n.renderer[a], l = i[a];
1736
- i[a] = (...p) => {
1737
- let c = o.apply(i, p);
1738
- return c === false && (c = l.apply(i, p)), c || "";
1739
- };
1740
- }
1741
- r.renderer = i;
1742
- }
1743
- if (n.tokenizer) {
1744
- let i = this.defaults.tokenizer || new w(this.defaults);
1745
- for (let s in n.tokenizer) {
1746
- if (!(s in i)) throw new Error(`tokenizer '${s}' does not exist`);
1747
- if (["options", "rules", "lexer"].includes(s)) continue;
1748
- let a = s, o = n.tokenizer[a], l = i[a];
1749
- i[a] = (...p) => {
1750
- let c = o.apply(i, p);
1751
- return c === false && (c = l.apply(i, p)), c;
1752
- };
1753
- }
1754
- r.tokenizer = i;
1755
- }
1756
- if (n.hooks) {
1757
- let i = this.defaults.hooks || new P();
1758
- for (let s in n.hooks) {
1759
- if (!(s in i)) throw new Error(`hook '${s}' does not exist`);
1760
- if (["options", "block"].includes(s)) continue;
1761
- let a = s, o = n.hooks[a], l = i[a];
1762
- P.passThroughHooks.has(s) ? i[a] = (p) => {
1763
- if (this.defaults.async && P.passThroughHooksRespectAsync.has(s)) return (async () => {
1764
- let d = await o.call(i, p);
1765
- return l.call(i, d);
1766
- })();
1767
- let c = o.call(i, p);
1768
- return l.call(i, c);
1769
- } : i[a] = (...p) => {
1770
- if (this.defaults.async) return (async () => {
1771
- let d = await o.apply(i, p);
1772
- return d === false && (d = await l.apply(i, p)), d;
1773
- })();
1774
- let c = o.apply(i, p);
1775
- return c === false && (c = l.apply(i, p)), c;
1776
- };
1777
- }
1778
- r.hooks = i;
1779
- }
1780
- if (n.walkTokens) {
1781
- let i = this.defaults.walkTokens, s = n.walkTokens;
1782
- r.walkTokens = function(a) {
1783
- let o = [];
1784
- return o.push(s.call(this, a)), i && (o = o.concat(i.call(this, a))), o;
1785
- };
1786
- }
1787
- this.defaults = { ...this.defaults, ...r };
1788
- }), this;
1789
- }
1790
- setOptions(e) {
1791
- return this.defaults = { ...this.defaults, ...e }, this;
1792
- }
1793
- lexer(e, t) {
1794
- return x.lex(e, t ?? this.defaults);
1795
- }
1796
- parser(e, t) {
1797
- return b.parse(e, t ?? this.defaults);
1798
- }
1799
- parseMarkdown(e) {
1800
- return (n, r) => {
1801
- let i = { ...r }, s = { ...this.defaults, ...i }, a = this.onError(!!s.silent, !!s.async);
1802
- if (this.defaults.async === true && i.async === false) return a(new Error("marked(): The async option was set to true by an extension. Remove async: false from the parse options object to return a Promise."));
1803
- if (typeof n > "u" || n === null) return a(new Error("marked(): input parameter is undefined or null"));
1804
- if (typeof n != "string") return a(new Error("marked(): input parameter is of type " + Object.prototype.toString.call(n) + ", string expected"));
1805
- if (s.hooks && (s.hooks.options = s, s.hooks.block = e), s.async) return (async () => {
1806
- let o = s.hooks ? await s.hooks.preprocess(n) : n, p = await (s.hooks ? await s.hooks.provideLexer() : e ? x.lex : x.lexInline)(o, s), c = s.hooks ? await s.hooks.processAllTokens(p) : p;
1807
- s.walkTokens && await Promise.all(this.walkTokens(c, s.walkTokens));
1808
- let h = await (s.hooks ? await s.hooks.provideParser() : e ? b.parse : b.parseInline)(c, s);
1809
- return s.hooks ? await s.hooks.postprocess(h) : h;
1810
- })().catch(a);
1811
- try {
1812
- s.hooks && (n = s.hooks.preprocess(n));
1813
- let l = (s.hooks ? s.hooks.provideLexer() : e ? x.lex : x.lexInline)(n, s);
1814
- s.hooks && (l = s.hooks.processAllTokens(l)), s.walkTokens && this.walkTokens(l, s.walkTokens);
1815
- let c = (s.hooks ? s.hooks.provideParser() : e ? b.parse : b.parseInline)(l, s);
1816
- return s.hooks && (c = s.hooks.postprocess(c)), c;
1817
- } catch (o) {
1818
- return a(o);
1819
- }
1820
- };
1821
- }
1822
- onError(e, t) {
1823
- return (n) => {
1824
- if (n.message += `
1825
- Please report this to https://github.com/markedjs/marked.`, e) {
1826
- let r = "<p>An error occurred:</p><pre>" + O(n.message + "", true) + "</pre>";
1827
- return t ? Promise.resolve(r) : r;
1828
- }
1829
- if (t) return Promise.reject(n);
1830
- throw n;
1831
- };
1832
- }
1833
- };
1834
- var L = new D();
1835
- function g(u3, e) {
1836
- return L.parse(u3, e);
1837
- }
1838
- g.options = g.setOptions = function(u3) {
1839
- return L.setOptions(u3), g.defaults = L.defaults, G(g.defaults), g;
1840
- };
1841
- g.getDefaults = M;
1842
- g.defaults = T;
1843
- g.use = function(...u3) {
1844
- return L.use(...u3), g.defaults = L.defaults, G(g.defaults), g;
1845
- };
1846
- g.walkTokens = function(u3, e) {
1847
- return L.walkTokens(u3, e);
1848
- };
1849
- g.parseInline = L.parseInline;
1850
- g.Parser = b;
1851
- g.parser = b.parse;
1852
- g.Renderer = y;
1853
- g.TextRenderer = $;
1854
- g.Lexer = x;
1855
- g.lexer = x.lex;
1856
- g.Tokenizer = w;
1857
- g.Hooks = P;
1858
- g.parse = g;
1859
- var Qt = g.options;
1860
- var jt = g.setOptions;
1861
- var Ft = g.use;
1862
- var Ut = g.walkTokens;
1863
- var Kt = g.parseInline;
1864
- var Xt = b.parse;
1865
- var Jt = x.lex;
1866
-
1867
- // packages/extensions/pages/src/markdown.ts
1868
- var marked = new D({ gfm: true });
1869
- var BASE_STYLES = `
1870
- *, *::before, *::after { box-sizing: border-box; }
1871
- body {
1872
- max-width: 48rem;
1873
- margin: 2rem auto;
1874
- padding: 0 1rem;
1875
- font-family: system-ui, -apple-system, sans-serif;
1876
- line-height: 1.6;
1877
- color: #1a1a1a;
1878
- }
1879
- h1, h2, h3, h4, h5, h6 { margin-top: 1.5em; margin-bottom: 0.5em; line-height: 1.3; }
1880
- h1 { font-size: 2em; }
1881
- a { color: #2563eb; }
1882
- code {
1883
- font-family: ui-monospace, "SFMono-Regular", monospace;
1884
- font-size: 0.9em;
1885
- background: #f3f4f6;
1886
- padding: 0.15em 0.3em;
1887
- border-radius: 3px;
1888
- }
1889
- pre {
1890
- background: #f3f4f6;
1891
- padding: 1em;
1892
- border-radius: 6px;
1893
- overflow-x: auto;
1894
- }
1895
- pre code { background: none; padding: 0; }
1896
- blockquote {
1897
- border-left: 3px solid #d1d5db;
1898
- margin-left: 0;
1899
- padding-left: 1em;
1900
- color: #4b5563;
1901
- }
1902
- table { border-collapse: collapse; width: 100%; }
1903
- th, td { border: 1px solid #d1d5db; padding: 0.5em 0.75em; text-align: left; }
1904
- th { background: #f9fafb; }
1905
- img { max-width: 100%; height: auto; }
1906
- hr { border: none; border-top: 1px solid #d1d5db; margin: 2em 0; }
1907
- `;
1908
- function escapeHtml(s) {
1909
- return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
1910
- }
1911
- function parseFrontmatter(raw) {
1912
- const match = raw.match(/^---\n([\s\S]*?)\n---\n?/);
1913
- if (!match) return { body: raw };
1914
- const block = match[1];
1915
- const body = raw.slice(match[0].length);
1916
- const titleMatch = block.match(/^title:\s*(.+)$/m);
1917
- const styleMatch = block.match(/^style:\s*(.+)$/m);
1918
- return {
1919
- title: titleMatch?.[1].trim(),
1920
- style: styleMatch?.[1].trim(),
1921
- body
1922
- };
1923
- }
1924
- function resolveStylesheet(mdFilePath, pagesRoot, frontmatterStyle) {
1925
- if (frontmatterStyle) {
1926
- const abs = resolve3(pagesRoot, frontmatterStyle);
1927
- if (abs.startsWith(pagesRoot + "/") && existsSync3(abs)) return frontmatterStyle;
1928
- }
1929
- const dir = dirname(mdFilePath);
1930
- const localCss = resolve3(dir, "style.css");
1931
- if (existsSync3(localCss)) return relative3(pagesRoot, localCss);
1932
- if (dir !== pagesRoot) {
1933
- const rootCss = resolve3(pagesRoot, "style.css");
1934
- if (existsSync3(rootCss)) return "style.css";
1935
- }
1936
- return null;
1937
- }
1938
- async function renderMarkdownPage(body, opts) {
1939
- const html = await marked.parse(body);
1940
- const title = escapeHtml(opts.title || "Untitled");
1941
- const linkTag = opts.stylesheetUrl ? `
1942
- <link rel="stylesheet" href="${escapeHtml(opts.stylesheetUrl)}">` : "";
1943
- return `<!DOCTYPE html>
1944
- <html lang="en">
1945
- <head>
1946
- <meta charset="utf-8">
1947
- <meta name="viewport" content="width=device-width, initial-scale=1">
1948
- <title>${title}</title>
1949
- <style>${BASE_STYLES}</style>${linkTag}
1950
- </head>
1951
- <body>
1952
- <article>${html}</article>
1953
- </body>
1954
- </html>`;
1955
- }
1956
-
1957
- // packages/extensions/pages/src/routes.ts
1958
- var MIME_TYPES = {
1959
- ".html": "text/html",
1960
- ".js": "application/javascript",
1961
- ".css": "text/css",
1962
- ".json": "application/json",
1963
- ".svg": "image/svg+xml",
1964
- ".png": "image/png",
1965
- ".jpg": "image/jpeg",
1966
- ".jpeg": "image/jpeg",
1967
- ".gif": "image/gif",
1968
- ".ico": "image/x-icon",
1969
- ".woff": "font/woff",
1970
- ".woff2": "font/woff2",
1971
- ".txt": "text/plain",
1972
- ".xml": "application/xml"
1973
- };
1974
- function createRoutes(ctx) {
1975
- return new Hono().get("/", async (c) => {
1976
- if (!ctx.db) return c.json({ error: "Pages database not available" }, 503);
1977
- const { sites, systemSite } = getSites(ctx.db);
1978
- const recentPages = getRecentPagesList(ctx.db);
1979
- return c.json({ sites, systemSite, recentPages });
1980
- }).get("/feed", async (c) => {
1981
- if (!ctx.db) return c.json({ error: "Pages database not available" }, 503);
1982
- const mind = c.req.query("mind");
1983
- const rawLimit = c.req.query("limit");
1984
- const limit = rawLimit ? parseInt(rawLimit, 10) || 8 : 8;
1985
- const recentPages = getRecentPagesList(ctx.db, { mind: mind || void 0, limit });
1986
- return c.json(
1987
- recentPages.map((p) => ({
1988
- id: `page-${p.mind}-${p.file}`,
1989
- title: `${p.mind}/${p.file}`,
1990
- url: p.url ?? `/minds/${p.mind}/pages/${p.file}`,
1991
- date: p.modified,
1992
- author: p.mind,
1993
- bodyHtml: `<p>Page updated</p>`,
1994
- iframeUrl: `/ext/pages/public/${p.mind}/${p.file}`,
1995
- icon: '<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><circle cx="8" cy="8" r="6"/><path d="M2 8h12M8 2c-2 2-2 10 0 12M8 2c2 2 2 10 0 12"/></svg>',
1996
- color: "purple"
1997
- }))
1998
- );
1999
- }).put("/publish/:name", async (c) => {
2000
- const user = ctx.resolveUser(c);
2001
- if (!user) return c.json({ error: "Unauthorized" }, 401);
2002
- const name = c.req.param("name");
2003
- if (user.role !== "admin" && user.username !== name) {
2004
- return c.json({ error: "Forbidden" }, 403);
2005
- }
2006
- const config = ctx.getSystemsConfig();
2007
- if (!config) return c.json({ error: "Not connected to volute.systems" }, 400);
2008
- const body = await c.req.text();
2009
- try {
2010
- const res = await fetch(`${config.apiUrl}/api/pages/publish/${name}`, {
2011
- method: "PUT",
2012
- headers: {
2013
- "Content-Type": "application/json",
2014
- Authorization: `Bearer ${config.apiKey}`
2015
- },
2016
- body
2017
- });
2018
- const data = await res.json().catch(() => ({ error: `HTTP ${res.status}` }));
2019
- return c.json(data, res.status);
2020
- } catch (err) {
2021
- return c.json({ error: `Connection failed: ${err.message}` }, 502);
2022
- }
2023
- }).get("/status/:name", async (c) => {
2024
- const user = ctx.resolveUser(c);
2025
- if (!user) return c.json({ error: "Unauthorized" }, 401);
2026
- const name = c.req.param("name");
2027
- if (user.role !== "admin" && user.username !== name) {
2028
- return c.json({ error: "Forbidden" }, 403);
2029
- }
2030
- const config = ctx.getSystemsConfig();
2031
- if (!config) return c.json({ error: "Not connected to volute.systems" }, 400);
2032
- try {
2033
- const res = await fetch(`${config.apiUrl}/api/pages/status/${name}`, {
2034
- headers: { Authorization: `Bearer ${config.apiKey}` }
2035
- });
2036
- const data = await res.json().catch(() => ({ error: `HTTP ${res.status}` }));
2037
- return c.json(data, res.status);
2038
- } catch (err) {
2039
- return c.json({ error: `Connection failed: ${err.message}` }, 502);
2040
- }
2041
- });
2042
- }
2043
- function createPublicRoutes(ctx) {
2044
- return new Hono().get("/:name/*", async (c) => {
2045
- const name = c.req.param("name");
2046
- if (name.includes("/") || name.includes("\\") || name === "." || name === "..")
2047
- return c.text("Not found", 404);
2048
- let pagesRoot;
2049
- let blockDotfiles = false;
2050
- if (name === "_system") {
2051
- pagesRoot = resolve4(ctx.dataDir, "repo");
2052
- blockDotfiles = true;
2053
- } else {
2054
- pagesRoot = resolve4(ctx.dataDir, "sites", name);
2055
- }
2056
- const prefix = `/public/${name}`;
2057
- const idx = c.req.path.indexOf(prefix);
2058
- const wildcard = idx >= 0 ? c.req.path.slice(idx + prefix.length) : "/";
2059
- const requestedPath = resolve4(pagesRoot, wildcard.slice(1));
2060
- if (requestedPath !== pagesRoot && !requestedPath.startsWith(`${pagesRoot}/`))
2061
- return c.text("Forbidden", 403);
2062
- if (blockDotfiles) {
2063
- const relativePath = requestedPath.slice(pagesRoot.length + 1);
2064
- if (relativePath.split("/").some((seg) => seg.startsWith(".")))
2065
- return c.text("Not found", 404);
2066
- }
2067
- let fileToServe = requestedPath;
2068
- let fileStat = await stat(requestedPath).catch(() => null);
2069
- if (fileStat?.isDirectory()) {
2070
- const indexPath = resolve4(requestedPath, "index.html");
2071
- fileStat = await stat(indexPath).catch(() => null);
2072
- if (fileStat?.isFile()) {
2073
- fileToServe = indexPath;
2074
- } else {
2075
- const mdIndexPath = resolve4(requestedPath, "index.md");
2076
- fileStat = await stat(mdIndexPath).catch(() => null);
2077
- if (fileStat?.isFile()) {
2078
- fileToServe = mdIndexPath;
2079
- } else {
2080
- return c.text("Not found", 404);
2081
- }
2082
- }
2083
- } else if (!fileStat?.isFile()) {
2084
- return c.text("Not found", 404);
2085
- }
2086
- const ext = extname(fileToServe);
2087
- try {
2088
- if (ext === ".md") {
2089
- const content = await readFile(fileToServe, "utf-8");
2090
- const { title, style, body: body2 } = parseFrontmatter(content);
2091
- const cssRelPath = resolveStylesheet(fileToServe, pagesRoot, style);
2092
- const cssUrl = cssRelPath ? `/ext/pages/public/${name}/${cssRelPath}` : void 0;
2093
- const html = await renderMarkdownPage(body2, { title, stylesheetUrl: cssUrl });
2094
- return c.body(html, 200, { "Content-Type": "text/html; charset=utf-8" });
2095
- }
2096
- const mime = MIME_TYPES[ext] || "application/octet-stream";
2097
- const body = await readFile(fileToServe);
2098
- return c.body(body, 200, { "Content-Type": mime });
2099
- } catch (err) {
2100
- const code = err.code;
2101
- if (code === "EACCES") return c.text("Forbidden", 403);
2102
- if (code === "ENOENT") return c.text("Not found", 404);
2103
- console.error(`[pages] error serving ${fileToServe}:`, err.message);
2104
- return c.text("Internal server error", 500);
2105
- }
2106
- });
2107
- }
2108
-
2109
- // packages/extensions/pages/src/index.ts
2110
- var assetsDir = resolve5(import.meta.dirname, "../dist/ui");
2111
- var skillsDir = resolve5(import.meta.dirname, "../skills");
2112
- var src_default = createExtension({
2113
- id: "pages",
2114
- name: "Pages",
2115
- version: "0.1.0",
2116
- description: "Publish and serve web pages from mind directories",
2117
- initDb,
2118
- routes: (ctx) => createRoutes(ctx),
2119
- publicRoutes: (ctx) => createPublicRoutes(ctx),
2120
- commands: createCommands(),
2121
- skillsDir,
2122
- standardSkill: true,
2123
- icon: '<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><rect x="1" y="2" width="14" height="12" rx="1.5"/><path d="M1 5h14"/><circle cx="3" cy="3.5" r="0.5" fill="currentColor" stroke="none"/><circle cx="5" cy="3.5" r="0.5" fill="currentColor" stroke="none"/></svg>',
2124
- color: "purple",
2125
- ui: {
2126
- assetsDir,
2127
- systemSection: {
2128
- id: "pages",
2129
- label: "Pages",
2130
- urlPatterns: ["/pages", "/pages/:site", "/pages/:site/:path"]
2131
- },
2132
- mindSections: [{ id: "pages", label: "Pages" }],
2133
- feedSource: {
2134
- endpoint: "/api/ext/pages/feed"
2135
- }
2136
- },
2137
- onDaemonStart(ctx) {
2138
- ensurePagesRepo(ctx.dataDir, isolationFrom(ctx)).then(() => {
2139
- if (ctx.db) {
2140
- const repoDir = resolve5(ctx.dataDir, "repo");
2141
- const htmlFiles = collectHtmlFiles(repoDir);
2142
- if (htmlFiles.length > 0) {
2143
- try {
2144
- syncSystemPages(ctx.db, htmlFiles);
2145
- } catch (err) {
2146
- console.error("[pages] failed to sync system pages to DB:", err);
2147
- }
2148
- }
2149
- }
2150
- }).catch((err) => {
2151
- console.error("[pages] failed to initialize pages repo:", err);
2152
- });
2153
- },
2154
- onMindStart(mindName, ctx) {
2155
- const mindDir = ctx.getMindDir(mindName);
2156
- if (!mindDir) return;
2157
- addPagesWorktree(mindName, mindDir, ctx.dataDir, isolationFrom(ctx)).catch((err) => {
2158
- console.error(`[pages] failed to add pages worktree for ${mindName}:`, err);
2159
- });
2160
- }
2161
- });
2162
- export {
2163
- src_default as default
2164
- };