create-metaclaw 3.3.0

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.
Files changed (92) hide show
  1. package/LICENSE +44 -0
  2. package/README.md +282 -0
  3. package/docs/assets/favicon.png +0 -0
  4. package/docs/assets/metaclaw-banner.svg +86 -0
  5. package/docs/assets/qis-logo.png +0 -0
  6. package/docs/assets/yz-favicon.png +0 -0
  7. package/docs/assets/yz-logo.png +0 -0
  8. package/docs/index.html +895 -0
  9. package/installer/assets/favicon.png +0 -0
  10. package/installer/auto-start.ts +330 -0
  11. package/installer/brand.ts +115 -0
  12. package/installer/core-scaffold.ts +448 -0
  13. package/installer/dashboard-generator.ts +657 -0
  14. package/installer/detect.ts +129 -0
  15. package/installer/index.ts +355 -0
  16. package/installer/module-loader.ts +412 -0
  17. package/installer/modules/boardroom/boardroom/client.ts.txt +201 -0
  18. package/installer/modules/boardroom/boardroom/db.ts.txt +322 -0
  19. package/installer/modules/boardroom/boardroom/meeting-agent.ts.txt +129 -0
  20. package/installer/modules/boardroom/boardroom/meeting-scheduler.ts.txt +194 -0
  21. package/installer/modules/boardroom/boardroom/server.ts.txt +473 -0
  22. package/installer/modules/boardroom/boardroom/start-boardroom.bat.txt +26 -0
  23. package/installer/modules/boardroom/boardroom/summons.ts.txt +76 -0
  24. package/installer/modules/boardroom/boardroom/turn-v2.ts.txt +172 -0
  25. package/installer/modules/boardroom/boardroom/turn.ts.txt +208 -0
  26. package/installer/modules/boardroom/boardroom/types.ts.txt +100 -0
  27. package/installer/modules/boardroom/metaclaw-module.json +35 -0
  28. package/installer/modules/boardroom/scripts/meeting-check.bat.txt +38 -0
  29. package/installer/modules/core/metaclaw-module.json +51 -0
  30. package/installer/modules/core/src/db.ts.txt +277 -0
  31. package/installer/modules/core/src/health-check.ts.txt +128 -0
  32. package/installer/modules/core/src/observability.ts.txt +20 -0
  33. package/installer/modules/core/src/safety.ts.txt +26 -0
  34. package/installer/modules/core/src/scan-capabilities.ts.txt +196 -0
  35. package/installer/modules/core/src/self-improve.ts.txt +48 -0
  36. package/installer/modules/core/src/self-update.ts.txt +345 -0
  37. package/installer/modules/core/src/sync-context.ts.txt +133 -0
  38. package/installer/modules/core/src/tasks.ts.txt +159 -0
  39. package/installer/modules/custom/metaclaw-module.json +15 -0
  40. package/installer/modules/custom/src/agent-custom.ts.txt +100 -0
  41. package/installer/modules/dashboard/metaclaw-module.json +23 -0
  42. package/installer/modules/dashboard/scripts/build-dashboard.cjs.txt +51 -0
  43. package/installer/modules/dashboard/src/update-dashboard.ts.txt +126 -0
  44. package/installer/modules/outreach/metaclaw-module.json +29 -0
  45. package/installer/modules/outreach/src/agent-outreach.ts.txt +193 -0
  46. package/installer/modules/outreach/src/inbox-agent.ts.txt +283 -0
  47. package/installer/modules/outreach/src/morning-report.ts.txt +124 -0
  48. package/installer/modules/research/metaclaw-module.json +15 -0
  49. package/installer/modules/research/src/agent-research.ts.txt +127 -0
  50. package/installer/modules/scheduler/metaclaw-module.json +27 -0
  51. package/installer/modules/scheduler/scripts/agent-cycle.bat.txt +85 -0
  52. package/installer/modules/scheduler/scripts/detect-session.bat.txt +41 -0
  53. package/installer/modules/scheduler/scripts/launch.bat.txt +120 -0
  54. package/installer/modules/scheduler/src/cron-manager.ts.txt +273 -0
  55. package/installer/modules/social/metaclaw-module.json +15 -0
  56. package/installer/modules/social/src/agent-social.ts.txt +110 -0
  57. package/installer/modules/support/metaclaw-module.json +15 -0
  58. package/installer/modules/support/src/agent-support.ts.txt +60 -0
  59. package/installer/modules/swarm/metaclaw-module.json +25 -0
  60. package/installer/modules/swarm/swarm/dht-client.ts.txt +376 -0
  61. package/installer/modules/swarm/swarm/relay-server.ts.txt +348 -0
  62. package/installer/modules/swarm/swarm/swarm-client.ts.txt +303 -0
  63. package/installer/modules/swarm/swarm/types.ts.txt +51 -0
  64. package/installer/modules/voice/metaclaw-module.json +16 -0
  65. package/installer/questionnaire.ts +277 -0
  66. package/installer/research.ts +258 -0
  67. package/installer/scaffold-from-config.ts +270 -0
  68. package/installer/task-generator.ts +324 -0
  69. package/installer/templates/agent-custom.ts.txt +100 -0
  70. package/installer/templates/agent-cycle.bat.txt +19 -0
  71. package/installer/templates/agent-outreach.ts.txt +193 -0
  72. package/installer/templates/agent-research.ts.txt +127 -0
  73. package/installer/templates/agent-social.ts.txt +110 -0
  74. package/installer/templates/agent-support.ts.txt +60 -0
  75. package/installer/templates/build-dashboard.cjs.txt +51 -0
  76. package/installer/templates/cron-manager.ts.txt +273 -0
  77. package/installer/templates/dashboard.html.txt +450 -0
  78. package/installer/templates/db.ts.txt +277 -0
  79. package/installer/templates/detect-session.bat.txt +41 -0
  80. package/installer/templates/health-check.ts.txt +128 -0
  81. package/installer/templates/inbox-agent.ts.txt +283 -0
  82. package/installer/templates/launch.bat.txt +120 -0
  83. package/installer/templates/morning-report.ts.txt +124 -0
  84. package/installer/templates/observability.ts.txt +20 -0
  85. package/installer/templates/safety.ts.txt +26 -0
  86. package/installer/templates/self-improve.ts.txt +48 -0
  87. package/installer/templates/self-update.ts.txt +345 -0
  88. package/installer/templates/state.json.txt +33 -0
  89. package/installer/templates/system-context.json.txt +33 -0
  90. package/installer/templates/update-dashboard.ts.txt +126 -0
  91. package/package.json +31 -0
  92. package/setup.bat +178 -0
