From b246207cb7448642302d7e2339a90081cb964082 Mon Sep 17 00:00:00 2001 From: Michael Ensor Date: Thu, 16 Apr 2026 23:59:37 +0800 Subject: [PATCH 01/15] fix: analyzer OpenAI runtime guard, fetch timeout/retry, model env var A3: Add a runtime guard in callOpenAI that throws a clear error when OPENAI_API_KEY is missing or malformed instead of silently failing with a 401. Replace bare fetch with fetchWithRetry (30s timeout, 2 retries with backoff) to handle transient network errors. A4: Replace hardcoded 'claude-haiku-4-5-20250315' at line 15 with process.env.EXITSTORM_ANALYSIS_MODEL ?? 'claude-haiku-4-5-20250315'. Document the new var in .env.example and README.md environment table. Agent: claude-sonnet-4-6 Session: action-a-exitstorm-rebuild Plan: ~/.claude/plans/inherited-exploring-lovelace.md --- .env.example | 3 +++ README.md | 12 +++++++++++ packages/analyzer/src/analyze.ts | 37 ++++++++++++++++++++++++++++++-- 3 files changed, 50 insertions(+), 2 deletions(-) diff --git a/.env.example b/.env.example index cf33833..a265ac8 100644 --- a/.env.example +++ b/.env.example @@ -5,6 +5,9 @@ ANTHROPIC_API_KEY= # sk-ant-api* format OPENAI_API_KEY= # sk-* format (fallback if Anthropic unavailable) +# Model override (optional - defaults to claude-haiku-4-5-20250315) +EXITSTORM_ANALYSIS_MODEL= + # Database DB_PATH=data/contributions.db diff --git a/README.md b/README.md index 0a150e4..3610be6 100644 --- a/README.md +++ b/README.md @@ -63,6 +63,18 @@ pnpm build pnpm test ``` +### Environment variables + +Copy `.env.example` to `.env` and fill in at least one AI provider key: + +| Variable | Required | Default | Description | +|---|---|---|---| +| `ANTHROPIC_API_KEY` | One of these two | - | Anthropic API key (`sk-ant-api*`). Preferred provider. | +| `OPENAI_API_KEY` | One of these two | - | OpenAI key (`sk-*`). Fallback if Anthropic is unavailable or unset. | +| `EXITSTORM_ANALYSIS_MODEL` | No | `claude-haiku-4-5-20250315` | Override the Anthropic model used for analysis. | +| `DB_PATH` | No | `data/contributions.db` | Path to the SQLite database file. | +| `EXITSTORM_IMAGE_SCRIPT` | No | - | Path to an external image generation script. Graphics are skipped if unset. | + ### CLI usage ```bash diff --git a/packages/analyzer/src/analyze.ts b/packages/analyzer/src/analyze.ts index 8ecb890..0d97347 100644 --- a/packages/analyzer/src/analyze.ts +++ b/packages/analyzer/src/analyze.ts @@ -8,11 +8,39 @@ import { buildAnalysisPrompt } from './prompt.js'; // ── AI Providers ─────────────────────────────────────────────────────────── +const ANALYSIS_MODEL = process.env.EXITSTORM_ANALYSIS_MODEL ?? 'claude-haiku-4-5-20250315'; + +/** Fetch with a timeout and up to `retries` retry attempts on network errors. */ +async function fetchWithRetry( + url: string, + init: RequestInit, + timeoutMs = 30_000, + retries = 2, +): Promise { + let lastErr: unknown; + for (let attempt = 0; attempt <= retries; attempt++) { + const controller = new AbortController(); + const timer = setTimeout(() => controller.abort(), timeoutMs); + try { + const res = await fetch(url, { ...init, signal: controller.signal }); + clearTimeout(timer); + return res; + } catch (err) { + clearTimeout(timer); + lastErr = err; + if (attempt < retries) { + await new Promise((r) => setTimeout(r, 500 * (attempt + 1))); + } + } + } + throw lastErr; +} + async function callAnthropic(apiKey: string, prompt: string): Promise { const { default: Anthropic } = await import('@anthropic-ai/sdk'); const client = new Anthropic({ apiKey }); const response = await client.messages.create({ - model: 'claude-haiku-4-5-20250315', + model: ANALYSIS_MODEL, max_tokens: 1800, messages: [{ role: 'user', content: prompt }], }); @@ -21,7 +49,12 @@ async function callAnthropic(apiKey: string, prompt: string): Promise { } async function callOpenAI(apiKey: string, prompt: string): Promise { - const res = await fetch('https://api.openai.com/v1/chat/completions', { + if (!apiKey?.startsWith('sk-')) { + throw new Error( + 'OPENAI_API_KEY is missing or malformed. Set it to a valid sk-* key before using the OpenAI provider.', + ); + } + const res = await fetchWithRetry('https://api.openai.com/v1/chat/completions', { method: 'POST', headers: { Authorization: `Bearer ${apiKey}`, From 07ce3695b3ba8575ec2a2d9ca0a77ab8b220765f Mon Sep 17 00:00:00 2001 From: Michael Ensor Date: Tue, 14 Apr 2026 02:54:10 +0800 Subject: [PATCH 02/15] docs: add presentation --- docs/presentation/index.html | 291 +++++++++++++++++++++++++++++++++++ 1 file changed, 291 insertions(+) create mode 100644 docs/presentation/index.html diff --git a/docs/presentation/index.html b/docs/presentation/index.html new file mode 100644 index 0000000..01a2eaf --- /dev/null +++ b/docs/presentation/index.html @@ -0,0 +1,291 @@ + + + + + +Exitstorm + + + + + + +
+
+
+ +
+
+ +
+
+
+
ARC Web
+

