framework
Version:
The (AI) Framework: turnkey, zero-config AI orchestration that wraps a coding-agent CLI (Claude Code) as a black box and takes you from an idea to a running app. Vite for AI.
80 lines • 4.44 kB
TypeScript
import type { RegistrySecrets } from './registry.js';
/**
* Where the daemon's Discord credential — the notifications webhook — comes from (#1095).
*
* It used to be an environment variable and nothing else, which made "enable Discord" the one
* onboarding step you could not finish from the dashboard: you had to edit the daemon's
* environment and restart it. It is now also settable from the UI, stored in the registry file
* beside the daemon token, and picked up without a restart.
*
* The values only ever move daemon-side. This module is the rules — resolution, precedence,
* validation — and holds no credential itself, which is what lets the dashboard share the same
* validation the daemon enforces; reading and writing them is `discord-credentials-store.ts`,
* deliberately a separate file so the home-file edge stays out of the browser bundle.
*
* What the dashboard is told is {@link DiscordCredentialStatus}: which credential exists and where
* it came from, never what it is. That is the presence-only contract `onNotifyChannels` has had
* since #948, kept on purpose — a stored credential is not a credential you can read back.
*/
/** The resolved credentials a daemon runs with. Absent means Discord notifications are off. */
export interface DiscordCredentials {
/** Where notifications are posted (#627). */
webhook?: string;
}
/**
* Which of the two places a credential came from. `env` wins, and the dashboard says so rather
* than offering an edit that would not take effect: an environment variable is how a deployment
* (a container, a systemd unit, a shared box) configures the daemon, and a value typed into a
* browser must not quietly override the machine it is running on.
*/
export type CredentialSource = 'env' | 'stored';
/** Which credentials the daemon holds and where each came from. Presence, never values. */
export interface DiscordCredentialStatus {
webhook?: CredentialSource;
}
/** An edit to the stored credentials: a string sets, `null` clears, absent leaves alone. */
export interface DiscordCredentialsPatch {
webhook?: string | null;
}
/** The outcome of a {@link DiscordCredentialsStore.save}. */
export type SaveCredentialsResult = {
ok: true;
} | {
ok: false;
error: string;
};
/** The env var behind each credential, so the two tables below cannot drift apart. */
export declare const ENV_KEYS: {
readonly webhook: "DISCORD_WEBHOOK";
};
/** The registry key behind each credential. */
export declare const SECRET_KEYS: {
readonly webhook: "discordWebhook";
};
/** The credential names, once, so every loop over them covers both by construction. */
export declare const CREDENTIALS: Array<keyof DiscordCredentials>;
/** The environment variable a credential is read from, for the UI's "set on the daemon" copy. */
export declare function credentialEnvVar(credential: keyof DiscordCredentials): string;
/** The credentials to run with: the environment first, the stored value as the fallback. */
export declare function resolveDiscordCredentials(env: NodeJS.ProcessEnv, secrets: RegistrySecrets): DiscordCredentials;
/** The same resolution, reported as presence + origin. The browser-facing half of the pair above. */
export declare function discordCredentialStatus(env: NodeJS.ProcessEnv, secrets: RegistrySecrets): DiscordCredentialStatus;
/**
* Reject what cannot possibly work, before it is stored and silently does nothing.
*
* Deliberately shallow: a token is only checked for the shape of a token (one opaque word), and a
* webhook for being an http(s) URL rather than for being on discord.com — people front webhooks
* with their own proxies, and the daemon has no business refusing a URL it was told to post to.
* Whether the credential actually authenticates is Discord's answer to give, and the daemon logs it.
*/
export declare function validateCredential(credential: keyof DiscordCredentials, value: string): string | undefined;
/**
* The store the dashboard's context carries (#1095): status out, edits in. The daemon
* wires one; a public host (the relay) leaves it unset, so the RPCs report nothing configured and
* refuse the write, the same way the preferences store degrades.
*/
export interface DiscordCredentialsStore {
status(): Promise<DiscordCredentialStatus>;
save(patch: DiscordCredentialsPatch): Promise<SaveCredentialsResult>;
}
//# sourceMappingURL=discord-credentials.d.ts.map