@datafrog-io/n2n-nexus 0.1.7 โ†’ 0.2.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.
@@ -1,2 +1,13 @@
1
- export { TOOL_DEFINITIONS } from "./definitions.js";
1
+ import { TOOL_REGISTRY } from "./schemas.js";
2
+ /**
3
+ * Dynamically generated Tool Definitions from Zod Schemas.
4
+ * This ensures Tool Registry and Input Validation are always in sync.
5
+ * Using native Zod 4 toJSONSchema support.
6
+ */
7
+ export const TOOL_DEFINITIONS = Object.entries(TOOL_REGISTRY).map(([name, entry]) => ({
8
+ name,
9
+ description: entry.description,
10
+ inputSchema: entry.schema.toJSONSchema()
11
+ }));
2
12
  export { handleToolCall } from "./handlers.js";
13
+ export { TOOL_REGISTRY } from "./schemas.js";
@@ -0,0 +1,275 @@
1
+ import { z } from "zod";
2
+ /**
3
+ * Project ID validation regex based on Nexus conventions.
4
+ */
5
+ export const ProjectIdSchema = z.string()
6
+ .describe("Strict flat identifier. MUST start with a type-prefix followed by an underscore.")
7
+ .refine(val => {
8
+ const validPrefixes = ["web_", "api_", "chrome_", "vscode_", "mcp_", "android_", "ios_", "flutter_", "desktop_", "lib_", "bot_", "infra_", "doc_"];
9
+ return validPrefixes.some(p => val.startsWith(p));
10
+ }, "Project ID must start with a valid prefix (e.g., 'web_', 'api_')")
11
+ .refine(val => !val.includes("..") && !val.includes("/") && !val.includes("\\"), "Project ID cannot contain '..' or slashes.");
12
+ /**
13
+ * 1. register_session_context
14
+ */
15
+ export const RegisterSessionSchema = z.object({
16
+ projectId: ProjectIdSchema
17
+ });
18
+ /**
19
+ * 2. sync_project_assets
20
+ */
21
+ export const SyncProjectAssetsSchema = z.object({
22
+ manifest: z.object({
23
+ id: ProjectIdSchema,
24
+ name: z.string(),
25
+ description: z.string(),
26
+ techStack: z.array(z.string()),
27
+ relations: z.array(z.object({
28
+ targetId: z.string(),
29
+ type: z.enum(["dependency", "parent", "child", "related"])
30
+ })),
31
+ lastUpdated: z.string().describe("ISO timestamp"),
32
+ repositoryUrl: z.string(),
33
+ localPath: z.string().describe("Physical disk path"),
34
+ endpoints: z.array(z.object({
35
+ name: z.string(),
36
+ url: z.string(),
37
+ description: z.string()
38
+ })),
39
+ apiSpec: z.array(z.object({
40
+ method: z.string(),
41
+ path: z.string(),
42
+ summary: z.string()
43
+ }))
44
+ }),
45
+ internalDocs: z.string().describe("Mandatory technical implementation guide (Markdown)")
46
+ });
47
+ /**
48
+ * Safe file name validation (no path traversal)
49
+ */
50
+ export const FileNameSchema = z.string()
51
+ .min(1, "File name cannot be empty")
52
+ .max(255, "File name too long")
53
+ .refine(val => !val.includes("/") && !val.includes("\\"), "File name cannot contain slashes")
54
+ .refine(val => !val.includes(".."), "File name cannot contain '..'")
55
+ .refine(val => !val.startsWith("."), "File name cannot start with '.'")
56
+ .describe("Safe file name without path components");
57
+ /**
58
+ * 3. upload_project_asset
59
+ */
60
+ export const UploadAssetSchema = z.object({
61
+ fileName: FileNameSchema,
62
+ base64Content: z.string()
63
+ });
64
+ /**
65
+ * 4. get_global_topology (No arguments)
66
+ */
67
+ export const EmptySchema = z.object({});
68
+ /**
69
+ * 7. send_message
70
+ */
71
+ export const SendMessageSchema = z.object({
72
+ message: z.string().min(1, "Message cannot be empty"),
73
+ category: z.enum(["MEETING_START", "PROPOSAL", "DECISION", "UPDATE", "CHAT"]).optional()
74
+ });
75
+ /**
76
+ * 8. read_messages
77
+ */
78
+ export const ReadMessagesSchema = z.object({
79
+ count: z.number().int().positive().optional().default(10),
80
+ meetingId: z.string().optional()
81
+ });
82
+ /**
83
+ * 9. update_global_strategy
84
+ */
85
+ export const UpdateStrategySchema = z.object({
86
+ content: z.string().min(1, "Strategy content cannot be empty")
87
+ });
88
+ /**
89
+ * 10. sync_global_doc
90
+ */
91
+ export const SyncGlobalDocSchema = z.object({
92
+ docId: z.string(),
93
+ title: z.string(),
94
+ content: z.string()
95
+ });
96
+ /**
97
+ * 13. update_project
98
+ */
99
+ export const UpdateProjectSchema = z.object({
100
+ projectId: ProjectIdSchema,
101
+ patch: z.object({}).passthrough().describe("Fields to update (e.g., description, techStack)")
102
+ });
103
+ /**
104
+ * 14. rename_project
105
+ */
106
+ export const RenameProjectSchema = z.object({
107
+ oldId: ProjectIdSchema,
108
+ newId: ProjectIdSchema
109
+ });
110
+ /**
111
+ * 15. moderator_maintenance
112
+ */
113
+ export const ModeratorMaintenanceSchema = z.object({
114
+ action: z.enum(["prune", "clear"]),
115
+ count: z.number().int().min(0)
116
+ });
117
+ /**
118
+ * 16. moderator_delete_project
119
+ */
120
+ export const ModeratorDeleteSchema = z.object({
121
+ projectId: ProjectIdSchema
122
+ });
123
+ /**
124
+ * 17. start_meeting
125
+ */
126
+ export const StartMeetingSchema = z.object({
127
+ topic: z.string().min(1, "Topic is required")
128
+ });
129
+ /**
130
+ * 18. end_meeting
131
+ */
132
+ export const EndMeetingSchema = z.object({
133
+ meetingId: z.string().optional(),
134
+ summary: z.string().optional()
135
+ });
136
+ /**
137
+ * 21. archive_meeting
138
+ */
139
+ export const ArchiveMeetingSchema = z.object({
140
+ meetingId: z.string()
141
+ });
142
+ /**
143
+ * 22. reopen_meeting
144
+ */
145
+ export const ReopenMeetingSchema = z.object({
146
+ meetingId: z.string()
147
+ });
148
+ // ============ Phase 2: Task Management Schemas ============
149
+ /**
150
+ * 22. create_task
151
+ */
152
+ export const CreateTaskSchema = z.object({
153
+ source_meeting_id: z.string().optional().describe("Link task to a meeting for traceability"),
154
+ metadata: z.object({}).passthrough().optional().describe("Custom task parameters"),
155
+ ttl: z.number().int().positive().optional().describe("Time-to-live in milliseconds")
156
+ });
157
+ /**
158
+ * 23. get_task
159
+ */
160
+ export const GetTaskSchema = z.object({
161
+ taskId: z.string()
162
+ });
163
+ /**
164
+ * 24. list_tasks
165
+ */
166
+ export const ListTasksSchema = z.object({
167
+ status: z.enum(["pending", "running", "completed", "failed", "cancelled"]).optional(),
168
+ limit: z.number().int().positive().optional().default(50)
169
+ });
170
+ /**
171
+ * 25. update_task
172
+ */
173
+ export const UpdateTaskSchema = z.object({
174
+ taskId: z.string(),
175
+ status: z.enum(["pending", "running", "completed", "failed", "cancelled"]).optional(),
176
+ progress: z.number().min(0).max(1).optional(),
177
+ result_uri: z.string().optional(),
178
+ error_message: z.string().optional()
179
+ });
180
+ /**
181
+ * 26. cancel_task
182
+ */
183
+ export const CancelTaskSchema = z.object({
184
+ taskId: z.string()
185
+ });
186
+ /**
187
+ * Tool Registry with descriptions and schemas
188
+ */
189
+ export const TOOL_REGISTRY = {
190
+ register_session_context: {
191
+ description: "[IDENTITY] Declare the PROJECT identity. Format: [prefix]_[technical-identifier]. (e.g., 'web_datafrog.io', 'mcp_nexus-core').",
192
+ schema: RegisterSessionSchema
193
+ },
194
+ sync_project_assets: {
195
+ description: "CRITICAL: [PREREQUISITE: register_session_context] Sync full project state. Both manifest and documentation are MANDATORY.",
196
+ schema: SyncProjectAssetsSchema
197
+ },
198
+ upload_project_asset: {
199
+ description: "Upload a binary file (images, PDFs, etc.) to the current project's asset folder. Requires active session (call register_session_context first). Returns the relative path of the saved file.",
200
+ schema: UploadAssetSchema
201
+ },
202
+ get_global_topology: {
203
+ description: "Retrieve complete project relationship graph. Returns { nodes: [{ id, name }], edges: [{ from, to, type }] }. Use this to visualize dependencies.",
204
+ schema: EmptySchema
205
+ },
206
+ send_message: {
207
+ 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.",
208
+ schema: SendMessageSchema
209
+ },
210
+ read_messages: {
211
+ description: "Read recent messages. Automatically reads from the active meeting if one exists, otherwise reads from global logs.",
212
+ schema: ReadMessagesSchema
213
+ },
214
+ update_global_strategy: {
215
+ description: "Overwrite master strategy. Content is MANDATORY.",
216
+ schema: UpdateStrategySchema
217
+ },
218
+ sync_global_doc: {
219
+ description: "Create or update a global document. Returns the document ID.",
220
+ schema: SyncGlobalDocSchema
221
+ },
222
+ update_project: {
223
+ description: "Partially update a project's manifest. Only provided fields will be updated.",
224
+ schema: UpdateProjectSchema
225
+ },
226
+ rename_project: {
227
+ description: "[ASYNC] Rename a project ID with automatic cascading updates to all relation references. Returns task ID.",
228
+ schema: RenameProjectSchema
229
+ },
230
+ moderator_maintenance: {
231
+ description: "[ADMIN 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.",
232
+ schema: ModeratorMaintenanceSchema
233
+ },
234
+ moderator_delete_project: {
235
+ description: "[ASYNC][ADMIN ONLY] Completely remove a project, its manifest, and all its assets from Nexus Hub. Returns task ID. Irreversible.",
236
+ schema: ModeratorDeleteSchema
237
+ },
238
+ start_meeting: {
239
+ description: "Start a new meeting session. Creates a dedicated file for the meeting. Returns the meeting ID and details.",
240
+ schema: StartMeetingSchema
241
+ },
242
+ end_meeting: {
243
+ description: "End an active meeting. Locks the session for further messages. [RESTRICTED: Only moderator can end].",
244
+ schema: EndMeetingSchema
245
+ },
246
+ archive_meeting: {
247
+ description: "Archive a closed meeting. Archived meetings are read-only and excluded from active queries. [RESTRICTED: Only moderator can archive].",
248
+ schema: ArchiveMeetingSchema
249
+ },
250
+ reopen_meeting: {
251
+ description: "Reopen a closed or archived meeting. [Open to all participants].",
252
+ schema: ReopenMeetingSchema
253
+ },
254
+ // --- Phase 2: Task Management ---
255
+ create_task: {
256
+ description: "[ASYNC] Create a new background task. Returns task ID for polling. Link to meeting for traceability.",
257
+ schema: CreateTaskSchema
258
+ },
259
+ get_task: {
260
+ description: "[ASYNC] Get the status and progress of a task by ID.",
261
+ schema: GetTaskSchema
262
+ },
263
+ list_tasks: {
264
+ description: "[ASYNC] List all tasks with optional status filter.",
265
+ schema: ListTasksSchema
266
+ },
267
+ update_task: {
268
+ description: "[ASYNC][INTERNAL] Update task status, progress, or result. Intended for background workers only - do not call directly from user-facing tools.",
269
+ schema: UpdateTaskSchema
270
+ },
271
+ cancel_task: {
272
+ description: "[ASYNC] Cancel a pending or running task.",
273
+ schema: CancelTaskSchema
274
+ },
275
+ };
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Simple mutex lock for preventing concurrent file writes.
3
+ * Ensures that only one write operation can happen at a time.
4
+ */
5
+ export class AsyncMutex {
6
+ locked = false;
7
+ queue = [];
8
+ async acquire() {
9
+ if (!this.locked) {
10
+ this.locked = true;
11
+ return;
12
+ }
13
+ return new Promise((resolve) => {
14
+ this.queue.push(resolve);
15
+ });
16
+ }
17
+ release() {
18
+ if (this.queue.length > 0) {
19
+ const next = this.queue.shift();
20
+ if (next)
21
+ next();
22
+ }
23
+ else {
24
+ this.locked = false;
25
+ }
26
+ }
27
+ async withLock(fn) {
28
+ await this.acquire();
29
+ try {
30
+ return await fn();
31
+ }
32
+ finally {
33
+ this.release();
34
+ }
35
+ }
36
+ }
@@ -0,0 +1,11 @@
1
+ import { ErrorCode, McpError } from "@modelcontextprotocol/sdk/types.js";
2
+ import { CONFIG } from "../config.js";
3
+ /**
4
+ * Validates moderator permissions for admin tools.
5
+ * @throws McpError if current session is not in Moderator mode.
6
+ */
7
+ export function checkModeratorPermission(toolName) {
8
+ if (!CONFIG.isModerator) {
9
+ throw new McpError(ErrorCode.InvalidRequest, `Forbidden: ${toolName} requires Moderator rights.`);
10
+ }
11
+ }
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Error utility functions for path sanitization and reporting.
3
+ */
4
+ /**
5
+ * Strips internal file paths from error messages to prevent sensitive path exposure.
6
+ */
7
+ export function sanitizeErrorMessage(msg) {
8
+ // Mask Windows paths (e.g. C:\Users\...)
9
+ let sanitized = msg.replace(/[A-Za-z]:\\[^\s:]+/g, "[internal-path]");
10
+ // Mask Unix paths (e.g. /home/user/...)
11
+ sanitized = sanitized.replace(/\/[^\s:]+\/[^\s:]*/g, "[internal-path]");
12
+ // Mask relative parent paths
13
+ sanitized = sanitized.replace(/\.\.[\\/][^\s]*/g, "[internal-path]");
14
+ return sanitized;
15
+ }
@@ -0,0 +1,56 @@
1
+ # Nexus ๅŠฉๆ‰‹ๅไฝœๆŒ‡ไปค (v0.2.0)
2
+
3
+ ไฝ ็Žฐๅœจๆ˜ฏ **n2ns Nexus** ๅไฝœ็ฝ‘็ปœ็š„ไธ€ๅ‘˜ใ€‚่ฏฅ็ณป็ปŸ้›†ๆˆไบ†ๅฎžๆ—ถ้€šไฟกใ€็ป“ๆž„ๅŒ–่ต„ไบง็ฎก็†ไปฅๅŠ **ๅผ‚ๆญฅไปปๅŠกๆต (Task Primitives)**๏ผŒๆ‰€ๆœ‰ๆ“ไฝœๅ‡่ฝๅœฐๅœจๆœฌๅœฐๆ–‡ไปถ็ณป็ปŸใ€‚
4
+
5
+ ## ๐Ÿšฆ ๆ ธๅฟƒๅŽŸๅˆ™๏ผš่ต„ๆบ่ฏปๅ–๏ผŒๅทฅๅ…ทๅ†™ๅ…ฅ
6
+ ไธบไบ†ไผ˜ๅŒ– Token ๆถˆ่€—๏ผŒNexus ๅฐ†**ๅช่ฏปไฟกๆฏ**ๆšด้œฒไธบ่ต„ๆบ (Resources)๏ผŒๅฐ†**ๆ‰ง่กŒๆ“ไฝœ**ไฟ็•™ไธบๅทฅๅ…ท (Tools)ใ€‚
7
+
8
+ ### 1. ็Šถๆ€ๅ‘็Žฐ (Reading via Resources)
9
+ ๅœจไปปไฝ•ไปปๅŠกๅผ€ๅง‹ๅ‰๏ผŒไฝ **ๅฟ…้กป**ไบ†่งฃ็Žฏๅขƒ็Šถๆ€ใ€‚็›ดๆŽฅ่ฏปๅ–ๅฏนๅบ”็š„ URI ๅณๅฏ๏ผŒๆ— ้œ€ๆถˆ่€—ๅทฅๅ…ท่ฐƒ็”จ้ขๅบฆ๏ผš
10
+ - **ๆŸฅ็œ‹่บซไปฝ**๏ผš`mcp://nexus/session`๏ผˆไฝ ็š„ ID ๅ’Œๆดป่ทƒ้กน็›ฎ๏ผ‰ใ€‚
11
+ - **็ณป็ปŸ็Šถๆ€**๏ผš`mcp://nexus/status`๏ผˆ็‰ˆๆœฌใ€ๅญ˜ๅ‚จๆจกๅผใ€ๆดป่ทƒไผš่ฎฎๆ•ฐ๏ผ‰ใ€‚
12
+ - **้กน็›ฎ็›ฎๅฝ•**๏ผš`mcp://nexus/hub/registry`๏ผˆๅ…ฌๅธ็›ฎๅ‰ๆœ‰ๅ“ชไบ›ๅ…ถไป–้กน็›ฎ๏ผ‰ใ€‚
13
+ - **ไผš่ฎฎ็›ฎๅฝ•**๏ผš`mcp://nexus/meetings/list`๏ผˆๅ“ชไบ›ไผš่ฎฎๆญฃๅœจ่ฟ›่กŒๆˆ–ๅทฒ็ป“ๆŸ๏ผ‰ใ€‚
14
+ - **ไปปๅŠกๅˆ—่กจ**๏ผš`mcp://nexus/tasks/list` (TODO: ่ต„ๆบๆ˜ ๅฐ„ไธญ) ๆˆ–ไฝฟ็”จ `list_tasks`ใ€‚
15
+ - **ๅ…จๅฑ€ๆ–‡ๆกฃๅˆ—่กจ**๏ผš`mcp://nexus/docs/list`๏ผˆๆœ‰ๅ“ชไบ›้€š็”จ่ง„่Œƒ๏ผ‰ใ€‚
16
+
17
+ ### 2. ๆทฑๅบฆๆŸฅ้˜… (Deep Reading)
18
+ - **ๆŸฅ้˜…้กน็›ฎ**: `mcp://nexus/projects/{id}/manifest` (API ๅฎšไน‰/ๆŠ€ๆœฏๆ ˆ) ๆˆ– `mcp://nexus/projects/{id}/internal-docs` (่ฏฆ็ป†ๅฎž็Žฐๆ–‡ๆกฃ)ใ€‚
19
+ - **ๆŸฅ้˜…ๆ–‡ๆกฃ**: `mcp://nexus/docs/{id}`ใ€‚
20
+ - **ๆŸฅ้˜…ไผš่ฎฎ**: `mcp://nexus/active-meeting` (ๅฝ“ๅ‰ๆดป่ทƒไผš่ฎฎๅ…จๆกˆ) ๆˆ– `mcp://nexus/meetings/{id}` (ๆŒ‡ๅฎšไผš่ฎฎ)ใ€‚
21
+ - **ๆŸฅ้˜…่ฎจ่ฎบ**: `mcp://nexus/chat/global` (ๅ…จๅฑ€ๅฎžๆ—ถๆถˆๆฏๆต)ใ€‚
22
+
23
+ ### 3. ้กน็›ฎ็ฎก็† (Writing via Tools)
24
+ ๅฝ“ไฝ ้œ€่ฆ**ๆ”นๅ˜**็Šถๆ€ๆ—ถ๏ผŒ่ฐƒ็”จๅทฅๅ…ท๏ผš
25
+ - **ๅฃฐๆ˜Žไฝ็ฝฎ**: `register_session_context(projectId)`ใ€‚่งฃ้”้กน็›ฎๅ†™ๆƒ้™ใ€‚
26
+ - **่ต„ไบงๅŒๆญฅ**: `sync_project_assets`ใ€‚
27
+ - **้กน็›ฎ็ปดๆŠค**: `update_project` ๆˆ– `rename_project` (่‡ชๅŠจๅค„็†ๆ‰€ๆœ‰ไพ่ต–ๅผ•็”จ)ใ€‚
28
+ - **็ด ๆไธŠไผ **: `upload_project_asset` (ๆžถๆž„ๅ›พ่ฝฌ Base64)ใ€‚
29
+
30
+ ### 4. ๅผ‚ๆญฅไปปๅŠกๆต (Tasks - Phase 2)
31
+ ๅฏนไบŽ่€—ๆ—ถ่พƒ้•ฟๆˆ–ๅฏ่ƒฝ่ถ…ๆ—ถ็š„ๆ“ไฝœ๏ผˆๅฆ‚ๅคง่ง„ๆจกๅŒๆญฅใ€้‡ๆž„๏ผ‰๏ผŒไฝ **ๅฟ…้กป**ไฝฟ็”จไปปๅŠกๅŽŸ่ฏญ๏ผš
32
+ - **ๅˆ›ๅปบไปปๅŠก**: `create_task(source_meeting_id?, metadata?)`ใ€‚่ฟ”ๅ›ž `taskId`ใ€‚
33
+ - **็Šถๆ€่ฝฎ่ฏข**: `get_task(taskId)`ใ€‚้€š่ฟ‡ `progress` (0.0-1.0) ไบ†่งฃไปปๅŠก่ฟ›ๅบฆใ€‚
34
+ - **ไปปๅŠกๅˆ—่กจ**: `list_tasks(status?)`ใ€‚
35
+ - **ๅ–ๆถˆไปปๅŠก**: `cancel_task(taskId)`ใ€‚
36
+
37
+ ### 5. ๅณๆ—ถๆฒŸ้€š (Collaboration via Tools)
38
+ - **ๅ‘้€ๆถˆๆฏ**: `send_message(message, category?)`ใ€‚
39
+ - **่Žทๅ–ไธŠไธ‹ๆ–‡**: `read_messages`ใ€‚่™ฝ็„ถๅทฒๆœ‰่ต„ๆบ๏ผŒไฝ†ๅฝ“ไฝ ้œ€่ฆๅธฆๅ‚ๆ•ฐ๏ผˆๅฆ‚ `count`๏ผ‰่Žทๅ–็‰นๅฎšๆ•ฐ้‡็š„ๅކๅฒ่ฎฐๅฝ•ๆ—ถ๏ผŒๆญคๅทฅๅ…ทๆ›ดๅˆ้€‚ใ€‚
40
+ - **ๆ›ดๆ–ฐๆˆ˜็•ฅ**: `update_global_strategy`๏ผˆไฟฎๆ”นๅ…จ็ƒ่“ๅ›พ๏ผ‰ใ€‚
41
+ - **ๆ–‡ๆกฃ็ปดๆŠค**: `sync_global_doc` (ๅˆ›ๅปบ/ๆ›ดๆ–ฐ้€š็”จ็Ÿฅ่ฏ†ๅบ“)ใ€‚
42
+
43
+ ### 6. ๆˆ˜ๆœฏไผš่ฎฎ (Tactical Meetings)
44
+ 1. **ๅ‘่ตท**: `start_meeting(topic)`ใ€‚
45
+ 2. **ๅ‚ไธŽ**: ๅ‘้€ category ไธบ `DECISION` ็š„ๆถˆๆฏไฝœไธบๅ…ฑ่ฏ†ใ€‚
46
+ 3. **็ป“ๆŸ**: `end_meeting(summary?)`ใ€‚้”ๅฎšๅކๅฒใ€‚
47
+ 4. **ๅฝ’ๆกฃ**: `archive_meeting(meetingId)`ใ€‚
48
+
49
+ ---
50
+
51
+ ## ๐Ÿ›ก๏ธ ่ง’่‰ฒ่ฏดๆ˜Ž
52
+ - **Regular**: ๆ‹ฅๆœ‰ๆณจๅ†Œใ€ๅŒๆญฅใ€่ฎจ่ฎบๅ’Œ็ปดๆŠคๆ–‡ๆกฃ็š„ๅฎŒๆ•ดๆƒ้™ใ€‚
53
+ - **Moderator**: ้ขๅค–ๆ‹ฅๆœ‰ๆธ…็†่ฎฐๅฝ•๏ผˆ`moderator_maintenance`๏ผ‰ๅŠ็‰ฉ็†ๅˆ ้™ค๏ผˆ`moderator_delete_project`๏ผ‰็š„ๆƒ้™ใ€‚
54
+
55
+ ## โŒ ้€€ๅ‡บๆœบๅˆถ
56
+ ๆœฌ็ณป็ปŸๆ˜ฏๅฏนๆœฌๅœฐ็ฃ็›˜็š„ๅŽŸๅญๅ†™ๅ…ฅใ€‚่ฏท็กฎไฟๅŒๆญฅๆ—ถๆไพ›ๆธ…ๆ™ฐ็š„ `internalDocs`๏ผŒไปฅไพฟๅ…ถไป– Assistant ่ƒฝๅคŸๆ— ็ผๆŽฅๆ‰‹ใ€‚
@@ -0,0 +1,170 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ ## [v0.2.0] - 2025-12-31
6
+
7
+ ### ๐Ÿš€ Task Primitive System (Phase 2 & 3)
8
+ - **Async Deepening**: Critical blocking operations (`rename_project`, `moderator_delete_project`) migrated to the Task primitive with background cascading updates.
9
+ - **Traceability**: All tasks now support `source_meeting_id` to link execution back to meeting decisions.
10
+ - **Progressive UI**: Added `progress` tracking (0.0-1.0) and `result_uri` for structured task output.
11
+ - **Lifecycle Tools**: Added `create_task`, `get_task`, `list_tasks`, `update_task`, and `cancel_task`.
12
+
13
+ ### ๐Ÿ›ก๏ธ Type Safety & Security
14
+ - **Defense-in-Depth**: Implemented secondary permission gates inside `handleRemoveProject` and `handleModeratorMaintenance` for maximum project isolation.
15
+ - **Meeting Hardening**: `end_meeting` and `archive_meeting` are now strictly **Moderator-only**.
16
+ - **Zod integration**: All tool definitions migrated to strictly-typed Zod schemas with regex path-traversal protection.
17
+ - **Infrastructure**: Modernized toolchain to **TypeScript 5.9.3**, **Vitest 4.0.16**, and **ESLint 9.39.2**.
18
+
19
+ ### โœ‚๏ธ Code Diet (Architectural Cleanliness)
20
+ - **The Great Purge**: Removed 6 redundant tools (`list_projects`, `read_project`, `list_global_docs`, `read_global_doc`, `list_meetings`, `read_meeting`) in favor of Resource URIs.
21
+ - **Native Zod 4 Schemas**: Removed `zod-to-json-schema` dependency; now using native Zod 4 `toJSONSchema()` generation.
22
+
23
+ ## [v0.1.9] - 2025-12-30
24
+
25
+ ### ๐Ÿ›ก๏ธ Collaboration & Security
26
+ - **Initiator-only Permissions**: Implemented restricted access for `end_meeting` and `archive_meeting`.
27
+ - **Session Presence Awareness**: Automated `[ONLINE/OFFLINE]` status messages in global logs.
28
+ - **Clean Tool Naming**: Finalized transition to `send_message` and `read_messages`.
29
+
30
+ ### ๐ŸŒ Resource Namespacing (MCP 2025 Standard)
31
+ - **Unified Authority**: All core resource URIs migrated to `mcp://nexus/`.
32
+ - **New Resources**: Added `mcp://nexus/status` and `mcp://nexus/active-meeting`.
33
+
34
+ ## [v0.1.8] - 2025-12-30
35
+
36
+ ### ๐ŸŽฏ Meeting Architecture (Phase 1 & 2)
37
+ - **Hybrid Storage Backend**: Automatic selection between **SQLite** (preferred) and **JSON Fallback**.
38
+ - **SQLite Engine**: Powered by `better-sqlite3` with **WAL mode** for high-concurrency and multi-process safety.
39
+ - **New Lifecycle Entity**: `MeetingSession` replaces monolithic chat logs with discrete sessions.
40
+ - **Lifecycle Tools**:
41
+ - `start_meeting(topic)`: Creates dedicated session with unique ID and random entropy.
42
+ - `end_meeting(meetingId?, summary?)`: Closes meeting, collects decisions.
43
+ - `archive_meeting(meetingId)`: Moves sessions to historical archives.
44
+ - `list_meetings(status?)`: Filtered discovery of sessions.
45
+ - `read_meeting(meetingId)`: Detailed retrieval of history, participants, and decisions.
46
+
47
+ ### ๐Ÿ—๏ธ API & Storage Improvements
48
+ - **Structured JSON Responses**: Meeting tools now return machine-readable JSON for better agent integration.
49
+ - **Smart Auto-Routing**: Global discussion messages are automatically routed to active meetings.
50
+ - **ID Generation**: Robust slug generation with Base64 fallback for non-ASCII topics (Chinese/Unicode).
51
+ - **Concurrency Control**: Shared `AsyncMutex` utility and native SQLite locking.
52
+ - **Status Reporting**: `mcp://nexus/status` now reports `storage_mode` and `is_degraded` flags.
53
+
54
+ ### ๐Ÿงช Quality Assurance
55
+ - **Comprehensive Test Suite**: Added 24+ integration and stress tests (100% Green).
56
+ - **Concurrency Stress Tests**: Validated data integrity under rapid message bursts.
57
+ - **Fallback Verification**: Confirmed system stability when native modules are unavailable.
58
+
59
+ ### ๐Ÿ›ก๏ธ Security
60
+ - **Hardened Project Deletion**: Renamed `delete_project` to `moderator_delete_project` and enforced explicit moderator validation to prevent unauthorized project destruction.
61
+ - **Path Sanitization**: Enhanced error handling to strip absolute local file paths from MCP error messages.
62
+
63
+ ### ๐Ÿ“„ Resources & Documentation
64
+ - **New Resource**: Added `mcp://nexus/active-meeting` for instant access to the current meeting transcript and decisions.
65
+ - **Improved Tooling UX**: Documented return value structures and administrative requirements in tool definitions.
66
+ - **Manuals**: Updated `ASSISTANT_GUIDE.md` and both README versions with new admin tool documentation and Phase 2 best practices.
67
+
68
+ ## [v0.1.7] - 2025-12-30
69
+
70
+ ### โš™๏ธ CLI Simplification
71
+ - **Moderator flag**: Replaced `--moderator-id <id>` with simple `--moderator` boolean flag.
72
+ - Moderator: `--id Master-AI --moderator`
73
+ - Regular AI: `--id Assistant-AI` (no extra flag needed)
74
+
75
+ ### โœ… Tests
76
+ - Added session resource tests for role verification (Moderator/Regular).
77
+ - All 17 unit tests passing.
78
+
79
+ ## [v0.1.6] - 2025-12-29
80
+
81
+ ### ๐Ÿ”’ Concurrency Safety
82
+ - **AsyncMutex Lock**: Implemented mutex-based concurrency control to prevent race conditions during simultaneous file writes.
83
+ - Protected write operations:
84
+ - Discussion: `addGlobalLog()`, `pruneGlobalLogs()`, `clearGlobalLogs()`
85
+ - Registry: `saveProjectManifest()`, `renameProject()`, `deleteProject()`
86
+
87
+ ### ๐Ÿ“ฆ Schema v2.0
88
+ - **Manifest Schema Enhancements**: Added new optional fields for enterprise coordination:
89
+ - `apiDependencies`: Map of projectId to version constraint (e.g., `">=v2.1"`)
90
+ - `gatewayCompatibility`: Gateway version compatibility string
91
+ - `api_versions`: Feature-level API versions
92
+ - `feature_tier`: Capability tier declaration (`"free"` | `"pro"` | `"enterprise"`)
93
+
94
+ ## [v0.1.5] - 2025-12-29
95
+
96
+ ### ๐Ÿš€ Major Features
97
+ - **Project ID Naming Convention**: Enforced `[prefix]_[technical-name]` standard with 13 type prefixes (web_, api_, chrome_, vscode_, mcp_, android_, ios_, flutter_, desktop_, lib_, bot_, infra_, doc_).
98
+ - **MCP Prompts Capability**: Added `init_project_nexus` prompt for guiding AI through proper project registration workflow.
99
+ - **delete_project Tool**: New admin tool for complete project removal (manifest, assets, registry entry).
100
+
101
+ ### ๐Ÿ”’ Guardrails
102
+ - Added `validateProjectId()` with runtime regex validation in `handleRegisterSession`, `handleSyncProjectAssets`, and `handleRenameProject`.
103
+ - Projects with invalid ID formats are now rejected at the API level.
104
+
105
+ ### โœจ Enhancements
106
+ - Resource names now display project type icons (e.g., "๐ŸŒ Website: web_example.com").
107
+ - Handler unit tests expanded to cover delete, rename, and validation scenarios.
108
+
109
+ ### ๐Ÿ“„ Documentation
110
+ - Added "Project ID Conventions" section to README.md.
111
+ - Updated tool descriptions with Prefix Dictionary guidance.
112
+
113
+ ## [v0.1.4] - 2025-12-29
114
+
115
+ ### ๐Ÿ› Bug Fix
116
+ - Added shebang (`#!/usr/bin/env node`) to fix npx execution on Windows.
117
+
118
+ ## [v0.1.3] - 2025-12-29
119
+
120
+ ### ๐Ÿ”ง CI/CD
121
+ - Switched to npm Trusted Publishing (OIDC) - no more NPM_TOKEN needed.
122
+ - Upgraded to Node.js 22 for npm 11.5.1+ support.
123
+ - Added `--provenance` flag for supply chain security.
124
+
125
+ ## [v0.1.2] - 2025-12-29
126
+
127
+ ### ๐Ÿ”ง Refactoring
128
+ - Modularized codebase into `tools/`, `resources/`, and `storage/` modules.
129
+ - Reduced `index.ts` from 535 to 115 lines.
130
+ - Moved tests from `src/__tests__/` to top-level `tests/` directory.
131
+
132
+ ### ๐Ÿ“ฆ CI/CD
133
+ - Changed GitHub Actions trigger from `release` to tag push (`v*`).
134
+
135
+ ### ๐Ÿ“„ Documentation
136
+ - Added npm downloads badge.
137
+ - Fixed repository URLs to `n2n-nexus`.
138
+
139
+ ## [v0.1.1] - 2025-12-29
140
+
141
+ ### ๐Ÿ“ฆ npm Release
142
+ - Published to npm as `@datafrog-io/n2n-nexus`.
143
+ - Updated README with `npx` configuration for easy MCP integration.
144
+ - Added CLI arguments documentation table.
145
+
146
+ ## [v0.1.0] - 2025-12-29
147
+
148
+ ### ๐Ÿš€ Major Features
149
+ - **Project Asset Hub**: Centralized storage for Project Manifests, Internal Docs, and Assets (Images/Files).
150
+ - **Communication Channels**:
151
+ - `mcp://chat/global`: Real-time inter-agent messaging stream.
152
+ - `post_global_discussion`: Broadcast tool for coordination.
153
+ - **Topology Engine**:
154
+ - `get_global_topology`: Auto-generates dependency graphs based on manifest `relations`.
155
+ - **Global Knowledge Base**:
156
+ - New `docs/` directory structure for shared standards.
157
+ - Tools: `sync_global_doc`, `read_global_doc`, `list_global_docs`.
158
+ - **Self-Healing Storage**:
159
+ - Automatic repair of corrupted JSON registries or logs.
160
+ - Safe-defaults for missing configurations.
161
+
162
+ ### ๐Ÿ› ๏ธ Tooling
163
+ - Added `update_project` for partial manifest patches.
164
+ - Added `rename_project` with auto-cascading reference updates across all projects.
165
+ - Added `register_session_context` for IDE session binding.
166
+ - Added `moderator_maintenance` for log pruning.
167
+
168
+ ### ๐Ÿ“š Documentation
169
+ - Updated `README.md` with complete architecture diagrams and data persistence details.
170
+ - Added `ASSISTANT_GUIDE.md` for AI-to-AI operational protocols.