faf-cli 4.4.4 → 4.5.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.
Files changed (62) hide show
  1. package/README.md +27 -17
  2. package/dist/cli.d.ts.map +1 -1
  3. package/dist/cli.js +63 -2
  4. package/dist/cli.js.map +1 -1
  5. package/dist/commands/agents.d.ts +14 -0
  6. package/dist/commands/agents.d.ts.map +1 -0
  7. package/dist/commands/agents.js +353 -0
  8. package/dist/commands/agents.js.map +1 -0
  9. package/dist/commands/bi-sync.d.ts +3 -0
  10. package/dist/commands/bi-sync.d.ts.map +1 -1
  11. package/dist/commands/bi-sync.js +38 -0
  12. package/dist/commands/bi-sync.js.map +1 -1
  13. package/dist/commands/cursor.d.ts +13 -0
  14. package/dist/commands/cursor.d.ts.map +1 -0
  15. package/dist/commands/cursor.js +310 -0
  16. package/dist/commands/cursor.js.map +1 -0
  17. package/dist/commands/go.d.ts.map +1 -1
  18. package/dist/commands/go.js +22 -19
  19. package/dist/commands/go.js.map +1 -1
  20. package/dist/commands/taf-log.d.ts +1 -0
  21. package/dist/commands/taf-log.d.ts.map +1 -1
  22. package/dist/commands/taf-log.js +53 -5
  23. package/dist/commands/taf-log.js.map +1 -1
  24. package/dist/commands/taf-stars.d.ts +8 -0
  25. package/dist/commands/taf-stars.d.ts.map +1 -0
  26. package/dist/commands/taf-stars.js +105 -0
  27. package/dist/commands/taf-stars.js.map +1 -0
  28. package/dist/commands/taf.d.ts +1 -0
  29. package/dist/commands/taf.d.ts.map +1 -1
  30. package/dist/commands/taf.js +9 -0
  31. package/dist/commands/taf.js.map +1 -1
  32. package/dist/compiler/faf-compiler.d.ts.map +1 -1
  33. package/dist/compiler/faf-compiler.js +24 -2
  34. package/dist/compiler/faf-compiler.js.map +1 -1
  35. package/dist/github/repo-selector.js +4 -4
  36. package/dist/github/repo-selector.js.map +1 -1
  37. package/dist/taf/index.d.ts +4 -0
  38. package/dist/taf/index.d.ts.map +1 -1
  39. package/dist/taf/index.js +16 -1
  40. package/dist/taf/index.js.map +1 -1
  41. package/dist/taf/star-badge.d.ts +32 -0
  42. package/dist/taf/star-badge.d.ts.map +1 -0
  43. package/dist/taf/star-badge.js +158 -0
  44. package/dist/taf/star-badge.js.map +1 -0
  45. package/dist/taf/star-rating.d.ts +30 -0
  46. package/dist/taf/star-rating.d.ts.map +1 -0
  47. package/dist/taf/star-rating.js +79 -0
  48. package/dist/taf/star-rating.js.map +1 -0
  49. package/dist/taf/test-output-parser.d.ts +42 -0
  50. package/dist/taf/test-output-parser.d.ts.map +1 -0
  51. package/dist/taf/test-output-parser.js +114 -0
  52. package/dist/taf/test-output-parser.js.map +1 -0
  53. package/dist/utils/agents-parser.d.ts +60 -0
  54. package/dist/utils/agents-parser.d.ts.map +1 -0
  55. package/dist/utils/agents-parser.js +325 -0
  56. package/dist/utils/agents-parser.js.map +1 -0
  57. package/dist/utils/cursorrules-parser.d.ts +56 -0
  58. package/dist/utils/cursorrules-parser.d.ts.map +1 -0
  59. package/dist/utils/cursorrules-parser.js +315 -0
  60. package/dist/utils/cursorrules-parser.js.map +1 -0
  61. package/package.json +1 -1
  62. package/project.faf +4 -4
