guardlink 1.0.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 +30 -0
- package/LICENSE +21 -0
- package/README.md +344 -0
- package/dist/agents/config.d.ts +46 -0
- package/dist/agents/config.d.ts.map +1 -0
- package/dist/agents/config.js +189 -0
- package/dist/agents/config.js.map +1 -0
- package/dist/agents/index.d.ts +24 -0
- package/dist/agents/index.d.ts.map +1 -0
- package/dist/agents/index.js +42 -0
- package/dist/agents/index.js.map +1 -0
- package/dist/agents/launcher.d.ts +54 -0
- package/dist/agents/launcher.d.ts.map +1 -0
- package/dist/agents/launcher.js +152 -0
- package/dist/agents/launcher.js.map +1 -0
- package/dist/agents/prompts.d.ts +14 -0
- package/dist/agents/prompts.d.ts.map +1 -0
- package/dist/agents/prompts.js +120 -0
- package/dist/agents/prompts.js.map +1 -0
- package/dist/analyze/index.d.ts +80 -0
- package/dist/analyze/index.d.ts.map +1 -0
- package/dist/analyze/index.js +306 -0
- package/dist/analyze/index.js.map +1 -0
- package/dist/analyze/llm.d.ts +52 -0
- package/dist/analyze/llm.d.ts.map +1 -0
- package/dist/analyze/llm.js +295 -0
- package/dist/analyze/llm.js.map +1 -0
- package/dist/analyze/prompts.d.ts +14 -0
- package/dist/analyze/prompts.d.ts.map +1 -0
- package/dist/analyze/prompts.js +205 -0
- package/dist/analyze/prompts.js.map +1 -0
- package/dist/analyzer/index.d.ts +5 -0
- package/dist/analyzer/index.d.ts.map +1 -0
- package/dist/analyzer/index.js +5 -0
- package/dist/analyzer/index.js.map +1 -0
- package/dist/analyzer/sarif.d.ts +84 -0
- package/dist/analyzer/sarif.d.ts.map +1 -0
- package/dist/analyzer/sarif.js +149 -0
- package/dist/analyzer/sarif.js.map +1 -0
- package/dist/cli/index.d.ts +25 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +821 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/dashboard/data.d.ts +52 -0
- package/dist/dashboard/data.d.ts.map +1 -0
- package/dist/dashboard/data.js +93 -0
- package/dist/dashboard/data.js.map +1 -0
- package/dist/dashboard/diagrams.d.ts +25 -0
- package/dist/dashboard/diagrams.d.ts.map +1 -0
- package/dist/dashboard/diagrams.js +243 -0
- package/dist/dashboard/diagrams.js.map +1 -0
- package/dist/dashboard/generate.d.ts +17 -0
- package/dist/dashboard/generate.d.ts.map +1 -0
- package/dist/dashboard/generate.js +1258 -0
- package/dist/dashboard/generate.js.map +1 -0
- package/dist/dashboard/index.d.ts +7 -0
- package/dist/dashboard/index.d.ts.map +1 -0
- package/dist/dashboard/index.js +7 -0
- package/dist/dashboard/index.js.map +1 -0
- package/dist/diff/engine.d.ts +51 -0
- package/dist/diff/engine.d.ts.map +1 -0
- package/dist/diff/engine.js +153 -0
- package/dist/diff/engine.js.map +1 -0
- package/dist/diff/format.d.ts +10 -0
- package/dist/diff/format.d.ts.map +1 -0
- package/dist/diff/format.js +111 -0
- package/dist/diff/format.js.map +1 -0
- package/dist/diff/git.d.ts +24 -0
- package/dist/diff/git.d.ts.map +1 -0
- package/dist/diff/git.js +85 -0
- package/dist/diff/git.js.map +1 -0
- package/dist/diff/index.d.ts +7 -0
- package/dist/diff/index.d.ts.map +1 -0
- package/dist/diff/index.js +7 -0
- package/dist/diff/index.js.map +1 -0
- package/dist/index.d.ts +20 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +17 -0
- package/dist/index.js.map +1 -0
- package/dist/init/detect.d.ts +42 -0
- package/dist/init/detect.d.ts.map +1 -0
- package/dist/init/detect.js +185 -0
- package/dist/init/detect.js.map +1 -0
- package/dist/init/index.d.ts +39 -0
- package/dist/init/index.d.ts.map +1 -0
- package/dist/init/index.js +228 -0
- package/dist/init/index.js.map +1 -0
- package/dist/init/picker.d.ts +32 -0
- package/dist/init/picker.d.ts.map +1 -0
- package/dist/init/picker.js +105 -0
- package/dist/init/picker.js.map +1 -0
- package/dist/init/templates.d.ts +25 -0
- package/dist/init/templates.d.ts.map +1 -0
- package/dist/init/templates.js +263 -0
- package/dist/init/templates.js.map +1 -0
- package/dist/mcp/index.d.ts +12 -0
- package/dist/mcp/index.d.ts.map +1 -0
- package/dist/mcp/index.js +18 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/mcp/lookup.d.ts +27 -0
- package/dist/mcp/lookup.d.ts.map +1 -0
- package/dist/mcp/lookup.js +282 -0
- package/dist/mcp/lookup.js.map +1 -0
- package/dist/mcp/server.d.ts +41 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +388 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp/suggest.d.ts +35 -0
- package/dist/mcp/suggest.d.ts.map +1 -0
- package/dist/mcp/suggest.js +268 -0
- package/dist/mcp/suggest.js.map +1 -0
- package/dist/parser/comment-strip.d.ts +15 -0
- package/dist/parser/comment-strip.d.ts.map +1 -0
- package/dist/parser/comment-strip.js +76 -0
- package/dist/parser/comment-strip.js.map +1 -0
- package/dist/parser/index.d.ts +10 -0
- package/dist/parser/index.d.ts.map +1 -0
- package/dist/parser/index.js +9 -0
- package/dist/parser/index.js.map +1 -0
- package/dist/parser/normalize.d.ts +22 -0
- package/dist/parser/normalize.d.ts.map +1 -0
- package/dist/parser/normalize.js +42 -0
- package/dist/parser/normalize.js.map +1 -0
- package/dist/parser/parse-file.d.ts +18 -0
- package/dist/parser/parse-file.d.ts.map +1 -0
- package/dist/parser/parse-file.js +68 -0
- package/dist/parser/parse-file.js.map +1 -0
- package/dist/parser/parse-line.d.ts +21 -0
- package/dist/parser/parse-line.d.ts.map +1 -0
- package/dist/parser/parse-line.js +230 -0
- package/dist/parser/parse-line.js.map +1 -0
- package/dist/parser/parse-project.d.ts +31 -0
- package/dist/parser/parse-project.d.ts.map +1 -0
- package/dist/parser/parse-project.js +281 -0
- package/dist/parser/parse-project.js.map +1 -0
- package/dist/report/index.d.ts +6 -0
- package/dist/report/index.d.ts.map +1 -0
- package/dist/report/index.js +6 -0
- package/dist/report/index.js.map +1 -0
- package/dist/report/mermaid.d.ts +15 -0
- package/dist/report/mermaid.d.ts.map +1 -0
- package/dist/report/mermaid.js +260 -0
- package/dist/report/mermaid.js.map +1 -0
- package/dist/report/report.d.ts +16 -0
- package/dist/report/report.d.ts.map +1 -0
- package/dist/report/report.js +211 -0
- package/dist/report/report.js.map +1 -0
- package/dist/tui/commands.d.ts +42 -0
- package/dist/tui/commands.d.ts.map +1 -0
- package/dist/tui/commands.js +1216 -0
- package/dist/tui/commands.js.map +1 -0
- package/dist/tui/config.d.ts +27 -0
- package/dist/tui/config.d.ts.map +1 -0
- package/dist/tui/config.js +27 -0
- package/dist/tui/config.js.map +1 -0
- package/dist/tui/format.d.ts +63 -0
- package/dist/tui/format.d.ts.map +1 -0
- package/dist/tui/format.js +253 -0
- package/dist/tui/format.js.map +1 -0
- package/dist/tui/index.d.ts +18 -0
- package/dist/tui/index.d.ts.map +1 -0
- package/dist/tui/index.js +470 -0
- package/dist/tui/index.js.map +1 -0
- package/dist/tui/input.d.ts +63 -0
- package/dist/tui/input.d.ts.map +1 -0
- package/dist/tui/input.js +454 -0
- package/dist/tui/input.js.map +1 -0
- package/dist/types/index.d.ts +254 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +6 -0
- package/dist/types/index.js.map +1 -0
- package/package.json +97 -0
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GuardLink — Line-level annotation parser.
|
|
3
|
+
* Parses a single comment line into a typed Annotation.
|
|
4
|
+
*
|
|
5
|
+
* @exposes #parser to #redos [medium] cwe:CWE-1333 -- "Complex regex patterns run against untrusted annotation content"
|
|
6
|
+
* @mitigates #parser against #redos using #regex-anchoring -- "All patterns use ^ anchor and defined character classes"
|
|
7
|
+
* @comment -- "PATTERNS object contains all annotation regex; patterns are pre-compiled for performance"
|
|
8
|
+
*/
|
|
9
|
+
import { normalizeName, resolveSeverity, unescapeDescription } from './normalize.js';
|
|
10
|
+
// ─── Shared regex fragments ──────────────────────────────────────────
|
|
11
|
+
const COMPONENT = String.raw `[A-Za-z_]\w*(?:\.[A-Za-z_]\w*)*`;
|
|
12
|
+
const ASSET_REF = String.raw `(?:#[a-zA-Z0-9_-]+|[A-Za-z_]\w*(?:\.[A-Za-z_]\w*)*)`; // #id or Dotted.Path
|
|
13
|
+
const NAME = String.raw `[A-Za-z]\w*(?:[_\- ][A-Za-z]\w*)*`;
|
|
14
|
+
const ID_DEF = String.raw `\(#([a-zA-Z0-9_-]+)\)`;
|
|
15
|
+
const ID_REF = String.raw `#([a-zA-Z0-9_-]+)`;
|
|
16
|
+
const THREAT_REF = String.raw `(?:#[a-zA-Z0-9_-]+|[A-Za-z]\w*(?:[_\- ][A-Za-z]\w*)*)`;
|
|
17
|
+
const SEVERITY = String.raw `\[(P[0-3]|critical|high|medium|low)\]`;
|
|
18
|
+
const EXT_REF = String.raw `([a-zA-Z]+:[A-Za-z0-9_:.\-]+)`;
|
|
19
|
+
const DESC = String.raw `--\s*"((?:[^"\\]|\\.)*)"`;
|
|
20
|
+
// Capture external refs (0 or more, space-separated)
|
|
21
|
+
const EXT_REFS_OPT = String.raw `((?:\s+[a-zA-Z]+:[A-Za-z0-9_:.\-]+)*)`;
|
|
22
|
+
// ─── Verb-specific patterns ──────────────────────────────────────────
|
|
23
|
+
const PATTERNS = {
|
|
24
|
+
// Definition — asset path must be dotted COMPONENT
|
|
25
|
+
asset: new RegExp(String.raw `^@asset\s+(${COMPONENT})(?:\s+${ID_DEF})?(?:\s+${DESC})?$`),
|
|
26
|
+
threat: new RegExp(String.raw `^@threat\s+(${NAME})(?:\s+${ID_DEF})?(?:\s+${SEVERITY})?${EXT_REFS_OPT}(?:\s+${DESC})?$`),
|
|
27
|
+
control: new RegExp(String.raw `^@control\s+(${NAME})(?:\s+${ID_DEF})?(?:\s+${DESC})?$`),
|
|
28
|
+
// Relationship — asset positions accept #id OR Dotted.Path via ASSET_REF
|
|
29
|
+
mitigates: new RegExp(String.raw `^@mitigates\s+(${ASSET_REF})\s+against\s+(${THREAT_REF})(?:\s+using\s+(${THREAT_REF}))?(?:\s+${DESC})?$`),
|
|
30
|
+
mitigates_v1: new RegExp(String.raw `^@mitigates\s+(${ASSET_REF})\s+against\s+(${THREAT_REF})(?:\s+with\s+(${THREAT_REF}))?(?:\s+${DESC})?$`),
|
|
31
|
+
exposes: new RegExp(String.raw `^@exposes\s+(${ASSET_REF})\s+to\s+(${THREAT_REF})(?:\s+${SEVERITY})?${EXT_REFS_OPT}(?:\s+${DESC})?$`),
|
|
32
|
+
accepts: new RegExp(String.raw `^@accepts\s+(${THREAT_REF})\s+on\s+(${ASSET_REF})(?:\s+${DESC})?$`),
|
|
33
|
+
accepts_v1: new RegExp(String.raw `^@accepts\s+(${THREAT_REF})\s+to\s+(${ASSET_REF})(?:\s+${DESC})?$`),
|
|
34
|
+
transfers: new RegExp(String.raw `^@transfers\s+(${THREAT_REF})\s+from\s+(${ASSET_REF})\s+to\s+(${ASSET_REF})(?:\s+${DESC})?$`),
|
|
35
|
+
flows: new RegExp(String.raw `^@flows\s+(${ASSET_REF})\s+->\s+(${ASSET_REF})(?:\s+via\s+(.+?))?(?:\s+${DESC})?$`),
|
|
36
|
+
boundary: new RegExp(String.raw `^@boundary\s+(?:between\s+)?(${ASSET_REF})\s+and\s+(${ASSET_REF})(?:\s+${ID_DEF})?(?:\s+${DESC})?$`),
|
|
37
|
+
boundary_pipe: new RegExp(String.raw `^@boundary\s+(${ASSET_REF})\s*\|\s*(${ASSET_REF})(?:\s+${ID_DEF})?(?:\s+${DESC})?$`),
|
|
38
|
+
connects_v1: new RegExp(String.raw `^@connects\s+(${ASSET_REF})\s+to\s+(${ASSET_REF})(?:\s+${DESC})?$`),
|
|
39
|
+
// Lifecycle — asset positions accept #id OR Dotted.Path
|
|
40
|
+
validates: new RegExp(String.raw `^@validates\s+(${THREAT_REF})\s+for\s+(${ASSET_REF})(?:\s+${DESC})?$`),
|
|
41
|
+
audit: new RegExp(String.raw `^@audit\s+(${ASSET_REF})(?:\s+${DESC})?$`),
|
|
42
|
+
review_v1: new RegExp(String.raw `^@review\s+(${ASSET_REF})(?:\s+${DESC})?$`),
|
|
43
|
+
owns: new RegExp(String.raw `^@owns\s+([a-zA-Z0-9_-]+)\s+for\s+(${ASSET_REF})(?:\s+${DESC})?$`),
|
|
44
|
+
handles: new RegExp(String.raw `^@handles\s+(pii|phi|financial|secrets|internal|public)\s+on\s+(${ASSET_REF})(?:\s+${DESC})?$`, 'i'),
|
|
45
|
+
assumes: new RegExp(String.raw `^@assumes\s+(${ASSET_REF})(?:\s+${DESC})?$`),
|
|
46
|
+
// Comment — developer note, description only
|
|
47
|
+
comment: new RegExp(String.raw `^@comment(?:\s+${DESC})?$`),
|
|
48
|
+
// Special
|
|
49
|
+
shield: new RegExp(String.raw `^@shield(?:\s+${DESC})?$`),
|
|
50
|
+
shield_begin: new RegExp(String.raw `^@shield:begin(?:\s+${DESC})?$`),
|
|
51
|
+
shield_end: /^@shield:end$/,
|
|
52
|
+
};
|
|
53
|
+
// ─── External ref extractor ──────────────────────────────────────────
|
|
54
|
+
function extractExternalRefs(raw) {
|
|
55
|
+
if (!raw || !raw.trim())
|
|
56
|
+
return [];
|
|
57
|
+
return raw.trim().split(/\s+/).filter(r => /^[a-zA-Z]+:[A-Za-z0-9_:.\-]+$/.test(r));
|
|
58
|
+
}
|
|
59
|
+
// ─── Ref resolver: #id or Name → string ──────────────────────────────
|
|
60
|
+
function resolveRef(ref) {
|
|
61
|
+
return ref.startsWith('#') ? ref : ref;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Parse a single annotation line (after comment prefix has been stripped).
|
|
65
|
+
* Returns the typed annotation, a diagnostic if parsing failed, or null if
|
|
66
|
+
* the line is not an annotation.
|
|
67
|
+
*/
|
|
68
|
+
export function parseLine(text, location) {
|
|
69
|
+
const trimmed = text.trim();
|
|
70
|
+
// Not an annotation
|
|
71
|
+
if (!trimmed.startsWith('@')) {
|
|
72
|
+
// Check for continuation line (-- "...")
|
|
73
|
+
const contMatch = trimmed.match(new RegExp(String.raw `^${DESC}$`));
|
|
74
|
+
if (contMatch) {
|
|
75
|
+
return { annotation: null, diagnostic: null, isContinuation: true };
|
|
76
|
+
}
|
|
77
|
+
return { annotation: null, diagnostic: null, isContinuation: false };
|
|
78
|
+
}
|
|
79
|
+
const base = { location, raw: trimmed };
|
|
80
|
+
let m;
|
|
81
|
+
// ── @asset ──
|
|
82
|
+
if ((m = trimmed.match(PATTERNS.asset))) {
|
|
83
|
+
return ok({ ...base, verb: 'asset', path: m[1], id: m[2], description: desc(m[3]) });
|
|
84
|
+
}
|
|
85
|
+
// ── @threat ──
|
|
86
|
+
if ((m = trimmed.match(PATTERNS.threat))) {
|
|
87
|
+
const name = m[1];
|
|
88
|
+
return ok({
|
|
89
|
+
...base, verb: 'threat', name, canonical_name: normalizeName(name),
|
|
90
|
+
id: m[2], severity: m[3] ? resolveSeverity(m[3]) : undefined,
|
|
91
|
+
external_refs: extractExternalRefs(m[4]), description: desc(m[5]),
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
// ── @control ──
|
|
95
|
+
if ((m = trimmed.match(PATTERNS.control))) {
|
|
96
|
+
const name = m[1];
|
|
97
|
+
return ok({
|
|
98
|
+
...base, verb: 'control', name, canonical_name: normalizeName(name),
|
|
99
|
+
id: m[2], description: desc(m[3]),
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
// ── @mitigates ──
|
|
103
|
+
if ((m = trimmed.match(PATTERNS.mitigates)) || (m = trimmed.match(PATTERNS.mitigates_v1))) {
|
|
104
|
+
return ok({
|
|
105
|
+
...base, verb: 'mitigates', asset: m[1],
|
|
106
|
+
threat: resolveRef(m[2]), control: m[3] ? resolveRef(m[3]) : undefined,
|
|
107
|
+
description: desc(m[4]),
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
// ── @exposes ──
|
|
111
|
+
if ((m = trimmed.match(PATTERNS.exposes))) {
|
|
112
|
+
return ok({
|
|
113
|
+
...base, verb: 'exposes', asset: m[1], threat: resolveRef(m[2]),
|
|
114
|
+
severity: m[3] ? resolveSeverity(m[3]) : undefined,
|
|
115
|
+
external_refs: extractExternalRefs(m[4]), description: desc(m[5]),
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
// ── @accepts ──
|
|
119
|
+
if ((m = trimmed.match(PATTERNS.accepts)) || (m = trimmed.match(PATTERNS.accepts_v1))) {
|
|
120
|
+
return ok({ ...base, verb: 'accepts', threat: resolveRef(m[1]), asset: m[2], description: desc(m[3]) });
|
|
121
|
+
}
|
|
122
|
+
// ── @transfers ──
|
|
123
|
+
if ((m = trimmed.match(PATTERNS.transfers))) {
|
|
124
|
+
return ok({
|
|
125
|
+
...base, verb: 'transfers', threat: resolveRef(m[1]),
|
|
126
|
+
source: m[2], target: m[3], description: desc(m[4]),
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
// ── @flows ──
|
|
130
|
+
if ((m = trimmed.match(PATTERNS.flows))) {
|
|
131
|
+
return ok({
|
|
132
|
+
...base, verb: 'flows', source: m[1], target: m[2],
|
|
133
|
+
mechanism: m[3]?.trim(), description: desc(m[4]),
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
// ── @boundary ──
|
|
137
|
+
if ((m = trimmed.match(PATTERNS.boundary))) {
|
|
138
|
+
return ok({
|
|
139
|
+
...base, verb: 'boundary', asset_a: m[1], asset_b: m[2],
|
|
140
|
+
id: m[3], description: desc(m[4]),
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
// ── @boundary pipe shorthand: @boundary A | B ──
|
|
144
|
+
if ((m = trimmed.match(PATTERNS.boundary_pipe))) {
|
|
145
|
+
return ok({
|
|
146
|
+
...base, verb: 'boundary', asset_a: m[1], asset_b: m[2],
|
|
147
|
+
id: m[3], description: desc(m[4]),
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
// ── @connects (v1 → flows) ──
|
|
151
|
+
if ((m = trimmed.match(PATTERNS.connects_v1))) {
|
|
152
|
+
return ok({
|
|
153
|
+
...base, verb: 'flows', source: m[1], target: m[2], description: desc(m[3]),
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
// ── @validates ──
|
|
157
|
+
if ((m = trimmed.match(PATTERNS.validates))) {
|
|
158
|
+
return ok({ ...base, verb: 'validates', control: resolveRef(m[1]), asset: m[2], description: desc(m[3]) });
|
|
159
|
+
}
|
|
160
|
+
// ── @audit / @review (v1) ──
|
|
161
|
+
if ((m = trimmed.match(PATTERNS.audit)) || (m = trimmed.match(PATTERNS.review_v1))) {
|
|
162
|
+
return ok({ ...base, verb: 'audit', asset: m[1], description: desc(m[2]) });
|
|
163
|
+
}
|
|
164
|
+
// ── @owns ──
|
|
165
|
+
if ((m = trimmed.match(PATTERNS.owns))) {
|
|
166
|
+
return ok({ ...base, verb: 'owns', owner: m[1], asset: m[2], description: desc(m[3]) });
|
|
167
|
+
}
|
|
168
|
+
// ── @handles ──
|
|
169
|
+
if ((m = trimmed.match(PATTERNS.handles))) {
|
|
170
|
+
return ok({
|
|
171
|
+
...base, verb: 'handles',
|
|
172
|
+
classification: m[1].toLowerCase(),
|
|
173
|
+
asset: m[2], description: desc(m[3]),
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
// ── @assumes ──
|
|
177
|
+
if ((m = trimmed.match(PATTERNS.assumes))) {
|
|
178
|
+
return ok({ ...base, verb: 'assumes', asset: m[1], description: desc(m[2]) });
|
|
179
|
+
}
|
|
180
|
+
// ── @comment ──
|
|
181
|
+
if ((m = trimmed.match(PATTERNS.comment))) {
|
|
182
|
+
return ok({ ...base, verb: 'comment', description: desc(m[1]) });
|
|
183
|
+
}
|
|
184
|
+
// ── @shield ──
|
|
185
|
+
if ((m = trimmed.match(PATTERNS.shield_begin))) {
|
|
186
|
+
return ok({ ...base, verb: 'shield:begin', description: desc(m[1]) });
|
|
187
|
+
}
|
|
188
|
+
if (trimmed.match(PATTERNS.shield_end)) {
|
|
189
|
+
return ok({ ...base, verb: 'shield:end' });
|
|
190
|
+
}
|
|
191
|
+
if ((m = trimmed.match(PATTERNS.shield))) {
|
|
192
|
+
return ok({ ...base, verb: 'shield', description: desc(m[1]) });
|
|
193
|
+
}
|
|
194
|
+
// Starts with @ but didn't match — likely a malformed annotation
|
|
195
|
+
const verbMatch = trimmed.match(/^@(\S+)/);
|
|
196
|
+
if (verbMatch) {
|
|
197
|
+
const knownVerbs = new Set([
|
|
198
|
+
'asset', 'threat', 'control', 'mitigates', 'exposes', 'accepts',
|
|
199
|
+
'transfers', 'flows', 'boundary', 'validates', 'audit', 'owns',
|
|
200
|
+
'handles', 'assumes', 'comment', 'shield', 'shield:begin', 'shield:end',
|
|
201
|
+
// v1 compat
|
|
202
|
+
'review', 'connects',
|
|
203
|
+
]);
|
|
204
|
+
if (knownVerbs.has(verbMatch[1])) {
|
|
205
|
+
return {
|
|
206
|
+
annotation: null,
|
|
207
|
+
diagnostic: {
|
|
208
|
+
level: 'error',
|
|
209
|
+
message: `Malformed @${verbMatch[1]} annotation: could not parse arguments`,
|
|
210
|
+
file: location.file,
|
|
211
|
+
line: location.line,
|
|
212
|
+
raw: trimmed,
|
|
213
|
+
},
|
|
214
|
+
isContinuation: false,
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
// Not a GuardLink annotation (could be @param, @returns, etc.)
|
|
219
|
+
return { annotation: null, diagnostic: null, isContinuation: false };
|
|
220
|
+
}
|
|
221
|
+
// ─── Helpers ─────────────────────────────────────────────────────────
|
|
222
|
+
function ok(annotation) {
|
|
223
|
+
return { annotation, diagnostic: null, isContinuation: false };
|
|
224
|
+
}
|
|
225
|
+
function desc(raw) {
|
|
226
|
+
if (!raw)
|
|
227
|
+
return undefined;
|
|
228
|
+
return unescapeDescription(raw);
|
|
229
|
+
}
|
|
230
|
+
//# sourceMappingURL=parse-line.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parse-line.js","sourceRoot":"","sources":["../../src/parser/parse-line.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GuardLink — Project-level parser.
|
|
3
|
+
* Walks a directory, parses all source files, and assembles a ThreatModel.
|
|
4
|
+
*
|
|
5
|
+
* @exposes #parser to #path-traversal [high] cwe:CWE-22 -- "Accepts user-provided root directory for file scanning"
|
|
6
|
+
* @exposes #parser to #dos [medium] cwe:CWE-400 -- "Iterates all files in directory tree, may exhaust memory on large repos"
|
|
7
|
+
* @mitigates #parser against #path-traversal using #glob-filtering -- "fast-glob with explicit exclude patterns prevents access outside project"
|
|
8
|
+
* @mitigates #parser against #dos using #glob-filtering -- "Default excludes (node_modules, dist, .git) limit scope"
|
|
9
|
+
* @flows #cli -> #parser via parseProject -- "CLI passes user-specified root directory to parser"
|
|
10
|
+
* @flows #mcp -> #parser via parseProject -- "MCP server passes root param from AI agents"
|
|
11
|
+
* @handles internal on #parser -- "Processes source files to extract security annotation metadata"
|
|
12
|
+
*/
|
|
13
|
+
import type { ThreatModel, ParseDiagnostic } from '../types/index.js';
|
|
14
|
+
export interface ParseProjectOptions {
|
|
15
|
+
/** Root directory to scan */
|
|
16
|
+
root: string;
|
|
17
|
+
/** Glob patterns to include (default: common source files) */
|
|
18
|
+
include?: string[];
|
|
19
|
+
/** Glob patterns to exclude (default: node_modules, dist, .git) */
|
|
20
|
+
exclude?: string[];
|
|
21
|
+
/** Project name for the ThreatModel */
|
|
22
|
+
project?: string;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Parse an entire project directory and return a ThreatModel.
|
|
26
|
+
*/
|
|
27
|
+
export declare function parseProject(options: ParseProjectOptions): Promise<{
|
|
28
|
+
model: ThreatModel;
|
|
29
|
+
diagnostics: ParseDiagnostic[];
|
|
30
|
+
}>;
|
|
31
|
+
//# sourceMappingURL=parse-project.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parse-project.d.ts","sourceRoot":"","sources":["../../src/parser/parse-project.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAIH,OAAO,KAAK,EACE,WAAW,EAAe,eAAe,EAQtD,MAAM,mBAAmB,CAAC;AAG3B,MAAM,WAAW,mBAAmB;IAClC,6BAA6B;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,8DAA8D;IAC9D,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,mEAAmE;IACnE,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,uCAAuC;IACvC,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAuBD;;GAEG;AACH,wBAAsB,YAAY,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC;IACxE,KAAK,EAAE,WAAW,CAAC;IACnB,WAAW,EAAE,eAAe,EAAE,CAAC;CAChC,CAAC,CAwDD"}
|
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GuardLink — Project-level parser.
|
|
3
|
+
* Walks a directory, parses all source files, and assembles a ThreatModel.
|
|
4
|
+
*
|
|
5
|
+
* @exposes #parser to #path-traversal [high] cwe:CWE-22 -- "Accepts user-provided root directory for file scanning"
|
|
6
|
+
* @exposes #parser to #dos [medium] cwe:CWE-400 -- "Iterates all files in directory tree, may exhaust memory on large repos"
|
|
7
|
+
* @mitigates #parser against #path-traversal using #glob-filtering -- "fast-glob with explicit exclude patterns prevents access outside project"
|
|
8
|
+
* @mitigates #parser against #dos using #glob-filtering -- "Default excludes (node_modules, dist, .git) limit scope"
|
|
9
|
+
* @flows #cli -> #parser via parseProject -- "CLI passes user-specified root directory to parser"
|
|
10
|
+
* @flows #mcp -> #parser via parseProject -- "MCP server passes root param from AI agents"
|
|
11
|
+
* @handles internal on #parser -- "Processes source files to extract security annotation metadata"
|
|
12
|
+
*/
|
|
13
|
+
import fg from 'fast-glob';
|
|
14
|
+
import { relative } from 'node:path';
|
|
15
|
+
import { parseFile } from './parse-file.js';
|
|
16
|
+
const DEFAULT_INCLUDE = [
|
|
17
|
+
'**/*.ts', '**/*.tsx', '**/*.js', '**/*.jsx',
|
|
18
|
+
'**/*.py', '**/*.rb', '**/*.go', '**/*.rs',
|
|
19
|
+
'**/*.java', '**/*.kt', '**/*.scala',
|
|
20
|
+
'**/*.c', '**/*.cpp', '**/*.cc', '**/*.h', '**/*.hpp',
|
|
21
|
+
'**/*.cs', '**/*.swift', '**/*.dart',
|
|
22
|
+
'**/*.sql', '**/*.lua', '**/*.hs',
|
|
23
|
+
'**/*.tf', '**/*.hcl',
|
|
24
|
+
'**/*.yaml', '**/*.yml',
|
|
25
|
+
'**/*.sh', '**/*.bash',
|
|
26
|
+
'**/*.html', '**/*.xml', '**/*.svg',
|
|
27
|
+
'**/*.css',
|
|
28
|
+
'**/*.ex', '**/*.exs',
|
|
29
|
+
];
|
|
30
|
+
const DEFAULT_EXCLUDE = [
|
|
31
|
+
'**/node_modules/**', '**/dist/**', '**/build/**', '**/.git/**',
|
|
32
|
+
'**/__pycache__/**', '**/target/**', '**/vendor/**', '**/.next/**',
|
|
33
|
+
'**/tests/**', '**/test/**', '**/__tests__/**',
|
|
34
|
+
];
|
|
35
|
+
/**
|
|
36
|
+
* Parse an entire project directory and return a ThreatModel.
|
|
37
|
+
*/
|
|
38
|
+
export async function parseProject(options) {
|
|
39
|
+
const { root, include = DEFAULT_INCLUDE, exclude = DEFAULT_EXCLUDE, project = 'unknown', } = options;
|
|
40
|
+
// Discover files (dot: true to include .guardlink/ definitions)
|
|
41
|
+
const files = await fg(include, {
|
|
42
|
+
cwd: root,
|
|
43
|
+
ignore: exclude,
|
|
44
|
+
absolute: true,
|
|
45
|
+
dot: true,
|
|
46
|
+
});
|
|
47
|
+
// Parse all files
|
|
48
|
+
const allAnnotations = [];
|
|
49
|
+
const allDiagnostics = [];
|
|
50
|
+
for (const file of files) {
|
|
51
|
+
const result = await parseFile(file);
|
|
52
|
+
// Normalize file paths to relative
|
|
53
|
+
for (const ann of result.annotations) {
|
|
54
|
+
ann.location.file = relative(root, ann.location.file);
|
|
55
|
+
}
|
|
56
|
+
for (const diag of result.diagnostics) {
|
|
57
|
+
diag.file = relative(root, diag.file);
|
|
58
|
+
}
|
|
59
|
+
allAnnotations.push(...result.annotations);
|
|
60
|
+
allDiagnostics.push(...result.diagnostics);
|
|
61
|
+
}
|
|
62
|
+
// Check for duplicate identifiers
|
|
63
|
+
const idMap = new Map();
|
|
64
|
+
for (const ann of allAnnotations) {
|
|
65
|
+
const id = getAnnotationId(ann);
|
|
66
|
+
if (id) {
|
|
67
|
+
if (idMap.has(id)) {
|
|
68
|
+
const prev = idMap.get(id);
|
|
69
|
+
allDiagnostics.push({
|
|
70
|
+
level: 'error',
|
|
71
|
+
message: `Duplicate identifier #${id} (first defined at ${prev.location.file}:${prev.location.line})`,
|
|
72
|
+
file: ann.location.file,
|
|
73
|
+
line: ann.location.line,
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
idMap.set(id, ann);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
// Assemble ThreatModel
|
|
82
|
+
const model = assembleModel(allAnnotations, files.length, project);
|
|
83
|
+
return { model, diagnostics: allDiagnostics };
|
|
84
|
+
}
|
|
85
|
+
function getAnnotationId(ann) {
|
|
86
|
+
if ('id' in ann)
|
|
87
|
+
return ann.id;
|
|
88
|
+
return undefined;
|
|
89
|
+
}
|
|
90
|
+
function assembleModel(annotations, fileCount, project) {
|
|
91
|
+
const model = {
|
|
92
|
+
version: '1.0.0',
|
|
93
|
+
project,
|
|
94
|
+
generated_at: new Date().toISOString(),
|
|
95
|
+
source_files: fileCount,
|
|
96
|
+
annotations_parsed: annotations.length,
|
|
97
|
+
assets: [],
|
|
98
|
+
threats: [],
|
|
99
|
+
controls: [],
|
|
100
|
+
mitigations: [],
|
|
101
|
+
exposures: [],
|
|
102
|
+
acceptances: [],
|
|
103
|
+
transfers: [],
|
|
104
|
+
flows: [],
|
|
105
|
+
boundaries: [],
|
|
106
|
+
validations: [],
|
|
107
|
+
audits: [],
|
|
108
|
+
ownership: [],
|
|
109
|
+
data_handling: [],
|
|
110
|
+
assumptions: [],
|
|
111
|
+
shields: [],
|
|
112
|
+
comments: [],
|
|
113
|
+
coverage: {
|
|
114
|
+
total_symbols: 0,
|
|
115
|
+
annotated_symbols: annotations.length,
|
|
116
|
+
coverage_percent: 0,
|
|
117
|
+
unannotated_critical: [],
|
|
118
|
+
},
|
|
119
|
+
};
|
|
120
|
+
for (const ann of annotations) {
|
|
121
|
+
switch (ann.verb) {
|
|
122
|
+
case 'asset': {
|
|
123
|
+
const a = ann;
|
|
124
|
+
model.assets.push({
|
|
125
|
+
path: a.path.split('.'),
|
|
126
|
+
id: a.id,
|
|
127
|
+
description: a.description,
|
|
128
|
+
location: a.location,
|
|
129
|
+
});
|
|
130
|
+
break;
|
|
131
|
+
}
|
|
132
|
+
case 'threat': {
|
|
133
|
+
const t = ann;
|
|
134
|
+
model.threats.push({
|
|
135
|
+
name: t.name,
|
|
136
|
+
canonical_name: t.canonical_name,
|
|
137
|
+
id: t.id,
|
|
138
|
+
severity: t.severity,
|
|
139
|
+
external_refs: t.external_refs,
|
|
140
|
+
description: t.description,
|
|
141
|
+
location: t.location,
|
|
142
|
+
});
|
|
143
|
+
break;
|
|
144
|
+
}
|
|
145
|
+
case 'control': {
|
|
146
|
+
const c = ann;
|
|
147
|
+
model.controls.push({
|
|
148
|
+
name: c.name,
|
|
149
|
+
canonical_name: c.canonical_name,
|
|
150
|
+
id: c.id,
|
|
151
|
+
description: c.description,
|
|
152
|
+
location: c.location,
|
|
153
|
+
});
|
|
154
|
+
break;
|
|
155
|
+
}
|
|
156
|
+
case 'mitigates': {
|
|
157
|
+
const m = ann;
|
|
158
|
+
model.mitigations.push({
|
|
159
|
+
asset: m.asset, threat: m.threat, control: m.control,
|
|
160
|
+
description: m.description, location: m.location,
|
|
161
|
+
});
|
|
162
|
+
break;
|
|
163
|
+
}
|
|
164
|
+
case 'exposes': {
|
|
165
|
+
const e = ann;
|
|
166
|
+
model.exposures.push({
|
|
167
|
+
asset: e.asset, threat: e.threat, severity: e.severity,
|
|
168
|
+
external_refs: e.external_refs,
|
|
169
|
+
description: e.description, location: e.location,
|
|
170
|
+
});
|
|
171
|
+
break;
|
|
172
|
+
}
|
|
173
|
+
case 'accepts': {
|
|
174
|
+
const a = ann;
|
|
175
|
+
model.acceptances.push({
|
|
176
|
+
threat: a.threat, asset: a.asset,
|
|
177
|
+
description: a.description, location: a.location,
|
|
178
|
+
});
|
|
179
|
+
break;
|
|
180
|
+
}
|
|
181
|
+
case 'transfers': {
|
|
182
|
+
const t = ann;
|
|
183
|
+
model.transfers.push({
|
|
184
|
+
threat: t.threat, source: t.source, target: t.target,
|
|
185
|
+
description: t.description, location: t.location,
|
|
186
|
+
});
|
|
187
|
+
break;
|
|
188
|
+
}
|
|
189
|
+
case 'flows': {
|
|
190
|
+
const f = ann;
|
|
191
|
+
model.flows.push({
|
|
192
|
+
source: f.source, target: f.target, mechanism: f.mechanism,
|
|
193
|
+
description: f.description, location: f.location,
|
|
194
|
+
});
|
|
195
|
+
break;
|
|
196
|
+
}
|
|
197
|
+
case 'boundary': {
|
|
198
|
+
const b = ann;
|
|
199
|
+
model.boundaries.push({
|
|
200
|
+
asset_a: b.asset_a, asset_b: b.asset_b, id: b.id,
|
|
201
|
+
description: b.description, location: b.location,
|
|
202
|
+
});
|
|
203
|
+
break;
|
|
204
|
+
}
|
|
205
|
+
case 'validates': {
|
|
206
|
+
const v = ann;
|
|
207
|
+
model.validations.push({
|
|
208
|
+
control: v.control, asset: v.asset,
|
|
209
|
+
description: v.description, location: v.location,
|
|
210
|
+
});
|
|
211
|
+
break;
|
|
212
|
+
}
|
|
213
|
+
case 'audit': {
|
|
214
|
+
const a = ann;
|
|
215
|
+
model.audits.push({
|
|
216
|
+
asset: a.asset,
|
|
217
|
+
description: a.description, location: a.location,
|
|
218
|
+
});
|
|
219
|
+
break;
|
|
220
|
+
}
|
|
221
|
+
case 'owns': {
|
|
222
|
+
const o = ann;
|
|
223
|
+
model.ownership.push({
|
|
224
|
+
owner: o.owner, asset: o.asset,
|
|
225
|
+
description: o.description, location: o.location,
|
|
226
|
+
});
|
|
227
|
+
break;
|
|
228
|
+
}
|
|
229
|
+
case 'handles': {
|
|
230
|
+
const h = ann;
|
|
231
|
+
model.data_handling.push({
|
|
232
|
+
classification: h.classification,
|
|
233
|
+
asset: h.asset,
|
|
234
|
+
description: h.description, location: h.location,
|
|
235
|
+
});
|
|
236
|
+
break;
|
|
237
|
+
}
|
|
238
|
+
case 'assumes': {
|
|
239
|
+
const a = ann;
|
|
240
|
+
model.assumptions.push({
|
|
241
|
+
asset: a.asset,
|
|
242
|
+
description: a.description, location: a.location,
|
|
243
|
+
});
|
|
244
|
+
break;
|
|
245
|
+
}
|
|
246
|
+
case 'comment': {
|
|
247
|
+
const c = ann;
|
|
248
|
+
model.comments.push({
|
|
249
|
+
description: c.description, location: c.location,
|
|
250
|
+
});
|
|
251
|
+
break;
|
|
252
|
+
}
|
|
253
|
+
case 'shield':
|
|
254
|
+
case 'shield:begin':
|
|
255
|
+
case 'shield:end': {
|
|
256
|
+
const s = ann;
|
|
257
|
+
model.shields.push({
|
|
258
|
+
reason: s.description,
|
|
259
|
+
location: s.location,
|
|
260
|
+
});
|
|
261
|
+
break;
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
// Second pass: resolve exposure severity from threat definitions
|
|
266
|
+
// when the @exposes annotation has no inline severity
|
|
267
|
+
const threatSeverityMap = new Map();
|
|
268
|
+
for (const t of model.threats) {
|
|
269
|
+
if (t.id && t.severity)
|
|
270
|
+
threatSeverityMap.set(`#${t.id}`, t.severity);
|
|
271
|
+
if (t.id && t.severity)
|
|
272
|
+
threatSeverityMap.set(t.id, t.severity);
|
|
273
|
+
}
|
|
274
|
+
for (const e of model.exposures) {
|
|
275
|
+
if (!e.severity) {
|
|
276
|
+
e.severity = threatSeverityMap.get(e.threat);
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
return model;
|
|
280
|
+
}
|
|
281
|
+
//# sourceMappingURL=parse-project.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parse-project.js","sourceRoot":"","sources":["../../src/parser/parse-project.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/report/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/report/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GuardLink Report — Mermaid diagram generator.
|
|
3
|
+
*
|
|
4
|
+
* Design principles:
|
|
5
|
+
* 1. DFD-style: Show data flows between assets, trust boundaries, and threats
|
|
6
|
+
* 2. Only connected nodes: Assets with no flows/exposures are omitted
|
|
7
|
+
* 3. Controls stay in tables: Don't add control nodes — they clutter the graph
|
|
8
|
+
* 4. Threat markers on edges: Show exposures as red dotted edges, not separate nodes
|
|
9
|
+
* 5. Distinct shapes: Actors (()), Processes [], Data stores [()]
|
|
10
|
+
* 6. Deduplicate: One node per asset, one label per data classification
|
|
11
|
+
* 7. Top-down layout: External → boundary → internal → data
|
|
12
|
+
*/
|
|
13
|
+
import type { ThreatModel } from '../types/index.js';
|
|
14
|
+
export declare function generateMermaid(model: ThreatModel): string;
|
|
15
|
+
//# sourceMappingURL=mermaid.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mermaid.d.ts","sourceRoot":"","sources":["../../src/report/mermaid.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAuBrD,wBAAgB,eAAe,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,CAiM1D"}
|