create-yonderclaw 1.0.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.
- package/LICENSE +44 -0
- package/README.md +288 -0
- package/bin/create-yonderclaw.mjs +43 -0
- package/docs/assets/favicon.png +0 -0
- package/docs/assets/metaclaw-banner.svg +86 -0
- package/docs/assets/qis-logo.png +0 -0
- package/docs/assets/yz-favicon.png +0 -0
- package/docs/assets/yz-logo.png +0 -0
- package/docs/index.html +1155 -0
- package/installer/assets/favicon.png +0 -0
- package/installer/auto-start.ts +330 -0
- package/installer/brand.ts +115 -0
- package/installer/core-scaffold.ts +448 -0
- package/installer/dashboard-generator.ts +657 -0
- package/installer/detect.ts +129 -0
- package/installer/index.ts +355 -0
- package/installer/module-loader.ts +412 -0
- package/installer/modules/boardroom/boardroom/client.ts.txt +201 -0
- package/installer/modules/boardroom/boardroom/db.ts.txt +322 -0
- package/installer/modules/boardroom/boardroom/meeting-agent.ts.txt +129 -0
- package/installer/modules/boardroom/boardroom/meeting-scheduler.ts.txt +194 -0
- package/installer/modules/boardroom/boardroom/server.ts.txt +473 -0
- package/installer/modules/boardroom/boardroom/start-boardroom.bat.txt +26 -0
- package/installer/modules/boardroom/boardroom/summons.ts.txt +76 -0
- package/installer/modules/boardroom/boardroom/turn-v2.ts.txt +172 -0
- package/installer/modules/boardroom/boardroom/turn.ts.txt +208 -0
- package/installer/modules/boardroom/boardroom/types.ts.txt +100 -0
- package/installer/modules/boardroom/metaclaw-module.json +35 -0
- package/installer/modules/boardroom/scripts/meeting-check.bat.txt +38 -0
- package/installer/modules/core/metaclaw-module.json +51 -0
- package/installer/modules/core/src/db.ts.txt +277 -0
- package/installer/modules/core/src/health-check.ts.txt +128 -0
- package/installer/modules/core/src/observability.ts.txt +20 -0
- package/installer/modules/core/src/safety.ts.txt +26 -0
- package/installer/modules/core/src/scan-capabilities.ts.txt +196 -0
- package/installer/modules/core/src/self-improve.ts.txt +48 -0
- package/installer/modules/core/src/self-update.ts.txt +345 -0
- package/installer/modules/core/src/sync-context.ts.txt +133 -0
- package/installer/modules/core/src/tasks.ts.txt +159 -0
- package/installer/modules/custom/metaclaw-module.json +15 -0
- package/installer/modules/custom/src/agent-custom.ts.txt +100 -0
- package/installer/modules/dashboard/metaclaw-module.json +23 -0
- package/installer/modules/dashboard/scripts/build-dashboard.cjs.txt +51 -0
- package/installer/modules/dashboard/src/update-dashboard.ts.txt +126 -0
- package/installer/modules/outreach/metaclaw-module.json +29 -0
- package/installer/modules/outreach/src/agent-outreach.ts.txt +193 -0
- package/installer/modules/outreach/src/inbox-agent.ts.txt +283 -0
- package/installer/modules/outreach/src/morning-report.ts.txt +124 -0
- package/installer/modules/research/metaclaw-module.json +15 -0
- package/installer/modules/research/src/agent-research.ts.txt +127 -0
- package/installer/modules/scheduler/metaclaw-module.json +27 -0
- package/installer/modules/scheduler/scripts/agent-cycle.bat.txt +85 -0
- package/installer/modules/scheduler/scripts/detect-session.bat.txt +41 -0
- package/installer/modules/scheduler/scripts/launch.bat.txt +120 -0
- package/installer/modules/scheduler/src/cron-manager.ts.txt +273 -0
- package/installer/modules/social/metaclaw-module.json +15 -0
- package/installer/modules/social/src/agent-social.ts.txt +110 -0
- package/installer/modules/support/metaclaw-module.json +15 -0
- package/installer/modules/support/src/agent-support.ts.txt +60 -0
- package/installer/modules/swarm/metaclaw-module.json +25 -0
- package/installer/modules/swarm/swarm/dht-client.ts.txt +376 -0
- package/installer/modules/swarm/swarm/relay-server.ts.txt +348 -0
- package/installer/modules/swarm/swarm/swarm-client.ts.txt +303 -0
- package/installer/modules/swarm/swarm/types.ts.txt +51 -0
- package/installer/modules/voice/metaclaw-module.json +16 -0
- package/installer/questionnaire.ts +277 -0
- package/installer/research.ts +258 -0
- package/installer/scaffold-from-config.ts +270 -0
- package/installer/task-generator.ts +324 -0
- package/installer/templates/agent-custom.ts.txt +100 -0
- package/installer/templates/agent-cycle.bat.txt +19 -0
- package/installer/templates/agent-outreach.ts.txt +193 -0
- package/installer/templates/agent-research.ts.txt +127 -0
- package/installer/templates/agent-social.ts.txt +110 -0
- package/installer/templates/agent-support.ts.txt +60 -0
- package/installer/templates/build-dashboard.cjs.txt +51 -0
- package/installer/templates/cron-manager.ts.txt +273 -0
- package/installer/templates/dashboard.html.txt +450 -0
- package/installer/templates/db.ts.txt +277 -0
- package/installer/templates/detect-session.bat.txt +41 -0
- package/installer/templates/health-check.ts.txt +128 -0
- package/installer/templates/inbox-agent.ts.txt +283 -0
- package/installer/templates/launch.bat.txt +120 -0
- package/installer/templates/morning-report.ts.txt +124 -0
- package/installer/templates/observability.ts.txt +20 -0
- package/installer/templates/safety.ts.txt +26 -0
- package/installer/templates/self-improve.ts.txt +48 -0
- package/installer/templates/self-update.ts.txt +345 -0
- package/installer/templates/state.json.txt +33 -0
- package/installer/templates/system-context.json.txt +33 -0
- package/installer/templates/update-dashboard.ts.txt +126 -0
- package/package.json +31 -0
- package/setup.bat +178 -0
|
Binary file
|
|
@@ -0,0 +1,330 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MetaClaw Auto-Start — named sessions that survive reboots
|
|
3
|
+
*
|
|
4
|
+
* Creates:
|
|
5
|
+
* 1. A named Claude Code session for the agent
|
|
6
|
+
* 2. A startup script that auto-launches and resumes that session
|
|
7
|
+
* 3. Task Scheduler entries for background jobs (inbox, follow-ups)
|
|
8
|
+
*
|
|
9
|
+
* The user never has to manually open Claude or remember session IDs.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import fs from "fs";
|
|
13
|
+
import path from "path";
|
|
14
|
+
import { execSync } from "child_process";
|
|
15
|
+
import os from "os";
|
|
16
|
+
import * as clack from "@clack/prompts";
|
|
17
|
+
import { brand, muted, success, status } from "./brand.js";
|
|
18
|
+
import type { SystemInfo } from "./detect.js";
|
|
19
|
+
|
|
20
|
+
export type AutoStartConfig = {
|
|
21
|
+
clawName: string; // User-chosen name, e.g. "SalesBot", "ResearchAgent"
|
|
22
|
+
sessionName: string; // Sanitized for file paths
|
|
23
|
+
projectDir: string;
|
|
24
|
+
claudePath: string; // Full path to claude.exe
|
|
25
|
+
startOnBoot: boolean;
|
|
26
|
+
backgroundTasks: Array<{
|
|
27
|
+
name: string;
|
|
28
|
+
script: string;
|
|
29
|
+
intervalMinutes: number;
|
|
30
|
+
businessHoursOnly: boolean;
|
|
31
|
+
}>;
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Ask the user to name their agent and configure auto-start.
|
|
36
|
+
*/
|
|
37
|
+
export async function configureAutoStart(
|
|
38
|
+
projectDir: string,
|
|
39
|
+
systemInfo: SystemInfo
|
|
40
|
+
): Promise<AutoStartConfig | null> {
|
|
41
|
+
const clawName = await clack.text({
|
|
42
|
+
message: "Name your agent (this is what it calls itself)",
|
|
43
|
+
placeholder: "Atlas",
|
|
44
|
+
defaultValue: "Atlas",
|
|
45
|
+
});
|
|
46
|
+
if (clack.isCancel(clawName)) return null;
|
|
47
|
+
|
|
48
|
+
const startOnBoot = await clack.confirm({
|
|
49
|
+
message: "Start this agent automatically when your PC boots?",
|
|
50
|
+
initialValue: true,
|
|
51
|
+
});
|
|
52
|
+
if (clack.isCancel(startOnBoot)) return null;
|
|
53
|
+
|
|
54
|
+
// Find Claude executable
|
|
55
|
+
const claudePath = findClaudePath(systemInfo);
|
|
56
|
+
|
|
57
|
+
const sessionName = (clawName as string).toLowerCase().replace(/[^a-z0-9]/g, "-");
|
|
58
|
+
|
|
59
|
+
return {
|
|
60
|
+
clawName: clawName as string,
|
|
61
|
+
sessionName,
|
|
62
|
+
projectDir,
|
|
63
|
+
claudePath,
|
|
64
|
+
startOnBoot: startOnBoot as boolean,
|
|
65
|
+
backgroundTasks: [
|
|
66
|
+
{ name: "InboxCheck", script: "src/inbox.ts", intervalMinutes: 30, businessHoursOnly: false },
|
|
67
|
+
{ name: "FollowUps", script: "src/run-followups.ts", intervalMinutes: 120, businessHoursOnly: true },
|
|
68
|
+
],
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Find the Claude Code executable path.
|
|
74
|
+
*/
|
|
75
|
+
function findClaudePath(systemInfo: SystemInfo): string {
|
|
76
|
+
const candidates = [
|
|
77
|
+
path.join(systemInfo.user.homedir, ".local", "bin", "claude.exe"),
|
|
78
|
+
path.join(systemInfo.user.homedir, ".local", "bin", "claude"),
|
|
79
|
+
"claude",
|
|
80
|
+
];
|
|
81
|
+
|
|
82
|
+
for (const p of candidates) {
|
|
83
|
+
try {
|
|
84
|
+
const resolved = execSync(`where "${p}" 2>nul || which "${p}" 2>/dev/null`, {
|
|
85
|
+
encoding: "utf-8",
|
|
86
|
+
timeout: 3000,
|
|
87
|
+
}).trim().split("\n")[0];
|
|
88
|
+
if (resolved) return resolved;
|
|
89
|
+
} catch {}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// Check if the local path exists directly
|
|
93
|
+
for (const p of candidates) {
|
|
94
|
+
if (fs.existsSync(p)) return p;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
return candidates[0]; // Best guess
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Create all auto-start scripts and register them.
|
|
102
|
+
*/
|
|
103
|
+
export function setupAutoStart(config: AutoStartConfig, systemInfo: SystemInfo): void {
|
|
104
|
+
const platform = systemInfo.os.platform;
|
|
105
|
+
|
|
106
|
+
if (platform === "Windows") {
|
|
107
|
+
setupWindowsAutoStart(config);
|
|
108
|
+
} else if (platform === "Linux") {
|
|
109
|
+
setupLinuxAutoStart(config);
|
|
110
|
+
} else if (platform === "macOS") {
|
|
111
|
+
setupMacAutoStart(config);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// ═══════════════════════════════════════
|
|
116
|
+
// WINDOWS
|
|
117
|
+
// ═══════════════════════════════════════
|
|
118
|
+
|
|
119
|
+
function setupWindowsAutoStart(config: AutoStartConfig) {
|
|
120
|
+
const scriptsDir = path.join(config.projectDir, "scripts");
|
|
121
|
+
fs.mkdirSync(scriptsDir, { recursive: true });
|
|
122
|
+
|
|
123
|
+
// 1. Create the agent launcher script
|
|
124
|
+
const launcherPath = path.join(scriptsDir, `launch-${config.sessionName}.bat`);
|
|
125
|
+
fs.writeFileSync(launcherPath, `@echo off
|
|
126
|
+
REM === MetaClaw Agent Launcher: ${config.clawName} ===
|
|
127
|
+
REM Auto-launches Claude Code and resumes the agent session.
|
|
128
|
+
REM Generated by MetaClaw Installer v3.3.0
|
|
129
|
+
|
|
130
|
+
title MetaClaw: ${config.clawName}
|
|
131
|
+
cd /d "${config.projectDir}"
|
|
132
|
+
|
|
133
|
+
echo.
|
|
134
|
+
echo Starting ${config.clawName}...
|
|
135
|
+
echo Session: ${config.sessionName}
|
|
136
|
+
echo.
|
|
137
|
+
|
|
138
|
+
REM Try to continue the last session, or start a new one
|
|
139
|
+
"${config.claudePath}" --continue --yes -p "You are ${config.clawName}, a MetaClaw autonomous agent. Read CLAUDE.md for your full configuration. Resume your tasks. Check HEARTBEAT.md for your scheduled checklist. Run any pending tasks."
|
|
140
|
+
|
|
141
|
+
REM If --continue fails (no prior session), start fresh
|
|
142
|
+
if %ERRORLEVEL% neq 0 (
|
|
143
|
+
"${config.claudePath}" --yes -p "You are ${config.clawName}, a MetaClaw autonomous agent. Read CLAUDE.md for your full configuration and begin your work. Check HEARTBEAT.md for your scheduled checklist."
|
|
144
|
+
)
|
|
145
|
+
|
|
146
|
+
REM Restart on exit (keeps the agent alive)
|
|
147
|
+
echo.
|
|
148
|
+
echo ${config.clawName} exited. Restarting in 10 seconds...
|
|
149
|
+
timeout /t 10 /nobreak >nul
|
|
150
|
+
goto :start
|
|
151
|
+
|
|
152
|
+
:start
|
|
153
|
+
"${config.claudePath}" --continue --yes -p "You are ${config.clawName}. Resume your tasks. Check HEARTBEAT.md."
|
|
154
|
+
goto :start
|
|
155
|
+
`);
|
|
156
|
+
|
|
157
|
+
// 2. Create a VBS wrapper to launch hidden (no visible window)
|
|
158
|
+
const vbsPath = path.join(scriptsDir, `launch-${config.sessionName}.vbs`);
|
|
159
|
+
fs.writeFileSync(vbsPath, `' MetaClaw Silent Launcher: ${config.clawName}
|
|
160
|
+
' Starts the agent in a minimized window
|
|
161
|
+
Set WshShell = CreateObject("WScript.Shell")
|
|
162
|
+
WshShell.Run chr(34) & "${launcherPath.replace(/\\/g, "\\\\")}" & chr(34), 7, False
|
|
163
|
+
`);
|
|
164
|
+
|
|
165
|
+
// 3. Background task scripts
|
|
166
|
+
for (const task of config.backgroundTasks) {
|
|
167
|
+
const taskBat = path.join(scriptsDir, `${task.name.toLowerCase()}.bat`);
|
|
168
|
+
fs.writeFileSync(taskBat, `@echo off
|
|
169
|
+
cd /d "${config.projectDir}"
|
|
170
|
+
npx tsx ${task.script} >> "data\\logs\\${task.name.toLowerCase()}.log" 2>&1
|
|
171
|
+
`);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// 4. Register with Task Scheduler
|
|
175
|
+
if (config.startOnBoot) {
|
|
176
|
+
try {
|
|
177
|
+
// Agent launcher — runs on logon
|
|
178
|
+
execSync(
|
|
179
|
+
`schtasks /create /tn "MetaClaw-${config.sessionName}" /tr "\\"${vbsPath}\\"" /sc ONLOGON /ru "%USERNAME%" /f`,
|
|
180
|
+
{ stdio: "pipe" }
|
|
181
|
+
);
|
|
182
|
+
console.log(status.ok(`Auto-start on login: MetaClaw-${config.sessionName}`));
|
|
183
|
+
} catch {
|
|
184
|
+
console.log(status.warn("Could not create logon task (run as Administrator)"));
|
|
185
|
+
|
|
186
|
+
// Fallback: add to Startup folder
|
|
187
|
+
const startupDir = path.join(os.homedir(), "AppData", "Roaming", "Microsoft", "Windows", "Start Menu", "Programs", "Startup");
|
|
188
|
+
try {
|
|
189
|
+
const shortcutPath = path.join(startupDir, `MetaClaw-${config.sessionName}.vbs`);
|
|
190
|
+
fs.copyFileSync(vbsPath, shortcutPath);
|
|
191
|
+
console.log(status.ok(`Added to Startup folder: ${shortcutPath}`));
|
|
192
|
+
} catch {
|
|
193
|
+
console.log(status.warn("Could not add to Startup folder either"));
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
// Background tasks
|
|
198
|
+
for (const task of config.backgroundTasks) {
|
|
199
|
+
try {
|
|
200
|
+
const taskBat = path.join(scriptsDir, `${task.name.toLowerCase()}.bat`);
|
|
201
|
+
const schedArgs = task.businessHoursOnly
|
|
202
|
+
? `/sc MINUTE /mo ${task.intervalMinutes} /st 08:00 /et 18:00`
|
|
203
|
+
: `/sc MINUTE /mo ${task.intervalMinutes}`;
|
|
204
|
+
|
|
205
|
+
execSync(
|
|
206
|
+
`schtasks /create /tn "MetaClaw-${config.sessionName}-${task.name}" /tr "\\"${taskBat}\\"" ${schedArgs} /ru "%USERNAME%" /f`,
|
|
207
|
+
{ stdio: "pipe" }
|
|
208
|
+
);
|
|
209
|
+
console.log(status.ok(`Scheduled: ${task.name} every ${task.intervalMinutes}m${task.businessHoursOnly ? " (business hours)" : ""}`));
|
|
210
|
+
} catch {
|
|
211
|
+
console.log(status.warn(`Could not schedule ${task.name} (run as Administrator)`));
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
// 5. Create a stop script
|
|
217
|
+
const stopPath = path.join(scriptsDir, `stop-${config.sessionName}.bat`);
|
|
218
|
+
fs.writeFileSync(stopPath, `@echo off
|
|
219
|
+
echo Stopping ${config.clawName}...
|
|
220
|
+
schtasks /end /tn "MetaClaw-${config.sessionName}" 2>nul
|
|
221
|
+
schtasks /end /tn "MetaClaw-${config.sessionName}-InboxCheck" 2>nul
|
|
222
|
+
schtasks /end /tn "MetaClaw-${config.sessionName}-FollowUps" 2>nul
|
|
223
|
+
taskkill /f /fi "WINDOWTITLE eq MetaClaw: ${config.clawName}" 2>nul
|
|
224
|
+
echo ${config.clawName} stopped.
|
|
225
|
+
pause
|
|
226
|
+
`);
|
|
227
|
+
|
|
228
|
+
// 6. Create a status script
|
|
229
|
+
const statusPath = path.join(scriptsDir, `status-${config.sessionName}.bat`);
|
|
230
|
+
fs.writeFileSync(statusPath, `@echo off
|
|
231
|
+
echo === ${config.clawName} Status ===
|
|
232
|
+
echo.
|
|
233
|
+
schtasks /query /tn "MetaClaw-${config.sessionName}" /fo LIST 2>nul || echo Agent launcher: Not scheduled
|
|
234
|
+
echo.
|
|
235
|
+
schtasks /query /tn "MetaClaw-${config.sessionName}-InboxCheck" /fo LIST 2>nul || echo Inbox check: Not scheduled
|
|
236
|
+
echo.
|
|
237
|
+
cd /d "${config.projectDir}"
|
|
238
|
+
npx tsx src/agent.ts --status
|
|
239
|
+
pause
|
|
240
|
+
`);
|
|
241
|
+
|
|
242
|
+
console.log("");
|
|
243
|
+
console.log(status.info(`Launcher: scripts/launch-${config.sessionName}.bat`));
|
|
244
|
+
console.log(status.info(`Stop: scripts/stop-${config.sessionName}.bat`));
|
|
245
|
+
console.log(status.info(`Status: scripts/status-${config.sessionName}.bat`));
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
// ═══════════════════════════════════════
|
|
249
|
+
// LINUX (systemd)
|
|
250
|
+
// ═══════════════════════════════════════
|
|
251
|
+
|
|
252
|
+
function setupLinuxAutoStart(config: AutoStartConfig) {
|
|
253
|
+
const serviceFile = `[Unit]
|
|
254
|
+
Description=MetaClaw Agent: ${config.clawName}
|
|
255
|
+
After=network.target
|
|
256
|
+
|
|
257
|
+
[Service]
|
|
258
|
+
Type=simple
|
|
259
|
+
WorkingDirectory=${config.projectDir}
|
|
260
|
+
ExecStart=${config.claudePath} --continue --yes -p "You are ${config.clawName}. Resume tasks. Check HEARTBEAT.md."
|
|
261
|
+
Restart=always
|
|
262
|
+
RestartSec=10
|
|
263
|
+
Environment=HOME=${os.homedir()}
|
|
264
|
+
|
|
265
|
+
[Install]
|
|
266
|
+
WantedBy=default.target
|
|
267
|
+
`;
|
|
268
|
+
|
|
269
|
+
const servicePath = path.join(config.projectDir, "scripts", `metaclaw-${config.sessionName}.service`);
|
|
270
|
+
fs.writeFileSync(servicePath, serviceFile);
|
|
271
|
+
|
|
272
|
+
console.log(status.info("Systemd service file created."));
|
|
273
|
+
console.log(status.info("To enable:"));
|
|
274
|
+
console.log(muted(` cp ${servicePath} ~/.config/systemd/user/`));
|
|
275
|
+
console.log(muted(` systemctl --user enable metaclaw-${config.sessionName}`));
|
|
276
|
+
console.log(muted(` systemctl --user start metaclaw-${config.sessionName}`));
|
|
277
|
+
|
|
278
|
+
// Cron for background tasks
|
|
279
|
+
const cronLines = config.backgroundTasks.map((t) => {
|
|
280
|
+
const cron = t.businessHoursOnly
|
|
281
|
+
? `*/${t.intervalMinutes} 8-18 * * *`
|
|
282
|
+
: `*/${t.intervalMinutes} * * * *`;
|
|
283
|
+
return `${cron} cd ${config.projectDir} && npx tsx ${t.script} >> data/logs/${t.name.toLowerCase()}.log 2>&1`;
|
|
284
|
+
});
|
|
285
|
+
|
|
286
|
+
const cronPath = path.join(config.projectDir, "scripts", "crontab.txt");
|
|
287
|
+
fs.writeFileSync(cronPath, cronLines.join("\n") + "\n");
|
|
288
|
+
console.log(status.info(`Crontab: crontab ${cronPath}`));
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
// ═══════════════════════════════════════
|
|
292
|
+
// macOS (launchd)
|
|
293
|
+
// ═══════════════════════════════════════
|
|
294
|
+
|
|
295
|
+
function setupMacAutoStart(config: AutoStartConfig) {
|
|
296
|
+
const plist = `<?xml version="1.0" encoding="UTF-8"?>
|
|
297
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
298
|
+
<plist version="1.0">
|
|
299
|
+
<dict>
|
|
300
|
+
<key>Label</key>
|
|
301
|
+
<string>com.metaclaw.${config.sessionName}</string>
|
|
302
|
+
<key>ProgramArguments</key>
|
|
303
|
+
<array>
|
|
304
|
+
<string>${config.claudePath}</string>
|
|
305
|
+
<string>--continue</string>
|
|
306
|
+
<string>--yes</string>
|
|
307
|
+
<string>-p</string>
|
|
308
|
+
<string>You are ${config.clawName}. Resume tasks. Check HEARTBEAT.md.</string>
|
|
309
|
+
</array>
|
|
310
|
+
<key>WorkingDirectory</key>
|
|
311
|
+
<string>${config.projectDir}</string>
|
|
312
|
+
<key>RunAtLoad</key>
|
|
313
|
+
<true/>
|
|
314
|
+
<key>KeepAlive</key>
|
|
315
|
+
<true/>
|
|
316
|
+
<key>StandardOutPath</key>
|
|
317
|
+
<string>${config.projectDir}/data/logs/agent.log</string>
|
|
318
|
+
<key>StandardErrorPath</key>
|
|
319
|
+
<string>${config.projectDir}/data/logs/agent-error.log</string>
|
|
320
|
+
</dict>
|
|
321
|
+
</plist>`;
|
|
322
|
+
|
|
323
|
+
const plistPath = path.join(config.projectDir, "scripts", `com.metaclaw.${config.sessionName}.plist`);
|
|
324
|
+
fs.writeFileSync(plistPath, plist);
|
|
325
|
+
|
|
326
|
+
console.log(status.info("LaunchAgent plist created."));
|
|
327
|
+
console.log(status.info("To enable:"));
|
|
328
|
+
console.log(muted(` cp ${plistPath} ~/Library/LaunchAgents/`));
|
|
329
|
+
console.log(muted(` launchctl load ~/Library/LaunchAgents/com.metaclaw.${config.sessionName}.plist`));
|
|
330
|
+
}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MetaClaw Branding v3 — clean, premium, no QIS references
|
|
3
|
+
* by Christopher Trevethan / Yonder Zenith LLC
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import chalk from "chalk";
|
|
7
|
+
import gradient from "gradient-string";
|
|
8
|
+
import figlet from "figlet";
|
|
9
|
+
|
|
10
|
+
// Colors matched to YZ/QIS branding — cyan dominant, clean dark theme
|
|
11
|
+
export const COLORS = {
|
|
12
|
+
primary: "#00BEEA", // YZ cyan (from favicon)
|
|
13
|
+
secondary: "#00D9FF", // Bright cyan accent
|
|
14
|
+
accent: "#FF6B6B", // Warnings only
|
|
15
|
+
success: "#10B981", // Green
|
|
16
|
+
muted: "#7F8C8D",
|
|
17
|
+
gold: "#FFD700",
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
// Brand gradient: cyan tones only — no rainbow
|
|
21
|
+
export const brandGradient = gradient(["#00BEEA", "#00D9FF", "#00BEEA"]);
|
|
22
|
+
export const cyanGradient = gradient(["#00BEEA", "#00D9FF"]);
|
|
23
|
+
export const successGradient = gradient(["#10B981", "#00BEEA"]);
|
|
24
|
+
export const goldGradient = gradient(["#FFD700", "#00BEEA"]);
|
|
25
|
+
|
|
26
|
+
export const brand = chalk.hex(COLORS.primary);
|
|
27
|
+
export const accent = chalk.hex(COLORS.accent);
|
|
28
|
+
export const muted = chalk.hex(COLORS.muted);
|
|
29
|
+
export const success = chalk.hex(COLORS.success);
|
|
30
|
+
export const purple = chalk.hex(COLORS.secondary);
|
|
31
|
+
export const gold = chalk.hex(COLORS.gold);
|
|
32
|
+
|
|
33
|
+
export function getLogo(): string {
|
|
34
|
+
const raw = figlet.textSync("MetaClaw", {
|
|
35
|
+
font: "ANSI Shadow",
|
|
36
|
+
horizontalLayout: "fitted",
|
|
37
|
+
});
|
|
38
|
+
return brandGradient(raw);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export function getTagline(): string {
|
|
42
|
+
return [
|
|
43
|
+
muted(" Autonomous AI Agents — Plug & Play"),
|
|
44
|
+
muted(" by ") + gold("Christopher Trevethan") + muted(" / ") + purple("Yonder Zenith LLC"),
|
|
45
|
+
].join("\n");
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export function getVersion(): string {
|
|
49
|
+
return chalk.bgHex(COLORS.primary).black(" MetaClaw v3.3.0 ");
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export function sectionHeader(title: string): string {
|
|
53
|
+
const line = brand("═".repeat(54));
|
|
54
|
+
return `\n${line}\n ${brandGradient(title)}\n${line}`;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export const status = {
|
|
58
|
+
ok: (msg: string) => ` ${success("✓")} ${msg}`,
|
|
59
|
+
fail: (msg: string) => ` ${accent("✗")} ${msg}`,
|
|
60
|
+
warn: (msg: string) => ` ${chalk.yellow("⚠")} ${msg}`,
|
|
61
|
+
info: (msg: string) => ` ${brand("›")} ${msg}`,
|
|
62
|
+
pending: (msg: string) => ` ${muted("○")} ${msg}`,
|
|
63
|
+
route: (msg: string) => ` ${cyanGradient("⟶")} ${msg}`,
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
export function box(content: string, width: number = 64): string {
|
|
67
|
+
const lines = content.split("\n");
|
|
68
|
+
const top = brand("╔" + "═".repeat(width - 2) + "╗");
|
|
69
|
+
const bottom = brand("╚" + "═".repeat(width - 2) + "╝");
|
|
70
|
+
const padded = lines.map((line) => {
|
|
71
|
+
const visible = line.replace(/\x1b\[[0-9;]*m/g, "");
|
|
72
|
+
const padding = Math.max(0, width - 4 - visible.length);
|
|
73
|
+
return brand("║") + " " + line + " ".repeat(padding) + brand("║");
|
|
74
|
+
});
|
|
75
|
+
return [top, ...padded, bottom].join("\n");
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export function welcomeScreen(): string {
|
|
79
|
+
return [
|
|
80
|
+
"",
|
|
81
|
+
getLogo(),
|
|
82
|
+
"",
|
|
83
|
+
` ${getVersion()}`,
|
|
84
|
+
"",
|
|
85
|
+
getTagline(),
|
|
86
|
+
"",
|
|
87
|
+
box([
|
|
88
|
+
successGradient(" Deploy autonomous AI agents in minutes."),
|
|
89
|
+
"",
|
|
90
|
+
muted(" Detect → Configure → Research → Deploy → Self-Improve"),
|
|
91
|
+
"",
|
|
92
|
+
brand(" Your custom agent, built by experts. Automatically."),
|
|
93
|
+
].join("\n")),
|
|
94
|
+
"",
|
|
95
|
+
].join("\n");
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
export function completionScreen(agentName: string, projectDir: string, clawType: string): string {
|
|
99
|
+
return [
|
|
100
|
+
"",
|
|
101
|
+
box([
|
|
102
|
+
successGradient(` ${agentName} is alive.`),
|
|
103
|
+
"",
|
|
104
|
+
` ${brand("Agent:")} ${agentName}`,
|
|
105
|
+
` ${brand("Type:")} ${clawType}`,
|
|
106
|
+
` ${brand("Location:")} ${projectDir}`,
|
|
107
|
+
` ${brand("Version:")} MetaClaw v3.3.0`,
|
|
108
|
+
` ${brand("Status:")} ${success("● Deployed & Auto-Starting")}`,
|
|
109
|
+
].join("\n")),
|
|
110
|
+
"",
|
|
111
|
+
muted(" Created by ") + gold("Christopher Trevethan"),
|
|
112
|
+
muted(" ") + purple("Yonder Zenith LLC"),
|
|
113
|
+
"",
|
|
114
|
+
].join("\n");
|
|
115
|
+
}
|