@electric-agent/agent 1.4.2 → 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
@@ -1,192 +0,0 @@
1
- /**
2
- * Known-correct import map: package → valid exports.
3
- */
4
- const CORRECT_IMPORTS = {
5
- "@tanstack/react-db": [
6
- "useLiveQuery",
7
- "useLiveSuspenseQuery",
8
- "createCollection",
9
- "localStorageCollectionOptions",
10
- "localOnlyCollectionOptions",
11
- "eq",
12
- "and",
13
- "or",
14
- "not",
15
- "gt",
16
- "gte",
17
- "lt",
18
- "lte",
19
- "inArray",
20
- "like",
21
- "ilike",
22
- "isNull",
23
- "isUndefined",
24
- "concat",
25
- "upper",
26
- "lower",
27
- "length",
28
- "count",
29
- "sum",
30
- "avg",
31
- "min",
32
- "max",
33
- ],
34
- "@tanstack/db": [
35
- "eq",
36
- "gt",
37
- "gte",
38
- "lt",
39
- "lte",
40
- "and",
41
- "or",
42
- "not",
43
- "inArray",
44
- "like",
45
- "ilike",
46
- "isNull",
47
- "isUndefined",
48
- "concat",
49
- "upper",
50
- "lower",
51
- "length",
52
- "count",
53
- "sum",
54
- "avg",
55
- "min",
56
- "max",
57
- ],
58
- "@tanstack/electric-db-collection": [
59
- "electricCollectionOptions",
60
- "isChangeMessage",
61
- "isControlMessage",
62
- ],
63
- "@electric-sql/client": ["ELECTRIC_PROTOCOL_QUERY_PARAMS", "ShapeStream", "Shape"],
64
- "@radix-ui/themes": [
65
- "Theme",
66
- "Container",
67
- "Flex",
68
- "Box",
69
- "Grid",
70
- "Section",
71
- "Heading",
72
- "Text",
73
- "Button",
74
- "IconButton",
75
- "TextField",
76
- "TextArea",
77
- "Select",
78
- "Checkbox",
79
- "Switch",
80
- "Slider",
81
- "Dialog",
82
- "DropdownMenu",
83
- "Badge",
84
- "Card",
85
- "Table",
86
- "Tabs",
87
- "Tooltip",
88
- "Avatar",
89
- "Separator",
90
- "ScrollArea",
91
- ],
92
- "@tanstack/react-router": [
93
- "createFileRoute",
94
- "createRootRoute",
95
- "Link",
96
- "Outlet",
97
- "useNavigate",
98
- "useParams",
99
- "useSearch",
100
- "redirect",
101
- ],
102
- "@tanstack/react-start": ["createStart"],
103
- "drizzle-orm": [
104
- "sql",
105
- "eq",
106
- "and",
107
- "or",
108
- "gt",
109
- "lt",
110
- "gte",
111
- "lte",
112
- "not",
113
- "inArray",
114
- "desc",
115
- "asc",
116
- ],
117
- "drizzle-orm/pg-core": [
118
- "pgTable",
119
- "pgEnum",
120
- "uuid",
121
- "text",
122
- "varchar",
123
- "integer",
124
- "serial",
125
- "boolean",
126
- "timestamp",
127
- "jsonb",
128
- "numeric",
129
- "real",
130
- "date",
131
- ],
132
- "drizzle-zod": ["createSelectSchema", "createInsertSchema", "createUpdateSchema"],
133
- "drizzle-orm/postgres-js": ["drizzle"],
134
- };
135
- /**
136
- * Known hallucinated imports that should be corrected.
137
- * Maps wrong package → guidance on the correct package.
138
- */
139
- const HALLUCINATION_MAP = {
140
- "@radix-ui/react-icons": 'lucide-react (already installed). Use named imports: import { Trash2, ArrowLeft, Plus, Check } from "lucide-react"',
141
- "drizzle-orm/zod": 'drizzle-zod (drizzle-orm/zod does not exist in drizzle-orm 0.45.x). Use: import { createSelectSchema, createInsertSchema } from "drizzle-zod"',
142
- };
143
- const IMPORT_REGEX = /import\s+\{([^}]+)\}\s+from\s+['"]([^'"]+)['"]/g;
144
- /**
145
- * PreToolUse hook: Validate imports in file content against known-correct table.
146
- * Denies writes that contain hallucinated or incorrect imports.
147
- */
148
- export const importValidation = async (input, _toolUseID, _opts) => {
149
- const preInput = input;
150
- const toolInput = preInput.tool_input;
151
- // Get file content from either Write (content) or Edit (new_string)
152
- const content = toolInput?.content || toolInput?.new_string;
153
- if (!content || typeof content !== "string")
154
- return {};
155
- // Only check TypeScript/JavaScript files
156
- const filePath = (toolInput?.file_path || "");
157
- if (!filePath.match(/\.(ts|tsx|js|jsx)$/))
158
- return {};
159
- const issues = [];
160
- for (const match of content.matchAll(IMPORT_REGEX)) {
161
- const imports = match[1]
162
- .split(",")
163
- .map((s) => s.trim())
164
- .filter(Boolean);
165
- const pkg = match[2];
166
- // Check for known hallucinated packages
167
- if (HALLUCINATION_MAP[pkg]) {
168
- issues.push(`Hallucinated import: "${pkg}" → use ${HALLUCINATION_MAP[pkg]}`);
169
- continue;
170
- }
171
- // Check against known-correct imports
172
- if (CORRECT_IMPORTS[pkg]) {
173
- for (const imp of imports) {
174
- const cleanImp = imp.replace(/\s+as\s+\w+/, "").trim();
175
- if (!CORRECT_IMPORTS[pkg].includes(cleanImp)) {
176
- issues.push(`Unknown export "${cleanImp}" from "${pkg}". Known exports: ${CORRECT_IMPORTS[pkg].join(", ")}`);
177
- }
178
- }
179
- }
180
- }
181
- if (issues.length > 0) {
182
- return {
183
- hookSpecificOutput: {
184
- hookEventName: "PreToolUse",
185
- permissionDecision: "deny",
186
- permissionDecisionReason: `Import validation failed:\n${issues.join("\n")}`,
187
- },
188
- };
189
- }
190
- return {};
191
- };
192
- //# sourceMappingURL=import-validation.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"import-validation.js","sourceRoot":"","sources":["../../src/hooks/import-validation.ts"],"names":[],"mappings":"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"}
@@ -1,15 +0,0 @@
1
- import type { HookCallbackMatcher, HookEvent } from "@anthropic-ai/claude-agent-sdk";
2
- /**
3
- * Create guardrail hooks for the coder agent, including projectDir-aware hooks.
4
- * The SessionStart hook injects both guardrails and ARCHITECTURE.md (when it exists).
5
- */
6
- export declare function createCoderHooks(projectDir: string): Partial<Record<HookEvent, HookCallbackMatcher[]>>;
7
- /**
8
- * Static hooks (guardrails only, no ARCHITECTURE.md injection).
9
- */
10
- export declare const hooks: Partial<Record<HookEvent, HookCallbackMatcher[]>>;
11
- /**
12
- * Hooks for the planner agent — blocks Bash and Write to keep it focused on reading playbooks.
13
- */
14
- export declare const plannerHooks: Partial<Record<HookEvent, HookCallbackMatcher[]>>;
15
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,SAAS,EAAE,MAAM,gCAAgC,CAAA;AASpF;;;GAGG;AACH,wBAAgB,gBAAgB,CAC/B,UAAU,EAAE,MAAM,GAChB,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,mBAAmB,EAAE,CAAC,CAAC,CASnD;AAED;;GAEG;AACH,eAAO,MAAM,KAAK,EAAE,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,mBAAmB,EAAE,CAAC,CAOnE,CAAA;AAED;;GAEG;AACH,eAAO,MAAM,YAAY,EAAE,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,mBAAmB,EAAE,CAAC,CAK1E,CAAA"}
@@ -1,42 +0,0 @@
1
- import { blockBash } from "./block-bash.js";
2
- import { dependencyGuard } from "./dependency-guard.js";
3
- import { createSessionStartHook, guardrailInject } from "./guardrail-inject.js";
4
- import { importValidation } from "./import-validation.js";
5
- import { migrationValidation } from "./migration-validation.js";
6
- import { schemaConsistency } from "./schema-consistency.js";
7
- import { writeProtection } from "./write-protection.js";
8
- /**
9
- * Create guardrail hooks for the coder agent, including projectDir-aware hooks.
10
- * The SessionStart hook injects both guardrails and ARCHITECTURE.md (when it exists).
11
- */
12
- export function createCoderHooks(projectDir) {
13
- return {
14
- SessionStart: [{ hooks: [createSessionStartHook(projectDir)] }],
15
- PreToolUse: [
16
- { matcher: "Write|Edit", hooks: [writeProtection, importValidation, dependencyGuard] },
17
- { matcher: "Bash", hooks: [migrationValidation] },
18
- ],
19
- PostToolUse: [{ matcher: "Write|Edit", hooks: [schemaConsistency] }],
20
- };
21
- }
22
- /**
23
- * Static hooks (guardrails only, no ARCHITECTURE.md injection).
24
- */
25
- export const hooks = {
26
- SessionStart: [{ hooks: [guardrailInject] }],
27
- PreToolUse: [
28
- { matcher: "Write|Edit", hooks: [writeProtection, importValidation, dependencyGuard] },
29
- { matcher: "Bash", hooks: [migrationValidation] },
30
- ],
31
- PostToolUse: [{ matcher: "Write|Edit", hooks: [schemaConsistency] }],
32
- };
33
- /**
34
- * Hooks for the planner agent — blocks Bash and Write to keep it focused on reading playbooks.
35
- */
36
- export const plannerHooks = {
37
- PreToolUse: [
38
- { matcher: "Bash", hooks: [blockBash] },
39
- { matcher: "Write|Edit", hooks: [blockBash] },
40
- ],
41
- };
42
- //# sourceMappingURL=index.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAC3C,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA;AACvD,OAAO,EAAE,sBAAsB,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA;AAC/E,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAA;AACzD,OAAO,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAA;AAC/D,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAA;AAC3D,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA;AAEvD;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAC/B,UAAkB;IAElB,OAAO;QACN,YAAY,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,sBAAsB,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC;QAC/D,UAAU,EAAE;YACX,EAAE,OAAO,EAAE,YAAY,EAAE,KAAK,EAAE,CAAC,eAAe,EAAE,gBAAgB,EAAE,eAAe,CAAC,EAAE;YACtF,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,mBAAmB,CAAC,EAAE;SACjD;QACD,WAAW,EAAE,CAAC,EAAE,OAAO,EAAE,YAAY,EAAE,KAAK,EAAE,CAAC,iBAAiB,CAAC,EAAE,CAAC;KACpE,CAAA;AACF,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,MAAM,KAAK,GAAsD;IACvE,YAAY,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,eAAe,CAAC,EAAE,CAAC;IAC5C,UAAU,EAAE;QACX,EAAE,OAAO,EAAE,YAAY,EAAE,KAAK,EAAE,CAAC,eAAe,EAAE,gBAAgB,EAAE,eAAe,CAAC,EAAE;QACtF,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,mBAAmB,CAAC,EAAE;KACjD;IACD,WAAW,EAAE,CAAC,EAAE,OAAO,EAAE,YAAY,EAAE,KAAK,EAAE,CAAC,iBAAiB,CAAC,EAAE,CAAC;CACpE,CAAA;AAED;;GAEG;AACH,MAAM,CAAC,MAAM,YAAY,GAAsD;IAC9E,UAAU,EAAE;QACX,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,SAAS,CAAC,EAAE;QACvC,EAAE,OAAO,EAAE,YAAY,EAAE,KAAK,EAAE,CAAC,SAAS,CAAC,EAAE;KAC7C;CACD,CAAA"}
@@ -1,9 +0,0 @@
1
- import type { HookCallback } from "@anthropic-ai/claude-agent-sdk";
2
- /**
3
- * PreToolUse hook: Intercept `drizzle-kit migrate` or `drizzle-kit push` commands.
4
- * Before allowing the command, scan all .sql files in drizzle/ and ensure every
5
- * CREATE TABLE has a corresponding ALTER TABLE ... REPLICA IDENTITY FULL.
6
- * Auto-fixes by appending the missing ALTER statements.
7
- */
8
- export declare const migrationValidation: HookCallback;
9
- //# sourceMappingURL=migration-validation.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"migration-validation.d.ts","sourceRoot":"","sources":["../../src/hooks/migration-validation.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAuB,MAAM,gCAAgC,CAAA;AAKvF;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB,EAAE,YA6DjC,CAAA"}
@@ -1,62 +0,0 @@
1
- import fs from "node:fs";
2
- import path from "node:path";
3
- const CREATE_TABLE_REGEX = /CREATE\s+TABLE\s+(?:IF\s+NOT\s+EXISTS\s+)?["']?(\w+)["']?/gi;
4
- const REPLICA_IDENTITY_REGEX = /ALTER\s+TABLE\s+["']?(\w+)["']?\s+REPLICA\s+IDENTITY\s+FULL/gi;
5
- /**
6
- * PreToolUse hook: Intercept `drizzle-kit migrate` or `drizzle-kit push` commands.
7
- * Before allowing the command, scan all .sql files in drizzle/ and ensure every
8
- * CREATE TABLE has a corresponding ALTER TABLE ... REPLICA IDENTITY FULL.
9
- * Auto-fixes by appending the missing ALTER statements.
10
- */
11
- export const migrationValidation = async (input, _toolUseID, _opts) => {
12
- const preInput = input;
13
- const toolInput = preInput.tool_input;
14
- const command = toolInput?.command;
15
- if (!command)
16
- return {};
17
- // Only intercept drizzle-kit migrate or push
18
- if (!command.includes("drizzle-kit migrate") && !command.includes("drizzle-kit push")) {
19
- return {};
20
- }
21
- const cwd = input.cwd || process.cwd();
22
- const drizzleDir = path.join(cwd, "drizzle");
23
- if (!fs.existsSync(drizzleDir))
24
- return {};
25
- let fixed = false;
26
- for (const file of fs.readdirSync(drizzleDir)) {
27
- if (!file.endsWith(".sql"))
28
- continue;
29
- const filePath = path.join(drizzleDir, file);
30
- const content = fs.readFileSync(filePath, "utf-8");
31
- // Find all CREATE TABLE statements
32
- const createTables = new Set();
33
- for (const match of content.matchAll(CREATE_TABLE_REGEX)) {
34
- createTables.add(match[1].toLowerCase());
35
- }
36
- // Find all REPLICA IDENTITY FULL statements
37
- const replicaTables = new Set();
38
- for (const match of content.matchAll(REPLICA_IDENTITY_REGEX)) {
39
- replicaTables.add(match[1].toLowerCase());
40
- }
41
- // Append missing REPLICA IDENTITY FULL
42
- const missing = [...createTables].filter((t) => !replicaTables.has(t));
43
- if (missing.length > 0) {
44
- const additions = missing
45
- .map((table) => `\nALTER TABLE "${table}" REPLICA IDENTITY FULL;`)
46
- .join("\n");
47
- fs.appendFileSync(filePath, `${additions}\n`, "utf-8");
48
- fixed = true;
49
- }
50
- }
51
- if (fixed) {
52
- return {
53
- hookSpecificOutput: {
54
- hookEventName: "PreToolUse",
55
- permissionDecision: "allow",
56
- permissionDecisionReason: "Auto-appended REPLICA IDENTITY FULL to migration files for Electric compatibility.",
57
- },
58
- };
59
- }
60
- return {};
61
- };
62
- //# sourceMappingURL=migration-validation.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"migration-validation.js","sourceRoot":"","sources":["../../src/hooks/migration-validation.ts"],"names":[],"mappings":"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"}
@@ -1,12 +0,0 @@
1
- import type { HookCallback } from "@anthropic-ai/claude-agent-sdk";
2
- /**
3
- * PostToolUse hook: After writing a collection file, verify it imports schemas
4
- * from the Drizzle-derived zod-schemas module instead of hand-writing Zod schemas.
5
- *
6
- * Also checks zod-schemas files for:
7
- * - Missing timestamp overrides (Electric streams dates as ISO strings)
8
- * - Wrong zod import (must use "zod/v4", not "zod")
9
- * - Using z.coerce.date() (creates ZodEffects rejected by TanStack DB)
10
- */
11
- export declare const schemaConsistency: HookCallback;
12
- //# sourceMappingURL=schema-consistency.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"schema-consistency.d.ts","sourceRoot":"","sources":["../../src/hooks/schema-consistency.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAwB,MAAM,gCAAgC,CAAA;AAExF;;;;;;;;GAQG;AACH,eAAO,MAAM,iBAAiB,EAAE,YAyF/B,CAAA"}
@@ -1,72 +0,0 @@
1
- /**
2
- * PostToolUse hook: After writing a collection file, verify it imports schemas
3
- * from the Drizzle-derived zod-schemas module instead of hand-writing Zod schemas.
4
- *
5
- * Also checks zod-schemas files for:
6
- * - Missing timestamp overrides (Electric streams dates as ISO strings)
7
- * - Wrong zod import (must use "zod/v4", not "zod")
8
- * - Using z.coerce.date() (creates ZodEffects rejected by TanStack DB)
9
- */
10
- export const schemaConsistency = async (input, _toolUseID, _opts) => {
11
- const postInput = input;
12
- const toolInput = postInput.tool_input;
13
- const filePath = (toolInput?.file_path || "");
14
- const content = (toolInput?.content || toolInput?.new_string || "");
15
- if (!content)
16
- return {};
17
- // Check zod-schemas files for date override issues
18
- if (filePath.includes("zod-schemas")) {
19
- const warnings = [];
20
- // Check for z.coerce.date() — creates ZodEffects that TanStack DB rejects
21
- if (content.includes("z.coerce.date()")) {
22
- warnings.push("BLOCKED: z.coerce.date() creates ZodEffects/pipe types that TanStack DB's schema introspection rejects with 'Invalid element: expected a Zod schema'. Use z.union([z.date(), z.string()]) instead.");
23
- }
24
- // Check for wrong zod import — must be "zod/v4" for drizzle-zod 0.8.x compatibility
25
- if ((content.includes('from "zod"') || content.includes("from 'zod'")) &&
26
- !content.includes("zod/v4")) {
27
- warnings.push('BLOCKED: Import z from "zod/v4" instead of "zod". drizzle-zod 0.8.x uses Zod v4 internals, and the v4 runtime rejects v3-style schema overrides.');
28
- }
29
- // Check for createSelectSchema without timestamp overrides
30
- if (content.includes("createSelectSchema") &&
31
- (content.includes("_at") || content.includes("At")) &&
32
- !content.includes("z.union") &&
33
- !content.includes("dateOrString")) {
34
- warnings.push("WARNING: createSelectSchema appears to have timestamp columns without z.union([z.date(), z.string()]).default(() => new Date()) overrides. Electric SQL streams dates as ISO strings — without this override, collection.update() will throw SchemaValidationError.");
35
- }
36
- // Check for z.union([z.date(), z.string()]) without .default() — causes collection.insert() to fail
37
- if (content.includes("z.union") &&
38
- (content.includes("_at") || content.includes("At")) &&
39
- !content.includes(".default(")) {
40
- warnings.push("WARNING: Timestamp overrides use z.union([z.date(), z.string()]) without .default(() => new Date()). Without .default(), collection.insert() will throw SchemaValidationError on created_at/updated_at because the client doesn't provide them (the DB sets defaults server-side). Fix: const dateOrString = z.union([z.date(), z.string()]).default(() => new Date())");
41
- }
42
- if (warnings.length > 0) {
43
- return {
44
- hookSpecificOutput: {
45
- hookEventName: "PostToolUse",
46
- additionalContext: warnings.join("\n\n"),
47
- },
48
- };
49
- }
50
- return {};
51
- }
52
- // Only check collection files below this point
53
- if (!filePath.includes("/db/collections/") && !filePath.includes("/collections/")) {
54
- return {};
55
- }
56
- // Warn if the file uses z.object() or z.string() directly instead of importing from zod-schemas
57
- const hasHandWrittenZod = content.includes("z.object(") ||
58
- content.includes("z.string(") ||
59
- content.includes("z.number(") ||
60
- content.includes("z.boolean(");
61
- const importsFromZodSchemas = content.includes("zod-schemas") || content.includes("zod_schemas");
62
- if (hasHandWrittenZod && !importsFromZodSchemas) {
63
- return {
64
- hookSpecificOutput: {
65
- hookEventName: "PostToolUse",
66
- additionalContext: "WARNING: This collection file appears to use hand-written Zod schemas instead of Drizzle-derived schemas. Import schemas from '../zod-schemas' (generated via createSelectSchema from drizzle-zod) to maintain the single-source-of-truth type chain.",
67
- },
68
- };
69
- }
70
- return {};
71
- };
72
- //# sourceMappingURL=schema-consistency.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"schema-consistency.js","sourceRoot":"","sources":["../../src/hooks/schema-consistency.ts"],"names":[],"mappings":"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"}
@@ -1,7 +0,0 @@
1
- import type { HookCallback } from "@anthropic-ai/claude-agent-sdk";
2
- /**
3
- * PreToolUse hook: Block writes to protected config files.
4
- * Silent rejection — the agent doesn't see the error.
5
- */
6
- export declare const writeProtection: HookCallback;
7
- //# sourceMappingURL=write-protection.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"write-protection.d.ts","sourceRoot":"","sources":["../../src/hooks/write-protection.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAuB,MAAM,gCAAgC,CAAA;AAYvF;;;GAGG;AACH,eAAO,MAAM,eAAe,EAAE,YAqB7B,CAAA"}
@@ -1,33 +0,0 @@
1
- const PROTECTED_FILES = new Set([
2
- "docker-compose.yml",
3
- "Caddyfile",
4
- "tsconfig.json",
5
- "biome.json",
6
- "pnpm-lock.yaml",
7
- "postgres.conf",
8
- "vitest.config.ts",
9
- ]);
10
- /**
11
- * PreToolUse hook: Block writes to protected config files.
12
- * Silent rejection — the agent doesn't see the error.
13
- */
14
- export const writeProtection = async (input, _toolUseID, _opts) => {
15
- const preInput = input;
16
- const toolInput = preInput.tool_input;
17
- const filePath = toolInput?.file_path;
18
- if (!filePath)
19
- return {};
20
- const fileName = filePath.split("/").pop() || "";
21
- if (PROTECTED_FILES.has(fileName)) {
22
- return {
23
- suppressOutput: true,
24
- hookSpecificOutput: {
25
- hookEventName: "PreToolUse",
26
- permissionDecision: "deny",
27
- permissionDecisionReason: `File "${fileName}" is protected and cannot be modified after scaffolding.`,
28
- },
29
- };
30
- }
31
- return {};
32
- };
33
- //# sourceMappingURL=write-protection.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"write-protection.js","sourceRoot":"","sources":["../../src/hooks/write-protection.ts"],"names":[],"mappings":"AAEA,MAAM,eAAe,GAAG,IAAI,GAAG,CAAC;IAC/B,oBAAoB;IACpB,WAAW;IACX,eAAe;IACf,YAAY;IACZ,gBAAgB;IAChB,eAAe;IACf,kBAAkB;CAClB,CAAC,CAAA;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,eAAe,GAAiB,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,EAAE;IAC/E,MAAM,QAAQ,GAAG,KAA4B,CAAA;IAC7C,MAAM,SAAS,GAAG,QAAQ,CAAC,UAAiD,CAAA;IAC5E,MAAM,QAAQ,GAAG,SAAS,EAAE,SAA+B,CAAA;IAE3D,IAAI,CAAC,QAAQ;QAAE,OAAO,EAAE,CAAA;IAExB,MAAM,QAAQ,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,CAAA;IAEhD,IAAI,eAAe,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;QACnC,OAAO;YACN,cAAc,EAAE,IAAI;YACpB,kBAAkB,EAAE;gBACnB,aAAa,EAAE,YAAqB;gBACpC,kBAAkB,EAAE,MAAe;gBACnC,wBAAwB,EAAE,SAAS,QAAQ,0DAA0D;aACrG;SACD,CAAA;IACF,CAAC;IAED,OAAO,EAAE,CAAA;AACV,CAAC,CAAA"}
@@ -1,15 +0,0 @@
1
- type LogLevel = "plan" | "approve" | "task" | "build" | "fix" | "done" | "error" | "verbose";
2
- export interface ProgressReporter {
3
- log(level: LogLevel, message: string): void;
4
- logToolUse(toolName: string, summary: string): void;
5
- verboseMode: boolean;
6
- }
7
- export declare function createProgressReporter(opts?: {
8
- verbose?: boolean;
9
- }): ProgressReporter;
10
- /**
11
- * Process SDK messages and route them to the progress reporter.
12
- */
13
- export declare function processAgentMessage(message: Record<string, unknown>, reporter: ProgressReporter): void;
14
- export {};
15
- //# sourceMappingURL=reporter.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"reporter.d.ts","sourceRoot":"","sources":["../../src/progress/reporter.ts"],"names":[],"mappings":"AAAA,KAAK,QAAQ,GAAG,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,OAAO,GAAG,KAAK,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,CAAA;AAa5F,MAAM,WAAW,gBAAgB;IAChC,GAAG,CAAC,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3C,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;IACnD,WAAW,EAAE,OAAO,CAAA;CACpB;AAED,wBAAgB,sBAAsB,CAAC,IAAI,CAAC,EAAE;IAAE,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,gBAAgB,CAgBrF;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAClC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChC,QAAQ,EAAE,gBAAgB,GACxB,IAAI,CAqGN"}
@@ -1,133 +0,0 @@
1
- const PREFIXES = {
2
- plan: "\x1b[36m[plan]\x1b[0m",
3
- approve: "\x1b[33m[approve]\x1b[0m",
4
- task: "\x1b[34m[task]\x1b[0m",
5
- build: "\x1b[35m[build]\x1b[0m",
6
- fix: "\x1b[33m[fix]\x1b[0m",
7
- done: "\x1b[32m[done]\x1b[0m",
8
- error: "\x1b[31m[error]\x1b[0m",
9
- verbose: "\x1b[2m[verbose]\x1b[0m",
10
- };
11
- export function createProgressReporter(opts) {
12
- const verboseMode = opts?.verbose ?? false;
13
- return {
14
- verboseMode,
15
- log(level, message) {
16
- if (level === "verbose" && !verboseMode)
17
- return;
18
- console.log(`${PREFIXES[level]} ${message}`);
19
- },
20
- logToolUse(toolName, summary) {
21
- const prefix = "\x1b[2m";
22
- const reset = "\x1b[0m";
23
- console.log(`${prefix} ↳ ${toolName}: ${summary}${reset}`);
24
- },
25
- };
26
- }
27
- /**
28
- * Process SDK messages and route them to the progress reporter.
29
- */
30
- export function processAgentMessage(message, reporter) {
31
- if (message.type === "assistant" && message.message?.content) {
32
- const content = message.message.content;
33
- for (const block of content) {
34
- if ("text" in block && block.text) {
35
- const text = block.text;
36
- if (reporter.verboseMode) {
37
- reporter.log("verbose", text);
38
- }
39
- else if (text.length > 10) {
40
- reporter.log("task", text);
41
- }
42
- }
43
- else if ("thinking" in block && block.thinking && reporter.verboseMode) {
44
- const thinking = block.thinking;
45
- reporter.log("verbose", `[thinking] ${thinking.slice(0, 500)}`);
46
- }
47
- else if ("name" in block) {
48
- const name = block.name;
49
- const input = (block.input || {});
50
- if (name === "Write" || name === "Edit") {
51
- reporter.logToolUse(name, (input.file_path || "unknown file"));
52
- }
53
- else if (name === "Bash") {
54
- const cmd = (input.command || "");
55
- reporter.logToolUse("Bash", cmd.slice(0, 80));
56
- }
57
- else if (name.includes("build")) {
58
- reporter.log("build", "Running build...");
59
- }
60
- else if (name.includes("playbook")) {
61
- reporter.logToolUse("Playbook", (input.name || "read"));
62
- }
63
- }
64
- }
65
- }
66
- else if (message.type === "user" && message.message?.content) {
67
- // SDK sends tool results as user messages with tool_result content blocks
68
- const msgContent = message.message.content;
69
- if (Array.isArray(msgContent)) {
70
- for (const block of msgContent) {
71
- if (typeof block === "object" &&
72
- block &&
73
- block.type === "tool_result") {
74
- const b = block;
75
- const content = b.content;
76
- const texts = [];
77
- if (typeof content === "string") {
78
- texts.push(content);
79
- }
80
- else if (Array.isArray(content)) {
81
- for (const inner of content) {
82
- if (typeof inner === "object" && inner && "text" in inner) {
83
- texts.push(inner.text);
84
- }
85
- }
86
- }
87
- for (const text of texts) {
88
- // Always surface build tool results (even without --verbose)
89
- if (text.includes("=== pnpm run build ===")) {
90
- try {
91
- const result = JSON.parse(text);
92
- const output = result.output || "";
93
- const lines = output.split("\n").filter((l) => l.trim());
94
- const tail = lines.slice(-8).join("\n");
95
- if (!result.success) {
96
- reporter.log("build", `FAILED (${result.errors})`);
97
- reporter.log("build", tail);
98
- }
99
- else {
100
- reporter.log("build", "Build passed");
101
- }
102
- }
103
- catch {
104
- // Not JSON — show raw tail
105
- const lines = text.split("\n").filter((l) => l.trim());
106
- reporter.log("build", lines.slice(-5).join("\n"));
107
- }
108
- continue;
109
- }
110
- if (reporter.verboseMode) {
111
- reporter.log("verbose", `[tool_result] ${text.slice(0, 1000)}`);
112
- }
113
- }
114
- }
115
- }
116
- }
117
- }
118
- else if (message.type === "result") {
119
- const sub = String(message.subtype);
120
- const cost = message.total_cost_usd;
121
- const costStr = `(cost: $${cost?.toFixed(4) || "?"})`;
122
- if (sub === "success") {
123
- reporter.log("done", `Agent completed ${costStr}`);
124
- }
125
- else if (sub.includes("max_turns")) {
126
- reporter.log("task", `Agent reached turn limit ${costStr}`);
127
- }
128
- else {
129
- reporter.log("error", `Agent stopped: ${sub} ${costStr}`);
130
- }
131
- }
132
- }
133
- //# sourceMappingURL=reporter.js.map