cortex-agents 1.0.1 → 1.1.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/dist/cli.js +132 -67
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -1,17 +1,23 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import * as fs from "fs";
|
|
3
3
|
import * as path from "path";
|
|
4
|
-
|
|
4
|
+
import { fileURLToPath } from "url";
|
|
5
|
+
const VERSION = "1.1.0";
|
|
5
6
|
const PLUGIN_NAME = "cortex-agents";
|
|
7
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
8
|
+
const __dirname = path.dirname(__filename);
|
|
9
|
+
// The .opencode directory shipped with the package (adjacent to dist/)
|
|
10
|
+
const PACKAGE_OPENCODE_DIR = path.resolve(__dirname, "..", ".opencode");
|
|
11
|
+
function getGlobalDir() {
|
|
12
|
+
const homeDir = process.env.HOME || process.env.USERPROFILE || "";
|
|
13
|
+
return path.join(homeDir, ".config", "opencode");
|
|
14
|
+
}
|
|
6
15
|
function findOpencodeConfig() {
|
|
7
|
-
// Check local first
|
|
8
16
|
const localPath = path.join(process.cwd(), "opencode.json");
|
|
9
17
|
if (fs.existsSync(localPath)) {
|
|
10
18
|
return { path: localPath, isGlobal: false };
|
|
11
19
|
}
|
|
12
|
-
|
|
13
|
-
const homeDir = process.env.HOME || process.env.USERPROFILE || "";
|
|
14
|
-
const globalPath = path.join(homeDir, ".config", "opencode", "opencode.json");
|
|
20
|
+
const globalPath = path.join(getGlobalDir(), "opencode.json");
|
|
15
21
|
if (fs.existsSync(globalPath)) {
|
|
16
22
|
return { path: globalPath, isGlobal: true };
|
|
17
23
|
}
|
|
@@ -19,8 +25,7 @@ function findOpencodeConfig() {
|
|
|
19
25
|
}
|
|
20
26
|
function readConfig(configPath) {
|
|
21
27
|
try {
|
|
22
|
-
|
|
23
|
-
return JSON.parse(content);
|
|
28
|
+
return JSON.parse(fs.readFileSync(configPath, "utf-8"));
|
|
24
29
|
}
|
|
25
30
|
catch {
|
|
26
31
|
return {};
|
|
@@ -29,44 +34,100 @@ function readConfig(configPath) {
|
|
|
29
34
|
function writeConfig(configPath, config) {
|
|
30
35
|
fs.writeFileSync(configPath, JSON.stringify(config, null, 2) + "\n");
|
|
31
36
|
}
|
|
37
|
+
function copyDirRecursive(src, dest) {
|
|
38
|
+
fs.mkdirSync(dest, { recursive: true });
|
|
39
|
+
for (const entry of fs.readdirSync(src, { withFileTypes: true })) {
|
|
40
|
+
const srcPath = path.join(src, entry.name);
|
|
41
|
+
const destPath = path.join(dest, entry.name);
|
|
42
|
+
if (entry.isDirectory()) {
|
|
43
|
+
copyDirRecursive(srcPath, destPath);
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
fs.copyFileSync(srcPath, destPath);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
function installAgentsAndSkills(targetDir) {
|
|
51
|
+
if (!fs.existsSync(PACKAGE_OPENCODE_DIR)) {
|
|
52
|
+
console.log(" Warning: Package .opencode directory not found, skipping agents/skills copy.");
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
const agentsSrc = path.join(PACKAGE_OPENCODE_DIR, "agents");
|
|
56
|
+
const skillsSrc = path.join(PACKAGE_OPENCODE_DIR, "skills");
|
|
57
|
+
// Copy agents
|
|
58
|
+
if (fs.existsSync(agentsSrc)) {
|
|
59
|
+
const agentsDest = path.join(targetDir, "agents");
|
|
60
|
+
copyDirRecursive(agentsSrc, agentsDest);
|
|
61
|
+
const count = fs.readdirSync(agentsSrc).filter((f) => f.endsWith(".md")).length;
|
|
62
|
+
console.log(` Installed ${count} agents -> ${agentsDest}`);
|
|
63
|
+
}
|
|
64
|
+
// Copy skills
|
|
65
|
+
if (fs.existsSync(skillsSrc)) {
|
|
66
|
+
const skillsDest = path.join(targetDir, "skills");
|
|
67
|
+
copyDirRecursive(skillsSrc, skillsDest);
|
|
68
|
+
const count = fs.readdirSync(skillsSrc).filter((f) => !f.startsWith(".")).length;
|
|
69
|
+
console.log(` Installed ${count} skills -> ${skillsDest}`);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
function removeAgentsAndSkills(targetDir) {
|
|
73
|
+
const agentsSrc = path.join(PACKAGE_OPENCODE_DIR, "agents");
|
|
74
|
+
const skillsSrc = path.join(PACKAGE_OPENCODE_DIR, "skills");
|
|
75
|
+
// Remove only agent files that we installed
|
|
76
|
+
if (fs.existsSync(agentsSrc)) {
|
|
77
|
+
for (const file of fs.readdirSync(agentsSrc)) {
|
|
78
|
+
const dest = path.join(targetDir, "agents", file);
|
|
79
|
+
if (fs.existsSync(dest)) {
|
|
80
|
+
fs.unlinkSync(dest);
|
|
81
|
+
console.log(` Removed agent: ${file}`);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
// Remove only skill dirs that we installed
|
|
86
|
+
if (fs.existsSync(skillsSrc)) {
|
|
87
|
+
for (const dir of fs.readdirSync(skillsSrc)) {
|
|
88
|
+
const dest = path.join(targetDir, "skills", dir);
|
|
89
|
+
if (fs.existsSync(dest)) {
|
|
90
|
+
fs.rmSync(dest, { recursive: true });
|
|
91
|
+
console.log(` Removed skill: ${dir}`);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
32
96
|
function install() {
|
|
33
97
|
console.log(`Installing ${PLUGIN_NAME} v${VERSION}...\n`);
|
|
98
|
+
const globalDir = getGlobalDir();
|
|
34
99
|
const configInfo = findOpencodeConfig();
|
|
35
100
|
if (!configInfo) {
|
|
36
101
|
// Create global config
|
|
37
|
-
const homeDir = process.env.HOME || process.env.USERPROFILE || "";
|
|
38
|
-
const globalDir = path.join(homeDir, ".config", "opencode");
|
|
39
|
-
const globalPath = path.join(globalDir, "opencode.json");
|
|
40
102
|
if (!fs.existsSync(globalDir)) {
|
|
41
103
|
fs.mkdirSync(globalDir, { recursive: true });
|
|
42
104
|
}
|
|
105
|
+
const globalPath = path.join(globalDir, "opencode.json");
|
|
43
106
|
const newConfig = {
|
|
44
107
|
$schema: "https://opencode.ai/config.json",
|
|
45
108
|
plugin: [PLUGIN_NAME],
|
|
46
109
|
};
|
|
47
110
|
writeConfig(globalPath, newConfig);
|
|
48
|
-
console.log(`Created
|
|
49
|
-
console.log(`Added plugin: ${PLUGIN_NAME}`);
|
|
50
|
-
console.log("\nRestart OpenCode to load the plugin.");
|
|
51
|
-
return;
|
|
111
|
+
console.log(`Created config: ${globalPath}`);
|
|
112
|
+
console.log(`Added plugin: ${PLUGIN_NAME}\n`);
|
|
52
113
|
}
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
114
|
+
else {
|
|
115
|
+
const config = readConfig(configInfo.path);
|
|
116
|
+
if (!config.plugin)
|
|
117
|
+
config.plugin = [];
|
|
118
|
+
if (!config.plugin.includes(PLUGIN_NAME)) {
|
|
119
|
+
config.plugin.push(PLUGIN_NAME);
|
|
120
|
+
writeConfig(configInfo.path, config);
|
|
121
|
+
console.log(`Added plugin to config: ${configInfo.path}\n`);
|
|
122
|
+
}
|
|
123
|
+
else {
|
|
124
|
+
console.log(`Plugin already in config: ${configInfo.path}\n`);
|
|
125
|
+
}
|
|
63
126
|
}
|
|
64
|
-
//
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
console.log(
|
|
68
|
-
console.log(`Config: ${configInfo.path}`);
|
|
69
|
-
console.log("\nRestart OpenCode to load the plugin.");
|
|
127
|
+
// Copy agents and skills into the global opencode config dir
|
|
128
|
+
console.log("Installing agents and skills...");
|
|
129
|
+
installAgentsAndSkills(globalDir);
|
|
130
|
+
console.log("\nDone! Restart OpenCode to load the plugin.");
|
|
70
131
|
}
|
|
71
132
|
function uninstall() {
|
|
72
133
|
console.log(`Uninstalling ${PLUGIN_NAME}...\n`);
|
|
@@ -76,64 +137,62 @@ function uninstall() {
|
|
|
76
137
|
return;
|
|
77
138
|
}
|
|
78
139
|
const config = readConfig(configInfo.path);
|
|
79
|
-
if (
|
|
80
|
-
|
|
81
|
-
|
|
140
|
+
if (config.plugin?.includes(PLUGIN_NAME)) {
|
|
141
|
+
config.plugin = config.plugin.filter((p) => p !== PLUGIN_NAME);
|
|
142
|
+
writeConfig(configInfo.path, config);
|
|
143
|
+
console.log(`Removed plugin from config: ${configInfo.path}\n`);
|
|
82
144
|
}
|
|
83
|
-
// Remove
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
console.log(
|
|
88
|
-
console.log("\nRestart OpenCode to apply changes.");
|
|
145
|
+
// Remove agents and skills
|
|
146
|
+
const globalDir = getGlobalDir();
|
|
147
|
+
console.log("Removing agents and skills...");
|
|
148
|
+
removeAgentsAndSkills(globalDir);
|
|
149
|
+
console.log("\nDone! Restart OpenCode to apply changes.");
|
|
89
150
|
}
|
|
90
151
|
function status() {
|
|
91
152
|
console.log(`${PLUGIN_NAME} v${VERSION}\n`);
|
|
92
153
|
const configInfo = findOpencodeConfig();
|
|
93
154
|
if (!configInfo) {
|
|
94
155
|
console.log("Status: NOT INSTALLED");
|
|
95
|
-
console.log(
|
|
96
|
-
console.log("Run 'npx cortex-agents install' to set up.");
|
|
156
|
+
console.log(`\nRun 'npx ${PLUGIN_NAME} install' to set up.`);
|
|
97
157
|
return;
|
|
98
158
|
}
|
|
99
159
|
const config = readConfig(configInfo.path);
|
|
100
160
|
const isInstalled = config.plugin?.includes(PLUGIN_NAME);
|
|
101
161
|
console.log(`Status: ${isInstalled ? "INSTALLED" : "NOT INSTALLED"}`);
|
|
102
162
|
console.log(`Config: ${configInfo.path} (${configInfo.isGlobal ? "global" : "local"})`);
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
163
|
+
// Check agents
|
|
164
|
+
const globalDir = getGlobalDir();
|
|
165
|
+
const agentsDir = path.join(globalDir, "agents");
|
|
166
|
+
const skillsDir = path.join(globalDir, "skills");
|
|
167
|
+
const agentCount = fs.existsSync(agentsDir)
|
|
168
|
+
? fs.readdirSync(agentsDir).filter((f) => f.endsWith(".md")).length
|
|
169
|
+
: 0;
|
|
170
|
+
const skillCount = fs.existsSync(skillsDir)
|
|
171
|
+
? fs.readdirSync(skillsDir).filter((f) => !f.startsWith(".")).length
|
|
172
|
+
: 0;
|
|
173
|
+
console.log(`\nAgents installed: ${agentCount}`);
|
|
174
|
+
console.log(`Skills installed: ${skillCount}`);
|
|
175
|
+
if (!isInstalled) {
|
|
176
|
+
console.log(`\nRun 'npx ${PLUGIN_NAME} install' to add to config.`);
|
|
112
177
|
}
|
|
113
178
|
}
|
|
114
179
|
function help() {
|
|
115
180
|
console.log(`${PLUGIN_NAME} v${VERSION}
|
|
116
181
|
|
|
117
|
-
|
|
182
|
+
Cortex agents for OpenCode - worktree workflow, plan persistence, and session management.
|
|
118
183
|
|
|
119
184
|
USAGE:
|
|
120
185
|
npx ${PLUGIN_NAME} <command>
|
|
121
186
|
|
|
122
187
|
COMMANDS:
|
|
123
|
-
install
|
|
124
|
-
uninstall Remove plugin from
|
|
125
|
-
status Show
|
|
188
|
+
install Install plugin, agents, and skills into OpenCode config
|
|
189
|
+
uninstall Remove plugin, agents, and skills from OpenCode config
|
|
190
|
+
status Show installation status
|
|
126
191
|
help Show this help message
|
|
127
192
|
|
|
128
193
|
EXAMPLES:
|
|
129
|
-
npx ${PLUGIN_NAME} install #
|
|
130
|
-
npx ${PLUGIN_NAME} status # Check
|
|
131
|
-
|
|
132
|
-
MANUAL INSTALLATION:
|
|
133
|
-
Add to your opencode.json:
|
|
134
|
-
{
|
|
135
|
-
"plugin": ["${PLUGIN_NAME}"]
|
|
136
|
-
}
|
|
194
|
+
npx ${PLUGIN_NAME} install # Full install
|
|
195
|
+
npx ${PLUGIN_NAME} status # Check status
|
|
137
196
|
|
|
138
197
|
INCLUDED TOOLS:
|
|
139
198
|
cortex_init, cortex_status - .cortex directory management
|
|
@@ -143,11 +202,17 @@ INCLUDED TOOLS:
|
|
|
143
202
|
session_save, session_list, session_load
|
|
144
203
|
|
|
145
204
|
INCLUDED AGENTS:
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
205
|
+
build - Pre-implementation workflow with branch/worktree prompts
|
|
206
|
+
plan - Create and save implementation plans with mermaid diagrams
|
|
207
|
+
debug - Pre-fix workflow with hotfix worktree support
|
|
208
|
+
fullstack - End-to-end feature implementation
|
|
209
|
+
testing - Test writing and coverage analysis
|
|
210
|
+
security - Security audit and vulnerability detection
|
|
211
|
+
devops - CI/CD and deployment automation
|
|
149
212
|
|
|
150
|
-
|
|
213
|
+
INCLUDED SKILLS:
|
|
214
|
+
web-development, testing-strategies, security-hardening,
|
|
215
|
+
deployment-automation, code-quality, git-workflow
|
|
151
216
|
`);
|
|
152
217
|
}
|
|
153
218
|
// Parse command
|
|
@@ -169,6 +234,6 @@ switch (command) {
|
|
|
169
234
|
break;
|
|
170
235
|
default:
|
|
171
236
|
console.error(`Unknown command: ${command}`);
|
|
172
|
-
console.error(
|
|
237
|
+
console.error(`Run 'npx ${PLUGIN_NAME} help' for usage.`);
|
|
173
238
|
process.exit(1);
|
|
174
239
|
}
|