@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,684 @@
1
+ import { existsSync, readFileSync, writeFileSync } from "node:fs";
2
+ import { homedir } from "node:os";
3
+ import { join } from "node:path";
4
+ import chalk from "chalk";
5
+ import { parseDocument } from "yaml";
6
+ import { CONFIG_SCHEMA_URL, findConfigFile, isCanonicalGlobalConfigPath } from "@made-by-moonlight/athene-core";
7
+ import { applyNotifierRoutingPreset, ensureNotifierDefault, getNotifierRoutingState, promptNotifierRoutingPreset, resolveRoutingPresetOption, routingLabel, } from "./notifier-routing.js";
8
+ import { DEFAULT_OPENCLAW_URL, HOOKS_PATH, detectOpenClawInstallation, probeGateway, validateToken, } from "./openclaw-probe.js";
9
+ const DEFAULT_OPENCLAW_CONFIG_PATH = join(homedir(), ".openclaw", "openclaw.json");
10
+ const DISPLAY_OPENCLAW_CONFIG_PATH = "~/.openclaw/openclaw.json";
11
+ export class OpenClawSetupError extends Error {
12
+ exitCode;
13
+ constructor(message, exitCode = 1) {
14
+ super(message);
15
+ this.exitCode = exitCode;
16
+ this.name = "OpenClawSetupError";
17
+ }
18
+ }
19
+ function isRecord(value) {
20
+ return value !== null && typeof value === "object" && !Array.isArray(value);
21
+ }
22
+ function stringValue(value) {
23
+ return typeof value === "string" && value.trim().length > 0 ? value.trim() : undefined;
24
+ }
25
+ function normalizeOpenClawHooksUrl(url) {
26
+ const normalized = url.trim().replace(/\/+$/, "");
27
+ return normalized.endsWith(HOOKS_PATH) ? normalized : `${normalized}${HOOKS_PATH}`;
28
+ }
29
+ function expandHomePath(path) {
30
+ if (path === "~")
31
+ return homedir();
32
+ if (path.startsWith("~/"))
33
+ return join(homedir(), path.slice(2));
34
+ return path;
35
+ }
36
+ function displayOpenClawConfigPath(path) {
37
+ const expanded = expandHomePath(path);
38
+ return expanded === DEFAULT_OPENCLAW_CONFIG_PATH ? DISPLAY_OPENCLAW_CONFIG_PATH : path;
39
+ }
40
+ function validateOpenClawUrl(url) {
41
+ let parsed;
42
+ try {
43
+ parsed = new URL(url);
44
+ }
45
+ catch {
46
+ throw new OpenClawSetupError("OpenClaw webhook URL is invalid.");
47
+ }
48
+ if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
49
+ throw new OpenClawSetupError("OpenClaw webhook URL must start with http:// or https://.");
50
+ }
51
+ }
52
+ function readConfigContext() {
53
+ const configPath = findConfigFile() ?? undefined;
54
+ if (!configPath) {
55
+ throw new OpenClawSetupError("No agent-orchestrator.yaml found. Run 'athene start' first to create one.");
56
+ }
57
+ const rawYaml = readFileSync(configPath, "utf-8");
58
+ const doc = parseDocument(rawYaml);
59
+ const rawConfig = doc.toJS() ?? {};
60
+ return { configPath, rawConfig };
61
+ }
62
+ function getExistingOpenClaw(rawConfig) {
63
+ const notifiers = isRecord(rawConfig["notifiers"]) ? rawConfig["notifiers"] : {};
64
+ const existing = notifiers["openclaw"];
65
+ return isRecord(existing) ? existing : {};
66
+ }
67
+ function getOpenClawJsonPath() {
68
+ return DEFAULT_OPENCLAW_CONFIG_PATH;
69
+ }
70
+ function readOpenClawJson(configPath = DEFAULT_OPENCLAW_CONFIG_PATH) {
71
+ const path = expandHomePath(configPath);
72
+ try {
73
+ if (!existsSync(path))
74
+ return { path, exists: false, config: {} };
75
+ const config = JSON.parse(readFileSync(path, "utf-8"));
76
+ const hooks = isRecord(config["hooks"]) ? config["hooks"] : {};
77
+ return {
78
+ path,
79
+ exists: true,
80
+ config,
81
+ token: stringValue(hooks["token"]),
82
+ };
83
+ }
84
+ catch {
85
+ return { path, exists: existsSync(path), config: {} };
86
+ }
87
+ }
88
+ function getConfiguredOpenClawConfigPath(opts, existingOpenClaw) {
89
+ return (stringValue(opts.openclawConfigPath) ??
90
+ stringValue(existingOpenClaw["openclawConfigPath"]) ??
91
+ stringValue(existingOpenClaw["configPath"]) ??
92
+ getOpenClawJsonPath());
93
+ }
94
+ function resolveConfiguredToken(existingOpenClaw, openclawConfigPath) {
95
+ const openclawJson = readOpenClawJson(openclawConfigPath);
96
+ if (openclawJson.token) {
97
+ return {
98
+ value: openclawJson.token,
99
+ source: "openclaw-config",
100
+ configPath: openclawJson.path,
101
+ };
102
+ }
103
+ const rawYamlToken = stringValue(existingOpenClaw["token"]);
104
+ if (rawYamlToken) {
105
+ const envVarMatch = rawYamlToken.match(/^\$\{([^}]+)\}$/);
106
+ if (envVarMatch) {
107
+ const envValue = process.env[envVarMatch[1]];
108
+ if (envValue)
109
+ return { value: envValue, source: "env", configPath: openclawJson.path };
110
+ }
111
+ else {
112
+ return { value: rawYamlToken, source: "yaml", configPath: openclawJson.path };
113
+ }
114
+ }
115
+ const envToken = process.env["OPENCLAW_HOOKS_TOKEN"];
116
+ if (envToken)
117
+ return { value: envToken, source: "env", configPath: openclawJson.path };
118
+ return undefined;
119
+ }
120
+ async function shouldReplaceConflictingOpenClaw(existingPlugin, force, nonInteractive) {
121
+ if (existingPlugin === undefined || existingPlugin === "openclaw" || force)
122
+ return true;
123
+ if (nonInteractive) {
124
+ throw new OpenClawSetupError(`notifiers.openclaw already uses plugin "${String(existingPlugin)}". Re-run with --force to replace it.`);
125
+ }
126
+ const clack = await import("@clack/prompts");
127
+ const replace = await clack.confirm({
128
+ message: `notifiers.openclaw already uses plugin "${String(existingPlugin)}". Replace it?`,
129
+ initialValue: false,
130
+ });
131
+ if (clack.isCancel(replace) || !replace) {
132
+ console.log(chalk.dim("Keeping existing OpenClaw notifier config."));
133
+ return false;
134
+ }
135
+ return true;
136
+ }
137
+ function cancelSetup(clack) {
138
+ clack.cancel("Setup cancelled.");
139
+ throw new OpenClawSetupError("Setup cancelled.", 0);
140
+ }
141
+ function printOpenClawStartInstructions() {
142
+ console.log("");
143
+ console.log(chalk.bold("Start or install OpenClaw"));
144
+ console.log(" 1. Start your local OpenClaw gateway.");
145
+ console.log(" 2. Confirm the gateway URL. The default is http://127.0.0.1:18789.");
146
+ console.log(" 3. Paste the hooks URL here. AO will normalize it to /hooks/agent.");
147
+ console.log(chalk.dim("If OpenClaw runs elsewhere, use that machine's gateway URL."));
148
+ console.log("");
149
+ }
150
+ function printOpenClawTokenInstructions(openclawConfigPath) {
151
+ const displayPath = displayOpenClawConfigPath(openclawConfigPath);
152
+ console.log("");
153
+ console.log(chalk.bold("Configure the OpenClaw hooks token"));
154
+ console.log(` 1. Open your OpenClaw config: ${displayPath}`);
155
+ console.log(" 2. In OpenClaw's webhook/hooks settings, create or copy the hooks token.");
156
+ console.log(" 3. Put that token in hooks.token and make sure hooks are enabled:");
157
+ console.log("");
158
+ console.log(chalk.cyan(`{
159
+ "hooks": {
160
+ "enabled": true,
161
+ "token": "<openclaw-hooks-token>",
162
+ "allowRequestSessionKey": true,
163
+ "allowedSessionKeyPrefixes": ["hook:"]
164
+ }
165
+ }`));
166
+ console.log("");
167
+ console.log(chalk.dim("OpenClaw requires this shared secret for POST /hooks/agent. AO reads it from the OpenClaw config and does not generate or store it in your shell profile."));
168
+ console.log(chalk.dim("Restart OpenClaw after changing the config."));
169
+ console.log("");
170
+ }
171
+ async function promptOpenClawUrl(clack, initialValue) {
172
+ const urlInput = await clack.text({
173
+ message: "OpenClaw webhook URL:",
174
+ placeholder: `${DEFAULT_OPENCLAW_URL}${HOOKS_PATH}`,
175
+ initialValue,
176
+ validate: (value) => {
177
+ if (!value)
178
+ return "OpenClaw webhook URL is required";
179
+ try {
180
+ validateOpenClawUrl(normalizeOpenClawHooksUrl(String(value)));
181
+ }
182
+ catch (error) {
183
+ return error instanceof Error ? error.message : String(error);
184
+ }
185
+ },
186
+ });
187
+ if (clack.isCancel(urlInput)) {
188
+ cancelSetup(clack);
189
+ }
190
+ return normalizeOpenClawHooksUrl(String(urlInput));
191
+ }
192
+ async function promptAfterOpenClawInstructions(clack, initialValue) {
193
+ printOpenClawStartInstructions();
194
+ while (true) {
195
+ const next = await clack.select({
196
+ message: "What do you want to do next?",
197
+ options: [
198
+ {
199
+ value: "enter-url",
200
+ label: "Enter OpenClaw URL",
201
+ hint: "Paste the local or remote gateway URL",
202
+ },
203
+ {
204
+ value: "back",
205
+ label: "Back",
206
+ hint: "Return to the previous menu",
207
+ },
208
+ {
209
+ value: "cancel",
210
+ label: "Cancel setup",
211
+ hint: "Do not change config",
212
+ },
213
+ ],
214
+ });
215
+ if (clack.isCancel(next) || next === "cancel") {
216
+ cancelSetup(clack);
217
+ }
218
+ if (next === "back")
219
+ return "back";
220
+ if (next === "enter-url")
221
+ return promptOpenClawUrl(clack, initialValue);
222
+ }
223
+ }
224
+ async function resolveInteractiveUrl(clack, opts, existingUrl) {
225
+ const providedUrl = stringValue(opts.url);
226
+ if (providedUrl) {
227
+ const normalized = normalizeOpenClawHooksUrl(providedUrl);
228
+ validateOpenClawUrl(normalized);
229
+ return normalized;
230
+ }
231
+ const defaultHooksUrl = `${DEFAULT_OPENCLAW_URL}${HOOKS_PATH}`;
232
+ let detectedUrl;
233
+ const spin = clack.spinner();
234
+ spin.start("Detecting OpenClaw gateway on localhost...");
235
+ const probe = await probeGateway(DEFAULT_OPENCLAW_URL);
236
+ if (probe.reachable) {
237
+ detectedUrl = defaultHooksUrl;
238
+ spin.stop(`Found OpenClaw gateway at ${DEFAULT_OPENCLAW_URL}`);
239
+ }
240
+ else {
241
+ spin.stop("No OpenClaw gateway detected on localhost");
242
+ }
243
+ while (true) {
244
+ const source = existingUrl
245
+ ? await clack.select({
246
+ message: "OpenClaw notifier is already configured. What do you want to do?",
247
+ options: [
248
+ {
249
+ value: "use-existing",
250
+ label: "Use existing gateway URL",
251
+ hint: existingUrl,
252
+ },
253
+ {
254
+ value: "change-url",
255
+ label: "Change gateway URL",
256
+ hint: "Paste a different OpenClaw gateway URL",
257
+ },
258
+ {
259
+ value: "use-local",
260
+ label: "Use local default URL",
261
+ hint: defaultHooksUrl,
262
+ },
263
+ {
264
+ value: "need-openclaw",
265
+ label: "Show OpenClaw setup steps",
266
+ hint: "AO will print the local gateway requirements",
267
+ },
268
+ {
269
+ value: "cancel",
270
+ label: "Cancel setup",
271
+ hint: "Do not change config",
272
+ },
273
+ ],
274
+ })
275
+ : await clack.select({
276
+ message: "How do you want to point AO at OpenClaw?",
277
+ options: [
278
+ {
279
+ value: "use-local",
280
+ label: probe.reachable ? "Use detected local gateway" : "Use local default URL",
281
+ hint: detectedUrl ?? defaultHooksUrl,
282
+ },
283
+ {
284
+ value: "change-url",
285
+ label: "Enter a different URL",
286
+ hint: "Use this when OpenClaw runs elsewhere",
287
+ },
288
+ {
289
+ value: "need-openclaw",
290
+ label: "Show OpenClaw setup steps",
291
+ hint: "AO will print the local gateway requirements",
292
+ },
293
+ {
294
+ value: "cancel",
295
+ label: "Cancel setup",
296
+ hint: "Do not change config",
297
+ },
298
+ ],
299
+ });
300
+ if (clack.isCancel(source) || source === "cancel") {
301
+ cancelSetup(clack);
302
+ }
303
+ if (source === "use-existing" && existingUrl)
304
+ return normalizeOpenClawHooksUrl(existingUrl);
305
+ if (source === "use-local")
306
+ return detectedUrl ?? defaultHooksUrl;
307
+ if (source === "change-url")
308
+ return promptOpenClawUrl(clack, existingUrl ?? detectedUrl);
309
+ if (source === "need-openclaw") {
310
+ const result = await promptAfterOpenClawInstructions(clack, existingUrl ?? detectedUrl);
311
+ if (result === "back")
312
+ continue;
313
+ return result;
314
+ }
315
+ }
316
+ }
317
+ async function resolveInteractiveToken(clack, opts, existingOpenClaw, initialOpenClawConfigPath) {
318
+ const providedToken = stringValue(opts.token);
319
+ if (providedToken) {
320
+ return { value: providedToken, source: "cli", configPath: expandHomePath(initialOpenClawConfigPath) };
321
+ }
322
+ let openclawConfigPath = initialOpenClawConfigPath;
323
+ while (true) {
324
+ const existingToken = resolveConfiguredToken(existingOpenClaw, openclawConfigPath);
325
+ const options = [
326
+ ...(existingToken
327
+ ? [
328
+ {
329
+ value: "use-existing",
330
+ label: `Use existing token from ${existingToken.source}`,
331
+ hint: existingToken.source === "openclaw-config"
332
+ ? displayOpenClawConfigPath(existingToken.configPath)
333
+ : "Legacy fallback; AO will not write shell exports",
334
+ },
335
+ ]
336
+ : []),
337
+ {
338
+ value: "check-config",
339
+ label: existingToken ? "Check OpenClaw config again" : "I added hooks.token to OpenClaw config",
340
+ hint: displayOpenClawConfigPath(openclawConfigPath),
341
+ },
342
+ {
343
+ value: "show-steps",
344
+ label: "Show where to configure the token",
345
+ hint: "Print OpenClaw-side config steps",
346
+ },
347
+ {
348
+ value: "manual",
349
+ label: "Enter token manually",
350
+ hint: "For remote OpenClaw only; AO stores it in agent-orchestrator.yaml",
351
+ },
352
+ {
353
+ value: "config-path",
354
+ label: "Use a different OpenClaw config path",
355
+ hint: "Read hooks.token from another local OpenClaw config",
356
+ },
357
+ {
358
+ value: "back",
359
+ label: "Back",
360
+ hint: "Return to gateway URL",
361
+ },
362
+ {
363
+ value: "cancel",
364
+ label: "Cancel setup",
365
+ hint: "Do not change config",
366
+ },
367
+ ];
368
+ const choice = await clack.select({
369
+ message: "How should AO configure the OpenClaw hooks token?",
370
+ options,
371
+ });
372
+ if (clack.isCancel(choice) || choice === "cancel") {
373
+ cancelSetup(clack);
374
+ }
375
+ if (choice === "back")
376
+ return "back";
377
+ if (choice === "use-existing" && existingToken)
378
+ return existingToken;
379
+ if (choice === "check-config") {
380
+ const refreshedToken = resolveConfiguredToken(existingOpenClaw, openclawConfigPath);
381
+ if (refreshedToken)
382
+ return refreshedToken;
383
+ clack.log.warn(`No hooks.token found in ${displayOpenClawConfigPath(openclawConfigPath)} yet.`);
384
+ continue;
385
+ }
386
+ if (choice === "show-steps") {
387
+ printOpenClawTokenInstructions(openclawConfigPath);
388
+ continue;
389
+ }
390
+ if (choice === "config-path") {
391
+ const pathInput = await clack.text({
392
+ message: "OpenClaw config path:",
393
+ placeholder: DISPLAY_OPENCLAW_CONFIG_PATH,
394
+ initialValue: displayOpenClawConfigPath(openclawConfigPath),
395
+ validate: (value) => (!value ? "OpenClaw config path is required" : undefined),
396
+ });
397
+ if (clack.isCancel(pathInput)) {
398
+ cancelSetup(clack);
399
+ }
400
+ openclawConfigPath = String(pathInput);
401
+ continue;
402
+ }
403
+ if (choice === "manual") {
404
+ const input = await clack.password({
405
+ message: "OpenClaw hooks token:",
406
+ validate: (value) => (!value ? "Token is required" : undefined),
407
+ });
408
+ if (clack.isCancel(input)) {
409
+ cancelSetup(clack);
410
+ }
411
+ return { value: String(input), source: "manual", configPath: expandHomePath(openclawConfigPath) };
412
+ }
413
+ }
414
+ }
415
+ async function resolveInteractiveRoutingPreset(clack, opts, rawConfig) {
416
+ const optionPreset = resolveOpenClawRoutingPreset(opts.routingPreset);
417
+ if (optionPreset)
418
+ return optionPreset;
419
+ const selection = await promptNotifierRoutingPreset(clack, rawConfig, "openclaw", "OpenClaw", () => cancelSetup(clack));
420
+ if (selection === "preserve")
421
+ return undefined;
422
+ return selection;
423
+ }
424
+ function resolveOpenClawRoutingPreset(value) {
425
+ try {
426
+ return resolveRoutingPresetOption(value, "OpenClaw");
427
+ }
428
+ catch (error) {
429
+ throw new OpenClawSetupError(error instanceof Error ? error.message : String(error));
430
+ }
431
+ }
432
+ function printReview(resolved) {
433
+ console.log("");
434
+ console.log(chalk.bold("OpenClaw setup review"));
435
+ console.log(` Webhook URL: ${resolved.url}`);
436
+ console.log(` Token: configured from ${resolved.tokenSource}`);
437
+ console.log(` OpenClaw config: ${displayOpenClawConfigPath(resolved.openclawConfigPath)}`);
438
+ console.log(` Routing: ${resolved.routingPreset ? routingLabel(resolved.routingPreset) : "unchanged"}`);
439
+ console.log(` Setup probe: ${resolved.shouldSendTest ? "enabled" : "skipped"}`);
440
+ console.log("");
441
+ }
442
+ async function promptInteractiveReview(clack, resolved) {
443
+ printReview(resolved);
444
+ const choice = await clack.select({
445
+ message: "Save this OpenClaw setup?",
446
+ options: [
447
+ { value: "save", label: "Save setup" },
448
+ { value: "url", label: "Change gateway URL" },
449
+ { value: "token", label: "Change token" },
450
+ { value: "routing", label: "Change routing" },
451
+ { value: "cancel", label: "Cancel setup", hint: "Do not change config" },
452
+ ],
453
+ });
454
+ if (clack.isCancel(choice) || choice === "cancel") {
455
+ cancelSetup(clack);
456
+ }
457
+ return choice;
458
+ }
459
+ async function resolveInteractiveSetup(opts, existingOpenClaw, rawConfig) {
460
+ const clack = await import("@clack/prompts");
461
+ const existingUrl = stringValue(existingOpenClaw["url"]);
462
+ const initialOpenClawConfigPath = getConfiguredOpenClawConfigPath(opts, existingOpenClaw);
463
+ clack.intro(chalk.bgCyan(chalk.black(" athene setup openclaw ")));
464
+ let url;
465
+ let tokenInfo;
466
+ let routingPreset;
467
+ let step = "url";
468
+ while (true) {
469
+ if (step === "url") {
470
+ url = await resolveInteractiveUrl(clack, opts, existingUrl);
471
+ step = "token";
472
+ }
473
+ if (step === "token") {
474
+ const selectedTokenInfo = await resolveInteractiveToken(clack, opts, existingOpenClaw, tokenInfo?.configPath ?? initialOpenClawConfigPath);
475
+ if (selectedTokenInfo === "back") {
476
+ step = "url";
477
+ continue;
478
+ }
479
+ tokenInfo = selectedTokenInfo;
480
+ step = "routing";
481
+ }
482
+ if (step === "routing") {
483
+ const selectedRoutingPreset = await resolveInteractiveRoutingPreset(clack, opts, rawConfig);
484
+ if (selectedRoutingPreset === "back") {
485
+ step = "token";
486
+ continue;
487
+ }
488
+ routingPreset = selectedRoutingPreset;
489
+ step = "review";
490
+ }
491
+ if (step === "review") {
492
+ const resolved = {
493
+ url: url ?? `${DEFAULT_OPENCLAW_URL}${HOOKS_PATH}`,
494
+ token: tokenInfo?.value ?? "",
495
+ openclawConfigPath: tokenInfo?.configPath ?? expandHomePath(initialOpenClawConfigPath),
496
+ routingPreset,
497
+ shouldSendTest: opts.test !== false,
498
+ tokenSource: tokenInfo?.source ?? "manual",
499
+ };
500
+ const next = await promptInteractiveReview(clack, resolved);
501
+ if (next === "save")
502
+ return resolved;
503
+ step = next;
504
+ }
505
+ }
506
+ }
507
+ async function resolveNonInteractiveSetup(opts, existingOpenClaw, _rawConfig) {
508
+ let rawUrl = stringValue(opts.url) ??
509
+ process.env["OPENCLAW_GATEWAY_URL"] ??
510
+ (opts.refresh ? stringValue(existingOpenClaw["url"]) : undefined);
511
+ if (!rawUrl) {
512
+ const installation = await detectOpenClawInstallation();
513
+ if (installation.state === "running") {
514
+ rawUrl = `${installation.gatewayUrl}${HOOKS_PATH}`;
515
+ console.log(chalk.dim(`Auto-detected OpenClaw gateway at ${installation.gatewayUrl}`));
516
+ }
517
+ else {
518
+ throw new OpenClawSetupError("Error: OpenClaw gateway not reachable and no --url provided.\n" +
519
+ " Start OpenClaw first, or pass --url explicitly:\n" +
520
+ " Example: athene setup openclaw --url http://127.0.0.1:18789/hooks/agent --openclaw-config-path ~/.openclaw/openclaw.json --non-interactive");
521
+ }
522
+ }
523
+ const url = normalizeOpenClawHooksUrl(rawUrl);
524
+ validateOpenClawUrl(url);
525
+ const openclawConfigPath = getConfiguredOpenClawConfigPath(opts, existingOpenClaw);
526
+ const configuredToken = resolveConfiguredToken(existingOpenClaw, openclawConfigPath);
527
+ const tokenInfo = stringValue(opts.token) !== undefined
528
+ ? {
529
+ value: stringValue(opts.token),
530
+ source: "cli",
531
+ configPath: expandHomePath(openclawConfigPath),
532
+ }
533
+ : configuredToken;
534
+ if (!tokenInfo) {
535
+ throw new OpenClawSetupError(`No OpenClaw hooks token found in ${displayOpenClawConfigPath(openclawConfigPath)}.\n` +
536
+ " Generate or copy the hooks token from OpenClaw, put it in hooks.token, then rerun setup.\n" +
537
+ ` Config example: ${displayOpenClawConfigPath(openclawConfigPath)} -> hooks.token\n` +
538
+ " For remote OpenClaw only, pass --token explicitly.");
539
+ }
540
+ console.log(chalk.dim("Skipping setup probe in non-interactive mode. Run `athene setup openclaw --status` to verify."));
541
+ const routingPreset = resolveOpenClawRoutingPreset(opts.routingPreset) ?? (opts.refresh ? undefined : "urgent-action");
542
+ return {
543
+ url,
544
+ token: tokenInfo.value,
545
+ openclawConfigPath: tokenInfo.configPath,
546
+ routingPreset,
547
+ shouldSendTest: opts.test !== false,
548
+ tokenSource: tokenInfo.source,
549
+ };
550
+ }
551
+ function writeOpenClawConfig(configPath, resolved, nonInteractive) {
552
+ const rawYaml = readFileSync(configPath, "utf-8");
553
+ const doc = parseDocument(rawYaml);
554
+ const rawConfig = doc.toJS() ?? {};
555
+ const notifiers = isRecord(rawConfig["notifiers"]) ? rawConfig["notifiers"] : {};
556
+ const openclawConfig = {
557
+ plugin: "openclaw",
558
+ url: resolved.url,
559
+ openclawConfigPath: displayOpenClawConfigPath(resolved.openclawConfigPath),
560
+ retries: 3,
561
+ retryDelayMs: 1000,
562
+ wakeMode: "now",
563
+ };
564
+ if (resolved.tokenSource === "cli" || resolved.tokenSource === "manual" || resolved.tokenSource === "yaml") {
565
+ openclawConfig["token"] = resolved.token;
566
+ }
567
+ else if (resolved.tokenSource === "env") {
568
+ openclawConfig["token"] = "$" + "{OPENCLAW_HOOKS_TOKEN}";
569
+ }
570
+ notifiers["openclaw"] = openclawConfig;
571
+ rawConfig["notifiers"] = notifiers;
572
+ if (resolved.routingPreset) {
573
+ ensureNotifierDefault(rawConfig, "openclaw");
574
+ }
575
+ applyNotifierRoutingPreset(rawConfig, "openclaw", resolved.routingPreset);
576
+ if (!isCanonicalGlobalConfigPath(configPath)) {
577
+ const currentSchema = doc.get("$schema");
578
+ if (!(typeof currentSchema === "string" && currentSchema.trim().length > 0)) {
579
+ doc.set("$schema", CONFIG_SCHEMA_URL);
580
+ }
581
+ }
582
+ doc.setIn(["notifiers"], rawConfig["notifiers"]);
583
+ doc.setIn(["defaults"], rawConfig["defaults"]);
584
+ if (rawConfig["notificationRouting"] !== undefined) {
585
+ doc.setIn(["notificationRouting"], rawConfig["notificationRouting"]);
586
+ }
587
+ writeFileSync(configPath, doc.toString({ indent: 2 }));
588
+ if (nonInteractive) {
589
+ console.log(chalk.green(`✓ Config written to ${configPath}`));
590
+ }
591
+ }
592
+ function printOpenClawInstructions(nonInteractive, resolved) {
593
+ const tokenLocation = resolved.tokenSource === "openclaw-config"
594
+ ? displayOpenClawConfigPath(resolved.openclawConfigPath)
595
+ : resolved.tokenSource === "env"
596
+ ? "OPENCLAW_HOOKS_TOKEN"
597
+ : "agent-orchestrator.yaml";
598
+ if (nonInteractive) {
599
+ console.log(chalk.green("✓ AO config written (OpenClaw config left unchanged)"));
600
+ console.log(`Token source: ${tokenLocation}`);
601
+ return;
602
+ }
603
+ console.log(`\n${chalk.green.bold("Done — AO config written.")}`);
604
+ console.log(chalk.dim(" agent-orchestrator.yaml — notifiers.openclaw block"));
605
+ console.log(chalk.dim(` token source — ${tokenLocation}`));
606
+ if (resolved.tokenSource === "openclaw-config") {
607
+ console.log(chalk.dim(" AO did not write OpenClaw config or shell profile exports."));
608
+ }
609
+ }
610
+ async function runInteractiveSetupProbe(resolved) {
611
+ if (!resolved.shouldSendTest) {
612
+ console.log(chalk.dim("Skipped OpenClaw setup probe."));
613
+ return;
614
+ }
615
+ const result = await validateToken(resolved.url, resolved.token);
616
+ if (result.valid) {
617
+ console.log(chalk.green("✓ OpenClaw setup probe passed"));
618
+ return;
619
+ }
620
+ console.log(chalk.yellow(`OpenClaw setup probe did not pass yet: ${result.error ?? "unknown validation error"}`));
621
+ console.log(chalk.dim("Restart OpenClaw, then run `athene setup openclaw --status` to verify."));
622
+ }
623
+ async function printStatus() {
624
+ const context = readConfigContext();
625
+ const existingOpenClaw = getExistingOpenClaw(context.rawConfig);
626
+ const plugin = stringValue(existingOpenClaw["plugin"]);
627
+ const configuredUrl = stringValue(existingOpenClaw["url"]);
628
+ const url = configuredUrl ? normalizeOpenClawHooksUrl(configuredUrl) : DEFAULT_OPENCLAW_URL;
629
+ const openclawConfigPath = getConfiguredOpenClawConfigPath({}, existingOpenClaw);
630
+ const tokenInfo = resolveConfiguredToken(existingOpenClaw, openclawConfigPath);
631
+ const openclawJson = readOpenClawJson(openclawConfigPath);
632
+ const installation = await detectOpenClawInstallation(url);
633
+ console.log(chalk.bold("OpenClaw notifier status"));
634
+ console.log(` Config: ${context.configPath}`);
635
+ console.log(` Plugin: ${plugin ?? chalk.dim("not configured")}`);
636
+ console.log(` Webhook URL: ${configuredUrl ?? chalk.dim("not configured")}`);
637
+ console.log(` Token: ${tokenInfo ? `configured from ${tokenInfo.source}` : chalk.dim("not configured")}`);
638
+ console.log(` OpenClaw config: ${openclawJson.exists ? displayOpenClawConfigPath(openclawJson.path) : chalk.dim(`${displayOpenClawConfigPath(openclawJson.path)} not found`)}`);
639
+ console.log(` Routing: ${getNotifierRoutingState(context.rawConfig, "openclaw").label}`);
640
+ console.log(` Gateway: ${installation.state} at ${installation.gatewayUrl}`);
641
+ if (installation.binaryPath)
642
+ console.log(` Binary: ${installation.binaryPath}`);
643
+ if (plugin !== "openclaw" || !tokenInfo || installation.state !== "running")
644
+ return;
645
+ const validation = await validateToken(url, tokenInfo.value);
646
+ if (validation.valid) {
647
+ console.log(chalk.green(" Token probe: PASS"));
648
+ }
649
+ else {
650
+ console.log(chalk.red(` Token probe: FAIL ${validation.error ?? "unknown error"}`));
651
+ }
652
+ }
653
+ export async function runOpenClawSetupAction(opts) {
654
+ const nonInteractive = opts.nonInteractive || !process.stdin.isTTY;
655
+ const force = Boolean(opts.force);
656
+ if (opts.status) {
657
+ await printStatus();
658
+ return;
659
+ }
660
+ const context = readConfigContext();
661
+ const existingOpenClaw = getExistingOpenClaw(context.rawConfig);
662
+ const shouldWire = await shouldReplaceConflictingOpenClaw(existingOpenClaw["plugin"], force, nonInteractive);
663
+ if (!shouldWire)
664
+ return;
665
+ const resolved = nonInteractive
666
+ ? await resolveNonInteractiveSetup(opts, existingOpenClaw, context.rawConfig)
667
+ : await resolveInteractiveSetup(opts, existingOpenClaw, context.rawConfig);
668
+ writeOpenClawConfig(context.configPath, resolved, nonInteractive);
669
+ if (!nonInteractive) {
670
+ await runInteractiveSetupProbe(resolved);
671
+ }
672
+ printOpenClawInstructions(nonInteractive, resolved);
673
+ if (!nonInteractive) {
674
+ const clack = await import("@clack/prompts");
675
+ clack.outro(`${chalk.green("OpenClaw setup complete!")} AO will send notifications to OpenClaw.\n` +
676
+ chalk.dim(" Test it with: athene notify test --to openclaw --template basic\n") +
677
+ chalk.dim(" Restart AO with 'athene stop && athene start' to activate."));
678
+ }
679
+ else {
680
+ console.log(chalk.green("\n✓ OpenClaw setup complete."));
681
+ console.log(chalk.dim("Restart AO to activate: athene stop && athene start"));
682
+ }
683
+ }
684
+ //# sourceMappingURL=openclaw-setup.js.map