cortex-agents 2.3.0 → 3.4.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.
Files changed (54) hide show
  1. package/.opencode/agents/{plan.md → architect.md} +104 -45
  2. package/.opencode/agents/audit.md +314 -0
  3. package/.opencode/agents/crosslayer.md +218 -0
  4. package/.opencode/agents/{debug.md → fix.md} +75 -46
  5. package/.opencode/agents/guard.md +202 -0
  6. package/.opencode/agents/{build.md → implement.md} +151 -107
  7. package/.opencode/agents/qa.md +265 -0
  8. package/.opencode/agents/ship.md +249 -0
  9. package/README.md +119 -31
  10. package/dist/cli.js +87 -16
  11. package/dist/index.d.ts.map +1 -1
  12. package/dist/index.js +215 -9
  13. package/dist/registry.d.ts +8 -3
  14. package/dist/registry.d.ts.map +1 -1
  15. package/dist/registry.js +16 -2
  16. package/dist/tools/cortex.d.ts +2 -2
  17. package/dist/tools/cortex.js +7 -7
  18. package/dist/tools/environment.d.ts +31 -0
  19. package/dist/tools/environment.d.ts.map +1 -0
  20. package/dist/tools/environment.js +93 -0
  21. package/dist/tools/github.d.ts +42 -0
  22. package/dist/tools/github.d.ts.map +1 -0
  23. package/dist/tools/github.js +200 -0
  24. package/dist/tools/repl.d.ts +50 -0
  25. package/dist/tools/repl.d.ts.map +1 -0
  26. package/dist/tools/repl.js +240 -0
  27. package/dist/tools/task.d.ts +2 -0
  28. package/dist/tools/task.d.ts.map +1 -1
  29. package/dist/tools/task.js +25 -30
  30. package/dist/tools/worktree.d.ts.map +1 -1
  31. package/dist/tools/worktree.js +22 -11
  32. package/dist/utils/github.d.ts +104 -0
  33. package/dist/utils/github.d.ts.map +1 -0
  34. package/dist/utils/github.js +243 -0
  35. package/dist/utils/ide.d.ts +76 -0
  36. package/dist/utils/ide.d.ts.map +1 -0
  37. package/dist/utils/ide.js +307 -0
  38. package/dist/utils/plan-extract.d.ts +7 -0
  39. package/dist/utils/plan-extract.d.ts.map +1 -1
  40. package/dist/utils/plan-extract.js +25 -1
  41. package/dist/utils/repl.d.ts +114 -0
  42. package/dist/utils/repl.d.ts.map +1 -0
  43. package/dist/utils/repl.js +434 -0
  44. package/dist/utils/terminal.d.ts +53 -1
  45. package/dist/utils/terminal.d.ts.map +1 -1
  46. package/dist/utils/terminal.js +642 -5
  47. package/package.json +1 -1
  48. package/.opencode/agents/devops.md +0 -176
  49. package/.opencode/agents/fullstack.md +0 -171
  50. package/.opencode/agents/security.md +0 -148
  51. package/.opencode/agents/testing.md +0 -132
  52. package/dist/plugin.d.ts +0 -1
  53. package/dist/plugin.d.ts.map +0 -1
  54. package/dist/plugin.js +0 -4
package/dist/cli.js CHANGED
@@ -3,8 +3,8 @@ import * as fs from "fs";
3
3
  import * as path from "path";
4
4
  import { fileURLToPath } from "url";
5
5
  import prompts from "prompts";
6
- import { PRIMARY_AGENTS, SUBAGENTS, ALL_AGENTS, getPrimaryChoices, getSubagentChoices, } from "./registry.js";
7
- const VERSION = "2.3.0";
6
+ import { PRIMARY_AGENTS, SUBAGENTS, ALL_AGENTS, DISABLED_BUILTIN_AGENTS, STALE_AGENT_FILES, getPrimaryChoices, getSubagentChoices, } from "./registry.js";
7
+ const VERSION = "3.4.0";
8
8
  const PLUGIN_NAME = "cortex-agents";
9
9
  const __filename = fileURLToPath(import.meta.url);
10
10
  const __dirname = path.dirname(__filename);
@@ -138,6 +138,23 @@ function installAgentsAndSkills(targetDir) {
138
138
  console.log(` Installed ${count} skills -> ${skillsDest}`);
139
139
  }
140
140
  }
