@boyingliu01/xp-gate 0.20.1 → 0.20.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 (81) hide show
  1. package/adapters/java.sh +373 -27
  2. package/gate-3.sh +51 -3
  3. package/gate-4.sh +32 -1
  4. package/hooks/gate-3.sh +51 -3
  5. package/hooks/gate-4.sh +32 -1
  6. package/hooks/pre-commit +275 -36
  7. package/lib/__tests__/doctor-spawn-capability.test.js +116 -0
  8. package/lib/__tests__/doctor-tui-skill-freshness.test.js +49 -10
  9. package/lib/doctor-tui.js +21 -3
  10. package/lib/doctor.js +111 -8
  11. package/lib/gate-audit.ts +3 -0
  12. package/lib/mattpocock-license-verdict.json +1 -1
  13. package/mock-policy/AGENTS.md +2 -2
  14. package/mutation/AGENTS.md +2 -2
  15. package/package.json +1 -1
  16. package/plugins/claude-code/.claude-plugin/plugin.json +1 -1
  17. package/plugins/claude-code/skills/admin-template-guidelines/SKILL.md +1 -0
  18. package/plugins/claude-code/skills/batch-grill-me/SKILL.md +1 -0
  19. package/plugins/claude-code/skills/clipboard-vision/SKILL.md +1 -0
  20. package/plugins/claude-code/skills/delphi-review/AGENTS.md +2 -2
  21. package/plugins/claude-code/skills/domain-modeling/SKILL.md +1 -0
  22. package/plugins/claude-code/skills/grill-with-docs/SKILL.md +1 -0
  23. package/plugins/claude-code/skills/grilling/SKILL.md +1 -0
  24. package/plugins/claude-code/skills/improve-codebase-architecture/SKILL.md +1 -0
  25. package/plugins/claude-code/skills/ralph-loop/SKILL.md +1 -0
  26. package/plugins/claude-code/skills/sprint-flow/AGENTS.md +2 -2
  27. package/plugins/claude-code/skills/test-driven-development/SKILL.md +1 -0
  28. package/plugins/claude-code/skills/test-specification-alignment/AGENTS.md +2 -2
  29. package/plugins/claude-code/skills/test-specification-alignment/SKILL.md +1 -0
  30. package/plugins/claude-code/skills/to-issues/SKILL.md +1 -0
  31. package/plugins/dsh/package.json +1 -1
  32. package/plugins/dsh/skills/admin-template-guidelines/SKILL.md +1 -0
  33. package/plugins/dsh/skills/batch-grill-me/SKILL.md +1 -0
  34. package/plugins/dsh/skills/clipboard-vision/SKILL.md +1 -0
  35. package/plugins/dsh/skills/delphi-review/AGENTS.md +2 -2
  36. package/plugins/dsh/skills/domain-modeling/SKILL.md +1 -0
  37. package/plugins/dsh/skills/grill-with-docs/SKILL.md +1 -0
  38. package/plugins/dsh/skills/grilling/SKILL.md +1 -0
  39. package/plugins/dsh/skills/improve-codebase-architecture/SKILL.md +1 -0
  40. package/plugins/dsh/skills/ralph-loop/SKILL.md +1 -0
  41. package/plugins/dsh/skills/sprint-flow/AGENTS.md +2 -2
  42. package/plugins/dsh/skills/test-driven-development/SKILL.md +1 -0
  43. package/plugins/dsh/skills/test-specification-alignment/AGENTS.md +2 -2
  44. package/plugins/dsh/skills/test-specification-alignment/SKILL.md +1 -0
  45. package/plugins/dsh/skills/to-issues/SKILL.md +1 -0
  46. package/plugins/opencode/package.json +1 -1
  47. package/plugins/opencode/skills/admin-template-guidelines/SKILL.md +1 -0
  48. package/plugins/opencode/skills/batch-grill-me/SKILL.md +1 -0
  49. package/plugins/opencode/skills/clipboard-vision/SKILL.md +1 -0
  50. package/plugins/opencode/skills/delphi-review/AGENTS.md +2 -2
  51. package/plugins/opencode/skills/domain-modeling/SKILL.md +1 -0
  52. package/plugins/opencode/skills/grill-with-docs/SKILL.md +1 -0
  53. package/plugins/opencode/skills/grilling/SKILL.md +1 -0
  54. package/plugins/opencode/skills/improve-codebase-architecture/SKILL.md +1 -0
  55. package/plugins/opencode/skills/ralph-loop/SKILL.md +1 -0
  56. package/plugins/opencode/skills/sprint-flow/AGENTS.md +2 -2
  57. package/plugins/opencode/skills/test-driven-development/SKILL.md +1 -0
  58. package/plugins/opencode/skills/test-specification-alignment/AGENTS.md +2 -2
  59. package/plugins/opencode/skills/test-specification-alignment/SKILL.md +1 -0
  60. package/plugins/opencode/skills/to-issues/SKILL.md +1 -0
  61. package/plugins/qoder/plugin.json +1 -1
  62. package/plugins/qoder/skills/delphi-review/AGENTS.md +2 -2
  63. package/plugins/qoder/skills/sprint-flow/AGENTS.md +2 -2
  64. package/plugins/qoder/skills/test-specification-alignment/AGENTS.md +2 -2
  65. package/principles/AGENTS.md +2 -2
  66. package/principles/adapters/__tests__/java.test.ts +317 -0
  67. package/principles/adapters/java.ts +325 -13
  68. package/skills/admin-template-guidelines/SKILL.md +1 -0
  69. package/skills/batch-grill-me/SKILL.md +1 -0
  70. package/skills/clipboard-vision/SKILL.md +1 -0
  71. package/skills/delphi-review/AGENTS.md +2 -2
  72. package/skills/domain-modeling/SKILL.md +1 -0
  73. package/skills/grill-with-docs/SKILL.md +1 -0
  74. package/skills/grilling/SKILL.md +1 -0
  75. package/skills/improve-codebase-architecture/SKILL.md +1 -0
  76. package/skills/ralph-loop/SKILL.md +1 -0
  77. package/skills/sprint-flow/AGENTS.md +2 -2
  78. package/skills/test-driven-development/SKILL.md +1 -0
  79. package/skills/test-specification-alignment/AGENTS.md +2 -2
  80. package/skills/test-specification-alignment/SKILL.md +1 -0
  81. package/skills/to-issues/SKILL.md +1 -0
