@gwdn/nexus-mcp 0.8.7 → 0.8.9

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.
Files changed (53) hide show
  1. package/dist/server.js +1 -1
  2. package/dist/tools/create-task.d.ts +1 -1
  3. package/dist/tools/create-task.js +3 -3
  4. package/dist/tools/directives.d.ts +2 -2
  5. package/dist/tools/letters.d.ts +1 -1
  6. package/dist/tools/update-task-status.d.ts +1 -1
  7. package/package.json +8 -2
  8. package/.github/workflows/ci.yml +0 -38
  9. package/.github/workflows/release.yml +0 -57
  10. package/src/__tests__/auth.test.ts +0 -162
  11. package/src/__tests__/decision-comments.test.ts +0 -173
  12. package/src/__tests__/e2e-integration.test.ts +0 -443
  13. package/src/__tests__/helpers.ts +0 -58
  14. package/src/__tests__/layer1-knowledge.test.ts +0 -302
  15. package/src/__tests__/layer2-coordination.test.ts +0 -918
  16. package/src/__tests__/layer3-governance.test.ts +0 -205
  17. package/src/__tests__/machine-id.test.ts +0 -136
  18. package/src/__tests__/nexus-api.test.ts +0 -127
  19. package/src/__tests__/project-list-and-skill-assign.test.ts +0 -282
  20. package/src/__tests__/reviews.test.ts +0 -420
  21. package/src/__tests__/server.test.ts +0 -251
  22. package/src/__tests__/setup.ts +0 -15
  23. package/src/__tests__/task-list-and-doc-list.test.ts +0 -226
  24. package/src/auth.ts +0 -81
  25. package/src/machine-id.ts +0 -60
  26. package/src/nexus-api.ts +0 -149
  27. package/src/server.ts +0 -629
  28. package/src/tools/add-task-note.ts +0 -50
  29. package/src/tools/append-session-entry.ts +0 -113
  30. package/src/tools/classify-document.ts +0 -55
  31. package/src/tools/create-task.ts +0 -66
  32. package/src/tools/decision-comments.ts +0 -103
  33. package/src/tools/delete-document.ts +0 -43
  34. package/src/tools/directives.ts +0 -303
  35. package/src/tools/get-document.ts +0 -80
  36. package/src/tools/get-project-memory.ts +0 -65
  37. package/src/tools/get-related-entities.ts +0 -73
  38. package/src/tools/governance.ts +0 -165
  39. package/src/tools/ingest-document.ts +0 -65
  40. package/src/tools/letter-inbox.ts +0 -157
  41. package/src/tools/letters.ts +0 -144
  42. package/src/tools/list-documents.ts +0 -58
  43. package/src/tools/list-tasks.ts +0 -57
  44. package/src/tools/project-list.ts +0 -52
  45. package/src/tools/reviews.ts +0 -281
  46. package/src/tools/search-knowledge.ts +0 -68
  47. package/src/tools/sessions.ts +0 -157
  48. package/src/tools/skill-assign.ts +0 -142
  49. package/src/tools/skills.ts +0 -255
  50. package/src/tools/update-document.ts +0 -66
  51. package/src/tools/update-task-status.ts +0 -64
  52. package/tsconfig.json +0 -21
  53. package/vitest.config.ts +0 -8
