unplugin-devpilot 0.0.5 → 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/dist/farm.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { t as unpluginDevpilot } from "./index-DMYihCqJ.mjs";
1
+ import { t as unpluginDevpilot } from "./index-D6IYERGx.mjs";
2
2
 
3
3
  //#region src/farm.d.ts
4
4
  /**
package/dist/farm.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { n as unpluginDevpilot } from "./src-DkQU5cZx.mjs";
1
+ import { n as unpluginDevpilot } from "./src-BHdaOKo9.mjs";
2
2
 
3
3
  //#region src/farm.ts
4
4
  /**
@@ -4221,6 +4221,18 @@ type McpToolRegister = <OutputArgs extends ZodRawShapeCompat | AnySchema, InputA
4221
4221
  };
4222
4222
  cb: NoInfer<ToolCallback<InputArgs>>;
4223
4223
  });
4224
+ interface McpToolResolved {
4225
+ name: string;
4226
+ config: {
4227
+ title?: string;
4228
+ description?: string;
4229
+ inputSchema?: ZodRawShapeCompat;
4230
+ outputSchema?: ZodRawShapeCompat | AnySchema;
4231
+ annotations?: ToolAnnotations;
4232
+ _meta?: Record<string, unknown>;
4233
+ };
4234
+ cb: ToolCallback<ZodRawShapeCompat>;
4235
+ }
4224
4236
  declare function defineMcpToolRegister<OutputArgs extends ZodRawShapeCompat | AnySchema, InputArgs extends undefined | ZodRawShapeCompat | AnySchema = undefined>(name: string, config: {
4225
4237
  title?: string;
4226
4238
  description?: string;
@@ -4265,4 +4277,4 @@ interface DevpilotPluginContext {
4265
4277
  */
4266
4278
  declare function resolveClientModule(importMetaUrl: string, relativePath: string): string;
4267
4279
  //#endregion
4268
- export { type resolveModule as a, defineMcpToolRegister as i, resolveClientModule as n, Storage as o, McpToolRegister as r, StorageValue as s, DevpilotPluginContext as t };
4280
+ export { type defineMcpToolRegister as a, type StorageValue as c, McpToolResolved as i, resolveClientModule as n, resolveModule as o, McpToolRegister as r, Storage as s, DevpilotPluginContext as t };
@@ -1,4 +1,4 @@
1
- import { o as Storage, r as McpToolRegister, s as StorageValue, t as DevpilotPluginContext } from "./index-B3RgT4Na.mjs";
1
+ import { c as StorageValue, r as McpToolRegister, s as Storage, t as DevpilotPluginContext } from "./index-BE1u_wvJ.mjs";
2
2
  import { UnpluginInstance } from "unplugin";
3
3
  import { WebSocket } from "ws";
4
4
 
package/dist/index.d.mts CHANGED
@@ -1,3 +1,3 @@
1
- import { a as resolveModule, i as defineMcpToolRegister, n as resolveClientModule, t as DevpilotPluginContext } from "./index-B3RgT4Na.mjs";
2
- import { _ as Options, a as clientManager, c as ClientDiscoveryFilter, d as PendingTask, f as PluginClientFunctions, g as DevpilotPlugin, h as TaskHistory, i as resolveSkillModule, l as ClientFunctions, m as ServerFunctions, n as getPluginStorage, o as BaseClientFunctions, p as PluginServerFunctions, r as storage, s as BaseServerFunctions, t as unpluginDevpilot, u as ClientInfo } from "./index-DMYihCqJ.mjs";
1
+ import { a as defineMcpToolRegister, n as resolveClientModule, o as resolveModule, t as DevpilotPluginContext } from "./index-BE1u_wvJ.mjs";
2
+ import { _ as Options, a as clientManager, c as ClientDiscoveryFilter, d as PendingTask, f as PluginClientFunctions, g as DevpilotPlugin, h as TaskHistory, i as resolveSkillModule, l as ClientFunctions, m as ServerFunctions, n as getPluginStorage, o as BaseClientFunctions, p as PluginServerFunctions, r as storage, s as BaseServerFunctions, t as unpluginDevpilot, u as ClientInfo } from "./index-D6IYERGx.mjs";
3
3
  export { BaseClientFunctions, BaseServerFunctions, ClientDiscoveryFilter, ClientFunctions, ClientInfo, DevpilotPlugin, DevpilotPluginContext, Options, PendingTask, PluginClientFunctions, PluginServerFunctions, ServerFunctions, TaskHistory, clientManager, unpluginDevpilot as default, unpluginDevpilot, defineMcpToolRegister, getPluginStorage, resolveClientModule, resolveModule, resolveSkillModule, storage };
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { a as storage, i as getPluginStorage, n as unpluginDevpilot, o as clientManager, r as resolveSkillModule, t as src_default } from "./src-DkQU5cZx.mjs";
2
- import { n as defineMcpToolRegister, r as resolveModule, t as resolveClientModule } from "./plugin-B1Afr0m3.mjs";
1
+ import { a as storage, i as getPluginStorage, n as unpluginDevpilot, o as clientManager, r as resolveSkillModule, t as src_default } from "./src-BHdaOKo9.mjs";
2
+ import { n as resolveModule, r as defineMcpToolRegister, t as resolveClientModule } from "./plugin-4eB8Zx4B.mjs";
3
3
 