Exitstorm

+
Community-powered micro-SaaS exit machine. Discord → financial model → team → build → exit.
+
Open SourceGitHubProduction
+
+
+ +
+ +
+
+
+
What it does
+

Key features

+
+
+
+ +
+--------------+
+
+--------------+
+
+
+ +
| @exitstorm
+
| @exitstorm |
+
+
+ +
|
+
| /core | <- types, constants, utils
+
+
+
+ +
+ +
+
+
+
By the numbers
+

Repository stats

+
+
+
100%
+
Open Source
+
+
+
MIT
+
License
+
+
+
+
Potential
+
+ +
+
+ +
+ +
+
+
+
Get started
+

Clone and explore

+
Start contributing today
+
"comment"># Clone the repo
git clone https://github.com/arc-web/exitstorm.git
cd exitstorm
"comment"># Read the README for next steps
cat README.md
+
+
+ +
+ +
+
+
+
Open source software powers innovation.
Join us on GitHub.
+
+
arc-web/exitstorm
+
+
+
+ + +
1 / 5
+
\u2190 \u2192 arrow keys to navigate
+ + + + \ No newline at end of file From 9798425a351663c08688268146c68e657b5df21a Mon Sep 17 00:00:00 2001 From: Michael Ensor Date: Tue, 14 Apr 2026 05:09:52 +0800 Subject: [PATCH 03/15] docs: add presentation --- docs/presentation/index.html | 83 +++++++++++++----------------------- 1 file changed, 30 insertions(+), 53 deletions(-) diff --git a/docs/presentation/index.html b/docs/presentation/index.html index 01a2eaf..ad7bf6e 100644 --- a/docs/presentation/index.html +++ b/docs/presentation/index.html @@ -133,85 +133,62 @@
-
-
+
+
ARC Web
-

Exitstorm

-
Community-powered micro-SaaS exit machine. Discord → financial model → team → build → exit.
-
Open SourceGitHubProduction
+

Exitstorm
Delivering impact

