opencodekit 0.5.0 → 0.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (79) hide show
  1. package/dist/index.js +1 -1
  2. package/dist/template/.opencode/AGENTS.md +12 -1
  3. package/dist/template/.opencode/command/skill-create.md +3 -3
  4. package/dist/template/.opencode/command/skill-optimize.md +1 -1
  5. package/dist/template/.opencode/command/summarize.md +71 -0
  6. package/dist/template/.opencode/opencode.json +23 -5
  7. package/dist/template/.opencode/package.json +1 -1
  8. package/dist/template/.opencode/plugin/sessions.ts +26 -1
  9. package/dist/template/.opencode/plugin/skill.ts +275 -0
  10. package/dist/template/.opencode/{skills → skill}/accessibility-audit/SKILL.md +5 -0
  11. package/dist/template/.opencode/{skills → skill}/brainstorming/SKILL.md +2 -2
  12. package/dist/template/.opencode/{skills → skill}/design-system-audit/SKILL.md +5 -0
  13. package/dist/template/.opencode/{skills → skill}/executing-plans/SKILL.md +13 -2
  14. package/dist/template/.opencode/{skills → skill}/frontend-aesthetics/SKILL.md +5 -0
  15. package/dist/template/.opencode/{skills → skill}/mockup-to-code/SKILL.md +5 -0
  16. package/dist/template/.opencode/{skills → skill}/requesting-code-review/SKILL.md +16 -6
  17. package/dist/template/.opencode/{skills → skill}/subagent-driven-development/SKILL.md +38 -17
  18. package/dist/template/.opencode/{skills → skill}/systematic-debugging/SKILL.md +28 -18
  19. package/dist/template/.opencode/{skills → skill}/testing-skills-with-subagents/SKILL.md +1 -1
  20. package/dist/template/.opencode/{skills → skill}/ui-ux-research/SKILL.md +5 -0
  21. package/dist/template/.opencode/{skills → skill}/visual-analysis/SKILL.md +5 -0
  22. package/dist/template/.opencode/{skills → skill}/writing-plans/SKILL.md +3 -3
  23. package/dist/template/.opencode/{skills → skill}/writing-skills/SKILL.md +101 -41
  24. package/package.json +1 -1
  25. package/dist/template/.opencode/plugin/superpowers.ts +0 -271
  26. package/dist/template/.opencode/superpowers/.claude/settings.local.json +0 -141
  27. package/dist/template/.opencode/superpowers/.claude-plugin/marketplace.json +0 -20
  28. package/dist/template/.opencode/superpowers/.claude-plugin/plugin.json +0 -13
  29. package/dist/template/.opencode/superpowers/.codex/INSTALL.md +0 -35
  30. package/dist/template/.opencode/superpowers/.codex/superpowers-bootstrap.md +0 -33
  31. package/dist/template/.opencode/superpowers/.codex/superpowers-codex +0 -267
  32. package/dist/template/.opencode/superpowers/.github/FUNDING.yml +0 -3
  33. package/dist/template/.opencode/superpowers/.opencode/INSTALL.md +0 -135
  34. package/dist/template/.opencode/superpowers/.opencode/plugin/superpowers.js +0 -215
  35. package/dist/template/.opencode/superpowers/LICENSE +0 -21
  36. package/dist/template/.opencode/superpowers/README.md +0 -165
  37. package/dist/template/.opencode/superpowers/RELEASE-NOTES.md +0 -493
  38. package/dist/template/.opencode/superpowers/agents/code-reviewer.md +0 -48
  39. package/dist/template/.opencode/superpowers/commands/brainstorm.md +0 -5
  40. package/dist/template/.opencode/superpowers/commands/execute-plan.md +0 -5
  41. package/dist/template/.opencode/superpowers/commands/write-plan.md +0 -5
  42. package/dist/template/.opencode/superpowers/docs/README.codex.md +0 -153
  43. package/dist/template/.opencode/superpowers/docs/README.opencode.md +0 -234
  44. package/dist/template/.opencode/superpowers/docs/plans/2025-11-22-opencode-support-design.md +0 -294
  45. package/dist/template/.opencode/superpowers/docs/plans/2025-11-22-opencode-support-implementation.md +0 -1095
  46. package/dist/template/.opencode/superpowers/hooks/hooks.json +0 -15
  47. package/dist/template/.opencode/superpowers/hooks/session-start.sh +0 -34
  48. package/dist/template/.opencode/superpowers/lib/skills-core.js +0 -208
  49. package/dist/template/.opencode/superpowers/tests/opencode/run-tests.sh +0 -165
  50. package/dist/template/.opencode/superpowers/tests/opencode/setup.sh +0 -73
  51. package/dist/template/.opencode/superpowers/tests/opencode/test-plugin-loading.sh +0 -81
  52. package/dist/template/.opencode/superpowers/tests/opencode/test-priority.sh +0 -198
  53. package/dist/template/.opencode/superpowers/tests/opencode/test-skills-core.sh +0 -440
  54. package/dist/template/.opencode/superpowers/tests/opencode/test-tools.sh +0 -104
  55. /package/dist/template/.opencode/{skills → skill}/condition-based-waiting/SKILL.md +0 -0
  56. /package/dist/template/.opencode/{skills → skill}/condition-based-waiting/example.ts +0 -0
  57. /package/dist/template/.opencode/{skills → skill}/defense-in-depth/SKILL.md +0 -0
  58. /package/dist/template/.opencode/{skills → skill}/dispatching-parallel-agents/SKILL.md +0 -0
  59. /package/dist/template/.opencode/{skills → skill}/finishing-a-development-branch/SKILL.md +0 -0
  60. /package/dist/template/.opencode/{skills → skill}/gemini-large-context/SKILL.md +0 -0
  61. /package/dist/template/.opencode/{skills → skill}/receiving-code-review/SKILL.md +0 -0
  62. /package/dist/template/.opencode/{skills/requesting-code-review/code-reviewer.md → skill/requesting-code-review/review.md} +0 -0
  63. /package/dist/template/.opencode/{skills → skill}/root-cause-tracing/SKILL.md +0 -0
  64. /package/dist/template/.opencode/{skills → skill}/root-cause-tracing/find-polluter.sh +0 -0
  65. /package/dist/template/.opencode/{skills → skill}/sharing-skills/SKILL.md +0 -0
  66. /package/dist/template/.opencode/{skills → skill}/systematic-debugging/CREATION-LOG.md +0 -0
  67. /package/dist/template/.opencode/{skills → skill}/systematic-debugging/test-academic.md +0 -0
  68. /package/dist/template/.opencode/{skills → skill}/systematic-debugging/test-pressure-1.md +0 -0
  69. /package/dist/template/.opencode/{skills → skill}/systematic-debugging/test-pressure-2.md +0 -0
  70. /package/dist/template/.opencode/{skills → skill}/systematic-debugging/test-pressure-3.md +0 -0
  71. /package/dist/template/.opencode/{skills → skill}/test-driven-development/SKILL.md +0 -0
  72. /package/dist/template/.opencode/{skills → skill}/testing-anti-patterns/SKILL.md +0 -0
  73. /package/dist/template/.opencode/{skills → skill}/testing-skills-with-subagents/examples/CLAUDE_MD_TESTING.md +0 -0
  74. /package/dist/template/.opencode/{skills → skill}/using-git-worktrees/SKILL.md +0 -0
  75. /package/dist/template/.opencode/{skills → skill}/using-superpowers/SKILL.md +0 -0
  76. /package/dist/template/.opencode/{skills → skill}/verification-before-completion/SKILL.md +0 -0
  77. /package/dist/template/.opencode/{skills → skill}/writing-skills/anthropic-best-practices.md +0 -0
  78. /package/dist/template/.opencode/{skills → skill}/writing-skills/graphviz-conventions.dot +0 -0
  79. /package/dist/template/.opencode/{skills → skill}/writing-skills/persuasion-principles.md +0 -0
