@onesclawkolor/onesclaw 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/README.md +65 -0
- package/dist/agent/conversation.d.ts +34 -0
- package/dist/agent/conversation.js +61 -0
- package/dist/agent/conversation.js.map +1 -0
- package/dist/agent/loop.d.ts +40 -0
- package/dist/agent/loop.js +213 -0
- package/dist/agent/loop.js.map +1 -0
- package/dist/agent/session.d.ts +73 -0
- package/dist/agent/session.js +225 -0
- package/dist/agent/session.js.map +1 -0
- package/dist/audit/file-sink.d.ts +6 -0
- package/dist/audit/file-sink.js +21 -0
- package/dist/audit/file-sink.js.map +1 -0
- package/dist/audit/ids.d.ts +3 -0
- package/dist/audit/ids.js +15 -0
- package/dist/audit/ids.js.map +1 -0
- package/dist/audit/types.d.ts +13 -0
- package/dist/audit/types.js +2 -0
- package/dist/audit/types.js.map +1 -0
- package/dist/cli/commands.d.ts +31 -0
- package/dist/cli/commands.js +433 -0
- package/dist/cli/commands.js.map +1 -0
- package/dist/cli/logger.d.ts +57 -0
- package/dist/cli/logger.js +79 -0
- package/dist/cli/logger.js.map +1 -0
- package/dist/cli/output.d.ts +59 -0
- package/dist/cli/output.js +306 -0
- package/dist/cli/output.js.map +1 -0
- package/dist/cli/prompt.d.ts +29 -0
- package/dist/cli/prompt.js +197 -0
- package/dist/cli/prompt.js.map +1 -0
- package/dist/cli/repl.d.ts +4 -0
- package/dist/cli/repl.js +486 -0
- package/dist/cli/repl.js.map +1 -0
- package/dist/commands/init.d.ts +4 -0
- package/dist/commands/init.js +84 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/model.d.ts +3 -0
- package/dist/commands/model.js +178 -0
- package/dist/commands/model.js.map +1 -0
- package/dist/commands/plugin-init.d.ts +23 -0
- package/dist/commands/plugin-init.js +303 -0
- package/dist/commands/plugin-init.js.map +1 -0
- package/dist/commands/provider-auth.d.ts +14 -0
- package/dist/commands/provider-auth.js +153 -0
- package/dist/commands/provider-auth.js.map +1 -0
- package/dist/config/manager.d.ts +71 -0
- package/dist/config/manager.js +201 -0
- package/dist/config/manager.js.map +1 -0
- package/dist/config/types.d.ts +43 -0
- package/dist/config/types.js +2 -0
- package/dist/config/types.js.map +1 -0
- package/dist/errors.d.ts +37 -0
- package/dist/errors.js +55 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +207 -0
- package/dist/index.js.map +1 -0
- package/dist/llm/anthropic.d.ts +83 -0
- package/dist/llm/anthropic.js +190 -0
- package/dist/llm/anthropic.js.map +1 -0
- package/dist/llm/factory.d.ts +105 -0
- package/dist/llm/factory.js +164 -0
- package/dist/llm/factory.js.map +1 -0
- package/dist/llm/openai-codex.d.ts +102 -0
- package/dist/llm/openai-codex.js +445 -0
- package/dist/llm/openai-codex.js.map +1 -0
- package/dist/llm/openai.d.ts +71 -0
- package/dist/llm/openai.js +289 -0
- package/dist/llm/openai.js.map +1 -0
- package/dist/llm/provider.d.ts +1 -0
- package/dist/llm/provider.js +2 -0
- package/dist/llm/provider.js.map +1 -0
- package/dist/llm/types.d.ts +72 -0
- package/dist/llm/types.js +2 -0
- package/dist/llm/types.js.map +1 -0
- package/dist/mcp/bridge.d.ts +17 -0
- package/dist/mcp/bridge.js +74 -0
- package/dist/mcp/bridge.js.map +1 -0
- package/dist/mcp/config.d.ts +10 -0
- package/dist/mcp/config.js +27 -0
- package/dist/mcp/config.js.map +1 -0
- package/dist/mcp/manager.d.ts +67 -0
- package/dist/mcp/manager.js +207 -0
- package/dist/mcp/manager.js.map +1 -0
- package/dist/memory/scope.d.ts +4 -0
- package/dist/memory/scope.js +14 -0
- package/dist/memory/scope.js.map +1 -0
- package/dist/memory/store.d.ts +28 -0
- package/dist/memory/store.js +126 -0
- package/dist/memory/store.js.map +1 -0
- package/dist/prompts/system.d.ts +4 -0
- package/dist/prompts/system.js +197 -0
- package/dist/prompts/system.js.map +1 -0
- package/dist/skills/loader.d.ts +25 -0
- package/dist/skills/loader.js +98 -0
- package/dist/skills/loader.js.map +1 -0
- package/dist/skills/registry.d.ts +57 -0
- package/dist/skills/registry.js +132 -0
- package/dist/skills/registry.js.map +1 -0
- package/dist/skills/sync.d.ts +33 -0
- package/dist/skills/sync.js +180 -0
- package/dist/skills/sync.js.map +1 -0
- package/dist/skills/types.d.ts +1 -0
- package/dist/skills/types.js +2 -0
- package/dist/skills/types.js.map +1 -0
- package/dist/tools/ask.d.ts +30 -0
- package/dist/tools/ask.js +60 -0
- package/dist/tools/ask.js.map +1 -0
- package/dist/tools/confirmation.d.ts +12 -0
- package/dist/tools/confirmation.js +75 -0
- package/dist/tools/confirmation.js.map +1 -0
- package/dist/tools/plugin-init.d.ts +29 -0
- package/dist/tools/plugin-init.js +47 -0
- package/dist/tools/plugin-init.js.map +1 -0
- package/dist/tools/registry.d.ts +56 -0
- package/dist/tools/registry.js +123 -0
- package/dist/tools/registry.js.map +1 -0
- package/dist/tools/safety.d.ts +2 -0
- package/dist/tools/safety.js +30 -0
- package/dist/tools/safety.js.map +1 -0
- package/dist/tools/server.d.ts +91 -0
- package/dist/tools/server.js +149 -0
- package/dist/tools/server.js.map +1 -0
- package/dist/tools/shell.d.ts +11 -0
- package/dist/tools/shell.js +174 -0
- package/dist/tools/shell.js.map +1 -0
- package/dist/tools/skills-sync.d.ts +19 -0
- package/dist/tools/skills-sync.js +29 -0
- package/dist/tools/skills-sync.js.map +1 -0
- package/dist/tools/ssh.d.ts +62 -0
- package/dist/tools/ssh.js +343 -0
- package/dist/tools/ssh.js.map +1 -0
- package/dist/tools/types.d.ts +10 -0
- package/dist/tools/types.js +2 -0
- package/dist/tools/types.js.map +1 -0
- package/dist/utils/retry.d.ts +7 -0
- package/dist/utils/retry.js +34 -0
- package/dist/utils/retry.js.map +1 -0
- package/install.sh +171 -0
- package/package.json +49 -0
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
|
|
2
|
+
import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';
|
|
3
|
+
import { logger } from '../cli/logger.js';
|
|
4
|
+
/**
|
|
5
|
+
* MCP 多服务器连接管理器
|
|
6
|
+
* 管理多个 MCP Server 的生命周期:连接、工具发现、调用、断开
|
|
7
|
+
*/
|
|
8
|
+
export class MCPManager {
|
|
9
|
+
connections = new Map();
|
|
10
|
+
_userInfo = null;
|
|
11
|
+
connectRetryTimes = 1;
|
|
12
|
+
/**
|
|
13
|
+
* 当前用户信息(从 ONES MCP who_am_i 获取)
|
|
14
|
+
*/
|
|
15
|
+
get userInfo() {
|
|
16
|
+
return this._userInfo;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* 并行连接所有 MCP 服务器
|
|
20
|
+
* required 服务器连接失败会抛出错误
|
|
21
|
+
* optional 服务器连接失败仅输出警告
|
|
22
|
+
*/
|
|
23
|
+
async connectAll(servers) {
|
|
24
|
+
const results = await Promise.allSettled(servers.map(async (server) => {
|
|
25
|
+
try {
|
|
26
|
+
await this.connectServerWithRetry(server);
|
|
27
|
+
}
|
|
28
|
+
catch (error) {
|
|
29
|
+
if (server.required) {
|
|
30
|
+
throw new Error(`必需的 MCP 服务器 "${server.name}" 连接失败: ${error instanceof Error ? error.message : String(error)}`);
|
|
31
|
+
}
|
|
32
|
+
console.warn(`⚠ MCP 服务器 "${server.name}" 连接失败(可选),跳过: ${error instanceof Error ? error.message : String(error)}`);
|
|
33
|
+
}
|
|
34
|
+
}));
|
|
35
|
+
// 检查 required 服务器是否有连接失败
|
|
36
|
+
for (const result of results) {
|
|
37
|
+
if (result.status === 'rejected') {
|
|
38
|
+
throw result.reason;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
// ONES MCP 连接成功后,获取用户身份
|
|
42
|
+
if (this.connections.has('ones')) {
|
|
43
|
+
try {
|
|
44
|
+
this._userInfo = await this.fetchUserInfo();
|
|
45
|
+
}
|
|
46
|
+
catch (error) {
|
|
47
|
+
console.warn(`⚠ 获取用户信息失败: ${error instanceof Error ? error.message : String(error)}`);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* 连接单个服务器,失败后自动重试一次
|
|
53
|
+
*/
|
|
54
|
+
async connectServerWithRetry(server) {
|
|
55
|
+
let lastError;
|
|
56
|
+
for (let attempt = 0; attempt <= this.connectRetryTimes; attempt += 1) {
|
|
57
|
+
try {
|
|
58
|
+
await this.connectServer(server);
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
catch (error) {
|
|
62
|
+
lastError = error;
|
|
63
|
+
if (attempt < this.connectRetryTimes) {
|
|
64
|
+
logger.debug('mcp', `Connect ${server.name} failed on attempt ${attempt + 1}, retrying once...`);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
throw lastError instanceof Error ? lastError : new Error(String(lastError));
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* 连接单个 MCP 服务器
|
|
72
|
+
*/
|
|
73
|
+
async connectServer(server) {
|
|
74
|
+
const transport = new StdioClientTransport({
|
|
75
|
+
command: server.command,
|
|
76
|
+
args: server.args,
|
|
77
|
+
env: {
|
|
78
|
+
...process.env,
|
|
79
|
+
...server.env,
|
|
80
|
+
},
|
|
81
|
+
stderr: 'pipe',
|
|
82
|
+
});
|
|
83
|
+
// 收集子进程 stderr 输出,用于连接失败时的诊断
|
|
84
|
+
let stderrOutput = '';
|
|
85
|
+
transport.stderr?.on('data', (chunk) => {
|
|
86
|
+
stderrOutput += chunk.toString();
|
|
87
|
+
});
|
|
88
|
+
const client = new Client({ name: 'onesclaw', version: '0.1.0' }, { capabilities: {} });
|
|
89
|
+
try {
|
|
90
|
+
// 超时 300s,给 OAuth 浏览器授权留足时间(默认 60s 不够)
|
|
91
|
+
await client.connect(transport, { timeout: 300_000 });
|
|
92
|
+
}
|
|
93
|
+
catch (error) {
|
|
94
|
+
// 连接失败时附加 stderr 信息帮助诊断
|
|
95
|
+
if (stderrOutput.trim()) {
|
|
96
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
97
|
+
throw new Error(`${msg}\n 子进程错误输出:\n ${stderrOutput.trim()}`);
|
|
98
|
+
}
|
|
99
|
+
throw error;
|
|
100
|
+
}
|
|
101
|
+
// 发现工具列表
|
|
102
|
+
const response = await client.listTools();
|
|
103
|
+
const tools = response.tools;
|
|
104
|
+
this.connections.set(server.name, { client, transport, tools, config: server });
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* 通过 ONES MCP 的 who_am_i 获取用户身份
|
|
108
|
+
*/
|
|
109
|
+
async fetchUserInfo() {
|
|
110
|
+
const result = await this.callTool('ones', 'who_am_i', {});
|
|
111
|
+
// who_am_i 返回的是 content 数组,提取文本内容
|
|
112
|
+
const content = result;
|
|
113
|
+
if (content.content && content.content.length > 0) {
|
|
114
|
+
const textContent = content.content.find((c) => c.type === 'text');
|
|
115
|
+
if (textContent?.text) {
|
|
116
|
+
const data = JSON.parse(textContent.text);
|
|
117
|
+
return {
|
|
118
|
+
id: data.id || data.uuid || '',
|
|
119
|
+
name: data.name || data.username || '',
|
|
120
|
+
email: data.email || '',
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
throw new Error('who_am_i 返回数据格式异常');
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* 获取指定服务器的工具列表
|
|
128
|
+
*/
|
|
129
|
+
getTools(serverName) {
|
|
130
|
+
const conn = this.connections.get(serverName);
|
|
131
|
+
if (!conn) {
|
|
132
|
+
throw new Error(`MCP 服务器 "${serverName}" 未连接`);
|
|
133
|
+
}
|
|
134
|
+
return conn.tools;
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* 获取所有已连接服务器的工具列表
|
|
138
|
+
*/
|
|
139
|
+
getAllTools() {
|
|
140
|
+
const result = new Map();
|
|
141
|
+
for (const [name, conn] of this.connections) {
|
|
142
|
+
result.set(name, conn.tools);
|
|
143
|
+
}
|
|
144
|
+
return result;
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* 获取所有已连接的服务器名称
|
|
148
|
+
*/
|
|
149
|
+
getConnectedServers() {
|
|
150
|
+
return Array.from(this.connections.keys());
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* 调用指定服务器的工具
|
|
154
|
+
* 调用失败时尝试断开重连一次
|
|
155
|
+
*/
|
|
156
|
+
async callTool(serverName, toolName, args) {
|
|
157
|
+
const conn = this.connections.get(serverName);
|
|
158
|
+
if (!conn) {
|
|
159
|
+
throw new Error(`MCP 服务器 "${serverName}" 未连接`);
|
|
160
|
+
}
|
|
161
|
+
try {
|
|
162
|
+
return await conn.client.callTool({
|
|
163
|
+
name: toolName,
|
|
164
|
+
arguments: args,
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
catch (error) {
|
|
168
|
+
logger.debug('mcp', `Tool call ${toolName} failed on ${serverName}, attempting reconnect...`);
|
|
169
|
+
// 尝试重连一次
|
|
170
|
+
try {
|
|
171
|
+
await conn.transport.close().catch(() => { });
|
|
172
|
+
this.connections.delete(serverName);
|
|
173
|
+
await this.connectServer(conn.config);
|
|
174
|
+
// 重连成功,重试调用
|
|
175
|
+
const newConn = this.connections.get(serverName);
|
|
176
|
+
if (newConn) {
|
|
177
|
+
return await newConn.client.callTool({
|
|
178
|
+
name: toolName,
|
|
179
|
+
arguments: args,
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
catch (reconnectError) {
|
|
184
|
+
logger.error('mcp', `Reconnection failed for ${serverName}: ${reconnectError instanceof Error ? reconnectError.message : String(reconnectError)}`);
|
|
185
|
+
}
|
|
186
|
+
// 重连失败或重试失败,抛出原始错误
|
|
187
|
+
throw error;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* 断开所有 MCP 连接,清理子进程
|
|
192
|
+
*/
|
|
193
|
+
async disconnectAll() {
|
|
194
|
+
const closePromises = Array.from(this.connections.entries()).map(async ([name, conn]) => {
|
|
195
|
+
try {
|
|
196
|
+
await conn.transport.close();
|
|
197
|
+
}
|
|
198
|
+
catch (error) {
|
|
199
|
+
console.warn(`⚠ 关闭 MCP 服务器 "${name}" 时出错: ${error instanceof Error ? error.message : String(error)}`);
|
|
200
|
+
}
|
|
201
|
+
});
|
|
202
|
+
await Promise.allSettled(closePromises);
|
|
203
|
+
this.connections.clear();
|
|
204
|
+
this._userInfo = null;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
//# sourceMappingURL=manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manager.js","sourceRoot":"","sources":["../../src/mcp/manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
// @ts-nocheck
|
|
2
|
+
import { createHash } from 'node:crypto';
|
|
3
|
+
import { resolve } from 'node:path';
|
|
4
|
+
/**
|
|
5
|
+
* 按用户 + 工作目录计算持久化记忆 scope key。
|
|
6
|
+
*/
|
|
7
|
+
export function computeScopeKey(userId, workspacePath) {
|
|
8
|
+
const normalizedUser = (userId || 'anonymous').trim().toLowerCase();
|
|
9
|
+
const normalizedWorkspace = resolve(workspacePath || process.cwd());
|
|
10
|
+
return createHash('sha256')
|
|
11
|
+
.update(`${normalizedUser}::${normalizedWorkspace}`)
|
|
12
|
+
.digest('hex');
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=scope.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scope.js","sourceRoot":"","sources":["../../src/memory/scope.ts"],"names":[],"mappings":"AAAA,cAAc;AACd,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC;;GAEG;AACH,MAAM,UAAU,eAAe,CAAC,MAAc,EAAE,aAAqB;IACnE,MAAM,cAAc,GAAG,CAAC,MAAM,IAAI,WAAW,CAAC,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACpE,MAAM,mBAAmB,GAAG,OAAO,CAAC,aAAa,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;IACpE,OAAO,UAAU,CAAC,QAAQ,CAAC;SACxB,MAAM,CAAC,GAAG,cAAc,KAAK,mBAAmB,EAAE,CAAC;SACnD,MAAM,CAAC,KAAK,CAAC,CAAC;AACnB,CAAC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export interface SessionMemoryRecord {
|
|
2
|
+
scope_key: string;
|
|
3
|
+
last_host: string | null;
|
|
4
|
+
active_skill: string | null;
|
|
5
|
+
skill_phase: string | null;
|
|
6
|
+
recent_decisions_json: string;
|
|
7
|
+
updated_at: string;
|
|
8
|
+
}
|
|
9
|
+
export declare class MemoryStore {
|
|
10
|
+
private dbPath;
|
|
11
|
+
private db;
|
|
12
|
+
private queue;
|
|
13
|
+
constructor(dbPath: string);
|
|
14
|
+
init(): Promise<void>;
|
|
15
|
+
close(): Promise<void>;
|
|
16
|
+
get(scopeKey: string): Promise<SessionMemoryRecord | null>;
|
|
17
|
+
upsert(scopeKey: string, data: {
|
|
18
|
+
lastHost?: string | null;
|
|
19
|
+
activeSkill?: string | null;
|
|
20
|
+
skillPhase?: string | null;
|
|
21
|
+
recentDecisionsJson?: string;
|
|
22
|
+
}): Promise<void>;
|
|
23
|
+
clear(scopeKey: string): Promise<void>;
|
|
24
|
+
private openAndMigrate;
|
|
25
|
+
private isCorruptedError;
|
|
26
|
+
private recoverFromCorruption;
|
|
27
|
+
private withLock;
|
|
28
|
+
}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { dirname } from 'node:path';
|
|
2
|
+
import { mkdir, rename, access, constants } from 'node:fs/promises';
|
|
3
|
+
import sqlite3 from 'sqlite3';
|
|
4
|
+
import { open } from 'sqlite';
|
|
5
|
+
export class MemoryStore {
|
|
6
|
+
dbPath;
|
|
7
|
+
db = null;
|
|
8
|
+
queue = Promise.resolve();
|
|
9
|
+
constructor(dbPath) {
|
|
10
|
+
this.dbPath = dbPath;
|
|
11
|
+
}
|
|
12
|
+
async init() {
|
|
13
|
+
await mkdir(dirname(this.dbPath), { recursive: true });
|
|
14
|
+
try {
|
|
15
|
+
await this.openAndMigrate();
|
|
16
|
+
}
|
|
17
|
+
catch (error) {
|
|
18
|
+
if (!this.isCorruptedError(error)) {
|
|
19
|
+
throw error;
|
|
20
|
+
}
|
|
21
|
+
await this.recoverFromCorruption();
|
|
22
|
+
await this.openAndMigrate();
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
async close() {
|
|
26
|
+
if (this.db) {
|
|
27
|
+
await this.db.close();
|
|
28
|
+
this.db = null;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
async get(scopeKey) {
|
|
32
|
+
if (!this.db) {
|
|
33
|
+
throw new Error('MemoryStore 未初始化');
|
|
34
|
+
}
|
|
35
|
+
const row = await this.db.get(`SELECT scope_key, last_host, active_skill, skill_phase, recent_decisions_json, updated_at
|
|
36
|
+
FROM session_memory
|
|
37
|
+
WHERE scope_key = ?`, [scopeKey]);
|
|
38
|
+
return row || null;
|
|
39
|
+
}
|
|
40
|
+
async upsert(scopeKey, data) {
|
|
41
|
+
return this.withLock(async () => {
|
|
42
|
+
if (!this.db) {
|
|
43
|
+
throw new Error('MemoryStore 未初始化');
|
|
44
|
+
}
|
|
45
|
+
const now = new Date().toISOString();
|
|
46
|
+
await this.db.exec('BEGIN IMMEDIATE');
|
|
47
|
+
try {
|
|
48
|
+
const existing = await this.get(scopeKey);
|
|
49
|
+
const lastHost = data.lastHost !== undefined ? data.lastHost : existing?.last_host ?? null;
|
|
50
|
+
const activeSkill = data.activeSkill !== undefined ? data.activeSkill : existing?.active_skill ?? null;
|
|
51
|
+
const skillPhase = data.skillPhase !== undefined ? data.skillPhase : existing?.skill_phase ?? null;
|
|
52
|
+
const recentDecisionsJson = data.recentDecisionsJson !== undefined
|
|
53
|
+
? data.recentDecisionsJson
|
|
54
|
+
: existing?.recent_decisions_json ?? '[]';
|
|
55
|
+
await this.db.run(`INSERT INTO session_memory (
|
|
56
|
+
scope_key,
|
|
57
|
+
last_host,
|
|
58
|
+
active_skill,
|
|
59
|
+
skill_phase,
|
|
60
|
+
recent_decisions_json,
|
|
61
|
+
updated_at
|
|
62
|
+
) VALUES (?, ?, ?, ?, ?, ?)
|
|
63
|
+
ON CONFLICT(scope_key)
|
|
64
|
+
DO UPDATE SET
|
|
65
|
+
last_host=excluded.last_host,
|
|
66
|
+
active_skill=excluded.active_skill,
|
|
67
|
+
skill_phase=excluded.skill_phase,
|
|
68
|
+
recent_decisions_json=excluded.recent_decisions_json,
|
|
69
|
+
updated_at=excluded.updated_at`, [scopeKey, lastHost, activeSkill, skillPhase, recentDecisionsJson, now]);
|
|
70
|
+
await this.db.exec('COMMIT');
|
|
71
|
+
}
|
|
72
|
+
catch (error) {
|
|
73
|
+
await this.db.exec('ROLLBACK');
|
|
74
|
+
throw error;
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
async clear(scopeKey) {
|
|
79
|
+
await this.withLock(async () => {
|
|
80
|
+
if (!this.db) {
|
|
81
|
+
throw new Error('MemoryStore 未初始化');
|
|
82
|
+
}
|
|
83
|
+
await this.db.run(`DELETE FROM session_memory WHERE scope_key = ?`, [scopeKey]);
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
async openAndMigrate() {
|
|
87
|
+
this.db = await open({
|
|
88
|
+
filename: this.dbPath,
|
|
89
|
+
driver: sqlite3.Database,
|
|
90
|
+
});
|
|
91
|
+
await this.db.exec(`
|
|
92
|
+
CREATE TABLE IF NOT EXISTS session_memory (
|
|
93
|
+
scope_key TEXT PRIMARY KEY,
|
|
94
|
+
last_host TEXT,
|
|
95
|
+
active_skill TEXT,
|
|
96
|
+
skill_phase TEXT,
|
|
97
|
+
recent_decisions_json TEXT NOT NULL DEFAULT '[]',
|
|
98
|
+
updated_at TEXT NOT NULL
|
|
99
|
+
)
|
|
100
|
+
`);
|
|
101
|
+
}
|
|
102
|
+
isCorruptedError(error) {
|
|
103
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
104
|
+
return (message.includes('SQLITE_CORRUPT') ||
|
|
105
|
+
message.includes('SQLITE_NOTADB') ||
|
|
106
|
+
message.includes('database disk image is malformed') ||
|
|
107
|
+
message.includes('file is not a database'));
|
|
108
|
+
}
|
|
109
|
+
async recoverFromCorruption() {
|
|
110
|
+
try {
|
|
111
|
+
await this.close();
|
|
112
|
+
await access(this.dbPath, constants.F_OK);
|
|
113
|
+
const backupPath = `${this.dbPath}.corrupt.${Date.now()}`;
|
|
114
|
+
await rename(this.dbPath, backupPath);
|
|
115
|
+
}
|
|
116
|
+
catch {
|
|
117
|
+
// 恢复失败时,由后续 open 抛错给调用方
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
withLock(fn) {
|
|
121
|
+
const run = this.queue.then(fn);
|
|
122
|
+
this.queue = run.then(() => undefined, () => undefined);
|
|
123
|
+
return run;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
//# sourceMappingURL=store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/memory/store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
// @ts-nocheck
|
|
2
|
+
/**
|
|
3
|
+
* 构建完整的 System Prompt
|
|
4
|
+
*/
|
|
5
|
+
export function buildSystemPrompt(context) {
|
|
6
|
+
const sections = [
|
|
7
|
+
buildRoleSection(),
|
|
8
|
+
buildUserSection(context.userInfo),
|
|
9
|
+
buildSkillsSection(context.skills),
|
|
10
|
+
buildKnowledgeSection(),
|
|
11
|
+
buildMCPToolsSection(context.mcpTools),
|
|
12
|
+
buildSafetySection(),
|
|
13
|
+
buildGuidelinesSection(),
|
|
14
|
+
];
|
|
15
|
+
return sections.join('\n\n');
|
|
16
|
+
}
|
|
17
|
+
// ─── Section 1: 角色定义 ───
|
|
18
|
+
function buildRoleSection() {
|
|
19
|
+
return `你是 ONESCLAW,ONES 企业内部 AI 助手。你的职责是帮助 ONES 团队成员完成日常工作,包括:
|
|
20
|
+
- 运维自动化(ONES 安装、升级、备份、巡检等)
|
|
21
|
+
- 插件开发(环境搭建、仓库初始化、文档查询)
|
|
22
|
+
- 知识检索(企业内部 Wiki 和外部文档查询)
|
|
23
|
+
- ONES 协作(任务管理、项目协作、Wiki、工时记录)
|
|
24
|
+
|
|
25
|
+
默认使用中文交流,跟随用户的语言偏好。回答应简洁专业,直接解决问题。`;
|
|
26
|
+
}
|
|
27
|
+
// ─── Section 2: 用户身份 ───
|
|
28
|
+
function buildUserSection(userInfo) {
|
|
29
|
+
if (!userInfo) {
|
|
30
|
+
return '当前用户:未登录';
|
|
31
|
+
}
|
|
32
|
+
return `当前用户:${userInfo.name}(${userInfo.email})`;
|
|
33
|
+
}
|
|
34
|
+
// ─── Section 3: 技能索引 ───
|
|
35
|
+
function buildSkillsSection(skills) {
|
|
36
|
+
if (skills.length === 0) {
|
|
37
|
+
return '## 可用技能\n\n暂无可用技能。';
|
|
38
|
+
}
|
|
39
|
+
const header = `## 可用技能
|
|
40
|
+
|
|
41
|
+
以下是你可以执行的运维和开发技能。当用户需要执行这些操作时,先用 list_skills 搜索匹配的技能,再用 load_skill 加载完整的执行步骤。
|
|
42
|
+
|
|
43
|
+
| 技能 | 域 | 说明 |
|
|
44
|
+
|------|-----|------|`;
|
|
45
|
+
const rows = skills.map((s) => `| ${s.name} | ${s.domain} | ${s.description} |`);
|
|
46
|
+
return [header, ...rows].join('\n');
|
|
47
|
+
}
|
|
48
|
+
// ─── Section 4: 知识检索指引 ───
|
|
49
|
+
function buildKnowledgeSection() {
|
|
50
|
+
return `## 知识检索
|
|
51
|
+
|
|
52
|
+
当用户提出需要查阅文档或知识的问题时,按以下策略选择数据源:
|
|
53
|
+
|
|
54
|
+
### 内部知识(ONES 企业 Wiki)
|
|
55
|
+
使用 ones__search_for_references_in_wiki 工具搜索企业内部 Wiki 知识库。
|
|
56
|
+
适用场景:公司内部流程、团队规范、项目文档、产品知识等。
|
|
57
|
+
- 可选参数 spaceID:限定搜索范围到特定 Wiki 空间。如需指定空间,先调用 ones__get_space_list 获取空间列表。
|
|
58
|
+
- 如果搜索结果摘要不够详细,可调用 ones__get_page_details 获取完整页面内容。
|
|
59
|
+
|
|
60
|
+
### ONES 运维实施手册
|
|
61
|
+
使用 context7__query-docs 工具,libraryId 为 "/websites/opsdoc_ones_cn"。
|
|
62
|
+
适用场景:ONES 安装部署、升级维护、故障排查、运维操作等。
|
|
63
|
+
无需先调用 resolve-library-id,直接使用此固定 ID。
|
|
64
|
+
|
|
65
|
+
### ONES 开发者平台文档
|
|
66
|
+
使用 context7__query-docs 工具,libraryId 为 "/websites/developer_ones_cn"。
|
|
67
|
+
适用场景:ONES 插件开发、OpenAPI 接口、开发者指南等。
|
|
68
|
+
无需先调用 resolve-library-id,直接使用此固定 ID。
|
|
69
|
+
|
|
70
|
+
### 通用编程文档
|
|
71
|
+
对于第三方库和框架文档,按两步操作:
|
|
72
|
+
1. 先调用 context7__resolve-library-id 获取库的 Context7 ID
|
|
73
|
+
2. 再调用 context7__query-docs 查询具体文档内容
|
|
74
|
+
适用场景:React、Node.js、Python 等通用编程库的文档查询。`;
|
|
75
|
+
}
|
|
76
|
+
// ─── Section 5: MCP 工具使用 ───
|
|
77
|
+
function buildMCPToolsSection(mcpTools) {
|
|
78
|
+
if (mcpTools.length === 0) {
|
|
79
|
+
return '## 平台工具\n\n暂无可用的 MCP 工具。';
|
|
80
|
+
}
|
|
81
|
+
// 按 server 前缀分组
|
|
82
|
+
const grouped = new Map();
|
|
83
|
+
for (const tool of mcpTools) {
|
|
84
|
+
const sepIdx = tool.indexOf('__');
|
|
85
|
+
if (sepIdx === -1)
|
|
86
|
+
continue;
|
|
87
|
+
const server = tool.substring(0, sepIdx);
|
|
88
|
+
const name = tool.substring(sepIdx + 2);
|
|
89
|
+
if (!grouped.has(server)) {
|
|
90
|
+
grouped.set(server, []);
|
|
91
|
+
}
|
|
92
|
+
grouped.get(server).push(name);
|
|
93
|
+
}
|
|
94
|
+
const sections = ['## 平台工具'];
|
|
95
|
+
for (const [server, tools] of grouped) {
|
|
96
|
+
if (server === 'ones') {
|
|
97
|
+
sections.push(buildOnesToolsSection(tools));
|
|
98
|
+
}
|
|
99
|
+
else if (server === 'context7') {
|
|
100
|
+
sections.push(buildContext7ToolsSection(tools));
|
|
101
|
+
}
|
|
102
|
+
else {
|
|
103
|
+
// 其他 MCP server
|
|
104
|
+
sections.push(`### ${server}\n可用工具:${tools.join('、')}`);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
return sections.join('\n\n');
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* ONES MCP 工具分类说明
|
|
111
|
+
*/
|
|
112
|
+
function buildOnesToolsSection(tools) {
|
|
113
|
+
const categories = [
|
|
114
|
+
{ title: '任务管理', pattern: /issue|onesql/, items: [] },
|
|
115
|
+
{ title: '项目管理', pattern: /project/, items: [] },
|
|
116
|
+
{ title: 'Wiki 知识库', pattern: /wiki|page|space/, items: [] },
|
|
117
|
+
{ title: '用户信息', pattern: /user|who_am_i/, items: [] },
|
|
118
|
+
{ title: '工时管理', pattern: /manhour|workhour/, items: [] },
|
|
119
|
+
{ title: '其他', pattern: /.*/, items: [] },
|
|
120
|
+
];
|
|
121
|
+
for (const tool of tools) {
|
|
122
|
+
let matched = false;
|
|
123
|
+
for (const cat of categories) {
|
|
124
|
+
if (cat.title !== '其他' && cat.pattern.test(tool)) {
|
|
125
|
+
cat.items.push(tool);
|
|
126
|
+
matched = true;
|
|
127
|
+
break;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
if (!matched) {
|
|
131
|
+
categories[categories.length - 1].items.push(tool);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
const lines = ['### ONES 平台工具'];
|
|
135
|
+
// 工时特殊说明
|
|
136
|
+
const hasManHour = categories.some((c) => c.title === '工时管理' && c.items.length > 0);
|
|
137
|
+
for (const cat of categories) {
|
|
138
|
+
if (cat.items.length === 0)
|
|
139
|
+
continue;
|
|
140
|
+
lines.push(`\n**${cat.title}**`);
|
|
141
|
+
for (const item of cat.items) {
|
|
142
|
+
lines.push(`- ones__${item}`);
|
|
143
|
+
}
|
|
144
|
+
if (cat.title === '工时管理' && hasManHour) {
|
|
145
|
+
lines.push('\n> 工时操作前必须先调用 ones__get_manhour_mode 确定模式(simple/summary),再使用对应模式的工具。');
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
return lines.join('\n');
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Context7 工具说明
|
|
152
|
+
*/
|
|
153
|
+
function buildContext7ToolsSection(tools) {
|
|
154
|
+
const lines = ['### Context7 文档检索工具'];
|
|
155
|
+
for (const tool of tools) {
|
|
156
|
+
lines.push(`- context7__${tool}`);
|
|
157
|
+
}
|
|
158
|
+
return lines.join('\n');
|
|
159
|
+
}
|
|
160
|
+
// ─── Section 6: 安全约束 ───
|
|
161
|
+
function buildSafetySection() {
|
|
162
|
+
return `## 安全规则
|
|
163
|
+
|
|
164
|
+
### 危险操作确认
|
|
165
|
+
以下操作必须先调用 ask_user 工具获取用户确认后才能执行:
|
|
166
|
+
- 卸载或删除操作(uninstall、rm -rf、drop 等)
|
|
167
|
+
- 数据库变更(SQL UPDATE、DELETE、TRUNCATE)
|
|
168
|
+
- 服务启停(systemctl stop、k3s-killall.sh)
|
|
169
|
+
- 不可逆的配置修改
|
|
170
|
+
- 任何可能导致数据丢失的操作
|
|
171
|
+
|
|
172
|
+
### 命令执行安全
|
|
173
|
+
- 执行 Shell/SSH 命令前,确认命令的影响范围
|
|
174
|
+
- 避免执行包含敏感信息(密码、密钥)的命令
|
|
175
|
+
- 长时间运行的命令应告知用户预期耗时
|
|
176
|
+
- execute_command / ssh_execute 遇到高危命令时,必须先 ask_user,再携带 confirmed=true 调用;否则工具会直接拒绝执行
|
|
177
|
+
- **ssh_execute 失败时必须立即停止当前任务**,向用户报告错误原因,不要继续执行后续步骤。SSH 连接失败意味着目标服务器不可达,继续执行没有意义
|
|
178
|
+
|
|
179
|
+
### 插件开发
|
|
180
|
+
在插件开发辅助场景中:
|
|
181
|
+
- 当用户需要初始化插件项目时,先通过对话确认插件名称和项目目录,然后调用 plugin_init 工具
|
|
182
|
+
- 仅协助环境搭建、仓库初始化和文档查询
|
|
183
|
+
- 不生成插件业务代码
|
|
184
|
+
- 引导用户参考开发者平台文档自行开发`;
|
|
185
|
+
}
|
|
186
|
+
// ─── Section 7: 行为指南 ───
|
|
187
|
+
function buildGuidelinesSection() {
|
|
188
|
+
return `## 行为指南
|
|
189
|
+
|
|
190
|
+
1. 执行 Skill 时严格按照 SKILL.md 中定义的步骤顺序执行,不跳过步骤
|
|
191
|
+
2. 每个步骤执行后验证结果,确认成功后再进入下一步
|
|
192
|
+
3. 遇到错误时,分析原因并尝试修复,无法修复则告知用户
|
|
193
|
+
4. 使用 ONESQL 查询时,严格遵循 ONESQL 语法(参考工具描述中的规范)
|
|
194
|
+
5. 工时操作前必须先获取工时模式(simple/summary)
|
|
195
|
+
6. 对于不确定的操作,主动询问用户而不是猜测`;
|
|
196
|
+
}
|
|
197
|
+
//# sourceMappingURL=system.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"system.js","sourceRoot":"","sources":["../../src/prompts/system.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 创建 load_skill 工具
|
|
3
|
+
* 读取并解析 SKILL.md,返回 frontmatter 元数据和 Markdown 正文
|
|
4
|
+
*/
|
|
5
|
+
export declare function createLoadSkillTool(registry: any): {
|
|
6
|
+
name: string;
|
|
7
|
+
description: string;
|
|
8
|
+
inputSchema: {
|
|
9
|
+
type: string;
|
|
10
|
+
properties: {
|
|
11
|
+
name: {
|
|
12
|
+
type: string;
|
|
13
|
+
description: string;
|
|
14
|
+
};
|
|
15
|
+
};
|
|
16
|
+
required: string[];
|
|
17
|
+
};
|
|
18
|
+
execute: (args: any) => Promise<{
|
|
19
|
+
content: string;
|
|
20
|
+
isError: boolean;
|
|
21
|
+
} | {
|
|
22
|
+
content: string;
|
|
23
|
+
isError?: undefined;
|
|
24
|
+
}>;
|
|
25
|
+
};
|