@cluesmith/codev 1.1.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/bin/af.js +8 -0
- package/bin/codev.js +4 -0
- package/bin/consult.js +7 -0
- package/dist/agent-farm/cli.d.ts +11 -0
- package/dist/agent-farm/cli.d.ts.map +1 -0
- package/dist/agent-farm/cli.js +359 -0
- package/dist/agent-farm/cli.js.map +1 -0
- package/dist/agent-farm/commands/cleanup.d.ts +12 -0
- package/dist/agent-farm/commands/cleanup.d.ts.map +1 -0
- package/dist/agent-farm/commands/cleanup.js +154 -0
- package/dist/agent-farm/commands/cleanup.js.map +1 -0
- package/dist/agent-farm/commands/db.d.ts +38 -0
- package/dist/agent-farm/commands/db.d.ts.map +1 -0
- package/dist/agent-farm/commands/db.js +133 -0
- package/dist/agent-farm/commands/db.js.map +1 -0
- package/dist/agent-farm/commands/index.d.ts +11 -0
- package/dist/agent-farm/commands/index.d.ts.map +1 -0
- package/dist/agent-farm/commands/index.js +11 -0
- package/dist/agent-farm/commands/index.js.map +1 -0
- package/dist/agent-farm/commands/open.d.ts +15 -0
- package/dist/agent-farm/commands/open.d.ts.map +1 -0
- package/dist/agent-farm/commands/open.js +118 -0
- package/dist/agent-farm/commands/open.js.map +1 -0
- package/dist/agent-farm/commands/rename.d.ts +13 -0
- package/dist/agent-farm/commands/rename.d.ts.map +1 -0
- package/dist/agent-farm/commands/rename.js +33 -0
- package/dist/agent-farm/commands/rename.js.map +1 -0
- package/dist/agent-farm/commands/send.d.ts +9 -0
- package/dist/agent-farm/commands/send.d.ts.map +1 -0
- package/dist/agent-farm/commands/send.js +282 -0
- package/dist/agent-farm/commands/send.js.map +1 -0
- package/dist/agent-farm/commands/spawn.d.ts +15 -0
- package/dist/agent-farm/commands/spawn.d.ts.map +1 -0
- package/dist/agent-farm/commands/spawn.js +575 -0
- package/dist/agent-farm/commands/spawn.js.map +1 -0
- package/dist/agent-farm/commands/start.d.ts +9 -0
- package/dist/agent-farm/commands/start.d.ts.map +1 -0
- package/dist/agent-farm/commands/start.js +175 -0
- package/dist/agent-farm/commands/start.js.map +1 -0
- package/dist/agent-farm/commands/status.d.ts +8 -0
- package/dist/agent-farm/commands/status.d.ts.map +1 -0
- package/dist/agent-farm/commands/status.js +123 -0
- package/dist/agent-farm/commands/status.js.map +1 -0
- package/dist/agent-farm/commands/stop.d.ts +8 -0
- package/dist/agent-farm/commands/stop.d.ts.map +1 -0
- package/dist/agent-farm/commands/stop.js +76 -0
- package/dist/agent-farm/commands/stop.js.map +1 -0
- package/dist/agent-farm/commands/tower.d.ts +19 -0
- package/dist/agent-farm/commands/tower.d.ts.map +1 -0
- package/dist/agent-farm/commands/tower.js +125 -0
- package/dist/agent-farm/commands/tower.js.map +1 -0
- package/dist/agent-farm/commands/tutorial.d.ts +10 -0
- package/dist/agent-farm/commands/tutorial.d.ts.map +1 -0
- package/dist/agent-farm/commands/tutorial.js +49 -0
- package/dist/agent-farm/commands/tutorial.js.map +1 -0
- package/dist/agent-farm/commands/util.d.ts +15 -0
- package/dist/agent-farm/commands/util.d.ts.map +1 -0
- package/dist/agent-farm/commands/util.js +108 -0
- package/dist/agent-farm/commands/util.js.map +1 -0
- package/dist/agent-farm/db/errors.d.ts +17 -0
- package/dist/agent-farm/db/errors.d.ts.map +1 -0
- package/dist/agent-farm/db/errors.js +46 -0
- package/dist/agent-farm/db/errors.js.map +1 -0
- package/dist/agent-farm/db/index.d.ts +41 -0
- package/dist/agent-farm/db/index.d.ts.map +1 -0
- package/dist/agent-farm/db/index.js +168 -0
- package/dist/agent-farm/db/index.js.map +1 -0
- package/dist/agent-farm/db/migrate.d.ts +15 -0
- package/dist/agent-farm/db/migrate.d.ts.map +1 -0
- package/dist/agent-farm/db/migrate.js +137 -0
- package/dist/agent-farm/db/migrate.js.map +1 -0
- package/dist/agent-farm/db/schema.d.ts +16 -0
- package/dist/agent-farm/db/schema.d.ts.map +1 -0
- package/dist/agent-farm/db/schema.js +103 -0
- package/dist/agent-farm/db/schema.js.map +1 -0
- package/dist/agent-farm/db/types.d.ts +87 -0
- package/dist/agent-farm/db/types.d.ts.map +1 -0
- package/dist/agent-farm/db/types.js +65 -0
- package/dist/agent-farm/db/types.js.map +1 -0
- package/dist/agent-farm/index.d.ts +7 -0
- package/dist/agent-farm/index.d.ts.map +1 -0
- package/dist/agent-farm/index.js +373 -0
- package/dist/agent-farm/index.js.map +1 -0
- package/dist/agent-farm/servers/annotate-server.d.ts +9 -0
- package/dist/agent-farm/servers/annotate-server.d.ts.map +1 -0
- package/dist/agent-farm/servers/annotate-server.js +136 -0
- package/dist/agent-farm/servers/annotate-server.js.map +1 -0
- package/dist/agent-farm/servers/dashboard-server.d.ts +9 -0
- package/dist/agent-farm/servers/dashboard-server.d.ts.map +1 -0
- package/dist/agent-farm/servers/dashboard-server.js +939 -0
- package/dist/agent-farm/servers/dashboard-server.js.map +1 -0
- package/dist/agent-farm/servers/tower-server.d.ts +9 -0
- package/dist/agent-farm/servers/tower-server.d.ts.map +1 -0
- package/dist/agent-farm/servers/tower-server.js +463 -0
- package/dist/agent-farm/servers/tower-server.js.map +1 -0
- package/dist/agent-farm/state.d.ts +93 -0
- package/dist/agent-farm/state.d.ts.map +1 -0
- package/dist/agent-farm/state.js +253 -0
- package/dist/agent-farm/state.js.map +1 -0
- package/dist/agent-farm/tutorial/index.d.ts +8 -0
- package/dist/agent-farm/tutorial/index.d.ts.map +1 -0
- package/dist/agent-farm/tutorial/index.js +8 -0
- package/dist/agent-farm/tutorial/index.js.map +1 -0
- package/dist/agent-farm/tutorial/prompts.d.ts +57 -0
- package/dist/agent-farm/tutorial/prompts.d.ts.map +1 -0
- package/dist/agent-farm/tutorial/prompts.js +147 -0
- package/dist/agent-farm/tutorial/prompts.js.map +1 -0
- package/dist/agent-farm/tutorial/runner.d.ts +52 -0
- package/dist/agent-farm/tutorial/runner.d.ts.map +1 -0
- package/dist/agent-farm/tutorial/runner.js +204 -0
- package/dist/agent-farm/tutorial/runner.js.map +1 -0
- package/dist/agent-farm/tutorial/state.d.ts +26 -0
- package/dist/agent-farm/tutorial/state.d.ts.map +1 -0
- package/dist/agent-farm/tutorial/state.js +89 -0
- package/dist/agent-farm/tutorial/state.js.map +1 -0
- package/dist/agent-farm/tutorial/steps/first-spec.d.ts +7 -0
- package/dist/agent-farm/tutorial/steps/first-spec.d.ts.map +1 -0
- package/dist/agent-farm/tutorial/steps/first-spec.js +136 -0
- package/dist/agent-farm/tutorial/steps/first-spec.js.map +1 -0
- package/dist/agent-farm/tutorial/steps/implementation.d.ts +7 -0
- package/dist/agent-farm/tutorial/steps/implementation.d.ts.map +1 -0
- package/dist/agent-farm/tutorial/steps/implementation.js +76 -0
- package/dist/agent-farm/tutorial/steps/implementation.js.map +1 -0
- package/dist/agent-farm/tutorial/steps/index.d.ts +10 -0
- package/dist/agent-farm/tutorial/steps/index.d.ts.map +1 -0
- package/dist/agent-farm/tutorial/steps/index.js +10 -0
- package/dist/agent-farm/tutorial/steps/index.js.map +1 -0
- package/dist/agent-farm/tutorial/steps/planning.d.ts +7 -0
- package/dist/agent-farm/tutorial/steps/planning.d.ts.map +1 -0
- package/dist/agent-farm/tutorial/steps/planning.js +143 -0
- package/dist/agent-farm/tutorial/steps/planning.js.map +1 -0
- package/dist/agent-farm/tutorial/steps/review.d.ts +7 -0
- package/dist/agent-farm/tutorial/steps/review.d.ts.map +1 -0
- package/dist/agent-farm/tutorial/steps/review.js +78 -0
- package/dist/agent-farm/tutorial/steps/review.js.map +1 -0
- package/dist/agent-farm/tutorial/steps/setup.d.ts +7 -0
- package/dist/agent-farm/tutorial/steps/setup.d.ts.map +1 -0
- package/dist/agent-farm/tutorial/steps/setup.js +126 -0
- package/dist/agent-farm/tutorial/steps/setup.js.map +1 -0
- package/dist/agent-farm/tutorial/steps/welcome.d.ts +7 -0
- package/dist/agent-farm/tutorial/steps/welcome.d.ts.map +1 -0
- package/dist/agent-farm/tutorial/steps/welcome.js +50 -0
- package/dist/agent-farm/tutorial/steps/welcome.js.map +1 -0
- package/dist/agent-farm/types.d.ts +131 -0
- package/dist/agent-farm/types.d.ts.map +1 -0
- package/dist/agent-farm/types.js +5 -0
- package/dist/agent-farm/types.js.map +1 -0
- package/dist/agent-farm/utils/config.d.ts +27 -0
- package/dist/agent-farm/utils/config.d.ts.map +1 -0
- package/dist/agent-farm/utils/config.js +242 -0
- package/dist/agent-farm/utils/config.js.map +1 -0
- package/dist/agent-farm/utils/deps.d.ts +51 -0
- package/dist/agent-farm/utils/deps.d.ts.map +1 -0
- package/dist/agent-farm/utils/deps.js +194 -0
- package/dist/agent-farm/utils/deps.js.map +1 -0
- package/dist/agent-farm/utils/index.d.ts +6 -0
- package/dist/agent-farm/utils/index.d.ts.map +1 -0
- package/dist/agent-farm/utils/index.js +6 -0
- package/dist/agent-farm/utils/index.js.map +1 -0
- package/dist/agent-farm/utils/logger.d.ts +31 -0
- package/dist/agent-farm/utils/logger.d.ts.map +1 -0
- package/dist/agent-farm/utils/logger.js +58 -0
- package/dist/agent-farm/utils/logger.js.map +1 -0
- package/dist/agent-farm/utils/orphan-handler.d.ts +27 -0
- package/dist/agent-farm/utils/orphan-handler.d.ts.map +1 -0
- package/dist/agent-farm/utils/orphan-handler.js +127 -0
- package/dist/agent-farm/utils/orphan-handler.js.map +1 -0
- package/dist/agent-farm/utils/port-registry.d.ts +58 -0
- package/dist/agent-farm/utils/port-registry.d.ts.map +1 -0
- package/dist/agent-farm/utils/port-registry.js +149 -0
- package/dist/agent-farm/utils/port-registry.js.map +1 -0
- package/dist/agent-farm/utils/shell.d.ts +45 -0
- package/dist/agent-farm/utils/shell.d.ts.map +1 -0
- package/dist/agent-farm/utils/shell.js +120 -0
- package/dist/agent-farm/utils/shell.js.map +1 -0
- package/dist/cli.d.ts +10 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +160 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/adopt.d.ts +12 -0
- package/dist/commands/adopt.d.ts.map +1 -0
- package/dist/commands/adopt.js +178 -0
- package/dist/commands/adopt.js.map +1 -0
- package/dist/commands/consult/index.d.ts +17 -0
- package/dist/commands/consult/index.d.ts.map +1 -0
- package/dist/commands/consult/index.js +405 -0
- package/dist/commands/consult/index.js.map +1 -0
- package/dist/commands/doctor.d.ts +10 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +346 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/init.d.ts +12 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +167 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/tower.d.ts +16 -0
- package/dist/commands/tower.d.ts.map +1 -0
- package/dist/commands/tower.js +21 -0
- package/dist/commands/tower.js.map +1 -0
- package/dist/commands/update.d.ts +13 -0
- package/dist/commands/update.d.ts.map +1 -0
- package/dist/commands/update.js +137 -0
- package/dist/commands/update.js.map +1 -0
- package/dist/lib/templates.d.ts +57 -0
- package/dist/lib/templates.d.ts.map +1 -0
- package/dist/lib/templates.js +205 -0
- package/dist/lib/templates.js.map +1 -0
- package/package.json +55 -0
- package/templates/AGENTS.md +49 -0
- package/templates/CLAUDE.md +47 -0
- package/templates/DEPENDENCIES.md +344 -0
- package/templates/agents/architecture-documenter.md +189 -0
- package/templates/agents/codev-updater.md +276 -0
- package/templates/agents/spider-protocol-updater.md +118 -0
- package/templates/annotate.html +903 -0
- package/templates/bin/agent-farm +18 -0
- package/templates/bin/annotate-server.js +140 -0
- package/templates/bin/codev-doctor +335 -0
- package/templates/builders.md +30 -0
- package/templates/config.json +7 -0
- package/templates/dashboard-split.html +1679 -0
- package/templates/dashboard.html +149 -0
- package/templates/plans/.gitkeep +0 -0
- package/templates/protocols/experiment/protocol.md +229 -0
- package/templates/protocols/experiment/templates/notes.md +97 -0
- package/templates/protocols/maintain/protocol.md +235 -0
- package/templates/protocols/spider/protocol.md +639 -0
- package/templates/protocols/spider/templates/plan.md +169 -0
- package/templates/protocols/spider/templates/review.md +207 -0
- package/templates/protocols/spider/templates/spec.md +140 -0
- package/templates/protocols/spider-solo/protocol.md +619 -0
- package/templates/protocols/spider-solo/templates/plan.md +169 -0
- package/templates/protocols/spider-solo/templates/review.md +207 -0
- package/templates/protocols/spider-solo/templates/spec.md +140 -0
- package/templates/protocols/tick/protocol.md +250 -0
- package/templates/protocols/tick/templates/plan.md +67 -0
- package/templates/protocols/tick/templates/review.md +90 -0
- package/templates/protocols/tick/templates/spec.md +61 -0
- package/templates/reviews/.gitkeep +0 -0
- package/templates/roles/architect.md +230 -0
- package/templates/roles/builder.md +175 -0
- package/templates/roles/consultant.md +27 -0
- package/templates/specs/.gitkeep +0 -0
- package/templates/templates/projectlist.md +129 -0
- package/templates/tower.html +1032 -0
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Thin wrapper - forwards all commands to @cluesmith/codev af
|
|
3
|
+
# This script allows projects to use ./codev/bin/agent-farm without
|
|
4
|
+
# having codev installed globally.
|
|
5
|
+
|
|
6
|
+
# First, try the globally installed 'af' command (from @cluesmith/codev)
|
|
7
|
+
if command -v af &> /dev/null; then
|
|
8
|
+
exec af "$@"
|
|
9
|
+
fi
|
|
10
|
+
|
|
11
|
+
# Fall back to npx if af is not globally installed
|
|
12
|
+
if command -v npx &> /dev/null; then
|
|
13
|
+
exec npx @cluesmith/codev af "$@"
|
|
14
|
+
fi
|
|
15
|
+
|
|
16
|
+
echo "Error: Could not find 'af' command" >&2
|
|
17
|
+
echo "Install @cluesmith/codev globally: npm install -g @cluesmith/codev" >&2
|
|
18
|
+
exit 1
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Simple annotation server for the Architect-Builder pattern.
|
|
5
|
+
* Serves the annotation viewer and handles file saves.
|
|
6
|
+
*
|
|
7
|
+
* Usage: node annotate-server.js --builder XXXX --file path/to/file.ts --port 8080
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
const http = require('http');
|
|
11
|
+
const fs = require('fs');
|
|
12
|
+
const path = require('path');
|
|
13
|
+
|
|
14
|
+
// Parse arguments
|
|
15
|
+
const args = process.argv.slice(2);
|
|
16
|
+
const getArg = (name) => {
|
|
17
|
+
const idx = args.indexOf('--' + name);
|
|
18
|
+
return idx !== -1 ? args[idx + 1] : null;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
const builderId = getArg('builder');
|
|
22
|
+
const filePath = getArg('file');
|
|
23
|
+
const port = parseInt(getArg('port') || '8080', 10);
|
|
24
|
+
|
|
25
|
+
if (!builderId || !filePath) {
|
|
26
|
+
console.error('Usage: annotate-server.js --builder XXXX --file path/to/file.ts [--port 8080]');
|
|
27
|
+
process.exit(1);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// Paths
|
|
31
|
+
const projectRoot = process.cwd();
|
|
32
|
+
const buildersDir = path.join(projectRoot, '.builders');
|
|
33
|
+
const builderDir = path.join(buildersDir, builderId);
|
|
34
|
+
const fullFilePath = path.join(builderDir, filePath);
|
|
35
|
+
const templatePath = path.join(projectRoot, 'codev', 'templates', 'annotate.html');
|
|
36
|
+
|
|
37
|
+
// Validate builder exists
|
|
38
|
+
if (!fs.existsSync(builderDir)) {
|
|
39
|
+
console.error(`Builder directory not found: ${builderDir}`);
|
|
40
|
+
process.exit(1);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Validate file exists
|
|
44
|
+
if (!fs.existsSync(fullFilePath)) {
|
|
45
|
+
console.error(`File not found: ${fullFilePath}`);
|
|
46
|
+
process.exit(1);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Get language from extension
|
|
50
|
+
const ext = path.extname(filePath).slice(1).toLowerCase();
|
|
51
|
+
const langMap = {
|
|
52
|
+
js: 'javascript', ts: 'typescript', jsx: 'javascript', tsx: 'typescript',
|
|
53
|
+
py: 'python', sh: 'bash', bash: 'bash',
|
|
54
|
+
md: 'markdown', html: 'markup', css: 'css',
|
|
55
|
+
json: 'json', yaml: 'yaml', yml: 'yaml'
|
|
56
|
+
};
|
|
57
|
+
const lang = langMap[ext] || ext;
|
|
58
|
+
|
|
59
|
+
// Create server
|
|
60
|
+
const server = http.createServer((req, res) => {
|
|
61
|
+
// CORS headers
|
|
62
|
+
res.setHeader('Access-Control-Allow-Origin', '*');
|
|
63
|
+
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
|
|
64
|
+
res.setHeader('Access-Control-Allow-Headers', 'Content-Type');
|
|
65
|
+
|
|
66
|
+
if (req.method === 'OPTIONS') {
|
|
67
|
+
res.writeHead(200);
|
|
68
|
+
res.end();
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// Serve annotation viewer
|
|
73
|
+
if (req.method === 'GET' && (req.url === '/' || req.url === '/index.html')) {
|
|
74
|
+
try {
|
|
75
|
+
let template = fs.readFileSync(templatePath, 'utf-8');
|
|
76
|
+
const fileContent = fs.readFileSync(fullFilePath, 'utf-8');
|
|
77
|
+
|
|
78
|
+
// Replace placeholders
|
|
79
|
+
template = template.replace(/\{\{BUILDER_ID\}\}/g, builderId);
|
|
80
|
+
template = template.replace(/\{\{FILE_PATH\}\}/g, filePath);
|
|
81
|
+
template = template.replace(/\{\{FILE\}\}/g, path.basename(filePath));
|
|
82
|
+
template = template.replace(/\{\{LANG\}\}/g, lang);
|
|
83
|
+
|
|
84
|
+
// Inject file content
|
|
85
|
+
const escapedContent = JSON.stringify(fileContent);
|
|
86
|
+
template = template.replace(
|
|
87
|
+
'// FILE_CONTENT will be injected by the server',
|
|
88
|
+
`init(${escapedContent});`
|
|
89
|
+
);
|
|
90
|
+
|
|
91
|
+
res.writeHead(200, { 'Content-Type': 'text/html' });
|
|
92
|
+
res.end(template);
|
|
93
|
+
} catch (err) {
|
|
94
|
+
res.writeHead(500, { 'Content-Type': 'text/plain' });
|
|
95
|
+
res.end('Error loading viewer: ' + err.message);
|
|
96
|
+
}
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// Handle file save
|
|
101
|
+
if (req.method === 'POST' && req.url === '/save') {
|
|
102
|
+
let body = '';
|
|
103
|
+
req.on('data', chunk => body += chunk);
|
|
104
|
+
req.on('end', () => {
|
|
105
|
+
try {
|
|
106
|
+
const { file, content } = JSON.parse(body);
|
|
107
|
+
|
|
108
|
+
// Security: only allow saving the opened file
|
|
109
|
+
if (file !== filePath) {
|
|
110
|
+
res.writeHead(403, { 'Content-Type': 'text/plain' });
|
|
111
|
+
res.end('Cannot save to different file');
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
fs.writeFileSync(fullFilePath, content, 'utf-8');
|
|
116
|
+
console.log(`Saved: ${fullFilePath}`);
|
|
117
|
+
|
|
118
|
+
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
119
|
+
res.end(JSON.stringify({ success: true }));
|
|
120
|
+
} catch (err) {
|
|
121
|
+
res.writeHead(500, { 'Content-Type': 'text/plain' });
|
|
122
|
+
res.end('Error saving file: ' + err.message);
|
|
123
|
+
}
|
|
124
|
+
});
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// 404 for everything else
|
|
129
|
+
res.writeHead(404, { 'Content-Type': 'text/plain' });
|
|
130
|
+
res.end('Not found');
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
server.listen(port, () => {
|
|
134
|
+
console.log(`\nAnnotation Viewer`);
|
|
135
|
+
console.log(`================`);
|
|
136
|
+
console.log(`Builder: ${builderId}`);
|
|
137
|
+
console.log(`File: ${filePath}`);
|
|
138
|
+
console.log(`\nOpen in browser: http://localhost:${port}`);
|
|
139
|
+
console.log(`\nPress Ctrl+C to stop the server`);
|
|
140
|
+
});
|
|
@@ -0,0 +1,335 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
#
|
|
3
|
+
# codev-doctor - Verify Codev installation and dependencies
|
|
4
|
+
#
|
|
5
|
+
# Usage: ./codev/bin/codev-doctor
|
|
6
|
+
#
|
|
7
|
+
# Checks:
|
|
8
|
+
# - Core dependencies: node, tmux, ttyd, git, gh, python
|
|
9
|
+
# - AI CLI dependencies: claude, gemini, codex (at least one required)
|
|
10
|
+
# - Python packages: typer (for consult tool)
|
|
11
|
+
#
|
|
12
|
+
# Exit codes:
|
|
13
|
+
# 0 - All required dependencies OK
|
|
14
|
+
# 1 - Missing required dependencies
|
|
15
|
+
#
|
|
16
|
+
|
|
17
|
+
set -euo pipefail
|
|
18
|
+
|
|
19
|
+
# Colors (disable if not a terminal)
|
|
20
|
+
if [[ -t 1 ]]; then
|
|
21
|
+
RED='\033[0;31m'
|
|
22
|
+
GREEN='\033[0;32m'
|
|
23
|
+
YELLOW='\033[0;33m'
|
|
24
|
+
BLUE='\033[0;34m'
|
|
25
|
+
BOLD='\033[1m'
|
|
26
|
+
NC='\033[0m' # No Color
|
|
27
|
+
else
|
|
28
|
+
RED=''
|
|
29
|
+
GREEN=''
|
|
30
|
+
YELLOW=''
|
|
31
|
+
BLUE=''
|
|
32
|
+
BOLD=''
|
|
33
|
+
NC=''
|
|
34
|
+
fi
|
|
35
|
+
|
|
36
|
+
# Counters
|
|
37
|
+
ERRORS=0
|
|
38
|
+
WARNINGS=0
|
|
39
|
+
|
|
40
|
+
# Detect OS for install hints
|
|
41
|
+
if [[ "$OSTYPE" == "darwin"* ]]; then
|
|
42
|
+
IS_MACOS=true
|
|
43
|
+
else
|
|
44
|
+
IS_MACOS=false
|
|
45
|
+
fi
|
|
46
|
+
|
|
47
|
+
# Print header
|
|
48
|
+
echo -e "${BOLD}Codev Doctor${NC} - Checking your environment"
|
|
49
|
+
echo "============================================"
|
|
50
|
+
echo ""
|
|
51
|
+
|
|
52
|
+
# Helper function to check if a command exists
|
|
53
|
+
command_exists() {
|
|
54
|
+
command -v "$1" &> /dev/null
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
# Helper function to print status
|
|
58
|
+
print_status() {
|
|
59
|
+
local name="$1"
|
|
60
|
+
local status="$2"
|
|
61
|
+
local version="${3:-}"
|
|
62
|
+
local note="${4:-}"
|
|
63
|
+
|
|
64
|
+
case "$status" in
|
|
65
|
+
ok)
|
|
66
|
+
printf " ${GREEN}%s${NC} %-12s %s" "✓" "$name" "$version"
|
|
67
|
+
;;
|
|
68
|
+
warn)
|
|
69
|
+
printf " ${YELLOW}%s${NC} %-12s %s" "⚠" "$name" "$version"
|
|
70
|
+
((WARNINGS++))
|
|
71
|
+
;;
|
|
72
|
+
fail)
|
|
73
|
+
printf " ${RED}%s${NC} %-12s %s" "✗" "$name" "$version"
|
|
74
|
+
((ERRORS++))
|
|
75
|
+
;;
|
|
76
|
+
skip)
|
|
77
|
+
printf " ${BLUE}%s${NC} %-12s %s" "○" "$name" "$version"
|
|
78
|
+
;;
|
|
79
|
+
esac
|
|
80
|
+
|
|
81
|
+
if [[ -n "$note" ]]; then
|
|
82
|
+
printf " ${BLUE}(%s)${NC}" "$note"
|
|
83
|
+
fi
|
|
84
|
+
echo ""
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
# Compare semantic versions: returns 0 if $1 >= $2
|
|
88
|
+
version_gte() {
|
|
89
|
+
local v1="$1"
|
|
90
|
+
local v2="$2"
|
|
91
|
+
|
|
92
|
+
# Split versions into arrays
|
|
93
|
+
IFS='.' read -ra v1_parts <<< "$v1"
|
|
94
|
+
IFS='.' read -ra v2_parts <<< "$v2"
|
|
95
|
+
|
|
96
|
+
# Compare each part
|
|
97
|
+
for i in 0 1 2; do
|
|
98
|
+
local p1="${v1_parts[$i]:-0}"
|
|
99
|
+
local p2="${v2_parts[$i]:-0}"
|
|
100
|
+
# Remove non-numeric suffixes (e.g., "3a" -> "3")
|
|
101
|
+
p1="${p1%%[!0-9]*}"
|
|
102
|
+
p2="${p2%%[!0-9]*}"
|
|
103
|
+
p1="${p1:-0}"
|
|
104
|
+
p2="${p2:-0}"
|
|
105
|
+
|
|
106
|
+
if (( p1 > p2 )); then
|
|
107
|
+
return 0
|
|
108
|
+
elif (( p1 < p2 )); then
|
|
109
|
+
return 1
|
|
110
|
+
fi
|
|
111
|
+
done
|
|
112
|
+
return 0
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
# Extract version from various command outputs
|
|
116
|
+
get_node_version() {
|
|
117
|
+
node --version 2>/dev/null | sed 's/^v//'
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
get_tmux_version() {
|
|
121
|
+
tmux -V 2>/dev/null | sed 's/tmux //' | sed 's/[a-z]$//'
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
get_ttyd_version() {
|
|
125
|
+
ttyd --version 2>/dev/null | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | head -1
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
get_git_version() {
|
|
129
|
+
git --version 2>/dev/null | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | head -1
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
get_python_version() {
|
|
133
|
+
python3 --version 2>/dev/null | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | head -1
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
# Check core dependencies
|
|
137
|
+
echo -e "${BOLD}Core Dependencies${NC} (required for Agent Farm)"
|
|
138
|
+
echo ""
|
|
139
|
+
|
|
140
|
+
# Node.js
|
|
141
|
+
if command_exists node; then
|
|
142
|
+
version=$(get_node_version)
|
|
143
|
+
if version_gte "$version" "18.0.0"; then
|
|
144
|
+
print_status "Node.js" "ok" "$version"
|
|
145
|
+
else
|
|
146
|
+
print_status "Node.js" "fail" "$version" "need >= 18.0.0"
|
|
147
|
+
fi
|
|
148
|
+
else
|
|
149
|
+
if $IS_MACOS; then
|
|
150
|
+
print_status "Node.js" "fail" "not installed" "brew install node"
|
|
151
|
+
else
|
|
152
|
+
print_status "Node.js" "fail" "not installed" "apt install nodejs npm"
|
|
153
|
+
fi
|
|
154
|
+
fi
|
|
155
|
+
|
|
156
|
+
# tmux
|
|
157
|
+
if command_exists tmux; then
|
|
158
|
+
version=$(get_tmux_version)
|
|
159
|
+
if version_gte "$version" "3.0"; then
|
|
160
|
+
print_status "tmux" "ok" "$version"
|
|
161
|
+
else
|
|
162
|
+
print_status "tmux" "fail" "$version" "need >= 3.0"
|
|
163
|
+
fi
|
|
164
|
+
else
|
|
165
|
+
if $IS_MACOS; then
|
|
166
|
+
print_status "tmux" "fail" "not installed" "brew install tmux"
|
|
167
|
+
else
|
|
168
|
+
print_status "tmux" "fail" "not installed" "apt install tmux"
|
|
169
|
+
fi
|
|
170
|
+
fi
|
|
171
|
+
|
|
172
|
+
# ttyd
|
|
173
|
+
if command_exists ttyd; then
|
|
174
|
+
version=$(get_ttyd_version)
|
|
175
|
+
if [[ -n "$version" ]] && version_gte "$version" "1.7.0"; then
|
|
176
|
+
print_status "ttyd" "ok" "$version"
|
|
177
|
+
elif [[ -n "$version" ]]; then
|
|
178
|
+
print_status "ttyd" "fail" "$version" "need >= 1.7.0"
|
|
179
|
+
else
|
|
180
|
+
print_status "ttyd" "warn" "(version unknown)" "may be incompatible"
|
|
181
|
+
fi
|
|
182
|
+
else
|
|
183
|
+
if $IS_MACOS; then
|
|
184
|
+
print_status "ttyd" "fail" "not installed" "brew install ttyd"
|
|
185
|
+
else
|
|
186
|
+
print_status "ttyd" "fail" "not installed" "build from source"
|
|
187
|
+
fi
|
|
188
|
+
fi
|
|
189
|
+
|
|
190
|
+
# git
|
|
191
|
+
if command_exists git; then
|
|
192
|
+
version=$(get_git_version)
|
|
193
|
+
if version_gte "$version" "2.5.0"; then
|
|
194
|
+
print_status "git" "ok" "$version"
|
|
195
|
+
else
|
|
196
|
+
print_status "git" "warn" "$version" "need >= 2.5.0"
|
|
197
|
+
fi
|
|
198
|
+
else
|
|
199
|
+
if $IS_MACOS; then
|
|
200
|
+
print_status "git" "fail" "not installed" "xcode-select --install"
|
|
201
|
+
else
|
|
202
|
+
print_status "git" "fail" "not installed" "apt install git"
|
|
203
|
+
fi
|
|
204
|
+
fi
|
|
205
|
+
|
|
206
|
+
# gh (GitHub CLI)
|
|
207
|
+
if command_exists gh; then
|
|
208
|
+
# Check if authenticated
|
|
209
|
+
if gh auth status &>/dev/null; then
|
|
210
|
+
print_status "gh" "ok" "authenticated"
|
|
211
|
+
else
|
|
212
|
+
print_status "gh" "warn" "not authenticated" "gh auth login"
|
|
213
|
+
fi
|
|
214
|
+
else
|
|
215
|
+
if $IS_MACOS; then
|
|
216
|
+
print_status "gh" "fail" "not installed" "brew install gh"
|
|
217
|
+
else
|
|
218
|
+
print_status "gh" "fail" "not installed" "apt install gh"
|
|
219
|
+
fi
|
|
220
|
+
fi
|
|
221
|
+
|
|
222
|
+
# Python
|
|
223
|
+
if command_exists python3; then
|
|
224
|
+
version=$(get_python_version)
|
|
225
|
+
if version_gte "$version" "3.10.0"; then
|
|
226
|
+
print_status "Python" "ok" "$version"
|
|
227
|
+
else
|
|
228
|
+
print_status "Python" "warn" "$version" "need >= 3.10"
|
|
229
|
+
fi
|
|
230
|
+
else
|
|
231
|
+
if $IS_MACOS; then
|
|
232
|
+
print_status "Python" "fail" "not installed" "brew install python"
|
|
233
|
+
else
|
|
234
|
+
print_status "Python" "fail" "not installed" "apt install python3"
|
|
235
|
+
fi
|
|
236
|
+
fi
|
|
237
|
+
|
|
238
|
+
echo ""
|
|
239
|
+
|
|
240
|
+
# Check AI CLI dependencies
|
|
241
|
+
echo -e "${BOLD}AI CLI Dependencies${NC} (at least one required)"
|
|
242
|
+
echo ""
|
|
243
|
+
|
|
244
|
+
AI_CLI_COUNT=0
|
|
245
|
+
|
|
246
|
+
# Helper to verify AI CLI actually works (not just installed)
|
|
247
|
+
verify_ai_cli() {
|
|
248
|
+
local cmd="$1"
|
|
249
|
+
local test_args="$2"
|
|
250
|
+
# Run the command with test args and capture exit code
|
|
251
|
+
# Don't use timeout (not available on macOS)
|
|
252
|
+
if "$cmd" $test_args &>/dev/null; then
|
|
253
|
+
return 0
|
|
254
|
+
else
|
|
255
|
+
return 1
|
|
256
|
+
fi
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
# Claude Code
|
|
260
|
+
if command_exists claude; then
|
|
261
|
+
if verify_ai_cli "claude" "--version"; then
|
|
262
|
+
print_status "Claude" "ok" "working"
|
|
263
|
+
((AI_CLI_COUNT++))
|
|
264
|
+
else
|
|
265
|
+
print_status "Claude" "warn" "installed but not working" "check config"
|
|
266
|
+
fi
|
|
267
|
+
else
|
|
268
|
+
print_status "Claude" "skip" "not installed" "npm i -g @anthropic-ai/claude-code"
|
|
269
|
+
fi
|
|
270
|
+
|
|
271
|
+
# Gemini CLI
|
|
272
|
+
if command_exists gemini; then
|
|
273
|
+
if verify_ai_cli "gemini" "--version"; then
|
|
274
|
+
print_status "Gemini" "ok" "working"
|
|
275
|
+
((AI_CLI_COUNT++))
|
|
276
|
+
else
|
|
277
|
+
print_status "Gemini" "warn" "installed but not working" "check GOOGLE_API_KEY"
|
|
278
|
+
fi
|
|
279
|
+
else
|
|
280
|
+
print_status "Gemini" "skip" "not installed" "see github.com/google-gemini/gemini-cli"
|
|
281
|
+
fi
|
|
282
|
+
|
|
283
|
+
# Codex CLI
|
|
284
|
+
if command_exists codex; then
|
|
285
|
+
if verify_ai_cli "codex" "--version"; then
|
|
286
|
+
print_status "Codex" "ok" "working"
|
|
287
|
+
((AI_CLI_COUNT++))
|
|
288
|
+
else
|
|
289
|
+
print_status "Codex" "warn" "installed but not working" "check OPENAI_API_KEY"
|
|
290
|
+
fi
|
|
291
|
+
else
|
|
292
|
+
print_status "Codex" "skip" "not installed" "npm i -g @openai/codex"
|
|
293
|
+
fi
|
|
294
|
+
|
|
295
|
+
if (( AI_CLI_COUNT == 0 )); then
|
|
296
|
+
echo ""
|
|
297
|
+
echo -e " ${RED}✗${NC} No AI CLI working! Install and configure at least one to use Codev."
|
|
298
|
+
((ERRORS++))
|
|
299
|
+
fi
|
|
300
|
+
|
|
301
|
+
echo ""
|
|
302
|
+
|
|
303
|
+
# Check Python packages (for consult tool)
|
|
304
|
+
echo -e "${BOLD}Python Packages${NC} (for consult tool)"
|
|
305
|
+
echo ""
|
|
306
|
+
|
|
307
|
+
if command_exists python3; then
|
|
308
|
+
# Check for typer
|
|
309
|
+
if python3 -c "import typer" 2>/dev/null; then
|
|
310
|
+
print_status "typer" "ok" "installed"
|
|
311
|
+
else
|
|
312
|
+
print_status "typer" "warn" "not installed" "pip install typer"
|
|
313
|
+
fi
|
|
314
|
+
else
|
|
315
|
+
print_status "typer" "skip" "Python not available"
|
|
316
|
+
fi
|
|
317
|
+
|
|
318
|
+
echo ""
|
|
319
|
+
|
|
320
|
+
# Summary
|
|
321
|
+
echo "============================================"
|
|
322
|
+
if (( ERRORS > 0 )); then
|
|
323
|
+
echo -e "${RED}${BOLD}FAILED${NC} - $ERRORS required dependency/dependencies missing"
|
|
324
|
+
echo ""
|
|
325
|
+
echo "Install missing dependencies and run this command again."
|
|
326
|
+
exit 1
|
|
327
|
+
elif (( WARNINGS > 0 )); then
|
|
328
|
+
echo -e "${YELLOW}${BOLD}OK with warnings${NC} - $WARNINGS dependency/dependencies below recommended version"
|
|
329
|
+
echo ""
|
|
330
|
+
echo "Consider upgrading for best experience."
|
|
331
|
+
exit 0
|
|
332
|
+
else
|
|
333
|
+
echo -e "${GREEN}${BOLD}ALL OK${NC} - Your environment is ready for Codev!"
|
|
334
|
+
exit 0
|
|
335
|
+
fi
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# Active Builders
|
|
2
|
+
|
|
3
|
+
Track active builder agents here. Update manually or via `architect status`.
|
|
4
|
+
|
|
5
|
+
## Status Values
|
|
6
|
+
|
|
7
|
+
- **spawning**: Worktree being created, ttyd starting
|
|
8
|
+
- **implementing**: Builder is working
|
|
9
|
+
- **blocked**: Builder waiting for architect input
|
|
10
|
+
- **pr-ready**: Builder has created a PR
|
|
11
|
+
- **reviewing**: Architect is reviewing the PR
|
|
12
|
+
- **complete**: PR merged, ready for cleanup
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## Builders
|
|
17
|
+
|
|
18
|
+
<!-- Add builders below as they are spawned -->
|
|
19
|
+
|
|
20
|
+
<!-- Example:
|
|
21
|
+
## Builder 0003: Feature Name
|
|
22
|
+
- **Branch**: builder/0003-feature-name
|
|
23
|
+
- **Port**: 7681
|
|
24
|
+
- **Status**: implementing
|
|
25
|
+
- **Phase**: 2/4
|
|
26
|
+
- **Started**: 2025-12-02 11:30
|
|
27
|
+
- **PR**: (none yet)
|
|
28
|
+
-->
|
|
29
|
+
|
|
30
|
+
(No active builders)
|