create-specglass 0.0.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/dist/app.d.ts ADDED
@@ -0,0 +1,6 @@
1
+ interface CreateAppProps {
2
+ initialProjectName?: string;
3
+ }
4
+ export declare function CreateApp({ initialProjectName }: CreateAppProps): import("react/jsx-runtime").JSX.Element;
5
+ export {};
6
+ //# sourceMappingURL=app.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../src/app.tsx"],"names":[],"mappings":"AAUA,UAAU,cAAc;IACtB,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,wBAAgB,SAAS,CAAC,EAAE,kBAAkB,EAAE,EAAE,cAAc,2CAgG/D"}
package/dist/app.js ADDED
@@ -0,0 +1,54 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useState, useEffect } from "react";
3
+ import { Box, Text } from "ink";
4
+ import { TextInput, Spinner, StatusMessage } from "@inkjs/ui";
5
+ import { scaffoldProject, ScaffoldError } from "./scaffold.js";
6
+ import { resolve } from "node:path";
7
+ const DEFAULT_PROJECT_NAME = "my-docs";
8
+ export function CreateApp({ initialProjectName }) {
9
+ const [phase, setPhase] = useState(initialProjectName ? "scaffolding" : "prompting");
10
+ const [projectName, setProjectName] = useState(initialProjectName ?? "");
11
+ const [error, setError] = useState(null);
12
+ useEffect(() => {
13
+ if (initialProjectName) {
14
+ runScaffold(initialProjectName);
15
+ }
16
+ }, [initialProjectName]);
17
+ async function runScaffold(name) {
18
+ setPhase("scaffolding");
19
+ try {
20
+ const targetDir = resolve(process.cwd(), name);
21
+ await scaffoldProject(name, targetDir);
22
+ setPhase("done");
23
+ setTimeout(() => process.exit(0), 100);
24
+ }
25
+ catch (err) {
26
+ if (err instanceof ScaffoldError) {
27
+ setError(err);
28
+ }
29
+ else {
30
+ setError(new ScaffoldError(err instanceof Error ? err.message : String(err), "SCAFFOLD_FAILED", "Check filesystem permissions and try again."));
31
+ }
32
+ setPhase("error");
33
+ setTimeout(() => process.exit(1), 100);
34
+ }
35
+ }
36
+ function handleSubmit(value) {
37
+ const name = value.trim() || DEFAULT_PROJECT_NAME;
38
+ setProjectName(name);
39
+ runScaffold(name);
40
+ }
41
+ if (phase === "prompting") {
42
+ return (_jsxs(Box, { flexDirection: "column", paddingX: 1, children: [_jsx(Box, { marginBottom: 1, children: _jsx(Text, { bold: true, children: "create-specglass" }) }), _jsxs(Box, { children: [_jsx(Text, { children: "Project name: " }), _jsx(TextInput, { placeholder: DEFAULT_PROJECT_NAME, onSubmit: handleSubmit })] })] }));
43
+ }
44
+ if (phase === "scaffolding") {
45
+ return (_jsx(Box, { paddingX: 1, children: _jsx(Spinner, { label: `Scaffolding ${projectName || initialProjectName}...` }) }));
46
+ }
47
+ if (phase === "error" && error) {
48
+ return (_jsxs(Box, { flexDirection: "column", paddingX: 1, children: [_jsx(StatusMessage, { variant: "error", children: error.message }), error.hint && (_jsxs(Text, { dimColor: true, children: ["Hint: ", error.hint] }))] }));
49
+ }
50
+ // done
51
+ const displayName = projectName || initialProjectName || DEFAULT_PROJECT_NAME;
52
+ return (_jsxs(Box, { flexDirection: "column", paddingX: 1, children: [_jsxs(StatusMessage, { variant: "success", children: ["Project created in ", displayName, "/"] }), _jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsx(Text, { children: "Next steps:" }), _jsxs(Text, { dimColor: true, children: [" cd ", displayName] }), _jsx(Text, { dimColor: true, children: " npm install" }), _jsx(Text, { dimColor: true, children: " npx specglass dev" })] })] }));
53
+ }
54
+ //# sourceMappingURL=app.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app.js","sourceRoot":"","sources":["../src/app.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":""}
package/dist/index.js ADDED
@@ -0,0 +1,23 @@
1
+ #!/usr/bin/env node
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import meow from "meow";
4
+ import { render } from "ink";
5
+ import { CreateApp } from "./app.js";
6
+ process.on("SIGINT", () => process.exit(130));
7
+ const cli = meow(`
8
+ Usage
9
+ $ create-specglass [project-name]
10
+
11
+ Options
12
+ --help Show this help message
13
+ --version Show version number
14
+
15
+ Examples
16
+ $ npx create-specglass
17
+ $ npx create-specglass my-docs
18
+ `, {
19
+ importMeta: import.meta,
20
+ });
21
+ const projectName = cli.input[0];
22
+ render(_jsx(CreateApp, { initialProjectName: projectName }));
23
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":";;AAEA,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,MAAM,EAAE,MAAM,KAAK,CAAC;AAC7B,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAErC,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAE9C,MAAM,GAAG,GAAG,IAAI,CACd;;;;;;;;;;;CAWD,EACC;IACE,UAAU,EAAE,MAAM,CAAC,IAAI;CACxB,CACF,CAAC;AAEF,MAAM,WAAW,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAEjC,MAAM,CAAC,KAAC,SAAS,IAAC,kBAAkB,EAAE,WAAW,GAAI,CAAC,CAAC"}
@@ -0,0 +1,8 @@
1
+ export declare class ScaffoldError extends Error {
2
+ readonly code: string;
3
+ readonly hint?: string | undefined;
4
+ constructor(message: string, code: string, hint?: string | undefined);
5
+ }
6
+ export declare function scaffoldProject(projectName: string, targetDir: string): Promise<void>;
7
+ export declare function resolveTemplateDir(): string;
8
+ //# sourceMappingURL=scaffold.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scaffold.d.ts","sourceRoot":"","sources":["../src/scaffold.ts"],"names":[],"mappings":"AAIA,qBAAa,aAAc,SAAQ,KAAK;aAGpB,IAAI,EAAE,MAAM;aACZ,IAAI,CAAC,EAAE,MAAM;gBAF7B,OAAO,EAAE,MAAM,EACC,IAAI,EAAE,MAAM,EACZ,IAAI,CAAC,EAAE,MAAM,YAAA;CAKhC;AAUD,wBAAsB,eAAe,CACnC,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,IAAI,CAAC,CA4Bf;AAiCD,wBAAgB,kBAAkB,IAAI,MAAM,CAE3C"}
@@ -0,0 +1,67 @@
1
+ import { mkdir, readdir, readFile, writeFile, access, cp } from "node:fs/promises";
2
+ import { join, resolve } from "node:path";
3
+ import { fileURLToPath } from "node:url";
4
+ export class ScaffoldError extends Error {
5
+ code;
6
+ hint;
7
+ constructor(message, code, hint) {
8
+ super(message);
9
+ this.code = code;
10
+ this.hint = hint;
11
+ this.name = "ScaffoldError";
12
+ }
13
+ }
14
+ const TEMPLATE_DIR = resolve(fileURLToPath(new URL(".", import.meta.url)), "..", "src", "templates", "default");
15
+ export async function scaffoldProject(projectName, targetDir) {
16
+ // Check if target directory already exists
17
+ try {
18
+ await access(targetDir);
19
+ throw new ScaffoldError(`Directory "${projectName}" already exists`, "PROJECT_EXISTS", `Choose a different project name or remove the existing directory.`);
20
+ }
21
+ catch (err) {
22
+ if (err instanceof ScaffoldError)
23
+ throw err;
24
+ // Directory doesn't exist — good, continue
25
+ }
26
+ // Create target directory
27
+ await mkdir(targetDir, { recursive: true });
28
+ // Copy and process all template files
29
+ try {
30
+ await copyTemplateDir(TEMPLATE_DIR, targetDir, { projectName });
31
+ }
32
+ catch (err) {
33
+ if (err instanceof ScaffoldError)
34
+ throw err;
35
+ throw new ScaffoldError(`Failed to scaffold project: ${err instanceof Error ? err.message : String(err)}`, "SCAFFOLD_FAILED", "Check filesystem permissions and try again.");
36
+ }
37
+ }
38
+ async function copyTemplateDir(srcDir, destDir, vars) {
39
+ const entries = await readdir(srcDir, { withFileTypes: true });
40
+ for (const entry of entries) {
41
+ const srcPath = join(srcDir, entry.name);
42
+ const destName = entry.name.endsWith(".tmpl")
43
+ ? entry.name.slice(0, -5)
44
+ : entry.name;
45
+ const destPath = join(destDir, destName);
46
+ if (entry.isDirectory()) {
47
+ await mkdir(destPath, { recursive: true });
48
+ await copyTemplateDir(srcPath, destPath, vars);
49
+ }
50
+ else if (entry.name.endsWith(".tmpl")) {
51
+ // Template file — read, substitute, write
52
+ let content = await readFile(srcPath, "utf-8");
53
+ for (const [key, value] of Object.entries(vars)) {
54
+ content = content.replaceAll(`{{${key}}}`, value);
55
+ }
56
+ await writeFile(destPath, content, "utf-8");
57
+ }
58
+ else {
59
+ // Static file — copy as-is
60
+ await cp(srcPath, destPath);
61
+ }
62
+ }
63
+ }
64
+ export function resolveTemplateDir() {
65
+ return TEMPLATE_DIR;
66
+ }
67
+ //# sourceMappingURL=scaffold.js.map
@@ -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-specglass",
3
+ "version": "0.0.2",
4
+ "description": "Scaffolding tool to create a new Specglass documentation project",
5
+ "type": "module",
6
+ "license": "MIT",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "https://github.com/Not-Diamond/ndocs.git",
10
+ "directory": "packages/create-specglass"
11
+ },
12
+ "homepage": "https://github.com/Not-Diamond/ndocs#readme",
13
+ "bin": {
14
+ "create-specglass": "./dist/index.js"
15
+ },
16
+ "exports": {
17
+ ".": {
18
+ "types": "./dist/index.d.ts",
19
+ "import": "./dist/index.js"
20
+ }
21
+ },
22
+ "engines": {
23
+ "node": ">=20"
24
+ },
25
+ "files": [
26
+ "dist",
27
+ "src/templates"
28
+ ],
29
+ "scripts": {
30
+ "build": "tsc",
31
+ "test": "vitest run",
32
+ "lint": "eslint src/"
33
+ },
34
+ "devDependencies": {
35
+ "@types/react": "^19.2.14",
36
+ "ink-testing-library": "^4.0.0",
37
+ "typescript": "^5.5",
38
+ "vitest": "^3.0"
39
+ },
40
+ "dependencies": {
41
+ "@inkjs/ui": "^2.0.0",
42
+ "ink": "^6.7.0",
43
+ "meow": "^13.2.0",
44
+ "react": "^19.2.4"
45
+ }
46
+ }
@@ -0,0 +1,4 @@
1
+ {
2
+ "index": "Welcome",
3
+ "getting-started": "Getting Started"
4
+ }
@@ -0,0 +1,87 @@
1
+ ---
2
+ title: Getting Started
3
+ description: Learn how to add content, configure your site, and deploy
4
+ ---
5
+
6
+ # Getting Started
7
+
8
+ This guide walks you through the basics of working with your specglass site.
9
+
10
+ ## Adding a page
11
+
12
+ Create a new `.mdx` file in the `content/docs/` directory:
13
+
14
+ ```mdx
15
+ ---
16
+ title: My New Page
17
+ description: A brief description for search and metadata
18
+ ---
19
+
20
+ # My New Page
21
+
22
+ Write your content here using Markdown.
23
+ ```
24
+
25
+ Every page needs **frontmatter** — the `title` and `description` between the `---` fences. These are used for the page title, navigation labels, and metadata.
26
+
27
+ ## Organizing navigation
28
+
29
+ The `_meta.json` file in each directory controls the order and labels of pages in the sidebar:
30
+
31
+ ```json
32
+ {
33
+ "index": "Welcome",
34
+ "getting-started": "Getting Started",
35
+ "my-new-page": "My New Page"
36
+ }
37
+ ```
38
+
39
+ Keys match filenames (without `.mdx`), and values are the display labels.
40
+
41
+ ## Using components
42
+
43
+ specglass includes built-in components you can use in any MDX page:
44
+
45
+ <Callout type="tip">
46
+ Components like this `Callout` are available globally — no imports needed.
47
+ </Callout>
48
+
49
+ <Callout type="warning">
50
+ Callout types include `info`, `tip`, `warning`, and `error`.
51
+ </Callout>
52
+
53
+ ## Configuring your site
54
+
55
+ Edit `specglass.config.ts` to change your site's title, description, and other settings:
56
+
57
+ ```ts
58
+ import { defineConfig } from "@specglass/core";
59
+
60
+ export default defineConfig({
61
+ site: {
62
+ title: "My Project Docs",
63
+ description: "Documentation for my project",
64
+ },
65
+ });
66
+ ```
67
+
68
+ ## Development workflow
69
+
70
+ ```bash
71
+ # Start dev server with hot reload
72
+ npm run dev
73
+
74
+ # Build static site for production
75
+ npm run build
76
+ ```
77
+
78
+ The dev server runs at `http://localhost:4321` by default. Changes to MDX files are reflected immediately.
79
+
80
+ ## Deploying
81
+
82
+ Running `npm run build` generates a static site in the `dist/` directory. Deploy it to any static hosting provider:
83
+
84
+ - **Vercel** — drop the `dist/` folder or connect your repository
85
+ - **Netlify** — set build command to `npm run build` and publish directory to `dist`
86
+ - **GitHub Pages** — use a CI workflow to build and deploy the `dist/` folder
87
+ - **Any web server** — upload the contents of `dist/`
@@ -0,0 +1,36 @@
1
+ ---
2
+ title: Welcome
3
+ description: Get started with your new documentation site
4
+ ---
5
+
6
+ # Welcome to your docs
7
+
8
+ You're looking at your brand-new documentation site, powered by **specglass**. This page — and everything in the `content/docs/` directory — is written in [MDX](https://mdxjs.com/), a format that combines Markdown with JSX components.
9
+
10
+ <Callout type="info">
11
+ This starter content is your documentation _about_ documentation. Edit these files to replace them with your own content, or use them as a reference while you get started.
12
+ </Callout>
13
+
14
+ ## What you can do
15
+
16
+ - **Write pages** in MDX with full Markdown support plus components
17
+ - **Organize navigation** using `_meta.json` files in each directory
18
+ - **Use built-in components** like `<Callout>` to add visual emphasis
19
+ - **Preview changes** instantly with `npm run dev`
20
+ - **Build for production** with `npm run build` to generate static HTML
21
+
22
+ ## Project structure
23
+
24
+ ```
25
+ content/
26
+ docs/
27
+ index.mdx ← You are here
28
+ getting-started.mdx ← Next steps
29
+ _meta.json ← Navigation order
30
+ specglass.config.ts ← Site configuration
31
+ package.json
32
+ ```
33
+
34
+ ## Next steps
35
+
36
+ Head to the [Getting Started](/docs/getting-started) guide to learn how to add pages, configure your site, and deploy.
@@ -0,0 +1,15 @@
1
+ {
2
+ "name": "{{projectName}}",
3
+ "version": "0.1.0",
4
+ "private": true,
5
+ "type": "module",
6
+ "scripts": {
7
+ "dev": "specglass dev",
8
+ "build": "specglass build"
9
+ },
10
+ "dependencies": {
11
+ "@specglass/cli": "^0.0.1",
12
+ "@specglass/core": "^0.0.1",
13
+ "@specglass/theme-default": "^0.0.1"
14
+ }
15
+ }
@@ -0,0 +1,8 @@
1
+ import { defineConfig } from "@specglass/core";
2
+
3
+ export default defineConfig({
4
+ site: {
5
+ title: "{{projectName}}",
6
+ description: "Documentation powered by specglass",
7
+ },
8
+ });
@@ -0,0 +1,14 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "module": "ESNext",
5
+ "moduleResolution": "bundler",
6
+ "strict": true,
7
+ "esModuleInterop": true,
8
+ "skipLibCheck": true,
9
+ "forceConsistentCasingInFileNames": true,
10
+ "resolveJsonModule": true,
11
+ "isolatedModules": true
12
+ },
13
+ "include": ["specglass.config.ts"]
14
+ }