create-bascik 1.0.0-rc.1 → 1.0.0-rc.11
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 +84 -8
- package/dist/agent-setup.d.ts +164 -0
- package/dist/agent-setup.js +430 -0
- package/dist/agent-setup.js.map +1 -0
- package/dist/cli.d.ts +31 -1
- package/dist/cli.js +140 -2
- package/dist/cli.js.map +1 -1
- package/dist/index.js +98 -27
- package/dist/index.js.map +1 -1
- package/dist/npm.d.ts +26 -0
- package/dist/npm.js +26 -0
- package/dist/npm.js.map +1 -0
- package/dist/scaffold.d.ts +114 -23
- package/dist/scaffold.js +678 -233
- package/dist/scaffold.js.map +1 -1
- package/dist/vscode-settings.d.ts +49 -0
- package/dist/vscode-settings.js +293 -0
- package/dist/vscode-settings.js.map +1 -0
- package/package.json +18 -10
- package/src/agent-setup.ts +555 -0
- package/src/cli.ts +184 -3
- package/src/index.ts +134 -26
- package/src/npm.ts +64 -0
- package/src/scaffold.ts +816 -275
- package/src/vscode-settings.ts +333 -0
- package/assets/SKILL.md +0 -2025
- package/src/scaffold.integration.test.ts +0 -210
- package/src/scaffold.test.ts +0 -494
- package/src/skill-sync.test.ts +0 -17
package/README.md
CHANGED
|
@@ -3,35 +3,40 @@
|
|
|
3
3
|
[](https://github.com/bascikdev/bascik/blob/main/create/test-coverage.json)
|
|
4
4
|
[](https://github.com/bascikdev/bascik/blob/main/create/test-coverage.json)
|
|
5
5
|
|
|
6
|
-
Interactive project initializer for [Bascik](https://bascik.dev).
|
|
6
|
+
Interactive project initializer for [Bascik](https://bascik.dev): the command behind `npm create bascik`. Use it to start a new Bascik site with a working starter, editor settings, tests, and the agent skills. Requires Node.js 22.22 or newer. The [Getting Started guide](https://bascik.dev/getting-started) walks through the result, and [Create App internals](https://bascik.dev/internals/create-app) explains how the scaffolder works.
|
|
7
7
|
|
|
8
8
|
## Quick Start
|
|
9
9
|
|
|
10
10
|
Scaffold a new Bascik project in one command:
|
|
11
11
|
|
|
12
12
|
```sh
|
|
13
|
-
npm create bascik@
|
|
13
|
+
npm create bascik@rc my-site -y
|
|
14
14
|
```
|
|
15
15
|
|
|
16
16
|
Pass a project name as an argument or run without arguments to be prompted:
|
|
17
17
|
|
|
18
18
|
```sh
|
|
19
|
-
npm create bascik@
|
|
19
|
+
npm create bascik@rc
|
|
20
20
|
```
|
|
21
21
|
|
|
22
|
+
The name is a new folder under the current one, such as `my-site` or `sites/my-site`; `.`, `..`, absolute paths and spaces are refused. A folder that already has one of the starter's files, such as `package.json` or `src/pages/index.html`, is refused before anything is written. To add Bascik to an existing project, see [Manual Setup](https://bascik.dev/getting-started#manual-setup).
|
|
23
|
+
|
|
22
24
|
## What it scaffolds
|
|
23
25
|
|
|
24
26
|
`create-bascik` creates a complete, ready-to-run starter site:
|
|
25
27
|
|
|
26
28
|
```text
|
|
27
29
|
my-site/
|
|
28
|
-
├── .
|
|
29
|
-
├── .
|
|
30
|
+
├── AGENTS.md ← Project brief for coding assistants
|
|
31
|
+
├── CLAUDE.md ← Imports AGENTS.md for Claude Code
|
|
32
|
+
├── .agents/skills/ ← Bascik agent skills for Copilot, Cursor, Codex, and others (on Y)
|
|
33
|
+
├── .claude/skills/ ← The same skills for Claude Code (on Y)
|
|
30
34
|
├── .vscode/
|
|
31
35
|
│ ├── launch.json ← Debug launchers for dev server and tests
|
|
32
|
-
│
|
|
36
|
+
│ ├── extensions.json ← Recommends official Bascik extension
|
|
37
|
+
│ └── settings.json ← Stops false VS Code errors on pages with several scripts
|
|
33
38
|
├── src/
|
|
34
|
-
│ ├── components/ ← site-meta, site-header, site-footer,
|
|
39
|
+
│ ├── components/ ← site-meta, site-header, site-footer, feature-card, my-counter, contact-form
|
|
35
40
|
│ └── pages/ ← index.html, about.html, contact.html, 404.html, css/styles.css
|
|
36
41
|
├── package.json ← dev, build, lint, test, and e2e scripts
|
|
37
42
|
└── .gitignore
|
|
@@ -39,6 +44,23 @@ my-site/
|
|
|
39
44
|
|
|
40
45
|
The starter does not include `bascik.config.ts` because it uses Bascik's built-in defaults. Add a config only when the project needs non-default behavior.
|
|
41
46
|
|
|
47
|
+
## Agent skills
|
|
48
|
+
|
|
49
|
+
After scaffolding, `create-bascik` asks:
|
|
50
|
+
|
|
51
|
+
```text
|
|
52
|
+
Install the Bascik agent skills for coding assistants (Claude Code, Copilot, Cursor, Codex...)? (Y/n)
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Yes, the default and what `-y` answers, runs the [skills CLI](https://skills.sh) to install every [Bascik skill](https://bascik.dev/agent-skills) except the opt-in `bascik-refactor`, at the release tag matching the Bascik version scaffolded. `--no-skills` skips it. When you skip it, or the install fails, for example offline, the project is still created and the command to run later is printed, pinned to the same release tag.
|
|
56
|
+
|
|
57
|
+
| Flag | Effect |
|
|
58
|
+
| :------------- | :------------------------------------------------- |
|
|
59
|
+
| `-y`, `--yes` | Answer every question with its default |
|
|
60
|
+
| `--no-skills` | Do not install the agent skills |
|
|
61
|
+
| `--no-install` | Do not run `npm install`, nor start the dev server |
|
|
62
|
+
| `--no-dev` | Do not start the dev server |
|
|
63
|
+
|
|
42
64
|
After scaffolding:
|
|
43
65
|
|
|
44
66
|
```sh
|
|
@@ -46,7 +68,59 @@ cd my-site
|
|
|
46
68
|
npm run dev
|
|
47
69
|
```
|
|
48
70
|
|
|
49
|
-
Your site will be live at `http://localhost:8080
|
|
71
|
+
Your site will be live at `http://localhost:8080` for the default template, `http://127.0.0.1:8787` for Cloudflare, or `http://127.0.0.1:8888` for Netlify.
|
|
72
|
+
|
|
73
|
+
## Templates
|
|
74
|
+
|
|
75
|
+
Pick a starter with `--template <name>` (or `--template=<name>`). Without the flag, the interactive prompts ask whether the site deploys to Cloudflare Workers, then to Netlify; with `-y` and no flag, you get the default.
|
|
76
|
+
|
|
77
|
+
| Template | What you get |
|
|
78
|
+
| :----------- | :----------------------------------------------------------------------------------------------------------------------- |
|
|
79
|
+
| `default` | The static starter above. `static` is accepted as an alias. |
|
|
80
|
+
| `cloudflare` | The same starter plus the [Cloudflare adapter](https://bascik.dev/deployment/cloudflare), Wrangler, and an edge demo. |
|
|
81
|
+
| `netlify` | The same starter plus the [Netlify adapter](https://bascik.dev/deployment/netlify), a `netlify.toml`, and the edge demo. |
|
|
82
|
+
|
|
83
|
+
```sh
|
|
84
|
+
npm create bascik@rc my-site -- --template cloudflare
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
The `--` matters: npm keeps flags placed before it for itself and does not pass them on, so `--template` has to follow a `--`. `-y` is the exception, since `create-bascik` also reads npm's own `yes` setting (`npm create bascik@rc my-site -y -- --template cloudflare` skips every prompt).
|
|
88
|
+
|
|
89
|
+
The Cloudflare template differs from the default in these files only:
|
|
90
|
+
|
|
91
|
+
- `package.json`: `@bascik/adapter-cloudflare` and `wrangler` as dev dependencies; `dev` runs `bascik --target cloudflare` with source watching and browser live reload in the real local platform runtime; `build` runs `bascik --build --target cloudflare`; `preview` and `deploy` run Wrangler from the emitted `dist/.bascik/cloudflare/` folder.
|
|
92
|
+
- `src/pages/edge.html`: a page with a `data-bascik-server` script that the Worker renders on every request, linked from a fourth feature card on the home page.
|
|
93
|
+
- `src/api/hello.ts`: an API route served at `/api/hello`.
|
|
94
|
+
- `e2e/app.spec.ts`: one extra test covering the edge page.
|
|
95
|
+
- `.gitignore`: ignores `.wrangler/`.
|
|
96
|
+
|
|
97
|
+
After scaffolding a Cloudflare project:
|
|
98
|
+
|
|
99
|
+
```sh
|
|
100
|
+
npm run dev # watched workerd development on http://127.0.0.1:8787
|
|
101
|
+
npm run build # bascik --build --target cloudflare
|
|
102
|
+
npm run preview # run the bundle locally in workerd
|
|
103
|
+
npm run deploy # wrangler deploy
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
The Netlify template differs from the default in these files only:
|
|
107
|
+
|
|
108
|
+
- `package.json`: `@bascik/adapter-netlify` and `netlify-cli` as dev dependencies; `dev` runs `bascik --target netlify` with source watching and browser live reload through the locally installed Netlify Dev; `build` runs `bascik --build --target netlify && bascik-netlify-install`; `preview` and `deploy` run the Netlify CLI through `npx`.
|
|
109
|
+
- `netlify.toml`: builds with `npm run build`, publishes `publish/`, and uses Netlify's `URL` as the site URL unless `BASCIK_SITE_URL` is set.
|
|
110
|
+
- `src/pages/edge.html` and `src/api/hello.ts`: the edge demo and API route, run in the Netlify Function.
|
|
111
|
+
- `e2e/app.spec.ts`: one extra test covering the edge page.
|
|
112
|
+
- `.gitignore`: ignores `publish/` and `.netlify/`.
|
|
113
|
+
|
|
114
|
+
After scaffolding a Netlify project:
|
|
115
|
+
|
|
116
|
+
```sh
|
|
117
|
+
npm run dev # watched Netlify development on http://127.0.0.1:8888
|
|
118
|
+
npm run build # bascik --build --target netlify && bascik-netlify-install
|
|
119
|
+
npm run preview # netlify dev --dir publish
|
|
120
|
+
npm run deploy # netlify deploy --build --prod
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
Both adapter development workflows use a local HTTP-only proxy; `--port` and `--host` override its public address. A rebuild or failed build may return 503, but the watcher stays alive and retries after the next source edit. Live reload is injected only by that proxy, never into production artifacts. `preview` remains a production-output workflow without Bascik's source watcher, and bare `bascik` remains the Node development server.
|
|
50
124
|
|
|
51
125
|
## Development & Testing
|
|
52
126
|
|
|
@@ -58,3 +132,5 @@ yarn create:typecheck # TypeScript type check
|
|
|
58
132
|
yarn create:unit # run unit tests
|
|
59
133
|
yarn create:coverage # run unit tests with coverage report
|
|
60
134
|
```
|
|
135
|
+
|
|
136
|
+
The integration tests compile scaffolded projects with the built framework and Cloudflare adapter, so run `yarn pkg:build && yarn adapter:cf:build` first (CI does the same).
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module agent-setup
|
|
3
|
+
*
|
|
4
|
+
* Sets a new Bascik project up for coding assistants:
|
|
5
|
+
*
|
|
6
|
+
* - `AGENTS.md` is a short project brief that GitHub Copilot, Cursor, Codex,
|
|
7
|
+
* Gemini CLI and others read: the commands, the house rules, and where the
|
|
8
|
+
* agent skills live.
|
|
9
|
+
* - `CLAUDE.md` imports that brief with `@AGENTS.md`. Claude Code reads
|
|
10
|
+
* CLAUDE.md, and skips AGENTS.md when a CLAUDE.md exists, so the import is
|
|
11
|
+
* what makes every assistant read the same brief.
|
|
12
|
+
* - The Bascik agent skills are installed with the skills CLI
|
|
13
|
+
* (https://skills.sh) into `.agents/skills/` and `.claude/skills/`, pinned
|
|
14
|
+
* to the Bascik version being set up. The opt-in `bascik-refactor` skill is
|
|
15
|
+
* left out.
|
|
16
|
+
*
|
|
17
|
+
* Existing AGENTS.md and CLAUDE.md files are merged, never replaced. A skills
|
|
18
|
+
* install that fails, such as when offline, never fails the setup: the report
|
|
19
|
+
* says which command to run later.
|
|
20
|
+
*
|
|
21
|
+
* Two identical copies exist, `create/src/agent-setup.ts` for
|
|
22
|
+
* `npm create bascik` and `pkg/src/lib/agent-setup.ts` for `bascik init`.
|
|
23
|
+
* `create/src/agent-setup.test.ts` fails when they differ.
|
|
24
|
+
*/
|
|
25
|
+
import { type SpawnSyncOptions, type SpawnSyncReturns } from "node:child_process";
|
|
26
|
+
/** The GitHub repository the skills CLI installs the Bascik skills from. */
|
|
27
|
+
export declare const SKILLS_REPO = "bascikdev/bascik";
|
|
28
|
+
/**
|
|
29
|
+
* The skills CLI, pinned so its flags cannot change under a released
|
|
30
|
+
* create-bascik. 1.7.4 needs Node 22.20, below Bascik's 22.22 floor.
|
|
31
|
+
*/
|
|
32
|
+
export declare const SKILLS_CLI = "skills@1.7.4";
|
|
33
|
+
/** The skills CLI agents whose folders a project gets, in SKILL_DESTINATIONS order. */
|
|
34
|
+
export declare const SKILL_AGENTS: readonly ["universal", "claude-code"];
|
|
35
|
+
/**
|
|
36
|
+
* Project directories that receive the agent skills. `.agents/skills` is the shared location read by GitHub
|
|
37
|
+
* Copilot, Cursor, Codex, Gemini CLI, OpenCode, and others; Claude Code reads `.claude/skills`.
|
|
38
|
+
*/
|
|
39
|
+
export declare const SKILL_DESTINATIONS: readonly [".agents/skills", ".claude/skills"];
|
|
40
|
+
/**
|
|
41
|
+
* The skills a new project gets. The skills CLI has no way to leave one out
|
|
42
|
+
* and silently ignores a name it does not know, so this is the full list of
|
|
43
|
+
* the repository's `skills/` folders minus OPT_IN_SKILLS, and a test keeps it
|
|
44
|
+
* that way.
|
|
45
|
+
*/
|
|
46
|
+
export declare const PROJECT_SKILLS: readonly ["bascik", "bascik-compatibility", "bascik-components", "bascik-config", "bascik-migrate", "bascik-scripts", "bascik-seo", "bascik-testing"];
|
|
47
|
+
/** Skills readers install on purpose with `--skill <name>`. */
|
|
48
|
+
export declare const OPT_IN_SKILLS: readonly ["bascik-refactor"];
|
|
49
|
+
export declare const SKILLS_QUESTION = "Install the Bascik agent skills for coding assistants (Claude Code, Copilot, Cursor, Codex...)? (Y/n) ";
|
|
50
|
+
/**
|
|
51
|
+
* Replaces the GitHub source, such as with a local checkout of the
|
|
52
|
+
* repository, so tests install without the network. Used as given: no
|
|
53
|
+
* version pin and no fallback.
|
|
54
|
+
*/
|
|
55
|
+
export declare const SKILLS_SOURCE_ENV = "BASCIK_SKILLS_SOURCE";
|
|
56
|
+
/** The git tag the skills for `version` are released under, or undefined when it is not a release version. */
|
|
57
|
+
export declare function skillsRef(version: string | undefined): string | undefined;
|
|
58
|
+
/** The arguments after `npx skills` that install the project skills from `source`. */
|
|
59
|
+
export declare function skillsAddArgs(source: string): string[];
|
|
60
|
+
/** The command a reader runs to install the project skills, at `ref` when given. */
|
|
61
|
+
export declare function skillsCommand(ref?: string): string;
|
|
62
|
+
type SpawnSyncFunction = (command: string, args: string[], options: SpawnSyncOptions) => SpawnSyncReturns<Buffer | string>;
|
|
63
|
+
/**
|
|
64
|
+
* The command that runs `npx <args>`. On Windows `npx` is `npx.cmd`, which
|
|
65
|
+
* Node cannot start directly, so it goes through `cmd.exe` the way
|
|
66
|
+
* create-bascik's `npmInvocation` runs npm.
|
|
67
|
+
*/
|
|
68
|
+
export declare function npxInvocation(args: string[], platform?: NodeJS.Platform, env?: NodeJS.ProcessEnv): {
|
|
69
|
+
command: string;
|
|
70
|
+
args: string[];
|
|
71
|
+
};
|
|
72
|
+
/**
|
|
73
|
+
* The lines that give the command to run later: pinned to `ref` when there
|
|
74
|
+
* is one, so the skills match the Bascik version, and how to drop the pin if
|
|
75
|
+
* that tag does not exist yet.
|
|
76
|
+
*/
|
|
77
|
+
export declare function skillsLaterLines(ref: string | undefined): string[];
|
|
78
|
+
export interface SkillsInstallResult {
|
|
79
|
+
/**
|
|
80
|
+
* `pinned`: installed at the release tag. `latest`: the tag install failed
|
|
81
|
+
* and the default branch worked. `custom`: installed from SKILLS_SOURCE_ENV.
|
|
82
|
+
* `failed`: nothing was installed.
|
|
83
|
+
*/
|
|
84
|
+
status: "pinned" | "latest" | "custom" | "failed";
|
|
85
|
+
/** The release tag that was tried, when the version had one. */
|
|
86
|
+
ref?: string;
|
|
87
|
+
/** Why the last attempt failed. */
|
|
88
|
+
error?: string;
|
|
89
|
+
/** The command to run later, when status is `failed`, pinned to `ref` when there is one. */
|
|
90
|
+
command: string;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Install the project skills into `cwd` with the skills CLI: at the release
|
|
94
|
+
* tag for `version` first, then from the default branch. Output is captured
|
|
95
|
+
* so a failed first attempt does not alarm anyone. Never throws.
|
|
96
|
+
*/
|
|
97
|
+
export declare function installSkills(cwd: string, options?: {
|
|
98
|
+
version?: string;
|
|
99
|
+
platform?: NodeJS.Platform;
|
|
100
|
+
env?: NodeJS.ProcessEnv;
|
|
101
|
+
spawn?: SpawnSyncFunction;
|
|
102
|
+
}): SkillsInstallResult;
|
|
103
|
+
/** What to tell the user about a skills install, one line per entry. */
|
|
104
|
+
export declare function skillsReportLines(result: SkillsInstallResult): string[];
|
|
105
|
+
/** The heading of the Bascik section, which is how a merge finds it again. */
|
|
106
|
+
export declare const AGENTS_SECTION_HEADING = "## Bascik";
|
|
107
|
+
/** The line in CLAUDE.md that imports the brief. Claude Code skips it inside code. */
|
|
108
|
+
export declare const CLAUDE_IMPORT = "@AGENTS.md";
|
|
109
|
+
export interface AgentsOptions {
|
|
110
|
+
template?: "default" | "cloudflare" | "netlify";
|
|
111
|
+
/**
|
|
112
|
+
* The commands that run the Bascik dev server and build, when the
|
|
113
|
+
* project's `dev` and `build` npm scripts do not, such as `bascik init` in
|
|
114
|
+
* a project whose scripts run another tool. Default: `npm run dev` and
|
|
115
|
+
* `npm run build`.
|
|
116
|
+
*/
|
|
117
|
+
commands?: {
|
|
118
|
+
dev?: string;
|
|
119
|
+
build?: string;
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
/** The Bascik section of AGENTS.md, added on its own to an AGENTS.md that has none. */
|
|
123
|
+
export declare function agentsSection(options?: AgentsOptions): string;
|
|
124
|
+
/** A new project's AGENTS.md. */
|
|
125
|
+
export declare function agentsMd(options?: AgentsOptions): string;
|
|
126
|
+
/** A new project's CLAUDE.md: the import line, then room for notes only Claude Code needs. */
|
|
127
|
+
export declare const CLAUDE_MD = "@AGENTS.md\n\n<!-- Claude Code reads this file instead of AGENTS.md, so the line above imports the shared brief. Add notes only Claude Code needs below. -->\n";
|
|
128
|
+
export type AgentFileStatus = "created" | "updated" | "unchanged" | "failed";
|
|
129
|
+
export interface AgentFilesReport {
|
|
130
|
+
agents: AgentFileStatus;
|
|
131
|
+
claude: AgentFileStatus;
|
|
132
|
+
}
|
|
133
|
+
/** Add the Bascik section to an AGENTS.md, keeping what is there. */
|
|
134
|
+
export declare function mergeAgentsMd(existing: string | undefined, options?: AgentsOptions): {
|
|
135
|
+
status: "created" | "updated" | "unchanged";
|
|
136
|
+
text: string;
|
|
137
|
+
};
|
|
138
|
+
/** Add the `@AGENTS.md` import to a CLAUDE.md, keeping what is there. */
|
|
139
|
+
export declare function mergeClaudeMd(existing: string | undefined): {
|
|
140
|
+
status: "created" | "updated" | "unchanged";
|
|
141
|
+
text: string;
|
|
142
|
+
};
|
|
143
|
+
/**
|
|
144
|
+
* Write or merge AGENTS.md and CLAUDE.md in `root`. Never throws; the report
|
|
145
|
+
* says what happened to each file.
|
|
146
|
+
*/
|
|
147
|
+
export declare function writeAgentFiles(root: string, options?: AgentsOptions): Promise<AgentFilesReport>;
|
|
148
|
+
/** Lines worth showing the user: what was added to an existing file, and what to fix by hand. */
|
|
149
|
+
export declare function agentFilesReportLines(report: AgentFilesReport): string[];
|
|
150
|
+
/** Whether an answer to a "(Y/n)" question is no. Anything else, including Enter, is yes. */
|
|
151
|
+
export declare function answeredNo(answer: string): boolean;
|
|
152
|
+
export interface Prompter {
|
|
153
|
+
/** Print `question` and resolve with the next line, or "" once input has ended. */
|
|
154
|
+
ask(question: string): Promise<string>;
|
|
155
|
+
close(): void;
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Ask questions on a terminal or a pipe. Lines that arrive before their
|
|
159
|
+
* question, as when answers are piped in, are kept for it, and once input
|
|
160
|
+
* ends (stdin closed, or `</dev/null`) every question gets "", its default,
|
|
161
|
+
* so a run without a terminal never hangs or dies mid-way.
|
|
162
|
+
*/
|
|
163
|
+
export declare function createPrompter(input?: NodeJS.ReadableStream, output?: NodeJS.WritableStream): Prompter;
|
|
164
|
+
export {};
|