unplugin-devpilot 0.0.2 → 0.0.4
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 +105 -0
- package/dist/farm.d.mts +1 -1
- package/dist/farm.mjs +1 -1
- package/dist/{index-9V3dRAxA.d.mts → index-Csy16I0Z.d.mts} +16 -1
- package/dist/{index-CQudsm6j.d.mts → index-WH3owjvn.d.mts} +51 -2
- package/dist/index.d.mts +3 -3
- package/dist/index.mjs +3 -3
- package/dist/{plugin-BPkoZQbf.mjs → plugin-B1Afr0m3.mjs} +20 -2
- package/dist/plugin.d.mts +2 -2
- package/dist/plugin.mjs +2 -2
- package/dist/rspack.d.mts +1 -1
- package/dist/rspack.mjs +1 -1
- package/dist/{src-D62s1VAN.mjs → src-AEXLBOF9.mjs} +365 -38
- package/dist/vite.d.mts +1 -1
- package/dist/vite.mjs +1 -1
- package/dist/webpack.d.mts +1 -1
- package/dist/webpack.mjs +1 -1
- package/package.json +28 -3
package/README.md
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
# unplugin-devpilot
|
|
2
|
+
|
|
3
|
+
[![npm version][npm-version-src]][npm-version-href]
|
|
4
|
+
[![npm downloads][npm-downloads-src]][npm-downloads-href]
|
|
5
|
+
[![Unit Test][unit-test-src]][unit-test-href]
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm i -D unplugin-devpilot
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
<details>
|
|
14
|
+
<summary>Vite</summary><br>
|
|
15
|
+
|
|
16
|
+
```ts
|
|
17
|
+
// vite.config.ts
|
|
18
|
+
import Devpilot from 'unplugin-devpilot/vite';
|
|
19
|
+
|
|
20
|
+
export default defineConfig({
|
|
21
|
+
plugins: [Devpilot()],
|
|
22
|
+
});
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
<br></details>
|
|
26
|
+
|
|
27
|
+
<details>
|
|
28
|
+
<summary>Webpack</summary><br>
|
|
29
|
+
|
|
30
|
+
```js
|
|
31
|
+
// webpack.config.js
|
|
32
|
+
import Devpilot from 'unplugin-devpilot/webpack';
|
|
33
|
+
|
|
34
|
+
export default {
|
|
35
|
+
/* ... */
|
|
36
|
+
plugins: [Devpilot()],
|
|
37
|
+
};
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
<br></details>
|
|
41
|
+
|
|
42
|
+
<details>
|
|
43
|
+
<summary>Rspack</summary><br>
|
|
44
|
+
|
|
45
|
+
```ts
|
|
46
|
+
// rspack.config.js
|
|
47
|
+
import Devpilot from 'unplugin-devpilot/rspack';
|
|
48
|
+
|
|
49
|
+
export default {
|
|
50
|
+
/* ... */
|
|
51
|
+
plugins: [Devpilot()],
|
|
52
|
+
};
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
<br></details>
|
|
56
|
+
|
|
57
|
+
## Client Import
|
|
58
|
+
|
|
59
|
+
Add this import to your project entry point to enable the devpilot client:
|
|
60
|
+
|
|
61
|
+
```ts
|
|
62
|
+
// main.ts or main.js (entry point)
|
|
63
|
+
import 'virtual:devpilot-client';
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
This import activates the WebSocket connection to the development server and initializes all registered plugins on the client side.
|
|
67
|
+
|
|
68
|
+
## Configuration
|
|
69
|
+
|
|
70
|
+
You can customize the plugin behavior by passing options:
|
|
71
|
+
|
|
72
|
+
```ts
|
|
73
|
+
// vite.config.ts
|
|
74
|
+
import Devpilot from 'unplugin-devpilot/vite';
|
|
75
|
+
|
|
76
|
+
export default defineConfig({
|
|
77
|
+
plugins: [
|
|
78
|
+
Devpilot({
|
|
79
|
+
wsPort: 3100, // Optional: Specify WebSocket port (will be randomly allocated if not specified)
|
|
80
|
+
mcpPort: 3101, // Optional: Specify MCP server port (will use random port if specified port is occupied)
|
|
81
|
+
plugins: [], // Optional: Array of DevpilotPlugin instances
|
|
82
|
+
}),
|
|
83
|
+
],
|
|
84
|
+
});
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### Port Allocation Strategy
|
|
88
|
+
|
|
89
|
+
- **wsPort**: When provided, the specified port is used if available; otherwise, a random available port is allocated. When not provided, a random available port is automatically allocated
|
|
90
|
+
- **mcpPort**: When not provided, defaults to 3101. If the port is already in use, an error will be thrown
|
|
91
|
+
|
|
92
|
+
This ensures your MCP server runs on a predictable port. If the default port is occupied, you'll need to specify a different port or free up the occupied port.
|
|
93
|
+
|
|
94
|
+
## License
|
|
95
|
+
|
|
96
|
+
[MIT](./LICENSE) License © 2025-PRESENT [Huali](https://github.com/zcf0508)
|
|
97
|
+
|
|
98
|
+
<!-- Badges -->
|
|
99
|
+
|
|
100
|
+
[npm-version-src]: https://img.shields.io/npm/v/unplugin-devpilot.svg
|
|
101
|
+
[npm-version-href]: https://npmjs.com/package/unplugin-devpilot
|
|
102
|
+
[npm-downloads-src]: https://img.shields.io/npm/dm/unplugin-devpilot
|
|
103
|
+
[npm-downloads-href]: https://www.npmcharts.com/compare/unplugin-devpilot?interval=30
|
|
104
|
+
[unit-test-src]: https://github.com/zcf0508/unplugin-devpilot/actions/workflows/unit-test.yml/badge.svg
|
|
105
|
+
[unit-test-href]: https://github.com/zcf0508/unplugin-devpilot/actions/workflows/unit-test.yml
|
package/dist/farm.d.mts
CHANGED
package/dist/farm.mjs
CHANGED
|
@@ -1,3 +1,18 @@
|
|
|
1
|
+
//#region src/core/utils.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Resolve the module path relative to the plugin to an absolute path
|
|
4
|
+
* Handles cross-platform paths (Windows, macOS, Linux) and proper escaping for imports
|
|
5
|
+
* @param importMetaUrl - Pass in import.meta.url
|
|
6
|
+
* @param relativePath - Path relative to the plugin
|
|
7
|
+
* @example
|
|
8
|
+
* ```ts
|
|
9
|
+
* import { resolveModule } from 'unplugin-devpilot/core/utils'
|
|
10
|
+
*
|
|
11
|
+
* const skillPath = resolveModule(import.meta.url, './skill.md')
|
|
12
|
+
* ```
|
|
13
|
+
*/
|
|
14
|
+
declare function resolveModule(importMetaUrl: string, relativePath: string): string;
|
|
15
|
+
//#endregion
|
|
1
16
|
//#region ../../node_modules/.pnpm/zod@4.3.6/node_modules/zod/v3/helpers/typeAliases.d.cts
|
|
2
17
|
type Primitive$2 = string | number | symbol | bigint | boolean | null | undefined;
|
|
3
18
|
//#endregion
|
|
@@ -4128,4 +4143,4 @@ interface DevpilotPluginContext {
|
|
|
4128
4143
|
*/
|
|
4129
4144
|
declare function resolveClientModule(importMetaUrl: string, relativePath: string): string;
|
|
4130
4145
|
//#endregion
|
|
4131
|
-
export { defineMcpToolRegister as i, resolveClientModule as n, McpToolRegister as r, DevpilotPluginContext as t };
|
|
4146
|
+
export { resolveModule as a, defineMcpToolRegister as i, resolveClientModule as n, McpToolRegister as r, DevpilotPluginContext as t };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { r as McpToolRegister, t as DevpilotPluginContext } from "./index-
|
|
1
|
+
import { r as McpToolRegister, t as DevpilotPluginContext } from "./index-Csy16I0Z.mjs";
|
|
2
2
|
import { UnpluginInstance } from "unplugin";
|
|
3
3
|
import { WebSocket } from "ws";
|
|
4
4
|
|
|
@@ -25,11 +25,40 @@ interface DevpilotPlugin {
|
|
|
25
25
|
*/
|
|
26
26
|
serverSetup?: (ctx: DevpilotPluginContext) => Record<string, (...args: any[]) => any>;
|
|
27
27
|
mcpSetup?: (ctx: DevpilotPluginContext) => Array<McpToolRegister>;
|
|
28
|
+
/**
|
|
29
|
+
* The skill module path to be injected
|
|
30
|
+
* - npm package path: 'my-plugin/skill'
|
|
31
|
+
* - absolute path: '/path/to/skill.md'
|
|
32
|
+
*
|
|
33
|
+
* Note: relative paths need to be resolved to absolute paths first
|
|
34
|
+
* @example
|
|
35
|
+
* ```ts
|
|
36
|
+
* import { resolveSkillModule } from 'unplugin-devpilot'
|
|
37
|
+
*
|
|
38
|
+
* skillModule: resolveSkillModule(import.meta.url, './skill.md')
|
|
39
|
+
* ```
|
|
40
|
+
*/
|
|
41
|
+
skillModule?: string | ((ctx: DevpilotPluginContext) => string);
|
|
28
42
|
}
|
|
29
43
|
interface Options {
|
|
30
44
|
wsPort?: number;
|
|
31
45
|
mcpPort?: number;
|
|
32
46
|
plugins?: DevpilotPlugin[];
|
|
47
|
+
/**
|
|
48
|
+
* The path to generate the core skill file
|
|
49
|
+
* - directory path: './src/skills/devpilot' (will generate SKILL.md in this directory)
|
|
50
|
+
* - file path: './src/skills/devpilot/SKILL.md' (will generate the specified file)
|
|
51
|
+
*
|
|
52
|
+
* If not specified, no core skill file will be generated
|
|
53
|
+
* @example
|
|
54
|
+
* ```ts
|
|
55
|
+
* Devpilot({
|
|
56
|
+
* skillCorePath: './src/skills/devpilot',
|
|
57
|
+
* plugins: [],
|
|
58
|
+
* })
|
|
59
|
+
* ```
|
|
60
|
+
*/
|
|
61
|
+
skillCorePath?: string;
|
|
33
62
|
}
|
|
34
63
|
//#endregion
|
|
35
64
|
//#region ../../node_modules/.pnpm/birpc@4.0.0/node_modules/birpc/dist/index.d.mts
|
|
@@ -222,7 +251,27 @@ declare class ClientManager {
|
|
|
222
251
|
}
|
|
223
252
|
declare const clientManager: ClientManager;
|
|
224
253
|
//#endregion
|
|
254
|
+
//#region src/core/skill-generator.d.ts
|
|
255
|
+
/**
|
|
256
|
+
* Resolve the skill module path relative to the plugin to an absolute path
|
|
257
|
+
* Handles cross-platform paths (Windows, macOS, Linux) and proper escaping for imports
|
|
258
|
+
* @param importMetaUrl - Pass in import.meta.url
|
|
259
|
+
* @param relativePath - Path relative to the plugin
|
|
260
|
+
* @example
|
|
261
|
+
* ```ts
|
|
262
|
+
* import { resolveSkillModule } from 'unplugin-devpilot'
|
|
263
|
+
*
|
|
264
|
+
* export function myPlugin(): DevpilotPlugin {
|
|
265
|
+
* return {
|
|
266
|
+
* namespace: 'my-plugin',
|
|
267
|
+
* skillModule: resolveSkillModule(import.meta.url, './skill.md'),
|
|
268
|
+
* }
|
|
269
|
+
* }
|
|
270
|
+
* ```
|
|
271
|
+
*/
|
|
272
|
+
declare function resolveSkillModule(importMetaUrl: string, relativePath: string): string;
|
|
273
|
+
//#endregion
|
|
225
274
|
//#region src/index.d.ts
|
|
226
275
|
declare const unpluginDevpilot: UnpluginInstance<Options | undefined, false>;
|
|
227
276
|
//#endregion
|
|
228
|
-
export {
|
|
277
|
+
export { BaseServerFunctions as a, ClientInfo as c, PluginServerFunctions as d, ServerFunctions as f, Options as h, BaseClientFunctions as i, PendingTask as l, DevpilotPlugin as m, resolveSkillModule as n, ClientDiscoveryFilter as o, TaskHistory as p, clientManager as r, ClientFunctions as s, unpluginDevpilot as t, PluginClientFunctions as u };
|
package/dist/index.d.mts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { i as defineMcpToolRegister, n as resolveClientModule, t as DevpilotPluginContext } from "./index-
|
|
2
|
-
import { a as
|
|
3
|
-
export { BaseClientFunctions, BaseServerFunctions, ClientDiscoveryFilter, ClientFunctions, ClientInfo, DevpilotPlugin, DevpilotPluginContext, Options, PendingTask, PluginClientFunctions, PluginServerFunctions, ServerFunctions, TaskHistory, clientManager, unpluginDevpilot as default, unpluginDevpilot, defineMcpToolRegister, resolveClientModule };
|
|
1
|
+
import { a as resolveModule, i as defineMcpToolRegister, n as resolveClientModule, t as DevpilotPluginContext } from "./index-Csy16I0Z.mjs";
|
|
2
|
+
import { a as BaseServerFunctions, c as ClientInfo, d as PluginServerFunctions, f as ServerFunctions, h as Options, i as BaseClientFunctions, l as PendingTask, m as DevpilotPlugin, n as resolveSkillModule, o as ClientDiscoveryFilter, p as TaskHistory, r as clientManager, s as ClientFunctions, t as unpluginDevpilot, u as PluginClientFunctions } from "./index-WH3owjvn.mjs";
|
|
3
|
+
export { BaseClientFunctions, BaseServerFunctions, ClientDiscoveryFilter, ClientFunctions, ClientInfo, DevpilotPlugin, DevpilotPluginContext, Options, PendingTask, PluginClientFunctions, PluginServerFunctions, ServerFunctions, TaskHistory, clientManager, unpluginDevpilot as default, unpluginDevpilot, defineMcpToolRegister, resolveClientModule, resolveModule, resolveSkillModule };
|
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { n as unpluginDevpilot, r as
|
|
2
|
-
import { n as defineMcpToolRegister, t as resolveClientModule } from "./plugin-
|
|
1
|
+
import { i as clientManager, n as unpluginDevpilot, r as resolveSkillModule, t as src_default } from "./src-AEXLBOF9.mjs";
|
|
2
|
+
import { n as defineMcpToolRegister, r as resolveModule, t as resolveClientModule } from "./plugin-B1Afr0m3.mjs";
|
|
3
3
|
|
|
4
|
-
export { clientManager, src_default as default, defineMcpToolRegister, resolveClientModule, unpluginDevpilot };
|
|
4
|
+
export { clientManager, src_default as default, defineMcpToolRegister, resolveClientModule, resolveModule, resolveSkillModule, unpluginDevpilot };
|
|
@@ -1,6 +1,24 @@
|
|
|
1
1
|
import { dirname, join } from "node:path";
|
|
2
2
|
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
3
3
|
|
|
4
|
+
//#region src/core/utils.ts
|
|
5
|
+
/**
|
|
6
|
+
* Resolve the module path relative to the plugin to an absolute path
|
|
7
|
+
* Handles cross-platform paths (Windows, macOS, Linux) and proper escaping for imports
|
|
8
|
+
* @param importMetaUrl - Pass in import.meta.url
|
|
9
|
+
* @param relativePath - Path relative to the plugin
|
|
10
|
+
* @example
|
|
11
|
+
* ```ts
|
|
12
|
+
* import { resolveModule } from 'unplugin-devpilot/core/utils'
|
|
13
|
+
*
|
|
14
|
+
* const skillPath = resolveModule(import.meta.url, './skill.md')
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
function resolveModule(importMetaUrl, relativePath) {
|
|
18
|
+
return pathToFileURL(join(dirname(fileURLToPath(importMetaUrl)), relativePath)).href;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
//#endregion
|
|
4
22
|
//#region src/core/plugin/mcp.ts
|
|
5
23
|
function defineMcpToolRegister(name, config, cb) {
|
|
6
24
|
return () => ({
|
|
@@ -30,8 +48,8 @@ function defineMcpToolRegister(name, config, cb) {
|
|
|
30
48
|
* ```
|
|
31
49
|
*/
|
|
32
50
|
function resolveClientModule(importMetaUrl, relativePath) {
|
|
33
|
-
return
|
|
51
|
+
return resolveModule(importMetaUrl, relativePath);
|
|
34
52
|
}
|
|
35
53
|
|
|
36
54
|
//#endregion
|
|
37
|
-
export { defineMcpToolRegister as n, resolveClientModule as t };
|
|
55
|
+
export { defineMcpToolRegister as n, resolveModule as r, resolveClientModule as t };
|
package/dist/plugin.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { i as defineMcpToolRegister, n as resolveClientModule, r as McpToolRegister, t as DevpilotPluginContext } from "./index-
|
|
2
|
-
export { DevpilotPluginContext, McpToolRegister as McpServerRegister, defineMcpToolRegister, resolveClientModule };
|
|
1
|
+
import { a as resolveModule, i as defineMcpToolRegister, n as resolveClientModule, r as McpToolRegister, t as DevpilotPluginContext } from "./index-Csy16I0Z.mjs";
|
|
2
|
+
export { DevpilotPluginContext, McpToolRegister as McpServerRegister, defineMcpToolRegister, resolveClientModule, resolveModule };
|
package/dist/plugin.mjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { n as defineMcpToolRegister, t as resolveClientModule } from "./plugin-
|
|
1
|
+
import { n as defineMcpToolRegister, r as resolveModule, t as resolveClientModule } from "./plugin-B1Afr0m3.mjs";
|
|
2
2
|
|
|
3
|
-
export { defineMcpToolRegister, resolveClientModule };
|
|
3
|
+
export { defineMcpToolRegister, resolveClientModule, resolveModule };
|
package/dist/rspack.d.mts
CHANGED
package/dist/rspack.mjs
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { r as resolveModule } from "./plugin-B1Afr0m3.mjs";
|
|
1
2
|
import { createRequire } from "node:module";
|
|
2
3
|
import process$1 from "node:process";
|
|
3
4
|
import { createUnplugin } from "unplugin";
|
|
@@ -5,6 +6,11 @@ import { createServer } from "node:http";
|
|
|
5
6
|
import { Http2ServerRequest } from "http2";
|
|
6
7
|
import { Readable } from "stream";
|
|
7
8
|
import crypto$1 from "crypto";
|
|
9
|
+
import { createServer as createServer$1 } from "node:net";
|
|
10
|
+
import { networkInterfaces } from "node:os";
|
|
11
|
+
import { dirname, extname, join } from "node:path";
|
|
12
|
+
import { promises } from "node:fs";
|
|
13
|
+
import { fileURLToPath } from "node:url";
|
|
8
14
|
|
|
9
15
|
//#region rolldown:runtime
|
|
10
16
|
var __create = Object.create;
|
|
@@ -19793,7 +19799,7 @@ var StreamableHTTPServerTransport = class {
|
|
|
19793
19799
|
|
|
19794
19800
|
//#endregion
|
|
19795
19801
|
//#region package.json
|
|
19796
|
-
var version = "0.0.
|
|
19802
|
+
var version = "0.0.4";
|
|
19797
19803
|
|
|
19798
19804
|
//#endregion
|
|
19799
19805
|
//#region ../../node_modules/.pnpm/es-toolkit@1.44.0/node_modules/es-toolkit/dist/compat/util/uniqueId.mjs
|
|
@@ -20190,21 +20196,314 @@ async function startMcpServer(port) {
|
|
|
20190
20196
|
});
|
|
20191
20197
|
}
|
|
20192
20198
|
function stopMcpServer() {
|
|
20193
|
-
|
|
20194
|
-
httpServer
|
|
20195
|
-
|
|
20199
|
+
return new Promise((resolve) => {
|
|
20200
|
+
if (httpServer) {
|
|
20201
|
+
const server = httpServer;
|
|
20202
|
+
httpServer = null;
|
|
20203
|
+
server.close(() => resolve());
|
|
20204
|
+
} else resolve();
|
|
20205
|
+
});
|
|
20206
|
+
}
|
|
20207
|
+
|
|
20208
|
+
//#endregion
|
|
20209
|
+
//#region ../../node_modules/.pnpm/get-port-please@3.2.0/node_modules/get-port-please/dist/index.mjs
|
|
20210
|
+
const unsafePorts = /* @__PURE__ */ new Set([
|
|
20211
|
+
1,
|
|
20212
|
+
7,
|
|
20213
|
+
9,
|
|
20214
|
+
11,
|
|
20215
|
+
13,
|
|
20216
|
+
15,
|
|
20217
|
+
17,
|
|
20218
|
+
19,
|
|
20219
|
+
20,
|
|
20220
|
+
21,
|
|
20221
|
+
22,
|
|
20222
|
+
23,
|
|
20223
|
+
25,
|
|
20224
|
+
37,
|
|
20225
|
+
42,
|
|
20226
|
+
43,
|
|
20227
|
+
53,
|
|
20228
|
+
69,
|
|
20229
|
+
77,
|
|
20230
|
+
79,
|
|
20231
|
+
87,
|
|
20232
|
+
95,
|
|
20233
|
+
101,
|
|
20234
|
+
102,
|
|
20235
|
+
103,
|
|
20236
|
+
104,
|
|
20237
|
+
109,
|
|
20238
|
+
110,
|
|
20239
|
+
111,
|
|
20240
|
+
113,
|
|
20241
|
+
115,
|
|
20242
|
+
117,
|
|
20243
|
+
119,
|
|
20244
|
+
123,
|
|
20245
|
+
135,
|
|
20246
|
+
137,
|
|
20247
|
+
139,
|
|
20248
|
+
143,
|
|
20249
|
+
161,
|
|
20250
|
+
179,
|
|
20251
|
+
389,
|
|
20252
|
+
427,
|
|
20253
|
+
465,
|
|
20254
|
+
512,
|
|
20255
|
+
513,
|
|
20256
|
+
514,
|
|
20257
|
+
515,
|
|
20258
|
+
526,
|
|
20259
|
+
530,
|
|
20260
|
+
531,
|
|
20261
|
+
532,
|
|
20262
|
+
540,
|
|
20263
|
+
548,
|
|
20264
|
+
554,
|
|
20265
|
+
556,
|
|
20266
|
+
563,
|
|
20267
|
+
587,
|
|
20268
|
+
601,
|
|
20269
|
+
636,
|
|
20270
|
+
989,
|
|
20271
|
+
990,
|
|
20272
|
+
993,
|
|
20273
|
+
995,
|
|
20274
|
+
1719,
|
|
20275
|
+
1720,
|
|
20276
|
+
1723,
|
|
20277
|
+
2049,
|
|
20278
|
+
3659,
|
|
20279
|
+
4045,
|
|
20280
|
+
5060,
|
|
20281
|
+
5061,
|
|
20282
|
+
6e3,
|
|
20283
|
+
6566,
|
|
20284
|
+
6665,
|
|
20285
|
+
6666,
|
|
20286
|
+
6667,
|
|
20287
|
+
6668,
|
|
20288
|
+
6669,
|
|
20289
|
+
6697,
|
|
20290
|
+
10080
|
|
20291
|
+
]);
|
|
20292
|
+
function isUnsafePort(port) {
|
|
20293
|
+
return unsafePorts.has(port);
|
|
20294
|
+
}
|
|
20295
|
+
function isSafePort(port) {
|
|
20296
|
+
return !isUnsafePort(port);
|
|
20297
|
+
}
|
|
20298
|
+
var GetPortError = class extends Error {
|
|
20299
|
+
constructor(message, opts) {
|
|
20300
|
+
super(message, opts);
|
|
20301
|
+
this.message = message;
|
|
20196
20302
|
}
|
|
20303
|
+
name = "GetPortError";
|
|
20304
|
+
};
|
|
20305
|
+
function _log(verbose, message) {
|
|
20306
|
+
if (verbose) console.log(`[get-port] ${message}`);
|
|
20307
|
+
}
|
|
20308
|
+
function _tryPort(port, host) {
|
|
20309
|
+
return new Promise((resolve) => {
|
|
20310
|
+
const server = createServer$1();
|
|
20311
|
+
server.unref();
|
|
20312
|
+
server.on("error", () => {
|
|
20313
|
+
resolve(false);
|
|
20314
|
+
});
|
|
20315
|
+
server.listen({
|
|
20316
|
+
port,
|
|
20317
|
+
host
|
|
20318
|
+
}, () => {
|
|
20319
|
+
const { port: port2 } = server.address();
|
|
20320
|
+
server.close(() => {
|
|
20321
|
+
resolve(isSafePort(port2) && port2);
|
|
20322
|
+
});
|
|
20323
|
+
});
|
|
20324
|
+
});
|
|
20325
|
+
}
|
|
20326
|
+
function _getLocalHosts(additional) {
|
|
20327
|
+
const hosts = new Set(additional);
|
|
20328
|
+
for (const _interface of Object.values(networkInterfaces())) for (const config of _interface || []) if (config.address && !config.internal && !config.address.startsWith("fe80::") && !config.address.startsWith("169.254")) hosts.add(config.address);
|
|
20329
|
+
return [...hosts];
|
|
20330
|
+
}
|
|
20331
|
+
function _fmtOnHost(hostname) {
|
|
20332
|
+
return hostname ? `on host ${JSON.stringify(hostname)}` : "on any host";
|
|
20333
|
+
}
|
|
20334
|
+
async function getRandomPort(host) {
|
|
20335
|
+
const port = await checkPort(0, host);
|
|
20336
|
+
if (port === false) throw new GetPortError(`Unable to find a random port ${_fmtOnHost(host)}`);
|
|
20337
|
+
return port;
|
|
20338
|
+
}
|
|
20339
|
+
async function checkPort(port, host = process.env.HOST, verbose) {
|
|
20340
|
+
if (!host) host = _getLocalHosts([void 0, "0.0.0.0"]);
|
|
20341
|
+
if (!Array.isArray(host)) return _tryPort(port, host);
|
|
20342
|
+
for (const _host of host) {
|
|
20343
|
+
const _port = await _tryPort(port, _host);
|
|
20344
|
+
if (_port === false) {
|
|
20345
|
+
if (port < 1024 && verbose) _log(verbose, `Unable to listen to the privileged port ${port} ${_fmtOnHost(_host)}`);
|
|
20346
|
+
return false;
|
|
20347
|
+
}
|
|
20348
|
+
if (port === 0 && _port !== 0) port = _port;
|
|
20349
|
+
}
|
|
20350
|
+
return port;
|
|
20197
20351
|
}
|
|
20198
20352
|
|
|
20199
20353
|
//#endregion
|
|
20200
20354
|
//#region src/core/options.ts
|
|
20201
|
-
|
|
20355
|
+
let lastResolvedWsPort;
|
|
20356
|
+
let lastResolvedMcpPort;
|
|
20357
|
+
async function resolveOptions(options) {
|
|
20358
|
+
const wsPort = await resolveWsPort(options.wsPort);
|
|
20359
|
+
const mcpPort = await resolveMcpPort(options.mcpPort);
|
|
20360
|
+
lastResolvedWsPort = wsPort;
|
|
20361
|
+
lastResolvedMcpPort = mcpPort;
|
|
20202
20362
|
return {
|
|
20203
|
-
wsPort
|
|
20204
|
-
mcpPort
|
|
20205
|
-
plugins: options.plugins || []
|
|
20363
|
+
wsPort,
|
|
20364
|
+
mcpPort,
|
|
20365
|
+
plugins: options.plugins || [],
|
|
20366
|
+
skillCorePath: options.skillCorePath
|
|
20206
20367
|
};
|
|
20207
20368
|
}
|
|
20369
|
+
async function resolveWsPort(preferred) {
|
|
20370
|
+
const candidate = preferred ?? lastResolvedWsPort;
|
|
20371
|
+
if (candidate !== void 0) {
|
|
20372
|
+
if (await checkPort(candidate) !== false) return candidate;
|
|
20373
|
+
if (candidate === lastResolvedWsPort) return candidate;
|
|
20374
|
+
}
|
|
20375
|
+
if (lastResolvedWsPort !== void 0) return lastResolvedWsPort;
|
|
20376
|
+
return getRandomPort();
|
|
20377
|
+
}
|
|
20378
|
+
async function resolveMcpPort(preferred) {
|
|
20379
|
+
const candidate = preferred || 3101;
|
|
20380
|
+
if (candidate === lastResolvedMcpPort) return candidate;
|
|
20381
|
+
if (await checkPort(candidate) === false) throw new Error(`MCP port ${candidate} is already in use. Please specify a different port or free up the port.`);
|
|
20382
|
+
return candidate;
|
|
20383
|
+
}
|
|
20384
|
+
|
|
20385
|
+
//#endregion
|
|
20386
|
+
//#region src/core/skill-generator.ts
|
|
20387
|
+
/**
|
|
20388
|
+
* Resolve the skill module path relative to the plugin to an absolute path
|
|
20389
|
+
* Handles cross-platform paths (Windows, macOS, Linux) and proper escaping for imports
|
|
20390
|
+
* @param importMetaUrl - Pass in import.meta.url
|
|
20391
|
+
* @param relativePath - Path relative to the plugin
|
|
20392
|
+
* @example
|
|
20393
|
+
* ```ts
|
|
20394
|
+
* import { resolveSkillModule } from 'unplugin-devpilot'
|
|
20395
|
+
*
|
|
20396
|
+
* export function myPlugin(): DevpilotPlugin {
|
|
20397
|
+
* return {
|
|
20398
|
+
* namespace: 'my-plugin',
|
|
20399
|
+
* skillModule: resolveSkillModule(import.meta.url, './skill.md'),
|
|
20400
|
+
* }
|
|
20401
|
+
* }
|
|
20402
|
+
* ```
|
|
20403
|
+
*/
|
|
20404
|
+
function resolveSkillModule(importMetaUrl, relativePath) {
|
|
20405
|
+
return resolveModule(importMetaUrl, relativePath);
|
|
20406
|
+
}
|
|
20407
|
+
/**
|
|
20408
|
+
* Determine if a path is a directory (no file extension) or a file
|
|
20409
|
+
* @param path - The path to check
|
|
20410
|
+
* @returns true if the path is a directory, false if it's a file
|
|
20411
|
+
*/
|
|
20412
|
+
function isDirectoryPath(path) {
|
|
20413
|
+
return extname(path) === "";
|
|
20414
|
+
}
|
|
20415
|
+
/**
|
|
20416
|
+
* Get the core skill file path, handling both directory and file paths
|
|
20417
|
+
* @param skillCorePath - The configured skill core path (directory or file)
|
|
20418
|
+
* @returns The actual file path to use for the core skill file
|
|
20419
|
+
*/
|
|
20420
|
+
function getCoreSkillFilePath(skillCorePath) {
|
|
20421
|
+
if (isDirectoryPath(skillCorePath)) return join(skillCorePath, "SKILL.md");
|
|
20422
|
+
return skillCorePath;
|
|
20423
|
+
}
|
|
20424
|
+
/**
|
|
20425
|
+
* Get all plugin skill modules
|
|
20426
|
+
*/
|
|
20427
|
+
function getPluginSkillModules(plugins, options) {
|
|
20428
|
+
const ctx = { wsPort: options.wsPort };
|
|
20429
|
+
return plugins.filter((p) => p.skillModule).map((p) => {
|
|
20430
|
+
const mod = typeof p.skillModule === "function" ? p.skillModule(ctx) : p.skillModule;
|
|
20431
|
+
let skillPath;
|
|
20432
|
+
if (mod.startsWith("file://")) skillPath = fileURLToPath(mod);
|
|
20433
|
+
else if (mod.startsWith("npm:") || !mod.startsWith(".") && !mod.startsWith("/") && (mod.includes("/") || mod.match(/^[@a-z0-9]\S+$/i))) skillPath = mod;
|
|
20434
|
+
else skillPath = mod;
|
|
20435
|
+
return {
|
|
20436
|
+
namespace: p.namespace,
|
|
20437
|
+
path: skillPath,
|
|
20438
|
+
originalSkillModule: mod
|
|
20439
|
+
};
|
|
20440
|
+
});
|
|
20441
|
+
}
|
|
20442
|
+
/**
|
|
20443
|
+
* Generate the core skill markdown content
|
|
20444
|
+
*/
|
|
20445
|
+
function generateCoreSkillContent(options, isDev) {
|
|
20446
|
+
if (!isDev) return "";
|
|
20447
|
+
return `# Devpilot Core Skills
|
|
20448
|
+
|
|
20449
|
+
This is the core skill file that aggregates all plugin skills.
|
|
20450
|
+
|
|
20451
|
+
## Available Skills
|
|
20452
|
+
|
|
20453
|
+
${getPluginSkillModules(options.plugins, options).map((skill) => {
|
|
20454
|
+
if (skill.originalSkillModule.startsWith("file://")) {
|
|
20455
|
+
const linkPath = `./${skill.namespace}.md`;
|
|
20456
|
+
return `- [${skill.namespace}](${linkPath}) - ${skill.namespace} capabilities`;
|
|
20457
|
+
} else if (skill.originalSkillModule.startsWith("npm:") || !skill.originalSkillModule.startsWith(".") && !skill.originalSkillModule.startsWith("/") && (skill.originalSkillModule.includes("/") || skill.originalSkillModule.match(/^[@a-z0-9]\S+$/i))) return `- [${skill.namespace}](${skill.originalSkillModule}) - ${skill.namespace} capabilities`;
|
|
20458
|
+
else {
|
|
20459
|
+
const linkPath = `./${skill.namespace}.md`;
|
|
20460
|
+
return `- [${skill.namespace}](${linkPath}) - ${skill.namespace} capabilities`;
|
|
20461
|
+
}
|
|
20462
|
+
}).join("\n") || "No plugin skills configured"}
|
|
20463
|
+
|
|
20464
|
+
## Usage
|
|
20465
|
+
|
|
20466
|
+
These skills can be used with Claude Agent to interact with web applications.
|
|
20467
|
+
|
|
20468
|
+
## Configuration
|
|
20469
|
+
|
|
20470
|
+
- **Core Skill Path**: ${options.skillCorePath || "Not configured"}
|
|
20471
|
+
- **Plugins**: ${options.plugins.length}
|
|
20472
|
+
- **WebSocket Port**: ${options.wsPort}
|
|
20473
|
+
- **MCP Port**: ${options.mcpPort}
|
|
20474
|
+
`;
|
|
20475
|
+
}
|
|
20476
|
+
/**
|
|
20477
|
+
* Generate and write the core skill file
|
|
20478
|
+
*/
|
|
20479
|
+
async function generateCoreSkill(options, isDev) {
|
|
20480
|
+
if (!options.skillCorePath) return;
|
|
20481
|
+
const skillFilePath = getCoreSkillFilePath(options.skillCorePath);
|
|
20482
|
+
const content = generateCoreSkillContent(options, isDev);
|
|
20483
|
+
if (!isDev || !content) {
|
|
20484
|
+
try {
|
|
20485
|
+
await promises.unlink(skillFilePath);
|
|
20486
|
+
} catch {}
|
|
20487
|
+
return;
|
|
20488
|
+
}
|
|
20489
|
+
let existingContent;
|
|
20490
|
+
try {
|
|
20491
|
+
existingContent = await promises.readFile(skillFilePath, "utf-8");
|
|
20492
|
+
} catch {}
|
|
20493
|
+
if (existingContent === content) return;
|
|
20494
|
+
const dir = dirname(skillFilePath);
|
|
20495
|
+
await promises.mkdir(dir, { recursive: true });
|
|
20496
|
+
const pluginSkills = getPluginSkillModules(options.plugins, options);
|
|
20497
|
+
for (const skill of pluginSkills) if (skill.originalSkillModule.startsWith("file://")) {
|
|
20498
|
+
const sourcePath = skill.path;
|
|
20499
|
+
const destPath = join(dir, `${skill.namespace}.md`);
|
|
20500
|
+
try {
|
|
20501
|
+
const skillContent = await promises.readFile(sourcePath, "utf-8");
|
|
20502
|
+
await promises.writeFile(destPath, skillContent, "utf-8");
|
|
20503
|
+
} catch {}
|
|
20504
|
+
}
|
|
20505
|
+
await promises.writeFile(skillFilePath, content, "utf-8");
|
|
20506
|
+
}
|
|
20208
20507
|
|
|
20209
20508
|
//#endregion
|
|
20210
20509
|
//#region ../../node_modules/.pnpm/birpc@4.0.0/node_modules/birpc/dist/index.mjs
|
|
@@ -23990,10 +24289,13 @@ function startWebSocketServer(port) {
|
|
|
23990
24289
|
return wss;
|
|
23991
24290
|
}
|
|
23992
24291
|
function stopWebSocketServer() {
|
|
23993
|
-
|
|
23994
|
-
wss
|
|
23995
|
-
|
|
23996
|
-
|
|
24292
|
+
return new Promise((resolve) => {
|
|
24293
|
+
if (wss) {
|
|
24294
|
+
const server = wss;
|
|
24295
|
+
wss = null;
|
|
24296
|
+
server.close(() => resolve());
|
|
24297
|
+
} else resolve();
|
|
24298
|
+
});
|
|
23997
24299
|
}
|
|
23998
24300
|
|
|
23999
24301
|
//#endregion
|
|
@@ -24024,23 +24326,33 @@ ${handlerCollection}
|
|
|
24024
24326
|
});
|
|
24025
24327
|
`;
|
|
24026
24328
|
}
|
|
24027
|
-
|
|
24028
|
-
|
|
24029
|
-
|
|
24030
|
-
const
|
|
24031
|
-
|
|
24032
|
-
|
|
24329
|
+
let serversStarted = false;
|
|
24330
|
+
let lastOptions = null;
|
|
24331
|
+
async function startServers(rawOptions) {
|
|
24332
|
+
const options = await resolveOptions(rawOptions);
|
|
24333
|
+
lastOptions = options;
|
|
24334
|
+
registerPluginServerMethods(options.plugins);
|
|
24335
|
+
registerPluginMcpRegisterMethods(options.plugins);
|
|
24336
|
+
if (!serversStarted) {
|
|
24033
24337
|
serversStarted = true;
|
|
24034
|
-
registerPluginServerMethods(options.plugins);
|
|
24035
|
-
registerPluginMcpRegisterMethods(options.plugins);
|
|
24036
24338
|
startWebSocketServer(options.wsPort);
|
|
24037
24339
|
await startMcpServer(options.mcpPort);
|
|
24038
24340
|
}
|
|
24039
|
-
|
|
24040
|
-
|
|
24041
|
-
|
|
24042
|
-
|
|
24043
|
-
|
|
24341
|
+
await generateCoreSkill(options, process$1.env.NODE_ENV !== "production");
|
|
24342
|
+
return options;
|
|
24343
|
+
}
|
|
24344
|
+
async function stopServers() {
|
|
24345
|
+
if (!serversStarted) return;
|
|
24346
|
+
serversStarted = false;
|
|
24347
|
+
await Promise.all([stopWebSocketServer(), stopMcpServer()]);
|
|
24348
|
+
if (lastOptions) await generateCoreSkill(lastOptions, false);
|
|
24349
|
+
}
|
|
24350
|
+
const unpluginDevpilot = createUnplugin((rawOptions = {}) => {
|
|
24351
|
+
let options = null;
|
|
24352
|
+
let isDevServer = false;
|
|
24353
|
+
const name = "unplugin-devpilot";
|
|
24354
|
+
async function ensureServersStarted() {
|
|
24355
|
+
options = await startServers(rawOptions);
|
|
24044
24356
|
}
|
|
24045
24357
|
return {
|
|
24046
24358
|
name,
|
|
@@ -24051,38 +24363,53 @@ const unpluginDevpilot = createUnplugin((rawOptions = {}) => {
|
|
|
24051
24363
|
loadInclude(id) {
|
|
24052
24364
|
return id === RESOLVED_VIRTUAL_MODULE_ID;
|
|
24053
24365
|
},
|
|
24054
|
-
load(id) {
|
|
24055
|
-
if (id === RESOLVED_VIRTUAL_MODULE_ID)
|
|
24366
|
+
async load(id) {
|
|
24367
|
+
if (id === RESOLVED_VIRTUAL_MODULE_ID) {
|
|
24368
|
+
if (!options) options = await resolveOptions(rawOptions);
|
|
24369
|
+
return generateVirtualClientModule(options, process$1.env.NODE_ENV !== "production");
|
|
24370
|
+
}
|
|
24056
24371
|
},
|
|
24057
24372
|
buildStart() {
|
|
24058
24373
|
if (process$1.env.NODE_ENV === "production") return;
|
|
24059
|
-
|
|
24374
|
+
if (isDevServer) return;
|
|
24375
|
+
return ensureServersStarted();
|
|
24060
24376
|
},
|
|
24061
24377
|
buildEnd() {
|
|
24062
|
-
|
|
24378
|
+
if (isDevServer) return;
|
|
24379
|
+
return stopServers();
|
|
24063
24380
|
},
|
|
24064
24381
|
vite: { configureServer() {
|
|
24065
|
-
|
|
24382
|
+
isDevServer = true;
|
|
24383
|
+
ensureServersStarted();
|
|
24066
24384
|
} },
|
|
24067
24385
|
webpack(compiler) {
|
|
24068
24386
|
compiler.hooks.watchRun.tapPromise(name, async () => {
|
|
24069
|
-
|
|
24387
|
+
isDevServer = true;
|
|
24388
|
+
await ensureServersStarted();
|
|
24070
24389
|
});
|
|
24071
|
-
compiler.hooks.
|
|
24072
|
-
|
|
24390
|
+
compiler.hooks.shutdown?.tap(name, () => {
|
|
24391
|
+
stopServers();
|
|
24073
24392
|
});
|
|
24074
24393
|
},
|
|
24075
24394
|
rspack(compiler) {
|
|
24076
24395
|
compiler.hooks.watchRun.tapPromise(name, async () => {
|
|
24077
|
-
|
|
24396
|
+
isDevServer = true;
|
|
24397
|
+
await ensureServersStarted();
|
|
24078
24398
|
});
|
|
24079
|
-
compiler.hooks.
|
|
24080
|
-
|
|
24399
|
+
compiler.hooks.shutdown?.tap(name, () => {
|
|
24400
|
+
stopServers();
|
|
24081
24401
|
});
|
|
24082
|
-
}
|
|
24402
|
+
},
|
|
24403
|
+
farm: { configureDevServer() {
|
|
24404
|
+
isDevServer = true;
|
|
24405
|
+
ensureServersStarted();
|
|
24406
|
+
} }
|
|
24083
24407
|
};
|
|
24084
24408
|
});
|
|
24409
|
+
process$1.on("beforeExit", () => {
|
|
24410
|
+
stopServers();
|
|
24411
|
+
});
|
|
24085
24412
|
var src_default = unpluginDevpilot;
|
|
24086
24413
|
|
|
24087
24414
|
//#endregion
|
|
24088
|
-
export { unpluginDevpilot as n,
|
|
24415
|
+
export { clientManager as i, unpluginDevpilot as n, resolveSkillModule as r, src_default as t };
|
package/dist/vite.d.mts
CHANGED
package/dist/vite.mjs
CHANGED
package/dist/webpack.d.mts
CHANGED
package/dist/webpack.mjs
CHANGED
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "unplugin-devpilot",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.4",
|
|
5
5
|
"description": "Description.",
|
|
6
6
|
"author": "zcf0508 <zcf0508@live.com>",
|
|
7
7
|
"license": "MIT",
|
|
@@ -52,6 +52,30 @@
|
|
|
52
52
|
"engines": {
|
|
53
53
|
"node": ">=20.19.0"
|
|
54
54
|
},
|
|
55
|
+
"peerDependencies": {
|
|
56
|
+
"@farmfe/core": ">=1",
|
|
57
|
+
"@nuxt/kit": "^3",
|
|
58
|
+
"@nuxt/schema": "^3",
|
|
59
|
+
"vite": ">=3",
|
|
60
|
+
"webpack": "^4 || ^5"
|
|
61
|
+
},
|
|
62
|
+
"peerDependenciesMeta": {
|
|
63
|
+
"@farmfe/core": {
|
|
64
|
+
"optional": true
|
|
65
|
+
},
|
|
66
|
+
"@nuxt/kit": {
|
|
67
|
+
"optional": true
|
|
68
|
+
},
|
|
69
|
+
"@nuxt/schema": {
|
|
70
|
+
"optional": true
|
|
71
|
+
},
|
|
72
|
+
"vite": {
|
|
73
|
+
"optional": true
|
|
74
|
+
},
|
|
75
|
+
"webpack": {
|
|
76
|
+
"optional": true
|
|
77
|
+
}
|
|
78
|
+
},
|
|
55
79
|
"dependencies": {
|
|
56
80
|
"unplugin": "^3.0.0"
|
|
57
81
|
},
|
|
@@ -60,6 +84,7 @@
|
|
|
60
84
|
"@types/ws": "^8.18.1",
|
|
61
85
|
"birpc": "^4.0.0",
|
|
62
86
|
"es-toolkit": "^1.44.0",
|
|
87
|
+
"get-port-please": "^3.2.0",
|
|
63
88
|
"hookable": "^6.0.1",
|
|
64
89
|
"mitt": "^3.0.1",
|
|
65
90
|
"ws": "^8.19.0",
|
|
@@ -69,8 +94,8 @@
|
|
|
69
94
|
"build": "tsdown",
|
|
70
95
|
"dev": "tsdown --watch",
|
|
71
96
|
"test": "vitest --run",
|
|
72
|
-
"typecheck:client": "
|
|
73
|
-
"typecheck:node": "
|
|
97
|
+
"typecheck:client": "tsgo --project tsconfig.client.json --noEmit",
|
|
98
|
+
"typecheck:node": "tsgo --noEmit",
|
|
74
99
|
"typecheck": "pnpm run typecheck:client && pnpm run typecheck:node"
|
|
75
100
|
}
|
|
76
101
|
}
|