create-issflow 1.0.3 → 1.1.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.
Files changed (42) hide show
  1. package/README.md +61 -56
  2. package/bin/cli.js +269 -259
  3. package/package.json +32 -28
  4. package/template/.claude/agents/debugger.md +47 -47
  5. package/template/.claude/agents/e2e-runner.md +66 -66
  6. package/template/.claude/agents/implementer.md +79 -75
  7. package/template/.claude/agents/planner.md +93 -71
  8. package/template/.claude/agents/researcher.md +103 -103
  9. package/template/.claude/agents/synthesizer.md +78 -72
  10. package/template/.claude/agents/test-author.md +70 -70
  11. package/template/.claude/commands/change-request.md +53 -0
  12. package/template/.claude/commands/log-decision.md +33 -33
  13. package/template/.claude/commands/log-issue.md +28 -28
  14. package/template/.claude/commands/overview.md +114 -99
  15. package/template/.claude/commands/phase.md +230 -202
  16. package/template/.claude/commands/propose.md +71 -0
  17. package/template/.claude/commands/quick.md +30 -30
  18. package/template/.claude/commands/replan.md +68 -63
  19. package/template/.claude/commands/store-wisdom.md +195 -195
  20. package/template/.claude/commands/synthesize.md +26 -26
  21. package/template/.claude/commands/unstuck.md +40 -40
  22. package/template/.claude/hooks/pre-compact.js +42 -0
  23. package/template/.claude/hooks/session-start.js +137 -0
  24. package/template/.claude/hooks/subagent-stop.js +18 -0
  25. package/template/.claude/istartsoft-flow/METHODOLOGY.md +403 -229
  26. package/template/.claude/skills/caveman/SKILL.md +39 -39
  27. package/template/.claude/skills/code-standards/SKILL.md +61 -0
  28. package/template/.claude/skills/code-standards/references/architecture.md +61 -0
  29. package/template/.claude/skills/code-standards/references/naming.md +60 -0
  30. package/template/.claude/skills/grill-me/SKILL.md +31 -10
  31. package/template/.claude/skills/karpathy-guidelines/SKILL.md +34 -34
  32. package/template/.claude/skills/security/SKILL.md +70 -0
  33. package/template/.claude/skills/security/references/pentest-checklist.md +46 -0
  34. package/template/.claude/skills/security/references/secure-coding.md +50 -0
  35. package/template/.claude/skills/security/references/standards.md +60 -0
  36. package/template/.claude/skills/security/references/threat-modeling.md +36 -0
  37. package/template/.claude/skills/ux-design/SKILL.md +113 -99
  38. package/template/.claude/skills/ux-design/{wireframe-template.md → references/wireframe-template.md} +95 -95
  39. package/template/.claude/templates/proposal.html +126 -0
  40. package/template/.claude/hooks/pre-compact.sh +0 -25
  41. package/template/.claude/hooks/session-start.sh +0 -120
  42. package/template/.claude/hooks/subagent-stop.sh +0 -11