4
4
  export { clientManager, src_default as default, defineMcpToolRegister, getPluginStorage, resolveClientModule, resolveModule, resolveSkillModule, storage, unpluginDevpilot };
@@ -1,6 +1,16 @@
1
1
  import { dirname, join } from "node:path";
2
2
  import { fileURLToPath, pathToFileURL } from "node:url";
3
3
 
4
+ //#region src/core/plugin/mcp.ts
5
+ function defineMcpToolRegister(name, config, cb) {
6
+ return () => ({
7
+ name,
8
+ config,
9
+ cb
10
+ });
11
+ }
12
+
13
+ //#endregion
4
14
  //#region src/core/utils.ts
5
15
  /**
6
16
  * Resolve the module path relative to the plugin to an absolute path
@@ -18,16 +28,6 @@ function resolveModule(importMetaUrl, relativePath) {
18
28
  return pathToFileURL(join(dirname(fileURLToPath(importMetaUrl)), relativePath)).href;
19
29
  }
20
30
 
21
- //#endregion
22
- //#region src/core/plugin/mcp.ts
23
- function defineMcpToolRegister(name, config, cb) {
24
- return () => ({
25
- name,
26
- config,
27
- cb
28
- });
29
- }
30
-
31
31
  //#endregion
32
32
  //#region src/core/plugin/index.ts
33
33
  /**
@@ -52,4 +52,4 @@ function resolveClientModule(importMetaUrl, relativePath) {
52
52
  }
53
53
 
54
54
  //#endregion
55
- export { defineMcpToolRegister as n, resolveModule as r, resolveClientModule as t };
55
+ export { resolveModule as n, defineMcpToolRegister as r, resolveClientModule as t };
package/dist/plugin.d.mts CHANGED
@@ -1,2 +1,2 @@
1
- import { a as resolveModule, i as defineMcpToolRegister, n as resolveClientModule, r as McpToolRegister, t as DevpilotPluginContext } from "./index-B3RgT4Na.mjs";
2
- export { DevpilotPluginContext, McpToolRegister as McpServerRegister, defineMcpToolRegister, resolveClientModule, resolveModule };
1
+ import { a as defineMcpToolRegister, i as McpToolResolved, n as resolveClientModule, o as resolveModule, r as McpToolRegister, t as DevpilotPluginContext } from "./index-BE1u_wvJ.mjs";
2
+ export { DevpilotPluginContext, McpToolRegister as McpServerRegister, McpToolResolved, defineMcpToolRegister, resolveClientModule, resolveModule };
package/dist/plugin.mjs CHANGED
@@ -1,3 +1,3 @@
1
- import { n as defineMcpToolRegister, r as resolveModule, t as resolveClientModule } from "./plugin-B1Afr0m3.mjs";
1
+ import { n as resolveModule, r as defineMcpToolRegister, t as resolveClientModule } from "./plugin-4eB8Zx4B.mjs";
2
2
 
3
3
  export { defineMcpToolRegister, resolveClientModule, resolveModule };
package/dist/rspack.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { t as unpluginDevpilot } from "./index-DMYihCqJ.mjs";
1
+ import { t as unpluginDevpilot } from "./index-D6IYERGx.mjs";
2
2
 
3
3
  //#region src/rspack.d.ts
4
4
  /**
package/dist/rspack.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { n as unpluginDevpilot } from "./src-DkQU5cZx.mjs";
1
+ import { n as unpluginDevpilot } from "./src-BHdaOKo9.mjs";
2
2
 
3
3
  //#region src/rspack.ts
4
4
  /**
@@ -1,4 +1,4 @@
1
- import { r as resolveModule } from "./plugin-B1Afr0m3.mjs";
1
+ import { n as resolveModule, r as defineMcpToolRegister } from "./plugin-4eB8Zx4B.mjs";
2
2
  import { createRequire } from "node:module";
3
3
  import process$1 from "node:process";
4
4
  import { createUnplugin } from "unplugin";
@@ -19799,7 +19799,7 @@ var StreamableHTTPServerTransport = class {
19799
19799
 
19800
19800
  //#endregion
19801
19801
  //#region package.json
19802
- var version = "0.0.5";
19802
+ var version = "0.0.6";
19803
19803
 
19804
19804
  //#endregion
19805
19805
  //#region ../../node_modules/.pnpm/es-toolkit@1.44.0/node_modules/es-toolkit/dist/compat/util/uniqueId.mjs
@@ -19960,6 +19960,110 @@ var ClientManager = class {
19960
19960
  };
19961
19961
  const clientManager = new ClientManager();
19962
19962
 
19963
+ //#endregion
19964
+ //#region src/core/builtin-tools.ts
19965
+ const builtinToolRegisters = [
19966
+ defineMcpToolRegister("list_clients", {
19967
+ title: "List Clients",
19968
+ description: "List all connected browser instances with optional filtering by URL, title, or clientId",
19969
+ inputSchema: {
19970
+ activeOnly: boolean().optional().default(true).describe("Only list active clients"),
19971
+ urlPattern: string().optional().describe("Filter clients by URL pattern (substring match, case-insensitive)"),
19972
+ titlePattern: string().optional().describe("Filter clients by page title pattern (substring match, case-insensitive)"),
19973
+ clientId: string().optional().describe("Filter by specific client ID"),
19974
+ groupByUrl: boolean().optional().default(false).describe("Group results by URL for easier identification")
19975
+ }
19976
+ }, async (params) => {
19977
+ const filter = {
19978
+ activeOnly: params.activeOnly,
19979
+ urlPattern: params.urlPattern,
19980
+ titlePattern: params.titlePattern,
19981
+ clientId: params.clientId
19982
+ };
19983
+ let clients;
19984
+ let grouped;
19985
+ if (params.groupByUrl) {
19986
+ grouped = clientManager.getClientsByUrl();
19987
+ clients = Object.values(grouped).flat();
19988
+ } else clients = clientManager.findClients(filter);
19989
+ const result = {
19990
+ clients,
19991
+ total: clients.length
19992
+ };
19993
+ if (params.groupByUrl) result.grouped = grouped;
19994
+ if (clients.length === 0) {
19995
+ result.suggestions = [
19996
+ "No clients found. Make sure the browser has the devpilot extension loaded.",
19997
+ "Try refreshing the browser page to reconnect.",
19998
+ "Use activeOnly=false to see recently disconnected clients."
19999
+ ];
20000
+ if (params.urlPattern) result.suggestions.push(`No clients match URL pattern: "${params.urlPattern}"`);
20001
+ }
20002
+ return { content: [{
20003
+ type: "text",
20004
+ text: JSON.stringify(result, null, 2)
20005
+ }] };
20006
+ }),
20007
+ defineMcpToolRegister("get_pending_tasks", {
20008
+ title: "Get Pending Tasks",
20009
+ description: "Get pending tasks submitted from browser",
20010
+ inputSchema: { clearAfterFetch: boolean().optional().default(true).describe("Clear tasks after fetching") }
20011
+ }, async (params) => {
20012
+ const tasks = clientManager.getPendingTasks(params.clearAfterFetch);
20013
+ return { content: [{
20014
+ type: "text",
20015
+ text: JSON.stringify({
20016
+ hasTasks: tasks.length > 0,
20017
+ tasks,
20018
+ message: tasks.length > 0 ? `Found ${tasks.length} pending task(s)` : "No pending tasks"
20019
+ }, null, 2)
20020
+ }] };
20021
+ }),
20022
+ defineMcpToolRegister("get_task_history", {
20023
+ title: "Get Task History",
20024
+ description: "Get history of tasks (including completed and failed tasks). Useful for task recovery after page refresh.",
20025
+ inputSchema: {
20026
+ clientId: string().optional().describe("Filter tasks by client ID"),
20027
+ status: _enum([
20028
+ "pending",
20029
+ "in_progress",
20030
+ "completed",
20031
+ "failed"
20032
+ ]).optional().describe("Filter by task status"),
20033
+ limit: number().optional().default(50).describe("Maximum number of tasks to return")
20034
+ }
20035
+ }, async (params) => {
20036
+ const history = clientManager.getTaskHistory({
20037
+ clientId: params.clientId,
20038
+ status: params.status,
20039
+ limit: params.limit
20040
+ });
20041
+ const result = {
20042
+ history,
20043
+ total: history.length,
20044
+ query: params
20045
+ };
20046
+ if (history.length === 0) {
20047
+ result.message = "No task history found.";
20048
+ if (params.clientId) result.suggestions = [`No tasks found for client "${params.clientId}".`, "Try without clientId filter to see all tasks."];
20049
+ }
20050
+ result.groupedByStatus = history.reduce((acc, task) => {
20051
+ acc[task.status] = (acc[task.status] || 0) + 1;
20052
+ return acc;
20053
+ }, {});
20054
+ return { content: [{
20055
+ type: "text",
20056
+ text: JSON.stringify(result, null, 2)
20057
+ }] };
20058
+ })
20059
+ ];
20060
+ function getBuiltinTools() {
20061
+ return builtinToolRegisters.map((r) => r());
20062
+ }
20063
+ function getBuiltinToolNames() {
20064
+ return builtinToolRegisters.map((r) => r().name);
20065
+ }
20066
+
19963
20067
  //#endregion
19964
20068
  //#region ../../node_modules/.pnpm/destr@2.0.5/node_modules/destr/dist/index.mjs
19965
20069
  const suspectProtoRx = /"(?:_|\\u0{2}5[Ff]){2}(?:p|\\u0{2}70)(?:r|\\u0{2}72)(?:o|\\u0{2}6[Ff])(?:t|\\u0{2}74)(?:o|\\u0{2}6[Ff])(?:_|\\u0{2}5[Ff]){2}"\s*:/;
@@ -20470,159 +20574,7 @@ async function startMcpServer(port) {
20470
20574
  name: "unplugin-devpilot",
20471
20575
  version
20472
20576
  });
20473
- mcpServer.registerTool("list_clients", {
20474
- title: "List Clients",
20475
- description: "List all connected browser instances with optional filtering by URL, title, or clientId",
20476
- inputSchema: {
20477
- activeOnly: boolean().optional().default(true).describe("Only list active clients"),
20478
- urlPattern: string().optional().describe("Filter clients by URL pattern (substring match, case-insensitive)"),
20479
- titlePattern: string().optional().describe("Filter clients by page title pattern (substring match, case-insensitive)"),
20480
- clientId: string().optional().describe("Filter by specific client ID"),
20481
- groupByUrl: boolean().optional().default(false).describe("Group results by URL for easier identification")
20482
- }
20483
- }, async (params) => {
20484
- const filter = {
20485
- activeOnly: params.activeOnly,
20486
- urlPattern: params.urlPattern,
20487
- titlePattern: params.titlePattern,
20488
- clientId: params.clientId
20489
- };
20490
- let clients;
20491
- let grouped;
20492
- if (params.groupByUrl) {
20493
- grouped = clientManager.getClientsByUrl();
20494
- clients = Object.values(grouped).flat();
20495
- } else clients = clientManager.findClients(filter);
20496
- const result = {
20497
- clients,
20498
- total: clients.length
20499
- };
20500
- if (params.groupByUrl) result.grouped = grouped;
20501
- if (clients.length === 0) {
20502
- result.suggestions = [
20503
- "No clients found. Make sure the browser has the devpilot extension loaded.",
20504
- "Try refreshing the browser page to reconnect.",
20505
- "Use activeOnly=false to see recently disconnected clients."
20506
- ];
20507
- if (params.urlPattern) result.suggestions.push(`No clients match URL pattern: "${params.urlPattern}"`);
20508
- }
20509
- return { content: [{
20510
- type: "text",
20511
- text: JSON.stringify(result, null, 2)
20512
- }] };
20513
- });
20514
- mcpServer.registerTool("get_pending_tasks", {
20515
- title: "Get Pending Tasks",
20516
- description: "Get pending tasks submitted from browser",
20517
- inputSchema: { clearAfterFetch: boolean().optional().default(true).describe("Clear tasks after fetching") }
20518
- }, async (params) => {
20519
- const tasks = clientManager.getPendingTasks(params.clearAfterFetch);
20520
- return { content: [{
20521
- type: "text",
20522
- text: JSON.stringify({
20523
- hasTasks: tasks.length > 0,
20524
- tasks,
20525
- message: tasks.length > 0 ? `Found ${tasks.length} pending task(s)` : "No pending tasks"
20526
- }, null, 2)
20527
- }] };
20528
- });
20529
- mcpServer.registerTool("find_clients_by_url", {
20530
- title: "Find Clients by URL",
20531
- description: "Find browser clients matching a URL pattern. Useful for reconnecting to specific pages after refresh.",
20532
- inputSchema: {
20533
- urlPattern: string().describe("URL pattern to search for (substring match, case-insensitive)"),
20534
- exactMatch: boolean().optional().default(false).describe("Require exact URL match instead of substring")
20535
- }
20536
- }, async (params) => {
20537
- const { urlPattern, exactMatch } = params;
20538
- const allClients = clientManager.getAllClients(true);
20539
- let matchedClients;
20540
- if (exactMatch) matchedClients = allClients.filter((c) => c.url === urlPattern);
20541
- else {
20542
- const patternLower = urlPattern.toLowerCase();
20543
- matchedClients = allClients.filter((c) => c.url.toLowerCase().includes(patternLower));
20544
- }
20545
- const result = {
20546
- matchedClients,
20547
- total: matchedClients.length,
20548
- query: {
20549
- urlPattern,
20550
- exactMatch
20551
- }
20552
- };
20553
- if (matchedClients.length === 0) result.suggestions = [
20554
- "No clients found matching this URL.",
20555
- "Try refreshing the browser page to reconnect.",
20556
- "Available URLs:",
20557
- ...allClients.map((c) => c.url).filter(Boolean).slice(0, 5).map((u) => ` - ${u}`)
20558
- ];
20559
- else if (matchedClients.length === 1) result.suggestion = `Use clientId "${matchedClients[0].clientId}" to target this client in other tools.`;
20560
- else result.suggestion = "Multiple clients found. Use clientId parameter to specify which one to target.";
20561
- return { content: [{
20562
- type: "text",
20563
- text: JSON.stringify(result, null, 2)
20564
- }] };
20565
- });
20566
- mcpServer.registerTool("get_task_history", {
20567
- title: "Get Task History",
20568
- description: "Get history of tasks (including completed and failed tasks). Useful for task recovery after page refresh.",
20569
- inputSchema: {
20570
- clientId: string().optional().describe("Filter tasks by client ID"),
20571
- status: _enum([
20572
- "pending",
20573
- "in_progress",
20574
- "completed",
20575
- "failed"
20576
- ]).optional().describe("Filter by task status"),
20577
- limit: number().optional().default(50).describe("Maximum number of tasks to return")
20578
- }
20579
- }, async (params) => {
20580
- const history = clientManager.getTaskHistory({
20581
- clientId: params.clientId,
20582
- status: params.status,
20583
- limit: params.limit
20584
- });
20585
- const result = {
20586
- history,
20587
- total: history.length,
20588
- query: params
20589
- };
20590
- if (history.length === 0) {
20591
- result.message = "No task history found.";
20592
- if (params.clientId) result.suggestions = [`No tasks found for client "${params.clientId}".`, "Try without clientId filter to see all tasks."];
20593
- }
20594
- result.groupedByStatus = history.reduce((acc, task) => {
20595
- acc[task.status] = (acc[task.status] || 0) + 1;
20596
- return acc;
20597
- }, {});
20598
- return { content: [{
20599
- type: "text",
20600
- text: JSON.stringify(result, null, 2)
20601
- }] };
20602
- });
20603
- mcpServer.registerTool("find_clients_by_title", {
20604
- title: "Find Clients by Title",
20605
- description: "Find browser clients by page title. Useful when URL is not unique or helpful.",
20606
- inputSchema: { titlePattern: string().describe("Title pattern to search for (substring match, case-insensitive)") }
20607
- }, async (params) => {
20608
- const { titlePattern } = params;
20609
- const patternLower = titlePattern.toLowerCase();
20610
- const matchedClients = clientManager.getAllClients(true).filter((c) => c.title.toLowerCase().includes(patternLower));
20611
- const result = {
20612
- matchedClients,
20613
- total: matchedClients.length,
20614
- query: { titlePattern }
20615
- };
20616
- if (matchedClients.length === 0) result.suggestions = [
20617
- "No clients found matching this title.",
20618
- "Available titles:",
20619
- ...clientManager.getAllClients(true).map((c) => c.title).filter(Boolean).slice(0, 5).map((t) => ` - ${t}`)
20620
- ];
20621
- return { content: [{
20622
- type: "text",
20623
- text: JSON.stringify(result, null, 2)
20624
- }] };
20625
- });
20577
+ for (const { name, config, cb } of getBuiltinTools()) mcpServer.registerTool(name, config, cb);
20626
20578
  Object.entries(mcpRegeisterMethods).forEach(([namespace, mcpRegeisters]) => {
20627
20579
  mcpRegeisters.forEach((mcpRegeister) => {
20628
20580
  const { name: _name, config, cb } = mcpRegeister();
@@ -20925,18 +20877,35 @@ function getPluginSkillModules(plugins, options) {
20925
20877
  };
20926
20878
  });
20927
20879
  }
20880
+ function collectAllowedTools(plugins, options) {
20881
+ const tools = [...getBuiltinToolNames()];
20882
+ for (const plugin of plugins) if (plugin.mcpSetup) try {
20883
+ const ctx = {
20884
+ wsPort: options.wsPort,
20885
+ storage: getPluginStorage(plugin.namespace)
20886
+ };
20887
+ const mcps = plugin.mcpSetup(ctx);
20888
+ for (const register of mcps) {
20889
+ const result = register();
20890
+ if (result.name) tools.push(result.name);
20891
+ }
20892
+ } catch {}
20893
+ return tools;
20894
+ }
20895
+ function generateFrontmatter(options) {
20896
+ const allowedTools = collectAllowedTools(options.plugins, options);
20897
+ return `---
20898
+ name: devpilot
20899
+ description: Devpilot core skill that aggregates all plugin skills for web application interaction and debugging.
20900
+ ${allowedTools.length > 0 ? `allowed-tools: [\n${allowedTools.map((t) => ` "${t}"`).join(",\n")}\n]` : "allowed-tools: []"}
20901
+ ---`;
20902
+ }
20928
20903
  /**
20929
20904
  * Generate the core skill markdown content
20930
20905
  */
