@chappibunny/repolens 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/RELEASE.md ADDED
@@ -0,0 +1,52 @@
1
+ # RepoLens Release Process
2
+
3
+ ## Versioning
4
+
5
+ RepoLens uses semantic versioning:
6
+
7
+ - Patch: bug fixes, internal cleanup, non-breaking improvements
8
+ - Minor: new features, new commands, new publishers
9
+ - Major: breaking CLI or config changes
10
+
11
+ ## Release Checklist
12
+
13
+ 1. Run tests: `npm test`
14
+ 2. Test tarball installation: `npm run test:install`
15
+ 3. Verify CLI works:
16
+ - `repolens --help`
17
+ - `repolens --version`
18
+ 4. Update `CHANGELOG.md`
19
+ 5. Bump version in `package.json`
20
+ 6. Commit release changes
21
+ 7. Tag the release
22
+ 8. Push branch and tag
23
+ 9. CI validates package installation automatically
24
+
25
+ ## Example Patch Release
26
+
27
+ ```bash
28
+ # 1. Update version
29
+ npm run release:patch # or :minor, :major
30
+
31
+ # 2. Run tests
32
+ npm test
33
+
34
+ # 3. Test installation
35
+ npm run test:install
36
+
37
+ # 4. Push release
38
+ git push --follow-tags
39
+
40
+ # 5. Verify GitHub Actions
41
+ # Check: https://github.com/CHAPIBUNNY/repolens/actions
42
+ ```
43
+
44
+ ## Testing Upgrade Path
45
+
46
+ To test that users can upgrade successfully:
47
+
48
+ ```bash
49
+ # In a test project
50
+ npx repolens@latest --version
51
+ npx repolens@latest publish
52
+ ```
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ import "../src/cli.js";
package/package.json ADDED
@@ -0,0 +1,61 @@
1
+ {
2
+ "name": "@chappibunny/repolens",
3
+ "version": "0.4.1",
4
+ "description": "AI-assisted documentation intelligence system for technical and non-technical audiences",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "main": "src/cli.js",
8
+ "bin": {
9
+ "repolens": "./bin/repolens.js"
10
+ },
11
+ "files": [
12
+ "bin",
13
+ "src",
14
+ "package.json",
15
+ "README.md",
16
+ "CHANGELOG.md",
17
+ "RELEASE.md"
18
+ ],
19
+ "keywords": [
20
+ "cli",
21
+ "docs",
22
+ "architecture",
23
+ "github",
24
+ "notion",
25
+ "markdown",
26
+ "developer-tools"
27
+ ],
28
+ "repository": {
29
+ "type": "git",
30
+ "url": "git+https://github.com/CHAPIBUNNY/repolens.git"
31
+ },
32
+ "homepage": "https://github.com/CHAPIBUNNY/repolens#readme",
33
+ "bugs": {
34
+ "url": "https://github.com/CHAPIBUNNY/repolens/issues"
35
+ },
36
+ "author": "Charl van Zyl",
37
+ "scripts": {
38
+ "test:notion": "node notion-test.js",
39
+ "publish": "node src/cli.js publish --config ../../.repolens.yml",
40
+ "init:test": "node src/cli.js init --target /tmp/repolens-init-test",
41
+ "test": "NODE_ENV=test vitest run --no-watch --reporter=verbose",
42
+ "pack:check": "npm pack",
43
+ "release:check": "npm test && npm pack",
44
+ "test:install": "./test-install.sh",
45
+ "release:patch": "npm version patch",
46
+ "release:minor": "npm version minor",
47
+ "release:major": "npm version major"
48
+ },
49
+ "dependencies": {
50
+ "dotenv": "^17.3.1",
51
+ "fast-glob": "^3.3.3",
52
+ "js-yaml": "^4.1.0",
53
+ "node-fetch": "^3.3.2"
54
+ },
55
+ "optionalDependencies": {
56
+ "@mermaid-js/mermaid-cli": "^11.12.0"
57
+ },
58
+ "devDependencies": {
59
+ "vitest": "^4.0.18"
60
+ }
61
+ }
@@ -0,0 +1,133 @@
1
+ // Document plan - defines the canonical document structure
2
+
3
+ export const DOCUMENT_PLAN = [
4
+ {
5
+ key: "executive_summary",
6
+ filename: "00-executive-summary.md",
7
+ title: "Executive Summary",
8
+ audience: "non-technical",
9
+ ai: true,
10
+ description: "High-level overview for leadership, product, and stakeholders"
11
+ },
12
+ {
13
+ key: "system_overview",
14
+ filename: "01-system-overview.md",
15
+ title: "System Overview",
16
+ audience: "mixed",
17
+ ai: true,
18
+ description: "Concise technical overview readable by all"
19
+ },
20
+ {
21
+ key: "business_domains",
22
+ filename: "02-business-domains.md",
23
+ title: "Business Domains",
24
+ audience: "mixed",
25
+ ai: true,
26
+ description: "Codebase structure translated into business language"
27
+ },
28
+ {
29
+ key: "architecture_overview",
30
+ filename: "03-architecture-overview.md",
31
+ title: "Architecture Overview",
32
+ audience: "technical",
33
+ ai: true,
34
+ description: "Layered architecture and design patterns"
35
+ },
36
+ {
37
+ key: "module_catalog",
38
+ filename: "04-module-catalog.md",
39
+ title: "Module Catalog",
40
+ audience: "technical",
41
+ ai: "hybrid",
42
+ description: "Complete inventory of code modules with AI explanations"
43
+ },
44
+ {
45
+ key: "route_map",
46
+ filename: "05-route-map.md",
47
+ title: "Route Map",
48
+ audience: "mixed",
49
+ ai: "hybrid",
50
+ description: "Application routes and API endpoints with context"
51
+ },
52
+ {
53
+ key: "api_surface",
54
+ filename: "06-api-surface.md",
55
+ title: "API Surface",
56
+ audience: "technical",
57
+ ai: "hybrid",
58
+ description: "Backend API endpoints with usage examples"
59
+ },
60
+ {
61
+ key: "data_flows",
62
+ filename: "07-data-flows.md",
63
+ title: "Data Flows",
64
+ audience: "mixed",
65
+ ai: true,
66
+ description: "Major information flows through the system"
67
+ },
68
+ {
69
+ key: "arch_diff",
70
+ filename: "08-change-impact.md",
71
+ title: "Architecture Diff",
72
+ audience: "mixed",
73
+ ai: true,
74
+ description: "Git diff analysis and impact assessment"
75
+ },
76
+ {
77
+ key: "system_map",
78
+ filename: "09-system-map.md",
79
+ title: "System Map",
80
+ audience: "mixed",
81
+ ai: "hybrid",
82
+ description: "Visual dependency graph with explanation"
83
+ },
84
+ {
85
+ key: "developer_onboarding",
86
+ filename: "10-developer-onboarding.md",
87
+ title: "Developer Onboarding",
88
+ audience: "technical",
89
+ ai: true,
90
+ description: "Quick start guide for new developers"
91
+ }
92
+ ];
93
+
94
+ export function getDocumentByKey(key) {
95
+ return DOCUMENT_PLAN.find(doc => doc.key === key);
96
+ }
97
+
98
+ export function getDocumentsByAudience(audience) {
99
+ return DOCUMENT_PLAN.filter(doc => doc.audience === audience);
100
+ }
101
+
102
+ export function getAIDocuments() {
103
+ return DOCUMENT_PLAN.filter(doc => doc.ai === true || doc.ai === "hybrid");
104
+ }
105
+
106
+ export function getDeterministicDocuments() {
107
+ return DOCUMENT_PLAN.filter(doc => !doc.ai);
108
+ }
109
+
110
+ export function getActiveDocuments(config) {
111
+ // If config specifies which sections to include, filter by that
112
+ if (config.documentation?.sections) {
113
+ return DOCUMENT_PLAN.filter(doc =>
114
+ config.documentation.sections.includes(doc.key)
115
+ );
116
+ }
117
+
118
+ // If features flags exist, respect them
119
+ if (config.features) {
120
+ return DOCUMENT_PLAN.filter(doc => {
121
+ // Always include core docs
122
+ if (["system_overview", "module_catalog", "route_map"].includes(doc.key)) {
123
+ return true;
124
+ }
125
+
126
+ // Check feature flags
127
+ return config.features[doc.key] !== false;
128
+ });
129
+ }
130
+
131
+ // Default: all documents
132
+ return DOCUMENT_PLAN;
133
+ }
@@ -0,0 +1,271 @@
1
+ // Generate documentation sections using AI
2
+
3
+ import { generateText, isAIEnabled } from "./provider.js";
4
+ import {
5
+ SYSTEM_PROMPT,
6
+ createExecutiveSummaryPrompt,
7
+ createSystemOverviewPrompt,
8
+ createBusinessDomainsPrompt,
9
+ createArchitectureOverviewPrompt,
10
+ createDataFlowsPrompt,
11
+ createDeveloperOnboardingPrompt,
12
+ createModuleSummaryPrompt,
13
+ createRouteSummaryPrompt,
14
+ createAPIDocumentationPrompt
15
+ } from "./prompts.js";
16
+ import { info, warn } from "../utils/logger.js";
17
+
18
+ export async function generateExecutiveSummary(context) {
19
+ if (!isAIEnabled()) {
20
+ return getFallbackExecutiveSummary(context);
21
+ }
22
+
23
+ info("Generating executive summary with AI...");
24
+
25
+ const result = await generateText({
26
+ system: SYSTEM_PROMPT,
27
+ user: createExecutiveSummaryPrompt(context),
28
+ temperature: 0.2,
29
+ maxTokens: 1500
30
+ });
31
+
32
+ if (!result.success) {
33
+ warn("AI generation failed, using fallback");
34
+ return getFallbackExecutiveSummary(context);
35
+ }
36
+
37
+ return result.text;
38
+ }
39
+
40
+ export async function generateSystemOverview(context) {
41
+ if (!isAIEnabled()) {
42
+ return getFallbackSystemOverview(context);
43
+ }
44
+
45
+ info("Generating system overview with AI...");
46
+
47
+ const result = await generateText({
48
+ system: SYSTEM_PROMPT,
49
+ user: createSystemOverviewPrompt(context),
50
+ temperature: 0.2,
51
+ maxTokens: 1200
52
+ });
53
+
54
+ if (!result.success) {
55
+ return getFallbackSystemOverview(context);
56
+ }
57
+
58
+ return result.text;
59
+ }
60
+
61
+ export async function generateBusinessDomains(context) {
62
+ if (!isAIEnabled()) {
63
+ return getFallbackBusinessDomains(context);
64
+ }
65
+
66
+ info("Generating business domains with AI...");
67
+
68
+ const result = await generateText({
69
+ system: SYSTEM_PROMPT,
70
+ user: createBusinessDomainsPrompt(context),
71
+ temperature: 0.2,
72
+ maxTokens: 2000
73
+ });
74
+
75
+ if (!result.success) {
76
+ return getFallbackBusinessDomains(context);
77
+ }
78
+
79
+ return result.text;
80
+ }
81
+
82
+ export async function generateArchitectureOverview(context) {
83
+ if (!isAIEnabled()) {
84
+ return getFallbackArchitectureOverview(context);
85
+ }
86
+
87
+ info("Generating architecture overview with AI...");
88
+
89
+ const result = await generateText({
90
+ system: SYSTEM_PROMPT,
91
+ user: createArchitectureOverviewPrompt(context),
92
+ temperature: 0.2,
93
+ maxTokens: 1800
94
+ });
95
+
96
+ if (!result.success) {
97
+ return getFallbackArchitectureOverview(context);
98
+ }
99
+
100
+ return result.text;
101
+ }
102
+
103
+ export async function generateDataFlows(flows, context) {
104
+ if (!isAIEnabled()) {
105
+ return getFallbackDataFlows(flows);
106
+ }
107
+
108
+ info("Generating data flows with AI...");
109
+
110
+ const result = await generateText({
111
+ system: SYSTEM_PROMPT,
112
+ user: createDataFlowsPrompt(flows, context),
113
+ temperature: 0.2,
114
+ maxTokens: 1800
115
+ });
116
+
117
+ if (!result.success) {
118
+ return getFallbackDataFlows(flows);
119
+ }
120
+
121
+ return result.text;
122
+ }
123
+
124
+ export async function generateDeveloperOnboarding(context) {
125
+ if (!isAIEnabled()) {
126
+ return getFallbackDeveloperOnboarding(context);
127
+ }
128
+
129
+ info("Generating developer onboarding with AI...");
130
+
131
+ const result = await generateText({
132
+ system: SYSTEM_PROMPT,
133
+ user: createDeveloperOnboardingPrompt(context),
134
+ temperature: 0.2,
135
+ maxTokens: 2200
136
+ });
137
+
138
+ if (!result.success) {
139
+ return getFallbackDeveloperOnboarding(context);
140
+ }
141
+
142
+ return result.text;
143
+ }
144
+
145
+ // Fallback generators (deterministic, no AI)
146
+
147
+ function getFallbackExecutiveSummary(context) {
148
+ return `# Executive Summary
149
+
150
+ ## What this system does
151
+
152
+ ${context.project.name} is a ${context.techStack.frameworks.join(", ") || "software"} application with ${context.project.modulesDetected} modules across ${context.project.filesScanned} files.
153
+
154
+ ## Main system areas
155
+
156
+ The codebase is organized into ${context.domains.length} main domains:
157
+
158
+ ${context.domains.map(d => `- ${d.name}: ${d.moduleCount} modules`).join("\n")}
159
+
160
+ ## Technology stack
161
+
162
+ - Frameworks: ${context.techStack.frameworks.join(", ") || "Not detected"}
163
+ - Languages: ${context.techStack.languages.join(", ") || "Not detected"}
164
+ - Build tools: ${context.techStack.buildTools.join(", ") || "Not detected"}
165
+
166
+ ## Key observations
167
+
168
+ - ${context.project.pagesDetected} pages detected
169
+ - ${context.project.apiRoutesDetected} API routes detected
170
+ - Architecture patterns: ${context.patterns.join(", ") || "Standard patterns"}
171
+
172
+ Note: AI-enhanced documentation is disabled. Enable with REPOLENS_AI_ENABLED=true for richer insights.`;
173
+ }
174
+
175
+ function getFallbackSystemOverview(context) {
176
+ return `# System Overview
177
+
178
+ ## Repository snapshot
179
+
180
+ - Files scanned: ${context.project.filesScanned}
181
+ - Modules: ${context.project.modulesDetected}
182
+ - Pages: ${context.project.pagesDetected}
183
+ - APIs: ${context.project.apiRoutesDetected}
184
+
185
+ ## Technology patterns
186
+
187
+ ${context.patterns.map(p => `- ${p}`).join("\n")}
188
+
189
+ ## Dominant domains
190
+
191
+ ${context.domains.slice(0, 5).map((d, i) => `${i + 1}. ${d.name} (${d.fileCount} files)`).join("\n")}
192
+
193
+ Note: AI-enhanced documentation is disabled. Enable with REPOLENS_AI_ENABLED=true for richer insights.`;
194
+ }
195
+
196
+ function getFallbackBusinessDomains(context) {
197
+ let output = `# Business Domains\n\n`;
198
+
199
+ for (const domain of context.domains) {
200
+ output += `## Domain: ${domain.name}\n\n`;
201
+ output += `${domain.description}\n\n`;
202
+ output += `Modules: ${domain.moduleCount}\n`;
203
+ output += `Files: ${domain.fileCount}\n\n`;
204
+ output += `Main modules:\n`;
205
+ output += domain.topModules.slice(0, 5).map(m => `- ${m}`).join("\n");
206
+ output += `\n\n`;
207
+ }
208
+
209
+ output += `Note: AI-enhanced documentation is disabled. Enable with REPOLENS_AI_ENABLED=true for richer insights.`;
210
+
211
+ return output;
212
+ }
213
+
214
+ function getFallbackArchitectureOverview(context) {
215
+ return `# Architecture Overview
216
+
217
+ ## Architecture style
218
+
219
+ Based on detected patterns: ${context.patterns.join(", ")}
220
+
221
+ ## Key layers
222
+
223
+ ${context.domains.slice(0, 5).map(d => `- ${d.name}: ${d.description}`).join("\n")}
224
+
225
+ ## Technology stack
226
+
227
+ - Frameworks: ${context.techStack.frameworks.join(", ")}
228
+ - Languages: ${context.techStack.languages.join(", ")}
229
+ - Build tools: ${context.techStack.buildTools.join(", ")}
230
+
231
+ Note: AI-enhanced documentation is disabled. Enable with REPOLENS_AI_ENABLED=true for richer insights.`;
232
+ }
233
+
234
+ function getFallbackDataFlows(flows) {
235
+ let output = `# Data Flows\n\n`;
236
+
237
+ for (const flow of flows) {
238
+ output += `## ${flow.name}\n\n`;
239
+ output += `${flow.description}\n\n`;
240
+ output += `Steps:\n`;
241
+ output += flow.steps.map((s, i) => `${i + 1}. ${s}`).join("\n");
242
+ output += `\n\n`;
243
+ }
244
+
245
+ output += `Note: AI-enhanced documentation is disabled. Enable with REPOLENS_AI_ENABLED=true for richer insights.`;
246
+
247
+ return output;
248
+ }
249
+
250
+ function getFallbackDeveloperOnboarding(context) {
251
+ return `# Developer Onboarding
252
+
253
+ ## Start here
254
+
255
+ This is a ${context.project.name} repository with ${context.project.modulesDetected} modules.
256
+
257
+ ## Main folders
258
+
259
+ ${context.repoRoots.map(root => `- ${root}`).join("\n")}
260
+
261
+ ## Technology stack
262
+
263
+ - ${context.techStack.frameworks.join(", ")}
264
+ - ${context.techStack.languages.join(", ")}
265
+
266
+ ## Top modules by size
267
+
268
+ ${context.topModules.slice(0, 10).map((m, i) => `${i + 1}. ${m.key} (${m.fileCount} files)`).join("\n")}
269
+
270
+ Note: AI-enhanced documentation is disabled. Enable with REPOLENS_AI_ENABLED=true for richer insights.`;
271
+ }