add-skill-kit 3.2.3 → 3.2.5
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 +1 -1
- package/bin/lib/commands/help.js +0 -4
- package/bin/lib/commands/install.js +90 -9
- package/bin/lib/ui.js +1 -1
- package/lib/agent-cli/__tests__/adaptive_engine.test.js +190 -0
- package/lib/agent-cli/__tests__/integration/cross_script.test.js +222 -0
- package/lib/agent-cli/__tests__/integration/full_cycle.test.js +230 -0
- package/lib/agent-cli/__tests__/pattern_analyzer.test.js +173 -0
- package/lib/agent-cli/__tests__/pre_execution_check.test.js +167 -0
- package/lib/agent-cli/__tests__/skill_injector.test.js +191 -0
- package/lib/agent-cli/bin/agent.js +191 -0
- package/lib/agent-cli/dashboard/dashboard_server.js +340 -0
- package/lib/agent-cli/dashboard/index.html +538 -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/auto_preview.py +148 -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/checklist.py +222 -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/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/learn.js +255 -0
- package/lib/agent-cli/lib/learn.test.js +70 -0
- package/lib/agent-cli/lib/migrate-to-v4.js +322 -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 +820 -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/session_manager.py +120 -0
- package/lib/agent-cli/lib/settings.js +227 -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/verify_all.py +327 -0
- package/lib/agent-cli/lib/watcher.js +181 -0
- package/lib/agent-cli/lib/watcher.test.js +85 -0
- package/lib/agent-cli/package.json +51 -0
- package/lib/agent-cli/scripts/adaptive_engine.js +381 -0
- package/lib/agent-cli/scripts/dashboard_server.js +224 -0
- package/lib/agent-cli/scripts/error_sensor.js +565 -0
- package/lib/agent-cli/scripts/learn_from_failure.js +225 -0
- package/lib/agent-cli/scripts/pattern_analyzer.js +781 -0
- package/lib/agent-cli/scripts/pre_execution_check.js +623 -0
- package/lib/agent-cli/scripts/rule_sharing.js +374 -0
- package/lib/agent-cli/scripts/skill_injector.js +387 -0
- package/lib/agent-cli/scripts/success_sensor.js +500 -0
- package/lib/agent-cli/scripts/user_correction_sensor.js +426 -0
- package/lib/agent-cli/services/auto-learn-service.js +247 -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/lib/agent-cli/types/index.d.ts +343 -0
- package/lib/agent-cli/utils/benchmark.js +269 -0
- package/lib/agent-cli/utils/logger.js +303 -0
- package/lib/agent-cli/utils/ml_patterns.js +300 -0
- package/lib/agent-cli/utils/recovery.js +312 -0
- package/lib/agent-cli/utils/telemetry.js +290 -0
- package/lib/agentskillskit-cli/README.md +21 -0
- package/{node_modules/agentskillskit-cli/bin → lib/agentskillskit-cli}/ag-smart.js +15 -15
- package/lib/agentskillskit-cli/package.json +51 -0
- package/package.json +19 -9
- /package/bin/{cli.js → kit.js} +0 -0
- /package/{node_modules/agentskillskit-cli → lib/agent-cli}/README.md +0 -0
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Lint Learn - Auto-Learn from ESLint Output
|
|
4
|
+
*
|
|
5
|
+
* Parses ESLint JSON output and creates lessons automatically.
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* npx eslint . --format json | agent lint-learn
|
|
9
|
+
* npx eslint . --format json > output.json && agent lint-learn output.json
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import fs from "fs";
|
|
13
|
+
import { loadKnowledge, saveKnowledge } from "../recall.js";
|
|
14
|
+
|
|
15
|
+
// ============================================================================
|
|
16
|
+
// ESLINT PARSER
|
|
17
|
+
// ============================================================================
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Parse ESLint JSON output and extract rules
|
|
21
|
+
* @param {string} jsonContent
|
|
22
|
+
* @returns {Array<{ rule: string, count: number, message: string }>}
|
|
23
|
+
*/
|
|
24
|
+
function parseEslintOutput(jsonContent) {
|
|
25
|
+
const ruleStats = {};
|
|
26
|
+
|
|
27
|
+
try {
|
|
28
|
+
const results = JSON.parse(jsonContent);
|
|
29
|
+
|
|
30
|
+
results.forEach(file => {
|
|
31
|
+
if (!file.messages) return;
|
|
32
|
+
|
|
33
|
+
file.messages.forEach(msg => {
|
|
34
|
+
if (!msg.ruleId) return;
|
|
35
|
+
|
|
36
|
+
if (!ruleStats[msg.ruleId]) {
|
|
37
|
+
ruleStats[msg.ruleId] = {
|
|
38
|
+
rule: msg.ruleId,
|
|
39
|
+
count: 0,
|
|
40
|
+
message: msg.message,
|
|
41
|
+
severity: msg.severity === 2 ? "ERROR" : "WARNING"
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
ruleStats[msg.ruleId].count++;
|
|
45
|
+
});
|
|
46
|
+
});
|
|
47
|
+
} catch (e) {
|
|
48
|
+
console.error("❌ Failed to parse ESLint JSON output:", e.message);
|
|
49
|
+
process.exit(1);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
return Object.values(ruleStats).sort((a, b) => b.count - a.count);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Convert ESLint rule to regex pattern
|
|
57
|
+
* @param {string} rule - ESLint rule ID
|
|
58
|
+
* @returns {string}
|
|
59
|
+
*/
|
|
60
|
+
function ruleToPattern(rule) {
|
|
61
|
+
// Map common ESLint rules to regex patterns
|
|
62
|
+
const patterns = {
|
|
63
|
+
"no-console": "console\\.(log|warn|error|info|debug)",
|
|
64
|
+
"no-debugger": "\\bdebugger\\b",
|
|
65
|
+
"no-var": "\\bvar\\s+",
|
|
66
|
+
"no-unused-vars": null, // Can't easily detect with regex
|
|
67
|
+
"no-undef": null,
|
|
68
|
+
"eqeqeq": "[^!=]==[^=]",
|
|
69
|
+
"no-eval": "\\beval\\s*\\(",
|
|
70
|
+
"no-alert": "\\balert\\s*\\("
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
return patterns[rule] || null;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// ============================================================================
|
|
77
|
+
// MAIN
|
|
78
|
+
// ============================================================================
|
|
79
|
+
|
|
80
|
+
async function main() {
|
|
81
|
+
const args = process.argv.slice(2);
|
|
82
|
+
let jsonContent = "";
|
|
83
|
+
|
|
84
|
+
if (args.includes("--help")) {
|
|
85
|
+
console.log(`
|
|
86
|
+
🔧 Lint Learn - Auto-Learn from ESLint
|
|
87
|
+
|
|
88
|
+
Usage:
|
|
89
|
+
npx eslint . --format json | agent lint-learn
|
|
90
|
+
agent lint-learn eslint-output.json
|
|
91
|
+
|
|
92
|
+
Creates lessons from ESLint violations automatically.
|
|
93
|
+
`);
|
|
94
|
+
process.exit(0);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// Read from file or stdin
|
|
98
|
+
if (args[0] && !args[0].startsWith("-")) {
|
|
99
|
+
if (fs.existsSync(args[0])) {
|
|
100
|
+
jsonContent = fs.readFileSync(args[0], "utf8");
|
|
101
|
+
} else {
|
|
102
|
+
console.error(`❌ File not found: ${args[0]}`);
|
|
103
|
+
process.exit(1);
|
|
104
|
+
}
|
|
105
|
+
} else {
|
|
106
|
+
// Read from stdin
|
|
107
|
+
const chunks = [];
|
|
108
|
+
process.stdin.setEncoding("utf8");
|
|
109
|
+
|
|
110
|
+
for await (const chunk of process.stdin) {
|
|
111
|
+
chunks.push(chunk);
|
|
112
|
+
}
|
|
113
|
+
jsonContent = chunks.join("");
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
if (!jsonContent.trim()) {
|
|
117
|
+
console.log("ℹ️ No input received. Pipe ESLint JSON output or provide a file.");
|
|
118
|
+
process.exit(0);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
const rules = parseEslintOutput(jsonContent);
|
|
122
|
+
|
|
123
|
+
if (rules.length === 0) {
|
|
124
|
+
console.log("✅ No ESLint violations found.");
|
|
125
|
+
process.exit(0);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
console.log(`\n🔧 Lint Learn - Found ${rules.length} unique ESLint rule(s)\n`);
|
|
129
|
+
|
|
130
|
+
const db = loadKnowledge();
|
|
131
|
+
let added = 0;
|
|
132
|
+
|
|
133
|
+
rules.forEach(r => {
|
|
134
|
+
const pattern = ruleToPattern(r.rule);
|
|
135
|
+
|
|
136
|
+
if (!pattern) {
|
|
137
|
+
console.log(`⏭️ Skipped: ${r.rule} (no regex pattern available)`);
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// Check if already exists
|
|
142
|
+
const exists = db.lessons.some(l => l.pattern === pattern);
|
|
143
|
+
if (exists) {
|
|
144
|
+
console.log(`⏭️ Skipped: ${r.rule} (already in memory)`);
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
const id = `LEARN-${String(db.lessons.length + 1).padStart(3, "0")}`;
|
|
149
|
+
|
|
150
|
+
db.lessons.push({
|
|
151
|
+
id,
|
|
152
|
+
pattern,
|
|
153
|
+
message: `ESLint: ${r.rule} - ${r.message}`,
|
|
154
|
+
severity: r.severity,
|
|
155
|
+
source: "eslint",
|
|
156
|
+
hitCount: r.count,
|
|
157
|
+
addedAt: new Date().toISOString()
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
added++;
|
|
161
|
+
console.log(`✅ Added: [${id}] ${r.rule} (${r.count} occurrences)`);
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
if (added > 0) {
|
|
165
|
+
saveKnowledge(db);
|
|
166
|
+
console.log(`\n🎓 Learned ${added} new lesson(s) from ESLint output.\n`);
|
|
167
|
+
} else {
|
|
168
|
+
console.log("\nℹ️ No new lessons to add.\n");
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
main();
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Ignore patterns parser for Agent Skill Kit
|
|
3
|
+
* Supports .agentignore file with glob patterns
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import fs from "fs";
|
|
7
|
+
import path from "path";
|
|
8
|
+
import { cwd } from "./config.js";
|
|
9
|
+
|
|
10
|
+
/** Default patterns always ignored */
|
|
11
|
+
const DEFAULT_IGNORES = [
|
|
12
|
+
"node_modules/**",
|
|
13
|
+
".git/**",
|
|
14
|
+
"dist/**",
|
|
15
|
+
"build/**",
|
|
16
|
+
".next/**",
|
|
17
|
+
"coverage/**",
|
|
18
|
+
"*.log"
|
|
19
|
+
];
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Load ignore patterns from .agentignore file
|
|
23
|
+
* @param {string} basePath - Base directory
|
|
24
|
+
* @returns {string[]} Array of patterns
|
|
25
|
+
*/
|
|
26
|
+
export function loadIgnorePatterns(basePath = cwd) {
|
|
27
|
+
const patterns = [...DEFAULT_IGNORES];
|
|
28
|
+
const ignoreFile = path.join(basePath, ".agentignore");
|
|
29
|
+
|
|
30
|
+
try {
|
|
31
|
+
if (fs.existsSync(ignoreFile)) {
|
|
32
|
+
const content = fs.readFileSync(ignoreFile, "utf8");
|
|
33
|
+
const lines = content.split("\n");
|
|
34
|
+
|
|
35
|
+
for (const line of lines) {
|
|
36
|
+
const trimmed = line.trim();
|
|
37
|
+
// Skip empty lines and comments
|
|
38
|
+
if (trimmed && !trimmed.startsWith("#")) {
|
|
39
|
+
patterns.push(trimmed);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
} catch (e) {
|
|
44
|
+
// Silently use defaults
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return [...new Set(patterns)]; // Remove duplicates
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Check if a file path matches any ignore pattern
|
|
52
|
+
* @param {string} filePath - Relative file path
|
|
53
|
+
* @param {string[]} patterns - Ignore patterns
|
|
54
|
+
* @returns {boolean}
|
|
55
|
+
*/
|
|
56
|
+
export function isIgnored(filePath, patterns) {
|
|
57
|
+
const normalized = filePath.replace(/\\/g, "/");
|
|
58
|
+
|
|
59
|
+
for (const pattern of patterns) {
|
|
60
|
+
// Simple glob matching
|
|
61
|
+
const regex = patternToRegex(pattern);
|
|
62
|
+
if (regex.test(normalized)) {
|
|
63
|
+
return true;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
return false;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Convert glob pattern to regex
|
|
72
|
+
* @param {string} pattern - Glob pattern
|
|
73
|
+
* @returns {RegExp}
|
|
74
|
+
*/
|
|
75
|
+
function patternToRegex(pattern) {
|
|
76
|
+
let regex = pattern
|
|
77
|
+
.replace(/\./g, "\\.") // Escape dots
|
|
78
|
+
.replace(/\*\*/g, ".*") // ** matches everything
|
|
79
|
+
.replace(/\*/g, "[^/]*") // * matches segment
|
|
80
|
+
.replace(/\?/g, "."); // ? matches single char
|
|
81
|
+
|
|
82
|
+
// Handle directory patterns (ending with /)
|
|
83
|
+
if (pattern.endsWith("/")) {
|
|
84
|
+
regex = regex.slice(0, -1) + "(/.*)?";
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return new RegExp(`^${regex}$|/${regex}$|^${regex}/`);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Filter files array by ignore patterns
|
|
92
|
+
* @param {string[]} files - Array of file paths
|
|
93
|
+
* @param {string[]} patterns - Ignore patterns
|
|
94
|
+
* @returns {{ included: string[], ignored: number }}
|
|
95
|
+
*/
|
|
96
|
+
export function filterFiles(files, patterns) {
|
|
97
|
+
const included = [];
|
|
98
|
+
let ignored = 0;
|
|
99
|
+
|
|
100
|
+
for (const file of files) {
|
|
101
|
+
if (isIgnored(file, patterns)) {
|
|
102
|
+
ignored++;
|
|
103
|
+
} else {
|
|
104
|
+
included.push(file);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
return { included, ignored };
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export default {
|
|
112
|
+
loadIgnorePatterns,
|
|
113
|
+
isIgnored,
|
|
114
|
+
filterFiles,
|
|
115
|
+
DEFAULT_IGNORES
|
|
116
|
+
};
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Tests for ignore module
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { describe, it, expect, beforeEach, afterEach } from "vitest";
|
|
6
|
+
import fs from "fs";
|
|
7
|
+
import path from "path";
|
|
8
|
+
import os from "os";
|
|
9
|
+
|
|
10
|
+
// Import directly without mocking - test actual behavior
|
|
11
|
+
import { loadIgnorePatterns, isIgnored } from "./ignore.js";
|
|
12
|
+
|
|
13
|
+
describe("ignore", () => {
|
|
14
|
+
describe("isIgnored", () => {
|
|
15
|
+
it("returns false when no patterns", () => {
|
|
16
|
+
const result = isIgnored("some/path.js", []);
|
|
17
|
+
expect(result).toBe(false);
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
it("matches exact pattern", () => {
|
|
21
|
+
const result = isIgnored("node_modules/pkg/file.js", ["node_modules"]);
|
|
22
|
+
expect(result).toBe(true);
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
it("matches glob pattern", () => {
|
|
26
|
+
const result = isIgnored("debug.log", ["*.log"]);
|
|
27
|
+
expect(result).toBe(true);
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
it("returns false for non-matching path", () => {
|
|
31
|
+
const result = isIgnored("src/app.js", ["*.log", "node_modules"]);
|
|
32
|
+
expect(result).toBe(false);
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
it("matches directory pattern", () => {
|
|
36
|
+
const result = isIgnored("dist/bundle.js", ["dist/**"]);
|
|
37
|
+
expect(result).toBe(true);
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
it("matches nested paths", () => {
|
|
41
|
+
const result = isIgnored(".git/objects/pack", [".git/**"]);
|
|
42
|
+
expect(result).toBe(true);
|
|
43
|
+
});
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
describe("loadIgnorePatterns", () => {
|
|
47
|
+
it("returns array of patterns", () => {
|
|
48
|
+
const patterns = loadIgnorePatterns();
|
|
49
|
+
expect(Array.isArray(patterns)).toBe(true);
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
it("includes default patterns", () => {
|
|
53
|
+
const patterns = loadIgnorePatterns();
|
|
54
|
+
// Should have at least some patterns (defaults or from file)
|
|
55
|
+
expect(patterns.length).toBeGreaterThan(0);
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
});
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Project initialization wizard
|
|
3
|
+
* Sets up agent config for new projects
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import fs from "fs";
|
|
7
|
+
import path from "path";
|
|
8
|
+
import { cwd, AGENT_DIR, KNOWLEDGE_DIR, LESSONS_PATH } from "./config.js";
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Detect project type based on files
|
|
12
|
+
* @returns {string} Project type
|
|
13
|
+
*/
|
|
14
|
+
export function detectProjectType() {
|
|
15
|
+
const files = fs.readdirSync(cwd);
|
|
16
|
+
|
|
17
|
+
if (files.includes("package.json")) {
|
|
18
|
+
const pkg = JSON.parse(fs.readFileSync(path.join(cwd, "package.json"), "utf8"));
|
|
19
|
+
|
|
20
|
+
if (pkg.dependencies?.next || pkg.devDependencies?.next) return "nextjs";
|
|
21
|
+
if (pkg.dependencies?.react || pkg.devDependencies?.react) return "react";
|
|
22
|
+
if (pkg.dependencies?.vue || pkg.devDependencies?.vue) return "vue";
|
|
23
|
+
if (pkg.dependencies?.express || pkg.devDependencies?.express) return "node";
|
|
24
|
+
return "node";
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
if (files.includes("requirements.txt") || files.includes("pyproject.toml")) return "python";
|
|
28
|
+
if (files.includes("Cargo.toml")) return "rust";
|
|
29
|
+
if (files.includes("go.mod")) return "go";
|
|
30
|
+
if (files.includes("pom.xml") || files.includes("build.gradle")) return "java";
|
|
31
|
+
|
|
32
|
+
return "generic";
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Get default ignore patterns for project type
|
|
37
|
+
* @param {string} projectType
|
|
38
|
+
* @returns {string[]}
|
|
39
|
+
*/
|
|
40
|
+
export function getDefaultIgnorePatterns(projectType) {
|
|
41
|
+
const common = [
|
|
42
|
+
"node_modules/**",
|
|
43
|
+
".git/**",
|
|
44
|
+
"dist/**",
|
|
45
|
+
"build/**",
|
|
46
|
+
"coverage/**",
|
|
47
|
+
"*.log",
|
|
48
|
+
"*.lock",
|
|
49
|
+
".env*"
|
|
50
|
+
];
|
|
51
|
+
|
|
52
|
+
const specific = {
|
|
53
|
+
node: ["package-lock.json"],
|
|
54
|
+
nextjs: [".next/**", "out/**"],
|
|
55
|
+
react: ["build/**"],
|
|
56
|
+
vue: [".nuxt/**"],
|
|
57
|
+
python: ["__pycache__/**", "*.pyc", ".venv/**", "venv/**"],
|
|
58
|
+
rust: ["target/**"],
|
|
59
|
+
go: ["vendor/**"],
|
|
60
|
+
java: ["target/**", "*.class"],
|
|
61
|
+
generic: []
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
return [...common, ...(specific[projectType] || [])];
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Initialize agent config
|
|
69
|
+
* @param {object} options
|
|
70
|
+
* @param {boolean} options.force - Overwrite existing
|
|
71
|
+
* @returns {{ success: boolean, message: string }}
|
|
72
|
+
*/
|
|
73
|
+
export function initProject(options = {}) {
|
|
74
|
+
const { force = false } = options;
|
|
75
|
+
|
|
76
|
+
// Check if already initialized
|
|
77
|
+
if (fs.existsSync(KNOWLEDGE_DIR) && !force) {
|
|
78
|
+
return {
|
|
79
|
+
success: false,
|
|
80
|
+
message: "Already initialized. Use --force to reinitialize."
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// Detect project type
|
|
85
|
+
const projectType = detectProjectType();
|
|
86
|
+
|
|
87
|
+
// Create directories
|
|
88
|
+
fs.mkdirSync(KNOWLEDGE_DIR, { recursive: true });
|
|
89
|
+
|
|
90
|
+
// Create lessons-learned.yaml
|
|
91
|
+
if (!fs.existsSync(LESSONS_PATH)) {
|
|
92
|
+
const initialLessons = `# Agent Skill Kit - Lessons Learned
|
|
93
|
+
# Project Type: ${projectType}
|
|
94
|
+
# Created: ${new Date().toISOString()}
|
|
95
|
+
|
|
96
|
+
lessons: []
|
|
97
|
+
`;
|
|
98
|
+
fs.writeFileSync(LESSONS_PATH, initialLessons);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// Create .agentignore if not exists
|
|
102
|
+
const agentignorePath = path.join(cwd, ".agentignore");
|
|
103
|
+
if (!fs.existsSync(agentignorePath)) {
|
|
104
|
+
const patterns = getDefaultIgnorePatterns(projectType);
|
|
105
|
+
fs.writeFileSync(agentignorePath, patterns.join("\n") + "\n");
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
return {
|
|
109
|
+
success: true,
|
|
110
|
+
message: `Initialized for ${projectType} project`,
|
|
111
|
+
projectType,
|
|
112
|
+
paths: {
|
|
113
|
+
knowledge: KNOWLEDGE_DIR,
|
|
114
|
+
lessons: LESSONS_PATH,
|
|
115
|
+
agentignore: agentignorePath
|
|
116
|
+
}
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
export default {
|
|
121
|
+
detectProjectType,
|
|
122
|
+
getDefaultIgnorePatterns,
|
|
123
|
+
initProject
|
|
124
|
+
};
|