20931
20906
  function generateCoreSkillContent(options, isDev) {
20932
20907
  if (!isDev) return "";
20933
- return `# Devpilot Core Skills
20934
-
20935
- This is the core skill file that aggregates all plugin skills.
20936
-
20937
- ## Available Skills
20938
-
20939
- ${getPluginSkillModules(options.plugins, options).map((skill) => {
20908
+ const skillList = getPluginSkillModules(options.plugins, options).map((skill) => {
20940
20909
  if (skill.originalSkillModule.startsWith("file://")) {
20941
20910
  const linkPath = `./${skill.namespace}.md`;
20942
20911
  return `- [${skill.namespace}](${linkPath}) - ${skill.namespace} capabilities`;
@@ -20945,7 +20914,16 @@ ${getPluginSkillModules(options.plugins, options).map((skill) => {
20945
20914
  const linkPath = `./${skill.namespace}.md`;
20946
20915
  return `- [${skill.namespace}](${linkPath}) - ${skill.namespace} capabilities`;
20947
20916
  }
20948
- }).join("\n") || "No plugin skills configured"}
20917
+ }).join("\n");
20918
+ return `${generateFrontmatter(options)}
20919
+
20920
+ # Devpilot Core Skills
20921
+
20922
+ This is the core skill file that aggregates all plugin skills.
20923
+
20924
+ ## Available Skills
20925
+
20926
+ ${skillList || "No plugin skills configured"}
20949
20927
 
20950
20928
  ## Usage
20951
20929
 
@@ -20978,29 +20956,38 @@ async function generateCoreSkill(options, isDev) {
20978
20956
  continue;
20979
20957
  }
20980
20958
  await promises.mkdir(dir, { recursive: true });
20981
- await promises.chmod(dir, 511);
20982
20959
  for (const skill of pluginSkills) if (skill.originalSkillModule.startsWith("file://")) await copyPluginSkillFile(skill.path, join(dir, `${skill.namespace}.md`));
20983
20960
  let existingContent;
20984
20961
  try {
20985
20962
  existingContent = await promises.readFile(skillFilePath, "utf-8");
20986
20963
  } catch {}
20987
- if (existingContent !== content) {
20988
- await promises.writeFile(skillFilePath, content, "utf-8");
20989
- await promises.chmod(skillFilePath, 511);
20990
- }
20964
+ if (existingContent !== content) await promises.writeFile(skillFilePath, content, "utf-8");
20991
20965
  await setPermissionsRecursive(dir).catch(() => {});
20992
20966
  }
