@relipa/ai-flow-kit 0.1.1 → 0.1.2-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.
Files changed (253) hide show
  1. package/README.md +0 -0
  2. package/bin/aiflow.js +55 -2
  3. package/bin/ak.js +0 -0
  4. package/custom/mcp-presets/README.md +204 -237
  5. package/custom/mcp-presets/backlog.json +0 -0
  6. package/custom/mcp-presets/figma-desktop.json +0 -0
  7. package/custom/mcp-presets/figma.json +0 -0
  8. package/custom/mcp-presets/gitnexus.json +0 -0
  9. package/custom/mcp-presets/google-sheets.json +0 -0
  10. package/custom/mcp-presets/jira.json +0 -0
  11. package/custom/prompts/bug-fix.md +0 -0
  12. package/custom/prompts/feature.md +0 -0
  13. package/custom/prompts/investigation.md +0 -0
  14. package/custom/rules/code-style.md +0 -0
  15. package/custom/rules/java/code-style.md +0 -0
  16. package/custom/rules/java/naming.md +0 -0
  17. package/custom/rules/java/review-checklist.md +0 -0
  18. package/custom/rules/java/spring-boot-examples.md +0 -0
  19. package/custom/rules/javascript/code-style.md +0 -0
  20. package/custom/rules/javascript/naming.md +0 -0
  21. package/custom/rules/ml-conventions.md +88 -0
  22. package/custom/rules/ml-review-checklist.md +14 -0
  23. package/custom/rules/naming.md +0 -0
  24. package/custom/rules/php/code-style.md +0 -0
  25. package/custom/rules/php/naming.md +0 -0
  26. package/custom/rules/project-conventions.md +0 -0
  27. package/custom/rules/review-checklist.md +0 -0
  28. package/custom/skills/deploy-model/SKILL.md +90 -0
  29. package/custom/skills/design-experiment/SKILL.md +88 -0
  30. package/custom/skills/evaluate-model/SKILL.md +93 -0
  31. package/custom/skills/explore-data/SKILL.md +87 -0
  32. package/custom/skills/figma-to-component/SKILL.md +0 -0
  33. package/custom/skills/frame-ml-problem/SKILL.md +88 -0
  34. package/custom/skills/generate-spec/SKILL.md +0 -0
  35. package/custom/skills/impact-analysis/SKILL.md +0 -0
  36. package/custom/skills/improve-algorithm/SKILL.md +74 -0
  37. package/custom/skills/investigate-bug/SKILL.md +0 -0
  38. package/custom/skills/read-study-requirement/SKILL.md +0 -0
  39. package/custom/skills/report-customer/SKILL.md +0 -0
  40. package/custom/skills/review-plan/SKILL.md +0 -0
  41. package/custom/skills/train-model/SKILL.md +78 -0
  42. package/custom/templates/laravel.md +0 -0
  43. package/custom/templates/nestjs.md +0 -0
  44. package/custom/templates/nextjs.md +0 -0
  45. package/custom/templates/nodejs-express.md +0 -0
  46. package/custom/templates/php-plain.md +0 -0
  47. package/custom/templates/php.md +0 -0
  48. package/custom/templates/python-django.md +0 -0
  49. package/custom/templates/python-fastapi.md +0 -0
  50. package/custom/templates/python-ml.md +273 -0
  51. package/custom/templates/python.md +0 -0
  52. package/custom/templates/reactjs.md +0 -0
  53. package/custom/templates/shared/gate-workflow.md +0 -0
  54. package/custom/templates/shared/ml-gate-workflow.md +103 -0
  55. package/custom/templates/spring-boot.md +0 -0
  56. package/custom/templates/tools/claude.md +0 -0
  57. package/custom/templates/tools/copilot.md +0 -0
  58. package/custom/templates/tools/cursor.md +0 -0
  59. package/custom/templates/tools/gemini.md +0 -0
  60. package/custom/templates/tools/generic.md +0 -0
  61. package/custom/templates/vue-nuxt.md +0 -0
  62. package/docs/common/AIFLOW.md +512 -512
  63. package/docs/common/CHANGELOG.md +0 -0
  64. package/docs/common/QUICK_START.md +0 -0
  65. package/docs/common/ai-integration.md +0 -0
  66. package/docs/common/cli-reference.md +0 -0
  67. package/docs/common/configuration.md +0 -0
  68. package/docs/common/getting-started.md +0 -0
  69. package/docs/common/troubleshooting.md +0 -0
  70. package/docs/common/workflows/bug-fix.md +0 -0
  71. package/docs/common/workflows/feature.md +0 -0
  72. package/docs/common/workflows/figma.md +0 -0
  73. package/docs/common/workflows/impact-analysis.md +0 -0
  74. package/docs/common/workflows/investigation.md +0 -0
  75. package/docs/common/workflows/refactor.md +0 -0
  76. package/docs/project/ARCHITECTURE.md +0 -0
  77. package/index.js +0 -0
  78. package/package.json +1 -1
  79. package/scripts/checkpoint.js +0 -0
  80. package/scripts/config.js +0 -0
  81. package/scripts/context.js +0 -0
  82. package/scripts/create-score-excel.js +0 -0
  83. package/scripts/detect.js +239 -239
  84. package/scripts/doctor.js +192 -218
  85. package/scripts/gitnexus-worker.js +0 -0
  86. package/scripts/guide.js +0 -0
  87. package/scripts/hooks/block-git-write.js +0 -0
  88. package/scripts/hooks/session-start.js +0 -0
  89. package/scripts/hooks/session-stop.js +0 -0
  90. package/scripts/init.js +1112 -1009
  91. package/scripts/link-resolver.js +0 -0
  92. package/scripts/memory.js +0 -0
  93. package/scripts/prompt.js +538 -538
  94. package/scripts/remove.js +0 -0
  95. package/scripts/task.js +546 -546
  96. package/scripts/telemetry/cli.js +0 -0
  97. package/scripts/telemetry/config.js +0 -0
  98. package/scripts/telemetry/crypto.js +0 -0
  99. package/scripts/telemetry/flush.js +0 -0
  100. package/scripts/telemetry/record.js +0 -0
  101. package/scripts/update.js +10 -7
  102. package/scripts/use.js +33 -12
  103. package/scripts/validate.js +0 -0
  104. package/upstream/.claude-plugin/marketplace.json +0 -0
  105. package/upstream/.claude-plugin/plugin.json +0 -0
  106. package/upstream/.codex/INSTALL.md +0 -0
  107. package/upstream/.cursor-plugin/plugin.json +0 -0
  108. package/upstream/.gitattributes +0 -0
  109. package/upstream/.github/FUNDING.yml +0 -0
  110. package/upstream/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  111. package/upstream/.github/ISSUE_TEMPLATE/config.yml +0 -0
  112. package/upstream/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  113. package/upstream/.github/ISSUE_TEMPLATE/platform_support.md +0 -0
  114. package/upstream/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  115. package/upstream/.opencode/INSTALL.md +0 -0
  116. package/upstream/.opencode/plugins/superpowers.js +0 -0
  117. package/upstream/.version-bump.json +0 -0
  118. package/upstream/AGENTS.md +0 -0
  119. package/upstream/CHANGELOG.md +0 -0
  120. package/upstream/CLAUDE.md +0 -0
  121. package/upstream/CODE_OF_CONDUCT.md +0 -0
  122. package/upstream/GEMINI.md +0 -0
  123. package/upstream/LICENSE +0 -0
  124. package/upstream/README.md +0 -0
  125. package/upstream/RELEASE-NOTES.md +0 -0
  126. package/upstream/agents/code-reviewer.md +0 -0
  127. package/upstream/commands/brainstorm.md +0 -0
  128. package/upstream/commands/execute-plan.md +0 -0
  129. package/upstream/commands/write-plan.md +0 -0
  130. package/upstream/docs/README.codex.md +0 -0
  131. package/upstream/docs/README.opencode.md +0 -0
  132. package/upstream/docs/plans/2025-11-22-opencode-support-design.md +0 -0
  133. package/upstream/docs/plans/2025-11-22-opencode-support-implementation.md +0 -0
  134. package/upstream/docs/plans/2025-11-28-skills-improvements-from-user-feedback.md +0 -0
  135. package/upstream/docs/plans/2026-01-17-visual-brainstorming.md +0 -0
  136. package/upstream/docs/superpowers/plans/2026-01-22-document-review-system.md +0 -0
  137. package/upstream/docs/superpowers/plans/2026-02-19-visual-brainstorming-refactor.md +0 -0
  138. package/upstream/docs/superpowers/plans/2026-03-11-zero-dep-brainstorm-server.md +0 -0
  139. package/upstream/docs/superpowers/plans/2026-03-23-codex-app-compatibility.md +0 -0
  140. package/upstream/docs/superpowers/specs/2026-01-22-document-review-system-design.md +0 -0
  141. package/upstream/docs/superpowers/specs/2026-02-19-visual-brainstorming-refactor-design.md +0 -0
  142. package/upstream/docs/superpowers/specs/2026-03-11-zero-dep-brainstorm-server-design.md +0 -0
  143. package/upstream/docs/superpowers/specs/2026-03-23-codex-app-compatibility-design.md +0 -0
  144. package/upstream/docs/testing.md +0 -0
  145. package/upstream/docs/windows/polyglot-hooks.md +0 -0
  146. package/upstream/gemini-extension.json +0 -0
  147. package/upstream/hooks/hooks-cursor.json +0 -0
  148. package/upstream/hooks/hooks.json +0 -0
  149. package/upstream/hooks/run-hook.cmd +0 -0
  150. package/upstream/hooks/session-start +0 -0
  151. package/upstream/package.json +0 -0
  152. package/upstream/scripts/bump-version.sh +0 -0
  153. package/upstream/skills/brainstorming/SKILL.md +0 -0
  154. package/upstream/skills/brainstorming/scripts/frame-template.html +0 -0
  155. package/upstream/skills/brainstorming/scripts/helper.js +0 -0
  156. package/upstream/skills/brainstorming/scripts/server.cjs +0 -0
  157. package/upstream/skills/brainstorming/scripts/start-server.sh +0 -0
  158. package/upstream/skills/brainstorming/scripts/stop-server.sh +0 -0
  159. package/upstream/skills/brainstorming/spec-document-reviewer-prompt.md +0 -0
  160. package/upstream/skills/brainstorming/visual-companion.md +0 -0
  161. package/upstream/skills/dispatching-parallel-agents/SKILL.md +0 -0
  162. package/upstream/skills/executing-plans/SKILL.md +0 -0
  163. package/upstream/skills/finishing-a-development-branch/SKILL.md +0 -0
  164. package/upstream/skills/receiving-code-review/SKILL.md +0 -0
  165. package/upstream/skills/requesting-code-review/SKILL.md +0 -0
  166. package/upstream/skills/requesting-code-review/code-reviewer.md +0 -0
  167. package/upstream/skills/subagent-driven-development/SKILL.md +0 -0
  168. package/upstream/skills/subagent-driven-development/code-quality-reviewer-prompt.md +0 -0
  169. package/upstream/skills/subagent-driven-development/implementer-prompt.md +0 -0
  170. package/upstream/skills/subagent-driven-development/spec-reviewer-prompt.md +0 -0
  171. package/upstream/skills/systematic-debugging/CREATION-LOG.md +0 -0
  172. package/upstream/skills/systematic-debugging/SKILL.md +0 -0
  173. package/upstream/skills/systematic-debugging/condition-based-waiting-example.ts +0 -0
  174. package/upstream/skills/systematic-debugging/condition-based-waiting.md +0 -0
  175. package/upstream/skills/systematic-debugging/defense-in-depth.md +0 -0
  176. package/upstream/skills/systematic-debugging/find-polluter.sh +0 -0
  177. package/upstream/skills/systematic-debugging/root-cause-tracing.md +0 -0
  178. package/upstream/skills/systematic-debugging/test-academic.md +0 -0
  179. package/upstream/skills/systematic-debugging/test-pressure-1.md +0 -0
  180. package/upstream/skills/systematic-debugging/test-pressure-2.md +0 -0
  181. package/upstream/skills/systematic-debugging/test-pressure-3.md +0 -0
  182. package/upstream/skills/tdd-lean/SKILL.md +0 -0
  183. package/upstream/skills/test-driven-development/SKILL.md +0 -0
  184. package/upstream/skills/test-driven-development/testing-anti-patterns.md +0 -0
  185. package/upstream/skills/using-git-worktrees/SKILL.md +0 -0
  186. package/upstream/skills/using-superpowers/SKILL.md +0 -0
  187. package/upstream/skills/using-superpowers/references/codex-tools.md +0 -0
  188. package/upstream/skills/using-superpowers/references/copilot-tools.md +0 -0
  189. package/upstream/skills/using-superpowers/references/gemini-tools.md +0 -0
  190. package/upstream/skills/verification-before-completion/SKILL.md +0 -0
  191. package/upstream/skills/writing-plans/SKILL.md +0 -0
  192. package/upstream/skills/writing-plans/plan-document-reviewer-prompt.md +0 -0
  193. package/upstream/skills/writing-skills/SKILL.md +0 -0
  194. package/upstream/skills/writing-skills/anthropic-best-practices.md +0 -0
  195. package/upstream/skills/writing-skills/examples/CLAUDE_MD_TESTING.md +0 -0
  196. package/upstream/skills/writing-skills/graphviz-conventions.dot +0 -0
  197. package/upstream/skills/writing-skills/persuasion-principles.md +0 -0
  198. package/upstream/skills/writing-skills/render-graphs.js +0 -0
  199. package/upstream/skills/writing-skills/testing-skills-with-subagents.md +0 -0
  200. package/upstream/tests/brainstorm-server/package-lock.json +0 -0
  201. package/upstream/tests/brainstorm-server/package.json +0 -0
  202. package/upstream/tests/brainstorm-server/server.test.js +0 -0
  203. package/upstream/tests/brainstorm-server/windows-lifecycle.test.sh +0 -0
  204. package/upstream/tests/brainstorm-server/ws-protocol.test.js +0 -0
  205. package/upstream/tests/claude-code/README.md +0 -0
  206. package/upstream/tests/claude-code/analyze-token-usage.py +0 -0
  207. package/upstream/tests/claude-code/run-skill-tests.sh +0 -0
  208. package/upstream/tests/claude-code/test-document-review-system.sh +0 -0
  209. package/upstream/tests/claude-code/test-helpers.sh +0 -0
  210. package/upstream/tests/claude-code/test-subagent-driven-development-integration.sh +0 -0
  211. package/upstream/tests/claude-code/test-subagent-driven-development.sh +0 -0
  212. package/upstream/tests/explicit-skill-requests/prompts/action-oriented.txt +0 -0
  213. package/upstream/tests/explicit-skill-requests/prompts/after-planning-flow.txt +0 -0
  214. package/upstream/tests/explicit-skill-requests/prompts/claude-suggested-it.txt +0 -0
  215. package/upstream/tests/explicit-skill-requests/prompts/i-know-what-sdd-means.txt +0 -0
  216. package/upstream/tests/explicit-skill-requests/prompts/mid-conversation-execute-plan.txt +0 -0
  217. package/upstream/tests/explicit-skill-requests/prompts/please-use-brainstorming.txt +0 -0
  218. package/upstream/tests/explicit-skill-requests/prompts/skip-formalities.txt +0 -0
  219. package/upstream/tests/explicit-skill-requests/prompts/subagent-driven-development-please.txt +0 -0
  220. package/upstream/tests/explicit-skill-requests/prompts/use-systematic-debugging.txt +0 -0
  221. package/upstream/tests/explicit-skill-requests/run-all.sh +0 -0
  222. package/upstream/tests/explicit-skill-requests/run-claude-describes-sdd.sh +0 -0
  223. package/upstream/tests/explicit-skill-requests/run-extended-multiturn-test.sh +0 -0
  224. package/upstream/tests/explicit-skill-requests/run-haiku-test.sh +0 -0
  225. package/upstream/tests/explicit-skill-requests/run-multiturn-test.sh +0 -0
  226. package/upstream/tests/explicit-skill-requests/run-test.sh +0 -0
  227. package/upstream/tests/opencode/run-tests.sh +0 -0
  228. package/upstream/tests/opencode/setup.sh +0 -0
  229. package/upstream/tests/opencode/test-plugin-loading.sh +0 -0
  230. package/upstream/tests/opencode/test-priority.sh +0 -0
  231. package/upstream/tests/opencode/test-tools.sh +0 -0
  232. package/upstream/tests/skill-triggering/prompts/dispatching-parallel-agents.txt +0 -0
  233. package/upstream/tests/skill-triggering/prompts/executing-plans.txt +0 -0
  234. package/upstream/tests/skill-triggering/prompts/requesting-code-review.txt +0 -0
  235. package/upstream/tests/skill-triggering/prompts/systematic-debugging.txt +0 -0
  236. package/upstream/tests/skill-triggering/prompts/test-driven-development.txt +0 -0
  237. package/upstream/tests/skill-triggering/prompts/writing-plans.txt +0 -0
  238. package/upstream/tests/skill-triggering/run-all.sh +0 -0
  239. package/upstream/tests/skill-triggering/run-test.sh +0 -0
  240. package/upstream/tests/subagent-driven-dev/go-fractals/design.md +0 -0
  241. package/upstream/tests/subagent-driven-dev/go-fractals/plan.md +0 -0
  242. package/upstream/tests/subagent-driven-dev/go-fractals/scaffold.sh +0 -0
  243. package/upstream/tests/subagent-driven-dev/run-test.sh +0 -0
  244. package/upstream/tests/subagent-driven-dev/svelte-todo/design.md +0 -0
  245. package/upstream/tests/subagent-driven-dev/svelte-todo/plan.md +0 -0
  246. package/upstream/tests/subagent-driven-dev/svelte-todo/scaffold.sh +0 -0
  247. package/custom/mcp-presets/playwright.json +0 -11
  248. package/custom/rules/test-patterns.md +0 -105
  249. package/custom/skills/automation-testing/SKILL.md +0 -168
  250. package/custom/skills/automation-testing/templates/BasePage.ts +0 -30
  251. package/custom/skills/automation-testing/templates/playwright.config.ts +0 -21
  252. package/custom/skills/automation-testing/templates/repos.json +0 -8
  253. package/scripts/score_members.js +0 -320
