vite-plus 0.1.0-alpha.0 → 0.1.1-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +41 -21
- package/README.md +104 -29
- package/dist/bin.d.ts +1 -1
- package/dist/bin.js +55 -18
- package/dist/config/agent.d.ts +9 -0
- package/dist/config/agent.js +190 -0
- package/dist/config/bin.d.ts +1 -0
- package/dist/config/bin.js +79 -0
- package/dist/config/hooks.d.ts +6 -0
- package/dist/config/hooks.js +101 -0
- package/dist/global/browser-CY4NBwxR.js +6500 -0
- package/dist/global/browser-DFpJ6sKb.js +3 -0
- package/dist/global/chunk-CtfvYSle.js +48 -0
- package/dist/global/cli-truncate-BxinOqz5.js +187 -0
- package/dist/global/{init.js → config.js} +212 -56
- package/dist/global/create.js +35 -11
- package/dist/global/{help-DeHOTK5z.js → json-Bfvtp2rL.js} +20 -71
- package/dist/global/lib-CibYHP32.js +99 -0
- package/dist/global/log-update-DdU6_LCN.js +583 -0
- package/dist/global/migrate.js +47 -18
- package/dist/global/package-Pq2biU7_.js +47 -0
- package/dist/global/{agent-BQgTGptV.js → prompts-CAIahN1u.js} +274 -149
- package/dist/global/slice-ansi-BhwAwMdF.js +144 -0
- package/dist/global/src-C6aLHRsS.js +331 -0
- package/dist/global/staged.js +9036 -0
- package/dist/global/strip-ansi-BL-dgd7n.js +245 -0
- package/dist/global/terminal-Cb-NuRkb.js +102 -0
- package/dist/global/version.js +35 -13
- package/dist/global/{workspace-DxLkU2Bw.js → workspace-De4OKHV7.js} +606 -6913
- package/dist/global/wrap-ansi-BJxjUEQR.js +4 -0
- package/dist/global/wrap-ansi-Iww6Ak1s.js +208 -0
- package/dist/index.d.ts +2 -0
- package/dist/init-config.d.ts +20 -0
- package/dist/init-config.js +210 -0
- package/dist/pack-bin.js +2 -2
- package/dist/resolve-vite-config.d.ts +4 -0
- package/dist/resolve-vite-config.js +11 -4
- package/dist/staged/bin.d.ts +1 -0
- package/dist/staged/bin.js +183 -0
- package/dist/staged-config.d.ts +1 -0
- package/dist/staged-config.js +0 -0
- package/dist/utils/agent.d.ts +2 -1
- package/dist/utils/agent.js +21 -11
- package/dist/utils/prompts.d.ts +5 -1
- package/dist/utils/prompts.js +29 -2
- package/package.json +12 -11
- package/rules/vite-prepare.yml +8 -0
- package/rules/vite-tools.yml +10 -0
- package/dist/global/terminal-dIO5Uf8n.js +0 -96
package/AGENTS.md
CHANGED
|
@@ -2,43 +2,62 @@
|
|
|
2
2
|
|
|
3
3
|
# Using Vite+, the Unified Toolchain for the Web
|
|
4
4
|
|
|
5
|
-
This project is using Vite+, a
|
|
5
|
+
This project is using Vite+, a unified toolchain built on top of Vite, Rolldown, Vitest, tsdown, Oxlint, Oxfmt, and Vite Task. Vite+ wraps runtime management, package management, and frontend tooling in a single global CLI called `vp`. Vite+ is distinct from Vite, but it invokes Vite through `vp dev` and `vp build`.
|
|
6
6
|
|
|
7
7
|
## Vite+ Workflow
|
|
8
8
|
|
|
9
9
|
`vp` is a global binary that handles the full development lifecycle. Run `vp help` to print a list of commands and `vp <command> --help` for information about a specific command.
|
|
10
10
|
|
|
11
|
-
###
|
|
11
|
+
### Start
|
|
12
|
+
|
|
13
|
+
- create - Create a new project from a template
|
|
14
|
+
- migrate - Migrate an existing project to Vite+
|
|
15
|
+
- config - Configure hooks and agent integration
|
|
16
|
+
- staged - Run linters on staged files
|
|
17
|
+
- install (`i`) - Install dependencies
|
|
18
|
+
- env - Manage Node.js versions
|
|
19
|
+
|
|
20
|
+
### Develop
|
|
12
21
|
|
|
13
22
|
- dev - Run the development server
|
|
14
|
-
-
|
|
23
|
+
- check - Run format, lint, and TypeScript type checks
|
|
15
24
|
- lint - Lint code
|
|
16
|
-
- test - Run tests
|
|
17
25
|
- fmt - Format code
|
|
18
|
-
-
|
|
19
|
-
- lib - Build library
|
|
20
|
-
- migrate - Migrate an existing project to Vite+
|
|
21
|
-
- create - Create a new monorepo package (in-project) or a new project (global)
|
|
22
|
-
- exec - Execute a command in workspace packages (supports `--filter`, `-r`, `--parallel`)
|
|
23
|
-
- run - Run tasks from `package.json` scripts
|
|
26
|
+
- test - Run tests
|
|
24
27
|
|
|
25
|
-
|
|
28
|
+
### Execute
|
|
29
|
+
|
|
30
|
+
- run - Run monorepo tasks
|
|
31
|
+
- exec - Execute a command from local `node_modules/.bin`
|
|
32
|
+
- dlx - Execute a package binary without installing it as a dependency
|
|
33
|
+
- cache - Manage the task cache
|
|
34
|
+
|
|
35
|
+
### Build
|
|
26
36
|
|
|
27
|
-
|
|
37
|
+
- build - Build for production
|
|
38
|
+
- pack - Build libraries
|
|
39
|
+
- preview - Preview production build
|
|
40
|
+
|
|
41
|
+
### Manage Dependencies
|
|
28
42
|
|
|
29
43
|
Vite+ automatically detects and wraps the underlying package manager such as pnpm, npm, or Yarn through the `packageManager` field in `package.json` or package manager-specific lockfiles.
|
|
30
44
|
|
|
31
|
-
- install - Install all dependencies, or add packages if package names are provided
|
|
32
45
|
- add - Add packages to dependencies
|
|
33
|
-
- remove - Remove packages from dependencies
|
|
34
|
-
-
|
|
35
|
-
-
|
|
36
|
-
- link - Link packages for local development
|
|
46
|
+
- remove (`rm`, `un`, `uninstall`) - Remove packages from dependencies
|
|
47
|
+
- update (`up`) - Update packages to latest versions
|
|
48
|
+
- dedupe - Deduplicate dependencies
|
|
37
49
|
- outdated - Check for outdated packages
|
|
50
|
+
- list (`ls`) - List installed packages
|
|
51
|
+
- why (`explain`) - Show why a package is installed
|
|
52
|
+
- info (`view`, `show`) - View package information from the registry
|
|
53
|
+
- link (`ln`) / unlink - Manage local package links
|
|
38
54
|
- pm - Forward a command to the package manager
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
55
|
+
|
|
56
|
+
### Maintain
|
|
57
|
+
|
|
58
|
+
- upgrade - Update `vp` itself to the latest version
|
|
59
|
+
|
|
60
|
+
These commands map to their corresponding tools. For example, `vp dev --port 3000` runs Vite's dev server and works the same as Vite. `vp test` runs JavaScript tests through the bundled Vitest. The version of all tools can be checked using `vp --version`. This is useful when researching documentation, features, and bugs.
|
|
42
61
|
|
|
43
62
|
## Common Pitfalls
|
|
44
63
|
|
|
@@ -46,11 +65,12 @@ Vite+ automatically detects and wraps the underlying package manager such as pnp
|
|
|
46
65
|
- **Always use Vite commands to run tools:** Don't attempt to run `vp vitest` or `vp oxlint`. They do not exist. Use `vp test` and `vp lint` instead.
|
|
47
66
|
- **Running scripts:** Vite+ commands take precedence over `package.json` scripts. If there is a `test` script defined in `scripts` that conflicts with the built-in `vp test` command, run it using `vp run test`.
|
|
48
67
|
- **Do not install Vitest, Oxlint, Oxfmt, or tsdown directly:** Vite+ wraps these tools. They must not be installed directly. You cannot upgrade these tools by installing their latest versions. Always use Vite+ commands.
|
|
68
|
+
- **Use Vite+ wrappers for one-off binaries:** Use `vp dlx` instead of package-manager-specific `dlx`/`npx` commands.
|
|
49
69
|
- **Import JavaScript modules from `vite-plus`:** Instead of importing from `vite` or `vitest`, all modules should be imported from the project's `vite-plus` dependency. For example, `import { defineConfig } from 'vite-plus';` or `import { expect, test, vi } from 'vite-plus/test';`. You must not install `vitest` to import test utilities.
|
|
50
70
|
- **Type-Aware Linting:** There is no need to install `oxlint-tsgolint`, `vp lint --type-aware` works out of the box.
|
|
51
71
|
|
|
52
72
|
## Review Checklist for Agents
|
|
53
73
|
|
|
54
74
|
- [ ] Run `vp install` after pulling remote changes and before getting started.
|
|
55
|
-
- [ ] Run `vp
|
|
75
|
+
- [ ] Run `vp check` and `vp test` to validate changes.
|
|
56
76
|
<!--VITE PLUS END-->
|
package/README.md
CHANGED
|
@@ -1,22 +1,26 @@
|
|
|
1
1
|
# VITE+(⚡︎) Local CLI
|
|
2
2
|
|
|
3
3
|
**The Unified Toolchain for the Web**
|
|
4
|
-
|
|
4
|
+
_runtime and package management, create, dev, check, test, build, pack, and monorepo task caching in a single dependency_
|
|
5
5
|
|
|
6
6
|
This package provides the project-local version of Vite+. The global `vite` command automatically delegates to this package for all project-specific tasks.
|
|
7
7
|
|
|
8
8
|
---
|
|
9
9
|
|
|
10
|
-
Vite+ combines [Vite](https://vite.dev/), [Vitest](https://vitest.dev/), [Oxlint](https://oxc.rs/docs/guide/usage/linter.html), [Oxfmt](https://oxc.rs/docs/guide/usage/formatter.html), [tsdown](https://tsdown.dev/) and [
|
|
10
|
+
Vite+ is the unified entry point for local web development. It combines [Vite](https://vite.dev/), [Vitest](https://vitest.dev/), [Oxlint](https://oxc.rs/docs/guide/usage/linter.html), [Oxfmt](https://oxc.rs/docs/guide/usage/formatter.html), [Rolldown](https://rolldown.rs/), [tsdown](https://tsdown.dev/), and [Vite Task](https://github.com/voidzero-dev/vite-task) into one zero-config toolchain that also manages runtime and package manager workflows:
|
|
11
11
|
|
|
12
|
-
-
|
|
13
|
-
-
|
|
14
|
-
-
|
|
15
|
-
-
|
|
16
|
-
-
|
|
17
|
-
-
|
|
12
|
+
- **`vp env`:** Manage Node.js globally and per project
|
|
13
|
+
- **`vp install`:** Install dependencies with automatic package manager detection
|
|
14
|
+
- **`vp dev`:** Run Vite's fast native ESM dev server with instant HMR
|
|
15
|
+
- **`vp check`:** Run formatting, linting, and type checks in one command
|
|
16
|
+
- **`vp test`:** Run tests through bundled Vitest
|
|
17
|
+
- **`vp build`:** Build applications for production with Vite + Rolldown
|
|
18
|
+
- **`vp run`:** Execute monorepo tasks with caching and dependency-aware scheduling
|
|
19
|
+
- **`vp pack`:** Build libraries for npm publishing or standalone app binaries
|
|
20
|
+
- **`vp create` / `vp migrate`:** Scaffold new projects and migrate existing ones
|
|
18
21
|
|
|
19
|
-
|
|
22
|
+
All of this is configured from your project root and works across Vite's framework ecosystem.
|
|
23
|
+
Vite+ is fully open-source under the MIT license.
|
|
20
24
|
|
|
21
25
|
## Getting Started
|
|
22
26
|
|
|
@@ -25,44 +29,115 @@ Install Vite+ globally as `vp`:
|
|
|
25
29
|
For Linux or macOS:
|
|
26
30
|
|
|
27
31
|
```bash
|
|
28
|
-
curl -fsSL https://
|
|
32
|
+
curl -fsSL https://viteplus.dev/install.sh | bash
|
|
29
33
|
```
|
|
30
34
|
|
|
31
35
|
For Windows:
|
|
32
36
|
|
|
33
37
|
```bash
|
|
34
|
-
irm https://
|
|
38
|
+
irm https://viteplus.dev/install.ps1 | iex
|
|
35
39
|
```
|
|
36
40
|
|
|
37
41
|
`vp` handles the full development lifecycle such as package management, development servers, linting, formatting, testing and building for production.
|
|
38
42
|
|
|
39
|
-
|
|
43
|
+
## Configuring Vite+
|
|
44
|
+
|
|
45
|
+
Vite+ can be configured using a single `vite.config.ts` at the root of your project:
|
|
46
|
+
|
|
47
|
+
```ts
|
|
48
|
+
import { defineConfig } from 'vite-plus';
|
|
49
|
+
|
|
50
|
+
export default defineConfig({
|
|
51
|
+
// Standard Vite configuration for dev/build/preview.
|
|
52
|
+
plugins: [],
|
|
53
|
+
|
|
54
|
+
// Vitest configuration.
|
|
55
|
+
test: {
|
|
56
|
+
include: ['src/**/*.test.ts'],
|
|
57
|
+
},
|
|
58
|
+
|
|
59
|
+
// Oxlint configuration.
|
|
60
|
+
lint: {
|
|
61
|
+
ignorePatterns: ['dist/**'],
|
|
62
|
+
},
|
|
63
|
+
|
|
64
|
+
// Oxfmt configuration.
|
|
65
|
+
fmt: {
|
|
66
|
+
semi: true,
|
|
67
|
+
singleQuote: true,
|
|
68
|
+
},
|
|
69
|
+
|
|
70
|
+
// Vite Task configuration.
|
|
71
|
+
run: {
|
|
72
|
+
tasks: {
|
|
73
|
+
'generate:icons': {
|
|
74
|
+
command: 'node scripts/generate-icons.js',
|
|
75
|
+
envs: ['ICON_THEME'],
|
|
76
|
+
},
|
|
77
|
+
},
|
|
78
|
+
},
|
|
79
|
+
|
|
80
|
+
// `vp staged` configuration.
|
|
81
|
+
staged: {
|
|
82
|
+
'*': 'vp check --fix',
|
|
83
|
+
},
|
|
84
|
+
});
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
This lets you keep the configuration for your development server, build, test, lint, format, task runner, and staged-file workflow in one place with type-safe config and shared defaults.
|
|
88
|
+
|
|
89
|
+
Use `vp migrate` to migrate to Vite+. It merges tool-specific config files such as `.oxlintrc*`, `.oxfmtrc*`, and lint-staged config into `vite.config.ts`.
|
|
90
|
+
|
|
91
|
+
### CLI Workflows (`vp help`)
|
|
92
|
+
|
|
93
|
+
#### Start
|
|
94
|
+
|
|
95
|
+
- **create** - Create a new project from a template
|
|
96
|
+
- **migrate** - Migrate an existing project to Vite+
|
|
97
|
+
- **config** - Configure hooks and agent integration
|
|
98
|
+
- **staged** - Run linters on staged files
|
|
99
|
+
- **install** (`i`) - Install dependencies
|
|
100
|
+
- **env** - Manage Node.js versions
|
|
101
|
+
|
|
102
|
+
#### Develop
|
|
40
103
|
|
|
41
104
|
- **dev** - Run the development server
|
|
42
|
-
- **
|
|
105
|
+
- **check** - Run format, lint, and type checks
|
|
43
106
|
- **lint** - Lint code
|
|
44
|
-
- **test** - Run tests
|
|
45
107
|
- **fmt** - Format code
|
|
46
|
-
- **
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
108
|
+
- **test** - Run tests
|
|
109
|
+
|
|
110
|
+
#### Execute
|
|
111
|
+
|
|
112
|
+
- **run** - Run monorepo tasks
|
|
113
|
+
- **exec** - Execute a command from local `node_modules/.bin`
|
|
114
|
+
- **dlx** - Execute a package binary without installing it as a dependency
|
|
115
|
+
- **cache** - Manage the task cache
|
|
116
|
+
|
|
117
|
+
#### Build
|
|
50
118
|
|
|
51
|
-
|
|
119
|
+
- **build** - Build for production
|
|
120
|
+
- **pack** - Build libraries
|
|
121
|
+
- **preview** - Preview production build
|
|
122
|
+
|
|
123
|
+
#### Manage Dependencies
|
|
52
124
|
|
|
53
|
-
Vite+ automatically
|
|
125
|
+
Vite+ automatically wraps your package manager (pnpm, npm, or Yarn) based on `packageManager` and lockfiles:
|
|
54
126
|
|
|
55
|
-
- **install** - Install all dependencies, or add packages if package names are provided
|
|
56
127
|
- **add** - Add packages to dependencies
|
|
57
|
-
- **remove** - Remove packages from dependencies
|
|
58
|
-
- **
|
|
59
|
-
- **
|
|
60
|
-
- **
|
|
61
|
-
- **
|
|
128
|
+
- **remove** (`rm`, `un`, `uninstall`) - Remove packages from dependencies
|
|
129
|
+
- **update** (`up`) - Update packages to latest versions
|
|
130
|
+
- **dedupe** - Deduplicate dependencies
|
|
131
|
+
- **outdated** - Check outdated packages
|
|
132
|
+
- **list** (`ls`) - List installed packages
|
|
133
|
+
- **why** (`explain`) - Show why a package is installed
|
|
134
|
+
- **info** (`view`, `show`) - View package metadata from the registry
|
|
135
|
+
- **link** (`ln`) / **unlink** - Manage local package links
|
|
62
136
|
- **pm** - Forward a command to the package manager
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
137
|
+
|
|
138
|
+
#### Maintain
|
|
139
|
+
|
|
140
|
+
- **upgrade** - Update `vp` itself to the latest version
|
|
66
141
|
|
|
67
142
|
### Scaffolding your first Vite+ project
|
|
68
143
|
|
package/dist/bin.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Unified entry point for both the local CLI (via bin/vp) and the global CLI (via Rust vp binary).
|
|
3
3
|
*
|
|
4
|
-
* Global commands (create, migrate,
|
|
4
|
+
* Global commands (create, migrate, config, mcp, staged, --version) are handled by rolldown-bundled modules.
|
|
5
5
|
* All other commands are delegated to the Rust core through NAPI bindings, which
|
|
6
6
|
* uses JavaScript tool resolver functions to locate tool binaries.
|
|
7
7
|
*
|
package/dist/bin.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Unified entry point for both the local CLI (via bin/vp) and the global CLI (via Rust vp binary).
|
|
3
3
|
*
|
|
4
|
-
* Global commands (create, migrate,
|
|
4
|
+
* Global commands (create, migrate, config, mcp, staged, --version) are handled by rolldown-bundled modules.
|
|
5
5
|
* All other commands are delegated to the Rust core through NAPI bindings, which
|
|
6
6
|
* uses JavaScript tool resolver functions to locate tool binaries.
|
|
7
7
|
*
|
|
@@ -9,7 +9,9 @@
|
|
|
9
9
|
* vite-plus installation using oxc_resolver and runs its dist/bin.js directly.
|
|
10
10
|
* If no local installation is found, this global dist/bin.js is used as fallback.
|
|
11
11
|
*/
|
|
12
|
+
import path from 'node:path';
|
|
12
13
|
import { run } from '../binding/index.js';
|
|
14
|
+
import { applyToolInitConfigToViteConfig, inspectInitCommand } from './init-config.js';
|
|
13
15
|
import { doc } from './resolve-doc.js';
|
|
14
16
|
import { fmt } from './resolve-fmt.js';
|
|
15
17
|
import { lint } from './resolve-lint.js';
|
|
@@ -17,6 +19,7 @@ import { pack } from './resolve-pack.js';
|
|
|
17
19
|
import { test } from './resolve-test.js';
|
|
18
20
|
import { resolveUniversalViteConfig } from './resolve-vite-config.js';
|
|
19
21
|
import { vite } from './resolve-vite.js';
|
|
22
|
+
import { accent, log } from './utils/terminal.js';
|
|
20
23
|
// Parse command line arguments
|
|
21
24
|
let args = process.argv.slice(2);
|
|
22
25
|
// Transform `vp help [command]` into `vp [command] --help`
|
|
@@ -35,9 +38,9 @@ else if (command === 'migrate') {
|
|
|
35
38
|
// @ts-ignore — rolldown output
|
|
36
39
|
await import('./global/migrate.js');
|
|
37
40
|
}
|
|
38
|
-
else if (command === '
|
|
41
|
+
else if (command === 'config') {
|
|
39
42
|
// @ts-ignore — rolldown output
|
|
40
|
-
await import('./global/
|
|
43
|
+
await import('./global/config.js');
|
|
41
44
|
}
|
|
42
45
|
else if (command === 'mcp') {
|
|
43
46
|
// @ts-ignore — rolldown output
|
|
@@ -47,23 +50,57 @@ else if (command === '--version' || command === '-V') {
|
|
|
47
50
|
// @ts-ignore — rolldown output
|
|
48
51
|
await import('./global/version.js');
|
|
49
52
|
}
|
|
53
|
+
else if (command === 'staged') {
|
|
54
|
+
// @ts-ignore — rolldown output
|
|
55
|
+
await import('./global/staged.js');
|
|
56
|
+
}
|
|
50
57
|
else {
|
|
51
58
|
// All other commands — delegate to Rust core via NAPI binding
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
59
|
+
try {
|
|
60
|
+
const initInspection = inspectInitCommand(command, args.slice(1));
|
|
61
|
+
if (initInspection.handled &&
|
|
62
|
+
initInspection.configKey &&
|
|
63
|
+
initInspection.hasExistingConfigKey &&
|
|
64
|
+
initInspection.existingViteConfigPath) {
|
|
65
|
+
log(`Skipped initialization: '${accent(initInspection.configKey)}' already exists in '${accent(path.basename(initInspection.existingViteConfigPath))}'.`);
|
|
66
|
+
process.exit(0);
|
|
67
|
+
}
|
|
68
|
+
const exitCode = await run({
|
|
69
|
+
lint,
|
|
70
|
+
pack,
|
|
71
|
+
fmt,
|
|
72
|
+
vite,
|
|
73
|
+
test,
|
|
74
|
+
doc,
|
|
75
|
+
resolveUniversalViteConfig,
|
|
76
|
+
args: process.argv.slice(2),
|
|
77
|
+
});
|
|
78
|
+
let finalExitCode = exitCode;
|
|
79
|
+
if (exitCode === 0) {
|
|
80
|
+
try {
|
|
81
|
+
const result = await applyToolInitConfigToViteConfig(command, args.slice(1));
|
|
82
|
+
if (result.handled &&
|
|
83
|
+
result.action === 'added' &&
|
|
84
|
+
result.configKey &&
|
|
85
|
+
result.viteConfigPath) {
|
|
86
|
+
log(`Added '${accent(result.configKey)}' to '${accent(path.basename(result.viteConfigPath))}'.`);
|
|
87
|
+
}
|
|
88
|
+
if (result.handled &&
|
|
89
|
+
result.action === 'skipped-existing' &&
|
|
90
|
+
result.configKey &&
|
|
91
|
+
result.viteConfigPath) {
|
|
92
|
+
log(`Skipped initialization: '${accent(result.configKey)}' already exists in '${accent(path.basename(result.viteConfigPath))}'.`);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
catch (err) {
|
|
96
|
+
console.error('[Vite+] Failed to initialize config in vite.config.ts:', err);
|
|
97
|
+
finalExitCode = 1;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
process.exit(finalExitCode);
|
|
101
|
+
}
|
|
102
|
+
catch (err) {
|
|
66
103
|
console.error('[Vite+] run error:', err);
|
|
67
104
|
process.exit(1);
|
|
68
|
-
}
|
|
105
|
+
}
|
|
69
106
|
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type AgentConfig } from '../utils/agent.js';
|
|
2
|
+
export interface AgentSetupSelection {
|
|
3
|
+
instructionFilePath: 'CLAUDE.md' | 'AGENTS.md';
|
|
4
|
+
agents: AgentConfig[];
|
|
5
|
+
}
|
|
6
|
+
export declare function resolveAgentSetup(root: string, interactive: boolean): Promise<AgentSetupSelection>;
|
|
7
|
+
export declare function hasExistingAgentInstructions(root: string): boolean;
|
|
8
|
+
export declare function injectAgentBlock(root: string, filePath: string): void;
|
|
9
|
+
export declare function setupMcpConfig(root: string, selectedAgents: AgentConfig[]): void;
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
2
|
+
import { dirname, join } from 'node:path';
|
|
3
|
+
import * as prompts from '@voidzero-dev/vite-plus-prompts';
|
|
4
|
+
import { detectAgents, getAgentById, } from '../utils/agent.js';
|
|
5
|
+
import { writeJsonFile, readJsonFile } from '../utils/json.js';
|
|
6
|
+
import { pkgRoot } from '../utils/path.js';
|
|
7
|
+
function detectInstructionFilePath(root, agentConfigs) {
|
|
8
|
+
if (agentConfigs.some((a) => a.skillsDir === '.claude/skills')) {
|
|
9
|
+
return 'CLAUDE.md';
|
|
10
|
+
}
|
|
11
|
+
if (existsSync(join(root, 'CLAUDE.md'))) {
|
|
12
|
+
return 'CLAUDE.md';
|
|
13
|
+
}
|
|
14
|
+
return 'AGENTS.md';
|
|
15
|
+
}
|
|
16
|
+
async function pickAgentWhenUndetected() {
|
|
17
|
+
const choice = await prompts.select({
|
|
18
|
+
message: 'Could not detect your coding agent. Which one are you using?',
|
|
19
|
+
options: [
|
|
20
|
+
{ value: 'claude-code', label: 'Claude Code' },
|
|
21
|
+
{ value: 'cursor', label: 'Cursor' },
|
|
22
|
+
{ value: 'codex', label: 'Codex' },
|
|
23
|
+
{ value: 'gemini-cli', label: 'Gemini CLI' },
|
|
24
|
+
{ value: 'generic', label: 'Generic' },
|
|
25
|
+
],
|
|
26
|
+
});
|
|
27
|
+
if (prompts.isCancel(choice)) {
|
|
28
|
+
prompts.cancel('Setup cancelled.');
|
|
29
|
+
process.exit(0);
|
|
30
|
+
}
|
|
31
|
+
if (choice === 'generic') {
|
|
32
|
+
return {
|
|
33
|
+
instructionFilePath: 'AGENTS.md',
|
|
34
|
+
agents: [],
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
const selected = getAgentById(choice);
|
|
38
|
+
if (!selected) {
|
|
39
|
+
return {
|
|
40
|
+
instructionFilePath: 'AGENTS.md',
|
|
41
|
+
agents: [],
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
return {
|
|
45
|
+
instructionFilePath: choice === 'claude-code' ? 'CLAUDE.md' : 'AGENTS.md',
|
|
46
|
+
agents: [selected],
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
export async function resolveAgentSetup(root, interactive) {
|
|
50
|
+
const detected = detectAgents(root);
|
|
51
|
+
if (detected.length > 0 || !interactive) {
|
|
52
|
+
return {
|
|
53
|
+
instructionFilePath: detectInstructionFilePath(root, detected),
|
|
54
|
+
agents: detected,
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
return pickAgentWhenUndetected();
|
|
58
|
+
}
|
|
59
|
+
// --- Version and template reading ---
|
|
60
|
+
function getOwnVersion() {
|
|
61
|
+
const pkg = JSON.parse(readFileSync(join(pkgRoot, 'package.json'), 'utf-8'));
|
|
62
|
+
if (typeof pkg.version !== 'string') {
|
|
63
|
+
throw new Error('vite-plus package.json is missing a "version" field');
|
|
64
|
+
}
|
|
65
|
+
return pkg.version;
|
|
66
|
+
}
|
|
67
|
+
function readAgentPrompt() {
|
|
68
|
+
return readFileSync(join(pkgRoot, 'AGENTS.md'), 'utf-8');
|
|
69
|
+
}
|
|
70
|
+
// --- Versioned injection ---
|
|
71
|
+
const MARKER_OPEN_RE = /<!--injected-by-vite-plus-v([\w.+-]+)-->/;
|
|
72
|
+
const MARKER_CLOSE = '<!--/injected-by-vite-plus-->';
|
|
73
|
+
const MARKER_BLOCK_RE = /<!--injected-by-vite-plus-v[\w.+-]+-->\n[\s\S]*?<!--\/injected-by-vite-plus-->/;
|
|
74
|
+
export function hasExistingAgentInstructions(root) {
|
|
75
|
+
for (const file of ['AGENTS.md', 'CLAUDE.md']) {
|
|
76
|
+
const fullPath = join(root, file);
|
|
77
|
+
if (existsSync(fullPath)) {
|
|
78
|
+
const content = readFileSync(fullPath, 'utf-8');
|
|
79
|
+
if (MARKER_OPEN_RE.test(content)) {
|
|
80
|
+
return true;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
return false;
|
|
85
|
+
}
|
|
86
|
+
export function injectAgentBlock(root, filePath) {
|
|
87
|
+
const fullPath = join(root, filePath);
|
|
88
|
+
const version = getOwnVersion();
|
|
89
|
+
const promptContent = readAgentPrompt();
|
|
90
|
+
const openMarker = `<!--injected-by-vite-plus-v${version}-->`;
|
|
91
|
+
const block = `${openMarker}\n${promptContent}\n${MARKER_CLOSE}`;
|
|
92
|
+
if (existsSync(fullPath)) {
|
|
93
|
+
const existing = readFileSync(fullPath, 'utf-8');
|
|
94
|
+
const match = existing.match(MARKER_OPEN_RE);
|
|
95
|
+
if (match) {
|
|
96
|
+
if (match[1] === version) {
|
|
97
|
+
prompts.log.info(`${filePath} already has Vite+ instructions (v${version})`);
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
// Replace existing block with updated version
|
|
101
|
+
const updated = existing.replace(MARKER_BLOCK_RE, block);
|
|
102
|
+
if (updated === existing) {
|
|
103
|
+
// Closing marker is missing or malformed — append fresh block
|
|
104
|
+
const separator = existing.endsWith('\n') ? '\n' : '\n\n';
|
|
105
|
+
writeFileSync(fullPath, existing + separator + block + '\n');
|
|
106
|
+
prompts.log.warn(`Existing Vite+ block in ${filePath} was malformed; appended fresh block`);
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
writeFileSync(fullPath, updated);
|
|
110
|
+
prompts.log.success(`Updated Vite+ instructions in ${filePath} (v${match[1]} → v${version})`);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
else {
|
|
114
|
+
// Append block to end of file
|
|
115
|
+
const separator = existing.endsWith('\n') ? '\n' : '\n\n';
|
|
116
|
+
writeFileSync(fullPath, existing + separator + block + '\n');
|
|
117
|
+
prompts.log.success(`Added Vite+ instructions to ${filePath}`);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
else {
|
|
121
|
+
writeFileSync(fullPath, block + '\n');
|
|
122
|
+
prompts.log.success(`Created ${filePath} with Vite+ instructions`);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
// --- MCP config ---
|
|
126
|
+
function writeMcpConfigForTarget(root, target) {
|
|
127
|
+
const fullPath = join(root, target.filePath);
|
|
128
|
+
let existing = {};
|
|
129
|
+
if (existsSync(fullPath)) {
|
|
130
|
+
try {
|
|
131
|
+
existing = readJsonFile(fullPath);
|
|
132
|
+
}
|
|
133
|
+
catch {
|
|
134
|
+
prompts.log.warn(`Could not parse ${target.filePath} — skipping MCP config. Please add the config manually.`);
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
if (!existing[target.rootKey]) {
|
|
139
|
+
existing[target.rootKey] = {};
|
|
140
|
+
}
|
|
141
|
+
if (existing[target.rootKey]['vite-plus']) {
|
|
142
|
+
prompts.log.info(`${target.filePath} already has vite-plus MCP config`);
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
existing[target.rootKey]['vite-plus'] = {
|
|
146
|
+
command: 'npx',
|
|
147
|
+
args: ['vp', 'mcp'],
|
|
148
|
+
...target.extraFields,
|
|
149
|
+
};
|
|
150
|
+
mkdirSync(dirname(fullPath), { recursive: true });
|
|
151
|
+
writeJsonFile(fullPath, existing);
|
|
152
|
+
prompts.log.success(`Added vite-plus MCP server to ${target.filePath}`);
|
|
153
|
+
}
|
|
154
|
+
function pickMcpTarget(root, targets) {
|
|
155
|
+
if (targets.length === 1) {
|
|
156
|
+
return targets[0];
|
|
157
|
+
}
|
|
158
|
+
return targets.find((t) => existsSync(join(root, t.filePath))) ?? targets[0];
|
|
159
|
+
}
|
|
160
|
+
export function setupMcpConfig(root, selectedAgents) {
|
|
161
|
+
if (selectedAgents.length === 0) {
|
|
162
|
+
prompts.note(JSON.stringify({
|
|
163
|
+
'vite-plus': {
|
|
164
|
+
command: 'npx',
|
|
165
|
+
args: ['vp', 'mcp'],
|
|
166
|
+
},
|
|
167
|
+
}, null, 2), 'Add this MCP server config to your agent');
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
const mcpAgents = [];
|
|
171
|
+
const hintAgents = [];
|
|
172
|
+
for (const agent of selectedAgents) {
|
|
173
|
+
if (agent.mcpConfig) {
|
|
174
|
+
mcpAgents.push({ agent, targets: agent.mcpConfig });
|
|
175
|
+
}
|
|
176
|
+
else if (agent.mcpHint) {
|
|
177
|
+
hintAgents.push({ agent, hint: agent.mcpHint });
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
// Print hints for agents without project-level config
|
|
181
|
+
for (const { agent, hint } of hintAgents) {
|
|
182
|
+
prompts.log.info(`${agent.displayName}: ${hint}`);
|
|
183
|
+
}
|
|
184
|
+
// Write config for agents with project-level support
|
|
185
|
+
for (const { agent, targets } of mcpAgents) {
|
|
186
|
+
const target = pickMcpTarget(root, targets);
|
|
187
|
+
prompts.log.info(`${agent.displayName} MCP target: ${target.filePath}`);
|
|
188
|
+
writeMcpConfigForTarget(root, target);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|