20993
20967
  }
20994
20968
  async function setPermissionsRecursive(dirPath) {
20995
- try {
20996
- await promises.chmod(dirPath, 511);
20997
- const entries = await promises.readdir(dirPath, { withFileTypes: true });
20998
- for (const entry of entries) {
20999
- const fullPath = join(dirPath, entry.name);
21000
- if (entry.isDirectory()) await setPermissionsRecursive(fullPath);
21001
- else await promises.chmod(fullPath, 511);
21002
- }
21003
- } catch {}
20969
+ const isRoot = process$1.getuid?.() === 0;
20970
+ const sudoUid = Number(process$1.env.SUDO_UID);
20971
+ const sudoGid = Number(process$1.env.SUDO_GID);
20972
+ const shouldChown = isRoot && !Number.isNaN(sudoUid) && !Number.isNaN(sudoGid);
20973
+ async function applyPermissions(targetPath, mode) {
20974
+ try {
20975
+ await promises.chmod(targetPath, mode);
20976
+ if (shouldChown) await promises.chown(targetPath, sudoUid, sudoGid);
20977
+ } catch {}
20978
+ }
20979
+ async function walk(currentPath) {
20980
+ await applyPermissions(currentPath, 511);
20981
+ try {
20982
+ const entries = await promises.readdir(currentPath, { withFileTypes: true });
20983
+ for (const entry of entries) {
20984
+ const fullPath = join(currentPath, entry.name);
20985
+ if (entry.isDirectory()) await walk(fullPath);
20986
+ else await applyPermissions(fullPath, 438);
20987
+ }
20988
+ } catch {}
20989
+ }
20990
+ await walk(dirPath);
21004
20991
  }
