aicodeman 0.2.8
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 +403 -0
- package/dist/ai-checker-base.d.ts +175 -0
- package/dist/ai-checker-base.d.ts.map +1 -0
- package/dist/ai-checker-base.js +424 -0
- package/dist/ai-checker-base.js.map +1 -0
- package/dist/ai-idle-checker.d.ts +53 -0
- package/dist/ai-idle-checker.d.ts.map +1 -0
- package/dist/ai-idle-checker.js +141 -0
- package/dist/ai-idle-checker.js.map +1 -0
- package/dist/ai-plan-checker.d.ts +52 -0
- package/dist/ai-plan-checker.d.ts.map +1 -0
- package/dist/ai-plan-checker.js +103 -0
- package/dist/ai-plan-checker.js.map +1 -0
- package/dist/bash-tool-parser.d.ts +191 -0
- package/dist/bash-tool-parser.d.ts.map +1 -0
- package/dist/bash-tool-parser.js +598 -0
- package/dist/bash-tool-parser.js.map +1 -0
- package/dist/cli.d.ts +12 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +460 -0
- package/dist/cli.js.map +1 -0
- package/dist/config/buffer-limits.d.ts +59 -0
- package/dist/config/buffer-limits.d.ts.map +1 -0
- package/dist/config/buffer-limits.js +74 -0
- package/dist/config/buffer-limits.js.map +1 -0
- package/dist/config/map-limits.d.ts +40 -0
- package/dist/config/map-limits.d.ts.map +1 -0
- package/dist/config/map-limits.js +52 -0
- package/dist/config/map-limits.js.map +1 -0
- package/dist/file-stream-manager.d.ts +148 -0
- package/dist/file-stream-manager.d.ts.map +1 -0
- package/dist/file-stream-manager.js +351 -0
- package/dist/file-stream-manager.js.map +1 -0
- package/dist/hooks-config.d.ts +31 -0
- package/dist/hooks-config.d.ts.map +1 -0
- package/dist/hooks-config.js +115 -0
- package/dist/hooks-config.js.map +1 -0
- package/dist/image-watcher.d.ts +86 -0
- package/dist/image-watcher.d.ts.map +1 -0
- package/dist/image-watcher.js +275 -0
- package/dist/image-watcher.js.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +54 -0
- package/dist/index.js.map +1 -0
- package/dist/mux-factory.d.ts +13 -0
- package/dist/mux-factory.d.ts.map +1 -0
- package/dist/mux-factory.js +19 -0
- package/dist/mux-factory.js.map +1 -0
- package/dist/mux-interface.d.ts +145 -0
- package/dist/mux-interface.d.ts.map +1 -0
- package/dist/mux-interface.js +9 -0
- package/dist/mux-interface.js.map +1 -0
- package/dist/plan-orchestrator.d.ts +123 -0
- package/dist/plan-orchestrator.d.ts.map +1 -0
- package/dist/plan-orchestrator.js +500 -0
- package/dist/plan-orchestrator.js.map +1 -0
- package/dist/prompts/index.d.ts +9 -0
- package/dist/prompts/index.d.ts.map +1 -0
- package/dist/prompts/index.js +9 -0
- package/dist/prompts/index.js.map +1 -0
- package/dist/prompts/planner.d.ts +14 -0
- package/dist/prompts/planner.d.ts.map +1 -0
- package/dist/prompts/planner.js +83 -0
- package/dist/prompts/planner.js.map +1 -0
- package/dist/prompts/research-agent.d.ts +10 -0
- package/dist/prompts/research-agent.d.ts.map +1 -0
- package/dist/prompts/research-agent.js +143 -0
- package/dist/prompts/research-agent.js.map +1 -0
- package/dist/push-store.d.ts +41 -0
- package/dist/push-store.d.ts.map +1 -0
- package/dist/push-store.js +168 -0
- package/dist/push-store.js.map +1 -0
- package/dist/ralph-config.d.ts +67 -0
- package/dist/ralph-config.d.ts.map +1 -0
- package/dist/ralph-config.js +134 -0
- package/dist/ralph-config.js.map +1 -0
- package/dist/ralph-loop.d.ts +124 -0
- package/dist/ralph-loop.d.ts.map +1 -0
- package/dist/ralph-loop.js +418 -0
- package/dist/ralph-loop.js.map +1 -0
- package/dist/ralph-tracker.d.ts +1081 -0
- package/dist/ralph-tracker.d.ts.map +1 -0
- package/dist/ralph-tracker.js +3343 -0
- package/dist/ralph-tracker.js.map +1 -0
- package/dist/respawn-controller.d.ts +1182 -0
- package/dist/respawn-controller.d.ts.map +1 -0
- package/dist/respawn-controller.js +2754 -0
- package/dist/respawn-controller.js.map +1 -0
- package/dist/run-summary.d.ts +123 -0
- package/dist/run-summary.d.ts.map +1 -0
- package/dist/run-summary.js +325 -0
- package/dist/run-summary.js.map +1 -0
- package/dist/session-lifecycle-log.d.ts +36 -0
- package/dist/session-lifecycle-log.d.ts.map +1 -0
- package/dist/session-lifecycle-log.js +101 -0
- package/dist/session-lifecycle-log.js.map +1 -0
- package/dist/session-manager.d.ts +97 -0
- package/dist/session-manager.d.ts.map +1 -0
- package/dist/session-manager.js +224 -0
- package/dist/session-manager.js.map +1 -0
- package/dist/session.d.ts +686 -0
- package/dist/session.d.ts.map +1 -0
- package/dist/session.js +2025 -0
- package/dist/session.js.map +1 -0
- package/dist/state-store.d.ts +189 -0
- package/dist/state-store.d.ts.map +1 -0
- package/dist/state-store.js +730 -0
- package/dist/state-store.js.map +1 -0
- package/dist/subagent-watcher.d.ts +345 -0
- package/dist/subagent-watcher.d.ts.map +1 -0
- package/dist/subagent-watcher.js +1469 -0
- package/dist/subagent-watcher.js.map +1 -0
- package/dist/task-queue.d.ts +108 -0
- package/dist/task-queue.d.ts.map +1 -0
- package/dist/task-queue.js +235 -0
- package/dist/task-queue.js.map +1 -0
- package/dist/task-tracker.d.ts +306 -0
- package/dist/task-tracker.d.ts.map +1 -0
- package/dist/task-tracker.js +488 -0
- package/dist/task-tracker.js.map +1 -0
- package/dist/task.d.ts +73 -0
- package/dist/task.d.ts.map +1 -0
- package/dist/task.js +177 -0
- package/dist/task.js.map +1 -0
- package/dist/team-watcher.d.ts +53 -0
- package/dist/team-watcher.d.ts.map +1 -0
- package/dist/team-watcher.js +313 -0
- package/dist/team-watcher.js.map +1 -0
- package/dist/templates/case-template.md +461 -0
- package/dist/templates/claude-md.d.ts +26 -0
- package/dist/templates/claude-md.d.ts.map +1 -0
- package/dist/templates/claude-md.js +74 -0
- package/dist/templates/claude-md.js.map +1 -0
- package/dist/tmux-manager.d.ts +181 -0
- package/dist/tmux-manager.d.ts.map +1 -0
- package/dist/tmux-manager.js +1405 -0
- package/dist/tmux-manager.js.map +1 -0
- package/dist/transcript-watcher.d.ts +110 -0
- package/dist/transcript-watcher.d.ts.map +1 -0
- package/dist/transcript-watcher.js +338 -0
- package/dist/transcript-watcher.js.map +1 -0
- package/dist/tunnel-manager.d.ts +54 -0
- package/dist/tunnel-manager.d.ts.map +1 -0
- package/dist/tunnel-manager.js +251 -0
- package/dist/tunnel-manager.js.map +1 -0
- package/dist/types.d.ts +1139 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +215 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/buffer-accumulator.d.ts +111 -0
- package/dist/utils/buffer-accumulator.d.ts.map +1 -0
- package/dist/utils/buffer-accumulator.js +172 -0
- package/dist/utils/buffer-accumulator.js.map +1 -0
- package/dist/utils/claude-cli-resolver.d.ts +26 -0
- package/dist/utils/claude-cli-resolver.d.ts.map +1 -0
- package/dist/utils/claude-cli-resolver.js +78 -0
- package/dist/utils/claude-cli-resolver.js.map +1 -0
- package/dist/utils/cleanup-manager.d.ts +165 -0
- package/dist/utils/cleanup-manager.d.ts.map +1 -0
- package/dist/utils/cleanup-manager.js +274 -0
- package/dist/utils/cleanup-manager.js.map +1 -0
- package/dist/utils/index.d.ts +19 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +19 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/lru-map.d.ts +140 -0
- package/dist/utils/lru-map.d.ts.map +1 -0
- package/dist/utils/lru-map.js +234 -0
- package/dist/utils/lru-map.js.map +1 -0
- package/dist/utils/nice-wrapper.d.ts +13 -0
- package/dist/utils/nice-wrapper.d.ts.map +1 -0
- package/dist/utils/nice-wrapper.js +17 -0
- package/dist/utils/nice-wrapper.js.map +1 -0
- package/dist/utils/opencode-cli-resolver.d.ts +21 -0
- package/dist/utils/opencode-cli-resolver.d.ts.map +1 -0
- package/dist/utils/opencode-cli-resolver.js +67 -0
- package/dist/utils/opencode-cli-resolver.js.map +1 -0
- package/dist/utils/regex-patterns.d.ts +64 -0
- package/dist/utils/regex-patterns.d.ts.map +1 -0
- package/dist/utils/regex-patterns.js +74 -0
- package/dist/utils/regex-patterns.js.map +1 -0
- package/dist/utils/stale-expiration-map.d.ts +159 -0
- package/dist/utils/stale-expiration-map.d.ts.map +1 -0
- package/dist/utils/stale-expiration-map.js +277 -0
- package/dist/utils/stale-expiration-map.js.map +1 -0
- package/dist/utils/string-similarity.d.ts +108 -0
- package/dist/utils/string-similarity.d.ts.map +1 -0
- package/dist/utils/string-similarity.js +189 -0
- package/dist/utils/string-similarity.js.map +1 -0
- package/dist/utils/token-validation.d.ts +39 -0
- package/dist/utils/token-validation.d.ts.map +1 -0
- package/dist/utils/token-validation.js +59 -0
- package/dist/utils/token-validation.js.map +1 -0
- package/dist/utils/type-safety.d.ts +33 -0
- package/dist/utils/type-safety.d.ts.map +1 -0
- package/dist/utils/type-safety.js +35 -0
- package/dist/utils/type-safety.js.map +1 -0
- package/dist/web/public/app.js +491 -0
- package/dist/web/public/app.js.br +0 -0
- package/dist/web/public/app.js.gz +0 -0
- package/dist/web/public/index.html +1675 -0
- package/dist/web/public/index.html.br +0 -0
- package/dist/web/public/index.html.gz +0 -0
- package/dist/web/public/manifest.json +8 -0
- package/dist/web/public/mobile.css +1 -0
- package/dist/web/public/mobile.css.br +0 -0
- package/dist/web/public/mobile.css.gz +0 -0
- package/dist/web/public/ralph-wizard.js +1037 -0
- package/dist/web/public/ralph-wizard.js.br +0 -0
- package/dist/web/public/ralph-wizard.js.gz +0 -0
- package/dist/web/public/styles.css +1 -0
- package/dist/web/public/styles.css.br +0 -0
- package/dist/web/public/styles.css.gz +0 -0
- package/dist/web/public/sw.js +67 -0
- package/dist/web/public/sw.js.br +0 -0
- package/dist/web/public/sw.js.gz +0 -0
- package/dist/web/public/upload.html +155 -0
- package/dist/web/public/upload.html.br +0 -0
- package/dist/web/public/upload.html.gz +0 -0
- package/dist/web/public/vendor/xterm-addon-fit.min.js +1 -0
- package/dist/web/public/vendor/xterm-addon-fit.min.js.br +0 -0
- package/dist/web/public/vendor/xterm-addon-fit.min.js.gz +0 -0
- package/dist/web/public/vendor/xterm-addon-unicode11.min.js +1 -0
- package/dist/web/public/vendor/xterm-addon-unicode11.min.js.br +0 -0
- package/dist/web/public/vendor/xterm-addon-unicode11.min.js.gz +0 -0
- package/dist/web/public/vendor/xterm-addon-webgl.min.js +2 -0
- package/dist/web/public/vendor/xterm-addon-webgl.min.js.br +0 -0
- package/dist/web/public/vendor/xterm-addon-webgl.min.js.gz +0 -0
- package/dist/web/public/vendor/xterm.css +209 -0
- package/dist/web/public/vendor/xterm.css.br +0 -0
- package/dist/web/public/vendor/xterm.css.gz +0 -0
- package/dist/web/public/vendor/xterm.min.js +9 -0
- package/dist/web/public/vendor/xterm.min.js.br +0 -0
- package/dist/web/public/vendor/xterm.min.js.gz +0 -0
- package/dist/web/schemas.d.ts +479 -0
- package/dist/web/schemas.d.ts.map +1 -0
- package/dist/web/schemas.js +448 -0
- package/dist/web/schemas.js.map +1 -0
- package/dist/web/server.d.ts +207 -0
- package/dist/web/server.d.ts.map +1 -0
- package/dist/web/server.js +5784 -0
- package/dist/web/server.js.map +1 -0
- package/package.json +110 -0
- package/scripts/postinstall.js +390 -0
|
@@ -0,0 +1,390 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Codeman postinstall verification script
|
|
5
|
+
* Runs after `npm install` to check environment readiness
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { execSync, spawn } from 'child_process';
|
|
9
|
+
import { chmodSync, existsSync } from 'fs';
|
|
10
|
+
import { homedir, platform } from 'os';
|
|
11
|
+
import { join } from 'path';
|
|
12
|
+
import { createRequire } from 'module';
|
|
13
|
+
|
|
14
|
+
// ============================================================================
|
|
15
|
+
// Configuration
|
|
16
|
+
// ============================================================================
|
|
17
|
+
|
|
18
|
+
const MIN_NODE_VERSION = 18;
|
|
19
|
+
|
|
20
|
+
// Claude CLI search paths (must match src/session.ts)
|
|
21
|
+
const home = homedir();
|
|
22
|
+
const CLAUDE_SEARCH_PATHS = [
|
|
23
|
+
join(home, '.local/bin/claude'),
|
|
24
|
+
join(home, '.claude/local/claude'),
|
|
25
|
+
'/usr/local/bin/claude',
|
|
26
|
+
join(home, '.npm-global/bin/claude'),
|
|
27
|
+
join(home, 'bin/claude'),
|
|
28
|
+
];
|
|
29
|
+
|
|
30
|
+
// ============================================================================
|
|
31
|
+
// Colors (with fallback for no-color environments)
|
|
32
|
+
// ============================================================================
|
|
33
|
+
|
|
34
|
+
const useColor = process.stdout.isTTY && !process.env.NO_COLOR;
|
|
35
|
+
|
|
36
|
+
const colors = {
|
|
37
|
+
green: (s) => useColor ? `\x1b[32m${s}\x1b[0m` : s,
|
|
38
|
+
yellow: (s) => useColor ? `\x1b[33m${s}\x1b[0m` : s,
|
|
39
|
+
red: (s) => useColor ? `\x1b[31m${s}\x1b[0m` : s,
|
|
40
|
+
cyan: (s) => useColor ? `\x1b[36m${s}\x1b[0m` : s,
|
|
41
|
+
bold: (s) => useColor ? `\x1b[1m${s}\x1b[0m` : s,
|
|
42
|
+
dim: (s) => useColor ? `\x1b[2m${s}\x1b[0m` : s,
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
// ============================================================================
|
|
46
|
+
// Utility Functions
|
|
47
|
+
// ============================================================================
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Check if a command exists in PATH
|
|
51
|
+
* Works on Unix and Windows
|
|
52
|
+
*/
|
|
53
|
+
function commandExists(cmd) {
|
|
54
|
+
try {
|
|
55
|
+
const checkCmd = platform() === 'win32' ? `where ${cmd}` : `command -v ${cmd}`;
|
|
56
|
+
execSync(checkCmd, { stdio: 'pipe' });
|
|
57
|
+
return true;
|
|
58
|
+
} catch {
|
|
59
|
+
return false;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Check if a TCP port is already in use
|
|
65
|
+
*/
|
|
66
|
+
async function isPortBusy(port) {
|
|
67
|
+
const net = await import('node:net');
|
|
68
|
+
return new Promise((resolve) => {
|
|
69
|
+
const srv = net.createServer();
|
|
70
|
+
srv.once('error', () => resolve(true));
|
|
71
|
+
srv.once('listening', () => { srv.close(); resolve(false); });
|
|
72
|
+
srv.listen(port, '127.0.0.1');
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Wait for a server to start accepting connections
|
|
78
|
+
*/
|
|
79
|
+
async function waitForServer(port, timeoutMs = 15000) {
|
|
80
|
+
const net = await import('node:net');
|
|
81
|
+
const start = Date.now();
|
|
82
|
+
while (Date.now() - start < timeoutMs) {
|
|
83
|
+
const ok = await new Promise((resolve) => {
|
|
84
|
+
const conn = net.createConnection({ port, host: '127.0.0.1' });
|
|
85
|
+
conn.once('connect', () => { conn.destroy(); resolve(true); });
|
|
86
|
+
conn.once('error', () => resolve(false));
|
|
87
|
+
});
|
|
88
|
+
if (ok) return true;
|
|
89
|
+
await new Promise(r => setTimeout(r, 500));
|
|
90
|
+
}
|
|
91
|
+
return false;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Get install instructions for tmux based on platform
|
|
96
|
+
*/
|
|
97
|
+
function getTmuxInstallInstructions() {
|
|
98
|
+
const os = platform();
|
|
99
|
+
|
|
100
|
+
if (os === 'darwin') {
|
|
101
|
+
return [
|
|
102
|
+
' macOS: brew install tmux',
|
|
103
|
+
];
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
if (os === 'linux') {
|
|
107
|
+
return [
|
|
108
|
+
' Ubuntu/Debian: sudo apt install tmux',
|
|
109
|
+
' Fedora/RHEL: sudo dnf install tmux',
|
|
110
|
+
' Arch Linux: sudo pacman -S tmux',
|
|
111
|
+
' Alpine: sudo apk add tmux',
|
|
112
|
+
];
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
if (os === 'win32') {
|
|
116
|
+
return [
|
|
117
|
+
' Windows: Use WSL (Windows Subsystem for Linux)',
|
|
118
|
+
];
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
return [' Please install tmux for your platform'];
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// ============================================================================
|
|
125
|
+
// Main Checks
|
|
126
|
+
// ============================================================================
|
|
127
|
+
|
|
128
|
+
console.log(colors.bold('Codeman postinstall check...'));
|
|
129
|
+
console.log('');
|
|
130
|
+
|
|
131
|
+
let hasWarnings = false;
|
|
132
|
+
let hasErrors = false;
|
|
133
|
+
|
|
134
|
+
// ----------------------------------------------------------------------------
|
|
135
|
+
// 1. Check Node.js version >= 18
|
|
136
|
+
// ----------------------------------------------------------------------------
|
|
137
|
+
|
|
138
|
+
const nodeVersion = process.versions.node;
|
|
139
|
+
const majorVersion = parseInt(nodeVersion.split('.')[0], 10);
|
|
140
|
+
|
|
141
|
+
if (majorVersion < MIN_NODE_VERSION) {
|
|
142
|
+
console.log(colors.red(`✗ Node.js v${nodeVersion} is too old`));
|
|
143
|
+
console.log(colors.dim(` Minimum required: v${MIN_NODE_VERSION}`));
|
|
144
|
+
console.log('');
|
|
145
|
+
hasErrors = true;
|
|
146
|
+
} else {
|
|
147
|
+
console.log(colors.green(`✓ Node.js v${nodeVersion}`) + colors.dim(` (meets >=v${MIN_NODE_VERSION} requirement)`));
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// ----------------------------------------------------------------------------
|
|
151
|
+
// 1b. Fix node-pty spawn-helper permissions (macOS posix_spawnp fix)
|
|
152
|
+
// ----------------------------------------------------------------------------
|
|
153
|
+
|
|
154
|
+
try {
|
|
155
|
+
const require = createRequire(import.meta.url);
|
|
156
|
+
const ptyPath = join(require.resolve('node-pty'), '..');
|
|
157
|
+
const spawnHelper = join(ptyPath, 'build', 'Release', 'spawn-helper');
|
|
158
|
+
if (existsSync(spawnHelper)) {
|
|
159
|
+
chmodSync(spawnHelper, 0o755);
|
|
160
|
+
console.log(colors.green('✓ node-pty spawn-helper permissions fixed'));
|
|
161
|
+
}
|
|
162
|
+
} catch {
|
|
163
|
+
// Non-critical — only affects macOS with prebuilt binaries
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// ----------------------------------------------------------------------------
|
|
167
|
+
// 1c. Rebuild node-pty from source for Node.js 22+ compatibility
|
|
168
|
+
// ----------------------------------------------------------------------------
|
|
169
|
+
|
|
170
|
+
if (majorVersion >= 22) {
|
|
171
|
+
try {
|
|
172
|
+
console.log(colors.dim(' Rebuilding node-pty from source for Node.js 22+...'));
|
|
173
|
+
execSync('npm rebuild node-pty --build-from-source', { stdio: 'pipe', timeout: 120000 });
|
|
174
|
+
console.log(colors.green('✓ node-pty rebuilt from source'));
|
|
175
|
+
} catch {
|
|
176
|
+
hasWarnings = true;
|
|
177
|
+
console.log(colors.yellow('⚠ Failed to rebuild node-pty from source'));
|
|
178
|
+
console.log(colors.dim(' You may need to run: npm rebuild node-pty --build-from-source'));
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
// ----------------------------------------------------------------------------
|
|
183
|
+
// 2. Check if terminal multiplexer is installed (tmux preferred, screen fallback)
|
|
184
|
+
// ----------------------------------------------------------------------------
|
|
185
|
+
|
|
186
|
+
if (commandExists('tmux')) {
|
|
187
|
+
console.log(colors.green('✓ tmux found (preferred)'));
|
|
188
|
+
} else if (commandExists('screen')) {
|
|
189
|
+
console.log(colors.green('✓ GNU Screen found') + colors.dim(' (fallback — consider installing tmux)'));
|
|
190
|
+
} else {
|
|
191
|
+
hasWarnings = true;
|
|
192
|
+
console.log(colors.yellow('⚠ No terminal multiplexer found'));
|
|
193
|
+
console.log(colors.dim(' tmux is required for session persistence.'));
|
|
194
|
+
console.log(colors.dim(' Install:'));
|
|
195
|
+
for (const instruction of getTmuxInstallInstructions()) {
|
|
196
|
+
console.log(colors.dim(instruction));
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// ----------------------------------------------------------------------------
|
|
201
|
+
// 3. Check if Claude CLI is found
|
|
202
|
+
// ----------------------------------------------------------------------------
|
|
203
|
+
|
|
204
|
+
let claudeFound = false;
|
|
205
|
+
let claudePath = null;
|
|
206
|
+
|
|
207
|
+
// First try PATH lookup
|
|
208
|
+
if (commandExists('claude')) {
|
|
209
|
+
claudeFound = true;
|
|
210
|
+
try {
|
|
211
|
+
const checkCmd = platform() === 'win32' ? 'where claude' : 'command -v claude';
|
|
212
|
+
claudePath = execSync(checkCmd, { stdio: 'pipe', encoding: 'utf-8' }).trim().split('\n')[0];
|
|
213
|
+
} catch {
|
|
214
|
+
// Ignore, we know it exists
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
// Check known paths if not found in PATH
|
|
219
|
+
if (!claudeFound) {
|
|
220
|
+
for (const p of CLAUDE_SEARCH_PATHS) {
|
|
221
|
+
if (existsSync(p)) {
|
|
222
|
+
claudeFound = true;
|
|
223
|
+
claudePath = p;
|
|
224
|
+
break;
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
if (claudeFound) {
|
|
230
|
+
const pathInfo = claudePath ? colors.dim(` (${claudePath})`) : '';
|
|
231
|
+
console.log(colors.green('✓ Claude CLI found') + pathInfo);
|
|
232
|
+
} else {
|
|
233
|
+
hasWarnings = true;
|
|
234
|
+
console.log(colors.yellow('⚠ Claude CLI not found'));
|
|
235
|
+
console.log(colors.dim(' Claude CLI is required to run AI sessions.'));
|
|
236
|
+
console.log(colors.dim(' Install:'));
|
|
237
|
+
console.log(colors.cyan(' curl -fsSL https://claude.ai/install.sh | bash'));
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
// ----------------------------------------------------------------------------
|
|
241
|
+
// 4. Copy xterm vendor files for dev mode (src/web/public/vendor/)
|
|
242
|
+
// Skip for global installs — dist/ already has built vendor files
|
|
243
|
+
// ----------------------------------------------------------------------------
|
|
244
|
+
|
|
245
|
+
const srcDir = join(import.meta.dirname, '..', 'src');
|
|
246
|
+
const isGlobalInstall = !existsSync(srcDir);
|
|
247
|
+
|
|
248
|
+
if (isGlobalInstall) {
|
|
249
|
+
console.log(colors.dim(' Skipping vendor copy (global install — dist/ already has built assets)'));
|
|
250
|
+
} else {
|
|
251
|
+
try {
|
|
252
|
+
const require = createRequire(import.meta.url);
|
|
253
|
+
const xtermDir = join(require.resolve('xterm'), '..', '..');
|
|
254
|
+
const fitDir = join(require.resolve('xterm-addon-fit'), '..', '..');
|
|
255
|
+
const webglDir = join(require.resolve('xterm-addon-webgl'), '..', '..');
|
|
256
|
+
const unicode11Dir = join(require.resolve('xterm-addon-unicode11'), '..', '..');
|
|
257
|
+
const vendorDir = join(srcDir, 'web', 'public', 'vendor');
|
|
258
|
+
|
|
259
|
+
const { mkdirSync, copyFileSync } = await import('fs');
|
|
260
|
+
mkdirSync(vendorDir, { recursive: true });
|
|
261
|
+
copyFileSync(join(xtermDir, 'css', 'xterm.css'), join(vendorDir, 'xterm.css'));
|
|
262
|
+
|
|
263
|
+
// Minify xterm JS for dev vendor dir (npm packages don't ship .min.js)
|
|
264
|
+
try {
|
|
265
|
+
execSync(`npx esbuild "${join(xtermDir, 'lib', 'xterm.js')}" --minify --outfile="${join(vendorDir, 'xterm.min.js')}"`, { stdio: 'pipe' });
|
|
266
|
+
execSync(`npx esbuild "${join(fitDir, 'lib', 'xterm-addon-fit.js')}" --minify --outfile="${join(vendorDir, 'xterm-addon-fit.min.js')}"`, { stdio: 'pipe' });
|
|
267
|
+
execSync(`npx esbuild "${join(unicode11Dir, 'lib', 'xterm-addon-unicode11.js')}" --minify --outfile="${join(vendorDir, 'xterm-addon-unicode11.min.js')}"`, { stdio: 'pipe' });
|
|
268
|
+
console.log(colors.green('✓ xterm vendor files copied to src/web/public/vendor/'));
|
|
269
|
+
} catch {
|
|
270
|
+
// Fallback: copy unminified
|
|
271
|
+
copyFileSync(join(xtermDir, 'lib', 'xterm.js'), join(vendorDir, 'xterm.min.js'));
|
|
272
|
+
copyFileSync(join(fitDir, 'lib', 'xterm-addon-fit.js'), join(vendorDir, 'xterm-addon-fit.min.js'));
|
|
273
|
+
copyFileSync(join(unicode11Dir, 'lib', 'xterm-addon-unicode11.js'), join(vendorDir, 'xterm-addon-unicode11.min.js'));
|
|
274
|
+
console.log(colors.green('✓ xterm vendor files copied') + colors.dim(' (unminified — esbuild not available)'));
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
// WebGL addon: copy unminified (matches build script behavior)
|
|
278
|
+
copyFileSync(join(webglDir, 'lib', 'xterm-addon-webgl.js'), join(vendorDir, 'xterm-addon-webgl.min.js'));
|
|
279
|
+
} catch (err) {
|
|
280
|
+
hasWarnings = true;
|
|
281
|
+
console.log(colors.yellow('⚠ Failed to copy xterm vendor files'));
|
|
282
|
+
console.log(colors.dim(` ${err.message}`));
|
|
283
|
+
console.log(colors.dim(' Dev server may fail to load xterm.js — run: npm run build'));
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
// ----------------------------------------------------------------------------
|
|
288
|
+
// Summary
|
|
289
|
+
// ----------------------------------------------------------------------------
|
|
290
|
+
|
|
291
|
+
console.log('');
|
|
292
|
+
|
|
293
|
+
if (hasErrors) {
|
|
294
|
+
console.log(colors.red(colors.bold('Installation cannot proceed due to errors above.')));
|
|
295
|
+
process.exit(1);
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
if (hasWarnings) {
|
|
299
|
+
console.log(colors.yellow('Note: Resolve warnings above for full functionality.'));
|
|
300
|
+
console.log('');
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
// ----------------------------------------------------------------------------
|
|
304
|
+
// Auto-start Codeman web server
|
|
305
|
+
// ----------------------------------------------------------------------------
|
|
306
|
+
|
|
307
|
+
const port = parseInt(process.env.PORT || '3000', 10);
|
|
308
|
+
const projectRoot = join(import.meta.dirname, '..');
|
|
309
|
+
|
|
310
|
+
if (process.env.CI || process.env.CODEMAN_NO_AUTOSTART) {
|
|
311
|
+
// CI or explicit opt-out — just print next steps
|
|
312
|
+
console.log(colors.bold('Next steps:'));
|
|
313
|
+
if (isGlobalInstall) {
|
|
314
|
+
console.log(colors.dim(' 1. Start: ') + colors.cyan('codeman web'));
|
|
315
|
+
console.log(colors.dim(' 2. Open: ') + colors.cyan(`http://localhost:${port}`));
|
|
316
|
+
} else {
|
|
317
|
+
console.log(colors.dim(' 1. Build: ') + colors.cyan('npm run build'));
|
|
318
|
+
console.log(colors.dim(' 2. Start: ') + colors.cyan('npx codeman web'));
|
|
319
|
+
console.log(colors.dim(' 3. Open: ') + colors.cyan(`http://localhost:${port}`));
|
|
320
|
+
}
|
|
321
|
+
console.log('');
|
|
322
|
+
} else {
|
|
323
|
+
// Auto-start the server
|
|
324
|
+
const portInUse = await isPortBusy(port);
|
|
325
|
+
|
|
326
|
+
if (portInUse) {
|
|
327
|
+
console.log(colors.green('✓ Codeman appears to be already running'));
|
|
328
|
+
console.log('');
|
|
329
|
+
console.log(colors.bold(' ┌──────────────────────────────────────────┐'));
|
|
330
|
+
console.log(colors.bold(` │ ${colors.cyan(`→ http://localhost:${port}`)}${' '.repeat(Math.max(0, 21 - String(port).length))}│`));
|
|
331
|
+
console.log(colors.bold(' └──────────────────────────────────────────┘'));
|
|
332
|
+
console.log('');
|
|
333
|
+
} else {
|
|
334
|
+
// Build if dist/ doesn't exist (local install only)
|
|
335
|
+
const distEntry = join(projectRoot, 'dist', 'index.js');
|
|
336
|
+
let buildOk = existsSync(distEntry);
|
|
337
|
+
|
|
338
|
+
if (!buildOk && !isGlobalInstall) {
|
|
339
|
+
const hasTsc = existsSync(join(projectRoot, 'node_modules', '.bin', 'tsc'));
|
|
340
|
+
if (hasTsc) {
|
|
341
|
+
console.log(colors.dim(' Building Codeman...'));
|
|
342
|
+
try {
|
|
343
|
+
execSync('npm run build', {
|
|
344
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
345
|
+
timeout: 180000,
|
|
346
|
+
cwd: projectRoot,
|
|
347
|
+
});
|
|
348
|
+
console.log(colors.green('✓ Build complete'));
|
|
349
|
+
buildOk = true;
|
|
350
|
+
} catch {
|
|
351
|
+
console.log(colors.yellow('⚠ Build failed — start manually: npm run build && npx codeman web'));
|
|
352
|
+
}
|
|
353
|
+
} else {
|
|
354
|
+
console.log(colors.yellow('⚠ TypeScript not found — run: npm run build'));
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
if (buildOk) {
|
|
359
|
+
console.log(colors.dim(' Starting Codeman web server...'));
|
|
360
|
+
try {
|
|
361
|
+
const child = spawn('node', [join(projectRoot, 'dist', 'index.js'), 'web'], {
|
|
362
|
+
detached: true,
|
|
363
|
+
stdio: 'ignore',
|
|
364
|
+
cwd: projectRoot,
|
|
365
|
+
env: { ...process.env, NODE_ENV: 'production' },
|
|
366
|
+
});
|
|
367
|
+
child.unref();
|
|
368
|
+
|
|
369
|
+
const ready = await waitForServer(port);
|
|
370
|
+
|
|
371
|
+
console.log('');
|
|
372
|
+
if (ready) {
|
|
373
|
+
console.log(colors.green('✓ Codeman is running'));
|
|
374
|
+
} else {
|
|
375
|
+
console.log(colors.yellow('⚠ Server may still be starting...'));
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
console.log('');
|
|
379
|
+
console.log(colors.bold(' ┌──────────────────────────────────────────┐'));
|
|
380
|
+
console.log(colors.bold(` │ ${colors.cyan(`→ http://localhost:${port}`)}${' '.repeat(Math.max(0, 21 - String(port).length))}│`));
|
|
381
|
+
console.log(colors.bold(' └──────────────────────────────────────────┘'));
|
|
382
|
+
console.log('');
|
|
383
|
+
} catch (err) {
|
|
384
|
+
console.log(colors.yellow(`⚠ Could not auto-start: ${err.message}`));
|
|
385
|
+
console.log(colors.dim(' Start manually: npx codeman web'));
|
|
386
|
+
console.log('');
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
}
|