renma 0.17.0 → 0.18.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/CHANGELOG.md +123 -1
- package/README.md +11 -1
- package/architecture.md +14 -4
- package/design.md +13 -2
- package/dist/agent-skills.d.ts +1 -1
- package/dist/agent-skills.d.ts.map +1 -1
- package/dist/agent-skills.js +28 -8
- package/dist/agent-skills.js.map +1 -1
- package/dist/catalog.d.ts +1 -1
- package/dist/catalog.d.ts.map +1 -1
- package/dist/catalog.js +120 -12
- package/dist/catalog.js.map +1 -1
- package/dist/cli-help.d.ts +9 -5
- package/dist/cli-help.d.ts.map +1 -1
- package/dist/cli-help.js +9 -0
- package/dist/cli-help.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +23 -0
- package/dist/cli.js.map +1 -1
- package/dist/commands/bom.d.ts +6 -3
- package/dist/commands/bom.d.ts.map +1 -1
- package/dist/commands/bom.js +27 -7
- package/dist/commands/bom.js.map +1 -1
- package/dist/commands/catalog.d.ts +1 -1
- package/dist/commands/catalog.d.ts.map +1 -1
- package/dist/commands/catalog.js +7 -1
- package/dist/commands/catalog.js.map +1 -1
- package/dist/commands/ci-report.d.ts.map +1 -1
- package/dist/commands/ci-report.js +18 -5
- package/dist/commands/ci-report.js.map +1 -1
- package/dist/commands/diff.js +8 -2
- package/dist/commands/diff.js.map +1 -1
- package/dist/commands/graph.d.ts +6 -2
- package/dist/commands/graph.d.ts.map +1 -1
- package/dist/commands/graph.js +23 -2
- package/dist/commands/graph.js.map +1 -1
- package/dist/commands/inspect.d.ts.map +1 -1
- package/dist/commands/inspect.js +2 -0
- package/dist/commands/inspect.js.map +1 -1
- package/dist/commands/ownership.d.ts +4 -3
- package/dist/commands/ownership.d.ts.map +1 -1
- package/dist/commands/ownership.js +27 -23
- package/dist/commands/ownership.js.map +1 -1
- package/dist/commands/readiness.d.ts +2 -1
- package/dist/commands/readiness.d.ts.map +1 -1
- package/dist/commands/readiness.js +98 -30
- package/dist/commands/readiness.js.map +1 -1
- package/dist/commands/scaffold.d.ts +3 -0
- package/dist/commands/scaffold.d.ts.map +1 -1
- package/dist/commands/scaffold.js +14 -0
- package/dist/commands/scaffold.js.map +1 -1
- package/dist/commands/suggest-metadata.d.ts.map +1 -1
- package/dist/commands/suggest-metadata.js +2 -0
- package/dist/commands/suggest-metadata.js.map +1 -1
- package/dist/commands/trust-graph.d.ts.map +1 -1
- package/dist/commands/trust-graph.js +12 -0
- package/dist/commands/trust-graph.js.map +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +10 -3
- package/dist/config.js.map +1 -1
- package/dist/diagnostic-ids.d.ts +8 -0
- package/dist/diagnostic-ids.d.ts.map +1 -1
- package/dist/diagnostic-ids.js +8 -0
- package/dist/diagnostic-ids.js.map +1 -1
- package/dist/discovery.d.ts +5 -0
- package/dist/discovery.d.ts.map +1 -1
- package/dist/discovery.js +108 -65
- package/dist/discovery.js.map +1 -1
- package/dist/markdown.d.ts.map +1 -1
- package/dist/markdown.js +15 -0
- package/dist/markdown.js.map +1 -1
- package/dist/model.d.ts +17 -1
- package/dist/model.d.ts.map +1 -1
- package/dist/model.js +4 -1
- package/dist/model.js.map +1 -1
- package/dist/quality-profile.d.ts +91 -0
- package/dist/quality-profile.d.ts.map +1 -0
- package/dist/quality-profile.js +91 -0
- package/dist/quality-profile.js.map +1 -0
- package/dist/repeated-context.d.ts.map +1 -1
- package/dist/repeated-context.js +38 -83
- package/dist/repeated-context.js.map +1 -1
- package/dist/repository-boundary.d.ts +30 -0
- package/dist/repository-boundary.d.ts.map +1 -0
- package/dist/repository-boundary.js +116 -0
- package/dist/repository-boundary.js.map +1 -0
- package/dist/repository-evidence.d.ts +2 -0
- package/dist/repository-evidence.d.ts.map +1 -1
- package/dist/repository-evidence.js +6 -4
- package/dist/repository-evidence.js.map +1 -1
- package/dist/repository-paths.d.ts +6 -2
- package/dist/repository-paths.d.ts.map +1 -1
- package/dist/repository-paths.js +75 -24
- package/dist/repository-paths.js.map +1 -1
- package/dist/rules.d.ts +2 -0
- package/dist/rules.d.ts.map +1 -1
- package/dist/rules.js +263 -176
- package/dist/rules.js.map +1 -1
- package/dist/scanner.d.ts.map +1 -1
- package/dist/scanner.js +5 -1
- package/dist/scanner.js.map +1 -1
- package/dist/security-diagnostics.d.ts.map +1 -1
- package/dist/security-diagnostics.js +95 -30
- package/dist/security-diagnostics.js.map +1 -1
- package/dist/security-diff.d.ts +5 -2
- package/dist/security-diff.d.ts.map +1 -1
- package/dist/security-diff.js +20 -4
- package/dist/security-diff.js.map +1 -1
- package/dist/security-policy-inventory.d.ts +15 -3
- package/dist/security-policy-inventory.d.ts.map +1 -1
- package/dist/security-policy-inventory.js +123 -26
- package/dist/security-policy-inventory.js.map +1 -1
- package/dist/security-policy.d.ts +7 -0
- package/dist/security-policy.d.ts.map +1 -1
- package/dist/security-policy.js +70 -7
- package/dist/security-policy.js.map +1 -1
- package/dist/security-posture.d.ts.map +1 -1
- package/dist/security-posture.js +2 -1
- package/dist/security-posture.js.map +1 -1
- package/dist/skill-migration.js +2 -0
- package/dist/skill-migration.js.map +1 -1
- package/dist/static-support.d.ts +13 -0
- package/dist/static-support.d.ts.map +1 -0
- package/dist/static-support.js +284 -0
- package/dist/static-support.js.map +1 -0
- package/dist/token-estimator.d.ts +21 -0
- package/dist/token-estimator.d.ts.map +1 -0
- package/dist/token-estimator.js +84 -0
- package/dist/token-estimator.js.map +1 -0
- package/dist/trust-graph.d.ts +3 -3
- package/dist/trust-graph.d.ts.map +1 -1
- package/dist/trust-graph.js +69 -10
- package/dist/trust-graph.js.map +1 -1
- package/dist/types.d.ts +6 -1
- package/dist/types.d.ts.map +1 -1
- package/docs/README.md +13 -7
- package/docs/advanced-skill-authoring.md +16 -9
- package/docs/agent-skills-compatibility.md +10 -2
- package/docs/authoring-guide.md +62 -4
- package/docs/diagnostics.md +44 -11
- package/docs/quality-profile.md +123 -0
- package/docs/repository-context-bom.md +67 -8
- package/docs/schemas/repository-context-bom-v2.schema.json +648 -0
- package/docs/schemas/trust-graph-v2.schema.json +301 -0
- package/docs/security-policy.md +21 -5
- package/docs/trust-graph.md +47 -0
- package/docs/user-manual.md +34 -5
- package/examples/context-repo/README.md +6 -7
- package/examples/context-repo/contexts/domain/payment/idempotency.md +7 -0
- package/examples/context-repo/contexts/testing/boundary-value-analysis.md +7 -0
- package/examples/context-repo/contexts/testing/negative-testing.md +7 -0
- package/examples/context-repo/skills/testing/spec-review/SKILL.md +5 -0
- package/package.json +3 -1
- package/plan-discovery.md +24 -15
- package/plan.md +59 -119
- package/scripts/verify-package.mjs +8 -1
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { classifyRepositorySkillPath, logicalSkillDirectory, } from "./discovery.js";
|
|
3
|
+
const SUPPORT_ROOTS = [
|
|
4
|
+
"references",
|
|
5
|
+
"scripts",
|
|
6
|
+
"assets",
|
|
7
|
+
"profiles",
|
|
8
|
+
"examples",
|
|
9
|
+
];
|
|
10
|
+
/** Parse exact, repository-local support references once for rules and graphs. */
|
|
11
|
+
export function staticSupportReferences(document, skillDirectory, localCandidatePaths) {
|
|
12
|
+
const candidatesByBasename = new Map();
|
|
13
|
+
for (const candidate of localCandidatePaths) {
|
|
14
|
+
const basename = path.posix.basename(candidate);
|
|
15
|
+
const values = candidatesByBasename.get(basename) ?? [];
|
|
16
|
+
values.push(candidate);
|
|
17
|
+
candidatesByBasename.set(basename, values);
|
|
18
|
+
}
|
|
19
|
+
const references = [];
|
|
20
|
+
const seen = new Set();
|
|
21
|
+
for (let index = 0; index < document.lines.length; index += 1) {
|
|
22
|
+
const line = document.lines[index] ?? "";
|
|
23
|
+
const values = [];
|
|
24
|
+
const markdownLinks = markdownLinkDestinations(line);
|
|
25
|
+
values.push(...markdownLinks);
|
|
26
|
+
let unquotedLine = maskRawMatches(line, markdownLinks.map((link) => link.raw));
|
|
27
|
+
const quotedMatches = [];
|
|
28
|
+
for (const match of unquotedLine.matchAll(/([`'"])((?:\.\/)?(?:references|scripts|assets|profiles|examples)\/.*?)\1/g)) {
|
|
29
|
+
if (match[2]) {
|
|
30
|
+
values.push({ raw: match[0], value: match[2] });
|
|
31
|
+
quotedMatches.push(match[0]);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
unquotedLine = maskRawMatches(unquotedLine, quotedMatches);
|
|
35
|
+
for (const match of unquotedLine.matchAll(/(?:^|[\s([])((?:\.\/)?(?:references|scripts|assets|profiles|examples)\/[^\s)`'"\],;]+)/g)) {
|
|
36
|
+
if (match[1])
|
|
37
|
+
values.push({ raw: match[0].trim(), value: match[1] });
|
|
38
|
+
}
|
|
39
|
+
for (const [basename, paths] of candidatesByBasename) {
|
|
40
|
+
if (paths.length !== 1 || !containsExactBasename(line, basename))
|
|
41
|
+
continue;
|
|
42
|
+
values.push({ raw: basename, value: paths[0] });
|
|
43
|
+
}
|
|
44
|
+
for (const value of values) {
|
|
45
|
+
const normalized = normalizeStaticSupportReference(value.value, skillDirectory);
|
|
46
|
+
if (!normalized)
|
|
47
|
+
continue;
|
|
48
|
+
const key = `${index + 1}:${normalized.targetPath}`;
|
|
49
|
+
if (seen.has(key))
|
|
50
|
+
continue;
|
|
51
|
+
seen.add(key);
|
|
52
|
+
references.push({
|
|
53
|
+
sourcePath: document.artifact.path,
|
|
54
|
+
targetPath: normalized.targetPath,
|
|
55
|
+
relativePath: normalized.relativePath,
|
|
56
|
+
line: index + 1,
|
|
57
|
+
raw: value.raw,
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return references.sort((left, right) => left.line - right.line ||
|
|
62
|
+
left.targetPath.localeCompare(right.targetPath) ||
|
|
63
|
+
left.raw.localeCompare(right.raw));
|
|
64
|
+
}
|
|
65
|
+
function maskRawMatches(line, matches) {
|
|
66
|
+
let masked = line;
|
|
67
|
+
for (const match of matches) {
|
|
68
|
+
masked = masked.replace(match, " ".repeat(match.length));
|
|
69
|
+
}
|
|
70
|
+
return masked;
|
|
71
|
+
}
|
|
72
|
+
export function buildStaticSupportDependencies(documents, entries, repositoryPaths) {
|
|
73
|
+
const documentsByPath = new Map(documents.map((document) => [document.artifact.path, document]));
|
|
74
|
+
const entriesByPath = new Map(entries.map((entry) => [entry.sourcePath, entry]));
|
|
75
|
+
const skillEntries = entries.filter((entry) => entry.kind === "skill");
|
|
76
|
+
const skillCounts = new Map();
|
|
77
|
+
for (const skill of skillEntries) {
|
|
78
|
+
const directory = logicalSkillDirectory(skill.sourcePath);
|
|
79
|
+
if (!directory)
|
|
80
|
+
continue;
|
|
81
|
+
skillCounts.set(directory, (skillCounts.get(directory) ?? 0) + 1);
|
|
82
|
+
}
|
|
83
|
+
const result = [];
|
|
84
|
+
for (const skill of skillEntries) {
|
|
85
|
+
const skillDirectory = logicalSkillDirectory(skill.sourcePath);
|
|
86
|
+
if (!skillDirectory)
|
|
87
|
+
continue;
|
|
88
|
+
if (skillCounts.get(skillDirectory) !== 1)
|
|
89
|
+
continue;
|
|
90
|
+
const localEntries = entries.filter((entry) => {
|
|
91
|
+
const classified = classifyRepositorySkillPath(entry.sourcePath);
|
|
92
|
+
return (classified?.kind === "support" &&
|
|
93
|
+
classified.skillDirectory === skillDirectory);
|
|
94
|
+
});
|
|
95
|
+
for (const local of localEntries) {
|
|
96
|
+
result.push({
|
|
97
|
+
from: skill.id,
|
|
98
|
+
to: local.id,
|
|
99
|
+
kind: "owns_local_resource",
|
|
100
|
+
sourcePath: skill.sourcePath,
|
|
101
|
+
});
|
|
102
|
+
if (local.ownership.source === "inherited") {
|
|
103
|
+
result.push({
|
|
104
|
+
from: local.id,
|
|
105
|
+
to: skill.id,
|
|
106
|
+
kind: "inherits_owner",
|
|
107
|
+
sourcePath: local.sourcePath,
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
if (local.kind === "script" || local.kind === "asset") {
|
|
111
|
+
result.push({
|
|
112
|
+
from: local.id,
|
|
113
|
+
to: skill.id,
|
|
114
|
+
kind: "inherits_policy",
|
|
115
|
+
sourcePath: local.sourcePath,
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
const candidatePaths = [...repositoryPaths].filter((candidate) => {
|
|
120
|
+
const classified = classifyRepositorySkillPath(candidate);
|
|
121
|
+
return (classified?.kind === "support" &&
|
|
122
|
+
classified.skillDirectory === skillDirectory);
|
|
123
|
+
});
|
|
124
|
+
const sources = [skill, ...localEntries]
|
|
125
|
+
.map((entry) => documentsByPath.get(entry.sourcePath))
|
|
126
|
+
.filter((document) => document !== undefined);
|
|
127
|
+
for (const source of sources) {
|
|
128
|
+
for (const reference of staticSupportReferences(source, skillDirectory, candidatePaths)) {
|
|
129
|
+
const target = entriesByPath.get(reference.targetPath);
|
|
130
|
+
if (!target ||
|
|
131
|
+
target.id === entriesByPath.get(source.artifact.path)?.id)
|
|
132
|
+
continue;
|
|
133
|
+
result.push({
|
|
134
|
+
from: entriesByPath.get(source.artifact.path)?.id ?? skill.id,
|
|
135
|
+
to: target.id,
|
|
136
|
+
kind: "statically_references",
|
|
137
|
+
sourcePath: source.artifact.path,
|
|
138
|
+
evidence: {
|
|
139
|
+
path: source.artifact.path,
|
|
140
|
+
startLine: reference.line,
|
|
141
|
+
endLine: reference.line,
|
|
142
|
+
snippet: reference.raw,
|
|
143
|
+
},
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
return dedupeDependencies(result);
|
|
149
|
+
}
|
|
150
|
+
function normalizeStaticSupportReference(value, skillDirectory) {
|
|
151
|
+
const cleaned = decodePath(stripUriSuffix(value.trim()))
|
|
152
|
+
.replace(/^<|>$/g, "")
|
|
153
|
+
.replace(/[),.;:]+$/, "")
|
|
154
|
+
.replace(/^\.\//, "");
|
|
155
|
+
if (!cleaned || path.posix.isAbsolute(cleaned))
|
|
156
|
+
return undefined;
|
|
157
|
+
if (cleaned.split("/").includes(".."))
|
|
158
|
+
return undefined;
|
|
159
|
+
const repositoryRelative = cleaned.startsWith(`${skillDirectory}/`)
|
|
160
|
+
? cleaned
|
|
161
|
+
: path.posix.join(skillDirectory, cleaned);
|
|
162
|
+
const normalized = path.posix.normalize(repositoryRelative);
|
|
163
|
+
const relativePath = path.posix.relative(skillDirectory, normalized);
|
|
164
|
+
if (relativePath.startsWith("../") ||
|
|
165
|
+
relativePath === ".." ||
|
|
166
|
+
!SUPPORT_ROOTS.includes(relativePath.split("/")[0]) ||
|
|
167
|
+
relativePath.endsWith("/")) {
|
|
168
|
+
return undefined;
|
|
169
|
+
}
|
|
170
|
+
return { targetPath: normalized, relativePath };
|
|
171
|
+
}
|
|
172
|
+
function markdownLinkDestinations(line) {
|
|
173
|
+
const destinations = [];
|
|
174
|
+
let searchFrom = 0;
|
|
175
|
+
while (searchFrom < line.length) {
|
|
176
|
+
const opener = line.indexOf("](", searchFrom);
|
|
177
|
+
if (opener < 0)
|
|
178
|
+
break;
|
|
179
|
+
const rawStart = line.lastIndexOf("[", opener);
|
|
180
|
+
let cursor = opener + 2;
|
|
181
|
+
while (/\s/.test(line[cursor] ?? ""))
|
|
182
|
+
cursor += 1;
|
|
183
|
+
const destinationStart = cursor;
|
|
184
|
+
let destination = "";
|
|
185
|
+
if (line[cursor] === "<") {
|
|
186
|
+
cursor += 1;
|
|
187
|
+
const valueStart = cursor;
|
|
188
|
+
while (cursor < line.length && line[cursor] !== ">")
|
|
189
|
+
cursor += 1;
|
|
190
|
+
if (line[cursor] === ">") {
|
|
191
|
+
destination = line.slice(valueStart, cursor);
|
|
192
|
+
cursor += 1;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
else {
|
|
196
|
+
let nestedParentheses = 0;
|
|
197
|
+
while (cursor < line.length) {
|
|
198
|
+
const character = line[cursor] ?? "";
|
|
199
|
+
if (character === "\\" && cursor + 1 < line.length) {
|
|
200
|
+
cursor += 2;
|
|
201
|
+
continue;
|
|
202
|
+
}
|
|
203
|
+
if (character === "(") {
|
|
204
|
+
nestedParentheses += 1;
|
|
205
|
+
}
|
|
206
|
+
else if (character === ")") {
|
|
207
|
+
if (nestedParentheses === 0)
|
|
208
|
+
break;
|
|
209
|
+
nestedParentheses -= 1;
|
|
210
|
+
}
|
|
211
|
+
else if (/\s/.test(character) && nestedParentheses === 0) {
|
|
212
|
+
break;
|
|
213
|
+
}
|
|
214
|
+
cursor += 1;
|
|
215
|
+
}
|
|
216
|
+
destination = line.slice(destinationStart, cursor);
|
|
217
|
+
}
|
|
218
|
+
let outerClose = cursor;
|
|
219
|
+
let titleParentheses = 0;
|
|
220
|
+
let quote;
|
|
221
|
+
while (outerClose < line.length) {
|
|
222
|
+
const character = line[outerClose] ?? "";
|
|
223
|
+
if (character === "\\") {
|
|
224
|
+
outerClose += 2;
|
|
225
|
+
continue;
|
|
226
|
+
}
|
|
227
|
+
if (quote) {
|
|
228
|
+
if (character === quote)
|
|
229
|
+
quote = undefined;
|
|
230
|
+
}
|
|
231
|
+
else if (character === '"' || character === "'") {
|
|
232
|
+
quote = character;
|
|
233
|
+
}
|
|
234
|
+
else if (character === "(") {
|
|
235
|
+
titleParentheses += 1;
|
|
236
|
+
}
|
|
237
|
+
else if (character === ")") {
|
|
238
|
+
if (titleParentheses === 0)
|
|
239
|
+
break;
|
|
240
|
+
titleParentheses -= 1;
|
|
241
|
+
}
|
|
242
|
+
outerClose += 1;
|
|
243
|
+
}
|
|
244
|
+
if (destination && outerClose < line.length) {
|
|
245
|
+
destinations.push({
|
|
246
|
+
raw: line.slice(rawStart >= 0 ? rawStart : opener, outerClose + 1),
|
|
247
|
+
value: destination,
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
searchFrom = Math.max(outerClose + 1, opener + 2);
|
|
251
|
+
}
|
|
252
|
+
return destinations;
|
|
253
|
+
}
|
|
254
|
+
function stripUriSuffix(value) {
|
|
255
|
+
const query = value.indexOf("?");
|
|
256
|
+
const fragment = value.indexOf("#");
|
|
257
|
+
const boundary = [query, fragment]
|
|
258
|
+
.filter((index) => index >= 0)
|
|
259
|
+
.sort((left, right) => left - right)[0];
|
|
260
|
+
return boundary === undefined ? value : value.slice(0, boundary);
|
|
261
|
+
}
|
|
262
|
+
function containsExactBasename(content, basename) {
|
|
263
|
+
const escaped = basename.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
264
|
+
return new RegExp(`(?:^|[\\s\`'"()\\[\\]{},;:])${escaped}(?=$|[\\s\`'"()\\[\\]{},;:?!]|\\.(?=\\s|$))`, "m").test(content);
|
|
265
|
+
}
|
|
266
|
+
function decodePath(value) {
|
|
267
|
+
try {
|
|
268
|
+
return decodeURIComponent(value);
|
|
269
|
+
}
|
|
270
|
+
catch {
|
|
271
|
+
return value;
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
function dedupeDependencies(dependencies) {
|
|
275
|
+
const seen = new Set();
|
|
276
|
+
return dependencies.filter((dependency) => {
|
|
277
|
+
const key = `${dependency.from}\0${dependency.kind}\0${dependency.to}\0${dependency.sourcePath}`;
|
|
278
|
+
if (seen.has(key))
|
|
279
|
+
return false;
|
|
280
|
+
seen.add(key);
|
|
281
|
+
return true;
|
|
282
|
+
});
|
|
283
|
+
}
|
|
284
|
+
//# sourceMappingURL=static-support.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"static-support.js","sourceRoot":"","sources":["../src/static-support.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/** A deterministic, model-neutral token estimate unit. */
|
|
2
|
+
export interface EstimatedTokenUnit {
|
|
3
|
+
value: string;
|
|
4
|
+
offset: number;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Estimate tokens without claiming compatibility with a model tokenizer.
|
|
8
|
+
*
|
|
9
|
+
* Latin-like words, code identifiers, URLs, and repository paths are lexical
|
|
10
|
+
* units. Consecutive Han, Hiragana, Katakana, and Hangul text is divided into
|
|
11
|
+
* two-code-point units so unspaced Japanese is neither one token nor one token
|
|
12
|
+
* per character. Other punctuation is grouped in runs of up to three code
|
|
13
|
+
* points. The algorithm is Unicode-aware, dependency-free, and deterministic,
|
|
14
|
+
* but is only suitable for stable repository thresholds and comparisons.
|
|
15
|
+
*/
|
|
16
|
+
export declare function estimateTokens(value: string): number;
|
|
17
|
+
/** Return the deterministic units used by estimateTokens. */
|
|
18
|
+
export declare function estimatedTokenUnits(value: string): EstimatedTokenUnit[];
|
|
19
|
+
/** Return Markdown after a complete leading YAML frontmatter block. */
|
|
20
|
+
export declare function markdownBody(value: string): string;
|
|
21
|
+
//# sourceMappingURL=token-estimator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token-estimator.d.ts","sourceRoot":"","sources":["../src/token-estimator.ts"],"names":[],"mappings":"AAAA,0DAA0D;AAC1D,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;AAOD;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEpD;AAED,6DAA6D;AAC7D,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,kBAAkB,EAAE,CAiEvE;AAED,uEAAuE;AACvE,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAOlD"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
const CJK_RUN = /[\p{Script=Han}\p{Script=Hiragana}\p{Script=Katakana}\p{Script=Hangul}]/u;
|
|
2
|
+
const WORD_RUN = /[\p{L}\p{N}_]/u;
|
|
3
|
+
const WORD_CONTINUATION = /[\p{L}\p{N}_./:+\-=]/u;
|
|
4
|
+
/**
|
|
5
|
+
* Estimate tokens without claiming compatibility with a model tokenizer.
|
|
6
|
+
*
|
|
7
|
+
* Latin-like words, code identifiers, URLs, and repository paths are lexical
|
|
8
|
+
* units. Consecutive Han, Hiragana, Katakana, and Hangul text is divided into
|
|
9
|
+
* two-code-point units so unspaced Japanese is neither one token nor one token
|
|
10
|
+
* per character. Other punctuation is grouped in runs of up to three code
|
|
11
|
+
* points. The algorithm is Unicode-aware, dependency-free, and deterministic,
|
|
12
|
+
* but is only suitable for stable repository thresholds and comparisons.
|
|
13
|
+
*/
|
|
14
|
+
export function estimateTokens(value) {
|
|
15
|
+
return estimatedTokenUnits(value).length;
|
|
16
|
+
}
|
|
17
|
+
/** Return the deterministic units used by estimateTokens. */
|
|
18
|
+
export function estimatedTokenUnits(value) {
|
|
19
|
+
const codePoints = [...value];
|
|
20
|
+
const offsets = [];
|
|
21
|
+
let utf16Offset = 0;
|
|
22
|
+
for (const codePoint of codePoints) {
|
|
23
|
+
offsets.push(utf16Offset);
|
|
24
|
+
utf16Offset += codePoint.length;
|
|
25
|
+
}
|
|
26
|
+
const units = [];
|
|
27
|
+
let index = 0;
|
|
28
|
+
while (index < codePoints.length) {
|
|
29
|
+
const current = codePoints[index] ?? "";
|
|
30
|
+
if (/\s/u.test(current)) {
|
|
31
|
+
index += 1;
|
|
32
|
+
continue;
|
|
33
|
+
}
|
|
34
|
+
if (CJK_RUN.test(current)) {
|
|
35
|
+
const start = index;
|
|
36
|
+
index += 1;
|
|
37
|
+
if (index < codePoints.length && CJK_RUN.test(codePoints[index] ?? "")) {
|
|
38
|
+
index += 1;
|
|
39
|
+
}
|
|
40
|
+
units.push({
|
|
41
|
+
value: codePoints.slice(start, index).join("").toLowerCase(),
|
|
42
|
+
offset: offsets[start] ?? 0,
|
|
43
|
+
});
|
|
44
|
+
continue;
|
|
45
|
+
}
|
|
46
|
+
if (WORD_RUN.test(current)) {
|
|
47
|
+
const start = index;
|
|
48
|
+
index += 1;
|
|
49
|
+
while (index < codePoints.length &&
|
|
50
|
+
WORD_CONTINUATION.test(codePoints[index] ?? "") &&
|
|
51
|
+
!CJK_RUN.test(codePoints[index] ?? "")) {
|
|
52
|
+
index += 1;
|
|
53
|
+
}
|
|
54
|
+
units.push({
|
|
55
|
+
value: codePoints.slice(start, index).join("").toLowerCase(),
|
|
56
|
+
offset: offsets[start] ?? 0,
|
|
57
|
+
});
|
|
58
|
+
continue;
|
|
59
|
+
}
|
|
60
|
+
const start = index;
|
|
61
|
+
index += 1;
|
|
62
|
+
while (index < codePoints.length &&
|
|
63
|
+
index - start < 3 &&
|
|
64
|
+
!/\s/u.test(codePoints[index] ?? "") &&
|
|
65
|
+
!WORD_RUN.test(codePoints[index] ?? "") &&
|
|
66
|
+
!CJK_RUN.test(codePoints[index] ?? "")) {
|
|
67
|
+
index += 1;
|
|
68
|
+
}
|
|
69
|
+
units.push({
|
|
70
|
+
value: codePoints.slice(start, index).join(""),
|
|
71
|
+
offset: offsets[start] ?? 0,
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
return units;
|
|
75
|
+
}
|
|
76
|
+
/** Return Markdown after a complete leading YAML frontmatter block. */
|
|
77
|
+
export function markdownBody(value) {
|
|
78
|
+
const lines = value.split(/\r?\n/);
|
|
79
|
+
if (lines[0]?.trim() !== "---")
|
|
80
|
+
return value;
|
|
81
|
+
const end = lines.findIndex((line, index) => index > 0 && line.trim() === "---");
|
|
82
|
+
return end < 0 ? value : lines.slice(end + 1).join("\n");
|
|
83
|
+
}
|
|
84
|
+
//# sourceMappingURL=token-estimator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token-estimator.js","sourceRoot":"","sources":["../src/token-estimator.ts"],"names":[],"mappings":"AAMA,MAAM,OAAO,GACX,0EAA0E,CAAC;AAC7E,MAAM,QAAQ,GAAG,gBAAgB,CAAC;AAClC,MAAM,iBAAiB,GAAG,uBAAuB,CAAC;AAElD;;;;;;;;;GASG;AACH,MAAM,UAAU,cAAc,CAAC,KAAa;IAC1C,OAAO,mBAAmB,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC;AAC3C,CAAC;AAED,6DAA6D;AAC7D,MAAM,UAAU,mBAAmB,CAAC,KAAa;IAC/C,MAAM,UAAU,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC;IAC9B,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,IAAI,WAAW,GAAG,CAAC,CAAC;IACpB,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;QACnC,OAAO,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QAC1B,WAAW,IAAI,SAAS,CAAC,MAAM,CAAC;IAClC,CAAC;IAED,MAAM,KAAK,GAAyB,EAAE,CAAC;IACvC,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,OAAO,KAAK,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC;QACjC,MAAM,OAAO,GAAG,UAAU,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;QACxC,IAAI,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;YACxB,KAAK,IAAI,CAAC,CAAC;YACX,SAAS;QACX,CAAC;QAED,IAAI,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;YAC1B,MAAM,KAAK,GAAG,KAAK,CAAC;YACpB,KAAK,IAAI,CAAC,CAAC;YACX,IAAI,KAAK,GAAG,UAAU,CAAC,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC;gBACvE,KAAK,IAAI,CAAC,CAAC;YACb,CAAC;YACD,KAAK,CAAC,IAAI,CAAC;gBACT,KAAK,EAAE,UAAU,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,WAAW,EAAE;gBAC5D,MAAM,EAAE,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC;aAC5B,CAAC,CAAC;YACH,SAAS;QACX,CAAC;QAED,IAAI,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;YAC3B,MAAM,KAAK,GAAG,KAAK,CAAC;YACpB,KAAK,IAAI,CAAC,CAAC;YACX,OACE,KAAK,GAAG,UAAU,CAAC,MAAM;gBACzB,iBAAiB,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;gBAC/C,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,EACtC,CAAC;gBACD,KAAK,IAAI,CAAC,CAAC;YACb,CAAC;YACD,KAAK,CAAC,IAAI,CAAC;gBACT,KAAK,EAAE,UAAU,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,WAAW,EAAE;gBAC5D,MAAM,EAAE,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC;aAC5B,CAAC,CAAC;YACH,SAAS;QACX,CAAC;QAED,MAAM,KAAK,GAAG,KAAK,CAAC;QACpB,KAAK,IAAI,CAAC,CAAC;QACX,OACE,KAAK,GAAG,UAAU,CAAC,MAAM;YACzB,KAAK,GAAG,KAAK,GAAG,CAAC;YACjB,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;YACpC,CAAC,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;YACvC,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,EACtC,CAAC;YACD,KAAK,IAAI,CAAC,CAAC;QACb,CAAC;QACD,KAAK,CAAC,IAAI,CAAC;YACT,KAAK,EAAE,UAAU,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC;YAC9C,MAAM,EAAE,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC;SAC5B,CAAC,CAAC;IACL,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,uEAAuE;AACvE,MAAM,UAAU,YAAY,CAAC,KAAa;IACxC,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IACnC,IAAI,KAAK,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,KAAK;QAAE,OAAO,KAAK,CAAC;IAC7C,MAAM,GAAG,GAAG,KAAK,CAAC,SAAS,CACzB,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,GAAG,CAAC,IAAI,IAAI,CAAC,IAAI,EAAE,KAAK,KAAK,CACpD,CAAC;IACF,OAAO,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC3D,CAAC"}
|
package/dist/trust-graph.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type Catalog } from "./model.js";
|
|
2
2
|
import type { SecurityPolicyAssetEvidence } from "./security-policy-inventory.js";
|
|
3
3
|
import type { Diagnostic, Evidence, Finding, RiskClass } from "./types.js";
|
|
4
|
-
export type TrustGraphSchemaVersion = "renma.trustGraph.
|
|
4
|
+
export type TrustGraphSchemaVersion = "renma.trustGraph.v2";
|
|
5
5
|
export type TrustGraphNodeType = "asset" | "owner" | "lifecycle_status" | "security_profile" | "effective_policy" | "diagnostic";
|
|
6
|
-
export type TrustGraphEdgeType = "owned_by" | "has_lifecycle_status" | "declares_dependency" | "references" | "selects_security_profile" | "inherits_policy" | "has_effective_policy" | "has_diagnostic";
|
|
6
|
+
export type TrustGraphEdgeType = "owned_by" | "has_lifecycle_status" | "declares_dependency" | "references" | "owns_local_resource" | "statically_references" | "inherits_owner" | "selects_security_profile" | "inherits_policy" | "has_effective_policy" | "has_diagnostic";
|
|
7
7
|
export type TrustGraphFindingSource = "finding" | "diagnostic";
|
|
8
8
|
export type TrustGraphFindingSeverity = Finding["severity"] | Diagnostic["severity"];
|
|
9
9
|
export interface TrustGraphSummary {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"trust-graph.d.ts","sourceRoot":"","sources":["../src/trust-graph.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"trust-graph.d.ts","sourceRoot":"","sources":["../src/trust-graph.ts"],"names":[],"mappings":"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"}
|
package/dist/trust-graph.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { createHash } from "node:crypto";
|
|
2
2
|
import { normalizeDependencyReference, resolveDependencyTarget, } from "./dependency-resolution.js";
|
|
3
|
+
import { effectiveAssetOwner, } from "./model.js";
|
|
3
4
|
const NODE_TYPES = [
|
|
4
5
|
"asset",
|
|
5
6
|
"owner",
|
|
@@ -13,6 +14,9 @@ const EDGE_TYPES = [
|
|
|
13
14
|
"has_lifecycle_status",
|
|
14
15
|
"declares_dependency",
|
|
15
16
|
"references",
|
|
17
|
+
"owns_local_resource",
|
|
18
|
+
"statically_references",
|
|
19
|
+
"inherits_owner",
|
|
16
20
|
"selects_security_profile",
|
|
17
21
|
"inherits_policy",
|
|
18
22
|
"has_effective_policy",
|
|
@@ -44,14 +48,27 @@ export function buildTrustGraph(input) {
|
|
|
44
48
|
]));
|
|
45
49
|
for (const asset of assets) {
|
|
46
50
|
addNode(nodes, assetNode(asset));
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
51
|
+
const owner = effectiveAssetOwner(asset);
|
|
52
|
+
if (owner) {
|
|
53
|
+
const ownerNodeId = ownerNode(owner).id;
|
|
54
|
+
addNode(nodes, ownerNode(owner));
|
|
55
|
+
const inheritedOwnerAsset = asset.ownership.source === "inherited" && asset.ownership.inheritedFrom
|
|
56
|
+
? assetsByPath.get(normalizeDependencyReference(asset.ownership.inheritedFrom.sourcePath))
|
|
57
|
+
: undefined;
|
|
50
58
|
addEdge(edges, {
|
|
51
59
|
from: assetNodeId(asset),
|
|
52
60
|
to: ownerNodeId,
|
|
53
61
|
type: "owned_by",
|
|
54
|
-
|
|
62
|
+
properties: {
|
|
63
|
+
ownershipSource: asset.ownership.source,
|
|
64
|
+
...(asset.ownership.source === "inherited" &&
|
|
65
|
+
asset.ownership.inheritedFrom
|
|
66
|
+
? { inheritedFrom: asset.ownership.inheritedFrom }
|
|
67
|
+
: {}),
|
|
68
|
+
},
|
|
69
|
+
evidence: inheritedOwnerAsset
|
|
70
|
+
? metadataEvidence(inheritedOwnerAsset, "owner")
|
|
71
|
+
: metadataEvidence(asset, "owner"),
|
|
55
72
|
});
|
|
56
73
|
}
|
|
57
74
|
if (asset.metadata.status) {
|
|
@@ -73,10 +90,19 @@ export function buildTrustGraph(input) {
|
|
|
73
90
|
addEdge(edges, {
|
|
74
91
|
from: assetNodeId(source),
|
|
75
92
|
to: assetNodeId(target),
|
|
76
|
-
type: dependency
|
|
93
|
+
type: trustEdgeTypeForDependency(dependency),
|
|
77
94
|
properties: {
|
|
78
95
|
dependencyKind: dependency.kind,
|
|
79
96
|
declaredTarget: dependency.to,
|
|
97
|
+
...(dependency.kind === "inherits_owner" ||
|
|
98
|
+
dependency.kind === "inherits_policy"
|
|
99
|
+
? {
|
|
100
|
+
inheritedFrom: {
|
|
101
|
+
id: target.id,
|
|
102
|
+
sourcePath: target.sourcePath,
|
|
103
|
+
},
|
|
104
|
+
}
|
|
105
|
+
: {}),
|
|
80
106
|
},
|
|
81
107
|
evidence: dependency.evidence ? [dependency.evidence] : [],
|
|
82
108
|
});
|
|
@@ -85,7 +111,18 @@ export function buildTrustGraph(input) {
|
|
|
85
111
|
const asset = assetsByPath.get(normalizeDependencyReference(policy.path));
|
|
86
112
|
if (!asset)
|
|
87
113
|
continue;
|
|
88
|
-
|
|
114
|
+
const inheritedAsset = policy.inheritedFrom
|
|
115
|
+
? assetsByPath.get(normalizeDependencyReference(policy.inheritedFrom.sourcePath))
|
|
116
|
+
: undefined;
|
|
117
|
+
addPolicyEvidence(nodes, edges, asset, inheritedAsset
|
|
118
|
+
? {
|
|
119
|
+
...policy,
|
|
120
|
+
inheritedFrom: {
|
|
121
|
+
id: inheritedAsset.id,
|
|
122
|
+
sourcePath: inheritedAsset.sourcePath,
|
|
123
|
+
},
|
|
124
|
+
}
|
|
125
|
+
: policy);
|
|
89
126
|
}
|
|
90
127
|
const findings = stableTrustGraphFindings((input.findings ?? []).map(findingToTrustGraphFinding), (input.diagnostics ?? []).map(diagnosticToTrustGraphFinding));
|
|
91
128
|
for (const finding of findings) {
|
|
@@ -105,13 +142,25 @@ export function buildTrustGraph(input) {
|
|
|
105
142
|
}
|
|
106
143
|
const sortedNodes = [...nodes.values()].sort(compareNodes);
|
|
107
144
|
const sortedEdges = [...edges.values()].sort(compareEdges);
|
|
108
|
-
|
|
109
|
-
schemaVersion: "renma.trustGraph.
|
|
145
|
+
const graph = {
|
|
146
|
+
schemaVersion: "renma.trustGraph.v2",
|
|
110
147
|
summary: summarizeTrustGraph(assets.length, sortedNodes, sortedEdges, findings),
|
|
111
148
|
nodes: sortedNodes,
|
|
112
149
|
edges: sortedEdges,
|
|
113
150
|
findings,
|
|
114
151
|
};
|
|
152
|
+
return graph;
|
|
153
|
+
}
|
|
154
|
+
function trustEdgeTypeForDependency(dependency) {
|
|
155
|
+
if (dependency.kind === "references")
|
|
156
|
+
return "references";
|
|
157
|
+
if (dependency.kind === "owns_local_resource" ||
|
|
158
|
+
dependency.kind === "statically_references" ||
|
|
159
|
+
dependency.kind === "inherits_owner" ||
|
|
160
|
+
dependency.kind === "inherits_policy") {
|
|
161
|
+
return dependency.kind;
|
|
162
|
+
}
|
|
163
|
+
return "declares_dependency";
|
|
115
164
|
}
|
|
116
165
|
function addPolicyEvidence(nodes, edges, asset, policy) {
|
|
117
166
|
if (policy.selectedSecurityProfile) {
|
|
@@ -130,6 +179,11 @@ function addPolicyEvidence(nodes, edges, asset, policy) {
|
|
|
130
179
|
: [],
|
|
131
180
|
});
|
|
132
181
|
}
|
|
182
|
+
if (!policy.hasEffectivePolicy)
|
|
183
|
+
return;
|
|
184
|
+
if (policy.policySources.length === 0) {
|
|
185
|
+
throw new Error(`Effective security policy for ${policy.path} has no provenance source.`);
|
|
186
|
+
}
|
|
133
187
|
for (let index = 1; index < policy.profileChain.length; index += 1) {
|
|
134
188
|
const childProfile = policy.profileChain[index];
|
|
135
189
|
const parentProfile = policy.profileChain[index - 1];
|
|
@@ -153,6 +207,8 @@ function addPolicyEvidence(nodes, edges, asset, policy) {
|
|
|
153
207
|
type: "has_effective_policy",
|
|
154
208
|
properties: {
|
|
155
209
|
hasLocalPolicyMetadata: policy.hasLocalPolicyMetadata,
|
|
210
|
+
policySources: policy.policySources,
|
|
211
|
+
...(policy.inheritedFrom ? { inheritedFrom: policy.inheritedFrom } : {}),
|
|
156
212
|
},
|
|
157
213
|
evidence: policy.evidence.policyFields,
|
|
158
214
|
});
|
|
@@ -167,8 +223,11 @@ function assetNode(asset) {
|
|
|
167
223
|
kind: asset.kind,
|
|
168
224
|
sourcePath: asset.sourcePath,
|
|
169
225
|
contentHash: asset.contentHash,
|
|
226
|
+
sizeBytes: asset.sizeBytes,
|
|
227
|
+
contentClassification: asset.contentClassification,
|
|
228
|
+
markdownParserEligible: asset.markdownParserEligible,
|
|
170
229
|
tags: asset.metadata.tags,
|
|
171
|
-
|
|
230
|
+
ownership: asset.ownership,
|
|
172
231
|
...(asset.metadata.status ? { status: asset.metadata.status } : {}),
|
|
173
232
|
},
|
|
174
233
|
evidence: [
|
|
@@ -241,7 +300,7 @@ function diagnosticNode(finding) {
|
|
|
241
300
|
};
|
|
242
301
|
}
|
|
243
302
|
function assetNodeId(asset) {
|
|
244
|
-
// Trust Graph
|
|
303
|
+
// Trust Graph keeps asset IDs logical. Duplicate-id diagnostics preserve
|
|
245
304
|
// per-source evidence when multiple catalog assets share the same id.
|
|
246
305
|
return `asset:${asset.id}`;
|
|
247
306
|
}
|