@made-by-moonlight/athene-cli 0.9.2
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 +22 -0
- package/dist/assets/plugin-registry.json +67 -0
- package/dist/assets/scripts/athene-doctor.ps1 +352 -0
- package/dist/assets/scripts/athene-doctor.sh +552 -0
- package/dist/assets/scripts/athene-update.ps1 +224 -0
- package/dist/assets/scripts/athene-update.sh +252 -0
- package/dist/commands/completion.d.ts +3 -0
- package/dist/commands/completion.d.ts.map +1 -0
- package/dist/commands/completion.js +26 -0
- package/dist/commands/completion.js.map +1 -0
- package/dist/commands/config.d.ts +11 -0
- package/dist/commands/config.d.ts.map +1 -0
- package/dist/commands/config.js +89 -0
- package/dist/commands/config.js.map +1 -0
- package/dist/commands/dashboard.d.ts +3 -0
- package/dist/commands/dashboard.d.ts.map +1 -0
- package/dist/commands/dashboard.js +103 -0
- package/dist/commands/dashboard.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 +329 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/events.d.ts +3 -0
- package/dist/commands/events.d.ts.map +1 -0
- package/dist/commands/events.js +172 -0
- package/dist/commands/events.js.map +1 -0
- package/dist/commands/migrate-storage.d.ts +3 -0
- package/dist/commands/migrate-storage.d.ts.map +1 -0
- package/dist/commands/migrate-storage.js +78 -0
- package/dist/commands/migrate-storage.js.map +1 -0
- package/dist/commands/notify.d.ts +3 -0
- package/dist/commands/notify.d.ts.map +1 -0
- package/dist/commands/notify.js +143 -0
- package/dist/commands/notify.js.map +1 -0
- package/dist/commands/open.d.ts +3 -0
- package/dist/commands/open.d.ts.map +1 -0
- package/dist/commands/open.js +167 -0
- package/dist/commands/open.js.map +1 -0
- package/dist/commands/plugin.d.ts +3 -0
- package/dist/commands/plugin.d.ts.map +1 -0
- package/dist/commands/plugin.js +462 -0
- package/dist/commands/plugin.js.map +1 -0
- package/dist/commands/project.d.ts +3 -0
- package/dist/commands/project.d.ts.map +1 -0
- package/dist/commands/project.js +143 -0
- package/dist/commands/project.js.map +1 -0
- package/dist/commands/report.d.ts +19 -0
- package/dist/commands/report.d.ts.map +1 -0
- package/dist/commands/report.js +114 -0
- package/dist/commands/report.js.map +1 -0
- package/dist/commands/review-check.d.ts +3 -0
- package/dist/commands/review-check.d.ts.map +1 -0
- package/dist/commands/review-check.js +122 -0
- package/dist/commands/review-check.js.map +1 -0
- package/dist/commands/review.d.ts +3 -0
- package/dist/commands/review.d.ts.map +1 -0
- package/dist/commands/review.js +215 -0
- package/dist/commands/review.js.map +1 -0
- package/dist/commands/send.d.ts +3 -0
- package/dist/commands/send.d.ts.map +1 -0
- package/dist/commands/send.js +187 -0
- package/dist/commands/send.js.map +1 -0
- package/dist/commands/session.d.ts +3 -0
- package/dist/commands/session.d.ts.map +1 -0
- package/dist/commands/session.js +439 -0
- package/dist/commands/session.js.map +1 -0
- package/dist/commands/setup.d.ts +5 -0
- package/dist/commands/setup.d.ts.map +1 -0
- package/dist/commands/setup.js +297 -0
- package/dist/commands/setup.js.map +1 -0
- package/dist/commands/spawn.d.ts +4 -0
- package/dist/commands/spawn.d.ts.map +1 -0
- package/dist/commands/spawn.js +436 -0
- package/dist/commands/spawn.js.map +1 -0
- package/dist/commands/start.d.ts +21 -0
- package/dist/commands/start.d.ts.map +1 -0
- package/dist/commands/start.js +1836 -0
- package/dist/commands/start.js.map +1 -0
- package/dist/commands/status.d.ts +3 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +556 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/update.d.ts +15 -0
- package/dist/commands/update.d.ts.map +1 -0
- package/dist/commands/update.js +652 -0
- package/dist/commands/update.js.map +1 -0
- package/dist/commands/verify.d.ts +3 -0
- package/dist/commands/verify.d.ts.map +1 -0
- package/dist/commands/verify.js +131 -0
- package/dist/commands/verify.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +24 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/bun-tmp-janitor.d.ts +18 -0
- package/dist/lib/bun-tmp-janitor.d.ts.map +1 -0
- package/dist/lib/bun-tmp-janitor.js +127 -0
- package/dist/lib/bun-tmp-janitor.js.map +1 -0
- package/dist/lib/caller-context.d.ts +13 -0
- package/dist/lib/caller-context.d.ts.map +1 -0
- package/dist/lib/caller-context.js +20 -0
- package/dist/lib/caller-context.js.map +1 -0
- package/dist/lib/cli-errors.d.ts +8 -0
- package/dist/lib/cli-errors.d.ts.map +1 -0
- package/dist/lib/cli-errors.js +20 -0
- package/dist/lib/cli-errors.js.map +1 -0
- package/dist/lib/completion.d.ts +13 -0
- package/dist/lib/completion.d.ts.map +1 -0
- package/dist/lib/completion.js +428 -0
- package/dist/lib/completion.js.map +1 -0
- package/dist/lib/composio-setup.d.ts +65 -0
- package/dist/lib/composio-setup.d.ts.map +1 -0
- package/dist/lib/composio-setup.js +3255 -0
- package/dist/lib/composio-setup.js.map +1 -0
- package/dist/lib/config-instruction.d.ts +2 -0
- package/dist/lib/config-instruction.d.ts.map +1 -0
- package/dist/lib/config-instruction.js +193 -0
- package/dist/lib/config-instruction.js.map +1 -0
- package/dist/lib/constants.d.ts +3 -0
- package/dist/lib/constants.d.ts.map +1 -0
- package/dist/lib/constants.js +3 -0
- package/dist/lib/constants.js.map +1 -0
- package/dist/lib/create-session-manager.d.ts +26 -0
- package/dist/lib/create-session-manager.d.ts.map +1 -0
- package/dist/lib/create-session-manager.js +55 -0
- package/dist/lib/create-session-manager.js.map +1 -0
- package/dist/lib/credential-resolver.d.ts +37 -0
- package/dist/lib/credential-resolver.d.ts.map +1 -0
- package/dist/lib/credential-resolver.js +105 -0
- package/dist/lib/credential-resolver.js.map +1 -0
- package/dist/lib/daemon.d.ts +69 -0
- package/dist/lib/daemon.d.ts.map +1 -0
- package/dist/lib/daemon.js +77 -0
- package/dist/lib/daemon.js.map +1 -0
- package/dist/lib/dashboard-rebuild.d.ts +53 -0
- package/dist/lib/dashboard-rebuild.d.ts.map +1 -0
- package/dist/lib/dashboard-rebuild.js +188 -0
- package/dist/lib/dashboard-rebuild.js.map +1 -0
- package/dist/lib/dashboard-setup.d.ts +14 -0
- package/dist/lib/dashboard-setup.d.ts.map +1 -0
- package/dist/lib/dashboard-setup.js +192 -0
- package/dist/lib/dashboard-setup.js.map +1 -0
- package/dist/lib/dashboard-url.d.ts +19 -0
- package/dist/lib/dashboard-url.d.ts.map +1 -0
- package/dist/lib/dashboard-url.js +25 -0
- package/dist/lib/dashboard-url.js.map +1 -0
- package/dist/lib/desktop-setup.d.ts +21 -0
- package/dist/lib/desktop-setup.d.ts.map +1 -0
- package/dist/lib/desktop-setup.js +556 -0
- package/dist/lib/desktop-setup.js.map +1 -0
- package/dist/lib/detect-agent.d.ts +24 -0
- package/dist/lib/detect-agent.d.ts.map +1 -0
- package/dist/lib/detect-agent.js +69 -0
- package/dist/lib/detect-agent.js.map +1 -0
- package/dist/lib/detect-env.d.ts +14 -0
- package/dist/lib/detect-env.d.ts.map +1 -0
- package/dist/lib/detect-env.js +46 -0
- package/dist/lib/detect-env.js.map +1 -0
- package/dist/lib/discord-setup.d.ts +20 -0
- package/dist/lib/discord-setup.d.ts.map +1 -0
- package/dist/lib/discord-setup.js +584 -0
- package/dist/lib/discord-setup.js.map +1 -0
- package/dist/lib/format.d.ts +11 -0
- package/dist/lib/format.d.ts.map +1 -0
- package/dist/lib/format.js +116 -0
- package/dist/lib/format.js.map +1 -0
- package/dist/lib/git-utils.d.ts +14 -0
- package/dist/lib/git-utils.d.ts.map +1 -0
- package/dist/lib/git-utils.js +45 -0
- package/dist/lib/git-utils.js.map +1 -0
- package/dist/lib/install-helpers.d.ts +24 -0
- package/dist/lib/install-helpers.d.ts.map +1 -0
- package/dist/lib/install-helpers.js +76 -0
- package/dist/lib/install-helpers.js.map +1 -0
- package/dist/lib/lifecycle-service.d.ts +11 -0
- package/dist/lib/lifecycle-service.d.ts.map +1 -0
- package/dist/lib/lifecycle-service.js +65 -0
- package/dist/lib/lifecycle-service.js.map +1 -0
- package/dist/lib/notifier-routing.d.ts +35 -0
- package/dist/lib/notifier-routing.d.ts.map +1 -0
- package/dist/lib/notifier-routing.js +133 -0
- package/dist/lib/notifier-routing.js.map +1 -0
- package/dist/lib/notify-test.d.ts +72 -0
- package/dist/lib/notify-test.d.ts.map +1 -0
- package/dist/lib/notify-test.js +674 -0
- package/dist/lib/notify-test.js.map +1 -0
- package/dist/lib/openclaw-probe.d.ts +38 -0
- package/dist/lib/openclaw-probe.d.ts.map +1 -0
- package/dist/lib/openclaw-probe.js +146 -0
- package/dist/lib/openclaw-probe.js.map +1 -0
- package/dist/lib/openclaw-setup.d.ts +19 -0
- package/dist/lib/openclaw-setup.d.ts.map +1 -0
- package/dist/lib/openclaw-setup.js +684 -0
- package/dist/lib/openclaw-setup.js.map +1 -0
- package/dist/lib/path-equality.d.ts +29 -0
- package/dist/lib/path-equality.d.ts.map +1 -0
- package/dist/lib/path-equality.js +52 -0
- package/dist/lib/path-equality.js.map +1 -0
- package/dist/lib/plugin-marketplace.d.ts +24 -0
- package/dist/lib/plugin-marketplace.d.ts.map +1 -0
- package/dist/lib/plugin-marketplace.js +175 -0
- package/dist/lib/plugin-marketplace.js.map +1 -0
- package/dist/lib/plugin-scaffold.d.ts +14 -0
- package/dist/lib/plugin-scaffold.d.ts.map +1 -0
- package/dist/lib/plugin-scaffold.js +174 -0
- package/dist/lib/plugin-scaffold.js.map +1 -0
- package/dist/lib/plugin-store.d.ts +9 -0
- package/dist/lib/plugin-store.d.ts.map +1 -0
- package/dist/lib/plugin-store.js +121 -0
- package/dist/lib/plugin-store.js.map +1 -0
- package/dist/lib/plugins.d.ts +17 -0
- package/dist/lib/plugins.d.ts.map +1 -0
- package/dist/lib/plugins.js +65 -0
- package/dist/lib/plugins.js.map +1 -0
- package/dist/lib/portfolio-display.d.ts +10 -0
- package/dist/lib/portfolio-display.d.ts.map +1 -0
- package/dist/lib/portfolio-display.js +17 -0
- package/dist/lib/portfolio-display.js.map +1 -0
- package/dist/lib/preflight.d.ts +27 -0
- package/dist/lib/preflight.d.ts.map +1 -0
- package/dist/lib/preflight.js +77 -0
- package/dist/lib/preflight.js.map +1 -0
- package/dist/lib/prevent-sleep.d.ts +34 -0
- package/dist/lib/prevent-sleep.d.ts.map +1 -0
- package/dist/lib/prevent-sleep.js +65 -0
- package/dist/lib/prevent-sleep.js.map +1 -0
- package/dist/lib/project-detection.d.ts +11 -0
- package/dist/lib/project-detection.d.ts.map +1 -0
- package/dist/lib/project-detection.js +206 -0
- package/dist/lib/project-detection.js.map +1 -0
- package/dist/lib/project-resolution.d.ts +10 -0
- package/dist/lib/project-resolution.d.ts.map +1 -0
- package/dist/lib/project-resolution.js +17 -0
- package/dist/lib/project-resolution.js.map +1 -0
- package/dist/lib/project-supervisor.d.ts +28 -0
- package/dist/lib/project-supervisor.d.ts.map +1 -0
- package/dist/lib/project-supervisor.js +167 -0
- package/dist/lib/project-supervisor.js.map +1 -0
- package/dist/lib/prompts.d.ts +7 -0
- package/dist/lib/prompts.d.ts.map +1 -0
- package/dist/lib/prompts.js +37 -0
- package/dist/lib/prompts.js.map +1 -0
- package/dist/lib/repo-utils.d.ts +16 -0
- package/dist/lib/repo-utils.d.ts.map +1 -0
- package/dist/lib/repo-utils.js +26 -0
- package/dist/lib/repo-utils.js.map +1 -0
- package/dist/lib/resolve-project.d.ts +113 -0
- package/dist/lib/resolve-project.d.ts.map +1 -0
- package/dist/lib/resolve-project.js +433 -0
- package/dist/lib/resolve-project.js.map +1 -0
- package/dist/lib/routes.d.ts +2 -0
- package/dist/lib/routes.d.ts.map +1 -0
- package/dist/lib/routes.js +5 -0
- package/dist/lib/routes.js.map +1 -0
- package/dist/lib/running-state.d.ts +76 -0
- package/dist/lib/running-state.d.ts.map +1 -0
- package/dist/lib/running-state.js +338 -0
- package/dist/lib/running-state.js.map +1 -0
- package/dist/lib/script-runner.d.ts +10 -0
- package/dist/lib/script-runner.d.ts.map +1 -0
- package/dist/lib/script-runner.js +189 -0
- package/dist/lib/script-runner.js.map +1 -0
- package/dist/lib/session-utils.d.ts +14 -0
- package/dist/lib/session-utils.d.ts.map +1 -0
- package/dist/lib/session-utils.js +58 -0
- package/dist/lib/session-utils.js.map +1 -0
- package/dist/lib/shell.d.ts +17 -0
- package/dist/lib/shell.d.ts.map +1 -0
- package/dist/lib/shell.js +90 -0
- package/dist/lib/shell.js.map +1 -0
- package/dist/lib/shutdown.d.ts +30 -0
- package/dist/lib/shutdown.d.ts.map +1 -0
- package/dist/lib/shutdown.js +177 -0
- package/dist/lib/shutdown.js.map +1 -0
- package/dist/lib/slack-setup.d.ts +17 -0
- package/dist/lib/slack-setup.d.ts.map +1 -0
- package/dist/lib/slack-setup.js +485 -0
- package/dist/lib/slack-setup.js.map +1 -0
- package/dist/lib/startup-preflight.d.ts +36 -0
- package/dist/lib/startup-preflight.d.ts.map +1 -0
- package/dist/lib/startup-preflight.js +273 -0
- package/dist/lib/startup-preflight.js.map +1 -0
- package/dist/lib/update-channel-onboarding.d.ts +52 -0
- package/dist/lib/update-channel-onboarding.d.ts.map +1 -0
- package/dist/lib/update-channel-onboarding.js +107 -0
- package/dist/lib/update-channel-onboarding.js.map +1 -0
- package/dist/lib/update-check.d.ts +161 -0
- package/dist/lib/update-check.d.ts.map +1 -0
- package/dist/lib/update-check.js +504 -0
- package/dist/lib/update-check.js.map +1 -0
- package/dist/lib/web-dir.d.ts +47 -0
- package/dist/lib/web-dir.d.ts.map +1 -0
- package/dist/lib/web-dir.js +179 -0
- package/dist/lib/web-dir.js.map +1 -0
- package/dist/lib/webhook-setup.d.ts +16 -0
- package/dist/lib/webhook-setup.d.ts.map +1 -0
- package/dist/lib/webhook-setup.js +383 -0
- package/dist/lib/webhook-setup.js.map +1 -0
- package/dist/options/version.d.ts +2 -0
- package/dist/options/version.d.ts.map +1 -0
- package/dist/options/version.js +7 -0
- package/dist/options/version.js.map +1 -0
- package/dist/program.d.ts +3 -0
- package/dist/program.d.ts.map +1 -0
- package/dist/program.js +63 -0
- package/dist/program.js.map +1 -0
- package/package.json +80 -0
- package/templates/rules/base.md +4 -0
- package/templates/rules/go.md +8 -0
- package/templates/rules/javascript.md +4 -0
- package/templates/rules/nextjs.md +7 -0
- package/templates/rules/pnpm-workspaces.md +4 -0
- package/templates/rules/python.md +8 -0
- package/templates/rules/react.md +8 -0
- package/templates/rules/typescript.md +6 -0
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runtime preflight checks for `athene start`.
|
|
3
|
+
*
|
|
4
|
+
* Distinct from `lib/preflight.ts` (which validates dashboard build
|
|
5
|
+
* artifacts). This module verifies system tools (git, tmux), warns about
|
|
6
|
+
* legacy storage and OpenClaw status, and applies side effects like idle
|
|
7
|
+
* sleep prevention and credential injection.
|
|
8
|
+
*
|
|
9
|
+
* Each check is exported individually for callers that need it at a
|
|
10
|
+
* specific point in the flow (e.g. `ensureGit` before clone). The
|
|
11
|
+
* top-level `runtimePreflight(config)` orchestrates the checks that
|
|
12
|
+
* `runStartup` runs once at process start.
|
|
13
|
+
*/
|
|
14
|
+
import { readFileSync, writeFileSync } from "node:fs";
|
|
15
|
+
import chalk from "chalk";
|
|
16
|
+
import { getAoBaseDir, getDefaultRuntime, getGlobalConfigPath, inventoryHashDirs, isWindows, } from "@made-by-moonlight/athene-core";
|
|
17
|
+
import { execSilent } from "./shell.js";
|
|
18
|
+
import { detectOpenClawInstallation } from "./openclaw-probe.js";
|
|
19
|
+
import { applyOpenClawCredentials } from "./credential-resolver.js";
|
|
20
|
+
import { preventIdleSleep } from "./prevent-sleep.js";
|
|
21
|
+
import { askYesNo, tryInstallWithAttempts } from "./install-helpers.js";
|
|
22
|
+
function gitInstallAttempts() {
|
|
23
|
+
if (process.platform === "darwin") {
|
|
24
|
+
return [{ cmd: "brew", args: ["install", "git"], label: "brew install git" }];
|
|
25
|
+
}
|
|
26
|
+
if (process.platform === "linux") {
|
|
27
|
+
return [
|
|
28
|
+
{
|
|
29
|
+
cmd: "sudo",
|
|
30
|
+
args: ["apt-get", "install", "-y", "git"],
|
|
31
|
+
label: "sudo apt-get install -y git",
|
|
32
|
+
},
|
|
33
|
+
{ cmd: "sudo", args: ["dnf", "install", "-y", "git"], label: "sudo dnf install -y git" },
|
|
34
|
+
];
|
|
35
|
+
}
|
|
36
|
+
if (process.platform === "win32") {
|
|
37
|
+
return [
|
|
38
|
+
{
|
|
39
|
+
cmd: "winget",
|
|
40
|
+
args: ["install", "--id", "Git.Git", "-e", "--source", "winget"],
|
|
41
|
+
label: "winget install --id Git.Git -e --source winget",
|
|
42
|
+
},
|
|
43
|
+
];
|
|
44
|
+
}
|
|
45
|
+
return [];
|
|
46
|
+
}
|
|
47
|
+
function gitInstallHints() {
|
|
48
|
+
if (process.platform === "darwin")
|
|
49
|
+
return ["brew install git"];
|
|
50
|
+
if (process.platform === "win32")
|
|
51
|
+
return ["winget install --id Git.Git -e --source winget"];
|
|
52
|
+
return ["sudo apt install git # Debian/Ubuntu", "sudo dnf install git # Fedora/RHEL"];
|
|
53
|
+
}
|
|
54
|
+
function tmuxInstallAttempts() {
|
|
55
|
+
if (process.platform === "darwin") {
|
|
56
|
+
return [{ cmd: "brew", args: ["install", "tmux"], label: "brew install tmux" }];
|
|
57
|
+
}
|
|
58
|
+
if (process.platform === "linux") {
|
|
59
|
+
return [
|
|
60
|
+
{
|
|
61
|
+
cmd: "sudo",
|
|
62
|
+
args: ["apt-get", "install", "-y", "tmux"],
|
|
63
|
+
label: "sudo apt-get install -y tmux",
|
|
64
|
+
},
|
|
65
|
+
{ cmd: "sudo", args: ["dnf", "install", "-y", "tmux"], label: "sudo dnf install -y tmux" },
|
|
66
|
+
];
|
|
67
|
+
}
|
|
68
|
+
return [];
|
|
69
|
+
}
|
|
70
|
+
function tmuxInstallHints() {
|
|
71
|
+
if (process.platform === "darwin")
|
|
72
|
+
return ["brew install tmux"];
|
|
73
|
+
if (process.platform === "win32")
|
|
74
|
+
return ["# Install WSL first, then inside WSL:", "sudo apt install tmux"];
|
|
75
|
+
return ["sudo apt install tmux # Debian/Ubuntu", "sudo dnf install tmux # Fedora/RHEL"];
|
|
76
|
+
}
|
|
77
|
+
export async function ensureGit(context) {
|
|
78
|
+
const hasGit = (await execSilent("git", ["--version"])) !== null;
|
|
79
|
+
if (hasGit)
|
|
80
|
+
return;
|
|
81
|
+
console.log(chalk.yellow(`⚠ Git is required for ${context}.`));
|
|
82
|
+
const shouldInstall = await askYesNo("Install Git now?", true, false);
|
|
83
|
+
if (shouldInstall) {
|
|
84
|
+
const installed = await tryInstallWithAttempts(gitInstallAttempts(), async () => (await execSilent("git", ["--version"])) !== null);
|
|
85
|
+
if (installed) {
|
|
86
|
+
console.log(chalk.green(" ✓ Git installed successfully"));
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
console.error(chalk.red("\n✗ Git is required but is not installed.\n"));
|
|
91
|
+
console.log(chalk.bold(" Install Git manually, then re-run athene start:\n"));
|
|
92
|
+
for (const hint of gitInstallHints()) {
|
|
93
|
+
console.log(chalk.cyan(` ${hint}`));
|
|
94
|
+
}
|
|
95
|
+
console.log();
|
|
96
|
+
process.exit(1);
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* On Windows, attempt to rewrite `runtime: tmux` -> `runtime: process` in the
|
|
100
|
+
* project's agent-orchestrator.yaml after asking the user. Uses a targeted
|
|
101
|
+
* line replace (not a yaml round-trip) so comments and quoting are preserved.
|
|
102
|
+
*
|
|
103
|
+
* Returns `true` on a successful rewrite. The caller is responsible for
|
|
104
|
+
* mutating the in-memory config (or reloading) so the rest of preflight
|
|
105
|
+
* sees the new runtime.
|
|
106
|
+
*/
|
|
107
|
+
async function offerWindowsRuntimeSwitch(configPath) {
|
|
108
|
+
console.log(chalk.yellow("\n⚠ tmux runtime is not supported on Windows."));
|
|
109
|
+
console.log(chalk.dim(` Config: ${configPath}`));
|
|
110
|
+
console.log(chalk.dim(" AO can rewrite `runtime: tmux` -> `runtime: process` in this file.\n" +
|
|
111
|
+
" If the file is git-tracked, you'll see this as a local change."));
|
|
112
|
+
const accept = await askYesNo("Switch this project to runtime: process?", true, false);
|
|
113
|
+
if (!accept)
|
|
114
|
+
return false;
|
|
115
|
+
let original;
|
|
116
|
+
try {
|
|
117
|
+
original = readFileSync(configPath, "utf-8");
|
|
118
|
+
}
|
|
119
|
+
catch (err) {
|
|
120
|
+
console.error(chalk.red(` ✗ Could not read config: ${err instanceof Error ? err.message : String(err)}`));
|
|
121
|
+
return false;
|
|
122
|
+
}
|
|
123
|
+
// Match the runtime line whether quoted or unquoted, and preserve any
|
|
124
|
+
// trailing comment. Anchored multiline so we don't accidentally rewrite
|
|
125
|
+
// e.g. a string value on another line.
|
|
126
|
+
const runtimeLineRe = /^([ \t]*runtime:[ \t]*)(?:'tmux'|"tmux"|tmux)([ \t]*(?:#.*)?)$/m;
|
|
127
|
+
if (!runtimeLineRe.test(original)) {
|
|
128
|
+
console.error(chalk.red(" ✗ Could not locate `runtime: tmux` line in config; aborting rewrite."));
|
|
129
|
+
return false;
|
|
130
|
+
}
|
|
131
|
+
const rewritten = original.replace(runtimeLineRe, "$1process$2");
|
|
132
|
+
try {
|
|
133
|
+
writeFileSync(configPath, rewritten, "utf-8");
|
|
134
|
+
}
|
|
135
|
+
catch (err) {
|
|
136
|
+
console.error(chalk.red(` ✗ Failed to write config: ${err instanceof Error ? err.message : String(err)}`));
|
|
137
|
+
return false;
|
|
138
|
+
}
|
|
139
|
+
console.log(chalk.green(" ✓ Updated runtime to process"));
|
|
140
|
+
return true;
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Ensure tmux is available — interactive install with user consent if missing.
|
|
144
|
+
* Called from runtimePreflight() so all `athene start` paths are covered.
|
|
145
|
+
*
|
|
146
|
+
* On Windows, tmux cannot run; instead, offer to rewrite the project config
|
|
147
|
+
* to `runtime: process`. Returns `{ switchedToProcess: true }` if the rewrite
|
|
148
|
+
* succeeded so the caller can update the in-memory config.
|
|
149
|
+
*/
|
|
150
|
+
export async function ensureTmux(configPath) {
|
|
151
|
+
if (isWindows()) {
|
|
152
|
+
if (configPath) {
|
|
153
|
+
const switched = await offerWindowsRuntimeSwitch(configPath);
|
|
154
|
+
if (switched)
|
|
155
|
+
return { switchedToProcess: true };
|
|
156
|
+
}
|
|
157
|
+
console.error(chalk.red("\n✗ tmux runtime is not supported on Windows.\n"));
|
|
158
|
+
console.log(chalk.bold(" Set ") +
|
|
159
|
+
chalk.cyan("runtime: process") +
|
|
160
|
+
chalk.bold(" in agent-orchestrator.yaml, then re-run athene start.\n"));
|
|
161
|
+
process.exit(1);
|
|
162
|
+
}
|
|
163
|
+
const hasTmux = (await execSilent("tmux", ["-V"])) !== null;
|
|
164
|
+
if (hasTmux)
|
|
165
|
+
return { switchedToProcess: false };
|
|
166
|
+
console.log(chalk.yellow('⚠ tmux is required for runtime "tmux".'));
|
|
167
|
+
const shouldInstall = await askYesNo("Install tmux now?", true, false);
|
|
168
|
+
if (shouldInstall) {
|
|
169
|
+
const installed = await tryInstallWithAttempts(tmuxInstallAttempts(), async () => (await execSilent("tmux", ["-V"])) !== null);
|
|
170
|
+
if (installed) {
|
|
171
|
+
console.log(chalk.green(" ✓ tmux installed successfully"));
|
|
172
|
+
return { switchedToProcess: false };
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
console.error(chalk.red("\n✗ tmux is required but is not installed.\n"));
|
|
176
|
+
console.log(chalk.bold(" Install tmux manually, then re-run athene start:\n"));
|
|
177
|
+
for (const hint of tmuxInstallHints()) {
|
|
178
|
+
console.log(chalk.cyan(` ${hint}`));
|
|
179
|
+
}
|
|
180
|
+
console.log();
|
|
181
|
+
process.exit(1);
|
|
182
|
+
}
|
|
183
|
+
export function warnAboutLegacyStorage() {
|
|
184
|
+
try {
|
|
185
|
+
const hashDirs = inventoryHashDirs(getAoBaseDir(), getGlobalConfigPath());
|
|
186
|
+
if (hashDirs.length === 0)
|
|
187
|
+
return;
|
|
188
|
+
const nonEmptyDirCount = hashDirs.reduce((sum, d) => {
|
|
189
|
+
if (d.empty)
|
|
190
|
+
return sum;
|
|
191
|
+
return sum + 1;
|
|
192
|
+
}, 0);
|
|
193
|
+
if (nonEmptyDirCount === 0)
|
|
194
|
+
return;
|
|
195
|
+
console.log(chalk.yellow(`\n ⚠ Found ${nonEmptyDirCount} legacy storage director${nonEmptyDirCount === 1 ? "y" : "ies"} that need${nonEmptyDirCount === 1 ? "s" : ""} migration.\n` +
|
|
196
|
+
` Sessions stored in the old format won't appear until migrated.\n` +
|
|
197
|
+
` Run ${chalk.bold("athene migrate-storage")} to upgrade (use ${chalk.bold("--dry-run")} to preview).\n`));
|
|
198
|
+
}
|
|
199
|
+
catch {
|
|
200
|
+
// Non-critical — don't block startup
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
export async function warnAboutOpenClawStatus(config) {
|
|
204
|
+
const openclawConfig = config.notifiers?.["openclaw"];
|
|
205
|
+
const openclawConfigured = openclawConfig !== null &&
|
|
206
|
+
openclawConfig !== undefined &&
|
|
207
|
+
typeof openclawConfig === "object" &&
|
|
208
|
+
openclawConfig.plugin === "openclaw";
|
|
209
|
+
const configuredUrl = openclawConfigured && typeof openclawConfig.url === "string" ? openclawConfig.url : undefined;
|
|
210
|
+
try {
|
|
211
|
+
const installation = configuredUrl
|
|
212
|
+
? await detectOpenClawInstallation(configuredUrl)
|
|
213
|
+
: await detectOpenClawInstallation();
|
|
214
|
+
if (openclawConfigured) {
|
|
215
|
+
if (installation.state !== "running") {
|
|
216
|
+
console.log(chalk.yellow(`⚠ OpenClaw is configured but the gateway is not reachable at ${installation.gatewayUrl}. Notifications may fail until it is running.`));
|
|
217
|
+
}
|
|
218
|
+
return;
|
|
219
|
+
}
|
|
220
|
+
if (installation.state === "running") {
|
|
221
|
+
console.log(chalk.yellow(`⚠ OpenClaw is running at ${installation.gatewayUrl} but AO is not configured to use it. Run \`athene setup openclaw\` if you want OpenClaw notifications.`));
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
catch {
|
|
225
|
+
// OpenClaw probing is advisory for `athene start`; never block startup on it.
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* Top-level orchestrator: tools + state warnings + idle-sleep + credentials.
|
|
230
|
+
* Replaces the inline preflight block in `runStartup`. Idempotent within a
|
|
231
|
+
* single process — the side effects (caffeinate spawn, env injection) latch
|
|
232
|
+
* for the lifetime of the process.
|
|
233
|
+
*/
|
|
234
|
+
export async function runtimePreflight(config) {
|
|
235
|
+
const runtime = config.defaults?.runtime ?? getDefaultRuntime();
|
|
236
|
+
if (runtime === "tmux") {
|
|
237
|
+
const result = await ensureTmux(config.configPath);
|
|
238
|
+
if (result.switchedToProcess) {
|
|
239
|
+
// Mutate in-memory config so the rest of startup uses the new runtime.
|
|
240
|
+
// Disk has already been updated; subsequent loadConfig() calls will
|
|
241
|
+
// see the same value.
|
|
242
|
+
const defaults = config.defaults ?? {};
|
|
243
|
+
defaults.runtime = "process";
|
|
244
|
+
config.defaults = defaults;
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
warnAboutLegacyStorage();
|
|
248
|
+
await warnAboutOpenClawStatus(config);
|
|
249
|
+
// Prevent macOS idle sleep while AO is running (if enabled in config).
|
|
250
|
+
// Uses caffeinate -i -w <pid> to hold an assertion tied to this process
|
|
251
|
+
// lifetime. No-op on non-macOS platforms.
|
|
252
|
+
if (config.power?.preventIdleSleep !== false) {
|
|
253
|
+
const sleepHandle = preventIdleSleep();
|
|
254
|
+
if (sleepHandle) {
|
|
255
|
+
console.log(chalk.dim(" Preventing macOS idle sleep while AO is running"));
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
// Only inject OpenClaw credentials when the project actually uses OpenClaw.
|
|
259
|
+
// Avoids exposing API keys to projects/plugins that don't need them.
|
|
260
|
+
const openclawNotifier = config.notifiers?.["openclaw"];
|
|
261
|
+
const hasOpenClaw = openclawNotifier !== null &&
|
|
262
|
+
openclawNotifier !== undefined &&
|
|
263
|
+
typeof openclawNotifier === "object" &&
|
|
264
|
+
openclawNotifier.plugin === "openclaw";
|
|
265
|
+
if (hasOpenClaw) {
|
|
266
|
+
const injectedKeys = applyOpenClawCredentials();
|
|
267
|
+
if (injectedKeys.length > 0) {
|
|
268
|
+
const names = injectedKeys.map((k) => k.key).join(", ");
|
|
269
|
+
console.log(chalk.dim(` Resolved from OpenClaw config: ${names}`));
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
//# sourceMappingURL=startup-preflight.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"startup-preflight.js","sourceRoot":"","sources":["../../src/lib/startup-preflight.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Update-channel onboarding helpers.
|
|
3
|
+
*
|
|
4
|
+
* On first `athene start`, prompt the user once for an `updateChannel` and persist
|
|
5
|
+
* it to ~/.agent-orchestrator/config.yaml. Never re-prompt — if they dismiss
|
|
6
|
+
* (Ctrl+C / Esc), default to `manual` so we don't surprise-install anything.
|
|
7
|
+
*
|
|
8
|
+
* Spec: release-process.html §08 (Onboarding integration).
|
|
9
|
+
*/
|
|
10
|
+
import { type UpdateChannel } from "@made-by-moonlight/athene-core";
|
|
11
|
+
interface PromptDeps {
|
|
12
|
+
/** Test seam — defaults to the real prompt. */
|
|
13
|
+
prompt?: (message: string, options: {
|
|
14
|
+
value: UpdateChannel | "skip";
|
|
15
|
+
label: string;
|
|
16
|
+
hint?: string;
|
|
17
|
+
}[]) => Promise<UpdateChannel | "skip">;
|
|
18
|
+
/** Test seam — defaults to `isHumanCaller()`. */
|
|
19
|
+
isInteractive?: () => boolean;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Has the user already been asked about update channels?
|
|
23
|
+
*
|
|
24
|
+
* True when:
|
|
25
|
+
* - The global config exists AND has `updateChannel` set.
|
|
26
|
+
*
|
|
27
|
+
* False when:
|
|
28
|
+
* - The global config does not exist yet (first run — prompt fires immediately).
|
|
29
|
+
* - The global config exists but `updateChannel` is unset (existing user, pre-onboarding).
|
|
30
|
+
*/
|
|
31
|
+
export declare function hasChosenUpdateChannel(): boolean;
|
|
32
|
+
/**
|
|
33
|
+
* Persist the chosen channel to the global config.
|
|
34
|
+
*
|
|
35
|
+
* No-op when the global config doesn't exist — autoCreateConfig() handles
|
|
36
|
+
* bootstrap during first run. When the file exists but can't be parsed,
|
|
37
|
+
* falls back to a fresh default config.
|
|
38
|
+
*/
|
|
39
|
+
export declare function persistUpdateChannel(channel: UpdateChannel): void;
|
|
40
|
+
/**
|
|
41
|
+
* Prompt the user once and persist the chosen channel.
|
|
42
|
+
*
|
|
43
|
+
* Skipped silently when:
|
|
44
|
+
* - The choice was already made (idempotent — never re-prompts).
|
|
45
|
+
* - The caller is not interactive (CI, scripted athene start).
|
|
46
|
+
*
|
|
47
|
+
* On dismissal, persists `manual` so we don't ask again — surprise auto-installs
|
|
48
|
+
* are worse than a quiet manual default.
|
|
49
|
+
*/
|
|
50
|
+
export declare function maybePromptForUpdateChannel(deps?: PromptDeps): Promise<void>;
|
|
51
|
+
export {};
|
|
52
|
+
//# sourceMappingURL=update-channel-onboarding.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"update-channel-onboarding.d.ts","sourceRoot":"","sources":["../../src/lib/update-channel-onboarding.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,OAAO,EAOL,KAAK,aAAa,EACnB,MAAM,gCAAgC,CAAC;AAIxC,UAAU,UAAU;IAClB,+CAA+C;IAC/C,MAAM,CAAC,EAAE,CACP,OAAO,EAAE,MAAM,EACf,OAAO,EAAE;QAAE,KAAK,EAAE,aAAa,GAAG,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,EAAE,KACvE,OAAO,CAAC,aAAa,GAAG,MAAM,CAAC,CAAC;IACrC,iDAAiD;IACjD,aAAa,CAAC,EAAE,MAAM,OAAO,CAAC;CAC/B;AAED;;;;;;;;;GASG;AACH,wBAAgB,sBAAsB,IAAI,OAAO,CAQhD;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,aAAa,GAAG,IAAI,CAUjE;AAED;;;;;;;;;GASG;AACH,wBAAsB,2BAA2B,CAAC,IAAI,GAAE,UAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAgDtF"}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Update-channel onboarding helpers.
|
|
3
|
+
*
|
|
4
|
+
* On first `athene start`, prompt the user once for an `updateChannel` and persist
|
|
5
|
+
* it to ~/.agent-orchestrator/config.yaml. Never re-prompt — if they dismiss
|
|
6
|
+
* (Ctrl+C / Esc), default to `manual` so we don't surprise-install anything.
|
|
7
|
+
*
|
|
8
|
+
* Spec: release-process.html §08 (Onboarding integration).
|
|
9
|
+
*/
|
|
10
|
+
import { existsSync } from "node:fs";
|
|
11
|
+
import chalk from "chalk";
|
|
12
|
+
import { createDefaultGlobalConfig, getGlobalConfigPath, loadGlobalConfig, saveGlobalConfig, UpdateChannelSchema, } from "@made-by-moonlight/athene-core";
|
|
13
|
+
import { promptSelect } from "./prompts.js";
|
|
14
|
+
import { isHumanCaller } from "./caller-context.js";
|
|
15
|
+
/**
|
|
16
|
+
* Has the user already been asked about update channels?
|
|
17
|
+
*
|
|
18
|
+
* True when:
|
|
19
|
+
* - The global config exists AND has `updateChannel` set.
|
|
20
|
+
*
|
|
21
|
+
* False when:
|
|
22
|
+
* - The global config does not exist yet (first run — prompt fires immediately).
|
|
23
|
+
* - The global config exists but `updateChannel` is unset (existing user, pre-onboarding).
|
|
24
|
+
*/
|
|
25
|
+
export function hasChosenUpdateChannel() {
|
|
26
|
+
if (!existsSync(getGlobalConfigPath()))
|
|
27
|
+
return false;
|
|
28
|
+
try {
|
|
29
|
+
const config = loadGlobalConfig();
|
|
30
|
+
return Boolean(config?.updateChannel);
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
return true; // Don't pester users when config can't be read.
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Persist the chosen channel to the global config.
|
|
38
|
+
*
|
|
39
|
+
* No-op when the global config doesn't exist — autoCreateConfig() handles
|
|
40
|
+
* bootstrap during first run. When the file exists but can't be parsed,
|
|
41
|
+
* falls back to a fresh default config.
|
|
42
|
+
*/
|
|
43
|
+
export function persistUpdateChannel(channel) {
|
|
44
|
+
const path = getGlobalConfigPath();
|
|
45
|
+
// Don't create an empty global config here — autoCreateConfig() handles
|
|
46
|
+
// bootstrap (with project registration) during first run. Writing an empty
|
|
47
|
+
// husk poisons the dashboard, which loads the global config and finds
|
|
48
|
+
// zero projects.
|
|
49
|
+
if (!existsSync(path))
|
|
50
|
+
return;
|
|
51
|
+
const existing = loadGlobalConfig(path) ?? createDefaultGlobalConfig();
|
|
52
|
+
const next = { ...existing, updateChannel: channel };
|
|
53
|
+
saveGlobalConfig(next, path);
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Prompt the user once and persist the chosen channel.
|
|
57
|
+
*
|
|
58
|
+
* Skipped silently when:
|
|
59
|
+
* - The choice was already made (idempotent — never re-prompts).
|
|
60
|
+
* - The caller is not interactive (CI, scripted athene start).
|
|
61
|
+
*
|
|
62
|
+
* On dismissal, persists `manual` so we don't ask again — surprise auto-installs
|
|
63
|
+
* are worse than a quiet manual default.
|
|
64
|
+
*/
|
|
65
|
+
export async function maybePromptForUpdateChannel(deps = {}) {
|
|
66
|
+
const isInteractive = deps.isInteractive ?? isHumanCaller;
|
|
67
|
+
if (!isInteractive())
|
|
68
|
+
return;
|
|
69
|
+
if (hasChosenUpdateChannel())
|
|
70
|
+
return;
|
|
71
|
+
// No global config yet — skip. autoCreateConfig() handles full bootstrap
|
|
72
|
+
// (creating the global config and registering the project) during first run.
|
|
73
|
+
// On the next `athene start` the global config will exist and the prompt fires.
|
|
74
|
+
// Skipping here avoids writing an empty husk that poisons the dashboard.
|
|
75
|
+
if (!existsSync(getGlobalConfigPath()))
|
|
76
|
+
return;
|
|
77
|
+
console.log(chalk.bold("\nHow do you want to receive updates?"));
|
|
78
|
+
console.log(chalk.dim(" Stable ships every Thursday. Nightly ships daily Fri–Tue. Manual stays put."));
|
|
79
|
+
console.log(chalk.dim(" You can switch later with `athene config set updateChannel <value>` —\n the next `athene update` will prompt before installing the other channel's build.\n"));
|
|
80
|
+
const promptFn = deps.prompt ?? defaultPrompt;
|
|
81
|
+
let raw;
|
|
82
|
+
try {
|
|
83
|
+
raw = await promptFn("Update channel:", [
|
|
84
|
+
{ value: "stable", label: "Stable — weekly releases. Recommended for most users.", hint: "@latest" },
|
|
85
|
+
{ value: "nightly", label: "Nightly — daily builds. Bleeding edge.", hint: "@nightly" },
|
|
86
|
+
{ value: "manual", label: "Manual — no checks. Run `athene update` yourself.", hint: "default if dismissed" },
|
|
87
|
+
]);
|
|
88
|
+
}
|
|
89
|
+
catch {
|
|
90
|
+
raw = "manual";
|
|
91
|
+
}
|
|
92
|
+
// Never re-prompt: the absence of `updateChannel` is the signal we use to
|
|
93
|
+
// know we haven't asked yet, so even on dismissal we must persist *something*.
|
|
94
|
+
// Validate against the schema before writing — never persist `undefined` or
|
|
95
|
+
// an unrecognized string (which would corrupt the config and re-trigger
|
|
96
|
+
// every Zod parse path with `.catch(undefined)` fallbacks).
|
|
97
|
+
const candidate = raw === "skip" || raw === undefined ? "manual" : raw;
|
|
98
|
+
const parsed = UpdateChannelSchema.safeParse(candidate);
|
|
99
|
+
const channel = parsed.success ? parsed.data : "manual";
|
|
100
|
+
persistUpdateChannel(channel);
|
|
101
|
+
console.log(chalk.green(` ✓ Update channel set to ${chalk.bold(channel)}`));
|
|
102
|
+
console.log(chalk.dim(` Change it later with: athene config set updateChannel <stable|nightly|manual>\n`));
|
|
103
|
+
}
|
|
104
|
+
async function defaultPrompt(message, options) {
|
|
105
|
+
return promptSelect(message, options);
|
|
106
|
+
}
|
|
107
|
+
//# sourceMappingURL=update-channel-onboarding.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"update-channel-onboarding.js","sourceRoot":"","sources":["../../src/lib/update-channel-onboarding.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared update service — install detection, version checking, cache management.
|
|
3
|
+
*
|
|
4
|
+
* Single source of truth consumed by:
|
|
5
|
+
* - `athene update` (install-aware routing)
|
|
6
|
+
* - Startup notifier (synchronous cache read)
|
|
7
|
+
* - `athene doctor` (version freshness check)
|
|
8
|
+
* - Dashboard (`/api/version` route)
|
|
9
|
+
*/
|
|
10
|
+
import { isVersionOutdated as coreIsVersionOutdated, type UpdateChannel, type InstallMethodOverride } from "@made-by-moonlight/athene-core";
|
|
11
|
+
export type InstallMethod = "git" | "npm-global" | "pnpm-global" | "bun-global" | "homebrew" | "unknown";
|
|
12
|
+
export interface UpdateInfo {
|
|
13
|
+
currentVersion: string;
|
|
14
|
+
latestVersion: string | null;
|
|
15
|
+
isOutdated: boolean;
|
|
16
|
+
installMethod: InstallMethod;
|
|
17
|
+
recommendedCommand: string;
|
|
18
|
+
checkedAt: string | null;
|
|
19
|
+
channel: UpdateChannel;
|
|
20
|
+
}
|
|
21
|
+
export interface CacheData {
|
|
22
|
+
latestVersion: string;
|
|
23
|
+
checkedAt: string;
|
|
24
|
+
currentVersionAtCheck: string;
|
|
25
|
+
/**
|
|
26
|
+
* Cache scoping. The cache stores exactly one entry — entries for a
|
|
27
|
+
* different install method or channel are treated as misses, forcing a
|
|
28
|
+
* refresh against the relevant source (git fetch / npm registry).
|
|
29
|
+
*/
|
|
30
|
+
installMethod?: InstallMethod;
|
|
31
|
+
channel?: UpdateChannel;
|
|
32
|
+
/** For non-git installs, derived from `isVersionOutdated(current, latest)`. */
|
|
33
|
+
isOutdated?: boolean;
|
|
34
|
+
/** For git installs, lets us cheaply detect a manual `git pull` since the last check. */
|
|
35
|
+
currentRevisionAtCheck?: string;
|
|
36
|
+
latestRevisionAtCheck?: string;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Resolve the user's chosen update channel from global config.
|
|
40
|
+
*
|
|
41
|
+
* Defaults to "manual" when:
|
|
42
|
+
* - The global config does not exist yet (first run).
|
|
43
|
+
* - The user has not set `updateChannel` (existing user, pre-onboarding).
|
|
44
|
+
*
|
|
45
|
+
* "manual" is intentionally conservative: surprise auto-installs are bad,
|
|
46
|
+
* and the onboarding flow promotes users to "stable" or "nightly" explicitly.
|
|
47
|
+
*/
|
|
48
|
+
export declare function resolveUpdateChannel(): UpdateChannel;
|
|
49
|
+
/** Read the install-method override from global config (if any). */
|
|
50
|
+
export declare function resolveInstallMethodOverride(): InstallMethodOverride | undefined;
|
|
51
|
+
export declare function hasNodeModulesAncestor(resolvedPath: string): boolean;
|
|
52
|
+
export declare function getCurrentRepoRoot(): string;
|
|
53
|
+
export declare function isAgentOrchestratorRepoRoot(root: string): boolean;
|
|
54
|
+
export declare function isAoCliPackageRoot(root: string): boolean;
|
|
55
|
+
/**
|
|
56
|
+
* Classify a resolved file path as one of the known install methods.
|
|
57
|
+
*
|
|
58
|
+
* Order matters — Homebrew installs typically nest the npm tree under
|
|
59
|
+
* `/Cellar/ao/.../libexec/lib/node_modules/`, so we check for `/Cellar/ao/`
|
|
60
|
+
* BEFORE classifying as `npm-global`. Bun's global store sits under
|
|
61
|
+
* `~/.bun/install/global/` and is detected the same way.
|
|
62
|
+
*/
|
|
63
|
+
export declare function classifyInstallPath(resolvedPath: string): InstallMethod;
|
|
64
|
+
/** Detect how the running `ao` binary was installed. Honors `installMethod` override. */
|
|
65
|
+
export declare function detectInstallMethod(): InstallMethod;
|
|
66
|
+
/**
|
|
67
|
+
* Resolve the currently-installed `@made-by-moonlight/athene` version.
|
|
68
|
+
*
|
|
69
|
+
* Delegates to core's `getInstalledAoVersion` (single source of truth shared
|
|
70
|
+
* with the dashboard) and falls back to the CLI's own embedded version when
|
|
71
|
+
* neither package is in `node_modules` (test/dev edge case).
|
|
72
|
+
*/
|
|
73
|
+
export declare function getCurrentVersion(): string;
|
|
74
|
+
export interface GitUpdateTarget {
|
|
75
|
+
remote: string;
|
|
76
|
+
branch: string;
|
|
77
|
+
ref: string;
|
|
78
|
+
}
|
|
79
|
+
export declare function getGitUpdateTarget(): GitUpdateTarget;
|
|
80
|
+
export declare function getGitUpdateRef(): string;
|
|
81
|
+
/**
|
|
82
|
+
* Map an install method + channel to the command the user should run.
|
|
83
|
+
*
|
|
84
|
+
* Git installs always run `athene update` (which delegates to `athene-update.sh`)
|
|
85
|
+
* regardless of channel — the channel only affects npm-published builds.
|
|
86
|
+
*
|
|
87
|
+
* Homebrew is special: we never auto-install. We surface the brew command as
|
|
88
|
+
* a notice so the user runs it themselves — auto-running `npm install -g`
|
|
89
|
+
* inside a brew prefix overwrites brew's symlinks.
|
|
90
|
+
*/
|
|
91
|
+
export declare function getUpdateCommand(method: InstallMethod, channel?: UpdateChannel): string;
|
|
92
|
+
/** True when the install method requires a manual user action (no auto-install). */
|
|
93
|
+
export declare function isManualOnlyInstall(method: InstallMethod): boolean;
|
|
94
|
+
export declare function isOutdatedForChannel(currentVersion: string, latestVersion: string, channel: UpdateChannel): boolean;
|
|
95
|
+
/** Directory holding the update cache. Re-exported for athene doctor / CLI smoke tests. */
|
|
96
|
+
export declare function getCacheDir(): string;
|
|
97
|
+
/**
|
|
98
|
+
* Read cached update info. Returns null if missing, expired, corrupt,
|
|
99
|
+
* version-mismatched, install-method-mismatched, or channel-mismatched.
|
|
100
|
+
*
|
|
101
|
+
* The cache is keyed by both `installMethod` and `channel` because the
|
|
102
|
+
* `latestVersion` stored at each tuple is meaningfully different (stable
|
|
103
|
+
* 0.5.0 vs nightly 0.5.0-nightly-abc; git's `origin/main` ref vs npm tag).
|
|
104
|
+
*/
|
|
105
|
+
export declare function readCachedUpdateInfo(installMethod?: InstallMethod, channel?: UpdateChannel): CacheData | null;
|
|
106
|
+
export declare function writeCache(data: CacheData): void;
|
|
107
|
+
export declare function invalidateCache(): void;
|
|
108
|
+
export interface GitLatestState {
|
|
109
|
+
ref: string;
|
|
110
|
+
headRevision: string;
|
|
111
|
+
latestRevision: string;
|
|
112
|
+
isBehind: boolean;
|
|
113
|
+
}
|
|
114
|
+
export declare function fetchGitLatestState(repoRoot?: string): Promise<GitLatestState | null>;
|
|
115
|
+
/**
|
|
116
|
+
* Fetch the latest version of @made-by-moonlight/athene for the given dist-tag.
|
|
117
|
+
*
|
|
118
|
+
* Hits the full package document (not the per-tag URL) so we get all dist-tags
|
|
119
|
+
* in one round trip. Channels:
|
|
120
|
+
* stable / manual → dist-tags.latest
|
|
121
|
+
* nightly → dist-tags.nightly (falls back to latest if no nightly tag)
|
|
122
|
+
*/
|
|
123
|
+
export declare function fetchLatestVersion(channel?: UpdateChannel): Promise<string | null>;
|
|
124
|
+
/**
|
|
125
|
+
* Check for updates, using cache when fresh and fetching when stale.
|
|
126
|
+
*
|
|
127
|
+
* Source of truth depends on install method:
|
|
128
|
+
* - git installs → `git fetch <remote> <branch>` + `merge-base`
|
|
129
|
+
* - npm/pnpm/bun/... → npm registry, dist-tags[channel]
|
|
130
|
+
*
|
|
131
|
+
* When the channel is "manual" the function still runs (so `--check` works
|
|
132
|
+
* and the dashboard can show current state) but the startup notice and the
|
|
133
|
+
* background refresh respect the channel and stay quiet.
|
|
134
|
+
*/
|
|
135
|
+
export declare function checkForUpdate(opts?: {
|
|
136
|
+
force?: boolean;
|
|
137
|
+
channel?: UpdateChannel;
|
|
138
|
+
installMethod?: InstallMethod;
|
|
139
|
+
repoRoot?: string;
|
|
140
|
+
}): Promise<UpdateInfo>;
|
|
141
|
+
/**
|
|
142
|
+
* Print an update notice to stderr if a newer version is cached.
|
|
143
|
+
*
|
|
144
|
+
* Skipped entirely when channel is "manual" — the user opted out of nudges.
|
|
145
|
+
* Stable users see "Run: athene update". Nightly users get the same nudge but
|
|
146
|
+
* the suggested install command picks `@nightly` instead of `@latest`.
|
|
147
|
+
*/
|
|
148
|
+
export declare function maybeShowUpdateNotice(): void;
|
|
149
|
+
/**
|
|
150
|
+
* Kick off a background cache refresh. Skips entirely on `manual` channel
|
|
151
|
+
* so users who opted out don't generate any registry traffic.
|
|
152
|
+
*/
|
|
153
|
+
export declare function scheduleBackgroundRefresh(): void;
|
|
154
|
+
/**
|
|
155
|
+
* Re-export the core implementation so CLI consumers (and the existing test
|
|
156
|
+
* suite) keep importing from this module while the dashboard imports the same
|
|
157
|
+
* function from `@made-by-moonlight/athene-core` — single source of truth for the prerelease
|
|
158
|
+
* comparison rules.
|
|
159
|
+
*/
|
|
160
|
+
export declare const isVersionOutdated: typeof coreIsVersionOutdated;
|
|
161
|
+
//# sourceMappingURL=update-check.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"update-check.d.ts","sourceRoot":"","sources":["../../src/lib/update-check.ts"],"names":[],"mappings":"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"}
|