aidoc-kit 0.1.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.
- package/LICENSE +21 -0
- package/README.md +231 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +200 -0
- package/dist/cli.js.map +1 -0
- package/dist/core/chunker.d.ts +41 -0
- package/dist/core/chunker.d.ts.map +1 -0
- package/dist/core/chunker.js +217 -0
- package/dist/core/chunker.js.map +1 -0
- package/dist/core/config.d.ts +20 -0
- package/dist/core/config.d.ts.map +1 -0
- package/dist/core/config.js +83 -0
- package/dist/core/config.js.map +1 -0
- package/dist/core/scanner.d.ts +10 -0
- package/dist/core/scanner.d.ts.map +1 -0
- package/dist/core/scanner.js +224 -0
- package/dist/core/scanner.js.map +1 -0
- package/dist/core/transformer.d.ts +7 -0
- package/dist/core/transformer.d.ts.map +1 -0
- package/dist/core/transformer.js +219 -0
- package/dist/core/transformer.js.map +1 -0
- package/dist/core/writer.d.ts +5 -0
- package/dist/core/writer.d.ts.map +1 -0
- package/dist/core/writer.js +99 -0
- package/dist/core/writer.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +23 -0
- package/dist/index.js.map +1 -0
- package/dist/rules/index.d.ts +7 -0
- package/dist/rules/index.d.ts.map +1 -0
- package/dist/rules/index.js +64 -0
- package/dist/rules/index.js.map +1 -0
- package/dist/types.d.ts +67 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/package.json +53 -0
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.generateAiDocBlock = generateAiDocBlock;
|
|
37
|
+
exports.applyRules = applyRules;
|
|
38
|
+
const ts = __importStar(require("typescript"));
|
|
39
|
+
const node_fs_1 = require("node:fs");
|
|
40
|
+
const node_path_1 = require("node:path");
|
|
41
|
+
// ─── Writer — generate @ai-* block for undocumented files ─────────────────
|
|
42
|
+
function generateAiDocBlock(filePath, cascadeDeps = [], config = {}) {
|
|
43
|
+
let source;
|
|
44
|
+
try {
|
|
45
|
+
source = (0, node_fs_1.readFileSync)(filePath, 'utf-8');
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
return '';
|
|
49
|
+
}
|
|
50
|
+
const sourceFile = ts.createSourceFile(filePath, source, ts.ScriptTarget.Latest, true);
|
|
51
|
+
const runtime = detectRuntime(source);
|
|
52
|
+
const imports = extractImports(sourceFile);
|
|
53
|
+
const agent = inferAgent(imports, filePath, config.agents ?? {});
|
|
54
|
+
const exports = extractExports(sourceFile);
|
|
55
|
+
const validateCmd = config.validate ?? 'npm run typecheck';
|
|
56
|
+
const exportList = exports.length > 0 ? exports.join(', ') : (0, node_path_1.basename)(filePath);
|
|
57
|
+
const importedIn = cascadeDeps.length > 0
|
|
58
|
+
? `Importé dans : ${cascadeDeps.slice(0, 3).join(', ')}`
|
|
59
|
+
: '';
|
|
60
|
+
const cascadeLines = cascadeDeps.length > 0
|
|
61
|
+
? cascadeDeps.map(f => ` * → ${f}`).join('\n')
|
|
62
|
+
: ' * (aucun détecté)';
|
|
63
|
+
return `/**
|
|
64
|
+
* @ai-agent ${agent}
|
|
65
|
+
* @ai-runtime ${runtime}
|
|
66
|
+
*
|
|
67
|
+
* @ai-context
|
|
68
|
+
* [GÉNÉRÉ] Ce fichier exporte : ${exportList}
|
|
69
|
+
* ${importedIn}
|
|
70
|
+
*
|
|
71
|
+
* @ai-when-modifying
|
|
72
|
+
* 1. Vérifier les fichiers en cascade ci-dessous avant de modifier
|
|
73
|
+
* 2. Après modification, indiquer au développeur de lancer @ai-validate
|
|
74
|
+
* 3. Si tu n'as pas accès au terminal, signaler la commande à exécuter
|
|
75
|
+
*
|
|
76
|
+
* @ai-cascade
|
|
77
|
+
${cascadeLines}
|
|
78
|
+
*
|
|
79
|
+
* @ai-validate
|
|
80
|
+
* ${validateCmd}
|
|
81
|
+
*/`;
|
|
82
|
+
}
|
|
83
|
+
// ─── Transformer — apply rules to a file ──────────────────────────────────
|
|
84
|
+
function applyRules(filePath, rules) {
|
|
85
|
+
let source;
|
|
86
|
+
try {
|
|
87
|
+
source = (0, node_fs_1.readFileSync)(filePath, 'utf-8');
|
|
88
|
+
}
|
|
89
|
+
catch {
|
|
90
|
+
return { changed: false, source: '' };
|
|
91
|
+
}
|
|
92
|
+
const sourceFile = ts.createSourceFile(filePath, source, ts.ScriptTarget.Latest, true);
|
|
93
|
+
const edits = [];
|
|
94
|
+
ts.forEachChild(sourceFile, function visit(node) {
|
|
95
|
+
for (const rule of rules) {
|
|
96
|
+
if (rule.match(node, sourceFile)) {
|
|
97
|
+
const replacement = rule.replace(node, sourceFile);
|
|
98
|
+
if (replacement !== null) {
|
|
99
|
+
edits.push({ start: node.getStart(sourceFile), end: node.getEnd(), replacement });
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
ts.forEachChild(node, visit);
|
|
104
|
+
});
|
|
105
|
+
if (edits.length === 0)
|
|
106
|
+
return { changed: false, source };
|
|
107
|
+
// Apply in reverse order to preserve character positions
|
|
108
|
+
edits.sort((a, b) => b.start - a.start);
|
|
109
|
+
let result = source;
|
|
110
|
+
for (const edit of edits) {
|
|
111
|
+
result = result.slice(0, edit.start) + edit.replacement + result.slice(edit.end);
|
|
112
|
+
}
|
|
113
|
+
return { changed: true, source: result };
|
|
114
|
+
}
|
|
115
|
+
// ─── AST helpers ──────────────────────────────────────────────────────────
|
|
116
|
+
function extractImports(sourceFile) {
|
|
117
|
+
const imports = [];
|
|
118
|
+
ts.forEachChild(sourceFile, node => {
|
|
119
|
+
if (ts.isImportDeclaration(node) && ts.isStringLiteral(node.moduleSpecifier)) {
|
|
120
|
+
imports.push(node.moduleSpecifier.text);
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
return imports;
|
|
124
|
+
}
|
|
125
|
+
function extractExports(sourceFile) {
|
|
126
|
+
const exports = [];
|
|
127
|
+
ts.forEachChild(sourceFile, node => {
|
|
128
|
+
const hasExport = (n) => n.modifiers?.some(m => m.kind === ts.SyntaxKind.ExportKeyword) ?? false;
|
|
129
|
+
if ((ts.isFunctionDeclaration(node) || ts.isClassDeclaration(node)) && hasExport(node)) {
|
|
130
|
+
if (node.name)
|
|
131
|
+
exports.push(node.name.text);
|
|
132
|
+
}
|
|
133
|
+
else if (ts.isVariableStatement(node) && hasExport(node)) {
|
|
134
|
+
node.declarationList.declarations.forEach(d => {
|
|
135
|
+
if (ts.isIdentifier(d.name))
|
|
136
|
+
exports.push(d.name.text);
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
else if (ts.isTypeAliasDeclaration(node) && hasExport(node)) {
|
|
140
|
+
exports.push(node.name.text);
|
|
141
|
+
}
|
|
142
|
+
else if (ts.isInterfaceDeclaration(node) && hasExport(node)) {
|
|
143
|
+
exports.push(node.name.text);
|
|
144
|
+
}
|
|
145
|
+
});
|
|
146
|
+
return exports;
|
|
147
|
+
}
|
|
148
|
+
/** Infer the responsible agent from import paths and file location */
|
|
149
|
+
function inferAgent(imports, filePath, customRules = {}) {
|
|
150
|
+
const importStr = imports.join(' ');
|
|
151
|
+
// 1. Custom rules from aidoc.config — checked first so projects can override
|
|
152
|
+
for (const [substring, agent] of Object.entries(customRules)) {
|
|
153
|
+
if (importStr.includes(substring) || filePath.includes(substring))
|
|
154
|
+
return agent;
|
|
155
|
+
}
|
|
156
|
+
// 2. Built-in import-based rules (most specific first)
|
|
157
|
+
if (/firebase-admin/.test(importStr))
|
|
158
|
+
return 'firebase-admin-expert';
|
|
159
|
+
if (/firebase\/auth/.test(importStr))
|
|
160
|
+
return 'auth-expert';
|
|
161
|
+
if (/firebase/.test(importStr))
|
|
162
|
+
return 'firebase-expert';
|
|
163
|
+
if (/next-auth|next\/auth/.test(importStr))
|
|
164
|
+
return 'auth-expert';
|
|
165
|
+
if (/stripe/.test(importStr))
|
|
166
|
+
return 'billing-expert';
|
|
167
|
+
if (/prisma|drizzle|sequelize|mongoose/.test(importStr))
|
|
168
|
+
return 'db-expert';
|
|
169
|
+
if (/@tanstack\/react-query|react-query|swr/.test(importStr))
|
|
170
|
+
return 'data-fetching-expert';
|
|
171
|
+
if (/zustand/.test(importStr))
|
|
172
|
+
return 'state-expert';
|
|
173
|
+
if (/react-hook-form/.test(importStr))
|
|
174
|
+
return 'forms-expert';
|
|
175
|
+
if (/next\/navigation|next\/router/.test(importStr))
|
|
176
|
+
return 'routing-expert';
|
|
177
|
+
if (/next\/image|next\/link/.test(importStr))
|
|
178
|
+
return 'ui-expert';
|
|
179
|
+
if (/context|provider/i.test(importStr))
|
|
180
|
+
return 'context-expert';
|
|
181
|
+
// 3. File path heuristics
|
|
182
|
+
if (/\/store\//i.test(filePath))
|
|
183
|
+
return 'state-expert';
|
|
184
|
+
if (/\/auth\//i.test(filePath))
|
|
185
|
+
return 'auth-expert';
|
|
186
|
+
if (/\/hooks\//i.test(filePath))
|
|
187
|
+
return 'hooks-expert';
|
|
188
|
+
if (/\/api\//i.test(filePath))
|
|
189
|
+
return 'api-expert';
|
|
190
|
+
if (/\/components?\//i.test(filePath))
|
|
191
|
+
return 'ui-expert';
|
|
192
|
+
if (/\/lib\//i.test(filePath) || /\/utils?\//i.test(filePath))
|
|
193
|
+
return 'utils-expert';
|
|
194
|
+
if (/\/types?\.?/i.test(filePath))
|
|
195
|
+
return 'types-expert';
|
|
196
|
+
return 'general-expert';
|
|
197
|
+
}
|
|
198
|
+
// ─── Runtime detection ─────────────────────────────────────────────────────
|
|
199
|
+
/**
|
|
200
|
+
* Detect the execution environment from source code.
|
|
201
|
+
* Explicit directives (`'use client'`, `'use server'`) take priority,
|
|
202
|
+
* then heuristics (React hooks → CLIENT, firebase-admin imports → SERVER).
|
|
203
|
+
*/
|
|
204
|
+
function detectRuntime(source) {
|
|
205
|
+
// Only inspect the file head for the directives to avoid false positives inside strings
|
|
206
|
+
const head = source.slice(0, 300);
|
|
207
|
+
if (/^\s*(?:\/\/[^\n]*\n\s*)*['"]use client['"]/.test(head))
|
|
208
|
+
return 'CLIENT UNIQUEMENT';
|
|
209
|
+
if (/^\s*(?:\/\/[^\n]*\n\s*)*['"]use server['"]/.test(head))
|
|
210
|
+
return 'SERVER UNIQUEMENT';
|
|
211
|
+
// Heuristics on full source
|
|
212
|
+
if (/['"]firebase-admin['"]/.test(source))
|
|
213
|
+
return 'SERVER UNIQUEMENT';
|
|
214
|
+
if (/\buseState\b|\buseEffect\b|\buseRef\b|\buseReducer\b|\buseCallback\b|\buseMemo\b/.test(source)) {
|
|
215
|
+
return 'CLIENT UNIQUEMENT';
|
|
216
|
+
}
|
|
217
|
+
return 'UNIVERSEL';
|
|
218
|
+
}
|
|
219
|
+
//# sourceMappingURL=transformer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transformer.js","sourceRoot":"","sources":["../../src/core/transformer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { ScanResult } from '../types';
|
|
2
|
+
export declare function writeKnowledgeBase(result: ScanResult, projectRoot: string): void;
|
|
3
|
+
export declare function writeAgentsMd(result: ScanResult, projectRoot: string): void;
|
|
4
|
+
export declare function writeDocBlock(filePath: string, docBlock: string): void;
|
|
5
|
+
//# sourceMappingURL=writer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"writer.d.ts","sourceRoot":"","sources":["../../src/core/writer.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAA6B,UAAU,EAAE,MAAM,UAAU,CAAA;AAIrE,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,GAAG,IAAI,CAKhF;AAID,wBAAgB,aAAa,CAAC,MAAM,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,GAAG,IAAI,CA2D3E;AAID,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAItE"}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.writeKnowledgeBase = writeKnowledgeBase;
|
|
4
|
+
exports.writeAgentsMd = writeAgentsMd;
|
|
5
|
+
exports.writeDocBlock = writeDocBlock;
|
|
6
|
+
const node_fs_1 = require("node:fs");
|
|
7
|
+
const node_path_1 = require("node:path");
|
|
8
|
+
// ─── Knowledge base ────────────────────────────────────────────────────────
|
|
9
|
+
function writeKnowledgeBase(result, projectRoot) {
|
|
10
|
+
const outDir = (0, node_path_1.join)(projectRoot, '.codemod');
|
|
11
|
+
(0, node_fs_1.mkdirSync)(outDir, { recursive: true });
|
|
12
|
+
const kb = buildKnowledgeBase(result.docs);
|
|
13
|
+
(0, node_fs_1.writeFileSync)((0, node_path_1.join)(outDir, 'ai-knowledge-base.json'), JSON.stringify(kb, null, 2), 'utf-8');
|
|
14
|
+
}
|
|
15
|
+
// ─── AGENTS.md ─────────────────────────────────────────────────────────────
|
|
16
|
+
function writeAgentsMd(result, projectRoot) {
|
|
17
|
+
const kb = buildKnowledgeBase(result.docs);
|
|
18
|
+
const lines = [
|
|
19
|
+
'# AGENTS',
|
|
20
|
+
'',
|
|
21
|
+
`> Généré par aidoc-kit le ${new Date().toISOString().slice(0, 10)}`,
|
|
22
|
+
`> ${result.totalScanned} fichiers scannés — ${result.docs.length} avec docs @ai-*`,
|
|
23
|
+
'',
|
|
24
|
+
'## Agents et leurs domaines',
|
|
25
|
+
'',
|
|
26
|
+
];
|
|
27
|
+
for (const [agent, info] of Object.entries(kb.agents)) {
|
|
28
|
+
lines.push(`### ${agent}`, '');
|
|
29
|
+
lines.push(`**Fichiers :** ${info.owns.length}`);
|
|
30
|
+
info.owns.slice(0, 10).forEach(f => lines.push(`- \`${f}\``));
|
|
31
|
+
if (info.owns.length > 10)
|
|
32
|
+
lines.push(`- *(+ ${info.owns.length - 10} autres)*`);
|
|
33
|
+
if (info.consultedBy.length > 0) {
|
|
34
|
+
lines.push('', `**Consulté par :** ${info.consultedBy.join(', ')}`);
|
|
35
|
+
}
|
|
36
|
+
lines.push('');
|
|
37
|
+
}
|
|
38
|
+
if (Object.keys(kb.runtimeMap).length > 0) {
|
|
39
|
+
lines.push('## Runtime Map', '');
|
|
40
|
+
for (const [runtime, files] of Object.entries(kb.runtimeMap)) {
|
|
41
|
+
lines.push(`### ${runtime} (${files.length} fichiers)`, '');
|
|
42
|
+
files.slice(0, 5).forEach(f => lines.push(`- \`${f}\``));
|
|
43
|
+
if (files.length > 5)
|
|
44
|
+
lines.push(`- *(+ ${files.length - 5} autres)*`);
|
|
45
|
+
lines.push('');
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
if (result.filesWithoutDocs.length > 0) {
|
|
49
|
+
lines.push('## Fichiers sans documentation @ai-*', '', `${result.filesWithoutDocs.length} fichier(s) sans bloc \`@ai-*\` détecté(s).`, 'Lancer `npx aidoc-kit scan --write` pour générer les blocs manquants.', '');
|
|
50
|
+
}
|
|
51
|
+
lines.push('## Fichiers volumineux — lire le chunk avant de modifier', '', 'Les fichiers de plus de 150 lignes ont un résumé structuré dans `.codemod/chunks/`.', 'Avant de modifier un fichier volumineux, **lire le fichier `.md` correspondant** dans ce dossier.', 'Ne pas tenter de lire le fichier source en entier — utiliser le chunk.', '', 'Exemple : avant de modifier `src/contexts/auth-context.tsx`', '→ Lire `.codemod/chunks/src/contexts/auth-context.tsx.md`', '', '> Les chunks sont générés et maintenus par le développeur via `npx aidoc-kit chunk`.', '> Si un chunk est manquant, demander au développeur de lancer cette commande.', '');
|
|
52
|
+
(0, node_fs_1.writeFileSync)((0, node_path_1.join)(projectRoot, 'AGENTS.md'), lines.join('\n'), 'utf-8');
|
|
53
|
+
}
|
|
54
|
+
// ─── Prepend doc block to a file ──────────────────────────────────────────
|
|
55
|
+
function writeDocBlock(filePath, docBlock) {
|
|
56
|
+
const existing = (0, node_fs_1.readFileSync)(filePath, 'utf-8');
|
|
57
|
+
if (existing.includes('@ai-agent'))
|
|
58
|
+
return; // already documented
|
|
59
|
+
(0, node_fs_1.writeFileSync)(filePath, docBlock + '\n' + existing, 'utf-8');
|
|
60
|
+
}
|
|
61
|
+
// ─── Builder ────────────────────────────────────────────────────────────────
|
|
62
|
+
function buildKnowledgeBase(docs) {
|
|
63
|
+
const agents = {};
|
|
64
|
+
const cascadeGraph = {};
|
|
65
|
+
const runtimeMap = {};
|
|
66
|
+
const validationCommands = {};
|
|
67
|
+
for (const doc of docs) {
|
|
68
|
+
// Agent ownership
|
|
69
|
+
if (!agents[doc.agent])
|
|
70
|
+
agents[doc.agent] = { owns: [], consultedBy: [] };
|
|
71
|
+
agents[doc.agent].owns.push(doc.file);
|
|
72
|
+
// Related agents get a "consultedBy" entry
|
|
73
|
+
for (const rel of doc.related) {
|
|
74
|
+
if (!rel)
|
|
75
|
+
continue;
|
|
76
|
+
if (!agents[rel])
|
|
77
|
+
agents[rel] = { owns: [], consultedBy: [] };
|
|
78
|
+
if (!agents[rel].consultedBy.includes(doc.agent)) {
|
|
79
|
+
agents[rel].consultedBy.push(doc.agent);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
// Cascade graph
|
|
83
|
+
if (doc.cascade.length > 0)
|
|
84
|
+
cascadeGraph[doc.file] = doc.cascade;
|
|
85
|
+
// Runtime map
|
|
86
|
+
const rt = doc.runtime || 'UNIVERSEL';
|
|
87
|
+
if (!runtimeMap[rt])
|
|
88
|
+
runtimeMap[rt] = [];
|
|
89
|
+
runtimeMap[rt].push(doc.file);
|
|
90
|
+
// Validation commands
|
|
91
|
+
if (doc.validate) {
|
|
92
|
+
if (!validationCommands[doc.validate])
|
|
93
|
+
validationCommands[doc.validate] = [];
|
|
94
|
+
validationCommands[doc.validate].push(doc.file);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
return { generatedAt: new Date().toISOString(), agents, cascadeGraph, runtimeMap, validationCommands };
|
|
98
|
+
}
|
|
99
|
+
//# sourceMappingURL=writer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"writer.js","sourceRoot":"","sources":["../../src/core/writer.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { scanProject, extractAiDocs, buildReverseImportMap } from './core/scanner';
|
|
2
|
+
export { generateAiDocBlock, applyRules } from './core/transformer';
|
|
3
|
+
export { writeKnowledgeBase, writeAgentsMd, writeDocBlock } from './core/writer';
|
|
4
|
+
export { loadConfig, isIgnored } from './core/config';
|
|
5
|
+
export { defaultRules, removeConsoleLogs, replaceAnyWithUnknown } from './rules/index';
|
|
6
|
+
export type { AiDocBlock, Rule, ScanResult, KnowledgeBase, AidocConfig } from './types';
|
|
7
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAA;AAClF,OAAO,EAAE,kBAAkB,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AACnE,OAAO,EAAE,kBAAkB,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,eAAe,CAAA;AAChF,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,eAAe,CAAA;AACrD,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAA;AACtF,YAAY,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,SAAS,CAAA"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.replaceAnyWithUnknown = exports.removeConsoleLogs = exports.defaultRules = exports.isIgnored = exports.loadConfig = exports.writeDocBlock = exports.writeAgentsMd = exports.writeKnowledgeBase = exports.applyRules = exports.generateAiDocBlock = exports.buildReverseImportMap = exports.extractAiDocs = exports.scanProject = void 0;
|
|
4
|
+
// Programmatic API — import aidoc-kit as a module
|
|
5
|
+
var scanner_1 = require("./core/scanner");
|
|
6
|
+
Object.defineProperty(exports, "scanProject", { enumerable: true, get: function () { return scanner_1.scanProject; } });
|
|
7
|
+
Object.defineProperty(exports, "extractAiDocs", { enumerable: true, get: function () { return scanner_1.extractAiDocs; } });
|
|
8
|
+
Object.defineProperty(exports, "buildReverseImportMap", { enumerable: true, get: function () { return scanner_1.buildReverseImportMap; } });
|
|
9
|
+
var transformer_1 = require("./core/transformer");
|
|
10
|
+
Object.defineProperty(exports, "generateAiDocBlock", { enumerable: true, get: function () { return transformer_1.generateAiDocBlock; } });
|
|
11
|
+
Object.defineProperty(exports, "applyRules", { enumerable: true, get: function () { return transformer_1.applyRules; } });
|
|
12
|
+
var writer_1 = require("./core/writer");
|
|
13
|
+
Object.defineProperty(exports, "writeKnowledgeBase", { enumerable: true, get: function () { return writer_1.writeKnowledgeBase; } });
|
|
14
|
+
Object.defineProperty(exports, "writeAgentsMd", { enumerable: true, get: function () { return writer_1.writeAgentsMd; } });
|
|
15
|
+
Object.defineProperty(exports, "writeDocBlock", { enumerable: true, get: function () { return writer_1.writeDocBlock; } });
|
|
16
|
+
var config_1 = require("./core/config");
|
|
17
|
+
Object.defineProperty(exports, "loadConfig", { enumerable: true, get: function () { return config_1.loadConfig; } });
|
|
18
|
+
Object.defineProperty(exports, "isIgnored", { enumerable: true, get: function () { return config_1.isIgnored; } });
|
|
19
|
+
var index_1 = require("./rules/index");
|
|
20
|
+
Object.defineProperty(exports, "defaultRules", { enumerable: true, get: function () { return index_1.defaultRules; } });
|
|
21
|
+
Object.defineProperty(exports, "removeConsoleLogs", { enumerable: true, get: function () { return index_1.removeConsoleLogs; } });
|
|
22
|
+
Object.defineProperty(exports, "replaceAnyWithUnknown", { enumerable: true, get: function () { return index_1.replaceAnyWithUnknown; } });
|
|
23
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,kDAAkD;AAClD,0CAAkF;AAAzE,sGAAA,WAAW,OAAA;AAAE,wGAAA,aAAa,OAAA;AAAE,gHAAA,qBAAqB,OAAA;AAC1D,kDAAmE;AAA1D,iHAAA,kBAAkB,OAAA;AAAE,yGAAA,UAAU,OAAA;AACvC,wCAAgF;AAAvE,4GAAA,kBAAkB,OAAA;AAAE,uGAAA,aAAa,OAAA;AAAE,uGAAA,aAAa,OAAA;AACzD,wCAAqD;AAA5C,oGAAA,UAAU,OAAA;AAAE,mGAAA,SAAS,OAAA;AAC9B,uCAAsF;AAA7E,qGAAA,YAAY,OAAA;AAAE,0GAAA,iBAAiB,OAAA;AAAE,8GAAA,qBAAqB,OAAA"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { Rule } from '../types';
|
|
2
|
+
/** Remove bare `console.log(...)` expression statements */
|
|
3
|
+
export declare const removeConsoleLogs: Rule;
|
|
4
|
+
/** Replace `any` type annotations with `unknown` */
|
|
5
|
+
export declare const replaceAnyWithUnknown: Rule;
|
|
6
|
+
export declare const defaultRules: Rule[];
|
|
7
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/rules/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,UAAU,CAAA;AAEpC,2DAA2D;AAC3D,eAAO,MAAM,iBAAiB,EAAE,IAgB/B,CAAA;AAED,oDAAoD;AACpD,eAAO,MAAM,qBAAqB,EAAE,IAKnC,CAAA;AAED,eAAO,MAAM,YAAY,EAAE,IAAI,EAA+C,CAAA"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.defaultRules = exports.replaceAnyWithUnknown = exports.removeConsoleLogs = void 0;
|
|
37
|
+
const ts = __importStar(require("typescript"));
|
|
38
|
+
/** Remove bare `console.log(...)` expression statements */
|
|
39
|
+
exports.removeConsoleLogs = {
|
|
40
|
+
name: 'remove-console-logs',
|
|
41
|
+
description: 'Supprime les appels console.log',
|
|
42
|
+
match: (node, sourceFile) => {
|
|
43
|
+
if (!ts.isExpressionStatement(node))
|
|
44
|
+
return false;
|
|
45
|
+
const expr = node.expression;
|
|
46
|
+
if (!ts.isCallExpression(expr))
|
|
47
|
+
return false;
|
|
48
|
+
const access = expr.expression;
|
|
49
|
+
return (ts.isPropertyAccessExpression(access) &&
|
|
50
|
+
ts.isIdentifier(access.expression) &&
|
|
51
|
+
access.expression.text === 'console' &&
|
|
52
|
+
access.name.text === 'log');
|
|
53
|
+
},
|
|
54
|
+
replace: () => '',
|
|
55
|
+
};
|
|
56
|
+
/** Replace `any` type annotations with `unknown` */
|
|
57
|
+
exports.replaceAnyWithUnknown = {
|
|
58
|
+
name: 'replace-any-with-unknown',
|
|
59
|
+
description: 'Remplace les annotations `any` par `unknown`',
|
|
60
|
+
match: (node) => node.kind === ts.SyntaxKind.AnyKeyword,
|
|
61
|
+
replace: () => 'unknown',
|
|
62
|
+
};
|
|
63
|
+
exports.defaultRules = [exports.removeConsoleLogs, exports.replaceAnyWithUnknown];
|
|
64
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/rules/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,+CAAgC;AAGhC,2DAA2D;AAC9C,QAAA,iBAAiB,GAAS;IACrC,IAAI,EAAE,qBAAqB;IAC3B,WAAW,EAAE,iCAAiC;IAC9C,KAAK,EAAE,CAAC,IAAI,EAAE,UAAU,EAAE,EAAE;QAC1B,IAAI,CAAC,EAAE,CAAC,qBAAqB,CAAC,IAAI,CAAC;YAAE,OAAO,KAAK,CAAA;QACjD,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAA;QAC5B,IAAI,CAAC,EAAE,CAAC,gBAAgB,CAAC,IAAI,CAAC;YAAE,OAAO,KAAK,CAAA;QAC5C,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,CAAA;QAC9B,OAAO,CACL,EAAE,CAAC,0BAA0B,CAAC,MAAM,CAAC;YACrC,EAAE,CAAC,YAAY,CAAC,MAAM,CAAC,UAAU,CAAC;YAClC,MAAM,CAAC,UAAU,CAAC,IAAI,KAAK,SAAS;YACpC,MAAM,CAAC,IAAI,CAAC,IAAI,KAAK,KAAK,CAC3B,CAAA;IACH,CAAC;IACD,OAAO,EAAE,GAAG,EAAE,CAAC,EAAE;CAClB,CAAA;AAED,oDAAoD;AACvC,QAAA,qBAAqB,GAAS;IACzC,IAAI,EAAE,0BAA0B;IAChC,WAAW,EAAE,8CAA8C;IAC3D,KAAK,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,EAAE,CAAC,UAAU,CAAC,UAAU;IACvD,OAAO,EAAE,GAAG,EAAE,CAAC,SAAS;CACzB,CAAA;AAEY,QAAA,YAAY,GAAW,CAAC,yBAAiB,EAAE,6BAAqB,CAAC,CAAA"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import type * as ts from 'typescript';
|
|
2
|
+
export interface AiDocBlock {
|
|
3
|
+
/** Relative path from project root */
|
|
4
|
+
file: string;
|
|
5
|
+
/** @ai-agent */
|
|
6
|
+
agent: string;
|
|
7
|
+
/** @ai-agents-related — comma-separated agent names */
|
|
8
|
+
related: string[];
|
|
9
|
+
/** @ai-runtime — e.g. "CLIENT UNIQUEMENT", "SERVER UNIQUEMENT", "UNIVERSEL" */
|
|
10
|
+
runtime: string;
|
|
11
|
+
/** @ai-context — free-form description */
|
|
12
|
+
context: string;
|
|
13
|
+
/** @ai-when-modifying — ordered rules */
|
|
14
|
+
whenModifying: string[];
|
|
15
|
+
/** @ai-cascade — files affected when this one changes */
|
|
16
|
+
cascade: string[];
|
|
17
|
+
/** @ai-validate — command to run after edits */
|
|
18
|
+
validate: string;
|
|
19
|
+
/** @ai-never — hard prohibitions */
|
|
20
|
+
neverDo: string[];
|
|
21
|
+
/** @ai-pattern — embedded code snippets */
|
|
22
|
+
patterns: string[];
|
|
23
|
+
}
|
|
24
|
+
export interface Rule {
|
|
25
|
+
name: string;
|
|
26
|
+
description?: string;
|
|
27
|
+
match: (node: ts.Node, sourceFile: ts.SourceFile) => boolean;
|
|
28
|
+
replace: (node: ts.Node, sourceFile: ts.SourceFile) => string | null;
|
|
29
|
+
}
|
|
30
|
+
export interface ScanResult {
|
|
31
|
+
/** Files that already have @ai-* blocks */
|
|
32
|
+
docs: AiDocBlock[];
|
|
33
|
+
/** Relative paths of files without any @ai-* block */
|
|
34
|
+
filesWithoutDocs: string[];
|
|
35
|
+
totalScanned: number;
|
|
36
|
+
}
|
|
37
|
+
export interface AidocConfig {
|
|
38
|
+
/**
|
|
39
|
+
* Custom import-substring → agent-name mappings.
|
|
40
|
+
* Checked before built-in rules.
|
|
41
|
+
* @example { '@/lib/permissions': 'permissions-expert', 'stripe': 'billing-expert' }
|
|
42
|
+
*/
|
|
43
|
+
agents?: Record<string, string>;
|
|
44
|
+
/**
|
|
45
|
+
* Glob-style patterns for files to ignore during scan.
|
|
46
|
+
* Supports prefix patterns (`src/generated/`), suffix patterns (`*.test.ts`)
|
|
47
|
+
* and exact relative paths.
|
|
48
|
+
* @example ['src/generated/', '*.test.ts', 'src/foo/bar.ts']
|
|
49
|
+
*/
|
|
50
|
+
ignore?: string[];
|
|
51
|
+
/**
|
|
52
|
+
* Default @ai-validate command written into generated blocks.
|
|
53
|
+
* @default 'npm run typecheck'
|
|
54
|
+
*/
|
|
55
|
+
validate?: string;
|
|
56
|
+
}
|
|
57
|
+
export interface KnowledgeBase {
|
|
58
|
+
generatedAt: string;
|
|
59
|
+
agents: Record<string, {
|
|
60
|
+
owns: string[];
|
|
61
|
+
consultedBy: string[];
|
|
62
|
+
}>;
|
|
63
|
+
cascadeGraph: Record<string, string[]>;
|
|
64
|
+
runtimeMap: Record<string, string[]>;
|
|
65
|
+
validationCommands: Record<string, string[]>;
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,EAAE,MAAM,YAAY,CAAA;AAIrC,MAAM,WAAW,UAAU;IACzB,sCAAsC;IACtC,IAAI,EAAE,MAAM,CAAA;IACZ,gBAAgB;IAChB,KAAK,EAAE,MAAM,CAAA;IACb,uDAAuD;IACvD,OAAO,EAAE,MAAM,EAAE,CAAA;IACjB,+EAA+E;IAC/E,OAAO,EAAE,MAAM,CAAA;IACf,0CAA0C;IAC1C,OAAO,EAAE,MAAM,CAAA;IACf,yCAAyC;IACzC,aAAa,EAAE,MAAM,EAAE,CAAA;IACvB,yDAAyD;IACzD,OAAO,EAAE,MAAM,EAAE,CAAA;IACjB,gDAAgD;IAChD,QAAQ,EAAE,MAAM,CAAA;IAChB,oCAAoC;IACpC,OAAO,EAAE,MAAM,EAAE,CAAA;IACjB,2CAA2C;IAC3C,QAAQ,EAAE,MAAM,EAAE,CAAA;CACnB;AAID,MAAM,WAAW,IAAI;IACnB,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,KAAK,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,UAAU,EAAE,EAAE,CAAC,UAAU,KAAK,OAAO,CAAA;IAC5D,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,UAAU,EAAE,EAAE,CAAC,UAAU,KAAK,MAAM,GAAG,IAAI,CAAA;CACrE;AAID,MAAM,WAAW,UAAU;IACzB,2CAA2C;IAC3C,IAAI,EAAE,UAAU,EAAE,CAAA;IAClB,sDAAsD;IACtD,gBAAgB,EAAE,MAAM,EAAE,CAAA;IAC1B,YAAY,EAAE,MAAM,CAAA;CACrB;AAID,MAAM,WAAW,WAAW;IAC1B;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC/B;;;;;OAKG;IACH,MAAM,CAAC,EAAE,MAAM,EAAE,CAAA;IACjB;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB;AAID,MAAM,WAAW,aAAa;IAC5B,WAAW,EAAE,MAAM,CAAA;IACnB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE;QACrB,IAAI,EAAE,MAAM,EAAE,CAAA;QACd,WAAW,EAAE,MAAM,EAAE,CAAA;KACtB,CAAC,CAAA;IACF,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAA;IACtC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAA;IACpC,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAA;CAC7C"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
package/package.json
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "aidoc-kit",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "AI-native documentation scanner for JS/TS projects",
|
|
5
|
+
"main": "./dist/index.js",
|
|
6
|
+
"types": "./dist/index.d.ts",
|
|
7
|
+
"bin": {
|
|
8
|
+
"aidoc-kit": "dist/cli.js"
|
|
9
|
+
},
|
|
10
|
+
"scripts": {
|
|
11
|
+
"build": "tsc",
|
|
12
|
+
"dev": "tsc --watch",
|
|
13
|
+
"typecheck": "tsc --noEmit",
|
|
14
|
+
"test": "node --test dist/**/*.test.js 2>/dev/null || echo 'No tests yet — build passed'",
|
|
15
|
+
"prepublishOnly": "npm run build"
|
|
16
|
+
},
|
|
17
|
+
"files": [
|
|
18
|
+
"dist/",
|
|
19
|
+
"README.md",
|
|
20
|
+
"LICENSE"
|
|
21
|
+
],
|
|
22
|
+
"keywords": [
|
|
23
|
+
"ai",
|
|
24
|
+
"documentation",
|
|
25
|
+
"codemod",
|
|
26
|
+
"typescript",
|
|
27
|
+
"ast",
|
|
28
|
+
"agents",
|
|
29
|
+
"copilot",
|
|
30
|
+
"llm",
|
|
31
|
+
"jsdoc",
|
|
32
|
+
"knowledge-base"
|
|
33
|
+
],
|
|
34
|
+
"license": "MIT",
|
|
35
|
+
"repository": {
|
|
36
|
+
"type": "git",
|
|
37
|
+
"url": "git+https://github.com/Clemsrec/aidoc-kit.git"
|
|
38
|
+
},
|
|
39
|
+
"homepage": "https://github.com/Clemsrec/aidoc-kit#readme",
|
|
40
|
+
"bugs": {
|
|
41
|
+
"url": "https://github.com/Clemsrec/aidoc-kit/issues"
|
|
42
|
+
},
|
|
43
|
+
"devDependencies": {
|
|
44
|
+
"@types/node": "^25.6.0",
|
|
45
|
+
"typescript": "^5.0.0"
|
|
46
|
+
},
|
|
47
|
+
"peerDependencies": {
|
|
48
|
+
"typescript": ">=5.0.0"
|
|
49
|
+
},
|
|
50
|
+
"engines": {
|
|
51
|
+
"node": ">=18.0.0"
|
|
52
|
+
}
|
|
53
|
+
}
|