@geml/geml 1.5.1 → 1.7.0

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 (45) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +248 -217
  3. package/codemap/adapters/crg.mjs +120 -120
  4. package/codemap/adapters/joern.mjs +131 -131
  5. package/codemap/adapters/scip.mjs +658 -658
  6. package/codemap/browser-stub.mjs +34 -29
  7. package/codemap/build.mjs +609 -609
  8. package/codemap/cross-stack.mjs +303 -303
  9. package/codemap/detect.mjs +399 -399
  10. package/codemap/emit.mjs +480 -480
  11. package/codemap/entries.mjs +129 -129
  12. package/codemap/exclude.mjs +52 -52
  13. package/codemap/find.mjs +49 -49
  14. package/codemap/foldings.mjs +110 -110
  15. package/codemap/joern-export.sc +83 -83
  16. package/codemap/mcp-server.mjs +431 -431
  17. package/codemap/normalize.mjs +275 -275
  18. package/codemap/recipe-trust.mjs +103 -103
  19. package/codemap/refresh.mjs +310 -310
  20. package/codemap/render-all.mjs +77 -77
  21. package/codemap/serve.mjs +585 -585
  22. package/codemap/sfc-virtualize.mjs +367 -367
  23. package/codemap/verify.mjs +155 -148
  24. package/dist/chart.d.ts +1 -0
  25. package/dist/chart.js +4 -1
  26. package/dist/diagnostics.d.ts +1 -1
  27. package/dist/diagnostics.js +16 -0
  28. package/dist/geml.d.ts +5 -1
  29. package/dist/geml.js +1277 -283
  30. package/dist/history.d.ts +11 -8
  31. package/dist/history.js +20 -15
  32. package/dist/mcp.d.ts +1 -1
  33. package/dist/mcp.js +108 -38
  34. package/dist/render-html.d.ts +5 -0
  35. package/dist/render-html.js +45 -36
  36. package/dist/render.d.ts +1 -0
  37. package/dist/render.js +172 -136
  38. package/dist/selector.d.ts +55 -0
  39. package/dist/selector.js +112 -0
  40. package/dist/serialize.js +12 -0
  41. package/dist/table.js +27 -1
  42. package/dist/to-md.js +5 -0
  43. package/package.json +67 -66
  44. package/skill/SKILL.md +82 -0
  45. package/skill/references/authoring.geml +333 -0
