faf-taf-git 2.4.0 → 2.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 (54) hide show
  1. package/CHANGELOG.md +23 -1
  2. package/README.md +1 -1
  3. package/RECEIPT-FORMAT.md +1 -1
  4. package/dist/cli.d.ts +5 -0
  5. package/dist/cli.d.ts.map +1 -1
  6. package/dist/cli.js +14 -1
  7. package/dist/cli.js.map +1 -1
  8. package/package.json +15 -2
  9. package/project.faf +32 -242
  10. package/.faf-dna +0 -95
  11. package/.fafignore +0 -41
  12. package/.github/dependabot.yml +0 -10
  13. package/.github/workflows/ci.yml +0 -53
  14. package/.github/workflows/claude-code-review.yml +0 -36
  15. package/.github/workflows/claude.yml +0 -39
  16. package/.github/workflows/homebrew.yml +0 -19
  17. package/.taf +0 -98
  18. package/CLAUDE.md +0 -38
  19. package/CODE_OF_CONDUCT.md +0 -21
  20. package/CONTRIBUTING.md +0 -289
  21. package/SECURITY.md +0 -19
  22. package/action.yml +0 -50
  23. package/agent.fafa +0 -53
  24. package/badge.svg +0 -21
  25. package/dist/bundle/index.js +0 -36554
  26. package/dist/index.js +0 -42827
  27. package/dist/index.js.map +0 -1
  28. package/dist/licenses.txt +0 -126
  29. package/dist/sourcemap-register.js +0 -1
  30. package/docs/RELEASE-NOTES.md +0 -200
  31. package/docs/USER-GUIDE.md +0 -301
  32. package/jest.config.js +0 -13
  33. package/src/badge.ts +0 -138
  34. package/src/cli.ts +0 -297
  35. package/src/index.ts +0 -201
  36. package/src/parsers/bun.ts +0 -103
  37. package/src/parsers/index.ts +0 -50
  38. package/src/parsers/jest.ts +0 -104
  39. package/src/parsers/junit.ts +0 -110
  40. package/src/parsers/vitest.ts +0 -65
  41. package/src/parsers/wjttc.ts +0 -160
  42. package/src/taf-core.ts +0 -139
  43. package/test-mcp.ts +0 -83
  44. package/test-standalone.ts +0 -87
  45. package/tests/action-bundle.test.ts +0 -34
  46. package/tests/action-parse-error.test.ts +0 -47
  47. package/tests/badge.test.ts +0 -260
  48. package/tests/bun-parser.test.ts +0 -173
  49. package/tests/jest-parser.test.ts +0 -122
  50. package/tests/junit-parser.test.ts +0 -109
  51. package/tests/vitest-parser.test.ts +0 -112
  52. package/tests/wjttc-parser.test.ts +0 -116
  53. package/tests/wjttc-taf.test.ts +0 -470
  54. package/tsconfig.json +0 -18