@@ -0,0 +1,158 @@
1
+ "use strict";
2
+ /**
3
+ * TAF Star Badge - SVG Renderer
4
+ *
5
+ * Black block + gold star polygon shapes.
6
+ * npm-safe: direct coordinates, no transform="scale(.1)" trick.
7
+ *
8
+ * Visual: black inverse block + gold fill = premium, classy
9
+ */
10
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
11
+ if (k2 === undefined) k2 = k;
12
+ var desc = Object.getOwnPropertyDescriptor(m, k);
13
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
14
+ desc = { enumerable: true, get: function() { return m[k]; } };
15
+ }
16
+ Object.defineProperty(o, k2, desc);
17
+ }) : (function(o, m, k, k2) {
18
+ if (k2 === undefined) k2 = k;
19
+ o[k2] = m[k];
20
+ }));
21
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
22
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
23
+ }) : function(o, v) {
24
+ o["default"] = v;
25
+ });
26
+ var __importStar = (this && this.__importStar) || (function () {
27
+ var ownKeys = function(o) {
28
+ ownKeys = Object.getOwnPropertyNames || function (o) {
29
+ var ar = [];
30
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
31
+ return ar;
32
+ };
33
+ return ownKeys(o);
34
+ };
35
+ return function (mod) {
36
+ if (mod && mod.__esModule) return mod;
37
+ var result = {};
38
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
39
+ __setModuleDefault(result, mod);
40
+ return result;
41
+ };
42
+ })();
43
+ Object.defineProperty(exports, "__esModule", { value: true });
44
+ exports.renderStarBadgeSvg = renderStarBadgeSvg;
45
+ exports.generateStarBadge = generateStarBadge;
46
+ const fs = __importStar(require("fs"));
47
+ const path = __importStar(require("path"));
48
+ const parser_1 = require("./parser");
49
+ const star_rating_1 = require("./star-rating");
50
+ const GOLD = '#FFB800';
51
+ const DIM = '#555';
52
+ const BG = '#111';
53
+ /**
54
+ * 5-pointed star polygon path centered at (cx, cy) with given radius.
55
+ * Returns an SVG path data string.
56
+ */
57
+ function starPath(cx, cy, outerR, innerR) {
58
+ const points = [];
59
+ for (let i = 0; i < 10; i++) {
60
+ const angle = (Math.PI / 2) + (i * Math.PI / 5);
61
+ const r = i % 2 === 0 ? outerR : innerR;
62
+ const x = cx + r * Math.cos(angle);
63
+ const y = cy - r * Math.sin(angle);
64
+ points.push(`${x.toFixed(1)},${y.toFixed(1)}`);
65
+ }
66
+ return `M${points.join('L')}Z`;
67
+ }
68
+ /**
69
+ * Render star badge SVG — black block with gold stars.
70
+ *
71
+ * @param stars - Star count (0-5, 0.5 increments)
72
+ * @param label - Display text (e.g. "878/878")
73
+ * @param passedCount - Tests passed
74
+ * @param totalCount - Tests total
75
+ */
76
+ function renderStarBadgeSvg(stars, label, passedCount, totalCount) {
77
+ const height = 28;
78
+ const starSize = 8; // outer radius
79
+ const innerSize = 3.5; // inner radius
80
+ const starSpacing = 20;
81
+ const starStartX = 14;
82
+ const starCenterY = height / 2;
83
+ // Calculate widths
84
+ const starsBlockWidth = starStartX + 5 * starSpacing;
85
+ const charWidth = 6.5;
86
+ const textPadding = 8;
87
+ const labelWidth = Math.round(label.length * charWidth + textPadding * 2);
88
+ const totalWidth = starsBlockWidth + labelWidth;
89
+ const ariaLabel = `${stars} out of 5 stars: ${passedCount} of ${totalCount} tests passed`;
90
+ let starsSvg = '';
91
+ for (let i = 0; i < 5; i++) {
92
+ const cx = starStartX + i * starSpacing;
93
+ const d = starPath(cx, starCenterY, starSize, innerSize);
94
+ if (i + 1 <= Math.floor(stars)) {
95
+ // Full star — gold filled
96
+ starsSvg += ` <path d="${d}" fill="${GOLD}"/>\n`;
97
+ }
98
+ else if (i + 0.5 === stars) {
99
+ // Half star — left half gold, right half outline
100
+ const clipId = `half-${i}`;
101
+ starsSvg += ` <defs><clipPath id="${clipId}"><rect x="${cx - starSize}" y="${starCenterY - starSize}" width="${starSize}" height="${starSize * 2}"/></clipPath></defs>\n`;
102
+ starsSvg += ` <path d="${d}" fill="${DIM}" stroke="${DIM}" stroke-width="0.5"/>\n`;
103
+ starsSvg += ` <path d="${d}" fill="${GOLD}" clip-path="url(#${clipId})"/>\n`;
104
+ }
105
+ else {
106
+ // Empty star — dim outline
107
+ starsSvg += ` <path d="${d}" fill="none" stroke="${DIM}" stroke-width="1"/>\n`;
108
+ }
109
+ }
110
+ const textX = starsBlockWidth + labelWidth / 2;
111
+ return `<svg xmlns="http://www.w3.org/2000/svg" width="${totalWidth}" height="${height}" role="img" aria-label="${ariaLabel}">
112
+ <title>${ariaLabel}</title>
113
+ <rect width="${totalWidth}" height="${height}" rx="4" fill="${BG}"/>
114
+ ${starsSvg} <text x="${textX}" y="18" fill="#fff" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" font-size="11" text-anchor="middle">${label}</text>
115
+ </svg>`;
116
+ }
117
+ /**
118
+ * Generate star badge from .taf file.
119
+ */
120
+ function generateStarBadge(options = {}) {
121
+ const tafPath = options.tafPath || path.join(process.cwd(), '.taf');
122
+ try {
123
+ if (!fs.existsSync(tafPath)) {
124
+ // No data — render empty stars
125
+ return {
126
+ success: true,
127
+ svg: renderStarBadgeSvg(0, 'no data', 0, 0),
128
+ rating: { stars: 0, display: '☆☆☆☆☆', label: '0.0 stars' },
129
+ };
130
+ }
131
+ const content = fs.readFileSync(tafPath, 'utf-8');
132
+ const taf = (0, parser_1.parseTAF)(content);
133
+ const rating = (0, star_rating_1.calculateStarRatingFromTAF)(taf);
134
+ if (!rating) {
135
+ return {
136
+ success: true,
137
+ svg: renderStarBadgeSvg(0, 'no data', 0, 0),
138
+ rating: { stars: 0, display: '☆☆☆☆☆', label: '0.0 stars' },
139
+ };
140
+ }
141
+ const latest = taf.test_history[taf.test_history.length - 1];
142
+ const passed = latest.tests.passed;
143
+ const total = latest.tests.total;
144
+ const label = `${passed}/${total}`;
145
+ return {
146
+ success: true,
147
+ svg: renderStarBadgeSvg(rating.stars, label, passed, total),
148
+ rating,
149
+ };
150
+ }
151
+ catch (error) {
152
+ return {
153
+ success: false,
154
+ error: error instanceof Error ? error.message : 'Failed to generate star badge',
155
+ };
156
+ }
157
+ }
158
+ //# sourceMappingURL=star-badge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"star-badge.js","sourceRoot":"","sources":["../../src/taf/star-badge.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * TAF Star Rating - Universal quality signal
3
+ *
4
+ * Pass rate → star count (0-5, 0.5 increments)
5
+ * ★★★★★ is instantly understood by everyone.
6
+ *
7
+ * MCP-portable: pure functions, no side effects
8
+ */
9
+ import { TAFFile } from './types';
10
+ export interface StarRating {
11
+ stars: number;
12
+ display: string;
13
+ label: string;
14
+ }
15
+ /**
16
+ * Calculate star rating from pass rate (0-1)
17
+ */
18
+ export declare function calculateStarRating(passRate: number): StarRating;
19
+ /**
20
+ * Format star count as unicode display string
21
+ *
22
+ * ★ = filled, ½ = half, ☆ = empty
23
+ */
24
+ export declare function formatStarsDisplay(stars: number): string;
25
+ /**
26
+ * Calculate star rating from TAF file data
27
+ * Returns null if no test history
28
+ */
29
+ export declare function calculateStarRatingFromTAF(taf: TAFFile): StarRating | null;
30
+ //# sourceMappingURL=star-rating.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"star-rating.d.ts","sourceRoot":"","sources":["../../src/taf/star-rating.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAElC,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,UAAU,CA4BhE;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAMxD;AAED;;;GAGG;AACH,wBAAgB,0BAA0B,CAAC,GAAG,EAAE,OAAO,GAAG,UAAU,GAAG,IAAI,CAa1E"}
@@ -0,0 +1,79 @@
1
+ "use strict";
2
+ /**
3
+ * TAF Star Rating - Universal quality signal
4
+ *
5
+ * Pass rate → star count (0-5, 0.5 increments)
6
+ * ★★★★★ is instantly understood by everyone.
7
+ *
8
+ * MCP-portable: pure functions, no side effects
9
+ */
10
+ Object.defineProperty(exports, "__esModule", { value: true });
11
+ exports.calculateStarRating = calculateStarRating;
12
+ exports.formatStarsDisplay = formatStarsDisplay;
13
+ exports.calculateStarRatingFromTAF = calculateStarRatingFromTAF;
14
+ /**
15
+ * Calculate star rating from pass rate (0-1)
16
+ */
17
+ function calculateStarRating(passRate) {
18
+ let stars;
19
+ if (passRate >= 1.0) {
20
+ stars = 5.0;
21
+ }
22
+ else if (passRate >= 0.95) {
23
+ stars = 4.5;
24
+ }
25
+ else if (passRate >= 0.85) {
26
+ stars = 4.0;
27
+ }
28
+ else if (passRate >= 0.70) {
29
+ stars = 3.5;
30
+ }
31
+ else if (passRate >= 0.55) {
32
+ stars = 3.0;
33
+ }
34
+ else if (passRate >= 0.40) {
35
+ stars = 2.5;
36
+ }
37
+ else if (passRate >= 0.20) {
38
+ stars = 2.0;
39
+ }
40
+ else if (passRate > 0) {
41
+ stars = 1.0;
42
+ }
43
+ else {
44
+ stars = 0.0;
45
+ }
46
+ return {
47
+ stars,
48
+ display: formatStarsDisplay(stars),
49
+ label: `${stars.toFixed(1)} stars`,
50
+ };
51
+ }
52
+ /**
53
+ * Format star count as unicode display string
54
+ *
55
+ * ★ = filled, ½ = half, ☆ = empty
56
+ */
57
+ function formatStarsDisplay(stars) {
58
+ const full = Math.floor(stars);
59
+ const hasHalf = stars % 1 !== 0;
60
+ const empty = 5 - full - (hasHalf ? 1 : 0);
61
+ return '★'.repeat(full) + (hasHalf ? '½' : '') + '☆'.repeat(empty);
62
+ }
63
+ /**
64
+ * Calculate star rating from TAF file data
65
+ * Returns null if no test history
66
+ */
67
+ function calculateStarRatingFromTAF(taf) {
68
+ if (!taf.test_history || taf.test_history.length === 0) {
69
+ return null;
70
+ }
71
+ // Use latest run
72
+ const latest = taf.test_history[taf.test_history.length - 1];
73
+ if (!latest.tests || latest.tests.total === 0) {
74
+ return null;
75
+ }
76
+ const passRate = latest.tests.passed / latest.tests.total;
77
+ return calculateStarRating(passRate);
78
+ }
79
+ //# sourceMappingURL=star-rating.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"star-rating.js","sourceRoot":"","sources":["../../src/taf/star-rating.ts"],"names":[],"mappings":";AAAA;;;;;;;GAOG;;AAaH,kDA4BC;AAOD,gDAMC;AAMD,gEAaC;AA/DD;;GAEG;AACH,SAAgB,mBAAmB,CAAC,QAAgB;IAClD,IAAI,KAAa,CAAC;IAElB,IAAI,QAAQ,IAAI,GAAG,EAAE,CAAC;QACpB,KAAK,GAAG,GAAG,CAAC;IACd,CAAC;SAAM,IAAI,QAAQ,IAAI,IAAI,EAAE,CAAC;QAC5B,KAAK,GAAG,GAAG,CAAC;IACd,CAAC;SAAM,IAAI,QAAQ,IAAI,IAAI,EAAE,CAAC;QAC5B,KAAK,GAAG,GAAG,CAAC;IACd,CAAC;SAAM,IAAI,QAAQ,IAAI,IAAI,EAAE,CAAC;QAC5B,KAAK,GAAG,GAAG,CAAC;IACd,CAAC;SAAM,IAAI,QAAQ,IAAI,IAAI,EAAE,CAAC;QAC5B,KAAK,GAAG,GAAG,CAAC;IACd,CAAC;SAAM,IAAI,QAAQ,IAAI,IAAI,EAAE,CAAC;QAC5B,KAAK,GAAG,GAAG,CAAC;IACd,CAAC;SAAM,IAAI,QAAQ,IAAI,IAAI,EAAE,CAAC;QAC5B,KAAK,GAAG,GAAG,CAAC;IACd,CAAC;SAAM,IAAI,QAAQ,GAAG,CAAC,EAAE,CAAC;QACxB,KAAK,GAAG,GAAG,CAAC;IACd,CAAC;SAAM,CAAC;QACN,KAAK,GAAG,GAAG,CAAC;IACd,CAAC;IAED,OAAO;QACL,KAAK;QACL,OAAO,EAAE,kBAAkB,CAAC,KAAK,CAAC;QAClC,KAAK,EAAE,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ;KACnC,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,SAAgB,kBAAkB,CAAC,KAAa;IAC9C,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAC/B,MAAM,OAAO,GAAG,KAAK,GAAG,CAAC,KAAK,CAAC,CAAC;IAChC,MAAM,KAAK,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAE3C,OAAO,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AACrE,CAAC;AAED;;;GAGG;AACH,SAAgB,0BAA0B,CAAC,GAAY;IACrD,IAAI,CAAC,GAAG,CAAC,YAAY,IAAI,GAAG,CAAC,YAAY,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,iBAAiB;IACjB,MAAM,MAAM,GAAG,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAC7D,IAAI,CAAC,MAAM,CAAC,KAAK,IAAI,MAAM,CAAC,KAAK,CAAC,KAAK,KAAK,CAAC,EAAE,CAAC;QAC9C,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC;IAC1D,OAAO,mBAAmB,CAAC,QAAQ,CAAC,CAAC;AACvC,CAAC"}
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Test output parser for stdin auto-parse
3
+ *
4
+ * Ported from faf-taf-git/src/parsers/ — proven Jest + Vitest parsers.
5
+ * Pure functions, zero dependencies.
6
+ */
7
+ export interface ParsedTestOutput {
8
+ total: number;
9
+ passed: number;
10
+ failed: number;
11
+ skipped?: number;
12
+ framework: 'jest' | 'vitest';
13
+ }
14
+ /**
15
+ * Strip ANSI color codes and normalize line endings
16
+ */
17
+ export declare function stripAnsi(text: string): string;
18
+ /**
19
+ * Parse Jest output to extract test results
20
+ *
21
+ * Formats:
22
+ * - "Tests: 173 passed, 173 total"
23
+ * - "Tests: 1 failed, 172 passed, 173 total"
24
+ * - "Tests: 9 skipped, 799 passed, 808 total"
25
+ */
26
+ export declare function parseJestOutput(output: string): ParsedTestOutput | null;
27
+ /**
28
+ * Parse Vitest output to extract test results
29
+ *
30
+ * Formats:
31
+ * - " Tests 8 passed (8)"
32
+ * - " Tests 2 failed | 6 passed (8)"
33
+ * - " Tests 1 skipped | 7 passed (8)"
34
+ * - " Tests 1 failed | 2 skipped | 5 passed (8)"
35
+ */
36
+ export declare function parseVitestOutput(output: string): ParsedTestOutput | null;
37
+ /**
38
+ * Parse test output from any supported framework.
39
+ * Tries Jest first, then Vitest.
40
+ */
41
+ export declare function parseTestOutput(output: string): ParsedTestOutput | null;
42
+ //# sourceMappingURL=test-output-parser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-output-parser.d.ts","sourceRoot":"","sources":["../../src/taf/test-output-parser.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,GAAG,QAAQ,CAAC;CAC9B;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAK9C;AAED;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,gBAAgB,GAAG,IAAI,CAkCvE;AAED;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,gBAAgB,GAAG,IAAI,CAoCzE;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,gBAAgB,GAAG,IAAI,CAEvE"}
@@ -0,0 +1,114 @@
1
+ "use strict";
2
+ /**
3
+ * Test output parser for stdin auto-parse
4
+ *
5
+ * Ported from faf-taf-git/src/parsers/ — proven Jest + Vitest parsers.
6
+ * Pure functions, zero dependencies.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.stripAnsi = stripAnsi;
10
+ exports.parseJestOutput = parseJestOutput;
11
+ exports.parseVitestOutput = parseVitestOutput;
12
+ exports.parseTestOutput = parseTestOutput;
13
+ /**
14
+ * Strip ANSI color codes and normalize line endings
15
+ */
16
+ function stripAnsi(text) {
17
+ // eslint-disable-next-line no-control-regex
18
+ let clean = text.replace(/\x1b\[[0-9;]*m/g, '');
19
+ clean = clean.replace(/\r\n/g, '\n').replace(/\r/g, '\n');
20
+ return clean;
21
+ }
22
+ /**
23
+ * Parse Jest output to extract test results
24
+ *
25
+ * Formats:
26
+ * - "Tests: 173 passed, 173 total"
27
+ * - "Tests: 1 failed, 172 passed, 173 total"
28
+ * - "Tests: 9 skipped, 799 passed, 808 total"
29
+ */
30
+ function parseJestOutput(output) {
31
+ const clean = stripAnsi(output);
32
+ // Must match "Tests:" line containing "total" to avoid false positives
33
+ const match = clean.match(/Tests:\s+(.+?\d+\s+total)/im);
34
+ if (!match || !match[1])
35
+ return null;
36
+ const line = match[1];
37
+ const totalMatch = line.match(/(\d+)\s+total/i);
38
+ if (!totalMatch)
39
+ return null;
40
+ const total = parseInt(totalMatch[1], 10);
41
+ if (total === 0)
42
+ return null;
43
+ let passed = 0;
44
+ let failed = 0;
45
+ let skipped = 0;
46
+ const passedMatch = line.match(/(\d+)\s+passed/i);
47
+ if (passedMatch)
48
+ passed = parseInt(passedMatch[1], 10);
49
+ const failedMatch = line.match(/(\d+)\s+failed/i);
50
+ if (failedMatch)
51
+ failed = parseInt(failedMatch[1], 10);
52
+ const skippedMatch = line.match(/(\d+)\s+skipped/i);
53
+ if (skippedMatch)
54
+ skipped = parseInt(skippedMatch[1], 10);
55
+ return {
56
+ total,
57
+ passed,
58
+ failed,
59
+ skipped: skipped > 0 ? skipped : undefined,
60
+ framework: 'jest',
61
+ };
62
+ }
63
+ /**
64
+ * Parse Vitest output to extract test results
65
+ *
66
+ * Formats:
67
+ * - " Tests 8 passed (8)"
68
+ * - " Tests 2 failed | 6 passed (8)"
69
+ * - " Tests 1 skipped | 7 passed (8)"
70
+ * - " Tests 1 failed | 2 skipped | 5 passed (8)"
71
+ */
72
+ function parseVitestOutput(output) {
73
+ const clean = stripAnsi(output);
74
+ const match = clean.match(/^\s*Tests\s+(.+?\(\d+\))/m);
75
+ if (!match || !match[1])
76
+ return null;
77
+ const line = match[1];
78
+ const totalMatch = line.match(/\((\d+)\)\s*$/);
79
+ if (!totalMatch)
80
+ return null;
81
+ const total = parseInt(totalMatch[1], 10);
82
+ if (total === 0)
83
+ return null;
84
+ let passed = 0;
85
+ let failed = 0;
86
+ let skipped = 0;
87
+ const passedMatch = line.match(/(\d+)\s+passed/i);
88
+ if (passedMatch)
89
+ passed = parseInt(passedMatch[1], 10);
90
+ const failedMatch = line.match(/(\d+)\s+failed/i);
91
+ if (failedMatch)
92
+ failed = parseInt(failedMatch[1], 10);
93
+ const skippedMatch = line.match(/(\d+)\s+skipped/i);
94
+ if (skippedMatch)
95
+ skipped = parseInt(skippedMatch[1], 10);
96
+ const todoMatch = line.match(/(\d+)\s+todo/i);
97
+ if (todoMatch)
98
+ skipped += parseInt(todoMatch[1], 10);
99
+ return {
100
+ total,
101
+ passed,
102
+ failed,
103
+ skipped: skipped > 0 ? skipped : undefined,
104
+ framework: 'vitest',
105
+ };
106
+ }
107
+ /**
108
+ * Parse test output from any supported framework.
109
+ * Tries Jest first, then Vitest.
110
+ */
111
+ function parseTestOutput(output) {
112
+ return parseJestOutput(output) || parseVitestOutput(output);
113
+ }
114
+ //# sourceMappingURL=test-output-parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-output-parser.js","sourceRoot":"","sources":["../../src/taf/test-output-parser.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,60 @@
1
+ /**
2
+ * AGENTS.md Parser
3
+ *
4
+ * Parses OpenAI Codex / Linux Foundation AGENTS.md files for bidirectional
5
+ * interoperability with FAF.
6
+ *
7
+ * AGENTS.md Structure:
8
+ * - H1: Project name
9
+ * - H2: Section headers (Project Overview, Tech Stack, etc.)
10
+ * - Bullets: Specific guidelines
11
+ *
12
+ * @see https://github.com/anthropics/claude-code/issues/27050
13
+ */
14
+ export interface AgentsMdSection {
15
+ title: string;
16
+ content: string[];
17
+ }
18
+ export interface AgentsMdFile {
19
+ projectName: string;
20
+ sections: AgentsMdSection[];
21
+ }
22
+ export interface FafFromAgents {
23
+ project: {
24
+ name: string;
25
+ description: string;
26
+ type: string;
27
+ rules: string[];
28
+ guidelines: string[];
29
+ codingStyle: string[];
30
+ buildCommands: string[];
31
+ architecture: string[];
32
+ };
33
+ metadata: {
34
+ source: string;
35
+ imported: string;
36
+ };
37
+ }
38
+ export interface AgentsImportResult {
39
+ success: boolean;
40
+ faf: FafFromAgents;
41
+ warnings: string[];
42
+ sectionsFound: string[];
43
+ }
44
+ export interface AgentsExportResult {
45
+ success: boolean;
46
+ filePath: string;
47
+ warnings: string[];
48
+ }
49
+ /**
50
+ * Parse AGENTS.md file content
51
+ */
52
+ export declare function parseAgentsMd(content: string): AgentsMdFile;
53
+ export declare function agentsImport(agentsPath: string): Promise<AgentsImportResult>;
54
+ export declare function agentsExport(fafContent: any, outputPath: string): Promise<AgentsExportResult>;
55
+ export declare function detectAgentsMd(basePath: string): Promise<string | null>;
56
+ /**
57
+ * Check for global AGENTS.md (~/.codex/AGENTS.md)
58
+ */
59
+ export declare function detectGlobalAgentsMd(): Promise<string | null>;
60
+ //# sourceMappingURL=agents-parser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agents-parser.d.ts","sourceRoot":"","sources":["../../src/utils/agents-parser.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AASH,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,MAAM,WAAW,YAAY;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,eAAe,EAAE,CAAC;CAC7B;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE;QACP,IAAI,EAAE,MAAM,CAAC;QACb,WAAW,EAAE,MAAM,CAAC;QACpB,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,EAAE,MAAM,EAAE,CAAC;QAChB,UAAU,EAAE,MAAM,EAAE,CAAC;QACrB,WAAW,EAAE,MAAM,EAAE,CAAC;QACtB,aAAa,EAAE,MAAM,EAAE,CAAC;QACxB,YAAY,EAAE,MAAM,EAAE,CAAC;KACxB,CAAC;IACF,QAAQ,EAAE;QACR,MAAM,EAAE,MAAM,CAAC;QACf,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC;CACH;AAED,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,OAAO,CAAC;IACjB,GAAG,EAAE,aAAa,CAAC;IACnB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,aAAa,EAAE,MAAM,EAAE,CAAC;CACzB;AAED,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAMD;;GAEG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,YAAY,CA0C3D;AA0CD,wBAAsB,YAAY,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAgDlF;AAyBD,wBAAsB,YAAY,CAChC,UAAU,EAAE,GAAG,EACf,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,kBAAkB,CAAC,CA2H7B;AAMD,wBAAsB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAiB7E;AAED;;GAEG;AACH,wBAAsB,oBAAoB,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAUnE"}