+
[![CI](https://github.com/arc-web/exitstorm/actions/workflows/ci.yml/badge.svg)](https://github.com/arc-web/exitstorm/actions)
+
TypeScriptOpen SourceProduction
-
-
-
-
What it does
-

Key features

-
-
-
- -
+--------------+
-
+--------------+
-
-
- -
| @exitstorm
-
| @exitstorm |
-
-
- -
|
-
| /core | <- types, constants, utils
-
-
-
- -
- -
-
+
+
By the numbers
-

Repository stats

+

Real impact

-
100%
-
Open Source
+
,
+
priority scores
+
+
+
,
+
team recommendations
-
MIT
-
License
+
,
+
and points allocations
-
-
Potential
+
,
+
no web UI
-
+
-
-
+
+
-
Get started
-

Clone and explore

-
Start contributing today
-
"comment"># Clone the repo
git clone https://github.com/arc-web/exitstorm.git
cd exitstorm
"comment"># Read the README for next steps
cat README.md
+
Under the hood
+

How it works

+
Real code from the repository
+
+--------------+
| @exitstorm |
| /core | <- types, constants, utils
+------+-------+
|
+---------------+---------------+
| | |
+------+------+ +------+------+ +------+-------+
| @exitstorm | | @exitstorm | | @exitstorm |
| /analyzer | | /graphics | | /team-engine |
+------+------+ +------+------+ +------+-------+
|
-
+
-
-
+
+
-
Open source software powers innovation.
Join us on GitHub.
+
node packages/analyzer/dist/cli.js AdLens AI-powered ad optimization for SMBs
arc-web/exitstorm
@@ -219,7 +196,7 @@

Clone and explore

-
1 / 5
+
1 / 4
\u2190 \u2192 arrow keys to navigate
+ + + + + +
+
+
+ +
+
+ +
+
+
+
ARC Web
+

Exitstorm
Delivering impact

+
[![CI](https://github.com/arc-web/exitstorm/actions/workflows/ci.yml/badge.svg)](https://github.com/arc-web/exitstorm/actions)
+
TypeScriptOpen SourceProduction
+
+
+ +
+ +
+
+
+
By the numbers
+

Real impact

+
+
+
,
+
priority scores
+
+
+
,
+
team recommendations
+
+
+
,
+
and points allocations
+
+
+
,
+
no web UI
+
+ +
+
+ +
+ +
+
+
+
Under the hood
+

How it works

+
Real code from the repository
+
+--------------+
| @exitstorm |
| /core | <- types, constants, utils
+------+-------+
|
+---------------+---------------+
| | |
+------+------+ +------+------+ +------+-------+
| @exitstorm | | @exitstorm | | @exitstorm |
| /analyzer | | /graphics | | /team-engine |
+------+------+ +------+------+ +------+-------+
|
+
+
+ +
+ +
+
+
+
node packages/analyzer/dist/cli.js AdLens AI-powered ad optimization for SMBs
+
+
arc-web/exitstorm
+
+
+
+ + +
1 / 4
+
\u2190 \u2192 arrow keys to navigate
+ + + + \ No newline at end of file From 003748a3403db422fb55dca70de833e7ee4d92a1 Mon Sep 17 00:00:00 2001 From: Michael Ensor Date: Tue, 14 Apr 2026 16:39:17 +0800 Subject: [PATCH 05/15] docs: add presentation --- docs/presentation/index.html | 110 ++++++++++++++++++++++++----------- 1 file changed, 76 insertions(+), 34 deletions(-) diff --git a/docs/presentation/index.html b/docs/presentation/index.html index ad7bf6e..27675b4 100644 --- a/docs/presentation/index.html +++ b/docs/presentation/index.html @@ -3,7 +3,7 @@ -Exitstorm +ExitStorm @@ -133,8 +166,8 @@
-
-
+
+
ARC Web

Exitstorm
TypeScript

@@ -145,8 +178,8 @@

Exitstorm
TypeScript

-
-
+
+
The problem

What's broken without this

@@ -172,8 +205,8 @@

What's broken without this

-
-
+
+
The difference

Why it matters

@@ -193,8 +226,8 @@

Why it matters

-
-
+
+
Under the hood

How it works

@@ -229,8 +262,8 @@

How it works

-
-
+
+
What it does

Core capabilities

@@ -256,8 +289,8 @@

Core capabilities

-
-
+
+
We built this so AI agents can score and staff projects the same way every time, without asking humans to guess.
@@ -267,8 +300,8 @@

Core capabilities

-
-
+
+
Codebase

Built with care

@@ -299,8 +332,8 @@

Built with care

-
-
+
+
Built by

Mike Ensor
Arc Web

@@ -312,7 +345,13 @@

Mike Ensor
Arc Web

1 / 8
-
\u2190 \u2192 arrow keys to navigate
+
\u2190 \u2192 arrow keys  |  P to play  |  M to mute
+
+ \ No newline at end of file diff --git a/docs/presentation/index.html b/docs/presentation/index.html index c76a8e6..847e7ed 100644 --- a/docs/presentation/index.html +++ b/docs/presentation/index.html @@ -110,6 +110,29 @@ blockquote { font-size:clamp(20px,3vw,32px); font-weight:600; line-height:1.4; position:relative; max-width:800px; margin:0 auto; padding:0 0 0 48px; opacity:0; } blockquote::before { content:'\201C'; position:absolute; left:0; top:-10px; font-size:60px; color:var(--accent); font-family:Georgia,serif; line-height:1; } +/* Timeline */ +.timeline { display:flex; flex-direction:column; gap:0; width:100%; max-width:800px; margin:0 auto; text-align:left; } +.tl-node { display:flex; gap:20px; align-items:flex-start; opacity:0; } +.tl-marker { display:flex; flex-direction:column; align-items:center; flex-shrink:0; } +.tl-dot { width:36px; height:36px; border-radius:50%; background:var(--surface); border:2px solid rgba(123,47,190,0.4); display:flex; align-items:center; justify-content:center; font-size:13px; font-weight:700; color:var(--muted); flex-shrink:0; transition:all 0.3s; } +.tl-node.done .tl-dot { background:rgba(16,185,129,0.15); border-color:rgba(16,185,129,0.5); color:#10B981; } +.tl-track { width:2px; height:32px; background:linear-gradient(to bottom,rgba(123,47,190,0.3),transparent); margin-top:4px; } +.tl-node:last-child .tl-track { display:none; } +.tl-body { padding:4px 0 32px; } +.tl-date { font-size:11px; font-weight:700; letter-spacing:0.12em; text-transform:uppercase; color:var(--accent); margin-bottom:4px; } +.tl-title { font-size:16px; font-weight:700; margin-bottom:4px; } +.tl-desc { font-size:13px; color:var(--muted); line-height:1.55; } + +/* Team */ +.team-grid { display:grid; grid-template-columns:repeat(auto-fill,minmax(180px,1fr)); gap:20px; width:100%; margin:8px auto 0; justify-content:center; } +.team-card { background:var(--surface); border:1px solid rgba(123,47,190,0.25); border-radius:16px; padding:24px 20px; text-align:center; opacity:0; transition:border-color 0.3s; } +.team-card:hover { border-color:rgba(245,166,35,0.4); } +.team-avatar { width:64px; height:64px; border-radius:50%; object-fit:cover; margin:0 auto 12px; display:block; border:2px solid rgba(123,47,190,0.3); } +.team-avatar-placeholder { width:64px; height:64px; border-radius:50%; background:linear-gradient(135deg,var(--primary),var(--accent)); display:flex; align-items:center; justify-content:center; font-size:24px; font-weight:800; color:#fff; margin:0 auto 12px; } +.team-name { font-size:15px; font-weight:700; margin-bottom:4px; } +.team-role { font-size:12px; color:var(--accent); font-weight:600; letter-spacing:0.06em; text-transform:uppercase; margin-bottom:6px; } +.team-note { font-size:12px; color:var(--muted); line-height:1.5; } + /* Text + Image */ .body-text { font-size:16px; color:var(--muted); line-height:1.7; max-width:700px; margin:0 auto; opacity:0; } .img-wrap { margin-top:24px; opacity:0; } @@ -119,8 +142,18 @@ .dot { width:6px; height:6px; border-radius:50%; background:rgba(255,255,255,0.15); cursor:pointer; border:none; padding:0; transition:all 0.3s; } .dot.active { background:var(--accent); transform:scale(1.5); } #counter { position:fixed; bottom:28px; right:32px; font-size:12px; color:var(--muted); z-index:100; } -#hint { position:fixed; bottom:28px; left:50%; transform:translateX(-50%); font-size:11px; color:rgba(122,114,138,0.4); z-index:100; letter-spacing:0.05em; } +#hint { position:fixed; bottom:28px; left:50%; transform:translateX(-50%); font-size:11px; color:rgba(122,114,138,0.4); z-index:100; letter-spacing:0.05em; white-space:nowrap; } +#mute-dot { display:inline-block; width:5px; height:5px; border-radius:50%; background:rgba(122,114,138,0.4); margin-left:8px; vertical-align:middle; transition:background 0.2s; } +#mute-dot.active { background:var(--accent); } #overlay { position:fixed; inset:0; background:var(--bg); z-index:50; pointer-events:none; opacity:0; } + +/* Autoplay */ +#play-btn { position:fixed; bottom:20px; left:28px; z-index:100; background:rgba(123,47,190,0.15); border:1px solid rgba(123,47,190,0.4); border-radius:100px; padding:7px 16px 7px 12px; display:flex; align-items:center; gap:8px; cursor:pointer; font-size:12px; font-weight:600; color:var(--primary-light); letter-spacing:0.05em; transition:background 0.2s,border-color 0.2s; } +#play-btn:hover { background:rgba(123,47,190,0.28); border-color:rgba(123,47,190,0.7); } +#play-btn svg { width:14px; height:14px; flex-shrink:0; } +#play-btn.playing { background:rgba(245,166,35,0.12); border-color:rgba(245,166,35,0.4); color:var(--accent); } +#play-btn.playing:hover { background:rgba(245,166,35,0.22); border-color:rgba(245,166,35,0.7); } +#progress-bar { position:fixed; bottom:0; left:0; height:2px; width:0%; background:linear-gradient(90deg,var(--primary),var(--accent)); z-index:101; transition:none; } @@ -133,8 +166,8 @@
-
-
+
+
ARC Web

Exitstorm
TypeScript

@@ -145,8 +178,8 @@

Exitstorm
TypeScript

-
-
+
+
The problem

What's broken without this

@@ -172,8 +205,8 @@

What's broken without this

-
-
+
+
The difference

Why it matters

@@ -193,8 +226,8 @@

Why it matters

-
-
+
+
Under the hood

How it works

@@ -229,8 +262,8 @@

How it works

-
-
+
+
What it does

Core capabilities

@@ -256,8 +289,8 @@

Core capabilities

-
-
+
+
We built this so AI agents can score and staff projects the same way every time, without asking humans to guess.
@@ -267,8 +300,8 @@

Core capabilities

-
-
+
+
Codebase

Built with care

@@ -299,8 +332,8 @@

Built with care

-
-
+
+
Built by

Mike Ensor
Arc Web

@@ -312,7 +345,13 @@

Mike Ensor
Arc Web

1 / 8
-
\u2190 \u2192 arrow keys to navigate
+
\u2190 \u2192 arrow keys  |  P to play  |  M to mute
+
+ \ No newline at end of file From dbade1d2ca0fd1b3249ec1c0c277813523b14303 Mon Sep 17 00:00:00 2001 From: Michael Ensor Date: Fri, 17 Apr 2026 14:10:14 +0800 Subject: [PATCH 12/15] docs: update presentation (home + /presentation) --- docs/index.html | 32 ++++++++++++++++---------------- docs/presentation/index.html | 32 ++++++++++++++++---------------- 2 files changed, 32 insertions(+), 32 deletions(-) diff --git a/docs/index.html b/docs/index.html index 847e7ed..444e655 100644 --- a/docs/index.html +++ b/docs/index.html @@ -166,8 +166,8 @@
-
-
+
+
ARC Web

Exitstorm
TypeScript

@@ -178,8 +178,8 @@

Exitstorm
TypeScript

-
-
+
+
The problem

What's broken without this

@@ -205,8 +205,8 @@

What's broken without this

-
-
+
+
The difference

Why it matters

@@ -226,8 +226,8 @@

Why it matters

-
-
+
+
Under the hood

How it works

@@ -262,8 +262,8 @@

How it works

-
-
+
+
What it does

Core capabilities

@@ -289,8 +289,8 @@

Core capabilities

-
-
+
+
We built this so AI agents can score and staff projects the same way every time, without asking humans to guess.
@@ -300,8 +300,8 @@

Core capabilities

-
-
+
+
Codebase

Built with care

@@ -332,8 +332,8 @@

Built with care

-
-
+
+
Built by

Mike Ensor
Arc Web

diff --git a/docs/presentation/index.html b/docs/presentation/index.html index 847e7ed..444e655 100644 --- a/docs/presentation/index.html +++ b/docs/presentation/index.html @@ -166,8 +166,8 @@
-
-
+
+
ARC Web

Exitstorm
TypeScript

@@ -178,8 +178,8 @@

Exitstorm
TypeScript

-
-
+
+
The problem

What's broken without this

@@ -205,8 +205,8 @@

What's broken without this

-
-
+
+
The difference

Why it matters

@@ -226,8 +226,8 @@

Why it matters

-
-
+
+
Under the hood

How it works

@@ -262,8 +262,8 @@

How it works

-
-
+
+
What it does

Core capabilities

@@ -289,8 +289,8 @@

Core capabilities

-
-
+
+
We built this so AI agents can score and staff projects the same way every time, without asking humans to guess.
@@ -300,8 +300,8 @@

Core capabilities

-
-
+
+
Codebase

Built with care

@@ -332,8 +332,8 @@

Built with care

-
-
+
+
Built by

Mike Ensor
Arc Web

From b4504b5da49d0139a9aef64d1ead895598b12eaa Mon Sep 17 00:00:00 2001 From: Michael Ensor Date: Fri, 17 Apr 2026 14:12:54 +0800 Subject: [PATCH 13/15] docs: update presentation (home + /presentation) --- docs/index.html | 32 ++++++++++++++++---------------- docs/presentation/index.html | 32 ++++++++++++++++---------------- 2 files changed, 32 insertions(+), 32 deletions(-) diff --git a/docs/index.html b/docs/index.html index 444e655..9d3669c 100644 --- a/docs/index.html +++ b/docs/index.html @@ -166,8 +166,8 @@
-
-
+
+
ARC Web

Exitstorm
TypeScript

@@ -178,8 +178,8 @@

Exitstorm
TypeScript

-
-
+
+
The problem

What's broken without this

@@ -205,8 +205,8 @@

What's broken without this

-
-
+
+
The difference

Why it matters

@@ -226,8 +226,8 @@

Why it matters

-
-
+
+
Under the hood

How it works

@@ -262,8 +262,8 @@

How it works

-
-
+
+
What it does

Core capabilities

@@ -289,8 +289,8 @@

Core capabilities

-
-
+
+
We built this so AI agents can score and staff projects the same way every time, without asking humans to guess.
@@ -300,8 +300,8 @@

Core capabilities

-
-
+
+
Codebase

Built with care

@@ -332,8 +332,8 @@

Built with care

-
-
+
+
Built by

Mike Ensor
Arc Web

diff --git a/docs/presentation/index.html b/docs/presentation/index.html index 444e655..9d3669c 100644 --- a/docs/presentation/index.html +++ b/docs/presentation/index.html @@ -166,8 +166,8 @@
-
-
+
+
ARC Web

Exitstorm
TypeScript

@@ -178,8 +178,8 @@

Exitstorm
TypeScript

-
-
+
+
The problem

What's broken without this

@@ -205,8 +205,8 @@

What's broken without this

-
-
+
+
The difference

Why it matters

@@ -226,8 +226,8 @@

Why it matters

-
-
+
+
Under the hood

How it works

@@ -262,8 +262,8 @@

How it works

-
-
+
+
What it does

Core capabilities

@@ -289,8 +289,8 @@

Core capabilities

-
-
+
+
We built this so AI agents can score and staff projects the same way every time, without asking humans to guess.
@@ -300,8 +300,8 @@

Core capabilities

-
-
+
+
Codebase

Built with care

@@ -332,8 +332,8 @@

Built with care

-
-
+
+
Built by

Mike Ensor
Arc Web

From 09de61b3b9815bf83646e917e5e7d479719efa55 Mon Sep 17 00:00:00 2001 From: Michael Ensor Date: Fri, 17 Apr 2026 14:28:09 +0800 Subject: [PATCH 14/15] docs: update presentation (home + /presentation) --- docs/index.html | 32 ++++++++++++++++---------------- docs/presentation/index.html | 32 ++++++++++++++++---------------- 2 files changed, 32 insertions(+), 32 deletions(-) diff --git a/docs/index.html b/docs/index.html index 9d3669c..a6d469e 100644 --- a/docs/index.html +++ b/docs/index.html @@ -166,8 +166,8 @@
-
-
+
+
ARC Web

Exitstorm
TypeScript

@@ -178,8 +178,8 @@

Exitstorm
TypeScript

-
-
+
+
The problem

What's broken without this

@@ -205,8 +205,8 @@

What's broken without this

-
-
+
+
The difference

Why it matters

@@ -226,8 +226,8 @@

Why it matters

-
-
+
+
Under the hood

How it works

@@ -262,8 +262,8 @@

How it works

-
-
+
+
What it does

Core capabilities

@@ -289,8 +289,8 @@

Core capabilities

-
-
+
+
We built this so AI agents can score and staff projects the same way every time, without asking humans to guess.
@@ -300,8 +300,8 @@

Core capabilities

-
-
+
+
Codebase

Built with care

@@ -332,8 +332,8 @@

Built with care

-
-
+
+
Built by

Mike Ensor
Arc Web

diff --git a/docs/presentation/index.html b/docs/presentation/index.html index 9d3669c..a6d469e 100644 --- a/docs/presentation/index.html +++ b/docs/presentation/index.html @@ -166,8 +166,8 @@
-
-
+
+
ARC Web

Exitstorm
TypeScript

@@ -178,8 +178,8 @@

Exitstorm
TypeScript

-
-
+
+
The problem

What's broken without this

@@ -205,8 +205,8 @@

What's broken without this

-
-
+
+
The difference

Why it matters

@@ -226,8 +226,8 @@

Why it matters

-
-
+
+
Under the hood

How it works

@@ -262,8 +262,8 @@

How it works

-
-
+
+
What it does

Core capabilities

@@ -289,8 +289,8 @@

Core capabilities

-
-
+
+
We built this so AI agents can score and staff projects the same way every time, without asking humans to guess.
@@ -300,8 +300,8 @@

Core capabilities

-
-
+
+
Codebase

Built with care

@@ -332,8 +332,8 @@

Built with care

-
-
+
+
Built by

Mike Ensor
Arc Web

From 597f69c3db478e5e90f32fd9a786e3e848d9cf9d Mon Sep 17 00:00:00 2001 From: Michael Ensor Date: Sun, 19 Apr 2026 10:36:28 +0800 Subject: [PATCH 15/15] feat: sync local updates - analyzer fixes, OpenAI guard improvements Co-Authored-By: Claude Sonnet 4.6 --- .../content/homepage-direction.html | 51 ++ .../content/homepage-layout.html | 37 ++ .../content/homepage-mockup.html | 445 ++++++++++++++++++ .../brainstorm/50469-1774880047/state/events | 1 + .../50469-1774880047/state/server-stopped | 1 + .../50469-1774880047/state/server.pid | 1 + README.md | 10 - 7 files changed, 536 insertions(+), 10 deletions(-) create mode 100644 .superpowers/brainstorm/50469-1774880047/content/homepage-direction.html create mode 100644 .superpowers/brainstorm/50469-1774880047/content/homepage-layout.html create mode 100644 .superpowers/brainstorm/50469-1774880047/content/homepage-mockup.html create mode 100644 .superpowers/brainstorm/50469-1774880047/state/events create mode 100644 .superpowers/brainstorm/50469-1774880047/state/server-stopped create mode 100644 .superpowers/brainstorm/50469-1774880047/state/server.pid diff --git a/.superpowers/brainstorm/50469-1774880047/content/homepage-direction.html b/.superpowers/brainstorm/50469-1774880047/content/homepage-direction.html new file mode 100644 index 0000000..fb16413 --- /dev/null +++ b/.superpowers/brainstorm/50469-1774880047/content/homepage-direction.html @@ -0,0 +1,51 @@ +

ExitStorm Homepage - Direction

+

What vibe should the homepage set?

+ +
+
+
+
+
analyzeProject("AdLens", "AI ad optimization")
+
+
+
8.1
+
PRIORITY
+
+
+
$96K
+
ARR
+
+
+
7,500
+
POINTS
+
+
+
+
+

A: Dark Tech / Developer-Focused

+

Dark background, terminal-style code snippets, glowing accent colors. Speaks to builders and AI agents. Shows the pipeline as a live demo. "Drop an idea, get a financial model."

+
+
+ +
+
+
+
Turn Ideas Into Exits
+
Financial models. Priority scores. Team matching. Automated.
+
+
+
8 Criteria
+
SCORING
+
+
+
5 Tiers
+
VALUATION
+
+
+
+
+

B: Clean / Business-Focused

+

Light background, clean typography, professional feel. Speaks to founders and operators. Shows the value prop clearly. "The operating system for micro-SaaS exits."

+
+
+
diff --git a/.superpowers/brainstorm/50469-1774880047/content/homepage-layout.html b/.superpowers/brainstorm/50469-1774880047/content/homepage-layout.html new file mode 100644 index 0000000..baf42ad --- /dev/null +++ b/.superpowers/brainstorm/50469-1774880047/content/homepage-layout.html @@ -0,0 +1,37 @@ +

Homepage Layout - Sections

+

How should the page flow? Click to select.

+ +
+
+
A
+
+

Split Audience - Tabs

+

Hero section shared, then two tabs: "I'm Building" and "I'm Investing". Each tab shows tailored messaging. Keeps the page short, lets each audience self-select.

+
+ Hero -> [Builders Tab | Investors Tab] -> How It Works -> CTA +
+
+
+ +
+
B
+
+

Single Scroll - Two Zones

+

Bold hero that hooks everyone, then a "For Builders" section with the pipeline and scoring, then a "For Investors" section with due diligence and portfolio analysis. Natural scroll, no tabs.

+
+ Hero -> For Builders (pipeline, scoring, teams) -> For Investors (analysis, portfolio, due diligence) -> CTA +
+
+
+ +
+
C
+
+

Unified Story - Woven Together

+

One narrative that serves both: "Here's how ideas become exits." Each section naturally speaks to both audiences - builders see the tools, investors see the rigor. Audience-specific CTAs at the bottom.

+
+ Hero -> The Pipeline -> Scoring -> Financials -> Teams -> Track Record -> Builder CTA | Investor CTA +
+
+
+
diff --git a/.superpowers/brainstorm/50469-1774880047/content/homepage-mockup.html b/.superpowers/brainstorm/50469-1774880047/content/homepage-mockup.html new file mode 100644 index 0000000..d127a8a --- /dev/null +++ b/.superpowers/brainstorm/50469-1774880047/content/homepage-mockup.html @@ -0,0 +1,445 @@ + + + + + +ExitStorm - Homepage Mockup + + + + + +
+

Stop Building Things
That Won't Sell

+

ExitStorm turns raw ideas into financial models, priority scores, and exit plans. Know if it's worth building before you write a line of code.

+
+
+
8.1
+
Priority Score
+
+
+
$96K
+
Projected ARR
+
+
+
$1.15M
+
Exit Valuation
+
+
+
+ + +
+
+ +

From Idea to Exit in 6 Steps

+

Every idea goes through the same rigorous process. No gut feelings. No guessing.

+
+
+
💡
+

Idea Input

+

Title + description. That's all it takes.

+
+
+
📈
+

Financial Model

+

ARR projections, valuation, breakeven timeline.

+
+
+
🎯
+

Priority Score

+

8 weighted criteria. 0-10 score. Build or skip.

+
+
+
👥
+

Team Assembly

+

Auto-matched from contributor history.

+
+
+
📊
+

Milestone Tracking

+

Points unlock as you hit real targets.

+
+
+
💰
+

Exit

+

List on Flippa/Acquire.com. Distribute proceeds.

+
+
+
+
+ + +
+ +

8 Criteria That Predict Exit-ability

+

Not generic startup metrics. These are tuned for what Flippa and Acquire.com buyers actually look for.

+
+
+
15%
+

ARR Quality

How recurring and predictable is the revenue?

+
+
+
15%
+

Rule of 40 Potential

Growth + margin headroom within 12 months.

+
+
+
15%
+

Build Speed

Under 2 weeks = 10. Over a year = 1. Ship fast, flip fast.

+
+
+
15%
+

Defensibility

Proprietary data, network effects, or thin wrapper?

+
+
+
10%
+

Churn Achievability

Embedded workflow tool or novelty single-use?

+
+
+
10%
+

Founder Independence

Fully automated = 10. Founder-dependent = 2. Buyers want hands-off.

+
+
+
10%
+

Pricing Power

Solves a $10K+/yr pain point, or commodity?

+
+
+
10%
+

Market Timing

Riding a trend, or ahead of the market?

+
+
+
+

Verdicts: Score under 5 = don't build. 5-7 = queue it. 7-8 = solid. 8+ = build first. The math is deterministic - AI provides the ratings, the weights are locked in code.

+
+
+ + +
+ +

Know Your Exit Number Before You Code

+

Every idea gets a complete financial model using acquisition multiples that match what buyers actually pay.

+
+
+

12-Month ARR

+
$96K
+
Realistic scenario
+
Conservative: $36K / Optimistic: $180K
+
+
+

Valuation Range

+
$288K - $1.15M
+
8-12x ARR (B2B AI SaaS)
+
+
+

Breakeven

+
8 mo
+
Exit window: 18-24 months
+
+
+ + + + + + + + + + + +
TypeMultipleWhy
B2B AI SaaS8-12x ARRHighest demand from acquirers right now
B2C SaaS3-5x ARRHigher churn, lower switching costs
Micro-SaaS2.5-4.5x SDESolo-buildable, under 3 months. SDE = ARR x 0.6
API Tools5-8x ARRUsage-based, sticky integration
Marketplace3-6x ARRNetwork effects offset by liquidity risk
+
+ + +
+
+ +

Earn What You Contribute. No Equity Fights.

+

Points replace equity negotiations. Earned by verified work, vested against real milestones, backed by a complete audit trail.

+ +
+
Lead Builder35%
+
Co-Builder20%
+
Designer / UX15%
+
QA / Testing10%
+
Growth / Marketing10%
+
Community5%
+
Docs / PM5%
+
+ +
+

Points unlock as the project hits real milestones:

+
+
5%
Kickoff
+
20%
MVP
+
35%
1st Customer
+
50%
$1K MRR
+
65%
$5K MRR
+
80%
Breakeven
+
95%
ARR Target
+
100%
Exit
+
+
+
+
+ + +
+ +

Due Diligence, Automated

+

Every project in the pipeline comes with structured data you can actually evaluate. No decks. No pitch theater. Just numbers.

+
+
+
📊
+

Standardized Financial Models

+

Every project gets the same analysis: 3-scenario ARR, valuation ranges using real acquisition multiples, breakeven timeline. Compare apples to apples across the entire pipeline.

+
+
+
🎯
+

8-Criteria Scoring

+

Weighted for exit-ability, not vanity. Founder Independence, Build Speed, and Defensibility are scored explicitly. The math is deterministic and auditable.

+
+
+
👥
+

Team Composition Data

+

See who's building what, matched by verified contribution history. No self-reported skills. Every team member earned their role through tracked, evidenced work.

+
+
+
🔒
+

Complete Audit Trail

+

Every contribution has a source, evidence, and timestamp. Daily point caps, vouch limits, and anti-gaming constraints mean the data is trustworthy enough to allocate real money against.

+
+
+
+ + + + + + + + diff --git a/.superpowers/brainstorm/50469-1774880047/state/events b/.superpowers/brainstorm/50469-1774880047/state/events new file mode 100644 index 0000000..50fe92d --- /dev/null +++ b/.superpowers/brainstorm/50469-1774880047/state/events @@ -0,0 +1 @@ +{"type":"click","text":"⚡\n Turn Ideas Into Exits\n Financial models. Priority scores. Team matching. Automated.\n \n \n 8 Criteria\n SCORING\n \n \n 5 Tiers\n VALUATION\n \n \n \n \n B: Clean / Business-Focused\n Light background, clean typography, professional feel. Speaks to founders and operators. Shows the value prop clearly. \"The operating system for micro-SaaS exits.\"","choice":"b","id":null,"timestamp":1774884555107} diff --git a/.superpowers/brainstorm/50469-1774880047/state/server-stopped b/.superpowers/brainstorm/50469-1774880047/state/server-stopped new file mode 100644 index 0000000..4e39d79 --- /dev/null +++ b/.superpowers/brainstorm/50469-1774880047/state/server-stopped @@ -0,0 +1 @@ +{"reason":"idle timeout","timestamp":1774881907261} diff --git a/.superpowers/brainstorm/50469-1774880047/state/server.pid b/.superpowers/brainstorm/50469-1774880047/state/server.pid new file mode 100644 index 0000000..72c21f8 --- /dev/null +++ b/.superpowers/brainstorm/50469-1774880047/state/server.pid @@ -0,0 +1 @@ +50479 diff --git a/README.md b/README.md index 36bc1ec..3610be6 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,5 @@
- - View Interactive Presentation - - -
- ---- - -
- # ExitStorm ### Idea Analysis and Exit Pipeline Engine