@@ -1,470 +0,0 @@
1
- /**
2
- * 🏎️ WJTTC Test Suite: faf-taf-git
3
- *
4
- * CAR = Claim, Audit, Receipt
5
- * This tests the RECEIPT (R) - the .taf file generator
6
- *
7
- * TIER 0: Platform Compatibility - Runs on all tracks
8
- * TIER 1: BRAKE - Receipt Accuracy (critical safety)
9
- * TIER 2: ENGINE - Receipt Completeness (core function)
10
- * TIER 3: AERO - Receipt Reliability (edge cases)
11
- *
12
- * "No CAR = No transport. The receipt must be bulletproof."
13
- */
14
-
15
- import * as fs from 'fs';
16
- import * as path from 'path';
17
- import * as os from 'os';
18
- import { execSync } from 'child_process';
19
-
20
- // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
21
- // HELPERS
22
- // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
23
-
24
- const ROOT_DIR = path.resolve(__dirname, '..');
25
- const CLI_PATH = path.join(ROOT_DIR, 'dist', 'cli.js');
26
-
27
- /**
28
- * Cross-platform temp directory creation
29
- */
30
- function createTempDir(prefix: string): string {
31
- return fs.mkdtempSync(path.join(os.tmpdir(), prefix));
32
- }
33
-
34
- /**
35
- * Cross-platform file finder
36
- */
37
- function findFiles(dir: string, pattern: RegExp, excludeDirs: string[] = []): string[] {
38
- const results: string[] = [];
39
-
40
- function walk(currentDir: string) {
41
- try {
42
- const entries = fs.readdirSync(currentDir, { withFileTypes: true });
43
- for (const entry of entries) {
44
- const fullPath = path.join(currentDir, entry.name);
45
- if (entry.isDirectory()) {
46
- if (!excludeDirs.includes(entry.name)) {
47
- walk(fullPath);
48
- }
49
- } else if (entry.isFile() && pattern.test(entry.name)) {
50
- results.push(fullPath);
51
- }
52
- }
53
- } catch (e) {
54
- // Directory may not exist
55
- }
56
- }
57
-
58
- walk(dir);
59
- return results;
60
- }
61
-
62
- // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
63
- // TIER 0: PLATFORM COMPATIBILITY - Runs on all tracks
64
- // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
65
-
66
- describe('🏁 TIER 0: Platform Compatibility', () => {
67
- const srcDir = path.join(ROOT_DIR, 'src');
68
- const testsDir = path.join(ROOT_DIR, 'tests');
69
-
70
- describe('🚫 No Hardcoded Unix Paths', () => {
71
- test('source files should not use hardcoded /tmp paths', () => {
72
- const violations: string[] = [];
73
- const srcFiles = findFiles(srcDir, /\.ts$/, ['node_modules']);
74
-
75
- for (const file of srcFiles) {
76
- const content = fs.readFileSync(file, 'utf8');
77
- const lines = content.split('\n');
78
-
79
- lines.forEach((line, idx) => {
80
- if (line.trim().startsWith('//') || line.trim().startsWith('*')) return;
81
- if (/FIX:|VIOLATION/.test(line)) return;
82
-
83
- if (/['"`]\/tmp\//.test(line)) {
84
- violations.push(`${path.basename(file)}:${idx + 1}: Hardcoded /tmp`);
85
- }
86
- });
87
- }
88
-
89
- expect(violations).toHaveLength(0);
90
- });
91
-
92
- test('source files should not use hardcoded /bin paths', () => {
93
- const violations: string[] = [];
94
- const srcFiles = findFiles(srcDir, /\.ts$/, ['node_modules']);
95
-
96
- for (const file of srcFiles) {
97
- const content = fs.readFileSync(file, 'utf8');
98
- const lines = content.split('\n');
99
-
100
- lines.forEach((line, idx) => {
101
- if (line.trim().startsWith('//') || line.trim().startsWith('*')) return;
102
-
103
- if (/['"`]\/bin\/(bash|sh)/.test(line)) {
104
- violations.push(`${path.basename(file)}:${idx + 1}: Hardcoded shell`);
105
- }
106
- });
107
- }
108
-
109
- expect(violations).toHaveLength(0);
110
- });
111
- });
112
-
113
- describe('🚫 No Unix-Only Commands', () => {
114
- test('should not use Unix find command in source', () => {
115
- const violations: string[] = [];
116
- const srcFiles = findFiles(srcDir, /\.ts$/, ['node_modules']);
117
-
118
- for (const file of srcFiles) {
119
- const content = fs.readFileSync(file, 'utf8');
120
-
121
- if (/exec(Sync)?\s*\(\s*['"`]find\s/.test(content)) {
122
- violations.push(path.basename(file));
123
- }
124
- }
125
-
126
- expect(violations).toHaveLength(0);
127
- });
128
- });
129
-
130
- describe('📊 Platform Summary', () => {
131
- test('should display platform info', () => {
132
- console.log('\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
133
- console.log('🏁 TIER 0: PLATFORM COMPATIBILITY - PASSED');
134
- console.log(`Platform: ${process.platform} | Node: ${process.version}`);
135
- console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n');
136
- expect(true).toBe(true);
137
- });
138
- });
139
- });
140
-
141
- // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
142
- // TIER 1: BRAKE - Receipt Accuracy (Critical Safety)
143
- // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
144
-
145
- describe('🛑 TIER 1: BRAKE - Receipt Accuracy', () => {
146
- let tempDir: string;
147
-
148
- beforeEach(() => {
149
- tempDir = createTempDir('wjttc-taf-brake-');
150
- });
151
-
152
- afterEach(() => {
153
- fs.rmSync(tempDir, { recursive: true, force: true });
154
- });
155
-
156
- describe('📝 .taf File Creation', () => {
157
- test('should create valid .taf file structure', () => {
158
- const tafPath = path.join(tempDir, '.taf');
159
-
160
- // Minimal .taf structure
161
- const tafContent = `# .taf - Testing Activity Feed
162
- format_version: "1.0.0"
163
- project: "test-project"
164
- created: "${new Date().toISOString()}"
165
- last_updated: "${new Date().toISOString()}"
166
- test_history: []
167
- `;
168
-
169
- fs.writeFileSync(tafPath, tafContent);
170
-
171
- expect(fs.existsSync(tafPath)).toBe(true);
172
-
173
- const content = fs.readFileSync(tafPath, 'utf8');
174
- expect(content).toContain('format_version');
175
- expect(content).toContain('project');
176
- expect(content).toContain('test_history');
177
- });
178
-
179
- test('.taf should be valid YAML', () => {
180
- const yaml = require('yaml');
181
- const tafPath = path.join(tempDir, '.taf');
182
-
183
- const tafContent = `format_version: "1.0.0"
184
- project: "test-project"
185
- created: "2026-01-28T00:00:00Z"
186
- last_updated: "2026-01-28T00:00:00Z"
187
- test_history:
188
- - timestamp: "2026-01-28T00:00:00Z"
189
- result: PASSED
190
- tests:
191
- total: 10
192
- passed: 10
193
- failed: 0
194
- `;
195
-
196
- fs.writeFileSync(tafPath, tafContent);
197
-
198
- const parsed = yaml.parse(fs.readFileSync(tafPath, 'utf8'));
199
-
200
- expect(parsed.format_version).toBe('1.0.0');
201
- expect(parsed.project).toBe('test-project');
202
- expect(parsed.test_history).toHaveLength(1);
203
- expect(parsed.test_history[0].result).toBe('PASSED');
204
- });
205
- });
206
-
207
- describe('🎯 Result Accuracy', () => {
208
- test('PASSED means all tests passed', () => {
209
- const result = { total: 10, passed: 10, failed: 0, skipped: 0 };
210
- const status = result.failed === 0 ? 'PASSED' : 'FAILED';
211
-
212
- expect(status).toBe('PASSED');
213
- });
214
-
215
- test('FAILED means at least one test failed', () => {
216
- const result = { total: 10, passed: 9, failed: 1, skipped: 0 };
217
- const status = result.failed === 0 ? 'PASSED' : 'FAILED';
218
-
219
- expect(status).toBe('FAILED');
220
- });
221
-
222
- test('counts must be accurate', () => {
223
- const result = { total: 100, passed: 95, failed: 3, skipped: 2 };
224
-
225
- expect(result.passed + result.failed + result.skipped).toBe(result.total);
226
- });
227
- });
228
-
229
- describe('🔗 .faf Integration', () => {
230
- test('should detect .faf file when present', () => {
231
- const fafPath = path.join(tempDir, '.faf');
232
- fs.writeFileSync(fafPath, 'faf_version: 2.5.0\nproject:\n name: test');
233
-
234
- const hasFaf = fs.existsSync(fafPath);
235
- expect(hasFaf).toBe(true);
236
- });
237
-
238
- test('should work without .faf file', () => {
239
- const fafPath = path.join(tempDir, '.faf');
240
- const hasFaf = fs.existsSync(fafPath);
241
-
242
- expect(hasFaf).toBe(false);
243
- // Should not throw - .faf is optional
244
- });
245
- });
246
- });
247
-
248
- // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
249
- // TIER 2: ENGINE - Receipt Completeness (Core Function)
250
- // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
251
-
252
- describe('🔧 TIER 2: ENGINE - Receipt Completeness', () => {
253
- describe('📋 Jest Parser', () => {
254
- // Import the parser
255
- const { parseJestOutput } = require('../dist/parsers/jest');
256
-
257
- test('should parse standard Jest output', () => {
258
- const output = 'Tests: 10 passed, 10 total';
259
- const result = parseJestOutput(output);
260
-
261
- expect(result).not.toBeNull();
262
- expect(result.passed).toBe(10);
263
- expect(result.total).toBe(10);
264
- expect(result.failed).toBe(0);
265
- });
266
-
267
- test('should parse Jest output with failures', () => {
268
- const output = 'Tests: 2 failed, 8 passed, 10 total';
269
- const result = parseJestOutput(output);
270
-
271
- expect(result).not.toBeNull();
272
- expect(result.passed).toBe(8);
273
- expect(result.failed).toBe(2);
274
- expect(result.total).toBe(10);
275
- });
276
-
277
- test('should parse Jest output with skipped', () => {
278
- const output = 'Tests: 1 skipped, 9 passed, 10 total';
279
- const result = parseJestOutput(output);
280
-
281
- expect(result).not.toBeNull();
282
- expect(result.skipped).toBe(1);
283
- });
284
-
285
- test('should handle malformed output gracefully', () => {
286
- const output = 'This is not Jest output';
287
- const result = parseJestOutput(output);
288
-
289
- expect(result).toBeNull();
290
- });
291
- });
292
-
293
- describe('📁 TAF Core Operations', () => {
294
- const { updateTafFile } = require('../dist/taf-core');
295
- let tempDir: string;
296
-
297
- beforeEach(() => {
298
- tempDir = createTempDir('wjttc-taf-engine-');
299
- });
300
-
301
- afterEach(() => {
302
- fs.rmSync(tempDir, { recursive: true, force: true });
303
- });
304
-
305
- test('should create .taf if not exists', () => {
306
- const tafPath = path.join(tempDir, '.taf');
307
- const testResults = { total: 5, passed: 5, failed: 0, skipped: 0 };
308
-
309
- updateTafFile(tafPath, testResults);
310
-
311
- expect(fs.existsSync(tafPath)).toBe(true);
312
- });
313
-
314
- test('should append to existing .taf', () => {
315
- const tafPath = path.join(tempDir, '.taf');
316
- const testResults = { total: 5, passed: 5, failed: 0, skipped: 0 };
317
-
318
- // First update
319
- updateTafFile(tafPath, testResults);
320
- const content1 = fs.readFileSync(tafPath, 'utf8');
321
-
322
- // Second update
323
- updateTafFile(tafPath, testResults);
324
- const content2 = fs.readFileSync(tafPath, 'utf8');
325
-
326
- // Should have grown (more entries)
327
- expect(content2.length).toBeGreaterThan(content1.length);
328
- });
329
- });
330
- });
331
-
332
- // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
333
- // TIER 3: AERO - Receipt Reliability (Edge Cases)
334
- // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
335
-
336
- describe('⚡ TIER 3: AERO - Receipt Reliability', () => {
337
- let tempDir: string;
338
-
339
- beforeEach(() => {
340
- tempDir = createTempDir('wjttc-taf-aero-');
341
- });
342
-
343
- afterEach(() => {
344
- fs.rmSync(tempDir, { recursive: true, force: true });
345
- });
346
-
347
- describe('📈 Scale Testing', () => {
348
- test('should handle large test counts', () => {
349
- const result = { total: 10000, passed: 9999, failed: 1, skipped: 0 };
350
-
351
- expect(result.total).toBe(10000);
352
- expect(result.passed + result.failed + result.skipped).toBe(result.total);
353
- });
354
-
355
- test('should handle zero tests gracefully', () => {
356
- const result = { total: 0, passed: 0, failed: 0, skipped: 0 };
357
-
358
- expect(result.total).toBe(0);
359
- // Should not throw
360
- });
361
- });
362
-
363
- describe('🛡️ Error Recovery', () => {
364
- test('should handle corrupted .taf file', () => {
365
- const tafPath = path.join(tempDir, '.taf');
366
- fs.writeFileSync(tafPath, 'this is not valid yaml: {{{{');
367
-
368
- // Should not crash when reading corrupted file
369
- try {
370
- const yaml = require('yaml');
371
- yaml.parse(fs.readFileSync(tafPath, 'utf8'));
372
- } catch (e) {
373
- // Expected - corrupted YAML
374
- expect(e).toBeDefined();
375
- }
376
- });
377
-
378
- test('should handle missing permissions gracefully', () => {
379
- // Skip on Windows (different permission model)
380
- if (process.platform === 'win32') {
381
- expect(true).toBe(true);
382
- return;
383
- }
384
-
385
- const readonlyDir = path.join(tempDir, 'readonly');
386
- fs.mkdirSync(readonlyDir);
387
- fs.chmodSync(readonlyDir, 0o444);
388
-
389
- const tafPath = path.join(readonlyDir, '.taf');
390
-
391
- try {
392
- fs.writeFileSync(tafPath, 'test');
393
- } catch (e: any) {
394
- expect(e.code).toBe('EACCES');
395
- } finally {
396
- fs.chmodSync(readonlyDir, 0o755);
397
- }
398
- });
399
- });
400
-
401
- describe('🌍 Cross-Platform Line Endings', () => {
402
- test('should handle Unix line endings (LF)', () => {
403
- const content = "line1\nline2\nline3";
404
- const lines = content.split(/\r?\n/);
405
-
406
- expect(lines).toHaveLength(3);
407
- });
408
-
409
- test('should handle Windows line endings (CRLF)', () => {
410
- const content = "line1\r\nline2\r\nline3";
411
- const lines = content.split(/\r?\n/);
412
-
413
- expect(lines).toHaveLength(3);
414
- });
415
- });
416
- });
417
-
418
- // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
419
- // CAR VALIDATION - The Full Receipt
420
- // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
421
-
422
- describe('🏎️ CAR VALIDATION - Complete Receipt System', () => {
423
- test('should display CAR summary', () => {
424
- console.log('\n');
425
- console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
426
- console.log('🏎️ CAR = Claim, Audit, Receipt');
427
- console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
428
- console.log('C = .faf (Claim) - Project DNA');
429
- console.log('A = WJTTC (Audit) - Score Verification');
430
- console.log('R = .taf (Receipt) - Proof Over Time');
431
- console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
432
- console.log('✅ faf-taf-git is the Receipt Printer');
433
- console.log('✅ WJTTC Suite: PASSED');
434
- console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n');
435
-
436
- expect(true).toBe(true);
437
- });
438
- });
439
-
440
- /**
441
- * WJTTC TIER SUMMARY
442
- * ==================
443
- *
444
- * TIER 0: Platform Compatibility
445
- * - No hardcoded /tmp paths
446
- * - No Unix-only commands
447
- * - Cross-platform ready
448
- *
449
- * TIER 1: BRAKE - Receipt Accuracy
450
- * - .taf file creation
451
- * - Valid YAML structure
452
- * - Accurate test results
453
- * - .faf integration
454
- *
455
- * TIER 2: ENGINE - Receipt Completeness
456
- * - Jest parser accuracy
457
- * - TAF core operations
458
- * - Append-only history
459
- *
460
- * TIER 3: AERO - Receipt Reliability
461
- * - Scale testing
462
- * - Error recovery
463
- * - Line ending handling
464
- *
465
- * CAR VALIDATION
466
- * - Full system verification
467
- * - Score is truth
468
- *
469
- * "No CAR = No transport"
470
- */
package/tsconfig.json DELETED
@@ -1,18 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "target": "ES2020",
4
- "module": "commonjs",
5
- "lib": ["ES2020"],
6
- "outDir": "./dist",
7
- "strict": true,
8
- "esModuleInterop": true,
9
- "skipLibCheck": true,
10
- "forceConsistentCasingInFileNames": true,
11
- "resolveJsonModule": true,
12
- "declaration": true,
13
- "declarationMap": true,
14
- "sourceMap": true
15
- },
16
- "include": ["src/**/*"],
17
- "exclude": ["node_modules", "dist", "tests"]
18
- }