psadk 1.3.4 → 1.3.5

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.
@@ -0,0 +1,100 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.PSSkillTool = void 0;
7
+ /* eslint-disable @typescript-eslint/no-explicit-any */
8
+ const v4_1 = require("zod/v4");
9
+ const PSAgentTool_1 = require("../PSAgentTool");
10
+ const utils_1 = require("../skills/utils");
11
+ const debuglogger_1 = __importDefault(require("../utils/debuglogger"));
12
+ const dlog = (0, debuglogger_1.default)('PSAI:SkillTool:');
13
+ //@todo arguments implementations, templated variable values expected in the arguments
14
+ class PSSkillTool extends PSAgentTool_1.PSAgentTool {
15
+ constructor(config) {
16
+ super({
17
+ name: PSSkillTool.toolName,
18
+ description: 'Execute skills by reading their markdown content and injecting it as context. ' +
19
+ 'Skills are reusable knowledge modules that provide specialized guidance and instructions.',
20
+ type: 'API',
21
+ local_execution: true,
22
+ hitl: true,
23
+ inputschema: {
24
+ url: `http://localhost/${PSSkillTool.toolName}`,
25
+ method: 'POST',
26
+ requestBody: v4_1.z.toJSONSchema(v4_1.z
27
+ .object({
28
+ skill_name: v4_1.z.string().meta({
29
+ title: 'Skill_Name',
30
+ description: 'The name of the skill to execute. Must be a valid skill name installed in the skills directory.',
31
+ }),
32
+ arguments: v4_1.z.string().optional().meta({
33
+ title: 'Arguments',
34
+ description: 'Optional arguments or context to provide to the skill. This will be included with the skill content.',
35
+ }),
36
+ })
37
+ .meta({
38
+ title: `${PSSkillTool.toolName}_request_body`,
39
+ description: `The request body parameters for the ${PSSkillTool.toolName} tool.`,
40
+ }), { io: 'input' }),
41
+ },
42
+ });
43
+ this.skillsPath = config.skillsPath;
44
+ this.allowedSkills = config.allowedSkills;
45
+ }
46
+ /**
47
+ * Validates if a skill is allowed to be executed
48
+ */
49
+ isSkillAllowed(skillName) {
50
+ if (!this.allowedSkills) {
51
+ return true; // No restrictions
52
+ }
53
+ return this.allowedSkills.includes(skillName);
54
+ }
55
+ async run(input, log) {
56
+ const logger = log || dlog;
57
+ // Debug logging
58
+ logger.info(`🔍 PSSkillTool received input:`, input);
59
+ // Access properties from request_body (the actual skill parameters are nested)
60
+ const requestBody = (input === null || input === void 0 ? void 0 : input.request_body) || input;
61
+ const skill_name = requestBody === null || requestBody === void 0 ? void 0 : requestBody.skill_name;
62
+ // Validate input
63
+ if (!skill_name || typeof skill_name !== 'string') {
64
+ throw new Error('Invalid skill name provided.');
65
+ }
66
+ // Validate skill name for security
67
+ if (!(0, utils_1.validateSkillName)(skill_name)) {
68
+ throw new Error(`Invalid skill name format: ${skill_name}. Skill names must contain only alphanumeric characters, hyphens, and underscores.`);
69
+ }
70
+ // Check if skill is allowed
71
+ if (!this.isSkillAllowed(skill_name)) {
72
+ throw new Error(`Skill not allowed: ${skill_name}. This agent is restricted to specific skills only.`);
73
+ }
74
+ // Check if skill exists on filesystem
75
+ if (!(0, utils_1.skillExists)(this.skillsPath, skill_name)) {
76
+ throw new Error(`Skill not found: ${skill_name}. Please ensure the skill is installed in ${this.skillsPath}.`);
77
+ }
78
+ try {
79
+ // Read skill content
80
+ const skillContent = await (0, utils_1.readSkillContent)(this.skillsPath, skill_name);
81
+ logger.info(`✅ Skill executed successfully: ${skill_name}`);
82
+ return {
83
+ status: 'success',
84
+ skill_name,
85
+ content: skillContent.content,
86
+ message: `Skill '${skill_name}' has been loaded and its content is now available in your context.`,
87
+ };
88
+ }
89
+ catch (error) {
90
+ logger.error(`❌ Failed to execute skill ${skill_name}:`, error);
91
+ if (error instanceof Error) {
92
+ throw new Error(`Failed to execute skill '${skill_name}': ${error.message}`);
93
+ }
94
+ throw new Error(`Unknown error occurred while executing skill '${skill_name}'`);
95
+ }
96
+ }
97
+ }
98
+ exports.PSSkillTool = PSSkillTool;
99
+ PSSkillTool.toolName = 'skill';
100
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiUFNTa2lsbFRvb2wuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvbGliL3Rvb2xzL1BTU2tpbGxUb29sLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7OztBQUFBLHVEQUF1RDtBQUN2RCwrQkFBMkI7QUFHM0IsZ0RBQTZDO0FBSzdDLDJDQUl5QjtBQUN6Qix1RUFBK0M7QUFFL0MsTUFBTSxJQUFJLEdBQUcsSUFBQSxxQkFBVyxFQUFDLGlCQUFpQixDQUFDLENBQUM7QUFFNUMsc0ZBQXNGO0FBQ3RGLE1BQWEsV0FBWSxTQUFRLHlCQUFXO0lBSzFDLFlBQVksTUFBa0M7UUFDNUMsS0FBSyxDQUFDO1lBQ0osSUFBSSxFQUFFLFdBQVcsQ0FBQyxRQUFRO1lBQzFCLFdBQVcsRUFDVCxnRkFBZ0Y7Z0JBQ2hGLDJGQUEyRjtZQUM3RixJQUFJLEVBQUUsS0FBSztZQUNYLGVBQWUsRUFBRSxJQUFJO1lBQ3JCLElBQUksRUFBRSxJQUFJO1lBQ1YsV0FBVyxFQUFFO2dCQUNYLEdBQUcsRUFBRSxvQkFBb0IsV0FBVyxDQUFDLFFBQVEsRUFBRTtnQkFDL0MsTUFBTSxFQUFFLE1BQU07Z0JBQ2QsV0FBVyxFQUFFLE1BQUMsQ0FBQyxZQUFZLENBQ3pCLE1BQUM7cUJBQ0UsTUFBTSxDQUFDO29CQUNOLFVBQVUsRUFBRSxNQUFDLENBQUMsTUFBTSxFQUFFLENBQUMsSUFBSSxDQUFDO3dCQUMxQixLQUFLLEVBQUUsWUFBWTt3QkFDbkIsV0FBVyxFQUNULGlHQUFpRztxQkFDcEcsQ0FBQztvQkFDRixTQUFTLEVBQUUsTUFBQyxDQUFDLE1BQU0sRUFBRSxDQUFDLFFBQVEsRUFBRSxDQUFDLElBQUksQ0FBQzt3QkFDcEMsS0FBSyxFQUFFLFdBQVc7d0JBQ2xCLFdBQVcsRUFDVCxzR0FBc0c7cUJBQ3pHLENBQUM7aUJBQ0gsQ0FBQztxQkFDRCxJQUFJLENBQUM7b0JBQ0osS0FBSyxFQUFFLEdBQUcsV0FBVyxDQUFDLFFBQVEsZUFBZTtvQkFD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
@@ -11,3 +11,6 @@ export * from './lib/tools/PSWriteFileTool';
11
11
  export * from './lib/tools/PSSubAgentTool';