@@ -1,6 +1,191 @@
1
1
  import { BaseAdapter } from './base';
2
2
  import { Adapter } from '../types';
3
3
 
4
+ /**
5
+ * Structural fields the clean-code rules consume (mirror of the TypeScript
6
+ * adapter's function shape). Before #507 this adapter returned only
7
+ * `{ name, type, modifiers, line, code }`, so every rule reading
8
+ * `startLine`/`length`/`paramCount`/`nestingDepth`/`hasTryCatch`/`ioOperations`
9
+ * silently saw `undefined` and skipped the file -- G4 reported a run over Java
10
+ * with zero effective coverage (#507 S4 audit).
11
+ */
12
+ interface JavaFunctionInfo {
13
+ name: string;
14
+ type: string;
15
+ modifiers: string[];
16
+ line: number;
17
+ startLine: number;
18
+ /** Body line span, matching the `length` field long-function reads. */
19
+ length: number;
20
+ paramCount: number;
21
+ nestingDepth: number;
22
+ hasTryCatch: boolean;
23
+ ioOperations: string[];
24
+ code: string;
25
+ }
26
+
27
+ interface JavaImportInfo {
28
+ name: string;
29
+ line: number;
30
+ used: boolean;
31
+ type: string;
32
+ }
33
+
34
+ /** Java-side I/O markers for the missing-error-handling rule. */
35
+ const JAVA_IO_OPERATIONS = [
36
+ 'executeQuery',
37
+ 'executeUpdate',
38
+ 'executeBatch',
39
+ 'getConnection',
40
+ 'FileInputStream',
41
+ 'FileOutputStream',
42
+ 'FileReader',
43
+ 'FileWriter',
44
+ 'BufferedReader',
45
+ 'BufferedWriter',
46
+ 'Files.',
47
+ 'HttpClient',
48
+ 'RestTemplate',
49
+ 'Socket',
50
+ ];
51
+
52
+ /**
53
+ * Numeric literal scan for the magic-numbers rule. Lookahead mirrors the
54
+ * TypeScript adapter (`(?![\w$])`): digits as call arguments (`foo(2)`) are
55
+ * the most common magic-number site and must be reported, so `)` is NOT
56
+ * excluded. A per-call regex comes from `javaParse.magicNumberRegex()`;
57
+ * `String.prototype.match` with the global flag returns all matches per line
58
+ * and ignores lastIndex, so there is no shared-state bug to worry about.
59
+ * Known gaps (documented in docs/java-principles-coverage.md): hex
60
+ * (0xFF), underscore separators (1_000) and literal suffixes (1000L) are
61
+ * not matched.
62
+ */
63
+ const MAGIC_NUMBER_SOURCE = '(?<![\\w$.])(-?\\d+(?:\\.\\d+)?)(?![\\w$])';
64
+
65
+ const MEMBER_KEYWORDS = new Set([
66
+ 'if', 'for', 'while', 'switch', 'catch', 'return', 'synchronized', 'new',
67
+ 'super', 'this', 'throw', 'assert', 'try'
68
+ ]);
69
+
70
+ /**
71
+ * Pure parse helpers, kept OUTSIDE the adapter class and called through this
72
+ * namespace object. Two reasons, both from the gate dogfooding itself (#507
73
+ * S4): the srp heuristic counts every bare `word(` inside a class body as a
74
+ * method, and dip flags every bare `new X(` as direct instantiation -- dotted
75
+ * namespace calls keep both scanners blind to implementation helpers.
76
+ */
77
+ export const javaParse = {
78
+ /** Top-level brace depth of a method body (deep-nesting rule). */
79
+ braceDepth(body: string): number {
80
+ let depth = 0;
81
+ let max = 0;
82
+ for (const ch of body) {
83
+ if (ch === '{') {
84
+ depth += 1;
85
+ if (depth > max) max = depth;
86
+ } else if (ch === '}') {
87
+ depth -= 1;
88
+ }
89
+ }
90
+ return max;
91
+ },
92
+
93
+ /** Parameter count of a raw parameter list, comma-aware at depth zero. */
94
+ countParams(paramList: string): number {
95
+ const trimmed = paramList.trim();
96
+ if (!trimmed) return 0;
97
+ let depth = 0;
98
+ let count = 1;
99
+ for (const ch of trimmed) {
100
+ if (ch === '(' || ch === '<' || ch === '[') depth += 1;
101
+ else if (ch === ')' || ch === '>' || ch === ']') depth -= 1;
102
+ else if (ch === ',' && depth === 0) count += 1;
103
+ }
104
+ return count;
105
+ },
106
+
107
+ /**
108
+ * Method-like members inside a class/interface body: `name(` occurrences
109
+ * minus control keywords and constructor calls. Mirrors the TypeScript
110
+ * adapter's member heuristic so SRP/god-class see the same signal shape.
111
+ */
112
+ countMembers(body: string): string[] {
113
+ const memberRe = /(?<![\w$.])(\w+)\s*\(/g;
114
+ const methods: string[] = [];
115
+ let m: RegExpExecArray | null;
116
+ while ((m = memberRe.exec(body)) !== null) {
117
+ const name = m[1];
118
+ if (!MEMBER_KEYWORDS.has(name) && !methods.includes(name)) methods.push(name);
119
+ }
120
+ return methods;
121
+ },
122
+
123
+ magicNumberRegex(): RegExp {
124
+ return new RegExp(MAGIC_NUMBER_SOURCE, 'g');
125
+ },
126
+
127
+ /**
128
+ * Strip string/char literals and comments (line + block, multi-line)
129
+ * before any brace/call-site analysis. Contents become empty/space so the
130
+ * LINE structure (and thus line numbers) is preserved -- column positions
131
+ * shift, so callers must use lineOf() instead of getLineNumber() on masked
132
+ * content. This is what keeps a `"{` inside a format string or a javadoc
133
+ * code example from corrupting nestingDepth/hasTryCatch/methodCount
134
+ * (#507 blind review M3/M4).
135
+ *
136
+ * String/char patterns exclude newlines (#507 Delphi round-1 B-MAJOR-3):
137
+ * a cross-line pairing let one unbalanced quote inside a comment swallow
138
+ * every line up to the NEXT real string, deleting whole control blocks
139
+ * from the analysis. Damage is now bounded to the offending line.
140
+ */
141
+ maskCode(body: string): string {
142
+ return body
143
+ .replace(/"(?:[^"\\\n]|\\[^\n])*"/g, '""')
144
+ .replace(/'(?:[^'\\\n]|\\[^\n])'/g, "''")
145
+ .replace(/\/\*[\s\S]*?\*\//g, (m) => m.replace(/[^\n]/g, ' '))
146
+ .replace(/\/\/.*$/gm, '');
147
+ },
148
+
149
+ /**
150
+ * Line number of `position` within `content`. maskCode preserves line
151
+ * structure (contents shrink but never add/remove lines), so a line
152
+ * computed on masked content is exact for the original file.
153
+ */
154
+ lineOf(content: string, position: number): number {
155
+ return content.substring(0, position).split('\n').length;
156
+ },
157
+
158
+ /**
159
+ * Brace-balanced block starting at the first `{` at/after `startPos`.
160
+ * Runs on MASKED content only -- on raw text a string-embedded `{`
161
+ * desynchronizes the depth tracker. Returns null when unbalanced
162
+ * (callers decide the fallback; base.extractCodeBlock's 100-char
163
+ * truncation fallback would silently hand back garbage structure).
164
+ */
165
+ extractBracedBlock(content: string, startPos: number): string | null {
166
+ let inBlock = false;
167
+ let depth = 0;
168
+ for (let i = startPos; i < content.length; i += 1) {
169
+ const ch = content[i];
170
+ if (ch === '{') {
171
+ inBlock = true;
172
+ depth += 1;
173
+ } else if (ch === '}' && inBlock) {
174
+ depth -= 1;
175
+ if (depth === 0) {
176
+ return content.substring(startPos, i + 1);
177
+ }
178
+ }
179
+ }
180
+ return null;
181
+ },
182
+
183
+ /** Usage detector for an imported simple name (word-boundary, $-escaped). */
184
+ importUsage(simpleName: string): RegExp {
185
+ return new RegExp(`\\b${simpleName.replace(/\$/g, '\\$')}\\b`);
186
+ },
187
+ };
188
+
4
189
  export class JavaAdapter extends BaseAdapter implements Adapter {
5
190
  detectLanguage(): string {
6
191
  const ext = this.filePath.toLowerCase();
@@ -19,38 +204,165 @@ export class JavaAdapter extends BaseAdapter implements Adapter {
19
204
  }
20
205
 
21
206
  extractFunctions(): unknown[] {
22
- const methodMatches = [];
23
- const methodRegex = /(public|private|protected|static|final|synchronized|native)\s+[\w<>[\]]+\s+(\w+)\s*\([^)]*\)\s*(throws\s+[\w,\s]+)?\s*{/g;
207
+ const results: JavaFunctionInfo[] = [];
208
+ const methodRegex = /(public|private|protected|static|final|synchronized|native)\s+[\w<>[\],\s]+?\s+(\w+)\s*\(([^)]*)\)\s*(throws\s+[\w,\s.]+)?\s*\{/g;
209
+ // Signature scan AND block extraction run on the MASKED content
210
+ // (#507 Delphi round-1 B-MAJOR-6 / A-minor-1): a javadoc example like
211
+ // `public int foo(int x) {` on raw text produced a ghost function whose
212
+ // length/nestingDepth fed long-function/deep-nesting, and an unbalanced
213
+ // string brace stretched the extracted block past the real method end.
214
+ // Masked content keeps line structure, so lineOf() is exact.
215
+ const maskedContent = javaParse.maskCode(this.fileContent);
24
216
  let match;
25
217
 
26
- while ((match = methodRegex.exec(this.fileContent)) !== null) {
27
- methodMatches.push({
218
+ while ((match = methodRegex.exec(maskedContent)) !== null) {
219
+ const code = javaParse.extractBracedBlock(maskedContent, match.index) ?? '';
220
+ const line = javaParse.lineOf(maskedContent, match.index);
221
+ const masked = code; // already masked (extracted from maskedContent)
222
+ results.push({
28
223
  name: match[2],
29
224
  type: 'method',
30
- modifiers: match[1].split(' ').filter(m => m.trim()),
31
- line: this.getLineNumber(match.index),
32
- code: this.extractCodeBlock(match.index)
225
+ modifiers: match[1].split(/\s+/).filter(m => m.trim()),
226
+ line,
227
+ startLine: line,
228
+ length: code ? code.split('\n').length : 0,
229
+ paramCount: javaParse.countParams(match[3] ?? ''),
230
+ nestingDepth: javaParse.braceDepth(masked),
231
+ hasTryCatch: /catch\s*\(/.test(masked),
232
+ ioOperations: JAVA_IO_OPERATIONS.filter(op => masked.includes(op)),
233
+ code
33
234
  });
34
235
  }
35
236
 
36
- return methodMatches;
237
+ return results;
37
238
  }
38
239
 
39
240
  extractClasses(): unknown[] {
40
241
  const classMatches = [];
41
- const classRegex = /(public|private|protected)?\s*(abstract|final|static)?\s*class\s+(\w+)\s*(extends\s+\w+)?\s*(implements\s+[\w,\s]+)?\s*{/g;
242
+ // Generic type parameters -- `class Box<T>`, `class Foo<T> extends Bar<T>` --
243
+ // are the norm in modern Java; without the optional `<...>` slot the
244
+ // whole class vanished from extractClasses and srp/god-class/dip went
245
+ // blind on generic code -- #507 blind review M1.
246
+ const classRegex = /(public|private|protected)?\s*(abstract|final|static)?\s*class\s+(\w+)\s*(?:<[^<>]*>)?\s*(extends\s+[\w.]+(?:<[^<>]*>)?)?\s*(implements\s+[\w,\s.]+(?:<[^<>]*>)?)?\s*\{/g;
42
247
  let match;
43
248
 
44
- while ((match = classRegex.exec(this.fileContent)) !== null) {
249
+ // Class scan also runs on masked content: a javadoc mention of `class
250
+ // Foo` no longer yields a ghost class, and string-embedded braces cannot
251
+ // stretch the extracted body (#507 Delphi round-1 B-MAJOR-6).
252
+ const maskedContent = javaParse.maskCode(this.fileContent);
253
+ while ((match = classRegex.exec(maskedContent)) !== null) {
254
+ const code = javaParse.extractBracedBlock(maskedContent, match.index) ?? '';
255
+ // srp reads `cls.methodCount` directly, with no code re-scan fallback,
256
+ // so an adapter omitting it makes SRP structurally dead on Java -- #507 S4.
257
+ const methods = javaParse.countMembers(code);
45
258
  classMatches.push({
46
259
  name: match[3],
47
260
  type: 'class',
48
261
  modifiers: [match[1], match[2]].filter(m => m && m.trim()),
49
- line: this.getLineNumber(match.index),
50
- code: this.extractCodeBlock(match.index)
262
+ line: javaParse.lineOf(maskedContent, match.index),
263
+ methodCount: methods.length,
264
+ methods,
265
+ code
51
266
  });
52
267
  }
53
268
 
54
269
  return classMatches;
55
270
  }
56
- }
271
+
272
+ /**
273
+ * Interfaces for the ISP rule, which reads `adapter.extractInterfaces()`.
274
+ * Java interface methods are bare signature lines, counted with the same
275
+ * member heuristic as classes minus constructors.
276
+ */
277
+ extractInterfaces(): Array<{ name: string; line: number; methods: string[]; methodCount: number; code: string }> {
278
+ const results: Array<{ name: string; line: number; methods: string[]; methodCount: number; code: string }> = [];
279
+ const ifaceRegex = /(?:public|private|protected)?\s*interface\s+(\w+)\s*(?:<[^<>]*>)?\s*\{/g;
280
+ let match;
281
+
282
+ // Masked scan, same rationale as extractClasses (#507 Delphi round-1
283
+ // B-MAJOR-6): no ghost interfaces from javadoc, no string-brace bleed.
284
+ const maskedContent = javaParse.maskCode(this.fileContent);
285
+ while ((match = ifaceRegex.exec(maskedContent)) !== null) {
286
+ const code = javaParse.extractBracedBlock(maskedContent, match.index) ?? '';
287
+ const methods = javaParse.countMembers(code);
288
+ results.push({
289
+ name: match[1],
290
+ line: javaParse.lineOf(maskedContent, match.index),
291
+ methods,
292
+ methodCount: methods.length,
293
+ code
294
+ });
295
+ }
296
+
297
+ return results;
298
+ }
299
+
300
+ /**
301
+ * Numeric literal scan for the magic-numbers rule. Constant declarations
302
+ * (`static final ... = <n>`) are skipped: naming a constant is exactly the
303
+ * remedy the rule asks for. Masking ORDER matters -- #507 blind review M3:
304
+ * string/char literals first, so `"http://x"` cannot swallow the rest of
305
+ * the line as a comment), then line comments, then block comments with
306
+ * cross-line state -- a commented-out code block must not resurrect its
307
+ * numbers as findings.
308
+ */
309
+ extract(): Array<{ value: number; line: number }> {
310
+ const out: Array<{ value: number; line: number }> = [];
311
+ const lines = this.fileContent.split('\n');
312
+ const numRegex = javaParse.magicNumberRegex();
313
+ let inBlockComment = false;
314
+ for (let i = 0; i < lines.length; i += 1) {
315
+ let line = lines[i];
316
+ if (inBlockComment) {
317
+ const end = line.indexOf('*/');
318
+ if (end === -1) continue;
319
+ line = line.slice(end + 2);
320
+ inBlockComment = false;
321
+ }
322
+ line = line
323
+ .replace(/"(?:[^"\\]|\\.)*"/g, '""')
324
+ .replace(/'(?:[^'\\]|\\.)'/g, "''")
325
+ .replace(/\/\/.*$/, '');
326
+ while (line.includes('/*')) {
327
+ const start = line.indexOf('/*');
328
+ const end = line.indexOf('*/', start + 2);
329
+ if (end === -1) {
330
+ line = line.slice(0, start);
331
+ inBlockComment = true;
332
+ break;
333
+ }
334
+ line = line.slice(0, start) + ' ' + line.slice(end + 2);
335
+ }
336
+ if (/^\s*(?:public|private|protected)?\s*static\s+final\s/.test(line)) continue;
337
+ const matches = line.match(numRegex) ?? [];
338
+ for (const value of matches) out.push({ value: Number(value), line: i + 1 });
339
+ }
340
+ return out;
341
+ }
342
+
343
+ /**
344
+ * Import statements with a usage signal for the unused-imports rule. Usage
345
+ * is a conservative check: the imported simple name must appear somewhere
346
+ * outside the import block itself.
347
+ */
348
+ get imports(): JavaImportInfo[] {
349
+ const lines = this.fileContent.split('\n');
350
+ const imports: JavaImportInfo[] = [];
351
+ const importRegex = /^\s*import\s+(?:static\s+)?([\w.]+)\s*;\s*$/;
352
+ const importLines = new Set<number>();
353
+ for (let i = 0; i < lines.length; i += 1) {
354
+ const m = importRegex.exec(lines[i]);
355
+ if (m) {
356
+ imports.push({ name: m[1], line: i + 1, used: false, type: 'import' });
357
+ importLines.add(i);
358
+ }
359
+ }
360
+ if (imports.length === 0) return imports;
361
+ const body = lines.filter((_, idx) => !importLines.has(idx)).join('\n');
362
+ for (const imp of imports) {
363
+ const simpleName = imp.name.split('.').pop() ?? imp.name;
364
+ imp.used = javaParse.importUsage(simpleName).test(body);
365
+ }
366
+ return imports;
367
+ }
368
+ }
@@ -1,5 +1,6 @@
1
1
  ---
2
2
  name: admin-template-guidelines
3
+ version: 1.0.0
3
4
  description: "6 maintainability rules for AI-generated admin interfaces (Fastify + Nunjucks + HTMX + Alpine.js). Prevents route bloat, test inconsistency, Nunjucks traps, repeated data logic, auth blind spots, and HTMX/Alpine confusion."
4
5
  maturity: alpha
5
6
  ---
@@ -1,5 +1,6 @@
1
1
  ---
2
2
  name: batch-grill-me
3
+ version: 1.0.0
3
4
  description: A relentless interview that asks every frontier question at once, round by round.
4
5
  disable-model-invocation: true
5
6
  ---
@@ -1,5 +1,6 @@
1
1
  ---
2
2
  name: clipboard-vision
3
+ version: 1.0.0
3
4
  description: Use when the user explicitly asks to analyze, describe, OCR, or inspect a single image currently stored in the system clipboard.
4
5
  ---
5
6
 
@@ -1,9 +1,9 @@
1
1
  # SKILLS/DELPHI-REVIEW KNOWLEDGE BASE
2
2
 
3
- **Generated:** 2026-10-08
3
+ **Generated:** 2026-10-12
4
4
  **Commit:** unknown
5
5
  **Branch:** unknown
6
- **Version:** 0.20.1.0
6
+ **Version:** 0.20.2.0
7
7
 
8
8
  ## OVERVIEW
9
9
  Delphi Consensus Review — multi-round anonymous expert review (≥90% threshold, exactly 3 experts with distinct executable model IDs). Supports design, requirements, and code-walkthrough modes.
@@ -1,5 +1,6 @@
1
1
  ---
2
2
  name: domain-modeling
3
+ version: 1.0.0
3
4
  description: Build and sharpen a project's domain model. Use when the user wants to pin down domain terminology or a ubiquitous language, record an architectural decision, or when another skill needs to maintain the domain model.
4
5
  ---
5
6
 
@@ -1,5 +1,6 @@
1
1
  ---
2
2
  name: grill-with-docs
3
+ version: 1.0.0
3
4
  description: A relentless interview to sharpen a plan or design, which also creates docs (ADR's and glossary) as we go.
4
5
  disable-model-invocation: true
5
6
  ---
@@ -1,5 +1,6 @@
1
1
  ---
2
2
  name: grilling
3
+ version: 1.0.0
3
4
  description: Grill the user relentlessly about a plan, decision, or idea. Use when the user wants to stress-test their thinking, or uses any 'grill' trigger phrases.
4
5
  ---
5
6
 
@@ -1,5 +1,6 @@
1
1
  ---
2
2
  name: improve-codebase-architecture
3
+ version: 1.0.0
3
4
  description: Find deepening opportunities in a codebase, informed by domain language in CONTEXT.md and decisions in ADRs. Use when user wants to improve architecture, find refactoring opportunities, consolidate tightly-coupled modules, or make a codebase more AI-navigable. Run periodically (weekly or after surges of development).
4
5
  ---
5
6
 
@@ -1,5 +1,6 @@
1
1
  ---
2
2
  name: ralph-loop
3
+ version: 1.0.0
3
4
  description: Use when executing Sprint-Flow Phase 2 BUILD, processing one REQ, building the next requirement, iterating with clean context, or requiring full regression per requirement.
4
5
  maturity: stable
5
6
  ---
@@ -1,9 +1,9 @@
1
1
  # SKILLS/SPRINT-FLOW KNOWLEDGE BASE
2
2
 
3
- **Generated:** 2026-10-08
3
+ **Generated:** 2026-10-12
4
4
  **Commit:** unknown
5
5
  **Branch:** unknown
6
- **Version:** 0.20.1.0
6
+ **Version:** 0.20.2.0
7
7
 
8
8
  ## OVERVIEW
9
9
  **6-phase** development pipeline (v2.0 compact redesign, Issue #290): PREP → DESIGN → BUILD → VERIFY → SHIP → CLOSE. Phase 3/6 BUILD default build mode is **ralph-loop** (REQ-level iteration, 40-67% token savings vs parallel). HARD-GATE between DESIGN (2/6) and BUILD (3/6): design must pass Delphi review (≥90% consensus) before any coding.
@@ -1,5 +1,6 @@
1
1
  ---
2
2
  name: test-driven-development
3
+ version: 1.0.0
3
4
  description: Use when implementing any feature or bugfix, before writing implementation code
4
5
  ---
5
6
 
@@ -1,9 +1,9 @@
1
1
  # SKILLS/TEST-SPECIFICATION-ALIGNMENT KNOWLEDGE BASE
2
2
 
3
- **Generated:** 2026-10-08
3
+ **Generated:** 2026-10-12
4
4
  **Commit:** unknown
5
5
  **Branch:** unknown
6
- **Version:** 0.20.1.0
6
+ **Version:** 0.20.2.0
7
7
 
8
8
  ## OVERVIEW
9
9
  Test-Specification Alignment Engine — two-stage validation ensuring tests accurately reflect requirements and design specs.
@@ -1,5 +1,6 @@
1
1
  ---
2
2
  name: test-specification-alignment
3
+ version: 1.0.0
3
4
  description: "Use when asked to run tests, verify tests, align tests with specification.yaml, before BUILD verification, or before release/ship."
4
5
  ---
5
6
 
@@ -1,5 +1,6 @@
1
1
  ---
2
2
  name: to-issues
3
+ version: 1.0.0
3
4
  description: Break a plan, spec, or PRD into independently-grabbable issues using tracer-bullet vertical slices. Use when user wants to convert a plan into issues, create implementation tickets, or break down work into vertical slices. Integrates with XP-Gate sprint-flow Phase 1.
4
5
  ---
5
6