@bernierllc/braingrid-cli-wrapper 0.1.1 → 0.3.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.
Files changed (57) hide show
  1. package/CHANGELOG.md +35 -0
  2. package/README.md +102 -11
  3. package/dist/commands/createProject.d.ts +8 -0
  4. package/dist/commands/createProject.js +31 -0
  5. package/dist/commands/listRequirements.d.ts +7 -0
  6. package/dist/commands/listRequirements.js +32 -0
  7. package/dist/commands/updateRequirementStatus.d.ts +8 -0
  8. package/dist/commands/updateRequirementStatus.js +29 -0
  9. package/dist/index.d.ts +3 -0
  10. package/dist/index.js +7 -1
  11. package/jest.config.cjs +0 -1
  12. package/package.json +17 -11
  13. package/src/__tests__/index.test.ts +77 -0
  14. package/src/commands/createProject.test.ts +75 -0
  15. package/src/commands/createProject.ts +37 -0
  16. package/src/commands/listRequirements.test.ts +89 -0
  17. package/src/commands/listRequirements.ts +37 -0
  18. package/src/commands/updateRequirementStatus.test.ts +85 -0
  19. package/src/commands/updateRequirementStatus.ts +33 -0
  20. package/src/index.ts +3 -0
  21. package/coverage/base.css +0 -224
  22. package/coverage/block-navigation.js +0 -87
  23. package/coverage/favicon.png +0 -0
  24. package/coverage/index.html +0 -131
  25. package/coverage/lcov-report/base.css +0 -224
  26. package/coverage/lcov-report/block-navigation.js +0 -87
  27. package/coverage/lcov-report/favicon.png +0 -0
  28. package/coverage/lcov-report/index.html +0 -131
  29. package/coverage/lcov-report/prettify.css +0 -1
  30. package/coverage/lcov-report/prettify.js +0 -2
  31. package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  32. package/coverage/lcov-report/sorter.js +0 -210
  33. package/coverage/lcov-report/src/cli.ts.html +0 -298
  34. package/coverage/lcov-report/src/commands/createIdea.ts.html +0 -193
  35. package/coverage/lcov-report/src/commands/createTask.ts.html +0 -235
  36. package/coverage/lcov-report/src/commands/index.html +0 -176
  37. package/coverage/lcov-report/src/commands/listProjects.ts.html +0 -160
  38. package/coverage/lcov-report/src/commands/listTasks.ts.html +0 -226
  39. package/coverage/lcov-report/src/commands/updateTaskStatus.ts.html +0 -205
  40. package/coverage/lcov-report/src/index.html +0 -146
  41. package/coverage/lcov-report/src/index.ts.html +0 -172
  42. package/coverage/lcov-report/src/models.ts.html +0 -364
  43. package/coverage/lcov.info +0 -240
  44. package/coverage/prettify.css +0 -1
  45. package/coverage/prettify.js +0 -2
  46. package/coverage/sort-arrow-sprite.png +0 -0
  47. package/coverage/sorter.js +0 -210
  48. package/coverage/src/cli.ts.html +0 -298
  49. package/coverage/src/commands/createIdea.ts.html +0 -193
  50. package/coverage/src/commands/createTask.ts.html +0 -235
  51. package/coverage/src/commands/index.html +0 -176
  52. package/coverage/src/commands/listProjects.ts.html +0 -160
  53. package/coverage/src/commands/listTasks.ts.html +0 -226
  54. package/coverage/src/commands/updateTaskStatus.ts.html +0 -205
  55. package/coverage/src/index.html +0 -146
  56. package/coverage/src/index.ts.html +0 -172
  57. package/coverage/src/models.ts.html +0 -364
