@ai-setting/roy-agent-cli 1.0.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/README.md +126 -0
- package/dist/bin/roy.js +127297 -0
- package/dist/roy-agent-darwin-arm64/bin/roy.js +127297 -0
- package/dist/roy-agent-darwin-x64/bin/roy.js +127297 -0
- package/dist/roy-agent-linux-arm64/bin/roy.js +127297 -0
- package/dist/roy-agent-linux-x64/bin/roy.js +127297 -0
- package/dist/roy-agent-windows-x64/bin/roy.js +127297 -0
- package/package.json +91 -0
- package/src/bin/roy.ts +12 -0
- package/src/cli.ts +101 -0
- package/src/commands/act.ts +480 -0
- package/src/commands/commands-add.ts +110 -0
- package/src/commands/commands-dirs.ts +70 -0
- package/src/commands/commands-info.ts +90 -0
- package/src/commands/commands-list.ts +161 -0
- package/src/commands/commands-remove.ts +147 -0
- package/src/commands/commands.ts +55 -0
- package/src/commands/config/config-service.test.ts +449 -0
- package/src/commands/config/config-service.ts +312 -0
- package/src/commands/config/deep-merge.test.ts +168 -0
- package/src/commands/config/deep-merge.ts +63 -0
- package/src/commands/config/export.ts +97 -0
- package/src/commands/config/filter-history-e2e.test.ts +141 -0
- package/src/commands/config/import-preserve-refs.test.ts +212 -0
- package/src/commands/config/import.ts +119 -0
- package/src/commands/config/index.ts +35 -0
- package/src/commands/config/list.ts +281 -0
- package/src/commands/config/roy-config-e2e.test.ts +297 -0
- package/src/commands/config/types.ts +54 -0
- package/src/commands/debug/index.ts +38 -0
- package/src/commands/debug/log.test.ts +233 -0
- package/src/commands/debug/log.ts +123 -0
- package/src/commands/debug/span.test.ts +297 -0
- package/src/commands/debug/span.ts +211 -0
- package/src/commands/debug/trace.test.ts +254 -0
- package/src/commands/debug/trace.ts +140 -0
- package/src/commands/eventsource/add.ts +133 -0
- package/src/commands/eventsource/index.ts +48 -0
- package/src/commands/eventsource/list.ts +194 -0
- package/src/commands/eventsource/remove.ts +95 -0
- package/src/commands/eventsource/start.ts +103 -0
- package/src/commands/eventsource/status.ts +185 -0
- package/src/commands/eventsource/stop.ts +89 -0
- package/src/commands/index.ts +22 -0
- package/src/commands/input-handler.test.ts +76 -0
- package/src/commands/input-handler.ts +43 -0
- package/src/commands/interactive-esc.test.ts +254 -0
- package/src/commands/interactive.shutdown.test.ts +122 -0
- package/src/commands/interactive.test.ts +221 -0
- package/src/commands/interactive.ts +1015 -0
- package/src/commands/lsp/check.ts +92 -0
- package/src/commands/lsp/index.ts +32 -0
- package/src/commands/lsp/install.ts +126 -0
- package/src/commands/lsp/list.ts +64 -0
- package/src/commands/mcp/index.ts +27 -0
- package/src/commands/mcp/list.ts +116 -0
- package/src/commands/mcp/reload.ts +70 -0
- package/src/commands/mcp/tools.ts +121 -0
- package/src/commands/memory/extract-e2e.test.ts +388 -0
- package/src/commands/memory/index.ts +11 -0
- package/src/commands/memory/memory-simplified.test.ts +58 -0
- package/src/commands/memory/memory.ts +25 -0
- package/src/commands/memory/organize.ts +300 -0
- package/src/commands/memory/recall.test.ts +120 -0
- package/src/commands/memory/recall.ts +88 -0
- package/src/commands/memory/record-extract-handle-query.test.ts +385 -0
- package/src/commands/memory/record-prompt-component.test.ts +343 -0
- package/src/commands/memory/record.test.ts +92 -0
- package/src/commands/memory/record.ts +332 -0
- package/src/commands/plugin.test.ts +292 -0
- package/src/commands/plugin.ts +267 -0
- package/src/commands/sessions/active.ts +96 -0
- package/src/commands/sessions/add-message.ts +96 -0
- package/src/commands/sessions/checkpoints.ts +154 -0
- package/src/commands/sessions/compact.test.ts +215 -0
- package/src/commands/sessions/compact.ts +269 -0
- package/src/commands/sessions/delete.ts +236 -0
- package/src/commands/sessions/get.ts +165 -0
- package/src/commands/sessions/grep.ts +233 -0
- package/src/commands/sessions/index.ts +95 -0
- package/src/commands/sessions/list.ts +210 -0
- package/src/commands/sessions/messages.test.ts +333 -0
- package/src/commands/sessions/messages.ts +248 -0
- package/src/commands/sessions/mock.ts +194 -0
- package/src/commands/sessions/new.ts +82 -0
- package/src/commands/sessions/rename.ts +98 -0
- package/src/commands/shared/event-handler.ts +213 -0
- package/src/commands/shared/event-message-formatter.ts +295 -0
- package/src/commands/shared/index.ts +11 -0
- package/src/commands/shared/query-executor.test.ts +434 -0
- package/src/commands/shared/query-executor.ts +324 -0
- package/src/commands/shared/repl-engine.test.ts +354 -0
- package/src/commands/shared/session-manager.test.ts +212 -0
- package/src/commands/shared/session-manager.ts +114 -0
- package/src/commands/skills/get.ts +90 -0
- package/src/commands/skills/index.ts +39 -0
- package/src/commands/skills/list.ts +129 -0
- package/src/commands/skills/reload.ts +59 -0
- package/src/commands/skills/search.ts +132 -0
- package/src/commands/skills/show-config.ts +93 -0
- package/src/commands/tasks/complete.ts +92 -0
- package/src/commands/tasks/create.ts +118 -0
- package/src/commands/tasks/delete.ts +86 -0
- package/src/commands/tasks/get.ts +116 -0
- package/src/commands/tasks/index.ts +53 -0
- package/src/commands/tasks/list.ts +140 -0
- package/src/commands/tasks/operations.ts +120 -0
- package/src/commands/tasks/update.ts +122 -0
- package/src/commands/tools/exec-tool.ts +128 -0
- package/src/commands/tools/get.ts +114 -0
- package/src/commands/tools/index.ts +35 -0
- package/src/commands/tools/list.ts +107 -0
- package/src/commands/tools/shared/index.ts +7 -0
- package/src/commands/tools/shared/schema-helper.ts +111 -0
- package/src/commands/workflow/commands/add.ts +315 -0
- package/src/commands/workflow/commands/get.ts +193 -0
- package/src/commands/workflow/commands/list.ts +137 -0
- package/src/commands/workflow/commands/nodes.ts +528 -0
- package/src/commands/workflow/commands/remove.ts +94 -0
- package/src/commands/workflow/commands/run.ts +398 -0
- package/src/commands/workflow/commands/status.ts +147 -0
- package/src/commands/workflow/commands/stop.ts +91 -0
- package/src/commands/workflow/commands/update.ts +130 -0
- package/src/commands/workflow/commands/validate.ts +139 -0
- package/src/commands/workflow/commands/workflow-cli.test.ts +196 -0
- package/src/commands/workflow/index.ts +65 -0
- package/src/commands/workflow/renderers.ts +358 -0
- package/src/commands/workflow/validators/index.ts +8 -0
- package/src/commands/workflow/validators/node-validator-factory.ts +40 -0
- package/src/commands/workflow/validators/node-validator.ts +125 -0
- package/src/commands/workflow/validators/nodes/agent-node-validator.ts +58 -0
- package/src/commands/workflow/validators/nodes/condition-node-validator.ts +34 -0
- package/src/commands/workflow/validators/nodes/decorator-node-validator.ts +45 -0
- package/src/commands/workflow/validators/nodes/merge-node-validator.ts +46 -0
- package/src/commands/workflow/validators/nodes/skill-node-validator.ts +33 -0
- package/src/commands/workflow/validators/nodes/tool-node-validator.ts +54 -0
- package/src/commands/workflow/validators/nodes/workflow-node-validator.ts +33 -0
- package/src/commands/workflow/validators/types.ts +78 -0
- package/src/commands/workflow/validators/workflow-validator.test.ts +273 -0
- package/src/commands/workflow/validators/workflow-validator.ts +320 -0
- package/src/index.ts +19 -0
- package/src/plugin/apply.ts +103 -0
- package/src/plugin/discover.ts +219 -0
- package/src/plugin/index.ts +45 -0
- package/src/plugin/registry.ts +272 -0
- package/src/plugin/types.ts +165 -0
- package/src/services/context-handler.service.test.ts +501 -0
- package/src/services/context-handler.service.ts +372 -0
- package/src/services/environment.service.commands-prompt.test.ts +167 -0
- package/src/services/environment.service.ts +656 -0
- package/src/services/output.service.test.ts +92 -0
- package/src/services/output.service.ts +122 -0
- package/src/services/quiet-mode.service.test.ts +114 -0
- package/src/services/quiet-mode.service.ts +81 -0
- package/src/services/stream-output.service.test.ts +214 -0
- package/src/services/stream-output.service.ts +323 -0
- package/src/util/which.test.ts +101 -0
- package/src/util/which.ts +55 -0
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview LSP Check Command
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { CommandModule } from "yargs";
|
|
6
|
+
import { createInstaller, LSP_PACKAGES, LSPConfigLoader } from "@ai-setting/roy-agent-coder-harness";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* 创建 lsp check 命令
|
|
10
|
+
*/
|
|
11
|
+
export const LspCheckCommand: CommandModule = {
|
|
12
|
+
command: "check [server-id]",
|
|
13
|
+
describe: "Check LSP server status and configuration",
|
|
14
|
+
|
|
15
|
+
builder: (yargs) =>
|
|
16
|
+
yargs
|
|
17
|
+
.positional("server-id", {
|
|
18
|
+
describe: "Check specific server (e.g., typescript)",
|
|
19
|
+
type: "string",
|
|
20
|
+
})
|
|
21
|
+
.option("verbose", {
|
|
22
|
+
alias: "v",
|
|
23
|
+
type: "boolean",
|
|
24
|
+
default: false,
|
|
25
|
+
description: "Show detailed information",
|
|
26
|
+
})
|
|
27
|
+
.option("json", {
|
|
28
|
+
type: "boolean",
|
|
29
|
+
default: false,
|
|
30
|
+
description: "Output as JSON",
|
|
31
|
+
}),
|
|
32
|
+
|
|
33
|
+
handler: async (argv) => {
|
|
34
|
+
const installer = createInstaller();
|
|
35
|
+
const configLoader = new LSPConfigLoader();
|
|
36
|
+
const config = configLoader.load();
|
|
37
|
+
|
|
38
|
+
if (argv.json) {
|
|
39
|
+
const servers = argv.serverId
|
|
40
|
+
? LSP_PACKAGES.filter((p) => p.serverId === argv.serverId)
|
|
41
|
+
: LSP_PACKAGES;
|
|
42
|
+
|
|
43
|
+
const result = {
|
|
44
|
+
config: config.toJSON(),
|
|
45
|
+
servers: servers.map((pkg) => ({
|
|
46
|
+
serverId: pkg.serverId,
|
|
47
|
+
npmPackage: pkg.npmPackage,
|
|
48
|
+
description: pkg.description,
|
|
49
|
+
installed: installer.isInstalled(pkg.npmPackage),
|
|
50
|
+
verify: installer.verify(pkg.serverId),
|
|
51
|
+
})),
|
|
52
|
+
};
|
|
53
|
+
console.log(JSON.stringify(result, null, 2));
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
console.log("\n⚙️ LSP Configuration\n");
|
|
58
|
+
console.log(` Config Path: ${configLoader.getConfigPath()}`);
|
|
59
|
+
console.log(` Install Path: ${config.installPath}`);
|
|
60
|
+
console.log(` Preload: ${config.preload ? "enabled" : "disabled"}`);
|
|
61
|
+
console.log(` Idle Timeout: ${config.idleTimeout}ms`);
|
|
62
|
+
|
|
63
|
+
const servers = argv.serverId
|
|
64
|
+
? LSP_PACKAGES.filter((p) => p.serverId === argv.serverId)
|
|
65
|
+
: LSP_PACKAGES;
|
|
66
|
+
|
|
67
|
+
console.log("\n📦 LSP Servers Status\n");
|
|
68
|
+
|
|
69
|
+
let hasIssues = false;
|
|
70
|
+
for (const pkg of servers) {
|
|
71
|
+
const verify = installer.verify(pkg.serverId);
|
|
72
|
+
const installed = verify.installed ? "✓ Installed" : "✗ Not installed";
|
|
73
|
+
|
|
74
|
+
console.log(` ${pkg.serverId.padEnd(12)} ${pkg.description}`);
|
|
75
|
+
console.log(` ${installed}`);
|
|
76
|
+
console.log(` Package: ${pkg.npmPackage}`);
|
|
77
|
+
|
|
78
|
+
if (verify.binary) {
|
|
79
|
+
console.log(` Binary in PATH: ${verify.binary}`);
|
|
80
|
+
} else if (verify.installed) {
|
|
81
|
+
console.log(` Warning: Installed but not in PATH`);
|
|
82
|
+
hasIssues = true;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
console.log();
|
|
87
|
+
if (hasIssues) {
|
|
88
|
+
console.log("⚠️ Some servers are installed but not in PATH.");
|
|
89
|
+
console.log(" Run 'npm config get prefix' to check npm global path\n");
|
|
90
|
+
}
|
|
91
|
+
},
|
|
92
|
+
};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview LSP Command Group
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { CommandModule } from "yargs";
|
|
6
|
+
import { LspInstallCommand } from "./install";
|
|
7
|
+
import { LspListCommand } from "./list";
|
|
8
|
+
import { LspCheckCommand } from "./check";
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* LSP Command
|
|
12
|
+
*/
|
|
13
|
+
export const LspCommand: CommandModule = {
|
|
14
|
+
command: "lsp",
|
|
15
|
+
describe: "Manage LSP (Language Server Protocol) servers",
|
|
16
|
+
|
|
17
|
+
builder: (yargs) =>
|
|
18
|
+
yargs
|
|
19
|
+
.command(LspInstallCommand)
|
|
20
|
+
.command(LspListCommand)
|
|
21
|
+
.command(LspCheckCommand)
|
|
22
|
+
.demandCommand()
|
|
23
|
+
.help(),
|
|
24
|
+
|
|
25
|
+
handler: () => {
|
|
26
|
+
console.log("Use 'roy lsp --help' for usage information");
|
|
27
|
+
},
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
export { LspInstallCommand } from "./install";
|
|
31
|
+
export { LspListCommand } from "./list";
|
|
32
|
+
export { LspCheckCommand } from "./check";
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview LSP Install Command
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { CommandModule } from "yargs";
|
|
6
|
+
import { createInstaller, LSP_PACKAGES } from "@ai-setting/roy-agent-coder-harness";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* 创建 lsp install 命令
|
|
10
|
+
*/
|
|
11
|
+
export const LspInstallCommand: CommandModule = {
|
|
12
|
+
command: "install [languages...]",
|
|
13
|
+
describe: "Install LSP server dependencies",
|
|
14
|
+
|
|
15
|
+
builder: (yargs) =>
|
|
16
|
+
yargs
|
|
17
|
+
.positional("languages", {
|
|
18
|
+
describe: "Languages to install (e.g., typescript, python)",
|
|
19
|
+
type: "string",
|
|
20
|
+
})
|
|
21
|
+
.option("global", {
|
|
22
|
+
alias: "g",
|
|
23
|
+
type: "boolean",
|
|
24
|
+
default: true,
|
|
25
|
+
description: "Install globally",
|
|
26
|
+
})
|
|
27
|
+
.option("local", {
|
|
28
|
+
alias: "l",
|
|
29
|
+
type: "string",
|
|
30
|
+
description: "Install to local path",
|
|
31
|
+
})
|
|
32
|
+
.option("all", {
|
|
33
|
+
alias: "a",
|
|
34
|
+
type: "boolean",
|
|
35
|
+
default: false,
|
|
36
|
+
description: "Install all available LSP servers",
|
|
37
|
+
})
|
|
38
|
+
.option("check", {
|
|
39
|
+
type: "boolean",
|
|
40
|
+
default: false,
|
|
41
|
+
description: "Only check if installed, don't install",
|
|
42
|
+
})
|
|
43
|
+
.option("verbose", {
|
|
44
|
+
alias: "v",
|
|
45
|
+
type: "boolean",
|
|
46
|
+
default: false,
|
|
47
|
+
description: "Verbose output",
|
|
48
|
+
}),
|
|
49
|
+
|
|
50
|
+
handler: async (argv) => {
|
|
51
|
+
const installer = createInstaller({
|
|
52
|
+
target: argv.local ? "local" : "global",
|
|
53
|
+
installPath: argv.local as string,
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
const languages = argv.languages as string[] | undefined;
|
|
57
|
+
|
|
58
|
+
if (argv.check) {
|
|
59
|
+
// Check mode
|
|
60
|
+
const installed = installer.getInstalledPackages();
|
|
61
|
+
const missing = installer.getMissingDependencies();
|
|
62
|
+
|
|
63
|
+
console.log("\n📦 LSP Server Status\n");
|
|
64
|
+
|
|
65
|
+
for (const pkg of LSP_PACKAGES) {
|
|
66
|
+
const isInstalled = installed.includes(pkg.serverId);
|
|
67
|
+
const status = isInstalled ? "✓ installed" : "✗ not installed";
|
|
68
|
+
console.log(` ${status.padEnd(20)} ${pkg.serverId.padEnd(12)} ${pkg.description}`);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
console.log(`\n${installed.length}/${LSP_PACKAGES.length} installed\n`);
|
|
72
|
+
|
|
73
|
+
if (missing.length > 0) {
|
|
74
|
+
console.log("Run 'roy lsp install' to install missing servers\n");
|
|
75
|
+
}
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
if (languages && languages.length > 0) {
|
|
80
|
+
// Install specific languages
|
|
81
|
+
const success: string[] = [];
|
|
82
|
+
const failed: string[] = [];
|
|
83
|
+
|
|
84
|
+
for (const lang of languages) {
|
|
85
|
+
const langLower = lang.toLowerCase();
|
|
86
|
+
if (installer.install(langLower, { verbose: !!argv.verbose })) {
|
|
87
|
+
success.push(langLower);
|
|
88
|
+
} else {
|
|
89
|
+
failed.push(langLower);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
console.log(`\n📦 Installation Summary\n`);
|
|
94
|
+
if (success.length > 0) {
|
|
95
|
+
console.log(` ✓ Installed: ${success.join(", ")}`);
|
|
96
|
+
}
|
|
97
|
+
if (failed.length > 0) {
|
|
98
|
+
console.log(` ✗ Failed: ${failed.join(", ")}`);
|
|
99
|
+
}
|
|
100
|
+
console.log();
|
|
101
|
+
} else if (argv.all) {
|
|
102
|
+
// Install all
|
|
103
|
+
console.log("\n📦 Installing all LSP servers...\n");
|
|
104
|
+
const result = installer.installAll({ verbose: !!argv.verbose });
|
|
105
|
+
|
|
106
|
+
console.log(`\n📦 Installation Summary\n`);
|
|
107
|
+
if (result.success.length > 0) {
|
|
108
|
+
console.log(` ✓ Installed: ${result.success.join(", ")}`);
|
|
109
|
+
}
|
|
110
|
+
if (result.failed.length > 0) {
|
|
111
|
+
console.log(` ✗ Failed: ${result.failed.join(", ")}`);
|
|
112
|
+
}
|
|
113
|
+
console.log();
|
|
114
|
+
} else {
|
|
115
|
+
// Show available
|
|
116
|
+
console.log("\n📦 Available LSP Servers\n");
|
|
117
|
+
for (const pkg of LSP_PACKAGES) {
|
|
118
|
+
const isInstalled = installer.isInstalled(pkg.npmPackage);
|
|
119
|
+
const status = isInstalled ? "✓" : "○";
|
|
120
|
+
console.log(` ${status} ${pkg.serverId.padEnd(12)} ${pkg.description}`);
|
|
121
|
+
}
|
|
122
|
+
console.log("\n Run 'roy lsp install <language>' to install specific servers");
|
|
123
|
+
console.log(" Run 'roy lsp install --all' to install all servers\n");
|
|
124
|
+
}
|
|
125
|
+
},
|
|
126
|
+
};
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview LSP List Command
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { CommandModule } from "yargs";
|
|
6
|
+
import { createInstaller, LSP_PACKAGES } from "@ai-setting/roy-agent-coder-harness";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* 创建 lsp list 命令
|
|
10
|
+
*/
|
|
11
|
+
export const LspListCommand: CommandModule = {
|
|
12
|
+
command: "list",
|
|
13
|
+
describe: "List installed LSP servers",
|
|
14
|
+
|
|
15
|
+
builder: (yargs) =>
|
|
16
|
+
yargs
|
|
17
|
+
.option("verbose", {
|
|
18
|
+
alias: "v",
|
|
19
|
+
type: "boolean",
|
|
20
|
+
default: false,
|
|
21
|
+
description: "Show detailed information",
|
|
22
|
+
})
|
|
23
|
+
.option("json", {
|
|
24
|
+
type: "boolean",
|
|
25
|
+
default: false,
|
|
26
|
+
description: "Output as JSON",
|
|
27
|
+
}),
|
|
28
|
+
|
|
29
|
+
handler: async (argv) => {
|
|
30
|
+
const installer = createInstaller();
|
|
31
|
+
const installed = installer.getInstalledPackages();
|
|
32
|
+
|
|
33
|
+
if (argv.json) {
|
|
34
|
+
const result = LSP_PACKAGES.map((pkg) => ({
|
|
35
|
+
serverId: pkg.serverId,
|
|
36
|
+
npmPackage: pkg.npmPackage,
|
|
37
|
+
description: pkg.description,
|
|
38
|
+
installed: installed.includes(pkg.serverId),
|
|
39
|
+
}));
|
|
40
|
+
console.log(JSON.stringify(result, null, 2));
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
console.log("\n📦 LSP Servers\n");
|
|
45
|
+
|
|
46
|
+
for (const pkg of LSP_PACKAGES) {
|
|
47
|
+
const isInstalled = installed.includes(pkg.serverId);
|
|
48
|
+
const status = isInstalled ? "✓" : "○";
|
|
49
|
+
const installedText = isInstalled ? "installed" : "not installed";
|
|
50
|
+
|
|
51
|
+
console.log(` ${status} ${pkg.serverId.padEnd(12)} ${pkg.description}`);
|
|
52
|
+
console.log(` ${pkg.npmPackage} - ${installedText}`);
|
|
53
|
+
|
|
54
|
+
if (argv.verbose && isInstalled) {
|
|
55
|
+
const verify = installer.verify(pkg.serverId);
|
|
56
|
+
if (verify.binary) {
|
|
57
|
+
console.log(` Binary: ${verify.binary}`);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
console.log(`\n${installed.length}/${LSP_PACKAGES.length} installed\n`);
|
|
63
|
+
},
|
|
64
|
+
};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview MCP Commands
|
|
3
|
+
*
|
|
4
|
+
* 命令组:roy mcp
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { CommandModule } from "yargs";
|
|
8
|
+
import { ListCommand } from "./list";
|
|
9
|
+
import { ToolsCommand } from "./tools";
|
|
10
|
+
import { ReloadCommand } from "./reload";
|
|
11
|
+
|
|
12
|
+
export const McpCommand: CommandModule<object, {}> = {
|
|
13
|
+
command: "mcp",
|
|
14
|
+
describe: "MCP 服务器管理",
|
|
15
|
+
builder: (yargs) =>
|
|
16
|
+
yargs
|
|
17
|
+
.command(ListCommand)
|
|
18
|
+
.command(ToolsCommand)
|
|
19
|
+
.command(ReloadCommand)
|
|
20
|
+
.demandCommand(1, "请指定一个子命令")
|
|
21
|
+
.help(),
|
|
22
|
+
handler: () => {}, // Required but never called since subcommands handle themselves
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export { ListCommand } from "./list";
|
|
26
|
+
export { ToolsCommand } from "./tools";
|
|
27
|
+
export { ReloadCommand } from "./reload";
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview MCP List Command
|
|
3
|
+
*
|
|
4
|
+
* 命令:roy mcp list
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { CommandModule } from "yargs";
|
|
8
|
+
import { EnvironmentService } from "../../services/environment.service";
|
|
9
|
+
import { OutputService } from "../../services/output.service";
|
|
10
|
+
import chalk from "chalk";
|
|
11
|
+
import type { McpComponent } from "@ai-setting/roy-agent-core";
|
|
12
|
+
|
|
13
|
+
interface ListOptions {
|
|
14
|
+
json?: boolean;
|
|
15
|
+
quiet?: boolean;
|
|
16
|
+
config?: string;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export const ListCommand: CommandModule<object, ListOptions> = {
|
|
20
|
+
command: "list",
|
|
21
|
+
aliases: ["ls"],
|
|
22
|
+
describe: "列出所有 MCP 服务器及其状态",
|
|
23
|
+
|
|
24
|
+
builder: (yargs) =>
|
|
25
|
+
yargs
|
|
26
|
+
.option("json", {
|
|
27
|
+
alias: "j",
|
|
28
|
+
type: "boolean",
|
|
29
|
+
default: false,
|
|
30
|
+
description: "JSON 输出",
|
|
31
|
+
})
|
|
32
|
+
.option("quiet", {
|
|
33
|
+
alias: "q",
|
|
34
|
+
type: "boolean",
|
|
35
|
+
default: false,
|
|
36
|
+
description: "简洁输出",
|
|
37
|
+
}),
|
|
38
|
+
|
|
39
|
+
async handler(args) {
|
|
40
|
+
const output = new OutputService();
|
|
41
|
+
const envService = new EnvironmentService(output);
|
|
42
|
+
|
|
43
|
+
try {
|
|
44
|
+
await envService.create({ configPath: args.config });
|
|
45
|
+
const env = envService.getEnvironment();
|
|
46
|
+
if (!env) {
|
|
47
|
+
output.error("Failed to create environment");
|
|
48
|
+
process.exit(1);
|
|
49
|
+
}
|
|
50
|
+
const mcpComponent = env.getComponent("mcp") as McpComponent | undefined;
|
|
51
|
+
|
|
52
|
+
if (!mcpComponent) {
|
|
53
|
+
output.error("McpComponent not available");
|
|
54
|
+
process.exit(1);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const servers = mcpComponent.listServers();
|
|
58
|
+
|
|
59
|
+
if (args.json) {
|
|
60
|
+
output.json({
|
|
61
|
+
servers: servers.map(s => ({
|
|
62
|
+
name: s.name,
|
|
63
|
+
status: s.status,
|
|
64
|
+
error: s.error,
|
|
65
|
+
toolsCount: s.toolsCount,
|
|
66
|
+
})),
|
|
67
|
+
count: servers.length,
|
|
68
|
+
});
|
|
69
|
+
} else if (args.quiet) {
|
|
70
|
+
servers.forEach(s => output.log(s.name));
|
|
71
|
+
} else {
|
|
72
|
+
if (servers.length === 0) {
|
|
73
|
+
output.log(chalk.yellow("No MCP servers configured"));
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
const statusColor = (status: string) => {
|
|
78
|
+
switch (status) {
|
|
79
|
+
case "connected": return chalk.green;
|
|
80
|
+
case "connecting": return chalk.yellow;
|
|
81
|
+
case "error": return chalk.red;
|
|
82
|
+
case "disconnected": return chalk.gray;
|
|
83
|
+
default: return chalk.white;
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
const header = [
|
|
88
|
+
chalk.bold("Name"),
|
|
89
|
+
chalk.bold("Status"),
|
|
90
|
+
chalk.bold("Tools"),
|
|
91
|
+
].join(" | ");
|
|
92
|
+
|
|
93
|
+
const rows = servers.map(s => [
|
|
94
|
+
chalk.cyan(s.name),
|
|
95
|
+
statusColor(s.status)(`[${s.status}]`),
|
|
96
|
+
s.toolsCount !== undefined ? String(s.toolsCount) : "-",
|
|
97
|
+
].join(" | "));
|
|
98
|
+
|
|
99
|
+
output.log([
|
|
100
|
+
`┌─ MCP Servers ${"─".repeat(40)}┐`,
|
|
101
|
+
`│${header}│`,
|
|
102
|
+
"├" + "─".repeat(header.length + 2) + "┤",
|
|
103
|
+
...rows.map(r => `│${r}│`),
|
|
104
|
+
"└" + "─".repeat(header.length + 2) + "┘",
|
|
105
|
+
"",
|
|
106
|
+
chalk.gray(`Total: ${servers.length} servers`),
|
|
107
|
+
].join("\n"));
|
|
108
|
+
}
|
|
109
|
+
} catch (error) {
|
|
110
|
+
output.error(`Failed to list MCP servers: ${error}`);
|
|
111
|
+
process.exit(1);
|
|
112
|
+
} finally {
|
|
113
|
+
await envService.dispose();
|
|
114
|
+
}
|
|
115
|
+
},
|
|
116
|
+
};
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview MCP Reload Command
|
|
3
|
+
*
|
|
4
|
+
* 命令:roy mcp reload
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { CommandModule } from "yargs";
|
|
8
|
+
import { EnvironmentService } from "../../services/environment.service";
|
|
9
|
+
import { OutputService } from "../../services/output.service";
|
|
10
|
+
import chalk from "chalk";
|
|
11
|
+
import type { McpComponent } from "@ai-setting/roy-agent-core";
|
|
12
|
+
|
|
13
|
+
interface ReloadOptions {
|
|
14
|
+
config?: string;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export const ReloadCommand: CommandModule<object, ReloadOptions> = {
|
|
18
|
+
command: "reload",
|
|
19
|
+
aliases: ["r"],
|
|
20
|
+
describe: "重新加载 MCP 服务器",
|
|
21
|
+
|
|
22
|
+
builder: (yargs) =>
|
|
23
|
+
yargs,
|
|
24
|
+
|
|
25
|
+
async handler(args) {
|
|
26
|
+
const output = new OutputService();
|
|
27
|
+
const envService = new EnvironmentService(output);
|
|
28
|
+
|
|
29
|
+
try {
|
|
30
|
+
await envService.create({ configPath: args.config });
|
|
31
|
+
const env = envService.getEnvironment();
|
|
32
|
+
if (!env) {
|
|
33
|
+
output.error("Failed to create environment");
|
|
34
|
+
process.exit(1);
|
|
35
|
+
}
|
|
36
|
+
const mcpComponent = env.getComponent("mcp") as McpComponent | undefined;
|
|
37
|
+
|
|
38
|
+
if (!mcpComponent) {
|
|
39
|
+
output.error("McpComponent not available");
|
|
40
|
+
process.exit(1);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
output.log(chalk.cyan("Reloading MCP servers..."));
|
|
44
|
+
|
|
45
|
+
await mcpComponent.reload();
|
|
46
|
+
|
|
47
|
+
const servers = mcpComponent.listServers();
|
|
48
|
+
const connected = servers.filter(s => s.status === "connected").length;
|
|
49
|
+
const errors = servers.filter(s => s.status === "error").length;
|
|
50
|
+
|
|
51
|
+
output.log(chalk.green(`✓ Reloaded ${servers.length} servers`));
|
|
52
|
+
|
|
53
|
+
if (connected > 0) {
|
|
54
|
+
output.log(chalk.green(` • ${connected} connected`));
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
if (errors > 0) {
|
|
58
|
+
output.warn(` • ${errors} failed`);
|
|
59
|
+
for (const server of servers.filter(s => s.status === "error")) {
|
|
60
|
+
output.log(chalk.gray(` - ${server.name}: ${server.error}`));
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
} catch (error) {
|
|
64
|
+
output.error(`Failed to reload MCP servers: ${error}`);
|
|
65
|
+
process.exit(1);
|
|
66
|
+
} finally {
|
|
67
|
+
await envService.dispose();
|
|
68
|
+
}
|
|
69
|
+
},
|
|
70
|
+
};
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview MCP Tools Command
|
|
3
|
+
*
|
|
4
|
+
* 命令:roy mcp tools
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { CommandModule } from "yargs";
|
|
8
|
+
import { EnvironmentService } from "../../services/environment.service";
|
|
9
|
+
import { OutputService } from "../../services/output.service";
|
|
10
|
+
import chalk from "chalk";
|
|
11
|
+
import type { McpComponent } from "@ai-setting/roy-agent-core";
|
|
12
|
+
|
|
13
|
+
interface ToolsOptions {
|
|
14
|
+
server?: string;
|
|
15
|
+
json?: boolean;
|
|
16
|
+
quiet?: boolean;
|
|
17
|
+
config?: string;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export const ToolsCommand: CommandModule<object, ToolsOptions> = {
|
|
21
|
+
command: "tools",
|
|
22
|
+
aliases: ["t"],
|
|
23
|
+
describe: "列出所有 MCP 工具",
|
|
24
|
+
|
|
25
|
+
builder: (yargs) =>
|
|
26
|
+
yargs
|
|
27
|
+
.option("server", {
|
|
28
|
+
alias: "s",
|
|
29
|
+
type: "string",
|
|
30
|
+
description: "按服务器筛选",
|
|
31
|
+
})
|
|
32
|
+
.option("json", {
|
|
33
|
+
alias: "j",
|
|
34
|
+
type: "boolean",
|
|
35
|
+
default: false,
|
|
36
|
+
description: "JSON 输出",
|
|
37
|
+
})
|
|
38
|
+
.option("quiet", {
|
|
39
|
+
alias: "q",
|
|
40
|
+
type: "boolean",
|
|
41
|
+
default: false,
|
|
42
|
+
description: "简洁输出",
|
|
43
|
+
}),
|
|
44
|
+
|
|
45
|
+
async handler(args) {
|
|
46
|
+
const output = new OutputService();
|
|
47
|
+
const envService = new EnvironmentService(output);
|
|
48
|
+
|
|
49
|
+
try {
|
|
50
|
+
await envService.create({ configPath: args.config });
|
|
51
|
+
const env = envService.getEnvironment();
|
|
52
|
+
if (!env) {
|
|
53
|
+
output.error("Failed to create environment");
|
|
54
|
+
process.exit(1);
|
|
55
|
+
}
|
|
56
|
+
const mcpComponent = env.getComponent("mcp") as McpComponent | undefined;
|
|
57
|
+
|
|
58
|
+
if (!mcpComponent) {
|
|
59
|
+
output.error("McpComponent not available");
|
|
60
|
+
process.exit(1);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
let tools = mcpComponent.listTools();
|
|
64
|
+
|
|
65
|
+
// 按服务器筛选
|
|
66
|
+
if (args.server) {
|
|
67
|
+
tools = tools.filter(t =>
|
|
68
|
+
t.metadata?.tags?.includes(args.server!)
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
if (args.json) {
|
|
73
|
+
output.json({
|
|
74
|
+
tools: tools.map(t => ({
|
|
75
|
+
name: t.name,
|
|
76
|
+
description: t.description,
|
|
77
|
+
category: t.metadata?.category,
|
|
78
|
+
tags: t.metadata?.tags,
|
|
79
|
+
})),
|
|
80
|
+
count: tools.length,
|
|
81
|
+
});
|
|
82
|
+
} else if (args.quiet) {
|
|
83
|
+
tools.forEach(t => output.log(t.name));
|
|
84
|
+
} else {
|
|
85
|
+
if (tools.length === 0) {
|
|
86
|
+
output.log(chalk.yellow("No MCP tools available"));
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// 按服务器分组
|
|
91
|
+
const byServer = new Map<string, typeof tools>();
|
|
92
|
+
for (const tool of tools) {
|
|
93
|
+
const serverName = tool.metadata?.tags?.find(t => t !== "mcp") || "unknown";
|
|
94
|
+
if (!byServer.has(serverName)) {
|
|
95
|
+
byServer.set(serverName, []);
|
|
96
|
+
}
|
|
97
|
+
byServer.get(serverName)!.push(tool);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
for (const [serverName, serverTools] of byServer) {
|
|
101
|
+
output.log(chalk.bold.cyan(`\n[${serverName}] ${serverTools.length} tools`));
|
|
102
|
+
|
|
103
|
+
for (const tool of serverTools) {
|
|
104
|
+
const desc = tool.description.length > 80
|
|
105
|
+
? tool.description.slice(0, 77) + "..."
|
|
106
|
+
: tool.description;
|
|
107
|
+
output.log(` ${chalk.green("+")} ${chalk.white(tool.name)}`);
|
|
108
|
+
output.log(` ${chalk.gray(desc)}`);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
output.log(chalk.gray(`\nTotal: ${tools.length} tools across ${byServer.size} servers`));
|
|
113
|
+
}
|
|
114
|
+
} catch (error) {
|
|
115
|
+
output.error(`Failed to list MCP tools: ${error}`);
|
|
116
|
+
process.exit(1);
|
|
117
|
+
} finally {
|
|
118
|
+
await envService.dispose();
|
|
119
|
+
}
|
|
120
|
+
},
|
|
121
|
+
};
|