feat: add workflow management commands and utilities

- Implemented workflow installation, listing, and syncing commands in `workflow.ts`.
- Created utility functions for project root detection and package version retrieval in `project-root.ts`.
- Added update checker functionality to notify users of new package versions in `update-checker.ts`.
- Developed unit tests for project root utilities and update checker to ensure functionality and version comparison accuracy.
This commit is contained in:
catlog22
2026-01-21 12:35:33 +08:00
parent ffe9898fd3
commit 9d6bc92837
13 changed files with 1832 additions and 5 deletions

View File

@@ -0,0 +1,73 @@
import { existsSync, readFileSync } from 'fs';
import { dirname, join } from 'path';
import { fileURLToPath } from 'url';
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
interface PackageInfo {
name: string;
version: string;
[key: string]: unknown;
}
/**
* Find project root by searching upward for package.json
* More robust than hardcoded relative paths
*/
export function findProjectRoot(startDir: string = __dirname): string | null {
let currentDir = startDir;
let previousDir = '';
// Traverse up until we find package.json or reach filesystem root
while (currentDir !== previousDir) {
const pkgPath = join(currentDir, 'package.json');
if (existsSync(pkgPath)) {
try {
const pkg = JSON.parse(readFileSync(pkgPath, 'utf8'));
// Verify this is our package (not a nested node_modules package)
if (pkg.name === 'claude-code-workflow' || pkg.bin?.ccw) {
return currentDir;
}
} catch {
// Invalid JSON, continue searching
}
}
previousDir = currentDir;
currentDir = dirname(currentDir);
}
return null;
}
/**
* Load package.json from project root
* Returns null if not found or invalid
*/
export function loadPackageInfo(): PackageInfo | null {
const projectRoot = findProjectRoot();
if (!projectRoot) return null;
const pkgPath = join(projectRoot, 'package.json');
try {
const content = readFileSync(pkgPath, 'utf8');
return JSON.parse(content) as PackageInfo;
} catch {
return null;
}
}
/**
* Get package version from project root
*/
export function getPackageVersion(): string {
const pkg = loadPackageInfo();
return pkg?.version || '1.0.0';
}
/**
* Get package root directory
*/
export function getPackageRoot(): string {
return findProjectRoot() || join(__dirname, '..', '..', '..');
}