@@ -1,99 +1,113 @@
1
- ---
2
- name: ux-design
3
- description: >
4
- The iStartSoft UX cookbook + wireframe baseline. A checklist an agent uses to
5
- VALIDATE generated UI so it does not drift outside the design frame. Use on
6
- every UI-facing task: building a screen/component, reviewing a UI diff, or
7
- before a frontend phase closes. Triggers: "ui", "screen", "component",
8
- "layout", "design", "ux", "wireframe", "responsive", "accessib", "a11y",
9
- "ตรวจดีไซน์", "หน้าจอ".
10
- ---
11
-
12
- # ux-design — cookbook + wireframe frame
13
-
14
- Caveman ULTRA mode. UI conforms to the FRAME. Build or change UI -> run this
15
- cookbook before you call it done. Drift outside the wireframe = defect, not
16
- creative liberty (METHODOLOGY hard rule 9).
17
-
18
- Read `wireframe-template.md` (same dir) when starting a new screen — it is the
19
- canonical low-fidelity baseline every screen must map to. Read it on demand only.
20
-
21
- -----
22
-
23
- ## When to apply
24
-
25
- - Building a screen / page / component.
26
- - Reviewing a UI diff (the "ตรวจ" pass).
27
- - CLOSE gate of any frontend phase the cookbook check MUST pass.
28
-
29
- Order: **wireframe first** (does the layout match the baseline frame?) ->
30
- **cookbook** (do the details obey the system?). Never invent layout the
31
- wireframe does not have. If the design truly needs a frame the wireframe lacks,
32
- STOP and update the wireframe baseline first (a design decision -> `log-decision`).
33
-
34
- -----
35
-
36
- ## The cookbook (check every item)
37
-
38
- ### 1. Design tokens — no raw values
39
- - Color / spacing / radius / type / shadow come from named tokens, never
40
- hard-coded hex / px literals scattered in components.
41
- - One source of truth (CSS vars / theme file). New token? add it to the source,
42
- don't inline it.
43
-
44
- ### 2. Spacing scale 8pt grid
45
- - All spacing is a multiple of 4px, prefer 8 (4 · 8 · 12 · 16 · 24 · 32 · 48 · 64).
46
- - No magic margins (`margin: 7px`). Off-grid spacing is a defect.
47
-
48
- ### 3. Type scale
49
- - A fixed, named ramp (e.g. xs/sm/base/lg/xl/2xl). No arbitrary font-sizes.
50
- - Line-height 1.4 for body. One primary font family + a fallback stack.
51
-
52
- ### 4. Accessibility — WCAG 2.1 AA (non-negotiable)
53
- - Text contrast ≥ **4.5:1** (≥ 3:1 for large text ≥ 24px / 19px-bold + UI/icon).
54
- - Every interactive element: keyboard-reachable, visible focus ring, 44×44px hit area.
55
- - Semantic HTML (`button`/`nav`/`main`/`label`), not `div` soup. Inputs have labels.
56
- - Images have `alt`; icon-only buttons have `aria-label`.
57
- - Color is never the ONLY signal (add text/icon for state).
58
-
59
- ### 5. Component inventory reuse, don't reinvent
60
- - Use an existing component before creating one. New component? it earns a place
61
- in the inventory + the wireframe legend.
62
- - One component = one responsibility.
63
-
64
- ### 6. State matrix every interactive element covers all states
65
- - `default · hover · focus · active · disabled · loading · error · empty`.
66
- - Lists/data views handle: **empty**, **loading (skeleton)**, **error**, **partial**.
67
- - No dead-end empty states (always an action or explanation).
68
-
69
- ### 7. Responsive breakpoints
70
- - Mobile-first. Honor the project breakpoints (XS < 640 · SM 640 · MD 768 ·
71
- LG 1024 · XL 1280). Layout must not break or overflow between them.
72
- - No fixed widths that overflow small screens. Touch targets hold on mobile.
73
-
74
- ### 8. Content & i18n
75
- - No hard-coded user-facing strings — go through the i18n layer.
76
- - Text can grow ~30% (translation) without breaking layout. Numbers/dates/currency
77
- are locale-formatted.
78
-
79
- ### 9. Feedback & motion
80
- - Every async action has visible feedback (spinner/skeleton/toast) within ~100ms.
81
- - Destructive actions confirm. Motion is subtle, respects `prefers-reduced-motion`.
82
-
83
- -----
84
-
85
- ## RETURN FORMAT (the "ตรวจ" verdict)
86
-
87
- ```
88
- UX CHECK: <screen/component>
89
- - wireframe match: PASS | DRIFT (<what left the frame>)
90
- - tokens/spacing/type: PASS | FAIL (<which raw values>)
91
- - a11y (WCAG AA): PASS | FAIL (<contrast/keyboard/semantic gap>)
92
- - states covered: <list missing, or "all">
93
- - responsive: PASS | FAIL (<breakpoint that breaks>)
94
- - i18n: PASS | FAIL
95
- - VERDICT: PASS | BLOCK (frontend phase cannot close)
96
- ```
97
-
98
- Sources behind these defaults: WCAG 2.1 AA, Material Design 3 (semantic tokens),
99
- Apple HIG, Shopify Polaris. See `docs/research/design-ux-cookbook-wireframe-pattern.md`.
1
+ ---
2
+ name: ux-design
3
+ description: >
4
+ The iStartSoft UX cookbook + wireframe baseline. A checklist an agent uses to
5
+ VALIDATE generated UI so it does not drift outside the design frame. Use on
6
+ every UI-facing task: building a screen/component, reviewing a UI diff, or
7
+ before a frontend phase closes. Triggers: "ui", "screen", "component",
8
+ "layout", "design", "ux", "wireframe", "responsive", "accessib", "a11y",
9
+ "ตรวจดีไซน์", "หน้าจอ".
10
+ ---
11
+
12
+ # ux-design — cookbook + wireframe frame
13
+
14
+ Caveman ULTRA mode. UI conforms to the FRAME. Build or change UI -> run this
15
+ cookbook before you call it done. Drift outside the wireframe = defect, not
16
+ creative liberty (METHODOLOGY hard rule 9).
17
+
18
+ Read `references/wireframe-template.md` when starting a new screen — it is the
19
+ canonical low-fidelity baseline every screen must map to. Read it on demand only.
20
+
21
+ -----
22
+
23
+ ## When to apply
24
+
25
+ ALL web / UI work runs this — no exception. Every screen or component is verified
26
+ against the cookbook + wireframe and produces a UX CHECK verdict; nothing UI ships
27
+ without it. New visual direction (a layout or look the wireframe doesn't cover) is
28
+ confirmed with the user before building — design is where human taste matters.
29
+
30
+ - Building a screen / page / component.
31
+ - Reviewing a UI diff (the "ตรวจ" pass).
32
+ - CLOSE gate of any frontend phase the cookbook check MUST pass.
33
+
34
+ Order: **wireframe first** (does the layout match the baseline frame?) ->
35
+ **cookbook** (do the details obey the system?). Never invent layout the
36
+ wireframe does not have. If the design truly needs a frame the wireframe lacks,
37
+ STOP and update the wireframe baseline first (a design decision -> `log-decision`).
38
+
39
+ -----
40
+
41
+ ## The cookbook (check every item)
42
+
43
+ ### 1. Design tokens — no raw values
44
+ - Color / spacing / radius / type / shadow come from named tokens, never
45
+ hard-coded hex / px literals scattered in components.
46
+ - One source of truth (CSS vars / theme file). New token? add it to the source,
47
+ don't inline it.
48
+
49
+ ### 2. Spacing scale 8pt grid
50
+ - All spacing is a multiple of 4px, prefer 8 (4 · 8 · 12 · 16 · 24 · 32 · 48 · 64).
51
+ - No magic margins (`margin: 7px`). Off-grid spacing is a defect.
52
+
53
+ ### 3. Type scale
54
+ - A fixed, named ramp (e.g. xs/sm/base/lg/xl/2xl). No arbitrary font-sizes.
55
+ - Line-height 1.4 for body. One primary font family + a fallback stack.
56
+
57
+ ### 4. Accessibility WCAG 2.1 AA (non-negotiable)
58
+ - Text contrast ≥ **4.5:1** (≥ 3:1 for large text ≥ 24px / 19px-bold + UI/icon).
59
+ - Every interactive element: keyboard-reachable, visible focus ring, 44×44px hit area.
60
+ - Semantic HTML (`button`/`nav`/`main`/`label`), not `div` soup. Inputs have labels.
61
+ - Images have `alt`; icon-only buttons have `aria-label`.
62
+ - Color is never the ONLY signal (add text/icon for state).
63
+
64
+ ### 5. Iconographyreal icons, never emoji
65
+ - Use ONE real icon set (SVG, `currentColor`, one consistent grid + stroke width).
66
+ - **NEVER use emoji as UI icons.** They render differently per OS/browser, don't
67
+ inherit color/size cleanly, aren't reliably accessible, and break visual
68
+ consistency. Emoji inside user *content* is fine; emoji as interface iconography
69
+ is a defect — replace with an SVG icon (or a consistent brand accent mark).
70
+ - Icon-only controls get an `aria-label`; purely decorative icons get `aria-hidden`.
71
+
72
+ ### 6. Component inventory reuse, don't reinvent
73
+ - Use an existing component before creating one. New component? it earns a place
74
+ in the inventory + the wireframe legend.
75
+ - One component = one responsibility.
76
+
77
+ ### 7. State matrix — every interactive element covers all states
78
+ - `default · hover · focus · active · disabled · loading · error · empty`.
79
+ - Lists/data views handle: **empty**, **loading (skeleton)**, **error**, **partial**.
80
+ - No dead-end empty states (always an action or explanation).
81
+
82
+ ### 8. Responsive breakpoints
83
+ - Mobile-first. Honor the project breakpoints (XS < 640 · SM 640 · MD 768 ·
84
+ LG 1024 · XL 1280). Layout must not break or overflow between them.
85
+ - No fixed widths that overflow small screens. Touch targets hold on mobile.
86
+
87
+ ### 9. Content & i18n
88
+ - No hard-coded user-facing strings — go through the i18n layer.
89
+ - Text can grow ~30% (translation) without breaking layout. Numbers/dates/currency
90
+ are locale-formatted.
91
+
92
+ ### 10. Feedback & motion
93
+ - Every async action has visible feedback (spinner/skeleton/toast) within ~100ms.
94
+ - Destructive actions confirm. Motion is subtle, respects `prefers-reduced-motion`.
95
+
96
+ -----
97
+
98
+ ## RETURN FORMAT (the "ตรวจ" verdict)
99
+
100
+ ```
101
+ UX CHECK: <screen/component>
102
+ - wireframe match: PASS | DRIFT (<what left the frame>)
103
+ - tokens/spacing/type: PASS | FAIL (<which raw values>)
104
+ - icons: PASS | FAIL (emoji used as icons / inconsistent set)
105
+ - a11y (WCAG AA): PASS | FAIL (<contrast/keyboard/semantic gap>)
106
+ - states covered: <list missing, or "all">
107
+ - responsive: PASS | FAIL (<breakpoint that breaks>)
108
+ - i18n: PASS | FAIL
109
+ - VERDICT: PASS | BLOCK (frontend phase cannot close)
110
+ ```
111
+
112
+ Sources behind these defaults: WCAG 2.1 AA, Material Design 3 (semantic tokens),
113
+ Apple HIG, Shopify Polaris. See `docs/research/design-ux-cookbook-wireframe-pattern.md`.
@@ -1,95 +1,95 @@
1
- # Wireframe baseline — canonical prototype frame
2
-
3
- The low-fidelity reference every screen maps to BEFORE pixels exist. Copy a block
4
- per screen, fill the `[...]`. The agent validates generated UI against this frame
5
- (METHODOLOGY hard rule 9). Anything the screen renders that this frame does not
6
- describe is **drift** — fix the UI or, if the frame is genuinely missing, update
7
- this file first (`log-decision`).
8
-
9
- Keep it low fidelity on purpose: boxes + intent, not styling. Styling lives in the
10
- design tokens / cookbook, not here.
11
-
12
- -----
13
-
14
- ## Global frame (applies to all screens)
15
-
16
- ```
17
- +--------------------------------------------------+
18
- | [top bar: logo · primary nav · account ] | <- persistent
19
- +--------------------------------------------------+
20
- | [breadcrumb / page title ] |
21
- | |
22
- | [ MAIN CONTENT REGION ] |
23
- | |
24
- +--------------------------------------------------+
25
- | [footer / status ] |
26
- +--------------------------------------------------+
27
- ```
28
-
29
- - Breakpoints: nav collapses to a menu below MD (768px). Content single-column
30
- below SM (640px).
31
- - Every screen declares: its route, its primary action, its empty/loading/error
32
- rendering.
33
-
34
- -----
35
-
36
- ## Screen template (copy per screen)
37
-
38
- ```
39
- ### Screen: [name]
40
- - Route: [/path]
41
- - Goal (one line): [what the user accomplishes here]
42
- - Primary action: [the single most important button/intent]
43
- - Entry points: [how the user arrives]
44
- - Exit / next: [where they go after the primary action]
45
-
46
- Layout (regions, top -> bottom):
47
- 1. [region] — [content + which components from the inventory]
48
- 2. [region] — [...]
49
- 3. [region] — [...]
50
-
51
- States:
52
- - loading: [skeleton of which regions]
53
- - empty: [message + the recovery action — never a dead end]
54
- - error: [message + retry]
55
- - success: [confirmation / what changes on screen]
56
-
57
- Data in / out:
58
- - reads: [endpoints from docs/ENDPOINTS.md]
59
- - writes: [endpoints]
60
-
61
- Responsive notes:
62
- - mobile: [what stacks / hides / becomes a sheet]
63
- - desktop: [what spreads out]
64
-
65
- A11y notes:
66
- - focus order: [logical tab order]
67
- - landmarks: [main / nav / form labels]
68
- ```
69
-
70
- -----
71
-
72
- ## Component legend (the inventory the wireframe references)
73
-
74
- List every reusable block a screen may place. A screen MAY ONLY use components
75
- named here; a new one is added here first.
76
-
77
- ```
78
- [Button] — primary | secondary | ghost | destructive
79
- [Input] — text | select | date | search (always labelled)
80
- [Card] — header + body + optional actions
81
- [Table/List] — has empty + loading + error states baked in
82
- [Modal/Sheet] — confirm | form ; sheet on mobile
83
- [Toast] — success | error | info (async feedback)
84
- [Nav] — top bar (desktop) -> menu (mobile)
85
- [...add project components here...]
86
- ```
87
-
88
- -----
89
-
90
- ## How to use (agent)
91
-
92
- 1. New screen -> write its block above from the PLAN acceptance spec.
93
- 2. Build the screen to match the block (layout + states + data + a11y).
94
- 3. Run the `ux-design` cookbook check. Verdict BLOCK -> fix before CLOSE.
95
- 4. Frame too small for a real need -> update this file + `log-decision`, then build.
1
+ # Wireframe baseline — canonical prototype frame
2
+
3
+ The low-fidelity reference every screen maps to BEFORE pixels exist. Copy a block
4
+ per screen, fill the `[...]`. The agent validates generated UI against this frame
5
+ (METHODOLOGY hard rule 9). Anything the screen renders that this frame does not
6
+ describe is **drift** — fix the UI or, if the frame is genuinely missing, update
7
+ this file first (`log-decision`).
8
+
9
+ Keep it low fidelity on purpose: boxes + intent, not styling. Styling lives in the
10
+ design tokens / cookbook, not here.
11
+
12
+ -----
13
+
14
+ ## Global frame (applies to all screens)
15
+
16
+ ```
17
+ +--------------------------------------------------+
18
+ | [top bar: logo · primary nav · account ] | <- persistent
19
+ +--------------------------------------------------+
20
+ | [breadcrumb / page title ] |
21
+ | |
22
+ | [ MAIN CONTENT REGION ] |
23
+ | |
24
+ +--------------------------------------------------+
25
+ | [footer / status ] |
26
+ +--------------------------------------------------+
27
+ ```
28
+
29
+ - Breakpoints: nav collapses to a menu below MD (768px). Content single-column
30
+ below SM (640px).
31
+ - Every screen declares: its route, its primary action, its empty/loading/error
32
+ rendering.
33
+
34
+ -----
35
+
36
+ ## Screen template (copy per screen)
37
+
38
+ ```
39
+ ### Screen: [name]
40
+ - Route: [/path]
41
+ - Goal (one line): [what the user accomplishes here]
42
+ - Primary action: [the single most important button/intent]
43
+ - Entry points: [how the user arrives]
44
+ - Exit / next: [where they go after the primary action]
45
+
46
+ Layout (regions, top -> bottom):
47
+ 1. [region] — [content + which components from the inventory]
48
+ 2. [region] — [...]
49
+ 3. [region] — [...]
50
+
51
+ States:
52
+ - loading: [skeleton of which regions]
53
+ - empty: [message + the recovery action — never a dead end]
54
+ - error: [message + retry]
55
+ - success: [confirmation / what changes on screen]
56
+
57
+ Data in / out:
58
+ - reads: [endpoints from docs/ENDPOINTS.md]
59
+ - writes: [endpoints]
60
+
61
+ Responsive notes:
62
+ - mobile: [what stacks / hides / becomes a sheet]
63
+ - desktop: [what spreads out]
64
+
65
+ A11y notes:
66
+ - focus order: [logical tab order]
67
+ - landmarks: [main / nav / form labels]
68
+ ```
69
+
70
+ -----
71
+
72
+ ## Component legend (the inventory the wireframe references)
73
+
74
+ List every reusable block a screen may place. A screen MAY ONLY use components
75
+ named here; a new one is added here first.
76
+
77
+ ```
78
+ [Button] — primary | secondary | ghost | destructive
79
+ [Input] — text | select | date | search (always labelled)
80
+ [Card] — header + body + optional actions
81
+ [Table/List] — has empty + loading + error states baked in
82
+ [Modal/Sheet] — confirm | form ; sheet on mobile
83
+ [Toast] — success | error | info (async feedback)
84
+ [Nav] — top bar (desktop) -> menu (mobile)
85
+ [...add project components here...]
86
+ ```
87
+
88
+ -----
89
+
90
+ ## How to use (agent)
91
+
92
+ 1. New screen -> write its block above from the PLAN acceptance spec.
93
+ 2. Build the screen to match the block (layout + states + data + a11y).
94
+ 3. Run the `ux-design` cookbook check. Verdict BLOCK -> fix before CLOSE.
95
+ 4. Frame too small for a real need -> update this file + `log-decision`, then build.
@@ -0,0 +1,126 @@
1
+ <!doctype html>
2
+ <!--
3
+ Client-facing proposal template (rendered by /propose from docs/PROPOSAL.md).
4
+ HOW TO USE (agent): copy this file to docs/proposal.html and replace every
5
+ {{PLACEHOLDER}}. LOCALISE the labels + content to the project's declared
6
+ language (e.g. natural Thai) — keep technical terms in English where a Thai dev
7
+ team would. Light + print-friendly on purpose (Ctrl/Cmd-P → "Save as PDF").
8
+ Repeat the <tr> in the phases table per phase; repeat <li> lists as needed.
9
+
10
+ WHITE-LABEL: this template is brand-neutral. Fill {{COMPANY}} / {{LOGO}} with the
11
+ ISSUING company's brand (whoever is sending the proposal) — NOT the kit's. {{LOGO}}
12
+ is optional: replace with an <img src="…"> or a text wordmark, or delete it.
13
+ Icons: none by design (no emoji) — keep it clean and typographic.
14
+ -->
15
+ <html lang="{{LANG}}">
16
+ <head>
17
+ <meta charset="utf-8" />
18
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
19
+ <title>{{TITLE}} — Proposal {{VERSION}}</title>
20
+ <style>
21
+ :root{ --ink:#1a2230; --muted:#5b6878; --line:#e3e8f0; --accent:#5b4cf0;
22
+ --accent2:#0ea5b7; --bg:#fff; --soft:#f6f8fc;
23
+ --sans:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Noto Sans Thai",system-ui,sans-serif;
24
+ --mono:ui-monospace,Menlo,Consolas,monospace; }
25
+ *{box-sizing:border-box}
26
+ body{margin:0;background:var(--soft);color:var(--ink);font-family:var(--sans);line-height:1.6}
27
+ .sheet{max-width:880px;margin:24px auto;background:var(--bg);border:1px solid var(--line);
28
+ border-radius:14px;overflow:hidden}
29
+ .head{padding:34px 40px;border-bottom:3px solid var(--accent);
30
+ background:linear-gradient(120deg,#f3f1ff,#eafcff)}
31
+ .brand-row{display:flex;align-items:center;gap:10px;margin-bottom:14px;font-size:1rem}
32
+ .brand-row .logo{display:inline-flex;align-items:center}
33
+ .head .ey{font:600 .72rem/1 var(--mono);letter-spacing:.18em;text-transform:uppercase;color:var(--accent)}
34
+ .head h1{margin:.3em 0 .1em;font-size:1.9rem;letter-spacing:-.02em}
35
+ .head .meta{color:var(--muted);font-size:.9rem}
36
+ main{padding:14px 40px 40px}
37
+ section{padding:20px 0;border-bottom:1px solid var(--line)}
38
+ section:last-child{border:none}
39
+ h2{font-size:1.05rem;margin:0 0 .5em;display:flex;align-items:center;gap:9px}
40
+ h2::before{content:"";width:10px;height:10px;border-radius:3px;
41
+ background:linear-gradient(120deg,var(--accent),var(--accent2))}
42
+ table{width:100%;border-collapse:collapse;font-size:.92rem}
43
+ th,td{text-align:left;padding:10px 12px;border-bottom:1px solid var(--line)}
44
+ th{background:var(--soft);font-size:.74rem;text-transform:uppercase;letter-spacing:.04em;color:var(--muted)}
45
+ td.num,th.num{text-align:right;font-family:var(--mono)}
46
+ tfoot td{font-weight:700;border-top:2px solid var(--ink);border-bottom:none}
47
+ ul{margin:.2em 0;padding-left:1.2em} li{margin:.2em 0;color:var(--muted)}
48
+ .total{font-size:1.5rem;font-weight:800}
49
+ .total small{font-size:.8rem;color:var(--muted);font-weight:500}
50
+ .cols{display:flex;gap:32px;flex-wrap:wrap} .cols>div{flex:1;min-width:220px}
51
+ .sign{display:flex;gap:40px;flex-wrap:wrap;margin-top:10px}
52
+ .sign div{flex:1;min-width:220px} .line{border-bottom:1px solid var(--ink);height:34px;margin-top:18px}
53
+ .muted{color:var(--muted)} .pill{display:inline-block;font:600 .7rem/1 var(--mono);
54
+ padding:3px 8px;border-radius:6px;background:var(--soft);border:1px solid var(--line);color:var(--muted)}
55
+ footer{padding:18px 40px;color:var(--muted);font-size:.8rem;background:var(--soft)}
56
+ @media print{ body{background:#fff} .sheet{margin:0;border:none;border-radius:0;max-width:none}
57
+ .head{background:#fff} section{break-inside:avoid} }
58
+ </style>
59
+ </head>
60
+ <body>
61
+ <div class="sheet">
62
+ <div class="head">
63
+ <div class="brand-row"><span class="logo">{{LOGO}}</span><strong>{{COMPANY}}</strong></div>
64
+ <div class="ey">Proposal · {{VERSION}}</div>
65
+ <h1>{{TITLE}}</h1>
66
+ <div class="meta">{{L_PREPARED_FOR}} {{CLIENT}} · {{DATE}} · <span class="pill">{{STATUS}}</span></div>
67
+ </div>
68
+ <main>
69
+ <section>
70
+ <h2>{{L_OVERVIEW}}</h2>
71
+ <p class="muted">{{SUMMARY}}</p>
72
+ </section>
73
+
74
+ <section>
75
+ <h2>{{L_SCOPE}}</h2>
76
+ <div class="cols">
77
+ <div><strong>{{L_IN_SCOPE}}</strong><ul>{{SCOPE_IN_ITEMS}}</ul></div>
78
+ <div><strong>{{L_OUT_SCOPE}}</strong><ul>{{SCOPE_OUT_ITEMS}}</ul></div>
79
+ </div>
80
+ </section>
81
+
82
+ <section>
83
+ <h2>{{L_PHASES}}</h2>
84
+ <table>
85
+ <thead><tr>
86
+ <th>{{L_PHASE}}</th><th>{{L_COMPLEXITY}}</th>
87
+ <th class="num">{{L_EFFORT}}</th><th class="num">{{L_COST}}</th>
88
+ </tr></thead>
89
+ <tbody>
90
+ {{PHASE_ROWS}}
91
+ <!-- e.g. <tr><td>1. Auth</td><td>M</td><td class="num">2–3d</td><td class="num">฿16,000–24,000</td></tr> -->
92
+ </tbody>
93
+ <tfoot><tr><td colspan="2">{{L_TOTAL}}</td><td class="num">{{TOTAL_EFFORT}}</td><td class="num">{{TOTAL_COST}}</td></tr></tfoot>
94
+ </table>
95
+ <p class="total" style="margin-top:14px">{{TOTAL_COST}} <small>{{CONTINGENCY_NOTE}}</small></p>
96
+ </section>
97
+
98
+ <section>
99
+ <h2>{{L_TIMELINE}}</h2>
100
+ <p class="muted">{{TIMELINE}}</p>
101
+ </section>
102
+
103
+ <section>
104
+ <div class="cols">
105
+ <div><h2>{{L_ASSUMPTIONS}}</h2><ul>{{ASSUMPTION_ITEMS}}</ul></div>
106
+ <div><h2>{{L_EXCLUSIONS}}</h2><ul>{{EXCLUSION_ITEMS}}</ul></div>
107
+ </div>
108
+ </section>
109
+
110
+ <section>
111
+ <h2>{{L_PAYMENT}}</h2>
112
+ <ul>{{PAYMENT_ITEMS}}</ul>
113
+ </section>
114
+
115
+ <section>
116
+ <h2>{{L_SIGNOFF}}</h2>
117
+ <div class="sign">
118
+ <div><div class="line"></div><div class="muted">{{L_CLIENT_SIGN}}</div></div>
119
+ <div><div class="line"></div><div class="muted">{{L_DATE}}</div></div>
120
+ </div>
121
+ </section>
122
+ </main>
123
+ <footer>{{FOOTER}}</footer>
124
+ </div>
125
+ </body>
126
+ </html>
@@ -1,25 +0,0 @@
1
- #!/usr/bin/env bash
2
- # PreCompact hook. Fires before auto/manual /compact.
3
- set -euo pipefail
4
- cd "${CLAUDE_PROJECT_DIR:-.}"
5
-
6
- mkdir -p docs/.snapshots
7
- STAMP=$(date +%Y%m%d-%H%M%S)
8
- SNAP="docs/.snapshots/precompact-${STAMP}.md"
9
-
10
- {
11
- echo "# Pre-compact snapshot ${STAMP}"
12
- echo
13
- echo "## Git"
14
- git status --short 2>/dev/null || true
15
- git diff --stat 2>/dev/null || true
16
- echo
17
- echo "## STATE.md at compact time"
18
- [ -f docs/STATE.md ] && cat docs/STATE.md || echo "(no STATE.md)"
19
- } > "$SNAP"
20
-
21
- ls -1t docs/.snapshots/precompact-*.md 2>/dev/null | tail -n +6 | xargs -r rm -f
22
-
23
- echo "Context was compacted. Recovery snapshot saved at ${SNAP}."
24
- echo "STATE.md and ISSUES.md were re-injected by the SessionStart hook - trust those."
25
- exit 0