@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.
- package/CHANGELOG.md +36 -0
- package/README.md +21 -17
- package/dist/cli.js +37 -16
- package/dist/cli.js.map +1 -1
- package/dist/handlers/agent.handlers.d.ts +12 -0
- package/dist/handlers/agent.handlers.d.ts.map +1 -0
- package/dist/handlers/agent.handlers.js +130 -0
- package/dist/handlers/agent.handlers.js.map +1 -0
- package/dist/handlers/index.d.ts +1 -0
- package/dist/handlers/index.d.ts.map +1 -1
- package/dist/handlers/index.js +1 -0
- package/dist/handlers/index.js.map +1 -1
- package/dist/handlers/init.handlers.js +4 -4
- package/dist/handlers/init.handlers.js.map +1 -1
- package/dist/handlers/project.handlers.d.ts +2 -3
- package/dist/handlers/project.handlers.d.ts.map +1 -1
- package/dist/handlers/project.handlers.js +80 -71
- package/dist/handlers/project.handlers.js.map +1 -1
- package/dist/handlers/requirement.handlers.d.ts.map +1 -1
- package/dist/handlers/requirement.handlers.js +21 -20
- package/dist/handlers/requirement.handlers.js.map +1 -1
- package/dist/handlers/status.handlers.d.ts.map +1 -1
- package/dist/handlers/status.handlers.js +5 -2
- package/dist/handlers/status.handlers.js.map +1 -1
- package/dist/handlers/task.handlers.d.ts.map +1 -1
- package/dist/handlers/task.handlers.js +45 -26
- package/dist/handlers/task.handlers.js.map +1 -1
- package/dist/rpc/server.d.ts +2 -0
- package/dist/rpc/server.d.ts.map +1 -1
- package/dist/rpc/server.js +28 -11
- package/dist/rpc/server.js.map +1 -1
- package/dist/services/agent-service.d.ts +29 -0
- package/dist/services/agent-service.d.ts.map +1 -0
- package/dist/services/agent-service.js +273 -0
- package/dist/services/agent-service.js.map +1 -0
- package/dist/services/credential-store.d.ts.map +1 -1
- package/dist/services/credential-store.js +1 -0
- package/dist/services/credential-store.js.map +1 -1
- package/dist/services/internal/github-service.d.ts +67 -0
- package/dist/services/internal/github-service.d.ts.map +1 -0
- package/dist/services/internal/github-service.js +81 -0
- package/dist/services/internal/github-service.js.map +1 -0
- package/dist/services/internal/repository-service.d.ts +79 -0
- package/dist/services/internal/repository-service.d.ts.map +1 -0
- package/dist/services/internal/repository-service.js +88 -0
- package/dist/services/internal/repository-service.js.map +1 -0
- package/dist/types/github.d.ts +105 -0
- package/dist/types/github.d.ts.map +1 -0
- package/dist/types/github.js +6 -0
- package/dist/types/github.js.map +1 -0
- package/dist/utils/cli-tools.d.ts.map +1 -1
- package/dist/utils/cli-tools.js +0 -1
- package/dist/utils/cli-tools.js.map +1 -1
- package/dist/utils/git.d.ts +5 -0
- package/dist/utils/git.d.ts.map +1 -1
- package/dist/utils/git.js +13 -0
- package/dist/utils/git.js.map +1 -1
- package/dist/utils/id-normalization.d.ts +26 -0
- package/dist/utils/id-normalization.d.ts.map +1 -0
- package/dist/utils/id-normalization.js +45 -0
- package/dist/utils/id-normalization.js.map +1 -0
- package/dist/utils/local-store.d.ts +7 -7
- package/dist/utils/local-store.d.ts.map +1 -1
- package/dist/utils/local-store.js +29 -17
- package/dist/utils/local-store.js.map +1 -1
- package/dist/utils/projects.d.ts +23 -0
- package/dist/utils/projects.d.ts.map +1 -0
- package/dist/utils/projects.js +36 -0
- package/dist/utils/projects.js.map +1 -0
- package/dist/utils/requirements.d.ts +15 -0
- package/dist/utils/requirements.d.ts.map +1 -1
- package/dist/utils/requirements.js +32 -7
- package/dist/utils/requirements.js.map +1 -1
- package/dist/utils/tasks.d.ts +12 -0
- package/dist/utils/tasks.d.ts.map +1 -1
- package/dist/utils/tasks.js +31 -6
- package/dist/utils/tasks.js.map +1 -1
- package/dist/utils/workspace-manager.d.ts +65 -0
- package/dist/utils/workspace-manager.d.ts.map +1 -0
- package/dist/utils/workspace-manager.js +98 -0
- package/dist/utils/workspace-manager.js.map +1 -0
- package/package.json +4 -1
- package/dist/services/context-manager.d.ts +0 -170
- package/dist/services/context-manager.d.ts.map +0 -1
- package/dist/services/context-manager.js +0 -261
- 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
|
|
14
|
-
|
|
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
|
|
20
|
-
|
|
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
|
|
26
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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":"AAAA;;;GAGG;AAEH,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAsB,wBAAwB,EAAE,MAAM,2BAA2B,CAAC;
|
|
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;
|
|
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
|
-
//
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
-
|
|
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 =
|
|
46
|
+
const numberMatch = trimmed.match(/^\d+$/);
|
|
22
47
|
if (numberMatch) {
|
|
23
|
-
return { type: 'req_id', value: parseInt(
|
|
48
|
+
return { type: 'req_id', value: parseInt(trimmed, 10) };
|
|
24
49
|
}
|
|
25
50
|
// Assume it's a UUID
|
|
26
|
-
return { type: 'uuid', value:
|
|
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":"
|
|
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"}
|
package/dist/utils/tasks.d.ts
CHANGED
|
@@ -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;
|
|
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"}
|
package/dist/utils/tasks.js
CHANGED
|
@@ -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
|
-
|
|
6
|
-
|
|
7
|
-
|
|
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
|
-
|
|
32
|
+
// Handle plain number format
|
|
33
|
+
const numberMatch = trimmed.match(/^\d+$/);
|
|
10
34
|
if (numberMatch) {
|
|
11
|
-
return { type: 'number', value: parseInt(
|
|
35
|
+
return { type: 'number', value: parseInt(trimmed, 10) };
|
|
12
36
|
}
|
|
13
|
-
|
|
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);
|
package/dist/utils/tasks.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tasks.js","sourceRoot":"","sources":["../../src/utils/tasks.ts"],"names":[],"mappings":"
|
|
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.
|
|
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",
|