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.
- package/LICENSE +21 -0
- package/README.md +350 -0
- package/dist/catalog.d.ts +8 -0
- package/dist/catalog.d.ts.map +1 -0
- package/dist/catalog.js +140 -0
- package/dist/catalog.js.map +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +301 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/catalog.d.ts +24 -0
- package/dist/commands/catalog.d.ts.map +1 -0
- package/dist/commands/catalog.js +88 -0
- package/dist/commands/catalog.js.map +1 -0
- package/dist/commands/graph.d.ts +45 -0
- package/dist/commands/graph.d.ts.map +1 -0
- package/dist/commands/graph.js +344 -0
- package/dist/commands/graph.js.map +1 -0
- package/dist/commands/inspect.d.ts +36 -0
- package/dist/commands/inspect.d.ts.map +1 -0
- package/dist/commands/inspect.js +143 -0
- package/dist/commands/inspect.js.map +1 -0
- package/dist/commands/ownership.d.ts +50 -0
- package/dist/commands/ownership.d.ts.map +1 -0
- package/dist/commands/ownership.js +154 -0
- package/dist/commands/ownership.js.map +1 -0
- package/dist/commands/readiness.d.ts +64 -0
- package/dist/commands/readiness.d.ts.map +1 -0
- package/dist/commands/readiness.js +614 -0
- package/dist/commands/readiness.js.map +1 -0
- package/dist/commands/scan.d.ts +4 -0
- package/dist/commands/scan.d.ts.map +1 -0
- package/dist/commands/scan.js +12 -0
- package/dist/commands/scan.js.map +1 -0
- package/dist/commands/suggest-semantic-split.d.ts +8 -0
- package/dist/commands/suggest-semantic-split.d.ts.map +1 -0
- package/dist/commands/suggest-semantic-split.js +215 -0
- package/dist/commands/suggest-semantic-split.js.map +1 -0
- package/dist/config.d.ts +15 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +184 -0
- package/dist/config.js.map +1 -0
- package/dist/discovery.d.ts +7 -0
- package/dist/discovery.d.ts.map +1 -0
- package/dist/discovery.js +122 -0
- package/dist/discovery.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -0
- package/dist/markdown.d.ts +4 -0
- package/dist/markdown.d.ts.map +1 -0
- package/dist/markdown.js +77 -0
- package/dist/markdown.js.map +1 -0
- package/dist/metadata.d.ts +8 -0
- package/dist/metadata.d.ts.map +1 -0
- package/dist/metadata.js +61 -0
- package/dist/metadata.js.map +1 -0
- package/dist/model.d.ts +56 -0
- package/dist/model.d.ts.map +1 -0
- package/dist/model.js +2 -0
- package/dist/model.js.map +1 -0
- package/dist/report.d.ts +6 -0
- package/dist/report.d.ts.map +1 -0
- package/dist/report.js +39 -0
- package/dist/report.js.map +1 -0
- package/dist/rule-engine.d.ts +16 -0
- package/dist/rule-engine.d.ts.map +1 -0
- package/dist/rule-engine.js +10 -0
- package/dist/rule-engine.js.map +1 -0
- package/dist/rules.d.ts +7 -0
- package/dist/rules.d.ts.map +1 -0
- package/dist/rules.js +1413 -0
- package/dist/rules.js.map +1 -0
- package/dist/scanner.d.ts +5 -0
- package/dist/scanner.d.ts.map +1 -0
- package/dist/scanner.js +104 -0
- package/dist/scanner.js.map +1 -0
- package/dist/types.d.ts +99 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +56 -0
- 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"}
|
package/dist/catalog.js
ADDED
|
@@ -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 @@
|
|
|
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"}
|