Files
clawdbot/extensions/tlon/src/targets.ts
2026-01-24 00:25:39 +00:00

80 lines
2.3 KiB
TypeScript

export type TlonTarget =
| { kind: "dm"; ship: string }
| { kind: "group"; nest: string; hostShip: string; channelName: string };
const SHIP_RE = /^~?[a-z-]+$/i;
const NEST_RE = /^chat\/([^/]+)\/([^/]+)$/i;
export function normalizeShip(raw: string): string {
const trimmed = raw.trim();
if (!trimmed) return trimmed;
return trimmed.startsWith("~") ? trimmed : `~${trimmed}`;
}
export function parseChannelNest(raw: string): { hostShip: string; channelName: string } | null {
const match = NEST_RE.exec(raw.trim());
if (!match) return null;
const hostShip = normalizeShip(match[1]);
const channelName = match[2];
return { hostShip, channelName };
}
export function parseTlonTarget(raw?: string | null): TlonTarget | null {
const trimmed = raw?.trim();
if (!trimmed) return null;
const withoutPrefix = trimmed.replace(/^tlon:/i, "");
const dmPrefix = withoutPrefix.match(/^dm[/:](.+)$/i);
if (dmPrefix) {
return { kind: "dm", ship: normalizeShip(dmPrefix[1]) };
}
const groupPrefix = withoutPrefix.match(/^(group|room)[/:](.+)$/i);
if (groupPrefix) {
const groupTarget = groupPrefix[2].trim();
if (groupTarget.startsWith("chat/")) {
const parsed = parseChannelNest(groupTarget);
if (!parsed) return null;
return {
kind: "group",
nest: `chat/${parsed.hostShip}/${parsed.channelName}`,
hostShip: parsed.hostShip,
channelName: parsed.channelName,
};
}
const parts = groupTarget.split("/");
if (parts.length === 2) {
const hostShip = normalizeShip(parts[0]);
const channelName = parts[1];
return {
kind: "group",
nest: `chat/${hostShip}/${channelName}`,
hostShip,
channelName,
};
}
return null;
}
if (withoutPrefix.startsWith("chat/")) {
const parsed = parseChannelNest(withoutPrefix);
if (!parsed) return null;
return {
kind: "group",
nest: `chat/${parsed.hostShip}/${parsed.channelName}`,
hostShip: parsed.hostShip,
channelName: parsed.channelName,
};
}
if (SHIP_RE.test(withoutPrefix)) {
return { kind: "dm", ship: normalizeShip(withoutPrefix) };
}
return null;
}
export function formatTargetHint(): string {
return "dm/~sampel-palnet | ~sampel-palnet | chat/~host-ship/channel | group:~host-ship/channel";
}