@agents-at-scale/ark 0.1.35-rc1 → 0.1.35

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 (207) hide show
  1. package/dist/commands/cluster/index.d.ts +1 -2
  2. package/dist/commands/cluster/index.js +5 -3
  3. package/dist/commands/completion.js +2 -159
  4. package/dist/commands/config.d.ts +3 -0
  5. package/dist/commands/config.js +321 -38
  6. package/dist/commands/generate/config.js +24 -5
  7. package/dist/commands/generate/generators/agent.js +2 -2
  8. package/dist/commands/generate/generators/mcpserver.d.ts +1 -2
  9. package/dist/commands/generate/generators/mcpserver.js +5 -26
  10. package/dist/commands/generate/generators/project.js +41 -22
  11. package/dist/commands/generate/generators/team.js +2 -2
  12. package/dist/commands/generate/index.d.ts +1 -2
  13. package/dist/commands/generate/index.js +1 -1
  14. package/dist/components/statusChecker.d.ts +23 -13
  15. package/dist/components/statusChecker.js +129 -275
  16. package/dist/config.d.ts +22 -3
  17. package/dist/config.js +161 -10
  18. package/dist/index.d.ts +1 -1
  19. package/dist/index.js +42 -40
  20. package/dist/lib/cluster.d.ts +1 -2
  21. package/dist/lib/cluster.js +16 -37
  22. package/dist/lib/config.d.ts +80 -26
  23. package/dist/lib/config.js +205 -70
  24. package/dist/lib/consts.d.ts +1 -0
  25. package/dist/lib/consts.js +2 -0
  26. package/dist/lib/errors.js +1 -1
  27. package/dist/lib/exec.d.ts +4 -0
  28. package/dist/lib/exec.js +11 -0
  29. package/dist/lib/types.d.ts +3 -10
  30. package/dist/ui/MainMenu.d.ts +1 -5
  31. package/dist/ui/MainMenu.js +91 -222
  32. package/dist/ui/statusFormatter.d.ts +7 -22
  33. package/dist/ui/statusFormatter.js +39 -39
  34. package/package.json +5 -17
  35. package/dist/arkServices.d.ts +0 -42
  36. package/dist/arkServices.js +0 -138
  37. package/dist/arkServices.spec.d.ts +0 -1
  38. package/dist/arkServices.spec.js +0 -24
  39. package/dist/charts/charts.d.ts +0 -5
  40. package/dist/charts/charts.js +0 -6
  41. package/dist/charts/dependencies.d.ts +0 -6
  42. package/dist/charts/dependencies.js +0 -50
  43. package/dist/charts/types.d.ts +0 -40
  44. package/dist/charts/types.js +0 -1
  45. package/dist/commands/agents/index.d.ts +0 -3
  46. package/dist/commands/agents/index.js +0 -51
  47. package/dist/commands/agents/index.spec.d.ts +0 -1
  48. package/dist/commands/agents/index.spec.js +0 -67
  49. package/dist/commands/agents/selector.d.ts +0 -8
  50. package/dist/commands/agents/selector.js +0 -53
  51. package/dist/commands/agents.d.ts +0 -2
  52. package/dist/commands/agents.js +0 -53
  53. package/dist/commands/chat/index.d.ts +0 -3
  54. package/dist/commands/chat/index.js +0 -29
  55. package/dist/commands/chat.d.ts +0 -2
  56. package/dist/commands/chat.js +0 -45
  57. package/dist/commands/cluster/get.d.ts +0 -2
  58. package/dist/commands/cluster/get.js +0 -39
  59. package/dist/commands/cluster/get.spec.d.ts +0 -1
  60. package/dist/commands/cluster/get.spec.js +0 -92
  61. package/dist/commands/cluster/index.spec.d.ts +0 -1
  62. package/dist/commands/cluster/index.spec.js +0 -24
  63. package/dist/commands/completion/index.d.ts +0 -3
  64. package/dist/commands/completion/index.js +0 -268
  65. package/dist/commands/completion/index.spec.d.ts +0 -1
  66. package/dist/commands/completion/index.spec.js +0 -34
  67. package/dist/commands/config/index.d.ts +0 -3
  68. package/dist/commands/config/index.js +0 -42
  69. package/dist/commands/config/index.spec.d.ts +0 -1
  70. package/dist/commands/config/index.spec.js +0 -78
  71. package/dist/commands/dashboard/index.d.ts +0 -4
  72. package/dist/commands/dashboard/index.js +0 -39
  73. package/dist/commands/dashboard.d.ts +0 -3
  74. package/dist/commands/dashboard.js +0 -39
  75. package/dist/commands/dev/index.d.ts +0 -3
  76. package/dist/commands/dev/index.js +0 -9
  77. package/dist/commands/dev/tool/check.d.ts +0 -2
  78. package/dist/commands/dev/tool/check.js +0 -142
  79. package/dist/commands/dev/tool/clean.d.ts +0 -2
  80. package/dist/commands/dev/tool/clean.js +0 -153
  81. package/dist/commands/dev/tool/generate.d.ts +0 -2
  82. package/dist/commands/dev/tool/generate.js +0 -28
  83. package/dist/commands/dev/tool/index.d.ts +0 -2
  84. package/dist/commands/dev/tool/index.js +0 -14
  85. package/dist/commands/dev/tool/init.d.ts +0 -2
  86. package/dist/commands/dev/tool/init.js +0 -320
  87. package/dist/commands/dev/tool/shared.d.ts +0 -5
  88. package/dist/commands/dev/tool/shared.js +0 -256
  89. package/dist/commands/dev/tool/status.d.ts +0 -2
  90. package/dist/commands/dev/tool/status.js +0 -136
  91. package/dist/commands/dev/tool-generate.spec.d.ts +0 -1
  92. package/dist/commands/dev/tool-generate.spec.js +0 -163
  93. package/dist/commands/dev/tool.d.ts +0 -2
  94. package/dist/commands/dev/tool.js +0 -559
  95. package/dist/commands/dev/tool.spec.d.ts +0 -1
  96. package/dist/commands/dev/tool.spec.js +0 -48
  97. package/dist/commands/install/index.d.ts +0 -8
  98. package/dist/commands/install/index.js +0 -302
  99. package/dist/commands/install/index.spec.d.ts +0 -1
  100. package/dist/commands/install/index.spec.js +0 -135
  101. package/dist/commands/install.d.ts +0 -3
  102. package/dist/commands/install.js +0 -147
  103. package/dist/commands/models/create.d.ts +0 -1
  104. package/dist/commands/models/create.js +0 -213
  105. package/dist/commands/models/create.spec.d.ts +0 -1
  106. package/dist/commands/models/create.spec.js +0 -125
  107. package/dist/commands/models/index.d.ts +0 -3
  108. package/dist/commands/models/index.js +0 -60
  109. package/dist/commands/models/index.spec.d.ts +0 -1
  110. package/dist/commands/models/index.spec.js +0 -76
  111. package/dist/commands/models/selector.d.ts +0 -8
  112. package/dist/commands/models/selector.js +0 -53
  113. package/dist/commands/routes/index.d.ts +0 -3
  114. package/dist/commands/routes/index.js +0 -93
  115. package/dist/commands/routes.d.ts +0 -2
  116. package/dist/commands/routes.js +0 -101
  117. package/dist/commands/status/index.d.ts +0 -4
  118. package/dist/commands/status/index.js +0 -232
  119. package/dist/commands/status.d.ts +0 -3
  120. package/dist/commands/status.js +0 -33
  121. package/dist/commands/targets/index.d.ts +0 -3
  122. package/dist/commands/targets/index.js +0 -65
  123. package/dist/commands/targets/index.spec.d.ts +0 -1
  124. package/dist/commands/targets/index.spec.js +0 -105
  125. package/dist/commands/targets.d.ts +0 -2
  126. package/dist/commands/targets.js +0 -65
  127. package/dist/commands/teams/index.d.ts +0 -3
  128. package/dist/commands/teams/index.js +0 -49
  129. package/dist/commands/teams/index.spec.d.ts +0 -1
  130. package/dist/commands/teams/index.spec.js +0 -70
  131. package/dist/commands/teams/selector.d.ts +0 -8
  132. package/dist/commands/teams/selector.js +0 -55
  133. package/dist/commands/tools/index.d.ts +0 -3
  134. package/dist/commands/tools/index.js +0 -49
  135. package/dist/commands/tools/index.spec.d.ts +0 -1
  136. package/dist/commands/tools/index.spec.js +0 -70
  137. package/dist/commands/tools/selector.d.ts +0 -8
  138. package/dist/commands/tools/selector.js +0 -53
  139. package/dist/commands/uninstall/index.d.ts +0 -3
  140. package/dist/commands/uninstall/index.js +0 -107
  141. package/dist/commands/uninstall/index.spec.d.ts +0 -1
  142. package/dist/commands/uninstall/index.spec.js +0 -117
  143. package/dist/commands/uninstall.d.ts +0 -2
  144. package/dist/commands/uninstall.js +0 -83
  145. package/dist/components/ChatUI.d.ts +0 -16
  146. package/dist/components/ChatUI.js +0 -801
  147. package/dist/components/StatusView.d.ts +0 -10
  148. package/dist/components/StatusView.js +0 -39
  149. package/dist/lib/arkApiClient.d.ts +0 -53
  150. package/dist/lib/arkApiClient.js +0 -102
  151. package/dist/lib/arkApiProxy.d.ts +0 -9
  152. package/dist/lib/arkApiProxy.js +0 -22
  153. package/dist/lib/arkServiceProxy.d.ts +0 -14
  154. package/dist/lib/arkServiceProxy.js +0 -95
  155. package/dist/lib/arkStatus.d.ts +0 -10
  156. package/dist/lib/arkStatus.js +0 -79
  157. package/dist/lib/arkStatus.spec.d.ts +0 -1
  158. package/dist/lib/arkStatus.spec.js +0 -49
  159. package/dist/lib/chatClient.d.ts +0 -33
  160. package/dist/lib/chatClient.js +0 -99
  161. package/dist/lib/cluster.spec.d.ts +0 -1
  162. package/dist/lib/cluster.spec.js +0 -338
  163. package/dist/lib/commandUtils.d.ts +0 -4
  164. package/dist/lib/commandUtils.js +0 -18
  165. package/dist/lib/commandUtils.test.d.ts +0 -1
  166. package/dist/lib/commandUtils.test.js +0 -44
  167. package/dist/lib/commands.d.ts +0 -16
  168. package/dist/lib/commands.js +0 -29
  169. package/dist/lib/commands.spec.d.ts +0 -1
  170. package/dist/lib/commands.spec.js +0 -146
  171. package/dist/lib/config.spec.d.ts +0 -1
  172. package/dist/lib/config.spec.js +0 -99
  173. package/dist/lib/config.test.d.ts +0 -1
  174. package/dist/lib/config.test.js +0 -93
  175. package/dist/lib/consts.spec.d.ts +0 -1
  176. package/dist/lib/consts.spec.js +0 -15
  177. package/dist/lib/dev/tools/analyzer.d.ts +0 -30
  178. package/dist/lib/dev/tools/analyzer.js +0 -190
  179. package/dist/lib/dev/tools/discover_tools.py +0 -392
  180. package/dist/lib/dev/tools/mcp-types.d.ts +0 -28
  181. package/dist/lib/dev/tools/mcp-types.js +0 -86
  182. package/dist/lib/dev/tools/types.d.ts +0 -50
  183. package/dist/lib/dev/tools/types.js +0 -1
  184. package/dist/lib/errors.spec.d.ts +0 -1
  185. package/dist/lib/errors.spec.js +0 -221
  186. package/dist/lib/output.d.ts +0 -36
  187. package/dist/lib/output.js +0 -89
  188. package/dist/lib/output.spec.d.ts +0 -1
  189. package/dist/lib/output.spec.js +0 -123
  190. package/dist/lib/portUtils.d.ts +0 -8
  191. package/dist/lib/portUtils.js +0 -39
  192. package/dist/lib/startup.d.ts +0 -5
  193. package/dist/lib/startup.js +0 -73
  194. package/dist/lib/startup.spec.d.ts +0 -1
  195. package/dist/lib/startup.spec.js +0 -168
  196. package/dist/types/types.d.ts +0 -40
  197. package/dist/types/types.js +0 -1
  198. package/dist/ui/AgentSelector.d.ts +0 -8
  199. package/dist/ui/AgentSelector.js +0 -53
  200. package/dist/ui/ModelSelector.d.ts +0 -8
  201. package/dist/ui/ModelSelector.js +0 -53
  202. package/dist/ui/TeamSelector.d.ts +0 -8
  203. package/dist/ui/TeamSelector.js +0 -55
  204. package/dist/ui/ToolSelector.d.ts +0 -8
  205. package/dist/ui/ToolSelector.js +0 -53
  206. package/dist/ui/statusFormatter.spec.d.ts +0 -1
  207. package/dist/ui/statusFormatter.spec.js +0 -58
