neuro-cli 4.1.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 (175) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +510 -0
  3. package/dist/advisor/advisor.d.ts +50 -0
  4. package/dist/advisor/advisor.js +178 -0
  5. package/dist/agents/base.d.ts +62 -0
  6. package/dist/agents/base.js +215 -0
  7. package/dist/agents/orchestrator.d.ts +46 -0
  8. package/dist/agents/orchestrator.js +192 -0
  9. package/dist/agents/team.d.ts +51 -0
  10. package/dist/agents/team.js +210 -0
  11. package/dist/api/models.d.ts +23 -0
  12. package/dist/api/models.js +514 -0
  13. package/dist/api/ollama.d.ts +153 -0
  14. package/dist/api/ollama.js +751 -0
  15. package/dist/api/openrouter.d.ts +55 -0
  16. package/dist/api/openrouter.js +223 -0
  17. package/dist/commands/commands.d.ts +43 -0
  18. package/dist/commands/commands.js +308 -0
  19. package/dist/config/config.d.ts +8 -0
  20. package/dist/config/config.js +311 -0
  21. package/dist/context/compaction.d.ts +54 -0
  22. package/dist/context/compaction.js +251 -0
  23. package/dist/context/custom-agents.d.ts +107 -0
  24. package/dist/context/custom-agents.js +397 -0
  25. package/dist/context/custom-tools.d.ts +120 -0
  26. package/dist/context/custom-tools.js +564 -0
  27. package/dist/context/git-checkpoint.d.ts +52 -0
  28. package/dist/context/git-checkpoint.js +240 -0
  29. package/dist/context/neuro-md.d.ts +48 -0
  30. package/dist/context/neuro-md.js +202 -0
  31. package/dist/context/neuroignore.d.ts +102 -0
  32. package/dist/context/neuroignore.js +441 -0
  33. package/dist/context/repo-map.d.ts +38 -0
  34. package/dist/context/repo-map.js +220 -0
  35. package/dist/context/skill-standard.d.ts +262 -0
  36. package/dist/context/skill-standard.js +1156 -0
  37. package/dist/context/skill-system.d.ts +75 -0
  38. package/dist/context/skill-system.js +578 -0
  39. package/dist/context/tree-sitter.d.ts +99 -0
  40. package/dist/context/tree-sitter.js +1956 -0
  41. package/dist/core/acp.d.ts +325 -0
  42. package/dist/core/acp.js +1498 -0
  43. package/dist/core/api-server.d.ts +143 -0
  44. package/dist/core/api-server.js +550 -0
  45. package/dist/core/approval.d.ts +81 -0
  46. package/dist/core/approval.js +432 -0
  47. package/dist/core/auto-compact.d.ts +127 -0
  48. package/dist/core/auto-compact.js +436 -0
  49. package/dist/core/auto-mode.d.ts +232 -0
  50. package/dist/core/auto-mode.js +831 -0
  51. package/dist/core/background-session.d.ts +166 -0
  52. package/dist/core/background-session.js +696 -0
  53. package/dist/core/cicd.d.ts +257 -0
  54. package/dist/core/cicd.js +1443 -0
  55. package/dist/core/cloud-sync.d.ts +156 -0
  56. package/dist/core/cloud-sync.js +582 -0
  57. package/dist/core/code-review.d.ts +132 -0
  58. package/dist/core/code-review.js +1191 -0
  59. package/dist/core/completion.d.ts +49 -0
  60. package/dist/core/completion.js +384 -0
  61. package/dist/core/context.d.ts +38 -0
  62. package/dist/core/context.js +144 -0
  63. package/dist/core/diff-preview.d.ts +35 -0
  64. package/dist/core/diff-preview.js +173 -0
  65. package/dist/core/doom-loop.d.ts +51 -0
  66. package/dist/core/doom-loop.js +179 -0
  67. package/dist/core/engine.d.ts +183 -0
  68. package/dist/core/engine.js +942 -0
  69. package/dist/core/extended-thinking.d.ts +103 -0
  70. package/dist/core/extended-thinking.js +269 -0
  71. package/dist/core/fallback.d.ts +54 -0
  72. package/dist/core/fallback.js +104 -0
  73. package/dist/core/git-worktree.d.ts +139 -0
  74. package/dist/core/git-worktree.js +614 -0
  75. package/dist/core/headless.d.ts +30 -0
  76. package/dist/core/headless.js +101 -0
  77. package/dist/core/i18n.d.ts +83 -0
  78. package/dist/core/i18n.js +739 -0
  79. package/dist/core/linting.d.ts +129 -0
  80. package/dist/core/linting.js +699 -0
  81. package/dist/core/model-router.d.ts +109 -0
  82. package/dist/core/model-router.js +581 -0
  83. package/dist/core/multi-model.d.ts +243 -0
  84. package/dist/core/multi-model.js +1099 -0
  85. package/dist/core/multi-session.d.ts +144 -0
  86. package/dist/core/multi-session.js +442 -0
  87. package/dist/core/multimodal.d.ts +125 -0
  88. package/dist/core/multimodal.js +286 -0
  89. package/dist/core/observability.d.ts +93 -0
  90. package/dist/core/observability.js +737 -0
  91. package/dist/core/os-sandbox.d.ts +122 -0
  92. package/dist/core/os-sandbox.js +1193 -0
  93. package/dist/core/outcome-grading.d.ts +228 -0
  94. package/dist/core/outcome-grading.js +1123 -0
  95. package/dist/core/output-styles.d.ts +57 -0
  96. package/dist/core/output-styles.js +382 -0
  97. package/dist/core/parallel-agents.d.ts +183 -0
  98. package/dist/core/parallel-agents.js +563 -0
  99. package/dist/core/plugin-bundle.d.ts +236 -0
  100. package/dist/core/plugin-bundle.js +887 -0
  101. package/dist/core/plugin-sdk.d.ts +139 -0
  102. package/dist/core/plugin-sdk.js +273 -0
  103. package/dist/core/prompt-cache.d.ts +163 -0
  104. package/dist/core/prompt-cache.js +599 -0
  105. package/dist/core/sandbox.d.ts +127 -0
  106. package/dist/core/sandbox.js +369 -0
  107. package/dist/core/scheduled-tasks.d.ts +151 -0
  108. package/dist/core/scheduled-tasks.js +502 -0
  109. package/dist/core/security-scanner.d.ts +160 -0
  110. package/dist/core/security-scanner.js +1494 -0
  111. package/dist/core/session.d.ts +83 -0
  112. package/dist/core/session.js +269 -0
  113. package/dist/core/shell-completion.d.ts +51 -0
  114. package/dist/core/shell-completion.js +674 -0
  115. package/dist/core/smart-monitor.d.ts +146 -0
  116. package/dist/core/smart-monitor.js +1199 -0
  117. package/dist/core/spec-driven.d.ts +233 -0
  118. package/dist/core/spec-driven.js +1485 -0
  119. package/dist/core/spending-warnings.d.ts +123 -0
  120. package/dist/core/spending-warnings.js +456 -0
  121. package/dist/core/sub-agent.d.ts +298 -0
  122. package/dist/core/sub-agent.js +1023 -0
  123. package/dist/core/telemetry.d.ts +157 -0
  124. package/dist/core/telemetry.js +412 -0
  125. package/dist/core/terminal-ux.d.ts +134 -0
  126. package/dist/core/terminal-ux.js +649 -0
  127. package/dist/core/testing.d.ts +146 -0
  128. package/dist/core/testing.js +1200 -0
  129. package/dist/core/types.d.ts +439 -0
  130. package/dist/core/types.js +6 -0
  131. package/dist/core/undo-redo.d.ts +112 -0
  132. package/dist/core/undo-redo.js +290 -0
  133. package/dist/core/updater.d.ts +159 -0
  134. package/dist/core/updater.js +608 -0
  135. package/dist/core/vim-mode.d.ts +151 -0
  136. package/dist/core/vim-mode.js +771 -0
  137. package/dist/core/voice.d.ts +137 -0
  138. package/dist/core/voice.js +538 -0
  139. package/dist/core/web-dashboard.d.ts +109 -0
  140. package/dist/core/web-dashboard.js +484 -0
  141. package/dist/hooks/hooks.d.ts +74 -0
  142. package/dist/hooks/hooks.js +160 -0
  143. package/dist/hooks/llm-evaluator.d.ts +165 -0
  144. package/dist/hooks/llm-evaluator.js +560 -0
  145. package/dist/index.d.ts +3 -0
  146. package/dist/index.js +1186 -0
  147. package/dist/lsp/lsp-manager.d.ts +63 -0
  148. package/dist/lsp/lsp-manager.js +351 -0
  149. package/dist/mcp/client.d.ts +133 -0
  150. package/dist/mcp/client.js +684 -0
  151. package/dist/mcp/mcp-apps.d.ts +70 -0
  152. package/dist/mcp/mcp-apps.js +1007 -0
  153. package/dist/tools/bash.d.ts +5 -0
  154. package/dist/tools/bash.js +195 -0
  155. package/dist/tools/browser.d.ts +92 -0
  156. package/dist/tools/browser.js +1570 -0
  157. package/dist/tools/extended.d.ts +6 -0
  158. package/dist/tools/extended.js +191 -0
  159. package/dist/tools/file.d.ts +10 -0
  160. package/dist/tools/file.js +382 -0
  161. package/dist/tools/github.d.ts +389 -0
  162. package/dist/tools/github.js +759 -0
  163. package/dist/tools/index.d.ts +9 -0
  164. package/dist/tools/index.js +40 -0
  165. package/dist/tools/memory.d.ts +6 -0
  166. package/dist/tools/memory.js +197 -0
  167. package/dist/tools/registry.d.ts +29 -0
  168. package/dist/tools/registry.js +64 -0
  169. package/dist/tools/web.d.ts +6 -0
  170. package/dist/tools/web.js +150 -0
  171. package/dist/ui/renderer.d.ts +97 -0
  172. package/dist/ui/renderer.js +279 -0
  173. package/dist/ui/theme.d.ts +27 -0
  174. package/dist/ui/theme.js +106 -0
  175. package/package.json +83 -0