141
+ function cleanupStaleAgents(globalDir) {
142
+ const agentsDir = path.join(globalDir, "agents");
143
+ if (!fs.existsSync(agentsDir))
144
+ return;
145
+ for (const file of STALE_AGENT_FILES) {
146
+ const filePath = path.join(agentsDir, file);
147
+ try {
148
+ if (fs.existsSync(filePath)) {
149
+ fs.unlinkSync(filePath);
150
+ console.log(` Cleaned up stale agent: ${file}`);
151
+ }
152
+ }
153
+ catch (err) {
154
+ console.warn(` Warning: Could not remove stale agent ${file}: ${err.message}`);
155
+ }
156
+ }
157
+ }
141
158
  function removeAgentsAndSkills(targetDir) {
142
159
  const agentsSrc = path.join(PACKAGE_OPENCODE_DIR, "agents");
143
160
  const skillsSrc = path.join(PACKAGE_OPENCODE_DIR, "skills");
@@ -173,9 +190,15 @@ function install() {
173
190
  fs.mkdirSync(globalDir, { recursive: true });
174
191
  }
175
192
  const globalPath = path.join(globalDir, "opencode.json");
193
+ const disabledAgents = {};
194
+ for (const name of DISABLED_BUILTIN_AGENTS) {
195
+ disabledAgents[name] = { disable: true };
196
+ }
176
197
  const newConfig = {
177
198
  $schema: "https://opencode.ai/config.json",
178
199
  plugin: [PLUGIN_NAME],
200
+ default_agent: "architect",
201
+ agent: disabledAgents,
179
202
  };
180
203
  writeConfig(globalPath, newConfig);
181
204
  console.log(`Created config: ${globalPath}`);
@@ -187,16 +210,26 @@ function install() {
187
210
  config.plugin = [];
188
211
  if (!config.plugin.includes(PLUGIN_NAME)) {
189
212
  config.plugin.push(PLUGIN_NAME);
190
- writeConfig(configInfo.path, config);
191
- console.log(`Added plugin to config: ${configInfo.path}\n`);
192
213
  }
193
- else {
194
- console.log(`Plugin already in config: ${configInfo.path}\n`);
214
+ // Disable built-in agents that cortex-agents replaces
215
+ if (!config.agent)
216
+ config.agent = {};
217
+ for (const name of DISABLED_BUILTIN_AGENTS) {
218
+ if (!config.agent[name])
219
+ config.agent[name] = {};
220
+ config.agent[name].disable = true;
195
221
  }
222
+ // Set default_agent, clean legacy camelCase key
223
+ config.default_agent = "architect";
224
+ delete config.defaultAgent;
225
+ writeConfig(configInfo.path, config);
226
+ console.log(`Updated config: ${configInfo.path}\n`);
196
227
  }
197
228
  // Copy agents and skills into the global opencode config dir
198
229
  console.log("Installing agents and skills...");
199
230
  installAgentsAndSkills(globalDir);
231
+ // Clean up stale agent files from previous cortex-agents versions
232
+ cleanupStaleAgents(globalDir);
200
233
  // Sync per-project models if .opencode/models.json exists
201
234
  if (hasProjectModelsConfig()) {
202
235
  console.log("\nPer-project model config found (.opencode/models.json)");
@@ -233,11 +266,23 @@ function uninstall() {
233
266
  }
234
267
  }
235
268
  }
269
+ // Re-enable built-in agents
270
+ for (const name of DISABLED_BUILTIN_AGENTS) {
271
+ if (config.agent[name]) {
272
+ delete config.agent[name].disable;
273
+ if (Object.keys(config.agent[name]).length === 0) {
274
+ delete config.agent[name];
275
+ }
276
+ }
277
+ }
236
278
  // Clean up empty agent object
237
279
  if (Object.keys(config.agent).length === 0) {
238
280
  delete config.agent;
239
281
  }
240
282
  }
283
+ // Remove default_agent + clean legacy key
284
+ delete config.default_agent;
285
+ delete config.defaultAgent;
241
286
  writeConfig(configInfo.path, config);
242
287
  // Remove agents and skills
243
288
  const globalDir = getGlobalDir();
@@ -276,6 +321,12 @@ async function configure() {
276
321
  config.plugin = [];
277
322
  config.plugin.push(PLUGIN_NAME);
278
323
  }
324
+ // Set default agent to architect (planning-first workflow)
325
+ if (!config.default_agent) {
326
+ config.default_agent = "architect";
327
+ }
328
+ // Clean legacy camelCase key
329
+ delete config.defaultAgent;
279
330
  // ── Primary model selection ────────────────────────────────
