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,9 @@
1
+ import { ToolRegistry } from './registry.js';
2
+ export declare function registerAllTools(registry?: ToolRegistry): ToolRegistry;
3
+ export { globalRegistry } from './registry.js';
4
+ export { fileTools } from './file.js';
5
+ export { shellTools } from './bash.js';
6
+ export { webTools } from './web.js';
7
+ export { memoryTools } from './memory.js';
8
+ export { extendedTools } from './extended.js';
9
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,40 @@
1
+ // ============================================================
2
+ // NeuroCLI - Tool Registration
3
+ // Registers all built-in tools (15+ tools)
4
+ // ============================================================
5
+ import { globalRegistry } from './registry.js';
6
+ import { fileTools } from './file.js';
7
+ import { shellTools } from './bash.js';
8
+ import { webTools } from './web.js';
9
+ import { memoryTools } from './memory.js';
10
+ import { extendedTools } from './extended.js';
11
+ export function registerAllTools(registry = globalRegistry) {
12
+ // Register file tools (7)
13
+ for (const tool of fileTools) {
14
+ registry.register(tool);
15
+ }
16
+ // Register shell/bash tools (2)
17
+ for (const tool of shellTools) {
18
+ registry.register(tool);
19
+ }
20
+ // Register web tools (3)
21
+ for (const tool of webTools) {
22
+ registry.register(tool);
23
+ }
24
+ // Register memory/knowledge tools (3)
25
+ for (const tool of memoryTools) {
26
+ registry.register(tool);
27
+ }
28
+ // Register extended tools: Todo, AskUser, Monitor (3)
29
+ for (const tool of extendedTools) {
30
+ registry.register(tool);
31
+ }
32
+ return registry;
33
+ }
34
+ export { globalRegistry } from './registry.js';
35
+ export { fileTools } from './file.js';
36
+ export { shellTools } from './bash.js';
37
+ export { webTools } from './web.js';
38
+ export { memoryTools } from './memory.js';
39
+ export { extendedTools } from './extended.js';
40
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,6 @@
1
+ import { ToolExecutor } from './registry.js';
2
+ export declare const saveMemoryTool: ToolExecutor;
3
+ export declare const recallMemoryTool: ToolExecutor;
4
+ export declare const projectContextTool: ToolExecutor;
5
+ export declare const memoryTools: ToolExecutor[];
6
+ //# sourceMappingURL=memory.d.ts.map
@@ -0,0 +1,197 @@
1
+ // ============================================================
2
+ // NeuroCLI - Memory & Knowledge Tools
3
+ // Persistent memory for cross-session learning
4
+ // ============================================================
5
+ import { readFileSync, writeFileSync, existsSync, mkdirSync } from 'fs';
6
+ import { join } from 'path';
7
+ import { homedir } from 'os';
8
+ const MEMORY_DIR = join(homedir(), '.neuro', 'memory');
9
+ function loadMemory() {
10
+ const memFile = join(MEMORY_DIR, 'store.json');
11
+ if (existsSync(memFile)) {
12
+ try {
13
+ return JSON.parse(readFileSync(memFile, 'utf-8'));
14
+ }
15
+ catch {
16
+ return { entries: {} };
17
+ }
18
+ }
19
+ return { entries: {} };
20
+ }
21
+ function saveMemory(store) {
22
+ if (!existsSync(MEMORY_DIR)) {
23
+ mkdirSync(MEMORY_DIR, { recursive: true });
24
+ }
25
+ writeFileSync(join(MEMORY_DIR, 'store.json'), JSON.stringify(store, null, 2), 'utf-8');
26
+ }
27
+ // ---- Save Memory ----
28
+ const saveMemoryDef = {
29
+ name: 'save_memory',
30
+ description: 'Save important information to persistent memory. Information persists across sessions. Use for project conventions, user preferences, API patterns, etc.',
31
+ parameters: {
32
+ type: 'object',
33
+ properties: {
34
+ key: { type: 'string', description: 'Unique key for this memory entry' },
35
+ value: { type: 'string', description: 'The information to save' },
36
+ tags: { type: 'string', description: 'Comma-separated tags for categorization' },
37
+ },
38
+ required: ['key', 'value'],
39
+ },
40
+ };
41
+ export const saveMemoryTool = {
42
+ name: 'save_memory',
43
+ definition: saveMemoryDef,
44
+ risk: 'low',
45
+ async execute(args) {
46
+ const store = loadMemory();
47
+ const key = args.key;
48
+ const tags = (args.tags || '').split(',').map(t => t.trim()).filter(Boolean);
49
+ const now = Date.now();
50
+ if (store.entries[key]) {
51
+ store.entries[key].value = args.value;
52
+ store.entries[key].tags = tags;
53
+ store.entries[key].updatedAt = now;
54
+ store.entries[key].accessCount++;
55
+ }
56
+ else {
57
+ store.entries[key] = {
58
+ key,
59
+ value: args.value,
60
+ tags,
61
+ createdAt: now,
62
+ updatedAt: now,
63
+ accessCount: 1,
64
+ };
65
+ }
66
+ saveMemory(store);
67
+ return `Memory saved: "${key}" (${args.value.length} chars, ${tags.length} tags)`;
68
+ },
69
+ };
70
+ // ---- Recall Memory ----
71
+ const recallMemoryDef = {
72
+ name: 'recall_memory',
73
+ description: 'Recall information from persistent memory. Search by key or tags.',
74
+ parameters: {
75
+ type: 'object',
76
+ properties: {
77
+ key: { type: 'string', description: 'Exact key to recall' },
78
+ tag: { type: 'string', description: 'Tag to search for' },
79
+ query: { type: 'string', description: 'Free-text search across all memories' },
80
+ },
81
+ required: [],
82
+ },
83
+ };
84
+ export const recallMemoryTool = {
85
+ name: 'recall_memory',
86
+ definition: recallMemoryDef,
87
+ risk: 'low',
88
+ async execute(args) {
89
+ const store = loadMemory();
90
+ const entries = Object.values(store.entries);
91
+ if (entries.length === 0)
92
+ return 'No memories stored yet.';
93
+ let results = [];
94
+ if (args.key) {
95
+ const entry = store.entries[args.key];
96
+ if (entry) {
97
+ entry.accessCount++;
98
+ saveMemory(store);
99
+ return `Memory: "${entry.key}"\n${entry.value}\nTags: ${entry.tags.join(', ')}\nCreated: ${new Date(entry.createdAt).toISOString()}`;
100
+ }
101
+ return `No memory found with key: "${args.key}"`;
102
+ }
103
+ if (args.tag) {
104
+ const tag = args.tag.toLowerCase();
105
+ results = entries.filter(e => e.tags.some(t => t.toLowerCase().includes(tag)));
106
+ }
107
+ if (args.query) {
108
+ const query = args.query.toLowerCase();
109
+ results = entries.filter(e => e.key.toLowerCase().includes(query) ||
110
+ e.value.toLowerCase().includes(query) ||
111
+ e.tags.some(t => t.toLowerCase().includes(query)));
112
+ }
113
+ if (!args.key && !args.tag && !args.query) {
114
+ results = entries;
115
+ }
116
+ if (results.length === 0)
117
+ return 'No matching memories found.';
118
+ return results.map(e => `📝 "${e.key}" [${e.tags.join(', ')}]\n ${e.value.slice(0, 200)}${e.value.length > 200 ? '...' : ''}\n Last updated: ${new Date(e.updatedAt).toISOString()}`).join('\n\n');
119
+ },
120
+ };
121
+ // ---- Project Context ----
122
+ const projectContextDef = {
123
+ name: 'project_context',
124
+ description: 'Gather context about the current project: tech stack, dependencies, structure, git status.',
125
+ parameters: {
126
+ type: 'object',
127
+ properties: {
128
+ depth: { type: 'string', description: 'How much context to gather', enum: ['quick', 'standard', 'deep'] },
129
+ },
130
+ required: [],
131
+ },
132
+ };
133
+ export const projectContextTool = {
134
+ name: 'project_context',
135
+ definition: projectContextDef,
136
+ risk: 'low',
137
+ async execute(args, context) {
138
+ const depth = args.depth || 'standard';
139
+ const lines = [];
140
+ lines.push(`📂 Working Directory: ${context.workingDirectory}`);
141
+ // Check for common project files
142
+ const projectFiles = [
143
+ 'package.json', 'tsconfig.json', 'Cargo.toml', 'pyproject.toml',
144
+ 'go.mod', 'pom.xml', 'build.gradle', 'Makefile', 'Dockerfile',
145
+ 'docker-compose.yml', '.env.example', 'README.md',
146
+ ];
147
+ const found = [];
148
+ for (const file of projectFiles) {
149
+ if (existsSync(join(context.workingDirectory, file))) {
150
+ found.push(file);
151
+ }
152
+ }
153
+ lines.push(`\n📋 Project Files: ${found.join(', ') || 'none detected'}`);
154
+ // Parse package.json if exists
155
+ const pkgPath = join(context.workingDirectory, 'package.json');
156
+ if (existsSync(pkgPath)) {
157
+ try {
158
+ const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));
159
+ lines.push(`\n📦 Name: ${pkg.name || 'unnamed'}`);
160
+ lines.push(`📦 Version: ${pkg.version || '0.0.0'}`);
161
+ if (pkg.dependencies) {
162
+ const deps = Object.keys(pkg.dependencies);
163
+ lines.push(`📦 Dependencies: ${deps.join(', ')}`);
164
+ }
165
+ if (pkg.devDependencies) {
166
+ const devDeps = Object.keys(pkg.devDependencies);
167
+ lines.push(`📦 Dev Dependencies: ${devDeps.join(', ')}`);
168
+ }
169
+ }
170
+ catch { }
171
+ }
172
+ // Parse pyproject.toml if exists
173
+ const pyPath = join(context.workingDirectory, 'pyproject.toml');
174
+ if (existsSync(pyPath)) {
175
+ try {
176
+ const content = readFileSync(pyPath, 'utf-8');
177
+ const nameMatch = content.match(/name\s*=\s*"([^"]+)"/);
178
+ if (nameMatch)
179
+ lines.push(`🐍 Python Project: ${nameMatch[1]}`);
180
+ }
181
+ catch { }
182
+ }
183
+ // Git info
184
+ try {
185
+ const { execSync } = await import('child_process');
186
+ const branch = execSync('git rev-parse --abbrev-ref HEAD', { encoding: 'utf-8', cwd: context.workingDirectory }).trim();
187
+ lines.push(`\n🌿 Git Branch: ${branch}`);
188
+ const status = execSync('git status --short', { encoding: 'utf-8', cwd: context.workingDirectory }).trim();
189
+ const changedFiles = status ? status.split('\n').length : 0;
190
+ lines.push(`🌿 Changed Files: ${changedFiles}`);
191
+ }
192
+ catch { }
193
+ return lines.join('\n');
194
+ },
195
+ };
196
+ export const memoryTools = [saveMemoryTool, recallMemoryTool, projectContextTool];
197
+ //# sourceMappingURL=memory.js.map
@@ -0,0 +1,29 @@
1
+ import { ToolDefinition, ToolResult, ApprovalRequest } from '../core/types.js';
2
+ export interface ToolExecutor {
3
+ name: string;
4
+ definition?: ToolDefinition;
5
+ description?: string;
6
+ parameters?: ToolDefinition['parameters'];
7
+ execute: (args: Record<string, unknown>, context: ToolContext) => Promise<string>;
8
+ getApprovalRequest?: (args: Record<string, unknown>) => ApprovalRequest;
9
+ risk: 'low' | 'medium' | 'high';
10
+ }
11
+ export interface ToolContext {
12
+ workingDirectory: string;
13
+ sessionId: string;
14
+ agentName: string;
15
+ onProgress?: (message: string) => void;
16
+ }
17
+ export declare class ToolRegistry {
18
+ private tools;
19
+ register(tool: ToolExecutor): void;
20
+ unregister(name: string): void;
21
+ get(name: string): ToolExecutor | undefined;
22
+ getAll(): ToolExecutor[];
23
+ getDefinitions(toolNames?: string[]): ToolDefinition[];
24
+ execute(name: string, args: Record<string, unknown>, context: ToolContext): Promise<ToolResult>;
25
+ getApprovalRequest(name: string, args: Record<string, unknown>): ApprovalRequest | null;
26
+ has(name: string): boolean;
27
+ }
28
+ export declare const globalRegistry: ToolRegistry;
29
+ //# sourceMappingURL=registry.d.ts.map
@@ -0,0 +1,64 @@
1
+ // ============================================================
2
+ // NeuroCLI - Tool Registry
3
+ // Central tool management and execution system
4
+ // ============================================================
5
+ export class ToolRegistry {
6
+ tools = new Map();
7
+ register(tool) {
8
+ this.tools.set(tool.name, tool);
9
+ }
10
+ unregister(name) {
11
+ this.tools.delete(name);
12
+ }
13
+ get(name) {
14
+ return this.tools.get(name);
15
+ }
16
+ getAll() {
17
+ return Array.from(this.tools.values());
18
+ }
19
+ getDefinitions(toolNames) {
20
+ if (toolNames) {
21
+ return toolNames
22
+ .map(name => this.tools.get(name)?.definition)
23
+ .filter((d) => d !== undefined);
24
+ }
25
+ return this.getAll().map(t => t.definition).filter((d) => d !== undefined);
26
+ }
27
+ async execute(name, args, context) {
28
+ const tool = this.tools.get(name);
29
+ if (!tool) {
30
+ return {
31
+ toolCallId: `error_${Date.now()}`,
32
+ content: `Unknown tool: ${name}`,
33
+ isError: true,
34
+ };
35
+ }
36
+ try {
37
+ const content = await tool.execute(args, context);
38
+ return {
39
+ toolCallId: `tool_${Date.now()}`,
40
+ content,
41
+ isError: false,
42
+ };
43
+ }
44
+ catch (error) {
45
+ return {
46
+ toolCallId: `error_${Date.now()}`,
47
+ content: `Tool execution error (${name}): ${error instanceof Error ? error.message : String(error)}`,
48
+ isError: true,
49
+ };
50
+ }
51
+ }
52
+ getApprovalRequest(name, args) {
53
+ const tool = this.tools.get(name);
54
+ if (!tool || !tool.getApprovalRequest)
55
+ return null;
56
+ return tool.getApprovalRequest(args);
57
+ }
58
+ has(name) {
59
+ return this.tools.has(name);
60
+ }
61
+ }
62
+ // Global singleton
63
+ export const globalRegistry = new ToolRegistry();
64
+ //# sourceMappingURL=registry.js.map
@@ -0,0 +1,6 @@
1
+ import { ToolExecutor } from './registry.js';
2
+ export declare const webSearchTool: ToolExecutor;
3
+ export declare const webFetchTool: ToolExecutor;
4
+ export declare const docSearchTool: ToolExecutor;
5
+ export declare const webTools: ToolExecutor[];
6
+ //# sourceMappingURL=web.d.ts.map
@@ -0,0 +1,150 @@
1
+ // ============================================================
2
+ // NeuroCLI - Web Tools
3
+ // Web search and fetch capabilities
4
+ // ============================================================
5
+ const MAX_FETCH_SIZE = 500 * 1024; // 500KB
6
+ const FETCH_TIMEOUT = 30000;
7
+ function truncateWebContent(content, maxLength = 30000) {
8
+ if (content.length <= maxLength)
9
+ return content;
10
+ const half = Math.floor(maxLength / 2);
11
+ return content.slice(0, half) + '\n\n... [content truncated] ...\n\n' + content.slice(-half);
12
+ }
13
+ // ---- Web Search ----
14
+ const webSearchDef = {
15
+ name: 'web_search',
16
+ description: 'Search the web for information. Returns search results with titles, URLs, and descriptions.',
17
+ parameters: {
18
+ type: 'object',
19
+ properties: {
20
+ query: { type: 'string', description: 'Search query' },
21
+ max_results: { type: 'number', description: 'Maximum number of results (default: 10)' },
22
+ },
23
+ required: ['query'],
24
+ },
25
+ };
26
+ export const webSearchTool = {
27
+ name: 'web_search',
28
+ definition: webSearchDef,
29
+ risk: 'low',
30
+ async execute(args) {
31
+ const query = args.query;
32
+ const maxResults = args.max_results || 10;
33
+ try {
34
+ // Use SearXNG or DuckDuckGo as search backend
35
+ const url = `https://api.duckduckgo.com/?q=${encodeURIComponent(query)}&format=json&no_html=1&max_results=${maxResults}`;
36
+ const response = await fetch(url, {
37
+ headers: { 'User-Agent': 'NeuroCLI/1.0' },
38
+ signal: AbortSignal.timeout(FETCH_TIMEOUT),
39
+ });
40
+ const data = await response.json();
41
+ const results = [];
42
+ if (data.Abstract) {
43
+ results.push(`📖 Summary: ${data.Abstract}\nSource: ${data.AbstractURL || 'DuckDuckGo'}\n`);
44
+ }
45
+ if (data.RelatedTopics) {
46
+ for (const topic of data.RelatedTopics.slice(0, maxResults)) {
47
+ if (topic.Text && topic.FirstURL) {
48
+ results.push(`🔗 ${topic.Text}\n URL: ${topic.FirstURL}`);
49
+ }
50
+ }
51
+ }
52
+ if (results.length === 0) {
53
+ // Fallback: try a different approach
54
+ return `Search results for "${query}":\n\nNo structured results found. Try using web_fetch to access specific URLs directly.`;
55
+ }
56
+ return `Search results for "${query}":\n\n${results.join('\n\n')}`;
57
+ }
58
+ catch (error) {
59
+ return `Search error: ${error.message}. Try using web_fetch with a specific URL instead.`;
60
+ }
61
+ },
62
+ };
63
+ // ---- Web Fetch ----
64
+ const webFetchDef = {
65
+ name: 'web_fetch',
66
+ description: 'Fetch and extract text content from a web page URL. Returns the page text content.',
67
+ parameters: {
68
+ type: 'object',
69
+ properties: {
70
+ url: { type: 'string', description: 'URL to fetch' },
71
+ selector: { type: 'string', description: 'CSS selector to extract specific content (optional)' },
72
+ raw: { type: 'boolean', description: 'Return raw HTML instead of text (default: false)' },
73
+ },
74
+ required: ['url'],
75
+ },
76
+ };
77
+ export const webFetchTool = {
78
+ name: 'web_fetch',
79
+ definition: webFetchDef,
80
+ risk: 'low',
81
+ async execute(args) {
82
+ const url = args.url;
83
+ const raw = args.raw || false;
84
+ try {
85
+ const response = await fetch(url, {
86
+ headers: {
87
+ 'User-Agent': 'Mozilla/5.0 (compatible; NeuroCLI/1.0)',
88
+ 'Accept': raw ? 'text/html' : 'text/html,application/xhtml+xml',
89
+ },
90
+ signal: AbortSignal.timeout(FETCH_TIMEOUT),
91
+ });
92
+ if (!response.ok) {
93
+ return `Error fetching ${url}: HTTP ${response.status} ${response.statusText}`;
94
+ }
95
+ let content = await response.text();
96
+ if (content.length > MAX_FETCH_SIZE) {
97
+ content = content.slice(0, MAX_FETCH_SIZE) + '\n\n... [content too large, truncated]';
98
+ }
99
+ if (!raw) {
100
+ // Basic HTML to text conversion
101
+ content = content
102
+ .replace(/<script[^>]*>[\s\S]*?<\/script>/gi, '')
103
+ .replace(/<style[^>]*>[\s\S]*?<\/style>/gi, '')
104
+ .replace(/<nav[^>]*>[\s\S]*?<\/nav>/gi, '')
105
+ .replace(/<footer[^>]*>[\s\S]*?<\/footer>/gi, '')
106
+ .replace(/<header[^>]*>[\s\S]*?<\/header>/gi, '')
107
+ .replace(/<[^>]+>/g, ' ')
108
+ .replace(/&nbsp;/g, ' ')
109
+ .replace(/&amp;/g, '&')
110
+ .replace(/&lt;/g, '<')
111
+ .replace(/&gt;/g, '>')
112
+ .replace(/&quot;/g, '"')
113
+ .replace(/&#39;/g, "'")
114
+ .replace(/\s+/g, ' ')
115
+ .trim();
116
+ }
117
+ return truncateWebContent(`Fetched: ${url}\n\n${content}`);
118
+ }
119
+ catch (error) {
120
+ return `Error fetching ${url}: ${error.message}`;
121
+ }
122
+ },
123
+ };
124
+ // ---- Documentation Search ----
125
+ const docSearchDef = {
126
+ name: 'doc_search',
127
+ description: 'Search documentation for a specific library, framework, or API. Returns relevant documentation snippets.',
128
+ parameters: {
129
+ type: 'object',
130
+ properties: {
131
+ library: { type: 'string', description: 'Library or framework name (e.g., "react", "next.js", "python")' },
132
+ query: { type: 'string', description: 'Specific question or topic to search for' },
133
+ },
134
+ required: ['library', 'query'],
135
+ },
136
+ };
137
+ export const docSearchTool = {
138
+ name: 'doc_search',
139
+ definition: docSearchDef,
140
+ risk: 'low',
141
+ async execute(args) {
142
+ const library = args.library;
143
+ const query = args.query;
144
+ const searchQuery = `${library} ${query} documentation`;
145
+ // Delegate to web search with documentation-focused query
146
+ return webSearchTool.execute({ query: searchQuery, max_results: 5 }, {});
147
+ },
148
+ };
149
+ export const webTools = [webSearchTool, webFetchTool, docSearchTool];
150
+ //# sourceMappingURL=web.js.map
@@ -0,0 +1,97 @@
1
+ import { Theme } from './theme.js';
2
+ import { TokenUsage } from '../core/types.js';
3
+ export declare class TerminalUI {
4
+ theme: Theme;
5
+ private showTokens;
6
+ private showCost;
7
+ constructor(themeName?: string, showTokens?: boolean, showCost?: boolean);
8
+ /**
9
+ * Print the banner / splash screen
10
+ */
11
+ banner(): void;
12
+ /**
13
+ * Print user message
14
+ */
15
+ userMessage(content: string): void;
16
+ /**
17
+ * Print assistant message with markdown-like formatting
18
+ */
19
+ assistantMessage(content: string): void;
20
+ /**
21
+ * Print streaming token
22
+ */
23
+ streamingToken(token: string): void;
24
+ /**
25
+ * Start streaming block
26
+ */
27
+ startStreaming(): void;
28
+ /**
29
+ * End streaming block
30
+ */
31
+ endStreaming(): void;
32
+ /**
33
+ * Print thinking indicator
34
+ */
35
+ thinking(message: string): void;
36
+ /**
37
+ * Print tool call
38
+ */
39
+ toolCall(name: string, args: Record<string, unknown>): void;
40
+ /**
41
+ * Print tool result
42
+ */
43
+ toolResult(name: string, result: string, isError: boolean): void;
44
+ /**
45
+ * Print approval request
46
+ */
47
+ approvalRequest(toolName: string, args: Record<string, unknown>, risk: 'low' | 'medium' | 'high'): boolean;
48
+ /**
49
+ * Print token usage
50
+ */
51
+ tokenUsage(usage: TokenUsage, modelId: string): void;
52
+ /**
53
+ * Print session stats
54
+ */
55
+ sessionStats(totalInput: number, totalOutput: number, totalCost: number): void;
56
+ /**
57
+ * Print agent activity
58
+ */
59
+ agentActivity(agentName: string, status: 'starting' | 'working' | 'done' | 'error'): void;
60
+ /**
61
+ * Print error
62
+ */
63
+ error(message: string): void;
64
+ /**
65
+ * Print info
66
+ */
67
+ info(message: string): void;
68
+ /**
69
+ * Print success
70
+ */
71
+ success(message: string): void;
72
+ /**
73
+ * Print warning
74
+ */
75
+ warning(message: string): void;
76
+ /**
77
+ * Print separator
78
+ */
79
+ separator(): void;
80
+ /**
81
+ * Print code block
82
+ */
83
+ codeBlock(code: string, language?: string): void;
84
+ /**
85
+ * Print model selection menu
86
+ */
87
+ modelList(selectedModel: string): void;
88
+ /**
89
+ * Print agent list
90
+ */
91
+ agentList(agents: Array<{
92
+ name: string;
93
+ description: string;
94
+ model: string;
95
+ }>): void;
96
+ }
97
+ //# sourceMappingURL=renderer.d.ts.map