@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.
Files changed (315) hide show
  1. package/LICENSE +22 -0
  2. package/dist/assets/plugin-registry.json +67 -0
  3. package/dist/assets/scripts/athene-doctor.ps1 +352 -0
  4. package/dist/assets/scripts/athene-doctor.sh +552 -0
  5. package/dist/assets/scripts/athene-update.ps1 +224 -0
  6. package/dist/assets/scripts/athene-update.sh +252 -0
  7. package/dist/commands/completion.d.ts +3 -0
  8. package/dist/commands/completion.d.ts.map +1 -0
  9. package/dist/commands/completion.js +26 -0
  10. package/dist/commands/completion.js.map +1 -0
  11. package/dist/commands/config.d.ts +11 -0
  12. package/dist/commands/config.d.ts.map +1 -0
  13. package/dist/commands/config.js +89 -0
  14. package/dist/commands/config.js.map +1 -0
  15. package/dist/commands/dashboard.d.ts +3 -0
  16. package/dist/commands/dashboard.d.ts.map +1 -0
  17. package/dist/commands/dashboard.js +103 -0
  18. package/dist/commands/dashboard.js.map +1 -0
  19. package/dist/commands/doctor.d.ts +3 -0
  20. package/dist/commands/doctor.d.ts.map +1 -0
  21. package/dist/commands/doctor.js +329 -0
  22. package/dist/commands/doctor.js.map +1 -0
  23. package/dist/commands/events.d.ts +3 -0
  24. package/dist/commands/events.d.ts.map +1 -0
  25. package/dist/commands/events.js +172 -0
  26. package/dist/commands/events.js.map +1 -0
  27. package/dist/commands/migrate-storage.d.ts +3 -0
  28. package/dist/commands/migrate-storage.d.ts.map +1 -0
  29. package/dist/commands/migrate-storage.js +78 -0
  30. package/dist/commands/migrate-storage.js.map +1 -0
  31. package/dist/commands/notify.d.ts +3 -0
  32. package/dist/commands/notify.d.ts.map +1 -0
  33. package/dist/commands/notify.js +143 -0
  34. package/dist/commands/notify.js.map +1 -0
  35. package/dist/commands/open.d.ts +3 -0
  36. package/dist/commands/open.d.ts.map +1 -0
  37. package/dist/commands/open.js +167 -0
  38. package/dist/commands/open.js.map +1 -0
  39. package/dist/commands/plugin.d.ts +3 -0
  40. package/dist/commands/plugin.d.ts.map +1 -0
  41. package/dist/commands/plugin.js +462 -0
  42. package/dist/commands/plugin.js.map +1 -0
  43. package/dist/commands/project.d.ts +3 -0
  44. package/dist/commands/project.d.ts.map +1 -0
  45. package/dist/commands/project.js +143 -0
  46. package/dist/commands/project.js.map +1 -0
  47. package/dist/commands/report.d.ts +19 -0
  48. package/dist/commands/report.d.ts.map +1 -0
  49. package/dist/commands/report.js +114 -0
  50. package/dist/commands/report.js.map +1 -0
  51. package/dist/commands/review-check.d.ts +3 -0
  52. package/dist/commands/review-check.d.ts.map +1 -0
  53. package/dist/commands/review-check.js +122 -0
  54. package/dist/commands/review-check.js.map +1 -0
  55. package/dist/commands/review.d.ts +3 -0
  56. package/dist/commands/review.d.ts.map +1 -0
  57. package/dist/commands/review.js +215 -0
  58. package/dist/commands/review.js.map +1 -0
  59. package/dist/commands/send.d.ts +3 -0
  60. package/dist/commands/send.d.ts.map +1 -0
  61. package/dist/commands/send.js +187 -0
  62. package/dist/commands/send.js.map +1 -0
  63. package/dist/commands/session.d.ts +3 -0
  64. package/dist/commands/session.d.ts.map +1 -0
  65. package/dist/commands/session.js +439 -0
  66. package/dist/commands/session.js.map +1 -0
  67. package/dist/commands/setup.d.ts +5 -0
  68. package/dist/commands/setup.d.ts.map +1 -0
  69. package/dist/commands/setup.js +297 -0
  70. package/dist/commands/setup.js.map +1 -0
  71. package/dist/commands/spawn.d.ts +4 -0
  72. package/dist/commands/spawn.d.ts.map +1 -0
  73. package/dist/commands/spawn.js +436 -0
  74. package/dist/commands/spawn.js.map +1 -0
  75. package/dist/commands/start.d.ts +21 -0
  76. package/dist/commands/start.d.ts.map +1 -0
  77. package/dist/commands/start.js +1836 -0
  78. package/dist/commands/start.js.map +1 -0
  79. package/dist/commands/status.d.ts +3 -0
  80. package/dist/commands/status.d.ts.map +1 -0
  81. package/dist/commands/status.js +556 -0
  82. package/dist/commands/status.js.map +1 -0
  83. package/dist/commands/update.d.ts +15 -0
  84. package/dist/commands/update.d.ts.map +1 -0
  85. package/dist/commands/update.js +652 -0
  86. package/dist/commands/update.js.map +1 -0
  87. package/dist/commands/verify.d.ts +3 -0
  88. package/dist/commands/verify.d.ts.map +1 -0
  89. package/dist/commands/verify.js +131 -0
  90. package/dist/commands/verify.js.map +1 -0
  91. package/dist/index.d.ts +3 -0
  92. package/dist/index.d.ts.map +1 -0
  93. package/dist/index.js +24 -0
  94. package/dist/index.js.map +1 -0
  95. package/dist/lib/bun-tmp-janitor.d.ts +18 -0
  96. package/dist/lib/bun-tmp-janitor.d.ts.map +1 -0
  97. package/dist/lib/bun-tmp-janitor.js +127 -0
  98. package/dist/lib/bun-tmp-janitor.js.map +1 -0
  99. package/dist/lib/caller-context.d.ts +13 -0
  100. package/dist/lib/caller-context.d.ts.map +1 -0
  101. package/dist/lib/caller-context.js +20 -0
  102. package/dist/lib/caller-context.js.map +1 -0
  103. package/dist/lib/cli-errors.d.ts +8 -0
  104. package/dist/lib/cli-errors.d.ts.map +1 -0
  105. package/dist/lib/cli-errors.js +20 -0
  106. package/dist/lib/cli-errors.js.map +1 -0
  107. package/dist/lib/completion.d.ts +13 -0
  108. package/dist/lib/completion.d.ts.map +1 -0
  109. package/dist/lib/completion.js +428 -0
  110. package/dist/lib/completion.js.map +1 -0
  111. package/dist/lib/composio-setup.d.ts +65 -0
  112. package/dist/lib/composio-setup.d.ts.map +1 -0
  113. package/dist/lib/composio-setup.js +3255 -0
  114. package/dist/lib/composio-setup.js.map +1 -0
  115. package/dist/lib/config-instruction.d.ts +2 -0
  116. package/dist/lib/config-instruction.d.ts.map +1 -0
  117. package/dist/lib/config-instruction.js +193 -0
  118. package/dist/lib/config-instruction.js.map +1 -0
  119. package/dist/lib/constants.d.ts +3 -0
  120. package/dist/lib/constants.d.ts.map +1 -0
  121. package/dist/lib/constants.js +3 -0
  122. package/dist/lib/constants.js.map +1 -0
  123. package/dist/lib/create-session-manager.d.ts +26 -0
  124. package/dist/lib/create-session-manager.d.ts.map +1 -0
  125. package/dist/lib/create-session-manager.js +55 -0
  126. package/dist/lib/create-session-manager.js.map +1 -0
  127. package/dist/lib/credential-resolver.d.ts +37 -0
  128. package/dist/lib/credential-resolver.d.ts.map +1 -0
  129. package/dist/lib/credential-resolver.js +105 -0
  130. package/dist/lib/credential-resolver.js.map +1 -0
  131. package/dist/lib/daemon.d.ts +69 -0
  132. package/dist/lib/daemon.d.ts.map +1 -0
  133. package/dist/lib/daemon.js +77 -0
  134. package/dist/lib/daemon.js.map +1 -0
  135. package/dist/lib/dashboard-rebuild.d.ts +53 -0
  136. package/dist/lib/dashboard-rebuild.d.ts.map +1 -0
  137. package/dist/lib/dashboard-rebuild.js +188 -0
  138. package/dist/lib/dashboard-rebuild.js.map +1 -0
  139. package/dist/lib/dashboard-setup.d.ts +14 -0
  140. package/dist/lib/dashboard-setup.d.ts.map +1 -0
  141. package/dist/lib/dashboard-setup.js +192 -0
  142. package/dist/lib/dashboard-setup.js.map +1 -0
  143. package/dist/lib/dashboard-url.d.ts +19 -0
  144. package/dist/lib/dashboard-url.d.ts.map +1 -0
  145. package/dist/lib/dashboard-url.js +25 -0
  146. package/dist/lib/dashboard-url.js.map +1 -0
  147. package/dist/lib/desktop-setup.d.ts +21 -0
  148. package/dist/lib/desktop-setup.d.ts.map +1 -0
  149. package/dist/lib/desktop-setup.js +556 -0
  150. package/dist/lib/desktop-setup.js.map +1 -0
  151. package/dist/lib/detect-agent.d.ts +24 -0
  152. package/dist/lib/detect-agent.d.ts.map +1 -0
  153. package/dist/lib/detect-agent.js +69 -0
  154. package/dist/lib/detect-agent.js.map +1 -0
  155. package/dist/lib/detect-env.d.ts +14 -0
  156. package/dist/lib/detect-env.d.ts.map +1 -0
  157. package/dist/lib/detect-env.js +46 -0
  158. package/dist/lib/detect-env.js.map +1 -0
  159. package/dist/lib/discord-setup.d.ts +20 -0
  160. package/dist/lib/discord-setup.d.ts.map +1 -0
  161. package/dist/lib/discord-setup.js +584 -0
  162. package/dist/lib/discord-setup.js.map +1 -0
  163. package/dist/lib/format.d.ts +11 -0
  164. package/dist/lib/format.d.ts.map +1 -0
  165. package/dist/lib/format.js +116 -0
  166. package/dist/lib/format.js.map +1 -0
  167. package/dist/lib/git-utils.d.ts +14 -0
  168. package/dist/lib/git-utils.d.ts.map +1 -0
  169. package/dist/lib/git-utils.js +45 -0
  170. package/dist/lib/git-utils.js.map +1 -0
  171. package/dist/lib/install-helpers.d.ts +24 -0
  172. package/dist/lib/install-helpers.d.ts.map +1 -0
  173. package/dist/lib/install-helpers.js +76 -0
  174. package/dist/lib/install-helpers.js.map +1 -0
  175. package/dist/lib/lifecycle-service.d.ts +11 -0
  176. package/dist/lib/lifecycle-service.d.ts.map +1 -0
  177. package/dist/lib/lifecycle-service.js +65 -0
  178. package/dist/lib/lifecycle-service.js.map +1 -0
  179. package/dist/lib/notifier-routing.d.ts +35 -0
  180. package/dist/lib/notifier-routing.d.ts.map +1 -0
  181. package/dist/lib/notifier-routing.js +133 -0
  182. package/dist/lib/notifier-routing.js.map +1 -0
  183. package/dist/lib/notify-test.d.ts +72 -0
  184. package/dist/lib/notify-test.d.ts.map +1 -0
  185. package/dist/lib/notify-test.js +674 -0
  186. package/dist/lib/notify-test.js.map +1 -0
  187. package/dist/lib/openclaw-probe.d.ts +38 -0
  188. package/dist/lib/openclaw-probe.d.ts.map +1 -0
  189. package/dist/lib/openclaw-probe.js +146 -0
  190. package/dist/lib/openclaw-probe.js.map +1 -0
  191. package/dist/lib/openclaw-setup.d.ts +19 -0
  192. package/dist/lib/openclaw-setup.d.ts.map +1 -0
  193. package/dist/lib/openclaw-setup.js +684 -0
  194. package/dist/lib/openclaw-setup.js.map +1 -0
  195. package/dist/lib/path-equality.d.ts +29 -0
  196. package/dist/lib/path-equality.d.ts.map +1 -0
  197. package/dist/lib/path-equality.js +52 -0
  198. package/dist/lib/path-equality.js.map +1 -0
  199. package/dist/lib/plugin-marketplace.d.ts +24 -0
  200. package/dist/lib/plugin-marketplace.d.ts.map +1 -0
  201. package/dist/lib/plugin-marketplace.js +175 -0
  202. package/dist/lib/plugin-marketplace.js.map +1 -0
  203. package/dist/lib/plugin-scaffold.d.ts +14 -0
  204. package/dist/lib/plugin-scaffold.d.ts.map +1 -0
  205. package/dist/lib/plugin-scaffold.js +174 -0
  206. package/dist/lib/plugin-scaffold.js.map +1 -0
  207. package/dist/lib/plugin-store.d.ts +9 -0
  208. package/dist/lib/plugin-store.d.ts.map +1 -0
  209. package/dist/lib/plugin-store.js +121 -0
  210. package/dist/lib/plugin-store.js.map +1 -0
  211. package/dist/lib/plugins.d.ts +17 -0
  212. package/dist/lib/plugins.d.ts.map +1 -0
  213. package/dist/lib/plugins.js +65 -0
  214. package/dist/lib/plugins.js.map +1 -0
  215. package/dist/lib/portfolio-display.d.ts +10 -0
  216. package/dist/lib/portfolio-display.d.ts.map +1 -0
  217. package/dist/lib/portfolio-display.js +17 -0
  218. package/dist/lib/portfolio-display.js.map +1 -0
  219. package/dist/lib/preflight.d.ts +27 -0
  220. package/dist/lib/preflight.d.ts.map +1 -0
  221. package/dist/lib/preflight.js +77 -0
  222. package/dist/lib/preflight.js.map +1 -0
  223. package/dist/lib/prevent-sleep.d.ts +34 -0
  224. package/dist/lib/prevent-sleep.d.ts.map +1 -0
  225. package/dist/lib/prevent-sleep.js +65 -0
  226. package/dist/lib/prevent-sleep.js.map +1 -0
  227. package/dist/lib/project-detection.d.ts +11 -0
  228. package/dist/lib/project-detection.d.ts.map +1 -0
  229. package/dist/lib/project-detection.js +206 -0
  230. package/dist/lib/project-detection.js.map +1 -0
  231. package/dist/lib/project-resolution.d.ts +10 -0
  232. package/dist/lib/project-resolution.d.ts.map +1 -0
  233. package/dist/lib/project-resolution.js +17 -0
  234. package/dist/lib/project-resolution.js.map +1 -0
  235. package/dist/lib/project-supervisor.d.ts +28 -0
  236. package/dist/lib/project-supervisor.d.ts.map +1 -0
  237. package/dist/lib/project-supervisor.js +167 -0
  238. package/dist/lib/project-supervisor.js.map +1 -0
  239. package/dist/lib/prompts.d.ts +7 -0
  240. package/dist/lib/prompts.d.ts.map +1 -0
  241. package/dist/lib/prompts.js +37 -0
  242. package/dist/lib/prompts.js.map +1 -0
  243. package/dist/lib/repo-utils.d.ts +16 -0
  244. package/dist/lib/repo-utils.d.ts.map +1 -0
  245. package/dist/lib/repo-utils.js +26 -0
  246. package/dist/lib/repo-utils.js.map +1 -0
  247. package/dist/lib/resolve-project.d.ts +113 -0
  248. package/dist/lib/resolve-project.d.ts.map +1 -0
  249. package/dist/lib/resolve-project.js +433 -0
  250. package/dist/lib/resolve-project.js.map +1 -0
  251. package/dist/lib/routes.d.ts +2 -0
  252. package/dist/lib/routes.d.ts.map +1 -0
  253. package/dist/lib/routes.js +5 -0
  254. package/dist/lib/routes.js.map +1 -0
  255. package/dist/lib/running-state.d.ts +76 -0
  256. package/dist/lib/running-state.d.ts.map +1 -0
  257. package/dist/lib/running-state.js +338 -0
  258. package/dist/lib/running-state.js.map +1 -0
  259. package/dist/lib/script-runner.d.ts +10 -0
  260. package/dist/lib/script-runner.d.ts.map +1 -0
  261. package/dist/lib/script-runner.js +189 -0
  262. package/dist/lib/script-runner.js.map +1 -0
  263. package/dist/lib/session-utils.d.ts +14 -0
  264. package/dist/lib/session-utils.d.ts.map +1 -0
  265. package/dist/lib/session-utils.js +58 -0
  266. package/dist/lib/session-utils.js.map +1 -0
  267. package/dist/lib/shell.d.ts +17 -0
  268. package/dist/lib/shell.d.ts.map +1 -0
  269. package/dist/lib/shell.js +90 -0
  270. package/dist/lib/shell.js.map +1 -0
  271. package/dist/lib/shutdown.d.ts +30 -0
  272. package/dist/lib/shutdown.d.ts.map +1 -0
  273. package/dist/lib/shutdown.js +177 -0
  274. package/dist/lib/shutdown.js.map +1 -0
  275. package/dist/lib/slack-setup.d.ts +17 -0
  276. package/dist/lib/slack-setup.d.ts.map +1 -0
  277. package/dist/lib/slack-setup.js +485 -0
  278. package/dist/lib/slack-setup.js.map +1 -0
  279. package/dist/lib/startup-preflight.d.ts +36 -0
  280. package/dist/lib/startup-preflight.d.ts.map +1 -0
  281. package/dist/lib/startup-preflight.js +273 -0
  282. package/dist/lib/startup-preflight.js.map +1 -0
  283. package/dist/lib/update-channel-onboarding.d.ts +52 -0
  284. package/dist/lib/update-channel-onboarding.d.ts.map +1 -0
  285. package/dist/lib/update-channel-onboarding.js +107 -0
  286. package/dist/lib/update-channel-onboarding.js.map +1 -0
  287. package/dist/lib/update-check.d.ts +161 -0
  288. package/dist/lib/update-check.d.ts.map +1 -0
  289. package/dist/lib/update-check.js +504 -0
  290. package/dist/lib/update-check.js.map +1 -0
  291. package/dist/lib/web-dir.d.ts +47 -0
  292. package/dist/lib/web-dir.d.ts.map +1 -0
  293. package/dist/lib/web-dir.js +179 -0
  294. package/dist/lib/web-dir.js.map +1 -0
  295. package/dist/lib/webhook-setup.d.ts +16 -0
  296. package/dist/lib/webhook-setup.d.ts.map +1 -0
  297. package/dist/lib/webhook-setup.js +383 -0
  298. package/dist/lib/webhook-setup.js.map +1 -0
  299. package/dist/options/version.d.ts +2 -0
  300. package/dist/options/version.d.ts.map +1 -0
  301. package/dist/options/version.js +7 -0
  302. package/dist/options/version.js.map +1 -0
  303. package/dist/program.d.ts +3 -0
  304. package/dist/program.d.ts.map +1 -0
  305. package/dist/program.js +63 -0
  306. package/dist/program.js.map +1 -0
  307. package/package.json +80 -0
  308. package/templates/rules/base.md +4 -0
  309. package/templates/rules/go.md +8 -0
  310. package/templates/rules/javascript.md +4 -0
  311. package/templates/rules/nextjs.md +7 -0
  312. package/templates/rules/pnpm-workspaces.md +4 -0
  313. package/templates/rules/python.md +8 -0
  314. package/templates/rules/react.md +8 -0
  315. package/templates/rules/typescript.md +6 -0
