@rafiqui987/markode 0.4.1 → 0.4.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +333 -74
- package/dist/web/assets/{abnfDiagram-WEYOIA3C-B-3Lcktj.js → abnfDiagram-WEYOIA3C-C2SJjHni.js} +1 -1
- package/dist/web/assets/{arc-B1vQQwbr.js → arc-Cx8Du0ud.js} +1 -1
- package/dist/web/assets/{architecture-WOLXFQ4H-D8_qhlNG.js → architecture-WOLXFQ4H-Cb7DZ4zr.js} +1 -1
- package/dist/web/assets/{architectureDiagram-ZHVYKT53-B4uGFnQg.js → architectureDiagram-ZHVYKT53-CGIbomEe.js} +1 -1
- package/dist/web/assets/{blockDiagram-RJAE7QA3-B1PRI2Fk.js → blockDiagram-RJAE7QA3-CxJLYpHi.js} +1 -1
- package/dist/web/assets/{c4Diagram-XDPPPE54-BOSiNgn_.js → c4Diagram-XDPPPE54-C3TE3am8.js} +1 -1
- package/dist/web/assets/channel-Dcw9X94G.js +1 -0
- package/dist/web/assets/{chunk-2E7WHVMD-B2TT-9T2.js → chunk-2E7WHVMD-Bg92ygkh.js} +1 -1
- package/dist/web/assets/{chunk-4EMNKR2T-BJStHb31.js → chunk-4EMNKR2T-CkWHQjq0.js} +1 -1
- package/dist/web/assets/{chunk-55XCU76K-CGSdzfU6.js → chunk-55XCU76K-FdEXCejS.js} +1 -1
- package/dist/web/assets/{chunk-7S6XSTFO-D7U3aXUK.js → chunk-7S6XSTFO-daOCefKF.js} +1 -1
- package/dist/web/assets/{chunk-AQDTSKZB-C6fkREWV.js → chunk-AQDTSKZB-C_O7jTkL.js} +1 -1
- package/dist/web/assets/{chunk-DSNLSHJZ-C0Wri32R.js → chunk-DSNLSHJZ-CK3bwwQ-.js} +1 -1
- package/dist/web/assets/{chunk-HAGFOTED-dS3yjqSY.js → chunk-HAGFOTED-opIvHyBo.js} +1 -1
- package/dist/web/assets/{chunk-HNE4Q36P-B0HJeFYe.js → chunk-HNE4Q36P-BL3zDF5M.js} +1 -1
- package/dist/web/assets/{chunk-NQOKRVIF-DCR-ZD6p.js → chunk-NQOKRVIF-CinujSFs.js} +1 -1
- package/dist/web/assets/{chunk-UHW7PFBP-DvXVrsgg.js → chunk-UHW7PFBP-d0gZdn-g.js} +1 -1
- package/dist/web/assets/{chunk-VQ5W62QI-mU_IBCXT.js → chunk-VQ5W62QI-B_xkLXrb.js} +1 -1
- package/dist/web/assets/{chunk-WQQL4CDK-DnyUQt3W.js → chunk-WQQL4CDK-DOuJFSVX.js} +1 -1
- package/dist/web/assets/{chunk-XXDRQBXY-DNhISORq.js → chunk-XXDRQBXY-CDlxlAW4.js} +1 -1
- package/dist/web/assets/{chunk-YZO67HFG-C_oEIdWe.js → chunk-YZO67HFG-BdDkz7-r.js} +1 -1
- package/dist/web/assets/{chunk-ZAUX2LTX-D5aMvPiJ.js → chunk-ZAUX2LTX-BaIU0CWB.js} +1 -1
- package/dist/web/assets/{chunk-ZCHMQSOR-B5J6sRpu.js → chunk-ZCHMQSOR-D9qWy94b.js} +1 -1
- package/dist/web/assets/{classDiagram-v2-4MYWR3UA-D4-o3iga.js → classDiagram-v2-4MYWR3UA-D1SE7F9-.js} +1 -1
- package/dist/web/assets/{cose-bilkent-JH36ORCC-CqNUB7G6.js → cose-bilkent-JH36ORCC-C2ELhXyb.js} +1 -1
- package/dist/web/assets/{cynefin-EF2NZ3EQ-BLBtXLl2.js → cynefin-EF2NZ3EQ-BsGiTfQX.js} +1 -1
- package/dist/web/assets/{cynefinDiagram-WF24UDRP-BlytpdKL.js → cynefinDiagram-WF24UDRP-Bs1ZtI6B.js} +1 -1
- package/dist/web/assets/{dagre-NK4GIZVX-DIUkOqo_.js → dagre-NK4GIZVX-DpWeBJ_u.js} +1 -1
- package/dist/web/assets/{diagram-CBK3MWTC-4WJqLswq.js → diagram-CBK3MWTC-4v-6xiYz.js} +1 -1
- package/dist/web/assets/{diagram-I5XIIV2D-s1EUO6xt.js → diagram-I5XIIV2D-Dzu2bn9N.js} +1 -1
- package/dist/web/assets/{diagram-ODIL2UCW-GvgDR4t8.js → diagram-ODIL2UCW-B-ZVeg44.js} +1 -1
- package/dist/web/assets/{diagram-PFBEJUXE-B6J9SedW.js → diagram-PFBEJUXE-Ctbwu_Qd.js} +1 -1
- package/dist/web/assets/{diagram-RJA3I4VV-CqA7qcNf.js → diagram-RJA3I4VV-C6jtr4QM.js} +1 -1
- package/dist/web/assets/{diagram-TYUNFSNR-Cln9POlx.js → diagram-TYUNFSNR-BLJ5rEgp.js} +1 -1
- package/dist/web/assets/{dist--fImHE6g.js → dist-BgauZQpT.js} +1 -1
- package/dist/web/assets/{dist-YudOLIZ5.js → dist-CYz0my_F.js} +1 -1
- package/dist/web/assets/{dist-Cd1DR3ly.js → dist-CZwyjOXO.js} +1 -1
- package/dist/web/assets/{dist-CVF0b6Yz.js → dist-Cihah0nd.js} +1 -1
- package/dist/web/assets/{dist-Bg-QtHy9.js → dist-CuHat3Fb.js} +1 -1
- package/dist/web/assets/{dist-BghTt_37.js → dist-DZRwaECR.js} +1 -1
- package/dist/web/assets/{dist-xGXJDvke.js → dist-DfBSxfI7.js} +1 -1
- package/dist/web/assets/{dist-DpqggjJG.js → dist-Dih0lXFk.js} +1 -1
- package/dist/web/assets/{dist-CU6eXj3N.js → dist-DogGhkjl.js} +1 -1
- package/dist/web/assets/{dist-CoioyMmF.js → dist-FYTUKDRT.js} +1 -1
- package/dist/web/assets/{dist-CykDxBaO.js → dist-T0asI_P_.js} +1 -1
- package/dist/web/assets/{ebnfDiagram-V4P3TTPT-BusXM5tX.js → ebnfDiagram-V4P3TTPT-Db6BDS1i.js} +1 -1
- package/dist/web/assets/{elk-QONTBCTQ-B9oq7Tkq.js → elk-QONTBCTQ-KjqoTzPz.js} +1 -1
- package/dist/web/assets/{erDiagram-KYQIGQAA-CmL9SAnh.js → erDiagram-KYQIGQAA-7yWMWLmA.js} +1 -1
- package/dist/web/assets/{eventmodeling-K75KTNOO-R6NmozzN.js → eventmodeling-K75KTNOO-Cc9vp_RM.js} +1 -1
- package/dist/web/assets/flowDiagram-IUGLLWBU-J6BJoxgh.js +1 -0
- package/dist/web/assets/{ganttDiagram-R7GPNTJY-DRa2V_Qe.js → ganttDiagram-R7GPNTJY-BDR6Qg8X.js} +1 -1
- package/dist/web/assets/{gitGraph-VSP46ZUC-CdFMO2LD.js → gitGraph-VSP46ZUC-0OuqK-zj.js} +1 -1
- package/dist/web/assets/{gitGraphDiagram-PDYL7XHY-C-xmUbl1.js → gitGraphDiagram-PDYL7XHY-B7Sr5Eni.js} +1 -1
- package/dist/web/assets/index-B48NiDFl.css +1 -0
- package/dist/web/assets/index-BBc3hXOj.js +133 -0
- package/dist/web/assets/{info-OHQRW6UA-CnPUMAqS.js → info-OHQRW6UA-BUNYCTVi.js} +1 -1
- package/dist/web/assets/{infoDiagram-MVDRKAX5-DxouwrN7.js → infoDiagram-MVDRKAX5-7bXDS2e8.js} +1 -1
- package/dist/web/assets/{ishikawaDiagram-HPEHV2GE-qrLpOq3_.js → ishikawaDiagram-HPEHV2GE-Dwg6CK2F.js} +1 -1
- package/dist/web/assets/{journeyDiagram-BOSHW7O7-BDTfHWHd.js → journeyDiagram-BOSHW7O7-DNoy6E_l.js} +1 -1
- package/dist/web/assets/{kanban-definition-FNSA4HC5-CTBgSpp6.js → kanban-definition-FNSA4HC5-BOAGEtpc.js} +1 -1
- package/dist/web/assets/{line-D8R5RRtF.js → line-D5__Z7-a.js} +1 -1
- package/dist/web/assets/{linear-BCL193tG.js → linear-BwpBL2bi.js} +1 -1
- package/dist/web/assets/{mermaid-parser.core-C1XIxySl.js → mermaid-parser.core-Dh1kQWot.js} +3 -3
- package/dist/web/assets/{mermaid.core-C-385ykR.js → mermaid.core-I_-4X5xX.js} +4 -4
- package/dist/web/assets/{mindmap-definition-6OY57UG3-BnCvQFLY.js → mindmap-definition-6OY57UG3-Czo4xfbC.js} +1 -1
- package/dist/web/assets/{packet-JDAUHWVQ-DVCRx-wc.js → packet-JDAUHWVQ-B1Tk-YPz.js} +1 -1
- package/dist/web/assets/{pegDiagram-ECIUJNBX-CIDVz_ln.js → pegDiagram-ECIUJNBX-opN3Yw-3.js} +1 -1
- package/dist/web/assets/{pie-XZMESJXO-BHXvmR-y.js → pie-XZMESJXO-PTPhpjur.js} +1 -1
- package/dist/web/assets/{pieDiagram-GNMPY74T-Bb_l0cKd.js → pieDiagram-GNMPY74T-zO1NGdF7.js} +1 -1
- package/dist/web/assets/{quadrantDiagram-D57K4MC3-Dqq4AGQt.js → quadrantDiagram-D57K4MC3-eoWl0lte.js} +1 -1
- package/dist/web/assets/{radar-ABXABTNO-Ba5vnnQ7.js → radar-ABXABTNO-CL9_kyLl.js} +1 -1
- package/dist/web/assets/{railroad-I3PHUGI6-CxoMtJ5h.js → railroad-I3PHUGI6-DAToCd8H.js} +1 -1
- package/dist/web/assets/{railroad-abnf-LNEFI6M7-BXxErwiU.js → railroad-abnf-LNEFI6M7-j9pG6Gat.js} +1 -1
- package/dist/web/assets/{railroad-ebnf-DWYD2UWJ-C_9H5arK.js → railroad-ebnf-DWYD2UWJ-CiM5sQUg.js} +1 -1
- package/dist/web/assets/{railroad-peg-JR7BVNR7-50KHJESB.js → railroad-peg-JR7BVNR7-C7APIBTP.js} +1 -1
- package/dist/web/assets/{railroadDiagram-Y72NRBL7-9w1amWMc.js → railroadDiagram-Y72NRBL7-DXA0-8Dt.js} +1 -1
- package/dist/web/assets/{requirementDiagram-EQYSW5RA-D3XygoSz.js → requirementDiagram-EQYSW5RA-D1PbJ9Cu.js} +1 -1
- package/dist/web/assets/{sankeyDiagram-SY24JHO5-C68crPY9.js → sankeyDiagram-SY24JHO5-CSfvmNAq.js} +1 -1
- package/dist/web/assets/{sequenceDiagram-BLEHNHQU-BNcJ1wfc.js → sequenceDiagram-BLEHNHQU-B1lprETQ.js} +1 -1
- package/dist/web/assets/{src-okGi814h.js → src-D76sYeGJ.js} +1 -1
- package/dist/web/assets/{stateDiagram-v2-A6IESKWZ-DX7rAO1j.js → stateDiagram-v2-A6IESKWZ-BEGC0Sgn.js} +1 -1
- package/dist/web/assets/{swimlanes-B3ENRKFQ-DGSmz_ab.js → swimlanes-B3ENRKFQ-D_JFS6ED.js} +1 -1
- package/dist/web/assets/swimlanesDiagram-AYQRV4AK-C-TLQ1Gu.js +8 -0
- package/dist/web/assets/{timeline-definition-JXYKGLGB-5COU2ouX.js → timeline-definition-JXYKGLGB-Bfk78u4E.js} +1 -1
- package/dist/web/assets/{treeView-D4JQ5SDB-BgrtWP9w.js → treeView-D4JQ5SDB-B_3xFlyk.js} +1 -1
- package/dist/web/assets/{treemap-SAJKECNS-CLZcktWl.js → treemap-SAJKECNS-BZYrffaG.js} +1 -1
- package/dist/web/assets/{usecaseDiagram-WPOLBNNX-BbJ7QjYR.js → usecaseDiagram-WPOLBNNX-CXEH2da9.js} +1 -1
- package/dist/web/assets/{vennDiagram-Q3Y3IDCW-IhZTghFG.js → vennDiagram-Q3Y3IDCW-J67gmeH3.js} +1 -1
- package/dist/web/assets/{wardley-7MLQ67FV-XjDz9vxn.js → wardley-7MLQ67FV-DagzfYQE.js} +1 -1
- package/dist/web/assets/{wardleyDiagram-IVAIDKWA-DTcLR0T-.js → wardleyDiagram-IVAIDKWA-CtlWSFS0.js} +1 -1
- package/dist/web/assets/{xychartDiagram-4URNHDU4-Dja-ugvw.js → xychartDiagram-4URNHDU4-C-iRO0Sb.js} +1 -1
- package/dist/web/index.html +2 -2
- package/package.json +1 -1
- package/dist/web/assets/channel-ggr2Mduz.js +0 -1
- package/dist/web/assets/flowDiagram-IUGLLWBU-CkUCRx3C.js +0 -1
- package/dist/web/assets/index-BFpTDsCp.js +0 -132
- package/dist/web/assets/index-CQGURl2V.css +0 -1
- package/dist/web/assets/swimlanesDiagram-AYQRV4AK-D8bRrq1P.js +0 -8
package/dist/cli.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
// src/cli/index.ts
|
|
4
|
-
import
|
|
4
|
+
import fs23 from "fs";
|
|
5
5
|
import path22 from "path";
|
|
6
6
|
|
|
7
7
|
// src/core/changes.ts
|
|
@@ -1834,9 +1834,45 @@ function keepLanguage(root2, rel) {
|
|
|
1834
1834
|
|
|
1835
1835
|
// src/core/server.ts
|
|
1836
1836
|
import { spawn } from "child_process";
|
|
1837
|
+
import fs18 from "fs";
|
|
1838
|
+
import path18 from "path";
|
|
1839
|
+
|
|
1840
|
+
// src/core/update.ts
|
|
1841
|
+
import { spawnSync as spawnSync2 } from "child_process";
|
|
1837
1842
|
import fs17 from "fs";
|
|
1838
1843
|
import path17 from "path";
|
|
1839
|
-
var
|
|
1844
|
+
var PKG = JSON.parse(fs17.readFileSync(path17.join(PKG_ROOT, "package.json"), "utf8"));
|
|
1845
|
+
var CURRENT_VERSION = PKG.version;
|
|
1846
|
+
function installer() {
|
|
1847
|
+
const dir = PKG_ROOT.split(path17.sep).join("/");
|
|
1848
|
+
if (dir.includes("/_npx/")) return "npx";
|
|
1849
|
+
if (!dir.includes("/node_modules/")) return null;
|
|
1850
|
+
return dir.includes("/pnpm/") || dir.includes("/.pnpm/") ? "pnpm" : "npm";
|
|
1851
|
+
}
|
|
1852
|
+
async function latestVersion() {
|
|
1853
|
+
const res = await fetch(`https://registry.npmjs.org/${PKG.name}`, {
|
|
1854
|
+
headers: { accept: "application/vnd.npm.install-v1+json", "cache-control": "no-cache" },
|
|
1855
|
+
signal: AbortSignal.timeout(15e3)
|
|
1856
|
+
});
|
|
1857
|
+
if (!res.ok) throw new Error(`The npm registry answered ${res.status}`);
|
|
1858
|
+
return (await res.json())["dist-tags"].latest;
|
|
1859
|
+
}
|
|
1860
|
+
function isNewer(a, b) {
|
|
1861
|
+
const pa = a.split(".").map((n) => parseInt(n, 10));
|
|
1862
|
+
const pb = b.split(".").map((n) => parseInt(n, 10));
|
|
1863
|
+
for (let i = 0; i < 3; i++) if ((pa[i] ?? 0) !== (pb[i] ?? 0)) return (pa[i] ?? 0) > (pb[i] ?? 0);
|
|
1864
|
+
return false;
|
|
1865
|
+
}
|
|
1866
|
+
function installCommand2(via, version) {
|
|
1867
|
+
const spec = `${PKG.name}@${version}`;
|
|
1868
|
+
return via === "pnpm" ? ["pnpm", "add", "-g", spec, "--config.minimum-release-age=0"] : ["npm", "install", "-g", spec, "--min-release-age=0", "--prefer-online"];
|
|
1869
|
+
}
|
|
1870
|
+
function runInstall(cmd) {
|
|
1871
|
+
return spawnSync2(cmd[0], cmd.slice(1), { stdio: "inherit", shell: process.platform === "win32" }).status === 0;
|
|
1872
|
+
}
|
|
1873
|
+
|
|
1874
|
+
// src/core/server.ts
|
|
1875
|
+
var serverFile = (root2) => path18.join(stateDir(root2), "server.json");
|
|
1840
1876
|
var isAlive = (pid) => {
|
|
1841
1877
|
try {
|
|
1842
1878
|
process.kill(pid, 0);
|
|
@@ -1847,18 +1883,18 @@ var isAlive = (pid) => {
|
|
|
1847
1883
|
};
|
|
1848
1884
|
function recordServer(root2, port) {
|
|
1849
1885
|
const file = serverFile(root2);
|
|
1850
|
-
|
|
1886
|
+
fs18.mkdirSync(path18.dirname(file), { recursive: true });
|
|
1851
1887
|
assertInside(file);
|
|
1852
|
-
|
|
1888
|
+
fs18.writeFileSync(file, JSON.stringify({ port, pid: process.pid, version: CURRENT_VERSION }));
|
|
1853
1889
|
process.once("exit", () => {
|
|
1854
|
-
if (runningServer(root2)?.pid === process.pid)
|
|
1890
|
+
if (runningServer(root2)?.pid === process.pid) fs18.rmSync(file, { force: true });
|
|
1855
1891
|
});
|
|
1856
1892
|
for (const sig of ["SIGINT", "SIGTERM", "SIGHUP"]) process.once(sig, () => process.exit(130));
|
|
1857
1893
|
}
|
|
1858
1894
|
function runningServer(root2) {
|
|
1859
1895
|
try {
|
|
1860
|
-
const s = JSON.parse(
|
|
1861
|
-
return Number.isInteger(s.port) && Number.isInteger(s.pid) && isAlive(s.pid) ? { port: s.port, pid: s.pid } : null;
|
|
1896
|
+
const s = JSON.parse(fs18.readFileSync(serverFile(root2), "utf8"));
|
|
1897
|
+
return Number.isInteger(s.port) && Number.isInteger(s.pid) && isAlive(s.pid) ? { port: s.port, pid: s.pid, version: s.version } : null;
|
|
1862
1898
|
} catch {
|
|
1863
1899
|
return null;
|
|
1864
1900
|
}
|
|
@@ -1872,7 +1908,11 @@ async function responds(port) {
|
|
|
1872
1908
|
}
|
|
1873
1909
|
async function ensureServer(root2, cli2, port) {
|
|
1874
1910
|
const running = runningServer(root2);
|
|
1875
|
-
if (running &&
|
|
1911
|
+
if (running && running.version !== CURRENT_VERSION) {
|
|
1912
|
+
process.kill(running.pid);
|
|
1913
|
+
for (let i = 0; i < 50 && isAlive(running.pid); i++) await new Promise((r) => setTimeout(r, 100));
|
|
1914
|
+
port = running.port;
|
|
1915
|
+
} else if (running && await responds(running.port)) return running;
|
|
1876
1916
|
const child = spawn(process.execPath, [...process.execArgv, cli2, "serve", "--no-open", "--port", String(port)], {
|
|
1877
1917
|
cwd: root2,
|
|
1878
1918
|
env: { ...process.env, MARKODE_ROOT: root2 },
|
|
@@ -1889,37 +1929,6 @@ async function ensureServer(root2, cli2, port) {
|
|
|
1889
1929
|
}
|
|
1890
1930
|
var editorUrl = (port, doc) => `http://localhost:${port}/${doc ? `open?path=${encodeURIComponent(doc).replace(/%2F/g, "/")}` : ""}`;
|
|
1891
1931
|
|
|
1892
|
-
// src/core/update.ts
|
|
1893
|
-
import { spawnSync as spawnSync2 } from "child_process";
|
|
1894
|
-
import fs18 from "fs";
|
|
1895
|
-
import path18 from "path";
|
|
1896
|
-
var PKG = JSON.parse(fs18.readFileSync(path18.join(PKG_ROOT, "package.json"), "utf8"));
|
|
1897
|
-
var CURRENT_VERSION = PKG.version;
|
|
1898
|
-
function installer() {
|
|
1899
|
-
const dir = PKG_ROOT.split(path18.sep).join("/");
|
|
1900
|
-
if (dir.includes("/_npx/")) return "npx";
|
|
1901
|
-
if (!dir.includes("/node_modules/")) return null;
|
|
1902
|
-
return dir.includes("/pnpm/") || dir.includes("/.pnpm/") ? "pnpm" : "npm";
|
|
1903
|
-
}
|
|
1904
|
-
async function latestVersion() {
|
|
1905
|
-
const res = await fetch(`https://registry.npmjs.org/${PKG.name}/latest`, { headers: { accept: "application/json" }, signal: AbortSignal.timeout(15e3) });
|
|
1906
|
-
if (!res.ok) throw new Error(`The npm registry answered ${res.status}`);
|
|
1907
|
-
return (await res.json()).version;
|
|
1908
|
-
}
|
|
1909
|
-
function isNewer(a, b) {
|
|
1910
|
-
const pa = a.split(".").map((n) => parseInt(n, 10));
|
|
1911
|
-
const pb = b.split(".").map((n) => parseInt(n, 10));
|
|
1912
|
-
for (let i = 0; i < 3; i++) if ((pa[i] ?? 0) !== (pb[i] ?? 0)) return (pa[i] ?? 0) > (pb[i] ?? 0);
|
|
1913
|
-
return false;
|
|
1914
|
-
}
|
|
1915
|
-
function installCommand2(via, version) {
|
|
1916
|
-
const spec = `${PKG.name}@${version}`;
|
|
1917
|
-
return via === "pnpm" ? ["pnpm", "add", "-g", spec, "--config.minimum-release-age=0"] : ["npm", "install", "-g", spec, "--min-release-age=0", "--prefer-online"];
|
|
1918
|
-
}
|
|
1919
|
-
function runInstall(cmd) {
|
|
1920
|
-
return spawnSync2(cmd[0], cmd.slice(1), { stdio: "inherit", shell: process.platform === "win32" }).status === 0;
|
|
1921
|
-
}
|
|
1922
|
-
|
|
1923
1932
|
// src/core/wait.ts
|
|
1924
1933
|
import fs19 from "fs";
|
|
1925
1934
|
import path19 from "path";
|
|
@@ -2053,13 +2062,206 @@ function answerSummary(root2, rel) {
|
|
|
2053
2062
|
|
|
2054
2063
|
// src/server/index.ts
|
|
2055
2064
|
import crypto3 from "crypto";
|
|
2056
|
-
import
|
|
2065
|
+
import fs21 from "fs";
|
|
2057
2066
|
import http from "http";
|
|
2058
2067
|
import path20 from "path";
|
|
2059
2068
|
import { watch } from "chokidar";
|
|
2060
2069
|
import open from "open";
|
|
2061
2070
|
import pc from "picocolors";
|
|
2062
2071
|
import { WebSocketServer } from "ws";
|
|
2072
|
+
|
|
2073
|
+
// src/core/search.ts
|
|
2074
|
+
import fs20 from "fs";
|
|
2075
|
+
import ignore2 from "ignore";
|
|
2076
|
+
var MAX_MATCHES = 2e3;
|
|
2077
|
+
var PREVIEW_BEFORE = 40;
|
|
2078
|
+
var PREVIEW_MAX = 200;
|
|
2079
|
+
var QueryError = class extends Error {
|
|
2080
|
+
};
|
|
2081
|
+
function buildRegex(o) {
|
|
2082
|
+
if (!o.query) return null;
|
|
2083
|
+
const source = o.regex ? o.query : o.query.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
2084
|
+
const flags = "g" + (o.caseSensitive ? "" : "i");
|
|
2085
|
+
try {
|
|
2086
|
+
if (o.wholeWord) {
|
|
2087
|
+
try {
|
|
2088
|
+
return new RegExp(`(?<![\\p{L}\\p{N}_])(?:${source})(?![\\p{L}\\p{N}_])`, flags + "u");
|
|
2089
|
+
} catch {
|
|
2090
|
+
return new RegExp(`\\b(?:${source})\\b`, flags);
|
|
2091
|
+
}
|
|
2092
|
+
}
|
|
2093
|
+
return new RegExp(source, flags);
|
|
2094
|
+
} catch (err) {
|
|
2095
|
+
throw new QueryError(err.message);
|
|
2096
|
+
}
|
|
2097
|
+
}
|
|
2098
|
+
function pathFilter(include, exclude) {
|
|
2099
|
+
const globs = (s) => s.split(",").map((g) => g.trim().replace(/^\.?\/+/, "")).filter(Boolean);
|
|
2100
|
+
const inc = globs(include);
|
|
2101
|
+
const exc = globs(exclude);
|
|
2102
|
+
const incIg = ignore2().add(inc);
|
|
2103
|
+
const excIg = ignore2().add(exc);
|
|
2104
|
+
return (rel) => (!inc.length || incIg.ignores(rel)) && (!exc.length || !excIg.ignores(rel));
|
|
2105
|
+
}
|
|
2106
|
+
function renderLine(line, index, state) {
|
|
2107
|
+
const drop = new Uint8Array(line.length);
|
|
2108
|
+
const dropRange = (from, to) => drop.fill(1, from, to);
|
|
2109
|
+
const result = () => {
|
|
2110
|
+
const cols = [];
|
|
2111
|
+
let plain = "";
|
|
2112
|
+
for (let i2 = 0; i2 < line.length; i2++)
|
|
2113
|
+
if (!drop[i2]) {
|
|
2114
|
+
plain += line[i2];
|
|
2115
|
+
cols.push(i2);
|
|
2116
|
+
}
|
|
2117
|
+
return { plain, cols };
|
|
2118
|
+
};
|
|
2119
|
+
if (index === 0 && line === "---") {
|
|
2120
|
+
state.frontmatter = true;
|
|
2121
|
+
dropRange(0, line.length);
|
|
2122
|
+
return result();
|
|
2123
|
+
}
|
|
2124
|
+
if (state.frontmatter) {
|
|
2125
|
+
if (line === "---" || line === "...") {
|
|
2126
|
+
state.frontmatter = false;
|
|
2127
|
+
dropRange(0, line.length);
|
|
2128
|
+
}
|
|
2129
|
+
return result();
|
|
2130
|
+
}
|
|
2131
|
+
if (/^\s*(```|~~~)/.test(line)) {
|
|
2132
|
+
state.fence = !state.fence;
|
|
2133
|
+
dropRange(0, line.length);
|
|
2134
|
+
return result();
|
|
2135
|
+
}
|
|
2136
|
+
if (state.fence) return result();
|
|
2137
|
+
let i = 0;
|
|
2138
|
+
while (i < line.length) {
|
|
2139
|
+
if (state.comment) {
|
|
2140
|
+
const end = line.indexOf("-->", i);
|
|
2141
|
+
dropRange(i, end < 0 ? line.length : end + 3);
|
|
2142
|
+
if (end < 0) return result();
|
|
2143
|
+
state.comment = false;
|
|
2144
|
+
i = end + 3;
|
|
2145
|
+
} else {
|
|
2146
|
+
const start = line.indexOf("<!--", i);
|
|
2147
|
+
if (start < 0) break;
|
|
2148
|
+
state.comment = true;
|
|
2149
|
+
dropRange(start, start + 4);
|
|
2150
|
+
i = start + 4;
|
|
2151
|
+
}
|
|
2152
|
+
}
|
|
2153
|
+
const all = (re, each) => {
|
|
2154
|
+
for (const m of line.matchAll(re)) each(m);
|
|
2155
|
+
};
|
|
2156
|
+
if (/^\s*\|?\s*:?-{3,}:?\s*(\|\s*:?-{3,}:?\s*)*\|?\s*$/.test(line) && line.includes("|")) {
|
|
2157
|
+
dropRange(0, line.length);
|
|
2158
|
+
return result();
|
|
2159
|
+
}
|
|
2160
|
+
const block = /^\s*(?:>\s?)*(?:#{1,6}\s+|(?:[-*+]|\d+[.)])\s+(?:\[[ xX]\]\s+)?)?/.exec(line);
|
|
2161
|
+
if (block) dropRange(0, block[0].length);
|
|
2162
|
+
all(/!?\[([^\]\n]*)\]\(([^)\n]*)\)/g, (m) => {
|
|
2163
|
+
const textStart = m.index + m[0].indexOf("[") + 1;
|
|
2164
|
+
dropRange(m.index, textStart);
|
|
2165
|
+
dropRange(textStart + m[1].length, m.index + m[0].length);
|
|
2166
|
+
});
|
|
2167
|
+
all(/<\/?[a-zA-Z][^<>\n]*>/g, (m) => {
|
|
2168
|
+
if (/^<[a-z][\w+.-]*:/i.test(m[0])) dropRange(m.index, m.index + 1), dropRange(m.index + m[0].length - 1, m.index + m[0].length);
|
|
2169
|
+
else dropRange(m.index, m.index + m[0].length);
|
|
2170
|
+
});
|
|
2171
|
+
all(/\\([\\`*_{}[\]()#+\-.!|~<>])|\*+|~~|`+|__+|(?<!\\)\|/g, (m) => {
|
|
2172
|
+
if (m[1]) dropRange(m.index, m.index + 1);
|
|
2173
|
+
else dropRange(m.index, m.index + m[0].length);
|
|
2174
|
+
});
|
|
2175
|
+
return result();
|
|
2176
|
+
}
|
|
2177
|
+
function eachMatch(text3, o, re, each) {
|
|
2178
|
+
const lines = text3.split("\n");
|
|
2179
|
+
const state = { fence: false, comment: false, frontmatter: false };
|
|
2180
|
+
for (let n = 0; n < lines.length; n++) {
|
|
2181
|
+
const line = lines[n].endsWith("\r") ? lines[n].slice(0, -1) : lines[n];
|
|
2182
|
+
const { plain, cols } = o.rendered ? renderLine(line, n, state) : { plain: line, cols: null };
|
|
2183
|
+
re.lastIndex = 0;
|
|
2184
|
+
for (let m = re.exec(plain); m; m = re.exec(plain)) {
|
|
2185
|
+
if (!m[0].length) {
|
|
2186
|
+
re.lastIndex++;
|
|
2187
|
+
continue;
|
|
2188
|
+
}
|
|
2189
|
+
const start = m.index;
|
|
2190
|
+
const end = start + m[0].length;
|
|
2191
|
+
const from = cols ? cols[start] : start;
|
|
2192
|
+
const to = cols ? cols[end - 1] + 1 : end;
|
|
2193
|
+
if (each(m, n, plain, start, end, from, to) === false) return;
|
|
2194
|
+
}
|
|
2195
|
+
}
|
|
2196
|
+
}
|
|
2197
|
+
function preview(view, start, end) {
|
|
2198
|
+
const lead = view.length - view.trimStart().length;
|
|
2199
|
+
let from = Math.max(lead, start - PREVIEW_BEFORE);
|
|
2200
|
+
const space = from > lead ? view.indexOf(" ", from) : -1;
|
|
2201
|
+
if (space >= 0 && space < start) from = space + 1;
|
|
2202
|
+
const prefix = from > lead ? "\u2026" : "";
|
|
2203
|
+
const text3 = prefix + view.slice(from, from + PREVIEW_MAX);
|
|
2204
|
+
return { preview: text3.trimEnd(), start: start - from + prefix.length, end: Math.min(end - from, PREVIEW_MAX) + prefix.length };
|
|
2205
|
+
}
|
|
2206
|
+
function searchText(text3, o, re, limit = MAX_MATCHES) {
|
|
2207
|
+
const out = [];
|
|
2208
|
+
eachMatch(text3, o, re, (m, line, view, start, end, from, to) => {
|
|
2209
|
+
out.push({ line: line + 1, col: from, len: to - from, ...preview(view, start, end), replaceable: to - from === end - start });
|
|
2210
|
+
return out.length < limit;
|
|
2211
|
+
});
|
|
2212
|
+
return out;
|
|
2213
|
+
}
|
|
2214
|
+
function searchFiles(files, o) {
|
|
2215
|
+
const re = buildRegex(o);
|
|
2216
|
+
if (!re) return { files: [], total: 0, truncated: false };
|
|
2217
|
+
const passes = pathFilter(o.include, o.exclude);
|
|
2218
|
+
const out = [];
|
|
2219
|
+
let total = 0;
|
|
2220
|
+
for (const f of files) {
|
|
2221
|
+
if (!passes(f.path)) continue;
|
|
2222
|
+
let text3;
|
|
2223
|
+
try {
|
|
2224
|
+
text3 = fs20.readFileSync(f.file, "utf8");
|
|
2225
|
+
} catch {
|
|
2226
|
+
continue;
|
|
2227
|
+
}
|
|
2228
|
+
const matches = searchText(text3, o, re, MAX_MATCHES - total + 1);
|
|
2229
|
+
if (!matches.length) continue;
|
|
2230
|
+
total += matches.length;
|
|
2231
|
+
if (total > MAX_MATCHES) {
|
|
2232
|
+
out.push({ path: f.path, matches: matches.slice(0, matches.length - (total - MAX_MATCHES)) });
|
|
2233
|
+
return { files: out, total: MAX_MATCHES, truncated: true };
|
|
2234
|
+
}
|
|
2235
|
+
out.push({ path: f.path, matches });
|
|
2236
|
+
}
|
|
2237
|
+
return { files: out, total, truncated: false };
|
|
2238
|
+
}
|
|
2239
|
+
function expand(m, replacement) {
|
|
2240
|
+
return replacement.replace(/\$(\$|&|\d{1,2}|<([^>]+)>)/g, (token, ref, name) => {
|
|
2241
|
+
if (ref === "$") return "$";
|
|
2242
|
+
if (ref === "&") return m[0];
|
|
2243
|
+
if (name !== void 0) return m.groups?.[name] ?? "";
|
|
2244
|
+
const n = Number(ref);
|
|
2245
|
+
return n > 0 && n < m.length ? m[n] ?? "" : token;
|
|
2246
|
+
});
|
|
2247
|
+
}
|
|
2248
|
+
function replaceText(text3, o, replacement, only) {
|
|
2249
|
+
const re = buildRegex(o);
|
|
2250
|
+
if (!re) return { text: text3, count: 0 };
|
|
2251
|
+
const lineStarts = [0];
|
|
2252
|
+
for (let i = 0; i < text3.length; i++) if (text3[i] === "\n") lineStarts.push(i + 1);
|
|
2253
|
+
const edits = [];
|
|
2254
|
+
eachMatch(text3, o, re, (m, line, _view, start, end, from, to) => {
|
|
2255
|
+
if (to - from !== end - start) return;
|
|
2256
|
+
if (only && !only.has(`${line + 1}:${from}`)) return;
|
|
2257
|
+
edits.push({ from: lineStarts[line] + from, to: lineStarts[line] + to, insert: o.regex ? expand(m, replacement) : replacement });
|
|
2258
|
+
});
|
|
2259
|
+
let out = text3;
|
|
2260
|
+
for (const e of edits.reverse()) out = out.slice(0, e.from) + e.insert + out.slice(e.to);
|
|
2261
|
+
return { text: out, count: edits.length };
|
|
2262
|
+
}
|
|
2263
|
+
|
|
2264
|
+
// src/server/index.ts
|
|
2063
2265
|
var IMAGE_MIME = {
|
|
2064
2266
|
".png": "image/png",
|
|
2065
2267
|
".jpg": "image/jpeg",
|
|
@@ -2123,7 +2325,7 @@ async function startServer({ root: root2, port, open: openBrowser }) {
|
|
|
2123
2325
|
if (typeof rel !== "string" || !rel.trim()) throw new HttpError(400, "Expected a path");
|
|
2124
2326
|
const abs = safeResolve(root2, rel);
|
|
2125
2327
|
if (abs === root2) throw new HttpError(400, "Refusing to delete the project root");
|
|
2126
|
-
if (!
|
|
2328
|
+
if (!fs21.existsSync(abs)) throw new HttpError(404, "Not found");
|
|
2127
2329
|
return abs;
|
|
2128
2330
|
};
|
|
2129
2331
|
const translationFile = (lang, rel) => {
|
|
@@ -2131,6 +2333,33 @@ async function startServer({ root: root2, port, open: openBrowser }) {
|
|
|
2131
2333
|
assertInside(file, root2);
|
|
2132
2334
|
return file;
|
|
2133
2335
|
};
|
|
2336
|
+
const searchOptions = (o) => {
|
|
2337
|
+
const flag2 = (v) => v === true || v === "1" || v === "true";
|
|
2338
|
+
return {
|
|
2339
|
+
query: typeof o.q === "string" ? o.q : "",
|
|
2340
|
+
caseSensitive: flag2(o.case),
|
|
2341
|
+
wholeWord: flag2(o.word),
|
|
2342
|
+
regex: flag2(o.regex),
|
|
2343
|
+
rendered: flag2(o.rendered),
|
|
2344
|
+
include: typeof o.include === "string" ? o.include : "",
|
|
2345
|
+
exclude: typeof o.exclude === "string" ? o.exclude : ""
|
|
2346
|
+
};
|
|
2347
|
+
};
|
|
2348
|
+
const searchable = (o) => {
|
|
2349
|
+
const l = viewLang(o.lang);
|
|
2350
|
+
return flattenFiles(scanTree(root2), o.ignored === true || o.ignored === "1").map((n) => {
|
|
2351
|
+
const tPath = l ? translationFile(l, n.path) : null;
|
|
2352
|
+
return { path: n.path, file: tPath && fs21.existsSync(tPath) ? tPath : safeResolve(root2, n.path), translation: !!tPath && fs21.existsSync(tPath) };
|
|
2353
|
+
});
|
|
2354
|
+
};
|
|
2355
|
+
const search = (o) => {
|
|
2356
|
+
try {
|
|
2357
|
+
return searchFiles(searchable(o), searchOptions(o));
|
|
2358
|
+
} catch (err) {
|
|
2359
|
+
if (err instanceof QueryError) throw new HttpError(400, err.message);
|
|
2360
|
+
throw err;
|
|
2361
|
+
}
|
|
2362
|
+
};
|
|
2134
2363
|
const routes = {
|
|
2135
2364
|
"GET /api/info": () => {
|
|
2136
2365
|
const c = config();
|
|
@@ -2189,14 +2418,44 @@ async function startServer({ root: root2, port, open: openBrowser }) {
|
|
|
2189
2418
|
const foreign = featureState(root2).translations ? Object.fromEntries(foreignFiles(root2, sourceLang()).map((f) => [f.path, f.detected])) : {};
|
|
2190
2419
|
return { tree: scanTree(root2), git: gitStatuses(root2), sync: sync2, foreign };
|
|
2191
2420
|
},
|
|
2421
|
+
"GET /api/search": (url3) => search(Object.fromEntries(url3.searchParams)),
|
|
2422
|
+
/**
|
|
2423
|
+
* Replace the matches of a search: in every file, in one (`path`), or only some of its matches
|
|
2424
|
+
* (`only`: `line:col` keys). Only the matched text changes in each file.
|
|
2425
|
+
*/
|
|
2426
|
+
"POST /api/replace": (_, body) => {
|
|
2427
|
+
const o = searchOptions(body);
|
|
2428
|
+
if (!o.query) throw new HttpError(400, "Expected a query");
|
|
2429
|
+
const replacement = String(body.replacement ?? "");
|
|
2430
|
+
const only = Array.isArray(body.only) ? new Set(body.only.map(String)) : void 0;
|
|
2431
|
+
try {
|
|
2432
|
+
buildRegex(o);
|
|
2433
|
+
} catch (err) {
|
|
2434
|
+
throw new HttpError(400, err.message);
|
|
2435
|
+
}
|
|
2436
|
+
const passes = pathFilter(o.include, o.exclude);
|
|
2437
|
+
const files = searchable(body).filter((f) => passes(f.path) && (typeof body.path !== "string" || f.path === body.path));
|
|
2438
|
+
let replaced = 0;
|
|
2439
|
+
const changed = [];
|
|
2440
|
+
for (const f of files) {
|
|
2441
|
+
const before = fs21.readFileSync(f.file, "utf8");
|
|
2442
|
+
const { text: text3, count } = replaceText(before, o, replacement, only);
|
|
2443
|
+
if (!count || text3 === before) continue;
|
|
2444
|
+
if (!f.translation && featureState(root2).agent) logSave(root2, f.path, before, text3);
|
|
2445
|
+
fs21.writeFileSync(f.file, text3);
|
|
2446
|
+
replaced += count;
|
|
2447
|
+
changed.push(f.path);
|
|
2448
|
+
}
|
|
2449
|
+
return { replaced, files: changed };
|
|
2450
|
+
},
|
|
2192
2451
|
"POST /api/keep-language": (_, body) => ({ lang: keepLanguage(root2, mdPath(body.path)) }),
|
|
2193
2452
|
"GET /api/file": (url3) => {
|
|
2194
2453
|
const rel = mdPath(url3.searchParams.get("path"));
|
|
2195
2454
|
const l = viewLang(url3.searchParams.get("lang"));
|
|
2196
|
-
const source =
|
|
2455
|
+
const source = fs21.readFileSync(safeResolve(root2, rel), "utf8");
|
|
2197
2456
|
if (l) {
|
|
2198
2457
|
const tPath = translationFile(l, rel);
|
|
2199
|
-
if (
|
|
2458
|
+
if (fs21.existsSync(tPath)) return { path: rel, content: fs21.readFileSync(tPath, "utf8"), target: "translation", status: fileStatus(root2, l, rel) };
|
|
2200
2459
|
return { path: rel, content: source, target: "source", status: "missing" };
|
|
2201
2460
|
}
|
|
2202
2461
|
return { path: rel, content: source, target: "source", status: null };
|
|
@@ -2205,19 +2464,19 @@ async function startServer({ root: root2, port, open: openBrowser }) {
|
|
|
2205
2464
|
const rel = mdPath(body.path);
|
|
2206
2465
|
const l = viewLang(body.lang);
|
|
2207
2466
|
const file = body.target === "translation" && l ? translationFile(l, rel) : safeResolve(root2, rel);
|
|
2208
|
-
|
|
2467
|
+
fs21.mkdirSync(path20.dirname(file), { recursive: true });
|
|
2209
2468
|
const content = String(body.content ?? "");
|
|
2210
|
-
if (!l && featureState(root2).agent) logSave(root2, rel,
|
|
2211
|
-
|
|
2469
|
+
if (!l && featureState(root2).agent) logSave(root2, rel, fs21.existsSync(file) ? fs21.readFileSync(file, "utf8") : "", content);
|
|
2470
|
+
fs21.writeFileSync(file, content);
|
|
2212
2471
|
return { ok: true, status: l ? fileStatus(root2, l, rel) : null };
|
|
2213
2472
|
},
|
|
2214
2473
|
"POST /api/file": (_, body) => {
|
|
2215
2474
|
const rel = mdPath(body.path);
|
|
2216
2475
|
const file = safeResolve(root2, rel);
|
|
2217
|
-
if (
|
|
2218
|
-
|
|
2476
|
+
if (fs21.existsSync(file)) throw new HttpError(409, "File already exists");
|
|
2477
|
+
fs21.mkdirSync(path20.dirname(file), { recursive: true });
|
|
2219
2478
|
const title = path20.basename(rel, ".md").replace(/^\d+[-_]/, "").replace(/[-_]/g, " ");
|
|
2220
|
-
|
|
2479
|
+
fs21.writeFileSync(file, `# ${title.charAt(0).toUpperCase() + title.slice(1)}
|
|
2221
2480
|
|
|
2222
2481
|
`);
|
|
2223
2482
|
return { ok: true, path: rel };
|
|
@@ -2227,20 +2486,20 @@ async function startServer({ root: root2, port, open: openBrowser }) {
|
|
|
2227
2486
|
if (typeof body.path !== "string" || !body.path.trim()) throw new HttpError(400, "Expected a path");
|
|
2228
2487
|
const dir = safeResolve(root2, body.path);
|
|
2229
2488
|
if (dir === root2) throw new HttpError(400, "Expected a path");
|
|
2230
|
-
if (
|
|
2231
|
-
|
|
2489
|
+
if (fs21.existsSync(dir)) throw new HttpError(409, "A file or folder with that name already exists");
|
|
2490
|
+
fs21.mkdirSync(dir, { recursive: true });
|
|
2232
2491
|
return { ok: true, path: toPosix(path20.relative(root2, dir)) };
|
|
2233
2492
|
},
|
|
2234
2493
|
"GET /api/delete-preview": (url3) => {
|
|
2235
2494
|
const abs = deletable(url3.searchParams.get("path"));
|
|
2236
|
-
if (!
|
|
2237
|
-
const files =
|
|
2495
|
+
if (!fs21.statSync(abs).isDirectory()) return { kind: "file", files: 1, md: 1 };
|
|
2496
|
+
const files = fs21.readdirSync(abs, { recursive: true, withFileTypes: true }).filter((e) => e.isFile());
|
|
2238
2497
|
return { kind: "dir", files: files.length, md: files.filter((e) => e.name.toLowerCase().endsWith(".md")).length };
|
|
2239
2498
|
},
|
|
2240
2499
|
"DELETE /api/path": (url3) => {
|
|
2241
2500
|
const rel = toPosix(path20.relative(root2, deletable(url3.searchParams.get("path"))));
|
|
2242
|
-
|
|
2243
|
-
for (const l of config().langs)
|
|
2501
|
+
fs21.rmSync(safeResolve(root2, rel), { recursive: true });
|
|
2502
|
+
for (const l of config().langs) fs21.rmSync(translationFile(l, rel), { recursive: true, force: true });
|
|
2244
2503
|
return { ok: true };
|
|
2245
2504
|
},
|
|
2246
2505
|
"POST /api/ignore": (_, body) => {
|
|
@@ -2257,7 +2516,7 @@ async function startServer({ root: root2, port, open: openBrowser }) {
|
|
|
2257
2516
|
},
|
|
2258
2517
|
"GET /api/rules": () => {
|
|
2259
2518
|
const mainDoc = readConfig(root2)?.mainDoc;
|
|
2260
|
-
const text3 = mainDoc &&
|
|
2519
|
+
const text3 = mainDoc && fs21.existsSync(path20.join(root2, mainDoc)) ? fs21.readFileSync(path20.join(root2, mainDoc), "utf8") : "";
|
|
2261
2520
|
return { rules: listRules(), applied: appliedRuleIds(text3), mainDoc: mainDoc ?? null };
|
|
2262
2521
|
},
|
|
2263
2522
|
"PUT /api/rules": (_, body) => saveRule(body),
|
|
@@ -2273,12 +2532,12 @@ async function startServer({ root: root2, port, open: openBrowser }) {
|
|
|
2273
2532
|
},
|
|
2274
2533
|
"GET /api/skills/file": (url3) => {
|
|
2275
2534
|
const skill = getSkill(root2, url3.searchParams.get("key"));
|
|
2276
|
-
return { path: skill.key, content:
|
|
2535
|
+
return { path: skill.key, content: fs21.readFileSync(path20.join(skill.key, "SKILL.md"), "utf8"), target: "source", status: null };
|
|
2277
2536
|
},
|
|
2278
2537
|
"PUT /api/skills/file": (_, body) => {
|
|
2279
2538
|
const skill = getSkill(root2, body.key);
|
|
2280
2539
|
if (skill.managed) throw new HttpError(403, "This skill is managed by the app that installed it");
|
|
2281
|
-
|
|
2540
|
+
fs21.writeFileSync(path20.join(skill.key, "SKILL.md"), String(body.content ?? ""));
|
|
2282
2541
|
return { ok: true, status: null };
|
|
2283
2542
|
},
|
|
2284
2543
|
"POST /api/skills/install": (_, body) => {
|
|
@@ -2327,12 +2586,12 @@ async function startServer({ root: root2, port, open: openBrowser }) {
|
|
|
2327
2586
|
return;
|
|
2328
2587
|
}
|
|
2329
2588
|
const type = IMAGE_MIME[path20.extname(file).toLowerCase()];
|
|
2330
|
-
if (!type || !
|
|
2589
|
+
if (!type || !fs21.existsSync(file) || !fs21.statSync(file).isFile()) {
|
|
2331
2590
|
res.writeHead(404).end();
|
|
2332
2591
|
return;
|
|
2333
2592
|
}
|
|
2334
2593
|
res.writeHead(200, { "content-type": type, "cache-control": "no-cache", "content-security-policy": "sandbox; frame-ancestors 'none'" });
|
|
2335
|
-
|
|
2594
|
+
fs21.createReadStream(file).pipe(res);
|
|
2336
2595
|
}
|
|
2337
2596
|
function openDoc(rel, res) {
|
|
2338
2597
|
let doc;
|
|
@@ -2384,7 +2643,7 @@ async function startServer({ root: root2, port, open: openBrowser }) {
|
|
|
2384
2643
|
console.log(`
|
|
2385
2644
|
${pc.bold("markode")} ${pc.dim("\u2192")} ${pc.cyan(url2)} ${pc.dim(root2)}
|
|
2386
2645
|
`);
|
|
2387
|
-
if (!
|
|
2646
|
+
if (!fs21.existsSync(WEB_DIR)) console.log(pc.yellow(" Web UI not built: run `pnpm build`, or `pnpm dev` and open http://localhost:4320\n"));
|
|
2388
2647
|
else if (openBrowser) open(url2).catch(() => {
|
|
2389
2648
|
});
|
|
2390
2649
|
}
|
|
@@ -2405,17 +2664,17 @@ function listen(server, port) {
|
|
|
2405
2664
|
}
|
|
2406
2665
|
function serveStatic(pathname, res) {
|
|
2407
2666
|
let file = path20.join(WEB_DIR, path20.normalize(pathname).replace(/^(\.\.[/\\])+/, ""));
|
|
2408
|
-
if (!file.startsWith(WEB_DIR) || !
|
|
2409
|
-
if (!
|
|
2667
|
+
if (!file.startsWith(WEB_DIR) || !fs21.existsSync(file) || fs21.statSync(file).isDirectory()) file = path20.join(WEB_DIR, "index.html");
|
|
2668
|
+
if (!fs21.existsSync(file)) {
|
|
2410
2669
|
res.writeHead(404).end("Web UI not built. Run `pnpm build`.");
|
|
2411
2670
|
return;
|
|
2412
2671
|
}
|
|
2413
2672
|
res.writeHead(200, { "content-type": MIME[path20.extname(file)] ?? "application/octet-stream", "content-security-policy": "frame-ancestors 'none'" });
|
|
2414
|
-
|
|
2673
|
+
fs21.createReadStream(file).pipe(res);
|
|
2415
2674
|
}
|
|
2416
2675
|
|
|
2417
2676
|
// src/cli/init.ts
|
|
2418
|
-
import
|
|
2677
|
+
import fs22 from "fs";
|
|
2419
2678
|
import path21 from "path";
|
|
2420
2679
|
import * as p from "@clack/prompts";
|
|
2421
2680
|
import pc2 from "picocolors";
|
|
@@ -2427,12 +2686,12 @@ function check(value) {
|
|
|
2427
2686
|
return value;
|
|
2428
2687
|
}
|
|
2429
2688
|
async function offerClaudeLink(root2, d) {
|
|
2430
|
-
if (
|
|
2689
|
+
if (fs22.existsSync(path21.join(root2, "CLAUDE.md"))) return;
|
|
2431
2690
|
const link2 = d ? d.mainDoc === "CLAUDE.md" : check(await p.confirm({ message: "Claude Code reads CLAUDE.md, not AGENTS.md. Add a CLAUDE.md that imports AGENTS.md?", initialValue: true }));
|
|
2432
2691
|
if (link2 && linkAgentsDoc(root2)) p.log.success("Created CLAUDE.md (imports AGENTS.md)");
|
|
2433
2692
|
}
|
|
2434
2693
|
async function chooseMainDoc(root2, d) {
|
|
2435
|
-
const existing = MAIN_DOCS.filter((d2) =>
|
|
2694
|
+
const existing = MAIN_DOCS.filter((d2) => fs22.existsSync(path21.join(root2, d2)) && !isPointer(fs22.readFileSync(path21.join(root2, d2), "utf8"), d2));
|
|
2436
2695
|
if (d) {
|
|
2437
2696
|
if (existing.length === 1 && existing[0] === "AGENTS.md") await offerClaudeLink(root2, d);
|
|
2438
2697
|
if (existing.length) return existing.includes(d.mainDoc) ? d.mainDoc : existing[0];
|
|
@@ -2707,7 +2966,7 @@ async function runInit(root2, plan2) {
|
|
|
2707
2966
|
const mainFile = path21.join(root2, mainDoc);
|
|
2708
2967
|
if (has2("dashboard")) workflow = await chooseWorkflow(root2, mainDoc, previous?.workflow, d);
|
|
2709
2968
|
if (workflow === "openspec" || workflow === "speckit") applyWorkflowToFile(mainFile, workflow);
|
|
2710
|
-
const mainText =
|
|
2969
|
+
const mainText = fs22.readFileSync(mainFile, "utf8");
|
|
2711
2970
|
const sourceLang = d ? SOURCE_LANG_MARK.test(mainText) ? sourceLangOf(mainText) : detectedLang : check(await p.select({ message: SOURCE_LANG_QUESTION, options: LANG_OPTIONS, initialValue: SOURCE_LANG_MARK.test(mainText) ? sourceLangOf(mainText) : detectedLang }));
|
|
2712
2971
|
const rules = listRules();
|
|
2713
2972
|
const applied = appliedRuleIds(mainText);
|
|
@@ -2906,9 +3165,9 @@ var option = (name) => {
|
|
|
2906
3165
|
var command = args[0] && !args[0].startsWith("-") ? args[0] : "start";
|
|
2907
3166
|
var root = process.env.MARKODE_ROOT ?? process.cwd();
|
|
2908
3167
|
async function main() {
|
|
2909
|
-
if (
|
|
3168
|
+
if (fs23.existsSync(root)) setProjectRoot(root);
|
|
2910
3169
|
if (flag("--help") || flag("-h")) return console.log(HELP);
|
|
2911
|
-
if (flag("--version") || flag("-v")) return console.log(JSON.parse(
|
|
3170
|
+
if (flag("--version") || flag("-v")) return console.log(JSON.parse(fs23.readFileSync(path22.join(PKG_ROOT, "package.json"), "utf8")).version);
|
|
2912
3171
|
const translation = flag("--status") || flag("--mark") || flag("--keep");
|
|
2913
3172
|
if ((command === "sync" || command === "translate") && translation) return sync();
|
|
2914
3173
|
if (command === "translate" || flag("--translate")) return runTranslate(root);
|
|
@@ -3007,7 +3266,7 @@ function link() {
|
|
|
3007
3266
|
}
|
|
3008
3267
|
async function url() {
|
|
3009
3268
|
const doc = args[1] && !args[1].startsWith("-") ? args[1] : void 0;
|
|
3010
|
-
if (doc && (!doc.toLowerCase().endsWith(".md") || !
|
|
3269
|
+
if (doc && (!doc.toLowerCase().endsWith(".md") || !fs23.existsSync(path22.join(root, doc)))) {
|
|
3011
3270
|
console.error(`Usage: markode url [<doc.md>] (relative to ${root})`);
|
|
3012
3271
|
process.exitCode = 1;
|
|
3013
3272
|
return;
|
|
@@ -3023,7 +3282,7 @@ function stop() {
|
|
|
3023
3282
|
}
|
|
3024
3283
|
async function update() {
|
|
3025
3284
|
const latest = await latestVersion();
|
|
3026
|
-
if (!isNewer(latest, CURRENT_VERSION)) return console.log(`markode ${CURRENT_VERSION} is the latest version.`);
|
|
3285
|
+
if (!isNewer(latest, CURRENT_VERSION)) return console.log(`markode ${CURRENT_VERSION} is the latest version (one published in the last minutes may not show yet).`);
|
|
3027
3286
|
console.log(`markode ${latest} is out (you have ${CURRENT_VERSION}).`);
|
|
3028
3287
|
if (flag("--check")) return;
|
|
3029
3288
|
const via = flag("--pnpm") ? "pnpm" : flag("--npm") ? "npm" : installer();
|
|
@@ -3031,7 +3290,7 @@ async function update() {
|
|
|
3031
3290
|
if (!via) return console.log("This copy runs from a clone of the repository: pull and build it, or install it with `markode update --pnpm` (or --npm).");
|
|
3032
3291
|
const cmd = installCommand2(via, latest);
|
|
3033
3292
|
console.log(`$ ${cmd.join(" ")}`);
|
|
3034
|
-
if (runInstall(cmd)) return console.log(`Updated to ${latest}.
|
|
3293
|
+
if (runInstall(cmd)) return console.log(`Updated to ${latest}. The next \`markode url\` (or /markode) restarts a running editor with it.`);
|
|
3035
3294
|
console.error("The install failed; the output above says why.");
|
|
3036
3295
|
process.exitCode = 1;
|
|
3037
3296
|
}
|
|
@@ -3049,7 +3308,7 @@ function changes() {
|
|
|
3049
3308
|
}
|
|
3050
3309
|
async function wait() {
|
|
3051
3310
|
const rel = args[1];
|
|
3052
|
-
if (!rel || !
|
|
3311
|
+
if (!rel || !fs23.existsSync(path22.join(root, rel))) {
|
|
3053
3312
|
console.error(`Usage: markode wait <proposal.md> (relative to ${root})`);
|
|
3054
3313
|
process.exitCode = 1;
|
|
3055
3314
|
return;
|
package/dist/web/assets/{abnfDiagram-WEYOIA3C-B-3Lcktj.js → abnfDiagram-WEYOIA3C-C2SJjHni.js}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{m as e,t}from"./mermaid-parser.core-
|
|
1
|
+
import{m as e,t}from"./mermaid-parser.core-Dh1kQWot.js";import{n}from"./chunk-Y2CYZVJY-DsF7k-Jl.js";import{m as r}from"./src-D76sYeGJ.js";import"./chunk-DSNLSHJZ-CK3bwwQ-.js";import{n as i,r as a,t as o}from"./chunk-2E7WHVMD-Bg92ygkh.js";import{t as s}from"./chunk-JWPE2WC7-DVXcaiue.js";import"./mermaid.core-I_-4X5xX.js";var c=e().RailroadAbnf.parser.LangiumParser,l=n(e=>{let t=e.alternatives.map(u);return t.length===1?t[0]:{type:`choice`,alternatives:t}},`transformAlternation`),u=n(e=>{let t=e.elements.map(f);return t.length===1?t[0]:{type:`sequence`,elements:t}},`transformConcatenation`),d=n(e=>{if(e.includes(`*`)){let[t,n]=e.split(`*`);return{min:t?parseInt(t,10):0,max:n?parseInt(n,10):1/0}}let t=parseInt(e,10);return{min:t,max:t}},`parseRepeat`),f=n(e=>{let t=p(e.primary);if(!e.repeat)return t;let{min:n,max:r}=d(e.repeat);return n===0&&r===1?{type:`optional`,element:t}:{type:`repetition`,element:t,min:n,max:r}},`transformElement`),p=n(e=>{switch(e.$type){case`AbnfStringLiteral`:return{type:`terminal`,value:e.value};case`AbnfNumVal`:return{type:`terminal`,value:e.value};case`AbnfRuleName`:return{type:`nonterminal`,name:e.name};case`AbnfGroup`:return l(e.element);case`AbnfOptionalGroup`:return{type:`optional`,element:l(e.element)};default:throw Error(`Unsupported ABNF primary node: ${e.$type}`)}},`transformPrimary`),m=n(e=>({name:e.name,definition:l(e.definition)}),`transformRule`),h=n(e=>{s(e,o),e.title&&o.setTitle(e.title),e.rules.map(e=>o.addRule(m(e)))},`populateDb`),g={parser:{parse:n(e=>{o.clear(),r.debug(`[ABNF Parser] Starting Langium parse`);let n=c.parse(e);if(n.lexerErrors.length>0||n.parserErrors.length>0)throw new t(n);let i=n.value;r.debug(`[ABNF Parser] Parsed rules:`,i.rules.length),h(i),r.debug(`[ABNF Parser] Parse complete`)},`parse`),parser:{yy:o}},db:o,renderer:a,styles:i};export{g as diagram};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{n as e,t}from"./path-fybaL0A-.js";import{a as n,c as r,d as i,f as a,i as o,l as s,m as c,n as l,o as u,p as d,r as f,u as p}from"./dist-
|
|
1
|
+
import{n as e,t}from"./path-fybaL0A-.js";import{a as n,c as r,d as i,f as a,i as o,l as s,m as c,n as l,o as u,p as d,r as f,u as p}from"./dist-Cihah0nd.js";function m(e){return e.innerRadius}function h(e){return e.outerRadius}function g(e){return e.startAngle}function _(e){return e.endAngle}function v(e){return e&&e.padAngle}function y(e,t,n,r,i,a,o,s){var c=n-e,l=r-t,u=o-i,d=s-a,f=d*c-u*l;if(!(f*f<1e-12))return f=(u*(t-a)-d*(e-i))/f,[e+f*c,t+f*l]}function b(e,t,n,r,i,a,o){var c=e-n,l=t-r,u=(o?a:-a)/d(c*c+l*l),f=u*l,p=-u*c,m=e+f,h=t+p,g=n+f,_=r+p,v=(m+g)/2,y=(h+_)/2,b=g-m,x=_-h,S=b*b+x*x,C=i-a,w=m*_-g*h,T=(x<0?-1:1)*d(s(0,C*C*S-w*w)),E=(w*x-b*T)/S,D=(-w*b-x*T)/S,O=(w*x+b*T)/S,k=(-w*b+x*T)/S,A=E-v,j=D-y,M=O-v,N=k-y;return A*A+j*j>M*M+N*N&&(E=O,D=k),{cx:E,cy:D,x01:-f,y01:-p,x11:E*(i/C-1),y11:D*(i/C-1)}}function x(){var s=m,x=h,S=e(0),C=null,w=g,T=_,E=v,D=null,O=t(k);function k(){var e,t,m=+s.apply(this,arguments),h=+x.apply(this,arguments),g=w.apply(this,arguments)-r,_=T.apply(this,arguments)-r,v=l(_-g),k=_>g;if(D||=e=O(),h<m&&(t=h,h=m,m=t),!(h>1e-12))D.moveTo(0,0);else if(v>c-1e-12)D.moveTo(h*u(g),h*a(g)),D.arc(0,0,h,g,_,!k),m>1e-12&&(D.moveTo(m*u(_),m*a(_)),D.arc(0,0,m,_,g,k));else{var A=g,j=_,M=g,N=_,P=v,F=v,I=E.apply(this,arguments)/2,L=I>1e-12&&(C?+C.apply(this,arguments):d(m*m+h*h)),R=p(l(h-m)/2,+S.apply(this,arguments)),z=R,B=R,V,H;if(L>1e-12){var U=o(L/m*a(I)),W=o(L/h*a(I));(P-=U*2)>1e-12?(U*=k?1:-1,M+=U,N-=U):(P=0,M=N=(g+_)/2),(F-=W*2)>1e-12?(W*=k?1:-1,A+=W,j-=W):(F=0,A=j=(g+_)/2)}var G=h*u(A),K=h*a(A),q=m*u(N),J=m*a(N);if(R>1e-12){var Y=h*u(j),X=h*a(j),Z=m*u(M),Q=m*a(M),$;if(v<i){if($=y(G,K,Z,Q,Y,X,q,J)){var ee=G-$[0],te=K-$[1],ne=Y-$[0],re=X-$[1],ie=1/a(f((ee*ne+te*re)/(d(ee*ee+te*te)*d(ne*ne+re*re)))/2),ae=d($[0]*$[0]+$[1]*$[1]);z=p(R,(m-ae)/(ie-1)),B=p(R,(h-ae)/(ie+1))}else z=B=0}}F>1e-12?B>1e-12?(V=b(Z,Q,G,K,h,B,k),H=b(Y,X,q,J,h,B,k),D.moveTo(V.cx+V.x01,V.cy+V.y01),B<R?D.arc(V.cx,V.cy,B,n(V.y01,V.x01),n(H.y01,H.x01),!k):(D.arc(V.cx,V.cy,B,n(V.y01,V.x01),n(V.y11,V.x11),!k),D.arc(0,0,h,n(V.cy+V.y11,V.cx+V.x11),n(H.cy+H.y11,H.cx+H.x11),!k),D.arc(H.cx,H.cy,B,n(H.y11,H.x11),n(H.y01,H.x01),!k))):(D.moveTo(G,K),D.arc(0,0,h,A,j,!k)):D.moveTo(G,K),!(m>1e-12)||!(P>1e-12)?D.lineTo(q,J):z>1e-12?(V=b(q,J,Y,X,m,-z,k),H=b(G,K,Z,Q,m,-z,k),D.lineTo(V.cx+V.x01,V.cy+V.y01),z<R?D.arc(V.cx,V.cy,z,n(V.y01,V.x01),n(H.y01,H.x01),!k):(D.arc(V.cx,V.cy,z,n(V.y01,V.x01),n(V.y11,V.x11),!k),D.arc(0,0,m,n(V.cy+V.y11,V.cx+V.x11),n(H.cy+H.y11,H.cx+H.x11),k),D.arc(H.cx,H.cy,z,n(H.y11,H.x11),n(H.y01,H.x01),!k))):D.arc(0,0,m,N,M,k)}if(D.closePath(),e)return D=null,e+``||null}return k.centroid=function(){var e=(+s.apply(this,arguments)+ +x.apply(this,arguments))/2,t=(+w.apply(this,arguments)+ +T.apply(this,arguments))/2-i/2;return[u(t)*e,a(t)*e]},k.innerRadius=function(t){return arguments.length?(s=typeof t==`function`?t:e(+t),k):s},k.outerRadius=function(t){return arguments.length?(x=typeof t==`function`?t:e(+t),k):x},k.cornerRadius=function(t){return arguments.length?(S=typeof t==`function`?t:e(+t),k):S},k.padRadius=function(t){return arguments.length?(C=t==null?null:typeof t==`function`?t:e(+t),k):C},k.startAngle=function(t){return arguments.length?(w=typeof t==`function`?t:e(+t),k):w},k.endAngle=function(t){return arguments.length?(T=typeof t==`function`?t:e(+t),k):T},k.padAngle=function(t){return arguments.length?(E=typeof t==`function`?t:e(+t),k):E},k.context=function(e){return arguments.length?(D=e??null,k):D},k}export{x as t};
|
package/dist/web/assets/{architecture-WOLXFQ4H-D8_qhlNG.js → architecture-WOLXFQ4H-Cb7DZ4zr.js}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
import"./chunk-NGNAAXSQ-C2Wy9Xmz.js";export{M as createArchitectureServices}from"./mermaid-parser.core-
|
|
1
|
+
import"./chunk-NGNAAXSQ-C2Wy9Xmz.js";export{M as createArchitectureServices}from"./mermaid-parser.core-Dh1kQWot.js";
|