@on-par/factory-cli 0.0.0-stage → 0.9.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/LICENSE +21 -0
- package/README.md +23 -2
- package/dist/cli/admission.d.ts +17 -0
- package/dist/cli/admission.d.ts.map +1 -0
- package/dist/cli/admission.js +37 -0
- package/dist/cli/admission.js.map +1 -0
- package/dist/cli/branch-prefix.d.ts +8 -0
- package/dist/cli/branch-prefix.d.ts.map +1 -0
- package/dist/cli/branch-prefix.js +16 -0
- package/dist/cli/branch-prefix.js.map +1 -0
- package/dist/cli/classifier-backtest.d.ts +50 -0
- package/dist/cli/classifier-backtest.d.ts.map +1 -0
- package/dist/cli/classifier-backtest.js +112 -0
- package/dist/cli/classifier-backtest.js.map +1 -0
- package/dist/cli/cost-json.d.ts +37 -0
- package/dist/cli/cost-json.d.ts.map +1 -0
- package/dist/cli/cost-json.js +48 -0
- package/dist/cli/cost-json.js.map +1 -0
- package/dist/cli/daemon.d.ts +113 -0
- package/dist/cli/daemon.d.ts.map +1 -0
- package/dist/cli/daemon.js +282 -0
- package/dist/cli/daemon.js.map +1 -0
- package/dist/cli/doctor.d.ts +127 -0
- package/dist/cli/doctor.d.ts.map +1 -0
- package/dist/cli/doctor.js +400 -0
- package/dist/cli/doctor.js.map +1 -0
- package/dist/cli/feedback.d.ts +74 -0
- package/dist/cli/feedback.d.ts.map +1 -0
- package/dist/cli/feedback.js +180 -0
- package/dist/cli/feedback.js.map +1 -0
- package/dist/cli/filing.d.ts +22 -0
- package/dist/cli/filing.d.ts.map +1 -0
- package/dist/cli/filing.js +53 -0
- package/dist/cli/filing.js.map +1 -0
- package/dist/cli/first-run.d.ts +9 -0
- package/dist/cli/first-run.d.ts.map +1 -0
- package/dist/cli/first-run.js +34 -0
- package/dist/cli/first-run.js.map +1 -0
- package/dist/cli/help-groups.d.ts +17 -0
- package/dist/cli/help-groups.d.ts.map +1 -0
- package/dist/cli/help-groups.js +50 -0
- package/dist/cli/help-groups.js.map +1 -0
- package/dist/cli/hosted-queue.d.ts +45 -0
- package/dist/cli/hosted-queue.d.ts.map +1 -0
- package/dist/cli/hosted-queue.js +74 -0
- package/dist/cli/hosted-queue.js.map +1 -0
- package/dist/cli/hosted-runner.d.ts +44 -0
- package/dist/cli/hosted-runner.d.ts.map +1 -0
- package/dist/cli/hosted-runner.js +68 -0
- package/dist/cli/hosted-runner.js.map +1 -0
- package/dist/cli/hosted.d.ts +38 -0
- package/dist/cli/hosted.d.ts.map +1 -0
- package/dist/cli/hosted.js +82 -0
- package/dist/cli/hosted.js.map +1 -0
- package/dist/cli/index.d.ts +656 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +4801 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/init-files.d.ts +8 -0
- package/dist/cli/init-files.d.ts.map +1 -0
- package/dist/cli/init-files.js +45 -0
- package/dist/cli/init-files.js.map +1 -0
- package/dist/cli/logs.d.ts +27 -0
- package/dist/cli/logs.d.ts.map +1 -0
- package/dist/cli/logs.js +52 -0
- package/dist/cli/logs.js.map +1 -0
- package/dist/cli/merge-scope.d.ts +7 -0
- package/dist/cli/merge-scope.d.ts.map +1 -0
- package/dist/cli/merge-scope.js +14 -0
- package/dist/cli/merge-scope.js.map +1 -0
- package/dist/cli/octokit.d.ts +43 -0
- package/dist/cli/octokit.d.ts.map +1 -0
- package/dist/cli/octokit.js +87 -0
- package/dist/cli/octokit.js.map +1 -0
- package/dist/cli/queue-add-json.d.ts +25 -0
- package/dist/cli/queue-add-json.d.ts.map +1 -0
- package/dist/cli/queue-add-json.js +24 -0
- package/dist/cli/queue-add-json.js.map +1 -0
- package/dist/cli/queue-clear.d.ts +15 -0
- package/dist/cli/queue-clear.d.ts.map +1 -0
- package/dist/cli/queue-clear.js +58 -0
- package/dist/cli/queue-clear.js.map +1 -0
- package/dist/cli/queue-list.d.ts +24 -0
- package/dist/cli/queue-list.d.ts.map +1 -0
- package/dist/cli/queue-list.js +25 -0
- package/dist/cli/queue-list.js.map +1 -0
- package/dist/cli/ready-check.d.ts +98 -0
- package/dist/cli/ready-check.d.ts.map +1 -0
- package/dist/cli/ready-check.js +169 -0
- package/dist/cli/ready-check.js.map +1 -0
- package/dist/cli/reset.d.ts +40 -0
- package/dist/cli/reset.d.ts.map +1 -0
- package/dist/cli/reset.js +215 -0
- package/dist/cli/reset.js.map +1 -0
- package/dist/cli/run-children.d.ts +24 -0
- package/dist/cli/run-children.d.ts.map +1 -0
- package/dist/cli/run-children.js +73 -0
- package/dist/cli/run-children.js.map +1 -0
- package/dist/cli/run-flags.d.ts +14 -0
- package/dist/cli/run-flags.d.ts.map +1 -0
- package/dist/cli/run-flags.js +43 -0
- package/dist/cli/run-flags.js.map +1 -0
- package/dist/cli/runs-diffstat.d.ts +43 -0
- package/dist/cli/runs-diffstat.d.ts.map +1 -0
- package/dist/cli/runs-diffstat.js +91 -0
- package/dist/cli/runs-diffstat.js.map +1 -0
- package/dist/cli/runs.d.ts +36 -0
- package/dist/cli/runs.d.ts.map +1 -0
- package/dist/cli/runs.js +102 -0
- package/dist/cli/runs.js.map +1 -0
- package/dist/cli/staleness.d.ts +30 -0
- package/dist/cli/staleness.d.ts.map +1 -0
- package/dist/cli/staleness.js +132 -0
- package/dist/cli/staleness.js.map +1 -0
- package/dist/cli/status-json.d.ts +45 -0
- package/dist/cli/status-json.d.ts.map +1 -0
- package/dist/cli/status-json.js +22 -0
- package/dist/cli/status-json.js.map +1 -0
- package/dist/cli/stop-resume-json.d.ts +18 -0
- package/dist/cli/stop-resume-json.d.ts.map +1 -0
- package/dist/cli/stop-resume-json.js +10 -0
- package/dist/cli/stop-resume-json.js.map +1 -0
- package/dist/cli/stop-sentinel.d.ts +23 -0
- package/dist/cli/stop-sentinel.d.ts.map +1 -0
- package/dist/cli/stop-sentinel.js +61 -0
- package/dist/cli/stop-sentinel.js.map +1 -0
- package/dist/cli/sweep-heartbeat.d.ts +33 -0
- package/dist/cli/sweep-heartbeat.d.ts.map +1 -0
- package/dist/cli/sweep-heartbeat.js +65 -0
- package/dist/cli/sweep-heartbeat.js.map +1 -0
- package/dist/cli/unpark.d.ts +28 -0
- package/dist/cli/unpark.d.ts.map +1 -0
- package/dist/cli/unpark.js +68 -0
- package/dist/cli/unpark.js.map +1 -0
- package/dist/cli/usage-json.d.ts +20 -0
- package/dist/cli/usage-json.d.ts.map +1 -0
- package/dist/cli/usage-json.js +36 -0
- package/dist/cli/usage-json.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +6 -0
- package/dist/cli.js.map +1 -0
- package/dist/entry.d.ts +6 -0
- package/dist/entry.d.ts.map +1 -0
- package/dist/entry.js +13 -0
- package/dist/entry.js.map +1 -0
- package/package.json +48 -4
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
// packages/cli/src/cli/daemon.ts — factory daemon start|stop|status|logs: launchctl
|
|
2
|
+
// wrappers around the foreground factoryd (#1179, epic #764), plus `daemon run`
|
|
3
|
+
// option resolution into FactorydConfig (#2128).
|
|
4
|
+
import { execFile } from 'node:child_process';
|
|
5
|
+
import { closeSync, existsSync, fstatSync, mkdirSync, openSync, readFileSync, readSync, realpathSync, writeFileSync, } from 'node:fs';
|
|
6
|
+
import { homedir } from 'node:os';
|
|
7
|
+
import { dirname, join } from 'node:path';
|
|
8
|
+
import { DEFAULT_FACTORYD_PORT, defaultRegistryPath, listRepos, loadRegistry, } from '@on-par/factory-core/internal';
|
|
9
|
+
export const FACTORYD_LABEL = 'com.onpar.factoryd';
|
|
10
|
+
/** Expected daemon-control failure. index.ts's commander wrappers map it onto
|
|
11
|
+
* CliExitError (importing CliExitError here would be circular — index.ts
|
|
12
|
+
* imports this module). */
|
|
13
|
+
export class DaemonCtlError extends Error {
|
|
14
|
+
code;
|
|
15
|
+
constructor(message, code) {
|
|
16
|
+
super(message);
|
|
17
|
+
this.code = code;
|
|
18
|
+
this.name = 'DaemonCtlError';
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
/** Where a given home directory keeps the LaunchAgent plist and the daemon log. */
|
|
22
|
+
export function factorydFiles(home) {
|
|
23
|
+
const launchAgentsDir = join(home, 'Library', 'LaunchAgents');
|
|
24
|
+
return {
|
|
25
|
+
launchAgentsDir,
|
|
26
|
+
plistPath: join(launchAgentsDir, `${FACTORYD_LABEL}.plist`),
|
|
27
|
+
logPath: join(home, '.factory', 'daemon.log'),
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
/** Resolves `factory daemon run` options into a FactorydConfig. Throws
|
|
31
|
+
* DaemonCtlError (code 2) on an invalid --port. */
|
|
32
|
+
export function resolveFactorydConfig(opts) {
|
|
33
|
+
const port = opts.port === undefined ? DEFAULT_FACTORYD_PORT : Number(opts.port);
|
|
34
|
+
if (!Number.isInteger(port) || port < 0 || port > 65535) {
|
|
35
|
+
throw new DaemonCtlError(`invalid --port "${opts.port}" — expected an integer 0-65535`, 2);
|
|
36
|
+
}
|
|
37
|
+
return { registryFile: opts.registry ?? defaultRegistryPath(), port, autoUpdate: opts.autoUpdate === true };
|
|
38
|
+
}
|
|
39
|
+
function xmlEscape(s) {
|
|
40
|
+
return s.replaceAll('&', '&').replaceAll('<', '<').replaceAll('>', '>');
|
|
41
|
+
}
|
|
42
|
+
/** Pure renderer for ~/Library/LaunchAgents/com.onpar.factoryd.plist. KeepAlive
|
|
43
|
+
* relaunches factoryd after any exit; RunAtLoad starts it at login/bootstrap;
|
|
44
|
+
* launchd redirects stdout+stderr to the daemon log. ProgramArguments invokes
|
|
45
|
+
* the foreground `factory daemon run` command with its defaults. */
|
|
46
|
+
export function renderFactorydPlist(opts) {
|
|
47
|
+
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
48
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
49
|
+
<plist version="1.0">
|
|
50
|
+
<dict>
|
|
51
|
+
<key>Label</key>
|
|
52
|
+
<string>${FACTORYD_LABEL}</string>
|
|
53
|
+
<key>ProgramArguments</key>
|
|
54
|
+
<array>
|
|
55
|
+
<string>${xmlEscape(opts.nodePath)}</string>
|
|
56
|
+
<string>${xmlEscape(opts.cliScriptPath)}</string>
|
|
57
|
+
<string>daemon</string>
|
|
58
|
+
<string>run</string>
|
|
59
|
+
</array>
|
|
60
|
+
<key>RunAtLoad</key>
|
|
61
|
+
<true/>
|
|
62
|
+
<key>KeepAlive</key>
|
|
63
|
+
<true/>
|
|
64
|
+
<key>StandardOutPath</key>
|
|
65
|
+
<string>${xmlEscape(opts.logPath)}</string>
|
|
66
|
+
<key>StandardErrorPath</key>
|
|
67
|
+
<string>${xmlEscape(opts.logPath)}</string>
|
|
68
|
+
</dict>
|
|
69
|
+
</plist>
|
|
70
|
+
`;
|
|
71
|
+
}
|
|
72
|
+
/** ps `etime` ([[dd-]hh:]mm:ss) → whole seconds; null when empty or malformed. */
|
|
73
|
+
export function parseEtime(etime) {
|
|
74
|
+
const m = /^(?:(\d+)-)?(?:(\d+):)?(\d+):(\d+)$/.exec(etime.trim());
|
|
75
|
+
if (!m)
|
|
76
|
+
return null;
|
|
77
|
+
const [, dd, hh, mm, ss] = m;
|
|
78
|
+
if (dd !== undefined && hh === undefined)
|
|
79
|
+
return null;
|
|
80
|
+
return ((Number(dd ?? 0) * 24 + Number(hh ?? 0)) * 60 + Number(mm)) * 60 + Number(ss);
|
|
81
|
+
}
|
|
82
|
+
export function parseLaunchctlPid(printOutput) {
|
|
83
|
+
const m = /^\s*pid\s*=\s*(\d+)\s*$/m.exec(printOutput);
|
|
84
|
+
return m ? Number(m[1]) : null;
|
|
85
|
+
}
|
|
86
|
+
/** Last n lines of text, ignoring a trailing newline. */
|
|
87
|
+
export function lastLines(text, n) {
|
|
88
|
+
const lines = text.split('\n');
|
|
89
|
+
if (lines.at(-1) === '')
|
|
90
|
+
lines.pop();
|
|
91
|
+
return lines.slice(-n);
|
|
92
|
+
}
|
|
93
|
+
/** The production exec seam: execFile without a shell, resolving (never
|
|
94
|
+
* rejecting) `{ code, stdout, stderr }` — a missing binary or non-numeric
|
|
95
|
+
* error code becomes code 1. Exported for direct coverage in daemon.test.ts. */
|
|
96
|
+
export function defaultExec() {
|
|
97
|
+
return (cmd, args) => new Promise((res) => {
|
|
98
|
+
execFile(cmd, args, (error, stdout, stderr) => {
|
|
99
|
+
const code = error ? (error.code ?? 1) : 0;
|
|
100
|
+
res({ code: typeof code === 'number' ? code : 1, stdout, stderr });
|
|
101
|
+
});
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
function resolveDeps(deps) {
|
|
105
|
+
return {
|
|
106
|
+
exec: deps.exec ?? defaultExec(),
|
|
107
|
+
home: deps.home ?? homedir(),
|
|
108
|
+
uid: deps.uid ?? process.getuid?.() ?? 0,
|
|
109
|
+
platform: deps.platform ?? process.platform,
|
|
110
|
+
out: deps.out ?? process.stdout,
|
|
111
|
+
nodePath: deps.nodePath ?? process.execPath,
|
|
112
|
+
cliScriptPath: deps.cliScriptPath ?? realpathSync(process.argv[1] ?? ''),
|
|
113
|
+
registryFile: deps.registryFile ?? defaultRegistryPath(),
|
|
114
|
+
pollMs: deps.pollMs ?? 250,
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
function requireDarwin(platform) {
|
|
118
|
+
if (platform !== 'darwin') {
|
|
119
|
+
throw new DaemonCtlError('factory daemon start|stop|status requires macOS launchd', 2);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
/** Install (or reinstall) and load the LaunchAgent. Always a full reinstall:
|
|
123
|
+
* regenerate the plist, bootout (ignoring failure — handles both "already
|
|
124
|
+
* loaded" and "not loaded"), then bootstrap into the gui domain so the daemon's
|
|
125
|
+
* Claude workers keep login-keychain access (docs/runbooks/macos-keychain-launchagent.md). */
|
|
126
|
+
export async function cmdDaemonStart(deps = {}) {
|
|
127
|
+
const d = resolveDeps(deps);
|
|
128
|
+
requireDarwin(d.platform);
|
|
129
|
+
const { launchAgentsDir, plistPath, logPath } = factorydFiles(d.home);
|
|
130
|
+
mkdirSync(launchAgentsDir, { recursive: true });
|
|
131
|
+
mkdirSync(dirname(logPath), { recursive: true });
|
|
132
|
+
writeFileSync(plistPath, renderFactorydPlist({ nodePath: d.nodePath, cliScriptPath: d.cliScriptPath, logPath }));
|
|
133
|
+
await d.exec('launchctl', ['bootout', `gui/${d.uid}/${FACTORYD_LABEL}`]);
|
|
134
|
+
const boot = await d.exec('launchctl', ['bootstrap', `gui/${d.uid}`, plistPath]);
|
|
135
|
+
if (boot.code !== 0) {
|
|
136
|
+
throw new DaemonCtlError(`launchctl bootstrap failed: ${boot.stderr.trim() || boot.stdout.trim() || `exit ${boot.code}`}`, 1);
|
|
137
|
+
}
|
|
138
|
+
const print = await d.exec('launchctl', ['print', `gui/${d.uid}/${FACTORYD_LABEL}`]);
|
|
139
|
+
const pid = parseLaunchctlPid(print.stdout);
|
|
140
|
+
d.out.write(`factoryd: installed ${plistPath}\n`);
|
|
141
|
+
d.out.write(pid === null ? 'factoryd: loaded — launchd will start it (RunAtLoad)\n' : `factoryd: running (pid ${pid})\n`);
|
|
142
|
+
}
|
|
143
|
+
/** Unload the LaunchAgent. Idempotent: a not-loaded agent is success. The plist
|
|
144
|
+
* stays on disk so `factory daemon start` re-enables it. */
|
|
145
|
+
export async function cmdDaemonStop(deps = {}) {
|
|
146
|
+
const d = resolveDeps(deps);
|
|
147
|
+
requireDarwin(d.platform);
|
|
148
|
+
const res = await d.exec('launchctl', ['bootout', `gui/${d.uid}/${FACTORYD_LABEL}`]);
|
|
149
|
+
if (res.code === 0) {
|
|
150
|
+
d.out.write('factoryd: stopped (unloaded from launchd)\n');
|
|
151
|
+
}
|
|
152
|
+
else {
|
|
153
|
+
d.out.write('factoryd: not loaded — already stopped\n');
|
|
154
|
+
}
|
|
155
|
+
d.out.write(' plist stays installed; `factory daemon start` re-enables it\n');
|
|
156
|
+
}
|
|
157
|
+
/** Report running/not-loaded, pid + uptime, plist install state, and the
|
|
158
|
+
* attached repos from the registry. Exit code 0 when running, 1 when not.
|
|
159
|
+
* With `opts.json`, print one DaemonStatusJson object instead of text. */
|
|
160
|
+
export async function cmdDaemonStatus(deps = {}, opts = {}) {
|
|
161
|
+
const d = resolveDeps(deps);
|
|
162
|
+
requireDarwin(d.platform);
|
|
163
|
+
const { plistPath, logPath } = factorydFiles(d.home);
|
|
164
|
+
if (opts.json) {
|
|
165
|
+
const printed = await d.exec('launchctl', ['print', `gui/${d.uid}/${FACTORYD_LABEL}`]);
|
|
166
|
+
const pid = printed.code === 0 ? parseLaunchctlPid(printed.stdout) : null;
|
|
167
|
+
const uptimeSec = pid === null ? null : parseEtime((await d.exec('ps', ['-o', 'etime=', '-p', String(pid)])).stdout);
|
|
168
|
+
const payload = {
|
|
169
|
+
schemaVersion: 1,
|
|
170
|
+
running: pid !== null,
|
|
171
|
+
pid,
|
|
172
|
+
uptimeSec,
|
|
173
|
+
plistInstalled: existsSync(plistPath),
|
|
174
|
+
repos: listRepos(await loadRegistry(d.registryFile)).map((r) => ({
|
|
175
|
+
slug: r.slug,
|
|
176
|
+
checkoutPath: r.path,
|
|
177
|
+
state: r.state,
|
|
178
|
+
})),
|
|
179
|
+
};
|
|
180
|
+
d.out.write(`${JSON.stringify(payload)}\n`);
|
|
181
|
+
if (pid === null)
|
|
182
|
+
process.exitCode = 1;
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
const print = await d.exec('launchctl', ['print', `gui/${d.uid}/${FACTORYD_LABEL}`]);
|
|
186
|
+
if (print.code !== 0) {
|
|
187
|
+
d.out.write('factoryd: not loaded\n');
|
|
188
|
+
d.out.write(existsSync(plistPath) ? ` plist installed: ${plistPath}\n` : ' plist not installed\n');
|
|
189
|
+
d.out.write(' run: factory daemon start\n');
|
|
190
|
+
process.exitCode = 1;
|
|
191
|
+
}
|
|
192
|
+
else {
|
|
193
|
+
const pid = parseLaunchctlPid(print.stdout);
|
|
194
|
+
if (pid === null) {
|
|
195
|
+
d.out.write('factoryd: loaded (not currently running)\n');
|
|
196
|
+
process.exitCode = 1;
|
|
197
|
+
}
|
|
198
|
+
else {
|
|
199
|
+
const ps = await d.exec('ps', ['-o', 'etime=', '-p', String(pid)]);
|
|
200
|
+
const uptime = ps.stdout.trim() || 'unknown';
|
|
201
|
+
d.out.write(`factoryd: running (pid ${pid}, uptime ${uptime})\n`);
|
|
202
|
+
}
|
|
203
|
+
d.out.write(` plist: ${plistPath}\n`);
|
|
204
|
+
}
|
|
205
|
+
d.out.write(` log: ${logPath}\n`);
|
|
206
|
+
const registry = await loadRegistry(d.registryFile);
|
|
207
|
+
const repos = listRepos(registry);
|
|
208
|
+
if (repos.length === 0) {
|
|
209
|
+
d.out.write(' attached repos: none\n');
|
|
210
|
+
}
|
|
211
|
+
else {
|
|
212
|
+
d.out.write(` attached repos (${repos.length}):\n`);
|
|
213
|
+
for (const repo of repos)
|
|
214
|
+
d.out.write(` ${repo.slug} [${repo.state}]\n`);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
/** Print the last N lines of ~/.factory/daemon.log; with --follow, keep
|
|
218
|
+
* streaming appended bytes until Ctrl-C (size-offset poll, like logs.ts's
|
|
219
|
+
* followEvents — no `tail -f` child process). Works on any platform. */
|
|
220
|
+
export async function cmdDaemonLogs(opts, deps = {}) {
|
|
221
|
+
const d = resolveDeps(deps);
|
|
222
|
+
const { logPath } = factorydFiles(d.home);
|
|
223
|
+
const n = Number(opts.lines ?? '100');
|
|
224
|
+
if (!Number.isInteger(n) || n < 0) {
|
|
225
|
+
throw new DaemonCtlError(`invalid --lines "${opts.lines}" — expected a non-negative integer`, 2);
|
|
226
|
+
}
|
|
227
|
+
let initial;
|
|
228
|
+
try {
|
|
229
|
+
initial = readFileSync(logPath, 'utf-8');
|
|
230
|
+
}
|
|
231
|
+
catch (err) {
|
|
232
|
+
if (err.code !== 'ENOENT')
|
|
233
|
+
throw err;
|
|
234
|
+
d.out.write(`no daemon log yet at ${logPath} — is the daemon started?\n`);
|
|
235
|
+
return;
|
|
236
|
+
}
|
|
237
|
+
const tail = lastLines(initial, n);
|
|
238
|
+
if (tail.length > 0)
|
|
239
|
+
d.out.write(tail.join('\n') + '\n');
|
|
240
|
+
if (!opts.follow)
|
|
241
|
+
return;
|
|
242
|
+
let offset = Buffer.byteLength(initial);
|
|
243
|
+
const poll = setInterval(() => {
|
|
244
|
+
let fd;
|
|
245
|
+
try {
|
|
246
|
+
fd = openSync(logPath, 'r');
|
|
247
|
+
}
|
|
248
|
+
catch {
|
|
249
|
+
return; // transiently missing (rotation) — keep polling
|
|
250
|
+
}
|
|
251
|
+
let size;
|
|
252
|
+
try {
|
|
253
|
+
size = fstatSync(fd).size;
|
|
254
|
+
}
|
|
255
|
+
catch {
|
|
256
|
+
closeSync(fd);
|
|
257
|
+
return;
|
|
258
|
+
}
|
|
259
|
+
if (size < offset)
|
|
260
|
+
offset = 0; // truncated/rotated: start over
|
|
261
|
+
if (size === offset) {
|
|
262
|
+
closeSync(fd);
|
|
263
|
+
return;
|
|
264
|
+
}
|
|
265
|
+
try {
|
|
266
|
+
const buf = Buffer.alloc(size - offset);
|
|
267
|
+
const read = readSync(fd, buf, 0, buf.length, offset);
|
|
268
|
+
offset += read;
|
|
269
|
+
d.out.write(buf.subarray(0, read).toString('utf-8'));
|
|
270
|
+
}
|
|
271
|
+
finally {
|
|
272
|
+
closeSync(fd);
|
|
273
|
+
}
|
|
274
|
+
}, d.pollMs);
|
|
275
|
+
await new Promise((res) => {
|
|
276
|
+
const done = () => res();
|
|
277
|
+
process.once('SIGINT', done);
|
|
278
|
+
process.once('SIGTERM', done);
|
|
279
|
+
});
|
|
280
|
+
clearInterval(poll);
|
|
281
|
+
}
|
|
282
|
+
//# sourceMappingURL=daemon.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"daemon.js","sourceRoot":"","sources":["../../src/cli/daemon.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
export interface DoctorCheck {
|
|
2
|
+
name: string;
|
|
3
|
+
ok: boolean;
|
|
4
|
+
detail: string;
|
|
5
|
+
/** One-line fix suggestion; only meaningful when ok=false. */
|
|
6
|
+
fix?: string;
|
|
7
|
+
/** Optional checks never fail the doctor exit code. */
|
|
8
|
+
optional?: boolean;
|
|
9
|
+
}
|
|
10
|
+
export interface DoctorEnvProbes {
|
|
11
|
+
commandAvailable: (cmd: string) => boolean;
|
|
12
|
+
envPresent: (key: string) => boolean;
|
|
13
|
+
/** Run a command, return trimmed stdout, or null if it fails. */
|
|
14
|
+
tryExec: (cmd: string) => string | null;
|
|
15
|
+
pathExists: (p: string) => boolean;
|
|
16
|
+
distFreshness?: () => {
|
|
17
|
+
fresh: boolean;
|
|
18
|
+
detail: string;
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
export declare function runDoctorChecks(probes: DoctorEnvProbes): DoctorCheck[];
|
|
22
|
+
export declare function formatDoctorChecks(checks: DoctorCheck[]): string;
|
|
23
|
+
export declare function doctorFailed(checks: DoctorCheck[]): boolean;
|
|
24
|
+
/** Which Claude profile a keychain probe checked: the keychain service name and, for a
|
|
25
|
+
* non-default profile, the CLAUDE_CONFIG_DIR it belongs to. Absent = default profile. */
|
|
26
|
+
export interface KeychainProbeProfile {
|
|
27
|
+
service?: string;
|
|
28
|
+
configDir?: string;
|
|
29
|
+
}
|
|
30
|
+
/** Result of the macOS login-keychain probe for the Claude Code credential entry (#1014). */
|
|
31
|
+
export type KeychainProbeStatus = {
|
|
32
|
+
status: 'skipped';
|
|
33
|
+
detail: string;
|
|
34
|
+
} | ({
|
|
35
|
+
status: 'readable';
|
|
36
|
+
} & KeychainProbeProfile) | ({
|
|
37
|
+
status: 'unreadable';
|
|
38
|
+
inTmux: boolean;
|
|
39
|
+
} & KeychainProbeProfile);
|
|
40
|
+
export declare function claudeKeychainCheck(probe: KeychainProbeStatus): DoctorCheck;
|
|
41
|
+
/** Non-null when `factory run` must fail fast instead of claiming issues (#1014).
|
|
42
|
+
* Only the tmux-without-keychain differential is certain enough to abort a run on. */
|
|
43
|
+
export declare function keychainPreflightError(probe: KeychainProbeStatus): string | null;
|
|
44
|
+
/** Outcome of one `claude -p` probe: it succeeded, it failed, or it was not run. */
|
|
45
|
+
export type ClaudeAuthProbe = 'ok' | 'failed' | 'skipped';
|
|
46
|
+
export interface ClaudeAuthProbeResult {
|
|
47
|
+
host: ClaudeAuthProbe;
|
|
48
|
+
sandboxed: ClaudeAuthProbe;
|
|
49
|
+
hostDetail: string;
|
|
50
|
+
sandboxDetail: string;
|
|
51
|
+
}
|
|
52
|
+
/** Reports host and sandboxed Claude auth as two separate checks (#1008). Only the
|
|
53
|
+
* differential — host ok, sandboxed failed — is a hard doctor failure; that is the one
|
|
54
|
+
* combination that proves the sandbox, not the credentials, is at fault. */
|
|
55
|
+
export declare function sandboxClaudeAuthChecks(result: ClaudeAuthProbeResult): DoctorCheck[];
|
|
56
|
+
export interface LeaseHealthRow {
|
|
57
|
+
worktreeId: string;
|
|
58
|
+
branch: string;
|
|
59
|
+
port: number;
|
|
60
|
+
pid: number;
|
|
61
|
+
alive: boolean;
|
|
62
|
+
reason?: 'dead-pid' | 'missing-worktree';
|
|
63
|
+
portSquatted?: boolean;
|
|
64
|
+
}
|
|
65
|
+
export declare function leaseChecks(rows: LeaseHealthRow[]): DoctorCheck[];
|
|
66
|
+
export interface EventLogIntegrity {
|
|
67
|
+
total: number;
|
|
68
|
+
unparseable: number;
|
|
69
|
+
}
|
|
70
|
+
export declare function analyzeEventLog(content: string): EventLogIntegrity;
|
|
71
|
+
export declare function eventLogCheck(integrity: EventLogIntegrity | null): DoctorCheck;
|
|
72
|
+
export interface ReapRow {
|
|
73
|
+
name: string;
|
|
74
|
+
removed: boolean;
|
|
75
|
+
detail: string;
|
|
76
|
+
}
|
|
77
|
+
export declare function orphanContainerChecks(names: readonly string[]): DoctorCheck[];
|
|
78
|
+
export declare function orphanMicroVmChecks(names: readonly string[]): DoctorCheck[];
|
|
79
|
+
export declare function formatContainerReconcileReport(reaped: ReapRow[]): string;
|
|
80
|
+
export declare function formatMicroVmReconcileReport(reaped: ReapRow[]): string;
|
|
81
|
+
export declare function formatReconcileReport(reaped: Array<{
|
|
82
|
+
lease: {
|
|
83
|
+
worktreeId: string;
|
|
84
|
+
port: number;
|
|
85
|
+
};
|
|
86
|
+
reason: string;
|
|
87
|
+
}>): string;
|
|
88
|
+
/** One worktree the reconcile pass removed. Structurally the subset of core's `GcCandidate`
|
|
89
|
+
* that the report renders — kept local so `doctor.ts` stays dependency-free and unit-testable. */
|
|
90
|
+
export interface ReconciledWorktree {
|
|
91
|
+
path: string;
|
|
92
|
+
branch: string | null;
|
|
93
|
+
reason: string;
|
|
94
|
+
branchDeleted: boolean;
|
|
95
|
+
}
|
|
96
|
+
export declare function formatWorktreeReconcileReport(removed: ReconciledWorktree[]): string;
|
|
97
|
+
/** One claim the reconcile pass put back in the queue. Structurally the subset of core's
|
|
98
|
+
* `StaleClaimRelease` that the report renders — kept local so `doctor.ts` stays
|
|
99
|
+
* dependency-free and unit-testable. */
|
|
100
|
+
export interface ReleasedClaim {
|
|
101
|
+
issue: number;
|
|
102
|
+
expiresAt: number;
|
|
103
|
+
released: boolean;
|
|
104
|
+
detail?: string;
|
|
105
|
+
}
|
|
106
|
+
export declare function formatClaimReconcileReport(released: ReleasedClaim[]): string;
|
|
107
|
+
/** One green-and-ready PR nobody merged. Structurally the subset of core's `UnmergedGreenPr`
|
|
108
|
+
* the report renders — kept local so `doctor.ts` stays dependency-free and unit-testable. */
|
|
109
|
+
export interface UnmergedGreenPrRow {
|
|
110
|
+
number: number;
|
|
111
|
+
branch: string;
|
|
112
|
+
issue: number | null;
|
|
113
|
+
ageHours: number;
|
|
114
|
+
}
|
|
115
|
+
/** Outcome of the green-PR scan: it ran, it was skipped (no repo/token), or it failed. */
|
|
116
|
+
export type GreenPrScanResult = {
|
|
117
|
+
status: 'ok';
|
|
118
|
+
rows: UnmergedGreenPrRow[];
|
|
119
|
+
} | {
|
|
120
|
+
status: 'skipped';
|
|
121
|
+
detail: string;
|
|
122
|
+
} | {
|
|
123
|
+
status: 'failed';
|
|
124
|
+
detail: string;
|
|
125
|
+
};
|
|
126
|
+
export declare function unmergedGreenPrChecks(result: GreenPrScanResult): DoctorCheck[];
|
|
127
|
+
//# sourceMappingURL=doctor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../src/cli/doctor.ts"],"names":[],"mappings":"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"}
|