chore: migrate to oxlint and oxfmt
Co-authored-by: Christoph Nakazawa <christoph.pojer@gmail.com>
This commit is contained in:
@@ -5,25 +5,17 @@ import {
|
||||
resolveDefaultDiscordAccountId,
|
||||
resolveDiscordAccount,
|
||||
} from "../../../discord/accounts.js";
|
||||
import {
|
||||
DEFAULT_ACCOUNT_ID,
|
||||
normalizeAccountId,
|
||||
} from "../../../routing/session-key.js";
|
||||
import { DEFAULT_ACCOUNT_ID, normalizeAccountId } from "../../../routing/session-key.js";
|
||||
import { formatDocsLink } from "../../../terminal/links.js";
|
||||
import type { WizardPrompter } from "../../../wizard/prompts.js";
|
||||
import type {
|
||||
ChannelOnboardingAdapter,
|
||||
ChannelOnboardingDmPolicy,
|
||||
} from "../onboarding-types.js";
|
||||
import type { ChannelOnboardingAdapter, ChannelOnboardingDmPolicy } from "../onboarding-types.js";
|
||||
import { addWildcardAllowFrom, promptAccountId } from "./helpers.js";
|
||||
|
||||
const channel = "discord" as const;
|
||||
|
||||
function setDiscordDmPolicy(cfg: ClawdbotConfig, dmPolicy: DmPolicy) {
|
||||
const allowFrom =
|
||||
dmPolicy === "open"
|
||||
? addWildcardAllowFrom(cfg.channels?.discord?.dm?.allowFrom)
|
||||
: undefined;
|
||||
dmPolicy === "open" ? addWildcardAllowFrom(cfg.channels?.discord?.dm?.allowFrom) : undefined;
|
||||
return {
|
||||
...cfg,
|
||||
channels: {
|
||||
@@ -77,12 +69,7 @@ export const discordOnboardingAdapter: ChannelOnboardingAdapter = {
|
||||
quickstartScore: configured ? 2 : 1,
|
||||
};
|
||||
},
|
||||
configure: async ({
|
||||
cfg,
|
||||
prompter,
|
||||
accountOverrides,
|
||||
shouldPromptAccountIds,
|
||||
}) => {
|
||||
configure: async ({ cfg, prompter, accountOverrides, shouldPromptAccountIds }) => {
|
||||
const discordOverride = accountOverrides.discord?.trim();
|
||||
const defaultDiscordAccountId = resolveDefaultDiscordAccountId(cfg);
|
||||
let discordAccountId = discordOverride
|
||||
@@ -106,8 +93,7 @@ export const discordOnboardingAdapter: ChannelOnboardingAdapter = {
|
||||
});
|
||||
const accountConfigured = Boolean(resolvedAccount.token);
|
||||
const allowEnv = discordAccountId === DEFAULT_ACCOUNT_ID;
|
||||
const canUseEnv =
|
||||
allowEnv && Boolean(process.env.DISCORD_BOT_TOKEN?.trim());
|
||||
const canUseEnv = allowEnv && Boolean(process.env.DISCORD_BOT_TOKEN?.trim());
|
||||
const hasConfigToken = Boolean(resolvedAccount.config.token);
|
||||
|
||||
let token: string | null = null;
|
||||
@@ -178,9 +164,7 @@ export const discordOnboardingAdapter: ChannelOnboardingAdapter = {
|
||||
...next.channels?.discord?.accounts,
|
||||
[discordAccountId]: {
|
||||
...next.channels?.discord?.accounts?.[discordAccountId],
|
||||
enabled:
|
||||
next.channels?.discord?.accounts?.[discordAccountId]
|
||||
?.enabled ?? true,
|
||||
enabled: next.channels?.discord?.accounts?.[discordAccountId]?.enabled ?? true,
|
||||
token,
|
||||
},
|
||||
},
|
||||
|
||||
@@ -1,18 +1,9 @@
|
||||
import {
|
||||
DEFAULT_ACCOUNT_ID,
|
||||
normalizeAccountId,
|
||||
} from "../../../routing/session-key.js";
|
||||
import type {
|
||||
PromptAccountId,
|
||||
PromptAccountIdParams,
|
||||
} from "../onboarding-types.js";
|
||||
import { DEFAULT_ACCOUNT_ID, normalizeAccountId } from "../../../routing/session-key.js";
|
||||
import type { PromptAccountId, PromptAccountIdParams } from "../onboarding-types.js";
|
||||
|
||||
export const promptAccountId: PromptAccountId = async (
|
||||
params: PromptAccountIdParams,
|
||||
) => {
|
||||
export const promptAccountId: PromptAccountId = async (params: PromptAccountIdParams) => {
|
||||
const existingIds = params.listAccountIds(params.cfg);
|
||||
const initial =
|
||||
params.currentId?.trim() || params.defaultAccountId || DEFAULT_ACCOUNT_ID;
|
||||
const initial = params.currentId?.trim() || params.defaultAccountId || DEFAULT_ACCOUNT_ID;
|
||||
const choice = (await params.prompter.select({
|
||||
message: `${params.label} account`,
|
||||
options: [
|
||||
|
||||
@@ -6,24 +6,16 @@ import {
|
||||
resolveDefaultIMessageAccountId,
|
||||
resolveIMessageAccount,
|
||||
} from "../../../imessage/accounts.js";
|
||||
import {
|
||||
DEFAULT_ACCOUNT_ID,
|
||||
normalizeAccountId,
|
||||
} from "../../../routing/session-key.js";
|
||||
import { DEFAULT_ACCOUNT_ID, normalizeAccountId } from "../../../routing/session-key.js";
|
||||
import { formatDocsLink } from "../../../terminal/links.js";
|
||||
import type {
|
||||
ChannelOnboardingAdapter,
|
||||
ChannelOnboardingDmPolicy,
|
||||
} from "../onboarding-types.js";
|
||||
import type { ChannelOnboardingAdapter, ChannelOnboardingDmPolicy } from "../onboarding-types.js";
|
||||
import { addWildcardAllowFrom, promptAccountId } from "./helpers.js";
|
||||
|
||||
const channel = "imessage" as const;
|
||||
|
||||
function setIMessageDmPolicy(cfg: ClawdbotConfig, dmPolicy: DmPolicy) {
|
||||
const allowFrom =
|
||||
dmPolicy === "open"
|
||||
? addWildcardAllowFrom(cfg.channels?.imessage?.allowFrom)
|
||||
: undefined;
|
||||
dmPolicy === "open" ? addWildcardAllowFrom(cfg.channels?.imessage?.allowFrom) : undefined;
|
||||
return {
|
||||
...cfg,
|
||||
channels: {
|
||||
@@ -53,10 +45,10 @@ export const imessageOnboardingAdapter: ChannelOnboardingAdapter = {
|
||||
const account = resolveIMessageAccount({ cfg, accountId });
|
||||
return Boolean(
|
||||
account.config.cliPath ||
|
||||
account.config.dbPath ||
|
||||
account.config.allowFrom ||
|
||||
account.config.service ||
|
||||
account.config.region,
|
||||
account.config.dbPath ||
|
||||
account.config.allowFrom ||
|
||||
account.config.service ||
|
||||
account.config.region,
|
||||
);
|
||||
});
|
||||
const imessageCliPath = cfg.channels?.imessage?.cliPath ?? "imsg";
|
||||
@@ -72,12 +64,7 @@ export const imessageOnboardingAdapter: ChannelOnboardingAdapter = {
|
||||
quickstartScore: imessageCliDetected ? 1 : 0,
|
||||
};
|
||||
},
|
||||
configure: async ({
|
||||
cfg,
|
||||
prompter,
|
||||
accountOverrides,
|
||||
shouldPromptAccountIds,
|
||||
}) => {
|
||||
configure: async ({ cfg, prompter, accountOverrides, shouldPromptAccountIds }) => {
|
||||
const imessageOverride = accountOverrides.imessage?.trim();
|
||||
const defaultIMessageAccountId = resolveDefaultIMessageAccountId(cfg);
|
||||
let imessageAccountId = imessageOverride
|
||||
@@ -109,10 +96,7 @@ export const imessageOnboardingAdapter: ChannelOnboardingAdapter = {
|
||||
});
|
||||
resolvedCliPath = String(entered).trim();
|
||||
if (!resolvedCliPath) {
|
||||
await prompter.note(
|
||||
"imsg CLI path required to enable iMessage.",
|
||||
"iMessage",
|
||||
);
|
||||
await prompter.note("imsg CLI path required to enable iMessage.", "iMessage");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -141,9 +125,7 @@ export const imessageOnboardingAdapter: ChannelOnboardingAdapter = {
|
||||
...next.channels?.imessage?.accounts,
|
||||
[imessageAccountId]: {
|
||||
...next.channels?.imessage?.accounts?.[imessageAccountId],
|
||||
enabled:
|
||||
next.channels?.imessage?.accounts?.[imessageAccountId]
|
||||
?.enabled ?? true,
|
||||
enabled: next.channels?.imessage?.accounts?.[imessageAccountId]?.enabled ?? true,
|
||||
cliPath: resolvedCliPath,
|
||||
},
|
||||
},
|
||||
|
||||
@@ -4,10 +4,7 @@ import { resolveMSTeamsCredentials } from "../../../msteams/token.js";
|
||||
import { DEFAULT_ACCOUNT_ID } from "../../../routing/session-key.js";
|
||||
import { formatDocsLink } from "../../../terminal/links.js";
|
||||
import type { WizardPrompter } from "../../../wizard/prompts.js";
|
||||
import type {
|
||||
ChannelOnboardingAdapter,
|
||||
ChannelOnboardingDmPolicy,
|
||||
} from "../onboarding-types.js";
|
||||
import type { ChannelOnboardingAdapter, ChannelOnboardingDmPolicy } from "../onboarding-types.js";
|
||||
import { addWildcardAllowFrom } from "./helpers.js";
|
||||
|
||||
const channel = "msteams" as const;
|
||||
@@ -15,9 +12,7 @@ const channel = "msteams" as const;
|
||||
function setMSTeamsDmPolicy(cfg: ClawdbotConfig, dmPolicy: DmPolicy) {
|
||||
const allowFrom =
|
||||
dmPolicy === "open"
|
||||
? addWildcardAllowFrom(cfg.channels?.msteams?.allowFrom)?.map((entry) =>
|
||||
String(entry),
|
||||
)
|
||||
? addWildcardAllowFrom(cfg.channels?.msteams?.allowFrom)?.map((entry) => String(entry))
|
||||
: undefined;
|
||||
return {
|
||||
...cfg,
|
||||
@@ -32,9 +27,7 @@ function setMSTeamsDmPolicy(cfg: ClawdbotConfig, dmPolicy: DmPolicy) {
|
||||
};
|
||||
}
|
||||
|
||||
async function noteMSTeamsCredentialHelp(
|
||||
prompter: WizardPrompter,
|
||||
): Promise<void> {
|
||||
async function noteMSTeamsCredentialHelp(prompter: WizardPrompter): Promise<void> {
|
||||
await prompter.note(
|
||||
[
|
||||
"1) Azure Bot registration → get App ID + Tenant ID",
|
||||
@@ -59,15 +52,11 @@ const dmPolicy: ChannelOnboardingDmPolicy = {
|
||||
export const msteamsOnboardingAdapter: ChannelOnboardingAdapter = {
|
||||
channel,
|
||||
getStatus: async ({ cfg }) => {
|
||||
const configured = Boolean(
|
||||
resolveMSTeamsCredentials(cfg.channels?.msteams),
|
||||
);
|
||||
const configured = Boolean(resolveMSTeamsCredentials(cfg.channels?.msteams));
|
||||
return {
|
||||
channel,
|
||||
configured,
|
||||
statusLines: [
|
||||
`MS Teams: ${configured ? "configured" : "needs app credentials"}`,
|
||||
],
|
||||
statusLines: [`MS Teams: ${configured ? "configured" : "needs app credentials"}`],
|
||||
selectionHint: configured ? "configured" : "needs app creds",
|
||||
quickstartScore: configured ? 2 : 0,
|
||||
};
|
||||
@@ -76,14 +65,14 @@ export const msteamsOnboardingAdapter: ChannelOnboardingAdapter = {
|
||||
const resolved = resolveMSTeamsCredentials(cfg.channels?.msteams);
|
||||
const hasConfigCreds = Boolean(
|
||||
cfg.channels?.msteams?.appId?.trim() &&
|
||||
cfg.channels?.msteams?.appPassword?.trim() &&
|
||||
cfg.channels?.msteams?.tenantId?.trim(),
|
||||
cfg.channels?.msteams?.appPassword?.trim() &&
|
||||
cfg.channels?.msteams?.tenantId?.trim(),
|
||||
);
|
||||
const canUseEnv = Boolean(
|
||||
!hasConfigCreds &&
|
||||
process.env.MSTEAMS_APP_ID?.trim() &&
|
||||
process.env.MSTEAMS_APP_PASSWORD?.trim() &&
|
||||
process.env.MSTEAMS_TENANT_ID?.trim(),
|
||||
process.env.MSTEAMS_APP_ID?.trim() &&
|
||||
process.env.MSTEAMS_APP_PASSWORD?.trim() &&
|
||||
process.env.MSTEAMS_TENANT_ID?.trim(),
|
||||
);
|
||||
|
||||
let next = cfg;
|
||||
|
||||
@@ -2,29 +2,21 @@ import { detectBinary } from "../../../commands/onboard-helpers.js";
|
||||
import { installSignalCli } from "../../../commands/signal-install.js";
|
||||
import type { ClawdbotConfig } from "../../../config/config.js";
|
||||
import type { DmPolicy } from "../../../config/types.js";
|
||||
import {
|
||||
DEFAULT_ACCOUNT_ID,
|
||||
normalizeAccountId,
|
||||
} from "../../../routing/session-key.js";
|
||||
import { DEFAULT_ACCOUNT_ID, normalizeAccountId } from "../../../routing/session-key.js";
|
||||
import {
|
||||
listSignalAccountIds,
|
||||
resolveDefaultSignalAccountId,
|
||||
resolveSignalAccount,
|
||||
} from "../../../signal/accounts.js";
|
||||
import { formatDocsLink } from "../../../terminal/links.js";
|
||||
import type {
|
||||
ChannelOnboardingAdapter,
|
||||
ChannelOnboardingDmPolicy,
|
||||
} from "../onboarding-types.js";
|
||||
import type { ChannelOnboardingAdapter, ChannelOnboardingDmPolicy } from "../onboarding-types.js";
|
||||
import { addWildcardAllowFrom, promptAccountId } from "./helpers.js";
|
||||
|
||||
const channel = "signal" as const;
|
||||
|
||||
function setSignalDmPolicy(cfg: ClawdbotConfig, dmPolicy: DmPolicy) {
|
||||
const allowFrom =
|
||||
dmPolicy === "open"
|
||||
? addWildcardAllowFrom(cfg.channels?.signal?.allowFrom)
|
||||
: undefined;
|
||||
dmPolicy === "open" ? addWildcardAllowFrom(cfg.channels?.signal?.allowFrom) : undefined;
|
||||
return {
|
||||
...cfg,
|
||||
channels: {
|
||||
@@ -62,9 +54,7 @@ export const signalOnboardingAdapter: ChannelOnboardingAdapter = {
|
||||
`Signal: ${configured ? "configured" : "needs setup"}`,
|
||||
`signal-cli: ${signalCliDetected ? "found" : "missing"} (${signalCliPath})`,
|
||||
],
|
||||
selectionHint: signalCliDetected
|
||||
? "signal-cli found"
|
||||
: "signal-cli missing",
|
||||
selectionHint: signalCliDetected ? "signal-cli found" : "signal-cli missing",
|
||||
quickstartScore: signalCliDetected ? 1 : 0,
|
||||
};
|
||||
},
|
||||
@@ -113,21 +103,12 @@ export const signalOnboardingAdapter: ChannelOnboardingAdapter = {
|
||||
if (result.ok && result.cliPath) {
|
||||
cliDetected = true;
|
||||
resolvedCliPath = result.cliPath;
|
||||
await prompter.note(
|
||||
`Installed signal-cli at ${result.cliPath}`,
|
||||
"Signal",
|
||||
);
|
||||
await prompter.note(`Installed signal-cli at ${result.cliPath}`, "Signal");
|
||||
} else if (!result.ok) {
|
||||
await prompter.note(
|
||||
result.error ?? "signal-cli install failed.",
|
||||
"Signal",
|
||||
);
|
||||
await prompter.note(result.error ?? "signal-cli install failed.", "Signal");
|
||||
}
|
||||
} catch (err) {
|
||||
await prompter.note(
|
||||
`signal-cli install failed: ${String(err)}`,
|
||||
"Signal",
|
||||
);
|
||||
await prompter.note(`signal-cli install failed: ${String(err)}`, "Signal");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -183,9 +164,7 @@ export const signalOnboardingAdapter: ChannelOnboardingAdapter = {
|
||||
...next.channels?.signal?.accounts,
|
||||
[signalAccountId]: {
|
||||
...next.channels?.signal?.accounts?.[signalAccountId],
|
||||
enabled:
|
||||
next.channels?.signal?.accounts?.[signalAccountId]
|
||||
?.enabled ?? true,
|
||||
enabled: next.channels?.signal?.accounts?.[signalAccountId]?.enabled ?? true,
|
||||
account,
|
||||
cliPath: resolvedCliPath ?? "signal-cli",
|
||||
},
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
import type { ClawdbotConfig } from "../../../config/config.js";
|
||||
import type { DmPolicy } from "../../../config/types.js";
|
||||
import {
|
||||
DEFAULT_ACCOUNT_ID,
|
||||
normalizeAccountId,
|
||||
} from "../../../routing/session-key.js";
|
||||
import { DEFAULT_ACCOUNT_ID, normalizeAccountId } from "../../../routing/session-key.js";
|
||||
import {
|
||||
listSlackAccountIds,
|
||||
resolveDefaultSlackAccountId,
|
||||
@@ -11,19 +8,14 @@ import {
|
||||
} from "../../../slack/accounts.js";
|
||||
import { formatDocsLink } from "../../../terminal/links.js";
|
||||
import type { WizardPrompter } from "../../../wizard/prompts.js";
|
||||
import type {
|
||||
ChannelOnboardingAdapter,
|
||||
ChannelOnboardingDmPolicy,
|
||||
} from "../onboarding-types.js";
|
||||
import type { ChannelOnboardingAdapter, ChannelOnboardingDmPolicy } from "../onboarding-types.js";
|
||||
import { addWildcardAllowFrom, promptAccountId } from "./helpers.js";
|
||||
|
||||
const channel = "slack" as const;
|
||||
|
||||
function setSlackDmPolicy(cfg: ClawdbotConfig, dmPolicy: DmPolicy) {
|
||||
const allowFrom =
|
||||
dmPolicy === "open"
|
||||
? addWildcardAllowFrom(cfg.channels?.slack?.dm?.allowFrom)
|
||||
: undefined;
|
||||
dmPolicy === "open" ? addWildcardAllowFrom(cfg.channels?.slack?.dm?.allowFrom) : undefined;
|
||||
return {
|
||||
...cfg,
|
||||
channels: {
|
||||
@@ -110,10 +102,7 @@ function buildSlackManifest(botName: string) {
|
||||
return JSON.stringify(manifest, null, 2);
|
||||
}
|
||||
|
||||
async function noteSlackTokenHelp(
|
||||
prompter: WizardPrompter,
|
||||
botName: string,
|
||||
): Promise<void> {
|
||||
async function noteSlackTokenHelp(prompter: WizardPrompter, botName: string): Promise<void> {
|
||||
const manifest = buildSlackManifest(botName);
|
||||
await prompter.note(
|
||||
[
|
||||
@@ -156,17 +145,10 @@ export const slackOnboardingAdapter: ChannelOnboardingAdapter = {
|
||||
quickstartScore: configured ? 2 : 1,
|
||||
};
|
||||
},
|
||||
configure: async ({
|
||||
cfg,
|
||||
prompter,
|
||||
accountOverrides,
|
||||
shouldPromptAccountIds,
|
||||
}) => {
|
||||
configure: async ({ cfg, prompter, accountOverrides, shouldPromptAccountIds }) => {
|
||||
const slackOverride = accountOverrides.slack?.trim();
|
||||
const defaultSlackAccountId = resolveDefaultSlackAccountId(cfg);
|
||||
let slackAccountId = slackOverride
|
||||
? normalizeAccountId(slackOverride)
|
||||
: defaultSlackAccountId;
|
||||
let slackAccountId = slackOverride ? normalizeAccountId(slackOverride) : defaultSlackAccountId;
|
||||
if (shouldPromptAccountIds && !slackOverride) {
|
||||
slackAccountId = await promptAccountId({
|
||||
cfg,
|
||||
@@ -183,9 +165,7 @@ export const slackOnboardingAdapter: ChannelOnboardingAdapter = {
|
||||
cfg: next,
|
||||
accountId: slackAccountId,
|
||||
});
|
||||
const accountConfigured = Boolean(
|
||||
resolvedAccount.botToken && resolvedAccount.appToken,
|
||||
);
|
||||
const accountConfigured = Boolean(resolvedAccount.botToken && resolvedAccount.appToken);
|
||||
const allowEnv = slackAccountId === DEFAULT_ACCOUNT_ID;
|
||||
const canUseEnv =
|
||||
allowEnv &&
|
||||
@@ -206,10 +186,7 @@ export const slackOnboardingAdapter: ChannelOnboardingAdapter = {
|
||||
if (!accountConfigured) {
|
||||
await noteSlackTokenHelp(prompter, slackBotName);
|
||||
}
|
||||
if (
|
||||
canUseEnv &&
|
||||
(!resolvedAccount.config.botToken || !resolvedAccount.config.appToken)
|
||||
) {
|
||||
if (canUseEnv && (!resolvedAccount.config.botToken || !resolvedAccount.config.appToken)) {
|
||||
const keepEnv = await prompter.confirm({
|
||||
message: "SLACK_BOT_TOKEN + SLACK_APP_TOKEN detected. Use env vars?",
|
||||
initialValue: true,
|
||||
@@ -296,9 +273,7 @@ export const slackOnboardingAdapter: ChannelOnboardingAdapter = {
|
||||
...next.channels?.slack?.accounts,
|
||||
[slackAccountId]: {
|
||||
...next.channels?.slack?.accounts?.[slackAccountId],
|
||||
enabled:
|
||||
next.channels?.slack?.accounts?.[slackAccountId]?.enabled ??
|
||||
true,
|
||||
enabled: next.channels?.slack?.accounts?.[slackAccountId]?.enabled ?? true,
|
||||
botToken,
|
||||
appToken,
|
||||
},
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
import type { ClawdbotConfig } from "../../../config/config.js";
|
||||
import type { DmPolicy } from "../../../config/types.js";
|
||||
import {
|
||||
DEFAULT_ACCOUNT_ID,
|
||||
normalizeAccountId,
|
||||
} from "../../../routing/session-key.js";
|
||||
import { DEFAULT_ACCOUNT_ID, normalizeAccountId } from "../../../routing/session-key.js";
|
||||
import {
|
||||
listTelegramAccountIds,
|
||||
resolveDefaultTelegramAccountId,
|
||||
@@ -11,19 +8,14 @@ import {
|
||||
} from "../../../telegram/accounts.js";
|
||||
import { formatDocsLink } from "../../../terminal/links.js";
|
||||
import type { WizardPrompter } from "../../../wizard/prompts.js";
|
||||
import type {
|
||||
ChannelOnboardingAdapter,
|
||||
ChannelOnboardingDmPolicy,
|
||||
} from "../onboarding-types.js";
|
||||
import type { ChannelOnboardingAdapter, ChannelOnboardingDmPolicy } from "../onboarding-types.js";
|
||||
import { addWildcardAllowFrom, promptAccountId } from "./helpers.js";
|
||||
|
||||
const channel = "telegram" as const;
|
||||
|
||||
function setTelegramDmPolicy(cfg: ClawdbotConfig, dmPolicy: DmPolicy) {
|
||||
const allowFrom =
|
||||
dmPolicy === "open"
|
||||
? addWildcardAllowFrom(cfg.channels?.telegram?.allowFrom)
|
||||
: undefined;
|
||||
dmPolicy === "open" ? addWildcardAllowFrom(cfg.channels?.telegram?.allowFrom) : undefined;
|
||||
return {
|
||||
...cfg,
|
||||
channels: {
|
||||
@@ -62,9 +54,7 @@ async function promptTelegramAllowFrom(params: {
|
||||
const entry = await prompter.text({
|
||||
message: "Telegram allowFrom (user id)",
|
||||
placeholder: "123456789",
|
||||
initialValue: existingAllowFrom[0]
|
||||
? String(existingAllowFrom[0])
|
||||
: undefined,
|
||||
initialValue: existingAllowFrom[0] ? String(existingAllowFrom[0]) : undefined,
|
||||
validate: (value) => {
|
||||
const raw = String(value ?? "").trim();
|
||||
if (!raw) return "Required";
|
||||
@@ -105,8 +95,7 @@ async function promptTelegramAllowFrom(params: {
|
||||
...cfg.channels?.telegram?.accounts,
|
||||
[accountId]: {
|
||||
...cfg.channels?.telegram?.accounts?.[accountId],
|
||||
enabled:
|
||||
cfg.channels?.telegram?.accounts?.[accountId]?.enabled ?? true,
|
||||
enabled: cfg.channels?.telegram?.accounts?.[accountId]?.enabled ?? true,
|
||||
dmPolicy: "allowlist",
|
||||
allowFrom: unique,
|
||||
},
|
||||
@@ -135,9 +124,7 @@ export const telegramOnboardingAdapter: ChannelOnboardingAdapter = {
|
||||
channel,
|
||||
configured,
|
||||
statusLines: [`Telegram: ${configured ? "configured" : "needs token"}`],
|
||||
selectionHint: configured
|
||||
? "recommended · configured"
|
||||
: "recommended · newcomer-friendly",
|
||||
selectionHint: configured ? "recommended · configured" : "recommended · newcomer-friendly",
|
||||
quickstartScore: configured ? 1 : 10,
|
||||
};
|
||||
},
|
||||
@@ -171,8 +158,7 @@ export const telegramOnboardingAdapter: ChannelOnboardingAdapter = {
|
||||
});
|
||||
const accountConfigured = Boolean(resolvedAccount.token);
|
||||
const allowEnv = telegramAccountId === DEFAULT_ACCOUNT_ID;
|
||||
const canUseEnv =
|
||||
allowEnv && Boolean(process.env.TELEGRAM_BOT_TOKEN?.trim());
|
||||
const canUseEnv = allowEnv && Boolean(process.env.TELEGRAM_BOT_TOKEN?.trim());
|
||||
const hasConfigToken = Boolean(
|
||||
resolvedAccount.config.botToken || resolvedAccount.config.tokenFile,
|
||||
);
|
||||
@@ -252,9 +238,7 @@ export const telegramOnboardingAdapter: ChannelOnboardingAdapter = {
|
||||
...next.channels?.telegram?.accounts,
|
||||
[telegramAccountId]: {
|
||||
...next.channels?.telegram?.accounts?.[telegramAccountId],
|
||||
enabled:
|
||||
next.channels?.telegram?.accounts?.[telegramAccountId]
|
||||
?.enabled ?? true,
|
||||
enabled: next.channels?.telegram?.accounts?.[telegramAccountId]?.enabled ?? true,
|
||||
botToken: token,
|
||||
},
|
||||
},
|
||||
|
||||
@@ -4,10 +4,7 @@ import { loginWeb } from "../../../channel-web.js";
|
||||
import type { ClawdbotConfig } from "../../../config/config.js";
|
||||
import { mergeWhatsAppConfig } from "../../../config/merge-config.js";
|
||||
import type { DmPolicy } from "../../../config/types.js";
|
||||
import {
|
||||
DEFAULT_ACCOUNT_ID,
|
||||
normalizeAccountId,
|
||||
} from "../../../routing/session-key.js";
|
||||
import { DEFAULT_ACCOUNT_ID, normalizeAccountId } from "../../../routing/session-key.js";
|
||||
import type { RuntimeEnv } from "../../../runtime.js";
|
||||
import { formatDocsLink } from "../../../terminal/links.js";
|
||||
import { normalizeE164 } from "../../../utils.js";
|
||||
@@ -22,28 +19,15 @@ import { promptAccountId } from "./helpers.js";
|
||||
|
||||
const channel = "whatsapp" as const;
|
||||
|
||||
function setWhatsAppDmPolicy(
|
||||
cfg: ClawdbotConfig,
|
||||
dmPolicy: DmPolicy,
|
||||
): ClawdbotConfig {
|
||||
function setWhatsAppDmPolicy(cfg: ClawdbotConfig, dmPolicy: DmPolicy): ClawdbotConfig {
|
||||
return mergeWhatsAppConfig(cfg, { dmPolicy });
|
||||
}
|
||||
|
||||
function setWhatsAppAllowFrom(
|
||||
cfg: ClawdbotConfig,
|
||||
allowFrom?: string[],
|
||||
): ClawdbotConfig {
|
||||
return mergeWhatsAppConfig(
|
||||
cfg,
|
||||
{ allowFrom },
|
||||
{ unsetOnUndefined: ["allowFrom"] },
|
||||
);
|
||||
function setWhatsAppAllowFrom(cfg: ClawdbotConfig, allowFrom?: string[]): ClawdbotConfig {
|
||||
return mergeWhatsAppConfig(cfg, { allowFrom }, { unsetOnUndefined: ["allowFrom"] });
|
||||
}
|
||||
|
||||
function setMessagesResponsePrefix(
|
||||
cfg: ClawdbotConfig,
|
||||
responsePrefix?: string,
|
||||
): ClawdbotConfig {
|
||||
function setMessagesResponsePrefix(cfg: ClawdbotConfig, responsePrefix?: string): ClawdbotConfig {
|
||||
return {
|
||||
...cfg,
|
||||
messages: {
|
||||
@@ -53,10 +37,7 @@ function setMessagesResponsePrefix(
|
||||
};
|
||||
}
|
||||
|
||||
function setWhatsAppSelfChatMode(
|
||||
cfg: ClawdbotConfig,
|
||||
selfChatMode: boolean,
|
||||
): ClawdbotConfig {
|
||||
function setWhatsAppSelfChatMode(cfg: ClawdbotConfig, selfChatMode: boolean): ClawdbotConfig {
|
||||
return mergeWhatsAppConfig(cfg, { selfChatMode });
|
||||
}
|
||||
|
||||
@@ -69,10 +50,7 @@ async function pathExists(filePath: string): Promise<boolean> {
|
||||
}
|
||||
}
|
||||
|
||||
async function detectWhatsAppLinked(
|
||||
cfg: ClawdbotConfig,
|
||||
accountId: string,
|
||||
): Promise<boolean> {
|
||||
async function detectWhatsAppLinked(cfg: ClawdbotConfig, accountId: string): Promise<boolean> {
|
||||
const { authDir } = resolveWhatsAppAuthDir({ cfg, accountId });
|
||||
const credsPath = path.join(authDir, "creds.json");
|
||||
return await pathExists(credsPath);
|
||||
@@ -86,8 +64,7 @@ async function promptWhatsAppAllowFrom(
|
||||
): Promise<ClawdbotConfig> {
|
||||
const existingPolicy = cfg.channels?.whatsapp?.dmPolicy ?? "pairing";
|
||||
const existingAllowFrom = cfg.channels?.whatsapp?.allowFrom ?? [];
|
||||
const existingLabel =
|
||||
existingAllowFrom.length > 0 ? existingAllowFrom.join(", ") : "unset";
|
||||
const existingLabel = existingAllowFrom.length > 0 ? existingAllowFrom.join(", ") : "unset";
|
||||
const existingResponsePrefix = cfg.messages?.responsePrefix;
|
||||
|
||||
if (options?.forceAllowlist) {
|
||||
@@ -96,8 +73,7 @@ async function promptWhatsAppAllowFrom(
|
||||
"WhatsApp number",
|
||||
);
|
||||
const entry = await prompter.text({
|
||||
message:
|
||||
"Your personal WhatsApp number (the phone you will message from)",
|
||||
message: "Your personal WhatsApp number (the phone you will message from)",
|
||||
placeholder: "+15555550123",
|
||||
initialValue: existingAllowFrom[0],
|
||||
validate: (value) => {
|
||||
@@ -164,8 +140,7 @@ async function promptWhatsAppAllowFrom(
|
||||
"WhatsApp number",
|
||||
);
|
||||
const entry = await prompter.text({
|
||||
message:
|
||||
"Your personal WhatsApp number (the phone you will message from)",
|
||||
message: "Your personal WhatsApp number (the phone you will message from)",
|
||||
placeholder: "+15555550123",
|
||||
initialValue: existingAllowFrom[0],
|
||||
validate: (value) => {
|
||||
@@ -274,9 +249,7 @@ async function promptWhatsAppAllowFrom(
|
||||
.split(/[\n,;]+/g)
|
||||
.map((p) => p.trim())
|
||||
.filter(Boolean);
|
||||
const normalized = parts.map((part) =>
|
||||
part === "*" ? "*" : normalizeE164(part),
|
||||
);
|
||||
const normalized = parts.map((part) => (part === "*" ? "*" : normalizeE164(part)));
|
||||
const unique = [...new Set(normalized.filter(Boolean))];
|
||||
next = setWhatsAppAllowFrom(next, unique);
|
||||
}
|
||||
@@ -289,18 +262,13 @@ export const whatsappOnboardingAdapter: ChannelOnboardingAdapter = {
|
||||
getStatus: async ({ cfg, accountOverrides }) => {
|
||||
const overrideId = accountOverrides.whatsapp?.trim();
|
||||
const defaultAccountId = resolveDefaultWhatsAppAccountId(cfg);
|
||||
const accountId = overrideId
|
||||
? normalizeAccountId(overrideId)
|
||||
: defaultAccountId;
|
||||
const accountId = overrideId ? normalizeAccountId(overrideId) : defaultAccountId;
|
||||
const linked = await detectWhatsAppLinked(cfg, accountId);
|
||||
const accountLabel =
|
||||
accountId === DEFAULT_ACCOUNT_ID ? "default" : accountId;
|
||||
const accountLabel = accountId === DEFAULT_ACCOUNT_ID ? "default" : accountId;
|
||||
return {
|
||||
channel,
|
||||
configured: linked,
|
||||
statusLines: [
|
||||
`WhatsApp (${accountLabel}): ${linked ? "linked" : "not linked"}`,
|
||||
],
|
||||
statusLines: [`WhatsApp (${accountLabel}): ${linked ? "linked" : "not linked"}`],
|
||||
selectionHint: linked ? "linked" : "not linked",
|
||||
quickstartScore: linked ? 5 : 4,
|
||||
};
|
||||
@@ -343,9 +311,7 @@ export const whatsappOnboardingAdapter: ChannelOnboardingAdapter = {
|
||||
...next.channels?.whatsapp?.accounts,
|
||||
[accountId]: {
|
||||
...next.channels?.whatsapp?.accounts?.[accountId],
|
||||
enabled:
|
||||
next.channels?.whatsapp?.accounts?.[accountId]?.enabled ??
|
||||
true,
|
||||
enabled: next.channels?.whatsapp?.accounts?.[accountId]?.enabled ?? true,
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -370,9 +336,7 @@ export const whatsappOnboardingAdapter: ChannelOnboardingAdapter = {
|
||||
);
|
||||
}
|
||||
const wantsLink = await prompter.confirm({
|
||||
message: linked
|
||||
? "WhatsApp already linked. Re-link now?"
|
||||
: "Link WhatsApp now (QR)?",
|
||||
message: linked ? "WhatsApp already linked. Re-link now?" : "Link WhatsApp now (QR)?",
|
||||
initialValue: !linked,
|
||||
});
|
||||
if (wantsLink) {
|
||||
@@ -380,16 +344,10 @@ export const whatsappOnboardingAdapter: ChannelOnboardingAdapter = {
|
||||
await loginWeb(false, undefined, runtime, accountId);
|
||||
} catch (err) {
|
||||
runtime.error(`WhatsApp login failed: ${String(err)}`);
|
||||
await prompter.note(
|
||||
`Docs: ${formatDocsLink("/whatsapp", "whatsapp")}`,
|
||||
"WhatsApp help",
|
||||
);
|
||||
await prompter.note(`Docs: ${formatDocsLink("/whatsapp", "whatsapp")}`, "WhatsApp help");
|
||||
}
|
||||
} else if (!linked) {
|
||||
await prompter.note(
|
||||
"Run `clawdbot channels login` later to link WhatsApp.",
|
||||
"WhatsApp",
|
||||
);
|
||||
await prompter.note("Run `clawdbot channels login` later to link WhatsApp.", "WhatsApp");
|
||||
}
|
||||
|
||||
next = await promptWhatsAppAllowFrom(next, runtime, prompter, {
|
||||
|
||||
Reference in New Issue
Block a user