create-bascik 1.0.0-rc.1

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.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scaffold.js","sourceRoot":"","sources":["../src/scaffold.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,46 @@
1
+ {
2
+ "name": "create-bascik",
3
+ "description": "Create a new Bascik project",
4
+ "version": "1.0.0-rc.1",
5
+ "repository": {
6
+ "type": "git",
7
+ "url": "git+https://github.com/bascikdev/bascik.git",
8
+ "directory": "create"
9
+ },
10
+ "license": "MIT",
11
+ "homepage": "https://bascik.dev",
12
+ "author": "Collin Thomas",
13
+ "type": "module",
14
+ "files": [
15
+ "assets/",
16
+ "dist/",
17
+ "src/",
18
+ "README.md"
19
+ ],
20
+ "bin": "dist/index.js",
21
+ "engines": {
22
+ "node": ">=22.18.0"
23
+ },
24
+ "publishConfig": {
25
+ "access": "public"
26
+ },
27
+ "devDependencies": {
28
+ "@types/node": "^24.0.0",
29
+ "@vitest/coverage-v8": "^4.1.10",
30
+ "typescript": "^7.0.2",
31
+ "vite": "^8.1.5",
32
+ "vitest": "^4.1.10"
33
+ },
34
+ "scripts": {
35
+ "build": "tsc -p tsconfig.build.json",
36
+ "prepare": "mkdir -p assets && ([ -f ../docs/src/pages/assets/SKILL.md ] && cp ../docs/src/pages/assets/SKILL.md assets/SKILL.md || true) && tsc -p tsconfig.build.json",
37
+ "prepack": "mkdir -p assets && cp ../docs/src/pages/assets/SKILL.md assets/SKILL.md",
38
+ "typecheck": "tsc --noEmit",
39
+ "unit": "vitest run",
40
+ "test": "vitest",
41
+ "test:ci": "vitest run",
42
+ "coverage": "vitest run --coverage.enabled && node bin/update-coverage.ts",
43
+ "cover": "yarn coverage",
44
+ "update-coverage": "vitest run --coverage.enabled && node bin/update-coverage.ts"
45
+ }
46
+ }
package/src/cli.ts ADDED
@@ -0,0 +1,11 @@
1
+ export interface CliOptions {
2
+ yesFlag: boolean;
3
+ noDevFlag: boolean;
4
+ }
5
+
6
+ export function parseCliOptions(args: string[]): CliOptions {
7
+ return {
8
+ yesFlag: args.includes("-y") || args.includes("--yes"),
9
+ noDevFlag: args.includes("--no-dev"),
10
+ };
11
+ }
package/src/index.ts ADDED
@@ -0,0 +1,66 @@
1
+ #!/usr/bin/env node
2
+ import { createInterface } from "node:readline/promises";
3
+ import { spawnSync } from "node:child_process";
4
+ import { join } from "node:path";
5
+ import { parseCliOptions } from "./cli.js";
6
+ import { scaffold, validateProjectName } from "./scaffold.js";
7
+
8
+ const args = process.argv.slice(2);
9
+ const { yesFlag, noDevFlag } = parseCliOptions(args);
10
+ const nameArg = args.find((a) => !a.startsWith("-"));
11
+
12
+ const rl = createInterface({ input: process.stdin, output: process.stdout });
13
+
14
+ let projectName: string;
15
+
16
+ if (nameArg) {
17
+ projectName = nameArg;
18
+ } else {
19
+ const answer = await rl.question("Project name (bascik-app): ");
20
+ projectName = answer.trim() || "bascik-app";
21
+ }
22
+
23
+ const error = validateProjectName(projectName);
24
+ if (error) {
25
+ rl.close();
26
+ console.error(`\nError: ${error}\n`);
27
+ process.exit(1);
28
+ }
29
+
30
+ console.log(`\nCreating Bascik project "${projectName}"…\n`);
31
+ await scaffold(projectName);
32
+ console.log(`✓ Scaffolded ${projectName}/\n`);
33
+
34
+ let shouldInstall: boolean;
35
+ let shouldDev: boolean;
36
+
37
+ if (yesFlag) {
38
+ shouldInstall = true;
39
+ shouldDev = !noDevFlag;
40
+ } else {
41
+ const installAnswer = await rl.question("Install dependencies now? (Y/n) ");
42
+ shouldInstall = installAnswer.trim().toLowerCase() !== "n";
43
+ const devAnswer = await rl.question("Start the dev server after install? (Y/n) ");
44
+ shouldDev = devAnswer.trim().toLowerCase() !== "n";
45
+ }
46
+
47
+ rl.close();
48
+
49
+ const projectDir = join(process.cwd(), projectName);
50
+ const npmCmd = process.platform === "win32" ? "npm.cmd" : "npm";
51
+
52
+ if (shouldInstall) {
53
+ console.log("\nInstalling dependencies…\n");
54
+ spawnSync(npmCmd, ["install"], { cwd: projectDir, stdio: "inherit" });
55
+ }
56
+
57
+ if (shouldDev) {
58
+ console.log("\nStarting dev server…\n");
59
+ spawnSync(npmCmd, ["run", "dev"], { cwd: projectDir, stdio: "inherit" });
60
+ console.log(`\nTo start again: cd ${projectName} && npm run dev\n`);
61
+ } else {
62
+ console.log("\nNext steps:\n");
63
+ if (!shouldInstall) console.log(` cd ${projectName}`);
64
+ if (!shouldInstall) console.log(" npm install");
65
+ console.log(" npm run dev\n");
66
+ }
@@ -0,0 +1,210 @@
1
+ /**
2
+ * scaffold.integration.test.ts
3
+ *
4
+ * Real scaffold-to-compiler integration test.
5
+ *
6
+ * Boundary tested:
7
+ * Real filesystem I/O -> `scaffold(projectName, parentDir)` -> Real Bascik CLI child process compilation.
8
+ *
9
+ * Collaborators:
10
+ * - Real filesystem (`mkdtemp`, `scaffold`, `readFile`, `rm`).
11
+ * - Real Bascik compiler invoked via child process (`node <pkg>/bin/bascik.js --build`).
12
+ * - Real asset copying, component expansion, build-script execution, and HTML publication.
13
+ *
14
+ * Contract asserted:
15
+ * 1. Default scaffolded site compiles successfully with exit code 0.
16
+ * 2. Emitted output contains all 4 pages (`index.html`, `about.html`, `contact.html`, `404.html`).
17
+ * 3. Component expansion occurs (e.g. `<header class="header">`, `<footer class="footer">`, `<my-counter>`).
18
+ * 4. Build scripts execute at build time (e.g. copyright year in site footer).
19
+ * 5. Static assets and favicons are preserved and copied to dist/.
20
+ * 6. Scaffolding copied the real SKILL.md asset into `.github/skills/bascik/SKILL.md` and `.claude/skills/bascik/SKILL.md`.
21
+ * 7. Negative-control sensitivity: A corrupted scaffolded page (invalid syntax / broken component) is rejected by the compiler.
22
+ * 8. Execution mode parity: Verified across both default and worker build pipelines.
23
+ */
24
+
25
+ import { describe, it, expect, afterEach, beforeAll } from "vitest";
26
+ import { mkdtemp, readFile, writeFile, rm, access } from "node:fs/promises";
27
+ import { existsSync } from "node:fs";
28
+ import { tmpdir } from "node:os";
29
+ import { join, resolve } from "node:path";
30
+ import { execFile } from "node:child_process";
31
+ import { promisify } from "node:util";
32
+ import { fileURLToPath } from "node:url";
33
+ import { scaffold } from "./scaffold.ts";
34
+
35
+ const execFileAsync = promisify(execFile);
36
+
37
+ // Resolve package CLI binary path and dist entry point
38
+ const PKG_CLI = resolve(
39
+ fileURLToPath(import.meta.url),
40
+ "../../../pkg/bin/bascik.js",
41
+ );
42
+ const PKG_DIST_INDEX = resolve(
43
+ fileURLToPath(import.meta.url),
44
+ "../../../pkg/dist/index.js",
45
+ );
46
+
47
+ const tempDirs: string[] = [];
48
+
49
+ afterEach(async () => {
50
+ await Promise.all(
51
+ tempDirs.splice(0).map((dir) => rm(dir, { recursive: true, force: true })),
52
+ );
53
+ });
54
+
55
+ async function createTempDir(prefix: string): Promise<string> {
56
+ const dir = await mkdtemp(join(tmpdir(), `bascik-scaffold-test-${prefix}-`));
57
+ tempDirs.push(dir);
58
+ return dir;
59
+ }
60
+
61
+ interface BuildResult {
62
+ stdout: string;
63
+ stderr: string;
64
+ exitCode: number;
65
+ }
66
+
67
+ async function runBascikBuild(projectDir: string, extraArgs: string[] = []): Promise<BuildResult> {
68
+ try {
69
+ const { stdout, stderr } = await execFileAsync(
70
+ process.execPath,
71
+ [PKG_CLI, "--build", ...extraArgs],
72
+ {
73
+ cwd: projectDir,
74
+ encoding: "utf8",
75
+ env: {
76
+ ...process.env,
77
+ NODE_ENV: "production",
78
+ BASCIK_SITE_URL: "https://example.com",
79
+ },
80
+ timeout: 30_000,
81
+ },
82
+ );
83
+ return { stdout, stderr, exitCode: 0 };
84
+ } catch (err: unknown) {
85
+ const execErr = err as { stdout?: string; stderr?: string; code?: number };
86
+ return {
87
+ stdout: execErr.stdout ?? "",
88
+ stderr: execErr.stderr ?? "",
89
+ exitCode: typeof execErr.code === "number" ? execErr.code : 1,
90
+ };
91
+ }
92
+ }
93
+
94
+ describe("scaffold-to-compiler integration", () => {
95
+ beforeAll(() => {
96
+ if (!existsSync(PKG_DIST_INDEX)) {
97
+ throw new Error(
98
+ `[scaffold.integration.test] Required artifact missing: ${PKG_DIST_INDEX}. ` +
99
+ "Run `yarn pkg:build` before running create-bascik integration tests.",
100
+ );
101
+ }
102
+ });
103
+
104
+ it("scaffolds and compiles a new project with real compiler and full artifact verification", async () => {
105
+ const parentDir = await createTempDir("default");
106
+ const projectName = "test-site";
107
+ const projectDir = join(parentDir, projectName);
108
+
109
+ // 1. Run real scaffold
110
+ await scaffold(projectName, parentDir);
111
+
112
+ // Verify SKILL.md was copied from real assets
113
+ const githubSkill = await readFile(join(projectDir, ".github/skills/bascik/SKILL.md"), "utf8");
114
+ const claudeSkill = await readFile(join(projectDir, ".claude/skills/bascik/SKILL.md"), "utf8");
115
+ expect(githubSkill.length).toBeGreaterThan(100);
116
+ expect(claudeSkill).toBe(githubSkill);
117
+
118
+ // 2. Compile via real Bascik CLI child process
119
+ const buildResult = await runBascikBuild(projectDir);
120
+ expect(buildResult.exitCode, `Build failed with stderr: ${buildResult.stderr}`).toBe(0);
121
+ expect(buildResult.stdout).toContain("Build complete");
122
+
123
+ const distDir = join(projectDir, "dist");
124
+
125
+ // 3. Verify all 4 expected pages are emitted
126
+ const indexHtml = await readFile(join(distDir, "index.html"), "utf8");
127
+ const aboutHtml = await readFile(join(distDir, "about.html"), "utf8");
128
+ const contactHtml = await readFile(join(distDir, "contact.html"), "utf8");
129
+ const notFoundHtml = await readFile(join(distDir, "404.html"), "utf8");
130
+
131
+ expect(indexHtml).toContain("<!DOCTYPE html>");
132
+ expect(aboutHtml).toContain("<!DOCTYPE html>");
133
+ expect(contactHtml).toContain("<!DOCTYPE html>");
134
+ expect(notFoundHtml).toContain("<!DOCTYPE html>");
135
+
136
+ // 4. Verify component expansion and props
137
+ // site-header expands to <header with brand prop or site name
138
+ expect(indexHtml).toContain("<header");
139
+ expect(indexHtml).toContain("test-site");
140
+ // my-counter expanded to counter button/UI
141
+ expect(indexHtml).toContain("data-testid=\"counter-inc\"");
142
+ expect(indexHtml).toContain("data-testid=\"counter-dec\"");
143
+
144
+ // 5. Verify build script executed in site-footer (current year)
145
+ const currentYear = String(new Date().getFullYear());
146
+ expect(indexHtml).toContain(`&copy; ${currentYear}`);
147
+ expect(aboutHtml).toContain(`&copy; ${currentYear}`);
148
+
149
+ // 6. Verify representative assets copied to dist
150
+ await expect(access(join(distDir, "favicon.ico"))).resolves.toBeUndefined();
151
+ await expect(access(join(distDir, "assets/favicon.svg"))).resolves.toBeUndefined();
152
+ await expect(access(join(distDir, "assets/favicon-32x32.png"))).resolves.toBeUndefined();
153
+ await expect(access(join(distDir, "assets/apple-touch-icon.png"))).resolves.toBeUndefined();
154
+ await expect(access(join(distDir, "css/styles.css"))).resolves.toBeUndefined();
155
+ }, 45_000);
156
+
157
+ it("compiles scaffolded project with workers enabled in config", async () => {
158
+ const parentDir = await createTempDir("workers");
159
+ const projectName = "worker-site";
160
+ const projectDir = join(parentDir, projectName);
161
+
162
+ await scaffold(projectName, parentDir);
163
+
164
+ // Add workers config to bascik.config.js
165
+ await writeFile(
166
+ join(projectDir, "bascik.config.js"),
167
+ `export default {
168
+ pipeline: { workers: true }
169
+ };
170
+ `,
171
+ "utf8",
172
+ );
173
+
174
+ const buildResult = await runBascikBuild(projectDir);
175
+ expect(buildResult.exitCode, `Worker build failed with stderr: ${buildResult.stderr}`).toBe(0);
176
+ expect(buildResult.stdout).toContain("Build complete");
177
+
178
+ const indexHtml = await readFile(join(projectDir, "dist/index.html"), "utf8");
179
+ const currentYear = String(new Date().getFullYear());
180
+ expect(indexHtml).toContain("<header");
181
+ expect(indexHtml).toContain(`&copy; ${currentYear}`);
182
+ }, 45_000);
183
+
184
+ it("negative control: rejects compilation when a required page contains invalid build-script syntax", async () => {
185
+ const parentDir = await createTempDir("negative-control");
186
+ const projectName = "corrupt-site";
187
+ const projectDir = join(parentDir, projectName);
188
+
189
+ await scaffold(projectName, parentDir);
190
+
191
+ // Inject deliberate build-script syntax error into index.html
192
+ const corruptPage = `<!DOCTYPE html>
193
+ <html>
194
+ <head><title>Corrupt</title></head>
195
+ <body>
196
+ <script data-bascik-build>
197
+ // Deliberate syntax error that fails build-script execution
198
+ const invalid = (;;
199
+ </script>
200
+ </body>
201
+ </html>`;
202
+ await writeFile(join(projectDir, "src/pages/index.html"), corruptPage, "utf8");
203
+
204
+ const buildResult = await runBascikBuild(projectDir);
205
+ expect(buildResult.exitCode).not.toBe(0);
206
+ // Verifier rejected the corrupted page
207
+ const combinedOutput = `${buildResult.stdout}\n${buildResult.stderr}`;
208
+ expect(combinedOutput.toLowerCase()).toMatch(/error|failed|syntaxerror/);
209
+ }, 45_000);
210
+ });