renma 0.1.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 (84) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +350 -0
  3. package/dist/catalog.d.ts +8 -0
  4. package/dist/catalog.d.ts.map +1 -0
  5. package/dist/catalog.js +140 -0
  6. package/dist/catalog.js.map +1 -0
  7. package/dist/cli.d.ts +2 -0
  8. package/dist/cli.d.ts.map +1 -0
  9. package/dist/cli.js +301 -0
  10. package/dist/cli.js.map +1 -0
  11. package/dist/commands/catalog.d.ts +24 -0
  12. package/dist/commands/catalog.d.ts.map +1 -0
  13. package/dist/commands/catalog.js +88 -0
  14. package/dist/commands/catalog.js.map +1 -0
  15. package/dist/commands/graph.d.ts +45 -0
  16. package/dist/commands/graph.d.ts.map +1 -0
  17. package/dist/commands/graph.js +344 -0
  18. package/dist/commands/graph.js.map +1 -0
  19. package/dist/commands/inspect.d.ts +36 -0
  20. package/dist/commands/inspect.d.ts.map +1 -0
  21. package/dist/commands/inspect.js +143 -0
  22. package/dist/commands/inspect.js.map +1 -0
  23. package/dist/commands/ownership.d.ts +50 -0
  24. package/dist/commands/ownership.d.ts.map +1 -0
  25. package/dist/commands/ownership.js +154 -0
  26. package/dist/commands/ownership.js.map +1 -0
  27. package/dist/commands/readiness.d.ts +64 -0
  28. package/dist/commands/readiness.d.ts.map +1 -0
  29. package/dist/commands/readiness.js +614 -0
  30. package/dist/commands/readiness.js.map +1 -0
  31. package/dist/commands/scan.d.ts +4 -0
  32. package/dist/commands/scan.d.ts.map +1 -0
  33. package/dist/commands/scan.js +12 -0
  34. package/dist/commands/scan.js.map +1 -0
  35. package/dist/commands/suggest-semantic-split.d.ts +8 -0
  36. package/dist/commands/suggest-semantic-split.d.ts.map +1 -0
  37. package/dist/commands/suggest-semantic-split.js +215 -0
  38. package/dist/commands/suggest-semantic-split.js.map +1 -0
  39. package/dist/config.d.ts +15 -0
  40. package/dist/config.d.ts.map +1 -0
  41. package/dist/config.js +184 -0
  42. package/dist/config.js.map +1 -0
  43. package/dist/discovery.d.ts +7 -0
  44. package/dist/discovery.d.ts.map +1 -0
  45. package/dist/discovery.js +122 -0
  46. package/dist/discovery.js.map +1 -0
  47. package/dist/index.d.ts +3 -0
  48. package/dist/index.d.ts.map +1 -0
  49. package/dist/index.js +4 -0
  50. package/dist/index.js.map +1 -0
  51. package/dist/markdown.d.ts +4 -0
  52. package/dist/markdown.d.ts.map +1 -0
  53. package/dist/markdown.js +77 -0
  54. package/dist/markdown.js.map +1 -0
  55. package/dist/metadata.d.ts +8 -0
  56. package/dist/metadata.d.ts.map +1 -0
  57. package/dist/metadata.js +61 -0
  58. package/dist/metadata.js.map +1 -0
  59. package/dist/model.d.ts +56 -0
  60. package/dist/model.d.ts.map +1 -0
  61. package/dist/model.js +2 -0
  62. package/dist/model.js.map +1 -0
  63. package/dist/report.d.ts +6 -0
  64. package/dist/report.d.ts.map +1 -0
  65. package/dist/report.js +39 -0
  66. package/dist/report.js.map +1 -0
  67. package/dist/rule-engine.d.ts +16 -0
  68. package/dist/rule-engine.d.ts.map +1 -0
  69. package/dist/rule-engine.js +10 -0
  70. package/dist/rule-engine.js.map +1 -0
  71. package/dist/rules.d.ts +7 -0
  72. package/dist/rules.d.ts.map +1 -0
  73. package/dist/rules.js +1413 -0
  74. package/dist/rules.js.map +1 -0
  75. package/dist/scanner.d.ts +5 -0
  76. package/dist/scanner.d.ts.map +1 -0
  77. package/dist/scanner.js +104 -0
  78. package/dist/scanner.js.map +1 -0
  79. package/dist/types.d.ts +99 -0
  80. package/dist/types.d.ts.map +1 -0
  81. package/dist/types.js +2 -0
  82. package/dist/types.js.map +1 -0
  83. package/package.json +56 -0
  84. package/scripts/split-reference.mjs +172 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Kazuaki Matsuo
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,350 @@
1
+ # Renma - 練磨
2
+
3
+ Renma helps teams keep LLM-ready context assets and skills healthy in Git.
4
+
5
+ Renma is a Git-native governance and quality layer for shared context repositories. It prepares repositories so Codex, Claude, Cursor, and future agents can consume team-owned expertise correctly. Renma does not choose task context, assemble prompts, inject context, or execute agent workflows; agents and runtimes decide how to use the assets for a task.
6
+
7
+ ```text
8
+ Skill = LLM-facing entrypoint / routing contract / usage guide
9
+ Context = independently owned source-of-truth knowledge asset
10
+ ```
11
+
12
+ ## Why Renma?
13
+
14
+ As AI-agent repositories grow, expertise often gets copied into many skills. Testing heuristics, domain risks, tool usage notes, and team-specific contracts drift apart. Ownership becomes unclear, references break, deprecated guidance remains reachable, and new engineers or agents cannot tell which knowledge is authoritative.
15
+
16
+ Renma treats context as a software asset:
17
+
18
+ - Reusable
19
+ - Owned
20
+ - Reviewable
21
+ - Versioned
22
+ - Composable
23
+ - Validated
24
+ - Easy to inspect in CI and code review
25
+
26
+ The first strong product focus is QA/testing: boundary value analysis, negative testing, regression risk, payment idempotency, duplicate charge prevention, refund edge cases, mobile offline behavior, mobile automation usage, internal test strategy, and known team-specific risks can live as shared context assets instead of being buried inside individual skills.
27
+
28
+ ## Repository Shape
29
+
30
+ Renma supports skill-local references, profiles, and examples, but the target repository model gives shared context assets first-class space:
31
+
32
+ ```text
33
+ skills/
34
+ testing/
35
+ test-case-generation.skill.md
36
+ spec-review.skill.md
37
+ regression-planning.skill.md
38
+ contexts/
39
+ testing/
40
+ boundary-value-analysis.md
41
+ negative-testing.md
42
+ regression-risk.md
43
+ domain/
44
+ payment/
45
+ idempotency.md
46
+ duplicate-charge.md
47
+ refund-risk.md
48
+ mobile/
49
+ offline-behavior.md
50
+ background-resume.md
51
+ tools/
52
+ mobile/
53
+ device-setup.md
54
+ helper-guidelines.md
55
+ teams/
56
+ checkout/
57
+ payment-api-contracts.md
58
+ known-risk-patterns.md
59
+ ```
60
+
61
+ `contexts/` is preferred. `context/` is also scanned for compatibility. Files under either root are cataloged as first-class `context` assets, while skill-local `references/` remain `reference` assets.
62
+
63
+ ## What Renma Does
64
+
65
+ Today Renma is a minimal-dependency TypeScript CLI that scans AI-agent skills, repository instructions, shared context Markdown, profile overlays, references, and examples. It runs deterministic quality, structure, and safety rules, then emits text or JSON reports with file and line evidence. It also emits deterministic catalog, ownership coverage, graph, and agent readiness reports from the same local catalog model.
66
+
67
+ Renma findings are intended to be actionable repair prompts for humans and LLM
68
+ tools such as Codex, Claude, and Cursor. Findings should explain what is wrong,
69
+ why it matters, where the evidence is, what a safe repair should preserve, and
70
+ how to verify the fix. Renma does not apply large semantic rewrites itself; it
71
+ emits structured diagnostics so a human or agent can propose a reviewable patch
72
+ and run Renma again.
73
+
74
+ Completed baseline:
75
+
76
+ - Bounded filesystem discovery
77
+ - Stable POSIX-style repo-relative paths
78
+ - Markdown parsing for headings, links, code fences, metadata, and evidence
79
+ - Structural quality checks for skills, shared context assets, and local support files
80
+ - Safety checks for risky instructions and literal secrets
81
+ - Deterministic catalog output for assets and dependency metadata
82
+ - Deterministic ownership coverage reporting for cataloged assets
83
+ - Context graph snapshot reporting
84
+ - Deterministic agent readiness scoring for static repository health
85
+ - Deterministic metadata governance for duplicate asset IDs, unknown declared references, references to deprecated or archived assets, and orphaned shared context assets
86
+ - Repository file outline and line-slice inspection helper
87
+ - Semantic split prompt helper for oversized context files
88
+ - CI-friendly exit behavior with `--fail-on`
89
+ - Config loading from `renma.config.json` and `.renma.json`
90
+
91
+ Near-term direction:
92
+
93
+ - Agent readiness report
94
+ - Repeated context and duplicate knowledge discovery
95
+ - Semantic diff for context changes
96
+ - Optional LLM-assisted repository evaluation bundles
97
+ - Optional external signal import
98
+
99
+ See [architecture.md](./architecture.md) and [plan.md](./plan.md) for the current design direction.
100
+
101
+ ## Requirements
102
+
103
+ - Node.js 22.17 or newer
104
+ - npm
105
+
106
+ Install:
107
+
108
+ ```bash
109
+ npm install
110
+ npm run build
111
+ ```
112
+
113
+ After building, run the CLI directly:
114
+
115
+ ```bash
116
+ node dist/index.js scan .
117
+ ```
118
+
119
+ When installed as a package, the binary name is:
120
+
121
+ ```bash
122
+ renma scan .
123
+ ```
124
+
125
+ ## Usage
126
+
127
+ ```bash
128
+ renma scan [path] [options]
129
+ renma catalog [path] [options]
130
+ renma graph [path] [options]
131
+ renma ownership [path] [options]
132
+ renma readiness [path] [options]
133
+ renma inspect <file> [options]
134
+ renma suggest-semantic-split <file> [options]
135
+ ```
136
+
137
+ Readiness output also includes a compact workflow readiness summary that groups workflow-level checks, counts pass/warn/fail states, and reports a deterministic workflow readiness percentage.
138
+
139
+ `renma readiness` emits a static, deterministic agent-readiness report with a score, level, summary metrics, checks, and diagnostics. It exits 0 only when the level is `ready`; `needs_attention` and `not_ready` exit 1 for CI use. It does not call LLMs, choose runtime context, assemble prompts, or repair files.
140
+
141
+ ### Agent readiness v1
142
+
143
+ Agent readiness v1 is a deterministic static report for checking whether skill workflow entrypoints are safe and understandable enough for human or agent consumption. It does not decide runtime context selection, assemble prompts, call an LLM, or repair files.
144
+
145
+ The v1 workflow checks cover:
146
+
147
+ - required context closure
148
+ - optional context health
149
+ - routing and usage clarity
150
+ - required inputs / prerequisites
151
+ - completion criteria / definition of done
152
+
153
+ The report also includes a workflow readiness summary that counts workflow pass/warn/fail states and reports a deterministic workflow readiness percentage.
154
+
155
+ A ready report is intentionally compact enough to paste into a PR description, for example: level, score, workflow readiness, graph resolution, ownership coverage, diagnostics, and layout status.
156
+
157
+ Dogfooding against the `appium/skills` branch `refine2` produced a ready v1 report with all workflow checks passing, all graph edges resolved, all assets owned, no diagnostics, and passing layout checks. The example confirmed that the Markdown recap is useful for PR reviews without changing Renma's deterministic static boundaries.
158
+
159
+ The JSON and Markdown reports expose `summary.workflow` counts, graph resolution, ownership coverage, diagnostics, and layout status. They do not perform runtime context selection, assemble prompt packages, call an LLM, auto-repair files, score repairability, or plan per-skill patches.
160
+
161
+ Workflow context closure checks that each skill entrypoint's declared required context references resolve to usable, non-deprecated, non-archived assets.
162
+
163
+ Workflow optional-context checks warn when declared optional context references are unresolved, deprecated, or archived, without deciding whether optional context should be loaded at runtime.
164
+
165
+ Workflow clarity warns when skill entrypoints lack deterministic routing, preflight, examples, verification, or other static guidance needed for responsible agent use.
166
+
167
+ Workflow required-input checks warn when skill entrypoints do not document the inputs, prerequisites, or permissions agents need before starting.
168
+
169
+ Workflow completion-criteria checks warn when skill entrypoints do not state the final output, evidence, report contents, patch expectations, or stop condition needed to complete the workflow.
170
+
171
+ `renma inspect` is a repository inspection helper for outlines and exact line slices; it does not choose task context or assemble prompts.
172
+
173
+ Options:
174
+
175
+ ```text
176
+ -c, --config <path> Read JSON config from path
177
+ --fail-on <level> Exit 1 when findings meet severity: low, medium, high, critical
178
+ --format <format> scan: text or json; catalog/ownership: json or markdown; graph: json, markdown, or mermaid; suggest: prompt or json
179
+ --include-owned ownership: include owned asset details
180
+ --json Shortcut for --format json
181
+ --view <view> graph: summary, workflow, or full
182
+ --lines <range> inspect: exact line range, e.g. L10-L42
183
+ --max-source-bytes <n>
184
+ suggest-semantic-split: source file byte budget
185
+ --max-context-bytes <n>
186
+ suggest-semantic-split: nearby context byte budget
187
+ -h, --help Show help
188
+ -v, --version Show version
189
+ ```
190
+
191
+ Examples:
192
+
193
+ ```bash
194
+ renma scan .
195
+ renma scan ./my-repo --json
196
+ renma scan . --fail-on medium
197
+ renma scan . --config ./renma.config.json
198
+ renma catalog . --format markdown
199
+ renma catalog . --json
200
+ renma graph . --format markdown
201
+ renma graph . --format mermaid
202
+ renma graph . --format mermaid --view workflow
203
+ renma graph . --json
204
+ renma ownership . --format markdown
205
+ renma ownership . --json
206
+ renma ownership . --json --include-owned
207
+ renma readiness . --format markdown
208
+ renma readiness . --json
209
+ renma inspect contexts/testing/boundary-value-analysis.md --format json
210
+ renma inspect contexts/testing/boundary-value-analysis.md --lines L40-L90 --format text
211
+ renma suggest-semantic-split contexts/testing/boundary-value-analysis.md
212
+ ```
213
+
214
+ ## What Gets Scanned
215
+
216
+ By default, Renma looks for:
217
+
218
+ ```text
219
+ skills/**/SKILL.md
220
+ .agents/**/*.md
221
+ AGENTS.md
222
+ README.md
223
+ context/**/*.md
224
+ contexts/**/*.md
225
+ tools/**/*
226
+ ```
227
+
228
+ It skips `node_modules`, `dist`, and `.git`, ignores symbolic links, enforces a maximum file size, and reports paths in stable POSIX-style form.
229
+
230
+ ## Configuration
231
+
232
+ Renma automatically looks for `renma.config.json`, then `.renma.json`.
233
+
234
+ Configuration is applied in this order:
235
+
236
+ 1. Defaults
237
+ 2. Config file
238
+ 3. CLI flags
239
+
240
+ Example:
241
+
242
+ ```json
243
+ {
244
+ "fail_on": "high",
245
+ "format": "json",
246
+ "globs": [
247
+ "skills/**/SKILL.md",
248
+ "AGENTS.md",
249
+ "contexts/**/*.md"
250
+ ],
251
+ "exclude": ["node_modules", "dist", ".git"],
252
+ "max_file_size_bytes": 524288,
253
+ "max_depth": 16,
254
+ "concurrency": 16,
255
+ "layout": {
256
+ "workflow_aliases": {}
257
+ }
258
+ }
259
+ ```
260
+
261
+ Supported fields:
262
+
263
+ - `fail_on`: `low`, `medium`, `high`, or `critical`
264
+ - `format`: `text` or `json`
265
+ - `globs`: array of glob patterns
266
+ - `exclude`: array of path segment names to skip
267
+ - `max_file_size_bytes`: positive integer
268
+ - `max_depth`: positive integer
269
+ - `concurrency`: positive integer
270
+ - `layout`: optional strict layout policy configuration
271
+ - `tool_namespace`: optional namespace for suggested `contexts/tools/<namespace>/...` and `tools/<namespace>/...` paths
272
+ - `workflow_aliases`: map of skill directory names to canonical workflow directory names
273
+
274
+ Invalid config fields exit with code `2`.
275
+
276
+ ## Layout Policy
277
+
278
+ Strict layout diagnostics are generic by default. Renma suggests context assets under `contexts/<workflow>/...` and helper assets under `tools/<workflow>/...` unless a repository config adds a tool namespace.
279
+
280
+ - `layout.tool_namespace` is optional. When set, it controls the namespace used in suggested `contexts/tools/<namespace>/<workflow>/...` and `tools/<namespace>/<workflow>/...` paths. When omitted, Renma suggests `contexts/<workflow>/...` and `tools/<workflow>/...` paths.
281
+ - `layout.workflow_aliases` maps skill directory names to canonical workflow directory names.
282
+
283
+ Example:
284
+
285
+ ```json
286
+ {
287
+ "layout": {
288
+ "tool_namespace": "mobile",
289
+ "workflow_aliases": {
290
+ "device-setup": "real-device"
291
+ }
292
+ }
293
+ }
294
+ ```
295
+
296
+ ## Exit Codes
297
+
298
+ - `0`: Scan completed and no findings met the failure threshold
299
+ - `1`: Scan completed and at least one finding met `fail_on`
300
+ - `2`: CLI usage error, invalid config, or unreadable required input
301
+
302
+ ## Checks
303
+
304
+ Current rules include:
305
+
306
+ - Missing skill description, examples, preflight, verification, negative routing, or explicit routing clarity
307
+ - Short frontmatter descriptions
308
+ - Oversized `SKILL.md` entrypoints
309
+ - Metadata governance findings surfaced through `scan`, including invalid lifecycle status values, missing shared context `id` or `owner`, duplicate asset IDs, unknown declared references, declared references to deprecated or archived assets, and orphaned shared context assets
310
+ - Oversized shared context assets or local support files in `contexts/`, `context/`, `profiles/`, `references/`, and `examples/`
311
+ - Unreachable skill-local profiles, references, and examples
312
+ - Profile overlays missing base skill declaration
313
+ - Skills that still route through deprecated or superseded local support assets after reusable knowledge has moved to canonical shared context assets
314
+ - Non-skill assets that still reference deprecated or superseded support files instead of canonical shared context assets
315
+ - Advisory reusable-context candidates in `SKILL.md` files with enough size and diverse setup, troubleshooting, platform, testing, risk, or domain-rule signals
316
+ - Advisory shared-context candidates in large `contexts/**/*.md` assets with generic source-of-truth headings and reusable guidance phrases
317
+ - Advisory shared-context assets under process-state folders such as `contexts/promoted/`, `contexts/generated/`, or `contexts/drafts/` that should become semantic final paths
318
+ - Literal secret-like values
319
+ - Private key material
320
+ - Destructive commands without nearby confirmation or recovery context
321
+ - Risky remote defaults
322
+ - Broad environment copying into subprocesses
323
+ - Hardcoded user-local paths
324
+
325
+ Declared reference validation resolves exact asset IDs and repository-relative paths, including paths with a leading `./` normalized away. It does not perform fuzzy matching, semantic lookup, runtime context selection, or prompt assembly.
326
+
327
+ Static checks are evidence. Passing a scan does not prove a repository or agent workflow is safe.
328
+
329
+ ## Development
330
+
331
+ ```bash
332
+ npm run build
333
+ npm run typecheck
334
+ npm test
335
+ ```
336
+
337
+ The package build emits the CLI to `dist/index.js`. Tests compile to `dist-test/`.
338
+
339
+ ## Inspirations
340
+
341
+ Renma is inspired by:
342
+
343
+ - [Waza](https://github.com/microsoft/waza), especially skill eval coverage, task-based regression checks, and readiness-oriented validation.
344
+ - [SkillSpector](https://github.com/NVIDIA/skillspector), especially deterministic security scanning, risk-oriented findings, SARIF/reporting direction, and analyzer-style rule organization.
345
+
346
+ Renma is an independent implementation focused on lightweight deterministic governance checks for AI-agent skill and context repositories.
347
+
348
+ ## License
349
+
350
+ MIT. See [LICENSE](./LICENSE).
@@ -0,0 +1,8 @@
1
+ import type { Catalog } from "./model.js";
2
+ import type { Diagnostic, ParsedDocument } from "./types.js";
3
+ /** Build a deterministic catalog of skill and context entries from parsed documents. */
4
+ export declare function buildCatalog(documents: ParsedDocument[]): {
5
+ catalog: Catalog;
6
+ diagnostics: Diagnostic[];
7
+ };
8
+ //# sourceMappingURL=catalog.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"catalog.d.ts","sourceRoot":"","sources":["../src/catalog.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAEV,OAAO,EAIR,MAAM,YAAY,CAAC;AAEpB,OAAO,KAAK,EAAE,UAAU,EAAY,cAAc,EAAE,MAAM,YAAY,CAAC;AAEvE,wFAAwF;AACxF,wBAAgB,YAAY,CAAC,SAAS,EAAE,cAAc,EAAE,GAAG;IACzD,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,EAAE,UAAU,EAAE,CAAC;CAC3B,CAkEA"}
@@ -0,0 +1,140 @@
1
+ import { createHash } from "node:crypto";
2
+ import { parseAssetMetadata } from "./metadata.js";
3
+ /** Build a deterministic catalog of skill and context entries from parsed documents. */
4
+ export function buildCatalog(documents) {
5
+ const diagnostics = [];
6
+ const entries = documents
7
+ .map((document) => {
8
+ const result = parseAssetMetadata(document);
9
+ diagnostics.push(...result.diagnostics);
10
+ diagnostics.push(...sharedContextMetadataDiagnostics(document, result.metadata));
11
+ const base = {
12
+ id: result.metadata.id ?? document.artifact.path,
13
+ sourcePath: document.artifact.path,
14
+ contentHash: contentHash(document.artifact.content),
15
+ metadata: result.metadata,
16
+ };
17
+ if (document.artifact.kind === "skill") {
18
+ return {
19
+ ...base,
20
+ kind: "skill",
21
+ requiredContext: result.metadata.requiresContext,
22
+ optionalContext: result.metadata.optionalContext,
23
+ conflicts: result.metadata.conflicts,
24
+ };
25
+ }
26
+ if (document.artifact.kind === "context" ||
27
+ document.artifact.kind === "profile" ||
28
+ document.artifact.kind === "reference" ||
29
+ document.artifact.kind === "example") {
30
+ return {
31
+ ...base,
32
+ kind: document.artifact.kind,
33
+ };
34
+ }
35
+ return undefined;
36
+ })
37
+ .filter((entry) => entry !== undefined)
38
+ .sort((a, b) => {
39
+ const byKind = kindOrder(a.kind) - kindOrder(b.kind);
40
+ if (byKind !== 0)
41
+ return byKind;
42
+ return a.sourcePath.localeCompare(b.sourcePath);
43
+ });
44
+ const dependencies = entries
45
+ .flatMap((entry) => dependenciesForEntry(entry))
46
+ .sort((a, b) => {
47
+ const byFrom = a.from.localeCompare(b.from);
48
+ if (byFrom !== 0)
49
+ return byFrom;
50
+ const byKind = dependencyKindOrder(a.kind) - dependencyKindOrder(b.kind);
51
+ if (byKind !== 0)
52
+ return byKind;
53
+ return a.to.localeCompare(b.to);
54
+ });
55
+ return {
56
+ catalog: {
57
+ entries,
58
+ assets: entries,
59
+ dependencies,
60
+ },
61
+ diagnostics,
62
+ };
63
+ }
64
+ function contentHash(content) {
65
+ return `sha256:${createHash("sha256").update(content).digest("hex")}`;
66
+ }
67
+ function sharedContextMetadataDiagnostics(document, metadata) {
68
+ if (document.artifact.kind !== "context")
69
+ return [];
70
+ const diagnostics = [];
71
+ if (!metadata.id) {
72
+ diagnostics.push({
73
+ severity: "warning",
74
+ path: document.artifact.path,
75
+ message: "Shared context asset is missing an id.",
76
+ });
77
+ }
78
+ if (!metadata.owner) {
79
+ diagnostics.push({
80
+ severity: "warning",
81
+ path: document.artifact.path,
82
+ message: "Shared context asset is missing an owner.",
83
+ });
84
+ }
85
+ return diagnostics;
86
+ }
87
+ /** Convert metadata relationship lists into graph edges for a catalog entry. */
88
+ function dependenciesForEntry(entry) {
89
+ return [
90
+ ...metadataDependencies(entry, "requires", entry.metadata.requiresContext),
91
+ ...metadataDependencies(entry, "optional", entry.metadata.optionalContext),
92
+ ...metadataDependencies(entry, "conflicts", entry.metadata.conflicts),
93
+ ...metadataDependencies(entry, "references", entry.metadata.supersededBy),
94
+ ];
95
+ }
96
+ function metadataDependencies(entry, kind, targets) {
97
+ return targets.map((target) => ({
98
+ from: entry.id,
99
+ to: target,
100
+ kind,
101
+ sourcePath: entry.sourcePath,
102
+ evidence: metadataEvidence(entry.sourcePath),
103
+ }));
104
+ }
105
+ /** Evidence points at frontmatter until metadata parsing preserves field line ranges. */
106
+ function metadataEvidence(path) {
107
+ return {
108
+ path,
109
+ startLine: 1,
110
+ endLine: 1,
111
+ snippet: "frontmatter dependency metadata",
112
+ };
113
+ }
114
+ /** Keep catalog output stable across filesystems and Node versions. */
115
+ function kindOrder(kind) {
116
+ if (kind === "skill")
117
+ return 0;
118
+ if (kind === "context")
119
+ return 1;
120
+ if (kind === "profile")
121
+ return 2;
122
+ if (kind === "reference")
123
+ return 3;
124
+ return 4;
125
+ }
126
+ /** Keep dependency output stable while grouping the most important edges first. */
127
+ function dependencyKindOrder(kind) {
128
+ if (kind === "requires")
129
+ return 0;
130
+ if (kind === "optional")
131
+ return 1;
132
+ if (kind === "conflicts")
133
+ return 2;
134
+ if (kind === "extends")
135
+ return 3;
136
+ if (kind === "references")
137
+ return 4;
138
+ return 5;
139
+ }
140
+ //# sourceMappingURL=catalog.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"catalog.js","sourceRoot":"","sources":["../src/catalog.ts"],"names":[],"mappings":"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"}
package/dist/cli.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ export declare function main(argv?: string[]): Promise<number>;
2
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AA2BA,wBAAsB,IAAI,CAAC,IAAI,WAAwB,GAAG,OAAO,CAAC,MAAM,CAAC,CA6ExE"}