pikakit 2.0.0 → 3.0.1
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.
- package/README.md +8 -8
- package/lib/agent-cli/bin/agent.js +187 -0
- package/lib/agent-cli/lib/audit.js +154 -0
- package/lib/agent-cli/lib/audit.test.js +100 -0
- package/lib/agent-cli/lib/auto-learn.js +319 -0
- package/lib/agent-cli/lib/backup.js +138 -0
- package/lib/agent-cli/lib/backup.test.js +78 -0
- package/lib/agent-cli/lib/cognitive-lesson.js +476 -0
- package/lib/agent-cli/lib/completion.js +149 -0
- package/lib/agent-cli/lib/config.js +35 -0
- package/lib/agent-cli/lib/eslint-fix.js +238 -0
- package/lib/agent-cli/lib/evolution-signal.js +215 -0
- package/lib/agent-cli/lib/export.js +86 -0
- package/lib/agent-cli/lib/export.test.js +65 -0
- package/lib/agent-cli/lib/fix.js +337 -0
- package/lib/agent-cli/lib/fix.test.js +80 -0
- package/lib/agent-cli/lib/gemini-export.js +83 -0
- package/lib/agent-cli/lib/generate-registry.js +42 -0
- package/lib/agent-cli/lib/hooks/install-hooks.js +152 -0
- package/lib/agent-cli/lib/hooks/lint-learn.js +172 -0
- package/lib/agent-cli/lib/icons.js +93 -0
- package/lib/agent-cli/lib/ignore.js +116 -0
- package/lib/agent-cli/lib/ignore.test.js +58 -0
- package/lib/agent-cli/lib/init.js +124 -0
- package/lib/agent-cli/lib/knowledge-index.js +326 -0
- package/lib/agent-cli/lib/knowledge-metrics.js +335 -0
- package/lib/agent-cli/lib/knowledge-retention.js +398 -0
- package/lib/agent-cli/lib/knowledge-validator.js +312 -0
- package/lib/agent-cli/lib/learn.js +255 -0
- package/lib/agent-cli/lib/learn.test.js +70 -0
- package/lib/agent-cli/lib/proposals.js +199 -0
- package/lib/agent-cli/lib/proposals.test.js +56 -0
- package/lib/agent-cli/lib/recall.js +835 -0
- package/lib/agent-cli/lib/recall.test.js +107 -0
- package/lib/agent-cli/lib/selfevolution-bridge.js +167 -0
- package/lib/agent-cli/lib/settings.js +203 -0
- package/lib/agent-cli/lib/skill-learn.js +296 -0
- package/lib/agent-cli/lib/stats.js +132 -0
- package/lib/agent-cli/lib/stats.test.js +94 -0
- package/lib/agent-cli/lib/types.js +33 -0
- package/lib/agent-cli/lib/ui/audit-ui.js +146 -0
- package/lib/agent-cli/lib/ui/backup-ui.js +107 -0
- package/lib/agent-cli/lib/ui/clack-helpers.js +317 -0
- package/lib/agent-cli/lib/ui/common.js +83 -0
- package/lib/agent-cli/lib/ui/completion-ui.js +126 -0
- package/lib/agent-cli/lib/ui/custom-select.js +69 -0
- package/lib/agent-cli/lib/ui/dashboard-ui.js +222 -0
- package/lib/agent-cli/lib/ui/evolution-signals-ui.js +107 -0
- package/lib/agent-cli/lib/ui/export-ui.js +94 -0
- package/lib/agent-cli/lib/ui/fix-all-ui.js +191 -0
- package/lib/agent-cli/lib/ui/help-ui.js +49 -0
- package/lib/agent-cli/lib/ui/index.js +199 -0
- package/lib/agent-cli/lib/ui/init-ui.js +56 -0
- package/lib/agent-cli/lib/ui/knowledge-ui.js +55 -0
- package/lib/agent-cli/lib/ui/learn-ui.js +706 -0
- package/lib/agent-cli/lib/ui/lessons-ui.js +148 -0
- package/lib/agent-cli/lib/ui/pretty.js +145 -0
- package/lib/agent-cli/lib/ui/proposals-ui.js +99 -0
- package/lib/agent-cli/lib/ui/recall-ui.js +342 -0
- package/lib/agent-cli/lib/ui/routing-demo.js +79 -0
- package/lib/agent-cli/lib/ui/routing-ui.js +325 -0
- package/lib/agent-cli/lib/ui/settings-ui.js +381 -0
- package/lib/agent-cli/lib/ui/stats-ui.js +123 -0
- package/lib/agent-cli/lib/ui/watch-ui.js +236 -0
- package/lib/agent-cli/lib/watcher.js +181 -0
- package/lib/agent-cli/lib/watcher.test.js +85 -0
- package/lib/agent-cli/src/MIGRATION.md +418 -0
- package/lib/agent-cli/src/README.md +367 -0
- package/lib/agent-cli/src/core/evolution/evolution-signal.js +42 -0
- package/lib/agent-cli/src/core/evolution/index.js +17 -0
- package/lib/agent-cli/src/core/evolution/review-gate.js +40 -0
- package/lib/agent-cli/src/core/evolution/signal-detector.js +137 -0
- package/lib/agent-cli/src/core/evolution/signal-queue.js +79 -0
- package/lib/agent-cli/src/core/evolution/threshold-checker.js +79 -0
- package/lib/agent-cli/src/core/index.js +15 -0
- package/lib/agent-cli/src/core/learning/cognitive-enhancer.js +282 -0
- package/lib/agent-cli/src/core/learning/index.js +12 -0
- package/lib/agent-cli/src/core/learning/lesson-synthesizer.js +83 -0
- package/lib/agent-cli/src/core/scanning/index.js +14 -0
- package/lib/agent-cli/src/data/index.js +13 -0
- package/lib/agent-cli/src/data/repositories/index.js +8 -0
- package/lib/agent-cli/src/data/repositories/lesson-repository.js +130 -0
- package/lib/agent-cli/src/data/repositories/signal-repository.js +119 -0
- package/lib/agent-cli/src/data/storage/index.js +8 -0
- package/lib/agent-cli/src/data/storage/json-storage.js +64 -0
- package/lib/agent-cli/src/data/storage/yaml-storage.js +66 -0
- package/lib/agent-cli/src/infrastructure/index.js +13 -0
- package/lib/agent-cli/src/presentation/formatters/skill-formatter.js +232 -0
- package/lib/agent-cli/src/services/export-service.js +162 -0
- package/lib/agent-cli/src/services/index.js +13 -0
- package/lib/agent-cli/src/services/learning-service.js +99 -0
- package/package.json +5 -3
package/README.md
CHANGED
|
@@ -19,8 +19,8 @@ npx pikakit
|
|
|
19
19
|
|
|
20
20
|
| Component | Count | Description |
|
|
21
21
|
|-----------|-------|-------------|
|
|
22
|
-
| **Skills** |
|
|
23
|
-
| **Workflows** |
|
|
22
|
+
| **Skills** | 50 | FAANG-grade coding skills |
|
|
23
|
+
| **Workflows** | 25 | `/think`, `/build`, `/autopilot`, etc. |
|
|
24
24
|
| **Agents** | 25 | Specialist AI agents |
|
|
25
25
|
| **Rules** | GEMINI.md | AI behavior configuration |
|
|
26
26
|
| **Scripts** | 25 | JavaScript automation scripts |
|
|
@@ -63,8 +63,8 @@ npx pikakit add myteam/company-skills # Custom skills
|
|
|
63
63
|
your-project/
|
|
64
64
|
├── .agent/
|
|
65
65
|
│ ├── GEMINI.md # AI Rules
|
|
66
|
-
│ ├── skills/ #
|
|
67
|
-
│ ├── workflows/ #
|
|
66
|
+
│ ├── skills/ # 50 Skills
|
|
67
|
+
│ ├── workflows/ # 25 Workflows
|
|
68
68
|
│ ├── agents/ # 25 Agents
|
|
69
69
|
│ ├── knowledge/ # Learning memory
|
|
70
70
|
│ ├── config/ # Configuration
|
|
@@ -158,19 +158,19 @@ npx pikakit add pikakit-agent-skills --force
|
|
|
158
158
|
├── CONTINUOUS_EXECUTION_POLICY.md # Autopilot Rules
|
|
159
159
|
├── WORKFLOW_CHAINS.md # Workflow Patterns
|
|
160
160
|
│
|
|
161
|
-
├── skills/ #
|
|
161
|
+
├── skills/ # 50 Skills
|
|
162
162
|
│ ├── auto-learner/
|
|
163
163
|
│ ├── react-architect/
|
|
164
164
|
│ ├── typescript-expert/
|
|
165
165
|
│ ├── debug-pro/
|
|
166
166
|
│ ├── studio/
|
|
167
|
-
│ └── ... (
|
|
167
|
+
│ └── ... (45 more)
|
|
168
168
|
│
|
|
169
|
-
├── workflows/ #
|
|
169
|
+
├── workflows/ # 25 Workflows
|
|
170
170
|
│ ├── think.md
|
|
171
171
|
│ ├── build.md
|
|
172
172
|
│ ├── autopilot.md
|
|
173
|
-
│ └── ... (
|
|
173
|
+
│ └── ... (22 more)
|
|
174
174
|
│
|
|
175
175
|
├── agents/ # 25 Agents
|
|
176
176
|
│ ├── frontend-specialist.md
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Smart Agent CLI - ESM Version (Production-Ready)
|
|
4
|
+
*
|
|
5
|
+
* The main interface for humans to interact with the Smart Agent Skills system.
|
|
6
|
+
*
|
|
7
|
+
* Commands:
|
|
8
|
+
* learn Add new lessons to memory
|
|
9
|
+
* recall Check files against memory
|
|
10
|
+
* audit Full compliance audit
|
|
11
|
+
* watch Real-time file monitoring
|
|
12
|
+
* stats Knowledge base statistics
|
|
13
|
+
* install-hooks Install git pre-commit hook
|
|
14
|
+
* lint-learn Auto-learn from ESLint output
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import { spawn } from "child_process";
|
|
18
|
+
import path from "path";
|
|
19
|
+
import { fileURLToPath } from "url";
|
|
20
|
+
import { VERSION } from "../lib/config.js";
|
|
21
|
+
|
|
22
|
+
// Fix UTF-8 output on Windows PowerShell/Console
|
|
23
|
+
if (process.platform === "win32" && process.stdout.isTTY) {
|
|
24
|
+
process.stdout.setDefaultEncoding("utf8");
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
28
|
+
const ARGS = process.argv.slice(2);
|
|
29
|
+
const COMMAND = ARGS[0];
|
|
30
|
+
const SCRIPTS_DIR = path.join(__dirname, "..", "lib");
|
|
31
|
+
const HOOKS_DIR = path.join(SCRIPTS_DIR, "hooks");
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Run a script with given arguments
|
|
35
|
+
* @param {string} script - Script filename (relative to lib/)
|
|
36
|
+
* @param {string[]} args - Arguments to pass
|
|
37
|
+
* @param {string} baseDir - Base directory for script
|
|
38
|
+
*/
|
|
39
|
+
function run(script, args = [], baseDir = SCRIPTS_DIR) {
|
|
40
|
+
const scriptPath = path.join(baseDir, script);
|
|
41
|
+
const child = spawn("node", [scriptPath, ...args], {
|
|
42
|
+
stdio: "inherit",
|
|
43
|
+
shell: true
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
child.on("close", (code) => {
|
|
47
|
+
process.exit(code || 0);
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
child.on("error", (err) => {
|
|
51
|
+
console.error(`❌ Failed to run ${script}:`, err.message);
|
|
52
|
+
process.exit(1);
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function printHelp() {
|
|
57
|
+
console.log(`
|
|
58
|
+
🤖 PikaKit CLI v${VERSION}
|
|
59
|
+
|
|
60
|
+
Usage: ag-smart <command> [options]
|
|
61
|
+
|
|
62
|
+
${"─".repeat(50)}
|
|
63
|
+
|
|
64
|
+
📚 CORE COMMANDS:
|
|
65
|
+
|
|
66
|
+
learn Teach a new lesson to the memory
|
|
67
|
+
ag-smart learn --add --pattern "var " --message "Use let/const"
|
|
68
|
+
ag-smart learn --list
|
|
69
|
+
ag-smart learn --remove LEARN-001
|
|
70
|
+
|
|
71
|
+
recall Check file(s) against learned patterns
|
|
72
|
+
ag-smart recall src/app.js
|
|
73
|
+
ag-smart recall ./src
|
|
74
|
+
|
|
75
|
+
audit Run full compliance audit
|
|
76
|
+
ag-smart audit [directory]
|
|
77
|
+
|
|
78
|
+
${"─".repeat(50)}
|
|
79
|
+
|
|
80
|
+
🚀 PRODUCTION FEATURES:
|
|
81
|
+
|
|
82
|
+
watch Real-time file monitoring
|
|
83
|
+
ag-smart watch [directory]
|
|
84
|
+
|
|
85
|
+
stats Knowledge base statistics
|
|
86
|
+
ag-smart stats
|
|
87
|
+
|
|
88
|
+
install-hooks Install git pre-commit hook
|
|
89
|
+
ag-smart install-hooks
|
|
90
|
+
ag-smart install-hooks --remove
|
|
91
|
+
|
|
92
|
+
lint-learn Auto-learn from ESLint JSON output
|
|
93
|
+
npx eslint . --format json | ag-smart lint-learn
|
|
94
|
+
|
|
95
|
+
fix 🆕 Auto-fix violations
|
|
96
|
+
ag-smart fix <file|dir> [--mode safe|aggressive]
|
|
97
|
+
|
|
98
|
+
sync-skills 🆕 Sync hot patterns to SKILL.md
|
|
99
|
+
ag-smart sync-skills
|
|
100
|
+
|
|
101
|
+
index 🆕 Knowledge index management
|
|
102
|
+
ag-smart index --rebuild | --status
|
|
103
|
+
|
|
104
|
+
metrics 🆕 Knowledge metrics dashboard
|
|
105
|
+
ag-smart metrics [--json]
|
|
106
|
+
|
|
107
|
+
validate Schema validation for knowledge files
|
|
108
|
+
ag-smart validate [--fix] [--json]
|
|
109
|
+
|
|
110
|
+
retention Retention policy runner
|
|
111
|
+
ag-smart retention [--dry-run] [--apply] [--status]
|
|
112
|
+
|
|
113
|
+
${"─".repeat(50)}
|
|
114
|
+
|
|
115
|
+
📖 HELP:
|
|
116
|
+
|
|
117
|
+
help, --help Show this help message
|
|
118
|
+
--version Show version number
|
|
119
|
+
|
|
120
|
+
💡 Docs: https://github.com/pikakit/agent-skills
|
|
121
|
+
`);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// Command routing
|
|
125
|
+
switch (COMMAND) {
|
|
126
|
+
// Core commands (v2 versions)
|
|
127
|
+
case "learn":
|
|
128
|
+
run("learn.js", ARGS.slice(1));
|
|
129
|
+
break;
|
|
130
|
+
case "recall":
|
|
131
|
+
run("recall.js", ARGS.slice(1));
|
|
132
|
+
break;
|
|
133
|
+
case "audit":
|
|
134
|
+
run("audit.js", ARGS.slice(1));
|
|
135
|
+
break;
|
|
136
|
+
|
|
137
|
+
// Production features
|
|
138
|
+
case "watch":
|
|
139
|
+
run("watcher.js", ARGS.slice(1));
|
|
140
|
+
break;
|
|
141
|
+
case "stats":
|
|
142
|
+
run("stats.js", ARGS.slice(1));
|
|
143
|
+
break;
|
|
144
|
+
case "install-hooks":
|
|
145
|
+
run("install-hooks.js", ARGS.slice(1), HOOKS_DIR);
|
|
146
|
+
break;
|
|
147
|
+
case "lint-learn":
|
|
148
|
+
run("lint-learn.js", ARGS.slice(1), HOOKS_DIR);
|
|
149
|
+
break;
|
|
150
|
+
case "fix":
|
|
151
|
+
run("fix.js", ARGS.slice(1));
|
|
152
|
+
break;
|
|
153
|
+
case "sync-skills":
|
|
154
|
+
run("skill-learn.js", ARGS.slice(1));
|
|
155
|
+
break;
|
|
156
|
+
case "index":
|
|
157
|
+
run("knowledge-index.js", ARGS.slice(1));
|
|
158
|
+
break;
|
|
159
|
+
case "metrics":
|
|
160
|
+
run("knowledge-metrics.js", ARGS.slice(1));
|
|
161
|
+
break;
|
|
162
|
+
case "validate":
|
|
163
|
+
run("knowledge-validator.js", ARGS.slice(1));
|
|
164
|
+
break;
|
|
165
|
+
case "retention":
|
|
166
|
+
run("knowledge-retention.js", ARGS.slice(1));
|
|
167
|
+
break;
|
|
168
|
+
|
|
169
|
+
// Meta
|
|
170
|
+
case "--version":
|
|
171
|
+
case "-v":
|
|
172
|
+
console.log(VERSION);
|
|
173
|
+
break;
|
|
174
|
+
case "help":
|
|
175
|
+
case "--help":
|
|
176
|
+
case "-h":
|
|
177
|
+
printHelp();
|
|
178
|
+
break;
|
|
179
|
+
case undefined:
|
|
180
|
+
// No command = show interactive Clack menu
|
|
181
|
+
import("../lib/ui/index.js").then(m => m.showMainMenu()).catch(console.error);
|
|
182
|
+
break;
|
|
183
|
+
default:
|
|
184
|
+
console.log(`❌ Unknown command: ${COMMAND}`);
|
|
185
|
+
console.log(" Run 'ag-smart help' for available commands.\n");
|
|
186
|
+
process.exit(1);
|
|
187
|
+
}
|
|
@@ -0,0 +1,154 @@
|
|
|
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);
|
|
@@ -0,0 +1,100 @@
|
|
|
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
|
+
});
|