create-craft 0.0.37

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.md ADDED
@@ -0,0 +1,21 @@
1
+ # MIT License
2
+
3
+ Copyright (c) 2025 Stacks.js
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
Binary file
package/bin/cli.ts ADDED
@@ -0,0 +1,718 @@
1
+ #!/usr/bin/env bun
2
+
3
+ /**
4
+ * create-craft - Scaffold a new Craft desktop app project
5
+ */
6
+
7
+ import { CLI } from '@stacksjs/clapp'
8
+ import { spawn } from 'node:child_process'
9
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs'
10
+ import { join, resolve } from 'node:path'
11
+ import process from 'node:process'
12
+
13
+ // Read the current version from the package's own package.json (which stays in sync via bumpx --recursive)
14
+ const craftVersion = JSON.parse(readFileSync(new URL('../package.json', import.meta.url), 'utf-8')).version
15
+
16
+ const cli = new CLI('create-craft')
17
+
18
+ /**
19
+ * Validate a project name against npm's package-name rules so the generated
20
+ * package.json is always parseable by npm/bun and free of shell metacharacters
21
+ * that could leak into commands like `bun install <name>`.
22
+ *
23
+ * Rules (subset of validate-npm-package-name):
24
+ * - 1..214 characters
25
+ * - lowercase letters, digits, and `-`, `_`, `.`
26
+ * - must start with letter or digit (no leading dot/underscore)
27
+ * - no whitespace, slashes, or path separators
28
+ */
29
+ function validateProjectName(name: string): void {
30
+ if (typeof name !== 'string' || name.length === 0) {
31
+ throw new Error('Project name must be a non-empty string')
32
+ }
33
+ if (name.length > 214) {
34
+ throw new Error('Project name must be 214 characters or fewer')
35
+ }
36
+ if (!/^[a-z0-9][a-z0-9._-]*$/.test(name)) {
37
+ throw new Error(
38
+ `Invalid project name "${name}". `
39
+ + 'Use lowercase letters, digits, dot, underscore, and dash only; must start with a letter or digit.',
40
+ )
41
+ }
42
+ }
43
+
44
+ // Default command - create a new project
45
+ cli
46
+ .command('[project-name]', 'Create a new Craft desktop app')
47
+ .option('--template <template>', 'Template to use', { default: 'minimal' })
48
+ .option('--skip-install', 'Skip installing dependencies', { default: false })
49
+ .example('create-craft my-app')
50
+ .example('create-craft my-app --template full-featured')
51
+ .example('bun create craft my-app')
52
+ .action(async (projectName?: string, options?: any) => {
53
+ if (!projectName) {
54
+ console.error('Error: Project name is required')
55
+ console.log('\nUsage: create-craft <project-name>')
56
+ console.log('Example: create-craft my-app')
57
+ process.exit(1)
58
+ }
59
+
60
+ try {
61
+ validateProjectName(projectName)
62
+ }
63
+ catch (e) {
64
+ console.error(`Error: ${(e as Error).message}`)
65
+ process.exit(2)
66
+ }
67
+
68
+ const template = options?.template || 'minimal'
69
+ const skipInstall = options?.skipInstall || false
70
+
71
+ console.log(`\n✨ Creating a new Craft app: ${projectName}`)
72
+ console.log(`📦 Template: ${template}\n`)
73
+
74
+ const projectPath = resolve(process.cwd(), projectName)
75
+
76
+ // Check if directory already exists
77
+ if (existsSync(projectPath)) {
78
+ console.error(`Error: Directory "${projectName}" already exists`)
79
+ process.exit(1)
80
+ }
81
+
82
+ // Create project directory
83
+ mkdirSync(projectPath, { recursive: true })
84
+
85
+ // Generate project based on template
86
+ if (template === 'minimal') {
87
+ createMinimalTemplate(projectPath, projectName)
88
+ }
89
+ else if (template === 'full-featured') {
90
+ createFullFeaturedTemplate(projectPath, projectName)
91
+ }
92
+ else if (template === 'todo-app') {
93
+ createTodoAppTemplate(projectPath, projectName)
94
+ }
95
+ else {
96
+ console.error(`Error: Unknown template "${template}"`)
97
+ console.log('\nAvailable templates: minimal, full-featured, todo-app')
98
+ process.exit(1)
99
+ }
100
+
101
+ // Install dependencies unless skipped
102
+ if (!skipInstall) {
103
+ console.log('\n📦 Installing dependencies...\n')
104
+ await installDependencies(projectPath)
105
+ }
106
+
107
+ // Success message
108
+ console.log('\n✅ Project created successfully!\n')
109
+ console.log('Next steps:')
110
+ console.log(` cd ${projectName}`)
111
+ if (skipInstall) {
112
+ console.log(' bun install')
113
+ }
114
+ console.log(' bun run dev\n')
115
+ })
116
+
117
+ // List available templates
118
+ cli
119
+ .command('list', 'List available templates')
120
+ .action(() => {
121
+ console.log('\n📋 Available templates:\n')
122
+ console.log(' minimal - Simplest possible Craft app')
123
+ console.log(' full-featured - Modern styled app with examples')
124
+ console.log(' todo-app - Interactive todo list application\n')
125
+ })
126
+
127
+ cli.version(craftVersion)
128
+ cli.help()
129
+ cli.parse()
130
+
131
+ // Template generators
132
+
133
+ function createMinimalTemplate(projectPath: string, projectName: string): void {
134
+ console.log('📝 Generating minimal template...')
135
+
136
+ // Create package.json
137
+ const packageJson = {
138
+ name: projectName,
139
+ version: '0.0.1',
140
+ type: 'module',
141
+ private: true,
142
+ scripts: {
143
+ doctor: 'craft --version',
144
+ dev: 'bun run src/index.ts',
145
+ build: 'bun build src/index.ts --outdir dist --target bun',
146
+ },
147
+ dependencies: {
148
+ 'craft-native': `^${craftVersion}`,
149
+
150
+ },
151
+ devDependencies: {
152
+ '@types/bun': 'latest',
153
+ },
154
+ }
155
+
156
+ writeFileSync(
157
+ join(projectPath, 'package.json'),
158
+ JSON.stringify(packageJson, null, 2),
159
+ )
160
+
161
+ // Create src directory
162
+ mkdirSync(join(projectPath, 'src'))
163
+
164
+ // Create src/index.ts
165
+ const indexTs = `import { show } from 'craft-native'
166
+
167
+ const html = \`
168
+ <!DOCTYPE html>
169
+ <html>
170
+ <head>
171
+ <meta charset="UTF-8">
172
+ <style>
173
+ body {
174
+ margin: 0;
175
+ height: 100vh;
176
+ display: flex;
177
+ justify-content: center;
178
+ align-items: center;
179
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
180
+ color: white;
181
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
182
+ }
183
+ h1 {
184
+ font-size: 3rem;
185
+ text-shadow: 2px 2px 4px rgba(0,0,0,0.3);
186
+ }
187
+ </style>
188
+ </head>
189
+ <body>
190
+ <h1>⚡ Hello from ${projectName}!</h1>
191
+ </body>
192
+ </html>
193
+ \`
194
+
195
+ await show(html, {
196
+ title: '${projectName}',
197
+ width: 600,
198
+ height: 400,
199
+ })
200
+ `
201
+
202
+ writeFileSync(join(projectPath, 'src/index.ts'), indexTs)
203
+
204
+ // Create README.md
205
+ const readme = `# ${projectName}
206
+
207
+ A minimal Craft desktop application.
208
+
209
+ ## Getting Started
210
+
211
+ \`\`\`bash
212
+ bun install
213
+ bun run doctor
214
+ bun run dev
215
+ \`\`\`
216
+
217
+ \`bun run doctor\` verifies that the native \`craft\` binary is available on your PATH. Install it with \`pantry install craft\` if the command is missing.
218
+
219
+ ## Build
220
+
221
+ \`\`\`bash
222
+ bun run build
223
+ \`\`\`
224
+
225
+ ## Learn More
226
+
227
+ - [Craft Documentation](https://github.com/home-lang/craft)
228
+ - [TypeScript SDK](https://github.com/home-lang/craft/tree/main/packages/typescript)
229
+ `
230
+
231
+ writeFileSync(join(projectPath, 'README.md'), readme)
232
+
233
+ // Create .gitignore
234
+ const gitignore = `node_modules
235
+ dist
236
+ zig-out
237
+ zig-cache
238
+ .DS_Store
239
+ `
240
+
241
+ writeFileSync(join(projectPath, '.gitignore'), gitignore)
242
+ }
243
+
244
+ function createFullFeaturedTemplate(projectPath: string, projectName: string): void {
245
+ console.log('📝 Generating full-featured template...')
246
+
247
+ // Create package.json
248
+ const packageJson = {
249
+ name: projectName,
250
+ version: '0.0.1',
251
+ type: 'module',
252
+ private: true,
253
+ scripts: {
254
+ doctor: 'craft --version',
255
+ dev: 'bun run src/index.ts',
256
+ build: 'bun build src/index.ts --outdir dist --target bun',
257
+ },
258
+ dependencies: {
259
+ 'craft-native': `^${craftVersion}`,
260
+
261
+ },
262
+ devDependencies: {
263
+ '@types/bun': 'latest',
264
+ },
265
+ }
266
+
267
+ writeFileSync(
268
+ join(projectPath, 'package.json'),
269
+ JSON.stringify(packageJson, null, 2),
270
+ )
271
+
272
+ // Create src directory
273
+ mkdirSync(join(projectPath, 'src'))
274
+
275
+ // Create src/index.ts
276
+ const indexTs = `import { show } from 'craft-native'
277
+
278
+ const html = \`
279
+ <!DOCTYPE html>
280
+ <html>
281
+ <head>
282
+ <meta charset="UTF-8">
283
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
284
+ <style>
285
+ * {
286
+ margin: 0;
287
+ padding: 0;
288
+ box-sizing: border-box;
289
+ }
290
+
291
+ body {
292
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
293
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
294
+ min-height: 100vh;
295
+ display: flex;
296
+ justify-content: center;
297
+ align-items: center;
298
+ padding: 20px;
299
+ }
300
+
301
+ .container {
302
+ background: white;
303
+ border-radius: 16px;
304
+ padding: 40px;
305
+ max-width: 600px;
306
+ box-shadow: 0 20px 60px rgba(0,0,0,0.3);
307
+ }
308
+
309
+ h1 {
310
+ color: #667eea;
311
+ font-size: 2.5rem;
312
+ margin-bottom: 20px;
313
+ }
314
+
315
+ p {
316
+ color: #666;
317
+ line-height: 1.6;
318
+ margin-bottom: 30px;
319
+ }
320
+
321
+ .features {
322
+ display: grid;
323
+ gap: 15px;
324
+ }
325
+
326
+ .feature {
327
+ padding: 15px;
328
+ background: #f8f9fa;
329
+ border-radius: 8px;
330
+ border-left: 4px solid #667eea;
331
+ }
332
+
333
+ .feature h3 {
334
+ color: #333;
335
+ margin-bottom: 5px;
336
+ }
337
+
338
+ .feature p {
339
+ margin: 0;
340
+ font-size: 0.9rem;
341
+ }
342
+ </style>
343
+ </head>
344
+ <body>
345
+ <div class="container">
346
+ <h1>⚡ ${projectName}</h1>
347
+ <p>Welcome to your new Craft desktop application!</p>
348
+
349
+ <div class="features">
350
+ <div class="feature">
351
+ <h3>🚀 Fast</h3>
352
+ <p>Built with Zig for maximum performance</p>
353
+ </div>
354
+ <div class="feature">
355
+ <h3>💡 Simple</h3>
356
+ <p>TypeScript-first API, no Zig required</p>
357
+ </div>
358
+ <div class="feature">
359
+ <h3>🎨 Modern</h3>
360
+ <p>Use any web framework you love</p>
361
+ </div>
362
+ </div>
363
+ </div>
364
+ </body>
365
+ </html>
366
+ \`
367
+
368
+ await show(html, {
369
+ title: '${projectName}',
370
+ width: 800,
371
+ height: 600,
372
+ })
373
+ `
374
+
375
+ writeFileSync(join(projectPath, 'src/index.ts'), indexTs)
376
+
377
+ // Create README.md
378
+ const readme = `# ${projectName}
379
+
380
+ A full-featured Craft desktop application.
381
+
382
+ ## Getting Started
383
+
384
+ \`\`\`bash
385
+ bun install
386
+ bun run doctor
387
+ bun run dev
388
+ \`\`\`
389
+
390
+ \`bun run doctor\` verifies that the native \`craft\` binary is available on your PATH. Install it with \`pantry install craft\` if the command is missing.
391
+
392
+ ## Build
393
+
394
+ \`\`\`bash
395
+ bun run build
396
+ \`\`\`
397
+
398
+ ## Features
399
+
400
+ - ⚡ Fast startup and runtime performance
401
+ - 💡 TypeScript-first development
402
+ - 🎨 Modern HTML/CSS/JavaScript support
403
+ - 🔥 Hot reload in development mode
404
+
405
+ ## Learn More
406
+
407
+ - [Craft Documentation](https://github.com/home-lang/craft)
408
+ - [TypeScript SDK](https://github.com/home-lang/craft/tree/main/packages/typescript)
409
+ `
410
+
411
+ writeFileSync(join(projectPath, 'README.md'), readme)
412
+
413
+ // Create .gitignore
414
+ const gitignore = `node_modules
415
+ dist
416
+ zig-out
417
+ zig-cache
418
+ .DS_Store
419
+ `
420
+
421
+ writeFileSync(join(projectPath, '.gitignore'), gitignore)
422
+ }
423
+
424
+ function createTodoAppTemplate(projectPath: string, projectName: string): void {
425
+ console.log('📝 Generating todo app template...')
426
+
427
+ // Create package.json
428
+ const packageJson = {
429
+ name: projectName,
430
+ version: '0.0.1',
431
+ type: 'module',
432
+ private: true,
433
+ scripts: {
434
+ doctor: 'craft --version',
435
+ dev: 'bun run src/index.ts',
436
+ build: 'bun build src/index.ts --outdir dist --target bun',
437
+ },
438
+ dependencies: {
439
+ 'craft-native': `^${craftVersion}`,
440
+
441
+ },
442
+ devDependencies: {
443
+ '@types/bun': 'latest',
444
+ },
445
+ }
446
+
447
+ writeFileSync(
448
+ join(projectPath, 'package.json'),
449
+ JSON.stringify(packageJson, null, 2),
450
+ )
451
+
452
+ // Create src directory
453
+ mkdirSync(join(projectPath, 'src'))
454
+
455
+ // Create src/index.ts with full todo app
456
+ const indexTs = `import { show } from 'craft-native'
457
+
458
+ const html = \`
459
+ <!DOCTYPE html>
460
+ <html>
461
+ <head>
462
+ <meta charset="UTF-8">
463
+ <style>
464
+ * {
465
+ margin: 0;
466
+ padding: 0;
467
+ box-sizing: border-box;
468
+ }
469
+
470
+ body {
471
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
472
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
473
+ min-height: 100vh;
474
+ display: flex;
475
+ justify-content: center;
476
+ align-items: center;
477
+ padding: 20px;
478
+ }
479
+
480
+ .container {
481
+ background: white;
482
+ border-radius: 16px;
483
+ padding: 30px;
484
+ width: 100%;
485
+ max-width: 500px;
486
+ box-shadow: 0 20px 60px rgba(0,0,0,0.3);
487
+ }
488
+
489
+ h1 {
490
+ color: #667eea;
491
+ margin-bottom: 20px;
492
+ font-size: 2rem;
493
+ }
494
+
495
+ .input-group {
496
+ display: flex;
497
+ gap: 10px;
498
+ margin-bottom: 20px;
499
+ }
500
+
501
+ input[type="text"] {
502
+ flex: 1;
503
+ padding: 12px;
504
+ border: 2px solid #e0e0e0;
505
+ border-radius: 8px;
506
+ font-size: 1rem;
507
+ }
508
+
509
+ button {
510
+ padding: 12px 24px;
511
+ background: #667eea;
512
+ color: white;
513
+ border: none;
514
+ border-radius: 8px;
515
+ cursor: pointer;
516
+ font-size: 1rem;
517
+ font-weight: 600;
518
+ }
519
+
520
+ button:hover {
521
+ background: #5568d3;
522
+ }
523
+
524
+ .todo-list {
525
+ list-style: none;
526
+ }
527
+
528
+ .todo-item {
529
+ display: flex;
530
+ align-items: center;
531
+ padding: 15px;
532
+ background: #f8f9fa;
533
+ border-radius: 8px;
534
+ margin-bottom: 10px;
535
+ gap: 10px;
536
+ }
537
+
538
+ .todo-item.completed {
539
+ opacity: 0.6;
540
+ }
541
+
542
+ .todo-item.completed span {
543
+ text-decoration: line-through;
544
+ }
545
+
546
+ input[type="checkbox"] {
547
+ width: 20px;
548
+ height: 20px;
549
+ cursor: pointer;
550
+ }
551
+
552
+ .todo-text {
553
+ flex: 1;
554
+ color: #333;
555
+ }
556
+
557
+ .delete-btn {
558
+ padding: 6px 12px;
559
+ background: #ff6b6b;
560
+ font-size: 0.9rem;
561
+ }
562
+
563
+ .delete-btn:hover {
564
+ background: #ee5a52;
565
+ }
566
+
567
+ .empty-state {
568
+ text-align: center;
569
+ padding: 40px;
570
+ color: #999;
571
+ }
572
+ </style>
573
+ </head>
574
+ <body>
575
+ <div class="container">
576
+ <h1>📝 Todo List</h1>
577
+
578
+ <div class="input-group">
579
+ <input type="text" id="todoInput" placeholder="What needs to be done?" />
580
+ <button onclick="addTodo()">Add</button>
581
+ </div>
582
+
583
+ <ul id="todoList" class="todo-list"></ul>
584
+ <div id="emptyState" class="empty-state">No todos yet. Add one above!</div>
585
+ </div>
586
+
587
+ <script>
588
+ let todos = []
589
+
590
+ function render() {
591
+ const list = document.getElementById('todoList')
592
+ const emptyState = document.getElementById('emptyState')
593
+
594
+ if (todos.length === 0) {
595
+ list.innerHTML = ''
596
+ emptyState.style.display = 'block'
597
+ return
598
+ }
599
+
600
+ emptyState.style.display = 'none'
601
+ list.innerHTML = todos.map((todo, index) => \\\`
602
+ <li class="todo-item \\\${todo.completed ? 'completed' : ''}">
603
+ <input type="checkbox" \\\${todo.completed ? 'checked' : ''} onchange="toggleTodo(\\\${index})" />
604
+ <span class="todo-text">\\\${todo.text}</span>
605
+ <button class="delete-btn" onclick="deleteTodo(\\\${index})">Delete</button>
606
+ </li>
607
+ \\\`).join('')
608
+ }
609
+
610
+ function addTodo() {
611
+ const input = document.getElementById('todoInput')
612
+ const text = input.value.trim()
613
+
614
+ if (text) {
615
+ todos.push({ text, completed: false })
616
+ input.value = ''
617
+ render()
618
+ }
619
+ }
620
+
621
+ function toggleTodo(index) {
622
+ todos[index].completed = !todos[index].completed
623
+ render()
624
+ }
625
+
626
+ function deleteTodo(index) {
627
+ todos.splice(index, 1)
628
+ render()
629
+ }
630
+
631
+ document.getElementById('todoInput').addEventListener('keypress', (e) => {
632
+ if (e.key === 'Enter') {
633
+ addTodo()
634
+ }
635
+ })
636
+
637
+ render()
638
+ </script>
639
+ </body>
640
+ </html>
641
+ \`
642
+
643
+ await show(html, {
644
+ title: '${projectName}',
645
+ width: 600,
646
+ height: 700,
647
+ })
648
+ `
649
+
650
+ writeFileSync(join(projectPath, 'src/index.ts'), indexTs)
651
+
652
+ // Create README.md
653
+ const readme = `# ${projectName}
654
+
655
+ An interactive todo list application built with Craft.
656
+
657
+ ## Getting Started
658
+
659
+ \`\`\`bash
660
+ bun install
661
+ bun run doctor
662
+ bun run dev
663
+ \`\`\`
664
+
665
+ \`bun run doctor\` verifies that the native \`craft\` binary is available on your PATH. Install it with \`pantry install craft\` if the command is missing.
666
+
667
+ ## Build
668
+
669
+ \`\`\`bash
670
+ bun run build
671
+ \`\`\`
672
+
673
+ ## Features
674
+
675
+ - ✅ Add, complete, and delete todos
676
+ - 💾 Clean, modern UI
677
+ - ⚡ Fast and lightweight
678
+
679
+ ## Learn More
680
+
681
+ - [Craft Documentation](https://github.com/home-lang/craft)
682
+ - [TypeScript SDK](https://github.com/home-lang/craft/tree/main/packages/typescript)
683
+ `
684
+
685
+ writeFileSync(join(projectPath, 'README.md'), readme)
686
+
687
+ // Create .gitignore
688
+ const gitignore = `node_modules
689
+ dist
690
+ zig-out
691
+ zig-cache
692
+ .DS_Store
693
+ `
694
+
695
+ writeFileSync(join(projectPath, '.gitignore'), gitignore)
696
+ }
697
+
698
+ function installDependencies(projectPath: string): Promise<void> {
699
+ return new Promise((resolve, reject) => {
700
+ const proc = spawn('bun', ['install'], {
701
+ cwd: projectPath,
702
+ stdio: 'inherit',
703
+ })
704
+
705
+ proc.on('exit', (code) => {
706
+ if (code === 0 || code === null) {
707
+ resolve()
708
+ }
709
+ else {
710
+ reject(new Error(`Installation failed with code ${code}`))
711
+ }
712
+ })
713
+
714
+ proc.on('error', (error) => {
715
+ reject(error)
716
+ })
717
+ })
718
+ }
package/package.json ADDED
@@ -0,0 +1,50 @@
1
+ {
2
+ "name": "create-craft",
3
+ "version": "0.0.37",
4
+ "private": false,
5
+ "type": "module",
6
+ "description": "Scaffold a new Craft desktop app project",
7
+ "author": "Chris Breuer <chris@stacksjs.org>",
8
+ "license": "MIT",
9
+ "homepage": "https://github.com/home-lang/craft#readme",
10
+ "repository": {
11
+ "type": "git",
12
+ "url": "git+https://github.com/home-lang/craft.git",
13
+ "directory": "packages/create-craft"
14
+ },
15
+ "bugs": {
16
+ "url": "https://github.com/home-lang/craft/issues"
17
+ },
18
+ "keywords": [
19
+ "create-craft",
20
+ "scaffold",
21
+ "desktop",
22
+ "app",
23
+ "framework",
24
+ "craft",
25
+ "starter",
26
+ "template",
27
+ "boilerplate"
28
+ ],
29
+ "bin": {
30
+ "create-craft": "./bin/cli.ts"
31
+ },
32
+ "files": [
33
+ "bin",
34
+ "README.md"
35
+ ],
36
+ "scripts": {
37
+ "dev": "bun --watch bin/cli.ts",
38
+ "typecheck": "tsc --noEmit"
39
+ },
40
+ "dependencies": {
41
+ "@stacksjs/clapp": "^0.2.0"
42
+ },
43
+ "devDependencies": {
44
+ "@types/bun": "latest"
45
+ },
46
+ "engines": {
47
+ "node": ">=18.0.0",
48
+ "bun": ">=1.0.0"
49
+ }
50
+ }