@@ -0,0 +1,129 @@
1
+ /**
2
+ * MetaClaw System Detection — auto-detect everything about the environment
3
+ */
4
+
5
+ import { execSync } from "child_process";
6
+ import os from "os";
7
+ import fs from "fs";
8
+ import path from "path";
9
+ import { status, muted } from "./brand.js";
10
+
11
+ export type SystemInfo = {
12
+ os: { platform: string; release: string; arch: string; hostname: string };
13
+ user: { username: string; homedir: string; desktop: string };
14
+ node: { installed: boolean; version: string };
15
+ git: { installed: boolean; version: string };
16
+ claude: { installed: boolean; version: string; authenticated: boolean };
17
+ docker: { installed: boolean; version: string };
18
+ python: { installed: boolean; version: string };
19
+ hardware: { cpus: number; ram: string; gpu: string };
20
+ paths: {
21
+ workspace: string;
22
+ claudeDir: string;
23
+ projectMemory: string;
24
+ };
25
+ };
26
+
27
+ function tryExec(cmd: string): string {
28
+ try {
29
+ return execSync(cmd, { encoding: "utf-8", timeout: 5000, stdio: ["pipe", "pipe", "pipe"] }).trim();
30
+ } catch {
31
+ return "";
32
+ }
33
+ }
34
+
35
+ function getGpuInfo(): string {
36
+ const platform = os.platform();
37
+ if (platform === "win32") {
38
+ const result = tryExec('wmic path win32_VideoController get name /format:list');
39
+ const match = result.match(/Name=(.+)/);
40
+ return match ? match[1].trim() : "Not detected";
41
+ }
42
+ if (platform === "linux") {
43
+ return tryExec("lspci | grep -i vga | head -1 | cut -d: -f3") || "Not detected";
44
+ }
45
+ if (platform === "darwin") {
46
+ return tryExec("system_profiler SPDisplaysDataType | grep 'Chipset Model' | head -1 | cut -d: -f2") || "Not detected";
47
+ }
48
+ return "Not detected";
49
+ }
50
+
51
+ /**
52
+ * Detect everything about the current system.
53
+ */
54
+ export function detectSystem(): SystemInfo {
55
+ const platform = os.platform();
56
+ const username = os.userInfo().username;
57
+ const homedir = os.homedir();
58
+ const desktop = path.join(homedir, "Desktop");
59
+
60
+ // Encode workspace path for Claude project memory
61
+ const workspacePath = path.join(desktop, "claude-workspace");
62
+ const encodedPath = workspacePath.replace(/[:/\\]/g, "-").replace(/^-/, "");
63
+
64
+ const nodeVersion = tryExec("node --version");
65
+ const gitVersion = tryExec("git --version").replace("git version ", "");
66
+ const claudeVersion = tryExec("claude --version") || tryExec(`"${homedir}\\.local\\bin\\claude.exe" --version`);
67
+ const dockerVersion = tryExec("docker --version").replace("Docker version ", "").split(",")[0];
68
+ const pythonVersion = tryExec("python --version").replace("Python ", "") || tryExec("python3 --version").replace("Python ", "");
69
+
70
+ const ramGB = (os.totalmem() / 1024 / 1024 / 1024).toFixed(1);
71
+
72
+ return {
73
+ os: {
74
+ platform: platform === "win32" ? "Windows" : platform === "darwin" ? "macOS" : "Linux",
75
+ release: os.release(),
76
+ arch: os.arch(),
77
+ hostname: os.hostname(),
78
+ },
79
+ user: {
80
+ username,
81
+ homedir,
82
+ desktop,
83
+ },
84
+ node: { installed: !!nodeVersion, version: nodeVersion || "Not installed" },
85
+ git: { installed: !!gitVersion, version: gitVersion || "Not installed" },
86
+ claude: {
87
+ installed: !!claudeVersion,
88
+ version: claudeVersion || "Not installed",
89
+ authenticated: fs.existsSync(path.join(homedir, ".claude", ".credentials.json")),
90
+ },
91
+ docker: { installed: !!dockerVersion, version: dockerVersion || "Not installed" },
92
+ python: { installed: !!pythonVersion, version: pythonVersion || "Not installed" },
93
+ hardware: {
94
+ cpus: os.cpus().length,
95
+ ram: `${ramGB} GB`,
96
+ gpu: getGpuInfo(),
97
+ },
98
+ paths: {
99
+ workspace: workspacePath,
100
+ claudeDir: path.join(homedir, ".claude"),
101
+ projectMemory: path.join(homedir, ".claude", "projects", encodedPath),
102
+ },
103
+ };
104
+ }
105
+
106
+ /**
107
+ * Display system detection results.
108
+ */
109
+ export function displayDetection(info: SystemInfo): void {
110
+ // OS
111
+ console.log(status.info(`${info.os.platform} ${info.os.release} (${info.os.arch})`));
112
+ console.log(status.info(`User: ${info.user.username} @ ${info.os.hostname}`));
113
+ console.log(status.info(`${info.hardware.cpus} CPUs, ${info.hardware.ram} RAM`));
114
+ if (info.hardware.gpu !== "Not detected") {
115
+ console.log(status.ok(`GPU: ${info.hardware.gpu}`));
116
+ } else {
117
+ console.log(status.warn("GPU: Not detected (will use cloud inference)"));
118
+ }
119
+
120
+ console.log("");
121
+
122
+ // Required tools only — no Docker/Python clutter
123
+ console.log(info.node.installed ? status.ok(`Node.js ${info.node.version}`) : status.fail("Node.js — not installed"));
124
+ console.log(info.git.installed ? status.ok(`Git ${info.git.version}`) : status.warn("Git — not installed"));
125
+ console.log(info.claude.installed ? status.ok(`Claude Code ${info.claude.version}`) : status.fail("Claude Code — not installed"));
126
+ if (info.claude.installed) {
127
+ console.log(info.claude.authenticated ? status.ok("Claude — authenticated") : status.warn("Claude — not authenticated"));
128
+ }
129
+ }
@@ -0,0 +1,355 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * MetaClaw Installer v3.3.0
4
+ * by Christopher Trevethan / Yonder Zenith LLC
5
+ *
6
+ * Fully automated: Detect → Configure → Research → Deploy → Launch
7
+ */
8
+
9
+ import * as clack from "@clack/prompts";
10
+ import chalk from "chalk";
11
+ import ora from "ora";
12
+ import { Listr } from "listr2";
13
+ import {
14
+ welcomeScreen, completionScreen, sectionHeader, status,
15
+ brand, muted, success, purple, accent, gold,
16
+ box, brandGradient, successGradient, goldGradient, cyanGradient,
17
+ } from "./brand.js";
18
+ import { detectSystem, displayDetection } from "./detect.js";
19
+ import type { SystemInfo } from "./detect.js";
20
+ import { runQuestionnaire } from "./questionnaire.js";
21
+ import type { QuestionnaireResult } from "./questionnaire.js";
22
+ import { runResearch } from "./research.js";
23
+ import type { ClawConfig } from "./research.js";
24
+ import { scaffoldProject } from "./core-scaffold.js";
25
+ import fs from "fs";
26
+ import path from "path";
27
+ import { execSync, spawn } from "child_process";
28
+
29
+ function sleep(ms: number): Promise<void> {
30
+ return new Promise((r) => setTimeout(r, ms));
31
+ }
32
+
33
+ function findClaudePath(systemInfo: SystemInfo): string {
34
+ const candidates = [
35
+ path.join(systemInfo.user.homedir, ".local", "bin", "claude.exe"),
36
+ path.join(systemInfo.user.homedir, ".local", "bin", "claude"),
37
+ ];
38
+ for (const p of candidates) {
39
+ if (fs.existsSync(p)) return p;
40
+ }
41
+ return "claude";
42
+ }
43
+
44
+ // ═══════════════════════════════════════════════
45
+ // MAIN
46
+ // ═══════════════════════════════════════════════
47
+
48
+ async function main() {
49
+ // Phase 1: Welcome (with pause so they can see the branding)
50
+ console.clear();
51
+ console.log(welcomeScreen());
52
+ await sleep(2500);
53
+
54
+ // Phase 2: System Detection
55
+ console.log(sectionHeader("System Detection"));
56
+ console.log("");
57
+ const spinner = ora({ text: "Scanning system...", color: "magenta", spinner: "dots12" }).start();
58
+ const systemInfo = detectSystem();
59
+ spinner.stop();
60
+ displayDetection(systemInfo);
61
+ console.log("");
62
+
63
+ if (!systemInfo.node.installed) {
64
+ console.log(accent(" Node.js is required. Install from https://nodejs.org"));
65
+ process.exit(1);
66
+ }
67
+
68
+ // Phase 2.5: Claude Authentication (MANDATORY)
69
+ const claudePath = findClaudePath(systemInfo);
70
+
71
+ if (!systemInfo.claude.installed) {
72
+ console.log(sectionHeader("Installing Claude Code"));
73
+ console.log("");
74
+ try {
75
+ execSync('powershell -Command "irm https://claude.ai/install.ps1 | iex"', { stdio: "inherit", timeout: 120000 });
76
+ } catch {
77
+ console.log(accent(" Install Claude Code manually: https://claude.ai/download"));
78
+ console.log(accent(" Then run setup.bat again."));
79
+ process.exit(1);
80
+ }
81
+ const recheck = detectSystem();
82
+ if (!recheck.claude.installed) {
83
+ console.log(accent(" Close this window, open a NEW terminal, run setup.bat again."));
84
+ process.exit(1);
85
+ }
86
+ systemInfo.claude = recheck.claude;
87
+ }
88
+
89
+ if (!systemInfo.claude.authenticated) {
90
+ console.log(sectionHeader("Claude Authentication Required"));
91
+ console.log("");
92
+ console.log(brand(" MetaClaw requires Claude to power your agent."));
93
+ console.log(muted(" You need a Claude Pro or Max subscription."));
94
+ console.log(muted(" A browser window will open — log in with your Claude account."));
95
+ console.log("");
96
+
97
+ try {
98
+ execSync(`"${claudePath}" auth login`, { stdio: "inherit", timeout: 300000 });
99
+ } catch {
100
+ try {
101
+ execSync(`"${path.join(systemInfo.user.homedir, ".local", "bin", "claude.exe")}" auth login`, { stdio: "inherit", timeout: 300000 });
102
+ } catch {
103
+ console.log(accent(" Run manually: claude auth login"));
104
+ console.log(accent(" Then run setup.bat again."));
105
+ process.exit(1);
106
+ }
107
+ }
108
+
109
+ const recheck = detectSystem();
110
+ if (!recheck.claude.authenticated) {
111
+ console.log(accent(" Authentication failed. Run: claude auth login"));
112
+ process.exit(1);
113
+ }
114
+ systemInfo.claude = recheck.claude;
115
+ console.log(status.ok("Claude authenticated!"));
116
+ }
117
+
118
+ console.log(status.ok("Claude ready"));
119
+ console.log("");
120
+
121
+ // Phase 3: Questionnaire
122
+ const result = await runQuestionnaire(systemInfo);
123
+ if (!result) { console.log(muted("\n Cancelled.\n")); process.exit(0); }
124
+
125
+ // Phase 3.5: Name the agent
126
+ console.log(sectionHeader("Agent Identity"));
127
+ const agentName = await clack.text({
128
+ message: "Name your agent",
129
+ placeholder: "Atlas",
130
+ defaultValue: "Atlas",
131
+ });
132
+ if (clack.isCancel(agentName)) process.exit(0);
133
+
134
+ const wantAutoStart = await clack.confirm({
135
+ message: "Start this agent automatically when your PC boots?",
136
+ initialValue: true,
137
+ });
138
+ if (clack.isCancel(wantAutoStart)) process.exit(0);
139
+
140
+ // Phase 4: AI Research
141
+ console.log("");
142
+ let clawConfig: ClawConfig | null = null;
143
+ console.log(status.route("Assembling the MetaClaw board for your " + result.template.name + "..."));
144
+ console.log("");
145
+ try {
146
+ clawConfig = await runResearch(result, systemInfo);
147
+ } catch {
148
+ console.log(status.warn("Board session had an issue — using battle-tested defaults."));
149
+ }
150
+ if (!clawConfig) {
151
+ console.log(status.info("Deploying with optimized defaults. The agent will self-improve from here."));
152
+ }
153
+ console.log("");
154
+
155
+ // Phase 5: Install & Configure
156
+ const projectDir = path.join(systemInfo.user.desktop, result.projectName);
157
+
158
+ const finalConfig: ClawConfig = clawConfig || {
159
+ name: agentName as string,
160
+ template: result.template.id,
161
+ systemPrompt: `You are ${agentName}, a ${result.template.name}. ${result.template.description}`,
162
+ tools: result.template.requiredTools,
163
+ safety: { maxActionsPerDay: 50, maxActionsPerHour: 10 },
164
+ schedule: { cron: "*/30 * * * *", description: "every 30 minutes" },
165
+ selfImprovement: { enabled: true, reflectionFrequency: "daily", metricsToTrack: ["success_rate"] },
166
+ rawResearch: "",
167
+ };
168
+ finalConfig.name = agentName as string;
169
+ (finalConfig as any).selfUpdateIntervalHours = parseInt(result.answers.selfUpdateIntervalHours as string) || 6;
170
+ (finalConfig as any).answers = result.answers;
171
+
172
+ console.log(sectionHeader(`Deploying ${result.template.icon} ${agentName}`));
173
+ console.log("");
174
+
175
+ const tasks = new Listr(
176
+ [
177
+ {
178
+ title: "Scaffolding project (all files + launch scripts + dashboard)",
179
+ task: async (ctx, task) => {
180
+ // THIS is the ONLY place files are created — core-scaffold handles EVERYTHING
181
+ // including launch.bat, open-dashboard.bat, Agents folder launcher
182
+ scaffoldProject(projectDir, finalConfig, systemInfo);
183
+ task.output = "20+ files generated";
184
+ },
185
+ options: { bottomBar: 1 },
186
+ },
187
+ {
188
+ title: "Installing dependencies",
189
+ task: async (ctx, task) => {
190
+ task.output = "Running npm install...";
191
+ try {
192
+ execSync("npm install", { cwd: projectDir, stdio: "pipe", timeout: 180000 });
193
+ task.output = "Dependencies installed";
194
+ } catch { task.output = "npm install had issues — may need manual retry"; }
195
+ },
196
+ options: { bottomBar: 1 },
197
+ },
198
+ {
199
+ title: "Initializing database",
200
+ task: async (ctx, task) => {
201
+ try {
202
+ execSync("npx tsx src/init-config.ts", { cwd: projectDir, stdio: "pipe", timeout: 15000 });
203
+ execSync("npx tsx src/init-prompts.ts", { cwd: projectDir, stdio: "pipe", timeout: 15000 });
204
+ task.output = "Database seeded";
205
+ } catch { task.output = "Init will run on first start"; }
206
+ },
207
+ options: { bottomBar: 1 },
208
+ },
209
+ {
210
+ title: "Generating dashboard data",
211
+ task: async (ctx, task) => {
212
+ try {
213
+ execSync("npx tsx src/update-dashboard.ts", { cwd: projectDir, stdio: "pipe", timeout: 15000 });
214
+ task.output = "Dashboard ready";
215
+ } catch { task.output = "Dashboard generates on first run"; }
216
+ },
217
+ options: { bottomBar: 1 },
218
+ },
219
+ {
220
+ title: "Setting up scheduled tasks",
221
+ task: async (ctx, task) => {
222
+ try {
223
+ execSync("npx tsx src/cron-manager.ts setup", { cwd: projectDir, encoding: "utf-8", stdio: "pipe", timeout: 15000 });
224
+ task.output = "Crons configured";
225
+ } catch { task.output = "Crons set up on first start"; }
226
+ },
227
+ options: { bottomBar: 1 },
228
+ },
229
+ {
230
+ title: "Running health check",
231
+ task: async (ctx, task) => {
232
+ try {
233
+ const output = execSync("npx tsx src/health-check.ts", { cwd: projectDir, encoding: "utf-8", stdio: "pipe", timeout: 15000 });
234
+ task.output = output.trim().split("\n")[0] || "All systems nominal";
235
+ } catch { task.output = "Health check runs on first start"; }
236
+ },
237
+ options: { bottomBar: 1 },
238
+ },
239
+ ],
240
+ { rendererOptions: { showTimer: true, collapseSubtasks: false } }
241
+ );
242
+
243
+ await tasks.run();
244
+
245
+ // Phase 5.5: Auto-start (Startup folder — no admin needed)
246
+ if (wantAutoStart) {
247
+ console.log(sectionHeader("Auto-Start Configuration"));
248
+ const sessionName = (agentName as string).toLowerCase().replace(/[^a-z0-9]/g, "-");
249
+ try {
250
+ const startupDir = path.join(systemInfo.user.homedir, "AppData", "Roaming", "Microsoft", "Windows", "Start Menu", "Programs", "Startup");
251
+ if (fs.existsSync(startupDir)) {
252
+ const launcherPath = path.join(projectDir, "scripts", "launch.bat");
253
+ fs.writeFileSync(
254
+ path.join(startupDir, `MetaClaw-${sessionName}.bat`),
255
+ `@echo off\r\nstart "" "${launcherPath}"\r\n`
256
+ );
257
+ console.log(status.ok("Auto-start on login: added to Startup folder"));
258
+ }
259
+ } catch {
260
+ console.log(status.warn("Add scripts\\launch.bat to Startup folder manually"));
261
+ }
262
+ }
263
+
264
+ // Phase 5.7: Shortcuts
265
+ const launcherContent = `@echo off\r\nstart "" cmd /k "cd /d ""${projectDir}"" && scripts\\launch.bat"\r\n`;
266
+
267
+ // Always create Agents folder launcher
268
+ try {
269
+ const agentsDir = path.join(systemInfo.user.desktop, "Agents");
270
+ fs.mkdirSync(agentsDir, { recursive: true });
271
+ fs.writeFileSync(path.join(agentsDir, `Launch ${agentName}.bat`), launcherContent);
272
+ console.log(status.ok(`Launcher: Desktop/Agents/Launch ${agentName}.bat`));
273
+ } catch {
274
+ console.log(status.warn("Could not create Agents folder launcher"));
275
+ }
276
+
277
+ // Desktop shortcut if requested
278
+ if (result.answers.addDesktopShortcut) {
279
+ try {
280
+ fs.writeFileSync(
281
+ path.join(systemInfo.user.desktop, `${agentName}.bat`),
282
+ launcherContent
283
+ );
284
+ console.log(status.ok(`Desktop shortcut: ${agentName}.bat`));
285
+ } catch {
286
+ console.log(status.warn("Could not create Desktop shortcut"));
287
+ }
288
+ }
289
+
290
+ // Phase 6: Completion
291
+ console.log(completionScreen(agentName as string, projectDir, result.template.icon + " " + result.template.name));
292
+
293
+ // Phase 7: Launch dashboard + Claude
294
+ const shouldLaunch = await clack.confirm({
295
+ message: `Launch ${agentName} now?`,
296
+ initialValue: true,
297
+ });
298
+
299
+ if (!clack.isCancel(shouldLaunch) && shouldLaunch) {
300
+ console.log(sectionHeader("Launching " + agentName));
301
+ console.log("");
302
+
303
+ // Open dashboard in app mode
304
+ console.log(status.route("Opening Command Center..."));
305
+ try {
306
+ const dashPath = path.join(projectDir, "dashboard.html").replace(/\\/g, "/");
307
+ const edgePaths = [
308
+ "C:\\Program Files (x86)\\Microsoft\\Edge\\Application\\msedge.exe",
309
+ "C:\\Program Files\\Microsoft\\Edge\\Application\\msedge.exe",
310
+ ];
311
+ let dashLaunched = false;
312
+ for (const ep of edgePaths) {
313
+ if (fs.existsSync(ep)) {
314
+ spawn(ep, [`--app=file:///${dashPath}`, "--window-size=1400,900"], { detached: true, stdio: "ignore" }).unref();
315
+ dashLaunched = true;
316
+ break;
317
+ }
318
+ }
319
+ if (!dashLaunched) execSync(`start "" "${path.join(projectDir, "dashboard.html")}"`, { stdio: "ignore", shell: true });
320
+ console.log(status.ok("Command Center opened"));
321
+ } catch {
322
+ console.log(status.warn("Open dashboard manually: " + path.join(projectDir, "dashboard.html")));
323
+ }
324
+
325
+ // Launch Claude via launch.bat in its own window
326
+ console.log(status.route("Launching Claude Code..."));
327
+ try {
328
+ const launcherPath = path.join(projectDir, "scripts", "launch.bat");
329
+ execSync(`start "" "${launcherPath}"`, { stdio: "ignore", shell: true });
330
+ console.log(status.ok(agentName + " is launching in a new window"));
331
+ } catch {
332
+ console.log(status.warn("Double-click: " + path.join(projectDir, "scripts", "launch.bat")));
333
+ }
334
+
335
+ console.log("");
336
+ console.log(status.info("Files created:"));
337
+ console.log(muted(` Launch: scripts\\launch.bat`));
338
+ console.log(muted(` Dashboard: scripts\\open-dashboard.bat`));
339
+ console.log(muted(` Agents: Desktop\\Agents\\Launch ${agentName}.bat`));
340
+ } else {
341
+ console.log("");
342
+ console.log(muted(" To launch later:"));
343
+ console.log(brand(` Double-click: Desktop\\Agents\\Launch ${agentName}.bat`));
344
+ console.log("");
345
+ }
346
+
347
+ console.log("");
348
+ console.log(goldGradient(" Your agent is ready. Go build something amazing."));
349
+ console.log("");
350
+ }
351
+
352
+ main().catch((err) => {
353
+ console.error(accent(`\n Error: ${err.message}\n`));
354
+ process.exit(1);
355
+ });