guardlink 1.4.0 → 1.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. package/CHANGELOG.md +48 -0
  2. package/README.md +17 -3
  3. package/dist/agents/index.d.ts +8 -0
  4. package/dist/agents/index.d.ts.map +1 -1
  5. package/dist/agents/index.js +35 -0
  6. package/dist/agents/index.js.map +1 -1
  7. package/dist/agents/launcher.d.ts +1 -1
  8. package/dist/agents/launcher.d.ts.map +1 -1
  9. package/dist/agents/launcher.js +6 -1
  10. package/dist/agents/launcher.js.map +1 -1
  11. package/dist/agents/prompts.d.ts +2 -1
  12. package/dist/agents/prompts.d.ts.map +1 -1
  13. package/dist/agents/prompts.js +66 -14
  14. package/dist/agents/prompts.js.map +1 -1
  15. package/dist/analyze/prompts.js +1 -1
  16. package/dist/cli/index.js +86 -49
  17. package/dist/cli/index.js.map +1 -1
  18. package/dist/diff/git.js +3 -3
  19. package/dist/diff/git.js.map +1 -1
  20. package/dist/init/index.d.ts +7 -0
  21. package/dist/init/index.d.ts.map +1 -1
  22. package/dist/init/index.js +60 -24
  23. package/dist/init/index.js.map +1 -1
  24. package/dist/init/templates.js +5 -5
  25. package/dist/mcp/server.d.ts.map +1 -1
  26. package/dist/mcp/server.js +13 -8
  27. package/dist/mcp/server.js.map +1 -1
  28. package/dist/mcp/suggest.d.ts +1 -0
  29. package/dist/mcp/suggest.d.ts.map +1 -1
  30. package/dist/mcp/suggest.js +1 -0
  31. package/dist/mcp/suggest.js.map +1 -1
  32. package/dist/parser/clear.d.ts +2 -1
  33. package/dist/parser/clear.d.ts.map +1 -1
  34. package/dist/parser/clear.js +18 -28
  35. package/dist/parser/clear.js.map +1 -1
  36. package/dist/parser/comment-strip.d.ts +5 -0
  37. package/dist/parser/comment-strip.d.ts.map +1 -1
  38. package/dist/parser/comment-strip.js +8 -0
  39. package/dist/parser/comment-strip.js.map +1 -1
  40. package/dist/parser/parse-file.d.ts +1 -0
  41. package/dist/parser/parse-file.d.ts.map +1 -1
  42. package/dist/parser/parse-file.js +31 -8
  43. package/dist/parser/parse-file.js.map +1 -1
  44. package/dist/parser/parse-line.d.ts +6 -0
  45. package/dist/parser/parse-line.d.ts.map +1 -1
  46. package/dist/parser/parse-line.js +23 -5
  47. package/dist/parser/parse-line.js.map +1 -1
  48. package/dist/parser/parse-project.d.ts +1 -0
  49. package/dist/parser/parse-project.d.ts.map +1 -1
  50. package/dist/parser/parse-project.js +17 -2
  51. package/dist/parser/parse-project.js.map +1 -1
  52. package/dist/review/index.d.ts +3 -1
  53. package/dist/review/index.d.ts.map +1 -1
  54. package/dist/review/index.js +77 -35
  55. package/dist/review/index.js.map +1 -1
  56. package/dist/tui/commands.d.ts.map +1 -1
  57. package/dist/tui/commands.js +72 -46
  58. package/dist/tui/commands.js.map +1 -1
  59. package/dist/types/index.d.ts +2 -0
  60. package/dist/types/index.d.ts.map +1 -1
  61. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/review/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAMH,OAAO,KAAK,EAAE,WAAW,EAAE,mBAAmB,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAIpF,MAAM,MAAM,cAAc,GAAG,QAAQ,GAAG,WAAW,GAAG,MAAM,CAAC;AAE7D,MAAM,WAAW,kBAAkB;IACjC,uCAAuC;IACvC,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,mBAAmB,CAAC;IAC9B,qCAAqC;IACrC,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,cAAc,CAAC;IACzB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,kBAAkB,CAAC;IAC7B,MAAM,EAAE,YAAY,CAAC;IACrB,oDAAoD;IACpD,aAAa,EAAE,MAAM,CAAC;CACvB;AAWD;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,WAAW,GAAG,kBAAkB,EAAE,CAsB/E;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,CAAC,CAAC,EAAE,QAAQ,GAAG,MAAM,CAGlD;AA0ID;;;;;;;GAOG;AACH,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,kBAAkB,EAC9B,MAAM,EAAE,YAAY,GACnB,OAAO,CAAC,YAAY,CAAC,CAuBvB;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,CAAC,EAAE,kBAAkB,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CASpF;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,YAAY,EAAE,GAAG,MAAM,CAY/D"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/review/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAOH,OAAO,KAAK,EAAE,WAAW,EAAE,mBAAmB,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAIpF,MAAM,MAAM,cAAc,GAAG,QAAQ,GAAG,WAAW,GAAG,MAAM,CAAC;AAE7D,MAAM,WAAW,kBAAkB;IACjC,uCAAuC;IACvC,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,mBAAmB,CAAC;IAC9B,wBAAwB;IACxB,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,cAAc,CAAC;IACzB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,kBAAkB,CAAC;IAC7B,MAAM,EAAE,YAAY,CAAC;IACrB,oDAAoD;IACpD,aAAa,EAAE,MAAM,CAAC;IACtB,wDAAwD;IACxD,UAAU,EAAE,MAAM,CAAC;CACpB;AAWD;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,WAAW,GAAG,kBAAkB,EAAE,CAsB/E;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,CAAC,CAAC,EAAE,QAAQ,GAAG,MAAM,CAGlD;AAuKD;;;;;;;GAOG;AACH,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,kBAAkB,EAC9B,MAAM,EAAE,YAAY,GACnB,OAAO,CAAC,YAAY,CAAC,CAwBvB;AAqBD;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,CAAC,EAAE,kBAAkB,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CASpF;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,YAAY,EAAE,GAAG,MAAM,CAY/D"}