@@ -1,99 +0,0 @@
1
- import { jest } from '@jest/globals';
2
- import path from 'path';
3
- import os from 'os';
4
- const mockFs = {
5
- existsSync: jest.fn(),
6
- readFileSync: jest.fn(),
7
- };
8
- jest.unstable_mockModule('fs', () => ({
9
- default: mockFs,
10
- ...mockFs,
11
- }));
12
- const mockYaml = {
13
- parse: jest.fn(),
14
- stringify: jest.fn(),
15
- };
16
- jest.unstable_mockModule('yaml', () => ({
17
- default: mockYaml,
18
- ...mockYaml,
19
- }));
20
- const { loadConfig, getConfigPaths, formatConfig } = await import('./config.js');
21
- describe('config', () => {
22
- const originalEnv = process.env;
23
- beforeEach(() => {
24
- jest.clearAllMocks();
25
- process.env = { ...originalEnv };
26
- });
27
- afterEach(() => {
28
- process.env = originalEnv;
29
- });
30
- it('returns default config when no files exist', () => {
31
- mockFs.existsSync.mockReturnValue(false);
32
- const config = loadConfig();
33
- expect(config).toEqual({
34
- chat: {
35
- streaming: true,
36
- outputFormat: 'text',
37
- },
38
- });
39
- });
40
- it('loads and merges configs in order: defaults, user, project', () => {
41
- mockFs.existsSync.mockReturnValue(true);
42
- mockFs.readFileSync
43
- .mockReturnValueOnce('user yaml')
44
- .mockReturnValueOnce('project yaml');
45
- mockYaml.parse
46
- .mockReturnValueOnce({
47
- chat: {
48
- streaming: false,
49
- outputFormat: 'markdown',
50
- },
51
- })
52
- .mockReturnValueOnce({
53
- chat: {
54
- streaming: true,
55
- },
56
- });
57
- const config = loadConfig();
58
- expect(config.chat?.streaming).toBe(true);
59
- expect(config.chat?.outputFormat).toBe('markdown');
60
- });
61
- it('environment variables override all configs', () => {
62
- mockFs.existsSync.mockReturnValue(false);
63
- process.env.ARK_CHAT_STREAMING = '1';
64
- process.env.ARK_CHAT_OUTPUT_FORMAT = 'MARKDOWN';
65
- const config = loadConfig();
66
- expect(config.chat?.streaming).toBe(true);
67
- expect(config.chat?.outputFormat).toBe('markdown');
68
- });
69
- it('throws error for invalid YAML', () => {
70
- const userConfigPath = path.join(os.homedir(), '.arkrc.yaml');
71
- mockFs.existsSync.mockImplementation((path) => path === userConfigPath);
72
- mockFs.readFileSync.mockReturnValue('invalid yaml');
73
- mockYaml.parse.mockImplementation(() => {
74
- throw new Error('YAML parse error');
75
- });
76
- expect(() => loadConfig()).toThrow(`Invalid YAML in ${userConfigPath}: YAML parse error`);
77
- });
78
- it('handles non-Error exceptions', () => {
79
- const userConfigPath = path.join(os.homedir(), '.arkrc.yaml');
80
- mockFs.existsSync.mockImplementation((path) => path === userConfigPath);
81
- mockFs.readFileSync.mockReturnValue('invalid yaml');
82
- mockYaml.parse.mockImplementation(() => {
83
- throw 'string error';
84
- });
85
- expect(() => loadConfig()).toThrow(`Invalid YAML in ${userConfigPath}: Unknown error`);
86
- });
87
- it('getConfigPaths returns correct paths', () => {
88
- const paths = getConfigPaths();
89
- expect(paths.user).toBe(path.join(os.homedir(), '.arkrc.yaml'));
90
- expect(paths.project).toBe(path.join(process.cwd(), '.arkrc.yaml'));
91
- });
92
- it('formatConfig uses yaml.stringify', () => {
93
- const config = { chat: { streaming: true, outputFormat: 'text' } };
94
- mockYaml.stringify.mockReturnValue('formatted');
95
- const result = formatConfig(config);
96
- expect(mockYaml.stringify).toHaveBeenCalledWith(config);
97
- expect(result).toBe('formatted');
98
- });
99
- });
@@ -1 +0,0 @@
1
- export {};
@@ -1,93 +0,0 @@
1
- import { describe, it, expect, beforeEach, afterEach } from '@jest/globals';
2
- import { loadConfig } from './config.js';
3
- import fs from 'fs';
4
- import path from 'path';
5
- import os from 'os';
6
- describe('Config', () => {
7
- const originalEnv = process.env;
8
- const testProjectConfig = path.join(process.cwd(), '.arkrc.yaml');
9
- const testUserConfig = path.join(os.homedir(), '.arkrc.yaml');
10
- beforeEach(() => {
11
- // Reset environment
12
- process.env = { ...originalEnv };
13
- // Clean up any existing test configs
14
- if (fs.existsSync(testProjectConfig)) {
15
- fs.unlinkSync(testProjectConfig);
16
- }
17
- if (fs.existsSync(testUserConfig)) {
18
- fs.unlinkSync(testUserConfig);
19
- }
20
- });
21
- afterEach(() => {
22
- // Restore environment
23
- process.env = originalEnv;
24
- // Clean up test configs
25
- if (fs.existsSync(testProjectConfig)) {
26
- fs.unlinkSync(testProjectConfig);
27
- }
28
- if (fs.existsSync(testUserConfig)) {
29
- fs.unlinkSync(testUserConfig);
30
- }
31
- });
32
- it('should load default config when no files or env vars exist', () => {
33
- const config = loadConfig();
34
- expect(config.chat?.streaming).toBe(true);
35
- expect(config.chat?.outputFormat).toBe('text');
36
- });
37
- it('should override defaults with environment variables', () => {
38
- process.env.ARK_CHAT_STREAMING = '0';
39
- process.env.ARK_CHAT_OUTPUT_FORMAT = 'markdown';
40
- const config = loadConfig();
41
- expect(config.chat?.streaming).toBe(false);
42
- expect(config.chat?.outputFormat).toBe('markdown');
43
- });
44
- it('should accept "1" and "true" for streaming', () => {
45
- process.env.ARK_CHAT_STREAMING = '1';
46
- let config = loadConfig();
47
- expect(config.chat?.streaming).toBe(true);
48
- process.env.ARK_CHAT_STREAMING = 'true';
49
- config = loadConfig();
50
- expect(config.chat?.streaming).toBe(true);
51
- });
52
- it('should load project config file', () => {
53
- const configContent = `
54
- chat:
55
- streaming: false
56
- outputFormat: markdown
57
- `;
58
- fs.writeFileSync(testProjectConfig, configContent);
59
- const config = loadConfig();
60
- expect(config.chat?.streaming).toBe(false);
61
- expect(config.chat?.outputFormat).toBe('markdown');
62
- });
63
- it('should prioritize env vars over config files', () => {
64
- const configContent = `
65
- chat:
66
- streaming: false
67
- outputFormat: markdown
68
- `;
69
- fs.writeFileSync(testProjectConfig, configContent);
70
- process.env.ARK_CHAT_STREAMING = '1';
71
- process.env.ARK_CHAT_OUTPUT_FORMAT = 'text';
72
- const config = loadConfig();
73
- expect(config.chat?.streaming).toBe(true);
74
- expect(config.chat?.outputFormat).toBe('text');
75
- });
76
- it('should handle invalid config files gracefully', () => {
77
- fs.writeFileSync(testProjectConfig, 'invalid: yaml: content: {{{');
78
- // Should fall back to defaults without throwing
79
- const config = loadConfig();
80
- expect(config.chat?.streaming).toBe(true);
81
- expect(config.chat?.outputFormat).toBe('text');
82
- });
83
- it('should handle partial configs', () => {
84
- const configContent = `
85
- chat:
86
- streaming: false
87
- `;
88
- fs.writeFileSync(testProjectConfig, configContent);
89
- const config = loadConfig();
90
- expect(config.chat?.streaming).toBe(false);
91
- expect(config.chat?.outputFormat).toBe('text'); // Should use default
92
- });
93
- });
@@ -1 +0,0 @@
1
- export {};
@@ -1,15 +0,0 @@
1
- import { describe, it, expect } from '@jest/globals';
2
- import { DEFAULT_ADDRESS_ARK_API, DEFAULT_TIMEOUT_MS, DEFAULT_CONNECTION_TEST_TIMEOUT_MS, CONFIG_DIR_NAME, CONFIG_FILE_NAME, DEFAULT_ARK_DASHBOARD_URL, DEFAULT_ARK_A2A_URL, DEFAULT_ARK_MEMORY_URL, DEFAULT_ARK_OTEL_URL, } from './consts.js';
3
- describe('Constants', () => {
4
- it('defines correct default values', () => {
5
- expect(DEFAULT_ADDRESS_ARK_API).toBe('http://localhost:8000');
6
- expect(DEFAULT_TIMEOUT_MS).toBe(30000);
7
- expect(DEFAULT_CONNECTION_TEST_TIMEOUT_MS).toBe(5000);
8
- expect(CONFIG_DIR_NAME).toBe('ark');
9
- expect(CONFIG_FILE_NAME).toBe('ark-cli.json');
10
- expect(DEFAULT_ARK_DASHBOARD_URL).toBe('http://localhost:3000');
11
- expect(DEFAULT_ARK_A2A_URL).toBe('http://localhost:8080');
12
- expect(DEFAULT_ARK_MEMORY_URL).toBe('http://localhost:8081');
13
- expect(DEFAULT_ARK_OTEL_URL).toBe('http://localhost:4318');
14
- });
15
- });
@@ -1,30 +0,0 @@
1
- import { ArkDevToolStatus, DiscoveryResult, ProjectDiscoveryResult } from './types.js';
2
- export declare class ArkDevToolAnalyzer {
3
- private discoverToolsScript;
4
- constructor();
5
- /**
6
- * Analyze a tool directory and return its status
7
- */
8
- analyzeToolDirectory(toolPath: string): Promise<ArkDevToolStatus>;
9
- /**
10
- * Get project information by checking for Python project files
11
- */
12
- private getProjectInfo;
13
- /**
14
- * Discover project configuration
15
- */
16
- discoverProject(targetPath: string): Promise<ProjectDiscoveryResult | undefined>;
17
- /**
18
- * Discover tools using the Python script
19
- */
20
- discoverTools(targetPath: string): Promise<DiscoveryResult | undefined>;
21
- /**
22
- * Recursively find all MCP tools in a project
23
- * This is a naive implementation that searches all Python files in the project tree
24
- */
25
- findProjectTools(projectRoot: string): Promise<any>;
26
- /**
27
- * Extract all tools from discovery result
28
- */
29
- private extractTools;
30
- }
@@ -1,190 +0,0 @@
1
- import { execSync } from 'child_process';
2
- import fs from 'fs';
3
- import path from 'path';
4
- import { fileURLToPath } from 'url';
5
- const __filename = fileURLToPath(import.meta.url);
6
- const __dirname = path.dirname(__filename);
7
- export class ArkDevToolAnalyzer {
8
- constructor() {
9
- // The Python script is always adjacent to this file
10
- // In dev: src/lib/dev/tools/discover_tools.py
11
- // In prod: dist/lib/dev/tools/discover_tools.py (copied by postbuild)
12
- this.discoverToolsScript = path.join(__dirname, 'discover_tools.py');
13
- }
14
- /**
15
- * Analyze a tool directory and return its status
16
- */
17
- async analyzeToolDirectory(toolPath) {
18
- const absolutePath = path.resolve(toolPath);
19
- // Check if path exists
20
- if (!fs.existsSync(absolutePath)) {
21
- throw new Error(`Path not found: ${absolutePath}`);
22
- }
23
- // Get project info
24
- const projectInfo = this.getProjectInfo(absolutePath);
25
- // Discover tools using Python script
26
- const discovery = await this.discoverTools(absolutePath);
27
- // Extract all tools from discovery
28
- const tools = this.extractTools(discovery);
29
- return {
30
- ...projectInfo,
31
- discovery,
32
- tools,
33
- };
34
- }
35
- /**
36
- * Get project information by checking for Python project files
37
- */
38
- getProjectInfo(dirPath) {
39
- const info = {
40
- path: dirPath,
41
- platform: 'python3',
42
- projectType: 'unknown',
43
- hasVenv: false,
44
- fastMCP: false,
45
- };
46
- // Check for virtual environment
47
- info.hasVenv =
48
- fs.existsSync(path.join(dirPath, '.venv')) ||
49
- fs.existsSync(path.join(dirPath, 'venv'));
50
- // Check Python project type and FastMCP presence
51
- const pyprojectPath = path.join(dirPath, 'pyproject.toml');
52
- const requirementsPath = path.join(dirPath, 'requirements.txt');
53
- if (fs.existsSync(pyprojectPath)) {
54
- info.projectType = 'pyproject';
55
- const content = fs.readFileSync(pyprojectPath, 'utf-8');
56
- if (content.includes('fastmcp')) {
57
- info.fastMCP = true;
58
- // Try to extract version
59
- const versionMatch = content.match(/fastmcp[>=<~]*([0-9.]+)/);
60
- if (versionMatch) {
61
- info.fastMCPVersion = versionMatch[1];
62
- }
63
- }
64
- }
65
- else if (fs.existsSync(requirementsPath)) {
66
- info.projectType = 'requirements';
67
- const content = fs.readFileSync(requirementsPath, 'utf-8');
68
- if (content.includes('fastmcp')) {
69
- info.fastMCP = true;
70
- const versionMatch = content.match(/fastmcp[>=<~]*([0-9.]+)/);
71
- if (versionMatch) {
72
- info.fastMCPVersion = versionMatch[1];
73
- }
74
- }
75
- }
76
- return info;
77
- }
78
- /**
79
- * Discover project configuration
80
- */
81
- async discoverProject(targetPath) {
82
- try {
83
- // Check if Python is available
84
- try {
85
- execSync('python3 --version', { stdio: 'ignore' });
86
- }
87
- catch {
88
- console.warn('Python 3 not found');
89
- return undefined;
90
- }
91
- // Check if discover_tools.py exists
92
- if (!fs.existsSync(this.discoverToolsScript)) {
93
- console.warn(`discover_tools.py not found at ${this.discoverToolsScript}`);
94
- return undefined;
95
- }
96
- // Run the discovery script with 'project' command
97
- const result = execSync(`python3 "${this.discoverToolsScript}" project "${targetPath}"`, {
98
- encoding: 'utf-8',
99
- maxBuffer: 1024 * 1024, // 1MB buffer
100
- });
101
- return JSON.parse(result);
102
- }
103
- catch (error) {
104
- console.error('Project discovery failed:', error);
105
- return undefined;
106
- }
107
- }
108
- /**
109
- * Discover tools using the Python script
110
- */
111
- async discoverTools(targetPath) {
112
- try {
113
- // Check if Python is available
114
- try {
115
- execSync('python3 --version', { stdio: 'ignore' });
116
- }
117
- catch {
118
- console.warn('Python 3 not found, skipping tool discovery');
119
- return undefined;
120
- }
121
- // Check if discover_tools.py exists
122
- if (!fs.existsSync(this.discoverToolsScript)) {
123
- console.warn(`discover_tools.py not found at ${this.discoverToolsScript}`);
124
- return undefined;
125
- }
126
- // Run the discovery script with 'tools' command
127
- const result = execSync(`python3 "${this.discoverToolsScript}" tools "${targetPath}"`, {
128
- encoding: 'utf-8',
129
- maxBuffer: 1024 * 1024 * 10, // 10MB buffer
130
- });
131
- return JSON.parse(result);
132
- }
133
- catch (error) {
134
- console.error('Tool discovery failed:', error);
135
- return undefined;
136
- }
137
- }
138
- /**
139
- * Recursively find all MCP tools in a project
140
- * This is a naive implementation that searches all Python files in the project tree
141
- */
142
- async findProjectTools(projectRoot) {
143
- try {
144
- // Check if Python is available
145
- try {
146
- execSync('python3 --version', { stdio: 'ignore' });
147
- }
148
- catch {
149
- console.warn('Python 3 not found');
150
- return null;
151
- }
152
- // Check if discover_tools.py exists
153
- if (!fs.existsSync(this.discoverToolsScript)) {
154
- console.warn(`discover_tools.py not found at ${this.discoverToolsScript}`);
155
- return null;
156
- }
157
- // Run the discovery script with 'project-tools' command
158
- const result = execSync(`python3 "${this.discoverToolsScript}" project-tools "${projectRoot}"`, {
159
- encoding: 'utf-8',
160
- maxBuffer: 1024 * 1024 * 10, // 10MB buffer
161
- });
162
- return JSON.parse(result);
163
- }
164
- catch (error) {
165
- console.error('Project tools discovery failed:', error);
166
- return null;
167
- }
168
- }
169
- /**
170
- * Extract all tools from discovery result
171
- */
172
- extractTools(discovery) {
173
- if (!discovery)
174
- return [];
175
- // Check if it's a directory result
176
- if ('files' in discovery) {
177
- const dirResult = discovery;
178
- const tools = [];
179
- for (const file of dirResult.files) {
180
- if (file.success && file.tools) {
181
- tools.push(...file.tools);
182
- }
183
- }
184
- return tools;
185
- }
186
- // Single file result
187
- const fileResult = discovery;
188
- return fileResult.success ? fileResult.tools : [];
189
- }
190
- }