opencode-sa-assistant 0.2.3 → 0.2.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -28,10 +28,14 @@ This plugin activates when you use the `wadd` keyword in your messages, transfor
28
28
 
29
29
  ## Installation
30
30
 
31
- ```bash
32
- # From the repository root
33
- cd packages/opencode-sa-assistant
34
- bun install
31
+ Add the plugin to your `opencode.json`:
32
+
33
+ ```json
34
+ {
35
+ "plugin": [
36
+ "opencode-sa-assistant"
37
+ ]
38
+ }
35
39
  ```
36
40
 
37
41
  ## Usage
@@ -73,14 +77,14 @@ wadd bezos에게 고객 경험 관점에서 이 기능을 평가해달라고 해
73
77
 
74
78
  ## Skills
75
79
 
76
- The plugin includes 4 skill modules:
80
+ The plugin includes 4 skill modules that are automatically installed to `~/.config/opencode/skills/`:
77
81
 
78
82
  - **guru**: Guru consultation patterns and philosophies
79
83
  - **mcp**: AWS MCP tools reference (search_documentation, read_documentation)
80
84
  - **docx**: AWS Blog-style document generation guidelines
81
85
  - **pptx**: SA presentation templates
82
86
 
83
- Skills are automatically loaded when needed.
87
+ Skills are installed globally to ensure they are available before any plugin caching occurs. Use `/skill guru` or `/skill mcp` to load them.
84
88
 
85
89
  ## Testing
86
90
 
@@ -92,7 +96,7 @@ bun test
92
96
  bun test src/__tests__/integration.test.ts
93
97
  ```
94
98
 
95
- **Test Coverage**: 65 tests, 212 assertions, 100% pass rate
99
+ **Test Coverage**: 80 tests, 234 assertions, 100% pass rate
96
100
 
97
101
  ## Development
98
102
 
@@ -163,6 +167,23 @@ Contributions are welcome! Please ensure:
163
167
 
164
168
  ## Changelog
165
169
 
170
+ ### v0.2.5 (2026-02-05)
171
+
172
+ - Fix: Skills now installed to global location (`~/.config/opencode/skills/`)
173
+ - Resolves oh-my-opencode cache timing issue
174
+ - Skills are now available via `/skill` command immediately
175
+ - Test coverage: 80 tests, 234 assertions
176
+
177
+ ### v0.2.4 (2026-02-05)
178
+
179
+ - Added skill installation to `.opencode/skills/`
180
+ - Skills: guru, mcp, docx, pptx
181
+
182
+ ### v0.2.3 (2026-02-05)
183
+
184
+ - Aligned wadd hook with oh-my-opencode pattern
185
+ - Added `removeCodeBlocks()` for keyword detection
186
+
166
187
  ### v0.1.0 (2026-02-05)
167
188
 
168
189
  - Initial release
@@ -171,4 +192,3 @@ Contributions are welcome! Please ensure:
171
192
  - Guru_Mandate consultation system
172
193
  - Well-Architected Framework integration
173
194
  - AWS MCP tools support
174
- - 65 tests, 100% pass rate
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-sa-assistant",
3
- "version": "0.2.3",
3
+ "version": "0.2.5",
4
4
  "type": "module",
5
5
  "main": "src/index.ts",
6
6
  "description": "OpenCode plugin for AWS Solutions Architect assistant with multi-agent Guru system",
@@ -8,9 +8,10 @@
8
8
  import { SA_ORCHESTRATOR_PROMPT } from "../prompts/orchestrator";
9
9
  import { GURU_PROMPTS } from "../prompts/gurus";
10
10
  import { SPECIALIST_PROMPTS } from "../prompts/specialists";
11
- import { existsSync, mkdirSync, writeFileSync } from "fs";
12
- import { join } from "path";
11
+ import { existsSync, mkdirSync, writeFileSync, readFileSync } from "fs";
12
+ import { join, dirname } from "path";
13
13
  import { homedir } from "os";
14
+ import { fileURLToPath } from "url";
14
15
 
