@nonbot/cli 0.9.2 → 0.9.3

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.
@@ -4,6 +4,7 @@ import * as activations from '../lib/activations.js';
4
4
  import { fireActivation, makeHeadlessSpawner, } from '../lib/activations.js';
5
5
  import { checkCompletions } from '../lib/completion.js';
6
6
  import { deliverAnsweredPrompts } from '../lib/run-prompt.js';
7
+ import { loadOrCreateMachineId, resolveMachineName } from '../lib/machine.js';
7
8
  import { emitRunStage as defaultEmitRunStage, startRunHeartbeat as defaultStartRunHeartbeat, RUN_STAGE, } from '../lib/choir/run-progress.js';
8
9
  import { groupBySession, launchCoordinatedSet, } from '../lib/choir/coordinated-set.js';
9
10
  import { applyPaneTitle } from '../lib/pane-title.js';
@@ -177,6 +178,8 @@ export async function runDaemonCommand(args = [], options = {}, deps = {}) {
177
178
  }
178
179
  const detectTmux = deps.detectTmuxSession ?? detectTmuxSession;
179
180
  const tmuxSessionName = detectTmux();
181
+ const machineId = deps.machineId ?? loadOrCreateMachineId();
182
+ const machineName = resolveMachineName();
180
183
  if (tmuxSessionName) {
181
184
  applyNonbotTmuxConfig({ spawnSync: deps.spawnSync });
182
185
  }
@@ -304,6 +307,8 @@ export async function runDaemonCommand(args = [], options = {}, deps = {}) {
304
307
  'X-CLI-Version': VERSION,
305
308
  'X-Terminal-Kind': terminalKind,
306
309
  'X-Terminal-Launchable': terminalLaunchable ? 'true' : 'false',
310
+ 'X-Machine-Id': machineId,
311
+ 'X-Machine-Name': machineName,
307
312
  };
308
313
  if (tmuxSessionName)
309
314
  headers['X-Tmux-Session'] = tmuxSessionName;
@@ -465,6 +470,7 @@ export async function runDaemonCommand(args = [], options = {}, deps = {}) {
465
470
  baseUrl: auth.baseUrl,
466
471
  pat: auth.pat,
467
472
  injected: injectedPrompts,
473
+ machineId,
468
474
  fetchImpl,
469
475
  spawnImpl: deps.spawnSync,
470
476
  log,
@@ -0,0 +1,51 @@
1
+ import { homedir, hostname } from 'node:os';
2
+ import { randomUUID } from 'node:crypto';
3
+ import * as nodeFs from 'node:fs';
4
+ import * as path from 'node:path';
5
+ const NAME_MAX = 64;
6
+ function configDir() {
7
+ const override = process.env.NONBOT_CONFIG_DIR;
8
+ if (override && override.length > 0)
9
+ return override;
10
+ return path.join(homedir(), '.config', 'nonbot');
11
+ }
12
+ export function machineFilePath(dir = configDir()) {
13
+ return path.join(dir, 'machine.json');
14
+ }
15
+ export function loadOrCreateMachineId(deps = {}) {
16
+ const fs = deps.fs ?? nodeFs;
17
+ const uuid = deps.uuid ?? randomUUID;
18
+ const dir = deps.dir ?? configDir();
19
+ const file = path.join(dir, 'machine.json');
20
+ try {
21
+ if (fs.existsSync(file)) {
22
+ const raw = JSON.parse(fs.readFileSync(file, 'utf-8'));
23
+ if (raw && typeof raw.machineId === 'string' && raw.machineId.length > 0) {
24
+ return raw.machineId;
25
+ }
26
+ }
27
+ }
28
+ catch {
29
+ }
30
+ const machineId = uuid();
31
+ try {
32
+ fs.mkdirSync(dir, { recursive: true, mode: 0o700 });
33
+ fs.writeFileSync(file, JSON.stringify({ machineId, createdAt: Date.now() }), { mode: 0o600 });
34
+ }
35
+ catch {
36
+ }
37
+ return machineId;
38
+ }
39
+ export function resolveMachineName(env = process.env) {
40
+ const override = env.NONBOT_MACHINE_NAME;
41
+ if (override && override.trim().length > 0)
42
+ return override.trim().slice(0, NAME_MAX);
43
+ try {
44
+ const h = hostname();
45
+ if (h && h.length > 0)
46
+ return h.slice(0, NAME_MAX);
47
+ }
48
+ catch {
49
+ }
50
+ return 'unknown';
51
+ }
@@ -99,13 +99,14 @@ export async function reportPrompt(args) {
99
99
  export async function pollAnsweredPrompts(args) {
100
100
  const fetchImpl = args.fetchImpl ?? fetch;
101
101
  try {
102
- const res = await fetchImpl(`${args.baseUrl}/api/cli/run-prompts/answered`, {
103
- headers: {
104
- Authorization: `Bearer ${args.pat}`,
105
- 'X-Requested-With': 'ConradPM-Native',
106
- 'X-CLI-Version': VERSION,
107
- },
108
- });
102
+ const headers = {
103
+ Authorization: `Bearer ${args.pat}`,
104
+ 'X-Requested-With': 'ConradPM-Native',
105
+ 'X-CLI-Version': VERSION,
106
+ };
107
+ if (args.machineId)
108
+ headers['X-Machine-Id'] = args.machineId;
109
+ const res = await fetchImpl(`${args.baseUrl}/api/cli/run-prompts/answered`, { headers });
109
110
  if (!res.ok)
110
111
  return [];
111
112
  const data = (await res.json());
@@ -178,6 +179,7 @@ export async function deliverAnsweredPrompts(opts) {
178
179
  const answered = await pollAnsweredPrompts({
179
180
  baseUrl: opts.baseUrl,
180
181
  pat: opts.pat,
182
+ machineId: opts.machineId,
181
183
  fetchImpl: opts.fetchImpl,
182
184
  });
183
185
  if (answered.length === 0)
package/dist/version.js CHANGED
@@ -1 +1 @@
1
- export const VERSION = '0.9.2';
1
+ export const VERSION = '0.9.3';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nonbot/cli",
3
- "version": "0.9.2",
3
+ "version": "0.9.3",
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",