@compilr-dev/cli 0.4.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/README.md +110 -0
- package/dist/agent.d.ts +62 -0
- package/dist/agent.js +317 -0
- package/dist/agents/registry.d.ts +66 -0
- package/dist/agents/registry.js +238 -0
- package/dist/agents/types.d.ts +40 -0
- package/dist/agents/types.js +94 -0
- package/dist/commands/custom-registry.d.ts +69 -0
- package/dist/commands/custom-registry.js +246 -0
- package/dist/commands/index.d.ts +7 -0
- package/dist/commands/index.js +7 -0
- package/dist/commands/types.d.ts +31 -0
- package/dist/commands/types.js +26 -0
- package/dist/commands.d.ts +63 -0
- package/dist/commands.js +324 -0
- package/dist/db/index.d.ts +42 -0
- package/dist/db/index.js +146 -0
- package/dist/db/repositories/document-repository.d.ts +63 -0
- package/dist/db/repositories/document-repository.js +184 -0
- package/dist/db/repositories/index.d.ts +9 -0
- package/dist/db/repositories/index.js +6 -0
- package/dist/db/repositories/project-repository.d.ts +132 -0
- package/dist/db/repositories/project-repository.js +337 -0
- package/dist/db/repositories/work-item-repository.d.ts +115 -0
- package/dist/db/repositories/work-item-repository.js +389 -0
- package/dist/db/schema.d.ts +83 -0
- package/dist/db/schema.js +143 -0
- package/dist/debug.d.ts +8 -0
- package/dist/debug.js +48 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +348 -0
- package/dist/index.old.d.ts +7 -0
- package/dist/index.old.js +1014 -0
- package/dist/repl.d.ts +121 -0
- package/dist/repl.js +1878 -0
- package/dist/settings/index.d.ts +80 -0
- package/dist/settings/index.js +195 -0
- package/dist/shared-handlers.d.ts +63 -0
- package/dist/shared-handlers.js +57 -0
- package/dist/slash-autocomplete.d.ts +41 -0
- package/dist/slash-autocomplete.js +638 -0
- package/dist/state.d.ts +75 -0
- package/dist/state.js +130 -0
- package/dist/tabbed-menu.d.ts +11 -0
- package/dist/tabbed-menu.js +328 -0
- package/dist/templates/backlog-md.d.ts +7 -0
- package/dist/templates/backlog-md.js +94 -0
- package/dist/templates/claude-md.d.ts +7 -0
- package/dist/templates/claude-md.js +189 -0
- package/dist/templates/coding-standards.d.ts +7 -0
- package/dist/templates/coding-standards.js +299 -0
- package/dist/templates/compilr-md.d.ts +7 -0
- package/dist/templates/compilr-md.js +189 -0
- package/dist/templates/config-json.d.ts +38 -0
- package/dist/templates/config-json.js +39 -0
- package/dist/templates/gitignore.d.ts +7 -0
- package/dist/templates/gitignore.js +85 -0
- package/dist/templates/index.d.ts +19 -0
- package/dist/templates/index.js +302 -0
- package/dist/templates/package-json.d.ts +7 -0
- package/dist/templates/package-json.js +111 -0
- package/dist/templates/readme-md.d.ts +7 -0
- package/dist/templates/readme-md.js +161 -0
- package/dist/templates/tsconfig.d.ts +7 -0
- package/dist/templates/tsconfig.js +61 -0
- package/dist/templates/types.d.ts +33 -0
- package/dist/templates/types.js +24 -0
- package/dist/test-autocomplete.d.ts +7 -0
- package/dist/test-autocomplete.js +85 -0
- package/dist/test-tabbed-menu.d.ts +7 -0
- package/dist/test-tabbed-menu.js +25 -0
- package/dist/themes/colors.d.ts +49 -0
- package/dist/themes/colors.js +135 -0
- package/dist/themes/index.d.ts +23 -0
- package/dist/themes/index.js +24 -0
- package/dist/themes/registry.d.ts +60 -0
- package/dist/themes/registry.js +195 -0
- package/dist/themes/types.d.ts +82 -0
- package/dist/themes/types.js +7 -0
- package/dist/tool-selector.d.ts +71 -0
- package/dist/tool-selector.js +184 -0
- package/dist/tools/ask-user-simple.d.ts +19 -0
- package/dist/tools/ask-user-simple.js +86 -0
- package/dist/tools/ask-user.d.ts +32 -0
- package/dist/tools/ask-user.js +113 -0
- package/dist/tools/backlog.d.ts +53 -0
- package/dist/tools/backlog.js +709 -0
- package/dist/tools.d.ts +15 -0
- package/dist/tools.js +121 -0
- package/dist/ui/agents-overlay.d.ts +12 -0
- package/dist/ui/agents-overlay.js +501 -0
- package/dist/ui/arch-type-overlay.d.ts +20 -0
- package/dist/ui/arch-type-overlay.js +229 -0
- package/dist/ui/ask-user-overlay.d.ts +26 -0
- package/dist/ui/ask-user-overlay.js +647 -0
- package/dist/ui/ask-user-simple-overlay.d.ts +25 -0
- package/dist/ui/ask-user-simple-overlay.js +242 -0
- package/dist/ui/backlog-overlay.d.ts +17 -0
- package/dist/ui/backlog-overlay.js +786 -0
- package/dist/ui/commands-overlay.d.ts +11 -0
- package/dist/ui/commands-overlay.js +410 -0
- package/dist/ui/config-overlay.d.ts +34 -0
- package/dist/ui/config-overlay.js +977 -0
- package/dist/ui/conversation.d.ts +82 -0
- package/dist/ui/conversation.js +508 -0
- package/dist/ui/diff.d.ts +38 -0
- package/dist/ui/diff.js +182 -0
- package/dist/ui/ephemeral.d.ts +111 -0
- package/dist/ui/ephemeral.js +413 -0
- package/dist/ui/file-autocomplete.d.ts +45 -0
- package/dist/ui/file-autocomplete.js +237 -0
- package/dist/ui/footer.d.ts +153 -0
- package/dist/ui/footer.js +422 -0
- package/dist/ui/index.d.ts +12 -0
- package/dist/ui/index.js +15 -0
- package/dist/ui/init-overlay.d.ts +24 -0
- package/dist/ui/init-overlay.js +525 -0
- package/dist/ui/input-prompt-v2.d.ts +179 -0
- package/dist/ui/input-prompt-v2.js +991 -0
- package/dist/ui/input-prompt.d.ts +97 -0
- package/dist/ui/input-prompt.js +800 -0
- package/dist/ui/iteration-limit-overlay.d.ts +21 -0
- package/dist/ui/iteration-limit-overlay.js +150 -0
- package/dist/ui/keys-overlay.d.ts +14 -0
- package/dist/ui/keys-overlay.js +181 -0
- package/dist/ui/model-warning-overlay.d.ts +30 -0
- package/dist/ui/model-warning-overlay.js +171 -0
- package/dist/ui/overlay-controller.d.ts +25 -0
- package/dist/ui/overlay-controller.js +35 -0
- package/dist/ui/overlays.d.ts +47 -0
- package/dist/ui/overlays.js +627 -0
- package/dist/ui/permission-overlay.d.ts +16 -0
- package/dist/ui/permission-overlay.js +494 -0
- package/dist/ui/terminal.d.ts +117 -0
- package/dist/ui/terminal.js +237 -0
- package/dist/ui/todo-zone.d.ts +112 -0
- package/dist/ui/todo-zone.js +353 -0
- package/dist/ui/tools-overlay.d.ts +26 -0
- package/dist/ui/tools-overlay.js +278 -0
- package/dist/ui/tutorial-overlay.d.ts +10 -0
- package/dist/ui/tutorial-overlay.js +936 -0
- package/dist/ui/types.d.ts +103 -0
- package/dist/ui/types.js +33 -0
- package/dist/utils/credentials.d.ts +55 -0
- package/dist/utils/credentials.js +268 -0
- package/dist/utils/model-tiers.d.ts +37 -0
- package/dist/utils/model-tiers.js +118 -0
- package/dist/utils/project-memory.d.ts +47 -0
- package/dist/utils/project-memory.js +117 -0
- package/dist/utils/project-status.d.ts +56 -0
- package/dist/utils/project-status.js +237 -0
- package/package.json +66 -0
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Project Memory Loader
|
|
3
|
+
*
|
|
4
|
+
* Loads project-level instructions from COMPILR.md or CLAUDE.md files.
|
|
5
|
+
* Provides size guards and warnings for large files.
|
|
6
|
+
*/
|
|
7
|
+
import * as fs from 'fs';
|
|
8
|
+
import * as path from 'path';
|
|
9
|
+
// =============================================================================
|
|
10
|
+
// Constants
|
|
11
|
+
// =============================================================================
|
|
12
|
+
/** Files to search for, in priority order */
|
|
13
|
+
const MEMORY_FILES = [
|
|
14
|
+
'COMPILR.md',
|
|
15
|
+
'.compilr/instructions.md',
|
|
16
|
+
'CLAUDE.md',
|
|
17
|
+
'.claude/instructions.md',
|
|
18
|
+
];
|
|
19
|
+
/** Default max size: 100KB */
|
|
20
|
+
const DEFAULT_MAX_SIZE = 100 * 1024;
|
|
21
|
+
/** Default warn size: 30KB */
|
|
22
|
+
const DEFAULT_WARN_SIZE = 30 * 1024;
|
|
23
|
+
// =============================================================================
|
|
24
|
+
// Main Function
|
|
25
|
+
// =============================================================================
|
|
26
|
+
/**
|
|
27
|
+
* Load project memory from COMPILR.md or CLAUDE.md
|
|
28
|
+
*
|
|
29
|
+
* @param options - Configuration options
|
|
30
|
+
* @returns Result with content and metadata
|
|
31
|
+
*/
|
|
32
|
+
export function loadProjectMemory(options = {}) {
|
|
33
|
+
const cwd = options.cwd ?? process.cwd();
|
|
34
|
+
const maxSize = options.maxSize ?? DEFAULT_MAX_SIZE;
|
|
35
|
+
// Search for memory file
|
|
36
|
+
for (const filename of MEMORY_FILES) {
|
|
37
|
+
const filePath = path.join(cwd, filename);
|
|
38
|
+
if (fs.existsSync(filePath)) {
|
|
39
|
+
try {
|
|
40
|
+
const stat = fs.statSync(filePath);
|
|
41
|
+
const originalSize = stat.size;
|
|
42
|
+
// Read file content
|
|
43
|
+
let content = fs.readFileSync(filePath, 'utf-8');
|
|
44
|
+
let truncated = false;
|
|
45
|
+
// Truncate if too large
|
|
46
|
+
if (content.length > maxSize) {
|
|
47
|
+
content = content.slice(0, maxSize);
|
|
48
|
+
// Try to truncate at a line boundary
|
|
49
|
+
const lastNewline = content.lastIndexOf('\n');
|
|
50
|
+
if (lastNewline > maxSize * 0.8) {
|
|
51
|
+
content = content.slice(0, lastNewline);
|
|
52
|
+
}
|
|
53
|
+
content += '\n\n[... truncated due to size ...]';
|
|
54
|
+
truncated = true;
|
|
55
|
+
}
|
|
56
|
+
return {
|
|
57
|
+
found: true,
|
|
58
|
+
content,
|
|
59
|
+
filePath,
|
|
60
|
+
originalSize,
|
|
61
|
+
truncated,
|
|
62
|
+
estimatedTokens: Math.ceil(content.length / 4),
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
catch {
|
|
66
|
+
// File exists but couldn't be read, continue to next
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
// No memory file found
|
|
72
|
+
return {
|
|
73
|
+
found: false,
|
|
74
|
+
content: '',
|
|
75
|
+
filePath: null,
|
|
76
|
+
originalSize: 0,
|
|
77
|
+
truncated: false,
|
|
78
|
+
estimatedTokens: 0,
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Check if a project memory file exists without loading it
|
|
83
|
+
*/
|
|
84
|
+
export function hasProjectMemory(cwd) {
|
|
85
|
+
const dir = cwd ?? process.cwd();
|
|
86
|
+
for (const filename of MEMORY_FILES) {
|
|
87
|
+
const filePath = path.join(dir, filename);
|
|
88
|
+
if (fs.existsSync(filePath)) {
|
|
89
|
+
return true;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
return false;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Get the size category for display purposes
|
|
96
|
+
*/
|
|
97
|
+
export function getSizeCategory(bytes) {
|
|
98
|
+
if (bytes < DEFAULT_WARN_SIZE) {
|
|
99
|
+
return 'small';
|
|
100
|
+
}
|
|
101
|
+
else if (bytes < DEFAULT_MAX_SIZE) {
|
|
102
|
+
return 'medium';
|
|
103
|
+
}
|
|
104
|
+
return 'large';
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Format bytes as human-readable string
|
|
108
|
+
*/
|
|
109
|
+
export function formatBytes(bytes) {
|
|
110
|
+
if (bytes < 1024) {
|
|
111
|
+
return `${String(bytes)} B`;
|
|
112
|
+
}
|
|
113
|
+
else if (bytes < 1024 * 1024) {
|
|
114
|
+
return `${(bytes / 1024).toFixed(1)} KB`;
|
|
115
|
+
}
|
|
116
|
+
return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
|
|
117
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Project Status Detection
|
|
3
|
+
* Detects project state for startup message guidance
|
|
4
|
+
*/
|
|
5
|
+
import type { CompilrConfig } from '../templates/config-json.js';
|
|
6
|
+
export type { CompilrConfig } from '../templates/config-json.js';
|
|
7
|
+
export interface ProjectStatus {
|
|
8
|
+
/** .compilr/ folder exists */
|
|
9
|
+
initialized: boolean;
|
|
10
|
+
/** COMPILR.md or CLAUDE.md exists */
|
|
11
|
+
hasMemory: boolean;
|
|
12
|
+
/** backlog.md exists in .compilr/ or root */
|
|
13
|
+
hasBacklog: boolean;
|
|
14
|
+
/** Backlog statistics (if backlog exists) */
|
|
15
|
+
backlogStats: {
|
|
16
|
+
total: number;
|
|
17
|
+
completed: number;
|
|
18
|
+
inProgress: number;
|
|
19
|
+
pending: number;
|
|
20
|
+
} | null;
|
|
21
|
+
/** PRD.md exists */
|
|
22
|
+
hasPRD: boolean;
|
|
23
|
+
/** architecture/ folder exists */
|
|
24
|
+
hasArchDocs: boolean;
|
|
25
|
+
/** Existing project markers (package.json, .git, Cargo.toml, etc.) */
|
|
26
|
+
isExistingProject: boolean;
|
|
27
|
+
/** Project type if detected */
|
|
28
|
+
projectType: string | null;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Detect project status for the current working directory
|
|
32
|
+
*/
|
|
33
|
+
export declare function detectProjectStatus(cwd?: string): ProjectStatus;
|
|
34
|
+
/**
|
|
35
|
+
* Find and load the .compilr/config.json file
|
|
36
|
+
* Searches in cwd, parent dirs, and sibling -docs folders
|
|
37
|
+
*/
|
|
38
|
+
export declare function loadCompilrConfig(cwd?: string): CompilrConfig | null;
|
|
39
|
+
/**
|
|
40
|
+
* Find the path to .compilr/config.json
|
|
41
|
+
* Returns null if not found
|
|
42
|
+
*/
|
|
43
|
+
export declare function findConfigPath(cwd?: string): string | null;
|
|
44
|
+
/**
|
|
45
|
+
* Get the project path from config, falling back to cwd
|
|
46
|
+
*/
|
|
47
|
+
export declare function getProjectPath(cwd?: string): string;
|
|
48
|
+
/**
|
|
49
|
+
* Get the docs path from config (for two-repo pattern)
|
|
50
|
+
*/
|
|
51
|
+
export declare function getDocsPath(cwd?: string): string | null;
|
|
52
|
+
/**
|
|
53
|
+
* Get workflow stage based on project status
|
|
54
|
+
*/
|
|
55
|
+
export type WorkflowStage = 'new' | 'initialized' | 'designing' | 'building' | 'maintaining';
|
|
56
|
+
export declare function getWorkflowStage(status: ProjectStatus): WorkflowStage;
|
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Project Status Detection
|
|
3
|
+
* Detects project state for startup message guidance
|
|
4
|
+
*/
|
|
5
|
+
import { existsSync, readFileSync, readdirSync, statSync } from 'node:fs';
|
|
6
|
+
import { join } from 'node:path';
|
|
7
|
+
/**
|
|
8
|
+
* Detect project status for the current working directory
|
|
9
|
+
*/
|
|
10
|
+
export function detectProjectStatus(cwd = process.cwd()) {
|
|
11
|
+
const status = {
|
|
12
|
+
initialized: false,
|
|
13
|
+
hasMemory: false,
|
|
14
|
+
hasBacklog: false,
|
|
15
|
+
backlogStats: null,
|
|
16
|
+
hasPRD: false,
|
|
17
|
+
hasArchDocs: false,
|
|
18
|
+
isExistingProject: false,
|
|
19
|
+
projectType: null,
|
|
20
|
+
};
|
|
21
|
+
// Check .compilr/ folder (future) or .claude/ (current)
|
|
22
|
+
status.initialized = existsSync(join(cwd, '.compilr')) || existsSync(join(cwd, '.claude'));
|
|
23
|
+
// Check for memory file (COMPILR.md, CLAUDE.md, or similar)
|
|
24
|
+
const memoryFiles = ['COMPILR.md', 'CLAUDE.md', 'GEMINI.md', 'COPILOT.md'];
|
|
25
|
+
status.hasMemory = memoryFiles.some(f => existsSync(join(cwd, f)));
|
|
26
|
+
// Check for backlog
|
|
27
|
+
const backlogPaths = [
|
|
28
|
+
join(cwd, '.compilr', 'backlog.md'),
|
|
29
|
+
join(cwd, '.claude', 'backlog.md'),
|
|
30
|
+
join(cwd, 'backlog.md'),
|
|
31
|
+
];
|
|
32
|
+
const backlogPath = backlogPaths.find(p => existsSync(p));
|
|
33
|
+
status.hasBacklog = !!backlogPath;
|
|
34
|
+
// Parse backlog stats if it exists
|
|
35
|
+
if (backlogPath) {
|
|
36
|
+
status.backlogStats = parseBacklogStats(backlogPath);
|
|
37
|
+
}
|
|
38
|
+
// Check for PRD
|
|
39
|
+
const prdPaths = [
|
|
40
|
+
join(cwd, '.compilr', 'PRD.md'),
|
|
41
|
+
join(cwd, '.claude', 'PRD.md'),
|
|
42
|
+
join(cwd, 'docs', 'PRD.md'),
|
|
43
|
+
join(cwd, 'PRD.md'),
|
|
44
|
+
];
|
|
45
|
+
status.hasPRD = prdPaths.some(p => existsSync(p));
|
|
46
|
+
// Check for architecture docs
|
|
47
|
+
const archPaths = [
|
|
48
|
+
join(cwd, '.compilr', 'architecture'),
|
|
49
|
+
join(cwd, '.claude', 'architecture'),
|
|
50
|
+
join(cwd, 'docs', 'architecture'),
|
|
51
|
+
join(cwd, 'architecture'),
|
|
52
|
+
];
|
|
53
|
+
status.hasArchDocs = archPaths.some(p => {
|
|
54
|
+
try {
|
|
55
|
+
return existsSync(p) && statSync(p).isDirectory();
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
// Check for existing project markers
|
|
62
|
+
const projectMarkers = [
|
|
63
|
+
['package.json', 'node'],
|
|
64
|
+
['Cargo.toml', 'rust'],
|
|
65
|
+
['go.mod', 'go'],
|
|
66
|
+
['pyproject.toml', 'python'],
|
|
67
|
+
['requirements.txt', 'python'],
|
|
68
|
+
['Gemfile', 'ruby'],
|
|
69
|
+
['pom.xml', 'java'],
|
|
70
|
+
['build.gradle', 'java'],
|
|
71
|
+
['composer.json', 'php'],
|
|
72
|
+
];
|
|
73
|
+
for (const [marker, type] of projectMarkers) {
|
|
74
|
+
if (existsSync(join(cwd, marker))) {
|
|
75
|
+
status.isExistingProject = true;
|
|
76
|
+
status.projectType = type;
|
|
77
|
+
break;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
// Also check for .git as a project marker
|
|
81
|
+
if (!status.isExistingProject && existsSync(join(cwd, '.git'))) {
|
|
82
|
+
status.isExistingProject = true;
|
|
83
|
+
}
|
|
84
|
+
return status;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Parse backlog.md to count items by status
|
|
88
|
+
*/
|
|
89
|
+
function parseBacklogStats(backlogPath) {
|
|
90
|
+
try {
|
|
91
|
+
const content = readFileSync(backlogPath, 'utf-8');
|
|
92
|
+
const lines = content.split('\n');
|
|
93
|
+
let total = 0;
|
|
94
|
+
let completed = 0;
|
|
95
|
+
let inProgress = 0;
|
|
96
|
+
let pending = 0;
|
|
97
|
+
// Look for status indicators in table rows or list items
|
|
98
|
+
// Patterns: ✅, 🚧, 📋, [x], [ ], - [ ], etc.
|
|
99
|
+
for (const line of lines) {
|
|
100
|
+
// Skip header rows and empty lines
|
|
101
|
+
if (line.startsWith('#') || line.startsWith('|--') || !line.trim())
|
|
102
|
+
continue;
|
|
103
|
+
// Check for status indicators
|
|
104
|
+
if (line.includes('✅') || line.includes('[x]') || line.includes('[X]')) {
|
|
105
|
+
total++;
|
|
106
|
+
completed++;
|
|
107
|
+
}
|
|
108
|
+
else if (line.includes('🚧') || line.includes('In Progress') || line.includes('in_progress')) {
|
|
109
|
+
total++;
|
|
110
|
+
inProgress++;
|
|
111
|
+
}
|
|
112
|
+
else if (line.includes('📋') || line.includes('Planned') || line.includes('[ ]') || line.includes('pending')) {
|
|
113
|
+
total++;
|
|
114
|
+
pending++;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
return { total, completed, inProgress, pending };
|
|
118
|
+
}
|
|
119
|
+
catch {
|
|
120
|
+
return null;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
// =============================================================================
|
|
124
|
+
// Compilr Config Loading
|
|
125
|
+
// =============================================================================
|
|
126
|
+
/**
|
|
127
|
+
* Find and load the .compilr/config.json file
|
|
128
|
+
* Searches in cwd, parent dirs, and sibling -docs folders
|
|
129
|
+
*/
|
|
130
|
+
export function loadCompilrConfig(cwd = process.cwd()) {
|
|
131
|
+
const configPath = findConfigPath(cwd);
|
|
132
|
+
if (!configPath)
|
|
133
|
+
return null;
|
|
134
|
+
try {
|
|
135
|
+
const content = readFileSync(configPath, 'utf-8');
|
|
136
|
+
return JSON.parse(content);
|
|
137
|
+
}
|
|
138
|
+
catch {
|
|
139
|
+
return null;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Find the path to .compilr/config.json
|
|
144
|
+
* Returns null if not found
|
|
145
|
+
*/
|
|
146
|
+
export function findConfigPath(cwd = process.cwd()) {
|
|
147
|
+
// Check in current directory
|
|
148
|
+
const localConfig = join(cwd, '.compilr', 'config.json');
|
|
149
|
+
if (existsSync(localConfig))
|
|
150
|
+
return localConfig;
|
|
151
|
+
// Check for .claude/ (legacy)
|
|
152
|
+
const legacyConfig = join(cwd, '.claude', 'config.json');
|
|
153
|
+
if (existsSync(legacyConfig))
|
|
154
|
+
return legacyConfig;
|
|
155
|
+
// Check for sibling -docs folder (two-repo pattern)
|
|
156
|
+
const parentDir = join(cwd, '..');
|
|
157
|
+
const currentDirName = cwd.split('/').pop() ?? '';
|
|
158
|
+
// If we're in project-name, check project-name-docs
|
|
159
|
+
const docsFolder = join(parentDir, `${currentDirName}-docs`, '.compilr', 'config.json');
|
|
160
|
+
if (existsSync(docsFolder))
|
|
161
|
+
return docsFolder;
|
|
162
|
+
// If we're in project-name-docs, the config is already here
|
|
163
|
+
// (handled by localConfig check above)
|
|
164
|
+
// Check subfolders (if cwd is parent of project)
|
|
165
|
+
try {
|
|
166
|
+
const entries = readdirSync(cwd, { withFileTypes: true });
|
|
167
|
+
for (const entry of entries) {
|
|
168
|
+
if (entry.isDirectory()) {
|
|
169
|
+
// Check for .compilr in subfolder
|
|
170
|
+
const subConfig = join(cwd, entry.name, '.compilr', 'config.json');
|
|
171
|
+
if (existsSync(subConfig))
|
|
172
|
+
return subConfig;
|
|
173
|
+
// Check for -docs sibling pattern
|
|
174
|
+
if (entry.name.endsWith('-docs')) {
|
|
175
|
+
const subDocsConfig = join(cwd, entry.name, '.compilr', 'config.json');
|
|
176
|
+
if (existsSync(subDocsConfig))
|
|
177
|
+
return subDocsConfig;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
catch {
|
|
183
|
+
// Ignore errors
|
|
184
|
+
}
|
|
185
|
+
return null;
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Get the project path from config, falling back to cwd
|
|
189
|
+
*/
|
|
190
|
+
export function getProjectPath(cwd = process.cwd()) {
|
|
191
|
+
const config = loadCompilrConfig(cwd);
|
|
192
|
+
if (config && config.paths.project) {
|
|
193
|
+
return config.paths.project;
|
|
194
|
+
}
|
|
195
|
+
return cwd;
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Get the docs path from config (for two-repo pattern)
|
|
199
|
+
*/
|
|
200
|
+
export function getDocsPath(cwd = process.cwd()) {
|
|
201
|
+
const config = loadCompilrConfig(cwd);
|
|
202
|
+
if (config) {
|
|
203
|
+
return config.paths.docs;
|
|
204
|
+
}
|
|
205
|
+
return null;
|
|
206
|
+
}
|
|
207
|
+
export function getWorkflowStage(status) {
|
|
208
|
+
// New project - nothing exists
|
|
209
|
+
if (!status.initialized && !status.isExistingProject) {
|
|
210
|
+
return 'new';
|
|
211
|
+
}
|
|
212
|
+
// Existing project but not initialized with compilr
|
|
213
|
+
if (!status.initialized && status.isExistingProject) {
|
|
214
|
+
return 'initialized';
|
|
215
|
+
}
|
|
216
|
+
// Has backlog with items - building or maintaining
|
|
217
|
+
if (status.hasBacklog && status.backlogStats) {
|
|
218
|
+
const { total, completed, pending, inProgress } = status.backlogStats;
|
|
219
|
+
// If most items are completed, we're in maintenance mode
|
|
220
|
+
if (total > 0 && completed / total > 0.8) {
|
|
221
|
+
return 'maintaining';
|
|
222
|
+
}
|
|
223
|
+
// If there are pending or in-progress items, we're building
|
|
224
|
+
if (inProgress > 0 || pending > 0) {
|
|
225
|
+
return 'building';
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
// Has PRD but no backlog - still designing
|
|
229
|
+
if (status.hasPRD && !status.hasBacklog) {
|
|
230
|
+
return 'designing';
|
|
231
|
+
}
|
|
232
|
+
// Initialized but no requirements - need to design
|
|
233
|
+
if (status.initialized && !status.hasPRD && !status.hasBacklog) {
|
|
234
|
+
return 'designing';
|
|
235
|
+
}
|
|
236
|
+
return 'initialized';
|
|
237
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@compilr-dev/cli",
|
|
3
|
+
"version": "0.4.0",
|
|
4
|
+
"description": "AI-powered coding assistant CLI using @compilr-dev/agents",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"bin": {
|
|
8
|
+
"compilr": "dist/index.js"
|
|
9
|
+
},
|
|
10
|
+
"scripts": {
|
|
11
|
+
"build": "tsc",
|
|
12
|
+
"start": "node dist/index.js",
|
|
13
|
+
"dev": "tsc && node dist/index.js",
|
|
14
|
+
"clean": "rm -rf dist",
|
|
15
|
+
"lint": "eslint src/",
|
|
16
|
+
"lint:fix": "eslint src/ --fix",
|
|
17
|
+
"prepublishOnly": "npm run lint && npm run build"
|
|
18
|
+
},
|
|
19
|
+
"keywords": [
|
|
20
|
+
"cli",
|
|
21
|
+
"ai",
|
|
22
|
+
"coding-assistant",
|
|
23
|
+
"agents",
|
|
24
|
+
"llm",
|
|
25
|
+
"claude",
|
|
26
|
+
"openai",
|
|
27
|
+
"terminal"
|
|
28
|
+
],
|
|
29
|
+
"author": "Carmelo Scozzola",
|
|
30
|
+
"license": "MIT",
|
|
31
|
+
"repository": {
|
|
32
|
+
"type": "git",
|
|
33
|
+
"url": "git+https://github.com/compilr-dev/cli.git"
|
|
34
|
+
},
|
|
35
|
+
"homepage": "https://compilr.dev",
|
|
36
|
+
"bugs": {
|
|
37
|
+
"url": "https://github.com/compilr-dev/cli/issues"
|
|
38
|
+
},
|
|
39
|
+
"files": [
|
|
40
|
+
"dist",
|
|
41
|
+
"README.md",
|
|
42
|
+
"LICENSE"
|
|
43
|
+
],
|
|
44
|
+
"engines": {
|
|
45
|
+
"node": ">=18.0.0"
|
|
46
|
+
},
|
|
47
|
+
"dependencies": {
|
|
48
|
+
"@anthropic-ai/sdk": "^0.30.1",
|
|
49
|
+
"@compilr-dev/agents": "^0.2.1",
|
|
50
|
+
"@compilr-dev/agents-coding": "^0.1.1",
|
|
51
|
+
"better-sqlite3": "^12.5.0",
|
|
52
|
+
"chalk": "^5.6.2",
|
|
53
|
+
"marked": "^15.0.12",
|
|
54
|
+
"marked-terminal": "^7.3.0",
|
|
55
|
+
"picocolors": "^1.1.1"
|
|
56
|
+
},
|
|
57
|
+
"devDependencies": {
|
|
58
|
+
"@eslint/js": "^9.39.1",
|
|
59
|
+
"@types/better-sqlite3": "^7.6.13",
|
|
60
|
+
"@types/marked-terminal": "^6.1.1",
|
|
61
|
+
"@types/node": "^22.0.0",
|
|
62
|
+
"eslint": "^9.39.1",
|
|
63
|
+
"typescript": "^5.3.0",
|
|
64
|
+
"typescript-eslint": "^8.48.0"
|
|
65
|
+
}
|
|
66
|
+
}
|