package/scripts/doctor.js CHANGED
@@ -1,218 +1,192 @@
1
- const fs = require('fs-extra');
2
- const path = require('path');
3
- const chalk = require('chalk');
4
- const { spawnSync } = require('child_process');
5
- const { detectRtk, isRtkHookConfigured, isGitNexusConfigured } = require('./init');
6
-
7
- function formatAgo(isoString) {
8
- const ms = Date.now() - new Date(isoString).getTime();
9
- const mins = Math.floor(ms / 60000);
10
- if (mins < 1) return 'just now';
11
- if (mins < 60) return `${mins}m ago`;
12
- const hrs = Math.floor(mins / 60);
13
- if (hrs < 24) return `${hrs}h ago`;
14
- return `${Math.floor(hrs / 24)}d ago`;
15
- }
16
-
17
- async function showTokenBreakdown(ticketId) {
18
- const tasksDir = path.join(process.cwd(), '.aiflow', 'tasks');
19
- const checkpointsFile = path.join(tasksDir, ticketId, 'checkpoints.json');
20
- if (!(await fs.pathExists(checkpointsFile))) return;
21
-
22
- const data = await fs.readJson(checkpointsFile).catch(() => ({ checkpoints: [] }));
23
- if (!data.checkpoints || data.checkpoints.length === 0) return;
24
-
25
- // Aggregate tokens per gate (taking the max/latest)
26
- const gateTokens = {};
27
- for (const cp of data.checkpoints) {
28
- if (!gateTokens[cp.gate] || cp.tokens > gateTokens[cp.gate]) {
29
- gateTokens[cp.gate] = cp.tokens;
30
- }
31
- }
32
-
33
- const GATE_LABELS = { 1: 'Analyze', 2: 'Plan', 3: 'Code', 4: 'Review', 5: 'PR' };
34
- const gates = Object.keys(gateTokens).sort();
35
- const total = gates.reduce((sum, g) => sum + gateTokens[g], 0);
36
-
37
- console.log('');
38
- console.log(chalk.bold(`Token usage for task ${ticketId}:`));
39
- for (const g of gates) {
40
- const label = GATE_LABELS[parseInt(g)] || `Gate ${g}`;
41
- const t = gateTokens[g];
42
- const bar = '█'.repeat(Math.round((t / total) * 20)).padEnd(20, '░');
43
- const pct = Math.round((t / total) * 100);
44
- console.log(` Gate ${g} ${label.padEnd(8)} ~${t.toLocaleString().padStart(6)} ${chalk.gray(bar)} ${pct}%`);
45
- }
46
- console.log(` Total estimated: ~${total.toLocaleString()} tokens`);
47
- }
48
-
49
- module.exports = async function doctor(options = {}) {
50
- const projectDir = process.cwd();
51
- const errors = [];
52
- const warnings = [];
53
-
54
- console.log(chalk.blue('Running health check for AI Flow Kit...\n'));
55
-
56
- // ── Token breakdown ────────────────────────────────────────
57
- let ticketId = options.ticket;
58
- if (!ticketId) {
59
- const contextFile = path.join(projectDir, '.aiflow', 'context', 'current.json');
60
- if (await fs.pathExists(contextFile)) {
61
- const ctx = await fs.readJson(contextFile).catch(() => ({}));
62
- ticketId = ctx.taskId;
63
- }
64
- }
65
-
66
- if (ticketId) {
67
- await showTokenBreakdown(ticketId);
68
- }
69
-
70
- // ── Core setup ─────────────────────────────────────────────
71
- if (!(await fs.pathExists(path.join(projectDir, '.claude', 'skills')))) {
72
- errors.push('Missing `.claude/skills` directory. Did you run `aiflow init`?');
73
- } else {
74
- console.log(chalk.green('✓ .claude/skills exists'));
75
- }
76
-
77
- if (!(await fs.pathExists(path.join(projectDir, '.rules')))) {
78
- errors.push('Missing `.rules` directory.');
79
- } else {
80
- console.log(chalk.green('✓ .rules exists'));
81
- }
82
-
83
- if (!(await fs.pathExists(path.join(projectDir, 'CLAUDE.md')))) {
84
- errors.push('Missing CLAUDE.md. AI context prompt is not set up.');
85
- } else {
86
- console.log(chalk.green('✓ CLAUDE.md exists'));
87
- }
88
-
89
- // ── Version tracking ───────────────────────────────────────
90
- const stateFile = path.join(projectDir, '.aiflow', 'state.json');
91
- if (!(await fs.pathExists(stateFile))) {
92
- errors.push('Missing `.aiflow/state.json`. Version tracking is broken.');
93
- } else {
94
- const state = await fs.readJson(stateFile);
95
- console.log(chalk.green(`✓ Version tracking active (v${state.current_version})`));
96
- }
97
-
98
- // ── SessionStart hook ──────────────────────────────────────
99
- const settingsPath = path.join(projectDir, '.claude', 'settings.json');
100
- if (await fs.pathExists(settingsPath)) {
101
- const settings = await fs.readJson(settingsPath).catch(() => ({}));
102
- const hookList = settings?.hooks?.SessionStart || [];
103
- const hasSessionHook = hookList.some(h =>
104
- (h.hooks || []).some(e => typeof e.command === 'string' && e.command.includes('session-start'))
105
- );
106
- if (hasSessionHook) {
107
- console.log(chalk.green('✓ SessionStart hook configured'));
108
- } else {
109
- warnings.push('SessionStart hook not found in .claude/settings.json — run `aiflow init` to set it up.');
110
- }
111
- } else {
112
- warnings.push('Missing .claude/settings.json — run `aiflow init`.');
113
- }
114
-
115
- // ── Clipboard ─────────────────────────────────────────────
116
- if (process.platform === 'linux') {
117
- const isWsl = (() => {
118
- try { return /microsoft|wsl/i.test(require('fs').readFileSync('/proc/version', 'utf-8')); }
119
- catch (_) { return false; }
120
- })();
121
-
122
- if (!isWsl) {
123
- const hasWlCopy = spawnSync('which', ['wl-copy'], { stdio: 'ignore' }).status === 0;
124
- const hasXclip = spawnSync('which', ['xclip'], { stdio: 'ignore' }).status === 0;
125
- const hasXsel = spawnSync('which', ['xsel'], { stdio: 'ignore' }).status === 0;
126
-
127
- if (hasWlCopy || hasXclip || hasXsel) {
128
- const tool = hasWlCopy ? 'wl-copy' : hasXclip ? 'xclip' : 'xsel';
129
- console.log(chalk.green(`✓ Clipboard tool available (${tool})`));
130
- } else {
131
- const isWayland = !!process.env.WAYLAND_DISPLAY;
132
- const pkg = isWayland ? 'wl-clipboard' : 'xclip';
133
- warnings.push(`Clipboard tool missing — \`ak prompt\` cannot copy to clipboard. Fix: sudo apt install ${pkg}`);
134
- console.log(chalk.yellow(` ⚠ Clipboard tool not found (need: ${pkg})`));
135
- console.log(chalk.gray(` Fix: sudo apt install ${pkg}`));
136
- }
137
- }
138
- }
139
-
140
- // ── Token savings tools ────────────────────────────────────
141
- console.log('');
142
- console.log(chalk.bold('Token savings:'));
143
-
144
- // RTK
145
- const rtk = await detectRtk();
146
- if (rtk.installed) {
147
- const hookOk = await isRtkHookConfigured(projectDir);
148
- if (hookOk) {
149
- console.log(chalk.green(` ✓ RTK (${rtk.version}) bash output compression active`));
150
- console.log(chalk.gray(' Estimated: 60–90% reduction on bash command outputs (test runs, git, npm...)'));
151
- } else {
152
- console.log(chalk.yellow(` ⚠ RTK installed (${rtk.version}) but hook not configured`));
153
- warnings.push('RTK hook not configured. Run `aiflow init` to enable token compression.');
154
- }
155
- } else {
156
- console.log(chalk.gray(' RTK not installed bash output compression inactive'));
157
- console.log(chalk.gray(' Install: cargo install rtk | Enable: aiflow init --with-rtk'));
158
- }
159
-
160
- // GitNexus
161
- const gnConfigured = await isGitNexusConfigured(projectDir);
162
- const gnStatusPath = path.join(projectDir, '.aiflow', 'gitnexus-status.json');
163
- if (gnConfigured) {
164
- let statusLine = chalk.green(' ✓ GitNexus MCP configured');
165
- try {
166
- if (await fs.pathExists(gnStatusPath)) {
167
- const gn = await fs.readJson(gnStatusPath);
168
- const GITNEXUS_STALE_MS = 3 * 60 * 60 * 1000; // 3 hours
169
- if (gn.status === 'done') {
170
- const ago = gn.completedAt
171
- ? chalk.gray(` — indexed ${formatAgo(gn.completedAt)}`)
172
- : '';
173
- statusLine = chalk.green(` GitNexus MCP configured — index ready${ago}`);
174
- console.log(statusLine);
175
- console.log(chalk.gray(' Estimated: ~50% fewer tokens at Gate 1 (context queries vs file reads)'));
176
- console.log(chalk.gray(' Estimated: ~70% fewer tokens at Gate 4 (impact() vs grep codebase)'));
177
- } else if (gn.status === 'running') {
178
- const age = Date.now() - new Date(gn.startedAt).getTime();
179
- if (age > GITNEXUS_STALE_MS) {
180
- console.log(chalk.red(' ✗ GitNexus MCP configured — indexing timed out (stale)'));
181
- console.log(chalk.gray(` Started ${formatAgo(gn.startedAt)} but never finished. Process may have crashed.`));
182
- // console.log(chalk.gray(' Retry: aiflow init --with-gitnexus --wait | Log: .aiflow/gitnexus-analyze.log'));
183
- } else {
184
- console.log(chalk.yellow(' ⟳ GitNexus MCP configured — indexing in progress...'));
185
- console.log(chalk.gray(' Log: .aiflow/gitnexus-analyze.log'));
186
- }
187
- } else if (gn.status === 'error') {
188
- console.log(chalk.red(' GitNexus MCP configured last index failed'));
189
- console.log(chalk.gray(' Retry: npx gitnexus analyze | Log: .aiflow/gitnexus-analyze.log'));
190
- }
191
- } else {
192
- console.log(chalk.yellow(' ⚠ GitNexus MCP configured but not yet indexed'));
193
- console.log(chalk.gray(' Run: npx gitnexus analyze'));
194
- }
195
- } catch (_) {
196
- console.log(statusLine);
197
- }
198
- } else {
199
- console.log(chalk.gray(' ○ GitNexus not configured — code intelligence inactive'));
200
- // console.log(chalk.gray(' Enable: aiflow init --with-gitnexus'));
201
- }
202
-
203
- // ── Summary ────────────────────────────────────────────────
204
- console.log('');
205
- if (warnings.length > 0) {
206
- console.log(chalk.yellow('Warnings:'));
207
- warnings.forEach(w => console.log(chalk.yellow(` ⚠ ${w}`)));
208
- console.log('');
209
- }
210
-
211
- if (errors.length > 0) {
212
- console.log(chalk.red('Issues found:'));
213
- errors.forEach(e => console.log(chalk.red(` ✗ ${e}`)));
214
- console.log(chalk.yellow('\nTry running `aiflow init` or `aiflow update` to fix these files.'));
215
- } else {
216
- console.log(chalk.green('✨ Everything looks healthy! You are ready to fly.'));
217
- }
218
- };
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
+ };
File without changes
package/scripts/guide.js CHANGED
File without changes
File without changes
File without changes
File without changes