cortex-agents 4.1.2 → 5.0.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 (53) hide show
  1. package/README.md +85 -16
  2. package/dist/cli.js +146 -13
  3. package/dist/engine/agents.d.ts +19 -0
  4. package/dist/engine/agents.d.ts.map +1 -0
  5. package/dist/engine/agents.js +69 -0
  6. package/dist/engine/db.d.ts +13 -0
  7. package/dist/engine/db.d.ts.map +1 -0
  8. package/dist/engine/db.js +28 -0
  9. package/dist/engine/index.d.ts +50 -0
  10. package/dist/engine/index.d.ts.map +1 -0
  11. package/dist/engine/index.js +135 -0
  12. package/dist/engine/models.d.ts +12 -0
  13. package/dist/engine/models.d.ts.map +1 -0
  14. package/dist/engine/models.js +23 -0
  15. package/dist/engine/renderers/claude.d.ts +18 -0
  16. package/dist/engine/renderers/claude.d.ts.map +1 -0
  17. package/dist/engine/renderers/claude.js +226 -0
  18. package/dist/engine/renderers/codex.d.ts +22 -0
  19. package/dist/engine/renderers/codex.d.ts.map +1 -0
  20. package/dist/engine/renderers/codex.js +115 -0
  21. package/dist/engine/renderers/gemini.d.ts +18 -0
  22. package/dist/engine/renderers/gemini.d.ts.map +1 -0
  23. package/dist/engine/renderers/gemini.js +203 -0
  24. package/dist/engine/renderers/index.d.ts +21 -0
  25. package/dist/engine/renderers/index.d.ts.map +1 -0
  26. package/dist/engine/renderers/index.js +13 -0
  27. package/dist/engine/renderers/opencode.d.ts +18 -0
  28. package/dist/engine/renderers/opencode.d.ts.map +1 -0
  29. package/dist/engine/renderers/opencode.js +119 -0
  30. package/dist/engine/schema.d.ts +13 -0
  31. package/dist/engine/schema.d.ts.map +1 -0
  32. package/dist/engine/schema.js +125 -0
  33. package/dist/engine/seed.d.ts +14 -0
  34. package/dist/engine/seed.d.ts.map +1 -0
  35. package/dist/engine/seed.js +398 -0
  36. package/dist/engine/skills.d.ts +11 -0
  37. package/dist/engine/skills.d.ts.map +1 -0
  38. package/dist/engine/skills.js +24 -0
  39. package/dist/engine/targets.d.ts +17 -0
  40. package/dist/engine/targets.d.ts.map +1 -0
  41. package/dist/engine/targets.js +79 -0
  42. package/dist/engine/types.d.ts +100 -0
  43. package/dist/engine/types.d.ts.map +1 -0
  44. package/dist/engine/types.js +5 -0
  45. package/dist/index.d.ts.map +1 -1
  46. package/dist/index.js +53 -0
  47. package/dist/tools/engine.d.ts +22 -0
  48. package/dist/tools/engine.d.ts.map +1 -0
  49. package/dist/tools/engine.js +56 -0
  50. package/dist/utils/cortex-code-bridge.d.ts +21 -0
  51. package/dist/utils/cortex-code-bridge.d.ts.map +1 -0
  52. package/dist/utils/cortex-code-bridge.js +104 -0
  53. package/package.json +4 -2
package/dist/index.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { CortexCodeBridge } from "./utils/cortex-code-bridge.js";
1
2
  // Import all tool modules
2
3
  import * as cortex from "./tools/cortex";
3
4
  import * as worktree from "./tools/worktree";
@@ -9,6 +10,7 @@ import * as task from "./tools/task";
9
10
  import * as github from "./tools/github";
10
11
  import * as repl from "./tools/repl";
11
12
  import * as qualityGate from "./tools/quality-gate";
13
+ import * as engineTools from "./tools/engine";
12
14
  // ─── Agent Descriptions (for handover toasts) ───────────────────────────────
