@relipa/ai-flow-kit 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AIFLOW.md +432 -0
- package/CHANGELOG.md +78 -0
- package/CONTRIBUTING.md +351 -0
- package/IMPLEMENTATION_SUMMARY.md +348 -0
- package/QUICK_START.md +392 -0
- package/README.md +323 -0
- package/bin/aiflow.js +178 -0
- package/custom/mcp-presets/README.md +138 -0
- package/custom/mcp-presets/backlog.json +15 -0
- package/custom/mcp-presets/figma.json +15 -0
- package/custom/mcp-presets/google-sheets.json +14 -0
- package/custom/mcp-presets/jira.json +16 -0
- package/custom/prompts/bug-fix.md +149 -0
- package/custom/prompts/feature.md +190 -0
- package/custom/prompts/investigation.md +164 -0
- package/custom/rules/code-style.md +7 -0
- package/custom/rules/java/code-style.md +11 -0
- package/custom/rules/java/naming.md +17 -0
- package/custom/rules/java/review-checklist.md +36 -0
- package/custom/rules/javascript/code-style.md +12 -0
- package/custom/rules/javascript/naming.md +14 -0
- package/custom/rules/naming.md +9 -0
- package/custom/rules/php/code-style.md +10 -0
- package/custom/rules/php/naming.md +15 -0
- package/custom/rules/review-checklist.md +9 -0
- package/custom/skills/figma-to-component/SKILL.md +207 -0
- package/custom/skills/generate-spec/SKILL.md +97 -0
- package/custom/skills/impact-analysis/SKILL.md +94 -0
- package/custom/skills/investigate-bug/SKILL.md +93 -0
- package/custom/skills/report-customer/SKILL.md +95 -0
- package/custom/skills/review-plan/SKILL.md +158 -0
- package/custom/skills/validate-ticket/SKILL.md +240 -0
- package/custom/templates/laravel.md +90 -0
- package/custom/templates/nextjs.md +89 -0
- package/custom/templates/reactjs.md +567 -0
- package/custom/templates/spring-boot.md +598 -0
- package/custom/templates/vue-nuxt.md +89 -0
- package/docs/architecture.md +395 -0
- package/docs/cli-reference.md +438 -0
- package/docs/configuration.md +412 -0
- package/docs/getting-started.md +248 -0
- package/docs/troubleshooting.md +587 -0
- package/docs/workflows/bug-fix.md +126 -0
- package/docs/workflows/feature.md +123 -0
- package/docs/workflows/impact-analysis.md +13 -0
- package/docs/workflows/investigation.md +13 -0
- package/docs/workflows/refactor.md +13 -0
- package/index.js +27 -0
- package/package.json +70 -0
- package/scripts/config.js +317 -0
- package/scripts/context.js +117 -0
- package/scripts/detect.js +239 -0
- package/scripts/doctor.js +48 -0
- package/scripts/guide.js +282 -0
- package/scripts/hooks/session-start.js +140 -0
- package/scripts/init.js +453 -0
- package/scripts/memory.js +247 -0
- package/scripts/prompt.js +392 -0
- package/scripts/remove.js +170 -0
- package/scripts/update.js +111 -0
- package/scripts/use.js +570 -0
- package/scripts/validate.js +303 -0
- package/upstream/.claude-plugin/marketplace.json +20 -0
- package/upstream/.claude-plugin/plugin.json +20 -0
- package/upstream/.codex/INSTALL.md +67 -0
- package/upstream/.cursor-plugin/plugin.json +25 -0
- package/upstream/.gitattributes +18 -0
- package/upstream/.github/FUNDING.yml +3 -0
- package/upstream/.github/ISSUE_TEMPLATE/bug_report.md +52 -0
- package/upstream/.github/ISSUE_TEMPLATE/config.yml +5 -0
- package/upstream/.github/ISSUE_TEMPLATE/feature_request.md +34 -0
- package/upstream/.github/ISSUE_TEMPLATE/platform_support.md +23 -0
- package/upstream/.github/PULL_REQUEST_TEMPLATE.md +87 -0
- package/upstream/.opencode/INSTALL.md +83 -0
- package/upstream/.opencode/plugins/superpowers.js +112 -0
- package/upstream/.version-bump.json +19 -0
- package/upstream/AGENTS.md +1 -0
- package/upstream/CHANGELOG.md +13 -0
- package/upstream/CLAUDE.md +85 -0
- package/upstream/CODE_OF_CONDUCT.md +128 -0
- package/upstream/GEMINI.md +2 -0
- package/upstream/LICENSE +21 -0
- package/upstream/README.md +190 -0
- package/upstream/RELEASE-NOTES.md +1096 -0
- package/upstream/agents/code-reviewer.md +48 -0
- package/upstream/commands/brainstorm.md +5 -0
- package/upstream/commands/execute-plan.md +5 -0
- package/upstream/commands/write-plan.md +5 -0
- package/upstream/docs/README.codex.md +126 -0
- package/upstream/docs/README.opencode.md +130 -0
- package/upstream/docs/plans/2025-11-22-opencode-support-design.md +294 -0
- package/upstream/docs/plans/2025-11-22-opencode-support-implementation.md +1095 -0
- package/upstream/docs/plans/2025-11-28-skills-improvements-from-user-feedback.md +711 -0
- package/upstream/docs/plans/2026-01-17-visual-brainstorming.md +571 -0
- package/upstream/docs/superpowers/plans/2026-01-22-document-review-system.md +301 -0
- package/upstream/docs/superpowers/plans/2026-02-19-visual-brainstorming-refactor.md +523 -0
- package/upstream/docs/superpowers/plans/2026-03-11-zero-dep-brainstorm-server.md +479 -0
- package/upstream/docs/superpowers/plans/2026-03-23-codex-app-compatibility.md +564 -0
- package/upstream/docs/superpowers/specs/2026-01-22-document-review-system-design.md +136 -0
- package/upstream/docs/superpowers/specs/2026-02-19-visual-brainstorming-refactor-design.md +162 -0
- package/upstream/docs/superpowers/specs/2026-03-11-zero-dep-brainstorm-server-design.md +118 -0
- package/upstream/docs/superpowers/specs/2026-03-23-codex-app-compatibility-design.md +244 -0
- package/upstream/docs/testing.md +303 -0
- package/upstream/docs/windows/polyglot-hooks.md +212 -0
- package/upstream/gemini-extension.json +6 -0
- package/upstream/hooks/hooks-cursor.json +10 -0
- package/upstream/hooks/hooks.json +16 -0
- package/upstream/hooks/run-hook.cmd +46 -0
- package/upstream/hooks/session-start +57 -0
- package/upstream/package.json +6 -0
- package/upstream/scripts/bump-version.sh +220 -0
- package/upstream/skills/brainstorming/SKILL.md +164 -0
- package/upstream/skills/brainstorming/scripts/frame-template.html +214 -0
- package/upstream/skills/brainstorming/scripts/helper.js +88 -0
- package/upstream/skills/brainstorming/scripts/server.cjs +354 -0
- package/upstream/skills/brainstorming/scripts/start-server.sh +148 -0
- package/upstream/skills/brainstorming/scripts/stop-server.sh +56 -0
- package/upstream/skills/brainstorming/spec-document-reviewer-prompt.md +49 -0
- package/upstream/skills/brainstorming/visual-companion.md +287 -0
- package/upstream/skills/dispatching-parallel-agents/SKILL.md +182 -0
- package/upstream/skills/executing-plans/SKILL.md +70 -0
- package/upstream/skills/finishing-a-development-branch/SKILL.md +200 -0
- package/upstream/skills/receiving-code-review/SKILL.md +213 -0
- package/upstream/skills/requesting-code-review/SKILL.md +105 -0
- package/upstream/skills/requesting-code-review/code-reviewer.md +146 -0
- package/upstream/skills/subagent-driven-development/SKILL.md +277 -0
- package/upstream/skills/subagent-driven-development/code-quality-reviewer-prompt.md +26 -0
- package/upstream/skills/subagent-driven-development/implementer-prompt.md +113 -0
- package/upstream/skills/subagent-driven-development/spec-reviewer-prompt.md +61 -0
- package/upstream/skills/systematic-debugging/CREATION-LOG.md +119 -0
- package/upstream/skills/systematic-debugging/SKILL.md +296 -0
- package/upstream/skills/systematic-debugging/condition-based-waiting-example.ts +158 -0
- package/upstream/skills/systematic-debugging/condition-based-waiting.md +115 -0
- package/upstream/skills/systematic-debugging/defense-in-depth.md +122 -0
- package/upstream/skills/systematic-debugging/find-polluter.sh +63 -0
- package/upstream/skills/systematic-debugging/root-cause-tracing.md +169 -0
- package/upstream/skills/systematic-debugging/test-academic.md +14 -0
- package/upstream/skills/systematic-debugging/test-pressure-1.md +58 -0
- package/upstream/skills/systematic-debugging/test-pressure-2.md +68 -0
- package/upstream/skills/systematic-debugging/test-pressure-3.md +69 -0
- package/upstream/skills/test-driven-development/SKILL.md +371 -0
- package/upstream/skills/test-driven-development/testing-anti-patterns.md +299 -0
- package/upstream/skills/using-git-worktrees/SKILL.md +218 -0
- package/upstream/skills/using-superpowers/SKILL.md +117 -0
- package/upstream/skills/using-superpowers/references/codex-tools.md +100 -0
- package/upstream/skills/using-superpowers/references/copilot-tools.md +52 -0
- package/upstream/skills/using-superpowers/references/gemini-tools.md +33 -0
- package/upstream/skills/verification-before-completion/SKILL.md +139 -0
- package/upstream/skills/writing-plans/SKILL.md +152 -0
- package/upstream/skills/writing-plans/plan-document-reviewer-prompt.md +49 -0
- package/upstream/skills/writing-skills/SKILL.md +655 -0
- package/upstream/skills/writing-skills/anthropic-best-practices.md +1150 -0
- package/upstream/skills/writing-skills/examples/CLAUDE_MD_TESTING.md +189 -0
- package/upstream/skills/writing-skills/graphviz-conventions.dot +172 -0
- package/upstream/skills/writing-skills/persuasion-principles.md +187 -0
- package/upstream/skills/writing-skills/render-graphs.js +168 -0
- package/upstream/skills/writing-skills/testing-skills-with-subagents.md +384 -0
- package/upstream/tests/brainstorm-server/package-lock.json +36 -0
- package/upstream/tests/brainstorm-server/package.json +10 -0
- package/upstream/tests/brainstorm-server/server.test.js +427 -0
- package/upstream/tests/brainstorm-server/windows-lifecycle.test.sh +351 -0
- package/upstream/tests/brainstorm-server/ws-protocol.test.js +392 -0
- package/upstream/tests/claude-code/README.md +158 -0
- package/upstream/tests/claude-code/analyze-token-usage.py +168 -0
- package/upstream/tests/claude-code/run-skill-tests.sh +187 -0
- package/upstream/tests/claude-code/test-document-review-system.sh +177 -0
- package/upstream/tests/claude-code/test-helpers.sh +202 -0
- package/upstream/tests/claude-code/test-subagent-driven-development-integration.sh +314 -0
- package/upstream/tests/claude-code/test-subagent-driven-development.sh +165 -0
- package/upstream/tests/explicit-skill-requests/prompts/action-oriented.txt +3 -0
- package/upstream/tests/explicit-skill-requests/prompts/after-planning-flow.txt +17 -0
- package/upstream/tests/explicit-skill-requests/prompts/claude-suggested-it.txt +11 -0
- package/upstream/tests/explicit-skill-requests/prompts/i-know-what-sdd-means.txt +8 -0
- package/upstream/tests/explicit-skill-requests/prompts/mid-conversation-execute-plan.txt +3 -0
- package/upstream/tests/explicit-skill-requests/prompts/please-use-brainstorming.txt +1 -0
- package/upstream/tests/explicit-skill-requests/prompts/skip-formalities.txt +3 -0
- package/upstream/tests/explicit-skill-requests/prompts/subagent-driven-development-please.txt +1 -0
- package/upstream/tests/explicit-skill-requests/prompts/use-systematic-debugging.txt +1 -0
- package/upstream/tests/explicit-skill-requests/run-all.sh +70 -0
- package/upstream/tests/explicit-skill-requests/run-claude-describes-sdd.sh +100 -0
- package/upstream/tests/explicit-skill-requests/run-extended-multiturn-test.sh +113 -0
- package/upstream/tests/explicit-skill-requests/run-haiku-test.sh +144 -0
- package/upstream/tests/explicit-skill-requests/run-multiturn-test.sh +143 -0
- package/upstream/tests/explicit-skill-requests/run-test.sh +136 -0
- package/upstream/tests/opencode/run-tests.sh +163 -0
- package/upstream/tests/opencode/setup.sh +88 -0
- package/upstream/tests/opencode/test-plugin-loading.sh +82 -0
- package/upstream/tests/opencode/test-priority.sh +198 -0
- package/upstream/tests/opencode/test-tools.sh +104 -0
- package/upstream/tests/skill-triggering/prompts/dispatching-parallel-agents.txt +8 -0
- package/upstream/tests/skill-triggering/prompts/executing-plans.txt +1 -0
- package/upstream/tests/skill-triggering/prompts/requesting-code-review.txt +3 -0
- package/upstream/tests/skill-triggering/prompts/systematic-debugging.txt +11 -0
- package/upstream/tests/skill-triggering/prompts/test-driven-development.txt +7 -0
- package/upstream/tests/skill-triggering/prompts/writing-plans.txt +10 -0
- package/upstream/tests/skill-triggering/run-all.sh +60 -0
- package/upstream/tests/skill-triggering/run-test.sh +88 -0
- package/upstream/tests/subagent-driven-dev/go-fractals/design.md +81 -0
- package/upstream/tests/subagent-driven-dev/go-fractals/plan.md +172 -0
- package/upstream/tests/subagent-driven-dev/go-fractals/scaffold.sh +45 -0
- package/upstream/tests/subagent-driven-dev/run-test.sh +106 -0
- package/upstream/tests/subagent-driven-dev/svelte-todo/design.md +70 -0
- package/upstream/tests/subagent-driven-dev/svelte-todo/plan.md +222 -0
- package/upstream/tests/subagent-driven-dev/svelte-todo/scaffold.sh +46 -0
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
const chalk = require('chalk');
|
|
2
|
+
|
|
3
|
+
class TaskDetector {
|
|
4
|
+
constructor() {
|
|
5
|
+
this.taskTypes = {
|
|
6
|
+
'bug-fix': {
|
|
7
|
+
keywords: [
|
|
8
|
+
'bug', 'error', 'broken', 'crash', 'fail', 'failed', 'failure',
|
|
9
|
+
'issue', 'problem', 'wrong', 'not working', 'doesn\'t work',
|
|
10
|
+
'can\'t', 'cannot', 'regression', 'fixing', 'fix',
|
|
11
|
+
'exception', 'bug report'
|
|
12
|
+
],
|
|
13
|
+
antiKeywords: ['add', 'create', 'new feature', 'build'],
|
|
14
|
+
icon: '🐛',
|
|
15
|
+
description: 'Fixing production issues'
|
|
16
|
+
},
|
|
17
|
+
'feature': {
|
|
18
|
+
keywords: [
|
|
19
|
+
'add', 'create', 'build', 'new', 'implement', 'feature',
|
|
20
|
+
'new feature', 'feature request', 'capability', 'support for',
|
|
21
|
+
'enable', 'make it possible', 'allow', 'user story'
|
|
22
|
+
],
|
|
23
|
+
antiKeywords: ['fix', 'bug', 'broken', 'error'],
|
|
24
|
+
icon: '✨',
|
|
25
|
+
description: 'Building new features'
|
|
26
|
+
},
|
|
27
|
+
'refactor': {
|
|
28
|
+
keywords: [
|
|
29
|
+
'refactor', 'improve', 'optimize', 'clean up', 'cleanup',
|
|
30
|
+
'simplify', 'reorganize', 'reorganise', 'redesign', 'restructure',
|
|
31
|
+
'modernize', 'upgrade', 'update', 'rework', 'rewrite',
|
|
32
|
+
'performance', 'efficient', 'better', 'enhancement'
|
|
33
|
+
],
|
|
34
|
+
antiKeywords: ['bug', 'broken', 'feature'],
|
|
35
|
+
icon: '♻️',
|
|
36
|
+
description: 'Improving existing code'
|
|
37
|
+
},
|
|
38
|
+
'investigation': {
|
|
39
|
+
keywords: [
|
|
40
|
+
'investigate', 'analyze', 'analysis', 'understand', 'how does',
|
|
41
|
+
'why', 'trace', 'explore', 'research', 'find out', 'examine',
|
|
42
|
+
'check', 'review', 'audit', 'assessment'
|
|
43
|
+
],
|
|
44
|
+
antiKeywords: ['fix', 'build', 'create'],
|
|
45
|
+
icon: '🔍',
|
|
46
|
+
description: 'Analyzing code and systems'
|
|
47
|
+
},
|
|
48
|
+
'impact-analysis': {
|
|
49
|
+
keywords: [
|
|
50
|
+
'impact', 'affect', 'affected', 'breaking', 'breaking change',
|
|
51
|
+
'scope', 'scope of change', 'side effect', 'consequence',
|
|
52
|
+
'dependent', 'dependency', 'risk', 'assess'
|
|
53
|
+
],
|
|
54
|
+
antiKeywords: [],
|
|
55
|
+
icon: '📊',
|
|
56
|
+
description: 'Assessing change impact'
|
|
57
|
+
},
|
|
58
|
+
'documentation': {
|
|
59
|
+
keywords: [
|
|
60
|
+
'document', 'readme', 'guide', 'tutorial',
|
|
61
|
+
'documentation', 'write doc', 'comment', 'docstring',
|
|
62
|
+
'explain', 'api doc', 'reference'
|
|
63
|
+
],
|
|
64
|
+
antiKeywords: ['code'],
|
|
65
|
+
icon: '📖',
|
|
66
|
+
description: 'Writing documentation'
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Detect task type from description
|
|
73
|
+
* Returns: { type, confidence, keywords, suggestions }
|
|
74
|
+
*/
|
|
75
|
+
detect(description, confidenceThreshold = 0.8) {
|
|
76
|
+
if (!description || typeof description !== 'string') {
|
|
77
|
+
return this.getDefaultResult();
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const lowerDesc = description.toLowerCase();
|
|
81
|
+
const scores = {};
|
|
82
|
+
|
|
83
|
+
// Score each task type
|
|
84
|
+
for (const [type, config] of Object.entries(this.taskTypes)) {
|
|
85
|
+
scores[type] = this.scoreType(lowerDesc, config);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// Find best match
|
|
89
|
+
const sorted = Object.entries(scores)
|
|
90
|
+
.sort(([, scoreA], [, scoreB]) => scoreB - scoreA);
|
|
91
|
+
|
|
92
|
+
if (!sorted.length || sorted[0][1] === 0) {
|
|
93
|
+
return this.getDefaultResult();
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const [bestType, score] = sorted[0];
|
|
97
|
+
const confidence = Math.min(score, 1.0);
|
|
98
|
+
|
|
99
|
+
return {
|
|
100
|
+
type: bestType,
|
|
101
|
+
confidence: Math.round(confidence * 100) / 100,
|
|
102
|
+
confidence_percent: Math.round(confidence * 100),
|
|
103
|
+
icon: this.taskTypes[bestType].icon,
|
|
104
|
+
description: this.taskTypes[bestType].description,
|
|
105
|
+
keywords: this.findMatchingKeywords(lowerDesc, this.taskTypes[bestType]),
|
|
106
|
+
suggestions: sorted.slice(1, 3).map(([t, s]) => ({
|
|
107
|
+
type: t,
|
|
108
|
+
confidence: Math.round(s * 100) / 100
|
|
109
|
+
})),
|
|
110
|
+
isConfident: confidence >= confidenceThreshold,
|
|
111
|
+
detectedKeywords: this.findAllMatchedKeywords(lowerDesc)
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Score a task type based on description
|
|
117
|
+
*/
|
|
118
|
+
scoreType(description, config) {
|
|
119
|
+
let score = 0;
|
|
120
|
+
|
|
121
|
+
// Count matching keywords
|
|
122
|
+
for (const keyword of config.keywords) {
|
|
123
|
+
if (description.includes(keyword)) {
|
|
124
|
+
score += 0.5;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// Penalize anti-keywords
|
|
129
|
+
for (const antiKeyword of config.antiKeywords) {
|
|
130
|
+
if (description.includes(antiKeyword)) {
|
|
131
|
+
score -= 0.3;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// Normalize score
|
|
136
|
+
return Math.max(0, Math.min(1, score / Math.max(1, config.keywords.length / 3)));
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Find which keywords matched in description
|
|
141
|
+
*/
|
|
142
|
+
findMatchingKeywords(description, config) {
|
|
143
|
+
const matches = [];
|
|
144
|
+
for (const keyword of config.keywords) {
|
|
145
|
+
if (description.includes(keyword)) {
|
|
146
|
+
matches.push(keyword);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
return matches.slice(0, 5); // Top 5 matches
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Find all matched keywords across all types
|
|
154
|
+
*/
|
|
155
|
+
findAllMatchedKeywords(description) {
|
|
156
|
+
const allKeywords = {};
|
|
157
|
+
for (const [type, config] of Object.entries(this.taskTypes)) {
|
|
158
|
+
const matched = this.findMatchingKeywords(description, config);
|
|
159
|
+
if (matched.length > 0) {
|
|
160
|
+
allKeywords[type] = matched;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
return allKeywords;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* Default result when detection fails
|
|
168
|
+
*/
|
|
169
|
+
getDefaultResult() {
|
|
170
|
+
return {
|
|
171
|
+
type: 'unknown',
|
|
172
|
+
confidence: 0,
|
|
173
|
+
confidence_percent: 0,
|
|
174
|
+
icon: '❓',
|
|
175
|
+
description: 'Unknown task type',
|
|
176
|
+
keywords: [],
|
|
177
|
+
suggestions: [],
|
|
178
|
+
isConfident: false,
|
|
179
|
+
detectedKeywords: {}
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* Get formatted output for CLI
|
|
185
|
+
*/
|
|
186
|
+
formatOutput(result, verbose = false) {
|
|
187
|
+
if (result.type === 'unknown') {
|
|
188
|
+
return `${result.icon} Could not detect task type\n\nPlease provide more details or specify task type explicitly:\n aiflow prompt bug-fix\n aiflow prompt feature\n aiflow prompt investigation`;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
let output = `${result.icon} ${result.type.toUpperCase()} (${result.confidence_percent}% confidence)\n\n`;
|
|
192
|
+
|
|
193
|
+
if (verbose) {
|
|
194
|
+
output += `Description: ${result.description}\n`;
|
|
195
|
+
output += `Detected keywords:\n`;
|
|
196
|
+
for (const keyword of result.keywords.slice(0, 5)) {
|
|
197
|
+
output += ` - ${keyword}\n`;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
if (result.suggestions.length > 0) {
|
|
201
|
+
output += `\nOther possibilities:\n`;
|
|
202
|
+
for (const sugg of result.suggestions) {
|
|
203
|
+
output += ` - ${sugg.type} (${Math.round(sugg.confidence * 100)}%)\n`;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
output += `\nSuggested skill: ${result.type}\n`;
|
|
209
|
+
output += `\nNext: aiflow prompt ${result.type}`;
|
|
210
|
+
|
|
211
|
+
return output;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* Export all task types for reference
|
|
216
|
+
*/
|
|
217
|
+
getTaskTypes() {
|
|
218
|
+
return this.taskTypes;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
* Get task type by name
|
|
223
|
+
*/
|
|
224
|
+
getTaskType(name) {
|
|
225
|
+
return this.taskTypes[name] || null;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* Get available task types
|
|
230
|
+
*/
|
|
231
|
+
getAvailableTypes() {
|
|
232
|
+
return Object.keys(this.taskTypes).map(type => ({
|
|
233
|
+
name: type,
|
|
234
|
+
...this.taskTypes[type]
|
|
235
|
+
}));
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
module.exports = TaskDetector;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
const fs = require('fs-extra');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const chalk = require('chalk');
|
|
4
|
+
|
|
5
|
+
module.exports = async function doctor() {
|
|
6
|
+
const projectDir = process.cwd();
|
|
7
|
+
const errors = [];
|
|
8
|
+
|
|
9
|
+
console.log(chalk.blue('Running health check for AI Flow Kit...\n'));
|
|
10
|
+
|
|
11
|
+
// Check .claude directory
|
|
12
|
+
if (!(await fs.pathExists(path.join(projectDir, '.claude', 'skills')))) {
|
|
13
|
+
errors.push("Missing `.claude/skills` directory. Did you run `aiflow init`?");
|
|
14
|
+
} else {
|
|
15
|
+
console.log(chalk.green('✓ .claude/skills exists'));
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// Check .rules directory
|
|
19
|
+
if (!(await fs.pathExists(path.join(projectDir, '.rules')))) {
|
|
20
|
+
errors.push("Missing `.rules` directory.");
|
|
21
|
+
} else {
|
|
22
|
+
console.log(chalk.green('✓ .rules exists'));
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// Check CLAUDE.md template
|
|
26
|
+
if (!(await fs.pathExists(path.join(projectDir, 'CLAUDE.md')))) {
|
|
27
|
+
errors.push("Missing CLAUDE.md. Prompt AI Context is not set up.");
|
|
28
|
+
} else {
|
|
29
|
+
console.log(chalk.green('✓ CLAUDE.md exists'));
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// Check .aiflow hidden state
|
|
33
|
+
const stateFile = path.join(projectDir, '.aiflow', 'state.json');
|
|
34
|
+
if (!(await fs.pathExists(stateFile))) {
|
|
35
|
+
errors.push("Missing `.aiflow/state.json`. Version tracking is broken.");
|
|
36
|
+
} else {
|
|
37
|
+
const state = await fs.readJson(stateFile);
|
|
38
|
+
console.log(chalk.green(`✓ Version tracking active (v${state.current_version})`));
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if (errors.length > 0) {
|
|
42
|
+
console.log(chalk.red('\nIssues found:'));
|
|
43
|
+
errors.forEach(e => console.log(chalk.red(` - ${e}`)));
|
|
44
|
+
console.log(chalk.yellow('\nTry running `aiflow init` or `aiflow update` to fix these files.'));
|
|
45
|
+
} else {
|
|
46
|
+
console.log(chalk.green('\n✨ Everything looks healthy! You are ready to fly.'));
|
|
47
|
+
}
|
|
48
|
+
};
|
package/scripts/guide.js
ADDED
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
const chalk = require('chalk');
|
|
2
|
+
|
|
3
|
+
// ──────────────────────────────────────────────────────────────
|
|
4
|
+
// Entry point
|
|
5
|
+
// ──────────────────────────────────────────────────────────────
|
|
6
|
+
|
|
7
|
+
module.exports = function guide(options = {}) {
|
|
8
|
+
if (options.flow) return showFlow();
|
|
9
|
+
if (options.commands) return showCommands();
|
|
10
|
+
showFull();
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
// ──────────────────────────────────────────────────────────────
|
|
14
|
+
// Full guide
|
|
15
|
+
// ──────────────────────────────────────────────────────────────
|
|
16
|
+
|
|
17
|
+
function showFull() {
|
|
18
|
+
showHeader();
|
|
19
|
+
showFlow();
|
|
20
|
+
showWorkflow();
|
|
21
|
+
showCommands();
|
|
22
|
+
showPromptGuide();
|
|
23
|
+
showFooter();
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// ──────────────────────────────────────────────────────────────
|
|
27
|
+
// Header
|
|
28
|
+
// ──────────────────────────────────────────────────────────────
|
|
29
|
+
|
|
30
|
+
function showHeader() {
|
|
31
|
+
console.log('\n' + chalk.bold.blue('═'.repeat(62)));
|
|
32
|
+
console.log(chalk.bold.white(' AI Flow Kit — Quickstart Guide'));
|
|
33
|
+
console.log(chalk.blue('═'.repeat(62)) + '\n');
|
|
34
|
+
console.log(chalk.gray(' All-in-one AI workflow for development teams using Claude AI.'));
|
|
35
|
+
console.log(chalk.gray(' Developers only need 3 steps for AI to understand the task and start working.\n'));
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// ──────────────────────────────────────────────────────────────
|
|
39
|
+
// Architecture / Flow diagram
|
|
40
|
+
// ──────────────────────────────────────────────────────────────
|
|
41
|
+
|
|
42
|
+
function showFlow() {
|
|
43
|
+
console.log(chalk.bold.cyan(' 📐 ARCHITECTURE & FLOW\n'));
|
|
44
|
+
|
|
45
|
+
console.log(chalk.gray(' ┌──────────────────────────────────────────────────────┐'));
|
|
46
|
+
console.log(chalk.gray(' │') + chalk.bold.yellow(' TECH LEAD (One-time setup)') + chalk.gray(' │'));
|
|
47
|
+
console.log(chalk.gray(' │') + chalk.white(' 1. Configure custom/rules/, custom/templates/') + chalk.gray(' │'));
|
|
48
|
+
console.log(chalk.gray(' │') + chalk.white(' 2. npm publish → developer: npm install -g pkg') + chalk.gray(' │'));
|
|
49
|
+
console.log(chalk.gray(' └─────────────────────────┬────────────────────────────┘'));
|
|
50
|
+
console.log(chalk.gray(' │'));
|
|
51
|
+
console.log(chalk.gray(' ┌─────────────▼──────────────┐'));
|
|
52
|
+
console.log(chalk.gray(' │') + chalk.bold.green(' aiflow init') + chalk.gray(' │'));
|
|
53
|
+
console.log(chalk.gray(' │') + chalk.white(' --framework spring-boot') + chalk.gray(' │'));
|
|
54
|
+
console.log(chalk.gray(' │') + chalk.white(' --adapter backlog') + chalk.gray(' │'));
|
|
55
|
+
console.log(chalk.gray(' └─────────────┬──────────────┘'));
|
|
56
|
+
console.log(chalk.gray(' │ generates'));
|
|
57
|
+
console.log(chalk.gray(' ┌─────────────▼──────────────────────────┐'));
|
|
58
|
+
console.log(chalk.gray(' │') + chalk.white(' .claude/skills/ ← superpowers + custom') + chalk.gray(' │'));
|
|
59
|
+
console.log(chalk.gray(' │') + chalk.white(' .claude/hooks/ ← SessionStart hook') + chalk.gray(' │'));
|
|
60
|
+
console.log(chalk.gray(' │') + chalk.white(' .rules/ ← team coding rules') + chalk.gray(' │'));
|
|
61
|
+
console.log(chalk.gray(' │') + chalk.white(' CLAUDE.md ← framework AI prompt') + chalk.gray(' │'));
|
|
62
|
+
console.log(chalk.gray(' │') + chalk.white(' .mcp.json ← MCP adapter config') + chalk.gray(' │'));
|
|
63
|
+
console.log(chalk.gray(' └─────────────┬──────────────────────────┘'));
|
|
64
|
+
console.log(chalk.gray(' │'));
|
|
65
|
+
console.log(chalk.gray(' ┌──────────────────▼───────────────────┐'));
|
|
66
|
+
console.log(chalk.gray(' │') + chalk.bold.green(' Developer Workflow (per task)') + chalk.gray(' │'));
|
|
67
|
+
console.log(chalk.gray(' │') + chalk.white(' │'));
|
|
68
|
+
console.log(chalk.gray(' │') + chalk.cyan(' 1. aiflow use PROJ-33') + chalk.gray(' │'));
|
|
69
|
+
console.log(chalk.gray(' │') + chalk.gray(' └─ pull title, desc, comments from │'));
|
|
70
|
+
console.log(chalk.gray(' │') + chalk.gray(' Backlog/Jira → current.json │'));
|
|
71
|
+
console.log(chalk.gray(' │') + chalk.white(' │'));
|
|
72
|
+
console.log(chalk.gray(' │') + chalk.cyan(' 2. aiflow prompt bug-fix') + chalk.gray(' │'));
|
|
73
|
+
console.log(chalk.gray(' │') + chalk.gray(' └─ generate AI prompt from context │'));
|
|
74
|
+
console.log(chalk.gray(' │') + chalk.gray(' + team rules → paste into Claude │'));
|
|
75
|
+
console.log(chalk.gray(' │') + chalk.white(' │'));
|
|
76
|
+
console.log(chalk.gray(' │') + chalk.cyan(' 3. claude (open Claude terminal)') + chalk.gray(' │'));
|
|
77
|
+
console.log(chalk.gray(' │') + chalk.gray(' └─ "Fix bug PROJ-33" (1 line) │'));
|
|
78
|
+
console.log(chalk.gray(' └──────────────────┬───────────────────┘'));
|
|
79
|
+
console.log(chalk.gray(' │'));
|
|
80
|
+
console.log(chalk.gray(' ┌──────────────────▼───────────────────┐'));
|
|
81
|
+
console.log(chalk.gray(' │') + chalk.bold.magenta(' Claude AI (automatic)') + chalk.gray(' │'));
|
|
82
|
+
console.log(chalk.gray(' │') + chalk.white(' │'));
|
|
83
|
+
console.log(chalk.gray(' │') + chalk.gray(' SessionStart hook injected superpowers │'));
|
|
84
|
+
console.log(chalk.gray(' │') + chalk.gray(' ↓ │'));
|
|
85
|
+
console.log(chalk.gray(' │') + chalk.gray(' Read CLAUDE.md (framework rules) │'));
|
|
86
|
+
console.log(chalk.gray(' │') + chalk.gray(' ↓ │'));
|
|
87
|
+
console.log(chalk.gray(' │') + chalk.gray(' Read context/current.json (ticket) │'));
|
|
88
|
+
console.log(chalk.gray(' │') + chalk.gray(' ↓ │'));
|
|
89
|
+
console.log(chalk.gray(' │') + chalk.gray(' Auto-detect task type → select skill │'));
|
|
90
|
+
console.log(chalk.gray(' │') + chalk.gray(' ↓ │'));
|
|
91
|
+
console.log(chalk.gray(' │') + chalk.gray(' Implement with team rules │'));
|
|
92
|
+
console.log(chalk.gray(' └────────────────────────────────────────┘'));
|
|
93
|
+
console.log();
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// ──────────────────────────────────────────────────────────────
|
|
97
|
+
// Step-by-step workflow
|
|
98
|
+
// ──────────────────────────────────────────────────────────────
|
|
99
|
+
|
|
100
|
+
function showWorkflow() {
|
|
101
|
+
console.log(chalk.bold.cyan(' 🚀 WORKFLOW STEP-BY-STEP\n'));
|
|
102
|
+
|
|
103
|
+
// Step 0: Install
|
|
104
|
+
console.log(chalk.bold.white(' Step 0 — Installation (One-time)'));
|
|
105
|
+
console.log(chalk.green(' npm install -g ai-flow-kit'));
|
|
106
|
+
console.log();
|
|
107
|
+
|
|
108
|
+
// Step 1: Init
|
|
109
|
+
console.log(chalk.bold.white(' Step 1 — Initialize project (Once per project)'));
|
|
110
|
+
console.log(chalk.green(' aiflow init --framework spring-boot --adapter backlog'));
|
|
111
|
+
console.log(chalk.gray(' → Creates .claude/, .rules/, CLAUDE.md, .mcp.json'));
|
|
112
|
+
console.log();
|
|
113
|
+
|
|
114
|
+
// Step 2: Load context
|
|
115
|
+
console.log(chalk.bold.white(' Step 2 — Load context from ticket (per task)'));
|
|
116
|
+
console.log(chalk.green(' aiflow use PROJ-33 --with-comments'));
|
|
117
|
+
console.log(chalk.green(' aiflow prompt bug-fix'));
|
|
118
|
+
console.log(chalk.green(' claude'));
|
|
119
|
+
console.log();
|
|
120
|
+
|
|
121
|
+
// Gate workflow
|
|
122
|
+
console.log(chalk.bold.white(' Step 3 — AI runs Strict Gate Workflow automatically'));
|
|
123
|
+
console.log();
|
|
124
|
+
console.log(chalk.yellow(' ⛩️ GATE 1') + chalk.gray(' — AI checks ticket for all 4 required components'));
|
|
125
|
+
console.log(chalk.gray(' If missing → ask one by one until complete'));
|
|
126
|
+
console.log(chalk.gray(' Developer types "continue" → move to Gate 2'));
|
|
127
|
+
console.log();
|
|
128
|
+
console.log(chalk.yellow(' ⛩️ GATE 2') + chalk.gray(' — AI generates detailed spec + plan'));
|
|
129
|
+
console.log(chalk.gray(' Developer reviews each section'));
|
|
130
|
+
console.log(chalk.gray(' Developer types "APPROVED" → move to Gate 3'));
|
|
131
|
+
console.log();
|
|
132
|
+
console.log(chalk.yellow(' ⛩️ GATE 3') + chalk.gray(' — AI generates code (TDD: tests first)'));
|
|
133
|
+
console.log(chalk.gray(' Automatic, developer only monitors'));
|
|
134
|
+
console.log();
|
|
135
|
+
console.log(chalk.yellow(' ⛩️ GATE 4') + chalk.gray(' — AI self-reviews + generates summary'));
|
|
136
|
+
console.log(chalk.gray(' Developer review → "APPROVED" or "BUG: ..."'));
|
|
137
|
+
console.log();
|
|
138
|
+
console.log(chalk.yellow(' ⛩️ GATE 5') + chalk.gray(' — Peer review → create PR → merge'));
|
|
139
|
+
console.log();
|
|
140
|
+
console.log(chalk.gray(' Full details: ') + chalk.green('cat AIFLOW.md'));
|
|
141
|
+
console.log();
|
|
142
|
+
|
|
143
|
+
// Frameworks supported
|
|
144
|
+
console.log(chalk.bold.white(' Frameworks: ') + chalk.gray('spring-boot │ reactjs │ nextjs │ vue-nuxt │ laravel'));
|
|
145
|
+
console.log(chalk.bold.white(' Adapters: ') + chalk.gray('backlog │ jira │ figma'));
|
|
146
|
+
console.log();
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// ──────────────────────────────────────────────────────────────
|
|
150
|
+
// Command reference
|
|
151
|
+
// ──────────────────────────────────────────────────────────────
|
|
152
|
+
|
|
153
|
+
function showCommands() {
|
|
154
|
+
console.log(chalk.bold.cyan(' 📋 COMMAND REFERENCE\n'));
|
|
155
|
+
|
|
156
|
+
const commands = [
|
|
157
|
+
{
|
|
158
|
+
group: 'Setup',
|
|
159
|
+
items: [
|
|
160
|
+
['aiflow init', '--framework <fw> --adapter <ad>', 'Initialize project'],
|
|
161
|
+
['aiflow doctor', '', 'Check setup health'],
|
|
162
|
+
['aiflow update', '', 'Update to the latest version'],
|
|
163
|
+
['aiflow remove', '', 'Remove ai-flow-kit from project'],
|
|
164
|
+
['aiflow remove', '--version <ver>', 'Remove a cached version'],
|
|
165
|
+
['aiflow remove', '--global', 'Uninstall global package'],
|
|
166
|
+
]
|
|
167
|
+
},
|
|
168
|
+
{
|
|
169
|
+
group: 'Workflow (use per task)',
|
|
170
|
+
items: [
|
|
171
|
+
['aiflow use <TICKET-ID>', '', 'Load context from Backlog/Jira'],
|
|
172
|
+
['aiflow use', '--manual', 'Enter context manually'],
|
|
173
|
+
['aiflow use', '--with-comments', 'Include all comments'],
|
|
174
|
+
['aiflow use', '--comments-last <n>', 'Only get last N comments'],
|
|
175
|
+
['aiflow prompt <type>', '', 'Generate AI prompt'],
|
|
176
|
+
['aiflow prompt', '--list', 'View all prompt types'],
|
|
177
|
+
['aiflow prompt', '--output <file>', 'Save prompt to file'],
|
|
178
|
+
['aiflow prompt', '--lang vietnamese', 'Prompt in Vietnamese'],
|
|
179
|
+
['aiflow detect "<description>"', '', 'Auto-detect task type'],
|
|
180
|
+
]
|
|
181
|
+
},
|
|
182
|
+
{
|
|
183
|
+
group: 'Context management',
|
|
184
|
+
items: [
|
|
185
|
+
['aiflow context show', '', 'View active context'],
|
|
186
|
+
['aiflow context list', '', 'List saved contexts'],
|
|
187
|
+
['aiflow context save <name>', '', 'Save current context'],
|
|
188
|
+
['aiflow context --load <name>', '', 'Load saved context'],
|
|
189
|
+
['aiflow context --delete <name>', '', 'Delete saved context'],
|
|
190
|
+
['aiflow context clear', '', 'Clear all contexts'],
|
|
191
|
+
]
|
|
192
|
+
},
|
|
193
|
+
{
|
|
194
|
+
group: 'Memory (team knowledge)',
|
|
195
|
+
items: [
|
|
196
|
+
['aiflow memory save <key> <value>', '', 'Save a note'],
|
|
197
|
+
['aiflow memory get <key>', '', 'Read a note'],
|
|
198
|
+
['aiflow memory list', '', 'List all notes'],
|
|
199
|
+
['aiflow memory search <query>', '', 'Search notes'],
|
|
200
|
+
['aiflow memory delete <key>', '', 'Delete a note'],
|
|
201
|
+
['aiflow memory clear', '', 'Clear all notes'],
|
|
202
|
+
]
|
|
203
|
+
},
|
|
204
|
+
{
|
|
205
|
+
group: 'Validation',
|
|
206
|
+
items: [
|
|
207
|
+
['aiflow validate <file>', '', 'Validate code against team rules'],
|
|
208
|
+
['aiflow validate <file>', '--fix', 'Auto-fix trailing whitespace'],
|
|
209
|
+
['aiflow validate <file>', '-r lenient', 'Only report critical errors'],
|
|
210
|
+
['aiflow validate <file>', '-r strict', 'Report all warnings'],
|
|
211
|
+
]
|
|
212
|
+
},
|
|
213
|
+
{
|
|
214
|
+
group: 'Help',
|
|
215
|
+
items: [
|
|
216
|
+
['aiflow guide', '', 'View this guide again'],
|
|
217
|
+
['aiflow guide', '--flow', 'Only view architecture & flow'],
|
|
218
|
+
['aiflow guide', '--commands', 'Only view command reference'],
|
|
219
|
+
['aiflow <command>', '--help', 'Help for each command'],
|
|
220
|
+
]
|
|
221
|
+
},
|
|
222
|
+
];
|
|
223
|
+
|
|
224
|
+
for (const { group, items } of commands) {
|
|
225
|
+
console.log(chalk.bold.white(` ${group}`));
|
|
226
|
+
for (const [cmd, opts, desc] of items) {
|
|
227
|
+
const cmdStr = chalk.green(cmd.padEnd(34));
|
|
228
|
+
const optStr = chalk.gray((opts || '').padEnd(22));
|
|
229
|
+
const descStr = chalk.white(desc);
|
|
230
|
+
console.log(` ${cmdStr}${optStr}${descStr}`);
|
|
231
|
+
}
|
|
232
|
+
console.log();
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
// ──────────────────────────────────────────────────────────────
|
|
237
|
+
// Prompt type guide
|
|
238
|
+
// ──────────────────────────────────────────────────────────────
|
|
239
|
+
|
|
240
|
+
function showPromptGuide() {
|
|
241
|
+
console.log(chalk.bold.cyan(' 🤖 PROMPT TYPES — WHEN TO USE?\n'));
|
|
242
|
+
|
|
243
|
+
const types = [
|
|
244
|
+
['bug-fix', 'Fixing bugs, crashes, regressions'],
|
|
245
|
+
['feature', 'Implementing new features (user stories)'],
|
|
246
|
+
['investigation', 'Investigating, analyzing root cause'],
|
|
247
|
+
['refactor', 'Improving code without changing behavior'],
|
|
248
|
+
['impact-analysis', 'Analyzing the impact of changes'],
|
|
249
|
+
['documentation', 'Writing docs, README, API reference'],
|
|
250
|
+
];
|
|
251
|
+
|
|
252
|
+
for (const [type, when] of types) {
|
|
253
|
+
console.log(` ${chalk.green(('aiflow prompt ' + type).padEnd(34))} ${chalk.gray(when)}`);
|
|
254
|
+
}
|
|
255
|
+
console.log();
|
|
256
|
+
|
|
257
|
+
console.log(chalk.bold.white(' Example complete workflow for a bug:\n'));
|
|
258
|
+
console.log(chalk.gray(' $ ') + chalk.green('aiflow use PROJ-33 --with-comments'));
|
|
259
|
+
console.log(chalk.gray(' ✓ Context loaded: PROJ-33 — Login button crash on iOS\n'));
|
|
260
|
+
console.log(chalk.gray(' $ ') + chalk.green('aiflow prompt bug-fix'));
|
|
261
|
+
console.log(chalk.gray(' ─────────────────────────────────────────────────────'));
|
|
262
|
+
console.log(chalk.gray(' # Fix Bug'));
|
|
263
|
+
console.log(chalk.gray(' **Task:** Investigate and fix the bug...'));
|
|
264
|
+
console.log(chalk.gray(' **Ticket:** PROJ-33'));
|
|
265
|
+
console.log(chalk.gray(' **Title:** Login button crash on iOS'));
|
|
266
|
+
console.log(chalk.gray(' ...team rules...'));
|
|
267
|
+
console.log(chalk.gray(' ─────────────────────────────────────────────────────\n'));
|
|
268
|
+
console.log(chalk.gray(' $ ') + chalk.green('claude'));
|
|
269
|
+
console.log(chalk.gray(' > Fix bug PROJ-33'));
|
|
270
|
+
console.log(chalk.gray(' → Claude automatically reads context, applies rules, invokes systematic-debugging skill\n'));
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
// ──────────────────────────────────────────────────────────────
|
|
274
|
+
// Footer
|
|
275
|
+
// ──────────────────────────────────────────────────────────────
|
|
276
|
+
|
|
277
|
+
function showFooter() {
|
|
278
|
+
console.log(chalk.blue('─'.repeat(62)));
|
|
279
|
+
console.log(chalk.gray(' View the guide anytime: ') + chalk.green('aiflow guide'));
|
|
280
|
+
console.log(chalk.gray(' Check setup health: ') + chalk.green('aiflow doctor'));
|
|
281
|
+
console.log(chalk.blue('─'.repeat(62)) + '\n');
|
|
282
|
+
}
|