@haposoft/cafekit 0.7.7 → 0.7.9
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/bin/install.js +43 -0
- package/package.json +1 -1
- package/src/claude/CLAUDE.md +12 -0
- package/src/claude/agents/brainstormer.md +1 -0
- package/src/claude/agents/code-auditor.md +2 -0
- package/src/claude/agents/god-developer.md +1 -0
- package/src/claude/agents/project-manager.md +1 -0
- package/src/claude/agents/researcher.md +9 -3
- package/src/claude/agents/spec-maker.md +1 -0
- package/src/claude/agents/ui-ux-designer.md +1 -0
- package/src/claude/migration-manifest.json +2 -1
- package/src/claude/rules/orchestrator.md +7 -7
- package/src/claude/scripts/web-search.cjs +162 -0
- package/src/claude/skills/research/SKILL.md +18 -6
- package/src/claude/status.cjs +2 -2
package/bin/install.js
CHANGED
|
@@ -827,6 +827,43 @@ function copyRulesDirectory(platformKey, results, options = {}) {
|
|
|
827
827
|
}
|
|
828
828
|
}
|
|
829
829
|
|
|
830
|
+
// Ensure .gitignore configured at root
|
|
831
|
+
function ensureGitignore(results, options = {}) {
|
|
832
|
+
const gitignorePath = path.join(process.cwd(), '.gitignore');
|
|
833
|
+
const header = '# CafeKit / Ecosystem';
|
|
834
|
+
const patterns = [
|
|
835
|
+
'specs/_shared/',
|
|
836
|
+
'plans/',
|
|
837
|
+
'!plans/templates/'
|
|
838
|
+
];
|
|
839
|
+
|
|
840
|
+
if (!fs.existsSync(gitignorePath)) {
|
|
841
|
+
const content = ['# Git Ignore', '', header, ...patterns, ''].join('\n');
|
|
842
|
+
fs.writeFileSync(gitignorePath, content, 'utf8');
|
|
843
|
+
console.log(' ✓ .gitignore created at root');
|
|
844
|
+
results.copied++;
|
|
845
|
+
return;
|
|
846
|
+
}
|
|
847
|
+
|
|
848
|
+
const content = fs.readFileSync(gitignorePath, 'utf8');
|
|
849
|
+
const lines = content.split('\n').map(l => l.trim());
|
|
850
|
+
const missing = patterns.filter(p => !lines.includes(p));
|
|
851
|
+
|
|
852
|
+
if (missing.length > 0) {
|
|
853
|
+
let newContent = content;
|
|
854
|
+
if (!newContent.endsWith('\n')) newContent += '\n';
|
|
855
|
+
if (!content.includes(header)) newContent += `\n${header}\n`;
|
|
856
|
+
|
|
857
|
+
newContent += missing.join('\n') + '\n';
|
|
858
|
+
fs.writeFileSync(gitignorePath, newContent, 'utf8');
|
|
859
|
+
console.log(` ↻ .gitignore updated: added ${missing.join(', ')}`);
|
|
860
|
+
results.updated++;
|
|
861
|
+
} else {
|
|
862
|
+
console.log(' → .gitignore already up to date');
|
|
863
|
+
results.skipped++;
|
|
864
|
+
}
|
|
865
|
+
}
|
|
866
|
+
|
|
830
867
|
// ═══════════════════════════════════════════════════════════
|
|
831
868
|
// GEMINI CLI SETUP
|
|
832
869
|
// ═══════════════════════════════════════════════════════════
|
|
@@ -1024,6 +1061,12 @@ async function main() {
|
|
|
1024
1061
|
console.log();
|
|
1025
1062
|
}
|
|
1026
1063
|
|
|
1064
|
+
// Ensure root .gitignore is configured correctly
|
|
1065
|
+
console.log('Root Configuration');
|
|
1066
|
+
console.log('-'.repeat(40));
|
|
1067
|
+
ensureGitignore(results, installerOptions);
|
|
1068
|
+
console.log();
|
|
1069
|
+
|
|
1027
1070
|
// Setup Gemini CLI and API Key config
|
|
1028
1071
|
await setupGeminiCLI(platforms);
|
|
1029
1072
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@haposoft/cafekit",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.9",
|
|
4
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",
|
package/src/claude/CLAUDE.md
CHANGED
|
@@ -64,6 +64,18 @@ When triggering Python scripts located under `.claude/skills/`, you must invoke
|
|
|
64
64
|
|
|
65
65
|
*Note: If a skill script throws an error, do not abandon the task. try run with venv. if error again, try fix and run
|
|
66
66
|
|
|
67
|
+
## Web Search Protocol
|
|
68
|
+
|
|
69
|
+
When you need to search the internet for information (research, docs lookup, troubleshooting, latest updates, etc.), follow this priority chain:
|
|
70
|
+
|
|
71
|
+
| Priority | Tool | Command | When to use |
|
|
72
|
+
|----------|------|---------|-------------|
|
|
73
|
+
| 🥇 **P1** | `web-search.cjs` | `node .claude/scripts/web-search.cjs "query"` | **ALWAYS try first.** Works on ALL models via Gemini Google Search Grounding. Supports `--multi "q1" "q2"` for batch. Returns JSON with answer + sources. |
|
|
74
|
+
| 🥈 **P2** | `WebSearch` (native) | Use WebSearch tool directly | Secondary verification, or when P1 fails/unavailable. |
|
|
75
|
+
| 🥉 **P3** | `docs-fetch.js` | `node .claude/scripts/docs-fetch.js "library"` | Only when you already know a specific library and need its raw documentation. |
|
|
76
|
+
|
|
77
|
+
**IMPORTANT**: When the user asks you to find information, research a topic, look up documentation, or investigate anything that requires internet access, you MUST use the Web Search Protocol above. Do NOT reply with "I cannot search the web" — you have `web-search.cjs` available via Bash.
|
|
78
|
+
|
|
67
79
|
## Code Refactoring Triggers
|
|
68
80
|
|
|
69
81
|
- **Size Thresholds**: Automatically consider splitting code files that grow beyond 200 lines.
|
|
@@ -50,6 +50,7 @@ Before concluding any brainstorm session, verify each measurement metric:
|
|
|
50
50
|
1. **Engineering Trinity:** YAGNI, KISS, and DRY.
|
|
51
51
|
2. **Brutal Honesty:** Interrogate assumptions. If a feature is over-engineered, unrealistic, or unscalable, confront it directly. Your value lies in preventing costly mistakes.
|
|
52
52
|
3. **Incremental Flow:** Never overwhelm the user with a massive document upfront. Proceed step by step, section by section.
|
|
53
|
+
4. **Web Search Protocol:** When needing to search the internet for references, benchmarks, or latest practices, ALWAYS use `node .claude/scripts/web-search.cjs "query"` first (Gemini Grounding). Use native WebSearch as secondary. Use `docs-fetch.js` only for known library docs.
|
|
53
54
|
|
|
54
55
|
## Ecosystem Alliances (Collaboration Tools)
|
|
55
56
|
|
|
@@ -11,6 +11,8 @@ Goal: Catch the mistakes AI-written code commonly makes — logic errors, securi
|
|
|
11
11
|
|
|
12
12
|
You DO NOT fix code. You only READ, SCORE, and REPORT.
|
|
13
13
|
|
|
14
|
+
**Web Search Protocol:** When needing to verify security best practices or lookup CVE databases, ALWAYS use `node .claude/scripts/web-search.cjs "query"` first (Gemini Grounding). Use native WebSearch as secondary.
|
|
15
|
+
|
|
14
16
|
## Pre-Review: Blast Radius Check (MANDATORY)
|
|
15
17
|
|
|
16
18
|
Before reading any specific logic, you MUST run a Dependency Scope Check (Blast Radius):
|
|
@@ -19,6 +19,7 @@ Any logic gaps must be clarified BEFORE typing, not discovered after bugs ship.
|
|
|
19
19
|
- **Token efficiency**: Write concisely, report briefly, no prose.
|
|
20
20
|
- **Surgical Reading (Large Files):** Never use blanket `Read` commands on files > 800 lines. Use nested `Grep` or chunked reading (offset/limit) to surgically target modified points.
|
|
21
21
|
- **Component Scaffold Limit:** Any React/UI component file that exceeds 200 LOC must trigger a proactive modularization step (split into smaller child files).
|
|
22
|
+
- **Web Search Protocol:** When needing to search the internet, ALWAYS use `node .claude/scripts/web-search.cjs "query"` first (Gemini Grounding). Use native WebSearch as secondary. Use `docs-fetch.js` only for known library docs.
|
|
22
23
|
|
|
23
24
|
## Self-Check Checklist (Before Reporting Complete)
|
|
24
25
|
|
|
@@ -15,6 +15,7 @@ Unlike typical managers who report on "feelings" or conversational summaries, yo
|
|
|
15
15
|
1. **Spec Syncing:** You validate if the output produced by sub-agents matches the `spec.json` requirements and the `design.md` architectural constraints.
|
|
16
16
|
2. **Blocker Assassination:** You identify task stagnation (e.g., a spec stuck in 'in-progress' across multiple sessions) and force the immediate assignment of next-step actions.
|
|
17
17
|
3. **Agile Aggregation:** When parallel sub-agents (like `god-developer` and `test-runner`) report completion, you sweep their logs, consolidate the facts, and generate a single authoritative **Feature Release Report**.
|
|
18
|
+
4. **Web Search Protocol:** When needing to search for project management best practices, dependency updates, or changelog references, ALWAYS use `node .claude/scripts/web-search.cjs "query"` first (Gemini Grounding). Use native WebSearch as secondary.
|
|
18
19
|
|
|
19
20
|
## Execution Constraints
|
|
20
21
|
|
|
@@ -41,14 +41,20 @@ You possess extreme proficiency in:
|
|
|
41
41
|
- Segregating Stable Production Practices away from Toxic Experimental Paradigms.
|
|
42
42
|
- Sniffing out valid Adoption Patterns and real-world implementation trending.
|
|
43
43
|
- Forgiving nothing when crafting Trade-off computational matrices for thousands of competing libraries.
|
|
44
|
-
- Deploying the `scripts/
|
|
44
|
+
- **[PRIORITY 1]** Deploying `scripts/web-search.cjs` as the **PRIMARY search tool** for all web queries. Usage: `node .claude/scripts/web-search.cjs "query"` or `node .claude/scripts/web-search.cjs --multi "q1" "q2"`. Returns JSON with answer, sources, and citations via Gemini Google Search Grounding. ALWAYS attempt this first before any other search method.
|
|
45
|
+
- **[PRIORITY 2]** If WebSearch native tool is available, use it as secondary verification or when `web-search.cjs` fails.
|
|
46
|
+
- **[PRIORITY 3]** Deploying `scripts/docs-fetch.js` only when official Github/Doc URLs are already identified and you need to pull raw documentation content.
|
|
45
47
|
- Deploying Bash and raw Grep utilities to surgically dissect embedded Document architectures and internal file payloads to evaluate raw insights.
|
|
46
48
|
|
|
47
49
|
**ABSOLUTE IMMOVEABLE DIRECTIVE**: You are **STRICTLY PROHIBITED** from generating executable endpoint "Implementation Code". You exist ONLY to maneuver data streams, render synthesis Summary text, and return comprehensive Markdown documentation pathways to the main caller Agent.
|
|
48
50
|
|
|
49
|
-
## Report Output
|
|
51
|
+
## Report Output Routing
|
|
50
52
|
|
|
51
|
-
|
|
53
|
+
Save research output based on context:
|
|
54
|
+
- **Feature research** (active spec exists) → `specs/<feature>/research.md`
|
|
55
|
+
- **System-wide research** (no active spec) → `specs/_shared/Research-<slug>-<date>.md`
|
|
56
|
+
|
|
57
|
+
Do NOT save to `plans/reports/` or `docs/`. All research belongs in `specs/`.
|
|
52
58
|
|
|
53
59
|
## Team Operations Mode
|
|
54
60
|
|
|
@@ -19,6 +19,7 @@ You DO NOT write implementation code. You produce Specifications that downstream
|
|
|
19
19
|
- **The 5 Whys:** Dig past the surface request to find the REAL problem.
|
|
20
20
|
- **80/20 MVP:** Identify the 20% of features that deliver 80% of value.
|
|
21
21
|
- **Systems Thinking:** How does this feature connect to (or break) existing systems?
|
|
22
|
+
- **Web Search Protocol:** When needing to search the internet, ALWAYS use `node .claude/scripts/web-search.cjs "query"` first (Gemini Grounding). Use native WebSearch as secondary. Use `docs-fetch.js` only for known library docs.
|
|
22
23
|
|
|
23
24
|
## Pre-Completion Checklist
|
|
24
25
|
|
|
@@ -18,6 +18,7 @@ You are an award-caliber UI/UX designer. You merge aesthetic excellence with eng
|
|
|
18
18
|
- **Micro-interactions:** Purposeful animations that enhance UX without performance cost.
|
|
19
19
|
- **Accessibility:** WCAG 2.1 AA compliance as a baseline, not an afterthought.
|
|
20
20
|
- **3D/WebGL:** Three.js scene composition, shader development (when appropriate).
|
|
21
|
+
- **Web Search Protocol:** When needing to search the internet for design trends, component libraries, or accessibility guides, ALWAYS use `node .claude/scripts/web-search.cjs "query"` first (Gemini Grounding). Use native WebSearch as secondary. Use `docs-fetch.js` only for known library docs.
|
|
21
22
|
|
|
22
23
|
## Design Workflow
|
|
23
24
|
|
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
Every subagent prompt **must** include these three paths:
|
|
6
6
|
|
|
7
7
|
- **Work Context** — the git root containing the target files
|
|
8
|
-
- **
|
|
9
|
-
- **
|
|
8
|
+
- **Specs Directory** — `{work_context}/specs/`
|
|
9
|
+
- **Docs Directory** — `{work_context}/docs/`
|
|
10
10
|
|
|
11
11
|
When CWD and work context differ (e.g., editing files in a sibling project), always use the **work context** paths.
|
|
12
12
|
|
|
@@ -14,8 +14,8 @@ When CWD and work context differ (e.g., editing files in a sibling project), alw
|
|
|
14
14
|
Example prompt:
|
|
15
15
|
"Resolve the date-parsing regression.
|
|
16
16
|
Work context: /repos/billing-service
|
|
17
|
-
|
|
18
|
-
|
|
17
|
+
Specs: /repos/billing-service/specs/
|
|
18
|
+
Docs: /repos/billing-service/docs/"
|
|
19
19
|
```
|
|
20
20
|
|
|
21
21
|
---
|
|
@@ -97,11 +97,11 @@ Files to modify: [list]
|
|
|
97
97
|
Files to read for context: [list]
|
|
98
98
|
Acceptance criteria: [list]
|
|
99
99
|
Constraints: [any relevant constraints]
|
|
100
|
-
|
|
100
|
+
Spec reference: [spec folder path if applicable]
|
|
101
101
|
|
|
102
102
|
Work context: [project path]
|
|
103
|
-
|
|
104
|
-
|
|
103
|
+
Specs: [specs path]
|
|
104
|
+
Docs: [docs path]
|
|
105
105
|
```
|
|
106
106
|
|
|
107
107
|
### Do
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Web Search via Gemini API + Google Search Grounding
|
|
4
|
+
* Fallback search tool for models without native WebSearch capability.
|
|
5
|
+
*
|
|
6
|
+
* Usage:
|
|
7
|
+
* node web-search.cjs "your search query here"
|
|
8
|
+
* node web-search.cjs --multi "query1" "query2" "query3"
|
|
9
|
+
*
|
|
10
|
+
* Requires: GEMINI_API_KEY in .claude/.env or environment
|
|
11
|
+
*
|
|
12
|
+
* Output: JSON-structured search results with sources and citations.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
const https = require('https');
|
|
16
|
+
const path = require('path');
|
|
17
|
+
const fs = require('fs');
|
|
18
|
+
|
|
19
|
+
// ---------------------------------------------------------------------------
|
|
20
|
+
// ENV Resolution: .claude/.env → process.env
|
|
21
|
+
// ---------------------------------------------------------------------------
|
|
22
|
+
function resolveApiKey() {
|
|
23
|
+
// Priority 1: Already in environment
|
|
24
|
+
if (process.env.GEMINI_API_KEY) return process.env.GEMINI_API_KEY;
|
|
25
|
+
|
|
26
|
+
// Priority 2: Project-local .claude/.env
|
|
27
|
+
const envPaths = [
|
|
28
|
+
path.join(process.cwd(), '.claude', '.env'),
|
|
29
|
+
path.join(process.cwd(), '..', '.claude', '.env'),
|
|
30
|
+
];
|
|
31
|
+
|
|
32
|
+
for (const envPath of envPaths) {
|
|
33
|
+
try {
|
|
34
|
+
if (fs.existsSync(envPath)) {
|
|
35
|
+
const content = fs.readFileSync(envPath, 'utf8');
|
|
36
|
+
const match = content.match(/^GEMINI_API_KEY=(.+)$/m);
|
|
37
|
+
if (match) return match[1].trim().replace(/^["']|["']$/g, '');
|
|
38
|
+
}
|
|
39
|
+
} catch { /* skip */ }
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// ---------------------------------------------------------------------------
|
|
46
|
+
// Gemini API Call with Google Search Grounding
|
|
47
|
+
// ---------------------------------------------------------------------------
|
|
48
|
+
function callGemini(apiKey, query, model) {
|
|
49
|
+
return new Promise((resolve, reject) => {
|
|
50
|
+
const payload = JSON.stringify({
|
|
51
|
+
contents: [{ parts: [{ text: query }] }],
|
|
52
|
+
tools: [{ googleSearch: {} }],
|
|
53
|
+
generationConfig: {
|
|
54
|
+
temperature: 0.1,
|
|
55
|
+
maxOutputTokens: 4096,
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
const options = {
|
|
60
|
+
hostname: 'generativelanguage.googleapis.com',
|
|
61
|
+
path: `/v1beta/models/${model}:generateContent?key=${apiKey}`,
|
|
62
|
+
method: 'POST',
|
|
63
|
+
headers: {
|
|
64
|
+
'Content-Type': 'application/json',
|
|
65
|
+
'Content-Length': Buffer.byteLength(payload),
|
|
66
|
+
},
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
const req = https.request(options, (res) => {
|
|
70
|
+
let data = '';
|
|
71
|
+
res.on('data', chunk => data += chunk);
|
|
72
|
+
res.on('end', () => {
|
|
73
|
+
try {
|
|
74
|
+
const json = JSON.parse(data);
|
|
75
|
+
if (json.error) {
|
|
76
|
+
reject(new Error(`Gemini API Error: ${json.error.message}`));
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
resolve(json);
|
|
80
|
+
} catch (e) {
|
|
81
|
+
reject(new Error(`Failed to parse Gemini response: ${e.message}`));
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
req.on('error', reject);
|
|
87
|
+
req.write(payload);
|
|
88
|
+
req.end();
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// ---------------------------------------------------------------------------
|
|
93
|
+
// Parse Grounding Metadata → Structured Output
|
|
94
|
+
// ---------------------------------------------------------------------------
|
|
95
|
+
function parseResponse(geminiResponse, query) {
|
|
96
|
+
const candidate = geminiResponse.candidates?.[0];
|
|
97
|
+
if (!candidate) return { query, error: 'No candidates returned' };
|
|
98
|
+
|
|
99
|
+
const text = candidate.content?.parts?.map(p => p.text).join('\n') || '';
|
|
100
|
+
const meta = candidate.groundingMetadata || {};
|
|
101
|
+
|
|
102
|
+
// Extract source URLs from groundingChunks
|
|
103
|
+
const sources = (meta.groundingChunks || []).map(chunk => ({
|
|
104
|
+
title: chunk.web?.title || 'Unknown',
|
|
105
|
+
url: chunk.web?.uri || '',
|
|
106
|
+
}));
|
|
107
|
+
|
|
108
|
+
// Extract search queries used by the model
|
|
109
|
+
const searchQueries = meta.webSearchQueries || [];
|
|
110
|
+
|
|
111
|
+
return {
|
|
112
|
+
query,
|
|
113
|
+
answer: text,
|
|
114
|
+
searchQueriesUsed: searchQueries,
|
|
115
|
+
sources,
|
|
116
|
+
sourceCount: sources.length,
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// ---------------------------------------------------------------------------
|
|
121
|
+
// Main
|
|
122
|
+
// ---------------------------------------------------------------------------
|
|
123
|
+
async function main() {
|
|
124
|
+
const args = process.argv.slice(2);
|
|
125
|
+
const isMulti = args[0] === '--multi';
|
|
126
|
+
const queries = isMulti ? args.slice(1) : [args.join(' ')];
|
|
127
|
+
|
|
128
|
+
if (queries.length === 0 || (queries.length === 1 && !queries[0])) {
|
|
129
|
+
console.error(JSON.stringify({
|
|
130
|
+
error: 'Usage: node web-search.cjs "your query" | node web-search.cjs --multi "q1" "q2"'
|
|
131
|
+
}));
|
|
132
|
+
process.exit(1);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
const apiKey = resolveApiKey();
|
|
136
|
+
if (!apiKey) {
|
|
137
|
+
console.error(JSON.stringify({
|
|
138
|
+
error: 'GEMINI_API_KEY not found. Set it in .claude/.env or environment variable.'
|
|
139
|
+
}));
|
|
140
|
+
process.exit(1);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// Use model from env or default to gemini-2.5-flash
|
|
144
|
+
const model = process.env.SEARCH_MODEL || 'gemini-2.5-flash';
|
|
145
|
+
|
|
146
|
+
const results = [];
|
|
147
|
+
|
|
148
|
+
for (const query of queries) {
|
|
149
|
+
try {
|
|
150
|
+
const raw = await callGemini(apiKey, query, model);
|
|
151
|
+
results.push(parseResponse(raw, query));
|
|
152
|
+
} catch (err) {
|
|
153
|
+
results.push({ query, error: err.message });
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// Output as JSON for agent consumption
|
|
158
|
+
const output = isMulti ? results : results[0];
|
|
159
|
+
console.log(JSON.stringify(output, null, 2));
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
main();
|
|
@@ -23,9 +23,11 @@ Call the `TaskCreate` tool to spin up the `researcher` subagent.
|
|
|
23
23
|
**Instructions to pass to Researcher:**
|
|
24
24
|
```text
|
|
25
25
|
Conduct comprehensive research on: [topic]
|
|
26
|
-
Constraint 1:
|
|
27
|
-
Constraint 2:
|
|
28
|
-
Constraint 3:
|
|
26
|
+
Constraint 1: ALWAYS use `node .claude/scripts/web-search.cjs "query"` as PRIMARY search method (supports --multi for batch). This uses Gemini Google Search Grounding and returns JSON with answer + sources.
|
|
27
|
+
Constraint 2: Use native WebSearch tool as secondary verification or when web-search.cjs fails.
|
|
28
|
+
Constraint 3: Use scripts/docs-fetch.js ONLY when official Github/Doc URLs are already identified.
|
|
29
|
+
Constraint 4: Limit total search calls to a maximum of 5 distinct queries to conserve context.
|
|
30
|
+
Constraint 5: Validate information via cross-referencing capabilities.
|
|
29
31
|
Output Format: Must strictly follow the 'Standard Research Report' layout.
|
|
30
32
|
```
|
|
31
33
|
|
|
@@ -36,6 +38,16 @@ Instruct the Researcher Subagent with this strict requirement:
|
|
|
36
38
|
> "Sử dụng nguyên bản template tại `packages/spec/src/claude/skills/specs/templates/research.md`. Tuyệt đối không tự ý đẻ thêm các đề mục ngoài phạm vi file template này."
|
|
37
39
|
|
|
38
40
|
## Post-Execution
|
|
39
|
-
Once the `researcher` completes the Task and returns the Markdown output:
|
|
40
|
-
|
|
41
|
-
|
|
41
|
+
Once the `researcher` completes the Task and returns the Markdown output, save it based on context:
|
|
42
|
+
|
|
43
|
+
### Output Routing
|
|
44
|
+
| Context | Save to | Example |
|
|
45
|
+
|---|---|---|
|
|
46
|
+
| Active spec exists (`specs/<feature>/`) | `specs/<feature>/research.md` | `specs/auth-login/research.md` |
|
|
47
|
+
| No active spec (system-wide / general) | `specs/_shared/Research-<slug>-<date>.md` | `specs/_shared/Research-mv3-best-practices-2026-04-11.md` |
|
|
48
|
+
|
|
49
|
+
### Rules
|
|
50
|
+
1. **Feature research** → Always save inside the active spec folder. If `specs/<feature>/` doesn't exist yet, create it.
|
|
51
|
+
2. **System-wide research** → Save to `specs/_shared/`. Create the directory if it doesn't exist.
|
|
52
|
+
3. **Never** save to `plans/reports/` or `docs/`. All research belongs in `specs/`.
|
|
53
|
+
4. Conclude the workflow by providing the user with the saved file path.
|
package/src/claude/status.cjs
CHANGED
|
@@ -402,8 +402,8 @@ async function main() {
|
|
|
402
402
|
const session = JSON.parse(fs.readFileSync(sessionPath, 'utf8'));
|
|
403
403
|
const planPath = session.activePlan?.trim();
|
|
404
404
|
if (planPath) {
|
|
405
|
-
// Extract slug from path like "plans/260106-1554-
|
|
406
|
-
const match = planPath.match(/plans
|
|
405
|
+
// Extract slug from path like "specs/auth-login" or legacy "plans/260106-1554-feature"
|
|
406
|
+
const match = planPath.match(/(?:specs|plans)\/(?:\d+-\d+-)?(.+?)(?:\/|$)/);
|
|
407
407
|
activePlan = match ? match[1] : planPath.split('/').pop();
|
|
408
408
|
}
|
|
409
409
|
}
|