@bernierllc/braingrid-cli-wrapper 0.3.2 → 0.5.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,100 +0,0 @@
1
- /*
2
- Copyright (c) 2025 Bernier LLC
3
-
4
- This file is licensed to the client under a limited-use license.
5
- The client may use and modify this code *only within the scope of the project it was delivered for*.
6
- Redistribution or use in other products or commercial offerings is not permitted without written consent from Bernier LLC.
7
- */
8
-
9
- import { createTask } from './createTask';
10
-
11
- jest.mock('../cli', () => ({
12
- runBrainGridCommand: jest.fn()
13
- }));
14
-
15
- import { runBrainGridCommand } from '../cli';
16
-
17
- describe('createTask', () => {
18
- beforeEach(() => {
19
- jest.clearAllMocks();
20
- });
21
-
22
- it('should create task with title only', async () => {
23
- const mockTask = {
24
- id: 'task-123',
25
- reqId: 'req-456',
26
- title: 'Build login UI',
27
- status: 'TODO'
28
- };
29
-
30
- (runBrainGridCommand as jest.MockedFunction<typeof runBrainGridCommand>).mockResolvedValue(mockTask);
31
-
32
- const result = await createTask('req-456', {
33
- title: 'Build login UI'
34
- });
35
-
36
- expect(runBrainGridCommand).toHaveBeenCalledWith([
37
- 'task',
38
- 'create',
39
- 'req-456',
40
- '--title',
41
- 'Build login UI',
42
- '--format',
43
- 'json'
44
- ]);
45
-
46
- expect(result.id).toBe('task-123');
47
- expect(result.title).toBe('Build login UI');
48
- });
49
-
50
- it('should create task with all options', async () => {
51
- const mockTask = {
52
- id: 'task-123',
53
- reqId: 'req-456',
54
- title: 'Build login UI',
55
- status: 'TODO',
56
- description: 'Create login form',
57
- tags: ['DEV', 'frontend'],
58
- dependencies: ['task-100', 'task-200']
59
- };
60
-
61
- (runBrainGridCommand as jest.MockedFunction<typeof runBrainGridCommand>).mockResolvedValue(mockTask);
62
-
63
- const result = await createTask('req-456', {
64
- title: 'Build login UI',
65
- description: 'Create login form',
66
- tags: ['DEV', 'frontend'],
67
- dependencies: ['task-100', 'task-200']
68
- });
69
-
70
- expect(runBrainGridCommand).toHaveBeenCalledWith([
71
- 'task',
72
- 'create',
73
- 'req-456',
74
- '--title',
75
- 'Build login UI',
76
- '--description',
77
- 'Create login form',
78
- '--tags',
79
- 'DEV,frontend',
80
- '--dependencies',
81
- 'task-100,task-200',
82
- '--format',
83
- 'json'
84
- ]);
85
-
86
- expect(result.tags).toEqual(['DEV', 'frontend']);
87
- expect(result.dependencies).toEqual(['task-100', 'task-200']);
88
- });
89
-
90
- it('should validate response schema', async () => {
91
- const invalidTask = {
92
- id: 123, // Should be string
93
- title: 'Test'
94
- };
95
-
96
- (runBrainGridCommand as jest.MockedFunction<typeof runBrainGridCommand>).mockResolvedValue(invalidTask);
97
-
98
- await expect(createTask('req-456', { title: 'Test' })).rejects.toThrow();
99
- });
100
- });
@@ -1,50 +0,0 @@
1
- /*
2
- Copyright (c) 2025 Bernier LLC
3
-
4
- This file is licensed to the client under a limited-use license.
5
- The client may use and modify this code *only within the scope of the project it was delivered for*.
6
- Redistribution or use in other products or commercial offerings is not permitted without written consent from Bernier LLC.
7
- */
8
-
9
- import { runBrainGridCommand } from '../cli';
10
- import { BrainGridTask, BrainGridTaskSchema } from '../models';
11
-
12
- export interface CreateTaskOptions {
13
- title: string;
14
- description?: string;
15
- tags?: string[];
16
- dependencies?: string[];
17
- }
18
-
19
- /**
20
- * Create a task in BrainGrid under a requirement
21
- */
22
- export async function createTask(
23
- reqId: string,
24
- options: CreateTaskOptions
25
- ): Promise<BrainGridTask> {
26
- const args = ['task', 'create', reqId, '--title', options.title];
27
-
28
- if (options.description) {
29
- args.push('--description', options.description);
30
- }
31
-
32
- if (options.tags && options.tags.length > 0) {
33
- args.push('--tags', options.tags.join(','));
34
- }
35
-
36
- if (options.dependencies && options.dependencies.length > 0) {
37
- args.push('--dependencies', options.dependencies.join(','));
38
- }
39
-
40
- args.push('--format', 'json');
41
-
42
- const result = await runBrainGridCommand(args);
43
-
44
- const parsed = BrainGridTaskSchema.safeParse(result);
45
- if (!parsed.success) {
46
- throw new Error(`Invalid BrainGrid response: ${parsed.error.message}`);
47
- }
48
-
49
- return parsed.data;
50
- }
@@ -1,72 +0,0 @@
1
- /*
2
- Copyright (c) 2025 Bernier LLC
3
-
4
- This file is licensed to the client under a limited-use license.
5
- The client may use and modify this code *only within the scope of the project it was delivered for*.
6
- Redistribution or use in other products or commercial offerings is not permitted without written consent from Bernier LLC.
7
- */
8
-
9
- import { listProjects } from './listProjects';
10
-
11
- jest.mock('../cli', () => ({
12
- runBrainGridCommand: jest.fn()
13
- }));
14
-
15
- import { runBrainGridCommand } from '../cli';
16
-
17
- describe('listProjects', () => {
18
- beforeEach(() => {
19
- jest.clearAllMocks();
20
- });
21
-
22
- it('should list all projects', async () => {
23
- const mockProjects = [
24
- {
25
- id: 'proj-1',
26
- name: 'Project 1',
27
- description: 'First project'
28
- },
29
- {
30
- id: 'proj-2',
31
- name: 'Project 2',
32
- description: 'Second project'
33
- }
34
- ];
35
-
36
- (runBrainGridCommand as jest.MockedFunction<typeof runBrainGridCommand>).mockResolvedValue(mockProjects);
37
-
38
- const result = await listProjects();
39
-
40
- expect(runBrainGridCommand).toHaveBeenCalledWith([
41
- 'projects',
42
- 'list',
43
- '--format',
44
- 'json'
45
- ]);
46
-
47
- expect(result).toHaveLength(2);
48
- expect(result[0].id).toBe('proj-1');
49
- expect(result[1].id).toBe('proj-2');
50
- });
51
-
52
- it('should return empty array when no projects', async () => {
53
- (runBrainGridCommand as jest.MockedFunction<typeof runBrainGridCommand>).mockResolvedValue([]);
54
-
55
- const result = await listProjects();
56
-
57
- expect(result).toEqual([]);
58
- });
59
-
60
- it('should validate response schema', async () => {
61
- const invalidProjects = [
62
- {
63
- id: 123, // Should be string
64
- name: 'Test'
65
- }
66
- ];
67
-
68
- (runBrainGridCommand as jest.MockedFunction<typeof runBrainGridCommand>).mockResolvedValue(invalidProjects);
69
-
70
- await expect(listProjects()).rejects.toThrow();
71
- });
72
- });
@@ -1,25 +0,0 @@
1
- /*
2
- Copyright (c) 2025 Bernier LLC
3
-
4
- This file is licensed to the client under a limited-use license.
5
- The client may use and modify this code *only within the scope of the project it was delivered for*.
6
- Redistribution or use in other products or commercial offerings is not permitted without written consent from Bernier LLC.
7
- */
8
-
9
- import { runBrainGridCommand } from '../cli';
10
- import { BrainGridProject, BrainGridProjectSchema } from '../models';
11
- import { z } from 'zod';
12
-
13
- /**
14
- * List all projects in BrainGrid
15
- */
16
- export async function listProjects(): Promise<BrainGridProject[]> {
17
- const result = await runBrainGridCommand(['projects', 'list', '--format', 'json']);
18
-
19
- const parsed = z.array(BrainGridProjectSchema).safeParse(result);
20
- if (!parsed.success) {
21
- throw new Error(`Invalid BrainGrid response: ${parsed.error.message}`);
22
- }
23
-
24
- return parsed.data;
25
- }
@@ -1,89 +0,0 @@
1
- /*
2
- Copyright (c) 2025 Bernier LLC
3
-
4
- This file is licensed to the client under a limited-use license.
5
- The client may use and modify this code *only within the scope of the project it was delivered for*.
6
- Redistribution or use in other products or commercial offerings is not permitted without written consent from Bernier LLC.
7
- */
8
-
9
- import { listRequirements } from './listRequirements';
10
-
11
- jest.mock('../cli', () => ({
12
- runBrainGridCommand: jest.fn()
13
- }));
14
-
15
- import { runBrainGridCommand } from '../cli';
16
-
17
- describe('listRequirements', () => {
18
- beforeEach(() => {
19
- jest.clearAllMocks();
20
- });
21
-
22
- it('should list all requirements', async () => {
23
- const mockRequirements = [
24
- {
25
- id: 'req-1',
26
- projectId: 'proj-1',
27
- title: 'Requirement 1',
28
- status: 'IDEA'
29
- },
30
- {
31
- id: 'req-2',
32
- projectId: 'proj-1',
33
- title: 'Requirement 2',
34
- status: 'PLANNED'
35
- }
36
- ];
37
-
38
- (runBrainGridCommand as jest.MockedFunction<typeof runBrainGridCommand>).mockResolvedValue(mockRequirements);
39
-
40
- const result = await listRequirements();
41
-
42
- expect(runBrainGridCommand).toHaveBeenCalledWith([
43
- 'requirement',
44
- 'list',
45
- '--format',
46
- 'json'
47
- ]);
48
- expect(result).toEqual(mockRequirements);
49
- });
50
-
51
- it('should list requirements for a specific project', async () => {
52
- const mockRequirements = [
53
- {
54
- id: 'req-1',
55
- projectId: 'proj-123',
56
- title: 'Requirement 1',
57
- status: 'IDEA'
58
- }
59
- ];
60
-
61
- (runBrainGridCommand as jest.MockedFunction<typeof runBrainGridCommand>).mockResolvedValue(mockRequirements);
62
-
63
- const result = await listRequirements('proj-123');
64
-
65
- expect(runBrainGridCommand).toHaveBeenCalledWith([
66
- 'requirement',
67
- 'list',
68
- '--format',
69
- 'json',
70
- '--project',
71
- 'proj-123'
72
- ]);
73
- expect(result).toEqual(mockRequirements);
74
- });
75
-
76
- it('should return empty array when no requirements exist', async () => {
77
- (runBrainGridCommand as jest.MockedFunction<typeof runBrainGridCommand>).mockResolvedValue([]);
78
-
79
- const result = await listRequirements();
80
-
81
- expect(result).toEqual([]);
82
- });
83
-
84
- it('should throw on invalid response', async () => {
85
- (runBrainGridCommand as jest.MockedFunction<typeof runBrainGridCommand>).mockResolvedValue([{ invalid: 'data' }]);
86
-
87
- await expect(listRequirements()).rejects.toThrow();
88
- });
89
- });
@@ -1,37 +0,0 @@
1
- /*
2
- Copyright (c) 2025 Bernier LLC
3
-
4
- This file is licensed to the client under a limited-use license.
5
- The client may use and modify this code *only within the scope of the project it was delivered for*.
6
- Redistribution or use in other products or commercial offerings is not permitted without written consent from Bernier LLC.
7
- */
8
-
9
- import { runBrainGridCommand } from '../cli';
10
- import { BrainGridRequirement, BrainGridRequirementSchema } from '../models';
11
- import { z } from 'zod';
12
-
13
- /**
14
- * Lists BrainGrid requirements
15
- * @param projectId - Optional project ID to filter requirements
16
- * @returns Promise resolving to array of requirements
17
- */
18
- export async function listRequirements(
19
- projectId?: string
20
- ): Promise<BrainGridRequirement[]> {
21
- const args = ['requirement', 'list', '--format', 'json'];
22
-
23
- if (projectId) {
24
- args.push('--project', projectId);
25
- }
26
-
27
- const result = await runBrainGridCommand(args);
28
-
29
- // Validate response
30
- const schema = z.array(BrainGridRequirementSchema);
31
- const parsed = schema.safeParse(result);
32
- if (!parsed.success) {
33
- throw new Error(`Invalid BrainGrid response: ${parsed.error.message}`);
34
- }
35
-
36
- return parsed.data;
37
- }
@@ -1,183 +0,0 @@
1
- /*
2
- Copyright (c) 2025 Bernier LLC
3
-
4
- This file is licensed to the client under a limited-use license.
5
- The client may use and modify this code *only within the scope of the project it was delivered for*.
6
- Redistribution or use in other products or commercial offerings is not permitted without written consent from Bernier LLC.
7
- */
8
-
9
- import { listTasks } from './listTasks';
10
-
11
- jest.mock('../cli', () => ({
12
- runBrainGridCommand: jest.fn()
13
- }));
14
-
15
- import { runBrainGridCommand } from '../cli';
16
-
17
- describe('listTasks', () => {
18
- beforeEach(() => {
19
- jest.clearAllMocks();
20
- });
21
-
22
- it('should list all tasks with no filters', async () => {
23
- const mockTasks = [
24
- {
25
- id: 'task-1',
26
- reqId: 'req-123',
27
- title: 'Task 1',
28
- status: 'TODO'
29
- },
30
- {
31
- id: 'task-2',
32
- reqId: 'req-123',
33
- title: 'Task 2',
34
- status: 'IN_PROGRESS'
35
- }
36
- ];
37
-
38
- (runBrainGridCommand as jest.MockedFunction<typeof runBrainGridCommand>).mockResolvedValue(mockTasks);
39
-
40
- const result = await listTasks();
41
-
42
- expect(runBrainGridCommand).toHaveBeenCalledWith([
43
- 'task',
44
- 'list',
45
- '--format',
46
- 'json'
47
- ]);
48
-
49
- expect(result).toHaveLength(2);
50
- expect(result[0].id).toBe('task-1');
51
- });
52
-
53
- it('should filter tasks by requirement ID', async () => {
54
- const mockTasks = [
55
- {
56
- id: 'task-1',
57
- reqId: 'req-123',
58
- title: 'Task 1',
59
- status: 'TODO'
60
- }
61
- ];
62
-
63
- (runBrainGridCommand as jest.MockedFunction<typeof runBrainGridCommand>).mockResolvedValue(mockTasks);
64
-
65
- await listTasks({ reqId: 'req-123' });
66
-
67
- expect(runBrainGridCommand).toHaveBeenCalledWith([
68
- 'task',
69
- 'list',
70
- '--req',
71
- 'req-123',
72
- '--format',
73
- 'json'
74
- ]);
75
- });
76
-
77
- it('should filter tasks by status', async () => {
78
- const mockTasks = [
79
- {
80
- id: 'task-1',
81
- reqId: 'req-123',
82
- title: 'Task 1',
83
- status: 'TODO'
84
- }
85
- ];
86
-
87
- (runBrainGridCommand as jest.MockedFunction<typeof runBrainGridCommand>).mockResolvedValue(mockTasks);
88
-
89
- await listTasks({
90
- status: ['TODO', 'READY']
91
- });
92
-
93
- expect(runBrainGridCommand).toHaveBeenCalledWith([
94
- 'task',
95
- 'list',
96
- '--status',
97
- 'TODO,READY',
98
- '--format',
99
- 'json'
100
- ]);
101
- });
102
-
103
- it('should filter tasks by tags', async () => {
104
- const mockTasks = [
105
- {
106
- id: 'task-1',
107
- reqId: 'req-123',
108
- title: 'Task 1',
109
- status: 'TODO',
110
- tags: ['DEV', 'frontend']
111
- }
112
- ];
113
-
114
- (runBrainGridCommand as jest.MockedFunction<typeof runBrainGridCommand>).mockResolvedValue(mockTasks);
115
-
116
- await listTasks({
117
- tags: ['DEV', 'frontend']
118
- });
119
-
120
- expect(runBrainGridCommand).toHaveBeenCalledWith([
121
- 'task',
122
- 'list',
123
- '--tags',
124
- 'DEV,frontend',
125
- '--format',
126
- 'json'
127
- ]);
128
- });
129
-
130
- it('should combine all filters', async () => {
131
- const mockTasks = [
132
- {
133
- id: 'task-1',
134
- reqId: 'req-123',
135
- title: 'Task 1',
136
- status: 'TODO',
137
- tags: ['DEV']
138
- }
139
- ];
140
-
141
- (runBrainGridCommand as jest.MockedFunction<typeof runBrainGridCommand>).mockResolvedValue(mockTasks);
142
-
143
- await listTasks({
144
- reqId: 'req-123',
145
- status: ['TODO'],
146
- tags: ['DEV']
147
- });
148
-
149
- expect(runBrainGridCommand).toHaveBeenCalledWith([
150
- 'task',
151
- 'list',
152
- '--req',
153
- 'req-123',
154
- '--status',
155
- 'TODO',
156
- '--tags',
157
- 'DEV',
158
- '--format',
159
- 'json'
160
- ]);
161
- });
162
-
163
- it('should return empty array when no tasks', async () => {
164
- (runBrainGridCommand as jest.MockedFunction<typeof runBrainGridCommand>).mockResolvedValue([]);
165
-
166
- const result = await listTasks();
167
-
168
- expect(result).toEqual([]);
169
- });
170
-
171
- it('should validate response schema', async () => {
172
- const invalidTasks = [
173
- {
174
- id: 123, // Should be string
175
- title: 'Test'
176
- }
177
- ];
178
-
179
- (runBrainGridCommand as jest.MockedFunction<typeof runBrainGridCommand>).mockResolvedValue(invalidTasks);
180
-
181
- await expect(listTasks()).rejects.toThrow();
182
- });
183
- });
@@ -1,47 +0,0 @@
1
- /*
2
- Copyright (c) 2025 Bernier LLC
3
-
4
- This file is licensed to the client under a limited-use license.
5
- The client may use and modify this code *only within the scope of the project it was delivered for*.
6
- Redistribution or use in other products or commercial offerings is not permitted without written consent from Bernier LLC.
7
- */
8
-
9
- import { runBrainGridCommand } from '../cli';
10
- import { BrainGridTask, BrainGridTaskSchema, TaskStatus } from '../models';
11
- import { z } from 'zod';
12
-
13
- export interface ListTasksOptions {
14
- reqId?: string;
15
- status?: TaskStatus[];
16
- tags?: string[];
17
- }
18
-
19
- /**
20
- * List tasks in BrainGrid with optional filters
21
- */
22
- export async function listTasks(options: ListTasksOptions = {}): Promise<BrainGridTask[]> {
23
- const args = ['task', 'list'];
24
-
25
- if (options.reqId) {
26
- args.push('--req', options.reqId);
27
- }
28
-
29
- if (options.status && options.status.length > 0) {
30
- args.push('--status', options.status.join(','));
31
- }
32
-
33
- if (options.tags && options.tags.length > 0) {
34
- args.push('--tags', options.tags.join(','));
35
- }
36
-
37
- args.push('--format', 'json');
38
-
39
- const result = await runBrainGridCommand(args);
40
-
41
- const parsed = z.array(BrainGridTaskSchema).safeParse(result);
42
- if (!parsed.success) {
43
- throw new Error(`Invalid BrainGrid response: ${parsed.error.message}`);
44
- }
45
-
46
- return parsed.data;
47
- }
@@ -1,85 +0,0 @@
1
- /*
2
- Copyright (c) 2025 Bernier LLC
3
-
4
- This file is licensed to the client under a limited-use license.
5
- The client may use and modify this code *only within the scope of the project it was delivered for*.
6
- Redistribution or use in other products or commercial offerings is not permitted without written consent from Bernier LLC.
7
- */
8
-
9
- import { updateRequirementStatus } from './updateRequirementStatus';
10
-
11
- jest.mock('../cli', () => ({
12
- runBrainGridCommand: jest.fn()
13
- }));
14
-
15
- import { runBrainGridCommand } from '../cli';
16
-
17
- describe('updateRequirementStatus', () => {
18
- beforeEach(() => {
19
- jest.clearAllMocks();
20
- });
21
-
22
- it('should update requirement status to PLANNED', async () => {
23
- (runBrainGridCommand as jest.MockedFunction<typeof runBrainGridCommand>).mockResolvedValue({});
24
-
25
- await updateRequirementStatus('req-123', 'PLANNED');
26
-
27
- expect(runBrainGridCommand).toHaveBeenCalledWith([
28
- 'requirement',
29
- 'update',
30
- 'req-123',
31
- '--status',
32
- 'PLANNED',
33
- '--format',
34
- 'json'
35
- ]);
36
- });
37
-
38
- it('should update requirement status to IN_PROGRESS', async () => {
39
- (runBrainGridCommand as jest.MockedFunction<typeof runBrainGridCommand>).mockResolvedValue({});
40
-
41
- await updateRequirementStatus('req-456', 'IN_PROGRESS');
42
-
43
- expect(runBrainGridCommand).toHaveBeenCalledWith([
44
- 'requirement',
45
- 'update',
46
- 'req-456',
47
- '--status',
48
- 'IN_PROGRESS',
49
- '--format',
50
- 'json'
51
- ]);
52
- });
53
-
54
- it('should update requirement status to COMPLETED', async () => {
55
- (runBrainGridCommand as jest.MockedFunction<typeof runBrainGridCommand>).mockResolvedValue({});
56
-
57
- await updateRequirementStatus('req-789', 'COMPLETED');
58
-
59
- expect(runBrainGridCommand).toHaveBeenCalledWith([
60
- 'requirement',
61
- 'update',
62
- 'req-789',
63
- '--status',
64
- 'COMPLETED',
65
- '--format',
66
- 'json'
67
- ]);
68
- });
69
-
70
- it('should update requirement status to CANCELLED', async () => {
71
- (runBrainGridCommand as jest.MockedFunction<typeof runBrainGridCommand>).mockResolvedValue({});
72
-
73
- await updateRequirementStatus('req-999', 'CANCELLED');
74
-
75
- expect(runBrainGridCommand).toHaveBeenCalledWith([
76
- 'requirement',
77
- 'update',
78
- 'req-999',
79
- '--status',
80
- 'CANCELLED',
81
- '--format',
82
- 'json'
83
- ]);
84
- });
85
- });