opencode-plugin-preload-skills 1.4.0 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +30 -0
- package/dist/index.cjs +67 -21
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +67 -21
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -23,6 +23,7 @@ A powerful plugin for [OpenCode](https://opencode.ai) that intelligently loads s
|
|
|
23
23
|
| **Conditional Loading** | Load only if dependency exists |
|
|
24
24
|
| **Token Budget** | Cap total skill tokens to protect context |
|
|
25
25
|
| **Summaries Mode** | Load compact summaries instead of full content |
|
|
26
|
+
| **System Prompt Injection** | Inject skills into system prompt instead of messages |
|
|
26
27
|
| **Usage Analytics** | Track which skills are actually used |
|
|
27
28
|
|
|
28
29
|
> **⚠️ Warning:** Preloaded skills consume context window tokens. Use `maxTokens` to set a budget and `useSummaries` for large skills.
|
|
@@ -90,6 +91,7 @@ A powerful plugin for [OpenCode](https://opencode.ai) that intelligently loads s
|
|
|
90
91
|
"large-skill": { "useSummary": true },
|
|
91
92
|
"critical-skill": { "useSummary": false }
|
|
92
93
|
},
|
|
94
|
+
"injectionMethod": "chatMessage",
|
|
93
95
|
"maxTokens": 10000,
|
|
94
96
|
"useSummaries": false,
|
|
95
97
|
"analytics": false,
|
|
@@ -110,6 +112,7 @@ A powerful plugin for [OpenCode](https://opencode.ai) that intelligently loads s
|
|
|
110
112
|
| `groups` | `Record<string, string[]>` | `{}` | Define skill bundles |
|
|
111
113
|
| `conditionalSkills` | `ConditionalSkill[]` | `[]` | Load if condition met |
|
|
112
114
|
| `skillSettings` | `Record<string, SkillSettings>` | `{}` | Per-skill settings |
|
|
115
|
+
| `injectionMethod` | `"chatMessage" \| "systemPrompt"` | `"chatMessage"` | Where to inject skills |
|
|
113
116
|
| `maxTokens` | `number` | `undefined` | Max tokens for all skills |
|
|
114
117
|
| `useSummaries` | `boolean` | `false` | Use skill summaries (global) |
|
|
115
118
|
| `analytics` | `boolean` | `false` | Track skill usage |
|
|
@@ -278,6 +281,33 @@ Override global settings for specific skills:
|
|
|
278
281
|
|
|
279
282
|
This lets you use full content for critical skills while summarizing large reference materials.
|
|
280
283
|
|
|
284
|
+
### Injection Method
|
|
285
|
+
|
|
286
|
+
Choose where skills are injected:
|
|
287
|
+
|
|
288
|
+
```json
|
|
289
|
+
{
|
|
290
|
+
"injectionMethod": "systemPrompt"
|
|
291
|
+
}
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
**Methods:**
|
|
295
|
+
|
|
296
|
+
| Method | Description | Use Case |
|
|
297
|
+
|--------|-------------|----------|
|
|
298
|
+
| `chatMessage` (default) | Injects skills into user messages | One-time injection, visible in conversation |
|
|
299
|
+
| `systemPrompt` | Injects into system prompt via `experimental.chat.system.transform` hook | Persistent across all LLM calls, invisible to user |
|
|
300
|
+
|
|
301
|
+
**System prompt injection benefits:**
|
|
302
|
+
- Skills persist automatically (no need for `persistAfterCompaction`)
|
|
303
|
+
- Cleaner conversation history (skills not visible in messages)
|
|
304
|
+
- Skills included in every LLM call automatically
|
|
305
|
+
|
|
306
|
+
**Chat message injection benefits:**
|
|
307
|
+
- Skills visible in conversation for debugging
|
|
308
|
+
- Works with all OpenCode versions
|
|
309
|
+
- More control over when skills appear
|
|
310
|
+
|
|
281
311
|
### Usage Analytics
|
|
282
312
|
|
|
283
313
|
Track which skills are loaded and how often:
|
package/dist/index.cjs
CHANGED
|
@@ -175,6 +175,7 @@ var DEFAULT_CONFIG = {
|
|
|
175
175
|
groups: {},
|
|
176
176
|
conditionalSkills: [],
|
|
177
177
|
skillSettings: {},
|
|
178
|
+
injectionMethod: "chatMessage",
|
|
178
179
|
maxTokens: void 0,
|
|
179
180
|
useSummaries: false,
|
|
180
181
|
analytics: false,
|
|
@@ -247,7 +248,8 @@ function loadConfigFile(projectDir) {
|
|
|
247
248
|
useSummaries: typeof parsed.useSummaries === "boolean" ? parsed.useSummaries : void 0,
|
|
248
249
|
analytics: typeof parsed.analytics === "boolean" ? parsed.analytics : void 0,
|
|
249
250
|
persistAfterCompaction: typeof parsed.persistAfterCompaction === "boolean" ? parsed.persistAfterCompaction : void 0,
|
|
250
|
-
debug: typeof parsed.debug === "boolean" ? parsed.debug : void 0
|
|
251
|
+
debug: typeof parsed.debug === "boolean" ? parsed.debug : void 0,
|
|
252
|
+
injectionMethod: parsed.injectionMethod === "systemPrompt" || parsed.injectionMethod === "chatMessage" ? parsed.injectionMethod : void 0
|
|
251
253
|
};
|
|
252
254
|
} catch {
|
|
253
255
|
return {};
|
|
@@ -331,6 +333,7 @@ var PreloadSkillsPlugin = async (ctx) => {
|
|
|
331
333
|
lastLoaded: now
|
|
332
334
|
});
|
|
333
335
|
}
|
|
336
|
+
saveAnalytics();
|
|
334
337
|
};
|
|
335
338
|
const saveAnalytics = () => {
|
|
336
339
|
if (!config.analytics) return;
|
|
@@ -449,7 +452,45 @@ var PreloadSkillsPlugin = async (ctx) => {
|
|
|
449
452
|
});
|
|
450
453
|
}
|
|
451
454
|
};
|
|
455
|
+
const useSystemPromptInjection = config.injectionMethod === "systemPrompt";
|
|
452
456
|
return {
|
|
457
|
+
"experimental.chat.system.transform": useSystemPromptInjection ? async (input, output) => {
|
|
458
|
+
if (!input.sessionID) return;
|
|
459
|
+
const state = getSessionState(input.sessionID);
|
|
460
|
+
const skillsToInject = [];
|
|
461
|
+
if (initialSkills.length > 0) {
|
|
462
|
+
skillsToInject.push(...initialSkills);
|
|
463
|
+
}
|
|
464
|
+
for (const name of state.loadedSkills) {
|
|
465
|
+
const skill = skillCache.get(name);
|
|
466
|
+
if (skill && !skillsToInject.find((s) => s.name === name)) {
|
|
467
|
+
skillsToInject.push(skill);
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
const pending = pendingSkillInjections.get(input.sessionID);
|
|
471
|
+
if (pending && pending.length > 0) {
|
|
472
|
+
for (const skill of pending) {
|
|
473
|
+
if (!skillsToInject.find((s) => s.name === skill.name)) {
|
|
474
|
+
skillsToInject.push(skill);
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
pendingSkillInjections.delete(input.sessionID);
|
|
478
|
+
}
|
|
479
|
+
if (skillsToInject.length > 0) {
|
|
480
|
+
const formatted = formatSkillsForInjection(skillsToInject, {
|
|
481
|
+
useSummaries: config.useSummaries,
|
|
482
|
+
skillSettings: config.skillSettings
|
|
483
|
+
});
|
|
484
|
+
output.system.push(formatted);
|
|
485
|
+
if (!state.initialSkillsInjected && initialSkills.length > 0) {
|
|
486
|
+
state.initialSkillsInjected = true;
|
|
487
|
+
log("info", "Injected skills into system prompt", {
|
|
488
|
+
sessionID: input.sessionID,
|
|
489
|
+
skills: skillsToInject.map((s) => s.name)
|
|
490
|
+
});
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
} : void 0,
|
|
453
494
|
"chat.message": async (input, output) => {
|
|
454
495
|
if (!input.sessionID) return;
|
|
455
496
|
const state = getSessionState(input.sessionID);
|
|
@@ -478,33 +519,38 @@ var PreloadSkillsPlugin = async (ctx) => {
|
|
|
478
519
|
}
|
|
479
520
|
}
|
|
480
521
|
}
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
skills: initialSkills.map((s) => s.name)
|
|
488
|
-
});
|
|
489
|
-
}
|
|
490
|
-
const pending = pendingSkillInjections.get(input.sessionID);
|
|
491
|
-
if (pending && pending.length > 0) {
|
|
492
|
-
const formatted = formatSkillsForInjection(pending, { useSummaries: config.useSummaries, skillSettings: config.skillSettings });
|
|
493
|
-
if (formatted) {
|
|
494
|
-
contentToInject.push(formatted);
|
|
495
|
-
log("info", "Injected triggered skills", {
|
|
522
|
+
if (!useSystemPromptInjection) {
|
|
523
|
+
const contentToInject = [];
|
|
524
|
+
if (!state.initialSkillsInjected && initialFormattedContent) {
|
|
525
|
+
contentToInject.push(initialFormattedContent);
|
|
526
|
+
state.initialSkillsInjected = true;
|
|
527
|
+
log("info", "Injected initial preloaded skills", {
|
|
496
528
|
sessionID: input.sessionID,
|
|
497
|
-
skills:
|
|
529
|
+
skills: initialSkills.map((s) => s.name)
|
|
498
530
|
});
|
|
499
531
|
}
|
|
500
|
-
pendingSkillInjections.
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
532
|
+
const pending = pendingSkillInjections.get(input.sessionID);
|
|
533
|
+
if (pending && pending.length > 0) {
|
|
534
|
+
const formatted = formatSkillsForInjection(pending, {
|
|
535
|
+
useSummaries: config.useSummaries,
|
|
536
|
+
skillSettings: config.skillSettings
|
|
537
|
+
});
|
|
538
|
+
if (formatted) {
|
|
539
|
+
contentToInject.push(formatted);
|
|
540
|
+
log("info", "Injected triggered skills", {
|
|
541
|
+
sessionID: input.sessionID,
|
|
542
|
+
skills: pending.map((s) => s.name)
|
|
543
|
+
});
|
|
544
|
+
}
|
|
545
|
+
pendingSkillInjections.delete(input.sessionID);
|
|
546
|
+
}
|
|
547
|
+
if (contentToInject.length > 0) {
|
|
548
|
+
firstTextPart.text = `${contentToInject.join("\n\n")}
|
|
504
549
|
|
|
505
550
|
---
|
|
506
551
|
|
|
507
552
|
${firstTextPart.text}`;
|
|
553
|
+
}
|
|
508
554
|
}
|
|
509
555
|
},
|
|
510
556
|
"tool.execute.after": async (input, _output) => {
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/utils.ts","../src/skill-loader.ts","../src/index.ts"],"names":["join","existsSync","readFileSync","homedir","dirname","mkdirSync","writeFileSync","extname"],"mappings":"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","file":"index.cjs","sourcesContent":["import { existsSync, readFileSync } from \"node:fs\"\nimport { join } from \"node:path\"\n\nexport function estimateTokens(text: string): number {\n return Math.ceil(text.length / 4)\n}\n\nexport function matchGlobPattern(filePath: string, pattern: string): boolean {\n let regexPattern = pattern\n .replace(/\\*\\*\\//g, \"\\x00DOUBLESTARSLASH\\x00\")\n .replace(/\\*\\*/g, \"\\x00DOUBLESTAR\\x00\")\n .replace(/\\*/g, \"\\x00SINGLESTAR\\x00\")\n .replace(/\\?/g, \"\\x00QUESTION\\x00\")\n \n regexPattern = regexPattern.replace(/[.+^${}()|[\\]\\\\]/g, \"\\\\$&\")\n \n regexPattern = regexPattern\n .replace(/\\x00DOUBLESTARSLASH\\x00/g, \"(?:[^/]+/)*\")\n .replace(/\\x00DOUBLESTAR\\x00/g, \".*\")\n .replace(/\\x00SINGLESTAR\\x00/g, \"[^/]*\")\n .replace(/\\x00QUESTION\\x00/g, \"[^/]\")\n\n const regex = new RegExp(`^${regexPattern}$`)\n return regex.test(filePath)\n}\n\nexport function matchesAnyPattern(\n filePath: string,\n patterns: string[]\n): boolean {\n return patterns.some((pattern) => matchGlobPattern(filePath, pattern))\n}\n\nexport function checkCondition(\n condition: { fileExists?: string; packageHasDependency?: string; envVar?: string },\n projectDir: string\n): boolean {\n if (condition.fileExists) {\n const fullPath = join(projectDir, condition.fileExists)\n if (!existsSync(fullPath)) return false\n }\n\n if (condition.packageHasDependency) {\n const packageJsonPath = join(projectDir, \"package.json\")\n if (!existsSync(packageJsonPath)) return false\n\n try {\n const packageJson = JSON.parse(readFileSync(packageJsonPath, \"utf-8\"))\n const deps = {\n ...packageJson.dependencies,\n ...packageJson.devDependencies,\n ...packageJson.peerDependencies,\n }\n if (!deps[condition.packageHasDependency]) return false\n } catch {\n return false\n }\n }\n\n if (condition.envVar) {\n if (!process.env[condition.envVar]) return false\n }\n\n return true\n}\n\nexport function extractKeywords(text: string): string[] {\n const words = text.toLowerCase().match(/\\b[a-z]{3,}\\b/g) ?? []\n return [...new Set(words)]\n}\n\nexport function textContainsKeyword(text: string, keywords: string[]): boolean {\n const lowerText = text.toLowerCase()\n return keywords.some((kw) => lowerText.includes(kw.toLowerCase()))\n}\n","import { existsSync, readFileSync } from \"node:fs\"\nimport { join } from \"node:path\"\nimport { homedir } from \"node:os\"\nimport type { ParsedSkill, SkillSettings } from \"./types.js\"\nimport { estimateTokens } from \"./utils.js\"\n\nconst SKILL_FILENAME = \"SKILL.md\"\n\nconst SKILL_SEARCH_PATHS = [\n (dir: string) => join(dir, \".opencode\", \"skills\"),\n (dir: string) => join(dir, \".claude\", \"skills\"),\n () => join(homedir(), \".config\", \"opencode\", \"skills\"),\n () => join(homedir(), \".claude\", \"skills\"),\n]\n\nfunction findSkillFile(skillName: string, projectDir: string): string | null {\n for (const getPath of SKILL_SEARCH_PATHS) {\n const skillDir = getPath(projectDir)\n const skillPath = join(skillDir, skillName, SKILL_FILENAME)\n\n if (existsSync(skillPath)) {\n return skillPath\n }\n }\n return null\n}\n\ninterface FrontmatterData {\n name?: string\n description?: string\n summary?: string\n}\n\nfunction parseFrontmatter(content: string): FrontmatterData {\n const frontmatterMatch = content.match(/^---\\s*\\n([\\s\\S]*?)\\n---/)\n if (!frontmatterMatch?.[1]) {\n return {}\n }\n\n const frontmatter = frontmatterMatch[1]\n const result: FrontmatterData = {}\n\n const nameMatch = frontmatter.match(/^name:\\s*(.+)$/m)\n if (nameMatch?.[1]) {\n result.name = nameMatch[1].trim()\n }\n\n const descMatch = frontmatter.match(/^description:\\s*(.+)$/m)\n if (descMatch?.[1]) {\n result.description = descMatch[1].trim()\n }\n\n const summaryMatch = frontmatter.match(/^summary:\\s*(.+)$/m)\n if (summaryMatch?.[1]) {\n result.summary = summaryMatch[1].trim()\n }\n\n return result\n}\n\nfunction extractAutoSummary(content: string, maxLength: number = 500): string {\n const withoutFrontmatter = content.replace(/^---\\s*\\n[\\s\\S]*?\\n---\\s*\\n?/, \"\")\n \n const firstSection = withoutFrontmatter.split(/\\n##\\s/)[0] ?? \"\"\n const cleaned = firstSection\n .replace(/^#\\s+.+\\n?/, \"\")\n .replace(/\\n+/g, \" \")\n .trim()\n\n if (cleaned.length <= maxLength) return cleaned\n return cleaned.slice(0, maxLength).replace(/\\s+\\S*$/, \"\") + \"...\"\n}\n\nexport function loadSkill(skillName: string, projectDir: string): ParsedSkill | null {\n const filePath = findSkillFile(skillName, projectDir)\n\n if (!filePath) {\n return null\n }\n\n try {\n const content = readFileSync(filePath, \"utf-8\")\n const { name, description, summary } = parseFrontmatter(content)\n\n return {\n name: name ?? skillName,\n description: description ?? \"\",\n summary: summary ?? extractAutoSummary(content),\n content,\n filePath,\n tokenCount: estimateTokens(content),\n }\n } catch {\n return null\n }\n}\n\nexport function loadSkills(skillNames: string[], projectDir: string): ParsedSkill[] {\n if (!Array.isArray(skillNames)) {\n return []\n }\n\n const skills: ParsedSkill[] = []\n\n for (const name of skillNames) {\n const skill = loadSkill(name, projectDir)\n if (skill) {\n skills.push(skill)\n }\n }\n\n return skills\n}\n\nexport interface FormatOptions {\n useSummaries?: boolean\n skillSettings?: Record<string, SkillSettings>\n}\n\nexport function formatSkillsForInjection(\n skills: ParsedSkill[],\n options: boolean | FormatOptions = false\n): string {\n if (!Array.isArray(skills) || skills.length === 0) {\n return \"\"\n }\n\n const opts: FormatOptions = typeof options === \"boolean\" \n ? { useSummaries: options } \n : options\n \n const globalUseSummaries = opts.useSummaries ?? false\n const skillSettings = opts.skillSettings ?? {}\n\n const parts = skills.map((skill) => {\n const perSkillSetting = skillSettings[skill.name]?.useSummary\n const shouldUseSummary = perSkillSetting ?? globalUseSummaries\n const content = shouldUseSummary && skill.summary ? skill.summary : skill.content\n return `<preloaded-skill name=\"${skill.name}\">\\n${content}\\n</preloaded-skill>`\n })\n\n return `<preloaded-skills>\nThe following skills have been automatically loaded for this session:\n\n${parts.join(\"\\n\\n\")}\n</preloaded-skills>`\n}\n\nexport function calculateTotalTokens(skills: ParsedSkill[]): number {\n return skills.reduce((sum, skill) => sum + skill.tokenCount, 0)\n}\n\nexport function filterSkillsByTokenBudget(\n skills: ParsedSkill[],\n maxTokens: number\n): ParsedSkill[] {\n const result: ParsedSkill[] = []\n let totalTokens = 0\n\n for (const skill of skills) {\n if (totalTokens + skill.tokenCount <= maxTokens) {\n result.push(skill)\n totalTokens += skill.tokenCount\n }\n }\n\n return result\n}\n","import { existsSync, readFileSync, writeFileSync, mkdirSync } from \"node:fs\"\nimport { join, extname, dirname } from \"node:path\"\nimport { homedir } from \"node:os\"\nimport type { Plugin, PluginInput } from \"@opencode-ai/plugin\"\nimport type { Event, UserMessage, Part } from \"@opencode-ai/sdk\"\nimport type {\n PreloadSkillsConfig,\n ParsedSkill,\n SessionState,\n ConditionalSkill,\n SkillSettings,\n SkillUsageStats,\n AnalyticsData,\n} from \"./types.js\"\nimport {\n loadSkills,\n formatSkillsForInjection,\n filterSkillsByTokenBudget,\n calculateTotalTokens,\n} from \"./skill-loader.js\"\nimport {\n checkCondition,\n matchGlobPattern,\n textContainsKeyword,\n} from \"./utils.js\"\n\nexport type { PreloadSkillsConfig, ParsedSkill }\nexport { loadSkills, formatSkillsForInjection }\n\nconst CONFIG_FILENAME = \"preload-skills.json\"\nconst ANALYTICS_FILENAME = \"preload-skills-analytics.json\"\nconst FILE_TOOLS = [\"read\", \"edit\", \"write\", \"glob\", \"grep\"]\n\nconst DEFAULT_CONFIG: PreloadSkillsConfig = {\n skills: [],\n fileTypeSkills: {},\n agentSkills: {},\n pathPatterns: {},\n contentTriggers: {},\n groups: {},\n conditionalSkills: [],\n skillSettings: {},\n maxTokens: undefined,\n useSummaries: false,\n analytics: false,\n persistAfterCompaction: true,\n debug: false,\n}\n\nfunction findConfigFile(projectDir: string): string | null {\n const locations = [\n join(projectDir, \".opencode\", CONFIG_FILENAME),\n join(projectDir, CONFIG_FILENAME),\n join(homedir(), \".config\", \"opencode\", CONFIG_FILENAME),\n ]\n\n for (const path of locations) {\n if (existsSync(path)) {\n return path\n }\n }\n return null\n}\n\nfunction parseStringArrayRecord(raw: unknown): Record<string, string[]> {\n if (!raw || typeof raw !== \"object\") return {}\n\n const result: Record<string, string[]> = {}\n for (const [key, value] of Object.entries(raw)) {\n if (Array.isArray(value)) {\n result[key] = value.filter((v) => typeof v === \"string\")\n }\n }\n return result\n}\n\nfunction parseConditionalSkills(raw: unknown): ConditionalSkill[] {\n if (!Array.isArray(raw)) return []\n\n return raw.filter(\n (item): item is ConditionalSkill =>\n typeof item === \"object\" &&\n item !== null &&\n typeof item.skill === \"string\" &&\n typeof item.if === \"object\"\n )\n}\n\nfunction parseSkillSettings(raw: unknown): Record<string, SkillSettings> {\n if (!raw || typeof raw !== \"object\") return {}\n\n const result: Record<string, SkillSettings> = {}\n for (const [skillName, settings] of Object.entries(raw)) {\n if (typeof settings === \"object\" && settings !== null) {\n const parsed: SkillSettings = {}\n if (\"useSummary\" in settings && typeof settings.useSummary === \"boolean\") {\n parsed.useSummary = settings.useSummary\n }\n if (Object.keys(parsed).length > 0) {\n result[skillName] = parsed\n }\n }\n }\n return result\n}\n\nfunction loadConfigFile(projectDir: string): Partial<PreloadSkillsConfig> {\n const configPath = findConfigFile(projectDir)\n if (!configPath) {\n return {}\n }\n\n try {\n const content = readFileSync(configPath, \"utf-8\")\n const parsed = JSON.parse(content) as Record<string, unknown>\n\n return {\n skills: Array.isArray(parsed.skills) ? parsed.skills : [],\n fileTypeSkills: parseStringArrayRecord(parsed.fileTypeSkills),\n agentSkills: parseStringArrayRecord(parsed.agentSkills),\n pathPatterns: parseStringArrayRecord(parsed.pathPatterns),\n contentTriggers: parseStringArrayRecord(parsed.contentTriggers),\n groups: parseStringArrayRecord(parsed.groups),\n conditionalSkills: parseConditionalSkills(parsed.conditionalSkills),\n skillSettings: parseSkillSettings(parsed.skillSettings),\n maxTokens:\n typeof parsed.maxTokens === \"number\" ? parsed.maxTokens : undefined,\n useSummaries:\n typeof parsed.useSummaries === \"boolean\"\n ? parsed.useSummaries\n : undefined,\n analytics:\n typeof parsed.analytics === \"boolean\" ? parsed.analytics : undefined,\n persistAfterCompaction:\n typeof parsed.persistAfterCompaction === \"boolean\"\n ? parsed.persistAfterCompaction\n : undefined,\n debug: typeof parsed.debug === \"boolean\" ? parsed.debug : undefined,\n }\n } catch {\n return {}\n }\n}\n\nfunction getFilePathFromArgs(args: Record<string, unknown>): string | null {\n if (typeof args.filePath === \"string\") return args.filePath\n if (typeof args.path === \"string\") return args.path\n if (typeof args.file === \"string\") return args.file\n return null\n}\n\nfunction getSkillsForExtension(\n ext: string,\n fileTypeSkills: Record<string, string[]>\n): string[] {\n const skills: string[] = []\n\n for (const [pattern, skillNames] of Object.entries(fileTypeSkills)) {\n const extensions = pattern.split(\",\").map((e) => e.trim().toLowerCase())\n if (extensions.includes(ext.toLowerCase())) {\n skills.push(...skillNames)\n }\n }\n\n return [...new Set(skills)]\n}\n\nfunction getSkillsForPath(\n filePath: string,\n pathPatterns: Record<string, string[]>\n): string[] {\n const skills: string[] = []\n\n for (const [pattern, skillNames] of Object.entries(pathPatterns)) {\n if (matchGlobPattern(filePath, pattern)) {\n skills.push(...skillNames)\n }\n }\n\n return [...new Set(skills)]\n}\n\nfunction resolveSkillGroups(\n skillNames: string[],\n groups: Record<string, string[]>\n): string[] {\n const resolved: string[] = []\n\n for (const name of skillNames) {\n if (name.startsWith(\"@\") && groups[name.slice(1)]) {\n resolved.push(...groups[name.slice(1)]!)\n } else {\n resolved.push(name)\n }\n }\n\n return [...new Set(resolved)]\n}\n\nexport const PreloadSkillsPlugin: Plugin = async (ctx: PluginInput) => {\n const sessionStates = new Map<string, SessionState>()\n const analyticsData = new Map<string, AnalyticsData>()\n\n const fileConfig = loadConfigFile(ctx.directory)\n const config: PreloadSkillsConfig = {\n ...DEFAULT_CONFIG,\n ...fileConfig,\n }\n\n const log = (\n level: \"debug\" | \"info\" | \"warn\" | \"error\",\n message: string,\n extra?: Record<string, unknown>\n ) => {\n if (level === \"debug\" && !config.debug) return\n\n ctx.client.app.log({\n body: {\n service: \"preload-skills\",\n level,\n message,\n extra,\n },\n })\n }\n\n const trackSkillUsage = (\n sessionID: string,\n skillName: string,\n triggerType: SkillUsageStats[\"triggerType\"]\n ) => {\n if (!config.analytics) return\n\n if (!analyticsData.has(sessionID)) {\n analyticsData.set(sessionID, {\n sessionId: sessionID,\n skillUsage: new Map(),\n })\n }\n\n const data = analyticsData.get(sessionID)!\n const now = Date.now()\n\n if (data.skillUsage.has(skillName)) {\n const stats = data.skillUsage.get(skillName)!\n stats.loadCount++\n stats.lastLoaded = now\n } else {\n data.skillUsage.set(skillName, {\n skillName,\n loadCount: 1,\n triggerType,\n firstLoaded: now,\n lastLoaded: now,\n })\n }\n }\n\n const saveAnalytics = () => {\n if (!config.analytics) return\n\n try {\n const analyticsPath = join(ctx.directory, \".opencode\", ANALYTICS_FILENAME)\n const dir = dirname(analyticsPath)\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true })\n }\n\n const serializable: Record<string, unknown> = {}\n for (const [sessionId, data] of analyticsData) {\n serializable[sessionId] = {\n sessionId: data.sessionId,\n skillUsage: Object.fromEntries(data.skillUsage),\n }\n }\n\n writeFileSync(analyticsPath, JSON.stringify(serializable, null, 2))\n } catch {\n log(\"warn\", \"Failed to save analytics\")\n }\n }\n\n const skillCache = new Map<string, ParsedSkill>()\n\n const loadSkillsWithBudget = (\n skillNames: string[],\n currentTokens: number,\n triggerType: SkillUsageStats[\"triggerType\"],\n sessionID: string\n ): { skills: ParsedSkill[]; tokensUsed: number } => {\n const resolved = resolveSkillGroups(skillNames, config.groups ?? {})\n let skills = loadSkills(resolved, ctx.directory)\n\n for (const skill of skills) {\n skillCache.set(skill.name, skill)\n }\n\n if (config.maxTokens) {\n const remainingBudget = config.maxTokens - currentTokens\n skills = filterSkillsByTokenBudget(skills, remainingBudget)\n }\n\n for (const skill of skills) {\n trackSkillUsage(sessionID, skill.name, triggerType)\n }\n\n return {\n skills,\n tokensUsed: calculateTotalTokens(skills),\n }\n }\n\n const resolveConditionalSkills = (): string[] => {\n if (!config.conditionalSkills?.length) return []\n\n const resolved: string[] = []\n for (const { skill, if: condition } of config.conditionalSkills) {\n if (checkCondition(condition, ctx.directory)) {\n resolved.push(skill)\n }\n }\n\n return resolved\n }\n\n let initialSkills: ParsedSkill[] = []\n let initialFormattedContent = \"\"\n let initialTokensUsed = 0\n\n const allInitialSkillNames = [\n ...config.skills,\n ...resolveConditionalSkills(),\n ]\n\n if (allInitialSkillNames.length > 0) {\n const result = loadSkillsWithBudget(\n allInitialSkillNames,\n 0,\n \"initial\",\n \"__init__\"\n )\n initialSkills = result.skills\n initialTokensUsed = result.tokensUsed\n initialFormattedContent = formatSkillsForInjection(\n initialSkills,\n { useSummaries: config.useSummaries, skillSettings: config.skillSettings }\n )\n\n const loadedNames = initialSkills.map((s) => s.name)\n const missingNames = allInitialSkillNames.filter(\n (s) => !loadedNames.includes(s) && !s.startsWith(\"@\")\n )\n\n log(\"info\", `Loaded ${initialSkills.length} initial skills`, {\n loaded: loadedNames,\n tokens: initialTokensUsed,\n missing: missingNames.length > 0 ? missingNames : undefined,\n })\n }\n\n const hasTriggeredSkills =\n Object.keys(config.fileTypeSkills ?? {}).length > 0 ||\n Object.keys(config.agentSkills ?? {}).length > 0 ||\n Object.keys(config.pathPatterns ?? {}).length > 0 ||\n Object.keys(config.contentTriggers ?? {}).length > 0\n\n if (allInitialSkillNames.length === 0 && !hasTriggeredSkills) {\n log(\"warn\", \"No skills configured. Create .opencode/preload-skills.json\")\n }\n\n const getSessionState = (sessionID: string): SessionState => {\n if (!sessionStates.has(sessionID)) {\n sessionStates.set(sessionID, {\n initialSkillsInjected: false,\n loadedSkills: new Set(initialSkills.map((s) => s.name)),\n totalTokensUsed: initialTokensUsed,\n })\n }\n return sessionStates.get(sessionID)!\n }\n\n const pendingSkillInjections = new Map<string, ParsedSkill[]>()\n\n const queueSkillsForInjection = (\n sessionID: string,\n skillNames: string[],\n triggerType: SkillUsageStats[\"triggerType\"],\n state: SessionState\n ) => {\n const newSkillNames = skillNames.filter((name) => !state.loadedSkills.has(name))\n if (newSkillNames.length === 0) return\n\n const result = loadSkillsWithBudget(\n newSkillNames,\n state.totalTokensUsed,\n triggerType,\n sessionID\n )\n\n if (result.skills.length > 0) {\n for (const skill of result.skills) {\n state.loadedSkills.add(skill.name)\n }\n state.totalTokensUsed += result.tokensUsed\n\n const existing = pendingSkillInjections.get(sessionID) ?? []\n pendingSkillInjections.set(sessionID, [...existing, ...result.skills])\n\n log(\"debug\", `Queued ${triggerType} skills for injection`, {\n sessionID,\n skills: result.skills.map((s) => s.name),\n tokens: result.tokensUsed,\n })\n }\n }\n\n return {\n \"chat.message\": async (\n input: {\n sessionID: string\n agent?: string\n model?: { providerID: string; modelID: string }\n messageID?: string\n variant?: string\n },\n output: { message: UserMessage; parts: Part[] }\n ): Promise<void> => {\n if (!input.sessionID) return\n\n const state = getSessionState(input.sessionID)\n const firstTextPart = output.parts.find((p) => p.type === \"text\")\n if (!firstTextPart || !(\"text\" in firstTextPart)) return\n\n const messageText = firstTextPart.text\n\n if (input.agent && config.agentSkills?.[input.agent]) {\n queueSkillsForInjection(\n input.sessionID,\n config.agentSkills[input.agent]!,\n \"agent\",\n state\n )\n }\n\n if (config.contentTriggers) {\n for (const [keyword, skillNames] of Object.entries(\n config.contentTriggers\n )) {\n if (textContainsKeyword(messageText, [keyword])) {\n queueSkillsForInjection(\n input.sessionID,\n skillNames,\n \"content\",\n state\n )\n }\n }\n }\n\n const contentToInject: string[] = []\n\n if (!state.initialSkillsInjected && initialFormattedContent) {\n contentToInject.push(initialFormattedContent)\n state.initialSkillsInjected = true\n log(\"info\", \"Injected initial preloaded skills\", {\n sessionID: input.sessionID,\n skills: initialSkills.map((s) => s.name),\n })\n }\n\n const pending = pendingSkillInjections.get(input.sessionID)\n if (pending && pending.length > 0) {\n const formatted = formatSkillsForInjection(pending, { useSummaries: config.useSummaries, skillSettings: config.skillSettings })\n if (formatted) {\n contentToInject.push(formatted)\n log(\"info\", \"Injected triggered skills\", {\n sessionID: input.sessionID,\n skills: pending.map((s) => s.name),\n })\n }\n pendingSkillInjections.delete(input.sessionID)\n }\n\n if (contentToInject.length > 0) {\n firstTextPart.text = `${contentToInject.join(\"\\n\\n\")}\\n\\n---\\n\\n${firstTextPart.text}`\n }\n },\n\n \"tool.execute.after\": async (\n input: {\n tool: string\n sessionID: string\n callID: string\n },\n _output: {\n title: string\n output: string\n metadata: unknown\n }\n ): Promise<void> => {\n if (!FILE_TOOLS.includes(input.tool)) return\n if (!input.sessionID) return\n\n const state = getSessionState(input.sessionID)\n\n const toolArgs = (_output.metadata as { args?: Record<string, unknown> })\n ?.args\n if (!toolArgs) return\n\n const filePath = getFilePathFromArgs(toolArgs)\n if (!filePath) return\n\n const ext = extname(filePath)\n if (ext && config.fileTypeSkills) {\n const extSkills = getSkillsForExtension(ext, config.fileTypeSkills)\n if (extSkills.length > 0) {\n queueSkillsForInjection(input.sessionID, extSkills, \"fileType\", state)\n }\n }\n\n if (config.pathPatterns) {\n const pathSkills = getSkillsForPath(filePath, config.pathPatterns)\n if (pathSkills.length > 0) {\n queueSkillsForInjection(input.sessionID, pathSkills, \"path\", state)\n }\n }\n },\n\n \"experimental.session.compacting\": async (\n input: { sessionID: string },\n output: { context: string[]; prompt?: string }\n ): Promise<void> => {\n if (!config.persistAfterCompaction) return\n\n const state = sessionStates.get(input.sessionID)\n if (!state || state.loadedSkills.size === 0) return\n\n const allLoadedSkills: ParsedSkill[] = []\n for (const name of state.loadedSkills) {\n const skill = skillCache.get(name)\n if (skill) allLoadedSkills.push(skill)\n }\n\n if (allLoadedSkills.length === 0) return\n\n const formatted = formatSkillsForInjection(\n allLoadedSkills,\n { useSummaries: config.useSummaries, skillSettings: config.skillSettings }\n )\n output.context.push(\n `## Preloaded Skills\\n\\nThe following skills were loaded during this session and should persist:\\n\\n${formatted}`\n )\n\n state.initialSkillsInjected = false\n\n log(\"info\", \"Added all loaded skills to compaction context\", {\n sessionID: input.sessionID,\n skillCount: allLoadedSkills.length,\n })\n\n saveAnalytics()\n },\n\n event: async ({ event }: { event: Event }): Promise<void> => {\n if (\n event.type === \"session.deleted\" &&\n \"sessionID\" in event.properties\n ) {\n const sessionID = event.properties.sessionID as string\n sessionStates.delete(sessionID)\n pendingSkillInjections.delete(sessionID)\n analyticsData.delete(sessionID)\n log(\"debug\", \"Cleaned up session state\", { sessionID })\n saveAnalytics()\n }\n },\n }\n}\n\nexport default PreloadSkillsPlugin\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/utils.ts","../src/skill-loader.ts","../src/index.ts"],"names":["join","existsSync","readFileSync","homedir","dirname","mkdirSync","writeFileSync","extname"],"mappings":"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","file":"index.cjs","sourcesContent":["import { existsSync, readFileSync } from \"node:fs\"\nimport { join } from \"node:path\"\n\nexport function estimateTokens(text: string): number {\n return Math.ceil(text.length / 4)\n}\n\nexport function matchGlobPattern(filePath: string, pattern: string): boolean {\n let regexPattern = pattern\n .replace(/\\*\\*\\//g, \"\\x00DOUBLESTARSLASH\\x00\")\n .replace(/\\*\\*/g, \"\\x00DOUBLESTAR\\x00\")\n .replace(/\\*/g, \"\\x00SINGLESTAR\\x00\")\n .replace(/\\?/g, \"\\x00QUESTION\\x00\")\n \n regexPattern = regexPattern.replace(/[.+^${}()|[\\]\\\\]/g, \"\\\\$&\")\n \n regexPattern = regexPattern\n .replace(/\\x00DOUBLESTARSLASH\\x00/g, \"(?:[^/]+/)*\")\n .replace(/\\x00DOUBLESTAR\\x00/g, \".*\")\n .replace(/\\x00SINGLESTAR\\x00/g, \"[^/]*\")\n .replace(/\\x00QUESTION\\x00/g, \"[^/]\")\n\n const regex = new RegExp(`^${regexPattern}$`)\n return regex.test(filePath)\n}\n\nexport function matchesAnyPattern(\n filePath: string,\n patterns: string[]\n): boolean {\n return patterns.some((pattern) => matchGlobPattern(filePath, pattern))\n}\n\nexport function checkCondition(\n condition: { fileExists?: string; packageHasDependency?: string; envVar?: string },\n projectDir: string\n): boolean {\n if (condition.fileExists) {\n const fullPath = join(projectDir, condition.fileExists)\n if (!existsSync(fullPath)) return false\n }\n\n if (condition.packageHasDependency) {\n const packageJsonPath = join(projectDir, \"package.json\")\n if (!existsSync(packageJsonPath)) return false\n\n try {\n const packageJson = JSON.parse(readFileSync(packageJsonPath, \"utf-8\"))\n const deps = {\n ...packageJson.dependencies,\n ...packageJson.devDependencies,\n ...packageJson.peerDependencies,\n }\n if (!deps[condition.packageHasDependency]) return false\n } catch {\n return false\n }\n }\n\n if (condition.envVar) {\n if (!process.env[condition.envVar]) return false\n }\n\n return true\n}\n\nexport function extractKeywords(text: string): string[] {\n const words = text.toLowerCase().match(/\\b[a-z]{3,}\\b/g) ?? []\n return [...new Set(words)]\n}\n\nexport function textContainsKeyword(text: string, keywords: string[]): boolean {\n const lowerText = text.toLowerCase()\n return keywords.some((kw) => lowerText.includes(kw.toLowerCase()))\n}\n","import { existsSync, readFileSync } from \"node:fs\"\nimport { join } from \"node:path\"\nimport { homedir } from \"node:os\"\nimport type { ParsedSkill, SkillSettings } from \"./types.js\"\nimport { estimateTokens } from \"./utils.js\"\n\nconst SKILL_FILENAME = \"SKILL.md\"\n\nconst SKILL_SEARCH_PATHS = [\n (dir: string) => join(dir, \".opencode\", \"skills\"),\n (dir: string) => join(dir, \".claude\", \"skills\"),\n () => join(homedir(), \".config\", \"opencode\", \"skills\"),\n () => join(homedir(), \".claude\", \"skills\"),\n]\n\nfunction findSkillFile(skillName: string, projectDir: string): string | null {\n for (const getPath of SKILL_SEARCH_PATHS) {\n const skillDir = getPath(projectDir)\n const skillPath = join(skillDir, skillName, SKILL_FILENAME)\n\n if (existsSync(skillPath)) {\n return skillPath\n }\n }\n return null\n}\n\ninterface FrontmatterData {\n name?: string\n description?: string\n summary?: string\n}\n\nfunction parseFrontmatter(content: string): FrontmatterData {\n const frontmatterMatch = content.match(/^---\\s*\\n([\\s\\S]*?)\\n---/)\n if (!frontmatterMatch?.[1]) {\n return {}\n }\n\n const frontmatter = frontmatterMatch[1]\n const result: FrontmatterData = {}\n\n const nameMatch = frontmatter.match(/^name:\\s*(.+)$/m)\n if (nameMatch?.[1]) {\n result.name = nameMatch[1].trim()\n }\n\n const descMatch = frontmatter.match(/^description:\\s*(.+)$/m)\n if (descMatch?.[1]) {\n result.description = descMatch[1].trim()\n }\n\n const summaryMatch = frontmatter.match(/^summary:\\s*(.+)$/m)\n if (summaryMatch?.[1]) {\n result.summary = summaryMatch[1].trim()\n }\n\n return result\n}\n\nfunction extractAutoSummary(content: string, maxLength: number = 500): string {\n const withoutFrontmatter = content.replace(/^---\\s*\\n[\\s\\S]*?\\n---\\s*\\n?/, \"\")\n \n const firstSection = withoutFrontmatter.split(/\\n##\\s/)[0] ?? \"\"\n const cleaned = firstSection\n .replace(/^#\\s+.+\\n?/, \"\")\n .replace(/\\n+/g, \" \")\n .trim()\n\n if (cleaned.length <= maxLength) return cleaned\n return cleaned.slice(0, maxLength).replace(/\\s+\\S*$/, \"\") + \"...\"\n}\n\nexport function loadSkill(skillName: string, projectDir: string): ParsedSkill | null {\n const filePath = findSkillFile(skillName, projectDir)\n\n if (!filePath) {\n return null\n }\n\n try {\n const content = readFileSync(filePath, \"utf-8\")\n const { name, description, summary } = parseFrontmatter(content)\n\n return {\n name: name ?? skillName,\n description: description ?? \"\",\n summary: summary ?? extractAutoSummary(content),\n content,\n filePath,\n tokenCount: estimateTokens(content),\n }\n } catch {\n return null\n }\n}\n\nexport function loadSkills(skillNames: string[], projectDir: string): ParsedSkill[] {\n if (!Array.isArray(skillNames)) {\n return []\n }\n\n const skills: ParsedSkill[] = []\n\n for (const name of skillNames) {\n const skill = loadSkill(name, projectDir)\n if (skill) {\n skills.push(skill)\n }\n }\n\n return skills\n}\n\nexport interface FormatOptions {\n useSummaries?: boolean\n skillSettings?: Record<string, SkillSettings>\n}\n\nexport function formatSkillsForInjection(\n skills: ParsedSkill[],\n options: boolean | FormatOptions = false\n): string {\n if (!Array.isArray(skills) || skills.length === 0) {\n return \"\"\n }\n\n const opts: FormatOptions = typeof options === \"boolean\" \n ? { useSummaries: options } \n : options\n \n const globalUseSummaries = opts.useSummaries ?? false\n const skillSettings = opts.skillSettings ?? {}\n\n const parts = skills.map((skill) => {\n const perSkillSetting = skillSettings[skill.name]?.useSummary\n const shouldUseSummary = perSkillSetting ?? globalUseSummaries\n const content = shouldUseSummary && skill.summary ? skill.summary : skill.content\n return `<preloaded-skill name=\"${skill.name}\">\\n${content}\\n</preloaded-skill>`\n })\n\n return `<preloaded-skills>\nThe following skills have been automatically loaded for this session:\n\n${parts.join(\"\\n\\n\")}\n</preloaded-skills>`\n}\n\nexport function calculateTotalTokens(skills: ParsedSkill[]): number {\n return skills.reduce((sum, skill) => sum + skill.tokenCount, 0)\n}\n\nexport function filterSkillsByTokenBudget(\n skills: ParsedSkill[],\n maxTokens: number\n): ParsedSkill[] {\n const result: ParsedSkill[] = []\n let totalTokens = 0\n\n for (const skill of skills) {\n if (totalTokens + skill.tokenCount <= maxTokens) {\n result.push(skill)\n totalTokens += skill.tokenCount\n }\n }\n\n return result\n}\n","import { existsSync, readFileSync, writeFileSync, mkdirSync } from \"node:fs\"\nimport { join, extname, dirname } from \"node:path\"\nimport { homedir } from \"node:os\"\nimport type { Plugin, PluginInput } from \"@opencode-ai/plugin\"\nimport type { Event, UserMessage, Part, Model } from \"@opencode-ai/sdk\"\nimport type {\n PreloadSkillsConfig,\n ParsedSkill,\n SessionState,\n ConditionalSkill,\n SkillSettings,\n SkillUsageStats,\n AnalyticsData,\n InjectionMethod,\n} from \"./types.js\"\nimport {\n loadSkills,\n formatSkillsForInjection,\n filterSkillsByTokenBudget,\n calculateTotalTokens,\n} from \"./skill-loader.js\"\nimport {\n checkCondition,\n matchGlobPattern,\n textContainsKeyword,\n} from \"./utils.js\"\n\nexport type { PreloadSkillsConfig, ParsedSkill }\nexport { loadSkills, formatSkillsForInjection }\n\nconst CONFIG_FILENAME = \"preload-skills.json\"\nconst ANALYTICS_FILENAME = \"preload-skills-analytics.json\"\nconst FILE_TOOLS = [\"read\", \"edit\", \"write\", \"glob\", \"grep\"]\n\nconst DEFAULT_CONFIG: PreloadSkillsConfig = {\n skills: [],\n fileTypeSkills: {},\n agentSkills: {},\n pathPatterns: {},\n contentTriggers: {},\n groups: {},\n conditionalSkills: [],\n skillSettings: {},\n injectionMethod: \"chatMessage\",\n maxTokens: undefined,\n useSummaries: false,\n analytics: false,\n persistAfterCompaction: true,\n debug: false,\n}\n\nfunction findConfigFile(projectDir: string): string | null {\n const locations = [\n join(projectDir, \".opencode\", CONFIG_FILENAME),\n join(projectDir, CONFIG_FILENAME),\n join(homedir(), \".config\", \"opencode\", CONFIG_FILENAME),\n ]\n\n for (const path of locations) {\n if (existsSync(path)) {\n return path\n }\n }\n return null\n}\n\nfunction parseStringArrayRecord(raw: unknown): Record<string, string[]> {\n if (!raw || typeof raw !== \"object\") return {}\n\n const result: Record<string, string[]> = {}\n for (const [key, value] of Object.entries(raw)) {\n if (Array.isArray(value)) {\n result[key] = value.filter((v) => typeof v === \"string\")\n }\n }\n return result\n}\n\nfunction parseConditionalSkills(raw: unknown): ConditionalSkill[] {\n if (!Array.isArray(raw)) return []\n\n return raw.filter(\n (item): item is ConditionalSkill =>\n typeof item === \"object\" &&\n item !== null &&\n typeof item.skill === \"string\" &&\n typeof item.if === \"object\"\n )\n}\n\nfunction parseSkillSettings(raw: unknown): Record<string, SkillSettings> {\n if (!raw || typeof raw !== \"object\") return {}\n\n const result: Record<string, SkillSettings> = {}\n for (const [skillName, settings] of Object.entries(raw)) {\n if (typeof settings === \"object\" && settings !== null) {\n const parsed: SkillSettings = {}\n if (\"useSummary\" in settings && typeof settings.useSummary === \"boolean\") {\n parsed.useSummary = settings.useSummary\n }\n if (Object.keys(parsed).length > 0) {\n result[skillName] = parsed\n }\n }\n }\n return result\n}\n\nfunction loadConfigFile(projectDir: string): Partial<PreloadSkillsConfig> {\n const configPath = findConfigFile(projectDir)\n if (!configPath) {\n return {}\n }\n\n try {\n const content = readFileSync(configPath, \"utf-8\")\n const parsed = JSON.parse(content) as Record<string, unknown>\n\n return {\n skills: Array.isArray(parsed.skills) ? parsed.skills : [],\n fileTypeSkills: parseStringArrayRecord(parsed.fileTypeSkills),\n agentSkills: parseStringArrayRecord(parsed.agentSkills),\n pathPatterns: parseStringArrayRecord(parsed.pathPatterns),\n contentTriggers: parseStringArrayRecord(parsed.contentTriggers),\n groups: parseStringArrayRecord(parsed.groups),\n conditionalSkills: parseConditionalSkills(parsed.conditionalSkills),\n skillSettings: parseSkillSettings(parsed.skillSettings),\n maxTokens:\n typeof parsed.maxTokens === \"number\" ? parsed.maxTokens : undefined,\n useSummaries:\n typeof parsed.useSummaries === \"boolean\"\n ? parsed.useSummaries\n : undefined,\n analytics:\n typeof parsed.analytics === \"boolean\" ? parsed.analytics : undefined,\n persistAfterCompaction:\n typeof parsed.persistAfterCompaction === \"boolean\"\n ? parsed.persistAfterCompaction\n : undefined,\n debug: typeof parsed.debug === \"boolean\" ? parsed.debug : undefined,\n injectionMethod:\n parsed.injectionMethod === \"systemPrompt\" ||\n parsed.injectionMethod === \"chatMessage\"\n ? (parsed.injectionMethod as InjectionMethod)\n : undefined,\n }\n } catch {\n return {}\n }\n}\n\nfunction getFilePathFromArgs(args: Record<string, unknown>): string | null {\n if (typeof args.filePath === \"string\") return args.filePath\n if (typeof args.path === \"string\") return args.path\n if (typeof args.file === \"string\") return args.file\n return null\n}\n\nfunction getSkillsForExtension(\n ext: string,\n fileTypeSkills: Record<string, string[]>\n): string[] {\n const skills: string[] = []\n\n for (const [pattern, skillNames] of Object.entries(fileTypeSkills)) {\n const extensions = pattern.split(\",\").map((e) => e.trim().toLowerCase())\n if (extensions.includes(ext.toLowerCase())) {\n skills.push(...skillNames)\n }\n }\n\n return [...new Set(skills)]\n}\n\nfunction getSkillsForPath(\n filePath: string,\n pathPatterns: Record<string, string[]>\n): string[] {\n const skills: string[] = []\n\n for (const [pattern, skillNames] of Object.entries(pathPatterns)) {\n if (matchGlobPattern(filePath, pattern)) {\n skills.push(...skillNames)\n }\n }\n\n return [...new Set(skills)]\n}\n\nfunction resolveSkillGroups(\n skillNames: string[],\n groups: Record<string, string[]>\n): string[] {\n const resolved: string[] = []\n\n for (const name of skillNames) {\n if (name.startsWith(\"@\") && groups[name.slice(1)]) {\n resolved.push(...groups[name.slice(1)]!)\n } else {\n resolved.push(name)\n }\n }\n\n return [...new Set(resolved)]\n}\n\nexport const PreloadSkillsPlugin: Plugin = async (ctx: PluginInput) => {\n const sessionStates = new Map<string, SessionState>()\n const analyticsData = new Map<string, AnalyticsData>()\n\n const fileConfig = loadConfigFile(ctx.directory)\n const config: PreloadSkillsConfig = {\n ...DEFAULT_CONFIG,\n ...fileConfig,\n }\n\n const log = (\n level: \"debug\" | \"info\" | \"warn\" | \"error\",\n message: string,\n extra?: Record<string, unknown>\n ) => {\n if (level === \"debug\" && !config.debug) return\n\n ctx.client.app.log({\n body: {\n service: \"preload-skills\",\n level,\n message,\n extra,\n },\n })\n }\n\n const trackSkillUsage = (\n sessionID: string,\n skillName: string,\n triggerType: SkillUsageStats[\"triggerType\"]\n ) => {\n if (!config.analytics) return\n\n if (!analyticsData.has(sessionID)) {\n analyticsData.set(sessionID, {\n sessionId: sessionID,\n skillUsage: new Map(),\n })\n }\n\n const data = analyticsData.get(sessionID)!\n const now = Date.now()\n\n if (data.skillUsage.has(skillName)) {\n const stats = data.skillUsage.get(skillName)!\n stats.loadCount++\n stats.lastLoaded = now\n } else {\n data.skillUsage.set(skillName, {\n skillName,\n loadCount: 1,\n triggerType,\n firstLoaded: now,\n lastLoaded: now,\n })\n }\n\n saveAnalytics()\n }\n\n const saveAnalytics = () => {\n if (!config.analytics) return\n\n try {\n const analyticsPath = join(ctx.directory, \".opencode\", ANALYTICS_FILENAME)\n const dir = dirname(analyticsPath)\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true })\n }\n\n const serializable: Record<string, unknown> = {}\n for (const [sessionId, data] of analyticsData) {\n serializable[sessionId] = {\n sessionId: data.sessionId,\n skillUsage: Object.fromEntries(data.skillUsage),\n }\n }\n\n writeFileSync(analyticsPath, JSON.stringify(serializable, null, 2))\n } catch {\n log(\"warn\", \"Failed to save analytics\")\n }\n }\n\n const skillCache = new Map<string, ParsedSkill>()\n\n const loadSkillsWithBudget = (\n skillNames: string[],\n currentTokens: number,\n triggerType: SkillUsageStats[\"triggerType\"],\n sessionID: string\n ): { skills: ParsedSkill[]; tokensUsed: number } => {\n const resolved = resolveSkillGroups(skillNames, config.groups ?? {})\n let skills = loadSkills(resolved, ctx.directory)\n\n for (const skill of skills) {\n skillCache.set(skill.name, skill)\n }\n\n if (config.maxTokens) {\n const remainingBudget = config.maxTokens - currentTokens\n skills = filterSkillsByTokenBudget(skills, remainingBudget)\n }\n\n for (const skill of skills) {\n trackSkillUsage(sessionID, skill.name, triggerType)\n }\n\n return {\n skills,\n tokensUsed: calculateTotalTokens(skills),\n }\n }\n\n const resolveConditionalSkills = (): string[] => {\n if (!config.conditionalSkills?.length) return []\n\n const resolved: string[] = []\n for (const { skill, if: condition } of config.conditionalSkills) {\n if (checkCondition(condition, ctx.directory)) {\n resolved.push(skill)\n }\n }\n\n return resolved\n }\n\n let initialSkills: ParsedSkill[] = []\n let initialFormattedContent = \"\"\n let initialTokensUsed = 0\n\n const allInitialSkillNames = [\n ...config.skills,\n ...resolveConditionalSkills(),\n ]\n\n if (allInitialSkillNames.length > 0) {\n const result = loadSkillsWithBudget(\n allInitialSkillNames,\n 0,\n \"initial\",\n \"__init__\"\n )\n initialSkills = result.skills\n initialTokensUsed = result.tokensUsed\n initialFormattedContent = formatSkillsForInjection(\n initialSkills,\n { useSummaries: config.useSummaries, skillSettings: config.skillSettings }\n )\n\n const loadedNames = initialSkills.map((s) => s.name)\n const missingNames = allInitialSkillNames.filter(\n (s) => !loadedNames.includes(s) && !s.startsWith(\"@\")\n )\n\n log(\"info\", `Loaded ${initialSkills.length} initial skills`, {\n loaded: loadedNames,\n tokens: initialTokensUsed,\n missing: missingNames.length > 0 ? missingNames : undefined,\n })\n }\n\n const hasTriggeredSkills =\n Object.keys(config.fileTypeSkills ?? {}).length > 0 ||\n Object.keys(config.agentSkills ?? {}).length > 0 ||\n Object.keys(config.pathPatterns ?? {}).length > 0 ||\n Object.keys(config.contentTriggers ?? {}).length > 0\n\n if (allInitialSkillNames.length === 0 && !hasTriggeredSkills) {\n log(\"warn\", \"No skills configured. Create .opencode/preload-skills.json\")\n }\n\n const getSessionState = (sessionID: string): SessionState => {\n if (!sessionStates.has(sessionID)) {\n sessionStates.set(sessionID, {\n initialSkillsInjected: false,\n loadedSkills: new Set(initialSkills.map((s) => s.name)),\n totalTokensUsed: initialTokensUsed,\n })\n }\n return sessionStates.get(sessionID)!\n }\n\n const pendingSkillInjections = new Map<string, ParsedSkill[]>()\n\n const queueSkillsForInjection = (\n sessionID: string,\n skillNames: string[],\n triggerType: SkillUsageStats[\"triggerType\"],\n state: SessionState\n ) => {\n const newSkillNames = skillNames.filter((name) => !state.loadedSkills.has(name))\n if (newSkillNames.length === 0) return\n\n const result = loadSkillsWithBudget(\n newSkillNames,\n state.totalTokensUsed,\n triggerType,\n sessionID\n )\n\n if (result.skills.length > 0) {\n for (const skill of result.skills) {\n state.loadedSkills.add(skill.name)\n }\n state.totalTokensUsed += result.tokensUsed\n\n const existing = pendingSkillInjections.get(sessionID) ?? []\n pendingSkillInjections.set(sessionID, [...existing, ...result.skills])\n\n log(\"debug\", `Queued ${triggerType} skills for injection`, {\n sessionID,\n skills: result.skills.map((s) => s.name),\n tokens: result.tokensUsed,\n })\n }\n }\n\n const useSystemPromptInjection = config.injectionMethod === \"systemPrompt\"\n\n return {\n \"experimental.chat.system.transform\": useSystemPromptInjection\n ? async (\n input: { sessionID?: string; model: Model },\n output: { system: string[] }\n ): Promise<void> => {\n if (!input.sessionID) return\n\n const state = getSessionState(input.sessionID)\n const skillsToInject: ParsedSkill[] = []\n\n if (initialSkills.length > 0) {\n skillsToInject.push(...initialSkills)\n }\n\n for (const name of state.loadedSkills) {\n const skill = skillCache.get(name)\n if (skill && !skillsToInject.find((s) => s.name === name)) {\n skillsToInject.push(skill)\n }\n }\n\n const pending = pendingSkillInjections.get(input.sessionID)\n if (pending && pending.length > 0) {\n for (const skill of pending) {\n if (!skillsToInject.find((s) => s.name === skill.name)) {\n skillsToInject.push(skill)\n }\n }\n pendingSkillInjections.delete(input.sessionID)\n }\n\n if (skillsToInject.length > 0) {\n const formatted = formatSkillsForInjection(skillsToInject, {\n useSummaries: config.useSummaries,\n skillSettings: config.skillSettings,\n })\n output.system.push(formatted)\n\n if (!state.initialSkillsInjected && initialSkills.length > 0) {\n state.initialSkillsInjected = true\n log(\"info\", \"Injected skills into system prompt\", {\n sessionID: input.sessionID,\n skills: skillsToInject.map((s) => s.name),\n })\n }\n }\n }\n : undefined,\n\n \"chat.message\": async (\n input: {\n sessionID: string\n agent?: string\n model?: { providerID: string; modelID: string }\n messageID?: string\n variant?: string\n },\n output: { message: UserMessage; parts: Part[] }\n ): Promise<void> => {\n if (!input.sessionID) return\n\n const state = getSessionState(input.sessionID)\n const firstTextPart = output.parts.find((p) => p.type === \"text\")\n if (!firstTextPart || !(\"text\" in firstTextPart)) return\n\n const messageText = firstTextPart.text\n\n if (input.agent && config.agentSkills?.[input.agent]) {\n queueSkillsForInjection(\n input.sessionID,\n config.agentSkills[input.agent]!,\n \"agent\",\n state\n )\n }\n\n if (config.contentTriggers) {\n for (const [keyword, skillNames] of Object.entries(\n config.contentTriggers\n )) {\n if (textContainsKeyword(messageText, [keyword])) {\n queueSkillsForInjection(\n input.sessionID,\n skillNames,\n \"content\",\n state\n )\n }\n }\n }\n\n if (!useSystemPromptInjection) {\n const contentToInject: string[] = []\n\n if (!state.initialSkillsInjected && initialFormattedContent) {\n contentToInject.push(initialFormattedContent)\n state.initialSkillsInjected = true\n log(\"info\", \"Injected initial preloaded skills\", {\n sessionID: input.sessionID,\n skills: initialSkills.map((s) => s.name),\n })\n }\n\n const pending = pendingSkillInjections.get(input.sessionID)\n if (pending && pending.length > 0) {\n const formatted = formatSkillsForInjection(pending, {\n useSummaries: config.useSummaries,\n skillSettings: config.skillSettings,\n })\n if (formatted) {\n contentToInject.push(formatted)\n log(\"info\", \"Injected triggered skills\", {\n sessionID: input.sessionID,\n skills: pending.map((s) => s.name),\n })\n }\n pendingSkillInjections.delete(input.sessionID)\n }\n\n if (contentToInject.length > 0) {\n firstTextPart.text = `${contentToInject.join(\"\\n\\n\")}\\n\\n---\\n\\n${firstTextPart.text}`\n }\n }\n },\n\n \"tool.execute.after\": async (\n input: {\n tool: string\n sessionID: string\n callID: string\n },\n _output: {\n title: string\n output: string\n metadata: unknown\n }\n ): Promise<void> => {\n if (!FILE_TOOLS.includes(input.tool)) return\n if (!input.sessionID) return\n\n const state = getSessionState(input.sessionID)\n\n const toolArgs = (_output.metadata as { args?: Record<string, unknown> })\n ?.args\n if (!toolArgs) return\n\n const filePath = getFilePathFromArgs(toolArgs)\n if (!filePath) return\n\n const ext = extname(filePath)\n if (ext && config.fileTypeSkills) {\n const extSkills = getSkillsForExtension(ext, config.fileTypeSkills)\n if (extSkills.length > 0) {\n queueSkillsForInjection(input.sessionID, extSkills, \"fileType\", state)\n }\n }\n\n if (config.pathPatterns) {\n const pathSkills = getSkillsForPath(filePath, config.pathPatterns)\n if (pathSkills.length > 0) {\n queueSkillsForInjection(input.sessionID, pathSkills, \"path\", state)\n }\n }\n },\n\n \"experimental.session.compacting\": async (\n input: { sessionID: string },\n output: { context: string[]; prompt?: string }\n ): Promise<void> => {\n if (!config.persistAfterCompaction) return\n\n const state = sessionStates.get(input.sessionID)\n if (!state || state.loadedSkills.size === 0) return\n\n const allLoadedSkills: ParsedSkill[] = []\n for (const name of state.loadedSkills) {\n const skill = skillCache.get(name)\n if (skill) allLoadedSkills.push(skill)\n }\n\n if (allLoadedSkills.length === 0) return\n\n const formatted = formatSkillsForInjection(\n allLoadedSkills,\n { useSummaries: config.useSummaries, skillSettings: config.skillSettings }\n )\n output.context.push(\n `## Preloaded Skills\\n\\nThe following skills were loaded during this session and should persist:\\n\\n${formatted}`\n )\n\n state.initialSkillsInjected = false\n\n log(\"info\", \"Added all loaded skills to compaction context\", {\n sessionID: input.sessionID,\n skillCount: allLoadedSkills.length,\n })\n\n saveAnalytics()\n },\n\n event: async ({ event }: { event: Event }): Promise<void> => {\n if (\n event.type === \"session.deleted\" &&\n \"sessionID\" in event.properties\n ) {\n const sessionID = event.properties.sessionID as string\n sessionStates.delete(sessionID)\n pendingSkillInjections.delete(sessionID)\n analyticsData.delete(sessionID)\n log(\"debug\", \"Cleaned up session state\", { sessionID })\n saveAnalytics()\n }\n },\n }\n}\n\nexport default PreloadSkillsPlugin\n"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -3,6 +3,7 @@ import { Plugin } from '@opencode-ai/plugin';
|
|
|
3
3
|
interface SkillSettings {
|
|
4
4
|
useSummary?: boolean;
|
|
5
5
|
}
|
|
6
|
+
type InjectionMethod = "systemPrompt" | "chatMessage";
|
|
6
7
|
interface PreloadSkillsConfig {
|
|
7
8
|
skills: string[];
|
|
8
9
|
fileTypeSkills?: Record<string, string[]>;
|
|
@@ -12,6 +13,7 @@ interface PreloadSkillsConfig {
|
|
|
12
13
|
groups?: Record<string, string[]>;
|
|
13
14
|
conditionalSkills?: ConditionalSkill[];
|
|
14
15
|
skillSettings?: Record<string, SkillSettings>;
|
|
16
|
+
injectionMethod?: InjectionMethod;
|
|
15
17
|
maxTokens?: number;
|
|
16
18
|
useSummaries?: boolean;
|
|
17
19
|
analytics?: boolean;
|
package/dist/index.d.ts
CHANGED
|
@@ -3,6 +3,7 @@ import { Plugin } from '@opencode-ai/plugin';
|
|
|
3
3
|
interface SkillSettings {
|
|
4
4
|
useSummary?: boolean;
|
|
5
5
|
}
|
|
6
|
+
type InjectionMethod = "systemPrompt" | "chatMessage";
|
|
6
7
|
interface PreloadSkillsConfig {
|
|
7
8
|
skills: string[];
|
|
8
9
|
fileTypeSkills?: Record<string, string[]>;
|
|
@@ -12,6 +13,7 @@ interface PreloadSkillsConfig {
|
|
|
12
13
|
groups?: Record<string, string[]>;
|
|
13
14
|
conditionalSkills?: ConditionalSkill[];
|
|
14
15
|
skillSettings?: Record<string, SkillSettings>;
|
|
16
|
+
injectionMethod?: InjectionMethod;
|
|
15
17
|
maxTokens?: number;
|
|
16
18
|
useSummaries?: boolean;
|
|
17
19
|
analytics?: boolean;
|
package/dist/index.js
CHANGED
|
@@ -171,6 +171,7 @@ var DEFAULT_CONFIG = {
|
|
|
171
171
|
groups: {},
|
|
172
172
|
conditionalSkills: [],
|
|
173
173
|
skillSettings: {},
|
|
174
|
+
injectionMethod: "chatMessage",
|
|
174
175
|
maxTokens: void 0,
|
|
175
176
|
useSummaries: false,
|
|
176
177
|
analytics: false,
|
|
@@ -243,7 +244,8 @@ function loadConfigFile(projectDir) {
|
|
|
243
244
|
useSummaries: typeof parsed.useSummaries === "boolean" ? parsed.useSummaries : void 0,
|
|
244
245
|
analytics: typeof parsed.analytics === "boolean" ? parsed.analytics : void 0,
|
|
245
246
|
persistAfterCompaction: typeof parsed.persistAfterCompaction === "boolean" ? parsed.persistAfterCompaction : void 0,
|
|
246
|
-
debug: typeof parsed.debug === "boolean" ? parsed.debug : void 0
|
|
247
|
+
debug: typeof parsed.debug === "boolean" ? parsed.debug : void 0,
|
|
248
|
+
injectionMethod: parsed.injectionMethod === "systemPrompt" || parsed.injectionMethod === "chatMessage" ? parsed.injectionMethod : void 0
|
|
247
249
|
};
|
|
248
250
|
} catch {
|
|
249
251
|
return {};
|
|
@@ -327,6 +329,7 @@ var PreloadSkillsPlugin = async (ctx) => {
|
|
|
327
329
|
lastLoaded: now
|
|
328
330
|
});
|
|
329
331
|
}
|
|
332
|
+
saveAnalytics();
|
|
330
333
|
};
|
|
331
334
|
const saveAnalytics = () => {
|
|
332
335
|
if (!config.analytics) return;
|
|
@@ -445,7 +448,45 @@ var PreloadSkillsPlugin = async (ctx) => {
|
|
|
445
448
|
});
|
|
446
449
|
}
|
|
447
450
|
};
|
|
451
|
+
const useSystemPromptInjection = config.injectionMethod === "systemPrompt";
|
|
448
452
|
return {
|
|
453
|
+
"experimental.chat.system.transform": useSystemPromptInjection ? async (input, output) => {
|
|
454
|
+
if (!input.sessionID) return;
|
|
455
|
+
const state = getSessionState(input.sessionID);
|
|
456
|
+
const skillsToInject = [];
|
|
457
|
+
if (initialSkills.length > 0) {
|
|
458
|
+
skillsToInject.push(...initialSkills);
|
|
459
|
+
}
|
|
460
|
+
for (const name of state.loadedSkills) {
|
|
461
|
+
const skill = skillCache.get(name);
|
|
462
|
+
if (skill && !skillsToInject.find((s) => s.name === name)) {
|
|
463
|
+
skillsToInject.push(skill);
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
const pending = pendingSkillInjections.get(input.sessionID);
|
|
467
|
+
if (pending && pending.length > 0) {
|
|
468
|
+
for (const skill of pending) {
|
|
469
|
+
if (!skillsToInject.find((s) => s.name === skill.name)) {
|
|
470
|
+
skillsToInject.push(skill);
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
pendingSkillInjections.delete(input.sessionID);
|
|
474
|
+
}
|
|
475
|
+
if (skillsToInject.length > 0) {
|
|
476
|
+
const formatted = formatSkillsForInjection(skillsToInject, {
|
|
477
|
+
useSummaries: config.useSummaries,
|
|
478
|
+
skillSettings: config.skillSettings
|
|
479
|
+
});
|
|
480
|
+
output.system.push(formatted);
|
|
481
|
+
if (!state.initialSkillsInjected && initialSkills.length > 0) {
|
|
482
|
+
state.initialSkillsInjected = true;
|
|
483
|
+
log("info", "Injected skills into system prompt", {
|
|
484
|
+
sessionID: input.sessionID,
|
|
485
|
+
skills: skillsToInject.map((s) => s.name)
|
|
486
|
+
});
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
} : void 0,
|
|
449
490
|
"chat.message": async (input, output) => {
|
|
450
491
|
if (!input.sessionID) return;
|
|
451
492
|
const state = getSessionState(input.sessionID);
|
|
@@ -474,33 +515,38 @@ var PreloadSkillsPlugin = async (ctx) => {
|
|
|
474
515
|
}
|
|
475
516
|
}
|
|
476
517
|
}
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
skills: initialSkills.map((s) => s.name)
|
|
484
|
-
});
|
|
485
|
-
}
|
|
486
|
-
const pending = pendingSkillInjections.get(input.sessionID);
|
|
487
|
-
if (pending && pending.length > 0) {
|
|
488
|
-
const formatted = formatSkillsForInjection(pending, { useSummaries: config.useSummaries, skillSettings: config.skillSettings });
|
|
489
|
-
if (formatted) {
|
|
490
|
-
contentToInject.push(formatted);
|
|
491
|
-
log("info", "Injected triggered skills", {
|
|
518
|
+
if (!useSystemPromptInjection) {
|
|
519
|
+
const contentToInject = [];
|
|
520
|
+
if (!state.initialSkillsInjected && initialFormattedContent) {
|
|
521
|
+
contentToInject.push(initialFormattedContent);
|
|
522
|
+
state.initialSkillsInjected = true;
|
|
523
|
+
log("info", "Injected initial preloaded skills", {
|
|
492
524
|
sessionID: input.sessionID,
|
|
493
|
-
skills:
|
|
525
|
+
skills: initialSkills.map((s) => s.name)
|
|
494
526
|
});
|
|
495
527
|
}
|
|
496
|
-
pendingSkillInjections.
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
528
|
+
const pending = pendingSkillInjections.get(input.sessionID);
|
|
529
|
+
if (pending && pending.length > 0) {
|
|
530
|
+
const formatted = formatSkillsForInjection(pending, {
|
|
531
|
+
useSummaries: config.useSummaries,
|
|
532
|
+
skillSettings: config.skillSettings
|
|
533
|
+
});
|
|
534
|
+
if (formatted) {
|
|
535
|
+
contentToInject.push(formatted);
|
|
536
|
+
log("info", "Injected triggered skills", {
|
|
537
|
+
sessionID: input.sessionID,
|
|
538
|
+
skills: pending.map((s) => s.name)
|
|
539
|
+
});
|
|
540
|
+
}
|
|
541
|
+
pendingSkillInjections.delete(input.sessionID);
|
|
542
|
+
}
|
|
543
|
+
if (contentToInject.length > 0) {
|
|
544
|
+
firstTextPart.text = `${contentToInject.join("\n\n")}
|
|
500
545
|
|
|
501
546
|
---
|
|
502
547
|
|
|
503
548
|
${firstTextPart.text}`;
|
|
549
|
+
}
|
|
504
550
|
}
|
|
505
551
|
},
|
|
506
552
|
"tool.execute.after": async (input, _output) => {
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/utils.ts","../src/skill-loader.ts","../src/index.ts"],"names":["join","existsSync","readFileSync","homedir"],"mappings":"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","file":"index.js","sourcesContent":["import { existsSync, readFileSync } from \"node:fs\"\nimport { join } from \"node:path\"\n\nexport function estimateTokens(text: string): number {\n return Math.ceil(text.length / 4)\n}\n\nexport function matchGlobPattern(filePath: string, pattern: string): boolean {\n let regexPattern = pattern\n .replace(/\\*\\*\\//g, \"\\x00DOUBLESTARSLASH\\x00\")\n .replace(/\\*\\*/g, \"\\x00DOUBLESTAR\\x00\")\n .replace(/\\*/g, \"\\x00SINGLESTAR\\x00\")\n .replace(/\\?/g, \"\\x00QUESTION\\x00\")\n \n regexPattern = regexPattern.replace(/[.+^${}()|[\\]\\\\]/g, \"\\\\$&\")\n \n regexPattern = regexPattern\n .replace(/\\x00DOUBLESTARSLASH\\x00/g, \"(?:[^/]+/)*\")\n .replace(/\\x00DOUBLESTAR\\x00/g, \".*\")\n .replace(/\\x00SINGLESTAR\\x00/g, \"[^/]*\")\n .replace(/\\x00QUESTION\\x00/g, \"[^/]\")\n\n const regex = new RegExp(`^${regexPattern}$`)\n return regex.test(filePath)\n}\n\nexport function matchesAnyPattern(\n filePath: string,\n patterns: string[]\n): boolean {\n return patterns.some((pattern) => matchGlobPattern(filePath, pattern))\n}\n\nexport function checkCondition(\n condition: { fileExists?: string; packageHasDependency?: string; envVar?: string },\n projectDir: string\n): boolean {\n if (condition.fileExists) {\n const fullPath = join(projectDir, condition.fileExists)\n if (!existsSync(fullPath)) return false\n }\n\n if (condition.packageHasDependency) {\n const packageJsonPath = join(projectDir, \"package.json\")\n if (!existsSync(packageJsonPath)) return false\n\n try {\n const packageJson = JSON.parse(readFileSync(packageJsonPath, \"utf-8\"))\n const deps = {\n ...packageJson.dependencies,\n ...packageJson.devDependencies,\n ...packageJson.peerDependencies,\n }\n if (!deps[condition.packageHasDependency]) return false\n } catch {\n return false\n }\n }\n\n if (condition.envVar) {\n if (!process.env[condition.envVar]) return false\n }\n\n return true\n}\n\nexport function extractKeywords(text: string): string[] {\n const words = text.toLowerCase().match(/\\b[a-z]{3,}\\b/g) ?? []\n return [...new Set(words)]\n}\n\nexport function textContainsKeyword(text: string, keywords: string[]): boolean {\n const lowerText = text.toLowerCase()\n return keywords.some((kw) => lowerText.includes(kw.toLowerCase()))\n}\n","import { existsSync, readFileSync } from \"node:fs\"\nimport { join } from \"node:path\"\nimport { homedir } from \"node:os\"\nimport type { ParsedSkill, SkillSettings } from \"./types.js\"\nimport { estimateTokens } from \"./utils.js\"\n\nconst SKILL_FILENAME = \"SKILL.md\"\n\nconst SKILL_SEARCH_PATHS = [\n (dir: string) => join(dir, \".opencode\", \"skills\"),\n (dir: string) => join(dir, \".claude\", \"skills\"),\n () => join(homedir(), \".config\", \"opencode\", \"skills\"),\n () => join(homedir(), \".claude\", \"skills\"),\n]\n\nfunction findSkillFile(skillName: string, projectDir: string): string | null {\n for (const getPath of SKILL_SEARCH_PATHS) {\n const skillDir = getPath(projectDir)\n const skillPath = join(skillDir, skillName, SKILL_FILENAME)\n\n if (existsSync(skillPath)) {\n return skillPath\n }\n }\n return null\n}\n\ninterface FrontmatterData {\n name?: string\n description?: string\n summary?: string\n}\n\nfunction parseFrontmatter(content: string): FrontmatterData {\n const frontmatterMatch = content.match(/^---\\s*\\n([\\s\\S]*?)\\n---/)\n if (!frontmatterMatch?.[1]) {\n return {}\n }\n\n const frontmatter = frontmatterMatch[1]\n const result: FrontmatterData = {}\n\n const nameMatch = frontmatter.match(/^name:\\s*(.+)$/m)\n if (nameMatch?.[1]) {\n result.name = nameMatch[1].trim()\n }\n\n const descMatch = frontmatter.match(/^description:\\s*(.+)$/m)\n if (descMatch?.[1]) {\n result.description = descMatch[1].trim()\n }\n\n const summaryMatch = frontmatter.match(/^summary:\\s*(.+)$/m)\n if (summaryMatch?.[1]) {\n result.summary = summaryMatch[1].trim()\n }\n\n return result\n}\n\nfunction extractAutoSummary(content: string, maxLength: number = 500): string {\n const withoutFrontmatter = content.replace(/^---\\s*\\n[\\s\\S]*?\\n---\\s*\\n?/, \"\")\n \n const firstSection = withoutFrontmatter.split(/\\n##\\s/)[0] ?? \"\"\n const cleaned = firstSection\n .replace(/^#\\s+.+\\n?/, \"\")\n .replace(/\\n+/g, \" \")\n .trim()\n\n if (cleaned.length <= maxLength) return cleaned\n return cleaned.slice(0, maxLength).replace(/\\s+\\S*$/, \"\") + \"...\"\n}\n\nexport function loadSkill(skillName: string, projectDir: string): ParsedSkill | null {\n const filePath = findSkillFile(skillName, projectDir)\n\n if (!filePath) {\n return null\n }\n\n try {\n const content = readFileSync(filePath, \"utf-8\")\n const { name, description, summary } = parseFrontmatter(content)\n\n return {\n name: name ?? skillName,\n description: description ?? \"\",\n summary: summary ?? extractAutoSummary(content),\n content,\n filePath,\n tokenCount: estimateTokens(content),\n }\n } catch {\n return null\n }\n}\n\nexport function loadSkills(skillNames: string[], projectDir: string): ParsedSkill[] {\n if (!Array.isArray(skillNames)) {\n return []\n }\n\n const skills: ParsedSkill[] = []\n\n for (const name of skillNames) {\n const skill = loadSkill(name, projectDir)\n if (skill) {\n skills.push(skill)\n }\n }\n\n return skills\n}\n\nexport interface FormatOptions {\n useSummaries?: boolean\n skillSettings?: Record<string, SkillSettings>\n}\n\nexport function formatSkillsForInjection(\n skills: ParsedSkill[],\n options: boolean | FormatOptions = false\n): string {\n if (!Array.isArray(skills) || skills.length === 0) {\n return \"\"\n }\n\n const opts: FormatOptions = typeof options === \"boolean\" \n ? { useSummaries: options } \n : options\n \n const globalUseSummaries = opts.useSummaries ?? false\n const skillSettings = opts.skillSettings ?? {}\n\n const parts = skills.map((skill) => {\n const perSkillSetting = skillSettings[skill.name]?.useSummary\n const shouldUseSummary = perSkillSetting ?? globalUseSummaries\n const content = shouldUseSummary && skill.summary ? skill.summary : skill.content\n return `<preloaded-skill name=\"${skill.name}\">\\n${content}\\n</preloaded-skill>`\n })\n\n return `<preloaded-skills>\nThe following skills have been automatically loaded for this session:\n\n${parts.join(\"\\n\\n\")}\n</preloaded-skills>`\n}\n\nexport function calculateTotalTokens(skills: ParsedSkill[]): number {\n return skills.reduce((sum, skill) => sum + skill.tokenCount, 0)\n}\n\nexport function filterSkillsByTokenBudget(\n skills: ParsedSkill[],\n maxTokens: number\n): ParsedSkill[] {\n const result: ParsedSkill[] = []\n let totalTokens = 0\n\n for (const skill of skills) {\n if (totalTokens + skill.tokenCount <= maxTokens) {\n result.push(skill)\n totalTokens += skill.tokenCount\n }\n }\n\n return result\n}\n","import { existsSync, readFileSync, writeFileSync, mkdirSync } from \"node:fs\"\nimport { join, extname, dirname } from \"node:path\"\nimport { homedir } from \"node:os\"\nimport type { Plugin, PluginInput } from \"@opencode-ai/plugin\"\nimport type { Event, UserMessage, Part } from \"@opencode-ai/sdk\"\nimport type {\n PreloadSkillsConfig,\n ParsedSkill,\n SessionState,\n ConditionalSkill,\n SkillSettings,\n SkillUsageStats,\n AnalyticsData,\n} from \"./types.js\"\nimport {\n loadSkills,\n formatSkillsForInjection,\n filterSkillsByTokenBudget,\n calculateTotalTokens,\n} from \"./skill-loader.js\"\nimport {\n checkCondition,\n matchGlobPattern,\n textContainsKeyword,\n} from \"./utils.js\"\n\nexport type { PreloadSkillsConfig, ParsedSkill }\nexport { loadSkills, formatSkillsForInjection }\n\nconst CONFIG_FILENAME = \"preload-skills.json\"\nconst ANALYTICS_FILENAME = \"preload-skills-analytics.json\"\nconst FILE_TOOLS = [\"read\", \"edit\", \"write\", \"glob\", \"grep\"]\n\nconst DEFAULT_CONFIG: PreloadSkillsConfig = {\n skills: [],\n fileTypeSkills: {},\n agentSkills: {},\n pathPatterns: {},\n contentTriggers: {},\n groups: {},\n conditionalSkills: [],\n skillSettings: {},\n maxTokens: undefined,\n useSummaries: false,\n analytics: false,\n persistAfterCompaction: true,\n debug: false,\n}\n\nfunction findConfigFile(projectDir: string): string | null {\n const locations = [\n join(projectDir, \".opencode\", CONFIG_FILENAME),\n join(projectDir, CONFIG_FILENAME),\n join(homedir(), \".config\", \"opencode\", CONFIG_FILENAME),\n ]\n\n for (const path of locations) {\n if (existsSync(path)) {\n return path\n }\n }\n return null\n}\n\nfunction parseStringArrayRecord(raw: unknown): Record<string, string[]> {\n if (!raw || typeof raw !== \"object\") return {}\n\n const result: Record<string, string[]> = {}\n for (const [key, value] of Object.entries(raw)) {\n if (Array.isArray(value)) {\n result[key] = value.filter((v) => typeof v === \"string\")\n }\n }\n return result\n}\n\nfunction parseConditionalSkills(raw: unknown): ConditionalSkill[] {\n if (!Array.isArray(raw)) return []\n\n return raw.filter(\n (item): item is ConditionalSkill =>\n typeof item === \"object\" &&\n item !== null &&\n typeof item.skill === \"string\" &&\n typeof item.if === \"object\"\n )\n}\n\nfunction parseSkillSettings(raw: unknown): Record<string, SkillSettings> {\n if (!raw || typeof raw !== \"object\") return {}\n\n const result: Record<string, SkillSettings> = {}\n for (const [skillName, settings] of Object.entries(raw)) {\n if (typeof settings === \"object\" && settings !== null) {\n const parsed: SkillSettings = {}\n if (\"useSummary\" in settings && typeof settings.useSummary === \"boolean\") {\n parsed.useSummary = settings.useSummary\n }\n if (Object.keys(parsed).length > 0) {\n result[skillName] = parsed\n }\n }\n }\n return result\n}\n\nfunction loadConfigFile(projectDir: string): Partial<PreloadSkillsConfig> {\n const configPath = findConfigFile(projectDir)\n if (!configPath) {\n return {}\n }\n\n try {\n const content = readFileSync(configPath, \"utf-8\")\n const parsed = JSON.parse(content) as Record<string, unknown>\n\n return {\n skills: Array.isArray(parsed.skills) ? parsed.skills : [],\n fileTypeSkills: parseStringArrayRecord(parsed.fileTypeSkills),\n agentSkills: parseStringArrayRecord(parsed.agentSkills),\n pathPatterns: parseStringArrayRecord(parsed.pathPatterns),\n contentTriggers: parseStringArrayRecord(parsed.contentTriggers),\n groups: parseStringArrayRecord(parsed.groups),\n conditionalSkills: parseConditionalSkills(parsed.conditionalSkills),\n skillSettings: parseSkillSettings(parsed.skillSettings),\n maxTokens:\n typeof parsed.maxTokens === \"number\" ? parsed.maxTokens : undefined,\n useSummaries:\n typeof parsed.useSummaries === \"boolean\"\n ? parsed.useSummaries\n : undefined,\n analytics:\n typeof parsed.analytics === \"boolean\" ? parsed.analytics : undefined,\n persistAfterCompaction:\n typeof parsed.persistAfterCompaction === \"boolean\"\n ? parsed.persistAfterCompaction\n : undefined,\n debug: typeof parsed.debug === \"boolean\" ? parsed.debug : undefined,\n }\n } catch {\n return {}\n }\n}\n\nfunction getFilePathFromArgs(args: Record<string, unknown>): string | null {\n if (typeof args.filePath === \"string\") return args.filePath\n if (typeof args.path === \"string\") return args.path\n if (typeof args.file === \"string\") return args.file\n return null\n}\n\nfunction getSkillsForExtension(\n ext: string,\n fileTypeSkills: Record<string, string[]>\n): string[] {\n const skills: string[] = []\n\n for (const [pattern, skillNames] of Object.entries(fileTypeSkills)) {\n const extensions = pattern.split(\",\").map((e) => e.trim().toLowerCase())\n if (extensions.includes(ext.toLowerCase())) {\n skills.push(...skillNames)\n }\n }\n\n return [...new Set(skills)]\n}\n\nfunction getSkillsForPath(\n filePath: string,\n pathPatterns: Record<string, string[]>\n): string[] {\n const skills: string[] = []\n\n for (const [pattern, skillNames] of Object.entries(pathPatterns)) {\n if (matchGlobPattern(filePath, pattern)) {\n skills.push(...skillNames)\n }\n }\n\n return [...new Set(skills)]\n}\n\nfunction resolveSkillGroups(\n skillNames: string[],\n groups: Record<string, string[]>\n): string[] {\n const resolved: string[] = []\n\n for (const name of skillNames) {\n if (name.startsWith(\"@\") && groups[name.slice(1)]) {\n resolved.push(...groups[name.slice(1)]!)\n } else {\n resolved.push(name)\n }\n }\n\n return [...new Set(resolved)]\n}\n\nexport const PreloadSkillsPlugin: Plugin = async (ctx: PluginInput) => {\n const sessionStates = new Map<string, SessionState>()\n const analyticsData = new Map<string, AnalyticsData>()\n\n const fileConfig = loadConfigFile(ctx.directory)\n const config: PreloadSkillsConfig = {\n ...DEFAULT_CONFIG,\n ...fileConfig,\n }\n\n const log = (\n level: \"debug\" | \"info\" | \"warn\" | \"error\",\n message: string,\n extra?: Record<string, unknown>\n ) => {\n if (level === \"debug\" && !config.debug) return\n\n ctx.client.app.log({\n body: {\n service: \"preload-skills\",\n level,\n message,\n extra,\n },\n })\n }\n\n const trackSkillUsage = (\n sessionID: string,\n skillName: string,\n triggerType: SkillUsageStats[\"triggerType\"]\n ) => {\n if (!config.analytics) return\n\n if (!analyticsData.has(sessionID)) {\n analyticsData.set(sessionID, {\n sessionId: sessionID,\n skillUsage: new Map(),\n })\n }\n\n const data = analyticsData.get(sessionID)!\n const now = Date.now()\n\n if (data.skillUsage.has(skillName)) {\n const stats = data.skillUsage.get(skillName)!\n stats.loadCount++\n stats.lastLoaded = now\n } else {\n data.skillUsage.set(skillName, {\n skillName,\n loadCount: 1,\n triggerType,\n firstLoaded: now,\n lastLoaded: now,\n })\n }\n }\n\n const saveAnalytics = () => {\n if (!config.analytics) return\n\n try {\n const analyticsPath = join(ctx.directory, \".opencode\", ANALYTICS_FILENAME)\n const dir = dirname(analyticsPath)\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true })\n }\n\n const serializable: Record<string, unknown> = {}\n for (const [sessionId, data] of analyticsData) {\n serializable[sessionId] = {\n sessionId: data.sessionId,\n skillUsage: Object.fromEntries(data.skillUsage),\n }\n }\n\n writeFileSync(analyticsPath, JSON.stringify(serializable, null, 2))\n } catch {\n log(\"warn\", \"Failed to save analytics\")\n }\n }\n\n const skillCache = new Map<string, ParsedSkill>()\n\n const loadSkillsWithBudget = (\n skillNames: string[],\n currentTokens: number,\n triggerType: SkillUsageStats[\"triggerType\"],\n sessionID: string\n ): { skills: ParsedSkill[]; tokensUsed: number } => {\n const resolved = resolveSkillGroups(skillNames, config.groups ?? {})\n let skills = loadSkills(resolved, ctx.directory)\n\n for (const skill of skills) {\n skillCache.set(skill.name, skill)\n }\n\n if (config.maxTokens) {\n const remainingBudget = config.maxTokens - currentTokens\n skills = filterSkillsByTokenBudget(skills, remainingBudget)\n }\n\n for (const skill of skills) {\n trackSkillUsage(sessionID, skill.name, triggerType)\n }\n\n return {\n skills,\n tokensUsed: calculateTotalTokens(skills),\n }\n }\n\n const resolveConditionalSkills = (): string[] => {\n if (!config.conditionalSkills?.length) return []\n\n const resolved: string[] = []\n for (const { skill, if: condition } of config.conditionalSkills) {\n if (checkCondition(condition, ctx.directory)) {\n resolved.push(skill)\n }\n }\n\n return resolved\n }\n\n let initialSkills: ParsedSkill[] = []\n let initialFormattedContent = \"\"\n let initialTokensUsed = 0\n\n const allInitialSkillNames = [\n ...config.skills,\n ...resolveConditionalSkills(),\n ]\n\n if (allInitialSkillNames.length > 0) {\n const result = loadSkillsWithBudget(\n allInitialSkillNames,\n 0,\n \"initial\",\n \"__init__\"\n )\n initialSkills = result.skills\n initialTokensUsed = result.tokensUsed\n initialFormattedContent = formatSkillsForInjection(\n initialSkills,\n { useSummaries: config.useSummaries, skillSettings: config.skillSettings }\n )\n\n const loadedNames = initialSkills.map((s) => s.name)\n const missingNames = allInitialSkillNames.filter(\n (s) => !loadedNames.includes(s) && !s.startsWith(\"@\")\n )\n\n log(\"info\", `Loaded ${initialSkills.length} initial skills`, {\n loaded: loadedNames,\n tokens: initialTokensUsed,\n missing: missingNames.length > 0 ? missingNames : undefined,\n })\n }\n\n const hasTriggeredSkills =\n Object.keys(config.fileTypeSkills ?? {}).length > 0 ||\n Object.keys(config.agentSkills ?? {}).length > 0 ||\n Object.keys(config.pathPatterns ?? {}).length > 0 ||\n Object.keys(config.contentTriggers ?? {}).length > 0\n\n if (allInitialSkillNames.length === 0 && !hasTriggeredSkills) {\n log(\"warn\", \"No skills configured. Create .opencode/preload-skills.json\")\n }\n\n const getSessionState = (sessionID: string): SessionState => {\n if (!sessionStates.has(sessionID)) {\n sessionStates.set(sessionID, {\n initialSkillsInjected: false,\n loadedSkills: new Set(initialSkills.map((s) => s.name)),\n totalTokensUsed: initialTokensUsed,\n })\n }\n return sessionStates.get(sessionID)!\n }\n\n const pendingSkillInjections = new Map<string, ParsedSkill[]>()\n\n const queueSkillsForInjection = (\n sessionID: string,\n skillNames: string[],\n triggerType: SkillUsageStats[\"triggerType\"],\n state: SessionState\n ) => {\n const newSkillNames = skillNames.filter((name) => !state.loadedSkills.has(name))\n if (newSkillNames.length === 0) return\n\n const result = loadSkillsWithBudget(\n newSkillNames,\n state.totalTokensUsed,\n triggerType,\n sessionID\n )\n\n if (result.skills.length > 0) {\n for (const skill of result.skills) {\n state.loadedSkills.add(skill.name)\n }\n state.totalTokensUsed += result.tokensUsed\n\n const existing = pendingSkillInjections.get(sessionID) ?? []\n pendingSkillInjections.set(sessionID, [...existing, ...result.skills])\n\n log(\"debug\", `Queued ${triggerType} skills for injection`, {\n sessionID,\n skills: result.skills.map((s) => s.name),\n tokens: result.tokensUsed,\n })\n }\n }\n\n return {\n \"chat.message\": async (\n input: {\n sessionID: string\n agent?: string\n model?: { providerID: string; modelID: string }\n messageID?: string\n variant?: string\n },\n output: { message: UserMessage; parts: Part[] }\n ): Promise<void> => {\n if (!input.sessionID) return\n\n const state = getSessionState(input.sessionID)\n const firstTextPart = output.parts.find((p) => p.type === \"text\")\n if (!firstTextPart || !(\"text\" in firstTextPart)) return\n\n const messageText = firstTextPart.text\n\n if (input.agent && config.agentSkills?.[input.agent]) {\n queueSkillsForInjection(\n input.sessionID,\n config.agentSkills[input.agent]!,\n \"agent\",\n state\n )\n }\n\n if (config.contentTriggers) {\n for (const [keyword, skillNames] of Object.entries(\n config.contentTriggers\n )) {\n if (textContainsKeyword(messageText, [keyword])) {\n queueSkillsForInjection(\n input.sessionID,\n skillNames,\n \"content\",\n state\n )\n }\n }\n }\n\n const contentToInject: string[] = []\n\n if (!state.initialSkillsInjected && initialFormattedContent) {\n contentToInject.push(initialFormattedContent)\n state.initialSkillsInjected = true\n log(\"info\", \"Injected initial preloaded skills\", {\n sessionID: input.sessionID,\n skills: initialSkills.map((s) => s.name),\n })\n }\n\n const pending = pendingSkillInjections.get(input.sessionID)\n if (pending && pending.length > 0) {\n const formatted = formatSkillsForInjection(pending, { useSummaries: config.useSummaries, skillSettings: config.skillSettings })\n if (formatted) {\n contentToInject.push(formatted)\n log(\"info\", \"Injected triggered skills\", {\n sessionID: input.sessionID,\n skills: pending.map((s) => s.name),\n })\n }\n pendingSkillInjections.delete(input.sessionID)\n }\n\n if (contentToInject.length > 0) {\n firstTextPart.text = `${contentToInject.join(\"\\n\\n\")}\\n\\n---\\n\\n${firstTextPart.text}`\n }\n },\n\n \"tool.execute.after\": async (\n input: {\n tool: string\n sessionID: string\n callID: string\n },\n _output: {\n title: string\n output: string\n metadata: unknown\n }\n ): Promise<void> => {\n if (!FILE_TOOLS.includes(input.tool)) return\n if (!input.sessionID) return\n\n const state = getSessionState(input.sessionID)\n\n const toolArgs = (_output.metadata as { args?: Record<string, unknown> })\n ?.args\n if (!toolArgs) return\n\n const filePath = getFilePathFromArgs(toolArgs)\n if (!filePath) return\n\n const ext = extname(filePath)\n if (ext && config.fileTypeSkills) {\n const extSkills = getSkillsForExtension(ext, config.fileTypeSkills)\n if (extSkills.length > 0) {\n queueSkillsForInjection(input.sessionID, extSkills, \"fileType\", state)\n }\n }\n\n if (config.pathPatterns) {\n const pathSkills = getSkillsForPath(filePath, config.pathPatterns)\n if (pathSkills.length > 0) {\n queueSkillsForInjection(input.sessionID, pathSkills, \"path\", state)\n }\n }\n },\n\n \"experimental.session.compacting\": async (\n input: { sessionID: string },\n output: { context: string[]; prompt?: string }\n ): Promise<void> => {\n if (!config.persistAfterCompaction) return\n\n const state = sessionStates.get(input.sessionID)\n if (!state || state.loadedSkills.size === 0) return\n\n const allLoadedSkills: ParsedSkill[] = []\n for (const name of state.loadedSkills) {\n const skill = skillCache.get(name)\n if (skill) allLoadedSkills.push(skill)\n }\n\n if (allLoadedSkills.length === 0) return\n\n const formatted = formatSkillsForInjection(\n allLoadedSkills,\n { useSummaries: config.useSummaries, skillSettings: config.skillSettings }\n )\n output.context.push(\n `## Preloaded Skills\\n\\nThe following skills were loaded during this session and should persist:\\n\\n${formatted}`\n )\n\n state.initialSkillsInjected = false\n\n log(\"info\", \"Added all loaded skills to compaction context\", {\n sessionID: input.sessionID,\n skillCount: allLoadedSkills.length,\n })\n\n saveAnalytics()\n },\n\n event: async ({ event }: { event: Event }): Promise<void> => {\n if (\n event.type === \"session.deleted\" &&\n \"sessionID\" in event.properties\n ) {\n const sessionID = event.properties.sessionID as string\n sessionStates.delete(sessionID)\n pendingSkillInjections.delete(sessionID)\n analyticsData.delete(sessionID)\n log(\"debug\", \"Cleaned up session state\", { sessionID })\n saveAnalytics()\n }\n },\n }\n}\n\nexport default PreloadSkillsPlugin\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/utils.ts","../src/skill-loader.ts","../src/index.ts"],"names":["join","existsSync","readFileSync","homedir"],"mappings":"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","file":"index.js","sourcesContent":["import { existsSync, readFileSync } from \"node:fs\"\nimport { join } from \"node:path\"\n\nexport function estimateTokens(text: string): number {\n return Math.ceil(text.length / 4)\n}\n\nexport function matchGlobPattern(filePath: string, pattern: string): boolean {\n let regexPattern = pattern\n .replace(/\\*\\*\\//g, \"\\x00DOUBLESTARSLASH\\x00\")\n .replace(/\\*\\*/g, \"\\x00DOUBLESTAR\\x00\")\n .replace(/\\*/g, \"\\x00SINGLESTAR\\x00\")\n .replace(/\\?/g, \"\\x00QUESTION\\x00\")\n \n regexPattern = regexPattern.replace(/[.+^${}()|[\\]\\\\]/g, \"\\\\$&\")\n \n regexPattern = regexPattern\n .replace(/\\x00DOUBLESTARSLASH\\x00/g, \"(?:[^/]+/)*\")\n .replace(/\\x00DOUBLESTAR\\x00/g, \".*\")\n .replace(/\\x00SINGLESTAR\\x00/g, \"[^/]*\")\n .replace(/\\x00QUESTION\\x00/g, \"[^/]\")\n\n const regex = new RegExp(`^${regexPattern}$`)\n return regex.test(filePath)\n}\n\nexport function matchesAnyPattern(\n filePath: string,\n patterns: string[]\n): boolean {\n return patterns.some((pattern) => matchGlobPattern(filePath, pattern))\n}\n\nexport function checkCondition(\n condition: { fileExists?: string; packageHasDependency?: string; envVar?: string },\n projectDir: string\n): boolean {\n if (condition.fileExists) {\n const fullPath = join(projectDir, condition.fileExists)\n if (!existsSync(fullPath)) return false\n }\n\n if (condition.packageHasDependency) {\n const packageJsonPath = join(projectDir, \"package.json\")\n if (!existsSync(packageJsonPath)) return false\n\n try {\n const packageJson = JSON.parse(readFileSync(packageJsonPath, \"utf-8\"))\n const deps = {\n ...packageJson.dependencies,\n ...packageJson.devDependencies,\n ...packageJson.peerDependencies,\n }\n if (!deps[condition.packageHasDependency]) return false\n } catch {\n return false\n }\n }\n\n if (condition.envVar) {\n if (!process.env[condition.envVar]) return false\n }\n\n return true\n}\n\nexport function extractKeywords(text: string): string[] {\n const words = text.toLowerCase().match(/\\b[a-z]{3,}\\b/g) ?? []\n return [...new Set(words)]\n}\n\nexport function textContainsKeyword(text: string, keywords: string[]): boolean {\n const lowerText = text.toLowerCase()\n return keywords.some((kw) => lowerText.includes(kw.toLowerCase()))\n}\n","import { existsSync, readFileSync } from \"node:fs\"\nimport { join } from \"node:path\"\nimport { homedir } from \"node:os\"\nimport type { ParsedSkill, SkillSettings } from \"./types.js\"\nimport { estimateTokens } from \"./utils.js\"\n\nconst SKILL_FILENAME = \"SKILL.md\"\n\nconst SKILL_SEARCH_PATHS = [\n (dir: string) => join(dir, \".opencode\", \"skills\"),\n (dir: string) => join(dir, \".claude\", \"skills\"),\n () => join(homedir(), \".config\", \"opencode\", \"skills\"),\n () => join(homedir(), \".claude\", \"skills\"),\n]\n\nfunction findSkillFile(skillName: string, projectDir: string): string | null {\n for (const getPath of SKILL_SEARCH_PATHS) {\n const skillDir = getPath(projectDir)\n const skillPath = join(skillDir, skillName, SKILL_FILENAME)\n\n if (existsSync(skillPath)) {\n return skillPath\n }\n }\n return null\n}\n\ninterface FrontmatterData {\n name?: string\n description?: string\n summary?: string\n}\n\nfunction parseFrontmatter(content: string): FrontmatterData {\n const frontmatterMatch = content.match(/^---\\s*\\n([\\s\\S]*?)\\n---/)\n if (!frontmatterMatch?.[1]) {\n return {}\n }\n\n const frontmatter = frontmatterMatch[1]\n const result: FrontmatterData = {}\n\n const nameMatch = frontmatter.match(/^name:\\s*(.+)$/m)\n if (nameMatch?.[1]) {\n result.name = nameMatch[1].trim()\n }\n\n const descMatch = frontmatter.match(/^description:\\s*(.+)$/m)\n if (descMatch?.[1]) {\n result.description = descMatch[1].trim()\n }\n\n const summaryMatch = frontmatter.match(/^summary:\\s*(.+)$/m)\n if (summaryMatch?.[1]) {\n result.summary = summaryMatch[1].trim()\n }\n\n return result\n}\n\nfunction extractAutoSummary(content: string, maxLength: number = 500): string {\n const withoutFrontmatter = content.replace(/^---\\s*\\n[\\s\\S]*?\\n---\\s*\\n?/, \"\")\n \n const firstSection = withoutFrontmatter.split(/\\n##\\s/)[0] ?? \"\"\n const cleaned = firstSection\n .replace(/^#\\s+.+\\n?/, \"\")\n .replace(/\\n+/g, \" \")\n .trim()\n\n if (cleaned.length <= maxLength) return cleaned\n return cleaned.slice(0, maxLength).replace(/\\s+\\S*$/, \"\") + \"...\"\n}\n\nexport function loadSkill(skillName: string, projectDir: string): ParsedSkill | null {\n const filePath = findSkillFile(skillName, projectDir)\n\n if (!filePath) {\n return null\n }\n\n try {\n const content = readFileSync(filePath, \"utf-8\")\n const { name, description, summary } = parseFrontmatter(content)\n\n return {\n name: name ?? skillName,\n description: description ?? \"\",\n summary: summary ?? extractAutoSummary(content),\n content,\n filePath,\n tokenCount: estimateTokens(content),\n }\n } catch {\n return null\n }\n}\n\nexport function loadSkills(skillNames: string[], projectDir: string): ParsedSkill[] {\n if (!Array.isArray(skillNames)) {\n return []\n }\n\n const skills: ParsedSkill[] = []\n\n for (const name of skillNames) {\n const skill = loadSkill(name, projectDir)\n if (skill) {\n skills.push(skill)\n }\n }\n\n return skills\n}\n\nexport interface FormatOptions {\n useSummaries?: boolean\n skillSettings?: Record<string, SkillSettings>\n}\n\nexport function formatSkillsForInjection(\n skills: ParsedSkill[],\n options: boolean | FormatOptions = false\n): string {\n if (!Array.isArray(skills) || skills.length === 0) {\n return \"\"\n }\n\n const opts: FormatOptions = typeof options === \"boolean\" \n ? { useSummaries: options } \n : options\n \n const globalUseSummaries = opts.useSummaries ?? false\n const skillSettings = opts.skillSettings ?? {}\n\n const parts = skills.map((skill) => {\n const perSkillSetting = skillSettings[skill.name]?.useSummary\n const shouldUseSummary = perSkillSetting ?? globalUseSummaries\n const content = shouldUseSummary && skill.summary ? skill.summary : skill.content\n return `<preloaded-skill name=\"${skill.name}\">\\n${content}\\n</preloaded-skill>`\n })\n\n return `<preloaded-skills>\nThe following skills have been automatically loaded for this session:\n\n${parts.join(\"\\n\\n\")}\n</preloaded-skills>`\n}\n\nexport function calculateTotalTokens(skills: ParsedSkill[]): number {\n return skills.reduce((sum, skill) => sum + skill.tokenCount, 0)\n}\n\nexport function filterSkillsByTokenBudget(\n skills: ParsedSkill[],\n maxTokens: number\n): ParsedSkill[] {\n const result: ParsedSkill[] = []\n let totalTokens = 0\n\n for (const skill of skills) {\n if (totalTokens + skill.tokenCount <= maxTokens) {\n result.push(skill)\n totalTokens += skill.tokenCount\n }\n }\n\n return result\n}\n","import { existsSync, readFileSync, writeFileSync, mkdirSync } from \"node:fs\"\nimport { join, extname, dirname } from \"node:path\"\nimport { homedir } from \"node:os\"\nimport type { Plugin, PluginInput } from \"@opencode-ai/plugin\"\nimport type { Event, UserMessage, Part, Model } from \"@opencode-ai/sdk\"\nimport type {\n PreloadSkillsConfig,\n ParsedSkill,\n SessionState,\n ConditionalSkill,\n SkillSettings,\n SkillUsageStats,\n AnalyticsData,\n InjectionMethod,\n} from \"./types.js\"\nimport {\n loadSkills,\n formatSkillsForInjection,\n filterSkillsByTokenBudget,\n calculateTotalTokens,\n} from \"./skill-loader.js\"\nimport {\n checkCondition,\n matchGlobPattern,\n textContainsKeyword,\n} from \"./utils.js\"\n\nexport type { PreloadSkillsConfig, ParsedSkill }\nexport { loadSkills, formatSkillsForInjection }\n\nconst CONFIG_FILENAME = \"preload-skills.json\"\nconst ANALYTICS_FILENAME = \"preload-skills-analytics.json\"\nconst FILE_TOOLS = [\"read\", \"edit\", \"write\", \"glob\", \"grep\"]\n\nconst DEFAULT_CONFIG: PreloadSkillsConfig = {\n skills: [],\n fileTypeSkills: {},\n agentSkills: {},\n pathPatterns: {},\n contentTriggers: {},\n groups: {},\n conditionalSkills: [],\n skillSettings: {},\n injectionMethod: \"chatMessage\",\n maxTokens: undefined,\n useSummaries: false,\n analytics: false,\n persistAfterCompaction: true,\n debug: false,\n}\n\nfunction findConfigFile(projectDir: string): string | null {\n const locations = [\n join(projectDir, \".opencode\", CONFIG_FILENAME),\n join(projectDir, CONFIG_FILENAME),\n join(homedir(), \".config\", \"opencode\", CONFIG_FILENAME),\n ]\n\n for (const path of locations) {\n if (existsSync(path)) {\n return path\n }\n }\n return null\n}\n\nfunction parseStringArrayRecord(raw: unknown): Record<string, string[]> {\n if (!raw || typeof raw !== \"object\") return {}\n\n const result: Record<string, string[]> = {}\n for (const [key, value] of Object.entries(raw)) {\n if (Array.isArray(value)) {\n result[key] = value.filter((v) => typeof v === \"string\")\n }\n }\n return result\n}\n\nfunction parseConditionalSkills(raw: unknown): ConditionalSkill[] {\n if (!Array.isArray(raw)) return []\n\n return raw.filter(\n (item): item is ConditionalSkill =>\n typeof item === \"object\" &&\n item !== null &&\n typeof item.skill === \"string\" &&\n typeof item.if === \"object\"\n )\n}\n\nfunction parseSkillSettings(raw: unknown): Record<string, SkillSettings> {\n if (!raw || typeof raw !== \"object\") return {}\n\n const result: Record<string, SkillSettings> = {}\n for (const [skillName, settings] of Object.entries(raw)) {\n if (typeof settings === \"object\" && settings !== null) {\n const parsed: SkillSettings = {}\n if (\"useSummary\" in settings && typeof settings.useSummary === \"boolean\") {\n parsed.useSummary = settings.useSummary\n }\n if (Object.keys(parsed).length > 0) {\n result[skillName] = parsed\n }\n }\n }\n return result\n}\n\nfunction loadConfigFile(projectDir: string): Partial<PreloadSkillsConfig> {\n const configPath = findConfigFile(projectDir)\n if (!configPath) {\n return {}\n }\n\n try {\n const content = readFileSync(configPath, \"utf-8\")\n const parsed = JSON.parse(content) as Record<string, unknown>\n\n return {\n skills: Array.isArray(parsed.skills) ? parsed.skills : [],\n fileTypeSkills: parseStringArrayRecord(parsed.fileTypeSkills),\n agentSkills: parseStringArrayRecord(parsed.agentSkills),\n pathPatterns: parseStringArrayRecord(parsed.pathPatterns),\n contentTriggers: parseStringArrayRecord(parsed.contentTriggers),\n groups: parseStringArrayRecord(parsed.groups),\n conditionalSkills: parseConditionalSkills(parsed.conditionalSkills),\n skillSettings: parseSkillSettings(parsed.skillSettings),\n maxTokens:\n typeof parsed.maxTokens === \"number\" ? parsed.maxTokens : undefined,\n useSummaries:\n typeof parsed.useSummaries === \"boolean\"\n ? parsed.useSummaries\n : undefined,\n analytics:\n typeof parsed.analytics === \"boolean\" ? parsed.analytics : undefined,\n persistAfterCompaction:\n typeof parsed.persistAfterCompaction === \"boolean\"\n ? parsed.persistAfterCompaction\n : undefined,\n debug: typeof parsed.debug === \"boolean\" ? parsed.debug : undefined,\n injectionMethod:\n parsed.injectionMethod === \"systemPrompt\" ||\n parsed.injectionMethod === \"chatMessage\"\n ? (parsed.injectionMethod as InjectionMethod)\n : undefined,\n }\n } catch {\n return {}\n }\n}\n\nfunction getFilePathFromArgs(args: Record<string, unknown>): string | null {\n if (typeof args.filePath === \"string\") return args.filePath\n if (typeof args.path === \"string\") return args.path\n if (typeof args.file === \"string\") return args.file\n return null\n}\n\nfunction getSkillsForExtension(\n ext: string,\n fileTypeSkills: Record<string, string[]>\n): string[] {\n const skills: string[] = []\n\n for (const [pattern, skillNames] of Object.entries(fileTypeSkills)) {\n const extensions = pattern.split(\",\").map((e) => e.trim().toLowerCase())\n if (extensions.includes(ext.toLowerCase())) {\n skills.push(...skillNames)\n }\n }\n\n return [...new Set(skills)]\n}\n\nfunction getSkillsForPath(\n filePath: string,\n pathPatterns: Record<string, string[]>\n): string[] {\n const skills: string[] = []\n\n for (const [pattern, skillNames] of Object.entries(pathPatterns)) {\n if (matchGlobPattern(filePath, pattern)) {\n skills.push(...skillNames)\n }\n }\n\n return [...new Set(skills)]\n}\n\nfunction resolveSkillGroups(\n skillNames: string[],\n groups: Record<string, string[]>\n): string[] {\n const resolved: string[] = []\n\n for (const name of skillNames) {\n if (name.startsWith(\"@\") && groups[name.slice(1)]) {\n resolved.push(...groups[name.slice(1)]!)\n } else {\n resolved.push(name)\n }\n }\n\n return [...new Set(resolved)]\n}\n\nexport const PreloadSkillsPlugin: Plugin = async (ctx: PluginInput) => {\n const sessionStates = new Map<string, SessionState>()\n const analyticsData = new Map<string, AnalyticsData>()\n\n const fileConfig = loadConfigFile(ctx.directory)\n const config: PreloadSkillsConfig = {\n ...DEFAULT_CONFIG,\n ...fileConfig,\n }\n\n const log = (\n level: \"debug\" | \"info\" | \"warn\" | \"error\",\n message: string,\n extra?: Record<string, unknown>\n ) => {\n if (level === \"debug\" && !config.debug) return\n\n ctx.client.app.log({\n body: {\n service: \"preload-skills\",\n level,\n message,\n extra,\n },\n })\n }\n\n const trackSkillUsage = (\n sessionID: string,\n skillName: string,\n triggerType: SkillUsageStats[\"triggerType\"]\n ) => {\n if (!config.analytics) return\n\n if (!analyticsData.has(sessionID)) {\n analyticsData.set(sessionID, {\n sessionId: sessionID,\n skillUsage: new Map(),\n })\n }\n\n const data = analyticsData.get(sessionID)!\n const now = Date.now()\n\n if (data.skillUsage.has(skillName)) {\n const stats = data.skillUsage.get(skillName)!\n stats.loadCount++\n stats.lastLoaded = now\n } else {\n data.skillUsage.set(skillName, {\n skillName,\n loadCount: 1,\n triggerType,\n firstLoaded: now,\n lastLoaded: now,\n })\n }\n\n saveAnalytics()\n }\n\n const saveAnalytics = () => {\n if (!config.analytics) return\n\n try {\n const analyticsPath = join(ctx.directory, \".opencode\", ANALYTICS_FILENAME)\n const dir = dirname(analyticsPath)\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true })\n }\n\n const serializable: Record<string, unknown> = {}\n for (const [sessionId, data] of analyticsData) {\n serializable[sessionId] = {\n sessionId: data.sessionId,\n skillUsage: Object.fromEntries(data.skillUsage),\n }\n }\n\n writeFileSync(analyticsPath, JSON.stringify(serializable, null, 2))\n } catch {\n log(\"warn\", \"Failed to save analytics\")\n }\n }\n\n const skillCache = new Map<string, ParsedSkill>()\n\n const loadSkillsWithBudget = (\n skillNames: string[],\n currentTokens: number,\n triggerType: SkillUsageStats[\"triggerType\"],\n sessionID: string\n ): { skills: ParsedSkill[]; tokensUsed: number } => {\n const resolved = resolveSkillGroups(skillNames, config.groups ?? {})\n let skills = loadSkills(resolved, ctx.directory)\n\n for (const skill of skills) {\n skillCache.set(skill.name, skill)\n }\n\n if (config.maxTokens) {\n const remainingBudget = config.maxTokens - currentTokens\n skills = filterSkillsByTokenBudget(skills, remainingBudget)\n }\n\n for (const skill of skills) {\n trackSkillUsage(sessionID, skill.name, triggerType)\n }\n\n return {\n skills,\n tokensUsed: calculateTotalTokens(skills),\n }\n }\n\n const resolveConditionalSkills = (): string[] => {\n if (!config.conditionalSkills?.length) return []\n\n const resolved: string[] = []\n for (const { skill, if: condition } of config.conditionalSkills) {\n if (checkCondition(condition, ctx.directory)) {\n resolved.push(skill)\n }\n }\n\n return resolved\n }\n\n let initialSkills: ParsedSkill[] = []\n let initialFormattedContent = \"\"\n let initialTokensUsed = 0\n\n const allInitialSkillNames = [\n ...config.skills,\n ...resolveConditionalSkills(),\n ]\n\n if (allInitialSkillNames.length > 0) {\n const result = loadSkillsWithBudget(\n allInitialSkillNames,\n 0,\n \"initial\",\n \"__init__\"\n )\n initialSkills = result.skills\n initialTokensUsed = result.tokensUsed\n initialFormattedContent = formatSkillsForInjection(\n initialSkills,\n { useSummaries: config.useSummaries, skillSettings: config.skillSettings }\n )\n\n const loadedNames = initialSkills.map((s) => s.name)\n const missingNames = allInitialSkillNames.filter(\n (s) => !loadedNames.includes(s) && !s.startsWith(\"@\")\n )\n\n log(\"info\", `Loaded ${initialSkills.length} initial skills`, {\n loaded: loadedNames,\n tokens: initialTokensUsed,\n missing: missingNames.length > 0 ? missingNames : undefined,\n })\n }\n\n const hasTriggeredSkills =\n Object.keys(config.fileTypeSkills ?? {}).length > 0 ||\n Object.keys(config.agentSkills ?? {}).length > 0 ||\n Object.keys(config.pathPatterns ?? {}).length > 0 ||\n Object.keys(config.contentTriggers ?? {}).length > 0\n\n if (allInitialSkillNames.length === 0 && !hasTriggeredSkills) {\n log(\"warn\", \"No skills configured. Create .opencode/preload-skills.json\")\n }\n\n const getSessionState = (sessionID: string): SessionState => {\n if (!sessionStates.has(sessionID)) {\n sessionStates.set(sessionID, {\n initialSkillsInjected: false,\n loadedSkills: new Set(initialSkills.map((s) => s.name)),\n totalTokensUsed: initialTokensUsed,\n })\n }\n return sessionStates.get(sessionID)!\n }\n\n const pendingSkillInjections = new Map<string, ParsedSkill[]>()\n\n const queueSkillsForInjection = (\n sessionID: string,\n skillNames: string[],\n triggerType: SkillUsageStats[\"triggerType\"],\n state: SessionState\n ) => {\n const newSkillNames = skillNames.filter((name) => !state.loadedSkills.has(name))\n if (newSkillNames.length === 0) return\n\n const result = loadSkillsWithBudget(\n newSkillNames,\n state.totalTokensUsed,\n triggerType,\n sessionID\n )\n\n if (result.skills.length > 0) {\n for (const skill of result.skills) {\n state.loadedSkills.add(skill.name)\n }\n state.totalTokensUsed += result.tokensUsed\n\n const existing = pendingSkillInjections.get(sessionID) ?? []\n pendingSkillInjections.set(sessionID, [...existing, ...result.skills])\n\n log(\"debug\", `Queued ${triggerType} skills for injection`, {\n sessionID,\n skills: result.skills.map((s) => s.name),\n tokens: result.tokensUsed,\n })\n }\n }\n\n const useSystemPromptInjection = config.injectionMethod === \"systemPrompt\"\n\n return {\n \"experimental.chat.system.transform\": useSystemPromptInjection\n ? async (\n input: { sessionID?: string; model: Model },\n output: { system: string[] }\n ): Promise<void> => {\n if (!input.sessionID) return\n\n const state = getSessionState(input.sessionID)\n const skillsToInject: ParsedSkill[] = []\n\n if (initialSkills.length > 0) {\n skillsToInject.push(...initialSkills)\n }\n\n for (const name of state.loadedSkills) {\n const skill = skillCache.get(name)\n if (skill && !skillsToInject.find((s) => s.name === name)) {\n skillsToInject.push(skill)\n }\n }\n\n const pending = pendingSkillInjections.get(input.sessionID)\n if (pending && pending.length > 0) {\n for (const skill of pending) {\n if (!skillsToInject.find((s) => s.name === skill.name)) {\n skillsToInject.push(skill)\n }\n }\n pendingSkillInjections.delete(input.sessionID)\n }\n\n if (skillsToInject.length > 0) {\n const formatted = formatSkillsForInjection(skillsToInject, {\n useSummaries: config.useSummaries,\n skillSettings: config.skillSettings,\n })\n output.system.push(formatted)\n\n if (!state.initialSkillsInjected && initialSkills.length > 0) {\n state.initialSkillsInjected = true\n log(\"info\", \"Injected skills into system prompt\", {\n sessionID: input.sessionID,\n skills: skillsToInject.map((s) => s.name),\n })\n }\n }\n }\n : undefined,\n\n \"chat.message\": async (\n input: {\n sessionID: string\n agent?: string\n model?: { providerID: string; modelID: string }\n messageID?: string\n variant?: string\n },\n output: { message: UserMessage; parts: Part[] }\n ): Promise<void> => {\n if (!input.sessionID) return\n\n const state = getSessionState(input.sessionID)\n const firstTextPart = output.parts.find((p) => p.type === \"text\")\n if (!firstTextPart || !(\"text\" in firstTextPart)) return\n\n const messageText = firstTextPart.text\n\n if (input.agent && config.agentSkills?.[input.agent]) {\n queueSkillsForInjection(\n input.sessionID,\n config.agentSkills[input.agent]!,\n \"agent\",\n state\n )\n }\n\n if (config.contentTriggers) {\n for (const [keyword, skillNames] of Object.entries(\n config.contentTriggers\n )) {\n if (textContainsKeyword(messageText, [keyword])) {\n queueSkillsForInjection(\n input.sessionID,\n skillNames,\n \"content\",\n state\n )\n }\n }\n }\n\n if (!useSystemPromptInjection) {\n const contentToInject: string[] = []\n\n if (!state.initialSkillsInjected && initialFormattedContent) {\n contentToInject.push(initialFormattedContent)\n state.initialSkillsInjected = true\n log(\"info\", \"Injected initial preloaded skills\", {\n sessionID: input.sessionID,\n skills: initialSkills.map((s) => s.name),\n })\n }\n\n const pending = pendingSkillInjections.get(input.sessionID)\n if (pending && pending.length > 0) {\n const formatted = formatSkillsForInjection(pending, {\n useSummaries: config.useSummaries,\n skillSettings: config.skillSettings,\n })\n if (formatted) {\n contentToInject.push(formatted)\n log(\"info\", \"Injected triggered skills\", {\n sessionID: input.sessionID,\n skills: pending.map((s) => s.name),\n })\n }\n pendingSkillInjections.delete(input.sessionID)\n }\n\n if (contentToInject.length > 0) {\n firstTextPart.text = `${contentToInject.join(\"\\n\\n\")}\\n\\n---\\n\\n${firstTextPart.text}`\n }\n }\n },\n\n \"tool.execute.after\": async (\n input: {\n tool: string\n sessionID: string\n callID: string\n },\n _output: {\n title: string\n output: string\n metadata: unknown\n }\n ): Promise<void> => {\n if (!FILE_TOOLS.includes(input.tool)) return\n if (!input.sessionID) return\n\n const state = getSessionState(input.sessionID)\n\n const toolArgs = (_output.metadata as { args?: Record<string, unknown> })\n ?.args\n if (!toolArgs) return\n\n const filePath = getFilePathFromArgs(toolArgs)\n if (!filePath) return\n\n const ext = extname(filePath)\n if (ext && config.fileTypeSkills) {\n const extSkills = getSkillsForExtension(ext, config.fileTypeSkills)\n if (extSkills.length > 0) {\n queueSkillsForInjection(input.sessionID, extSkills, \"fileType\", state)\n }\n }\n\n if (config.pathPatterns) {\n const pathSkills = getSkillsForPath(filePath, config.pathPatterns)\n if (pathSkills.length > 0) {\n queueSkillsForInjection(input.sessionID, pathSkills, \"path\", state)\n }\n }\n },\n\n \"experimental.session.compacting\": async (\n input: { sessionID: string },\n output: { context: string[]; prompt?: string }\n ): Promise<void> => {\n if (!config.persistAfterCompaction) return\n\n const state = sessionStates.get(input.sessionID)\n if (!state || state.loadedSkills.size === 0) return\n\n const allLoadedSkills: ParsedSkill[] = []\n for (const name of state.loadedSkills) {\n const skill = skillCache.get(name)\n if (skill) allLoadedSkills.push(skill)\n }\n\n if (allLoadedSkills.length === 0) return\n\n const formatted = formatSkillsForInjection(\n allLoadedSkills,\n { useSummaries: config.useSummaries, skillSettings: config.skillSettings }\n )\n output.context.push(\n `## Preloaded Skills\\n\\nThe following skills were loaded during this session and should persist:\\n\\n${formatted}`\n )\n\n state.initialSkillsInjected = false\n\n log(\"info\", \"Added all loaded skills to compaction context\", {\n sessionID: input.sessionID,\n skillCount: allLoadedSkills.length,\n })\n\n saveAnalytics()\n },\n\n event: async ({ event }: { event: Event }): Promise<void> => {\n if (\n event.type === \"session.deleted\" &&\n \"sessionID\" in event.properties\n ) {\n const sessionID = event.properties.sessionID as string\n sessionStates.delete(sessionID)\n pendingSkillInjections.delete(sessionID)\n analyticsData.delete(sessionID)\n log(\"debug\", \"Cleaned up session state\", { sessionID })\n saveAnalytics()\n }\n },\n }\n}\n\nexport default PreloadSkillsPlugin\n"]}
|