@cluesmith/codev 2.0.0-rc.3 → 2.0.0-rc.33
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/porch.js +6 -35
- package/dashboard/dist/assets/index-CXwnJkPh.css +32 -0
- package/dashboard/dist/assets/index-D429K6qO.js +120 -0
- package/dashboard/dist/assets/index-D429K6qO.js.map +1 -0
- package/dashboard/dist/index.html +13 -0
- package/dist/agent-farm/cli.d.ts.map +1 -1
- package/dist/agent-farm/cli.js +74 -64
- package/dist/agent-farm/cli.js.map +1 -1
- package/dist/agent-farm/commands/architect.d.ts.map +1 -1
- package/dist/agent-farm/commands/architect.js +0 -2
- package/dist/agent-farm/commands/architect.js.map +1 -1
- package/dist/agent-farm/commands/attach.d.ts +13 -0
- package/dist/agent-farm/commands/attach.d.ts.map +1 -0
- package/dist/agent-farm/commands/attach.js +179 -0
- package/dist/agent-farm/commands/attach.js.map +1 -0
- package/dist/agent-farm/commands/cleanup.d.ts.map +1 -1
- package/dist/agent-farm/commands/cleanup.js +30 -3
- package/dist/agent-farm/commands/cleanup.js.map +1 -1
- package/dist/agent-farm/commands/consult.js +1 -1
- package/dist/agent-farm/commands/consult.js.map +1 -1
- package/dist/agent-farm/commands/index.d.ts +2 -2
- package/dist/agent-farm/commands/index.d.ts.map +1 -1
- package/dist/agent-farm/commands/index.js +2 -2
- package/dist/agent-farm/commands/index.js.map +1 -1
- package/dist/agent-farm/commands/{util.d.ts → shell.d.ts} +5 -5
- package/dist/agent-farm/commands/shell.d.ts.map +1 -0
- package/dist/agent-farm/commands/{util.js → shell.js} +23 -36
- package/dist/agent-farm/commands/shell.js.map +1 -0
- package/dist/agent-farm/commands/spawn.d.ts.map +1 -1
- package/dist/agent-farm/commands/spawn.js +455 -217
- package/dist/agent-farm/commands/spawn.js.map +1 -1
- package/dist/agent-farm/commands/start.d.ts.map +1 -1
- package/dist/agent-farm/commands/start.js +21 -74
- package/dist/agent-farm/commands/start.js.map +1 -1
- package/dist/agent-farm/commands/stop.d.ts.map +1 -1
- package/dist/agent-farm/commands/stop.js +79 -10
- package/dist/agent-farm/commands/stop.js.map +1 -1
- package/dist/agent-farm/commands/tower.d.ts.map +1 -1
- package/dist/agent-farm/commands/tower.js +2 -1
- package/dist/agent-farm/commands/tower.js.map +1 -1
- package/dist/agent-farm/db/index.d.ts.map +1 -1
- package/dist/agent-farm/db/index.js +15 -0
- package/dist/agent-farm/db/index.js.map +1 -1
- package/dist/agent-farm/db/schema.d.ts +1 -1
- package/dist/agent-farm/db/schema.d.ts.map +1 -1
- package/dist/agent-farm/db/schema.js +6 -3
- package/dist/agent-farm/db/schema.js.map +1 -1
- package/dist/agent-farm/db/types.d.ts +3 -0
- package/dist/agent-farm/db/types.d.ts.map +1 -1
- package/dist/agent-farm/db/types.js +3 -0
- package/dist/agent-farm/db/types.js.map +1 -1
- package/dist/agent-farm/hq-connector.d.ts +2 -2
- package/dist/agent-farm/hq-connector.js +2 -2
- package/dist/agent-farm/servers/dashboard-server.js +412 -131
- package/dist/agent-farm/servers/dashboard-server.js.map +1 -1
- package/dist/agent-farm/servers/tower-server.js +353 -16
- package/dist/agent-farm/servers/tower-server.js.map +1 -1
- package/dist/agent-farm/state.d.ts +4 -10
- package/dist/agent-farm/state.d.ts.map +1 -1
- package/dist/agent-farm/state.js +30 -31
- package/dist/agent-farm/state.js.map +1 -1
- package/dist/agent-farm/types.d.ts +48 -0
- package/dist/agent-farm/types.d.ts.map +1 -1
- package/dist/agent-farm/utils/config.d.ts.map +1 -1
- package/dist/agent-farm/utils/config.js +12 -11
- package/dist/agent-farm/utils/config.js.map +1 -1
- package/dist/agent-farm/utils/deps.d.ts.map +1 -1
- package/dist/agent-farm/utils/deps.js +0 -16
- package/dist/agent-farm/utils/deps.js.map +1 -1
- package/dist/agent-farm/utils/notifications.d.ts +30 -0
- package/dist/agent-farm/utils/notifications.d.ts.map +1 -0
- package/dist/agent-farm/utils/notifications.js +121 -0
- package/dist/agent-farm/utils/notifications.js.map +1 -0
- package/dist/agent-farm/utils/server-utils.d.ts +2 -1
- package/dist/agent-farm/utils/server-utils.d.ts.map +1 -1
- package/dist/agent-farm/utils/server-utils.js +11 -1
- package/dist/agent-farm/utils/server-utils.js.map +1 -1
- package/dist/agent-farm/utils/shell.d.ts +9 -22
- package/dist/agent-farm/utils/shell.d.ts.map +1 -1
- package/dist/agent-farm/utils/shell.js +34 -34
- package/dist/agent-farm/utils/shell.js.map +1 -1
- package/dist/agent-farm/utils/terminal-ports.d.ts +1 -1
- package/dist/agent-farm/utils/terminal-ports.js +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +5 -54
- package/dist/cli.js.map +1 -1
- package/dist/commands/adopt.d.ts.map +1 -1
- package/dist/commands/adopt.js +39 -4
- package/dist/commands/adopt.js.map +1 -1
- package/dist/commands/consult/index.d.ts.map +1 -1
- package/dist/commands/consult/index.js +63 -3
- package/dist/commands/consult/index.js.map +1 -1
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +0 -15
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +31 -2
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/porch/build-counter.d.ts +5 -0
- package/dist/commands/porch/build-counter.d.ts.map +1 -0
- package/dist/commands/porch/build-counter.js +5 -0
- package/dist/commands/porch/build-counter.js.map +1 -0
- package/dist/commands/porch/checks.d.ts +16 -29
- package/dist/commands/porch/checks.d.ts.map +1 -1
- package/dist/commands/porch/checks.js +90 -144
- package/dist/commands/porch/checks.js.map +1 -1
- package/dist/commands/porch/claude.d.ts +27 -0
- package/dist/commands/porch/claude.d.ts.map +1 -0
- package/dist/commands/porch/claude.js +107 -0
- package/dist/commands/porch/claude.js.map +1 -0
- package/dist/commands/porch/index.d.ts +21 -43
- package/dist/commands/porch/index.d.ts.map +1 -1
- package/dist/commands/porch/index.js +469 -753
- package/dist/commands/porch/index.js.map +1 -1
- package/dist/commands/porch/plan.d.ts +70 -0
- package/dist/commands/porch/plan.d.ts.map +1 -0
- package/dist/commands/porch/plan.js +190 -0
- package/dist/commands/porch/plan.js.map +1 -0
- package/dist/commands/porch/prompts.d.ts +19 -0
- package/dist/commands/porch/prompts.d.ts.map +1 -0
- package/dist/commands/porch/prompts.js +250 -0
- package/dist/commands/porch/prompts.js.map +1 -0
- package/dist/commands/porch/protocol.d.ts +59 -0
- package/dist/commands/porch/protocol.d.ts.map +1 -0
- package/dist/commands/porch/protocol.js +260 -0
- package/dist/commands/porch/protocol.js.map +1 -0
- package/dist/commands/porch/run.d.ts +40 -0
- package/dist/commands/porch/run.d.ts.map +1 -0
- package/dist/commands/porch/run.js +893 -0
- package/dist/commands/porch/run.js.map +1 -0
- package/dist/commands/porch/state.d.ts +23 -112
- package/dist/commands/porch/state.d.ts.map +1 -1
- package/dist/commands/porch/state.js +81 -685
- package/dist/commands/porch/state.js.map +1 -1
- package/dist/commands/porch/types.d.ts +72 -173
- package/dist/commands/porch/types.d.ts.map +1 -1
- package/dist/commands/porch/types.js +2 -1
- package/dist/commands/porch/types.js.map +1 -1
- package/dist/commands/update.d.ts.map +1 -1
- package/dist/commands/update.js +22 -0
- package/dist/commands/update.js.map +1 -1
- package/dist/lib/scaffold.d.ts +24 -0
- package/dist/lib/scaffold.d.ts.map +1 -1
- package/dist/lib/scaffold.js +78 -0
- package/dist/lib/scaffold.js.map +1 -1
- package/dist/terminal/index.d.ts +8 -0
- package/dist/terminal/index.d.ts.map +1 -0
- package/dist/terminal/index.js +5 -0
- package/dist/terminal/index.js.map +1 -0
- package/dist/terminal/pty-manager.d.ts +60 -0
- package/dist/terminal/pty-manager.d.ts.map +1 -0
- package/dist/terminal/pty-manager.js +334 -0
- package/dist/terminal/pty-manager.js.map +1 -0
- package/dist/terminal/pty-session.d.ts +79 -0
- package/dist/terminal/pty-session.d.ts.map +1 -0
- package/dist/terminal/pty-session.js +215 -0
- package/dist/terminal/pty-session.js.map +1 -0
- package/dist/terminal/ring-buffer.d.ts +27 -0
- package/dist/terminal/ring-buffer.d.ts.map +1 -0
- package/dist/terminal/ring-buffer.js +74 -0
- package/dist/terminal/ring-buffer.js.map +1 -0
- package/dist/terminal/ws-protocol.d.ts +27 -0
- package/dist/terminal/ws-protocol.d.ts.map +1 -0
- package/dist/terminal/ws-protocol.js +44 -0
- package/dist/terminal/ws-protocol.js.map +1 -0
- package/package.json +18 -3
- package/skeleton/DEPENDENCIES.md +3 -29
- package/skeleton/builders.md +1 -1
- package/skeleton/protocol-schema.json +282 -0
- package/skeleton/protocols/bugfix/builder-prompt.md +49 -0
- package/skeleton/protocols/bugfix/protocol.json +14 -2
- package/skeleton/protocols/experiment/builder-prompt.md +47 -0
- package/skeleton/protocols/experiment/protocol.json +101 -0
- package/skeleton/protocols/maintain/builder-prompt.md +41 -0
- package/skeleton/protocols/maintain/prompts/audit.md +111 -0
- package/skeleton/protocols/maintain/prompts/clean.md +91 -0
- package/skeleton/protocols/maintain/prompts/sync.md +113 -0
- package/skeleton/protocols/maintain/prompts/verify.md +110 -0
- package/skeleton/protocols/maintain/protocol.json +141 -0
- package/skeleton/protocols/maintain/protocol.md +13 -7
- package/skeleton/protocols/protocol-schema.json +53 -0
- package/skeleton/protocols/spider/builder-prompt.md +53 -0
- package/skeleton/protocols/spider/prompts/implement.md +208 -0
- package/skeleton/protocols/spider/prompts/plan.md +214 -0
- package/skeleton/protocols/spider/prompts/review.md +217 -0
- package/skeleton/protocols/spider/prompts/specify.md +192 -0
- package/skeleton/protocols/spider/protocol.json +96 -148
- package/skeleton/protocols/spider/protocol.md +26 -16
- package/skeleton/protocols/spider/templates/plan.md +14 -0
- package/skeleton/protocols/tick/builder-prompt.md +51 -0
- package/skeleton/protocols/tick/protocol.json +7 -2
- package/skeleton/resources/commands/agent-farm.md +25 -43
- package/skeleton/resources/commands/overview.md +6 -16
- package/skeleton/resources/workflow-reference.md +2 -2
- package/skeleton/roles/architect.md +152 -315
- package/skeleton/roles/builder.md +109 -218
- package/skeleton/templates/AGENTS.md +1 -1
- package/skeleton/templates/CLAUDE.md +1 -1
- package/skeleton/templates/cheatsheet.md +4 -2
- package/templates/dashboard/index.html +17 -43
- package/templates/dashboard/js/dialogs.js +7 -7
- package/templates/dashboard/js/files.js +2 -2
- package/templates/dashboard/js/main.js +3 -3
- package/templates/dashboard/js/projects.js +3 -3
- package/templates/dashboard/js/tabs.js +1 -1
- package/templates/dashboard/js/utils.js +22 -87
- package/templates/tower.html +474 -17
- package/dist/agent-farm/commands/kickoff.d.ts +0 -19
- package/dist/agent-farm/commands/kickoff.d.ts.map +0 -1
- package/dist/agent-farm/commands/kickoff.js +0 -323
- package/dist/agent-farm/commands/kickoff.js.map +0 -1
- package/dist/agent-farm/commands/rename.d.ts +0 -13
- package/dist/agent-farm/commands/rename.d.ts.map +0 -1
- package/dist/agent-farm/commands/rename.js +0 -33
- package/dist/agent-farm/commands/rename.js.map +0 -1
- package/dist/agent-farm/commands/tutorial.d.ts +0 -10
- package/dist/agent-farm/commands/tutorial.d.ts.map +0 -1
- package/dist/agent-farm/commands/tutorial.js +0 -49
- package/dist/agent-farm/commands/tutorial.js.map +0 -1
- package/dist/agent-farm/commands/util.d.ts.map +0 -1
- package/dist/agent-farm/commands/util.js.map +0 -1
- package/dist/agent-farm/tutorial/index.d.ts +0 -8
- package/dist/agent-farm/tutorial/index.d.ts.map +0 -1
- package/dist/agent-farm/tutorial/index.js +0 -8
- package/dist/agent-farm/tutorial/index.js.map +0 -1
- package/dist/agent-farm/tutorial/prompts.d.ts +0 -57
- package/dist/agent-farm/tutorial/prompts.d.ts.map +0 -1
- package/dist/agent-farm/tutorial/prompts.js +0 -147
- package/dist/agent-farm/tutorial/prompts.js.map +0 -1
- package/dist/agent-farm/tutorial/runner.d.ts +0 -52
- package/dist/agent-farm/tutorial/runner.d.ts.map +0 -1
- package/dist/agent-farm/tutorial/runner.js +0 -204
- package/dist/agent-farm/tutorial/runner.js.map +0 -1
- package/dist/agent-farm/tutorial/state.d.ts +0 -26
- package/dist/agent-farm/tutorial/state.d.ts.map +0 -1
- package/dist/agent-farm/tutorial/state.js +0 -89
- package/dist/agent-farm/tutorial/state.js.map +0 -1
- package/dist/agent-farm/tutorial/steps/first-spec.d.ts +0 -7
- package/dist/agent-farm/tutorial/steps/first-spec.d.ts.map +0 -1
- package/dist/agent-farm/tutorial/steps/first-spec.js +0 -136
- package/dist/agent-farm/tutorial/steps/first-spec.js.map +0 -1
- package/dist/agent-farm/tutorial/steps/implementation.d.ts +0 -7
- package/dist/agent-farm/tutorial/steps/implementation.d.ts.map +0 -1
- package/dist/agent-farm/tutorial/steps/implementation.js +0 -76
- package/dist/agent-farm/tutorial/steps/implementation.js.map +0 -1
- package/dist/agent-farm/tutorial/steps/index.d.ts +0 -10
- package/dist/agent-farm/tutorial/steps/index.d.ts.map +0 -1
- package/dist/agent-farm/tutorial/steps/index.js +0 -10
- package/dist/agent-farm/tutorial/steps/index.js.map +0 -1
- package/dist/agent-farm/tutorial/steps/planning.d.ts +0 -7
- package/dist/agent-farm/tutorial/steps/planning.d.ts.map +0 -1
- package/dist/agent-farm/tutorial/steps/planning.js +0 -143
- package/dist/agent-farm/tutorial/steps/planning.js.map +0 -1
- package/dist/agent-farm/tutorial/steps/review.d.ts +0 -7
- package/dist/agent-farm/tutorial/steps/review.d.ts.map +0 -1
- package/dist/agent-farm/tutorial/steps/review.js +0 -78
- package/dist/agent-farm/tutorial/steps/review.js.map +0 -1
- package/dist/agent-farm/tutorial/steps/setup.d.ts +0 -7
- package/dist/agent-farm/tutorial/steps/setup.d.ts.map +0 -1
- package/dist/agent-farm/tutorial/steps/setup.js +0 -126
- package/dist/agent-farm/tutorial/steps/setup.js.map +0 -1
- package/dist/agent-farm/tutorial/steps/welcome.d.ts +0 -7
- package/dist/agent-farm/tutorial/steps/welcome.d.ts.map +0 -1
- package/dist/agent-farm/tutorial/steps/welcome.js +0 -50
- package/dist/agent-farm/tutorial/steps/welcome.js.map +0 -1
- package/dist/commands/pcheck/cache.d.ts +0 -48
- package/dist/commands/pcheck/cache.d.ts.map +0 -1
- package/dist/commands/pcheck/cache.js +0 -170
- package/dist/commands/pcheck/cache.js.map +0 -1
- package/dist/commands/pcheck/evaluator.d.ts +0 -15
- package/dist/commands/pcheck/evaluator.d.ts.map +0 -1
- package/dist/commands/pcheck/evaluator.js +0 -246
- package/dist/commands/pcheck/evaluator.js.map +0 -1
- package/dist/commands/pcheck/index.d.ts +0 -12
- package/dist/commands/pcheck/index.d.ts.map +0 -1
- package/dist/commands/pcheck/index.js +0 -249
- package/dist/commands/pcheck/index.js.map +0 -1
- package/dist/commands/pcheck/parser.d.ts +0 -39
- package/dist/commands/pcheck/parser.d.ts.map +0 -1
- package/dist/commands/pcheck/parser.js +0 -155
- package/dist/commands/pcheck/parser.js.map +0 -1
- package/dist/commands/pcheck/types.d.ts +0 -82
- package/dist/commands/pcheck/types.d.ts.map +0 -1
- package/dist/commands/pcheck/types.js +0 -5
- package/dist/commands/pcheck/types.js.map +0 -1
- package/dist/commands/porch/consultation.d.ts +0 -56
- package/dist/commands/porch/consultation.d.ts.map +0 -1
- package/dist/commands/porch/consultation.js +0 -330
- package/dist/commands/porch/consultation.js.map +0 -1
- package/dist/commands/porch/notifications.d.ts +0 -99
- package/dist/commands/porch/notifications.d.ts.map +0 -1
- package/dist/commands/porch/notifications.js +0 -223
- package/dist/commands/porch/notifications.js.map +0 -1
- package/dist/commands/porch/plan-parser.d.ts +0 -38
- package/dist/commands/porch/plan-parser.d.ts.map +0 -1
- package/dist/commands/porch/plan-parser.js +0 -166
- package/dist/commands/porch/plan-parser.js.map +0 -1
- package/dist/commands/porch/protocol-loader.d.ts +0 -46
- package/dist/commands/porch/protocol-loader.d.ts.map +0 -1
- package/dist/commands/porch/protocol-loader.js +0 -249
- package/dist/commands/porch/protocol-loader.js.map +0 -1
- package/dist/commands/porch/signal-parser.d.ts +0 -88
- package/dist/commands/porch/signal-parser.d.ts.map +0 -1
- package/dist/commands/porch/signal-parser.js +0 -148
- package/dist/commands/porch/signal-parser.js.map +0 -1
- package/dist/commands/tower.d.ts +0 -16
- package/dist/commands/tower.d.ts.map +0 -1
- package/dist/commands/tower.js +0 -21
- package/dist/commands/tower.js.map +0 -1
- package/skeleton/config.json +0 -7
- package/skeleton/porch/protocols/bugfix.json +0 -85
- package/skeleton/porch/protocols/spider.json +0 -135
- package/skeleton/porch/protocols/tick.json +0 -76
- package/templates/dashboard/css/activity.css +0 -151
- package/templates/dashboard/js/activity.js +0 -112
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Single PTY session: wraps node-pty with ring buffer, disk logging,
|
|
3
|
+
* WebSocket broadcast, and reconnection support.
|
|
4
|
+
*/
|
|
5
|
+
import fs from 'node:fs';
|
|
6
|
+
import path from 'node:path';
|
|
7
|
+
import { EventEmitter } from 'node:events';
|
|
8
|
+
import { RingBuffer } from './ring-buffer.js';
|
|
9
|
+
export class PtySession extends EventEmitter {
|
|
10
|
+
config;
|
|
11
|
+
id;
|
|
12
|
+
label;
|
|
13
|
+
createdAt;
|
|
14
|
+
ringBuffer;
|
|
15
|
+
pty = null;
|
|
16
|
+
cols;
|
|
17
|
+
rows;
|
|
18
|
+
exitCode;
|
|
19
|
+
logFd = null;
|
|
20
|
+
logBytes = 0;
|
|
21
|
+
logPath;
|
|
22
|
+
diskLogEnabled;
|
|
23
|
+
diskLogMaxBytes;
|
|
24
|
+
reconnectTimeoutMs;
|
|
25
|
+
disconnectTimer = null;
|
|
26
|
+
clients = new Set();
|
|
27
|
+
constructor(config) {
|
|
28
|
+
super();
|
|
29
|
+
this.config = config;
|
|
30
|
+
this.id = config.id;
|
|
31
|
+
this.label = config.label;
|
|
32
|
+
this.cols = config.cols;
|
|
33
|
+
this.rows = config.rows;
|
|
34
|
+
this.createdAt = new Date().toISOString();
|
|
35
|
+
this.ringBuffer = new RingBuffer(config.ringBufferLines ?? 1000);
|
|
36
|
+
this.diskLogEnabled = config.diskLogEnabled ?? true;
|
|
37
|
+
this.diskLogMaxBytes = config.diskLogMaxBytes ?? 50 * 1024 * 1024;
|
|
38
|
+
this.reconnectTimeoutMs = config.reconnectTimeoutMs ?? 300_000;
|
|
39
|
+
this.logPath = path.join(config.logDir, `${config.id}.log`);
|
|
40
|
+
}
|
|
41
|
+
/** Spawn the PTY process. Must be called after construction. */
|
|
42
|
+
async spawn() {
|
|
43
|
+
// Dynamic import to avoid hard dependency at module level
|
|
44
|
+
const nodePty = await import('node-pty');
|
|
45
|
+
// Ensure log directory exists
|
|
46
|
+
if (this.diskLogEnabled) {
|
|
47
|
+
fs.mkdirSync(path.dirname(this.logPath), { recursive: true });
|
|
48
|
+
this.logFd = fs.openSync(this.logPath, 'a');
|
|
49
|
+
}
|
|
50
|
+
this.pty = nodePty.spawn(this.config.command, this.config.args, {
|
|
51
|
+
name: 'xterm-256color',
|
|
52
|
+
cols: this.cols,
|
|
53
|
+
rows: this.rows,
|
|
54
|
+
cwd: this.config.cwd,
|
|
55
|
+
env: this.config.env,
|
|
56
|
+
});
|
|
57
|
+
this.pty.onData((data) => {
|
|
58
|
+
this.onPtyData(data);
|
|
59
|
+
});
|
|
60
|
+
this.pty.onExit(({ exitCode }) => {
|
|
61
|
+
this.exitCode = exitCode;
|
|
62
|
+
this.emit('exit', exitCode);
|
|
63
|
+
this.cleanup();
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
onPtyData(data) {
|
|
67
|
+
// Store in ring buffer
|
|
68
|
+
this.ringBuffer.pushData(data);
|
|
69
|
+
// Write to disk log
|
|
70
|
+
if (this.diskLogEnabled && this.logFd !== null) {
|
|
71
|
+
const buf = Buffer.from(data, 'utf-8');
|
|
72
|
+
if (this.logBytes + buf.length <= this.diskLogMaxBytes) {
|
|
73
|
+
fs.writeSync(this.logFd, buf);
|
|
74
|
+
this.logBytes += buf.length;
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
this.rotateDiskLog();
|
|
78
|
+
fs.writeSync(this.logFd, buf);
|
|
79
|
+
this.logBytes = buf.length;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
// Broadcast to all connected WebSocket clients
|
|
83
|
+
for (const client of this.clients) {
|
|
84
|
+
try {
|
|
85
|
+
client.send(data);
|
|
86
|
+
}
|
|
87
|
+
catch {
|
|
88
|
+
this.clients.delete(client);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
this.emit('data', data);
|
|
92
|
+
}
|
|
93
|
+
rotateDiskLog() {
|
|
94
|
+
if (this.logFd !== null) {
|
|
95
|
+
fs.closeSync(this.logFd);
|
|
96
|
+
}
|
|
97
|
+
const rotatedPath = this.logPath + '.1';
|
|
98
|
+
// Remove old rotation if exists
|
|
99
|
+
try {
|
|
100
|
+
fs.unlinkSync(rotatedPath + '.1');
|
|
101
|
+
}
|
|
102
|
+
catch { /* ignore */ }
|
|
103
|
+
try {
|
|
104
|
+
fs.renameSync(rotatedPath, rotatedPath + '.1');
|
|
105
|
+
}
|
|
106
|
+
catch { /* ignore */ }
|
|
107
|
+
try {
|
|
108
|
+
fs.renameSync(this.logPath, rotatedPath);
|
|
109
|
+
}
|
|
110
|
+
catch { /* ignore */ }
|
|
111
|
+
this.logFd = fs.openSync(this.logPath, 'a');
|
|
112
|
+
this.logBytes = 0;
|
|
113
|
+
}
|
|
114
|
+
/** Write user input to the PTY. */
|
|
115
|
+
write(data) {
|
|
116
|
+
if (this.pty && this.status === 'running') {
|
|
117
|
+
this.pty.write(data);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
/** Resize the PTY. */
|
|
121
|
+
resize(cols, rows) {
|
|
122
|
+
this.cols = cols;
|
|
123
|
+
this.rows = rows;
|
|
124
|
+
if (this.pty && this.status === 'running') {
|
|
125
|
+
this.pty.resize(cols, rows);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
/** Kill the PTY process. */
|
|
129
|
+
kill() {
|
|
130
|
+
if (this.pty && this.status === 'running') {
|
|
131
|
+
try {
|
|
132
|
+
// Kill process group to prevent orphans
|
|
133
|
+
process.kill(-this.pty.pid, 'SIGTERM');
|
|
134
|
+
setTimeout(() => {
|
|
135
|
+
try {
|
|
136
|
+
process.kill(-this.pty.pid, 'SIGKILL');
|
|
137
|
+
}
|
|
138
|
+
catch { /* already dead */ }
|
|
139
|
+
}, 5000);
|
|
140
|
+
}
|
|
141
|
+
catch {
|
|
142
|
+
// Process already exited
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
this.cleanup();
|
|
146
|
+
}
|
|
147
|
+
/** Attach a WebSocket client. Returns ring buffer contents for replay. */
|
|
148
|
+
attach(client) {
|
|
149
|
+
this.clients.add(client);
|
|
150
|
+
if (this.disconnectTimer) {
|
|
151
|
+
clearTimeout(this.disconnectTimer);
|
|
152
|
+
this.disconnectTimer = null;
|
|
153
|
+
}
|
|
154
|
+
return this.ringBuffer.getAll();
|
|
155
|
+
}
|
|
156
|
+
/** Attach with resume from a specific sequence number. */
|
|
157
|
+
attachResume(client, sinceSeq) {
|
|
158
|
+
this.clients.add(client);
|
|
159
|
+
if (this.disconnectTimer) {
|
|
160
|
+
clearTimeout(this.disconnectTimer);
|
|
161
|
+
this.disconnectTimer = null;
|
|
162
|
+
}
|
|
163
|
+
return this.ringBuffer.getSince(sinceSeq);
|
|
164
|
+
}
|
|
165
|
+
/** Detach a WebSocket client. Starts disconnect timer if no clients remain. */
|
|
166
|
+
detach(client) {
|
|
167
|
+
this.clients.delete(client);
|
|
168
|
+
if (this.clients.size === 0 && this.status === 'running') {
|
|
169
|
+
this.disconnectTimer = setTimeout(() => {
|
|
170
|
+
this.emit('timeout');
|
|
171
|
+
this.kill();
|
|
172
|
+
}, this.reconnectTimeoutMs);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
get status() {
|
|
176
|
+
return this.exitCode === undefined ? 'running' : 'exited';
|
|
177
|
+
}
|
|
178
|
+
get pid() {
|
|
179
|
+
return this.pty?.pid ?? -1;
|
|
180
|
+
}
|
|
181
|
+
get info() {
|
|
182
|
+
return {
|
|
183
|
+
id: this.id,
|
|
184
|
+
pid: this.pid,
|
|
185
|
+
cols: this.cols,
|
|
186
|
+
rows: this.rows,
|
|
187
|
+
label: this.label,
|
|
188
|
+
status: this.status,
|
|
189
|
+
createdAt: this.createdAt,
|
|
190
|
+
exitCode: this.exitCode,
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
get clientCount() {
|
|
194
|
+
return this.clients.size;
|
|
195
|
+
}
|
|
196
|
+
cleanup() {
|
|
197
|
+
if (this.disconnectTimer) {
|
|
198
|
+
clearTimeout(this.disconnectTimer);
|
|
199
|
+
this.disconnectTimer = null;
|
|
200
|
+
}
|
|
201
|
+
// Release all WebSocket clients
|
|
202
|
+
this.clients.clear();
|
|
203
|
+
// Release ring buffer memory
|
|
204
|
+
this.ringBuffer.clear();
|
|
205
|
+
// Close disk log handle
|
|
206
|
+
if (this.logFd !== null) {
|
|
207
|
+
try {
|
|
208
|
+
fs.closeSync(this.logFd);
|
|
209
|
+
}
|
|
210
|
+
catch { /* ignore */ }
|
|
211
|
+
this.logFd = null;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
//# sourceMappingURL=pty-session.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pty-session.js","sourceRoot":"","sources":["../../src/terminal/pty-session.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fixed-size circular buffer for storing terminal output lines.
|
|
3
|
+
* Used for reconnection replay — stores last N lines in memory.
|
|
4
|
+
*/
|
|
5
|
+
export declare class RingBuffer {
|
|
6
|
+
private readonly capacity;
|
|
7
|
+
private buffer;
|
|
8
|
+
private head;
|
|
9
|
+
private count;
|
|
10
|
+
private seq;
|
|
11
|
+
constructor(capacity?: number);
|
|
12
|
+
/** Push a line into the buffer. Returns the assigned sequence number. */
|
|
13
|
+
push(line: string): number;
|
|
14
|
+
/** Push raw data, splitting on newlines. Returns last sequence number. */
|
|
15
|
+
pushData(data: string): number;
|
|
16
|
+
/** Get all stored lines in order. */
|
|
17
|
+
getAll(): string[];
|
|
18
|
+
/** Get lines starting from a given sequence number (for resume). */
|
|
19
|
+
getSince(sinceSeq: number): string[];
|
|
20
|
+
/** Current sequence number (last written). */
|
|
21
|
+
get currentSeq(): number;
|
|
22
|
+
/** Number of lines currently stored. */
|
|
23
|
+
get size(): number;
|
|
24
|
+
/** Clear the buffer and release memory. */
|
|
25
|
+
clear(): void;
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=ring-buffer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ring-buffer.d.ts","sourceRoot":"","sources":["../../src/terminal/ring-buffer.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,qBAAa,UAAU;IAMT,OAAO,CAAC,QAAQ,CAAC,QAAQ;IALrC,OAAO,CAAC,MAAM,CAAW;IACzB,OAAO,CAAC,IAAI,CAAa;IACzB,OAAO,CAAC,KAAK,CAAa;IAC1B,OAAO,CAAC,GAAG,CAAa;gBAEK,QAAQ,GAAE,MAAa;IAIpD,yEAAyE;IACzE,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAW1B,0EAA0E;IAC1E,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAS9B,qCAAqC;IACrC,MAAM,IAAI,MAAM,EAAE;IAQlB,oEAAoE;IACpE,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE;IAcpC,8CAA8C;IAC9C,IAAI,UAAU,IAAI,MAAM,CAEvB;IAED,wCAAwC;IACxC,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED,2CAA2C;IAC3C,KAAK,IAAI,IAAI;CAMd"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fixed-size circular buffer for storing terminal output lines.
|
|
3
|
+
* Used for reconnection replay — stores last N lines in memory.
|
|
4
|
+
*/
|
|
5
|
+
export class RingBuffer {
|
|
6
|
+
capacity;
|
|
7
|
+
buffer;
|
|
8
|
+
head = 0;
|
|
9
|
+
count = 0;
|
|
10
|
+
seq = 0; // monotonically increasing sequence number
|
|
11
|
+
constructor(capacity = 1000) {
|
|
12
|
+
this.capacity = capacity;
|
|
13
|
+
this.buffer = new Array(capacity);
|
|
14
|
+
}
|
|
15
|
+
/** Push a line into the buffer. Returns the assigned sequence number. */
|
|
16
|
+
push(line) {
|
|
17
|
+
const index = (this.head + this.count) % this.capacity;
|
|
18
|
+
this.buffer[index] = line;
|
|
19
|
+
if (this.count < this.capacity) {
|
|
20
|
+
this.count++;
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
this.head = (this.head + 1) % this.capacity;
|
|
24
|
+
}
|
|
25
|
+
return ++this.seq;
|
|
26
|
+
}
|
|
27
|
+
/** Push raw data, splitting on newlines. Returns last sequence number. */
|
|
28
|
+
pushData(data) {
|
|
29
|
+
const lines = data.split('\n');
|
|
30
|
+
let lastSeq = this.seq;
|
|
31
|
+
for (const line of lines) {
|
|
32
|
+
lastSeq = this.push(line);
|
|
33
|
+
}
|
|
34
|
+
return lastSeq;
|
|
35
|
+
}
|
|
36
|
+
/** Get all stored lines in order. */
|
|
37
|
+
getAll() {
|
|
38
|
+
const result = [];
|
|
39
|
+
for (let i = 0; i < this.count; i++) {
|
|
40
|
+
result.push(this.buffer[(this.head + i) % this.capacity]);
|
|
41
|
+
}
|
|
42
|
+
return result;
|
|
43
|
+
}
|
|
44
|
+
/** Get lines starting from a given sequence number (for resume). */
|
|
45
|
+
getSince(sinceSeq) {
|
|
46
|
+
const linesAvailable = this.count;
|
|
47
|
+
const oldestSeq = this.seq - linesAvailable + 1;
|
|
48
|
+
const startSeq = Math.max(sinceSeq + 1, oldestSeq);
|
|
49
|
+
if (startSeq > this.seq)
|
|
50
|
+
return [];
|
|
51
|
+
const skip = startSeq - oldestSeq;
|
|
52
|
+
const result = [];
|
|
53
|
+
for (let i = skip; i < this.count; i++) {
|
|
54
|
+
result.push(this.buffer[(this.head + i) % this.capacity]);
|
|
55
|
+
}
|
|
56
|
+
return result;
|
|
57
|
+
}
|
|
58
|
+
/** Current sequence number (last written). */
|
|
59
|
+
get currentSeq() {
|
|
60
|
+
return this.seq;
|
|
61
|
+
}
|
|
62
|
+
/** Number of lines currently stored. */
|
|
63
|
+
get size() {
|
|
64
|
+
return this.count;
|
|
65
|
+
}
|
|
66
|
+
/** Clear the buffer and release memory. */
|
|
67
|
+
clear() {
|
|
68
|
+
this.buffer = [];
|
|
69
|
+
this.head = 0;
|
|
70
|
+
this.count = 0;
|
|
71
|
+
// Don't reset seq — it should be monotonic
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=ring-buffer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ring-buffer.js","sourceRoot":"","sources":["../../src/terminal/ring-buffer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WebSocket frame encoding/decoding for terminal communication.
|
|
3
|
+
*
|
|
4
|
+
* Hybrid protocol:
|
|
5
|
+
* - 0x00 prefix: Control frame (remainder is UTF-8 JSON)
|
|
6
|
+
* - 0x01 prefix: Data frame (remainder is raw PTY bytes)
|
|
7
|
+
*/
|
|
8
|
+
export declare const FRAME_CONTROL = 0;
|
|
9
|
+
export declare const FRAME_DATA = 1;
|
|
10
|
+
export interface ControlMessage {
|
|
11
|
+
type: 'resize' | 'ping' | 'pong' | 'pause' | 'resume' | 'error';
|
|
12
|
+
payload: Record<string, unknown>;
|
|
13
|
+
}
|
|
14
|
+
/** Encode a control message into a binary frame. */
|
|
15
|
+
export declare function encodeControl(msg: ControlMessage): Buffer;
|
|
16
|
+
/** Encode raw PTY data into a binary frame. */
|
|
17
|
+
export declare function encodeData(data: Buffer | string): Buffer;
|
|
18
|
+
export type DecodedFrame = {
|
|
19
|
+
type: 'control';
|
|
20
|
+
message: ControlMessage;
|
|
21
|
+
} | {
|
|
22
|
+
type: 'data';
|
|
23
|
+
data: Buffer;
|
|
24
|
+
};
|
|
25
|
+
/** Decode a received WebSocket frame. */
|
|
26
|
+
export declare function decodeFrame(frame: Buffer): DecodedFrame;
|
|
27
|
+
//# sourceMappingURL=ws-protocol.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ws-protocol.d.ts","sourceRoot":"","sources":["../../src/terminal/ws-protocol.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,eAAO,MAAM,aAAa,IAAO,CAAC;AAClC,eAAO,MAAM,UAAU,IAAO,CAAC;AAE/B,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,QAAQ,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,QAAQ,GAAG,OAAO,CAAC;IAChE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC;AAED,oDAAoD;AACpD,wBAAgB,aAAa,CAAC,GAAG,EAAE,cAAc,GAAG,MAAM,CAOzD;AAED,+CAA+C;AAC/C,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAMxD;AAED,MAAM,MAAM,YAAY,GACpB;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,OAAO,EAAE,cAAc,CAAA;CAAE,GAC5C;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAEnC,yCAAyC;AACzC,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,YAAY,CAmBvD"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WebSocket frame encoding/decoding for terminal communication.
|
|
3
|
+
*
|
|
4
|
+
* Hybrid protocol:
|
|
5
|
+
* - 0x00 prefix: Control frame (remainder is UTF-8 JSON)
|
|
6
|
+
* - 0x01 prefix: Data frame (remainder is raw PTY bytes)
|
|
7
|
+
*/
|
|
8
|
+
export const FRAME_CONTROL = 0x00;
|
|
9
|
+
export const FRAME_DATA = 0x01;
|
|
10
|
+
/** Encode a control message into a binary frame. */
|
|
11
|
+
export function encodeControl(msg) {
|
|
12
|
+
const json = JSON.stringify(msg);
|
|
13
|
+
const jsonBuf = Buffer.from(json, 'utf-8');
|
|
14
|
+
const frame = Buffer.allocUnsafe(1 + jsonBuf.length);
|
|
15
|
+
frame[0] = FRAME_CONTROL;
|
|
16
|
+
jsonBuf.copy(frame, 1);
|
|
17
|
+
return frame;
|
|
18
|
+
}
|
|
19
|
+
/** Encode raw PTY data into a binary frame. */
|
|
20
|
+
export function encodeData(data) {
|
|
21
|
+
const dataBuf = typeof data === 'string' ? Buffer.from(data, 'utf-8') : data;
|
|
22
|
+
const frame = Buffer.allocUnsafe(1 + dataBuf.length);
|
|
23
|
+
frame[0] = FRAME_DATA;
|
|
24
|
+
dataBuf.copy(frame, 1);
|
|
25
|
+
return frame;
|
|
26
|
+
}
|
|
27
|
+
/** Decode a received WebSocket frame. */
|
|
28
|
+
export function decodeFrame(frame) {
|
|
29
|
+
if (frame.length === 0) {
|
|
30
|
+
throw new Error('Empty frame');
|
|
31
|
+
}
|
|
32
|
+
const prefix = frame[0];
|
|
33
|
+
const payload = frame.subarray(1);
|
|
34
|
+
if (prefix === FRAME_CONTROL) {
|
|
35
|
+
const json = payload.toString('utf-8');
|
|
36
|
+
const message = JSON.parse(json);
|
|
37
|
+
return { type: 'control', message };
|
|
38
|
+
}
|
|
39
|
+
if (prefix === FRAME_DATA) {
|
|
40
|
+
return { type: 'data', data: payload };
|
|
41
|
+
}
|
|
42
|
+
throw new Error(`Unknown frame prefix: 0x${prefix.toString(16)}`);
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=ws-protocol.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ws-protocol.js","sourceRoot":"","sources":["../../src/terminal/ws-protocol.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,CAAC,MAAM,aAAa,GAAG,IAAI,CAAC;AAClC,MAAM,CAAC,MAAM,UAAU,GAAG,IAAI,CAAC;AAO/B,oDAAoD;AACpD,MAAM,UAAU,aAAa,CAAC,GAAmB;IAC/C,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;IACjC,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAC3C,MAAM,KAAK,GAAG,MAAM,CAAC,WAAW,CAAC,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACrD,KAAK,CAAC,CAAC,CAAC,GAAG,aAAa,CAAC;IACzB,OAAO,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;IACvB,OAAO,KAAK,CAAC;AACf,CAAC;AAED,+CAA+C;AAC/C,MAAM,UAAU,UAAU,CAAC,IAAqB;IAC9C,MAAM,OAAO,GAAG,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAC7E,MAAM,KAAK,GAAG,MAAM,CAAC,WAAW,CAAC,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACrD,KAAK,CAAC,CAAC,CAAC,GAAG,UAAU,CAAC;IACtB,OAAO,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;IACvB,OAAO,KAAK,CAAC;AACf,CAAC;AAMD,yCAAyC;AACzC,MAAM,UAAU,WAAW,CAAC,KAAa;IACvC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,MAAM,IAAI,KAAK,CAAC,aAAa,CAAC,CAAC;IACjC,CAAC;IAED,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;IACxB,MAAM,OAAO,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;IAElC,IAAI,MAAM,KAAK,aAAa,EAAE,CAAC;QAC7B,MAAM,IAAI,GAAG,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;QACvC,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAmB,CAAC;QACnD,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC;IACtC,CAAC;IAED,IAAI,MAAM,KAAK,UAAU,EAAE,CAAC;QAC1B,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;IACzC,CAAC;IAED,MAAM,IAAI,KAAK,CAAC,2BAA2B,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;AACpE,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cluesmith/codev",
|
|
3
|
-
"version": "2.0.0-rc.
|
|
3
|
+
"version": "2.0.0-rc.33",
|
|
4
4
|
"description": "Codev CLI - AI-assisted software development framework",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -14,32 +14,47 @@
|
|
|
14
14
|
"dist",
|
|
15
15
|
"bin",
|
|
16
16
|
"skeleton",
|
|
17
|
-
"templates"
|
|
17
|
+
"templates",
|
|
18
|
+
"dashboard/dist"
|
|
18
19
|
],
|
|
19
20
|
"scripts": {
|
|
20
|
-
"
|
|
21
|
+
"clean": "rm -rf dist",
|
|
22
|
+
"build": "npm run clean && tsc && npm run build:dashboard && npm run copy-skeleton",
|
|
23
|
+
"build:dashboard": "cd dashboard && npm install && npm run build",
|
|
24
|
+
"dev:dashboard": "cd dashboard && npm run dev",
|
|
21
25
|
"copy-skeleton": "rm -rf skeleton && cp -r ../../codev-skeleton skeleton",
|
|
22
26
|
"dev": "tsx src/cli.ts",
|
|
23
27
|
"start": "node dist/cli.js",
|
|
24
28
|
"test": "vitest",
|
|
29
|
+
"test:e2e": "vitest run --config vitest.e2e.config.ts",
|
|
30
|
+
"test:e2e:watch": "vitest --config vitest.e2e.config.ts",
|
|
31
|
+
"postinstall": "node -e \"try{require('fs').chmodSync(require('path').join(require.resolve('node-pty'),'..','..','prebuilds',process.platform+'-'+process.arch,'spawn-helper'),0o755)}catch{}\"",
|
|
25
32
|
"prepublishOnly": "npm run build"
|
|
26
33
|
},
|
|
27
34
|
"dependencies": {
|
|
35
|
+
"@anthropic-ai/claude-agent-sdk": "^0.2.25",
|
|
28
36
|
"@google/genai": "^1.0.0",
|
|
29
37
|
"better-sqlite3": "^12.5.0",
|
|
30
38
|
"chalk": "^5.3.0",
|
|
31
39
|
"commander": "^12.1.0",
|
|
32
40
|
"glob": "^11.0.0",
|
|
33
41
|
"http-proxy": "^1.18.1",
|
|
42
|
+
"js-yaml": "^4.1.0",
|
|
43
|
+
"node-pty": "^1.1.0",
|
|
34
44
|
"open": "^10.1.0",
|
|
45
|
+
"qrcode-terminal": "^0.12.0",
|
|
35
46
|
"tree-kill": "^1.2.2",
|
|
36
47
|
"ws": "^8.18.0"
|
|
37
48
|
},
|
|
38
49
|
"devDependencies": {
|
|
50
|
+
"@playwright/test": "^1.58.0",
|
|
39
51
|
"@types/better-sqlite3": "^7.6.13",
|
|
40
52
|
"@types/http-proxy": "^1.17.17",
|
|
53
|
+
"@types/js-yaml": "^4.0.9",
|
|
41
54
|
"@types/node": "^22.10.1",
|
|
55
|
+
"@types/qrcode-terminal": "^0.12.2",
|
|
42
56
|
"@types/ws": "^8.18.1",
|
|
57
|
+
"playwright": "^1.58.0",
|
|
43
58
|
"tsx": "^4.19.2",
|
|
44
59
|
"typescript": "^5.7.2",
|
|
45
60
|
"vitest": "^4.0.15"
|
package/skeleton/DEPENDENCIES.md
CHANGED
|
@@ -57,29 +57,6 @@ sudo apt install tmux
|
|
|
57
57
|
tmux -V # Should show tmux 3.x or higher
|
|
58
58
|
```
|
|
59
59
|
|
|
60
|
-
### ttyd
|
|
61
|
-
|
|
62
|
-
| Requirement | Value |
|
|
63
|
-
|-------------|-------|
|
|
64
|
-
| Minimum Version | 1.7.0 |
|
|
65
|
-
| Purpose | Web-based terminal for dashboard access |
|
|
66
|
-
|
|
67
|
-
**Installation:**
|
|
68
|
-
|
|
69
|
-
```bash
|
|
70
|
-
# macOS
|
|
71
|
-
brew install ttyd
|
|
72
|
-
|
|
73
|
-
# Ubuntu/Debian (build from source)
|
|
74
|
-
sudo apt install build-essential cmake git libjson-c-dev libwebsockets-dev
|
|
75
|
-
git clone https://github.com/tsl0922/ttyd.git
|
|
76
|
-
cd ttyd && mkdir build && cd build
|
|
77
|
-
cmake .. && make && sudo make install
|
|
78
|
-
|
|
79
|
-
# Verify
|
|
80
|
-
ttyd --version # Should show 1.7.x or higher
|
|
81
|
-
```
|
|
82
|
-
|
|
83
60
|
### git
|
|
84
61
|
|
|
85
62
|
| Requirement | Value |
|
|
@@ -193,7 +170,6 @@ codex --version
|
|
|
193
170
|
|------------|-----------------|-----------|
|
|
194
171
|
| Node.js | 18.0.0 | Yes |
|
|
195
172
|
| tmux | 3.0 | Yes |
|
|
196
|
-
| ttyd | 1.7.0 | Yes |
|
|
197
173
|
| git | 2.5.0 | Yes |
|
|
198
174
|
| gh | latest | Yes |
|
|
199
175
|
| Claude Code | latest | At least one AI CLI |
|
|
@@ -210,7 +186,7 @@ All dependencies are available via Homebrew:
|
|
|
210
186
|
|
|
211
187
|
```bash
|
|
212
188
|
# Install all core dependencies at once
|
|
213
|
-
brew install node tmux
|
|
189
|
+
brew install node tmux gh
|
|
214
190
|
|
|
215
191
|
# Git is included with Xcode command line tools
|
|
216
192
|
xcode-select --install
|
|
@@ -218,15 +194,13 @@ xcode-select --install
|
|
|
218
194
|
|
|
219
195
|
### Ubuntu/Debian
|
|
220
196
|
|
|
221
|
-
Most dependencies are available via apt
|
|
197
|
+
Most dependencies are available via apt:
|
|
222
198
|
|
|
223
199
|
```bash
|
|
224
200
|
# Core dependencies
|
|
225
201
|
sudo apt install nodejs npm tmux git
|
|
226
202
|
|
|
227
203
|
# gh requires adding GitHub's apt repository (see above)
|
|
228
|
-
|
|
229
|
-
# ttyd must be built from source (see above)
|
|
230
204
|
```
|
|
231
205
|
|
|
232
206
|
### Windows
|
|
@@ -267,7 +241,7 @@ sudo apt update
|
|
|
267
241
|
sudo apt install tmux
|
|
268
242
|
```
|
|
269
243
|
|
|
270
|
-
###
|
|
244
|
+
### Terminal connection issues
|
|
271
245
|
|
|
272
246
|
Ensure no firewall is blocking the ports (default: 4200-4299):
|
|
273
247
|
|
package/skeleton/builders.md
CHANGED
|
@@ -4,7 +4,7 @@ Track active builder agents here. Update manually or via `architect status`.
|
|
|
4
4
|
|
|
5
5
|
## Status Values
|
|
6
6
|
|
|
7
|
-
- **spawning**: Worktree being created,
|
|
7
|
+
- **spawning**: Worktree being created, terminal starting
|
|
8
8
|
- **implementing**: Builder is working
|
|
9
9
|
- **blocked**: Builder waiting for architect input
|
|
10
10
|
- **pr-ready**: Builder has created a PR
|