@haposoft/cafekit 0.8.15 → 0.8.17
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 +43 -4
- package/bin/install.js +698 -114
- package/package.json +1 -1
- package/src/claude/CLAUDE.md +4 -0
- package/src/claude/hooks/lib/config.cjs +0 -1
- package/src/claude/hooks/lib/context.cjs +2 -2
- package/src/claude/hooks/rules.cjs +7 -0
- package/src/claude/migration-manifest.json +11 -3
- package/src/claude/rules/skill-domain-routing.md +87 -0
- package/src/claude/rules/skill-workflow-routing.md +84 -0
- package/src/claude/scripts/generate-skill-catalog.cjs +180 -0
- package/src/claude/settings/settings.json +0 -4
- package/src/opencode/AGENTS.md +140 -0
- package/src/antigravity/GEMINI.md +0 -162
- package/src/antigravity/workflows/code.md +0 -16
- package/src/antigravity/workflows/docs-init.md +0 -432
- package/src/antigravity/workflows/docs-update.md +0 -245
- package/src/antigravity/workflows/impact-analysis-output-example.md +0 -313
- package/src/antigravity/workflows/impact-analysis.md +0 -730
- package/src/antigravity/workflows/review.md +0 -15
- package/src/antigravity/workflows/spec-design.md +0 -220
- package/src/antigravity/workflows/spec-init.md +0 -78
- package/src/antigravity/workflows/spec-requirements.md +0 -122
- package/src/antigravity/workflows/spec-status.md +0 -95
- package/src/antigravity/workflows/spec-tasks.md +0 -156
- package/src/antigravity/workflows/spec-validate.md +0 -106
- package/src/antigravity/workflows/test.md +0 -13
- package/src/claude/hooks/lib/skill-router-routes.cjs +0 -196
- package/src/claude/hooks/skill-router.cjs +0 -68
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@haposoft/cafekit",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.17",
|
|
4
4
|
"description": "Claude Code-first spec-driven workflow for AI coding assistants. Bundles CafeKit hapo: skills, runtime hooks, agents, and installer scaffolding.",
|
|
5
5
|
"author": "Haposoft <nghialt@haposoft.com>",
|
|
6
6
|
"license": "MIT",
|
package/src/claude/CLAUDE.md
CHANGED
|
@@ -88,6 +88,8 @@ Consult these when the task touches the relevant area:
|
|
|
88
88
|
|
|
89
89
|
- Primary workflow: `./.claude/rules/workflow.md`
|
|
90
90
|
- Development rules: `./.claude/rules/ai-dev-rules.md`
|
|
91
|
+
- Skill workflow routing: `./.claude/rules/skill-workflow-routing.md`
|
|
92
|
+
- Skill domain routing: `./.claude/rules/skill-domain-routing.md`
|
|
91
93
|
- Subagent coordination: `./.claude/rules/orchestrator.md`
|
|
92
94
|
- Docs maintenance: `./.claude/rules/manage-docs.md`
|
|
93
95
|
- State sync: `./.claude/rules/state-sync.md`
|
|
@@ -97,6 +99,8 @@ Consult these when the task touches the relevant area:
|
|
|
97
99
|
## Skill And Script Use
|
|
98
100
|
|
|
99
101
|
- Evaluate the available skills catalog before work and activate the relevant skill(s).
|
|
102
|
+
- Use `./.claude/rules/skill-workflow-routing.md` and `./.claude/rules/skill-domain-routing.md` to choose skills. CafeKit does not auto-route prompts through a scoring hook.
|
|
103
|
+
- When needed, run `node .claude/scripts/generate-skill-catalog.cjs --skills` to inspect the installed skill catalog.
|
|
100
104
|
- If there is a reasonable chance a skill applies, prefer the skill workflow over ad hoc execution.
|
|
101
105
|
- If modifying skills, edit the current project/runtime files, not `~/.claude/skills` directly.
|
|
102
106
|
- Run Python skill scripts with the skill venv:
|
|
@@ -358,7 +358,7 @@ function buildRulesSection({ devRulesPath, catalogScript, skillsVenv, plansPath,
|
|
|
358
358
|
lines.push(`- **IMPORTANT:** DO NOT create markdown files outside of "${plansRef}" or "${docsRef}" UNLESS the user explicitly requests it.`);
|
|
359
359
|
|
|
360
360
|
if (catalogScript) {
|
|
361
|
-
lines.push(`- Activate skills:
|
|
361
|
+
lines.push(`- Activate skills: Use \`.claude/rules/skill-workflow-routing.md\` and \`.claude/rules/skill-domain-routing.md\`; run \`node ${catalogScript} --skills\` when you need a generated skills catalog.`);
|
|
362
362
|
}
|
|
363
363
|
|
|
364
364
|
if (skillsVenv) {
|
|
@@ -525,7 +525,7 @@ function buildReminderContext({ sessionId, config, staticEnv, configDirName = '.
|
|
|
525
525
|
|
|
526
526
|
// Resolve paths
|
|
527
527
|
const devRulesPath = resolveRulesPath('ai-dev-rules.md', configDirName);
|
|
528
|
-
const catalogScript = resolveScriptPath('
|
|
528
|
+
const catalogScript = resolveScriptPath('generate-skill-catalog.cjs', configDirName);
|
|
529
529
|
const skillsVenv = resolveSkillsVenv(configDirName);
|
|
530
530
|
|
|
531
531
|
// Build plan context
|
|
@@ -91,6 +91,13 @@ try {
|
|
|
91
91
|
lines.push('- Ensure token efficiency while maintaining high quality.');
|
|
92
92
|
lines.push('');
|
|
93
93
|
|
|
94
|
+
// Skill routing: advisory rule docs, no automatic prompt router.
|
|
95
|
+
lines.push('## Skill Routing');
|
|
96
|
+
lines.push('- Choose skills from intent using `.claude/rules/skill-workflow-routing.md` and `.claude/rules/skill-domain-routing.md`.');
|
|
97
|
+
lines.push('- If needed, run `node .claude/scripts/generate-skill-catalog.cjs --skills` to inspect installed skills.');
|
|
98
|
+
lines.push('- Explicit user commands and direct-answer requests override routing suggestions.');
|
|
99
|
+
lines.push('');
|
|
100
|
+
|
|
94
101
|
// Modularization
|
|
95
102
|
lines.push('## [IMPORTANT] Consider Modularization:');
|
|
96
103
|
lines.push('- If a file exceeds 200 lines, consider splitting it');
|
|
@@ -58,6 +58,7 @@
|
|
|
58
58
|
"required": [
|
|
59
59
|
"validate-docs.cjs",
|
|
60
60
|
"validate-docs-reconstruct.cjs",
|
|
61
|
+
"generate-skill-catalog.cjs",
|
|
61
62
|
"browser-tool.cjs",
|
|
62
63
|
"validate-spec-output.cjs"
|
|
63
64
|
]
|
|
@@ -68,6 +69,15 @@
|
|
|
68
69
|
"hooks": {
|
|
69
70
|
"assumed": []
|
|
70
71
|
},
|
|
72
|
+
"obsolete": {
|
|
73
|
+
"runtimeFiles": [
|
|
74
|
+
"hooks/skill-router.cjs",
|
|
75
|
+
"hooks/lib/skill-router-routes.cjs"
|
|
76
|
+
],
|
|
77
|
+
"settingsHookCommandSubstrings": [
|
|
78
|
+
"hooks/skill-router.cjs"
|
|
79
|
+
]
|
|
80
|
+
},
|
|
71
81
|
"runtime": {
|
|
72
82
|
"files": [
|
|
73
83
|
"gitignore",
|
|
@@ -80,7 +90,6 @@
|
|
|
80
90
|
"hooks/privacy-block.cjs",
|
|
81
91
|
"hooks/inspect-block.cjs",
|
|
82
92
|
"hooks/rules.cjs",
|
|
83
|
-
"hooks/skill-router.cjs",
|
|
84
93
|
"hooks/spec-state.cjs",
|
|
85
94
|
"hooks/state.cjs",
|
|
86
95
|
"hooks/lib/color.cjs",
|
|
@@ -89,8 +98,7 @@
|
|
|
89
98
|
"hooks/lib/git.cjs",
|
|
90
99
|
"hooks/lib/config.cjs",
|
|
91
100
|
"hooks/lib/context.cjs",
|
|
92
|
-
"hooks/lib/detect.cjs"
|
|
93
|
-
"hooks/lib/skill-router-routes.cjs"
|
|
101
|
+
"hooks/lib/detect.cjs"
|
|
94
102
|
]
|
|
95
103
|
},
|
|
96
104
|
"settings": {
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# Skill Domain Routing
|
|
2
|
+
|
|
3
|
+
Use this decision tree to choose domain skills from the installed CafeKit skill set. This is advisory routing, not an automatic hook.
|
|
4
|
+
|
|
5
|
+
## Frontend And UI
|
|
6
|
+
|
|
7
|
+
```text
|
|
8
|
+
User wants to...
|
|
9
|
+
├── choose style, color, layout, UX, design system -> /hapo:frontend-design
|
|
10
|
+
├── build React/TypeScript UI components -> /hapo:frontend-development
|
|
11
|
+
├── optimize React/Next.js performance or rerenders -> /hapo:react-best-practices
|
|
12
|
+
├── apply deep UI/UX intelligence, visual polish -> /hapo:ui-ux-pro-max
|
|
13
|
+
└── test UI in browser -> /hapo:web-testing or /hapo:agent-browser
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
Use `/hapo:react-best-practices` for performance/re-render patterns. Use `/hapo:frontend-development` for normal implementation.
|
|
17
|
+
|
|
18
|
+
## Backend, Data, And Infrastructure
|
|
19
|
+
|
|
20
|
+
```text
|
|
21
|
+
User wants to...
|
|
22
|
+
├── API, service, auth, database-backed feature -> /hapo:backend-development
|
|
23
|
+
├── deployment, Docker, Kubernetes, Cloudflare, CI/CD -> /hapo:devops
|
|
24
|
+
├── mobile apps, iOS, Android, React Native, Flutter -> /hapo:mobile-development
|
|
25
|
+
└── impact of changing existing behavior -> /hapo:impact-analysis
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Codebase Understanding
|
|
29
|
+
|
|
30
|
+
```text
|
|
31
|
+
User wants to...
|
|
32
|
+
├── find files, locate code, scan project structure -> /hapo:inspect
|
|
33
|
+
├── diagnose an error or failing check -> /hapo:debug
|
|
34
|
+
├── understand possible side effects -> /hapo:impact-analysis
|
|
35
|
+
└── compare external approaches or best practices -> /hapo:research
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Local source truth comes from `/hapo:inspect`; external/current knowledge comes from `/hapo:research`.
|
|
39
|
+
|
|
40
|
+
## Documentation
|
|
41
|
+
|
|
42
|
+
```text
|
|
43
|
+
User wants to...
|
|
44
|
+
├── create missing project docs -> /hapo:docs --init
|
|
45
|
+
├── update docs after source changes -> /hapo:docs --update
|
|
46
|
+
├── summarize codebase quickly -> /hapo:docs --summarize
|
|
47
|
+
├── reconstruct as-is docs from legacy source code -> /hapo:docs --reconstruct <scope>
|
|
48
|
+
└── create a future feature spec -> /hapo:specs
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Keep as-is reconstruction separate from future requirements. Reconstructed docs document current behavior; specs define requested changes.
|
|
52
|
+
|
|
53
|
+
## Testing And Browser
|
|
54
|
+
|
|
55
|
+
```text
|
|
56
|
+
User wants to...
|
|
57
|
+
├── run test suites, coverage, scoped verification -> /hapo:test
|
|
58
|
+
├── E2E/unit/integration/load/security/a11y strategy -> /hapo:web-testing
|
|
59
|
+
├── drive a browser with snapshots or Browserbase -> /hapo:agent-browser
|
|
60
|
+
└── Chrome DevTools/Puppeteer evidence -> /hapo:chrome-devtools
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Documents And Media
|
|
64
|
+
|
|
65
|
+
```text
|
|
66
|
+
User wants to...
|
|
67
|
+
├── PowerPoint/slides -> /hapo:pptx
|
|
68
|
+
├── Word documents -> /hapo:docx
|
|
69
|
+
├── PDFs -> /hapo:pdf
|
|
70
|
+
├── spreadsheets/CSV/XLSX -> /hapo:xlsx
|
|
71
|
+
└── image/audio/video/document multimodal analysis -> /hapo:ai-multimodal
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## Git And Release
|
|
75
|
+
|
|
76
|
+
```text
|
|
77
|
+
User wants to...
|
|
78
|
+
├── commit, branch, tag, push, release prep -> /hapo:git
|
|
79
|
+
└── review before release -> /hapo:code-review
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## Usage Notes
|
|
83
|
+
|
|
84
|
+
- Read the selected skill's `SKILL.md` before acting.
|
|
85
|
+
- Do not activate a skill only because one keyword appears. Use the whole user intent.
|
|
86
|
+
- If a task spans multiple domains, name the primary skill and mention the secondary skill in the plan.
|
|
87
|
+
- If no domain skill fits, use the core CafeKit workflow in `skill-workflow-routing.md`.
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# Skill Workflow Routing
|
|
2
|
+
|
|
3
|
+
Use this rule instead of automatic prompt routing. Read the user's intent, choose the primary CafeKit workflow, then load the relevant `.claude/skills/<skill>/SKILL.md`.
|
|
4
|
+
|
|
5
|
+
Do not inject or force a skill when the user explicitly asks for a direct answer, a specific command, or a different workflow.
|
|
6
|
+
|
|
7
|
+
## Core Specification Workflow
|
|
8
|
+
|
|
9
|
+
```text
|
|
10
|
+
/hapo:brainstorm -> /hapo:specs -> /hapo:develop -> /hapo:test -> /hapo:code-review -> /hapo:git
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
| User intent | Suggested start |
|
|
14
|
+
|---|---|
|
|
15
|
+
| unclear idea, possible approaches, scope tradeoffs | `/hapo:brainstorm` |
|
|
16
|
+
| create requirements, design, task breakdown, validate spec | `/hapo:specs` |
|
|
17
|
+
| implement an approved spec or a specific task file | `/hapo:develop` |
|
|
18
|
+
| run tests, QA, runtime verification | `/hapo:test` |
|
|
19
|
+
| review code quality, security, regressions, maintainability | `/hapo:code-review` |
|
|
20
|
+
| commit, tag, push, branch, release prep | `/hapo:git` |
|
|
21
|
+
|
|
22
|
+
## Bug And Incident Workflow
|
|
23
|
+
|
|
24
|
+
```text
|
|
25
|
+
/hapo:debug -> /hapo:hotfix -> /hapo:test -> /hapo:code-review
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
| User intent | Suggested start |
|
|
29
|
+
|---|---|
|
|
30
|
+
| diagnose why something fails, find root cause, inspect CI/logs | `/hapo:debug` |
|
|
31
|
+
| fix a known bug after diagnosis, urgent regression, production issue | `/hapo:hotfix` |
|
|
32
|
+
| verify the fix and affected behavior | `/hapo:test` |
|
|
33
|
+
| check side effects before closeout | `/hapo:code-review` |
|
|
34
|
+
|
|
35
|
+
`/hapo:debug` is diagnostic-only. Do not edit product code there. Use `/hapo:hotfix` when the user asks to fix.
|
|
36
|
+
|
|
37
|
+
## Existing System Documentation Workflow
|
|
38
|
+
|
|
39
|
+
```text
|
|
40
|
+
/hapo:inspect -> /hapo:docs --reconstruct -> human review -> /hapo:specs -> /hapo:develop
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
| User intent | Suggested start |
|
|
44
|
+
|---|---|
|
|
45
|
+
| understand source structure or locate implementation areas | `/hapo:inspect` |
|
|
46
|
+
| rebuild as-is docs/requirements from a legacy codebase | `/hapo:docs --reconstruct <scope>` |
|
|
47
|
+
| update normal project docs | `/hapo:docs --update` |
|
|
48
|
+
| initialize missing docs | `/hapo:docs --init` |
|
|
49
|
+
| summarize a codebase without full docs work | `/hapo:docs --summarize` |
|
|
50
|
+
|
|
51
|
+
Do not turn reconstructed docs directly into implementation. Human review must approve the as-is docs before `/hapo:specs` defines future changes.
|
|
52
|
+
|
|
53
|
+
## Research And Analysis Workflow
|
|
54
|
+
|
|
55
|
+
```text
|
|
56
|
+
/hapo:inspect -> /hapo:impact-analysis -> /hapo:research
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
| User intent | Suggested start |
|
|
60
|
+
|---|---|
|
|
61
|
+
| file discovery, codebase structure, source scouting | `/hapo:inspect` |
|
|
62
|
+
| affected files, blast radius, dependency impact, side effects | `/hapo:impact-analysis` |
|
|
63
|
+
| external best practices, tool comparison, technical investigation | `/hapo:research` |
|
|
64
|
+
|
|
65
|
+
Use `/hapo:research` for external knowledge. Use `/hapo:inspect` for local source truth.
|
|
66
|
+
|
|
67
|
+
## Output Artifact Workflow
|
|
68
|
+
|
|
69
|
+
| User intent | Suggested skill |
|
|
70
|
+
|---|---|
|
|
71
|
+
| diagrams, architecture maps, Mermaid/SVG/PNG graph output | `/hapo:generate-graph` |
|
|
72
|
+
| PowerPoint or slide deck creation/editing | `/hapo:pptx` |
|
|
73
|
+
| Word documents | `/hapo:docx` |
|
|
74
|
+
| PDF processing | `/hapo:pdf` |
|
|
75
|
+
| spreadsheets | `/hapo:xlsx` |
|
|
76
|
+
| screenshots, images, audio, video, OCR, multimodal understanding | `/hapo:ai-multimodal` |
|
|
77
|
+
|
|
78
|
+
## Selection Rules
|
|
79
|
+
|
|
80
|
+
- Pick one primary workflow first.
|
|
81
|
+
- Add a secondary skill only when it materially changes execution.
|
|
82
|
+
- Prefer explicit user commands over this table.
|
|
83
|
+
- If two workflows conflict, ask one concise clarification.
|
|
84
|
+
- If the user asks to "fix" and root cause is unknown, start with `/hapo:debug` unless the issue is trivial and local.
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* CafeKit skill catalog scanner.
|
|
4
|
+
*
|
|
5
|
+
* This mirrors the Research/.claude approach: expose the installed skill set as
|
|
6
|
+
* a readable catalog so the model can choose skills from rules, not from an
|
|
7
|
+
* automatic prompt-scoring hook.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
const fs = require('fs');
|
|
11
|
+
const path = require('path');
|
|
12
|
+
|
|
13
|
+
function usage() {
|
|
14
|
+
console.log(`Usage:
|
|
15
|
+
node .claude/scripts/generate-skill-catalog.cjs [--skills] [--json] [--root <skills-dir>]
|
|
16
|
+
|
|
17
|
+
Examples:
|
|
18
|
+
node .claude/scripts/generate-skill-catalog.cjs --skills
|
|
19
|
+
node .claude/scripts/generate-skill-catalog.cjs --json --root .claude/skills`);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function parseArgs(argv) {
|
|
23
|
+
const args = { json: false, help: false, root: null };
|
|
24
|
+
for (let i = 0; i < argv.length; i += 1) {
|
|
25
|
+
const arg = argv[i];
|
|
26
|
+
if (arg === '--help' || arg === '-h') args.help = true;
|
|
27
|
+
else if (arg === '--json') args.json = true;
|
|
28
|
+
else if (arg === '--skills') continue;
|
|
29
|
+
else if (arg === '--root') {
|
|
30
|
+
args.root = argv[i + 1] || null;
|
|
31
|
+
i += 1;
|
|
32
|
+
} else {
|
|
33
|
+
args.root = args.root || arg;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return args;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function defaultSkillsRoot() {
|
|
40
|
+
const installed = path.resolve(process.cwd(), '.claude', 'skills');
|
|
41
|
+
if (fs.existsSync(installed)) return installed;
|
|
42
|
+
return path.resolve(__dirname, '..', 'skills');
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function readText(filePath) {
|
|
46
|
+
return fs.readFileSync(filePath, 'utf8');
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function extractFrontmatter(content) {
|
|
50
|
+
const match = content.match(/^---\s*\n([\s\S]*?)\n---\s*\n/);
|
|
51
|
+
if (!match) return {};
|
|
52
|
+
const frontmatter = {};
|
|
53
|
+
const lines = match[1].split(/\r?\n/);
|
|
54
|
+
for (let i = 0; i < lines.length; i += 1) {
|
|
55
|
+
const line = lines[i];
|
|
56
|
+
const kv = line.match(/^([A-Za-z0-9_-]+):\s*(.*)$/);
|
|
57
|
+
if (!kv) continue;
|
|
58
|
+
const key = kv[1];
|
|
59
|
+
let value = kv[2].trim();
|
|
60
|
+
if (value === '>' || value === '>-' || value === '|' || value === '|-') {
|
|
61
|
+
const block = [];
|
|
62
|
+
i += 1;
|
|
63
|
+
while (i < lines.length && /^\s+/.test(lines[i])) {
|
|
64
|
+
block.push(lines[i].trim());
|
|
65
|
+
i += 1;
|
|
66
|
+
}
|
|
67
|
+
i -= 1;
|
|
68
|
+
value = block.join(' ');
|
|
69
|
+
}
|
|
70
|
+
if (
|
|
71
|
+
(value.startsWith('"') && value.endsWith('"')) ||
|
|
72
|
+
(value.startsWith("'") && value.endsWith("'"))
|
|
73
|
+
) {
|
|
74
|
+
value = value.slice(1, -1);
|
|
75
|
+
}
|
|
76
|
+
frontmatter[key] = value;
|
|
77
|
+
}
|
|
78
|
+
return frontmatter;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function firstParagraph(content) {
|
|
82
|
+
const body = content.replace(/^---\s*\n[\s\S]*?\n---\s*\n/, '');
|
|
83
|
+
const paragraph = [];
|
|
84
|
+
for (const rawLine of body.split(/\r?\n/)) {
|
|
85
|
+
const line = rawLine.trim();
|
|
86
|
+
if (!line || line.startsWith('#')) {
|
|
87
|
+
if (paragraph.length > 0) break;
|
|
88
|
+
continue;
|
|
89
|
+
}
|
|
90
|
+
paragraph.push(line);
|
|
91
|
+
if (paragraph.join(' ').length > 160) break;
|
|
92
|
+
}
|
|
93
|
+
return paragraph.join(' ').slice(0, 360);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function categorize(name, description) {
|
|
97
|
+
const text = `${name} ${description}`.toLowerCase();
|
|
98
|
+
if (/spec|brainstorm|develop|sync/.test(text)) return 'workflow';
|
|
99
|
+
if (/debug|hotfix|inspect|impact|review|test|agent-browser|chrome/.test(text)) return 'quality';
|
|
100
|
+
if (/frontend|react|ui|ux|mobile/.test(text)) return 'frontend-mobile';
|
|
101
|
+
if (/pdf|docx|pptx|xlsx|multimodal/.test(text)) return 'artifacts-tools';
|
|
102
|
+
if (/backend|devops|api|database|deploy/.test(text)) return 'backend-infra';
|
|
103
|
+
if (/docs|research|graph/.test(text)) return 'knowledge';
|
|
104
|
+
if (/git/.test(text)) return 'git';
|
|
105
|
+
return 'other';
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
function scanSkills(root) {
|
|
109
|
+
if (!fs.existsSync(root)) {
|
|
110
|
+
throw new Error(`skills root not found: ${root}`);
|
|
111
|
+
}
|
|
112
|
+
const entries = fs.readdirSync(root, { withFileTypes: true });
|
|
113
|
+
const skills = [];
|
|
114
|
+
for (const entry of entries) {
|
|
115
|
+
if (!entry.isDirectory() || entry.name.startsWith('.')) continue;
|
|
116
|
+
const skillPath = path.join(root, entry.name, 'SKILL.md');
|
|
117
|
+
if (!fs.existsSync(skillPath)) continue;
|
|
118
|
+
const content = readText(skillPath);
|
|
119
|
+
const frontmatter = extractFrontmatter(content);
|
|
120
|
+
const name = frontmatter.name || entry.name;
|
|
121
|
+
const description = frontmatter.description || firstParagraph(content);
|
|
122
|
+
skills.push({
|
|
123
|
+
name,
|
|
124
|
+
directory: entry.name,
|
|
125
|
+
description,
|
|
126
|
+
category: categorize(name, description),
|
|
127
|
+
has_references: fs.existsSync(path.join(root, entry.name, 'references')),
|
|
128
|
+
has_scripts: fs.existsSync(path.join(root, entry.name, 'scripts')),
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
return skills.sort((a, b) => a.name.localeCompare(b.name));
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
function renderMarkdown(skills, root) {
|
|
135
|
+
const lines = [
|
|
136
|
+
'# CafeKit Skills Catalog',
|
|
137
|
+
'',
|
|
138
|
+
`Skills root: \`${root}\``,
|
|
139
|
+
`Total skills: ${skills.length}`,
|
|
140
|
+
'',
|
|
141
|
+
];
|
|
142
|
+
const categories = [...new Set(skills.map((skill) => skill.category))].sort();
|
|
143
|
+
for (const category of categories) {
|
|
144
|
+
lines.push(`## ${category}`, '');
|
|
145
|
+
for (const skill of skills.filter((item) => item.category === category)) {
|
|
146
|
+
const badges = [
|
|
147
|
+
skill.has_references ? 'refs' : null,
|
|
148
|
+
skill.has_scripts ? 'scripts' : null,
|
|
149
|
+
].filter(Boolean);
|
|
150
|
+
lines.push(
|
|
151
|
+
`- \`${skill.name}\` (${skill.directory})${badges.length ? ` [${badges.join(', ')}]` : ''}: ${skill.description}`
|
|
152
|
+
);
|
|
153
|
+
}
|
|
154
|
+
lines.push('');
|
|
155
|
+
}
|
|
156
|
+
return lines.join('\n').trim() + '\n';
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
function main() {
|
|
160
|
+
const args = parseArgs(process.argv.slice(2));
|
|
161
|
+
if (args.help) {
|
|
162
|
+
usage();
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
const root = path.resolve(process.cwd(), args.root || defaultSkillsRoot());
|
|
167
|
+
const skills = scanSkills(root);
|
|
168
|
+
if (args.json) {
|
|
169
|
+
console.log(JSON.stringify({ root, total: skills.length, skills }, null, 2));
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
console.log(renderMarkdown(skills, root));
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
try {
|
|
176
|
+
main();
|
|
177
|
+
} catch (error) {
|
|
178
|
+
console.error(`[skill-catalog] ${error.message}`);
|
|
179
|
+
process.exit(1);
|
|
180
|
+
}
|
|
@@ -42,10 +42,6 @@
|
|
|
42
42
|
"type": "command",
|
|
43
43
|
"command": "node \"$CLAUDE_PROJECT_DIR/.claude/hooks/rules.cjs\""
|
|
44
44
|
},
|
|
45
|
-
{
|
|
46
|
-
"type": "command",
|
|
47
|
-
"command": "node \"$CLAUDE_PROJECT_DIR/.claude/hooks/skill-router.cjs\""
|
|
48
|
-
},
|
|
49
45
|
{
|
|
50
46
|
"type": "command",
|
|
51
47
|
"command": "node \"$CLAUDE_PROJECT_DIR/.claude/hooks/spec-state.cjs\""
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
# AGENTS.md
|
|
2
|
+
|
|
3
|
+
Primary operating instructions for OpenCode using the CafeKit runtime.
|
|
4
|
+
|
|
5
|
+
## OpenCode Runtime Mapping
|
|
6
|
+
|
|
7
|
+
- Project instructions live in `AGENTS.md`.
|
|
8
|
+
- CafeKit commands live in `.opencode/commands/` and use OpenCode-native slash names without the `hapo:` prefix.
|
|
9
|
+
- CafeKit subagents live in `.opencode/agents/` using OpenCode frontmatter.
|
|
10
|
+
- CafeKit skills intentionally live in `.claude/skills/` because OpenCode reads Claude-compatible skills natively.
|
|
11
|
+
- Shared CafeKit support files live in `.claude/rules/`, `.claude/scripts/`, `.claude/references/`, and `.claude/runtime.json`.
|
|
12
|
+
- OpenCode config is merged into `opencode.json`; keep project-specific model/provider choices there.
|
|
13
|
+
|
|
14
|
+
## Command Surface
|
|
15
|
+
|
|
16
|
+
Use these OpenCode commands:
|
|
17
|
+
|
|
18
|
+
- `/brainstorm <idea-or-problem>`: scout and narrow an unclear idea before specs.
|
|
19
|
+
- `/specs <feature-or-spec-command>`: create, update, validate, or approve specs.
|
|
20
|
+
- `/develop <feature> [task-file] [--flash]`: implement approved spec tasks.
|
|
21
|
+
- `/test [scope|--full]`: verify implementation and collect evidence.
|
|
22
|
+
- `/code-review [scope|--pending]`: review for correctness, regressions, and scope drift.
|
|
23
|
+
- `/debug <issue>`: diagnose root cause without product-code edits.
|
|
24
|
+
- `/hotfix <issue>`: apply a narrow, scout-first production fix.
|
|
25
|
+
- `/docs [--init|--update|--summarize|--reconstruct]`: maintain or reconstruct project docs.
|
|
26
|
+
- `/inspect <target>`: inspect source, artifacts, or external context.
|
|
27
|
+
- `/generate-graph <request>`: generate technical diagrams.
|
|
28
|
+
|
|
29
|
+
The underlying CafeKit skills are still named `hapo:*` in their documentation. In OpenCode, use the commands above; each command reads the matching skill from `.claude/skills/<skill>/SKILL.md`.
|
|
30
|
+
|
|
31
|
+
## Core Objective
|
|
32
|
+
|
|
33
|
+
Act as the project orchestrator: understand the request, keep scope tight, use the right CafeKit skill/agent, and deliver verified work that follows the project's architecture.
|
|
34
|
+
|
|
35
|
+
## Core Behavior
|
|
36
|
+
|
|
37
|
+
These rules reduce common agent coding failures: hidden assumptions, overbuilt solutions, unrelated edits, and unverified completion claims. They take priority over speed-oriented shortcuts.
|
|
38
|
+
|
|
39
|
+
### 1. Think Before Coding
|
|
40
|
+
|
|
41
|
+
- Do not assume silently. State assumptions when they affect the work.
|
|
42
|
+
- If multiple interpretations are plausible, surface them before implementation.
|
|
43
|
+
- If the simpler option is likely better, say so and push back.
|
|
44
|
+
- If the task/spec is too vague to verify, stop and ask or route back to spec correction.
|
|
45
|
+
- Before feature planning or coding, read `./README.md` for project context.
|
|
46
|
+
|
|
47
|
+
### 2. Simplicity First
|
|
48
|
+
|
|
49
|
+
- Solve the requested problem with the smallest maintainable change.
|
|
50
|
+
- Do not add speculative features, future-proofing, or single-use abstractions.
|
|
51
|
+
- Reuse existing modules before creating new ones.
|
|
52
|
+
- If code grows past 200 lines and could be materially simpler, consider splitting it by real boundaries.
|
|
53
|
+
- Prefer YAGNI, KISS, and DRY in that order.
|
|
54
|
+
|
|
55
|
+
### 3. Surgical Changes
|
|
56
|
+
|
|
57
|
+
- Touch only files required by the task.
|
|
58
|
+
- Do not refactor adjacent code, comments, or formatting unless needed for the requested change.
|
|
59
|
+
- Match existing style even if you would choose another style in a new project.
|
|
60
|
+
- Remove only dead code/imports created by your own change.
|
|
61
|
+
- Mention unrelated issues instead of fixing them opportunistically.
|
|
62
|
+
|
|
63
|
+
### 4. Goal-Driven Execution
|
|
64
|
+
|
|
65
|
+
- Convert requests into verifiable success criteria.
|
|
66
|
+
- For spec tasks, use `Completion Criteria` and `Evidence` as the source of truth. Existing task files may use `Task Test Plan & Verification Evidence` or legacy `Verification & Evidence`.
|
|
67
|
+
- For bugs, reproduce with a failing test or concrete evidence when feasible before fixing.
|
|
68
|
+
- Loop until verification passes or a real blocker is recorded.
|
|
69
|
+
|
|
70
|
+
## CafeKit Operating Loop
|
|
71
|
+
|
|
72
|
+
Use this loop for non-trivial work:
|
|
73
|
+
|
|
74
|
+
1. Understand: read README, relevant docs, active spec/task, and existing code.
|
|
75
|
+
2. Plan: choose the smallest coherent path; use `/specs` for feature specs when needed.
|
|
76
|
+
3. Execute: implement only the active task/scope; no placeholder completion.
|
|
77
|
+
4. Verify: run exact task commands first, then repo-level lint/test/build as needed.
|
|
78
|
+
5. Sync: mark task state only after proof exists.
|
|
79
|
+
|
|
80
|
+
## OpenCode Runtime Limits And Replacements
|
|
81
|
+
|
|
82
|
+
- Claude Code hooks/statusline/settings do not run in OpenCode.
|
|
83
|
+
- Treat `.claude/rules/*` as explicit reference material, not injected hook context.
|
|
84
|
+
- When a skill says to use unavailable Claude-specific tools such as `Task`, `TodoWrite`, or `AskUserQuestion`, use OpenCode's agent/subtask flow, a concise markdown checklist, or ask the user directly.
|
|
85
|
+
- Privacy and inspect gates are instruction-level gates in OpenCode unless a project-specific OpenCode plugin adds hard enforcement.
|
|
86
|
+
|
|
87
|
+
## Operating Discipline
|
|
88
|
+
|
|
89
|
+
- If a CafeKit skill may apply, read and use that skill before acting.
|
|
90
|
+
- No completion claim without fresh evidence from the current run: command output, artifact inspection, runtime proof, or an explicitly recorded blocker.
|
|
91
|
+
- For bugs, CI failures, and regressions, diagnose root cause before editing. Symptom patches are not completion.
|
|
92
|
+
- For implementation work, keep each task scoped to one clear owner/context. Reviewers should receive task files, diffs, and acceptance criteria, not chat history.
|
|
93
|
+
- For branch closeout, verify first, then choose an explicit finish action: merge, push/PR, keep branch/worktree, or discard with confirmation.
|
|
94
|
+
|
|
95
|
+
## Definition Of Done
|
|
96
|
+
|
|
97
|
+
A task is done only when all apply:
|
|
98
|
+
|
|
99
|
+
- implementation satisfies `Completion Criteria`
|
|
100
|
+
- `Evidence` is satisfied with concrete proof
|
|
101
|
+
- preflight/build/test outcomes are passing or an explicit blocker is recorded
|
|
102
|
+
- code review has no critical issues
|
|
103
|
+
- a verification receipt exists before task state is synced to `done`
|
|
104
|
+
|
|
105
|
+
`NO_TESTS` and `0 tests + exit 0` are not passing outcomes when the task requires automated tests.
|
|
106
|
+
|
|
107
|
+
## Rule References
|
|
108
|
+
|
|
109
|
+
Consult these when the task touches the relevant area:
|
|
110
|
+
|
|
111
|
+
- Primary workflow: `./.claude/rules/workflow.md`
|
|
112
|
+
- Development rules: `./.claude/rules/ai-dev-rules.md`
|
|
113
|
+
- Subagent coordination: `./.claude/rules/orchestrator.md`
|
|
114
|
+
- Docs maintenance: `./.claude/rules/manage-docs.md`
|
|
115
|
+
- State sync: `./.claude/rules/state-sync.md`
|
|
116
|
+
- Hook handling reference: `./.claude/rules/hook-protocols.md`
|
|
117
|
+
- Other protocols: `./.claude/rules/*`
|
|
118
|
+
|
|
119
|
+
## Skill And Script Use
|
|
120
|
+
|
|
121
|
+
- Evaluate the installed skill catalog before work and activate the relevant skill(s).
|
|
122
|
+
- If there is a reasonable chance a skill applies, prefer the skill workflow over ad hoc execution.
|
|
123
|
+
- If modifying skills, edit the current project/runtime files, not `~/.claude/skills` directly.
|
|
124
|
+
- Run Python skill scripts with the skill venv:
|
|
125
|
+
- macOS/Linux: `.claude/skills/.venv/bin/python3 scripts/<script>.py`
|
|
126
|
+
- Windows: `.claude\skills\.venv\Scripts\python.exe scripts\<script>.py`
|
|
127
|
+
- If a skill script fails, diagnose and fix the script or environment instead of abandoning the task.
|
|
128
|
+
|
|
129
|
+
## Git And Reporting
|
|
130
|
+
|
|
131
|
+
- Use conventional commits.
|
|
132
|
+
- Do not add AI attribution by default.
|
|
133
|
+
- Lint before commit and run the full required verification before push.
|
|
134
|
+
- Keep commits focused on actual changes.
|
|
135
|
+
- Reports should be concise; list unresolved questions or blockers at the end.
|
|
136
|
+
|
|
137
|
+
## Language Consistency
|
|
138
|
+
|
|
139
|
+
When generating specs or structured project output, use the user's preferred language consistently across the whole spec workspace. Technical terms, code samples, and file paths may remain English.
|
|
140
|
+
|