@electric-agent/agent 1.4.3 → 1.4.6

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 (94) hide show
  1. package/dist/scaffold/index.js +3 -3
  2. package/package.json +3 -3
  3. package/dist/agents/clarifier.d.ts +0 -16
  4. package/dist/agents/clarifier.d.ts.map +0 -1
  5. package/dist/agents/clarifier.js +0 -158
  6. package/dist/agents/clarifier.js.map +0 -1
  7. package/dist/agents/coder.d.ts +0 -14
  8. package/dist/agents/coder.d.ts.map +0 -1
  9. package/dist/agents/coder.js +0 -126
  10. package/dist/agents/coder.js.map +0 -1
  11. package/dist/agents/planner.d.ts +0 -6
  12. package/dist/agents/planner.d.ts.map +0 -1
  13. package/dist/agents/planner.js +0 -69
  14. package/dist/agents/planner.js.map +0 -1
  15. package/dist/agents/prompts.d.ts +0 -9
  16. package/dist/agents/prompts.d.ts.map +0 -1
  17. package/dist/agents/prompts.js +0 -231
  18. package/dist/agents/prompts.js.map +0 -1
  19. package/dist/cli/headless.d.ts +0 -9
  20. package/dist/cli/headless.d.ts.map +0 -1
  21. package/dist/cli/headless.js +0 -506
  22. package/dist/cli/headless.js.map +0 -1
  23. package/dist/engine/message-parser.d.ts +0 -8
  24. package/dist/engine/message-parser.d.ts.map +0 -1
  25. package/dist/engine/message-parser.js +0 -106
  26. package/dist/engine/message-parser.js.map +0 -1
  27. package/dist/engine/orchestrator.d.ts +0 -50
  28. package/dist/engine/orchestrator.d.ts.map +0 -1
  29. package/dist/engine/orchestrator.js +0 -492
  30. package/dist/engine/orchestrator.js.map +0 -1
  31. package/dist/engine/stdio-adapter.d.ts +0 -24
  32. package/dist/engine/stdio-adapter.d.ts.map +0 -1
  33. package/dist/engine/stdio-adapter.js +0 -139
  34. package/dist/engine/stdio-adapter.js.map +0 -1
  35. package/dist/engine/stream-adapter.d.ts +0 -45
  36. package/dist/engine/stream-adapter.d.ts.map +0 -1
  37. package/dist/engine/stream-adapter.js +0 -154
  38. package/dist/engine/stream-adapter.js.map +0 -1
  39. package/dist/hooks/block-bash.d.ts +0 -7
  40. package/dist/hooks/block-bash.d.ts.map +0 -1
  41. package/dist/hooks/block-bash.js +0 -15
  42. package/dist/hooks/block-bash.js.map +0 -1
  43. package/dist/hooks/dependency-guard.d.ts +0 -7
  44. package/dist/hooks/dependency-guard.d.ts.map +0 -1
  45. package/dist/hooks/dependency-guard.js +0 -43
  46. package/dist/hooks/dependency-guard.js.map +0 -1
  47. package/dist/hooks/guardrail-inject.d.ts +0 -17
  48. package/dist/hooks/guardrail-inject.d.ts.map +0 -1
  49. package/dist/hooks/guardrail-inject.js +0 -69
  50. package/dist/hooks/guardrail-inject.js.map +0 -1
  51. package/dist/hooks/import-validation.d.ts +0 -7
  52. package/dist/hooks/import-validation.d.ts.map +0 -1
  53. package/dist/hooks/import-validation.js +0 -192
  54. package/dist/hooks/import-validation.js.map +0 -1
  55. package/dist/hooks/index.d.ts +0 -15
  56. package/dist/hooks/index.d.ts.map +0 -1
  57. package/dist/hooks/index.js +0 -42
  58. package/dist/hooks/index.js.map +0 -1
  59. package/dist/hooks/migration-validation.d.ts +0 -9
  60. package/dist/hooks/migration-validation.d.ts.map +0 -1
  61. package/dist/hooks/migration-validation.js +0 -62
  62. package/dist/hooks/migration-validation.js.map +0 -1
  63. package/dist/hooks/schema-consistency.d.ts +0 -12
  64. package/dist/hooks/schema-consistency.d.ts.map +0 -1
  65. package/dist/hooks/schema-consistency.js +0 -72
  66. package/dist/hooks/schema-consistency.js.map +0 -1
  67. package/dist/hooks/write-protection.d.ts +0 -7
  68. package/dist/hooks/write-protection.d.ts.map +0 -1
  69. package/dist/hooks/write-protection.js +0 -33
  70. package/dist/hooks/write-protection.js.map +0 -1
  71. package/dist/progress/reporter.d.ts +0 -15
  72. package/dist/progress/reporter.d.ts.map +0 -1
  73. package/dist/progress/reporter.js +0 -133
  74. package/dist/progress/reporter.js.map +0 -1
  75. package/dist/tools/build.d.ts +0 -3
  76. package/dist/tools/build.d.ts.map +0 -1
  77. package/dist/tools/build.js +0 -84
  78. package/dist/tools/build.js.map +0 -1
  79. package/dist/tools/playbook.d.ts +0 -14
  80. package/dist/tools/playbook.d.ts.map +0 -1
  81. package/dist/tools/playbook.js +0 -239
  82. package/dist/tools/playbook.js.map +0 -1
  83. package/dist/tools/server.d.ts +0 -3
  84. package/dist/tools/server.d.ts.map +0 -1
  85. package/dist/tools/server.js +0 -13
  86. package/dist/tools/server.js.map +0 -1
  87. package/dist/working-memory/errors.d.ts +0 -14
  88. package/dist/working-memory/errors.d.ts.map +0 -1
  89. package/dist/working-memory/errors.js +0 -89
  90. package/dist/working-memory/errors.js.map +0 -1
  91. package/dist/working-memory/session.d.ts +0 -12
  92. package/dist/working-memory/session.d.ts.map +0 -1
  93. package/dist/working-memory/session.js +0 -71
  94. package/dist/working-memory/session.js.map +0 -1