280
331
  const { primary, subagent } = await promptModelSelection();
281
332
  // ── Write config ───────────────────────────────────────────
@@ -283,6 +334,14 @@ async function configure() {
283
334
  // Per-project: write .opencode/models.json + sync to local opencode.json
284
335
  writeProjectModels(primary, subagent);
285
336
  syncProjectModelsToConfig();
337
+ // Ensure default agent is set in local opencode.json
338
+ const localConfig = readConfig(path.join(process.cwd(), "opencode.json"));
339
+ if (!localConfig.default_agent) {
340
+ localConfig.default_agent = "architect";
341
+ }
342
+ // Clean legacy camelCase key
343
+ delete localConfig.defaultAgent;
344
+ writeConfig(path.join(process.cwd(), "opencode.json"), localConfig);
286
345
  const modelsPath = getProjectModelsPath();
287
346
  const localConfigPath = path.join(process.cwd(), "opencode.json");
288
347
  console.log("━".repeat(50));
@@ -304,6 +363,12 @@ async function configure() {
304
363
  config.agent[name] = {};
305
364
  config.agent[name].model = subagent;
306
365
  }
366
+ // Re-assert disable entries for built-in agents
367
+ for (const name of DISABLED_BUILTIN_AGENTS) {
368
+ if (!config.agent[name])
369
+ config.agent[name] = {};
370
+ config.agent[name].disable = true;
371
+ }
307
372
  const targetPath = configInfo?.path || path.join(getGlobalDir(), "opencode.json");
308
373
  writeConfig(targetPath, config);
309
374
  console.log("━".repeat(50));
@@ -330,7 +395,7 @@ async function promptModelSelection() {
330
395
  description: "provider/model format",
331
396
  value: "__custom__",
332
397
  });