package/CHANGELOG.md ADDED
@@ -0,0 +1,35 @@
1
+ # Change Log
2
+
3
+ All notable changes to this project will be documented in this file.
4
+ See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
+
6
+ # 0.3.0 (2025-12-25)
7
+
8
+
9
+ ### Bug Fixes
10
+
11
+ * **ci:** add lerna version step before publish ([3d20300](https://github.com/bernier-llc/tools/commit/3d203002143bf353fffafe4f8a78a99009567347))
12
+ * **jest:** move global options to root config and fix typos ([c14710c](https://github.com/bernier-llc/tools/commit/c14710c11e8fc34dd7f773edf01328151564323a))
13
+ * update neverhub-adapter deps to workspace:* and publish 0.1.2 ([f0e3d04](https://github.com/bernier-llc/tools/commit/f0e3d04d8d4f094e3bb899ddf81e93243d16e2c2))
14
+
15
+
16
+ ### Features
17
+
18
+ * add 4 more core/integration packages ([dd05b81](https://github.com/bernier-llc/tools/commit/dd05b816c94adcbd99556afbd9e316146654f44c))
19
+
20
+
21
+
22
+
23
+
24
+ # 0.2.0 (2025-12-25)
25
+
26
+
27
+ ### Bug Fixes
28
+
29
+ * **jest:** move global options to root config and fix typos ([c14710c](https://github.com/bernier-llc/tools/commit/c14710c11e8fc34dd7f773edf01328151564323a))
30
+ * update neverhub-adapter deps to workspace:* and publish 0.1.2 ([f0e3d04](https://github.com/bernier-llc/tools/commit/f0e3d04d8d4f094e3bb899ddf81e93243d16e2c2))
31
+
32
+
33
+ ### Features
34
+
35
+ * add 4 more core/integration packages ([dd05b81](https://github.com/bernier-llc/tools/commit/dd05b816c94adcbd99556afbd9e316146654f44c))
package/README.md CHANGED
@@ -23,22 +23,41 @@ npm install @bernierllc/braingrid-cli-wrapper
23
23
  ## Quick Start
24
24
 
25
25
  ```typescript
26
- import { createIdea, listProjects, createTask } from '@bernierllc/braingrid-cli-wrapper';
26
+ import {
27
+ createIdea,
28
+ listProjects,
29
+ createProject,
30
+ listRequirements,
31
+ updateRequirementStatus,
32
+ createTask
33
+ } from '@bernierllc/braingrid-cli-wrapper';
27
34
 
28
- // Create a new requirement (IDEA)
29
- const requirement = await createIdea('Add OAuth2 authentication', 'proj-123');
30
- console.log(`Created requirement ${requirement.id} with status ${requirement.status}`);
35
+ // Create a new project
36
+ const project = await createProject('My Project', 'Project description');
37
+ console.log(`Created project ${project.id}`);
31
38
 
32
39
  // List all projects
33
40
  const projects = await listProjects();
34
41
  console.log(`Found ${projects.length} projects`);
35
42
 
43
+ // Create a new requirement (IDEA)
44
+ const requirement = await createIdea('Add OAuth2 authentication', project.id);
45
+ console.log(`Created requirement ${requirement.id} with status ${requirement.status}`);
46
+
47
+ // List requirements
48
+ const requirements = await listRequirements(project.id);
49
+ console.log(`Found ${requirements.length} requirements`);
50
+
51
+ // Update requirement status
52
+ await updateRequirementStatus(requirement.id, 'PLANNED');
53
+ console.log(`Updated requirement to PLANNED status`);
54
+
36
55
  // Create a task under a requirement
37
- const task = await createTask('req-456', {
56
+ const task = await createTask(requirement.id, {
38
57
  title: 'Build login UI',
39
58
  description: 'Create login form component',
40
59
  tags: ['DEV', 'frontend'],
41
- dependencies: ['task-100']
60
+ dependencies: []
42
61
  });
43
62
  console.log(`Created task ${task.id}`);
44
63
  ```
@@ -89,6 +108,60 @@ const projects = await listProjects();
89
108
  // [{ id: 'proj-1', name: 'My Project', description: 'Project description' }]
90
109
  ```
91
110
 
111
+ #### `createProject(name: string, description?: string): Promise<BrainGridProject>`
112
+
113
+ Creates a new project in BrainGrid.
114
+
115
+ **Input:**
116
+ - `name` (string, required): Project name
117
+ - `description` (string, optional): Project description
118
+
119
+ **Output:**
120
+ - Returns a `BrainGridProject` object
121
+
122
+ **Example:**
123
+ ```typescript
124
+ const project = await createProject('My Project', 'Project description');
125
+ // { id: 'proj-123', name: 'My Project', description: 'Project description' }
126
+ ```
127
+
128
+ #### `listRequirements(projectId?: string): Promise<BrainGridRequirement[]>`
129
+
130
+ Lists requirements, optionally filtered by project.
131
+
132
+ **Input:**
133
+ - `projectId` (string, optional): Filter by project ID
134
+
135
+ **Output:**
136
+ - Returns an array of `BrainGridRequirement` objects
137
+
138
+ **Example:**
139
+ ```typescript
140
+ // List all requirements
141
+ const allRequirements = await listRequirements();
142
+
143
+ // List requirements for a specific project
144
+ const projectRequirements = await listRequirements('proj-123');
145
+ // [{ id: 'req-1', projectId: 'proj-123', title: 'Add auth', status: 'IDEA' }]
146
+ ```
147
+
148
+ #### `updateRequirementStatus(requirementId: string, status: RequirementStatus): Promise<void>`
149
+
150
+ Updates a requirement's status.
151
+
152
+ **Input:**
153
+ - `requirementId` (string, required): Requirement ID to update
154
+ - `status` (RequirementStatus, required): New status (IDEA, PLANNED, IN_PROGRESS, COMPLETED, CANCELLED, PAUSED)
155
+
156
+ **Output:** Promise that resolves when update is complete
157
+
158
+ **Example:**
159
+ ```typescript
160
+ await updateRequirementStatus('req-123', 'PLANNED');
161
+ await updateRequirementStatus('req-123', 'IN_PROGRESS');
162
+ await updateRequirementStatus('req-123', 'COMPLETED');
163
+ ```
164
+
92
165
  #### `createTask(reqId: string, options: CreateTaskOptions): Promise<BrainGridTask>`
93
166
 
94
167
  Creates a task under a requirement.
@@ -289,17 +362,26 @@ export BRAINGRID_CLI_PATH=/custom/path/braingrid
289
362
 
290
363
  ```typescript
291
364
  import {
365
+ createProject,
292
366
  listProjects,
293
367
  createIdea,
368
+ listRequirements,
369
+ updateRequirementStatus,
294
370
  createTask,
295
371
  listTasks,
296
372
  updateTaskStatus
297
373
  } from '@bernierllc/braingrid-cli-wrapper';
298
374
 
299
375
  async function workflow() {
300
- // 1. List projects
376
+ // 1. Create or list projects
377
+ const project = await createProject(
378
+ 'My Project',
379
+ 'Authentication system project'
380
+ );
381
+
382
+ // Or list existing projects
301
383
  const projects = await listProjects();
302
- const project = projects[0];
384
+ console.log(`Found ${projects.length} projects`);
303
385
 
304
386
  // 2. Create a requirement
305
387
  const requirement = await createIdea(
@@ -307,7 +389,13 @@ async function workflow() {
307
389
  project.id
308
390
  );
309
391
 
310
- // 3. Create tasks
392
+ // 3. List and update requirements
393
+ const requirements = await listRequirements(project.id);
394
+ console.log(`Project has ${requirements.length} requirements`);
395
+
396
+ await updateRequirementStatus(requirement.id, 'PLANNED');
397
+
398
+ // 4. Create tasks
311
399
  const task1 = await createTask(requirement.id, {
312
400
  title: 'Design authentication flow',
313
401
  tags: ['DESIGN']
@@ -319,16 +407,19 @@ async function workflow() {
319
407
  dependencies: [task1.id]
320
408
  });
321
409
 
322
- // 4. List tasks
410
+ // 5. List tasks
323
411
  const tasks = await listTasks({ reqId: requirement.id });
324
412
  console.log(`Created ${tasks.length} tasks`);
325
413
 
326
- // 5. Update task status
414
+ // 6. Update task status
327
415
  await updateTaskStatus(task1.id, { status: 'COMPLETED' });
328
416
  await updateTaskStatus(task2.id, {
329
417
  status: 'IN_PROGRESS',
330
418
  assignedTo: 'user-123'
331
419
  });
420
+
421
+ // 7. Mark requirement as in progress
422
+ await updateRequirementStatus(requirement.id, 'IN_PROGRESS');
332
423
  }
333
424
  ```
334
425
 
@@ -0,0 +1,8 @@
1
+ import { BrainGridProject } from '../models';
2
+ /**
3
+ * Creates a new BrainGrid project
4
+ * @param name - Project name (required)
5
+ * @param description - Project description (optional)
6
+ * @returns Promise resolving to the created project
7
+ */
8
+ export declare function createProject(name: string, description?: string): Promise<BrainGridProject>;
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+ /*
3
+ Copyright (c) 2025 Bernier LLC
4
+
5
+ This file is licensed to the client under a limited-use license.
6
+ The client may use and modify this code *only within the scope of the project it was delivered for*.
7
+ Redistribution or use in other products or commercial offerings is not permitted without written consent from Bernier LLC.
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.createProject = createProject;
11
+ const cli_1 = require("../cli");
12
+ const models_1 = require("../models");
13
+ /**
14
+ * Creates a new BrainGrid project
15
+ * @param name - Project name (required)
16
+ * @param description - Project description (optional)
17
+ * @returns Promise resolving to the created project
18
+ */
19
+ async function createProject(name, description) {
20
+ const args = ['project', 'create', '--name', name, '--format', 'json'];
21
+ if (description) {
22
+ args.push('--description', description);
23
+ }
24
+ const result = await (0, cli_1.runBrainGridCommand)(args);
25
+ // Validate response
26
+ const parsed = models_1.BrainGridProjectSchema.safeParse(result);
27
+ if (!parsed.success) {
28
+ throw new Error(`Invalid BrainGrid response: ${parsed.error.message}`);
29
+ }
30
+ return parsed.data;
31
+ }
@@ -0,0 +1,7 @@
1
+ import { BrainGridRequirement } from '../models';
2
+ /**
3
+ * Lists BrainGrid requirements
4
+ * @param projectId - Optional project ID to filter requirements
5
+ * @returns Promise resolving to array of requirements
6
+ */
7
+ export declare function listRequirements(projectId?: string): Promise<BrainGridRequirement[]>;
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ /*
3
+ Copyright (c) 2025 Bernier LLC
4
+
5
+ This file is licensed to the client under a limited-use license.
6
+ The client may use and modify this code *only within the scope of the project it was delivered for*.
7
+ Redistribution or use in other products or commercial offerings is not permitted without written consent from Bernier LLC.
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.listRequirements = listRequirements;
11
+ const cli_1 = require("../cli");
12
+ const models_1 = require("../models");
13
+ const zod_1 = require("zod");
14
+ /**
15
+ * Lists BrainGrid requirements
16
+ * @param projectId - Optional project ID to filter requirements
17
+ * @returns Promise resolving to array of requirements
18
+ */
19
+ async function listRequirements(projectId) {
20
+ const args = ['requirement', 'list', '--format', 'json'];
21
+ if (projectId) {
22
+ args.push('--project', projectId);
23
+ }
24
+ const result = await (0, cli_1.runBrainGridCommand)(args);
25
+ // Validate response
26
+ const schema = zod_1.z.array(models_1.BrainGridRequirementSchema);
27
+ const parsed = schema.safeParse(result);
28
+ if (!parsed.success) {
29
+ throw new Error(`Invalid BrainGrid response: ${parsed.error.message}`);
30
+ }
31
+ return parsed.data;
32
+ }
@@ -0,0 +1,8 @@
1
+ import { RequirementStatus } from '../models';
2
+ /**
3
+ * Updates a requirement's status
4
+ * @param requirementId - Requirement ID to update
5
+ * @param status - New status to set
6
+ * @returns Promise resolving when update is complete
7
+ */
8
+ export declare function updateRequirementStatus(requirementId: string, status: RequirementStatus): Promise<void>;
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ /*
3
+ Copyright (c) 2025 Bernier LLC
4
+
5
+ This file is licensed to the client under a limited-use license.
6
+ The client may use and modify this code *only within the scope of the project it was delivered for*.
7
+ Redistribution or use in other products or commercial offerings is not permitted without written consent from Bernier LLC.
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.updateRequirementStatus = updateRequirementStatus;
11
+ const cli_1 = require("../cli");
12
+ /**
13
+ * Updates a requirement's status
14
+ * @param requirementId - Requirement ID to update
15
+ * @param status - New status to set
16
+ * @returns Promise resolving when update is complete
17
+ */
18
+ async function updateRequirementStatus(requirementId, status) {
19
+ const args = [
20
+ 'requirement',
21
+ 'update',
22
+ requirementId,
23
+ '--status',
24
+ status,
25
+ '--format',
26
+ 'json'
27
+ ];
28
+ await (0, cli_1.runBrainGridCommand)(args);
29
+ }
package/dist/index.d.ts CHANGED
@@ -1,6 +1,9 @@
1
1
  export { BrainGridProject, BrainGridRequirement, BrainGridTask, RequirementStatus, TaskStatus, BrainGridProjectSchema, BrainGridRequirementSchema, BrainGridTaskSchema, BrainGridCliError } from './models';
2
2
  export { createIdea } from './commands/createIdea';
3
3
  export { listProjects } from './commands/listProjects';
4
+ export { createProject } from './commands/createProject';
5
+ export { listRequirements } from './commands/listRequirements';
6
+ export { updateRequirementStatus } from './commands/updateRequirementStatus';
4
7
  export { createTask, CreateTaskOptions } from './commands/createTask';
5
8
  export { updateTaskStatus, UpdateTaskOptions } from './commands/updateTaskStatus';
6
9
  export { listTasks, ListTasksOptions } from './commands/listTasks';
package/dist/index.js CHANGED
@@ -7,7 +7,7 @@ The client may use and modify this code *only within the scope of the project it
7
7
  Redistribution or use in other products or commercial offerings is not permitted without written consent from Bernier LLC.
8
8
  */
9
9
  Object.defineProperty(exports, "__esModule", { value: true });
10
- exports.listTasks = exports.updateTaskStatus = exports.createTask = exports.listProjects = exports.createIdea = exports.BrainGridCliError = exports.BrainGridTaskSchema = exports.BrainGridRequirementSchema = exports.BrainGridProjectSchema = void 0;
10
+ exports.listTasks = exports.updateTaskStatus = exports.createTask = exports.updateRequirementStatus = exports.listRequirements = exports.createProject = exports.listProjects = exports.createIdea = exports.BrainGridCliError = exports.BrainGridTaskSchema = exports.BrainGridRequirementSchema = exports.BrainGridProjectSchema = void 0;
11
11
  // BrainGrid CLI Wrapper - Type-safe wrapper for BrainGrid CLI
12
12
  // Export types and schemas
13
13
  var models_1 = require("./models");
@@ -20,6 +20,12 @@ var createIdea_1 = require("./commands/createIdea");
20
20
  Object.defineProperty(exports, "createIdea", { enumerable: true, get: function () { return createIdea_1.createIdea; } });
21
21
  var listProjects_1 = require("./commands/listProjects");
22
22
  Object.defineProperty(exports, "listProjects", { enumerable: true, get: function () { return listProjects_1.listProjects; } });
23
+ var createProject_1 = require("./commands/createProject");
24
+ Object.defineProperty(exports, "createProject", { enumerable: true, get: function () { return createProject_1.createProject; } });
25
+ var listRequirements_1 = require("./commands/listRequirements");
26
+ Object.defineProperty(exports, "listRequirements", { enumerable: true, get: function () { return listRequirements_1.listRequirements; } });
27
+ var updateRequirementStatus_1 = require("./commands/updateRequirementStatus");
28
+ Object.defineProperty(exports, "updateRequirementStatus", { enumerable: true, get: function () { return updateRequirementStatus_1.updateRequirementStatus; } });
23
29
  var createTask_1 = require("./commands/createTask");
24
30
  Object.defineProperty(exports, "createTask", { enumerable: true, get: function () { return createTask_1.createTask; } });
25
31
  var updateTaskStatus_1 = require("./commands/updateTaskStatus");
package/jest.config.cjs CHANGED
@@ -15,7 +15,6 @@ module.exports = {
15
15
  '!src/**/*.d.ts',
16
16
  ],
17
17
  coverageDirectory: 'coverage',
18
- coverageReporters: ['text', 'lcov', 'html'],
19
18
  moduleFileExtensions: ['ts', 'js', 'json'],
20
19
  setupFilesAfterEnv: [],
21
20
  };
package/package.json CHANGED
@@ -1,9 +1,19 @@
1
1
  {
2
2
  "name": "@bernierllc/braingrid-cli-wrapper",
3
- "version": "0.1.1",
3
+ "version": "0.3.0",
4
4
  "description": "Type-safe wrapper for BrainGrid CLI",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
7
+ "scripts": {
8
+ "build": "tsc",
9
+ "test": "jest",
10
+ "test:run": "jest",
11
+ "test:watch": "jest --watch",
12
+ "test:coverage": "jest --coverage",
13
+ "lint": "eslint src --ext .ts",
14
+ "clean": "rimraf dist",
15
+ "prepublishOnly": "npm run build"
16
+ },
7
17
  "keywords": [
8
18
  "braingrid",
9
19
  "cli",
@@ -34,13 +44,9 @@
34
44
  "engines": {
35
45
  "node": ">=18"
36
46
  },
37
- "scripts": {
38
- "build": "tsc",
39
- "test": "jest",
40
- "test:run": "jest",
41
- "test:watch": "jest --watch",
42
- "test:coverage": "jest --coverage",
43
- "lint": "eslint src --ext .ts",
44
- "clean": "rimraf dist"
45
- }
46
- }
47
+ "publishConfig": {
48
+ "access": "public",
49
+ "registry": "https://registry.npmjs.org/"
50
+ },
51
+ "gitHead": "af7e74b3715d56d3a193e1bb6743b337c2b0df6d"
52
+ }
@@ -0,0 +1,77 @@
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
+ // Mock CLI module before importing index
10
+ jest.mock('../cli', () => ({
11
+ runBrainGridCommand: jest.fn()
12
+ }));
13
+
14
+ // Mock all command modules to avoid loading real execa
15
+ jest.mock('../commands/createIdea', () => ({
16
+ createIdea: jest.fn()
17
+ }));
18
+ jest.mock('../commands/listProjects', () => ({
19
+ listProjects: jest.fn()
20
+ }));
21
+ jest.mock('../commands/createProject', () => ({
22
+ createProject: jest.fn()
23
+ }));
24
+ jest.mock('../commands/listRequirements', () => ({
25
+ listRequirements: jest.fn()
26
+ }));
27
+ jest.mock('../commands/updateRequirementStatus', () => ({
28
+ updateRequirementStatus: jest.fn()
29
+ }));
30
+ jest.mock('../commands/createTask', () => ({
31
+ createTask: jest.fn()
32
+ }));
33
+ jest.mock('../commands/updateTaskStatus', () => ({
34
+ updateTaskStatus: jest.fn()
35
+ }));
36
+ jest.mock('../commands/listTasks', () => ({
37
+ listTasks: jest.fn()
38
+ }));
39
+
40
+ import * as BrainGridWrapper from '../index';
41
+
42
+ describe('BrainGrid CLI Wrapper - Index Exports', () => {
43
+ it('should export all type definitions', () => {
44
+ expect(BrainGridWrapper.BrainGridProjectSchema).toBeDefined();
45
+ expect(BrainGridWrapper.BrainGridRequirementSchema).toBeDefined();
46
+ expect(BrainGridWrapper.BrainGridTaskSchema).toBeDefined();
47
+ expect(BrainGridWrapper.BrainGridCliError).toBeDefined();
48
+ });
49
+
50
+ it('should export all command functions', () => {
51
+ expect(typeof BrainGridWrapper.createIdea).toBe('function');
52
+ expect(typeof BrainGridWrapper.listProjects).toBe('function');
53
+ expect(typeof BrainGridWrapper.createProject).toBe('function');
54
+ expect(typeof BrainGridWrapper.listRequirements).toBe('function');
55
+ expect(typeof BrainGridWrapper.updateRequirementStatus).toBe('function');
56
+ expect(typeof BrainGridWrapper.createTask).toBe('function');
57
+ expect(typeof BrainGridWrapper.updateTaskStatus).toBe('function');
58
+ expect(typeof BrainGridWrapper.listTasks).toBe('function');
59
+ });
60
+
61
+ it('should export BrainGridCliError as a class', () => {
62
+ const error = new BrainGridWrapper.BrainGridCliError(
63
+ 'Test error',
64
+ 'braingrid test',
65
+ 1,
66
+ 'test stderr'
67
+ );
68
+
69
+ expect(error).toBeInstanceOf(Error);
70
+ expect(error).toBeInstanceOf(BrainGridWrapper.BrainGridCliError);
71
+ expect(error.name).toBe('BrainGridCliError');
72
+ expect(error.message).toBe('Test error');
73
+ expect(error.command).toBe('braingrid test');
74
+ expect(error.exitCode).toBe(1);
75
+ expect(error.stderr).toBe('test stderr');
76
+ });
77
+ });
@@ -0,0 +1,75 @@
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 { createProject } from './createProject';
10
+
11
+ jest.mock('../cli', () => ({
12
+ runBrainGridCommand: jest.fn()
13
+ }));
14
+
15
+ import { runBrainGridCommand } from '../cli';
16
+
17
+ describe('createProject', () => {
18
+ beforeEach(() => {
19
+ jest.clearAllMocks();
20
+ });
21
+
22
+ it('should create project with name only', async () => {
23
+ (runBrainGridCommand as jest.MockedFunction<typeof runBrainGridCommand>).mockResolvedValue({
24
+ id: 'proj-123',
25
+ name: 'Test Project'
26
+ });
27
+
28
+ const result = await createProject('Test Project');
29
+
30
+ expect(runBrainGridCommand).toHaveBeenCalledWith([
31
+ 'project',
32
+ 'create',
33
+ '--name',
34
+ 'Test Project',
35
+ '--format',
36
+ 'json'
37
+ ]);
38
+ expect(result).toEqual({
39
+ id: 'proj-123',
40
+ name: 'Test Project'
41
+ });
42
+ });
43
+
44
+ it('should create project with name and description', async () => {
45
+ (runBrainGridCommand as jest.MockedFunction<typeof runBrainGridCommand>).mockResolvedValue({
46
+ id: 'proj-456',
47
+ name: 'My Project',
48
+ description: 'Project description'
49
+ });
50
+
51
+ const result = await createProject('My Project', 'Project description');
52
+
53
+ expect(runBrainGridCommand).toHaveBeenCalledWith([
54
+ 'project',
55
+ 'create',
56
+ '--name',
57
+ 'My Project',
58
+ '--format',
59
+ 'json',
60
+ '--description',
61
+ 'Project description'
62
+ ]);
63
+ expect(result).toEqual({
64
+ id: 'proj-456',
65
+ name: 'My Project',
66
+ description: 'Project description'
67
+ });
68
+ });
69
+
70
+ it('should throw on invalid response', async () => {
71
+ (runBrainGridCommand as jest.MockedFunction<typeof runBrainGridCommand>).mockResolvedValue({ invalid: 'data' });
72
+
73
+ await expect(createProject('Test')).rejects.toThrow();
74
+ });
75
+ });
@@ -0,0 +1,37 @@
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
+
12
+ /**
13
+ * Creates a new BrainGrid project
14
+ * @param name - Project name (required)
15
+ * @param description - Project description (optional)
16
+ * @returns Promise resolving to the created project
17
+ */
18
+ export async function createProject(
19
+ name: string,
20
+ description?: string
21
+ ): Promise<BrainGridProject> {
22
+ const args = ['project', 'create', '--name', name, '--format', 'json'];
23
+
24
+ if (description) {
25
+ args.push('--description', description);
26
+ }
27
+
28
+ const result = await runBrainGridCommand(args);
29
+
30
+ // Validate response
31
+ const parsed = BrainGridProjectSchema.safeParse(result);
32
+ if (!parsed.success) {
33
+ throw new Error(`Invalid BrainGrid response: ${parsed.error.message}`);
34
+ }
35
+
36
+ return parsed.data;
37
+ }