@haposoft/cafekit 0.3.12 → 0.5.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 +83 -28
- package/bin/install.js +245 -3
- package/package.json +5 -3
- package/src/claude/agents/code-reviewer.md +14 -13
- package/src/claude/agents/debugger.md +1 -1
- package/src/claude/commands/review/codebase/parallel.md +1 -1
- package/src/claude/commands/review/codebase.md +2 -2
- package/src/claude/hooks/agent.cjs +203 -0
- package/src/claude/hooks/lib/color.cjs +95 -0
- package/src/claude/hooks/lib/config.cjs +831 -0
- package/src/claude/hooks/lib/context.cjs +616 -0
- package/src/claude/hooks/lib/counter.cjs +103 -0
- package/src/claude/hooks/lib/detect.cjs +474 -0
- package/src/claude/hooks/lib/git.cjs +143 -0
- package/src/claude/hooks/lib/parser.cjs +182 -0
- package/src/claude/hooks/session.cjs +360 -0
- package/src/claude/hooks/usage.cjs +179 -0
- package/src/claude/migration-manifest.json +29 -2
- package/src/claude/runtime.json +5 -0
- package/src/claude/settings/status.settings.json +54 -0
- package/src/claude/status.cjs +539 -0
- package/src/common/skills/code/SKILL.md +55 -0
- package/src/common/skills/code/references/execution-loop.md +21 -0
- package/src/common/skills/impact-analysis/SKILL.md +1 -1
- package/src/common/skills/impact-analysis/references/dependency-scouting.md +16 -15
- package/src/common/skills/inspector/SKILL.md +161 -0
- package/src/common/skills/inspector/references/external-gemini-inspection.md +169 -0
- package/src/common/skills/inspector/references/internal-inspection.md +173 -0
- package/src/common/skills/review/SKILL.md +46 -0
- package/src/common/skills/review/references/review-focus.md +28 -0
- package/src/common/skills/spec-design/SKILL.md +66 -0
- package/src/common/skills/spec-design/references/design-discovery.md +46 -0
- package/src/common/skills/spec-init/SKILL.md +61 -0
- package/src/common/skills/spec-requirements/SKILL.md +59 -0
- package/src/common/skills/spec-requirements/references/requirements-workflow.md +36 -0
- package/src/common/skills/spec-tasks/SKILL.md +60 -0
- package/src/common/skills/spec-tasks/references/task-sizing.md +36 -0
- package/src/common/skills/test/SKILL.md +40 -0
package/README.md
CHANGED
|
@@ -43,6 +43,44 @@ CafeKit is a **multi-platform** CLI tool that installs a structured workflow for
|
|
|
43
43
|
- **📦 No global install** - Use directly with `npx`
|
|
44
44
|
- **🚀 Future-proof** - Easy to add support for new AI editors
|
|
45
45
|
|
|
46
|
+
## Claude Code Statusline (Claude Code Only)
|
|
47
|
+
|
|
48
|
+
CafeKit automatically installs an enhanced statusline for Claude Code that provides real-time session context.
|
|
49
|
+
|
|
50
|
+
**What it shows:**
|
|
51
|
+
- **Context usage** - Percentage and token count (e.g., `23% 45K/200K`)
|
|
52
|
+
- **Session timer** - Elapsed time since session start
|
|
53
|
+
- **Git status** - Current branch and dirty state indicator
|
|
54
|
+
- **Active agents** - Count of running subagents
|
|
55
|
+
- **Todo items** - Count of pending tasks
|
|
56
|
+
|
|
57
|
+
**Installation:**
|
|
58
|
+
- Automatically installed when running `npx @haposoft/cafekit` in a Claude Code project
|
|
59
|
+
- Merges with existing `settings.json` configuration without overwriting user settings
|
|
60
|
+
- Safe to re-run - preserves non-CafeKit statusline configurations
|
|
61
|
+
- Upgrade mode (`--upgrade`) refreshes managed runtime files
|
|
62
|
+
|
|
63
|
+
**Configuration:**
|
|
64
|
+
The statusline is configured via `.claude/settings.json`:
|
|
65
|
+
```json
|
|
66
|
+
{
|
|
67
|
+
"statusLine": {
|
|
68
|
+
"type": "command",
|
|
69
|
+
"command": "node \"$CLAUDE_PROJECT_DIR/.claude/status.cjs\"",
|
|
70
|
+
"padding": 0
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
**Runtime files installed:**
|
|
76
|
+
- `.claude/status.cjs` - Main statusline script
|
|
77
|
+
- `.claude/hooks/session.cjs` - Session initialization hook
|
|
78
|
+
- `.claude/hooks/agent.cjs` - Subagent context injection hook
|
|
79
|
+
- `.claude/hooks/usage.cjs` - Usage tracking hook
|
|
80
|
+
- `.claude/hooks/lib/*.cjs` - Shared utilities (color, parser, git, config, etc.)
|
|
81
|
+
|
|
82
|
+
**Note:** This feature is Claude Code exclusive and not available for Antigravity.
|
|
83
|
+
|
|
46
84
|
## Installation
|
|
47
85
|
|
|
48
86
|
### Prerequisites
|
|
@@ -63,7 +101,8 @@ The installer will:
|
|
|
63
101
|
2. **Prompt** you to select platform if not detected
|
|
64
102
|
3. **Copy** workflow commands to the appropriate directory
|
|
65
103
|
4. **Install** shared skills for spec-driven development
|
|
66
|
-
5. **
|
|
104
|
+
5. **[Claude Code only]** Install unprefixed skill directories (`spec-init`, `spec-requirements`, `spec-design`, `spec-tasks`, `code`, `test`, `review`) that expose `hapo:`-prefixed skill names
|
|
105
|
+
6. **Ensure dependencies** for `code - test - review` by installing missing command/agent templates
|
|
67
106
|
|
|
68
107
|
Installer modes:
|
|
69
108
|
- **Default install mode**: `npx @haposoft/cafekit` (skip existing files)
|
|
@@ -72,33 +111,40 @@ Installer modes:
|
|
|
72
111
|
|
|
73
112
|
**Example output (Claude Code):**
|
|
74
113
|
```
|
|
75
|
-
CafeKit
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
114
|
+
CafeKit Installer v0.3.12
|
|
115
|
+
========================================
|
|
116
|
+
|
|
117
|
+
Installing for: Claude Code
|
|
118
|
+
Mode: install (skip existing files)
|
|
119
|
+
|
|
120
|
+
Claude Code (.claude/)
|
|
121
|
+
----------------------------------------
|
|
122
|
+
✓ Skill installed: specs
|
|
123
|
+
✓ Skill installed: spec-init
|
|
124
|
+
✓ Skill installed: spec-requirements
|
|
125
|
+
✓ Skill installed: spec-design
|
|
126
|
+
✓ Skill installed: spec-tasks
|
|
127
|
+
✓ Skill installed: code
|
|
128
|
+
✓ Skill installed: test
|
|
129
|
+
✓ Skill installed: review
|
|
130
|
+
✓ Copied: spec-init.md
|
|
131
|
+
✓ Copied: spec-requirements.md
|
|
132
|
+
...
|
|
133
|
+
|
|
134
|
+
╔════════════════════════════════════════════════════════╗
|
|
135
|
+
║ Installation Complete! ║
|
|
136
|
+
╚════════════════════════════════════════════════════════╝
|
|
137
|
+
|
|
138
|
+
Installed Skills: Yes ✓
|
|
98
139
|
|
|
99
140
|
Next steps:
|
|
100
|
-
|
|
101
|
-
|
|
141
|
+
1. Start your AI editor
|
|
142
|
+
|
|
143
|
+
For Claude Code:
|
|
144
|
+
Run: /spec-init <feature-name>
|
|
145
|
+
Or use skill: /hapo:spec-init <feature-description>
|
|
146
|
+
|
|
147
|
+
2. Follow the workflow: requirements - design - tasks - code - test - review
|
|
102
148
|
|
|
103
149
|
Documentation: https://github.com/haposoft/cafekit
|
|
104
150
|
```
|
|
@@ -565,7 +611,15 @@ User clicks -> dispatch action -> update context -> localStorage -> re-render
|
|
|
565
611
|
│ ├── spec-status.md
|
|
566
612
|
│ └── docs.md # Docs workflows
|
|
567
613
|
└── skills/
|
|
568
|
-
|
|
614
|
+
├── specs/
|
|
615
|
+
├── impact-analysis/
|
|
616
|
+
├── spec-init/
|
|
617
|
+
├── spec-requirements/
|
|
618
|
+
├── spec-design/
|
|
619
|
+
├── spec-tasks/
|
|
620
|
+
├── code/
|
|
621
|
+
├── test/
|
|
622
|
+
└── review/
|
|
569
623
|
```
|
|
570
624
|
|
|
571
625
|
**Antigravity** (`.agent/`):
|
|
@@ -583,7 +637,8 @@ User clicks -> dispatch action -> update context -> localStorage -> re-render
|
|
|
583
637
|
│ ├── docs-init.md # Docs workflows
|
|
584
638
|
│ └── docs-update.md
|
|
585
639
|
├── skills/
|
|
586
|
-
│
|
|
640
|
+
│ ├── specs/
|
|
641
|
+
│ └── impact-analysis/
|
|
587
642
|
└── rules/
|
|
588
643
|
└── GEMINI.md # System rules (always_on)
|
|
589
644
|
```
|
package/bin/install.js
CHANGED
|
@@ -17,8 +17,16 @@
|
|
|
17
17
|
const fs = require('fs');
|
|
18
18
|
const path = require('path');
|
|
19
19
|
const readline = require('readline');
|
|
20
|
+
const { execSync } = require('child_process');
|
|
20
21
|
const packageJson = require('../package.json');
|
|
21
22
|
|
|
23
|
+
function validateManifestV2(manifest) {
|
|
24
|
+
if (!manifest || manifest.version !== 2) return false;
|
|
25
|
+
if (!manifest.runtime?.files || !Array.isArray(manifest.runtime.files)) return false;
|
|
26
|
+
if (!manifest.settings?.template) return false;
|
|
27
|
+
return true;
|
|
28
|
+
}
|
|
29
|
+
|
|
22
30
|
function loadClaudeMigrationManifest() {
|
|
23
31
|
const manifestPath = path.join(__dirname, '../src/claude/migration-manifest.json');
|
|
24
32
|
|
|
@@ -27,7 +35,15 @@ function loadClaudeMigrationManifest() {
|
|
|
27
35
|
}
|
|
28
36
|
|
|
29
37
|
try {
|
|
30
|
-
|
|
38
|
+
const manifest = JSON.parse(fs.readFileSync(manifestPath, 'utf8'));
|
|
39
|
+
|
|
40
|
+
if (!validateManifestV2(manifest)) {
|
|
41
|
+
console.error('✗ Invalid manifest v2 schema - missing required fields');
|
|
42
|
+
console.error(' Expected: version=2, runtime.files[], settings.template');
|
|
43
|
+
process.exit(1);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
return manifest;
|
|
31
47
|
} catch (error) {
|
|
32
48
|
console.warn(`⚠ Failed to parse Claude migration manifest: ${error.message}`);
|
|
33
49
|
return null;
|
|
@@ -472,8 +488,8 @@ function copyPlatformFiles(platformKey, results, options = {}) {
|
|
|
472
488
|
if (platformKey === 'claude') {
|
|
473
489
|
requiredSkills = CLAUDE_MIGRATION_MANIFEST?.skills?.required || [];
|
|
474
490
|
} else if (platformKey === 'antigravity') {
|
|
475
|
-
// Antigravity also needs impact-analysis
|
|
476
|
-
requiredSkills = ['impact-analysis'];
|
|
491
|
+
// Antigravity also needs shared investigation and impact-analysis skills
|
|
492
|
+
requiredSkills = ['impact-analysis', 'debug'];
|
|
477
493
|
}
|
|
478
494
|
|
|
479
495
|
requiredSkills
|
|
@@ -649,6 +665,224 @@ function copyGeminiFile(platformKey, results, options = {}) {
|
|
|
649
665
|
}
|
|
650
666
|
}
|
|
651
667
|
|
|
668
|
+
// Copy Claude runtime files (statusline bundle)
|
|
669
|
+
function copyClaudeRuntimeFiles(platformKey, results, options = {}) {
|
|
670
|
+
if (platformKey !== 'claude') return;
|
|
671
|
+
|
|
672
|
+
const manifest = CLAUDE_MIGRATION_MANIFEST;
|
|
673
|
+
if (!manifest?.runtime?.files) return;
|
|
674
|
+
|
|
675
|
+
const shouldOverwriteManagedFiles = Boolean(options.upgrade);
|
|
676
|
+
const srcBase = path.join(__dirname, '../src/claude');
|
|
677
|
+
const targetBase = path.join(PLATFORMS.claude.folder);
|
|
678
|
+
|
|
679
|
+
manifest.runtime.files.forEach(relPath => {
|
|
680
|
+
const srcPath = path.join(srcBase, relPath);
|
|
681
|
+
const targetPath = path.join(targetBase, relPath);
|
|
682
|
+
|
|
683
|
+
if (!fs.existsSync(srcPath)) {
|
|
684
|
+
console.log(` ⚠ Runtime file not found: ${relPath}`);
|
|
685
|
+
results.missingDependencies++;
|
|
686
|
+
return;
|
|
687
|
+
}
|
|
688
|
+
|
|
689
|
+
const targetExists = fs.existsSync(targetPath);
|
|
690
|
+
const shouldCopy = shouldOverwriteManagedFiles || !targetExists;
|
|
691
|
+
|
|
692
|
+
if (shouldCopy) {
|
|
693
|
+
fs.mkdirSync(path.dirname(targetPath), { recursive: true });
|
|
694
|
+
fs.copyFileSync(srcPath, targetPath);
|
|
695
|
+
|
|
696
|
+
if (targetExists) {
|
|
697
|
+
console.log(` ↻ Runtime updated: ${relPath}`);
|
|
698
|
+
results.updated++;
|
|
699
|
+
} else {
|
|
700
|
+
console.log(` ✓ Runtime installed: ${relPath}`);
|
|
701
|
+
results.copied++;
|
|
702
|
+
}
|
|
703
|
+
} else {
|
|
704
|
+
results.skipped++;
|
|
705
|
+
}
|
|
706
|
+
});
|
|
707
|
+
}
|
|
708
|
+
|
|
709
|
+
// Merge Claude settings.json
|
|
710
|
+
function mergeClaudeSettings(platformKey, results, options = {}) {
|
|
711
|
+
if (platformKey !== 'claude') return;
|
|
712
|
+
|
|
713
|
+
const manifest = CLAUDE_MIGRATION_MANIFEST;
|
|
714
|
+
if (!manifest?.settings?.template) return;
|
|
715
|
+
|
|
716
|
+
const templatePath = path.join(__dirname, '../src/claude', manifest.settings.template);
|
|
717
|
+
const targetPath = path.join(PLATFORMS.claude.folder, 'settings.json');
|
|
718
|
+
|
|
719
|
+
if (!fs.existsSync(templatePath)) {
|
|
720
|
+
console.log(` ⚠ Settings template not found: ${manifest.settings.template}`);
|
|
721
|
+
return;
|
|
722
|
+
}
|
|
723
|
+
|
|
724
|
+
const managedSettings = JSON.parse(fs.readFileSync(templatePath, 'utf8'));
|
|
725
|
+
let existingSettings = {};
|
|
726
|
+
|
|
727
|
+
if (fs.existsSync(targetPath)) {
|
|
728
|
+
existingSettings = JSON.parse(fs.readFileSync(targetPath, 'utf8'));
|
|
729
|
+
}
|
|
730
|
+
|
|
731
|
+
const mergedSettings = { ...existingSettings };
|
|
732
|
+
|
|
733
|
+
// Merge statusLine
|
|
734
|
+
if (managedSettings.statusLine) {
|
|
735
|
+
const existingCommand = existingSettings.statusLine?.command || '';
|
|
736
|
+
const isCafeKitOwned = existingCommand.includes('status.cjs') || existingCommand.includes('statusline.cjs');
|
|
737
|
+
|
|
738
|
+
if (options.upgrade || !existingSettings.statusLine || isCafeKitOwned) {
|
|
739
|
+
mergedSettings.statusLine = managedSettings.statusLine;
|
|
740
|
+
console.log(` ✓ Settings: statusLine merged`);
|
|
741
|
+
}
|
|
742
|
+
}
|
|
743
|
+
|
|
744
|
+
// Merge hooks
|
|
745
|
+
if (managedSettings.hooks) {
|
|
746
|
+
mergedSettings.hooks = mergedSettings.hooks || {};
|
|
747
|
+
|
|
748
|
+
Object.keys(managedSettings.hooks).forEach(eventName => {
|
|
749
|
+
const managedHooks = managedSettings.hooks[eventName];
|
|
750
|
+
const existingHooks = mergedSettings.hooks[eventName] || [];
|
|
751
|
+
const mergedHooks = [...existingHooks];
|
|
752
|
+
|
|
753
|
+
managedHooks.forEach(managedHook => {
|
|
754
|
+
const managedCommand = managedHook.hooks?.[0]?.command || '';
|
|
755
|
+
const isDuplicate = mergedHooks.some(existingHook => {
|
|
756
|
+
return existingHook.hooks?.some(h => h.command === managedCommand);
|
|
757
|
+
});
|
|
758
|
+
|
|
759
|
+
if (!isDuplicate) {
|
|
760
|
+
mergedHooks.push(managedHook);
|
|
761
|
+
console.log(` ✓ Settings: hook ${eventName} merged`);
|
|
762
|
+
}
|
|
763
|
+
});
|
|
764
|
+
|
|
765
|
+
mergedSettings.hooks[eventName] = mergedHooks;
|
|
766
|
+
});
|
|
767
|
+
}
|
|
768
|
+
|
|
769
|
+
fs.writeFileSync(targetPath, JSON.stringify(mergedSettings, null, 2), 'utf8');
|
|
770
|
+
}
|
|
771
|
+
|
|
772
|
+
// ═══════════════════════════════════════════════════════════
|
|
773
|
+
// GEMINI CLI SETUP
|
|
774
|
+
// ═══════════════════════════════════════════════════════════
|
|
775
|
+
|
|
776
|
+
function checkGeminiCLI() {
|
|
777
|
+
try {
|
|
778
|
+
execSync('which gemini', { stdio: 'ignore' });
|
|
779
|
+
return true;
|
|
780
|
+
} catch {
|
|
781
|
+
return false;
|
|
782
|
+
}
|
|
783
|
+
}
|
|
784
|
+
|
|
785
|
+
function installGeminiCLI() {
|
|
786
|
+
console.log('\n⚙ Installing gemini-cli...');
|
|
787
|
+
try {
|
|
788
|
+
execSync('npm install -g @google/generative-ai-cli', { stdio: 'inherit' });
|
|
789
|
+
console.log(' ✓ gemini-cli installed successfully');
|
|
790
|
+
return true;
|
|
791
|
+
} catch (error) {
|
|
792
|
+
console.log(' ✗ Failed to install gemini-cli automatically');
|
|
793
|
+
console.log(' Please run manually: npm install -g @google/generative-ai-cli');
|
|
794
|
+
return false;
|
|
795
|
+
}
|
|
796
|
+
}
|
|
797
|
+
|
|
798
|
+
async function promptInstallGemini() {
|
|
799
|
+
const rl = readline.createInterface({
|
|
800
|
+
input: process.stdin,
|
|
801
|
+
output: process.stdout
|
|
802
|
+
});
|
|
803
|
+
|
|
804
|
+
console.log('\n📦 Optional: Gemini CLI Installation');
|
|
805
|
+
console.log(' hapo:inspect with ext mode requires gemini-cli');
|
|
806
|
+
console.log(' • Install now: Auto-install and configure API key');
|
|
807
|
+
console.log(' • Skip: You can still use hapo:inspect in internal mode');
|
|
808
|
+
console.log();
|
|
809
|
+
|
|
810
|
+
return new Promise((resolve) => {
|
|
811
|
+
rl.question('Install gemini-cli? (Y/n): ', (answer) => {
|
|
812
|
+
rl.close();
|
|
813
|
+
const response = answer.trim().toLowerCase();
|
|
814
|
+
resolve(response === '' || response === 'y' || response === 'yes');
|
|
815
|
+
});
|
|
816
|
+
});
|
|
817
|
+
}
|
|
818
|
+
|
|
819
|
+
async function promptGeminiAPIKey() {
|
|
820
|
+
const rl = readline.createInterface({
|
|
821
|
+
input: process.stdin,
|
|
822
|
+
output: process.stdout
|
|
823
|
+
});
|
|
824
|
+
|
|
825
|
+
console.log('\n📝 Gemini API Key Configuration');
|
|
826
|
+
console.log(' Get your API key: https://aistudio.google.com/apikey');
|
|
827
|
+
console.log();
|
|
828
|
+
|
|
829
|
+
return new Promise((resolve) => {
|
|
830
|
+
rl.question('Enter your Gemini API key (or press Enter to skip): ', (answer) => {
|
|
831
|
+
rl.close();
|
|
832
|
+
resolve(answer.trim());
|
|
833
|
+
});
|
|
834
|
+
});
|
|
835
|
+
}
|
|
836
|
+
|
|
837
|
+
function configureGeminiKey(apiKey) {
|
|
838
|
+
try {
|
|
839
|
+
execSync(`gemini config set-key ${apiKey}`, { stdio: 'inherit' });
|
|
840
|
+
console.log(' ✓ Gemini API key configured successfully');
|
|
841
|
+
return true;
|
|
842
|
+
} catch (error) {
|
|
843
|
+
console.log(' ✗ Failed to configure Gemini API key');
|
|
844
|
+
console.log(' Please run manually: gemini config set-key YOUR_API_KEY');
|
|
845
|
+
return false;
|
|
846
|
+
}
|
|
847
|
+
}
|
|
848
|
+
|
|
849
|
+
async function setupGeminiCLI() {
|
|
850
|
+
const hasGemini = checkGeminiCLI();
|
|
851
|
+
|
|
852
|
+
if (hasGemini) {
|
|
853
|
+
console.log(' ✓ gemini-cli already installed');
|
|
854
|
+
return;
|
|
855
|
+
}
|
|
856
|
+
|
|
857
|
+
const shouldInstall = await promptInstallGemini();
|
|
858
|
+
|
|
859
|
+
if (!shouldInstall) {
|
|
860
|
+
console.log('\n ℹ Skipped gemini-cli installation');
|
|
861
|
+
console.log(' • hapo:inspect will work in internal mode (default)');
|
|
862
|
+
console.log(' • To install later: npm install -g @google/generative-ai-cli');
|
|
863
|
+
return;
|
|
864
|
+
}
|
|
865
|
+
|
|
866
|
+
console.log('\n⚙ Installing gemini-cli...');
|
|
867
|
+
const installed = installGeminiCLI();
|
|
868
|
+
|
|
869
|
+
if (installed) {
|
|
870
|
+
const apiKey = await promptGeminiAPIKey();
|
|
871
|
+
|
|
872
|
+
if (apiKey) {
|
|
873
|
+
configureGeminiKey(apiKey);
|
|
874
|
+
} else {
|
|
875
|
+
console.log('\n📝 Skipped API key configuration');
|
|
876
|
+
console.log(' Configure later with: gemini config set-key YOUR_API_KEY');
|
|
877
|
+
}
|
|
878
|
+
} else {
|
|
879
|
+
console.log('\n📝 Manual installation steps:');
|
|
880
|
+
console.log(' 1. npm install -g @google/generative-ai-cli');
|
|
881
|
+
console.log(' 2. Get API key: https://aistudio.google.com/apikey');
|
|
882
|
+
console.log(' 3. gemini config set-key YOUR_API_KEY');
|
|
883
|
+
}
|
|
884
|
+
}
|
|
885
|
+
|
|
652
886
|
// ═══════════════════════════════════════════════════════════
|
|
653
887
|
// MAIN
|
|
654
888
|
// ═══════════════════════════════════════════════════════════
|
|
@@ -718,6 +952,8 @@ async function main() {
|
|
|
718
952
|
// Copy ROUTING.md for Claude Code platform
|
|
719
953
|
if (platformKey === 'claude') {
|
|
720
954
|
copyRoutingFile(platformKey, results, installerOptions);
|
|
955
|
+
copyClaudeRuntimeFiles(platformKey, results, installerOptions);
|
|
956
|
+
mergeClaudeSettings(platformKey, results, installerOptions);
|
|
721
957
|
}
|
|
722
958
|
|
|
723
959
|
// Copy GEMINI.md for Antigravity platform
|
|
@@ -729,6 +965,9 @@ async function main() {
|
|
|
729
965
|
console.log();
|
|
730
966
|
}
|
|
731
967
|
|
|
968
|
+
// Setup Gemini CLI for hapo:inspect ext mode
|
|
969
|
+
setupGeminiCLI();
|
|
970
|
+
|
|
732
971
|
// Note: CLAUDE.md and docs/ are generated via /docs init command
|
|
733
972
|
|
|
734
973
|
// Summary
|
|
@@ -756,6 +995,9 @@ async function main() {
|
|
|
756
995
|
const platform = PLATFORMS[platformKey];
|
|
757
996
|
console.log(`\n For ${platform.name}:`);
|
|
758
997
|
console.log(` Run: ${platform.commandPrefix}spec-init <feature-name>`);
|
|
998
|
+
if (platformKey === 'claude') {
|
|
999
|
+
console.log(' Or use skill: /hapo:spec-init <feature-description>');
|
|
1000
|
+
}
|
|
759
1001
|
}
|
|
760
1002
|
|
|
761
1003
|
console.log('\n 2. Follow the workflow: requirements - design - tasks - code - test - review');
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@haposoft/cafekit",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Spec-Driven Development workflow for AI coding assistants. Supports Claude Code and Antigravity with spec-first
|
|
3
|
+
"version": "0.5.0",
|
|
4
|
+
"description": "Spec-Driven Development workflow for AI coding assistants. Supports Claude Code and Antigravity with spec-first workflows plus Claude Code hapo: skills.",
|
|
5
5
|
"author": "Haposoft <nghialt@haposoft.com>",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"private": false,
|
|
@@ -32,7 +32,9 @@
|
|
|
32
32
|
"ai-coding",
|
|
33
33
|
"specification",
|
|
34
34
|
"requirements",
|
|
35
|
-
"sdd"
|
|
35
|
+
"sdd",
|
|
36
|
+
"skills",
|
|
37
|
+
"hapo"
|
|
36
38
|
],
|
|
37
39
|
"engines": {
|
|
38
40
|
"node": ">=18.0.0"
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: code-reviewer
|
|
3
|
-
description: "Comprehensive code review with
|
|
3
|
+
description: "Comprehensive code review with inspect-based edge case detection. Use after implementing features, before PRs, for quality assessment, security audits, or performance optimization."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
Senior software engineer specializing in code quality assessment. Expertise in TypeScript, JavaScript, Dart (Flutter), security, and performance.
|
|
7
7
|
|
|
8
|
-
**IMPORTANT**: Ensure token efficiency. Use `
|
|
8
|
+
**IMPORTANT**: Ensure token efficiency. Use `hapo:inspector` and `code-review` protocols for edge-case discovery before review.
|
|
9
9
|
|
|
10
10
|
## Core Responsibilities
|
|
11
11
|
|
|
@@ -18,36 +18,37 @@ Senior software engineer specializing in code quality assessment. Expertise in T
|
|
|
18
18
|
|
|
19
19
|
## Review Process
|
|
20
20
|
|
|
21
|
-
### 1. Edge Case
|
|
21
|
+
### 1. Edge Case Inspection (NEW - Do First)
|
|
22
22
|
|
|
23
|
-
Before reviewing,
|
|
23
|
+
Before reviewing, inspect for edge cases the diff doesn't show:
|
|
24
24
|
|
|
25
25
|
```bash
|
|
26
26
|
git diff --name-only HEAD~1 # Get changed files
|
|
27
27
|
```
|
|
28
28
|
|
|
29
|
-
Use `/
|
|
29
|
+
Use `/hapo:inspector` with an edge-case-focused prompt:
|
|
30
30
|
```
|
|
31
|
-
|
|
31
|
+
Inspect edge cases for recent changes.
|
|
32
|
+
Scope: {directories around changed files}
|
|
32
33
|
Changed: {files}
|
|
33
34
|
Find: affected dependents, data flow risks, boundary conditions, async races, state mutations
|
|
34
35
|
```
|
|
35
36
|
|
|
36
|
-
Document
|
|
37
|
+
Document inspect findings for inclusion in review.
|
|
37
38
|
|
|
38
39
|
### 2. Initial Analysis
|
|
39
40
|
|
|
40
41
|
- Read `.specs/<feature>/tasks.md` and related changed files
|
|
41
42
|
- Focus on recently changed files (use `git diff`)
|
|
42
43
|
- For full codebase: use `repomix` to compact, then analyze
|
|
43
|
-
- Wait for
|
|
44
|
+
- Wait for inspect results before proceeding
|
|
44
45
|
|
|
45
46
|
### 3. Systematic Review
|
|
46
47
|
|
|
47
48
|
| Area | Focus |
|
|
48
49
|
|------|-------|
|
|
49
50
|
| Structure | Organization, modularity |
|
|
50
|
-
| Logic | Correctness, edge cases from
|
|
51
|
+
| Logic | Correctness, edge cases from inspect |
|
|
51
52
|
| Types | Safety, error handling |
|
|
52
53
|
| Performance | Bottlenecks, inefficiencies |
|
|
53
54
|
| Security | Vulnerabilities, data exposure |
|
|
@@ -79,7 +80,7 @@ Mark reviewed task status and add next steps in workflow handoff.
|
|
|
79
80
|
- Files: [list]
|
|
80
81
|
- LOC: [count]
|
|
81
82
|
- Focus: [recent/specific/full]
|
|
82
|
-
-
|
|
83
|
+
- Inspect findings: [edge cases discovered]
|
|
83
84
|
|
|
84
85
|
### Overall Assessment
|
|
85
86
|
[Brief quality overview]
|
|
@@ -96,8 +97,8 @@ Mark reviewed task status and add next steps in workflow handoff.
|
|
|
96
97
|
### Low Priority
|
|
97
98
|
[Style, minor opts]
|
|
98
99
|
|
|
99
|
-
### Edge Cases Found by
|
|
100
|
-
[List issues from
|
|
100
|
+
### Edge Cases Found by Inspect
|
|
101
|
+
[List issues from inspection phase]
|
|
101
102
|
|
|
102
103
|
### Positive Observations
|
|
103
104
|
[Good practices noted]
|
|
@@ -122,7 +123,7 @@ Mark reviewed task status and add next steps in workflow handoff.
|
|
|
122
123
|
- No AI attribution in code/commits
|
|
123
124
|
- Security best practices priority
|
|
124
125
|
- **Verify spec task checklist completion**
|
|
125
|
-
- **
|
|
126
|
+
- **Inspect edge cases BEFORE reviewing**
|
|
126
127
|
|
|
127
128
|
## Report Output
|
|
128
129
|
|
|
@@ -41,7 +41,7 @@ When investigating issues, you will:
|
|
|
41
41
|
- **When you need to understand the project structure:**
|
|
42
42
|
- Read `docs/codebase-summary.md` if it exists & up-to-date (less than 2 days old)
|
|
43
43
|
- Otherwise, only use the `repomix` command to generate comprehensive codebase summary of the current project at `./repomix-output.xml` and create/update a codebase summary file at `./codebase-summary.md`
|
|
44
|
-
- **IMPORTANT**: ONLY process this following step `codebase-summary.md` doesn't contain what you need: use `/
|
|
44
|
+
- **IMPORTANT**: ONLY process this following step `codebase-summary.md` doesn't contain what you need: use `/hapo:inspector ext` for scoped Gemini discovery or `/hapo:inspector` for scoped internal discovery to inspect only the relevant codebase scopes and find the files needed to complete the task
|
|
45
45
|
- When you are given a Github repository URL, use `repomix --remote <github-repo-url>` bash command to generate a fresh codebase summary:
|
|
46
46
|
```bash
|
|
47
47
|
# usage: repomix --remote <github-repo-url>
|
|
@@ -13,7 +13,7 @@ argument-hint: [scope-or-prompt]
|
|
|
13
13
|
|
|
14
14
|
Main agent deeply analyzes the scope to LIST all potential edge cases FIRST:
|
|
15
15
|
- Read `codebase-summary.md` for context
|
|
16
|
-
- Use `/
|
|
16
|
+
- Use `/hapo:inspector ext` for scoped Gemini discovery; if external mode is unavailable or not appropriate, fall back to `/hapo:inspector` for scoped internal discovery
|
|
17
17
|
- **Think exhaustively** about what could go wrong:
|
|
18
18
|
- Null/undefined scenarios
|
|
19
19
|
- Boundary conditions (off-by-one, empty, max values)
|
|
@@ -24,7 +24,7 @@ Think harder to scan the codebase and analyze it follow the Orchestration Protoc
|
|
|
24
24
|
|
|
25
25
|
* Use 2 `researcher` subagents in parallel to search up to max 5 sources for the user's request, idea validation, best practices, challenges, and find the best possible solutions.
|
|
26
26
|
* Keep every research markdown report concise (≤150 lines) while covering all requested topics and citations.
|
|
27
|
-
* Use `/
|
|
27
|
+
* Use `/hapo:inspector ext` for scoped Gemini discovery or `/hapo:inspector` for scoped internal discovery to search the codebase for files needed to complete the task
|
|
28
28
|
|
|
29
29
|
### Code Review
|
|
30
30
|
|
|
@@ -34,7 +34,7 @@ Think harder to scan the codebase and analyze it follow the Orchestration Protoc
|
|
|
34
34
|
* **IMPORTANT:** Sacrifice grammar for the sake of concision when writing outputs.
|
|
35
35
|
|
|
36
36
|
### Plan
|
|
37
|
-
* Use `planner` subagent to analyze reports from `researcher` and `
|
|
37
|
+
* Use `planner` subagent to analyze reports from `researcher` and `hapo:inspector` discovery runs to create an improvement plan following the progressive disclosure structure:
|
|
38
38
|
- Create a directory using naming pattern from `## Naming` section.
|
|
39
39
|
- Save the overview access point at `plan.md`, keep it generic, under 80 lines, and list each phase with status/progress and links.
|
|
40
40
|
- For each phase, add `phase-XX-phase-name.md` files containing sections (Context links, Overview with date/priority/statuses, Key Insights, Requirements, Architecture, Related code files, Implementation Steps, Todo list, Success Criteria, Risk Assessment, Security Considerations, Next steps).
|