@mcpc-tech/core 0.3.15 → 0.3.17

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/index.cjs CHANGED
@@ -20966,13 +20966,13 @@ var mode_ai_sampling_plugin_default = createAISamplingModePlugin();
20966
20966
  var import_acp_ai_provider = require("@mcpc-tech/acp-ai-provider");
20967
20967
  var AIACPExecutor = class extends BaseAIExecutor {
20968
20968
  acpSettings;
20969
- clientTools;
20969
+ tools;
20970
20970
  provider = null;
20971
20971
  model = null;
20972
20972
  constructor(config2) {
20973
20973
  super(config2);
20974
20974
  this.acpSettings = config2.acpSettings;
20975
- this.clientTools = config2.clientTools ?? [];
20975
+ this.tools = config2.tools;
20976
20976
  }
20977
20977
  initProvider() {
20978
20978
  if (!this.model) {
@@ -20989,21 +20989,21 @@ var AIACPExecutor = class extends BaseAIExecutor {
20989
20989
  return "acp";
20990
20990
  }
20991
20991
  getToolListDescription() {
20992
- if (this.clientTools.length === 0) {
20993
- return "Tools will be provided by AI SDK";
20992
+ if (this.tools.length === 0) {
20993
+ return "Tools will be provided by ACP agent";
20994
20994
  }
20995
- return this.clientTools.map(([name, detail]) => `- ${name}: ${detail.description || "No description"}`).join("\n");
20995
+ return this.tools.map(([name, detail]) => `- ${name}: ${detail.description || "No description"}`).join("\n");
20996
20996
  }
20997
20997
  buildTools() {
20998
20998
  const aiTools = {};
20999
- for (const [name, detail] of this.clientTools) {
20999
+ for (const [name, detail] of this.tools) {
21000
21000
  if (!detail.execute) continue;
21001
21001
  aiTools[name] = this.convertToAISDKTool(name, detail, async (input) => {
21002
21002
  const result = await detail.execute(input);
21003
21003
  return this.formatResult(result);
21004
21004
  });
21005
21005
  }
21006
- return aiTools;
21006
+ return (0, import_acp_ai_provider.acpTools)(aiTools);
21007
21007
  }
21008
21008
  formatResult(result) {
21009
21009
  const texts = result.content?.filter((c) => c.type === "text").map((c) => c.text);
@@ -21024,13 +21024,13 @@ var AIACPExecutor = class extends BaseAIExecutor {
21024
21024
 
21025
21025
  // __mcpc__core_latest/node_modules/@mcpc/core/src/executors/ai/ai-acp-registrar.js
21026
21026
  function registerAIACPTool(server, params) {
21027
- const { name, description, allToolNames, depGroups, acpSettings, clientTools = [], maxSteps = 50, tracingEnabled = false } = params;
21027
+ const { name, description, allToolNames, depGroups, toolNameToDetailList, acpSettings, maxSteps = 50, tracingEnabled = false } = params;
21028
21028
  const createArgsDef = createArgsDefFactory(name, allToolNames, depGroups, void 0, void 0);
21029
21029
  const executor = new AIACPExecutor({
21030
21030
  name,
21031
21031
  description,
21032
21032
  acpSettings,
21033
- clientTools,
21033
+ tools: toolNameToDetailList,
21034
21034
  maxSteps,
21035
21035
  tracingEnabled
21036
21036
  });
@@ -21069,8 +21069,8 @@ var createAIACPModePlugin = () => ({
21069
21069
  name: context2.name,
21070
21070
  allToolNames: context2.allToolNames,
21071
21071
  depGroups: context2.depGroups,
21072
+ toolNameToDetailList: context2.toolNameToDetailList,
21072
21073
  acpSettings: opts.acpSettings,
21073
- clientTools: opts.clientTools,
21074
21074
  maxSteps: opts.maxSteps,
21075
21075
  tracingEnabled: opts.tracingEnabled
21076
21076
  });
package/index.mjs CHANGED
@@ -20951,16 +20951,16 @@ var createAISamplingModePlugin = () => ({
20951
20951
  var mode_ai_sampling_plugin_default = createAISamplingModePlugin();
20952
20952
 
20953
20953
  // __mcpc__core_latest/node_modules/@mcpc/core/src/executors/ai/ai-acp-executor.js
20954
- import { createACPProvider } from "@mcpc-tech/acp-ai-provider";
20954
+ import { acpTools, createACPProvider } from "@mcpc-tech/acp-ai-provider";
20955
20955
  var AIACPExecutor = class extends BaseAIExecutor {
20956
20956
  acpSettings;
20957
- clientTools;
20957
+ tools;
20958
20958
  provider = null;
20959
20959
  model = null;
20960
20960
  constructor(config2) {
20961
20961
  super(config2);
20962
20962
  this.acpSettings = config2.acpSettings;
20963
- this.clientTools = config2.clientTools ?? [];
20963
+ this.tools = config2.tools;
20964
20964
  }
20965
20965
  initProvider() {
20966
20966
  if (!this.model) {
@@ -20977,21 +20977,21 @@ var AIACPExecutor = class extends BaseAIExecutor {
20977
20977
  return "acp";
20978
20978
  }
20979
20979
  getToolListDescription() {
20980
- if (this.clientTools.length === 0) {
20981
- return "Tools will be provided by AI SDK";
20980
+ if (this.tools.length === 0) {
20981
+ return "Tools will be provided by ACP agent";
20982
20982
  }
20983
- return this.clientTools.map(([name, detail]) => `- ${name}: ${detail.description || "No description"}`).join("\n");
20983
+ return this.tools.map(([name, detail]) => `- ${name}: ${detail.description || "No description"}`).join("\n");
20984
20984
  }
20985
20985
  buildTools() {
20986
20986
  const aiTools = {};
20987
- for (const [name, detail] of this.clientTools) {
20987
+ for (const [name, detail] of this.tools) {
20988
20988
  if (!detail.execute) continue;
20989
20989
  aiTools[name] = this.convertToAISDKTool(name, detail, async (input) => {
20990
20990
  const result = await detail.execute(input);
20991
20991
  return this.formatResult(result);
20992
20992
  });
20993
20993
  }
20994
- return aiTools;
20994
+ return acpTools(aiTools);
20995
20995
  }
20996
20996
  formatResult(result) {
20997
20997
  const texts = result.content?.filter((c) => c.type === "text").map((c) => c.text);
@@ -21012,13 +21012,13 @@ var AIACPExecutor = class extends BaseAIExecutor {
21012
21012
 
21013
21013
  // __mcpc__core_latest/node_modules/@mcpc/core/src/executors/ai/ai-acp-registrar.js
21014
21014
  function registerAIACPTool(server, params) {
21015
- const { name, description, allToolNames, depGroups, acpSettings, clientTools = [], maxSteps = 50, tracingEnabled = false } = params;
21015
+ const { name, description, allToolNames, depGroups, toolNameToDetailList, acpSettings, maxSteps = 50, tracingEnabled = false } = params;
21016
21016
  const createArgsDef = createArgsDefFactory(name, allToolNames, depGroups, void 0, void 0);
21017
21017
  const executor = new AIACPExecutor({
21018
21018
  name,
21019
21019
  description,
21020
21020
  acpSettings,
21021
- clientTools,
21021
+ tools: toolNameToDetailList,
21022
21022
  maxSteps,
21023
21023
  tracingEnabled
21024
21024
  });
@@ -21057,8 +21057,8 @@ var createAIACPModePlugin = () => ({
21057
21057
  name: context2.name,
21058
21058
  allToolNames: context2.allToolNames,
21059
21059
  depGroups: context2.depGroups,
21060
+ toolNameToDetailList: context2.toolNameToDetailList,
21060
21061
  acpSettings: opts.acpSettings,
21061
- clientTools: opts.clientTools,
21062
21062
  maxSteps: opts.maxSteps,
21063
21063
  tracingEnabled: opts.tracingEnabled
21064
21064
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mcpc-tech/core",
3
- "version": "0.3.15",
3
+ "version": "0.3.17",
4
4
  "homepage": "https://jsr.io/@mcpc/core",
5
5
  "dependencies": {
6
6
  "@ai-sdk/provider": "^2.0.0",
@@ -53,25 +53,16 @@ function parseFrontmatter(content) {
53
53
  const match = content.match(/^---\n([\s\S]*?)\n---/);
54
54
  if (!match) return null;
55
55
  const yaml = match[1];
56
- const result = {};
56
+ let name = "", description = "";
57
57
  for (const line of yaml.split("\n")) {
58
- if (line.trim() === "metadata:") {
59
- result.metadata = {};
60
- continue;
61
- }
62
- const metadataMatch = line.match(/^\s{2}(\w+):\s*"?([^"]*)"?$/);
63
- if (metadataMatch && result.metadata) {
64
- result.metadata[metadataMatch[1]] = metadataMatch[2];
65
- continue;
66
- }
67
- const fieldMatch = line.match(/^(\S+):\s*(.*)$/);
68
- if (fieldMatch) {
69
- const [, key, value] = fieldMatch;
70
- result[key] = value.replace(/^["']|["']$/g, "");
58
+ const m = line.match(/^(name|description):\s*(.+)$/);
59
+ if (m) {
60
+ const value = m[2].replace(/^["']|["']$/g, "");
61
+ if (m[1] === "name") name = value;
62
+ else description = value;
71
63
  }
72
64
  }
73
- if (!result.name || !result.description) return null;
74
- return result;
65
+ return name && description ? { name, description } : null;
75
66
  }
76
67
  function extractBody(content) {
77
68
  return content.replace(/^---\n[\s\S]*?\n---\n*/, "");
@@ -85,14 +76,12 @@ async function scanSkills(basePath) {
85
76
  const skillDir = (0, import_node_path.join)(basePath, entry.name);
86
77
  const skillFile = (0, import_node_path.join)(skillDir, "SKILL.md");
87
78
  try {
88
- await (0, import_promises.stat)(skillFile);
89
79
  const content = await (0, import_promises.readFile)(skillFile, "utf-8");
90
80
  const frontmatter = parseFrontmatter(content);
91
81
  if (frontmatter && frontmatter.name === entry.name) {
92
82
  skills.push({
93
83
  ...frontmatter,
94
- basePath: skillDir,
95
- filePath: skillFile
84
+ basePath: skillDir
96
85
  });
97
86
  }
98
87
  } catch {
@@ -108,14 +97,16 @@ function generateToolDescription(skills, agentName) {
108
97
  }
109
98
  const skillsList = skills.map((s) => `- ${s.name}: ${s.description}`).join("\n");
110
99
  const toolName = `${agentName}__load-skill`;
111
- return `Load a skill's detailed instructions or reference files for the "${agentName}" agent.
100
+ return `Load a skill's instructions or reference files for the "${agentName}" agent.
112
101
 
113
102
  Available skills:
114
103
  ${skillsList}
115
104
 
116
105
  Usage:
117
106
  - ${toolName}({ skill: "skill-name" }) - Load main SKILL.md content
118
- - ${toolName}({ skill: "skill-name", ref: "references/file.md" }) - Load reference file`;
107
+ - ${toolName}({ skill: "skill-name", ref: "path/to/file" }) - Load reference file
108
+
109
+ Note: For scripts/ and assets/, use appropriate tools directly.`;
119
110
  }
120
111
  function createSkillsPlugin(options) {
121
112
  const { paths } = options;
@@ -156,7 +147,7 @@ function createSkillsPlugin(options) {
156
147
  },
157
148
  ref: {
158
149
  type: "string",
159
- description: "Optional: relative path to a reference file within the skill directory"
150
+ description: "Optional: relative path to any file within the skill directory"
160
151
  }
161
152
  },
162
153
  required: ["skill"]
@@ -176,26 +167,37 @@ function createSkillsPlugin(options) {
176
167
  const relPath = (0, import_node_path.relative)(meta.basePath, refPath);
177
168
  if (relPath.startsWith("..")) {
178
169
  return {
179
- content: [
180
- { type: "text", text: `Invalid ref path: ${args.ref}` }
181
- ],
170
+ content: [{
171
+ type: "text",
172
+ text: `Invalid path: ${args.ref}`
173
+ }],
182
174
  isError: true
183
175
  };
184
176
  }
177
+ const dir = relPath.split(/[/\\]/)[0];
178
+ if (dir === "scripts" || dir === "assets") {
179
+ return {
180
+ content: [{ type: "text", text: `Path: ${refPath}` }]
181
+ };
182
+ }
185
183
  try {
186
184
  const content = await (0, import_promises.readFile)(refPath, "utf-8");
187
185
  return { content: [{ type: "text", text: content }] };
188
186
  } catch {
189
187
  return {
190
- content: [
191
- { type: "text", text: `File not found: ${args.ref}` }
192
- ],
188
+ content: [{
189
+ type: "text",
190
+ text: `File not found: ${args.ref}`
191
+ }],
193
192
  isError: true
194
193
  };
195
194
  }
196
195
  }
197
196
  try {
198
- const content = await (0, import_promises.readFile)(meta.filePath, "utf-8");
197
+ const content = await (0, import_promises.readFile)(
198
+ (0, import_node_path.join)(meta.basePath, "SKILL.md"),
199
+ "utf-8"
200
+ );
199
201
  const body = extractBody(content);
200
202
  return { content: [{ type: "text", text: body }] };
201
203
  } catch {
@@ -3,7 +3,7 @@ import { createRequire } from 'node:module';
3
3
  const require = createRequire(import.meta.url);
4
4
 
5
5
  // __mcpc__core_latest/node_modules/@mcpc/core/src/plugins/skills.ts
6
- import { readdir, readFile, stat } from "node:fs/promises";
6
+ import { readdir, readFile } from "node:fs/promises";
7
7
  import { join, relative, resolve } from "node:path";
8
8
 
9
9
  // __mcpc__core_latest/node_modules/@mcpc/core/src/utils/schema.js
@@ -31,25 +31,16 @@ function parseFrontmatter(content) {
31
31
  const match = content.match(/^---\n([\s\S]*?)\n---/);
32
32
  if (!match) return null;
33
33
  const yaml = match[1];
34
- const result = {};
34
+ let name = "", description = "";
35
35
  for (const line of yaml.split("\n")) {
36
- if (line.trim() === "metadata:") {
37
- result.metadata = {};
38
- continue;
39
- }
40
- const metadataMatch = line.match(/^\s{2}(\w+):\s*"?([^"]*)"?$/);
41
- if (metadataMatch && result.metadata) {
42
- result.metadata[metadataMatch[1]] = metadataMatch[2];
43
- continue;
44
- }
45
- const fieldMatch = line.match(/^(\S+):\s*(.*)$/);
46
- if (fieldMatch) {
47
- const [, key, value] = fieldMatch;
48
- result[key] = value.replace(/^["']|["']$/g, "");
36
+ const m = line.match(/^(name|description):\s*(.+)$/);
37
+ if (m) {
38
+ const value = m[2].replace(/^["']|["']$/g, "");
39
+ if (m[1] === "name") name = value;
40
+ else description = value;
49
41
  }
50
42
  }
51
- if (!result.name || !result.description) return null;
52
- return result;
43
+ return name && description ? { name, description } : null;
53
44
  }
54
45
  function extractBody(content) {
55
46
  return content.replace(/^---\n[\s\S]*?\n---\n*/, "");
@@ -63,14 +54,12 @@ async function scanSkills(basePath) {
63
54
  const skillDir = join(basePath, entry.name);
64
55
  const skillFile = join(skillDir, "SKILL.md");
65
56
  try {
66
- await stat(skillFile);
67
57
  const content = await readFile(skillFile, "utf-8");
68
58
  const frontmatter = parseFrontmatter(content);
69
59
  if (frontmatter && frontmatter.name === entry.name) {
70
60
  skills.push({
71
61
  ...frontmatter,
72
- basePath: skillDir,
73
- filePath: skillFile
62
+ basePath: skillDir
74
63
  });
75
64
  }
76
65
  } catch {
@@ -86,14 +75,16 @@ function generateToolDescription(skills, agentName) {
86
75
  }
87
76
  const skillsList = skills.map((s) => `- ${s.name}: ${s.description}`).join("\n");
88
77
  const toolName = `${agentName}__load-skill`;
89
- return `Load a skill's detailed instructions or reference files for the "${agentName}" agent.
78
+ return `Load a skill's instructions or reference files for the "${agentName}" agent.
90
79
 
91
80
  Available skills:
92
81
  ${skillsList}
93
82
 
94
83
  Usage:
95
84
  - ${toolName}({ skill: "skill-name" }) - Load main SKILL.md content
96
- - ${toolName}({ skill: "skill-name", ref: "references/file.md" }) - Load reference file`;
85
+ - ${toolName}({ skill: "skill-name", ref: "path/to/file" }) - Load reference file
86
+
87
+ Note: For scripts/ and assets/, use appropriate tools directly.`;
97
88
  }
98
89
  function createSkillsPlugin(options) {
99
90
  const { paths } = options;
@@ -134,7 +125,7 @@ function createSkillsPlugin(options) {
134
125
  },
135
126
  ref: {
136
127
  type: "string",
137
- description: "Optional: relative path to a reference file within the skill directory"
128
+ description: "Optional: relative path to any file within the skill directory"
138
129
  }
139
130
  },
140
131
  required: ["skill"]
@@ -154,26 +145,37 @@ function createSkillsPlugin(options) {
154
145
  const relPath = relative(meta.basePath, refPath);
155
146
  if (relPath.startsWith("..")) {
156
147
  return {
157
- content: [
158
- { type: "text", text: `Invalid ref path: ${args.ref}` }
159
- ],
148
+ content: [{
149
+ type: "text",
150
+ text: `Invalid path: ${args.ref}`
151
+ }],
160
152
  isError: true
161
153
  };
162
154
  }
155
+ const dir = relPath.split(/[/\\]/)[0];
156
+ if (dir === "scripts" || dir === "assets") {
157
+ return {
158
+ content: [{ type: "text", text: `Path: ${refPath}` }]
159
+ };
160
+ }
163
161
  try {
164
162
  const content = await readFile(refPath, "utf-8");
165
163
  return { content: [{ type: "text", text: content }] };
166
164
  } catch {
167
165
  return {
168
- content: [
169
- { type: "text", text: `File not found: ${args.ref}` }
170
- ],
166
+ content: [{
167
+ type: "text",
168
+ text: `File not found: ${args.ref}`
169
+ }],
171
170
  isError: true
172
171
  };
173
172
  }
174
173
  }
175
174
  try {
176
- const content = await readFile(meta.filePath, "utf-8");
175
+ const content = await readFile(
176
+ join(meta.basePath, "SKILL.md"),
177
+ "utf-8"
178
+ );
177
179
  const body = extractBody(content);
178
180
  return { content: [{ type: "text", text: body }] };
179
181
  } catch {
package/plugins.cjs CHANGED
@@ -392,25 +392,19 @@ function parseFrontmatter(content) {
392
392
  const match = content.match(/^---\n([\s\S]*?)\n---/);
393
393
  if (!match) return null;
394
394
  const yaml = match[1];
395
- const result = {};
395
+ let name = "", description = "";
396
396
  for (const line of yaml.split("\n")) {
397
- if (line.trim() === "metadata:") {
398
- result.metadata = {};
399
- continue;
400
- }
401
- const metadataMatch = line.match(/^\s{2}(\w+):\s*"?([^"]*)"?$/);
402
- if (metadataMatch && result.metadata) {
403
- result.metadata[metadataMatch[1]] = metadataMatch[2];
404
- continue;
405
- }
406
- const fieldMatch = line.match(/^(\S+):\s*(.*)$/);
407
- if (fieldMatch) {
408
- const [, key, value] = fieldMatch;
409
- result[key] = value.replace(/^["']|["']$/g, "");
397
+ const m = line.match(/^(name|description):\s*(.+)$/);
398
+ if (m) {
399
+ const value = m[2].replace(/^["']|["']$/g, "");
400
+ if (m[1] === "name") name = value;
401
+ else description = value;
410
402
  }
411
403
  }
412
- if (!result.name || !result.description) return null;
413
- return result;
404
+ return name && description ? {
405
+ name,
406
+ description
407
+ } : null;
414
408
  }
415
409
  function extractBody(content) {
416
410
  return content.replace(/^---\n[\s\S]*?\n---\n*/, "");
@@ -426,14 +420,12 @@ async function scanSkills(basePath) {
426
420
  const skillDir = (0, import_node_path4.join)(basePath, entry.name);
427
421
  const skillFile = (0, import_node_path4.join)(skillDir, "SKILL.md");
428
422
  try {
429
- await (0, import_promises2.stat)(skillFile);
430
423
  const content = await (0, import_promises2.readFile)(skillFile, "utf-8");
431
424
  const frontmatter = parseFrontmatter(content);
432
425
  if (frontmatter && frontmatter.name === entry.name) {
433
426
  skills.push({
434
427
  ...frontmatter,
435
- basePath: skillDir,
436
- filePath: skillFile
428
+ basePath: skillDir
437
429
  });
438
430
  }
439
431
  } catch {
@@ -449,14 +441,16 @@ function generateToolDescription(skills, agentName) {
449
441
  }
450
442
  const skillsList = skills.map((s) => `- ${s.name}: ${s.description}`).join("\n");
451
443
  const toolName = `${agentName}__load-skill`;
452
- return `Load a skill's detailed instructions or reference files for the "${agentName}" agent.
444
+ return `Load a skill's instructions or reference files for the "${agentName}" agent.
453
445
 
454
446
  Available skills:
455
447
  ${skillsList}
456
448
 
457
449
  Usage:
458
450
  - ${toolName}({ skill: "skill-name" }) - Load main SKILL.md content
459
- - ${toolName}({ skill: "skill-name", ref: "references/file.md" }) - Load reference file`;
451
+ - ${toolName}({ skill: "skill-name", ref: "path/to/file" }) - Load reference file
452
+
453
+ Note: For scripts/ and assets/, use appropriate tools directly.`;
460
454
  }
461
455
  function createSkillsPlugin(options) {
462
456
  const { paths } = options;
@@ -491,7 +485,7 @@ function createSkillsPlugin(options) {
491
485
  },
492
486
  ref: {
493
487
  type: "string",
494
- description: "Optional: relative path to a reference file within the skill directory"
488
+ description: "Optional: relative path to any file within the skill directory"
495
489
  }
496
490
  },
497
491
  required: [
@@ -518,12 +512,23 @@ function createSkillsPlugin(options) {
518
512
  content: [
519
513
  {
520
514
  type: "text",
521
- text: `Invalid ref path: ${args.ref}`
515
+ text: `Invalid path: ${args.ref}`
522
516
  }
523
517
  ],
524
518
  isError: true
525
519
  };
526
520
  }
521
+ const dir = relPath.split(/[/\\]/)[0];
522
+ if (dir === "scripts" || dir === "assets") {
523
+ return {
524
+ content: [
525
+ {
526
+ type: "text",
527
+ text: `Path: ${refPath}`
528
+ }
529
+ ]
530
+ };
531
+ }
527
532
  try {
528
533
  const content = await (0, import_promises2.readFile)(refPath, "utf-8");
529
534
  return {
@@ -547,7 +552,7 @@ function createSkillsPlugin(options) {
547
552
  }
548
553
  }
549
554
  try {
550
- const content = await (0, import_promises2.readFile)(meta.filePath, "utf-8");
555
+ const content = await (0, import_promises2.readFile)((0, import_node_path4.join)(meta.basePath, "SKILL.md"), "utf-8");
551
556
  const body = extractBody(content);
552
557
  return {
553
558
  content: [
package/plugins.mjs CHANGED
@@ -350,31 +350,25 @@ var defaultLargeResultPlugin = createLargeResultPlugin({
350
350
  var large_result_default = defaultLargeResultPlugin;
351
351
 
352
352
  // __mcpc__core_latest/node_modules/@mcpc/core/src/plugins/skills.js
353
- import { readdir, readFile, stat } from "node:fs/promises";
353
+ import { readdir, readFile } from "node:fs/promises";
354
354
  import { join as join2, relative as relative2, resolve as resolve2 } from "node:path";
355
355
  function parseFrontmatter(content) {
356
356
  const match = content.match(/^---\n([\s\S]*?)\n---/);
357
357
  if (!match) return null;
358
358
  const yaml = match[1];
359
- const result = {};
359
+ let name = "", description = "";
360
360
  for (const line of yaml.split("\n")) {
361
- if (line.trim() === "metadata:") {
362
- result.metadata = {};
363
- continue;
364
- }
365
- const metadataMatch = line.match(/^\s{2}(\w+):\s*"?([^"]*)"?$/);
366
- if (metadataMatch && result.metadata) {
367
- result.metadata[metadataMatch[1]] = metadataMatch[2];
368
- continue;
369
- }
370
- const fieldMatch = line.match(/^(\S+):\s*(.*)$/);
371
- if (fieldMatch) {
372
- const [, key, value] = fieldMatch;
373
- result[key] = value.replace(/^["']|["']$/g, "");
361
+ const m = line.match(/^(name|description):\s*(.+)$/);
362
+ if (m) {
363
+ const value = m[2].replace(/^["']|["']$/g, "");
364
+ if (m[1] === "name") name = value;
365
+ else description = value;
374
366
  }
375
367
  }
376
- if (!result.name || !result.description) return null;
377
- return result;
368
+ return name && description ? {
369
+ name,
370
+ description
371
+ } : null;
378
372
  }
379
373
  function extractBody(content) {
380
374
  return content.replace(/^---\n[\s\S]*?\n---\n*/, "");
@@ -390,14 +384,12 @@ async function scanSkills(basePath) {
390
384
  const skillDir = join2(basePath, entry.name);
391
385
  const skillFile = join2(skillDir, "SKILL.md");
392
386
  try {
393
- await stat(skillFile);
394
387
  const content = await readFile(skillFile, "utf-8");
395
388
  const frontmatter = parseFrontmatter(content);
396
389
  if (frontmatter && frontmatter.name === entry.name) {
397
390
  skills.push({
398
391
  ...frontmatter,
399
- basePath: skillDir,
400
- filePath: skillFile
392
+ basePath: skillDir
401
393
  });
402
394
  }
403
395
  } catch {
@@ -413,14 +405,16 @@ function generateToolDescription(skills, agentName) {
413
405
  }
414
406
  const skillsList = skills.map((s) => `- ${s.name}: ${s.description}`).join("\n");
415
407
  const toolName = `${agentName}__load-skill`;
416
- return `Load a skill's detailed instructions or reference files for the "${agentName}" agent.
408
+ return `Load a skill's instructions or reference files for the "${agentName}" agent.
417
409
 
418
410
  Available skills:
419
411
  ${skillsList}
420
412
 
421
413
  Usage:
422
414
  - ${toolName}({ skill: "skill-name" }) - Load main SKILL.md content
423
- - ${toolName}({ skill: "skill-name", ref: "references/file.md" }) - Load reference file`;
415
+ - ${toolName}({ skill: "skill-name", ref: "path/to/file" }) - Load reference file
416
+
417
+ Note: For scripts/ and assets/, use appropriate tools directly.`;
424
418
  }
425
419
  function createSkillsPlugin(options) {
426
420
  const { paths } = options;
@@ -455,7 +449,7 @@ function createSkillsPlugin(options) {
455
449
  },
456
450
  ref: {
457
451
  type: "string",
458
- description: "Optional: relative path to a reference file within the skill directory"
452
+ description: "Optional: relative path to any file within the skill directory"
459
453
  }
460
454
  },
461
455
  required: [
@@ -482,12 +476,23 @@ function createSkillsPlugin(options) {
482
476
  content: [
483
477
  {
484
478
  type: "text",
485
- text: `Invalid ref path: ${args.ref}`
479
+ text: `Invalid path: ${args.ref}`
486
480
  }
487
481
  ],
488
482
  isError: true
489
483
  };
490
484
  }
485
+ const dir = relPath.split(/[/\\]/)[0];
486
+ if (dir === "scripts" || dir === "assets") {
487
+ return {
488
+ content: [
489
+ {
490
+ type: "text",
491
+ text: `Path: ${refPath}`
492
+ }
493
+ ]
494
+ };
495
+ }
491
496
  try {
492
497
  const content = await readFile(refPath, "utf-8");
493
498
  return {
@@ -511,7 +516,7 @@ function createSkillsPlugin(options) {
511
516
  }
512
517
  }
513
518
  try {
514
- const content = await readFile(meta.filePath, "utf-8");
519
+ const content = await readFile(join2(meta.basePath, "SKILL.md"), "utf-8");
515
520
  const body = extractBody(content);
516
521
  return {
517
522
  content: [
@@ -1 +1 @@
1
- {"version":3,"file":"skills.d.ts","sources":["../../../src/plugins/skills.ts"],"names":[],"mappings":"AAOA,cAAmC,UAAU,6BAA6B;UAqBhE;EACR,mCAAmC,GACnC,OAAO,MAAM;;AAgHf;;CAEC,GACD,OAAO,iBAAS,mBAAmB,SAAS,mBAAmB,GAAG;AA0HlE;;;;;;;;;;;;;CAaC,GACD,OAAO,iBAAS,aAAa,QAAQ,OAAO,MAAM,EAAE,MAAM,CAAC,GAAG;AAM9D,eAAe,mBAAmB"}
1
+ {"version":3,"file":"skills.d.ts","sources":["../../../src/plugins/skills.ts"],"names":[],"mappings":"AAOA,cAAmC,UAAU,6BAA6B;UAWhE;EACR,mCAAmC,GACnC,OAAO,MAAM;;AAoGf;;CAEC,GACD,OAAO,iBAAS,mBAAmB,SAAS,mBAAmB,GAAG;AAuIlE;;;;;;;;;;;;;CAaC,GACD,OAAO,iBAAS,aAAa,QAAQ,OAAO,MAAM,EAAE,MAAM,CAAC,GAAG;AAM9D,eAAe,mBAAmB"}