@braingrid/cli 0.1.0 → 0.1.1

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 (86) hide show
  1. package/CHANGELOG.md +36 -0
  2. package/README.md +21 -17
  3. package/dist/cli.js +37 -16
  4. package/dist/cli.js.map +1 -1
  5. package/dist/handlers/agent.handlers.d.ts +12 -0
  6. package/dist/handlers/agent.handlers.d.ts.map +1 -0
  7. package/dist/handlers/agent.handlers.js +130 -0
  8. package/dist/handlers/agent.handlers.js.map +1 -0
  9. package/dist/handlers/index.d.ts +1 -0
  10. package/dist/handlers/index.d.ts.map +1 -1
  11. package/dist/handlers/index.js +1 -0
  12. package/dist/handlers/index.js.map +1 -1
  13. package/dist/handlers/init.handlers.js +4 -4
  14. package/dist/handlers/init.handlers.js.map +1 -1
  15. package/dist/handlers/project.handlers.d.ts +2 -3
  16. package/dist/handlers/project.handlers.d.ts.map +1 -1
  17. package/dist/handlers/project.handlers.js +80 -71
  18. package/dist/handlers/project.handlers.js.map +1 -1
  19. package/dist/handlers/requirement.handlers.d.ts.map +1 -1
  20. package/dist/handlers/requirement.handlers.js +21 -20
  21. package/dist/handlers/requirement.handlers.js.map +1 -1
  22. package/dist/handlers/status.handlers.d.ts.map +1 -1
  23. package/dist/handlers/status.handlers.js +5 -2
  24. package/dist/handlers/status.handlers.js.map +1 -1
  25. package/dist/handlers/task.handlers.d.ts.map +1 -1
  26. package/dist/handlers/task.handlers.js +45 -26
  27. package/dist/handlers/task.handlers.js.map +1 -1
  28. package/dist/rpc/server.d.ts +2 -0
  29. package/dist/rpc/server.d.ts.map +1 -1
  30. package/dist/rpc/server.js +28 -11
  31. package/dist/rpc/server.js.map +1 -1
  32. package/dist/services/agent-service.d.ts +29 -0
  33. package/dist/services/agent-service.d.ts.map +1 -0
  34. package/dist/services/agent-service.js +273 -0
  35. package/dist/services/agent-service.js.map +1 -0
  36. package/dist/services/credential-store.d.ts.map +1 -1
  37. package/dist/services/credential-store.js +1 -0
  38. package/dist/services/credential-store.js.map +1 -1
  39. package/dist/services/internal/github-service.d.ts +67 -0
  40. package/dist/services/internal/github-service.d.ts.map +1 -0
  41. package/dist/services/internal/github-service.js +81 -0
  42. package/dist/services/internal/github-service.js.map +1 -0
  43. package/dist/services/internal/repository-service.d.ts +79 -0
  44. package/dist/services/internal/repository-service.d.ts.map +1 -0
  45. package/dist/services/internal/repository-service.js +88 -0
  46. package/dist/services/internal/repository-service.js.map +1 -0
  47. package/dist/types/github.d.ts +105 -0
  48. package/dist/types/github.d.ts.map +1 -0
  49. package/dist/types/github.js +6 -0
  50. package/dist/types/github.js.map +1 -0
  51. package/dist/utils/cli-tools.d.ts.map +1 -1
  52. package/dist/utils/cli-tools.js +0 -1
  53. package/dist/utils/cli-tools.js.map +1 -1
  54. package/dist/utils/git.d.ts +5 -0
  55. package/dist/utils/git.d.ts.map +1 -1
  56. package/dist/utils/git.js +13 -0
  57. package/dist/utils/git.js.map +1 -1
  58. package/dist/utils/id-normalization.d.ts +26 -0
  59. package/dist/utils/id-normalization.d.ts.map +1 -0
  60. package/dist/utils/id-normalization.js +45 -0
  61. package/dist/utils/id-normalization.js.map +1 -0
  62. package/dist/utils/local-store.d.ts +7 -7
  63. package/dist/utils/local-store.d.ts.map +1 -1
  64. package/dist/utils/local-store.js +29 -17
  65. package/dist/utils/local-store.js.map +1 -1
  66. package/dist/utils/projects.d.ts +23 -0
  67. package/dist/utils/projects.d.ts.map +1 -0
  68. package/dist/utils/projects.js +36 -0
  69. package/dist/utils/projects.js.map +1 -0
  70. package/dist/utils/requirements.d.ts +15 -0
  71. package/dist/utils/requirements.d.ts.map +1 -1
  72. package/dist/utils/requirements.js +32 -7
  73. package/dist/utils/requirements.js.map +1 -1
  74. package/dist/utils/tasks.d.ts +12 -0
  75. package/dist/utils/tasks.d.ts.map +1 -1
  76. package/dist/utils/tasks.js +31 -6
  77. package/dist/utils/tasks.js.map +1 -1
  78. package/dist/utils/workspace-manager.d.ts +65 -0
  79. package/dist/utils/workspace-manager.d.ts.map +1 -0
  80. package/dist/utils/workspace-manager.js +98 -0
  81. package/dist/utils/workspace-manager.js.map +1 -0
  82. package/package.json +4 -1
  83. package/dist/services/context-manager.d.ts +0 -170
  84. package/dist/services/context-manager.d.ts.map +0 -1
  85. package/dist/services/context-manager.js +0 -261
  86. package/dist/services/context-manager.js.map +0 -1
@@ -5,31 +5,43 @@
5
5
  import fs from 'node:fs';
