@waniwani/cli 0.0.46 → 0.0.47
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +83 -13
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
// src/cli.ts
|
|
4
4
|
import { createRequire } from "module";
|
|
5
|
-
import { Command as
|
|
5
|
+
import { Command as Command26 } from "commander";
|
|
6
6
|
|
|
7
7
|
// src/commands/config/index.ts
|
|
8
8
|
import { Command as Command2 } from "commander";
|
|
@@ -1209,11 +1209,28 @@ var loginCommand = new Command4("login").description("Log in to WaniWani").optio
|
|
|
1209
1209
|
clientId
|
|
1210
1210
|
);
|
|
1211
1211
|
spinner.succeed("Logged in successfully!");
|
|
1212
|
+
let orgName = null;
|
|
1213
|
+
try {
|
|
1214
|
+
const { orgs, activeOrgId } = await api.get("/api/oauth/orgs");
|
|
1215
|
+
if (activeOrgId) {
|
|
1216
|
+
const activeOrg = orgs.find((o) => o.id === activeOrgId);
|
|
1217
|
+
if (activeOrg) {
|
|
1218
|
+
orgName = activeOrg.name;
|
|
1219
|
+
}
|
|
1220
|
+
}
|
|
1221
|
+
} catch {
|
|
1222
|
+
}
|
|
1212
1223
|
if (json) {
|
|
1213
|
-
formatOutput(
|
|
1224
|
+
formatOutput(
|
|
1225
|
+
{ success: true, loggedIn: true, ...orgName && { org: orgName } },
|
|
1226
|
+
true
|
|
1227
|
+
);
|
|
1214
1228
|
} else {
|
|
1215
1229
|
console.log();
|
|
1216
1230
|
formatSuccess("You're now logged in to WaniWani!", false);
|
|
1231
|
+
if (orgName) {
|
|
1232
|
+
console.log(` Organization: ${chalk3.cyan(orgName)}`);
|
|
1233
|
+
}
|
|
1217
1234
|
console.log();
|
|
1218
1235
|
console.log("Get started:");
|
|
1219
1236
|
console.log(
|
|
@@ -2646,17 +2663,70 @@ var useCommand = new Command20("use").description("Select an MCP to use for subs
|
|
|
2646
2663
|
var mcpCommand = new Command21("mcp").description("MCP management commands").addCommand(createCommand).addCommand(cloneCommand).addCommand(listCommand2).addCommand(useCommand).addCommand(statusCommand).addCommand(previewCommand).addCommand(stopCommand).addCommand(logsCommand).addCommand(syncCommand).addCommand(deleteCommand).addCommand(fileCommand).addCommand(runCommandCommand);
|
|
2647
2664
|
|
|
2648
2665
|
// src/commands/org/index.ts
|
|
2649
|
-
import { Command as
|
|
2666
|
+
import { Command as Command25 } from "commander";
|
|
2650
2667
|
|
|
2651
|
-
// src/commands/org/
|
|
2652
|
-
import chalk10 from "chalk";
|
|
2668
|
+
// src/commands/org/current.ts
|
|
2653
2669
|
import { Command as Command22 } from "commander";
|
|
2654
2670
|
import ora16 from "ora";
|
|
2655
|
-
var
|
|
2671
|
+
var currentCommand = new Command22("current").description("Show the current active organization").action(async (_options, command) => {
|
|
2656
2672
|
const globalOptions = command.optsWithGlobals();
|
|
2657
2673
|
const json = globalOptions.json ?? false;
|
|
2658
2674
|
try {
|
|
2659
|
-
const spinner = ora16("Fetching
|
|
2675
|
+
const spinner = ora16("Fetching current organization...").start();
|
|
2676
|
+
const result = await api.get("/api/oauth/orgs");
|
|
2677
|
+
spinner.stop();
|
|
2678
|
+
const { orgs, activeOrgId } = result;
|
|
2679
|
+
if (!activeOrgId) {
|
|
2680
|
+
if (json) {
|
|
2681
|
+
formatOutput({ org: null }, true);
|
|
2682
|
+
} else {
|
|
2683
|
+
console.log("No active organization.");
|
|
2684
|
+
console.log(
|
|
2685
|
+
"\nSwitch to an organization: waniwani org switch <name>"
|
|
2686
|
+
);
|
|
2687
|
+
}
|
|
2688
|
+
return;
|
|
2689
|
+
}
|
|
2690
|
+
const activeOrg = orgs.find((o) => o.id === activeOrgId);
|
|
2691
|
+
if (!activeOrg) {
|
|
2692
|
+
if (json) {
|
|
2693
|
+
formatOutput({ org: null }, true);
|
|
2694
|
+
} else {
|
|
2695
|
+
console.log("Active organization not found.");
|
|
2696
|
+
console.log(
|
|
2697
|
+
"\nSwitch to an organization: waniwani org switch <name>"
|
|
2698
|
+
);
|
|
2699
|
+
}
|
|
2700
|
+
return;
|
|
2701
|
+
}
|
|
2702
|
+
if (json) {
|
|
2703
|
+
formatOutput({ org: activeOrg }, true);
|
|
2704
|
+
} else {
|
|
2705
|
+
console.log();
|
|
2706
|
+
formatList(
|
|
2707
|
+
[
|
|
2708
|
+
{ label: "Name", value: activeOrg.name },
|
|
2709
|
+
{ label: "Slug", value: activeOrg.slug },
|
|
2710
|
+
{ label: "Role", value: activeOrg.role }
|
|
2711
|
+
],
|
|
2712
|
+
false
|
|
2713
|
+
);
|
|
2714
|
+
}
|
|
2715
|
+
} catch (error) {
|
|
2716
|
+
handleError(error, json);
|
|
2717
|
+
process.exit(1);
|
|
2718
|
+
}
|
|
2719
|
+
});
|
|
2720
|
+
|
|
2721
|
+
// src/commands/org/list.ts
|
|
2722
|
+
import chalk10 from "chalk";
|
|
2723
|
+
import { Command as Command23 } from "commander";
|
|
2724
|
+
import ora17 from "ora";
|
|
2725
|
+
var listCommand3 = new Command23("list").description("List your organizations").action(async (_options, command) => {
|
|
2726
|
+
const globalOptions = command.optsWithGlobals();
|
|
2727
|
+
const json = globalOptions.json ?? false;
|
|
2728
|
+
try {
|
|
2729
|
+
const spinner = ora17("Fetching organizations...").start();
|
|
2660
2730
|
const result = await api.get("/api/oauth/orgs");
|
|
2661
2731
|
spinner.stop();
|
|
2662
2732
|
const { orgs, activeOrgId } = result;
|
|
@@ -2702,13 +2772,13 @@ var listCommand3 = new Command22("list").description("List your organizations").
|
|
|
2702
2772
|
});
|
|
2703
2773
|
|
|
2704
2774
|
// src/commands/org/switch.ts
|
|
2705
|
-
import { Command as
|
|
2706
|
-
import
|
|
2707
|
-
var switchCommand = new
|
|
2775
|
+
import { Command as Command24 } from "commander";
|
|
2776
|
+
import ora18 from "ora";
|
|
2777
|
+
var switchCommand = new Command24("switch").description("Switch to a different organization").argument("<name>", "Name or slug of the organization to switch to").action(async (name, _options, command) => {
|
|
2708
2778
|
const globalOptions = command.optsWithGlobals();
|
|
2709
2779
|
const json = globalOptions.json ?? false;
|
|
2710
2780
|
try {
|
|
2711
|
-
const spinner =
|
|
2781
|
+
const spinner = ora18("Fetching organizations...").start();
|
|
2712
2782
|
const { orgs } = await api.get("/api/oauth/orgs");
|
|
2713
2783
|
const org = orgs.find((o) => o.name === name || o.slug === name);
|
|
2714
2784
|
if (!org) {
|
|
@@ -2741,12 +2811,12 @@ var switchCommand = new Command23("switch").description("Switch to a different o
|
|
|
2741
2811
|
});
|
|
2742
2812
|
|
|
2743
2813
|
// src/commands/org/index.ts
|
|
2744
|
-
var orgCommand = new
|
|
2814
|
+
var orgCommand = new Command25("org").description("Organization management commands").addCommand(currentCommand).addCommand(listCommand3).addCommand(switchCommand);
|
|
2745
2815
|
|
|
2746
2816
|
// src/cli.ts
|
|
2747
2817
|
var require2 = createRequire(import.meta.url);
|
|
2748
2818
|
var { version } = require2("../package.json");
|
|
2749
|
-
var program = new
|
|
2819
|
+
var program = new Command26().name("waniwani").description("WaniWani CLI for MCP development workflow").version(version).option("--json", "Output results as JSON").option("--verbose", "Enable verbose logging");
|
|
2750
2820
|
program.addCommand(loginCommand);
|
|
2751
2821
|
program.addCommand(logoutCommand);
|
|
2752
2822
|
program.addCommand(mcpCommand);
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cli.ts","../src/commands/config/index.ts","../src/commands/config/init.ts","../src/lib/config.ts","../src/lib/errors.ts","../src/lib/output.ts","../src/commands/git-credential-helper.ts","../src/lib/git-auth.ts","../src/lib/auth.ts","../src/lib/api.ts","../src/lib/sync.ts","../src/lib/utils.ts","../src/commands/login.ts","../src/commands/logout.ts","../src/commands/mcp/index.ts","../src/commands/mcp/clone.ts","../src/lib/credential-helper-setup.ts","../src/commands/mcp/create.ts","../src/commands/mcp/delete.ts","../src/commands/mcp/file/index.ts","../src/commands/mcp/file/list.ts","../src/commands/mcp/file/read.ts","../src/commands/mcp/file/write.ts","../src/commands/mcp/list.ts","../src/commands/mcp/logs.ts","../src/commands/mcp/preview.ts","../src/lib/async.ts","../src/commands/mcp/run-command.ts","../src/commands/mcp/status.ts","../src/commands/mcp/stop.ts","../src/commands/mcp/sync.ts","../src/commands/mcp/use.ts","../src/commands/org/index.ts","../src/commands/org/list.ts","../src/commands/org/switch.ts","../src/index.ts"],"sourcesContent":["import { createRequire } from \"node:module\";\nimport { Command } from \"commander\";\nimport { configCommand } from \"./commands/config/index.js\";\nimport { gitCredentialHelperCommand } from \"./commands/git-credential-helper.js\";\nimport { loginCommand } from \"./commands/login.js\";\nimport { logoutCommand } from \"./commands/logout.js\";\nimport { mcpCommand } from \"./commands/mcp/index.js\";\nimport { orgCommand } from \"./commands/org/index.js\";\n\nconst require = createRequire(import.meta.url);\nconst { version } = require(\"../package.json\") as { version: string };\n\nexport const program = new Command()\n\t.name(\"waniwani\")\n\t.description(\"WaniWani CLI for MCP development workflow\")\n\t.version(version)\n\t.option(\"--json\", \"Output results as JSON\")\n\t.option(\"--verbose\", \"Enable verbose logging\");\n\n// Auth commands\nprogram.addCommand(loginCommand);\nprogram.addCommand(logoutCommand);\n\n// Main commands\nprogram.addCommand(mcpCommand);\nprogram.addCommand(orgCommand);\nprogram.addCommand(configCommand);\n\n// Git integration (called by git, not users)\nprogram.addCommand(gitCredentialHelperCommand);\n","import { Command } from \"commander\";\nimport { configInitCommand } from \"./init.js\";\n\nexport const configCommand = new Command(\"config\")\n\t.description(\"Manage WaniWani configuration\")\n\t.addCommand(configInitCommand);\n","import { existsSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { Command } from \"commander\";\nimport {\n\tCONFIG_FILE_NAME,\n\tinitConfigAt,\n\tLOCAL_CONFIG_DIR,\n} from \"../../lib/config.js\";\nimport { CLIError, handleError } from \"../../lib/errors.js\";\nimport { formatOutput, formatSuccess } from \"../../lib/output.js\";\n\nexport const configInitCommand = new Command(\"init\")\n\t.description(\"Initialize .waniwani config in the current directory\")\n\t.option(\"--force\", \"Overwrite existing config\")\n\t.action(async (options, command) => {\n\t\tconst globalOptions = command.optsWithGlobals();\n\t\tconst json = globalOptions.json ?? false;\n\n\t\ttry {\n\t\t\tconst cwd = process.cwd();\n\t\t\tconst configPath = join(cwd, LOCAL_CONFIG_DIR, CONFIG_FILE_NAME);\n\n\t\t\t// Check if config already exists\n\t\t\tif (existsSync(configPath) && !options.force) {\n\t\t\t\tthrow new CLIError(\n\t\t\t\t\t`Config already exists at ${configPath}. Use --force to overwrite.`,\n\t\t\t\t\t\"CONFIG_EXISTS\",\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// Create .waniwani/settings.json with defaults\n\t\t\tconst result = await initConfigAt(cwd);\n\n\t\t\tif (json) {\n\t\t\t\tformatOutput({ created: result.path, config: result.config }, true);\n\t\t\t} else {\n\t\t\t\tformatSuccess(`Created ${result.path}`, false);\n\t\t\t}\n\t\t} catch (error) {\n\t\t\thandleError(error, json);\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n","import { existsSync } from \"node:fs\";\nimport { chmod, mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { z } from \"zod\";\n\nexport const LOCAL_CONFIG_DIR = \".waniwani\";\nexport const CONFIG_FILE_NAME = \"settings.json\";\n\nconst LOCAL_DIR = join(process.cwd(), LOCAL_CONFIG_DIR);\nconst LOCAL_FILE = join(LOCAL_DIR, CONFIG_FILE_NAME);\nconst DEFAULT_API_URL = \"https://app.waniwani.ai\";\nconst CONFIG_DIR_MODE = 0o700;\nconst CONFIG_FILE_MODE = 0o600;\n\nconst ConfigSchema = z.object({\n\t// Settings\n\tsessionId: z.string().nullable().default(null),\n\tmcpId: z.string().nullable().default(null),\n\tapiUrl: z.string().default(DEFAULT_API_URL),\n\t// Auth (merged from auth.json)\n\taccessToken: z.string().nullable().default(null),\n\trefreshToken: z.string().nullable().default(null),\n\texpiresAt: z.string().nullable().default(null),\n\tclientId: z.string().nullable().default(null),\n});\n\ntype ConfigData = z.infer<typeof ConfigSchema>;\n\nclass Config {\n\tprivate dir: string;\n\tprivate file: string;\n\tprivate cache: ConfigData | null = null;\n\n\tconstructor() {\n\t\tthis.dir = LOCAL_DIR;\n\t\tthis.file = LOCAL_FILE;\n\t}\n\n\tprivate async setSecurePermissions(): Promise<void> {\n\t\tawait chmod(this.dir, CONFIG_DIR_MODE);\n\t\tawait chmod(this.file, CONFIG_FILE_MODE);\n\t}\n\n\tprivate async load(): Promise<ConfigData> {\n\t\tif (!this.cache) {\n\t\t\ttry {\n\t\t\t\tthis.cache = ConfigSchema.parse(\n\t\t\t\t\tJSON.parse(await readFile(this.file, \"utf-8\")),\n\t\t\t\t);\n\t\t\t} catch {\n\t\t\t\tthis.cache = ConfigSchema.parse({});\n\t\t\t}\n\t\t}\n\t\treturn this.cache;\n\t}\n\n\tprivate async save(data: ConfigData): Promise<void> {\n\t\tthis.cache = data;\n\t\tawait mkdir(this.dir, { recursive: true, mode: CONFIG_DIR_MODE });\n\t\tawait writeFile(this.file, JSON.stringify(data, null, \"\\t\"));\n\t\tawait this.setSecurePermissions();\n\t}\n\n\t/**\n\t * Ensure the .waniwani directory exists in cwd.\n\t * Used by login to create config before saving tokens.\n\t */\n\tasync ensureConfigDir(): Promise<void> {\n\t\tawait mkdir(this.dir, { recursive: true, mode: CONFIG_DIR_MODE });\n\t\tawait chmod(this.dir, CONFIG_DIR_MODE);\n\t}\n\n\t/**\n\t * Check if a .waniwani config directory exists in cwd.\n\t */\n\thasConfig(): boolean {\n\t\treturn existsSync(this.dir);\n\t}\n\n\t// --- Settings methods ---\n\n\tasync getMcpId() {\n\t\treturn (await this.load()).mcpId;\n\t}\n\n\tasync setMcpId(id: string | null) {\n\t\tconst data = await this.load();\n\t\tdata.mcpId = id;\n\t\tawait this.save(data);\n\t}\n\n\tasync getSessionId() {\n\t\treturn (await this.load()).sessionId;\n\t}\n\n\tasync setSessionId(id: string | null) {\n\t\tconst data = await this.load();\n\t\tdata.sessionId = id;\n\t\tawait this.save(data);\n\t}\n\n\tasync getApiUrl() {\n\t\tif (process.env.WANIWANI_API_URL) return process.env.WANIWANI_API_URL;\n\t\treturn (await this.load()).apiUrl;\n\t}\n\n\tasync clear() {\n\t\tawait this.save(ConfigSchema.parse({}));\n\t}\n\n\t// --- Auth methods ---\n\n\tasync getAccessToken(): Promise<string | null> {\n\t\treturn (await this.load()).accessToken;\n\t}\n\n\tasync getRefreshToken(): Promise<string | null> {\n\t\treturn (await this.load()).refreshToken;\n\t}\n\n\tasync getClientId(): Promise<string | null> {\n\t\treturn (await this.load()).clientId;\n\t}\n\n\tasync setTokens(\n\t\taccessToken: string,\n\t\trefreshToken: string,\n\t\texpiresIn: number,\n\t\tclientId?: string,\n\t): Promise<void> {\n\t\tconst expiresAt = new Date(Date.now() + expiresIn * 1000).toISOString();\n\t\tconst data = await this.load();\n\t\tdata.accessToken = accessToken;\n\t\tdata.refreshToken = refreshToken;\n\t\tdata.expiresAt = expiresAt;\n\t\tif (clientId) {\n\t\t\tdata.clientId = clientId;\n\t\t}\n\t\tawait this.save(data);\n\t}\n\n\tasync clearAuth(): Promise<void> {\n\t\tconst data = await this.load();\n\t\tdata.accessToken = null;\n\t\tdata.refreshToken = null;\n\t\tdata.expiresAt = null;\n\t\tdata.clientId = null;\n\t\tawait this.save(data);\n\t}\n\n\tasync isTokenExpired(): Promise<boolean> {\n\t\tconst data = await this.load();\n\t\tif (!data.expiresAt) return true;\n\t\t// Consider expired 5 minutes before actual expiry\n\t\treturn new Date(data.expiresAt).getTime() - 5 * 60 * 1000 < Date.now();\n\t}\n}\n\nexport const config = new Config();\n\n/**\n * Initialize a .waniwani/settings.json at the given directory.\n * Returns the created config data and path.\n */\nexport async function initConfigAt(\n\tdir: string,\n\toverrides: Partial<ConfigData> = {},\n): Promise<{ path: string; config: ConfigData }> {\n\tconst configDir = join(dir, LOCAL_CONFIG_DIR);\n\tconst configPath = join(configDir, CONFIG_FILE_NAME);\n\n\tawait mkdir(configDir, { recursive: true, mode: CONFIG_DIR_MODE });\n\n\tconst data = ConfigSchema.parse(overrides);\n\tawait writeFile(configPath, JSON.stringify(data, null, \"\\t\"), \"utf-8\");\n\tawait chmod(configDir, CONFIG_DIR_MODE);\n\tawait chmod(configPath, CONFIG_FILE_MODE);\n\n\treturn { path: configPath, config: data };\n}\n","import chalk from \"chalk\";\nimport { ZodError } from \"zod\";\n\nexport class CLIError extends Error {\n\tconstructor(\n\t\tmessage: string,\n\t\tpublic code: string,\n\t\tpublic details?: Record<string, unknown>,\n\t) {\n\t\tsuper(message);\n\t\tthis.name = \"CLIError\";\n\t}\n}\n\nexport class ConfigError extends CLIError {\n\tconstructor(message: string, details?: Record<string, unknown>) {\n\t\tsuper(message, \"CONFIG_ERROR\", details);\n\t}\n}\n\nexport class AuthError extends CLIError {\n\tconstructor(message: string, details?: Record<string, unknown>) {\n\t\tsuper(message, \"AUTH_ERROR\", details);\n\t}\n}\n\nexport class SandboxError extends CLIError {\n\tconstructor(message: string, details?: Record<string, unknown>) {\n\t\tsuper(message, \"SANDBOX_ERROR\", details);\n\t}\n}\n\nexport class GitHubError extends CLIError {\n\tconstructor(message: string, details?: Record<string, unknown>) {\n\t\tsuper(message, \"GITHUB_ERROR\", details);\n\t}\n}\n\nexport class McpError extends CLIError {\n\tconstructor(message: string, details?: Record<string, unknown>) {\n\t\tsuper(message, \"MCP_ERROR\", details);\n\t}\n}\n\nexport function handleError(error: unknown, json: boolean): void {\n\tif (error instanceof ZodError) {\n\t\tconst message = error.issues\n\t\t\t.map((e) => `${e.path.join(\".\")}: ${e.message}`)\n\t\t\t.join(\", \");\n\t\toutputError(\"VALIDATION_ERROR\", `Invalid input: ${message}`, json);\n\t} else if (error instanceof CLIError) {\n\t\toutputError(error.code, error.message, json, error.details);\n\t} else if (error instanceof Error) {\n\t\toutputError(\"UNKNOWN_ERROR\", error.message, json);\n\t} else {\n\t\toutputError(\"UNKNOWN_ERROR\", String(error), json);\n\t}\n}\n\nfunction outputError(\n\tcode: string,\n\tmessage: string,\n\tjson: boolean,\n\tdetails?: Record<string, unknown>,\n): void {\n\tif (json) {\n\t\tconsole.error(\n\t\t\tJSON.stringify({ success: false, error: { code, message, details } }),\n\t\t);\n\t} else {\n\t\tconsole.error(chalk.red(`Error [${code}]:`), message);\n\t\tif (details) {\n\t\t\tconsole.error(chalk.gray(\"Details:\"), JSON.stringify(details, null, 2));\n\t\t}\n\t}\n}\n","import chalk from \"chalk\";\n\nexport function formatOutput<T>(data: T, json: boolean): void {\n\tif (json) {\n\t\tconsole.log(JSON.stringify({ success: true, data }, null, 2));\n\t} else {\n\t\tprettyPrint(data);\n\t}\n}\n\nexport function formatSuccess(message: string, json: boolean): void {\n\tif (json) {\n\t\tconsole.log(JSON.stringify({ success: true, message }));\n\t} else {\n\t\tconsole.log(chalk.green(\"✓\"), message);\n\t}\n}\n\nexport function formatError(error: Error | string, json: boolean): void {\n\tconst message = error instanceof Error ? error.message : error;\n\tif (json) {\n\t\tconsole.error(JSON.stringify({ success: false, error: message }));\n\t} else {\n\t\tconsole.error(chalk.red(\"✗\"), message);\n\t}\n}\n\nexport function formatTable(\n\theaders: string[],\n\trows: string[][],\n\tjson: boolean,\n): void {\n\tif (json) {\n\t\tconst data = rows.map((row) =>\n\t\t\tObject.fromEntries(headers.map((header, i) => [header, row[i]])),\n\t\t);\n\t\tconsole.log(JSON.stringify({ success: true, data }, null, 2));\n\t} else {\n\t\t// Simple table formatting without external dependency\n\t\tconst colWidths = headers.map((h, i) =>\n\t\t\tMath.max(h.length, ...rows.map((r) => (r[i] || \"\").length)),\n\t\t);\n\n\t\tconst separator = colWidths.map((w) => \"-\".repeat(w + 2)).join(\"+\");\n\t\tconst formatRow = (row: string[]) =>\n\t\t\trow.map((cell, i) => ` ${(cell || \"\").padEnd(colWidths[i])} `).join(\"|\");\n\n\t\tconsole.log(chalk.cyan(formatRow(headers)));\n\t\tconsole.log(separator);\n\t\tfor (const row of rows) {\n\t\t\tconsole.log(formatRow(row));\n\t\t}\n\t}\n}\n\nexport function formatList(\n\titems: Array<{ label: string; value: string }>,\n\tjson: boolean,\n): void {\n\tif (json) {\n\t\tconst data = Object.fromEntries(\n\t\t\titems.map((item) => [item.label, item.value]),\n\t\t);\n\t\tconsole.log(JSON.stringify({ success: true, data }, null, 2));\n\t} else {\n\t\tconst maxLabelLength = Math.max(...items.map((i) => i.label.length));\n\t\titems.forEach((item) => {\n\t\t\tconsole.log(\n\t\t\t\t`${chalk.gray(item.label.padEnd(maxLabelLength))} ${chalk.white(item.value)}`,\n\t\t\t);\n\t\t});\n\t}\n}\n\nfunction prettyPrint(data: unknown, indent = 0): void {\n\tconst prefix = \" \".repeat(indent);\n\n\tif (Array.isArray(data)) {\n\t\tdata.forEach((item, index) => {\n\t\t\tconsole.log(`${prefix}${chalk.gray(`[${index}]`)}`);\n\t\t\tprettyPrint(item, indent + 1);\n\t\t});\n\t} else if (typeof data === \"object\" && data !== null) {\n\t\tfor (const [key, value] of Object.entries(data)) {\n\t\t\tif (typeof value === \"object\" && value !== null) {\n\t\t\t\tconsole.log(`${prefix}${chalk.gray(key)}:`);\n\t\t\t\tprettyPrint(value, indent + 1);\n\t\t\t} else {\n\t\t\t\tconsole.log(\n\t\t\t\t\t`${prefix}${chalk.gray(key)}: ${chalk.white(String(value))}`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t} else {\n\t\tconsole.log(`${prefix}${chalk.white(String(data))}`);\n\t}\n}\n","import { readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { Command } from \"commander\";\nimport { CONFIG_FILE_NAME, LOCAL_CONFIG_DIR } from \"../lib/config.js\";\nimport { getGitAuthContext } from \"../lib/git-auth.js\";\nimport { findProjectRoot } from \"../lib/sync.js\";\n\n/**\n * Parse git credential helper input from stdin.\n * Format: key=value lines, terminated by an empty line.\n */\nfunction parseCredentialInput(input: string): Record<string, string> {\n\tconst fields: Record<string, string> = {};\n\tfor (const line of input.split(\"\\n\")) {\n\t\tconst trimmed = line.trim();\n\t\tif (!trimmed) continue;\n\t\tconst eqIdx = trimmed.indexOf(\"=\");\n\t\tif (eqIdx > 0) {\n\t\t\tfields[trimmed.slice(0, eqIdx)] = trimmed.slice(eqIdx + 1);\n\t\t}\n\t}\n\treturn fields;\n}\n\nexport const gitCredentialHelperCommand = new Command(\"git-credential-helper\")\n\t.description(\"Git credential helper (used by git, not called directly)\")\n\t.argument(\"<operation>\", \"get, store, or erase\")\n\t.action(async (operation: string) => {\n\t\t// Only handle \"get\" — \"store\" and \"erase\" are no-ops\n\t\tif (operation !== \"get\") {\n\t\t\tprocess.exit(0);\n\t\t}\n\n\t\ttry {\n\t\t\t// Read credential request from stdin\n\t\t\tconst input = readFileSync(0, \"utf-8\");\n\t\t\tconst fields = parseCredentialInput(input);\n\n\t\t\t// Only handle HTTPS\n\t\t\tif (fields.protocol && fields.protocol !== \"https\") {\n\t\t\t\tprocess.exit(0);\n\t\t\t}\n\n\t\t\t// Find project root\n\t\t\tconst projectRoot = await findProjectRoot(process.cwd());\n\t\t\tif (!projectRoot) {\n\t\t\t\tprocess.stderr.write(\n\t\t\t\t\t\"waniwani: not in a WaniWani project (no .waniwani/ found)\\n\",\n\t\t\t\t);\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\n\t\t\t// Read mcpId directly from config file\n\t\t\tconst configPath = join(projectRoot, LOCAL_CONFIG_DIR, CONFIG_FILE_NAME);\n\t\t\tconst configData = JSON.parse(readFileSync(configPath, \"utf-8\"));\n\t\t\tconst mcpId = configData.mcpId;\n\n\t\t\tif (!mcpId) {\n\t\t\t\tprocess.stderr.write(\"waniwani: no mcpId in config\\n\");\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\n\t\t\t// Get ephemeral credentials\n\t\t\tconst gitAuth = await getGitAuthContext(mcpId);\n\n\t\t\tif (!gitAuth.credentials) {\n\t\t\t\tprocess.stderr.write(\"waniwani: no credentials returned from API\\n\");\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\n\t\t\t// Output in git credential helper format\n\t\t\tprocess.stdout.write(\n\t\t\t\t`username=${gitAuth.credentials.username}\\npassword=${gitAuth.credentials.password}\\n`,\n\t\t\t);\n\t\t} catch (error) {\n\t\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\t\tprocess.stderr.write(`waniwani credential helper error: ${message}\\n`);\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n","import { execFileSync, type StdioOptions } from \"node:child_process\";\nimport { chmodSync, mkdtempSync, rmSync, writeFileSync } from \"node:fs\";\nimport { tmpdir } from \"node:os\";\nimport { join } from \"node:path\";\nimport type { CloneUrlResponse, GitAuthResponse } from \"../types/index.js\";\nimport { ApiError, api } from \"./api.js\";\n\nexport interface GitHttpCredentials {\n\tusername: string;\n\tpassword: string;\n}\n\nexport interface GitAuthContext {\n\tcloneUrl: string;\n\tremoteUrl: string;\n\tcredentials: GitHttpCredentials | null;\n\tgithubApiBaseUrl: string | null;\n}\n\n/**\n * Convert a remote URL to GitHub API base URL (cloud or GHES).\n */\nfunction getGitHubApiBaseUrl(remoteUrl: string): string | null {\n\ttry {\n\t\tconst parsed = new URL(remoteUrl);\n\t\treturn parsed.hostname === \"github.com\" ||\n\t\t\tparsed.hostname === \"www.github.com\"\n\t\t\t? \"https://api.github.com\"\n\t\t\t: `${parsed.protocol}//${parsed.host}/api/v3`;\n\t} catch {\n\t\treturn null;\n\t}\n}\n\n/**\n * Parse clone-url endpoint response and split credentialed clone URLs into:\n * - remoteUrl: safe URL without embedded credentials\n * - credentials: username/password for transient auth\n */\nfunction parseCloneUrlAuth(cloneUrl: string): GitAuthContext {\n\ttry {\n\t\tconst parsed = new URL(cloneUrl);\n\t\tconst username = decodeURIComponent(parsed.username);\n\t\tconst password = decodeURIComponent(parsed.password);\n\n\t\tif (username && password) {\n\t\t\tparsed.username = \"\";\n\t\t\tparsed.password = \"\";\n\t\t\tconst remoteUrl = parsed.toString();\n\n\t\t\treturn {\n\t\t\t\tcloneUrl,\n\t\t\t\tremoteUrl,\n\t\t\t\tcredentials: { username, password },\n\t\t\t\tgithubApiBaseUrl: getGitHubApiBaseUrl(remoteUrl),\n\t\t\t};\n\t\t}\n\t} catch {\n\t\t// If cloneUrl is not parseable as URL (unlikely), use it as-is.\n\t}\n\n\treturn {\n\t\tcloneUrl,\n\t\tremoteUrl: cloneUrl,\n\t\tcredentials: null,\n\t\tgithubApiBaseUrl: null,\n\t};\n}\n\n/**\n * Fetch git auth context from backend. Prefers structured /git-auth endpoint,\n * falls back to /clone-url for backward compatibility with older backends.\n */\nexport async function getGitAuthContext(\n\tmcpId: string,\n): Promise<GitAuthContext> {\n\ttry {\n\t\tconst gitAuth = await api.get<GitAuthResponse>(\n\t\t\t`/api/mcp/repositories/${mcpId}/git-auth`,\n\t\t);\n\t\tconst parsedRemote = new URL(gitAuth.remoteUrl);\n\t\tparsedRemote.username = gitAuth.username;\n\t\tparsedRemote.password = gitAuth.token;\n\t\tconst cloneUrl = parsedRemote.toString();\n\n\t\treturn {\n\t\t\tcloneUrl,\n\t\t\tremoteUrl: gitAuth.remoteUrl,\n\t\t\tcredentials: {\n\t\t\t\tusername: gitAuth.username,\n\t\t\t\tpassword: gitAuth.token,\n\t\t\t},\n\t\t\tgithubApiBaseUrl: getGitHubApiBaseUrl(gitAuth.remoteUrl),\n\t\t};\n\t} catch (error) {\n\t\t// If the new endpoint isn't available yet, use legacy clone-url.\n\t\tif (error instanceof ApiError && error.statusCode !== 404) {\n\t\t\tthrow error;\n\t\t}\n\n\t\tconst { cloneUrl } = await api.get<CloneUrlResponse>(\n\t\t\t`/api/mcp/repositories/${mcpId}/clone-url`,\n\t\t);\n\t\treturn parseCloneUrlAuth(cloneUrl);\n\t}\n}\n\n/**\n * Run a git command with ephemeral credentials via GIT_ASKPASS.\n * Credentials are only exposed in process env for this single command.\n */\nexport function runGitWithCredentials(\n\targs: string[],\n\toptions?: {\n\t\tcwd?: string;\n\t\tstdio?: StdioOptions;\n\t\tcredentials?: GitHttpCredentials | null;\n\t},\n): void {\n\tconst { cwd, stdio = \"ignore\", credentials = null } = options ?? {};\n\n\tif (!credentials) {\n\t\texecFileSync(\"git\", args, { cwd, stdio });\n\t\treturn;\n\t}\n\n\tconst dir = mkdtempSync(join(tmpdir(), \"waniwani-askpass-\"));\n\tconst askpassPath = join(dir, \"askpass.sh\");\n\n\ttry {\n\t\twriteFileSync(\n\t\t\taskpassPath,\n\t\t\t`#!/bin/sh\ncase \"$1\" in\n *sername*) printf '%s\\\\n' \"$WANIWANI_GIT_USERNAME\" ;;\n *assword*) printf '%s\\\\n' \"$WANIWANI_GIT_PASSWORD\" ;;\n *) printf '\\\\n' ;;\nesac\n`,\n\t\t\t\"utf-8\",\n\t\t);\n\t\tchmodSync(askpassPath, 0o700);\n\n\t\texecFileSync(\"git\", [\"-c\", \"credential.helper=\", ...args], {\n\t\t\tcwd,\n\t\t\tstdio,\n\t\t\tenv: {\n\t\t\t\t...process.env,\n\t\t\t\tGIT_ASKPASS: askpassPath,\n\t\t\t\tGIT_TERMINAL_PROMPT: \"0\",\n\t\t\t\tWANIWANI_GIT_USERNAME: credentials.username,\n\t\t\t\tWANIWANI_GIT_PASSWORD: credentials.password,\n\t\t\t},\n\t\t});\n\t} finally {\n\t\trmSync(dir, { recursive: true, force: true });\n\t}\n}\n\n/**\n * Best-effort revocation for GitHub App installation tokens.\n * If the token type/host doesn't support this endpoint, this is a no-op.\n */\nconst REVOKE_TIMEOUT_MS = 5_000;\n\nexport async function revokeGitHubInstallationToken(\n\tauth: GitAuthContext,\n): Promise<void> {\n\tif (!auth.credentials?.password || !auth.githubApiBaseUrl) return;\n\n\tconst controller = new AbortController();\n\tconst timeout = setTimeout(() => controller.abort(), REVOKE_TIMEOUT_MS);\n\ttry {\n\t\tawait fetch(`${auth.githubApiBaseUrl}/installation/token`, {\n\t\t\tmethod: \"DELETE\",\n\t\t\theaders: {\n\t\t\t\tAccept: \"application/vnd.github+json\",\n\t\t\t\tAuthorization: `Bearer ${auth.credentials.password}`,\n\t\t\t\t\"X-GitHub-Api-Version\": \"2022-11-28\",\n\t\t\t},\n\t\t\tsignal: controller.signal,\n\t\t});\n\t} catch {\n\t\t// Best-effort only; token still naturally expires.\n\t} finally {\n\t\tclearTimeout(timeout);\n\t}\n}\n","import { config } from \"./config.js\";\n\n/**\n * AuthManager delegates all storage to the config module.\n * Auth tokens are stored in .waniwani/settings.json alongside other config.\n */\nclass AuthManager {\n\tasync isLoggedIn(): Promise<boolean> {\n\t\tconst token = await config.getAccessToken();\n\t\treturn !!token;\n\t}\n\n\tasync getAccessToken(): Promise<string | null> {\n\t\treturn config.getAccessToken();\n\t}\n\n\tasync getRefreshToken(): Promise<string | null> {\n\t\treturn config.getRefreshToken();\n\t}\n\n\tasync setTokens(\n\t\taccessToken: string,\n\t\trefreshToken: string,\n\t\texpiresIn: number,\n\t\tclientId?: string,\n\t): Promise<void> {\n\t\treturn config.setTokens(accessToken, refreshToken, expiresIn, clientId);\n\t}\n\n\tasync clear(): Promise<void> {\n\t\treturn config.clearAuth();\n\t}\n\n\tasync isTokenExpired(): Promise<boolean> {\n\t\treturn config.isTokenExpired();\n\t}\n\n\tasync tryRefreshToken(): Promise<boolean> {\n\t\tconst refreshToken = await config.getRefreshToken();\n\t\tconst clientId = await config.getClientId();\n\t\tif (!refreshToken || !clientId) return false;\n\n\t\ttry {\n\t\t\tconst apiUrl = await config.getApiUrl();\n\t\t\tconst response = await fetch(`${apiUrl}/api/auth/oauth2/token`, {\n\t\t\t\tmethod: \"POST\",\n\t\t\t\theaders: { \"Content-Type\": \"application/x-www-form-urlencoded\" },\n\t\t\t\tbody: new URLSearchParams({\n\t\t\t\t\tgrant_type: \"refresh_token\",\n\t\t\t\t\trefresh_token: refreshToken,\n\t\t\t\t\tclient_id: clientId,\n\t\t\t\t}).toString(),\n\t\t\t});\n\n\t\t\tif (!response.ok) {\n\t\t\t\tawait this.clear();\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tconst data = (await response.json()) as {\n\t\t\t\taccess_token: string;\n\t\t\t\trefresh_token: string;\n\t\t\t\texpires_in: number;\n\t\t\t};\n\n\t\t\tawait this.setTokens(\n\t\t\t\tdata.access_token,\n\t\t\t\tdata.refresh_token,\n\t\t\t\tdata.expires_in,\n\t\t\t);\n\n\t\t\treturn true;\n\t\t} catch {\n\t\t\tawait this.clear();\n\t\t\treturn false;\n\t\t}\n\t}\n}\n\nexport const auth = new AuthManager();\n","import { auth } from \"./auth.js\";\nimport { config } from \"./config.js\";\nimport { AuthError, CLIError } from \"./errors.js\";\n\nexport interface ApiResponse<T> {\n\tsuccess: boolean;\n\tdata?: T;\n\terror?:\n\t\t| string\n\t\t| {\n\t\t\t\tcode?: string;\n\t\t\t\tmessage?: string;\n\t\t\t\tdetails?: Record<string, unknown>;\n\t\t };\n\tcode?: string;\n\tmessage?: string;\n}\n\nexport class ApiError extends CLIError {\n\tconstructor(\n\t\tmessage: string,\n\t\tcode: string,\n\t\tpublic statusCode: number,\n\t\tdetails?: Record<string, unknown>,\n\t) {\n\t\tsuper(message, code, details);\n\t\tthis.name = \"ApiError\";\n\t}\n}\n\nasync function request<T>(\n\tmethod: string,\n\tpath: string,\n\toptions?: {\n\t\tbody?: unknown;\n\t\trequireAuth?: boolean;\n\t\theaders?: Record<string, string>;\n\t},\n): Promise<T> {\n\tconst {\n\t\tbody,\n\t\trequireAuth = true,\n\t\theaders: extraHeaders = {},\n\t} = options || {};\n\n\tconst headers: Record<string, string> = {\n\t\t\"Content-Type\": \"application/json\",\n\t\t...extraHeaders,\n\t};\n\n\tif (requireAuth) {\n\t\tconst token = await auth.getAccessToken();\n\t\tif (!token) {\n\t\t\tthrow new AuthError(\n\t\t\t\t\"Not logged in. Run 'waniwani login' to authenticate.\",\n\t\t\t);\n\t\t}\n\t\theaders.Authorization = `Bearer ${token}`;\n\t}\n\n\tconst baseUrl = await config.getApiUrl();\n\tconst url = `${baseUrl}${path}`;\n\n\tconst response = await fetch(url, {\n\t\tmethod,\n\t\theaders,\n\t\tbody: body ? JSON.stringify(body) : undefined,\n\t});\n\n\t// Handle empty responses (204 No Content)\n\tif (response.status === 204) {\n\t\treturn undefined as T;\n\t}\n\n\tlet data: ApiResponse<T>;\n\tlet rawBody: string | undefined;\n\n\ttry {\n\t\trawBody = await response.text();\n\t\tdata = JSON.parse(rawBody) as ApiResponse<T>;\n\t} catch {\n\t\t// JSON parsing failed - use raw body as error message\n\t\tthrow new ApiError(\n\t\t\trawBody || `Request failed with status ${response.status}`,\n\t\t\t\"API_ERROR\",\n\t\t\tresponse.status,\n\t\t\t{ statusText: response.statusText },\n\t\t);\n\t}\n\n\tif (!response.ok || data.error) {\n\t\tconst errorObject =\n\t\t\ttypeof data.error === \"object\" && data.error !== null\n\t\t\t\t? data.error\n\t\t\t\t: undefined;\n\t\tconst errorString = typeof data.error === \"string\" ? data.error : undefined;\n\n\t\t// Try to extract error message from various possible response formats\n\t\tconst errorMessage =\n\t\t\terrorObject?.message ||\n\t\t\tdata.message ||\n\t\t\terrorString ||\n\t\t\trawBody ||\n\t\t\t`Request failed with status ${response.status}`;\n\n\t\tconst errorCode =\n\t\t\terrorString ||\n\t\t\terrorObject?.code ||\n\t\t\tdata.code ||\n\t\t\tdata.message ||\n\t\t\terrorObject?.message ||\n\t\t\t\"API_ERROR\";\n\n\t\tconst errorDetails = {\n\t\t\t...errorObject?.details,\n\t\t\tstatusText: response.statusText,\n\t\t\t...(errorObject ? {} : { rawResponse: data }),\n\t\t};\n\n\t\tconst error = {\n\t\t\tcode: errorCode,\n\t\t\tmessage: errorMessage,\n\t\t\tdetails: errorDetails,\n\t\t};\n\n\t\t// Handle token expiration\n\t\tif (response.status === 401) {\n\t\t\tconst refreshed = await auth.tryRefreshToken();\n\t\t\tif (refreshed) {\n\t\t\t\t// Retry with new token\n\t\t\t\treturn request<T>(method, path, options);\n\t\t\t}\n\t\t\tthrow new AuthError(\n\t\t\t\t\"Session expired. Run 'waniwani login' to re-authenticate.\",\n\t\t\t);\n\t\t}\n\n\t\tthrow new ApiError(\n\t\t\terror.message,\n\t\t\terror.code,\n\t\t\tresponse.status,\n\t\t\terror.details,\n\t\t);\n\t}\n\n\treturn data.data as T;\n}\n\nexport const api = {\n\tget: <T>(path: string, options?: { requireAuth?: boolean }) =>\n\t\trequest<T>(\"GET\", path, options),\n\n\tpost: <T>(\n\t\tpath: string,\n\t\tbody?: unknown,\n\t\toptions?: { requireAuth?: boolean; headers?: Record<string, string> },\n\t) => request<T>(\"POST\", path, { body, ...options }),\n\n\tdelete: <T>(path: string, options?: { requireAuth?: boolean }) =>\n\t\trequest<T>(\"DELETE\", path, options),\n\n\tgetBaseUrl: () => config.getApiUrl(),\n};\n","import { existsSync } from \"node:fs\";\nimport { mkdir, readdir, readFile, stat, writeFile } from \"node:fs/promises\";\nimport { dirname, join, relative } from \"node:path\";\nimport ignore from \"ignore\";\nimport type { PullFilesResponse } from \"../types/index.js\";\nimport { api } from \"./api.js\";\nimport { detectBinary, isBinaryPath } from \"./utils.js\";\n\nconst PROJECT_DIR = \".waniwani\";\n\n/**\n * Find the project root by walking up from the given directory\n * looking for a .waniwani directory\n */\nexport async function findProjectRoot(\n\tstartDir: string,\n): Promise<string | null> {\n\tlet current = startDir;\n\tconst root = dirname(current);\n\n\twhile (current !== root) {\n\t\tif (existsSync(join(current, PROJECT_DIR))) {\n\t\t\treturn current;\n\t\t}\n\t\tconst parent = dirname(current);\n\t\tif (parent === current) break;\n\t\tcurrent = parent;\n\t}\n\n\t// Check root as well\n\tif (existsSync(join(current, PROJECT_DIR))) {\n\t\treturn current;\n\t}\n\n\treturn null;\n}\n\n/**\n * Default patterns to always ignore\n */\nconst DEFAULT_IGNORE_PATTERNS = [\n\t\".waniwani\",\n\t\".git\",\n\t\"node_modules\",\n\t\".DS_Store\",\n\t\"*.log\",\n\t\".cache\",\n\t\"dist\",\n\t\"coverage\",\n\t\".turbo\",\n\t\".next\",\n\t\".nuxt\",\n\t\".vercel\",\n];\n\nconst DEFAULT_ENV_IGNORE_PATTERNS = [\".env\", \".env.*\"];\n\nexport interface SyncIgnoreOptions {\n\tincludeEnvFiles?: boolean;\n}\n\n/**\n * Load ignore patterns from .gitignore and add defaults\n */\nexport async function loadIgnorePatterns(\n\tprojectRoot: string,\n\toptions: SyncIgnoreOptions = {},\n): Promise<ReturnType<typeof ignore>> {\n\tconst { includeEnvFiles = false } = options;\n\tconst ig = ignore();\n\n\t// Add default patterns\n\tig.add(DEFAULT_IGNORE_PATTERNS);\n\tif (!includeEnvFiles) {\n\t\tig.add(DEFAULT_ENV_IGNORE_PATTERNS);\n\t}\n\n\t// Load .gitignore if it exists\n\tconst gitignorePath = join(projectRoot, \".gitignore\");\n\tif (existsSync(gitignorePath)) {\n\t\ttry {\n\t\t\tconst content = await readFile(gitignorePath, \"utf-8\");\n\t\t\tig.add(content);\n\t\t} catch {\n\t\t\t// Ignore read errors\n\t\t}\n\t}\n\n\t// For local preview hydration, include env files even if they're gitignored.\n\tif (includeEnvFiles) {\n\t\tig.add([\"!.env\", \"!.env.*\"]);\n\t}\n\n\treturn ig;\n}\n\nexport interface FileToSync {\n\tpath: string;\n\tcontent: string;\n\tencoding: \"utf8\" | \"base64\";\n}\n\n/**\n * Collect all files in a directory that should be synced\n * Respects .gitignore and default ignore patterns\n */\nexport async function collectFiles(\n\tprojectRoot: string,\n\toptions: SyncIgnoreOptions = {},\n): Promise<FileToSync[]> {\n\tconst ig = await loadIgnorePatterns(projectRoot, options);\n\tconst files: FileToSync[] = [];\n\n\tasync function walk(dir: string) {\n\t\tconst entries = await readdir(dir, { withFileTypes: true });\n\n\t\tfor (const entry of entries) {\n\t\t\tconst fullPath = join(dir, entry.name);\n\t\t\tconst relativePath = relative(projectRoot, fullPath);\n\n\t\t\t// Check if path is ignored\n\t\t\tif (ig.ignores(relativePath)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (entry.isDirectory()) {\n\t\t\t\tawait walk(fullPath);\n\t\t\t} else if (entry.isFile()) {\n\t\t\t\ttry {\n\t\t\t\t\tconst content = await readFile(fullPath);\n\t\t\t\t\tconst isBinary = isBinaryPath(fullPath) || detectBinary(content);\n\n\t\t\t\t\tfiles.push({\n\t\t\t\t\t\tpath: relativePath,\n\t\t\t\t\t\tcontent: isBinary\n\t\t\t\t\t\t\t? content.toString(\"base64\")\n\t\t\t\t\t\t\t: content.toString(\"utf8\"),\n\t\t\t\t\t\tencoding: isBinary ? \"base64\" : \"utf8\",\n\t\t\t\t\t});\n\t\t\t\t} catch {\n\t\t\t\t\t// Skip files that can't be read\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tawait walk(projectRoot);\n\treturn files;\n}\n\n/**\n * Pull all files from GitHub to a local directory.\n * Uses a single API call to fetch all files from the repository.\n */\nexport async function pullFilesFromGithub(\n\tmcpId: string,\n\ttargetDir: string,\n): Promise<{ count: number; files: string[] }> {\n\t// Fetch all files from GitHub in one request\n\tconst result = await api.get<PullFilesResponse>(\n\t\t`/api/mcp/repositories/${mcpId}/files`,\n\t);\n\n\tconst writtenFiles: string[] = [];\n\n\tfor (const file of result.files) {\n\t\tconst localPath = join(targetDir, file.path);\n\t\tconst dir = dirname(localPath);\n\n\t\t// Ensure directory exists\n\t\tawait mkdir(dir, { recursive: true });\n\n\t\t// Write file content\n\t\tif (file.encoding === \"base64\") {\n\t\t\tawait writeFile(localPath, Buffer.from(file.content, \"base64\"));\n\t\t} else {\n\t\t\tawait writeFile(localPath, file.content, \"utf8\");\n\t\t}\n\n\t\twrittenFiles.push(file.path);\n\t}\n\n\treturn { count: writtenFiles.length, files: writtenFiles };\n}\n\n/**\n * Collect a single file for syncing\n */\nexport async function collectSingleFile(\n\tprojectRoot: string,\n\tfilePath: string,\n): Promise<FileToSync | null> {\n\tconst fullPath = join(projectRoot, filePath);\n\tconst relativePath = relative(projectRoot, fullPath);\n\n\t// Check if file exists\n\tif (!existsSync(fullPath)) {\n\t\treturn null;\n\t}\n\n\ttry {\n\t\tconst fileStat = await stat(fullPath);\n\t\tif (!fileStat.isFile()) {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst content = await readFile(fullPath);\n\t\tconst isBinary = isBinaryPath(fullPath) || detectBinary(content);\n\n\t\treturn {\n\t\t\tpath: relativePath,\n\t\t\tcontent: isBinary ? content.toString(\"base64\") : content.toString(\"utf8\"),\n\t\t\tencoding: isBinary ? \"base64\" : \"utf8\",\n\t\t};\n\t} catch {\n\t\treturn null;\n\t}\n}\n","import { config } from \"./config.js\";\nimport { McpError } from \"./errors.js\";\n\n/**\n * Requires an MCP ID, falling back to the active MCP from config.\n * Throws McpError if no MCP is available.\n */\nexport async function requireMcpId(mcpId?: string): Promise<string> {\n\tif (mcpId) return mcpId;\n\n\tconst configMcpId = await config.getMcpId();\n\tif (!configMcpId) {\n\t\tthrow new McpError(\n\t\t\t\"No active MCP. Run 'waniwani mcp create <name>' or 'waniwani mcp use <name>'.\",\n\t\t);\n\t}\n\treturn configMcpId;\n}\n\n/**\n * Get the active session ID from config.\n * Throws McpError if no session ID is stored.\n */\nexport async function requireSessionId(): Promise<string> {\n\tconst sessionId = await config.getSessionId();\n\n\tif (!sessionId) {\n\t\tthrow new McpError(\n\t\t\t\"No active session. Run 'waniwani mcp preview' to start development.\",\n\t\t);\n\t}\n\n\treturn sessionId;\n}\n\n/**\n * Binary file extensions that should be base64 encoded\n */\nconst BINARY_EXTENSIONS = new Set([\n\t\".png\",\n\t\".jpg\",\n\t\".jpeg\",\n\t\".gif\",\n\t\".ico\",\n\t\".webp\",\n\t\".svg\",\n\t\".woff\",\n\t\".woff2\",\n\t\".ttf\",\n\t\".eot\",\n\t\".otf\",\n\t\".zip\",\n\t\".tar\",\n\t\".gz\",\n\t\".pdf\",\n\t\".exe\",\n\t\".dll\",\n\t\".so\",\n\t\".dylib\",\n\t\".bin\",\n\t\".mp3\",\n\t\".mp4\",\n\t\".wav\",\n\t\".ogg\",\n\t\".webm\",\n]);\n\n/**\n * Check if a file path is likely a binary file based on extension\n */\nexport function isBinaryPath(filePath: string): boolean {\n\tconst ext = filePath.slice(filePath.lastIndexOf(\".\")).toLowerCase();\n\treturn BINARY_EXTENSIONS.has(ext);\n}\n\n/**\n * Detect if a buffer contains binary data by checking for null bytes\n */\nexport function detectBinary(buffer: Buffer): boolean {\n\t// Check first 8KB for null bytes\n\tconst sample = buffer.subarray(0, 8192);\n\treturn sample.includes(0);\n}\n","import { spawn } from \"node:child_process\";\nimport { createServer, type Server } from \"node:http\";\nimport type { Socket } from \"node:net\";\nimport chalk from \"chalk\";\nimport { Command } from \"commander\";\nimport ora from \"ora\";\nimport { auth } from \"../lib/auth.js\";\nimport { config } from \"../lib/config.js\";\nimport { CLIError, handleError } from \"../lib/errors.js\";\nimport { formatOutput, formatSuccess } from \"../lib/output.js\";\nimport type {\n\tOAuthClientRegistrationResponse,\n\tOAuthTokenResponse,\n} from \"../types/index.js\";\n\n// ASCII art logo for WaniWani\nconst LOGO_LINES = [\n\t\"██╗ ██╗ █████╗ ███╗ ██╗ ██╗ ██╗ ██╗ █████╗ ███╗ ██╗ ██╗\",\n\t\"██║ ██║██╔══██╗████╗ ██║ ██║ ██║ ██║██╔══██╗████╗ ██║ ██║\",\n\t\"██║ █╗ ██║███████║██╔██╗ ██║ ██║ ██║ █╗ ██║███████║██╔██╗ ██║ ██║\",\n\t\"██║███╗██║██╔══██║██║╚██╗██║ ██║ ██║███╗██║██╔══██║██║╚██╗██║ ██║\",\n\t\"╚███╔███╔╝██║ ██║██║ ╚████║ ██║ ╚███╔███╔╝██║ ██║██║ ╚████║ ██║\",\n\t\" ╚══╝╚══╝ ╚═╝ ╚═╝╚═╝ ╚═══╝ ╚═╝ ╚══╝╚══╝ ╚═╝ ╚═╝╚═╝ ╚═══╝ ╚═╝\",\n];\n\n// 256-color gradient - warm tones inspired by WaniWani brand\nconst LOGO_COLORS = [\n\t\"\\x1b[38;5;223m\", // light peach\n\t\"\\x1b[38;5;216m\", // peach\n\t\"\\x1b[38;5;209m\", // salmon\n\t\"\\x1b[38;5;203m\", // coral\n\t\"\\x1b[38;5;167m\", // warm red\n\t\"\\x1b[38;5;131m\", // deep terracotta\n];\n\nconst RESET = \"\\x1b[0m\";\n\nfunction showLogo(): void {\n\tconsole.log();\n\tfor (let i = 0; i < LOGO_LINES.length; i++) {\n\t\tconsole.log(`${LOGO_COLORS[i]}${LOGO_LINES[i]}${RESET}`);\n\t}\n\tconsole.log();\n}\n\nconst CALLBACK_PORT = 54321;\nconst CALLBACK_URL = `http://localhost:${CALLBACK_PORT}/callback`;\nconst CLIENT_NAME = \"waniwani-cli\";\n\nfunction generateCodeVerifier(): string {\n\tconst array = new Uint8Array(32);\n\tcrypto.getRandomValues(array);\n\treturn btoa(String.fromCharCode(...array))\n\t\t.replace(/\\+/g, \"-\")\n\t\t.replace(/\\//g, \"_\")\n\t\t.replace(/=+$/, \"\");\n}\n\nasync function generateCodeChallenge(verifier: string): Promise<string> {\n\tconst encoder = new TextEncoder();\n\tconst data = encoder.encode(verifier);\n\tconst hash = await crypto.subtle.digest(\"SHA-256\", data);\n\treturn btoa(String.fromCharCode(...new Uint8Array(hash)))\n\t\t.replace(/\\+/g, \"-\")\n\t\t.replace(/\\//g, \"_\")\n\t\t.replace(/=+$/, \"\");\n}\n\nfunction generateState(): string {\n\tconst array = new Uint8Array(16);\n\tcrypto.getRandomValues(array);\n\treturn Array.from(array, (b) => b.toString(16).padStart(2, \"0\")).join(\"\");\n}\n\nasync function registerClient(): Promise<OAuthClientRegistrationResponse> {\n\tconst apiUrl = await config.getApiUrl();\n\tconst response = await fetch(`${apiUrl}/api/auth/oauth2/register`, {\n\t\tmethod: \"POST\",\n\t\theaders: {\n\t\t\t\"Content-Type\": \"application/json\",\n\t\t},\n\t\tbody: JSON.stringify({\n\t\t\tclient_name: CLIENT_NAME,\n\t\t\tredirect_uris: [CALLBACK_URL],\n\t\t\tgrant_types: [\"authorization_code\", \"refresh_token\"],\n\t\t\tresponse_types: [\"code\"],\n\t\t\ttoken_endpoint_auth_method: \"none\",\n\t\t}),\n\t});\n\n\tif (!response.ok) {\n\t\tconst error = await response.json().catch(() => ({}));\n\t\tthrow new CLIError(\n\t\t\t(error as { error_description?: string }).error_description ||\n\t\t\t\t\"Failed to register OAuth client\",\n\t\t\t\"CLIENT_REGISTRATION_FAILED\",\n\t\t);\n\t}\n\n\treturn response.json() as Promise<OAuthClientRegistrationResponse>;\n}\n\nasync function openBrowser(url: string): Promise<void> {\n\tconst [cmd, ...args] =\n\t\tprocess.platform === \"darwin\"\n\t\t\t? [\"open\", url]\n\t\t\t: process.platform === \"win32\"\n\t\t\t\t? [\"cmd\", \"/c\", \"start\", url]\n\t\t\t\t: [\"xdg-open\", url];\n\n\tspawn(cmd, args, { stdio: \"ignore\", detached: true }).unref();\n}\n\nasync function waitForCallback(\n\texpectedState: string,\n\ttimeoutMs: number = 300000,\n): Promise<string> {\n\treturn new Promise((resolve, reject) => {\n\t\tlet server: Server | null = null;\n\t\tconst sockets = new Set<Socket>();\n\n\t\tconst timeout = setTimeout(() => {\n\t\t\tcleanup();\n\t\t\treject(new CLIError(\"Login timed out\", \"LOGIN_TIMEOUT\"));\n\t\t}, timeoutMs);\n\n\t\tconst cleanup = () => {\n\t\t\tclearTimeout(timeout);\n\t\t\t// Destroy all active connections to allow process to exit\n\t\t\tfor (const socket of sockets) {\n\t\t\t\tsocket.destroy();\n\t\t\t}\n\t\t\tsockets.clear();\n\t\t\tserver?.close();\n\t\t};\n\n\t\tconst htmlResponse = (title: string, message: string, isSuccess: boolean) =>\n\t\t\t`<!DOCTYPE html>\n<html>\n<head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <title>${title} - WaniWani</title>\n <style>\n * { margin: 0; padding: 0; box-sizing: border-box; }\n body {\n font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n min-height: 100vh;\n display: flex;\n align-items: center;\n justify-content: center;\n background: #fafafa;\n position: relative;\n overflow: hidden;\n }\n .blob {\n position: absolute;\n border-radius: 50%;\n filter: blur(60px);\n pointer-events: none;\n }\n .blob-1 {\n top: 0;\n left: 25%;\n width: 24rem;\n height: 24rem;\n background: linear-gradient(to bottom right, rgba(253, 224, 71, 0.3), rgba(251, 146, 60, 0.3));\n }\n .blob-2 {\n bottom: 0;\n right: 25%;\n width: 24rem;\n height: 24rem;\n background: linear-gradient(to bottom right, rgba(134, 239, 172, 0.3), rgba(52, 211, 153, 0.3));\n }\n .blob-3 {\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n width: 40rem;\n height: 40rem;\n background: linear-gradient(to bottom right, rgba(255, 237, 213, 0.2), rgba(254, 249, 195, 0.2));\n }\n .container {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 2rem;\n padding: 2rem;\n z-index: 10;\n text-align: center;\n }\n .logo {\n font-size: 1.75rem;\n font-weight: 700;\n color: #1e293b;\n letter-spacing: -0.025em;\n }\n .icon-circle {\n width: 80px;\n height: 80px;\n border-radius: 50%;\n display: flex;\n align-items: center;\n justify-content: center;\n background: ${isSuccess ? \"rgba(52, 211, 153, 0.15)\" : \"rgba(239, 68, 68, 0.15)\"};\n }\n .icon {\n width: 40px;\n height: 40px;\n color: ${isSuccess ? \"#10b981\" : \"#ef4444\"};\n }\n h1 {\n font-size: 2rem;\n font-weight: 700;\n color: #1e293b;\n }\n p {\n font-size: 1.125rem;\n color: #64748b;\n max-width: 400px;\n }\n </style>\n</head>\n<body>\n <div class=\"blob blob-1\"></div>\n <div class=\"blob blob-2\"></div>\n <div class=\"blob blob-3\"></div>\n <div class=\"container\">\n <span class=\"logo\">WaniWani</span>\n <div class=\"icon-circle\">\n ${\n\t\t\t\tisSuccess\n\t\t\t\t\t? '<svg class=\"icon\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M20 6 9 17l-5-5\"></path></svg>'\n\t\t\t\t\t: '<svg class=\"icon\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M18 6 6 18\"></path><path d=\"m6 6 12 12\"></path></svg>'\n\t\t\t}\n </div>\n <h1>${title}</h1>\n <p>${message}</p>\n </div>\n</body>\n</html>`;\n\n\t\ttry {\n\t\t\tserver = createServer((req, res) => {\n\t\t\t\tconst url = new URL(\n\t\t\t\t\treq.url || \"/\",\n\t\t\t\t\t`http://localhost:${CALLBACK_PORT}`,\n\t\t\t\t);\n\n\t\t\t\tif (url.pathname === \"/callback\") {\n\t\t\t\t\tconst code = url.searchParams.get(\"code\");\n\t\t\t\t\tconst state = url.searchParams.get(\"state\");\n\t\t\t\t\tconst error = url.searchParams.get(\"error\");\n\n\t\t\t\t\tres.setHeader(\"Content-Type\", \"text/html\");\n\n\t\t\t\t\tif (error) {\n\t\t\t\t\t\tres.statusCode = 400;\n\t\t\t\t\t\tres.end(htmlResponse(\"Login Failed\", `Error: ${error}`, false));\n\t\t\t\t\t\tcleanup();\n\t\t\t\t\t\treject(new CLIError(`OAuth error: ${error}`, \"OAUTH_ERROR\"));\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (state !== expectedState) {\n\t\t\t\t\t\tres.statusCode = 400;\n\t\t\t\t\t\tres.end(\n\t\t\t\t\t\t\thtmlResponse(\n\t\t\t\t\t\t\t\t\"Login Failed\",\n\t\t\t\t\t\t\t\t\"Invalid state parameter. Please try again.\",\n\t\t\t\t\t\t\t\tfalse,\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t);\n\t\t\t\t\t\tcleanup();\n\t\t\t\t\t\treject(new CLIError(\"Invalid state parameter\", \"INVALID_STATE\"));\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (!code) {\n\t\t\t\t\t\tres.statusCode = 400;\n\t\t\t\t\t\tres.end(\n\t\t\t\t\t\t\thtmlResponse(\n\t\t\t\t\t\t\t\t\"Login Failed\",\n\t\t\t\t\t\t\t\t\"No authorization code received.\",\n\t\t\t\t\t\t\t\tfalse,\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t);\n\t\t\t\t\t\tcleanup();\n\t\t\t\t\t\treject(new CLIError(\"No authorization code\", \"NO_CODE\"));\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tres.statusCode = 200;\n\t\t\t\t\tres.end(\n\t\t\t\t\t\thtmlResponse(\n\t\t\t\t\t\t\t\"Login Successful!\",\n\t\t\t\t\t\t\t\"You can close this window and return to the terminal.\",\n\t\t\t\t\t\t\ttrue,\n\t\t\t\t\t\t),\n\t\t\t\t\t);\n\n\t\t\t\t\t// Schedule cleanup after response is sent\n\t\t\t\t\tsetTimeout(() => {\n\t\t\t\t\t\tcleanup();\n\t\t\t\t\t\tresolve(code);\n\t\t\t\t\t}, 100);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tres.statusCode = 404;\n\t\t\t\tres.end(\"Not found\");\n\t\t\t});\n\n\t\t\t// Track connections so we can force-close them\n\t\t\tserver.on(\"connection\", (socket) => {\n\t\t\t\tsockets.add(socket);\n\t\t\t\tsocket.on(\"close\", () => sockets.delete(socket));\n\t\t\t});\n\n\t\t\tserver.on(\"error\", (err: NodeJS.ErrnoException) => {\n\t\t\t\tcleanup();\n\t\t\t\tif (err.code === \"EADDRINUSE\") {\n\t\t\t\t\treject(\n\t\t\t\t\t\tnew CLIError(\n\t\t\t\t\t\t\t`Port ${CALLBACK_PORT} is already in use. Close any other WaniWani CLI instances and try again.`,\n\t\t\t\t\t\t\t\"PORT_IN_USE\",\n\t\t\t\t\t\t),\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\treject(err);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tserver.listen(CALLBACK_PORT);\n\t\t} catch (err: unknown) {\n\t\t\tcleanup();\n\t\t\treject(err);\n\t\t}\n\t});\n}\n\nasync function exchangeCodeForToken(\n\tcode: string,\n\tcodeVerifier: string,\n\tclientId: string,\n\tresource: string,\n): Promise<OAuthTokenResponse> {\n\tconst apiUrl = await config.getApiUrl();\n\tconst response = await fetch(`${apiUrl}/api/auth/oauth2/token`, {\n\t\tmethod: \"POST\",\n\t\theaders: {\n\t\t\t\"Content-Type\": \"application/x-www-form-urlencoded\",\n\t\t},\n\t\tbody: new URLSearchParams({\n\t\t\tgrant_type: \"authorization_code\",\n\t\t\tcode,\n\t\t\tredirect_uri: CALLBACK_URL,\n\t\t\tclient_id: clientId,\n\t\t\tcode_verifier: codeVerifier,\n\t\t\tresource, // RFC 8707 - required to get JWT token\n\t\t}).toString(),\n\t});\n\n\tif (!response.ok) {\n\t\tconst error = await response.json().catch(() => ({}));\n\t\tthrow new CLIError(\n\t\t\t(error as { error_description?: string }).error_description ||\n\t\t\t\t\"Failed to exchange code for token\",\n\t\t\t\"TOKEN_EXCHANGE_FAILED\",\n\t\t);\n\t}\n\n\treturn response.json() as Promise<OAuthTokenResponse>;\n}\n\nexport const loginCommand = new Command(\"login\")\n\t.description(\"Log in to WaniWani\")\n\t.option(\"--no-browser\", \"Don't open the browser automatically\")\n\t.action(async (options, command) => {\n\t\tconst globalOptions = command.optsWithGlobals();\n\t\tconst json = globalOptions.json ?? false;\n\n\t\ttry {\n\t\t\t// Check if already logged in with a valid session\n\t\t\tif (await auth.isLoggedIn()) {\n\t\t\t\t// Check if token is expired\n\t\t\t\tif (await auth.isTokenExpired()) {\n\t\t\t\t\t// Try to refresh the token\n\t\t\t\t\tconst refreshed = await auth.tryRefreshToken();\n\t\t\t\t\tif (refreshed) {\n\t\t\t\t\t\tif (json) {\n\t\t\t\t\t\t\tformatOutput({ alreadyLoggedIn: true, refreshed: true }, true);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tconsole.log(\n\t\t\t\t\t\t\t\tchalk.green(\"Session refreshed. You're still logged in.\"),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\t// Refresh failed, clear and proceed with login\n\t\t\t\t\tif (!json) {\n\t\t\t\t\t\tconsole.log(\n\t\t\t\t\t\t\tchalk.yellow(\"Session expired. Starting new login flow...\"),\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\tawait auth.clear();\n\t\t\t\t} else {\n\t\t\t\t\t// Token is valid\n\t\t\t\t\tif (json) {\n\t\t\t\t\t\tformatOutput({ alreadyLoggedIn: true }, true);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tconsole.log(\n\t\t\t\t\t\t\tchalk.yellow(\n\t\t\t\t\t\t\t\t\"Already logged in. Use 'waniwani logout' to log out first.\",\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (!json) {\n\t\t\t\tshowLogo();\n\t\t\t}\n\n\t\t\tconst spinner = ora(\"Registering client...\").start();\n\n\t\t\t// Register OAuth client dynamically\n\t\t\tconst { client_id: clientId } = await registerClient();\n\n\t\t\tspinner.text = \"Preparing authentication...\";\n\n\t\t\t// Generate PKCE values\n\t\t\tconst codeVerifier = generateCodeVerifier();\n\t\t\tconst codeChallenge = await generateCodeChallenge(codeVerifier);\n\t\t\tconst state = generateState();\n\n\t\t\t// Build authorization URL\n\t\t\tconst apiUrl = await config.getApiUrl();\n\t\t\tconst authUrl = new URL(`${apiUrl}/api/auth/oauth2/authorize`);\n\t\t\tauthUrl.searchParams.set(\"client_id\", clientId);\n\t\t\tauthUrl.searchParams.set(\"redirect_uri\", CALLBACK_URL);\n\t\t\tauthUrl.searchParams.set(\"response_type\", \"code\");\n\t\t\tauthUrl.searchParams.set(\"code_challenge\", codeChallenge);\n\t\t\tauthUrl.searchParams.set(\"code_challenge_method\", \"S256\");\n\t\t\tauthUrl.searchParams.set(\"state\", state);\n\t\t\tauthUrl.searchParams.set(\"resource\", apiUrl); // RFC 8707 - request JWT token\n\n\t\t\tspinner.stop();\n\n\t\t\tif (!json) {\n\t\t\t\tconsole.log(\"Opening browser for authentication...\\n\");\n\t\t\t\tconsole.log(`If the browser doesn't open, visit:\\n`);\n\t\t\t\tconsole.log(chalk.cyan(` ${authUrl.toString()}`));\n\t\t\t\tconsole.log();\n\t\t\t}\n\n\t\t\t// Start callback server and open browser\n\t\t\tconst callbackPromise = waitForCallback(state);\n\n\t\t\tif (options.browser !== false) {\n\t\t\t\tawait openBrowser(authUrl.toString());\n\t\t\t}\n\n\t\t\tspinner.start(\"Waiting for authorization...\");\n\n\t\t\t// Wait for callback with auth code\n\t\t\tconst code = await callbackPromise;\n\n\t\t\tspinner.text = \"Exchanging code for token...\";\n\n\t\t\t// Exchange code for token\n\t\t\tconst tokenResponse = await exchangeCodeForToken(\n\t\t\t\tcode,\n\t\t\t\tcodeVerifier,\n\t\t\t\tclientId,\n\t\t\t\tapiUrl, // RFC 8707 resource parameter\n\t\t\t);\n\n\t\t\t// Ensure .waniwani/ exists in cwd before storing tokens\n\t\t\tawait config.ensureConfigDir();\n\n\t\t\t// Store tokens and client ID for refresh\n\t\t\tawait auth.setTokens(\n\t\t\t\ttokenResponse.access_token,\n\t\t\t\ttokenResponse.refresh_token,\n\t\t\t\ttokenResponse.expires_in,\n\t\t\t\tclientId,\n\t\t\t);\n\n\t\t\tspinner.succeed(\"Logged in successfully!\");\n\n\t\t\tif (json) {\n\t\t\t\tformatOutput({ success: true, loggedIn: true }, true);\n\t\t\t} else {\n\t\t\t\tconsole.log();\n\t\t\t\tformatSuccess(\"You're now logged in to WaniWani!\", false);\n\t\t\t\tconsole.log();\n\t\t\t\tconsole.log(\"Get started:\");\n\t\t\t\tconsole.log(\n\t\t\t\t\t\" waniwani mcp create my-server Create a new MCP sandbox\",\n\t\t\t\t);\n\t\t\t\tconsole.log(' waniwani task \"Add a tool\" Send tasks to Claude');\n\t\t\t\tconsole.log(\n\t\t\t\t\t\" waniwani org list View your organizations\",\n\t\t\t\t);\n\t\t\t}\n\t\t} catch (error) {\n\t\t\thandleError(error, json);\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n","import { Command } from \"commander\";\nimport { auth } from \"../lib/auth.js\";\nimport { handleError } from \"../lib/errors.js\";\nimport { formatOutput, formatSuccess } from \"../lib/output.js\";\n\nexport const logoutCommand = new Command(\"logout\")\n\t.description(\"Log out from WaniWani\")\n\t.action(async (_options, command) => {\n\t\tconst globalOptions = command.optsWithGlobals();\n\t\tconst json = globalOptions.json ?? false;\n\n\t\ttry {\n\t\t\tif (!(await auth.isLoggedIn())) {\n\t\t\t\tif (json) {\n\t\t\t\t\tformatOutput({ alreadyLoggedOut: true }, true);\n\t\t\t\t} else {\n\t\t\t\t\tconsole.log(\"Not currently logged in.\");\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Clear auth tokens only (keep config like apiUrl intact)\n\t\t\tawait auth.clear();\n\n\t\t\tif (json) {\n\t\t\t\tformatOutput({ success: true }, true);\n\t\t\t} else {\n\t\t\t\tformatSuccess(\"You have been logged out.\", false);\n\t\t\t}\n\t\t} catch (error) {\n\t\t\thandleError(error, json);\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n","import { Command } from \"commander\";\nimport { cloneCommand } from \"./clone.js\";\nimport { createCommand } from \"./create.js\";\nimport { deleteCommand } from \"./delete.js\";\nimport { fileCommand } from \"./file/index.js\";\nimport { listCommand } from \"./list.js\";\nimport { logsCommand } from \"./logs.js\";\nimport { previewCommand } from \"./preview.js\";\nimport { runCommandCommand } from \"./run-command.js\";\nimport { statusCommand } from \"./status.js\";\nimport { stopCommand } from \"./stop.js\";\nimport { syncCommand } from \"./sync.js\";\nimport { useCommand } from \"./use.js\";\n\nexport const mcpCommand = new Command(\"mcp\")\n\t.description(\"MCP management commands\")\n\t.addCommand(createCommand)\n\t.addCommand(cloneCommand)\n\t.addCommand(listCommand)\n\t.addCommand(useCommand)\n\t.addCommand(statusCommand)\n\t.addCommand(previewCommand)\n\t.addCommand(stopCommand)\n\t.addCommand(logsCommand)\n\t.addCommand(syncCommand)\n\t.addCommand(deleteCommand)\n\t.addCommand(fileCommand)\n\t.addCommand(runCommandCommand);\n","import { execFileSync, execSync } from \"node:child_process\";\nimport { existsSync } from \"node:fs\";\nimport { readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { Command } from \"commander\";\nimport ora from \"ora\";\nimport { api } from \"../../lib/api.js\";\nimport {\n\tCONFIG_FILE_NAME,\n\tinitConfigAt,\n\tLOCAL_CONFIG_DIR,\n} from \"../../lib/config.js\";\nimport { setupGitCredentialHelper } from \"../../lib/credential-helper-setup.js\";\nimport { CLIError, handleError, McpError } from \"../../lib/errors.js\";\nimport {\n\tgetGitAuthContext,\n\trevokeGitHubInstallationToken,\n\trunGitWithCredentials,\n} from \"../../lib/git-auth.js\";\nimport { formatOutput, formatSuccess } from \"../../lib/output.js\";\nimport type {\n\tMcpRepository,\n\tMcpRepositoryListResponse,\n} from \"../../types/index.js\";\n\n/**\n * Load parent .waniwani/settings.json if it exists.\n * Copies all settings including auth tokens, but excludes mcpId (new project gets its own).\n */\nasync function loadParentConfig(\n\tcwd: string,\n): Promise<Record<string, unknown> | null> {\n\tconst parentConfigPath = join(cwd, LOCAL_CONFIG_DIR, CONFIG_FILE_NAME);\n\tif (!existsSync(parentConfigPath)) {\n\t\treturn null;\n\t}\n\n\ttry {\n\t\tconst content = await readFile(parentConfigPath, \"utf-8\");\n\t\tconst config = JSON.parse(content);\n\t\tconst { mcpId: _, sessionId: __, ...rest } = config;\n\t\treturn rest;\n\t} catch {\n\t\treturn null;\n\t}\n}\n\nfunction checkGitInstalled(): void {\n\ttry {\n\t\texecSync(\"git --version\", { stdio: \"ignore\" });\n\t} catch {\n\t\tthrow new CLIError(\n\t\t\t\"git is required but not found. Install it from https://git-scm.com/\",\n\t\t\t\"GIT_NOT_FOUND\",\n\t\t);\n\t}\n}\n\nexport const cloneCommand = new Command(\"clone\")\n\t.description(\"Clone an existing MCP project to a local directory\")\n\t.argument(\"<name>\", \"Name of the MCP to clone\")\n\t.argument(\"[directory]\", \"Directory to clone into (defaults to MCP name)\")\n\t.action(\n\t\tasync (\n\t\t\tname: string,\n\t\t\tdirectory: string | undefined,\n\t\t\t_options: unknown,\n\t\t\tcommand,\n\t\t) => {\n\t\t\tconst globalOptions = command.optsWithGlobals();\n\t\t\tconst json = globalOptions.json ?? false;\n\n\t\t\ttry {\n\t\t\t\tconst cwd = process.cwd();\n\t\t\t\tconst dirName = directory ?? name;\n\t\t\t\tconst projectDir = join(cwd, dirName);\n\n\t\t\t\t// Check if directory already exists\n\t\t\t\tif (existsSync(projectDir)) {\n\t\t\t\t\tif (json) {\n\t\t\t\t\t\tformatOutput(\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tsuccess: false,\n\t\t\t\t\t\t\t\terror: `Directory \"${dirName}\" already exists`,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\ttrue,\n\t\t\t\t\t\t);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tconsole.error(`Error: Directory \"${dirName}\" already exists`);\n\t\t\t\t\t}\n\t\t\t\t\tprocess.exit(1);\n\t\t\t\t}\n\n\t\t\t\tcheckGitInstalled();\n\n\t\t\t\tconst spinner = ora(\"Fetching MCPs...\").start();\n\n\t\t\t\t// Find MCP by name\n\t\t\t\tconst mcps = await api.get<McpRepositoryListResponse>(\n\t\t\t\t\t\"/api/mcp/repositories\",\n\t\t\t\t);\n\t\t\t\tconst mcp = mcps.find((m: McpRepository) => m.name === name);\n\n\t\t\t\tif (!mcp) {\n\t\t\t\t\tspinner.fail(\"MCP not found\");\n\t\t\t\t\tthrow new McpError(\n\t\t\t\t\t\t`MCP \"${name}\" not found. Run 'waniwani mcp list' to see available MCPs.`,\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\t// Get authenticated clone context\n\t\t\t\tspinner.text = \"Cloning repository...\";\n\t\t\t\tconst gitAuth = await getGitAuthContext(mcp.id);\n\n\t\t\t\t// Clone the repository\n\t\t\t\ttry {\n\t\t\t\t\trunGitWithCredentials([\"clone\", gitAuth.remoteUrl, projectDir], {\n\t\t\t\t\t\tstdio: \"ignore\",\n\t\t\t\t\t\tcredentials: gitAuth.credentials,\n\t\t\t\t\t});\n\t\t\t\t} catch {\n\t\t\t\t\tspinner.fail(\"Failed to clone repository\");\n\t\t\t\t\tthrow new CLIError(\n\t\t\t\t\t\t\"Failed to clone repository. Ensure git is configured correctly.\",\n\t\t\t\t\t\t\"CLONE_FAILED\",\n\t\t\t\t\t);\n\t\t\t\t} finally {\n\t\t\t\t\tawait revokeGitHubInstallationToken(gitAuth);\n\t\t\t\t}\n\n\t\t\t\t// Keep origin clean (no embedded credentials/signatures)\n\t\t\t\texecFileSync(\n\t\t\t\t\t\"git\",\n\t\t\t\t\t[\"remote\", \"set-url\", \"origin\", mcp.githubCloneUrl],\n\t\t\t\t\t{\n\t\t\t\t\t\tcwd: projectDir,\n\t\t\t\t\t\tstdio: \"ignore\",\n\t\t\t\t\t},\n\t\t\t\t);\n\n\t\t\t\t// Create .waniwani/settings.json with mcpId\n\t\t\t\tconst parentConfig = await loadParentConfig(cwd);\n\t\t\t\tawait initConfigAt(projectDir, {\n\t\t\t\t\t...parentConfig,\n\t\t\t\t\tmcpId: mcp.id,\n\t\t\t\t});\n\n\t\t\t\t// Set up git credential helper for transparent git push\n\t\t\t\tsetupGitCredentialHelper(projectDir);\n\n\t\t\t\tspinner.succeed(\"Repository cloned\");\n\n\t\t\t\tif (json) {\n\t\t\t\t\tformatOutput(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tsuccess: true,\n\t\t\t\t\t\t\tprojectDir,\n\t\t\t\t\t\t\tmcpId: mcp.id,\n\t\t\t\t\t\t},\n\t\t\t\t\t\ttrue,\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\tconsole.log();\n\t\t\t\t\tformatSuccess(`MCP \"${name}\" cloned!`, false);\n\t\t\t\t\tconsole.log();\n\t\t\t\t\tconsole.log(\"Next steps:\");\n\t\t\t\t\tconsole.log(` cd ${dirName}`);\n\t\t\t\t\tconsole.log(\" waniwani mcp preview # Start developing\");\n\t\t\t\t\tconsole.log(\" git push origin main # Deploy\");\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\thandleError(error, json);\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\t\t},\n\t);\n","import { execFileSync } from \"node:child_process\";\nimport { realpathSync } from \"node:fs\";\n\n/**\n * Configure git credential helper in a repository's local .git/config.\n * Uses the absolute path to the current CLI binary to avoid PATH issues.\n */\nexport function setupGitCredentialHelper(repoDir: string): void {\n\tconst binaryPath = realpathSync(process.argv[1]);\n\tconst helperCommand = `!${process.execPath} ${binaryPath} git-credential-helper`;\n\n\texecFileSync(\n\t\t\"git\",\n\t\t[\"config\", \"--local\", \"credential.helper\", helperCommand],\n\t\t{ cwd: repoDir, stdio: \"ignore\" },\n\t);\n}\n","import { execFileSync, execSync } from \"node:child_process\";\nimport { existsSync } from \"node:fs\";\nimport { readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { Command } from \"commander\";\nimport ora from \"ora\";\nimport { api } from \"../../lib/api.js\";\nimport {\n\tCONFIG_FILE_NAME,\n\tinitConfigAt,\n\tLOCAL_CONFIG_DIR,\n} from \"../../lib/config.js\";\nimport { setupGitCredentialHelper } from \"../../lib/credential-helper-setup.js\";\nimport { CLIError, handleError } from \"../../lib/errors.js\";\nimport {\n\tgetGitAuthContext,\n\trevokeGitHubInstallationToken,\n\trunGitWithCredentials,\n} from \"../../lib/git-auth.js\";\nimport { formatOutput, formatSuccess } from \"../../lib/output.js\";\nimport type { McpRepository } from \"../../types/index.js\";\n\n/**\n * Load parent .waniwani/settings.json if it exists.\n * Copies all settings including auth tokens, but excludes mcpId (new project gets its own).\n */\nasync function loadParentConfig(\n\tcwd: string,\n): Promise<Record<string, unknown> | null> {\n\tconst parentConfigPath = join(cwd, LOCAL_CONFIG_DIR, CONFIG_FILE_NAME);\n\tif (!existsSync(parentConfigPath)) {\n\t\treturn null;\n\t}\n\n\ttry {\n\t\tconst content = await readFile(parentConfigPath, \"utf-8\");\n\t\tconst config = JSON.parse(content);\n\t\t// Remove mcpId from parent - the new project gets its own\n\t\t// Keep auth tokens so user doesn't need to re-login\n\t\tconst { mcpId: _, sessionId: __, ...rest } = config;\n\t\treturn rest;\n\t} catch {\n\t\treturn null;\n\t}\n}\n\nfunction checkGitInstalled(): void {\n\ttry {\n\t\texecSync(\"git --version\", { stdio: \"ignore\" });\n\t} catch {\n\t\tthrow new CLIError(\n\t\t\t\"git is required but not found. Install it from https://git-scm.com/\",\n\t\t\t\"GIT_NOT_FOUND\",\n\t\t);\n\t}\n}\n\nexport const createCommand = new Command(\"create\")\n\t.description(\"Create a new MCP project\")\n\t.argument(\"<name>\", \"Name for the MCP project\")\n\t.action(async (name: string, _options, command) => {\n\t\tconst globalOptions = command.optsWithGlobals();\n\t\tconst json = globalOptions.json ?? false;\n\n\t\ttry {\n\t\t\tconst cwd = process.cwd();\n\t\t\tconst projectDir = join(cwd, name);\n\n\t\t\t// Check if directory already exists\n\t\t\tif (existsSync(projectDir)) {\n\t\t\t\tif (json) {\n\t\t\t\t\tformatOutput(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tsuccess: false,\n\t\t\t\t\t\t\terror: `Directory \"${name}\" already exists`,\n\t\t\t\t\t\t},\n\t\t\t\t\t\ttrue,\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\tconsole.error(`Error: Directory \"${name}\" already exists`);\n\t\t\t\t}\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\n\t\t\t// Check git is installed before making API calls\n\t\t\tcheckGitInstalled();\n\n\t\t\t// Create repository on backend (GitHub repo created immediately)\n\t\t\tconst spinner = ora(\"Creating MCP...\").start();\n\n\t\t\tconst result = await api.post<McpRepository>(\"/api/mcp/repositories\", {\n\t\t\t\tname,\n\t\t\t});\n\n\t\t\t// Get authenticated clone context\n\t\t\tspinner.text = \"Cloning repository...\";\n\t\t\tconst gitAuth = await getGitAuthContext(result.id);\n\n\t\t\t// Clone the repository\n\t\t\ttry {\n\t\t\t\trunGitWithCredentials([\"clone\", gitAuth.remoteUrl, projectDir], {\n\t\t\t\t\tstdio: \"ignore\",\n\t\t\t\t\tcredentials: gitAuth.credentials,\n\t\t\t\t});\n\t\t\t} catch {\n\t\t\t\tspinner.fail(\"Failed to clone repository\");\n\t\t\t\tthrow new CLIError(\n\t\t\t\t\t`Failed to clone repository. Ensure git is configured correctly.`,\n\t\t\t\t\t\"CLONE_FAILED\",\n\t\t\t\t);\n\t\t\t} finally {\n\t\t\t\tawait revokeGitHubInstallationToken(gitAuth);\n\t\t\t}\n\n\t\t\t// Keep origin clean (no embedded credentials/signatures)\n\t\t\texecFileSync(\n\t\t\t\t\"git\",\n\t\t\t\t[\"remote\", \"set-url\", \"origin\", result.githubCloneUrl],\n\t\t\t\t{\n\t\t\t\t\tcwd: projectDir,\n\t\t\t\t\tstdio: \"ignore\",\n\t\t\t\t},\n\t\t\t);\n\n\t\t\t// Create .waniwani/settings.json with mcpId (after clone so dir exists)\n\t\t\tconst parentConfig = await loadParentConfig(cwd);\n\t\t\tawait initConfigAt(projectDir, {\n\t\t\t\t...parentConfig,\n\t\t\t\tmcpId: result.id,\n\t\t\t});\n\n\t\t\t// Set up git credential helper for transparent git push\n\t\t\tsetupGitCredentialHelper(projectDir);\n\n\t\t\tspinner.succeed(\"MCP project created\");\n\n\t\t\tif (json) {\n\t\t\t\tformatOutput(\n\t\t\t\t\t{\n\t\t\t\t\t\tsuccess: true,\n\t\t\t\t\t\tprojectDir,\n\t\t\t\t\t\tmcpId: result.id,\n\t\t\t\t\t},\n\t\t\t\t\ttrue,\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tconsole.log();\n\t\t\t\tformatSuccess(`MCP \"${name}\" created!`, false);\n\t\t\t\tconsole.log();\n\t\t\t\tconsole.log(\"Next steps:\");\n\t\t\t\tconsole.log(` cd ${name}`);\n\t\t\t\tconsole.log(\" waniwani mcp preview # Start developing\");\n\t\t\t\tconsole.log(\" git push origin main # Deploy\");\n\t\t\t}\n\t\t} catch (error) {\n\t\t\thandleError(error, json);\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n","import { confirm } from \"@inquirer/prompts\";\nimport chalk from \"chalk\";\nimport { Command } from \"commander\";\nimport ora from \"ora\";\nimport { api } from \"../../lib/api.js\";\nimport { config } from \"../../lib/config.js\";\nimport { handleError } from \"../../lib/errors.js\";\nimport { formatOutput, formatSuccess } from \"../../lib/output.js\";\nimport { requireMcpId } from \"../../lib/utils.js\";\nimport type { McpRepository } from \"../../types/index.js\";\n\nexport const deleteCommand = new Command(\"delete\")\n\t.description(\"Delete the MCP (includes all associated resources)\")\n\t.option(\"--mcp-id <id>\", \"Specific MCP ID\")\n\t.option(\"--force\", \"Skip confirmation prompt\")\n\t.action(async (options, command) => {\n\t\tconst globalOptions = command.optsWithGlobals();\n\t\tconst json = globalOptions.json ?? false;\n\n\t\ttry {\n\t\t\tconst mcpId = await requireMcpId(options.mcpId);\n\n\t\t\t// Get MCP details for confirmation\n\t\t\tconst mcp = await api.get<McpRepository>(\n\t\t\t\t`/api/mcp/repositories/${mcpId}`,\n\t\t\t);\n\n\t\t\t// Require confirmation unless --force\n\t\t\tif (!options.force && !json) {\n\t\t\t\tconsole.log();\n\t\t\t\tconsole.log(chalk.yellow(\"This will permanently delete:\"));\n\t\t\t\tconsole.log(` - MCP: ${mcp.name}`);\n\t\t\t\tif (mcp.activeSandbox) {\n\t\t\t\t\tconsole.log(\" - Active sandbox\");\n\t\t\t\t}\n\t\t\t\tconsole.log();\n\n\t\t\t\tconst confirmed = await confirm({\n\t\t\t\t\tmessage: `Delete \"${mcp.name}\"?`,\n\t\t\t\t\tdefault: false,\n\t\t\t\t});\n\n\t\t\t\tif (!confirmed) {\n\t\t\t\t\tconsole.log(\"Cancelled.\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst spinner = ora(\"Deleting MCP...\").start();\n\t\t\tawait api.delete(`/api/mcp/repositories/${mcpId}`);\n\t\t\tspinner.succeed(\"MCP deleted\");\n\n\t\t\t// Clear active MCP and session if it was the one we deleted\n\t\t\tif ((await config.getMcpId()) === mcpId) {\n\t\t\t\tawait config.setMcpId(null);\n\t\t\t\tawait config.setSessionId(null);\n\t\t\t}\n\n\t\t\tif (json) {\n\t\t\t\tformatOutput({ deleted: mcpId }, true);\n\t\t\t} else {\n\t\t\t\tformatSuccess(\"MCP deleted.\", false);\n\t\t\t}\n\t\t} catch (error) {\n\t\t\thandleError(error, json);\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n","import { Command } from \"commander\";\nimport { listCommand } from \"./list.js\";\nimport { readCommand } from \"./read.js\";\nimport { writeCommand } from \"./write.js\";\n\nexport const fileCommand = new Command(\"file\")\n\t.description(\"File operations in MCP sandbox\")\n\t.addCommand(readCommand)\n\t.addCommand(writeCommand)\n\t.addCommand(listCommand);\n","import chalk from \"chalk\";\nimport { Command } from \"commander\";\nimport ora from \"ora\";\nimport { api } from \"../../../lib/api.js\";\nimport { handleError } from \"../../../lib/errors.js\";\nimport { formatOutput, formatTable } from \"../../../lib/output.js\";\nimport { requireMcpId, requireSessionId } from \"../../../lib/utils.js\";\nimport type { ListFilesResponse } from \"../../../types/index.js\";\n\nexport const listCommand = new Command(\"list\")\n\t.description(\"List files in the MCP sandbox\")\n\t.argument(\"[path]\", \"Directory path (defaults to /app)\", \"/app\")\n\t.option(\"--mcp-id <id>\", \"Specific MCP ID\")\n\t.action(async (path: string, options, command) => {\n\t\tconst globalOptions = command.optsWithGlobals();\n\t\tconst json = globalOptions.json ?? false;\n\n\t\ttry {\n\t\t\tawait requireMcpId(options.mcpId);\n\t\t\tconst sessionId = await requireSessionId();\n\n\t\t\tconst spinner = ora(`Listing ${path}...`).start();\n\n\t\t\tconst result = await api.get<ListFilesResponse>(\n\t\t\t\t`/api/mcp/sessions/${sessionId}/files/list?path=${encodeURIComponent(path)}`,\n\t\t\t);\n\n\t\t\tspinner.stop();\n\n\t\t\tif (json) {\n\t\t\t\tformatOutput(result, true);\n\t\t\t} else {\n\t\t\t\tconsole.log(chalk.bold(`\\nDirectory: ${result.path}\\n`));\n\n\t\t\t\tif (result.entries.length === 0) {\n\t\t\t\t\tconsole.log(\" (empty)\");\n\t\t\t\t} else {\n\t\t\t\t\tconst rows = result.entries.map((entry) => {\n\t\t\t\t\t\tconst name =\n\t\t\t\t\t\t\tentry.type === \"directory\"\n\t\t\t\t\t\t\t\t? chalk.blue(`${entry.name}/`)\n\t\t\t\t\t\t\t\t: entry.name;\n\t\t\t\t\t\tconst size =\n\t\t\t\t\t\t\tentry.type === \"directory\"\n\t\t\t\t\t\t\t\t? chalk.gray(\"<dir>\")\n\t\t\t\t\t\t\t\t: formatSize(entry.size);\n\t\t\t\t\t\treturn [name, size];\n\t\t\t\t\t});\n\n\t\t\t\t\tformatTable([\"Name\", \"Size\"], rows, false);\n\t\t\t\t}\n\t\t\t\tconsole.log();\n\t\t\t}\n\t\t} catch (error) {\n\t\t\thandleError(error, json);\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n\nfunction formatSize(bytes?: number): string {\n\tif (bytes === undefined) return \"\";\n\tif (bytes < 1024) return `${bytes} B`;\n\tif (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;\n\treturn `${(bytes / (1024 * 1024)).toFixed(1)} MB`;\n}\n","import { writeFile } from \"node:fs/promises\";\nimport { Command } from \"commander\";\nimport ora from \"ora\";\nimport { api } from \"../../../lib/api.js\";\nimport { handleError, McpError } from \"../../../lib/errors.js\";\nimport { formatOutput, formatSuccess } from \"../../../lib/output.js\";\nimport { requireMcpId, requireSessionId } from \"../../../lib/utils.js\";\nimport type { ReadFileResponse } from \"../../../types/index.js\";\n\nexport const readCommand = new Command(\"read\")\n\t.description(\"Read a file from the MCP sandbox\")\n\t.argument(\"<path>\", \"Path in sandbox (e.g., /app/src/index.ts)\")\n\t.option(\"--mcp-id <id>\", \"Specific MCP ID\")\n\t.option(\"--output <file>\", \"Write to local file instead of stdout\")\n\t.option(\"--base64\", \"Output as base64 (for binary files)\")\n\t.action(async (path: string, options, command) => {\n\t\tconst globalOptions = command.optsWithGlobals();\n\t\tconst json = globalOptions.json ?? false;\n\n\t\ttry {\n\t\t\tawait requireMcpId(options.mcpId);\n\t\t\tconst sessionId = await requireSessionId();\n\n\t\t\tconst encoding = options.base64 ? \"base64\" : \"utf8\";\n\t\t\tconst spinner = ora(`Reading ${path}...`).start();\n\n\t\t\tconst result = await api.get<ReadFileResponse>(\n\t\t\t\t`/api/mcp/sessions/${sessionId}/files?path=${encodeURIComponent(path)}&encoding=${encoding}`,\n\t\t\t);\n\n\t\t\tspinner.stop();\n\n\t\t\tif (!result.exists) {\n\t\t\t\tthrow new McpError(`File not found: ${path}`);\n\t\t\t}\n\n\t\t\tif (options.output) {\n\t\t\t\t// Write to local file\n\t\t\t\tconst buffer =\n\t\t\t\t\tresult.encoding === \"base64\"\n\t\t\t\t\t\t? Buffer.from(result.content, \"base64\")\n\t\t\t\t\t\t: Buffer.from(result.content, \"utf8\");\n\t\t\t\tawait writeFile(options.output, buffer);\n\t\t\t\tif (json) {\n\t\t\t\t\tformatOutput({ path, savedTo: options.output }, true);\n\t\t\t\t} else {\n\t\t\t\t\tformatSuccess(`Saved to ${options.output}`, false);\n\t\t\t\t}\n\t\t\t} else if (json) {\n\t\t\t\tformatOutput(result, true);\n\t\t\t} else {\n\t\t\t\t// Print to stdout\n\t\t\t\tprocess.stdout.write(result.content);\n\t\t\t\t// Add newline if content doesn't end with one\n\t\t\t\tif (!result.content.endsWith(\"\\n\")) {\n\t\t\t\t\tprocess.stdout.write(\"\\n\");\n\t\t\t\t}\n\t\t\t}\n\t\t} catch (error) {\n\t\t\thandleError(error, json);\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n","import { readFile } from \"node:fs/promises\";\nimport { Command } from \"commander\";\nimport ora from \"ora\";\nimport { api } from \"../../../lib/api.js\";\nimport { CLIError, handleError } from \"../../../lib/errors.js\";\nimport { formatOutput, formatSuccess } from \"../../../lib/output.js\";\nimport { requireMcpId, requireSessionId } from \"../../../lib/utils.js\";\nimport type { WriteFilesResponse } from \"../../../types/index.js\";\n\nexport const writeCommand = new Command(\"write\")\n\t.description(\"Write a file to the MCP sandbox\")\n\t.argument(\"<path>\", \"Path in sandbox (e.g., /app/src/index.ts)\")\n\t.option(\"--mcp-id <id>\", \"Specific MCP ID\")\n\t.option(\"--content <content>\", \"Content to write\")\n\t.option(\"--file <localFile>\", \"Local file to upload\")\n\t.option(\"--base64\", \"Treat content as base64 encoded\")\n\t.action(async (path: string, options, command) => {\n\t\tconst globalOptions = command.optsWithGlobals();\n\t\tconst json = globalOptions.json ?? false;\n\n\t\ttry {\n\t\t\tawait requireMcpId(options.mcpId);\n\t\t\tconst sessionId = await requireSessionId();\n\n\t\t\t// Get content from --content or --file\n\t\t\tlet content: string;\n\t\t\tlet encoding: \"utf8\" | \"base64\" = \"utf8\";\n\n\t\t\tif (options.content) {\n\t\t\t\tcontent = options.content;\n\t\t\t\tif (options.base64) {\n\t\t\t\t\tencoding = \"base64\";\n\t\t\t\t}\n\t\t\t} else if (options.file) {\n\t\t\t\tconst fileBuffer = await readFile(options.file);\n\t\t\t\tif (options.base64) {\n\t\t\t\t\tcontent = fileBuffer.toString(\"base64\");\n\t\t\t\t\tencoding = \"base64\";\n\t\t\t\t} else {\n\t\t\t\t\tcontent = fileBuffer.toString(\"utf8\");\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tthrow new CLIError(\n\t\t\t\t\t\"Either --content or --file is required\",\n\t\t\t\t\t\"MISSING_CONTENT\",\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst spinner = ora(`Writing ${path}...`).start();\n\n\t\t\tconst result = await api.post<WriteFilesResponse>(\n\t\t\t\t`/api/mcp/sessions/${sessionId}/files`,\n\t\t\t\t{\n\t\t\t\t\tfiles: [{ path, content, encoding }],\n\t\t\t\t},\n\t\t\t);\n\n\t\t\tspinner.succeed(`Wrote ${path}`);\n\n\t\t\tif (json) {\n\t\t\t\tformatOutput(result, true);\n\t\t\t} else {\n\t\t\t\tformatSuccess(`File written: ${path}`, false);\n\t\t\t}\n\t\t} catch (error) {\n\t\t\thandleError(error, json);\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n","import chalk from \"chalk\";\nimport { Command } from \"commander\";\nimport ora from \"ora\";\nimport { api } from \"../../lib/api.js\";\nimport { config } from \"../../lib/config.js\";\nimport { handleError } from \"../../lib/errors.js\";\nimport { formatOutput, formatTable } from \"../../lib/output.js\";\nimport type {\n\tMcpRepository,\n\tMcpRepositoryListResponse,\n} from \"../../types/index.js\";\n\nexport const listCommand = new Command(\"list\")\n\t.description(\"List all MCPs in your organization\")\n\t.action(async (_options, command) => {\n\t\tconst globalOptions = command.optsWithGlobals();\n\t\tconst json = globalOptions.json ?? false;\n\n\t\ttry {\n\t\t\tconst spinner = ora(\"Fetching MCPs...\").start();\n\n\t\t\tconst mcps = await api.get<McpRepositoryListResponse>(\n\t\t\t\t\"/api/mcp/repositories\",\n\t\t\t);\n\n\t\t\tspinner.stop();\n\n\t\t\tconst activeMcpId = await config.getMcpId();\n\n\t\t\tif (json) {\n\t\t\t\tformatOutput(\n\t\t\t\t\t{\n\t\t\t\t\t\tmcps: mcps.map((m: McpRepository) => ({\n\t\t\t\t\t\t\t...m,\n\t\t\t\t\t\t\tisActive: m.id === activeMcpId,\n\t\t\t\t\t\t})),\n\t\t\t\t\t\tactiveMcpId,\n\t\t\t\t\t},\n\t\t\t\t\ttrue,\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tif (mcps.length === 0) {\n\t\t\t\t\tconsole.log(\"No MCPs found.\");\n\t\t\t\t\tconsole.log(\"\\nCreate a new MCP: waniwani mcp create <name>\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconsole.log(chalk.bold(\"\\nMCPs:\\n\"));\n\n\t\t\t\tconst rows = mcps.map((m: McpRepository) => {\n\t\t\t\t\tconst isActive = m.id === activeMcpId;\n\t\t\t\t\tconst deployStatus = m.deployedAt\n\t\t\t\t\t\t? chalk.green(\"Deployed\")\n\t\t\t\t\t\t: chalk.yellow(\"Pending\");\n\t\t\t\t\tconst sandboxStatus = m.activeSandbox\n\t\t\t\t\t\t? chalk.green(\"Active\")\n\t\t\t\t\t\t: chalk.gray(\"None\");\n\t\t\t\t\tconst lastDeploy = m.deployedAt\n\t\t\t\t\t\t? new Date(m.deployedAt).toLocaleDateString()\n\t\t\t\t\t\t: chalk.gray(\"Never\");\n\n\t\t\t\t\treturn [\n\t\t\t\t\t\tisActive ? chalk.cyan(`* ${m.name}`) : ` ${m.name}`,\n\t\t\t\t\t\tdeployStatus,\n\t\t\t\t\t\tsandboxStatus,\n\t\t\t\t\t\tlastDeploy,\n\t\t\t\t\t];\n\t\t\t\t});\n\n\t\t\t\tformatTable([\"Name\", \"Status\", \"Sandbox\", \"Last Deploy\"], rows, false);\n\n\t\t\t\tconsole.log();\n\t\t\t\tif (activeMcpId) {\n\t\t\t\t\tconst activeMcp = mcps.find((m) => m.id === activeMcpId);\n\t\t\t\t\tif (activeMcp) {\n\t\t\t\t\t\tconsole.log(`Active MCP: ${chalk.cyan(activeMcp.name)}`);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tconsole.log(\"\\nSelect an MCP: waniwani mcp use <name>\");\n\t\t\t}\n\t\t} catch (error) {\n\t\t\thandleError(error, json);\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n","import chalk from \"chalk\";\nimport { Command } from \"commander\";\nimport ora from \"ora\";\nimport { api } from \"../../lib/api.js\";\nimport { auth } from \"../../lib/auth.js\";\nimport { AuthError, handleError, McpError } from \"../../lib/errors.js\";\nimport { formatOutput } from \"../../lib/output.js\";\nimport { requireMcpId, requireSessionId } from \"../../lib/utils.js\";\nimport type { LogEvent, ServerStatusResponse } from \"../../types/index.js\";\n\nexport const logsCommand = new Command(\"logs\")\n\t.description(\"Stream logs from the MCP server\")\n\t.argument(\"[cmdId]\", \"Command ID (defaults to running server)\")\n\t.option(\"--mcp-id <id>\", \"Specific MCP ID\")\n\t.option(\"-f, --follow\", \"Keep streaming logs (default)\", true)\n\t.option(\"--no-follow\", \"Fetch logs and exit\")\n\t.action(async (cmdIdArg: string | undefined, options, command) => {\n\t\tconst globalOptions = command.optsWithGlobals();\n\t\tconst json = globalOptions.json ?? false;\n\n\t\tlet reader: ReadableStreamDefaultReader<Uint8Array> | undefined;\n\n\t\t// Handle Ctrl+C gracefully\n\t\tconst cleanup = () => {\n\t\t\tif (reader) {\n\t\t\t\treader.cancel().catch(() => {});\n\t\t\t}\n\t\t\tprocess.exit(0);\n\t\t};\n\t\tprocess.on(\"SIGINT\", cleanup);\n\t\tprocess.on(\"SIGTERM\", cleanup);\n\n\t\ttry {\n\t\t\tawait requireMcpId(options.mcpId);\n\t\t\tconst sessionId = await requireSessionId();\n\n\t\t\tconst token = await auth.getAccessToken();\n\t\t\tif (!token) {\n\t\t\t\tthrow new AuthError(\n\t\t\t\t\t\"Not logged in. Run 'waniwani login' to authenticate.\",\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tlet cmdId = cmdIdArg;\n\n\t\t\t// If no cmdId provided, get it from server status\n\t\t\tif (!cmdId) {\n\t\t\t\tconst spinner = ora(\"Getting server status...\").start();\n\t\t\t\tconst status = await api.post<ServerStatusResponse>(\n\t\t\t\t\t`/api/mcp/sessions/${sessionId}/server`,\n\t\t\t\t\t{ action: \"status\" },\n\t\t\t\t);\n\t\t\t\tspinner.stop();\n\n\t\t\t\tif (!status.running || !status.cmdId) {\n\t\t\t\t\tthrow new McpError(\n\t\t\t\t\t\t\"No server is running. Run 'waniwani mcp preview' first.\",\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tcmdId = status.cmdId;\n\t\t\t}\n\n\t\t\tconst baseUrl = await api.getBaseUrl();\n\t\t\tconst streamParam = options.follow ? \"?stream=true\" : \"\";\n\t\t\tconst url = `${baseUrl}/api/mcp/sessions/${sessionId}/commands/${cmdId}${streamParam}`;\n\n\t\t\tif (!json) {\n\t\t\t\tconsole.log(chalk.gray(`Streaming logs for command ${cmdId}...`));\n\t\t\t\tconsole.log(chalk.gray(\"Press Ctrl+C to stop\\n\"));\n\t\t\t}\n\n\t\t\tconst response = await fetch(url, {\n\t\t\t\tmethod: \"GET\",\n\t\t\t\theaders: {\n\t\t\t\t\tAuthorization: `Bearer ${token}`,\n\t\t\t\t\tAccept: options.follow ? \"text/event-stream\" : \"application/json\",\n\t\t\t\t},\n\t\t\t});\n\n\t\t\tif (!response.ok) {\n\t\t\t\tconst error = await response\n\t\t\t\t\t.json()\n\t\t\t\t\t.catch(() => ({ message: response.statusText }));\n\t\t\t\tthrow new Error(\n\t\t\t\t\terror.message || `Request failed with status ${response.status}`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// Non-streaming mode\n\t\t\tif (!options.follow) {\n\t\t\t\tconst data = await response.json();\n\t\t\t\tif (json) {\n\t\t\t\t\tformatOutput(data, true);\n\t\t\t\t} else {\n\t\t\t\t\tif (data.stdout) {\n\t\t\t\t\t\tprocess.stdout.write(data.stdout);\n\t\t\t\t\t}\n\t\t\t\t\tif (data.stderr) {\n\t\t\t\t\t\tprocess.stderr.write(chalk.red(data.stderr));\n\t\t\t\t\t}\n\t\t\t\t\tif (data.exitCode !== undefined) {\n\t\t\t\t\t\tconsole.log(chalk.gray(`\\nExit code: ${data.exitCode}`));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Streaming mode\n\t\t\treader = response.body?.getReader();\n\t\t\tif (!reader) {\n\t\t\t\tthrow new Error(\"No response body\");\n\t\t\t}\n\n\t\t\tconst decoder = new TextDecoder();\n\t\t\tlet buffer = \"\";\n\t\t\tconst collectedLogs: LogEvent[] = [];\n\n\t\t\twhile (true) {\n\t\t\t\tconst { done, value } = await reader.read();\n\t\t\t\tif (done) break;\n\n\t\t\t\tbuffer += decoder.decode(value, { stream: true });\n\t\t\t\tconst lines = buffer.split(\"\\n\");\n\t\t\t\tbuffer = lines.pop() || \"\";\n\n\t\t\t\tfor (const line of lines) {\n\t\t\t\t\tif (line.startsWith(\"event: \")) {\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (line.startsWith(\"data: \")) {\n\t\t\t\t\t\tconst data = line.slice(6);\n\t\t\t\t\t\tif (!data || data === \"[DONE]\") continue;\n\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tconst event = JSON.parse(data) as LogEvent;\n\t\t\t\t\t\t\tcollectedLogs.push(event);\n\n\t\t\t\t\t\t\tif (json) {\n\t\t\t\t\t\t\t\t// In JSON mode, we'll output at the end\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// Handle different event types\n\t\t\t\t\t\t\tif (event.cmdId) {\n\t\t\t\t\t\t\t\t// Initial event with cmdId\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif (event.stream && event.data !== undefined) {\n\t\t\t\t\t\t\t\tif (event.stream === \"stdout\") {\n\t\t\t\t\t\t\t\t\tprocess.stdout.write(event.data);\n\t\t\t\t\t\t\t\t} else if (event.stream === \"stderr\") {\n\t\t\t\t\t\t\t\t\tprocess.stderr.write(chalk.red(event.data));\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif (event.exitCode !== undefined) {\n\t\t\t\t\t\t\t\tconst exitColor =\n\t\t\t\t\t\t\t\t\tevent.exitCode === 0 ? chalk.green : chalk.red;\n\t\t\t\t\t\t\t\tconsole.log(\n\t\t\t\t\t\t\t\t\texitColor(`\\nProcess exited with code ${event.exitCode}`),\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif (event.error) {\n\t\t\t\t\t\t\t\tconsole.error(chalk.red(`\\nError: ${event.error}`));\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\t// Ignore malformed JSON\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Output collected logs in JSON mode\n\t\t\tif (json) {\n\t\t\t\tformatOutput(collectedLogs, true);\n\t\t\t}\n\t\t} catch (error) {\n\t\t\thandleError(error, json);\n\t\t\tprocess.exit(1);\n\t\t} finally {\n\t\t\tprocess.off(\"SIGINT\", cleanup);\n\t\t\tprocess.off(\"SIGTERM\", cleanup);\n\t\t}\n\t});\n","import { existsSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { watch } from \"chokidar\";\nimport { Command, InvalidArgumentError } from \"commander\";\nimport ora from \"ora\";\nimport { api } from \"../../lib/api.js\";\nimport { withTimeout } from \"../../lib/async.js\";\nimport { config } from \"../../lib/config.js\";\nimport { CLIError, handleError } from \"../../lib/errors.js\";\nimport { formatSuccess } from \"../../lib/output.js\";\nimport {\n\tcollectFiles,\n\tcollectSingleFile,\n\tfindProjectRoot,\n\tloadIgnorePatterns,\n} from \"../../lib/sync.js\";\nimport type {\n\tMcpSandbox,\n\tRunCommandResponse,\n\tSandboxStartResponse,\n\tServerStartResponse,\n\tServerStatusResponse,\n\tWriteFilesResponse,\n} from \"../../types/index.js\";\n\nconst SHUTDOWN_MAX_WAIT_MS = 3000;\nconst SHUTDOWN_STEP_TIMEOUT_MS = 1200;\nconst DEV_SERVER_VERIFY_ATTEMPTS = 4;\nconst DEV_SERVER_VERIFY_INTERVAL_MS = 750;\nconst DEFAULT_DEV_SERVER_MONITOR_INTERVAL_MS = 60000;\n\ntype SessionInfo = {\n\tid: string;\n\tpreviewUrl: string;\n\tsandboxId?: string;\n};\n\ntype CommandStatusResponse = {\n\tcmdId: string;\n\texitCode: number | null;\n\trunning: boolean;\n};\n\ntype CommandOutputResponse = {\n\tcmdId: string;\n\texitCode: number | null;\n\tstdout: string;\n\tstderr: string;\n};\n\ntype PackageManager = \"bun\" | \"pnpm\" | \"yarn\" | \"npm-ci\" | \"npm\";\n\nconst MAX_INSTALL_TIMEOUT_MS = 300000;\n\nfunction resolveSessionInfo(\n\tresponse:\n\t\t| SandboxStartResponse\n\t\t| McpSandbox\n\t\t| (McpSandbox & { sandbox?: McpSandbox }),\n): SessionInfo {\n\t// Legacy shape: { sandbox: {...}, previewUrl }\n\tconst maybeLegacy = response as SandboxStartResponse;\n\tif (maybeLegacy?.sandbox?.id && maybeLegacy?.previewUrl) {\n\t\treturn {\n\t\t\tid: maybeLegacy.sandbox.id,\n\t\t\tpreviewUrl: maybeLegacy.previewUrl,\n\t\t\tsandboxId: maybeLegacy.sandbox.sandboxId,\n\t\t};\n\t}\n\n\t// Current shape: session object itself\n\tconst maybeSession = response as McpSandbox;\n\tif (maybeSession?.id && maybeSession?.previewUrl) {\n\t\treturn {\n\t\t\tid: maybeSession.id,\n\t\t\tpreviewUrl: maybeSession.previewUrl,\n\t\t\tsandboxId: maybeSession.sandboxId,\n\t\t};\n\t}\n\n\tthrow new CLIError(\"Invalid session response from API\", \"SESSION_ERROR\");\n}\n\nfunction detectPackageManager(projectRoot: string): PackageManager {\n\tif (\n\t\texistsSync(join(projectRoot, \"bun.lock\")) ||\n\t\texistsSync(join(projectRoot, \"bun.lockb\"))\n\t) {\n\t\treturn \"bun\";\n\t}\n\tif (existsSync(join(projectRoot, \"pnpm-lock.yaml\"))) return \"pnpm\";\n\tif (existsSync(join(projectRoot, \"yarn.lock\"))) return \"yarn\";\n\tif (\n\t\texistsSync(join(projectRoot, \"package-lock.json\")) ||\n\t\texistsSync(join(projectRoot, \"npm-shrinkwrap.json\"))\n\t) {\n\t\treturn \"npm-ci\";\n\t}\n\treturn \"npm\";\n}\n\nfunction getInstallCommand(pm: PackageManager): {\n\tcommand: string;\n\targs: string[];\n} {\n\tswitch (pm) {\n\t\tcase \"bun\":\n\t\t\treturn { command: \"bun\", args: [\"install\", \"--frozen-lockfile\"] };\n\t\tcase \"pnpm\":\n\t\t\treturn {\n\t\t\t\tcommand: \"pnpm\",\n\t\t\t\targs: [\"install\", \"--frozen-lockfile\", \"--prefer-offline\"],\n\t\t\t};\n\t\tcase \"yarn\":\n\t\t\treturn {\n\t\t\t\tcommand: \"yarn\",\n\t\t\t\targs: [\"install\", \"--frozen-lockfile\", \"--prefer-offline\"],\n\t\t\t};\n\t\tcase \"npm-ci\":\n\t\t\treturn {\n\t\t\t\tcommand: \"npm\",\n\t\t\t\targs: [\"ci\", \"--no-audit\", \"--no-fund\", \"--prefer-offline\"],\n\t\t\t};\n\t\tdefault:\n\t\t\treturn {\n\t\t\t\tcommand: \"npm\",\n\t\t\t\targs: [\"install\", \"--no-audit\", \"--no-fund\"],\n\t\t\t};\n\t}\n}\n\nfunction getNonFrozenInstallCommand(pm: PackageManager): {\n\tcommand: string;\n\targs: string[];\n} | null {\n\tswitch (pm) {\n\t\tcase \"bun\":\n\t\t\treturn { command: \"bun\", args: [\"install\"] };\n\t\tcase \"pnpm\":\n\t\t\treturn { command: \"pnpm\", args: [\"install\", \"--prefer-offline\"] };\n\t\tcase \"yarn\":\n\t\t\treturn { command: \"yarn\", args: [\"install\", \"--prefer-offline\"] };\n\t\tcase \"npm-ci\":\n\t\t\treturn { command: \"npm\", args: [\"install\", \"--no-audit\", \"--no-fund\"] };\n\t\tdefault:\n\t\t\treturn null;\n\t}\n}\n\nfunction shouldRetryWithoutFrozenLockfile(result: RunCommandResponse): boolean {\n\tconst output = `${result.stderr}\\n${result.stdout}`.toLowerCase();\n\tconst npmLockMismatchDetected =\n\t\t(output.includes(\"update your lock file\") &&\n\t\t\toutput.includes(\"npm install\")) ||\n\t\t(output.includes(\"package-lock.json\") && output.includes(\"not in sync\")) ||\n\t\t(output.includes(\"package-lock.json\") &&\n\t\t\toutput.includes(\"are not in sync\")) ||\n\t\t(output.includes(\"npm ci\") &&\n\t\t\toutput.includes(\"can only install packages\") &&\n\t\t\toutput.includes(\"package-lock.json\"));\n\n\treturn (\n\t\toutput.includes(\"frozen-lockfile\") ||\n\t\toutput.includes(\"lockfile had changes\") ||\n\t\toutput.includes(\"lockfile is frozen\") ||\n\t\t(output.includes(\"lockfile\") && output.includes(\"out of date\")) ||\n\t\tnpmLockMismatchDetected\n\t);\n}\n\nfunction isAlreadyRunningServerError(error: unknown): boolean {\n\tconst normalized = getNormalizedError(error);\n\treturn (\n\t\tnormalized.includes(\"already_running\") ||\n\t\tnormalized.includes(\"already running\")\n\t);\n}\n\nfunction isServerNotRunningError(error: unknown): boolean {\n\tconst normalized = getNormalizedError(error);\n\treturn (\n\t\tnormalized.includes(\"server_not_running\") ||\n\t\tnormalized.includes(\"server not running\")\n\t);\n}\n\nfunction getNormalizedError(error: unknown): string {\n\tif (!(error instanceof CLIError)) return \"\";\n\tconst details = JSON.stringify(error.details ?? {}).toLowerCase();\n\treturn `${error.code} ${error.message} ${details}`.toLowerCase();\n}\n\nasync function getServerStatusOrNull(\n\tsessionId: string,\n): Promise<ServerStatusResponse | null> {\n\ttry {\n\t\treturn await api.get<ServerStatusResponse>(\n\t\t\t`/api/mcp/sessions/${sessionId}/server`,\n\t\t);\n\t} catch (error) {\n\t\tif (isServerNotRunningError(error)) {\n\t\t\treturn null;\n\t\t}\n\t\tthrow error;\n\t}\n}\n\nfunction getDevCommand(pm: PackageManager): string {\n\tswitch (pm) {\n\t\tcase \"bun\":\n\t\t\treturn \"bun run dev\";\n\t\tcase \"pnpm\":\n\t\t\treturn \"pnpm run dev\";\n\t\tcase \"yarn\":\n\t\t\treturn \"yarn run dev\";\n\t\tdefault:\n\t\t\treturn \"npm run dev\";\n\t}\n}\n\nfunction sleep(ms: number): Promise<void> {\n\treturn new Promise((resolve) => {\n\t\tsetTimeout(resolve, ms);\n\t});\n}\n\nfunction parseStatusPollIntervalMs(value: string): number {\n\tconst parsed = Number(value);\n\tif (!Number.isInteger(parsed) || parsed < 500) {\n\t\tthrow new InvalidArgumentError(\n\t\t\t\"Status poll interval must be an integer >= 500 milliseconds.\",\n\t\t);\n\t}\n\treturn parsed;\n}\n\nasync function getCommandOutputOrNull(\n\tsessionId: string,\n\tcmdId: string,\n): Promise<CommandOutputResponse | null> {\n\ttry {\n\t\treturn await api.get<CommandOutputResponse>(\n\t\t\t`/api/mcp/sessions/${sessionId}/commands/${cmdId}`,\n\t\t);\n\t} catch {\n\t\treturn null;\n\t}\n}\n\nasync function cleanupPreviewSession(sessionId: string): Promise<void> {\n\tawait withTimeout(\n\t\tapi\n\t\t\t.post(`/api/mcp/sessions/${sessionId}/server`, { action: \"stop\" })\n\t\t\t.catch(() => undefined),\n\t\tSHUTDOWN_STEP_TIMEOUT_MS,\n\t);\n\n\tawait withTimeout(\n\t\tapi.delete(`/api/mcp/sessions/${sessionId}`).catch(() => undefined),\n\t\tSHUTDOWN_STEP_TIMEOUT_MS,\n\t);\n\n\tawait withTimeout(\n\t\tconfig.setSessionId(null).catch(() => undefined),\n\t\tSHUTDOWN_STEP_TIMEOUT_MS,\n\t);\n}\n\nexport const previewCommand = new Command(\"preview\")\n\t.description(\"Start live development with sandbox and file watching\")\n\t.option(\"--mcp-id <id>\", \"Specific MCP ID\")\n\t.option(\"--no-watch\", \"Skip file watching\")\n\t.option(\"--no-logs\", \"Don't stream logs to terminal\")\n\t.option(\n\t\t\"--status-poll-interval-ms <ms>\",\n\t\t\"Watch-mode server status polling interval in milliseconds (default: 60000)\",\n\t\tparseStatusPollIntervalMs,\n\t\tDEFAULT_DEV_SERVER_MONITOR_INTERVAL_MS,\n\t)\n\t.action(async (options, command) => {\n\t\tconst globalOptions = command.optsWithGlobals();\n\t\tconst json = globalOptions.json ?? false;\n\t\tconst statusPollIntervalMs =\n\t\t\toptions.statusPollIntervalMs ?? DEFAULT_DEV_SERVER_MONITOR_INTERVAL_MS;\n\n\t\ttry {\n\t\t\t// Find project root and MCP ID\n\t\t\tconst projectRoot = await findProjectRoot(process.cwd());\n\t\t\tif (!projectRoot) {\n\t\t\t\tthrow new CLIError(\n\t\t\t\t\t\"Not in a WaniWani project. Run 'waniwani mcp create <name>' first.\",\n\t\t\t\t\t\"NOT_IN_PROJECT\",\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tlet mcpId = options.mcpId;\n\t\t\tif (!mcpId) {\n\t\t\t\tmcpId = await config.getMcpId();\n\t\t\t}\n\t\t\tif (!mcpId) {\n\t\t\t\tthrow new CLIError(\n\t\t\t\t\t\"No MCP found. Run 'waniwani mcp create <name>' or use --mcp-id.\",\n\t\t\t\t\t\"NO_MCP\",\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst spinner = ora(\"Starting development environment...\").start();\n\n\t\t\t// Step 1: Create or get session (this also starts the sandbox)\n\t\t\tspinner.text = \"Starting session...\";\n\t\t\tlet sessionId: string;\n\t\t\tlet previewUrl: string;\n\t\t\tlet sandboxId: string | undefined;\n\t\t\ttry {\n\t\t\t\tconst sessionResponse = await api.post<SandboxStartResponse>(\n\t\t\t\t\t`/api/mcp/repositories/${mcpId}/session`,\n\t\t\t\t\t{},\n\t\t\t\t);\n\t\t\t\tconst sessionInfo = resolveSessionInfo(sessionResponse);\n\t\t\t\tsessionId = sessionInfo.id;\n\t\t\t\tpreviewUrl = sessionInfo.previewUrl;\n\t\t\t\tsandboxId = sessionInfo.sandboxId;\n\t\t\t} catch {\n\t\t\t\t// Session might already exist, try to get it\n\t\t\t\tconst existing = await api.get<McpSandbox | null>(\n\t\t\t\t\t`/api/mcp/repositories/${mcpId}/session`,\n\t\t\t\t);\n\t\t\t\tif (!existing) {\n\t\t\t\t\tthrow new CLIError(\"Failed to start session\", \"SESSION_ERROR\");\n\t\t\t\t}\n\t\t\t\tconst sessionInfo = resolveSessionInfo(existing);\n\t\t\t\tsessionId = sessionInfo.id;\n\t\t\t\tpreviewUrl = sessionInfo.previewUrl;\n\t\t\t\tsandboxId = sessionInfo.sandboxId;\n\t\t\t}\n\n\t\t\t// Store session ID in config\n\t\t\tawait config.setSessionId(sessionId);\n\n\t\t\t// Step 2: Sync current files to sandbox (CLI-driven hydration)\n\t\t\tspinner.text = \"Syncing files to sandbox...\";\n\t\t\tconst files = await collectFiles(projectRoot, { includeEnvFiles: true });\n\t\t\tif (files.length > 0) {\n\t\t\t\tawait api.post<WriteFilesResponse>(\n\t\t\t\t\t`/api/mcp/sessions/${sessionId}/files`,\n\t\t\t\t\t{ files },\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// Step 3: Install dependencies to match local state\n\t\t\tconst packageManager = detectPackageManager(projectRoot);\n\t\t\tlet installCommand = getInstallCommand(packageManager);\n\t\t\tspinner.text = `Installing dependencies (${installCommand.command})...`;\n\t\t\tlet installResult = await api.post<RunCommandResponse>(\n\t\t\t\t`/api/mcp/sessions/${sessionId}/commands`,\n\t\t\t\t{\n\t\t\t\t\tcommand: installCommand.command,\n\t\t\t\t\targs: installCommand.args,\n\t\t\t\t\ttimeout: MAX_INSTALL_TIMEOUT_MS,\n\t\t\t\t},\n\t\t\t);\n\n\t\t\tif (installResult.exitCode !== 0) {\n\t\t\t\tconst nonFrozenInstallCommand =\n\t\t\t\t\tgetNonFrozenInstallCommand(packageManager);\n\t\t\t\tif (\n\t\t\t\t\tnonFrozenInstallCommand &&\n\t\t\t\t\tshouldRetryWithoutFrozenLockfile(installResult)\n\t\t\t\t) {\n\t\t\t\t\tinstallCommand = nonFrozenInstallCommand;\n\t\t\t\t\tspinner.text = `Retrying install without frozen lockfile (${installCommand.command})...`;\n\t\t\t\t\tinstallResult = await api.post<RunCommandResponse>(\n\t\t\t\t\t\t`/api/mcp/sessions/${sessionId}/commands`,\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcommand: installCommand.command,\n\t\t\t\t\t\t\targs: installCommand.args,\n\t\t\t\t\t\t\ttimeout: MAX_INSTALL_TIMEOUT_MS,\n\t\t\t\t\t\t},\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (installResult.exitCode !== 0) {\n\t\t\t\tthrow new CLIError(\n\t\t\t\t\tinstallResult.stderr ||\n\t\t\t\t\t\t`Dependency install failed with exit code ${installResult.exitCode}`,\n\t\t\t\t\t\"SANDBOX_HYDRATION_FAILED\",\n\t\t\t\t\t{\n\t\t\t\t\t\tcommand: [installCommand.command, ...installCommand.args].join(\" \"),\n\t\t\t\t\t\texitCode: installResult.exitCode,\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// Step 4: Start server with package-manager-aware dev command\n\t\t\tconst devCommand = getDevCommand(packageManager);\n\t\t\tlet serverCmdId: string | undefined;\n\t\t\tlet didStartServer = false;\n\n\t\t\tconst serverStatus = await getServerStatusOrNull(sessionId);\n\t\t\tconst serverStatusPreviewUrl = serverStatus?.previewUrl;\n\t\t\tif (serverStatusPreviewUrl) {\n\t\t\t\tpreviewUrl = serverStatusPreviewUrl;\n\t\t\t}\n\n\t\t\tif (serverStatus?.running) {\n\t\t\t\tspinner.text = \"Server already running, attaching...\";\n\t\t\t\tserverCmdId = serverStatus.cmdId;\n\t\t\t} else {\n\t\t\t\tspinner.text = `Starting server (${devCommand})...`;\n\t\t\t\ttry {\n\t\t\t\t\tconst serverStart = await api.post<ServerStartResponse>(\n\t\t\t\t\t\t`/api/mcp/sessions/${sessionId}/server`,\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\taction: \"start\",\n\t\t\t\t\t\t\tcommand: devCommand,\n\t\t\t\t\t\t},\n\t\t\t\t\t);\n\t\t\t\t\tconst serverStartPreviewUrl = serverStart.previewUrl;\n\t\t\t\t\tif (serverStartPreviewUrl) {\n\t\t\t\t\t\tpreviewUrl = serverStartPreviewUrl;\n\t\t\t\t\t}\n\t\t\t\t\tserverCmdId = serverStart.cmdId;\n\t\t\t\t\tdidStartServer = true;\n\t\t\t\t} catch (error) {\n\t\t\t\t\tif (!isAlreadyRunningServerError(error)) {\n\t\t\t\t\t\tthrow error;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst refreshedStatus = await getServerStatusOrNull(sessionId);\n\t\t\t\t\tif (!refreshedStatus?.running) {\n\t\t\t\t\t\tthrow error;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst refreshedPreviewUrl = refreshedStatus.previewUrl;\n\t\t\t\t\tif (refreshedPreviewUrl) {\n\t\t\t\t\t\tpreviewUrl = refreshedPreviewUrl;\n\t\t\t\t\t}\n\t\t\t\t\tserverCmdId = refreshedStatus.cmdId;\n\t\t\t\t\tspinner.text = \"Server already running, attaching...\";\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (didStartServer && !serverCmdId) {\n\t\t\t\tawait cleanupPreviewSession(sessionId);\n\t\t\t\tthrow new CLIError(\n\t\t\t\t\t\"Server start command ID was not returned by the API.\",\n\t\t\t\t\t\"SERVER_START_FAILED\",\n\t\t\t\t\t{ command: devCommand },\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tif (didStartServer && serverCmdId) {\n\t\t\t\tspinner.text = \"Verifying server startup...\";\n\t\t\t\tfor (let attempt = 0; attempt < DEV_SERVER_VERIFY_ATTEMPTS; attempt++) {\n\t\t\t\t\tif (attempt > 0) {\n\t\t\t\t\t\tawait sleep(DEV_SERVER_VERIFY_INTERVAL_MS);\n\t\t\t\t\t}\n\n\t\t\t\t\tconst commandStatus = await api.get<CommandStatusResponse>(\n\t\t\t\t\t\t`/api/mcp/sessions/${sessionId}/commands/${serverCmdId}?statusOnly=true`,\n\t\t\t\t\t);\n\n\t\t\t\t\tif (commandStatus.exitCode === null) {\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst commandOutput = await api\n\t\t\t\t\t\t.get<CommandOutputResponse>(\n\t\t\t\t\t\t\t`/api/mcp/sessions/${sessionId}/commands/${serverCmdId}`,\n\t\t\t\t\t\t)\n\t\t\t\t\t\t.catch(() => null);\n\n\t\t\t\t\tawait cleanupPreviewSession(sessionId);\n\t\t\t\t\tthrow new CLIError(\n\t\t\t\t\t\t`Dev server command exited during startup with code ${commandStatus.exitCode}.`,\n\t\t\t\t\t\t\"SERVER_START_FAILED\",\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcommand: devCommand,\n\t\t\t\t\t\t\tcmdId: serverCmdId,\n\t\t\t\t\t\t\texitCode: commandStatus.exitCode,\n\t\t\t\t\t\t\tstdout: commandOutput?.stdout ?? \"\",\n\t\t\t\t\t\t\tstderr: commandOutput?.stderr ?? \"\",\n\t\t\t\t\t\t},\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tspinner.succeed(\"Development environment ready\");\n\n\t\t\tconsole.log();\n\t\t\tformatSuccess(\"Live preview started!\", false);\n\t\t\tconsole.log();\n\t\t\tif (sandboxId) {\n\t\t\t\tconsole.log(` Sandbox ID: ${sandboxId}`);\n\t\t\t}\n\t\t\tconsole.log(` Preview URL: ${previewUrl}`);\n\t\t\tconsole.log();\n\t\t\tconsole.log(` MCP Inspector:`);\n\t\t\tconsole.log(\n\t\t\t\t` npx @modelcontextprotocol/inspector@latest --transport http --server-url \"${previewUrl}/mcp\"`,\n\t\t\t);\n\t\t\tconsole.log();\n\n\t\t\tif (options.watch !== false) {\n\t\t\t\tconsole.log(\"Watching for file changes... (Ctrl+C to stop)\");\n\t\t\t\tconsole.log();\n\n\t\t\t\t// Step 5: Start file watcher\n\t\t\t\tconst ig = await loadIgnorePatterns(projectRoot, {\n\t\t\t\t\tincludeEnvFiles: true,\n\t\t\t\t});\n\n\t\t\t\tconst watcher = watch(projectRoot, {\n\t\t\t\t\tignored: (path) => {\n\t\t\t\t\t\t// Get relative path from project root\n\t\t\t\t\t\tconst relative = path.replace(`${projectRoot}/`, \"\");\n\t\t\t\t\t\tif (relative === path) return false; // Don't ignore the root\n\t\t\t\t\t\treturn ig.ignores(relative);\n\t\t\t\t\t},\n\t\t\t\t\tpersistent: true,\n\t\t\t\t\tignoreInitial: true,\n\t\t\t\t\tawaitWriteFinish: {\n\t\t\t\t\t\tstabilityThreshold: 100,\n\t\t\t\t\t\tpollInterval: 50,\n\t\t\t\t\t},\n\t\t\t\t});\n\n\t\t\t\tconst syncFile = async (filePath: string) => {\n\t\t\t\t\tconst relativePath = filePath.replace(`${projectRoot}/`, \"\");\n\t\t\t\t\tconst file = await collectSingleFile(projectRoot, relativePath);\n\t\t\t\t\tif (file) {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tawait api.post<WriteFilesResponse>(\n\t\t\t\t\t\t\t\t`/api/mcp/sessions/${sessionId}/files`,\n\t\t\t\t\t\t\t\t{ files: [file] },\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tconsole.log(` Synced: ${relativePath}`);\n\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\tconsole.error(` Failed to sync: ${relativePath}`);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t};\n\n\t\t\t\twatcher.on(\"add\", syncFile);\n\t\t\t\twatcher.on(\"change\", syncFile);\n\t\t\t\twatcher.on(\"unlink\", (filePath) => {\n\t\t\t\t\tconst relativePath = filePath.replace(`${projectRoot}/`, \"\");\n\t\t\t\t\tconsole.log(` Deleted: ${relativePath}`);\n\t\t\t\t});\n\n\t\t\t\tlet shuttingDown = false;\n\t\t\t\tlet serverMonitorInterval: NodeJS.Timeout | null = null;\n\t\t\t\tconst gracefulShutdown = async (exitCode = 0) => {\n\t\t\t\t\tif (shuttingDown) return;\n\t\t\t\t\tshuttingDown = true;\n\t\t\t\t\tif (serverMonitorInterval) {\n\t\t\t\t\t\tclearInterval(serverMonitorInterval);\n\t\t\t\t\t\tserverMonitorInterval = null;\n\t\t\t\t\t}\n\n\t\t\t\t\tconsole.log();\n\t\t\t\t\tconsole.log(\"Stopping development environment...\");\n\n\t\t\t\t\ttry {\n\t\t\t\t\t\tawait withTimeout(\n\t\t\t\t\t\t\t(async () => {\n\t\t\t\t\t\t\t\tawait withTimeout(\n\t\t\t\t\t\t\t\t\twatcher.close().catch(() => undefined),\n\t\t\t\t\t\t\t\t\tSHUTDOWN_STEP_TIMEOUT_MS,\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\tawait cleanupPreviewSession(sessionId);\n\t\t\t\t\t\t\t})(),\n\t\t\t\t\t\t\tSHUTDOWN_MAX_WAIT_MS,\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tonTimeout: () => {\n\t\t\t\t\t\t\t\t\tconsole.log(\"Shutdown timed out, forcing exit.\");\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t);\n\t\t\t\t\t} finally {\n\t\t\t\t\t\tprocess.exit(exitCode);\n\t\t\t\t\t}\n\t\t\t\t};\n\n\t\t\t\tif (serverCmdId) {\n\t\t\t\t\tserverMonitorInterval = setInterval(() => {\n\t\t\t\t\t\tif (shuttingDown) return;\n\t\t\t\t\t\tvoid (async () => {\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\tconst commandStatus = await api.get<CommandStatusResponse>(\n\t\t\t\t\t\t\t\t\t`/api/mcp/sessions/${sessionId}/commands/${serverCmdId}?statusOnly=true`,\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\tif (commandStatus.exitCode === null) {\n\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tif (commandStatus.exitCode === 0) {\n\t\t\t\t\t\t\t\t\tconsole.log(\"Dev server exited (code 0).\");\n\t\t\t\t\t\t\t\t\tawait gracefulShutdown(0);\n\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tconst commandOutput = await getCommandOutputOrNull(\n\t\t\t\t\t\t\t\t\tsessionId,\n\t\t\t\t\t\t\t\t\tserverCmdId,\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\thandleError(\n\t\t\t\t\t\t\t\t\tnew CLIError(\n\t\t\t\t\t\t\t\t\t\t`Dev server exited with code ${commandStatus.exitCode}.`,\n\t\t\t\t\t\t\t\t\t\t\"SERVER_EXITED\",\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\tcommand: devCommand,\n\t\t\t\t\t\t\t\t\t\t\tcmdId: serverCmdId,\n\t\t\t\t\t\t\t\t\t\t\texitCode: commandStatus.exitCode,\n\t\t\t\t\t\t\t\t\t\t\tstdout: commandOutput?.stdout ?? \"\",\n\t\t\t\t\t\t\t\t\t\t\tstderr: commandOutput?.stderr ?? \"\",\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\tjson,\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\tawait gracefulShutdown(1);\n\t\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\t\t// Ignore transient polling errors while watch loop is active.\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t})();\n\t\t\t\t\t}, statusPollIntervalMs);\n\t\t\t\t}\n\n\t\t\t\t// Handle graceful process termination.\n\t\t\t\tprocess.once(\"SIGINT\", () => {\n\t\t\t\t\tvoid gracefulShutdown();\n\t\t\t\t});\n\t\t\t\tprocess.once(\"SIGTERM\", () => {\n\t\t\t\t\tvoid gracefulShutdown();\n\t\t\t\t});\n\n\t\t\t\t// Keep the process running\n\t\t\t\tawait new Promise(() => {});\n\t\t\t}\n\t\t} catch (error) {\n\t\t\thandleError(error, json);\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n","/**\n * Resolve a promise, or return null if it does not settle within timeoutMs.\n */\nexport async function withTimeout<T>(\n\tpromise: Promise<T>,\n\ttimeoutMs: number,\n\toptions?: {\n\t\tonTimeout?: () => void;\n\t},\n): Promise<T | null> {\n\tlet timer: NodeJS.Timeout | undefined;\n\n\ttry {\n\t\treturn await Promise.race([\n\t\t\tpromise,\n\t\t\tnew Promise<null>((resolve) => {\n\t\t\t\ttimer = setTimeout(() => {\n\t\t\t\t\toptions?.onTimeout?.();\n\t\t\t\t\tresolve(null);\n\t\t\t\t}, timeoutMs);\n\t\t\t}),\n\t\t]);\n\t} finally {\n\t\tif (timer) {\n\t\t\tclearTimeout(timer);\n\t\t}\n\t}\n}\n","import chalk from \"chalk\";\nimport { Command } from \"commander\";\nimport ora from \"ora\";\nimport { api } from \"../../lib/api.js\";\nimport { handleError } from \"../../lib/errors.js\";\nimport { formatOutput } from \"../../lib/output.js\";\nimport { requireMcpId, requireSessionId } from \"../../lib/utils.js\";\nimport type { RunCommandResponse } from \"../../types/index.js\";\n\nexport const runCommandCommand = new Command(\"run-command\")\n\t.description(\"Run a command in the MCP sandbox\")\n\t.argument(\"<command>\", \"Command to run\")\n\t.argument(\"[args...]\", \"Command arguments\")\n\t.option(\"--mcp-id <id>\", \"Specific MCP ID\")\n\t.option(\"--cwd <path>\", \"Working directory\")\n\t.option(\n\t\t\"--timeout <ms>\",\n\t\t\"Command timeout in milliseconds (default: 30000, max: 300000)\",\n\t)\n\t.action(async (cmd: string, args: string[], options, command) => {\n\t\tconst globalOptions = command.optsWithGlobals();\n\t\tconst json = globalOptions.json ?? false;\n\n\t\ttry {\n\t\t\tawait requireMcpId(options.mcpId);\n\t\t\tconst sessionId = await requireSessionId();\n\n\t\t\tconst timeout = options.timeout\n\t\t\t\t? Number.parseInt(options.timeout, 10)\n\t\t\t\t: undefined;\n\n\t\t\tconst spinner = ora(`Running: ${cmd} ${args.join(\" \")}`.trim()).start();\n\n\t\t\tconst result = await api.post<RunCommandResponse>(\n\t\t\t\t`/api/mcp/sessions/${sessionId}/commands`,\n\t\t\t\t{\n\t\t\t\t\tcommand: cmd,\n\t\t\t\t\targs: args.length > 0 ? args : undefined,\n\t\t\t\t\tcwd: options.cwd,\n\t\t\t\t\ttimeout,\n\t\t\t\t},\n\t\t\t);\n\n\t\t\tspinner.stop();\n\n\t\t\tif (json) {\n\t\t\t\tformatOutput(result, true);\n\t\t\t} else {\n\t\t\t\t// Show command\n\t\t\t\tconst cmdLine = [cmd, ...args].join(\" \");\n\t\t\t\tconsole.log(chalk.gray(`$ ${cmdLine}`));\n\t\t\t\tconsole.log();\n\n\t\t\t\t// Show stdout\n\t\t\t\tif (result.stdout) {\n\t\t\t\t\tprocess.stdout.write(result.stdout);\n\t\t\t\t\tif (!result.stdout.endsWith(\"\\n\")) {\n\t\t\t\t\t\tprocess.stdout.write(\"\\n\");\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Show stderr\n\t\t\t\tif (result.stderr) {\n\t\t\t\t\tprocess.stderr.write(chalk.red(result.stderr));\n\t\t\t\t\tif (!result.stderr.endsWith(\"\\n\")) {\n\t\t\t\t\t\tprocess.stderr.write(\"\\n\");\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Show exit code and duration\n\t\t\t\tconsole.log();\n\t\t\t\tconst exitColor = result.exitCode === 0 ? chalk.green : chalk.red;\n\t\t\t\tconsole.log(\n\t\t\t\t\texitColor(`Exit code: ${result.exitCode}`),\n\t\t\t\t\tchalk.gray(`(${(result.duration / 1000).toFixed(2)}s)`),\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// Exit with the command's exit code\n\t\t\tif (result.exitCode !== 0) {\n\t\t\t\tprocess.exit(result.exitCode);\n\t\t\t}\n\t\t} catch (error) {\n\t\t\thandleError(error, json);\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n","import chalk from \"chalk\";\nimport { Command } from \"commander\";\nimport ora from \"ora\";\nimport { api } from \"../../lib/api.js\";\nimport { handleError } from \"../../lib/errors.js\";\nimport { formatList, formatOutput } from \"../../lib/output.js\";\nimport { requireMcpId } from \"../../lib/utils.js\";\nimport type { McpRepository, ServerStatusResponse } from \"../../types/index.js\";\n\nexport const statusCommand = new Command(\"status\")\n\t.description(\"Show current MCP status\")\n\t.option(\"--mcp-id <id>\", \"Specific MCP ID\")\n\t.action(async (options, command) => {\n\t\tconst globalOptions = command.optsWithGlobals();\n\t\tconst json = globalOptions.json ?? false;\n\n\t\ttry {\n\t\t\tconst mcpId = await requireMcpId(options.mcpId);\n\n\t\t\tconst spinner = ora(\"Fetching MCP status...\").start();\n\n\t\t\tconst result = await api.get<McpRepository>(\n\t\t\t\t`/api/mcp/repositories/${mcpId}`,\n\t\t\t);\n\n\t\t\t// Fetch server status if sandbox is active\n\t\t\tlet serverStatus: ServerStatusResponse | null = null;\n\t\t\tif (result.activeSandbox) {\n\t\t\t\tserverStatus = await api\n\t\t\t\t\t.post<ServerStatusResponse>(\n\t\t\t\t\t\t`/api/mcp/sessions/${result.activeSandbox.id}/server`,\n\t\t\t\t\t\t{ action: \"status\" },\n\t\t\t\t\t)\n\t\t\t\t\t.catch(() => null);\n\t\t\t}\n\n\t\t\tspinner.stop();\n\n\t\t\tif (json) {\n\t\t\t\tformatOutput({ ...result, server: serverStatus }, true);\n\t\t\t} else {\n\t\t\t\tconst deployStatus = result.deployedAt\n\t\t\t\t\t? chalk.green(\"Deployed\")\n\t\t\t\t\t: chalk.yellow(\"Pending\");\n\n\t\t\t\tconst items = [\n\t\t\t\t\t{ label: \"Name\", value: result.name },\n\t\t\t\t\t{ label: \"MCP ID\", value: result.id },\n\t\t\t\t\t{ label: \"Status\", value: deployStatus },\n\t\t\t\t\t{\n\t\t\t\t\t\tlabel: \"Last Deploy\",\n\t\t\t\t\t\tvalue: result.deployedAt\n\t\t\t\t\t\t\t? new Date(result.deployedAt).toLocaleString()\n\t\t\t\t\t\t\t: chalk.gray(\"Never\"),\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tlabel: \"Created\",\n\t\t\t\t\t\tvalue: new Date(result.createdAt).toLocaleString(),\n\t\t\t\t\t},\n\t\t\t\t];\n\n\t\t\t\t// Add sandbox info if active\n\t\t\t\tif (result.activeSandbox) {\n\t\t\t\t\tconst sandbox = result.activeSandbox;\n\t\t\t\t\tconst serverRunning = serverStatus?.running ?? sandbox.serverRunning;\n\t\t\t\t\tconst serverStatusColor = serverRunning ? chalk.green : chalk.yellow;\n\n\t\t\t\t\titems.push(\n\t\t\t\t\t\t{ label: \"\", value: \"\" }, // Separator\n\t\t\t\t\t\t{ label: \"Sandbox\", value: chalk.green(\"Active\") },\n\t\t\t\t\t\t{ label: \"Preview URL\", value: sandbox.previewUrl },\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tlabel: \"Server\",\n\t\t\t\t\t\t\tvalue: serverStatusColor(serverRunning ? \"Running\" : \"Stopped\"),\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tlabel: \"Expires\",\n\t\t\t\t\t\t\tvalue: sandbox.expiresAt\n\t\t\t\t\t\t\t\t? new Date(sandbox.expiresAt).toLocaleString()\n\t\t\t\t\t\t\t\t: chalk.gray(\"N/A\"),\n\t\t\t\t\t\t},\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\titems.push(\n\t\t\t\t\t\t{ label: \"\", value: \"\" }, // Separator\n\t\t\t\t\t\t{ label: \"Sandbox\", value: chalk.gray(\"None\") },\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\tformatList(items, false);\n\n\t\t\t\tconsole.log();\n\t\t\t\tif (!result.activeSandbox) {\n\t\t\t\t\tconsole.log(\"Start development: waniwani mcp preview\");\n\t\t\t\t} else if (!serverStatus?.running) {\n\t\t\t\t\tconsole.log(\"View logs: waniwani mcp logs\");\n\t\t\t\t}\n\t\t\t}\n\t\t} catch (error) {\n\t\t\thandleError(error, json);\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n","import { Command } from \"commander\";\nimport ora from \"ora\";\nimport { api } from \"../../lib/api.js\";\nimport { config } from \"../../lib/config.js\";\nimport { handleError } from \"../../lib/errors.js\";\nimport { formatOutput, formatSuccess } from \"../../lib/output.js\";\nimport { requireMcpId, requireSessionId } from \"../../lib/utils.js\";\n\nexport const stopCommand = new Command(\"stop\")\n\t.description(\"Stop the development environment (sandbox + server)\")\n\t.option(\"--mcp-id <id>\", \"Specific MCP ID\")\n\t.action(async (options, command) => {\n\t\tconst globalOptions = command.optsWithGlobals();\n\t\tconst json = globalOptions.json ?? false;\n\n\t\ttry {\n\t\t\tawait requireMcpId(options.mcpId);\n\t\t\tconst sessionId = await requireSessionId();\n\n\t\t\tconst spinner = ora(\"Stopping development environment...\").start();\n\n\t\t\t// Stop server first\n\t\t\ttry {\n\t\t\t\tawait api.post(`/api/mcp/sessions/${sessionId}/server`, {\n\t\t\t\t\taction: \"stop\",\n\t\t\t\t});\n\t\t\t} catch {\n\t\t\t\t// Server might not be running, continue\n\t\t\t}\n\n\t\t\t// Delete session\n\t\t\tawait api.delete(`/api/mcp/sessions/${sessionId}`);\n\n\t\t\t// Clear session from config\n\t\t\tawait config.setSessionId(null);\n\n\t\t\tspinner.succeed(\"Development environment stopped\");\n\n\t\t\tif (json) {\n\t\t\t\tformatOutput({ stopped: true }, true);\n\t\t\t} else {\n\t\t\t\tformatSuccess(\"Sandbox stopped.\", false);\n\t\t\t\tconsole.log();\n\t\t\t\tconsole.log(\"Start again: waniwani mcp preview\");\n\t\t\t}\n\t\t} catch (error) {\n\t\t\thandleError(error, json);\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n","import { Command } from \"commander\";\nimport ora from \"ora\";\nimport { CLIError, handleError } from \"../../lib/errors.js\";\nimport { formatOutput, formatSuccess } from \"../../lib/output.js\";\nimport { findProjectRoot, pullFilesFromGithub } from \"../../lib/sync.js\";\nimport { requireMcpId } from \"../../lib/utils.js\";\n\nexport const syncCommand = new Command(\"sync\")\n\t.description(\"Pull template files to local project\")\n\t.option(\"--mcp-id <id>\", \"Specific MCP ID\")\n\t.action(async (options, command) => {\n\t\tconst globalOptions = command.optsWithGlobals();\n\t\tconst json = globalOptions.json ?? false;\n\n\t\ttry {\n\t\t\tconst mcpId = await requireMcpId(options.mcpId);\n\n\t\t\t// Find project root\n\t\t\tconst projectRoot = await findProjectRoot(process.cwd());\n\t\t\tif (!projectRoot) {\n\t\t\t\tthrow new CLIError(\n\t\t\t\t\t\"Not in a WaniWani project. Run 'waniwani mcp create <name>' first.\",\n\t\t\t\t\t\"NOT_IN_PROJECT\",\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst spinner = ora(\"Pulling files...\").start();\n\n\t\t\tconst result = await pullFilesFromGithub(mcpId, projectRoot);\n\n\t\t\tspinner.succeed(`Pulled ${result.count} files`);\n\n\t\t\tif (json) {\n\t\t\t\tformatOutput({ files: result.files }, true);\n\t\t\t} else {\n\t\t\t\tconsole.log();\n\t\t\t\tformatSuccess(\"Files synced!\", false);\n\t\t\t\tif (result.files.length > 0 && result.files.length <= 10) {\n\t\t\t\t\tconsole.log();\n\t\t\t\t\tfor (const file of result.files) {\n\t\t\t\t\t\tconsole.log(` ${file}`);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} catch (error) {\n\t\t\thandleError(error, json);\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n","import { Command } from \"commander\";\nimport ora from \"ora\";\nimport { api } from \"../../lib/api.js\";\nimport { config } from \"../../lib/config.js\";\nimport { handleError, McpError } from \"../../lib/errors.js\";\nimport { formatOutput, formatSuccess } from \"../../lib/output.js\";\nimport type {\n\tMcpRepository,\n\tMcpRepositoryListResponse,\n} from \"../../types/index.js\";\n\nexport const useCommand = new Command(\"use\")\n\t.description(\"Select an MCP to use for subsequent commands\")\n\t.argument(\"<name>\", \"Name of the MCP to use\")\n\t.action(async (name: string, _options, command) => {\n\t\tconst globalOptions = command.optsWithGlobals();\n\t\tconst json = globalOptions.json ?? false;\n\n\t\ttry {\n\t\t\tconst spinner = ora(\"Fetching MCPs...\").start();\n\n\t\t\t// Fetch all MCPs\n\t\t\tconst mcps = await api.get<McpRepositoryListResponse>(\n\t\t\t\t\"/api/mcp/repositories\",\n\t\t\t);\n\n\t\t\tspinner.stop();\n\n\t\t\t// Find MCP by name\n\t\t\tconst mcp = mcps.find((m: McpRepository) => m.name === name);\n\n\t\t\tif (!mcp) {\n\t\t\t\tthrow new McpError(\n\t\t\t\t\t`MCP \"${name}\" not found. Run 'waniwani mcp list' to see available MCPs.`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tawait config.setMcpId(mcp.id);\n\t\t\t// Clear session since we're switching MCPs\n\t\t\tawait config.setSessionId(null);\n\n\t\t\tif (json) {\n\t\t\t\tformatOutput({ selected: mcp }, true);\n\t\t\t} else {\n\t\t\t\tformatSuccess(`Now using MCP \"${name}\"`, false);\n\t\t\t\tconsole.log();\n\t\t\t\tconsole.log(` MCP ID: ${mcp.id}`);\n\t\t\t\tconsole.log();\n\t\t\t\tconsole.log(\"Next steps:\");\n\t\t\t\tconsole.log(\" waniwani mcp preview # Start live preview\");\n\t\t\t\tconsole.log(\" waniwani mcp status # Check status\");\n\t\t\t}\n\t\t} catch (error) {\n\t\t\thandleError(error, json);\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n","import { Command } from \"commander\";\nimport { listCommand } from \"./list.js\";\nimport { switchCommand } from \"./switch.js\";\n\nexport const orgCommand = new Command(\"org\")\n\t.description(\"Organization management commands\")\n\t.addCommand(listCommand)\n\t.addCommand(switchCommand);\n","import chalk from \"chalk\";\nimport { Command } from \"commander\";\nimport ora from \"ora\";\nimport { api } from \"../../lib/api.js\";\nimport { handleError } from \"../../lib/errors.js\";\nimport { formatOutput, formatTable } from \"../../lib/output.js\";\nimport type { Org, OrgListResponse } from \"../../types/index.js\";\n\nexport const listCommand = new Command(\"list\")\n\t.description(\"List your organizations\")\n\t.action(async (_options, command) => {\n\t\tconst globalOptions = command.optsWithGlobals();\n\t\tconst json = globalOptions.json ?? false;\n\n\t\ttry {\n\t\t\tconst spinner = ora(\"Fetching organizations...\").start();\n\n\t\t\tconst result = await api.get<OrgListResponse>(\"/api/oauth/orgs\");\n\n\t\t\tspinner.stop();\n\n\t\t\tconst { orgs, activeOrgId } = result;\n\n\t\t\tif (json) {\n\t\t\t\tformatOutput(\n\t\t\t\t\t{\n\t\t\t\t\t\torgs: orgs.map((o: Org) => ({\n\t\t\t\t\t\t\t...o,\n\t\t\t\t\t\t\tisActive: o.id === activeOrgId,\n\t\t\t\t\t\t})),\n\t\t\t\t\t\tactiveOrgId,\n\t\t\t\t\t},\n\t\t\t\t\ttrue,\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tif (orgs.length === 0) {\n\t\t\t\t\tconsole.log(\"No organizations found.\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconsole.log(chalk.bold(\"\\nOrganizations:\\n\"));\n\n\t\t\t\tconst rows = orgs.map((o: Org) => {\n\t\t\t\t\tconst isActive = o.id === activeOrgId;\n\t\t\t\t\treturn [\n\t\t\t\t\t\tisActive ? chalk.cyan(`* ${o.name}`) : ` ${o.name}`,\n\t\t\t\t\t\to.slug,\n\t\t\t\t\t\to.role,\n\t\t\t\t\t];\n\t\t\t\t});\n\n\t\t\t\tformatTable([\"Name\", \"Slug\", \"Role\"], rows, false);\n\n\t\t\t\tconsole.log();\n\t\t\t\tif (activeOrgId) {\n\t\t\t\t\tconst activeOrg = orgs.find((o: Org) => o.id === activeOrgId);\n\t\t\t\t\tif (activeOrg) {\n\t\t\t\t\t\tconsole.log(`Active organization: ${chalk.cyan(activeOrg.name)}`);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tconsole.log(\"\\nSwitch organization: waniwani org switch <name>\");\n\t\t\t}\n\t\t} catch (error) {\n\t\t\thandleError(error, json);\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n","import { Command } from \"commander\";\nimport ora from \"ora\";\nimport { api } from \"../../lib/api.js\";\nimport { config } from \"../../lib/config.js\";\nimport { CLIError, handleError } from \"../../lib/errors.js\";\nimport { formatOutput, formatSuccess } from \"../../lib/output.js\";\nimport type {\n\tOrg,\n\tOrgListResponse,\n\tOrgSwitchResponse,\n} from \"../../types/index.js\";\n\nexport const switchCommand = new Command(\"switch\")\n\t.description(\"Switch to a different organization\")\n\t.argument(\"<name>\", \"Name or slug of the organization to switch to\")\n\t.action(async (name: string, _options, command) => {\n\t\tconst globalOptions = command.optsWithGlobals();\n\t\tconst json = globalOptions.json ?? false;\n\n\t\ttry {\n\t\t\tconst spinner = ora(\"Fetching organizations...\").start();\n\n\t\t\t// First fetch orgs to find the org ID\n\t\t\tconst { orgs } = await api.get<OrgListResponse>(\"/api/oauth/orgs\");\n\n\t\t\t// Find org by name or slug\n\t\t\tconst org = orgs.find((o: Org) => o.name === name || o.slug === name);\n\n\t\t\tif (!org) {\n\t\t\t\tspinner.stop();\n\t\t\t\tthrow new CLIError(\n\t\t\t\t\t`Organization \"${name}\" not found. Run 'waniwani org list' to see available organizations.`,\n\t\t\t\t\t\"ORG_NOT_FOUND\",\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tspinner.text = \"Switching organization...\";\n\n\t\t\t// Switch to the org\n\t\t\tawait api.post<OrgSwitchResponse>(\"/api/oauth/orgs/switch\", {\n\t\t\t\torgId: org.id,\n\t\t\t});\n\n\t\t\tspinner.succeed(\"Organization switched\");\n\n\t\t\t// Clear local MCP selection since we switched orgs\n\t\t\tconfig.setMcpId(null);\n\n\t\t\tif (json) {\n\t\t\t\tformatOutput({ switched: org }, true);\n\t\t\t} else {\n\t\t\t\tformatSuccess(`Switched to organization \"${org.name}\"`, false);\n\t\t\t\tconsole.log();\n\t\t\t\tconsole.log(\"Note: Active MCP selection has been cleared.\");\n\t\t\t\tconsole.log(\n\t\t\t\t\t\"Run 'waniwani mcp list' to see MCPs in this organization.\",\n\t\t\t\t);\n\t\t\t}\n\t\t} catch (error) {\n\t\t\thandleError(error, json);\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n","import { program } from \"./cli.js\";\n\nprogram.parse(process.argv);\n"],"mappings":"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","names":["Command","Command","existsSync","join","chalk","chalk","join","existsSync","Command","join","Command","join","join","auth","existsSync","mkdir","readFile","writeFile","join","existsSync","join","readFile","mkdir","writeFile","Command","join","chalk","Command","Command","chalk","Command","Command","Command","execFileSync","existsSync","readFile","join","Command","ora","execFileSync","join","existsSync","readFile","config","Command","ora","execFileSync","execFileSync","execSync","existsSync","readFile","join","Command","ora","loadParentConfig","join","existsSync","readFile","config","checkGitInstalled","execSync","Command","ora","execFileSync","chalk","Command","ora","Command","chalk","ora","Command","chalk","Command","ora","Command","ora","chalk","writeFile","Command","ora","Command","ora","writeFile","readFile","Command","ora","Command","readFile","ora","Command","chalk","Command","ora","listCommand","Command","ora","chalk","chalk","Command","ora","Command","ora","chalk","existsSync","join","Command","ora","existsSync","join","Command","ora","relative","chalk","Command","ora","Command","ora","chalk","chalk","Command","ora","Command","ora","chalk","Command","ora","Command","ora","Command","ora","Command","ora","Command","ora","Command","ora","Command","listCommand","Command","chalk","Command","ora","listCommand","Command","ora","chalk","Command","ora","Command","ora","Command","listCommand","require","Command"]}
|
|
1
|
+
{"version":3,"sources":["../src/cli.ts","../src/commands/config/index.ts","../src/commands/config/init.ts","../src/lib/config.ts","../src/lib/errors.ts","../src/lib/output.ts","../src/commands/git-credential-helper.ts","../src/lib/git-auth.ts","../src/lib/auth.ts","../src/lib/api.ts","../src/lib/sync.ts","../src/lib/utils.ts","../src/commands/login.ts","../src/commands/logout.ts","../src/commands/mcp/index.ts","../src/commands/mcp/clone.ts","../src/lib/credential-helper-setup.ts","../src/commands/mcp/create.ts","../src/commands/mcp/delete.ts","../src/commands/mcp/file/index.ts","../src/commands/mcp/file/list.ts","../src/commands/mcp/file/read.ts","../src/commands/mcp/file/write.ts","../src/commands/mcp/list.ts","../src/commands/mcp/logs.ts","../src/commands/mcp/preview.ts","../src/lib/async.ts","../src/commands/mcp/run-command.ts","../src/commands/mcp/status.ts","../src/commands/mcp/stop.ts","../src/commands/mcp/sync.ts","../src/commands/mcp/use.ts","../src/commands/org/index.ts","../src/commands/org/current.ts","../src/commands/org/list.ts","../src/commands/org/switch.ts","../src/index.ts"],"sourcesContent":["import { createRequire } from \"node:module\";\nimport { Command } from \"commander\";\nimport { configCommand } from \"./commands/config/index.js\";\nimport { gitCredentialHelperCommand } from \"./commands/git-credential-helper.js\";\nimport { loginCommand } from \"./commands/login.js\";\nimport { logoutCommand } from \"./commands/logout.js\";\nimport { mcpCommand } from \"./commands/mcp/index.js\";\nimport { orgCommand } from \"./commands/org/index.js\";\n\nconst require = createRequire(import.meta.url);\nconst { version } = require(\"../package.json\") as { version: string };\n\nexport const program = new Command()\n\t.name(\"waniwani\")\n\t.description(\"WaniWani CLI for MCP development workflow\")\n\t.version(version)\n\t.option(\"--json\", \"Output results as JSON\")\n\t.option(\"--verbose\", \"Enable verbose logging\");\n\n// Auth commands\nprogram.addCommand(loginCommand);\nprogram.addCommand(logoutCommand);\n\n// Main commands\nprogram.addCommand(mcpCommand);\nprogram.addCommand(orgCommand);\nprogram.addCommand(configCommand);\n\n// Git integration (called by git, not users)\nprogram.addCommand(gitCredentialHelperCommand);\n","import { Command } from \"commander\";\nimport { configInitCommand } from \"./init.js\";\n\nexport const configCommand = new Command(\"config\")\n\t.description(\"Manage WaniWani configuration\")\n\t.addCommand(configInitCommand);\n","import { existsSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { Command } from \"commander\";\nimport {\n\tCONFIG_FILE_NAME,\n\tinitConfigAt,\n\tLOCAL_CONFIG_DIR,\n} from \"../../lib/config.js\";\nimport { CLIError, handleError } from \"../../lib/errors.js\";\nimport { formatOutput, formatSuccess } from \"../../lib/output.js\";\n\nexport const configInitCommand = new Command(\"init\")\n\t.description(\"Initialize .waniwani config in the current directory\")\n\t.option(\"--force\", \"Overwrite existing config\")\n\t.action(async (options, command) => {\n\t\tconst globalOptions = command.optsWithGlobals();\n\t\tconst json = globalOptions.json ?? false;\n\n\t\ttry {\n\t\t\tconst cwd = process.cwd();\n\t\t\tconst configPath = join(cwd, LOCAL_CONFIG_DIR, CONFIG_FILE_NAME);\n\n\t\t\t// Check if config already exists\n\t\t\tif (existsSync(configPath) && !options.force) {\n\t\t\t\tthrow new CLIError(\n\t\t\t\t\t`Config already exists at ${configPath}. Use --force to overwrite.`,\n\t\t\t\t\t\"CONFIG_EXISTS\",\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// Create .waniwani/settings.json with defaults\n\t\t\tconst result = await initConfigAt(cwd);\n\n\t\t\tif (json) {\n\t\t\t\tformatOutput({ created: result.path, config: result.config }, true);\n\t\t\t} else {\n\t\t\t\tformatSuccess(`Created ${result.path}`, false);\n\t\t\t}\n\t\t} catch (error) {\n\t\t\thandleError(error, json);\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n","import { existsSync } from \"node:fs\";\nimport { chmod, mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { z } from \"zod\";\n\nexport const LOCAL_CONFIG_DIR = \".waniwani\";\nexport const CONFIG_FILE_NAME = \"settings.json\";\n\nconst LOCAL_DIR = join(process.cwd(), LOCAL_CONFIG_DIR);\nconst LOCAL_FILE = join(LOCAL_DIR, CONFIG_FILE_NAME);\nconst DEFAULT_API_URL = \"https://app.waniwani.ai\";\nconst CONFIG_DIR_MODE = 0o700;\nconst CONFIG_FILE_MODE = 0o600;\n\nconst ConfigSchema = z.object({\n\t// Settings\n\tsessionId: z.string().nullable().default(null),\n\tmcpId: z.string().nullable().default(null),\n\tapiUrl: z.string().default(DEFAULT_API_URL),\n\t// Auth (merged from auth.json)\n\taccessToken: z.string().nullable().default(null),\n\trefreshToken: z.string().nullable().default(null),\n\texpiresAt: z.string().nullable().default(null),\n\tclientId: z.string().nullable().default(null),\n});\n\ntype ConfigData = z.infer<typeof ConfigSchema>;\n\nclass Config {\n\tprivate dir: string;\n\tprivate file: string;\n\tprivate cache: ConfigData | null = null;\n\n\tconstructor() {\n\t\tthis.dir = LOCAL_DIR;\n\t\tthis.file = LOCAL_FILE;\n\t}\n\n\tprivate async setSecurePermissions(): Promise<void> {\n\t\tawait chmod(this.dir, CONFIG_DIR_MODE);\n\t\tawait chmod(this.file, CONFIG_FILE_MODE);\n\t}\n\n\tprivate async load(): Promise<ConfigData> {\n\t\tif (!this.cache) {\n\t\t\ttry {\n\t\t\t\tthis.cache = ConfigSchema.parse(\n\t\t\t\t\tJSON.parse(await readFile(this.file, \"utf-8\")),\n\t\t\t\t);\n\t\t\t} catch {\n\t\t\t\tthis.cache = ConfigSchema.parse({});\n\t\t\t}\n\t\t}\n\t\treturn this.cache;\n\t}\n\n\tprivate async save(data: ConfigData): Promise<void> {\n\t\tthis.cache = data;\n\t\tawait mkdir(this.dir, { recursive: true, mode: CONFIG_DIR_MODE });\n\t\tawait writeFile(this.file, JSON.stringify(data, null, \"\\t\"));\n\t\tawait this.setSecurePermissions();\n\t}\n\n\t/**\n\t * Ensure the .waniwani directory exists in cwd.\n\t * Used by login to create config before saving tokens.\n\t */\n\tasync ensureConfigDir(): Promise<void> {\n\t\tawait mkdir(this.dir, { recursive: true, mode: CONFIG_DIR_MODE });\n\t\tawait chmod(this.dir, CONFIG_DIR_MODE);\n\t}\n\n\t/**\n\t * Check if a .waniwani config directory exists in cwd.\n\t */\n\thasConfig(): boolean {\n\t\treturn existsSync(this.dir);\n\t}\n\n\t// --- Settings methods ---\n\n\tasync getMcpId() {\n\t\treturn (await this.load()).mcpId;\n\t}\n\n\tasync setMcpId(id: string | null) {\n\t\tconst data = await this.load();\n\t\tdata.mcpId = id;\n\t\tawait this.save(data);\n\t}\n\n\tasync getSessionId() {\n\t\treturn (await this.load()).sessionId;\n\t}\n\n\tasync setSessionId(id: string | null) {\n\t\tconst data = await this.load();\n\t\tdata.sessionId = id;\n\t\tawait this.save(data);\n\t}\n\n\tasync getApiUrl() {\n\t\tif (process.env.WANIWANI_API_URL) return process.env.WANIWANI_API_URL;\n\t\treturn (await this.load()).apiUrl;\n\t}\n\n\tasync clear() {\n\t\tawait this.save(ConfigSchema.parse({}));\n\t}\n\n\t// --- Auth methods ---\n\n\tasync getAccessToken(): Promise<string | null> {\n\t\treturn (await this.load()).accessToken;\n\t}\n\n\tasync getRefreshToken(): Promise<string | null> {\n\t\treturn (await this.load()).refreshToken;\n\t}\n\n\tasync getClientId(): Promise<string | null> {\n\t\treturn (await this.load()).clientId;\n\t}\n\n\tasync setTokens(\n\t\taccessToken: string,\n\t\trefreshToken: string,\n\t\texpiresIn: number,\n\t\tclientId?: string,\n\t): Promise<void> {\n\t\tconst expiresAt = new Date(Date.now() + expiresIn * 1000).toISOString();\n\t\tconst data = await this.load();\n\t\tdata.accessToken = accessToken;\n\t\tdata.refreshToken = refreshToken;\n\t\tdata.expiresAt = expiresAt;\n\t\tif (clientId) {\n\t\t\tdata.clientId = clientId;\n\t\t}\n\t\tawait this.save(data);\n\t}\n\n\tasync clearAuth(): Promise<void> {\n\t\tconst data = await this.load();\n\t\tdata.accessToken = null;\n\t\tdata.refreshToken = null;\n\t\tdata.expiresAt = null;\n\t\tdata.clientId = null;\n\t\tawait this.save(data);\n\t}\n\n\tasync isTokenExpired(): Promise<boolean> {\n\t\tconst data = await this.load();\n\t\tif (!data.expiresAt) return true;\n\t\t// Consider expired 5 minutes before actual expiry\n\t\treturn new Date(data.expiresAt).getTime() - 5 * 60 * 1000 < Date.now();\n\t}\n}\n\nexport const config = new Config();\n\n/**\n * Initialize a .waniwani/settings.json at the given directory.\n * Returns the created config data and path.\n */\nexport async function initConfigAt(\n\tdir: string,\n\toverrides: Partial<ConfigData> = {},\n): Promise<{ path: string; config: ConfigData }> {\n\tconst configDir = join(dir, LOCAL_CONFIG_DIR);\n\tconst configPath = join(configDir, CONFIG_FILE_NAME);\n\n\tawait mkdir(configDir, { recursive: true, mode: CONFIG_DIR_MODE });\n\n\tconst data = ConfigSchema.parse(overrides);\n\tawait writeFile(configPath, JSON.stringify(data, null, \"\\t\"), \"utf-8\");\n\tawait chmod(configDir, CONFIG_DIR_MODE);\n\tawait chmod(configPath, CONFIG_FILE_MODE);\n\n\treturn { path: configPath, config: data };\n}\n","import chalk from \"chalk\";\nimport { ZodError } from \"zod\";\n\nexport class CLIError extends Error {\n\tconstructor(\n\t\tmessage: string,\n\t\tpublic code: string,\n\t\tpublic details?: Record<string, unknown>,\n\t) {\n\t\tsuper(message);\n\t\tthis.name = \"CLIError\";\n\t}\n}\n\nexport class ConfigError extends CLIError {\n\tconstructor(message: string, details?: Record<string, unknown>) {\n\t\tsuper(message, \"CONFIG_ERROR\", details);\n\t}\n}\n\nexport class AuthError extends CLIError {\n\tconstructor(message: string, details?: Record<string, unknown>) {\n\t\tsuper(message, \"AUTH_ERROR\", details);\n\t}\n}\n\nexport class SandboxError extends CLIError {\n\tconstructor(message: string, details?: Record<string, unknown>) {\n\t\tsuper(message, \"SANDBOX_ERROR\", details);\n\t}\n}\n\nexport class GitHubError extends CLIError {\n\tconstructor(message: string, details?: Record<string, unknown>) {\n\t\tsuper(message, \"GITHUB_ERROR\", details);\n\t}\n}\n\nexport class McpError extends CLIError {\n\tconstructor(message: string, details?: Record<string, unknown>) {\n\t\tsuper(message, \"MCP_ERROR\", details);\n\t}\n}\n\nexport function handleError(error: unknown, json: boolean): void {\n\tif (error instanceof ZodError) {\n\t\tconst message = error.issues\n\t\t\t.map((e) => `${e.path.join(\".\")}: ${e.message}`)\n\t\t\t.join(\", \");\n\t\toutputError(\"VALIDATION_ERROR\", `Invalid input: ${message}`, json);\n\t} else if (error instanceof CLIError) {\n\t\toutputError(error.code, error.message, json, error.details);\n\t} else if (error instanceof Error) {\n\t\toutputError(\"UNKNOWN_ERROR\", error.message, json);\n\t} else {\n\t\toutputError(\"UNKNOWN_ERROR\", String(error), json);\n\t}\n}\n\nfunction outputError(\n\tcode: string,\n\tmessage: string,\n\tjson: boolean,\n\tdetails?: Record<string, unknown>,\n): void {\n\tif (json) {\n\t\tconsole.error(\n\t\t\tJSON.stringify({ success: false, error: { code, message, details } }),\n\t\t);\n\t} else {\n\t\tconsole.error(chalk.red(`Error [${code}]:`), message);\n\t\tif (details) {\n\t\t\tconsole.error(chalk.gray(\"Details:\"), JSON.stringify(details, null, 2));\n\t\t}\n\t}\n}\n","import chalk from \"chalk\";\n\nexport function formatOutput<T>(data: T, json: boolean): void {\n\tif (json) {\n\t\tconsole.log(JSON.stringify({ success: true, data }, null, 2));\n\t} else {\n\t\tprettyPrint(data);\n\t}\n}\n\nexport function formatSuccess(message: string, json: boolean): void {\n\tif (json) {\n\t\tconsole.log(JSON.stringify({ success: true, message }));\n\t} else {\n\t\tconsole.log(chalk.green(\"✓\"), message);\n\t}\n}\n\nexport function formatError(error: Error | string, json: boolean): void {\n\tconst message = error instanceof Error ? error.message : error;\n\tif (json) {\n\t\tconsole.error(JSON.stringify({ success: false, error: message }));\n\t} else {\n\t\tconsole.error(chalk.red(\"✗\"), message);\n\t}\n}\n\nexport function formatTable(\n\theaders: string[],\n\trows: string[][],\n\tjson: boolean,\n): void {\n\tif (json) {\n\t\tconst data = rows.map((row) =>\n\t\t\tObject.fromEntries(headers.map((header, i) => [header, row[i]])),\n\t\t);\n\t\tconsole.log(JSON.stringify({ success: true, data }, null, 2));\n\t} else {\n\t\t// Simple table formatting without external dependency\n\t\tconst colWidths = headers.map((h, i) =>\n\t\t\tMath.max(h.length, ...rows.map((r) => (r[i] || \"\").length)),\n\t\t);\n\n\t\tconst separator = colWidths.map((w) => \"-\".repeat(w + 2)).join(\"+\");\n\t\tconst formatRow = (row: string[]) =>\n\t\t\trow.map((cell, i) => ` ${(cell || \"\").padEnd(colWidths[i])} `).join(\"|\");\n\n\t\tconsole.log(chalk.cyan(formatRow(headers)));\n\t\tconsole.log(separator);\n\t\tfor (const row of rows) {\n\t\t\tconsole.log(formatRow(row));\n\t\t}\n\t}\n}\n\nexport function formatList(\n\titems: Array<{ label: string; value: string }>,\n\tjson: boolean,\n): void {\n\tif (json) {\n\t\tconst data = Object.fromEntries(\n\t\t\titems.map((item) => [item.label, item.value]),\n\t\t);\n\t\tconsole.log(JSON.stringify({ success: true, data }, null, 2));\n\t} else {\n\t\tconst maxLabelLength = Math.max(...items.map((i) => i.label.length));\n\t\titems.forEach((item) => {\n\t\t\tconsole.log(\n\t\t\t\t`${chalk.gray(item.label.padEnd(maxLabelLength))} ${chalk.white(item.value)}`,\n\t\t\t);\n\t\t});\n\t}\n}\n\nfunction prettyPrint(data: unknown, indent = 0): void {\n\tconst prefix = \" \".repeat(indent);\n\n\tif (Array.isArray(data)) {\n\t\tdata.forEach((item, index) => {\n\t\t\tconsole.log(`${prefix}${chalk.gray(`[${index}]`)}`);\n\t\t\tprettyPrint(item, indent + 1);\n\t\t});\n\t} else if (typeof data === \"object\" && data !== null) {\n\t\tfor (const [key, value] of Object.entries(data)) {\n\t\t\tif (typeof value === \"object\" && value !== null) {\n\t\t\t\tconsole.log(`${prefix}${chalk.gray(key)}:`);\n\t\t\t\tprettyPrint(value, indent + 1);\n\t\t\t} else {\n\t\t\t\tconsole.log(\n\t\t\t\t\t`${prefix}${chalk.gray(key)}: ${chalk.white(String(value))}`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t} else {\n\t\tconsole.log(`${prefix}${chalk.white(String(data))}`);\n\t}\n}\n","import { readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { Command } from \"commander\";\nimport { CONFIG_FILE_NAME, LOCAL_CONFIG_DIR } from \"../lib/config.js\";\nimport { getGitAuthContext } from \"../lib/git-auth.js\";\nimport { findProjectRoot } from \"../lib/sync.js\";\n\n/**\n * Parse git credential helper input from stdin.\n * Format: key=value lines, terminated by an empty line.\n */\nfunction parseCredentialInput(input: string): Record<string, string> {\n\tconst fields: Record<string, string> = {};\n\tfor (const line of input.split(\"\\n\")) {\n\t\tconst trimmed = line.trim();\n\t\tif (!trimmed) continue;\n\t\tconst eqIdx = trimmed.indexOf(\"=\");\n\t\tif (eqIdx > 0) {\n\t\t\tfields[trimmed.slice(0, eqIdx)] = trimmed.slice(eqIdx + 1);\n\t\t}\n\t}\n\treturn fields;\n}\n\nexport const gitCredentialHelperCommand = new Command(\"git-credential-helper\")\n\t.description(\"Git credential helper (used by git, not called directly)\")\n\t.argument(\"<operation>\", \"get, store, or erase\")\n\t.action(async (operation: string) => {\n\t\t// Only handle \"get\" — \"store\" and \"erase\" are no-ops\n\t\tif (operation !== \"get\") {\n\t\t\tprocess.exit(0);\n\t\t}\n\n\t\ttry {\n\t\t\t// Read credential request from stdin\n\t\t\tconst input = readFileSync(0, \"utf-8\");\n\t\t\tconst fields = parseCredentialInput(input);\n\n\t\t\t// Only handle HTTPS\n\t\t\tif (fields.protocol && fields.protocol !== \"https\") {\n\t\t\t\tprocess.exit(0);\n\t\t\t}\n\n\t\t\t// Find project root\n\t\t\tconst projectRoot = await findProjectRoot(process.cwd());\n\t\t\tif (!projectRoot) {\n\t\t\t\tprocess.stderr.write(\n\t\t\t\t\t\"waniwani: not in a WaniWani project (no .waniwani/ found)\\n\",\n\t\t\t\t);\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\n\t\t\t// Read mcpId directly from config file\n\t\t\tconst configPath = join(projectRoot, LOCAL_CONFIG_DIR, CONFIG_FILE_NAME);\n\t\t\tconst configData = JSON.parse(readFileSync(configPath, \"utf-8\"));\n\t\t\tconst mcpId = configData.mcpId;\n\n\t\t\tif (!mcpId) {\n\t\t\t\tprocess.stderr.write(\"waniwani: no mcpId in config\\n\");\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\n\t\t\t// Get ephemeral credentials\n\t\t\tconst gitAuth = await getGitAuthContext(mcpId);\n\n\t\t\tif (!gitAuth.credentials) {\n\t\t\t\tprocess.stderr.write(\"waniwani: no credentials returned from API\\n\");\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\n\t\t\t// Output in git credential helper format\n\t\t\tprocess.stdout.write(\n\t\t\t\t`username=${gitAuth.credentials.username}\\npassword=${gitAuth.credentials.password}\\n`,\n\t\t\t);\n\t\t} catch (error) {\n\t\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\t\tprocess.stderr.write(`waniwani credential helper error: ${message}\\n`);\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n","import { execFileSync, type StdioOptions } from \"node:child_process\";\nimport { chmodSync, mkdtempSync, rmSync, writeFileSync } from \"node:fs\";\nimport { tmpdir } from \"node:os\";\nimport { join } from \"node:path\";\nimport type { CloneUrlResponse, GitAuthResponse } from \"../types/index.js\";\nimport { ApiError, api } from \"./api.js\";\n\nexport interface GitHttpCredentials {\n\tusername: string;\n\tpassword: string;\n}\n\nexport interface GitAuthContext {\n\tcloneUrl: string;\n\tremoteUrl: string;\n\tcredentials: GitHttpCredentials | null;\n\tgithubApiBaseUrl: string | null;\n}\n\n/**\n * Convert a remote URL to GitHub API base URL (cloud or GHES).\n */\nfunction getGitHubApiBaseUrl(remoteUrl: string): string | null {\n\ttry {\n\t\tconst parsed = new URL(remoteUrl);\n\t\treturn parsed.hostname === \"github.com\" ||\n\t\t\tparsed.hostname === \"www.github.com\"\n\t\t\t? \"https://api.github.com\"\n\t\t\t: `${parsed.protocol}//${parsed.host}/api/v3`;\n\t} catch {\n\t\treturn null;\n\t}\n}\n\n/**\n * Parse clone-url endpoint response and split credentialed clone URLs into:\n * - remoteUrl: safe URL without embedded credentials\n * - credentials: username/password for transient auth\n */\nfunction parseCloneUrlAuth(cloneUrl: string): GitAuthContext {\n\ttry {\n\t\tconst parsed = new URL(cloneUrl);\n\t\tconst username = decodeURIComponent(parsed.username);\n\t\tconst password = decodeURIComponent(parsed.password);\n\n\t\tif (username && password) {\n\t\t\tparsed.username = \"\";\n\t\t\tparsed.password = \"\";\n\t\t\tconst remoteUrl = parsed.toString();\n\n\t\t\treturn {\n\t\t\t\tcloneUrl,\n\t\t\t\tremoteUrl,\n\t\t\t\tcredentials: { username, password },\n\t\t\t\tgithubApiBaseUrl: getGitHubApiBaseUrl(remoteUrl),\n\t\t\t};\n\t\t}\n\t} catch {\n\t\t// If cloneUrl is not parseable as URL (unlikely), use it as-is.\n\t}\n\n\treturn {\n\t\tcloneUrl,\n\t\tremoteUrl: cloneUrl,\n\t\tcredentials: null,\n\t\tgithubApiBaseUrl: null,\n\t};\n}\n\n/**\n * Fetch git auth context from backend. Prefers structured /git-auth endpoint,\n * falls back to /clone-url for backward compatibility with older backends.\n */\nexport async function getGitAuthContext(\n\tmcpId: string,\n): Promise<GitAuthContext> {\n\ttry {\n\t\tconst gitAuth = await api.get<GitAuthResponse>(\n\t\t\t`/api/mcp/repositories/${mcpId}/git-auth`,\n\t\t);\n\t\tconst parsedRemote = new URL(gitAuth.remoteUrl);\n\t\tparsedRemote.username = gitAuth.username;\n\t\tparsedRemote.password = gitAuth.token;\n\t\tconst cloneUrl = parsedRemote.toString();\n\n\t\treturn {\n\t\t\tcloneUrl,\n\t\t\tremoteUrl: gitAuth.remoteUrl,\n\t\t\tcredentials: {\n\t\t\t\tusername: gitAuth.username,\n\t\t\t\tpassword: gitAuth.token,\n\t\t\t},\n\t\t\tgithubApiBaseUrl: getGitHubApiBaseUrl(gitAuth.remoteUrl),\n\t\t};\n\t} catch (error) {\n\t\t// If the new endpoint isn't available yet, use legacy clone-url.\n\t\tif (error instanceof ApiError && error.statusCode !== 404) {\n\t\t\tthrow error;\n\t\t}\n\n\t\tconst { cloneUrl } = await api.get<CloneUrlResponse>(\n\t\t\t`/api/mcp/repositories/${mcpId}/clone-url`,\n\t\t);\n\t\treturn parseCloneUrlAuth(cloneUrl);\n\t}\n}\n\n/**\n * Run a git command with ephemeral credentials via GIT_ASKPASS.\n * Credentials are only exposed in process env for this single command.\n */\nexport function runGitWithCredentials(\n\targs: string[],\n\toptions?: {\n\t\tcwd?: string;\n\t\tstdio?: StdioOptions;\n\t\tcredentials?: GitHttpCredentials | null;\n\t},\n): void {\n\tconst { cwd, stdio = \"ignore\", credentials = null } = options ?? {};\n\n\tif (!credentials) {\n\t\texecFileSync(\"git\", args, { cwd, stdio });\n\t\treturn;\n\t}\n\n\tconst dir = mkdtempSync(join(tmpdir(), \"waniwani-askpass-\"));\n\tconst askpassPath = join(dir, \"askpass.sh\");\n\n\ttry {\n\t\twriteFileSync(\n\t\t\taskpassPath,\n\t\t\t`#!/bin/sh\ncase \"$1\" in\n *sername*) printf '%s\\\\n' \"$WANIWANI_GIT_USERNAME\" ;;\n *assword*) printf '%s\\\\n' \"$WANIWANI_GIT_PASSWORD\" ;;\n *) printf '\\\\n' ;;\nesac\n`,\n\t\t\t\"utf-8\",\n\t\t);\n\t\tchmodSync(askpassPath, 0o700);\n\n\t\texecFileSync(\"git\", [\"-c\", \"credential.helper=\", ...args], {\n\t\t\tcwd,\n\t\t\tstdio,\n\t\t\tenv: {\n\t\t\t\t...process.env,\n\t\t\t\tGIT_ASKPASS: askpassPath,\n\t\t\t\tGIT_TERMINAL_PROMPT: \"0\",\n\t\t\t\tWANIWANI_GIT_USERNAME: credentials.username,\n\t\t\t\tWANIWANI_GIT_PASSWORD: credentials.password,\n\t\t\t},\n\t\t});\n\t} finally {\n\t\trmSync(dir, { recursive: true, force: true });\n\t}\n}\n\n/**\n * Best-effort revocation for GitHub App installation tokens.\n * If the token type/host doesn't support this endpoint, this is a no-op.\n */\nconst REVOKE_TIMEOUT_MS = 5_000;\n\nexport async function revokeGitHubInstallationToken(\n\tauth: GitAuthContext,\n): Promise<void> {\n\tif (!auth.credentials?.password || !auth.githubApiBaseUrl) return;\n\n\tconst controller = new AbortController();\n\tconst timeout = setTimeout(() => controller.abort(), REVOKE_TIMEOUT_MS);\n\ttry {\n\t\tawait fetch(`${auth.githubApiBaseUrl}/installation/token`, {\n\t\t\tmethod: \"DELETE\",\n\t\t\theaders: {\n\t\t\t\tAccept: \"application/vnd.github+json\",\n\t\t\t\tAuthorization: `Bearer ${auth.credentials.password}`,\n\t\t\t\t\"X-GitHub-Api-Version\": \"2022-11-28\",\n\t\t\t},\n\t\t\tsignal: controller.signal,\n\t\t});\n\t} catch {\n\t\t// Best-effort only; token still naturally expires.\n\t} finally {\n\t\tclearTimeout(timeout);\n\t}\n}\n","import { config } from \"./config.js\";\n\n/**\n * AuthManager delegates all storage to the config module.\n * Auth tokens are stored in .waniwani/settings.json alongside other config.\n */\nclass AuthManager {\n\tasync isLoggedIn(): Promise<boolean> {\n\t\tconst token = await config.getAccessToken();\n\t\treturn !!token;\n\t}\n\n\tasync getAccessToken(): Promise<string | null> {\n\t\treturn config.getAccessToken();\n\t}\n\n\tasync getRefreshToken(): Promise<string | null> {\n\t\treturn config.getRefreshToken();\n\t}\n\n\tasync setTokens(\n\t\taccessToken: string,\n\t\trefreshToken: string,\n\t\texpiresIn: number,\n\t\tclientId?: string,\n\t): Promise<void> {\n\t\treturn config.setTokens(accessToken, refreshToken, expiresIn, clientId);\n\t}\n\n\tasync clear(): Promise<void> {\n\t\treturn config.clearAuth();\n\t}\n\n\tasync isTokenExpired(): Promise<boolean> {\n\t\treturn config.isTokenExpired();\n\t}\n\n\tasync tryRefreshToken(): Promise<boolean> {\n\t\tconst refreshToken = await config.getRefreshToken();\n\t\tconst clientId = await config.getClientId();\n\t\tif (!refreshToken || !clientId) return false;\n\n\t\ttry {\n\t\t\tconst apiUrl = await config.getApiUrl();\n\t\t\tconst response = await fetch(`${apiUrl}/api/auth/oauth2/token`, {\n\t\t\t\tmethod: \"POST\",\n\t\t\t\theaders: { \"Content-Type\": \"application/x-www-form-urlencoded\" },\n\t\t\t\tbody: new URLSearchParams({\n\t\t\t\t\tgrant_type: \"refresh_token\",\n\t\t\t\t\trefresh_token: refreshToken,\n\t\t\t\t\tclient_id: clientId,\n\t\t\t\t}).toString(),\n\t\t\t});\n\n\t\t\tif (!response.ok) {\n\t\t\t\tawait this.clear();\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tconst data = (await response.json()) as {\n\t\t\t\taccess_token: string;\n\t\t\t\trefresh_token: string;\n\t\t\t\texpires_in: number;\n\t\t\t};\n\n\t\t\tawait this.setTokens(\n\t\t\t\tdata.access_token,\n\t\t\t\tdata.refresh_token,\n\t\t\t\tdata.expires_in,\n\t\t\t);\n\n\t\t\treturn true;\n\t\t} catch {\n\t\t\tawait this.clear();\n\t\t\treturn false;\n\t\t}\n\t}\n}\n\nexport const auth = new AuthManager();\n","import { auth } from \"./auth.js\";\nimport { config } from \"./config.js\";\nimport { AuthError, CLIError } from \"./errors.js\";\n\nexport interface ApiResponse<T> {\n\tsuccess: boolean;\n\tdata?: T;\n\terror?:\n\t\t| string\n\t\t| {\n\t\t\t\tcode?: string;\n\t\t\t\tmessage?: string;\n\t\t\t\tdetails?: Record<string, unknown>;\n\t\t };\n\tcode?: string;\n\tmessage?: string;\n}\n\nexport class ApiError extends CLIError {\n\tconstructor(\n\t\tmessage: string,\n\t\tcode: string,\n\t\tpublic statusCode: number,\n\t\tdetails?: Record<string, unknown>,\n\t) {\n\t\tsuper(message, code, details);\n\t\tthis.name = \"ApiError\";\n\t}\n}\n\nasync function request<T>(\n\tmethod: string,\n\tpath: string,\n\toptions?: {\n\t\tbody?: unknown;\n\t\trequireAuth?: boolean;\n\t\theaders?: Record<string, string>;\n\t},\n): Promise<T> {\n\tconst {\n\t\tbody,\n\t\trequireAuth = true,\n\t\theaders: extraHeaders = {},\n\t} = options || {};\n\n\tconst headers: Record<string, string> = {\n\t\t\"Content-Type\": \"application/json\",\n\t\t...extraHeaders,\n\t};\n\n\tif (requireAuth) {\n\t\tconst token = await auth.getAccessToken();\n\t\tif (!token) {\n\t\t\tthrow new AuthError(\n\t\t\t\t\"Not logged in. Run 'waniwani login' to authenticate.\",\n\t\t\t);\n\t\t}\n\t\theaders.Authorization = `Bearer ${token}`;\n\t}\n\n\tconst baseUrl = await config.getApiUrl();\n\tconst url = `${baseUrl}${path}`;\n\n\tconst response = await fetch(url, {\n\t\tmethod,\n\t\theaders,\n\t\tbody: body ? JSON.stringify(body) : undefined,\n\t});\n\n\t// Handle empty responses (204 No Content)\n\tif (response.status === 204) {\n\t\treturn undefined as T;\n\t}\n\n\tlet data: ApiResponse<T>;\n\tlet rawBody: string | undefined;\n\n\ttry {\n\t\trawBody = await response.text();\n\t\tdata = JSON.parse(rawBody) as ApiResponse<T>;\n\t} catch {\n\t\t// JSON parsing failed - use raw body as error message\n\t\tthrow new ApiError(\n\t\t\trawBody || `Request failed with status ${response.status}`,\n\t\t\t\"API_ERROR\",\n\t\t\tresponse.status,\n\t\t\t{ statusText: response.statusText },\n\t\t);\n\t}\n\n\tif (!response.ok || data.error) {\n\t\tconst errorObject =\n\t\t\ttypeof data.error === \"object\" && data.error !== null\n\t\t\t\t? data.error\n\t\t\t\t: undefined;\n\t\tconst errorString = typeof data.error === \"string\" ? data.error : undefined;\n\n\t\t// Try to extract error message from various possible response formats\n\t\tconst errorMessage =\n\t\t\terrorObject?.message ||\n\t\t\tdata.message ||\n\t\t\terrorString ||\n\t\t\trawBody ||\n\t\t\t`Request failed with status ${response.status}`;\n\n\t\tconst errorCode =\n\t\t\terrorString ||\n\t\t\terrorObject?.code ||\n\t\t\tdata.code ||\n\t\t\tdata.message ||\n\t\t\terrorObject?.message ||\n\t\t\t\"API_ERROR\";\n\n\t\tconst errorDetails = {\n\t\t\t...errorObject?.details,\n\t\t\tstatusText: response.statusText,\n\t\t\t...(errorObject ? {} : { rawResponse: data }),\n\t\t};\n\n\t\tconst error = {\n\t\t\tcode: errorCode,\n\t\t\tmessage: errorMessage,\n\t\t\tdetails: errorDetails,\n\t\t};\n\n\t\t// Handle token expiration\n\t\tif (response.status === 401) {\n\t\t\tconst refreshed = await auth.tryRefreshToken();\n\t\t\tif (refreshed) {\n\t\t\t\t// Retry with new token\n\t\t\t\treturn request<T>(method, path, options);\n\t\t\t}\n\t\t\tthrow new AuthError(\n\t\t\t\t\"Session expired. Run 'waniwani login' to re-authenticate.\",\n\t\t\t);\n\t\t}\n\n\t\tthrow new ApiError(\n\t\t\terror.message,\n\t\t\terror.code,\n\t\t\tresponse.status,\n\t\t\terror.details,\n\t\t);\n\t}\n\n\treturn data.data as T;\n}\n\nexport const api = {\n\tget: <T>(path: string, options?: { requireAuth?: boolean }) =>\n\t\trequest<T>(\"GET\", path, options),\n\n\tpost: <T>(\n\t\tpath: string,\n\t\tbody?: unknown,\n\t\toptions?: { requireAuth?: boolean; headers?: Record<string, string> },\n\t) => request<T>(\"POST\", path, { body, ...options }),\n\n\tdelete: <T>(path: string, options?: { requireAuth?: boolean }) =>\n\t\trequest<T>(\"DELETE\", path, options),\n\n\tgetBaseUrl: () => config.getApiUrl(),\n};\n","import { existsSync } from \"node:fs\";\nimport { mkdir, readdir, readFile, stat, writeFile } from \"node:fs/promises\";\nimport { dirname, join, relative } from \"node:path\";\nimport ignore from \"ignore\";\nimport type { PullFilesResponse } from \"../types/index.js\";\nimport { api } from \"./api.js\";\nimport { detectBinary, isBinaryPath } from \"./utils.js\";\n\nconst PROJECT_DIR = \".waniwani\";\n\n/**\n * Find the project root by walking up from the given directory\n * looking for a .waniwani directory\n */\nexport async function findProjectRoot(\n\tstartDir: string,\n): Promise<string | null> {\n\tlet current = startDir;\n\tconst root = dirname(current);\n\n\twhile (current !== root) {\n\t\tif (existsSync(join(current, PROJECT_DIR))) {\n\t\t\treturn current;\n\t\t}\n\t\tconst parent = dirname(current);\n\t\tif (parent === current) break;\n\t\tcurrent = parent;\n\t}\n\n\t// Check root as well\n\tif (existsSync(join(current, PROJECT_DIR))) {\n\t\treturn current;\n\t}\n\n\treturn null;\n}\n\n/**\n * Default patterns to always ignore\n */\nconst DEFAULT_IGNORE_PATTERNS = [\n\t\".waniwani\",\n\t\".git\",\n\t\"node_modules\",\n\t\".DS_Store\",\n\t\"*.log\",\n\t\".cache\",\n\t\"dist\",\n\t\"coverage\",\n\t\".turbo\",\n\t\".next\",\n\t\".nuxt\",\n\t\".vercel\",\n];\n\nconst DEFAULT_ENV_IGNORE_PATTERNS = [\".env\", \".env.*\"];\n\nexport interface SyncIgnoreOptions {\n\tincludeEnvFiles?: boolean;\n}\n\n/**\n * Load ignore patterns from .gitignore and add defaults\n */\nexport async function loadIgnorePatterns(\n\tprojectRoot: string,\n\toptions: SyncIgnoreOptions = {},\n): Promise<ReturnType<typeof ignore>> {\n\tconst { includeEnvFiles = false } = options;\n\tconst ig = ignore();\n\n\t// Add default patterns\n\tig.add(DEFAULT_IGNORE_PATTERNS);\n\tif (!includeEnvFiles) {\n\t\tig.add(DEFAULT_ENV_IGNORE_PATTERNS);\n\t}\n\n\t// Load .gitignore if it exists\n\tconst gitignorePath = join(projectRoot, \".gitignore\");\n\tif (existsSync(gitignorePath)) {\n\t\ttry {\n\t\t\tconst content = await readFile(gitignorePath, \"utf-8\");\n\t\t\tig.add(content);\n\t\t} catch {\n\t\t\t// Ignore read errors\n\t\t}\n\t}\n\n\t// For local preview hydration, include env files even if they're gitignored.\n\tif (includeEnvFiles) {\n\t\tig.add([\"!.env\", \"!.env.*\"]);\n\t}\n\n\treturn ig;\n}\n\nexport interface FileToSync {\n\tpath: string;\n\tcontent: string;\n\tencoding: \"utf8\" | \"base64\";\n}\n\n/**\n * Collect all files in a directory that should be synced\n * Respects .gitignore and default ignore patterns\n */\nexport async function collectFiles(\n\tprojectRoot: string,\n\toptions: SyncIgnoreOptions = {},\n): Promise<FileToSync[]> {\n\tconst ig = await loadIgnorePatterns(projectRoot, options);\n\tconst files: FileToSync[] = [];\n\n\tasync function walk(dir: string) {\n\t\tconst entries = await readdir(dir, { withFileTypes: true });\n\n\t\tfor (const entry of entries) {\n\t\t\tconst fullPath = join(dir, entry.name);\n\t\t\tconst relativePath = relative(projectRoot, fullPath);\n\n\t\t\t// Check if path is ignored\n\t\t\tif (ig.ignores(relativePath)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (entry.isDirectory()) {\n\t\t\t\tawait walk(fullPath);\n\t\t\t} else if (entry.isFile()) {\n\t\t\t\ttry {\n\t\t\t\t\tconst content = await readFile(fullPath);\n\t\t\t\t\tconst isBinary = isBinaryPath(fullPath) || detectBinary(content);\n\n\t\t\t\t\tfiles.push({\n\t\t\t\t\t\tpath: relativePath,\n\t\t\t\t\t\tcontent: isBinary\n\t\t\t\t\t\t\t? content.toString(\"base64\")\n\t\t\t\t\t\t\t: content.toString(\"utf8\"),\n\t\t\t\t\t\tencoding: isBinary ? \"base64\" : \"utf8\",\n\t\t\t\t\t});\n\t\t\t\t} catch {\n\t\t\t\t\t// Skip files that can't be read\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tawait walk(projectRoot);\n\treturn files;\n}\n\n/**\n * Pull all files from GitHub to a local directory.\n * Uses a single API call to fetch all files from the repository.\n */\nexport async function pullFilesFromGithub(\n\tmcpId: string,\n\ttargetDir: string,\n): Promise<{ count: number; files: string[] }> {\n\t// Fetch all files from GitHub in one request\n\tconst result = await api.get<PullFilesResponse>(\n\t\t`/api/mcp/repositories/${mcpId}/files`,\n\t);\n\n\tconst writtenFiles: string[] = [];\n\n\tfor (const file of result.files) {\n\t\tconst localPath = join(targetDir, file.path);\n\t\tconst dir = dirname(localPath);\n\n\t\t// Ensure directory exists\n\t\tawait mkdir(dir, { recursive: true });\n\n\t\t// Write file content\n\t\tif (file.encoding === \"base64\") {\n\t\t\tawait writeFile(localPath, Buffer.from(file.content, \"base64\"));\n\t\t} else {\n\t\t\tawait writeFile(localPath, file.content, \"utf8\");\n\t\t}\n\n\t\twrittenFiles.push(file.path);\n\t}\n\n\treturn { count: writtenFiles.length, files: writtenFiles };\n}\n\n/**\n * Collect a single file for syncing\n */\nexport async function collectSingleFile(\n\tprojectRoot: string,\n\tfilePath: string,\n): Promise<FileToSync | null> {\n\tconst fullPath = join(projectRoot, filePath);\n\tconst relativePath = relative(projectRoot, fullPath);\n\n\t// Check if file exists\n\tif (!existsSync(fullPath)) {\n\t\treturn null;\n\t}\n\n\ttry {\n\t\tconst fileStat = await stat(fullPath);\n\t\tif (!fileStat.isFile()) {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst content = await readFile(fullPath);\n\t\tconst isBinary = isBinaryPath(fullPath) || detectBinary(content);\n\n\t\treturn {\n\t\t\tpath: relativePath,\n\t\t\tcontent: isBinary ? content.toString(\"base64\") : content.toString(\"utf8\"),\n\t\t\tencoding: isBinary ? \"base64\" : \"utf8\",\n\t\t};\n\t} catch {\n\t\treturn null;\n\t}\n}\n","import { config } from \"./config.js\";\nimport { McpError } from \"./errors.js\";\n\n/**\n * Requires an MCP ID, falling back to the active MCP from config.\n * Throws McpError if no MCP is available.\n */\nexport async function requireMcpId(mcpId?: string): Promise<string> {\n\tif (mcpId) return mcpId;\n\n\tconst configMcpId = await config.getMcpId();\n\tif (!configMcpId) {\n\t\tthrow new McpError(\n\t\t\t\"No active MCP. Run 'waniwani mcp create <name>' or 'waniwani mcp use <name>'.\",\n\t\t);\n\t}\n\treturn configMcpId;\n}\n\n/**\n * Get the active session ID from config.\n * Throws McpError if no session ID is stored.\n */\nexport async function requireSessionId(): Promise<string> {\n\tconst sessionId = await config.getSessionId();\n\n\tif (!sessionId) {\n\t\tthrow new McpError(\n\t\t\t\"No active session. Run 'waniwani mcp preview' to start development.\",\n\t\t);\n\t}\n\n\treturn sessionId;\n}\n\n/**\n * Binary file extensions that should be base64 encoded\n */\nconst BINARY_EXTENSIONS = new Set([\n\t\".png\",\n\t\".jpg\",\n\t\".jpeg\",\n\t\".gif\",\n\t\".ico\",\n\t\".webp\",\n\t\".svg\",\n\t\".woff\",\n\t\".woff2\",\n\t\".ttf\",\n\t\".eot\",\n\t\".otf\",\n\t\".zip\",\n\t\".tar\",\n\t\".gz\",\n\t\".pdf\",\n\t\".exe\",\n\t\".dll\",\n\t\".so\",\n\t\".dylib\",\n\t\".bin\",\n\t\".mp3\",\n\t\".mp4\",\n\t\".wav\",\n\t\".ogg\",\n\t\".webm\",\n]);\n\n/**\n * Check if a file path is likely a binary file based on extension\n */\nexport function isBinaryPath(filePath: string): boolean {\n\tconst ext = filePath.slice(filePath.lastIndexOf(\".\")).toLowerCase();\n\treturn BINARY_EXTENSIONS.has(ext);\n}\n\n/**\n * Detect if a buffer contains binary data by checking for null bytes\n */\nexport function detectBinary(buffer: Buffer): boolean {\n\t// Check first 8KB for null bytes\n\tconst sample = buffer.subarray(0, 8192);\n\treturn sample.includes(0);\n}\n","import { spawn } from \"node:child_process\";\nimport { createServer, type Server } from \"node:http\";\nimport type { Socket } from \"node:net\";\nimport chalk from \"chalk\";\nimport { Command } from \"commander\";\nimport ora from \"ora\";\nimport { api } from \"../lib/api.js\";\nimport { auth } from \"../lib/auth.js\";\nimport { config } from \"../lib/config.js\";\nimport { CLIError, handleError } from \"../lib/errors.js\";\nimport { formatOutput, formatSuccess } from \"../lib/output.js\";\nimport type {\n\tOAuthClientRegistrationResponse,\n\tOAuthTokenResponse,\n\tOrgListResponse,\n} from \"../types/index.js\";\n\n// ASCII art logo for WaniWani\nconst LOGO_LINES = [\n\t\"██╗ ██╗ █████╗ ███╗ ██╗ ██╗ ██╗ ██╗ █████╗ ███╗ ██╗ ██╗\",\n\t\"██║ ██║██╔══██╗████╗ ██║ ██║ ██║ ██║██╔══██╗████╗ ██║ ██║\",\n\t\"██║ █╗ ██║███████║██╔██╗ ██║ ██║ ██║ █╗ ██║███████║██╔██╗ ██║ ██║\",\n\t\"██║███╗██║██╔══██║██║╚██╗██║ ██║ ██║███╗██║██╔══██║██║╚██╗██║ ██║\",\n\t\"╚███╔███╔╝██║ ██║██║ ╚████║ ██║ ╚███╔███╔╝██║ ██║██║ ╚████║ ██║\",\n\t\" ╚══╝╚══╝ ╚═╝ ╚═╝╚═╝ ╚═══╝ ╚═╝ ╚══╝╚══╝ ╚═╝ ╚═╝╚═╝ ╚═══╝ ╚═╝\",\n];\n\n// 256-color gradient - warm tones inspired by WaniWani brand\nconst LOGO_COLORS = [\n\t\"\\x1b[38;5;223m\", // light peach\n\t\"\\x1b[38;5;216m\", // peach\n\t\"\\x1b[38;5;209m\", // salmon\n\t\"\\x1b[38;5;203m\", // coral\n\t\"\\x1b[38;5;167m\", // warm red\n\t\"\\x1b[38;5;131m\", // deep terracotta\n];\n\nconst RESET = \"\\x1b[0m\";\n\nfunction showLogo(): void {\n\tconsole.log();\n\tfor (let i = 0; i < LOGO_LINES.length; i++) {\n\t\tconsole.log(`${LOGO_COLORS[i]}${LOGO_LINES[i]}${RESET}`);\n\t}\n\tconsole.log();\n}\n\nconst CALLBACK_PORT = 54321;\nconst CALLBACK_URL = `http://localhost:${CALLBACK_PORT}/callback`;\nconst CLIENT_NAME = \"waniwani-cli\";\n\nfunction generateCodeVerifier(): string {\n\tconst array = new Uint8Array(32);\n\tcrypto.getRandomValues(array);\n\treturn btoa(String.fromCharCode(...array))\n\t\t.replace(/\\+/g, \"-\")\n\t\t.replace(/\\//g, \"_\")\n\t\t.replace(/=+$/, \"\");\n}\n\nasync function generateCodeChallenge(verifier: string): Promise<string> {\n\tconst encoder = new TextEncoder();\n\tconst data = encoder.encode(verifier);\n\tconst hash = await crypto.subtle.digest(\"SHA-256\", data);\n\treturn btoa(String.fromCharCode(...new Uint8Array(hash)))\n\t\t.replace(/\\+/g, \"-\")\n\t\t.replace(/\\//g, \"_\")\n\t\t.replace(/=+$/, \"\");\n}\n\nfunction generateState(): string {\n\tconst array = new Uint8Array(16);\n\tcrypto.getRandomValues(array);\n\treturn Array.from(array, (b) => b.toString(16).padStart(2, \"0\")).join(\"\");\n}\n\nasync function registerClient(): Promise<OAuthClientRegistrationResponse> {\n\tconst apiUrl = await config.getApiUrl();\n\tconst response = await fetch(`${apiUrl}/api/auth/oauth2/register`, {\n\t\tmethod: \"POST\",\n\t\theaders: {\n\t\t\t\"Content-Type\": \"application/json\",\n\t\t},\n\t\tbody: JSON.stringify({\n\t\t\tclient_name: CLIENT_NAME,\n\t\t\tredirect_uris: [CALLBACK_URL],\n\t\t\tgrant_types: [\"authorization_code\", \"refresh_token\"],\n\t\t\tresponse_types: [\"code\"],\n\t\t\ttoken_endpoint_auth_method: \"none\",\n\t\t}),\n\t});\n\n\tif (!response.ok) {\n\t\tconst error = await response.json().catch(() => ({}));\n\t\tthrow new CLIError(\n\t\t\t(error as { error_description?: string }).error_description ||\n\t\t\t\t\"Failed to register OAuth client\",\n\t\t\t\"CLIENT_REGISTRATION_FAILED\",\n\t\t);\n\t}\n\n\treturn response.json() as Promise<OAuthClientRegistrationResponse>;\n}\n\nasync function openBrowser(url: string): Promise<void> {\n\tconst [cmd, ...args] =\n\t\tprocess.platform === \"darwin\"\n\t\t\t? [\"open\", url]\n\t\t\t: process.platform === \"win32\"\n\t\t\t\t? [\"cmd\", \"/c\", \"start\", url]\n\t\t\t\t: [\"xdg-open\", url];\n\n\tspawn(cmd, args, { stdio: \"ignore\", detached: true }).unref();\n}\n\nasync function waitForCallback(\n\texpectedState: string,\n\ttimeoutMs: number = 300000,\n): Promise<string> {\n\treturn new Promise((resolve, reject) => {\n\t\tlet server: Server | null = null;\n\t\tconst sockets = new Set<Socket>();\n\n\t\tconst timeout = setTimeout(() => {\n\t\t\tcleanup();\n\t\t\treject(new CLIError(\"Login timed out\", \"LOGIN_TIMEOUT\"));\n\t\t}, timeoutMs);\n\n\t\tconst cleanup = () => {\n\t\t\tclearTimeout(timeout);\n\t\t\t// Destroy all active connections to allow process to exit\n\t\t\tfor (const socket of sockets) {\n\t\t\t\tsocket.destroy();\n\t\t\t}\n\t\t\tsockets.clear();\n\t\t\tserver?.close();\n\t\t};\n\n\t\tconst htmlResponse = (title: string, message: string, isSuccess: boolean) =>\n\t\t\t`<!DOCTYPE html>\n<html>\n<head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <title>${title} - WaniWani</title>\n <style>\n * { margin: 0; padding: 0; box-sizing: border-box; }\n body {\n font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n min-height: 100vh;\n display: flex;\n align-items: center;\n justify-content: center;\n background: #fafafa;\n position: relative;\n overflow: hidden;\n }\n .blob {\n position: absolute;\n border-radius: 50%;\n filter: blur(60px);\n pointer-events: none;\n }\n .blob-1 {\n top: 0;\n left: 25%;\n width: 24rem;\n height: 24rem;\n background: linear-gradient(to bottom right, rgba(253, 224, 71, 0.3), rgba(251, 146, 60, 0.3));\n }\n .blob-2 {\n bottom: 0;\n right: 25%;\n width: 24rem;\n height: 24rem;\n background: linear-gradient(to bottom right, rgba(134, 239, 172, 0.3), rgba(52, 211, 153, 0.3));\n }\n .blob-3 {\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n width: 40rem;\n height: 40rem;\n background: linear-gradient(to bottom right, rgba(255, 237, 213, 0.2), rgba(254, 249, 195, 0.2));\n }\n .container {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 2rem;\n padding: 2rem;\n z-index: 10;\n text-align: center;\n }\n .logo {\n font-size: 1.75rem;\n font-weight: 700;\n color: #1e293b;\n letter-spacing: -0.025em;\n }\n .icon-circle {\n width: 80px;\n height: 80px;\n border-radius: 50%;\n display: flex;\n align-items: center;\n justify-content: center;\n background: ${isSuccess ? \"rgba(52, 211, 153, 0.15)\" : \"rgba(239, 68, 68, 0.15)\"};\n }\n .icon {\n width: 40px;\n height: 40px;\n color: ${isSuccess ? \"#10b981\" : \"#ef4444\"};\n }\n h1 {\n font-size: 2rem;\n font-weight: 700;\n color: #1e293b;\n }\n p {\n font-size: 1.125rem;\n color: #64748b;\n max-width: 400px;\n }\n </style>\n</head>\n<body>\n <div class=\"blob blob-1\"></div>\n <div class=\"blob blob-2\"></div>\n <div class=\"blob blob-3\"></div>\n <div class=\"container\">\n <span class=\"logo\">WaniWani</span>\n <div class=\"icon-circle\">\n ${\n\t\t\t\tisSuccess\n\t\t\t\t\t? '<svg class=\"icon\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M20 6 9 17l-5-5\"></path></svg>'\n\t\t\t\t\t: '<svg class=\"icon\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M18 6 6 18\"></path><path d=\"m6 6 12 12\"></path></svg>'\n\t\t\t}\n </div>\n <h1>${title}</h1>\n <p>${message}</p>\n </div>\n</body>\n</html>`;\n\n\t\ttry {\n\t\t\tserver = createServer((req, res) => {\n\t\t\t\tconst url = new URL(\n\t\t\t\t\treq.url || \"/\",\n\t\t\t\t\t`http://localhost:${CALLBACK_PORT}`,\n\t\t\t\t);\n\n\t\t\t\tif (url.pathname === \"/callback\") {\n\t\t\t\t\tconst code = url.searchParams.get(\"code\");\n\t\t\t\t\tconst state = url.searchParams.get(\"state\");\n\t\t\t\t\tconst error = url.searchParams.get(\"error\");\n\n\t\t\t\t\tres.setHeader(\"Content-Type\", \"text/html\");\n\n\t\t\t\t\tif (error) {\n\t\t\t\t\t\tres.statusCode = 400;\n\t\t\t\t\t\tres.end(htmlResponse(\"Login Failed\", `Error: ${error}`, false));\n\t\t\t\t\t\tcleanup();\n\t\t\t\t\t\treject(new CLIError(`OAuth error: ${error}`, \"OAUTH_ERROR\"));\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (state !== expectedState) {\n\t\t\t\t\t\tres.statusCode = 400;\n\t\t\t\t\t\tres.end(\n\t\t\t\t\t\t\thtmlResponse(\n\t\t\t\t\t\t\t\t\"Login Failed\",\n\t\t\t\t\t\t\t\t\"Invalid state parameter. Please try again.\",\n\t\t\t\t\t\t\t\tfalse,\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t);\n\t\t\t\t\t\tcleanup();\n\t\t\t\t\t\treject(new CLIError(\"Invalid state parameter\", \"INVALID_STATE\"));\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (!code) {\n\t\t\t\t\t\tres.statusCode = 400;\n\t\t\t\t\t\tres.end(\n\t\t\t\t\t\t\thtmlResponse(\n\t\t\t\t\t\t\t\t\"Login Failed\",\n\t\t\t\t\t\t\t\t\"No authorization code received.\",\n\t\t\t\t\t\t\t\tfalse,\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t);\n\t\t\t\t\t\tcleanup();\n\t\t\t\t\t\treject(new CLIError(\"No authorization code\", \"NO_CODE\"));\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tres.statusCode = 200;\n\t\t\t\t\tres.end(\n\t\t\t\t\t\thtmlResponse(\n\t\t\t\t\t\t\t\"Login Successful!\",\n\t\t\t\t\t\t\t\"You can close this window and return to the terminal.\",\n\t\t\t\t\t\t\ttrue,\n\t\t\t\t\t\t),\n\t\t\t\t\t);\n\n\t\t\t\t\t// Schedule cleanup after response is sent\n\t\t\t\t\tsetTimeout(() => {\n\t\t\t\t\t\tcleanup();\n\t\t\t\t\t\tresolve(code);\n\t\t\t\t\t}, 100);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tres.statusCode = 404;\n\t\t\t\tres.end(\"Not found\");\n\t\t\t});\n\n\t\t\t// Track connections so we can force-close them\n\t\t\tserver.on(\"connection\", (socket) => {\n\t\t\t\tsockets.add(socket);\n\t\t\t\tsocket.on(\"close\", () => sockets.delete(socket));\n\t\t\t});\n\n\t\t\tserver.on(\"error\", (err: NodeJS.ErrnoException) => {\n\t\t\t\tcleanup();\n\t\t\t\tif (err.code === \"EADDRINUSE\") {\n\t\t\t\t\treject(\n\t\t\t\t\t\tnew CLIError(\n\t\t\t\t\t\t\t`Port ${CALLBACK_PORT} is already in use. Close any other WaniWani CLI instances and try again.`,\n\t\t\t\t\t\t\t\"PORT_IN_USE\",\n\t\t\t\t\t\t),\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\treject(err);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tserver.listen(CALLBACK_PORT);\n\t\t} catch (err: unknown) {\n\t\t\tcleanup();\n\t\t\treject(err);\n\t\t}\n\t});\n}\n\nasync function exchangeCodeForToken(\n\tcode: string,\n\tcodeVerifier: string,\n\tclientId: string,\n\tresource: string,\n): Promise<OAuthTokenResponse> {\n\tconst apiUrl = await config.getApiUrl();\n\tconst response = await fetch(`${apiUrl}/api/auth/oauth2/token`, {\n\t\tmethod: \"POST\",\n\t\theaders: {\n\t\t\t\"Content-Type\": \"application/x-www-form-urlencoded\",\n\t\t},\n\t\tbody: new URLSearchParams({\n\t\t\tgrant_type: \"authorization_code\",\n\t\t\tcode,\n\t\t\tredirect_uri: CALLBACK_URL,\n\t\t\tclient_id: clientId,\n\t\t\tcode_verifier: codeVerifier,\n\t\t\tresource, // RFC 8707 - required to get JWT token\n\t\t}).toString(),\n\t});\n\n\tif (!response.ok) {\n\t\tconst error = await response.json().catch(() => ({}));\n\t\tthrow new CLIError(\n\t\t\t(error as { error_description?: string }).error_description ||\n\t\t\t\t\"Failed to exchange code for token\",\n\t\t\t\"TOKEN_EXCHANGE_FAILED\",\n\t\t);\n\t}\n\n\treturn response.json() as Promise<OAuthTokenResponse>;\n}\n\nexport const loginCommand = new Command(\"login\")\n\t.description(\"Log in to WaniWani\")\n\t.option(\"--no-browser\", \"Don't open the browser automatically\")\n\t.action(async (options, command) => {\n\t\tconst globalOptions = command.optsWithGlobals();\n\t\tconst json = globalOptions.json ?? false;\n\n\t\ttry {\n\t\t\t// Check if already logged in with a valid session\n\t\t\tif (await auth.isLoggedIn()) {\n\t\t\t\t// Check if token is expired\n\t\t\t\tif (await auth.isTokenExpired()) {\n\t\t\t\t\t// Try to refresh the token\n\t\t\t\t\tconst refreshed = await auth.tryRefreshToken();\n\t\t\t\t\tif (refreshed) {\n\t\t\t\t\t\tif (json) {\n\t\t\t\t\t\t\tformatOutput({ alreadyLoggedIn: true, refreshed: true }, true);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tconsole.log(\n\t\t\t\t\t\t\t\tchalk.green(\"Session refreshed. You're still logged in.\"),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\t// Refresh failed, clear and proceed with login\n\t\t\t\t\tif (!json) {\n\t\t\t\t\t\tconsole.log(\n\t\t\t\t\t\t\tchalk.yellow(\"Session expired. Starting new login flow...\"),\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\tawait auth.clear();\n\t\t\t\t} else {\n\t\t\t\t\t// Token is valid\n\t\t\t\t\tif (json) {\n\t\t\t\t\t\tformatOutput({ alreadyLoggedIn: true }, true);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tconsole.log(\n\t\t\t\t\t\t\tchalk.yellow(\n\t\t\t\t\t\t\t\t\"Already logged in. Use 'waniwani logout' to log out first.\",\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (!json) {\n\t\t\t\tshowLogo();\n\t\t\t}\n\n\t\t\tconst spinner = ora(\"Registering client...\").start();\n\n\t\t\t// Register OAuth client dynamically\n\t\t\tconst { client_id: clientId } = await registerClient();\n\n\t\t\tspinner.text = \"Preparing authentication...\";\n\n\t\t\t// Generate PKCE values\n\t\t\tconst codeVerifier = generateCodeVerifier();\n\t\t\tconst codeChallenge = await generateCodeChallenge(codeVerifier);\n\t\t\tconst state = generateState();\n\n\t\t\t// Build authorization URL\n\t\t\tconst apiUrl = await config.getApiUrl();\n\t\t\tconst authUrl = new URL(`${apiUrl}/api/auth/oauth2/authorize`);\n\t\t\tauthUrl.searchParams.set(\"client_id\", clientId);\n\t\t\tauthUrl.searchParams.set(\"redirect_uri\", CALLBACK_URL);\n\t\t\tauthUrl.searchParams.set(\"response_type\", \"code\");\n\t\t\tauthUrl.searchParams.set(\"code_challenge\", codeChallenge);\n\t\t\tauthUrl.searchParams.set(\"code_challenge_method\", \"S256\");\n\t\t\tauthUrl.searchParams.set(\"state\", state);\n\t\t\tauthUrl.searchParams.set(\"resource\", apiUrl); // RFC 8707 - request JWT token\n\n\t\t\tspinner.stop();\n\n\t\t\tif (!json) {\n\t\t\t\tconsole.log(\"Opening browser for authentication...\\n\");\n\t\t\t\tconsole.log(`If the browser doesn't open, visit:\\n`);\n\t\t\t\tconsole.log(chalk.cyan(` ${authUrl.toString()}`));\n\t\t\t\tconsole.log();\n\t\t\t}\n\n\t\t\t// Start callback server and open browser\n\t\t\tconst callbackPromise = waitForCallback(state);\n\n\t\t\tif (options.browser !== false) {\n\t\t\t\tawait openBrowser(authUrl.toString());\n\t\t\t}\n\n\t\t\tspinner.start(\"Waiting for authorization...\");\n\n\t\t\t// Wait for callback with auth code\n\t\t\tconst code = await callbackPromise;\n\n\t\t\tspinner.text = \"Exchanging code for token...\";\n\n\t\t\t// Exchange code for token\n\t\t\tconst tokenResponse = await exchangeCodeForToken(\n\t\t\t\tcode,\n\t\t\t\tcodeVerifier,\n\t\t\t\tclientId,\n\t\t\t\tapiUrl, // RFC 8707 resource parameter\n\t\t\t);\n\n\t\t\t// Ensure .waniwani/ exists in cwd before storing tokens\n\t\t\tawait config.ensureConfigDir();\n\n\t\t\t// Store tokens and client ID for refresh\n\t\t\tawait auth.setTokens(\n\t\t\t\ttokenResponse.access_token,\n\t\t\t\ttokenResponse.refresh_token,\n\t\t\t\ttokenResponse.expires_in,\n\t\t\t\tclientId,\n\t\t\t);\n\n\t\t\tspinner.succeed(\"Logged in successfully!\");\n\n\t\t\t// Fetch current org info (don't block login on failure)\n\t\t\tlet orgName: string | null = null;\n\t\t\ttry {\n\t\t\t\tconst { orgs, activeOrgId } =\n\t\t\t\t\tawait api.get<OrgListResponse>(\"/api/oauth/orgs\");\n\t\t\t\tif (activeOrgId) {\n\t\t\t\t\tconst activeOrg = orgs.find((o) => o.id === activeOrgId);\n\t\t\t\t\tif (activeOrg) {\n\t\t\t\t\t\torgName = activeOrg.name;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} catch {\n\t\t\t\t// Silently ignore - org info is optional\n\t\t\t}\n\n\t\t\tif (json) {\n\t\t\t\tformatOutput(\n\t\t\t\t\t{ success: true, loggedIn: true, ...(orgName && { org: orgName }) },\n\t\t\t\t\ttrue,\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tconsole.log();\n\t\t\t\tformatSuccess(\"You're now logged in to WaniWani!\", false);\n\t\t\t\tif (orgName) {\n\t\t\t\t\tconsole.log(` Organization: ${chalk.cyan(orgName)}`);\n\t\t\t\t}\n\t\t\t\tconsole.log();\n\t\t\t\tconsole.log(\"Get started:\");\n\t\t\t\tconsole.log(\n\t\t\t\t\t\" waniwani mcp create my-server Create a new MCP sandbox\",\n\t\t\t\t);\n\t\t\t\tconsole.log(' waniwani task \"Add a tool\" Send tasks to Claude');\n\t\t\t\tconsole.log(\n\t\t\t\t\t\" waniwani org list View your organizations\",\n\t\t\t\t);\n\t\t\t}\n\t\t} catch (error) {\n\t\t\thandleError(error, json);\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n","import { Command } from \"commander\";\nimport { auth } from \"../lib/auth.js\";\nimport { handleError } from \"../lib/errors.js\";\nimport { formatOutput, formatSuccess } from \"../lib/output.js\";\n\nexport const logoutCommand = new Command(\"logout\")\n\t.description(\"Log out from WaniWani\")\n\t.action(async (_options, command) => {\n\t\tconst globalOptions = command.optsWithGlobals();\n\t\tconst json = globalOptions.json ?? false;\n\n\t\ttry {\n\t\t\tif (!(await auth.isLoggedIn())) {\n\t\t\t\tif (json) {\n\t\t\t\t\tformatOutput({ alreadyLoggedOut: true }, true);\n\t\t\t\t} else {\n\t\t\t\t\tconsole.log(\"Not currently logged in.\");\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Clear auth tokens only (keep config like apiUrl intact)\n\t\t\tawait auth.clear();\n\n\t\t\tif (json) {\n\t\t\t\tformatOutput({ success: true }, true);\n\t\t\t} else {\n\t\t\t\tformatSuccess(\"You have been logged out.\", false);\n\t\t\t}\n\t\t} catch (error) {\n\t\t\thandleError(error, json);\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n","import { Command } from \"commander\";\nimport { cloneCommand } from \"./clone.js\";\nimport { createCommand } from \"./create.js\";\nimport { deleteCommand } from \"./delete.js\";\nimport { fileCommand } from \"./file/index.js\";\nimport { listCommand } from \"./list.js\";\nimport { logsCommand } from \"./logs.js\";\nimport { previewCommand } from \"./preview.js\";\nimport { runCommandCommand } from \"./run-command.js\";\nimport { statusCommand } from \"./status.js\";\nimport { stopCommand } from \"./stop.js\";\nimport { syncCommand } from \"./sync.js\";\nimport { useCommand } from \"./use.js\";\n\nexport const mcpCommand = new Command(\"mcp\")\n\t.description(\"MCP management commands\")\n\t.addCommand(createCommand)\n\t.addCommand(cloneCommand)\n\t.addCommand(listCommand)\n\t.addCommand(useCommand)\n\t.addCommand(statusCommand)\n\t.addCommand(previewCommand)\n\t.addCommand(stopCommand)\n\t.addCommand(logsCommand)\n\t.addCommand(syncCommand)\n\t.addCommand(deleteCommand)\n\t.addCommand(fileCommand)\n\t.addCommand(runCommandCommand);\n","import { execFileSync, execSync } from \"node:child_process\";\nimport { existsSync } from \"node:fs\";\nimport { readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { Command } from \"commander\";\nimport ora from \"ora\";\nimport { api } from \"../../lib/api.js\";\nimport {\n\tCONFIG_FILE_NAME,\n\tinitConfigAt,\n\tLOCAL_CONFIG_DIR,\n} from \"../../lib/config.js\";\nimport { setupGitCredentialHelper } from \"../../lib/credential-helper-setup.js\";\nimport { CLIError, handleError, McpError } from \"../../lib/errors.js\";\nimport {\n\tgetGitAuthContext,\n\trevokeGitHubInstallationToken,\n\trunGitWithCredentials,\n} from \"../../lib/git-auth.js\";\nimport { formatOutput, formatSuccess } from \"../../lib/output.js\";\nimport type {\n\tMcpRepository,\n\tMcpRepositoryListResponse,\n} from \"../../types/index.js\";\n\n/**\n * Load parent .waniwani/settings.json if it exists.\n * Copies all settings including auth tokens, but excludes mcpId (new project gets its own).\n */\nasync function loadParentConfig(\n\tcwd: string,\n): Promise<Record<string, unknown> | null> {\n\tconst parentConfigPath = join(cwd, LOCAL_CONFIG_DIR, CONFIG_FILE_NAME);\n\tif (!existsSync(parentConfigPath)) {\n\t\treturn null;\n\t}\n\n\ttry {\n\t\tconst content = await readFile(parentConfigPath, \"utf-8\");\n\t\tconst config = JSON.parse(content);\n\t\tconst { mcpId: _, sessionId: __, ...rest } = config;\n\t\treturn rest;\n\t} catch {\n\t\treturn null;\n\t}\n}\n\nfunction checkGitInstalled(): void {\n\ttry {\n\t\texecSync(\"git --version\", { stdio: \"ignore\" });\n\t} catch {\n\t\tthrow new CLIError(\n\t\t\t\"git is required but not found. Install it from https://git-scm.com/\",\n\t\t\t\"GIT_NOT_FOUND\",\n\t\t);\n\t}\n}\n\nexport const cloneCommand = new Command(\"clone\")\n\t.description(\"Clone an existing MCP project to a local directory\")\n\t.argument(\"<name>\", \"Name of the MCP to clone\")\n\t.argument(\"[directory]\", \"Directory to clone into (defaults to MCP name)\")\n\t.action(\n\t\tasync (\n\t\t\tname: string,\n\t\t\tdirectory: string | undefined,\n\t\t\t_options: unknown,\n\t\t\tcommand,\n\t\t) => {\n\t\t\tconst globalOptions = command.optsWithGlobals();\n\t\t\tconst json = globalOptions.json ?? false;\n\n\t\t\ttry {\n\t\t\t\tconst cwd = process.cwd();\n\t\t\t\tconst dirName = directory ?? name;\n\t\t\t\tconst projectDir = join(cwd, dirName);\n\n\t\t\t\t// Check if directory already exists\n\t\t\t\tif (existsSync(projectDir)) {\n\t\t\t\t\tif (json) {\n\t\t\t\t\t\tformatOutput(\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tsuccess: false,\n\t\t\t\t\t\t\t\terror: `Directory \"${dirName}\" already exists`,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\ttrue,\n\t\t\t\t\t\t);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tconsole.error(`Error: Directory \"${dirName}\" already exists`);\n\t\t\t\t\t}\n\t\t\t\t\tprocess.exit(1);\n\t\t\t\t}\n\n\t\t\t\tcheckGitInstalled();\n\n\t\t\t\tconst spinner = ora(\"Fetching MCPs...\").start();\n\n\t\t\t\t// Find MCP by name\n\t\t\t\tconst mcps = await api.get<McpRepositoryListResponse>(\n\t\t\t\t\t\"/api/mcp/repositories\",\n\t\t\t\t);\n\t\t\t\tconst mcp = mcps.find((m: McpRepository) => m.name === name);\n\n\t\t\t\tif (!mcp) {\n\t\t\t\t\tspinner.fail(\"MCP not found\");\n\t\t\t\t\tthrow new McpError(\n\t\t\t\t\t\t`MCP \"${name}\" not found. Run 'waniwani mcp list' to see available MCPs.`,\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\t// Get authenticated clone context\n\t\t\t\tspinner.text = \"Cloning repository...\";\n\t\t\t\tconst gitAuth = await getGitAuthContext(mcp.id);\n\n\t\t\t\t// Clone the repository\n\t\t\t\ttry {\n\t\t\t\t\trunGitWithCredentials([\"clone\", gitAuth.remoteUrl, projectDir], {\n\t\t\t\t\t\tstdio: \"ignore\",\n\t\t\t\t\t\tcredentials: gitAuth.credentials,\n\t\t\t\t\t});\n\t\t\t\t} catch {\n\t\t\t\t\tspinner.fail(\"Failed to clone repository\");\n\t\t\t\t\tthrow new CLIError(\n\t\t\t\t\t\t\"Failed to clone repository. Ensure git is configured correctly.\",\n\t\t\t\t\t\t\"CLONE_FAILED\",\n\t\t\t\t\t);\n\t\t\t\t} finally {\n\t\t\t\t\tawait revokeGitHubInstallationToken(gitAuth);\n\t\t\t\t}\n\n\t\t\t\t// Keep origin clean (no embedded credentials/signatures)\n\t\t\t\texecFileSync(\n\t\t\t\t\t\"git\",\n\t\t\t\t\t[\"remote\", \"set-url\", \"origin\", mcp.githubCloneUrl],\n\t\t\t\t\t{\n\t\t\t\t\t\tcwd: projectDir,\n\t\t\t\t\t\tstdio: \"ignore\",\n\t\t\t\t\t},\n\t\t\t\t);\n\n\t\t\t\t// Create .waniwani/settings.json with mcpId\n\t\t\t\tconst parentConfig = await loadParentConfig(cwd);\n\t\t\t\tawait initConfigAt(projectDir, {\n\t\t\t\t\t...parentConfig,\n\t\t\t\t\tmcpId: mcp.id,\n\t\t\t\t});\n\n\t\t\t\t// Set up git credential helper for transparent git push\n\t\t\t\tsetupGitCredentialHelper(projectDir);\n\n\t\t\t\tspinner.succeed(\"Repository cloned\");\n\n\t\t\t\tif (json) {\n\t\t\t\t\tformatOutput(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tsuccess: true,\n\t\t\t\t\t\t\tprojectDir,\n\t\t\t\t\t\t\tmcpId: mcp.id,\n\t\t\t\t\t\t},\n\t\t\t\t\t\ttrue,\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\tconsole.log();\n\t\t\t\t\tformatSuccess(`MCP \"${name}\" cloned!`, false);\n\t\t\t\t\tconsole.log();\n\t\t\t\t\tconsole.log(\"Next steps:\");\n\t\t\t\t\tconsole.log(` cd ${dirName}`);\n\t\t\t\t\tconsole.log(\" waniwani mcp preview # Start developing\");\n\t\t\t\t\tconsole.log(\" git push origin main # Deploy\");\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\thandleError(error, json);\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\t\t},\n\t);\n","import { execFileSync } from \"node:child_process\";\nimport { realpathSync } from \"node:fs\";\n\n/**\n * Configure git credential helper in a repository's local .git/config.\n * Uses the absolute path to the current CLI binary to avoid PATH issues.\n */\nexport function setupGitCredentialHelper(repoDir: string): void {\n\tconst binaryPath = realpathSync(process.argv[1]);\n\tconst helperCommand = `!${process.execPath} ${binaryPath} git-credential-helper`;\n\n\texecFileSync(\n\t\t\"git\",\n\t\t[\"config\", \"--local\", \"credential.helper\", helperCommand],\n\t\t{ cwd: repoDir, stdio: \"ignore\" },\n\t);\n}\n","import { execFileSync, execSync } from \"node:child_process\";\nimport { existsSync } from \"node:fs\";\nimport { readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { Command } from \"commander\";\nimport ora from \"ora\";\nimport { api } from \"../../lib/api.js\";\nimport {\n\tCONFIG_FILE_NAME,\n\tinitConfigAt,\n\tLOCAL_CONFIG_DIR,\n} from \"../../lib/config.js\";\nimport { setupGitCredentialHelper } from \"../../lib/credential-helper-setup.js\";\nimport { CLIError, handleError } from \"../../lib/errors.js\";\nimport {\n\tgetGitAuthContext,\n\trevokeGitHubInstallationToken,\n\trunGitWithCredentials,\n} from \"../../lib/git-auth.js\";\nimport { formatOutput, formatSuccess } from \"../../lib/output.js\";\nimport type { McpRepository } from \"../../types/index.js\";\n\n/**\n * Load parent .waniwani/settings.json if it exists.\n * Copies all settings including auth tokens, but excludes mcpId (new project gets its own).\n */\nasync function loadParentConfig(\n\tcwd: string,\n): Promise<Record<string, unknown> | null> {\n\tconst parentConfigPath = join(cwd, LOCAL_CONFIG_DIR, CONFIG_FILE_NAME);\n\tif (!existsSync(parentConfigPath)) {\n\t\treturn null;\n\t}\n\n\ttry {\n\t\tconst content = await readFile(parentConfigPath, \"utf-8\");\n\t\tconst config = JSON.parse(content);\n\t\t// Remove mcpId from parent - the new project gets its own\n\t\t// Keep auth tokens so user doesn't need to re-login\n\t\tconst { mcpId: _, sessionId: __, ...rest } = config;\n\t\treturn rest;\n\t} catch {\n\t\treturn null;\n\t}\n}\n\nfunction checkGitInstalled(): void {\n\ttry {\n\t\texecSync(\"git --version\", { stdio: \"ignore\" });\n\t} catch {\n\t\tthrow new CLIError(\n\t\t\t\"git is required but not found. Install it from https://git-scm.com/\",\n\t\t\t\"GIT_NOT_FOUND\",\n\t\t);\n\t}\n}\n\nexport const createCommand = new Command(\"create\")\n\t.description(\"Create a new MCP project\")\n\t.argument(\"<name>\", \"Name for the MCP project\")\n\t.action(async (name: string, _options, command) => {\n\t\tconst globalOptions = command.optsWithGlobals();\n\t\tconst json = globalOptions.json ?? false;\n\n\t\ttry {\n\t\t\tconst cwd = process.cwd();\n\t\t\tconst projectDir = join(cwd, name);\n\n\t\t\t// Check if directory already exists\n\t\t\tif (existsSync(projectDir)) {\n\t\t\t\tif (json) {\n\t\t\t\t\tformatOutput(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tsuccess: false,\n\t\t\t\t\t\t\terror: `Directory \"${name}\" already exists`,\n\t\t\t\t\t\t},\n\t\t\t\t\t\ttrue,\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\tconsole.error(`Error: Directory \"${name}\" already exists`);\n\t\t\t\t}\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\n\t\t\t// Check git is installed before making API calls\n\t\t\tcheckGitInstalled();\n\n\t\t\t// Create repository on backend (GitHub repo created immediately)\n\t\t\tconst spinner = ora(\"Creating MCP...\").start();\n\n\t\t\tconst result = await api.post<McpRepository>(\"/api/mcp/repositories\", {\n\t\t\t\tname,\n\t\t\t});\n\n\t\t\t// Get authenticated clone context\n\t\t\tspinner.text = \"Cloning repository...\";\n\t\t\tconst gitAuth = await getGitAuthContext(result.id);\n\n\t\t\t// Clone the repository\n\t\t\ttry {\n\t\t\t\trunGitWithCredentials([\"clone\", gitAuth.remoteUrl, projectDir], {\n\t\t\t\t\tstdio: \"ignore\",\n\t\t\t\t\tcredentials: gitAuth.credentials,\n\t\t\t\t});\n\t\t\t} catch {\n\t\t\t\tspinner.fail(\"Failed to clone repository\");\n\t\t\t\tthrow new CLIError(\n\t\t\t\t\t`Failed to clone repository. Ensure git is configured correctly.`,\n\t\t\t\t\t\"CLONE_FAILED\",\n\t\t\t\t);\n\t\t\t} finally {\n\t\t\t\tawait revokeGitHubInstallationToken(gitAuth);\n\t\t\t}\n\n\t\t\t// Keep origin clean (no embedded credentials/signatures)\n\t\t\texecFileSync(\n\t\t\t\t\"git\",\n\t\t\t\t[\"remote\", \"set-url\", \"origin\", result.githubCloneUrl],\n\t\t\t\t{\n\t\t\t\t\tcwd: projectDir,\n\t\t\t\t\tstdio: \"ignore\",\n\t\t\t\t},\n\t\t\t);\n\n\t\t\t// Create .waniwani/settings.json with mcpId (after clone so dir exists)\n\t\t\tconst parentConfig = await loadParentConfig(cwd);\n\t\t\tawait initConfigAt(projectDir, {\n\t\t\t\t...parentConfig,\n\t\t\t\tmcpId: result.id,\n\t\t\t});\n\n\t\t\t// Set up git credential helper for transparent git push\n\t\t\tsetupGitCredentialHelper(projectDir);\n\n\t\t\tspinner.succeed(\"MCP project created\");\n\n\t\t\tif (json) {\n\t\t\t\tformatOutput(\n\t\t\t\t\t{\n\t\t\t\t\t\tsuccess: true,\n\t\t\t\t\t\tprojectDir,\n\t\t\t\t\t\tmcpId: result.id,\n\t\t\t\t\t},\n\t\t\t\t\ttrue,\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tconsole.log();\n\t\t\t\tformatSuccess(`MCP \"${name}\" created!`, false);\n\t\t\t\tconsole.log();\n\t\t\t\tconsole.log(\"Next steps:\");\n\t\t\t\tconsole.log(` cd ${name}`);\n\t\t\t\tconsole.log(\" waniwani mcp preview # Start developing\");\n\t\t\t\tconsole.log(\" git push origin main # Deploy\");\n\t\t\t}\n\t\t} catch (error) {\n\t\t\thandleError(error, json);\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n","import { confirm } from \"@inquirer/prompts\";\nimport chalk from \"chalk\";\nimport { Command } from \"commander\";\nimport ora from \"ora\";\nimport { api } from \"../../lib/api.js\";\nimport { config } from \"../../lib/config.js\";\nimport { handleError } from \"../../lib/errors.js\";\nimport { formatOutput, formatSuccess } from \"../../lib/output.js\";\nimport { requireMcpId } from \"../../lib/utils.js\";\nimport type { McpRepository } from \"../../types/index.js\";\n\nexport const deleteCommand = new Command(\"delete\")\n\t.description(\"Delete the MCP (includes all associated resources)\")\n\t.option(\"--mcp-id <id>\", \"Specific MCP ID\")\n\t.option(\"--force\", \"Skip confirmation prompt\")\n\t.action(async (options, command) => {\n\t\tconst globalOptions = command.optsWithGlobals();\n\t\tconst json = globalOptions.json ?? false;\n\n\t\ttry {\n\t\t\tconst mcpId = await requireMcpId(options.mcpId);\n\n\t\t\t// Get MCP details for confirmation\n\t\t\tconst mcp = await api.get<McpRepository>(\n\t\t\t\t`/api/mcp/repositories/${mcpId}`,\n\t\t\t);\n\n\t\t\t// Require confirmation unless --force\n\t\t\tif (!options.force && !json) {\n\t\t\t\tconsole.log();\n\t\t\t\tconsole.log(chalk.yellow(\"This will permanently delete:\"));\n\t\t\t\tconsole.log(` - MCP: ${mcp.name}`);\n\t\t\t\tif (mcp.activeSandbox) {\n\t\t\t\t\tconsole.log(\" - Active sandbox\");\n\t\t\t\t}\n\t\t\t\tconsole.log();\n\n\t\t\t\tconst confirmed = await confirm({\n\t\t\t\t\tmessage: `Delete \"${mcp.name}\"?`,\n\t\t\t\t\tdefault: false,\n\t\t\t\t});\n\n\t\t\t\tif (!confirmed) {\n\t\t\t\t\tconsole.log(\"Cancelled.\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst spinner = ora(\"Deleting MCP...\").start();\n\t\t\tawait api.delete(`/api/mcp/repositories/${mcpId}`);\n\t\t\tspinner.succeed(\"MCP deleted\");\n\n\t\t\t// Clear active MCP and session if it was the one we deleted\n\t\t\tif ((await config.getMcpId()) === mcpId) {\n\t\t\t\tawait config.setMcpId(null);\n\t\t\t\tawait config.setSessionId(null);\n\t\t\t}\n\n\t\t\tif (json) {\n\t\t\t\tformatOutput({ deleted: mcpId }, true);\n\t\t\t} else {\n\t\t\t\tformatSuccess(\"MCP deleted.\", false);\n\t\t\t}\n\t\t} catch (error) {\n\t\t\thandleError(error, json);\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n","import { Command } from \"commander\";\nimport { listCommand } from \"./list.js\";\nimport { readCommand } from \"./read.js\";\nimport { writeCommand } from \"./write.js\";\n\nexport const fileCommand = new Command(\"file\")\n\t.description(\"File operations in MCP sandbox\")\n\t.addCommand(readCommand)\n\t.addCommand(writeCommand)\n\t.addCommand(listCommand);\n","import chalk from \"chalk\";\nimport { Command } from \"commander\";\nimport ora from \"ora\";\nimport { api } from \"../../../lib/api.js\";\nimport { handleError } from \"../../../lib/errors.js\";\nimport { formatOutput, formatTable } from \"../../../lib/output.js\";\nimport { requireMcpId, requireSessionId } from \"../../../lib/utils.js\";\nimport type { ListFilesResponse } from \"../../../types/index.js\";\n\nexport const listCommand = new Command(\"list\")\n\t.description(\"List files in the MCP sandbox\")\n\t.argument(\"[path]\", \"Directory path (defaults to /app)\", \"/app\")\n\t.option(\"--mcp-id <id>\", \"Specific MCP ID\")\n\t.action(async (path: string, options, command) => {\n\t\tconst globalOptions = command.optsWithGlobals();\n\t\tconst json = globalOptions.json ?? false;\n\n\t\ttry {\n\t\t\tawait requireMcpId(options.mcpId);\n\t\t\tconst sessionId = await requireSessionId();\n\n\t\t\tconst spinner = ora(`Listing ${path}...`).start();\n\n\t\t\tconst result = await api.get<ListFilesResponse>(\n\t\t\t\t`/api/mcp/sessions/${sessionId}/files/list?path=${encodeURIComponent(path)}`,\n\t\t\t);\n\n\t\t\tspinner.stop();\n\n\t\t\tif (json) {\n\t\t\t\tformatOutput(result, true);\n\t\t\t} else {\n\t\t\t\tconsole.log(chalk.bold(`\\nDirectory: ${result.path}\\n`));\n\n\t\t\t\tif (result.entries.length === 0) {\n\t\t\t\t\tconsole.log(\" (empty)\");\n\t\t\t\t} else {\n\t\t\t\t\tconst rows = result.entries.map((entry) => {\n\t\t\t\t\t\tconst name =\n\t\t\t\t\t\t\tentry.type === \"directory\"\n\t\t\t\t\t\t\t\t? chalk.blue(`${entry.name}/`)\n\t\t\t\t\t\t\t\t: entry.name;\n\t\t\t\t\t\tconst size =\n\t\t\t\t\t\t\tentry.type === \"directory\"\n\t\t\t\t\t\t\t\t? chalk.gray(\"<dir>\")\n\t\t\t\t\t\t\t\t: formatSize(entry.size);\n\t\t\t\t\t\treturn [name, size];\n\t\t\t\t\t});\n\n\t\t\t\t\tformatTable([\"Name\", \"Size\"], rows, false);\n\t\t\t\t}\n\t\t\t\tconsole.log();\n\t\t\t}\n\t\t} catch (error) {\n\t\t\thandleError(error, json);\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n\nfunction formatSize(bytes?: number): string {\n\tif (bytes === undefined) return \"\";\n\tif (bytes < 1024) return `${bytes} B`;\n\tif (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;\n\treturn `${(bytes / (1024 * 1024)).toFixed(1)} MB`;\n}\n","import { writeFile } from \"node:fs/promises\";\nimport { Command } from \"commander\";\nimport ora from \"ora\";\nimport { api } from \"../../../lib/api.js\";\nimport { handleError, McpError } from \"../../../lib/errors.js\";\nimport { formatOutput, formatSuccess } from \"../../../lib/output.js\";\nimport { requireMcpId, requireSessionId } from \"../../../lib/utils.js\";\nimport type { ReadFileResponse } from \"../../../types/index.js\";\n\nexport const readCommand = new Command(\"read\")\n\t.description(\"Read a file from the MCP sandbox\")\n\t.argument(\"<path>\", \"Path in sandbox (e.g., /app/src/index.ts)\")\n\t.option(\"--mcp-id <id>\", \"Specific MCP ID\")\n\t.option(\"--output <file>\", \"Write to local file instead of stdout\")\n\t.option(\"--base64\", \"Output as base64 (for binary files)\")\n\t.action(async (path: string, options, command) => {\n\t\tconst globalOptions = command.optsWithGlobals();\n\t\tconst json = globalOptions.json ?? false;\n\n\t\ttry {\n\t\t\tawait requireMcpId(options.mcpId);\n\t\t\tconst sessionId = await requireSessionId();\n\n\t\t\tconst encoding = options.base64 ? \"base64\" : \"utf8\";\n\t\t\tconst spinner = ora(`Reading ${path}...`).start();\n\n\t\t\tconst result = await api.get<ReadFileResponse>(\n\t\t\t\t`/api/mcp/sessions/${sessionId}/files?path=${encodeURIComponent(path)}&encoding=${encoding}`,\n\t\t\t);\n\n\t\t\tspinner.stop();\n\n\t\t\tif (!result.exists) {\n\t\t\t\tthrow new McpError(`File not found: ${path}`);\n\t\t\t}\n\n\t\t\tif (options.output) {\n\t\t\t\t// Write to local file\n\t\t\t\tconst buffer =\n\t\t\t\t\tresult.encoding === \"base64\"\n\t\t\t\t\t\t? Buffer.from(result.content, \"base64\")\n\t\t\t\t\t\t: Buffer.from(result.content, \"utf8\");\n\t\t\t\tawait writeFile(options.output, buffer);\n\t\t\t\tif (json) {\n\t\t\t\t\tformatOutput({ path, savedTo: options.output }, true);\n\t\t\t\t} else {\n\t\t\t\t\tformatSuccess(`Saved to ${options.output}`, false);\n\t\t\t\t}\n\t\t\t} else if (json) {\n\t\t\t\tformatOutput(result, true);\n\t\t\t} else {\n\t\t\t\t// Print to stdout\n\t\t\t\tprocess.stdout.write(result.content);\n\t\t\t\t// Add newline if content doesn't end with one\n\t\t\t\tif (!result.content.endsWith(\"\\n\")) {\n\t\t\t\t\tprocess.stdout.write(\"\\n\");\n\t\t\t\t}\n\t\t\t}\n\t\t} catch (error) {\n\t\t\thandleError(error, json);\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n","import { readFile } from \"node:fs/promises\";\nimport { Command } from \"commander\";\nimport ora from \"ora\";\nimport { api } from \"../../../lib/api.js\";\nimport { CLIError, handleError } from \"../../../lib/errors.js\";\nimport { formatOutput, formatSuccess } from \"../../../lib/output.js\";\nimport { requireMcpId, requireSessionId } from \"../../../lib/utils.js\";\nimport type { WriteFilesResponse } from \"../../../types/index.js\";\n\nexport const writeCommand = new Command(\"write\")\n\t.description(\"Write a file to the MCP sandbox\")\n\t.argument(\"<path>\", \"Path in sandbox (e.g., /app/src/index.ts)\")\n\t.option(\"--mcp-id <id>\", \"Specific MCP ID\")\n\t.option(\"--content <content>\", \"Content to write\")\n\t.option(\"--file <localFile>\", \"Local file to upload\")\n\t.option(\"--base64\", \"Treat content as base64 encoded\")\n\t.action(async (path: string, options, command) => {\n\t\tconst globalOptions = command.optsWithGlobals();\n\t\tconst json = globalOptions.json ?? false;\n\n\t\ttry {\n\t\t\tawait requireMcpId(options.mcpId);\n\t\t\tconst sessionId = await requireSessionId();\n\n\t\t\t// Get content from --content or --file\n\t\t\tlet content: string;\n\t\t\tlet encoding: \"utf8\" | \"base64\" = \"utf8\";\n\n\t\t\tif (options.content) {\n\t\t\t\tcontent = options.content;\n\t\t\t\tif (options.base64) {\n\t\t\t\t\tencoding = \"base64\";\n\t\t\t\t}\n\t\t\t} else if (options.file) {\n\t\t\t\tconst fileBuffer = await readFile(options.file);\n\t\t\t\tif (options.base64) {\n\t\t\t\t\tcontent = fileBuffer.toString(\"base64\");\n\t\t\t\t\tencoding = \"base64\";\n\t\t\t\t} else {\n\t\t\t\t\tcontent = fileBuffer.toString(\"utf8\");\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tthrow new CLIError(\n\t\t\t\t\t\"Either --content or --file is required\",\n\t\t\t\t\t\"MISSING_CONTENT\",\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst spinner = ora(`Writing ${path}...`).start();\n\n\t\t\tconst result = await api.post<WriteFilesResponse>(\n\t\t\t\t`/api/mcp/sessions/${sessionId}/files`,\n\t\t\t\t{\n\t\t\t\t\tfiles: [{ path, content, encoding }],\n\t\t\t\t},\n\t\t\t);\n\n\t\t\tspinner.succeed(`Wrote ${path}`);\n\n\t\t\tif (json) {\n\t\t\t\tformatOutput(result, true);\n\t\t\t} else {\n\t\t\t\tformatSuccess(`File written: ${path}`, false);\n\t\t\t}\n\t\t} catch (error) {\n\t\t\thandleError(error, json);\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n","import chalk from \"chalk\";\nimport { Command } from \"commander\";\nimport ora from \"ora\";\nimport { api } from \"../../lib/api.js\";\nimport { config } from \"../../lib/config.js\";\nimport { handleError } from \"../../lib/errors.js\";\nimport { formatOutput, formatTable } from \"../../lib/output.js\";\nimport type {\n\tMcpRepository,\n\tMcpRepositoryListResponse,\n} from \"../../types/index.js\";\n\nexport const listCommand = new Command(\"list\")\n\t.description(\"List all MCPs in your organization\")\n\t.action(async (_options, command) => {\n\t\tconst globalOptions = command.optsWithGlobals();\n\t\tconst json = globalOptions.json ?? false;\n\n\t\ttry {\n\t\t\tconst spinner = ora(\"Fetching MCPs...\").start();\n\n\t\t\tconst mcps = await api.get<McpRepositoryListResponse>(\n\t\t\t\t\"/api/mcp/repositories\",\n\t\t\t);\n\n\t\t\tspinner.stop();\n\n\t\t\tconst activeMcpId = await config.getMcpId();\n\n\t\t\tif (json) {\n\t\t\t\tformatOutput(\n\t\t\t\t\t{\n\t\t\t\t\t\tmcps: mcps.map((m: McpRepository) => ({\n\t\t\t\t\t\t\t...m,\n\t\t\t\t\t\t\tisActive: m.id === activeMcpId,\n\t\t\t\t\t\t})),\n\t\t\t\t\t\tactiveMcpId,\n\t\t\t\t\t},\n\t\t\t\t\ttrue,\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tif (mcps.length === 0) {\n\t\t\t\t\tconsole.log(\"No MCPs found.\");\n\t\t\t\t\tconsole.log(\"\\nCreate a new MCP: waniwani mcp create <name>\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconsole.log(chalk.bold(\"\\nMCPs:\\n\"));\n\n\t\t\t\tconst rows = mcps.map((m: McpRepository) => {\n\t\t\t\t\tconst isActive = m.id === activeMcpId;\n\t\t\t\t\tconst deployStatus = m.deployedAt\n\t\t\t\t\t\t? chalk.green(\"Deployed\")\n\t\t\t\t\t\t: chalk.yellow(\"Pending\");\n\t\t\t\t\tconst sandboxStatus = m.activeSandbox\n\t\t\t\t\t\t? chalk.green(\"Active\")\n\t\t\t\t\t\t: chalk.gray(\"None\");\n\t\t\t\t\tconst lastDeploy = m.deployedAt\n\t\t\t\t\t\t? new Date(m.deployedAt).toLocaleDateString()\n\t\t\t\t\t\t: chalk.gray(\"Never\");\n\n\t\t\t\t\treturn [\n\t\t\t\t\t\tisActive ? chalk.cyan(`* ${m.name}`) : ` ${m.name}`,\n\t\t\t\t\t\tdeployStatus,\n\t\t\t\t\t\tsandboxStatus,\n\t\t\t\t\t\tlastDeploy,\n\t\t\t\t\t];\n\t\t\t\t});\n\n\t\t\t\tformatTable([\"Name\", \"Status\", \"Sandbox\", \"Last Deploy\"], rows, false);\n\n\t\t\t\tconsole.log();\n\t\t\t\tif (activeMcpId) {\n\t\t\t\t\tconst activeMcp = mcps.find((m) => m.id === activeMcpId);\n\t\t\t\t\tif (activeMcp) {\n\t\t\t\t\t\tconsole.log(`Active MCP: ${chalk.cyan(activeMcp.name)}`);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tconsole.log(\"\\nSelect an MCP: waniwani mcp use <name>\");\n\t\t\t}\n\t\t} catch (error) {\n\t\t\thandleError(error, json);\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n","import chalk from \"chalk\";\nimport { Command } from \"commander\";\nimport ora from \"ora\";\nimport { api } from \"../../lib/api.js\";\nimport { auth } from \"../../lib/auth.js\";\nimport { AuthError, handleError, McpError } from \"../../lib/errors.js\";\nimport { formatOutput } from \"../../lib/output.js\";\nimport { requireMcpId, requireSessionId } from \"../../lib/utils.js\";\nimport type { LogEvent, ServerStatusResponse } from \"../../types/index.js\";\n\nexport const logsCommand = new Command(\"logs\")\n\t.description(\"Stream logs from the MCP server\")\n\t.argument(\"[cmdId]\", \"Command ID (defaults to running server)\")\n\t.option(\"--mcp-id <id>\", \"Specific MCP ID\")\n\t.option(\"-f, --follow\", \"Keep streaming logs (default)\", true)\n\t.option(\"--no-follow\", \"Fetch logs and exit\")\n\t.action(async (cmdIdArg: string | undefined, options, command) => {\n\t\tconst globalOptions = command.optsWithGlobals();\n\t\tconst json = globalOptions.json ?? false;\n\n\t\tlet reader: ReadableStreamDefaultReader<Uint8Array> | undefined;\n\n\t\t// Handle Ctrl+C gracefully\n\t\tconst cleanup = () => {\n\t\t\tif (reader) {\n\t\t\t\treader.cancel().catch(() => {});\n\t\t\t}\n\t\t\tprocess.exit(0);\n\t\t};\n\t\tprocess.on(\"SIGINT\", cleanup);\n\t\tprocess.on(\"SIGTERM\", cleanup);\n\n\t\ttry {\n\t\t\tawait requireMcpId(options.mcpId);\n\t\t\tconst sessionId = await requireSessionId();\n\n\t\t\tconst token = await auth.getAccessToken();\n\t\t\tif (!token) {\n\t\t\t\tthrow new AuthError(\n\t\t\t\t\t\"Not logged in. Run 'waniwani login' to authenticate.\",\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tlet cmdId = cmdIdArg;\n\n\t\t\t// If no cmdId provided, get it from server status\n\t\t\tif (!cmdId) {\n\t\t\t\tconst spinner = ora(\"Getting server status...\").start();\n\t\t\t\tconst status = await api.post<ServerStatusResponse>(\n\t\t\t\t\t`/api/mcp/sessions/${sessionId}/server`,\n\t\t\t\t\t{ action: \"status\" },\n\t\t\t\t);\n\t\t\t\tspinner.stop();\n\n\t\t\t\tif (!status.running || !status.cmdId) {\n\t\t\t\t\tthrow new McpError(\n\t\t\t\t\t\t\"No server is running. Run 'waniwani mcp preview' first.\",\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tcmdId = status.cmdId;\n\t\t\t}\n\n\t\t\tconst baseUrl = await api.getBaseUrl();\n\t\t\tconst streamParam = options.follow ? \"?stream=true\" : \"\";\n\t\t\tconst url = `${baseUrl}/api/mcp/sessions/${sessionId}/commands/${cmdId}${streamParam}`;\n\n\t\t\tif (!json) {\n\t\t\t\tconsole.log(chalk.gray(`Streaming logs for command ${cmdId}...`));\n\t\t\t\tconsole.log(chalk.gray(\"Press Ctrl+C to stop\\n\"));\n\t\t\t}\n\n\t\t\tconst response = await fetch(url, {\n\t\t\t\tmethod: \"GET\",\n\t\t\t\theaders: {\n\t\t\t\t\tAuthorization: `Bearer ${token}`,\n\t\t\t\t\tAccept: options.follow ? \"text/event-stream\" : \"application/json\",\n\t\t\t\t},\n\t\t\t});\n\n\t\t\tif (!response.ok) {\n\t\t\t\tconst error = await response\n\t\t\t\t\t.json()\n\t\t\t\t\t.catch(() => ({ message: response.statusText }));\n\t\t\t\tthrow new Error(\n\t\t\t\t\terror.message || `Request failed with status ${response.status}`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// Non-streaming mode\n\t\t\tif (!options.follow) {\n\t\t\t\tconst data = await response.json();\n\t\t\t\tif (json) {\n\t\t\t\t\tformatOutput(data, true);\n\t\t\t\t} else {\n\t\t\t\t\tif (data.stdout) {\n\t\t\t\t\t\tprocess.stdout.write(data.stdout);\n\t\t\t\t\t}\n\t\t\t\t\tif (data.stderr) {\n\t\t\t\t\t\tprocess.stderr.write(chalk.red(data.stderr));\n\t\t\t\t\t}\n\t\t\t\t\tif (data.exitCode !== undefined) {\n\t\t\t\t\t\tconsole.log(chalk.gray(`\\nExit code: ${data.exitCode}`));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Streaming mode\n\t\t\treader = response.body?.getReader();\n\t\t\tif (!reader) {\n\t\t\t\tthrow new Error(\"No response body\");\n\t\t\t}\n\n\t\t\tconst decoder = new TextDecoder();\n\t\t\tlet buffer = \"\";\n\t\t\tconst collectedLogs: LogEvent[] = [];\n\n\t\t\twhile (true) {\n\t\t\t\tconst { done, value } = await reader.read();\n\t\t\t\tif (done) break;\n\n\t\t\t\tbuffer += decoder.decode(value, { stream: true });\n\t\t\t\tconst lines = buffer.split(\"\\n\");\n\t\t\t\tbuffer = lines.pop() || \"\";\n\n\t\t\t\tfor (const line of lines) {\n\t\t\t\t\tif (line.startsWith(\"event: \")) {\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (line.startsWith(\"data: \")) {\n\t\t\t\t\t\tconst data = line.slice(6);\n\t\t\t\t\t\tif (!data || data === \"[DONE]\") continue;\n\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tconst event = JSON.parse(data) as LogEvent;\n\t\t\t\t\t\t\tcollectedLogs.push(event);\n\n\t\t\t\t\t\t\tif (json) {\n\t\t\t\t\t\t\t\t// In JSON mode, we'll output at the end\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// Handle different event types\n\t\t\t\t\t\t\tif (event.cmdId) {\n\t\t\t\t\t\t\t\t// Initial event with cmdId\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif (event.stream && event.data !== undefined) {\n\t\t\t\t\t\t\t\tif (event.stream === \"stdout\") {\n\t\t\t\t\t\t\t\t\tprocess.stdout.write(event.data);\n\t\t\t\t\t\t\t\t} else if (event.stream === \"stderr\") {\n\t\t\t\t\t\t\t\t\tprocess.stderr.write(chalk.red(event.data));\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif (event.exitCode !== undefined) {\n\t\t\t\t\t\t\t\tconst exitColor =\n\t\t\t\t\t\t\t\t\tevent.exitCode === 0 ? chalk.green : chalk.red;\n\t\t\t\t\t\t\t\tconsole.log(\n\t\t\t\t\t\t\t\t\texitColor(`\\nProcess exited with code ${event.exitCode}`),\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif (event.error) {\n\t\t\t\t\t\t\t\tconsole.error(chalk.red(`\\nError: ${event.error}`));\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\t// Ignore malformed JSON\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Output collected logs in JSON mode\n\t\t\tif (json) {\n\t\t\t\tformatOutput(collectedLogs, true);\n\t\t\t}\n\t\t} catch (error) {\n\t\t\thandleError(error, json);\n\t\t\tprocess.exit(1);\n\t\t} finally {\n\t\t\tprocess.off(\"SIGINT\", cleanup);\n\t\t\tprocess.off(\"SIGTERM\", cleanup);\n\t\t}\n\t});\n","import { existsSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { watch } from \"chokidar\";\nimport { Command, InvalidArgumentError } from \"commander\";\nimport ora from \"ora\";\nimport { api } from \"../../lib/api.js\";\nimport { withTimeout } from \"../../lib/async.js\";\nimport { config } from \"../../lib/config.js\";\nimport { CLIError, handleError } from \"../../lib/errors.js\";\nimport { formatSuccess } from \"../../lib/output.js\";\nimport {\n\tcollectFiles,\n\tcollectSingleFile,\n\tfindProjectRoot,\n\tloadIgnorePatterns,\n} from \"../../lib/sync.js\";\nimport type {\n\tMcpSandbox,\n\tRunCommandResponse,\n\tSandboxStartResponse,\n\tServerStartResponse,\n\tServerStatusResponse,\n\tWriteFilesResponse,\n} from \"../../types/index.js\";\n\nconst SHUTDOWN_MAX_WAIT_MS = 3000;\nconst SHUTDOWN_STEP_TIMEOUT_MS = 1200;\nconst DEV_SERVER_VERIFY_ATTEMPTS = 4;\nconst DEV_SERVER_VERIFY_INTERVAL_MS = 750;\nconst DEFAULT_DEV_SERVER_MONITOR_INTERVAL_MS = 60000;\n\ntype SessionInfo = {\n\tid: string;\n\tpreviewUrl: string;\n\tsandboxId?: string;\n};\n\ntype CommandStatusResponse = {\n\tcmdId: string;\n\texitCode: number | null;\n\trunning: boolean;\n};\n\ntype CommandOutputResponse = {\n\tcmdId: string;\n\texitCode: number | null;\n\tstdout: string;\n\tstderr: string;\n};\n\ntype PackageManager = \"bun\" | \"pnpm\" | \"yarn\" | \"npm-ci\" | \"npm\";\n\nconst MAX_INSTALL_TIMEOUT_MS = 300000;\n\nfunction resolveSessionInfo(\n\tresponse:\n\t\t| SandboxStartResponse\n\t\t| McpSandbox\n\t\t| (McpSandbox & { sandbox?: McpSandbox }),\n): SessionInfo {\n\t// Legacy shape: { sandbox: {...}, previewUrl }\n\tconst maybeLegacy = response as SandboxStartResponse;\n\tif (maybeLegacy?.sandbox?.id && maybeLegacy?.previewUrl) {\n\t\treturn {\n\t\t\tid: maybeLegacy.sandbox.id,\n\t\t\tpreviewUrl: maybeLegacy.previewUrl,\n\t\t\tsandboxId: maybeLegacy.sandbox.sandboxId,\n\t\t};\n\t}\n\n\t// Current shape: session object itself\n\tconst maybeSession = response as McpSandbox;\n\tif (maybeSession?.id && maybeSession?.previewUrl) {\n\t\treturn {\n\t\t\tid: maybeSession.id,\n\t\t\tpreviewUrl: maybeSession.previewUrl,\n\t\t\tsandboxId: maybeSession.sandboxId,\n\t\t};\n\t}\n\n\tthrow new CLIError(\"Invalid session response from API\", \"SESSION_ERROR\");\n}\n\nfunction detectPackageManager(projectRoot: string): PackageManager {\n\tif (\n\t\texistsSync(join(projectRoot, \"bun.lock\")) ||\n\t\texistsSync(join(projectRoot, \"bun.lockb\"))\n\t) {\n\t\treturn \"bun\";\n\t}\n\tif (existsSync(join(projectRoot, \"pnpm-lock.yaml\"))) return \"pnpm\";\n\tif (existsSync(join(projectRoot, \"yarn.lock\"))) return \"yarn\";\n\tif (\n\t\texistsSync(join(projectRoot, \"package-lock.json\")) ||\n\t\texistsSync(join(projectRoot, \"npm-shrinkwrap.json\"))\n\t) {\n\t\treturn \"npm-ci\";\n\t}\n\treturn \"npm\";\n}\n\nfunction getInstallCommand(pm: PackageManager): {\n\tcommand: string;\n\targs: string[];\n} {\n\tswitch (pm) {\n\t\tcase \"bun\":\n\t\t\treturn { command: \"bun\", args: [\"install\", \"--frozen-lockfile\"] };\n\t\tcase \"pnpm\":\n\t\t\treturn {\n\t\t\t\tcommand: \"pnpm\",\n\t\t\t\targs: [\"install\", \"--frozen-lockfile\", \"--prefer-offline\"],\n\t\t\t};\n\t\tcase \"yarn\":\n\t\t\treturn {\n\t\t\t\tcommand: \"yarn\",\n\t\t\t\targs: [\"install\", \"--frozen-lockfile\", \"--prefer-offline\"],\n\t\t\t};\n\t\tcase \"npm-ci\":\n\t\t\treturn {\n\t\t\t\tcommand: \"npm\",\n\t\t\t\targs: [\"ci\", \"--no-audit\", \"--no-fund\", \"--prefer-offline\"],\n\t\t\t};\n\t\tdefault:\n\t\t\treturn {\n\t\t\t\tcommand: \"npm\",\n\t\t\t\targs: [\"install\", \"--no-audit\", \"--no-fund\"],\n\t\t\t};\n\t}\n}\n\nfunction getNonFrozenInstallCommand(pm: PackageManager): {\n\tcommand: string;\n\targs: string[];\n} | null {\n\tswitch (pm) {\n\t\tcase \"bun\":\n\t\t\treturn { command: \"bun\", args: [\"install\"] };\n\t\tcase \"pnpm\":\n\t\t\treturn { command: \"pnpm\", args: [\"install\", \"--prefer-offline\"] };\n\t\tcase \"yarn\":\n\t\t\treturn { command: \"yarn\", args: [\"install\", \"--prefer-offline\"] };\n\t\tcase \"npm-ci\":\n\t\t\treturn { command: \"npm\", args: [\"install\", \"--no-audit\", \"--no-fund\"] };\n\t\tdefault:\n\t\t\treturn null;\n\t}\n}\n\nfunction shouldRetryWithoutFrozenLockfile(result: RunCommandResponse): boolean {\n\tconst output = `${result.stderr}\\n${result.stdout}`.toLowerCase();\n\tconst npmLockMismatchDetected =\n\t\t(output.includes(\"update your lock file\") &&\n\t\t\toutput.includes(\"npm install\")) ||\n\t\t(output.includes(\"package-lock.json\") && output.includes(\"not in sync\")) ||\n\t\t(output.includes(\"package-lock.json\") &&\n\t\t\toutput.includes(\"are not in sync\")) ||\n\t\t(output.includes(\"npm ci\") &&\n\t\t\toutput.includes(\"can only install packages\") &&\n\t\t\toutput.includes(\"package-lock.json\"));\n\n\treturn (\n\t\toutput.includes(\"frozen-lockfile\") ||\n\t\toutput.includes(\"lockfile had changes\") ||\n\t\toutput.includes(\"lockfile is frozen\") ||\n\t\t(output.includes(\"lockfile\") && output.includes(\"out of date\")) ||\n\t\tnpmLockMismatchDetected\n\t);\n}\n\nfunction isAlreadyRunningServerError(error: unknown): boolean {\n\tconst normalized = getNormalizedError(error);\n\treturn (\n\t\tnormalized.includes(\"already_running\") ||\n\t\tnormalized.includes(\"already running\")\n\t);\n}\n\nfunction isServerNotRunningError(error: unknown): boolean {\n\tconst normalized = getNormalizedError(error);\n\treturn (\n\t\tnormalized.includes(\"server_not_running\") ||\n\t\tnormalized.includes(\"server not running\")\n\t);\n}\n\nfunction getNormalizedError(error: unknown): string {\n\tif (!(error instanceof CLIError)) return \"\";\n\tconst details = JSON.stringify(error.details ?? {}).toLowerCase();\n\treturn `${error.code} ${error.message} ${details}`.toLowerCase();\n}\n\nasync function getServerStatusOrNull(\n\tsessionId: string,\n): Promise<ServerStatusResponse | null> {\n\ttry {\n\t\treturn await api.get<ServerStatusResponse>(\n\t\t\t`/api/mcp/sessions/${sessionId}/server`,\n\t\t);\n\t} catch (error) {\n\t\tif (isServerNotRunningError(error)) {\n\t\t\treturn null;\n\t\t}\n\t\tthrow error;\n\t}\n}\n\nfunction getDevCommand(pm: PackageManager): string {\n\tswitch (pm) {\n\t\tcase \"bun\":\n\t\t\treturn \"bun run dev\";\n\t\tcase \"pnpm\":\n\t\t\treturn \"pnpm run dev\";\n\t\tcase \"yarn\":\n\t\t\treturn \"yarn run dev\";\n\t\tdefault:\n\t\t\treturn \"npm run dev\";\n\t}\n}\n\nfunction sleep(ms: number): Promise<void> {\n\treturn new Promise((resolve) => {\n\t\tsetTimeout(resolve, ms);\n\t});\n}\n\nfunction parseStatusPollIntervalMs(value: string): number {\n\tconst parsed = Number(value);\n\tif (!Number.isInteger(parsed) || parsed < 500) {\n\t\tthrow new InvalidArgumentError(\n\t\t\t\"Status poll interval must be an integer >= 500 milliseconds.\",\n\t\t);\n\t}\n\treturn parsed;\n}\n\nasync function getCommandOutputOrNull(\n\tsessionId: string,\n\tcmdId: string,\n): Promise<CommandOutputResponse | null> {\n\ttry {\n\t\treturn await api.get<CommandOutputResponse>(\n\t\t\t`/api/mcp/sessions/${sessionId}/commands/${cmdId}`,\n\t\t);\n\t} catch {\n\t\treturn null;\n\t}\n}\n\nasync function cleanupPreviewSession(sessionId: string): Promise<void> {\n\tawait withTimeout(\n\t\tapi\n\t\t\t.post(`/api/mcp/sessions/${sessionId}/server`, { action: \"stop\" })\n\t\t\t.catch(() => undefined),\n\t\tSHUTDOWN_STEP_TIMEOUT_MS,\n\t);\n\n\tawait withTimeout(\n\t\tapi.delete(`/api/mcp/sessions/${sessionId}`).catch(() => undefined),\n\t\tSHUTDOWN_STEP_TIMEOUT_MS,\n\t);\n\n\tawait withTimeout(\n\t\tconfig.setSessionId(null).catch(() => undefined),\n\t\tSHUTDOWN_STEP_TIMEOUT_MS,\n\t);\n}\n\nexport const previewCommand = new Command(\"preview\")\n\t.description(\"Start live development with sandbox and file watching\")\n\t.option(\"--mcp-id <id>\", \"Specific MCP ID\")\n\t.option(\"--no-watch\", \"Skip file watching\")\n\t.option(\"--no-logs\", \"Don't stream logs to terminal\")\n\t.option(\n\t\t\"--status-poll-interval-ms <ms>\",\n\t\t\"Watch-mode server status polling interval in milliseconds (default: 60000)\",\n\t\tparseStatusPollIntervalMs,\n\t\tDEFAULT_DEV_SERVER_MONITOR_INTERVAL_MS,\n\t)\n\t.action(async (options, command) => {\n\t\tconst globalOptions = command.optsWithGlobals();\n\t\tconst json = globalOptions.json ?? false;\n\t\tconst statusPollIntervalMs =\n\t\t\toptions.statusPollIntervalMs ?? DEFAULT_DEV_SERVER_MONITOR_INTERVAL_MS;\n\n\t\ttry {\n\t\t\t// Find project root and MCP ID\n\t\t\tconst projectRoot = await findProjectRoot(process.cwd());\n\t\t\tif (!projectRoot) {\n\t\t\t\tthrow new CLIError(\n\t\t\t\t\t\"Not in a WaniWani project. Run 'waniwani mcp create <name>' first.\",\n\t\t\t\t\t\"NOT_IN_PROJECT\",\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tlet mcpId = options.mcpId;\n\t\t\tif (!mcpId) {\n\t\t\t\tmcpId = await config.getMcpId();\n\t\t\t}\n\t\t\tif (!mcpId) {\n\t\t\t\tthrow new CLIError(\n\t\t\t\t\t\"No MCP found. Run 'waniwani mcp create <name>' or use --mcp-id.\",\n\t\t\t\t\t\"NO_MCP\",\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst spinner = ora(\"Starting development environment...\").start();\n\n\t\t\t// Step 1: Create or get session (this also starts the sandbox)\n\t\t\tspinner.text = \"Starting session...\";\n\t\t\tlet sessionId: string;\n\t\t\tlet previewUrl: string;\n\t\t\tlet sandboxId: string | undefined;\n\t\t\ttry {\n\t\t\t\tconst sessionResponse = await api.post<SandboxStartResponse>(\n\t\t\t\t\t`/api/mcp/repositories/${mcpId}/session`,\n\t\t\t\t\t{},\n\t\t\t\t);\n\t\t\t\tconst sessionInfo = resolveSessionInfo(sessionResponse);\n\t\t\t\tsessionId = sessionInfo.id;\n\t\t\t\tpreviewUrl = sessionInfo.previewUrl;\n\t\t\t\tsandboxId = sessionInfo.sandboxId;\n\t\t\t} catch {\n\t\t\t\t// Session might already exist, try to get it\n\t\t\t\tconst existing = await api.get<McpSandbox | null>(\n\t\t\t\t\t`/api/mcp/repositories/${mcpId}/session`,\n\t\t\t\t);\n\t\t\t\tif (!existing) {\n\t\t\t\t\tthrow new CLIError(\"Failed to start session\", \"SESSION_ERROR\");\n\t\t\t\t}\n\t\t\t\tconst sessionInfo = resolveSessionInfo(existing);\n\t\t\t\tsessionId = sessionInfo.id;\n\t\t\t\tpreviewUrl = sessionInfo.previewUrl;\n\t\t\t\tsandboxId = sessionInfo.sandboxId;\n\t\t\t}\n\n\t\t\t// Store session ID in config\n\t\t\tawait config.setSessionId(sessionId);\n\n\t\t\t// Step 2: Sync current files to sandbox (CLI-driven hydration)\n\t\t\tspinner.text = \"Syncing files to sandbox...\";\n\t\t\tconst files = await collectFiles(projectRoot, { includeEnvFiles: true });\n\t\t\tif (files.length > 0) {\n\t\t\t\tawait api.post<WriteFilesResponse>(\n\t\t\t\t\t`/api/mcp/sessions/${sessionId}/files`,\n\t\t\t\t\t{ files },\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// Step 3: Install dependencies to match local state\n\t\t\tconst packageManager = detectPackageManager(projectRoot);\n\t\t\tlet installCommand = getInstallCommand(packageManager);\n\t\t\tspinner.text = `Installing dependencies (${installCommand.command})...`;\n\t\t\tlet installResult = await api.post<RunCommandResponse>(\n\t\t\t\t`/api/mcp/sessions/${sessionId}/commands`,\n\t\t\t\t{\n\t\t\t\t\tcommand: installCommand.command,\n\t\t\t\t\targs: installCommand.args,\n\t\t\t\t\ttimeout: MAX_INSTALL_TIMEOUT_MS,\n\t\t\t\t},\n\t\t\t);\n\n\t\t\tif (installResult.exitCode !== 0) {\n\t\t\t\tconst nonFrozenInstallCommand =\n\t\t\t\t\tgetNonFrozenInstallCommand(packageManager);\n\t\t\t\tif (\n\t\t\t\t\tnonFrozenInstallCommand &&\n\t\t\t\t\tshouldRetryWithoutFrozenLockfile(installResult)\n\t\t\t\t) {\n\t\t\t\t\tinstallCommand = nonFrozenInstallCommand;\n\t\t\t\t\tspinner.text = `Retrying install without frozen lockfile (${installCommand.command})...`;\n\t\t\t\t\tinstallResult = await api.post<RunCommandResponse>(\n\t\t\t\t\t\t`/api/mcp/sessions/${sessionId}/commands`,\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcommand: installCommand.command,\n\t\t\t\t\t\t\targs: installCommand.args,\n\t\t\t\t\t\t\ttimeout: MAX_INSTALL_TIMEOUT_MS,\n\t\t\t\t\t\t},\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (installResult.exitCode !== 0) {\n\t\t\t\tthrow new CLIError(\n\t\t\t\t\tinstallResult.stderr ||\n\t\t\t\t\t\t`Dependency install failed with exit code ${installResult.exitCode}`,\n\t\t\t\t\t\"SANDBOX_HYDRATION_FAILED\",\n\t\t\t\t\t{\n\t\t\t\t\t\tcommand: [installCommand.command, ...installCommand.args].join(\" \"),\n\t\t\t\t\t\texitCode: installResult.exitCode,\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// Step 4: Start server with package-manager-aware dev command\n\t\t\tconst devCommand = getDevCommand(packageManager);\n\t\t\tlet serverCmdId: string | undefined;\n\t\t\tlet didStartServer = false;\n\n\t\t\tconst serverStatus = await getServerStatusOrNull(sessionId);\n\t\t\tconst serverStatusPreviewUrl = serverStatus?.previewUrl;\n\t\t\tif (serverStatusPreviewUrl) {\n\t\t\t\tpreviewUrl = serverStatusPreviewUrl;\n\t\t\t}\n\n\t\t\tif (serverStatus?.running) {\n\t\t\t\tspinner.text = \"Server already running, attaching...\";\n\t\t\t\tserverCmdId = serverStatus.cmdId;\n\t\t\t} else {\n\t\t\t\tspinner.text = `Starting server (${devCommand})...`;\n\t\t\t\ttry {\n\t\t\t\t\tconst serverStart = await api.post<ServerStartResponse>(\n\t\t\t\t\t\t`/api/mcp/sessions/${sessionId}/server`,\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\taction: \"start\",\n\t\t\t\t\t\t\tcommand: devCommand,\n\t\t\t\t\t\t},\n\t\t\t\t\t);\n\t\t\t\t\tconst serverStartPreviewUrl = serverStart.previewUrl;\n\t\t\t\t\tif (serverStartPreviewUrl) {\n\t\t\t\t\t\tpreviewUrl = serverStartPreviewUrl;\n\t\t\t\t\t}\n\t\t\t\t\tserverCmdId = serverStart.cmdId;\n\t\t\t\t\tdidStartServer = true;\n\t\t\t\t} catch (error) {\n\t\t\t\t\tif (!isAlreadyRunningServerError(error)) {\n\t\t\t\t\t\tthrow error;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst refreshedStatus = await getServerStatusOrNull(sessionId);\n\t\t\t\t\tif (!refreshedStatus?.running) {\n\t\t\t\t\t\tthrow error;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst refreshedPreviewUrl = refreshedStatus.previewUrl;\n\t\t\t\t\tif (refreshedPreviewUrl) {\n\t\t\t\t\t\tpreviewUrl = refreshedPreviewUrl;\n\t\t\t\t\t}\n\t\t\t\t\tserverCmdId = refreshedStatus.cmdId;\n\t\t\t\t\tspinner.text = \"Server already running, attaching...\";\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (didStartServer && !serverCmdId) {\n\t\t\t\tawait cleanupPreviewSession(sessionId);\n\t\t\t\tthrow new CLIError(\n\t\t\t\t\t\"Server start command ID was not returned by the API.\",\n\t\t\t\t\t\"SERVER_START_FAILED\",\n\t\t\t\t\t{ command: devCommand },\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tif (didStartServer && serverCmdId) {\n\t\t\t\tspinner.text = \"Verifying server startup...\";\n\t\t\t\tfor (let attempt = 0; attempt < DEV_SERVER_VERIFY_ATTEMPTS; attempt++) {\n\t\t\t\t\tif (attempt > 0) {\n\t\t\t\t\t\tawait sleep(DEV_SERVER_VERIFY_INTERVAL_MS);\n\t\t\t\t\t}\n\n\t\t\t\t\tconst commandStatus = await api.get<CommandStatusResponse>(\n\t\t\t\t\t\t`/api/mcp/sessions/${sessionId}/commands/${serverCmdId}?statusOnly=true`,\n\t\t\t\t\t);\n\n\t\t\t\t\tif (commandStatus.exitCode === null) {\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst commandOutput = await api\n\t\t\t\t\t\t.get<CommandOutputResponse>(\n\t\t\t\t\t\t\t`/api/mcp/sessions/${sessionId}/commands/${serverCmdId}`,\n\t\t\t\t\t\t)\n\t\t\t\t\t\t.catch(() => null);\n\n\t\t\t\t\tawait cleanupPreviewSession(sessionId);\n\t\t\t\t\tthrow new CLIError(\n\t\t\t\t\t\t`Dev server command exited during startup with code ${commandStatus.exitCode}.`,\n\t\t\t\t\t\t\"SERVER_START_FAILED\",\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcommand: devCommand,\n\t\t\t\t\t\t\tcmdId: serverCmdId,\n\t\t\t\t\t\t\texitCode: commandStatus.exitCode,\n\t\t\t\t\t\t\tstdout: commandOutput?.stdout ?? \"\",\n\t\t\t\t\t\t\tstderr: commandOutput?.stderr ?? \"\",\n\t\t\t\t\t\t},\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tspinner.succeed(\"Development environment ready\");\n\n\t\t\tconsole.log();\n\t\t\tformatSuccess(\"Live preview started!\", false);\n\t\t\tconsole.log();\n\t\t\tif (sandboxId) {\n\t\t\t\tconsole.log(` Sandbox ID: ${sandboxId}`);\n\t\t\t}\n\t\t\tconsole.log(` Preview URL: ${previewUrl}`);\n\t\t\tconsole.log();\n\t\t\tconsole.log(` MCP Inspector:`);\n\t\t\tconsole.log(\n\t\t\t\t` npx @modelcontextprotocol/inspector@latest --transport http --server-url \"${previewUrl}/mcp\"`,\n\t\t\t);\n\t\t\tconsole.log();\n\n\t\t\tif (options.watch !== false) {\n\t\t\t\tconsole.log(\"Watching for file changes... (Ctrl+C to stop)\");\n\t\t\t\tconsole.log();\n\n\t\t\t\t// Step 5: Start file watcher\n\t\t\t\tconst ig = await loadIgnorePatterns(projectRoot, {\n\t\t\t\t\tincludeEnvFiles: true,\n\t\t\t\t});\n\n\t\t\t\tconst watcher = watch(projectRoot, {\n\t\t\t\t\tignored: (path) => {\n\t\t\t\t\t\t// Get relative path from project root\n\t\t\t\t\t\tconst relative = path.replace(`${projectRoot}/`, \"\");\n\t\t\t\t\t\tif (relative === path) return false; // Don't ignore the root\n\t\t\t\t\t\treturn ig.ignores(relative);\n\t\t\t\t\t},\n\t\t\t\t\tpersistent: true,\n\t\t\t\t\tignoreInitial: true,\n\t\t\t\t\tawaitWriteFinish: {\n\t\t\t\t\t\tstabilityThreshold: 100,\n\t\t\t\t\t\tpollInterval: 50,\n\t\t\t\t\t},\n\t\t\t\t});\n\n\t\t\t\tconst syncFile = async (filePath: string) => {\n\t\t\t\t\tconst relativePath = filePath.replace(`${projectRoot}/`, \"\");\n\t\t\t\t\tconst file = await collectSingleFile(projectRoot, relativePath);\n\t\t\t\t\tif (file) {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tawait api.post<WriteFilesResponse>(\n\t\t\t\t\t\t\t\t`/api/mcp/sessions/${sessionId}/files`,\n\t\t\t\t\t\t\t\t{ files: [file] },\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tconsole.log(` Synced: ${relativePath}`);\n\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\tconsole.error(` Failed to sync: ${relativePath}`);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t};\n\n\t\t\t\twatcher.on(\"add\", syncFile);\n\t\t\t\twatcher.on(\"change\", syncFile);\n\t\t\t\twatcher.on(\"unlink\", (filePath) => {\n\t\t\t\t\tconst relativePath = filePath.replace(`${projectRoot}/`, \"\");\n\t\t\t\t\tconsole.log(` Deleted: ${relativePath}`);\n\t\t\t\t});\n\n\t\t\t\tlet shuttingDown = false;\n\t\t\t\tlet serverMonitorInterval: NodeJS.Timeout | null = null;\n\t\t\t\tconst gracefulShutdown = async (exitCode = 0) => {\n\t\t\t\t\tif (shuttingDown) return;\n\t\t\t\t\tshuttingDown = true;\n\t\t\t\t\tif (serverMonitorInterval) {\n\t\t\t\t\t\tclearInterval(serverMonitorInterval);\n\t\t\t\t\t\tserverMonitorInterval = null;\n\t\t\t\t\t}\n\n\t\t\t\t\tconsole.log();\n\t\t\t\t\tconsole.log(\"Stopping development environment...\");\n\n\t\t\t\t\ttry {\n\t\t\t\t\t\tawait withTimeout(\n\t\t\t\t\t\t\t(async () => {\n\t\t\t\t\t\t\t\tawait withTimeout(\n\t\t\t\t\t\t\t\t\twatcher.close().catch(() => undefined),\n\t\t\t\t\t\t\t\t\tSHUTDOWN_STEP_TIMEOUT_MS,\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\tawait cleanupPreviewSession(sessionId);\n\t\t\t\t\t\t\t})(),\n\t\t\t\t\t\t\tSHUTDOWN_MAX_WAIT_MS,\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tonTimeout: () => {\n\t\t\t\t\t\t\t\t\tconsole.log(\"Shutdown timed out, forcing exit.\");\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t);\n\t\t\t\t\t} finally {\n\t\t\t\t\t\tprocess.exit(exitCode);\n\t\t\t\t\t}\n\t\t\t\t};\n\n\t\t\t\tif (serverCmdId) {\n\t\t\t\t\tserverMonitorInterval = setInterval(() => {\n\t\t\t\t\t\tif (shuttingDown) return;\n\t\t\t\t\t\tvoid (async () => {\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\tconst commandStatus = await api.get<CommandStatusResponse>(\n\t\t\t\t\t\t\t\t\t`/api/mcp/sessions/${sessionId}/commands/${serverCmdId}?statusOnly=true`,\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\tif (commandStatus.exitCode === null) {\n\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tif (commandStatus.exitCode === 0) {\n\t\t\t\t\t\t\t\t\tconsole.log(\"Dev server exited (code 0).\");\n\t\t\t\t\t\t\t\t\tawait gracefulShutdown(0);\n\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tconst commandOutput = await getCommandOutputOrNull(\n\t\t\t\t\t\t\t\t\tsessionId,\n\t\t\t\t\t\t\t\t\tserverCmdId,\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\thandleError(\n\t\t\t\t\t\t\t\t\tnew CLIError(\n\t\t\t\t\t\t\t\t\t\t`Dev server exited with code ${commandStatus.exitCode}.`,\n\t\t\t\t\t\t\t\t\t\t\"SERVER_EXITED\",\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\tcommand: devCommand,\n\t\t\t\t\t\t\t\t\t\t\tcmdId: serverCmdId,\n\t\t\t\t\t\t\t\t\t\t\texitCode: commandStatus.exitCode,\n\t\t\t\t\t\t\t\t\t\t\tstdout: commandOutput?.stdout ?? \"\",\n\t\t\t\t\t\t\t\t\t\t\tstderr: commandOutput?.stderr ?? \"\",\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\tjson,\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\tawait gracefulShutdown(1);\n\t\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\t\t// Ignore transient polling errors while watch loop is active.\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t})();\n\t\t\t\t\t}, statusPollIntervalMs);\n\t\t\t\t}\n\n\t\t\t\t// Handle graceful process termination.\n\t\t\t\tprocess.once(\"SIGINT\", () => {\n\t\t\t\t\tvoid gracefulShutdown();\n\t\t\t\t});\n\t\t\t\tprocess.once(\"SIGTERM\", () => {\n\t\t\t\t\tvoid gracefulShutdown();\n\t\t\t\t});\n\n\t\t\t\t// Keep the process running\n\t\t\t\tawait new Promise(() => {});\n\t\t\t}\n\t\t} catch (error) {\n\t\t\thandleError(error, json);\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n","/**\n * Resolve a promise, or return null if it does not settle within timeoutMs.\n */\nexport async function withTimeout<T>(\n\tpromise: Promise<T>,\n\ttimeoutMs: number,\n\toptions?: {\n\t\tonTimeout?: () => void;\n\t},\n): Promise<T | null> {\n\tlet timer: NodeJS.Timeout | undefined;\n\n\ttry {\n\t\treturn await Promise.race([\n\t\t\tpromise,\n\t\t\tnew Promise<null>((resolve) => {\n\t\t\t\ttimer = setTimeout(() => {\n\t\t\t\t\toptions?.onTimeout?.();\n\t\t\t\t\tresolve(null);\n\t\t\t\t}, timeoutMs);\n\t\t\t}),\n\t\t]);\n\t} finally {\n\t\tif (timer) {\n\t\t\tclearTimeout(timer);\n\t\t}\n\t}\n}\n","import chalk from \"chalk\";\nimport { Command } from \"commander\";\nimport ora from \"ora\";\nimport { api } from \"../../lib/api.js\";\nimport { handleError } from \"../../lib/errors.js\";\nimport { formatOutput } from \"../../lib/output.js\";\nimport { requireMcpId, requireSessionId } from \"../../lib/utils.js\";\nimport type { RunCommandResponse } from \"../../types/index.js\";\n\nexport const runCommandCommand = new Command(\"run-command\")\n\t.description(\"Run a command in the MCP sandbox\")\n\t.argument(\"<command>\", \"Command to run\")\n\t.argument(\"[args...]\", \"Command arguments\")\n\t.option(\"--mcp-id <id>\", \"Specific MCP ID\")\n\t.option(\"--cwd <path>\", \"Working directory\")\n\t.option(\n\t\t\"--timeout <ms>\",\n\t\t\"Command timeout in milliseconds (default: 30000, max: 300000)\",\n\t)\n\t.action(async (cmd: string, args: string[], options, command) => {\n\t\tconst globalOptions = command.optsWithGlobals();\n\t\tconst json = globalOptions.json ?? false;\n\n\t\ttry {\n\t\t\tawait requireMcpId(options.mcpId);\n\t\t\tconst sessionId = await requireSessionId();\n\n\t\t\tconst timeout = options.timeout\n\t\t\t\t? Number.parseInt(options.timeout, 10)\n\t\t\t\t: undefined;\n\n\t\t\tconst spinner = ora(`Running: ${cmd} ${args.join(\" \")}`.trim()).start();\n\n\t\t\tconst result = await api.post<RunCommandResponse>(\n\t\t\t\t`/api/mcp/sessions/${sessionId}/commands`,\n\t\t\t\t{\n\t\t\t\t\tcommand: cmd,\n\t\t\t\t\targs: args.length > 0 ? args : undefined,\n\t\t\t\t\tcwd: options.cwd,\n\t\t\t\t\ttimeout,\n\t\t\t\t},\n\t\t\t);\n\n\t\t\tspinner.stop();\n\n\t\t\tif (json) {\n\t\t\t\tformatOutput(result, true);\n\t\t\t} else {\n\t\t\t\t// Show command\n\t\t\t\tconst cmdLine = [cmd, ...args].join(\" \");\n\t\t\t\tconsole.log(chalk.gray(`$ ${cmdLine}`));\n\t\t\t\tconsole.log();\n\n\t\t\t\t// Show stdout\n\t\t\t\tif (result.stdout) {\n\t\t\t\t\tprocess.stdout.write(result.stdout);\n\t\t\t\t\tif (!result.stdout.endsWith(\"\\n\")) {\n\t\t\t\t\t\tprocess.stdout.write(\"\\n\");\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Show stderr\n\t\t\t\tif (result.stderr) {\n\t\t\t\t\tprocess.stderr.write(chalk.red(result.stderr));\n\t\t\t\t\tif (!result.stderr.endsWith(\"\\n\")) {\n\t\t\t\t\t\tprocess.stderr.write(\"\\n\");\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Show exit code and duration\n\t\t\t\tconsole.log();\n\t\t\t\tconst exitColor = result.exitCode === 0 ? chalk.green : chalk.red;\n\t\t\t\tconsole.log(\n\t\t\t\t\texitColor(`Exit code: ${result.exitCode}`),\n\t\t\t\t\tchalk.gray(`(${(result.duration / 1000).toFixed(2)}s)`),\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// Exit with the command's exit code\n\t\t\tif (result.exitCode !== 0) {\n\t\t\t\tprocess.exit(result.exitCode);\n\t\t\t}\n\t\t} catch (error) {\n\t\t\thandleError(error, json);\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n","import chalk from \"chalk\";\nimport { Command } from \"commander\";\nimport ora from \"ora\";\nimport { api } from \"../../lib/api.js\";\nimport { handleError } from \"../../lib/errors.js\";\nimport { formatList, formatOutput } from \"../../lib/output.js\";\nimport { requireMcpId } from \"../../lib/utils.js\";\nimport type { McpRepository, ServerStatusResponse } from \"../../types/index.js\";\n\nexport const statusCommand = new Command(\"status\")\n\t.description(\"Show current MCP status\")\n\t.option(\"--mcp-id <id>\", \"Specific MCP ID\")\n\t.action(async (options, command) => {\n\t\tconst globalOptions = command.optsWithGlobals();\n\t\tconst json = globalOptions.json ?? false;\n\n\t\ttry {\n\t\t\tconst mcpId = await requireMcpId(options.mcpId);\n\n\t\t\tconst spinner = ora(\"Fetching MCP status...\").start();\n\n\t\t\tconst result = await api.get<McpRepository>(\n\t\t\t\t`/api/mcp/repositories/${mcpId}`,\n\t\t\t);\n\n\t\t\t// Fetch server status if sandbox is active\n\t\t\tlet serverStatus: ServerStatusResponse | null = null;\n\t\t\tif (result.activeSandbox) {\n\t\t\t\tserverStatus = await api\n\t\t\t\t\t.post<ServerStatusResponse>(\n\t\t\t\t\t\t`/api/mcp/sessions/${result.activeSandbox.id}/server`,\n\t\t\t\t\t\t{ action: \"status\" },\n\t\t\t\t\t)\n\t\t\t\t\t.catch(() => null);\n\t\t\t}\n\n\t\t\tspinner.stop();\n\n\t\t\tif (json) {\n\t\t\t\tformatOutput({ ...result, server: serverStatus }, true);\n\t\t\t} else {\n\t\t\t\tconst deployStatus = result.deployedAt\n\t\t\t\t\t? chalk.green(\"Deployed\")\n\t\t\t\t\t: chalk.yellow(\"Pending\");\n\n\t\t\t\tconst items = [\n\t\t\t\t\t{ label: \"Name\", value: result.name },\n\t\t\t\t\t{ label: \"MCP ID\", value: result.id },\n\t\t\t\t\t{ label: \"Status\", value: deployStatus },\n\t\t\t\t\t{\n\t\t\t\t\t\tlabel: \"Last Deploy\",\n\t\t\t\t\t\tvalue: result.deployedAt\n\t\t\t\t\t\t\t? new Date(result.deployedAt).toLocaleString()\n\t\t\t\t\t\t\t: chalk.gray(\"Never\"),\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tlabel: \"Created\",\n\t\t\t\t\t\tvalue: new Date(result.createdAt).toLocaleString(),\n\t\t\t\t\t},\n\t\t\t\t];\n\n\t\t\t\t// Add sandbox info if active\n\t\t\t\tif (result.activeSandbox) {\n\t\t\t\t\tconst sandbox = result.activeSandbox;\n\t\t\t\t\tconst serverRunning = serverStatus?.running ?? sandbox.serverRunning;\n\t\t\t\t\tconst serverStatusColor = serverRunning ? chalk.green : chalk.yellow;\n\n\t\t\t\t\titems.push(\n\t\t\t\t\t\t{ label: \"\", value: \"\" }, // Separator\n\t\t\t\t\t\t{ label: \"Sandbox\", value: chalk.green(\"Active\") },\n\t\t\t\t\t\t{ label: \"Preview URL\", value: sandbox.previewUrl },\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tlabel: \"Server\",\n\t\t\t\t\t\t\tvalue: serverStatusColor(serverRunning ? \"Running\" : \"Stopped\"),\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tlabel: \"Expires\",\n\t\t\t\t\t\t\tvalue: sandbox.expiresAt\n\t\t\t\t\t\t\t\t? new Date(sandbox.expiresAt).toLocaleString()\n\t\t\t\t\t\t\t\t: chalk.gray(\"N/A\"),\n\t\t\t\t\t\t},\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\titems.push(\n\t\t\t\t\t\t{ label: \"\", value: \"\" }, // Separator\n\t\t\t\t\t\t{ label: \"Sandbox\", value: chalk.gray(\"None\") },\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\tformatList(items, false);\n\n\t\t\t\tconsole.log();\n\t\t\t\tif (!result.activeSandbox) {\n\t\t\t\t\tconsole.log(\"Start development: waniwani mcp preview\");\n\t\t\t\t} else if (!serverStatus?.running) {\n\t\t\t\t\tconsole.log(\"View logs: waniwani mcp logs\");\n\t\t\t\t}\n\t\t\t}\n\t\t} catch (error) {\n\t\t\thandleError(error, json);\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n","import { Command } from \"commander\";\nimport ora from \"ora\";\nimport { api } from \"../../lib/api.js\";\nimport { config } from \"../../lib/config.js\";\nimport { handleError } from \"../../lib/errors.js\";\nimport { formatOutput, formatSuccess } from \"../../lib/output.js\";\nimport { requireMcpId, requireSessionId } from \"../../lib/utils.js\";\n\nexport const stopCommand = new Command(\"stop\")\n\t.description(\"Stop the development environment (sandbox + server)\")\n\t.option(\"--mcp-id <id>\", \"Specific MCP ID\")\n\t.action(async (options, command) => {\n\t\tconst globalOptions = command.optsWithGlobals();\n\t\tconst json = globalOptions.json ?? false;\n\n\t\ttry {\n\t\t\tawait requireMcpId(options.mcpId);\n\t\t\tconst sessionId = await requireSessionId();\n\n\t\t\tconst spinner = ora(\"Stopping development environment...\").start();\n\n\t\t\t// Stop server first\n\t\t\ttry {\n\t\t\t\tawait api.post(`/api/mcp/sessions/${sessionId}/server`, {\n\t\t\t\t\taction: \"stop\",\n\t\t\t\t});\n\t\t\t} catch {\n\t\t\t\t// Server might not be running, continue\n\t\t\t}\n\n\t\t\t// Delete session\n\t\t\tawait api.delete(`/api/mcp/sessions/${sessionId}`);\n\n\t\t\t// Clear session from config\n\t\t\tawait config.setSessionId(null);\n\n\t\t\tspinner.succeed(\"Development environment stopped\");\n\n\t\t\tif (json) {\n\t\t\t\tformatOutput({ stopped: true }, true);\n\t\t\t} else {\n\t\t\t\tformatSuccess(\"Sandbox stopped.\", false);\n\t\t\t\tconsole.log();\n\t\t\t\tconsole.log(\"Start again: waniwani mcp preview\");\n\t\t\t}\n\t\t} catch (error) {\n\t\t\thandleError(error, json);\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n","import { Command } from \"commander\";\nimport ora from \"ora\";\nimport { CLIError, handleError } from \"../../lib/errors.js\";\nimport { formatOutput, formatSuccess } from \"../../lib/output.js\";\nimport { findProjectRoot, pullFilesFromGithub } from \"../../lib/sync.js\";\nimport { requireMcpId } from \"../../lib/utils.js\";\n\nexport const syncCommand = new Command(\"sync\")\n\t.description(\"Pull template files to local project\")\n\t.option(\"--mcp-id <id>\", \"Specific MCP ID\")\n\t.action(async (options, command) => {\n\t\tconst globalOptions = command.optsWithGlobals();\n\t\tconst json = globalOptions.json ?? false;\n\n\t\ttry {\n\t\t\tconst mcpId = await requireMcpId(options.mcpId);\n\n\t\t\t// Find project root\n\t\t\tconst projectRoot = await findProjectRoot(process.cwd());\n\t\t\tif (!projectRoot) {\n\t\t\t\tthrow new CLIError(\n\t\t\t\t\t\"Not in a WaniWani project. Run 'waniwani mcp create <name>' first.\",\n\t\t\t\t\t\"NOT_IN_PROJECT\",\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst spinner = ora(\"Pulling files...\").start();\n\n\t\t\tconst result = await pullFilesFromGithub(mcpId, projectRoot);\n\n\t\t\tspinner.succeed(`Pulled ${result.count} files`);\n\n\t\t\tif (json) {\n\t\t\t\tformatOutput({ files: result.files }, true);\n\t\t\t} else {\n\t\t\t\tconsole.log();\n\t\t\t\tformatSuccess(\"Files synced!\", false);\n\t\t\t\tif (result.files.length > 0 && result.files.length <= 10) {\n\t\t\t\t\tconsole.log();\n\t\t\t\t\tfor (const file of result.files) {\n\t\t\t\t\t\tconsole.log(` ${file}`);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} catch (error) {\n\t\t\thandleError(error, json);\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n","import { Command } from \"commander\";\nimport ora from \"ora\";\nimport { api } from \"../../lib/api.js\";\nimport { config } from \"../../lib/config.js\";\nimport { handleError, McpError } from \"../../lib/errors.js\";\nimport { formatOutput, formatSuccess } from \"../../lib/output.js\";\nimport type {\n\tMcpRepository,\n\tMcpRepositoryListResponse,\n} from \"../../types/index.js\";\n\nexport const useCommand = new Command(\"use\")\n\t.description(\"Select an MCP to use for subsequent commands\")\n\t.argument(\"<name>\", \"Name of the MCP to use\")\n\t.action(async (name: string, _options, command) => {\n\t\tconst globalOptions = command.optsWithGlobals();\n\t\tconst json = globalOptions.json ?? false;\n\n\t\ttry {\n\t\t\tconst spinner = ora(\"Fetching MCPs...\").start();\n\n\t\t\t// Fetch all MCPs\n\t\t\tconst mcps = await api.get<McpRepositoryListResponse>(\n\t\t\t\t\"/api/mcp/repositories\",\n\t\t\t);\n\n\t\t\tspinner.stop();\n\n\t\t\t// Find MCP by name\n\t\t\tconst mcp = mcps.find((m: McpRepository) => m.name === name);\n\n\t\t\tif (!mcp) {\n\t\t\t\tthrow new McpError(\n\t\t\t\t\t`MCP \"${name}\" not found. Run 'waniwani mcp list' to see available MCPs.`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tawait config.setMcpId(mcp.id);\n\t\t\t// Clear session since we're switching MCPs\n\t\t\tawait config.setSessionId(null);\n\n\t\t\tif (json) {\n\t\t\t\tformatOutput({ selected: mcp }, true);\n\t\t\t} else {\n\t\t\t\tformatSuccess(`Now using MCP \"${name}\"`, false);\n\t\t\t\tconsole.log();\n\t\t\t\tconsole.log(` MCP ID: ${mcp.id}`);\n\t\t\t\tconsole.log();\n\t\t\t\tconsole.log(\"Next steps:\");\n\t\t\t\tconsole.log(\" waniwani mcp preview # Start live preview\");\n\t\t\t\tconsole.log(\" waniwani mcp status # Check status\");\n\t\t\t}\n\t\t} catch (error) {\n\t\t\thandleError(error, json);\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n","import { Command } from \"commander\";\nimport { currentCommand } from \"./current.js\";\nimport { listCommand } from \"./list.js\";\nimport { switchCommand } from \"./switch.js\";\n\nexport const orgCommand = new Command(\"org\")\n\t.description(\"Organization management commands\")\n\t.addCommand(currentCommand)\n\t.addCommand(listCommand)\n\t.addCommand(switchCommand);\n","import { Command } from \"commander\";\nimport ora from \"ora\";\nimport { api } from \"../../lib/api.js\";\nimport { handleError } from \"../../lib/errors.js\";\nimport { formatList, formatOutput } from \"../../lib/output.js\";\nimport type { Org, OrgListResponse } from \"../../types/index.js\";\n\nexport const currentCommand = new Command(\"current\")\n\t.description(\"Show the current active organization\")\n\t.action(async (_options, command) => {\n\t\tconst globalOptions = command.optsWithGlobals();\n\t\tconst json = globalOptions.json ?? false;\n\n\t\ttry {\n\t\t\tconst spinner = ora(\"Fetching current organization...\").start();\n\n\t\t\tconst result = await api.get<OrgListResponse>(\"/api/oauth/orgs\");\n\n\t\t\tspinner.stop();\n\n\t\t\tconst { orgs, activeOrgId } = result;\n\n\t\t\tif (!activeOrgId) {\n\t\t\t\tif (json) {\n\t\t\t\t\tformatOutput({ org: null }, true);\n\t\t\t\t} else {\n\t\t\t\t\tconsole.log(\"No active organization.\");\n\t\t\t\t\tconsole.log(\n\t\t\t\t\t\t\"\\nSwitch to an organization: waniwani org switch <name>\",\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst activeOrg = orgs.find((o: Org) => o.id === activeOrgId);\n\n\t\t\tif (!activeOrg) {\n\t\t\t\tif (json) {\n\t\t\t\t\tformatOutput({ org: null }, true);\n\t\t\t\t} else {\n\t\t\t\t\tconsole.log(\"Active organization not found.\");\n\t\t\t\t\tconsole.log(\n\t\t\t\t\t\t\"\\nSwitch to an organization: waniwani org switch <name>\",\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (json) {\n\t\t\t\tformatOutput({ org: activeOrg }, true);\n\t\t\t} else {\n\t\t\t\tconsole.log();\n\t\t\t\tformatList(\n\t\t\t\t\t[\n\t\t\t\t\t\t{ label: \"Name\", value: activeOrg.name },\n\t\t\t\t\t\t{ label: \"Slug\", value: activeOrg.slug },\n\t\t\t\t\t\t{ label: \"Role\", value: activeOrg.role },\n\t\t\t\t\t],\n\t\t\t\t\tfalse,\n\t\t\t\t);\n\t\t\t}\n\t\t} catch (error) {\n\t\t\thandleError(error, json);\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n","import chalk from \"chalk\";\nimport { Command } from \"commander\";\nimport ora from \"ora\";\nimport { api } from \"../../lib/api.js\";\nimport { handleError } from \"../../lib/errors.js\";\nimport { formatOutput, formatTable } from \"../../lib/output.js\";\nimport type { Org, OrgListResponse } from \"../../types/index.js\";\n\nexport const listCommand = new Command(\"list\")\n\t.description(\"List your organizations\")\n\t.action(async (_options, command) => {\n\t\tconst globalOptions = command.optsWithGlobals();\n\t\tconst json = globalOptions.json ?? false;\n\n\t\ttry {\n\t\t\tconst spinner = ora(\"Fetching organizations...\").start();\n\n\t\t\tconst result = await api.get<OrgListResponse>(\"/api/oauth/orgs\");\n\n\t\t\tspinner.stop();\n\n\t\t\tconst { orgs, activeOrgId } = result;\n\n\t\t\tif (json) {\n\t\t\t\tformatOutput(\n\t\t\t\t\t{\n\t\t\t\t\t\torgs: orgs.map((o: Org) => ({\n\t\t\t\t\t\t\t...o,\n\t\t\t\t\t\t\tisActive: o.id === activeOrgId,\n\t\t\t\t\t\t})),\n\t\t\t\t\t\tactiveOrgId,\n\t\t\t\t\t},\n\t\t\t\t\ttrue,\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tif (orgs.length === 0) {\n\t\t\t\t\tconsole.log(\"No organizations found.\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconsole.log(chalk.bold(\"\\nOrganizations:\\n\"));\n\n\t\t\t\tconst rows = orgs.map((o: Org) => {\n\t\t\t\t\tconst isActive = o.id === activeOrgId;\n\t\t\t\t\treturn [\n\t\t\t\t\t\tisActive ? chalk.cyan(`* ${o.name}`) : ` ${o.name}`,\n\t\t\t\t\t\to.slug,\n\t\t\t\t\t\to.role,\n\t\t\t\t\t];\n\t\t\t\t});\n\n\t\t\t\tformatTable([\"Name\", \"Slug\", \"Role\"], rows, false);\n\n\t\t\t\tconsole.log();\n\t\t\t\tif (activeOrgId) {\n\t\t\t\t\tconst activeOrg = orgs.find((o: Org) => o.id === activeOrgId);\n\t\t\t\t\tif (activeOrg) {\n\t\t\t\t\t\tconsole.log(`Active organization: ${chalk.cyan(activeOrg.name)}`);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tconsole.log(\"\\nSwitch organization: waniwani org switch <name>\");\n\t\t\t}\n\t\t} catch (error) {\n\t\t\thandleError(error, json);\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n","import { Command } from \"commander\";\nimport ora from \"ora\";\nimport { api } from \"../../lib/api.js\";\nimport { config } from \"../../lib/config.js\";\nimport { CLIError, handleError } from \"../../lib/errors.js\";\nimport { formatOutput, formatSuccess } from \"../../lib/output.js\";\nimport type {\n\tOrg,\n\tOrgListResponse,\n\tOrgSwitchResponse,\n} from \"../../types/index.js\";\n\nexport const switchCommand = new Command(\"switch\")\n\t.description(\"Switch to a different organization\")\n\t.argument(\"<name>\", \"Name or slug of the organization to switch to\")\n\t.action(async (name: string, _options, command) => {\n\t\tconst globalOptions = command.optsWithGlobals();\n\t\tconst json = globalOptions.json ?? false;\n\n\t\ttry {\n\t\t\tconst spinner = ora(\"Fetching organizations...\").start();\n\n\t\t\t// First fetch orgs to find the org ID\n\t\t\tconst { orgs } = await api.get<OrgListResponse>(\"/api/oauth/orgs\");\n\n\t\t\t// Find org by name or slug\n\t\t\tconst org = orgs.find((o: Org) => o.name === name || o.slug === name);\n\n\t\t\tif (!org) {\n\t\t\t\tspinner.stop();\n\t\t\t\tthrow new CLIError(\n\t\t\t\t\t`Organization \"${name}\" not found. Run 'waniwani org list' to see available organizations.`,\n\t\t\t\t\t\"ORG_NOT_FOUND\",\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tspinner.text = \"Switching organization...\";\n\n\t\t\t// Switch to the org\n\t\t\tawait api.post<OrgSwitchResponse>(\"/api/oauth/orgs/switch\", {\n\t\t\t\torgId: org.id,\n\t\t\t});\n\n\t\t\tspinner.succeed(\"Organization switched\");\n\n\t\t\t// Clear local MCP selection since we switched orgs\n\t\t\tconfig.setMcpId(null);\n\n\t\t\tif (json) {\n\t\t\t\tformatOutput({ switched: org }, true);\n\t\t\t} else {\n\t\t\t\tformatSuccess(`Switched to organization \"${org.name}\"`, false);\n\t\t\t\tconsole.log();\n\t\t\t\tconsole.log(\"Note: Active MCP selection has been cleared.\");\n\t\t\t\tconsole.log(\n\t\t\t\t\t\"Run 'waniwani mcp list' to see MCPs in this organization.\",\n\t\t\t\t);\n\t\t\t}\n\t\t} catch (error) {\n\t\t\thandleError(error, json);\n\t\t\tprocess.exit(1);\n\t\t}\n\t});\n","import { program } from \"./cli.js\";\n\nprogram.parse(process.argv);\n"],"mappings":"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","names":["Command","Command","existsSync","join","chalk","chalk","join","existsSync","Command","join","Command","join","join","auth","existsSync","mkdir","readFile","writeFile","join","existsSync","join","readFile","mkdir","writeFile","Command","join","chalk","Command","Command","chalk","Command","Command","Command","execFileSync","existsSync","readFile","join","Command","ora","execFileSync","join","existsSync","readFile","config","Command","ora","execFileSync","execFileSync","execSync","existsSync","readFile","join","Command","ora","loadParentConfig","join","existsSync","readFile","config","checkGitInstalled","execSync","Command","ora","execFileSync","chalk","Command","ora","Command","chalk","ora","Command","chalk","Command","ora","Command","ora","chalk","writeFile","Command","ora","Command","ora","writeFile","readFile","Command","ora","Command","readFile","ora","Command","chalk","Command","ora","listCommand","Command","ora","chalk","chalk","Command","ora","Command","ora","chalk","existsSync","join","Command","ora","existsSync","join","Command","ora","relative","chalk","Command","ora","Command","ora","chalk","chalk","Command","ora","Command","ora","chalk","Command","ora","Command","ora","Command","ora","Command","ora","Command","ora","Command","ora","Command","listCommand","Command","Command","ora","Command","ora","chalk","Command","ora","listCommand","Command","ora","chalk","Command","ora","Command","ora","Command","listCommand","require","Command"]}
|