opencode-sa-assistant 0.1.0 → 0.2.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/package.json +1 -1
- package/src/agents/index.ts +166 -0
- package/src/index.ts +7 -0
package/package.json
CHANGED
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SA Agent Markdown File Generator
|
|
3
|
+
*
|
|
4
|
+
* Automatically creates agent MD files in ~/.config/opencode/agents/
|
|
5
|
+
* so that SA agents appear in Tab selector and /agent list.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { SA_ORCHESTRATOR_PROMPT } from "../prompts/orchestrator";
|
|
9
|
+
import { GURU_PROMPTS } from "../prompts/gurus";
|
|
10
|
+
import { SPECIALIST_PROMPTS } from "../prompts/specialists";
|
|
11
|
+
import { existsSync, mkdirSync, writeFileSync } from "fs";
|
|
12
|
+
import { join } from "path";
|
|
13
|
+
import { homedir } from "os";
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Agent definition with frontmatter metadata
|
|
17
|
+
*/
|
|
18
|
+
interface AgentDefinition {
|
|
19
|
+
name: string;
|
|
20
|
+
description: string;
|
|
21
|
+
mode: "primary" | "subagent";
|
|
22
|
+
prompt: string;
|
|
23
|
+
tools?: Record<string, boolean>;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* SA Agent definitions
|
|
28
|
+
*/
|
|
29
|
+
export const SA_AGENTS: AgentDefinition[] = [
|
|
30
|
+
{
|
|
31
|
+
name: "sa-orchestrator",
|
|
32
|
+
description: "AWS Solutions Architect Orchestrator - SA Assistant의 메인 에이전트",
|
|
33
|
+
mode: "primary",
|
|
34
|
+
prompt: SA_ORCHESTRATOR_PROMPT,
|
|
35
|
+
tools: {
|
|
36
|
+
write: true,
|
|
37
|
+
edit: true,
|
|
38
|
+
bash: true,
|
|
39
|
+
webfetch: true,
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
name: "sa-bezos",
|
|
44
|
+
description: "Jeff Bezos Thinking Coach - 고객 중심 사고 전문가",
|
|
45
|
+
mode: "subagent",
|
|
46
|
+
prompt: GURU_PROMPTS.bezos,
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
name: "sa-vogels",
|
|
50
|
+
description: "Werner Vogels Thinking Coach - 분산 시스템 전문가",
|
|
51
|
+
mode: "subagent",
|
|
52
|
+
prompt: GURU_PROMPTS.vogels,
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
name: "sa-naval",
|
|
56
|
+
description: "Naval Ravikant Thinking Coach - 시스템적 사고 전문가",
|
|
57
|
+
mode: "subagent",
|
|
58
|
+
prompt: GURU_PROMPTS.naval,
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
name: "sa-feynman",
|
|
62
|
+
description: "Richard Feynman Thinking Coach - 학습 최적화 전문가",
|
|
63
|
+
mode: "subagent",
|
|
64
|
+
prompt: GURU_PROMPTS.feynman,
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
name: "sa-explorer",
|
|
68
|
+
description: "Architecture Explorer - 아키텍처 분석 전문가",
|
|
69
|
+
mode: "subagent",
|
|
70
|
+
prompt: SPECIALIST_PROMPTS.explorer,
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
name: "sa-researcher",
|
|
74
|
+
description: "AWS Researcher - AWS 정보 수집 전문가 (MCP 도구 활용)",
|
|
75
|
+
mode: "subagent",
|
|
76
|
+
prompt: SPECIALIST_PROMPTS.researcher,
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
name: "sa-reviewer",
|
|
80
|
+
description: "Architecture Reviewer - Well-Architected 검토 전문가",
|
|
81
|
+
mode: "subagent",
|
|
82
|
+
prompt: SPECIALIST_PROMPTS.reviewer,
|
|
83
|
+
},
|
|
84
|
+
];
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Generate markdown content for an agent
|
|
88
|
+
*/
|
|
89
|
+
function generateAgentMarkdown(agent: AgentDefinition): string {
|
|
90
|
+
const toolsSection = agent.tools
|
|
91
|
+
? Object.entries(agent.tools)
|
|
92
|
+
.map(([tool, enabled]) => ` ${tool}: ${enabled}`)
|
|
93
|
+
.join("\n")
|
|
94
|
+
: "";
|
|
95
|
+
|
|
96
|
+
const frontmatter = [
|
|
97
|
+
"---",
|
|
98
|
+
`description: ${agent.description}`,
|
|
99
|
+
`mode: ${agent.mode}`,
|
|
100
|
+
toolsSection ? `tools:\n${toolsSection}` : "",
|
|
101
|
+
"---",
|
|
102
|
+
]
|
|
103
|
+
.filter(Boolean)
|
|
104
|
+
.join("\n");
|
|
105
|
+
|
|
106
|
+
return `${frontmatter}\n\n${agent.prompt}`;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Get the agents directory path
|
|
111
|
+
*/
|
|
112
|
+
function getAgentsDir(): string {
|
|
113
|
+
return join(homedir(), ".config", "opencode", "agents");
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Install SA agents to ~/.config/opencode/agents/
|
|
118
|
+
* Creates the directory if it doesn't exist.
|
|
119
|
+
* Only writes files if they don't exist or have different content.
|
|
120
|
+
*/
|
|
121
|
+
export function installSAAgents(): { installed: string[]; skipped: string[] } {
|
|
122
|
+
const agentsDir = getAgentsDir();
|
|
123
|
+
const installed: string[] = [];
|
|
124
|
+
const skipped: string[] = [];
|
|
125
|
+
|
|
126
|
+
// Create agents directory if it doesn't exist
|
|
127
|
+
if (!existsSync(agentsDir)) {
|
|
128
|
+
mkdirSync(agentsDir, { recursive: true });
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
for (const agent of SA_AGENTS) {
|
|
132
|
+
const filePath = join(agentsDir, `${agent.name}.md`);
|
|
133
|
+
const content = generateAgentMarkdown(agent);
|
|
134
|
+
|
|
135
|
+
// Check if file already exists
|
|
136
|
+
if (existsSync(filePath)) {
|
|
137
|
+
// Skip if file exists (don't overwrite user modifications)
|
|
138
|
+
skipped.push(agent.name);
|
|
139
|
+
} else {
|
|
140
|
+
// Write new file
|
|
141
|
+
writeFileSync(filePath, content, "utf-8");
|
|
142
|
+
installed.push(agent.name);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
return { installed, skipped };
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Uninstall SA agents (remove MD files)
|
|
151
|
+
*/
|
|
152
|
+
export function uninstallSAAgents(): string[] {
|
|
153
|
+
const agentsDir = getAgentsDir();
|
|
154
|
+
const removed: string[] = [];
|
|
155
|
+
|
|
156
|
+
for (const agent of SA_AGENTS) {
|
|
157
|
+
const filePath = join(agentsDir, `${agent.name}.md`);
|
|
158
|
+
if (existsSync(filePath)) {
|
|
159
|
+
const { unlinkSync } = require("fs");
|
|
160
|
+
unlinkSync(filePath);
|
|
161
|
+
removed.push(agent.name);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
return removed;
|
|
166
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -1,7 +1,14 @@
|
|
|
1
1
|
import type { Plugin } from "@opencode-ai/plugin";
|
|
2
2
|
import { chatMessageHook, systemTransformHook } from "./hooks/wadd-mode";
|
|
3
|
+
import { installSAAgents } from "./agents";
|
|
3
4
|
|
|
4
5
|
export const SaAssistantPlugin: Plugin = async (ctx) => {
|
|
6
|
+
const { installed, skipped } = installSAAgents();
|
|
7
|
+
|
|
8
|
+
if (installed.length > 0) {
|
|
9
|
+
console.log(`[SA Assistant] Installed agents: ${installed.join(", ")}`);
|
|
10
|
+
}
|
|
11
|
+
|
|
5
12
|
return {
|
|
6
13
|
"chat.message": chatMessageHook,
|
|
7
14
|
"experimental.chat.system.transform": systemTransformHook,
|