@@ -0,0 +1,504 @@
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 { execFile, execFileSync } from "node:child_process";
11
+ import { existsSync, mkdirSync, readFileSync, unlinkSync, writeFileSync } from "node:fs";
12
+ import { dirname, resolve } from "node:path";
13
+ import { fileURLToPath } from "node:url";
14
+ import { promisify } from "node:util";
15
+ import { getInstalledAoVersion, getUpdateCheckCachePath, isVersionOutdatedForChannel as coreIsVersionOutdatedForChannel, isVersionOutdated as coreIsVersionOutdated, loadGlobalConfig, } from "@made-by-moonlight/athene-core";
16
+ import { getCliVersion } from "../options/version.js";
17
+ // ---------------------------------------------------------------------------
18
+ // Constants
19
+ // ---------------------------------------------------------------------------
20
+ /** Full package document — includes `dist-tags` for channel resolution. */
21
+ const REGISTRY_PACKAGE_URL = "https://registry.npmjs.org/@made-by-moonlight%2Fathene";
22
+ const FETCH_TIMEOUT_MS = 3000;
23
+ const CACHE_TTL_MS = 24 * 60 * 60 * 1000; // 24 hours
24
+ const DEFAULT_GIT_REMOTE = "origin";
25
+ const DEFAULT_GIT_BRANCH = "main";
26
+ const execFileAsync = promisify(execFile);
27
+ // ---------------------------------------------------------------------------
28
+ // Channel resolution
29
+ // ---------------------------------------------------------------------------
30
+ /**
31
+ * Resolve the user's chosen update channel from global config.
32
+ *
33
+ * Defaults to "manual" when:
34
+ * - The global config does not exist yet (first run).
35
+ * - The user has not set `updateChannel` (existing user, pre-onboarding).
36
+ *
37
+ * "manual" is intentionally conservative: surprise auto-installs are bad,
38
+ * and the onboarding flow promotes users to "stable" or "nightly" explicitly.
39
+ */
40
+ export function resolveUpdateChannel() {
41
+ try {
42
+ const config = loadGlobalConfig();
43
+ return config?.updateChannel ?? "manual";
44
+ }
45
+ catch {
46
+ return "manual";
47
+ }
48
+ }
49
+ /** Read the install-method override from global config (if any). */
50
+ export function resolveInstallMethodOverride() {
51
+ try {
52
+ const config = loadGlobalConfig();
53
+ return config?.installMethod;
54
+ }
55
+ catch {
56
+ return undefined;
57
+ }
58
+ }
59
+ // ---------------------------------------------------------------------------
60
+ // Install detection
61
+ // ---------------------------------------------------------------------------
62
+ export function hasNodeModulesAncestor(resolvedPath) {
63
+ return resolvedPath.includes("/node_modules/") || resolvedPath.includes("\\node_modules\\");
64
+ }
65
+ function readPackageName(packageJsonPath) {
66
+ try {
67
+ const raw = readFileSync(packageJsonPath, "utf-8");
68
+ const parsed = JSON.parse(raw);
69
+ return typeof parsed.name === "string" ? parsed.name : null;
70
+ }
71
+ catch {
72
+ return null;
73
+ }
74
+ }
75
+ function getSourceRepoRoot(resolvedPath) {
76
+ return resolve(dirname(resolvedPath), "../../../../");
77
+ }
78
+ export function getCurrentRepoRoot() {
79
+ return getSourceRepoRoot(fileURLToPath(import.meta.url));
80
+ }
81
+ export function isAgentOrchestratorRepoRoot(root) {
82
+ if (!existsSync(resolve(root, ".git"))) {
83
+ return false;
84
+ }
85
+ return readPackageName(resolve(root, "packages", "ao", "package.json")) === "@made-by-moonlight/athene";
86
+ }
87
+ export function isAoCliPackageRoot(root) {
88
+ if (!existsSync(resolve(root, "dist", "index.js"))) {
89
+ return false;
90
+ }
91
+ return readPackageName(resolve(root, "package.json")) === "@made-by-moonlight/athene-cli";
92
+ }
93
+ /**
94
+ * Classify a resolved file path as one of the known install methods.
95
+ *
96
+ * Order matters — Homebrew installs typically nest the npm tree under
97
+ * `/Cellar/ao/.../libexec/lib/node_modules/`, so we check for `/Cellar/ao/`
98
+ * BEFORE classifying as `npm-global`. Bun's global store sits under
99
+ * `~/.bun/install/global/` and is detected the same way.
100
+ */
101
+ export function classifyInstallPath(resolvedPath) {
102
+ // Homebrew installs of the `ao` formula land under /Cellar/ao/<version>/.
103
+ // Detect this BEFORE the generic node_modules walk, because brew installs
104
+ // also live under .../lib/node_modules/. We don't auto-install for brew —
105
+ // that would clobber the symlinks brew owns.
106
+ if (resolvedPath.includes("/Cellar/ao/") || resolvedPath.includes("\\Cellar\\ao\\")) {
107
+ return "homebrew";
108
+ }
109
+ // Bun's global install layout: ~/.bun/install/global/node_modules/...
110
+ if (resolvedPath.includes("/.bun/install/global/") ||
111
+ resolvedPath.includes("\\.bun\\install\\global\\")) {
112
+ return "bun-global";
113
+ }
114
+ if (hasNodeModulesAncestor(resolvedPath)) {
115
+ const isPnpmGlobal = resolvedPath.includes("/pnpm/global/") || resolvedPath.includes("\\pnpm\\global\\");
116
+ if (isPnpmGlobal)
117
+ return "pnpm-global";
118
+ const isNpmGlobal = resolvedPath.includes("/lib/node_modules/") || resolvedPath.includes("\\lib\\node_modules\\");
119
+ if (isNpmGlobal)
120
+ return "npm-global";
121
+ return "unknown";
122
+ }
123
+ // Running from a source checkout → git install
124
+ // Walk up from packages/cli/dist/lib/ (or src/lib/) to repo root
125
+ const repoRoot = getSourceRepoRoot(resolvedPath);
126
+ if (isAgentOrchestratorRepoRoot(repoRoot)) {
127
+ return "git";
128
+ }
129
+ return "unknown";
130
+ }
131
+ /** Detect how the running `ao` binary was installed. Honors `installMethod` override. */
132
+ export function detectInstallMethod() {
133
+ const override = resolveInstallMethodOverride();
134
+ if (override)
135
+ return override;
136
+ return classifyInstallPath(fileURLToPath(import.meta.url));
137
+ }
138
+ // ---------------------------------------------------------------------------
139
+ // Version
140
+ // ---------------------------------------------------------------------------
141
+ /**
142
+ * Resolve the currently-installed `@made-by-moonlight/athene` version.
143
+ *
144
+ * Delegates to core's `getInstalledAoVersion` (single source of truth shared
145
+ * with the dashboard) and falls back to the CLI's own embedded version when
146
+ * neither package is in `node_modules` (test/dev edge case).
147
+ */
148
+ export function getCurrentVersion() {
149
+ const fromCore = getInstalledAoVersion();
150
+ if (fromCore !== "0.0.0")
151
+ return fromCore;
152
+ return getCliVersion();
153
+ }
154
+ export function getGitUpdateTarget() {
155
+ const remote = process.env["AO_UPDATE_GIT_REMOTE"] || DEFAULT_GIT_REMOTE;
156
+ const branch = process.env["AO_UPDATE_GIT_BRANCH"] || DEFAULT_GIT_BRANCH;
157
+ return { remote, branch, ref: `${remote}/${branch}` };
158
+ }
159
+ export function getGitUpdateRef() {
160
+ return getGitUpdateTarget().ref;
161
+ }
162
+ // ---------------------------------------------------------------------------
163
+ // Update command mapping
164
+ // ---------------------------------------------------------------------------
165
+ /**
166
+ * Map an install method + channel to the command the user should run.
167
+ *
168
+ * Git installs always run `athene update` (which delegates to `athene-update.sh`)
169
+ * regardless of channel — the channel only affects npm-published builds.
170
+ *
171
+ * Homebrew is special: we never auto-install. We surface the brew command as
172
+ * a notice so the user runs it themselves — auto-running `npm install -g`
173
+ * inside a brew prefix overwrites brew's symlinks.
174
+ */
175
+ export function getUpdateCommand(method, channel = "stable") {
176
+ // "manual" channel maps to "stable" for the install command — the channel
177
+ // affects when we check, not which tag manual installers should pick.
178
+ const tag = channel === "nightly" ? "nightly" : "latest";
179
+ switch (method) {
180
+ case "git":
181
+ return "athene update";
182
+ case "npm-global":
183
+ return `npm install -g @made-by-moonlight/athene@${tag}`;
184
+ case "pnpm-global":
185
+ return `pnpm add -g @made-by-moonlight/athene@${tag}`;
186
+ case "bun-global":
187
+ return `bun add -g @made-by-moonlight/athene@${tag}`;
188
+ case "homebrew":
189
+ return "brew upgrade ao";
190
+ case "unknown":
191
+ return `npm install -g @made-by-moonlight/athene@${tag}`;
192
+ }
193
+ }
194
+ /** True when the install method requires a manual user action (no auto-install). */
195
+ export function isManualOnlyInstall(method) {
196
+ return method === "homebrew";
197
+ }
198
+ export function isOutdatedForChannel(currentVersion, latestVersion, channel) {
199
+ return coreIsVersionOutdatedForChannel(currentVersion, latestVersion, channel);
200
+ }
201
+ // ---------------------------------------------------------------------------
202
+ // Cache
203
+ // ---------------------------------------------------------------------------
204
+ /** Directory holding the update cache. Re-exported for athene doctor / CLI smoke tests. */
205
+ export function getCacheDir() {
206
+ // dirname(getUpdateCheckCachePath()) keeps this in lock-step with core's
207
+ // canonical path resolver.
208
+ return dirname(getUpdateCheckCachePath());
209
+ }
210
+ function getCachePath() {
211
+ return getUpdateCheckCachePath();
212
+ }
213
+ /**
214
+ * Read cached update info. Returns null if missing, expired, corrupt,
215
+ * version-mismatched, install-method-mismatched, or channel-mismatched.
216
+ *
217
+ * The cache is keyed by both `installMethod` and `channel` because the
218
+ * `latestVersion` stored at each tuple is meaningfully different (stable
219
+ * 0.5.0 vs nightly 0.5.0-nightly-abc; git's `origin/main` ref vs npm tag).
220
+ */
221
+ export function readCachedUpdateInfo(installMethod = detectInstallMethod(), channel) {
222
+ try {
223
+ const raw = readFileSync(getCachePath(), "utf-8");
224
+ const data = JSON.parse(raw);
225
+ if (!data.latestVersion || !data.checkedAt)
226
+ return null;
227
+ // Legacy cache entries predate install-method scoping — treat as unsafe.
228
+ if (!data.installMethod)
229
+ return null;
230
+ if (data.installMethod !== installMethod)
231
+ return null;
232
+ // Channel scoping. When the caller passes an explicit channel, the cache
233
+ // entry MUST advertise its own channel and that channel MUST match. A
234
+ // legacy entry without a `channel` field (written before channel scoping
235
+ // landed) is treated as a miss — otherwise a stable→nightly switch would
236
+ // keep returning the pre-switch latestVersion until the TTL expired.
237
+ if (channel) {
238
+ if (!data.channel)
239
+ return null;
240
+ if (data.channel !== channel)
241
+ return null;
242
+ }
243
+ // Cache is stale if user upgraded since the check
244
+ const currentVersion = getCurrentVersion();
245
+ if (data.currentVersionAtCheck && data.currentVersionAtCheck !== currentVersion) {
246
+ return null;
247
+ }
248
+ if (installMethod === "git" && data.currentRevisionAtCheck) {
249
+ try {
250
+ if (runGit(["rev-parse", "HEAD"], getCurrentRepoRoot()) !== data.currentRevisionAtCheck) {
251
+ return null;
252
+ }
253
+ }
254
+ catch {
255
+ return null;
256
+ }
257
+ }
258
+ // Cache expired
259
+ const age = Date.now() - new Date(data.checkedAt).getTime();
260
+ if (age > CACHE_TTL_MS)
261
+ return null;
262
+ return data;
263
+ }
264
+ catch {
265
+ return null;
266
+ }
267
+ }
268
+ export function writeCache(data) {
269
+ try {
270
+ const dir = getCacheDir();
271
+ mkdirSync(dir, { recursive: true });
272
+ writeFileSync(getCachePath(), JSON.stringify(data, null, 2));
273
+ }
274
+ catch {
275
+ // Best-effort — don't crash if cache dir is unwritable
276
+ }
277
+ }
278
+ export function invalidateCache() {
279
+ try {
280
+ unlinkSync(getCachePath());
281
+ }
282
+ catch {
283
+ // File might not exist — that's fine
284
+ }
285
+ }
286
+ function runGit(args, cwd) {
287
+ return execFileSync("git", args, {
288
+ cwd,
289
+ encoding: "utf-8",
290
+ stdio: ["ignore", "pipe", "ignore"],
291
+ }).trim();
292
+ }
293
+ export async function fetchGitLatestState(repoRoot = getCurrentRepoRoot()) {
294
+ try {
295
+ const { remote, branch, ref } = getGitUpdateTarget();
296
+ await execFileAsync("git", ["fetch", remote, branch], { cwd: repoRoot });
297
+ const headRevision = runGit(["rev-parse", "HEAD"], repoRoot);
298
+ const latestRevision = runGit(["rev-parse", ref], repoRoot);
299
+ let isBehind = false;
300
+ try {
301
+ runGit(["merge-base", "--is-ancestor", "HEAD", ref], repoRoot);
302
+ isBehind = headRevision !== latestRevision;
303
+ }
304
+ catch {
305
+ isBehind = false;
306
+ }
307
+ return { ref, headRevision, latestRevision, isBehind };
308
+ }
309
+ catch {
310
+ return null;
311
+ }
312
+ }
313
+ // ---------------------------------------------------------------------------
314
+ // Registry fetch
315
+ // ---------------------------------------------------------------------------
316
+ /**
317
+ * Fetch the latest version of @made-by-moonlight/athene for the given dist-tag.
318
+ *
319
+ * Hits the full package document (not the per-tag URL) so we get all dist-tags
320
+ * in one round trip. Channels:
321
+ * stable / manual → dist-tags.latest
322
+ * nightly → dist-tags.nightly (falls back to latest if no nightly tag)
323
+ */
324
+ export async function fetchLatestVersion(channel = "stable") {
325
+ try {
326
+ const response = await fetch(REGISTRY_PACKAGE_URL, {
327
+ signal: AbortSignal.timeout(FETCH_TIMEOUT_MS),
328
+ headers: { Accept: "application/json" },
329
+ });
330
+ if (!response.ok)
331
+ return null;
332
+ const data = (await response.json());
333
+ const tags = data["dist-tags"];
334
+ if (!tags || typeof tags !== "object")
335
+ return null;
336
+ const tag = channel === "nightly" ? "nightly" : "latest";
337
+ const value = tags[tag];
338
+ if (typeof value === "string")
339
+ return value;
340
+ // Nightly tag missing? Fall back to latest so the dashboard isn't broken
341
+ // before the first nightly publishes.
342
+ if (tag === "nightly" && typeof tags["latest"] === "string") {
343
+ return tags["latest"];
344
+ }
345
+ return null;
346
+ }
347
+ catch {
348
+ return null;
349
+ }
350
+ }
351
+ // ---------------------------------------------------------------------------
352
+ // Orchestrator
353
+ // ---------------------------------------------------------------------------
354
+ /**
355
+ * Check for updates, using cache when fresh and fetching when stale.
356
+ *
357
+ * Source of truth depends on install method:
358
+ * - git installs → `git fetch <remote> <branch>` + `merge-base`
359
+ * - npm/pnpm/bun/... → npm registry, dist-tags[channel]
360
+ *
361
+ * When the channel is "manual" the function still runs (so `--check` works
362
+ * and the dashboard can show current state) but the startup notice and the
363
+ * background refresh respect the channel and stay quiet.
364
+ */
365
+ export async function checkForUpdate(opts) {
366
+ const channel = opts?.channel ?? resolveUpdateChannel();
367
+ const currentVersion = getCurrentVersion();
368
+ const installMethod = opts?.installMethod ?? detectInstallMethod();
369
+ const recommendedCommand = getUpdateCommand(installMethod, channel);
370
+ if (!opts?.force) {
371
+ const cached = readCachedUpdateInfo(installMethod, channel);
372
+ if (cached) {
373
+ return {
374
+ currentVersion,
375
+ latestVersion: cached.latestVersion,
376
+ isOutdated: cached.installMethod === "git"
377
+ ? cached.isOutdated === true
378
+ : isOutdatedForChannel(currentVersion, cached.latestVersion, channel),
379
+ installMethod,
380
+ recommendedCommand,
381
+ checkedAt: cached.checkedAt,
382
+ channel,
383
+ };
384
+ }
385
+ }
386
+ const now = new Date().toISOString();
387
+ if (installMethod === "git") {
388
+ const gitState = await fetchGitLatestState(opts?.repoRoot);
389
+ if (gitState) {
390
+ writeCache({
391
+ latestVersion: gitState.ref,
392
+ checkedAt: now,
393
+ currentVersionAtCheck: currentVersion,
394
+ installMethod,
395
+ channel,
396
+ isOutdated: gitState.isBehind,
397
+ currentRevisionAtCheck: gitState.headRevision,
398
+ latestRevisionAtCheck: gitState.latestRevision,
399
+ });
400
+ }
401
+ return {
402
+ currentVersion,
403
+ latestVersion: gitState?.ref ?? null,
404
+ isOutdated: gitState?.isBehind ?? false,
405
+ installMethod,
406
+ recommendedCommand,
407
+ checkedAt: gitState ? now : null,
408
+ channel,
409
+ };
410
+ }
411
+ // npm/pnpm/bun/unknown installs use the npm registry as their update channel.
412
+ const latestVersion = await fetchLatestVersion(channel);
413
+ if (latestVersion) {
414
+ writeCache({
415
+ latestVersion,
416
+ checkedAt: now,
417
+ currentVersionAtCheck: currentVersion,
418
+ installMethod,
419
+ channel,
420
+ isOutdated: isOutdatedForChannel(currentVersion, latestVersion, channel),
421
+ });
422
+ }
423
+ return {
424
+ currentVersion,
425
+ latestVersion,
426
+ isOutdated: latestVersion
427
+ ? isOutdatedForChannel(currentVersion, latestVersion, channel)
428
+ : false,
429
+ installMethod,
430
+ recommendedCommand,
431
+ checkedAt: latestVersion ? now : null,
432
+ channel,
433
+ };
434
+ }
435
+ // ---------------------------------------------------------------------------
436
+ // Startup notifier (synchronous, cache-only)
437
+ // ---------------------------------------------------------------------------
438
+ /**
439
+ * Print an update notice to stderr if a newer version is cached.
440
+ *
441
+ * Skipped entirely when channel is "manual" — the user opted out of nudges.
442
+ * Stable users see "Run: athene update". Nightly users get the same nudge but
443
+ * the suggested install command picks `@nightly` instead of `@latest`.
444
+ */
445
+ export function maybeShowUpdateNotice() {
446
+ if (!process.stderr.isTTY)
447
+ return;
448
+ if (process.env["AO_NO_UPDATE_NOTIFIER"] === "1")
449
+ return;
450
+ if (process.env["CI"] || process.env["AGENT_ORCHESTRATOR_CI"])
451
+ return;
452
+ const skipArgs = ["update", "doctor", "--version", "-V", "--help", "-h"];
453
+ if (process.argv.some((arg) => skipArgs.includes(arg)))
454
+ return;
455
+ const channel = resolveUpdateChannel();
456
+ if (channel === "manual")
457
+ return;
458
+ const installMethod = detectInstallMethod();
459
+ const cached = readCachedUpdateInfo(installMethod, channel);
460
+ if (!cached)
461
+ return;
462
+ const currentVersion = getCurrentVersion();
463
+ const isOutdated = installMethod === "git"
464
+ ? cached.isOutdated === true
465
+ : isOutdatedForChannel(currentVersion, cached.latestVersion, channel);
466
+ if (!isOutdated)
467
+ return;
468
+ const channelSuffix = channel === "nightly" ? " (nightly)" : "";
469
+ const command = getUpdateCommand(installMethod, channel);
470
+ let message;
471
+ if (installMethod === "git") {
472
+ message = `\nUpdate available${channelSuffix} from ${cached.latestVersion} — Run: ${command}\n\n`;
473
+ }
474
+ else if (currentVersion === "0.0.0") {
475
+ message = `\nUpdate available${channelSuffix}: update to latest version — Run: ${command}\n\n`;
476
+ }
477
+ else {
478
+ message = `\nUpdate available${channelSuffix}: ${currentVersion} → ${cached.latestVersion} — Run: ${command}\n\n`;
479
+ }
480
+ process.stderr.write(message);
481
+ }
482
+ /**
483
+ * Kick off a background cache refresh. Skips entirely on `manual` channel
484
+ * so users who opted out don't generate any registry traffic.
485
+ */
486
+ export function scheduleBackgroundRefresh() {
487
+ if (resolveUpdateChannel() === "manual")
488
+ return;
489
+ const timer = setTimeout(() => {
490
+ checkForUpdate().catch(() => { });
491
+ }, 0);
492
+ timer.unref();
493
+ }
494
+ // ---------------------------------------------------------------------------
495
+ // Helpers
496
+ // ---------------------------------------------------------------------------
497
+ /**
498
+ * Re-export the core implementation so CLI consumers (and the existing test
499
+ * suite) keep importing from this module while the dashboard imports the same
500
+ * function from `@made-by-moonlight/athene-core` — single source of truth for the prerelease
501
+ * comparison rules.
502
+ */
503
+ export const isVersionOutdated = coreIsVersionOutdated;
504
+ //# sourceMappingURL=update-check.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update-check.js","sourceRoot":"","sources":["../../src/lib/update-check.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Web directory locator — finds the @made-by-moonlight/athene-web package.
3
+ * Shared utility to avoid duplication between dashboard.ts and start.ts.
4
+ */
5
+ /**
6
+ * Check if a TCP port is available by attempting to connect to it.
7
+ * A successful connect means something is already listening (port in use).
8
+ * ECONNREFUSED means nothing is listening (port free).
9
+ *
10
+ * Connect-based detection is more reliable than bind-based because it works
11
+ * regardless of whether the occupying process is bound to 127.0.0.1, ::1,
12
+ * 0.0.0.0, or :: (IPv6 wildcard).
13
+ */
14
+ export declare function isPortAvailable(port: number): Promise<boolean>;
15
+ /** How many consecutive ports to scan before giving up. */
16
+ export declare const MAX_PORT_SCAN = 100;
17
+ /**
18
+ * Find the first available port starting from `start`, scanning upward.
19
+ * Returns `null` if no free port is found within `maxScan` attempts.
20
+ */
21
+ export declare function findFreePort(start: number, maxScan?: number): Promise<number | null>;
22
+ /**
23
+ * Open a URL in the user's browser without throwing back into the caller.
24
+ */
25
+ export declare function openUrl(url: string): void;
26
+ /**
27
+ * Poll until a port is accepting connections, then open a URL in the browser.
28
+ * Respects an AbortSignal so the caller can cancel if the dashboard process
29
+ * exits early. Gives up silently after timeoutMs (default 30s).
30
+ */
31
+ export declare function waitForPortAndOpen(port: number, url: string, signal: AbortSignal, timeoutMs?: number): Promise<void>;
32
+ /**
33
+ * Build environment variables for spawning the dashboard process.
34
+ * Shared between `athene start` and `athene dashboard` to avoid duplication.
35
+ *
36
+ * Terminal server ports default to 14800/14801 but can be overridden via config.
37
+ * When no explicit port is set, auto-detects available ports to allow multiple
38
+ * dashboard instances to run simultaneously without EADDRINUSE conflicts.
39
+ */
40
+ export declare function buildDashboardEnv(port: number, configPath: string | null, terminalPort?: number, directTerminalPort?: number): Promise<Record<string, string>>;
41
+ /**
42
+ * Locate the @made-by-moonlight/athene-web package directory.
43
+ * Uses createRequire for ESM-compatible require.resolve, with fallback
44
+ * to sibling package paths that work from both src/ and dist/.
45
+ */
46
+ export declare function findWebDir(): string;
47
+ //# sourceMappingURL=web-dir.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"web-dir.d.ts","sourceRoot":"","sources":["../../src/lib/web-dir.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAiBH;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAS9D;AAED,2DAA2D;AAC3D,eAAO,MAAM,aAAa,MAAM,CAAC;AAEjC;;;GAGG;AACH,wBAAsB,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,SAAgB,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAKjG;AAED;;GAEG;AACH,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAqBzC;AAED;;;;GAIG;AACH,wBAAsB,kBAAkB,CACtC,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,WAAW,EACnB,SAAS,SAAS,GACjB,OAAO,CAAC,IAAI,CAAC,CAUf;AAqBD;;;;;;;GAOG;AACH,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,MAAM,GAAG,IAAI,EACzB,YAAY,CAAC,EAAE,MAAM,EACrB,kBAAkB,CAAC,EAAE,MAAM,GAC1B,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAyCjC;AAED;;;;GAIG;AACH,wBAAgB,UAAU,IAAI,MAAM,CAwBnC"}