pikakit 3.0.5 → 3.7.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 (100) hide show
  1. package/README.md +1 -1
  2. package/bin/lib/commands/install.js +119 -242
  3. package/package.json +3 -4
  4. package/lib/agent-cli/bin/agent.js +0 -187
  5. package/lib/agent-cli/dashboard/dashboard_server.js +0 -312
  6. package/lib/agent-cli/lib/ab-testing.js +0 -364
  7. package/lib/agent-cli/lib/audit.js +0 -154
  8. package/lib/agent-cli/lib/audit.test.js +0 -100
  9. package/lib/agent-cli/lib/auto-learn.js +0 -319
  10. package/lib/agent-cli/lib/backup.js +0 -138
  11. package/lib/agent-cli/lib/backup.test.js +0 -78
  12. package/lib/agent-cli/lib/causality-engine.js +0 -331
  13. package/lib/agent-cli/lib/cognitive-lesson.js +0 -476
  14. package/lib/agent-cli/lib/completion.js +0 -149
  15. package/lib/agent-cli/lib/config.js +0 -35
  16. package/lib/agent-cli/lib/dashboard-data.js +0 -380
  17. package/lib/agent-cli/lib/eslint-fix.js +0 -238
  18. package/lib/agent-cli/lib/evolution-signal.js +0 -215
  19. package/lib/agent-cli/lib/export.js +0 -86
  20. package/lib/agent-cli/lib/export.test.js +0 -65
  21. package/lib/agent-cli/lib/fix.js +0 -337
  22. package/lib/agent-cli/lib/fix.test.js +0 -80
  23. package/lib/agent-cli/lib/gemini-export.js +0 -83
  24. package/lib/agent-cli/lib/generate-registry.js +0 -42
  25. package/lib/agent-cli/lib/hooks/install-hooks.js +0 -152
  26. package/lib/agent-cli/lib/hooks/lint-learn.js +0 -172
  27. package/lib/agent-cli/lib/icons.js +0 -93
  28. package/lib/agent-cli/lib/ignore.js +0 -116
  29. package/lib/agent-cli/lib/ignore.test.js +0 -58
  30. package/lib/agent-cli/lib/init.js +0 -124
  31. package/lib/agent-cli/lib/knowledge-index.js +0 -326
  32. package/lib/agent-cli/lib/knowledge-metrics.js +0 -335
  33. package/lib/agent-cli/lib/knowledge-retention.js +0 -398
  34. package/lib/agent-cli/lib/knowledge-validator.js +0 -312
  35. package/lib/agent-cli/lib/learn.js +0 -255
  36. package/lib/agent-cli/lib/learn.test.js +0 -70
  37. package/lib/agent-cli/lib/metrics-collector.js +0 -410
  38. package/lib/agent-cli/lib/proposals.js +0 -199
  39. package/lib/agent-cli/lib/proposals.test.js +0 -56
  40. package/lib/agent-cli/lib/recall.js +0 -835
  41. package/lib/agent-cli/lib/recall.test.js +0 -107
  42. package/lib/agent-cli/lib/reinforcement.js +0 -299
  43. package/lib/agent-cli/lib/selfevolution-bridge.js +0 -167
  44. package/lib/agent-cli/lib/settings.js +0 -203
  45. package/lib/agent-cli/lib/skill-generator.js +0 -379
  46. package/lib/agent-cli/lib/skill-learn.js +0 -296
  47. package/lib/agent-cli/lib/stats.js +0 -132
  48. package/lib/agent-cli/lib/stats.test.js +0 -94
  49. package/lib/agent-cli/lib/types.js +0 -33
  50. package/lib/agent-cli/lib/ui/audit-ui.js +0 -146
  51. package/lib/agent-cli/lib/ui/backup-ui.js +0 -107
  52. package/lib/agent-cli/lib/ui/clack-helpers.js +0 -317
  53. package/lib/agent-cli/lib/ui/common.js +0 -83
  54. package/lib/agent-cli/lib/ui/completion-ui.js +0 -126
  55. package/lib/agent-cli/lib/ui/custom-select.js +0 -69
  56. package/lib/agent-cli/lib/ui/dashboard-ui.js +0 -222
  57. package/lib/agent-cli/lib/ui/evolution-signals-ui.js +0 -107
  58. package/lib/agent-cli/lib/ui/export-ui.js +0 -94
  59. package/lib/agent-cli/lib/ui/fix-all-ui.js +0 -191
  60. package/lib/agent-cli/lib/ui/help-ui.js +0 -49
  61. package/lib/agent-cli/lib/ui/index.js +0 -199
  62. package/lib/agent-cli/lib/ui/init-ui.js +0 -56
  63. package/lib/agent-cli/lib/ui/knowledge-ui.js +0 -55
  64. package/lib/agent-cli/lib/ui/learn-ui.js +0 -706
  65. package/lib/agent-cli/lib/ui/lessons-ui.js +0 -148
  66. package/lib/agent-cli/lib/ui/pretty.js +0 -145
  67. package/lib/agent-cli/lib/ui/proposals-ui.js +0 -99
  68. package/lib/agent-cli/lib/ui/recall-ui.js +0 -342
  69. package/lib/agent-cli/lib/ui/routing-demo.js +0 -79
  70. package/lib/agent-cli/lib/ui/routing-ui.js +0 -325
  71. package/lib/agent-cli/lib/ui/settings-ui.js +0 -381
  72. package/lib/agent-cli/lib/ui/stats-ui.js +0 -123
  73. package/lib/agent-cli/lib/ui/watch-ui.js +0 -236
  74. package/lib/agent-cli/lib/watcher.js +0 -181
  75. package/lib/agent-cli/lib/watcher.test.js +0 -85
  76. package/lib/agent-cli/src/MIGRATION.md +0 -418
  77. package/lib/agent-cli/src/README.md +0 -367
  78. package/lib/agent-cli/src/core/evolution/evolution-signal.js +0 -42
  79. package/lib/agent-cli/src/core/evolution/index.js +0 -17
  80. package/lib/agent-cli/src/core/evolution/review-gate.js +0 -40
  81. package/lib/agent-cli/src/core/evolution/signal-detector.js +0 -137
  82. package/lib/agent-cli/src/core/evolution/signal-queue.js +0 -79
  83. package/lib/agent-cli/src/core/evolution/threshold-checker.js +0 -79
  84. package/lib/agent-cli/src/core/index.js +0 -15
  85. package/lib/agent-cli/src/core/learning/cognitive-enhancer.js +0 -282
  86. package/lib/agent-cli/src/core/learning/index.js +0 -12
  87. package/lib/agent-cli/src/core/learning/lesson-synthesizer.js +0 -83
  88. package/lib/agent-cli/src/core/scanning/index.js +0 -14
  89. package/lib/agent-cli/src/data/index.js +0 -13
  90. package/lib/agent-cli/src/data/repositories/index.js +0 -8
  91. package/lib/agent-cli/src/data/repositories/lesson-repository.js +0 -130
  92. package/lib/agent-cli/src/data/repositories/signal-repository.js +0 -119
  93. package/lib/agent-cli/src/data/storage/index.js +0 -8
  94. package/lib/agent-cli/src/data/storage/json-storage.js +0 -64
  95. package/lib/agent-cli/src/data/storage/yaml-storage.js +0 -66
  96. package/lib/agent-cli/src/infrastructure/index.js +0 -13
  97. package/lib/agent-cli/src/presentation/formatters/skill-formatter.js +0 -232
  98. package/lib/agent-cli/src/services/export-service.js +0 -162
  99. package/lib/agent-cli/src/services/index.js +0 -13
  100. package/lib/agent-cli/src/services/learning-service.js +0 -99
