@xagent-ai/cli 1.3.6 → 1.4.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 +9 -0
- package/README_CN.md +9 -0
- package/dist/cli.js +26 -0
- package/dist/cli.js.map +1 -1
- package/dist/mcp.d.ts +8 -1
- package/dist/mcp.d.ts.map +1 -1
- package/dist/mcp.js +53 -20
- package/dist/mcp.js.map +1 -1
- package/dist/sdk-output-adapter.d.ts +79 -0
- package/dist/sdk-output-adapter.d.ts.map +1 -1
- package/dist/sdk-output-adapter.js +118 -0
- package/dist/sdk-output-adapter.js.map +1 -1
- package/dist/session.d.ts +88 -1
- package/dist/session.d.ts.map +1 -1
- package/dist/session.js +351 -5
- package/dist/session.js.map +1 -1
- package/dist/slash-commands.d.ts.map +1 -1
- package/dist/slash-commands.js +3 -5
- package/dist/slash-commands.js.map +1 -1
- package/dist/smart-approval.d.ts.map +1 -1
- package/dist/smart-approval.js +1 -0
- package/dist/smart-approval.js.map +1 -1
- package/dist/system-prompt-generator.d.ts +15 -1
- package/dist/system-prompt-generator.d.ts.map +1 -1
- package/dist/system-prompt-generator.js +36 -27
- package/dist/system-prompt-generator.js.map +1 -1
- package/dist/team-manager/index.d.ts +6 -0
- package/dist/team-manager/index.d.ts.map +1 -0
- package/dist/team-manager/index.js +6 -0
- package/dist/team-manager/index.js.map +1 -0
- package/dist/team-manager/message-broker.d.ts +128 -0
- package/dist/team-manager/message-broker.d.ts.map +1 -0
- package/dist/team-manager/message-broker.js +638 -0
- package/dist/team-manager/message-broker.js.map +1 -0
- package/dist/team-manager/team-coordinator.d.ts +45 -0
- package/dist/team-manager/team-coordinator.d.ts.map +1 -0
- package/dist/team-manager/team-coordinator.js +887 -0
- package/dist/team-manager/team-coordinator.js.map +1 -0
- package/dist/team-manager/team-store.d.ts +49 -0
- package/dist/team-manager/team-store.d.ts.map +1 -0
- package/dist/team-manager/team-store.js +436 -0
- package/dist/team-manager/team-store.js.map +1 -0
- package/dist/team-manager/teammate-spawner.d.ts +86 -0
- package/dist/team-manager/teammate-spawner.d.ts.map +1 -0
- package/dist/team-manager/teammate-spawner.js +605 -0
- package/dist/team-manager/teammate-spawner.js.map +1 -0
- package/dist/team-manager/types.d.ts +164 -0
- package/dist/team-manager/types.d.ts.map +1 -0
- package/dist/team-manager/types.js +27 -0
- package/dist/team-manager/types.js.map +1 -0
- package/dist/tools.d.ts +41 -1
- package/dist/tools.d.ts.map +1 -1
- package/dist/tools.js +288 -32
- package/dist/tools.js.map +1 -1
- package/package.json +1 -1
- package/src/cli.ts +20 -0
- package/src/mcp.ts +64 -25
- package/src/sdk-output-adapter.ts +177 -0
- package/src/session.ts +423 -15
- package/src/slash-commands.ts +3 -7
- package/src/smart-approval.ts +1 -0
- package/src/system-prompt-generator.ts +59 -26
- package/src/team-manager/index.ts +5 -0
- package/src/team-manager/message-broker.ts +751 -0
- package/src/team-manager/team-coordinator.ts +1117 -0
- package/src/team-manager/team-store.ts +558 -0
- package/src/team-manager/teammate-spawner.ts +800 -0
- package/src/team-manager/types.ts +206 -0
- package/src/tools.ts +316 -33
package/src/mcp.ts
CHANGED
|
@@ -16,6 +16,11 @@ export class MCPServer {
|
|
|
16
16
|
private tools: Map<string, MCPTool> = new Map();
|
|
17
17
|
private isConnected: boolean = false;
|
|
18
18
|
private sessionId: string | null = null; // Save MCP session-id
|
|
19
|
+
private hasLoggedParseWarning: boolean = false; // Whether parse failure warning has been logged
|
|
20
|
+
private connectionAttempted: boolean = false; // Whether connection has been attempted
|
|
21
|
+
private toolsCheckInterval: NodeJS.Timeout | null = null; // Timer ID for tools check
|
|
22
|
+
private toolsCheckStartTime: number = 0; // Start time of tools check
|
|
23
|
+
private pendingToolsPromise: Promise<boolean> | null = null; // Pending promise for tools check
|
|
19
24
|
|
|
20
25
|
constructor(config: MCPServerConfig) {
|
|
21
26
|
this.config = config;
|
|
@@ -30,10 +35,18 @@ export class MCPServer {
|
|
|
30
35
|
}
|
|
31
36
|
|
|
32
37
|
async connect(): Promise<void> {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
38
|
+
// If already connected, return early
|
|
39
|
+
if (this.isConnected) {
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// If connection attempt is in progress (waitForTools not completed), don't start another
|
|
44
|
+
if (this.connectionAttempted) {
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// Mark as connection attempt started
|
|
49
|
+
this.connectionAttempted = true;
|
|
37
50
|
const transportType = this.getTransportType();
|
|
38
51
|
|
|
39
52
|
try {
|
|
@@ -44,14 +57,22 @@ export class MCPServer {
|
|
|
44
57
|
}
|
|
45
58
|
|
|
46
59
|
// Wait for tools to be loaded (max 10 seconds)
|
|
47
|
-
await this.waitForTools(10000);
|
|
48
|
-
|
|
49
|
-
this.isConnected = true;
|
|
60
|
+
const toolsLoaded = await this.waitForTools(10000);
|
|
50
61
|
const session = getSingletonSession();
|
|
51
|
-
|
|
52
|
-
|
|
62
|
+
const isSdkMode = session?.getIsSdkMode();
|
|
63
|
+
const serverInfo = this.config.command || this.config.url || 'unknown';
|
|
64
|
+
|
|
65
|
+
if (toolsLoaded) {
|
|
66
|
+
this.isConnected = true;
|
|
67
|
+
if (!isSdkMode) {
|
|
68
|
+
await logOutput('success', `MCP Server connected`);
|
|
69
|
+
}
|
|
53
70
|
} else {
|
|
54
|
-
|
|
71
|
+
// Disconnect after timeout
|
|
72
|
+
this.disconnect();
|
|
73
|
+
if (!isSdkMode) {
|
|
74
|
+
await logOutput('warning', `[MCP] Server '${serverInfo}' timed out, skipping`);
|
|
75
|
+
}
|
|
55
76
|
}
|
|
56
77
|
} catch (error) {
|
|
57
78
|
await logOutput('error', `[mcp] Failed to connect MCP Server`, { error: error instanceof Error ? error.message : String(error) });
|
|
@@ -62,32 +83,48 @@ export class MCPServer {
|
|
|
62
83
|
/**
|
|
63
84
|
* Wait for tools to be loaded from MCP server
|
|
64
85
|
* @param timeoutMs Maximum time to wait in milliseconds
|
|
86
|
+
* @returns Promise<boolean> - true if tools loaded, false if timeout
|
|
65
87
|
*/
|
|
66
|
-
async waitForTools(timeoutMs: number = 10000): Promise<
|
|
88
|
+
async waitForTools(timeoutMs: number = 10000): Promise<boolean> {
|
|
67
89
|
if (this.tools.size > 0) {
|
|
68
|
-
return;
|
|
90
|
+
return true;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// If there's already a pending Promise, reuse the previous startTime
|
|
94
|
+
if (this.pendingToolsPromise) {
|
|
95
|
+
return this.pendingToolsPromise;
|
|
69
96
|
}
|
|
70
97
|
|
|
71
|
-
|
|
98
|
+
this.toolsCheckStartTime = Date.now();
|
|
99
|
+
|
|
100
|
+
this.pendingToolsPromise = new Promise((resolve) => {
|
|
72
101
|
const checkInterval = 100;
|
|
73
|
-
const startTime = Date.now();
|
|
74
102
|
|
|
75
103
|
const check = () => {
|
|
76
104
|
if (this.tools.size > 0) {
|
|
77
|
-
|
|
78
|
-
resolve();
|
|
79
|
-
} else if (Date.now() -
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
// Continue checking
|
|
105
|
+
this.cleanupToolsCheck();
|
|
106
|
+
resolve(true);
|
|
107
|
+
} else if (Date.now() - this.toolsCheckStartTime > timeoutMs) {
|
|
108
|
+
this.cleanupToolsCheck();
|
|
109
|
+
const serverInfo = this.config.command || this.config.url || 'unknown';
|
|
110
|
+
logOutput('warning', `[MCP] Server '${serverInfo}' timed out(${timeoutMs}ms), skipping`);
|
|
111
|
+
resolve(false);
|
|
85
112
|
}
|
|
86
113
|
};
|
|
87
114
|
|
|
88
|
-
|
|
89
|
-
check();
|
|
115
|
+
this.toolsCheckInterval = setInterval(check, checkInterval);
|
|
116
|
+
check();
|
|
90
117
|
});
|
|
118
|
+
|
|
119
|
+
return this.pendingToolsPromise;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
private cleanupToolsCheck(): void {
|
|
123
|
+
if (this.toolsCheckInterval) {
|
|
124
|
+
clearInterval(this.toolsCheckInterval);
|
|
125
|
+
this.toolsCheckInterval = null;
|
|
126
|
+
}
|
|
127
|
+
this.pendingToolsPromise = null;
|
|
91
128
|
}
|
|
92
129
|
|
|
93
130
|
private async connectStdio(): Promise<void> {
|
|
@@ -341,7 +378,7 @@ export class MCPServer {
|
|
|
341
378
|
}
|
|
342
379
|
const session = getSingletonSession();
|
|
343
380
|
if (session?.getIsSdkMode()) {
|
|
344
|
-
// SDK
|
|
381
|
+
// Skip output in SDK mode
|
|
345
382
|
} else {
|
|
346
383
|
console.log(`Loaded ${result.tools.length} tools from MCP Server`);
|
|
347
384
|
}
|
|
@@ -654,7 +691,9 @@ export class MCPServer {
|
|
|
654
691
|
this.process = null;
|
|
655
692
|
}
|
|
656
693
|
this.isConnected = false;
|
|
694
|
+
this.connectionAttempted = false;
|
|
657
695
|
this.tools.clear();
|
|
696
|
+
this.cleanupToolsCheck();
|
|
658
697
|
}
|
|
659
698
|
|
|
660
699
|
isServerConnected(): boolean {
|
|
@@ -804,6 +804,183 @@ export class SdkOutputAdapter {
|
|
|
804
804
|
return modeConfigs[mode.toLowerCase()] || modeConfigs.default;
|
|
805
805
|
}
|
|
806
806
|
|
|
807
|
+
// ==================== Team Output Methods ====================
|
|
808
|
+
|
|
809
|
+
/**
|
|
810
|
+
* Format and output team creation.
|
|
811
|
+
*/
|
|
812
|
+
outputTeamCreate(params: {
|
|
813
|
+
teamId: string;
|
|
814
|
+
teamName: string;
|
|
815
|
+
brokerPort: number;
|
|
816
|
+
members: Array<{
|
|
817
|
+
id: string;
|
|
818
|
+
name: string;
|
|
819
|
+
role: string;
|
|
820
|
+
taskId?: string;
|
|
821
|
+
taskTitle?: string;
|
|
822
|
+
}>;
|
|
823
|
+
}): void {
|
|
824
|
+
this.output({
|
|
825
|
+
type: 'system',
|
|
826
|
+
subtype: 'team_create',
|
|
827
|
+
timestamp: Date.now(),
|
|
828
|
+
data: {
|
|
829
|
+
teamId: params.teamId,
|
|
830
|
+
teamName: params.teamName,
|
|
831
|
+
brokerPort: params.brokerPort,
|
|
832
|
+
members: params.members
|
|
833
|
+
}
|
|
834
|
+
});
|
|
835
|
+
}
|
|
836
|
+
|
|
837
|
+
/**
|
|
838
|
+
* Format and output team member spawn.
|
|
839
|
+
*/
|
|
840
|
+
outputTeamMemberSpawn(params: {
|
|
841
|
+
memberId: string;
|
|
842
|
+
memberName: string;
|
|
843
|
+
memberRole: string;
|
|
844
|
+
displayMode: string;
|
|
845
|
+
}): void {
|
|
846
|
+
this.output({
|
|
847
|
+
type: 'system',
|
|
848
|
+
subtype: 'team_member_spawn',
|
|
849
|
+
timestamp: Date.now(),
|
|
850
|
+
data: {
|
|
851
|
+
memberId: params.memberId,
|
|
852
|
+
memberName: params.memberName,
|
|
853
|
+
memberRole: params.memberRole,
|
|
854
|
+
displayMode: params.displayMode
|
|
855
|
+
}
|
|
856
|
+
});
|
|
857
|
+
}
|
|
858
|
+
|
|
859
|
+
/**
|
|
860
|
+
* Format and output team member output (filtered/formatted).
|
|
861
|
+
*/
|
|
862
|
+
outputTeamMemberOutput(params: {
|
|
863
|
+
memberId: string;
|
|
864
|
+
memberName: string;
|
|
865
|
+
content: string;
|
|
866
|
+
type: 'info' | 'success' | 'error' | 'warning' | 'tool' | 'result';
|
|
867
|
+
}): void {
|
|
868
|
+
this.output({
|
|
869
|
+
type: 'output',
|
|
870
|
+
subtype: 'team_member_output',
|
|
871
|
+
timestamp: Date.now(),
|
|
872
|
+
data: {
|
|
873
|
+
memberId: params.memberId,
|
|
874
|
+
memberName: params.memberName,
|
|
875
|
+
content: params.content,
|
|
876
|
+
outputType: params.type
|
|
877
|
+
}
|
|
878
|
+
});
|
|
879
|
+
}
|
|
880
|
+
|
|
881
|
+
/**
|
|
882
|
+
* Format and output team task update.
|
|
883
|
+
*/
|
|
884
|
+
outputTeamTaskUpdate(params: {
|
|
885
|
+
taskId: string;
|
|
886
|
+
taskTitle?: string;
|
|
887
|
+
status: 'created' | 'claimed' | 'in_progress' | 'completed' | 'released' | 'deleted';
|
|
888
|
+
assignee?: string;
|
|
889
|
+
assigneeName?: string;
|
|
890
|
+
result?: string;
|
|
891
|
+
}): void {
|
|
892
|
+
this.output({
|
|
893
|
+
type: 'system',
|
|
894
|
+
subtype: 'team_task_update',
|
|
895
|
+
timestamp: Date.now(),
|
|
896
|
+
data: {
|
|
897
|
+
taskId: params.taskId,
|
|
898
|
+
taskTitle: params.taskTitle,
|
|
899
|
+
status: params.status,
|
|
900
|
+
assignee: params.assignee,
|
|
901
|
+
assigneeName: params.assigneeName,
|
|
902
|
+
result: params.result
|
|
903
|
+
}
|
|
904
|
+
});
|
|
905
|
+
}
|
|
906
|
+
|
|
907
|
+
/**
|
|
908
|
+
* Format and output team message.
|
|
909
|
+
*/
|
|
910
|
+
outputTeamMessage(params: {
|
|
911
|
+
messageId: string;
|
|
912
|
+
fromMemberId: string;
|
|
913
|
+
fromMemberName?: string;
|
|
914
|
+
toMemberId: string | 'broadcast';
|
|
915
|
+
content: string;
|
|
916
|
+
}): void {
|
|
917
|
+
this.output({
|
|
918
|
+
type: 'system',
|
|
919
|
+
subtype: 'team_message',
|
|
920
|
+
timestamp: Date.now(),
|
|
921
|
+
data: {
|
|
922
|
+
messageId: params.messageId,
|
|
923
|
+
fromMemberId: params.fromMemberId,
|
|
924
|
+
fromMemberName: params.fromMemberName,
|
|
925
|
+
toMemberId: params.toMemberId,
|
|
926
|
+
content: params.content
|
|
927
|
+
}
|
|
928
|
+
});
|
|
929
|
+
}
|
|
930
|
+
|
|
931
|
+
/**
|
|
932
|
+
* Format and output team cleanup.
|
|
933
|
+
*/
|
|
934
|
+
outputTeamCleanup(params: {
|
|
935
|
+
teamId: string;
|
|
936
|
+
teamName?: string;
|
|
937
|
+
shutdownCount: number;
|
|
938
|
+
totalCount: number;
|
|
939
|
+
}): void {
|
|
940
|
+
this.output({
|
|
941
|
+
type: 'system',
|
|
942
|
+
subtype: 'team_cleanup',
|
|
943
|
+
timestamp: Date.now(),
|
|
944
|
+
data: {
|
|
945
|
+
teamId: params.teamId,
|
|
946
|
+
teamName: params.teamName,
|
|
947
|
+
shutdownCount: params.shutdownCount,
|
|
948
|
+
totalCount: params.totalCount
|
|
949
|
+
}
|
|
950
|
+
});
|
|
951
|
+
}
|
|
952
|
+
|
|
953
|
+
/**
|
|
954
|
+
* Format and output team status summary.
|
|
955
|
+
*/
|
|
956
|
+
outputTeamStatus(params: {
|
|
957
|
+
teamId: string;
|
|
958
|
+
teamName: string;
|
|
959
|
+
memberCount: number;
|
|
960
|
+
activeTaskCount: number;
|
|
961
|
+
completedTaskCount: number;
|
|
962
|
+
members: Array<{
|
|
963
|
+
id: string;
|
|
964
|
+
name: string;
|
|
965
|
+
role: string;
|
|
966
|
+
status: string;
|
|
967
|
+
}>;
|
|
968
|
+
}): void {
|
|
969
|
+
this.output({
|
|
970
|
+
type: 'system',
|
|
971
|
+
subtype: 'team_status',
|
|
972
|
+
timestamp: Date.now(),
|
|
973
|
+
data: {
|
|
974
|
+
teamId: params.teamId,
|
|
975
|
+
teamName: params.teamName,
|
|
976
|
+
memberCount: params.memberCount,
|
|
977
|
+
activeTaskCount: params.activeTaskCount,
|
|
978
|
+
completedTaskCount: params.completedTaskCount,
|
|
979
|
+
members: params.members
|
|
980
|
+
}
|
|
981
|
+
});
|
|
982
|
+
}
|
|
983
|
+
|
|
807
984
|
/**
|
|
808
985
|
* Convert a SessionInput to SDK format.
|
|
809
986
|
*/
|