@relipa/ai-flow-kit 0.0.6-beta.0 → 0.0.7-beta.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/README.md +33 -13
- package/bin/aiflow.js +58 -2
- package/custom/mcp-presets/gitnexus.json +8 -0
- package/custom/rules/java/spring-boot-examples.md +329 -329
- package/custom/skills/generate-spec/SKILL.md +7 -0
- package/custom/skills/impact-analysis/SKILL.md +10 -0
- package/custom/skills/read-study-requirement/SKILL.md +11 -0
- package/custom/skills/review-plan/SKILL.md +15 -0
- package/custom/templates/spring-boot.md +224 -224
- package/docs/common/AIFLOW.md +12 -6
- package/docs/common/CHANGELOG.md +49 -5
- package/docs/common/QUICK_START.md +13 -11
- package/docs/common/cli-reference.md +23 -0
- package/package.json +2 -7
- package/scripts/checkpoint.js +46 -0
- package/scripts/doctor.js +192 -89
- package/scripts/gitnexus-worker.js +94 -0
- package/scripts/guide.js +42 -51
- package/scripts/hooks/session-start.js +274 -244
- package/scripts/hooks/session-stop.js +55 -0
- package/scripts/init.js +293 -18
- package/scripts/prompt.js +2 -2
- package/scripts/remove.js +54 -0
- package/scripts/task.js +446 -384
- package/scripts/update.js +14 -4
- package/scripts/use.js +41 -0
- package/upstream/.claude-plugin/marketplace.json +4 -4
- package/upstream/.claude-plugin/plugin.json +2 -4
- package/upstream/.cursor-plugin/plugin.json +2 -4
- package/upstream/docs/plans/2025-11-22-opencode-support-design.md +1 -1
- package/upstream/docs/plans/2025-11-28-skills-improvements-from-user-feedback.md +2 -2
- package/upstream/docs/testing.md +2 -2
- package/upstream/skills/subagent-driven-development/SKILL.md +5 -6
- package/upstream/skills/subagent-driven-development/implementer-prompt.md +2 -3
- package/upstream/skills/systematic-debugging/CREATION-LOG.md +1 -1
- package/upstream/skills/systematic-debugging/root-cause-tracing.md +1 -1
- package/upstream/skills/tdd-lean/SKILL.md +127 -0
- package/upstream/skills/using-git-worktrees/SKILL.md +4 -5
- package/upstream/skills/writing-plans/SKILL.md +3 -9
- package/upstream/tests/brainstorm-server/package-lock.json +36 -0
package/docs/common/CHANGELOG.md
CHANGED
|
@@ -1,15 +1,42 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
All notable changes to
|
|
3
|
+
All notable changes to **ai-flow-kit** will be documented in this file.
|
|
4
4
|
|
|
5
5
|
Format follows [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
|
6
6
|
Versioning follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
8
|
---
|
|
9
9
|
|
|
10
|
+
## [0.0.7] - 2026-05-07
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- **Intelligent AI Instruction Synchronization** — Marker-based (`<!-- aiflow-kit-start -->`) block updates for `CLAUDE.md`, `GEMINI.md`, and `.cursorrules`.
|
|
15
|
+
- **Interactive Instruction Safety** — Granular confirmation prompts for all instruction file modifications (update block, overwrite, or create new).
|
|
16
|
+
- **Automated Repository Hygiene** — Generated files and folders (`.aiflow/`, `plan/`, `.claude/`, `.rules/`, `.mcp.json`, and instruction files) are now automatically managed in `.gitignore`.
|
|
17
|
+
- **`aiflow sync-skills` command** — Lightweight command to synchronize Skill Registry and Instruction files without a full version upgrade.
|
|
18
|
+
- **Enhanced `aiflow guide --flow`** — Now dynamically displays the `## Workflow Overview` section directly from `AIFLOW.md` for up-to-date documentation.
|
|
19
|
+
- **Token savings dashboard in `aiflow doctor`** — new "Token savings" section shows RTK status and estimated 60–90% reduction on bash outputs.
|
|
20
|
+
|
|
21
|
+
### Changed
|
|
22
|
+
|
|
23
|
+
- **`aiflow update` efficiency** — Now automatically performs skill and instruction synchronization even if the version is unchanged (removes the need for `--force`).
|
|
24
|
+
- **Safety First Development** — Removed all automatic `git commit` instructions from AI skills (`subagent-driven-development`, `using-git-worktrees`, `writing-plans`) to ensure developer-led commit management.
|
|
25
|
+
- **Localized CLI** — All interactive prompts and confirmation messages translated to English for consistency.
|
|
26
|
+
- **`aiflow init` RTK entry** — flag description updated to clarify RTK saves bash output tokens (60–90%).
|
|
27
|
+
- **`aiflow doctor`** — RTK section merged into new "Token savings" section.
|
|
28
|
+
- **README.md / QUICK_START.md** — Updated to reflect `sync-skills` and improved update flow.
|
|
29
|
+
|
|
30
|
+
### Fixed
|
|
31
|
+
|
|
32
|
+
- Fixed `.github/copilot-instructions.md` not being included in automated `.gitignore` rules.
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
10
36
|
## [0.0.6] - 2026-04-29
|
|
11
37
|
|
|
12
38
|
### Added
|
|
39
|
+
|
|
13
40
|
- **Global Fast Mode (Default)** — Optimize AI efficiency by prioritizing speed and minimizing token usage.
|
|
14
41
|
- Gate 1: Fast track scan with max 1 clarifying question.
|
|
15
42
|
- Gate 3: Disable subagents by default; implement all tasks in a single session.
|
|
@@ -25,6 +52,7 @@ Versioning follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
|
25
52
|
- **Spring Boot code examples extracted** — Java code examples moved to separate files to reduce `CLAUDE.md` size.
|
|
26
53
|
|
|
27
54
|
### Changed
|
|
55
|
+
|
|
28
56
|
- **Default mode** for all new tasks is now `fast` instead of `auto`.
|
|
29
57
|
- **`aiflow init` improvements** — Supports multi-select framework and protects existing instruction files from being overwritten.
|
|
30
58
|
- **CLAUDE.md Optimization** — Reduced Spring Boot template size by ~70%, saving ~3-5k tokens per session.
|
|
@@ -32,18 +60,20 @@ Versioning follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
|
32
60
|
- **Automatic Task Pausing** — When loading a new ticket, the current task is automatically paused and its state is saved.
|
|
33
61
|
|
|
34
62
|
### Fixed
|
|
35
|
-
- Broken 404 documentation links on the npmjs.com page.
|
|
36
63
|
|
|
64
|
+
- Broken 404 documentation links on the npmjs.com page.
|
|
37
65
|
|
|
38
66
|
---
|
|
39
67
|
|
|
40
68
|
## [0.0.4-beta.5] - 2026-04-21
|
|
41
69
|
|
|
42
70
|
### Added
|
|
71
|
+
|
|
43
72
|
- Created a dedicated `docs/` folder to house all developer-facing documentation.
|
|
44
73
|
- Integrated AI Skill Registry into all tool templates (Claude, Cursor, Gemini, Copilot) for better skill discovery.
|
|
45
74
|
|
|
46
75
|
### Changed
|
|
76
|
+
|
|
47
77
|
- Moved `README.md`, `QUICK_START.md`, `AIFLOW.md`, `CHANGELOG.md`, and `IMPLEMENTATION_SUMMARY.md` into the `docs/` directory.
|
|
48
78
|
- Updated `package.json` to exclude internal-only files (`CONTRIBUTING.md`, `plan.md`) from the NPM package distribution.
|
|
49
79
|
- Updated `scripts/init.js` to source documentation from the new `docs/` location.
|
|
@@ -54,11 +84,13 @@ Versioning follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
|
54
84
|
## [0.0.5-beta.0] - 2026-04-23
|
|
55
85
|
|
|
56
86
|
### Added
|
|
87
|
+
|
|
57
88
|
- **`aiflow gate <n> <action>` command** — Called automatically by AI during gate transitions. Supports `start` and `approved` actions for gates 1-5. Options: `--ticket <id>`, `--ai-tool <tool>`.
|
|
58
89
|
- **Telemetry gate logging** — Gate workflow templates now emit `aiflow gate N start/approved --ticket [id]` telemetry calls at each gate transition for usage metrics.
|
|
59
90
|
- **`aiflow telemetry flush` command** — Force-sends buffered telemetry events immediately.
|
|
60
91
|
|
|
61
92
|
### Changed
|
|
93
|
+
|
|
62
94
|
- **`aiflow init` safe overwrite flow** — When a project already has `CLAUDE.md`, `GEMINI.md`, `.cursorrules`, etc., `aiflow init` now prompts before overwriting:
|
|
63
95
|
- **No (default):** keeps existing file untouched; saves the aiflow template to `.aiflow/reference/<file>` for manual comparison/merge.
|
|
64
96
|
- **Yes:** backs up the existing file to `.aiflow/backup/<file>` before overwriting — nothing is permanently lost.
|
|
@@ -73,7 +105,8 @@ Versioning follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
|
73
105
|
## [0.0.5] - 2026-04-23
|
|
74
106
|
|
|
75
107
|
### Added
|
|
76
|
-
|
|
108
|
+
|
|
109
|
+
- **Telemetry System (MVP)**: Added anonymous usage tracking to measure command metrics and user adoption.
|
|
77
110
|
- `aiflow telemetry enable/disable/status` commands to easily opt-in or opt-out.
|
|
78
111
|
- Automatically captures environment metadata and Git email via `git config --global user.email`.
|
|
79
112
|
- Secure payload signing natively using Node `crypto` HMAC-SHA256 to ensure data authenticity.
|
|
@@ -81,6 +114,7 @@ Versioning follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
|
81
114
|
- Support tracking for multiple AI platforms including Cursor and Gemini via Command Execution events and the new Telemetry SDK.
|
|
82
115
|
|
|
83
116
|
### Security
|
|
117
|
+
|
|
84
118
|
- **Strict Privacy**: Explicitly removed all prompt content and chat history tracking to ensure 100% confidentiality of company code and PII.
|
|
85
119
|
|
|
86
120
|
---
|
|
@@ -88,14 +122,18 @@ Versioning follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
|
88
122
|
## [Unreleased]
|
|
89
123
|
|
|
90
124
|
## [0.0.3-beta.0] - 2026-04-13
|
|
125
|
+
|
|
91
126
|
### Security
|
|
127
|
+
|
|
92
128
|
- Removed internal GitLab repository links and tracking information.
|
|
93
129
|
- Cleaned `.npmrc` configuration.
|
|
94
130
|
- Added helper scripts for beta and stable releases.
|
|
95
131
|
|
|
96
132
|
## [0.0.2] - 2026-04-13
|
|
133
|
+
|
|
97
134
|
### Changed
|
|
98
|
-
|
|
135
|
+
|
|
136
|
+
- Updated package name in documentation and configuration.
|
|
99
137
|
- Fixed installation guides in README and QUICK_START.
|
|
100
138
|
|
|
101
139
|
## [0.0.1] - 2026-04-13 — Initial Release
|
|
@@ -103,6 +141,7 @@ Versioning follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
|
103
141
|
### Added
|
|
104
142
|
|
|
105
143
|
#### CLI (`aiflow`)
|
|
144
|
+
|
|
106
145
|
- `aiflow init` — scaffold AI workflow config into any project
|
|
107
146
|
(supports `--framework` spring-boot/reactjs, `--adapter` jira/backlog)
|
|
108
147
|
- `aiflow use <skill>` — activate a custom skill in the current project
|
|
@@ -113,6 +152,7 @@ Versioning follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
|
113
152
|
- `aiflow --version` — print installed version
|
|
114
153
|
|
|
115
154
|
#### 5-Gate AI Workflow
|
|
155
|
+
|
|
116
156
|
- **Gate 1 — AI Analyze Requirement**: Auto-starts when a ticket context exists
|
|
117
157
|
in `.aiflow/context/current.json`; outputs `plan/[ticket-id]/requirement.md`
|
|
118
158
|
- **Gate 2 — Implementation Plan**: TDD plan generation, gated by `APPROVED`
|
|
@@ -121,6 +161,7 @@ Versioning follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
|
121
161
|
- **Gate 5 — Peer Review & PR**: Guided PR creation via `requesting-code-review` skill
|
|
122
162
|
|
|
123
163
|
#### Custom Skills (7 skills)
|
|
164
|
+
|
|
124
165
|
- `read-study-requirement` — Gate 1 requirement analysis with clarifying Q&A loop
|
|
125
166
|
- `generate-spec` — Gate 2 TDD implementation spec generator
|
|
126
167
|
- `impact-analysis` — breaking-change and dependency impact assessment
|
|
@@ -130,17 +171,20 @@ Versioning follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
|
130
171
|
- `figma-to-component` — Figma design → UI component code generator
|
|
131
172
|
|
|
132
173
|
#### Multi-AI Support
|
|
174
|
+
|
|
133
175
|
- **Claude Code** integration via `CLAUDE.md` + `.claude/` directory structure
|
|
134
176
|
- **Gemini CLI** integration via `GEMINI.md`
|
|
135
177
|
- **GitHub Copilot** integration via agents config
|
|
136
178
|
- Superpowers skill library bundled as `upstream/` (pinned to v5.0.5)
|
|
137
179
|
|
|
138
180
|
#### Project Templates
|
|
181
|
+
|
|
139
182
|
- `AIFLOW.md` — team workflow reference document
|
|
140
183
|
- `QUICK_START.md` — 5-minute setup guide
|
|
141
184
|
- `.aiflowrc.json.example` — configuration file reference
|
|
142
185
|
|
|
143
186
|
### Architecture Notes
|
|
187
|
+
|
|
144
188
|
- Stateless per-ticket design — no persistent memory across sessions (planned: v0.1.x)
|
|
145
189
|
- Manual skill sync model via `aiflow use` (managed `aiflow skill` CLI planned: v0.1.x)
|
|
146
190
|
- Spring Boot (Java 17+) used as the reference framework in `CLAUDE.md` coding rules
|
|
@@ -150,7 +194,7 @@ Versioning follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
|
150
194
|
## How to upgrade
|
|
151
195
|
|
|
152
196
|
```bash
|
|
153
|
-
npm install -g
|
|
197
|
+
npm install -g ai-flow-kit@latest
|
|
154
198
|
aiflow --version
|
|
155
199
|
```
|
|
156
200
|
|
|
@@ -7,17 +7,16 @@
|
|
|
7
7
|
## Installation
|
|
8
8
|
|
|
9
9
|
```bash
|
|
10
|
-
|
|
11
|
-
npm install -g @relipa/ai-flow-kit
|
|
10
|
+
npm install -g ai-flow-kit
|
|
12
11
|
|
|
13
12
|
# Beta version (recommend for newest features)
|
|
14
|
-
npm install -g
|
|
13
|
+
npm install -g ai-flow-kit@beta
|
|
15
14
|
|
|
16
15
|
# Verification
|
|
17
16
|
aiflow --version
|
|
18
17
|
|
|
19
18
|
# Uninstall
|
|
20
|
-
npm uninstall -g
|
|
19
|
+
npm uninstall -g ai-flow-kit
|
|
21
20
|
```
|
|
22
21
|
|
|
23
22
|
---
|
|
@@ -146,7 +145,7 @@ APPROVED
|
|
|
146
145
|
|
|
147
146
|
AI outputs:
|
|
148
147
|
- TDD task breakdown (test first → implement → verify)
|
|
149
|
-
-
|
|
148
|
+
- Verification strategy (evidence before claims)
|
|
150
149
|
- Test commands
|
|
151
150
|
|
|
152
151
|
**Your action:**
|
|
@@ -166,7 +165,7 @@ APPROVED
|
|
|
166
165
|
|
|
167
166
|
- Writes tests FIRST → runs → confirms FAIL
|
|
168
167
|
- Implements code → tests PASS
|
|
169
|
-
-
|
|
168
|
+
- Verifies implementation works
|
|
170
169
|
|
|
171
170
|
**Your action:** Monitor. No action needed unless AI asks a question.
|
|
172
171
|
|
|
@@ -256,7 +255,7 @@ Developer AI Peer
|
|
|
256
255
|
│ "APPROVED" ──────────────────►│ │
|
|
257
256
|
│ │ │
|
|
258
257
|
│ GATE 3 │ Write tests → implement │
|
|
259
|
-
│ (monitor) │
|
|
258
|
+
│ (monitor) │ Verify implementation works │
|
|
260
259
|
│ │ │
|
|
261
260
|
│ ─── GATE 4 ──────────────────►│ │
|
|
262
261
|
│ │ Self-review + summary │
|
|
@@ -317,10 +316,13 @@ claude # AI auto-starts: map dependencies → ass
|
|
|
317
316
|
```bash
|
|
318
317
|
# Setup
|
|
319
318
|
aiflow init --framework nestjs --adapter backlog
|
|
320
|
-
aiflow init --framework spring-boot --with-rtk
|
|
321
|
-
aiflow init --
|
|
319
|
+
aiflow init --framework spring-boot --with-rtk # RTK: bash output compression (60–90%)
|
|
320
|
+
# aiflow init --framework spring-boot --with-gitnexus # GitNexus: waits for index to complete
|
|
321
|
+
# aiflow init --framework spring-boot --with-gitnexus --no-wait # GitNexus: index in background
|
|
322
|
+
aiflow init --no-rtk # skip RTK setup
|
|
322
323
|
aiflow doctor # health check
|
|
323
324
|
aiflow guide # multi-tool guide
|
|
325
|
+
aiflow sync-skills # manually sync AI instruction files
|
|
324
326
|
|
|
325
327
|
# Per task
|
|
326
328
|
aiflow use PROJ-33 # load context (Fast Mode, default)
|
|
@@ -366,7 +368,7 @@ aiflow guide --commands # command reference
|
|
|
366
368
|
aiflow remove # remove from project
|
|
367
369
|
aiflow remove --global # uninstall globally (npm uninstall -g)
|
|
368
370
|
aiflow remove --version 1.0.0 # remove cached version from .aiflow/
|
|
369
|
-
npm uninstall -g
|
|
371
|
+
npm uninstall -g ai-flow-kit # standard npm uninstall
|
|
370
372
|
```
|
|
371
373
|
|
|
372
374
|
---
|
|
@@ -405,7 +407,7 @@ aiflow guide
|
|
|
405
407
|
|
|
406
408
|
**`aiflow` not found:**
|
|
407
409
|
```bash
|
|
408
|
-
npm install -g
|
|
410
|
+
npm install -g ai-flow-kit
|
|
409
411
|
```
|
|
410
412
|
|
|
411
413
|
**Incorrect credentials:**
|
|
@@ -399,6 +399,29 @@ You can switch back with: aiflow use 1.0.0
|
|
|
399
399
|
✨ Update completed!
|
|
400
400
|
```
|
|
401
401
|
|
|
402
|
+
## sync-skills
|
|
403
|
+
|
|
404
|
+
Manually synchronize AI Instruction files with local custom skills.
|
|
405
|
+
|
|
406
|
+
```bash
|
|
407
|
+
# Sync AI Instruction files
|
|
408
|
+
aiflow sync-skills
|
|
409
|
+
```
|
|
410
|
+
|
|
411
|
+
**What it does:**
|
|
412
|
+
1. Reads all active local skills and upstream skills
|
|
413
|
+
2. Generates the updated AI Skill Registry table
|
|
414
|
+
3. Safely updates the AI Instruction blocks (`<!-- aiflow-kit-start -->`) in your project's `CLAUDE.md`, `GEMINI.md`, or `.cursorrules` without wiping your custom rules
|
|
415
|
+
4. If no marker blocks are found, it asks for confirmation to overwrite with the correct structure
|
|
416
|
+
|
|
417
|
+
**Example:**
|
|
418
|
+
```bash
|
|
419
|
+
$ aiflow sync-skills
|
|
420
|
+
⟳ Syncing AI Instruction files...
|
|
421
|
+
✓ Updated AI Flow block in CLAUDE.md
|
|
422
|
+
✨ Sync completed!
|
|
423
|
+
```
|
|
424
|
+
|
|
402
425
|
## doctor
|
|
403
426
|
|
|
404
427
|
Health check for your setup.
|
package/package.json
CHANGED
|
@@ -1,13 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@relipa/ai-flow-kit",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.7-beta.0",
|
|
4
4
|
"description": "All-in-one AI Flow Kit for team development with Claude AI - skills, templates, and MCP adapters",
|
|
5
|
-
"author": "
|
|
6
|
-
"repository": {
|
|
7
|
-
"type": "git",
|
|
8
|
-
"url": "https://gitlab.relipa.vn/ai/ai-flow-kit.git"
|
|
9
|
-
},
|
|
10
|
-
"homepage": "https://gitlab.relipa.vn/ai/ai-flow-kit#readme",
|
|
5
|
+
"author": "Example Team",
|
|
11
6
|
"publishConfig": {
|
|
12
7
|
"access": "public",
|
|
13
8
|
"registry": "https://registry.npmjs.com/"
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
const fs = require('fs-extra');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const chalk = require('chalk');
|
|
4
|
+
|
|
5
|
+
const PROJECT_DIR = process.cwd();
|
|
6
|
+
const AIFLOW_DIR = path.join(PROJECT_DIR, '.aiflow');
|
|
7
|
+
const CONTEXT_FILE = path.join(AIFLOW_DIR, 'context', 'current.json');
|
|
8
|
+
|
|
9
|
+
const GATE_LABELS = { 1: 'Analyze', 2: 'Plan', 3: 'Code', 4: 'Review', 5: 'PR' };
|
|
10
|
+
|
|
11
|
+
module.exports = async function checkpoint(options = {}) {
|
|
12
|
+
const { gate, step, tokens, ticket: ticketOpt } = options;
|
|
13
|
+
|
|
14
|
+
if (!gate || !step || tokens === undefined) {
|
|
15
|
+
console.log(chalk.yellow('Usage: aiflow checkpoint --gate <N> --step <name> --tokens <N>'));
|
|
16
|
+
console.log(chalk.gray(' Example: aiflow checkpoint --gate 3 --step "tests-written" --tokens 3200'));
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// Resolve ticket ID
|
|
21
|
+
let ticketId = ticketOpt;
|
|
22
|
+
if (!ticketId) {
|
|
23
|
+
const ctx = await fs.readJson(CONTEXT_FILE).catch(() => null);
|
|
24
|
+
ticketId = ctx && ctx.taskId ? ctx.taskId : 'unknown';
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const taskDir = path.join(AIFLOW_DIR, 'tasks', ticketId);
|
|
28
|
+
await fs.ensureDir(taskDir);
|
|
29
|
+
|
|
30
|
+
const checkpointPath = path.join(taskDir, 'checkpoints.json');
|
|
31
|
+
const existing = (await fs.pathExists(checkpointPath))
|
|
32
|
+
? await fs.readJson(checkpointPath).catch(() => ({ checkpoints: [] }))
|
|
33
|
+
: { checkpoints: [] };
|
|
34
|
+
|
|
35
|
+
const entry = {
|
|
36
|
+
gate: parseInt(gate),
|
|
37
|
+
step,
|
|
38
|
+
tokens: parseInt(tokens),
|
|
39
|
+
timestamp: new Date().toISOString(),
|
|
40
|
+
};
|
|
41
|
+
existing.checkpoints.push(entry);
|
|
42
|
+
await fs.writeJson(checkpointPath, existing, { spaces: 2 });
|
|
43
|
+
|
|
44
|
+
const label = GATE_LABELS[parseInt(gate)] || `Gate ${gate}`;
|
|
45
|
+
console.log(chalk.green(`✓ Checkpoint: Gate ${gate} (${label}) — ${step} — ~${parseInt(tokens).toLocaleString()} tokens`));
|
|
46
|
+
};
|
package/scripts/doctor.js
CHANGED
|
@@ -1,89 +1,192 @@
|
|
|
1
|
-
const fs = require('fs-extra');
|
|
2
|
-
const path = require('path');
|
|
3
|
-
const chalk = require('chalk');
|
|
4
|
-
const { detectRtk, isRtkHookConfigured } = require('./init');
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
const
|
|
8
|
-
const
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
const
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
if (
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
console.log('');
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
if (
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
console.log(chalk.
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
1
|
+
const fs = require('fs-extra');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const chalk = require('chalk');
|
|
4
|
+
const { detectRtk, isRtkHookConfigured, isGitNexusConfigured } = require('./init');
|
|
5
|
+
|
|
6
|
+
function formatAgo(isoString) {
|
|
7
|
+
const ms = Date.now() - new Date(isoString).getTime();
|
|
8
|
+
const mins = Math.floor(ms / 60000);
|
|
9
|
+
if (mins < 1) return 'just now';
|
|
10
|
+
if (mins < 60) return `${mins}m ago`;
|
|
11
|
+
const hrs = Math.floor(mins / 60);
|
|
12
|
+
if (hrs < 24) return `${hrs}h ago`;
|
|
13
|
+
return `${Math.floor(hrs / 24)}d ago`;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
async function showTokenBreakdown(ticketId) {
|
|
17
|
+
const tasksDir = path.join(process.cwd(), '.aiflow', 'tasks');
|
|
18
|
+
const checkpointsFile = path.join(tasksDir, ticketId, 'checkpoints.json');
|
|
19
|
+
if (!(await fs.pathExists(checkpointsFile))) return;
|
|
20
|
+
|
|
21
|
+
const data = await fs.readJson(checkpointsFile).catch(() => ({ checkpoints: [] }));
|
|
22
|
+
if (!data.checkpoints || data.checkpoints.length === 0) return;
|
|
23
|
+
|
|
24
|
+
// Aggregate tokens per gate (taking the max/latest)
|
|
25
|
+
const gateTokens = {};
|
|
26
|
+
for (const cp of data.checkpoints) {
|
|
27
|
+
if (!gateTokens[cp.gate] || cp.tokens > gateTokens[cp.gate]) {
|
|
28
|
+
gateTokens[cp.gate] = cp.tokens;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const GATE_LABELS = { 1: 'Analyze', 2: 'Plan', 3: 'Code', 4: 'Review', 5: 'PR' };
|
|
33
|
+
const gates = Object.keys(gateTokens).sort();
|
|
34
|
+
const total = gates.reduce((sum, g) => sum + gateTokens[g], 0);
|
|
35
|
+
|
|
36
|
+
console.log('');
|
|
37
|
+
console.log(chalk.bold(`Token usage for task ${ticketId}:`));
|
|
38
|
+
for (const g of gates) {
|
|
39
|
+
const label = GATE_LABELS[parseInt(g)] || `Gate ${g}`;
|
|
40
|
+
const t = gateTokens[g];
|
|
41
|
+
const bar = '█'.repeat(Math.round((t / total) * 20)).padEnd(20, '░');
|
|
42
|
+
const pct = Math.round((t / total) * 100);
|
|
43
|
+
console.log(` Gate ${g} ${label.padEnd(8)} ~${t.toLocaleString().padStart(6)} ${chalk.gray(bar)} ${pct}%`);
|
|
44
|
+
}
|
|
45
|
+
console.log(` Total estimated: ~${total.toLocaleString()} tokens`);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
module.exports = async function doctor(options = {}) {
|
|
49
|
+
const projectDir = process.cwd();
|
|
50
|
+
const errors = [];
|
|
51
|
+
const warnings = [];
|
|
52
|
+
|
|
53
|
+
console.log(chalk.blue('Running health check for AI Flow Kit...\n'));
|
|
54
|
+
|
|
55
|
+
// ── Token breakdown ────────────────────────────────────────
|
|
56
|
+
let ticketId = options.ticket;
|
|
57
|
+
if (!ticketId) {
|
|
58
|
+
const contextFile = path.join(projectDir, '.aiflow', 'context', 'current.json');
|
|
59
|
+
if (await fs.pathExists(contextFile)) {
|
|
60
|
+
const ctx = await fs.readJson(contextFile).catch(() => ({}));
|
|
61
|
+
ticketId = ctx.taskId;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
if (ticketId) {
|
|
66
|
+
await showTokenBreakdown(ticketId);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// ── Core setup ─────────────────────────────────────────────
|
|
70
|
+
if (!(await fs.pathExists(path.join(projectDir, '.claude', 'skills')))) {
|
|
71
|
+
errors.push('Missing `.claude/skills` directory. Did you run `aiflow init`?');
|
|
72
|
+
} else {
|
|
73
|
+
console.log(chalk.green('✓ .claude/skills exists'));
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
if (!(await fs.pathExists(path.join(projectDir, '.rules')))) {
|
|
77
|
+
errors.push('Missing `.rules` directory.');
|
|
78
|
+
} else {
|
|
79
|
+
console.log(chalk.green('✓ .rules exists'));
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
if (!(await fs.pathExists(path.join(projectDir, 'CLAUDE.md')))) {
|
|
83
|
+
errors.push('Missing CLAUDE.md. AI context prompt is not set up.');
|
|
84
|
+
} else {
|
|
85
|
+
console.log(chalk.green('✓ CLAUDE.md exists'));
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// ── Version tracking ───────────────────────────────────────
|
|
89
|
+
const stateFile = path.join(projectDir, '.aiflow', 'state.json');
|
|
90
|
+
if (!(await fs.pathExists(stateFile))) {
|
|
91
|
+
errors.push('Missing `.aiflow/state.json`. Version tracking is broken.');
|
|
92
|
+
} else {
|
|
93
|
+
const state = await fs.readJson(stateFile);
|
|
94
|
+
console.log(chalk.green(`✓ Version tracking active (v${state.current_version})`));
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// ── SessionStart hook ──────────────────────────────────────
|
|
98
|
+
const settingsPath = path.join(projectDir, '.claude', 'settings.json');
|
|
99
|
+
if (await fs.pathExists(settingsPath)) {
|
|
100
|
+
const settings = await fs.readJson(settingsPath).catch(() => ({}));
|
|
101
|
+
const hookList = settings?.hooks?.SessionStart || [];
|
|
102
|
+
const hasSessionHook = hookList.some(h =>
|
|
103
|
+
(h.hooks || []).some(e => typeof e.command === 'string' && e.command.includes('session-start'))
|
|
104
|
+
);
|
|
105
|
+
if (hasSessionHook) {
|
|
106
|
+
console.log(chalk.green('✓ SessionStart hook configured'));
|
|
107
|
+
} else {
|
|
108
|
+
warnings.push('SessionStart hook not found in .claude/settings.json — run `aiflow init` to set it up.');
|
|
109
|
+
}
|
|
110
|
+
} else {
|
|
111
|
+
warnings.push('Missing .claude/settings.json — run `aiflow init`.');
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// ── Token savings tools ────────────────────────────────────
|
|
115
|
+
console.log('');
|
|
116
|
+
console.log(chalk.bold('Token savings:'));
|
|
117
|
+
|
|
118
|
+
// RTK
|
|
119
|
+
const rtk = await detectRtk();
|
|
120
|
+
if (rtk.installed) {
|
|
121
|
+
const hookOk = await isRtkHookConfigured(projectDir);
|
|
122
|
+
if (hookOk) {
|
|
123
|
+
console.log(chalk.green(` ✓ RTK (${rtk.version}) — bash output compression active`));
|
|
124
|
+
console.log(chalk.gray(' Estimated: 60–90% reduction on bash command outputs (test runs, git, npm...)'));
|
|
125
|
+
} else {
|
|
126
|
+
console.log(chalk.yellow(` ⚠ RTK installed (${rtk.version}) but hook not configured`));
|
|
127
|
+
warnings.push('RTK hook not configured. Run `aiflow init` to enable token compression.');
|
|
128
|
+
}
|
|
129
|
+
} else {
|
|
130
|
+
console.log(chalk.gray(' ○ RTK not installed — bash output compression inactive'));
|
|
131
|
+
console.log(chalk.gray(' Install: cargo install rtk | Enable: aiflow init --with-rtk'));
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// GitNexus
|
|
135
|
+
const gnConfigured = await isGitNexusConfigured(projectDir);
|
|
136
|
+
const gnStatusPath = path.join(projectDir, '.aiflow', 'gitnexus-status.json');
|
|
137
|
+
if (gnConfigured) {
|
|
138
|
+
let statusLine = chalk.green(' ✓ GitNexus MCP configured');
|
|
139
|
+
try {
|
|
140
|
+
if (await fs.pathExists(gnStatusPath)) {
|
|
141
|
+
const gn = await fs.readJson(gnStatusPath);
|
|
142
|
+
const GITNEXUS_STALE_MS = 3 * 60 * 60 * 1000; // 3 hours
|
|
143
|
+
if (gn.status === 'done') {
|
|
144
|
+
const ago = gn.completedAt
|
|
145
|
+
? chalk.gray(` — indexed ${formatAgo(gn.completedAt)}`)
|
|
146
|
+
: '';
|
|
147
|
+
statusLine = chalk.green(` ✓ GitNexus MCP configured — index ready${ago}`);
|
|
148
|
+
console.log(statusLine);
|
|
149
|
+
console.log(chalk.gray(' Estimated: ~50% fewer tokens at Gate 1 (context queries vs file reads)'));
|
|
150
|
+
console.log(chalk.gray(' Estimated: ~70% fewer tokens at Gate 4 (impact() vs grep codebase)'));
|
|
151
|
+
} else if (gn.status === 'running') {
|
|
152
|
+
const age = Date.now() - new Date(gn.startedAt).getTime();
|
|
153
|
+
if (age > GITNEXUS_STALE_MS) {
|
|
154
|
+
console.log(chalk.red(' ✗ GitNexus MCP configured — indexing timed out (stale)'));
|
|
155
|
+
console.log(chalk.gray(` Started ${formatAgo(gn.startedAt)} but never finished. Process may have crashed.`));
|
|
156
|
+
// console.log(chalk.gray(' Retry: aiflow init --with-gitnexus --wait | Log: .aiflow/gitnexus-analyze.log'));
|
|
157
|
+
} else {
|
|
158
|
+
console.log(chalk.yellow(' ⟳ GitNexus MCP configured — indexing in progress...'));
|
|
159
|
+
console.log(chalk.gray(' Log: .aiflow/gitnexus-analyze.log'));
|
|
160
|
+
}
|
|
161
|
+
} else if (gn.status === 'error') {
|
|
162
|
+
console.log(chalk.red(' ✗ GitNexus MCP configured — last index failed'));
|
|
163
|
+
console.log(chalk.gray(' Retry: npx gitnexus analyze | Log: .aiflow/gitnexus-analyze.log'));
|
|
164
|
+
}
|
|
165
|
+
} else {
|
|
166
|
+
console.log(chalk.yellow(' ⚠ GitNexus MCP configured but not yet indexed'));
|
|
167
|
+
console.log(chalk.gray(' Run: npx gitnexus analyze'));
|
|
168
|
+
}
|
|
169
|
+
} catch (_) {
|
|
170
|
+
console.log(statusLine);
|
|
171
|
+
}
|
|
172
|
+
} else {
|
|
173
|
+
console.log(chalk.gray(' ○ GitNexus not configured — code intelligence inactive'));
|
|
174
|
+
// console.log(chalk.gray(' Enable: aiflow init --with-gitnexus'));
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// ── Summary ────────────────────────────────────────────────
|
|
178
|
+
console.log('');
|
|
179
|
+
if (warnings.length > 0) {
|
|
180
|
+
console.log(chalk.yellow('Warnings:'));
|
|
181
|
+
warnings.forEach(w => console.log(chalk.yellow(` ⚠ ${w}`)));
|
|
182
|
+
console.log('');
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
if (errors.length > 0) {
|
|
186
|
+
console.log(chalk.red('Issues found:'));
|
|
187
|
+
errors.forEach(e => console.log(chalk.red(` ✗ ${e}`)));
|
|
188
|
+
console.log(chalk.yellow('\nTry running `aiflow init` or `aiflow update` to fix these files.'));
|
|
189
|
+
} else {
|
|
190
|
+
console.log(chalk.green('✨ Everything looks healthy! You are ready to fly.'));
|
|
191
|
+
}
|
|
192
|
+
};
|