@@ -1,364 +0,0 @@
1
- /**
2
- * A/B Testing v7.0 - Pattern Experiment Framework
3
- *
4
- * Manages A/B tests for comparing pattern effectiveness.
5
- * Tracks experiment results and determines winners.
6
- *
7
- * @version 7.0.0
8
- * @author PikaKit
9
- */
10
-
11
- import fs from 'fs';
12
- import path from 'path';
13
- import { fileURLToPath } from 'url';
14
-
15
- const __filename = fileURLToPath(import.meta.url);
16
- const __dirname = path.dirname(__filename);
17
-
18
- // Find project root
19
- function findProjectRoot() {
20
- let dir = process.cwd();
21
- while (dir !== path.dirname(dir)) {
22
- if (fs.existsSync(path.join(dir, '.agent'))) return dir;
23
- if (fs.existsSync(path.join(dir, 'package.json'))) return dir;
24
- dir = path.dirname(dir);
25
- }
26
- return process.cwd();
27
- }
28
-
29
- const projectRoot = findProjectRoot();
30
- const METRICS_DIR = path.join(projectRoot, '.agent', 'metrics');
31
- const AB_TESTS_FILE = path.join(METRICS_DIR, 'ab-tests.json');
32
-
33
- // ============================================================================
34
- // DATA STRUCTURES
35
- // ============================================================================
36
-
37
- /**
38
- * A/B Test structure:
39
- * {
40
- * id: string,
41
- * name: string,
42
- * description: string,
43
- * variantA: { id: string, patternId: string, description: string },
44
- * variantB: { id: string, patternId: string, description: string },
45
- * status: 'running' | 'completed' | 'paused',
46
- * startDate: string,
47
- * endDate: string | null,
48
- * results: {
49
- * variantA: { impressions: number, successes: number },
50
- * variantB: { impressions: number, successes: number }
51
- * },
52
- * winner: 'A' | 'B' | null,
53
- * confidence: number
54
- * }
55
- */
56
-
57
- // ============================================================================
58
- // DATA LOADERS
59
- // ============================================================================
60
-
61
- /**
62
- * Ensure metrics directory exists
63
- */
64
- function ensureMetricsDir() {
65
- if (!fs.existsSync(METRICS_DIR)) {
66
- fs.mkdirSync(METRICS_DIR, { recursive: true });
67
- }
68
- }
69
-
70
- /**
71
- * Load A/B tests data
72
- */
73
- function loadABTestsData() {
74
- if (fs.existsSync(AB_TESTS_FILE)) {
75
- try {
76
- return JSON.parse(fs.readFileSync(AB_TESTS_FILE, 'utf8'));
77
- } catch (e) {
78
- return getDefaultData();
79
- }
80
- }
81
- return getDefaultData();
82
- }
83
-
84
- /**
85
- * Save A/B tests data
86
- */
87
- function saveABTestsData(data) {
88
- ensureMetricsDir();
89
- data.lastUpdated = new Date().toISOString();
90
- fs.writeFileSync(AB_TESTS_FILE, JSON.stringify(data, null, 2));
91
- }
92
-
93
- /**
94
- * Get default data structure
95
- */
96
- function getDefaultData() {
97
- return {
98
- tests: [],
99
- lastUpdated: new Date().toISOString(),
100
- totalCompleted: 0
101
- };
102
- }
103
-
104
- // ============================================================================
105
- // TEST MANAGEMENT
106
- // ============================================================================
107
-
108
- /**
109
- * Create a new A/B test
110
- */
111
- export function createTest(name, description, variantA, variantB) {
112
- const data = loadABTestsData();
113
-
114
- const test = {
115
- id: `test-${Date.now()}-${Math.random().toString(36).slice(2, 7)}`,
116
- name,
117
- description,
118
- variantA: {
119
- id: 'A',
120
- ...variantA
121
- },
122
- variantB: {
123
- id: 'B',
124
- ...variantB
125
- },
126
- status: 'running',
127
- startDate: new Date().toISOString(),
128
- endDate: null,
129
- results: {
130
- variantA: { impressions: 0, successes: 0 },
131
- variantB: { impressions: 0, successes: 0 }
132
- },
133
- winner: null,
134
- confidence: 0
135
- };
136
-
137
- data.tests.push(test);
138
- saveABTestsData(data);
139
-
140
- return test;
141
- }
142
-
143
- /**
144
- * Record an impression for a variant
145
- */
146
- export function recordImpression(testId, variant, success = false) {
147
- const data = loadABTestsData();
148
- const test = data.tests.find(t => t.id === testId);
149
-
150
- if (!test || test.status !== 'running') {
151
- return { success: false, error: 'Test not found or not running' };
152
- }
153
-
154
- const variantKey = variant.toUpperCase() === 'A' ? 'variantA' : 'variantB';
155
- test.results[variantKey].impressions += 1;
156
-
157
- if (success) {
158
- test.results[variantKey].successes += 1;
159
- }
160
-
161
- // Recalculate confidence
162
- updateTestConfidence(test);
163
-
164
- // Auto-complete if enough data
165
- const minImpressions = 30;
166
- if (test.results.variantA.impressions >= minImpressions &&
167
- test.results.variantB.impressions >= minImpressions &&
168
- test.confidence >= 0.95) {
169
- completeTest(testId);
170
- }
171
-
172
- saveABTestsData(data);
173
-
174
- return { success: true, test };
175
- }
176
-
177
- /**
178
- * Update test confidence using simple statistical calculation
179
- */
180
- function updateTestConfidence(test) {
181
- const rA = test.results.variantA;
182
- const rB = test.results.variantB;
183
-
184
- if (rA.impressions === 0 || rB.impressions === 0) {
185
- test.confidence = 0;
186
- return;
187
- }
188
-
189
- const successRateA = rA.successes / rA.impressions;
190
- const successRateB = rB.successes / rB.impressions;
191
-
192
- // Simple confidence calculation based on sample size and difference
193
- const n = Math.min(rA.impressions, rB.impressions);
194
- const diff = Math.abs(successRateA - successRateB);
195
-
196
- // Higher sample size and larger difference = higher confidence
197
- test.confidence = Math.min(
198
- (n / 50) * (diff / 0.2), // Scale by sample size and effect size
199
- 0.99
200
- );
201
-
202
- // Determine preliminary winner
203
- if (test.confidence >= 0.8) {
204
- test.winner = successRateA > successRateB ? 'A' : 'B';
205
- }
206
- }
207
-
208
- /**
209
- * Complete a test
210
- */
211
- export function completeTest(testId) {
212
- const data = loadABTestsData();
213
- const test = data.tests.find(t => t.id === testId);
214
-
215
- if (!test) {
216
- return { success: false, error: 'Test not found' };
217
- }
218
-
219
- test.status = 'completed';
220
- test.endDate = new Date().toISOString();
221
-
222
- // Determine final winner
223
- const rA = test.results.variantA;
224
- const rB = test.results.variantB;
225
-
226
- if (rA.impressions > 0 && rB.impressions > 0) {
227
- const successRateA = rA.successes / rA.impressions;
228
- const successRateB = rB.successes / rB.impressions;
229
- test.winner = successRateA >= successRateB ? 'A' : 'B';
230
- }
231
-
232
- data.totalCompleted = (data.totalCompleted || 0) + 1;
233
- saveABTestsData(data);
234
-
235
- return { success: true, test };
236
- }
237
-
238
- /**
239
- * Pause a test
240
- */
241
- export function pauseTest(testId) {
242
- const data = loadABTestsData();
243
- const test = data.tests.find(t => t.id === testId);
244
-
245
- if (!test) {
246
- return { success: false, error: 'Test not found' };
247
- }
248
-
249
- test.status = 'paused';
250
- saveABTestsData(data);
251
-
252
- return { success: true, test };
253
- }
254
-
255
- /**
256
- * Resume a test
257
- */
258
- export function resumeTest(testId) {
259
- const data = loadABTestsData();
260
- const test = data.tests.find(t => t.id === testId);
261
-
262
- if (!test || test.status === 'completed') {
263
- return { success: false, error: 'Test not found or already completed' };
264
- }
265
-
266
- test.status = 'running';
267
- saveABTestsData(data);
268
-
269
- return { success: true, test };
270
- }
271
-
272
- // ============================================================================
273
- // QUERIES
274
- // ============================================================================
275
-
276
- /**
277
- * Get all active tests
278
- */
279
- export function getActiveTests() {
280
- const data = loadABTestsData();
281
- return data.tests.filter(t => t.status === 'running');
282
- }
283
-
284
- /**
285
- * Get completed tests
286
- */
287
- export function getCompletedTests() {
288
- const data = loadABTestsData();
289
- return data.tests.filter(t => t.status === 'completed');
290
- }
291
-
292
- /**
293
- * Get all tests
294
- */
295
- export function getAllTests() {
296
- const data = loadABTestsData();
297
- return data.tests;
298
- }
299
-
300
- /**
301
- * Get test by ID
302
- */
303
- export function getTest(testId) {
304
- const data = loadABTestsData();
305
- return data.tests.find(t => t.id === testId);
306
- }
307
-
308
- /**
309
- * Get A/B testing statistics
310
- */
311
- export function getABTestStats() {
312
- const data = loadABTestsData();
313
- const active = data.tests.filter(t => t.status === 'running');
314
- const completed = data.tests.filter(t => t.status === 'completed');
315
-
316
- // Calculate win rate for variant A vs B
317
- let aWins = 0;
318
- let bWins = 0;
319
-
320
- for (const test of completed) {
321
- if (test.winner === 'A') aWins++;
322
- else if (test.winner === 'B') bWins++;
323
- }
324
-
325
- return {
326
- running: active.length,
327
- completed: completed.length,
328
- total: data.tests.length,
329
- variantAWinRate: completed.length > 0 ? Math.round((aWins / completed.length) * 100) : 0,
330
- variantBWinRate: completed.length > 0 ? Math.round((bWins / completed.length) * 100) : 0
331
- };
332
- }
333
-
334
- /**
335
- * Select variant for a test (randomized)
336
- */
337
- export function selectVariant(testId) {
338
- const test = getTest(testId);
339
-
340
- if (!test || test.status !== 'running') {
341
- return null;
342
- }
343
-
344
- // Simple 50/50 split
345
- return Math.random() < 0.5 ? 'A' : 'B';
346
- }
347
-
348
- // ============================================================================
349
- // EXPORTS
350
- // ============================================================================
351
-
352
- export default {
353
- createTest,
354
- recordImpression,
355
- completeTest,
356
- pauseTest,
357
- resumeTest,
358
- getActiveTests,
359
- getCompletedTests,
360
- getAllTests,
361
- getTest,
362
- getABTestStats,
363
- selectVariant
364
- };
@@ -1,154 +0,0 @@
1
- #!/usr/bin/env node
2
- /**
3
- * Smart Audit Script (Production-Ready)
4
- *
5
- * The "Judge" - Orchestrates all compliance checks:
6
- * 1. Memory Recall (Past Mistakes)
7
- * 2. Constitution Checks (Governance)
8
- * 3. Real-time Analysis
9
- *
10
- * Usage: agent audit [directory]
11
- */
12
-
13
- import fs from "fs";
14
- import path from "path";
15
- import { fileURLToPath } from "url";
16
- import { scanDirectory, loadKnowledge, saveKnowledge, printResults } from "./recall.js";
17
- import { AGENT_DIR, VERSION } from "./config.js";
18
- import * as p from "@clack/prompts";
19
- import pc from "picocolors";
20
-
21
- const __dirname = path.dirname(fileURLToPath(import.meta.url));
22
-
23
- // ============================================================================
24
- // AUDIT CONFIGURATION
25
- // ============================================================================
26
-
27
- const SCAN_EXTENSIONS = [".js", ".ts", ".tsx", ".jsx", ".mjs"];
28
-
29
- // ============================================================================
30
- // GOVERNANCE CHECKS
31
- // ============================================================================
32
-
33
- /**
34
- * Check if governance files exist
35
- * @param {string} projectRoot
36
- * @returns {{ passed: boolean, details: string[] }}
37
- */
38
- function checkGovernance(projectRoot) {
39
- const details = [];
40
- let passed = true;
41
-
42
- const governanceFiles = [
43
- { path: path.join(projectRoot, ".agent", "GEMINI.md"), name: "GEMINI.md" },
44
- { path: path.join(projectRoot, ".agent", "ARCHITECTURE.md"), name: "ARCHITECTURE.md" }
45
- ];
46
-
47
- governanceFiles.forEach(file => {
48
- if (fs.existsSync(file.path)) {
49
- details.push(`${pc.green("✓")} ${file.name} found`);
50
- } else {
51
- details.push(`${pc.yellow("⚠")} ${file.name} not found (optional)`);
52
- }
53
- });
54
-
55
- // Check for skills
56
- const skillsDir = path.join(projectRoot, ".agent", "skills");
57
- if (fs.existsSync(skillsDir)) {
58
- const skills = fs.readdirSync(skillsDir).filter(f =>
59
- fs.statSync(path.join(skillsDir, f)).isDirectory()
60
- );
61
- details.push(`${pc.green("✓")} ${skills.length} skill(s) loaded`);
62
- }
63
-
64
- return { passed, details };
65
- }
66
-
67
- // ============================================================================
68
- // MAIN AUDIT
69
- // ============================================================================
70
-
71
- /**
72
- * Run full audit on a project
73
- * @param {string} projectRoot
74
- */
75
- async function runAudit(projectRoot) {
76
- p.intro(pc.cyan(`⚖️ SMART AUDIT v${VERSION}`));
77
-
78
- let exitCode = 0;
79
- const startTime = Date.now();
80
-
81
- // Phase 1: Memory Recall
82
- const s1 = p.spinner();
83
- s1.start("Phase 1: Memory Recall");
84
-
85
- const db = loadKnowledge();
86
-
87
- if (db.lessons.length === 0) {
88
- s1.stop("Phase 1: No lessons learned yet");
89
- } else {
90
- const { results } = scanDirectory(projectRoot, db, SCAN_EXTENSIONS);
91
-
92
- if (results.length > 0) {
93
- const stats = printResults(results);
94
- saveKnowledge(db);
95
-
96
- if (stats.errors > 0) {
97
- exitCode = 1;
98
- }
99
- s1.stop(`Phase 1: Found ${stats.total} violation(s)`);
100
- } else {
101
- s1.stop("Phase 1: No violations found");
102
- }
103
- }
104
-
105
- // Phase 2: Governance
106
- const s2 = p.spinner();
107
- s2.start("Phase 2: Governance Check");
108
-
109
- const govResult = checkGovernance(projectRoot);
110
- s2.stop("Phase 2: Governance checked");
111
-
112
- p.note(govResult.details.join("\n"), pc.dim("Governance"));
113
-
114
- // Phase 3: Summary
115
- const duration = ((Date.now() - startTime) / 1000).toFixed(2);
116
- const totalHits = db.lessons.reduce((sum, l) => sum + (l.hitCount || 0), 0);
117
-
118
- const summaryLines = [
119
- `⏱️ Completed in ${duration}s`,
120
- `📊 Lessons in memory: ${db.lessons.length}`,
121
- `🎯 Total pattern hits: ${totalHits}`
122
- ];
123
- p.note(summaryLines.join("\n"), pc.dim("Summary"));
124
-
125
- if (exitCode === 0) {
126
- p.outro(pc.green("✅ AUDIT PASSED: Code is smart and compliant"));
127
- } else {
128
- p.outro(pc.red("❌ AUDIT FAILED: Please fix ERROR violations"));
129
- }
130
-
131
- process.exit(exitCode);
132
- }
133
-
134
- // ============================================================================
135
- // CLI
136
- // ============================================================================
137
-
138
- const args = process.argv.slice(2);
139
- const projectRoot = args[0] || process.cwd();
140
-
141
- if (args.includes("--help")) {
142
- console.log(`
143
- ⚖️ Smart Audit - Compliance Checker
144
-
145
- Usage:
146
- agent audit [directory]
147
-
148
- Options:
149
- --help Show this help
150
- `);
151
- process.exit(0);
152
- }
153
-
154
- runAudit(projectRoot);
@@ -1,100 +0,0 @@
1
- /**
2
- * @fileoverview Tests for audit.js functionality
3
- */
4
- import { describe, it, expect, beforeEach, afterEach } from "vitest";
5
- import fs from "fs";
6
- import path from "path";
7
- import os from "os";
8
-
9
- const TEST_DIR = path.join(os.tmpdir(), "agent-skill-kit-audit-test");
10
- const AGENT_DIR = path.join(TEST_DIR, ".agent");
11
-
12
- describe("Audit - Governance Check", () => {
13
- beforeEach(() => {
14
- fs.mkdirSync(AGENT_DIR, { recursive: true });
15
- });
16
-
17
- afterEach(() => {
18
- fs.rmSync(TEST_DIR, { recursive: true, force: true });
19
- });
20
-
21
- it("detects GEMINI.md presence", () => {
22
- const geminiPath = path.join(AGENT_DIR, "GEMINI.md");
23
-
24
- // Before creation
25
- expect(fs.existsSync(geminiPath)).toBe(false);
26
-
27
- // After creation
28
- fs.writeFileSync(geminiPath, "# Test", "utf8");
29
- expect(fs.existsSync(geminiPath)).toBe(true);
30
- });
31
-
32
- it("detects ARCHITECTURE.md presence", () => {
33
- const archPath = path.join(AGENT_DIR, "ARCHITECTURE.md");
34
- fs.writeFileSync(archPath, "# Architecture", "utf8");
35
-
36
- expect(fs.existsSync(archPath)).toBe(true);
37
- });
38
-
39
- it("counts skills in skills directory", () => {
40
- const skillsDir = path.join(AGENT_DIR, "skills");
41
- fs.mkdirSync(skillsDir, { recursive: true });
42
-
43
- // Create mock skills
44
- fs.mkdirSync(path.join(skillsDir, "skill-1"));
45
- fs.mkdirSync(path.join(skillsDir, "skill-2"));
46
-
47
- const skills = fs.readdirSync(skillsDir).filter(f =>
48
- fs.statSync(path.join(skillsDir, f)).isDirectory()
49
- );
50
-
51
- expect(skills.length).toBe(2);
52
- });
53
- });
54
-
55
- describe("Audit - Compliance Results", () => {
56
- it("calculates pass/fail status correctly", () => {
57
- const results = {
58
- errors: 0,
59
- warnings: 2,
60
- total: 2
61
- };
62
-
63
- // Errors = 0 means pass
64
- expect(results.errors === 0).toBe(true);
65
- });
66
-
67
- it("fails when errors exist", () => {
68
- const results = {
69
- errors: 1,
70
- warnings: 0,
71
- total: 1
72
- };
73
-
74
- expect(results.errors > 0).toBe(true);
75
- });
76
-
77
- it("calculates total correctly", () => {
78
- const violations = [
79
- { lesson: { severity: "ERROR" }, matches: [1, 2] },
80
- { lesson: { severity: "WARNING" }, matches: [1] }
81
- ];
82
-
83
- let total = 0;
84
- let errors = 0;
85
- let warnings = 0;
86
-
87
- violations.forEach(v => {
88
- total += v.matches.length;
89
- if (v.lesson.severity === "ERROR") {
90
- errors += v.matches.length;
91
- } else {
92
- warnings += v.matches.length;
93
- }
94
- });
95
-
96
- expect(total).toBe(3);
97
- expect(errors).toBe(2);
98
- expect(warnings).toBe(1);
99
- });
100
- });