@@ -1,157 +0,0 @@
1
- /**
2
- * Session lifecycle tools -- Layer 2 Coordination
3
- *
4
- * session_create: Start a new work session for a project
5
- * session_close: End a session with summary and next entry point
6
- * session_list: List open sessions for a project
7
- *
8
- * Delegates to POST /api/mcp/sessions.
9
- */
10
-
11
- import { z } from 'zod'
12
- import { nexusPost } from '../nexus-api.js'
13
-
14
- // ---------------------------------------------------------------------------
15
- // create_session -> session_create
16
- // ---------------------------------------------------------------------------
17
-
18
- export const createSessionSchema = {
19
- project_id: z.string().uuid().describe('Project UUID'),
20
- title: z.string().max(500).describe('Session title (e.g., "Architecture review")'),
21
- agent_id: z
22
- .string()
23
- .max(200)
24
- .optional()
25
- .describe('Agent identifier starting this session'),
26
- }
27
-
28
- type CreateSessionArgs = {
29
- project_id: string
30
- title: string
31
- agent_id?: string
32
- user_id: string
33
- }
34
-
35
- export async function createSession(args: CreateSessionArgs) {
36
- const result = await nexusPost('/api/mcp/sessions', {
37
- action: 'session_create',
38
- project_id: args.project_id,
39
- title: args.title,
40
- })
41
-
42
- if (!result.ok) {
43
- return {
44
- content: [
45
- {
46
- type: 'text' as const,
47
- text: JSON.stringify({ error: result.error }, null, 2),
48
- },
49
- ],
50
- isError: true,
51
- }
52
- }
53
-
54
- return {
55
- content: [
56
- { type: 'text' as const, text: JSON.stringify(result.data, null, 2) },
57
- ],
58
- }
59
- }
60
-
61
- // ---------------------------------------------------------------------------
62
- // close_session -> session_close
63
- // ---------------------------------------------------------------------------
64
-
65
- export const closeSessionSchema = {
66
- session_id: z.string().uuid().describe('Session UUID to close'),
67
- summary: z
68
- .string()
69
- .max(100_000)
70
- .optional()
71
- .describe('Summary of what was accomplished in the session'),
72
- next_entry_point: z
73
- .string()
74
- .max(10_000)
75
- .optional()
76
- .describe('Suggested starting point for the next session'),
77
- }
78
-
79
- type CloseSessionArgs = {
80
- session_id: string
81
- summary?: string
82
- next_entry_point?: string
83
- user_id: string
84
- }
85
-
86
- export async function closeSession(args: CloseSessionArgs) {
87
- const result = await nexusPost('/api/mcp/sessions', {
88
- action: 'session_close',
89
- session_id: args.session_id,
90
- summary: args.summary,
91
- next_entry_point: args.next_entry_point,
92
- })
93
-
94
- if (!result.ok) {
95
- return {
96
- content: [
97
- {
98
- type: 'text' as const,
99
- text: JSON.stringify({ error: result.error }, null, 2),
100
- },
101
- ],
102
- isError: true,
103
- }
104
- }
105
-
106
- return {
107
- content: [
108
- { type: 'text' as const, text: JSON.stringify(result.data, null, 2) },
109
- ],
110
- }
111
- }
112
-
113
- // ---------------------------------------------------------------------------
114
- // list_open_sessions -> session_list
115
- // ---------------------------------------------------------------------------
116
-
117
- export const listOpenSessionsSchema = {
118
- project_id: z.string().uuid().describe('Project UUID'),
119
- limit: z
120
- .number()
121
- .int()
122
- .min(1)
123
- .max(100)
124
- .default(25)
125
- .describe('Maximum number of sessions to return (default 25)'),
126
- }
127
-
128
- type ListOpenSessionsArgs = {
129
- project_id: string
130
- limit?: number
131
- }
132
-
133
- export async function listOpenSessions(args: ListOpenSessionsArgs) {
134
- const result = await nexusPost('/api/mcp/sessions', {
135
- action: 'session_list',
136
- project_id: args.project_id,
137
- limit: args.limit ?? 25,
138
- })
139
-
140
- if (!result.ok) {
141
- return {
142
- content: [
143
- {
144
- type: 'text' as const,
145
- text: JSON.stringify({ error: result.error }, null, 2),
146
- },
147
- ],
148
- isError: true,
149
- }
150
- }
151
-
152
- return {
153
- content: [
154
- { type: 'text' as const, text: JSON.stringify(result.data, null, 2) },
155
- ],
156
- }
157
- }
@@ -1,142 +0,0 @@
1
- /**
2
- * sk_assign + sk_unassign + sk_export -- Layer 2 Coordination
3
- *
4
- * Skill-project assignment management tools for the Nexus platform.
5
- * Delegates to POST /api/mcp/skills.
6
- */
7
-
8
- import { z } from 'zod'
9
- import { nexusPost } from '../nexus-api.js'
10
-
11
- // ---------------------------------------------------------------------------
12
- // sk_assign
13
- // ---------------------------------------------------------------------------
14
-
15
- export const skAssignSchema = {
16
- project_id: z.string().uuid().describe('Project UUID'),
17
- skill_id: z.string().max(200).describe('Skill identifier or UUID'),
18
- pinned_version: z
19
- .number()
20
- .int()
21
- .optional()
22
- .describe('Pin to a specific skill version'),
23
- enabled: z
24
- .boolean()
25
- .optional()
26
- .describe('Whether the assignment is enabled (default: true)'),
27
- }
28
-
29
- type SkAssignArgs = {
30
- project_id: string
31
- skill_id: string
32
- pinned_version?: number
33
- enabled?: boolean
34
- user_id: string
35
- }
36
-
37
- export async function skAssign(args: SkAssignArgs) {
38
- const result = await nexusPost('/api/mcp/skills', {
39
- action: 'sk_assign',
40
- project_id: args.project_id,
41
- skill_id: args.skill_id,
42
- pinned_version: args.pinned_version,
43
- enabled: args.enabled,
44
- })
45
-
46
- if (!result.ok) {
47
- return {
48
- content: [
49
- {
50
- type: 'text' as const,
51
- text: JSON.stringify({ error: result.error }, null, 2),
52
- },
53
- ],
54
- isError: true,
55
- }
56
- }
57
-
58
- return {
59
- content: [
60
- { type: 'text' as const, text: JSON.stringify(result.data, null, 2) },
61
- ],
62
- }
63
- }
64
-
65
- // ---------------------------------------------------------------------------
66
- // sk_unassign
67
- // ---------------------------------------------------------------------------
68
-
69
- export const skUnassignSchema = {
70
- project_id: z.string().uuid().describe('Project UUID'),
71
- skill_id: z.string().max(200).describe('Skill identifier or UUID'),
72
- }
73
-
74
- type SkUnassignArgs = {
75
- project_id: string
76
- skill_id: string
77
- user_id: string
78
- }
79
-
80
- export async function skUnassign(args: SkUnassignArgs) {
81
- const result = await nexusPost('/api/mcp/skills', {
82
- action: 'sk_unassign',
83
- project_id: args.project_id,
84
- skill_id: args.skill_id,
85
- })
86
-
87
- if (!result.ok) {
88
- return {
89
- content: [
90
- {
91
- type: 'text' as const,
92
- text: JSON.stringify({ error: result.error }, null, 2),
93
- },
94
- ],
95
- isError: true,
96
- }
97
- }
98
-
99
- return {
100
- content: [
101
- { type: 'text' as const, text: JSON.stringify(result.data, null, 2) },
102
- ],
103
- }
104
- }
105
-
106
- // ---------------------------------------------------------------------------
107
- // sk_export
108
- // ---------------------------------------------------------------------------
109
-
110
- export const skExportSchema = {
111
- project_id: z.string().uuid().describe('Project UUID'),
112
- }
113
-
114
- type SkExportArgs = {
115
- project_id: string
116
- user_id: string
117
- }
118
-
119
- export async function skExport(args: SkExportArgs) {
120
- const result = await nexusPost('/api/mcp/skills', {
121
- action: 'sk_export',
122
- project_id: args.project_id,
123
- })
124
-
125
- if (!result.ok) {
126
- return {
127
- content: [
128
- {
129
- type: 'text' as const,
130
- text: JSON.stringify({ error: result.error }, null, 2),
131
- },
132
- ],
133
- isError: true,
134
- }
135
- }
136
-
137
- return {
138
- content: [
139
- { type: 'text' as const, text: JSON.stringify(result.data, null, 2) },
140
- ],
141
- }
142
- }
@@ -1,255 +0,0 @@
1
- /**
2
- * sk_list + sk_get + sk_create + sk_update + sk_activate -- Layer 2 Coordination
3
- *
4
- * Skill management tools for the Nexus platform.
5
- * Skills are tenant-scoped instruction sets for agent sessions.
6
- * Delegates to POST /api/mcp/skills.
7
- */
8
-
9
- import { z } from 'zod'
10
- import { nexusPost } from '../nexus-api.js'
11
-
12
- // ---------------------------------------------------------------------------
13
- // sk_list
14
- // ---------------------------------------------------------------------------
15
-
16
- export const skListSchema = {
17
- status_filter: z
18
- .array(z.enum(['draft', 'active', 'archived']))
19
- .optional()
20
- .describe('Filter by skill status (default: draft, active)'),
21
- limit: z
22
- .number()
23
- .min(1)
24
- .max(100)
25
- .default(50)
26
- .describe('Max number of skills to return'),
27
- }
28
-
29
- type SkListArgs = {
30
- status_filter?: string[]
31
- limit?: number
32
- user_id: string
33
- }
34
-
35
- export async function skList(args: SkListArgs) {
36
- const result = await nexusPost('/api/mcp/skills', {
37
- action: 'sk_list',
38
- status_filter: args.status_filter,
39
- limit: args.limit ?? 50,
40
- })
41
-
42
- if (!result.ok) {
43
- return {
44
- content: [
45
- {
46
- type: 'text' as const,
47
- text: JSON.stringify({ error: result.error }, null, 2),
48
- },
49
- ],
50
- isError: true,
51
- }
52
- }
53
-
54
- return {
55
- content: [
56
- { type: 'text' as const, text: JSON.stringify(result.data, null, 2) },
57
- ],
58
- }
59
- }
60
-
61
- // ---------------------------------------------------------------------------
62
- // sk_get
63
- // ---------------------------------------------------------------------------
64
-
65
- export const skGetSchema = {
66
- skill_id: z
67
- .string()
68
- .max(200)
69
- .describe('Skill identifier (e.g., nx-init-nexus) or UUID'),
70
- }
71
-
72
- type SkGetArgs = {
73
- skill_id: string
74
- user_id: string
75
- }
76
-
77
- export async function skGet(args: SkGetArgs) {
78
- const result = await nexusPost('/api/mcp/skills', {
79
- action: 'sk_get',
80
- skill_id: args.skill_id,
81
- })
82
-
83
- if (!result.ok) {
84
- return {
85
- content: [
86
- {
87
- type: 'text' as const,
88
- text: JSON.stringify({ error: result.error }, null, 2),
89
- },
90
- ],
91
- isError: true,
92
- }
93
- }
94
-
95
- return {
96
- content: [
97
- { type: 'text' as const, text: JSON.stringify(result.data, null, 2) },
98
- ],
99
- }
100
- }
101
-
102
- // ---------------------------------------------------------------------------
103
- // sk_create
104
- // ---------------------------------------------------------------------------
105
-
106
- export const skCreateSchema = {
107
- skill_id: z.string().max(200).describe('Skill identifier (e.g., nx-init-nexus)'),
108
- name: z.string().max(500).describe('Human-readable skill name'),
109
- description: z.string().max(1000).optional().describe('Short description'),
110
- body: z.string().max(100_000).describe('Full markdown instruction content'),
111
- auto_generate_command: z
112
- .boolean()
113
- .default(true)
114
- .describe('Auto-generate an OpenCode command (default: true)'),
115
- }
116
-
117
- type SkCreateArgs = {
118
- skill_id: string
119
- name: string
120
- description?: string
121
- body: string
122
- auto_generate_command?: boolean
123
- user_id: string
124
- }
125
-
126
- export async function skCreate(args: SkCreateArgs) {
127
- const result = await nexusPost('/api/mcp/skills', {
128
- action: 'sk_create',
129
- skill_id: args.skill_id,
130
- name: args.name,
131
- description: args.description,
132
- body: args.body,
133
- auto_generate_command: args.auto_generate_command ?? true,
134
- })
135
-
136
- if (!result.ok) {
137
- return {
138
- content: [
139
- {
140
- type: 'text' as const,
141
- text: JSON.stringify({ error: result.error }, null, 2),
142
- },
143
- ],
144
- isError: true,
145
- }
146
- }
147
-
148
- return {
149
- content: [
150
- { type: 'text' as const, text: JSON.stringify(result.data, null, 2) },
151
- ],
152
- }
153
- }
154
-
155
- // ---------------------------------------------------------------------------
156
- // sk_update
157
- // ---------------------------------------------------------------------------
158
-
159
- export const skUpdateSchema = {
160
- skill_id: z
161
- .string()
162
- .max(200)
163
- .describe('Skill identifier (e.g., nx-init-nexus) or UUID'),
164
- name: z.string().max(500).optional().describe('Updated name'),
165
- description: z.string().max(1000).optional().describe('Updated description'),
166
- body: z.string().max(100_000).optional().describe('Updated markdown content'),
167
- auto_generate_command: z
168
- .boolean()
169
- .optional()
170
- .describe('Toggle command auto-generation'),
171
- }
172
-
173
- type SkUpdateArgs = {
174
- skill_id: string
175
- name?: string
176
- description?: string
177
- body?: string
178
- auto_generate_command?: boolean
179
- user_id: string
180
- }
181
-
182
- export async function skUpdate(args: SkUpdateArgs) {
183
- const result = await nexusPost('/api/mcp/skills', {
184
- action: 'sk_update',
185
- skill_id: args.skill_id,
186
- name: args.name,
187
- description: args.description,
188
- body: args.body,
189
- auto_generate_command: args.auto_generate_command,
190
- })
191
-
192
- if (!result.ok) {
193
- return {
194
- content: [
195
- {
196
- type: 'text' as const,
197
- text: JSON.stringify({ error: result.error }, null, 2),
198
- },
199
- ],
200
- isError: true,
201
- }
202
- }
203
-
204
- return {
205
- content: [
206
- { type: 'text' as const, text: JSON.stringify(result.data, null, 2) },
207
- ],
208
- }
209
- }
210
-
211
- // ---------------------------------------------------------------------------
212
- // sk_activate
213
- // ---------------------------------------------------------------------------
214
-
215
- export const skActivateSchema = {
216
- skill_id: z
217
- .string()
218
- .max(200)
219
- .describe('Skill identifier (e.g., nx-init-nexus) or UUID'),
220
- status: z
221
- .enum(['active', 'archived', 'draft'])
222
- .describe('New status for the skill'),
223
- }
224
-
225
- type SkActivateArgs = {
226
- skill_id: string
227
- status: string
228
- user_id: string
229
- }
230
-
231
- export async function skActivate(args: SkActivateArgs) {
232
- const result = await nexusPost('/api/mcp/skills', {
233
- action: 'sk_activate',
234
- skill_id: args.skill_id,
235
- status: args.status,
236
- })
237
-
238
- if (!result.ok) {
239
- return {
240
- content: [
241
- {
242
- type: 'text' as const,
243
- text: JSON.stringify({ error: result.error }, null, 2),
244
- },
245
- ],
246
- isError: true,
247
- }
248
- }
249
-
250
- return {
251
- content: [
252
- { type: 'text' as const, text: JSON.stringify(result.data, null, 2) },
253
- ],
254
- }
255
- }
@@ -1,66 +0,0 @@
1
- /**
2
- * doc_update -- Layer 2 Coordination
3
- *
4
- * Update title, body, or source_url of an ingest item.
5
- * Supports full body replacement or append mode.
6
- * Delegates to POST /api/mcp/documents (action: doc_update).
7
- */
8
-
9
- import { z } from 'zod'
10
- import { nexusPost } from '../nexus-api.js'
11
-
12
- export const updateDocumentSchema = {
13
- document_id: z.string().uuid().describe('Document UUID to update'),
14
- title: z.string().max(500).optional().describe('New document title'),
15
- body: z
16
- .string()
17
- .max(100_000)
18
- .optional()
19
- .describe('New document body (replaces existing content)'),
20
- source_url: z.string().url().optional().describe('Updated source URL'),
21
- append_body: z
22
- .string()
23
- .max(100_000)
24
- .optional()
25
- .describe(
26
- 'Content to append to existing body (ignored if body is also provided)',
27
- ),
28
- }
29
-
30
- type UpdateDocumentArgs = {
31
- document_id: string
32
- title?: string
33
- body?: string
34
- source_url?: string
35
- append_body?: string
36
- user_id: string
37
- }
38
-
39
- export async function updateDocument(args: UpdateDocumentArgs) {
40
- const result = await nexusPost('/api/mcp/documents', {
41
- action: 'doc_update',
42
- document_id: args.document_id,
43
- title: args.title,
44
- body: args.body,
45
- source_url: args.source_url,
46
- append_body: args.append_body,
47
- })
48
-
49
- if (!result.ok) {
50
- return {
51
- content: [
52
- {
53
- type: 'text' as const,
54
- text: JSON.stringify({ error: result.error }, null, 2),
55
- },
56
- ],
57
- isError: true,
58
- }
59
- }
60
-
61
- return {
62
- content: [
63
- { type: 'text' as const, text: JSON.stringify(result.data, null, 2) },
64
- ],
65
- }
66
- }
@@ -1,64 +0,0 @@
1
- /**
2
- * task_update -- Layer 2 Coordination
3
- *
4
- * Updates the status (and optionally priority/assignee) of an existing task.
5
- * Delegates to POST /api/mcp/tasks (action: task_update).
6
- */
7
-
8
- import { z } from 'zod'
9
- import { nexusPost } from '../nexus-api.js'
10
-
11
- export const updateTaskStatusSchema = {
12
- task_id: z.string().uuid().describe('Task UUID to update'),
13
- status: z
14
- .enum(['open', 'in_progress', 'blocked', 'done', 'cancelled'])
15
- .describe('New task status'),
16
- priority: z
17
- .enum(['low', 'medium', 'high', 'urgent'])
18
- .optional()
19
- .describe('Updated priority (optional)'),
20
- assignee: z
21
- .string()
22
- .uuid()
23
- .optional()
24
- .describe('UUID of the newly assigned user (optional)'),
25
- agent_id: z.string().max(200).optional().describe('Agent identifier if applicable'),
26
- }
27
-
28
- type UpdateTaskStatusArgs = {
29
- task_id: string
30
- status: string
31
- priority?: string
32
- assignee?: string
33
- user_id: string
34
- agent_id?: string
35
- }
36
-
37
- export async function updateTaskStatus(args: UpdateTaskStatusArgs) {
38
- const result = await nexusPost('/api/mcp/tasks', {
39
- action: 'task_update',
40
- task_id: args.task_id,
41
- status: args.status,
42
- priority: args.priority,
43
- assignee: args.assignee,
44
- agent_id: args.agent_id,
45
- })
46
-
47
- if (!result.ok) {
48
- return {
49
- content: [
50
- {
51
- type: 'text' as const,
52
- text: JSON.stringify({ error: result.error }, null, 2),
53
- },
54
- ],
55
- isError: true,
56
- }
57
- }
58
-
59
- return {
60
- content: [
61
- { type: 'text' as const, text: JSON.stringify(result.data, null, 2) },
62
- ],
63
- }
64
- }
package/tsconfig.json DELETED
@@ -1,21 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "target": "ES2022",
4
- "module": "Node16",
5
- "moduleResolution": "Node16",
6
- "lib": ["ES2022"],
7
- "types": ["node"],
8
- "outDir": "dist",
9
- "rootDir": "src",
10
- "strict": true,
11
- "esModuleInterop": true,
12
- "skipLibCheck": true,
13
- "forceConsistentCasingInFileNames": true,
14
- "resolveJsonModule": true,
15
- "declaration": true,
16
- "declarationMap": true,
17
- "sourceMap": true
18
- },
19
- "include": ["src/**/*.ts"],
20
- "exclude": ["node_modules", "dist", "src/__tests__"]
21
- }
package/vitest.config.ts DELETED
@@ -1,8 +0,0 @@
1
- import { defineConfig } from 'vitest/config'
2
-
3
- export default defineConfig({
4
- test: {
5
- globals: true,
6
- setupFiles: ['./src/__tests__/setup.ts'],
7
- },
8
- })