6
6
  import path from 'node:path';
7
7
  import { LocalProjectConfigSchema } from '../types/local-project.js';
8
+ import { getGitRoot } from './git.js';
8
9
  const BRAINGRID_DIR = '.braingrid';
9
10
  const PROJECT_CONFIG_FILE = 'project.json';
11
+ /**
12
+ * Get the default directory for .braingrid folder
13
+ * Prefers git repository root, falls back to current working directory
14
+ */
15
+ async function getDefaultCwd() {
16
+ const gitRoot = await getGitRoot();
17
+ return gitRoot || process.cwd();
18
+ }
10
19
  /**
11
20
  * Get the path to the .braingrid directory
12
21
  */
13
- export function getBraingridDir(cwd = process.cwd()) {
14
- return path.join(cwd, BRAINGRID_DIR);
22
+ export async function getBraingridDir(cwd) {
23
+ const dir = cwd ?? (await getDefaultCwd());
24
+ return path.join(dir, BRAINGRID_DIR);
15
25
  }
16
26
  /**
17
27
  * Get the path to the project.json file
18
28
  */
19
- export function getProjectConfigPath(cwd = process.cwd()) {
20
- return path.join(getBraingridDir(cwd), PROJECT_CONFIG_FILE);
29
+ export async function getProjectConfigPath(cwd) {
30
+ const braingridDir = await getBraingridDir(cwd);
31
+ return path.join(braingridDir, PROJECT_CONFIG_FILE);
21
32
  }
22
33
  /**
23
34
  * Check if .braingrid/project.json exists
24
35
  */
25
- export function projectConfigExists(cwd = process.cwd()) {
26
- return fs.existsSync(getProjectConfigPath(cwd));
36
+ export async function projectConfigExists(cwd) {
37
+ const configPath = await getProjectConfigPath(cwd);
38
+ return fs.existsSync(configPath);
27
39
  }
28
40
  /**
29
41
  * Ensure .braingrid directory exists
30
42
  */
31
- function ensureBraingridDir(cwd = process.cwd()) {
32
- const dir = getBraingridDir(cwd);
43
+ async function ensureBraingridDir(cwd) {
44
+ const dir = await getBraingridDir(cwd);
33
45
  if (!fs.existsSync(dir)) {
34
46
  fs.mkdirSync(dir, { recursive: true });
35
47
  }
@@ -38,8 +50,8 @@ function ensureBraingridDir(cwd = process.cwd()) {
38
50
  * Load project configuration from .braingrid/project.json
39
51
  * @throws Error if file doesn't exist or is invalid
40
52
  */
41
- export function loadProjectConfig(cwd = process.cwd()) {
42
- const configPath = getProjectConfigPath(cwd);
53
+ export async function loadProjectConfig(cwd) {
54
+ const configPath = await getProjectConfigPath(cwd);
43
55
  if (!fs.existsSync(configPath)) {
44
56
  throw new Error(`Project not initialized. Run 'braingrid init' to initialize this repository.`);
45
57
  }
@@ -51,17 +63,17 @@ export function loadProjectConfig(cwd = process.cwd()) {
51
63
  /**
52
64
  * Save project configuration to .braingrid/project.json
53
65
  */
54
- export function saveProjectConfig(config, cwd = process.cwd()) {
55
- ensureBraingridDir(cwd);
56
- const configPath = getProjectConfigPath(cwd);
66
+ export async function saveProjectConfig(config, cwd) {
67
+ await ensureBraingridDir(cwd);
68
+ const configPath = await getProjectConfigPath(cwd);
57
69
  const content = JSON.stringify(config, null, 2);
58
70
  fs.writeFileSync(configPath, content, 'utf8');
59
71
  }
60
72
  /**
61
73
  * Delete .braingrid/project.json
62
74
  */
63
- export function deleteProjectConfig(cwd = process.cwd()) {
64
- const configPath = getProjectConfigPath(cwd);
75
+ export async function deleteProjectConfig(cwd) {
76
+ const configPath = await getProjectConfigPath(cwd);
65
77
  if (fs.existsSync(configPath)) {
66
78
  fs.unlinkSync(configPath);
67
79
  }
@@ -70,9 +82,9 @@ export function deleteProjectConfig(cwd = process.cwd()) {
70
82
  * Get the local project ID from .braingrid/project.json
71
83
  * Returns the short_id (e.g., PROJ-123) if project.json exists, null otherwise
72
84
  */
73
- export function getLocalProjectId(cwd = process.cwd()) {
85
+ export async function getLocalProjectId(cwd) {
74
86
  try {
75
- const config = loadProjectConfig(cwd);
87
+ const config = await loadProjectConfig(cwd);
76
88
  return config.project_short_id;
77
89
  }
78
90
  catch {
@@ -1 +1 @@
1
- {"version":3,"file":"local-store.js","sourceRoot":"","sources":["../../src/utils/local-store.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"local-store.js","sourceRoot":"","sources":["../../src/utils/local-store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ import { Project } from '../types/project.js';
2
+ /**
3
+ * Format a project with friendly PROJ-<number> format
4
+ * Note: short_id already contains "PROJ-123" format
5
+ */
6
+ export declare function formatProjectId(project: Project): string;
7
+ /**
8
+ * Normalize project ID from various formats to API-compatible format:
9
+ * - "PROJ-123" -> "PROJ-123" (already normalized)
10
+ * - "proj-123" -> "PROJ-123" (uppercase)
11
+ * - "PROJ 123" -> "PROJ-123" (add dash, uppercase)
12
+ * - "proj 123" -> "PROJ-123" (add dash, uppercase)
13
+ * - "123" -> "PROJ-123" (add prefix)
14
+ * - "uuid-string" -> "uuid-string" (UUID, return as-is)
15
+ *
16
+ * This function takes user input and returns the ID that should be used in API calls
17
+ */
18
+ export declare function parseProjectId(input: string): string;
19
+ /**
20
+ * Find a project by either short_id or UUID
21
+ */
22
+ export declare function findProjectById(projects: Project[], identifier: string): Project | undefined;
23
+ //# sourceMappingURL=projects.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"projects.d.ts","sourceRoot":"","sources":["../../src/utils/projects.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAG9C;;;GAGG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CAExD;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEpD;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,CAW5F"}
@@ -0,0 +1,36 @@
1
+ import { normalizeId } from './id-normalization.js';
2
+ /**
3
+ * Format a project with friendly PROJ-<number> format
4
+ * Note: short_id already contains "PROJ-123" format
5
+ */
6
+ export function formatProjectId(project) {
7
+ return project.short_id;
8
+ }
9
+ /**
10
+ * Normalize project ID from various formats to API-compatible format:
11
+ * - "PROJ-123" -> "PROJ-123" (already normalized)
12
+ * - "proj-123" -> "PROJ-123" (uppercase)
13
+ * - "PROJ 123" -> "PROJ-123" (add dash, uppercase)
14
+ * - "proj 123" -> "PROJ-123" (add dash, uppercase)
15
+ * - "123" -> "PROJ-123" (add prefix)
16
+ * - "uuid-string" -> "uuid-string" (UUID, return as-is)
17
+ *
18
+ * This function takes user input and returns the ID that should be used in API calls
19
+ */
20
+ export function parseProjectId(input) {
21
+ return normalizeId('PROJ', input);
22
+ }
23
+ /**
24
+ * Find a project by either short_id or UUID
25
+ */
26
+ export function findProjectById(projects, identifier) {
27
+ const normalized = parseProjectId(identifier);
28
+ // Try to find by short_id first (handles PROJ-X format)
29
+ const byShortId = projects.find(proj => proj.short_id === normalized);
30
+ if (byShortId) {
31
+ return byShortId;
32
+ }
33
+ // Try to find by UUID
34
+ return projects.find(proj => proj.id === normalized);
35
+ }
36
+ //# sourceMappingURL=projects.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"projects.js","sourceRoot":"","sources":["../../src/utils/projects.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAEpD;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,OAAgB;IAC/C,OAAO,OAAO,CAAC,QAAQ,CAAC;AACzB,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,cAAc,CAAC,KAAa;IAC3C,OAAO,WAAW,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;AACnC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,eAAe,CAAC,QAAmB,EAAE,UAAkB;IACtE,MAAM,UAAU,GAAG,cAAc,CAAC,UAAU,CAAC,CAAC;IAE9C,wDAAwD;IACxD,MAAM,SAAS,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,KAAK,UAAU,CAAC,CAAC;IACtE,IAAI,SAAS,EAAE,CAAC;QACf,OAAO,SAAS,CAAC;IAClB,CAAC;IAED,sBAAsB;IACtB,OAAO,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,KAAK,UAAU,CAAC,CAAC;AACtD,CAAC"}
@@ -4,9 +4,24 @@ import { Requirement } from '../types/requirement.js';
4
4
  * Note: short_id already contains "REQ-123" format
5
5
  */
6
6
  export declare function formatRequirementId(requirement: Requirement): string;
7
+ /**
8
+ * Normalize requirement ID from various formats to API-compatible format:
9
+ * - "REQ-123" -> "REQ-123" (already normalized)
10
+ * - "req-123" -> "REQ-123" (uppercase)
11
+ * - "REQ 123" -> "REQ-123" (add dash, uppercase)
12
+ * - "req 123" -> "REQ-123" (add dash, uppercase)
13
+ * - "123" -> "REQ-123" (add prefix)
14
+ * - "uuid-string" -> "uuid-string" (UUID, return as-is)
15
+ *
16
+ * This function takes user input and returns the ID that should be used in API calls
17
+ */
18
+ export declare function normalizeRequirementId(input: string): string;
7
19
  /**
8
20
  * Parse a requirement ID from various formats:
9
21
  * - "REQ-123" -> { type: 'req_id', value: 123 }
22
+ * - "req-123" -> { type: 'req_id', value: 123 }
23
+ * - "REQ 123" -> { type: 'req_id', value: 123 }
24
+ * - "req 123" -> { type: 'req_id', value: 123 }
10
25
  * - "123" -> { type: 'req_id', value: 123 }
11
26
  * - "uuid-string" -> { type: 'uuid', value: 'uuid-string' }
12
27
  */
@@ -1 +1 @@
1
- {"version":3,"file":"requirements.d.ts","sourceRoot":"","sources":["../../src/utils/requirements.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAEtD;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,WAAW,GAAG,MAAM,CAEpE;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG;IAClD,IAAI,EAAE,QAAQ,GAAG,MAAM,CAAC;IACxB,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC;CACvB,CAeA;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAClC,YAAY,EAAE,WAAW,EAAE,EAC3B,UAAU,EAAE,MAAM,GAChB,WAAW,GAAG,SAAS,CAQzB;AAED;;;GAGG;AACH,wBAAgB,yBAAyB,CAAC,UAAU,EAAE,MAAM,GAAG;IAAE,EAAE,CAAC,EAAE,MAAM,CAAA;CAAE,CAS7E"}
1
+ {"version":3,"file":"requirements.d.ts","sourceRoot":"","sources":["../../src/utils/requirements.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAGtD;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,WAAW,GAAG,MAAM,CAEpE;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAE5D;AAED;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG;IAClD,IAAI,EAAE,QAAQ,GAAG,MAAM,CAAC;IACxB,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC;CACvB,CAwBA;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAClC,YAAY,EAAE,WAAW,EAAE,EAC3B,UAAU,EAAE,MAAM,GAChB,WAAW,GAAG,SAAS,CAQzB;AAED;;;GAGG;AACH,wBAAgB,yBAAyB,CAAC,UAAU,EAAE,MAAM,GAAG;IAAE,EAAE,CAAC,EAAE,MAAM,CAAA;CAAE,CAS7E"}
@@ -1,3 +1,4 @@
1
+ import { normalizeId } from './id-normalization.js';
1
2
  /**
2
3
  * Format a requirement with friendly REQ-<number> format
3
4
  * Note: short_id already contains "REQ-123" format
@@ -5,25 +6,49 @@
5
6
  export function formatRequirementId(requirement) {
6
7
  return requirement.short_id || `REQ-${requirement.req_id || 0}`;
7
8
  }
9
+ /**
10
+ * Normalize requirement ID from various formats to API-compatible format:
11
+ * - "REQ-123" -> "REQ-123" (already normalized)
12
+ * - "req-123" -> "REQ-123" (uppercase)
13
+ * - "REQ 123" -> "REQ-123" (add dash, uppercase)
14
+ * - "req 123" -> "REQ-123" (add dash, uppercase)
15
+ * - "123" -> "REQ-123" (add prefix)
16
+ * - "uuid-string" -> "uuid-string" (UUID, return as-is)
17
+ *
18
+ * This function takes user input and returns the ID that should be used in API calls
19
+ */
20
+ export function normalizeRequirementId(input) {
21
+ return normalizeId('REQ', input);
22
+ }
8
23
  /**
9
24
  * Parse a requirement ID from various formats:
10
25
  * - "REQ-123" -> { type: 'req_id', value: 123 }
26
+ * - "req-123" -> { type: 'req_id', value: 123 }
27
+ * - "REQ 123" -> { type: 'req_id', value: 123 }
28
+ * - "req 123" -> { type: 'req_id', value: 123 }
11
29
  * - "123" -> { type: 'req_id', value: 123 }
12
30
  * - "uuid-string" -> { type: 'uuid', value: 'uuid-string' }
13
31
  */
14
32
  export function parseRequirementId(input) {
15
- // Handle REQ-123 format
16
- const reqMatch = input.match(/^REQ-(\d+)$/i);
17
- if (reqMatch) {
18
- return { type: 'req_id', value: parseInt(reqMatch[1], 10) };
33
+ // Trim whitespace
34
+ const trimmed = input.trim();
35
+ // Handle "REQ-123" or "req-123" format (with dash)
36
+ const reqDashMatch = trimmed.match(/^REQ-(\d+)$/i);
37
+ if (reqDashMatch) {
38
+ return { type: 'req_id', value: parseInt(reqDashMatch[1], 10) };
39
+ }
40
+ // Handle "REQ 123" or "req 123" format (with space)
41
+ const reqSpaceMatch = trimmed.match(/^REQ\s+(\d+)$/i);
42
+ if (reqSpaceMatch) {
43
+ return { type: 'req_id', value: parseInt(reqSpaceMatch[1], 10) };
19
44
  }
20
45
  // Handle plain number format
21
- const numberMatch = input.match(/^\d+$/);
46
+ const numberMatch = trimmed.match(/^\d+$/);
22
47
  if (numberMatch) {
23
- return { type: 'req_id', value: parseInt(input, 10) };
48
+ return { type: 'req_id', value: parseInt(trimmed, 10) };
24
49
  }
25
50
  // Assume it's a UUID
26
- return { type: 'uuid', value: input };
51
+ return { type: 'uuid', value: trimmed };
27
52
  }
28
53
  /**
29
54
  * Find a requirement by either req_id or UUID
@@ -1 +1 @@
1
- {"version":3,"file":"requirements.js","sourceRoot":"","sources":["../../src/utils/requirements.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CAAC,WAAwB;IAC3D,OAAO,WAAW,CAAC,QAAQ,IAAI,OAAO,WAAW,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;AACjE,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,kBAAkB,CAAC,KAAa;IAI/C,wBAAwB;IACxB,MAAM,QAAQ,GAAG,KAAK,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;IAC7C,IAAI,QAAQ,EAAE,CAAC;QACd,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC;IAC7D,CAAC;IAED,6BAA6B;IAC7B,MAAM,WAAW,GAAG,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IACzC,IAAI,WAAW,EAAE,CAAC;QACjB,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,CAAC,KAAK,EAAE,EAAE,CAAC,EAAE,CAAC;IACvD,CAAC;IAED,qBAAqB;IACrB,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;AACvC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,mBAAmB,CAClC,YAA2B,EAC3B,UAAkB;IAElB,MAAM,MAAM,GAAG,kBAAkB,CAAC,UAAU,CAAC,CAAC;IAE9C,IAAI,MAAM,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC9B,OAAO,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,QAAQ,KAAK,OAAO,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC;IACzE,CAAC;SAAM,CAAC;QACP,OAAO,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,KAAK,MAAM,CAAC,KAAK,CAAC,CAAC;IAC1D,CAAC;AACF,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,yBAAyB,CAAC,UAAkB;IAC3D,MAAM,MAAM,GAAG,kBAAkB,CAAC,UAAU,CAAC,CAAC;IAE9C,IAAI,MAAM,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;QAC5B,OAAO,EAAE,EAAE,EAAE,MAAM,CAAC,KAAe,EAAE,CAAC;IACvC,CAAC;SAAM,CAAC;QACP,+CAA+C;QAC/C,OAAO,EAAE,CAAC;IACX,CAAC;AACF,CAAC"}
1
+ {"version":3,"file":"requirements.js","sourceRoot":"","sources":["../../src/utils/requirements.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAEpD;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CAAC,WAAwB;IAC3D,OAAO,WAAW,CAAC,QAAQ,IAAI,OAAO,WAAW,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;AACjE,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,sBAAsB,CAAC,KAAa;IACnD,OAAO,WAAW,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;AAClC,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,kBAAkB,CAAC,KAAa;IAI/C,kBAAkB;IAClB,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IAE7B,mDAAmD;IACnD,MAAM,YAAY,GAAG,OAAO,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;IACnD,IAAI,YAAY,EAAE,CAAC;QAClB,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC;IACjE,CAAC;IAED,oDAAoD;IACpD,MAAM,aAAa,GAAG,OAAO,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC;IACtD,IAAI,aAAa,EAAE,CAAC;QACnB,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC;IAClE,CAAC;IAED,6BAA6B;IAC7B,MAAM,WAAW,GAAG,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAC3C,IAAI,WAAW,EAAE,CAAC;QACjB,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,CAAC,OAAO,EAAE,EAAE,CAAC,EAAE,CAAC;IACzD,CAAC;IAED,qBAAqB;IACrB,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;AACzC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,mBAAmB,CAClC,YAA2B,EAC3B,UAAkB;IAElB,MAAM,MAAM,GAAG,kBAAkB,CAAC,UAAU,CAAC,CAAC;IAE9C,IAAI,MAAM,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC9B,OAAO,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,QAAQ,KAAK,OAAO,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC;IACzE,CAAC;SAAM,CAAC;QACP,OAAO,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,KAAK,MAAM,CAAC,KAAK,CAAC,CAAC;IAC1D,CAAC;AACF,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,yBAAyB,CAAC,UAAkB;IAC3D,MAAM,MAAM,GAAG,kBAAkB,CAAC,UAAU,CAAC,CAAC;IAE9C,IAAI,MAAM,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;QAC5B,OAAO,EAAE,EAAE,EAAE,MAAM,CAAC,KAAe,EAAE,CAAC;IACvC,CAAC;SAAM,CAAC;QACP,+CAA+C;QAC/C,OAAO,EAAE,CAAC;IACX,CAAC;AACF,CAAC"}
@@ -1,5 +1,17 @@
1
1
  import { RequirementTask as Task } from '../types/requirement.js';
2
2
  export declare function formatTaskId(task: Task): string;
3
+ /**
4
+ * Normalize task ID from various formats to API-compatible format:
5
+ * - "TASK-123" -> "TASK-123" (already normalized)
6
+ * - "task-123" -> "TASK-123" (uppercase)
7
+ * - "TASK 123" -> "TASK-123" (add dash, uppercase)
8
+ * - "task 123" -> "TASK-123" (add dash, uppercase)
9
+ * - "123" -> "TASK-123" (add prefix)
10
+ * - "uuid-string" -> "uuid-string" (UUID, return as-is)
11
+ *
12
+ * This function takes user input and returns the ID that should be used in API calls
13
+ */
14
+ export declare function normalizeTaskId(input: string): string;
3
15
  export declare function parseTaskId(input: string): {
4
16
  type: 'number' | 'uuid';
5
17
  value: string | number;
@@ -1 +1 @@
1
- {"version":3,"file":"tasks.d.ts","sourceRoot":"","sources":["../../src/utils/tasks.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,IAAI,IAAI,EAAE,MAAM,yBAAyB,CAAC;AAElE,wBAAgB,YAAY,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAE/C;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,QAAQ,GAAG,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAA;CAAE,CAY9F;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAQ3E;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAaxD"}
1
+ {"version":3,"file":"tasks.d.ts","sourceRoot":"","sources":["../../src/utils/tasks.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,IAAI,IAAI,EAAE,MAAM,yBAAyB,CAAC;AAGlE,wBAAgB,YAAY,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAE/C;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAErD;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,QAAQ,GAAG,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAA;CAAE,CAwB9F;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAQ3E;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAaxD"}
@@ -1,16 +1,41 @@
1
+ import { normalizeId } from './id-normalization.js';
1
2
  export function formatTaskId(task) {
2
3
  return `TASK-${task.number}`;
3
4
  }
5
+ /**
6
+ * Normalize task ID from various formats to API-compatible format:
7
+ * - "TASK-123" -> "TASK-123" (already normalized)
8
+ * - "task-123" -> "TASK-123" (uppercase)
9
+ * - "TASK 123" -> "TASK-123" (add dash, uppercase)
10
+ * - "task 123" -> "TASK-123" (add dash, uppercase)
11
+ * - "123" -> "TASK-123" (add prefix)
12
+ * - "uuid-string" -> "uuid-string" (UUID, return as-is)
13
+ *
14
+ * This function takes user input and returns the ID that should be used in API calls
15
+ */
16
+ export function normalizeTaskId(input) {
17
+ return normalizeId('TASK', input);
18
+ }
4
19
  export function parseTaskId(input) {
5
- const taskMatch = input.match(/^TASK-(\d+)$/i);
6
- if (taskMatch) {
7
- return { type: 'number', value: parseInt(taskMatch[1], 10) };
20
+ // Trim whitespace
21
+ const trimmed = input.trim();
22
+ // Handle "TASK-123" or "task-123" format (with dash)
23
+ const taskDashMatch = trimmed.match(/^TASK-(\d+)$/i);
24
+ if (taskDashMatch) {
25
+ return { type: 'number', value: parseInt(taskDashMatch[1], 10) };
26
+ }
27
+ // Handle "TASK 123" or "task 123" format (with space)
28
+ const taskSpaceMatch = trimmed.match(/^TASK\s+(\d+)$/i);
29
+ if (taskSpaceMatch) {
30
+ return { type: 'number', value: parseInt(taskSpaceMatch[1], 10) };
8
31
  }
9
- const numberMatch = input.match(/^\d+$/);
32
+ // Handle plain number format
33
+ const numberMatch = trimmed.match(/^\d+$/);
10
34
  if (numberMatch) {
11
- return { type: 'number', value: parseInt(input, 10) };
35
+ return { type: 'number', value: parseInt(trimmed, 10) };
12
36
  }
13
- return { type: 'uuid', value: input };
37
+ // Assume it's a UUID
38
+ return { type: 'uuid', value: trimmed };
14
39
  }
15
40
  export function findTaskById(tasks, identifier) {
16
41
  const parsed = parseTaskId(identifier);
@@ -1 +1 @@
1
- {"version":3,"file":"tasks.js","sourceRoot":"","sources":["../../src/utils/tasks.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,YAAY,CAAC,IAAU;IACtC,OAAO,QAAQ,IAAI,CAAC,MAAM,EAAE,CAAC;AAC9B,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,KAAa;IACxC,MAAM,SAAS,GAAG,KAAK,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC;IAC/C,IAAI,SAAS,EAAE,CAAC;QACf,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC;IAC9D,CAAC;IAED,MAAM,WAAW,GAAG,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IACzC,IAAI,WAAW,EAAE,CAAC;QACjB,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,CAAC,KAAK,EAAE,EAAE,CAAC,EAAE,CAAC;IACvD,CAAC;IAED,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;AACvC,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,KAAa,EAAE,UAAkB;IAC7D,MAAM,MAAM,GAAG,WAAW,CAAC,UAAU,CAAC,CAAC;IAEvC,IAAI,MAAM,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC9B,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,KAAK,MAAM,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC;IACjE,CAAC;SAAM,CAAC;QACP,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,KAAK,MAAM,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC;IAC7D,CAAC;AACF,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,MAAc;IAC/C,QAAQ,MAAM,EAAE,CAAC;QAChB,KAAK,SAAS;YACb,OAAO,IAAI,CAAC;QACb,KAAK,aAAa;YACjB,OAAO,IAAI,CAAC;QACb,KAAK,WAAW;YACf,OAAO,GAAG,CAAC;QACZ,KAAK,WAAW;YACf,OAAO,GAAG,CAAC;QACZ;YACC,OAAO,IAAI,CAAC;IACd,CAAC;AACF,CAAC"}
1
+ {"version":3,"file":"tasks.js","sourceRoot":"","sources":["../../src/utils/tasks.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAEpD,MAAM,UAAU,YAAY,CAAC,IAAU;IACtC,OAAO,QAAQ,IAAI,CAAC,MAAM,EAAE,CAAC;AAC9B,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,eAAe,CAAC,KAAa;IAC5C,OAAO,WAAW,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;AACnC,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,KAAa;IACxC,kBAAkB;IAClB,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IAE7B,qDAAqD;IACrD,MAAM,aAAa,GAAG,OAAO,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC;IACrD,IAAI,aAAa,EAAE,CAAC;QACnB,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC;IAClE,CAAC;IAED,sDAAsD;IACtD,MAAM,cAAc,GAAG,OAAO,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;IACxD,IAAI,cAAc,EAAE,CAAC;QACpB,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC;IACnE,CAAC;IAED,6BAA6B;IAC7B,MAAM,WAAW,GAAG,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAC3C,IAAI,WAAW,EAAE,CAAC;QACjB,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,CAAC,OAAO,EAAE,EAAE,CAAC,EAAE,CAAC;IACzD,CAAC;IAED,qBAAqB;IACrB,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;AACzC,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,KAAa,EAAE,UAAkB;IAC7D,MAAM,MAAM,GAAG,WAAW,CAAC,UAAU,CAAC,CAAC;IAEvC,IAAI,MAAM,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC9B,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,KAAK,MAAM,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC;IACjE,CAAC;SAAM,CAAC;QACP,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,KAAK,MAAM,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC;IAC7D,CAAC;AACF,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,MAAc;IAC/C,QAAQ,MAAM,EAAE,CAAC;QAChB,KAAK,SAAS;YACb,OAAO,IAAI,CAAC;QACb,KAAK,aAAa;YACjB,OAAO,IAAI,CAAC;QACb,KAAK,WAAW;YACf,OAAO,GAAG,CAAC;QACZ,KAAK,WAAW;YACf,OAAO,GAAG,CAAC;QACZ;YACC,OAAO,IAAI,CAAC;IACd,CAAC;AACF,CAAC"}
@@ -0,0 +1,65 @@
1
+ /**
2
+ * Workspace Manager
3
+ *
4
+ * Manages workspace-level state including:
5
+ * - Current project resolution (from .braingrid/project.json)
6
+ * - Active requirement context (session-scoped)
7
+ *
8
+ * This provides a centralized way to access workspace context across handlers.
9
+ */
10
+ /**
11
+ * Result type for project resolution
12
+ */
13
+ export type WorkspaceProjectResult = {
14
+ success: true;
15
+ projectId: string;
16
+ } | {
17
+ success: false;
18
+ error: string;
19
+ };
20
+ /**
21
+ * Manages workspace-level state
22
+ *
23
+ * Singleton pattern - one instance per CLI session
24
+ */
25
+ export declare class WorkspaceManager {
26
+ private activeRequirementId;
27
+ /**
28
+ * Get the project ID for the current workspace
29
+ *
30
+ * Resolution order:
31
+ * 1. If explicitProjectId provided → normalize and return it
32
+ * 2. Check .braingrid/project.json for configured project (at git root)
33
+ * 3. If not initialized → return error with initialization instructions
34
+ *
35
+ * @param explicitProjectId - Optional project ID from -p or --project flag
36
+ * @returns Result with either projectId (normalized) or error message
37
+ */
38
+ getProject(explicitProjectId?: string): Promise<WorkspaceProjectResult>;
39
+ /**
40
+ * Set the active requirement for this workspace session
41
+ *
42
+ * This is used to automatically include requirement context in agent conversations
43
+ *
44
+ * @param requirementId - The requirement ID to set as active
45
+ */
46
+ setActiveRequirement(requirementId: string): void;
47
+ /**
48
+ * Get the currently active requirement ID
49
+ *
50
+ * @returns The active requirement ID or null if none set
51
+ */
52
+ getActiveRequirement(): string | null;
53
+ /**
54
+ * Clear the active requirement
55
+ */
56
+ clearActiveRequirement(): void;
57
+ /**
58
+ * Check if there is an active requirement set
59
+ *
60
+ * @returns true if a requirement is active, false otherwise
61
+ */
62
+ hasActiveRequirement(): boolean;
63
+ }
64
+ export declare const workspaceManager: WorkspaceManager;
65
+ //# sourceMappingURL=workspace-manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workspace-manager.d.ts","sourceRoot":"","sources":["../../src/utils/workspace-manager.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAMH;;GAEG;AACH,MAAM,MAAM,sBAAsB,GAC/B;IACA,OAAO,EAAE,IAAI,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;CACjB,GACD;IACA,OAAO,EAAE,KAAK,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;CACb,CAAC;AAEL;;;;GAIG;AACH,qBAAa,gBAAgB;IAC5B,OAAO,CAAC,mBAAmB,CAAuB;IAElD;;;;;;;;;;OAUG;IACG,UAAU,CAAC,iBAAiB,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,sBAAsB,CAAC;IAkC7E;;;;;;OAMG;IACH,oBAAoB,CAAC,aAAa,EAAE,MAAM,GAAG,IAAI;IAIjD;;;;OAIG;IACH,oBAAoB,IAAI,MAAM,GAAG,IAAI;IAIrC;;OAEG;IACH,sBAAsB,IAAI,IAAI;IAI9B;;;;OAIG;IACH,oBAAoB,IAAI,OAAO;CAG/B;AAGD,eAAO,MAAM,gBAAgB,kBAAyB,CAAC"}
@@ -0,0 +1,98 @@
1
+ /**
2
+ * Workspace Manager
3
+ *
4
+ * Manages workspace-level state including:
5
+ * - Current project resolution (from .braingrid/project.json)
6
+ * - Active requirement context (session-scoped)
7
+ *
8
+ * This provides a centralized way to access workspace context across handlers.
9
+ */
10
+ import chalk from 'chalk';
11
+ import { getLocalProjectId } from './local-store.js';
12
+ import { parseProjectId } from './projects.js';
13
+ /**
14
+ * Manages workspace-level state
15
+ *
16
+ * Singleton pattern - one instance per CLI session
17
+ */
18
+ export class WorkspaceManager {
19
+ constructor() {
20
+ this.activeRequirementId = null;
21
+ }
22
+ /**
23
+ * Get the project ID for the current workspace
24
+ *
25
+ * Resolution order:
26
+ * 1. If explicitProjectId provided → normalize and return it
27
+ * 2. Check .braingrid/project.json for configured project (at git root)
28
+ * 3. If not initialized → return error with initialization instructions
29
+ *
30
+ * @param explicitProjectId - Optional project ID from -p or --project flag
31
+ * @returns Result with either projectId (normalized) or error message
32
+ */
33
+ async getProject(explicitProjectId) {
34
+ // If explicit project provided via flag
35
+ if (explicitProjectId) {
36
+ const normalized = parseProjectId(explicitProjectId);
37
+ return {
38
+ success: true,
39
+ projectId: normalized,
40
+ };
41
+ }
42
+ // Try to get from .braingrid/project.json (searches git root first)
43
+ const localProjectId = await getLocalProjectId();
44
+ if (localProjectId) {
45
+ const normalized = parseProjectId(localProjectId);
46
+ return {
47
+ success: true,
48
+ projectId: normalized,
49
+ };
50
+ }
51
+ // Not initialized
52
+ return {
53
+ success: false,
54
+ error: chalk.red('❌ No project specified and no local project found.') +
55
+ '\n\n' +
56
+ chalk.dim('To initialize this workspace, run:\n') +
57
+ chalk.cyan(' braingrid init --wizard') +
58
+ '\n\n' +
59
+ chalk.dim('Or specify a project explicitly:\n') +
60
+ chalk.cyan(' braingrid <command> -p PROJ-123'),
61
+ };
62
+ }
63
+ /**
64
+ * Set the active requirement for this workspace session
65
+ *
66
+ * This is used to automatically include requirement context in agent conversations
67
+ *
68
+ * @param requirementId - The requirement ID to set as active
69
+ */
70
+ setActiveRequirement(requirementId) {
71
+ this.activeRequirementId = requirementId;
72
+ }
73
+ /**
74
+ * Get the currently active requirement ID
75
+ *
76
+ * @returns The active requirement ID or null if none set
77
+ */
78
+ getActiveRequirement() {
79
+ return this.activeRequirementId;
80
+ }
81
+ /**
82
+ * Clear the active requirement
83
+ */
84
+ clearActiveRequirement() {
85
+ this.activeRequirementId = null;
86
+ }
87
+ /**
88
+ * Check if there is an active requirement set
89
+ *
90
+ * @returns true if a requirement is active, false otherwise
91
+ */
92
+ hasActiveRequirement() {
93
+ return this.activeRequirementId !== null;
94
+ }
95
+ }
96
+ // Export singleton instance
97
+ export const workspaceManager = new WorkspaceManager();
98
+ //# sourceMappingURL=workspace-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workspace-manager.js","sourceRoot":"","sources":["../../src/utils/workspace-manager.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAe/C;;;;GAIG;AACH,MAAM,OAAO,gBAAgB;IAA7B;QACS,wBAAmB,GAAkB,IAAI,CAAC;IAkFnD,CAAC;IAhFA;;;;;;;;;;OAUG;IACH,KAAK,CAAC,UAAU,CAAC,iBAA0B;QAC1C,wCAAwC;QACxC,IAAI,iBAAiB,EAAE,CAAC;YACvB,MAAM,UAAU,GAAG,cAAc,CAAC,iBAAiB,CAAC,CAAC;YACrD,OAAO;gBACN,OAAO,EAAE,IAAI;gBACb,SAAS,EAAE,UAAU;aACrB,CAAC;QACH,CAAC;QAED,oEAAoE;QACpE,MAAM,cAAc,GAAG,MAAM,iBAAiB,EAAE,CAAC;QACjD,IAAI,cAAc,EAAE,CAAC;YACpB,MAAM,UAAU,GAAG,cAAc,CAAC,cAAc,CAAC,CAAC;YAClD,OAAO;gBACN,OAAO,EAAE,IAAI;gBACb,SAAS,EAAE,UAAU;aACrB,CAAC;QACH,CAAC;QAED,kBAAkB;QAClB,OAAO;YACN,OAAO,EAAE,KAAK;YACd,KAAK,EACJ,KAAK,CAAC,GAAG,CAAC,oDAAoD,CAAC;gBAC/D,MAAM;gBACN,KAAK,CAAC,GAAG,CAAC,sCAAsC,CAAC;gBACjD,KAAK,CAAC,IAAI,CAAC,2BAA2B,CAAC;gBACvC,MAAM;gBACN,KAAK,CAAC,GAAG,CAAC,oCAAoC,CAAC;gBAC/C,KAAK,CAAC,IAAI,CAAC,mCAAmC,CAAC;SAChD,CAAC;IACH,CAAC;IAED;;;;;;OAMG;IACH,oBAAoB,CAAC,aAAqB;QACzC,IAAI,CAAC,mBAAmB,GAAG,aAAa,CAAC;IAC1C,CAAC;IAED;;;;OAIG;IACH,oBAAoB;QACnB,OAAO,IAAI,CAAC,mBAAmB,CAAC;IACjC,CAAC;IAED;;OAEG;IACH,sBAAsB;QACrB,IAAI,CAAC,mBAAmB,GAAG,IAAI,CAAC;IACjC,CAAC;IAED;;;;OAIG;IACH,oBAAoB;QACnB,OAAO,IAAI,CAAC,mBAAmB,KAAK,IAAI,CAAC;IAC1C,CAAC;CACD;AAED,4BAA4B;AAC5B,MAAM,CAAC,MAAM,gBAAgB,GAAG,IAAI,gBAAgB,EAAE,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@braingrid/cli",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "BrainGrid - Turn thoughts into AI-ready specs. Command-line interface for spec-driven development.",
5
5
  "type": "module",
6
6
  "main": "dist/cli.js",
@@ -38,6 +38,7 @@
38
38
  "chalk": "^5.3.0",
39
39
  "commander": "^12.0.0",
40
40
  "conf": "13.0.1",
41
+ "ink": "^6.3.1",
41
42
  "node-machine-id": "1.1.12",
42
43
  "open": "^10.1.0",
43
44
  "zod": "^4.1.11",
@@ -62,6 +63,8 @@
62
63
  "build:prod": "NODE_ENV=production tsc -p .",
63
64
  "dev": "tsx src/cli.ts",
64
65
  "dev:local": "NODE_ENV=local tsx src/cli.ts",
66
+ "docs:fetch-openapi": "mkdir -p docs && gh api repos/BrainGridAI/braingrid-app/contents/src/app/api/v1/openapi.yaml | jq -r '.content' | base64 -D > docs/openapi.yaml",
67
+ "docs:sync": "bash scripts/sync-docs-to-braingrid.sh",
65
68
  "start": "NODE_ENV=production node dist/cli.js",
66
69
  "start:local": "NODE_ENV=local node dist/cli.js",
67
70
  "start:dev": "NODE_ENV=development node dist/cli.js",