12
12
  export * from './lib/tools/PSMemoryTool';
13
13
  export * from './lib/tools/PSClarifyTool';
14
+ export * from './lib/tools/PSSkillTool';
15
+ export * from './lib/skills/types';
16
+ export * from './lib/skills/utils';
@@ -27,4 +27,7 @@ __exportStar(require("./lib/tools/PSWriteFileTool"), exports);
27
27
  __exportStar(require("./lib/tools/PSSubAgentTool"), exports);
28
28
  __exportStar(require("./lib/tools/PSMemoryTool"), exports);
29
29
  __exportStar(require("./lib/tools/PSClarifyTool"), exports);
30
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLDZDQUEyQjtBQUMzQixnREFBOEI7QUFDOUIsc0RBQW9DO0FBQ3BDLHNEQUFvQztBQUNwQyxvREFBa0M7QUFDbEMsb0RBQWtDO0FBQ2xDLHVEQUFxQztBQUNyQyxnRUFBOEM7QUFDOUMsNkRBQTJDO0FBQzNDLDhEQUE0QztBQUM1Qyw2REFBMkM7QUFDM0MsMkRBQXlDO0FBQ3pDLDREQUEwQyJ9
30
+ __exportStar(require("./lib/tools/PSSkillTool"), exports);
31
+ __exportStar(require("./lib/skills/types"), exports);
32
+ __exportStar(require("./lib/skills/utils"), exports);
33
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLDZDQUEyQjtBQUMzQixnREFBOEI7QUFDOUIsc0RBQW9DO0FBQ3BDLHNEQUFvQztBQUNwQyxvREFBa0M7QUFDbEMsb0RBQWtDO0FBQ2xDLHVEQUFxQztBQUNyQyxnRUFBOEM7QUFDOUMsNkRBQTJDO0FBQzNDLDhEQUE0QztBQUM1Qyw2REFBMkM7QUFDM0MsMkRBQXlDO0FBQ3pDLDREQUEwQztBQUMxQywwREFBd0M7QUFDeEMscURBQW1DO0FBQ25DLHFEQUFtQyJ9
@@ -2,6 +2,7 @@ declare const SKILL_CONSTANTS: {
2
2
  SKILL_WATCH_PATTERN: string;
3
3
  SKILLS_FOLDER_WATCH_PATTERN: string;
4
4
  SLINGSHOT_DIR: string;
5
+ AGENTS_DIR: string;
5
6
  SKILLS_DIR: string;
6
7
  GLOBAL_SKILLS_DIR: string;
7
8
  SKILL_DEFINITION_FILE: string;
@@ -6,6 +6,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  const STATIC_CONSTANTS = {
7
7
  // Directory names
8
8
  SLINGSHOT_DIR: '.slingshot',
9
+ AGENTS_DIR: '.agents', // Base directory for npx skills CLI
9
10
  SKILLS_DIR: 'skills',
10
11
  GLOBAL_SKILLS_DIR: 'skills', // For extension global path
11
12
  // File names
@@ -23,4 +24,4 @@ const SKILL_CONSTANTS = {
23
24
  SKILLS_FOLDER_WATCH_PATTERN: `${STATIC_CONSTANTS.SLINGSHOT_DIR}/${STATIC_CONSTANTS.SKILLS_DIR}/**`,
24
25
  };
25
26
  exports.default = SKILL_CONSTANTS;
26
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uc3RhbnRzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2xpYi9za2lsbHMvY29uc3RhbnRzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUE7O0dBRUc7QUFDSCxNQUFNLGdCQUFnQixHQUFHO0lBQ3ZCLGtCQUFrQjtJQUNsQixhQUFhLEVBQUUsWUFBWTtJQUMzQixVQUFVLEVBQUUsUUFBUTtJQUNwQixpQkFBaUIsRUFBRSxRQUFRLEVBQUUsNEJBQTRCO0lBRXpELGFBQWE7SUFDYixxQkFBcUIsRUFBRSxVQUFVO0lBQ2pDLGFBQWEsRUFBRSxxQkFBcUI7SUFDcEMsVUFBVSxFQUFFLG1CQUFtQjtJQUUvQixTQUFTO0lBQ1QsY0FBYyxFQUFFLEdBQUcsRUFBRSxlQUFlO0NBQ3JDLENBQUM7QUFFRixNQUFNLGVBQWUsR0FBRztJQUN0QixHQUFHLGdCQUFnQjtJQUNuQix3Q0FBd0M7SUFDeEMsbUJBQW1CLEVBQUUsR0FBRyxnQkFBZ0IsQ0FBQyxhQUFhLElBQUksZ0JBQWdCLENBQUMsVUFBVSxPQUFPLGdCQUFnQixDQUFDLHFCQUFxQixFQUFFO0lBQ3BJLHlFQUF5RTtJQUN6RSwyQkFBMkIsRUFBRSxHQUFHLGdCQUFnQixDQUFDLGFBQWEsSUFBSSxnQkFBZ0IsQ0FBQyxVQUFVLEtBQUs7Q0FDbkcsQ0FBQztBQUVGLGtCQUFlLGVBQWUsQ0FBQyJ9
27
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uc3RhbnRzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2xpYi9za2lsbHMvY29uc3RhbnRzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUE7O0dBRUc7QUFDSCxNQUFNLGdCQUFnQixHQUFHO0lBQ3ZCLGtCQUFrQjtJQUNsQixhQUFhLEVBQUUsWUFBWTtJQUMzQixVQUFVLEVBQUUsU0FBUyxFQUFFLG9DQUFvQztJQUMzRCxVQUFVLEVBQUUsUUFBUTtJQUNwQixpQkFBaUIsRUFBRSxRQUFRLEVBQUUsNEJBQTRCO0lBRXpELGFBQWE7SUFDYixxQkFBcUIsRUFBRSxVQUFVO0lBQ2pDLGFBQWEsRUFBRSxxQkFBcUI7SUFDcEMsVUFBVSxFQUFFLG1CQUFtQjtJQUUvQixTQUFTO0lBQ1QsY0FBYyxFQUFFLEdBQUcsRUFBRSxlQUFlO0NBQ3JDLENBQUM7QUFFRixNQUFNLGVBQWUsR0FBRztJQUN0QixHQUFHLGdCQUFnQjtJQUNuQix3Q0FBd0M7SUFDeEMsbUJBQW1CLEVBQUUsR0FBRyxnQkFBZ0IsQ0FBQyxhQUFhLElBQUksZ0JBQWdCLENBQUMsVUFBVSxPQUFPLGdCQUFnQixDQUFDLHFCQUFxQixFQUFFO0lBQ3BJLHlFQUF5RTtJQUN6RSwyQkFBMkIsRUFBRSxHQUFHLGdCQUFnQixDQUFDLGFBQWEsSUFBSSxnQkFBZ0IsQ0FBQyxVQUFVLEtBQUs7Q0FDbkcsQ0FBQztBQUVGLGtCQUFlLGVBQWUsQ0FBQyJ9
@@ -1,5 +1,10 @@
1
+ import { SkillMetadata } from './types';
1
2
  /**
2
- * Parses a SKILL.md file to extract metadata for the registry.
3
+ * Parses a SKILL.md file content to extract all metadata using gray-matter
4
+ */
5
+ export declare function parseSkillMetadataFromContent(content: string, skillPath: string): SkillMetadata;
6
+ /**
7
+ * Parses a SKILL.md file to extract metadata for the registry (legacy format)
3
8
  * @param {string} filePath - The absolute path to the SKILL.md file.
4
9
  * @returns {Object|null} - Returns { name, description, folderPath } or null if invalid.
5
10
  */
@@ -3,12 +3,27 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.parseSkillMetadataFromContent = parseSkillMetadataFromContent;
6
7
  exports.default = parseSkillMetadata;
7
8
  const node_fs_1 = __importDefault(require("node:fs"));
8
9
  const node_path_1 = __importDefault(require("node:path"));
9
- const yaml_1 = __importDefault(require("yaml"));
10
+ const gray_matter_1 = __importDefault(require("gray-matter"));
10
11
  /**
11
- * Parses a SKILL.md file to extract metadata for the registry.
12
+ * Parses a SKILL.md file content to extract all metadata using gray-matter
13
+ */
14
+ function parseSkillMetadataFromContent(content, skillPath) {
15
+ const parsed = (0, gray_matter_1.default)(content);
16
+ return {
17
+ name: parsed.data.name || 'unknown',
18
+ description: parsed.data.description || 'No description available',
19
+ version: parsed.data.version,
20
+ author: parsed.data.author,
21
+ license: parsed.data.license,
22
+ path: skillPath,
23
+ };
24
+ }
25
+ /**
26
+ * Parses a SKILL.md file to extract metadata for the registry (legacy format)
12
27
  * @param {string} filePath - The absolute path to the SKILL.md file.
13
28
  * @returns {Object|null} - Returns { name, description, folderPath } or null if invalid.
14
29
  */
@@ -18,23 +33,18 @@ function parseSkillMetadata(filePath) {
18
33
  return null;
19
34
  }
20
35
  const fileContent = node_fs_1.default.readFileSync(filePath, 'utf8');
21
- // Use gray-matter to parse YAML frontmatter safely
22
- const data = yaml_1.default.parse(fileContent);
23
- // Validation: Name is required by the spec
24
- if (!data || !data.name) {
25
- return null;
26
- }
27
- const trimmedName = data.name.trim();
28
- const trimmedDescription = data.description ? data.description.trim() : '';
36
+ const skillPath = node_path_1.default.dirname(filePath);
37
+ // Parse using the unified function
38
+ const fullMetadata = parseSkillMetadataFromContent(fileContent, skillPath);
39
+ // Return legacy format for backward compatibility
29
40
  return {
30
- name: trimmedName,
31
- description: trimmedDescription || 'No description provided.',
32
- // We store the directory path, not the file path, as that's the "Skill Root"
33
- folderPath: node_path_1.default.dirname(filePath),
41
+ name: fullMetadata.name,
42
+ description: fullMetadata.description,
43
+ folderPath: fullMetadata.path,
34
44
  };
35
45
  }
36
46
  catch {
37
47
  return null;
38
48
  }
39
49
  }