@@ -0,0 +1,57 @@
1
+ export interface OutputStyle {
2
+ name: string;
3
+ description: string;
4
+ systemPromptAddition: string;
5
+ formatRules: {
6
+ codeBlocks: 'minimal' | 'detailed' | 'annotated';
7
+ explanations: 'brief' | 'moderate' | 'thorough';
8
+ examples: boolean;
9
+ stepByStep: boolean;
10
+ includeReasoning: boolean;
11
+ language: 'technical' | 'simple' | 'academic' | 'casual';
12
+ };
13
+ }
14
+ export declare class StyleManager {
15
+ private currentStyle;
16
+ private styles;
17
+ private stylesDir;
18
+ private projectStylesDir;
19
+ constructor(workingDirectory: string);
20
+ /** Return the currently active style. */
21
+ getStyle(): OutputStyle;
22
+ /** Switch to a named style. Returns true on success. */
23
+ setStyle(name: string): boolean;
24
+ /** Return all available styles (built-in + custom). */
25
+ listStyles(): OutputStyle[];
26
+ /** Return the system-prompt addition string for the active style. */
27
+ getSystemPromptAddition(): string;
28
+ /** Scan both global and project style directories for custom styles. */
29
+ discoverCustomStyles(): void;
30
+ /** Load a single style from a markdown file path. */
31
+ loadStyleFromFile(filePath: string): OutputStyle | null;
32
+ /** Pretty-print all styles to stdout (used by /style command). */
33
+ printStyles(): void;
34
+ private loadBuiltinStyles;
35
+ /**
36
+ * Parse a markdown file with YAML frontmatter into an OutputStyle.
37
+ *
38
+ * Expected format:
39
+ * ---
40
+ * description: Short description of the style
41
+ * codeBlocks: minimal | detailed | annotated
42
+ * explanations: brief | moderate | thorough
43
+ * examples: true | false
44
+ * stepByStep: true | false
45
+ * includeReasoning: true | false
46
+ * language: technical | simple | academic | casual
47
+ * ---
48
+ *
49
+ * The body of the markdown becomes the systemPromptAddition.
50
+ */
51
+ private parseStyleMarkdown;
52
+ private loadStylesFromDirectory;
53
+ private getPersistencePath;
54
+ private persistStylePreference;
55
+ private readPersistedStyle;
56
+ }
57
+ //# sourceMappingURL=output-styles.d.ts.map
@@ -0,0 +1,382 @@
1
+ // ============================================================
2
+ // NeuroCLI - Output Styles System
3
+ // Controls how the AI formats its responses
4
+ // ============================================================
5
+ import { readFileSync, writeFileSync, existsSync, readdirSync, mkdirSync } from 'fs';
6
+ import { join, basename } from 'path';
7
+ import { homedir } from 'os';
8
+ // -----------------------------------------------------------
9
+ // StyleManager
10
+ // -----------------------------------------------------------
11
+ const GLOBAL_STYLES_DIR = join(homedir(), '.neuro', 'styles');
12
+ const PROJECT_STYLES_SUBDIR = '.neuro/styles';
13
+ export class StyleManager {
14
+ currentStyle;
15
+ styles;
16
+ stylesDir;
17
+ projectStylesDir;
18
+ constructor(workingDirectory) {
19
+ this.styles = new Map();
20
+ this.stylesDir = GLOBAL_STYLES_DIR;
21
+ this.projectStylesDir = join(workingDirectory, PROJECT_STYLES_SUBDIR);
22
+ // Load built-in styles first
23
+ this.loadBuiltinStyles();
24
+ // Discover custom styles (global + project-level)
25
+ this.discoverCustomStyles();
26
+ // Default to the "default" style
27
+ this.currentStyle = this.styles.get('default');
28
+ }
29
+ // -------------------------------------------------------
30
+ // Public API
31
+ // -------------------------------------------------------
32
+ /** Return the currently active style. */
33
+ getStyle() {
34
+ return this.currentStyle;
35
+ }
36
+ /** Switch to a named style. Returns true on success. */
37
+ setStyle(name) {
38
+ const style = this.styles.get(name);
39
+ if (!style)
40
+ return false;
41
+ this.currentStyle = style;
42
+ this.persistStylePreference(name);
43
+ return true;
44
+ }
45
+ /** Return all available styles (built-in + custom). */
46
+ listStyles() {
47
+ return Array.from(this.styles.values());
48
+ }
49
+ /** Return the system-prompt addition string for the active style. */
50
+ getSystemPromptAddition() {
51
+ return this.currentStyle.systemPromptAddition;
52
+ }
53
+ /** Scan both global and project style directories for custom styles. */
54
+ discoverCustomStyles() {
55
+ // Global styles
56
+ this.loadStylesFromDirectory(this.stylesDir);
57
+ // Project-level styles (take precedence over global with same name)
58
+ this.loadStylesFromDirectory(this.projectStylesDir);
59
+ // Re-apply persisted preference if available
60
+ const persisted = this.readPersistedStyle();
61
+ if (persisted && this.styles.has(persisted)) {
62
+ this.currentStyle = this.styles.get(persisted);
63
+ }
64
+ }
65
+ /** Load a single style from a markdown file path. */
66
+ loadStyleFromFile(filePath) {
67
+ if (!existsSync(filePath))
68
+ return null;
69
+ try {
70
+ const content = readFileSync(filePath, 'utf-8');
71
+ const filename = basename(filePath, '.md');
72
+ return this.parseStyleMarkdown(content, filename);
73
+ }
74
+ catch {
75
+ return null;
76
+ }
77
+ }
78
+ /** Pretty-print all styles to stdout (used by /style command). */
79
+ printStyles() {
80
+ const styles = this.listStyles();
81
+ const currentName = this.currentStyle.name;
82
+ console.log('\n Output Styles\n -------------');
83
+ for (const style of styles) {
84
+ const marker = style.name === currentName ? ' *' : ' ';
85
+ const tag = style.name === currentName ? ' (active)' : '';
86
+ console.log(` ${marker} ${style.name}${tag}`);
87
+ console.log(` ${style.description}`);
88
+ }
89
+ console.log('\n Usage: /style <name> Switch active style');
90
+ console.log(' Custom styles: ~/.neuro/styles/*.md or .neuro/styles/*.md\n');
91
+ }
92
+ // -------------------------------------------------------
93
+ // Built-in styles
94
+ // -------------------------------------------------------
95
+ loadBuiltinStyles() {
96
+ const builtins = [
97
+ // 1. default ------------------------------------------------
98
+ {
99
+ name: 'default',
100
+ description: 'Balanced approach with moderate detail and clear formatting',
101
+ systemPromptAddition: [
102
+ 'Respond in a balanced, clear manner.',
103
+ 'Provide enough detail to be helpful without being excessive.',
104
+ 'Use code blocks when relevant. Include brief explanations.',
105
+ ].join(' '),
106
+ formatRules: {
107
+ codeBlocks: 'detailed',
108
+ explanations: 'moderate',
109
+ examples: true,
110
+ stepByStep: false,
111
+ includeReasoning: false,
112
+ language: 'simple',
113
+ },
114
+ },
115
+ // 2. concise ------------------------------------------------
116
+ {
117
+ name: 'concise',
118
+ description: 'Brief responses, minimal code, direct answers',
119
+ systemPromptAddition: [
120
+ 'Be extremely concise. Give direct answers with minimal elaboration.',
121
+ 'Prefer code over explanation. Use inline code instead of blocks when possible.',
122
+ 'Skip greetings and filler. Never add commentary unless asked.',
123
+ 'If a question can be answered in one line, do so.',
124
+ ].join(' '),
125
+ formatRules: {
126
+ codeBlocks: 'minimal',
127
+ explanations: 'brief',
128
+ examples: false,
129
+ stepByStep: false,
130
+ includeReasoning: false,
131
+ language: 'simple',
132
+ },
133
+ },
134
+ // 3. explanatory --------------------------------------------
135
+ {
136
+ name: 'explanatory',
137
+ description: 'Detailed explanations with context and examples',
138
+ systemPromptAddition: [
139
+ 'Provide thorough, detailed explanations with full context.',
140
+ 'Include examples for every concept. Explain the "why" behind decisions.',
141
+ 'Use annotated code blocks that explain each significant line.',
142
+ 'When introducing a concept, define it before using it.',
143
+ 'Anticipate follow-up questions and address them proactively.',
144
+ ].join(' '),
145
+ formatRules: {
146
+ codeBlocks: 'annotated',
147
+ explanations: 'thorough',
148
+ examples: true,
149
+ stepByStep: true,
150
+ includeReasoning: true,
151
+ language: 'simple',
152
+ },
153
+ },
154
+ // 4. learning -----------------------------------------------
155
+ {
156
+ name: 'learning',
157
+ description: 'Tutorial style with step-by-step explanations',
158
+ systemPromptAddition: [
159
+ 'Teach concepts step by step, as if the reader is learning for the first time.',
160
+ 'Break every process into numbered steps. Explain each step before moving on.',
161
+ 'Use analogies to relate new concepts to familiar ones.',
162
+ 'Include "Try it yourself" suggestions after key concepts.',
163
+ 'Highlight common mistakes and how to avoid them.',
164
+ 'Summarize key takeaways at the end of each explanation.',
165
+ ].join(' '),
166
+ formatRules: {
167
+ codeBlocks: 'annotated',
168
+ explanations: 'thorough',
169
+ examples: true,
170
+ stepByStep: true,
171
+ includeReasoning: true,
172
+ language: 'simple',
173
+ },
174
+ },
175
+ // 5. narrative ----------------------------------------------
176
+ {
177
+ name: 'narrative',
178
+ description: 'Story-driven explanations that contextualize concepts',
179
+ systemPromptAddition: [
180
+ 'Present information as a narrative or story when possible.',
181
+ 'Use real-world scenarios to frame technical concepts.',
182
+ 'Build explanations from a problem statement through discovery to solution.',
183
+ 'Make connections between ideas feel natural and logical.',
184
+ 'Use descriptive language but stay technically accurate.',
185
+ ].join(' '),
186
+ formatRules: {
187
+ codeBlocks: 'detailed',
188
+ explanations: 'thorough',
189
+ examples: true,
190
+ stepByStep: false,
191
+ includeReasoning: true,
192
+ language: 'casual',
193
+ },
194
+ },
195
+ // 6. technical ----------------------------------------------
196
+ {
197
+ name: 'technical',
198
+ description: 'Precise technical language, API documentation style',
199
+ systemPromptAddition: [
200
+ 'Use precise, formal technical language throughout.',
201
+ 'Reference specifications, RFCs, and official documentation when relevant.',
202
+ 'Format code with type signatures, parameter descriptions, and return types.',
203
+ 'Use correct terminology. Avoid colloquialisms.',
204
+ 'Structure responses like API documentation: signature, description, parameters, returns, examples.',
205
+ ].join(' '),
206
+ formatRules: {
207
+ codeBlocks: 'detailed',
208
+ explanations: 'moderate',
209
+ examples: true,
210
+ stepByStep: false,
211
+ includeReasoning: false,
212
+ language: 'technical',
213
+ },
214
+ },
215
+ // 7. review -------------------------------------------------
216
+ {
217
+ name: 'review',
218
+ description: 'Focused on code review with severity levels',
219
+ systemPromptAddition: [
220
+ 'Review code with a critical eye, identifying issues by severity level.',
221
+ 'Categorize findings as: CRITICAL (must fix), WARNING (should fix), INFO (consider fixing).',
222
+ 'For each finding, explain the issue, its impact, and a suggested fix.',
223
+ 'Check for: correctness, security, performance, readability, maintainability.',
224
+ 'Highlight positive patterns and good practices when found.',
225
+ 'Provide a summary with counts at the end.',
226
+ ].join(' '),
227
+ formatRules: {
228
+ codeBlocks: 'annotated',
229
+ explanations: 'moderate',
230
+ examples: false,
231
+ stepByStep: false,
232
+ includeReasoning: true,
233
+ language: 'technical',
234
+ },
235
+ },
236
+ // 8. debug --------------------------------------------------
237
+ {
238
+ name: 'debug',
239
+ description: 'Systematic investigation style for troubleshooting',
240
+ systemPromptAddition: [
241
+ 'Approach problems systematically using a structured debugging methodology.',
242
+ 'Start by reproducing or confirming the issue. State observations before hypotheses.',
243
+ 'List possible causes ranked by likelihood. Test each hypothesis explicitly.',
244
+ 'Show the reasoning chain: observation -> hypothesis -> test -> conclusion.',
245
+ 'When a fix is found, explain the root cause and how to prevent recurrence.',
246
+ 'Use binary search / elimination approach for complex issues.',
247
+ ].join(' '),
248
+ formatRules: {
249
+ codeBlocks: 'detailed',
250
+ explanations: 'thorough',
251
+ examples: false,
252
+ stepByStep: true,
253
+ includeReasoning: true,
254
+ language: 'technical',
255
+ },
256
+ },
257
+ ];
258
+ for (const style of builtins) {
259
+ this.styles.set(style.name, style);
260
+ }
261
+ }
262
+ // -------------------------------------------------------
263
+ // Custom style parsing
264
+ // -------------------------------------------------------
265
+ /**
266
+ * Parse a markdown file with YAML frontmatter into an OutputStyle.
267
+ *
268
+ * Expected format:
269
+ * ---
270
+ * description: Short description of the style
271
+ * codeBlocks: minimal | detailed | annotated
272
+ * explanations: brief | moderate | thorough
273
+ * examples: true | false
274
+ * stepByStep: true | false
275
+ * includeReasoning: true | false
276
+ * language: technical | simple | academic | casual
277
+ * ---
278
+ *
279
+ * The body of the markdown becomes the systemPromptAddition.
280
+ */
281
+ parseStyleMarkdown(content, filename) {
282
+ const frontmatterRegex = /^---\s*\n([\s\S]*?)\n---\s*\n([\s\S]*)$/;
283
+ const match = content.match(frontmatterRegex);
284
+ if (!match)
285
+ return null;
286
+ const frontmatter = match[1];
287
+ const body = match[2].trim();
288
+ if (!body)
289
+ return null;
290
+ // Parse simple YAML key-value pairs
291
+ const values = {};
292
+ for (const line of frontmatter.split('\n')) {
293
+ const kvMatch = line.match(/^\s*(\w+)\s*:\s*(.+)\s*$/);
294
+ if (kvMatch) {
295
+ values[kvMatch[1]] = kvMatch[2].trim();
296
+ }
297
+ }
298
+ // Validate formatRules enums
299
+ const validCodeBlocks = ['minimal', 'detailed', 'annotated'];
300
+ const validExplanations = ['brief', 'moderate', 'thorough'];
301
+ const validLanguage = ['technical', 'simple', 'academic', 'casual'];
302
+ const codeBlocks = validCodeBlocks.includes(values.codeBlocks)
303
+ ? values.codeBlocks
304
+ : 'detailed';
305
+ const explanations = validExplanations.includes(values.explanations)
306
+ ? values.explanations
307
+ : 'moderate';
308
+ const language = validLanguage.includes(values.language)
309
+ ? values.language
310
+ : 'simple';
311
+ const parseBool = (raw, fallback) => {
312
+ if (raw === undefined)
313
+ return fallback;
314
+ return raw.toLowerCase() === 'true';
315
+ };
316
+ return {
317
+ name: filename.toLowerCase().replace(/\s+/g, '-'),
318
+ description: values.description || `Custom style: ${filename}`,
319
+ systemPromptAddition: body,
320
+ formatRules: {
321
+ codeBlocks,
322
+ explanations,
323
+ examples: parseBool(values.examples, true),
324
+ stepByStep: parseBool(values.stepByStep, false),
325
+ includeReasoning: parseBool(values.includeReasoning, false),
326
+ language,
327
+ },
328
+ };
329
+ }
330
+ // -------------------------------------------------------
331
+ // Directory scanning helpers
332
+ // -------------------------------------------------------
333
+ loadStylesFromDirectory(dir) {
334
+ if (!existsSync(dir))
335
+ return;
336
+ try {
337
+ const entries = readdirSync(dir, { withFileTypes: true });
338
+ for (const entry of entries) {
339
+ if (!entry.isFile() || !entry.name.endsWith('.md'))
340
+ continue;
341
+ const filePath = join(dir, entry.name);
342
+ const style = this.loadStyleFromFile(filePath);
343
+ if (style) {
344
+ this.styles.set(style.name, style);
345
+ }
346
+ }
347
+ }
348
+ catch {
349
+ // Silently ignore unreadable directories
350
+ }
351
+ }
352
+ // -------------------------------------------------------
353
+ // Persistence helpers
354
+ // -------------------------------------------------------
355
+ getPersistencePath() {
356
+ return join(this.stylesDir, '.active-style');
357
+ }
358
+ persistStylePreference(name) {
359
+ try {
360
+ if (!existsSync(this.stylesDir)) {
361
+ mkdirSync(this.stylesDir, { recursive: true });
362
+ }
363
+ writeFileSync(this.getPersistencePath(), name, 'utf-8');
364
+ }
365
+ catch {
366
+ // Persistence is best-effort; do not crash
367
+ }
368
+ }
369
+ readPersistedStyle() {
370
+ const filePath = this.getPersistencePath();
371
+ if (!existsSync(filePath))
372
+ return null;
373
+ try {
374
+ const content = readFileSync(filePath, 'utf-8').trim();
375
+ return content || null;
376
+ }
377
+ catch {
378
+ return null;
379
+ }
380
+ }
381
+ }
382
+ //# sourceMappingURL=output-styles.js.map
@@ -0,0 +1,183 @@
1
+ import { EventEmitter } from 'events';
2
+ export interface ParallelAgentConfig {
3
+ id: string;
4
+ name: string;
5
+ prompt: string;
6
+ model?: string;
7
+ workingDirectory?: string;
8
+ maxIterations?: number;
9
+ maxTokens?: number;
10
+ tools?: string[];
11
+ sharedState?: Record<string, unknown>;
12
+ priority: 'low' | 'normal' | 'high';
13
+ autoStart: boolean;
14
+ }
15
+ export interface ParallelAgentState {
16
+ id: string;
17
+ name: string;
18
+ status: 'spawning' | 'running' | 'completed' | 'failed' | 'cancelled';
19
+ startedAt: number;
20
+ completedAt?: number;
21
+ iterations: number;
22
+ tokensUsed: number;
23
+ result?: string;
24
+ error?: string;
25
+ progress: number;
26
+ }
27
+ export interface ParallelAgentMetrics {
28
+ totalAgents: number;
29
+ activeAgents: number;
30
+ completedAgents: number;
31
+ failedAgents: number;
32
+ cancelledAgents: number;
33
+ averageDurationMs: number;
34
+ totalTokensUsed: number;
35
+ }
36
+ type AgentCompleteCallback = (agentId: string, state: ParallelAgentState) => void;
37
+ type AgentErrorCallback = (agentId: string, error: string, state: ParallelAgentState) => void;
38
+ export declare class ParallelAgentManager extends EventEmitter {
39
+ private agents;
40
+ private maxConcurrent;
41
+ private globalSharedState;
42
+ private onAgentCompleteCallbacks;
43
+ private onAgentErrorCallbacks;
44
+ /** Queue of agent IDs waiting to run when a slot opens. */
45
+ private pendingQueue;
46
+ constructor(options?: {
47
+ maxConcurrent?: number;
48
+ sharedState?: Record<string, unknown>;
49
+ });
50
+ /**
51
+ * Spawn a new parallel agent. If `config.autoStart` is true the agent
52
+ * begins running immediately (subject to the concurrency limit).
53
+ * Returns the agent ID.
54
+ */
55
+ spawn(config: ParallelAgentConfig): string;
56
+ /**
57
+ * Cancel a running (or pending) agent.
58
+ */
59
+ cancel(agentId: string): boolean;
60
+ /**
61
+ * Cancel all running and pending agents.
62
+ */
63
+ cancelAll(): number;
64
+ /**
65
+ * Get the state of a specific agent.
66
+ */
67
+ getStatus(agentId: string): ParallelAgentState | null;
68
+ /**
69
+ * List all currently running agents (status === 'running' | 'spawning').
70
+ */
71
+ listActive(): ParallelAgentState[];
72
+ /**
73
+ * List all agents including completed ones.
74
+ */
75
+ listAll(): ParallelAgentState[];
76
+ /**
77
+ * Wait for a specific agent to complete and return its result.
78
+ * Rejects if the agent was cancelled or failed.
79
+ */
80
+ waitFor(agentId: string): Promise<string>;
81
+ /**
82
+ * Wait for all currently running agents to finish.
83
+ * Returns a map of agentId → result (or error message on failure).
84
+ */
85
+ waitForAll(): Promise<Map<string, {
86
+ result?: string;
87
+ error?: string;
88
+ }>>;
89
+ /**
90
+ * Get the result of a completed agent.
91
+ */
92
+ getResult(agentId: string): string | null;
93
+ /**
94
+ * Broadcast a message to all running agents' shared state.
95
+ * The message is stored under `sharedState.__broadcasts`.
96
+ */
97
+ broadcastMessage(message: string): number;
98
+ /**
99
+ * Register a callback for when any agent completes successfully.
100
+ */
101
+ onAgentComplete(callback: AgentCompleteCallback): void;
102
+ /**
103
+ * Register a callback for when any agent encounters an error.
104
+ */
105
+ onAgentError(callback: AgentErrorCallback): void;
106
+ /**
107
+ * Get aggregate metrics across all agents.
108
+ */
109
+ getMetrics(): ParallelAgentMetrics;
110
+ /**
111
+ * Read a value from the shared state of a specific agent.
112
+ */
113
+ getSharedValue(agentId: string, key: string): unknown;
114
+ /**
115
+ * Write a value to the shared state of a specific agent.
116
+ * Also writes to the global shared state so future agents inherit it.
117
+ */
118
+ setSharedValue(agentId: string, key: string, value: unknown): boolean;
119
+ /**
120
+ * Update the progress of a running agent (0-100).
121
+ */
122
+ updateProgress(agentId: string, progress: number): boolean;
123
+ /**
124
+ * Clean up sandbox directories for completed/failed/cancelled agents.
125
+ */
126
+ cleanup(): number;
127
+ /**
128
+ * Schedule an agent to start. If we're at the concurrency limit,
129
+ * the agent is placed in the pending queue.
130
+ */
131
+ private scheduleStart;
132
+ /**
133
+ * Actually start running an agent.
134
+ */
135
+ private runAgent;
136
+ /**
137
+ * The core agent execution loop.
138
+ *
139
+ * In a real implementation this would call an LLM, execute tools, etc.
140
+ * Here we simulate the loop with AbortController support, token tracking,
141
+ * iteration limits, and sandboxed file I/O — all using only Node built-ins.
142
+ */
143
+ private executeAgentLoop;
144
+ /**
145
+ * Yield control to the event loop so other agents can progress.
146
+ * Uses setImmediate for true interleaving.
147
+ */
148
+ private yieldControl;
149
+ /**
150
+ * Rough token estimation (heuristic: ~4 chars per token).
151
+ */
152
+ private estimateTokens;
153
+ /**
154
+ * Persist the agent's context to its sandbox directory.
155
+ */
156
+ private persistContext;
157
+ /**
158
+ * Write an iteration log to the sandbox directory.
159
+ */
160
+ private writeIterationLog;
161
+ /**
162
+ * When a slot opens, try to start the highest-priority pending agent.
163
+ */
164
+ private tryStartPending;
165
+ /**
166
+ * Count currently active (spawning + running) agents.
167
+ */
168
+ private activeCount;
169
+ /**
170
+ * Fire all registered onAgentComplete callbacks.
171
+ */
172
+ private fireCompleteCallbacks;
173
+ /**
174
+ * Fire all registered onAgentError callbacks.
175
+ */
176
+ private fireErrorCallbacks;
177
+ /**
178
+ * Ensure a directory exists.
179
+ */
180
+ private ensureDir;
181
+ }
182
+ export {};
183
+ //# sourceMappingURL=parallel-agents.d.ts.map