@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,113 +0,0 @@
1
- /**
2
- * session_append -- Layer 2 Coordination
3
- *
4
- * Appends an entry to an existing session.
5
- * Enforces append-only semantics and session write isolation.
6
- * Delegates to POST /api/mcp/sessions (action: session_append).
7
- */
8
-
9
- import { z } from 'zod'
10
- import { nexusPost } from '../nexus-api.js'
11
-
12
- export const appendSessionEntrySchema = {
13
- session_id: z.string().uuid().describe('Session UUID to append to'),
14
- entry_type: z
15
- .enum([
16
- 'decision_referenced',
17
- 'task_created',
18
- 'task_updated',
19
- 'letter_sent',
20
- 'letter_replied',
21
- 'research_added',
22
- 'conflict_detected',
23
- 'adr_drafted',
24
- 'adr_accepted',
25
- 'handoff_recorded',
26
- 'note',
27
- 'correction',
28
- 'security_scan',
29
- 'performance_scan',
30
- ])
31
- .describe('Type of session entry'),
32
- summary: z.string().max(100_000).describe('Entry content / summary text'),
33
- linked_entity_type: z
34
- .string()
35
- .max(50)
36
- .optional()
37
- .describe(
38
- 'Type of linked entity (e.g., "task", "decision", "letter", "research_link")',
39
- ),
40
- linked_entity_id: z
41
- .string()
42
- .uuid()
43
- .optional()
44
- .describe('UUID of the linked entity'),
45
- agent_id: z.string().max(200).optional().describe('Agent identifier if applicable'),
46
- metadata: z
47
- .string()
48
- .max(10_000)
49
- .optional()
50
- .describe(
51
- 'JSON string of metadata to merge into the session entry. ' +
52
- 'Example: \'{"model": "claude-opus-4", "toolstack": "opencode", "machine_id": "..."}\'',
53
- ),
54
- }
55
-
56
- type AppendSessionEntryArgs = {
57
- session_id: string
58
- entry_type: string
59
- summary: string
60
- linked_entity_type?: string
61
- linked_entity_id?: string
62
- user_id: string
63
- agent_id?: string
64
- metadata?: string
65
- }
66
-
67
- export async function appendSessionEntry(args: AppendSessionEntryArgs) {
68
- let parsedMetadata: Record<string, unknown> | undefined
69
- if (args.metadata) {
70
- try {
71
- parsedMetadata = JSON.parse(args.metadata)
72
- } catch {
73
- return {
74
- content: [
75
- {
76
- type: 'text' as const,
77
- text: JSON.stringify({ error: 'metadata must be a valid JSON string' }, null, 2),
78
- },
79
- ],
80
- isError: true,
81
- }
82
- }
83
- }
84
-
85
- const result = await nexusPost('/api/mcp/sessions', {
86
- action: 'session_append',
87
- session_id: args.session_id,
88
- entry_type: args.entry_type,
89
- summary: args.summary,
90
- agent_id: args.agent_id,
91
- linked_entity_type: args.linked_entity_type,
92
- linked_entity_id: args.linked_entity_id,
93
- ...(parsedMetadata ? { metadata: parsedMetadata } : {}),
94
- })
95
-
96
- if (!result.ok) {
97
- return {
98
- content: [
99
- {
100
- type: 'text' as const,
101
- text: JSON.stringify({ error: result.error }, null, 2),
102
- },
103
- ],
104
- isError: true,
105
- }
106
- }
107
-
108
- return {
109
- content: [
110
- { type: 'text' as const, text: JSON.stringify(result.data, null, 2) },
111
- ],
112
- }
113
- }
@@ -1,55 +0,0 @@
1
- /**
2
- * doc_classify -- Layer 2 Coordination
3
- *
4
- * Update the classification of an ingest item.
5
- * Delegates to POST /api/mcp/documents (action: doc_classify).
6
- */
7
-
8
- import { z } from 'zod'
9
- import { nexusPost } from '../nexus-api.js'
10
-
11
- export const classifyDocumentSchema = {
12
- document_id: z.string().uuid().describe('Document UUID to classify'),
13
- classification: z
14
- .enum([
15
- 'unclassified',
16
- 'research_note',
17
- 'planning_item',
18
- 'decision_input',
19
- 'reference',
20
- 'archive',
21
- ])
22
- .describe('New classification for the document'),
23
- }
24
-
25
- type ClassifyDocumentArgs = {
26
- document_id: string
27
- classification: string
28
- user_id: string
29
- }
30
-
31
- export async function classifyDocument(args: ClassifyDocumentArgs) {
32
- const result = await nexusPost('/api/mcp/documents', {
33
- action: 'doc_classify',
34
- document_id: args.document_id,
35
- classification: args.classification,
36
- })
37
-
38
- if (!result.ok) {
39
- return {
40
- content: [
41
- {
42
- type: 'text' as const,
43
- text: JSON.stringify({ error: result.error }, null, 2),
44
- },
45
- ],
46
- isError: true,
47
- }
48
- }
49
-
50
- return {
51
- content: [
52
- { type: 'text' as const, text: JSON.stringify(result.data, null, 2) },
53
- ],
54
- }
55
- }
@@ -1,66 +0,0 @@
1
- /**
2
- * task_create -- Layer 2 Coordination
3
- *
4
- * Creates a new task within a project scope.
5
- * Delegates to POST /api/mcp/tasks (action: task_create).
6
- */
7
-
8
- import { z } from 'zod'
9
- import { nexusPost } from '../nexus-api.js'
10
-
11
- export const createTaskSchema = {
12
- project_id: z.string().uuid().describe('Project UUID'),
13
- title: z.string().max(500).describe('Task title'),
14
- description: z.string().max(100_000).optional().describe('Task description'),
15
- priority: z
16
- .enum(['low', 'normal', 'high', 'urgent'])
17
- .default('normal')
18
- .describe('Task priority'),
19
- assignee: z.string().uuid().optional().describe('UUID of the assigned user'),
20
- status: z
21
- .enum(['open', 'in_progress', 'blocked', 'done', 'cancelled'])
22
- .default('open')
23
- .describe('Initial task status'),
24
- agent_id: z.string().max(200).optional().describe('Agent identifier if applicable'),
25
- }
26
-
27
- type CreateTaskArgs = {
28
- project_id: string
29
- title: string
30
- description?: string
31
- priority?: string
32
- assignee?: string
33
- status?: string
34
- user_id: string
35
- agent_id?: string
36
- }
37
-
38
- export async function createTask(args: CreateTaskArgs) {
39
- const result = await nexusPost('/api/mcp/tasks', {
40
- action: 'task_create',
41
- project_id: args.project_id,
42
- title: args.title,
43
- description: args.description,
44
- priority: args.priority ?? 'normal',
45
- assignee: args.assignee,
46
- status: args.status ?? 'open',
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,103 +0,0 @@
1
- /**
2
- * Decision comment tools -- Layer 2 Coordination
3
- *
4
- * Provides append-only comment threads for ADR decisions.
5
- * Delegates to POST /api/mcp/governance (actions: dc_add, dc_list).
6
- */
7
-
8
- import { z } from 'zod'
9
- import { nexusPost } from '../nexus-api.js'
10
-
11
- // ---------------------------------------------------------------------------
12
- // add_decision_comment -> dc_add
13
- // ---------------------------------------------------------------------------
14
-
15
- export const addDecisionCommentSchema = {
16
- decision_id: z.string().uuid().describe('Decision UUID to comment on'),
17
- body: z.string().max(100_000).describe('Comment body (markdown supported)'),
18
- agent_id: z
19
- .string()
20
- .max(200)
21
- .optional()
22
- .describe('Agent identifier if comment is posted by an agent'),
23
- }
24
-
25
- type AddDecisionCommentArgs = {
26
- decision_id: string
27
- body: string
28
- agent_id?: string
29
- user_id: string
30
- }
31
-
32
- export async function addDecisionComment(args: AddDecisionCommentArgs) {
33
- const result = await nexusPost('/api/mcp/governance', {
34
- action: 'dc_add',
35
- decision_id: args.decision_id,
36
- body: args.body,
37
- agent_id: args.agent_id,
38
- })
39
-
40
- if (!result.ok) {
41
- return {
42
- content: [
43
- {
44
- type: 'text' as const,
45
- text: JSON.stringify({ error: result.error }, null, 2),
46
- },
47
- ],
48
- isError: true,
49
- }
50
- }
51
-
52
- return {
53
- content: [
54
- { type: 'text' as const, text: JSON.stringify(result.data, null, 2) },
55
- ],
56
- }
57
- }
58
-
59
- // ---------------------------------------------------------------------------
60
- // list_decision_comments -> dc_list
61
- // ---------------------------------------------------------------------------
62
-
63
- export const listDecisionCommentsSchema = {
64
- decision_id: z.string().uuid().describe('Decision UUID'),
65
- limit: z
66
- .number()
67
- .int()
68
- .min(1)
69
- .max(100)
70
- .default(50)
71
- .describe('Maximum comments to return'),
72
- }
73
-
74
- type ListDecisionCommentsArgs = {
75
- decision_id: string
76
- limit?: number
77
- }
78
-
79
- export async function listDecisionComments(args: ListDecisionCommentsArgs) {
80
- const result = await nexusPost('/api/mcp/governance', {
81
- action: 'dc_list',
82
- decision_id: args.decision_id,
83
- limit: args.limit ?? 50,
84
- })
85
-
86
- if (!result.ok) {
87
- return {
88
- content: [
89
- {
90
- type: 'text' as const,
91
- text: JSON.stringify({ error: result.error }, null, 2),
92
- },
93
- ],
94
- isError: true,
95
- }
96
- }
97
-
98
- return {
99
- content: [
100
- { type: 'text' as const, text: JSON.stringify(result.data, null, 2) },
101
- ],
102
- }
103
- }
@@ -1,43 +0,0 @@
1
- /**
2
- * doc_delete -- Layer 2 Coordination
3
- *
4
- * Delete an ingest item from a project's knowledge base.
5
- * Delegates to POST /api/mcp/documents (action: doc_delete).
6
- */
7
-
8
- import { z } from 'zod'
9
- import { nexusPost } from '../nexus-api.js'
10
-
11
- export const deleteDocumentSchema = {
12
- document_id: z.string().uuid().describe('Document UUID to delete'),
13
- }
14
-
15
- type DeleteDocumentArgs = {
16
- document_id: string
17
- user_id: string
18
- }
19
-
20
- export async function deleteDocument(args: DeleteDocumentArgs) {
21
- const result = await nexusPost('/api/mcp/documents', {
22
- action: 'doc_delete',
23
- document_id: args.document_id,
24
- })
25
-
26
- if (!result.ok) {
27
- return {
28
- content: [
29
- {
30
- type: 'text' as const,
31
- text: JSON.stringify({ error: result.error }, null, 2),
32
- },
33
- ],
34
- isError: true,
35
- }
36
- }
37
-
38
- return {
39
- content: [
40
- { type: 'text' as const, text: JSON.stringify(result.data, null, 2) },
41
- ],
42
- }
43
- }
@@ -1,303 +0,0 @@
1
- /**
2
- * pd_list + pd_get + pd_create + pd_update + pd_delete + pd_toggle + directive_export
3
- *
4
- * Project Directives management tools for the Nexus platform.
5
- * Directives are project-scoped rules/policies that guide agent behavior.
6
- * Delegates to POST /api/mcp/directives.
7
- */
8
-
9
- import { z } from 'zod'
10
- import { nexusPost } from '../nexus-api.js'
11
-
12
- // ---------------------------------------------------------------------------
13
- // Shared helpers
14
- // ---------------------------------------------------------------------------
15
-
16
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
17
- function errorResult(result: { error: string | null }) {
18
- return {
19
- content: [
20
- {
21
- type: 'text' as const,
22
- text: JSON.stringify({ error: result.error }, null, 2),
23
- },
24
- ],
25
- isError: true,
26
- }
27
- }
28
-
29
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
30
- function okResult(data: any) {
31
- return {
32
- content: [
33
- { type: 'text' as const, text: JSON.stringify(data, null, 2) },
34
- ],
35
- }
36
- }
37
-
38
- // ---------------------------------------------------------------------------
39
- // pd_list
40
- // ---------------------------------------------------------------------------
41
-
42
- export const pdListSchema = {
43
- project_id: z
44
- .string()
45
- .uuid()
46
- .describe('Project UUID'),
47
- enabled: z
48
- .boolean()
49
- .optional()
50
- .describe('Filter by enabled status'),
51
- limit: z
52
- .number()
53
- .min(1)
54
- .max(100)
55
- .default(50)
56
- .describe('Maximum results to return'),
57
- }
58
-
59
- type PdListArgs = {
60
- project_id: string
61
- enabled?: boolean
62
- limit?: number
63
- user_id: string
64
- }
65
-
66
- export async function pdList(args: PdListArgs) {
67
- const result = await nexusPost('/api/mcp/directives', {
68
- action: 'pd_list',
69
- project_id: args.project_id,
70
- enabled: args.enabled,
71
- limit: args.limit ?? 50,
72
- })
73
-
74
- if (!result.ok) return errorResult(result)
75
- return okResult(result.data)
76
- }
77
-
78
- // ---------------------------------------------------------------------------
79
- // pd_get
80
- // ---------------------------------------------------------------------------
81
-
82
- export const pdGetSchema = {
83
- directive_id: z
84
- .string()
85
- .uuid()
86
- .describe('Directive UUID'),
87
- }
88
-
89
- type PdGetArgs = {
90
- directive_id: string
91
- user_id: string
92
- }
93
-
94
- export async function pdGet(args: PdGetArgs) {
95
- const result = await nexusPost('/api/mcp/directives', {
96
- action: 'pd_get',
97
- directive_id: args.directive_id,
98
- })
99
-
100
- if (!result.ok) return errorResult(result)
101
- return okResult(result.data)
102
- }
103
-
104
- // ---------------------------------------------------------------------------
105
- // pd_create
106
- // ---------------------------------------------------------------------------
107
-
108
- export const pdCreateSchema = {
109
- project_id: z
110
- .string()
111
- .uuid()
112
- .describe('Project UUID'),
113
- title: z
114
- .string()
115
- .max(500)
116
- .describe('Directive title'),
117
- body: z
118
- .string()
119
- .max(10000)
120
- .optional()
121
- .describe('Directive body (markdown)'),
122
- category: z
123
- .string()
124
- .max(100)
125
- .default('general')
126
- .describe('Directive category (e.g. general, security, deployment)'),
127
- priority: z
128
- .enum(['low', 'medium', 'high'])
129
- .default('medium')
130
- .describe('Directive priority'),
131
- enabled: z
132
- .boolean()
133
- .default(true)
134
- .describe('Whether the directive is enabled'),
135
- }
136
-
137
- type PdCreateArgs = {
138
- project_id: string
139
- title: string
140
- body?: string
141
- category?: string
142
- priority?: string
143
- enabled?: boolean
144
- user_id: string
145
- }
146
-
147
- export async function pdCreate(args: PdCreateArgs) {
148
- const result = await nexusPost('/api/mcp/directives', {
149
- action: 'pd_create',
150
- project_id: args.project_id,
151
- title: args.title,
152
- body: args.body,
153
- category: args.category ?? 'general',
154
- priority: args.priority ?? 'medium',
155
- enabled: args.enabled !== false,
156
- })
157
-
158
- if (!result.ok) return errorResult(result)
159
- return okResult(result.data)
160
- }
161
-
162
- // ---------------------------------------------------------------------------
163
- // pd_update
164
- // ---------------------------------------------------------------------------
165
-
166
- export const pdUpdateSchema = {
167
- directive_id: z
168
- .string()
169
- .uuid()
170
- .describe('Directive UUID'),
171
- title: z
172
- .string()
173
- .max(500)
174
- .optional()
175
- .describe('Updated title'),
176
- body: z
177
- .string()
178
- .max(10000)
179
- .optional()
180
- .describe('Updated body (markdown)'),
181
- category: z
182
- .string()
183
- .max(100)
184
- .optional()
185
- .describe('Updated category'),
186
- priority: z
187
- .enum(['low', 'medium', 'high'])
188
- .optional()
189
- .describe('Updated priority'),
190
- enabled: z
191
- .boolean()
192
- .optional()
193
- .describe('Updated enabled state'),
194
- }
195
-
196
- type PdUpdateArgs = {
197
- directive_id: string
198
- title?: string
199
- body?: string
200
- category?: string
201
- priority?: string
202
- enabled?: boolean
203
- user_id: string
204
- }
205
-
206
- export async function pdUpdate(args: PdUpdateArgs) {
207
- const result = await nexusPost('/api/mcp/directives', {
208
- action: 'pd_update',
209
- directive_id: args.directive_id,
210
- title: args.title,
211
- body: args.body,
212
- category: args.category,
213
- priority: args.priority,
214
- enabled: args.enabled,
215
- })
216
-
217
- if (!result.ok) return errorResult(result)
218
- return okResult(result.data)
219
- }
220
-
221
- // ---------------------------------------------------------------------------
222
- // pd_delete
223
- // ---------------------------------------------------------------------------
224
-
225
- export const pdDeleteSchema = {
226
- directive_id: z
227
- .string()
228
- .uuid()
229
- .describe('Directive UUID to delete'),
230
- }
231
-
232
- type PdDeleteArgs = {
233
- directive_id: string
234
- user_id: string
235
- }
236
-
237
- export async function pdDelete(args: PdDeleteArgs) {
238
- const result = await nexusPost('/api/mcp/directives', {
239
- action: 'pd_delete',
240
- directive_id: args.directive_id,
241
- })
242
-
243
- if (!result.ok) return errorResult(result)
244
- return okResult(result.data)
245
- }
246
-
247
- // ---------------------------------------------------------------------------
248
- // pd_toggle
249
- // ---------------------------------------------------------------------------
250
-
251
- export const pdToggleSchema = {
252
- directive_id: z
253
- .string()
254
- .uuid()
255
- .describe('Directive UUID to toggle'),
256
- enabled: z
257
- .boolean()
258
- .optional()
259
- .describe('Explicit enabled state (omit to invert current)'),
260
- }
261
-
262
- type PdToggleArgs = {
263
- directive_id: string
264
- enabled?: boolean
265
- user_id: string
266
- }
267
-
268
- export async function pdToggle(args: PdToggleArgs) {
269
- const result = await nexusPost('/api/mcp/directives', {
270
- action: 'pd_toggle',
271
- directive_id: args.directive_id,
272
- enabled: args.enabled,
273
- })
274
-
275
- if (!result.ok) return errorResult(result)
276
- return okResult(result.data)
277
- }
278
-
279
- // ---------------------------------------------------------------------------
280
- // directive_export
281
- // ---------------------------------------------------------------------------
282
-
283
- export const directiveExportSchema = {
284
- project_id: z
285
- .string()
286
- .uuid()
287
- .describe('Project UUID'),
288
- }
289
-
290
- type DirectiveExportArgs = {
291
- project_id: string
292
- user_id: string
293
- }
294
-
295
- export async function directiveExport(args: DirectiveExportArgs) {
296
- const result = await nexusPost('/api/mcp/directives', {
297
- action: 'directive_export',
298
- project_id: args.project_id,
299
- })
300
-
301
- if (!result.ok) return errorResult(result)
302
- return okResult(result.data)
303
- }