@brantrusnak/openclaw-omadeus 1.0.4 → 1.0.5

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.
@@ -27,10 +27,11 @@ const gatewayState = {
27
27
  };
28
28
  const isUnconfigured = (account) => account.credentialSource === "none";
29
29
  let lastPersistedToken = null;
30
- async function persistSessionToken(token) {
30
+ async function persistSessionToken(token, environment) {
31
31
  if (lastPersistedToken === token) return;
32
32
  const runtime = getOmadeusRuntime();
33
- if ((getOmadeusChannelConfig(runtime.config.current()) ?? {}).sessionToken === token) {
33
+ const section = getOmadeusChannelConfig(runtime.config.current()) ?? {};
34
+ if (section.sessionToken === token && section.sessionTokenEnvironment === environment) {
34
35
  lastPersistedToken = token;
35
36
  return;
36
37
  }
@@ -41,7 +42,8 @@ async function persistSessionToken(token) {
41
42
  ...draft.channels ?? {},
42
43
  omadeus: {
43
44
  ...getOmadeusChannelConfig(draft) ?? {},
44
- sessionToken: token
45
+ sessionToken: token,
46
+ sessionTokenEnvironment: environment
45
47
  }
46
48
  };
47
49
  }
@@ -82,12 +84,12 @@ const omadeusConfigAdapter = createTopLevelChannelConfigAdapter({
82
84
  defaultAccountId: resolveDefaultOmadeusAccountId,
83
85
  deleteMode: "clear-fields",
84
86
  clearBaseFields: [
85
- "casUrl",
86
- "maestroUrl",
87
+ "environment",
87
88
  "email",
88
89
  "password",
89
90
  "organizationId",
90
91
  "sessionToken",
92
+ "sessionTokenEnvironment",
91
93
  "inbound"
92
94
  ],
93
95
  resolveAllowFrom: () => [],
@@ -473,7 +475,7 @@ const omadeusPlugin = {
473
475
  initialToken: account.sessionToken,
474
476
  onRefresh: (token) => {
475
477
  log.info("[omadeus] token refreshed");
476
- persistSessionToken(token).catch((err) => log.warn(`[omadeus] failed to persist session token: ${String(err)}`));
478
+ persistSessionToken(token, account.environment).catch((err) => log.warn(`[omadeus] failed to persist session token: ${String(err)}`));
477
479
  },
478
480
  onError: (err) => {
479
481
  log.error(`[omadeus] token refresh failed: ${err.message}`);
@@ -1,5 +1,5 @@
1
1
  import { DEFAULT_ACCOUNT_ID } from "../runtime-api.js";
2
- import "./defaults.js";
2
+ import { getOmadeusEnvironmentUrls, resolveOmadeusEnvironment } from "./defaults.js";
3
3
  //#region src/config.ts
4
4
  function getOmadeusChannelConfig(cfg) {
5
5
  return cfg.channels?.["omadeus"];
@@ -14,11 +14,15 @@ function resolveDefaultOmadeusAccountId(_cfg) {
14
14
  function resolveOmadeusAccount(params) {
15
15
  const { cfg } = params;
16
16
  const section = getOmadeusChannelConfig(cfg) ?? {};
17
+ const environment = resolveOmadeusEnvironment(section.environment);
18
+ const { casUrl, maestroUrl } = getOmadeusEnvironmentUrls(environment);
17
19
  const envCredentials = resolveOmadeusEnvCredentials();
18
20
  const email = section.email?.trim() || envCredentials?.email || "";
19
21
  const password = section.password?.trim() || envCredentials?.password || "";
20
22
  const orgId = section.organizationId ?? envCredentials?.organizationId;
21
- const sessionToken = section.sessionToken?.trim() ?? "";
23
+ const rawSessionToken = section.sessionToken?.trim() ?? "";
24
+ const sessionTokenEnvironment = resolveOmadeusEnvironment(section.sessionTokenEnvironment);
25
+ const sessionToken = Boolean(rawSessionToken) && sessionTokenEnvironment === environment ? rawSessionToken : "";
22
26
  const hasCredentials = Boolean(email && password && orgId);
23
27
  const hasSessionToken = Boolean(sessionToken);
24
28
  const credentialSource = Boolean(section.email?.trim() && section.password?.trim() && section.organizationId) ? "config" : hasCredentials ? "env" : hasSessionToken ? "session" : "none";
@@ -27,8 +31,9 @@ function resolveOmadeusAccount(params) {
27
31
  name: "Omadeus",
28
32
  enabled: section.enabled !== false,
29
33
  config: section,
30
- casUrl: section.casUrl?.trim() || "https://dev1-cas.rouztech.com",
31
- maestroUrl: section.maestroUrl?.trim() || "https://dev3-maestro.rouztech.com",
34
+ environment,
35
+ casUrl,
36
+ maestroUrl,
32
37
  email,
33
38
  password,
34
39
  organizationId: orgId ?? 0,
@@ -1,5 +1,31 @@
1
- //#region src/defaults.ts
2
- const OMADEUS_CAS_URL = "https://dev1-cas.rouztech.com";
3
- const OMADEUS_MAESTRO_URL = "https://dev3-maestro.rouztech.com";
1
+ const OMADEUS_ENVIRONMENTS = {
2
+ production: {
3
+ label: "Production",
4
+ casUrl: "https://xas.xeba.tech",
5
+ maestroUrl: "https://maestro.xeba.tech"
6
+ },
7
+ staging: {
8
+ label: "Staging",
9
+ casUrl: "https://staging-xas.xeba.tech",
10
+ maestroUrl: "https://staging.xeba.tech"
11
+ },
12
+ dev: {
13
+ label: "Dev",
14
+ casUrl: "https://dev1-cas.rouztech.com",
15
+ maestroUrl: "https://dev1-maestro.rouztech.com"
16
+ }
17
+ };
18
+ const OMADEUS_ENVIRONMENT_SET = new Set(Object.keys(OMADEUS_ENVIRONMENTS));
19
+ function resolveOmadeusEnvironment(value) {
20
+ if (typeof value === "string" && OMADEUS_ENVIRONMENT_SET.has(value)) return value;
21
+ return "dev";
22
+ }
23
+ function getOmadeusEnvironmentUrls(env) {
24
+ const config = OMADEUS_ENVIRONMENTS[env];
25
+ return {
26
+ casUrl: config.casUrl,
27
+ maestroUrl: config.maestroUrl
28
+ };
29
+ }
4
30
  //#endregion
5
- export { OMADEUS_CAS_URL, OMADEUS_MAESTRO_URL };
31
+ export { OMADEUS_ENVIRONMENTS, getOmadeusEnvironmentUrls, resolveOmadeusEnvironment };
@@ -1,4 +1,4 @@
1
- import { OMADEUS_CAS_URL, OMADEUS_MAESTRO_URL } from "./defaults.js";
1
+ import { OMADEUS_ENVIRONMENTS, getOmadeusEnvironmentUrls, resolveOmadeusEnvironment } from "./defaults.js";
2
2
  import { getOmadeusChannelConfig, resolveOmadeusAccount } from "./config.js";
3
3
  import { listOrganizationMembers, listOrganizations } from "./api/auth.api.js";
4
4
  import { formatMemberLabel } from "./member-resolve.js";
@@ -19,17 +19,26 @@ function formatAuthError(err) {
19
19
  } else if (typeof cause === "string" && cause.trim()) parts.push(cause);
20
20
  return parts.join(" — ");
21
21
  }
22
- async function noteOmadeusAuthHelp(prompter) {
22
+ async function noteOmadeusAuthHelp(prompter, environment) {
23
+ const envLabel = OMADEUS_ENVIRONMENTS[environment].label;
23
24
  await prompter.note([
24
- "Omadeus authenticates via CAS + Maestro (email + password + organization).",
25
- "You need:",
26
- " - Email + password",
27
- " - Organization ID (we can look it up for you)",
28
- `CAS URL: ${OMADEUS_CAS_URL}`,
29
- `Maestro URL: ${OMADEUS_MAESTRO_URL}`,
30
- "Env vars supported: OMADEUS_EMAIL, OMADEUS_PASSWORD, OMADEUS_ORGANIZATION_ID."
25
+ `Connect OpenClaw to Omadeus (${envLabel}).`,
26
+ "",
27
+ "We'll ask for your email and password, then show the organizations on your account so you can pick one."
31
28
  ].join("\n"), "Omadeus setup");
32
29
  }
30
+ async function promptEnvironment(prompter, existing) {
31
+ const initial = existing ?? "dev";
32
+ return resolveOmadeusEnvironment(await prompter.select({
33
+ message: "Select Omadeus environment",
34
+ options: Object.keys(OMADEUS_ENVIRONMENTS).map((env) => ({
35
+ value: env,
36
+ label: OMADEUS_ENVIRONMENTS[env].label,
37
+ hint: getOmadeusEnvironmentUrls(env).maestroUrl
38
+ })),
39
+ initialValue: initial
40
+ }));
41
+ }
33
42
  async function promptOrganizationId(params) {
34
43
  const { prompter, maestroUrl, email, existing } = params;
35
44
  try {
@@ -208,11 +217,11 @@ const omadeusSetupWizard = {
208
217
  const account = resolveOmadeusAccount({ cfg });
209
218
  const section = getOmadeusChannelConfig(cfg) ?? {};
210
219
  let next = cfg;
211
- if (account.credentialSource === "none") await noteOmadeusAuthHelp(prompter);
220
+ const environment = await promptEnvironment(prompter, section.environment ? resolveOmadeusEnvironment(section.environment) : void 0);
221
+ const { casUrl, maestroUrl } = getOmadeusEnvironmentUrls(environment);
222
+ if (account.credentialSource === "none") await noteOmadeusAuthHelp(prompter, environment);
212
223
  const envEmail = process.env.OMADEUS_EMAIL?.trim();
213
224
  const envPassword = process.env.OMADEUS_PASSWORD?.trim();
214
- const casUrl = OMADEUS_CAS_URL;
215
- const maestroUrl = OMADEUS_MAESTRO_URL;
216
225
  let { email, password } = await promptCredentials(prompter, {
217
226
  email: section.email ?? envEmail,
218
227
  password: section.password ?? envPassword
@@ -307,12 +316,12 @@ const omadeusSetupWizard = {
307
316
  ...next.channels,
308
317
  omadeus: {
309
318
  enabled: true,
310
- casUrl,
311
- maestroUrl,
319
+ environment,
312
320
  email,
313
321
  password,
314
322
  organizationId,
315
323
  sessionToken,
324
+ sessionTokenEnvironment: environment,
316
325
  inbound: {
317
326
  version: 1,
318
327
  direct: {
@@ -1,3 +1,4 @@
1
+ import { resolveOmadeusEnvironment } from "./defaults.js";
1
2
  //#region src/setup-core.ts
2
3
  function readSetupStringField(input, key) {
3
4
  const value = input[key];
@@ -18,8 +19,8 @@ const omadeusSetupAdapter = {
18
19
  },
19
20
  applyAccountConfig: ({ cfg, input }) => {
20
21
  const rawInput = input;
21
- const casUrl = input.httpUrl?.trim() || void 0;
22
- const maestroUrl = input.url?.trim() || void 0;
22
+ const environmentRaw = readSetupStringField(rawInput, "environment");
23
+ const environment = environmentRaw ? resolveOmadeusEnvironment(environmentRaw) : void 0;
23
24
  const email = readSetupStringField(rawInput, "email");
24
25
  const password = input.password?.trim() || void 0;
25
26
  const organizationId = readSetupNumberField(rawInput, "organizationId");
@@ -32,8 +33,7 @@ const omadeusSetupAdapter = {
32
33
  omadeus: {
33
34
  ...omadeusPrevious,
34
35
  enabled: true,
35
- ...casUrl ? { casUrl } : {},
36
- ...maestroUrl ? { maestroUrl } : {},
36
+ ...environment ? { environment } : {},
37
37
  ...email ? { email } : {},
38
38
  ...password ? { password } : {},
39
39
  ...organizationId ? { organizationId } : {}
@@ -6,12 +6,18 @@
6
6
  "additionalProperties": false,
7
7
  "properties": {
8
8
  "enabled": { "type": "boolean" },
9
- "casUrl": { "type": "string" },
10
- "maestroUrl": { "type": "string" },
9
+ "environment": {
10
+ "type": "string",
11
+ "enum": ["production", "staging", "dev"]
12
+ },
11
13
  "email": { "type": "string" },
12
14
  "password": { "type": "string" },
13
15
  "organizationId": { "type": "number" },
14
16
  "sessionToken": { "type": "string" },
17
+ "sessionTokenEnvironment": {
18
+ "type": "string",
19
+ "enum": ["production", "staging", "dev"]
20
+ },
15
21
  "inbound": {
16
22
  "type": "object",
17
23
  "additionalProperties": false,
@@ -92,12 +98,18 @@
92
98
  "additionalProperties": false,
93
99
  "properties": {
94
100
  "enabled": { "type": "boolean" },
95
- "casUrl": { "type": "string" },
96
- "maestroUrl": { "type": "string" },
101
+ "environment": {
102
+ "type": "string",
103
+ "enum": ["production", "staging", "dev"]
104
+ },
97
105
  "email": { "type": "string" },
98
106
  "password": { "type": "string" },
99
107
  "organizationId": { "type": "number" },
100
108
  "sessionToken": { "type": "string" },
109
+ "sessionTokenEnvironment": {
110
+ "type": "string",
111
+ "enum": ["production", "staging", "dev"]
112
+ },
101
113
  "inbound": {
102
114
  "type": "object",
103
115
  "additionalProperties": false,
@@ -172,13 +184,8 @@
172
184
  }
173
185
  },
174
186
  "uiHints": {
175
- "casUrl": {
176
- "label": "CAS URL",
177
- "placeholder": "https://dev1-cas.rouztech.com"
178
- },
179
- "maestroUrl": {
180
- "label": "Maestro URL",
181
- "placeholder": "https://dev3-maestro.rouztech.com"
187
+ "environment": {
188
+ "label": "Environment"
182
189
  },
183
190
  "email": {
184
191
  "label": "Email"
@@ -195,6 +202,10 @@
195
202
  "sensitive": true,
196
203
  "advanced": true
197
204
  },
205
+ "sessionTokenEnvironment": {
206
+ "label": "Session token environment",
207
+ "advanced": true
208
+ },
198
209
  "inbound": {
199
210
  "label": "Inbound policy (Jaguar chat)",
200
211
  "advanced": true
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@brantrusnak/openclaw-omadeus",
3
- "version": "1.0.4",
3
+ "version": "1.0.5",
4
4
  "private": false,
5
5
  "description": "OpenClaw Omadeus project management channel plugin",
6
6
  "homepage": "https://github.com/brantrusnak/openclaw-omadeus-plugin#readme",
package/src/channel.ts CHANGED
@@ -57,12 +57,15 @@ const isUnconfigured = (account: Account) => account.credentialSource === "none"
57
57
 
58
58
  let lastPersistedToken: string | null = null;
59
59
 
60
- async function persistSessionToken(token: string): Promise<void> {
60
+ async function persistSessionToken(
61
+ token: string,
62
+ environment: Account["environment"],
63
+ ): Promise<void> {
61
64
  if (lastPersistedToken === token) return;
62
65
  const runtime = getOmadeusRuntime();
63
66
  const cfg = runtime.config.current() as OpenClawConfig;
64
67
  const section = getOmadeusChannelConfig(cfg) ?? {};
65
- if (section.sessionToken === token) {
68
+ if (section.sessionToken === token && section.sessionTokenEnvironment === environment) {
66
69
  lastPersistedToken = token;
67
70
  return;
68
71
  }
@@ -74,6 +77,7 @@ async function persistSessionToken(token: string): Promise<void> {
74
77
  omadeus: {
75
78
  ...(getOmadeusChannelConfig(draft) ?? {}),
76
79
  sessionToken: token,
80
+ sessionTokenEnvironment: environment,
77
81
  },
78
82
  };
79
83
  },
@@ -103,12 +107,12 @@ const omadeusConfigAdapter = createTopLevelChannelConfigAdapter<Account>({
103
107
  defaultAccountId: resolveDefaultOmadeusAccountId,
104
108
  deleteMode: "clear-fields",
105
109
  clearBaseFields: [
106
- "casUrl",
107
- "maestroUrl",
110
+ "environment",
108
111
  "email",
109
112
  "password",
110
113
  "organizationId",
111
114
  "sessionToken",
115
+ "sessionTokenEnvironment",
112
116
  "inbound",
113
117
  ],
114
118
  // Keep adapter contract satisfied even though Omadeus no longer uses DM allowlists.
@@ -561,7 +565,7 @@ export const omadeusPlugin: ChannelPlugin<Account> = {
561
565
  initialToken: account.sessionToken,
562
566
  onRefresh: (token) => {
563
567
  log.info("[omadeus] token refreshed");
564
- void persistSessionToken(token).catch((err) =>
568
+ void persistSessionToken(token, account.environment).catch((err) =>
565
569
  log.warn(`[omadeus] failed to persist session token: ${String(err)}`),
566
570
  );
567
571
  },
package/src/config.ts CHANGED
@@ -1,5 +1,8 @@
1
1
  import { DEFAULT_ACCOUNT_ID, type OpenClawConfig } from "../runtime-api.js";
2
- import { OMADEUS_CAS_URL, OMADEUS_MAESTRO_URL } from "./defaults.js";
2
+ import {
3
+ getOmadeusEnvironmentUrls,
4
+ resolveOmadeusEnvironment,
5
+ } from "./defaults.js";
3
6
  import type { OmadeusChannelConfig, ResolvedOmadeusAccount } from "./types.js";
4
7
 
5
8
  export function getOmadeusChannelConfig(cfg: OpenClawConfig): OmadeusChannelConfig | undefined {
@@ -24,11 +27,17 @@ export function resolveOmadeusAccount(params: {
24
27
  }): ResolvedOmadeusAccount {
25
28
  const { cfg } = params;
26
29
  const section = getOmadeusChannelConfig(cfg) ?? {};
30
+ const environment = resolveOmadeusEnvironment(section.environment);
31
+ const { casUrl, maestroUrl } = getOmadeusEnvironmentUrls(environment);
27
32
  const envCredentials = resolveOmadeusEnvCredentials();
28
33
  const email = section.email?.trim() || envCredentials?.email || "";
29
34
  const password = section.password?.trim() || envCredentials?.password || "";
30
35
  const orgId = section.organizationId ?? envCredentials?.organizationId;
31
- const sessionToken = section.sessionToken?.trim() ?? "";
36
+ const rawSessionToken = section.sessionToken?.trim() ?? "";
37
+ const sessionTokenEnvironment = resolveOmadeusEnvironment(section.sessionTokenEnvironment);
38
+ const sessionTokenValid =
39
+ Boolean(rawSessionToken) && sessionTokenEnvironment === environment;
40
+ const sessionToken = sessionTokenValid ? rawSessionToken : "";
32
41
  const hasCredentials = Boolean(email && password && orgId);
33
42
  const hasSessionToken = Boolean(sessionToken);
34
43
  const hasConfigCredentials = Boolean(
@@ -47,8 +56,9 @@ export function resolveOmadeusAccount(params: {
47
56
  name: "Omadeus",
48
57
  enabled: section.enabled !== false,
49
58
  config: section,
50
- casUrl: section.casUrl?.trim() || OMADEUS_CAS_URL,
51
- maestroUrl: section.maestroUrl?.trim() || OMADEUS_MAESTRO_URL,
59
+ environment,
60
+ casUrl,
61
+ maestroUrl,
52
62
  email,
53
63
  password,
54
64
  organizationId: orgId ?? 0,
package/src/defaults.ts CHANGED
@@ -1,2 +1,44 @@
1
- export const OMADEUS_CAS_URL = "https://dev1-cas.rouztech.com";
2
- export const OMADEUS_MAESTRO_URL = "https://dev3-maestro.rouztech.com";
1
+ export type OmadeusEnvironment = "production" | "staging" | "dev";
2
+
3
+ export const OMADEUS_DEFAULT_ENVIRONMENT: OmadeusEnvironment = "dev";
4
+
5
+ export type OmadeusEnvironmentConfig = {
6
+ label: string;
7
+ casUrl: string;
8
+ maestroUrl: string;
9
+ };
10
+
11
+ export const OMADEUS_ENVIRONMENTS: Record<OmadeusEnvironment, OmadeusEnvironmentConfig> = {
12
+ production: {
13
+ label: "Production",
14
+ casUrl: "https://xas.xeba.tech",
15
+ maestroUrl: "https://maestro.xeba.tech",
16
+ },
17
+ staging: {
18
+ label: "Staging",
19
+ casUrl: "https://staging-xas.xeba.tech",
20
+ maestroUrl: "https://staging.xeba.tech",
21
+ },
22
+ dev: {
23
+ label: "Dev",
24
+ casUrl: "https://dev1-cas.rouztech.com",
25
+ maestroUrl: "https://dev1-maestro.rouztech.com",
26
+ },
27
+ };
28
+
29
+ const OMADEUS_ENVIRONMENT_SET = new Set<string>(Object.keys(OMADEUS_ENVIRONMENTS));
30
+
31
+ export function resolveOmadeusEnvironment(value: unknown): OmadeusEnvironment {
32
+ if (typeof value === "string" && OMADEUS_ENVIRONMENT_SET.has(value)) {
33
+ return value as OmadeusEnvironment;
34
+ }
35
+ return OMADEUS_DEFAULT_ENVIRONMENT;
36
+ }
37
+
38
+ export function getOmadeusEnvironmentUrls(env: OmadeusEnvironment): {
39
+ casUrl: string;
40
+ maestroUrl: string;
41
+ } {
42
+ const config = OMADEUS_ENVIRONMENTS[env];
43
+ return { casUrl: config.casUrl, maestroUrl: config.maestroUrl };
44
+ }
package/src/onboarding.ts CHANGED
@@ -7,7 +7,13 @@ import {
7
7
  import { listMemberChannelViews } from "./api/channel.api.js";
8
8
  import { authenticate } from "./auth.js";
9
9
  import { getOmadeusChannelConfig, resolveOmadeusAccount } from "./config.js";
10
- import { OMADEUS_CAS_URL, OMADEUS_MAESTRO_URL } from "./defaults.js";
10
+ import {
11
+ getOmadeusEnvironmentUrls,
12
+ OMADEUS_DEFAULT_ENVIRONMENT,
13
+ OMADEUS_ENVIRONMENTS,
14
+ resolveOmadeusEnvironment,
15
+ type OmadeusEnvironment,
16
+ } from "./defaults.js";
11
17
  import { formatMemberLabel } from "./member-resolve.js";
12
18
  import type {
13
19
  OmadeusChannelConfig,
@@ -41,21 +47,38 @@ function formatAuthError(err: unknown): string {
41
47
  return parts.join(" — ");
42
48
  }
43
49
 
44
- async function noteOmadeusAuthHelp(prompter: WizardPrompter): Promise<void> {
50
+ async function noteOmadeusAuthHelp(
51
+ prompter: WizardPrompter,
52
+ environment: OmadeusEnvironment,
53
+ ): Promise<void> {
54
+ const envLabel = OMADEUS_ENVIRONMENTS[environment].label;
45
55
  await prompter.note(
46
56
  [
47
- "Omadeus authenticates via CAS + Maestro (email + password + organization).",
48
- "You need:",
49
- " - Email + password",
50
- " - Organization ID (we can look it up for you)",
51
- `CAS URL: ${OMADEUS_CAS_URL}`,
52
- `Maestro URL: ${OMADEUS_MAESTRO_URL}`,
53
- "Env vars supported: OMADEUS_EMAIL, OMADEUS_PASSWORD, OMADEUS_ORGANIZATION_ID.",
57
+ `Connect OpenClaw to Omadeus (${envLabel}).`,
58
+ "",
59
+ "We'll ask for your email and password, then show the organizations on your account so you can pick one.",
54
60
  ].join("\n"),
55
61
  "Omadeus setup",
56
62
  );
57
63
  }
58
64
 
65
+ async function promptEnvironment(
66
+ prompter: WizardPrompter,
67
+ existing?: OmadeusEnvironment,
68
+ ): Promise<OmadeusEnvironment> {
69
+ const initial = existing ?? OMADEUS_DEFAULT_ENVIRONMENT;
70
+ const choice = await prompter.select({
71
+ message: "Select Omadeus environment",
72
+ options: (Object.keys(OMADEUS_ENVIRONMENTS) as OmadeusEnvironment[]).map((env) => ({
73
+ value: env,
74
+ label: OMADEUS_ENVIRONMENTS[env].label,
75
+ hint: getOmadeusEnvironmentUrls(env).maestroUrl,
76
+ })),
77
+ initialValue: initial,
78
+ });
79
+ return resolveOmadeusEnvironment(choice);
80
+ }
81
+
59
82
  async function promptOrganizationId(params: {
60
83
  prompter: WizardPrompter;
61
84
  maestroUrl: string;
@@ -315,16 +338,19 @@ export const omadeusSetupWizard: ChannelSetupWizard = {
315
338
  const section = getOmadeusChannelConfig(cfg) ?? {};
316
339
  let next = cfg;
317
340
 
341
+ const environment = await promptEnvironment(
342
+ prompter,
343
+ section.environment ? resolveOmadeusEnvironment(section.environment) : undefined,
344
+ );
345
+ const { casUrl, maestroUrl } = getOmadeusEnvironmentUrls(environment);
346
+
318
347
  if (account.credentialSource === "none") {
319
- await noteOmadeusAuthHelp(prompter);
348
+ await noteOmadeusAuthHelp(prompter, environment);
320
349
  }
321
350
 
322
351
  const envEmail = process.env.OMADEUS_EMAIL?.trim();
323
352
  const envPassword = process.env.OMADEUS_PASSWORD?.trim();
324
353
 
325
- const casUrl = OMADEUS_CAS_URL;
326
- const maestroUrl = OMADEUS_MAESTRO_URL;
327
-
328
354
  let { email, password } = await promptCredentials(prompter, {
329
355
  email: section.email ?? envEmail,
330
356
  password: section.password ?? envPassword,
@@ -465,12 +491,12 @@ export const omadeusSetupWizard: ChannelSetupWizard = {
465
491
  ...next.channels,
466
492
  omadeus: {
467
493
  enabled: true,
468
- casUrl,
469
- maestroUrl,
494
+ environment,
470
495
  email,
471
496
  password,
472
497
  organizationId,
473
498
  sessionToken,
499
+ sessionTokenEnvironment: environment,
474
500
  inbound: {
475
501
  version: 1,
476
502
  direct: {
package/src/setup-core.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import type { ChannelSetupAdapter } from "openclaw/plugin-sdk/setup";
2
2
  import type { OpenClawConfig } from "../runtime-api.js";
3
+ import { resolveOmadeusEnvironment } from "./defaults.js";
3
4
 
4
5
  function readSetupStringField(input: Record<string, unknown>, key: string): string | undefined {
5
6
  const value = input[key];
@@ -29,8 +30,8 @@ export const omadeusSetupAdapter: ChannelSetupAdapter = {
29
30
  },
30
31
  applyAccountConfig: ({ cfg, input }) => {
31
32
  const rawInput = input as Record<string, unknown>;
32
- const casUrl = input.httpUrl?.trim() || undefined;
33
- const maestroUrl = input.url?.trim() || undefined;
33
+ const environmentRaw = readSetupStringField(rawInput, "environment");
34
+ const environment = environmentRaw ? resolveOmadeusEnvironment(environmentRaw) : undefined;
34
35
  const email = readSetupStringField(rawInput, "email");
35
36
  const password = input.password?.trim() || undefined;
36
37
  const organizationId = readSetupNumberField(rawInput, "organizationId");
@@ -51,8 +52,7 @@ export const omadeusSetupAdapter: ChannelSetupAdapter = {
51
52
  omadeus: {
52
53
  ...omadeusPrevious,
53
54
  enabled: true,
54
- ...(casUrl ? { casUrl } : {}),
55
- ...(maestroUrl ? { maestroUrl } : {}),
55
+ ...(environment ? { environment } : {}),
56
56
  ...(email ? { email } : {}),
57
57
  ...(password ? { password } : {}),
58
58
  ...(organizationId ? { organizationId } : {}),
package/src/types.ts CHANGED
@@ -1,3 +1,5 @@
1
+ import type { OmadeusEnvironment } from "./defaults.js";
2
+
1
3
  // ---------------------------------------------------------------------------
2
4
  // Omadeus config shape (stored under channels.omadeus in OpenClaw config)
3
5
  // ---------------------------------------------------------------------------
@@ -61,13 +63,14 @@ export type OmadeusInboundPolicy = {
61
63
 
62
64
  export type OmadeusChannelConfig = {
63
65
  enabled?: boolean;
64
- casUrl?: string;
65
- maestroUrl?: string;
66
+ environment?: OmadeusEnvironment;
66
67
  email?: string;
67
68
  password?: string;
68
69
  organizationId?: number;
69
70
  /** Cached Omadeus session JWT obtained during onboarding/startup. */
70
71
  sessionToken?: string;
72
+ /** Environment the cached sessionToken was minted under (must match `environment`). */
73
+ sessionTokenEnvironment?: OmadeusEnvironment;
71
74
  /** Jaguar chat ingress allowlists and mention rules. */
72
75
  inbound?: OmadeusInboundPolicy;
73
76
  };
@@ -77,6 +80,7 @@ export type ResolvedOmadeusAccount = {
77
80
  name?: string;
78
81
  enabled: boolean;
79
82
  config: OmadeusChannelConfig;
83
+ environment: OmadeusEnvironment;
80
84
  casUrl: string;
81
85
  maestroUrl: string;
82
86
  email: string;