@@ -1,77 +1,77 @@
1
- #!/usr/bin/env node
2
- // geml codemap render — render every codemap document to a sibling .html.
3
- //
4
- // geml codemap render [codemap-dir]
5
- //
6
- // The output folder then works with NO server: open index.html straight from
7
- // disk (file://). Module click-through opens each container page inside the
8
- // graph area (nested frame), so the whole map is browsable offline — this is
9
- // the "copy the folder to someone" mode. For a live view that never goes
10
- // stale, use `geml codemap serve` instead.
11
- import { readdirSync, readFileSync, writeFileSync, realpathSync } from "node:fs";
12
- import { join, basename, sep, resolve as resolvePath } from "node:path";
13
- import { parse, renderHtml } from "../dist/geml.js";
14
-
15
- if (process.argv[2] === "--help" || process.argv[2] === "-h") {
16
- console.error("usage: geml codemap render [codemap-dir] (dir defaults to ./.geml-code-graph)");
17
- process.exit(2);
18
- }
19
- const dir = process.argv[2] || ".geml-code-graph";
20
-
21
- // One shared cache for the whole batch: every page's graph slice crosses the
22
- // same neighbour documents, and a fresh parse per page turns N pages into
23
- // O(N x working set) — hours at repo scale. A one-shot process has no
24
- // staleness to worry about, so cache unconditionally (the whole codemap's
25
- // text + parsed docs live in memory for the duration of the run).
26
- const texts = new Map(); // rel -> text | null
27
- const parsed = new Map(); // text -> Document
28
- // `rel` is document-controlled — a `src=` composed by the renderer — and the
29
- // output of this command is a published artifact, so an unconfined read here
30
- // writes any .geml on the filesystem into a file that then gets served. Gate on
31
- // the realpath, the same shape `serve` and the CLI resolver use.
32
- let realDir = null;
33
- try { realDir = realpathSync(resolvePath(dir)); } catch { realDir = null; }
34
- const loadDoc = (rel) => {
35
- if (!texts.has(rel)) {
36
- let text = null;
37
- if (realDir !== null) {
38
- try {
39
- const real = realpathSync(join(dir, rel));
40
- if (real === realDir || real.startsWith(realDir + sep)) text = readFileSync(real, "utf8");
41
- } catch { text = null; }
42
- }
43
- texts.set(rel, text);
44
- }
45
- return texts.get(rel);
46
- };
47
- const parseDoc = (s) => {
48
- let d = parsed.get(s);
49
- if (!d) { d = parse(s); parsed.set(s, d); }
50
- return d;
51
- };
52
-
53
- let n = 0;
54
- const failed = [];
55
- let files;
56
- try {
57
- files = readdirSync(dir);
58
- } catch {
59
- console.error(`error: cannot read directory ${dir}`);
60
- process.exit(1);
61
- }
62
- for (const f of files) {
63
- if (!f.endsWith(".geml")) continue;
64
- try {
65
- const text = loadDoc(f);
66
- if (text === null) throw new Error("unreadable");
67
- const doc = parseDoc(text);
68
- const html = renderHtml(doc, { source: basename(f), loadDoc, parseDoc });
69
- writeFileSync(join(dir, f.replace(/\.geml$/, ".html")), html);
70
- n++;
71
- } catch (e) {
72
- failed.push(f);
73
- console.error(`render: ${f}: ${e.message}`);
74
- }
75
- }
76
- console.error(`rendered ${n} page(s) -> ${dir}${failed.length ? `; FAILED: ${failed.join(", ")}` : ""}`);
77
- process.exit(failed.length ? 1 : 0);
1
+ #!/usr/bin/env node
2
+ // geml codemap render — render every codemap document to a sibling .html.
3
+ //
4
+ // geml codemap render [codemap-dir]
5
+ //
6
+ // The output folder then works with NO server: open index.html straight from
7
+ // disk (file://). Module click-through opens each container page inside the
8
+ // graph area (nested frame), so the whole map is browsable offline — this is
9
+ // the "copy the folder to someone" mode. For a live view that never goes
10
+ // stale, use `geml codemap serve` instead.
11
+ import { readdirSync, readFileSync, writeFileSync, realpathSync } from "node:fs";
12
+ import { join, basename, sep, resolve as resolvePath } from "node:path";
13
+ import { parse, renderHtml } from "../dist/geml.js";
14
+
15
+ if (process.argv[2] === "--help" || process.argv[2] === "-h") {
16
+ console.error("usage: geml codemap render [codemap-dir] (dir defaults to ./.geml-code-graph)");
17
+ process.exit(2);
18
+ }
19
+ const dir = process.argv[2] || ".geml-code-graph";
20
+
21
+ // One shared cache for the whole batch: every page's graph slice crosses the
22
+ // same neighbour documents, and a fresh parse per page turns N pages into
23
+ // O(N x working set) — hours at repo scale. A one-shot process has no
24
+ // staleness to worry about, so cache unconditionally (the whole codemap's
25
+ // text + parsed docs live in memory for the duration of the run).
26
+ const texts = new Map(); // rel -> text | null
27
+ const parsed = new Map(); // text -> Document
28
+ // `rel` is document-controlled — a `src=` composed by the renderer — and the
29
+ // output of this command is a published artifact, so an unconfined read here
30
+ // writes any .geml on the filesystem into a file that then gets served. Gate on
31
+ // the realpath, the same shape `serve` and the CLI resolver use.
32
+ let realDir = null;
33
+ try { realDir = realpathSync(resolvePath(dir)); } catch { realDir = null; }
34
+ const loadDoc = (rel) => {
35
+ if (!texts.has(rel)) {
36
+ let text = null;
37
+ if (realDir !== null) {
38
+ try {
39
+ const real = realpathSync(join(dir, rel));
40
+ if (real === realDir || real.startsWith(realDir + sep)) text = readFileSync(real, "utf8");
41
+ } catch { text = null; }
42
+ }
43
+ texts.set(rel, text);
44
+ }
45
+ return texts.get(rel);
46
+ };
47
+ const parseDoc = (s) => {
48
+ let d = parsed.get(s);
49
+ if (!d) { d = parse(s); parsed.set(s, d); }
50
+ return d;
51
+ };
52
+
53
+ let n = 0;
54
+ const failed = [];
55
+ let files;
56
+ try {
57
+ files = readdirSync(dir);
58
+ } catch {
59
+ console.error(`error: cannot read directory ${dir}`);
60
+ process.exit(1);
61
+ }
62
+ for (const f of files) {
63
+ if (!f.endsWith(".geml")) continue;
64
+ try {
65
+ const text = loadDoc(f);
66
+ if (text === null) throw new Error("unreadable");
67
+ const doc = parseDoc(text);
68
+ const html = renderHtml(doc, { source: basename(f), loadDoc, parseDoc });
69
+ writeFileSync(join(dir, f.replace(/\.geml$/, ".html")), html);
70
+ n++;
71
+ } catch (e) {
72
+ failed.push(f);
73
+ console.error(`render: ${f}: ${e.message}`);
74
+ }
75
+ }
76
+ console.error(`rendered ${n} page(s) -> ${dir}${failed.length ? `; FAILED: ${failed.join(", ")}` : ""}`);
77
+ process.exit(failed.length ? 1 : 0);