@haposoft/cafekit 0.8.12 → 0.8.14

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.
@@ -0,0 +1,123 @@
1
+ # Update Workflow
2
+
3
+ Use with `/hapo:docs update`.
4
+
5
+ ## Goal
6
+
7
+ Refresh existing living docs after code or project-state changes without rewriting docs that are already accurate.
8
+
9
+ ## Inputs
10
+
11
+ - docs root from `.claude/runtime.json` (`paths.docs`, default `docs`)
12
+ - existing docs under that root
13
+ - recent source changes when git context is available
14
+ - relevant source code, tests, schemas, config, CI, deploy files
15
+ - any additional user focus in the prompt
16
+
17
+ ## Workflow
18
+
19
+ ### Phase 0: Preflight
20
+
21
+ 1. Read repo instructions and docs root.
22
+ 2. Verify the docs root exists.
23
+ 3. If the docs root does not exist, switch to `init` or explain that no docs baseline exists.
24
+ 4. Identify update focus:
25
+ - user-named module or doc
26
+ - recent source diff
27
+ - docs-sync stale hash signal
28
+ - a full docs refresh only when user asks for it
29
+
30
+ ### Phase 1: Source Change Scout
31
+
32
+ Scout source areas that can affect docs:
33
+
34
+ 1. Compare git change context when available.
35
+ 2. Map changed files to affected topics:
36
+ - product capability/PDR
37
+ - architecture or module boundaries
38
+ - commands/config/deployment
39
+ - design/code standards
40
+ - roadmap/changelog state
41
+ 3. Run targeted source reads for evidence.
42
+ 4. Use `hapo:inspect` only when the affected scope is unclear or broad.
43
+
44
+ Do not treat commit messages as sufficient evidence. Verify changed behavior in code, tests, config, or schemas.
45
+
46
+ ### Phase 1.5: Existing Docs Read
47
+
48
+ Read existing docs before edits.
49
+
50
+ Use document count and file size to decide reading strategy:
51
+
52
+ | Docs set | Reading strategy |
53
+ |---|---|
54
+ | 1-3 markdown files | Read directly |
55
+ | 4-6 markdown files | Split across 2-3 readers when delegation is available |
56
+ | 7+ markdown files | Split across up to 5 readers by LOC and topic |
57
+
58
+ Each reading pass extracts:
59
+
60
+ - document purpose
61
+ - claims that may be affected
62
+ - related cross-links
63
+ - stale or contradictory sections
64
+ - unresolved questions already present
65
+
66
+ Merge source scout and docs readings before writing.
67
+
68
+ ### Phase 2: Surgical Docs Update
69
+
70
+ Delegate to `docs-keeper` when available. The update must stay surgical:
71
+
72
+ 1. Edit only affected docs and sections.
73
+ 2. Remove or rewrite stale claims when source evidence contradicts docs.
74
+ 3. Preserve useful human-written context not contradicted by evidence.
75
+ 4. Add new links only after verifying targets.
76
+ 5. Record remaining unknowns instead of inventing migration guidance or architecture.
77
+
78
+ Common update targets:
79
+
80
+ | File | Update when |
81
+ |---|---|
82
+ | `README.md` | setup, usage, command entry points changed |
83
+ | `project-overview-pdr.md` | actors, capabilities, constraints, status changed |
84
+ | `codebase-summary.md` | structure, stack, runtime map changed |
85
+ | `code-standards.md` | real conventions or required commands changed |
86
+ | `system-architecture.md` | components, data flow, integrations, deployment changed |
87
+ | `deployment-guide.md` | build/deploy/env/config changed |
88
+ | `design-guidelines.md` | design system or UI conventions changed |
89
+ | `project-roadmap.md` | milestone/project state changed |
90
+
91
+ ### Phase 3: Size Check
92
+
93
+ 1. Check docs LOC after updates.
94
+ 2. Use `docs.maxLoc` when provided; default to 800.
95
+ 3. Split large documents on semantic boundaries if this update pushes them over the limit.
96
+ 4. Report oversized docs left unchanged when splitting is outside the user scope.
97
+
98
+ ### Phase 4: Validation And Sync
99
+
100
+ 1. Run `.claude/scripts/validate-docs.cjs <docs-root>` when available.
101
+ 2. Treat warnings as review signals; fix resolvable broken links and clearly state remaining warnings.
102
+ 3. Update `<docs-root>/.sync_hash` only after docs are accurately synchronized with the code version being documented.
103
+
104
+ ## Additional Requests
105
+
106
+ Apply extra user instructions only within docs scope. Do not start product implementation from a docs update prompt.
107
+
108
+ ## Required Final Report
109
+
110
+ Report:
111
+
112
+ - docs root used
113
+ - source changes/scopes reviewed
114
+ - docs changed and docs intentionally untouched
115
+ - stale claims corrected
116
+ - validation result
117
+ - unresolved questions
118
+
119
+ If a requested change belongs to future behavior rather than current project docs, recommend:
120
+
121
+ ```text
122
+ /hapo:specs <change request>
123
+ ```
@@ -0,0 +1,14 @@
1
+ # Evidence Map: {{SCOPE}}
2
+
3
+ ## Ledger
4
+
5
+ | ID | Surface | Source | Observation | Related Behavior | Confidence | Gap |
6
+ |---|---|---|---|---|---|---|
7
+ | E-API-001 | API | `{{PATH}}:{{SYMBOL}}` | {{DIRECT_OBSERVATION}} | R-ASIS-001 | High | None |
8
+ | E-TEST-001 | Test | `{{PATH}}` | {{ASSERTED_BEHAVIOR}} | R-ASIS-001 | High | None |
9
+
10
+ ## Evidence Notes
11
+
12
+ - Evidence IDs must stay stable inside this bundle.
13
+ - Existing docs may seed investigation, but source/test/schema/config evidence confirms claims.
14
+ - Put missing runtime data, customer policy, and unreachable code paths in the Gap column and unknowns file.
@@ -0,0 +1,205 @@
1
+ <!doctype html>
2
+ <html lang="en" data-reconstruct-overview>
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1">
6
+ <title>As-Is Reconstruction Overview - {{SCOPE}}</title>
7
+ <style>
8
+ :root {
9
+ color-scheme: light;
10
+ --bg: #f5faf8;
11
+ --panel: #fff;
12
+ --ink: #15231e;
13
+ --muted: #566b63;
14
+ --line: #d8e6e0;
15
+ --brand: #087a5a;
16
+ --sky: #0369a1;
17
+ --observed: #047857;
18
+ --inferred: #b45309;
19
+ --unknown: #be123c;
20
+ --soft: #eaf6f1;
21
+ --shadow: 0 14px 36px rgba(15, 23, 42, 0.08);
22
+ }
23
+ * { box-sizing: border-box; }
24
+ body {
25
+ margin: 0;
26
+ background:
27
+ radial-gradient(circle at 8% 4%, rgba(8, 122, 90, 0.18), transparent 30rem),
28
+ radial-gradient(circle at 92% 2%, rgba(3, 105, 161, 0.14), transparent 28rem),
29
+ linear-gradient(180deg, #f9fffd, var(--bg));
30
+ color: var(--ink);
31
+ font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
32
+ line-height: 1.5;
33
+ }
34
+ main { width: min(1240px, calc(100% - 32px)); margin: 0 auto; padding: 32px 0 56px; }
35
+ .hero, aside, section {
36
+ border: 1px solid var(--line);
37
+ border-radius: 16px;
38
+ background: rgba(255, 255, 255, 0.94);
39
+ box-shadow: var(--shadow);
40
+ }
41
+ .hero { padding: 28px; display: grid; gap: 18px; }
42
+ .eyebrow { color: var(--brand); font-size: 12px; font-weight: 800; text-transform: uppercase; }
43
+ h1, h2, h3 { letter-spacing: 0; line-height: 1.15; margin: 0; }
44
+ h1 { font-size: clamp(30px, 4vw, 52px); }
45
+ h2 { font-size: 22px; }
46
+ h3 { font-size: 16px; }
47
+ p { margin: 0; }
48
+ .muted { color: var(--muted); }
49
+ .metrics, .grid { display: grid; gap: 12px; }
50
+ .metrics { grid-template-columns: repeat(5, minmax(0, 1fr)); }
51
+ .metric, .card {
52
+ border: 1px solid var(--line);
53
+ border-radius: 12px;
54
+ background: #fbfefd;
55
+ padding: 14px;
56
+ }
57
+ .metric span, .label { color: var(--muted); display: block; font-size: 12px; }
58
+ .metric strong { display: block; font-size: 18px; margin-top: 6px; overflow-wrap: anywhere; }
59
+ .layout {
60
+ display: grid;
61
+ grid-template-columns: 260px minmax(0, 1fr);
62
+ gap: 18px;
63
+ align-items: start;
64
+ margin-top: 18px;
65
+ }
66
+ aside { padding: 18px; position: sticky; top: 18px; }
67
+ nav { display: grid; gap: 8px; margin-top: 14px; }
68
+ nav a {
69
+ border: 1px solid var(--line);
70
+ border-radius: 10px;
71
+ color: var(--ink);
72
+ background: #fbfefd;
73
+ padding: 9px 10px;
74
+ text-decoration: none;
75
+ }
76
+ nav a:hover { border-color: var(--brand); color: var(--brand); }
77
+ .content { display: grid; gap: 16px; }
78
+ section { padding: 20px; display: grid; gap: 14px; }
79
+ .grid.two { grid-template-columns: repeat(2, minmax(0, 1fr)); }
80
+ .grid.three { grid-template-columns: repeat(3, minmax(0, 1fr)); }
81
+ .badge {
82
+ border: 1px solid currentColor;
83
+ border-radius: 999px;
84
+ display: inline-flex;
85
+ font-size: 12px;
86
+ font-weight: 800;
87
+ gap: 6px;
88
+ padding: 4px 9px;
89
+ width: fit-content;
90
+ }
91
+ .observed { color: var(--observed); background: #ecfdf5; }
92
+ .inferred { color: var(--inferred); background: #fff7ed; }
93
+ .unknown { color: var(--unknown); background: #fff1f2; }
94
+ .flow { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
95
+ .node { border: 1px solid var(--line); border-radius: 10px; background: var(--soft); padding: 9px 11px; }
96
+ .arrow { color: var(--sky); font-weight: 900; }
97
+ table { width: 100%; border-collapse: collapse; font-size: 14px; }
98
+ th, td { border-bottom: 1px solid var(--line); padding: 10px 8px; text-align: left; vertical-align: top; }
99
+ th { color: var(--muted); }
100
+ code { border: 1px solid var(--line); border-radius: 6px; background: var(--soft); padding: 1px 5px; }
101
+ ul { margin: 0; padding-left: 18px; }
102
+ @media (max-width: 900px) {
103
+ .layout, .metrics, .grid.two, .grid.three { grid-template-columns: 1fr; }
104
+ aside { position: static; }
105
+ }
106
+ </style>
107
+ </head>
108
+ <body>
109
+ <main>
110
+ <header class="hero">
111
+ <div class="eyebrow">CafeKit As-Is Reconstruction</div>
112
+ <div>
113
+ <h1>{{SCOPE}}</h1>
114
+ <p class="muted">Review current behavior recovered from source evidence before creating change specs.</p>
115
+ </div>
116
+ <div class="metrics">
117
+ <div class="metric"><span>Source revision</span><strong>{{SOURCE_REVISION}}</strong></div>
118
+ <div class="metric"><span>Generated</span><strong>{{GENERATED_AT}}</strong></div>
119
+ <div class="metric"><span>Observed</span><strong>{{OBSERVED_COUNT}}</strong></div>
120
+ <div class="metric"><span>Inferred</span><strong>{{INFERRED_COUNT}}</strong></div>
121
+ <div class="metric"><span>Unknown</span><strong>{{UNKNOWN_COUNT}}</strong></div>
122
+ </div>
123
+ </header>
124
+
125
+ <div class="layout">
126
+ <aside>
127
+ <h2>Review Map</h2>
128
+ <p class="muted">Markdown and JSON remain source of truth. This HTML is a visual review surface.</p>
129
+ <nav>
130
+ <a href="#system">System</a>
131
+ <a href="#requirements">Requirements</a>
132
+ <a href="#entities">Entities</a>
133
+ <a href="#rules">Rules</a>
134
+ <a href="#integrations">Integrations</a>
135
+ <a href="#unknowns">Unknowns</a>
136
+ <a href="#evidence">Evidence</a>
137
+ </nav>
138
+ </aside>
139
+
140
+ <div class="content">
141
+ <section id="system">
142
+ <h2>System Overview</h2>
143
+ <!-- SYSTEM_OVERVIEW_START -->
144
+ <div class="flow">
145
+ <span class="node">{{ACTOR}}</span><span class="arrow">-&gt;</span>
146
+ <span class="node">{{ENTRY_POINT}}</span><span class="arrow">-&gt;</span>
147
+ <span class="node">{{STATE_OR_EXTERNAL_SYSTEM}}</span>
148
+ </div>
149
+ <!-- SYSTEM_OVERVIEW_END -->
150
+ </section>
151
+
152
+ <section id="requirements">
153
+ <h2>Recovered Requirements</h2>
154
+ <div class="grid two">
155
+ <!-- REQUIREMENTS_START -->
156
+ <article class="card">
157
+ <span class="badge observed">Observed</span>
158
+ <h3>R-ASIS-001 {{CURRENT_BEHAVIOR}}</h3>
159
+ <p class="muted">Actor: {{ACTOR}} | Evidence: E-API-001, E-TEST-001</p>
160
+ </article>
161
+ <!-- REQUIREMENTS_END -->
162
+ </div>
163
+ </section>
164
+
165
+ <section id="entities">
166
+ <h2>Entities And Statuses</h2>
167
+ <!-- ENTITIES_START -->
168
+ <div class="grid three"><div class="card">{{ENTITY_AND_STATUS_SUMMARY}}</div></div>
169
+ <!-- ENTITIES_END -->
170
+ </section>
171
+
172
+ <section id="rules">
173
+ <h2>Business Rules And Decisions</h2>
174
+ <!-- RULES_START -->
175
+ <ul><li>{{VALIDATION_CALCULATION_CONSTRAINT_OR_DECISION}}</li></ul>
176
+ <!-- RULES_END -->
177
+ </section>
178
+
179
+ <section id="integrations">
180
+ <h2>Integrations</h2>
181
+ <!-- INTEGRATIONS_START -->
182
+ <table><thead><tr><th>System</th><th>Evidence</th><th>Current behavior</th></tr></thead>
183
+ <tbody><tr><td>{{EXTERNAL_SYSTEM}}</td><td>{{EVIDENCE_ID}}</td><td>{{BEHAVIOR}}</td></tr></tbody></table>
184
+ <!-- INTEGRATIONS_END -->
185
+ </section>
186
+
187
+ <section id="unknowns">
188
+ <h2>Human Review Queue</h2>
189
+ <!-- UNKNOWNS_START -->
190
+ <article class="card"><span class="badge unknown">Unknown</span><p>{{QUESTION_FOR_DOMAIN_REVIEWER}}</p></article>
191
+ <!-- UNKNOWNS_END -->
192
+ </section>
193
+
194
+ <section id="evidence">
195
+ <h2>Evidence Trace</h2>
196
+ <!-- EVIDENCE_START -->
197
+ <table><thead><tr><th>ID</th><th>Source</th><th>Observation</th></tr></thead>
198
+ <tbody><tr><td>E-API-001</td><td><code>{{PATH_OR_SYMBOL}}</code></td><td>{{DIRECT_OBSERVATION}}</td></tr></tbody></table>
199
+ <!-- EVIDENCE_END -->
200
+ </section>
201
+ </div>
202
+ </div>
203
+ </main>
204
+ </body>
205
+ </html>
@@ -0,0 +1,40 @@
1
+ {
2
+ "scope": "{{SCOPE}}",
3
+ "generated_at": "{{ISO_TIMESTAMP}}",
4
+ "status": "draft",
5
+ "docs_root": "{{DOCS_ROOT}}/as-is/{{SCOPE_SLUG}}",
6
+ "source_revision": "{{SOURCE_REVISION_OR_UNAVAILABLE_REASON}}",
7
+ "source_branch": "{{SOURCE_BRANCH_OR_UNAVAILABLE_REASON}}",
8
+ "evidence_policy": "observed-inferred-unknown",
9
+ "review_gate": "human_review_required",
10
+ "review_status": "pending",
11
+ "reviewed_by": null,
12
+ "reviewed_at": null,
13
+ "approved_for_specs": false,
14
+ "source_scope": [
15
+ "{{SCOPE}}"
16
+ ],
17
+ "documents": [
18
+ "overview.html",
19
+ "system-overview.md",
20
+ "requirements-as-is.md",
21
+ "roles-and-permissions.md",
22
+ "entities-and-statuses.md",
23
+ "business-rules.md",
24
+ "integrations.md",
25
+ "architecture-c4.md",
26
+ "constraints-risks-and-decisions.md",
27
+ "glossary.md",
28
+ "evidence-map.md",
29
+ "unknowns-and-assumptions.md"
30
+ ],
31
+ "counts": {
32
+ "requirements": 0,
33
+ "evidence_items": 0,
34
+ "observed": 0,
35
+ "inferred": 0,
36
+ "unknown": 0,
37
+ "open_unknowns": 0
38
+ },
39
+ "next_recommended_step": "human_review"
40
+ }
@@ -0,0 +1,34 @@
1
+ # As-Is Requirements: {{SCOPE}}
2
+
3
+ ## Evidence Policy
4
+
5
+ Each requirement records current behavior only.
6
+
7
+ - `Observed`: current behavior directly supported by source/test/schema/config evidence.
8
+ - `Inferred`: likely current behavior supported by multiple signals but not fully proven.
9
+ - `Unknown`: code indicates a gap that needs human or runtime confirmation.
10
+
11
+ ## R-ASIS-001: {{CURRENT_BEHAVIOR_TITLE}}
12
+
13
+ - Type: Observed
14
+ - Confidence: High
15
+ - Evidence:
16
+ - E-API-001 - `{{PATH_OR_SYMBOL}}`
17
+ - E-TEST-001 - `{{PATH_OR_SYMBOL}}`
18
+ - Actors:
19
+ - {{ACTOR_OR_CALLER}}
20
+ - Trigger:
21
+ - {{ENTRY_POINT_OR_EVENT}}
22
+ - Inputs:
23
+ - {{INPUTS_OR_NONE}}
24
+ - Current outcome:
25
+ - {{CURRENT_RESULT}}
26
+ - Exceptions or gaps:
27
+ - {{ERROR_PATH_OR_UNKNOWN}}
28
+ - Notes:
29
+ - {{SHORT_REVIEW_NOTE}}
30
+
31
+ ## Open Review Notes
32
+
33
+ - Replace template examples with source-backed requirements.
34
+ - Move requested future changes to `/hapo:specs`, not this file.
@@ -0,0 +1,19 @@
1
+ # Unknowns And Assumptions: {{SCOPE}}
2
+
3
+ ## Review Queue
4
+
5
+ | ID | Topic | Type | Why It Is Unresolved | Needed Confirmation |
6
+ |---|---|---|---|---|
7
+ | U-001 | {{TOPIC}} | Unknown | {{CODE_OR_RUNTIME_GAP}} | {{DOMAIN_OR_RUNTIME_ANSWER}} |
8
+
9
+ ## Inferred Behavior To Confirm
10
+
11
+ - {{INFERRED_BEHAVIOR_WITH_EVIDENCE_IDS}}
12
+
13
+ ## Business Rules Missing From Code
14
+
15
+ - {{QUESTION_FOR_DOMAIN_REVIEWER}}
16
+
17
+ ## Runtime Or Environment Gaps
18
+
19
+ - {{EXTERNAL_SERVICE_DATA_OR_CONFIG_GAP}}
@@ -14,7 +14,8 @@ const fs = require('fs');
14
14
  const path = require('path');
15
15
 
16
16
  // Import modular components
17
- const { green, yellow, red, cyan, magenta, dim, coloredBar, RESET, shouldUseColor } = require('./hooks/lib/color.cjs');
17
+ const colors = require('./hooks/lib/color.cjs');
18
+ const { green, yellow, red, cyan, magenta, dim, coloredBar, RESET } = colors;
18
19
  const { parseTranscript } = require('./hooks/lib/parser.cjs');
19
20
  const { countConfigs } = require('./hooks/lib/counter.cjs');
20
21
  const { loadConfig } = require('./hooks/lib/config.cjs');
@@ -358,7 +359,7 @@ function render(ctx, singleLineMode = false) {
358
359
 
359
360
  // Output all lines with non-breaking spaces for alignment
360
361
  for (const line of lines) {
361
- const outputLine = shouldUseColor ? `${RESET}${line.replace(/ /g, '\u00A0')}` : line;
362
+ const outputLine = colors.shouldUseColor ? `${RESET}${line.replace(/ /g, '\u00A0')}` : line;
362
363
  console.log(outputLine);
363
364
  }
364
365
  }
@@ -509,6 +510,7 @@ async function main() {
509
510
  // Load config and get statusline mode
510
511
  const config = loadConfig({ includeProject: false, includeAssertions: false, includeLocale: false });
511
512
  const statuslineMode = config.statusline || 'full';
513
+ colors.setColorEnabled(config.statuslineColors !== false);
512
514
 
513
515
  // Render based on mode
514
516
  switch (statuslineMode) {