launchframe 0.4.0 → 0.4.2
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/.amazonq/cli-agents/clone-website.json +9 -0
- package/.amazonq/cli-agents/launchframe.json +9 -0
- package/.amazonq/rules/project.md +158 -0
- package/.augment/commands/clone-website.md +488 -0
- package/.augment/commands/launchframe.md +43 -0
- package/.claude/skills/clone-website/SKILL.md +14 -0
- package/.claude/skills/launchframe/SKILL.md +42 -0
- package/.clinerules +78 -67
- package/.codex/skills/clone-website/SKILL.md +487 -473
- package/.codex/skills/launchframe/SKILL.md +42 -0
- package/.continue/commands/clone-website.md +489 -475
- package/.continue/commands/launchframe.md +44 -0
- package/.continue/rules/project.md +82 -71
- package/.cursor/commands/clone-website.md +484 -470
- package/.cursor/commands/launchframe.md +39 -0
- package/.gemini/commands/clone-website.toml +490 -476
- package/.gemini/commands/launchframe.toml +45 -0
- package/.github/copilot-instructions.md +78 -67
- package/.github/skills/clone-website/SKILL.md +487 -473
- package/.github/skills/launchframe/SKILL.md +42 -0
- package/.opencode/commands/clone-website.md +487 -473
- package/.opencode/commands/launchframe.md +42 -0
- package/.windsurf/workflows/clone-website.md +484 -470
- package/.windsurf/workflows/launchframe.md +39 -0
- package/AGENTS.md +3 -2
- package/README.md +15 -14
- package/bin/launchframe.mjs +114 -77
- package/docs/research/INSPECTION_GUIDE.md +10 -0
- package/package.json +4 -2
- package/scripts/sync-skills.mjs +108 -95
- package/src/lib/launchframe-config.ts +2 -3
package/scripts/sync-skills.mjs
CHANGED
|
@@ -1,111 +1,124 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
* Generates
|
|
5
|
-
* Source of truth:
|
|
4
|
+
* Generates invokable skill/command files for all supported AI coding platforms.
|
|
5
|
+
* Source of truth: `.claude/skills/<skill-id>/SKILL.md` (YAML frontmatter + markdown body).
|
|
6
6
|
*
|
|
7
7
|
* Usage: node scripts/sync-skills.mjs
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
-
import { readFileSync, writeFileSync, mkdirSync } from
|
|
11
|
-
import { dirname, join } from
|
|
12
|
-
import { fileURLToPath } from
|
|
10
|
+
import { readFileSync, writeFileSync, mkdirSync } from "node:fs";
|
|
11
|
+
import { dirname, join } from "node:path";
|
|
12
|
+
import { fileURLToPath } from "node:url";
|
|
13
|
+
|
|
14
|
+
const ROOT = join(dirname(fileURLToPath(import.meta.url)), "..");
|
|
15
|
+
|
|
16
|
+
const SKILLS = [
|
|
17
|
+
{
|
|
18
|
+
id: "clone-website",
|
|
19
|
+
sourceRel: ".claude/skills/clone-website/SKILL.md",
|
|
20
|
+
shortDesc: "Reverse-engineer and clone any website as a pixel-perfect replica",
|
|
21
|
+
plainSubstitution: "the target URL provided by the user",
|
|
22
|
+
augmentArgumentHint: "<url>",
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
id: "launchframe",
|
|
26
|
+
sourceRel: ".claude/skills/launchframe/SKILL.md",
|
|
27
|
+
shortDesc:
|
|
28
|
+
"Scaffold with npx launchframe@latest into the current folder — no arguments required",
|
|
29
|
+
plainSubstitution:
|
|
30
|
+
"optional notes from the user after the slash command (the CLI itself needs no URL or SaaS strings)",
|
|
31
|
+
augmentArgumentHint: "",
|
|
32
|
+
},
|
|
33
|
+
];
|
|
13
34
|
|
|
14
|
-
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
let raw;
|
|
20
|
-
try {
|
|
21
|
-
raw = readFileSync(SOURCE, 'utf8').replace(/\r\n/g, '\n');
|
|
22
|
-
} catch {
|
|
23
|
-
console.error(`Error: Source skill not found at .claude/skills/clone-website/SKILL.md`);
|
|
24
|
-
process.exit(1);
|
|
35
|
+
function write(relPath, content) {
|
|
36
|
+
const full = join(ROOT, relPath);
|
|
37
|
+
mkdirSync(dirname(full), { recursive: true });
|
|
38
|
+
writeFileSync(full, content, "utf8");
|
|
39
|
+
console.log(` \u2713 ${relPath}`);
|
|
25
40
|
}
|
|
26
41
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
42
|
+
function parseSkill(sourceRel) {
|
|
43
|
+
const full = join(ROOT, sourceRel);
|
|
44
|
+
const raw = readFileSync(full, "utf8").replace(/\r\n/g, "\n");
|
|
45
|
+
const match = raw.match(/^---\n([\s\S]*?)\n---\n([\s\S]*)$/);
|
|
46
|
+
if (!match) {
|
|
47
|
+
throw new Error(`Could not parse frontmatter: ${sourceRel}`);
|
|
48
|
+
}
|
|
49
|
+
return { raw, body: match[2] };
|
|
31
50
|
}
|
|
32
51
|
|
|
33
|
-
|
|
34
|
-
const
|
|
52
|
+
function syncSkill(skill) {
|
|
53
|
+
const { id, sourceRel, shortDesc, plainSubstitution, augmentArgumentHint } = skill;
|
|
54
|
+
|
|
55
|
+
let parsed;
|
|
56
|
+
try {
|
|
57
|
+
parsed = parseSkill(sourceRel);
|
|
58
|
+
} catch (e) {
|
|
59
|
+
console.error(e.message || e);
|
|
60
|
+
process.exit(1);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const { raw, body } = parsed;
|
|
64
|
+
const noArgs = (text) => text.replace(/\$ARGUMENTS/g, plainSubstitution);
|
|
65
|
+
const header =
|
|
66
|
+
`<!-- AUTO-GENERATED from ${sourceRel} \u2014 do not edit directly.\n` +
|
|
67
|
+
` Run \`node scripts/sync-skills.mjs\` to regenerate. -->\n\n`;
|
|
68
|
+
|
|
69
|
+
console.log(`\nSyncing ${id}...\n Source: ${sourceRel}\n`);
|
|
70
|
+
|
|
71
|
+
write(`.codex/skills/${id}/SKILL.md`, raw);
|
|
72
|
+
write(`.github/skills/${id}/SKILL.md`, raw);
|
|
73
|
+
|
|
74
|
+
write(`.cursor/commands/${id}.md`, header + noArgs(body));
|
|
75
|
+
|
|
76
|
+
write(`.windsurf/workflows/${id}.md`, header + noArgs(body));
|
|
77
|
+
|
|
78
|
+
const geminiBody = body.replace(/\$ARGUMENTS/g, "{{args}}");
|
|
79
|
+
write(
|
|
80
|
+
`.gemini/commands/${id}.toml`,
|
|
81
|
+
`# AUTO-GENERATED from ${sourceRel}\n` +
|
|
82
|
+
`# Run \`node scripts/sync-skills.mjs\` to regenerate.\n\n` +
|
|
83
|
+
`description = ${JSON.stringify(shortDesc)}\n\n` +
|
|
84
|
+
`[prompt]\ntext = '''\n${geminiBody}\n'''\n`,
|
|
85
|
+
);
|
|
86
|
+
|
|
87
|
+
write(
|
|
88
|
+
`.opencode/commands/${id}.md`,
|
|
89
|
+
`---\ndescription: ${JSON.stringify(shortDesc)}\n---\n${header}${body}`,
|
|
90
|
+
);
|
|
91
|
+
|
|
92
|
+
write(
|
|
93
|
+
`.augment/commands/${id}.md`,
|
|
94
|
+
`---\ndescription: ${JSON.stringify(shortDesc)}\nargument-hint: ${JSON.stringify(augmentArgumentHint)}\n---\n${header}${body}`,
|
|
95
|
+
);
|
|
96
|
+
|
|
97
|
+
write(
|
|
98
|
+
`.continue/commands/${id}.md`,
|
|
99
|
+
`---\nname: ${id}\ndescription: ${JSON.stringify(shortDesc)}\ninvokable: true\n---\n${header}${body}`,
|
|
100
|
+
);
|
|
101
|
+
|
|
102
|
+
write(
|
|
103
|
+
`.amazonq/cli-agents/${id}.json`,
|
|
104
|
+
JSON.stringify(
|
|
105
|
+
{
|
|
106
|
+
name: id,
|
|
107
|
+
description: shortDesc,
|
|
108
|
+
prompt: noArgs(body),
|
|
109
|
+
fileContext: ["AGENTS.md", "docs/research/**"],
|
|
110
|
+
},
|
|
111
|
+
null,
|
|
112
|
+
2,
|
|
113
|
+
) + "\n",
|
|
114
|
+
);
|
|
115
|
+
}
|
|
35
116
|
|
|
36
|
-
|
|
117
|
+
console.log("Syncing skills to all platforms...");
|
|
37
118
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
mkdirSync(dirname(full), { recursive: true });
|
|
41
|
-
writeFileSync(full, content, 'utf8');
|
|
42
|
-
console.log(` \u2713 ${relPath}`);
|
|
119
|
+
for (const skill of SKILLS) {
|
|
120
|
+
syncSkill(skill);
|
|
43
121
|
}
|
|
44
122
|
|
|
45
|
-
const
|
|
46
|
-
|
|
47
|
-
' Run `node scripts/sync-skills.mjs` to regenerate. -->\n\n';
|
|
48
|
-
|
|
49
|
-
const noArgs = (text) => text.replace(/\$ARGUMENTS/g, 'the target URL provided by the user');
|
|
50
|
-
|
|
51
|
-
// --- Generate ---
|
|
52
|
-
|
|
53
|
-
console.log('Syncing clone-website skill to all platforms...');
|
|
54
|
-
console.log(` Source: .claude/skills/clone-website/SKILL.md\n`);
|
|
55
|
-
|
|
56
|
-
// 1. Codex CLI — same SKILL.md format, same $ARGUMENTS syntax
|
|
57
|
-
write('.codex/skills/clone-website/SKILL.md', raw);
|
|
58
|
-
|
|
59
|
-
// 2. GitHub Copilot — same SKILL.md format
|
|
60
|
-
write('.github/skills/clone-website/SKILL.md', raw);
|
|
61
|
-
|
|
62
|
-
// 3. Cursor — plain markdown, no argument substitution support
|
|
63
|
-
write('.cursor/commands/clone-website.md', HEADER + noArgs(body));
|
|
64
|
-
|
|
65
|
-
// 4. Windsurf — markdown workflow
|
|
66
|
-
write('.windsurf/workflows/clone-website.md', HEADER + noArgs(body));
|
|
67
|
-
|
|
68
|
-
// 5. Gemini CLI — TOML format, {{args}} for arguments
|
|
69
|
-
const geminiBody = body.replace(/\$ARGUMENTS/g, '{{args}}');
|
|
70
|
-
write(
|
|
71
|
-
'.gemini/commands/clone-website.toml',
|
|
72
|
-
`# AUTO-GENERATED from .claude/skills/clone-website/SKILL.md\n` +
|
|
73
|
-
`# Run \`node scripts/sync-skills.mjs\` to regenerate.\n\n` +
|
|
74
|
-
`description = "${shortDesc}"\n\n` +
|
|
75
|
-
`[prompt]\ntext = '''\n${geminiBody}\n'''\n`
|
|
76
|
-
);
|
|
77
|
-
|
|
78
|
-
// 6. OpenCode — markdown + YAML frontmatter, $ARGUMENTS works natively
|
|
79
|
-
write(
|
|
80
|
-
'.opencode/commands/clone-website.md',
|
|
81
|
-
`---\ndescription: "${shortDesc}"\n---\n${HEADER}${body}`
|
|
82
|
-
);
|
|
83
|
-
|
|
84
|
-
// 7. Augment Code — markdown + YAML frontmatter
|
|
85
|
-
write(
|
|
86
|
-
'.augment/commands/clone-website.md',
|
|
87
|
-
`---\ndescription: "${shortDesc}"\nargument-hint: "<url>"\n---\n${HEADER}${body}`
|
|
88
|
-
);
|
|
89
|
-
|
|
90
|
-
// 8. Continue — prompt file with invokable: true
|
|
91
|
-
write(
|
|
92
|
-
'.continue/commands/clone-website.md',
|
|
93
|
-
`---\nname: clone-website\ndescription: "${shortDesc}"\ninvokable: true\n---\n${HEADER}${body}`
|
|
94
|
-
);
|
|
95
|
-
|
|
96
|
-
// 9. Amazon Q — JSON agent definition
|
|
97
|
-
write(
|
|
98
|
-
'.amazonq/cli-agents/clone-website.json',
|
|
99
|
-
JSON.stringify(
|
|
100
|
-
{
|
|
101
|
-
name: 'clone-website',
|
|
102
|
-
description: shortDesc,
|
|
103
|
-
prompt: noArgs(body),
|
|
104
|
-
fileContext: ['AGENTS.md', 'docs/research/**'],
|
|
105
|
-
},
|
|
106
|
-
null,
|
|
107
|
-
2
|
|
108
|
-
) + '\n'
|
|
109
|
-
);
|
|
110
|
-
|
|
111
|
-
console.log('\nDone! 9 platform command files generated from source skill.');
|
|
123
|
+
const totalFiles = SKILLS.length * 9;
|
|
124
|
+
console.log(`\nDone! ${totalFiles} platform files generated (${SKILLS.length} skills \u00d7 9 targets).`);
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Defaults
|
|
3
|
-
* The Launchframe CLI overwrites this file in scaffolded projects.
|
|
2
|
+
* Defaults before scaffolding. After `npx launchframe@latest`, edit these values.
|
|
4
3
|
*/
|
|
5
4
|
export const LAUNCHFRAME_SOURCE_URL = "https://example.com" as const;
|
|
6
5
|
|
|
7
6
|
export const LAUNCHFRAME_SAAS_IDEA =
|
|
8
|
-
|
|
7
|
+
"Edit your SaaS pitch here, then run /clone-website with LAUNCHFRAME_SOURCE_URL." as const;
|