21005
20992
  async function copyPluginSkillFile(sourcePath, destPath) {
21006
20993
  try {
@@ -21011,7 +20998,6 @@ async function copyPluginSkillFile(sourcePath, destPath) {
21011
20998
  } catch {}
21012
20999
  if (existingDest !== skillContent) {
21013
21000
  await promises.writeFile(destPath, skillContent, "utf-8");
21014
- await promises.chmod(destPath, 511);
21015
21001
  return true;
21016
21002
  }
21017
21003
  return false;
package/dist/vite.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { t as unpluginDevpilot } from "./index-DMYihCqJ.mjs";
1
+ import { t as unpluginDevpilot } from "./index-D6IYERGx.mjs";
2
2
 
3
3
  //#region src/vite.d.ts
4
4
  /**
package/dist/vite.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { n as unpluginDevpilot } from "./src-DkQU5cZx.mjs";
1
+ import { n as unpluginDevpilot } from "./src-BHdaOKo9.mjs";
2
2
 
3
3
  //#region src/vite.ts
4
4
  /**
@@ -1,4 +1,4 @@
1
- import { t as unpluginDevpilot } from "./index-DMYihCqJ.mjs";
1
+ import { t as unpluginDevpilot } from "./index-D6IYERGx.mjs";
2
2
 
3
3
  //#region src/webpack.d.ts
4
4
  /**
package/dist/webpack.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { n as unpluginDevpilot } from "./src-DkQU5cZx.mjs";
1
+ import { n as unpluginDevpilot } from "./src-BHdaOKo9.mjs";
2
2
 
3
3
  //#region src/webpack.ts
4
4
  /**
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "unplugin-devpilot",
3
3
  "type": "module",
4
- "version": "0.0.5",
4
+ "version": "0.0.6",
5
5
  "description": "Description.",
6
6
  "author": "zcf0508 <zcf0508@live.com>",
7
7
  "license": "MIT",