@nonbot/cli 0.9.1 → 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.
- package/dist/commands/daemon.js +17 -13
- package/dist/lib/machine.js +51 -0
- package/dist/lib/run-prompt.js +18 -11
- package/dist/version.js +1 -1
- package/package.json +1 -1
package/dist/commands/daemon.js
CHANGED
|
@@ -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;
|
|
@@ -460,19 +465,18 @@ export async function runDaemonCommand(args = [], options = {}, deps = {}) {
|
|
|
460
465
|
emitSummary();
|
|
461
466
|
}
|
|
462
467
|
}
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
}
|
|
468
|
+
try {
|
|
469
|
+
await deliverAnsweredPrompts({
|
|
470
|
+
baseUrl: auth.baseUrl,
|
|
471
|
+
pat: auth.pat,
|
|
472
|
+
injected: injectedPrompts,
|
|
473
|
+
machineId,
|
|
474
|
+
fetchImpl,
|
|
475
|
+
spawnImpl: deps.spawnSync,
|
|
476
|
+
log,
|
|
477
|
+
});
|
|
478
|
+
}
|
|
479
|
+
catch {
|
|
476
480
|
}
|
|
477
481
|
if (trackedPanes.size > 0) {
|
|
478
482
|
const reported = await checkCompletions({
|
|
@@ -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
|
+
}
|
package/dist/lib/run-prompt.js
CHANGED
|
@@ -4,6 +4,9 @@ import { VERSION } from '../version.js';
|
|
|
4
4
|
const QUESTION_MAX = 200;
|
|
5
5
|
const LABEL_MAX = 80;
|
|
6
6
|
const OPTIONS_MAX = 8;
|
|
7
|
+
const PANE_ID_RE = /^%\d+$/;
|
|
8
|
+
const ANSWERED_MAX = 16;
|
|
9
|
+
const ANSWER_TEXT_MAX = 4096;
|
|
7
10
|
const MENU_LINE_RE = /^\s*[>❯▸▶*•]?\s*(\d{1,2})[.)]\s+(\S.*)$/;
|
|
8
11
|
const GLYPH_RE = /[│┃|╭╮╯╰─━┄┈┌┐└┘├┤>❯▸▶*•]/g;
|
|
9
12
|
export function parsePromptMenu(paneText, fallbackMessage = '') {
|
|
@@ -96,20 +99,21 @@ export async function reportPrompt(args) {
|
|
|
96
99
|
export async function pollAnsweredPrompts(args) {
|
|
97
100
|
const fetchImpl = args.fetchImpl ?? fetch;
|
|
98
101
|
try {
|
|
99
|
-
const
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
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 });
|
|
106
110
|
if (!res.ok)
|
|
107
111
|
return [];
|
|
108
112
|
const data = (await res.json());
|
|
109
113
|
if (!data || !Array.isArray(data.prompts))
|
|
110
114
|
return [];
|
|
111
115
|
const out = [];
|
|
112
|
-
for (const r of data.prompts) {
|
|
116
|
+
for (const r of data.prompts.slice(0, ANSWERED_MAX)) {
|
|
113
117
|
if (!r || typeof r.promptId !== 'string' || typeof r.activationId !== 'string')
|
|
114
118
|
continue;
|
|
115
119
|
out.push({
|
|
@@ -117,7 +121,7 @@ export async function pollAnsweredPrompts(args) {
|
|
|
117
121
|
activationId: r.activationId,
|
|
118
122
|
paneId: typeof r.paneId === 'string' && r.paneId.length > 0 ? r.paneId : null,
|
|
119
123
|
answerIndex: typeof r.answerIndex === 'number' ? r.answerIndex : null,
|
|
120
|
-
answerText: typeof r.answerText === 'string' ? r.answerText : null,
|
|
124
|
+
answerText: typeof r.answerText === 'string' ? r.answerText.slice(0, ANSWER_TEXT_MAX) : null,
|
|
121
125
|
answeredAt: typeof r.answeredAt === 'number' ? r.answeredAt : undefined,
|
|
122
126
|
});
|
|
123
127
|
}
|
|
@@ -147,13 +151,15 @@ export async function confirmDelivered(args) {
|
|
|
147
151
|
}
|
|
148
152
|
}
|
|
149
153
|
export function injectAnswer(paneId, answerIndex, answerText, spawnImpl = nodeSpawnSync) {
|
|
150
|
-
|
|
154
|
+
if (!PANE_ID_RE.test(paneId))
|
|
155
|
+
return false;
|
|
156
|
+
const keys = answerIndex !== null && Number.isFinite(answerIndex) && answerIndex >= 0
|
|
151
157
|
? String(answerIndex)
|
|
152
158
|
: answerText ?? '';
|
|
153
159
|
if (keys.length === 0)
|
|
154
160
|
return false;
|
|
155
161
|
try {
|
|
156
|
-
spawnImpl('tmux', ['send-keys', '-l', '-t', paneId, keys], {
|
|
162
|
+
spawnImpl('tmux', ['send-keys', '-l', '-t', paneId, '--', keys], {
|
|
157
163
|
encoding: 'utf-8',
|
|
158
164
|
timeout: 2000,
|
|
159
165
|
windowsHide: true,
|
|
@@ -173,6 +179,7 @@ export async function deliverAnsweredPrompts(opts) {
|
|
|
173
179
|
const answered = await pollAnsweredPrompts({
|
|
174
180
|
baseUrl: opts.baseUrl,
|
|
175
181
|
pat: opts.pat,
|
|
182
|
+
machineId: opts.machineId,
|
|
176
183
|
fetchImpl: opts.fetchImpl,
|
|
177
184
|
});
|
|
178
185
|
if (answered.length === 0)
|
package/dist/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const VERSION = '0.9.
|
|
1
|
+
export const VERSION = '0.9.3';
|
package/package.json
CHANGED