@mrciphersmith/keryx 0.2.83 → 0.2.88

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 (49) hide show
  1. package/README.md +1 -1
  2. package/dist/cli.js +29861 -20525
  3. package/dist/core.js +25871 -0
  4. package/package.json +16 -2
  5. package/src/gdgraph/dangling.ts +204 -0
  6. package/src/gdgraph/find.ts +529 -37
  7. package/src/gdgraph/repomap.ts +140 -12
  8. package/src/gdgraph/staleness.ts +22 -9
  9. package/src/gdgraph/symbol.ts +45 -6
  10. package/src/gdgraph/treesitter/extract.ts +153 -5
  11. package/src/gdgraph/wiki-layer.ts +32 -1
  12. package/src/gdskills/bundled/skills/core/reviewer-skill-creator/SKILL.md +29 -0
  13. package/src/gdskills/bundled/skills/orchestration/code-verifier/SKILL.codex.md +1 -1
  14. package/src/gdskills/bundled/skills/orchestration/code-verifier/SKILL.cursor.md +1 -1
  15. package/src/gdskills/bundled/skills/orchestration/code-verifier/SKILL.md +1 -1
  16. package/src/gdskills/bundled/skills/orchestration/code-verifier/SKILL.opencode.md +1 -1
  17. package/src/gdskills/bundled/skills/orchestration/code-verifier/SKILL.zed.md +1 -1
  18. package/src/gdskills/bundled/skills/orchestration/flow-orchestrator/SKILL.md +50 -13
  19. package/src/gdskills/bundled/skills/orchestration/job-orchestrator/SKILL.codex.md +1 -1
  20. package/src/gdskills/bundled/skills/orchestration/job-orchestrator/SKILL.cursor.md +1 -1
  21. package/src/gdskills/bundled/skills/orchestration/job-orchestrator/SKILL.md +1 -1
  22. package/src/gdskills/bundled/skills/orchestration/job-orchestrator/SKILL.opencode.md +1 -1
  23. package/src/gdskills/bundled/skills/orchestration/job-orchestrator/SKILL.zed.md +1 -1
  24. package/src/gdskills/bundled/skills/quality/security-audit/SKILL.codex.md +52 -5
  25. package/src/gdskills/bundled/skills/quality/security-audit/SKILL.cursor.md +52 -5
  26. package/src/gdskills/bundled/skills/quality/security-audit/SKILL.md +52 -5
  27. package/src/gdskills/bundled/skills/review/review-pr-feedback/SKILL.md +12 -0
  28. package/src/gdgraph/affected.test.ts +0 -133
  29. package/src/gdgraph/build-integrity.test.ts +0 -193
  30. package/src/gdgraph/build-lang.test.ts +0 -406
  31. package/src/gdgraph/build.test.ts +0 -120
  32. package/src/gdgraph/config.test.ts +0 -47
  33. package/src/gdgraph/core-sources.test.ts +0 -99
  34. package/src/gdgraph/fallback.test.ts +0 -153
  35. package/src/gdgraph/find.test.ts +0 -78
  36. package/src/gdgraph/import-kind.test.ts +0 -525
  37. package/src/gdgraph/path.test.ts +0 -56
  38. package/src/gdgraph/repomap.test.ts +0 -110
  39. package/src/gdgraph/service.test.ts +0 -89
  40. package/src/gdgraph/staleness.test.ts +0 -208
  41. package/src/gdgraph/symbol.test.ts +0 -89
  42. package/src/gdgraph/symbols-capability.test.ts +0 -138
  43. package/src/gdgraph/treesitter/adapter.test.ts +0 -496
  44. package/src/gdgraph/treesitter/extract.test.ts +0 -278
  45. package/src/gdgraph/treesitter/no-treesitter-import.test.ts +0 -51
  46. package/src/gdgraph/treesitter/real-grammar-fixture.test.ts +0 -71
  47. package/src/gdgraph/treesitter/resolve-calls.test.ts +0 -38
  48. package/src/gdgraph/wiki-layer-no-git.test.ts +0 -73
  49. package/src/gdgraph/wiki-layer.test.ts +0 -211
