@zibby/core 0.1.21 → 0.1.23

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 (167) hide show
  1. package/dist/agents/base.js +17 -0
  2. package/dist/backend-client.js +1 -0
  3. package/dist/constants/tool-names.js +1 -0
  4. package/dist/constants/zibby-scratch.js +1 -0
  5. package/dist/constants.js +1 -0
  6. package/dist/enrichment/base.js +1 -0
  7. package/dist/enrichment/enrichers/accessibility-enricher.js +1 -0
  8. package/dist/enrichment/enrichers/dom-enricher.js +1 -0
  9. package/dist/enrichment/enrichers/page-state-enricher.js +1 -0
  10. package/dist/enrichment/enrichers/position-enricher.js +1 -0
  11. package/dist/enrichment/index.js +1 -0
  12. package/dist/enrichment/mcp-integration.js +1 -0
  13. package/dist/enrichment/mcp-ref-enricher.js +1 -0
  14. package/dist/enrichment/pipeline.js +3 -0
  15. package/dist/enrichment/trace-text-enricher.js +1 -0
  16. package/dist/framework/agents/assistant-strategy.js +5 -0
  17. package/dist/framework/agents/base.js +1 -0
  18. package/dist/framework/agents/claude-strategy.js +4 -0
  19. package/dist/framework/agents/codex-strategy.js +4 -0
  20. package/dist/framework/agents/cursor-strategy.js +32 -0
  21. package/dist/framework/agents/gemini-strategy.js +11 -0
  22. package/dist/framework/agents/index.js +13 -0
  23. package/dist/framework/agents/middleware/assistant-round-pipeline.js +3 -0
  24. package/dist/framework/agents/providers/base.js +1 -0
  25. package/dist/framework/agents/providers/index.js +1 -0
  26. package/dist/framework/agents/providers/openai-transport.js +2 -0
  27. package/dist/framework/agents/providers/openai.js +1 -0
  28. package/dist/framework/agents/providers/transport-base.js +1 -0
  29. package/dist/framework/agents/utils/auth-resolver.js +1 -0
  30. package/dist/framework/agents/utils/cursor-output-formatter.js +1 -0
  31. package/dist/framework/agents/utils/openai-proxy-formatter.js +9 -0
  32. package/dist/framework/agents/utils/payload-budget.js +3 -0
  33. package/dist/framework/agents/utils/structured-output-formatter.js +21 -0
  34. package/dist/framework/code-generator.js +10 -0
  35. package/dist/framework/constants.js +1 -0
  36. package/dist/framework/context-loader.js +5 -0
  37. package/dist/framework/function-bridge.js +2 -0
  38. package/dist/framework/function-skill-registry.js +1 -0
  39. package/dist/framework/graph-compiler.js +1 -0
  40. package/dist/framework/graph.js +5 -0
  41. package/dist/framework/index.js +1 -0
  42. package/dist/framework/mcp-client.js +2 -0
  43. package/dist/framework/node-registry.js +9 -0
  44. package/dist/framework/node.js +5 -0
  45. package/dist/framework/output-parser.js +3 -0
  46. package/dist/framework/skill-registry.js +1 -0
  47. package/dist/framework/state-utils.js +1 -0
  48. package/dist/framework/state.js +1 -0
  49. package/dist/framework/tool-resolver.js +1 -0
  50. package/dist/index.js +8 -0
  51. package/dist/runtime/generation/base.js +1 -0
  52. package/dist/runtime/generation/index.js +3 -0
  53. package/dist/runtime/generation/mcp-ref-strategy.js +41 -0
  54. package/dist/runtime/generation/stable-id-strategy.js +16 -0
  55. package/dist/runtime/stable-id-runtime.js +1 -0
  56. package/dist/runtime/verification/base.js +1 -0
  57. package/dist/runtime/verification/index.js +3 -0
  58. package/dist/runtime/verification/playwright-json-strategy.js +1 -0
  59. package/dist/runtime/zibby-runtime.js +1 -0
  60. package/dist/sync/index.js +1 -0
  61. package/dist/sync/uploader.js +1 -0
  62. package/dist/tools/run-playwright-test.js +5 -0
  63. package/dist/utils/adf-converter.js +7 -0
  64. package/dist/utils/ast-utils.js +1 -0
  65. package/dist/utils/ci-setup.js +5 -0
  66. package/dist/utils/cursor-mcp-isolated-home.js +1 -0
  67. package/dist/utils/cursor-utils.js +18 -0
  68. package/dist/utils/live-frame-discovery.js +1 -0
  69. package/dist/utils/logger.js +1 -0
  70. package/dist/utils/mcp-config-writer.js +10 -0
  71. package/dist/utils/mission-control-from-run-states.js +1 -0
  72. package/dist/utils/node-schema-parser.js +1 -0
  73. package/dist/utils/parallel-config.js +1 -0
  74. package/dist/utils/post-process-events.js +1 -0
  75. package/dist/utils/result-handler.js +1 -0
  76. package/{src → dist}/utils/ripple-effect.js +3 -12
  77. package/dist/utils/run-capacity-coordinator.js +1 -0
  78. package/dist/utils/run-capacity-queue.js +2 -0
  79. package/dist/utils/run-index-merge.js +1 -0
  80. package/dist/utils/run-index-post-cli.js +1 -0
  81. package/dist/utils/run-registry.js +3 -0
  82. package/dist/utils/run-state-session.js +2 -0
  83. package/dist/utils/selector-generator.js +4 -0
  84. package/dist/utils/session-state-constants.js +1 -0
  85. package/dist/utils/session-state-live-runs.js +1 -0
  86. package/dist/utils/streaming-parser.js +4 -0
  87. package/dist/utils/test-post-processor.js +18 -0
  88. package/dist/utils/timeline.js +14 -0
  89. package/dist/utils/trace-parser.js +2 -0
  90. package/dist/utils/video-organizer.js +3 -0
  91. package/package.json +49 -35
  92. package/templates/browser-test-automation/README.md +29 -7
  93. package/templates/browser-test-automation/chat.mjs +36 -0
  94. package/templates/browser-test-automation/graph.mjs +5 -9
  95. package/templates/browser-test-automation/nodes/execute-live.mjs +30 -58
  96. package/templates/browser-test-automation/nodes/generate-script.mjs +32 -12
  97. package/templates/browser-test-automation/nodes/utils.mjs +153 -10
  98. package/templates/browser-test-automation/pipeline-ids.js +12 -0
  99. package/templates/browser-test-automation/result-handler.mjs +78 -2
  100. package/templates/browser-test-automation/run-index.mjs +418 -0
  101. package/scripts/export-default-workflows.js +0 -51
  102. package/scripts/patch-cursor-mcp.js +0 -174
  103. package/scripts/setup-ci.sh +0 -115
  104. package/scripts/setup-official-playwright-mcp.sh +0 -226
  105. package/scripts/test-with-video.sh +0 -49
  106. package/src/agents/base.js +0 -361
  107. package/src/constants.js +0 -47
  108. package/src/enrichment/base.js +0 -49
  109. package/src/enrichment/enrichers/accessibility-enricher.js +0 -197
  110. package/src/enrichment/enrichers/dom-enricher.js +0 -171
  111. package/src/enrichment/enrichers/page-state-enricher.js +0 -129
  112. package/src/enrichment/enrichers/position-enricher.js +0 -67
  113. package/src/enrichment/index.js +0 -96
  114. package/src/enrichment/mcp-integration.js +0 -149
  115. package/src/enrichment/mcp-ref-enricher.js +0 -78
  116. package/src/enrichment/pipeline.js +0 -192
  117. package/src/enrichment/trace-text-enricher.js +0 -115
  118. package/src/framework/AGENTS.md +0 -98
  119. package/src/framework/agents/base.js +0 -72
  120. package/src/framework/agents/claude-strategy.js +0 -278
  121. package/src/framework/agents/cursor-strategy.js +0 -544
  122. package/src/framework/agents/index.js +0 -105
  123. package/src/framework/agents/utils/cursor-output-formatter.js +0 -67
  124. package/src/framework/agents/utils/openai-proxy-formatter.js +0 -249
  125. package/src/framework/code-generator.js +0 -301
  126. package/src/framework/constants.js +0 -33
  127. package/src/framework/context-loader.js +0 -101
  128. package/src/framework/function-bridge.js +0 -78
  129. package/src/framework/function-skill-registry.js +0 -20
  130. package/src/framework/graph-compiler.js +0 -342
  131. package/src/framework/graph.js +0 -610
  132. package/src/framework/index.js +0 -28
  133. package/src/framework/node-registry.js +0 -163
  134. package/src/framework/node.js +0 -259
  135. package/src/framework/output-parser.js +0 -71
  136. package/src/framework/skill-registry.js +0 -55
  137. package/src/framework/state-utils.js +0 -52
  138. package/src/framework/state.js +0 -67
  139. package/src/framework/tool-resolver.js +0 -65
  140. package/src/index.js +0 -345
  141. package/src/runtime/generation/base.js +0 -46
  142. package/src/runtime/generation/index.js +0 -70
  143. package/src/runtime/generation/mcp-ref-strategy.js +0 -197
  144. package/src/runtime/generation/stable-id-strategy.js +0 -170
  145. package/src/runtime/stable-id-runtime.js +0 -248
  146. package/src/runtime/verification/base.js +0 -44
  147. package/src/runtime/verification/index.js +0 -67
  148. package/src/runtime/verification/playwright-json-strategy.js +0 -119
  149. package/src/runtime/zibby-runtime.js +0 -299
  150. package/src/sync/index.js +0 -2
  151. package/src/sync/uploader.js +0 -29
  152. package/src/tools/run-playwright-test.js +0 -158
  153. package/src/utils/adf-converter.js +0 -68
  154. package/src/utils/ast-utils.js +0 -37
  155. package/src/utils/ci-setup.js +0 -124
  156. package/src/utils/cursor-utils.js +0 -71
  157. package/src/utils/logger.js +0 -144
  158. package/src/utils/mcp-config-writer.js +0 -115
  159. package/src/utils/node-schema-parser.js +0 -522
  160. package/src/utils/post-process-events.js +0 -55
  161. package/src/utils/result-handler.js +0 -102
  162. package/src/utils/selector-generator.js +0 -239
  163. package/src/utils/streaming-parser.js +0 -387
  164. package/src/utils/test-post-processor.js +0 -211
  165. package/src/utils/timeline.js +0 -217
  166. package/src/utils/trace-parser.js +0 -325
  167. package/src/utils/video-organizer.js +0 -91
