Tlon: split setup adapter helpers

This commit is contained in:
Vincent Koc
2026-03-15 19:19:22 -07:00
parent c6950367fb
commit c89527f389
4 changed files with 108 additions and 99 deletions

View File

@@ -7,7 +7,8 @@ import type {
} from "openclaw/plugin-sdk/tlon";
import { tlonChannelConfigSchema } from "./config-schema.js";
import { monitorTlonProvider } from "./monitor/index.js";
import { tlonSetupAdapter, tlonSetupWizard } from "./setup-surface.js";
import { tlonSetupAdapter } from "./setup-core.js";
import { tlonSetupWizard } from "./setup-surface.js";
import { formatTargetHint, normalizeShip, parseTlonTarget } from "./targets.js";
import { resolveTlonAccount, listTlonAccountIds } from "./types.js";
import { authenticate } from "./urbit/auth.js";

View File

@@ -0,0 +1,101 @@
import {
applyAccountNameToChannelSection,
patchScopedAccountConfig,
} from "../../../src/channels/plugins/setup-helpers.js";
import type { ChannelSetupAdapter } from "../../../src/channels/plugins/types.adapters.js";
import type { ChannelSetupInput } from "../../../src/channels/plugins/types.core.js";
import type { OpenClawConfig } from "../../../src/config/config.js";
import { DEFAULT_ACCOUNT_ID, normalizeAccountId } from "../../../src/routing/session-key.js";
import { buildTlonAccountFields } from "./account-fields.js";
import { resolveTlonAccount } from "./types.js";
const channel = "tlon" as const;
export type TlonSetupInput = ChannelSetupInput & {
ship?: string;
url?: string;
code?: string;
allowPrivateNetwork?: boolean;
groupChannels?: string[];
dmAllowlist?: string[];
autoDiscoverChannels?: boolean;
ownerShip?: string;
};
export function applyTlonSetupConfig(params: {
cfg: OpenClawConfig;
accountId: string;
input: TlonSetupInput;
}): OpenClawConfig {
const { cfg, accountId, input } = params;
const useDefault = accountId === DEFAULT_ACCOUNT_ID;
const namedConfig = applyAccountNameToChannelSection({
cfg,
channelKey: channel,
accountId,
name: input.name,
});
const base = namedConfig.channels?.tlon ?? {};
const payload = buildTlonAccountFields(input);
if (useDefault) {
return {
...namedConfig,
channels: {
...namedConfig.channels,
tlon: {
...base,
enabled: true,
...payload,
},
},
};
}
return patchScopedAccountConfig({
cfg: namedConfig,
channelKey: channel,
accountId,
patch: { enabled: base.enabled ?? true },
accountPatch: {
enabled: true,
...payload,
},
ensureChannelEnabled: false,
ensureAccountEnabled: false,
});
}
export const tlonSetupAdapter: ChannelSetupAdapter = {
resolveAccountId: ({ accountId }) => normalizeAccountId(accountId),
applyAccountName: ({ cfg, accountId, name }) =>
applyAccountNameToChannelSection({
cfg,
channelKey: channel,
accountId,
name,
}),
validateInput: ({ cfg, accountId, input }) => {
const setupInput = input as TlonSetupInput;
const resolved = resolveTlonAccount(cfg, accountId ?? undefined);
const ship = setupInput.ship?.trim() || resolved.ship;
const url = setupInput.url?.trim() || resolved.url;
const code = setupInput.code?.trim() || resolved.code;
if (!ship) {
return "Tlon requires --ship.";
}
if (!url) {
return "Tlon requires --url.";
}
if (!code) {
return "Tlon requires --code.";
}
return null;
},
applyAccountConfig: ({ cfg, accountId, input }) =>
applyTlonSetupConfig({
cfg,
accountId,
input: input as TlonSetupInput,
}),
};

View File

