@lesscap/baton-cli 0.3.2 → 0.3.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/baton.mjs +194 -19
- package/package.json +1 -1
package/dist/baton.mjs
CHANGED
|
@@ -1137,6 +1137,17 @@ var fmtWorker = (w) => {
|
|
|
1137
1137
|
const offline = w.connected === false ? " [offline]" : "";
|
|
1138
1138
|
return `W-${w.id} ${w.name} ${w.hostname}${offline}`;
|
|
1139
1139
|
};
|
|
1140
|
+
var fmtInterval = (sec) => {
|
|
1141
|
+
if (sec % 86400 === 0) return `${sec / 86400}d`;
|
|
1142
|
+
if (sec % 3600 === 0) return `${sec / 3600}h`;
|
|
1143
|
+
if (sec % 60 === 0) return `${sec / 60}m`;
|
|
1144
|
+
return `${sec}s`;
|
|
1145
|
+
};
|
|
1146
|
+
var fmtLoop = (l) => {
|
|
1147
|
+
const label = l.name ? `${l.name} ` : "";
|
|
1148
|
+
const last = l.lastStatus ? ` last:${l.lastStatus}` : "";
|
|
1149
|
+
return `${l.id} [${l.enabled ? "on" : "off"}] ${label}every ${fmtInterval(l.intervalSec)}${last} "${l.message}"`;
|
|
1150
|
+
};
|
|
1140
1151
|
var renderOne = (item, fmt, json) => json ? toJson(item) : fmt(item);
|
|
1141
1152
|
var renderList = (items, fmt, json) => {
|
|
1142
1153
|
if (json) return toJson(items);
|
|
@@ -1193,6 +1204,20 @@ var primeLogin = (baseUrl) => {
|
|
|
1193
1204
|
);
|
|
1194
1205
|
};
|
|
1195
1206
|
|
|
1207
|
+
// src/client/loops.ts
|
|
1208
|
+
var loopsClient = (baseUrl) => {
|
|
1209
|
+
const u = (p) => `${baseUrl}${p}`;
|
|
1210
|
+
return {
|
|
1211
|
+
create: (sessionId, input) => request(u(`/sessions/${sessionId}/loops`), { method: "POST", body: input }),
|
|
1212
|
+
listBySession: (sessionId) => request(u(`/sessions/${sessionId}/loops`), { method: "GET" }),
|
|
1213
|
+
get: (id) => request(u(`/loops/${id}`), { method: "GET" }),
|
|
1214
|
+
update: (id, input) => request(u(`/loops/${id}`), { method: "PATCH", body: input }),
|
|
1215
|
+
remove: async (id) => {
|
|
1216
|
+
await request(u(`/loops/${id}`), { method: "DELETE" });
|
|
1217
|
+
}
|
|
1218
|
+
};
|
|
1219
|
+
};
|
|
1220
|
+
|
|
1196
1221
|
// src/client/projects.ts
|
|
1197
1222
|
var projectClient = (baseUrl) => {
|
|
1198
1223
|
const u = (p) => `${baseUrl}${p}`;
|
|
@@ -1368,6 +1393,7 @@ var clientFromBase = (baseUrl) => ({
|
|
|
1368
1393
|
requirements: requirementClient(baseUrl),
|
|
1369
1394
|
tasks: taskClient(baseUrl),
|
|
1370
1395
|
sessions: sessionsClient(baseUrl),
|
|
1396
|
+
loops: loopsClient(baseUrl),
|
|
1371
1397
|
workers: workersClient(baseUrl)
|
|
1372
1398
|
});
|
|
1373
1399
|
var BOUNDARY_EVENTS = /* @__PURE__ */ new Set([
|
|
@@ -1441,6 +1467,13 @@ var parseWorkerHandle = (handle) => {
|
|
|
1441
1467
|
return m ? Number(m[1]) : null;
|
|
1442
1468
|
};
|
|
1443
1469
|
var splitCsv = (s) => s ? s.split(",").map((x) => x.trim()).filter(Boolean) : void 0;
|
|
1470
|
+
var parseDuration = (s) => {
|
|
1471
|
+
const m = s.trim().match(/^(\d+)\s*([smhd]?)$/);
|
|
1472
|
+
if (!m) throw new Error(`bad interval "${s}" \u2014 use e.g. 90s, 30m, 2h, 1d`);
|
|
1473
|
+
const n = Number(m[1]);
|
|
1474
|
+
const mult = m[2] === "d" ? 86400 : m[2] === "h" ? 3600 : m[2] === "m" ? 60 : 1;
|
|
1475
|
+
return n * mult;
|
|
1476
|
+
};
|
|
1444
1477
|
|
|
1445
1478
|
// src/commands/channel/close.ts
|
|
1446
1479
|
var closeCommand = defineCommand({
|
|
@@ -1962,6 +1995,163 @@ var init = defineCommand({
|
|
|
1962
1995
|
}
|
|
1963
1996
|
});
|
|
1964
1997
|
|
|
1998
|
+
// src/commands/session/shared.ts
|
|
1999
|
+
import { homedir } from "node:os";
|
|
2000
|
+
import { join as join3 } from "node:path";
|
|
2001
|
+
var defaultWorktreeDir = (env = process.env) => env.BATON_WORKTREE_DIR ?? join3(env.XDG_DATA_HOME ?? join3(env.HOME ?? homedir(), ".local/share"), "baton", "worktrees");
|
|
2002
|
+
var slug = (s) => s.toLowerCase().replace(/[^a-z0-9_-]+/g, "-");
|
|
2003
|
+
var resolveSession = async (client, projectId, handle) => {
|
|
2004
|
+
const asInt = Number(handle);
|
|
2005
|
+
if (Number.isInteger(asInt) && asInt > 0) {
|
|
2006
|
+
const byId = await client.sessions.get(asInt).catch(() => null);
|
|
2007
|
+
if (byId) return { id: byId.id, name: byId.name };
|
|
2008
|
+
}
|
|
2009
|
+
const byName = await client.sessions.findByName(projectId, handle);
|
|
2010
|
+
if (byName) return { id: byName.id, name: byName.name };
|
|
2011
|
+
throw new Error(`session "${handle}" not found in project ${projectId}`);
|
|
2012
|
+
};
|
|
2013
|
+
|
|
2014
|
+
// src/commands/loop/create.ts
|
|
2015
|
+
var loopCreateCommand = defineCommand({
|
|
2016
|
+
meta: { name: "create", description: "create a recurring scheduled message on a session" },
|
|
2017
|
+
args: {
|
|
2018
|
+
session: { type: "positional", required: true, description: "session int id or name" },
|
|
2019
|
+
message: {
|
|
2020
|
+
type: "string",
|
|
2021
|
+
required: true,
|
|
2022
|
+
description: "message sent to the session each beat"
|
|
2023
|
+
},
|
|
2024
|
+
every: {
|
|
2025
|
+
type: "string",
|
|
2026
|
+
required: true,
|
|
2027
|
+
description: "interval: 90s / 30m / 2h / 1d (min 30s)"
|
|
2028
|
+
},
|
|
2029
|
+
name: { type: "string", description: "optional label" },
|
|
2030
|
+
off: { type: "boolean", description: "create paused (disabled)" },
|
|
2031
|
+
project: { type: "string", description: "project id (overrides .baton.json)" },
|
|
2032
|
+
...common
|
|
2033
|
+
},
|
|
2034
|
+
run: async ({ args }) => {
|
|
2035
|
+
const c = clientFor(args);
|
|
2036
|
+
const session2 = await resolveSession(c, resolveProjectId(args), args.session);
|
|
2037
|
+
const loop2 = await c.loops.create(session2.id, {
|
|
2038
|
+
message: args.message,
|
|
2039
|
+
intervalSec: parseDuration(args.every),
|
|
2040
|
+
name: args.name,
|
|
2041
|
+
enabled: !args.off
|
|
2042
|
+
});
|
|
2043
|
+
console.log(renderOne(loop2, fmtLoop, Boolean(args.json)));
|
|
2044
|
+
}
|
|
2045
|
+
});
|
|
2046
|
+
|
|
2047
|
+
// src/commands/loop/disable.ts
|
|
2048
|
+
var loopDisableCommand = defineCommand({
|
|
2049
|
+
meta: { name: "disable", description: "disable (pause) a loop" },
|
|
2050
|
+
args: {
|
|
2051
|
+
loop: { type: "positional", required: true, description: "loop int id" },
|
|
2052
|
+
...common
|
|
2053
|
+
},
|
|
2054
|
+
run: async ({ args }) => {
|
|
2055
|
+
const c = clientFor(args);
|
|
2056
|
+
const loop2 = await c.loops.update(Number(args.loop), { enabled: false });
|
|
2057
|
+
console.log(renderOne(loop2, fmtLoop, Boolean(args.json)));
|
|
2058
|
+
}
|
|
2059
|
+
});
|
|
2060
|
+
|
|
2061
|
+
// src/commands/loop/enable.ts
|
|
2062
|
+
var loopEnableCommand = defineCommand({
|
|
2063
|
+
meta: { name: "enable", description: "enable (resume) a loop" },
|
|
2064
|
+
args: {
|
|
2065
|
+
loop: { type: "positional", required: true, description: "loop int id" },
|
|
2066
|
+
...common
|
|
2067
|
+
},
|
|
2068
|
+
run: async ({ args }) => {
|
|
2069
|
+
const c = clientFor(args);
|
|
2070
|
+
const loop2 = await c.loops.update(Number(args.loop), { enabled: true });
|
|
2071
|
+
console.log(renderOne(loop2, fmtLoop, Boolean(args.json)));
|
|
2072
|
+
}
|
|
2073
|
+
});
|
|
2074
|
+
|
|
2075
|
+
// src/commands/loop/get.ts
|
|
2076
|
+
var loopGetCommand = defineCommand({
|
|
2077
|
+
meta: { name: "get", description: "show one loop" },
|
|
2078
|
+
args: {
|
|
2079
|
+
loop: { type: "positional", required: true, description: "loop int id" },
|
|
2080
|
+
...common
|
|
2081
|
+
},
|
|
2082
|
+
run: async ({ args }) => {
|
|
2083
|
+
const c = clientFor(args);
|
|
2084
|
+
const loop2 = await c.loops.get(Number(args.loop));
|
|
2085
|
+
console.log(renderOne(loop2, fmtLoop, Boolean(args.json)));
|
|
2086
|
+
}
|
|
2087
|
+
});
|
|
2088
|
+
|
|
2089
|
+
// src/commands/loop/ls.ts
|
|
2090
|
+
var loopLsCommand = defineCommand({
|
|
2091
|
+
meta: { name: "ls", description: "list a session's loops" },
|
|
2092
|
+
args: {
|
|
2093
|
+
session: { type: "positional", required: true, description: "session int id or name" },
|
|
2094
|
+
project: { type: "string", description: "project id (overrides .baton.json)" },
|
|
2095
|
+
...common
|
|
2096
|
+
},
|
|
2097
|
+
run: async ({ args }) => {
|
|
2098
|
+
const c = clientFor(args);
|
|
2099
|
+
const session2 = await resolveSession(c, resolveProjectId(args), args.session);
|
|
2100
|
+
const loops = await c.loops.listBySession(session2.id);
|
|
2101
|
+
console.log(renderList(loops, fmtLoop, Boolean(args.json)));
|
|
2102
|
+
}
|
|
2103
|
+
});
|
|
2104
|
+
|
|
2105
|
+
// src/commands/loop/rm.ts
|
|
2106
|
+
var loopRmCommand = defineCommand({
|
|
2107
|
+
meta: { name: "rm", description: "delete a loop" },
|
|
2108
|
+
args: {
|
|
2109
|
+
loop: { type: "positional", required: true, description: "loop int id" },
|
|
2110
|
+
...common
|
|
2111
|
+
},
|
|
2112
|
+
run: async ({ args }) => {
|
|
2113
|
+
const c = clientFor(args);
|
|
2114
|
+
const id = Number(args.loop);
|
|
2115
|
+
await c.loops.remove(id);
|
|
2116
|
+
console.log(removed("loop", id, Boolean(args.json)));
|
|
2117
|
+
}
|
|
2118
|
+
});
|
|
2119
|
+
|
|
2120
|
+
// src/commands/loop/set.ts
|
|
2121
|
+
var loopSetCommand = defineCommand({
|
|
2122
|
+
meta: { name: "set", description: "update a loop (message / interval / name)" },
|
|
2123
|
+
args: {
|
|
2124
|
+
loop: { type: "positional", required: true, description: "loop int id" },
|
|
2125
|
+
message: { type: "string", description: "new message" },
|
|
2126
|
+
every: { type: "string", description: "new interval: 90s / 30m / 2h / 1d" },
|
|
2127
|
+
name: { type: "string", description: "new label" },
|
|
2128
|
+
...common
|
|
2129
|
+
},
|
|
2130
|
+
run: async ({ args }) => {
|
|
2131
|
+
const c = clientFor(args);
|
|
2132
|
+
const patch2 = {};
|
|
2133
|
+
if (args.message !== void 0) patch2.message = args.message;
|
|
2134
|
+
if (args.every !== void 0 && args.every !== "") patch2.intervalSec = parseDuration(args.every);
|
|
2135
|
+
if (args.name !== void 0) patch2.name = args.name;
|
|
2136
|
+
const loop2 = await c.loops.update(Number(args.loop), patch2);
|
|
2137
|
+
console.log(renderOne(loop2, fmtLoop, Boolean(args.json)));
|
|
2138
|
+
}
|
|
2139
|
+
});
|
|
2140
|
+
|
|
2141
|
+
// src/commands/loop.ts
|
|
2142
|
+
var loop = defineCommand({
|
|
2143
|
+
meta: { name: "loop", description: "recurring scheduled messages that wake a session" },
|
|
2144
|
+
subCommands: {
|
|
2145
|
+
create: loopCreateCommand,
|
|
2146
|
+
ls: loopLsCommand,
|
|
2147
|
+
get: loopGetCommand,
|
|
2148
|
+
set: loopSetCommand,
|
|
2149
|
+
enable: loopEnableCommand,
|
|
2150
|
+
disable: loopDisableCommand,
|
|
2151
|
+
rm: loopRmCommand
|
|
2152
|
+
}
|
|
2153
|
+
});
|
|
2154
|
+
|
|
1965
2155
|
// src/commands/project.ts
|
|
1966
2156
|
var createProject = (c, input, json) => c.projects.create(input).then((p) => renderOne(p, fmtProject, json));
|
|
1967
2157
|
var listProjects = (c, workspaceId, json) => c.projects.listByWorkspace(workspaceId).then((ps) => renderList(ps, fmtProject, json));
|
|
@@ -2039,7 +2229,7 @@ var project = defineCommand({
|
|
|
2039
2229
|
// src/commands/relay.ts
|
|
2040
2230
|
import { mkdirSync as mkdirSync2, readFileSync as readFileSync3, writeFileSync as writeFileSync4 } from "node:fs";
|
|
2041
2231
|
import { tmpdir as tmpdir2 } from "node:os";
|
|
2042
|
-
import { join as
|
|
2232
|
+
import { join as join4 } from "node:path";
|
|
2043
2233
|
|
|
2044
2234
|
// src/client/relay.ts
|
|
2045
2235
|
var relayClient = (baseUrl) => {
|
|
@@ -2167,11 +2357,11 @@ var listenCommand2 = defineCommand({
|
|
|
2167
2357
|
process.stdout.write(`${JSON.stringify(o)}
|
|
2168
2358
|
`);
|
|
2169
2359
|
};
|
|
2170
|
-
const spillDir =
|
|
2360
|
+
const spillDir = join4(tmpdir2(), "hotline", args.channel);
|
|
2171
2361
|
mkdirSync2(spillDir, { recursive: true });
|
|
2172
2362
|
const surface = (m) => {
|
|
2173
2363
|
const text = typeof m.text === "string" ? m.text : "";
|
|
2174
|
-
const file =
|
|
2364
|
+
const file = join4(spillDir, `${m.seq}.txt`);
|
|
2175
2365
|
writeFileSync4(file, text);
|
|
2176
2366
|
const truncated = text.length > PREVIEW2;
|
|
2177
2367
|
emit({
|
|
@@ -2325,22 +2515,6 @@ var requirement = defineCommand({
|
|
|
2325
2515
|
}
|
|
2326
2516
|
});
|
|
2327
2517
|
|
|
2328
|
-
// src/commands/session/shared.ts
|
|
2329
|
-
import { homedir } from "node:os";
|
|
2330
|
-
import { join as join4 } from "node:path";
|
|
2331
|
-
var defaultWorktreeDir = (env = process.env) => env.BATON_WORKTREE_DIR ?? join4(env.XDG_DATA_HOME ?? join4(env.HOME ?? homedir(), ".local/share"), "baton", "worktrees");
|
|
2332
|
-
var slug = (s) => s.toLowerCase().replace(/[^a-z0-9_-]+/g, "-");
|
|
2333
|
-
var resolveSession = async (client, projectId, handle) => {
|
|
2334
|
-
const asInt = Number(handle);
|
|
2335
|
-
if (Number.isInteger(asInt) && asInt > 0) {
|
|
2336
|
-
const byId = await client.sessions.get(asInt).catch(() => null);
|
|
2337
|
-
if (byId) return { id: byId.id, name: byId.name };
|
|
2338
|
-
}
|
|
2339
|
-
const byName = await client.sessions.findByName(projectId, handle);
|
|
2340
|
-
if (byName) return { id: byName.id, name: byName.name };
|
|
2341
|
-
throw new Error(`session "${handle}" not found in project ${projectId}`);
|
|
2342
|
-
};
|
|
2343
|
-
|
|
2344
2518
|
// src/commands/session/abort.ts
|
|
2345
2519
|
var sessionAbortCommand = defineCommand({
|
|
2346
2520
|
meta: {
|
|
@@ -3866,6 +4040,7 @@ var main = defineCommand({
|
|
|
3866
4040
|
init,
|
|
3867
4041
|
worker,
|
|
3868
4042
|
session,
|
|
4043
|
+
loop,
|
|
3869
4044
|
relay,
|
|
3870
4045
|
channel,
|
|
3871
4046
|
workspace,
|