@kya-os/cli
Version:
CLI for MCP-I setup and management
204 lines ⢠8.37 kB
JavaScript
import chalk from "chalk";
import { existsSync, rmSync, mkdirSync, writeFileSync } from "fs";
import { join } from "path";
import inquirer from "inquirer";
import { showSuccess, showError, showInfo } from "../utils/prompts.js";
/**
* Clean identity configuration with optional backup
*/
export async function identityClean(options = {}) {
const { force = false, backup = true } = options;
console.log(chalk.cyan("\nš§¹ Clean Identity Configuration\n"));
const identityDir = join(process.cwd(), ".mcpi");
const identityFile = join(identityDir, "identity.json");
const keysDir = join(identityDir, "keys");
// Check if identity exists
if (!existsSync(identityFile)) {
showInfo("No identity configuration found to clean.");
return;
}
// Show what will be cleaned
console.log(`${chalk.bold("Files to be cleaned:")}`);
if (existsSync(identityFile)) {
console.log(` ${chalk.red("ā")} ${chalk.gray(".mcpi/identity.json")}`);
}
if (existsSync(keysDir)) {
console.log(` ${chalk.red("ā")} ${chalk.gray(".mcpi/keys/ (archived keys)")}`);
}
// Confirmation unless forced
if (!force) {
const { confirmed } = await inquirer.prompt([
{
type: "confirm",
name: "confirmed",
message: "Are you sure you want to clean the identity configuration?",
default: false,
},
]);
if (!confirmed) {
console.log(chalk.yellow("Operation cancelled."));
return;
}
}
try {
// Create backup if requested
if (backup && existsSync(identityFile)) {
const timestamp = new Date().toISOString().replace(/[:.]/g, "-");
const backupDir = join(identityDir, "backups");
const backupFile = join(backupDir, `identity-${timestamp}.json`);
if (!existsSync(backupDir)) {
mkdirSync(backupDir, { recursive: true });
}
// Copy identity file to backup
const identityContent = require("fs").readFileSync(identityFile, "utf-8");
writeFileSync(backupFile, identityContent);
showInfo(`Backup created: ${backupFile}`);
}
// Remove identity file
if (existsSync(identityFile)) {
rmSync(identityFile);
console.log(` ${chalk.green("ā")} Removed identity.json`);
}
// Remove keys directory
if (existsSync(keysDir)) {
rmSync(keysDir, { recursive: true });
console.log(` ${chalk.green("ā")} Removed keys directory`);
}
// Remove receipts directory if it exists and is empty
const receiptsDir = join(identityDir, "receipts");
if (existsSync(receiptsDir)) {
try {
const receipts = require("fs").readdirSync(receiptsDir);
if (receipts.length === 0) {
rmSync(receiptsDir, { recursive: true });
console.log(` ${chalk.green("ā")} Removed empty receipts directory`);
}
else {
showInfo(`Kept receipts directory (${receipts.length} files)`);
}
}
catch (error) {
// Ignore errors reading receipts directory
}
}
// Remove .mcpi directory if it's empty
try {
const remaining = require("fs").readdirSync(identityDir);
if (remaining.length === 0 ||
(remaining.length === 1 && remaining[0] === "backups")) {
// Keep backups directory but remove .mcpi if only backups remain
if (remaining.length === 0) {
rmSync(identityDir, { recursive: true });
console.log(` ${chalk.green("ā")} Removed .mcpi directory`);
}
}
}
catch (error) {
// Ignore errors - directory might not be empty
}
showSuccess("Identity configuration cleaned successfully!");
console.log(`\n${chalk.gray("Next steps:")}`);
console.log(`${chalk.gray("⢠Run")} ${chalk.cyan("mcpi init")} ${chalk.gray("to create a new identity")}`);
console.log(`${chalk.gray("⢠Or restore from backup if needed")}`);
if (backup) {
console.log(`\n${chalk.gray("Backup location:")} ${chalk.cyan(".mcpi/backups/")}`);
}
}
catch (error) {
showError(`Failed to clean identity: ${error.message}`);
console.log(`\n${chalk.gray("You can try:")}`);
console.log(`${chalk.gray("⢠Using --force flag to skip confirmation")}`);
console.log(`${chalk.gray("⢠Manually removing .mcpi/ directory")}`);
console.log(`${chalk.gray("⢠Checking file permissions")}`);
process.exit(1);
}
}
/**
* Restore identity from backup
*/
export async function identityRestore(backupFile) {
console.log(chalk.cyan("\nš Restore Identity Configuration\n"));
const identityDir = join(process.cwd(), ".mcpi");
const backupDir = join(identityDir, "backups");
const identityFile = join(identityDir, "identity.json");
// Check if identity already exists
if (existsSync(identityFile)) {
const { overwrite } = await inquirer.prompt([
{
type: "confirm",
name: "overwrite",
message: "Identity already exists. Overwrite?",
default: false,
},
]);
if (!overwrite) {
console.log(chalk.yellow("Operation cancelled."));
return;
}
}
// List available backups if no specific file provided
if (!backupFile) {
if (!existsSync(backupDir)) {
showError("No backup directory found.");
return;
}
const backups = require("fs")
.readdirSync(backupDir)
.filter((f) => f.startsWith("identity-") && f.endsWith(".json"))
.sort()
.reverse(); // Most recent first
if (backups.length === 0) {
showError("No identity backups found.");
return;
}
const { selectedBackup } = await inquirer.prompt([
{
type: "list",
name: "selectedBackup",
message: "Select backup to restore:",
choices: backups.map((backup) => ({
name: `${backup} (${new Date(backup
.replace("identity-", "")
.replace(".json", "")
.replace(/-/g, ":")).toLocaleString()})`,
value: backup,
})),
},
]);
backupFile = join(backupDir, selectedBackup);
}
try {
// Ensure backup file exists
if (!existsSync(backupFile)) {
showError(`Backup file not found: ${backupFile}`);
return;
}
// Validate backup file
const backupContent = require("fs").readFileSync(backupFile, "utf-8");
const identity = JSON.parse(backupContent);
// Basic validation
if (!identity.did || !identity.kid || !identity.privateKey) {
showError("Invalid backup file format.");
return;
}
// Ensure identity directory exists
if (!existsSync(identityDir)) {
mkdirSync(identityDir, { recursive: true });
}
// Restore identity file
writeFileSync(identityFile, backupContent);
showSuccess("Identity restored successfully!");
console.log(`\n${chalk.bold("Restored Identity:")}`);
console.log(` DID: ${chalk.gray(identity.did)}`);
console.log(` Key ID: ${chalk.gray(identity.kid)}`);
console.log(` Created: ${chalk.gray(identity.createdAt)}`);
console.log(`\n${chalk.gray("You can now:")}`);
console.log(`${chalk.gray("⢠Run")} ${chalk.cyan("mcpi status")} ${chalk.gray("to check agent status")}`);
console.log(`${chalk.gray("⢠Run")} ${chalk.cyan("mcpi dev")} ${chalk.gray("to start development")}`);
}
catch (error) {
showError(`Failed to restore identity: ${error.message}`);
process.exit(1);
}
}
//# sourceMappingURL=identity.js.map