@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,142 +0,0 @@
1
- import { Command } from 'commander';
2
- import chalk from 'chalk';
3
- import path from 'path';
4
- import ora from 'ora';
5
- import output from '../../../lib/output.js';
6
- import { ArkDevToolAnalyzer } from '../../../lib/dev/tools/analyzer.js';
7
- import { toMCPTool } from '../../../lib/dev/tools/mcp-types.js';
8
- async function checkTool(toolPath, options) {
9
- const absolutePath = path.resolve(toolPath);
10
- const analyzer = new ArkDevToolAnalyzer();
11
- const isJson = options.output === 'json';
12
- // Build up result object as we go
13
- const result = {
14
- path: absolutePath,
15
- projectRoot: null,
16
- error: null,
17
- platform: null,
18
- projectType: null,
19
- projectName: null,
20
- projectVersion: null,
21
- hasFastmcp: false,
22
- fastmcpVersion: null,
23
- tools: [],
24
- toolDiscoveryError: null,
25
- };
26
- if (!isJson) {
27
- console.log();
28
- }
29
- // Single spinner for all analysis (skip for JSON output)
30
- const analyzeSpinner = isJson
31
- ? null
32
- : ora(`analyzing ${absolutePath}`).start();
33
- // Small delay to let user see what's happening (skip for JSON)
34
- if (!isJson) {
35
- await new Promise((resolve) => setTimeout(resolve, 500));
36
- }
37
- // Collect all information
38
- const project = await analyzer.discoverProject(absolutePath);
39
- if (!project || !project.exists) {
40
- result.error = 'path not found';
41
- if (isJson) {
42
- console.log(JSON.stringify(result, null, 2));
43
- }
44
- else {
45
- analyzeSpinner.stop();
46
- output.error(`path not found: ${absolutePath}`);
47
- }
48
- process.exit(1);
49
- }
50
- if (!project.is_directory) {
51
- result.error = 'path is not a directory';
52
- if (isJson) {
53
- console.log(JSON.stringify(result, null, 2));
54
- }
55
- else {
56
- analyzeSpinner.stop();
57
- output.error(`path is not a directory: ${absolutePath}`);
58
- }
59
- process.exit(1);
60
- }
61
- if (!project.platform) {
62
- result.error =
63
- 'platform unknown - no pyproject.toml or requirements.txt found';
64
- if (isJson) {
65
- console.log(JSON.stringify(result, null, 2));
66
- }
67
- else {
68
- analyzeSpinner.stop();
69
- output.error(`no pyproject.toml or requirements.txt found in: ${absolutePath}`);
70
- }
71
- process.exit(1);
72
- }
73
- // Update result with project info
74
- result.platform = project.platform;
75
- result.projectType = project.project_type;
76
- result.projectName = project.project_name;
77
- result.projectVersion = project.project_version;
78
- result.hasFastmcp = project.has_fastmcp;
79
- result.fastmcpVersion = project.fastmcp_version;
80
- result.projectRoot = absolutePath; // Store the project root
81
- // Discover tools recursively in the project
82
- const rawTools = [];
83
- try {
84
- const projectTools = await analyzer.findProjectTools(absolutePath);
85
- if (projectTools && projectTools.tools) {
86
- rawTools.push(...projectTools.tools);
87
- }
88
- }
89
- catch (error) {
90
- result.toolDiscoveryError =
91
- error instanceof Error ? error.message : 'Unknown error';
92
- }
93
- // Store tools in the appropriate format
94
- result.tools = isJson ? rawTools.map(toMCPTool) : rawTools;
95
- if (isJson) {
96
- // Output raw JSON
97
- console.log(JSON.stringify(result, null, 2));
98
- return;
99
- }
100
- analyzeSpinner.succeed('analysis complete');
101
- console.log();
102
- // Display summary in cleaner format
103
- output.section(path.basename(absolutePath));
104
- // Platform
105
- output.statusCheck('found', 'platform', result.platform);
106
- // Project type with name and version in gray
107
- let projectDetails = '';
108
- if (result.projectName) {
109
- projectDetails = result.projectName;
110
- if (result.projectVersion) {
111
- projectDetails += ` v${result.projectVersion}`;
112
- }
113
- }
114
- output.statusCheck('found', 'project', result.projectType, projectDetails);
115
- // Framework with version in gray
116
- if (result.hasFastmcp) {
117
- const fastmcpDetails = result.fastmcpVersion
118
- ? `v${result.fastmcpVersion}`
119
- : undefined;
120
- output.statusCheck('found', 'framework', 'fastmcp', fastmcpDetails);
121
- }
122
- else {
123
- output.statusCheck('missing', 'framework', 'fastmcp');
124
- }
125
- // Tools with details
126
- output.statusCheck('found', 'tools', result.tools.length.toString());
127
- if (result.tools.length > 0) {
128
- for (const tool of result.tools) {
129
- const description = tool.docstring ? tool.docstring.split('\n')[0] : '';
130
- console.log(chalk.gray(` - ${tool.name}: ${description}`));
131
- }
132
- }
133
- }
134
- export function createCheckCommand() {
135
- const checkCommand = new Command('check');
136
- checkCommand
137
- .description('Check the status of an MCP tool project')
138
- .argument('<path>', 'Path to the tool directory')
139
- .option('-o, --output <format>', 'Output format (json)', 'text')
140
- .action(checkTool);
141
- return checkCommand;
142
- }
@@ -1,2 +0,0 @@
1
- import { Command } from 'commander';
2
- export declare function createCleanCommand(): Command;
@@ -1,153 +0,0 @@
1
- import { Command } from 'commander';
2
- import chalk from 'chalk';
3
- import path from 'path';
4
- import { fileURLToPath } from 'url';
5
- import fs from 'fs';
6
- import yaml from 'yaml';
7
- import inquirer from 'inquirer';
8
- import output from '../../../lib/output.js';
9
- async function cleanTool(toolPath, options = {}) {
10
- const absolutePath = path.resolve(toolPath);
11
- const arkConfigPath = path.join(absolutePath, '.ark.yaml');
12
- // Check if .ark.yaml exists
13
- if (!fs.existsSync(arkConfigPath)) {
14
- output.error('.ark.yaml not found. Run "ark dev tool init" first.');
15
- process.exit(1);
16
- }
17
- // Load .ark.yaml to validate it's parseable
18
- yaml.parse(fs.readFileSync(arkConfigPath, 'utf-8'));
19
- // Find template directory
20
- const currentFile = fileURLToPath(import.meta.url);
21
- const distDir = path.dirname(path.dirname(path.dirname(path.dirname(currentFile)))); // Goes to dist/
22
- const arkCliDir = path.dirname(distDir); // Goes to ark-cli/
23
- const templateDir = path.join(arkCliDir, 'templates', 'python-mcp-tool');
24
- if (!fs.existsSync(templateDir)) {
25
- output.error('Template directory not found');
26
- process.exit(1);
27
- }
28
- // Collect all template-based files (not directories)
29
- const allTemplateFiles = [];
30
- const dirsToCheck = new Set();
31
- collectTemplateFiles(templateDir, absolutePath, allTemplateFiles, dirsToCheck);
32
- // Filter to only existing files
33
- const filesToClean = allTemplateFiles.filter((file) => {
34
- const fullPath = path.join(absolutePath, file);
35
- return fs.existsSync(fullPath);
36
- });
37
- if (filesToClean.length === 0) {
38
- console.log(chalk.green('No template-generated files found to clean.'));
39
- return;
40
- }
41
- console.log(chalk.yellow(`Found ${filesToClean.length} template-generated file(s) to potentially remove:`));
42
- // Display the list of files
43
- filesToClean.forEach((file) => {
44
- console.log(chalk.gray(` - ${file}`));
45
- });
46
- console.log();
47
- let removedCount = 0;
48
- let skippedCount = 0;
49
- // First, delete individual files
50
- for (const file of filesToClean) {
51
- const fullPath = path.join(absolutePath, file);
52
- // Ask for confirmation unless --yes flag is set
53
- let shouldDelete = options.yes;
54
- if (!shouldDelete) {
55
- const answer = await inquirer.prompt([
56
- {
57
- type: 'confirm',
58
- name: 'delete',
59
- message: `Delete file ${chalk.cyan(file)}?`,
60
- default: false,
61
- },
62
- ]);
63
- shouldDelete = answer.delete;
64
- }
65
- if (shouldDelete) {
66
- try {
67
- fs.unlinkSync(fullPath);
68
- console.log(chalk.green(` ✓ Removed ${file}`));
69
- removedCount++;
70
- }
71
- catch (err) {
72
- console.log(chalk.red(` ✗ Failed to remove ${file}: ${err instanceof Error ? err.message : 'Unknown error'}`));
73
- }
74
- }
75
- else {
76
- console.log(chalk.gray(` - Skipped ${file}`));
77
- skippedCount++;
78
- }
79
- }
80
- // Now check for empty directories and offer to delete them
81
- const sortedDirs = Array.from(dirsToCheck).sort((a, b) => b.length - a.length); // Process deepest dirs first
82
- for (const dir of sortedDirs) {
83
- const fullPath = path.join(absolutePath, dir);
84
- // Check if directory exists and is empty
85
- if (fs.existsSync(fullPath) && fs.statSync(fullPath).isDirectory()) {
86
- const contents = fs.readdirSync(fullPath);
87
- if (contents.length === 0) {
88
- // Directory is empty, ask to delete it
89
- let shouldDelete = options.yes;
90
- if (!shouldDelete) {
91
- const answer = await inquirer.prompt([
92
- {
93
- type: 'confirm',
94
- name: 'delete',
95
- message: `Delete empty directory ${chalk.cyan(dir)}?`,
96
- default: false,
97
- },
98
- ]);
99
- shouldDelete = answer.delete;
100
- }
101
- if (shouldDelete) {
102
- try {
103
- fs.rmdirSync(fullPath);
104
- console.log(chalk.green(` ✓ Removed empty directory ${dir}`));
105
- }
106
- catch (err) {
107
- console.log(chalk.red(` ✗ Failed to remove directory ${dir}: ${err instanceof Error ? err.message : 'Unknown error'}`));
108
- }
109
- }
110
- else {
111
- console.log(chalk.gray(` - Kept empty directory ${dir}`));
112
- }
113
- }
114
- }
115
- }
116
- console.log();
117
- if (removedCount > 0) {
118
- console.log(chalk.green(`✓ Removed ${removedCount} file(s)`));
119
- }
120
- if (skippedCount > 0) {
121
- console.log(chalk.gray(`Skipped ${skippedCount} file(s)`));
122
- }
123
- }
124
- function collectTemplateFiles(sourceDir, targetDir, files, dirsToCheck, relativePath = '') {
125
- const entries = fs.readdirSync(sourceDir, { withFileTypes: true });
126
- for (const entry of entries) {
127
- if (entry.isDirectory()) {
128
- // Track directory for later checking
129
- const dirPath = path.join(relativePath, entry.name);
130
- dirsToCheck.add(dirPath);
131
- // Recursively collect from subdirectory
132
- const subSourceDir = path.join(sourceDir, entry.name);
133
- collectTemplateFiles(subSourceDir, targetDir, files, dirsToCheck, dirPath);
134
- }
135
- else {
136
- // Check if it's a template file
137
- const targetFileName = entry.name.startsWith('template.')
138
- ? entry.name.replace('template.', '')
139
- : entry.name;
140
- const filePath = path.join(relativePath, targetFileName);
141
- files.push(filePath);
142
- }
143
- }
144
- }
145
- export function createCleanCommand() {
146
- const cleanCommand = new Command('clean');
147
- cleanCommand
148
- .description('Remove template-generated files from an MCP tool project')
149
- .argument('<path>', 'Path to the tool directory')
150
- .option('-y, --yes', 'Skip confirmation prompts and delete all files')
151
- .action(cleanTool);
152
- return cleanCommand;
153
- }
@@ -1,2 +0,0 @@
1
- import { Command } from 'commander';
2
- export declare function createGenerateCommand(): Command;
@@ -1,28 +0,0 @@
1
- import { Command } from 'commander';
2
- import chalk from 'chalk';
3
- import path from 'path';
4
- import { generateProjectFiles } from './shared.js';
5
- async function generateTool(toolPath, options = {}) {
6
- const absolutePath = path.resolve(toolPath);
7
- if (!options.dryRun) {
8
- if (options.overwrite) {
9
- console.log(chalk.yellow('Overwrite mode: existing files will be replaced'));
10
- }
11
- }
12
- await generateProjectFiles(absolutePath, {
13
- interactive: !options.dryRun,
14
- dryRun: options.dryRun,
15
- overwrite: options.overwrite,
16
- });
17
- // Next steps message removed - files are ready to use
18
- }
19
- export function createGenerateCommand() {
20
- const generateCommand = new Command('generate');
21
- generateCommand
22
- .description('Generate project files (Dockerfile, .dockerignore, etc.) from templates')
23
- .argument('<path>', 'Path to the tool directory')
24
- .option('--dry-run', 'Show generated template files without creating them')
25
- .option('--overwrite', 'Overwrite existing files')
26
- .action(generateTool);
27
- return generateCommand;
28
- }
@@ -1,2 +0,0 @@
1
- import { Command } from 'commander';
2
- export declare function createToolCommand(): Command;
@@ -1,14 +0,0 @@
1
- import { Command } from 'commander';
2
- import { createCheckCommand } from './check.js';
3
- import { createInitCommand } from './init.js';
4
- import { createGenerateCommand } from './generate.js';
5
- import { createCleanCommand } from './clean.js';
6
- export function createToolCommand() {
7
- const toolCommand = new Command('tool');
8
- toolCommand.description('MCP tool development utilities');
9
- toolCommand.addCommand(createCheckCommand());
10
- toolCommand.addCommand(createInitCommand());
11
- toolCommand.addCommand(createGenerateCommand());
12
- toolCommand.addCommand(createCleanCommand());
13
- return toolCommand;
14
- }
@@ -1,2 +0,0 @@
1
- import { Command } from 'commander';
2
- export declare function createInitCommand(): Command;
@@ -1,320 +0,0 @@
1
- import { Command } from 'commander';
2
- import chalk from 'chalk';
3
- import path from 'path';
4
- import ora from 'ora';
5
- import inquirer from 'inquirer';
6
- import fs from 'fs';
7
- import yaml from 'yaml';
8
- import output from '../../../lib/output.js';
9
- import { ArkDevToolAnalyzer } from '../../../lib/dev/tools/analyzer.js';
10
- import { generateProjectFiles } from './shared.js';
11
- async function initTool(toolPath) {
12
- const absolutePath = path.resolve(toolPath);
13
- const analyzer = new ArkDevToolAnalyzer();
14
- // Check if .ark.yaml already exists
15
- const arkConfigPath = path.join(absolutePath, '.ark.yaml');
16
- if (fs.existsSync(arkConfigPath)) {
17
- const { overwrite } = await inquirer.prompt([
18
- {
19
- type: 'confirm',
20
- name: 'overwrite',
21
- message: chalk.yellow('.ark.yaml already exists. Overwrite?'),
22
- default: false,
23
- },
24
- ]);
25
- if (!overwrite) {
26
- console.log(chalk.gray('Initialization cancelled'));
27
- return;
28
- }
29
- }
30
- // Initialize configuration object
31
- const arkConfig = {
32
- version: '1.0',
33
- project: {},
34
- };
35
- // Step 1: Check if path exists and is a directory
36
- const checkSpinner = ora('Checking project path...').start();
37
- const project = await analyzer.discoverProject(absolutePath);
38
- if (!project || !project.exists) {
39
- checkSpinner.fail('Path not found');
40
- output.error(`Path not found: ${absolutePath}`);
41
- process.exit(1);
42
- }
43
- if (!project.is_directory) {
44
- checkSpinner.fail('Path is not a directory');
45
- output.error(`Path is not a directory: ${absolutePath}`);
46
- process.exit(1);
47
- }
48
- checkSpinner.succeed('Project path verified');
49
- arkConfig.project.path = absolutePath;
50
- // Step 2: Detect platform
51
- console.log();
52
- if (!project.platform) {
53
- console.log(chalk.yellow('⚠ No Python project files found (pyproject.toml or requirements.txt)'));
54
- const { continueWithoutProject } = await inquirer.prompt([
55
- {
56
- type: 'confirm',
57
- name: 'continueWithoutProject',
58
- message: 'Continue without project files?',
59
- default: false,
60
- },
61
- ]);
62
- if (!continueWithoutProject) {
63
- console.log(chalk.gray('Initialization cancelled'));
64
- return;
65
- }
66
- // Set defaults but don't create anything
67
- arkConfig.project.platform = 'python3';
68
- arkConfig.project.type = 'none';
69
- }
70
- else {
71
- console.log(chalk.green(`✓ Detected platform: ${chalk.white(project.platform)}`));
72
- console.log(chalk.gray(` Found from: ${project.project_type === 'pyproject' ? 'pyproject.toml' : 'requirements.txt'}`));
73
- const { confirmPlatform } = await inquirer.prompt([
74
- {
75
- type: 'confirm',
76
- name: 'confirmPlatform',
77
- message: `Confirm platform is ${project.platform}?`,
78
- default: true,
79
- },
80
- ]);
81
- if (!confirmPlatform) {
82
- console.log(chalk.gray('Initialization cancelled'));
83
- return;
84
- }
85
- arkConfig.project.platform = project.platform;
86
- arkConfig.project.type = project.project_type;
87
- // Step 3: Project metadata
88
- if (project.project_name) {
89
- console.log();
90
- console.log(chalk.green(`✓ Found project name: ${chalk.white(project.project_name)}`));
91
- console.log(chalk.gray(` From: pyproject.toml [project.name]`));
92
- const { confirmName } = await inquirer.prompt([
93
- {
94
- type: 'confirm',
95
- name: 'confirmName',
96
- message: `Save project name as "${project.project_name}"?`,
97
- default: true,
98
- },
99
- ]);
100
- if (confirmName) {
101
- arkConfig.project.name = project.project_name;
102
- }
103
- if (project.project_version) {
104
- console.log();
105
- console.log(chalk.green(`✓ Found project version: ${chalk.white(project.project_version)}`));
106
- console.log(chalk.gray(` From: pyproject.toml [project.version]`));
107
- const { confirmVersion } = await inquirer.prompt([
108
- {
109
- type: 'confirm',
110
- name: 'confirmVersion',
111
- message: `Save project version as "${project.project_version}"?`,
112
- default: true,
113
- },
114
- ]);
115
- if (confirmVersion) {
116
- arkConfig.project.version = project.project_version;
117
- }
118
- }
119
- }
120
- // Step 4: Check for FastMCP
121
- console.log();
122
- if (project.has_fastmcp) {
123
- console.log(chalk.green(`✓ Found FastMCP framework: ${chalk.white(`v${project.fastmcp_version || 'unknown'}`)}`));
124
- console.log(chalk.gray(` From: ${project.project_type === 'pyproject' ? 'pyproject.toml dependencies' : 'requirements.txt'}`));
125
- const { confirmFramework } = await inquirer.prompt([
126
- {
127
- type: 'confirm',
128
- name: 'confirmFramework',
129
- message: `Save framework as FastMCP v${project.fastmcp_version}?`,
130
- default: true,
131
- },
132
- ]);
133
- if (confirmFramework) {
134
- arkConfig.project.framework = 'fastmcp';
135
- arkConfig.project.frameworkVersion = project.fastmcp_version;
136
- }
137
- }
138
- else {
139
- console.log(chalk.yellow('⚠ FastMCP not found in dependencies'));
140
- console.log(chalk.gray(` Checked: ${project.project_type === 'pyproject' ? 'pyproject.toml' : 'requirements.txt'}`));
141
- const { recordMissing } = await inquirer.prompt([
142
- {
143
- type: 'confirm',
144
- name: 'recordMissing',
145
- message: 'Record that FastMCP is not installed?',
146
- default: true,
147
- },
148
- ]);
149
- if (recordMissing) {
150
- arkConfig.project.framework = 'none';
151
- }
152
- }
153
- }
154
- // Step 5: MCP Transport Configuration (only if FastMCP is detected)
155
- if (arkConfig.project.framework === 'fastmcp') {
156
- // Try to detect transport from existing code
157
- let detectedTransport = null;
158
- const pythonFiles = fs
159
- .readdirSync(absolutePath)
160
- .filter((f) => f.endsWith('.py'));
161
- for (const file of pythonFiles) {
162
- const content = fs.readFileSync(path.join(absolutePath, file), 'utf-8');
163
- if (content.includes('transport="sse"')) {
164
- detectedTransport = 'sse';
165
- break;
166
- }
167
- else if (content.includes('transport="http"')) {
168
- detectedTransport = 'http';
169
- break;
170
- }
171
- else if (content.includes('transport="stdio"') ||
172
- content.includes('.run()')) {
173
- detectedTransport = 'stdio';
174
- break;
175
- }
176
- }
177
- if (detectedTransport) {
178
- console.log(chalk.green(`✓ MCP: Detected transport ${chalk.white(detectedTransport)}`));
179
- const { confirmTransport } = await inquirer.prompt([
180
- {
181
- type: 'confirm',
182
- name: 'confirmTransport',
183
- message: `Use transport "${detectedTransport}"?`,
184
- default: true,
185
- },
186
- ]);
187
- if (confirmTransport) {
188
- arkConfig.mcp = { transport: detectedTransport };
189
- }
190
- }
191
- // If not detected or not confirmed, ask
192
- if (!arkConfig.mcp) {
193
- const { transport } = await inquirer.prompt([
194
- {
195
- type: 'list',
196
- name: 'transport',
197
- message: 'Select MCP transport for deployment:',
198
- choices: [
199
- {
200
- name: 'SSE (Server-Sent Events) - Recommended for Kubernetes',
201
- value: 'sse',
202
- short: 'SSE',
203
- },
204
- {
205
- name: 'HTTP - Stateless request/response',
206
- value: 'http',
207
- short: 'HTTP',
208
- },
209
- {
210
- name: 'STDIO - Standard input/output for CLI tools',
211
- value: 'stdio',
212
- short: 'STDIO',
213
- },
214
- ],
215
- default: 'sse',
216
- },
217
- ]);
218
- arkConfig.mcp = { transport };
219
- }
220
- // Ask for port if not stdio
221
- if (arkConfig.mcp.transport !== 'stdio') {
222
- const { port } = await inquirer.prompt([
223
- {
224
- type: 'input',
225
- name: 'port',
226
- message: 'MCP server port:',
227
- default: '8080',
228
- validate: (input) => {
229
- const num = parseInt(input);
230
- if (isNaN(num) || num < 1 || num > 65535) {
231
- return 'Please enter a valid port number (1-65535)';
232
- }
233
- return true;
234
- },
235
- },
236
- ]);
237
- arkConfig.mcp.port = parseInt(port);
238
- // Show configuration snippet
239
- console.log();
240
- console.log(chalk.yellow('📝 Add this to your MCP server code:'));
241
- console.log(chalk.gray('─'.repeat(40)));
242
- if (arkConfig.mcp.transport === 'sse') {
243
- console.log(chalk.green(`if __name__ == "__main__":
244
- import os
245
- port = int(os.environ.get("PORT", "${arkConfig.mcp.port}"))
246
- mcp.run(transport="sse", host="0.0.0.0", port=port)`));
247
- }
248
- else if (arkConfig.mcp.transport === 'http') {
249
- console.log(chalk.green(`if __name__ == "__main__":
250
- import os
251
- port = int(os.environ.get("PORT", "${arkConfig.mcp.port}"))
252
- mcp.run(transport="http", host="0.0.0.0", port=port, path="/")`));
253
- }
254
- console.log(chalk.gray('─'.repeat(40)));
255
- console.log(chalk.dim('The PORT environment variable will be set by Kubernetes'));
256
- }
257
- }
258
- // Step 6: Write .ark.yaml
259
- console.log();
260
- const writeSpinner = ora('Writing .ark.yaml configuration...').start();
261
- try {
262
- const yamlContent = yaml.stringify(arkConfig);
263
- fs.writeFileSync(arkConfigPath, yamlContent, 'utf-8');
264
- writeSpinner.succeed('.ark.yaml created successfully');
265
- console.log();
266
- console.log(chalk.blue('Configuration Summary:'));
267
- console.log(chalk.gray('─'.repeat(40)));
268
- console.log(`Platform: ${arkConfig.project.platform}`);
269
- console.log(`Type: ${arkConfig.project.type}`);
270
- if (arkConfig.project.name) {
271
- console.log(`Name: ${arkConfig.project.name}`);
272
- console.log(`Version: ${arkConfig.project.version || 'unknown'}`);
273
- }
274
- if (arkConfig.project.framework) {
275
- console.log(`Framework: ${arkConfig.project.framework}`);
276
- }
277
- if (arkConfig.mcp) {
278
- console.log(`Transport: ${arkConfig.mcp.transport}`);
279
- if (arkConfig.mcp.port) {
280
- console.log(`Port: ${arkConfig.mcp.port}`);
281
- }
282
- }
283
- console.log(chalk.gray('─'.repeat(40)));
284
- console.log();
285
- console.log(chalk.green('✓ Initialization complete!'));
286
- // Step 6: Ask about generating project files
287
- console.log();
288
- const { generateFiles } = await inquirer.prompt([
289
- {
290
- type: 'confirm',
291
- name: 'generateFiles',
292
- message: 'Generate project files (Dockerfile, .dockerignore, etc.)?',
293
- default: true,
294
- },
295
- ]);
296
- if (generateFiles) {
297
- console.log();
298
- await generateProjectFiles(absolutePath, {
299
- interactive: true,
300
- dryRun: false,
301
- overwrite: false,
302
- });
303
- }
304
- console.log();
305
- console.log(' • Edit ' + chalk.cyan('.ark.yaml') + ' to update configuration');
306
- }
307
- catch (error) {
308
- writeSpinner.fail('Failed to write .ark.yaml');
309
- output.error(`Error: ${error instanceof Error ? error.message : 'Unknown error'}`);
310
- process.exit(1);
311
- }
312
- }
313
- export function createInitCommand() {
314
- const initCommand = new Command('init');
315
- initCommand
316
- .description('Initialize an MCP tool project with .ark.yaml configuration')
317
- .argument('<path>', 'Path to the tool directory')
318
- .action(initTool);
319
- return initCommand;
320
- }
@@ -1,5 +0,0 @@
1
- export declare function generateProjectFiles(toolPath: string, options?: {
2
- interactive?: boolean;
3
- dryRun?: boolean;
4
- overwrite?: boolean;
5
- }): Promise<boolean>;