@limo-labs/limo-cli 0.1.0-alpha.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 (42) hide show
  1. package/README.md +238 -0
  2. package/dist/agents/analyst.d.ts +24 -0
  3. package/dist/agents/analyst.js +128 -0
  4. package/dist/agents/editor.d.ts +26 -0
  5. package/dist/agents/editor.js +157 -0
  6. package/dist/agents/planner-validator.d.ts +7 -0
  7. package/dist/agents/planner-validator.js +125 -0
  8. package/dist/agents/planner.d.ts +56 -0
  9. package/dist/agents/planner.js +186 -0
  10. package/dist/agents/writer.d.ts +25 -0
  11. package/dist/agents/writer.js +164 -0
  12. package/dist/commands/analyze.d.ts +14 -0
  13. package/dist/commands/analyze.js +562 -0
  14. package/dist/index.d.ts +2 -0
  15. package/dist/index.js +41 -0
  16. package/dist/report/diagrams.d.ts +27 -0
  17. package/dist/report/diagrams.js +74 -0
  18. package/dist/report/graphCompiler.d.ts +37 -0
  19. package/dist/report/graphCompiler.js +277 -0
  20. package/dist/report/markdownGenerator.d.ts +71 -0
  21. package/dist/report/markdownGenerator.js +148 -0
  22. package/dist/tools/additional.d.ts +116 -0
  23. package/dist/tools/additional.js +349 -0
  24. package/dist/tools/extended.d.ts +101 -0
  25. package/dist/tools/extended.js +586 -0
  26. package/dist/tools/index.d.ts +86 -0
  27. package/dist/tools/index.js +362 -0
  28. package/dist/types/agents.types.d.ts +139 -0
  29. package/dist/types/agents.types.js +6 -0
  30. package/dist/types/graphSemantics.d.ts +99 -0
  31. package/dist/types/graphSemantics.js +104 -0
  32. package/dist/utils/debug.d.ts +28 -0
  33. package/dist/utils/debug.js +125 -0
  34. package/dist/utils/limoConfigParser.d.ts +21 -0
  35. package/dist/utils/limoConfigParser.js +274 -0
  36. package/dist/utils/reviewMonitor.d.ts +20 -0
  37. package/dist/utils/reviewMonitor.js +121 -0
  38. package/package.json +62 -0
  39. package/prompts/analyst.md +343 -0
  40. package/prompts/editor.md +196 -0
  41. package/prompts/planner.md +388 -0
  42. package/prompts/writer.md +218 -0
