@agentvault/agentvault 0.14.21 → 0.14.23
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/channel.d.ts +4 -0
- package/dist/channel.d.ts.map +1 -1
- package/dist/cli.js +382 -313
- package/dist/cli.js.map +4 -4
- package/dist/create-agent.d.ts.map +1 -1
- package/dist/http-handlers.d.ts.map +1 -1
- package/dist/index.js +11 -2
- package/dist/index.js.map +2 -2
- package/dist/openclaw-entry.js +3 -2
- package/dist/openclaw-entry.js.map +2 -2
- package/dist/setup.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -46432,10 +46432,11 @@ async function handleSendRequest(parsed, channel2) {
|
|
|
46432
46432
|
const hubAddr = channel2.resolveA2AChannelHub(parsed.channel_id);
|
|
46433
46433
|
if (hubAddr) a2aTarget = hubAddr;
|
|
46434
46434
|
}
|
|
46435
|
+
const roomId = parsed.room_id ?? channel2.lastInboundRoomId;
|
|
46435
46436
|
if (a2aTarget && typeof a2aTarget === "string") {
|
|
46436
46437
|
await channel2.sendToAgent(a2aTarget, text);
|
|
46437
|
-
} else if (
|
|
46438
|
-
await channel2.sendToRoom(
|
|
46438
|
+
} else if (roomId) {
|
|
46439
|
+
await channel2.sendToRoom(roomId, text, {
|
|
46439
46440
|
messageType: parsed.message_type,
|
|
46440
46441
|
priority: parsed.priority,
|
|
46441
46442
|
metadata: parsed.metadata
|
|
@@ -46753,6 +46754,8 @@ var init_channel = __esm({
|
|
|
46753
46754
|
_telemetryReporter = null;
|
|
46754
46755
|
/** Topic ID from the most recent inbound message — used as fallback for replies. */
|
|
46755
46756
|
_lastIncomingTopicId;
|
|
46757
|
+
/** Room ID from the most recent inbound room message — used as fallback for HTTP /send replies. */
|
|
46758
|
+
_lastInboundRoomId;
|
|
46756
46759
|
/** Rate-limit: last resync_request timestamp per conversation (5-min cooldown). */
|
|
46757
46760
|
_lastResyncRequest = /* @__PURE__ */ new Map();
|
|
46758
46761
|
/** Debounce timer for server backup uploads (60s). */
|
|
@@ -46786,6 +46789,10 @@ var init_channel = __esm({
|
|
|
46786
46789
|
get sessionCount() {
|
|
46787
46790
|
return this._sessions.size;
|
|
46788
46791
|
}
|
|
46792
|
+
/** Room ID from the most recent inbound room message (for HTTP /send fallback). */
|
|
46793
|
+
get lastInboundRoomId() {
|
|
46794
|
+
return this._lastInboundRoomId;
|
|
46795
|
+
}
|
|
46789
46796
|
/** Returns hub addresses of all persisted A2A peer channels. */
|
|
46790
46797
|
get a2aPeerAddresses() {
|
|
46791
46798
|
if (!this._persisted?.a2aChannels) return [];
|
|
@@ -48691,6 +48698,7 @@ ${messageText}`;
|
|
|
48691
48698
|
}
|
|
48692
48699
|
}
|
|
48693
48700
|
}
|
|
48701
|
+
if (!roomId) this._lastInboundRoomId = void 0;
|
|
48694
48702
|
const metadata = {
|
|
48695
48703
|
messageId: msgData.message_id,
|
|
48696
48704
|
conversationId: convId,
|
|
@@ -49070,6 +49078,7 @@ ${messageText}`;
|
|
|
49070
49078
|
*/
|
|
49071
49079
|
async _handleRoomMessage(msgData) {
|
|
49072
49080
|
if (msgData.sender_device_id === this._deviceId) return;
|
|
49081
|
+
this._lastInboundRoomId = msgData.room_id;
|
|
49073
49082
|
const convId = msgData.conversation_id ?? this._findConversationForSender(msgData.sender_device_id, msgData.room_id);
|
|
49074
49083
|
if (!convId) {
|
|
49075
49084
|
console.warn(
|
|
@@ -70513,265 +70522,6 @@ var init_index = __esm({
|
|
|
70513
70522
|
}
|
|
70514
70523
|
});
|
|
70515
70524
|
|
|
70516
|
-
// src/create-agent.ts
|
|
70517
|
-
var create_agent_exports = {};
|
|
70518
|
-
__export(create_agent_exports, {
|
|
70519
|
-
findNextPort: () => findNextPort,
|
|
70520
|
-
generateWorkspaceFiles: () => generateWorkspaceFiles,
|
|
70521
|
-
openclawHome: () => openclawHome,
|
|
70522
|
-
readOpenClawConfig: () => readOpenClawConfig,
|
|
70523
|
-
runCreateCommand: () => runCreateCommand
|
|
70524
|
-
});
|
|
70525
|
-
import { execSync } from "node:child_process";
|
|
70526
|
-
import { existsSync, mkdirSync, readFileSync, writeFileSync, copyFileSync } from "node:fs";
|
|
70527
|
-
import { join as join4 } from "node:path";
|
|
70528
|
-
function openclawHome() {
|
|
70529
|
-
const home = process.env.HOME ?? process.env.USERPROFILE ?? "";
|
|
70530
|
-
return join4(home, ".openclaw");
|
|
70531
|
-
}
|
|
70532
|
-
function readOpenClawConfig(home) {
|
|
70533
|
-
const configPath = join4(home, "openclaw.json");
|
|
70534
|
-
const raw = readFileSync(configPath, "utf-8");
|
|
70535
|
-
return JSON.parse(raw);
|
|
70536
|
-
}
|
|
70537
|
-
function writeOpenClawConfig(home, config2, backupSuffix) {
|
|
70538
|
-
const configPath = join4(home, "openclaw.json");
|
|
70539
|
-
const backupPath = `${configPath}.bak.pre-${backupSuffix}`;
|
|
70540
|
-
copyFileSync(configPath, backupPath);
|
|
70541
|
-
writeFileSync(configPath, JSON.stringify(config2, null, 2) + "\n", "utf-8");
|
|
70542
|
-
}
|
|
70543
|
-
function collectPorts(config2) {
|
|
70544
|
-
const ports = [];
|
|
70545
|
-
const accounts = config2?.channels?.agentvault?.accounts;
|
|
70546
|
-
if (accounts && typeof accounts === "object") {
|
|
70547
|
-
for (const acct of Object.values(accounts)) {
|
|
70548
|
-
if (typeof acct.httpPort === "number") {
|
|
70549
|
-
ports.push(acct.httpPort);
|
|
70550
|
-
}
|
|
70551
|
-
}
|
|
70552
|
-
}
|
|
70553
|
-
return ports;
|
|
70554
|
-
}
|
|
70555
|
-
function findNextPort(config2, startPort = 18800) {
|
|
70556
|
-
const ports = collectPorts(config2);
|
|
70557
|
-
if (ports.length === 0) return startPort;
|
|
70558
|
-
return Math.max(...ports, startPort - 1) + 1;
|
|
70559
|
-
}
|
|
70560
|
-
function isPortInUse(config2, port) {
|
|
70561
|
-
return collectPorts(config2).includes(port);
|
|
70562
|
-
}
|
|
70563
|
-
function generateWorkspaceFiles(name2) {
|
|
70564
|
-
const displayName = name2.charAt(0).toUpperCase() + name2.slice(1).toLowerCase();
|
|
70565
|
-
return {
|
|
70566
|
-
"IDENTITY.md": `# IDENTITY.md - Who Am I?
|
|
70567
|
-
|
|
70568
|
-
- **Name:** ${displayName}
|
|
70569
|
-
- **Creature:** AI assistant \u2014 a capable peer agent in the AgentVault network
|
|
70570
|
-
- **Vibe:** Direct, competent, focused on their specialty domain
|
|
70571
|
-
- **Emoji:** (placeholder \u2014 update to something fitting)
|
|
70572
|
-
- **Avatar:** _(none set yet)_
|
|
70573
|
-
|
|
70574
|
-
> TODO: Customize this file to give ${name2} a distinct identity.
|
|
70575
|
-
`,
|
|
70576
|
-
"SOUL.md": `# SOUL.md - Who You Are
|
|
70577
|
-
|
|
70578
|
-
> TODO: Define ${name2}'s personality, tone, and behavioral rules.
|
|
70579
|
-
> Copy and adapt from ~/.openclaw/workspace/SOUL.md as a starting point.
|
|
70580
|
-
|
|
70581
|
-
## Core Truths
|
|
70582
|
-
|
|
70583
|
-
- Be genuinely helpful, not performatively helpful.
|
|
70584
|
-
- Have opinions. Be resourceful before asking.
|
|
70585
|
-
- Earn trust through competence.
|
|
70586
|
-
|
|
70587
|
-
## Channel Reply Rules
|
|
70588
|
-
|
|
70589
|
-
- Never include reasoning or internal logic in visible replies.
|
|
70590
|
-
- No narrating your approach before or after tool calls.
|
|
70591
|
-
- Just deliver the answer \u2014 clean and direct.
|
|
70592
|
-
|
|
70593
|
-
## Vibe
|
|
70594
|
-
|
|
70595
|
-
_(Define ${name2}'s specific personality here.)_
|
|
70596
|
-
`,
|
|
70597
|
-
"HEARTBEAT.md": `# Heartbeat
|
|
70598
|
-
|
|
70599
|
-
- Stay available. If nothing needs attention, reply HEARTBEAT_OK.
|
|
70600
|
-
- **Heartbeat replies are INTERNAL ONLY.** Reply with ONLY \`HEARTBEAT_OK\` when nothing needs attention.
|
|
70601
|
-
- If something genuinely urgent needs attention, send it proactively FIRST, THEN reply HEARTBEAT_OK.
|
|
70602
|
-
`,
|
|
70603
|
-
"MEMORY.md": `# MEMORY.md - Long-Term Memory
|
|
70604
|
-
|
|
70605
|
-
_(Empty \u2014 ${name2} starts with a clean memory. Update as the agent learns.)_
|
|
70606
|
-
`
|
|
70607
|
-
};
|
|
70608
|
-
}
|
|
70609
|
-
async function runCreateCommand(options) {
|
|
70610
|
-
const { name: name2, token: token2, apiUrl: apiUrl2, force } = options;
|
|
70611
|
-
const home = openclawHome();
|
|
70612
|
-
const configPath = join4(home, "openclaw.json");
|
|
70613
|
-
const workspaceDir = join4(home, `workspace-${name2}`);
|
|
70614
|
-
const dataDir2 = join4(home, "agents", name2, "agentvault-data");
|
|
70615
|
-
const templateDir = join4(home, "workspace");
|
|
70616
|
-
console.log(`
|
|
70617
|
-
\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557
|
|
70618
|
-
\u2551 AgentVault \u2014 Create New Agent \u2551
|
|
70619
|
-
\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D
|
|
70620
|
-
`);
|
|
70621
|
-
console.log(" Step 1/7 \u2014 Preflight checks...");
|
|
70622
|
-
try {
|
|
70623
|
-
execSync("openclaw --version", { stdio: "pipe" });
|
|
70624
|
-
} catch {
|
|
70625
|
-
console.error(" Error: 'openclaw' not found in PATH. Is OpenClaw installed?");
|
|
70626
|
-
process.exit(1);
|
|
70627
|
-
}
|
|
70628
|
-
if (!existsSync(configPath)) {
|
|
70629
|
-
console.error(` Error: openclaw.json not found at ${configPath}`);
|
|
70630
|
-
process.exit(1);
|
|
70631
|
-
}
|
|
70632
|
-
console.log(" Preflight passed.\n");
|
|
70633
|
-
console.log(" Step 2/7 \u2014 Detecting port...");
|
|
70634
|
-
const config2 = readOpenClawConfig(home);
|
|
70635
|
-
let port;
|
|
70636
|
-
if (options.port != null) {
|
|
70637
|
-
port = options.port;
|
|
70638
|
-
if (isPortInUse(config2, port)) {
|
|
70639
|
-
console.error(` Error: Port ${port} is already in use in openclaw.json.`);
|
|
70640
|
-
process.exit(1);
|
|
70641
|
-
}
|
|
70642
|
-
console.log(` Using explicit port ${port}.
|
|
70643
|
-
`);
|
|
70644
|
-
} else {
|
|
70645
|
-
port = findNextPort(config2);
|
|
70646
|
-
console.log(` Auto-assigned port ${port}.
|
|
70647
|
-
`);
|
|
70648
|
-
}
|
|
70649
|
-
console.log(" Step 3/7 \u2014 Creating agent with OpenClaw...");
|
|
70650
|
-
try {
|
|
70651
|
-
execSync(`openclaw agents add -- ${name2}`, { stdio: "pipe" });
|
|
70652
|
-
console.log(` Agent '${name2}' created.
|
|
70653
|
-
`);
|
|
70654
|
-
} catch {
|
|
70655
|
-
console.log(` Warning: 'openclaw agents add' failed \u2014 agent may already exist. Continuing.
|
|
70656
|
-
`);
|
|
70657
|
-
}
|
|
70658
|
-
console.log(" Step 4/7 \u2014 Creating directories...");
|
|
70659
|
-
mkdirSync(workspaceDir, { recursive: true });
|
|
70660
|
-
mkdirSync(dataDir2, { recursive: true });
|
|
70661
|
-
console.log(` Workspace: ${workspaceDir}`);
|
|
70662
|
-
console.log(` DataDir: ${dataDir2}
|
|
70663
|
-
`);
|
|
70664
|
-
console.log(" Step 5/7 \u2014 Writing workspace files...");
|
|
70665
|
-
const files = generateWorkspaceFiles(name2);
|
|
70666
|
-
for (const [filename, content] of Object.entries(files)) {
|
|
70667
|
-
writeFileSync(join4(workspaceDir, filename), content, "utf-8");
|
|
70668
|
-
}
|
|
70669
|
-
for (const copyFile of ["AGENTS.md", "USER.md"]) {
|
|
70670
|
-
const src = join4(templateDir, copyFile);
|
|
70671
|
-
if (existsSync(src)) {
|
|
70672
|
-
copyFileSync(src, join4(workspaceDir, copyFile));
|
|
70673
|
-
console.log(` Copied ${copyFile} from template workspace.`);
|
|
70674
|
-
}
|
|
70675
|
-
}
|
|
70676
|
-
console.log(" Workspace files written.\n");
|
|
70677
|
-
console.log(" Step 6/7 \u2014 Enrolling with AgentVault...\n");
|
|
70678
|
-
await runSetupCommand({
|
|
70679
|
-
token: token2,
|
|
70680
|
-
name: name2,
|
|
70681
|
-
apiUrl: apiUrl2,
|
|
70682
|
-
dataDir: dataDir2,
|
|
70683
|
-
accountId: name2,
|
|
70684
|
-
force
|
|
70685
|
-
});
|
|
70686
|
-
console.log("\n Step 7/7 \u2014 Patching openclaw.json...");
|
|
70687
|
-
try {
|
|
70688
|
-
const freshConfig = readOpenClawConfig(home);
|
|
70689
|
-
let patched = false;
|
|
70690
|
-
const avChannel = freshConfig?.channels?.agentvault;
|
|
70691
|
-
if (avChannel?.accounts) {
|
|
70692
|
-
const acct = avChannel.accounts[name2];
|
|
70693
|
-
if (acct) {
|
|
70694
|
-
acct.httpPort = port;
|
|
70695
|
-
patched = true;
|
|
70696
|
-
}
|
|
70697
|
-
}
|
|
70698
|
-
if (avChannel) {
|
|
70699
|
-
const bindings = avChannel.bindings;
|
|
70700
|
-
const hasWildcard = bindings?.some(
|
|
70701
|
-
(b2) => b2.match?.accountId === "*"
|
|
70702
|
-
);
|
|
70703
|
-
if (!hasWildcard) {
|
|
70704
|
-
avChannel.bindings = [{ match: { accountId: "*" } }, ...bindings ?? []];
|
|
70705
|
-
console.log(` Added wildcard binding (accountId: "*").`);
|
|
70706
|
-
}
|
|
70707
|
-
}
|
|
70708
|
-
if (patched) {
|
|
70709
|
-
writeOpenClawConfig(home, freshConfig, name2);
|
|
70710
|
-
console.log(` httpPort set to ${port}.
|
|
70711
|
-
`);
|
|
70712
|
-
} else {
|
|
70713
|
-
console.log(` Warning: Could not find account '${name2}' in channels.agentvault.accounts.`);
|
|
70714
|
-
console.log(` You may need to manually set httpPort: ${port} in openclaw.json.
|
|
70715
|
-
`);
|
|
70716
|
-
}
|
|
70717
|
-
} catch (err) {
|
|
70718
|
-
console.log(` Warning: Failed to patch openclaw.json: ${err.message}
|
|
70719
|
-
`);
|
|
70720
|
-
}
|
|
70721
|
-
console.log(" Verifying agent...");
|
|
70722
|
-
try {
|
|
70723
|
-
const http = await import("node:http");
|
|
70724
|
-
await new Promise((resolve4) => {
|
|
70725
|
-
const req = http.get(`http://127.0.0.1:${port}/status`, { timeout: 3e3 }, (res) => {
|
|
70726
|
-
console.log(` Port ${port} responded (HTTP ${res.statusCode}).`);
|
|
70727
|
-
res.resume();
|
|
70728
|
-
resolve4();
|
|
70729
|
-
});
|
|
70730
|
-
req.on("error", () => {
|
|
70731
|
-
console.log(` Port ${port} not yet responding \u2014 gateway may need a moment.`);
|
|
70732
|
-
resolve4();
|
|
70733
|
-
});
|
|
70734
|
-
req.on("timeout", () => {
|
|
70735
|
-
req.destroy();
|
|
70736
|
-
console.log(` Port ${port} timed out \u2014 check gateway logs.`);
|
|
70737
|
-
resolve4();
|
|
70738
|
-
});
|
|
70739
|
-
});
|
|
70740
|
-
} catch {
|
|
70741
|
-
console.log(" Verification skipped.");
|
|
70742
|
-
}
|
|
70743
|
-
if (process.platform === "darwin") {
|
|
70744
|
-
const { validatePlist: validatePlist2 } = await init_doctor().then(() => doctor_exports);
|
|
70745
|
-
const plistResult = validatePlist2();
|
|
70746
|
-
if (plistResult.status === "stale") {
|
|
70747
|
-
console.log(`
|
|
70748
|
-
\u26A0\uFE0F macOS LaunchAgent plist has stale paths.
|
|
70749
|
-
Run to diagnose and fix: npx @agentvault/agentvault doctor
|
|
70750
|
-
`);
|
|
70751
|
-
}
|
|
70752
|
-
}
|
|
70753
|
-
console.log(`
|
|
70754
|
-
\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550
|
|
70755
|
-
Agent '${name2}' created successfully!
|
|
70756
|
-
\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550
|
|
70757
|
-
|
|
70758
|
-
Workspace: ${workspaceDir}
|
|
70759
|
-
DataDir: ${dataDir2}
|
|
70760
|
-
HTTP Port: ${port}
|
|
70761
|
-
|
|
70762
|
-
Next steps:
|
|
70763
|
-
1. Edit ${workspaceDir}/SOUL.md \u2014 give ${name2} a personality
|
|
70764
|
-
2. Edit ${workspaceDir}/IDENTITY.md \u2014 set name, emoji, vibe
|
|
70765
|
-
3. Approve the agent in the AgentVault app
|
|
70766
|
-
`);
|
|
70767
|
-
}
|
|
70768
|
-
var init_create_agent = __esm({
|
|
70769
|
-
async "src/create-agent.ts"() {
|
|
70770
|
-
"use strict";
|
|
70771
|
-
await init_setup();
|
|
70772
|
-
}
|
|
70773
|
-
});
|
|
70774
|
-
|
|
70775
70525
|
// src/doctor.ts
|
|
70776
70526
|
var doctor_exports = {};
|
|
70777
70527
|
__export(doctor_exports, {
|
|
@@ -70789,13 +70539,13 @@ __export(doctor_exports, {
|
|
|
70789
70539
|
runDoctorCommand: () => runDoctorCommand,
|
|
70790
70540
|
validatePlist: () => validatePlist
|
|
70791
70541
|
});
|
|
70792
|
-
import { execSync
|
|
70793
|
-
import { existsSync
|
|
70794
|
-
import { join as
|
|
70542
|
+
import { execSync } from "node:child_process";
|
|
70543
|
+
import { existsSync, readFileSync, writeFileSync, chmodSync } from "node:fs";
|
|
70544
|
+
import { join as join4 } from "node:path";
|
|
70795
70545
|
import { createInterface } from "node:readline";
|
|
70796
70546
|
function checkOpenClawInstalled() {
|
|
70797
70547
|
try {
|
|
70798
|
-
const out =
|
|
70548
|
+
const out = execSync("openclaw --version", { stdio: "pipe", timeout: 1e4 });
|
|
70799
70549
|
const version2 = out.toString().trim();
|
|
70800
70550
|
return { name: "OpenClaw installed", status: "pass", message: version2 };
|
|
70801
70551
|
} catch {
|
|
@@ -70807,8 +70557,8 @@ function checkOpenClawInstalled() {
|
|
|
70807
70557
|
}
|
|
70808
70558
|
}
|
|
70809
70559
|
function checkConfigExists(home) {
|
|
70810
|
-
const configPath =
|
|
70811
|
-
if (!
|
|
70560
|
+
const configPath = join4(home, "openclaw.json");
|
|
70561
|
+
if (!existsSync(configPath)) {
|
|
70812
70562
|
return {
|
|
70813
70563
|
name: "Config exists",
|
|
70814
70564
|
status: "fail",
|
|
@@ -70816,7 +70566,7 @@ function checkConfigExists(home) {
|
|
|
70816
70566
|
};
|
|
70817
70567
|
}
|
|
70818
70568
|
try {
|
|
70819
|
-
JSON.parse(
|
|
70569
|
+
JSON.parse(readFileSync(configPath, "utf-8"));
|
|
70820
70570
|
return { name: "Config exists", status: "pass", message: configPath };
|
|
70821
70571
|
} catch {
|
|
70822
70572
|
return {
|
|
@@ -70892,7 +70642,7 @@ function checkPlist() {
|
|
|
70892
70642
|
}
|
|
70893
70643
|
function checkGatewayPort() {
|
|
70894
70644
|
try {
|
|
70895
|
-
|
|
70645
|
+
execSync("curl -sf --max-time 3 http://127.0.0.1:18789/", { stdio: "pipe" });
|
|
70896
70646
|
return { name: "Gateway port (18789)", status: "pass", message: "Responding" };
|
|
70897
70647
|
} catch {
|
|
70898
70648
|
return {
|
|
@@ -70914,12 +70664,12 @@ function checkAgentDataDirs(config2) {
|
|
|
70914
70664
|
}
|
|
70915
70665
|
const checkDir = (label, dataDir2) => {
|
|
70916
70666
|
const resolved = dataDir2.replace(/^~/, home);
|
|
70917
|
-
if (!
|
|
70667
|
+
if (!existsSync(resolved)) {
|
|
70918
70668
|
warnings.push(`${label}: dir missing (${resolved})`);
|
|
70919
70669
|
return;
|
|
70920
70670
|
}
|
|
70921
|
-
const statePath2 =
|
|
70922
|
-
if (!
|
|
70671
|
+
const statePath2 = join4(resolved, "agentvault.json");
|
|
70672
|
+
if (!existsSync(statePath2)) {
|
|
70923
70673
|
warnings.push(`${label}: no agentvault.json`);
|
|
70924
70674
|
}
|
|
70925
70675
|
};
|
|
@@ -70937,12 +70687,12 @@ function checkAgentDataDirs(config2) {
|
|
|
70937
70687
|
}
|
|
70938
70688
|
function checkPm2Status() {
|
|
70939
70689
|
try {
|
|
70940
|
-
|
|
70690
|
+
execSync("pm2 --version", { stdio: "pipe", timeout: 5e3 });
|
|
70941
70691
|
} catch {
|
|
70942
70692
|
return { name: "pm2 status", status: "skip", message: "pm2 not installed" };
|
|
70943
70693
|
}
|
|
70944
70694
|
try {
|
|
70945
|
-
const info =
|
|
70695
|
+
const info = execSync("pm2 describe openclaw-gateway", { stdio: "pipe", timeout: 5e3 });
|
|
70946
70696
|
const out = info.toString();
|
|
70947
70697
|
if (out.includes("online")) {
|
|
70948
70698
|
return { name: "pm2 status", status: "pass", message: "openclaw-gateway: online" };
|
|
@@ -70957,22 +70707,22 @@ function checkPm2Status() {
|
|
|
70957
70707
|
}
|
|
70958
70708
|
function plistPath() {
|
|
70959
70709
|
const home = process.env.HOME ?? "";
|
|
70960
|
-
return
|
|
70710
|
+
return join4(home, "Library", "LaunchAgents", PLIST_FILENAME);
|
|
70961
70711
|
}
|
|
70962
70712
|
function parsePlist(plistFile) {
|
|
70963
|
-
if (!
|
|
70713
|
+
if (!existsSync(plistFile)) return null;
|
|
70964
70714
|
try {
|
|
70965
|
-
const json2 =
|
|
70715
|
+
const json2 = execSync(`plutil -convert json -o - "${plistFile}"`, {
|
|
70966
70716
|
stdio: "pipe",
|
|
70967
70717
|
timeout: 5e3
|
|
70968
70718
|
}).toString();
|
|
70969
70719
|
const parsed = JSON.parse(json2);
|
|
70970
70720
|
const programArgs = parsed.ProgramArguments ?? [];
|
|
70971
70721
|
const stalePaths = [];
|
|
70972
|
-
const wrapperPath =
|
|
70722
|
+
const wrapperPath = join4(process.env.HOME ?? "", ".openclaw", WRAPPER_SCRIPT_NAME);
|
|
70973
70723
|
for (const arg of programArgs) {
|
|
70974
70724
|
if (arg.startsWith("/") && arg !== "/bin/bash" && arg !== wrapperPath) {
|
|
70975
|
-
if (!
|
|
70725
|
+
if (!existsSync(arg)) {
|
|
70976
70726
|
stalePaths.push(arg);
|
|
70977
70727
|
}
|
|
70978
70728
|
}
|
|
@@ -70987,7 +70737,7 @@ function validatePlist() {
|
|
|
70987
70737
|
return { status: "skip" };
|
|
70988
70738
|
}
|
|
70989
70739
|
const path = plistPath();
|
|
70990
|
-
if (!
|
|
70740
|
+
if (!existsSync(path)) {
|
|
70991
70741
|
return { status: "missing", plistPath: path };
|
|
70992
70742
|
}
|
|
70993
70743
|
const info = parsePlist(path);
|
|
@@ -70995,7 +70745,7 @@ function validatePlist() {
|
|
|
70995
70745
|
return { status: "missing", plistPath: path };
|
|
70996
70746
|
}
|
|
70997
70747
|
const home = process.env.HOME ?? "";
|
|
70998
|
-
const wrapperPath =
|
|
70748
|
+
const wrapperPath = join4(home, ".openclaw", WRAPPER_SCRIPT_NAME);
|
|
70999
70749
|
if (info.programArgs.includes(wrapperPath)) {
|
|
71000
70750
|
return { status: "already-fixed", plistPath: path };
|
|
71001
70751
|
}
|
|
@@ -71006,14 +70756,14 @@ function validatePlist() {
|
|
|
71006
70756
|
}
|
|
71007
70757
|
function applyPlistFix(info) {
|
|
71008
70758
|
const home = process.env.HOME ?? "";
|
|
71009
|
-
const openclawDir =
|
|
71010
|
-
const wrapperPath =
|
|
70759
|
+
const openclawDir = join4(home, ".openclaw");
|
|
70760
|
+
const wrapperPath = join4(openclawDir, WRAPPER_SCRIPT_NAME);
|
|
71011
70761
|
const wrapperContent = `#!/bin/bash
|
|
71012
70762
|
export PATH="$HOME/.local/bin:$HOME/.pnpm/bin:$HOME/Library/pnpm/bin:$HOME/Library/pnpm:/opt/homebrew/bin:/usr/local/bin:$PATH"
|
|
71013
70763
|
exec "$(which openclaw)" gateway start "$@"
|
|
71014
70764
|
`;
|
|
71015
70765
|
try {
|
|
71016
|
-
|
|
70766
|
+
writeFileSync(wrapperPath, wrapperContent, "utf-8");
|
|
71017
70767
|
chmodSync(wrapperPath, 493);
|
|
71018
70768
|
console.log(` Created wrapper: ${wrapperPath}`);
|
|
71019
70769
|
} catch (err) {
|
|
@@ -71023,16 +70773,16 @@ exec "$(which openclaw)" gateway start "$@"
|
|
|
71023
70773
|
const plistBuddy = "/usr/libexec/PlistBuddy";
|
|
71024
70774
|
const plist = info.plistPath;
|
|
71025
70775
|
try {
|
|
71026
|
-
|
|
70776
|
+
execSync(`${plistBuddy} -c "Set :ProgramArguments:0 /bin/bash" "${plist}"`, { stdio: "pipe" });
|
|
71027
70777
|
try {
|
|
71028
|
-
|
|
70778
|
+
execSync(`${plistBuddy} -c "Set :ProgramArguments:1 ${wrapperPath}" "${plist}"`, { stdio: "pipe" });
|
|
71029
70779
|
} catch {
|
|
71030
|
-
|
|
70780
|
+
execSync(`${plistBuddy} -c "Add :ProgramArguments:1 string ${wrapperPath}" "${plist}"`, { stdio: "pipe" });
|
|
71031
70781
|
}
|
|
71032
70782
|
let argCount = info.programArgs.length;
|
|
71033
70783
|
for (let i2 = argCount - 1; i2 >= 2; i2--) {
|
|
71034
70784
|
try {
|
|
71035
|
-
|
|
70785
|
+
execSync(`${plistBuddy} -c "Delete :ProgramArguments:${i2}" "${plist}"`, { stdio: "pipe" });
|
|
71036
70786
|
} catch {
|
|
71037
70787
|
}
|
|
71038
70788
|
}
|
|
@@ -71042,11 +70792,11 @@ exec "$(which openclaw)" gateway start "$@"
|
|
|
71042
70792
|
return false;
|
|
71043
70793
|
}
|
|
71044
70794
|
try {
|
|
71045
|
-
|
|
70795
|
+
execSync(`launchctl unload "${plist}"`, { stdio: "pipe" });
|
|
71046
70796
|
} catch {
|
|
71047
70797
|
}
|
|
71048
70798
|
try {
|
|
71049
|
-
|
|
70799
|
+
execSync(`launchctl load "${plist}"`, { stdio: "pipe" });
|
|
71050
70800
|
console.log(" Reloaded LaunchAgent.");
|
|
71051
70801
|
} catch (err) {
|
|
71052
70802
|
console.error(` Failed to reload LaunchAgent: ${err.message}`);
|
|
@@ -71151,11 +70901,304 @@ var init_doctor = __esm({
|
|
|
71151
70901
|
}
|
|
71152
70902
|
});
|
|
71153
70903
|
|
|
71154
|
-
// src/
|
|
71155
|
-
var
|
|
71156
|
-
__export(
|
|
71157
|
-
|
|
71158
|
-
|
|
70904
|
+
// src/create-agent.ts
|
|
70905
|
+
var create_agent_exports = {};
|
|
70906
|
+
__export(create_agent_exports, {
|
|
70907
|
+
findNextPort: () => findNextPort,
|
|
70908
|
+
generateWorkspaceFiles: () => generateWorkspaceFiles,
|
|
70909
|
+
openclawHome: () => openclawHome,
|
|
70910
|
+
readOpenClawConfig: () => readOpenClawConfig,
|
|
70911
|
+
runCreateCommand: () => runCreateCommand
|
|
70912
|
+
});
|
|
70913
|
+
import { execSync as execSync2 } from "node:child_process";
|
|
70914
|
+
import { existsSync as existsSync2, mkdirSync, readFileSync as readFileSync2, writeFileSync as writeFileSync2, copyFileSync } from "node:fs";
|
|
70915
|
+
import { join as join5 } from "node:path";
|
|
70916
|
+
function openclawHome() {
|
|
70917
|
+
const home = process.env.HOME ?? process.env.USERPROFILE ?? "";
|
|
70918
|
+
return join5(home, ".openclaw");
|
|
70919
|
+
}
|
|
70920
|
+
function readOpenClawConfig(home) {
|
|
70921
|
+
const configPath = join5(home, "openclaw.json");
|
|
70922
|
+
const raw = readFileSync2(configPath, "utf-8");
|
|
70923
|
+
return JSON.parse(raw);
|
|
70924
|
+
}
|
|
70925
|
+
function writeOpenClawConfig(home, config2, backupSuffix) {
|
|
70926
|
+
const configPath = join5(home, "openclaw.json");
|
|
70927
|
+
const backupPath = `${configPath}.bak.pre-${backupSuffix}`;
|
|
70928
|
+
copyFileSync(configPath, backupPath);
|
|
70929
|
+
writeFileSync2(configPath, JSON.stringify(config2, null, 2) + "\n", "utf-8");
|
|
70930
|
+
}
|
|
70931
|
+
function collectPorts(config2) {
|
|
70932
|
+
const ports = [];
|
|
70933
|
+
const accounts = config2?.channels?.agentvault?.accounts;
|
|
70934
|
+
if (accounts && typeof accounts === "object") {
|
|
70935
|
+
for (const acct of Object.values(accounts)) {
|
|
70936
|
+
if (typeof acct.httpPort === "number") {
|
|
70937
|
+
ports.push(acct.httpPort);
|
|
70938
|
+
}
|
|
70939
|
+
}
|
|
70940
|
+
}
|
|
70941
|
+
return ports;
|
|
70942
|
+
}
|
|
70943
|
+
function findNextPort(config2, startPort = 18800) {
|
|
70944
|
+
const ports = collectPorts(config2);
|
|
70945
|
+
if (ports.length === 0) return startPort;
|
|
70946
|
+
return Math.max(...ports, startPort - 1) + 1;
|
|
70947
|
+
}
|
|
70948
|
+
function isPortInUse(config2, port) {
|
|
70949
|
+
return collectPorts(config2).includes(port);
|
|
70950
|
+
}
|
|
70951
|
+
function generateWorkspaceFiles(name2) {
|
|
70952
|
+
const displayName = name2.charAt(0).toUpperCase() + name2.slice(1).toLowerCase();
|
|
70953
|
+
return {
|
|
70954
|
+
"IDENTITY.md": `# IDENTITY.md - Who Am I?
|
|
70955
|
+
|
|
70956
|
+
- **Name:** ${displayName}
|
|
70957
|
+
- **Creature:** AI assistant \u2014 a capable peer agent in the AgentVault network
|
|
70958
|
+
- **Vibe:** Direct, competent, focused on their specialty domain
|
|
70959
|
+
- **Emoji:** (placeholder \u2014 update to something fitting)
|
|
70960
|
+
- **Avatar:** _(none set yet)_
|
|
70961
|
+
|
|
70962
|
+
> TODO: Customize this file to give ${name2} a distinct identity.
|
|
70963
|
+
`,
|
|
70964
|
+
"SOUL.md": `# SOUL.md - Who You Are
|
|
70965
|
+
|
|
70966
|
+
> TODO: Define ${name2}'s personality, tone, and behavioral rules.
|
|
70967
|
+
> Copy and adapt from ~/.openclaw/workspace/SOUL.md as a starting point.
|
|
70968
|
+
|
|
70969
|
+
## Core Truths
|
|
70970
|
+
|
|
70971
|
+
- Be genuinely helpful, not performatively helpful.
|
|
70972
|
+
- Have opinions. Be resourceful before asking.
|
|
70973
|
+
- Earn trust through competence.
|
|
70974
|
+
|
|
70975
|
+
## Channel Reply Rules
|
|
70976
|
+
|
|
70977
|
+
- Never include reasoning or internal logic in visible replies.
|
|
70978
|
+
- No narrating your approach before or after tool calls.
|
|
70979
|
+
- Just deliver the answer \u2014 clean and direct.
|
|
70980
|
+
|
|
70981
|
+
## Vibe
|
|
70982
|
+
|
|
70983
|
+
_(Define ${name2}'s specific personality here.)_
|
|
70984
|
+
`,
|
|
70985
|
+
"HEARTBEAT.md": `# Heartbeat
|
|
70986
|
+
|
|
70987
|
+
- Stay available. If nothing needs attention, reply HEARTBEAT_OK.
|
|
70988
|
+
- **Heartbeat replies are INTERNAL ONLY.** Reply with ONLY \`HEARTBEAT_OK\` when nothing needs attention.
|
|
70989
|
+
- If something genuinely urgent needs attention, send it proactively FIRST, THEN reply HEARTBEAT_OK.
|
|
70990
|
+
`,
|
|
70991
|
+
"MEMORY.md": `# MEMORY.md - Long-Term Memory
|
|
70992
|
+
|
|
70993
|
+
_(Empty \u2014 ${name2} starts with a clean memory. Update as the agent learns.)_
|
|
70994
|
+
`
|
|
70995
|
+
};
|
|
70996
|
+
}
|
|
70997
|
+
async function runCreateCommand(options) {
|
|
70998
|
+
const { name: name2, token: token2, apiUrl: apiUrl2, force } = options;
|
|
70999
|
+
const home = openclawHome();
|
|
71000
|
+
const configPath = join5(home, "openclaw.json");
|
|
71001
|
+
const workspaceDir = join5(home, `workspace-${name2}`);
|
|
71002
|
+
const dataDir2 = join5(home, "agents", name2, "agentvault-data");
|
|
71003
|
+
const templateDir = join5(home, "workspace");
|
|
71004
|
+
console.log(`
|
|
71005
|
+
\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557
|
|
71006
|
+
\u2551 AgentVault \u2014 Create New Agent \u2551
|
|
71007
|
+
\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D
|
|
71008
|
+
`);
|
|
71009
|
+
console.log(" Step 1/7 \u2014 Preflight checks...");
|
|
71010
|
+
try {
|
|
71011
|
+
execSync2("openclaw --version", { stdio: "pipe" });
|
|
71012
|
+
} catch {
|
|
71013
|
+
console.error(" Error: 'openclaw' not found in PATH. Is OpenClaw installed?");
|
|
71014
|
+
process.exit(1);
|
|
71015
|
+
}
|
|
71016
|
+
if (!existsSync2(configPath)) {
|
|
71017
|
+
console.error(` Error: openclaw.json not found at ${configPath}`);
|
|
71018
|
+
process.exit(1);
|
|
71019
|
+
}
|
|
71020
|
+
console.log(" Preflight passed.\n");
|
|
71021
|
+
console.log(" Step 2/7 \u2014 Detecting port...");
|
|
71022
|
+
const config2 = readOpenClawConfig(home);
|
|
71023
|
+
let port;
|
|
71024
|
+
if (options.port != null) {
|
|
71025
|
+
port = options.port;
|
|
71026
|
+
if (isPortInUse(config2, port)) {
|
|
71027
|
+
console.error(` Error: Port ${port} is already in use in openclaw.json.`);
|
|
71028
|
+
process.exit(1);
|
|
71029
|
+
}
|
|
71030
|
+
console.log(` Using explicit port ${port}.
|
|
71031
|
+
`);
|
|
71032
|
+
} else {
|
|
71033
|
+
port = findNextPort(config2);
|
|
71034
|
+
console.log(` Auto-assigned port ${port}.
|
|
71035
|
+
`);
|
|
71036
|
+
}
|
|
71037
|
+
console.log(" Step 3/7 \u2014 Creating agent with OpenClaw...");
|
|
71038
|
+
try {
|
|
71039
|
+
execSync2(`openclaw agents add -- ${name2}`, { stdio: "pipe" });
|
|
71040
|
+
console.log(` Agent '${name2}' created.
|
|
71041
|
+
`);
|
|
71042
|
+
} catch {
|
|
71043
|
+
console.log(` Warning: 'openclaw agents add' failed \u2014 agent may already exist. Continuing.
|
|
71044
|
+
`);
|
|
71045
|
+
}
|
|
71046
|
+
console.log(" Step 4/7 \u2014 Creating directories...");
|
|
71047
|
+
mkdirSync(workspaceDir, { recursive: true });
|
|
71048
|
+
mkdirSync(dataDir2, { recursive: true });
|
|
71049
|
+
console.log(` Workspace: ${workspaceDir}`);
|
|
71050
|
+
console.log(` DataDir: ${dataDir2}
|
|
71051
|
+
`);
|
|
71052
|
+
console.log(" Step 5/7 \u2014 Writing workspace files...");
|
|
71053
|
+
const files = generateWorkspaceFiles(name2);
|
|
71054
|
+
for (const [filename, content] of Object.entries(files)) {
|
|
71055
|
+
writeFileSync2(join5(workspaceDir, filename), content, "utf-8");
|
|
71056
|
+
}
|
|
71057
|
+
for (const copyFile of ["AGENTS.md", "USER.md"]) {
|
|
71058
|
+
const src = join5(templateDir, copyFile);
|
|
71059
|
+
if (existsSync2(src)) {
|
|
71060
|
+
copyFileSync(src, join5(workspaceDir, copyFile));
|
|
71061
|
+
console.log(` Copied ${copyFile} from template workspace.`);
|
|
71062
|
+
}
|
|
71063
|
+
}
|
|
71064
|
+
console.log(" Workspace files written.\n");
|
|
71065
|
+
console.log(" Step 6/7 \u2014 Enrolling with AgentVault...\n");
|
|
71066
|
+
await runSetupCommand({
|
|
71067
|
+
token: token2,
|
|
71068
|
+
name: name2,
|
|
71069
|
+
apiUrl: apiUrl2,
|
|
71070
|
+
dataDir: dataDir2,
|
|
71071
|
+
accountId: name2,
|
|
71072
|
+
force
|
|
71073
|
+
});
|
|
71074
|
+
console.log("\n Step 7/7 \u2014 Patching openclaw.json...");
|
|
71075
|
+
try {
|
|
71076
|
+
const freshConfig = readOpenClawConfig(home);
|
|
71077
|
+
let patched = false;
|
|
71078
|
+
const avChannel = freshConfig?.channels?.agentvault;
|
|
71079
|
+
if (avChannel?.accounts) {
|
|
71080
|
+
const acct = avChannel.accounts[name2];
|
|
71081
|
+
if (acct) {
|
|
71082
|
+
acct.httpPort = port;
|
|
71083
|
+
patched = true;
|
|
71084
|
+
}
|
|
71085
|
+
}
|
|
71086
|
+
if (avChannel) {
|
|
71087
|
+
const channelBindings = avChannel.bindings;
|
|
71088
|
+
const hasAccountBinding = channelBindings?.some(
|
|
71089
|
+
(b2) => b2.match?.accountId === name2
|
|
71090
|
+
);
|
|
71091
|
+
if (!hasAccountBinding) {
|
|
71092
|
+
const arr = channelBindings ?? [];
|
|
71093
|
+
const wildcardIdx = arr.findIndex((b2) => b2.match?.accountId === "*");
|
|
71094
|
+
const entry = { match: { accountId: name2 } };
|
|
71095
|
+
if (wildcardIdx >= 0) {
|
|
71096
|
+
arr.splice(wildcardIdx, 0, entry);
|
|
71097
|
+
} else {
|
|
71098
|
+
arr.push(entry);
|
|
71099
|
+
}
|
|
71100
|
+
avChannel.bindings = arr;
|
|
71101
|
+
patched = true;
|
|
71102
|
+
console.log(` Added channel binding for account "${name2}".`);
|
|
71103
|
+
}
|
|
71104
|
+
const hasWildcard = avChannel.bindings.some(
|
|
71105
|
+
(b2) => b2.match?.accountId === "*"
|
|
71106
|
+
);
|
|
71107
|
+
if (!hasWildcard) {
|
|
71108
|
+
avChannel.bindings.push({ match: { accountId: "*" } });
|
|
71109
|
+
patched = true;
|
|
71110
|
+
console.log(` Added wildcard channel binding (accountId: "*").`);
|
|
71111
|
+
}
|
|
71112
|
+
}
|
|
71113
|
+
const topBindings = freshConfig.bindings;
|
|
71114
|
+
const hasTopBinding = topBindings?.some(
|
|
71115
|
+
(b2) => b2.agentId === name2 && b2.match?.accountId === name2
|
|
71116
|
+
);
|
|
71117
|
+
if (!hasTopBinding) {
|
|
71118
|
+
const entry = {
|
|
71119
|
+
agentId: name2,
|
|
71120
|
+
match: { channel: "agentvault", accountId: name2 }
|
|
71121
|
+
};
|
|
71122
|
+
if (topBindings) {
|
|
71123
|
+
topBindings.push(entry);
|
|
71124
|
+
} else {
|
|
71125
|
+
freshConfig.bindings = [entry];
|
|
71126
|
+
}
|
|
71127
|
+
patched = true;
|
|
71128
|
+
console.log(` Added top-level binding: ${name2} \u2192 agentvault:${name2}.`);
|
|
71129
|
+
}
|
|
71130
|
+
if (patched) {
|
|
71131
|
+
writeOpenClawConfig(home, freshConfig, name2);
|
|
71132
|
+
console.log(` httpPort set to ${port}.
|
|
71133
|
+
`);
|
|
71134
|
+
} else {
|
|
71135
|
+
console.log(` Warning: Could not find account '${name2}' in channels.agentvault.accounts.`);
|
|
71136
|
+
console.log(` You may need to manually set httpPort: ${port} in openclaw.json.
|
|
71137
|
+
`);
|
|
71138
|
+
}
|
|
71139
|
+
} catch (err) {
|
|
71140
|
+
console.log(` Warning: Failed to patch openclaw.json: ${err.message}
|
|
71141
|
+
`);
|
|
71142
|
+
}
|
|
71143
|
+
console.log(" Verifying agent...");
|
|
71144
|
+
try {
|
|
71145
|
+
const http = await import("node:http");
|
|
71146
|
+
await new Promise((resolve4) => {
|
|
71147
|
+
const req = http.get(`http://127.0.0.1:${port}/status`, { timeout: 3e3 }, (res) => {
|
|
71148
|
+
console.log(` Port ${port} responded (HTTP ${res.statusCode}).`);
|
|
71149
|
+
res.resume();
|
|
71150
|
+
resolve4();
|
|
71151
|
+
});
|
|
71152
|
+
req.on("error", () => {
|
|
71153
|
+
console.log(` Port ${port} not yet responding \u2014 gateway may need a moment.`);
|
|
71154
|
+
resolve4();
|
|
71155
|
+
});
|
|
71156
|
+
req.on("timeout", () => {
|
|
71157
|
+
req.destroy();
|
|
71158
|
+
console.log(` Port ${port} timed out \u2014 check gateway logs.`);
|
|
71159
|
+
resolve4();
|
|
71160
|
+
});
|
|
71161
|
+
});
|
|
71162
|
+
} catch {
|
|
71163
|
+
console.log(" Verification skipped.");
|
|
71164
|
+
}
|
|
71165
|
+
if (process.platform === "darwin") {
|
|
71166
|
+
const { validatePlist: validatePlist2 } = await init_doctor().then(() => doctor_exports);
|
|
71167
|
+
const plistResult = validatePlist2();
|
|
71168
|
+
if (plistResult.status === "stale") {
|
|
71169
|
+
console.log(`
|
|
71170
|
+
\u26A0\uFE0F macOS LaunchAgent plist has stale paths.
|
|
71171
|
+
Run to diagnose and fix: npx @agentvault/agentvault doctor
|
|
71172
|
+
`);
|
|
71173
|
+
}
|
|
71174
|
+
}
|
|
71175
|
+
console.log(`
|
|
71176
|
+
\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550
|
|
71177
|
+
Agent '${name2}' created successfully!
|
|
71178
|
+
\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550
|
|
71179
|
+
|
|
71180
|
+
Workspace: ${workspaceDir}
|
|
71181
|
+
DataDir: ${dataDir2}
|
|
71182
|
+
HTTP Port: ${port}
|
|
71183
|
+
|
|
71184
|
+
Next steps:
|
|
71185
|
+
1. Edit ${workspaceDir}/SOUL.md \u2014 give ${name2} a personality
|
|
71186
|
+
2. Edit ${workspaceDir}/IDENTITY.md \u2014 set name, emoji, vibe
|
|
71187
|
+
3. Approve the agent in the AgentVault app
|
|
71188
|
+
`);
|
|
71189
|
+
}
|
|
71190
|
+
var init_create_agent = __esm({
|
|
71191
|
+
async "src/create-agent.ts"() {
|
|
71192
|
+
"use strict";
|
|
71193
|
+
await init_setup();
|
|
71194
|
+
}
|
|
71195
|
+
});
|
|
71196
|
+
|
|
71197
|
+
// src/setup.ts
|
|
71198
|
+
var setup_exports = {};
|
|
71199
|
+
__export(setup_exports, {
|
|
71200
|
+
configurePm2: () => configurePm2,
|
|
71201
|
+
installPlugin: () => installPlugin,
|
|
71159
71202
|
runSetupCommand: () => runSetupCommand
|
|
71160
71203
|
});
|
|
71161
71204
|
import { execSync as execSync3, spawnSync } from "node:child_process";
|
|
@@ -71329,27 +71372,53 @@ async function runSetupCommand(options) {
|
|
|
71329
71372
|
break;
|
|
71330
71373
|
}
|
|
71331
71374
|
}
|
|
71332
|
-
if (configPatched) {
|
|
71375
|
+
if (configPatched && options.accountId) {
|
|
71333
71376
|
try {
|
|
71334
|
-
const
|
|
71335
|
-
|
|
71336
|
-
|
|
71337
|
-
|
|
71338
|
-
const
|
|
71339
|
-
|
|
71340
|
-
|
|
71341
|
-
|
|
71342
|
-
|
|
71343
|
-
|
|
71377
|
+
const { readOpenClawConfig: readOpenClawConfig2 } = await init_create_agent().then(() => create_agent_exports);
|
|
71378
|
+
const home2 = process.env.HOME ?? "";
|
|
71379
|
+
const ocHome = `${home2}/.openclaw`;
|
|
71380
|
+
const fs = await import("node:fs");
|
|
71381
|
+
const path = await import("node:path");
|
|
71382
|
+
const configPath = path.join(ocHome, "openclaw.json");
|
|
71383
|
+
if (fs.existsSync(configPath)) {
|
|
71384
|
+
const raw = fs.readFileSync(configPath, "utf-8");
|
|
71385
|
+
const cfg = JSON.parse(raw);
|
|
71386
|
+
let changed = false;
|
|
71387
|
+
const avChannel = cfg?.channels?.agentvault;
|
|
71388
|
+
if (avChannel) {
|
|
71389
|
+
const channelBindings = avChannel.bindings ?? [];
|
|
71390
|
+
if (!channelBindings.some((b2) => b2.match?.accountId === options.accountId)) {
|
|
71391
|
+
const wildcardIdx = channelBindings.findIndex((b2) => b2.match?.accountId === "*");
|
|
71392
|
+
const entry = { match: { accountId: options.accountId } };
|
|
71393
|
+
if (wildcardIdx >= 0) {
|
|
71394
|
+
channelBindings.splice(wildcardIdx, 0, entry);
|
|
71395
|
+
} else {
|
|
71396
|
+
channelBindings.push(entry);
|
|
71397
|
+
}
|
|
71398
|
+
avChannel.bindings = channelBindings;
|
|
71399
|
+
changed = true;
|
|
71400
|
+
}
|
|
71401
|
+
if (!channelBindings.some((b2) => b2.match?.accountId === "*")) {
|
|
71402
|
+
channelBindings.push({ match: { accountId: "*" } });
|
|
71403
|
+
changed = true;
|
|
71404
|
+
}
|
|
71405
|
+
}
|
|
71406
|
+
const topBindings = cfg.bindings ?? [];
|
|
71407
|
+
if (!topBindings.some((b2) => b2.agentId === options.accountId && b2.match?.accountId === options.accountId)) {
|
|
71408
|
+
topBindings.push({
|
|
71409
|
+
agentId: options.accountId,
|
|
71410
|
+
match: { channel: "agentvault", accountId: options.accountId }
|
|
71411
|
+
});
|
|
71412
|
+
cfg.bindings = topBindings;
|
|
71413
|
+
changed = true;
|
|
71414
|
+
}
|
|
71415
|
+
if (changed) {
|
|
71416
|
+
const backupPath = `${configPath}.bak.pre-setup-${options.accountId}`;
|
|
71417
|
+
fs.copyFileSync(configPath, backupPath);
|
|
71418
|
+
fs.writeFileSync(configPath, JSON.stringify(cfg, null, 2) + "\n", "utf-8");
|
|
71419
|
+
}
|
|
71344
71420
|
}
|
|
71345
71421
|
} catch {
|
|
71346
|
-
try {
|
|
71347
|
-
execSync3(
|
|
71348
|
-
`openclaw config set channels.agentvault.bindings '[{"match":{"accountId":"*"}}]'`,
|
|
71349
|
-
{ stdio: "pipe", env }
|
|
71350
|
-
);
|
|
71351
|
-
} catch {
|
|
71352
|
-
}
|
|
71353
71422
|
}
|
|
71354
71423
|
}
|
|
71355
71424
|
if (configPatched) {
|