@@ -15,8 +15,9 @@
15
15
  * @handles internal on #cli -- "Processes exposure metadata and user justification text"
16
16
  */
17
17
  import { readFile, writeFile } from 'node:fs/promises';
18
- import { resolve } from 'node:path';
19
- import { stripCommentPrefix } from '../parser/comment-strip.js';
18
+ import { extname, resolve } from 'node:path';
19
+ import { commentStyleForExt, stripCommentPrefix } from '../parser/comment-strip.js';
20
+ import { parseLine } from '../parser/parse-line.js';
20
21
  import { findUnmitigatedExposures } from '../parser/validate.js';
21
22
  // ─── Severity ordering ──────────────────────────────────────────────
22
23
  const SEVERITY_ORDER = {
@@ -45,7 +46,7 @@ export function getReviewableExposures(model) {
45
46
  return filtered.map((exposure, i) => ({
46
47
  index: i + 1,
47
48
  exposure,
48
- id: `${exposure.location.file}:${exposure.location.line}`,
49
+ id: reviewExposureId(exposure),
49
50
  }));
50
51
  }
51
52
  /**
@@ -60,39 +61,57 @@ export function severityLabel(s) {
60
61
  * Detect the comment style and indentation from the @exposes source line.
61
62
  * Supports JSDoc ( * @...), single-line (// @...), and hash (# @...) styles.
62
63
  */
63
- function detectCommentStyle(rawLine) {
64
+ function detectCommentStyle(rawLine, filePath) {
64
65
  const indent = rawLine.match(/^(\s*)/)?.[1] || '';
65
66
  const trimmed = rawLine.trimStart();
67
+ if (trimmed.startsWith('@')) {
68
+ return { prefix: '', suffix: '', indent };
69
+ }
66
70
  if (trimmed.startsWith('* @') || trimmed.startsWith('* @')) {
67
- return { prefix: '* ', indent };
71
+ return { prefix: '* ', suffix: '', indent };
68
72
  }
69
73
  if (trimmed.startsWith('// @')) {
70
- return { prefix: '// ', indent };
74
+ return { prefix: '// ', suffix: '', indent };
71
75
  }
72
76
  if (trimmed.startsWith('# @')) {
73
- return { prefix: '# ', indent };
77
+ return { prefix: '# ', suffix: '', indent };
74
78
  }
75
79
  if (trimmed.startsWith('-- @')) {
76
- return { prefix: '-- ', indent };
80
+ return { prefix: '-- ', suffix: '', indent };
81
+ }
82
+ if (trimmed.startsWith('<!--')) {
83
+ return { prefix: '<!-- ', suffix: ' -->', indent };
84
+ }
85
+ if (trimmed.startsWith('/*')) {
86
+ return { prefix: '/* ', suffix: ' */', indent };
87
+ }
88
+ return fallbackCommentStyle(filePath, indent);
89
+ }
90
+ function fallbackCommentStyle(filePath, indent) {
91
+ switch (commentStyleForExt(extname(filePath))) {
92
+ case '#': return { prefix: '# ', suffix: '', indent };
93
+ case '--': return { prefix: '-- ', suffix: '', indent };
94
+ case '<!--': return { prefix: '<!-- ', suffix: ' -->', indent };
95
+ case '/*': return { prefix: '/* ', suffix: ' */', indent };
96
+ case '%': return { prefix: '% ', suffix: '', indent };
97
+ case ';': return { prefix: '; ', suffix: '', indent };
98
+ case 'REM': return { prefix: 'REM ', suffix: '', indent };
99
+ case "'": return { prefix: "' ", suffix: '', indent };
100
+ case '//':
101
+ default:
102
+ return { prefix: '// ', suffix: '', indent };
77
103
  }
78
- // Fallback: single-line JS style
79
- return { prefix: '// ', indent };
80
104
  }
81
105
  /**
82
106
  * Check if a source line is a GuardLink annotation (used to walk past coupled blocks).
83
107
  */
84
108
  function isAnnotationLine(line) {
85
- const inner = stripCommentPrefix(line);
86
- if (inner === null)
87
- return false;
88
- const trimmed = inner.trim();
89
- // Annotation line: starts with @verb
90
- if (trimmed.startsWith('@'))
109
+ const rawTrimmed = line.trimStart();
110
+ if (/^--\s*"/.test(rawTrimmed))
91
111
  return true;
92
- // Continuation line: -- "..."
93
- if (/^--\s*"/.test(trimmed))
94
- return true;
95
- return false;
112
+ const inner = stripCommentPrefix(line) ?? rawTrimmed;
113
+ const parsed = parseLine(inner, { file: '<review>', line: 1 });
114
+ return Boolean(parsed.annotation || parsed.sourceDirective || parsed.isContinuation);
96
115
  }
97
116
  /**
98
117
  * Find the insertion point after the coupled annotation block that contains
@@ -101,11 +120,14 @@ function isAnnotationLine(line) {
101
120
  * Walks forward from the exposure line past consecutive annotation lines
102
121
  * to find the end of the block, then returns the 0-indexed line to insert after.
103
122
  */
104
- function findInsertionIndex(lines, exposureLine) {
123
+ function findInsertionIndex(lines, exposureLine, stopAtSourceBoundary = false) {
105
124
  // exposureLine is 1-indexed, convert to 0-indexed
106
125
  let idx = exposureLine - 1;
107
126
  // Walk forward past consecutive annotation lines
108
127
  while (idx + 1 < lines.length && isAnnotationLine(lines[idx + 1])) {
128
+ if (stopAtSourceBoundary && lines[idx + 1].trimStart().startsWith('@source')) {
129
+ break;
130
+ }
109
131
  idx++;
110
132
  }
111
133
  // Insert after the last annotation line in the block
@@ -120,21 +142,21 @@ function todayISO() {
120
142
  * Returns lines WITHOUT trailing newline.
121
143
  */
122
144
  function buildAcceptLines(style, exposure, justification) {
123
- const { prefix, indent } = style;
145
+ const { prefix, suffix, indent } = style;
124
146
  const date = todayISO();
125
147
  return [
126
- `${indent}${prefix}@accepts ${exposure.threat} on ${exposure.asset} -- "${escapeDesc(justification)}"`,
127
- `${indent}${prefix}@audit ${exposure.asset} -- "Accepted via guardlink review on ${date}"`,
148
+ `${indent}${prefix}@accepts ${exposure.threat} on ${exposure.asset} -- "${escapeDesc(justification)}"${suffix}`,
149
+ `${indent}${prefix}@audit ${exposure.asset} -- "Accepted via guardlink review on ${date}"${suffix}`,
128
150
  ];
129
151
  }
130
152
  /**
131
153
  * Build the annotation line to insert for a "remediate" decision.
132
154
  */
133
155
  function buildRemediateLines(style, exposure, note) {
134
- const { prefix, indent } = style;
156
+ const { prefix, suffix, indent } = style;
135
157
  const date = todayISO();
136
158
  return [
137
- `${indent}${prefix}@audit ${exposure.asset} -- "Planned remediation: ${escapeDesc(note)} — flagged via guardlink review on ${date}"`,
159
+ `${indent}${prefix}@audit ${exposure.asset} -- "Planned remediation: ${escapeDesc(note)} — flagged via guardlink review on ${date}"${suffix}`,
138
160
  ];
139
161
  }
140
162
  /** Escape double quotes in description strings */
@@ -149,15 +171,17 @@ function escapeDesc(s) {
149
171
  * Returns the number of lines inserted.
150
172
  */
151
173
  async function insertAnnotations(root, exposure, newLines) {
152
- const filePath = resolve(root, exposure.location.file);
174
+ const filePath = resolve(root, getWriteLocation(exposure).file);
153
175
  const content = await readFile(filePath, 'utf-8');
154
176
  const lines = content.split('\n');
155
177
  // Validate that the exposure line exists and looks right
156
- const exposureIdx = exposure.location.line - 1; // 0-indexed
178
+ const targetLocation = getWriteLocation(exposure);
179
+ const exposureIdx = targetLocation.line - 1; // 0-indexed
157
180
  if (exposureIdx < 0 || exposureIdx >= lines.length) {
158
- throw new Error(`Line ${exposure.location.line} out of range in ${exposure.location.file}`);
181
+ throw new Error(`Line ${targetLocation.line} out of range in ${targetLocation.file}`);
159
182
  }
160
- const insertIdx = findInsertionIndex(lines, exposure.location.line);
183
+ const style = detectCommentStyle(lines[exposureIdx], targetLocation.file);
184
+ const insertIdx = findInsertionIndex(lines, targetLocation.line, style.prefix === '');
161
185
  // Splice in the new lines
162
186
  lines.splice(insertIdx, 0, ...newLines);
163
187
  await writeFile(filePath, lines.join('\n'));
@@ -174,15 +198,16 @@ async function insertAnnotations(root, exposure, newLines) {
174
198
  */
175
199
  export async function applyReviewAction(root, reviewable, action) {
176
200
  if (action.decision === 'skip') {
177
- return { exposure: reviewable, action, linesInserted: 0 };
201
+ return { exposure: reviewable, action, linesInserted: 0, targetFile: getWriteLocation(reviewable.exposure).file };
178
202
  }
179
203
  const { exposure } = reviewable;
180
- const filePath = resolve(root, exposure.location.file);
204
+ const targetLocation = getWriteLocation(exposure);
205
+ const filePath = resolve(root, targetLocation.file);
181
206
  const content = await readFile(filePath, 'utf-8');
182
207
  const lines = content.split('\n');
183
208
  // Detect comment style from the @exposes line
184
- const exposureIdx = exposure.location.line - 1;
185
- const style = detectCommentStyle(lines[exposureIdx]);
209
+ const exposureIdx = targetLocation.line - 1;
210
+ const style = detectCommentStyle(lines[exposureIdx], targetLocation.file);
186
211
  let newLines;
187
212
  if (action.decision === 'accept') {
188
213
  newLines = buildAcceptLines(style, exposure, action.justification);
@@ -191,7 +216,24 @@ export async function applyReviewAction(root, reviewable, action) {
191
216
  newLines = buildRemediateLines(style, exposure, action.justification);
192
217
  }
193
218
  const linesInserted = await insertAnnotations(root, exposure, newLines);
194
- return { exposure: reviewable, action, linesInserted };
219
+ return { exposure: reviewable, action, linesInserted, targetFile: targetLocation.file };
220
+ }
221
+ function getWriteLocation(exposure) {
222
+ return {
223
+ file: exposure.location.origin_file || exposure.location.file,
224
+ line: exposure.location.origin_line || exposure.location.line,
225
+ };
226
+ }
227
+ function reviewExposureId(exposure) {
228
+ const writeLocation = getWriteLocation(exposure);
229
+ return [
230
+ writeLocation.file,
231
+ String(writeLocation.line),
232
+ exposure.location.file,
233
+ String(exposure.location.line),
234
+ exposure.asset,
235
+ exposure.threat,
236
+ ].join(':');
195
237
  }
196
238
  /**
197
239
  * Format an exposure for display in CLI/TUI review UI.
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/review/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/review/index.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../../src/tui/commands.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../../src/tui/commands.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAYH,OAAO,KAAK,EAAE,WAAW,EAAmB,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AA0B3F,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,WAAW,GAAG,IAAI,CAAC;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,uCAAuC;IACvC,EAAE,EAAE,OAAO,eAAe,EAAE,SAAS,CAAC;IACtC,8DAA8D;IAC9D,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,qEAAqE;IACrE,aAAa,EAAE,mBAAmB,EAAE,CAAC;CACtC;AAED,8CAA8C;AAC9C,wBAAsB,YAAY,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAGjE;AAoBD,wBAAgB,OAAO,IAAI,IAAI,CAkD9B;AAID,wBAAgB,MAAM,IAAI,IAAI,CAyK7B;AAID,wBAAgB,SAAS,CAAC,GAAG,EAAE,UAAU,GAAG,IAAI,CA+D/C;AAID,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,GAAG,IAAI,CA8DhE;AAID,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,GAAG,IAAI,CAyB3D;AAID,wBAAgB,OAAO,CAAC,GAAG,EAAE,UAAU,GAAG,IAAI,CA0B7C;AAID,wBAAgB,SAAS,CAAC,GAAG,EAAE,UAAU,GAAG,IAAI,CA8C/C;AAID,wBAAgB,QAAQ,CAAC,GAAG,EAAE,UAAU,GAAG,IAAI,CA6E9C;AAID,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,GAAG,IAAI,CAuH3D;AAID,wBAAsB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAoC1E;AAID,wBAAsB,QAAQ,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAmC7D;AAID,wBAAsB,WAAW,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAkEhE;AAID,wBAAsB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CA2B1E;AAID,wBAAsB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAwC3E;AA6GD,wBAAsB,QAAQ,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAkI7D;AAkFD,wBAAsB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAwIlF;AAID,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,UAAU,GAAG,IAAI,CAsBtD;AAID,wBAAsB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAmE9E;AAID,wBAAsB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CA8E1E;AAID,wBAAsB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAoD3E;AAID,wBAAsB,OAAO,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CA2B5D;AAID,wBAAgB,cAAc,CAAC,GAAG,EAAE,UAAU,GAAG,IAAI,CAkBpD;AAID,wBAAsB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAiF5E;AAID,wBAAsB,SAAS,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAiB9D;AAID,wBAAsB,YAAY,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAuBjE;AAID,wBAAgB,YAAY,CAAC,GAAG,EAAE,UAAU,GAAG,IAAI,CAuBlD;AAID,wBAAsB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAoF1E;AAID,wBAAsB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAgH3E"}
@@ -32,7 +32,7 @@ import { diffModels, formatDiff, parseAtRef } from '../diff/index.js';
32
32
  import { generateSarif } from '../analyzer/index.js';
33
33
  import { C, severityBadge, severityText, severityTextPad, severityOrder, computeGrade, gradeColored, readCodeContext, trunc, bar, fileLink, fileLinkTrunc, cleanCliArtifacts } from './format.js';
34
34
  import { resolveLLMConfig, saveTuiConfig, loadTuiConfig } from './config.js';
35
- import { AGENTS, parseAgentFlag, launchAgent, launchAgentInline, copyToClipboard, buildAnnotatePrompt } from '../agents/index.js';
35
+ import { AGENTS, parseAgentFlag, parseAnnotationModeFlag, launchAgent, launchAgentInline, copyToClipboard, buildAnnotatePrompt } from '../agents/index.js';
36
36
  import { describeConfigSource } from '../agents/config.js';
37
37
  import { getReviewableExposures, applyReviewAction, summarizeReview } from '../review/index.js';
38
38
  import { loadWorkspaceConfig, linkProject, addToWorkspace, removeFromWorkspace, mergeReports, formatMergeSummary, diffMergedReports } from '../workspace/index.js';
@@ -87,6 +87,7 @@ export function cmdHelp() {
87
87
  ['/assets', 'Asset tree with threat/control counts'],
88
88
  ['/files', 'Annotated file tree with exposure counts'],
89
89
  ['/view <file>', 'Show all annotations in a file with code context'],
90
+ ['/unannotated', 'List source files with no annotations'],
90
91
  ['', ''],
91
92
  ['/threat-report <fw>', 'AI threat report (stride|dread|pasta|attacker|rapid|general|custom)'],
92
93
  ['/threat-reports', 'List saved AI threat reports'],
@@ -133,115 +134,135 @@ export function cmdGal() {
133
134
  console.log(H(' GAL — GuardLink Annotation Language'));
134
135
  console.log(H(' ══════════════════════════════════════════════════════════'));
135
136
  console.log('');
136
- console.log(D(' Annotations live in source code comments. GuardLink parses'));
137
- console.log(D(' them to build a live threat model from your codebase.'));
137
+ console.log(D(' Annotations live in source comments or standalone .gal files.'));
138
+ console.log(D(' GuardLink parses them into a live threat model for your codebase.'));
138
139
  console.log('');
139
- console.log(D(' Syntax: @verb subject [preposition object] [: description]'));
140
+ console.log(D(' Syntax: @verb subject [preposition object] [-- "description"]'));
141
+ console.log(D(' Inline examples below use comment prefixes; raw .gal files use the same lines without // or #.'));
142
+ console.log(D(' In .gal files, use @source file:<path> line:<n> [symbol:<name>] to anchor following annotations.'));
140
143
  console.log('');
141
144
  // ── DEFINITIONS ──────────────────────────────────────────────────
142
145
  console.log(H(' ── Definitions ─────────────────────────────────────────────'));
143
146
  console.log('');
144
- console.log(` ${V('@asset')} ${K('<path>')} ${D('[: description]')}`);
147
+ console.log(` ${V('@asset')} ${K('<path>')} ${D('[-- "description"]')}`);
145
148
  console.log(D(' Declare a named asset (component, service, data store).'));
146
149
  console.log(D(' Path uses dot notation for hierarchy.'));
147
- console.log(EX(' // @asset api.auth.token_store : Stores JWT refresh tokens'));
150
+ console.log(EX(' // @asset api.auth.token_store -- "Stores JWT refresh tokens"'));
148
151
  console.log(EX(' // @asset db.users'));
149
152
  console.log('');
150
- console.log(` ${V('@threat')} ${K('<name>')} ${D('[severity: critical|high|medium|low] [: description]')}`);
151
- console.log(D(' Declare a named threat. Severity aliases: P0=critical P1=high P2=medium P3=low.'));
152
- console.log(EX(' // @threat SQL Injection severity:high : Unsanitized input reaches DB'));
153
- console.log(EX(' // @threat Token Theft severity:P0'));
153
+ console.log(` ${V('@threat')} ${K('<name>')} ${D('(#id)')} ${D('[critical|high|medium|low]')} ${D('[ext-refs]')} ${D('[-- "description"]')}`);
154
+ console.log(D(' Declare a named threat. Severity in brackets: [P0]=[critical] [P1]=[high] [P2]=[medium] [P3]=[low].'));
155
+ console.log(EX(' // @threat SQL Injection (#sql-inj) [high] cwe:CWE-89 -- "Unsanitized input reaches DB"'));
156
+ console.log(EX(' // @threat Token Theft [P0]'));
154
157
  console.log('');
155
- console.log(` ${V('@control')} ${K('<name>')} ${D('[: description]')}`);
158
+ console.log(` ${V('@control')} ${K('<name>')} ${D('(#id)')} ${D('[-- "description"]')}`);
156
159
  console.log(D(' Declare a security control (mitigation mechanism).'));
157
- console.log(EX(' // @control Input Validation : Sanitize all user-supplied strings'));
160
+ console.log(EX(' // @control Input Validation (#input-val) -- "Sanitize all user-supplied strings"'));
158
161
  console.log(EX(' // @control Rate Limiting'));
159
162
  console.log('');
160
163
  // ── RELATIONSHIPS ─────────────────────────────────────────────────
161
164
  console.log(H(' ── Relationships ───────────────────────────────────────────'));
162
165
  console.log('');
163
- console.log(` ${V('@exposes')} ${K('<asset>')} ${D('to')} ${K('<threat>')} ${D('[severity: ...] [: description]')}`);
166
+ console.log(` ${V('@exposes')} ${K('<asset>')} ${D('to')} ${K('<threat>')} ${D('[severity]')} ${D('[ext-refs]')} ${D('[-- "description"]')}`);
164
167
  console.log(D(' Mark an asset as exposed to a threat at this code location.'));
165
168
  console.log(D(' This is the primary annotation — every exposure creates a finding.'));
166
- console.log(EX(' // @exposes api.auth to SQL Injection severity:high'));
167
- console.log(EX(' // @exposes db.users to Token Theft severity:critical : No token rotation'));
169
+ console.log(EX(' // @exposes api.auth to SQL Injection [high] cwe:CWE-89'));
170
+ console.log(EX(' // @exposes db.users to Token Theft [critical] -- "No token rotation"'));
168
171
  console.log('');
169
- console.log(` ${V('@mitigates')} ${K('<asset>')} ${D('against')} ${K('<threat>')} ${D('[with')} ${K('<control>')}${D('] [: description]')}`);
172
+ console.log(` ${V('@mitigates')} ${K('<asset>')} ${D('against')} ${K('<threat>')} ${D('[using')} ${K('<control>')}${D(']')} ${D('[-- "description"]')}`);
170
173
  console.log(D(' Mark that a control mitigates a threat on an asset.'));
171
174
  console.log(D(' Closes the exposure — removes it from open findings.'));
172
- console.log(EX(' // @mitigates api.auth against SQL Injection with Input Validation'));
173
- console.log(EX(' // @mitigates db.users against Token Theft : Rotation implemented in v2'));
175
+ console.log(D(' "using" is the primary keyword; "with" also accepted.'));
176
+ console.log(EX(' // @mitigates api.auth against SQL Injection using Input Validation'));
177
+ console.log(EX(' // @mitigates db.users against Token Theft -- "Rotation implemented in v2"'));
174
178
  console.log('');
175
- console.log(` ${V('@accepts')} ${K('<threat>')} ${D('on')} ${K('<asset>')} ${D('[: reason]')}`);
179
+ console.log(` ${V('@accepts')} ${K('<threat>')} ${D('on')} ${K('<asset>')} ${D('[-- "reason"]')}`);
176
180
  console.log(D(' Explicitly accept a risk. Removes it from open findings.'));
177
181
  console.log(D(' Use when the risk is known and intentionally not mitigated.'));
178
- console.log(EX(' // @accepts Timing Attack on api.auth : Acceptable for current threat model'));
182
+ console.log(EX(' // @accepts Timing Attack on api.auth -- "Acceptable for current threat model"'));
179
183
  console.log('');
180
- console.log(` ${V('@transfers')} ${K('<threat>')} ${D('from')} ${K('<source>')} ${D('to')} ${K('<target>')} ${D('[: description]')}`);
184
+ console.log(` ${V('@transfers')} ${K('<threat>')} ${D('from')} ${K('<source>')} ${D('to')} ${K('<target>')} ${D('[-- "description"]')}`);
181
185
  console.log(D(' Transfer responsibility for a threat to another asset/team.'));
182
- console.log(EX(' // @transfers DDoS from api.gateway to cdn.cloudflare : Handled by CDN layer'));
186
+ console.log(EX(' // @transfers DDoS from api.gateway to cdn.cloudflare -- "Handled by CDN layer"'));
183
187
  console.log('');
184
188
  // ── DATA FLOWS ────────────────────────────────────────────────────
185
189
  console.log(H(' ── Data Flows & Boundaries ─────────────────────────────────'));
186
190
  console.log('');
187
- console.log(` ${V('@flows')} ${K('<source>')} ${D('to')} ${K('<target>')} ${D('[via')} ${K('<mechanism>')}${D('] [: description]')}`);
191
+ console.log(` ${V('@flows')} ${K('<source>')} ${D('->')} ${K('<target>')} ${D('[via')} ${K('<mechanism>')}${D(']')} ${D('[-- "description"]')}`);
188
192
  console.log(D(' Document data movement between components.'));
189
193
  console.log(D(' Appears in the Data Flow Diagram.'));
190
- console.log(EX(' // @flows api.auth to db.users via TLS 1.3'));
191
- console.log(EX(' // @flows mobile.app to api.gateway via HTTPS : User credentials'));
194
+ console.log(EX(' // @flows api.auth -> db.users via TLS 1.3'));
195
+ console.log(EX(' // @flows mobile.app -> api.gateway via HTTPS -- "User credentials"'));
192
196
  console.log('');
193
- console.log(` ${V('@boundary')} ${K('<asset_a>')} ${D('and')} ${K('<asset_b>')} ${D('[: description]')}`);
197
+ console.log(` ${V('@boundary')} ${K('<asset_a>')} ${D('and')} ${K('<asset_b>')} ${D('(#id)')} ${D('[-- "description"]')}`);
194
198
  console.log(D(' Declare a trust boundary between two assets.'));
195
199
  console.log(D(' Groups assets in the Data Flow Diagram.'));
196
- console.log(EX(' // @boundary internet and api.gateway : Public-facing edge'));
197
- console.log(EX(' // @boundary api.gateway and db.users : Internal network boundary'));
200
+ console.log(D(' Alternate: @boundary between A and B or @boundary A | B'));
201
+ console.log(EX(' // @boundary internet and api.gateway (#edge) -- "Public-facing edge"'));
202
+ console.log(EX(' // @boundary api.gateway | db.users -- "Internal network boundary"'));
198
203
  console.log('');
199
204
  // ── LIFECYCLE ─────────────────────────────────────────────────────
200
205
  console.log(H(' ── Lifecycle & Governance ──────────────────────────────────'));
201
206
  console.log('');
202
- console.log(` ${V('@handles')} ${K('<classification>')} ${D('on')} ${K('<asset>')} ${D('[: description]')}`);
207
+ console.log(` ${V('@handles')} ${K('<classification>')} ${D('on')} ${K('<asset>')} ${D('[-- "description"]')}`);
203
208
  console.log(D(' Declare data classification handled by an asset.'));
204
209
  console.log(D(' Classifications: pii phi financial secrets internal public'));
205
- console.log(EX(' // @handles pii on db.users : Stores name, email, phone'));
210
+ console.log(EX(' // @handles pii on db.users -- "Stores name, email, phone"'));
206
211
  console.log(EX(' // @handles secrets on api.auth.token_store'));
207
212
  console.log('');
208
- console.log(` ${V('@owns')} ${K('<owner>')} ${K('<asset>')} ${D('[: description]')}`);
213
+ console.log(` ${V('@owns')} ${K('<owner>')} ${D('for')} ${K('<asset>')} ${D('[-- "description"]')}`);
209
214
  console.log(D(' Assign ownership of an asset to a team or person.'));
210
- console.log(EX(' // @owns platform-team api.auth'));
215
+ console.log(EX(' // @owns platform-team for api.auth'));
211
216
  console.log('');
212
- console.log(` ${V('@validates')} ${K('<control>')} ${D('on')} ${K('<asset>')} ${D('[: description]')}`);
217
+ console.log(` ${V('@validates')} ${K('<control>')} ${D('for')} ${K('<asset>')} ${D('[-- "description"]')}`);
213
218
  console.log(D(' Assert that a control has been validated/tested on an asset.'));
214
- console.log(EX(' // @validates Input Validation on api.auth : Pen-tested 2024-Q3'));
219
+ console.log(EX(' // @validates Input Validation for api.auth -- "Pen-tested 2024-Q3"'));
215
220
  console.log('');
216
- console.log(` ${V('@audit')} ${K('<asset>')} ${D('[: description]')}`);
221
+ console.log(` ${V('@audit')} ${K('<asset>')} ${D('[-- "description"]')}`);
217
222
  console.log(D(' Mark that this code path is an audit trail point.'));
218
- console.log(EX(' // @audit db.users : All writes logged to audit_log table'));
223
+ console.log(EX(' // @audit db.users -- "All writes logged to audit_log table"'));
219
224
  console.log('');
220
- console.log(` ${V('@assumes')} ${K('<asset>')} ${D('[: description]')}`);
225
+ console.log(` ${V('@assumes')} ${K('<asset>')} ${D('[-- "description"]')}`);
221
226
  console.log(D(' Document a security assumption about an asset.'));
222
- console.log(EX(' // @assumes api.gateway : Upstream WAF filters malformed requests'));
227
+ console.log(EX(' // @assumes api.gateway -- "Upstream WAF filters malformed requests"'));
223
228
  console.log('');
224
- console.log(` ${V('@comment')} ${D('[: description]')}`);
229
+ console.log(` ${V('@comment')} ${D('[-- "description"]')}`);
225
230
  console.log(D(' Free-form developer security note (no structural effect).'));
226
- console.log(EX(' // @comment : TODO — add rate limiting before v2 launch'));
231
+ console.log(EX(' // @comment -- "TODO — add rate limiting before v2 launch"'));
227
232
  console.log('');
228
233
  // ── SHIELD BLOCKS ─────────────────────────────────────────────────
229
234
  console.log(H(' ── Shield Blocks ───────────────────────────────────────────'));
230
235
  console.log('');
236
+ console.log(` ${V('@shield')} ${D('[-- "reason"]')}`);
237
+ console.log(D(' Single-line marker for a security-sensitive code point.'));
238
+ console.log(EX(' // @shield -- "Crypto key derivation — do not refactor without review"'));
239
+ console.log('');
231
240
  console.log(` ${V('@shield:begin')} ${D('/')} ${V('@shield:end')}`);
232
241
  console.log(D(' Wrap a code block to mark it as security-sensitive.'));
233
242
  console.log(D(' GuardLink will flag unannotated symbols inside the block.'));
234
- console.log(EX(' // @shield:begin'));
243
+ console.log(EX(' // @shield:begin -- "Auth verification block"'));
235
244
  console.log(EX(' function verifyToken(token: string) { ... }'));
236
245
  console.log(EX(' // @shield:end'));
237
246
  console.log('');
247
+ // ── EXTERNAL REFERENCES ─────────────────────────────────────────
248
+ console.log(H(' ── External References ─────────────────────────────────────'));
249
+ console.log('');
250
+ console.log(D(' Append space-separated refs after severity on @threat and @exposes:'));
251
+ console.log(EX(' cwe:CWE-89 owasp:A03:2021 capec:CAPEC-66 attack:T1190'));
252
+ console.log('');
253
+ console.log(D(' Example:'));
254
+ console.log(EX(' // @exposes api.auth to SQL Injection [high] cwe:CWE-89 owasp:A03:2021'));
255
+ console.log('');
238
256
  // ── TIPS ──────────────────────────────────────────────────────────
239
257
  console.log(H(' ── Tips ────────────────────────────────────────────────────'));
240
258
  console.log('');
259
+ console.log(D(' • Descriptions use -- "quoted text" format (not : colon)'));
260
+ console.log(D(' • Severity uses brackets: [critical] [high] [medium] [low] or [P0]-[P3]'));
241
261
  console.log(D(' • Annotations work in any comment style: // /* # -- <!-- -->'));
242
262
  console.log(D(' • Place annotations on the line ABOVE the code they describe'));
243
263
  console.log(D(' • Asset names are case-insensitive and normalized (spaces→underscores)'));
244
264
  console.log(D(' • Threat/control names can reference IDs with #id syntax'));
265
+ console.log(D(' • @flows uses -> arrow syntax (not "to")'));
245
266
  console.log(D(' • Run /parse after adding annotations to update the threat model'));
246
267
  console.log(D(' • Run /validate to check for syntax errors and dangling references'));
247
268
  console.log(D(' • Run /annotate to have an AI agent add annotations automatically'));
@@ -1273,10 +1294,15 @@ export function cmdThreatReports(ctx) {
1273
1294
  }
1274
1295
  // ─── /annotate ───────────────────────────────────────────────────────
1275
1296
  export async function cmdAnnotate(args, ctx) {
1276
- const { agent: flagAgent, cleanArgs } = parseAgentFlag(args);
1297
+ const { mode: annotationMode, cleanArgs: argsWithoutMode, error: modeError } = parseAnnotationModeFlag(args);
1298
+ if (modeError) {
1299
+ console.log(C.warn(` ${modeError}`));
1300
+ return;
1301
+ }
1302
+ const { agent: flagAgent, cleanArgs } = parseAgentFlag(argsWithoutMode);
1277
1303
  if (!cleanArgs.trim()) {
1278
- console.log(C.warn(' Usage: /annotate <prompt> [--claude-code|--codex|--gemini|--cursor|--windsurf|--clipboard]'));
1279
- console.log(C.dim(' Example: /annotate "annotate auth endpoints for OWASP Top 10" --claude-code'));
1304
+ console.log(C.warn(' Usage: /annotate <prompt> [--mode inline|external] [--claude-code|--codex|--gemini|--cursor|--windsurf|--clipboard]'));
1305
+ console.log(C.dim(' Example: /annotate "annotate auth endpoints for OWASP Top 10" --mode external --claude-code'));
1280
1306
  return;
1281
1307
  }
1282
1308
  console.log('');
@@ -1285,7 +1311,7 @@ export async function cmdAnnotate(args, ctx) {
1285
1311
  if (!agent)
1286
1312
  return;
1287
1313
  // Build context prompt using shared builder
1288
- const prompt = buildAnnotatePrompt(cleanArgs.trim(), ctx.root, ctx.model);
1314
+ const prompt = buildAnnotatePrompt(cleanArgs.trim(), ctx.root, ctx.model, annotationMode);
1289
1315
  // For terminal agents: foreground spawn (agent takes over terminal)
1290
1316
  if (agent.cmd) {
1291
1317
  const copied = copyToClipboard(prompt);
@@ -1540,7 +1566,7 @@ export async function cmdReview(args, ctx) {
1540
1566
  console.log(` ${C.success('✓')} Marked for remediation — ${result.linesInserted} line(s) written\n`);
1541
1567
  }
1542
1568
  else {
1543
- results.push({ exposure: reviewable, action: { decision: 'skip', justification: '' }, linesInserted: 0 });
1569
+ results.push({ exposure: reviewable, action: { decision: 'skip', justification: '' }, linesInserted: 0, targetFile: reviewable.exposure.location.file });
1544
1570
  console.log(` ${C.dim('— Skipped')}\n`);
1545
1571
  }
1546
1572
  }