@elixium.ai/mcp-server 0.4.0 → 0.6.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 +25 -0
- package/dist/constants/featureConfigFallback.js +30 -0
- package/dist/constants/workflowModelLabels.js +59 -0
- package/dist/index.js +308 -130
- package/dist/stakeholders.js +72 -0
- package/dist/toolSchemas.js +245 -0
- package/package.json +8 -6
- package/dist/__tests__/board-isolation.test.js +0 -83
- package/dist/__tests__/create-board.test.js +0 -97
- package/dist/__tests__/fixtures/boards.js +0 -117
- package/dist/__tests__/list-boards.test.js +0 -54
- package/dist/__tests__/select-board.test.js +0 -74
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, vi, beforeEach } from "vitest";
|
|
2
|
-
import { listBoards, resetBoardContext, selectBoard } from "../board-context.js";
|
|
3
|
-
import { ALL_BOARDS, ACTIVE_BOARDS, } from "./fixtures/boards.js";
|
|
4
|
-
const mockClient = {
|
|
5
|
-
get: vi.fn(),
|
|
6
|
-
post: vi.fn(),
|
|
7
|
-
};
|
|
8
|
-
beforeEach(() => {
|
|
9
|
-
vi.clearAllMocks();
|
|
10
|
-
resetBoardContext();
|
|
11
|
-
});
|
|
12
|
-
describe("list_boards", () => {
|
|
13
|
-
it("1.1 returns all boards with required fields", async () => {
|
|
14
|
-
mockClient.get.mockResolvedValue({ data: ACTIVE_BOARDS });
|
|
15
|
-
const result = await listBoards(mockClient);
|
|
16
|
-
expect(result.boards).toHaveLength(2);
|
|
17
|
-
for (const board of result.boards) {
|
|
18
|
-
expect(board).toHaveProperty("id");
|
|
19
|
-
expect(board).toHaveProperty("name");
|
|
20
|
-
expect(board).toHaveProperty("slug");
|
|
21
|
-
expect(board).toHaveProperty("createdAt");
|
|
22
|
-
}
|
|
23
|
-
});
|
|
24
|
-
it("1.2 returns empty array when no boards exist", async () => {
|
|
25
|
-
mockClient.get.mockResolvedValue({ data: [] });
|
|
26
|
-
const result = await listBoards(mockClient);
|
|
27
|
-
expect(result.boards).toEqual([]);
|
|
28
|
-
});
|
|
29
|
-
it("1.3 excludes archived boards by default", async () => {
|
|
30
|
-
mockClient.get.mockResolvedValue({ data: ALL_BOARDS });
|
|
31
|
-
const result = await listBoards(mockClient);
|
|
32
|
-
expect(result.boards).toHaveLength(2);
|
|
33
|
-
expect(result.boards.every((b) => !b.isArchived)).toBe(true);
|
|
34
|
-
});
|
|
35
|
-
it("1.4 includes archived boards when requested", async () => {
|
|
36
|
-
mockClient.get.mockResolvedValue({ data: ALL_BOARDS });
|
|
37
|
-
const result = await listBoards(mockClient, { includeArchived: true });
|
|
38
|
-
expect(result.boards).toHaveLength(3);
|
|
39
|
-
const archived = result.boards.find((b) => b.slug === "archived-board");
|
|
40
|
-
expect(archived?.isArchived).toBe(true);
|
|
41
|
-
});
|
|
42
|
-
it("1.5 indicates currently selected board", async () => {
|
|
43
|
-
// First select alpha
|
|
44
|
-
mockClient.get.mockResolvedValue({ data: ALL_BOARDS });
|
|
45
|
-
await selectBoard(mockClient, "alpha");
|
|
46
|
-
// Then list
|
|
47
|
-
mockClient.get.mockResolvedValue({ data: ALL_BOARDS });
|
|
48
|
-
const result = await listBoards(mockClient);
|
|
49
|
-
const alpha = result.boards.find((b) => b.slug === "alpha");
|
|
50
|
-
const beta = result.boards.find((b) => b.slug === "beta");
|
|
51
|
-
expect(alpha?.selected).toBe(true);
|
|
52
|
-
expect(beta?.selected).toBeUndefined();
|
|
53
|
-
});
|
|
54
|
-
});
|
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, vi, beforeEach } from "vitest";
|
|
2
|
-
import { selectBoard, resetBoardContext, getActiveBoardSlug, getRuntimeBoardId, } from "../board-context.js";
|
|
3
|
-
import { ALL_BOARDS, BOARD_ALPHA, BOARD_BETA } from "./fixtures/boards.js";
|
|
4
|
-
const mockClient = {
|
|
5
|
-
get: vi.fn(),
|
|
6
|
-
post: vi.fn(),
|
|
7
|
-
};
|
|
8
|
-
beforeEach(() => {
|
|
9
|
-
vi.clearAllMocks();
|
|
10
|
-
resetBoardContext();
|
|
11
|
-
});
|
|
12
|
-
describe("select_board", () => {
|
|
13
|
-
it("3.1 selects board by slug and confirms selection", async () => {
|
|
14
|
-
mockClient.get.mockResolvedValue({ data: ALL_BOARDS });
|
|
15
|
-
const result = await selectBoard(mockClient, "alpha");
|
|
16
|
-
expect(result.id).toBe(BOARD_ALPHA.id);
|
|
17
|
-
expect(result.name).toBe("Alpha Board");
|
|
18
|
-
expect(result.slug).toBe("alpha");
|
|
19
|
-
expect(getActiveBoardSlug()).toBe("alpha");
|
|
20
|
-
expect(getRuntimeBoardId()).toBe(BOARD_ALPHA.id);
|
|
21
|
-
});
|
|
22
|
-
it("3.2 case-insensitive slug matching", async () => {
|
|
23
|
-
mockClient.get.mockResolvedValue({ data: ALL_BOARDS });
|
|
24
|
-
const result1 = await selectBoard(mockClient, "Alpha");
|
|
25
|
-
expect(result1.id).toBe(BOARD_ALPHA.id);
|
|
26
|
-
resetBoardContext();
|
|
27
|
-
mockClient.get.mockResolvedValue({ data: ALL_BOARDS });
|
|
28
|
-
const result2 = await selectBoard(mockClient, "ALPHA");
|
|
29
|
-
expect(result2.id).toBe(BOARD_ALPHA.id);
|
|
30
|
-
});
|
|
31
|
-
it("3.3 returns error for invalid slug", async () => {
|
|
32
|
-
mockClient.get.mockResolvedValue({ data: ALL_BOARDS });
|
|
33
|
-
await expect(selectBoard(mockClient, "nonexistent")).rejects.toThrow('Board "nonexistent" not found');
|
|
34
|
-
// Board context should remain unset
|
|
35
|
-
expect(getActiveBoardSlug()).toBeNull();
|
|
36
|
-
expect(getRuntimeBoardId()).toBeNull();
|
|
37
|
-
});
|
|
38
|
-
it("3.3b preserves previous selection on error", async () => {
|
|
39
|
-
// Select alpha first
|
|
40
|
-
mockClient.get.mockResolvedValue({ data: ALL_BOARDS });
|
|
41
|
-
await selectBoard(mockClient, "alpha");
|
|
42
|
-
expect(getActiveBoardSlug()).toBe("alpha");
|
|
43
|
-
// Try to select nonexistent — should fail
|
|
44
|
-
mockClient.get.mockResolvedValue({ data: ALL_BOARDS });
|
|
45
|
-
await expect(selectBoard(mockClient, "nonexistent")).rejects.toThrow();
|
|
46
|
-
// Alpha should still be selected
|
|
47
|
-
expect(getActiveBoardSlug()).toBe("alpha");
|
|
48
|
-
expect(getRuntimeBoardId()).toBe(BOARD_ALPHA.id);
|
|
49
|
-
});
|
|
50
|
-
it("3.4 subsequent calls use selected board", async () => {
|
|
51
|
-
mockClient.get.mockResolvedValue({ data: ALL_BOARDS });
|
|
52
|
-
await selectBoard(mockClient, "alpha");
|
|
53
|
-
// getActiveBoardSlug should return "alpha" for downstream tools
|
|
54
|
-
expect(getActiveBoardSlug()).toBe("alpha");
|
|
55
|
-
expect(getRuntimeBoardId()).toBe(BOARD_ALPHA.id);
|
|
56
|
-
});
|
|
57
|
-
it("3.5 switching boards updates context", async () => {
|
|
58
|
-
mockClient.get.mockResolvedValue({ data: ALL_BOARDS });
|
|
59
|
-
await selectBoard(mockClient, "alpha");
|
|
60
|
-
expect(getActiveBoardSlug()).toBe("alpha");
|
|
61
|
-
mockClient.get.mockResolvedValue({ data: ALL_BOARDS });
|
|
62
|
-
await selectBoard(mockClient, "beta");
|
|
63
|
-
expect(getActiveBoardSlug()).toBe("beta");
|
|
64
|
-
expect(getRuntimeBoardId()).toBe(BOARD_BETA.id);
|
|
65
|
-
});
|
|
66
|
-
it("3.6 overrides ELIXIUM_BOARD_SLUG env var", async () => {
|
|
67
|
-
// Before runtime selection, env var is used
|
|
68
|
-
expect(getActiveBoardSlug("alpha")).toBe("alpha");
|
|
69
|
-
// After runtime selection, runtime wins
|
|
70
|
-
mockClient.get.mockResolvedValue({ data: ALL_BOARDS });
|
|
71
|
-
await selectBoard(mockClient, "beta");
|
|
72
|
-
expect(getActiveBoardSlug("alpha")).toBe("beta");
|
|
73
|
-
});
|
|
74
|
-
});
|