create-bodhi-js 0.1.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 BodhiSearch
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,143 @@
1
+ # create-bodhi-js
2
+
3
+ Scaffold Bodhi-powered applications with React, TypeScript, Vite, Tailwind CSS, shadcn/ui, and comprehensive tooling.
4
+
5
+ ## Usage
6
+
7
+ ```bash
8
+ # Interactive mode
9
+ npm create bodhi-js@latest
10
+
11
+ # With project name
12
+ npm create bodhi-js@latest my-app
13
+
14
+ # With options
15
+ npm create bodhi-js@latest my-app -- --template react --github-pages
16
+ ```
17
+
18
+ ## Features
19
+
20
+ **Core Stack**:
21
+ - ⚡ [Vite 7](https://vite.dev/) - Next generation frontend tooling
22
+ - ⚛️ [React 19](https://react.dev/) - Latest React with modern patterns
23
+ - 📘 [TypeScript](https://www.typescriptlang.org/) - Strict mode enabled
24
+ - 🎨 [Tailwind CSS v4](https://tailwindcss.com/) - Utility-first CSS
25
+ - 🧩 [shadcn/ui](https://ui.shadcn.com/) - Re-usable components
26
+ - 🤖 [bodhi-js-react](https://github.com/BodhiSearch/bodhi-browser) - Local LLM integration
27
+
28
+ **Code Quality**:
29
+ - 🔍 ESLint 9 + Prettier
30
+ - 📝 EditorConfig
31
+ - 🎯 Strict TypeScript
32
+
33
+ **Testing**:
34
+ - ✅ [Vitest](https://vitest.dev/) - Unit testing
35
+ - 🎭 [Playwright](https://playwright.dev/) - E2E testing
36
+
37
+ **CI/CD** (optional):
38
+ - 🔄 GitHub Actions
39
+ - 📦 GitHub Pages deployment
40
+ - 🤖 Dependabot
41
+
42
+ ## Options
43
+
44
+ ```
45
+ Usage: create-bodhi-js [project-name] [options]
46
+
47
+ Arguments:
48
+ project-name Name of the project
49
+
50
+ Options:
51
+ -V, --version output the version number
52
+ -t, --template <name> Template to use (react, svelte, vue) (default: "react")
53
+ --no-install Skip dependency installation
54
+ --no-git Skip git initialization
55
+ --github-pages Enable GitHub Pages deployment setup
56
+ -h, --help display help for command
57
+ ```
58
+
59
+ ## Templates
60
+
61
+ ### Available Templates
62
+
63
+ - **react** - React + TypeScript + Vite + Tailwind + shadcn/ui + bodhi-js-react (default)
64
+
65
+ ### Custom Templates
66
+
67
+ Use any Git repository as a template:
68
+
69
+ ```bash
70
+ npm create bodhi-js@latest my-app -- --template gh:username/my-template
71
+ ```
72
+
73
+ Supported Git providers (via [giget](https://github.com/unjs/giget)):
74
+ - GitHub: `gh:user/repo`
75
+ - GitLab: `gitlab:user/repo`
76
+ - BitBucket: `bitbucket:user/repo`
77
+
78
+ ## What's Included?
79
+
80
+ When you scaffold a project with `create-bodhi-js`, you get:
81
+
82
+ ```
83
+ my-app/
84
+ ├── .github/ # GitHub templates and workflows
85
+ │ ├── workflows/ # CI/CD pipelines
86
+ │ ├── ISSUE_TEMPLATE/ # Issue templates
87
+ │ └── ...
88
+ ├── e2e/ # Playwright E2E tests
89
+ ├── public/ # Static assets
90
+ ├── src/
91
+ │ ├── components/ # React components
92
+ │ │ └── ui/ # shadcn/ui components
93
+ │ ├── hooks/ # Custom React hooks
94
+ │ ├── lib/ # Utility functions
95
+ │ ├── test/ # Test setup
96
+ │ ├── App.tsx # Main app component
97
+ │ ├── main.tsx # Entry point
98
+ │ ├── env.ts # Environment variable validation
99
+ │ └── index.css # Global styles
100
+ ├── .editorconfig # Editor configuration
101
+ ├── .prettierrc # Prettier configuration
102
+ ├── components.json # shadcn/ui configuration
103
+ ├── eslint.config.js # ESLint configuration
104
+ ├── playwright.config.ts # Playwright configuration
105
+ ├── tsconfig.json # TypeScript configuration
106
+ ├── vite.config.ts # Vite configuration
107
+ └── package.json # Dependencies and scripts
108
+ ```
109
+
110
+ ## Post-Installation
111
+
112
+ After scaffolding your project:
113
+
114
+ 1. **Configure environment variables**:
115
+ ```bash
116
+ cp .env.example .env
117
+ # Edit .env with your Bodhi OAuth credentials
118
+ ```
119
+
120
+ 2. **Start development server**:
121
+ ```bash
122
+ npm run dev
123
+ ```
124
+
125
+ 3. **Run tests**:
126
+ ```bash
127
+ npm test # Unit tests
128
+ npm run test:e2e # E2E tests
129
+ ```
130
+
131
+ 4. **Build for production**:
132
+ ```bash
133
+ npm run build
134
+ ```
135
+
136
+ ## License
137
+
138
+ MIT License - see [LICENSE](LICENSE) for details.
139
+
140
+ ## Related
141
+
142
+ - [bodhi-browser](https://github.com/BodhiSearch/bodhi-browser) - Bodhi Browser Extension
143
+ - [template-bodhi-react-vite](https://github.com/BodhiSearch/template-bodhi-react-vite) - React template source
@@ -0,0 +1 @@
1
+ #!/usr/bin/env node
package/dist/index.js ADDED
@@ -0,0 +1,242 @@
1
+ #!/usr/bin/env node
2
+ #!/usr/bin/env node
3
+
4
+ // src/index.ts
5
+ import { Command } from "commander";
6
+
7
+ // src/cli.ts
8
+ import * as p from "@clack/prompts";
9
+ import pc from "picocolors";
10
+
11
+ // src/scaffold.ts
12
+ import { downloadTemplate } from "giget";
13
+ import { promises as fs2 } from "fs";
14
+ import path2 from "path";
15
+
16
+ // src/processor.ts
17
+ import Handlebars from "handlebars";
18
+ import { promises as fs } from "fs";
19
+ import path from "path";
20
+ var TEMPLATE_FILES = [
21
+ "package.json",
22
+ "vite.config.ts",
23
+ "index.html",
24
+ "public/404.html",
25
+ "README.md",
26
+ "playwright.config.ts"
27
+ ];
28
+ async function processTemplates(targetDir, vars) {
29
+ for (const file of TEMPLATE_FILES) {
30
+ const filePath = path.join(targetDir, file);
31
+ try {
32
+ const content = await fs.readFile(filePath, "utf-8");
33
+ const template = Handlebars.compile(content);
34
+ const rendered = template(vars);
35
+ await fs.writeFile(filePath, rendered, "utf-8");
36
+ } catch {
37
+ }
38
+ }
39
+ }
40
+
41
+ // src/scaffold.ts
42
+ import { exec } from "child_process";
43
+ import { promisify } from "util";
44
+ var execAsync = promisify(exec);
45
+ async function scaffold(options) {
46
+ const {
47
+ projectName,
48
+ templateUrl,
49
+ githubOrg,
50
+ githubPages,
51
+ basePath,
52
+ pathSegmentsToKeep,
53
+ install,
54
+ git
55
+ } = options;
56
+ const targetDir = path2.resolve(process.cwd(), projectName);
57
+ try {
58
+ await fs2.access(targetDir);
59
+ throw new Error(`Directory ${projectName} already exists`);
60
+ } catch (err) {
61
+ if (err.code !== "ENOENT") {
62
+ throw err;
63
+ }
64
+ }
65
+ await downloadTemplate(templateUrl, {
66
+ dir: targetDir,
67
+ offline: false
68
+ });
69
+ const templateSubdir = path2.join(targetDir, "template");
70
+ try {
71
+ await fs2.access(templateSubdir);
72
+ const files = await fs2.readdir(templateSubdir);
73
+ for (const file of files) {
74
+ await fs2.rename(path2.join(templateSubdir, file), path2.join(targetDir, file));
75
+ }
76
+ await fs2.rmdir(templateSubdir);
77
+ } catch {
78
+ }
79
+ const dotfiles = ["_gitignore", "_editorconfig", "_prettierrc", "_prettierignore"];
80
+ for (const file of dotfiles) {
81
+ const oldPath = path2.join(targetDir, file);
82
+ const newPath = path2.join(targetDir, file.replace("_", "."));
83
+ try {
84
+ await fs2.rename(oldPath, newPath);
85
+ } catch {
86
+ }
87
+ }
88
+ await processTemplates(targetDir, {
89
+ projectName,
90
+ githubOrg,
91
+ githubPages,
92
+ basePath,
93
+ pathSegmentsToKeep
94
+ });
95
+ if (!githubPages) {
96
+ const filesToDelete = [
97
+ path2.join(targetDir, ".github/workflows/deploy-pages.yml"),
98
+ path2.join(targetDir, "public/404.html")
99
+ ];
100
+ for (const file of filesToDelete) {
101
+ try {
102
+ await fs2.unlink(file);
103
+ } catch {
104
+ }
105
+ }
106
+ }
107
+ const metaFiles = ["template.json", "test-template.sh", "TECH.md"];
108
+ for (const file of metaFiles) {
109
+ try {
110
+ await fs2.unlink(path2.join(targetDir, file));
111
+ } catch {
112
+ }
113
+ }
114
+ if (git) {
115
+ try {
116
+ await execAsync("git init", { cwd: targetDir });
117
+ await execAsync("git add .", { cwd: targetDir });
118
+ await execAsync('git commit -m "chore: initial commit from create-bodhi-js"', {
119
+ cwd: targetDir
120
+ });
121
+ } catch {
122
+ console.warn("Warning: Git initialization failed");
123
+ }
124
+ }
125
+ if (install) {
126
+ await execAsync("npm install", { cwd: targetDir });
127
+ }
128
+ }
129
+
130
+ // src/templates.ts
131
+ var TEMPLATES = {
132
+ react: "gh:BodhiSearch/template-bodhi-react-vite"
133
+ // Future templates
134
+ // svelte: 'gh:BodhiSearch/template-bodhi-svelte-vite',
135
+ // vue: 'gh:BodhiSearch/template-bodhi-vue-vite',
136
+ };
137
+ function resolveTemplate(name) {
138
+ if (TEMPLATES[name]) {
139
+ return TEMPLATES[name];
140
+ }
141
+ if (name.includes(":")) {
142
+ return name;
143
+ }
144
+ throw new Error(
145
+ `Unknown template: ${name}
146
+
147
+ Available templates:
148
+ ${Object.keys(TEMPLATES).map((t) => ` - ${t}`).join("\n")}
149
+
150
+ Or use a custom template: gh:user/repo`
151
+ );
152
+ }
153
+
154
+ // src/cli.ts
155
+ async function create(projectName, options) {
156
+ console.log();
157
+ p.intro(pc.bgCyan(pc.black(" create-bodhi-js ")));
158
+ let targetDir = projectName;
159
+ const template = options.template;
160
+ if (!targetDir) {
161
+ const result = await p.text({
162
+ message: "Project name:",
163
+ placeholder: "my-bodhi-app",
164
+ validate: (value) => {
165
+ if (!value) return "Project name is required";
166
+ if (!/^[a-z0-9-]+$/.test(value)) return "Use lowercase letters, numbers, and hyphens only";
167
+ return void 0;
168
+ }
169
+ });
170
+ if (p.isCancel(result)) {
171
+ p.cancel("Operation cancelled");
172
+ process.exit(0);
173
+ }
174
+ targetDir = result;
175
+ }
176
+ let templateUrl;
177
+ try {
178
+ templateUrl = resolveTemplate(template);
179
+ } catch (error) {
180
+ p.log.error(error.message);
181
+ process.exit(1);
182
+ }
183
+ let enableGithubPages = options.githubPages ?? false;
184
+ if (!options.githubPages) {
185
+ const result = await p.confirm({
186
+ message: "Enable GitHub Pages deployment?",
187
+ initialValue: false
188
+ });
189
+ if (p.isCancel(result)) {
190
+ p.cancel("Operation cancelled");
191
+ process.exit(0);
192
+ }
193
+ enableGithubPages = result;
194
+ }
195
+ let githubOrg = "";
196
+ let basePath = "/";
197
+ let pathSegmentsToKeep = 0;
198
+ if (enableGithubPages) {
199
+ const orgResult = await p.text({
200
+ message: "GitHub organization/username:",
201
+ placeholder: "my-org"
202
+ });
203
+ if (p.isCancel(orgResult)) {
204
+ p.cancel("Operation cancelled");
205
+ process.exit(0);
206
+ }
207
+ githubOrg = orgResult;
208
+ basePath = `/${targetDir}/`;
209
+ pathSegmentsToKeep = 1;
210
+ }
211
+ const spinner2 = p.spinner();
212
+ spinner2.start("Scaffolding project...");
213
+ try {
214
+ await scaffold({
215
+ projectName: targetDir,
216
+ templateUrl,
217
+ githubOrg,
218
+ githubPages: enableGithubPages,
219
+ basePath,
220
+ pathSegmentsToKeep,
221
+ install: options.install,
222
+ git: options.git
223
+ });
224
+ spinner2.stop("Project scaffolded successfully!");
225
+ p.note(
226
+ [`cd ${targetDir}`, !options.install && "npm install", "npm run dev"].filter(Boolean).join("\n"),
227
+ "Next steps"
228
+ );
229
+ p.outro(pc.green("Happy coding! \u{1F680}"));
230
+ } catch (error) {
231
+ spinner2.stop("Failed to scaffold project");
232
+ p.log.error(error.message);
233
+ process.exit(1);
234
+ }
235
+ }
236
+
237
+ // src/index.ts
238
+ var program = new Command();
239
+ program.name("create-bodhi-js").description("Scaffold Bodhi-powered applications").version("0.1.0").argument("[project-name]", "Name of the project").option("-t, --template <name>", "Template to use (react, svelte, vue)", "react").option("--no-install", "Skip dependency installation").option("--no-git", "Skip git initialization").option("--github-pages", "Enable GitHub Pages deployment setup").action(async (projectName, options) => {
240
+ await create(projectName, options);
241
+ });
242
+ program.parse();
package/package.json ADDED
@@ -0,0 +1,70 @@
1
+ {
2
+ "name": "create-bodhi-js",
3
+ "version": "0.1.0",
4
+ "description": "Scaffold Bodhi-powered applications with React, TypeScript, Vite, and more",
5
+ "type": "module",
6
+ "bin": {
7
+ "create-bodhi-js": "./dist/index.js"
8
+ },
9
+ "main": "./dist/index.js",
10
+ "files": [
11
+ "dist",
12
+ "README.md",
13
+ "LICENSE"
14
+ ],
15
+ "scripts": {
16
+ "dev": "tsx src/index.ts",
17
+ "build": "tsup",
18
+ "typecheck": "tsc --noEmit",
19
+ "lint": "eslint . --max-warnings 0",
20
+ "lint:fix": "eslint . --fix",
21
+ "check": "npm run lint && npm run typecheck",
22
+ "check:fix": "npm run lint:fix && npm run typecheck",
23
+ "test": "echo \"Tests coming soon\" && exit 0",
24
+ "prepublishOnly": "npm run build"
25
+ },
26
+ "keywords": [
27
+ "create-bodhi-js",
28
+ "bodhi",
29
+ "bodhi-js",
30
+ "react",
31
+ "vite",
32
+ "typescript",
33
+ "template",
34
+ "scaffolding",
35
+ "cli"
36
+ ],
37
+ "author": "BodhiSearch",
38
+ "license": "MIT",
39
+ "repository": {
40
+ "type": "git",
41
+ "url": "git+https://github.com/BodhiSearch/create-bodhi-js.git"
42
+ },
43
+ "bugs": {
44
+ "url": "https://github.com/BodhiSearch/create-bodhi-js/issues"
45
+ },
46
+ "homepage": "https://github.com/BodhiSearch/create-bodhi-js#readme",
47
+ "dependencies": {
48
+ "@clack/prompts": "^0.11.0",
49
+ "commander": "^14.0.2",
50
+ "giget": "^2.0.0",
51
+ "handlebars": "^4.7.8",
52
+ "picocolors": "^1.1.1"
53
+ },
54
+ "devDependencies": {
55
+ "@eslint/js": "^9.39.1",
56
+ "@types/node": "^25.0.3",
57
+ "eslint": "^9.39.1",
58
+ "eslint-config-prettier": "^10.1.8",
59
+ "eslint-plugin-prettier": "^5.5.4",
60
+ "globals": "^17.0.0",
61
+ "prettier": "^3.7.4",
62
+ "tsup": "^8.5.0",
63
+ "tsx": "^4.19.2",
64
+ "typescript": "^5.9.3",
65
+ "typescript-eslint": "^8.46.4"
66
+ },
67
+ "engines": {
68
+ "node": ">=18.0.0"
69
+ }
70
+ }