@webhouse/create-cms 0.1.1 → 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/dist/index.js +178 -51
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,23 +1,47 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
// src/index.ts
|
|
4
|
-
import { existsSync, mkdirSync, writeFileSync } from "fs";
|
|
4
|
+
import { existsSync, mkdirSync, readdirSync, writeFileSync } from "fs";
|
|
5
5
|
import { join, resolve } from "path";
|
|
6
|
+
import { execSync } from "child_process";
|
|
6
7
|
var projectName = process.argv[2] || "my-cms-site";
|
|
7
8
|
var projectDir = resolve(process.cwd(), projectName);
|
|
9
|
+
var cyan = (s) => `\x1B[36m${s}\x1B[0m`;
|
|
10
|
+
var green = (s) => `\x1B[32m${s}\x1B[0m`;
|
|
11
|
+
var dim = (s) => `\x1B[2m${s}\x1B[0m`;
|
|
12
|
+
var bold = (s) => `\x1B[1m${s}\x1B[0m`;
|
|
8
13
|
console.log("");
|
|
9
|
-
console.log(
|
|
14
|
+
console.log(`${cyan("i")} Creating new CMS project: ${bold(projectName)}`);
|
|
10
15
|
console.log("");
|
|
11
16
|
if (existsSync(projectDir)) {
|
|
12
|
-
|
|
13
|
-
|
|
17
|
+
const entries = readdirSync(projectDir);
|
|
18
|
+
if (entries.length > 0) {
|
|
19
|
+
console.error(`\x1B[31m\u2717\x1B[0m Directory already exists and is not empty: ${projectDir}`);
|
|
20
|
+
process.exit(1);
|
|
21
|
+
}
|
|
22
|
+
} else {
|
|
23
|
+
mkdirSync(projectDir, { recursive: true });
|
|
24
|
+
}
|
|
25
|
+
function write(relativePath, content) {
|
|
26
|
+
const fullPath = join(projectDir, relativePath);
|
|
27
|
+
const dir = fullPath.substring(0, fullPath.lastIndexOf("/"));
|
|
28
|
+
if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
|
|
29
|
+
writeFileSync(fullPath, content, "utf-8");
|
|
30
|
+
console.log(` ${green("\u2713")} ${relativePath}`);
|
|
14
31
|
}
|
|
15
|
-
|
|
16
|
-
mkdirSync(join(projectDir, "content", "posts"), { recursive: true });
|
|
17
|
-
writeFileSync(join(projectDir, "cms.config.ts"), `import { defineConfig, defineCollection } from '@webhouse/cms';
|
|
32
|
+
write("cms.config.ts", `import { defineConfig, defineCollection } from '@webhouse/cms';
|
|
18
33
|
|
|
19
34
|
export default defineConfig({
|
|
20
35
|
collections: [
|
|
36
|
+
defineCollection({
|
|
37
|
+
name: 'pages',
|
|
38
|
+
label: 'Pages',
|
|
39
|
+
fields: [
|
|
40
|
+
{ name: 'title', type: 'text', label: 'Title', required: true },
|
|
41
|
+
{ name: 'description', type: 'textarea', label: 'Description' },
|
|
42
|
+
{ name: 'content', type: 'richtext', label: 'Content' },
|
|
43
|
+
],
|
|
44
|
+
}),
|
|
21
45
|
defineCollection({
|
|
22
46
|
name: 'posts',
|
|
23
47
|
label: 'Blog Posts',
|
|
@@ -26,6 +50,8 @@ export default defineConfig({
|
|
|
26
50
|
{ name: 'excerpt', type: 'textarea', label: 'Excerpt' },
|
|
27
51
|
{ name: 'content', type: 'richtext', label: 'Content' },
|
|
28
52
|
{ name: 'date', type: 'date', label: 'Publish Date' },
|
|
53
|
+
{ name: 'author', type: 'text', label: 'Author' },
|
|
54
|
+
{ name: 'tags', type: 'tags', label: 'Tags' },
|
|
29
55
|
],
|
|
30
56
|
}),
|
|
31
57
|
],
|
|
@@ -35,38 +61,105 @@ export default defineConfig({
|
|
|
35
61
|
contentDir: 'content',
|
|
36
62
|
},
|
|
37
63
|
},
|
|
38
|
-
build: {
|
|
39
|
-
outDir: 'dist',
|
|
40
|
-
},
|
|
41
|
-
api: {
|
|
42
|
-
port: 3000,
|
|
43
|
-
},
|
|
44
64
|
});
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
);
|
|
69
|
-
|
|
65
|
+
`);
|
|
66
|
+
write("CLAUDE.md", `# ${projectName}
|
|
67
|
+
|
|
68
|
+
This is a **@webhouse/cms** managed site.
|
|
69
|
+
|
|
70
|
+
## Content
|
|
71
|
+
|
|
72
|
+
All content lives in the \`content/\` directory as JSON files, organised by collection:
|
|
73
|
+
|
|
74
|
+
\`\`\`
|
|
75
|
+
content/
|
|
76
|
+
pages/
|
|
77
|
+
posts/
|
|
78
|
+
\`\`\`
|
|
79
|
+
|
|
80
|
+
## Reading content in Next.js
|
|
81
|
+
|
|
82
|
+
Use the \`@webhouse/cms\` SDK to load content:
|
|
83
|
+
|
|
84
|
+
\`\`\`ts
|
|
85
|
+
import { loadContent } from '@webhouse/cms';
|
|
86
|
+
|
|
87
|
+
// Load all entries in a collection
|
|
88
|
+
const posts = await loadContent('posts');
|
|
89
|
+
|
|
90
|
+
// Load a single entry by slug
|
|
91
|
+
const post = await loadContent('posts', 'hello-world');
|
|
92
|
+
\`\`\`
|
|
93
|
+
|
|
94
|
+
## Adding new collections
|
|
95
|
+
|
|
96
|
+
Edit \`cms.config.ts\` and add a new \`defineCollection()\` block.
|
|
97
|
+
After adding a collection, restart the CMS admin to see it.
|
|
98
|
+
|
|
99
|
+
## Running the CMS admin
|
|
100
|
+
|
|
101
|
+
\`\`\`bash
|
|
102
|
+
npx @webhouse/cms-cli dev # Local admin UI
|
|
103
|
+
\`\`\`
|
|
104
|
+
|
|
105
|
+
Or use **webhouse.app** for the hosted admin experience.
|
|
106
|
+
|
|
107
|
+
## Reference
|
|
108
|
+
|
|
109
|
+
See the [\`@webhouse/cms\` CLAUDE.md](https://github.com/webhousecode/cms/blob/main/CLAUDE.md) for full field type documentation and API reference.
|
|
110
|
+
`);
|
|
111
|
+
write(".mcp.json", JSON.stringify({
|
|
112
|
+
mcpServers: {
|
|
113
|
+
cms: {
|
|
114
|
+
command: "npx",
|
|
115
|
+
args: ["@webhouse/cms-cli", "mcp"]
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}, null, 2) + "\n");
|
|
119
|
+
write("content/.gitkeep", "");
|
|
120
|
+
write(".gitignore", `# CMS per-site data (AI keys, user data \u2014 never committed)
|
|
121
|
+
_data/
|
|
122
|
+
.mcp.json
|
|
123
|
+
|
|
124
|
+
# dotenv environment variable files
|
|
125
|
+
.env
|
|
126
|
+
.env.*
|
|
127
|
+
!.env.example
|
|
128
|
+
|
|
129
|
+
# Dependency directories
|
|
130
|
+
node_modules/
|
|
131
|
+
|
|
132
|
+
# Build output
|
|
133
|
+
.next/
|
|
134
|
+
out/
|
|
135
|
+
dist/
|
|
136
|
+
build/
|
|
137
|
+
|
|
138
|
+
# OS
|
|
139
|
+
.DS_Store
|
|
140
|
+
Thumbs.db
|
|
141
|
+
|
|
142
|
+
# Editor
|
|
143
|
+
.vscode/
|
|
144
|
+
.idea/
|
|
145
|
+
*.swp
|
|
146
|
+
*.swo
|
|
147
|
+
|
|
148
|
+
# Debug
|
|
149
|
+
npm-debug.log*
|
|
150
|
+
yarn-debug.log*
|
|
151
|
+
yarn-error.log*
|
|
152
|
+
`);
|
|
153
|
+
write(".env.example", `# ${projectName}
|
|
154
|
+
# Copy to .env.local and fill in values
|
|
155
|
+
|
|
156
|
+
# Site URL (used for preview links and OG tags)
|
|
157
|
+
# NEXT_PUBLIC_SITE_URL=https://example.com
|
|
158
|
+
|
|
159
|
+
# AI keys (optional \u2014 can also be set via CMS Admin \u2192 Settings \u2192 AI)
|
|
160
|
+
# ANTHROPIC_API_KEY=
|
|
161
|
+
`);
|
|
162
|
+
write("package.json", JSON.stringify({
|
|
70
163
|
name: projectName,
|
|
71
164
|
version: "0.1.0",
|
|
72
165
|
private: true,
|
|
@@ -76,20 +169,54 @@ writeFileSync(join(projectDir, "package.json"), JSON.stringify({
|
|
|
76
169
|
build: "cms build"
|
|
77
170
|
},
|
|
78
171
|
dependencies: {
|
|
79
|
-
"@webhouse/cms": "^0.1.
|
|
80
|
-
"@webhouse/cms-cli": "^0.1.
|
|
81
|
-
"@webhouse/cms-ai": "^0.1.1"
|
|
172
|
+
"@webhouse/cms": "^0.1.2",
|
|
173
|
+
"@webhouse/cms-cli": "^0.1.2"
|
|
82
174
|
}
|
|
83
|
-
}, null, 2)
|
|
84
|
-
|
|
175
|
+
}, null, 2) + "\n");
|
|
176
|
+
write(".nvmrc", "22\n");
|
|
177
|
+
console.log("");
|
|
178
|
+
function detectPackageManager() {
|
|
179
|
+
const userAgent = process.env.npm_config_user_agent || "";
|
|
180
|
+
if (userAgent.startsWith("pnpm")) return "pnpm";
|
|
181
|
+
if (userAgent.startsWith("yarn")) return "yarn";
|
|
182
|
+
try {
|
|
183
|
+
execSync("pnpm --version", { stdio: "ignore" });
|
|
184
|
+
return "pnpm";
|
|
185
|
+
} catch {
|
|
186
|
+
}
|
|
187
|
+
try {
|
|
188
|
+
execSync("yarn --version", { stdio: "ignore" });
|
|
189
|
+
return "yarn";
|
|
190
|
+
} catch {
|
|
191
|
+
}
|
|
192
|
+
return "npm";
|
|
193
|
+
}
|
|
194
|
+
var pm = detectPackageManager();
|
|
195
|
+
console.log(`${cyan("i")} Installing dependencies with ${bold(pm)}...`);
|
|
196
|
+
console.log("");
|
|
197
|
+
try {
|
|
198
|
+
execSync(`${pm} install`, { cwd: projectDir, stdio: "inherit" });
|
|
199
|
+
console.log("");
|
|
200
|
+
console.log(`${green("\u2713")} Dependencies installed`);
|
|
201
|
+
} catch {
|
|
202
|
+
console.log("");
|
|
203
|
+
console.log(`\x1B[33m!\x1B[0m Could not install dependencies. Run \`${pm} install\` manually.`);
|
|
204
|
+
}
|
|
205
|
+
console.log("");
|
|
206
|
+
console.log(`${green("\u2713")} Project created at ${dim(projectDir)}`);
|
|
207
|
+
console.log("");
|
|
208
|
+
console.log(bold("Next steps:"));
|
|
209
|
+
console.log("");
|
|
210
|
+
console.log(` ${dim("$")} cd ${projectName}`);
|
|
211
|
+
console.log(` ${dim("$")} npx @webhouse/cms-cli dev ${dim("# Start CMS admin UI")}`);
|
|
212
|
+
console.log("");
|
|
213
|
+
console.log(bold("AI content generation:"));
|
|
214
|
+
console.log("");
|
|
215
|
+
console.log(` 1. Add your ANTHROPIC_API_KEY to .env`);
|
|
216
|
+
console.log(` 2. ${dim("$")} npx @webhouse/cms-cli ai generate posts "Write a blog post about..."`);
|
|
85
217
|
console.log("");
|
|
86
|
-
console.log("
|
|
87
|
-
console.log(` cd ${projectName}`);
|
|
88
|
-
console.log(" npm install");
|
|
89
|
-
console.log(" npx cms dev # Start dev server + admin UI");
|
|
90
|
-
console.log(" npx cms build # Build static site");
|
|
218
|
+
console.log(bold("MCP integration:"));
|
|
91
219
|
console.log("");
|
|
92
|
-
console.log(
|
|
93
|
-
console.log(
|
|
94
|
-
console.log(' 2. npx cms ai generate posts "Write a blog post about..."');
|
|
220
|
+
console.log(` .mcp.json is already configured \u2014 Claude Code and other`);
|
|
221
|
+
console.log(` MCP-compatible agents can manage your content automatically.`);
|
|
95
222
|
console.log("");
|