40
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2tpbGxQYXJzZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvbGliL3NraWxscy9za2lsbFBhcnNlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQVVBLHFDQThCQztBQXhDRCxzREFBeUI7QUFDekIsMERBQTZCO0FBRTdCLGdEQUF3QjtBQUV4Qjs7OztHQUlHO0FBQ0gsU0FBd0Isa0JBQWtCLENBQ3hDLFFBQWdCO0lBRWhCLElBQUksQ0FBQztRQUNILElBQUksQ0FBQyxpQkFBRSxDQUFDLFVBQVUsQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDO1lBQzdCLE9BQU8sSUFBSSxDQUFDO1FBQ2QsQ0FBQztRQUVELE1BQU0sV0FBVyxHQUFHLGlCQUFFLENBQUMsWUFBWSxDQUFDLFFBQVEsRUFBRSxNQUFNLENBQUMsQ0FBQztRQUV0RCxtREFBbUQ7UUFDbkQsTUFBTSxJQUFJLEdBQUcsY0FBSSxDQUFDLEtBQUssQ0FBQyxXQUFXLENBQUMsQ0FBQztRQUVyQywyQ0FBMkM7UUFDM0MsSUFBSSxDQUFDLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQztZQUN4QixPQUFPLElBQUksQ0FBQztRQUNkLENBQUM7UUFFRCxNQUFNLFdBQVcsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDO1FBQ3JDLE1BQU0sa0JBQWtCLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO1FBRTNFLE9BQU87WUFDTCxJQUFJLEVBQUUsV0FBVztZQUNqQixXQUFXLEVBQUUsa0JBQWtCLElBQUksMEJBQTBCO1lBQzdELDZFQUE2RTtZQUM3RSxVQUFVLEVBQUUsbUJBQUksQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDO1NBQ25DLENBQUM7SUFDSixDQUFDO0lBQUMsTUFBTSxDQUFDO1FBQ1AsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0FBQ0gsQ0FBQyJ9
50
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2tpbGxQYXJzZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvbGliL3NraWxscy9za2lsbFBhcnNlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQVVBLHNFQWNDO0FBT0QscUNBdUJDO0FBdERELHNEQUF5QjtBQUN6QiwwREFBNkI7QUFFN0IsOERBQWlDO0FBSWpDOztHQUVHO0FBQ0gsU0FBZ0IsNkJBQTZCLENBQzNDLE9BQWUsRUFDZixTQUFpQjtJQUVqQixNQUFNLE1BQU0sR0FBRyxJQUFBLHFCQUFNLEVBQUMsT0FBTyxDQUFDLENBQUM7SUFFL0IsT0FBTztRQUNMLElBQUksRUFBRSxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksSUFBSSxTQUFTO1FBQ25DLFdBQVcsRUFBRSxNQUFNLENBQUMsSUFBSSxDQUFDLFdBQVcsSUFBSSwwQkFBMEI7UUFDbEUsT0FBTyxFQUFFLE1BQU0sQ0FBQyxJQUFJLENBQUMsT0FBTztRQUM1QixNQUFNLEVBQUUsTUFBTSxDQUFDLElBQUksQ0FBQyxNQUFNO1FBQzFCLE9BQU8sRUFBRSxNQUFNLENBQUMsSUFBSSxDQUFDLE9BQU87UUFDNUIsSUFBSSxFQUFFLFNBQVM7S0FDaEIsQ0FBQztBQUNKLENBQUM7QUFFRDs7OztHQUlHO0FBQ0gsU0FBd0Isa0JBQWtCLENBQ3hDLFFBQWdCO0lBRWhCLElBQUksQ0FBQztRQUNILElBQUksQ0FBQyxpQkFBRSxDQUFDLFVBQVUsQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDO1lBQzdCLE9BQU8sSUFBSSxDQUFDO1FBQ2QsQ0FBQztRQUVELE1BQU0sV0FBVyxHQUFHLGlCQUFFLENBQUMsWUFBWSxDQUFDLFFBQVEsRUFBRSxNQUFNLENBQUMsQ0FBQztRQUN0RCxNQUFNLFNBQVMsR0FBRyxtQkFBSSxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUV6QyxtQ0FBbUM7UUFDbkMsTUFBTSxZQUFZLEdBQUcsNkJBQTZCLENBQUMsV0FBVyxFQUFFLFNBQVMsQ0FBQyxDQUFDO1FBRTNFLGtEQUFrRDtRQUNsRCxPQUFPO1lBQ0wsSUFBSSxFQUFFLFlBQVksQ0FBQyxJQUFJO1lBQ3ZCLFdBQVcsRUFBRSxZQUFZLENBQUMsV0FBVztZQUNyQyxVQUFVLEVBQUUsWUFBWSxDQUFDLElBQUk7U0FDOUIsQ0FBQztJQUNKLENBQUM7SUFBQyxNQUFNLENBQUM7UUFDUCxPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7QUFDSCxDQUFDIn0=
@@ -0,0 +1,61 @@
1
+ export interface SkillContent {
2
+ metadata: SkillFrontmatter;
3
+ content: string;
4
+ rawContent: string;
5
+ }
6
+ export interface SkillFrontmatter {
7
+ name: string;
8
+ description: string;
9
+ version: string;
10
+ author: string;
11
+ dependencies?: string[];
12
+ }
13
+ export interface SkillSourceConfig {
14
+ source: string;
15
+ sourceType?: 'git' | 'npm' | 'local';
16
+ version?: string;
17
+ branch?: string;
18
+ }
19
+ export interface SkillSourcesObject {
20
+ [skillName: string]: SkillSourceConfig;
21
+ }
22
+ export interface PSSkillToolConfig {
23
+ skillsPath: string;
24
+ allowedSkills?: string[];
25
+ skillSources?: SkillSourcesObject;
26
+ autoInstall?: boolean;
27
+ }
28
+ export interface PSSkillToolExecutionConfig {
29
+ skillsPath: string;
30
+ allowedSkills?: string[];
31
+ }
32
+ export interface SkillInstallationOptions {
33
+ source: string;
34
+ skillsPath: string;
35
+ timeout?: number;
36
+ }
37
+ export interface SkillInvocation {
38
+ skill_name: string;
39
+ arguments?: string;
40
+ }
41
+ export interface SkillMetadata {
42
+ name: string;
43
+ description: string;
44
+ path: string;
45
+ version?: string;
46
+ author?: string;
47
+ license?: string;
48
+ }
49
+ export interface SkillExecutionResult {
50
+ status: 'success' | 'error';
51
+ skill_name: string;
52
+ content?: string;
53
+ metadata?: {
54
+ name: string;
55
+ description: string;
56
+ version: string;
57
+ author: string;
58
+ };
59
+ message: string;
60
+ error?: string;
61
+ }
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvbGliL3NraWxscy90eXBlcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiIn0=
@@ -1,3 +1,5 @@
1
+ import { IStreamLogger } from '../PSAgentLogger';
2
+ import { SkillContent, SkillInstallationOptions, SkillMetadata, SkillSourcesObject } from './types';
1
3
  /**
2
4
  * Gets the slingshot directories for both workspace and user levels.
3
5
  * Creates the directories if they don't exist.
@@ -8,3 +10,57 @@ export default function getSlingshotDirectories(repoRoot: string): {
8
10
  workspaceLevelSlingshotDir: string | null;
9
11
  userLevelSlingshotDir: string | null;
10
12
  };
13
+ /**
14
+ * Validates skill name for security (prevents path traversal)
15
+ */
16
+ export declare function validateSkillName(skillName: string): boolean;
17
+ /**
18
+ * Validates skill source URL for security (prevents command injection)
19
+ */
20
+ export declare function validateSkillSource(source: string): boolean;
21
+ /**
22
+ * Ensures skills directory exists
23
+ */
24
+ export declare function ensureSkillsDirectory(skillsPath: string): Promise<void>;
25
+ /**
26
+ * Gets the path to a skill's SKILL.md file
27
+ * Skills are stored in the .agents/skills subdirectory as created by npx skills CLI
28
+ */
29
+ export declare function getSkillFilePath(skillsPath: string, skillName: string): string;
30
+ /**
31
+ * Checks if a skill exists locally
32
+ */
33
+ export declare function skillExists(skillsPath: string, skillName: string): boolean;
34
+ /**
35
+ * Reads skill content and parses frontmatter using skillParser
36
+ */
37
+ export declare function readSkillContent(skillsPath: string, skillName: string): Promise<SkillContent>;
38
+ /**
39
+ * Scans a directory for installed skills and returns metadata
40
+ */
41
+ export declare function scanInstalledSkills(skillsPath: string): Promise<Map<string, SkillMetadata>>;
42
+ /**
43
+ * Normalizes skill source URLs to handle common formatting issues
44
+ */
45
+ export declare function normalizeSkillSource(source: string): string;
46
+ /**
47
+ * Extract skill name from source URL
48
+ */
49
+ export declare function extractSkillName(source: string): string;
50
+ /**
51
+ * Install a skill using npx skills command (simplified)
52
+ */
53
+ export declare function installSkill(options: SkillInstallationOptions): Promise<SkillMetadata>;
54
+ /**
55
+ * Converts skill metadata to XML format for system prompts
56
+ */
57
+ export declare function convertSkillsToSystemPromptXml(skills: SkillMetadata[]): string;
58
+ /**
59
+ * Get skills XML from a skills directory scan
60
+ */
61
+ export declare function getSkillsSystemPromptFromDirectory(skillsPath: string): Promise<string>;
62
+ /**
63
+ * Setup skills directory and get system prompt
64
+ * Accepts skill sources as an object mapping skill names to source configurations
65
+ */
66
+ export declare function setupSkillsAndGetPrompt(skillsPath: string, sources?: SkillSourcesObject, log?: IStreamLogger): Promise<string>;