333
- console.log("Primary agents (build, plan, debug) handle complex tasks.\nUse your best available model.\n");
398
+ console.log("Primary agents (implement, architect, fix, audit) handle complex tasks.\nUse your best available model.\n");
334
399
  const { primaryModel } = await prompts({
335
400
  type: "select",
336
401
  name: "primaryModel",
@@ -364,7 +429,7 @@ async function promptModelSelection() {
364
429
  description: "provider/model format",
365
430
  value: "__custom__",
366
431
  });
367
- console.log("Subagents (fullstack, testing, security, devops) handle focused tasks.\nA faster/cheaper model works great here.\n");
432
+ console.log("Subagents (crosslayer, qa, guard, ship) handle focused tasks.\nA faster/cheaper model works great here.\n");
368
433
  const { subagentModel } = await prompts({
369
434
  type: "select",
370
435
  name: "subagentModel",
@@ -566,18 +631,20 @@ EXAMPLES:
566
631
  npx ${PLUGIN_NAME} status # Check status
567
632
 
568
633
  AGENTS:
569
- Primary (build, plan, debug):
634
+ Primary (implement, architect, fix, audit):
570
635
  Handle complex tasks — select your best model.
571
636
 
572
- Subagents (fullstack, testing, security, devops):
637
+ Subagents (crosslayer, qa, guard, ship):
573
638
  Handle focused tasks — a fast/cheap model works great.
574
639
 
575
- TOOLS (23):
640
+ TOOLS (32):
576
641
  cortex_init, cortex_status .cortex directory management
577
642
  cortex_configure Per-project model configuration
578
643
  worktree_create, worktree_list Git worktree management
579
644
  worktree_remove, worktree_open
580
645
  worktree_launch Launch worktree (terminal/PTY/background)
646
+ detect_environment Detect IDE/terminal for launch options
647
+ get_environment_info Quick environment info for agents
581
648
  branch_create, branch_status Git branch operations
582
649
  branch_switch
583
650
  plan_save, plan_list Plan persistence
@@ -587,13 +654,17 @@ TOOLS (23):
587
654
  docs_init, docs_save Mermaid documentation
588
655
  docs_list, docs_index
589
656
  task_finalize Commit, push, and create PR
657
+ github_status, github_issues GitHub issue and project browsing
658
+ github_projects
659
+ repl_init, repl_status Iterative task-by-task implementation loop
660
+ repl_report, repl_summary
590
661
 
591
662
  SKILLS (14):
592
- web-development, frontend-development, backend-development,
593
- mobile-development, desktop-development, database-design,
594
- api-design, architecture-patterns, design-patterns,
595
- testing-strategies, security-hardening, deployment-automation,
596
- performance-optimization, code-quality, git-workflow
663
+ frontend-development, backend-development, mobile-development,
664
+ desktop-development, database-design, api-design,
665
+ architecture-patterns, design-patterns, testing-strategies,
666
+ security-hardening, deployment-automation, performance-optimization,
667
+ code-quality, git-workflow
597
668
  `);
598
669
  }
599
670
  // ─── CLI Entry Point ─────────────────────────────────────────────────────────
@@ -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;AAsBlD,eAAO,MAAM,YAAY,EAAE,MAmE1B,CAAC;AAGF,eAAe,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAiLlD,eAAO,MAAM,YAAY,EAAE,MAsK1B,CAAC;AAGF,eAAe,YAAY,CAAC"}
package/dist/index.js CHANGED
@@ -6,16 +6,133 @@ import * as plan from "./tools/plan";
6
6
  import * as session from "./tools/session";
7
7
  import * as docs from "./tools/docs";
8
8
  import * as task from "./tools/task";
9
- // Agent descriptions for handover toast notifications
9
+ import * as environment from "./tools/environment";
10
+ import * as github from "./tools/github";
11
+ import * as repl from "./tools/repl";
12
+ // ─── Agent Descriptions (for handover toasts) ───────────────────────────────
10
13
  const AGENT_DESCRIPTIONS = {
11
- build: "Development mode — ready to implement",
12
- plan: "Planning mode — read-only analysis",
13
- debug: "Debug mode — troubleshooting and fixes",
14
- fullstack: "Fullstack subagentend-to-end implementation",
15
- testing: "Testing subagent — writing tests",
16
- security: "Security subagent — vulnerability audit",
17
- devops: "DevOps subagent — CI/CD and deployment",
14
+ implement: "Development mode — ready to implement",
15
+ architect: "Planning mode — read-only analysis",
16
+ fix: "Debug mode — troubleshooting and fixes",
17
+ audit: "Review modecode quality assessment",
18
+ crosslayer: "Crosslayer subagent — end-to-end implementation",
19
+ qa: "QA subagent — writing tests",
20
+ guard: "Security subagent — vulnerability audit",
21
+ ship: "DevOps subagent — CI/CD and deployment",
18
22
  };
23
+ const TOOL_NOTIFICATIONS = {
24
+ task_finalize: {
25
+ successTitle: "Task Finalized",
26
+ successMsg: (args) => `Committed & pushed: ${(args.commitMessage ?? "").substring(0, 50)}`,
27
+ errorTitle: "Finalization Failed",
28
+ errorMsg: (_, out) => out
29
+ .replace(/^✗\s*/, "")
30
+ .split("\n")[0]
31
+ .substring(0, 100),
32
+ successDuration: 5000,
33
+ errorDuration: 10000,
34
+ },
35
+ plan_save: {
36
+ successTitle: "Plan Saved",
37
+ successMsg: (args) => args.title ?? "Plan saved",
38
+ errorTitle: "Plan Save Failed",
39
+ errorMsg: (_, out) => out.substring(0, 100),
40
+ },
41
+ plan_delete: {
42
+ successTitle: "Plan Deleted",
43
+ successMsg: (args) => args.filename ?? "Plan deleted",
44
+ errorTitle: "Plan Delete Failed",
45
+ errorMsg: (_, out) => out.substring(0, 100),
46
+ },
47
+ session_save: {
48
+ successTitle: "Session Saved",
49
+ successMsg: () => "Session summary recorded",
50
+ errorTitle: "Session Save Failed",
51
+ errorMsg: (_, out) => out.substring(0, 100),
52
+ },
53
+ docs_save: {
54
+ successTitle: "Documentation Saved",
55
+ successMsg: (args) => `${args.type ?? "doc"}: ${args.title ?? "Untitled"}`,
56
+ errorTitle: "Doc Save Failed",
57
+ errorMsg: (_, out) => out.substring(0, 100),
58
+ },
59
+ docs_init: {
60
+ successTitle: "Docs Initialized",
61
+ successMsg: () => "Documentation directory created",
62
+ errorTitle: "Docs Init Failed",
63
+ errorMsg: (_, out) => out.substring(0, 100),
64
+ },
65
+ cortex_init: {
66
+ successTitle: "Project Initialized",
67
+ successMsg: () => ".cortex directory created",
68
+ errorTitle: "Init Failed",
69
+ errorMsg: (_, out) => out.substring(0, 100),
70
+ },
71
+ cortex_configure: {
72
+ successTitle: "Models Configured",
73
+ successMsg: (args) => `Primary: ${args.primaryModel?.split("/").pop() || "set"}`,
74
+ errorTitle: "Configure Failed",
75
+ errorMsg: (_, out) => out.substring(0, 100),
76
+ },
77
+ branch_switch: {
78
+ successTitle: "Branch Switched",
79
+ successMsg: (args) => `Now on ${args.branch ?? "branch"}`,
80
+ errorTitle: "Branch Switch Failed",
81
+ errorMsg: (_, out) => out
82
+ .replace(/^✗\s*/, "")
83
+ .split("\n")[0]
84
+ .substring(0, 100),
85
+ },
86
+ github_status: {
87
+ successTitle: "GitHub Connected",
88
+ successMsg: (_args, output) => {
89
+ const repoMatch = output.match(/Repository:\s+(.+)/);
90
+ return repoMatch ? `Connected to ${repoMatch[1].substring(0, 100)}` : "GitHub CLI available";
91
+ },
92
+ errorTitle: "GitHub Not Available",
93
+ errorMsg: (_, out) => out
94
+ .replace(/^✗\s*/, "")
95
+ .split("\n")[0]
96
+ .substring(0, 100),
97
+ },
98
+ repl_init: {
99
+ successTitle: "REPL Loop Started",
100
+ successMsg: (args) => `${(args.planFilename ?? "Plan").split("/").pop()?.substring(0, 40)} — tasks loaded`,
101
+ errorTitle: "REPL Init Failed",
102
+ errorMsg: (_, out) => out.substring(0, 100),
103
+ },
104
+ repl_report: {
105
+ successTitle: "Task Update",
106
+ successMsg: (args) => `Result: ${args.result ?? "reported"}`,
107
+ errorTitle: "Report Failed",
108
+ errorMsg: (_, out) => out.substring(0, 100),
109
+ },
110
+ };
111
+ // ─── Error Message Extraction ────────────────────────────────────────────────
112
+ //
113
+ // Extracts a human-readable message from the session error union type
114
+ // (ProviderAuthError | UnknownError | MessageOutputLengthError |
115
+ // MessageAbortedError | ApiError).
116
+ function extractErrorMessage(error) {
117
+ if (!error)
118
+ return "An unknown error occurred";
119
+ const msg = typeof error.data?.message === "string" ? error.data.message : "";
120
+ switch (error.name) {
121
+ case "ProviderAuthError":
122
+ return `Auth error: ${msg || "Provider authentication failed"}`;
123
+ case "UnknownError":
124
+ return msg || "An unknown error occurred";
125
+ case "MessageOutputLengthError":
126
+ return "Output length exceeded — try compacting the session";
127
+ case "MessageAbortedError":
128
+ return `Aborted: ${msg || "Message was aborted"}`;
129
+ case "APIError":
130
+ return `API error: ${msg || "Request failed"}`;
131
+ default:
132
+ return `Error: ${error.name}`;
133
+ }
134
+ }
135
+ // ─── Plugin Entry ────────────────────────────────────────────────────────────
19
136
  export const CortexPlugin = async (ctx) => {
20
137
  return {
21
138
  tool: {
@@ -49,10 +166,62 @@ export const CortexPlugin = async (ctx) => {
49
166
  docs_index: docs.index,
50
167
  // Task tools - finalize workflow (commit, push, PR)
51
168
  task_finalize: task.finalize,
169
+ // Environment tools - IDE/terminal detection for contextual options
170
+ detect_environment: environment.detectEnvironment,
171
+ get_environment_info: environment.getEnvironmentInfo,
172
+ // GitHub integration tools - work item listing, issue selection, project boards
173
+ github_status: github.status,
174
+ github_issues: github.issues,
175
+ github_projects: github.projects,
176
+ // REPL loop tools - iterative task-by-task implementation
177
+ repl_init: repl.init,
178
+ repl_status: repl.status,
179
+ repl_report: repl.report,
180
+ repl_summary: repl.summary,
52
181
  },
53
- // Agent handover toast notifications
182
+ // ── Post-execution toast notifications ────────────────────────────────
183
+ //
184
+ // Fires after every tool execution. Uses the TOOL_NOTIFICATIONS map
185
+ // to determine which tools get toasts and what content to display.
186
+ // Tools with existing factory-based toasts are excluded from the map.
187
+ "tool.execute.after": async (input, output) => {
188
+ const config = TOOL_NOTIFICATIONS[input.tool];
189
+ if (!config)
190
+ return; // No notification configured for this tool
191
+ try {
192
+ const result = output.output;
193
+ const isSuccess = result.startsWith("✓");
194
+ const isError = result.startsWith("✗");
195
+ if (isSuccess) {
196
+ await ctx.client.tui.showToast({
197
+ body: {
198
+ title: config.successTitle,
199
+ message: config.successMsg(input.args, result),
200
+ variant: "success",
201
+ duration: config.successDuration ?? 4000,
202
+ },
203
+ });
204
+ }
205
+ else if (isError) {
206
+ await ctx.client.tui.showToast({
207
+ body: {
208
+ title: config.errorTitle,
209
+ message: config.errorMsg(input.args, result),
210
+ variant: "error",
211
+ duration: config.errorDuration ?? 8000,
212
+ },
213
+ });
214
+ }
215
+ // Informational or warning outputs (⚠) — no toast to avoid noise
216
+ }
217
+ catch {
218
+ // Toast failure is non-fatal
219
+ }
220
+ },
221
+ // ── Event-driven notifications ───────────────────────────────────────
54
222
  async event({ event }) {
55
223
  try {
224
+ // Agent handover notifications
56
225
  if (event.type === "message.part.updated" &&
57
226
  "part" in event.properties &&
58
227
  event.properties.part.type === "agent") {
@@ -67,6 +236,43 @@ export const CortexPlugin = async (ctx) => {
67
236
  },
68
237
  });
69
238
  }
239
+ // Session error notifications
240
+ if (event.type === "session.error") {
241
+ const rawError = event.properties.error;
242
+ // Runtime validation before cast — ensure error has expected shape
243
+ const error = rawError &&
244
+ typeof rawError === "object" &&
245
+ "name" in rawError &&
246
+ typeof rawError.name === "string"
247
+ ? rawError
248
+ : undefined;
249
+ const message = extractErrorMessage(error);
250
+ await ctx.client.tui.showToast({
251
+ body: {
252
+ title: "Session Error",
253
+ message,
254
+ variant: "error",
255
+ duration: 10000,
256
+ },
257
+ });
258
+ }
259
+ // PTY exited notifications (relevant for worktree terminal sessions)
260
+ if (event.type === "pty.exited") {
261
+ const rawExitCode = event.properties.exitCode;
262
+ const exitCode = typeof rawExitCode === "number" && Number.isInteger(rawExitCode)
263
+ ? rawExitCode
264
+ : -1;
265
+ await ctx.client.tui.showToast({
266
+ body: {
267
+ title: "Terminal Exited",
268
+ message: exitCode === 0
269
+ ? "Terminal session completed successfully"
270
+ : `Terminal exited with code ${exitCode}`,
271
+ variant: exitCode === 0 ? "success" : "warning",
272
+ duration: exitCode === 0 ? 4000 : 8000,
273
+ },
274
+ });
275
+ }
70
276
  }
71
277
  catch {
72
278
  // Toast failure is non-fatal — silently ignore
@@ -19,11 +19,16 @@ export interface ModelEntry {
19
19
  }
20
20
  export declare const MODEL_REGISTRY: ModelEntry[];
21
21
  /** Primary agents receive the best available model */
22
- export declare const PRIMARY_AGENTS: readonly ["build", "plan", "debug"];
22
+ export declare const PRIMARY_AGENTS: readonly ["implement", "architect", "fix", "audit"];
23
23
  /** Subagents receive a fast/cost-effective model */
24
- export declare const SUBAGENTS: readonly ["fullstack", "testing", "security", "devops"];
24
+ export declare const SUBAGENTS: readonly ["crosslayer", "qa", "guard", "ship"];
25
25
  /** All agent names combined */
26
- export declare const ALL_AGENTS: readonly ["build", "plan", "debug", "fullstack", "testing", "security", "devops"];
26
+ export declare const ALL_AGENTS: readonly ["implement", "architect", "fix", "audit", "crosslayer", "qa", "guard", "ship"];
27
+ /** OpenCode built-in agents disabled when cortex-agents is installed.
28
+ * Replaced by cortex equivalents: build → implement, plan → architect */
29
+ export declare const DISABLED_BUILTIN_AGENTS: readonly ["build", "plan"];
30
+ /** Old agent files to clean up from previous cortex-agents versions */
31
+ export declare const STALE_AGENT_FILES: readonly ["build.md", "plan.md", "debug.md", "review.md", "fullstack.md", "testing.md", "security.md", "devops.md"];
27
32
  /**
28
33
  * Build the interactive choices list for primary model selection.
29
34
  * Shows premium and standard tier models (excluding fast).
@@ -1 +1 @@
1
- {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,WAAW,UAAU;IACzB,uDAAuD;IACvD,EAAE,EAAE,MAAM,CAAC;IACX,kCAAkC;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,4BAA4B;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,2CAA2C;IAC3C,IAAI,EAAE,SAAS,GAAG,UAAU,GAAG,MAAM,CAAC;IACtC,oDAAoD;IACpD,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,eAAO,MAAM,cAAc,EAAE,UAAU,EAuGtC,CAAC;AAEF,sDAAsD;AACtD,eAAO,MAAM,cAAc,qCAAsC,CAAC;AAElE,oDAAoD;AACpD,eAAO,MAAM,SAAS,yDAA0D,CAAC;AAEjF,+BAA+B;AAC/B,eAAO,MAAM,UAAU,mFAA6C,CAAC;AAErE;;;GAGG;AACH,wBAAgB,iBAAiB;;;;IAMhC;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,cAAc,EAAE,MAAM;;;;IAcxD"}
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,WAAW,UAAU;IACzB,uDAAuD;IACvD,EAAE,EAAE,MAAM,CAAC;IACX,kCAAkC;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,4BAA4B;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,2CAA2C;IAC3C,IAAI,EAAE,SAAS,GAAG,UAAU,GAAG,MAAM,CAAC;IACtC,oDAAoD;IACpD,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,eAAO,MAAM,cAAc,EAAE,UAAU,EAuGtC,CAAC;AAEF,sDAAsD;AACtD,eAAO,MAAM,cAAc,qDAAsD,CAAC;AAElF,oDAAoD;AACpD,eAAO,MAAM,SAAS,gDAAiD,CAAC;AAExE,+BAA+B;AAC/B,eAAO,MAAM,UAAU,0FAA6C,CAAC;AAErE;0EAC0E;AAC1E,eAAO,MAAM,uBAAuB,4BAA6B,CAAC;AAElE,uEAAuE;AACvE,eAAO,MAAM,iBAAiB,qHASpB,CAAC;AAEX;;;GAGG;AACH,wBAAgB,iBAAiB;;;;IAMhC;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,cAAc,EAAE,MAAM;;;;IAcxD"}
package/dist/registry.js CHANGED
@@ -105,11 +105,25 @@ export const MODEL_REGISTRY = [
105
105
  },
106
106
  ];
107
107
  /** Primary agents receive the best available model */
108
- export const PRIMARY_AGENTS = ["build", "plan", "debug"];
108
+ export const PRIMARY_AGENTS = ["implement", "architect", "fix", "audit"];
109
109
  /** Subagents receive a fast/cost-effective model */
110
- export const SUBAGENTS = ["fullstack", "testing", "security", "devops"];
110
+ export const SUBAGENTS = ["crosslayer", "qa", "guard", "ship"];
111
111
  /** All agent names combined */
112
112
  export const ALL_AGENTS = [...PRIMARY_AGENTS, ...SUBAGENTS];
113
+ /** OpenCode built-in agents disabled when cortex-agents is installed.
114
+ * Replaced by cortex equivalents: build → implement, plan → architect */
115
+ export const DISABLED_BUILTIN_AGENTS = ["build", "plan"];
116
+ /** Old agent files to clean up from previous cortex-agents versions */
117
+ export const STALE_AGENT_FILES = [
118
+ "build.md",
119
+ "plan.md",
120
+ "debug.md",
121
+ "review.md",
122
+ "fullstack.md",
123
+ "testing.md",
124
+ "security.md",
125
+ "devops.md",
126
+ ];
113
127
  /**
114
128
  * Build the interactive choices list for primary model selection.
115
129
  * Shows premium and standard tier models (excluding fast).
@@ -12,8 +12,8 @@ export declare const status: {
12
12
  /**
13
13
  * cortex_configure — Write per-project model configuration to ./opencode.json.
14
14
  *
15
- * Accepts a primary model (for build/plan/debug) and a subagent model
16
- * (for fullstack/testing/security/devops). Merges into any existing
15
+ * Accepts a primary model (for implement/architect/fix/audit) and a subagent model
16
+ * (for crosslayer/qa/guard/ship). Merges into any existing
17
17
  * opencode.json at the project root, preserving other settings.
18
18
  */
19
19
  export declare const configure: {
@@ -151,13 +151,13 @@ Plans: ${planCount}`;
151
151
  /**
152
152
  * cortex_configure — Write per-project model configuration to ./opencode.json.
153
153
  *
154
- * Accepts a primary model (for build/plan/debug) and a subagent model
155
- * (for fullstack/testing/security/devops). Merges into any existing
154
+ * Accepts a primary model (for implement/architect/fix/audit) and a subagent model
155
+ * (for crosslayer/qa/guard/ship). Merges into any existing
156
156
  * opencode.json at the project root, preserving other settings.
157
157
  */
158
158
  export const configure = tool({
159
159
  description: "Save per-project model configuration to ./opencode.json. " +
160
- "Sets the model for primary agents (build, plan, debug) and subagents (fullstack, testing, security, devops). " +
160
+ "Sets the model for primary agents (implement, architect, fix, audit) and subagents (crosslayer, qa, guard, ship). " +
161
161
  "Available models — Premium: " +
162
162
  MODEL_REGISTRY.filter((m) => m.tier === "premium")
163
163
  .map((m) => `${m.name} (${m.id})`)
@@ -174,10 +174,10 @@ export const configure = tool({
174
174
  args: {
175
175
  primaryModel: z
176
176
  .string()
177
- .describe("Model ID for primary agents (build, plan, debug). Format: provider/model-name"),
177
+ .describe("Model ID for primary agents (implement, architect, fix, audit). Format: provider/model-name"),
178
178
  subagentModel: z
179
179
  .string()
180
- .describe("Model ID for subagents (fullstack, testing, security, devops). Format: provider/model-name"),
180
+ .describe("Model ID for subagents (crosslayer, qa, guard, ship). Format: provider/model-name"),
181
181
  },
182
182
  async execute(args, context) {
183
183
  const configPath = path.join(context.worktree, "opencode.json");
@@ -246,10 +246,10 @@ export const configure = tool({
246
246
  return `✓ Model configuration saved to:
247
247
  ${savedTo}
248
248
 
249
- Primary agents (build, plan, debug):
249
+ Primary agents (implement, architect, fix, audit):
250
250
  → ${primaryDisplay} (${args.primaryModel})
251
251
 
252
- Subagents (fullstack, testing, security, devops):
252
+ Subagents (crosslayer, qa, guard, ship):
253
253
  → ${subagentDisplay} (${args.subagentModel})
254
254
 
255
255
  Restart OpenCode to apply changes.`;
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Environment Detection Tool
3
+ *
4
+ * Provides agents with information about the current development environment
5
+ * (IDE, terminal, editor) to offer contextually appropriate worktree launch options.
6
+ *
7
+ * Uses two detection systems:
8
+ * - IDE detection (ide.ts) — for "Open in IDE" options
9
+ * - Terminal detection (terminal.ts) — for "Open in terminal tab" options
10
+ *
11
+ * The terminal detection uses a multi-strategy chain:
12
+ * 1. Environment variables (fast, synchronous)
13
+ * 2. Process-tree walk (finds terminal in parent processes)
14
+ * 3. Frontmost app detection (macOS only)
15
+ * 4. User preference (.cortex/config.json)
16
+ */
17
+ export declare const detectEnvironment: {
18
+ description: string;
19
+ args: {};
20
+ execute(args: Record<string, never>, context: import("@opencode-ai/plugin").ToolContext): Promise<string>;
21
+ };
22
+ /**
23
+ * Quick environment check tool for agents.
24
+ * Returns a simplified response for quick decision-making.
25
+ */
26
+ export declare const getEnvironmentInfo: {
27
+ description: string;
28
+ args: {};
29
+ execute(args: Record<string, never>, context: import("@opencode-ai/plugin").ToolContext): Promise<string>;
30
+ };
31
+ //# sourceMappingURL=environment.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"environment.d.ts","sourceRoot":"","sources":["../../src/tools/environment.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAMH,eAAO,MAAM,iBAAiB;;;;CAgD5B,CAAC;AAEH;;;GAGG;AACH,eAAO,MAAM,kBAAkB;;;;CA4B7B,CAAC"}