@yoavsh/treekeeper 0.0.0-stage → 0.1.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/CHANGELOG.md +14 -0
- package/LICENSE +21 -0
- package/README.md +237 -2
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +165 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/archive.d.ts +3 -0
- package/dist/commands/archive.d.ts.map +1 -0
- package/dist/commands/archive.js +55 -0
- package/dist/commands/archive.js.map +1 -0
- package/dist/commands/config.d.ts +2 -0
- package/dist/commands/config.d.ts.map +1 -0
- package/dist/commands/config.js +54 -0
- package/dist/commands/config.js.map +1 -0
- package/dist/commands/context.d.ts +34 -0
- package/dist/commands/context.d.ts.map +1 -0
- package/dist/commands/context.js +53 -0
- package/dist/commands/context.js.map +1 -0
- package/dist/commands/daemon.d.ts +3 -0
- package/dist/commands/daemon.d.ts.map +1 -0
- package/dist/commands/daemon.js +81 -0
- package/dist/commands/daemon.js.map +1 -0
- package/dist/commands/doctor.d.ts +3 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +119 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/gc.d.ts +3 -0
- package/dist/commands/gc.d.ts.map +1 -0
- package/dist/commands/gc.js +98 -0
- package/dist/commands/gc.js.map +1 -0
- package/dist/commands/status.d.ts +4 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +52 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/watch.d.ts +10 -0
- package/dist/commands/watch.d.ts.map +1 -0
- package/dist/commands/watch.js +41 -0
- package/dist/commands/watch.js.map +1 -0
- package/dist/core/apply.d.ts +47 -0
- package/dist/core/apply.d.ts.map +1 -0
- package/dist/core/apply.js +223 -0
- package/dist/core/apply.js.map +1 -0
- package/dist/core/archive.d.ts +69 -0
- package/dist/core/archive.d.ts.map +1 -0
- package/dist/core/archive.js +202 -0
- package/dist/core/archive.js.map +1 -0
- package/dist/core/config.d.ts +69 -0
- package/dist/core/config.d.ts.map +1 -0
- package/dist/core/config.js +261 -0
- package/dist/core/config.js.map +1 -0
- package/dist/core/decide.d.ts +102 -0
- package/dist/core/decide.d.ts.map +1 -0
- package/dist/core/decide.js +148 -0
- package/dist/core/decide.js.map +1 -0
- package/dist/core/forge.d.ts +39 -0
- package/dist/core/forge.d.ts.map +1 -0
- package/dist/core/forge.js +190 -0
- package/dist/core/forge.js.map +1 -0
- package/dist/core/git.d.ts +63 -0
- package/dist/core/git.d.ts.map +1 -0
- package/dist/core/git.js +194 -0
- package/dist/core/git.js.map +1 -0
- package/dist/core/plan.d.ts +75 -0
- package/dist/core/plan.d.ts.map +1 -0
- package/dist/core/plan.js +288 -0
- package/dist/core/plan.js.map +1 -0
- package/dist/core/render.d.ts +14 -0
- package/dist/core/render.d.ts.map +1 -0
- package/dist/core/render.js +128 -0
- package/dist/core/render.js.map +1 -0
- package/dist/core/scan.d.ts +22 -0
- package/dist/core/scan.d.ts.map +1 -0
- package/dist/core/scan.js +99 -0
- package/dist/core/scan.js.map +1 -0
- package/dist/core/sessions.d.ts +37 -0
- package/dist/core/sessions.d.ts.map +1 -0
- package/dist/core/sessions.js +300 -0
- package/dist/core/sessions.js.map +1 -0
- package/dist/core/size.d.ts +3 -0
- package/dist/core/size.d.ts.map +1 -0
- package/dist/core/size.js +11 -0
- package/dist/core/size.js.map +1 -0
- package/dist/daemon/lock.d.ts +10 -0
- package/dist/daemon/lock.d.ts.map +1 -0
- package/dist/daemon/lock.js +64 -0
- package/dist/daemon/lock.js.map +1 -0
- package/dist/daemon/service.d.ts +34 -0
- package/dist/daemon/service.d.ts.map +1 -0
- package/dist/daemon/service.js +257 -0
- package/dist/daemon/service.js.map +1 -0
- package/dist/daemon/state.d.ts +19 -0
- package/dist/daemon/state.d.ts.map +1 -0
- package/dist/daemon/state.js +32 -0
- package/dist/daemon/state.js.map +1 -0
- package/dist/index.d.ts +26 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +19 -0
- package/dist/index.js.map +1 -0
- package/dist/util/bytes.d.ts +4 -0
- package/dist/util/bytes.d.ts.map +1 -0
- package/dist/util/bytes.js +14 -0
- package/dist/util/bytes.js.map +1 -0
- package/dist/util/color.d.ts +16 -0
- package/dist/util/color.d.ts.map +1 -0
- package/dist/util/color.js +32 -0
- package/dist/util/color.js.map +1 -0
- package/dist/util/exec.d.ts +27 -0
- package/dist/util/exec.d.ts.map +1 -0
- package/dist/util/exec.js +57 -0
- package/dist/util/exec.js.map +1 -0
- package/dist/util/log.d.ts +29 -0
- package/dist/util/log.d.ts.map +1 -0
- package/dist/util/log.js +72 -0
- package/dist/util/log.js.map +1 -0
- package/dist/util/paths.d.ts +18 -0
- package/dist/util/paths.d.ts.map +1 -0
- package/dist/util/paths.js +87 -0
- package/dist/util/paths.js.map +1 -0
- package/dist/util/prompt.d.ts +3 -0
- package/dist/util/prompt.d.ts.map +1 -0
- package/dist/util/prompt.js +15 -0
- package/dist/util/prompt.js.map +1 -0
- package/dist/util/redact.d.ts +15 -0
- package/dist/util/redact.d.ts.map +1 -0
- package/dist/util/redact.js +44 -0
- package/dist/util/redact.js.map +1 -0
- package/dist/util/time.d.ts +13 -0
- package/dist/util/time.d.ts.map +1 -0
- package/dist/util/time.js +77 -0
- package/dist/util/time.js.map +1 -0
- package/docs/integrations.md +128 -0
- package/docs/safety.md +62 -0
- package/package.json +69 -4
- package/src/cli.ts +175 -0
- package/src/commands/archive.ts +72 -0
- package/src/commands/config.ts +57 -0
- package/src/commands/context.ts +86 -0
- package/src/commands/daemon.ts +86 -0
- package/src/commands/doctor.ts +131 -0
- package/src/commands/gc.ts +108 -0
- package/src/commands/status.ts +68 -0
- package/src/commands/watch.ts +48 -0
- package/src/core/apply.ts +276 -0
- package/src/core/archive.ts +269 -0
- package/src/core/config.ts +339 -0
- package/src/core/decide.ts +230 -0
- package/src/core/forge.ts +243 -0
- package/src/core/git.ts +254 -0
- package/src/core/plan.ts +431 -0
- package/src/core/render.ts +168 -0
- package/src/core/scan.ts +105 -0
- package/src/core/sessions.ts +339 -0
- package/src/core/size.ts +10 -0
- package/src/daemon/lock.ts +65 -0
- package/src/daemon/service.ts +321 -0
- package/src/daemon/state.ts +49 -0
- package/src/index.ts +36 -0
- package/src/util/bytes.ts +11 -0
- package/src/util/color.ts +33 -0
- package/src/util/exec.ts +80 -0
- package/src/util/log.ts +88 -0
- package/src/util/paths.ts +84 -0
- package/src/util/prompt.ts +13 -0
- package/src/util/redact.ts +43 -0
- package/src/util/time.ts +75 -0
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
import { mkdir, readFile, rm, writeFile } from "node:fs/promises";
|
|
2
|
+
import { homedir } from "node:os";
|
|
3
|
+
import { dirname, join, resolve } from "node:path";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
5
|
+
import { run } from "../util/exec.js";
|
|
6
|
+
import { treekeeperHome } from "../util/paths.js";
|
|
7
|
+
import { parseDuration } from "../util/time.js";
|
|
8
|
+
import { readState } from "./state.js";
|
|
9
|
+
export const LABEL = "com.treekeeper.agent";
|
|
10
|
+
export const SYSTEMD_UNIT = "treekeeper";
|
|
11
|
+
export function currentManager() {
|
|
12
|
+
if (process.platform === "darwin")
|
|
13
|
+
return "launchd";
|
|
14
|
+
if (process.platform === "linux")
|
|
15
|
+
return "systemd";
|
|
16
|
+
return "unsupported";
|
|
17
|
+
}
|
|
18
|
+
function launchAgentPath() {
|
|
19
|
+
return join(homedir(), "Library", "LaunchAgents", `${LABEL}.plist`);
|
|
20
|
+
}
|
|
21
|
+
function systemdDir() {
|
|
22
|
+
const base = process.env.XDG_CONFIG_HOME
|
|
23
|
+
? resolve(process.env.XDG_CONFIG_HOME)
|
|
24
|
+
: join(homedir(), ".config");
|
|
25
|
+
return join(base, "systemd", "user");
|
|
26
|
+
}
|
|
27
|
+
function daemonLogPath() {
|
|
28
|
+
return join(treekeeperHome(), "daemon.out.log");
|
|
29
|
+
}
|
|
30
|
+
/** Absolute path to this installation's CLI entry point. */
|
|
31
|
+
export function cliPath() {
|
|
32
|
+
return resolve(fileURLToPath(new URL("../cli.js", import.meta.url)));
|
|
33
|
+
}
|
|
34
|
+
/** The command a scheduled sweep runs. */
|
|
35
|
+
export function sweepArgv(extra = []) {
|
|
36
|
+
return [process.execPath, cliPath(), "gc", "--all", "--apply", "--yes", "--quiet", ...extra];
|
|
37
|
+
}
|
|
38
|
+
export async function daemonStatus() {
|
|
39
|
+
const manager = currentManager();
|
|
40
|
+
const state = await readState();
|
|
41
|
+
const base = {
|
|
42
|
+
manager,
|
|
43
|
+
installed: false,
|
|
44
|
+
active: false,
|
|
45
|
+
unitPath: null,
|
|
46
|
+
intervalSeconds: null,
|
|
47
|
+
lastSweep: state.lastSweep,
|
|
48
|
+
logFile: daemonLogPath(),
|
|
49
|
+
};
|
|
50
|
+
if (manager === "launchd") {
|
|
51
|
+
const path = launchAgentPath();
|
|
52
|
+
const plist = await readIfPresent(path);
|
|
53
|
+
base.unitPath = path;
|
|
54
|
+
base.installed = plist !== null;
|
|
55
|
+
if (plist) {
|
|
56
|
+
const m = /<key>StartInterval<\/key>\s*<integer>(\d+)<\/integer>/.exec(plist);
|
|
57
|
+
base.intervalSeconds = m?.[1] ? Number(m[1]) : null;
|
|
58
|
+
const list = await run("launchctl", ["list", LABEL], { timeoutMs: 10_000 });
|
|
59
|
+
base.active = list.code === 0;
|
|
60
|
+
}
|
|
61
|
+
return base;
|
|
62
|
+
}
|
|
63
|
+
if (manager === "systemd") {
|
|
64
|
+
const timer = join(systemdDir(), `${SYSTEMD_UNIT}.timer`);
|
|
65
|
+
const unit = await readIfPresent(timer);
|
|
66
|
+
base.unitPath = timer;
|
|
67
|
+
base.installed = unit !== null;
|
|
68
|
+
if (unit) {
|
|
69
|
+
const m = /OnUnitActiveSec=(\d+)/.exec(unit);
|
|
70
|
+
base.intervalSeconds = m?.[1] ? Number(m[1]) : null;
|
|
71
|
+
const active = await run("systemctl", ["--user", "is-active", `${SYSTEMD_UNIT}.timer`], {
|
|
72
|
+
timeoutMs: 10_000,
|
|
73
|
+
});
|
|
74
|
+
base.active = active.stdout.trim() === "active";
|
|
75
|
+
}
|
|
76
|
+
return base;
|
|
77
|
+
}
|
|
78
|
+
return base;
|
|
79
|
+
}
|
|
80
|
+
/** Write and load the service definition for the current platform. */
|
|
81
|
+
export async function installDaemon(interval) {
|
|
82
|
+
const manager = currentManager();
|
|
83
|
+
const seconds = Math.max(60, Math.round(parseDuration(interval) / 1000));
|
|
84
|
+
const messages = [];
|
|
85
|
+
if (manager === "launchd") {
|
|
86
|
+
const path = launchAgentPath();
|
|
87
|
+
await mkdir(dirname(path), { recursive: true });
|
|
88
|
+
await mkdir(treekeeperHome(), { recursive: true });
|
|
89
|
+
await writeFile(path, launchdPlist(seconds));
|
|
90
|
+
// bootout first so a re-install picks up a changed interval.
|
|
91
|
+
await run("launchctl", ["bootout", `gui/${process.getuid?.() ?? 501}/${LABEL}`], { timeoutMs: 15_000 });
|
|
92
|
+
const boot = await run("launchctl", ["bootstrap", `gui/${process.getuid?.() ?? 501}`, path], { timeoutMs: 20_000 });
|
|
93
|
+
if (boot.code !== 0) {
|
|
94
|
+
const legacy = await run("launchctl", ["load", "-w", path], { timeoutMs: 20_000 });
|
|
95
|
+
if (legacy.code !== 0) {
|
|
96
|
+
messages.push(`wrote ${path} but launchctl could not load it: ${(boot.stderr || legacy.stderr).trim()}`);
|
|
97
|
+
return { ok: false, manager, unitPath: path, messages };
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
messages.push(`installed ${path}`, `sweeping every ${seconds}s · logs in ${daemonLogPath()}`);
|
|
101
|
+
return { ok: true, manager, unitPath: path, messages };
|
|
102
|
+
}
|
|
103
|
+
if (manager === "systemd") {
|
|
104
|
+
const dir = systemdDir();
|
|
105
|
+
await mkdir(dir, { recursive: true });
|
|
106
|
+
await mkdir(treekeeperHome(), { recursive: true });
|
|
107
|
+
const servicePath = join(dir, `${SYSTEMD_UNIT}.service`);
|
|
108
|
+
const timerPath = join(dir, `${SYSTEMD_UNIT}.timer`);
|
|
109
|
+
await writeFile(servicePath, systemdService());
|
|
110
|
+
await writeFile(timerPath, systemdTimer(seconds));
|
|
111
|
+
await run("systemctl", ["--user", "daemon-reload"], { timeoutMs: 20_000 });
|
|
112
|
+
const enable = await run("systemctl", ["--user", "enable", "--now", `${SYSTEMD_UNIT}.timer`], { timeoutMs: 20_000 });
|
|
113
|
+
if (enable.code !== 0) {
|
|
114
|
+
messages.push(`wrote the units but systemctl failed: ${enable.stderr.trim()}`);
|
|
115
|
+
return { ok: false, manager, unitPath: timerPath, messages };
|
|
116
|
+
}
|
|
117
|
+
messages.push(`installed ${servicePath} and ${timerPath}`, `sweeping every ${seconds}s`, "tip: `loginctl enable-linger $USER` keeps the timer running while you are logged out");
|
|
118
|
+
return { ok: true, manager, unitPath: timerPath, messages };
|
|
119
|
+
}
|
|
120
|
+
messages.push(`no supported service manager on ${process.platform}.`, "Run `treekeeper watch` under your own supervisor, or schedule `treekeeper gc --all --apply --yes`.");
|
|
121
|
+
return { ok: false, manager, unitPath: null, messages };
|
|
122
|
+
}
|
|
123
|
+
export async function uninstallDaemon() {
|
|
124
|
+
const manager = currentManager();
|
|
125
|
+
const messages = [];
|
|
126
|
+
if (manager === "launchd") {
|
|
127
|
+
const path = launchAgentPath();
|
|
128
|
+
await run("launchctl", ["bootout", `gui/${process.getuid?.() ?? 501}/${LABEL}`], { timeoutMs: 15_000 });
|
|
129
|
+
await run("launchctl", ["unload", "-w", path], { timeoutMs: 15_000 });
|
|
130
|
+
await rm(path, { force: true });
|
|
131
|
+
messages.push(`removed ${path}`);
|
|
132
|
+
return { ok: true, manager, unitPath: path, messages };
|
|
133
|
+
}
|
|
134
|
+
if (manager === "systemd") {
|
|
135
|
+
const dir = systemdDir();
|
|
136
|
+
await run("systemctl", ["--user", "disable", "--now", `${SYSTEMD_UNIT}.timer`], { timeoutMs: 20_000 });
|
|
137
|
+
await rm(join(dir, `${SYSTEMD_UNIT}.timer`), { force: true });
|
|
138
|
+
await rm(join(dir, `${SYSTEMD_UNIT}.service`), { force: true });
|
|
139
|
+
await run("systemctl", ["--user", "daemon-reload"], { timeoutMs: 20_000 });
|
|
140
|
+
messages.push("removed the treekeeper timer and service");
|
|
141
|
+
return { ok: true, manager, unitPath: null, messages };
|
|
142
|
+
}
|
|
143
|
+
messages.push("nothing to uninstall");
|
|
144
|
+
return { ok: true, manager, unitPath: null, messages };
|
|
145
|
+
}
|
|
146
|
+
export async function setDaemonRunning(running) {
|
|
147
|
+
const manager = currentManager();
|
|
148
|
+
const messages = [];
|
|
149
|
+
if (manager === "launchd") {
|
|
150
|
+
const path = launchAgentPath();
|
|
151
|
+
const uid = process.getuid?.() ?? 501;
|
|
152
|
+
const r = running
|
|
153
|
+
? await run("launchctl", ["bootstrap", `gui/${uid}`, path], { timeoutMs: 20_000 })
|
|
154
|
+
: await run("launchctl", ["bootout", `gui/${uid}/${LABEL}`], { timeoutMs: 20_000 });
|
|
155
|
+
messages.push(r.code === 0 ? (running ? "started" : "stopped") : (r.stderr || r.stdout).trim());
|
|
156
|
+
return { ok: r.code === 0, manager, unitPath: path, messages };
|
|
157
|
+
}
|
|
158
|
+
if (manager === "systemd") {
|
|
159
|
+
const r = await run("systemctl", ["--user", running ? "start" : "stop", `${SYSTEMD_UNIT}.timer`], { timeoutMs: 20_000 });
|
|
160
|
+
messages.push(r.code === 0 ? (running ? "started" : "stopped") : r.stderr.trim());
|
|
161
|
+
return { ok: r.code === 0, manager, unitPath: null, messages };
|
|
162
|
+
}
|
|
163
|
+
messages.push(`not supported on ${process.platform}`);
|
|
164
|
+
return { ok: false, manager, unitPath: null, messages };
|
|
165
|
+
}
|
|
166
|
+
export function launchdPlist(seconds) {
|
|
167
|
+
const args = sweepArgv()
|
|
168
|
+
.map((a) => ` <string>${escapeXml(a)}</string>`)
|
|
169
|
+
.join("\n");
|
|
170
|
+
const log = escapeXml(daemonLogPath());
|
|
171
|
+
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
172
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
173
|
+
<plist version="1.0">
|
|
174
|
+
<dict>
|
|
175
|
+
<key>Label</key>
|
|
176
|
+
<string>${LABEL}</string>
|
|
177
|
+
<key>ProgramArguments</key>
|
|
178
|
+
<array>
|
|
179
|
+
${args}
|
|
180
|
+
</array>
|
|
181
|
+
<key>StartInterval</key>
|
|
182
|
+
<integer>${seconds}</integer>
|
|
183
|
+
<key>RunAtLoad</key>
|
|
184
|
+
<true/>
|
|
185
|
+
<key>LowPriorityIO</key>
|
|
186
|
+
<true/>
|
|
187
|
+
<key>Nice</key>
|
|
188
|
+
<integer>5</integer>
|
|
189
|
+
<key>ProcessType</key>
|
|
190
|
+
<string>Background</string>
|
|
191
|
+
<key>StandardOutPath</key>
|
|
192
|
+
<string>${log}</string>
|
|
193
|
+
<key>StandardErrorPath</key>
|
|
194
|
+
<string>${log}</string>
|
|
195
|
+
<key>EnvironmentVariables</key>
|
|
196
|
+
<dict>
|
|
197
|
+
<key>PATH</key>
|
|
198
|
+
<string>${escapeXml(schedulerPath())}</string>
|
|
199
|
+
</dict>
|
|
200
|
+
</dict>
|
|
201
|
+
</plist>
|
|
202
|
+
`;
|
|
203
|
+
}
|
|
204
|
+
export function systemdService() {
|
|
205
|
+
const [exe, ...rest] = sweepArgv();
|
|
206
|
+
return `[Unit]
|
|
207
|
+
Description=treekeeper — reclaim disk from finished agent worktrees
|
|
208
|
+
Documentation=https://github.com/yoavshmariahu/treekeeper
|
|
209
|
+
|
|
210
|
+
[Service]
|
|
211
|
+
Type=oneshot
|
|
212
|
+
Nice=5
|
|
213
|
+
IOSchedulingClass=idle
|
|
214
|
+
Environment=PATH=${schedulerPath()}
|
|
215
|
+
ExecStart=${exe} ${rest.join(" ")}
|
|
216
|
+
`;
|
|
217
|
+
}
|
|
218
|
+
export function systemdTimer(seconds) {
|
|
219
|
+
return `[Unit]
|
|
220
|
+
Description=treekeeper periodic sweep
|
|
221
|
+
|
|
222
|
+
[Timer]
|
|
223
|
+
OnBootSec=300
|
|
224
|
+
OnUnitActiveSec=${seconds}
|
|
225
|
+
AccuracySec=60
|
|
226
|
+
Persistent=true
|
|
227
|
+
|
|
228
|
+
[Install]
|
|
229
|
+
WantedBy=timers.target
|
|
230
|
+
`;
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* Service managers start jobs with a minimal PATH, which would hide `git` and
|
|
234
|
+
* `gh`. Carry the installing shell's PATH plus the usual suspects.
|
|
235
|
+
*/
|
|
236
|
+
function schedulerPath() {
|
|
237
|
+
const extra = ["/opt/homebrew/bin", "/usr/local/bin", "/usr/bin", "/bin", "/usr/sbin", "/sbin"];
|
|
238
|
+
const current = (process.env.PATH ?? "").split(":").filter((p) => p !== "");
|
|
239
|
+
const seen = new Set();
|
|
240
|
+
return [...current, ...extra].filter((p) => (seen.has(p) ? false : (seen.add(p), true))).join(":");
|
|
241
|
+
}
|
|
242
|
+
function escapeXml(s) {
|
|
243
|
+
return s
|
|
244
|
+
.replaceAll("&", "&")
|
|
245
|
+
.replaceAll("<", "<")
|
|
246
|
+
.replaceAll(">", ">")
|
|
247
|
+
.replaceAll('"', """);
|
|
248
|
+
}
|
|
249
|
+
async function readIfPresent(path) {
|
|
250
|
+
try {
|
|
251
|
+
return await readFile(path, "utf8");
|
|
252
|
+
}
|
|
253
|
+
catch {
|
|
254
|
+
return null;
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
//# sourceMappingURL=service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"service.js","sourceRoot":"","sources":["../../src/daemon/service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export interface SweepRecord {
|
|
2
|
+
at: number;
|
|
3
|
+
durationMs: number;
|
|
4
|
+
repos: number;
|
|
5
|
+
worktrees: number;
|
|
6
|
+
branches: number;
|
|
7
|
+
reclaimedKb: number;
|
|
8
|
+
failures: number;
|
|
9
|
+
}
|
|
10
|
+
export interface State {
|
|
11
|
+
version: 1;
|
|
12
|
+
lastSweep: SweepRecord | null;
|
|
13
|
+
sweeps: number;
|
|
14
|
+
totalReclaimedKb: number;
|
|
15
|
+
}
|
|
16
|
+
export declare function statePath(): string;
|
|
17
|
+
export declare function readState(): Promise<State>;
|
|
18
|
+
export declare function recordSweep(sweep: SweepRecord): Promise<void>;
|
|
19
|
+
//# sourceMappingURL=state.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../src/daemon/state.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,KAAK;IACpB,OAAO,EAAE,CAAC,CAAC;IACX,SAAS,EAAE,WAAW,GAAG,IAAI,CAAC;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,wBAAgB,SAAS,IAAI,MAAM,CAElC;AAED,wBAAsB,SAAS,IAAI,OAAO,CAAC,KAAK,CAAC,CAUhD;AAED,wBAAsB,WAAW,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAWnE"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { treekeeperHome } from "../util/paths.js";
|
|
4
|
+
export function statePath() {
|
|
5
|
+
return join(treekeeperHome(), "state.json");
|
|
6
|
+
}
|
|
7
|
+
export async function readState() {
|
|
8
|
+
try {
|
|
9
|
+
const parsed = JSON.parse(await readFile(statePath(), "utf8"));
|
|
10
|
+
if (parsed && typeof parsed === "object" && parsed.version === 1) {
|
|
11
|
+
return parsed;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
catch {
|
|
15
|
+
/* first run */
|
|
16
|
+
}
|
|
17
|
+
return { version: 1, lastSweep: null, sweeps: 0, totalReclaimedKb: 0 };
|
|
18
|
+
}
|
|
19
|
+
export async function recordSweep(sweep) {
|
|
20
|
+
const state = await readState();
|
|
21
|
+
state.lastSweep = sweep;
|
|
22
|
+
state.sweeps += 1;
|
|
23
|
+
state.totalReclaimedKb += sweep.reclaimedKb;
|
|
24
|
+
try {
|
|
25
|
+
await mkdir(treekeeperHome(), { recursive: true });
|
|
26
|
+
await writeFile(statePath(), JSON.stringify(state, null, 2) + "\n");
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
/* a missing state file only costs a status line */
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=state.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state.js","sourceRoot":"","sources":["../../src/daemon/state.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC9D,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAmBlD,MAAM,UAAU,SAAS;IACvB,OAAO,IAAI,CAAC,cAAc,EAAE,EAAE,YAAY,CAAC,CAAC;AAC9C,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,SAAS;IAC7B,IAAI,CAAC;QACH,MAAM,MAAM,GAAY,IAAI,CAAC,KAAK,CAAC,MAAM,QAAQ,CAAC,SAAS,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC;QACxE,IAAI,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAK,MAAgB,CAAC,OAAO,KAAK,CAAC,EAAE,CAAC;YAC5E,OAAO,MAAe,CAAC;QACzB,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,eAAe;IACjB,CAAC;IACD,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,EAAE,gBAAgB,EAAE,CAAC,EAAE,CAAC;AACzE,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,KAAkB;IAClD,MAAM,KAAK,GAAG,MAAM,SAAS,EAAE,CAAC;IAChC,KAAK,CAAC,SAAS,GAAG,KAAK,CAAC;IACxB,KAAK,CAAC,MAAM,IAAI,CAAC,CAAC;IAClB,KAAK,CAAC,gBAAgB,IAAI,KAAK,CAAC,WAAW,CAAC;IAC5C,IAAI,CAAC;QACH,MAAM,KAAK,CAAC,cAAc,EAAE,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACnD,MAAM,SAAS,CAAC,SAAS,EAAE,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IACtE,CAAC;IAAC,MAAM,CAAC;QACP,mDAAmD;IACrD,CAAC;AACH,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Programmatic entry point, for harnesses that would rather call treekeeper
|
|
3
|
+
* in-process than shell out to the CLI.
|
|
4
|
+
*
|
|
5
|
+
* import { loadConfig, createForge, discoverRepos, buildPlan, applyPlan } from "@yoavsh/treekeeper";
|
|
6
|
+
*/
|
|
7
|
+
export { loadConfig, loadRepoConfig, defaultConfig, globalConfigPath } from "./core/config.js";
|
|
8
|
+
export type { Config, SessionConfig, ArchiveConfig, DirtyPolicy } from "./core/config.js";
|
|
9
|
+
export { buildPlan, policyFromConfig, reclaimable, mergeStatus } from "./core/plan.js";
|
|
10
|
+
export type { Plan, PlanOptions, PlanSummary, RepoPlan, WorktreeCandidate, BranchCandidate, } from "./core/plan.js";
|
|
11
|
+
export { decideWorktree, decideBranch } from "./core/decide.js";
|
|
12
|
+
export type { Verdict, Policy, WorktreeFacts, BranchFacts, MergeStatus, Risk, } from "./core/decide.js";
|
|
13
|
+
export { applyPlan } from "./core/apply.js";
|
|
14
|
+
export type { ApplyOptions, ApplyResult, Removal, Failure } from "./core/apply.js";
|
|
15
|
+
export { archiveWork, listArchives, pruneArchives } from "./core/archive.js";
|
|
16
|
+
export type { ArchiveRecord } from "./core/archive.js";
|
|
17
|
+
export { createForge, selectPr } from "./core/forge.js";
|
|
18
|
+
export type { Forge, PrRef, PrIndex, PrState } from "./core/forge.js";
|
|
19
|
+
export { discoverRepos, reposFromPaths } from "./core/scan.js";
|
|
20
|
+
export { createActivityContext, detectActivity, isActive } from "./core/sessions.js";
|
|
21
|
+
export type { ActivityContext, ActivityHit } from "./core/sessions.js";
|
|
22
|
+
export { renderPlan, renderApply, summaryLine } from "./core/render.js";
|
|
23
|
+
export { Logger } from "./util/log.js";
|
|
24
|
+
export { parseDuration, formatDuration } from "./util/time.js";
|
|
25
|
+
export { main as cli } from "./cli.js";
|
|
26
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAC/F,YAAY,EAAE,MAAM,EAAE,aAAa,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAE1F,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AACvF,YAAY,EACV,IAAI,EAAE,WAAW,EAAE,WAAW,EAAE,QAAQ,EAAE,iBAAiB,EAAE,eAAe,GAC7E,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAChE,YAAY,EACV,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,WAAW,EAAE,WAAW,EAAE,IAAI,GAC/D,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAEnF,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAC7E,YAAY,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAEvD,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AACxD,YAAY,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAEtE,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAC/D,OAAO,EAAE,qBAAqB,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AACrF,YAAY,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEvE,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACxE,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AACvC,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAC/D,OAAO,EAAE,IAAI,IAAI,GAAG,EAAE,MAAM,UAAU,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Programmatic entry point, for harnesses that would rather call treekeeper
|
|
3
|
+
* in-process than shell out to the CLI.
|
|
4
|
+
*
|
|
5
|
+
* import { loadConfig, createForge, discoverRepos, buildPlan, applyPlan } from "@yoavsh/treekeeper";
|
|
6
|
+
*/
|
|
7
|
+
export { loadConfig, loadRepoConfig, defaultConfig, globalConfigPath } from "./core/config.js";
|
|
8
|
+
export { buildPlan, policyFromConfig, reclaimable, mergeStatus } from "./core/plan.js";
|
|
9
|
+
export { decideWorktree, decideBranch } from "./core/decide.js";
|
|
10
|
+
export { applyPlan } from "./core/apply.js";
|
|
11
|
+
export { archiveWork, listArchives, pruneArchives } from "./core/archive.js";
|
|
12
|
+
export { createForge, selectPr } from "./core/forge.js";
|
|
13
|
+
export { discoverRepos, reposFromPaths } from "./core/scan.js";
|
|
14
|
+
export { createActivityContext, detectActivity, isActive } from "./core/sessions.js";
|
|
15
|
+
export { renderPlan, renderApply, summaryLine } from "./core/render.js";
|
|
16
|
+
export { Logger } from "./util/log.js";
|
|
17
|
+
export { parseDuration, formatDuration } from "./util/time.js";
|
|
18
|
+
export { main as cli } from "./cli.js";
|
|
19
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAG/F,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAKvF,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAKhE,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAG5C,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAG7E,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAGxD,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAC/D,OAAO,EAAE,qBAAqB,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAGrF,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACxE,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AACvC,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAC/D,OAAO,EAAE,IAAI,IAAI,GAAG,EAAE,MAAM,UAAU,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bytes.d.ts","sourceRoot":"","sources":["../../src/util/bytes.ts"],"names":[],"mappings":"AAAA,mEAAmE;AACnE,wBAAgB,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAK3C;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEjD"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/** Kilobytes (as reported by `du -sk`) to a short human string. */
|
|
2
|
+
export function formatKb(kb) {
|
|
3
|
+
if (!Number.isFinite(kb) || kb < 0)
|
|
4
|
+
return "?";
|
|
5
|
+
if (kb >= 1024 * 1024)
|
|
6
|
+
return `${(kb / (1024 * 1024)).toFixed(1)}G`;
|
|
7
|
+
if (kb >= 1024)
|
|
8
|
+
return `${Math.round(kb / 1024)}M`;
|
|
9
|
+
return `${Math.round(kb)}K`;
|
|
10
|
+
}
|
|
11
|
+
export function formatBytes(bytes) {
|
|
12
|
+
return formatKb(bytes / 1024);
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=bytes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bytes.js","sourceRoot":"","sources":["../../src/util/bytes.ts"],"names":[],"mappings":"AAAA,mEAAmE;AACnE,MAAM,UAAU,QAAQ,CAAC,EAAU;IACjC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,GAAG,CAAC;QAAE,OAAO,GAAG,CAAC;IAC/C,IAAI,EAAE,IAAI,IAAI,GAAG,IAAI;QAAE,OAAO,GAAG,CAAC,EAAE,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC;IACpE,IAAI,EAAE,IAAI,IAAI;QAAE,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC;IACnD,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC;AAC9B,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,KAAa;IACvC,OAAO,QAAQ,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC;AAChC,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export declare const color: {
|
|
2
|
+
enabled: boolean;
|
|
3
|
+
bold: (s: string | number) => string;
|
|
4
|
+
dim: (s: string | number) => string;
|
|
5
|
+
red: (s: string | number) => string;
|
|
6
|
+
green: (s: string | number) => string;
|
|
7
|
+
yellow: (s: string | number) => string;
|
|
8
|
+
blue: (s: string | number) => string;
|
|
9
|
+
magenta: (s: string | number) => string;
|
|
10
|
+
cyan: (s: string | number) => string;
|
|
11
|
+
gray: (s: string | number) => string;
|
|
12
|
+
};
|
|
13
|
+
/** Visible width, ignoring ANSI escapes, so columns line up when colour is on. */
|
|
14
|
+
export declare function visibleWidth(s: string): number;
|
|
15
|
+
export declare function padEndVisible(s: string, width: number): string;
|
|
16
|
+
//# sourceMappingURL=color.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"color.d.ts","sourceRoot":"","sources":["../../src/util/color.ts"],"names":[],"mappings":"AAUA,eAAO,MAAM,KAAK;;cAHsC,MAAM,GAAG,MAAM;aAAf,MAAM,GAAG,MAAM;aAAf,MAAM,GAAG,MAAM;eAAf,MAAM,GAAG,MAAM;gBAAf,MAAM,GAAG,MAAM;cAAf,MAAM,GAAG,MAAM;iBAAf,MAAM,GAAG,MAAM;cAAf,MAAM,GAAG,MAAM;cAAf,MAAM,GAAG,MAAM;CActE,CAAC;AAEF,kFAAkF;AAClF,wBAAgB,YAAY,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAG9C;AAED,wBAAgB,aAAa,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAG9D"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
const enabled = (() => {
|
|
2
|
+
if (process.env.NO_COLOR !== undefined && process.env.NO_COLOR !== "")
|
|
3
|
+
return false;
|
|
4
|
+
if (process.env.FORCE_COLOR !== undefined && process.env.FORCE_COLOR !== "0")
|
|
5
|
+
return true;
|
|
6
|
+
if (process.env.TERM === "dumb")
|
|
7
|
+
return false;
|
|
8
|
+
return Boolean(process.stdout.isTTY);
|
|
9
|
+
})();
|
|
10
|
+
const wrap = (open, close = "\u001b[0m") => (s) => enabled ? `${open}${s}${close}` : String(s);
|
|
11
|
+
export const color = {
|
|
12
|
+
enabled,
|
|
13
|
+
bold: wrap("\u001b[1m"),
|
|
14
|
+
dim: wrap("\u001b[2m"),
|
|
15
|
+
red: wrap("\u001b[31m"),
|
|
16
|
+
green: wrap("\u001b[32m"),
|
|
17
|
+
yellow: wrap("\u001b[33m"),
|
|
18
|
+
blue: wrap("\u001b[34m"),
|
|
19
|
+
magenta: wrap("\u001b[35m"),
|
|
20
|
+
cyan: wrap("\u001b[36m"),
|
|
21
|
+
gray: wrap("\u001b[90m"),
|
|
22
|
+
};
|
|
23
|
+
/** Visible width, ignoring ANSI escapes, so columns line up when colour is on. */
|
|
24
|
+
export function visibleWidth(s) {
|
|
25
|
+
// eslint-disable-next-line no-control-regex
|
|
26
|
+
return s.replace(/\u001b\[[0-9;]*m/g, "").length;
|
|
27
|
+
}
|
|
28
|
+
export function padEndVisible(s, width) {
|
|
29
|
+
const pad = width - visibleWidth(s);
|
|
30
|
+
return pad > 0 ? s + " ".repeat(pad) : s;
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=color.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"color.js","sourceRoot":"","sources":["../../src/util/color.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,GAAG,CAAC,GAAG,EAAE;IACpB,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,SAAS,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,EAAE;QAAE,OAAO,KAAK,CAAC;IACpF,IAAI,OAAO,CAAC,GAAG,CAAC,WAAW,KAAK,SAAS,IAAI,OAAO,CAAC,GAAG,CAAC,WAAW,KAAK,GAAG;QAAE,OAAO,IAAI,CAAC;IAC1F,IAAI,OAAO,CAAC,GAAG,CAAC,IAAI,KAAK,MAAM;QAAE,OAAO,KAAK,CAAC;IAC9C,OAAO,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AACvC,CAAC,CAAC,EAAE,CAAC;AAEL,MAAM,IAAI,GAAG,CAAC,IAAY,EAAE,KAAK,GAAG,WAAW,EAAE,EAAE,CAAC,CAAC,CAAkB,EAAE,EAAE,CACzE,OAAO,CAAC,CAAC,CAAC,GAAG,IAAI,GAAG,CAAC,GAAG,KAAK,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AAE9C,MAAM,CAAC,MAAM,KAAK,GAAG;IACnB,OAAO;IACP,IAAI,EAAE,IAAI,CAAC,WAAW,CAAC;IACvB,GAAG,EAAE,IAAI,CAAC,WAAW,CAAC;IACtB,GAAG,EAAE,IAAI,CAAC,YAAY,CAAC;IACvB,KAAK,EAAE,IAAI,CAAC,YAAY,CAAC;IACzB,MAAM,EAAE,IAAI,CAAC,YAAY,CAAC;IAC1B,IAAI,EAAE,IAAI,CAAC,YAAY,CAAC;IACxB,OAAO,EAAE,IAAI,CAAC,YAAY,CAAC;IAC3B,IAAI,EAAE,IAAI,CAAC,YAAY,CAAC;IACxB,IAAI,EAAE,IAAI,CAAC,YAAY,CAAC;CACzB,CAAC;AAEF,kFAAkF;AAClF,MAAM,UAAU,YAAY,CAAC,CAAS;IACpC,4CAA4C;IAC5C,OAAO,CAAC,CAAC,OAAO,CAAC,mBAAmB,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC;AACnD,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,CAAS,EAAE,KAAa;IACpD,MAAM,GAAG,GAAG,KAAK,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC;IACpC,OAAO,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC3C,CAAC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export interface RunResult {
|
|
2
|
+
code: number;
|
|
3
|
+
stdout: string;
|
|
4
|
+
stderr: string;
|
|
5
|
+
/** True when the binary itself could not be launched (not installed, EACCES, timeout). */
|
|
6
|
+
failedToStart: boolean;
|
|
7
|
+
}
|
|
8
|
+
export interface RunOptions {
|
|
9
|
+
cwd?: string;
|
|
10
|
+
timeoutMs?: number;
|
|
11
|
+
env?: NodeJS.ProcessEnv;
|
|
12
|
+
maxBuffer?: number;
|
|
13
|
+
input?: string;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Run a command without ever throwing. Every caller in treekeeper has to make a
|
|
17
|
+
* decision from the exit code (a missing `gh`, a repo without a remote, a branch
|
|
18
|
+
* that vanished), so an exception-based API would just mean try/catch everywhere.
|
|
19
|
+
*/
|
|
20
|
+
export declare function run(cmd: string, args: string[], opts?: RunOptions): Promise<RunResult>;
|
|
21
|
+
/** stdout trimmed on success, `null` on any failure. */
|
|
22
|
+
export declare function runOk(cmd: string, args: string[], opts?: RunOptions): Promise<string | null>;
|
|
23
|
+
/** stdout split into non-empty trimmed lines; `[]` on failure. */
|
|
24
|
+
export declare function runLines(cmd: string, args: string[], opts?: RunOptions): Promise<string[]>;
|
|
25
|
+
/** Whether an executable is on PATH. Cached for the life of the process. */
|
|
26
|
+
export declare function have(cmd: string): Promise<boolean>;
|
|
27
|
+
//# sourceMappingURL=exec.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"exec.d.ts","sourceRoot":"","sources":["../../src/util/exec.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,0FAA0F;IAC1F,aAAa,EAAE,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,UAAU;IACzB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;GAIG;AACH,wBAAgB,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,IAAI,GAAE,UAAe,GAAG,OAAO,CAAC,SAAS,CAAC,CA8B1F;AAED,wDAAwD;AACxD,wBAAsB,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,IAAI,GAAE,UAAe,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAGtG;AAED,kEAAkE;AAClE,wBAAsB,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,IAAI,GAAE,UAAe,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAIpG;AAID,4EAA4E;AAC5E,wBAAsB,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAQxD"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { execFile } from "node:child_process";
|
|
2
|
+
/**
|
|
3
|
+
* Run a command without ever throwing. Every caller in treekeeper has to make a
|
|
4
|
+
* decision from the exit code (a missing `gh`, a repo without a remote, a branch
|
|
5
|
+
* that vanished), so an exception-based API would just mean try/catch everywhere.
|
|
6
|
+
*/
|
|
7
|
+
export function run(cmd, args, opts = {}) {
|
|
8
|
+
return new Promise((resolve) => {
|
|
9
|
+
const child = execFile(cmd, args, {
|
|
10
|
+
cwd: opts.cwd,
|
|
11
|
+
timeout: opts.timeoutMs ?? 60_000,
|
|
12
|
+
maxBuffer: opts.maxBuffer ?? 64 * 1024 * 1024,
|
|
13
|
+
env: opts.env ?? process.env,
|
|
14
|
+
encoding: "utf8",
|
|
15
|
+
}, (err, stdout, stderr) => {
|
|
16
|
+
if (!err) {
|
|
17
|
+
resolve({ code: 0, stdout, stderr, failedToStart: false });
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
const code = typeof err.code === "number" ? err.code : null;
|
|
21
|
+
resolve({
|
|
22
|
+
code: code ?? 127,
|
|
23
|
+
stdout: stdout ?? "",
|
|
24
|
+
stderr: stderr ?? String(err.message ?? ""),
|
|
25
|
+
failedToStart: code === null,
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
if (opts.input !== undefined) {
|
|
29
|
+
child.stdin?.end(opts.input);
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
/** stdout trimmed on success, `null` on any failure. */
|
|
34
|
+
export async function runOk(cmd, args, opts = {}) {
|
|
35
|
+
const r = await run(cmd, args, opts);
|
|
36
|
+
return r.code === 0 ? r.stdout.trim() : null;
|
|
37
|
+
}
|
|
38
|
+
/** stdout split into non-empty trimmed lines; `[]` on failure. */
|
|
39
|
+
export async function runLines(cmd, args, opts = {}) {
|
|
40
|
+
const out = await runOk(cmd, args, opts);
|
|
41
|
+
if (out === null || out === "")
|
|
42
|
+
return [];
|
|
43
|
+
return out.split("\n").map((l) => l.trim()).filter((l) => l.length > 0);
|
|
44
|
+
}
|
|
45
|
+
const haveCache = new Map();
|
|
46
|
+
/** Whether an executable is on PATH. Cached for the life of the process. */
|
|
47
|
+
export async function have(cmd) {
|
|
48
|
+
const cached = haveCache.get(cmd);
|
|
49
|
+
if (cached !== undefined)
|
|
50
|
+
return cached;
|
|
51
|
+
const probe = process.platform === "win32" ? "where" : "which";
|
|
52
|
+
const r = await run(probe, [cmd], { timeoutMs: 5_000 });
|
|
53
|
+
const ok = r.code === 0 && r.stdout.trim().length > 0;
|
|
54
|
+
haveCache.set(cmd, ok);
|
|
55
|
+
return ok;
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=exec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"exec.js","sourceRoot":"","sources":["../../src/util/exec.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { LogLevel } from "../core/config.js";
|
|
2
|
+
export type LogFields = Record<string, unknown>;
|
|
3
|
+
export interface LoggerOptions {
|
|
4
|
+
level?: LogLevel;
|
|
5
|
+
/** JSONL destination. Omit to log to the console only. */
|
|
6
|
+
file?: string;
|
|
7
|
+
/** Suppress console output (the log file still receives everything). */
|
|
8
|
+
quiet?: boolean;
|
|
9
|
+
}
|
|
10
|
+
export declare class Logger {
|
|
11
|
+
readonly level: LogLevel;
|
|
12
|
+
private readonly file;
|
|
13
|
+
private readonly quiet;
|
|
14
|
+
private fileBroken;
|
|
15
|
+
constructor(opts?: LoggerOptions);
|
|
16
|
+
debug(msg: string, fields?: LogFields): void;
|
|
17
|
+
info(msg: string, fields?: LogFields): void;
|
|
18
|
+
warn(msg: string, fields?: LogFields): void;
|
|
19
|
+
error(msg: string, fields?: LogFields): void;
|
|
20
|
+
/**
|
|
21
|
+
* A durable record of something treekeeper *did* (or decided not to do).
|
|
22
|
+
* Always written to the log file regardless of level, because this is the
|
|
23
|
+
* audit trail a developer reads after a worktree disappears.
|
|
24
|
+
*/
|
|
25
|
+
event(type: string, fields?: LogFields): void;
|
|
26
|
+
private emit;
|
|
27
|
+
private write;
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=log.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"log.d.ts","sourceRoot":"","sources":["../../src/util/log.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAOlD,MAAM,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAEhD,MAAM,WAAW,aAAa;IAC5B,KAAK,CAAC,EAAE,QAAQ,CAAC;IACjB,0DAA0D;IAC1D,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,wEAAwE;IACxE,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,qBAAa,MAAM;IACjB,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC;IACzB,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAqB;IAC1C,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAU;IAChC,OAAO,CAAC,UAAU,CAAS;gBAEf,IAAI,GAAE,aAAkB;IAMpC,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,SAAS,GAAG,IAAI;IAG5C,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,SAAS,GAAG,IAAI;IAG3C,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,SAAS,GAAG,IAAI;IAG3C,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,SAAS,GAAG,IAAI;IAI5C;;;;OAIG;IACH,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,GAAE,SAAc,GAAG,IAAI;IAIjD,OAAO,CAAC,IAAI;IAeZ,OAAO,CAAC,KAAK;CAad"}
|