roger-roger 0.1.2 → 0.1.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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "roger-roger",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"description": "Bring yourself back to the conversation: your coding agents reach you by Slack, a sound or a spoken line when they finish, get stuck, or need a decision, and you answer from your phone.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
id = "roger-roger"
|
|
8
8
|
name = "roger-roger"
|
|
9
|
-
version = "0.1.
|
|
9
|
+
version = "0.1.3"
|
|
10
10
|
min_herdr_version = "0.9.0"
|
|
11
11
|
description = "Slack, a sound or a spoken line from the agents in your panes, and questions you answer from your phone"
|
|
12
12
|
platforms = ["linux", "macos", "windows"]
|
|
@@ -180,7 +180,7 @@ export function helpText(command = "", { columns = process.stdout.columns || 100
|
|
|
180
180
|
for (const line of wrap(TAGLINE, cols - 2)) out.push(` ${c.dim(line)}`);
|
|
181
181
|
out.push("");
|
|
182
182
|
out.push(` ${c.bold("Usage")}`);
|
|
183
|
-
out.push(...table([["roger-roger <command> [flags]", "every command prints one JSON object"], ["roger-roger help <command>", "that command's flags"]], {
|
|
183
|
+
out.push(...table([["roger-roger <command> [flags]", "every command prints one JSON object"], ["roger-roger help <command>", "that command's flags"], ["roger-roger --version", "which copy this is"]], {
|
|
184
184
|
indent: 4, columns: cols, c, maxLeft: 30, left: (l) => c.cyan("roger-roger") + " " + c.dim(l.slice("roger-roger ".length)),
|
|
185
185
|
}));
|
|
186
186
|
const sections = [...new Set(COMMANDS.map((x) => x.section))];
|
|
@@ -115,23 +115,37 @@ export function globalCopy(env = process.env) {
|
|
|
115
115
|
const root = (r.stdout ?? "").trim();
|
|
116
116
|
if (r.status !== 0 || !root) return null;
|
|
117
117
|
const pkg = path.join(root, "roger-roger");
|
|
118
|
-
|
|
118
|
+
let version = "";
|
|
119
|
+
try {
|
|
120
|
+
version = JSON.parse(fs.readFileSync(path.join(pkg, "package.json"), "utf8")).version ?? "";
|
|
121
|
+
} catch {}
|
|
122
|
+
return { root, dir: path.join(pkg, "skills", "roger-roger"), present: Boolean(version), version };
|
|
119
123
|
} catch {
|
|
120
124
|
return null;
|
|
121
125
|
}
|
|
122
126
|
}
|
|
123
127
|
|
|
128
|
+
/** a < b for dotted versions; anything unparseable counts as older. */
|
|
129
|
+
export function olderThan(a, b) {
|
|
130
|
+
const parse = (v) => String(v ?? "").split(".").map((n) => parseInt(n, 10) || 0);
|
|
131
|
+
const [x, y] = [parse(a), parse(b)];
|
|
132
|
+
for (let i = 0; i < 3; i++) if ((x[i] ?? 0) !== (y[i] ?? 0)) return (x[i] ?? 0) < (y[i] ?? 0);
|
|
133
|
+
return false;
|
|
134
|
+
}
|
|
135
|
+
|
|
124
136
|
/**
|
|
125
137
|
* Which copy of the skill everything should point at, and whether to offer a global install:
|
|
126
138
|
* the copy this runs from, unless that is a passing one (npx's cache, say) and there is no global
|
|
127
|
-
* copy yet
|
|
139
|
+
* copy yet, or the global copy is older than this one (`npx roger-roger@latest install` after an
|
|
140
|
+
* update). A global copy that is as new as a checkout or a skills.sh copy is left alone: whoever
|
|
128
141
|
* runs this copy meant this copy.
|
|
129
142
|
*/
|
|
130
|
-
export function pickTarget(running, global) {
|
|
143
|
+
export function pickTarget(running, global, runningVersion = VERSION) {
|
|
131
144
|
if (!global) return { target: running, offer: false, reason: "npm was not found" };
|
|
132
145
|
if (norm(running) === norm(global.dir)) return { target: running, offer: false, reason: "global" };
|
|
133
|
-
if (global.present) return { target: running, offer:
|
|
134
|
-
return { target: running, offer: true, reason: "
|
|
146
|
+
if (!global.present) return { target: running, offer: true, reason: "no global copy yet" };
|
|
147
|
+
if (runningVersion && olderThan(global.version, runningVersion)) return { target: running, offer: true, reason: "update", from: global.version, to: runningVersion };
|
|
148
|
+
return { target: running, offer: false, reason: "a global copy exists, but this one was run" };
|
|
135
149
|
}
|
|
136
150
|
|
|
137
151
|
/** `npm install -g roger-roger@latest`. Throws with npm's last words when it fails. */
|
|
@@ -422,9 +436,11 @@ export async function runInstall(args, { script, hooks, input = process.stdin, o
|
|
|
422
436
|
if (pick.reason === "global") {
|
|
423
437
|
ui.done("The roger-roger command is on your PATH", global.dir);
|
|
424
438
|
} else if (pick.offer) {
|
|
425
|
-
const yes = await ui.confirm(
|
|
439
|
+
const yes = await ui.confirm(pick.reason === "update"
|
|
440
|
+
? { message: `Update the roger-roger command from ${pick.from} to ${pick.to}?`, hint: "npm install -g roger-roger@latest; the old one would keep answering" }
|
|
441
|
+
: { message: "Put the roger-roger command on your PATH?", hint: "npm install -g roger-roger, so you and your agents can run it from anywhere" });
|
|
426
442
|
if (yes) {
|
|
427
|
-
const done = await attempt(ui, "Installing globally", () => ui.run("Installing roger-roger with npm
|
|
443
|
+
const done = await attempt(ui, pick.reason === "update" ? "Updating" : "Installing globally", () => ui.run(`${pick.reason === "update" ? "Updating" : "Installing"} roger-roger with npm`, () => installGlobally(env), { done: () => ({ text: `The roger-roger command is on your PATH${pick.to ? `, at ${pick.to}` : ""}`, detail: global.dir }) }), { skipLabel: "Carry on with this copy" });
|
|
428
444
|
if (done !== null && fs.existsSync(path.join(global.dir, "scripts", "roger-roger.mjs"))) {
|
|
429
445
|
target = global.dir;
|
|
430
446
|
hookScript = path.join(global.dir, "scripts", "roger-roger.mjs");
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
import fs from "node:fs";
|
|
11
11
|
import path from "node:path";
|
|
12
12
|
import {
|
|
13
|
-
DEFAULTS, DUCK_MODES, KINDS, METHODS, ON_EXPIRE, SPEECH_MODES, WHEN_MODES,
|
|
13
|
+
DEFAULTS, DUCK_MODES, KINDS, METHODS, ON_EXPIRE, SPEECH_MODES, VERSION, WHEN_MODES,
|
|
14
14
|
applySetup, rogerRogerHome, configPath, listArg, listSounds, loadConfig, migrateLegacyHome, parseArgs,
|
|
15
15
|
readSlackCredentials, saveConfig, slackAppToken, slackToken,
|
|
16
16
|
} from "./lib.mjs";
|
|
@@ -324,6 +324,10 @@ const AGENTS = {
|
|
|
324
324
|
|
|
325
325
|
/** `help`, `help <command>`, `--help`, or a command that doesn't exist: the overview, or one command's page. */
|
|
326
326
|
function help(command, args) {
|
|
327
|
+
if (["--version", "-v", "-V", "version"].includes(command)) {
|
|
328
|
+
process.stdout.write(`${VERSION || "unversioned copy"}\n`);
|
|
329
|
+
return;
|
|
330
|
+
}
|
|
327
331
|
const wanted = command === "help" ? args._[0] : "";
|
|
328
332
|
const unknown = command && !["help", "--help", "-h", undefined].includes(command);
|
|
329
333
|
if (unknown) process.stderr.write(`roger-roger: unknown command "${command}"\n`);
|