@@ -1,267 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- const fs = require('fs');
4
- const path = require('path');
5
- const os = require('os');
6
- const skillsCore = require('../lib/skills-core');
7
-
8
- // Paths
9
- const homeDir = os.homedir();
10
- const superpowersSkillsDir = path.join(homeDir, '.codex', 'superpowers', 'skills');
11
- const personalSkillsDir = path.join(homeDir, '.codex', 'skills');
12
- const bootstrapFile = path.join(homeDir, '.codex', 'superpowers', '.codex', 'superpowers-bootstrap.md');
13
- const superpowersRepoDir = path.join(homeDir, '.codex', 'superpowers');
14
-
15
- // Utility functions
16
- function printSkill(skillPath, sourceType) {
17
- const skillFile = path.join(skillPath, 'SKILL.md');
18
- const relPath = sourceType === 'personal'
19
- ? path.relative(personalSkillsDir, skillPath)
20
- : path.relative(superpowersSkillsDir, skillPath);
21
-
22
- // Print skill name with namespace
23
- if (sourceType === 'personal') {
24
- console.log(relPath.replace(/\\/g, '/')); // Personal skills are not namespaced
25
- } else {
26
- console.log(`superpowers:${relPath.replace(/\\/g, '/')}`); // Superpowers skills get superpowers namespace
27
- }
28
-
29
- // Extract and print metadata
30
- const { name, description } = skillsCore.extractFrontmatter(skillFile);
31
-
32
- if (description) console.log(` ${description}`);
33
- console.log('');
34
- }
35
-
36
- // Commands
37
- function runFindSkills() {
38
- console.log('Available skills:');
39
- console.log('==================');
40
- console.log('');
41
-
42
- const foundSkills = new Set();
43
-
44
- // Find personal skills first (these take precedence)
45
- const personalSkills = skillsCore.findSkillsInDir(personalSkillsDir, 'personal', 2);
46
- for (const skill of personalSkills) {
47
- const relPath = path.relative(personalSkillsDir, skill.path);
48
- foundSkills.add(relPath);
49
- printSkill(skill.path, 'personal');
50
- }
51
-
52
- // Find superpowers skills (only if not already found in personal)
53
- const superpowersSkills = skillsCore.findSkillsInDir(superpowersSkillsDir, 'superpowers', 1);
54
- for (const skill of superpowersSkills) {
55
- const relPath = path.relative(superpowersSkillsDir, skill.path);
56
- if (!foundSkills.has(relPath)) {
57
- printSkill(skill.path, 'superpowers');
58
- }
59
- }
60
-
61
- console.log('Usage:');
62
- console.log(' superpowers-codex use-skill <skill-name> # Load a specific skill');
63
- console.log('');
64
- console.log('Skill naming:');
65
- console.log(' Superpowers skills: superpowers:skill-name (from ~/.codex/superpowers/skills/)');
66
- console.log(' Personal skills: skill-name (from ~/.codex/skills/)');
67
- console.log(' Personal skills override superpowers skills when names match.');
68
- console.log('');
69
- console.log('Note: All skills are disclosed at session start via bootstrap.');
70
- }
71
-
72
- function runBootstrap() {
73
- console.log('# Superpowers Bootstrap for Codex');
74
- console.log('# ================================');
75
- console.log('');
76
-
77
- // Check for updates (with timeout protection)
78
- if (skillsCore.checkForUpdates(superpowersRepoDir)) {
79
- console.log('## Update Available');
80
- console.log('');
81
- console.log('⚠️ Your superpowers installation is behind the latest version.');
82
- console.log('To update, run: `cd ~/.codex/superpowers && git pull`');
83
- console.log('');
84
- console.log('---');
85
- console.log('');
86
- }
87
-
88
- // Show the bootstrap instructions
89
- if (fs.existsSync(bootstrapFile)) {
90
- console.log('## Bootstrap Instructions:');
91
- console.log('');
92
- try {
93
- const content = fs.readFileSync(bootstrapFile, 'utf8');
94
- console.log(content);
95
- } catch (error) {
96
- console.log(`Error reading bootstrap file: ${error.message}`);
97
- }
98
- console.log('');
99
- console.log('---');
100
- console.log('');
101
- }
102
-
103
- // Run find-skills to show available skills
104
- console.log('## Available Skills:');
105
- console.log('');
106
- runFindSkills();
107
-
108
- console.log('');
109
- console.log('---');
110
- console.log('');
111
-
112
- // Load the using-superpowers skill automatically
113
- console.log('## Auto-loading superpowers:using-superpowers skill:');
114
- console.log('');
115
- runUseSkill('superpowers:using-superpowers');
116
-
117
- console.log('');
118
- console.log('---');
119
- console.log('');
120
- console.log('# Bootstrap Complete!');
121
- console.log('# You now have access to all superpowers skills.');
122
- console.log('# Use "superpowers-codex use-skill <skill>" to load and apply skills.');
123
- console.log('# Remember: If a skill applies to your task, you MUST use it!');
124
- }
125
-
126
- function runUseSkill(skillName) {
127
- if (!skillName) {
128
- console.log('Usage: superpowers-codex use-skill <skill-name>');
129
- console.log('Examples:');
130
- console.log(' superpowers-codex use-skill superpowers:brainstorming # Load superpowers skill');
131
- console.log(' superpowers-codex use-skill brainstorming # Load personal skill (or superpowers if not found)');
132
- console.log(' superpowers-codex use-skill my-custom-skill # Load personal skill');
133
- return;
134
- }
135
-
136
- // Handle namespaced skill names
137
- let actualSkillPath;
138
- let forceSuperpowers = false;
139
-
140
- if (skillName.startsWith('superpowers:')) {
141
- // Remove the superpowers: namespace prefix
142
- actualSkillPath = skillName.substring('superpowers:'.length);
143
- forceSuperpowers = true;
144
- } else {
145
- actualSkillPath = skillName;
146
- }
147
-
148
- // Remove "skills/" prefix if present
149
- if (actualSkillPath.startsWith('skills/')) {
150
- actualSkillPath = actualSkillPath.substring('skills/'.length);
151
- }
152
-
153
- // Function to find skill file
154
- function findSkillFile(searchPath) {
155
- // Check for exact match with SKILL.md
156
- const skillMdPath = path.join(searchPath, 'SKILL.md');
157
- if (fs.existsSync(skillMdPath)) {
158
- return skillMdPath;
159
- }
160
-
161
- // Check for direct SKILL.md file
162
- if (searchPath.endsWith('SKILL.md') && fs.existsSync(searchPath)) {
163
- return searchPath;
164
- }
165
-
166
- return null;
167
- }
168
-
169
- let skillFile = null;
170
-
171
- // If superpowers: namespace was used, only check superpowers skills
172
- if (forceSuperpowers) {
173
- if (fs.existsSync(superpowersSkillsDir)) {
174
- const superpowersPath = path.join(superpowersSkillsDir, actualSkillPath);
175
- skillFile = findSkillFile(superpowersPath);
176
- }
177
- } else {
178
- // First check personal skills directory (takes precedence)
179
- if (fs.existsSync(personalSkillsDir)) {
180
- const personalPath = path.join(personalSkillsDir, actualSkillPath);
181
- skillFile = findSkillFile(personalPath);
182
- if (skillFile) {
183
- console.log(`# Loading personal skill: ${actualSkillPath}`);
184
- console.log(`# Source: ${skillFile}`);
185
- console.log('');
186
- }
187
- }
188
-
189
- // If not found in personal, check superpowers skills
190
- if (!skillFile && fs.existsSync(superpowersSkillsDir)) {
191
- const superpowersPath = path.join(superpowersSkillsDir, actualSkillPath);
192
- skillFile = findSkillFile(superpowersPath);
193
- if (skillFile) {
194
- console.log(`# Loading superpowers skill: superpowers:${actualSkillPath}`);
195
- console.log(`# Source: ${skillFile}`);
196
- console.log('');
197
- }
198
- }
199
- }
200
-
201
- // If still not found, error
202
- if (!skillFile) {
203
- console.log(`Error: Skill not found: ${actualSkillPath}`);
204
- console.log('');
205
- console.log('Available skills:');
206
- runFindSkills();
207
- return;
208
- }
209
-
210
- // Extract frontmatter and content using shared core functions
211
- let content, frontmatter;
212
- try {
213
- const fullContent = fs.readFileSync(skillFile, 'utf8');
214
- const { name, description } = skillsCore.extractFrontmatter(skillFile);
215
- content = skillsCore.stripFrontmatter(fullContent);
216
- frontmatter = { name, description };
217
- } catch (error) {
218
- console.log(`Error reading skill file: ${error.message}`);
219
- return;
220
- }
221
-
222
- // Display skill header with clean info
223
- const displayName = forceSuperpowers ? `superpowers:${actualSkillPath}` :
224
- (skillFile.includes(personalSkillsDir) ? actualSkillPath : `superpowers:${actualSkillPath}`);
225
-
226
- const skillDirectory = path.dirname(skillFile);
227
-
228
- console.log(`# ${frontmatter.name || displayName}`);
229
- if (frontmatter.description) {
230
- console.log(`# ${frontmatter.description}`);
231
- }
232
- console.log(`# Supporting tools and docs are in ${skillDirectory}`);
233
- console.log('# ============================================');
234
- console.log('');
235
-
236
- // Display the skill content (without frontmatter)
237
- console.log(content);
238
-
239
- }
240
-
241
- // Main CLI
242
- const command = process.argv[2];
243
- const arg = process.argv[3];
244
-
245
- switch (command) {
246
- case 'bootstrap':
247
- runBootstrap();
248
- break;
249
- case 'use-skill':
250
- runUseSkill(arg);
251
- break;
252
- case 'find-skills':
253
- runFindSkills();
254
- break;
255
- default:
256
- console.log('Superpowers for Codex');
257
- console.log('Usage:');
258
- console.log(' superpowers-codex bootstrap # Run complete bootstrap with all skills');
259
- console.log(' superpowers-codex use-skill <skill-name> # Load a specific skill');
260
- console.log(' superpowers-codex find-skills # List all available skills');
261
- console.log('');
262
- console.log('Examples:');
263
- console.log(' superpowers-codex bootstrap');
264
- console.log(' superpowers-codex use-skill superpowers:brainstorming');
265
- console.log(' superpowers-codex use-skill my-custom-skill');
266
- break;
267
- }
@@ -1,3 +0,0 @@
1
- # These are supported funding model platforms
2
-
3
- github: [obra]
@@ -1,135 +0,0 @@
1
- # Installing Superpowers for OpenCode
2
-
3
- ## Prerequisites
4
-
5
- - [OpenCode.ai](https://opencode.ai) installed
6
- - Node.js installed
7
- - Git installed
8
-
9
- ## Installation Steps
10
-
11
- ### 1. Install Superpowers
12
-
13
- ```bash
14
- mkdir -p ~/.config/opencode/superpowers
15
- git clone https://github.com/obra/superpowers.git ~/.config/opencode/superpowers
16
- ```
17
-
18
- ### 2. Register the Plugin
19
-
20
- Create a symlink so OpenCode discovers the plugin:
21
-
22
- ```bash
23
- mkdir -p ~/.config/opencode/plugin
24
- ln -sf ~/.config/opencode/superpowers/.opencode/plugin/superpowers.js ~/.config/opencode/plugin/superpowers.js
25
- ```
26
-
27
- ### 3. Restart OpenCode
28
-
29
- Restart OpenCode. The plugin will automatically inject superpowers context via the chat.message hook.
30
-
31
- You should see superpowers is active when you ask "do you have superpowers?"
32
-
33
- ## Usage
34
-
35
- ### Finding Skills
36
-
37
- Use the `find_skills` tool to list all available skills:
38
-
39
- ```
40
- use find_skills tool
41
- ```
42
-
43
- ### Loading a Skill
44
-
45
- Use the `use_skill` tool to load a specific skill:
46
-
47
- ```
48
- use use_skill tool with skill_name: "superpowers:brainstorming"
49
- ```
50
-
51
- ### Personal Skills
52
-
53
- Create your own skills in `~/.config/opencode/skills/`:
54
-
55
- ```bash
56
- mkdir -p ~/.config/opencode/skills/my-skill
57
- ```
58
-
59
- Create `~/.config/opencode/skills/my-skill/SKILL.md`:
60
-
61
- ```markdown
62
- ---
63
- name: my-skill
64
- description: Use when [condition] - [what it does]
65
- ---
66
-
67
- # My Skill
68
-
69
- [Your skill content here]
70
- ```
71
-
72
- Personal skills override superpowers skills with the same name.
73
-
74
- ### Project Skills
75
-
76
- Create project-specific skills in your OpenCode project:
77
-
78
- ```bash
79
- # In your OpenCode project
80
- mkdir -p .opencode/skills/my-project-skill
81
- ```
82
-
83
- Create `.opencode/skills/my-project-skill/SKILL.md`:
84
-
85
- ```markdown
86
- ---
87
- name: my-project-skill
88
- description: Use when [condition] - [what it does]
89
- ---
90
-
91
- # My Project Skill
92
-
93
- [Your skill content here]
94
- ```
95
-
96
- **Skill Priority:** Project skills override personal skills, which override superpowers skills.
97
-
98
- **Skill Naming:**
99
- - `project:skill-name` - Force project skill lookup
100
- - `skill-name` - Searches project → personal → superpowers
101
- - `superpowers:skill-name` - Force superpowers skill lookup
102
-
103
- ## Updating
104
-
105
- ```bash
106
- cd ~/.config/opencode/superpowers
107
- git pull
108
- ```
109
-
110
- ## Troubleshooting
111
-
112
- ### Plugin not loading
113
-
114
- 1. Check plugin file exists: `ls ~/.config/opencode/superpowers/.opencode/plugin/superpowers.js`
115
- 2. Check OpenCode logs for errors
116
- 3. Verify Node.js is installed: `node --version`
117
-
118
- ### Skills not found
119
-
120
- 1. Verify skills directory exists: `ls ~/.config/opencode/superpowers/skills`
121
- 2. Use `find_skills` tool to see what's discovered
122
- 3. Check file structure: each skill should have a `SKILL.md` file
123
-
124
- ### Tool mapping issues
125
-
126
- When a skill references a Claude Code tool you don't have:
127
- - `TodoWrite` → use `update_plan`
128
- - `Task` with subagents → use `@mention` syntax to invoke OpenCode subagents
129
- - `Skill` → use `use_skill` tool
130
- - File operations → use your native tools
131
-
132
- ## Getting Help
133
-
134
- - Report issues: https://github.com/obra/superpowers/issues
135
- - Documentation: https://github.com/obra/superpowers
@@ -1,215 +0,0 @@
1
- /**
2
- * Superpowers plugin for OpenCode.ai
3
- *
4
- * Provides custom tools for loading and discovering skills,
5
- * with prompt generation for agent configuration.
6
- */
7
-
8
- import path from 'path';
9
- import fs from 'fs';
10
- import os from 'os';
11
- import { fileURLToPath } from 'url';
12
- import { tool } from '@opencode-ai/plugin/tool';
13
- import * as skillsCore from '../../lib/skills-core.js';
14
-
15
- const __dirname = path.dirname(fileURLToPath(import.meta.url));
16
-
17
- export const SuperpowersPlugin = async ({ client, directory }) => {
18
- const homeDir = os.homedir();
19
- const projectSkillsDir = path.join(directory, '.opencode/skills');
20
- // Derive superpowers skills dir from plugin location (works for both symlinked and local installs)
21
- const superpowersSkillsDir = path.resolve(__dirname, '../../skills');
22
- const personalSkillsDir = path.join(homeDir, '.config/opencode/skills');
23
-
24
- // Helper to generate bootstrap content
25
- const getBootstrapContent = (compact = false) => {
26
- const usingSuperpowersPath = skillsCore.resolveSkillPath('using-superpowers', superpowersSkillsDir, personalSkillsDir);
27
- if (!usingSuperpowersPath) return null;
28
-
29
- const fullContent = fs.readFileSync(usingSuperpowersPath.skillFile, 'utf8');
30
- const content = skillsCore.stripFrontmatter(fullContent);
31
-
32
- const toolMapping = compact
33
- ? `**Tool Mapping:** TodoWrite->update_plan, Task->@mention, Skill->use_skill
34
-
35
- **Skills naming (priority order):** project: > personal > superpowers:`
36
- : `**Tool Mapping for OpenCode:**
37
- When skills reference tools you don't have, substitute OpenCode equivalents:
38
- - \`TodoWrite\` → \`update_plan\`
39
- - \`Task\` tool with subagents → Use OpenCode's subagent system (@mention)
40
- - \`Skill\` tool → \`use_skill\` custom tool
41
- - \`Read\`, \`Write\`, \`Edit\`, \`Bash\` → Your native tools
42
-
43
- **Skills naming (priority order):**
44
- - Project skills: \`project:skill-name\` (in .opencode/skills/)
45
- - Personal skills: \`skill-name\` (in ~/.config/opencode/skills/)
46
- - Superpowers skills: \`superpowers:skill-name\`
47
- - Project skills override personal, which override superpowers when names match`;
48
-
49
- return `<EXTREMELY_IMPORTANT>
50
- You have superpowers.
51
-
52
- **IMPORTANT: The using-superpowers skill content is included below. It is ALREADY LOADED - you are currently following it. Do NOT use the use_skill tool to load "using-superpowers" - that would be redundant. Use use_skill only for OTHER skills.**
53
-
54
- ${content}
55
-
56
- ${toolMapping}
57
- </EXTREMELY_IMPORTANT>`;
58
- };
59
-
60
- // Helper to inject bootstrap via session.prompt
61
- const injectBootstrap = async (sessionID, compact = false) => {
62
- const bootstrapContent = getBootstrapContent(compact);
63
- if (!bootstrapContent) return false;
64
-
65
- try {
66
- await client.session.prompt({
67
- path: { id: sessionID },
68
- body: {
69
- noReply: true,
70
- parts: [{ type: "text", text: bootstrapContent }]
71
- }
72
- });
73
- return true;
74
- } catch (err) {
75
- return false;
76
- }
77
- };
78
-
79
- return {
80
- tool: {
81
- use_skill: tool({
82
- description: 'Load and read a specific skill to guide your work. Skills contain proven workflows, mandatory processes, and expert techniques.',
83
- args: {
84
- skill_name: tool.schema.string().describe('Name of the skill to load (e.g., "superpowers:brainstorming", "my-custom-skill", or "project:my-skill")')
85
- },
86
- execute: async (args, context) => {
87
- const { skill_name } = args;
88
-
89
- // Resolve with priority: project > personal > superpowers
90
- // Check for project: prefix first
91
- const forceProject = skill_name.startsWith('project:');
92
- const actualSkillName = forceProject ? skill_name.replace(/^project:/, '') : skill_name;
93
-
94
- let resolved = null;
95
-
96
- // Try project skills first (if project: prefix or no prefix)
97
- if (forceProject || !skill_name.startsWith('superpowers:')) {
98
- const projectPath = path.join(projectSkillsDir, actualSkillName);
99
- const projectSkillFile = path.join(projectPath, 'SKILL.md');
100
- if (fs.existsSync(projectSkillFile)) {
101
- resolved = {
102
- skillFile: projectSkillFile,
103
- sourceType: 'project',
104
- skillPath: actualSkillName
105
- };
106
- }
107
- }
108
-
109
- // Fall back to personal/superpowers resolution
110
- if (!resolved && !forceProject) {
111
- resolved = skillsCore.resolveSkillPath(skill_name, superpowersSkillsDir, personalSkillsDir);
112
- }
113
-
114
- if (!resolved) {
115
- return `Error: Skill "${skill_name}" not found.\n\nRun find_skills to see available skills.`;
116
- }
117
-
118
- const fullContent = fs.readFileSync(resolved.skillFile, 'utf8');
119
- const { name, description } = skillsCore.extractFrontmatter(resolved.skillFile);
120
- const content = skillsCore.stripFrontmatter(fullContent);
121
- const skillDirectory = path.dirname(resolved.skillFile);
122
-
123
- const skillHeader = `# ${name || skill_name}
124
- # ${description || ''}
125
- # Supporting tools and docs are in ${skillDirectory}
126
- # ============================================`;
127
-
128
- // Insert as user message with noReply for persistence across compaction
129
- try {
130
- await client.session.prompt({
131
- path: { id: context.sessionID },
132
- body: {
133
- noReply: true,
134
- parts: [
135
- { type: "text", text: `Loading skill: ${name || skill_name}` },
136
- { type: "text", text: `${skillHeader}\n\n${content}` }
137
- ]
138
- }
139
- });
140
- } catch (err) {
141
- // Fallback: return content directly if message insertion fails
142
- return `${skillHeader}\n\n${content}`;
143
- }
144
-
145
- return `Launching skill: ${name || skill_name}`;
146
- }
147
- }),
148
- find_skills: tool({
149
- description: 'List all available skills in the project, personal, and superpowers skill libraries.',
150
- args: {},
151
- execute: async (args, context) => {
152
- const projectSkills = skillsCore.findSkillsInDir(projectSkillsDir, 'project', 3);
153
- const personalSkills = skillsCore.findSkillsInDir(personalSkillsDir, 'personal', 3);
154
- const superpowersSkills = skillsCore.findSkillsInDir(superpowersSkillsDir, 'superpowers', 3);
155
-
156
- // Priority: project > personal > superpowers
157
- const allSkills = [...projectSkills, ...personalSkills, ...superpowersSkills];
158
-
159
- if (allSkills.length === 0) {
160
- return 'No skills found. Install superpowers skills to ~/.config/opencode/superpowers/skills/ or add project skills to .opencode/skills/';
161
- }
162
-
163
- let output = 'Available skills:\n\n';
164
-
165
- for (const skill of allSkills) {
166
- let namespace;
167
- switch (skill.sourceType) {
168
- case 'project':
169
- namespace = 'project:';
170
- break;
171
- case 'personal':
172
- namespace = '';
173
- break;
174
- default:
175
- namespace = 'superpowers:';
176
- }
177
- const skillName = skill.name || path.basename(skill.path);
178
-
179
- output += `${namespace}${skillName}\n`;
180
- if (skill.description) {
181
- output += ` ${skill.description}\n`;
182
- }
183
- output += ` Directory: ${skill.path}\n\n`;
184
- }
185
-
186
- return output;
187
- }
188
- })
189
- },
190
- event: async ({ event }) => {
191
- // Extract sessionID from various event structures
192
- const getSessionID = () => {
193
- return event.properties?.info?.id ||
194
- event.properties?.sessionID ||
195
- event.session?.id;
196
- };
197
-
198
- // Inject bootstrap at session creation (before first user message)
199
- if (event.type === 'session.created') {
200
- const sessionID = getSessionID();
201
- if (sessionID) {
202
- await injectBootstrap(sessionID, false);
203
- }
204
- }
205
-
206
- // Re-inject bootstrap after context compaction (compact version to save tokens)
207
- if (event.type === 'session.compacted') {
208
- const sessionID = getSessionID();
209
- if (sessionID) {
210
- await injectBootstrap(sessionID, true);
211
- }
212
- }
213
- }
214
- };
215
- };
@@ -1,21 +0,0 @@
1
- MIT License
2
-
3
- Copyright (c) 2025 Jesse Vincent
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.