@autono/create-open-pages 0.5.0 → 0.7.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/cli.js +168 -110
- package/package.json +7 -8
- package/template/README.md +2 -1
- package/template/netlify.toml +4 -0
- package/template/package.json +1 -2
- package/template/vercel.json +2 -0
package/dist/cli.js
CHANGED
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import * as p from "@clack/prompts";
|
|
3
|
+
import { S_ERROR } from "@clack/prompts";
|
|
2
4
|
import chalk from "chalk";
|
|
3
5
|
import { cp, mkdir, readFile, readdir, rm, symlink, writeFile } from "node:fs/promises";
|
|
4
|
-
import { basename, dirname, join, resolve } from "node:path";
|
|
6
|
+
import { basename, dirname, join, relative, resolve, sep } from "node:path";
|
|
5
7
|
import { fileURLToPath } from "node:url";
|
|
6
8
|
import { Command } from "commander";
|
|
7
|
-
import prompts from "prompts";
|
|
8
9
|
import { spawn } from "node:child_process";
|
|
10
|
+
import { createHash } from "node:crypto";
|
|
9
11
|
import { existsSync } from "node:fs";
|
|
10
|
-
|
|
11
12
|
//#region src/git.ts
|
|
12
13
|
const IS_WINDOWS$1 = process.platform === "win32";
|
|
13
14
|
async function run$1(cmd, args, cwd) {
|
|
14
|
-
return new Promise((resolve
|
|
15
|
+
return new Promise((resolve, reject) => {
|
|
15
16
|
const child = spawn(cmd, args, {
|
|
16
17
|
cwd,
|
|
17
18
|
stdio: [
|
|
@@ -30,7 +31,7 @@ async function run$1(cmd, args, cwd) {
|
|
|
30
31
|
stderr += d.toString();
|
|
31
32
|
});
|
|
32
33
|
child.on("error", reject);
|
|
33
|
-
child.on("close", (code) => resolve
|
|
34
|
+
child.on("close", (code) => resolve({
|
|
34
35
|
code,
|
|
35
36
|
stdout,
|
|
36
37
|
stderr
|
|
@@ -39,8 +40,7 @@ async function run$1(cmd, args, cwd) {
|
|
|
39
40
|
}
|
|
40
41
|
async function isGitAvailable() {
|
|
41
42
|
try {
|
|
42
|
-
|
|
43
|
-
return res.code === 0;
|
|
43
|
+
return (await run$1("git", ["--version"], process.cwd())).code === 0;
|
|
44
44
|
} catch {
|
|
45
45
|
return false;
|
|
46
46
|
}
|
|
@@ -62,10 +62,10 @@ async function gitInitAndCommit(target) {
|
|
|
62
62
|
status: "skipped-nested",
|
|
63
63
|
message: "target is already inside a git work tree; leaving parent repo alone"
|
|
64
64
|
};
|
|
65
|
-
const init
|
|
66
|
-
if (init
|
|
65
|
+
const init = await run$1("git", ["init"], target);
|
|
66
|
+
if (init.code !== 0) return {
|
|
67
67
|
status: "failed",
|
|
68
|
-
message: `git init failed: ${init
|
|
68
|
+
message: `git init failed: ${init.stderr.trim() || init.stdout.trim()}`
|
|
69
69
|
};
|
|
70
70
|
const add = await run$1("git", ["add", "-A"], target);
|
|
71
71
|
if (add.code !== 0) return {
|
|
@@ -83,7 +83,6 @@ async function gitInitAndCommit(target) {
|
|
|
83
83
|
};
|
|
84
84
|
return { status: "committed" };
|
|
85
85
|
}
|
|
86
|
-
|
|
87
86
|
//#endregion
|
|
88
87
|
//#region src/init.ts
|
|
89
88
|
const HERE = dirname(fileURLToPath(import.meta.url));
|
|
@@ -98,11 +97,10 @@ function sanitizeDirName(value) {
|
|
|
98
97
|
}
|
|
99
98
|
async function isDirNonEmpty(target) {
|
|
100
99
|
if (!existsSync(target)) return false;
|
|
101
|
-
|
|
102
|
-
return entries.some((e) => !e.startsWith("."));
|
|
100
|
+
return (await readdir(target)).some((e) => !e.startsWith("."));
|
|
103
101
|
}
|
|
104
102
|
function coreVersionRange() {
|
|
105
|
-
return `^0.
|
|
103
|
+
return `^0.7.0`;
|
|
106
104
|
}
|
|
107
105
|
async function linkOrCopy(relSrc, dst) {
|
|
108
106
|
await rm(dst, {
|
|
@@ -128,25 +126,40 @@ async function materializeTemplateLinks(target) {
|
|
|
128
126
|
await linkOrCopy(join("..", "..", ".agents", "skills", entry.name), join(claudeSkills, entry.name));
|
|
129
127
|
}
|
|
130
128
|
}
|
|
131
|
-
async function
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
129
|
+
async function writeUiManifest(target) {
|
|
130
|
+
const manifest = {};
|
|
131
|
+
for (const entry of [
|
|
132
|
+
"ui",
|
|
133
|
+
"lib",
|
|
134
|
+
"hooks"
|
|
135
|
+
]) {
|
|
136
|
+
const root = join(target, entry);
|
|
137
|
+
if (!existsSync(root)) continue;
|
|
138
|
+
for (const rel of await collectFiles(root)) {
|
|
139
|
+
const wsRel = join(entry, rel).split(sep).join("/");
|
|
140
|
+
manifest[wsRel] = createHash("sha256").update(await readFile(join(root, rel))).digest("hex");
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
const sorted = Object.fromEntries(Object.entries(manifest).sort(([a], [b]) => a.localeCompare(b)));
|
|
144
|
+
await writeFile(join(target, "ui", ".sync-manifest.json"), `${JSON.stringify(sorted, null, 2)}\n`);
|
|
141
145
|
}
|
|
142
|
-
async function
|
|
143
|
-
const
|
|
146
|
+
async function collectFiles(dir, prefix = "") {
|
|
147
|
+
const out = [];
|
|
148
|
+
for (const entry of await readdir(dir, { withFileTypes: true })) {
|
|
149
|
+
const rel = prefix ? join(prefix, entry.name) : entry.name;
|
|
150
|
+
if (entry.isDirectory()) out.push(...await collectFiles(join(dir, entry.name), rel));
|
|
151
|
+
else if (entry.isFile()) out.push(rel);
|
|
152
|
+
}
|
|
153
|
+
return out;
|
|
154
|
+
}
|
|
155
|
+
async function scaffold(opts) {
|
|
156
|
+
const { target, force, name } = opts;
|
|
144
157
|
if (!existsSync(TEMPLATE_DIR)) throw new Error(`Template missing at ${TEMPLATE_DIR}. If you are running from source, run \`pnpm --filter @autono/create-open-pages build\` first.`);
|
|
145
|
-
const target = resolve(process.cwd(), dir);
|
|
146
158
|
await mkdir(target, { recursive: true });
|
|
147
159
|
if (await isDirNonEmpty(target) && !force) throw new Error(`Target ${target} is not empty. Pass --force to scaffold into it anyway.`);
|
|
148
160
|
await cp(TEMPLATE_DIR, target, { recursive: true });
|
|
149
161
|
await materializeTemplateLinks(target);
|
|
162
|
+
await writeUiManifest(target);
|
|
150
163
|
const pkgPath = join(target, "package.json");
|
|
151
164
|
if (existsSync(pkgPath)) {
|
|
152
165
|
const pkg = JSON.parse(await readFile(pkgPath, "utf8"));
|
|
@@ -157,34 +170,38 @@ async function init(opts) {
|
|
|
157
170
|
await writeFile(pkgPath, `${JSON.stringify(pkg, null, 2)}\n`);
|
|
158
171
|
}
|
|
159
172
|
await writeFile(join(target, ".gitignore"), "node_modules\ndist\nexport\n.DS_Store\n");
|
|
160
|
-
const cdTarget = dir === "." ? basename(target) : dir;
|
|
161
|
-
process.stdout.write(`\n${chalk.green.bold("✔ Created open-pages workspace")} ${chalk.dim(`in ${target}`)}\n`);
|
|
162
|
-
let installed = false;
|
|
163
|
-
if (install) {
|
|
164
|
-
process.stdout.write(`\n${chalk.bold(`Installing dependencies with ${packageManager}…`)}\n\n`);
|
|
165
|
-
try {
|
|
166
|
-
await runInstall(packageManager, target);
|
|
167
|
-
installed = true;
|
|
168
|
-
} catch (err) {
|
|
169
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
170
|
-
process.stdout.write(`\n${chalk.yellow("! Dependency install failed:")} ${chalk.dim(msg)}\n` + chalk.dim(` You can retry manually with \`${packageManager} install\`.\n`));
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
if (git) {
|
|
174
|
-
const result = await gitInitAndCommit(target);
|
|
175
|
-
if (result.status === "committed") process.stdout.write(`${chalk.green("✔")} Initialized git repository with first commit.\n`);
|
|
176
|
-
else if (result.status === "skipped-nested") process.stdout.write(`${chalk.yellow("!")} Skipped ${chalk.bold("git init")}: ${chalk.dim(result.message ?? "")}\n`);
|
|
177
|
-
else if (result.status === "skipped-no-git") process.stdout.write(`${chalk.yellow("!")} Skipped git setup: ${chalk.dim(result.message ?? "")}\n`);
|
|
178
|
-
else process.stdout.write(`${chalk.yellow("!")} Git setup failed: ${chalk.dim(result.message ?? "")}\n` + chalk.dim(" You can initialize the repo manually.\n"));
|
|
179
|
-
}
|
|
180
|
-
process.stdout.write(`\n${chalk.bold("Next steps:")}\n`);
|
|
181
|
-
process.stdout.write(` ${chalk.cyan(`cd ${cdTarget}`)}\n`);
|
|
182
|
-
if (!installed && install) process.stdout.write(` ${chalk.cyan(`${packageManager} install`)}\n`);
|
|
183
|
-
else if (!install) process.stdout.write(` ${chalk.cyan(`${packageManager} install`)} ${chalk.dim("# install was skipped")}\n`);
|
|
184
|
-
const devCommand = packageManager === "npm" ? "npm run dev" : `${packageManager} dev`;
|
|
185
|
-
process.stdout.write(` ${chalk.cyan(devCommand)}\n`);
|
|
186
173
|
}
|
|
187
|
-
|
|
174
|
+
function installDependencies(pm, cwd) {
|
|
175
|
+
return new Promise((res) => {
|
|
176
|
+
let output = "";
|
|
177
|
+
const child = spawn(pm, ["install"], {
|
|
178
|
+
cwd,
|
|
179
|
+
stdio: [
|
|
180
|
+
"ignore",
|
|
181
|
+
"pipe",
|
|
182
|
+
"pipe"
|
|
183
|
+
],
|
|
184
|
+
shell: IS_WINDOWS
|
|
185
|
+
});
|
|
186
|
+
child.stdout?.on("data", (chunk) => {
|
|
187
|
+
output += chunk.toString();
|
|
188
|
+
});
|
|
189
|
+
child.stderr?.on("data", (chunk) => {
|
|
190
|
+
output += chunk.toString();
|
|
191
|
+
});
|
|
192
|
+
child.on("error", (err) => res({
|
|
193
|
+
ok: false,
|
|
194
|
+
output: err.message
|
|
195
|
+
}));
|
|
196
|
+
child.on("close", (code) => {
|
|
197
|
+
if (code === 0) res({ ok: true });
|
|
198
|
+
else res({
|
|
199
|
+
ok: false,
|
|
200
|
+
output: output.trim() || `${pm} install exited with code ${code}`
|
|
201
|
+
});
|
|
202
|
+
});
|
|
203
|
+
});
|
|
204
|
+
}
|
|
188
205
|
//#endregion
|
|
189
206
|
//#region src/package-manager.ts
|
|
190
207
|
const PACKAGE_MANAGERS = [
|
|
@@ -200,17 +217,18 @@ function detectPackageManager() {
|
|
|
200
217
|
if (ua.startsWith("bun")) return "bun";
|
|
201
218
|
return "npm";
|
|
202
219
|
}
|
|
203
|
-
|
|
204
220
|
//#endregion
|
|
205
221
|
//#region src/index.ts
|
|
206
222
|
async function readVersion() {
|
|
207
223
|
const here = dirname(fileURLToPath(import.meta.url));
|
|
208
|
-
|
|
209
|
-
return pkg.version;
|
|
224
|
+
return JSON.parse(await readFile(join(here, "..", "package.json"), "utf8")).version;
|
|
210
225
|
}
|
|
211
|
-
function
|
|
212
|
-
|
|
213
|
-
|
|
226
|
+
function unwrap(value) {
|
|
227
|
+
if (p.isCancel(value)) {
|
|
228
|
+
p.cancel("Cancelled.");
|
|
229
|
+
process.exit(130);
|
|
230
|
+
}
|
|
231
|
+
return value;
|
|
214
232
|
}
|
|
215
233
|
function packageManagerFromFlags(flags) {
|
|
216
234
|
const picks = [];
|
|
@@ -218,94 +236,134 @@ function packageManagerFromFlags(flags) {
|
|
|
218
236
|
if (flags.usePnpm) picks.push("pnpm");
|
|
219
237
|
if (flags.useYarn) picks.push("yarn");
|
|
220
238
|
if (flags.useBun) picks.push("bun");
|
|
221
|
-
if (picks.length > 1) throw new Error(`Only one of --use-npm / --use-pnpm / --use-yarn / --use-bun may be specified (got ${picks.map((
|
|
239
|
+
if (picks.length > 1) throw new Error(`Only one of --use-npm / --use-pnpm / --use-yarn / --use-bun may be specified (got ${picks.map((pm) => `--use-${pm}`).join(", ")}).`);
|
|
222
240
|
return picks[0];
|
|
223
241
|
}
|
|
242
|
+
function displayPath(target) {
|
|
243
|
+
const rel = relative(process.cwd(), target);
|
|
244
|
+
if (rel === "" || rel.startsWith("..")) return target;
|
|
245
|
+
return rel;
|
|
246
|
+
}
|
|
247
|
+
function step(label, isTTY) {
|
|
248
|
+
const spinner = isTTY ? p.spinner() : void 0;
|
|
249
|
+
if (spinner) spinner.start(label);
|
|
250
|
+
else p.log.step(label);
|
|
251
|
+
return {
|
|
252
|
+
done(message) {
|
|
253
|
+
if (spinner) spinner.stop(message);
|
|
254
|
+
else p.log.step(message);
|
|
255
|
+
},
|
|
256
|
+
fail(message) {
|
|
257
|
+
if (spinner) spinner.error(message);
|
|
258
|
+
else p.log.error(message);
|
|
259
|
+
}
|
|
260
|
+
};
|
|
261
|
+
}
|
|
262
|
+
function tail(output, lines = 12) {
|
|
263
|
+
return output.split("\n").slice(-lines).join("\n");
|
|
264
|
+
}
|
|
224
265
|
async function runInit(dirArg, flags) {
|
|
225
266
|
const isTTY = Boolean(process.stdin.isTTY && process.stdout.isTTY);
|
|
267
|
+
let packageManager = packageManagerFromFlags(flags);
|
|
226
268
|
let dir = dirArg;
|
|
227
|
-
const name = flags.name;
|
|
228
269
|
let force = flags.force ?? false;
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
}, { onCancel });
|
|
237
|
-
dir = answers.dir;
|
|
238
|
-
}
|
|
270
|
+
const install = flags.install !== false;
|
|
271
|
+
const git = flags.git !== false;
|
|
272
|
+
if (isTTY && dir === void 0) dir = unwrap(await p.text({
|
|
273
|
+
message: "Where should we create your workspace?",
|
|
274
|
+
placeholder: ".",
|
|
275
|
+
defaultValue: "."
|
|
276
|
+
}));
|
|
239
277
|
if (dir !== void 0) {
|
|
240
278
|
const safe = sanitizeDirName(dir);
|
|
241
279
|
if (safe !== dir) {
|
|
242
280
|
if (!isTTY) throw new Error(`Target directory "${dir}" contains characters that break shell commands (spaces, quotes, etc.). Try "${safe}" instead.`);
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
type: "text",
|
|
246
|
-
name: "dir",
|
|
281
|
+
p.log.warn(`${chalk.bold(`"${dir}"`)} has characters that confuse shells.`);
|
|
282
|
+
dir = sanitizeDirName(unwrap(await p.text({
|
|
247
283
|
message: "Directory name",
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
284
|
+
initialValue: safe,
|
|
285
|
+
validate: (value) => value?.trim() ? void 0 : "Enter a directory name."
|
|
286
|
+
})));
|
|
251
287
|
}
|
|
252
288
|
}
|
|
253
|
-
if (isTTY && packageManager === void 0 &&
|
|
289
|
+
if (isTTY && packageManager === void 0 && install) {
|
|
254
290
|
const detected = detectPackageManager();
|
|
255
|
-
|
|
256
|
-
type: "select",
|
|
257
|
-
name: "packageManager",
|
|
291
|
+
packageManager = unwrap(await p.select({
|
|
258
292
|
message: "Package manager",
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
293
|
+
options: PACKAGE_MANAGERS.map((pm) => ({
|
|
294
|
+
value: pm,
|
|
295
|
+
label: pm,
|
|
296
|
+
hint: pm === detected ? "detected" : void 0
|
|
262
297
|
})),
|
|
263
|
-
|
|
264
|
-
}
|
|
265
|
-
packageManager = answers.packageManager;
|
|
298
|
+
initialValue: detected
|
|
299
|
+
}));
|
|
266
300
|
}
|
|
267
301
|
const resolvedDir = dir ?? ".";
|
|
268
302
|
const target = resolve(process.cwd(), resolvedDir);
|
|
269
303
|
if (!force && await isDirNonEmpty(target)) {
|
|
270
304
|
if (!isTTY) throw new Error(`Target ${target} is not empty. Pass --force to scaffold into it anyway.`);
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
}, { onCancel });
|
|
277
|
-
if (!overwrite) {
|
|
278
|
-
process.stdout.write(chalk.dim("Aborted.\n"));
|
|
305
|
+
if (!unwrap(await p.confirm({
|
|
306
|
+
message: `${chalk.yellow(displayPath(target))} is not empty. Scaffold into it anyway?`,
|
|
307
|
+
initialValue: false
|
|
308
|
+
}))) {
|
|
309
|
+
p.outro(chalk.dim("Nothing written."));
|
|
279
310
|
return;
|
|
280
311
|
}
|
|
281
312
|
force = true;
|
|
282
313
|
}
|
|
283
|
-
const
|
|
284
|
-
|
|
314
|
+
const pm = packageManager ?? detectPackageManager();
|
|
315
|
+
await scaffold({
|
|
316
|
+
target,
|
|
285
317
|
force,
|
|
286
|
-
name
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
318
|
+
name: flags.name
|
|
319
|
+
});
|
|
320
|
+
p.log.step(`Created workspace ${chalk.dim(`in ${displayPath(target)}`)}`);
|
|
321
|
+
let installed = false;
|
|
322
|
+
if (install) {
|
|
323
|
+
const task = step(`Installing dependencies with ${pm}`, isTTY);
|
|
324
|
+
const result = await installDependencies(pm, target);
|
|
325
|
+
if (result.ok) {
|
|
326
|
+
installed = true;
|
|
327
|
+
task.done(`Installed dependencies with ${pm}`);
|
|
328
|
+
} else {
|
|
329
|
+
task.fail("Dependency install failed");
|
|
330
|
+
p.log.message(chalk.dim(tail(result.output)));
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
if (git) {
|
|
334
|
+
const result = await gitInitAndCommit(target);
|
|
335
|
+
if (result.status === "committed") p.log.step("Initialized git repository");
|
|
336
|
+
else if (result.status === "failed") p.log.warn(`Git setup failed ${chalk.dim(`· ${result.message ?? ""}`)}`);
|
|
337
|
+
else p.log.info(`Skipped git init ${chalk.dim(`· ${result.message ?? ""}`)}`);
|
|
338
|
+
}
|
|
339
|
+
const next = [];
|
|
340
|
+
if (target !== process.cwd()) next.push(`cd ${resolvedDir}`);
|
|
341
|
+
if (!installed) next.push(`${pm} install`);
|
|
342
|
+
next.push(pm === "npm" ? "npm run dev" : `${pm} dev`);
|
|
343
|
+
p.note(next.map((line) => chalk.cyan(line)).join("\n"), "Next steps");
|
|
344
|
+
p.outro(`All set! ${chalk.dim("Pages: https://pages.openpages.sh")}`);
|
|
292
345
|
}
|
|
293
346
|
async function run(argv) {
|
|
294
347
|
const version = await readVersion();
|
|
295
348
|
const program = new Command();
|
|
296
349
|
program.name("create-open-pages").description("Scaffold and manage open-pages workspaces.").version(version, "-v, --version", "print version").helpOption("-h, --help", "show help").showHelpAfterError(chalk.dim("(run `create-open-pages --help` for usage)"));
|
|
297
350
|
program.command("init", { isDefault: true }).description("Create a new open-pages workspace").argument("[dir]", "target directory", void 0).option("-f, --force", "overwrite non-empty target directory", false).option("-n, --name <name>", "override package name (defaults to folder name)").option("--use-npm", "use npm to install dependencies").option("--use-pnpm", "use pnpm to install dependencies").option("--use-yarn", "use yarn to install dependencies").option("--use-bun", "use bun to install dependencies").option("--no-install", "skip dependency installation").option("--no-git", "skip git init and initial commit").action(async (dir, flags) => {
|
|
298
|
-
|
|
351
|
+
p.intro(`${chalk.inverse.bold(" open-pages ")} ${chalk.dim(`v${version}`)}`);
|
|
352
|
+
try {
|
|
353
|
+
await runInit(dir, flags);
|
|
354
|
+
} catch (err) {
|
|
355
|
+
p.cancel(err instanceof Error ? err.message : String(err));
|
|
356
|
+
process.exit(1);
|
|
357
|
+
}
|
|
299
358
|
});
|
|
300
359
|
await program.parseAsync(argv, { from: "user" });
|
|
301
360
|
}
|
|
302
|
-
|
|
303
361
|
//#endregion
|
|
304
362
|
//#region src/cli.ts
|
|
305
363
|
run(process.argv.slice(2)).catch((err) => {
|
|
306
364
|
const message = err instanceof Error ? err.message : String(err);
|
|
307
|
-
process.stderr.write(
|
|
365
|
+
process.stderr.write(`\n ${chalk.red(S_ERROR)} ${message}\n`);
|
|
308
366
|
process.exit(1);
|
|
309
367
|
});
|
|
310
|
-
|
|
311
|
-
|
|
368
|
+
//#endregion
|
|
369
|
+
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@autono/create-open-pages",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0",
|
|
4
4
|
"description": "Scaffold an open-pages workspace — agent skills preconfigured, live real-PDF preview out of the box.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
"prepack": "pnpm build"
|
|
19
19
|
},
|
|
20
20
|
"engines": {
|
|
21
|
-
"node": ">=
|
|
21
|
+
"node": "^20.19.0 || >=22.12.0"
|
|
22
22
|
},
|
|
23
23
|
"keywords": [
|
|
24
24
|
"pdf",
|
|
@@ -45,14 +45,13 @@
|
|
|
45
45
|
"access": "public"
|
|
46
46
|
},
|
|
47
47
|
"dependencies": {
|
|
48
|
+
"@clack/prompts": "^1.7.0",
|
|
48
49
|
"chalk": "^6.0.0",
|
|
49
|
-
"commander": "^15.0.0"
|
|
50
|
-
"prompts": "^2.4.2"
|
|
50
|
+
"commander": "^15.0.0"
|
|
51
51
|
},
|
|
52
52
|
"devDependencies": {
|
|
53
|
-
"@types/node": "^
|
|
54
|
-
"
|
|
55
|
-
"
|
|
56
|
-
"typescript": "^5.9.3"
|
|
53
|
+
"@types/node": "^26.6.2",
|
|
54
|
+
"tsdown": "^0.23.0",
|
|
55
|
+
"typescript": "^7.0.2"
|
|
57
56
|
}
|
|
58
57
|
}
|
package/template/README.md
CHANGED
|
@@ -31,7 +31,8 @@ Then open `http://localhost:5173`, edit `pages/getting-started/index.tsx`, or cr
|
|
|
31
31
|
| `npm run export` | Build pages into `export/<id>/`, one deployable folder per page. |
|
|
32
32
|
| `npm run preview` | Preview the built workspace locally. |
|
|
33
33
|
| `npm run sync:skills` | Sync the bundled agent skills into the workspace. |
|
|
34
|
-
| `
|
|
34
|
+
| `npx open-pages sync:ui` | Update `ui/`, `lib/`, and `hooks/` to the installed runtime's set; files you edited are kept (`--force` to overwrite). |
|
|
35
|
+
| `npm run update` | Update `@autono/open-pages` and sync skills and UI. |
|
|
35
36
|
|
|
36
37
|
## Authoring a page
|
|
37
38
|
|
package/template/netlify.toml
CHANGED
package/template/package.json
CHANGED
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"react-dom": "^19.2.0",
|
|
18
18
|
"@base-ui/react": "^1.7.0",
|
|
19
19
|
"@fontsource-variable/geist": "^5.3.0",
|
|
20
|
-
"@shadcn/react": "^0.3.
|
|
20
|
+
"@shadcn/react": "^0.3.1",
|
|
21
21
|
"class-variance-authority": "^0.7.1",
|
|
22
22
|
"clsx": "^2.1.1",
|
|
23
23
|
"cmdk": "^1.1.1",
|
|
@@ -39,7 +39,6 @@
|
|
|
39
39
|
"devDependencies": {
|
|
40
40
|
"@types/react": "^19.2.0",
|
|
41
41
|
"@types/react-dom": "^19.2.0",
|
|
42
|
-
"vite": "^6.4.3",
|
|
43
42
|
"tailwindcss": "^4.3.3",
|
|
44
43
|
"typescript": "^5.9.3"
|
|
45
44
|
}
|