@draekien/create-d9-app 0.0.4 → 0.0.6
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/README.md +212 -5
- package/dist/index.js +57 -34
- package/package.json +18 -2
- package/templates/base/.agents/skills/hugeicons/SKILL.md +335 -0
- package/templates/base/.agents/skills/hugeicons/references/icon-list-flutter.md +4552 -0
- package/templates/base/.agents/skills/hugeicons/references/icon-list.md +5476 -0
- package/templates/base/.agents/skills/motion/SKILL.md +75 -0
- package/templates/base/.agents/skills/motion/best-practices/base-ui.md +106 -0
- package/templates/base/.agents/skills/motion/best-practices/css-or-motion.md +20 -0
- package/templates/base/.agents/skills/motion/best-practices/index.md +95 -0
- package/templates/base/.agents/skills/motion/best-practices/motion.md +25 -0
- package/templates/base/.agents/skills/motion/best-practices/react.md +102 -0
- package/templates/base/.agents/skills/motion/best-practices/vue.md +37 -0
- package/templates/base/.agents/skills/motion/codex/index.md +95 -0
- package/templates/base/.agents/skills/motion/css-spring/index.md +70 -0
- package/templates/base/.agents/skills/motion/performance-audit/index.md +44 -0
- package/templates/base/.agents/skills/motion/transition-preview/index.md +51 -0
- package/templates/base/.agents/skills/turborepo/SKILL.md +26 -0
- package/templates/base/.agents/skills/upgrade-dependencies/SKILL.md +61 -18
- package/templates/base/.claude/agents/motion-reviewer.md +50 -0
- package/templates/base/.claude/skills/hugeicons/SKILL.md +335 -0
- package/templates/base/.claude/skills/hugeicons/references/icon-list-flutter.md +4552 -0
- package/templates/base/.claude/skills/hugeicons/references/icon-list.md +5476 -0
- package/templates/base/.claude/skills/motion/SKILL.md +75 -0
- package/templates/base/.claude/skills/motion/best-practices/base-ui.md +106 -0
- package/templates/base/.claude/skills/motion/best-practices/css-or-motion.md +20 -0
- package/templates/base/.claude/skills/motion/best-practices/index.md +95 -0
- package/templates/base/.claude/skills/motion/best-practices/motion.md +25 -0
- package/templates/base/.claude/skills/motion/best-practices/react.md +102 -0
- package/templates/base/.claude/skills/motion/best-practices/vue.md +37 -0
- package/templates/base/.claude/skills/motion/codex/index.md +95 -0
- package/templates/base/.claude/skills/motion/css-spring/index.md +70 -0
- package/templates/base/.claude/skills/motion/performance-audit/index.md +44 -0
- package/templates/base/.claude/skills/motion/transition-preview/index.md +51 -0
- package/templates/base/.claude/skills/turborepo/SKILL.md +26 -0
- package/templates/base/.claude/skills/upgrade-dependencies/SKILL.md +61 -18
- package/templates/base/apps/web/public/favicon.svg +1 -0
- package/templates/base/apps/web/src/router.tsx +3 -1
- package/templates/base/apps/web/src/routes/__root.tsx +4 -1
- package/templates/base/package.json +1 -1
- package/templates/base/skills-lock.json +19 -1
- package/templates/integrations.json +22 -0
- package/templates/optional/motion-cursor-rule/.cursor/rules/motion.mdc +14 -0
package/README.md
CHANGED
|
@@ -1,10 +1,217 @@
|
|
|
1
|
-
#
|
|
1
|
+
# create-d9-app
|
|
2
2
|
|
|
3
|
-
Scaffolds a Turborepo monorepo.
|
|
3
|
+
Scaffolds a Turborepo monorepo with TanStack Start, React, TypeScript, Biome, Tailwind, shadcn and pnpm, set up for AI coding agents from the first commit.
|
|
4
4
|
|
|
5
5
|
```sh
|
|
6
|
-
npm create @draekien/d9-app my-app
|
|
7
6
|
pnpm create @draekien/d9-app my-app
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
cd my-app
|
|
8
|
+
pnpm dev
|
|
10
9
|
```
|
|
10
|
+
|
|
11
|
+
## What you get
|
|
12
|
+
|
|
13
|
+
```text
|
|
14
|
+
my-app/
|
|
15
|
+
├── apps/
|
|
16
|
+
│ └── web/ TanStack Start app on Vite, with example routes and tests
|
|
17
|
+
├── packages/
|
|
18
|
+
│ └── ui/ shadcn components, exported as @workspace/ui
|
|
19
|
+
├── .agents/skills/ upgrade-dependencies skill (Codex, Cursor, Agent Skills)
|
|
20
|
+
├── .claude/ rules, skills and hooks for Claude Code
|
|
21
|
+
├── .codex/hooks.json hooks for Codex
|
|
22
|
+
├── .intent/ TanStack Intent gate that loads skills before edits
|
|
23
|
+
├── AGENTS.md project rules for coding agents (CLAUDE.md includes it)
|
|
24
|
+
├── biome.json lint and format, plus GritQL plugins for React and TanStack rules
|
|
25
|
+
├── lefthook.yml pre-commit: comment check and biome --write on staged files
|
|
26
|
+
├── pnpm-workspace.yaml saveExact: true
|
|
27
|
+
├── turbo.json
|
|
28
|
+
└── package.json packageManager: pnpm@12.11.0, engines.node >=22.18.0
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
| Concern | Tool |
|
|
32
|
+
| --- | --- |
|
|
33
|
+
| App framework | TanStack Start (Router, Query, Form, Table, Hotkeys) |
|
|
34
|
+
| UI | React 19 with React Compiler |
|
|
35
|
+
| Language | TypeScript 7 |
|
|
36
|
+
| Build and test | Vite, Vitest |
|
|
37
|
+
| Monorepo | Turborepo, pnpm workspaces |
|
|
38
|
+
| Lint and format | Biome |
|
|
39
|
+
| Git hooks | Lefthook |
|
|
40
|
+
| Components | shadcn on Base UI, Hugeicons |
|
|
41
|
+
| Styling | Tailwind 4, Motion |
|
|
42
|
+
|
|
43
|
+
Every dependency is pinned to an exact version. The project never receives an upstream release until you run the bundled [`upgrade-dependencies`](#upgrade-dependencies) skill or change a pin yourself.
|
|
44
|
+
|
|
45
|
+
## Requirements
|
|
46
|
+
|
|
47
|
+
| Requirement | Why |
|
|
48
|
+
| --- | --- |
|
|
49
|
+
| Node.js 22.18 or newer | The generated project sets `engines.node` to `>=22.18.0`. The CLI exits with an error below Node 22. |
|
|
50
|
+
| pnpm | Required on PATH, whichever of `npm create`, `pnpm create`, `yarn create` or `bun create` runs the CLI: the CLI runs `pnpm install` unless you pass `--no-install`. The generated project pins `pnpm@12.11.0` in `packageManager`; pnpm downloads and runs that version inside the project ([`pmOnFail`](https://pnpm.io/settings/cli#pmonfail), default `download`). |
|
|
51
|
+
| git | Optional. Used for the initial commit unless you pass `--no-git`. |
|
|
52
|
+
|
|
53
|
+
On Windows, do not run pnpm through Corepack. `corepack enable` puts a `pnpm.CMD` batch file on PATH, and cmd.exe stops that batch file at `Terminate batch job (Y/N)?` when you press Ctrl+C in `pnpm dev`, so Turborepo waits and then force-kills the dev server. Run `corepack disable pnpm` and install pnpm with the installer pnpm.io recommends for Windows:
|
|
54
|
+
|
|
55
|
+
```powershell
|
|
56
|
+
npx get-pnpm
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## Usage
|
|
60
|
+
|
|
61
|
+
```text
|
|
62
|
+
Usage: create-d9-app <dir> [options]
|
|
63
|
+
|
|
64
|
+
Arguments:
|
|
65
|
+
<dir> Directory to create the project in; "." uses the current directory
|
|
66
|
+
|
|
67
|
+
Options:
|
|
68
|
+
--yes Accept every default and skip all prompts
|
|
69
|
+
--no-git Do not initialise a git repository or make the initial commit
|
|
70
|
+
--no-install Do not run pnpm install
|
|
71
|
+
--integrations <names>
|
|
72
|
+
Comma-separated agent integrations to configure, or "none"
|
|
73
|
+
--help Show this message
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Scaffold into the current directory. It must be empty apart from `.git`, `.gitignore`, `.idea`, `.vscode`, `LICENSE` and `.DS_Store`:
|
|
77
|
+
|
|
78
|
+
```sh
|
|
79
|
+
mkdir my-app && cd my-app
|
|
80
|
+
pnpm create @draekien/d9-app .
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
The package name in `package.json` is the directory name, so the directory name has to be a valid npm package name: lowercase, URL-safe, not a Node built-in module name.
|
|
84
|
+
|
|
85
|
+
### Prompts and flags
|
|
86
|
+
|
|
87
|
+
Every prompt has a flag. A flag answers its prompt without asking.
|
|
88
|
+
|
|
89
|
+
| Prompt | Default | Flag |
|
|
90
|
+
| --- | --- | --- |
|
|
91
|
+
| Where should the project be created? | `my-app` | `<dir>` |
|
|
92
|
+
| Initialise a git repository? | yes | `--no-git` |
|
|
93
|
+
| Install dependencies? | yes | `--no-install` |
|
|
94
|
+
| Which agent integrations do you want? | `shadcn`, `hugeicons`, `motion` | `--integrations <names>` or `--integrations none` |
|
|
95
|
+
|
|
96
|
+
After an interactive run the CLI prints the command that reproduces your answers:
|
|
97
|
+
|
|
98
|
+
```text
|
|
99
|
+
To create a project with the same options
|
|
100
|
+
pnpm create @draekien/d9-app my-app --yes --no-git
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### Non-interactive use
|
|
104
|
+
|
|
105
|
+
With `--yes`, or when stdin is not a terminal, or when `CI` is set, nothing is prompted. Every option not set by a flag takes its default. `<dir>` is required unless `--yes` supplies the default `my-app`:
|
|
106
|
+
|
|
107
|
+
```sh
|
|
108
|
+
pnpm create @draekien/d9-app my-app --yes
|
|
109
|
+
pnpm create @draekien/d9-app --yes --no-install
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
```text
|
|
113
|
+
$ CI=1 pnpm create @draekien/d9-app
|
|
114
|
+
Missing required <dir>. Pass a project directory or --yes to use the default.
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
## Working in the generated project
|
|
118
|
+
|
|
119
|
+
Run every task from the repository root. Turborepo runs it in each workspace package.
|
|
120
|
+
|
|
121
|
+
| Command | Runs |
|
|
122
|
+
| --- | --- |
|
|
123
|
+
| `pnpm dev` | `vite dev` for `apps/web` |
|
|
124
|
+
| `pnpm build` | `vite build` for `apps/web`, dependencies first |
|
|
125
|
+
| `pnpm check` | Biome lint and format check, the comment check, and every package `check` task |
|
|
126
|
+
| `pnpm typecheck` | `tsc --noEmit` in every package |
|
|
127
|
+
| `pnpm test` | `vitest run` in every package |
|
|
128
|
+
|
|
129
|
+
The pre-commit hook runs the comment check and `biome check --write` on staged files, then re-stages what it fixed.
|
|
130
|
+
|
|
131
|
+
`pnpm check` and the hook delete every `//` comment except `///`, `biome-ignore` and `@ts-` directives. Write comments only to document a public API surface.
|
|
132
|
+
|
|
133
|
+
Add shadcn components from `packages/ui`:
|
|
134
|
+
|
|
135
|
+
```sh
|
|
136
|
+
cd packages/ui
|
|
137
|
+
pnpm exec shadcn add dialog
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
Import them from the app as `@workspace/ui/components/dialog`.
|
|
141
|
+
|
|
142
|
+
## Agent setup
|
|
143
|
+
|
|
144
|
+
The generated project configures Claude Code and Codex. Cursor reads `.cursor/mcp.json`. Other agents that read `AGENTS.md` and `.agents/skills/` get the rules and the skills without extra setup.
|
|
145
|
+
|
|
146
|
+
| File | Purpose |
|
|
147
|
+
| --- | --- |
|
|
148
|
+
| `AGENTS.md`, `CLAUDE.md` | Project rules: run tasks from the root, exact pins only, never edit `routeTree.gen.ts`, where tests live. |
|
|
149
|
+
| `.claude/rules/*.md` | Path-scoped rules for TypeScript, components, tests and generated files. Loaded only for matching files. |
|
|
150
|
+
| `.claude/settings.json`, `.codex/hooks.json` | `SessionStart` and `PreToolUse` hooks that run the TanStack Intent gate. |
|
|
151
|
+
| `.intent/hooks/` | The gate: lists the skills shipped inside the installed `@tanstack/*` packages at session start, and denies the first edit of a session until the agent has checked that list and loaded a matching skill with `pnpm exec intent load`. |
|
|
152
|
+
| `.agents/skills/`, `.claude/skills/` | `shadcn`, `turborepo`, `motion` and `hugeicons`, the skills each project publishes, pinned by content hash in `skills-lock.json`; and `upgrade-dependencies`. |
|
|
153
|
+
| `.claude/agents/motion-reviewer.md` | Motion's reviewer subagent, from the same source as the `motion` skill. |
|
|
154
|
+
| `.mcp.json`, `.cursor/mcp.json` | MCP servers for Claude Code and Cursor: `shadcn` and `hugeicons` as pinned `npx` commands, `motion` over HTTP. Claude Code asks you to approve project servers on first use. |
|
|
155
|
+
| `biome.json` | GritQL plugins that enforce React and TanStack Query rules, such as no fetch in an effect and no inline query key. |
|
|
156
|
+
|
|
157
|
+
### upgrade-dependencies
|
|
158
|
+
|
|
159
|
+
Ask the agent to upgrade dependencies. In Claude Code the skill is also a slash command:
|
|
160
|
+
|
|
161
|
+
```text
|
|
162
|
+
/upgrade-dependencies
|
|
163
|
+
/upgrade-dependencies --accept
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
The skill:
|
|
167
|
+
|
|
168
|
+
1. Finds every exact pin with a newer version that was published at least `minimumReleaseAge` ago (default 1440 minutes, the pnpm default).
|
|
169
|
+
2. Reads the release notes for each upgrade and shows you the breaking changes before editing anything. `--accept` skips that stop for patch and minor upgrades.
|
|
170
|
+
3. Applies patch and minor upgrades, runs install, build, check, typecheck and test, and reverts any package whose upgrade fails a check unless the release notes name the migration.
|
|
171
|
+
4. Holds every major upgrade until you confirm it, one package at a time. `--accept` never confirms a major.
|
|
172
|
+
5. Reports every change:
|
|
173
|
+
|
|
174
|
+
```text
|
|
175
|
+
| Package | Old | New | Type |
|
|
176
|
+
| -------------- | ----- | ----- | ----- |
|
|
177
|
+
| @base-ui/react | 1.8.0 | 1.9.0 | minor |
|
|
178
|
+
|
|
179
|
+
held: major
|
|
180
|
+
- @types/node 22.20.5 -> 26.6.4 (apps/web, packages/ui): declined
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
The skill is a single markdown file. Install the latest copy into an existing project with the [skills](https://github.com/vercel-labs/skills) CLI:
|
|
184
|
+
|
|
185
|
+
```sh
|
|
186
|
+
npx skills add draekien/create-d9-app --skill upgrade-dependencies
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
## Errors
|
|
190
|
+
|
|
191
|
+
| Message | Cause |
|
|
192
|
+
| --- | --- |
|
|
193
|
+
| `create-d9-app requires Node.js 22 or newer.` | Older Node. Switch to Node 22.18 or newer. |
|
|
194
|
+
| `<dir> is not empty. Remove these entries or choose another directory:` | Target has files other than the allowed set above. The listed entries are the ones that block. |
|
|
195
|
+
| `Invalid package name "<name>" derived from the directory:` | Directory name is not a valid npm package name. Rename it or scaffold elsewhere. |
|
|
196
|
+
| `Missing required <dir>.` | Non-interactive run without `<dir>` or `--yes`. |
|
|
197
|
+
| `Terminate batch job (Y/N)?` after Ctrl+C in `pnpm dev` | Windows, with pnpm run through a Corepack shim. Disable it and install pnpm directly; see Requirements. |
|
|
198
|
+
|
|
199
|
+
## Versioning
|
|
200
|
+
|
|
201
|
+
The CLI is at `0.0.x`. Every release is a patch until the owner decides to leave `0.0.x`. Each release lists its changes in the [changelog](https://github.com/draekien/create-d9-app/blob/main/packages/cli/CHANGELOG.md).
|
|
202
|
+
|
|
203
|
+
Template pins refresh from the npm registry on the 1st and 15th of each month, with the same release age rule as the skill. A new CLI release ships them. A project already scaffolded is not changed by a CLI release; use `upgrade-dependencies` for that.
|
|
204
|
+
|
|
205
|
+
## Design decisions
|
|
206
|
+
|
|
207
|
+
- [ADR 0001: Pin template dependency versions](https://github.com/draekien/create-d9-app/blob/main/docs/adr/0001-pin-template-dependency-versions.md)
|
|
208
|
+
- [ADR 0002: Always generate a monorepo](https://github.com/draekien/create-d9-app/blob/main/docs/adr/0002-always-generate-a-monorepo.md)
|
|
209
|
+
- [ADR 0003: Generate templates at build time from upstream tools](https://github.com/draekien/create-d9-app/blob/main/docs/adr/0003-generate-templates-at-build-time-from-upstream-tools.md)
|
|
210
|
+
|
|
211
|
+
## Contributing
|
|
212
|
+
|
|
213
|
+
See [CONTRIBUTING.md](https://github.com/draekien/create-d9-app/blob/main/CONTRIBUTING.md). Bugs and requests: [issues](https://github.com/draekien/create-d9-app/issues).
|
|
214
|
+
|
|
215
|
+
## License
|
|
216
|
+
|
|
217
|
+
[MIT](https://github.com/draekien/create-d9-app/blob/main/LICENSE)
|
package/dist/index.js
CHANGED
|
@@ -1,44 +1,65 @@
|
|
|
1
|
-
import{builtinModules as e}from"node:module";import{spawnSync as t}from"node:child_process";import n from"node:fs";import r from"node:path";import{fileURLToPath as i}from"node:url";import{parseArgs as a,styleText as o}from"node:util";import s,{stdin as c,stdout as l}from"node:process";import u from"node:readline";var d=(e,t)=>()=>(t||(e((t={exports:{}}).exports,t),e=null),t.exports);function f(e,n,r=!0){return t(`git`,n,{cwd:e,encoding:`utf8`,stdio:r?`pipe`:`inherit`})}function p(e){return f(e,[`rev-parse`,`--is-inside-work-tree`]).status===0}function m(e){let t=t=>f(e,[`config`,t]).stdout.trim()!==``,n=[];return t(`user.name`)||n.push(`-c`,`user.name=create-d9-app`),t(`user.email`)||n.push(`-c`,`user.email=create-d9-app@users.noreply.github.com`),n}function h(e){if(p(e))return{ok:!0,skipped:!0,output:``};let t=[[`init`],[`add`,`-A`],[...m(e),`commit`,`-m`,`chore: initial commit`]];for(let n of t){let t=f(e,n);if(t.status!==0)return{ok:!1,skipped:!1,output:`${t.stdout}${t.stderr}`}}return{ok:!0,skipped:!1,output:``}}function g({
|
|
2
|
-
|
|
3
|
-
`),
|
|
4
|
-
`){a&&(r
|
|
5
|
-
`&&(i&&pe(i)&&(r+=
|
|
6
|
-
`)
|
|
1
|
+
import{builtinModules as e}from"node:module";import{spawnSync as t}from"node:child_process";import n from"node:fs";import r from"node:path";import{fileURLToPath as i}from"node:url";import{parseArgs as a,styleText as o}from"node:util";import s,{stdin as c,stdout as l}from"node:process";import u from"node:readline";var d=(e,t)=>()=>(t||(e((t={exports:{}}).exports,t),e=null),t.exports);function f(e,n,r=!0){return t(`git`,n,{cwd:e,encoding:`utf8`,stdio:r?`pipe`:`inherit`})}function p(e){return f(e,[`rev-parse`,`--is-inside-work-tree`]).status===0}function m(e){let t=t=>f(e,[`config`,t]).stdout.trim()!==``,n=[];return t(`user.name`)||n.push(`-c`,`user.name=create-d9-app`),t(`user.email`)||n.push(`-c`,`user.email=create-d9-app@users.noreply.github.com`),n}function h(e){if(p(e))return{ok:!0,skipped:!0,output:``};let t=[[`init`],[`add`,`-A`],[...m(e),`commit`,`-m`,`chore: initial commit`]];for(let n of t){let t=f(e,n);if(t.status!==0)return{ok:!1,skipped:!1,output:`${t.stdout}${t.stderr}`}}return{ok:!0,skipped:!1,output:``}}function g(e){return JSON.parse(n.readFileSync(r.join(e,`integrations.json`),`utf8`))}function _(e){return Object.keys(e).filter(t=>e[t]?.default)}function v(e,t){if(e.kind===`stdio`)return{command:e.command,args:e.args};if(e.kind===`http`)return t===`claude`?{type:`http`,url:e.url}:{url:e.url}}function y(e,t){n.mkdirSync(r.dirname(e),{recursive:!0});let i=JSON.stringify(t,null,2).replace(/\[\n\s+([^[\]{}]*?)\n\s*\]/g,(e,t)=>`[${t.replace(/,\n\s+/g,`, `)}]`);n.writeFileSync(e,`${i}\n`)}function b(e,t,n){let i=Object.keys(e).filter(n=>t.includes(n)&&e[n]?.kind!==`overlay`);if(i.length===0)return;let a=t=>Object.fromEntries(i.flatMap(n=>{let r=e[n];return r?[[n,v(r,t)]]:[]}));y(r.join(n,`.mcp.json`),{mcpServers:a(`claude`)}),y(r.join(n,`.cursor`,`mcp.json`),{mcpServers:a(`cursor`)})}function x(e,t){let n=e.split(`,`).map(e=>e.trim()).filter(Boolean);if(n.length===1&&n[0]===`none`)return[];let r=Object.keys(t),i=n.filter(e=>!r.includes(e));if(i.length>0||n.length===0)throw Error(`Unknown --integrations value ${i.length>0?i.join(`, `):JSON.stringify(e)}. Valid names: ${r.join(`, `)}, or none.`);return r.filter(e=>n.includes(e))}function S(e,t){let n=[],r=[];for(let[i,a]of Object.entries(e))t.includes(i)&&a.kind!==`overlay`&&(a.kind===`stdio`?n.push(`[mcp_servers.${i}]\ncommand = ${JSON.stringify(a.command)}\nargs = [${a.args.map(e=>JSON.stringify(e)).join(`, `)}]`):(n.push(`[mcp_servers.${i}]\nurl = ${JSON.stringify(a.url)}`),a.login&&r.push(`\`${i}\` needs a ${a.login}.`)));return n.length===0?``:[`## Codex MCP servers`,``,"Codex reads MCP servers only from `~/.codex/config.toml`, not from `.mcp.json`. Add these tables to that file to get the servers this project configures for Claude Code and Cursor:",``,"```toml",n.join(`
|
|
2
|
+
|
|
3
|
+
`),"```",...r.length>0?[``,r.join(` `)]:[],``].join(`
|
|
4
|
+
`)}function ee(e,t,i){let a=S(e,t);a&&n.appendFileSync(r.join(i,`AGENTS.md`),`\n${a}`)}function te({stdin:e,stdout:t,env:n,yes:r}){return!(!e.isTTY||!t.isTTY||n.CI||r)}function ne({targetDir:e,cwd:t,install:n}){let i=r.relative(t,e),a=[];return i!==``&&a.push(`cd ${/\s/.test(i)?JSON.stringify(i):i}`),n||a.push(`pnpm install`),a.push(`pnpm dev`),`Next steps:\n${a.map(e=>` ${e}`).join(`
|
|
5
|
+
`)}\n`}const C={_gitignore:`.gitignore`};function w(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function re(e){let t=r.join(e,`tools`);return n.existsSync(t)?n.readdirSync(t,{withFileTypes:!0}).filter(e=>e.isDirectory()).map(e=>e.name).sort():[]}function T(e,t){let n={...e};for(let[e,r]of Object.entries(t)){let t=n[e];n[e]=w(t)&&w(r)?T(t,r):r}return n}function E(e,t){n.mkdirSync(t,{recursive:!0});for(let i of n.readdirSync(e,{withFileTypes:!0})){let a=r.join(e,i.name),o=r.join(t,C[i.name]??i.name);if(i.isDirectory())E(a,o);else if(i.name===`package.json`&&n.existsSync(o)){let e=T(JSON.parse(n.readFileSync(o,`utf8`)),JSON.parse(n.readFileSync(a,`utf8`)));n.writeFileSync(o,`${JSON.stringify(e,null,2)}\n`)}else n.copyFileSync(a,o)}}function ie(e,t,i=[]){for(let n of re(e))E(r.join(e,`tools`,n),t);for(let a of[...i].sort()){let i=r.join(e,`optional`,a);n.existsSync(i)&&E(i,t)}}const ae=(()=>{let e=/[\uD800-\uDBFF][\uDC00-\uDFFF]/g;return t=>{let n=0;for(e.lastIndex=0;e.test(t);)n+=1;return t.length-n}})(),oe=e=>e===12288||e>=65281&&e<=65376||e>=65504&&e<=65510,se=e=>e===8987||e===9001||e>=12272&&e<=12287||e>=12289&&e<=12350||e>=12441&&e<=12543||e>=12549&&e<=12591||e>=12593&&e<=12686||e>=12688&&e<=12771||e>=12783&&e<=12830||e>=12832&&e<=12871||e>=12880&&e<=19903||e>=65040&&e<=65049||e>=65072&&e<=65106||e>=65108&&e<=65126||e>=65128&&e<=65131||e>=127488&&e<=127490||e>=127504&&e<=127547||e>=127552&&e<=127560||e>=131072&&e<=196605||e>=196608&&e<=262141,ce=/[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]|\u001b\]8;[^;]*;.*?(?:\u0007|\u001b\u005c)/y,le=/[\x00-\x08\x0A-\x1F\x7F-\x9F]{1,1000}/y,D=/(?:(?![\uFF61-\uFF9F\uFF00-\uFFEF])[\p{Script=Han}\p{Script=Hiragana}\p{Script=Katakana}\p{Script=Hangul}\p{Script=Tangut}]){1,1000}/uy,ue=/\t{1,1000}/y,de=/[\u{1F1E6}-\u{1F1FF}]{2}|\u{1F3F4}[\u{E0061}-\u{E007A}]{2}[\u{E0030}-\u{E0039}\u{E0061}-\u{E007A}]{1,3}\u{E007F}|(?:\p{Emoji}\uFE0F\u20E3?|\p{Emoji_Modifier_Base}\p{Emoji_Modifier}?|\p{Emoji_Presentation})(?:\u200D(?:\p{Emoji_Modifier_Base}\p{Emoji_Modifier}?|\p{Emoji_Presentation}|\p{Emoji}\uFE0F\u20E3?))*/uy,fe=/(?:[\x20-\x7E\xA0-\xFF](?!\uFE0F)){1,1000}/y,pe=/\p{M}+/gu,me={limit:1/0,ellipsis:``},O=(e,t={},n={})=>{let r=t.limit??1/0,i=t.ellipsis??``,a=t?.ellipsisWidth??(i?O(i,me,n).width:0),o=n.controlWidth??0,s=n.tabWidth??8,c=n.emojiWidth??2,l=n.regularWidth??1,u=n.wideWidth??2,d=[[fe,l],[ce,0],[le,o],[ue,s],[de,c],[D,u]],f=0,p=0,m=e.length,h=0,g=!1,_=m,v=Math.max(0,r-a),y=0,b=0,x=0,S=0;outer:for(;;){if(b>y||p>=m&&p>f){let t=e.slice(y,b)||e.slice(f,p);h=0;for(let e of t.replaceAll(pe,``)){let t=e.codePointAt(0)||0;if(S=oe(t)?2:se(t)?u:l,x+S>v&&(_=Math.min(_,Math.max(y,f)+h)),x+S>r){g=!0;break outer}h+=e.length,x+=S}y=b=0}if(p>=m)break outer;for(let t=0,n=d.length;t<n;t++){let[n,i]=d[t];if(n.lastIndex=p,n.test(e)){if(h=n===D?ae(e.slice(p,n.lastIndex)):n===de?1:n.lastIndex-p,S=h*i,x+S>v&&(_=Math.min(_,p+Math.floor((v-x)/i))),x+S>r){g=!0;break outer}x+=S,y=f,b=p,p=f=n.lastIndex;continue outer}}p+=1}return{width:g?v:x,index:g?_:m,truncated:g,ellipsed:g&&r>=a}},he={limit:1/0,ellipsis:``,ellipsisWidth:0},k=(e,t={})=>O(e,he,t).width,A=`]8;;`,ge=RegExp(`(?:\\[(?<code>\\d+)m|\\${A}(?<uri>.*))`,`y`),_e=e=>{if(e>=30&&e<=37||e>=90&&e<=97)return 39;if(e>=40&&e<=47||e>=100&&e<=107)return 49;if(e===1||e===2)return 22;if(e===3)return 23;if(e===4)return 24;if(e===7)return 27;if(e===8)return 28;if(e===9)return 29;if(e===0)return 0},j=e=>`[${e}m`,ve=e=>`${A}${e}`,M=(e,t,n)=>{let r=t[Symbol.iterator](),i=!1,a=!1,o=e.at(-1),s=o===void 0?0:k(o),c=r.next(),l=r.next(),u=0;for(;!c.done;){let o=c.value,d=k(o);s+d<=n?e[e.length-1]+=o:(e.push(o),s=0),(o===`\x1B`||o===``)&&(i=!0,a=t.startsWith(A,u+1)),i?a?o===`\x07`&&(i=!1,a=!1):o===`m`&&(i=!1):(s+=d,s===n&&!l.done&&(e.push(``),s=0)),c=l,l=r.next(),u+=o.length}o=e.at(-1),!s&&o!==void 0&&o.length&&e.length>1&&(e[e.length-2]+=e.pop())},ye=e=>{let t=e.split(` `),n=t.length;for(;n&&!k(t[n-1]);)n--;return n===t.length?e:t.slice(0,n).join(` `)+t.slice(n).join(``)},be=(e,t,n={})=>{if(n.trim!==!1&&e.trim()===``)return``;let r=``,i,a,o=e.split(` `),s=[``],c=0;for(let e=0;e<o.length;e++){let r=o[e];if(n.trim!==!1){let e=s.at(-1)??``,t=e.trimStart();e.length!==t.length&&(s[s.length-1]=t,c=k(t))}e!==0&&(c>=t&&(n.wordWrap===!1||n.trim===!1)&&(s.push(``),c=0),(c||n.trim===!1)&&(s[s.length-1]+=` `,c++));let i=k(r);if(n.hard&&i>t){let e=t-c,n=1+Math.floor((i-e-1)/t);Math.floor((i-1)/t)<n&&s.push(``),M(s,r,t),c=k(s.at(-1)??``)}else{if(c+i>t&&c&&i){if(n.wordWrap===!1&&c<t){M(s,r,t),c=k(s.at(-1)??``);continue}s.push(``),c=0}c+i>t&&n.wordWrap===!1?(M(s,r,t),c=k(s.at(-1)??``)):(s[s.length-1]+=r,c+=i)}}n.trim!==!1&&(s=s.map(e=>ye(e)));let l=s.join(`
|
|
6
|
+
`),u=!1;for(let e=0;e<l.length;e++){let t=l[e];if(r+=t,u)u=!1;else if(u=t>=`\ud800`&&t<=`\udbff`,u)continue;if(t===`\x1B`||t===``){ge.lastIndex=e+1;let t=ge.exec(l)?.groups;if(t?.code!==void 0){let e=Number.parseFloat(t.code);i=e===39?void 0:e}else t?.uri!==void 0&&(a=t.uri.length===0?void 0:t.uri)}if(l[e+1]===`
|
|
7
|
+
`){a&&(r+=ve(``));let e=i?_e(i):void 0;i&&e&&(r+=j(e))}else t===`
|
|
8
|
+
`&&(i&&_e(i)&&(r+=j(i)),a&&(r+=ve(a)))}return r},xe=/\r?\n/;function N(e,t,n){return String(e).normalize().split(xe).map(e=>be(e,t,n)).join(`
|
|
9
|
+
`)}var P=(/* @__PURE__ */ d(((e,t)=>{let n={to(e,t){return t?`[${t+1};${e+1}H`:`[${e+1}G`},move(e,t){let n=``;return e<0?n+=`[${-e}D`:e>0&&(n+=`[${e}C`),t<0?n+=`[${-t}A`:t>0&&(n+=`[${t}B`),n},up:(e=1)=>`[${e}A`,down:(e=1)=>`[${e}B`,forward:(e=1)=>`[${e}C`,backward:(e=1)=>`[${e}D`,nextLine:(e=1)=>`\x1B[E`.repeat(e),prevLine:(e=1)=>`\x1B[F`.repeat(e),left:`\x1B[G`,hide:`\x1B[?25l`,show:`\x1B[?25h`,save:`\x1B7`,restore:`\x1B8`};t.exports={cursor:n,scroll:{up:(e=1)=>`\x1B[S`.repeat(e),down:(e=1)=>`\x1B[T`.repeat(e)},erase:{screen:`\x1B[2J`,up:(e=1)=>`\x1B[1J`.repeat(e),down:(e=1)=>`\x1B[J`.repeat(e),line:`\x1B[2K`,lineEnd:`\x1B[K`,lineStart:`\x1B[1K`,lines(e){let t=``;for(let r=0;r<e;r++)t+=this.line+(r<e-1?n.up():``);return e&&(t+=n.left),t}},beep:`\x07`}})))();const F={actions:/* @__PURE__ */ new Set([`up`,`down`,`left`,`right`,`space`,`enter`,`cancel`]),aliases:/* @__PURE__ */ new Map([[`k`,`up`],[`j`,`down`],[`h`,`left`],[`l`,`right`],[``,`cancel`],[`escape`,`cancel`]]),messages:{cancel:`Canceled`,error:`Something went wrong`},withGuide:!0,accessible:void 0,date:{monthNames:[`January`,`February`,`March`,`April`,`May`,`June`,`July`,`August`,`September`,`October`,`November`,`December`],messages:{required:`Please enter a valid date`,invalidMonth:`There are only 12 months in a year`,invalidDay:(e,t)=>`There are only ${e} days in ${t}`,afterMin:e=>`Date must be on or after ${e.toISOString().slice(0,10)}`,beforeMax:e=>`Date must be on or before ${e.toISOString().slice(0,10)}`}}};function Se(e){if(e!==void 0)return e;if(F.accessible!==void 0)return F.accessible;let t=process.env.ACCESSIBLE;return t!==void 0&&t!==``&&t!==`0`&&t!==`false`}function Ce(e,t){if(typeof e==`string`)return F.aliases.get(e)===t;for(let n of e)if(n!==void 0&&Ce(n,t))return!0;return!1}function we(e,t){if(e===t)return;let n=e.split(`
|
|
7
10
|
`),r=t.split(`
|
|
8
|
-
`),i=Math.max(n.length,r.length),a=[];for(let e=0;e<i;e++)n[e]!==r[e]&&a.push(e);return{lines:a,numLinesBefore:n.length,numLinesAfter:r.length,numLines:i}}globalThis.process.platform.startsWith(`win`);const I=Symbol(`clack:cancel`);function
|
|
11
|
+
`),i=Math.max(n.length,r.length),a=[];for(let e=0;e<i;e++)n[e]!==r[e]&&a.push(e);return{lines:a,numLinesBefore:n.length,numLinesAfter:r.length,numLines:i}}globalThis.process.platform.startsWith(`win`);const I=Symbol(`clack:cancel`);function Te(e){return e===I}function L(e,t){let n=e;n.isTTY&&n.setRawMode(t)}const R=e=>`columns`in e&&typeof e.columns==`number`?e.columns:80,Ee=e=>`rows`in e&&typeof e.rows==`number`?e.rows:20;function z(e,t,n,r=n,i=n,a){return N(t,R(e??l)-n.length,{hard:!0,trim:!1}).split(`
|
|
9
12
|
`).map((e,t,o)=>{let s=a?a(e,t):e;return t===0?`${r}${s}`:t===o.length-1?`${i}${s}`:`${n}${s}`}).join(`
|
|
10
|
-
`)}function
|
|
11
|
-
`),L(this.input,!1),this.rl?.close(),this.rl=void 0,this.emit(`${this.state}`,this.value),this.unsubscribe()}restoreCursor(){let e=
|
|
12
|
-
`).length-1;this.output.write(
|
|
13
|
-
`);this.output.write(t[a]),this._prevFrame=e,this.output.write(
|
|
13
|
+
`)}function De(e,t){if(`~standard`in e){let n=e[`~standard`].validate(t);return n instanceof Promise?n.then(e=>e.issues?.at(0)?.message):n.issues?.at(0)?.message}return e(t)}var B=class{input;output;_abortSignal;rl;opts;_render;_track=!1;_prevFrame=``;_subscribers=/* @__PURE__ */ new Map;_cursor=0;state=`initial`;error=``;value;userInput=``;get accessible(){return Se(this.opts.accessible)}constructor(e,t=!0){let{input:n=c,output:r=l,render:i,signal:a,...o}=e;this.opts=o,this.onKeypress=this.onKeypress.bind(this),this.close=this.close.bind(this),this.render=this.render.bind(this),this._render=i.bind(this),this._track=t,this._abortSignal=a,this.input=n,this.output=r}unsubscribe(){this._subscribers.clear()}setSubscriber(e,t){let n=this._subscribers.get(e)??[];n.push(t),this._subscribers.set(e,n)}on(e,t){this.setSubscriber(e,{cb:t})}once(e,t){this.setSubscriber(e,{cb:t,once:!0})}emit(e,...t){let n=this._subscribers.get(e)??[],r=[];for(let e of n)e.cb(...t),e.once&&r.push(()=>n.splice(n.indexOf(e),1));for(let e of r)e()}prompt(){return new Promise(e=>{if(this._abortSignal){if(this._abortSignal.aborted)return this.state=`cancel`,this.close(),e(I);this._abortSignal.addEventListener(`abort`,()=>{this.state=`cancel`,this.close()},{once:!0})}this.rl=u.createInterface({input:this.input,tabSize:2,prompt:``,escapeCodeTimeout:50,terminal:!0}),this.rl.prompt(),this.opts.initialUserInput!==void 0&&this._setUserInput(this.opts.initialUserInput,!0),this.input.on(`keypress`,this.onKeypress),L(this.input,!0),this.output.on(`resize`,this.render),this.render(),this.once(`submit`,()=>{this.output.write(P.cursor.show),this.output.off(`resize`,this.render),L(this.input,!1),e(this.value)}),this.once(`cancel`,()=>{this.output.write(P.cursor.show),this.output.off(`resize`,this.render),L(this.input,!1),e(I)})})}_isActionKey(e,t){return e===` `}_shouldSubmit(e,t){return!0}_setValue(e){this.value=e,this.emit(`value`,this.value)}_setUserInput(e,t){this.userInput=e??``,this.emit(`userInput`,this.userInput),t&&this._track&&this.rl&&(this.rl.write(this.userInput),this._cursor=this.rl.cursor)}_clearUserInput(){this.rl?.write(null,{ctrl:!0,name:`u`}),this._setUserInput(``)}async onKeypress(e,t){if(this.state!==`validating`){if(this._track&&t.name!==`return`&&(t.name&&this._isActionKey(e,t)&&this.rl?.write(null,{ctrl:!0,name:`h`}),this._cursor=this.rl?.cursor??0,this._setUserInput(this.rl?.line)),this.state===`error`&&(this.state=`active`),t?.name&&(!this._track&&F.aliases.has(t.name)&&this.emit(`cursor`,F.aliases.get(t.name)),F.actions.has(t.name)&&this.emit(`cursor`,t.name)),e&&(e.toLowerCase()===`y`||e.toLowerCase()===`n`)&&this.emit(`confirm`,e.toLowerCase()===`y`),this.emit(`key`,e,t),t?.name===`return`&&this._shouldSubmit(e,t)){if(this.opts.validate){let e=De(this.opts.validate,this.value),t;e instanceof Promise?(this.state=`validating`,this.render(),t=await e):t=e,t&&(this.error=t instanceof Error?t.message:t,this.state=`error`,this.rl?.write(this.userInput))}this.state!==`error`&&(this.state=`submit`)}Ce([e,t?.name,t?.sequence],`cancel`)&&(this.state=`cancel`),(this.state===`submit`||this.state===`cancel`)&&this.emit(`finalize`),this.render(),(this.state===`submit`||this.state===`cancel`)&&this.close()}}close(){this.input.unpipe(),this.input.removeListener(`keypress`,this.onKeypress),this.output.write(`
|
|
14
|
+
`),L(this.input,!1),this.rl?.close(),this.rl=void 0,this.emit(`${this.state}`,this.value),this.unsubscribe()}restoreCursor(){let e=N(this._prevFrame,process.stdout.columns,{hard:!0,trim:!1}).split(`
|
|
15
|
+
`).length-1;this.output.write(P.cursor.move(-999,e*-1))}render(){let e=N(this._render(this)??``,process.stdout.columns,{hard:!0,trim:!1});if(e!==this._prevFrame){if(this.state===`initial`)this.output.write(P.cursor.hide);else{let t=we(this._prevFrame,e),n=Ee(this.output);if(this.restoreCursor(),t){let r=Math.max(0,t.numLinesAfter-n),i=Math.max(0,t.numLinesBefore-n),a=t.lines.find(e=>e>=r);if(a===void 0){this._prevFrame=e;return}if(t.lines.length===1){this.output.write(P.cursor.move(0,a-i)),this.output.write(P.erase.lines(1));let t=e.split(`
|
|
16
|
+
`);this.output.write(t[a]),this._prevFrame=e,this.output.write(P.cursor.move(0,t.length-a-1));return}if(t.lines.length>1){if(r<i)a=r;else{let e=a-i;e>0&&this.output.write(P.cursor.move(0,e))}this.output.write(P.erase.down());let t=e.split(`
|
|
14
17
|
`).slice(a);this.output.write(t.join(`
|
|
15
|
-
`)),this._prevFrame=e;return}}this.output.write(
|
|
18
|
+
`)),this._prevFrame=e;return}}this.output.write(P.erase.down())}this.output.write(e),this.state===`initial`&&(this.state=`active`),this._prevFrame=e}}},Oe=class extends B{get cursor(){return+!this.value}get _value(){return this.cursor===0}constructor(e){super(e,!1),this.value=!!e.initialValue,this.on(`userInput`,()=>{this.value=this._value}),this.on(`confirm`,e=>{this.output.write(P.cursor.move(0,-1)),this.value=e,this.state=`submit`,this.close()}),this.on(`cursor`,()=>{this.value=!this.value})}};let ke=class extends B{options;cursor=0;#e;getGroupItems(e){return this.options.filter(t=>t.group===e)}isGroupSelected(e){let t=this.getGroupItems(e),n=this.value;return n!==void 0&&t.every(e=>n.includes(e.value))}toggleValue(){let e=this.options[this.cursor];if(e!==void 0){if(this.value===void 0&&(this.value=[]),e.group===!0){let t=e.value,n=this.getGroupItems(t);this.value=this.isGroupSelected(t)?this.value.filter(e=>n.findIndex(t=>t.value===e)===-1):[...this.value,...n.map(e=>e.value)],this.value=Array.from(new Set(this.value))}else{let t=this.value.includes(e.value);this.value=t?this.value.filter(t=>t!==e.value):[...this.value,e.value]}}}constructor(e){super(e,!1);let{options:t}=e;this.#e=e.selectableGroups!==!1,this.options=Object.entries(t).flatMap(([e,t])=>[{value:e,group:!0,label:e},...t.map(t=>({...t,group:e}))]),this.value=[...e.initialValues??[]],this.cursor=Math.max(this.options.findIndex(({value:t})=>t===e.cursorAt),+!this.#e),this.on(`cursor`,e=>{switch(e){case`left`:case`up`:{this.cursor=this.cursor===0?this.options.length-1:this.cursor-1;let e=this.options[this.cursor]?.group===!0;!this.#e&&e&&(this.cursor=this.cursor===0?this.options.length-1:this.cursor-1);break}case`down`:case`right`:{this.cursor=this.cursor===this.options.length-1?0:this.cursor+1;let e=this.options[this.cursor]?.group===!0;!this.#e&&e&&(this.cursor=this.cursor===this.options.length-1?0:this.cursor+1);break}case`space`:this.toggleValue()}})}};var Ae=class extends B{get userInputWithCursor(){if(this.state===`submit`)return this.userInput;let e=this.userInput;if(this.cursor>=e.length)return`${this.userInput}\u2588`;let t=e.slice(0,this.cursor),n=e.slice(this.cursor,this.cursor+1),r=e.slice(this.cursor+1);return`${t}${o(`inverse`,n)}${r}`}get cursor(){return this._cursor}constructor(e){super({...e,initialUserInput:e.initialUserInput??e.initialValue}),this.on(`userInput`,e=>{this._setValue(e)}),this.on(`finalize`,()=>{this.value||=e.defaultValue,this.value===void 0&&(this.value=``)})}};function je(){return s.platform===`win32`?!!s.env.CI||!!s.env.WT_SESSION||!!s.env.TERMINUS_SUBLIME||s.env.ConEmuTask===`{cmd::Cmder}`||s.env.TERM_PROGRAM===`Terminus-Sublime`||s.env.TERM_PROGRAM===`vscode`||s.env.TERM===`xterm-256color`||s.env.TERM===`alacritty`||s.env.TERMINAL_EMULATOR===`JetBrains-JediTerm`:s.env.TERM!==`linux`}const Me=je(),V=(e,t)=>Me?e:t,H=V(`◆`,`*`),Ne=V(`■`,`x`),Pe=V(`▲`,`x`),U=V(`◇`,`o`),W=V(`│`,`|`),G=V(`└`,`—`),K=V(`●`,`>`),q=V(`○`,` `),J=V(`◻`,`[•]`),Y=V(`◼`,`[+]`),Fe=V(`◻`,`[ ]`),Ie=V(`─`,`-`),Le=V(`╮`,`+`),Re=V(`├`,`+`),ze=V(`╯`,`+`),Be=V(`╰`,`+`),X=e=>{switch(e){case`initial`:case`active`:return o(`cyan`,H);case`cancel`:return o(`red`,Ne);case`error`:return o(`yellow`,Pe);case`submit`:return o(`green`,U);case`validating`:return o(`dim`,H)}};function Ve(e,t){let n=[`${t?`${o(`cyan`,W)} `:``}${e.join(` • `)}`];return t&&n.push(o(`cyan`,G)),n}const He=(e,t,n,r,i,a=!1)=>{let o=t,s=0;if(a)for(let t=r-1;t>=n;t--){let n=e[t];if(n&&(o-=n.length),s++,o<=i)break}else for(let t=n;t<r;t++){let n=e[t];if(n&&(o-=n.length),s++,o<=i)break}return{lineCount:o,removals:s}},Ue=({cursor:e,options:t,style:n,output:r=process.stdout,maxItems:i=1/0,columnPadding:a=0,rowPadding:s=4})=>{let c=R(r)-a,l=Ee(r),u=o(`dim`,`...`),d=Math.max(l-s,0),f=Math.max(Math.min(i,d),5),p=0;e>=f-3&&(p=Math.max(Math.min(e-f+3,t.length-f),0));let m=f<t.length&&p>0,h=f<t.length&&p+f<t.length,g=Math.min(p+f,t.length),_=[],v=0;m&&v++,h&&v++;let y=p+ +!!m,b=g-+!!h;for(let r=y;r<b;r++){let i=t[r],a=N(i?n(i,r===e):``,c,{hard:!0,trim:!1}).split(`
|
|
19
|
+
`);_.push(a),v+=a.length}if(v>d){let t=0,n=0,r=v,i=e-y,a=d,o=()=>He(_,r,0,i,a),s=()=>He(_,r,i+1,_.length,a,!0);m?({lineCount:r,removals:t}=o(),r>a&&(h||--a,{lineCount:r,removals:n}=s())):(h||--a,{lineCount:r,removals:n}=s(),r>a&&(--a,{lineCount:r,removals:t}=o())),t>0&&(m=!0,_.splice(0,t)),n>0&&(h=!0,_.splice(_.length-n,n))}let x=[];m&&x.push(u);for(let e of _)for(let t of e)x.push(t);return h&&x.push(u),x},We=e=>{let t=e.active??`Yes`,n=e.inactive??`No`;return new Oe({active:t,inactive:n,signal:e.signal,input:e.input,output:e.output,initialValue:e.initialValue??!0,render(){let r=e.withGuide??F.withGuide,i=`${X(this.state)} `,a=r?`${o(`gray`,W)} `:``,s=z(e.output,e.message,a,i),c=`${r?`${o(`gray`,W)}
|
|
16
20
|
`:``}${s}
|
|
17
|
-
`,l=this.value?t:n;switch(this.state){case`submit`:return`${c}${r?`${o(`gray`,
|
|
18
|
-
${o(`gray`,
|
|
19
|
-
${o(`cyan`,
|
|
20
|
-
`:` ${o(`dim`,`/`)} `}${this.value?`${o(`dim`,
|
|
21
|
+
`,l=this.value?t:n;switch(this.state){case`submit`:return`${c}${r?`${o(`gray`,W)} `:``}${o(`dim`,l)}`;case`cancel`:return`${c}${r?`${o(`gray`,W)} `:``}${o([`strikethrough`,`dim`],l)}${r?`
|
|
22
|
+
${o(`gray`,W)}`:``}`;default:{let i=r?`${o(`cyan`,W)} `:``,a=r?o(`cyan`,G):``;return`${c}${i}${this.value?`${o(`green`,K)} ${t}`:`${o(`dim`,q)} ${o(`dim`,t)}`}${e.vertical?r?`
|
|
23
|
+
${o(`cyan`,W)} `:`
|
|
24
|
+
`:` ${o(`dim`,`/`)} `}${this.value?`${o(`dim`,q)} ${o(`dim`,n)}`:`${o(`green`,K)} ${n}`}
|
|
21
25
|
${a}
|
|
22
|
-
`}}}}).prompt()}
|
|
26
|
+
`}}}}).prompt()},Ge=[`${o(`dim`,`↑/↓`)} to navigate`,`${o(`dim`,`Space:`)} select`,`${o(`dim`,`Enter:`)} confirm`],Ke=e=>{let{selectableGroups:t=!0,groupSpacing:n=0}=e,r=(r,i,a=[])=>{let s=r.label??String(r.value),c=typeof r.group==`string`,l=c&&(a[a.indexOf(r)+1]??{group:!0}),u=c&&l&&l.group===!0,d=``,f=``;c&&(t?(d=u?`${G} `:`${W} `,f=u?` `:`${W} `):d=` `);let p=``;if(n>0&&!c&&(p=`
|
|
27
|
+
`.repeat(n)),i===`active`)return z(e.output,`${s}${r.hint?` ${o(`dim`,`(${r.hint})`)}`:``}`,`${p}${o(`dim`,d)} `,`${p}${o(`dim`,d)}${o(`cyan`,J)} `,`${p}${o(`dim`,f)} `);if(i===`group-active`)return z(e.output,s,`${p}${d} `,`${p}${d}${o(`cyan`,J)} `,`${p}${f} `,e=>o(`dim`,e));if(i===`group-active-selected`)return z(e.output,s,`${p}${d} `,`${p}${d}${o(`green`,Y)} `,`${p}${f} `,e=>o(`dim`,e));if(i===`selected`){let n=c||t?o(`green`,Y):``;return z(e.output,`${s}${r.hint?` (${r.hint})`:``}`,`${p}${o(`dim`,d)} `,`${p}${o(`dim`,d)}${n} `,`${p}${o(`dim`,f)} `,e=>o(`dim`,e))}if(i===`cancelled`)return`${o([`strikethrough`,`dim`],s)}`;if(i===`active-selected`)return z(e.output,`${s}${r.hint?` ${o(`dim`,`(${r.hint})`)}`:``}`,`${p}${o(`dim`,d)} `,`${p}${o(`dim`,d)}${o(`green`,Y)} `,`${p}${o(`dim`,f)} `);if(i===`submitted`)return`${o(`dim`,s)}`;let m=c||t?o(`dim`,Fe):``;return z(e.output,s,`${p}${o(`dim`,d)} `,`${p}${o(`dim`,d)}${m} `,`${p}${o(`dim`,f)} `,e=>o(`dim`,e))},i=e.required??!0,a=e.showInstructions??!0;return new ke({options:e.options,signal:e.signal,input:e.input,output:e.output,initialValues:e.initialValues,required:i,cursorAt:e.cursorAt,selectableGroups:t,validate(e){if(i&&(e===void 0||e.length===0))return`Please select at least one option.
|
|
28
|
+
${o(`reset`,o(`dim`,`Press ${o([`gray`,`bgWhite`,`inverse`],` space `)} to select, ${o(`gray`,o([`bgWhite`,`inverse`],` enter `))} to submit`))}`},render(){let t=e.withGuide??F.withGuide,n=`${t?`${o(`gray`,W)}
|
|
29
|
+
`:``}${X(this.state)} ${e.message}
|
|
30
|
+
`,i=this.value??[],s=(e,t)=>{let n=this.options,a=i.includes(e.value)||e.group===!0&&this.isGroupSelected(`${e.value}`);return!t&&typeof e.group==`string`&&this.options[this.cursor]?.value===e.group?r(e,a?`group-active-selected`:`group-active`,n):t&&a?r(e,`active-selected`,n):a?r(e,`selected`,n):r(e,t?`active`:`inactive`,n)};switch(this.state){case`submit`:{let e=this.options.filter(({value:e})=>i.includes(e)).map(e=>r(e,`submitted`)),a=e.length===0?``:` ${e.join(o(`dim`,`, `))}`;return`${n}${t?o(`gray`,W):``}${a}`}case`cancel`:{let e=this.options.filter(({value:e})=>i.includes(e)).map(e=>r(e,`cancelled`)).join(o(`dim`,`, `));return`${n}${t?`${o(`gray`,W)} `:``}${e.trim()?`${e}${t?`
|
|
31
|
+
${o(`gray`,W)}`:``}`:``}`}case`error`:{let r=t?`${o(`yellow`,W)} `:``,i=this.error.split(`
|
|
32
|
+
`).map((e,n)=>n===0?`${t?`${o(`yellow`,G)} `:``}${o(`yellow`,e)}`:` ${e}`).join(`
|
|
33
|
+
`),a=n.split(`
|
|
34
|
+
`).length,c=i.split(`
|
|
35
|
+
`).length+1;return`${n}${r}${Ue({output:e.output,options:this.options,cursor:this.cursor,maxItems:e.maxItems,columnPadding:r.length,rowPadding:a+c,style:s}).join(`
|
|
36
|
+
${r}`)}
|
|
37
|
+
${i}
|
|
38
|
+
`}default:{let r=t?`${o(`cyan`,W)} `:``,i=n.split(`
|
|
39
|
+
`).length,c=a?Ve(Ge,t):t?[o(`cyan`,G)]:[],l=c.join(`
|
|
40
|
+
`),u=c.length+1;return`${n}${r}${Ue({output:e.output,options:this.options,cursor:this.cursor,maxItems:e.maxItems,columnPadding:r.length,rowPadding:i+u,style:s}).join(`
|
|
41
|
+
${r}`)}
|
|
42
|
+
${l}
|
|
43
|
+
`}}}}).prompt()},qe=(e=``,t)=>{let n=t?.output??process.stdout,r=t?.withGuide??F.withGuide?`${o(`gray`,G)} `:``;n.write(`${r}${o(`red`,e)}
|
|
23
44
|
|
|
24
|
-
`)},
|
|
25
|
-
`),a=i.reduce((e,t)=>Math.max(
|
|
26
|
-
`).map(a),``],l=
|
|
27
|
-
`),f=i?`${o(`gray`,
|
|
28
|
-
`:``,p=i?
|
|
45
|
+
`)},Je=e=>e,Ye=(e,t,n)=>{let r={hard:!0,trim:!1},i=N(e,t,r).split(`
|
|
46
|
+
`),a=i.reduce((e,t)=>Math.max(k(t),e),0);return N(e,t-(i.map(n).reduce((e,t)=>Math.max(k(t),e),0)-a),r)},Xe=(e=``,t=``,n)=>{let r=n?.output??s.stdout,i=n?.withGuide??F.withGuide,a=n?.format??Je,c=[``,...Ye(e,R(r)-6,a).split(`
|
|
47
|
+
`).map(a),``],l=k(t),u=Math.max(c.reduce((e,t)=>{let n=k(t);return n>e?n:e},0),l)+2,d=c.map(e=>`${o(`gray`,W)} ${e}${` `.repeat(u-k(e))}${o(`gray`,W)}`).join(`
|
|
48
|
+
`),f=i?`${o(`gray`,W)}
|
|
49
|
+
`:``,p=i?Re:Be;r.write(`${f}${o(`green`,U)} ${o(`reset`,t)} ${o(`gray`,Ie.repeat(Math.max(u-l-1,1))+Le)}
|
|
29
50
|
${d}
|
|
30
|
-
${o(`gray`,p+
|
|
31
|
-
`)};`${o(`dim`,`↑/↓`)}`,`${o(`dim`,`Enter:`)}`,`${o(`gray`,
|
|
32
|
-
`:``}${
|
|
33
|
-
`,r=e.placeholder&&e.placeholder.length>0?o(`inverse`,e.placeholder[0])+o(`dim`,e.placeholder.slice(1)):o([`inverse`,`hidden`],`_`),i=this.userInput?this.userInputWithCursor:r,a=this.value??``;switch(this.state){case`validating`:{let e=t?`${o(`cyan`,
|
|
51
|
+
${o(`gray`,p+Ie.repeat(u+2)+ze)}
|
|
52
|
+
`)};`${o(`dim`,`↑/↓`)}`,`${o(`dim`,`Enter:`)}`,`${o(`gray`,W)}`;const Ze=e=>new Ae({validate:e.validate,placeholder:e.placeholder,defaultValue:e.defaultValue,initialValue:e.initialValue,output:e.output,signal:e.signal,input:e.input,render(){let t=e?.withGuide??F.withGuide,n=`${`${t?`${o(`gray`,W)}
|
|
53
|
+
`:``}${X(this.state)} `}${e.message}
|
|
54
|
+
`,r=e.placeholder&&e.placeholder.length>0?o(`inverse`,e.placeholder[0])+o(`dim`,e.placeholder.slice(1)):o([`inverse`,`hidden`],`_`),i=this.userInput?this.userInputWithCursor:r,a=this.value??``;switch(this.state){case`validating`:{let e=t?`${o(`cyan`,W)} `:``,r=t?o(`cyan`,G):``;return`${n}${e}${o(`dim`,i)}
|
|
34
55
|
${r} ${o(`dim`,`Validating...`)}
|
|
35
|
-
`}case`error`:{let e=this.error?` ${o(`yellow`,this.error)}`:``,r=t?`${o(`yellow`,
|
|
56
|
+
`}case`error`:{let e=this.error?` ${o(`yellow`,this.error)}`:``,r=t?`${o(`yellow`,W)} `:``,a=t?o(`yellow`,G):``;return`${n.trim()}
|
|
36
57
|
${r}${i}
|
|
37
58
|
${a}${e}
|
|
38
|
-
`}case`submit`:{let e=a?`${t?` `:``}${o(`dim`,a)}`:``;return`${n}${t?o(`gray`,
|
|
39
|
-
${r}`:``}`}default:return`${n}${t?`${o(`cyan`,
|
|
40
|
-
${t?o(`cyan`,
|
|
41
|
-
`}}}).prompt(),
|
|
59
|
+
`}case`submit`:{let e=a?`${t?` `:``}${o(`dim`,a)}`:``;return`${n}${t?o(`gray`,W):``}${e}`}case`cancel`:{let e=a?` ${o([`strikethrough`,`dim`],a)}`:``,r=t?o(`gray`,W):``;return`${n}${r}${e}${a.trim()?`
|
|
60
|
+
${r}`:``}`}default:return`${n}${t?`${o(`cyan`,W)} `:``}${i}
|
|
61
|
+
${t?o(`cyan`,G):``}
|
|
62
|
+
`}}}).prompt(),Qe=`my-app`;function $e(e,t){return{dir:e.dir??`my-app`,git:!e[`no-git`],install:!e[`no-install`],integrations:e.integrations===void 0?_(t):x(e.integrations,t)}}function et(e){if(!(e.yes||e.dir))return`Missing required <dir>. Pass a project directory or --yes to use the default.`}function tt(e,t){let n=[`pnpm create @draekien/d9-app`,/\s/.test(e.dir)?JSON.stringify(e.dir):e.dir,`--yes`];e.git||n.push(`--no-git`),e.install||n.push(`--no-install`);let r=_(t);return(e.integrations.length!==r.length||e.integrations.some(e=>!r.includes(e)))&&n.push(`--integrations ${e.integrations.join(`,`)||`none`}`),n.join(` `)}function nt(e,{output:t},n){Xe(tt(e,n),`To create a project with the same options`,{output:t})}async function rt(e,{input:t,output:n},r){let i=$e(e,r);return{dir:e.dir===void 0?Z(await Ze({message:`Where should the project be created?`,placeholder:Qe,defaultValue:Qe,input:t,output:n})):i.dir,git:e[`no-git`]?i.git:Z(await We({message:`Initialise a git repository?`,initialValue:!0,input:t,output:n})),install:e[`no-install`]?i.install:Z(await We({message:`Install dependencies?`,initialValue:!0,input:t,output:n})),integrations:e.integrations===void 0?Z(await Ke({message:`Which agent integrations do you want?`,options:it(r),initialValues:_(r),required:!1,input:t,output:n})):i.integrations}}function it(e){let t=[],n=[];for(let[r,i]of Object.entries(e))i.kind===`overlay`?n.push({value:r,hint:i.hint}):t.push({value:r,hint:i.kind===`http`?i.login:void 0});return{"MCP servers":t,"Optional agent files":n}}function Z(e){return Te(e)&&(qe(`Operation cancelled.`),process.exit(0)),e}const at=/* @__PURE__ */ new Set([`.git`,`.gitignore`,`.idea`,`.vscode`,`LICENSE`,`.DS_Store`]),ot=/* @__PURE__ */ new Set([`node_modules`,`favicon.ico`]);function st(e){return r.basename(r.resolve(e))}function ct(t){if(t.length===0)return`name length must be greater than zero`;if(t.length>214)return`name length must be at most 214 characters`;if(t!==t.trim())return`name cannot contain leading or trailing spaces`;if(t!==t.toLowerCase())return`name cannot contain uppercase letters`;if(t.startsWith(`.`))return`name cannot start with a period`;if(t.startsWith(`_`))return`name cannot start with an underscore`;if(encodeURIComponent(t)!==t||/[~)('!*]/.test(t))return`name can only contain URL-friendly characters`;if(ot.has(t)||e.includes(t))return`name is reserved`}function lt(e){return n.existsSync(e)?n.statSync(e).isDirectory()?n.readdirSync(e).filter(e=>!at.has(e)):[r.basename(e)]:[]}const ut=`Usage: create-d9-app <dir> [options]
|
|
42
63
|
|
|
43
64
|
Arguments:
|
|
44
65
|
<dir> Directory to create the project in; "." uses the current directory
|
|
@@ -47,7 +68,9 @@ Options:
|
|
|
47
68
|
--yes Accept every default and skip all prompts
|
|
48
69
|
--no-git Do not initialise a git repository or make the initial commit
|
|
49
70
|
--no-install Do not run pnpm install
|
|
71
|
+
--integrations <names>
|
|
72
|
+
Comma-separated agent integrations to configure, or "none"
|
|
50
73
|
--help Show this message
|
|
51
|
-
`,
|
|
52
|
-
${
|
|
53
|
-
`)}`),
|
|
74
|
+
`,Q=i(new URL(`../templates`,import.meta.url)),dt=r.join(Q,`base`);function ft(e,t){n.mkdirSync(t,{recursive:!0});for(let i of n.readdirSync(e,{withFileTypes:!0})){let a=r.join(e,i.name),o=r.join(t,C[i.name]??i.name);i.isDirectory()?ft(a,o):n.copyFileSync(a,o)}}function pt(e,t){let i=r.join(e,`package.json`),a=JSON.parse(n.readFileSync(i,`utf8`));a.name=t,n.writeFileSync(i,`${JSON.stringify(a,null,2)}\n`)}function $(e){process.stderr.write(`${e}\n`),process.exit(1)}async function mt(){let{values:e,positionals:n}=a({allowPositionals:!0,options:{yes:{type:`boolean`},"no-git":{type:`boolean`},"no-install":{type:`boolean`},integrations:{type:`string`},help:{type:`boolean`}}});if(e.help){process.stdout.write(ut);return}let i={dir:n[0],yes:e.yes,"no-git":e[`no-git`],"no-install":e[`no-install`],integrations:e.integrations},o=g(Q),s=te({stdin:process.stdin,stdout:process.stdout,env:process.env,yes:!!e.yes}),c=s?void 0:et(i);c&&(process.stderr.write(`${c}
|
|
75
|
+
${ut}`),process.exit(1));let l;try{l=s?await rt(i,{input:process.stdin,output:process.stdout},o):$e(i,o)}catch(e){$(e instanceof Error?e.message:String(e))}let u=r.resolve(l.dir),d=st(u),f=ct(d);f&&$(`Invalid package name "${d}" derived from the directory: ${f}.`);let p=lt(u);p.length>0&&$(`${u} is not empty. Remove these entries or choose another directory:\n${p.map(e=>` ${e}`).join(`
|
|
76
|
+
`)}`),ft(dt,u);let m=l.integrations;if(ie(Q,u,m),b(o,m,u),ee(o,m,u),pt(u,d),l.install){let e=t(`pnpm install`,{cwd:u,stdio:`inherit`,shell:!0});e.status!==0&&process.exit(e.status??1)}if(l.git){let e=h(u);e.ok||$(`git initialisation failed:\n${e.output}`)}process.stdout.write(`Created ${u}\n`),process.stdout.write(ne({targetDir:u,cwd:process.cwd(),install:l.install})),s&&nt(l,{input:process.stdin,output:process.stdout},o)}await mt();export{};
|
package/package.json
CHANGED
|
@@ -1,8 +1,24 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@draekien/create-d9-app",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.6",
|
|
4
4
|
"type": "module",
|
|
5
|
-
"description": "Scaffold a Turborepo monorepo with
|
|
5
|
+
"description": "Scaffold a Turborepo monorepo with TanStack Start, React, TypeScript, Biome, Tailwind, shadcn and pnpm, set up for AI coding agents",
|
|
6
|
+
"keywords": [
|
|
7
|
+
"create",
|
|
8
|
+
"scaffold",
|
|
9
|
+
"template",
|
|
10
|
+
"monorepo",
|
|
11
|
+
"turborepo",
|
|
12
|
+
"pnpm",
|
|
13
|
+
"tanstack",
|
|
14
|
+
"tanstack-start",
|
|
15
|
+
"react",
|
|
16
|
+
"typescript",
|
|
17
|
+
"biome",
|
|
18
|
+
"tailwind",
|
|
19
|
+
"shadcn",
|
|
20
|
+
"agents"
|
|
21
|
+
],
|
|
6
22
|
"license": "MIT",
|
|
7
23
|
"repository": {
|
|
8
24
|
"type": "git",
|