@anastops/cli 0.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.
- package/dist/commands/config.d.ts +7 -0
- package/dist/commands/config.d.ts.map +1 -0
- package/dist/commands/config.js +131 -0
- package/dist/commands/config.js.map +1 -0
- package/dist/commands/doctor.d.ts +7 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +204 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/init.d.ts +12 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +105 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/ranger.d.ts +14 -0
- package/dist/commands/ranger.d.ts.map +1 -0
- package/dist/commands/ranger.js +67 -0
- package/dist/commands/ranger.js.map +1 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +46 -0
- package/dist/index.js.map +1 -0
- package/dist/utils/index.d.ts +2 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +2 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/table.d.ts +25 -0
- package/dist/utils/table.d.ts.map +1 -0
- package/dist/utils/table.js +65 -0
- package/dist/utils/table.js.map +1 -0
- package/package.json +68 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/commands/config.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AA2FH,wBAAsB,aAAa,CACjC,MAAM,EAAE,MAAM,EACd,GAAG,CAAC,EAAE,MAAM,EACZ,KAAK,CAAC,EAAE,MAAM,GACb,OAAO,CAAC,IAAI,CAAC,CAmEf"}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* anastops config command
|
|
3
|
+
*
|
|
4
|
+
* Manage configuration
|
|
5
|
+
*/
|
|
6
|
+
import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'fs';
|
|
7
|
+
import { join } from 'path';
|
|
8
|
+
import chalk from 'chalk';
|
|
9
|
+
function getConfigPath() {
|
|
10
|
+
return join(process.cwd(), '.anastops', 'config.json');
|
|
11
|
+
}
|
|
12
|
+
function loadConfig() {
|
|
13
|
+
const configPath = getConfigPath();
|
|
14
|
+
if (!existsSync(configPath)) {
|
|
15
|
+
return {};
|
|
16
|
+
}
|
|
17
|
+
try {
|
|
18
|
+
return JSON.parse(readFileSync(configPath, 'utf-8'));
|
|
19
|
+
}
|
|
20
|
+
catch (error) {
|
|
21
|
+
console.error('Failed to parse config file:', error);
|
|
22
|
+
return {};
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
function saveConfig(config) {
|
|
26
|
+
const configPath = getConfigPath();
|
|
27
|
+
const configDir = join(process.cwd(), '.anastops');
|
|
28
|
+
if (!existsSync(configDir)) {
|
|
29
|
+
mkdirSync(configDir, { recursive: true });
|
|
30
|
+
}
|
|
31
|
+
writeFileSync(configPath, JSON.stringify(config, null, 2));
|
|
32
|
+
}
|
|
33
|
+
function isRecord(value) {
|
|
34
|
+
return value !== null && typeof value === 'object' && !Array.isArray(value);
|
|
35
|
+
}
|
|
36
|
+
function getNestedValue(obj, path) {
|
|
37
|
+
const parts = path.split('.');
|
|
38
|
+
let current = obj;
|
|
39
|
+
for (const part of parts) {
|
|
40
|
+
if (!isRecord(current)) {
|
|
41
|
+
return undefined;
|
|
42
|
+
}
|
|
43
|
+
current = current[part];
|
|
44
|
+
}
|
|
45
|
+
return current;
|
|
46
|
+
}
|
|
47
|
+
function setNestedValue(obj, path, value) {
|
|
48
|
+
const parts = path.split('.');
|
|
49
|
+
let current = obj;
|
|
50
|
+
for (let i = 0; i < parts.length - 1; i++) {
|
|
51
|
+
const part = parts[i];
|
|
52
|
+
if (part === undefined)
|
|
53
|
+
continue;
|
|
54
|
+
if (current[part] === undefined || typeof current[part] !== 'object') {
|
|
55
|
+
current[part] = {};
|
|
56
|
+
}
|
|
57
|
+
current = current[part];
|
|
58
|
+
}
|
|
59
|
+
const lastPart = parts[parts.length - 1];
|
|
60
|
+
if (lastPart !== undefined) {
|
|
61
|
+
current[lastPart] = value;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
function printConfig(config, prefix = '') {
|
|
65
|
+
for (const [key, value] of Object.entries(config)) {
|
|
66
|
+
const fullKey = prefix !== '' ? `${prefix}.${key}` : key;
|
|
67
|
+
if (value !== null && typeof value === 'object' && !Array.isArray(value)) {
|
|
68
|
+
printConfig(value, fullKey);
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
console.log(` ${chalk.dim(fullKey)}: ${JSON.stringify(value)}`);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
export async function configCommand(action, key, value) {
|
|
76
|
+
const configAction = action;
|
|
77
|
+
switch (configAction) {
|
|
78
|
+
case 'list': {
|
|
79
|
+
const config = loadConfig();
|
|
80
|
+
if (Object.keys(config).length === 0) {
|
|
81
|
+
console.log(chalk.yellow('No configuration found.'));
|
|
82
|
+
console.log(chalk.dim('Run: anastops init'));
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
console.log(chalk.bold('Configuration'));
|
|
86
|
+
console.log(chalk.dim('─'.repeat(50)));
|
|
87
|
+
printConfig(config);
|
|
88
|
+
console.log('');
|
|
89
|
+
break;
|
|
90
|
+
}
|
|
91
|
+
case 'get': {
|
|
92
|
+
if (key === undefined) {
|
|
93
|
+
console.error(chalk.red('Usage: anastops config get <key>'));
|
|
94
|
+
process.exit(1);
|
|
95
|
+
}
|
|
96
|
+
const config = loadConfig();
|
|
97
|
+
const configValue = getNestedValue(config, key);
|
|
98
|
+
if (configValue === undefined) {
|
|
99
|
+
console.log(chalk.yellow(`Key not found: ${key}`));
|
|
100
|
+
process.exit(1);
|
|
101
|
+
}
|
|
102
|
+
console.log(JSON.stringify(configValue, null, 2));
|
|
103
|
+
break;
|
|
104
|
+
}
|
|
105
|
+
case 'set': {
|
|
106
|
+
if (key === undefined || value === undefined) {
|
|
107
|
+
console.error(chalk.red('Usage: anastops config set <key> <value>'));
|
|
108
|
+
process.exit(1);
|
|
109
|
+
}
|
|
110
|
+
const config = loadConfig();
|
|
111
|
+
// Try to parse value as JSON, fall back to string
|
|
112
|
+
let parsedValue;
|
|
113
|
+
try {
|
|
114
|
+
parsedValue = JSON.parse(value);
|
|
115
|
+
}
|
|
116
|
+
catch (_error) {
|
|
117
|
+
// Value is not valid JSON, treating as plain string
|
|
118
|
+
parsedValue = value;
|
|
119
|
+
}
|
|
120
|
+
setNestedValue(config, key, parsedValue);
|
|
121
|
+
saveConfig(config);
|
|
122
|
+
console.log(chalk.green('✓'), `Set ${key} = ${JSON.stringify(parsedValue)}`);
|
|
123
|
+
break;
|
|
124
|
+
}
|
|
125
|
+
default:
|
|
126
|
+
console.error(chalk.red(`Unknown action: ${action}`));
|
|
127
|
+
console.error(chalk.dim('Available actions: get, set, list'));
|
|
128
|
+
process.exit(1);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/commands/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAcH,wBAAsB,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC,CAiNnD"}
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* anastops doctor command
|
|
3
|
+
*
|
|
4
|
+
* Check system health and diagnose issues
|
|
5
|
+
*/
|
|
6
|
+
import { AdapterRegistry } from '@anastops/adapters';
|
|
7
|
+
import chalk from 'chalk';
|
|
8
|
+
import ora from 'ora';
|
|
9
|
+
export async function doctorCommand() {
|
|
10
|
+
console.log('');
|
|
11
|
+
console.log(chalk.bold('Anastops Health Check'));
|
|
12
|
+
console.log(chalk.dim('─'.repeat(50)));
|
|
13
|
+
console.log('');
|
|
14
|
+
const results = [];
|
|
15
|
+
// Check Node.js version
|
|
16
|
+
const nodeVersion = process.version;
|
|
17
|
+
const nodeVersionNum = parseInt(nodeVersion.slice(1).split('.')[0] ?? '0', 10);
|
|
18
|
+
results.push({
|
|
19
|
+
name: 'Node.js',
|
|
20
|
+
status: nodeVersionNum >= 18 ? 'pass' : 'fail',
|
|
21
|
+
message: nodeVersion,
|
|
22
|
+
details: nodeVersionNum < 18 ? 'Requires Node.js 18+' : undefined,
|
|
23
|
+
});
|
|
24
|
+
// Check configuration
|
|
25
|
+
const configSpinner = ora('Checking configuration...').start();
|
|
26
|
+
try {
|
|
27
|
+
const { existsSync } = await import('fs');
|
|
28
|
+
const { join } = await import('path');
|
|
29
|
+
const configPath = join(process.cwd(), '.anastops', 'config.json');
|
|
30
|
+
const hasConfig = existsSync(configPath);
|
|
31
|
+
configSpinner.stop();
|
|
32
|
+
results.push({
|
|
33
|
+
name: 'Configuration',
|
|
34
|
+
status: hasConfig ? 'pass' : 'warn',
|
|
35
|
+
message: hasConfig ? 'Found .anastops/config.json' : 'Not initialized',
|
|
36
|
+
details: !hasConfig ? 'Run: anastops init' : undefined,
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
catch {
|
|
40
|
+
configSpinner.stop();
|
|
41
|
+
results.push({
|
|
42
|
+
name: 'Configuration',
|
|
43
|
+
status: 'fail',
|
|
44
|
+
message: 'Error checking configuration',
|
|
45
|
+
details: undefined,
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
// Check Docker
|
|
49
|
+
const dockerSpinner = ora('Checking Docker...').start();
|
|
50
|
+
try {
|
|
51
|
+
const { execSync } = await import('child_process');
|
|
52
|
+
execSync('docker info', { stdio: 'pipe' });
|
|
53
|
+
dockerSpinner.stop();
|
|
54
|
+
results.push({
|
|
55
|
+
name: 'Docker',
|
|
56
|
+
status: 'pass',
|
|
57
|
+
message: 'Running',
|
|
58
|
+
details: undefined,
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
catch {
|
|
62
|
+
dockerSpinner.stop();
|
|
63
|
+
results.push({
|
|
64
|
+
name: 'Docker',
|
|
65
|
+
status: 'warn',
|
|
66
|
+
message: 'Not running or not installed',
|
|
67
|
+
details: 'Required for Redis/MongoDB',
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
// Check Redis using Docker SDK-style approach (programmatic parsing)
|
|
71
|
+
const redisSpinner = ora('Checking Redis...').start();
|
|
72
|
+
try {
|
|
73
|
+
const { execSync } = await import('child_process');
|
|
74
|
+
// Use Docker's --filter option to avoid shell injection via pipe
|
|
75
|
+
const dockerOutput = execSync('docker ps --filter "name=anastops-redis" --format "{{.Names}}"', {
|
|
76
|
+
stdio: 'pipe',
|
|
77
|
+
encoding: 'utf-8',
|
|
78
|
+
});
|
|
79
|
+
const isRunning = dockerOutput.trim().includes('anastops-redis');
|
|
80
|
+
redisSpinner.stop();
|
|
81
|
+
results.push({
|
|
82
|
+
name: 'Redis',
|
|
83
|
+
status: isRunning ? 'pass' : 'warn',
|
|
84
|
+
message: isRunning ? 'Container running' : 'Container not running',
|
|
85
|
+
details: isRunning ? undefined : 'Run: npm run docker:up',
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
catch (error) {
|
|
89
|
+
redisSpinner.stop();
|
|
90
|
+
console.error('Failed to check Redis container:', error);
|
|
91
|
+
results.push({
|
|
92
|
+
name: 'Redis',
|
|
93
|
+
status: 'warn',
|
|
94
|
+
message: 'Container not running',
|
|
95
|
+
details: 'Run: npm run docker:up',
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
// Check MongoDB using Docker SDK-style approach (programmatic parsing)
|
|
99
|
+
const mongoSpinner = ora('Checking MongoDB...').start();
|
|
100
|
+
try {
|
|
101
|
+
const { execSync } = await import('child_process');
|
|
102
|
+
// Use Docker's --filter option to avoid shell injection via pipe
|
|
103
|
+
const dockerOutput = execSync('docker ps --filter "name=anastops-mongodb" --format "{{.Names}}"', {
|
|
104
|
+
stdio: 'pipe',
|
|
105
|
+
encoding: 'utf-8',
|
|
106
|
+
});
|
|
107
|
+
const isRunning = dockerOutput.trim().includes('anastops-mongodb');
|
|
108
|
+
mongoSpinner.stop();
|
|
109
|
+
results.push({
|
|
110
|
+
name: 'MongoDB',
|
|
111
|
+
status: isRunning ? 'pass' : 'warn',
|
|
112
|
+
message: isRunning ? 'Container running' : 'Container not running',
|
|
113
|
+
details: isRunning ? undefined : 'Run: npm run docker:up',
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
catch (error) {
|
|
117
|
+
mongoSpinner.stop();
|
|
118
|
+
console.error('Failed to check MongoDB container:', error);
|
|
119
|
+
results.push({
|
|
120
|
+
name: 'MongoDB',
|
|
121
|
+
status: 'warn',
|
|
122
|
+
message: 'Container not running',
|
|
123
|
+
details: 'Run: npm run docker:up',
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
// Check AI providers
|
|
127
|
+
console.log('');
|
|
128
|
+
console.log(chalk.bold('AI Providers'));
|
|
129
|
+
console.log(chalk.dim('─'.repeat(50)));
|
|
130
|
+
const registry = AdapterRegistry.getInstance();
|
|
131
|
+
for (const adapter of registry.list()) {
|
|
132
|
+
const spinner = ora(`Checking ${adapter.name}...`).start();
|
|
133
|
+
try {
|
|
134
|
+
const [installed, authenticated] = await Promise.all([
|
|
135
|
+
adapter.isInstalled(),
|
|
136
|
+
adapter.isAuthenticated().catch(() => false),
|
|
137
|
+
]);
|
|
138
|
+
spinner.stop();
|
|
139
|
+
if (!installed) {
|
|
140
|
+
results.push({
|
|
141
|
+
name: adapter.name,
|
|
142
|
+
status: 'warn',
|
|
143
|
+
message: 'CLI not installed',
|
|
144
|
+
details: undefined,
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
else if (!authenticated) {
|
|
148
|
+
results.push({
|
|
149
|
+
name: adapter.name,
|
|
150
|
+
status: 'warn',
|
|
151
|
+
message: 'Installed but not authenticated',
|
|
152
|
+
details: undefined,
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
else {
|
|
156
|
+
const version = await adapter.getVersion();
|
|
157
|
+
results.push({
|
|
158
|
+
name: adapter.name,
|
|
159
|
+
status: 'pass',
|
|
160
|
+
message: `Ready (v${version ?? 'unknown'})`,
|
|
161
|
+
details: undefined,
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
catch {
|
|
166
|
+
spinner.stop();
|
|
167
|
+
results.push({
|
|
168
|
+
name: adapter.name,
|
|
169
|
+
status: 'fail',
|
|
170
|
+
message: 'Error checking provider',
|
|
171
|
+
details: undefined,
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
// Print results
|
|
176
|
+
console.log('');
|
|
177
|
+
console.log(chalk.bold('Results'));
|
|
178
|
+
console.log(chalk.dim('─'.repeat(50)));
|
|
179
|
+
for (const result of results) {
|
|
180
|
+
const icon = result.status === 'pass'
|
|
181
|
+
? chalk.green('✓')
|
|
182
|
+
: result.status === 'warn'
|
|
183
|
+
? chalk.yellow('!')
|
|
184
|
+
: chalk.red('✗');
|
|
185
|
+
console.log(` ${icon} ${result.name}: ${result.message}`);
|
|
186
|
+
if (result.details !== undefined) {
|
|
187
|
+
console.log(chalk.dim(` ${result.details}`));
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
// Summary
|
|
191
|
+
const passed = results.filter((r) => r.status === 'pass').length;
|
|
192
|
+
const warnings = results.filter((r) => r.status === 'warn').length;
|
|
193
|
+
const failed = results.filter((r) => r.status === 'fail').length;
|
|
194
|
+
console.log('');
|
|
195
|
+
console.log(chalk.dim('─'.repeat(50)));
|
|
196
|
+
console.log(` ${chalk.green(passed + ' passed')} | ` +
|
|
197
|
+
`${chalk.yellow(warnings + ' warnings')} | ` +
|
|
198
|
+
`${chalk.red(failed + ' failed')}`);
|
|
199
|
+
console.log('');
|
|
200
|
+
if (failed > 0) {
|
|
201
|
+
process.exit(1);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
//# sourceMappingURL=doctor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* anastops init command
|
|
3
|
+
*
|
|
4
|
+
* Initialize Anastops in the current project
|
|
5
|
+
*/
|
|
6
|
+
interface InitOptions {
|
|
7
|
+
skipDocker?: boolean;
|
|
8
|
+
skipMcp?: boolean;
|
|
9
|
+
}
|
|
10
|
+
export declare function initCommand(options: InitOptions): Promise<void>;
|
|
11
|
+
export {};
|
|
12
|
+
//# sourceMappingURL=init.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAQH,UAAU,WAAW;IACnB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,wBAAsB,WAAW,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAuGrE"}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* anastops init command
|
|
3
|
+
*
|
|
4
|
+
* Initialize Anastops in the current project
|
|
5
|
+
*/
|
|
6
|
+
import { existsSync, mkdirSync, writeFileSync, readFileSync } from 'fs';
|
|
7
|
+
import { join } from 'path';
|
|
8
|
+
import chalk from 'chalk';
|
|
9
|
+
import ora from 'ora';
|
|
10
|
+
export async function initCommand(options) {
|
|
11
|
+
const spinner = ora('Initializing Anastops...').start();
|
|
12
|
+
try {
|
|
13
|
+
const cwd = process.cwd();
|
|
14
|
+
// Create .anastops directory
|
|
15
|
+
const configDir = join(cwd, '.anastops');
|
|
16
|
+
if (!existsSync(configDir)) {
|
|
17
|
+
mkdirSync(configDir, { recursive: true });
|
|
18
|
+
}
|
|
19
|
+
// Create config file
|
|
20
|
+
const configPath = join(configDir, 'config.json');
|
|
21
|
+
const config = {
|
|
22
|
+
version: '0.1.0',
|
|
23
|
+
default_provider: 'claude',
|
|
24
|
+
context_budget: 1600,
|
|
25
|
+
routing: {
|
|
26
|
+
tiers: {
|
|
27
|
+
1: { provider: 'local', model: 'agent-booster' },
|
|
28
|
+
2: { provider: 'gemini', model: 'gemini-2.0-flash' },
|
|
29
|
+
3: { provider: 'claude', model: 'claude-haiku' },
|
|
30
|
+
4: { provider: 'claude', model: 'claude-sonnet' },
|
|
31
|
+
5: { provider: 'claude', model: 'claude-opus' },
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
memory: {
|
|
35
|
+
redis_url: 'redis://localhost:6380',
|
|
36
|
+
mongodb_url: 'mongodb://localhost:27018/anastops',
|
|
37
|
+
},
|
|
38
|
+
};
|
|
39
|
+
writeFileSync(configPath, JSON.stringify(config, null, 2));
|
|
40
|
+
spinner.succeed('Created .anastops/config.json');
|
|
41
|
+
// Set up Docker if not skipped
|
|
42
|
+
if (!options.skipDocker) {
|
|
43
|
+
const dockerSpinner = ora('Checking Docker setup...').start();
|
|
44
|
+
const dockerComposePath = join(cwd, 'docker', 'docker-compose.yml');
|
|
45
|
+
if (existsSync(dockerComposePath)) {
|
|
46
|
+
dockerSpinner.succeed('Docker Compose file found');
|
|
47
|
+
console.log(chalk.dim(' Run: npm run docker:up to start Redis and MongoDB'));
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
dockerSpinner.info('Docker Compose not found. Run from the package root for Docker setup.');
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
// Set up MCP server registration if not skipped
|
|
54
|
+
if (!options.skipMcp) {
|
|
55
|
+
const mcpSpinner = ora('Setting up MCP server...').start();
|
|
56
|
+
// Create MCP config for Claude Desktop
|
|
57
|
+
const mcpConfigDir = join(process.env['HOME'] ?? '', '.config', 'claude');
|
|
58
|
+
if (!existsSync(mcpConfigDir)) {
|
|
59
|
+
mkdirSync(mcpConfigDir, { recursive: true });
|
|
60
|
+
}
|
|
61
|
+
const mcpConfigPath = join(mcpConfigDir, 'claude_desktop_config.json');
|
|
62
|
+
const mcpConfig = {
|
|
63
|
+
mcpServers: {
|
|
64
|
+
anastops: {
|
|
65
|
+
command: 'npx',
|
|
66
|
+
args: ['@anastops/mcp-server'],
|
|
67
|
+
},
|
|
68
|
+
},
|
|
69
|
+
};
|
|
70
|
+
// Check if config exists and merge
|
|
71
|
+
if (existsSync(mcpConfigPath)) {
|
|
72
|
+
try {
|
|
73
|
+
console.log('DEBUG: Reading file:', mcpConfigPath);
|
|
74
|
+
const existing = JSON.parse(readFileSync(mcpConfigPath, 'utf-8'));
|
|
75
|
+
existing.mcpServers = existing.mcpServers ?? {};
|
|
76
|
+
existing.mcpServers.anastops = mcpConfig.mcpServers.anastops;
|
|
77
|
+
writeFileSync(mcpConfigPath, JSON.stringify(existing, null, 2));
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
writeFileSync(mcpConfigPath, JSON.stringify(mcpConfig, null, 2));
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
writeFileSync(mcpConfigPath, JSON.stringify(mcpConfig, null, 2));
|
|
85
|
+
}
|
|
86
|
+
mcpSpinner.succeed('MCP server registered for Claude Desktop');
|
|
87
|
+
}
|
|
88
|
+
// Summary
|
|
89
|
+
console.log('');
|
|
90
|
+
console.log(chalk.green('✓ Anastops initialized successfully!'));
|
|
91
|
+
console.log('');
|
|
92
|
+
console.log('Next steps:');
|
|
93
|
+
console.log(chalk.dim(' 1. Start infrastructure:'), 'npm run docker:up');
|
|
94
|
+
console.log(chalk.dim(' 2. Check health:'), 'anastops doctor');
|
|
95
|
+
console.log(chalk.dim(' 3. Create a session:'), 'anastops spawn "Your objective"');
|
|
96
|
+
console.log('');
|
|
97
|
+
}
|
|
98
|
+
catch (error) {
|
|
99
|
+
spinner.fail('Initialization failed');
|
|
100
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
101
|
+
console.error(chalk.red(message));
|
|
102
|
+
process.exit(1);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
//# sourceMappingURL=init.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ranger command - Launch interactive TUI dashboard
|
|
3
|
+
*
|
|
4
|
+
* The TUI is now implemented in Python using Textual.
|
|
5
|
+
* This command launches the Python-based ranger-tui package.
|
|
6
|
+
*/
|
|
7
|
+
interface RangerOptions {
|
|
8
|
+
refresh?: string | undefined;
|
|
9
|
+
session?: string | undefined;
|
|
10
|
+
json?: boolean | undefined;
|
|
11
|
+
}
|
|
12
|
+
export declare function rangerCommand(options: RangerOptions): Promise<void>;
|
|
13
|
+
export {};
|
|
14
|
+
//# sourceMappingURL=ranger.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ranger.d.ts","sourceRoot":"","sources":["../../src/commands/ranger.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAOH,UAAU,aAAa;IACrB,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B,IAAI,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CAC5B;AAKD,wBAAsB,aAAa,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CA2DzE"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ranger command - Launch interactive TUI dashboard
|
|
3
|
+
*
|
|
4
|
+
* The TUI is now implemented in Python using Textual.
|
|
5
|
+
* This command launches the Python-based ranger-tui package.
|
|
6
|
+
*/
|
|
7
|
+
import { spawn } from 'node:child_process';
|
|
8
|
+
import { resolve, dirname } from 'node:path';
|
|
9
|
+
import { fileURLToPath } from 'node:url';
|
|
10
|
+
import chalk from 'chalk';
|
|
11
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
12
|
+
const __dirname = dirname(__filename);
|
|
13
|
+
export async function rangerCommand(options) {
|
|
14
|
+
// Path to the ranger-tui package
|
|
15
|
+
const rangerTuiPath = resolve(__dirname, '../../../ranger-tui');
|
|
16
|
+
console.log(chalk.cyan('Starting Ranger TUI...'));
|
|
17
|
+
console.log(chalk.dim(`Path: ${rangerTuiPath}`));
|
|
18
|
+
// Build command arguments
|
|
19
|
+
const args = ['-m', 'ranger_tui'];
|
|
20
|
+
// Environment variables
|
|
21
|
+
const env = {
|
|
22
|
+
...process.env,
|
|
23
|
+
RANGER_REFRESH_INTERVAL: options.refresh ?? '2',
|
|
24
|
+
};
|
|
25
|
+
if (options.session) {
|
|
26
|
+
env.RANGER_INITIAL_SESSION = options.session;
|
|
27
|
+
}
|
|
28
|
+
// JSON mode outputs data and exits
|
|
29
|
+
if (options.json) {
|
|
30
|
+
console.log(chalk.yellow('JSON mode not yet supported in Textual TUI'));
|
|
31
|
+
console.log(chalk.dim('Use the MCP tools directly for JSON output'));
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
// Launch the Python TUI
|
|
35
|
+
const pythonProcess = spawn('python3', args, {
|
|
36
|
+
cwd: rangerTuiPath,
|
|
37
|
+
stdio: 'inherit',
|
|
38
|
+
env,
|
|
39
|
+
});
|
|
40
|
+
// Handle process exit
|
|
41
|
+
return new Promise((resolvePromise, reject) => {
|
|
42
|
+
pythonProcess.on('close', (code) => {
|
|
43
|
+
if (code === 0) {
|
|
44
|
+
resolvePromise();
|
|
45
|
+
}
|
|
46
|
+
else if (code === 127) {
|
|
47
|
+
console.error(chalk.red('\nPython not found. Please install Python 3.11+ and ranger-tui:'));
|
|
48
|
+
console.error(chalk.dim(' cd packages/ranger-tui && pip install -e .'));
|
|
49
|
+
reject(new Error(`Ranger TUI exited with code ${code}`));
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
console.error(chalk.red(`\nRanger TUI exited with code ${code}`));
|
|
53
|
+
console.error(chalk.dim('Make sure ranger-tui is installed:'));
|
|
54
|
+
console.error(chalk.dim(' cd packages/ranger-tui && pip install -e .'));
|
|
55
|
+
reject(new Error(`Ranger TUI exited with code ${code}`));
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
pythonProcess.on('error', (err) => {
|
|
59
|
+
console.error(chalk.red('\nFailed to start Ranger TUI:'));
|
|
60
|
+
console.error(chalk.dim(err.message));
|
|
61
|
+
console.error(chalk.dim('\nMake sure Python 3.11+ is installed and ranger-tui is set up:'));
|
|
62
|
+
console.error(chalk.dim(' cd packages/ranger-tui && pip install -e .'));
|
|
63
|
+
reject(err);
|
|
64
|
+
});
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=ranger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ranger.js","sourceRoot":"","sources":["../../src/commands/ranger.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* @anastops/cli
|
|
4
|
+
*
|
|
5
|
+
* Infrastructure CLI for Anastops MCP Server setup and diagnostics
|
|
6
|
+
*
|
|
7
|
+
* NOTE: Orchestration commands (spawn, fork, list, status) have been removed.
|
|
8
|
+
* All session/agent/task orchestration is handled through MCP Server tools.
|
|
9
|
+
* This CLI is for infrastructure setup, configuration, and health checks only.
|
|
10
|
+
*
|
|
11
|
+
* @see REQ-1.7.4: "CLI SHALL NOT provide orchestration commands"
|
|
12
|
+
*/
|
|
13
|
+
export {};
|
|
14
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;;;;;;;;GAUG"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* @anastops/cli
|
|
4
|
+
*
|
|
5
|
+
* Infrastructure CLI for Anastops MCP Server setup and diagnostics
|
|
6
|
+
*
|
|
7
|
+
* NOTE: Orchestration commands (spawn, fork, list, status) have been removed.
|
|
8
|
+
* All session/agent/task orchestration is handled through MCP Server tools.
|
|
9
|
+
* This CLI is for infrastructure setup, configuration, and health checks only.
|
|
10
|
+
*
|
|
11
|
+
* @see REQ-1.7.4: "CLI SHALL NOT provide orchestration commands"
|
|
12
|
+
*/
|
|
13
|
+
import { Command } from 'commander';
|
|
14
|
+
import { configCommand } from './commands/config.js';
|
|
15
|
+
import { doctorCommand } from './commands/doctor.js';
|
|
16
|
+
import { initCommand } from './commands/init.js';
|
|
17
|
+
import { rangerCommand } from './commands/ranger.js';
|
|
18
|
+
const program = new Command();
|
|
19
|
+
program
|
|
20
|
+
.name('anastops')
|
|
21
|
+
.description('Infrastructure CLI for Anastops MCP Server setup and diagnostics')
|
|
22
|
+
.version('0.1.0');
|
|
23
|
+
// Infrastructure commands only
|
|
24
|
+
program
|
|
25
|
+
.command('init')
|
|
26
|
+
.description('Initialize Anastops in current project')
|
|
27
|
+
.option('--skip-docker', 'Skip Docker infrastructure setup')
|
|
28
|
+
.option('--skip-mcp', 'Skip MCP server registration')
|
|
29
|
+
.action(initCommand);
|
|
30
|
+
program
|
|
31
|
+
.command('doctor')
|
|
32
|
+
.description('Check system health and diagnose issues')
|
|
33
|
+
.action(doctorCommand);
|
|
34
|
+
program
|
|
35
|
+
.command('config <action> [key] [value]')
|
|
36
|
+
.description('Manage configuration (get|set|list)')
|
|
37
|
+
.action(configCommand);
|
|
38
|
+
program
|
|
39
|
+
.command('ranger')
|
|
40
|
+
.description('Launch interactive Textual TUI dashboard (requires Python 3.11+)')
|
|
41
|
+
.option('--refresh <seconds>', 'Auto-refresh interval', '2')
|
|
42
|
+
.option('--session <id>', 'Jump directly to a session')
|
|
43
|
+
.option('--json', 'Output current state as JSON and exit (not yet supported)')
|
|
44
|
+
.action(rangerCommand);
|
|
45
|
+
program.parse();
|
|
46
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAErD,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,UAAU,CAAC;KAChB,WAAW,CAAC,kEAAkE,CAAC;KAC/E,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,+BAA+B;AAC/B,OAAO;KACJ,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,wCAAwC,CAAC;KACrD,MAAM,CAAC,eAAe,EAAE,kCAAkC,CAAC;KAC3D,MAAM,CAAC,YAAY,EAAE,8BAA8B,CAAC;KACpD,MAAM,CAAC,WAAW,CAAC,CAAC;AAEvB,OAAO;KACJ,OAAO,CAAC,QAAQ,CAAC;KACjB,WAAW,CAAC,yCAAyC,CAAC;KACtD,MAAM,CAAC,aAAa,CAAC,CAAC;AAEzB,OAAO;KACJ,OAAO,CAAC,+BAA+B,CAAC;KACxC,WAAW,CAAC,qCAAqC,CAAC;KAClD,MAAM,CAAC,aAAa,CAAC,CAAC;AAEzB,OAAO;KACJ,OAAO,CAAC,QAAQ,CAAC;KACjB,WAAW,CAAC,kEAAkE,CAAC;KAC/E,MAAM,CAAC,qBAAqB,EAAE,uBAAuB,EAAE,GAAG,CAAC;KAC3D,MAAM,CAAC,gBAAgB,EAAE,4BAA4B,CAAC;KACtD,MAAM,CAAC,QAAQ,EAAE,2DAA2D,CAAC;KAC7E,MAAM,CAAC,aAAa,CAAC,CAAC;AAEzB,OAAO,CAAC,KAAK,EAAE,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,KAAK,WAAW,EAAE,KAAK,YAAY,EAAE,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,OAAO,EAAuC,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
export interface TableColumn {
|
|
3
|
+
header: string;
|
|
4
|
+
width: number;
|
|
5
|
+
align?: 'left' | 'center' | 'right';
|
|
6
|
+
}
|
|
7
|
+
export interface TableOptions {
|
|
8
|
+
columns: TableColumn[];
|
|
9
|
+
borderColor?: typeof chalk.gray;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Renders a table with borders
|
|
13
|
+
*/
|
|
14
|
+
export declare function renderTable(options: TableOptions, rows: string[][]): string;
|
|
15
|
+
/**
|
|
16
|
+
* Symbols for status display
|
|
17
|
+
*/
|
|
18
|
+
export declare const symbols: {
|
|
19
|
+
success: string;
|
|
20
|
+
failure: string;
|
|
21
|
+
warning: string;
|
|
22
|
+
info: string;
|
|
23
|
+
pending: string;
|
|
24
|
+
};
|
|
25
|
+
//# sourceMappingURL=table.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"table.d.ts","sourceRoot":"","sources":["../../src/utils/table.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,OAAO,CAAC;CACrC;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,WAAW,EAAE,CAAC;IACvB,WAAW,CAAC,EAAE,OAAO,KAAK,CAAC,IAAI,CAAC;CACjC;AAwBD;;GAEG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,GAAG,MAAM,CA0C3E;AAED;;GAEG;AACH,eAAO,MAAM,OAAO;;;;;;CAMnB,CAAC"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
/**
|
|
3
|
+
* Pads a string to the specified width with the specified alignment
|
|
4
|
+
*/
|
|
5
|
+
function padString(str, width, align = 'left') {
|
|
6
|
+
// Strip ANSI codes for length calculation
|
|
7
|
+
const strippedLength = str.replace(/\x1B\[[0-9;]*m/g, '').length;
|
|
8
|
+
const padding = Math.max(0, width - strippedLength);
|
|
9
|
+
switch (align) {
|
|
10
|
+
case 'center': {
|
|
11
|
+
const leftPad = Math.floor(padding / 2);
|
|
12
|
+
const rightPad = padding - leftPad;
|
|
13
|
+
return ' '.repeat(leftPad) + str + ' '.repeat(rightPad);
|
|
14
|
+
}
|
|
15
|
+
case 'right':
|
|
16
|
+
return ' '.repeat(padding) + str;
|
|
17
|
+
case 'left':
|
|
18
|
+
default:
|
|
19
|
+
return str + ' '.repeat(padding);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Renders a table with borders
|
|
24
|
+
*/
|
|
25
|
+
export function renderTable(options, rows) {
|
|
26
|
+
const { columns, borderColor = chalk.gray } = options;
|
|
27
|
+
const lines = [];
|
|
28
|
+
// Build horizontal border
|
|
29
|
+
const topBorder = borderColor('\u250C') +
|
|
30
|
+
columns.map((col) => borderColor('\u2500'.repeat(col.width + 2))).join(borderColor('\u252C')) +
|
|
31
|
+
borderColor('\u2510');
|
|
32
|
+
const middleBorder = borderColor('\u251C') +
|
|
33
|
+
columns.map((col) => borderColor('\u2500'.repeat(col.width + 2))).join(borderColor('\u253C')) +
|
|
34
|
+
borderColor('\u2524');
|
|
35
|
+
const bottomBorder = borderColor('\u2514') +
|
|
36
|
+
columns.map((col) => borderColor('\u2500'.repeat(col.width + 2))).join(borderColor('\u2534')) +
|
|
37
|
+
borderColor('\u2518');
|
|
38
|
+
// Build header row
|
|
39
|
+
const headerRow = borderColor('\u2502') +
|
|
40
|
+
columns.map((col) => ' ' + chalk.bold(padString(col.header, col.width, col.align)) + ' ').join(borderColor('\u2502')) +
|
|
41
|
+
borderColor('\u2502');
|
|
42
|
+
lines.push(topBorder);
|
|
43
|
+
lines.push(headerRow);
|
|
44
|
+
lines.push(middleBorder);
|
|
45
|
+
// Build data rows
|
|
46
|
+
for (const row of rows) {
|
|
47
|
+
const dataRow = borderColor('\u2502') +
|
|
48
|
+
columns.map((col, i) => ' ' + padString(row[i] || '', col.width, col.align) + ' ').join(borderColor('\u2502')) +
|
|
49
|
+
borderColor('\u2502');
|
|
50
|
+
lines.push(dataRow);
|
|
51
|
+
}
|
|
52
|
+
lines.push(bottomBorder);
|
|
53
|
+
return lines.join('\n');
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Symbols for status display
|
|
57
|
+
*/
|
|
58
|
+
export const symbols = {
|
|
59
|
+
success: chalk.green('\u2713'),
|
|
60
|
+
failure: chalk.red('-'),
|
|
61
|
+
warning: chalk.yellow('!'),
|
|
62
|
+
info: chalk.blue('i'),
|
|
63
|
+
pending: chalk.gray('\u2022'),
|
|
64
|
+
};
|
|
65
|
+
//# sourceMappingURL=table.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"table.js","sourceRoot":"","sources":["../../src/utils/table.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@anastops/cli",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Infrastructure CLI for Anastops MCP Server setup and diagnostics",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"type": "module",
|
|
8
|
+
"bin": {
|
|
9
|
+
"anastops": "./dist/index.js"
|
|
10
|
+
},
|
|
11
|
+
"exports": {
|
|
12
|
+
".": {
|
|
13
|
+
"types": "./dist/index.d.ts",
|
|
14
|
+
"import": "./dist/index.js"
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
"scripts": {
|
|
18
|
+
"build": "tsc",
|
|
19
|
+
"dev": "tsc --watch",
|
|
20
|
+
"start": "node dist/index.js",
|
|
21
|
+
"test": "vitest run",
|
|
22
|
+
"test:watch": "vitest",
|
|
23
|
+
"test:coverage": "vitest run --coverage",
|
|
24
|
+
"lint": "eslint src --ext .ts",
|
|
25
|
+
"typecheck": "tsc --noEmit",
|
|
26
|
+
"clean": "rm -rf dist"
|
|
27
|
+
},
|
|
28
|
+
"dependencies": {
|
|
29
|
+
"@anastops/core": "workspace:*",
|
|
30
|
+
"@anastops/adapters": "workspace:*",
|
|
31
|
+
"@anastops/mcp-server": "workspace:*",
|
|
32
|
+
"commander": "^14.0.2",
|
|
33
|
+
"enquirer": "^2.4.1",
|
|
34
|
+
"chalk": "^5.6.2",
|
|
35
|
+
"ora": "^9.0.0",
|
|
36
|
+
"cli-table3": "^0.6.5"
|
|
37
|
+
},
|
|
38
|
+
"devDependencies": {
|
|
39
|
+
"@types/node": "^20.11.0",
|
|
40
|
+
"typescript": "^5.9.3",
|
|
41
|
+
"vitest": "^4.0.17"
|
|
42
|
+
},
|
|
43
|
+
"peerDependencies": {
|
|
44
|
+
"typescript": ">=5.0.0"
|
|
45
|
+
},
|
|
46
|
+
"files": [
|
|
47
|
+
"dist"
|
|
48
|
+
],
|
|
49
|
+
"keywords": [
|
|
50
|
+
"cli",
|
|
51
|
+
"ai",
|
|
52
|
+
"orchestration",
|
|
53
|
+
"anastops"
|
|
54
|
+
],
|
|
55
|
+
"repository": {
|
|
56
|
+
"type": "git",
|
|
57
|
+
"url": "https://github.com/Yish-AI/anastops.git",
|
|
58
|
+
"directory": "packages/cli"
|
|
59
|
+
},
|
|
60
|
+
"bugs": {
|
|
61
|
+
"url": "https://github.com/Yish-AI/anastops/issues"
|
|
62
|
+
},
|
|
63
|
+
"homepage": "https://github.com/Yish-AI/anastops#readme",
|
|
64
|
+
"license": "MIT",
|
|
65
|
+
"publishConfig": {
|
|
66
|
+
"access": "public"
|
|
67
|
+
}
|
|
68
|
+
}
|