@cluesmith/codev 2.0.0-rc.69 → 2.0.0-rc.70

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.
Files changed (139) hide show
  1. package/dashboard/dist/assets/{index-CG7nUttd.js → index-CDAINZKT.js} +21 -21
  2. package/dashboard/dist/assets/{index-CG7nUttd.js.map → index-CDAINZKT.js.map} +1 -1
  3. package/dashboard/dist/index.html +1 -1
  4. package/dist/agent-farm/cli.js +2 -2
  5. package/dist/agent-farm/cli.js.map +1 -1
  6. package/dist/agent-farm/commands/architect.d.ts +3 -3
  7. package/dist/agent-farm/commands/architect.d.ts.map +1 -1
  8. package/dist/agent-farm/commands/architect.js +20 -142
  9. package/dist/agent-farm/commands/architect.js.map +1 -1
  10. package/dist/agent-farm/commands/attach.d.ts.map +1 -1
  11. package/dist/agent-farm/commands/attach.js +13 -50
  12. package/dist/agent-farm/commands/attach.js.map +1 -1
  13. package/dist/agent-farm/commands/cleanup.d.ts.map +1 -1
  14. package/dist/agent-farm/commands/cleanup.js +1 -11
  15. package/dist/agent-farm/commands/cleanup.js.map +1 -1
  16. package/dist/agent-farm/commands/send.d.ts +1 -1
  17. package/dist/agent-farm/commands/send.d.ts.map +1 -1
  18. package/dist/agent-farm/commands/send.js +35 -92
  19. package/dist/agent-farm/commands/send.js.map +1 -1
  20. package/dist/agent-farm/commands/spawn.d.ts.map +1 -1
  21. package/dist/agent-farm/commands/spawn.js +26 -58
  22. package/dist/agent-farm/commands/spawn.js.map +1 -1
  23. package/dist/agent-farm/commands/status.js +1 -1
  24. package/dist/agent-farm/commands/status.js.map +1 -1
  25. package/dist/agent-farm/commands/stop.d.ts.map +1 -1
  26. package/dist/agent-farm/commands/stop.js +9 -44
  27. package/dist/agent-farm/commands/stop.js.map +1 -1
  28. package/dist/agent-farm/commands/tower-cloud.d.ts.map +1 -1
  29. package/dist/agent-farm/commands/tower-cloud.js +18 -1
  30. package/dist/agent-farm/commands/tower-cloud.js.map +1 -1
  31. package/dist/agent-farm/db/index.d.ts.map +1 -1
  32. package/dist/agent-farm/db/index.js +61 -0
  33. package/dist/agent-farm/db/index.js.map +1 -1
  34. package/dist/agent-farm/db/migrate.d.ts.map +1 -1
  35. package/dist/agent-farm/db/migrate.js +6 -9
  36. package/dist/agent-farm/db/migrate.js.map +1 -1
  37. package/dist/agent-farm/db/schema.d.ts +2 -2
  38. package/dist/agent-farm/db/schema.d.ts.map +1 -1
  39. package/dist/agent-farm/db/schema.js +3 -4
  40. package/dist/agent-farm/db/schema.js.map +1 -1
  41. package/dist/agent-farm/db/types.d.ts +0 -3
  42. package/dist/agent-farm/db/types.d.ts.map +1 -1
  43. package/dist/agent-farm/db/types.js +0 -3
  44. package/dist/agent-farm/db/types.js.map +1 -1
  45. package/dist/agent-farm/lib/tower-client.d.ts +4 -0
  46. package/dist/agent-farm/lib/tower-client.d.ts.map +1 -1
  47. package/dist/agent-farm/lib/tower-client.js +10 -0
  48. package/dist/agent-farm/lib/tower-client.js.map +1 -1
  49. package/dist/agent-farm/lib/tunnel-client.d.ts.map +1 -1
  50. package/dist/agent-farm/lib/tunnel-client.js +6 -13
  51. package/dist/agent-farm/lib/tunnel-client.js.map +1 -1
  52. package/dist/agent-farm/servers/tower-server.js +482 -494
  53. package/dist/agent-farm/servers/tower-server.js.map +1 -1
  54. package/dist/agent-farm/state.d.ts.map +1 -1
  55. package/dist/agent-farm/state.js +6 -10
  56. package/dist/agent-farm/state.js.map +1 -1
  57. package/dist/agent-farm/types.d.ts +0 -7
  58. package/dist/agent-farm/types.d.ts.map +1 -1
  59. package/dist/agent-farm/utils/deps.d.ts.map +1 -1
  60. package/dist/agent-farm/utils/deps.js +0 -16
  61. package/dist/agent-farm/utils/deps.js.map +1 -1
  62. package/dist/agent-farm/utils/gate-watcher.js +4 -4
  63. package/dist/agent-farm/utils/gate-watcher.js.map +1 -1
  64. package/dist/agent-farm/utils/session.d.ts +6 -6
  65. package/dist/agent-farm/utils/session.d.ts.map +1 -1
  66. package/dist/agent-farm/utils/session.js +4 -4
  67. package/dist/agent-farm/utils/session.js.map +1 -1
  68. package/dist/agent-farm/utils/shell.d.ts +4 -4
  69. package/dist/agent-farm/utils/shell.js +4 -4
  70. package/dist/cli.d.ts.map +1 -1
  71. package/dist/cli.js +2 -0
  72. package/dist/cli.js.map +1 -1
  73. package/dist/commands/consult/index.d.ts +1 -0
  74. package/dist/commands/consult/index.d.ts.map +1 -1
  75. package/dist/commands/consult/index.js +19 -5
  76. package/dist/commands/consult/index.js.map +1 -1
  77. package/dist/commands/doctor.d.ts.map +1 -1
  78. package/dist/commands/doctor.js +0 -12
  79. package/dist/commands/doctor.js.map +1 -1
  80. package/dist/commands/porch/next.d.ts.map +1 -1
  81. package/dist/commands/porch/next.js +90 -8
  82. package/dist/commands/porch/next.js.map +1 -1
  83. package/dist/commands/porch/prompts.d.ts.map +1 -1
  84. package/dist/commands/porch/prompts.js +26 -4
  85. package/dist/commands/porch/prompts.js.map +1 -1
  86. package/dist/commands/porch/verdict.d.ts +0 -8
  87. package/dist/commands/porch/verdict.d.ts.map +1 -1
  88. package/dist/commands/porch/verdict.js +0 -13
  89. package/dist/commands/porch/verdict.js.map +1 -1
  90. package/dist/terminal/pty-manager.d.ts +9 -0
  91. package/dist/terminal/pty-manager.d.ts.map +1 -1
  92. package/dist/terminal/pty-manager.js +45 -2
  93. package/dist/terminal/pty-manager.js.map +1 -1
  94. package/dist/terminal/pty-session.d.ts +27 -4
  95. package/dist/terminal/pty-session.d.ts.map +1 -1
  96. package/dist/terminal/pty-session.js +112 -4
  97. package/dist/terminal/pty-session.js.map +1 -1
  98. package/dist/terminal/ring-buffer.d.ts +10 -3
  99. package/dist/terminal/ring-buffer.d.ts.map +1 -1
  100. package/dist/terminal/ring-buffer.js +25 -5
  101. package/dist/terminal/ring-buffer.js.map +1 -1
  102. package/dist/terminal/session-manager.d.ts +115 -0
  103. package/dist/terminal/session-manager.d.ts.map +1 -0
  104. package/dist/terminal/session-manager.js +582 -0
  105. package/dist/terminal/session-manager.js.map +1 -0
  106. package/dist/terminal/shepherd-client.d.ts +58 -0
  107. package/dist/terminal/shepherd-client.d.ts.map +1 -0
  108. package/dist/terminal/shepherd-client.js +212 -0
  109. package/dist/terminal/shepherd-client.js.map +1 -0
  110. package/dist/terminal/shepherd-main.d.ts +19 -0
  111. package/dist/terminal/shepherd-main.d.ts.map +1 -0
  112. package/dist/terminal/shepherd-main.js +153 -0
  113. package/dist/terminal/shepherd-main.js.map +1 -0
  114. package/dist/terminal/shepherd-process.d.ts +75 -0
  115. package/dist/terminal/shepherd-process.d.ts.map +1 -0
  116. package/dist/terminal/shepherd-process.js +279 -0
  117. package/dist/terminal/shepherd-process.js.map +1 -0
  118. package/dist/terminal/shepherd-protocol.d.ts +115 -0
  119. package/dist/terminal/shepherd-protocol.d.ts.map +1 -0
  120. package/dist/terminal/shepherd-protocol.js +214 -0
  121. package/dist/terminal/shepherd-protocol.js.map +1 -0
  122. package/dist/terminal/shepherd-replay-buffer.d.ts +38 -0
  123. package/dist/terminal/shepherd-replay-buffer.d.ts.map +1 -0
  124. package/dist/terminal/shepherd-replay-buffer.js +94 -0
  125. package/dist/terminal/shepherd-replay-buffer.js.map +1 -0
  126. package/package.json +1 -1
  127. package/skeleton/.claude/skills/codev/SKILL.md +1 -1
  128. package/skeleton/DEPENDENCIES.md +2 -34
  129. package/skeleton/consult-types/impl-review.md +9 -9
  130. package/skeleton/consult-types/integration-review.md +1 -1
  131. package/skeleton/consult-types/plan-review.md +1 -1
  132. package/skeleton/consult-types/pr-ready.md +1 -1
  133. package/skeleton/consult-types/spec-review.md +1 -1
  134. package/skeleton/protocols/bugfix/prompts/pr.md +23 -4
  135. package/skeleton/protocols/maintain/protocol.md +3 -3
  136. package/skeleton/resources/commands/agent-farm.md +2 -3
  137. package/skeleton/resources/commands/codev.md +0 -2
  138. package/skeleton/roles/architect.md +1 -1
  139. package/skeleton/roles/consultant.md +6 -6
