launchframe 0.1.13 → 0.2.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.
package/README.md
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Landingfram
|
|
2
2
|
|
|
3
|
-
A reusable workflow for reverse-engineering live marketing sites into a **shadcn-style token theme**, **reference dumps** (DOM, copy index, media index), and a **layout-mirror** React scaffold — optimized for AI coding agents.
|
|
3
|
+
A reusable workflow for reverse-engineering live marketing sites into a **shadcn-style token theme**, **reference dumps** (DOM, copy index, media index), and a **layout-mirror** React scaffold — optimized for AI coding agents (same orchestration model as [ai-website-cloner-template](https://github.com/JCodesMore/ai-website-cloner-template)).
|
|
4
4
|
|
|
5
|
-
**Recommended:** [Claude Code](https://docs.anthropic.com/en/docs/claude-code) or **Cursor** for multi-phase builds — but
|
|
5
|
+
**Recommended:** [Claude Code](https://docs.anthropic.com/en/docs/claude-code) or **Cursor** for multi-phase builds — but Landingfram output works with any agent that can read Markdown and TypeScript.
|
|
6
6
|
|
|
7
|
-
Point the CLI at a URL, run **`npx launchframe@latest`**, then drive the same **spec → parallel builders → merge → QA** rhythm
|
|
7
|
+
Point the CLI at a URL, run **`npx launchframe@latest <url> "<SaaS idea>"`**, then drive the same **spec → parallel builders → merge → QA** rhythm. In Cursor, use the **Clone Website** command (`.cursor/commands/clone-website.md`); in Claude Code / Codex, use the **`clone-website`** skill. Those workflows merge [ai-website-cloner-template](https://github.com/JCodesMore/ai-website-cloner-template) discipline with **automated** Playwright recon. The same npm package also exposes a **`landingfram`** bin shim for older scripts.
|
|
8
8
|
|
|
9
9
|
## Quick start (any folder)
|
|
10
10
|
|
|
@@ -29,50 +29,57 @@ Pass multiple URLs for a combined token synthesis (see CLI reference below). You
|
|
|
29
29
|
|
|
30
30
|
| Agent | Status |
|
|
31
31
|
| ----- | ------ |
|
|
32
|
-
| [Claude Code](https://docs.anthropic.com/en/docs/claude-code) | Recommended |
|
|
33
|
-
| [
|
|
32
|
+
| [Claude Code](https://docs.anthropic.com/en/docs/claude-code) | Recommended — align with upstream template |
|
|
33
|
+
| [Codex CLI](https://github.com/openai/codex) | Supported — `.codex/skills/clone-website/` |
|
|
34
|
+
| [OpenCode](https://opencode.ai/) | Supported |
|
|
34
35
|
| [GitHub Copilot](https://github.com/features/copilot) | Supported — `AGENTS.md` → `npm run sync:agents` |
|
|
36
|
+
| [Cursor](https://cursor.com/) | Supported — `.cursor/commands/clone-website.md` |
|
|
37
|
+
| [Windsurf](https://codeium.com/windsurf) | Supported |
|
|
35
38
|
| [Gemini CLI](https://github.com/google-gemini/gemini-cli) | Supported (`GEMINI.md`) |
|
|
36
39
|
| [Cline](https://github.com/cline/cline) | Supported |
|
|
40
|
+
| [Roo Code](https://github.com/RooCodeInc/Roo-Code) | Supported |
|
|
37
41
|
| [Continue](https://continue.dev/) | Supported |
|
|
38
42
|
| [Amazon Q](https://aws.amazon.com/q/developer/) | Supported |
|
|
43
|
+
| [Augment Code](https://www.augmentcode.com/) | Supported |
|
|
44
|
+
| [Aider](https://aider.chat/) | Supported |
|
|
39
45
|
| … | Any agent that reads `AGENTS.md` |
|
|
40
46
|
|
|
41
47
|
## Prerequisites
|
|
42
48
|
|
|
43
49
|
- [Node.js](https://nodejs.org/) **20+**
|
|
44
50
|
- Chromium via Playwright (`npx playwright install chromium`)
|
|
51
|
+
- **From a git clone of this monorepo:** initialize the upstream template submodule with `git submodule update --init --recursive` (or clone with `git clone --recurse-submodules …`) so `vendor/ai-website-cloner-template` is available for reference.
|
|
45
52
|
|
|
46
53
|
## Tech stack
|
|
47
54
|
|
|
48
55
|
- **Extract:** Node.js, Playwright, TypeScript
|
|
49
|
-
- **Published CLI:** `npx launchframe` → `packages/extract/`
|
|
56
|
+
- **Published CLI:** `npx launchframe` → `packages/extract/` (`landingfram` is a bin alias on install)
|
|
50
57
|
- **Studio (optional):** Next.js App Router in `apps/studio/` (**Next.js 16**, **React 19**, Tailwind CSS, **Lucide** via `@framework/blocks` / direct imports — aligned with [ai-website-cloner-template](https://github.com/JCodesMore/ai-website-cloner-template); studio Tailwind is v3 today while their README cites **v4**; emitted run artifacts remain drop-in CSS/token bundles.)
|
|
51
58
|
- **Mirror output:** React, Framer Motion, Phosphor (generated `page.tsx`)
|
|
52
59
|
- **Tokens:** `tailwind.config.ts`, `globals.css`, `tokens.json`, `REPORT.md`
|
|
53
60
|
|
|
54
61
|
## Parity with [ai-website-cloner-template](https://github.com/JCodesMore/ai-website-cloner-template)
|
|
55
62
|
|
|
56
|
-
|
|
63
|
+
Landingfram mirrors that template’s **phases and artifact roles**, not its single-repo layout:
|
|
57
64
|
|
|
58
|
-
| Aspect | What they do | What
|
|
65
|
+
| Aspect | What they do | What Landingfram does (same intent) |
|
|
59
66
|
| -------- | ------------------ | ------------------------------------- |
|
|
60
|
-
| **Phase 1 recon** | `/clone-website` drives screenshots, tokens, interaction sweep | **`npx launchframe`** performs automated recon (Playwright) into a run folder; optional Browser MCP passes match their sweep discipline (**Clone Website** in Cursor ≈ orchestration checklist) |
|
|
67
|
+
| **Phase 1 recon** | `/clone-website` drives screenshots, tokens, interaction sweep | **`npx launchframe`** performs automated recon (Playwright) into a run folder; optional Browser MCP passes match their sweep discipline (**Clone Website** in Cursor / **`clone-website`** skill elsewhere ≈ orchestration checklist) |
|
|
61
68
|
| **Repo shape** | One Next.js app (`src/app`, `components`, …) | **Monorepo:** CLI (`packages/extract`) + optional **`apps/studio`** + **`packages/blocks`**; published CLI ships separately |
|
|
62
69
|
| **Where artifacts live** | `docs/research/`, `docs/design-references/`, `public/` | Same tree **inside** `./output/<runId>/` (gitignored by default). To match their repo layout, run with **`--out path/to/your-next-app/extraction-<slug>`** or merge **`docs/`** + **`downloaded_assets/`** into your app’s **`docs/`** and **`public/images`** (and **`public/videos`**, **`public/seo`**) when integrating |
|
|
63
70
|
| **Stack** | Next 16, React 19, Tailwind v4, Lucide | **Next 16 + React 19 + Lucide** in studio/blocks; Tailwind **v3** in-studio until upgraded to v4 |
|
|
64
71
|
|
|
65
72
|
## How it works
|
|
66
73
|
|
|
67
|
-
|
|
74
|
+
Same multi-phase pipeline as [ai-website-cloner-template](https://github.com/JCodesMore/ai-website-cloner-template) (`vendor/ai-website-cloner-template` in this repo):
|
|
68
75
|
|
|
69
|
-
1. **
|
|
70
|
-
2. **Foundation** —
|
|
71
|
-
3. **Component specs** —
|
|
72
|
-
4. **Parallel build** — agents in worktrees
|
|
73
|
-
5. **Assembly & QA** —
|
|
76
|
+
1. **Reconnaissance** — screenshots, design token extraction, interaction sweep (scroll, click, hover, responsive). **Launchfram:** run **`npx launchframe@latest <url> "<SaaS idea>"`** first for an automated baseline into **`./output/<runId>/`**; agents still use browser MCP for the mandatory sweep where needed (see **`.cursor/commands/clone-website.md`**).
|
|
77
|
+
2. **Foundation** — updates fonts, colors, globals, downloads all assets (merge emitted `globals.css` / `tailwind.config.ts` / `tokens.json` from the run when present).
|
|
78
|
+
3. **Component specs** — detailed spec files (`docs/research/components/`) with exact computed CSS values, states, behaviors, and content.
|
|
79
|
+
4. **Parallel build** — dispatches builder agents in git worktrees, one per section/component.
|
|
80
|
+
5. **Assembly & QA** — merges worktrees, wires up the page, runs visual diff against the original.
|
|
74
81
|
|
|
75
|
-
Each builder
|
|
82
|
+
Each builder agent receives the full component specification **inline** — exact `getComputedStyle()` values, interaction models, multi-state content, responsive breakpoints, and asset paths. Authority order: **`FOR_AI.md`** and **`AGENTS.md`**.
|
|
76
83
|
|
|
77
84
|
## Use cases
|
|
78
85
|
|
|
@@ -84,7 +91,7 @@ Each builder should receive **inline** spec content, not “go read the repo.”
|
|
|
84
91
|
|
|
85
92
|
- **Impersonation or phishing**
|
|
86
93
|
- **Passing off** another brand’s identity, trademarks, or licensed media
|
|
87
|
-
- **Violating robots.txt or site terms** —
|
|
94
|
+
- **Violating robots.txt or site terms** — Landingfram checks robots by default (`--no-robots` is discouraged)
|
|
88
95
|
|
|
89
96
|
## Output layout
|
|
90
97
|
|
|
@@ -158,12 +165,13 @@ npm run sync:agents # Regenerate Copilot / Cline / Continue / Amazon Q stub
|
|
|
158
165
|
- **Cursor:** `.cursor/rules/project.mdc` points at `AGENTS.md`; use **Clone Website** for the full cloner-template-style checklist.
|
|
159
166
|
- Edit **`AGENTS.md`**, then run **`npm run sync:agents`**.
|
|
160
167
|
|
|
161
|
-
### Updating agent copies
|
|
168
|
+
### Updating agent copies (parity with upstream template)
|
|
162
169
|
|
|
163
|
-
| What | Source of truth | Sync
|
|
164
|
-
| ---- |
|
|
170
|
+
| What | Source of truth (this repo) | Sync / notes |
|
|
171
|
+
| ---- | --------------------------- | ------------ |
|
|
165
172
|
| Project instructions | `AGENTS.md` | `npm run sync:agents` |
|
|
166
|
-
|
|
|
173
|
+
| `/clone-website` skill text | `vendor/ai-website-cloner-template/.claude/skills/clone-website/SKILL.md` | Copy into `.claude/`, `.codex/`, `.github/skills/`; re-apply **Pre-Flight step 0** (Launchfram). Cursor command: `vendor/.../.cursor/commands/clone-website.md` → `.cursor/commands/` (same step 0). |
|
|
174
|
+
| Inspection checklist | `vendor/.../docs/research/INSPECTION_GUIDE.md` | Merged in `docs/research/INSPECTION_GUIDE.md` with a **Landingfram** mapping section. |
|
|
167
175
|
|
|
168
176
|
## What this is not
|
|
169
177
|
|
package/bin/launchframe.mjs
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/**
|
|
3
|
-
* CLI entry for `npx launchframe`
|
|
4
|
-
* Spawns the TypeScript extract pipeline with the same Node
|
|
5
|
-
* this package. Output defaults to `./output/<runId>/` in the
|
|
6
|
-
* working directory (where the user ran the command), not inside the
|
|
3
|
+
* CLI entry for `npx launchframe@latest` (npm package name) and the `landingfram`
|
|
4
|
+
* bin shim on install. Spawns the TypeScript extract pipeline with the same Node
|
|
5
|
+
* that installed this package. Output defaults to `./output/<runId>/` in the
|
|
6
|
+
* *current* working directory (where the user ran the command), not inside the
|
|
7
7
|
* package install path.
|
|
8
8
|
*/
|
|
9
9
|
|
|
@@ -25,7 +25,7 @@ try {
|
|
|
25
25
|
tsxCli = join(dirname(tsxPkg), "dist", "cli.mjs");
|
|
26
26
|
} catch {
|
|
27
27
|
console.error(
|
|
28
|
-
"launchframe: could not resolve the `tsx` runtime. Re-install: npm install -g launchframe",
|
|
28
|
+
"launchframe: could not resolve the `tsx` runtime. Re-install with: npm install -g launchframe",
|
|
29
29
|
);
|
|
30
30
|
process.exit(1);
|
|
31
31
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "launchframe",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "Launchframe CLI: point it at SaaS sites you admire and get a drop-in shadcn/ui design system (tokens, Tailwind theme, CSS variables, AI handoff) plus ai-website-cloner-style recon (reference DOM, mirror, design references, research stubs). Primary install: npx launchframe@latest.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Evan Gruhlkey",
|
|
7
7
|
"homepage": "https://github.com/evangruhlkey/launchframe#readme",
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
},
|
|
15
15
|
"keywords": [
|
|
16
16
|
"launchframe",
|
|
17
|
+
"landingfram",
|
|
17
18
|
"shadcn",
|
|
18
19
|
"shadcn-ui",
|
|
19
20
|
"tailwind",
|
|
@@ -26,6 +27,7 @@
|
|
|
26
27
|
"cli"
|
|
27
28
|
],
|
|
28
29
|
"bin": {
|
|
30
|
+
"landingfram": "bin/launchframe.mjs",
|
|
29
31
|
"launchframe": "bin/launchframe.mjs"
|
|
30
32
|
},
|
|
31
33
|
"files": [
|
|
@@ -209,7 +209,7 @@ async function captureInteractionHints(page: Page): Promise<unknown> {
|
|
|
209
209
|
function emitDesignReferencesReadme(host: string, slug: string): string {
|
|
210
210
|
return `# Design references — ${host}
|
|
211
211
|
|
|
212
|
-
Automated captures (
|
|
212
|
+
Automated captures (Landingfram \`automated-clone-pass\`), analogous to **ai-website-cloner-template** \`docs/design-references/\`.
|
|
213
213
|
|
|
214
214
|
| Artifact | Purpose |
|
|
215
215
|
| -------- | ------- |
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Emits research artifacts under each extract run, aligned in layout and intent
|
|
3
3
|
* with the AI Website Cloner template (topology, behaviors bible, per-section
|
|
4
|
-
* specs). Values are derived from
|
|
4
|
+
* specs). Values are derived from Landingfram's automated crawl where available;
|
|
5
5
|
* interactive sweeps still require manual Browser MCP work for full fidelity.
|
|
6
6
|
*/
|
|
7
7
|
|
|
@@ -123,7 +123,7 @@ function emitTopology(url: string, host: string, layout: SiteLayout | undefined)
|
|
|
123
123
|
``,
|
|
124
124
|
`- **URL:** ${url}`,
|
|
125
125
|
`- **Host:** ${host}`,
|
|
126
|
-
`- **Generated by:**
|
|
126
|
+
`- **Generated by:** Landingfram automated crawl (primary viewport + optional responsive passes under \`docs/design-references/\`)`,
|
|
127
127
|
``,
|
|
128
128
|
`## Section order (top → bottom)`,
|
|
129
129
|
``,
|
|
@@ -174,7 +174,7 @@ function emitBehaviors(
|
|
|
174
174
|
- **URL:** ${url}
|
|
175
175
|
- **Capture viewport:** ${vpLine}
|
|
176
176
|
|
|
177
|
-
## What
|
|
177
|
+
## What Landingfram captured automatically
|
|
178
178
|
|
|
179
179
|
- Single desktop pass in headless Chromium with **reduced motion** forced for deterministic screenshots.
|
|
180
180
|
- **Automated multi-viewport + scroll sweep** PNGs under \`docs/design-references/${hostSlug(host)}/\` (desktop/tablet/mobile + scroll frames).
|
|
@@ -203,7 +203,7 @@ Document findings below as you discover them.
|
|
|
203
203
|
|
|
204
204
|
## Operator SaaS idea
|
|
205
205
|
|
|
206
|
-
${run.saasIdea?.trim() || "_Pass `--idea` or a second positional string when invoking
|
|
206
|
+
${run.saasIdea?.trim() || "_Pass `--idea` or a second positional string when invoking landingfram._"}
|
|
207
207
|
|
|
208
208
|
When rebuilding UI, preserve **interaction models** from this table (once filled); rewrite **copy** to match the SaaS idea without impersonating the reference brand.
|
|
209
209
|
`;
|
package/packages/extract/emit.ts
CHANGED
|
@@ -44,7 +44,7 @@ function write(dir: string, file: string, contents: string): string {
|
|
|
44
44
|
|
|
45
45
|
function emitTailwindConfig(system: DesignSystem): string {
|
|
46
46
|
return `/**
|
|
47
|
-
* Tailwind theme extracted by
|
|
47
|
+
* Tailwind theme extracted by landingfram.
|
|
48
48
|
* Run id: ${system.runId}
|
|
49
49
|
*
|
|
50
50
|
* Sources (inspirational only, no source code or assets reused):
|
|
@@ -126,7 +126,7 @@ function heightFor(step: string, system: DesignSystem): string {
|
|
|
126
126
|
|
|
127
127
|
function emitGlobalsCss(system: DesignSystem): string {
|
|
128
128
|
return `/**
|
|
129
|
-
* Drop-in CSS variables produced by
|
|
129
|
+
* Drop-in CSS variables produced by landingfram.
|
|
130
130
|
* Compatible with shadcn/ui's --background / --foreground / etc. tokens.
|
|
131
131
|
*/
|
|
132
132
|
|
|
@@ -46,11 +46,11 @@ import type { ExtractionRun, RawTokens, SiteCapture, SiteLayout } from "./types.
|
|
|
46
46
|
|
|
47
47
|
const __filename = fileURLToPath(import.meta.url);
|
|
48
48
|
const __dirname = dirname(__filename);
|
|
49
|
-
/** Writes under the user's cwd so `npx launchframe` from any folder works. */
|
|
49
|
+
/** Writes under the user's cwd so `npx launchframe` / `npx landingfram` from any folder works. */
|
|
50
50
|
const DEFAULT_OUTPUT_ROOT = join(process.cwd(), "output");
|
|
51
51
|
|
|
52
52
|
const USER_AGENT =
|
|
53
|
-
"
|
|
53
|
+
"landingfram/0.1 (+https://github.com/evangruhlkey/launchframe; design-token research; respects robots.txt)";
|
|
54
54
|
|
|
55
55
|
interface CliArgs {
|
|
56
56
|
urls: string[];
|
|
@@ -59,7 +59,7 @@ interface CliArgs {
|
|
|
59
59
|
respectRobots: boolean;
|
|
60
60
|
rateLimitPerMinute: number;
|
|
61
61
|
runName?: string;
|
|
62
|
-
/** SaaS product narrative from `--idea`, a positional string, or LAUNCHFRAME_SAAS_IDEA. */
|
|
62
|
+
/** SaaS product narrative from `--idea`, a positional string, or LANDINGFRAM_SAAS_IDEA / LAUNCHFRAME_SAAS_IDEA. */
|
|
63
63
|
saasIdea?: string;
|
|
64
64
|
/** When true, skip HTTP downloads from reference/media.json */
|
|
65
65
|
skipAssetDownload: boolean;
|
|
@@ -145,7 +145,8 @@ function parseArgs(argv: string[]): CliArgs {
|
|
|
145
145
|
args.saasIdea = positional[0];
|
|
146
146
|
}
|
|
147
147
|
|
|
148
|
-
const envIdea =
|
|
148
|
+
const envIdea =
|
|
149
|
+
process.env.LANDINGFRAM_SAAS_IDEA?.trim() || process.env.LAUNCHFRAME_SAAS_IDEA?.trim();
|
|
149
150
|
if (envIdea && !args.saasIdea) {
|
|
150
151
|
args.saasIdea = envIdea;
|
|
151
152
|
}
|