opencode-lazy-loader 1.0.0 → 1.0.1

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,13 @@
1
+ import { type ToolDefinition } from '@opencode-ai/plugin';
2
+ import type { LoadedSkill } from '../types.js';
3
+ import type { SkillMcpManager } from '../skill-mcp-manager.js';
4
+ export interface CreateSkillMcpToolOptions {
5
+ manager: SkillMcpManager;
6
+ getLoadedSkills: () => LoadedSkill[];
7
+ getSessionID: () => string;
8
+ }
9
+ /**
10
+ * Create the skill_mcp tool
11
+ */
12
+ export declare function createSkillMcpTool(options: CreateSkillMcpToolOptions): ToolDefinition;
13
+ //# sourceMappingURL=skill-mcp.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skill-mcp.d.ts","sourceRoot":"","sources":["../../src/tools/skill-mcp.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,KAAK,cAAc,EAAE,MAAM,qBAAqB,CAAA;AAC/D,OAAO,KAAK,EAAE,WAAW,EAAmB,MAAM,aAAa,CAAA;AAC/D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAA;AAqI9D,MAAM,WAAW,yBAAyB;IACxC,OAAO,EAAE,eAAe,CAAA;IACxB,eAAe,EAAE,MAAM,WAAW,EAAE,CAAA;IACpC,YAAY,EAAE,MAAM,MAAM,CAAA;CAC3B;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,yBAAyB,GAAG,cAAc,CAoErF"}
@@ -0,0 +1,162 @@
1
+ import { tool } from '@opencode-ai/plugin';
2
+ const SKILL_MCP_DESCRIPTION = `Invoke MCP server operations from skill-embedded MCPs. Requires mcp_name plus exactly one of: tool_name, resource_name, or prompt_name.`;
3
+ /**
4
+ * Validate that exactly one operation parameter is provided
5
+ */
6
+ function validateOperationParams(args) {
7
+ const operations = [];
8
+ if (args.tool_name) {
9
+ operations.push({ type: 'tool', name: args.tool_name });
10
+ }
11
+ if (args.resource_name) {
12
+ operations.push({ type: 'resource', name: args.resource_name });
13
+ }
14
+ if (args.prompt_name) {
15
+ operations.push({ type: 'prompt', name: args.prompt_name });
16
+ }
17
+ if (operations.length === 0) {
18
+ throw new Error(`Missing operation. Exactly one of tool_name, resource_name, or prompt_name must be specified.\n\n` +
19
+ `Examples:\n` +
20
+ ` skill_mcp(mcp_name="sqlite", tool_name="query", arguments='{"sql": "SELECT * FROM users"}')\n` +
21
+ ` skill_mcp(mcp_name="memory", resource_name="memory://notes")\n` +
22
+ ` skill_mcp(mcp_name="helper", prompt_name="summarize", arguments='{"text": "..."}')`);
23
+ }
24
+ if (operations.length > 1) {
25
+ const provided = [
26
+ args.tool_name && `tool_name="${args.tool_name}"`,
27
+ args.resource_name && `resource_name="${args.resource_name}"`,
28
+ args.prompt_name && `prompt_name="${args.prompt_name}"`
29
+ ].filter(Boolean).join(', ');
30
+ throw new Error(`Multiple operations specified. Exactly one of tool_name, resource_name, or prompt_name must be provided.\n\n` +
31
+ `Received: ${provided}\n\n` +
32
+ `Use separate calls for each operation.`);
33
+ }
34
+ return operations[0];
35
+ }
36
+ /**
37
+ * Find an MCP server configuration by name across all skills
38
+ */
39
+ function findMcpServer(mcpName, skills) {
40
+ for (const skill of skills) {
41
+ if (skill.mcpConfig && mcpName in skill.mcpConfig) {
42
+ return { skill, config: skill.mcpConfig[mcpName] };
43
+ }
44
+ }
45
+ return null;
46
+ }
47
+ /**
48
+ * Format available MCPs for error message
49
+ */
50
+ function formatAvailableMcps(skills) {
51
+ const mcps = [];
52
+ for (const skill of skills) {
53
+ if (skill.mcpConfig) {
54
+ for (const serverName of Object.keys(skill.mcpConfig)) {
55
+ mcps.push(` - "${serverName}" from skill "${skill.name}"`);
56
+ }
57
+ }
58
+ }
59
+ return mcps.length > 0 ? mcps.join('\n') : ' (none found)';
60
+ }
61
+ /**
62
+ * Parse JSON arguments string
63
+ */
64
+ function parseArguments(argsJson) {
65
+ if (!argsJson) {
66
+ return {};
67
+ }
68
+ try {
69
+ const parsed = JSON.parse(argsJson);
70
+ if (typeof parsed !== 'object' || parsed === null) {
71
+ throw new Error('Arguments must be a JSON object');
72
+ }
73
+ return parsed;
74
+ }
75
+ catch (error) {
76
+ const errorMessage = error instanceof Error ? error.message : String(error);
77
+ throw new Error(`Invalid arguments JSON: ${errorMessage}\n\n` +
78
+ `Expected a valid JSON object, e.g.: '{"key": "value"}'\n` +
79
+ `Received: ${argsJson}`);
80
+ }
81
+ }
82
+ /**
83
+ * Apply grep filter to output
84
+ */
85
+ function applyGrepFilter(output, pattern) {
86
+ if (!pattern) {
87
+ return output;
88
+ }
89
+ try {
90
+ const regex = new RegExp(pattern, 'i');
91
+ const lines = output.split('\n');
92
+ const filtered = lines.filter((line) => regex.test(line));
93
+ return filtered.length > 0
94
+ ? filtered.join('\n')
95
+ : `[grep] No lines matched pattern: ${pattern}`;
96
+ }
97
+ catch {
98
+ return output;
99
+ }
100
+ }
101
+ /**
102
+ * Create the skill_mcp tool
103
+ */
104
+ export function createSkillMcpTool(options) {
105
+ const { manager, getLoadedSkills, getSessionID } = options;
106
+ return tool({
107
+ description: SKILL_MCP_DESCRIPTION,
108
+ args: {
109
+ mcp_name: tool.schema.string().describe('Name of the MCP server from skill config'),
110
+ tool_name: tool.schema.string().optional().describe('MCP tool to call'),
111
+ resource_name: tool.schema.string().optional().describe('MCP resource URI to read'),
112
+ prompt_name: tool.schema.string().optional().describe('MCP prompt to get'),
113
+ arguments: tool.schema.string().optional().describe('JSON string of arguments'),
114
+ grep: tool.schema.string().optional().describe('Regex pattern to filter output lines (only matching lines returned)')
115
+ },
116
+ async execute(args) {
117
+ const operation = validateOperationParams(args);
118
+ const skills = getLoadedSkills();
119
+ const found = findMcpServer(args.mcp_name, skills);
120
+ if (!found) {
121
+ throw new Error(`MCP server "${args.mcp_name}" not found.\n\n` +
122
+ `Available MCP servers in loaded skills:\n` +
123
+ formatAvailableMcps(skills) + '\n\n' +
124
+ `Hint: Load the skill first using the 'skill' tool, then call skill_mcp.`);
125
+ }
126
+ const info = {
127
+ serverName: args.mcp_name,
128
+ skillName: found.skill.name,
129
+ sessionID: getSessionID()
130
+ };
131
+ const context = {
132
+ config: found.config,
133
+ skillName: found.skill.name
134
+ };
135
+ const parsedArgs = parseArguments(args.arguments);
136
+ let output;
137
+ switch (operation.type) {
138
+ case 'tool': {
139
+ const result = await manager.callTool(info, context, operation.name, parsedArgs);
140
+ output = JSON.stringify(result, null, 2);
141
+ break;
142
+ }
143
+ case 'resource': {
144
+ const result = await manager.readResource(info, context, operation.name);
145
+ output = JSON.stringify(result, null, 2);
146
+ break;
147
+ }
148
+ case 'prompt': {
149
+ const stringArgs = {};
150
+ for (const [key, value] of Object.entries(parsedArgs)) {
151
+ stringArgs[key] = String(value);
152
+ }
153
+ const result = await manager.getPrompt(info, context, operation.name, stringArgs);
154
+ output = JSON.stringify(result, null, 2);
155
+ break;
156
+ }
157
+ }
158
+ return applyGrepFilter(output, args.grep);
159
+ }
160
+ });
161
+ }
162
+ //# sourceMappingURL=skill-mcp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skill-mcp.js","sourceRoot":"","sources":["../../src/tools/skill-mcp.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import { type ToolDefinition } from '@opencode-ai/plugin';
2
+ import type { LoadedSkill } from '../types.js';
3
+ import type { SkillMcpManager } from '../skill-mcp-manager.js';
4
+ export interface CreateSkillToolOptions {
5
+ skills: LoadedSkill[];
6
+ mcpManager?: SkillMcpManager;
7
+ getSessionID?: () => string;
8
+ }
9
+ /**
10
+ * Create the skill tool
11
+ */
12
+ export declare function createSkillTool(options: CreateSkillToolOptions): ToolDefinition;
13
+ //# sourceMappingURL=skill.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skill.d.ts","sourceRoot":"","sources":["../../src/tools/skill.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,KAAK,cAAc,EAAE,MAAM,qBAAqB,CAAA;AAE/D,OAAO,KAAK,EAAE,WAAW,EAAmB,MAAM,aAAa,CAAA;AAC/D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAA;AAqK9D,MAAM,WAAW,sBAAsB;IACrC,MAAM,EAAE,WAAW,EAAE,CAAA;IACrB,UAAU,CAAC,EAAE,eAAe,CAAA;IAC5B,YAAY,CAAC,EAAE,MAAM,MAAM,CAAA;CAC5B;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,sBAAsB,GAAG,cAAc,CAgD/E"}
@@ -0,0 +1,160 @@
1
+ import { tool } from '@opencode-ai/plugin';
2
+ import { dirname } from 'path';
3
+ import { parseFrontmatter } from '../utils/frontmatter.js';
4
+ const TOOL_DESCRIPTION_NO_SKILLS = 'Load a skill to get detailed instructions for a specific task. No skills are currently available.';
5
+ const TOOL_DESCRIPTION_PREFIX = `Load a skill to get detailed instructions for a specific task.
6
+
7
+ Skills provide specialized knowledge and step-by-step guidance.
8
+ Use this when a task matches an available skill's description.`;
9
+ /**
10
+ * Convert loaded skill to info for display
11
+ */
12
+ function loadedSkillToInfo(skill) {
13
+ return {
14
+ name: skill.name,
15
+ description: skill.definition.description || '',
16
+ scope: skill.scope
17
+ };
18
+ }
19
+ /**
20
+ * Format skills as XML for tool description
21
+ */
22
+ function formatSkillsXml(skills) {
23
+ if (skills.length === 0)
24
+ return '';
25
+ const skillsXml = skills.map((skill) => {
26
+ return [
27
+ ' <skill>',
28
+ ` <name>${skill.name}</name>`,
29
+ ` <description>${skill.description}</description>`,
30
+ ' </skill>'
31
+ ].join('\n');
32
+ }).join('\n');
33
+ return `
34
+
35
+ <available_skills>
36
+ ${skillsXml}
37
+ </available_skills>`;
38
+ }
39
+ /**
40
+ * Extract skill body content
41
+ */
42
+ async function extractSkillBody(skill) {
43
+ if (skill.lazyContent) {
44
+ const fullTemplate = await skill.lazyContent.load();
45
+ const templateMatch = fullTemplate.match(/<skill-instruction>([\s\S]*?)<\/skill-instruction>/);
46
+ return templateMatch ? templateMatch[1].trim() : fullTemplate;
47
+ }
48
+ if (skill.path) {
49
+ const { readFileSync } = await import('fs');
50
+ const content = readFileSync(skill.path, 'utf-8');
51
+ const { body } = parseFrontmatter(content);
52
+ return body.trim();
53
+ }
54
+ const templateMatch = skill.definition.template?.match(/<skill-instruction>([\s\S]*?)<\/skill-instruction>/);
55
+ return templateMatch ? templateMatch[1].trim() : skill.definition.template || '';
56
+ }
57
+ /**
58
+ * Format MCP capabilities for display
59
+ */
60
+ async function formatMcpCapabilities(skill, manager, sessionID) {
61
+ if (!skill.mcpConfig || Object.keys(skill.mcpConfig).length === 0) {
62
+ return null;
63
+ }
64
+ const sections = ['', '## Available MCP Servers', ''];
65
+ for (const [serverName, config] of Object.entries(skill.mcpConfig)) {
66
+ const info = {
67
+ serverName,
68
+ skillName: skill.name,
69
+ sessionID
70
+ };
71
+ const context = {
72
+ config: config,
73
+ skillName: skill.name
74
+ };
75
+ sections.push(`### ${serverName}`);
76
+ sections.push('');
77
+ try {
78
+ const [tools, resources, prompts] = await Promise.all([
79
+ manager.listTools(info, context).catch(() => []),
80
+ manager.listResources(info, context).catch(() => []),
81
+ manager.listPrompts(info, context).catch(() => [])
82
+ ]);
83
+ if (tools.length > 0) {
84
+ sections.push('**Tools:**');
85
+ sections.push('');
86
+ for (const t of tools) {
87
+ sections.push(`#### \`${t.name}\``);
88
+ if (t.description) {
89
+ sections.push(t.description);
90
+ }
91
+ sections.push('');
92
+ sections.push('**inputSchema:**');
93
+ sections.push('```json');
94
+ sections.push(JSON.stringify(t.inputSchema, null, 2));
95
+ sections.push('```');
96
+ sections.push('');
97
+ }
98
+ }
99
+ if (resources.length > 0) {
100
+ sections.push(`**Resources**: ${resources.map((r) => r.uri).join(', ')}`);
101
+ }
102
+ if (prompts.length > 0) {
103
+ sections.push(`**Prompts**: ${prompts.map((p) => p.name).join(', ')}`);
104
+ }
105
+ if (tools.length === 0 && resources.length === 0 && prompts.length === 0) {
106
+ sections.push('*No capabilities discovered*');
107
+ }
108
+ }
109
+ catch (error) {
110
+ const errorMessage = error instanceof Error ? error.message : String(error);
111
+ sections.push(`*Failed to connect: ${errorMessage.split('\n')[0]}*`);
112
+ }
113
+ sections.push('');
114
+ sections.push(`Use \`skill_mcp\` tool with \`mcp_name="${serverName}"\` to invoke.`);
115
+ sections.push('');
116
+ }
117
+ return sections.join('\n');
118
+ }
119
+ /**
120
+ * Create the skill tool
121
+ */
122
+ export function createSkillTool(options) {
123
+ const { skills, mcpManager, getSessionID } = options;
124
+ // Build description with available skills
125
+ const skillInfos = skills.map(loadedSkillToInfo);
126
+ const description = skillInfos.length === 0
127
+ ? TOOL_DESCRIPTION_NO_SKILLS
128
+ : TOOL_DESCRIPTION_PREFIX + formatSkillsXml(skillInfos);
129
+ return tool({
130
+ description,
131
+ args: {
132
+ name: tool.schema.string().describe("The skill identifier from available_skills (e.g., 'code-review' or 'my-skill')")
133
+ },
134
+ async execute(args) {
135
+ const skill = skills.find((s) => s.name === args.name);
136
+ if (!skill) {
137
+ const available = skills.map((s) => s.name).join(', ');
138
+ throw new Error(`Skill "${args.name}" not found. Available skills: ${available || 'none'}`);
139
+ }
140
+ const body = await extractSkillBody(skill);
141
+ const dir = skill.path ? dirname(skill.path) : skill.resolvedPath || process.cwd();
142
+ const output = [
143
+ `## Skill: ${skill.name}`,
144
+ '',
145
+ `**Base directory**: ${dir}`,
146
+ '',
147
+ body
148
+ ];
149
+ // Add MCP capabilities if manager available
150
+ if (mcpManager && getSessionID && skill.mcpConfig) {
151
+ const mcpInfo = await formatMcpCapabilities(skill, mcpManager, getSessionID());
152
+ if (mcpInfo) {
153
+ output.push(mcpInfo);
154
+ }
155
+ }
156
+ return output.join('\n');
157
+ }
158
+ });
159
+ }
160
+ //# sourceMappingURL=skill.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skill.js","sourceRoot":"","sources":["../../src/tools/skill.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,70 @@
1
+ /**
2
+ * Configuration for an MCP server
3
+ */
4
+ export interface McpServerConfig {
5
+ command?: string | string[];
6
+ environment?: Record<string, string>;
7
+ }
8
+ /**
9
+ * Skill scope - where the skill was loaded from
10
+ */
11
+ export type SkillScope = 'opencode' | 'opencode-project';
12
+ /**
13
+ * Lazy content loader for skill templates
14
+ */
15
+ export interface LazyContent {
16
+ loaded: boolean;
17
+ content?: string;
18
+ load: () => Promise<string>;
19
+ }
20
+ /**
21
+ * Skill definition stored with the skill
22
+ */
23
+ export interface SkillDefinition {
24
+ name: string;
25
+ description: string;
26
+ template: string;
27
+ }
28
+ /**
29
+ * A loaded skill with all metadata
30
+ */
31
+ export interface LoadedSkill {
32
+ name: string;
33
+ path?: string;
34
+ resolvedPath?: string;
35
+ definition: SkillDefinition;
36
+ scope: SkillScope;
37
+ mcpConfig?: Record<string, McpServerConfig>;
38
+ lazyContent?: LazyContent;
39
+ }
40
+ /**
41
+ * Information needed to identify an MCP client connection
42
+ */
43
+ export interface McpClientInfo {
44
+ sessionID: string;
45
+ skillName: string;
46
+ serverName: string;
47
+ }
48
+ /**
49
+ * Context for MCP operations
50
+ */
51
+ export interface McpContext {
52
+ config: McpServerConfig;
53
+ skillName: string;
54
+ }
55
+ /**
56
+ * Parsed frontmatter data from skill markdown
57
+ */
58
+ export interface SkillFrontmatter {
59
+ name?: string;
60
+ description?: string;
61
+ mcp?: Record<string, McpServerConfig>;
62
+ }
63
+ /**
64
+ * Result of parsing a markdown file with frontmatter
65
+ */
66
+ export interface ParsedFrontmatter {
67
+ data: SkillFrontmatter;
68
+ body: string;
69
+ }
70
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CACrC;AAED;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG,UAAU,GAAG,kBAAkB,CAAA;AAExD;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,OAAO,CAAA;IACf,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,IAAI,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAA;CAC5B;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,MAAM,CAAA;IACnB,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,UAAU,EAAE,eAAe,CAAA;IAC3B,KAAK,EAAE,UAAU,CAAA;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAA;IAC3C,WAAW,CAAC,EAAE,WAAW,CAAA;CAC1B;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;IACjB,UAAU,EAAE,MAAM,CAAA;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,eAAe,CAAA;IACvB,SAAS,EAAE,MAAM,CAAA;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAA;CACtC;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,gBAAgB,CAAA;IACtB,IAAI,EAAE,MAAM,CAAA;CACb"}
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Expand environment variables in a string
3
+ * Supports ${VAR} and ${VAR:-default} syntax
4
+ */
5
+ export declare function expandEnvVars(value: string): string;
6
+ /**
7
+ * Recursively expand environment variables in an object
8
+ */
9
+ export declare function expandEnvVarsInObject<T>(obj: T): T;
10
+ /**
11
+ * Create a clean environment for MCP processes
12
+ * Merges process.env with custom env vars, expanding variables
13
+ */
14
+ export declare function createCleanMcpEnvironment(customEnv?: Record<string, string>): Record<string, string>;
15
+ //# sourceMappingURL=env-vars.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env-vars.d.ts","sourceRoot":"","sources":["../../src/utils/env-vars.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAOnD;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,CAkBlD;AAED;;;GAGG;AACH,wBAAgB,yBAAyB,CACvC,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GACjC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CA6BxB"}
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Expand environment variables in a string
3
+ * Supports ${VAR} and ${VAR:-default} syntax
4
+ */
5
+ export function expandEnvVars(value) {
6
+ return value.replace(/\$\{([^}:]+)(?::-([^}]*))?\}/g, (_, varName, defaultValue) => {
7
+ return process.env[varName] ?? defaultValue ?? '';
8
+ });
9
+ }
10
+ /**
11
+ * Recursively expand environment variables in an object
12
+ */
13
+ export function expandEnvVarsInObject(obj) {
14
+ if (typeof obj === 'string') {
15
+ return expandEnvVars(obj);
16
+ }
17
+ if (Array.isArray(obj)) {
18
+ return obj.map(expandEnvVarsInObject);
19
+ }
20
+ if (obj && typeof obj === 'object') {
21
+ const result = {};
22
+ for (const [key, value] of Object.entries(obj)) {
23
+ result[key] = expandEnvVarsInObject(value);
24
+ }
25
+ return result;
26
+ }
27
+ return obj;
28
+ }
29
+ /**
30
+ * Create a clean environment for MCP processes
31
+ * Merges process.env with custom env vars, expanding variables
32
+ */
33
+ export function createCleanMcpEnvironment(customEnv) {
34
+ const baseEnv = {};
35
+ // Copy essential environment variables
36
+ const essentialVars = [
37
+ 'PATH',
38
+ 'HOME',
39
+ 'USER',
40
+ 'SHELL',
41
+ 'TERM',
42
+ 'NODE_ENV',
43
+ 'npm_config_registry',
44
+ 'npm_config_cache'
45
+ ];
46
+ for (const varName of essentialVars) {
47
+ if (process.env[varName]) {
48
+ baseEnv[varName] = process.env[varName];
49
+ }
50
+ }
51
+ // Merge custom env vars with expansion
52
+ if (customEnv) {
53
+ for (const [key, value] of Object.entries(customEnv)) {
54
+ baseEnv[key] = expandEnvVars(value);
55
+ }
56
+ }
57
+ return baseEnv;
58
+ }
59
+ //# sourceMappingURL=env-vars.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env-vars.js","sourceRoot":"","sources":["../../src/utils/env-vars.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,KAAa;IACzC,OAAO,KAAK,CAAC,OAAO,CAClB,+BAA+B,EAC/B,CAAC,CAAC,EAAE,OAAe,EAAE,YAAqB,EAAE,EAAE;QAC5C,OAAO,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,YAAY,IAAI,EAAE,CAAA;IACnD,CAAC,CACF,CAAA;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,qBAAqB,CAAI,GAAM;IAC7C,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;QAC5B,OAAO,aAAa,CAAC,GAAG,CAAM,CAAA;IAChC,CAAC;IAED,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QACvB,OAAO,GAAG,CAAC,GAAG,CAAC,qBAAqB,CAAM,CAAA;IAC5C,CAAC;IAED,IAAI,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;QACnC,MAAM,MAAM,GAA4B,EAAE,CAAA;QAC1C,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;YAC/C,MAAM,CAAC,GAAG,CAAC,GAAG,qBAAqB,CAAC,KAAK,CAAC,CAAA;QAC5C,CAAC;QACD,OAAO,MAAW,CAAA;IACpB,CAAC;IAED,OAAO,GAAG,CAAA;AACZ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,yBAAyB,CACvC,SAAkC;IAElC,MAAM,OAAO,GAA2B,EAAE,CAAA;IAE1C,uCAAuC;IACvC,MAAM,aAAa,GAAG;QACpB,MAAM;QACN,MAAM;QACN,MAAM;QACN,OAAO;QACP,MAAM;QACN,UAAU;QACV,qBAAqB;QACrB,kBAAkB;KACnB,CAAA;IAED,KAAK,MAAM,OAAO,IAAI,aAAa,EAAE,CAAC;QACpC,IAAI,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;YACzB,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,OAAO,CAAE,CAAA;QAC1C,CAAC;IACH,CAAC;IAED,uCAAuC;IACvC,IAAI,SAAS,EAAE,CAAC;QACd,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC;YACrD,OAAO,CAAC,GAAG,CAAC,GAAG,aAAa,CAAC,KAAK,CAAC,CAAA;QACrC,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAA;AAChB,CAAC"}
@@ -0,0 +1,10 @@
1
+ import type { ParsedFrontmatter, McpServerConfig } from '../types.js';
2
+ /**
3
+ * Parse YAML frontmatter from markdown content
4
+ */
5
+ export declare function parseFrontmatter(content: string): ParsedFrontmatter;
6
+ /**
7
+ * Parse MCP config specifically from frontmatter content
8
+ */
9
+ export declare function parseSkillMcpConfigFromFrontmatter(content: string): Record<string, McpServerConfig> | undefined;
10
+ //# sourceMappingURL=frontmatter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"frontmatter.d.ts","sourceRoot":"","sources":["../../src/utils/frontmatter.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAoB,eAAe,EAAE,MAAM,aAAa,CAAA;AAEvF;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,iBAAiB,CAoBnE;AAED;;GAEG;AACH,wBAAgB,kCAAkC,CAChD,OAAO,EAAE,MAAM,GACd,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,GAAG,SAAS,CAiB7C"}
@@ -0,0 +1,44 @@
1
+ import * as yaml from 'js-yaml';
2
+ /**
3
+ * Parse YAML frontmatter from markdown content
4
+ */
5
+ export function parseFrontmatter(content) {
6
+ const frontmatterMatch = content.match(/^---\r?\n([\s\S]*?)\r?\n---/);
7
+ if (!frontmatterMatch) {
8
+ return {
9
+ data: {},
10
+ body: content
11
+ };
12
+ }
13
+ try {
14
+ const data = yaml.load(frontmatterMatch[1]);
15
+ const body = content.slice(frontmatterMatch[0].length).trim();
16
+ return { data: data || {}, body };
17
+ }
18
+ catch {
19
+ return {
20
+ data: {},
21
+ body: content
22
+ };
23
+ }
24
+ }
25
+ /**
26
+ * Parse MCP config specifically from frontmatter content
27
+ */
28
+ export function parseSkillMcpConfigFromFrontmatter(content) {
29
+ const frontmatterMatch = content.match(/^---\r?\n([\s\S]*?)\r?\n---/);
30
+ if (!frontmatterMatch) {
31
+ return undefined;
32
+ }
33
+ try {
34
+ const parsed = yaml.load(frontmatterMatch[1]);
35
+ if (parsed && typeof parsed === 'object' && 'mcp' in parsed && parsed.mcp) {
36
+ return parsed.mcp;
37
+ }
38
+ }
39
+ catch {
40
+ return undefined;
41
+ }
42
+ return undefined;
43
+ }
44
+ //# sourceMappingURL=frontmatter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"frontmatter.js","sourceRoot":"","sources":["../../src/utils/frontmatter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,SAAS,CAAA;AAG/B;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAAC,OAAe;IAC9C,MAAM,gBAAgB,GAAG,OAAO,CAAC,KAAK,CAAC,6BAA6B,CAAC,CAAA;IAErE,IAAI,CAAC,gBAAgB,EAAE,CAAC;QACtB,OAAO;YACL,IAAI,EAAE,EAAE;YACR,IAAI,EAAE,OAAO;SACd,CAAA;IACH,CAAC;IAED,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAqB,CAAA;QAC/D,MAAM,IAAI,GAAG,OAAO,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAA;QAC7D,OAAO,EAAE,IAAI,EAAE,IAAI,IAAI,EAAE,EAAE,IAAI,EAAE,CAAA;IACnC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO;YACL,IAAI,EAAE,EAAE;YACR,IAAI,EAAE,OAAO;SACd,CAAA;IACH,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,kCAAkC,CAChD,OAAe;IAEf,MAAM,gBAAgB,GAAG,OAAO,CAAC,KAAK,CAAC,6BAA6B,CAAC,CAAA;IAErE,IAAI,CAAC,gBAAgB,EAAE,CAAC;QACtB,OAAO,SAAS,CAAA;IAClB,CAAC;IAED,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAA8C,CAAA;QAC1F,IAAI,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,KAAK,IAAI,MAAM,IAAI,MAAM,CAAC,GAAG,EAAE,CAAC;YAC1E,OAAO,MAAM,CAAC,GAAG,CAAA;QACnB,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAA;IAClB,CAAC;IAED,OAAO,SAAS,CAAA;AAClB,CAAC"}
package/package.json CHANGED
@@ -1,14 +1,15 @@
1
1
  {
2
2
  "name": "opencode-lazy-loader",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "description": "OpenCode plugin for lazy-loading skill-embedded MCP servers",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
7
7
  "types": "dist/index.d.ts",
8
8
  "scripts": {
9
- "build": "tsc",
10
- "watch": "tsc --watch",
11
- "clean": "rm -rf dist"
9
+ "build": "npx tsc",
10
+ "watch": "npx tsc --watch",
11
+ "clean": "rm -rf dist",
12
+ "prepack": "npm run clean && npm run build"
12
13
  },
13
14
  "keywords": [
14
15
  "opencode",