13
15
  const AGENT_DESCRIPTIONS = {
14
16
  implement: "Development mode — ready to implement",
@@ -149,6 +151,7 @@ function extractErrorMessage(error) {
149
151
  }
150
152
  // ─── Plugin Entry ────────────────────────────────────────────────────────────
151
153
  export const CortexPlugin = async (ctx) => {
154
+ const bridge = new CortexCodeBridge();
152
155
  return {
153
156
  tool: {
154
157
  // Cortex tools - .cortex directory management
@@ -193,6 +196,9 @@ export const CortexPlugin = async (ctx) => {
193
196
  repl_summary: repl.summary,
194
197
  // Quality gate aggregation tool
195
198
  quality_gate_summary: qualityGate.qualityGateSummary,
199
+ // Engine-backed tools
200
+ cortex_get_skill: engineTools.getSkill,
201
+ cortex_list_agents: engineTools.listAgents,
196
202
  },
197
203
  // ── Post-execution toast notifications ────────────────────────────────
198
204
  //
@@ -235,6 +241,53 @@ export const CortexPlugin = async (ctx) => {
235
241
  },
236
242
  // ── Event-driven notifications ───────────────────────────────────────
237
243
  async event({ event }) {
244
+ // ── Cortex Code bridge (fire-and-forget, no-op outside Cortex Code) ──
245
+ if (bridge.isActive) {
246
+ // session.status busy → agent started working
247
+ if (event.type === "session.status" &&
248
+ event.properties.status.type === "busy") {
249
+ bridge.taskStarted();
250
+ }
251
+ // session.status idle → agent waiting for user input
252
+ if (event.type === "session.status" &&
253
+ event.properties.status.type === "idle") {
254
+ bridge.interactionNeeded("input");
255
+ }
256
+ // session.idle → all processing complete
257
+ if (event.type === "session.idle") {
258
+ bridge.taskFinished();
259
+ }
260
+ // session.error → forward error
261
+ if (event.type === "session.error") {
262
+ const rawError = event.properties.error;
263
+ const error = rawError &&
264
+ typeof rawError === "object" &&
265
+ "name" in rawError &&
266
+ typeof rawError.name === "string"
267
+ ? rawError
268
+ : undefined;
269
+ bridge.error(extractErrorMessage(error));
270
+ }
271
+ // message.part.updated — text content
272
+ if (event.type === "message.part.updated" &&
273
+ event.properties.part.type === "text") {
274
+ bridge.text(event.properties.part.text);
275
+ }
276
+ // message.part.updated — tool call
277
+ if (event.type === "message.part.updated" &&
278
+ event.properties.part.type === "tool") {
279
+ const part = event.properties.part;
280
+ bridge.toolCall(part.callID, part.tool, part.metadata);
281
+ }
282
+ // message.updated — token/cost tracking (assistant messages with usage)
283
+ if (event.type === "message.updated" &&
284
+ event.properties.info.role === "assistant") {
285
+ const msg = event.properties.info;
286
+ if ("tokens" in msg && msg.tokens) {
287
+ bridge.usage(msg.tokens.input ?? 0, msg.tokens.output ?? 0, msg.cost ?? 0, "modelID" in msg ? msg.modelID : undefined);
288
+ }
289
+ }
290
+ }
238
291
  try {
239
292
  // Agent handover notifications
240
293
  if (event.type === "message.part.updated" &&
@@ -0,0 +1,22 @@
1
+ export declare const getSkill: {
2
+ description: string;
3
+ args: {
4
+ skillId: import("zod").ZodString;
5
+ };
6
+ execute(args: {
7
+ skillId: string;
8
+ }, context: import("@opencode-ai/plugin").ToolContext): Promise<string>;
9
+ };
10
+ export declare const listAgents: {
11
+ description: string;
12
+ args: {
13
+ mode: import("zod").ZodOptional<import("zod").ZodEnum<{
14
+ primary: "primary";
15
+ subagent: "subagent";
16
+ }>>;
17
+ };
18
+ execute(args: {
19
+ mode?: "primary" | "subagent" | undefined;
20
+ }, context: import("@opencode-ai/plugin").ToolContext): Promise<string>;
21
+ };
22
+ //# sourceMappingURL=engine.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../src/tools/engine.ts"],"names":[],"mappings":"AAiBA,eAAO,MAAM,QAAQ;;;;;;;;CAoBnB,CAAC;AAEH,eAAO,MAAM,UAAU;;;;;;;;;;;CA4BrB,CAAC"}
@@ -0,0 +1,56 @@
1
+ // ---------------------------------------------------------------------------
2
+ // Engine-backed MCP tools: cortex_get_skill, cortex_list_agents
3
+ // ---------------------------------------------------------------------------
4
+ import { tool } from "@opencode-ai/plugin";
5
+ import { CortexEngine } from "../engine/index.js";
6
+ let _engine = null;
7
+ function getEngine() {
8
+ if (!_engine) {
9
+ _engine = new CortexEngine();
10
+ _engine.initialize();
11
+ }
12
+ return _engine;
13
+ }
14
+ export const getSkill = tool({
15
+ description: "Retrieve the full content of a domain skill by ID. Returns the skill markdown including guidelines, patterns, and best practices.",
16
+ args: {
17
+ skillId: tool.schema
18
+ .string()
19
+ .describe('The skill identifier, e.g. "security-hardening", "api-design"'),
20
+ },
21
+ async execute(args) {
22
+ const engine = getEngine();
23
+ const content = engine.getSkillContent(args.skillId);
24
+ if (!content) {
25
+ const skills = engine.listSkills();
26
+ const available = skills.map((s) => s.id).join(", ");
27
+ return `✗ Skill not found: ${args.skillId}\n\nAvailable skills: ${available}`;
28
+ }
29
+ return content;
30
+ },
31
+ });
32
+ export const listAgents = tool({
33
+ description: "List all registered agents with their mode (primary/subagent), description, and available tools.",
34
+ args: {
35
+ mode: tool.schema
36
+ .enum(["primary", "subagent"])
37
+ .optional()
38
+ .describe("Filter by agent mode"),
39
+ },
40
+ async execute(args) {
41
+ const engine = getEngine();
42
+ const filter = args.mode ? { mode: args.mode } : undefined;
43
+ const agents = engine.listAgents(filter);
44
+ if (agents.length === 0) {
45
+ return "✗ No agents found in the database. Run 'npx cortex-agents install' first.";
46
+ }
47
+ const lines = agents.map((a) => {
48
+ const tools = engine.getAgentTools(a.id);
49
+ const enabledTools = tools
50
+ .filter((t) => t.allowed)
51
+ .map((t) => t.tool_name);
52
+ return `- **${a.id}** (${a.mode}) — ${a.description}\n Tools: ${enabledTools.join(", ") || "none"}`;
53
+ });
54
+ return `✓ ${agents.length} agents:\n\n${lines.join("\n\n")}`;
55
+ },
56
+ });
@@ -0,0 +1,21 @@
1
+ export declare class CortexCodeBridge {
2
+ private readonly eventUrl;
3
+ private readonly taskId;
4
+ private readonly active;
5
+ private tokensIn;
6
+ private tokensOut;
7
+ private costUsd;
8
+ private sessionStartTime;
9
+ private started;
10
+ constructor();
11
+ get isActive(): boolean;
12
+ taskStarted(): void;
13
+ taskFinished(): void;
14
+ usage(tokensIn: number, tokensOut: number, costUsd: number, model?: string): void;
15
+ interactionNeeded(reason: string, prompt?: string): void;
16
+ text(content: string): void;
17
+ toolCall(id: string, name: string, input?: unknown): void;
18
+ error(message: string, code?: string, recoverable?: boolean): void;
19
+ private send;
20
+ }
21
+ //# sourceMappingURL=cortex-code-bridge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cortex-code-bridge.d.ts","sourceRoot":"","sources":["../../src/utils/cortex-code-bridge.ts"],"names":[],"mappings":"AAgBA,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAqB;IAC9C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAqB;IAC5C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAU;IAGjC,OAAO,CAAC,QAAQ,CAAK;IACrB,OAAO,CAAC,SAAS,CAAK;IACtB,OAAO,CAAC,OAAO,CAAK;IAEpB,OAAO,CAAC,gBAAgB,CAAc;IACtC,OAAO,CAAC,OAAO,CAAS;;IAUxB,IAAI,QAAQ,IAAI,OAAO,CAEtB;IAID,WAAW,IAAI,IAAI;IAOnB,YAAY,IAAI,IAAI;IAUpB,KAAK,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI;IAYjF,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI;IAOxD,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAI3B,QAAQ,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO,GAAG,IAAI;IAQzD,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,OAAO,GAAG,IAAI;IAUlE,OAAO,CAAC,IAAI;CAkBb"}
@@ -0,0 +1,104 @@
1
+ // ─── Cortex Code Event Bridge ─────────────────────────────────────────────────
2
+ //
3
+ // When running inside Cortex Code's embedded terminal, the environment provides:
4
+ // CORTEX_EVENT_URL — HTTP endpoint for structured events
5
+ // CORTEX_TASK_ID — ID of the parent task in Cortex Code
6
+ // CORTEX_CODE — "1" when running inside Cortex Code
7
+ //
8
+ // This bridge POSTs structured events so Cortex Code can precisely track agent
9
+ // state (working, waiting, finished) instead of relying on ANSI heuristics.
10
+ //
11
+ // Payload format (Cortex Event Protocol):
12
+ // { cortex: "event", taskId, type, timestamp, ...fields }
13
+ //
14
+ // All HTTP calls are fire-and-forget with a 5s timeout — they never block the
15
+ // agent or throw errors.
16
+ export class CortexCodeBridge {
17
+ eventUrl;
18
+ taskId;
19
+ active;
20
+ // Accumulated usage for task_finished summary
21
+ tokensIn = 0;
22
+ tokensOut = 0;
23
+ costUsd = 0;
24
+ sessionStartTime = Date.now();
25
+ started = false;
26
+ constructor() {
27
+ this.eventUrl = process.env.CORTEX_EVENT_URL;
28
+ this.taskId = process.env.CORTEX_TASK_ID;
29
+ const cortexCode = process.env.CORTEX_CODE;
30
+ this.active = !!(this.eventUrl && this.taskId && cortexCode);
31
+ }
32
+ get isActive() {
33
+ return this.active;
34
+ }
35
+ // ── Event Senders ─────────────────────────────────────────────────────────
36
+ taskStarted() {
37
+ if (this.started)
38
+ return;
39
+ this.started = true;
40
+ this.sessionStartTime = Date.now();
41
+ this.send("task_started", {});
42
+ }
43
+ taskFinished() {
44
+ const duration = Date.now() - this.sessionStartTime;
45
+ this.send("task_finished", {
46
+ tokensIn: this.tokensIn,
47
+ tokensOut: this.tokensOut,
48
+ costUsd: this.costUsd,
49
+ duration,
50
+ });
51
+ }
52
+ usage(tokensIn, tokensOut, costUsd, model) {
53
+ this.tokensIn += tokensIn;
54
+ this.tokensOut += tokensOut;
55
+ this.costUsd += costUsd;
56
+ this.send("usage", {
57
+ tokensIn,
58
+ tokensOut,
59
+ costUsd,
60
+ ...(model ? { model } : {}),
61
+ });
62
+ }
63
+ interactionNeeded(reason, prompt) {
64
+ this.send("interaction_needed", {
65
+ reason,
66
+ ...(prompt ? { prompt } : {}),
67
+ });
68
+ }
69
+ text(content) {
70
+ this.send("text", { content });
71
+ }
72
+ toolCall(id, name, input) {
73
+ this.send("tool_call", {
74
+ id,
75
+ name,
76
+ ...(input !== undefined ? { input } : {}),
77
+ });
78
+ }
79
+ error(message, code, recoverable) {
80
+ this.send("error", {
81
+ message,
82
+ ...(code ? { code } : {}),
83
+ ...(recoverable !== undefined ? { recoverable } : {}),
84
+ });
85
+ }
86
+ // ── Internal ──────────────────────────────────────────────────────────────
87
+ send(type, fields) {
88
+ if (!this.active)
89
+ return;
90
+ const payload = {
91
+ cortex: "event",
92
+ taskId: this.taskId,
93
+ type,
94
+ timestamp: Date.now(),
95
+ ...fields,
96
+ };
97
+ fetch(this.eventUrl, {
98
+ method: "POST",
99
+ headers: { "Content-Type": "application/json" },
100
+ body: JSON.stringify(payload),
101
+ signal: AbortSignal.timeout(5000),
102
+ }).catch(() => { });
103
+ }
104
+ }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "cortex-agents",
3
- "version": "4.1.2",
4
- "description": "Supercharge OpenCode with structured workflows, intelligent agents, and automated development practices",
3
+ "version": "5.0.0",
4
+ "description": "Structured AI development workflows for OpenCode and Claude Code plan, build, ship with discipline",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
7
7
  "types": "dist/index.d.ts",
@@ -55,12 +55,14 @@
55
55
  },
56
56
  "devDependencies": {
57
57
  "@opencode-ai/plugin": "^1.0.0",
58
+ "@types/better-sqlite3": "^7.6.13",
58
59
  "@types/node": "^20.0.0",
59
60
  "@types/prompts": "^2.4.9",
60
61
  "typescript": "^5.0.0",
61
62
  "vitest": "^3.0.0"
62
63
  },
63
64
  "dependencies": {
65
+ "better-sqlite3": "^12.6.2",
64
66
  "prompts": "^2.4.2"
65
67
  }
66
68
  }