15
16
  /**
16
17
  * Agent definition with frontmatter metadata
@@ -164,3 +165,109 @@ export function uninstallSAAgents(): string[] {
164
165
 
165
166
  return removed;
166
167
  }
168
+
169
+ /**
170
+ * SA Skill names that will be installed
171
+ */
172
+ export const SA_SKILL_NAMES = ["docx", "pptx", "mcp", "guru"] as const;
173
+
174
+ /**
175
+ * Get the skills directory path for global installation
176
+ * Uses ~/.config/opencode/skills/ to ensure skills are available
177
+ * before any plugin loads (solving the oh-my-opencode cache timing issue)
178
+ */
179
+ function getSkillsDir(): string {
180
+ return join(homedir(), ".config", "opencode", "skills");
181
+ }
182
+
183
+ /**
184
+ * Get the source skills directory (where SKILL.md files are bundled)
185
+ */
186
+ function getSourceSkillsDir(): string {
187
+ // In ESM, use import.meta.url to find the module location
188
+ // Fallback to __dirname for CommonJS compatibility
189
+ try {
190
+ const currentFile = fileURLToPath(import.meta.url);
191
+ return join(dirname(currentFile), "..", "skills");
192
+ } catch {
193
+ // Fallback for environments where import.meta.url is not available
194
+ return join(__dirname, "..", "skills");
195
+ }
196
+ }
197
+
198
+ /**
199
+ * Install SA skills to ~/.config/opencode/skills/ (global location)
200
+ */
201
+ export function installSASkills(): { installed: string[]; skipped: string[]; errors: string[] } {
202
+ const skillsDir = getSkillsDir();
203
+ const sourceDir = getSourceSkillsDir();
204
+ const installed: string[] = [];
205
+ const skipped: string[] = [];
206
+ const errors: string[] = [];
207
+
208
+ for (const skillName of SA_SKILL_NAMES) {
209
+ const targetDir = join(skillsDir, skillName);
210
+ const targetPath = join(targetDir, "SKILL.md");
211
+ const sourcePath = join(sourceDir, skillName, "SKILL.md");
212
+
213
+ try {
214
+ // Check if target already exists
215
+ if (existsSync(targetPath)) {
216
+ skipped.push(skillName);
217
+ continue;
218
+ }
219
+
220
+ // Read source file
221
+ if (!existsSync(sourcePath)) {
222
+ errors.push(`${skillName}: source file not found at ${sourcePath}`);
223
+ continue;
224
+ }
225
+
226
+ const content = readFileSync(sourcePath, "utf-8");
227
+
228
+ // Create target directory
229
+ if (!existsSync(targetDir)) {
230
+ mkdirSync(targetDir, { recursive: true });
231
+ }
232
+
233
+ // Write skill file
234
+ writeFileSync(targetPath, content, "utf-8");
235
+ installed.push(skillName);
236
+ } catch (err) {
237
+ errors.push(`${skillName}: ${err instanceof Error ? err.message : String(err)}`);
238
+ }
239
+ }
240
+
241
+ return { installed, skipped, errors };
242
+ }
243
+
244
+ /**
245
+ * Uninstall SA skills from ~/.config/opencode/skills/
246
+ */
247
+ export function uninstallSASkills(): string[] {
248
+ const skillsDir = getSkillsDir();
249
+ const removed: string[] = [];
250
+
251
+ for (const skillName of SA_SKILL_NAMES) {
252
+ const skillDir = join(skillsDir, skillName);
253
+ const skillPath = join(skillDir, "SKILL.md");
254
+
255
+ if (existsSync(skillPath)) {
256
+ try {
257
+ const { unlinkSync, rmdirSync } = require("fs");
258
+ unlinkSync(skillPath);
259
+ // Try to remove the directory if empty
260
+ try {
261
+ rmdirSync(skillDir);
262
+ } catch {
263
+ // Directory not empty, leave it
264
+ }
265
+ removed.push(skillName);
266
+ } catch {
267
+ // Ignore errors during uninstall
268
+ }
269
+ }
270
+ }
271
+
272
+ return removed;
273
+ }
package/src/index.ts CHANGED
@@ -1,12 +1,21 @@
1
1
  import type { Plugin } from "@opencode-ai/plugin";
2
2
  import { chatMessageHook, systemTransformHook } from "./hooks/wadd-mode";
3
- import { installSAAgents } from "./agents";
3
+ import { installSAAgents, installSASkills } from "./agents";
4
4
 
5
5
  export const SaAssistantPlugin: Plugin = async (ctx) => {
6
- const { installed, skipped } = installSAAgents();
6
+ const agentResult = installSAAgents();
7
+ const skillResult = installSASkills();
7
8
 
8
- if (installed.length > 0) {
9
- console.log(`[SA Assistant] Installed agents: ${installed.join(", ")}`);
9
+ if (agentResult.installed.length > 0) {
10
+ console.log(`[SA Assistant] Installed agents: ${agentResult.installed.join(", ")}`);
11
+ }
12
+
13
+ if (skillResult.installed.length > 0) {
14
+ console.log(`[SA Assistant] Installed skills: ${skillResult.installed.join(", ")}`);
15
+ }
16
+
17
+ if (skillResult.errors.length > 0) {
18
+ console.warn(`[SA Assistant] Skill installation errors: ${skillResult.errors.join(", ")}`);
10
19
  }
11
20
 
12
21
  return {