@capgo/cli
Version:
A CLI to upload to capgo servers
80 lines (79 loc) • 4.21 kB
TypeScript
import { z } from 'zod';
import { loadSavedCredentials, removeSavedCredentialKeys, updateSavedCredentials } from '../../credentials.js';
import { exportCredentialsToEnv } from '../env-export.js';
/** The canonical Capgo credential field names (buildCredentialsSchema). Used only for a gentle typo nudge. */
export declare const KNOWN_CREDENTIAL_KEYS: ReadonlySet<string>;
/**
* Screen a valueFile path BEFORE reading it. The MCP caller (an LLM) supplies this path, so an injected
* prompt could try to read ~/.ssh/id_ed25519 or another app's ~/.capgo-credentials into the store (which
* is then sent to the build server). Allow only credential-file extensions, and never read from a known
* secret directory. Returns an error string to surface to the caller, or null when the path is acceptable.
*/
export declare function screenValueFilePath(filePath: string): string | null;
/**
* Screen an export targetPath: the .env (which holds real secrets) must stay INSIDE the project
* directory so the tool can never be steered into writing to e.g. /etc/cron.d or ~/.bashrc. Returns an
* error string, or null when the path stays in the project.
*/
export declare function screenExportPath(targetPath: string, projectDir: string): string | null;
export interface CredentialsManageInput {
action: 'list' | 'export' | 'set' | 'remove';
platform?: 'ios' | 'android';
key?: string;
value?: string;
/** For set: a path to a credential file whose base64 becomes the value (keystores, .p12, .p8, service-account JSON). */
valueFile?: string;
path?: string;
overwrite?: boolean;
appId?: string;
}
/** Injectable seam — the registration wires the real credential store + env export; tests pass fakes. */
export interface CredentialsManageDeps {
getAppId: () => Promise<string | undefined>;
loadSavedCredentials: (appId: string) => Promise<Awaited<ReturnType<typeof loadSavedCredentials>>>;
updateSavedCredentials: typeof updateSavedCredentials;
removeSavedCredentialKeys: typeof removeSavedCredentialKeys;
exportCredentialsToEnv: typeof exportCredentialsToEnv;
/** Read a file and return its base64 — used by set + valueFile. Must reject symlinks. */
readFileBase64: (path: string) => Promise<string>;
/** True when a project-local .capgo-credentials.json holds this app — so set/remove write there, not global. */
localCredentialsExist: (appId: string) => Promise<boolean>;
}
/** Build the real deps (global credential store) bound to a getAppId resolver. */
export declare function buildCredentialsManageDeps(getAppId: () => Promise<string | undefined>): CredentialsManageDeps;
/**
* Run one credentials-manage action and return human-facing text (the MCP tool wraps it as a text block).
* Returns guidance instead of throwing for every expected "can't do that" case so the assistant can recover.
*/
export declare function runCredentialsManage(input: CredentialsManageInput, deps: CredentialsManageDeps): Promise<string>;
/** zod shape for the tool's arguments. */
export declare const credentialsManageSchema: {
action: z.ZodEnum<{
set: "set";
list: "list";
export: "export";
remove: "remove";
}>;
platform: z.ZodOptional<z.ZodEnum<{
android: "android";
ios: "ios";
}>>;
key: z.ZodOptional<z.ZodString>;
value: z.ZodOptional<z.ZodString>;
valueFile: z.ZodOptional<z.ZodString>;
path: z.ZodOptional<z.ZodString>;
overwrite: z.ZodOptional<z.ZodBoolean>;
appId: z.ZodOptional<z.ZodString>;
};
/** Minimal MCP server surface this registers against (mirrors onboarding-tools' McpLike.tool). */
interface ToolRegistrar {
tool: (name: string, description: string, schema: Record<string, unknown>, handler: (args: CredentialsManageInput) => Promise<{
content: Array<{
type: 'text';
text: string;
}>;
}>) => unknown;
}
/** Register `capgo_builder_credentials_manage` on the given MCP server, bound to a getAppId resolver. */
export declare function registerCredentialsManageTool(server: ToolRegistrar, getAppId: () => Promise<string | undefined>, depsOverride?: CredentialsManageDeps): void;
export {};