@@ -0,0 +1,212 @@
1
+ /**
2
+ * ShepherdClient: Tower's connection to a single shepherd process.
3
+ *
4
+ * Connects to a shepherd via Unix socket, performs HELLO/WELCOME handshake,
5
+ * and provides a typed API for sending/receiving frames. Emits events for
6
+ * data, exit, replay, and errors.
7
+ *
8
+ * Usage:
9
+ * const client = new ShepherdClient('/path/to/shepherd.sock');
10
+ * const welcome = await client.connect();
11
+ * client.on('data', (buf) => { ... });
12
+ * client.write('ls\n');
13
+ * client.disconnect();
14
+ */
15
+ import net from 'node:net';
16
+ import { EventEmitter } from 'node:events';
17
+ import { FrameType, PROTOCOL_VERSION, createFrameParser, encodeHello, encodeData, encodeResize, encodeSignal, encodeSpawn, encodePing, encodePong, parseJsonPayload, isKnownFrameType, } from './shepherd-protocol.js';
18
+ export class ShepherdClient extends EventEmitter {
19
+ socketPath;
20
+ socket = null;
21
+ _connected = false;
22
+ replayData = null;
23
+ constructor(socketPath) {
24
+ super();
25
+ this.socketPath = socketPath;
26
+ }
27
+ /**
28
+ * Emit an 'error' event only if listeners are attached.
29
+ * Prevents Node.js from throwing on unhandled 'error' events,
30
+ * which would crash Tower.
31
+ */
32
+ safeEmitError(err) {
33
+ if (this.listenerCount('error') > 0) {
34
+ this.emit('error', err);
35
+ }
36
+ }
37
+ get connected() {
38
+ return this._connected;
39
+ }
40
+ /**
41
+ * Connect to the shepherd, perform HELLO/WELCOME handshake.
42
+ * Resolves with the WelcomeMessage on success.
43
+ * Rejects on connection error or handshake failure.
44
+ */
45
+ connect() {
46
+ return new Promise((resolve, reject) => {
47
+ if (this._connected) {
48
+ reject(new Error('Already connected'));
49
+ return;
50
+ }
51
+ const socket = net.createConnection(this.socketPath);
52
+ this.socket = socket;
53
+ let handshakeResolved = false;
54
+ const parser = createFrameParser();
55
+ const onError = (err) => {
56
+ if (!handshakeResolved) {
57
+ handshakeResolved = true;
58
+ reject(err);
59
+ }
60
+ else {
61
+ this.safeEmitError(err);
62
+ }
63
+ this.cleanup();
64
+ };
65
+ socket.on('error', onError);
66
+ parser.on('error', (err) => {
67
+ this.safeEmitError(err);
68
+ this.cleanup();
69
+ });
70
+ socket.on('connect', () => {
71
+ socket.pipe(parser);
72
+ // Send HELLO to initiate handshake
73
+ socket.write(encodeHello({ version: PROTOCOL_VERSION }));
74
+ });
75
+ socket.on('close', () => {
76
+ const wasConnected = this._connected;
77
+ this.cleanup();
78
+ if (wasConnected) {
79
+ this.emit('close');
80
+ }
81
+ if (!handshakeResolved) {
82
+ handshakeResolved = true;
83
+ reject(new Error('Connection closed during handshake'));
84
+ }
85
+ });
86
+ // Buffer frames that arrive before WELCOME (e.g., DATA from PTY output
87
+ // that the shepherd forwards immediately on connection)
88
+ const preWelcomeBuffer = [];
89
+ parser.on('data', (frame) => {
90
+ if (!handshakeResolved) {
91
+ if (frame.type === FrameType.WELCOME) {
92
+ try {
93
+ const welcome = parseJsonPayload(frame.payload);
94
+ // Version mismatch handling per spec:
95
+ // - shepherd version < Tower version → disconnect (stale shepherd)
96
+ // - shepherd version > Tower version → warn but continue
97
+ const shepherdVersion = welcome.version ?? 0;
98
+ if (shepherdVersion < PROTOCOL_VERSION) {
99
+ handshakeResolved = true;
100
+ reject(new Error(`Shepherd protocol version ${shepherdVersion} is older than Tower version ${PROTOCOL_VERSION}`));
101
+ this.cleanup();
102
+ return;
103
+ }
104
+ if (shepherdVersion > PROTOCOL_VERSION) {
105
+ // Newer shepherd — log warning but continue (forward compatible)
106
+ this.emit('version-warning', shepherdVersion, PROTOCOL_VERSION);
107
+ }
108
+ handshakeResolved = true;
109
+ this._connected = true;
110
+ // Replay any buffered frames received before WELCOME
111
+ for (const buffered of preWelcomeBuffer) {
112
+ this.handleFrame(buffered);
113
+ }
114
+ resolve(welcome);
115
+ }
116
+ catch {
117
+ handshakeResolved = true;
118
+ reject(new Error('Invalid WELCOME payload'));
119
+ this.cleanup();
120
+ }
121
+ }
122
+ else {
123
+ // Buffer non-WELCOME frames for replay after handshake
124
+ preWelcomeBuffer.push(frame);
125
+ }
126
+ }
127
+ else {
128
+ // Post-handshake: dispatch frames
129
+ this.handleFrame(frame);
130
+ }
131
+ });
132
+ });
133
+ }
134
+ handleFrame(frame) {
135
+ if (!isKnownFrameType(frame.type)) {
136
+ // Unknown types silently ignored (forward compatibility)
137
+ return;
138
+ }
139
+ switch (frame.type) {
140
+ case FrameType.DATA:
141
+ this.emit('data', frame.payload);
142
+ break;
143
+ case FrameType.EXIT: {
144
+ try {
145
+ const exit = parseJsonPayload(frame.payload);
146
+ this.emit('exit', exit);
147
+ }
148
+ catch {
149
+ this.safeEmitError(new Error('Invalid EXIT payload'));
150
+ }
151
+ break;
152
+ }
153
+ case FrameType.REPLAY:
154
+ this.replayData = frame.payload;
155
+ this.emit('replay', frame.payload);
156
+ break;
157
+ case FrameType.PING:
158
+ this.socket?.write(encodePong());
159
+ break;
160
+ case FrameType.PONG:
161
+ this.emit('pong');
162
+ break;
163
+ case FrameType.WELCOME:
164
+ // Duplicate WELCOME after handshake — ignore
165
+ break;
166
+ default:
167
+ // Other frame types (HELLO, RESIZE, SIGNAL, SPAWN) are shepherd-bound,
168
+ // not expected from shepherd → Tower
169
+ break;
170
+ }
171
+ }
172
+ disconnect() {
173
+ this.cleanup();
174
+ }
175
+ cleanup() {
176
+ this._connected = false;
177
+ if (this.socket && !this.socket.destroyed) {
178
+ this.socket.destroy();
179
+ }
180
+ this.socket = null;
181
+ }
182
+ write(data) {
183
+ if (!this._connected || !this.socket)
184
+ return;
185
+ this.socket.write(encodeData(data));
186
+ }
187
+ resize(cols, rows) {
188
+ if (!this._connected || !this.socket)
189
+ return;
190
+ this.socket.write(encodeResize({ cols, rows }));
191
+ }
192
+ signal(sig) {
193
+ if (!this._connected || !this.socket)
194
+ return;
195
+ this.socket.write(encodeSignal({ signal: sig }));
196
+ }
197
+ spawn(msg) {
198
+ if (!this._connected || !this.socket)
199
+ return;
200
+ this.socket.write(encodeSpawn(msg));
201
+ }
202
+ ping() {
203
+ if (!this._connected || !this.socket)
204
+ return;
205
+ this.socket.write(encodePing());
206
+ }
207
+ /** Get the last received replay data, or null if none. */
208
+ getReplayData() {
209
+ return this.replayData;
210
+ }
211
+ }
212
+ //# sourceMappingURL=shepherd-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shepherd-client.js","sourceRoot":"","sources":["../../src/terminal/shepherd-client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Shepherd main: standalone entry point spawned by Tower as a detached process.
4
+ *
5
+ * Usage:
6
+ * node shepherd-main.js <json-config>
7
+ *
8
+ * Where json-config is a JSON string with:
9
+ * { command, args, cwd, env, cols, rows, socketPath }
10
+ *
11
+ * On startup:
12
+ * 1. Creates socket directory with 0700 permissions
13
+ * 2. Spawns PTY with requested command
14
+ * 3. Writes { pid, startTime } to stdout as JSON, then closes stdout
15
+ * 4. Listens on Unix socket at socketPath
16
+ * 5. Handles SIGTERM gracefully
17
+ */
18
+ export {};
19
+ //# sourceMappingURL=shepherd-main.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shepherd-main.d.ts","sourceRoot":"","sources":["../../src/terminal/shepherd-main.ts"],"names":[],"mappings":";AAEA;;;;;;;;;;;;;;;GAeG"}
@@ -0,0 +1,153 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Shepherd main: standalone entry point spawned by Tower as a detached process.
4
+ *
5
+ * Usage:
6
+ * node shepherd-main.js <json-config>
7
+ *
8
+ * Where json-config is a JSON string with:
9
+ * { command, args, cwd, env, cols, rows, socketPath }
10
+ *
11
+ * On startup:
12
+ * 1. Creates socket directory with 0700 permissions
13
+ * 2. Spawns PTY with requested command
14
+ * 3. Writes { pid, startTime } to stdout as JSON, then closes stdout
15
+ * 4. Listens on Unix socket at socketPath
16
+ * 5. Handles SIGTERM gracefully
17
+ */
18
+ import fs from 'node:fs';
19
+ import path from 'node:path';
20
+ import { createRequire } from 'node:module';
21
+ import { ShepherdProcess } from './shepherd-process.js';
22
+ // createRequire enables importing native/CJS modules (like node-pty) from ESM.
23
+ // The package uses "type": "module", so bare `require()` is not available.
24
+ const require = createRequire(import.meta.url);
25
+ function createRealPty() {
26
+ let ptyModule = null;
27
+ let ptyInstance = null;
28
+ let dataCallback = null;
29
+ let exitCallback = null;
30
+ return {
31
+ spawn(command, args, options) {
32
+ // Load node-pty at spawn time via createRequire (defined at module level).
33
+ // node-pty is a native CJS module; createRequire handles ESM→CJS interop.
34
+ ptyModule = require('node-pty');
35
+ ptyInstance = ptyModule.spawn(command, args, {
36
+ name: options.name ?? 'xterm-256color',
37
+ cols: options.cols,
38
+ rows: options.rows,
39
+ cwd: options.cwd,
40
+ env: options.env,
41
+ });
42
+ if (dataCallback) {
43
+ ptyInstance.onData(dataCallback);
44
+ }
45
+ if (exitCallback) {
46
+ ptyInstance.onExit(exitCallback);
47
+ }
48
+ },
49
+ write(data) {
50
+ ptyInstance?.write(data);
51
+ },
52
+ resize(cols, rows) {
53
+ ptyInstance?.resize(cols, rows);
54
+ },
55
+ kill(signal) {
56
+ if (ptyInstance) {
57
+ try {
58
+ process.kill(ptyInstance.pid, signal ?? 15);
59
+ }
60
+ catch {
61
+ // Process already dead
62
+ }
63
+ }
64
+ },
65
+ onData(callback) {
66
+ dataCallback = callback;
67
+ if (ptyInstance) {
68
+ ptyInstance.onData(callback);
69
+ }
70
+ },
71
+ onExit(callback) {
72
+ exitCallback = callback;
73
+ if (ptyInstance) {
74
+ ptyInstance.onExit(callback);
75
+ }
76
+ },
77
+ get pid() {
78
+ return ptyInstance?.pid ?? -1;
79
+ },
80
+ };
81
+ }
82
+ async function main() {
83
+ const configJson = process.argv[2];
84
+ if (!configJson) {
85
+ process.stderr.write('Usage: shepherd-main.js <json-config>\n');
86
+ process.exit(1);
87
+ }
88
+ let config;
89
+ try {
90
+ config = JSON.parse(configJson);
91
+ }
92
+ catch {
93
+ process.stderr.write('Invalid JSON config\n');
94
+ process.exit(1);
95
+ }
96
+ // Ensure socket directory exists with 0700 permissions
97
+ const socketDir = path.dirname(config.socketPath);
98
+ fs.mkdirSync(socketDir, { recursive: true, mode: 0o700 });
99
+ // Remove stale socket file if it exists
100
+ try {
101
+ const stat = fs.lstatSync(config.socketPath);
102
+ if (stat.isSocket()) {
103
+ fs.unlinkSync(config.socketPath);
104
+ }
105
+ }
106
+ catch {
107
+ // File doesn't exist — fine
108
+ }
109
+ const shepherd = new ShepherdProcess(createRealPty, config.socketPath, config.replayBufferLines ?? 10_000);
110
+ // Start the shepherd (spawns PTY and listens on socket)
111
+ await shepherd.start(config.command, config.args, config.cwd, config.env, config.cols, config.rows);
112
+ // Write PID and start time to stdout, then close stdout
113
+ const info = JSON.stringify({
114
+ pid: process.pid,
115
+ startTime: shepherd.getStartTime(),
116
+ });
117
+ process.stdout.write(info, () => {
118
+ // Close stdout after write completes (Tower reads this, then we detach)
119
+ try {
120
+ fs.closeSync(1);
121
+ }
122
+ catch {
123
+ // Already closed or not available
124
+ }
125
+ });
126
+ // Handle SIGTERM: graceful shutdown
127
+ process.on('SIGTERM', () => {
128
+ shepherd.shutdown();
129
+ // Clean up socket file
130
+ try {
131
+ fs.unlinkSync(config.socketPath);
132
+ }
133
+ catch {
134
+ // Already gone
135
+ }
136
+ process.exit(0);
137
+ });
138
+ // When the child process exits and no connection is active, exit the shepherd
139
+ shepherd.on('exit', () => {
140
+ // Don't exit immediately — Tower might send a SPAWN frame to restart.
141
+ // The shepherd stays alive as long as the socket server is running.
142
+ // If Tower never reconnects, the shepherd will be cleaned up by stale
143
+ // socket cleanup on next Tower startup.
144
+ });
145
+ shepherd.on('error', (err) => {
146
+ process.stderr.write(`Shepherd error: ${err.message}\n`);
147
+ });
148
+ }
149
+ main().catch((err) => {
150
+ process.stderr.write(`Shepherd fatal: ${err.message}\n`);
151
+ process.exit(1);
152
+ });
153
+ //# sourceMappingURL=shepherd-main.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shepherd-main.js","sourceRoot":"","sources":["../../src/terminal/shepherd-main.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,75 @@
1
+ /**
2
+ * ShepherdProcess: the testable core logic of the shepherd daemon.
3
+ *
4
+ * Owns a single PTY via the IShepherdPty interface (injected for testability).
5
+ * Listens on a Unix socket for a single Tower connection. Handles the binary
6
+ * wire protocol: HELLO/WELCOME handshake, DATA forwarding, RESIZE, SIGNAL,
7
+ * SPAWN, PING/PONG, and EXIT lifecycle.
8
+ *
9
+ * The shepherd accepts only one Tower connection at a time. A new connection
10
+ * replaces the old one (handles rapid Tower restarts cleanly).
11
+ */
12
+ import net from 'node:net';
13
+ import { EventEmitter } from 'node:events';
14
+ export interface PtyOptions {
15
+ name?: string;
16
+ cols: number;
17
+ rows: number;
18
+ cwd: string;
19
+ env: Record<string, string>;
20
+ }
21
+ export interface IShepherdPty {
22
+ spawn(command: string, args: string[], options: PtyOptions): void;
23
+ write(data: string): void;
24
+ resize(cols: number, rows: number): void;
25
+ kill(signal?: number): void;
26
+ onData(callback: (data: string) => void): void;
27
+ onExit(callback: (exitInfo: {
28
+ exitCode: number;
29
+ signal?: number;
30
+ }) => void): void;
31
+ pid: number;
32
+ }
33
+ export declare class ShepherdProcess extends EventEmitter {
34
+ private readonly ptyFactory;
35
+ private readonly socketPath;
36
+ private pty;
37
+ private server;
38
+ private currentConnection;
39
+ private replayBuffer;
40
+ private cols;
41
+ private rows;
42
+ private startTime;
43
+ private exited;
44
+ constructor(ptyFactory: () => IShepherdPty, socketPath: string, replayBufferLines?: number);
45
+ /**
46
+ * Start the shepherd: spawn the PTY and begin listening on the Unix socket.
47
+ */
48
+ start(command: string, args: string[], cwd: string, env: Record<string, string>, cols: number, rows: number): Promise<void>;
49
+ private spawnPty;
50
+ private listen;
51
+ /**
52
+ * Handle an incoming Tower connection. Only one connection is active at a
53
+ * time — a new connection closes the previous one.
54
+ */
55
+ handleConnection(socket: net.Socket): void;
56
+ private handleFrame;
57
+ private handleHello;
58
+ private handleData;
59
+ private handleResize;
60
+ private handleSignal;
61
+ private handleSpawn;
62
+ /** Get the current replay buffer data. */
63
+ getReplayData(): Buffer;
64
+ /** Get the process start time (epoch ms). */
65
+ getStartTime(): number;
66
+ /** Get the current PTY PID. */
67
+ getPid(): number;
68
+ /** Whether the child process has exited. */
69
+ get hasExited(): boolean;
70
+ /**
71
+ * Graceful shutdown: kill child process, close socket server, clean up.
72
+ */
73
+ shutdown(): void;
74
+ }
75
+ //# sourceMappingURL=shepherd-process.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shepherd-process.d.ts","sourceRoot":"","sources":["../../src/terminal/shepherd-process.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,OAAO,GAAG,MAAM,UAAU,CAAC;AAC3B,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAwB3C,MAAM,WAAW,UAAU;IACzB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC7B;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,UAAU,GAAG,IAAI,CAAC;IAClE,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACzC,IAAI,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,MAAM,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI,CAAC;IAC/C,MAAM,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,GAAG,IAAI,CAAC;IAClF,GAAG,EAAE,MAAM,CAAC;CACb;AAID,qBAAa,eAAgB,SAAQ,YAAY;IAW7C,OAAO,CAAC,QAAQ,CAAC,UAAU;IAC3B,OAAO,CAAC,QAAQ,CAAC,UAAU;IAX7B,OAAO,CAAC,GAAG,CAA6B;IACxC,OAAO,CAAC,MAAM,CAA2B;IACzC,OAAO,CAAC,iBAAiB,CAA2B;IACpD,OAAO,CAAC,YAAY,CAAuB;IAC3C,OAAO,CAAC,IAAI,CAAM;IAClB,OAAO,CAAC,IAAI,CAAM;IAClB,OAAO,CAAC,SAAS,CAAsB;IACvC,OAAO,CAAC,MAAM,CAAS;gBAGJ,UAAU,EAAE,MAAM,YAAY,EAC9B,UAAU,EAAE,MAAM,EACnC,iBAAiB,GAAE,MAAe;IAMpC;;OAEG;IACG,KAAK,CACT,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EAAE,EACd,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC3B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,IAAI,CAAC;IAShB,OAAO,CAAC,QAAQ;IAmDhB,OAAO,CAAC,MAAM;IAwBd;;;OAGG;IACH,gBAAgB,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,GAAG,IAAI;IAiC1C,OAAO,CAAC,WAAW;IAkCnB,OAAO,CAAC,WAAW;IA2BnB,OAAO,CAAC,UAAU;IAMlB,OAAO,CAAC,YAAY;IAcpB,OAAO,CAAC,YAAY;IAgBpB,OAAO,CAAC,WAAW;IAqBnB,0CAA0C;IAC1C,aAAa,IAAI,MAAM;IAIvB,6CAA6C;IAC7C,YAAY,IAAI,MAAM;IAItB,+BAA+B;IAC/B,MAAM,IAAI,MAAM;IAIhB,4CAA4C;IAC5C,IAAI,SAAS,IAAI,OAAO,CAEvB;IAED;;OAEG;IACH,QAAQ,IAAI,IAAI;CAiBjB"}