package/README.md ADDED
@@ -0,0 +1,238 @@
1
+ # Limo CLI
2
+
3
+ Command-line interface for Limo - AI-powered codebase analysis and migration planning tool.
4
+
5
+ ## Features
6
+
7
+ - 🤖 **Multi-Agent Analysis** - Planner, Analyst, Writer, and Editor agents collaborate
8
+ - 📊 **Professional Reports** - Executive summaries, diagrams, and detailed analysis
9
+ - 🎯 **LIMO.md Support** - Customize analysis scope with LIMO.md configuration
10
+ - 📈 **Semantic Diagrams** - Type-safe architecture diagrams with nodes and edges
11
+ - 🌍 **Multi-language** - Supports English, 简体中文, 日本語, and more
12
+
13
+ ## Installation
14
+
15
+ ```bash
16
+ npm install
17
+ npm run build
18
+ ```
19
+
20
+ ## Usage
21
+
22
+ ### Basic Analysis
23
+
24
+ ```bash
25
+ node dist/index.js analyze /path/to/project
26
+ ```
27
+
28
+ ### With Options
29
+
30
+ ```bash
31
+ # Specify language
32
+ node dist/index.js analyze /path/to/project --lang 简体中文
33
+
34
+ # Verbose mode (show AI thinking)
35
+ node dist/index.js analyze /path/to/project --verbose
36
+
37
+ # Custom modules
38
+ node dist/index.js analyze /path/to/project --modules architecture,security,dependencies
39
+
40
+ # Custom output directory
41
+ node dist/index.js analyze /path/to/project --output .limo-reports
42
+ ```
43
+
44
+ ## LIMO.md Configuration
45
+
46
+ Create a `LIMO.md` file in your project root to customize the analysis:
47
+
48
+ ```markdown
49
+ # LIMO Configuration
50
+
51
+ ## Focus Areas
52
+ - security
53
+ - architecture
54
+ - dependencies
55
+
56
+ ## Exclude
57
+ - testing
58
+ - migration
59
+
60
+ ## Analysis Scope
61
+ Focus on the authentication and authorization modules.
62
+
63
+ ## Company Context
64
+ This is a financial institution with strict security requirements.
65
+
66
+ ## Constraints
67
+ - Must use Java 17
68
+ - Cannot use external dependencies
69
+ - Must maintain backward compatibility
70
+ ```
71
+
72
+ The CLI will automatically detect and parse LIMO.md, adjusting the analysis accordingly.
73
+
74
+ ## Architecture
75
+
76
+ ### 4-Phase Analysis Workflow
77
+
78
+ 1. **Planning** - Planner creates comprehensive analysis plan
79
+ 2. **Analysis** - Analyst performs deep code exploration
80
+ 3. **Writing** - Writer generates detailed report sections
81
+ 4. **Editing** - Editor creates executive summary and finalizes report
82
+
83
+ ### Report Structure
84
+
85
+ ```markdown
86
+ # Analysis Report - Project Name
87
+
88
+ **Generated**: February 21, 2026, 12:00:00 AM
89
+ **Project**: /path/to/project
90
+ **AI Model**: claude-opus-4.6
91
+ **Analysis Modules**: architecture, security, dependencies
92
+
93
+ **Statistics**:
94
+ - Report Sections: 15
95
+ - Diagrams: 8
96
+ - Key Findings: 42
97
+
98
+ ---
99
+
100
+ ## 📊 Executive Summary
101
+
102
+ [Overall analysis summary...]
103
+
104
+ ---
105
+
106
+ ## Architecture Analysis
107
+
108
+ [Detailed content...]
109
+
110
+ ![Architecture Diagram](data:image/svg+xml;base64,...)
111
+
112
+ *Diagram: System architecture showing main components*
113
+
114
+ ---
115
+
116
+ ## Security Analysis
117
+
118
+ [Detailed content...]
119
+
120
+ ![Security Flow](data:image/svg+xml;base64,...)
121
+
122
+ *Diagram: Authentication and authorization flow*
123
+ ```
124
+
125
+ ## Report Output
126
+
127
+ Reports are saved to `.limo/reports/{uuid}/`:
128
+ - `report.md` - Final markdown report
129
+ - `memory.json` - Analysis memories
130
+ - `plan.json` - Analysis plan
131
+
132
+ ## Development
133
+
134
+ ### Build
135
+
136
+ ```bash
137
+ npm run build
138
+ ```
139
+
140
+ ### Watch Mode
141
+
142
+ ```bash
143
+ npm run watch
144
+ ```
145
+
146
+ ### Debug
147
+
148
+ ```bash
149
+ # Enable debug logging
150
+ LIMO_DEBUG=true node dist/index.js analyze /path/to/project
151
+
152
+ # Enable API debug logging
153
+ LIMO_DEBUG_API=true node dist/index.js analyze /path/to/project
154
+ ```
155
+
156
+ ## Requirements
157
+
158
+ - Node.js 18+
159
+ - GitHub Copilot subscription (for AI analysis)
160
+ - `gh` CLI installed and authenticated
161
+
162
+ ## Project Structure
163
+
164
+ ```
165
+ src/
166
+ ├── index.ts # CLI entry point
167
+ ├── commands/
168
+ │ └── analyze.ts # Main analysis command
169
+ ├── agents/
170
+ │ ├── planner.ts # Planning agent
171
+ │ ├── analyst.ts # Analysis agent
172
+ │ ├── writer.ts # Writing agent
173
+ │ └── editor.ts # Editing agent
174
+ ├── tools/
175
+ │ ├── index.ts # Core tools
176
+ │ ├── extended.ts # Extended tools
177
+ │ └── additional.ts # Additional tools
178
+ ├── report/
179
+ │ ├── markdownGenerator.ts # Report generation
180
+ │ ├── diagrams.ts # Diagram embedding
181
+ │ └── graphCompiler.ts # Graph to SVG compilation
182
+ ├── utils/
183
+ │ ├── debug.ts # Debug utilities
184
+ │ └── limoConfigParser.ts # LIMO.md parser
185
+ └── types/
186
+ └── graphSemantics.ts # Graph type definitions
187
+
188
+ prompts/
189
+ ├── planner.md # Planner agent prompt
190
+ ├── analyst.md # Analyst agent prompt
191
+ ├── writer.md # Writer agent prompt
192
+ └── editor.md # Editor agent prompt
193
+ ```
194
+
195
+ ## Key Features
196
+
197
+ ### Semantic Diagrams
198
+
199
+ Uses type-safe graph semantics for diagrams:
200
+
201
+ ```typescript
202
+ {
203
+ "diagram_id": "architecture",
204
+ "title": "System Architecture",
205
+ "nodes": [
206
+ { "id": "web", "label": "Web Layer", "type": "layer" },
207
+ { "id": "api", "label": "API Layer", "type": "layer" },
208
+ { "id": "data", "label": "Data Layer", "type": "layer" }
209
+ ],
210
+ "edges": [
211
+ { "from": "web", "to": "api", "type": "calls" },
212
+ { "from": "api", "to": "data", "type": "calls" }
213
+ ]
214
+ }
215
+ ```
216
+
217
+ Available node types: `component`, `layer`, `system`, `data`, `process`, `actor`, `external`
218
+ Available edge types: `dependency`, `calls`, `uses`, `contains`, `inherits`, `implements`, `data_flow`, `control_flow`, `stored_in`, `manages`
219
+
220
+ ### LIMO.md Parser
221
+
222
+ Automatically parses LIMO.md with smart detection:
223
+ - **Structured Markdown** - Sections with headings and lists
224
+ - **Natural Language** - Keywords like "focus on", "skip", "must"
225
+ - **Module Validation** - Validates against known modules
226
+ - **Constraints Extraction** - Finds "must", "cannot", "should not" statements
227
+
228
+ ## License
229
+
230
+ MIT
231
+
232
+ ## Contributing
233
+
234
+ Contributions welcome! Please open an issue or PR.
235
+
236
+ ---
237
+
238
+ **Built with ❤️ using GitHub Copilot and Claude**
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Analyst Agent - Performs deep code analysis based on plan tasks
3
+ * Using declarative TSX syntax
4
+ */
5
+ import { z } from 'zod';
6
+ import { type AgentNode } from '@limo-labs/deity';
7
+ declare const AnalystInputSchema: z.ZodObject<{
8
+ task: z.ZodAny;
9
+ workspaceRoot: z.ZodString;
10
+ promptsDir: z.ZodString;
11
+ }, z.core.$strip>;
12
+ type AnalystInput = z.infer<typeof AnalystInputSchema>;
13
+ declare const AnalystOutputSchema: z.ZodObject<{
14
+ taskId: z.ZodString;
15
+ success: z.ZodBoolean;
16
+ memoriesCreated: z.ZodNumber;
17
+ error: z.ZodOptional<z.ZodString>;
18
+ }, z.core.$strip>;
19
+ type AnalystOutput = z.infer<typeof AnalystOutputSchema>;
20
+ /**
21
+ * Create Analyst Agent using declarative TSX syntax
22
+ */
23
+ export declare function createAnalystAgent(promptsDir: string): AgentNode<AnalystInput, AnalystOutput>;
24
+ export {};
@@ -0,0 +1,128 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "@limo-labs/deity/jsx-runtime";
2
+ /**
3
+ * Analyst Agent - Performs deep code analysis based on plan tasks
4
+ * Using declarative TSX syntax
5
+ */
6
+ import { z } from 'zod';
7
+ import { Agent, Prompt, System, User, Result, Validate, Retry } from '@limo-labs/deity';
8
+ import { countToolCalls } from '@limo-labs/deity';
9
+ import * as fs from 'fs/promises';
10
+ import * as path from 'path';
11
+ // Input schema
12
+ const AnalystInputSchema = z.object({
13
+ task: z.any(), // Task object from plan
14
+ workspaceRoot: z.string(),
15
+ promptsDir: z.string()
16
+ });
17
+ // Output schema
18
+ const AnalystOutputSchema = z.object({
19
+ taskId: z.string(),
20
+ success: z.boolean(),
21
+ memoriesCreated: z.number(),
22
+ error: z.string().optional()
23
+ });
24
+ /**
25
+ * Build system prompt by loading from prompts directory
26
+ */
27
+ async function buildSystemPrompt(promptsDir) {
28
+ const promptPath = path.join(promptsDir, 'analyst.md');
29
+ // Verify prompt file exists before reading
30
+ try {
31
+ await fs.access(promptPath);
32
+ }
33
+ catch (error) {
34
+ throw new Error(`Critical: Analyst prompt file not found at ${promptPath}\n` +
35
+ `Please ensure prompts are copied from VSCode extension or run 'npm run sync-prompts'`);
36
+ }
37
+ return await fs.readFile(promptPath, 'utf-8');
38
+ }
39
+ /**
40
+ * Build user message with analysis task details
41
+ */
42
+ function buildUserMessage(ctx) {
43
+ const { task, workspaceRoot } = ctx.inputs;
44
+ return `**Analysis Task**: ${task.title}
45
+
46
+ **Module**: ${task.module}
47
+
48
+ **Description**: ${task.description}
49
+
50
+ **Project Path**: ${workspaceRoot}
51
+
52
+ **Required Memory Keys** (suggestions - create these or similar):
53
+ ${(task.memory_keys_to_generate || []).map((k) => `- ${k}`).join('\n')}
54
+
55
+ **Required Outputs**:
56
+ - Minimum word count: ${task.required_outputs?.min_word_count || 600}
57
+ - Code examples: ${task.required_outputs?.code_examples || 2}
58
+ - Diagrams: ${task.required_outputs?.diagrams || 0}
59
+
60
+ **Instructions**:
61
+ 1. Use file_list to discover relevant files in the project
62
+ 2. Use file_read to examine key files (pom.xml, source code, config files)
63
+ 3. Extract and analyze: architecture patterns, tech stack, code quality, dependencies
64
+ 4. Store ALL findings using memory_store with appropriate importance levels (7-10 for key discoveries)
65
+ 5. Create ${(task.memory_keys_to_generate || []).length} or more detailed memory entries
66
+
67
+ Focus on discovering actual project specifics - file names, class names, versions, patterns from THIS project.
68
+
69
+ **Task Completion**: Your analysis is complete when you have stored ${(task.memory_keys_to_generate || []).length} or more memory entries with detailed findings.`;
70
+ }
71
+ /**
72
+ * Extract analyst output from LLM result
73
+ */
74
+ function extractAnalystOutput(ctx, llmResult) {
75
+ // Count successful memory_store tool calls using utility
76
+ const memoriesCreated = countToolCalls(llmResult, 'memory_store', (result) => {
77
+ return result?.success === true;
78
+ });
79
+ const taskId = ctx.inputs.task.task_id;
80
+ if (memoriesCreated === 0) {
81
+ return {
82
+ taskId,
83
+ success: false,
84
+ memoriesCreated: 0,
85
+ error: 'Analyst did not store any memories - no analysis was performed'
86
+ };
87
+ }
88
+ return {
89
+ taskId,
90
+ success: true,
91
+ memoriesCreated
92
+ };
93
+ }
94
+ /**
95
+ * Create Analyst Agent using declarative TSX syntax
96
+ */
97
+ export function createAnalystAgent(promptsDir) {
98
+ return (_jsxs(Agent, { id: "analyst", input: AnalystInputSchema, output: AnalystOutputSchema, children: [_jsxs(Prompt, { children: [_jsx(System, { children: async () => buildSystemPrompt(promptsDir) }), _jsx(User, { children: (ctx) => buildUserMessage(ctx) })] }), _jsx(Result, { children: (ctx, llmResult) => extractAnalystOutput(ctx, llmResult) }), _jsx(Validate, { children: (output, ctx) => {
99
+ const { task } = ctx.inputs;
100
+ const typedOutput = output;
101
+ const rules = [];
102
+ if (!typedOutput.success) {
103
+ if (!typedOutput.error) {
104
+ rules.push({
105
+ check: false,
106
+ error: 'Failed analysis must include error message'
107
+ });
108
+ }
109
+ return { rules };
110
+ }
111
+ // Check if memories were created
112
+ if (typedOutput.memoriesCreated === 0) {
113
+ rules.push({
114
+ check: false,
115
+ error: 'Analyst must store findings in memory'
116
+ });
117
+ }
118
+ // Check if required memory keys were generated
119
+ const requiredKeys = task.memory_keys_to_generate || [];
120
+ if (requiredKeys.length > 0 && typedOutput.memoriesCreated < requiredKeys.length) {
121
+ rules.push({
122
+ check: false,
123
+ error: `Expected at least ${requiredKeys.length} memory entries for keys: ${requiredKeys.join(', ')}`
124
+ });
125
+ }
126
+ return { rules };
127
+ } }), _jsx(Retry, { maxAttempts: 2, feedbackOnError: true })] }));
128
+ }
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Editor Agent - Generates executive summary and finalizes report
3
+ * Using declarative TSX syntax
4
+ */
5
+ import { z } from 'zod';
6
+ import { type AgentNode } from '@limo-labs/deity';
7
+ declare const EditorInputSchema: z.ZodObject<{
8
+ projectName: z.ZodString;
9
+ taskCount: z.ZodNumber;
10
+ sectionCount: z.ZodNumber;
11
+ diagramCount: z.ZodNumber;
12
+ promptsDir: z.ZodString;
13
+ reportLanguage: z.ZodOptional<z.ZodString>;
14
+ }, z.core.$strip>;
15
+ type EditorInput = z.infer<typeof EditorInputSchema>;
16
+ declare const EditorOutputSchema: z.ZodObject<{
17
+ success: z.ZodBoolean;
18
+ summaryGenerated: z.ZodBoolean;
19
+ error: z.ZodOptional<z.ZodString>;
20
+ }, z.core.$strip>;
21
+ type EditorOutput = z.infer<typeof EditorOutputSchema>;
22
+ /**
23
+ * Create Editor Agent using declarative TSX syntax
24
+ */
25
+ export declare function createEditorAgent(promptsDir: string): AgentNode<EditorInput, EditorOutput>;
26
+ export {};
@@ -0,0 +1,157 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "@limo-labs/deity/jsx-runtime";
2
+ /**
3
+ * Editor Agent - Generates executive summary and finalizes report
4
+ * Using declarative TSX syntax
5
+ */
6
+ import { z } from 'zod';
7
+ import { Agent, Prompt, System, User, Result, Validate, Retry } from '@limo-labs/deity';
8
+ import { extractAllToolResults } from '@limo-labs/deity';
9
+ import * as fs from 'fs/promises';
10
+ import * as path from 'path';
11
+ // Input schema
12
+ const EditorInputSchema = z.object({
13
+ projectName: z.string(),
14
+ taskCount: z.number(),
15
+ sectionCount: z.number(),
16
+ diagramCount: z.number(),
17
+ promptsDir: z.string(),
18
+ reportLanguage: z.string().optional()
19
+ });
20
+ // Output schema
21
+ const EditorOutputSchema = z.object({
22
+ success: z.boolean(),
23
+ summaryGenerated: z.boolean(),
24
+ error: z.string().optional()
25
+ });
26
+ /**
27
+ * Build system prompt by loading from prompts directory
28
+ */
29
+ async function buildSystemPrompt(promptsDir, reportLanguage) {
30
+ const promptPath = path.join(promptsDir, 'editor.md');
31
+ // Verify prompt file exists before reading
32
+ try {
33
+ await fs.access(promptPath);
34
+ }
35
+ catch (error) {
36
+ throw new Error(`Critical: Editor prompt file not found at ${promptPath}\n` +
37
+ `Please ensure prompts are copied from VSCode extension or run 'npm run sync-prompts'`);
38
+ }
39
+ let systemPrompt = await fs.readFile(promptPath, 'utf-8');
40
+ // Inject language instruction if reportLanguage is provided
41
+ if (reportLanguage && reportLanguage !== 'English') {
42
+ const languageInstruction = `
43
+
44
+ ## CRITICAL: Output Language Requirement
45
+
46
+ **YOU MUST write ALL content in ${reportLanguage}.**
47
+
48
+ This applies to:
49
+ - Executive summary
50
+ - Section titles and headings
51
+ - All descriptions and findings
52
+ - Recommendations
53
+
54
+ IMPORTANT Guidelines:
55
+ 1. Write naturally in ${reportLanguage}, not as a direct translation
56
+ 2. Use appropriate technical terminology for ${reportLanguage}
57
+ 3. Preserve code snippets and technical identifiers in their original language
58
+ 4. Memory keys must remain in English (system requirement)
59
+
60
+ `;
61
+ systemPrompt = systemPrompt + languageInstruction;
62
+ }
63
+ return systemPrompt;
64
+ }
65
+ /**
66
+ * Build user message with editing task details
67
+ */
68
+ function buildUserMessage(ctx) {
69
+ const { projectName, taskCount, sectionCount, diagramCount } = ctx.inputs;
70
+ return `**Report Finalization Task**: Generate Executive Summary
71
+
72
+ **Project**: ${projectName}
73
+ **Analysis Scope**:
74
+ - ${taskCount} analysis tasks completed
75
+ - ${sectionCount} report sections generated
76
+ - ${diagramCount} diagrams created
77
+
78
+ **Your Responsibilities**:
79
+
80
+ 1. **Generate Executive Summary** (MANDATORY)
81
+ - Recall all key memories to understand the full analysis
82
+ - Create a comprehensive overview (200-400 words) covering:
83
+ * What the project is (brief description)
84
+ * Key findings from the analysis
85
+ * Architecture highlights and patterns
86
+ * Main recommendations for improvement
87
+ - Use section_id "executive_summary" when calling report_write
88
+
89
+ 2. **Review Report Quality**
90
+ - Ensure all sections are cohesive
91
+ - Check that findings are actionable
92
+ - Verify diagrams support the narrative
93
+
94
+ **Instructions**:
95
+ 1. Use memory_list or memory_search to discover all analysis findings
96
+ 2. Recall key memories across different areas (architecture, code quality, testing, etc.)
97
+ 3. Synthesize findings into a coherent executive summary
98
+ 4. MUST call report_write with section_id "executive_summary" (THIS IS MANDATORY!)
99
+
100
+ The executive summary should give readers a clear understanding of:
101
+ - What was analyzed
102
+ - What was discovered
103
+ - What should be done next
104
+
105
+ Write based on ACTUAL analysis findings - be specific and actionable.`;
106
+ }
107
+ /**
108
+ * Extract editor output from LLM result
109
+ */
110
+ function extractEditorOutput(_ctx, llmResult) {
111
+ // Extract all report_write results using utility
112
+ const allReports = extractAllToolResults(llmResult, 'report_write', {
113
+ unwrap: true,
114
+ required: false
115
+ });
116
+ if (allReports.length === 0) {
117
+ return {
118
+ success: false,
119
+ summaryGenerated: false,
120
+ error: 'Editor did not call report_write - no executive summary was generated'
121
+ };
122
+ }
123
+ // Check if executive_summary section was created
124
+ const execSummaryCreated = allReports.some((report) => report?.section_id === 'executive_summary');
125
+ return {
126
+ success: true,
127
+ summaryGenerated: execSummaryCreated
128
+ };
129
+ }
130
+ /**
131
+ * Create Editor Agent using declarative TSX syntax
132
+ */
133
+ export function createEditorAgent(promptsDir) {
134
+ return (_jsxs(Agent, { id: "editor", input: EditorInputSchema, output: EditorOutputSchema, children: [_jsxs(Prompt, { children: [_jsx(System, { children: async (ctx) => {
135
+ const reportLanguage = ctx.inputs.reportLanguage;
136
+ return buildSystemPrompt(promptsDir, reportLanguage);
137
+ } }), _jsx(User, { children: (ctx) => buildUserMessage(ctx) })] }), _jsx(Result, { children: (ctx, llmResult) => extractEditorOutput(ctx, llmResult) }), _jsx(Validate, { children: (output) => {
138
+ const typedOutput = output;
139
+ const rules = [];
140
+ if (!typedOutput.success) {
141
+ if (!typedOutput.error) {
142
+ rules.push({
143
+ check: false,
144
+ error: 'Failed task must include error message'
145
+ });
146
+ }
147
+ return { rules };
148
+ }
149
+ if (!typedOutput.summaryGenerated) {
150
+ rules.push({
151
+ check: false,
152
+ error: 'Editor must generate executive summary (section_id: "executive_summary")'
153
+ });
154
+ }
155
+ return { rules };
156
+ } }), _jsx(Retry, { maxAttempts: 2, feedbackOnError: true })] }));
157
+ }
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Planner Validator - Validates that planner created a comprehensive analysis plan
3
+ */
4
+ import type { Validator, ValidationResult, LLMLoopState, ExecutionContext } from '@limo-labs/deity';
5
+ export declare class PlannerValidator implements Validator {
6
+ validate(ctx: ExecutionContext, loopState: LLMLoopState): Promise<ValidationResult>;
7
+ }