context-first-cli 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +144 -0
- package/dist/commands/doctor.d.ts +2 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +253 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/feature.d.ts +11 -0
- package/dist/commands/feature.d.ts.map +1 -0
- package/dist/commands/feature.js +224 -0
- package/dist/commands/feature.js.map +1 -0
- package/dist/commands/init.d.ts +2 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +95 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/scaffold-orchestrator.d.ts +2 -0
- package/dist/commands/scaffold-orchestrator.d.ts.map +1 -0
- package/dist/commands/scaffold-orchestrator.js +203 -0
- package/dist/commands/scaffold-orchestrator.js.map +1 -0
- package/dist/commands/status.d.ts +2 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +102 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +54 -0
- package/dist/index.js.map +1 -0
- package/dist/utils/config.d.ts +67 -0
- package/dist/utils/config.d.ts.map +1 -0
- package/dist/utils/config.js +118 -0
- package/dist/utils/config.js.map +1 -0
- package/dist/utils/git.d.ts +35 -0
- package/dist/utils/git.d.ts.map +1 -0
- package/dist/utils/git.js +152 -0
- package/dist/utils/git.js.map +1 -0
- package/package.json +59 -0
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.statusCommand = statusCommand;
|
|
7
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
8
|
+
const path_1 = __importDefault(require("path"));
|
|
9
|
+
const config_1 = require("../utils/config");
|
|
10
|
+
const git_1 = require("../utils/git");
|
|
11
|
+
async function statusCommand() {
|
|
12
|
+
console.log(chalk_1.default.blue.bold('\nš Workspace Status\n'));
|
|
13
|
+
// Try to find workspace metadata in current directory or parent
|
|
14
|
+
const metadata = await (0, config_1.loadWorkspaceMetadata)(process.cwd());
|
|
15
|
+
if (!metadata) {
|
|
16
|
+
// Check if we're inside a workspace by looking for .workspace.json in parent directories
|
|
17
|
+
let currentDir = process.cwd();
|
|
18
|
+
let workspaceRoot = null;
|
|
19
|
+
while (true) {
|
|
20
|
+
const metadataPath = path_1.default.join(currentDir, '.workspace.json');
|
|
21
|
+
if (await (0, config_1.pathExists)(metadataPath)) {
|
|
22
|
+
workspaceRoot = currentDir;
|
|
23
|
+
break;
|
|
24
|
+
}
|
|
25
|
+
const parentDir = path_1.default.dirname(currentDir);
|
|
26
|
+
if (parentDir === currentDir) {
|
|
27
|
+
// Reached root
|
|
28
|
+
break;
|
|
29
|
+
}
|
|
30
|
+
currentDir = parentDir;
|
|
31
|
+
}
|
|
32
|
+
if (!workspaceRoot) {
|
|
33
|
+
(0, config_1.exitWithError)('Not inside a workspace. Run this command from within a feature workspace.');
|
|
34
|
+
}
|
|
35
|
+
const workspaceMetadata = await (0, config_1.loadWorkspaceMetadata)(workspaceRoot);
|
|
36
|
+
if (!workspaceMetadata) {
|
|
37
|
+
(0, config_1.exitWithError)('Could not load workspace metadata');
|
|
38
|
+
}
|
|
39
|
+
await displayStatus(workspaceRoot, workspaceMetadata);
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
await displayStatus(process.cwd(), metadata);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
async function displayStatus(workspaceRoot, metadata) {
|
|
46
|
+
// Display workspace info
|
|
47
|
+
console.log(chalk_1.default.bold('Workspace Information:'));
|
|
48
|
+
console.log(chalk_1.default.gray(` Issue ID: ${chalk_1.default.cyan(metadata.issueId)}`));
|
|
49
|
+
console.log(chalk_1.default.gray(` Created: ${new Date(metadata.createdAt).toLocaleString()}`));
|
|
50
|
+
console.log(chalk_1.default.gray(` Last Updated: ${new Date(metadata.lastUpdated).toLocaleString()}`));
|
|
51
|
+
console.log(chalk_1.default.gray(` Status: ${metadata.status === 'active' ? chalk_1.default.green('active') : chalk_1.default.gray('archived')}`));
|
|
52
|
+
console.log(chalk_1.default.gray(` Location: ${workspaceRoot}`));
|
|
53
|
+
// Display repository statuses
|
|
54
|
+
console.log(chalk_1.default.bold('\nš¦ Repositories:\n'));
|
|
55
|
+
for (const repoId of metadata.repositories) {
|
|
56
|
+
const repoPath = path_1.default.join(workspaceRoot, repoId);
|
|
57
|
+
if (!(await (0, config_1.pathExists)(repoPath))) {
|
|
58
|
+
console.log(chalk_1.default.yellow(` ${repoId}: Directory not found`));
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
const status = await (0, git_1.getRepoStatus)(repoPath);
|
|
62
|
+
console.log(chalk_1.default.cyan(` ${repoId}:`));
|
|
63
|
+
console.log(chalk_1.default.gray(` Branch: ${status.branch || 'unknown'}`));
|
|
64
|
+
if (status.modified > 0) {
|
|
65
|
+
console.log(chalk_1.default.yellow(` Modified files: ${status.modified}`));
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
console.log(chalk_1.default.gray(` Modified files: 0`));
|
|
69
|
+
}
|
|
70
|
+
if (status.staged > 0) {
|
|
71
|
+
console.log(chalk_1.default.green(` Staged files: ${status.staged}`));
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
console.log(chalk_1.default.gray(` Staged files: 0`));
|
|
75
|
+
}
|
|
76
|
+
if (status.ahead > 0) {
|
|
77
|
+
console.log(chalk_1.default.blue(` Commits ahead: ${status.ahead}`));
|
|
78
|
+
}
|
|
79
|
+
if (status.behind > 0) {
|
|
80
|
+
console.log(chalk_1.default.yellow(` Commits behind: ${status.behind}`));
|
|
81
|
+
}
|
|
82
|
+
console.log('');
|
|
83
|
+
}
|
|
84
|
+
// Summary
|
|
85
|
+
const allStatuses = await Promise.all(metadata.repositories.map(async (repoId) => {
|
|
86
|
+
const repoPath = path_1.default.join(workspaceRoot, repoId);
|
|
87
|
+
if (await (0, config_1.pathExists)(repoPath)) {
|
|
88
|
+
return await (0, git_1.getRepoStatus)(repoPath);
|
|
89
|
+
}
|
|
90
|
+
return null;
|
|
91
|
+
}));
|
|
92
|
+
const totalModified = allStatuses.reduce((sum, s) => sum + (s?.modified || 0), 0);
|
|
93
|
+
const totalStaged = allStatuses.reduce((sum, s) => sum + (s?.staged || 0), 0);
|
|
94
|
+
console.log(chalk_1.default.bold('Summary:'));
|
|
95
|
+
if (totalModified > 0 || totalStaged > 0) {
|
|
96
|
+
console.log(chalk_1.default.yellow(` You have ${totalModified} modified and ${totalStaged} staged files across all repositories.`));
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
console.log(chalk_1.default.green(' All repositories are clean.'));
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
//# sourceMappingURL=status.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status.js","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
const commander_1 = require("commander");
|
|
5
|
+
const init_1 = require("./commands/init");
|
|
6
|
+
const scaffold_orchestrator_1 = require("./commands/scaffold-orchestrator");
|
|
7
|
+
const feature_1 = require("./commands/feature");
|
|
8
|
+
const doctor_1 = require("./commands/doctor");
|
|
9
|
+
const status_1 = require("./commands/status");
|
|
10
|
+
const program = new commander_1.Command();
|
|
11
|
+
program
|
|
12
|
+
.name('context-cli')
|
|
13
|
+
.description('A CLI to manage the Context-First development methodology across any project')
|
|
14
|
+
.version('1.0.0');
|
|
15
|
+
// Setup commands
|
|
16
|
+
program
|
|
17
|
+
.command('init')
|
|
18
|
+
.description('Initialize Context-First in an existing project')
|
|
19
|
+
.action(init_1.initCommand);
|
|
20
|
+
program
|
|
21
|
+
.command('scaffold:orchestrator')
|
|
22
|
+
.description('Create a new orchestrator repository from a template')
|
|
23
|
+
.action(scaffold_orchestrator_1.scaffoldOrchestratorCommand);
|
|
24
|
+
// Feature management commands
|
|
25
|
+
const feature = program.command('feature').description('Manage feature workspaces');
|
|
26
|
+
feature
|
|
27
|
+
.command('start <issue-id>')
|
|
28
|
+
.description('Create a new feature workspace')
|
|
29
|
+
.option('-r, --repos <repos>', 'Comma-separated list of repositories to include')
|
|
30
|
+
.action(feature_1.featureCommands.start);
|
|
31
|
+
feature
|
|
32
|
+
.command('list')
|
|
33
|
+
.description('List all active feature workspaces')
|
|
34
|
+
.action(feature_1.featureCommands.list);
|
|
35
|
+
feature
|
|
36
|
+
.command('switch <issue-id>')
|
|
37
|
+
.description('Switch to an existing feature workspace')
|
|
38
|
+
.action(feature_1.featureCommands.switch);
|
|
39
|
+
feature
|
|
40
|
+
.command('end <issue-id>')
|
|
41
|
+
.description('Archive and clean up a completed feature workspace')
|
|
42
|
+
.option('-f, --force', 'Force cleanup without confirmation')
|
|
43
|
+
.action(feature_1.featureCommands.end);
|
|
44
|
+
// Diagnostic commands
|
|
45
|
+
program
|
|
46
|
+
.command('doctor')
|
|
47
|
+
.description('Check environment and configuration')
|
|
48
|
+
.action(doctor_1.doctorCommand);
|
|
49
|
+
program
|
|
50
|
+
.command('status')
|
|
51
|
+
.description('Show detailed status of the current workspace')
|
|
52
|
+
.action(status_1.statusCommand);
|
|
53
|
+
program.parse(process.argv);
|
|
54
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAEA,yCAAoC;AAEpC,0CAA8C;AAC9C,4EAA+E;AAC/E,gDAAqD;AACrD,8CAAkD;AAClD,8CAAkD;AAElD,MAAM,OAAO,GAAG,IAAI,mBAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,aAAa,CAAC;KACnB,WAAW,CAAC,8EAA8E,CAAC;KAC3F,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,iBAAiB;AACjB,OAAO;KACJ,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,iDAAiD,CAAC;KAC9D,MAAM,CAAC,kBAAW,CAAC,CAAC;AAEvB,OAAO;KACJ,OAAO,CAAC,uBAAuB,CAAC;KAChC,WAAW,CAAC,sDAAsD,CAAC;KACnE,MAAM,CAAC,mDAA2B,CAAC,CAAC;AAEvC,8BAA8B;AAC9B,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,WAAW,CAAC,2BAA2B,CAAC,CAAC;AAEpF,OAAO;KACJ,OAAO,CAAC,kBAAkB,CAAC;KAC3B,WAAW,CAAC,gCAAgC,CAAC;KAC7C,MAAM,CAAC,qBAAqB,EAAE,iDAAiD,CAAC;KAChF,MAAM,CAAC,yBAAe,CAAC,KAAK,CAAC,CAAC;AAEjC,OAAO;KACJ,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,oCAAoC,CAAC;KACjD,MAAM,CAAC,yBAAe,CAAC,IAAI,CAAC,CAAC;AAEhC,OAAO;KACJ,OAAO,CAAC,mBAAmB,CAAC;KAC5B,WAAW,CAAC,yCAAyC,CAAC;KACtD,MAAM,CAAC,yBAAe,CAAC,MAAM,CAAC,CAAC;AAElC,OAAO;KACJ,OAAO,CAAC,gBAAgB,CAAC;KACzB,WAAW,CAAC,oDAAoD,CAAC;KACjE,MAAM,CAAC,aAAa,EAAE,oCAAoC,CAAC;KAC3D,MAAM,CAAC,yBAAe,CAAC,GAAG,CAAC,CAAC;AAE/B,sBAAsB;AACtB,OAAO;KACJ,OAAO,CAAC,QAAQ,CAAC;KACjB,WAAW,CAAC,qCAAqC,CAAC;KAClD,MAAM,CAAC,sBAAa,CAAC,CAAC;AAEzB,OAAO;KACJ,OAAO,CAAC,QAAQ,CAAC;KACjB,WAAW,CAAC,+CAA+C,CAAC;KAC5D,MAAM,CAAC,sBAAa,CAAC,CAAC;AAEzB,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
export interface ContextConfig {
|
|
2
|
+
orchestratorRepo: string;
|
|
3
|
+
aiProvider: 'claude' | 'cursor' | 'custom';
|
|
4
|
+
commandsDir: string;
|
|
5
|
+
version: string;
|
|
6
|
+
createdAt: string;
|
|
7
|
+
}
|
|
8
|
+
export interface ContextManifest {
|
|
9
|
+
version: string;
|
|
10
|
+
project: string;
|
|
11
|
+
description: string;
|
|
12
|
+
repositories: Repository[];
|
|
13
|
+
}
|
|
14
|
+
export interface Repository {
|
|
15
|
+
id: string;
|
|
16
|
+
role: 'specs-provider' | 'application' | 'service';
|
|
17
|
+
url: string;
|
|
18
|
+
dependsOn?: string[];
|
|
19
|
+
description: string;
|
|
20
|
+
}
|
|
21
|
+
export interface WorkspaceMetadata {
|
|
22
|
+
issueId: string;
|
|
23
|
+
repositories: string[];
|
|
24
|
+
createdAt: string;
|
|
25
|
+
lastUpdated: string;
|
|
26
|
+
status: 'active' | 'archived';
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Load the .contextrc.json configuration file
|
|
30
|
+
*/
|
|
31
|
+
export declare function loadConfig(cwd?: string): Promise<ContextConfig | null>;
|
|
32
|
+
/**
|
|
33
|
+
* Find the nearest .contextrc.json by walking up the directory tree
|
|
34
|
+
*/
|
|
35
|
+
export declare function findConfig(startDir?: string): Promise<{
|
|
36
|
+
config: ContextConfig;
|
|
37
|
+
configDir: string;
|
|
38
|
+
} | null>;
|
|
39
|
+
/**
|
|
40
|
+
* Load the context-manifest.json from the orchestrator
|
|
41
|
+
*/
|
|
42
|
+
export declare function loadManifest(orchestratorPath: string): Promise<ContextManifest | null>;
|
|
43
|
+
/**
|
|
44
|
+
* Load workspace metadata
|
|
45
|
+
*/
|
|
46
|
+
export declare function loadWorkspaceMetadata(workspacePath: string): Promise<WorkspaceMetadata | null>;
|
|
47
|
+
/**
|
|
48
|
+
* Save workspace metadata
|
|
49
|
+
*/
|
|
50
|
+
export declare function saveWorkspaceMetadata(workspacePath: string, metadata: WorkspaceMetadata): Promise<void>;
|
|
51
|
+
/**
|
|
52
|
+
* Get the workspaces directory path
|
|
53
|
+
*/
|
|
54
|
+
export declare function getWorkspacesDir(): string;
|
|
55
|
+
/**
|
|
56
|
+
* Ensure a directory exists
|
|
57
|
+
*/
|
|
58
|
+
export declare function ensureDir(dirPath: string): Promise<void>;
|
|
59
|
+
/**
|
|
60
|
+
* Check if a path exists
|
|
61
|
+
*/
|
|
62
|
+
export declare function pathExists(filePath: string): Promise<boolean>;
|
|
63
|
+
/**
|
|
64
|
+
* Display error and exit
|
|
65
|
+
*/
|
|
66
|
+
export declare function exitWithError(message: string): never;
|
|
67
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/utils/config.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,aAAa;IAC5B,gBAAgB,EAAE,MAAM,CAAC;IACzB,UAAU,EAAE,QAAQ,GAAG,QAAQ,GAAG,QAAQ,CAAC;IAC3C,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,UAAU,EAAE,CAAC;CAC5B;AAED,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,gBAAgB,GAAG,aAAa,GAAG,SAAS,CAAC;IACnD,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,QAAQ,GAAG,UAAU,CAAC;CAC/B;AAED;;GAEG;AACH,wBAAsB,UAAU,CAAC,GAAG,GAAE,MAAsB,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CAQ3F;AAED;;GAEG;AACH,wBAAsB,UAAU,CAAC,QAAQ,GAAE,MAAsB,GAAG,OAAO,CAAC;IAAE,MAAM,EAAE,aAAa,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAAC,CAgB/H;AAED;;GAEG;AACH,wBAAsB,YAAY,CAAC,gBAAgB,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CAQ5F;AAED;;GAEG;AACH,wBAAsB,qBAAqB,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC,CAQpG;AAED;;GAEG;AACH,wBAAsB,qBAAqB,CAAC,aAAa,EAAE,MAAM,EAAE,QAAQ,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAG7G;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,MAAM,CAEzC;AAED;;GAEG;AACH,wBAAsB,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAM9D;AAED;;GAEG;AACH,wBAAsB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAOnE;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,KAAK,CAGpD"}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.loadConfig = loadConfig;
|
|
7
|
+
exports.findConfig = findConfig;
|
|
8
|
+
exports.loadManifest = loadManifest;
|
|
9
|
+
exports.loadWorkspaceMetadata = loadWorkspaceMetadata;
|
|
10
|
+
exports.saveWorkspaceMetadata = saveWorkspaceMetadata;
|
|
11
|
+
exports.getWorkspacesDir = getWorkspacesDir;
|
|
12
|
+
exports.ensureDir = ensureDir;
|
|
13
|
+
exports.pathExists = pathExists;
|
|
14
|
+
exports.exitWithError = exitWithError;
|
|
15
|
+
const promises_1 = __importDefault(require("fs/promises"));
|
|
16
|
+
const path_1 = __importDefault(require("path"));
|
|
17
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
18
|
+
/**
|
|
19
|
+
* Load the .contextrc.json configuration file
|
|
20
|
+
*/
|
|
21
|
+
async function loadConfig(cwd = process.cwd()) {
|
|
22
|
+
try {
|
|
23
|
+
const configPath = path_1.default.join(cwd, '.contextrc.json');
|
|
24
|
+
const content = await promises_1.default.readFile(configPath, 'utf-8');
|
|
25
|
+
return JSON.parse(content);
|
|
26
|
+
}
|
|
27
|
+
catch (error) {
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Find the nearest .contextrc.json by walking up the directory tree
|
|
33
|
+
*/
|
|
34
|
+
async function findConfig(startDir = process.cwd()) {
|
|
35
|
+
let currentDir = startDir;
|
|
36
|
+
while (true) {
|
|
37
|
+
const config = await loadConfig(currentDir);
|
|
38
|
+
if (config) {
|
|
39
|
+
return { config, configDir: currentDir };
|
|
40
|
+
}
|
|
41
|
+
const parentDir = path_1.default.dirname(currentDir);
|
|
42
|
+
if (parentDir === currentDir) {
|
|
43
|
+
// Reached root
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
currentDir = parentDir;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Load the context-manifest.json from the orchestrator
|
|
51
|
+
*/
|
|
52
|
+
async function loadManifest(orchestratorPath) {
|
|
53
|
+
try {
|
|
54
|
+
const manifestPath = path_1.default.join(orchestratorPath, 'context-manifest.json');
|
|
55
|
+
const content = await promises_1.default.readFile(manifestPath, 'utf-8');
|
|
56
|
+
return JSON.parse(content);
|
|
57
|
+
}
|
|
58
|
+
catch (error) {
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Load workspace metadata
|
|
64
|
+
*/
|
|
65
|
+
async function loadWorkspaceMetadata(workspacePath) {
|
|
66
|
+
try {
|
|
67
|
+
const metadataPath = path_1.default.join(workspacePath, '.workspace.json');
|
|
68
|
+
const content = await promises_1.default.readFile(metadataPath, 'utf-8');
|
|
69
|
+
return JSON.parse(content);
|
|
70
|
+
}
|
|
71
|
+
catch (error) {
|
|
72
|
+
return null;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Save workspace metadata
|
|
77
|
+
*/
|
|
78
|
+
async function saveWorkspaceMetadata(workspacePath, metadata) {
|
|
79
|
+
const metadataPath = path_1.default.join(workspacePath, '.workspace.json');
|
|
80
|
+
await promises_1.default.writeFile(metadataPath, JSON.stringify(metadata, null, 2), 'utf-8');
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Get the workspaces directory path
|
|
84
|
+
*/
|
|
85
|
+
function getWorkspacesDir() {
|
|
86
|
+
return path_1.default.join(process.env.HOME || process.env.USERPROFILE || '/tmp', '.context-workspaces');
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Ensure a directory exists
|
|
90
|
+
*/
|
|
91
|
+
async function ensureDir(dirPath) {
|
|
92
|
+
try {
|
|
93
|
+
await promises_1.default.mkdir(dirPath, { recursive: true });
|
|
94
|
+
}
|
|
95
|
+
catch (error) {
|
|
96
|
+
// Ignore if already exists
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Check if a path exists
|
|
101
|
+
*/
|
|
102
|
+
async function pathExists(filePath) {
|
|
103
|
+
try {
|
|
104
|
+
await promises_1.default.access(filePath);
|
|
105
|
+
return true;
|
|
106
|
+
}
|
|
107
|
+
catch {
|
|
108
|
+
return false;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Display error and exit
|
|
113
|
+
*/
|
|
114
|
+
function exitWithError(message) {
|
|
115
|
+
console.error(chalk_1.default.red(`\nā ${message}\n`));
|
|
116
|
+
process.exit(1);
|
|
117
|
+
}
|
|
118
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/utils/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Clone a repository if it doesn't exist
|
|
3
|
+
*/
|
|
4
|
+
export declare function ensureRepoCloned(repoUrl: string, targetPath: string): Promise<void>;
|
|
5
|
+
/**
|
|
6
|
+
* Create a git worktree
|
|
7
|
+
*/
|
|
8
|
+
export declare function createWorktree(mainRepoPath: string, worktreePath: string, branchName: string): Promise<void>;
|
|
9
|
+
/**
|
|
10
|
+
* Remove a git worktree
|
|
11
|
+
*/
|
|
12
|
+
export declare function removeWorktree(mainRepoPath: string, worktreePath: string): Promise<void>;
|
|
13
|
+
/**
|
|
14
|
+
* List all worktrees for a repository
|
|
15
|
+
*/
|
|
16
|
+
export declare function listWorktrees(mainRepoPath: string): Promise<string[]>;
|
|
17
|
+
/**
|
|
18
|
+
* Get the current branch name
|
|
19
|
+
*/
|
|
20
|
+
export declare function getCurrentBranch(repoPath: string): Promise<string | null>;
|
|
21
|
+
/**
|
|
22
|
+
* Get repository status
|
|
23
|
+
*/
|
|
24
|
+
export declare function getRepoStatus(repoPath: string): Promise<{
|
|
25
|
+
branch: string | null;
|
|
26
|
+
modified: number;
|
|
27
|
+
staged: number;
|
|
28
|
+
ahead: number;
|
|
29
|
+
behind: number;
|
|
30
|
+
}>;
|
|
31
|
+
/**
|
|
32
|
+
* Check if a path is a git repository
|
|
33
|
+
*/
|
|
34
|
+
export declare function isGitRepo(repoPath: string): Promise<boolean>;
|
|
35
|
+
//# sourceMappingURL=git.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"git.d.ts","sourceRoot":"","sources":["../../src/utils/git.ts"],"names":[],"mappings":"AAKA;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAazF;AAED;;GAEG;AACH,wBAAsB,cAAc,CAClC,YAAY,EAAE,MAAM,EACpB,YAAY,EAAE,MAAM,EACpB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,IAAI,CAAC,CA2Bf;AAED;;GAEG;AACH,wBAAsB,cAAc,CAAC,YAAY,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAU9F;AAED;;GAEG;AACH,wBAAsB,aAAa,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAoB3E;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAQ/E;AAED;;GAEG;AACH,wBAAsB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC;IAC7D,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC,CAqBD;AAED;;GAEG;AACH,wBAAsB,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAQlE"}
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.ensureRepoCloned = ensureRepoCloned;
|
|
7
|
+
exports.createWorktree = createWorktree;
|
|
8
|
+
exports.removeWorktree = removeWorktree;
|
|
9
|
+
exports.listWorktrees = listWorktrees;
|
|
10
|
+
exports.getCurrentBranch = getCurrentBranch;
|
|
11
|
+
exports.getRepoStatus = getRepoStatus;
|
|
12
|
+
exports.isGitRepo = isGitRepo;
|
|
13
|
+
const simple_git_1 = __importDefault(require("simple-git"));
|
|
14
|
+
const child_process_1 = require("child_process");
|
|
15
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
16
|
+
/**
|
|
17
|
+
* Clone a repository if it doesn't exist
|
|
18
|
+
*/
|
|
19
|
+
async function ensureRepoCloned(repoUrl, targetPath) {
|
|
20
|
+
const git = (0, simple_git_1.default)();
|
|
21
|
+
try {
|
|
22
|
+
await git.clone(repoUrl, targetPath);
|
|
23
|
+
console.log(chalk_1.default.green(`ā Cloned ${repoUrl}`));
|
|
24
|
+
}
|
|
25
|
+
catch (error) {
|
|
26
|
+
if (error.message.includes('already exists')) {
|
|
27
|
+
console.log(chalk_1.default.gray(` Repository already exists at ${targetPath}`));
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
throw error;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Create a git worktree
|
|
36
|
+
*/
|
|
37
|
+
async function createWorktree(mainRepoPath, worktreePath, branchName) {
|
|
38
|
+
const git = (0, simple_git_1.default)(mainRepoPath);
|
|
39
|
+
// Check if branch exists remotely or locally
|
|
40
|
+
const branches = await git.branch();
|
|
41
|
+
const branchExists = branches.all.includes(branchName) || branches.all.includes(`remotes/origin/${branchName}`);
|
|
42
|
+
if (!branchExists) {
|
|
43
|
+
// Create new branch from current HEAD
|
|
44
|
+
await git.checkoutLocalBranch(branchName);
|
|
45
|
+
console.log(chalk_1.default.gray(` Created new branch: ${branchName}`));
|
|
46
|
+
}
|
|
47
|
+
// Create worktree
|
|
48
|
+
try {
|
|
49
|
+
(0, child_process_1.execSync)(`git worktree add "${worktreePath}" "${branchName}"`, {
|
|
50
|
+
cwd: mainRepoPath,
|
|
51
|
+
stdio: 'pipe',
|
|
52
|
+
});
|
|
53
|
+
console.log(chalk_1.default.green(`ā Created worktree at ${worktreePath}`));
|
|
54
|
+
}
|
|
55
|
+
catch (error) {
|
|
56
|
+
if (error.message.includes('already exists')) {
|
|
57
|
+
console.log(chalk_1.default.yellow(` Worktree already exists at ${worktreePath}`));
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
throw error;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Remove a git worktree
|
|
66
|
+
*/
|
|
67
|
+
async function removeWorktree(mainRepoPath, worktreePath) {
|
|
68
|
+
try {
|
|
69
|
+
(0, child_process_1.execSync)(`git worktree remove "${worktreePath}" --force`, {
|
|
70
|
+
cwd: mainRepoPath,
|
|
71
|
+
stdio: 'pipe',
|
|
72
|
+
});
|
|
73
|
+
console.log(chalk_1.default.green(`ā Removed worktree at ${worktreePath}`));
|
|
74
|
+
}
|
|
75
|
+
catch (error) {
|
|
76
|
+
console.log(chalk_1.default.yellow(` Could not remove worktree: ${error.message}`));
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* List all worktrees for a repository
|
|
81
|
+
*/
|
|
82
|
+
async function listWorktrees(mainRepoPath) {
|
|
83
|
+
try {
|
|
84
|
+
const output = (0, child_process_1.execSync)('git worktree list --porcelain', {
|
|
85
|
+
cwd: mainRepoPath,
|
|
86
|
+
encoding: 'utf-8',
|
|
87
|
+
});
|
|
88
|
+
const worktrees = [];
|
|
89
|
+
const lines = output.split('\n');
|
|
90
|
+
for (const line of lines) {
|
|
91
|
+
if (line.startsWith('worktree ')) {
|
|
92
|
+
worktrees.push(line.substring(9));
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
return worktrees;
|
|
96
|
+
}
|
|
97
|
+
catch (error) {
|
|
98
|
+
return [];
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Get the current branch name
|
|
103
|
+
*/
|
|
104
|
+
async function getCurrentBranch(repoPath) {
|
|
105
|
+
try {
|
|
106
|
+
const git = (0, simple_git_1.default)(repoPath);
|
|
107
|
+
const status = await git.status();
|
|
108
|
+
return status.current || null;
|
|
109
|
+
}
|
|
110
|
+
catch (error) {
|
|
111
|
+
return null;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Get repository status
|
|
116
|
+
*/
|
|
117
|
+
async function getRepoStatus(repoPath) {
|
|
118
|
+
try {
|
|
119
|
+
const git = (0, simple_git_1.default)(repoPath);
|
|
120
|
+
const status = await git.status();
|
|
121
|
+
return {
|
|
122
|
+
branch: status.current || null,
|
|
123
|
+
modified: status.modified.length + status.created.length + status.deleted.length,
|
|
124
|
+
staged: status.staged.length,
|
|
125
|
+
ahead: status.ahead,
|
|
126
|
+
behind: status.behind,
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
catch (error) {
|
|
130
|
+
return {
|
|
131
|
+
branch: null,
|
|
132
|
+
modified: 0,
|
|
133
|
+
staged: 0,
|
|
134
|
+
ahead: 0,
|
|
135
|
+
behind: 0,
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Check if a path is a git repository
|
|
141
|
+
*/
|
|
142
|
+
async function isGitRepo(repoPath) {
|
|
143
|
+
try {
|
|
144
|
+
const git = (0, simple_git_1.default)(repoPath);
|
|
145
|
+
await git.status();
|
|
146
|
+
return true;
|
|
147
|
+
}
|
|
148
|
+
catch (error) {
|
|
149
|
+
return false;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
//# sourceMappingURL=git.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"git.js","sourceRoot":"","sources":["../../src/utils/git.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "context-first-cli",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "A generic CLI to manage the Context-First development methodology across any project.",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"bin": {
|
|
8
|
+
"context-cli": "./dist/index.js"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"dist",
|
|
12
|
+
"README.md",
|
|
13
|
+
"LICENSE"
|
|
14
|
+
],
|
|
15
|
+
"scripts": {
|
|
16
|
+
"build": "tsc",
|
|
17
|
+
"dev": "tsx src/index.ts",
|
|
18
|
+
"start": "node dist/index.js",
|
|
19
|
+
"prepublishOnly": "npm run build",
|
|
20
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
21
|
+
},
|
|
22
|
+
"repository": {
|
|
23
|
+
"type": "git",
|
|
24
|
+
"url": "git+https://github.com/thatix-io/context-first-cli.git"
|
|
25
|
+
},
|
|
26
|
+
"keywords": [
|
|
27
|
+
"context-first",
|
|
28
|
+
"cli",
|
|
29
|
+
"development",
|
|
30
|
+
"methodology",
|
|
31
|
+
"orchestrator",
|
|
32
|
+
"worktree",
|
|
33
|
+
"git",
|
|
34
|
+
"workflow",
|
|
35
|
+
"automation",
|
|
36
|
+
"ai-assisted"
|
|
37
|
+
],
|
|
38
|
+
"author": "Thiago Abreu <thiagoabreu.dev>",
|
|
39
|
+
"license": "MIT",
|
|
40
|
+
"bugs": {
|
|
41
|
+
"url": "https://github.com/thatix-io/context-first-cli/issues"
|
|
42
|
+
},
|
|
43
|
+
"homepage": "https://github.com/thatix-io/context-first-cli#readme",
|
|
44
|
+
"engines": {
|
|
45
|
+
"node": ">=18.0.0"
|
|
46
|
+
},
|
|
47
|
+
"dependencies": {
|
|
48
|
+
"chalk": "^5.6.2",
|
|
49
|
+
"commander": "^14.0.2",
|
|
50
|
+
"inquirer": "^13.2.0",
|
|
51
|
+
"simple-git": "^3.30.0"
|
|
52
|
+
},
|
|
53
|
+
"devDependencies": {
|
|
54
|
+
"@types/inquirer": "^9.0.9",
|
|
55
|
+
"@types/node": "^25.0.9",
|
|
56
|
+
"tsx": "^4.21.0",
|
|
57
|
+
"typescript": "^5.9.3"
|
|
58
|
+
}
|
|
59
|
+
}
|