@@ -1,192 +0,0 @@
1
- /**
2
- * Enrichment Pipeline Manager
3
- * Orchestrates multiple enrichers to add data to events
4
- */
5
-
6
- export class EnrichmentPipeline {
7
- constructor(config = {}) {
8
- this.enrichers = [];
9
- this.config = config;
10
- this.stats = {
11
- totalEvents: 0,
12
- enrichedEvents: 0,
13
- skippedEvents: 0,
14
- errors: {}
15
- };
16
- }
17
-
18
- /**
19
- * Register an enricher
20
- * @param {EventEnricher} enricher
21
- */
22
- register(enricher) {
23
- this.enrichers.push(enricher);
24
- // Sort by priority (highest first)
25
- this.enrichers.sort((a, b) => b.getPriority() - a.getPriority());
26
- return this;
27
- }
28
-
29
- /**
30
- * Unregister an enricher by name
31
- * @param {string} name
32
- */
33
- unregister(name) {
34
- this.enrichers = this.enrichers.filter(e => e.getName() !== name);
35
- return this;
36
- }
37
-
38
- /**
39
- * Get enricher by name
40
- * @param {string} name
41
- */
42
- get(name) {
43
- return this.enrichers.find(e => e.getName() === name);
44
- }
45
-
46
- /**
47
- * Enable/disable specific enricher
48
- * @param {string} name
49
- * @param {boolean} enabled
50
- */
51
- setEnabled(name, enabled) {
52
- const enricher = this.get(name);
53
- if (enricher) {
54
- enricher.enabled = enabled;
55
- }
56
- return this;
57
- }
58
-
59
- /**
60
- * Enrich an event through the pipeline
61
- * @param {Object} event - MCP event
62
- * @param {Object} context - { page, element, ref, session }
63
- * @returns {Promise<Object>} - Enriched event
64
- */
65
- async enrich(event, context) {
66
- this.stats.totalEvents++;
67
-
68
- // Start with original event
69
- const enriched = { ...event };
70
-
71
- // Track which enrichers ran
72
- const enrichersRun = [];
73
- const enrichersSkipped = [];
74
- const enrichersFailed = [];
75
-
76
- // Run each enricher in priority order
77
- for (const enricher of this.enrichers) {
78
- try {
79
- // Check if enricher can run
80
- if (!enricher.canEnrich(context)) {
81
- enrichersSkipped.push(enricher.getName());
82
- continue;
83
- }
84
-
85
- // Run enricher
86
- const startTime = Date.now();
87
- const data = await enricher.enrich(event, context);
88
- const duration = Date.now() - startTime;
89
-
90
- if (data) {
91
- // Merge enriched data
92
- Object.assign(enriched, data);
93
- enrichersRun.push({ name: enricher.getName(), duration });
94
- } else {
95
- enrichersSkipped.push(enricher.getName());
96
- }
97
- } catch (error) {
98
- console.warn(`[EnrichmentPipeline] ${enricher.getName()} failed:`, error.message);
99
- enrichersFailed.push(enricher.getName());
100
-
101
- // Track errors
102
- this.stats.errors[enricher.getName()] = (this.stats.errors[enricher.getName()] || 0) + 1;
103
- }
104
- }
105
-
106
- // Add enrichment metadata
107
- enriched._enrichment = {
108
- version: '1.0',
109
- timestamp: new Date().toISOString(),
110
- enrichers: {
111
- run: enrichersRun,
112
- skipped: enrichersSkipped,
113
- failed: enrichersFailed
114
- }
115
- };
116
-
117
- // Update stats
118
- if (enrichersRun.length > 0) {
119
- this.stats.enrichedEvents++;
120
- } else {
121
- this.stats.skippedEvents++;
122
- }
123
-
124
- return enriched;
125
- }
126
-
127
- /**
128
- * Enrich multiple events in batch
129
- * @param {Array} events
130
- * @param {Object} context
131
- * @returns {Promise<Array>}
132
- */
133
- async enrichBatch(events, context) {
134
- const results = [];
135
-
136
- for (const event of events) {
137
- const enriched = await this.enrich(event, context);
138
- results.push(enriched);
139
- }
140
-
141
- return results;
142
- }
143
-
144
- /**
145
- * Get pipeline statistics
146
- */
147
- getStats() {
148
- return {
149
- ...this.stats,
150
- enrichers: this.enrichers.map(e => ({
151
- name: e.getName(),
152
- enabled: e.enabled,
153
- priority: e.getPriority(),
154
- errors: this.stats.errors[e.getName()] || 0
155
- }))
156
- };
157
- }
158
-
159
- /**
160
- * Reset statistics
161
- */
162
- resetStats() {
163
- this.stats = {
164
- totalEvents: 0,
165
- enrichedEvents: 0,
166
- skippedEvents: 0,
167
- errors: {}
168
- };
169
- }
170
-
171
- /**
172
- * Log pipeline status
173
- */
174
- logStatus() {
175
- console.log('\n📊 Enrichment Pipeline Status:');
176
- console.log(` Total events: ${this.stats.totalEvents}`);
177
- console.log(` Enriched: ${this.stats.enrichedEvents}`);
178
- console.log(` Skipped: ${this.stats.skippedEvents}`);
179
- console.log(`\n Registered enrichers (${this.enrichers.length}):`);
180
-
181
- for (const enricher of this.enrichers) {
182
- const status = enricher.enabled ? '✓' : '✗';
183
- const errors = this.stats.errors[enricher.getName()] || 0;
184
- const errorStr = errors > 0 ? ` (${errors} errors)` : '';
185
- console.log(` ${status} ${enricher.getName()} (priority: ${enricher.getPriority()})${errorStr}`);
186
- }
187
-
188
- console.log();
189
- }
190
- }
191
-
192
- export default EnrichmentPipeline;
@@ -1,115 +0,0 @@
1
- import { EventEnricher } from './base.js';
2
- import { TraceParser } from '../utils/trace-parser.js';
3
- import { existsSync } from 'fs';
4
- import { join } from 'path';
5
-
6
- /**
7
- * TraceTextEnricher - Extracts ACTUAL element text from Playwright trace
8
- *
9
- * Problem: AI might say "Login button" but actual DOM has "登录" (Chinese)
10
- * Solution: Parse trace.zip to find the actual element text at action time
11
- *
12
- * This runs AFTER recording as a post-processing step.
13
- */
14
- export class TraceTextEnricher extends EventEnricher {
15
- constructor(config = {}) {
16
- super(config);
17
- this.priority = 190; // Just below MCPRefEnricher
18
- this.traceData = null;
19
- }
20
-
21
- getName() {
22
- return 'TraceText';
23
- }
24
-
25
- getPriority() {
26
- return this.priority;
27
- }
28
-
29
- /**
30
- * Load trace data once for all events
31
- */
32
- async loadTrace(sessionPath) {
33
- if (this.traceData) return;
34
-
35
- const _tracePath = join(sessionPath, 'traces');
36
- const traceZipPath = join(sessionPath, 'trace.zip');
37
-
38
- if (existsSync(traceZipPath)) {
39
- try {
40
- this.traceData = await TraceParser.parseTraceZip(traceZipPath);
41
- console.log(`[TraceTextEnricher] ✅ Loaded trace with ${this.traceData.length} actions`);
42
- } catch (e) {
43
- console.log(`[TraceTextEnricher] ⚠️ Failed to parse trace: ${e.message}`);
44
- }
45
- }
46
- }
47
-
48
- async enrich(event, context) {
49
- const ref = event.data?.params?.ref;
50
- const eventId = event.id;
51
- if (ref === undefined && eventId === undefined) return null;
52
-
53
- // Load trace on first event
54
- if (!this.traceData && context.sessionPath) {
55
- await this.loadTrace(context.sessionPath);
56
- }
57
-
58
- if (!this.traceData) return null;
59
-
60
- // Match by sequence order: event.id maps to traceData[id]
61
- // This is more reliable than matching by ref (which trace doesn't have)
62
- const traceAction = this.traceData[eventId];
63
- if (!traceAction) {
64
- console.log(`[TraceTextEnricher] ⚠️ No trace action for event ${eventId}`);
65
- return null;
66
- }
67
-
68
- // NEW: Use the actualText extracted from accessibility tree
69
- const actualText = traceAction.actualText || this._extractTextFromSelector(traceAction.selector);
70
- const actualRole = traceAction.actualRole;
71
- const actualAriaLabel = traceAction.actualAriaLabel;
72
-
73
- if (actualText || actualRole || actualAriaLabel) {
74
- console.log(`[TraceTextEnricher] ✅ Event ${eventId}: text="${actualText}", role="${actualRole}", label="${actualAriaLabel}"`);
75
- return {
76
- traceActualText: actualText,
77
- traceActualRole: actualRole,
78
- traceActualAriaLabel: actualAriaLabel,
79
- traceSelector: traceAction.selector,
80
- traceStrategies: traceAction.strategies // Include all strategies
81
- };
82
- }
83
-
84
- return null;
85
- }
86
-
87
- /**
88
- * Extract actual text from Playwright's internal selector format
89
- * Examples:
90
- * - internal:label="登录" -> "登录"
91
- * - getByText('Submit') -> "Submit"
92
- * - getByRole('button', { name: '确定' }) -> "确定"
93
- */
94
- _extractTextFromSelector(selector) {
95
- if (!selector) return null;
96
-
97
- // Try internal:label format
98
- const labelMatch = selector.match(/internal:label="([^"]+)"/);
99
- if (labelMatch) return labelMatch[1];
100
-
101
- // Try internal:text format
102
- const textMatch = selector.match(/internal:text="([^"]+)"/);
103
- if (textMatch) return textMatch[1];
104
-
105
- // Try getByText format
106
- const getByTextMatch = selector.match(/getByText\(['"]([^'"]+)['"]\)/);
107
- if (getByTextMatch) return getByTextMatch[1];
108
-
109
- // Try getByRole with name format
110
- const getByRoleMatch = selector.match(/name:\s*['"]([^'"]+)['"]/);
111
- if (getByRoleMatch) return getByRoleMatch[1];
112
-
113
- return null;
114
- }
115
- }
@@ -1,98 +0,0 @@
1
- # Workflow Execution Architecture
2
-
3
- ## Single Source of Truth: Template Node Files
4
-
5
- Workflows are **compiled from source code**, not loaded from JSON files.
6
-
7
- The template node definitions in `packages/core/templates/` are the single source of truth.
8
- There is no static JSON workflow file — any such file (e.g. `default-analysis-workflow.json`) is stale and unused.
9
-
10
- ## How It Works
11
-
12
- ### 1. Graph Builders Compile Templates into Workflows
13
-
14
- Each workflow type has a graph builder that imports node definitions and wires them together:
15
-
16
- ```
17
- packages/core/templates/code-analysis/graph.js → buildAnalysisGraph()
18
- packages/core/templates/code-implementation/graph.js → buildImplementationGraph()
19
- ```
20
-
21
- These builders import the actual node files:
22
-
23
- ```
24
- packages/core/templates/code-analysis/nodes/
25
- ├── setup-node.js
26
- ├── analyze-ticket-node.js
27
- ├── generate-code-node.js
28
- ├── generate-test-cases-node.js
29
- └── finalize-node.js
30
- ```
31
-
32
- Each node file exports `{ name, outputSchema, execute }`. The `execute` function is the actual runtime code.
33
-
34
- ### 2. Backend Resolves Workflow at Execution Time
35
-
36
- When a user triggers an analysis (`POST /projects/:projectId/tickets/:ticketKey/analyze`), the backend resolves the workflow in this order:
37
-
38
- 1. **WORKFLOWS_TABLE** (DynamoDB) — user-customized workflow saved via the UI workflow editor
39
- 2. **project.analysisGraphConfig** (PROJECTS_TABLE) — legacy per-project config
40
- 3. **null** — no saved workflow; the CLI will use the compiled default
41
-
42
- The resolved config (or null) is uploaded to S3 as `context.json` and passed to the ECS container via `CONTEXT_PRESIGNED_URL`.
43
-
44
- ### 3. ECS Container Compiles and Runs the Graph
45
-
46
- The CLI (`packages/cli/src/commands/analyze-graph.js`) picks the workflow source:
47
-
48
- ```
49
- if (options.workflow) → local file (--workflow flag, dev only)
50
- else if (execCtx.graphConfig) → custom saved workflow from DynamoDB (serialized JSON)
51
- else → getDefaultGraph('analysis') → buildAnalysisGraph() from templates
52
- ```
53
-
54
- When using the default path, `buildAnalysisGraph()` imports the node files directly — the `execute` functions run as compiled JavaScript, not as eval'd strings.
55
-
56
- When using a saved custom workflow, `compileGraph()` deserializes the JSON and wraps `executeCode` strings via `new Function()`.
57
-
58
- ### 4. Key Implication: Saved Workflows Can Go Stale
59
-
60
- If a user saves a workflow via the UI editor, the `executeCode` is serialized as a string snapshot into DynamoDB. Future code fixes to the template node files **do not** propagate to saved workflows.
61
-
62
- **To pick up template fixes**: reset the workflow in the UI settings (Project → Settings → Workflow → Reset to Default). This deletes the DynamoDB record and forces the CLI to recompile from templates.
63
-
64
- ## State Access Pattern
65
-
66
- The graph stores each node's output under `state[nodeName]`:
67
-
68
- ```js
69
- // In graph.js after node execution:
70
- state.update({ [currentNode]: result.output });
71
-
72
- // So to access previous node results:
73
- state.analyze_ticket?.analysis // NOT state.analysis
74
- state.generate_code?.codeImplementation // NOT state.codeImplementation
75
- ```
76
-
77
- ## invokeAgent Return Shape
78
-
79
- When `invokeAgent` is called with a `schema` option, it returns `{ raw, structured }` (not the structured data directly):
80
-
81
- ```js
82
- const result = await invokeAgent(prompt, { state, model, schema: SomeSchema });
83
- const output = result?.structured || result; // unwrap
84
- ```
85
-
86
- Without a schema, it returns a plain string.
87
-
88
- ## File-Based Structured Output (Cursor Strategy)
89
-
90
- For Cursor agent, structured output uses a file-based approach:
91
-
92
- 1. Framework generates a unique file path: `.zibby/tmp/zibby-result-<timestamp>.json`
93
- 2. Instructions appended to prompt telling agent to write JSON to that file
94
- 3. After agent completes, framework reads the file and validates with Zod
95
- 4. If validation fails and `strictMode` is enabled, falls back to OpenAI proxy for schema enforcement
96
- 5. Result files are kept (not deleted) for debugging
97
-
98
- The Claude strategy uses its SDK's native structured output — completely separate path.
@@ -1,72 +0,0 @@
1
- /**
2
- * Base class for AI agent strategies.
3
- * All provider implementations (Cursor, Claude, etc.) must extend this class.
4
- *
5
- * @abstract
6
- */
7
- export class AgentStrategy {
8
- /**
9
- * @param {string} name - Provider identifier (e.g. 'cursor', 'claude')
10
- * @param {string} description - Human-readable description
11
- * @param {number} [priority=0] - Selection priority (higher = preferred)
12
- */
13
- constructor(name, description, priority = 0) {
14
- this.name = name;
15
- this.description = description;
16
- this.priority = priority;
17
- }
18
-
19
- /**
20
- * Execute a prompt against this agent.
21
- *
22
- * @abstract
23
- * @param {string} prompt - The prompt text
24
- * @param {AgentInvokeOptions} options
25
- * @returns {Promise<string | AgentStructuredResult>}
26
- * - Without schema: returns raw output string
27
- * - With schema: returns { raw: string, structured: object }
28
- * - On failure: throws Error
29
- *
30
- * @typedef {Object} AgentInvokeOptions
31
- * @property {string} [model] - Model name or 'auto'
32
- * @property {string} [workspace] - Working directory
33
- * @property {object} [schema] - Zod schema for structured output
34
- * @property {Array} [tools] - MCP tools available to the agent
35
- * @property {Array} [images] - Image attachments (provider-specific)
36
- * @property {string} [sessionPath] - Session artifact directory
37
- * @property {number} [timeout] - Execution timeout in ms
38
- * @property {object} [config] - Full workflow config
39
- *
40
- * @typedef {Object} AgentStructuredResult
41
- * @property {string} raw - Raw agent output
42
- * @property {object} structured - Parsed and validated output
43
- */
44
- async invoke(prompt, _options = {}) {
45
- throw new Error('AgentStrategy.invoke() must be implemented by subclass');
46
- }
47
-
48
- /**
49
- * Check if this agent strategy is available in the current environment.
50
- *
51
- * @abstract
52
- * @param {object} [context] - Environment context (unused by most providers)
53
- * @returns {boolean}
54
- */
55
- canHandle(_context) {
56
- throw new Error('AgentStrategy.canHandle() must be implemented by subclass');
57
- }
58
-
59
- getName() {
60
- return this.name;
61
- }
62
-
63
- getDescription() {
64
- return this.description;
65
- }
66
-
67
- getPriority() {
68
- return this.priority;
69
- }
70
- }
71
-
72
- export default AgentStrategy;