feat(channels): add credential write and per-account lifecycle control
Add setChannelAccountConfig/removeChannelAccountConfig to CredentialManager for persisting channel tokens. Make ChannelManager.startAccount public and add stopAccount for individual account lifecycle control via IPC. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
6a02fd29be
commit
0542c82fe6
2 changed files with 89 additions and 2 deletions
|
|
@ -330,6 +330,75 @@ export class CredentialManager {
|
|||
this.reset();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a channel account config and save to credentials.json5.
|
||||
* Creates the channels section if it doesn't exist.
|
||||
* Used by the desktop Channels page to persist bot tokens.
|
||||
*/
|
||||
setChannelAccountConfig(channelId: string, accountId: string, accountConfig: Record<string, unknown>): void {
|
||||
const path = getCredentialsPath();
|
||||
|
||||
let config: CredentialsConfig = { version: 1 };
|
||||
if (existsSync(path)) {
|
||||
try {
|
||||
const raw = readFileSync(path, "utf8");
|
||||
config = JSON5.parse(raw) as CredentialsConfig;
|
||||
} catch {
|
||||
config = { version: 1 };
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure channels.[channelId] structure exists
|
||||
if (!config.channels) {
|
||||
config.channels = {};
|
||||
}
|
||||
if (!config.channels[channelId]) {
|
||||
config.channels[channelId] = {};
|
||||
}
|
||||
|
||||
// Set or update the account config
|
||||
config.channels[channelId]![accountId] = accountConfig;
|
||||
|
||||
mkdirSync(dirname(path), { recursive: true });
|
||||
const content = JSON.stringify(config, null, 2);
|
||||
writeFileSync(path, content, "utf8");
|
||||
|
||||
this.reset();
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a channel account config from credentials.json5.
|
||||
* Cleans up the parent channel section if no accounts remain.
|
||||
*/
|
||||
removeChannelAccountConfig(channelId: string, accountId: string): void {
|
||||
const path = getCredentialsPath();
|
||||
if (!existsSync(path)) return;
|
||||
|
||||
let config: CredentialsConfig;
|
||||
try {
|
||||
const raw = readFileSync(path, "utf8");
|
||||
config = JSON5.parse(raw) as CredentialsConfig;
|
||||
} catch {
|
||||
return;
|
||||
}
|
||||
|
||||
const channelSection = config.channels?.[channelId];
|
||||
if (!channelSection) return;
|
||||
|
||||
delete channelSection[accountId];
|
||||
|
||||
// Clean up empty channel section
|
||||
if (Object.keys(channelSection).length === 0) {
|
||||
delete config.channels![channelId];
|
||||
}
|
||||
|
||||
mkdirSync(dirname(path), { recursive: true });
|
||||
const content = JSON.stringify(config, null, 2);
|
||||
writeFileSync(path, content, "utf8");
|
||||
|
||||
this.reset();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the default LLM provider and save to credentials.json5.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -98,8 +98,11 @@ export class ChannelManager {
|
|||
this.ensureSubscribed();
|
||||
}
|
||||
|
||||
/** Start a specific channel account */
|
||||
private async startAccount(
|
||||
/**
|
||||
* Start a specific channel account.
|
||||
* Public so the desktop IPC layer can call it after saving config.
|
||||
*/
|
||||
async startAccount(
|
||||
channelId: string,
|
||||
accountId: string,
|
||||
accountConfig: Record<string, unknown>,
|
||||
|
|
@ -433,6 +436,21 @@ export class ChannelManager {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop a specific channel account.
|
||||
* Public so the desktop IPC layer can call it when removing config.
|
||||
*/
|
||||
stopAccount(channelId: string, accountId: string): void {
|
||||
const key = `${channelId}:${accountId}`;
|
||||
const handle = this.accounts.get(key);
|
||||
if (!handle) return;
|
||||
|
||||
handle.abortController.abort();
|
||||
handle.state = { ...handle.state, status: "stopped" };
|
||||
this.accounts.delete(key);
|
||||
console.log(`[Channels] Stopped ${key}`);
|
||||
}
|
||||
|
||||
/** Stop all running channel accounts */
|
||||
stopAll(): void {
|
||||
console.log("[Channels] Stopping all channels...");
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue