@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,302 +0,0 @@
1
- /**
2
- * Tests for Layer 1 Knowledge Access tools:
3
- * - kb_search
4
- * - kb_memory
5
- * - kb_get
6
- * - kb_related
7
- *
8
- * All tools now delegate to the Nexus API via nexusPost().
9
- * Tests mock the nexus-api module.
10
- */
11
-
12
- import { beforeEach, describe, expect, it, vi } from 'vitest'
13
- import { mockApiError, mockApiSuccess, parseToolResponse, TEST_IDS } from './helpers'
14
-
15
- vi.mock('../nexus-api.js', () => ({
16
- nexusPost: vi.fn(),
17
- }))
18
-
19
- import { nexusPost } from '../nexus-api.js'
20
-
21
- // ---------------------------------------------------------------------------
22
- // kb_search
23
- // ---------------------------------------------------------------------------
24
-
25
- describe('Layer 1: kb_search', () => {
26
- beforeEach(() => {
27
- vi.restoreAllMocks()
28
- })
29
-
30
- it('should return matching results for keyword search', async () => {
31
- vi.mocked(nexusPost).mockResolvedValue(
32
- mockApiSuccess({
33
- total_results: 1,
34
- results: [
35
- {
36
- entity_type: 'task',
37
- entity_id: TEST_IDS.taskId,
38
- title: 'Fix authentication bug',
39
- relevance: 'exact',
40
- },
41
- ],
42
- }),
43
- )
44
-
45
- const { searchKnowledge } = await import('../tools/search-knowledge.js')
46
- const result = await searchKnowledge({
47
- query: 'authentication bug',
48
- project_id: TEST_IDS.projectId,
49
- entity_types: ['task'],
50
- })
51
-
52
- expect(result.isError).toBeUndefined()
53
- const parsed = parseToolResponse(result)
54
- expect(parsed.total_results).toBe(1)
55
- expect(parsed.results[0].entity_type).toBe('task')
56
- expect(parsed.results[0].entity_id).toBe(TEST_IDS.taskId)
57
- })
58
-
59
- it('should return empty results when no matches', async () => {
60
- vi.mocked(nexusPost).mockResolvedValue(
61
- mockApiSuccess({ total_results: 0, results: [] }),
62
- )
63
-
64
- const { searchKnowledge } = await import('../tools/search-knowledge.js')
65
- const result = await searchKnowledge({
66
- query: 'nonexistent term xyz123',
67
- project_id: TEST_IDS.projectId,
68
- })
69
-
70
- const parsed = parseToolResponse(result)
71
- expect(parsed.total_results).toBe(0)
72
- expect(parsed.results).toEqual([])
73
- })
74
-
75
- it('should pass correct parameters to the API', async () => {
76
- vi.mocked(nexusPost).mockResolvedValue(
77
- mockApiSuccess({ total_results: 0, results: [] }),
78
- )
79
-
80
- const { searchKnowledge } = await import('../tools/search-knowledge.js')
81
- await searchKnowledge({
82
- query: 'test',
83
- project_id: TEST_IDS.projectId,
84
- entity_types: ['task', 'decision'],
85
- search_mode: 'hybrid',
86
- limit: 5,
87
- })
88
-
89
- expect(nexusPost).toHaveBeenCalledWith('/api/mcp/search', {
90
- project_id: TEST_IDS.projectId,
91
- query: 'test',
92
- entity_types: ['task', 'decision'],
93
- search_mode: 'hybrid',
94
- limit: 5,
95
- })
96
- })
97
-
98
- it('should handle API errors gracefully', async () => {
99
- vi.mocked(nexusPost).mockResolvedValue(mockApiError('connection lost'))
100
-
101
- const { searchKnowledge } = await import('../tools/search-knowledge.js')
102
- const result = await searchKnowledge({
103
- query: 'test',
104
- project_id: TEST_IDS.projectId,
105
- })
106
-
107
- expect(result.isError).toBe(true)
108
- const parsed = parseToolResponse(result)
109
- expect(parsed.error).toBe('connection lost')
110
- })
111
- })
112
-
113
- // ---------------------------------------------------------------------------
114
- // kb_memory
115
- // ---------------------------------------------------------------------------
116
-
117
- describe('Layer 1: kb_memory', () => {
118
- beforeEach(() => {
119
- vi.restoreAllMocks()
120
- })
121
-
122
- it('should return curated project context', async () => {
123
- vi.mocked(nexusPost).mockResolvedValue(
124
- mockApiSuccess({
125
- project_id: TEST_IDS.projectId,
126
- depth: 'standard',
127
- categories_included: ['adrs', 'active_tasks'],
128
- memory: {
129
- project: { id: TEST_IDS.projectId, name: 'Test Project' },
130
- adrs: [{ id: TEST_IDS.adrId, title: 'ADR-001', status: 'accepted' }],
131
- active_tasks: [{ id: TEST_IDS.taskId, title: 'Open task', status: 'open' }],
132
- },
133
- }),
134
- )
135
-
136
- const { getProjectMemory } = await import('../tools/get-project-memory.js')
137
- const result = await getProjectMemory({
138
- project_id: TEST_IDS.projectId,
139
- include: ['adrs', 'active_tasks'],
140
- })
141
-
142
- expect(result.isError).toBeUndefined()
143
- const parsed = parseToolResponse(result)
144
- expect(parsed.project_id).toBe(TEST_IDS.projectId)
145
- expect(parsed.memory.adrs).toHaveLength(1)
146
- expect(parsed.memory.active_tasks).toHaveLength(1)
147
- })
148
-
149
- it('should pass depth parameter to the API', async () => {
150
- vi.mocked(nexusPost).mockResolvedValue(
151
- mockApiSuccess({ project_id: TEST_IDS.projectId, depth: 'light', memory: {} }),
152
- )
153
-
154
- const { getProjectMemory } = await import('../tools/get-project-memory.js')
155
- await getProjectMemory({
156
- project_id: TEST_IDS.projectId,
157
- include: ['adrs'],
158
- depth: 'light',
159
- })
160
-
161
- expect(nexusPost).toHaveBeenCalledWith('/api/mcp/memory', {
162
- project_id: TEST_IDS.projectId,
163
- include: ['adrs'],
164
- depth: 'light',
165
- })
166
- })
167
-
168
- it('should handle API errors', async () => {
169
- vi.mocked(nexusPost).mockResolvedValue(mockApiError('Project not found'))
170
-
171
- const { getProjectMemory } = await import('../tools/get-project-memory.js')
172
- const result = await getProjectMemory({
173
- project_id: TEST_IDS.projectId,
174
- include: ['adrs'],
175
- })
176
-
177
- expect(result.isError).toBe(true)
178
- })
179
- })
180
-
181
- // ---------------------------------------------------------------------------
182
- // kb_get
183
- // ---------------------------------------------------------------------------
184
-
185
- describe('Layer 1: kb_get', () => {
186
- beforeEach(() => {
187
- vi.restoreAllMocks()
188
- })
189
-
190
- it('should fetch a document in structured mode', async () => {
191
- vi.mocked(nexusPost).mockResolvedValue(
192
- mockApiSuccess({
193
- entity_type: 'session',
194
- entity_id: TEST_IDS.sessionId,
195
- document: { id: TEST_IDS.sessionId, title: 'Test Session', status: 'open' },
196
- entries: [{ id: TEST_IDS.entryId, entry_type: 'note', summary: 'A note' }],
197
- }),
198
- )
199
-
200
- const { getDocument } = await import('../tools/get-document.js')
201
- const result = await getDocument({
202
- entity_type: 'session',
203
- entity_id: TEST_IDS.sessionId,
204
- })
205
-
206
- expect(result.isError).toBeUndefined()
207
- const parsed = parseToolResponse(result)
208
- expect(parsed.entity_type).toBe('session')
209
- expect(parsed.entity_id).toBe(TEST_IDS.sessionId)
210
- })
211
-
212
- it('should fetch a document in markdown mode', async () => {
213
- vi.mocked(nexusPost).mockResolvedValue(
214
- mockApiSuccess({
215
- entity_type: 'decision',
216
- entity_id: TEST_IDS.adrId,
217
- format: 'markdown',
218
- content: '# ADR-001\n\nSome content',
219
- }),
220
- )
221
-
222
- const { getDocument } = await import('../tools/get-document.js')
223
- const result = await getDocument({
224
- entity_type: 'decision',
225
- entity_id: TEST_IDS.adrId,
226
- render_mode: 'markdown',
227
- })
228
-
229
- expect(result.isError).toBeUndefined()
230
- expect(result.content[0].text).toContain('# ADR-001')
231
- })
232
-
233
- it('should return error for not found entity', async () => {
234
- vi.mocked(nexusPost).mockResolvedValue(mockApiError('Document not found', 404))
235
-
236
- const { getDocument } = await import('../tools/get-document.js')
237
- const result = await getDocument({
238
- entity_type: 'session',
239
- entity_id: TEST_IDS.sessionId,
240
- })
241
-
242
- expect(result.isError).toBe(true)
243
- })
244
- })
245
-
246
- // ---------------------------------------------------------------------------
247
- // kb_related
248
- // ---------------------------------------------------------------------------
249
-
250
- describe('Layer 1: kb_related', () => {
251
- beforeEach(() => {
252
- vi.restoreAllMocks()
253
- })
254
-
255
- it('should return related entities for a session', async () => {
256
- vi.mocked(nexusPost).mockResolvedValue(
257
- mockApiSuccess({
258
- source: {
259
- entity_type: 'session',
260
- entity_id: TEST_IDS.sessionId,
261
- project_id: TEST_IDS.projectId,
262
- },
263
- total_related: 1,
264
- related: [
265
- {
266
- relation: 'task_in_project',
267
- entity_type: 'task',
268
- entity_id: TEST_IDS.taskId,
269
- title: 'Related task',
270
- status: 'open',
271
- created_at: '2026-04-12',
272
- },
273
- ],
274
- }),
275
- )
276
-
277
- const { getRelatedEntities } = await import('../tools/get-related-entities.js')
278
- const result = await getRelatedEntities({
279
- entity_type: 'session',
280
- entity_id: TEST_IDS.sessionId,
281
- })
282
-
283
- expect(result.isError).toBeUndefined()
284
- const parsed = parseToolResponse(result)
285
- expect(parsed.source.entity_type).toBe('session')
286
- expect(parsed.source.entity_id).toBe(TEST_IDS.sessionId)
287
- expect(parsed.total_related).toBe(1)
288
- expect(parsed.related[0].entity_type).toBe('task')
289
- })
290
-
291
- it('should handle API errors', async () => {
292
- vi.mocked(nexusPost).mockResolvedValue(mockApiError('Entity not found', 404))
293
-
294
- const { getRelatedEntities } = await import('../tools/get-related-entities.js')
295
- const result = await getRelatedEntities({
296
- entity_type: 'session',
297
- entity_id: TEST_IDS.sessionId,
298
- })
299
-
300
- expect(result.isError).toBe(true)
301
- })
302
- })