agentp 0.9.0 → 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/bin/ocmux CHANGED
@@ -2,11 +2,11 @@
2
2
 
3
3
  const fs = require('fs');
4
4
  const path = require('path');
5
- const crypto = require('crypto');
6
5
  const readline = require('readline');
7
- const { spawnSync, execSync } = require('child_process');
6
+ const { spawnSync } = require('child_process');
8
7
  const os = require('os');
9
8
  const {
9
+ SESSION,
10
10
  readState,
11
11
  statefileFor,
12
12
  tuiPaneId,
@@ -15,6 +15,13 @@ const {
15
15
  activeWindowIndex,
16
16
  paneCount,
17
17
  listServers,
18
+ ensureSession,
19
+ pinWindowName,
20
+ sleep,
21
+ hashDir,
22
+ logfileFor,
23
+ URL_RE,
24
+ resurrectServer,
18
25
  } = require('../lib/ocmux');
19
26
 
20
27
  // ---------------------------------------------------------------------------
@@ -23,10 +30,8 @@ const {
23
30
 
24
31
  const { version } = require('../package.json');
25
32
 
26
- const SESSION = 'Opencode';
27
33
  const SCRIPT = path.basename(process.argv[1] || 'ocmux');
28
34
  const HOME = os.homedir();
29
- const URL_RE = /opencode server listening on (http:\/\/[^\s]*)/;
30
35
 
31
36
  // ---------------------------------------------------------------------------
32
37
  // Helpers
@@ -41,18 +46,6 @@ function tmux(args) {
41
46
  return result;
42
47
  }
43
48
 
44
- function sleep(seconds) {
45
- execSync(`sleep ${seconds}`, { stdio: 'ignore' });
46
- }
47
-
48
- function hashDir(dir) {
49
- return crypto.createHash('md5').update(dir).digest('hex').slice(0, 12);
50
- }
51
-
52
- function logfileFor(dir) {
53
- return `/tmp/opencode-serve-${hashDir(dir)}.log`;
54
- }
55
-
56
49
  function findParentStatefile(startDir) {
57
50
  let dir = path.resolve(startDir);
58
51
  while (true) {
@@ -150,20 +143,7 @@ function ensureTuiZoomed(windowIndex) {
150
143
  if (paneId) tmux(['resize-pane', '-Z', '-t', paneId]);
151
144
  }
152
145
 
153
- function pinWindowName(windowIndex) {
154
- tmux(['set-window-option', '-t', `${SESSION}:${windowIndex}`, 'automatic-rename', 'off']);
155
- }
156
146
 
157
- function ensureSession() {
158
- const r = tmux(['has-session', '-t', SESSION]);
159
- if (r.status !== 0) {
160
- const rc = tmux(['new-session', '-d', '-s', SESSION]);
161
- if (rc.status !== 0) {
162
- console.error('Error: failed to create tmux session');
163
- process.exit(1);
164
- }
165
- }
166
- }
167
147
 
168
148
  function outputUrl(url, dir, longMode) {
169
149
  if (longMode) {
@@ -185,17 +165,21 @@ function printHelp() {
185
165
  console.error('that session is used.');
186
166
  console.error('');
187
167
  console.error('Subcommands:');
188
- console.error(' serve Create a server in <directory> (default: $PWD) and attach a TUI.');
189
- console.error(' Aliased as "new" for backwards compatibility.');
190
- console.error(' Errors if one already exists there.');
191
- console.error(' Warns if a parent directory already has a server.');
192
- console.error(' --git Use the nearest parent with a .git entry (file or dir).');
193
- console.error(' --GIT Use the nearest parent with a .git directory only.');
194
- console.error(' Refuses to create above an existing .ocmux.json found while searching.');
195
- console.error( ' --print-logs Pass --print-logs to opencode serve (prints server logs to stderr).');
196
- console.error(' kill Kill the server found upward from <directory>.');
197
- console.error(' Removes its tmux window and state file.');
198
- console.error(' list List all running servers with their directories and URLs.');
168
+ console.error(' serve Create a server in <directory> (default: $PWD) and attach a TUI.');
169
+ console.error(' Aliased as "new" for backwards compatibility.');
170
+ console.error(' Errors if one already exists there.');
171
+ console.error(' Warns if a parent directory already has a server.');
172
+ console.error(' --git Use the nearest parent with a .git entry (file or dir).');
173
+ console.error(' --GIT Use the nearest parent with a .git directory only.');
174
+ console.error(' Refuses to create above an existing .ocmux.json found while searching.');
175
+ console.error(' --print-logs Pass --print-logs to opencode serve (prints server logs to stderr).');
176
+ console.error(' kill Kill the server found upward from <directory>.');
177
+ console.error(' Removes its tmux window and state file.');
178
+ console.error(' resurrect Recover a dead server: kills the old window, removes the state file,');
179
+ console.error(' then creates a fresh server + TUI in the same directory.');
180
+ console.error(' Works even if no tmux window exists (stale state file).');
181
+ console.error(' --print-logs Pass --print-logs to the new opencode serve.');
182
+ console.error(' list List all running servers with their directories and URLs.');
199
183
  console.error('');
200
184
  console.error(' -- Treat the next argument as a directory even if it matches');
201
185
  console.error(' a subcommand name (e.g. "ocmux -- kill").');
@@ -207,6 +191,7 @@ function printHelp() {
207
191
  console.error(' -h Show this help');
208
192
  console.error('');
209
193
  console.error('See also: agentp -- pipe prompts into OpenCode from stdin');
194
+ console.error(' tgagentp -- Telegram bridge for OpenCode (tgagentp --help)');
210
195
  process.exit(0);
211
196
  }
212
197
 
@@ -428,6 +413,30 @@ function cmdKill(statefile) {
428
413
  console.error('Done.');
429
414
  }
430
415
 
416
+ // ---------------------------------------------------------------------------
417
+ // Subcommand: resurrect — kill dead server and create a fresh one
418
+ // ---------------------------------------------------------------------------
419
+
420
+ function cmdResurrect(targetDir, longMode, printLogs) {
421
+ const sf = findParentStatefile(targetDir);
422
+ if (!sf) {
423
+ console.error(`Error: no .ocmux.json found in ${targetDir} or any of its parents.`);
424
+ console.error("Run 'ocmux serve' to create a new server.");
425
+ process.exit(1);
426
+ }
427
+
428
+ const serverDir = path.dirname(sf);
429
+ console.error(`Resurrecting server for ${serverDir}...`);
430
+
431
+ try {
432
+ const { url } = resurrectServer(serverDir, printLogs);
433
+ outputUrl(url, serverDir, longMode);
434
+ } catch (err) {
435
+ console.error(`Error: ${err.message}`);
436
+ process.exit(1);
437
+ }
438
+ }
439
+
431
440
  // ---------------------------------------------------------------------------
432
441
  // Argument parsing
433
442
  // ---------------------------------------------------------------------------
@@ -489,7 +498,7 @@ function main() {
489
498
  process.exit(1);
490
499
  }
491
500
  targetDir = resolveDir(arg);
492
- } else if (arg === 'serve' || arg === 'new' || arg === 'kill' || arg === 'list') {
501
+ } else if (arg === 'serve' || arg === 'new' || arg === 'kill' || arg === 'list' || arg === 'resurrect') {
493
502
  if (subcommand) {
494
503
  console.error(`Error: multiple subcommands specified: '${subcommand}' and '${arg}'`);
495
504
  process.exit(1);
@@ -537,6 +546,12 @@ function main() {
537
546
  process.exit(1);
538
547
  }
539
548
  cmdKill(sf);
549
+ } else if (subcommand === 'resurrect') {
550
+ if (gitMode) {
551
+ console.error("Error: '--git' and '--GIT' are only valid with 'serve'.");
552
+ process.exit(1);
553
+ }
554
+ cmdResurrect(targetDir, longMode, printLogs);
540
555
  } else if (subcommand === 'serve' || subcommand === 'new') {
541
556
  if (gitMode) {
542
557
  const flagLabel = gitMode === 'root' ? '--GIT' : '--git';