@notiamo/runner 0.2.0 → 0.2.1
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/README.md +1 -0
- package/dist/cli.js +58 -17
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -22,6 +22,7 @@ From a checkout of the Notiamo repository: `pnpm --filter @notiamo/runner build`
|
|
|
22
22
|
| Command | What |
|
|
23
23
|
| --- | --- |
|
|
24
24
|
| `notiamo-runner init` | Set up: token, Claude Code sign-in, install and start the service. |
|
|
25
|
+
| `notiamo-runner update` | Move a runner that is set up to the version you run it from: the token, name and sign-in stay; the checks run again; the service starts the new version. `npx @notiamo/runner@latest update` (add `--profile <name>` for a named runner). |
|
|
25
26
|
| `notiamo-runner status` | Whether the service is installed and running, and the last log line. |
|
|
26
27
|
| `notiamo-runner logs` | The last 50 lines of the log. |
|
|
27
28
|
| `notiamo-runner stop` | Stop the service until the next login or boot. |
|
package/dist/cli.js
CHANGED
|
@@ -30644,6 +30644,35 @@ async function runInit(deps) {
|
|
|
30644
30644
|
const host = normalizeHost(await ask("Notiamo address: ", DEFAULT_HOST));
|
|
30645
30645
|
const hostname3 = deps.hostname ?? os4.hostname();
|
|
30646
30646
|
const name = await ask("Name of this runner: ", hostname3);
|
|
30647
|
+
const engineVersion = await checkMachine(deps, env, platform, print);
|
|
30648
|
+
try {
|
|
30649
|
+
await new NotiamoApi({ host, token }, deps.fetch).hello({ version: VERSION, os: platform, engine: "claude", engineVersion });
|
|
30650
|
+
} catch (e) {
|
|
30651
|
+
if (e instanceof ApiError && e.status === 401) throw new Error("The runner token was not accepted.");
|
|
30652
|
+
throw new Error(`Notiamo at ${host} did not answer: ${e instanceof Error ? e.message : String(e)}`);
|
|
30653
|
+
}
|
|
30654
|
+
const claudeEnv = { ...env, CLAUDE_CONFIG_DIR: p.claudeConfigDir };
|
|
30655
|
+
if (!deps.skipLogin) {
|
|
30656
|
+
print("Sign Claude Code in for the runner (its own sign-in, kept apart from yours):");
|
|
30657
|
+
await (deps.interactive ?? runInteractive)("claude", ["auth", "login"], claudeEnv);
|
|
30658
|
+
}
|
|
30659
|
+
const check2 = await deps.exec("claude", ["-p", "say ok"], { env: claudeEnv });
|
|
30660
|
+
if (check2.code !== 0) throw new Error("Claude Code is not signed in for the runner.");
|
|
30661
|
+
await warnKeychain(deps, env, platform, print);
|
|
30662
|
+
saveConfig({ host, token, name, dataDir: dir, engine: "claude" }, dir);
|
|
30663
|
+
await installService({
|
|
30664
|
+
platform,
|
|
30665
|
+
profile: deps.profile,
|
|
30666
|
+
paths: p,
|
|
30667
|
+
exec: deps.exec,
|
|
30668
|
+
home: deps.home ?? os4.homedir(),
|
|
30669
|
+
env,
|
|
30670
|
+
nodePath: deps.nodePath ?? process.execPath,
|
|
30671
|
+
cliPath: deps.cliPath ?? process.argv[1]
|
|
30672
|
+
});
|
|
30673
|
+
print(`Runner ${name}${deps.profile ? ` (profile ${deps.profile})` : ""} is installed and running. Logs: ${p.log}`);
|
|
30674
|
+
}
|
|
30675
|
+
async function checkMachine(deps, env, platform, print) {
|
|
30647
30676
|
const version2 = await deps.exec("claude", ["--version"], { env });
|
|
30648
30677
|
if (version2.code !== 0) throw new Error("Claude Code is not installed. Install it first: https://claude.com/claude-code");
|
|
30649
30678
|
const engineVersion = version2.stdout.trim().slice(0, 100) || "unknown";
|
|
@@ -30663,25 +30692,31 @@ async function runInit(deps) {
|
|
|
30663
30692
|
} else if (platform === "win32") {
|
|
30664
30693
|
print("Note: on Windows without WSL2, shell commands of a run are not sandboxed; Claude's own file tools are still limited to the run folder.");
|
|
30665
30694
|
}
|
|
30695
|
+
return engineVersion;
|
|
30696
|
+
}
|
|
30697
|
+
async function warnKeychain(deps, env, platform, print) {
|
|
30698
|
+
if (platform !== "darwin") return;
|
|
30699
|
+
const git = await deps.exec("security", ["find-internet-password", "-s", "github.com"], { env, timeout: 1e4 });
|
|
30700
|
+
const gh = await deps.exec("security", ["find-generic-password", "-s", "gh:github.com"], { env, timeout: 1e4 });
|
|
30701
|
+
if (git.code === 0 || gh.code === 0) print(KEYCHAIN_WARNING);
|
|
30702
|
+
}
|
|
30703
|
+
async function runUpdate(deps) {
|
|
30704
|
+
const dir = deps.dir ?? profileDir(deps.profile);
|
|
30705
|
+
const platform = deps.platform ?? process.platform;
|
|
30706
|
+
const p = paths(dir);
|
|
30707
|
+
const env = deps.env ?? process.env;
|
|
30708
|
+
const print = deps.print ?? ((s) => console.log(s));
|
|
30709
|
+
const cfg = loadConfig(dir);
|
|
30710
|
+
const engineVersion = await checkMachine(deps, env, platform, print);
|
|
30666
30711
|
try {
|
|
30667
|
-
await new NotiamoApi({ host, token }, deps.fetch).hello({ version: VERSION, os: platform, engine: "claude", engineVersion });
|
|
30712
|
+
await new NotiamoApi({ host: cfg.host, token: cfg.token }, deps.fetch).hello({ version: VERSION, os: platform, engine: "claude", engineVersion });
|
|
30668
30713
|
} catch (e) {
|
|
30669
|
-
if (e instanceof ApiError && e.status === 401) throw new Error("The runner token
|
|
30670
|
-
throw new Error(`Notiamo at ${host} did not answer: ${e instanceof Error ? e.message : String(e)}`);
|
|
30671
|
-
}
|
|
30672
|
-
const claudeEnv = { ...env, CLAUDE_CONFIG_DIR: p.claudeConfigDir };
|
|
30673
|
-
if (!deps.skipLogin) {
|
|
30674
|
-
print("Sign Claude Code in for the runner (its own sign-in, kept apart from yours):");
|
|
30675
|
-
await (deps.interactive ?? runInteractive)("claude", ["auth", "login"], claudeEnv);
|
|
30714
|
+
if (e instanceof ApiError && e.status === 401) throw new Error("The saved runner token is not accepted any more (revoked or deleted). Make a new runner in Notiamo and run init.");
|
|
30715
|
+
throw new Error(`Notiamo at ${cfg.host} did not answer: ${e instanceof Error ? e.message : String(e)}`);
|
|
30676
30716
|
}
|
|
30677
|
-
const check2 = await deps.exec("claude", ["-p", "say ok"], { env:
|
|
30678
|
-
if (check2.code !== 0) throw new Error("Claude Code is not signed in for the runner.");
|
|
30679
|
-
|
|
30680
|
-
const git2 = await deps.exec("security", ["find-internet-password", "-s", "github.com"], { env, timeout: 1e4 });
|
|
30681
|
-
const gh = await deps.exec("security", ["find-generic-password", "-s", "gh:github.com"], { env, timeout: 1e4 });
|
|
30682
|
-
if (git2.code === 0 || gh.code === 0) print(KEYCHAIN_WARNING);
|
|
30683
|
-
}
|
|
30684
|
-
saveConfig({ host, token, name, dataDir: dir, engine: "claude" }, dir);
|
|
30717
|
+
const check2 = await deps.exec("claude", ["-p", "say ok"], { env: { ...env, CLAUDE_CONFIG_DIR: p.claudeConfigDir } });
|
|
30718
|
+
if (check2.code !== 0) throw new Error("Claude Code is not signed in for the runner. Run: notiamo-runner init");
|
|
30719
|
+
await warnKeychain(deps, env, platform, print);
|
|
30685
30720
|
await installService({
|
|
30686
30721
|
platform,
|
|
30687
30722
|
profile: deps.profile,
|
|
@@ -30692,7 +30727,7 @@ async function runInit(deps) {
|
|
|
30692
30727
|
nodePath: deps.nodePath ?? process.execPath,
|
|
30693
30728
|
cliPath: deps.cliPath ?? process.argv[1]
|
|
30694
30729
|
});
|
|
30695
|
-
print(`Runner ${name}${deps.profile ? ` (profile ${deps.profile})` : ""}
|
|
30730
|
+
print(`Runner ${cfg.name}${deps.profile ? ` (profile ${deps.profile})` : ""} now runs version ${VERSION}. Logs: ${p.log}`);
|
|
30696
30731
|
}
|
|
30697
30732
|
|
|
30698
30733
|
// src/log.ts
|
|
@@ -63529,6 +63564,9 @@ async function prompt(q2, opts = {}) {
|
|
|
63529
63564
|
async function init({ profile } = {}) {
|
|
63530
63565
|
await runInit({ prompt, exec: realExec, fetch, profile });
|
|
63531
63566
|
}
|
|
63567
|
+
async function update({ profile } = {}) {
|
|
63568
|
+
await runUpdate({ exec: realExec, fetch, profile });
|
|
63569
|
+
}
|
|
63532
63570
|
async function start({ profile } = {}) {
|
|
63533
63571
|
const dir = profileDir(profile);
|
|
63534
63572
|
const cfg = loadConfig(dir);
|
|
@@ -63634,6 +63672,7 @@ var HELP = `notiamo-runner ${VERSION}: runs Notiamo agent runs on this machine w
|
|
|
63634
63672
|
Usage: notiamo-runner <command> [--profile <name>]
|
|
63635
63673
|
|
|
63636
63674
|
init Set the runner up: token, Claude Code sign-in, start at login or boot
|
|
63675
|
+
update Move a runner that is set up to this version: keeps its token and sign-in
|
|
63637
63676
|
start Run in the foreground (what the service runs)
|
|
63638
63677
|
stop Stop the service until the next login or boot
|
|
63639
63678
|
status Whether the service is installed and running, and the last log line
|
|
@@ -63656,6 +63695,8 @@ ${HELP}`);
|
|
|
63656
63695
|
switch (cmd) {
|
|
63657
63696
|
case "init":
|
|
63658
63697
|
return init(o);
|
|
63698
|
+
case "update":
|
|
63699
|
+
return update(o);
|
|
63659
63700
|
case "start":
|
|
63660
63701
|
return start(o);
|
|
63661
63702
|
case "stop":
|