cortex-agents 2.3.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/dist/index.js CHANGED
@@ -6,7 +6,7 @@ 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
+ // ─── Agent Descriptions (for handover toasts) ───────────────────────────────
10
10
  const AGENT_DESCRIPTIONS = {
11
11
  build: "Development mode — ready to implement",
12
12
  plan: "Planning mode — read-only analysis",
@@ -16,6 +16,95 @@ const AGENT_DESCRIPTIONS = {
16
16
  security: "Security subagent — vulnerability audit",
17
17
  devops: "DevOps subagent — CI/CD and deployment",
18
18
  };
19
+ const TOOL_NOTIFICATIONS = {
20
+ task_finalize: {
21
+ successTitle: "Task Finalized",
22
+ successMsg: (args) => `Committed & pushed: ${(args.commitMessage ?? "").substring(0, 50)}`,
23
+ errorTitle: "Finalization Failed",
24
+ errorMsg: (_, out) => out
25
+ .replace(/^✗\s*/, "")
26
+ .split("\n")[0]
27
+ .substring(0, 100),
28
+ successDuration: 5000,
29
+ errorDuration: 10000,
30
+ },
31
+ plan_save: {
32
+ successTitle: "Plan Saved",
33
+ successMsg: (args) => args.title ?? "Plan saved",
34
+ errorTitle: "Plan Save Failed",
35
+ errorMsg: (_, out) => out.substring(0, 100),
36
+ },
37
+ plan_delete: {
38
+ successTitle: "Plan Deleted",
39
+ successMsg: (args) => args.filename ?? "Plan deleted",
40
+ errorTitle: "Plan Delete Failed",
41
+ errorMsg: (_, out) => out.substring(0, 100),
42
+ },
43
+ session_save: {
44
+ successTitle: "Session Saved",
45
+ successMsg: () => "Session summary recorded",
46
+ errorTitle: "Session Save Failed",
47
+ errorMsg: (_, out) => out.substring(0, 100),
48
+ },
49
+ docs_save: {
50
+ successTitle: "Documentation Saved",
51
+ successMsg: (args) => `${args.type ?? "doc"}: ${args.title ?? "Untitled"}`,
52
+ errorTitle: "Doc Save Failed",
53
+ errorMsg: (_, out) => out.substring(0, 100),
54
+ },
55
+ docs_init: {
56
+ successTitle: "Docs Initialized",
57
+ successMsg: () => "Documentation directory created",
58
+ errorTitle: "Docs Init Failed",
59
+ errorMsg: (_, out) => out.substring(0, 100),
60
+ },
61
+ cortex_init: {
62
+ successTitle: "Project Initialized",
63
+ successMsg: () => ".cortex directory created",
64
+ errorTitle: "Init Failed",
65
+ errorMsg: (_, out) => out.substring(0, 100),
66
+ },
67
+ cortex_configure: {
68
+ successTitle: "Models Configured",
69
+ successMsg: (args) => `Primary: ${args.primaryModel?.split("/").pop() || "set"}`,
70
+ errorTitle: "Configure Failed",
71
+ errorMsg: (_, out) => out.substring(0, 100),
72
+ },
73
+ branch_switch: {
74
+ successTitle: "Branch Switched",
75
+ successMsg: (args) => `Now on ${args.branch ?? "branch"}`,
76
+ errorTitle: "Branch Switch Failed",
77
+ errorMsg: (_, out) => out
78
+ .replace(/^✗\s*/, "")
79
+ .split("\n")[0]
80
+ .substring(0, 100),
81
+ },
82
+ };
83
+ // ─── Error Message Extraction ────────────────────────────────────────────────
84
+ //
85
+ // Extracts a human-readable message from the session error union type
86
+ // (ProviderAuthError | UnknownError | MessageOutputLengthError |
87
+ // MessageAbortedError | ApiError).
88
+ function extractErrorMessage(error) {
89
+ if (!error)
90
+ return "An unknown error occurred";
91
+ const msg = typeof error.data?.message === "string" ? error.data.message : "";
92
+ switch (error.name) {
93
+ case "ProviderAuthError":
94
+ return `Auth error: ${msg || "Provider authentication failed"}`;
95
+ case "UnknownError":
96
+ return msg || "An unknown error occurred";
97
+ case "MessageOutputLengthError":
98
+ return "Output length exceeded — try compacting the session";
99
+ case "MessageAbortedError":
100
+ return `Aborted: ${msg || "Message was aborted"}`;
101
+ case "APIError":
102
+ return `API error: ${msg || "Request failed"}`;
103
+ default:
104
+ return `Error: ${error.name}`;
105
+ }
106
+ }
107
+ // ─── Plugin Entry ────────────────────────────────────────────────────────────
19
108
  export const CortexPlugin = async (ctx) => {
20
109
  return {
21
110
  tool: {
@@ -50,9 +139,49 @@ export const CortexPlugin = async (ctx) => {
50
139
  // Task tools - finalize workflow (commit, push, PR)
51
140
  task_finalize: task.finalize,
52
141
  },
53
- // Agent handover toast notifications
142
+ // ── Post-execution toast notifications ────────────────────────────────
143
+ //
144
+ // Fires after every tool execution. Uses the TOOL_NOTIFICATIONS map
145
+ // to determine which tools get toasts and what content to display.
146
+ // Tools with existing factory-based toasts are excluded from the map.
147
+ "tool.execute.after": async (input, output) => {
148
+ const config = TOOL_NOTIFICATIONS[input.tool];
149
+ if (!config)
150
+ return; // No notification configured for this tool
151
+ try {
152
+ const result = output.output;
153
+ const isSuccess = result.startsWith("✓");
154
+ const isError = result.startsWith("✗");
155
+ if (isSuccess) {
156
+ await ctx.client.tui.showToast({
157
+ body: {
158
+ title: config.successTitle,
159
+ message: config.successMsg(input.args, result),
160
+ variant: "success",
161
+ duration: config.successDuration ?? 4000,
162
+ },
163
+ });
164
+ }
165
+ else if (isError) {
166
+ await ctx.client.tui.showToast({
167
+ body: {
168
+ title: config.errorTitle,
169
+ message: config.errorMsg(input.args, result),
170
+ variant: "error",
171
+ duration: config.errorDuration ?? 8000,
172
+ },
173
+ });
174
+ }
175
+ // Informational or warning outputs (⚠) — no toast to avoid noise
176
+ }
177
+ catch {
178
+ // Toast failure is non-fatal
179
+ }
180
+ },
181
+ // ── Event-driven notifications ───────────────────────────────────────
54
182
  async event({ event }) {
55
183
  try {
184
+ // Agent handover notifications
56
185
  if (event.type === "message.part.updated" &&
57
186
  "part" in event.properties &&
58
187
  event.properties.part.type === "agent") {
@@ -67,6 +196,43 @@ export const CortexPlugin = async (ctx) => {
67
196
  },
68
197
  });
69
198
  }
199
+ // Session error notifications
200
+ if (event.type === "session.error") {
201
+ const rawError = event.properties.error;
202
+ // Runtime validation before cast — ensure error has expected shape
203
+ const error = rawError &&
204
+ typeof rawError === "object" &&
205
+ "name" in rawError &&
206
+ typeof rawError.name === "string"
207
+ ? rawError
208
+ : undefined;
209
+ const message = extractErrorMessage(error);
210
+ await ctx.client.tui.showToast({
211
+ body: {
212
+ title: "Session Error",
213
+ message,
214
+ variant: "error",
215
+ duration: 10000,
216
+ },
217
+ });
218
+ }
219
+ // PTY exited notifications (relevant for worktree terminal sessions)
220
+ if (event.type === "pty.exited") {
221
+ const rawExitCode = event.properties.exitCode;
222
+ const exitCode = typeof rawExitCode === "number" && Number.isInteger(rawExitCode)
223
+ ? rawExitCode
224
+ : -1;
225
+ await ctx.client.tui.showToast({
226
+ body: {
227
+ title: "Terminal Exited",
228
+ message: exitCode === 0
229
+ ? "Terminal session completed successfully"
230
+ : `Terminal exited with code ${exitCode}`,
231
+ variant: exitCode === 0 ? "success" : "warning",
232
+ duration: exitCode === 0 ? 4000 : 8000,
233
+ },
234
+ });
235
+ }
70
236
  }
71
237
  catch {
72
238
  // Toast failure is non-fatal — silently ignore
@@ -19,11 +19,11 @@ 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 ["build", "plan", "debug", "review"];
23
23
  /** Subagents receive a fast/cost-effective model */
24
24
  export declare const SUBAGENTS: readonly ["fullstack", "testing", "security", "devops"];
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 ["build", "plan", "debug", "review", "fullstack", "testing", "security", "devops"];
27
27
  /**
28
28
  * Build the interactive choices list for primary model selection.
29
29
  * 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,+CAAgD,CAAC;AAE5E,oDAAoD;AACpD,eAAO,MAAM,SAAS,yDAA0D,CAAC;AAEjF,+BAA+B;AAC/B,eAAO,MAAM,UAAU,6FAA6C,CAAC;AAErE;;;GAGG;AACH,wBAAgB,iBAAiB;;;;IAMhC;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,cAAc,EAAE,MAAM;;;;IAcxD"}
package/dist/registry.js CHANGED
@@ -105,7 +105,7 @@ 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 = ["build", "plan", "debug", "review"];
109
109
  /** Subagents receive a fast/cost-effective model */
110
110
  export const SUBAGENTS = ["fullstack", "testing", "security", "devops"];
111
111
  /** All agent names combined */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cortex-agents",
3
- "version": "2.3.0",
3
+ "version": "2.3.1",
4
4
  "description": "Supercharge OpenCode with structured workflows, intelligent agents, and automated development practices",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",