@@ -1,211 +0,0 @@
1
- // LWG wiki layer (flow 223, phase 0): AC1, AC5, AC6, AC7, AC10, AC13.
2
-
3
- import { describe, expect, test } from "bun:test";
4
- import { mkdtemp, mkdir, readFile, writeFile } from "node:fs/promises";
5
- import { tmpdir } from "node:os";
6
- import path from "node:path";
7
- import { buildGraph } from "./build";
8
- import { getFilesDescribedBy, getPagesDescribing, loadGraph } from "./query";
9
- import type { GraphData } from "./types";
10
- import { buildWikiLayer, computeFingerprints, wikiPageId } from "./wiki-layer";
11
-
12
- const GRAPH: GraphData = {
13
- nodes: [
14
- { id: "src/ctx/index.ts", kind: "file", path: "src/ctx/index.ts", language: "typescript" },
15
- { id: "src/ctx/run.ts", kind: "file", path: "src/ctx/run.ts", language: "typescript" },
16
- { id: "logo.png", kind: "asset", path: "logo.png", language: "asset" },
17
- ],
18
- edges: [],
19
- };
20
-
21
- function page(relativePath: string, overrides: Partial<{ title: string; pageType: string }> = {}) {
22
- return {
23
- relativePath,
24
- title: overrides.title ?? relativePath,
25
- pageType: overrides.pageType ?? "component",
26
- status: "accepted" as string | null,
27
- version: "1.0.0" as string | null,
28
- };
29
- }
30
-
31
- describe("buildWikiLayer", () => {
32
- test("AC1: emits a page node per page and describes edges for resolved paths", () => {
33
- const layer = buildWikiLayer({
34
- projectRoot: "/x",
35
- graph: GRAPH,
36
- validModules: new Set(["src/ctx"]),
37
- pages: [page("components/src-ctx.md")],
38
- pageContents: new Map([
39
- ["components/src-ctx.md", "Describes:\n - src/ctx/index.ts\n - src/ctx/run.ts\n"],
40
- ]),
41
- });
42
-
43
- expect(layer.pages).toHaveLength(1);
44
- expect(layer.pages[0]?.id).toBe("wiki:components/src-ctx.md");
45
- expect(layer.pages[0]?.undecidable).toBe(false);
46
- expect(layer.describes.map((edge) => edge.to)).toEqual(["src/ctx/index.ts", "src/ctx/run.ts"]);
47
- expect(layer.describes.every((edge) => edge.origin === "frontmatter")).toBe(true);
48
- });
49
-
50
- test("AC6: an unbuilt graph yields an EMPTY layer, not a layer of orphans", () => {
51
- const layer = buildWikiLayer({
52
- projectRoot: "/x",
53
- graph: GRAPH,
54
- validModules: undefined,
55
- pages: [page("components/src-ctx.md")],
56
- pageContents: new Map([["components/src-ctx.md", "Describes:\n - src/ctx/index.ts\n"]]),
57
- });
58
-
59
- // The dangerous alternative is one page node per page marked undecidable:
60
- // that reads downstream as "every page describes nothing", i.e. everything
61
- // is orphaned. Absent information must stay absent.
62
- expect(layer).toEqual({ pages: [], describes: [] });
63
- });
64
-
65
- test("AC5: the module set drives the layer — a stubbed set changes the output", () => {
66
- const withModules = buildWikiLayer({
67
- projectRoot: "/x",
68
- graph: GRAPH,
69
- validModules: new Set(["src/ctx"]),
70
- pages: [page("components/src-ctx.md")],
71
- pageContents: new Map([["components/src-ctx.md", "# Page\n"]]),
72
- });
73
- const withoutModules = buildWikiLayer({
74
- projectRoot: "/x",
75
- graph: GRAPH,
76
- validModules: undefined,
77
- pages: [page("components/src-ctx.md")],
78
- pageContents: new Map([["components/src-ctx.md", "# Page\n"]]),
79
- });
80
- expect(withModules.pages.length).not.toBe(withoutModules.pages.length);
81
- });
82
-
83
- test("AC10: a page describing nothing is undecidable and emits no edges", () => {
84
- const layer = buildWikiLayer({
85
- projectRoot: "/x",
86
- graph: GRAPH,
87
- validModules: new Set(["src/ctx"]),
88
- pages: [page("architecture/overview.md", { pageType: "architecture" })],
89
- pageContents: new Map([["architecture/overview.md", "# Overview\nStatus: accepted\n"]]),
90
- });
91
-
92
- expect(layer.pages[0]?.undecidable).toBe(true);
93
- expect(layer.describes).toEqual([]);
94
- });
95
-
96
- test("asset nodes are never describable targets", () => {
97
- const layer = buildWikiLayer({
98
- projectRoot: "/x",
99
- graph: GRAPH,
100
- validModules: new Set(["src/ctx"]),
101
- pages: [page("components/x.md")],
102
- pageContents: new Map([["components/x.md", "Describes:\n - logo.png\n"]]),
103
- });
104
- expect(layer.describes).toEqual([]);
105
- expect(layer.pages[0]?.undecidable).toBe(true);
106
- });
107
- });
108
-
109
- describe("computeFingerprints (AC7)", () => {
110
- test("hashes are content-derived, stable and sorted by path", () => {
111
- const records = [
112
- { path: "b.ts", content: "export const b = 1;\n" },
113
- { path: "a.ts", content: "export const a = 1;\n" },
114
- ];
115
- const first = computeFingerprints(records, new Map([["a.ts", 5]]));
116
- const second = computeFingerprints(records, new Map([["a.ts", 5]]));
117
-
118
- expect(first.map((f) => f.path)).toEqual(["a.ts", "b.ts"]);
119
- expect(first).toEqual(second);
120
- expect(first[0]?.contentHash).toMatch(/^[0-9a-f]{64}$/);
121
- expect(first[0]?.contentHash).not.toBe(first[1]?.contentHash);
122
- // A file whose mtime could not be read is recorded as 0, not dropped.
123
- expect(first[1]?.mtimeMs).toBe(0);
124
- });
125
- });
126
-
127
- describe("reverse queries (AC3)", () => {
128
- const graph: GraphData = {
129
- ...GRAPH,
130
- describes: [
131
- { id: "d1", from: wikiPageId("components/a.md"), to: "src/ctx/index.ts", pattern: "src/ctx", origin: "key-files" },
132
- { id: "d2", from: wikiPageId("components/b.md"), to: "src/ctx/index.ts", pattern: "src/ctx/index.ts", origin: "frontmatter" },
133
- { id: "d3", from: wikiPageId("components/b.md"), to: "src/ctx/run.ts", pattern: "src/ctx/run.ts", origin: "frontmatter" },
134
- ],
135
- };
136
-
137
- test("a file covered by two pages returns both, and nothing else", () => {
138
- expect(getPagesDescribing(graph, "src/ctx/index.ts")).toEqual([
139
- "wiki:components/a.md",
140
- "wiki:components/b.md",
141
- ]);
142
- expect(getPagesDescribing(graph, "src/ctx/run.ts")).toEqual(["wiki:components/b.md"]);
143
- });
144
-
145
- test("the forward direction is available from the same layer", () => {
146
- expect(getFilesDescribedBy(graph, wikiPageId("components/b.md"))).toEqual([
147
- "src/ctx/index.ts",
148
- "src/ctx/run.ts",
149
- ]);
150
- });
151
-
152
- test("no layer means no information, and an empty answer says so honestly", () => {
153
- expect(getPagesDescribing({ nodes: [], edges: [] }, "src/ctx/index.ts")).toEqual([]);
154
- });
155
- });
156
-
157
- describe("end-to-end build (AC1, AC7, AC13)", () => {
158
- async function fixture(): Promise<string> {
159
- const root = await mkdtemp(path.join(tmpdir(), "lwg-build-"));
160
- await mkdir(path.join(root, "src", "ctx"), { recursive: true });
161
- await writeFile(path.join(root, "src", "ctx", "index.ts"), 'export * from "./run";\n');
162
- await writeFile(path.join(root, "src", "ctx", "run.ts"), "export const run = () => 1;\n");
163
- return root;
164
- }
165
-
166
- test("layer files appear, and nodes.jsonl/edges.jsonl stay byte-identical (AC13)", async () => {
167
- const root = await fixture();
168
- const storage = path.join(root, ".metaproject", "data", "gdgraph", "storage");
169
-
170
- // Build with no wiki at all: the layer cannot run.
171
- await buildGraph(root);
172
- const nodesBefore = await readFile(path.join(storage, "nodes.jsonl"), "utf8");
173
- const edgesBefore = await readFile(path.join(storage, "edges.jsonl"), "utf8");
174
-
175
- // Now add a wiki page and rebuild: the layer runs.
176
- await mkdir(path.join(root, ".metaproject", "wiki", "components"), { recursive: true });
177
- await writeFile(
178
- path.join(root, ".metaproject", "wiki", "components", "src-ctx.md"),
179
- "# src/ctx\nVersion: 1.0.0\nType: component\nStatus: accepted\nDescribes:\n - src/ctx/run.ts\n",
180
- );
181
- await buildGraph(root);
182
-
183
- const nodesAfter = await readFile(path.join(storage, "nodes.jsonl"), "utf8");
184
- const edgesAfter = await readFile(path.join(storage, "edges.jsonl"), "utf8");
185
- // The whole reason the layer is separate: legacy artifacts unchanged.
186
- expect(nodesAfter).toBe(nodesBefore);
187
- expect(edgesAfter).toBe(edgesBefore);
188
-
189
- const graph = await loadGraph(root);
190
- expect(graph.wikiPages?.map((p) => p.id)).toEqual(["wiki:components/src-ctx.md"]);
191
- expect(getFilesDescribedBy(graph, "wiki:components/src-ctx.md")).toEqual(["src/ctx/run.ts"]);
192
-
193
- const manifest = JSON.parse(await readFile(path.join(storage, "build-manifest.json"), "utf8"));
194
- expect(manifest.files.map((f: { path: string }) => f.path)).toEqual([
195
- "src/ctx/index.ts",
196
- "src/ctx/run.ts",
197
- ]);
198
- expect(manifest.files[0].contentHash).toMatch(/^[0-9a-f]{64}$/);
199
- expect(manifest.files[0].mtimeMs).toBeGreaterThan(0);
200
- });
201
-
202
- test("AC2: a graph with no layer files loads with the fields simply absent", async () => {
203
- const root = await fixture();
204
- await buildGraph(root);
205
- // No wiki directory was ever created, so no layer files exist.
206
- const graph = await loadGraph(root);
207
- expect(graph.wikiPages).toBeUndefined();
208
- expect(graph.describes).toBeUndefined();
209
- expect(graph.nodes.length).toBeGreaterThan(0);
210
- });
211
- });