@datafrog-io/n2n-nexus 0.2.0 → 0.3.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 +59 -81
- package/build/config.js +176 -4
- package/build/index.js +133 -16
- package/build/resources/index.js +21 -29
- package/build/storage/index.js +64 -9
- package/build/storage/sqlite-meeting.js +38 -8
- package/build/storage/sqlite.js +10 -0
- package/build/storage/store.js +11 -4
- package/build/tools/definitions.js +295 -0
- package/build/tools/handlers.js +38 -27
- package/build/tools/index.js +6 -9
- package/build/tools/schemas.js +18 -15
- package/build/utils/auth.js +5 -5
- package/docs/ARCHITECTURE.md +63 -0
- package/docs/ARCHITECTURE_zh.md +43 -0
- package/docs/ASSISTANT_GUIDE.md +23 -17
- package/docs/CHANGELOG_zh.md +94 -166
- package/{README_zh.md → docs/README_zh.md} +60 -57
- package/docs/TODO_zh.md +71 -0
- package/package.json +2 -2
- package/docs/CHANGELOG.md +0 -170
package/build/tools/handlers.js
CHANGED
|
@@ -32,7 +32,7 @@ export async function handleToolCall(name, toolArgs, ctx) {
|
|
|
32
32
|
case "upload_project_asset":
|
|
33
33
|
return handleUploadAsset(validatedArgs, ctx);
|
|
34
34
|
case "get_global_topology":
|
|
35
|
-
return handleGetTopology();
|
|
35
|
+
return handleGetTopology(validatedArgs);
|
|
36
36
|
case "send_message":
|
|
37
37
|
return handleSendMessage(validatedArgs, ctx);
|
|
38
38
|
case "read_messages":
|
|
@@ -45,10 +45,10 @@ export async function handleToolCall(name, toolArgs, ctx) {
|
|
|
45
45
|
return handleUpdateProject(validatedArgs);
|
|
46
46
|
case "rename_project":
|
|
47
47
|
return handleRenameProject(validatedArgs, ctx);
|
|
48
|
-
case "
|
|
48
|
+
case "host_delete_project":
|
|
49
49
|
return handleRemoveProject(validatedArgs, ctx);
|
|
50
|
-
case "
|
|
51
|
-
return
|
|
50
|
+
case "host_maintenance":
|
|
51
|
+
return handleHostMaintenance(validatedArgs, ctx);
|
|
52
52
|
// --- Meeting Tools ---
|
|
53
53
|
case "start_meeting":
|
|
54
54
|
return handleStartMeeting(validatedArgs, ctx);
|
|
@@ -226,8 +226,8 @@ async function handleRenameProject(args, ctx) {
|
|
|
226
226
|
};
|
|
227
227
|
}
|
|
228
228
|
// --- Global Handlers ---
|
|
229
|
-
async function handleGetTopology() {
|
|
230
|
-
const topo = await StorageManager.calculateTopology();
|
|
229
|
+
async function handleGetTopology(args) {
|
|
230
|
+
const topo = await StorageManager.calculateTopology(args?.projectId);
|
|
231
231
|
return { content: [{ type: "text", text: JSON.stringify(topo, null, 2) }] };
|
|
232
232
|
}
|
|
233
233
|
async function handleSendMessage(args, ctx) {
|
|
@@ -268,15 +268,25 @@ async function handleSendMessage(args, ctx) {
|
|
|
268
268
|
}
|
|
269
269
|
async function handleReadMessages(args) {
|
|
270
270
|
const count = args?.count || 10;
|
|
271
|
-
// If meetingId specified, read from that meeting
|
|
271
|
+
// If meetingId specified, read from that meeting (with incremental cursor)
|
|
272
272
|
if (args?.meetingId) {
|
|
273
|
-
const messages = await UnifiedMeetingStore.getRecentMessages(count, args.meetingId);
|
|
274
|
-
return {
|
|
273
|
+
const messages = await UnifiedMeetingStore.getRecentMessages(count, args.meetingId, CONFIG.instanceId);
|
|
274
|
+
return {
|
|
275
|
+
content: [{
|
|
276
|
+
type: "text",
|
|
277
|
+
text: JSON.stringify({
|
|
278
|
+
source: "meeting",
|
|
279
|
+
meetingId: args.meetingId,
|
|
280
|
+
newMessages: messages.length,
|
|
281
|
+
messages
|
|
282
|
+
}, null, 2)
|
|
283
|
+
}]
|
|
284
|
+
};
|
|
275
285
|
}
|
|
276
286
|
// Check for active meeting first
|
|
277
287
|
const activeMeeting = await UnifiedMeetingStore.getActiveMeeting();
|
|
278
288
|
if (activeMeeting) {
|
|
279
|
-
const messages = await UnifiedMeetingStore.getRecentMessages(count, activeMeeting.id);
|
|
289
|
+
const messages = await UnifiedMeetingStore.getRecentMessages(count, activeMeeting.id, CONFIG.instanceId);
|
|
280
290
|
return {
|
|
281
291
|
content: [{
|
|
282
292
|
type: "text",
|
|
@@ -284,12 +294,13 @@ async function handleReadMessages(args) {
|
|
|
284
294
|
source: "meeting",
|
|
285
295
|
meetingId: activeMeeting.id,
|
|
286
296
|
topic: activeMeeting.topic,
|
|
297
|
+
newMessages: messages.length,
|
|
287
298
|
messages
|
|
288
299
|
}, null, 2)
|
|
289
300
|
}]
|
|
290
301
|
};
|
|
291
302
|
}
|
|
292
|
-
// Fallback to global logs
|
|
303
|
+
// Fallback to global logs (no incremental support for global yet)
|
|
293
304
|
const logs = await StorageManager.getRecentLogs(count);
|
|
294
305
|
return {
|
|
295
306
|
content: [{
|
|
@@ -310,12 +321,12 @@ async function handleUpdateStrategy(args, _ctx) {
|
|
|
310
321
|
return { content: [{ type: "text", text: "Strategy updated." }] };
|
|
311
322
|
}
|
|
312
323
|
/**
|
|
313
|
-
* ASYNC:
|
|
324
|
+
* ASYNC: host_delete_project now returns a taskId.
|
|
314
325
|
*/
|
|
315
326
|
async function handleRemoveProject(args, ctx) {
|
|
316
|
-
// Defense-in-Depth: Explicit
|
|
317
|
-
if (!CONFIG.
|
|
318
|
-
throw new McpError(ErrorCode.InvalidRequest, "Permission denied: Only
|
|
327
|
+
// Defense-in-Depth: Explicit host check
|
|
328
|
+
if (!CONFIG.isHost) {
|
|
329
|
+
throw new McpError(ErrorCode.InvalidRequest, "Permission denied: Only hosts can delete projects.");
|
|
319
330
|
}
|
|
320
331
|
if (!args?.projectId)
|
|
321
332
|
throw new McpError(ErrorCode.InvalidParams, "projectId is required.");
|
|
@@ -326,7 +337,7 @@ async function handleRemoveProject(args, ctx) {
|
|
|
326
337
|
// Create background task
|
|
327
338
|
const task = createTask({
|
|
328
339
|
metadata: {
|
|
329
|
-
operation: "
|
|
340
|
+
operation: "host_delete_project",
|
|
330
341
|
projectId: args.projectId,
|
|
331
342
|
initiator: CONFIG.instanceId
|
|
332
343
|
}
|
|
@@ -340,7 +351,7 @@ async function handleRemoveProject(args, ctx) {
|
|
|
340
351
|
ctx.notifyResourceUpdate("mcp://nexus/hub/registry");
|
|
341
352
|
ctx.notifyResourceUpdate("mcp://nexus/get_global_topology");
|
|
342
353
|
updateTask(task.id, { status: "completed", progress: 1.0 });
|
|
343
|
-
await StorageManager.addGlobalLog("SYSTEM", `[${CONFIG.instanceId}] Task Completed: Project '${args.projectId}' deleted by
|
|
354
|
+
await StorageManager.addGlobalLog("SYSTEM", `[${CONFIG.instanceId}] Task Completed: Project '${args.projectId}' deleted by host.`);
|
|
344
355
|
}
|
|
345
356
|
catch (error) {
|
|
346
357
|
updateTask(task.id, {
|
|
@@ -369,10 +380,10 @@ async function handleSyncGlobalDoc(args) {
|
|
|
369
380
|
return { content: [{ type: "text", text: `Global document '${args.docId}' synchronized.` }] };
|
|
370
381
|
}
|
|
371
382
|
// --- Admin Handlers ---
|
|
372
|
-
async function
|
|
373
|
-
// Defense-in-Depth: Explicit
|
|
374
|
-
if (!CONFIG.
|
|
375
|
-
throw new McpError(ErrorCode.InvalidRequest, "Permission denied: Only
|
|
383
|
+
async function handleHostMaintenance(args, ctx) {
|
|
384
|
+
// Defense-in-Depth: Explicit host check
|
|
385
|
+
if (!CONFIG.isHost) {
|
|
386
|
+
throw new McpError(ErrorCode.InvalidRequest, "Permission denied: Only hosts can perform maintenance.");
|
|
376
387
|
}
|
|
377
388
|
if (!args.action || args.count === undefined) {
|
|
378
389
|
throw new McpError(ErrorCode.InvalidParams, "Both 'action' and 'count' are mandatory for maintenance.");
|
|
@@ -423,9 +434,9 @@ async function handleEndMeeting(args, ctx) {
|
|
|
423
434
|
throw new McpError(ErrorCode.InvalidRequest, "No active meeting found to end. Please specify meetingId.");
|
|
424
435
|
targetId = active.id;
|
|
425
436
|
}
|
|
426
|
-
// STRICT: Only
|
|
427
|
-
if (!CONFIG.
|
|
428
|
-
throw new McpError(ErrorCode.InvalidRequest, "Permission denied: Only
|
|
437
|
+
// STRICT: Only hosts can end meetings
|
|
438
|
+
if (!CONFIG.isHost) {
|
|
439
|
+
throw new McpError(ErrorCode.InvalidRequest, "Permission denied: Only hosts can end meetings.");
|
|
429
440
|
}
|
|
430
441
|
const { meeting, suggestedSyncTargets } = await UnifiedMeetingStore.endMeeting(targetId, args.summary, undefined);
|
|
431
442
|
ctx.notifyResourceUpdate("mcp://nexus/status");
|
|
@@ -447,9 +458,9 @@ async function handleEndMeeting(args, ctx) {
|
|
|
447
458
|
async function handleArchiveMeeting(args, _ctx) {
|
|
448
459
|
if (!args.meetingId)
|
|
449
460
|
throw new McpError(ErrorCode.InvalidParams, "meetingId is required.");
|
|
450
|
-
// STRICT: Only
|
|
451
|
-
if (!CONFIG.
|
|
452
|
-
throw new McpError(ErrorCode.InvalidRequest, "Permission denied: Only
|
|
461
|
+
// STRICT: Only hosts can archive meetings
|
|
462
|
+
if (!CONFIG.isHost) {
|
|
463
|
+
throw new McpError(ErrorCode.InvalidRequest, "Permission denied: Only hosts can archive meetings.");
|
|
453
464
|
}
|
|
454
465
|
await UnifiedMeetingStore.archiveMeeting(args.meetingId, undefined);
|
|
455
466
|
return {
|
package/build/tools/index.js
CHANGED
|
@@ -1,13 +1,10 @@
|
|
|
1
|
-
import { TOOL_REGISTRY } from "./schemas.js";
|
|
2
1
|
/**
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
2
|
+
* Token-Optimized Tool Exports
|
|
3
|
+
*
|
|
4
|
+
* Uses hand-crafted minimal definitions instead of Zod toJSONSchema()
|
|
5
|
+
* to reduce context window consumption by ~60%.
|
|
6
6
|
*/
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
description: entry.description,
|
|
10
|
-
inputSchema: entry.schema.toJSONSchema()
|
|
11
|
-
}));
|
|
7
|
+
import { TOOL_DEFINITIONS, ALL_TOOL_DEFINITIONS } from "./definitions.js";
|
|
8
|
+
export { TOOL_DEFINITIONS, ALL_TOOL_DEFINITIONS };
|
|
12
9
|
export { handleToolCall } from "./handlers.js";
|
|
13
10
|
export { TOOL_REGISTRY } from "./schemas.js";
|
package/build/tools/schemas.js
CHANGED
|
@@ -62,8 +62,11 @@ export const UploadAssetSchema = z.object({
|
|
|
62
62
|
base64Content: z.string()
|
|
63
63
|
});
|
|
64
64
|
/**
|
|
65
|
-
* 4. get_global_topology
|
|
65
|
+
* 4. get_global_topology
|
|
66
66
|
*/
|
|
67
|
+
export const TopologySchema = z.object({
|
|
68
|
+
projectId: ProjectIdSchema.optional().describe("Focus on specific project's subgraph. Omit for summary list.")
|
|
69
|
+
});
|
|
67
70
|
export const EmptySchema = z.object({});
|
|
68
71
|
/**
|
|
69
72
|
* 7. send_message
|
|
@@ -108,16 +111,16 @@ export const RenameProjectSchema = z.object({
|
|
|
108
111
|
newId: ProjectIdSchema
|
|
109
112
|
});
|
|
110
113
|
/**
|
|
111
|
-
* 15.
|
|
114
|
+
* 15. host_maintenance
|
|
112
115
|
*/
|
|
113
|
-
export const
|
|
116
|
+
export const HostMaintenanceSchema = z.object({
|
|
114
117
|
action: z.enum(["prune", "clear"]),
|
|
115
118
|
count: z.number().int().min(0)
|
|
116
119
|
});
|
|
117
120
|
/**
|
|
118
|
-
* 16.
|
|
121
|
+
* 16. host_delete_project
|
|
119
122
|
*/
|
|
120
|
-
export const
|
|
123
|
+
export const HostDeleteSchema = z.object({
|
|
121
124
|
projectId: ProjectIdSchema
|
|
122
125
|
});
|
|
123
126
|
/**
|
|
@@ -200,8 +203,8 @@ export const TOOL_REGISTRY = {
|
|
|
200
203
|
schema: UploadAssetSchema
|
|
201
204
|
},
|
|
202
205
|
get_global_topology: {
|
|
203
|
-
description: "
|
|
204
|
-
schema:
|
|
206
|
+
description: "Project topology. Default: list summary. With projectId: detailed subgraph.",
|
|
207
|
+
schema: TopologySchema
|
|
205
208
|
},
|
|
206
209
|
send_message: {
|
|
207
210
|
description: "Post a message to the Nexus collaboration space. If an active meeting exists, the message is automatically routed to that meeting. Otherwise, it goes to the global discussion log. Use this for proposals, decisions, or general coordination.",
|
|
@@ -227,24 +230,24 @@ export const TOOL_REGISTRY = {
|
|
|
227
230
|
description: "[ASYNC] Rename a project ID with automatic cascading updates to all relation references. Returns task ID.",
|
|
228
231
|
schema: RenameProjectSchema
|
|
229
232
|
},
|
|
230
|
-
|
|
231
|
-
description: "[
|
|
232
|
-
schema:
|
|
233
|
+
host_maintenance: {
|
|
234
|
+
description: "[HOST ONLY] Manage global discussion logs. 'prune' removes the oldest N entries (keeps newest). 'clear' wipes all logs (use count=0). Returns summary of removed entries. Irreversible.",
|
|
235
|
+
schema: HostMaintenanceSchema
|
|
233
236
|
},
|
|
234
|
-
|
|
235
|
-
description: "[ASYNC][
|
|
236
|
-
schema:
|
|
237
|
+
host_delete_project: {
|
|
238
|
+
description: "[ASYNC][HOST ONLY] Completely remove a project, its manifest, and all its assets from Nexus Hub. Returns task ID. Irreversible.",
|
|
239
|
+
schema: HostDeleteSchema
|
|
237
240
|
},
|
|
238
241
|
start_meeting: {
|
|
239
242
|
description: "Start a new meeting session. Creates a dedicated file for the meeting. Returns the meeting ID and details.",
|
|
240
243
|
schema: StartMeetingSchema
|
|
241
244
|
},
|
|
242
245
|
end_meeting: {
|
|
243
|
-
description: "End an active meeting. Locks the session for further messages. [RESTRICTED: Only
|
|
246
|
+
description: "End an active meeting. Locks the session for further messages. [RESTRICTED: Only host can end].",
|
|
244
247
|
schema: EndMeetingSchema
|
|
245
248
|
},
|
|
246
249
|
archive_meeting: {
|
|
247
|
-
description: "Archive a closed meeting. Archived meetings are read-only and excluded from active queries. [RESTRICTED: Only
|
|
250
|
+
description: "Archive a closed meeting. Archived meetings are read-only and excluded from active queries. [RESTRICTED: Only host can archive].",
|
|
248
251
|
schema: ArchiveMeetingSchema
|
|
249
252
|
},
|
|
250
253
|
reopen_meeting: {
|
package/build/utils/auth.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { ErrorCode, McpError } from "@modelcontextprotocol/sdk/types.js";
|
|
2
2
|
import { CONFIG } from "../config.js";
|
|
3
3
|
/**
|
|
4
|
-
* Validates
|
|
5
|
-
* @throws McpError if current session is not in
|
|
4
|
+
* Validates host permissions for privileged tools.
|
|
5
|
+
* @throws McpError if current session is not in Host mode.
|
|
6
6
|
*/
|
|
7
|
-
export function
|
|
8
|
-
if (!CONFIG.
|
|
9
|
-
throw new McpError(ErrorCode.InvalidRequest, `Forbidden: ${toolName} requires
|
|
7
|
+
export function checkHostPermission(toolName) {
|
|
8
|
+
if (!CONFIG.isHost) {
|
|
9
|
+
throw new McpError(ErrorCode.InvalidRequest, `Forbidden: ${toolName} requires Host rights.`);
|
|
10
10
|
}
|
|
11
11
|
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# Architecture & Standards
|
|
2
|
+
|
|
3
|
+
## 🏛️ Architecture
|
|
4
|
+
|
|
5
|
+
1. **Nexus Room (Discussion)**: Unified public channel for all IDE assistants to coordinate across projects.
|
|
6
|
+
2. **Asset Vault (Archives)**:
|
|
7
|
+
- **Manifest**: Technical details, billing, topology, and API specs for each project.
|
|
8
|
+
- **Internal Docs**: Detailed technical implementation plans.
|
|
9
|
+
- **Assets**: Local physical assets (Logos, UI screenshots, etc.).
|
|
10
|
+
3. **Global Knowledge**:
|
|
11
|
+
- **Master Strategy**: Top-level strategic blueprint.
|
|
12
|
+
- **Global Docs**: Cross-project common documents (e.g., Coding Standards, Roadmaps).
|
|
13
|
+
4. **Topology Engine**: Automated dependency graph analysis.
|
|
14
|
+
|
|
15
|
+
## 💾 Data Persistence
|
|
16
|
+
|
|
17
|
+
Nexus stores all data in the local file system (customizable path), ensuring complete data sovereignty.
|
|
18
|
+
|
|
19
|
+
**Directory Structure Example**:
|
|
20
|
+
```text
|
|
21
|
+
Nexus_Storage/
|
|
22
|
+
├── global/
|
|
23
|
+
│ ├── blueprint.md # Master Strategy
|
|
24
|
+
│ ├── discussion.json # Global Chat History (fallback)
|
|
25
|
+
│ ├── docs_index.json # Global Docs Index
|
|
26
|
+
│ └── docs/ # Global Markdown Docs
|
|
27
|
+
│ ├── coding-standards.md
|
|
28
|
+
│ └── deployment-flow.md
|
|
29
|
+
├── projects/
|
|
30
|
+
│ └── {project-id}/
|
|
31
|
+
│ ├── manifest.json # Project Metadata
|
|
32
|
+
│ ├── internal_blueprint.md # Technical Implementation Docs
|
|
33
|
+
│ └── assets/ # Binary Assets (images, PDFs)
|
|
34
|
+
├── meetings/ # Meeting files (JSON fallback mode)
|
|
35
|
+
│ └── {meeting-id}.json
|
|
36
|
+
├── registry.json # Global Project Index
|
|
37
|
+
├── archives/ # Reserved for backups
|
|
38
|
+
└── nexus.db # SQLite Database (meetings, tasks, state)
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
**Self-healing**: Core data files (e.g., `registry.json`, `discussion.json`) include automatic detection and repair mechanisms. If files are corrupted or missing, the system automatically rebuilds the initial state to ensure uninterrupted service.
|
|
42
|
+
|
|
43
|
+
**Concurrency Safety**: All write operations to shared files (`discussion.json`, `registry.json`) are protected by an `AsyncMutex` lock, preventing race conditions when multiple AI agents communicate simultaneously.
|
|
44
|
+
|
|
45
|
+
## 🏷️ Project ID Conventions (Naming Standard)
|
|
46
|
+
|
|
47
|
+
To ensure clarity and prevent collisions in the flat local namespace, all Project IDs MUST follow the **Prefix Dictionary** format: `[prefix]_[project-name]`.
|
|
48
|
+
|
|
49
|
+
| Prefix | Category | Example |
|
|
50
|
+
| :--- | :--- | :--- |
|
|
51
|
+
| `web_` | Websites, landing pages, domain-based projects | `web_datafrog.io` |
|
|
52
|
+
| `api_` | Backend services, REST/gRPC APIs | `api_user-auth` |
|
|
53
|
+
| `chrome_` | Chrome extensions | `chrome_evisa-helper` |
|
|
54
|
+
| `vscode_` | VSCode extensions | `vscode_super-theme` |
|
|
55
|
+
| `mcp_` | MCP Servers and MCP-related tools | `mcp_github-repo` |
|
|
56
|
+
| `android_` | Native Android projects (Kotlin/Java) | `android_client-app` |
|
|
57
|
+
| `ios_` | Native iOS projects (Swift/ObjC) | `ios_client-app` |
|
|
58
|
+
| `flutter_` | **Mobile Cross-platform Special Case** | `flutter_unified-app` |
|
|
59
|
+
| `desktop_` | General desktop apps (Tauri, Electron, etc.) | `desktop_main-hub` |
|
|
60
|
+
| `lib_` | Shared libraries, SDKs, NPM/Python packages | `lib_crypto-core` |
|
|
61
|
+
| `bot_` | Bots (Discord, Slack, DingTalk, etc.) | `bot_auto-moderator` |
|
|
62
|
+
| `infra_` | Infrastructure as Code, CI/CD, DevOps scripts | `infra_k8s-config` |
|
|
63
|
+
| `doc_` | Pure technical handbooks, strategies, roadmaps | `doc_coding-guide` |
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# 架构与标准 (Architecture & Standards)
|
|
2
|
+
|
|
3
|
+
## 🏛️ 系统架构 (Architecture)
|
|
4
|
+
|
|
5
|
+
1. **Nexus Room (讨论区)**: 所有 IDE 助手的统一公域频道,用于跨项目协调。
|
|
6
|
+
2. **Asset Vault (归档库)**:
|
|
7
|
+
- **Manifest**: 每个项目的技术细节、计费、拓扑关系、API 规范。
|
|
8
|
+
- **Internal Docs**: 每个项目的详细技术实施方案。
|
|
9
|
+
- **Assets**: 本地物理素材存储(Logo/UI 截图等)。
|
|
10
|
+
3. **Global Knowledge (全局知识库)**:
|
|
11
|
+
- **Master Strategy**: 顶层战略总纲。
|
|
12
|
+
- **Global Docs**: 跨项目的通用文档(如编码规范、路线图)。
|
|
13
|
+
4. **Topology Engine**: 自动分析项目间的依赖关系图谱。
|
|
14
|
+
|
|
15
|
+
## 💾 数据持久化 (Data Persistence)
|
|
16
|
+
|
|
17
|
+
Nexus 将所有数据存储在本地文件系统中(默认路径可配置),完全掌控数据主权。
|
|
18
|
+
|
|
19
|
+
**目录结构示例**:
|
|
20
|
+
```text
|
|
21
|
+
Nexus_Storage/
|
|
22
|
+
├── global/
|
|
23
|
+
│ ├── blueprint.md # Master Strategy
|
|
24
|
+
│ ├── discussion.json # 全局聊天历史 (fallback)
|
|
25
|
+
│ ├── docs_index.json # 全局文档索引
|
|
26
|
+
│ └── docs/ # 全局 Markdown 文档
|
|
27
|
+
│ ├── coding-standards.md
|
|
28
|
+
│ └── deployment-flow.md
|
|
29
|
+
├── projects/
|
|
30
|
+
│ └── {project-id}/
|
|
31
|
+
│ ├── manifest.json # 项目元数据
|
|
32
|
+
│ ├── internal_blueprint.md # 技术实现文档
|
|
33
|
+
│ └── assets/ # 二进制资产 (图片、PDF)
|
|
34
|
+
├── meetings/ # 会议文件 (JSON 回退模式)
|
|
35
|
+
│ └── {meeting-id}.json
|
|
36
|
+
├── registry.json # 全局项目索引
|
|
37
|
+
├── archives/ # 归档备份 (保留)
|
|
38
|
+
└── nexus.db # SQLite 数据库 (会议、任务、状态)
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
**自我修复 (Self-healing)**: 核心数据文件(如 `registry.json`, `discussion.json`)具备自动检测与修复机制。如果文件损坏或意外丢失,系统会自动重建初始状态,确保服务不中断。
|
|
42
|
+
|
|
43
|
+
**多并发安全 (Concurrency Safety)**: 对共享文件(`discussion.json`, `registry.json`)的所有写入操作均受 `AsyncMutex` 锁保护,防止多个 AI 代理同时通信时发生竞争条件。
|
package/docs/ASSISTANT_GUIDE.md
CHANGED
|
@@ -1,24 +1,28 @@
|
|
|
1
|
-
# Nexus 助手协作指令 (v0.2.
|
|
1
|
+
# Nexus 助手协作指令 (v0.2.1)
|
|
2
2
|
|
|
3
3
|
你现在是 **n2ns Nexus** 协作网络的一员。该系统集成了实时通信、结构化资产管理以及 **异步任务流 (Task Primitives)**,所有操作均落地在本地文件系统。
|
|
4
4
|
|
|
5
|
-
## 🚦
|
|
6
|
-
|
|
5
|
+
## 🚦 核心原则:渐进式发现,增量读取
|
|
6
|
+
|
|
7
|
+
Nexus 采用 **Context7 风格** 的渐进加载模式,最大化 Token 效率:
|
|
8
|
+
1. **先 List,再深入** - 获取概览后按需查询详情
|
|
9
|
+
2. **增量读取** - 只获取你未读的消息
|
|
10
|
+
3. **模板 URI** - 从 registry 发现 ID,构造 URI 读取详情
|
|
7
11
|
|
|
8
12
|
### 1. 状态发现 (Reading via Resources)
|
|
9
|
-
在任何任务开始前,你**必须**了解环境状态。直接读取对应的 URI
|
|
13
|
+
在任何任务开始前,你**必须**了解环境状态。直接读取对应的 URI 即可:
|
|
10
14
|
- **查看身份**:`mcp://nexus/session`(你的 ID 和活跃项目)。
|
|
11
15
|
- **系统状态**:`mcp://nexus/status`(版本、存储模式、活跃会议数)。
|
|
12
|
-
- **项目目录**:`mcp://nexus/hub/registry
|
|
16
|
+
- **项目目录**:`mcp://nexus/hub/registry`(**优先读取** - 发现所有项目 ID)。
|
|
13
17
|
- **会议目录**:`mcp://nexus/meetings/list`(哪些会议正在进行或已结束)。
|
|
14
|
-
- **任务列表**:`mcp://nexus/tasks/list` (TODO: 资源映射中) 或使用 `list_tasks`。
|
|
15
18
|
- **全局文档列表**:`mcp://nexus/docs/list`(有哪些通用规范)。
|
|
16
19
|
|
|
17
|
-
### 2. 深度查阅 (
|
|
18
|
-
|
|
19
|
-
-
|
|
20
|
-
-
|
|
21
|
-
-
|
|
20
|
+
### 2. 深度查阅 (Template-Based Discovery)
|
|
21
|
+
从目录获取 ID 后,使用模板构造 URI:
|
|
22
|
+
- **查阅项目**: `mcp://nexus/projects/{projectId}/manifest` 或 `mcp://nexus/projects/{projectId}/internal-docs`。
|
|
23
|
+
- **查阅文档**: `mcp://nexus/docs/{docId}`。
|
|
24
|
+
- **查阅会议**: `mcp://nexus/meetings/{meetingId}` 或 `mcp://nexus/active-meeting`。
|
|
25
|
+
- **依赖分析**: `get_global_topology()` 先返回摘要,传 `projectId` 获取详细子图。
|
|
22
26
|
|
|
23
27
|
### 3. 项目管理 (Writing via Tools)
|
|
24
28
|
当你需要**改变**状态时,调用工具:
|
|
@@ -28,29 +32,31 @@
|
|
|
28
32
|
- **素材上传**: `upload_project_asset` (架构图转 Base64)。
|
|
29
33
|
|
|
30
34
|
### 4. 异步任务流 (Tasks - Phase 2)
|
|
31
|
-
|
|
35
|
+
对于耗时较长或可能超时的操作(如大规模同步、重构),使用任务原语:
|
|
32
36
|
- **创建任务**: `create_task(source_meeting_id?, metadata?)`。返回 `taskId`。
|
|
33
37
|
- **状态轮询**: `get_task(taskId)`。通过 `progress` (0.0-1.0) 了解任务进度。
|
|
34
38
|
- **任务列表**: `list_tasks(status?)`。
|
|
35
39
|
- **取消任务**: `cancel_task(taskId)`。
|
|
36
40
|
|
|
37
|
-
### 5. 即时沟通 (Collaboration
|
|
41
|
+
### 5. 即时沟通 (Incremental Collaboration)
|
|
38
42
|
- **发送消息**: `send_message(message, category?)`。
|
|
39
|
-
-
|
|
43
|
+
- **获取消息**: `read_messages(count?)`。**[增量模式]** 自动只返回你未读的消息。
|
|
40
44
|
- **更新战略**: `update_global_strategy`(修改全球蓝图)。
|
|
41
45
|
- **文档维护**: `sync_global_doc` (创建/更新通用知识库)。
|
|
42
46
|
|
|
43
47
|
### 6. 战术会议 (Tactical Meetings)
|
|
44
48
|
1. **发起**: `start_meeting(topic)`。
|
|
45
49
|
2. **参与**: 发送 category 为 `DECISION` 的消息作为共识。
|
|
46
|
-
3. **结束**: `end_meeting(summary?)
|
|
47
|
-
4. **归档**: `archive_meeting(meetingId)
|
|
50
|
+
3. **结束**: `end_meeting(summary?)`。锁定历史(**Host only**)。
|
|
51
|
+
4. **归档**: `archive_meeting(meetingId)`(**Host only**)。
|
|
52
|
+
5. **重开**: `reopen_meeting(meetingId)`。
|
|
48
53
|
|
|
49
54
|
---
|
|
50
55
|
|
|
51
56
|
## 🛡️ 角色说明
|
|
52
57
|
- **Regular**: 拥有注册、同步、讨论和维护文档的完整权限。
|
|
53
|
-
- **
|
|
58
|
+
- **Host**: 管理员实例(通常是第一个启动的实例),额外拥有清理记录(`host_maintenance`)、结束/归档会议及物理删除(`host_delete_project`)的权限。
|
|
54
59
|
|
|
55
60
|
## ❌ 退出机制
|
|
56
61
|
本系统是对本地磁盘的原子写入。请确保同步时提供清晰的 `internalDocs`,以便其他 Assistant 能够无缝接手。
|
|
62
|
+
|