@chappibunny/repolens 0.9.0 → 1.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/CHANGELOG.md +76 -0
- package/README.md +63 -33
- package/package.json +1 -1
- package/src/ai/generate-sections.js +0 -6
- package/src/ai/provider.js +30 -19
- package/src/cli.js +35 -15
- package/src/core/config-schema.js +61 -12
- package/src/init.js +2 -5
- package/src/migrate.js +2 -2
- package/src/publishers/github-wiki.js +454 -0
- package/src/publishers/index.js +24 -2
- package/src/publishers/notion.js +2 -2
- package/src/publishers/publish.js +2 -1
- package/src/utils/branch.js +27 -0
- package/src/utils/rate-limit.js +4 -2
- package/src/utils/telemetry.js +6 -2
- package/src/utils/update-check.js +2 -2
- package/src/utils/validate.js +33 -24
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,82 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to RepoLens will be documented in this file.
|
|
4
4
|
|
|
5
|
+
## 1.1.0
|
|
6
|
+
|
|
7
|
+
### ✨ GitHub Wiki Publisher UX Enhancement
|
|
8
|
+
|
|
9
|
+
Major upgrade to the wiki output quality — better information hierarchy, audience-aware navigation, and richer page structure.
|
|
10
|
+
|
|
11
|
+
- **Audience-grouped Home page**: Pages organized by reader (Stakeholders, Engineers, New Contributors, Change Tracking) instead of a flat list
|
|
12
|
+
- **Page descriptions**: Each link on Home includes a one-line summary of the page's purpose
|
|
13
|
+
- **Status rail**: Home page now shows a metadata table (project, branch, page count, publisher, source)
|
|
14
|
+
- **Recommended reading order**: Guided path through the docs for first-time readers
|
|
15
|
+
- **Grouped sidebar**: Navigation split into Overview and Architecture sections (plus Custom Pages)
|
|
16
|
+
- **Page metadata headers**: Every page gets a `[← Home](Home)` back-link, audience tag, and branch indicator
|
|
17
|
+
- **Cleaner footer**: Compact format with branch context and Home link
|
|
18
|
+
- **New constants**: `PAGE_DESCRIPTIONS`, `AUDIENCE_GROUPS`, `SIDEBAR_GROUPS`, `PAGE_AUDIENCE`
|
|
19
|
+
- **New helpers**: `getPageDisplayTitle()`, `getCustomPageKeys()`, `wikiLink()`, `pageHeader()`
|
|
20
|
+
|
|
21
|
+
### 🐛 Bug Fixes
|
|
22
|
+
- **Temperature still sent to GPT-5**: `DEFAULT_TEMPERATURE = 0.2` always leaked into API requests even after v1.0.1 fixes — the fallback chain (`temperature ?? aiConfig.temperature ?? DEFAULT_TEMPERATURE`) guaranteed it was never `undefined`. Removed the default entirely; temperature is now only sent when explicitly configured via `REPOLENS_AI_TEMPERATURE` env var or `ai.temperature` in config.
|
|
23
|
+
|
|
24
|
+
## 1.0.1
|
|
25
|
+
|
|
26
|
+
### 🐛 Bug Fixes
|
|
27
|
+
- **GPT-5 API compatibility**: Use `max_completion_tokens` instead of deprecated `max_tokens` parameter
|
|
28
|
+
- **GPT-5 temperature handling**: Omit `temperature` from API requests for models that only support the default value (e.g. gpt-5-mini)
|
|
29
|
+
- Removed all hardcoded `temperature: 0.2` overrides from AI section generators
|
|
30
|
+
- Removed `REPOLENS_AI_TEMPERATURE` from CI workflow and `.env.example`
|
|
31
|
+
- Updated `init` scaffolding to omit temperature from default config
|
|
32
|
+
|
|
33
|
+
### 🔧 Improvements
|
|
34
|
+
- Upgraded GitHub Actions: checkout v4.2.2, setup-node v4.2.0, Node.js 22
|
|
35
|
+
|
|
36
|
+
## 1.0.0
|
|
37
|
+
|
|
38
|
+
### 🎉 Stable Release
|
|
39
|
+
|
|
40
|
+
RepoLens v1.0.0 marks the first stable release with a frozen public API. All CLI commands, configuration schema, and plugin interfaces are now covered by semantic versioning guarantees. See [STABILITY.md](STABILITY.md) for the full contract.
|
|
41
|
+
|
|
42
|
+
### ✨ New Features
|
|
43
|
+
- **GitHub Wiki Publisher**: Publish documentation directly to your repository's Wiki tab
|
|
44
|
+
- Git-based: clones wiki repo, writes pages, commits and pushes
|
|
45
|
+
- Generates `Home.md` index, `_Sidebar.md` navigation, `_Footer.md`
|
|
46
|
+
- Branch filtering via `github_wiki.branches` in `.repolens.yml`
|
|
47
|
+
- Auto-detects repository from `GITHUB_REPOSITORY` env or git remote
|
|
48
|
+
- Token sanitization in error messages (never leaks `GITHUB_TOKEN`)
|
|
49
|
+
- Config: `sidebar` and `footer` toggles
|
|
50
|
+
- 17 tests covering publishing, branch filtering, config validation, and security
|
|
51
|
+
|
|
52
|
+
### 🐛 Bug Fixes
|
|
53
|
+
- **GPT-5 API compatibility**: Use `max_completion_tokens` instead of deprecated `max_tokens` parameter
|
|
54
|
+
- **GPT-5 temperature handling**: Omit `temperature` from API requests for models that only support the default value (e.g. gpt-5-mini)
|
|
55
|
+
- **Git identity in wiki publisher**: Set committer name/email (`RepoLens Bot`) so CI runners can commit
|
|
56
|
+
- **Publisher allowlist**: Added `github_wiki` to `validate.js` publisher validation (was only in `config-schema.js`)
|
|
57
|
+
- **Doctor false-success**: `repolens doctor` now correctly exits with code 2 when `runDoctor()` reports failures (previously always printed "validation passed")
|
|
58
|
+
- **Feedback exit code**: `repolens feedback` now exits with code 1 when feedback fails to send (previously exited 0)
|
|
59
|
+
- **Unknown flags**: `repolens --unknown-flag` now prints an error instead of silently running publish
|
|
60
|
+
- **scan.ignore security bypass**: Security validator now checks `scan.ignore` patterns (was incorrectly checking non-existent `scan.exclude`)
|
|
61
|
+
- **Domains type mismatch**: Both validators now expect `domains` as an object (was array in security validator, object in schema validator)
|
|
62
|
+
- **Plugin publisher crash isolation**: Plugin publisher errors are now caught and logged instead of crashing the pipeline
|
|
63
|
+
|
|
64
|
+
### ✅ Config Stability
|
|
65
|
+
- `configVersion: 1` is now **required** (was optional in schema validator)
|
|
66
|
+
- Added `confluence` config section validation (branches array)
|
|
67
|
+
- Added `ai.temperature` range validation (0–2)
|
|
68
|
+
- Added `ai.max_tokens` range validation (>0)
|
|
69
|
+
- AI config values from `.repolens.yml` are now used as fallbacks when env vars are not set
|
|
70
|
+
|
|
71
|
+
### 🔧 Improvements
|
|
72
|
+
- Standardized exit codes: `EXIT_SUCCESS=0`, `EXIT_ERROR=1`, `EXIT_VALIDATION=2` as named constants
|
|
73
|
+
- Replaced all `console.log`/`console.warn` in production code with logger utilities
|
|
74
|
+
- Removed stale "v0.4.0" references from CLI help text and migrate command
|
|
75
|
+
- Sentry DSN moved to `REPOLENS_SENTRY_DSN` env var (with backwards-compatible default)
|
|
76
|
+
- Hardcoded email in `init` scaffolding replaced with `your-email@example.com` placeholder
|
|
77
|
+
|
|
78
|
+
### 📄 Documentation
|
|
79
|
+
- Added [STABILITY.md](STABILITY.md): Complete public API contract (CLI, config schema, plugin interface, exit codes, env vars)
|
|
80
|
+
|
|
5
81
|
## 0.9.0
|
|
6
82
|
|
|
7
83
|
### ✨ New Features
|
package/README.md
CHANGED
|
@@ -16,11 +16,11 @@
|
|
|
16
16
|
|
|
17
17
|
AI-assisted documentation intelligence system that generates architecture docs for engineers AND readable system docs for stakeholders
|
|
18
18
|
|
|
19
|
-
**Current Status**:
|
|
19
|
+
**Current Status**: v1.0.0 — Stable Release
|
|
20
20
|
|
|
21
21
|
RepoLens automatically generates and maintains living architecture documentation by analyzing your repository structure, extracting meaningful insights from your package.json, and creating visual dependency graphs. Run it once, or let it auto-update on every push.
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
The CLI, configuration schema, and plugin interface are **stable** as of v1.0. See [STABILITY.md](STABILITY.md) for the full API contract and semver guarantees.
|
|
24
24
|
|
|
25
25
|
---
|
|
26
26
|
|
|
@@ -49,7 +49,7 @@ For Confluence:
|
|
|
49
49
|
```bash
|
|
50
50
|
# Edit .env and add:
|
|
51
51
|
CONFLUENCE_URL=https://your-company.atlassian.net/wiki
|
|
52
|
-
CONFLUENCE_EMAIL=
|
|
52
|
+
CONFLUENCE_EMAIL=your-email@example.com
|
|
53
53
|
CONFLUENCE_API_TOKEN=your-token
|
|
54
54
|
CONFLUENCE_SPACE_KEY=DOCS
|
|
55
55
|
```
|
|
@@ -124,7 +124,7 @@ RepoLens automatically detects:
|
|
|
124
124
|
✅ **Deterministic Fallback** - Always generates docs even if AI unavailable
|
|
125
125
|
✅ **Business Domain Inference** - Automatically maps code to business functions
|
|
126
126
|
✅ **Data Flow Analysis** - Understands how information moves through your system
|
|
127
|
-
✅ **Multiple Publishers** - Output to Notion, Confluence, Markdown, or all
|
|
127
|
+
✅ **Multiple Publishers** - Output to Notion, Confluence, GitHub Wiki, Markdown, or all four
|
|
128
128
|
✅ **Branch-Aware** - Prevent doc conflicts across branches
|
|
129
129
|
✅ **GitHub Actions** - Autonomous operation on every push
|
|
130
130
|
✅ **Team Notifications** - Discord integration with rich embeds (NEW in v0.6.0)
|
|
@@ -137,6 +137,8 @@ RepoLens automatically detects:
|
|
|
137
137
|
✅ **TypeScript Type Graph** - Map interfaces, classes, and type relationships (NEW in v0.8.0)
|
|
138
138
|
✅ **Dependency Graph** - Import analysis with circular dependency detection (NEW in v0.8.0)
|
|
139
139
|
✅ **Architecture Drift** - Track structural changes against a baseline (NEW in v0.8.0)
|
|
140
|
+
✅ **Plugin System** - Extend with custom renderers, publishers, and hooks (NEW in v0.9.0)
|
|
141
|
+
✅ **Stable API** - CLI, config, and plugin interface frozen with semver guarantees (v1.0.0)
|
|
140
142
|
|
|
141
143
|
---
|
|
142
144
|
|
|
@@ -228,7 +230,7 @@ npm link
|
|
|
228
230
|
Install from a specific version:
|
|
229
231
|
|
|
230
232
|
```bash
|
|
231
|
-
npm install https://github.com/CHAPIBUNNY/repolens/releases/download/
|
|
233
|
+
npm install https://github.com/CHAPIBUNNY/repolens/releases/download/v1.0.0/chappibunny-repolens-1.0.0.tgz
|
|
232
234
|
```
|
|
233
235
|
</details>
|
|
234
236
|
|
|
@@ -311,6 +313,14 @@ publishers:
|
|
|
311
313
|
```
|
|
312
314
|
Maximum visibility: Notion for async collaboration, Confluence for enterprise docs, Markdown for local backups.
|
|
313
315
|
|
|
316
|
+
**GitHub Wiki** (ideal for open source):
|
|
317
|
+
```yaml
|
|
318
|
+
publishers:
|
|
319
|
+
- github_wiki
|
|
320
|
+
- markdown
|
|
321
|
+
```
|
|
322
|
+
Docs live alongside your code — accessible from the repo's Wiki tab. Requires `GITHUB_TOKEN`.
|
|
323
|
+
|
|
314
324
|
### Step 3: Enable AI Features (Optional)
|
|
315
325
|
|
|
316
326
|
**AI-enhanced documentation adds natural language explanations for non-technical audiences.**
|
|
@@ -318,7 +328,7 @@ Maximum visibility: Notion for async collaboration, Confluence for enterprise do
|
|
|
318
328
|
**3.1: Choose an AI Provider**
|
|
319
329
|
|
|
320
330
|
RepoLens works with any OpenAI-compatible API:
|
|
321
|
-
- **OpenAI** (gpt-
|
|
331
|
+
- **OpenAI** (gpt-5-mini, gpt-5.4, gpt-5-nano)
|
|
322
332
|
- **Anthropic Claude** (via API gateway)
|
|
323
333
|
- **Azure OpenAI** (enterprise deployments)
|
|
324
334
|
- **Local Models** (Ollama, LM Studio, etc.)
|
|
@@ -333,8 +343,7 @@ REPOLENS_AI_API_KEY=sk-xxxxxxxxxxxxx
|
|
|
333
343
|
|
|
334
344
|
# Optional: Customize provider
|
|
335
345
|
REPOLENS_AI_BASE_URL=https://api.openai.com/v1
|
|
336
|
-
REPOLENS_AI_MODEL=gpt-
|
|
337
|
-
REPOLENS_AI_TEMPERATURE=0.3
|
|
346
|
+
REPOLENS_AI_MODEL=gpt-5-mini
|
|
338
347
|
REPOLENS_AI_MAX_TOKENS=2000
|
|
339
348
|
```
|
|
340
349
|
|
|
@@ -344,7 +353,6 @@ REPOLENS_AI_MAX_TOKENS=2000
|
|
|
344
353
|
ai:
|
|
345
354
|
enabled: true # Enable AI features
|
|
346
355
|
mode: hybrid # hybrid, full, or off
|
|
347
|
-
temperature: 0.3 # Lower = more focused (0.0-1.0)
|
|
348
356
|
max_tokens: 2000 # Token limit per request
|
|
349
357
|
|
|
350
358
|
features:
|
|
@@ -356,7 +364,7 @@ features:
|
|
|
356
364
|
change_impact: true # Architecture diff with context
|
|
357
365
|
```
|
|
358
366
|
|
|
359
|
-
**Cost Estimates** (with gpt-
|
|
367
|
+
**Cost Estimates** (with gpt-5-mini):
|
|
360
368
|
- Small repo (<50 files): $0.10-$0.30 per run
|
|
361
369
|
- Medium repo (50-200 files): $0.30-$0.80 per run
|
|
362
370
|
- Large repo (200+ files): $0.80-$2.00 per run
|
|
@@ -428,7 +436,7 @@ If using the Confluence publisher:
|
|
|
428
436
|
Create `.env` in your project root:
|
|
429
437
|
```bash
|
|
430
438
|
CONFLUENCE_URL=https://your-company.atlassian.net/wiki
|
|
431
|
-
CONFLUENCE_EMAIL=
|
|
439
|
+
CONFLUENCE_EMAIL=your-email@example.com
|
|
432
440
|
CONFLUENCE_API_TOKEN=your-api-token-here
|
|
433
441
|
CONFLUENCE_SPACE_KEY=DOCS
|
|
434
442
|
CONFLUENCE_PARENT_PAGE_ID=123456789 # Optional
|
|
@@ -449,7 +457,7 @@ Add as repository secrets:
|
|
|
449
457
|
2. Click **"New repository secret"**
|
|
450
458
|
3. Add:
|
|
451
459
|
- Name: `CONFLUENCE_URL`, Value: `https://your-company.atlassian.net/wiki`
|
|
452
|
-
- Name: `CONFLUENCE_EMAIL`, Value: `
|
|
460
|
+
- Name: `CONFLUENCE_EMAIL`, Value: `your-email@example.com`
|
|
453
461
|
- Name: `CONFLUENCE_API_TOKEN`, Value: `your-token`
|
|
454
462
|
- Name: `CONFLUENCE_SPACE_KEY`, Value: `DOCS`
|
|
455
463
|
- Name: `CONFLUENCE_PARENT_PAGE_ID`, Value: `123456789` (optional)
|
|
@@ -939,13 +947,17 @@ features:
|
|
|
939
947
|
|
|
940
948
|
| Field | Type | Required | Description |
|
|
941
949
|
|-------|------|----------|-------------|
|
|
942
|
-
| `configVersion` | number |
|
|
950
|
+
| `configVersion` | number | **Yes** | Schema version (must be `1`) |
|
|
943
951
|
| `project.name` | string | Yes | Project name |
|
|
944
952
|
| `project.docs_title_prefix` | string | No | Prefix for documentation titles (default: project name) |
|
|
945
|
-
| `publishers` | array | Yes | Output targets: `notion`, `confluence`, `markdown` |
|
|
953
|
+
| `publishers` | array | Yes | Output targets: `notion`, `confluence`, `github_wiki`, `markdown` (+ plugin publishers) |
|
|
954
|
+
| `plugins` | array | No | Plugin paths or npm package names |
|
|
946
955
|
| `notion.branches` | array | No | Branch whitelist for Notion publishing. Supports globs. |
|
|
947
956
|
| `notion.includeBranchInTitle` | boolean | No | Add `[branch-name]` to titles (default: `true`) |
|
|
948
957
|
| `confluence.branches` | array | No | Branch whitelist for Confluence publishing. Supports globs. |
|
|
958
|
+
| `github_wiki.branches` | array | No | Branch whitelist for GitHub Wiki publishing. Supports globs. |
|
|
959
|
+
| `github_wiki.sidebar` | boolean | No | Generate `_Sidebar.md` navigation (default: `true`) |
|
|
960
|
+
| `github_wiki.footer` | boolean | No | Generate `_Footer.md` (default: `true`) |
|
|
949
961
|
| `discord.enabled` | boolean | No | Enable Discord notifications (default: `true` if webhook set) |
|
|
950
962
|
| `discord.notifyOn` | string | No | Notification policy: `always`, `significant`, `never` (default: `significant`) |
|
|
951
963
|
| `discord.significantThreshold` | number | No | Change % threshold for notifications (default: `10`) |
|
|
@@ -956,7 +968,11 @@ features:
|
|
|
956
968
|
| `scan.ignore` | array | Yes | Glob patterns to exclude |
|
|
957
969
|
| `module_roots` | array | No | Root directories for module detection |
|
|
958
970
|
| `outputs.pages` | array | Yes | Documentation pages to generate |
|
|
959
|
-
| `features` | object | No |
|
|
971
|
+
| `features` | object | No | Feature flags (boolean values) |
|
|
972
|
+
| `ai.enabled` | boolean | No | Enable AI-powered documentation |
|
|
973
|
+
| `ai.mode` | string | No | AI mode: `hybrid`, `full`, or `off` |
|
|
974
|
+
| `ai.temperature` | number | No | Generation temperature (0–2). Not supported by all models (e.g. gpt-5-mini ignores it) |
|
|
975
|
+
| `ai.max_tokens` | number | No | Max completion tokens per request (>0) |
|
|
960
976
|
|
|
961
977
|
---
|
|
962
978
|
|
|
@@ -986,6 +1002,13 @@ Optional for Discord notifications:
|
|
|
986
1002
|
|----------|----------|-------------|
|
|
987
1003
|
| `DISCORD_WEBHOOK_URL` | No | Discord webhook URL for team notifications |
|
|
988
1004
|
|
|
1005
|
+
Required for GitHub Wiki publisher:
|
|
1006
|
+
|
|
1007
|
+
| Variable | Required | Description |
|
|
1008
|
+
|----------|----------|-------------|
|
|
1009
|
+
| `GITHUB_TOKEN` | Yes | Personal access token or Actions `${{ secrets.GITHUB_TOKEN }}` |
|
|
1010
|
+
| `GITHUB_REPOSITORY` | No | `owner/repo` (auto-detected from git remote in Actions) |
|
|
1011
|
+
|
|
989
1012
|
**Local Development:** Create `.env` file in project root
|
|
990
1013
|
**GitHub Actions:** Add as repository secrets in Settings → Secrets and variables → Actions
|
|
991
1014
|
|
|
@@ -1070,7 +1093,7 @@ npm test
|
|
|
1070
1093
|
- Integration workflows
|
|
1071
1094
|
- Doctor command validation
|
|
1072
1095
|
|
|
1073
|
-
**Coverage:**
|
|
1096
|
+
**Coverage:** 180 tests passing across 15 test files
|
|
1074
1097
|
|
|
1075
1098
|
### Test Package Installation Locally
|
|
1076
1099
|
|
|
@@ -1081,7 +1104,7 @@ Simulates the full user installation experience:
|
|
|
1081
1104
|
npm pack
|
|
1082
1105
|
|
|
1083
1106
|
# Install globally from tarball
|
|
1084
|
-
npm install -g chappibunny-repolens-0.
|
|
1107
|
+
npm install -g chappibunny-repolens-1.0.0.tgz
|
|
1085
1108
|
|
|
1086
1109
|
# Verify
|
|
1087
1110
|
repolens --version
|
|
@@ -1130,11 +1153,15 @@ repolens/
|
|
|
1130
1153
|
│ │ ├── publish.js # Publishing pipeline
|
|
1131
1154
|
│ │ ├── notion.js # Notion API integration
|
|
1132
1155
|
│ │ ├── confluence.js # Confluence REST API integration
|
|
1156
|
+
│ │ ├── github-wiki.js # GitHub Wiki publisher (git-based)
|
|
1133
1157
|
│ │ └── markdown.js # Local Markdown generation
|
|
1134
1158
|
│ ├── integrations/
|
|
1135
1159
|
│ │ └── discord.js # Discord webhook notifications
|
|
1136
1160
|
│ ├── delivery/
|
|
1137
1161
|
│ │ └── comment.js # PR comment delivery
|
|
1162
|
+
│ ├── plugins/
|
|
1163
|
+
│ │ ├── loader.js # Plugin resolution and dynamic import
|
|
1164
|
+
│ │ └── manager.js # Plugin registry and lifecycle orchestration
|
|
1138
1165
|
│ └── utils/
|
|
1139
1166
|
│ ├── logger.js # Logging utilities
|
|
1140
1167
|
│ ├── retry.js # API retry logic (exponential backoff)
|
|
@@ -1146,10 +1173,11 @@ repolens/
|
|
|
1146
1173
|
│ ├── telemetry.js # Opt-in error tracking + performance timers
|
|
1147
1174
|
│ ├── errors.js # Enhanced error messages with guidance
|
|
1148
1175
|
│ └── update-check.js # Version update notifications
|
|
1149
|
-
├── tests/ # Vitest test suite (
|
|
1176
|
+
├── tests/ # Vitest test suite (180 tests across 15 files)
|
|
1150
1177
|
├── .repolens.yml # Dogfooding config
|
|
1151
1178
|
├── package.json
|
|
1152
1179
|
├── CHANGELOG.md
|
|
1180
|
+
├── STABILITY.md
|
|
1153
1181
|
├── RELEASE.md
|
|
1154
1182
|
└── ROADMAP.md
|
|
1155
1183
|
```
|
|
@@ -1163,13 +1191,13 @@ RepoLens uses automated GitHub Actions releases.
|
|
|
1163
1191
|
### Creating a Release
|
|
1164
1192
|
|
|
1165
1193
|
```bash
|
|
1166
|
-
# Patch version (0.
|
|
1194
|
+
# Patch version (1.0.0 → 1.0.1) - Bug fixes
|
|
1167
1195
|
npm run release:patch
|
|
1168
1196
|
|
|
1169
|
-
# Minor version (0.
|
|
1197
|
+
# Minor version (1.0.0 → 1.1.0) - New features
|
|
1170
1198
|
npm run release:minor
|
|
1171
1199
|
|
|
1172
|
-
# Major version (0.
|
|
1200
|
+
# Major version (1.0.0 → 2.0.0) - Breaking changes
|
|
1173
1201
|
npm run release:major
|
|
1174
1202
|
|
|
1175
1203
|
# Push the tag to trigger workflow
|
|
@@ -1189,26 +1217,25 @@ See [RELEASE.md](./RELEASE.md) for detailed workflow.
|
|
|
1189
1217
|
|
|
1190
1218
|
## 🤝 Contributing
|
|
1191
1219
|
|
|
1192
|
-
RepoLens is currently in early access. v1.0 will open for community contributions.
|
|
1193
|
-
|
|
1194
1220
|
**Ways to help:**
|
|
1195
1221
|
- **Try it out**: Install and use in your projects
|
|
1196
1222
|
- **Report issues**: Share bugs, edge cases, or UX friction
|
|
1197
1223
|
- **Request features**: Tell us what's missing
|
|
1198
|
-
- **
|
|
1224
|
+
- **Build plugins**: Extend RepoLens with custom renderers and publishers
|
|
1225
|
+
- **Share feedback**: `repolens feedback`
|
|
1199
1226
|
|
|
1200
1227
|
---
|
|
1201
1228
|
|
|
1202
|
-
## 🗺️ Roadmap
|
|
1229
|
+
## 🗺️ Roadmap
|
|
1203
1230
|
|
|
1204
|
-
**Current Status:**
|
|
1231
|
+
**Current Status:** v1.0.0 — Stable Release
|
|
1205
1232
|
|
|
1206
|
-
###
|
|
1233
|
+
### v1.0 — Complete ✅
|
|
1207
1234
|
|
|
1208
1235
|
- [x] CLI commands: `init`, `doctor`, `publish`, `migrate`, `watch`, `feedback`, `version`, `help`
|
|
1209
|
-
- [x] Config schema v1 with validation
|
|
1236
|
+
- [x] Config schema v1 with validation (frozen)
|
|
1210
1237
|
- [x] Auto-discovery of `.repolens.yml`
|
|
1211
|
-
- [x] Publishers: Notion + Confluence + Markdown
|
|
1238
|
+
- [x] Publishers: Notion + Confluence + GitHub Wiki + Markdown
|
|
1212
1239
|
- [x] Branch-aware publishing with filtering
|
|
1213
1240
|
- [x] Smart tech stack detection from package.json
|
|
1214
1241
|
- [x] Unicode dependency diagrams (no external deps)
|
|
@@ -1217,7 +1244,7 @@ RepoLens is currently in early access. v1.0 will open for community contribution
|
|
|
1217
1244
|
- [x] GitHub Actions automation (publish + release)
|
|
1218
1245
|
- [x] PR architecture diff comments
|
|
1219
1246
|
- [x] Performance guardrails (10k warning, 50k limit)
|
|
1220
|
-
- [x] Comprehensive test suite (
|
|
1247
|
+
- [x] Comprehensive test suite (180 tests across 15 files)
|
|
1221
1248
|
- [x] Security hardening (secret detection, injection prevention, fuzzing)
|
|
1222
1249
|
- [x] Discord notifications with rich embeds
|
|
1223
1250
|
- [x] Documentation coverage & health scoring
|
|
@@ -1235,11 +1262,14 @@ RepoLens is currently in early access. v1.0 will open for community contribution
|
|
|
1235
1262
|
- [x] Dependency graph with circular dependency detection
|
|
1236
1263
|
- [x] Architecture drift detection (baseline comparison)
|
|
1237
1264
|
- [x] Plugin system for custom renderers and publishers
|
|
1265
|
+
- [x] Stability audit: CLI, config schema, and plugin interface frozen
|
|
1266
|
+
- [x] [STABILITY.md](STABILITY.md): Public API contract with semver guarantees
|
|
1238
1267
|
|
|
1239
|
-
###
|
|
1268
|
+
### Future
|
|
1240
1269
|
|
|
1241
|
-
- [ ]
|
|
1242
|
-
- [ ]
|
|
1270
|
+
- [ ] Additional publishers (Obsidian)
|
|
1271
|
+
- [ ] VS Code extension
|
|
1272
|
+
- [ ] GitHub App
|
|
1243
1273
|
|
|
1244
1274
|
See [ROADMAP.md](./ROADMAP.md) for detailed planning.
|
|
1245
1275
|
|
package/package.json
CHANGED
|
@@ -25,7 +25,6 @@ export async function generateExecutiveSummary(context) {
|
|
|
25
25
|
const result = await generateText({
|
|
26
26
|
system: SYSTEM_PROMPT,
|
|
27
27
|
user: createExecutiveSummaryPrompt(context),
|
|
28
|
-
temperature: 0.2,
|
|
29
28
|
maxTokens: 1500
|
|
30
29
|
});
|
|
31
30
|
|
|
@@ -47,7 +46,6 @@ export async function generateSystemOverview(context) {
|
|
|
47
46
|
const result = await generateText({
|
|
48
47
|
system: SYSTEM_PROMPT,
|
|
49
48
|
user: createSystemOverviewPrompt(context),
|
|
50
|
-
temperature: 0.2,
|
|
51
49
|
maxTokens: 1200
|
|
52
50
|
});
|
|
53
51
|
|
|
@@ -68,7 +66,6 @@ export async function generateBusinessDomains(context) {
|
|
|
68
66
|
const result = await generateText({
|
|
69
67
|
system: SYSTEM_PROMPT,
|
|
70
68
|
user: createBusinessDomainsPrompt(context),
|
|
71
|
-
temperature: 0.2,
|
|
72
69
|
maxTokens: 2000
|
|
73
70
|
});
|
|
74
71
|
|
|
@@ -89,7 +86,6 @@ export async function generateArchitectureOverview(context) {
|
|
|
89
86
|
const result = await generateText({
|
|
90
87
|
system: SYSTEM_PROMPT,
|
|
91
88
|
user: createArchitectureOverviewPrompt(context),
|
|
92
|
-
temperature: 0.2,
|
|
93
89
|
maxTokens: 1800
|
|
94
90
|
});
|
|
95
91
|
|
|
@@ -110,7 +106,6 @@ export async function generateDataFlows(flows, context) {
|
|
|
110
106
|
const result = await generateText({
|
|
111
107
|
system: SYSTEM_PROMPT,
|
|
112
108
|
user: createDataFlowsPrompt(flows, context),
|
|
113
|
-
temperature: 0.2,
|
|
114
109
|
maxTokens: 1800
|
|
115
110
|
});
|
|
116
111
|
|
|
@@ -131,7 +126,6 @@ export async function generateDeveloperOnboarding(context) {
|
|
|
131
126
|
const result = await generateText({
|
|
132
127
|
system: SYSTEM_PROMPT,
|
|
133
128
|
user: createDeveloperOnboardingPrompt(context),
|
|
134
|
-
temperature: 0.2,
|
|
135
129
|
maxTokens: 2200
|
|
136
130
|
});
|
|
137
131
|
|
package/src/ai/provider.js
CHANGED
|
@@ -4,12 +4,12 @@ import { warn, info } from "../utils/logger.js";
|
|
|
4
4
|
import { executeAIRequest } from "../utils/rate-limit.js";
|
|
5
5
|
|
|
6
6
|
const DEFAULT_TIMEOUT_MS = 60000;
|
|
7
|
-
const DEFAULT_TEMPERATURE = 0.2;
|
|
8
7
|
const DEFAULT_MAX_TOKENS = 2500;
|
|
9
8
|
|
|
10
|
-
export async function generateText({ system, user, temperature, maxTokens }) {
|
|
11
|
-
// Check if AI is enabled
|
|
12
|
-
const
|
|
9
|
+
export async function generateText({ system, user, temperature, maxTokens, config }) {
|
|
10
|
+
// Check if AI is enabled (env var takes precedence, then config)
|
|
11
|
+
const aiConfig = config?.ai || {};
|
|
12
|
+
const enabled = process.env.REPOLENS_AI_ENABLED === "true" || aiConfig.enabled === true;
|
|
13
13
|
|
|
14
14
|
if (!enabled) {
|
|
15
15
|
return {
|
|
@@ -19,13 +19,17 @@ export async function generateText({ system, user, temperature, maxTokens }) {
|
|
|
19
19
|
};
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
// Get provider configuration
|
|
22
|
+
// Get provider configuration (env vars take precedence, then config, then defaults)
|
|
23
23
|
const provider = process.env.REPOLENS_AI_PROVIDER || "openai_compatible";
|
|
24
24
|
const baseUrl = process.env.REPOLENS_AI_BASE_URL;
|
|
25
25
|
const apiKey = process.env.REPOLENS_AI_API_KEY;
|
|
26
|
-
const model = process.env.REPOLENS_AI_MODEL || "gpt-
|
|
26
|
+
const model = process.env.REPOLENS_AI_MODEL || "gpt-5-mini";
|
|
27
27
|
const timeoutMs = parseInt(process.env.REPOLENS_AI_TIMEOUT_MS || DEFAULT_TIMEOUT_MS);
|
|
28
28
|
|
|
29
|
+
// Use config values as fallback for maxTokens; temperature only when explicitly set
|
|
30
|
+
const resolvedTemp = temperature ?? aiConfig.temperature ?? undefined;
|
|
31
|
+
const resolvedMaxTokens = maxTokens ?? aiConfig.max_tokens ?? DEFAULT_MAX_TOKENS;
|
|
32
|
+
|
|
29
33
|
// Validate configuration
|
|
30
34
|
if (!apiKey) {
|
|
31
35
|
warn("REPOLENS_AI_API_KEY not set. AI features disabled.");
|
|
@@ -47,8 +51,8 @@ export async function generateText({ system, user, temperature, maxTokens }) {
|
|
|
47
51
|
model,
|
|
48
52
|
system,
|
|
49
53
|
user,
|
|
50
|
-
temperature:
|
|
51
|
-
maxTokens:
|
|
54
|
+
temperature: resolvedTemp,
|
|
55
|
+
maxTokens: resolvedMaxTokens,
|
|
52
56
|
timeoutMs
|
|
53
57
|
});
|
|
54
58
|
|
|
@@ -76,21 +80,28 @@ async function callOpenAICompatibleAPI({ baseUrl, apiKey, model, system, user, t
|
|
|
76
80
|
const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
|
|
77
81
|
|
|
78
82
|
try {
|
|
83
|
+
// Build request body — omit temperature if not supported by model
|
|
84
|
+
const body = {
|
|
85
|
+
model,
|
|
86
|
+
messages: [
|
|
87
|
+
{ role: "system", content: system },
|
|
88
|
+
{ role: "user", content: user }
|
|
89
|
+
],
|
|
90
|
+
max_completion_tokens: maxTokens
|
|
91
|
+
};
|
|
92
|
+
// Only send temperature when explicitly configured — some models
|
|
93
|
+
// (e.g. gpt-5-mini) reject any non-default value
|
|
94
|
+
if (temperature != null) {
|
|
95
|
+
body.temperature = temperature;
|
|
96
|
+
}
|
|
97
|
+
|
|
79
98
|
const response = await fetch(url, {
|
|
80
99
|
method: "POST",
|
|
81
100
|
headers: {
|
|
82
101
|
"Content-Type": "application/json",
|
|
83
102
|
"Authorization": `Bearer ${apiKey}`
|
|
84
103
|
},
|
|
85
|
-
body: JSON.stringify(
|
|
86
|
-
model,
|
|
87
|
-
messages: [
|
|
88
|
-
{ role: "system", content: system },
|
|
89
|
-
{ role: "user", content: user }
|
|
90
|
-
],
|
|
91
|
-
temperature,
|
|
92
|
-
max_tokens: maxTokens
|
|
93
|
-
}),
|
|
104
|
+
body: JSON.stringify(body),
|
|
94
105
|
signal: controller.signal
|
|
95
106
|
});
|
|
96
107
|
|
|
@@ -129,9 +140,9 @@ export function getAIConfig() {
|
|
|
129
140
|
return {
|
|
130
141
|
enabled: isAIEnabled(),
|
|
131
142
|
provider: process.env.REPOLENS_AI_PROVIDER || "openai_compatible",
|
|
132
|
-
model: process.env.REPOLENS_AI_MODEL || "gpt-
|
|
143
|
+
model: process.env.REPOLENS_AI_MODEL || "gpt-5-mini",
|
|
133
144
|
hasApiKey: !!process.env.REPOLENS_AI_API_KEY,
|
|
134
|
-
temperature: parseFloat(process.env.REPOLENS_AI_TEMPERATURE
|
|
145
|
+
temperature: process.env.REPOLENS_AI_TEMPERATURE ? parseFloat(process.env.REPOLENS_AI_TEMPERATURE) : undefined,
|
|
135
146
|
maxTokens: parseInt(process.env.REPOLENS_AI_MAX_TOKENS || DEFAULT_MAX_TOKENS)
|
|
136
147
|
};
|
|
137
148
|
}
|
package/src/cli.js
CHANGED
|
@@ -41,6 +41,11 @@ import {
|
|
|
41
41
|
} from "./utils/telemetry.js";
|
|
42
42
|
import { createInterface } from "node:readline";
|
|
43
43
|
|
|
44
|
+
// Standardized exit codes
|
|
45
|
+
const EXIT_SUCCESS = 0;
|
|
46
|
+
const EXIT_ERROR = 1;
|
|
47
|
+
const EXIT_VALIDATION = 2;
|
|
48
|
+
|
|
44
49
|
function formatDuration(ms) {
|
|
45
50
|
if (ms < 1000) return `${ms}ms`;
|
|
46
51
|
return `${(ms / 1000).toFixed(1)}s`;
|
|
@@ -136,7 +141,7 @@ Usage:
|
|
|
136
141
|
Commands:
|
|
137
142
|
init Scaffold RepoLens files in your repository
|
|
138
143
|
doctor Validate your RepoLens setup
|
|
139
|
-
migrate Upgrade workflow files to
|
|
144
|
+
migrate Upgrade workflow files to current format
|
|
140
145
|
publish Scan, render, and publish documentation
|
|
141
146
|
watch Watch for file changes and regenerate docs
|
|
142
147
|
feedback Send feedback to the RepoLens team
|
|
@@ -213,7 +218,7 @@ async function main() {
|
|
|
213
218
|
error("Failed to initialize RepoLens:");
|
|
214
219
|
error(err.message);
|
|
215
220
|
await closeTelemetry();
|
|
216
|
-
process.exit(
|
|
221
|
+
process.exit(EXIT_ERROR);
|
|
217
222
|
}
|
|
218
223
|
return;
|
|
219
224
|
}
|
|
@@ -225,10 +230,16 @@ async function main() {
|
|
|
225
230
|
|
|
226
231
|
const timer = startTimer("doctor");
|
|
227
232
|
try {
|
|
228
|
-
await runDoctor(targetDir);
|
|
233
|
+
const result = await runDoctor(targetDir);
|
|
229
234
|
const duration = stopTimer(timer);
|
|
230
|
-
info("✓ RepoLens validation passed");
|
|
231
235
|
|
|
236
|
+
if (result && result.ok === false) {
|
|
237
|
+
trackUsage("doctor", "failure", { duration });
|
|
238
|
+
await closeTelemetry();
|
|
239
|
+
process.exit(EXIT_VALIDATION);
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
info("✓ RepoLens validation passed");
|
|
232
243
|
trackUsage("doctor", "success", { duration });
|
|
233
244
|
await closeTelemetry();
|
|
234
245
|
} catch (err) {
|
|
@@ -238,7 +249,7 @@ async function main() {
|
|
|
238
249
|
error("Validation failed:");
|
|
239
250
|
error(err.message);
|
|
240
251
|
await closeTelemetry();
|
|
241
|
-
process.exit(
|
|
252
|
+
process.exit(EXIT_VALIDATION);
|
|
242
253
|
}
|
|
243
254
|
return;
|
|
244
255
|
}
|
|
@@ -267,7 +278,7 @@ async function main() {
|
|
|
267
278
|
error("Migration failed:");
|
|
268
279
|
error(err.message);
|
|
269
280
|
await closeTelemetry();
|
|
270
|
-
process.exit(
|
|
281
|
+
process.exit(EXIT_ERROR);
|
|
271
282
|
}
|
|
272
283
|
return;
|
|
273
284
|
}
|
|
@@ -280,13 +291,20 @@ async function main() {
|
|
|
280
291
|
info(`Using config: ${configPath}`);
|
|
281
292
|
} catch (err) {
|
|
282
293
|
error(err.message);
|
|
283
|
-
process.exit(
|
|
294
|
+
process.exit(EXIT_VALIDATION);
|
|
284
295
|
}
|
|
285
296
|
await runWatch(configPath);
|
|
286
297
|
return;
|
|
287
298
|
}
|
|
288
299
|
|
|
289
|
-
|
|
300
|
+
// Reject unknown flags/commands before falling through to publish
|
|
301
|
+
if (command && command.startsWith("--") && !["--help", "-h", "--version", "-v"].includes(command)) {
|
|
302
|
+
error(`Unknown option: ${command}`);
|
|
303
|
+
error("Run 'repolens help' for usage information.");
|
|
304
|
+
process.exit(EXIT_ERROR);
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
if (command === "publish" || !command) {
|
|
290
308
|
await printBanner();
|
|
291
309
|
|
|
292
310
|
const commandTimer = startTimer("publish");
|
|
@@ -299,7 +317,7 @@ async function main() {
|
|
|
299
317
|
} catch (err) {
|
|
300
318
|
stopTimer(commandTimer);
|
|
301
319
|
error(err.message);
|
|
302
|
-
process.exit(
|
|
320
|
+
process.exit(EXIT_VALIDATION);
|
|
303
321
|
}
|
|
304
322
|
|
|
305
323
|
let cfg, scan;
|
|
@@ -312,7 +330,7 @@ async function main() {
|
|
|
312
330
|
trackUsage("publish", "failure", { step: "config-load" });
|
|
313
331
|
error(formatError("CONFIG_VALIDATION_FAILED", err));
|
|
314
332
|
await closeTelemetry();
|
|
315
|
-
process.exit(
|
|
333
|
+
process.exit(EXIT_VALIDATION);
|
|
316
334
|
}
|
|
317
335
|
|
|
318
336
|
// Load plugins
|
|
@@ -342,7 +360,7 @@ async function main() {
|
|
|
342
360
|
: err.message?.includes("limit") ? "SCAN_TOO_MANY_FILES" : null;
|
|
343
361
|
error(code ? formatError(code, err) : `Failed to scan repository:\n ${err.message}`);
|
|
344
362
|
await closeTelemetry();
|
|
345
|
-
process.exit(
|
|
363
|
+
process.exit(EXIT_ERROR);
|
|
346
364
|
}
|
|
347
365
|
|
|
348
366
|
const rawDiff = getGitDiff("origin/main");
|
|
@@ -399,7 +417,7 @@ async function main() {
|
|
|
399
417
|
error("Failed to publish documentation:");
|
|
400
418
|
error(err.message);
|
|
401
419
|
await closeTelemetry();
|
|
402
|
-
process.exit(
|
|
420
|
+
process.exit(EXIT_ERROR);
|
|
403
421
|
}
|
|
404
422
|
|
|
405
423
|
await closeTelemetry();
|
|
@@ -423,7 +441,7 @@ async function main() {
|
|
|
423
441
|
if (!message.trim()) {
|
|
424
442
|
error("Feedback message cannot be empty.");
|
|
425
443
|
await closeTelemetry();
|
|
426
|
-
process.exit(
|
|
444
|
+
process.exit(EXIT_ERROR);
|
|
427
445
|
}
|
|
428
446
|
|
|
429
447
|
info("\nSending feedback...");
|
|
@@ -437,6 +455,8 @@ async function main() {
|
|
|
437
455
|
info("✓ Thank you! Your feedback has been sent.");
|
|
438
456
|
} else {
|
|
439
457
|
error("Failed to send feedback. Please try again later.");
|
|
458
|
+
await closeTelemetry();
|
|
459
|
+
process.exit(EXIT_ERROR);
|
|
440
460
|
}
|
|
441
461
|
} catch (err) {
|
|
442
462
|
rl.close();
|
|
@@ -451,7 +471,7 @@ async function main() {
|
|
|
451
471
|
|
|
452
472
|
error(`Unknown command: ${command}`);
|
|
453
473
|
error("Available commands: init, doctor, migrate, publish, watch, feedback, version, help");
|
|
454
|
-
process.exit(
|
|
474
|
+
process.exit(EXIT_ERROR);
|
|
455
475
|
}
|
|
456
476
|
|
|
457
477
|
main().catch(async (err) => {
|
|
@@ -481,5 +501,5 @@ main().catch(async (err) => {
|
|
|
481
501
|
}
|
|
482
502
|
|
|
483
503
|
await closeTelemetry();
|
|
484
|
-
process.exit(
|
|
504
|
+
process.exit(EXIT_ERROR);
|
|
485
505
|
});
|