@@ -1,31 +1,13 @@
import {
applyAccountNameToChannelSection,
patchScopedAccountConfig,
} from "../../../src/channels/plugins/setup-helpers.js";
import type { ChannelSetupWizard } from "../../../src/channels/plugins/setup-wizard.js";
import type { ChannelSetupAdapter } from "../../../src/channels/plugins/types.adapters.js";
import type { ChannelSetupInput } from "../../../src/channels/plugins/types.core.js";
import type { OpenClawConfig } from "../../../src/config/config.js";
import { DEFAULT_ACCOUNT_ID, normalizeAccountId } from "../../../src/routing/session-key.js";
import { DEFAULT_ACCOUNT_ID } from "../../../src/routing/session-key.js";
import { formatDocsLink } from "../../../src/terminal/links.js";
import { buildTlonAccountFields } from "./account-fields.js";
import { applyTlonSetupConfig, type TlonSetupInput, tlonSetupAdapter } from "./setup-core.js";
import { normalizeShip } from "./targets.js";
import { listTlonAccountIds, resolveTlonAccount, type TlonResolvedAccount } from "./types.js";
import { isBlockedUrbitHostname, validateUrbitBaseUrl } from "./urbit/base-url.js";
const channel = "tlon" as const;
type TlonSetupInput = ChannelSetupInput & {
ship?: string;
url?: string;
code?: string;
allowPrivateNetwork?: boolean;
groupChannels?: string[];
dmAllowlist?: string[];
autoDiscoverChannels?: boolean;
ownerShip?: string;
};
function isConfigured(account: TlonResolvedAccount): boolean {
return Boolean(account.ship && account.url && account.code);
}
@@ -37,83 +19,7 @@ function parseList(value: string): string[] {
.filter(Boolean);
}
function applyTlonSetupConfig(params: {
cfg: OpenClawConfig;
accountId: string;
input: TlonSetupInput;
}): OpenClawConfig {
const { cfg, accountId, input } = params;
const useDefault = accountId === DEFAULT_ACCOUNT_ID;
const namedConfig = applyAccountNameToChannelSection({
cfg,
channelKey: channel,
accountId,
name: input.name,
});
const base = namedConfig.channels?.tlon ?? {};
const payload = buildTlonAccountFields(input);
if (useDefault) {
return {
...namedConfig,
channels: {
...namedConfig.channels,
tlon: {
...base,
enabled: true,
...payload,
},
},
};
}
return patchScopedAccountConfig({
cfg: namedConfig,
channelKey: channel,
accountId,
patch: { enabled: base.enabled ?? true },
accountPatch: {
enabled: true,
...payload,
},
ensureChannelEnabled: false,
ensureAccountEnabled: false,
});
}
export const tlonSetupAdapter: ChannelSetupAdapter = {
resolveAccountId: ({ accountId }) => normalizeAccountId(accountId),
applyAccountName: ({ cfg, accountId, name }) =>
applyAccountNameToChannelSection({
cfg,
channelKey: channel,
accountId,
name,
}),
validateInput: ({ cfg, accountId, input }) => {
const setupInput = input as TlonSetupInput;
const resolved = resolveTlonAccount(cfg, accountId ?? undefined);
const ship = setupInput.ship?.trim() || resolved.ship;
const url = setupInput.url?.trim() || resolved.url;
const code = setupInput.code?.trim() || resolved.code;
if (!ship) {
return "Tlon requires --ship.";
}
if (!url) {
return "Tlon requires --url.";
}
if (!code) {
return "Tlon requires --code.";
}
return null;
},
applyAccountConfig: ({ cfg, accountId, input }) =>
applyTlonSetupConfig({
cfg,
accountId,
input: input as TlonSetupInput,
}),
};
export { tlonSetupAdapter } from "./setup-core.js";
export const tlonSetupWizard: ChannelSetupWizard = {
channel,

View File

@@ -28,4 +28,5 @@ export type { RuntimeEnv } from "../runtime.js";
export { formatDocsLink } from "../terminal/links.js";
export type { WizardPrompter } from "../wizard/prompts.js";
export { createLoggerBackedRuntime } from "./runtime.js";
export { tlonSetupAdapter, tlonSetupWizard } from "../../extensions/tlon/src/setup-surface.js";
export { tlonSetupAdapter } from "../../extensions/tlon/src/setup-core.js";
export { tlonSetupWizard } from "../../extensions/tlon/src/setup-surface.js";