@haposoft/cafekit 0.9.1 → 0.9.2

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 CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  > Claude Code-first spec-driven workflow and runtime bundle for AI coding assistants.
4
4
 
5
- [![Version](https://img.shields.io/badge/version-0.9.1-blue.svg)](https://github.com/haposoft/cafekit)
5
+ [![Version](https://img.shields.io/badge/version-0.9.2-blue.svg)](https://github.com/haposoft/cafekit)
6
6
  [![License](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)
7
7
  [![Claude%20Code](https://img.shields.io/badge/Claude%20Code-Primary-orange.svg)](https://claude.ai/code)
8
8
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@haposoft/cafekit",
3
- "version": "0.9.1",
3
+ "version": "0.9.2",
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",
@@ -26,6 +26,8 @@ try {
26
26
 
27
27
  const EXPIRY_DAYS = 7;
28
28
  const MAX_ARCHIVES = 5;
29
+ const MAX_AGENT_SECTIONS = 3;
30
+ const MAX_MODIFIED_FILES_DISPLAY = 5;
29
31
  const TRACKED_POST_TOOL_EVENTS = new Set(['Task', 'TaskCreate', 'TaskUpdate', 'TodoWrite']);
30
32
 
31
33
  function stateDir(cwd) {
@@ -126,7 +128,7 @@ try {
126
128
  }).trim();
127
129
 
128
130
  if (diff) {
129
- data.modifiedFiles = diff.split('\n').slice(0, 20);
131
+ data.modifiedFiles = diff.split('\n').slice(0, MAX_MODIFIED_FILES_DISPLAY);
130
132
  }
131
133
  } catch {
132
134
  // fail-open
@@ -157,27 +159,40 @@ try {
157
159
  }
158
160
 
159
161
  function buildAgentSection(data) {
160
- const agentType = data.agent_type || 'unknown';
162
+ const agentType = data.agent_type || '';
163
+ if (!agentType || agentType === 'unknown') return '';
161
164
  const time = new Date().toISOString().slice(11, 19);
162
165
  return `\n## Agent Result: ${agentType} (${time})\n- Completed at ${time}\n`;
163
166
  }
164
167
 
168
+ function takeRecentAgentSections(sections) {
169
+ if (!Array.isArray(sections) || sections.length <= MAX_AGENT_SECTIONS) return sections || [];
170
+ return sections.slice(-MAX_AGENT_SECTIONS);
171
+ }
172
+
165
173
  function mergeAgentSections(existing, content) {
166
174
  if (!existing) return content;
167
175
 
168
176
  const agentSections = existing.match(/## Agent Result:.+?(?=\n## |$)/gs);
169
177
  if (!agentSections) return content;
170
178
 
179
+ const kept = takeRecentAgentSections(agentSections);
171
180
  const marker = '\n## Key Files Modified';
172
181
  if (content.includes(marker)) {
173
- return content.replace(marker, `\n${agentSections.join('\n')}${marker}`);
182
+ return content.replace(marker, `\n${kept.join('\n')}${marker}`);
174
183
  }
175
184
 
176
- return `${content.trimEnd()}\n\n${agentSections.join('\n')}\n`;
185
+ return `${content.trimEnd()}\n\n${kept.join('\n')}\n`;
177
186
  }
178
187
 
179
188
  function appendAgentSection(existing, agentSection) {
180
189
  if (!existing) return agentSection.trimStart();
190
+ if (!agentSection) {
191
+ const sections = existing.match(/## Agent Result:.+?(?=\n## |$)/gs) || [];
192
+ if (sections.length <= MAX_AGENT_SECTIONS) return existing;
193
+ const kept = takeRecentAgentSections(sections);
194
+ return existing.replace(/(## Agent Result:.+?(?=\n## |$))+/gs, kept.join('\n'));
195
+ }
181
196
 
182
197
  const marker = '\n## Key Files Modified';
183
198
  if (existing.includes(marker)) {
@@ -226,8 +241,10 @@ try {
226
241
  }
227
242
 
228
243
  if (event === 'SubagentStop') {
229
- const file = path.join(dir, 'latest.md');
230
244
  const agentSection = buildAgentSection(data);
245
+ if (!agentSection) process.exit(0);
246
+
247
+ const file = path.join(dir, 'latest.md');
231
248
  const existing = fs.existsSync(file) ? fs.readFileSync(file, 'utf8') : '';
232
249
  const updated = existing
233
250
  ? appendAgentSection(existing, agentSection)
@@ -69,17 +69,30 @@ Leverage these specific tools or sub-agents to execute the workflow effectively:
69
69
  - `brainstormer`: Call only for medium/high-complexity architecture trade-offs.
70
70
  - **Ecosystem Swarm (`SendMessage`):** Call `researcher` (validation), `docs-keeper` (architecture boundaries), or `project-manager` (scope warnings) for deeply complex specs.
71
71
 
72
+ ## Discovery Question Framework
73
+
74
+ Load and follow `references/question-framework.md` before the first user-facing discovery question.
75
+
76
+ Use it to:
77
+ - Generate questions from scout evidence, user intent, exact requirement gaps, matching domain matrices, and risk surfaces.
78
+ - Avoid asking the user to answer technical facts that should be verified from code, docs, or current provider/browser documentation.
79
+ - Prioritize only questions that can materially change architecture, MVP scope, UX, cost/privacy/security, acceptance criteria, or delivery format.
80
+ - Record every user-confirmed decision in a decision register in the final report.
81
+
82
+ If the framework conflicts with the general "one question at a time" rule, prefer the framework's question budget and batching limits: one high-impact question by default, up to 3 independent questions in one `AskUserQuestion` call only when batching reduces friction without mixing unrelated decisions.
83
+
72
84
  ## Authoritative Workflow
73
85
 
74
86
  ```mermaid
75
87
  flowchart TD
76
88
  A["Run /hapo:inspect or narrow scout"] --> B["Summarize codebase findings"]
77
- B --> C["Ask one grounded clarifying question"]
78
- C --> D{"Exact requirements captured?"}
79
- D -->|No| C
89
+ B --> C["Load question framework"]
90
+ C --> DQ["Ask highest-impact grounded question"]
91
+ DQ --> D{"Exact requirements captured?"}
92
+ D -->|No| DQ
80
93
  D -->|Yes| E{"Multiple independent subsystems?"}
81
94
  E -->|Yes| F["Decompose into sub-projects"]
82
- F --> C
95
+ F --> DQ
83
96
  E -->|No| G{"Medium/high complexity?"}
84
97
  G -->|Yes| H["Call brainstormer/researcher/docs-keeper as needed"]
85
98
  G -->|No| I["Propose 2-3 approaches"]
@@ -107,10 +120,14 @@ flowchart TD
107
120
 
108
121
  ### 2. Discovery Phase
109
122
 
110
- - Ask exactly **one question at a time**. Do not stack multiple unrelated questions.
123
+ - Load `references/question-framework.md`.
124
+ - Ask exactly **one high-impact question at a time** by default. Do not stack unrelated questions.
125
+ - You may batch up to 3 independent questions only when each question maps to a different required decision surface and none requires explanation before the user can answer.
111
126
  - Prefer multiple-choice options grounded in scout findings.
112
127
  - Push vague intent into concrete examples, sample inputs/outputs, or acceptance criteria.
113
128
  - Challenge the first proposed solution when the underlying goal suggests a simpler path.
129
+ - Do not ask users to decide technical facts. Research browser/runtime/provider/package facts first; then ask only the product or trade-off decision.
130
+ - Track decisions as you go so the final report can distinguish `User Decision`, `Assumption`, and `Open Question`.
114
131
 
115
132
  ### 3. Scope Guard
116
133
 
@@ -154,7 +171,7 @@ Before passing the completed design to the user for final review, you must inter
154
171
  ### 8. Final Handoff & Documentation
155
172
  Upon the user's explicit final approval of the sanitized design document:
156
173
  1. Generate the final **Design Doc / Summary Report**.
157
- 2. Include: problem statement, exact requirements, evaluated approaches, recommended solution, risks, validation criteria, and next steps.
174
+ 2. Include: problem statement, exact requirements, evaluated approaches, recommended solution, risks, validation criteria, decision register, open questions, and next steps.
158
175
  3. Invoke `/hapo:specs` with the report context to hand off into CafeKit's structured specification phase.
159
176
  4. Optionally update an existing project notes, docs, or report file if the approved design context should be persisted for future work.
160
177
 
@@ -0,0 +1,232 @@
1
+ # Brainstorm Question Framework
2
+
3
+ Use this reference to decide **what to ask**, **what not to ask**, and **how to record decisions** during `hapo:brainstorm`.
4
+
5
+ The goal is not to ask many questions. The goal is to ask the smallest set of questions that can materially change the design.
6
+
7
+ ## Source Hierarchy
8
+
9
+ Generate questions from this hierarchy, in order:
10
+
11
+ 1. **Scout evidence** — repo type, framework, existing modules, docs, specs, plans, runtime config, and constraints.
12
+ 2. **User intent** — nouns, verbs, success language, target users, examples, and implied deliverables in the prompt.
13
+ 3. **Exact requirement gaps** — expected output, acceptance criteria, scope boundary, non-negotiable constraints, touchpoints.
14
+ 4. **Domain matrix** — only domains that actually apply to the request.
15
+ 5. **Risk matrix** — security, privacy, cost, runtime limits, provider failure, migration, compliance, maintainability.
16
+
17
+ Never ask a question that the repository, docs, or trusted technical research can answer directly.
18
+
19
+ ## Ask / Do Not Ask
20
+
21
+ Ask the user when the answer changes:
22
+
23
+ - product scope or MVP boundaries
24
+ - target user workflow or UX surface
25
+ - expected output artifact or delivery format
26
+ - acceptance criteria
27
+ - business priority, timeline, or rollout
28
+ - cost, privacy, API-key ownership, external provider choice
29
+ - irreversible workspace action such as renaming/moving/deleting
30
+ - whether to accept a trade-off after you explain it
31
+
32
+ Do **not** ask the user when the answer is a technical fact you should verify:
33
+
34
+ - browser or runtime limits
35
+ - package/API compatibility
36
+ - dependency maintenance state
37
+ - security best practice
38
+ - exact syntax for framework config
39
+ - existing code location, schema, endpoint, or convention
40
+
41
+ If a topic mixes user preference and technical fact, verify the technical facts first, then ask the preference question with those facts included.
42
+
43
+ ## Prioritization
44
+
45
+ Before asking, score each candidate question:
46
+
47
+ | Signal | Score |
48
+ |---|---:|
49
+ | Could change architecture, data model, or platform | +3 |
50
+ | Could change MVP scope or exclude a feature | +3 |
51
+ | Could affect cost, privacy, security, or compliance | +3 |
52
+ | Defines observable acceptance criteria | +2 |
53
+ | Defines UX flow or primary user surface | +2 |
54
+ | Can be answered from repo/docs/research | -4 |
55
+ | Merely names an implementation detail with a safe default | -2 |
56
+
57
+ Ask only the highest-impact question. If several are tied and independent, ask at most 3 in one `AskUserQuestion` batch; otherwise ask one at a time.
58
+
59
+ ## Required Decision Surfaces
60
+
61
+ Every brainstorm must eventually resolve these surfaces:
62
+
63
+ | Surface | Question Intent |
64
+ |---|---|
65
+ | Outcome | What does the user expect to exist or happen after the work? |
66
+ | Done | How will the user verify it works? |
67
+ | Scope | What is explicitly not included now? |
68
+ | Constraints | What cannot change: stack, platform, naming, runtime, compatibility, deadline? |
69
+ | Touchpoints | Which existing files/modules/contracts will this affect? |
70
+
71
+ If any surface is missing, ask a grounded question before proposing architecture.
72
+
73
+ ## Domain Matrix
74
+
75
+ Use only the domains that match the request.
76
+
77
+ ### Product / UX
78
+
79
+ Ask when the prompt includes UI, workflow, dashboard, extension, app, or user-facing behavior.
80
+
81
+ - Primary user: who uses this first?
82
+ - Primary flow: what is the shortest successful path?
83
+ - Surface: page, overlay, sidebar, modal, command, background task?
84
+ - State: loading, empty, error, partial result, retry?
85
+ - Accessibility or localization expectations?
86
+
87
+ ### Browser Extension
88
+
89
+ Ask when the work involves Chrome, Edge, Firefox, YouTube, DOM injection, content scripts, popup, options page, or browser APIs.
90
+
91
+ - Target browser/runtime and manifest version?
92
+ - UI surface: content overlay, sidebar, popup, options page, or all?
93
+ - Permissions posture: minimal host permissions or broader convenience?
94
+ - Storage: browser storage, IndexedDB, sync storage, or no persistence?
95
+ - Publishing target: dev-only, Chrome Web Store, enterprise install?
96
+
97
+ Verify instead of asking:
98
+
99
+ - Manifest V3 service worker lifetime.
100
+ - Browser-reserved shortcut conflicts.
101
+ - Content script isolated-world vs main-world behavior.
102
+ - Current Chrome API compatibility.
103
+
104
+ ### AI / LLM
105
+
106
+ Ask when the work involves translation, summarization, agents, prompt output, generation, or provider choice.
107
+
108
+ - Provider ownership: user API key, app-owned key, proxy, or local model?
109
+ - Provider shape: fixed provider, multi-provider, or custom base URL?
110
+ - Output contract: prose, JSON, markdown, SRT, code, patch?
111
+ - Failure behavior: retry, fallback, partial result, ask user, or stop?
112
+ - Cache policy: never, per session, persistent, or shared?
113
+ - Privacy boundary: what content may leave the browser/server?
114
+
115
+ Verify instead of asking:
116
+
117
+ - Whether a provider is Anthropic-compatible vs OpenAI-compatible.
118
+ - Whether a provider supports tool use / JSON schema / streaming.
119
+ - Current API endpoint paths and auth header format.
120
+
121
+ ### Data / Transcript / Documents
122
+
123
+ Ask when the work transforms documents, captions, data, logs, OCR, audio, video, or legacy code into another artifact.
124
+
125
+ - Source priority and fallback order?
126
+ - Output format and fidelity level?
127
+ - Confidence / evidence tracking requirement?
128
+ - Missing/unknown handling?
129
+ - Export/import requirements?
130
+
131
+ ### Backend / API / Database
132
+
133
+ Ask when the work includes server endpoints, persistence, auth, jobs, integrations, or migrations.
134
+
135
+ - API contract: endpoint, method, request/response shape?
136
+ - Persistence: new table, existing table, no DB?
137
+ - Auth/permission model?
138
+ - Idempotency, retries, and background job behavior?
139
+ - Migration and rollback constraints?
140
+
141
+ ### Docs / Legacy Reconstruction
142
+
143
+ Ask when the work is documentation, legacy analysis, or requirement reconstruction.
144
+
145
+ - Scope path/module to reconstruct?
146
+ - Output docs required: overview, requirements, architecture, evidence map, unknowns?
147
+ - Evidence level: observed-only or inferred allowed with confidence?
148
+ - Review gate: who approves the reconstructed docs?
149
+ - Change request follows reconstruction or is separate?
150
+
151
+ ### Release / Packaging
152
+
153
+ Ask when the work includes publish, store listing, npm release, versioning, or deployment.
154
+
155
+ - Target release channel?
156
+ - Version bump type?
157
+ - Required checks before publish?
158
+ - Store/listing metadata ownership?
159
+ - Rollback or deprecation plan?
160
+
161
+ ## Question Format
162
+
163
+ Use `AskUserQuestion` when available.
164
+
165
+ - Use 2-4 concrete options.
166
+ - Put the recommended option first and label it `(Recommended)`.
167
+ - Include a one-sentence impact description per option.
168
+ - Do not add an explicit "Other" option; the tool supplies it.
169
+ - Avoid abstract labels like "Option A" unless paired with concrete meaning.
170
+
171
+ Good:
172
+
173
+ > "Where should transcript fallback live?"
174
+ > - "Defer STT for MVP (Recommended)" — Ships faster; no fragile audio extraction now.
175
+ > - "Browser-only STT" — No backend, but fragile and heavy.
176
+ > - "Companion backend" — More robust, but requires hosting and ops.
177
+
178
+ Bad:
179
+
180
+ > "What architecture do you want?"
181
+
182
+ ## Explain Before Asking
183
+
184
+ When the user cannot reasonably know the answer, first explain the trade-off briefly, then ask.
185
+
186
+ Use this pattern:
187
+
188
+ 1. State why the decision matters.
189
+ 2. Give 2-3 viable options with consequences.
190
+ 3. Recommend one.
191
+ 4. Ask the user to confirm or override.
192
+
193
+ Do not force a choice before explaining hidden technical risk.
194
+
195
+ ## Decision Register
196
+
197
+ Every final brainstorm report must include a decision register.
198
+
199
+ ```markdown
200
+ ## Decision Register
201
+
202
+ | ID | Question | Options Presented | User Decision | Rationale | Impact |
203
+ |---|---|---|---|---|---|
204
+ | D-001 | Where does transcript fallback live? | Defer STT / Browser-only / Backend | Defer STT | Ships MVP safely | Phase 7 becomes graceful fallback |
205
+ ```
206
+
207
+ Rules:
208
+
209
+ - Record only decisions actually made by the user or explicitly accepted in chat.
210
+ - Do not write "user selected" unless `AskUserQuestion` or direct user text confirms it.
211
+ - If you infer a default, label it as `Assumption`, not `User Decision`.
212
+ - Carry unresolved decisions into `Open Questions`.
213
+
214
+ ## Maximum Question Budget
215
+
216
+ Default budget:
217
+
218
+ - Small change: 1-2 questions.
219
+ - Medium feature: 3-6 questions.
220
+ - Large/greenfield/architecture-heavy: 6-10 questions across multiple rounds.
221
+
222
+ Stop asking when the next question would only refine an implementation detail with a safe default. Propose the design and list remaining assumptions instead.
223
+
224
+ ## Final Self-Check
225
+
226
+ Before presenting design:
227
+
228
+ - Did each asked question map to one of the required decision surfaces or domain risks?
229
+ - Did any question ask the user to answer a technical fact that should have been researched?
230
+ - Are all user decisions captured in the decision register?
231
+ - Are assumptions clearly separated from user decisions?
232
+ - Are open questions truly blocking, or can they be deferred?