@@ -181,9 +181,9 @@ function copyTemplateFiles(srcDir, destDir) {
181
181
  }
182
182
  }
183
183
  const ADDED_DEPENDENCIES = {
184
- "@tanstack/db": "0.5.32",
185
- "@tanstack/react-db": "0.1.76",
186
- "@tanstack/electric-db-collection": "0.2.40",
184
+ "@tanstack/db": "0.5.31",
185
+ "@tanstack/react-db": "0.1.75",
186
+ "@tanstack/electric-db-collection": "0.2.39",
187
187
  "@electric-sql/client": "1.5.12",
188
188
  "drizzle-orm": "0.45.1",
189
189
  "drizzle-zod": "^0.8.3",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@electric-agent/agent",
3
- "version": "1.4.3",
3
+ "version": "1.4.6",
4
4
  "description": "CLI tool that turns natural-language app descriptions into running reactive Electric SQL + TanStack DB applications",
5
5
  "type": "module",
6
6
  "bin": {
@@ -26,8 +26,8 @@
26
26
  "commander": "^13.1.0",
27
27
  "dotenv": "^17.3.1",
28
28
  "zod": "^3.24.1",
29
- "@electric-agent/studio": "1.13.1",
30
- "@electric-agent/protocol": "1.8.0"
29
+ "@electric-agent/protocol": "1.8.1",
30
+ "@electric-agent/studio": "1.14.0"
31
31
  },
32
32
  "devDependencies": {
33
33
  "@types/node": "^22.15.0",
@@ -1,16 +0,0 @@
1
- /**
2
- * Infer a short, meaningful kebab-case project name from a description using an LLM.
3
- * Falls back to "electric-app" if the call fails or returns garbage.
4
- */
5
- export declare function inferProjectName(description: string): Promise<string>;
6
- export interface ClarificationResult {
7
- confidence: number;
8
- summary: string;
9
- questions: string[];
10
- }
11
- /**
12
- * Evaluate a user's app description for clarity and completeness.
13
- * Returns a confidence score and optional clarification questions.
14
- */
15
- export declare function evaluateDescription(description: string): Promise<ClarificationResult>;
16
- //# sourceMappingURL=clarifier.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"clarifier.d.ts","sourceRoot":"","sources":["../../src/agents/clarifier.ts"],"names":[],"mappings":"AAYA;;;GAGG;AACH,wBAAsB,gBAAgB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CA8C3E;AAED,MAAM,WAAW,mBAAmB;IACnC,UAAU,EAAE,MAAM,CAAA;IAClB,OAAO,EAAE,MAAM,CAAA;IACf,SAAS,EAAE,MAAM,EAAE,CAAA;CACnB;AAcD;;;GAGG;AACH,wBAAsB,mBAAmB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAsF3F"}
@@ -1,158 +0,0 @@
1
- import { query } from "@anthropic-ai/claude-agent-sdk";
2
- function toKebabCase(str) {
3
- return str
4
- .toLowerCase()
5
- .replace(/[^a-z0-9\s-]/g, "")
6
- .replace(/\s+/g, "-")
7
- .replace(/-+/g, "-")
8
- .replace(/^-|-$/g, "")
9
- .slice(0, 40);
10
- }
11
- /**
12
- * Infer a short, meaningful kebab-case project name from a description using an LLM.
13
- * Falls back to "electric-app" if the call fails or returns garbage.
14
- */
15
- export async function inferProjectName(description) {
16
- let responseText = "";
17
- async function* generateMessages() {
18
- yield {
19
- type: "user",
20
- session_id: "",
21
- parent_tool_use_id: null,
22
- message: {
23
- role: "user",
24
- content: `Given this app description, suggest a short project name (2-3 words, kebab-case, no prefix). Respond with only the name.\n\nDescription:\n"""\n${description}\n"""`,
25
- },
26
- };
27
- }
28
- try {
29
- for await (const message of query({
30
- prompt: generateMessages(),
31
- options: {
32
- model: "claude-haiku-4-5-20251001",
33
- systemPrompt: "You are a naming assistant. Given an app description, respond with a single short kebab-case project name (2-3 words). No explanation, no quotes, just the name.",
34
- maxTurns: 1,
35
- allowedTools: [],
36
- permissionMode: "bypassPermissions",
37
- allowDangerouslySkipPermissions: true,
38
- },
39
- })) {
40
- if (message.type === "assistant" && message.message?.content) {
41
- for (const block of message.message.content) {
42
- if ("text" in block && block.text) {
43
- responseText = block.text;
44
- }
45
- }
46
- }
47
- }
48
- // Sanitize: extract first line, kebab-case it, validate
49
- const candidate = toKebabCase(responseText.trim().split("\n")[0]);
50
- if (candidate.length >= 2 && /^[a-z]/.test(candidate)) {
51
- return candidate;
52
- }
53
- return "electric-app";
54
- }
55
- catch {
56
- return "electric-app";
57
- }
58
- }
59
- function extractJson(text) {
60
- // Try to find JSON in code fences first
61
- const fenceMatch = text.match(/```(?:json)?\s*\n?([\s\S]*?)\n?```/);
62
- if (fenceMatch)
63
- return fenceMatch[1].trim();
64
- // Try to find a JSON object
65
- const jsonMatch = text.match(/\{[\s\S]*\}/);
66
- if (jsonMatch)
67
- return jsonMatch[0];
68
- return text.trim();
69
- }
70
- /**
71
- * Evaluate a user's app description for clarity and completeness.
72
- * Returns a confidence score and optional clarification questions.
73
- */
74
- export async function evaluateDescription(description) {
75
- let responseText = "";
76
- async function* generateMessages() {
77
- yield {
78
- type: "user",
79
- session_id: "",
80
- parent_tool_use_id: null,
81
- message: {
82
- role: "user",
83
- content: `Evaluate the following application description and determine how clear and complete it is for building a reactive local-first application using Electric SQL and TanStack DB.
84
-
85
- About Electric SQL:
86
- Electric is a sync engine for local-first apps. It syncs data between Postgres and local devices using Shapes (subsets of database tables). Apps built with Electric get:
87
- - Real-time sync: changes in Postgres instantly appear on all connected clients
88
- - Optimistic mutations: writes happen locally first, then sync to Postgres
89
- - Offline support: the app works without a network connection and syncs when reconnected
90
- - Multi-user collaboration: multiple users see each other's changes in real-time
91
-
92
- Description:
93
- """
94
- ${description}
95
- """
96
-
97
- Respond with ONLY a JSON object (no markdown code fences, no other text) in this exact format:
98
- {
99
- "confidence": <number 0-100>,
100
- "summary": "<one sentence summarizing what you understand the app to be>",
101
- "questions": ["<question 1>", "<question 2>", ...]
102
- }
103
-
104
- Scoring guidelines:
105
- - 80-100: Very clear and detailed. The description specifies both the app type AND key features, interactions, or data model details. E.g. "a kanban board with multiple boards, drag-and-drop columns, and card labels" or "a todo app with categories, due dates, and shared lists".
106
- - 50-79: Recognizable app type but light on specifics. E.g. "a todo app", "a chat app", "a project tracker". The general idea is clear but asking 1-2 questions would meaningfully improve the result.
107
- - 0-49: Too vague to proceed. E.g. "make me an app", "something with data", "a dashboard".
108
-
109
- Score based on how much detail the user provided, not on how much you could infer. A bare app-type name like "a todo list" should score in the 50-70 range — the concept is known, but we don't know which features matter to this user.
110
-
111
- If confidence >= 70, return an empty questions array.
112
- If confidence < 70, ask 1-3 targeted questions to fill in the gaps. Focus on what would most improve the plan:
113
- - What are the key features or interactions? (e.g. drag-and-drop, categories, search)
114
- - What are the main entities/data objects and their relationships?
115
- - Should the app support multi-user collaboration with real-time sync?
116
- - Should it work offline and sync when reconnected?
117
- Keep questions concise and specific to the described app type — avoid generic questions.`,
118
- },
119
- };
120
- }
121
- for await (const message of query({
122
- prompt: generateMessages(),
123
- options: {
124
- model: "claude-sonnet-4-6",
125
- systemPrompt: "You are a requirements analyst. Evaluate app descriptions and identify ambiguities. Always respond with valid JSON only.",
126
- maxTurns: 1,
127
- allowedTools: [],
128
- permissionMode: "bypassPermissions",
129
- allowDangerouslySkipPermissions: true,
130
- },
131
- })) {
132
- if (message.type === "assistant" && message.message?.content) {
133
- for (const block of message.message.content) {
134
- if ("text" in block && block.text) {
135
- responseText = block.text;
136
- }
137
- }
138
- }
139
- }
140
- try {
141
- const cleaned = extractJson(responseText);
142
- const parsed = JSON.parse(cleaned);
143
- return {
144
- confidence: typeof parsed.confidence === "number" ? parsed.confidence : 50,
145
- summary: parsed.summary || "",
146
- questions: Array.isArray(parsed.questions) ? parsed.questions : [],
147
- };
148
- }
149
- catch {
150
- // If parsing fails, assume low confidence
151
- return {
152
- confidence: 30,
153
- summary: "",
154
- questions: ["Could you describe in more detail what your application should do?"],
155
- };
156
- }
157
- }
158
- //# sourceMappingURL=clarifier.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"clarifier.js","sourceRoot":"","sources":["../../src/agents/clarifier.ts"],"names":[],"mappings":"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"}
@@ -1,14 +0,0 @@
1
- import { type ProgressReporter } from "../progress/reporter.js";
2
- export type StopReason = "complete" | "max_turns" | "max_budget" | "error";
3
- export interface CoderResult {
4
- success: boolean;
5
- errors: string[];
6
- stopReason: StopReason;
7
- /** SDK session ID — pass to resumeSessionId to continue with full conversation context */
8
- sessionId?: string;
9
- }
10
- /**
11
- * Run the coder agent to execute tasks from PLAN.md.
12
- */
13
- export declare function runCoder(projectDir: string, task?: string, reporter?: ProgressReporter, onMessage?: (msg: Record<string, unknown>) => void, resumeSessionId?: string, abortController?: AbortController): Promise<CoderResult>;
14
- //# sourceMappingURL=coder.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"coder.d.ts","sourceRoot":"","sources":["../../src/agents/coder.ts"],"names":[],"mappings":"AAEA,OAAO,EAEN,KAAK,gBAAgB,EAErB,MAAM,yBAAyB,CAAA;AAMhC,MAAM,MAAM,UAAU,GAAG,UAAU,GAAG,WAAW,GAAG,YAAY,GAAG,OAAO,CAAA;AAE1E,MAAM,WAAW,WAAW;IAC3B,OAAO,EAAE,OAAO,CAAA;IAChB,MAAM,EAAE,MAAM,EAAE,CAAA;IAChB,UAAU,EAAE,UAAU,CAAA;IACtB,0FAA0F;IAC1F,SAAS,CAAC,EAAE,MAAM,CAAA;CAClB;AAED;;GAEG;AACH,wBAAsB,QAAQ,CAC7B,UAAU,EAAE,MAAM,EAClB,IAAI,CAAC,EAAE,MAAM,EACb,QAAQ,CAAC,EAAE,gBAAgB,EAC3B,SAAS,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,EAClD,eAAe,CAAC,EAAE,MAAM,EACxB,eAAe,CAAC,EAAE,eAAe,GAC/B,OAAO,CAAC,WAAW,CAAC,CA0HtB"}
@@ -1,126 +0,0 @@
1
- import { query } from "@anthropic-ai/claude-agent-sdk";
2
- import { createCoderHooks } from "../hooks/index.js";
3
- import { createProgressReporter, processAgentMessage, } from "../progress/reporter.js";
4
- import { createToolServer } from "../tools/server.js";
5
- import { consecutiveIdenticalFailures, logError } from "../working-memory/errors.js";
6
- import { updateSession } from "../working-memory/session.js";
7
- import { buildCoderPrompt } from "./prompts.js";
8
- /**
9
- * Run the coder agent to execute tasks from PLAN.md.
10
- */
11
- export async function runCoder(projectDir, task, reporter, onMessage, resumeSessionId, abortController) {
12
- const r = reporter ?? createProgressReporter();
13
- const coderPrompt = buildCoderPrompt(projectDir);
14
- const mcpServer = createToolServer(projectDir, r);
15
- const errors = [];
16
- let success = true;
17
- let stopReason = "complete";
18
- let sessionId;
19
- const prompt = task ||
20
- "Read PLAN.md and execute ALL unchecked tasks in order. After completing each task, mark it as done with [x] in PLAN.md. Run the build tool after each phase to verify the code compiles. Continue until all tasks are checked off.";
21
- await updateSession(projectDir, {
22
- currentTask: task || "Executing next task from PLAN.md",
23
- buildStatus: "in-progress",
24
- });
25
- async function* generateMessages() {
26
- yield {
27
- type: "user",
28
- session_id: "",
29
- parent_tool_use_id: null,
30
- message: {
31
- role: "user",
32
- content: prompt,
33
- },
34
- };
35
- }
36
- const queryOptions = {
37
- model: "claude-sonnet-4-6",
38
- systemPrompt: coderPrompt,
39
- maxThinkingTokens: 4096,
40
- allowedTools: [
41
- "Read",
42
- "Write",
43
- "Edit",
44
- "Glob",
45
- "Grep",
46
- "Bash",
47
- "WebSearch",
48
- "mcp__electric-agent-tools__build",
49
- "mcp__electric-agent-tools__read_playbook",
50
- "mcp__electric-agent-tools__list_playbooks",
51
- ],
52
- mcpServers: { "electric-agent-tools": mcpServer },
53
- hooks: createCoderHooks(projectDir),
54
- cwd: projectDir,
55
- maxTurns: 200,
56
- maxBudgetUsd: 25.0,
57
- permissionMode: "bypassPermissions",
58
- allowDangerouslySkipPermissions: true,
59
- };
60
- // Resume previous conversation if session ID is provided
61
- if (resumeSessionId) {
62
- queryOptions.resume = resumeSessionId;
63
- }
64
- // Wire abort controller so cancellation stops the SDK agent
65
- if (abortController) {
66
- queryOptions.abortController = abortController;
67
- }
68
- try {
69
- for await (const message of query({
70
- prompt: generateMessages(),
71
- options: queryOptions,
72
- })) {
73
- processAgentMessage(message, r);
74
- onMessage?.(message);
75
- // Capture session ID for potential resume
76
- const msgSessionId = message.session_id;
77
- if (msgSessionId) {
78
- sessionId = msgSessionId;
79
- }
80
- // Handle result messages
81
- if (message.type === "result") {
82
- const sub = String(message.subtype);
83
- if (sub === "success") {
84
- stopReason = "complete";
85
- }
86
- else if (sub.includes("max_turns")) {
87
- stopReason = "max_turns";
88
- // Not a hard failure — work can be continued
89
- }
90
- else if (sub.includes("max_budget")) {
91
- stopReason = "max_budget";
92
- // Not a hard failure — user can increase budget and continue
93
- }
94
- else {
95
- stopReason = "error";
96
- success = false;
97
- errors.push(sub);
98
- }
99
- }
100
- }
101
- }
102
- catch (err) {
103
- success = false;
104
- stopReason = "error";
105
- const errMsg = err instanceof Error ? err.message : "Unknown error";
106
- errors.push(errMsg);
107
- logError(projectDir, {
108
- errorClass: "infrastructure",
109
- file: "agent",
110
- message: errMsg,
111
- attemptedFix: "none",
112
- });
113
- }
114
- // Check for consecutive identical failures
115
- if (consecutiveIdenticalFailures(projectDir)) {
116
- r.log("error", "Consecutive identical failures detected — escalation needed");
117
- await updateSession(projectDir, { buildStatus: "escalation-needed" });
118
- }
119
- else {
120
- await updateSession(projectDir, {
121
- buildStatus: success ? "passing" : "failing",
122
- });
123
- }
124
- return { success, errors, stopReason, sessionId };
125
- }
126
- //# sourceMappingURL=coder.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"coder.js","sourceRoot":"","sources":["../../src/agents/coder.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAuB,MAAM,gCAAgC,CAAA;AAC3E,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAA;AACpD,OAAO,EACN,sBAAsB,EAEtB,mBAAmB,GACnB,MAAM,yBAAyB,CAAA;AAChC,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAA;AACrD,OAAO,EAAE,4BAA4B,EAAE,QAAQ,EAAE,MAAM,6BAA6B,CAAA;AACpF,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAA;AAC5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAA;AAY/C;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,QAAQ,CAC7B,UAAkB,EAClB,IAAa,EACb,QAA2B,EAC3B,SAAkD,EAClD,eAAwB,EACxB,eAAiC;IAEjC,MAAM,CAAC,GAAG,QAAQ,IAAI,sBAAsB,EAAE,CAAA;IAC9C,MAAM,WAAW,GAAG,gBAAgB,CAAC,UAAU,CAAC,CAAA;IAChD,MAAM,SAAS,GAAG,gBAAgB,CAAC,UAAU,EAAE,CAAC,CAAC,CAAA;IACjD,MAAM,MAAM,GAAa,EAAE,CAAA;IAC3B,IAAI,OAAO,GAAG,IAAI,CAAA;IAClB,IAAI,UAAU,GAAe,UAAU,CAAA;IACvC,IAAI,SAA6B,CAAA;IAEjC,MAAM,MAAM,GACX,IAAI;QACJ,oOAAoO,CAAA;IAErO,MAAM,aAAa,CAAC,UAAU,EAAE;QAC/B,WAAW,EAAE,IAAI,IAAI,kCAAkC;QACvD,WAAW,EAAE,aAAa;KAC1B,CAAC,CAAA;IAEF,KAAK,SAAS,CAAC,CAAC,gBAAgB;QAC/B,MAAM;YACL,IAAI,EAAE,MAAe;YACrB,UAAU,EAAE,EAAE;YACd,kBAAkB,EAAE,IAAI;YACxB,OAAO,EAAE;gBACR,IAAI,EAAE,MAAe;gBACrB,OAAO,EAAE,MAAM;aACf;SACD,CAAA;IACF,CAAC;IAED,MAAM,YAAY,GAA4B;QAC7C,KAAK,EAAE,mBAAmB;QAC1B,YAAY,EAAE,WAAW;QACzB,iBAAiB,EAAE,IAAI;QACvB,YAAY,EAAE;YACb,MAAM;YACN,OAAO;YACP,MAAM;YACN,MAAM;YACN,MAAM;YACN,MAAM;YACN,WAAW;YACX,kCAAkC;YAClC,0CAA0C;YAC1C,2CAA2C;SAC3C;QACD,UAAU,EAAE,EAAE,sBAAsB,EAAE,SAAS,EAAE;QACjD,KAAK,EAAE,gBAAgB,CAAC,UAAU,CAAC;QACnC,GAAG,EAAE,UAAU;QACf,QAAQ,EAAE,GAAG;QACb,YAAY,EAAE,IAAI;QAClB,cAAc,EAAE,mBAAmB;QACnC,+BAA+B,EAAE,IAAI;KACrC,CAAA;IAED,yDAAyD;IACzD,IAAI,eAAe,EAAE,CAAC;QACrB,YAAY,CAAC,MAAM,GAAG,eAAe,CAAA;IACtC,CAAC;IAED,4DAA4D;IAC5D,IAAI,eAAe,EAAE,CAAC;QACrB,YAAY,CAAC,eAAe,GAAG,eAAe,CAAA;IAC/C,CAAC;IAED,IAAI,CAAC;QACJ,IAAI,KAAK,EAAE,MAAM,OAAO,IAAI,KAAK,CAAC;YACjC,MAAM,EAAE,gBAAgB,EAAE;YAC1B,OAAO,EAAE,YAAY;SACrB,CAAC,EAAE,CAAC;YACJ,mBAAmB,CAAC,OAAO,EAAE,CAAC,CAAC,CAAA;YAC/B,SAAS,EAAE,CAAC,OAAO,CAAC,CAAA;YAEpB,0CAA0C;YAC1C,MAAM,YAAY,GAAI,OAAmC,CAAC,UAAgC,CAAA;YAC1F,IAAI,YAAY,EAAE,CAAC;gBAClB,SAAS,GAAG,YAAY,CAAA;YACzB,CAAC;YAED,yBAAyB;YACzB,IAAI,OAAO,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBAC/B,MAAM,GAAG,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAA;gBACnC,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;oBACvB,UAAU,GAAG,UAAU,CAAA;gBACxB,CAAC;qBAAM,IAAI,GAAG,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;oBACtC,UAAU,GAAG,WAAW,CAAA;oBACxB,6CAA6C;gBAC9C,CAAC;qBAAM,IAAI,GAAG,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC;oBACvC,UAAU,GAAG,YAAY,CAAA;oBACzB,6DAA6D;gBAC9D,CAAC;qBAAM,CAAC;oBACP,UAAU,GAAG,OAAO,CAAA;oBACpB,OAAO,GAAG,KAAK,CAAA;oBACf,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;gBACjB,CAAC;YACF,CAAC;QACF,CAAC;IACF,CAAC;IAAC,OAAO,GAAY,EAAE,CAAC;QACvB,OAAO,GAAG,KAAK,CAAA;QACf,UAAU,GAAG,OAAO,CAAA;QACpB,MAAM,MAAM,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CAAA;QACnE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;QAEnB,QAAQ,CAAC,UAAU,EAAE;YACpB,UAAU,EAAE,gBAAgB;YAC5B,IAAI,EAAE,OAAO;YACb,OAAO,EAAE,MAAM;YACf,YAAY,EAAE,MAAM;SACpB,CAAC,CAAA;IACH,CAAC;IAED,2CAA2C;IAC3C,IAAI,4BAA4B,CAAC,UAAU,CAAC,EAAE,CAAC;QAC9C,CAAC,CAAC,GAAG,CAAC,OAAO,EAAE,6DAA6D,CAAC,CAAA;QAC7E,MAAM,aAAa,CAAC,UAAU,EAAE,EAAE,WAAW,EAAE,mBAAmB,EAAE,CAAC,CAAA;IACtE,CAAC;SAAM,CAAC;QACP,MAAM,aAAa,CAAC,UAAU,EAAE;YAC/B,WAAW,EAAE,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS;SAC5C,CAAC,CAAA;IACH,CAAC;IAED,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,CAAA;AAClD,CAAC"}
@@ -1,6 +0,0 @@
1
- import { type ProgressReporter } from "../progress/reporter.js";
2
- /**
3
- * Run the planner agent to generate a PLAN.md from an app description.
4
- */
5
- export declare function runPlanner(appDescription: string, projectDir: string, reporter?: ProgressReporter, onMessage?: (msg: Record<string, unknown>) => void, abortController?: AbortController): Promise<string>;
6
- //# sourceMappingURL=planner.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"planner.d.ts","sourceRoot":"","sources":["../../src/agents/planner.ts"],"names":[],"mappings":"AAEA,OAAO,EAEN,KAAK,gBAAgB,EAErB,MAAM,yBAAyB,CAAA;AAIhC;;GAEG;AACH,wBAAsB,UAAU,CAC/B,cAAc,EAAE,MAAM,EACtB,UAAU,EAAE,MAAM,EAClB,QAAQ,CAAC,EAAE,gBAAgB,EAC3B,SAAS,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,EAClD,eAAe,CAAC,EAAE,eAAe,GAC/B,OAAO,CAAC,MAAM,CAAC,CAkEjB"}
@@ -1,69 +0,0 @@
1
- import { query } from "@anthropic-ai/claude-agent-sdk";
2
- import { plannerHooks } from "../hooks/index.js";
3
- import { createProgressReporter, processAgentMessage, } from "../progress/reporter.js";
4
- import { createToolServer } from "../tools/server.js";
5
- import { buildPlannerPrompt } from "./prompts.js";
6
- /**
7
- * Run the planner agent to generate a PLAN.md from an app description.
8
- */
9
- export async function runPlanner(appDescription, projectDir, reporter, onMessage, abortController) {
10
- const r = reporter ?? createProgressReporter();
11
- const plannerPrompt = buildPlannerPrompt();
12
- const mcpServer = createToolServer(projectDir, r);
13
- let planContent = "";
14
- async function* generateMessages() {
15
- yield {
16
- type: "user",
17
- session_id: "",
18
- parent_tool_use_id: null,
19
- message: {
20
- role: "user",
21
- content: `Create a detailed implementation plan for this app: "${appDescription}"
22
-
23
- Steps:
24
- 1. list_playbooks — discover available playbook skills and their descriptions
25
- 2. read_playbook("electric-app-guardrails") — critical integration rules
26
- 3. Read 1-2 more playbooks relevant to this app (based on what list_playbooks returned)
27
- 4. Output the complete PLAN.md with Drizzle pgTable() definitions for ALL entities
28
-
29
- The plan must include read_playbook instructions in each phase so the coder reads the right playbook before coding that phase (see system prompt for format).`,
30
- },
31
- };
32
- }
33
- const queryOptions = {
34
- model: "claude-sonnet-4-6",
35
- systemPrompt: plannerPrompt,
36
- maxThinkingTokens: 4096,
37
- allowedTools: [
38
- "WebSearch",
39
- "mcp__electric-agent-tools__read_playbook",
40
- "mcp__electric-agent-tools__list_playbooks",
41
- ],
42
- mcpServers: { "electric-agent-tools": mcpServer },
43
- hooks: plannerHooks,
44
- cwd: projectDir,
45
- maxTurns: 10,
46
- permissionMode: "bypassPermissions",
47
- allowDangerouslySkipPermissions: true,
48
- };
49
- if (abortController) {
50
- queryOptions.abortController = abortController;
51
- }
52
- for await (const message of query({
53
- prompt: generateMessages(),
54
- options: queryOptions,
55
- })) {
56
- processAgentMessage(message, r);
57
- onMessage?.(message);
58
- // Capture the final text output as the plan
59
- if (message.type === "assistant" && message.message?.content) {
60
- for (const block of message.message.content) {
61
- if ("text" in block && block.text) {
62
- planContent = block.text;
63
- }
64
- }
65
- }
66
- }
67
- return planContent;
68
- }
69
- //# sourceMappingURL=planner.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"planner.js","sourceRoot":"","sources":["../../src/agents/planner.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAuB,MAAM,gCAAgC,CAAA;AAC3E,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAChD,OAAO,EACN,sBAAsB,EAEtB,mBAAmB,GACnB,MAAM,yBAAyB,CAAA;AAChC,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAA;AACrD,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAA;AAEjD;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAC/B,cAAsB,EACtB,UAAkB,EAClB,QAA2B,EAC3B,SAAkD,EAClD,eAAiC;IAEjC,MAAM,CAAC,GAAG,QAAQ,IAAI,sBAAsB,EAAE,CAAA;IAC9C,MAAM,aAAa,GAAG,kBAAkB,EAAE,CAAA;IAC1C,MAAM,SAAS,GAAG,gBAAgB,CAAC,UAAU,EAAE,CAAC,CAAC,CAAA;IAEjD,IAAI,WAAW,GAAG,EAAE,CAAA;IAEpB,KAAK,SAAS,CAAC,CAAC,gBAAgB;QAC/B,MAAM;YACL,IAAI,EAAE,MAAe;YACrB,UAAU,EAAE,EAAE;YACd,kBAAkB,EAAE,IAAI;YACxB,OAAO,EAAE;gBACR,IAAI,EAAE,MAAe;gBACrB,OAAO,EAAE,wDAAwD,cAAc;;;;;;;;8JAQ2E;aAC1J;SACD,CAAA;IACF,CAAC;IAED,MAAM,YAAY,GAA4B;QAC7C,KAAK,EAAE,mBAAmB;QAC1B,YAAY,EAAE,aAAa;QAC3B,iBAAiB,EAAE,IAAI;QACvB,YAAY,EAAE;YACb,WAAW;YACX,0CAA0C;YAC1C,2CAA2C;SAC3C;QACD,UAAU,EAAE,EAAE,sBAAsB,EAAE,SAAS,EAAE;QACjD,KAAK,EAAE,YAAY;QACnB,GAAG,EAAE,UAAU;QACf,QAAQ,EAAE,EAAE;QACZ,cAAc,EAAE,mBAAmB;QACnC,+BAA+B,EAAE,IAAI;KACrC,CAAA;IAED,IAAI,eAAe,EAAE,CAAC;QACrB,YAAY,CAAC,eAAe,GAAG,eAAe,CAAA;IAC/C,CAAC;IAED,IAAI,KAAK,EAAE,MAAM,OAAO,IAAI,KAAK,CAAC;QACjC,MAAM,EAAE,gBAAgB,EAAE;QAC1B,OAAO,EAAE,YAAY;KACrB,CAAC,EAAE,CAAC;QACJ,mBAAmB,CAAC,OAAO,EAAE,CAAC,CAAC,CAAA;QAC/B,SAAS,EAAE,CAAC,OAAO,CAAC,CAAA;QAEpB,4CAA4C;QAC5C,IAAI,OAAO,CAAC,IAAI,KAAK,WAAW,IAAI,OAAO,CAAC,OAAO,EAAE,OAAO,EAAE,CAAC;YAC9D,KAAK,MAAM,KAAK,IAAI,OAAO,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;gBAC7C,IAAI,MAAM,IAAI,KAAK,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;oBACnC,WAAW,GAAG,KAAK,CAAC,IAAc,CAAA;gBACnC,CAAC;YACF,CAAC;QACF,CAAC;IACF,CAAC;IAED,OAAO,WAAW,CAAA;AACnB,CAAC"}
@@ -1,9 +0,0 @@
1
- /**
2
- * Build the system prompt for the coder agent.
3
- */
4
- export declare function buildCoderPrompt(projectDir: string): string;
5
- /**
6
- * Build the system prompt for the planner agent.
7
- */
8
- export declare function buildPlannerPrompt(): string;
9
- //# sourceMappingURL=prompts.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"prompts.d.ts","sourceRoot":"","sources":["../../src/agents/prompts.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAuI3D;AAED;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,CAuF3C"}