@nonbot/cli 0.9.12 → 0.9.13

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.
@@ -12,7 +12,7 @@ import { groupBySession, launchCoordinatedSet, setIsIsolated, } from '../lib/cho
12
12
  import { IsolatedSessionTracker, reconcileAndCleanup as defaultReconcileAndCleanup, resolveBaseBranch as defaultResolveBaseBranch, } from '../lib/choir/isolated-session.js';
13
13
  import { applyPaneTitle, applyPaneState } from '../lib/pane-title.js';
14
14
  import { installService, uninstallService } from '../lib/service.js';
15
- import { probeTmuxAttached, postDaemonStopAck, requestRemoteDaemonStop, stopDaemonLocally, writePidFile, removePidFile, } from '../lib/daemon-lifecycle.js';
15
+ import { probeTmuxAttached, postDaemonStopAck, requestRemoteDaemonStop, stopDaemonLocally, attachDaemonSession, writePidFile, removePidFile, } from '../lib/daemon-lifecycle.js';
16
16
  import { detectTmuxSession, inTmuxSession, nonbotTmuxOptOut, resolveTerminal, } from '../lib/terminal.js';
17
17
  import { VERSION } from '../version.js';
18
18
  import { errorBlock, statusRow, daemonOpener, daemonCloser, activationCard, runSummary, formatElapsed, liveFooter, needsYouBanner, resumedLine, buildPaneBorderFormat, buildTmuxStatusLeft, buildTmuxStatusRight, WORDMARK_WIDTH, c, } from '../lib/output.js';
@@ -182,6 +182,15 @@ export async function runDaemonCommand(args = [], options = {}, deps = {}) {
182
182
  spawnImpl: deps.spawnSync,
183
183
  });
184
184
  }
185
+ if (args[0] === 'attach') {
186
+ const sessionFlag = args.indexOf('--session');
187
+ const sessionName = sessionFlag >= 0 ? args[sessionFlag + 1] : undefined;
188
+ return attachDaemonSession({
189
+ log: rawLog, errLog,
190
+ spawnImpl: deps.spawnSync,
191
+ ...(sessionName ? { sessionName } : {}),
192
+ });
193
+ }
185
194
  if (args.includes('--install')) {
186
195
  const install = deps.installService ?? installService;
187
196
  const res = await install();
package/dist/index.js CHANGED
@@ -21,7 +21,7 @@ const COMMANDS = [
21
21
  },
22
22
  {
23
23
  name: 'daemon',
24
- description: 'Long-running listener — polls /api/cli/activations/pending every 2s. `nonbot daemon stop` stops it (local; --machine <id> / --all go remote).',
24
+ description: 'Long-running listener — polls /api/cli/activations/pending every 2s. `nonbot daemon stop` stops it (local; --machine <id> / --all go remote); `nonbot daemon attach` reattaches a lost tmux window.',
25
25
  run: (args) => runDaemonCommand(args),
26
26
  },
27
27
  {
@@ -106,6 +106,35 @@ export async function requestRemoteDaemonStop(opts) {
106
106
  return 1;
107
107
  }
108
108
  }
109
+ export function attachDaemonSession(deps) {
110
+ const spawn = deps.spawnImpl ?? nodeSpawnSync;
111
+ const sessionName = deps.sessionName ?? 'nonbot';
112
+ try {
113
+ const probe = spawn('tmux', ['has-session', '-t', sessionName], {
114
+ encoding: 'utf-8', timeout: 2000, windowsHide: true,
115
+ });
116
+ if (probe.status !== 0) {
117
+ deps.errLog(`✗ no tmux session '${sessionName}' to attach to.\n Start the daemon first: nonbot daemon\n`);
118
+ return 1;
119
+ }
120
+ }
121
+ catch {
122
+ deps.errLog('✗ tmux not found — install it (brew install tmux) or run the daemon without tmux.\n');
123
+ return 1;
124
+ }
125
+ deps.log(`↳ attaching to tmux session '${sessionName}' — press Ctrl-B then D to detach again.\n`);
126
+ try {
127
+ const res = spawn('tmux', ['attach', '-t', sessionName], {
128
+ ...{ stdio: 'inherit' },
129
+ windowsHide: true,
130
+ });
131
+ return res.status === 0 ? 0 : 1;
132
+ }
133
+ catch {
134
+ deps.errLog(`✗ could not attach to '${sessionName}'.\n`);
135
+ return 1;
136
+ }
137
+ }
109
138
  export async function stopDaemonLocally(deps) {
110
139
  const kill = deps.kill ?? ((pid, sig) => process.kill(pid, sig));
111
140
  const sleep = deps.sleep ?? ((ms) => new Promise((r) => setTimeout(r, ms)));
package/dist/version.js CHANGED
@@ -1 +1 @@
1
- export const VERSION = '0.9.12';
1
+ export const VERSION = '0.9.13';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nonbot/cli",
3
- "version": "0.9.12",
3
+ "version": "0.9.13",
4
4
  "type": "module",
5
5
  "description": "The local host for non.bot ▶ Run — opens a terminal on your machine and starts the work in your linked repo.",
6
6
  "license": "UNLICENSED",