@rubytech/create-maxy-code 0.1.111 → 0.1.113
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/dist/__tests__/brew-install.test.js +10 -0
- package/dist/__tests__/brew-resolve.test.js +35 -0
- package/dist/__tests__/launchd-plist.test.js +46 -0
- package/dist/__tests__/macos-darwin-branch.test.js +85 -0
- package/dist/brew-install.js +5 -0
- package/dist/index.js +26 -6
- package/package.json +1 -1
- package/payload/platform/plugins/cloudflare/references/manual-setup.md +105 -0
- package/payload/platform/plugins/docs/references/deployment.md +22 -4
- package/payload/platform/plugins/memory/mcp/dist/index.js +35 -0
- package/payload/platform/plugins/memory/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/image-fetch.d.ts +15 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/image-fetch.d.ts.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/image-fetch.js +64 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/image-fetch.js.map +1 -0
- package/payload/platform/plugins/memory/references/schema-estate-agent.md +76 -1
- package/payload/platform/plugins/venture-studio/PLUGIN.md +13 -4
- package/payload/platform/plugins/venture-studio/bin/scaffold.sh +15 -3
- package/payload/platform/plugins/venture-studio/skills/brand-pack/SKILL.md +1 -1
- package/payload/platform/plugins/venture-studio/skills/investor-data-room/SKILL.md +27 -14
- package/payload/platform/plugins/venture-studio/skills/investor-data-room/references/business-plan-template.md +7 -4
- package/payload/platform/plugins/venture-studio/skills/investor-data-room/references/data-room-structure.md +16 -5
- package/payload/platform/plugins/venture-studio/skills/investor-data-room/references/deck-blueprint-template.md +7 -6
- package/payload/platform/plugins/venture-studio/skills/office-hours/SKILL.md +8 -9
- package/payload/platform/plugins/venture-studio/skills/prototype-host/SKILL.md +179 -0
- package/payload/platform/plugins/venture-studio/skills/prototype-host/references/cloudflared-ingress-edit.md +81 -0
- package/payload/platform/plugins/venture-studio/skills/prototype-host/references/scaffold-frameworks.md +60 -0
- package/payload/platform/plugins/venture-studio/skills/prototype-host/references/systemd-user-service.md +104 -0
- package/payload/platform/plugins/venture-studio/skills/zero-to-prototype/SKILL.md +4 -0
- package/payload/platform/templates/agents/public/IDENTITY.md +11 -1
- package/payload/premium-plugins/real-agent/BUNDLE.md +3 -2
- package/payload/premium-plugins/real-agent/agents/listing-curator.md +152 -0
- package/payload/premium-plugins/real-agent/plugins/brochures/skills/a4-print-documents/SKILL.md +1 -1
- package/payload/premium-plugins/real-agent/plugins/brochures/skills/brand-design/SKILL.md +5 -11
- package/payload/premium-plugins/real-agent/plugins/brochures/skills/make-brochure/SKILL.md +7 -7
- package/payload/premium-plugins/real-agent/plugins/brochures/skills/property-extract/SKILL.md +31 -39
- package/payload/premium-plugins/real-agent/plugins/brochures/skills/property-market-report/SKILL.md +4 -4
- package/payload/premium-plugins/real-agent/plugins/brochures/skills/property-socials/SKILL.md +3 -2
- package/payload/premium-plugins/real-agent/plugins/buyers/.claude-plugin/plugin.json +1 -1
- package/payload/premium-plugins/real-agent/plugins/buyers/PLUGIN.md +3 -2
- package/payload/premium-plugins/real-agent/plugins/buyers/skills/property-recommender/SKILL.md +96 -0
- package/payload/premium-plugins/venture-studio/PLUGIN.md +13 -4
- package/payload/premium-plugins/venture-studio/bin/scaffold.sh +15 -3
- package/payload/premium-plugins/venture-studio/skills/brand-pack/SKILL.md +1 -1
- package/payload/premium-plugins/venture-studio/skills/investor-data-room/SKILL.md +27 -14
- package/payload/premium-plugins/venture-studio/skills/investor-data-room/references/business-plan-template.md +7 -4
- package/payload/premium-plugins/venture-studio/skills/investor-data-room/references/data-room-structure.md +16 -5
- package/payload/premium-plugins/venture-studio/skills/investor-data-room/references/deck-blueprint-template.md +7 -6
- package/payload/premium-plugins/venture-studio/skills/office-hours/SKILL.md +8 -9
- package/payload/premium-plugins/venture-studio/skills/prototype-host/SKILL.md +179 -0
- package/payload/premium-plugins/venture-studio/skills/prototype-host/references/cloudflared-ingress-edit.md +81 -0
- package/payload/premium-plugins/venture-studio/skills/prototype-host/references/scaffold-frameworks.md +60 -0
- package/payload/premium-plugins/venture-studio/skills/prototype-host/references/systemd-user-service.md +104 -0
- package/payload/premium-plugins/venture-studio/skills/zero-to-prototype/SKILL.md +4 -0
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
# Venture-studio data-room scaffold — deterministic enforcement of the
|
|
3
3
|
# scaffold-first principle (Task 286 + feedback_doctrine_paragraph_is_not_a_gate).
|
|
4
4
|
#
|
|
5
|
-
# Creates exactly one Project (with
|
|
5
|
+
# Creates exactly one Project (with nine pre-seeded artefact Tasks) in
|
|
6
6
|
# the graph, then materialises the ten-section data-room directory tree
|
|
7
7
|
# on disk. The venture-studio agent's downstream skills are gated on
|
|
8
8
|
# both signals existing — see venture-studio/PLUGIN.md.
|
|
@@ -53,9 +53,14 @@ fi
|
|
|
53
53
|
|
|
54
54
|
DATA_ROOM="${PROJECT_ROOT}/.docs/data-room"
|
|
55
55
|
|
|
56
|
-
#
|
|
56
|
+
# Nine pre-seeded artefact tasks — order and names match
|
|
57
57
|
# premium-plugins/venture-studio/PLUGIN.md § First-conversation routing.
|
|
58
58
|
# Section order is preserved so the agent can walk them sequentially.
|
|
59
|
+
# Prototype-host is slotted between Stage 2 (wedge + landing copy) and
|
|
60
|
+
# Stage 3 (business plan): brand-pack and wedge are hard prerequisites
|
|
61
|
+
# (the skill consumes 06-product-ip/brand/ tokens and 01-narrative/LANDING.md);
|
|
62
|
+
# hosting before business plan keeps the founder's wedge-validation loop
|
|
63
|
+
# (live URL) ahead of investor-pack work.
|
|
59
64
|
PAYLOAD=$(cat <<JSON
|
|
60
65
|
{
|
|
61
66
|
"accountId": "${ACCOUNT_ID}",
|
|
@@ -64,8 +69,9 @@ PAYLOAD=$(cat <<JSON
|
|
|
64
69
|
"tier": "full",
|
|
65
70
|
"workItems": [
|
|
66
71
|
{"name": "Stage 1 — Office-hours design doc", "description": "Produces 01-narrative/office-hours-design.md via the office-hours skill."},
|
|
67
|
-
{"name": "Brand pack", "description": "Produces brand identity (palette, typography, logo) into 06-product-ip/brand/ via the brand-pack skill."},
|
|
68
72
|
{"name": "Stage 2 — Wedge validation + landing page + PRD", "description": "Produces 01-narrative/{PMF,LANDING,PRD}.md via the zero-to-prototype skill."},
|
|
73
|
+
{"name": "Brand pack", "description": "Produces brand guidelines + summary + color palette + typography system + tone-of-voice (voice/messaging/copy) + logo guidelines into 06-product-ip/brand/ via the brand-pack skill."},
|
|
74
|
+
{"name": "Prototype host", "description": "Public URL for the landing page and/or wedge prototype via cloudflared ingress + systemd-managed dev server (skill: prototype-host)."},
|
|
69
75
|
{"name": "Stage 3 — Business plan", "description": "Produces 01-narrative/business-plan.md via investor-data-room Stage 3."},
|
|
70
76
|
{"name": "Stage 3b — Term sheet", "description": "Produces html/prospectus/term_sheet.html via investor-data-room Stage 3b."},
|
|
71
77
|
{"name": "Stage 4 — Deck blueprint", "description": "Produces 01-narrative/deck-blueprint.md via investor-data-room Stage 4."},
|
|
@@ -101,4 +107,10 @@ for section in \
|
|
|
101
107
|
mkdir -p "${DATA_ROOM}/${section}"
|
|
102
108
|
done
|
|
103
109
|
|
|
110
|
+
# Hosted-prototype source roots live alongside the numbered sections under
|
|
111
|
+
# data-room/. The prototype-host skill populates this with one subdir per
|
|
112
|
+
# surface (landing/, prototype/, etc.); creating the parent here so the
|
|
113
|
+
# directory exists before the first invocation.
|
|
114
|
+
mkdir -p "${DATA_ROOM}/prototype"
|
|
115
|
+
|
|
104
116
|
echo "scaffold.sh: data-room scaffolded at ${DATA_ROOM}"
|
|
@@ -39,7 +39,7 @@ Before generating anything, gather the following. Ask all questions in a single
|
|
|
39
39
|
- Website URL (fetch it if provided — extract existing colors, fonts, tone)
|
|
40
40
|
- Inspiration brands (brands they admire aesthetically)
|
|
41
41
|
|
|
42
|
-
If the user provides a URL,
|
|
42
|
+
If the user provides a URL — their own site, a competitor brand, or an inspiration brand — dispatch the `research-assistant` specialist (with `deep-research` for site copy + visual scan, `WebFetch` available through the specialist) rather than calling `fetch` or `WebFetch` directly from this skill. The specialist returns: dominant colors (CSS or visual description), font choices, tone of copy, and any existing brand signals. Pre-fill your recommendations from the specialist's structured findings.
|
|
43
43
|
|
|
44
44
|
---
|
|
45
45
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: investor-data-room
|
|
3
|
-
description: Use when a UK-domiciled founder needs to produce a full seed-raise pack from idea to deliverables: graph-structured data room,
|
|
3
|
+
description: Use when a UK-domiciled founder needs to produce a full seed-raise pack from idea to deliverables: graph-structured data room, 16-section business plan, persuasive prospectus + formal term sheet (with FCA self-certification appendices), 13-slide deck blueprint, print-ready HTML+PDF for each. Trigger phrases include "build me a data room", "draft a business plan", "deck from the business plan", "draft an investment prospectus", "generate a term sheet", "from office hours to investor pack", "set up the fundraise repo". The skill never speculates on financial figures or cap-table values: every number traces to a Companies House filing, a financial model worksheet, or a source citation. Public-facing artefacts contain zero internal workings (no "reconciliation pending", no "open Q" markers, no comparison-to-baseline commentary). Design tokens are harmonised across business plan, prospectus, term sheet, and deck via the operator's project design-tokens spec.
|
|
4
4
|
allowed-tools:
|
|
5
5
|
- Bash
|
|
6
6
|
- Read
|
|
@@ -25,13 +25,15 @@ Complete when the data room contains:
|
|
|
25
25
|
README.md # data-room index, status snapshot, doctrine
|
|
26
26
|
01-narrative/
|
|
27
27
|
office-hours-design.md # ideation working scratchpad
|
|
28
|
-
business-plan.md #
|
|
29
|
-
deck-blueprint.md #
|
|
28
|
+
business-plan.md # 16-section business plan
|
|
29
|
+
deck-blueprint.md # 13-slide blueprint
|
|
30
|
+
exit-thesis.md # named acquirers + recent exit comparables
|
|
30
31
|
02-corporate-legal/
|
|
31
32
|
README.md # incorporation filings, articles, board minutes
|
|
32
33
|
incorporation-<co-house-no>-<date>.pdf # IN01 + statement of capital + cap table
|
|
33
34
|
03-cap-table/
|
|
34
35
|
README.md # pre/post-investment cap table with PSC notes
|
|
36
|
+
comparables.md # recent comparable rounds (company / pre-money / post-money / multiple / source) cited by the term-sheet valuation
|
|
35
37
|
04-financials/
|
|
36
38
|
README.md
|
|
37
39
|
model_worksheet.md # opening cash, capex, burn, MRR ramp, two-round
|
|
@@ -78,7 +80,9 @@ Skip stages that are already complete; do not regenerate stale artefacts blindly
|
|
|
78
80
|
|
|
79
81
|
## Stage 1 — Office-hours ideation
|
|
80
82
|
|
|
81
|
-
Drive a conversational discovery session using the sibling `office-hours` skill.
|
|
83
|
+
Drive a conversational discovery session using the sibling `office-hours` skill. Market sizing and competitor recon during discovery dispatch the `research-assistant` specialist with `deep-research` + `data-research` rather than calling `WebSearch` directly — every market figure that ends up in `08-market/sources.md` must trace to a structured-research citation.
|
|
84
|
+
|
|
85
|
+
Output a single `office-hours-design.md` capturing:
|
|
82
86
|
|
|
83
87
|
- Problem statement
|
|
84
88
|
- Demand evidence (with numbers and dates)
|
|
@@ -113,22 +117,23 @@ References: `references/data-room-structure.md` for the section-by-section purpo
|
|
|
113
117
|
|
|
114
118
|
## Stage 3 — Business plan synthesis
|
|
115
119
|
|
|
116
|
-
Generate `01-narrative/business-plan.md` with **
|
|
120
|
+
Generate `01-narrative/business-plan.md` with **16 sections** following the canonical structure:
|
|
117
121
|
|
|
118
122
|
1. Executive Summary
|
|
119
123
|
2. Vision and Mission (Vision / Mission / Doctrine triad)
|
|
120
124
|
3. The Company (legal entity table + pre-investment cap table)
|
|
121
|
-
4. The Market (TAM/SAM/SOM + structural tailwind + self-employed wedge + domestic adjacency + international upside + pricing)
|
|
125
|
+
4. The Market (TAM/SAM/SOM bottoms-up with geography-tier floor + CAGR with citation + 3-yr market-expansion thesis + market-share trajectory to 3–8% SAM in 5 yrs + structural tailwind + self-employed wedge + domestic adjacency + international upside + pricing)
|
|
122
126
|
5. The Product (what it is + wedge product + upsell path + substrate moat + conversation ingestion + network + Anthropic asymmetric capture + human-services layer)
|
|
123
|
-
6. The Business Model (revenue streams + unit economics)
|
|
127
|
+
6. The Business Model (revenue streams + unit economics — ACV, CAC, LTV, **LTV:CAC**, gross margin, **burn multiple**, churn — each a named line)
|
|
124
128
|
7. Go-to-Market (Wedge → Beachhead → Blitzscale framework + demand evidence + GTM partners + horse-before-cart logic + geography)
|
|
125
129
|
8. Competition (three failing categories + RANL differentiation + most-direct-competitor counter)
|
|
126
130
|
9. Operations (technology stack + data sovereignty + IP ownership chain + compliance posture summary)
|
|
127
131
|
10. Compliance and regulatory positioning (UK consumer protection + UK data/AI regime + EU AI Act + adjacent UK obligations + moat-not-tax close)
|
|
128
132
|
11. Team (founders + strategic shareholders + hiring plan)
|
|
129
|
-
12. Financial Plan (12.1 opening balance sheet through 12.7 use of funds)
|
|
133
|
+
12. Financial Plan (12.1 opening balance sheet through 12.7 use of funds; valuation per round cites `03-cap-table/comparables.md`)
|
|
130
134
|
13. Risks and Mitigations
|
|
131
135
|
14. Milestones (the N-month thesis)
|
|
136
|
+
14b. Exit thesis (target exit value + 5–8-year horizon + exit routes — strategic / PE / IPO — + 3–5 named acquirers with one-line rationale each)
|
|
132
137
|
15. The bottom line (summary table + close)
|
|
133
138
|
+ Appendices (titled documents only; no internal-only file pointers)
|
|
134
139
|
|
|
@@ -140,7 +145,14 @@ Generate `01-narrative/business-plan.md` with **15 sections** following the cano
|
|
|
140
145
|
- **Financial figures derive from the model worksheet.** Cite "Appendix A" by title.
|
|
141
146
|
- **No em-dashes between alphabetic words** in user-facing prose (recurring style violation in this project's history; see `references/internal-workings-scrub.md`).
|
|
142
147
|
|
|
143
|
-
|
|
148
|
+
**Research routing across Stage 3.** Every figure sourced from the wider world routes through the `research-assistant` specialist — never raw `WebSearch` / `WebFetch` from this skill:
|
|
149
|
+
|
|
150
|
+
- **Section 4 (Market)** — TAM/SAM/SOM citations, CAGR sourcing, market-share trajectory baselines, competitor rebuttal facts: dispatch `research-assistant` with `data-research`.
|
|
151
|
+
- **Section 10 (Compliance)** — DMCC Act (UK consumer protection for estate-agency), ICO ADM framework (Articles 22A–22D under UK GDPR + ICO 2025 strategy), EU AI Act (force date, high-risk classification for property-financing decisions): dispatch `research-assistant` with `academic-verify` to retrieve the primary regulatory texts. Cite each in the body.
|
|
152
|
+
- **Section 12 (Financial — valuation comparables)** — recent comparable rounds that feed `03-cap-table/comparables.md`: dispatch `research-assistant` with `data-research`.
|
|
153
|
+
- **Section 14b (Exit thesis)** — 3–5 named acquirers (strategic / PE / IPO) with one-line rationale each, plus recent comparable exits (company / acquirer / multiple / year / source) that feed the exit section of `03-cap-table/comparables.md`: dispatch `research-assistant` with `data-research`.
|
|
154
|
+
|
|
155
|
+
The specialist returns structured findings; the skill quotes those findings verbatim into the relevant section and into `08-market/sources.md` / `03-cap-table/comparables.md`.
|
|
144
156
|
|
|
145
157
|
References: `references/business-plan-template.md` for the section-by-section template; `references/compliance-research-checklist.md` for the UK + EU regulatory regimes to verify.
|
|
146
158
|
|
|
@@ -172,20 +184,21 @@ References: `references/termsheet-template.md`.
|
|
|
172
184
|
|
|
173
185
|
## Stage 4 — Deck blueprint synthesis
|
|
174
186
|
|
|
175
|
-
Generate `01-narrative/deck-blueprint.md` as a **
|
|
187
|
+
Generate `01-narrative/deck-blueprint.md` as a **13-slide brief** the deck designer can execute. Each slide has Purpose, Headline (one-line message), Body (bullets + figures pulled from the business plan), Visual suggestion, and Source reference. The 13 slides:
|
|
176
188
|
|
|
177
189
|
1. Cover (raise headline + founders)
|
|
178
190
|
2. Vision (Vision / Mission / Doctrine)
|
|
179
|
-
3. The Market (TAM + tailwind + wedge)
|
|
191
|
+
3. The Market (TAM + tailwind + wedge + **CAGR with citation**)
|
|
180
192
|
4. Business Model (subscription + service layer + unit economics)
|
|
181
193
|
5. Go-to-Market (Wedge → Beachhead → Blitzscale + named partners)
|
|
182
194
|
6. The Product (substrate + wedge + network + asymmetric capture + services layer)
|
|
183
195
|
7. Competition (three failing categories + most-direct counter)
|
|
184
196
|
8. The Team (founders + strategic shareholders)
|
|
185
|
-
9. Economics (P&L summary + cash flow + break-even)
|
|
197
|
+
9. Economics (P&L summary + cash flow + break-even + **LTV:CAC and burn multiple**)
|
|
186
198
|
10. The Raise (size, valuation, dilution, instrument, use of funds, IP transfer, follow-on round)
|
|
187
|
-
11.
|
|
188
|
-
12.
|
|
199
|
+
11. Exit (target exit value + 5–8-year horizon + routes — strategic / PE / IPO — + 3–5 named acquirers with one-line rationale)
|
|
200
|
+
12. Milestones (M0 to M-final timeline)
|
|
201
|
+
13. Other Information (compliance + platform dependency + contact)
|
|
189
202
|
|
|
190
203
|
Production notes attached: format (16:9 landscape, PDF + source deck), design tokens reference (the operator's project design-tokens spec, path supplied at Stage 5 invocation), chart-source consistency with the financial model, speaker-note attribution.
|
|
191
204
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Business plan template —
|
|
1
|
+
# Business plan template — 16-section structure
|
|
2
2
|
|
|
3
3
|
The canonical structure used by `01-narrative/business-plan.md`. Every public-facing artefact (deck, prospectus, term sheet) derives from this file. Apply the internal-workings scrub (see `internal-workings-scrub.md`) on every revision.
|
|
4
4
|
|
|
@@ -14,13 +14,13 @@ Three blocks. **Vision.** Where the company ends up at full execution. **Mission
|
|
|
14
14
|
Legal entity table (legal name, Companies House number, incorporation date, registered office, SIC, PSC status, sole proposed director on IN01) + pre-investment cap table (sourced from the IN01 verbatim) + post-investment dilution pointer.
|
|
15
15
|
|
|
16
16
|
### 4. The Market
|
|
17
|
-
Subsections: Size of the addressable market (TAM with citation per figure); Structural tailwind (margin squeeze, regulatory tailwind, or equivalent); Self-employed wedge or analogous high-growth segment; Domestic adjacency (next-vertical expansion); International upside (channel partner enabling it); Pricing and TAM (per-customer ACV × addressable count = TAM number).
|
|
17
|
+
Subsections: Size of the addressable market (TAM with citation per figure, bottoms-up construction; geography-tier floor — **late pre-seed TAM is expected to clear $1B US / $500M UK / $500M EU**, flag if the named geography sits below its floor); Market growth rate (single CAGR figure with citation + a one-line 3-year market-expansion thesis stating why the market gets bigger and why this company captures more share as it does); Market-share trajectory (path to 3-8% of SAM within 5 years, reconciled line-by-line against the ARR target in Section 12); Structural tailwind (margin squeeze, regulatory tailwind, or equivalent); Self-employed wedge or analogous high-growth segment; Domestic adjacency (next-vertical expansion); International upside (channel partner enabling it); Pricing and TAM (per-customer ACV × addressable count = TAM number).
|
|
18
18
|
|
|
19
19
|
### 5. The Product
|
|
20
20
|
Subsections: What it is (substrate description, CRM-agnostic / data-sovereign positioning); The wedge product (narrowest unit of value, public-by-default if applicable); The upsell path (wedge → high-value output → full substrate); The substrate moat (operator-data + ontological graph + flywheel); Conversation ingestion (or equivalent lock-in mechanic); The network (federation thesis); Asymmetric-capture position (the LLM-binary wrap argument, with commercial-practice insurance); Human-services layer (training, support, white-glove, anti-fragile-against-frontier-AI).
|
|
21
21
|
|
|
22
22
|
### 6. The Business Model
|
|
23
|
-
Revenue streams (subscription tiers + future network-effect revenue)
|
|
23
|
+
Revenue streams (subscription tiers + future network-effect revenue). Unit economics — each metric is a named line: **ACV**, **CAC**, **LTV**, **LTV:CAC ratio** (target ≥ 3:1 by Month 12), **gross margin** (target ≥ 70% steady-state), **burn multiple** (net burn ÷ net new ARR; target ≤ 2× during wedge, ≤ 1× post-PMF), **churn** (logo + revenue). Compute-mark-up doctrine ("never mark up the LLM compute; customer pays the LLM provider directly").
|
|
24
24
|
|
|
25
25
|
### 7. Go-to-Market
|
|
26
26
|
Wedge → Beachhead → Blitzscale framework (with months and funding source per phase), demand evidence (40+ EOIs, paid intents, founder dogfood, partnership status — every number cited), GTM partners (one row per named partner with role and source), horse-before-cart logic (public-first wedge that earns trust for the private high-value upsell), geography.
|
|
@@ -38,7 +38,7 @@ Three regulatory regimes: UK consumer protection (DMCC Act for estate agency / e
|
|
|
38
38
|
Founders (foregrounded) with role + concise career summary + key credentials + pre-investment shareholding. Strategic shareholders from incorporation (advisors, family, JV partners on the cap table from day one). Hiring plan table with month-triggered roles + salary + trigger condition.
|
|
39
39
|
|
|
40
40
|
### 12. Financial Plan
|
|
41
|
-
12.1 Opening balance sheet (M0 after capex). 12.2 Year-1 Income Statement (revenue + COGS + every opex line + depreciation + EBIT + corp tax + net loss). 12.3 Year-1 cash flow summary table (period-by-period opening, net flow, closing cash). 12.4 Closing balance sheet (M12). 12.5 Two-round funding strategy (timing, size, pre-money, purpose, gating evidence per round). 12.6 Contingency levers. 12.7 Use of funds (this round) by bucket.
|
|
41
|
+
12.1 Opening balance sheet (M0 after capex). 12.2 Year-1 Income Statement (revenue + COGS + every opex line + depreciation + EBIT + corp tax + net loss). 12.3 Year-1 cash flow summary table (period-by-period opening, net flow, closing cash). 12.4 Closing balance sheet (M12). 12.5 Two-round funding strategy (timing, size, pre-money, purpose, gating evidence per round) — **valuation per round cites `03-cap-table/comparables.md`** (recent comparable rounds: company / pre-money / post-money / multiple / source). 12.6 Contingency levers. 12.7 Use of funds (this round) by bucket.
|
|
42
42
|
|
|
43
43
|
### 13. Risks and Mitigations
|
|
44
44
|
Two-column table: risk + mitigation. Cover Loop / Anthropic / competitor-ships-earlier / wedge-fails-to-convert / founder-transition / counsel-delays / Round-2-market / investor-structure.
|
|
@@ -46,6 +46,9 @@ Two-column table: risk + mitigation. Cover Loop / Anthropic / competitor-ships-e
|
|
|
46
46
|
### 14. Milestones (the N-month thesis)
|
|
47
47
|
Month-by-month table: M0 close + closing conditions; M1 first paying customer; M3 product-engineer hire + ~10 customers; M6 wedge phase complete; M7 Round 2 raise opens; M9 Round 2 closes; M12 break-even.
|
|
48
48
|
|
|
49
|
+
### 14b. Exit thesis
|
|
50
|
+
Target exit value (£m), horizon (5–8 years), exit routes considered (strategic acquisition, PE rollup, IPO) with a one-line view on which route is most likely and why. **3–5 named acquirers**, each with a one-line rationale (why they would buy: distribution gap, technology gap, defensive play, vertical entry). Sourced from `08-market/sources.md` and `03-cap-table/comparables.md` (recent exit comparables: company / acquirer / multiple / year / source). Body references "Appendix B" by title.
|
|
51
|
+
|
|
49
52
|
### 15. The bottom line
|
|
50
53
|
Summary table of headline numbers (raise size, pre-money, post-money, dilution, runway, Y1 revenue/loss/cash-burn/closing-cash/ARR, break-even month, Round 2 timing/size). Closing paragraph.
|
|
51
54
|
|
|
@@ -9,8 +9,9 @@ Standard ten numbered sections plus root README, internal-narrative subdirectory
|
|
|
9
9
|
|
|
10
10
|
**Currently present.**
|
|
11
11
|
- `office-hours-design.md` — APPROVED office-hours output (internal).
|
|
12
|
-
- `business-plan.md` —
|
|
13
|
-
- `deck-blueprint.md` —
|
|
12
|
+
- `business-plan.md` — 16-section public business plan.
|
|
13
|
+
- `deck-blueprint.md` — 13-slide brief.
|
|
14
|
+
- `exit-thesis.md` — target exit value, 5–8-year horizon, exit routes (strategic / PE / IPO), 3–5 named acquirers with one-line rationale each.
|
|
14
15
|
|
|
15
16
|
### 02-corporate-legal
|
|
16
17
|
**Purpose.** Statutory documentation. First section any investor's lawyer asks for.
|
|
@@ -20,12 +21,12 @@ Standard ten numbered sections plus root README, internal-narrative subdirectory
|
|
|
20
21
|
### 03-cap-table
|
|
21
22
|
**Purpose.** Who owns what, before and after the round. Most-scrutinised number in seed-stage diligence.
|
|
22
23
|
|
|
23
|
-
**Standard contents.** Pre-investment cap table (per IN01), post-investment cap table (with dilution math), fully-diluted including option pool, founder vesting schedule (if any), share register, subscription letters.
|
|
24
|
+
**Standard contents.** Pre-investment cap table (per IN01), post-investment cap table (with dilution math), fully-diluted including option pool, founder vesting schedule (if any), share register, subscription letters, `comparables.md` (recent comparable rounds — company / pre-money / post-money / multiple / source — that the term sheet's valuation cites).
|
|
24
25
|
|
|
25
26
|
### 04-financials
|
|
26
27
|
**Purpose.** The investability of the raise: runway, burn, revenue ramp, break-even, contingency.
|
|
27
28
|
|
|
28
|
-
**Standard contents.** `model_worksheet.md` (opening cash, capex, monthly burn, MRR ramp, two-round funding strategy, contingency levers), historical accounts (if any), bank statements, unit economics, VAT status.
|
|
29
|
+
**Standard contents.** `model_worksheet.md` (opening cash, capex, monthly burn, MRR ramp, two-round funding strategy, contingency levers), historical accounts (if any), bank statements, unit economics (must include **LTV:CAC ratio** and **burn multiple** as named lines alongside ACV / CAC / LTV / gross margin / churn), VAT status.
|
|
29
30
|
|
|
30
31
|
### 05-commercial
|
|
31
32
|
**Purpose.** Customer pipeline, demand evidence, GTM partners, route-to-revenue.
|
|
@@ -45,7 +46,7 @@ Standard ten numbered sections plus root README, internal-narrative subdirectory
|
|
|
45
46
|
### 08-market
|
|
46
47
|
**Purpose.** Size of the prize, shape of demand, competitive landscape. Every market figure in the business plan must trace to a row in this section.
|
|
47
48
|
|
|
48
|
-
**Standard contents.** `sources.md` (every figure with citation), `competitor-value-claims-rebuttal.md` (vendor-by-vendor rebuttal framework), TAM/SAM/SOM file, customer-segmentation analysis, regulatory landscape, international-expansion potential.
|
|
49
|
+
**Standard contents.** `sources.md` (every figure with citation), `competitor-value-claims-rebuttal.md` (vendor-by-vendor rebuttal framework), TAM/SAM/SOM file (bottoms-up; **geography-tier floor** — late pre-seed TAM is expected to clear $1B US / $500M UK / $500M EU; flag any named geography that sits below its floor), `market-growth-rate.md` (single CAGR figure with citation + one-line 3-year market-expansion thesis), `market-share-trajectory.md` (path to 3–8% SAM within 5 years, reconciled to the ARR target in the business plan), customer-segmentation analysis, regulatory landscape, international-expansion potential.
|
|
49
50
|
|
|
50
51
|
### 09-operations
|
|
51
52
|
**Purpose.** Day-to-day regulatory, compliance, and operational infrastructure.
|
|
@@ -57,6 +58,16 @@ Standard ten numbered sections plus root README, internal-narrative subdirectory
|
|
|
57
58
|
|
|
58
59
|
**Standard contents.** Press kit, pitch deck (live presentation version), demo recording, reference contacts, advisor letters, awards, published thought leadership.
|
|
59
60
|
|
|
61
|
+
### prototype/ (sibling of the ten numbered sections)
|
|
62
|
+
**Purpose.** Running code: landing page source, wedge prototype source, dev-server logs. This is the only top-level under `.docs/data-room/` that ships an executable surface rather than narrative or diligence artefacts. Lives outside the numbered investor sections because investors read the rendered URL, not the source tree.
|
|
63
|
+
|
|
64
|
+
**Standard contents.** One subdirectory per hosted surface (e.g. `landing/`, `prototype/`, `prototype-v2/`), each containing:
|
|
65
|
+
- Framework scaffold (e.g. Vite `package.json`, `src/`, `index.html`) or a single static `index.html`.
|
|
66
|
+
- `.port` — the local port the dev server / file server binds to (allocated by `prototype-host` skill from the 4100–4199 range).
|
|
67
|
+
- Framework dotfiles (`.gitignore`, `vite.config.ts`, etc.).
|
|
68
|
+
|
|
69
|
+
**Lifecycle.** Created by `bin/scaffold.sh` (empty directory) when the data room is first scaffolded. Populated by the `prototype-host` skill when the founder runs "host the landing" or "host the prototype". Multiple surfaces can coexist — port allocation, cloudflared ingress rules, and systemd unit names are all namespaced by surface name.
|
|
70
|
+
|
|
60
71
|
## Top-level README.md doubles as data-room index
|
|
61
72
|
|
|
62
73
|
Three things at the root:
|
|
@@ -1,23 +1,24 @@
|
|
|
1
|
-
# Deck blueprint template —
|
|
1
|
+
# Deck blueprint template — 13 slides
|
|
2
2
|
|
|
3
3
|
Each slide is specified by Purpose, Headline (one-line message), Body (bullets + figures pulled from the business plan), Visual suggestion, and Source reference. The deck is the presentation surface; the business plan is the source of truth.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## 13-slide layout
|
|
6
6
|
|
|
7
7
|
| # | Slide | What it lands |
|
|
8
8
|
|---|---|---|
|
|
9
9
|
| 1 | Cover | Company name, raise headline, three foregrounded founders, Companies House identifier. |
|
|
10
10
|
| 2 | Vision | Vision / Mission / Doctrine triad. |
|
|
11
|
-
| 3 | The Market | TAM with citation, structural tailwind (margin-squeeze / regulatory / equivalent), self-employed or analogous wedge, domestic adjacency, international upside, pricing band
|
|
11
|
+
| 3 | The Market | TAM with citation, structural tailwind (margin-squeeze / regulatory / equivalent), self-employed or analogous wedge, domestic adjacency, international upside, pricing band, **CAGR with citation**. |
|
|
12
12
|
| 4 | Business Model | Subscription tiers + hardware + service layer + future network-effect revenue + unit economics + compute-no-markup doctrine. |
|
|
13
13
|
| 5 | Go-to-Market | Wedge → Beachhead → Blitzscale framework, demand evidence numbers, named GTM partners, horse-before-cart logic. |
|
|
14
14
|
| 6 | The Product | Substrate description, wedge, upsell path, substrate moat, conversation ingestion, network, asymmetric capture, services layer. |
|
|
15
15
|
| 7 | Competition | Three failing categories + most-direct-competitor counter (CRM-agnostic vs migration-required). |
|
|
16
16
|
| 8 | The Team | Founders + strategic shareholders, with one-line credential per person and shareholding %. |
|
|
17
|
-
| 9 | Economics | Y1 revenue, P&L loss, cash burn, M11 cash low, M12 closing cash, closing ARR, break-even month
|
|
17
|
+
| 9 | Economics | Y1 revenue, P&L loss, cash burn, M11 cash low, M12 closing cash, closing ARR, break-even month, **LTV:CAC and burn multiple**. Two-panel chart: MRR ramp with burn overlay + monthly cash balance. |
|
|
18
18
|
| 10 | The Raise | Size, pre-money, post-money, dilution, instrument, use of funds, IP transfer at close, Round 2 size + timing, pre-emption. Pie chart of post-investment cap table. |
|
|
19
|
-
| 11 |
|
|
20
|
-
| 12 |
|
|
19
|
+
| 11 | Exit | Target exit value, 5–8-year horizon, exit routes (strategic / PE / IPO), 3–5 named acquirers with one-line rationale each. Sourced from `01-narrative/exit-thesis.md`. |
|
|
20
|
+
| 12 | Milestones | M0 to M-final timeline with MRR curve and Round-1 / Round-2 close markers. |
|
|
21
|
+
| 13 | Other Information | Compliance (DMCC + UK ICO + EU AI Act), platform-dependency disclosure with the commercial-practice-insurance answer, contact card (founders + email + web). |
|
|
21
22
|
|
|
22
23
|
## Production notes attached to the blueprint
|
|
23
24
|
|
|
@@ -32,14 +32,13 @@ You are a **YC office hours partner**. Your job is to ensure the problem is unde
|
|
|
32
32
|
|
|
33
33
|
## Phase 1: Context Gathering
|
|
34
34
|
|
|
35
|
-
Understand the
|
|
35
|
+
Understand the operator's business and the area they want to change.
|
|
36
36
|
|
|
37
|
-
1. Read
|
|
38
|
-
2.
|
|
39
|
-
3.
|
|
40
|
-
4. **List any prior office-hours design docs on disk** under the operator's project (e.g. the data-room `01-narrative/` directory when invoked from `venture-studio`, or the operator-supplied path otherwise). If prior designs exist, list them: "Prior designs for this project: [titles + dates]"
|
|
37
|
+
1. Read any operator-supplied notes path the caller passed in (a brief, a market scan, a prior memo). If no path was passed, skip.
|
|
38
|
+
2. **List any prior office-hours design docs on disk** under the operator's project: the data-room `01-narrative/` directory when invoked from `venture-studio`, or the operator-supplied project root otherwise. If prior designs exist, list them: "Prior designs for this project: [titles + dates]"
|
|
39
|
+
3. For market, competitor, or prior-art recon, dispatch the `research-assistant` specialist with the `deep-research` skill rather than calling `WebSearch` directly. The specialist returns structured findings the design doc can cite.
|
|
41
40
|
|
|
42
|
-
|
|
41
|
+
4. **Ask: what's your goal with this?** This is a real question, not a formality. The answer determines everything about how the session runs.
|
|
43
42
|
|
|
44
43
|
Via AskUserQuestion, ask:
|
|
45
44
|
|
|
@@ -56,7 +55,7 @@ Understand the project and the area the user wants to change.
|
|
|
56
55
|
- Startup, intrapreneurship → **Startup mode** (Phase 2A)
|
|
57
56
|
- Hackathon, open source, research, learning, having fun → **Builder mode** (Phase 2B)
|
|
58
57
|
|
|
59
|
-
|
|
58
|
+
5. **Assess product stage** (only for startup/intrapreneurship modes):
|
|
60
59
|
- Pre-product (idea stage, no users yet)
|
|
61
60
|
- Has users (people using it, not yet paying)
|
|
62
61
|
- Has paying customers
|
|
@@ -275,7 +274,7 @@ If no matches found, proceed silently.
|
|
|
275
274
|
|
|
276
275
|
## Phase 2.75: Landscape Awareness
|
|
277
276
|
|
|
278
|
-
|
|
277
|
+
**Search Before Building — three layers, eureka moments.** Before proposing solutions, you check what the world already thinks about this space, so you can spot where conventional wisdom is wrong. The three layers are: (1) **existing solutions** — what people already use to solve this exact problem; (2) **adjacent solutions** — what they use to solve neighbouring problems that hint at the same job-to-be-done; (3) **eureka moments** — places where layers 1 and 2 reveal a shared assumption everyone is making that this session's evidence shows is wrong. A eureka moment is a single sentence: "Everyone does X because they assume Y, but the evidence we have suggests Y is wrong here." Layer 3 is the only layer that justifies building something different.
|
|
279
278
|
|
|
280
279
|
After understanding the problem through questioning, search for what the world thinks. This is NOT competitive research (that's /design-consultation's job). This is understanding conventional wisdom so you can evaluate where it's wrong.
|
|
281
280
|
|
|
@@ -302,7 +301,7 @@ Read the top 2-3 results. Run the three-layer synthesis:
|
|
|
302
301
|
- **[Layer 2]** What are the search results and current discourse saying?
|
|
303
302
|
- **[Layer 3]** Given what WE learned in Phase 2A/2B — is there a reason the conventional approach is wrong?
|
|
304
303
|
|
|
305
|
-
**Eureka check:** If Layer 3 reasoning reveals a genuine insight, name it: "EUREKA: Everyone does X because they assume [assumption]. But [evidence from our conversation] suggests that's wrong here. This means [implication]."
|
|
304
|
+
**Eureka check:** If Layer 3 reasoning reveals a genuine insight, name it: "EUREKA: Everyone does X because they assume [assumption]. But [evidence from our conversation] suggests that's wrong here. This means [implication]." Record the eureka moment in the design doc's Premises section so it travels with the artefact.
|
|
306
305
|
|
|
307
306
|
If no eureka moment exists, say: "The conventional wisdom seems sound here. Let's build on it." Proceed to Phase 3.
|
|
308
307
|
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: prototype-host
|
|
3
|
+
description: Use when the operator asks to "host the landing", "host the prototype", "deploy this", "give me a public URL", or any variant that means "make the landing page or wedge prototype reachable on a real URL the founder can send to a customer". Scaffolds a source tree, allocates a local port, edits the brand's cloudflared ingress, creates a DNS row, runs the dev server (or static file-server) under a systemd-user unit, and verifies HTTP 200 from outside the box. Idempotent: re-run for the same surface restarts cleanly without duplicating ports, ingress rows, or units.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# prototype-host
|
|
7
|
+
|
|
8
|
+
## Outcome
|
|
9
|
+
|
|
10
|
+
A founder asks "host the landing" or "host the prototype" and ends the turn with a working public URL — `https://<surface>.<brand-hostname>` — that returns HTTP 200, backed by a dev server (or static file server) supervised by systemd so it survives reboot. No CI, no Vercel, no Pages — the install device itself serves the prototype through the brand's existing cloudflared tunnel.
|
|
11
|
+
|
|
12
|
+
The skill is a composition of primitives that already exist on every Maxy Code install: cloudflared multi-hostname ingress (see [`cloudflared/references/manual-setup.md`](../../../../platform/plugins/cloudflare/references/manual-setup.md)), `systemctl --user` unit files for per-process supervision, and the agent's Bash + Read + Write + Edit tools for source scaffolding. The skill's job is to compose them deterministically so the founder never has to.
|
|
13
|
+
|
|
14
|
+
## Inputs
|
|
15
|
+
|
|
16
|
+
The agent gathers these before invoking any of the six phases. Defaults below; use `AskUserQuestion` only when the operator's intent is ambiguous about surface name or framework.
|
|
17
|
+
|
|
18
|
+
| Input | Default | Notes |
|
|
19
|
+
|---|---|---|
|
|
20
|
+
| `surface` | `landing` for "host the landing"; `prototype` for "host the prototype"; otherwise ask | The DNS label; becomes `<surface>.<brand-hostname>`. Lowercase, kebab-case, must be a valid DNS label (`^[a-z0-9-]+$`, max 63 chars). |
|
|
21
|
+
| `framework` | `static` for `landing`; `vite` for `prototype` | One of `static`, `vite`, `next`, `sveltekit`, `astro`. See [`references/scaffold-frameworks.md`](references/scaffold-frameworks.md). |
|
|
22
|
+
| `surface-dir` | `${PROJECT_ROOT}/.docs/data-room/prototype/<surface>/` | Source tree root. |
|
|
23
|
+
|
|
24
|
+
Two environment values the skill derives, never asks for:
|
|
25
|
+
|
|
26
|
+
- `BRAND` — from `jq -r '.hostname' <PROJECT_ROOT>/platform/config/brand.json` (same idiom every other skill uses).
|
|
27
|
+
- `BRAND_HOSTNAME` — the cloudflared root domain for this install: `jq -r '.cloudflareRootDomain // .hostname' <PROJECT_ROOT>/platform/config/brand.json`. If the field is empty, abort with literal stderr `[prototype-host] FATAL brand-hostname-unresolved — set cloudflareRootDomain in brand.json`.
|
|
28
|
+
|
|
29
|
+
## Hard prerequisite — brand-pack must have run
|
|
30
|
+
|
|
31
|
+
Before phase 1, check `[ -d "${PROJECT_ROOT}/.docs/data-room/06-product-ip/brand" ]` and `[ -n "$(ls -A "${PROJECT_ROOT}/.docs/data-room/06-product-ip/brand" 2>/dev/null)" ]`. If either fails, abort:
|
|
32
|
+
|
|
33
|
+
```
|
|
34
|
+
[prototype-host] FATAL brand-pack-missing — run brand-pack first; hosted surfaces consume 06-product-ip/brand/{color-palette,typography-system,tone-of-voice}.md
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
This is doctrinal — hosting a brandless landing ships a surface that either confounds conversion data or forces a re-render after brand-pack. The check is exit-code, not LLM judgement.
|
|
38
|
+
|
|
39
|
+
## Phases
|
|
40
|
+
|
|
41
|
+
Every phase emits exactly one structured stdout line on success:
|
|
42
|
+
|
|
43
|
+
```
|
|
44
|
+
[prototype-host] phase=<n> surface=<surface> framework=<framework> port=<port> ingress=<state> dns=<state> service=<unit> status=<systemd-state> http=<code>
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Any phase that cannot produce its key/value pair fails by emitting literal stderr (no narration, no retry, no menu-phrasings — [[feedback_no_stdout_parsing_for_control_flow]]) and exits non-zero. The agent surfaces the stderr verbatim to the operator.
|
|
48
|
+
|
|
49
|
+
### Phase 1 — Surface intake (idempotency check)
|
|
50
|
+
|
|
51
|
+
If `<surface-dir>/.port` exists, this is a re-run. Read the port from `.port`, skip directly to phase 5 (systemd restart) then phase 6 (verify). Log:
|
|
52
|
+
|
|
53
|
+
```
|
|
54
|
+
[prototype-host] phase=1 surface=<surface> idempotent=true port=<port>
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Otherwise proceed to phase 2.
|
|
58
|
+
|
|
59
|
+
### Phase 2 — Scaffold source
|
|
60
|
+
|
|
61
|
+
Run the framework's canonical scaffolder into `<surface-dir>/`. The exact commands per framework live in [`references/scaffold-frameworks.md`](references/scaffold-frameworks.md). Static `landing` is a special case: write `<surface-dir>/index.html` directly from `01-narrative/LANDING.md` using the brand tokens.
|
|
62
|
+
|
|
63
|
+
Brand application (every framework):
|
|
64
|
+
|
|
65
|
+
1. Read `06-product-ip/brand/color-palette.md` — extract the CSS custom properties (the file ships a `:root { --color-*: ... }` block).
|
|
66
|
+
2. Read `06-product-ip/brand/typography-system.md` — extract the font-family + scale tokens.
|
|
67
|
+
3. For `static`: inline both into the `<head>` of `<surface-dir>/index.html`.
|
|
68
|
+
4. For framework scaffolds: write the tokens into the framework's global stylesheet entry point (`src/index.css` for Vite/Astro, `app/globals.css` for Next, `src/app.css` for SvelteKit).
|
|
69
|
+
5. For the landing's hero + CTA copy: read `06-product-ip/brand/tone-of-voice.md` and apply it when rewriting `01-narrative/LANDING.md` into HTML.
|
|
70
|
+
|
|
71
|
+
### Phase 3 — Port allocation
|
|
72
|
+
|
|
73
|
+
First unbound port in 4100–4199:
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
for p in $(seq 4100 4199); do
|
|
77
|
+
ss -tln 2>/dev/null | awk '{print $4}' | grep -qE ":${p}$" || { echo "$p"; break; }
|
|
78
|
+
done
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Write to `<surface-dir>/.port`. If the range is exhausted, abort:
|
|
82
|
+
|
|
83
|
+
```
|
|
84
|
+
[prototype-host] FATAL port-range-exhausted range=4100-4199 — free a port or extend the range
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
The range is a skill constant (not a `brand.json` field) because it sits below every documented admin/chat/VNC band and above the OS ephemeral range default. Extending the range is a follow-up task, not a per-install knob.
|
|
88
|
+
|
|
89
|
+
### Phase 4 — Cloudflared ingress edit
|
|
90
|
+
|
|
91
|
+
Per [`references/cloudflared-ingress-edit.md`](references/cloudflared-ingress-edit.md):
|
|
92
|
+
|
|
93
|
+
1. Append a hostname rule for `<surface>.<BRAND_HOSTNAME>` → `http://localhost:<port>` immediately before the final `http_status:404` catch-all in `${CFG_DIR}/config.yml`. The reference doc carries the exact `awk` insert pattern (sed cannot safely insert before the last line of a multi-line YAML rule).
|
|
94
|
+
2. Validate: `cloudflared --origincert "${CFG_DIR}/cert.pem" --config "${CFG_DIR}/config.yml" tunnel ingress validate`. Non-zero exit aborts with the literal cloudflared error.
|
|
95
|
+
3. Create DNS row: `cloudflared --origincert "${CFG_DIR}/cert.pem" tunnel route dns --overwrite-dns "${TUNNEL_ID}" <surface>.<BRAND_HOSTNAME>`. `TUNNEL_ID` comes from `${CFG_DIR}/tunnel.state` (the Step 5b file every install writes).
|
|
96
|
+
4. Reload cloudflared: `systemctl --user restart ${BRAND}-cloudflared.service`.
|
|
97
|
+
|
|
98
|
+
Idempotency: before appending, grep `${CFG_DIR}/config.yml` for `<surface>.<BRAND_HOSTNAME>`. If present, skip the append + DNS route + reload — the row already exists; this is a re-run after a failed phase 5 or 6.
|
|
99
|
+
|
|
100
|
+
### Phase 5 — Systemd user unit
|
|
101
|
+
|
|
102
|
+
Per [`references/systemd-user-service.md`](references/systemd-user-service.md), write `${HOME}/.config/systemd/user/${BRAND}-prototype-<surface>.service`. Two modes:
|
|
103
|
+
|
|
104
|
+
- **Dev-server mode** (frameworks with hot-reload — Vite, Next dev, SvelteKit dev, Astro dev): `ExecStart=` runs the framework's dev command bound to `<port>` via `PORT=` or `--port`.
|
|
105
|
+
- **Static file-server mode** (the `static` framework): run `npm run build` first (no-op for raw HTML), then `ExecStart=cloudflared file-server --port <port> <surface-dir>` (or `<surface-dir>/dist` for built output). No Node process for raw static landings.
|
|
106
|
+
|
|
107
|
+
Then:
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
systemctl --user daemon-reload
|
|
111
|
+
systemctl --user enable --now "${BRAND}-prototype-<surface>.service"
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
Check `systemctl --user is-active "${BRAND}-prototype-<surface>.service"` returns `active`. If not, dump the last 50 lines of `journalctl --user -u ${BRAND}-prototype-<surface>.service -n 50 --no-pager` to stderr and abort.
|
|
115
|
+
|
|
116
|
+
### Phase 6 — External verification
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
curl -I -m 15 "https://<surface>.<BRAND_HOSTNAME>"
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
The skill emits the full HTTP response line (e.g. `HTTP/2 200`) to chat. Anything other than `200` aborts with the full curl output as literal stderr — same setup-done contract Task 288 established for cloudflare setup. This is end-to-end proof because the chat itself runs through the same tunnel: if the cloudflared connector were dead, the agent would never have answered the operator.
|
|
123
|
+
|
|
124
|
+
Final success line:
|
|
125
|
+
|
|
126
|
+
```
|
|
127
|
+
[prototype-host] DONE surface=<surface> url=https://<surface>.<BRAND_HOSTNAME> port=<port> service=${BRAND}-prototype-<surface>.service http=200
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
## Idempotency contract
|
|
131
|
+
|
|
132
|
+
Re-running the skill with the same `<surface>` is a first-class flow, not an error:
|
|
133
|
+
|
|
134
|
+
| State on re-run | Behaviour |
|
|
135
|
+
|---|---|
|
|
136
|
+
| `<surface-dir>/.port` exists, ingress row exists, service active | Restart the systemd unit; re-verify; emit `idempotent=true` |
|
|
137
|
+
| `.port` exists, ingress row missing | Re-run phase 4 (append, validate, route, reload); restart unit; verify |
|
|
138
|
+
| `.port` exists, service failed | Restart unit; if still failing, dump journal and abort |
|
|
139
|
+
| Nothing exists | Fresh six-phase run |
|
|
140
|
+
|
|
141
|
+
The skill never allocates a second port for the same surface, never appends a duplicate ingress row, never creates a second systemd unit with a different name.
|
|
142
|
+
|
|
143
|
+
## Failure surfaces
|
|
144
|
+
|
|
145
|
+
Likely failure points and the literal stderr the agent should expect:
|
|
146
|
+
|
|
147
|
+
- **Port range exhausted** — `[prototype-host] FATAL port-range-exhausted range=4100-4199`
|
|
148
|
+
- **Ingress validate fails** — cloudflared's own multi-line YAML error, verbatim
|
|
149
|
+
- **DNS route fails** — cloudflared's stderr (typically a 1xxx error code from the API)
|
|
150
|
+
- **Systemd unit fails to start** — last 50 lines of journalctl, verbatim
|
|
151
|
+
- **Curl returns non-200** — full `curl -I` output, verbatim
|
|
152
|
+
|
|
153
|
+
Diagnostic commands the agent should suggest on failure:
|
|
154
|
+
|
|
155
|
+
```bash
|
|
156
|
+
cat ${CFG_DIR}/config.yml
|
|
157
|
+
cloudflared --origincert "${CFG_DIR}/cert.pem" --config ${CFG_DIR}/config.yml tunnel ingress validate
|
|
158
|
+
systemctl --user status ${BRAND}-prototype-<surface>.service
|
|
159
|
+
journalctl --user -u ${BRAND}-prototype-<surface>.service -n 200 --no-pager
|
|
160
|
+
ss -tln | grep :<port>
|
|
161
|
+
dig <surface>.<BRAND_HOSTNAME>
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
## Out of scope
|
|
165
|
+
|
|
166
|
+
- Production hosting (Cloudflare Pages, Vercel, Netlify, Workers). The dev server on the install device covers the founder workflow; production deploy is a separate, later task.
|
|
167
|
+
- TLS / cert handling beyond cloudflared's own.
|
|
168
|
+
- Per-prototype auth gating — the public landing is public; access control is a separate skill.
|
|
169
|
+
- `brand.json` schema changes. Port range is a skill constant.
|
|
170
|
+
- `paths.ts` reads.
|
|
171
|
+
- Multi-tunnel — one tunnel per install with multiple ingress rules is the existing pattern.
|
|
172
|
+
- CI/CD or git-push deploy.
|
|
173
|
+
- Pre-built framework templates beyond the framework's official `create-*` scaffolders.
|
|
174
|
+
- Telemetry on the public URL — the founder wires their own (Plausible, GA, server logs).
|
|
175
|
+
- A `prototype-host-remove` companion skill. For now: `systemctl --user disable --now ${BRAND}-prototype-<surface>.service` + manually strip the ingress row + delete the DNS record. Removal is a follow-up task if it becomes friction.
|
|
176
|
+
|
|
177
|
+
## Multi-prototype is supported by construction
|
|
178
|
+
|
|
179
|
+
Port allocation scans first-free; ingress rules are additive; systemd unit names are namespaced by `<surface>`. Running `landing` + `prototype` + `prototype-v2` simultaneously on the same install requires no special handling — invoke the skill three times with three different surface names.
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
# Cloudflared ingress edit — append a hostname rule before the catch-all
|
|
2
|
+
|
|
3
|
+
This is the canonical pattern for adding a new hostname → local port mapping to an existing brand cloudflared `config.yml`. Sourced from the multi-hostname ingress block documented at [`platform/plugins/cloudflare/references/manual-setup.md`](../../../../../platform/plugins/cloudflare/references/manual-setup.md) under the "Multi-ingress: adding hostnames for prototype services" section.
|
|
4
|
+
|
|
5
|
+
## The config.yml shape
|
|
6
|
+
|
|
7
|
+
A working brand `config.yml` always looks like:
|
|
8
|
+
|
|
9
|
+
```yaml
|
|
10
|
+
tunnel: <TUNNEL_ID>
|
|
11
|
+
credentials-file: <CFG_DIR>/<TUNNEL_ID>.json
|
|
12
|
+
ingress:
|
|
13
|
+
- hostname: admin.<BRAND_HOSTNAME>
|
|
14
|
+
service: http://localhost:<PORT>
|
|
15
|
+
- hostname: public.<BRAND_HOSTNAME>
|
|
16
|
+
service: http://localhost:<PORT>
|
|
17
|
+
- service: http_status:404
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
A new prototype rule must land **before** the `http_status:404` catch-all; otherwise cloudflared matches the catch-all first and the prototype hostname returns 404.
|
|
21
|
+
|
|
22
|
+
## The append pattern
|
|
23
|
+
|
|
24
|
+
`sed` cannot safely insert before the last block of a multi-line YAML rule (`- service: http_status:404` is one logical entry but the line above it might be a comment or blank). `awk` is the right primitive: scan for the literal `- service: http_status:404` line and insert two lines before it.
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
SURFACE="<surface>" # e.g. landing
|
|
28
|
+
PORT="<port>" # from <surface-dir>/.port
|
|
29
|
+
HOSTNAME="${SURFACE}.${BRAND_HOSTNAME}"
|
|
30
|
+
|
|
31
|
+
# Idempotency guard — skip if the hostname already appears as an ingress rule.
|
|
32
|
+
if grep -qE "^[[:space:]]*-[[:space:]]+hostname:[[:space:]]+${HOSTNAME}\b" "${CFG_DIR}/config.yml"; then
|
|
33
|
+
echo "[prototype-host] ingress-row-exists hostname=${HOSTNAME} — skipping append"
|
|
34
|
+
else
|
|
35
|
+
awk -v host="${HOSTNAME}" -v port="${PORT}" '
|
|
36
|
+
/^[[:space:]]*-[[:space:]]+service:[[:space:]]+http_status:404[[:space:]]*$/ {
|
|
37
|
+
print " - hostname: " host
|
|
38
|
+
print " service: http://localhost:" port
|
|
39
|
+
}
|
|
40
|
+
{ print }
|
|
41
|
+
' "${CFG_DIR}/config.yml" > "${CFG_DIR}/config.yml.new"
|
|
42
|
+
mv "${CFG_DIR}/config.yml.new" "${CFG_DIR}/config.yml"
|
|
43
|
+
fi
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Validate, route, reload
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
# 1. Validate the YAML and ingress semantics.
|
|
50
|
+
cloudflared --origincert "${CFG_DIR}/cert.pem" \
|
|
51
|
+
--config "${CFG_DIR}/config.yml" \
|
|
52
|
+
tunnel ingress validate
|
|
53
|
+
|
|
54
|
+
# 2. Create the DNS row (CNAME from <hostname> to <TUNNEL_ID>.cfargotunnel.com).
|
|
55
|
+
TUNNEL_ID=$(jq -r '.id // .tunnelId' "${CFG_DIR}/tunnel.state")
|
|
56
|
+
cloudflared --origincert "${CFG_DIR}/cert.pem" \
|
|
57
|
+
tunnel route dns --overwrite-dns "${TUNNEL_ID}" "${HOSTNAME}"
|
|
58
|
+
|
|
59
|
+
# 3. Reload the connector so it picks up the new ingress rule.
|
|
60
|
+
systemctl --user restart "${BRAND}-cloudflared.service"
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Each step is its own command, runs sequentially, exits non-zero on failure. The skill propagates the failing command's stderr verbatim — no parsing, no narration ([[feedback_no_stdout_parsing_for_control_flow]]).
|
|
64
|
+
|
|
65
|
+
## What `--overwrite-dns` does
|
|
66
|
+
|
|
67
|
+
If a CNAME for `<hostname>` already exists in the account's DNS (e.g. from a prior install), `tunnel route dns` errors with `record already exists`. `--overwrite-dns` replaces the existing record with one pointing at this tunnel. Use it unconditionally — the alternative (probe-then-create) doubles the API surface and races with concurrent DNS edits.
|
|
68
|
+
|
|
69
|
+
## Why restart, not reload
|
|
70
|
+
|
|
71
|
+
`cloudflared` watches `config.yml` only when launched with `--config-watch` (off by default in the brand service unit). `systemctl --user restart` is the deterministic way to pick up the new rule. Brief connection blip (~1s) is acceptable because the brand's admin + public hostnames already tolerate the same blip on every cloudflared upgrade.
|
|
72
|
+
|
|
73
|
+
## Failure points
|
|
74
|
+
|
|
75
|
+
| Symptom | Root cause | Fix |
|
|
76
|
+
|---|---|---|
|
|
77
|
+
| `validate: ingress rule N has no service` | `awk` inserted only the hostname line, not the service line | Re-run; the snippet emits both lines atomically per match |
|
|
78
|
+
| `validate: failed to parse YAML` | A previous `awk` run left a partial line | `cat ${CFG_DIR}/config.yml` and hand-fix; the skill cannot recover from corrupt YAML |
|
|
79
|
+
| `route dns: 1004 invalid hostname` | `<surface>` violates DNS label rules (uppercase, underscore, leading dash) | Re-run with a valid `<surface>`; the skill validates `^[a-z0-9-]+$` before phase 4 |
|
|
80
|
+
| `route dns: 9103 unauthorized` | The cert.pem in `${CFG_DIR}` doesn't grant DNS-edit on the zone | Re-run Step 1 of the cloudflare runbook to refresh `cert.pem` |
|
|
81
|
+
| Restart succeeds but `curl -I` returns 502 | The dev server isn't actually listening on `<port>` | Phase 5 (systemd) failed earlier; the skill should have caught it. Read `journalctl --user -u ${BRAND}-prototype-<surface>.service -n 50` |
|