docforagents 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.
@@ -0,0 +1,2 @@
1
+
2
+ export { }
package/dist/index.js ADDED
@@ -0,0 +1,648 @@
1
+ #!/usr/bin/env node
2
+
3
+ // src/index.ts
4
+ import { Command } from "commander";
5
+
6
+ // src/commands/init.ts
7
+ import path3 from "path";
8
+ import chalk2 from "chalk";
9
+ import prompts2 from "prompts";
10
+
11
+ // src/core/detector.ts
12
+ import path from "path";
13
+ import fs2 from "fs/promises";
14
+
15
+ // src/utils/files.ts
16
+ import fs from "fs/promises";
17
+ async function exists(targetPath) {
18
+ try {
19
+ await fs.access(targetPath);
20
+ return true;
21
+ } catch {
22
+ return false;
23
+ }
24
+ }
25
+ async function readJson(filePath) {
26
+ try {
27
+ const content = await fs.readFile(filePath, "utf-8");
28
+ return JSON.parse(content);
29
+ } catch {
30
+ return null;
31
+ }
32
+ }
33
+ async function readText(filePath) {
34
+ try {
35
+ return await fs.readFile(filePath, "utf-8");
36
+ } catch {
37
+ return null;
38
+ }
39
+ }
40
+ async function getTopLevelDirectories(targetPath, ignoredDirs = ["node_modules", ".git", "dist", "build", "target", "venv", ".venv", "__pycache__", ".docforagents", "knowledge"]) {
41
+ try {
42
+ const items = await fs.readdir(targetPath, { withFileTypes: true });
43
+ return items.filter((item) => item.isDirectory() && !ignoredDirs.includes(item.name)).map((item) => item.name);
44
+ } catch {
45
+ return [];
46
+ }
47
+ }
48
+
49
+ // src/core/detector.ts
50
+ async function detectProject(targetPath) {
51
+ const absolutePath = path.resolve(targetPath);
52
+ let projectName = path.basename(absolutePath);
53
+ const packageJson = await readJson(path.join(absolutePath, "package.json"));
54
+ if (packageJson && packageJson.name) {
55
+ projectName = packageJson.name;
56
+ } else {
57
+ const cargoToml = await readText(path.join(absolutePath, "Cargo.toml"));
58
+ if (cargoToml) {
59
+ const match = cargoToml.match(/name\s*=\s*"([^"]+)"/);
60
+ if (match && match[1]) {
61
+ projectName = match[1];
62
+ }
63
+ }
64
+ }
65
+ const languages = [];
66
+ if (await exists(path.join(absolutePath, "package.json"))) {
67
+ const tsconfigExists = await exists(path.join(absolutePath, "tsconfig.json"));
68
+ if (tsconfigExists) {
69
+ languages.push("TypeScript", "JavaScript");
70
+ } else {
71
+ languages.push("JavaScript");
72
+ }
73
+ }
74
+ if (await exists(path.join(absolutePath, "requirements.txt")) || await exists(path.join(absolutePath, "pyproject.toml")) || await exists(path.join(absolutePath, "Pipfile")) || await exists(path.join(absolutePath, "setup.py"))) {
75
+ languages.push("Python");
76
+ }
77
+ if (await exists(path.join(absolutePath, "go.mod"))) {
78
+ languages.push("Go");
79
+ }
80
+ if (await exists(path.join(absolutePath, "Cargo.toml"))) {
81
+ languages.push("Rust");
82
+ }
83
+ if (await exists(path.join(absolutePath, "pom.xml")) || await exists(path.join(absolutePath, "build.gradle"))) {
84
+ languages.push("Java");
85
+ }
86
+ try {
87
+ const files = await fs2.readdir(absolutePath);
88
+ if (files.some((f) => f.endsWith(".csproj") || f.endsWith(".sln"))) {
89
+ languages.push("C#");
90
+ }
91
+ } catch {
92
+ }
93
+ const frameworks = [];
94
+ if (packageJson) {
95
+ const deps = {
96
+ ...packageJson.dependencies || {},
97
+ ...packageJson.devDependencies || {}
98
+ };
99
+ if (deps["next"]) frameworks.push("Next.js");
100
+ else if (deps["react-native"]) frameworks.push("React Native");
101
+ else if (deps["react"]) frameworks.push("React");
102
+ if (deps["nuxt"]) frameworks.push("Nuxt");
103
+ else if (deps["vue"]) frameworks.push("Vue");
104
+ if (deps["@angular/core"]) frameworks.push("Angular");
105
+ if (deps["svelte"] || deps["@sveltejs/kit"]) frameworks.push("Svelte");
106
+ if (deps["express"]) frameworks.push("Express");
107
+ if (deps["@nestjs/core"]) frameworks.push("NestJS");
108
+ if (deps["koa"]) frameworks.push("Koa");
109
+ if (deps["fastify"]) frameworks.push("Fastify");
110
+ if (deps["tailwindcss"]) frameworks.push("Tailwind CSS");
111
+ }
112
+ const pyprojectToml = await readText(path.join(absolutePath, "pyproject.toml"));
113
+ const reqsTxt = await readText(path.join(absolutePath, "requirements.txt"));
114
+ const pythonDeps = `${pyprojectToml || ""} ${reqsTxt || ""}`;
115
+ if (pythonDeps.includes("fastapi")) frameworks.push("FastAPI");
116
+ if (pythonDeps.includes("django")) frameworks.push("Django");
117
+ if (pythonDeps.includes("flask")) frameworks.push("Flask");
118
+ if (pythonDeps.includes("streamlit")) frameworks.push("Streamlit");
119
+ const goMod = await readText(path.join(absolutePath, "go.mod"));
120
+ if (goMod) {
121
+ if (goMod.includes("github.com/gin-gonic/gin")) frameworks.push("Gin");
122
+ if (goMod.includes("github.com/labstack/echo")) frameworks.push("Echo");
123
+ if (goMod.includes("github.com/gofiber/fiber")) frameworks.push("Fiber");
124
+ }
125
+ const cargoTomlStr = await readText(path.join(absolutePath, "Cargo.toml"));
126
+ if (cargoTomlStr) {
127
+ if (cargoTomlStr.includes("tokio")) frameworks.push("Tokio");
128
+ if (cargoTomlStr.includes("actix-web")) frameworks.push("Actix-Web");
129
+ if (cargoTomlStr.includes("axum")) frameworks.push("Axum");
130
+ if (cargoTomlStr.includes("rocket")) frameworks.push("Rocket");
131
+ }
132
+ const tools = [];
133
+ if (await exists(path.join(absolutePath, "Dockerfile")) || await exists(path.join(absolutePath, "docker-compose.yml"))) {
134
+ tools.push("Docker");
135
+ }
136
+ if (await exists(path.join(absolutePath, ".github/workflows"))) {
137
+ tools.push("GitHub Actions");
138
+ }
139
+ if (await exists(path.join(absolutePath, ".gitlab-ci.yml"))) {
140
+ tools.push("GitLab CI");
141
+ }
142
+ if (packageJson) {
143
+ const deps = { ...packageJson.dependencies || {}, ...packageJson.devDependencies || {} };
144
+ if (deps["prisma"]) tools.push("Prisma ORM");
145
+ if (deps["mongoose"]) tools.push("Mongoose (MongoDB)");
146
+ if (deps["sequelize"]) tools.push("Sequelize");
147
+ if (deps["typeorm"]) tools.push("TypeORM");
148
+ if (deps["pg"]) tools.push("PostgreSQL Client");
149
+ if (deps["sqlite3"]) tools.push("SQLite3 Client");
150
+ }
151
+ if (pythonDeps.includes("sqlalchemy")) tools.push("SQLAlchemy ORM");
152
+ if (pythonDeps.includes("tortoise-orm")) tools.push("Tortoise ORM");
153
+ const directories = await getTopLevelDirectories(absolutePath);
154
+ return {
155
+ projectName,
156
+ languages: Array.from(new Set(languages)),
157
+ frameworks: Array.from(new Set(frameworks)),
158
+ tools: Array.from(new Set(tools)),
159
+ directories
160
+ };
161
+ }
162
+
163
+ // src/core/generator.ts
164
+ import fs3 from "fs/promises";
165
+ import path2 from "path";
166
+
167
+ // src/core/templates.ts
168
+ function generateConfigJson(metadata) {
169
+ const config = {
170
+ $schema: "https://docforagents.org/schemas/v1/config.json",
171
+ version: "1.0.0",
172
+ project: {
173
+ name: metadata.projectName,
174
+ languages: metadata.languages,
175
+ frameworks: metadata.frameworks,
176
+ tools: metadata.tools
177
+ },
178
+ knowledgeDir: "knowledge",
179
+ exclude: [
180
+ "node_modules",
181
+ ".git",
182
+ "dist",
183
+ "build",
184
+ "target",
185
+ "venv",
186
+ ".venv",
187
+ "__pycache__",
188
+ ".docforagents/cache"
189
+ ],
190
+ rules: {
191
+ requireAdrForMajorChanges: false,
192
+ requireAgentsUpdateOnApiChange: true
193
+ }
194
+ };
195
+ return JSON.stringify(config, null, 2);
196
+ }
197
+ function generateRootAgentsMd(metadata) {
198
+ const languagesList = metadata.languages.map((l) => `- ${l}`).join("\n") || "- (None detected)";
199
+ const frameworksList = metadata.frameworks.map((f) => `- ${f}`).join("\n") || "- (None detected)";
200
+ const toolsList = metadata.tools.map((t) => `- ${t}`).join("\n") || "- (None detected)";
201
+ const directoryList = metadata.directories.map((dir) => `- [${dir}/](file://./${dir}/) \u2014 *Add responsibilities of this directory* (see [${dir}/AGENTS.md](file://./${dir}/AGENTS.md) for local rules)`).join("\n") || "- (No directories detected)";
202
+ return `# AGENTS.md \u2014 AI Agent Context Entry Point
203
+
204
+ > [!NOTE]
205
+ > **To AI Coding Agents:** This file serves as your primary landing page for understanding the architecture, rules, and entry points of the **${metadata.projectName}** project. Before executing tasks or modifications, review this page and follow the links to specific files.
206
+
207
+ ## Project Overview
208
+ *Briefly describe what this project does, its goals, and its business context.*
209
+
210
+ ## Core Stack & Environment
211
+ ### Languages
212
+ ${languagesList}
213
+
214
+ ### Frameworks & Libraries
215
+ ${frameworksList}
216
+
217
+ ### Infrastructure & Tools
218
+ ${toolsList}
219
+
220
+ ---
221
+
222
+ ## Repository Map
223
+
224
+ ### Core Knowledge Base
225
+ All architectural and domain-specific knowledge resides in the \`knowledge/\` directory:
226
+ - [Architecture Overview](file://./knowledge/architecture/overview.md) \u2014 System components, data flow, design patterns.
227
+ - [API Documentation](file://./knowledge/api/overview.md) \u2014 Endpoints, schemas, payloads.
228
+ - [Architecture Decisions (ADRs)](file://./knowledge/decisions/README.md) \u2014 Why the project was built this way.
229
+ - [Glossary of Terms](file://./knowledge/glossary/terms.md) \u2014 Domain vocabulary and definitions.
230
+ - [Testing Guidelines](file://./knowledge/testing/overview.md) \u2014 Test setup, commands, and strategies.
231
+
232
+ ### Directory Structure
233
+ ${directoryList}
234
+
235
+ ---
236
+
237
+ ## Agent Guidelines & Conventions
238
+
239
+ ### 1. Read Before Write
240
+ - Check the relevant local \`AGENTS.md\` inside directories you are editing.
241
+ - Look at the [Architecture Decisions](file://./knowledge/decisions/README.md) to understand existing patterns (e.g. repository pattern, clean architecture).
242
+
243
+ ### 2. Standardized Changes
244
+ - **API changes** MUST update [API Overview](file://./knowledge/api/overview.md) and local \`AGENTS.md\` interfaces.
245
+ - **Architectural changes** require an Architecture Decision Record (ADR) under [Decisions](file://./knowledge/decisions/README.md).
246
+
247
+ ### 3. Verification
248
+ - Always execute tests according to [Testing Guidelines](file://./knowledge/testing/overview.md) before declaring a task complete.
249
+ `;
250
+ }
251
+ function generateFolderAgentsMd(folderName) {
252
+ return `# AGENTS.md \u2014 Local Directory Rules for \`${folderName}/\`
253
+
254
+ > [!NOTE]
255
+ > **To AI Coding Agents:** This file defines the responsibilities, entry points, and coding conventions specific to the \`${folderName}/\` directory. Adhere strictly to these guidelines when making modifications here.
256
+
257
+ ## Purpose & Responsibility
258
+ *Describe the single responsibility of this directory (e.g. "Handles authentication endpoints and JWT verification").*
259
+
260
+ ## Core Entry Points
261
+ - [\`index.ts\` or entry file](file://./index.ts) \u2014 *Describe what imports/exports this file exposes.*
262
+
263
+ ## Internal Dependencies & Imports
264
+ - **Imports from other modules:** *Specify which parent modules this directory is allowed to import from.*
265
+ - **Outward dependencies:** *What external npm/pip packages or databases does this folder communicate with?*
266
+
267
+ ## Conventions & Implementation Rules
268
+ 1. **Design Patterns**: *e.g., Use controllers for route handling, delegate business logic to services.*
269
+ 2. **Naming Conventions**: *e.g., Suffix all services with \`Service\` (e.g., \`AuthService\`).*
270
+ 3. **Error Handling**: *e.g., Do not throw raw errors; wrap in \`AppError\` with status codes.*
271
+ 4. **Security**: *e.g., Ensure JWT middleware is applied to all new route configurations.*
272
+ `;
273
+ }
274
+ function generateArchitectureOverviewMd(projectName) {
275
+ return `# Architecture Overview \u2014 ${projectName}
276
+
277
+ ## System Overview
278
+ *Provide a high-level description of how this system is put together. Mention if it is a monolith, microservices, SPA, Serverless, etc.*
279
+
280
+ ## Core Components
281
+ *List the primary components/modules of the application and their relationships.*
282
+
283
+ \`\`\`mermaid
284
+ graph TD
285
+ Client[Client / Frontend] --> API[API Gateway / Backend]
286
+ API --> DB[(Database)]
287
+ API --> Cache[(Cache / Redis)]
288
+ \`\`\`
289
+
290
+ ## Core Design Patterns
291
+ *Outline the engineering patterns used in this codebase (e.g., Clean Architecture, MVC, CQRS, Repository Pattern, Dependency Injection).*
292
+
293
+ - **Pattern A**: *Description of how it is applied.*
294
+ - **Pattern B**: *Description of how it is applied.*
295
+
296
+ ## Data Flows
297
+ 1. **Request Flow**: *Trace a typical request from the frontend to database and back.*
298
+ 2. **Background Processes**: *Describe queues, cron jobs, event-driven pipelines if applicable.*
299
+ `;
300
+ }
301
+ function generateApiOverviewMd(projectName) {
302
+ return `# API Reference \u2014 ${projectName}
303
+
304
+ ## Authentication & Authorization
305
+ *Describe how clients authenticate to the APIs (e.g. Bearer tokens, cookies, API keys).*
306
+
307
+ \`\`\`http
308
+ Authorization: Bearer <token>
309
+ \`\`\`
310
+
311
+ ## Base URLs
312
+ - Development: \`http://localhost:3000/api\`
313
+ - Staging: \`https://staging.api.example.com/v1\`
314
+ - Production: \`https://api.example.com/v1\`
315
+
316
+ ## Main Endpoints
317
+
318
+ ### 1. Health check
319
+ - **Method / Path**: \`GET /health\`
320
+ - **Description**: Returns the system status.
321
+ - **Response**:
322
+ \`\`\`json
323
+ {
324
+ "status": "healthy",
325
+ "timestamp": "2026-07-27T18:00:00Z"
326
+ }
327
+ \`\`\`
328
+
329
+ ### 2. [Endpoint Name]
330
+ - **Method / Path**: \`POST /resource\`
331
+ - **Headers**: \`Content-Type: application/json\`
332
+ - **Request Body**:
333
+ \`\`\`json
334
+ {
335
+ "name": "example"
336
+ }
337
+ \`\`\`
338
+ - **Response (201 Created)**:
339
+ \`\`\`json
340
+ {
341
+ "id": "uuid-1234",
342
+ "name": "example"
343
+ }
344
+ \`\`\`
345
+ `;
346
+ }
347
+ function generateDecisionsReadmeMd(projectName) {
348
+ return `# Architectural Decision Records (ADR)
349
+
350
+ This folder contains the history of major design and architectural choices made in the **${projectName}** repository.
351
+
352
+ ## What is an ADR?
353
+ An Architectural Decision Record (ADR) is a document that captures an important architectural decision, including the context in which the decision was made, the consequences of the decision, and its current status (Proposed, Accepted, Superceded).
354
+
355
+ ## ADR Index
356
+
357
+ | ADR # | Title | Status | Date |
358
+ |-------|-------|--------|------|
359
+ | [ADR-001](file://./001-initial-architecture.md) | Initial Architecture Scaffolding | Accepted | 2026-07-27 |
360
+
361
+ *To create a new ADR, copy the template format and name it sequentially (e.g. \`002-use-redis-caching.md\`).*
362
+ `;
363
+ }
364
+ function generateGlossaryMd() {
365
+ return `# Domain Glossary
366
+
367
+ Define the core business terms and domain models used in this repository. This reduces ambiguity for AI agents and onboarding engineers.
368
+
369
+ | Term | Definition | Context / Usage |
370
+ |------|------------|-----------------|
371
+ | **ADR** | Architecture Decision Record. | Engineering workflow documentation |
372
+ | **Agent** | An autonomous AI agent performing operations on code. | AI Coding context |
373
+ | **Knowledge Layer** | The directory containing machine-readable code specification and guidelines. | Standard repo structure |
374
+ `;
375
+ }
376
+ function generateTestingOverviewMd(metadata) {
377
+ return `# Testing Guidelines
378
+
379
+ ## Running Tests
380
+ *Provide the exact commands required to execute the test suite.*
381
+
382
+ \`\`\`bash
383
+ # Run unit tests
384
+ npm run test
385
+ # Run integration / e2e tests
386
+ npm run test:e2e
387
+ \`\`\`
388
+
389
+ ## Testing Philosophy
390
+ - **Unit Tests**: Describe where unit tests are placed (e.g., next to the file as \`*.test.ts\` or in a \`test/\` directory).
391
+ - **Integration Tests**: Describe how to test integrations with mock services/databases.
392
+ - **Coverage**: Target code coverage expectations.
393
+
394
+ ## Creating New Tests
395
+ - Use the standard test framework configurations.
396
+ - Mock external network calls using MSW, nock, or custom mock suites.
397
+ `;
398
+ }
399
+
400
+ // src/core/generator.ts
401
+ async function generateKnowledgeBase(targetPath, metadata, options = {}) {
402
+ const absolutePath = path2.resolve(targetPath);
403
+ const filesCreated = [];
404
+ const filesSkipped = [];
405
+ const writeFileSafely = async (filePath, content) => {
406
+ const relativePath = path2.relative(absolutePath, filePath);
407
+ const fileExists = await exists(filePath);
408
+ if (fileExists && !options.forceOverwrite) {
409
+ filesSkipped.push(relativePath);
410
+ return;
411
+ }
412
+ await fs3.mkdir(path2.dirname(filePath), { recursive: true });
413
+ await fs3.writeFile(filePath, content, "utf-8");
414
+ filesCreated.push(relativePath);
415
+ };
416
+ const configPath = path2.join(absolutePath, ".docforagents", "config.json");
417
+ await writeFileSafely(configPath, generateConfigJson(metadata));
418
+ const rootAgentsPath = path2.join(absolutePath, "AGENTS.md");
419
+ await writeFileSafely(rootAgentsPath, generateRootAgentsMd(metadata));
420
+ const knowledgeDir = path2.join(absolutePath, "knowledge");
421
+ await writeFileSafely(
422
+ path2.join(knowledgeDir, "architecture", "overview.md"),
423
+ generateArchitectureOverviewMd(metadata.projectName)
424
+ );
425
+ await writeFileSafely(
426
+ path2.join(knowledgeDir, "api", "overview.md"),
427
+ generateApiOverviewMd(metadata.projectName)
428
+ );
429
+ await writeFileSafely(
430
+ path2.join(knowledgeDir, "decisions", "README.md"),
431
+ generateDecisionsReadmeMd(metadata.projectName)
432
+ );
433
+ await writeFileSafely(
434
+ path2.join(knowledgeDir, "glossary", "terms.md"),
435
+ generateGlossaryMd()
436
+ );
437
+ await writeFileSafely(
438
+ path2.join(knowledgeDir, "testing", "overview.md"),
439
+ generateTestingOverviewMd(metadata)
440
+ );
441
+ const foldersToGenerate = options.folderAgents !== void 0 ? options.folderAgents : options.skipFolderAgents ? [] : metadata.directories;
442
+ for (const dir of foldersToGenerate) {
443
+ if (dir.startsWith(".")) {
444
+ continue;
445
+ }
446
+ const folderAgentsPath = path2.join(absolutePath, dir, "AGENTS.md");
447
+ await writeFileSafely(folderAgentsPath, generateFolderAgentsMd(dir));
448
+ }
449
+ return {
450
+ filesCreated,
451
+ filesSkipped
452
+ };
453
+ }
454
+
455
+ // src/utils/prompts.ts
456
+ import chalk from "chalk";
457
+ import prompts from "prompts";
458
+ function printFolderRecommendation(projectName, directories) {
459
+ if (directories.length === 0) return;
460
+ console.log(chalk.bold(`
461
+ \u{1F4C1} ${projectName}`));
462
+ const maxToShow = 5;
463
+ const dirsToShow = directories.slice(0, maxToShow);
464
+ const remaining = directories.length - maxToShow;
465
+ dirsToShow.forEach((dir, idx) => {
466
+ const isLast = idx === dirsToShow.length - 1 && remaining <= 0;
467
+ const branch = isLast ? "\u2514\u2500\u2500" : "\u251C\u2500\u2500";
468
+ console.log(` ${branch} \u{1F4C1} ${dir}/`);
469
+ console.log(` ${isLast ? " " : "\u2502 "} \u2514\u2500\u2500 \u{1F4DD} ${chalk.green("AGENTS.md")} ${chalk.gray("(recommended)")}`);
470
+ });
471
+ if (remaining > 0) {
472
+ console.log(` \u2514\u2500\u2500 ${chalk.gray(`... and ${remaining} more folders`)}`);
473
+ }
474
+ console.log();
475
+ }
476
+ async function configureFolderAgentsCreation(projectName, directories) {
477
+ const filteredDirs = directories.filter((dir) => !dir.startsWith("."));
478
+ if (filteredDirs.length === 0) {
479
+ return [];
480
+ }
481
+ printFolderRecommendation(projectName, filteredDirs);
482
+ const isLargeProject = filteredDirs.length > 5;
483
+ if (isLargeProject) {
484
+ console.log(
485
+ chalk.yellow(
486
+ `\u26A0\uFE0F This is a large project with ${filteredDirs.length} folders recommended for AGENTS.md creation.`
487
+ )
488
+ );
489
+ console.log(
490
+ chalk.gray(
491
+ ` Auto-creating rules via LLM for all folders may consume a significant amount of time and tokens.
492
+ `
493
+ )
494
+ );
495
+ }
496
+ const response = await prompts(
497
+ {
498
+ type: "select",
499
+ name: "action",
500
+ message: "Configure folder-level AGENTS.md creation:",
501
+ choices: [
502
+ {
503
+ title: `Auto-create in all recommended folders (${filteredDirs.length} folders)`,
504
+ value: "all"
505
+ },
506
+ {
507
+ title: "Manual control (select specific folders)",
508
+ value: "manual"
509
+ },
510
+ {
511
+ title: "Skip folder-level AGENTS.md entirely",
512
+ value: "skip"
513
+ }
514
+ ],
515
+ initial: 0
516
+ },
517
+ {
518
+ onCancel: () => {
519
+ console.log(chalk.yellow("\nOperation cancelled."));
520
+ process.exit(0);
521
+ }
522
+ }
523
+ );
524
+ if (response.action === "all") {
525
+ return filteredDirs;
526
+ }
527
+ if (response.action === "skip") {
528
+ return [];
529
+ }
530
+ if (response.action === "manual") {
531
+ const manualResponse = await prompts(
532
+ {
533
+ type: "multiselect",
534
+ name: "folders",
535
+ message: "Select subdirectories to create AGENTS.md in:",
536
+ choices: filteredDirs.map((dir) => ({
537
+ title: `${dir}/`,
538
+ value: dir,
539
+ selected: true
540
+ })),
541
+ hint: "- Space to select/deselect, Enter to confirm",
542
+ min: 0
543
+ },
544
+ {
545
+ onCancel: () => {
546
+ console.log(chalk.yellow("\nOperation cancelled."));
547
+ process.exit(0);
548
+ }
549
+ }
550
+ );
551
+ return manualResponse.folders || [];
552
+ }
553
+ return [];
554
+ }
555
+
556
+ // src/commands/init.ts
557
+ async function handleInit(targetDir = ".", options = {}) {
558
+ const resolvedPath = path3.resolve(targetDir);
559
+ console.log(chalk2.bold.cyan("\n\u{1F50D} Scanning repository for docforagents initialization..."));
560
+ console.log(chalk2.gray(`Path: ${resolvedPath}
561
+ `));
562
+ let metadata;
563
+ try {
564
+ metadata = await detectProject(resolvedPath);
565
+ } catch (error) {
566
+ console.error(chalk2.red("Error scanning project:"), error);
567
+ process.exit(1);
568
+ }
569
+ console.log(chalk2.bold("Detected stack:"));
570
+ console.log(` Project Name: ${chalk2.green(metadata.projectName)}`);
571
+ console.log(` Languages: ${chalk2.blue(metadata.languages.join(", ") || "None detected")}`);
572
+ console.log(` Frameworks: ${chalk2.blue(metadata.frameworks.join(", ") || "None detected")}`);
573
+ console.log(` Tools/Infra: ${chalk2.blue(metadata.tools.join(", ") || "None detected")}`);
574
+ console.log(` Directories: ${chalk2.blue(metadata.directories.join(", ") || "None detected")}
575
+ `);
576
+ let projectName = metadata.projectName;
577
+ let selectedFolders = metadata.directories.filter((dir) => !dir.startsWith("."));
578
+ let proceed = true;
579
+ if (!options.yes) {
580
+ const nameResponse = await prompts2(
581
+ {
582
+ type: "text",
583
+ name: "projectName",
584
+ message: "Customize project name:",
585
+ initial: projectName
586
+ },
587
+ {
588
+ onCancel: () => {
589
+ console.log(chalk2.yellow("\nInitialization cancelled."));
590
+ process.exit(0);
591
+ }
592
+ }
593
+ );
594
+ projectName = nameResponse.projectName ?? projectName;
595
+ selectedFolders = await configureFolderAgentsCreation(projectName, metadata.directories);
596
+ const proceedResponse = await prompts2(
597
+ {
598
+ type: "confirm",
599
+ name: "proceed",
600
+ message: "Proceed to write standard knowledge layer?",
601
+ initial: true
602
+ },
603
+ {
604
+ onCancel: () => {
605
+ console.log(chalk2.yellow("\nInitialization cancelled."));
606
+ process.exit(0);
607
+ }
608
+ }
609
+ );
610
+ proceed = proceedResponse.proceed ?? proceed;
611
+ }
612
+ if (!proceed) {
613
+ console.log(chalk2.yellow("\nInitialization aborted."));
614
+ return;
615
+ }
616
+ metadata.projectName = projectName;
617
+ console.log(chalk2.cyan("\n\u270D\uFE0F Writing knowledge base..."));
618
+ try {
619
+ const result = await generateKnowledgeBase(resolvedPath, metadata, {
620
+ forceOverwrite: options.force,
621
+ folderAgents: selectedFolders
622
+ });
623
+ if (result.filesCreated.length > 0) {
624
+ console.log(chalk2.bold.green(`
625
+ Successfully created ${result.filesCreated.length} files:`));
626
+ result.filesCreated.forEach((f) => console.log(` ${chalk2.green("\u2713")} ${f}`));
627
+ }
628
+ if (result.filesSkipped.length > 0) {
629
+ console.log(chalk2.bold.yellow(`
630
+ Skipped ${result.filesSkipped.length} existing files (use --force or -f to overwrite):`));
631
+ result.filesSkipped.forEach((f) => console.log(` ${chalk2.yellow("-")} ${f}`));
632
+ }
633
+ console.log(chalk2.bold.cyan("\n\u{1F389} Knowledge Layer Scaffolded successfully!"));
634
+ console.log("Your repository is now machine-readable for AI agents. Open root " + chalk2.bold.green("AGENTS.md") + " to get started.\n");
635
+ } catch (error) {
636
+ console.error(chalk2.red("\nError generating files:"), error);
637
+ process.exit(1);
638
+ }
639
+ }
640
+
641
+ // src/index.ts
642
+ var program = new Command();
643
+ program.name("docforagents").description("Open-source AI-native knowledge specification and tooling for software repositories").version("0.1.0");
644
+ program.command("init").description("Scaffold the AI-native knowledge specification in a repository").argument("[path]", "Path to the project directory", ".").option("-y, --yes", "Skip interactive prompts and use detected defaults").option("-f, --force", "Overwrite existing knowledge specification files if they exist").action(async (targetDir, options) => {
645
+ await handleInit(targetDir, options);
646
+ });
647
+ program.parse(process.argv);
648
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/commands/init.ts","../src/core/detector.ts","../src/utils/files.ts","../src/core/generator.ts","../src/core/templates.ts","../src/utils/prompts.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport { handleInit } from \"./commands/init\";\n// import { handleAnalyze } from \"./commands/analyze\";\n\nconst program = new Command();\n\nprogram\n .name(\"docforagents\")\n .description(\"Open-source AI-native knowledge specification and tooling for software repositories\")\n .version(\"0.1.0\");\n\nprogram\n .command(\"init\")\n .description(\"Scaffold the AI-native knowledge specification in a repository\")\n .argument(\"[path]\", \"Path to the project directory\", \".\")\n .option(\"-y, --yes\", \"Skip interactive prompts and use detected defaults\")\n .option(\"-f, --force\", \"Overwrite existing knowledge specification files if they exist\")\n .action(async (targetDir, options) => {\n await handleInit(targetDir, options);\n });\n\n// program\n// .command(\"analyze\")\n// .description(\"Scan the repository codebase and generate AI documentation files\")\n// .argument(\"[path]\", \"Path to the project directory\", \".\")\n// .option(\"-y, --yes\", \"Skip interactive prompts and generate for all recommended folders\")\n// .option(\"--skip-folders\", \"Skip generating folder-level AGENTS.md rule files\")\n// .action(async (targetDir, options) => {\n// await handleAnalyze(targetDir, options);\n// });\n\nprogram.parse(process.argv);\n","import path from \"path\";\nimport chalk from \"chalk\";\nimport prompts from \"prompts\";\nimport { detectProject } from \"../core/detector\";\nimport { generateKnowledgeBase } from \"../core/generator\";\nimport { configureFolderAgentsCreation } from \"../utils/prompts\";\n\nexport interface InitOptions {\n yes?: boolean;\n force?: boolean;\n}\n\n/**\n * Handle the 'init' command.\n */\nexport async function handleInit(targetDir: string = \".\", options: InitOptions = {}): Promise<void> {\n const resolvedPath = path.resolve(targetDir);\n \n console.log(chalk.bold.cyan(\"\\nšŸ” Scanning repository for docforagents initialization...\"));\n console.log(chalk.gray(`Path: ${resolvedPath}\\n`));\n\n // 1. Detect project details\n let metadata;\n try {\n metadata = await detectProject(resolvedPath);\n } catch (error) {\n console.error(chalk.red(\"Error scanning project:\"), error);\n process.exit(1);\n }\n\n // Log detected items\n console.log(chalk.bold(\"Detected stack:\"));\n console.log(` Project Name: ${chalk.green(metadata.projectName)}`);\n console.log(` Languages: ${chalk.blue(metadata.languages.join(\", \") || \"None detected\")}`);\n console.log(` Frameworks: ${chalk.blue(metadata.frameworks.join(\", \") || \"None detected\")}`);\n console.log(` Tools/Infra: ${chalk.blue(metadata.tools.join(\", \") || \"None detected\")}`);\n console.log(` Directories: ${chalk.blue(metadata.directories.join(\", \") || \"None detected\")}\\n`);\n\n let projectName = metadata.projectName;\n let selectedFolders: string[] = metadata.directories.filter(dir => !dir.startsWith(\".\"));\n let proceed = true;\n\n // 2. Interactive Prompts (unless --yes flag is passed)\n if (!options.yes) {\n const nameResponse = await prompts(\n {\n type: \"text\",\n name: \"projectName\",\n message: \"Customize project name:\",\n initial: projectName,\n },\n {\n onCancel: () => {\n console.log(chalk.yellow(\"\\nInitialization cancelled.\"));\n process.exit(0);\n }\n }\n );\n\n projectName = nameResponse.projectName ?? projectName;\n\n // Use interactive folder config helper\n selectedFolders = await configureFolderAgentsCreation(projectName, metadata.directories);\n\n const proceedResponse = await prompts(\n {\n type: \"confirm\",\n name: \"proceed\",\n message: \"Proceed to write standard knowledge layer?\",\n initial: true,\n },\n {\n onCancel: () => {\n console.log(chalk.yellow(\"\\nInitialization cancelled.\"));\n process.exit(0);\n }\n }\n );\n\n proceed = proceedResponse.proceed ?? proceed;\n }\n\n if (!proceed) {\n console.log(chalk.yellow(\"\\nInitialization aborted.\"));\n return;\n }\n\n // Update metadata with customized project name\n metadata.projectName = projectName;\n\n // 3. Generate files\n console.log(chalk.cyan(\"\\nāœļø Writing knowledge base...\"));\n \n try {\n const result = await generateKnowledgeBase(resolvedPath, metadata, {\n forceOverwrite: options.force,\n folderAgents: selectedFolders,\n });\n\n // 4. Summarize results\n if (result.filesCreated.length > 0) {\n console.log(chalk.bold.green(`\\nSuccessfully created ${result.filesCreated.length} files:`));\n result.filesCreated.forEach(f => console.log(` ${chalk.green(\"āœ“\")} ${f}`));\n }\n\n if (result.filesSkipped.length > 0) {\n console.log(chalk.bold.yellow(`\\nSkipped ${result.filesSkipped.length} existing files (use --force or -f to overwrite):`));\n result.filesSkipped.forEach(f => console.log(` ${chalk.yellow(\"-\")} ${f}`));\n }\n\n console.log(chalk.bold.cyan(\"\\nšŸŽ‰ Knowledge Layer Scaffolded successfully!\"));\n console.log(\"Your repository is now machine-readable for AI agents. Open root \" + chalk.bold.green(\"AGENTS.md\") + \" to get started.\\n\");\n\n } catch (error) {\n console.error(chalk.red(\"\\nError generating files:\"), error);\n process.exit(1);\n }\n}\n","import path from \"path\";\nimport fs from \"fs/promises\";\nimport { exists, readJson, readText, getTopLevelDirectories } from \"../utils/files\";\n\nexport interface ProjectMetadata {\n projectName: string;\n languages: string[];\n frameworks: string[];\n tools: string[];\n directories: string[];\n}\n\n/**\n * Scan a repository path to detect project configurations.\n */\nexport async function detectProject(targetPath: string): Promise<ProjectMetadata> {\n const absolutePath = path.resolve(targetPath);\n \n // 1. Resolve Project Name\n let projectName = path.basename(absolutePath);\n const packageJson = await readJson(path.join(absolutePath, \"package.json\"));\n if (packageJson && packageJson.name) {\n projectName = packageJson.name;\n } else {\n // Try to get Cargo.toml project name\n const cargoToml = await readText(path.join(absolutePath, \"Cargo.toml\"));\n if (cargoToml) {\n const match = cargoToml.match(/name\\s*=\\s*\"([^\"]+)\"/);\n if (match && match[1]) {\n projectName = match[1];\n }\n }\n }\n\n // 2. Detect Languages\n const languages: string[] = [];\n \n if (await exists(path.join(absolutePath, \"package.json\"))) {\n // Determine if it is TS or JS\n const tsconfigExists = await exists(path.join(absolutePath, \"tsconfig.json\"));\n if (tsconfigExists) {\n languages.push(\"TypeScript\", \"JavaScript\");\n } else {\n languages.push(\"JavaScript\");\n }\n }\n \n if (\n (await exists(path.join(absolutePath, \"requirements.txt\"))) ||\n (await exists(path.join(absolutePath, \"pyproject.toml\"))) ||\n (await exists(path.join(absolutePath, \"Pipfile\"))) ||\n (await exists(path.join(absolutePath, \"setup.py\")))\n ) {\n languages.push(\"Python\");\n }\n\n if (await exists(path.join(absolutePath, \"go.mod\"))) {\n languages.push(\"Go\");\n }\n\n if (await exists(path.join(absolutePath, \"Cargo.toml\"))) {\n languages.push(\"Rust\");\n }\n\n if (\n (await exists(path.join(absolutePath, \"pom.xml\"))) ||\n (await exists(path.join(absolutePath, \"build.gradle\")))\n ) {\n languages.push(\"Java\");\n }\n\n // Scan root for csproj files\n try {\n const files = await fs.readdir(absolutePath);\n if (files.some(f => f.endsWith(\".csproj\") || f.endsWith(\".sln\"))) {\n languages.push(\"C#\");\n }\n } catch {\n // Ignore read errors\n }\n\n // 3. Detect Frameworks\n const frameworks: string[] = [];\n \n // JS/TS dependencies scan\n if (packageJson) {\n const deps = {\n ...(packageJson.dependencies || {}),\n ...(packageJson.devDependencies || {}),\n };\n \n if (deps[\"next\"]) frameworks.push(\"Next.js\");\n else if (deps[\"react-native\"]) frameworks.push(\"React Native\");\n else if (deps[\"react\"]) frameworks.push(\"React\");\n \n if (deps[\"nuxt\"]) frameworks.push(\"Nuxt\");\n else if (deps[\"vue\"]) frameworks.push(\"Vue\");\n \n if (deps[\"@angular/core\"]) frameworks.push(\"Angular\");\n if (deps[\"svelte\"] || deps[\"@sveltejs/kit\"]) frameworks.push(\"Svelte\");\n \n if (deps[\"express\"]) frameworks.push(\"Express\");\n if (deps[\"@nestjs/core\"]) frameworks.push(\"NestJS\");\n if (deps[\"koa\"]) frameworks.push(\"Koa\");\n if (deps[\"fastify\"]) frameworks.push(\"Fastify\");\n if (deps[\"tailwindcss\"]) frameworks.push(\"Tailwind CSS\");\n }\n\n // Python dependencies scan\n const pyprojectToml = await readText(path.join(absolutePath, \"pyproject.toml\"));\n const reqsTxt = await readText(path.join(absolutePath, \"requirements.txt\"));\n const pythonDeps = `${pyprojectToml || \"\"} ${reqsTxt || \"\"}`;\n \n if (pythonDeps.includes(\"fastapi\")) frameworks.push(\"FastAPI\");\n if (pythonDeps.includes(\"django\")) frameworks.push(\"Django\");\n if (pythonDeps.includes(\"flask\")) frameworks.push(\"Flask\");\n if (pythonDeps.includes(\"streamlit\")) frameworks.push(\"Streamlit\");\n\n // Go dependencies scan\n const goMod = await readText(path.join(absolutePath, \"go.mod\"));\n if (goMod) {\n if (goMod.includes(\"github.com/gin-gonic/gin\")) frameworks.push(\"Gin\");\n if (goMod.includes(\"github.com/labstack/echo\")) frameworks.push(\"Echo\");\n if (goMod.includes(\"github.com/gofiber/fiber\")) frameworks.push(\"Fiber\");\n }\n\n // Rust dependencies scan\n const cargoTomlStr = await readText(path.join(absolutePath, \"Cargo.toml\"));\n if (cargoTomlStr) {\n if (cargoTomlStr.includes(\"tokio\")) frameworks.push(\"Tokio\");\n if (cargoTomlStr.includes(\"actix-web\")) frameworks.push(\"Actix-Web\");\n if (cargoTomlStr.includes(\"axum\")) frameworks.push(\"Axum\");\n if (cargoTomlStr.includes(\"rocket\")) frameworks.push(\"Rocket\");\n }\n\n // 4. Detect Tools & Infrastructure\n const tools: string[] = [];\n \n if (await exists(path.join(absolutePath, \"Dockerfile\")) || await exists(path.join(absolutePath, \"docker-compose.yml\"))) {\n tools.push(\"Docker\");\n }\n if (await exists(path.join(absolutePath, \".github/workflows\"))) {\n tools.push(\"GitHub Actions\");\n }\n if (await exists(path.join(absolutePath, \".gitlab-ci.yml\"))) {\n tools.push(\"GitLab CI\");\n }\n\n // Check common ORMs or DB libraries\n if (packageJson) {\n const deps = { ...(packageJson.dependencies || {}), ...(packageJson.devDependencies || {}) };\n if (deps[\"prisma\"]) tools.push(\"Prisma ORM\");\n if (deps[\"mongoose\"]) tools.push(\"Mongoose (MongoDB)\");\n if (deps[\"sequelize\"]) tools.push(\"Sequelize\");\n if (deps[\"typeorm\"]) tools.push(\"TypeORM\");\n if (deps[\"pg\"]) tools.push(\"PostgreSQL Client\");\n if (deps[\"sqlite3\"]) tools.push(\"SQLite3 Client\");\n }\n if (pythonDeps.includes(\"sqlalchemy\")) tools.push(\"SQLAlchemy ORM\");\n if (pythonDeps.includes(\"tortoise-orm\")) tools.push(\"Tortoise ORM\");\n\n // 5. Scan directories for local AGENTS.md candidates\n const directories = await getTopLevelDirectories(absolutePath);\n\n return {\n projectName,\n languages: Array.from(new Set(languages)),\n frameworks: Array.from(new Set(frameworks)),\n tools: Array.from(new Set(tools)),\n directories,\n };\n}\n","import fs from \"fs/promises\";\nimport path from \"path\";\n\n/**\n * Check if a file or directory exists at the given path.\n */\nexport async function exists(targetPath: string): Promise<boolean> {\n try {\n await fs.access(targetPath);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Read and parse JSON file safely. Returns null if error or file doesn't exist.\n */\nexport async function readJson<T = any>(filePath: string): Promise<T | null> {\n try {\n const content = await fs.readFile(filePath, \"utf-8\");\n return JSON.parse(content) as T;\n } catch {\n return null;\n }\n}\n\n/**\n * Read text file safely. Returns null if error or file doesn't exist.\n */\nexport async function readText(filePath: string): Promise<string | null> {\n try {\n return await fs.readFile(filePath, \"utf-8\");\n } catch {\n return null;\n }\n}\n\n/**\n * Get all top-level directories in targetPath, excluding common ignore paths.\n */\nexport async function getTopLevelDirectories(\n targetPath: string,\n ignoredDirs: string[] = [\"node_modules\", \".git\", \"dist\", \"build\", \"target\", \"venv\", \".venv\", \"__pycache__\", \".docforagents\", \"knowledge\"]\n): Promise<string[]> {\n try {\n const items = await fs.readdir(targetPath, { withFileTypes: true });\n return items\n .filter((item) => item.isDirectory() && !ignoredDirs.includes(item.name))\n .map((item) => item.name);\n } catch {\n return [];\n }\n}\n","import fs from \"fs/promises\";\nimport path from \"path\";\nimport { ProjectMetadata } from \"./detector\";\nimport { exists } from \"../utils/files\";\nimport {\n generateConfigJson,\n generateRootAgentsMd,\n generateFolderAgentsMd,\n generateArchitectureOverviewMd,\n generateApiOverviewMd,\n generateDecisionsReadmeMd,\n generateGlossaryMd,\n generateTestingOverviewMd,\n} from \"./templates\";\n\nexport interface GenerationResult {\n filesCreated: string[];\n filesSkipped: string[];\n}\n\n/**\n * Generate the standard docforagents layout in the target project path.\n */\nexport async function generateKnowledgeBase(\n targetPath: string,\n metadata: ProjectMetadata,\n options: { forceOverwrite?: boolean; skipFolderAgents?: boolean; folderAgents?: string[] } = {}\n): Promise<GenerationResult> {\n const absolutePath = path.resolve(targetPath);\n const filesCreated: string[] = [];\n const filesSkipped: string[] = [];\n\n // Helper to safely write a file and track results\n const writeFileSafely = async (filePath: string, content: string) => {\n const relativePath = path.relative(absolutePath, filePath);\n const fileExists = await exists(filePath);\n \n if (fileExists && !options.forceOverwrite) {\n filesSkipped.push(relativePath);\n return;\n }\n\n // Ensure parent directory exists\n await fs.mkdir(path.dirname(filePath), { recursive: true });\n await fs.writeFile(filePath, content, \"utf-8\");\n filesCreated.push(relativePath);\n };\n\n // 1. Create root configurations & entry points\n const configPath = path.join(absolutePath, \".docforagents\", \"config.json\");\n await writeFileSafely(configPath, generateConfigJson(metadata));\n\n const rootAgentsPath = path.join(absolutePath, \"AGENTS.md\");\n await writeFileSafely(rootAgentsPath, generateRootAgentsMd(metadata));\n\n // 2. Create knowledge base directory files\n const knowledgeDir = path.join(absolutePath, \"knowledge\");\n \n await writeFileSafely(\n path.join(knowledgeDir, \"architecture\", \"overview.md\"),\n generateArchitectureOverviewMd(metadata.projectName)\n );\n\n await writeFileSafely(\n path.join(knowledgeDir, \"api\", \"overview.md\"),\n generateApiOverviewMd(metadata.projectName)\n );\n\n await writeFileSafely(\n path.join(knowledgeDir, \"decisions\", \"README.md\"),\n generateDecisionsReadmeMd(metadata.projectName)\n );\n\n await writeFileSafely(\n path.join(knowledgeDir, \"glossary\", \"terms.md\"),\n generateGlossaryMd()\n );\n\n await writeFileSafely(\n path.join(knowledgeDir, \"testing\", \"overview.md\"),\n generateTestingOverviewMd(metadata)\n );\n\n // 3. Create folder-level AGENTS.md files\n const foldersToGenerate = options.folderAgents !== undefined\n ? options.folderAgents\n : (options.skipFolderAgents ? [] : metadata.directories);\n\n for (const dir of foldersToGenerate) {\n if (dir.startsWith(\".\")) {\n continue;\n }\n const folderAgentsPath = path.join(absolutePath, dir, \"AGENTS.md\");\n await writeFileSafely(folderAgentsPath, generateFolderAgentsMd(dir));\n }\n\n return {\n filesCreated,\n filesSkipped,\n };\n}\n","import { ProjectMetadata } from \"./detector\";\n\n/**\n * Generate config.json content based on metadata.\n */\nexport function generateConfigJson(metadata: ProjectMetadata): string {\n const config = {\n $schema: \"https://docforagents.org/schemas/v1/config.json\",\n version: \"1.0.0\",\n project: {\n name: metadata.projectName,\n languages: metadata.languages,\n frameworks: metadata.frameworks,\n tools: metadata.tools,\n },\n knowledgeDir: \"knowledge\",\n exclude: [\n \"node_modules\",\n \".git\",\n \"dist\",\n \"build\",\n \"target\",\n \"venv\",\n \".venv\",\n \"__pycache__\",\n \".docforagents/cache\"\n ],\n rules: {\n requireAdrForMajorChanges: false,\n requireAgentsUpdateOnApiChange: true\n }\n };\n return JSON.stringify(config, null, 2);\n}\n\n/**\n * Generate root AGENTS.md template.\n */\nexport function generateRootAgentsMd(metadata: ProjectMetadata): string {\n const languagesList = metadata.languages.map(l => `- ${l}`).join(\"\\n\") || \"- (None detected)\";\n const frameworksList = metadata.frameworks.map(f => `- ${f}`).join(\"\\n\") || \"- (None detected)\";\n const toolsList = metadata.tools.map(t => `- ${t}`).join(\"\\n\") || \"- (None detected)\";\n \n const directoryList = metadata.directories\n .map(dir => `- [${dir}/](file://./${dir}/) — *Add responsibilities of this directory* (see [${dir}/AGENTS.md](file://./${dir}/AGENTS.md) for local rules)`)\n .join(\"\\n\") || \"- (No directories detected)\";\n\n return `# AGENTS.md — AI Agent Context Entry Point\n\n> [!NOTE]\n> **To AI Coding Agents:** This file serves as your primary landing page for understanding the architecture, rules, and entry points of the **${metadata.projectName}** project. Before executing tasks or modifications, review this page and follow the links to specific files.\n\n## Project Overview\n*Briefly describe what this project does, its goals, and its business context.*\n\n## Core Stack & Environment\n### Languages\n${languagesList}\n\n### Frameworks & Libraries\n${frameworksList}\n\n### Infrastructure & Tools\n${toolsList}\n\n---\n\n## Repository Map\n\n### Core Knowledge Base\nAll architectural and domain-specific knowledge resides in the \\`knowledge/\\` directory:\n- [Architecture Overview](file://./knowledge/architecture/overview.md) — System components, data flow, design patterns.\n- [API Documentation](file://./knowledge/api/overview.md) — Endpoints, schemas, payloads.\n- [Architecture Decisions (ADRs)](file://./knowledge/decisions/README.md) — Why the project was built this way.\n- [Glossary of Terms](file://./knowledge/glossary/terms.md) — Domain vocabulary and definitions.\n- [Testing Guidelines](file://./knowledge/testing/overview.md) — Test setup, commands, and strategies.\n\n### Directory Structure\n${directoryList}\n\n---\n\n## Agent Guidelines & Conventions\n\n### 1. Read Before Write\n- Check the relevant local \\`AGENTS.md\\` inside directories you are editing.\n- Look at the [Architecture Decisions](file://./knowledge/decisions/README.md) to understand existing patterns (e.g. repository pattern, clean architecture).\n\n### 2. Standardized Changes\n- **API changes** MUST update [API Overview](file://./knowledge/api/overview.md) and local \\`AGENTS.md\\` interfaces.\n- **Architectural changes** require an Architecture Decision Record (ADR) under [Decisions](file://./knowledge/decisions/README.md).\n\n### 3. Verification\n- Always execute tests according to [Testing Guidelines](file://./knowledge/testing/overview.md) before declaring a task complete.\n`;\n}\n\n/**\n * Generate folder-level AGENTS.md template.\n */\nexport function generateFolderAgentsMd(folderName: string): string {\n return `# AGENTS.md — Local Directory Rules for \\`${folderName}/\\`\n\n> [!NOTE]\n> **To AI Coding Agents:** This file defines the responsibilities, entry points, and coding conventions specific to the \\`${folderName}/\\` directory. Adhere strictly to these guidelines when making modifications here.\n\n## Purpose & Responsibility\n*Describe the single responsibility of this directory (e.g. \\\"Handles authentication endpoints and JWT verification\\\").*\n\n## Core Entry Points\n- [\\`index.ts\\` or entry file](file://./index.ts) — *Describe what imports/exports this file exposes.*\n\n## Internal Dependencies & Imports\n- **Imports from other modules:** *Specify which parent modules this directory is allowed to import from.*\n- **Outward dependencies:** *What external npm/pip packages or databases does this folder communicate with?*\n\n## Conventions & Implementation Rules\n1. **Design Patterns**: *e.g., Use controllers for route handling, delegate business logic to services.*\n2. **Naming Conventions**: *e.g., Suffix all services with \\`Service\\` (e.g., \\`AuthService\\`).*\n3. **Error Handling**: *e.g., Do not throw raw errors; wrap in \\`AppError\\` with status codes.*\n4. **Security**: *e.g., Ensure JWT middleware is applied to all new route configurations.*\n`;\n}\n\n/**\n * Template for knowledge/architecture/overview.md\n */\nexport function generateArchitectureOverviewMd(projectName: string): string {\n return `# Architecture Overview — ${projectName}\n\n## System Overview\n*Provide a high-level description of how this system is put together. Mention if it is a monolith, microservices, SPA, Serverless, etc.*\n\n## Core Components\n*List the primary components/modules of the application and their relationships.*\n\n\\`\\`\\`mermaid\ngraph TD\n Client[Client / Frontend] --> API[API Gateway / Backend]\n API --> DB[(Database)]\n API --> Cache[(Cache / Redis)]\n\\`\\`\\`\n\n## Core Design Patterns\n*Outline the engineering patterns used in this codebase (e.g., Clean Architecture, MVC, CQRS, Repository Pattern, Dependency Injection).*\n\n- **Pattern A**: *Description of how it is applied.*\n- **Pattern B**: *Description of how it is applied.*\n\n## Data Flows\n1. **Request Flow**: *Trace a typical request from the frontend to database and back.*\n2. **Background Processes**: *Describe queues, cron jobs, event-driven pipelines if applicable.*\n`;\n}\n\n/**\n * Template for knowledge/api/overview.md\n */\nexport function generateApiOverviewMd(projectName: string): string {\n return `# API Reference — ${projectName}\n\n## Authentication & Authorization\n*Describe how clients authenticate to the APIs (e.g. Bearer tokens, cookies, API keys).*\n\n\\`\\`\\`http\nAuthorization: Bearer <token>\n\\`\\`\\`\n\n## Base URLs\n- Development: \\`http://localhost:3000/api\\`\n- Staging: \\`https://staging.api.example.com/v1\\`\n- Production: \\`https://api.example.com/v1\\`\n\n## Main Endpoints\n\n### 1. Health check\n- **Method / Path**: \\`GET /health\\`\n- **Description**: Returns the system status.\n- **Response**:\n \\`\\`\\`json\n {\n \"status\": \"healthy\",\n \"timestamp\": \"2026-07-27T18:00:00Z\"\n }\n \\`\\`\\`\n\n### 2. [Endpoint Name]\n- **Method / Path**: \\`POST /resource\\`\n- **Headers**: \\`Content-Type: application/json\\`\n- **Request Body**:\n \\`\\`\\`json\n {\n \"name\": \"example\"\n }\n \\`\\`\\`\n- **Response (201 Created)**:\n \\`\\`\\`json\n {\n \"id\": \"uuid-1234\",\n \"name\": \"example\"\n }\n \\`\\`\\`\n`;\n}\n\n/**\n * Template for knowledge/decisions/README.md\n */\nexport function generateDecisionsReadmeMd(projectName: string): string {\n return `# Architectural Decision Records (ADR)\n\nThis folder contains the history of major design and architectural choices made in the **${projectName}** repository.\n\n## What is an ADR?\nAn Architectural Decision Record (ADR) is a document that captures an important architectural decision, including the context in which the decision was made, the consequences of the decision, and its current status (Proposed, Accepted, Superceded).\n\n## ADR Index\n\n| ADR # | Title | Status | Date |\n|-------|-------|--------|------|\n| [ADR-001](file://./001-initial-architecture.md) | Initial Architecture Scaffolding | Accepted | 2026-07-27 |\n\n*To create a new ADR, copy the template format and name it sequentially (e.g. \\`002-use-redis-caching.md\\`).*\n`;\n}\n\n/**\n * Template for knowledge/glossary/terms.md\n */\nexport function generateGlossaryMd(): string {\n return `# Domain Glossary\n\nDefine the core business terms and domain models used in this repository. This reduces ambiguity for AI agents and onboarding engineers.\n\n| Term | Definition | Context / Usage |\n|------|------------|-----------------|\n| **ADR** | Architecture Decision Record. | Engineering workflow documentation |\n| **Agent** | An autonomous AI agent performing operations on code. | AI Coding context |\n| **Knowledge Layer** | The directory containing machine-readable code specification and guidelines. | Standard repo structure |\n`;\n}\n\n/**\n * Template for knowledge/testing/overview.md\n */\nexport function generateTestingOverviewMd(metadata: ProjectMetadata): string {\n return `# Testing Guidelines\n\n## Running Tests\n*Provide the exact commands required to execute the test suite.*\n\n\\`\\`\\`bash\n# Run unit tests\nnpm run test\n# Run integration / e2e tests\nnpm run test:e2e\n\\`\\`\\`\n\n## Testing Philosophy\n- **Unit Tests**: Describe where unit tests are placed (e.g., next to the file as \\`*.test.ts\\` or in a \\`test/\\` directory).\n- **Integration Tests**: Describe how to test integrations with mock services/databases.\n- **Coverage**: Target code coverage expectations.\n\n## Creating New Tests\n- Use the standard test framework configurations.\n- Mock external network calls using MSW, nock, or custom mock suites.\n`;\n}\n\n/**\n * Generate the prompt for folder-specific AGENTS.md generation.\n */\nexport function generateFolderAgentsPrompt(\n folderName: string,\n tree: string,\n filesContext: string\n): string {\n return `You are tasked with generating the customized folder-level AGENTS.md for the directory \\`${folderName}/\\`.\nBelow is the directory tree for this subdirectory:\n\\`\\`\\`\n${tree}\n\\`\\`\\`\n\nHere is the content of key files inside this directory:\n${filesContext}\n\nAnalyze the files to generate a highly detailed rules document for AI coding agents modifying this directory.\nInclude:\n1. **Purpose & Responsibility**: Describe the single responsibility of this directory (e.g. \"Handles authentication endpoints and JWT verification\").\n2. **Core Entry Points**: List the primary entry files and export signatures that other directories or external clients interact with.\n3. **Internal Dependencies & Imports**: Detail which other directories this folder imports from, and any critical packages it depends on.\n4. **Conventions & Implementation Rules**: Extract local conventions, design patterns (e.g., repository patterns, controller structures), naming schemes, and error/security constraints specific to this directory.\n\nFormat your output exactly as standard Markdown, using standard alert boxes (> [!NOTE]) for emphasis. Start directly with \\`# AGENTS.md — Local Directory Rules for \\`${folderName}/\\` \\`.`;\n}\n","import chalk from \"chalk\";\nimport prompts from \"prompts\";\n\n/**\n * Print a clean visual representation of the folders recommended for AGENTS.md creation.\n */\nexport function printFolderRecommendation(projectName: string, directories: string[]): void {\n if (directories.length === 0) return;\n\n console.log(chalk.bold(`\\nšŸ“ ${projectName}`));\n \n // Show up to 5 directories. If more, show the rest as a summary.\n const maxToShow = 5;\n const dirsToShow = directories.slice(0, maxToShow);\n const remaining = directories.length - maxToShow;\n\n dirsToShow.forEach((dir, idx) => {\n const isLast = idx === dirsToShow.length - 1 && remaining <= 0;\n const branch = isLast ? \"└──\" : \"ā”œā”€ā”€\";\n console.log(` ${branch} šŸ“ ${dir}/`);\n console.log(` ${isLast ? \" \" : \"│ \"} └── šŸ“ ${chalk.green(\"AGENTS.md\")} ${chalk.gray(\"(recommended)\")}`);\n });\n\n if (remaining > 0) {\n console.log(` └── ${chalk.gray(`... and ${remaining} more folders`)}`);\n }\n console.log();\n}\n\n/**\n * Interactively prompt the user to approve or select directories for AGENTS.md creation.\n * If the project is large (> 5 directories), we alert the user about potential token/time usage.\n */\nexport async function configureFolderAgentsCreation(\n projectName: string,\n directories: string[]\n): Promise<string[]> {\n const filteredDirs = directories.filter(dir => !dir.startsWith(\".\"));\n if (filteredDirs.length === 0) {\n return [];\n }\n\n printFolderRecommendation(projectName, filteredDirs);\n\n const isLargeProject = filteredDirs.length > 5;\n if (isLargeProject) {\n console.log(\n chalk.yellow(\n `āš ļø This is a large project with ${filteredDirs.length} folders recommended for AGENTS.md creation.`\n )\n );\n console.log(\n chalk.gray(\n ` Auto-creating rules via LLM for all folders may consume a significant amount of time and tokens.\\n`\n )\n );\n }\n\n const response = await prompts(\n {\n type: \"select\",\n name: \"action\",\n message: \"Configure folder-level AGENTS.md creation:\",\n choices: [\n {\n title: `Auto-create in all recommended folders (${filteredDirs.length} folders)`,\n value: \"all\",\n },\n {\n title: \"Manual control (select specific folders)\",\n value: \"manual\",\n },\n {\n title: \"Skip folder-level AGENTS.md entirely\",\n value: \"skip\",\n },\n ],\n initial: 0,\n },\n {\n onCancel: () => {\n console.log(chalk.yellow(\"\\nOperation cancelled.\"));\n process.exit(0);\n },\n }\n );\n\n if (response.action === \"all\") {\n return filteredDirs;\n }\n\n if (response.action === \"skip\") {\n return [];\n }\n\n if (response.action === \"manual\") {\n const manualResponse = await prompts(\n {\n type: \"multiselect\",\n name: \"folders\",\n message: \"Select subdirectories to create AGENTS.md in:\",\n choices: filteredDirs.map((dir) => ({\n title: `${dir}/`,\n value: dir,\n selected: true,\n })),\n hint: \"- Space to select/deselect, Enter to confirm\",\n min: 0,\n },\n {\n onCancel: () => {\n console.log(chalk.yellow(\"\\nOperation cancelled.\"));\n process.exit(0);\n },\n }\n );\n\n return manualResponse.folders || [];\n }\n\n return [];\n}\n"],"mappings":"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","names":["path","chalk","prompts","fs","fs","fs","path","path","fs","path","chalk","prompts"]}
package/package.json ADDED
@@ -0,0 +1,45 @@
1
+ {
2
+ "name": "docforagents",
3
+ "version": "0.1.0",
4
+ "description": "Open-source AI-native knowledge specification and tooling for software repositories",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "bin": {
8
+ "docforagents": "./dist/index.js"
9
+ },
10
+ "scripts": {
11
+ "build": "tsup",
12
+ "dev": "tsup --watch",
13
+ "test": "vitest run",
14
+ "start": "node dist/index.js",
15
+ "prepublishOnly": "npm run build"
16
+ },
17
+ "files": [
18
+ "dist"
19
+ ],
20
+ "keywords": [
21
+ "ai",
22
+ "agent",
23
+ "documentation",
24
+ "openapi",
25
+ "agents",
26
+ "knowledge",
27
+ "specification"
28
+ ],
29
+ "author": "",
30
+ "license": "Apache-2.0",
31
+ "dependencies": {
32
+ "@google/generative-ai": "^0.24.1",
33
+ "chalk": "^5.3.0",
34
+ "commander": "^12.1.0",
35
+ "fast-glob": "^3.3.2",
36
+ "prompts": "^2.4.2"
37
+ },
38
+ "devDependencies": {
39
+ "@types/node": "^20.14.12",
40
+ "@types/prompts": "^2.4.9",
41
+ "tsup": "^8.2.3",
42
+ "typescript": "^5.5.4",
43
+ "vitest": "^2.0.4"
44
+ }
45
+ }