cortex-agents 2.2.0 → 2.3.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.
- package/.opencode/agents/build.md +118 -70
- package/.opencode/agents/debug.md +132 -19
- package/.opencode/agents/devops.md +213 -72
- package/.opencode/agents/fullstack.md +183 -48
- package/.opencode/agents/plan.md +79 -4
- package/.opencode/agents/review.md +314 -0
- package/.opencode/agents/security.md +166 -53
- package/.opencode/agents/testing.md +215 -38
- package/README.md +98 -34
- package/dist/cli.js +209 -50
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +174 -8
- package/dist/registry.d.ts +2 -2
- package/dist/registry.d.ts.map +1 -1
- package/dist/registry.js +1 -1
- package/dist/tools/branch.d.ts +7 -1
- package/dist/tools/branch.d.ts.map +1 -1
- package/dist/tools/branch.js +88 -53
- package/dist/tools/cortex.d.ts +19 -0
- package/dist/tools/cortex.d.ts.map +1 -1
- package/dist/tools/cortex.js +109 -0
- package/dist/tools/session.d.ts.map +1 -1
- package/dist/tools/session.js +3 -1
- package/dist/tools/task.d.ts.map +1 -1
- package/dist/tools/task.js +65 -57
- package/dist/tools/worktree.d.ts +10 -2
- package/dist/tools/worktree.d.ts.map +1 -1
- package/dist/tools/worktree.js +320 -246
- package/dist/utils/shell.d.ts +53 -0
- package/dist/utils/shell.d.ts.map +1 -0
- package/dist/utils/shell.js +118 -0
- package/dist/utils/terminal.d.ts +66 -0
- package/dist/utils/terminal.d.ts.map +1 -0
- package/dist/utils/terminal.js +627 -0
- package/dist/utils/worktree-detect.d.ts.map +1 -1
- package/dist/utils/worktree-detect.js +5 -4
- package/package.json +5 -4
package/README.md
CHANGED
|
@@ -43,7 +43,7 @@ npx cortex-agents configure # Pick your models interactively
|
|
|
43
43
|
# Restart OpenCode - done.
|
|
44
44
|
```
|
|
45
45
|
|
|
46
|
-
That's it. Your OpenCode session now has
|
|
46
|
+
That's it. Your OpenCode session now has 8 specialized agents, 23 tools, and 14 domain skills.
|
|
47
47
|
|
|
48
48
|
<br>
|
|
49
49
|
|
|
@@ -78,6 +78,8 @@ Create isolated development environments and launch them instantly:
|
|
|
78
78
|
|
|
79
79
|
Plans are automatically propagated into the worktree's `.cortex/plans/` so the new session has full context.
|
|
80
80
|
|
|
81
|
+
**Cross-platform terminal support** via the terminal driver system — automatically detects and integrates with tmux, iTerm2, Terminal.app, kitty, wezterm, Konsole, and GNOME Terminal. Tabs opened by the launcher are tracked and automatically closed when the worktree is removed.
|
|
82
|
+
|
|
81
83
|
### Task Finalizer
|
|
82
84
|
|
|
83
85
|
One tool to close the loop:
|
|
@@ -114,35 +116,48 @@ Handle complex, multi-step work. Use your best model.
|
|
|
114
116
|
|
|
115
117
|
| Agent | Role | Superpower |
|
|
116
118
|
|-------|------|-----------|
|
|
117
|
-
| **build** | Full-access development |
|
|
118
|
-
| **plan** | Read-only analysis |
|
|
119
|
-
| **debug** | Deep troubleshooting |
|
|
119
|
+
| **build** | Full-access development | Skill-aware implementation, worktree launcher, quality gates, task finalizer |
|
|
120
|
+
| **plan** | Read-only analysis | Architectural plans with mermaid diagrams, NFR analysis, hands off to build |
|
|
121
|
+
| **debug** | Deep troubleshooting | Performance debugging, distributed tracing, hotfix workflow |
|
|
122
|
+
| **review** | Code quality assessment | Tech debt scoring, pattern review, refactoring advisor (read-only) |
|
|
120
123
|
|
|
121
124
|
### Subagents
|
|
122
125
|
|
|
123
|
-
Focused specialists.
|
|
126
|
+
Focused specialists launched **automatically** as parallel quality gates. Each auto-loads its core domain skill for deeper analysis. Use a fast/cheap model.
|
|
127
|
+
|
|
128
|
+
| Agent | Role | Auto-Loads Skill | Triggered By |
|
|
129
|
+
|-------|------|-----------------|-------------|
|
|
130
|
+
| **@testing** | Writes tests, runs suite, reports coverage | `testing-strategies` | Build (always), Debug (always) |
|
|
131
|
+
| **@security** | OWASP audit, secrets scan, code-level fix patches | `security-hardening` | Build (always), Debug (if security-relevant) |
|
|
132
|
+
| **@fullstack** | Cross-layer implementation + feasibility analysis | Per-layer skills | Build (multi-layer features), Plan (analysis) |
|
|
133
|
+
| **@devops** | CI/CD validation, IaC review, deployment strategy | `deployment-automation` | Build (when CI/Docker/infra files change) |
|
|
134
|
+
|
|
135
|
+
Subagents return **structured reports** with severity levels (`BLOCKING`, `CRITICAL`, `HIGH`, `MEDIUM`, `LOW`) that the orchestrating agent uses to decide whether to proceed or fix issues first.
|
|
136
|
+
|
|
137
|
+
### Skill Routing
|
|
138
|
+
|
|
139
|
+
All agents detect the project's technology stack and **automatically load relevant skills** before working. This turns the 14 domain skills from passive knowledge into active intelligence:
|
|
124
140
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
| **@devops** | CI/CD pipelines, Docker, deployment automation |
|
|
141
|
+
```
|
|
142
|
+
Build Agent detects: package.json has React + Express + Prisma
|
|
143
|
+
→ auto-loads: frontend-development, backend-development, database-design, api-design
|
|
144
|
+
→ implements with deep framework-specific knowledge
|
|
145
|
+
```
|
|
131
146
|
|
|
132
147
|
<br>
|
|
133
148
|
|
|
134
149
|
## Tools
|
|
135
150
|
|
|
136
|
-
|
|
151
|
+
23 tools bundled and auto-registered. No configuration needed.
|
|
137
152
|
|
|
138
153
|
<table>
|
|
139
154
|
<tr><td width="50%">
|
|
140
155
|
|
|
141
156
|
**Git Workflow**
|
|
142
157
|
- `branch_status` - Current branch + change detection
|
|
143
|
-
- `branch_create` - Convention-named branches
|
|
158
|
+
- `branch_create` - Convention-named branches (with toast notifications)
|
|
144
159
|
- `branch_switch` - Safe branch switching
|
|
145
|
-
- `worktree_create` - Isolated worktree in `.worktrees/`
|
|
160
|
+
- `worktree_create` - Isolated worktree in `.worktrees/` (with toast notifications)
|
|
146
161
|
- `worktree_launch` - Launch worktree (terminal/PTY/background)
|
|
147
162
|
- `worktree_list` / `worktree_remove` / `worktree_open`
|
|
148
163
|
|
|
@@ -151,7 +166,7 @@ Focused specialists. Invoked with `@mention`. Use a fast/cheap model.
|
|
|
151
166
|
**Planning & Sessions**
|
|
152
167
|
- `plan_save` / `plan_load` / `plan_list` / `plan_delete`
|
|
153
168
|
- `session_save` / `session_list` / `session_load`
|
|
154
|
-
- `cortex_init` / `cortex_status`
|
|
169
|
+
- `cortex_init` / `cortex_status` / `cortex_configure`
|
|
155
170
|
|
|
156
171
|
</td></tr>
|
|
157
172
|
<tr><td width="50%">
|
|
@@ -164,11 +179,12 @@ Focused specialists. Invoked with `@mention`. Use a fast/cheap model.
|
|
|
164
179
|
|
|
165
180
|
</td><td width="50%">
|
|
166
181
|
|
|
167
|
-
**Finalization**
|
|
182
|
+
**Finalization & Config**
|
|
168
183
|
- `task_finalize` - Stage, commit, push, create PR
|
|
169
184
|
- Auto-detects worktree (targets main)
|
|
170
185
|
- Auto-populates PR from `.cortex/plans/`
|
|
171
186
|
- Warns if docs are missing
|
|
187
|
+
- `cortex_configure` - Set models from within an agent session
|
|
172
188
|
|
|
173
189
|
</td></tr>
|
|
174
190
|
</table>
|
|
@@ -181,7 +197,6 @@ Focused specialists. Invoked with `@mention`. Use a fast/cheap model.
|
|
|
181
197
|
|
|
182
198
|
| Skill | Covers |
|
|
183
199
|
|-------|--------|
|
|
184
|
-
| **web-development** | Full-stack patterns, REST/GraphQL, SSR, state management |
|
|
185
200
|
| **frontend-development** | React, Vue, Svelte, CSS architecture, accessibility |
|
|
186
201
|
| **backend-development** | API design, middleware, auth, caching, queue systems |
|
|
187
202
|
| **mobile-development** | React Native, Flutter, native iOS/Android patterns |
|
|
@@ -201,10 +216,11 @@ Focused specialists. Invoked with `@mention`. Use a fast/cheap model.
|
|
|
201
216
|
|
|
202
217
|
## Model Configuration
|
|
203
218
|
|
|
204
|
-
Cortex agents are **model-agnostic**.
|
|
219
|
+
Cortex agents are **model-agnostic**. Configure globally or per-project:
|
|
205
220
|
|
|
206
221
|
```bash
|
|
207
|
-
npx cortex-agents configure
|
|
222
|
+
npx cortex-agents configure # Global (all projects)
|
|
223
|
+
npx cortex-agents configure --project # Per-project (saves to .opencode/models.json)
|
|
208
224
|
```
|
|
209
225
|
|
|
210
226
|
```
|
|
@@ -223,6 +239,19 @@ npx cortex-agents configure
|
|
|
223
239
|
Same as primary
|
|
224
240
|
```
|
|
225
241
|
|
|
242
|
+
### In-Agent Configuration
|
|
243
|
+
|
|
244
|
+
Agents can also configure models during a session via the `cortex_configure` tool — no need to leave OpenCode. The agent will prompt you to select models when `.cortex/` is first initialized.
|
|
245
|
+
|
|
246
|
+
### Per-Project vs Global
|
|
247
|
+
|
|
248
|
+
| Scope | Where | Use Case |
|
|
249
|
+
|-------|-------|----------|
|
|
250
|
+
| **Global** | `~/.config/opencode/opencode.json` | Default for all projects |
|
|
251
|
+
| **Per-project** | `.opencode/models.json` + `opencode.json` | Different models for different repos |
|
|
252
|
+
|
|
253
|
+
Per-project config takes priority. Team members get the same model settings when they clone the repo (`.opencode/models.json` is git-tracked).
|
|
254
|
+
|
|
226
255
|
### Supported Providers
|
|
227
256
|
|
|
228
257
|
| Provider | Premium | Standard | Fast |
|
|
@@ -246,6 +275,8 @@ your-project/
|
|
|
246
275
|
config.json Configuration
|
|
247
276
|
plans/ Implementation plans (git tracked)
|
|
248
277
|
sessions/ Session summaries (gitignored)
|
|
278
|
+
.opencode/
|
|
279
|
+
models.json Per-project model config (git tracked)
|
|
249
280
|
.worktrees/ Git worktrees (gitignored)
|
|
250
281
|
feature-auth/ Isolated development copy
|
|
251
282
|
bugfix-login/
|
|
@@ -261,11 +292,13 @@ your-project/
|
|
|
261
292
|
## CLI Reference
|
|
262
293
|
|
|
263
294
|
```bash
|
|
264
|
-
npx cortex-agents install
|
|
265
|
-
npx cortex-agents configure
|
|
266
|
-
npx cortex-agents configure --
|
|
267
|
-
npx cortex-agents
|
|
268
|
-
npx cortex-agents
|
|
295
|
+
npx cortex-agents install # Install plugin, agents, and skills
|
|
296
|
+
npx cortex-agents configure # Global model selection
|
|
297
|
+
npx cortex-agents configure --project # Per-project model selection
|
|
298
|
+
npx cortex-agents configure --reset # Reset global models
|
|
299
|
+
npx cortex-agents configure --project --reset # Reset per-project models
|
|
300
|
+
npx cortex-agents uninstall # Clean removal of everything
|
|
301
|
+
npx cortex-agents status # Show installation and model status
|
|
269
302
|
```
|
|
270
303
|
|
|
271
304
|
<br>
|
|
@@ -278,20 +311,50 @@ Every time the build agent starts, it follows a structured pre-implementation ch
|
|
|
278
311
|
|
|
279
312
|
```
|
|
280
313
|
Step 1 branch_status Am I on a protected branch?
|
|
281
|
-
Step 2 cortex_status Is .cortex initialized?
|
|
314
|
+
Step 2 cortex_status Is .cortex initialized? Offer model config if new project.
|
|
282
315
|
Step 3 plan_list / plan_load Is there a plan for this work?
|
|
283
|
-
Step 4 Ask: strategy
|
|
284
|
-
Step 4b Ask: launch mode
|
|
285
|
-
Step 5 Execute Create branch
|
|
316
|
+
Step 4 Ask: strategy Worktree (recommended) or branch?
|
|
317
|
+
Step 4b Ask: launch mode Terminal tab (recommended) / stay / PTY / background?
|
|
318
|
+
Step 5 Execute Create worktree/branch, auto-detect terminal
|
|
286
319
|
Step 6 Implement Write code following the plan
|
|
287
|
-
Step 7
|
|
288
|
-
Step 8
|
|
289
|
-
Step 9
|
|
290
|
-
Step 10
|
|
320
|
+
Step 7 Quality Gate Launch @testing + @security in parallel
|
|
321
|
+
Step 8 Ask: documentation Decision doc / feature doc / flow doc?
|
|
322
|
+
Step 9 session_save Record what was done and why
|
|
323
|
+
Step 10 task_finalize Commit, push, create PR
|
|
324
|
+
Step 11 Ask: cleanup Remove worktree + close terminal tab? (if applicable)
|
|
291
325
|
```
|
|
292
326
|
|
|
293
327
|
This isn't just documentation - it's enforced by the agent's instructions. The AI follows this workflow every time.
|
|
294
328
|
|
|
329
|
+
### Sub-Agent Quality Gates
|
|
330
|
+
|
|
331
|
+
After implementation (Step 7), the build agent **automatically** launches sub-agents in parallel as quality gates:
|
|
332
|
+
|
|
333
|
+
```
|
|
334
|
+
Build Agent completes implementation
|
|
335
|
+
|
|
|
336
|
+
+-- launches in parallel (single message) --+
|
|
337
|
+
| |
|
|
338
|
+
v v
|
|
339
|
+
@testing @security
|
|
340
|
+
Writes unit tests OWASP audit
|
|
341
|
+
Runs test suite Secrets scan
|
|
342
|
+
Reports coverage Severity ratings
|
|
343
|
+
Returns: PASS/FAIL Returns: PASS/FAIL
|
|
344
|
+
| |
|
|
345
|
+
+-------- results reviewed by Build ---------+
|
|
346
|
+
|
|
|
347
|
+
v
|
|
348
|
+
Quality Gate Summary included in PR body
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
The debug agent uses the same pattern: `@testing` for regression tests (always) and `@security` when the fix touches sensitive code.
|
|
352
|
+
|
|
353
|
+
Sub-agents use **structured return contracts** so results are actionable:
|
|
354
|
+
- `BLOCKING` / `CRITICAL` / `HIGH` findings block finalization
|
|
355
|
+
- `MEDIUM` findings are noted in the PR body
|
|
356
|
+
- `LOW` findings are deferred
|
|
357
|
+
|
|
295
358
|
### Agent Handover
|
|
296
359
|
|
|
297
360
|
When agents switch, a toast notification tells you what mode you're in:
|
|
@@ -300,9 +363,10 @@ When agents switch, a toast notification tells you what mode you're in:
|
|
|
300
363
|
Agent: build Development mode - ready to implement
|
|
301
364
|
Agent: plan Planning mode - read-only analysis
|
|
302
365
|
Agent: debug Debug mode - troubleshooting and fixes
|
|
366
|
+
Agent: review Review mode - code quality assessment
|
|
303
367
|
```
|
|
304
368
|
|
|
305
|
-
The Plan agent creates plans with mermaid diagrams and hands off to Build. Build loads the plan and implements
|
|
369
|
+
The Plan agent creates plans with mermaid diagrams and hands off to Build. Build loads the plan, detects the tech stack, loads relevant skills, and implements. If something breaks, Debug takes over with performance debugging tools. Review provides code quality assessment and tech debt analysis on demand.
|
|
306
370
|
|
|
307
371
|
<br>
|
|
308
372
|
|
|
@@ -346,7 +410,7 @@ cd ~/.config/opencode && npm unlink cortex-agents && npm install
|
|
|
346
410
|
|
|
347
411
|
- **New skills** - Domain-specific knowledge packs (e.g., Rust, Go, DevOps for AWS)
|
|
348
412
|
- **New agents** - Specialized agents (e.g., reviewer, migration, docs-writer)
|
|
349
|
-
- **
|
|
413
|
+
- **Terminal drivers** - Improve detection/support for additional terminal emulators
|
|
350
414
|
- **Tool improvements** - Better PR templates, test runners, linter integration
|
|
351
415
|
- **Bug fixes** - Anything that doesn't work as expected
|
|
352
416
|
|
package/dist/cli.js
CHANGED
|
@@ -4,7 +4,7 @@ import * as path from "path";
|
|
|
4
4
|
import { fileURLToPath } from "url";
|
|
5
5
|
import prompts from "prompts";
|
|
6
6
|
import { PRIMARY_AGENTS, SUBAGENTS, ALL_AGENTS, getPrimaryChoices, getSubagentChoices, } from "./registry.js";
|
|
7
|
-
const VERSION = "2.
|
|
7
|
+
const VERSION = "2.3.0";
|
|
8
8
|
const PLUGIN_NAME = "cortex-agents";
|
|
9
9
|
const __filename = fileURLToPath(import.meta.url);
|
|
10
10
|
const __dirname = path.dirname(__filename);
|
|
@@ -38,6 +38,66 @@ function writeConfig(configPath, config) {
|
|
|
38
38
|
fs.mkdirSync(path.dirname(configPath), { recursive: true });
|
|
39
39
|
fs.writeFileSync(configPath, JSON.stringify(config, null, 2) + "\n");
|
|
40
40
|
}
|
|
41
|
+
// ─── Per-Project Model Config (.opencode/models.json) ───────────────────────
|
|
42
|
+
const PROJECT_MODELS_FILE = "models.json";
|
|
43
|
+
function getProjectModelsPath() {
|
|
44
|
+
return path.join(process.cwd(), ".opencode", PROJECT_MODELS_FILE);
|
|
45
|
+
}
|
|
46
|
+
function hasProjectModelsConfig() {
|
|
47
|
+
return fs.existsSync(getProjectModelsPath());
|
|
48
|
+
}
|
|
49
|
+
function readProjectModels() {
|
|
50
|
+
const modelsPath = getProjectModelsPath();
|
|
51
|
+
if (!fs.existsSync(modelsPath))
|
|
52
|
+
return null;
|
|
53
|
+
try {
|
|
54
|
+
return JSON.parse(fs.readFileSync(modelsPath, "utf-8"));
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
function writeProjectModels(primary, subagent) {
|
|
61
|
+
const modelsPath = getProjectModelsPath();
|
|
62
|
+
const dir = path.dirname(modelsPath);
|
|
63
|
+
if (!fs.existsSync(dir)) {
|
|
64
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
65
|
+
}
|
|
66
|
+
const config = {
|
|
67
|
+
primary: { model: primary },
|
|
68
|
+
subagent: { model: subagent },
|
|
69
|
+
agents: {},
|
|
70
|
+
};
|
|
71
|
+
for (const name of PRIMARY_AGENTS) {
|
|
72
|
+
config.agents[name] = { model: primary };
|
|
73
|
+
}
|
|
74
|
+
for (const name of SUBAGENTS) {
|
|
75
|
+
config.agents[name] = { model: subagent };
|
|
76
|
+
}
|
|
77
|
+
fs.writeFileSync(modelsPath, JSON.stringify(config, null, 2) + "\n");
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Sync .opencode/models.json → local opencode.json agent model settings.
|
|
81
|
+
* Creates or merges into local opencode.json at project root.
|
|
82
|
+
*/
|
|
83
|
+
function syncProjectModelsToConfig() {
|
|
84
|
+
const models = readProjectModels();
|
|
85
|
+
if (!models)
|
|
86
|
+
return false;
|
|
87
|
+
const localPath = path.join(process.cwd(), "opencode.json");
|
|
88
|
+
const config = fs.existsSync(localPath)
|
|
89
|
+
? readConfig(localPath)
|
|
90
|
+
: { $schema: "https://opencode.ai/config.json" };
|
|
91
|
+
if (!config.agent)
|
|
92
|
+
config.agent = {};
|
|
93
|
+
for (const [name, entry] of Object.entries(models.agents)) {
|
|
94
|
+
if (!config.agent[name])
|
|
95
|
+
config.agent[name] = {};
|
|
96
|
+
config.agent[name].model = entry.model;
|
|
97
|
+
}
|
|
98
|
+
writeConfig(localPath, config);
|
|
99
|
+
return true;
|
|
100
|
+
}
|
|
41
101
|
// ─── File Copy Helpers ───────────────────────────────────────────────────────
|
|
42
102
|
function copyDirRecursive(src, dest) {
|
|
43
103
|
fs.mkdirSync(dest, { recursive: true });
|
|
@@ -137,8 +197,16 @@ function install() {
|
|
|
137
197
|
// Copy agents and skills into the global opencode config dir
|
|
138
198
|
console.log("Installing agents and skills...");
|
|
139
199
|
installAgentsAndSkills(globalDir);
|
|
200
|
+
// Sync per-project models if .opencode/models.json exists
|
|
201
|
+
if (hasProjectModelsConfig()) {
|
|
202
|
+
console.log("\nPer-project model config found (.opencode/models.json)");
|
|
203
|
+
if (syncProjectModelsToConfig()) {
|
|
204
|
+
console.log(" Synced model settings to local opencode.json");
|
|
205
|
+
}
|
|
206
|
+
}
|
|
140
207
|
console.log("\nDone! Next steps:");
|
|
141
|
-
console.log(` 1. Run 'npx ${PLUGIN_NAME} configure' to select your models`);
|
|
208
|
+
console.log(` 1. Run 'npx ${PLUGIN_NAME} configure' to select your models (global)`);
|
|
209
|
+
console.log(` Or 'npx ${PLUGIN_NAME} configure --project' for per-project config`);
|
|
142
210
|
console.log(" 2. Restart OpenCode to load the plugin\n");
|
|
143
211
|
}
|
|
144
212
|
function uninstall() {
|
|
@@ -180,30 +248,89 @@ function uninstall() {
|
|
|
180
248
|
async function configure() {
|
|
181
249
|
const args = process.argv.slice(3);
|
|
182
250
|
const isReset = args.includes("--reset");
|
|
251
|
+
const isProject = args.includes("--project");
|
|
183
252
|
// Handle --reset flag
|
|
184
253
|
if (isReset) {
|
|
185
|
-
return configureReset();
|
|
254
|
+
return configureReset(isProject);
|
|
255
|
+
}
|
|
256
|
+
const scope = isProject ? "Per-Project" : "Global";
|
|
257
|
+
console.log(`\n🔧 Cortex Agents — ${scope} Model Configuration\n`);
|
|
258
|
+
if (isProject) {
|
|
259
|
+
const opencodeDir = path.join(process.cwd(), ".opencode");
|
|
260
|
+
if (!fs.existsSync(opencodeDir)) {
|
|
261
|
+
console.log(`⚠ No .opencode/ directory found in ${process.cwd()}.`);
|
|
262
|
+
console.log(` Run 'npx ${PLUGIN_NAME} install' first, or use 'configure' without --project for global config.\n`);
|
|
263
|
+
process.exit(1);
|
|
264
|
+
}
|
|
265
|
+
console.log(`Project: ${process.cwd()}`);
|
|
266
|
+
console.log(`Config: .opencode/models.json + opencode.json\n`);
|
|
186
267
|
}
|
|
187
|
-
|
|
188
|
-
// Ensure plugin is installed first
|
|
268
|
+
// Ensure plugin is installed first (for global mode)
|
|
189
269
|
const configInfo = findOpencodeConfig();
|
|
190
270
|
const config = configInfo
|
|
191
271
|
? readConfig(configInfo.path)
|
|
192
272
|
: { $schema: "https://opencode.ai/config.json" };
|
|
193
|
-
if (!config.plugin?.includes(PLUGIN_NAME)) {
|
|
273
|
+
if (!isProject && !config.plugin?.includes(PLUGIN_NAME)) {
|
|
194
274
|
console.log(`⚠ Plugin not installed. Adding '${PLUGIN_NAME}' to config first.\n`);
|
|
195
275
|
if (!config.plugin)
|
|
196
276
|
config.plugin = [];
|
|
197
277
|
config.plugin.push(PLUGIN_NAME);
|
|
198
278
|
}
|
|
199
279
|
// ── Primary model selection ────────────────────────────────
|
|
280
|
+
const { primary, subagent } = await promptModelSelection();
|
|
281
|
+
// ── Write config ───────────────────────────────────────────
|
|
282
|
+
if (isProject) {
|
|
283
|
+
// Per-project: write .opencode/models.json + sync to local opencode.json
|
|
284
|
+
writeProjectModels(primary, subagent);
|
|
285
|
+
syncProjectModelsToConfig();
|
|
286
|
+
const modelsPath = getProjectModelsPath();
|
|
287
|
+
const localConfigPath = path.join(process.cwd(), "opencode.json");
|
|
288
|
+
console.log("━".repeat(50));
|
|
289
|
+
console.log(`✓ Per-project config saved:\n`);
|
|
290
|
+
console.log(` Models: ${modelsPath}`);
|
|
291
|
+
console.log(` Runtime: ${localConfigPath}\n`);
|
|
292
|
+
}
|
|
293
|
+
else {
|
|
294
|
+
// Global: write to opencode.json (existing behavior)
|
|
295
|
+
if (!config.agent)
|
|
296
|
+
config.agent = {};
|
|
297
|
+
for (const name of PRIMARY_AGENTS) {
|
|
298
|
+
if (!config.agent[name])
|
|
299
|
+
config.agent[name] = {};
|
|
300
|
+
config.agent[name].model = primary;
|
|
301
|
+
}
|
|
302
|
+
for (const name of SUBAGENTS) {
|
|
303
|
+
if (!config.agent[name])
|
|
304
|
+
config.agent[name] = {};
|
|
305
|
+
config.agent[name].model = subagent;
|
|
306
|
+
}
|
|
307
|
+
const targetPath = configInfo?.path || path.join(getGlobalDir(), "opencode.json");
|
|
308
|
+
writeConfig(targetPath, config);
|
|
309
|
+
console.log("━".repeat(50));
|
|
310
|
+
console.log(`✓ Configuration saved to ${targetPath}\n`);
|
|
311
|
+
}
|
|
312
|
+
console.log(" Primary agents:");
|
|
313
|
+
for (const name of PRIMARY_AGENTS) {
|
|
314
|
+
console.log(` ${name.padEnd(10)} → ${primary}`);
|
|
315
|
+
}
|
|
316
|
+
console.log("\n Subagents:");
|
|
317
|
+
for (const name of SUBAGENTS) {
|
|
318
|
+
console.log(` ${name.padEnd(10)} → ${subagent}`);
|
|
319
|
+
}
|
|
320
|
+
console.log("\nRestart OpenCode to apply changes.\n");
|
|
321
|
+
}
|
|
322
|
+
/**
|
|
323
|
+
* Interactive prompt for primary + subagent model selection.
|
|
324
|
+
* Shared between global and per-project configure flows.
|
|
325
|
+
*/
|
|
326
|
+
async function promptModelSelection() {
|
|
200
327
|
const primaryChoices = getPrimaryChoices();
|
|
201
328
|
primaryChoices.push({
|
|
202
329
|
title: "Enter custom model ID",
|
|
203
330
|
description: "provider/model format",
|
|
204
331
|
value: "__custom__",
|
|
205
332
|
});
|
|
206
|
-
console.log("Primary agents (build, plan, debug) handle complex tasks.\nUse your best available model.\n");
|
|
333
|
+
console.log("Primary agents (build, plan, debug, review) handle complex tasks.\nUse your best available model.\n");
|
|
207
334
|
const { primaryModel } = await prompts({
|
|
208
335
|
type: "select",
|
|
209
336
|
name: "primaryModel",
|
|
@@ -211,7 +338,6 @@ async function configure() {
|
|
|
211
338
|
choices: primaryChoices,
|
|
212
339
|
hint: "Use arrow keys, Enter to confirm",
|
|
213
340
|
});
|
|
214
|
-
// User cancelled (Ctrl+C)
|
|
215
341
|
if (primaryModel === undefined) {
|
|
216
342
|
console.log("\nConfiguration cancelled.\n");
|
|
217
343
|
process.exit(0);
|
|
@@ -265,36 +391,54 @@ async function configure() {
|
|
|
265
391
|
subagent = custom;
|
|
266
392
|
}
|
|
267
393
|
console.log(`✓ Subagent model: ${subagent}\n`);
|
|
268
|
-
|
|
269
|
-
if (!config.agent)
|
|
270
|
-
config.agent = {};
|
|
271
|
-
for (const name of PRIMARY_AGENTS) {
|
|
272
|
-
if (!config.agent[name])
|
|
273
|
-
config.agent[name] = {};
|
|
274
|
-
config.agent[name].model = primary;
|
|
275
|
-
}
|
|
276
|
-
for (const name of SUBAGENTS) {
|
|
277
|
-
if (!config.agent[name])
|
|
278
|
-
config.agent[name] = {};
|
|
279
|
-
config.agent[name].model = subagent;
|
|
280
|
-
}
|
|
281
|
-
const targetPath = configInfo?.path || path.join(getGlobalDir(), "opencode.json");
|
|
282
|
-
writeConfig(targetPath, config);
|
|
283
|
-
// ── Print summary ──────────────────────────────────────────
|
|
284
|
-
console.log("━".repeat(50));
|
|
285
|
-
console.log(`✓ Configuration saved to ${targetPath}\n`);
|
|
286
|
-
console.log(" Primary agents:");
|
|
287
|
-
for (const name of PRIMARY_AGENTS) {
|
|
288
|
-
console.log(` ${name.padEnd(10)} → ${primary}`);
|
|
289
|
-
}
|
|
290
|
-
console.log("\n Subagents:");
|
|
291
|
-
for (const name of SUBAGENTS) {
|
|
292
|
-
console.log(` ${name.padEnd(10)} → ${subagent}`);
|
|
293
|
-
}
|
|
294
|
-
console.log("\nRestart OpenCode to apply changes.\n");
|
|
394
|
+
return { primary, subagent };
|
|
295
395
|
}
|
|
296
|
-
function configureReset() {
|
|
297
|
-
|
|
396
|
+
function configureReset(isProject = false) {
|
|
397
|
+
const scope = isProject ? "Per-Project" : "Global";
|
|
398
|
+
console.log(`\n🔧 Cortex Agents — Reset ${scope} Model Configuration\n`);
|
|
399
|
+
if (isProject) {
|
|
400
|
+
// Reset per-project config
|
|
401
|
+
const modelsPath = getProjectModelsPath();
|
|
402
|
+
let removedModels = false;
|
|
403
|
+
if (fs.existsSync(modelsPath)) {
|
|
404
|
+
fs.unlinkSync(modelsPath);
|
|
405
|
+
console.log(`✓ Removed ${modelsPath}`);
|
|
406
|
+
removedModels = true;
|
|
407
|
+
}
|
|
408
|
+
// Also clean agent models from local opencode.json
|
|
409
|
+
const localConfigPath = path.join(process.cwd(), "opencode.json");
|
|
410
|
+
if (fs.existsSync(localConfigPath)) {
|
|
411
|
+
const config = readConfig(localConfigPath);
|
|
412
|
+
if (config.agent) {
|
|
413
|
+
let resetCount = 0;
|
|
414
|
+
for (const name of ALL_AGENTS) {
|
|
415
|
+
if (config.agent[name]?.model) {
|
|
416
|
+
delete config.agent[name].model;
|
|
417
|
+
resetCount++;
|
|
418
|
+
if (Object.keys(config.agent[name]).length === 0) {
|
|
419
|
+
delete config.agent[name];
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
if (Object.keys(config.agent).length === 0) {
|
|
424
|
+
delete config.agent;
|
|
425
|
+
}
|
|
426
|
+
if (resetCount > 0) {
|
|
427
|
+
writeConfig(localConfigPath, config);
|
|
428
|
+
console.log(`✓ Removed ${resetCount} agent model entries from ${localConfigPath}`);
|
|
429
|
+
removedModels = true;
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
if (!removedModels) {
|
|
434
|
+
console.log("No per-project model configuration found. Nothing to reset.\n");
|
|
435
|
+
return;
|
|
436
|
+
}
|
|
437
|
+
console.log("\nAgents will now fall back to global or OpenCode default models.");
|
|
438
|
+
console.log("Restart OpenCode to apply changes.\n");
|
|
439
|
+
return;
|
|
440
|
+
}
|
|
441
|
+
// Global reset (existing behavior)
|
|
298
442
|
const configInfo = findOpencodeConfig();
|
|
299
443
|
if (!configInfo) {
|
|
300
444
|
console.log("No OpenCode config found. Nothing to reset.\n");
|
|
@@ -355,12 +499,20 @@ function status() {
|
|
|
355
499
|
: 0;
|
|
356
500
|
console.log(`\nAgents installed: ${agentCount}`);
|
|
357
501
|
console.log(`Skills installed: ${skillCount}`);
|
|
358
|
-
// Show model configuration
|
|
502
|
+
// Show per-project model configuration
|
|
503
|
+
const projectModels = readProjectModels();
|
|
504
|
+
if (projectModels) {
|
|
505
|
+
console.log("\nPer-Project Models (.opencode/models.json):");
|
|
506
|
+
console.log(` Primary agents: ${projectModels.primary.model}`);
|
|
507
|
+
console.log(` Subagents: ${projectModels.subagent.model}`);
|
|
508
|
+
}
|
|
509
|
+
// Show global/active model configuration
|
|
359
510
|
if (config.agent) {
|
|
360
511
|
const primaryModels = PRIMARY_AGENTS.map((n) => config.agent?.[n]?.model).filter(Boolean);
|
|
361
512
|
const subagentModels = SUBAGENTS.map((n) => config.agent?.[n]?.model).filter(Boolean);
|
|
362
513
|
if (primaryModels.length > 0 || subagentModels.length > 0) {
|
|
363
|
-
|
|
514
|
+
const source = projectModels ? "Active" : "Global";
|
|
515
|
+
console.log(`\n${source} Model Configuration (opencode.json):`);
|
|
364
516
|
if (primaryModels.length > 0) {
|
|
365
517
|
const unique = [...new Set(primaryModels)];
|
|
366
518
|
console.log(` Primary agents: ${unique.join(", ")}`);
|
|
@@ -370,14 +522,16 @@ function status() {
|
|
|
370
522
|
console.log(` Subagents: ${unique.join(", ")}`);
|
|
371
523
|
}
|
|
372
524
|
}
|
|
373
|
-
else {
|
|
525
|
+
else if (!projectModels) {
|
|
374
526
|
console.log("\nModels: Not configured (using OpenCode defaults)");
|
|
375
|
-
console.log(` Run 'npx ${PLUGIN_NAME} configure'
|
|
527
|
+
console.log(` Run 'npx ${PLUGIN_NAME} configure' for global config`);
|
|
528
|
+
console.log(` Run 'npx ${PLUGIN_NAME} configure --project' for per-project config`);
|
|
376
529
|
}
|
|
377
530
|
}
|
|
378
|
-
else {
|
|
531
|
+
else if (!projectModels) {
|
|
379
532
|
console.log("\nModels: Not configured (using OpenCode defaults)");
|
|
380
|
-
console.log(` Run 'npx ${PLUGIN_NAME} configure'
|
|
533
|
+
console.log(` Run 'npx ${PLUGIN_NAME} configure' for global config`);
|
|
534
|
+
console.log(` Run 'npx ${PLUGIN_NAME} configure --project' for per-project config`);
|
|
381
535
|
}
|
|
382
536
|
if (!isInstalled) {
|
|
383
537
|
console.log(`\nRun 'npx ${PLUGIN_NAME} install' to add to config.`);
|
|
@@ -395,27 +549,32 @@ USAGE:
|
|
|
395
549
|
|
|
396
550
|
COMMANDS:
|
|
397
551
|
install Install plugin, agents, and skills into OpenCode config
|
|
398
|
-
configure Interactive model selection
|
|
552
|
+
configure Interactive model selection (global)
|
|
553
|
+
configure --project Interactive model selection (per-project, saves to .opencode/)
|
|
399
554
|
configure --reset Reset model configuration to OpenCode defaults
|
|
555
|
+
configure --project --reset Reset per-project model configuration
|
|
400
556
|
uninstall Remove plugin, agents, skills, and model config
|
|
401
557
|
status Show installation and model configuration status
|
|
402
558
|
help Show this help message
|
|
403
559
|
|
|
404
560
|
EXAMPLES:
|
|
405
|
-
npx ${PLUGIN_NAME} install
|
|
406
|
-
npx ${PLUGIN_NAME} configure
|
|
407
|
-
npx ${PLUGIN_NAME} configure --
|
|
408
|
-
npx ${PLUGIN_NAME}
|
|
561
|
+
npx ${PLUGIN_NAME} install # Install plugin
|
|
562
|
+
npx ${PLUGIN_NAME} configure # Global model selection
|
|
563
|
+
npx ${PLUGIN_NAME} configure --project # Per-project models (.opencode/models.json)
|
|
564
|
+
npx ${PLUGIN_NAME} configure --reset # Reset global models
|
|
565
|
+
npx ${PLUGIN_NAME} configure --project --reset # Reset per-project models
|
|
566
|
+
npx ${PLUGIN_NAME} status # Check status
|
|
409
567
|
|
|
410
568
|
AGENTS:
|
|
411
|
-
Primary (build, plan, debug):
|
|
569
|
+
Primary (build, plan, debug, review):
|
|
412
570
|
Handle complex tasks — select your best model.
|
|
413
571
|
|
|
414
572
|
Subagents (fullstack, testing, security, devops):
|
|
415
573
|
Handle focused tasks — a fast/cheap model works great.
|
|
416
574
|
|
|
417
|
-
TOOLS (
|
|
575
|
+
TOOLS (23):
|
|
418
576
|
cortex_init, cortex_status .cortex directory management
|
|
577
|
+
cortex_configure Per-project model configuration
|
|
419
578
|
worktree_create, worktree_list Git worktree management
|
|
420
579
|
worktree_remove, worktree_open
|
|
421
580
|
worktree_launch Launch worktree (terminal/PTY/background)
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAmJlD,eAAO,MAAM,YAAY,EAAE,MAuJ1B,CAAC;AAGF,eAAe,YAAY,CAAC"}
|