hovclaw 0.1.2 → 0.1.3
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/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<h1 align="center">HOVClaw</h1>
|
|
2
2
|
|
|
3
3
|
<p align="center">
|
|
4
|
-
<strong>Lean self-hosted AI agent gateway
|
|
4
|
+
<strong>Lean self-hosted AI agent gateway</strong>
|
|
5
5
|
</p>
|
|
6
6
|
|
|
7
7
|
<p align="center">
|
|
@@ -20,7 +20,6 @@ HOVClaw is built on a simple principle: **run your own AI agent infrastructure,
|
|
|
20
20
|
|
|
21
21
|
- **Self-hosted first** - Everything runs on your machine, no cloud dependency
|
|
22
22
|
- **Channel-native** - Talk to your agent via Telegram or Discord, not a custom app
|
|
23
|
-
- **OpenClaw-compatible** - Mirror config to `~/.openclaw` for ClawHub discovery and tooling interop
|
|
24
23
|
- **Gateway-first control** - WebSocket protocol v3 for programmatic access, with a built-in web UI for quick ops
|
|
25
24
|
|
|
26
25
|
## Features
|
|
@@ -59,12 +58,6 @@ HOVClaw is built on a simple principle: **run your own AI agent infrastructure,
|
|
|
59
58
|
- **Channel notifications** - Scheduled job results delivered to Telegram or Discord
|
|
60
59
|
- **Concurrent execution** - Configurable max concurrent jobs
|
|
61
60
|
|
|
62
|
-
### OpenClaw Compatibility
|
|
63
|
-
|
|
64
|
-
- **Mirror strategy** - HOVClaw is source of truth; mirror files written to `~/.openclaw`
|
|
65
|
-
- **ClawHub discovery** - `~/.openclaw/openclaw.json` + `~/.openclaw/skills` symlink
|
|
66
|
-
- **Compat CLI** - `hovclaw compat status --sync` to verify mirror state
|
|
67
|
-
|
|
68
61
|
## Installation
|
|
69
62
|
|
|
70
63
|
### Prerequisites
|
|
@@ -252,8 +245,6 @@ hovclaw gateway open-ui
|
|
|
252
245
|
# Daemon
|
|
253
246
|
hovclaw daemon install|uninstall|start|stop|restart|status|logs
|
|
254
247
|
|
|
255
|
-
# Compatibility
|
|
256
|
-
hovclaw compat status [--sync] [--json]
|
|
257
248
|
```
|
|
258
249
|
|
|
259
250
|
## Gateway Methods (v3)
|
|
@@ -148,7 +148,7 @@ function runDoctorChecks(options, env = process.env) {
|
|
|
148
148
|
} else addFinding(findings, "telegram-webhook-secret", "fail", "Telegram webhook secret missing", `Accounts: ${webhookAccountsMissingSecret.join(", ")}`);
|
|
149
149
|
else addFinding(findings, "telegram-webhook-secret", "pass", "Telegram webhook secret policy", "OK");
|
|
150
150
|
}
|
|
151
|
-
if (!loadedConfig.gateway.enabled) addFinding(findings, "gateway-enabled", "warn", "Gateway is disabled", "Enable gateway for
|
|
151
|
+
if (!loadedConfig.gateway.enabled) addFinding(findings, "gateway-enabled", "warn", "Gateway is disabled", "Enable gateway for gateway RPC and built-in web UI access.");
|
|
152
152
|
else addFinding(findings, "gateway-enabled", "pass", "Gateway enabled", "OK");
|
|
153
153
|
if (loadedConfig.gateway.auth.allowUnauthenticated) addFinding(findings, "gateway-auth-mode", "warn", "Gateway unauthenticated mode is enabled", "Set gateway.auth.allowUnauthenticated=false for secure deployments.");
|
|
154
154
|
else if (!loadedConfig.gateway.auth.token.trim() && !loadedConfig.gateway.auth.password.trim()) if (options.repair) {
|
package/dist/hovclaw.js
CHANGED
|
@@ -4,11 +4,11 @@ import path from "node:path";
|
|
|
4
4
|
import { fileURLToPath } from "node:url";
|
|
5
5
|
import { log } from "@clack/prompts";
|
|
6
6
|
import { Command } from "commander";
|
|
7
|
+
import crypto, { randomUUID, timingSafeEqual } from "node:crypto";
|
|
8
|
+
import WebSocket from "ws";
|
|
7
9
|
import os from "node:os";
|
|
8
10
|
import dotenv from "dotenv";
|
|
9
11
|
import { z } from "zod";
|
|
10
|
-
import crypto, { randomUUID, timingSafeEqual } from "node:crypto";
|
|
11
|
-
import WebSocket from "ws";
|
|
12
12
|
import fs$1 from "node:fs/promises";
|
|
13
13
|
import { Agent } from "@mariozechner/pi-agent-core";
|
|
14
14
|
import { Type, getModel, getOAuthApiKey, getProviders } from "@mariozechner/pi-ai";
|
|
@@ -39,132 +39,6 @@ var __exportAll = (all, no_symbols) => {
|
|
|
39
39
|
return target;
|
|
40
40
|
};
|
|
41
41
|
|
|
42
|
-
//#endregion
|
|
43
|
-
//#region src/compat/openclaw-mirror.ts
|
|
44
|
-
function resolveOpenClawHome(env = process.env) {
|
|
45
|
-
const override = env.OPENCLAW_STATE_DIR?.trim();
|
|
46
|
-
if (override) return path.resolve(override.startsWith("~") ? path.join(os.homedir(), override.slice(1)) : override);
|
|
47
|
-
return path.join(os.homedir(), ".openclaw");
|
|
48
|
-
}
|
|
49
|
-
function resolveOpenClawConfigPath(openclawHome) {
|
|
50
|
-
return path.join(openclawHome, "openclaw.json");
|
|
51
|
-
}
|
|
52
|
-
function resolveOpenClawSharedSkillsPath(openclawHome) {
|
|
53
|
-
return path.join(openclawHome, "skills");
|
|
54
|
-
}
|
|
55
|
-
function readJsonIfExists(filePath) {
|
|
56
|
-
if (!fs.existsSync(filePath)) return null;
|
|
57
|
-
try {
|
|
58
|
-
return JSON.parse(fs.readFileSync(filePath, "utf8"));
|
|
59
|
-
} catch {
|
|
60
|
-
return null;
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
function buildMirrorConfig(config) {
|
|
64
|
-
const fallbackWorkspace = config.agents.defaults.workspace || path.join(config.hovclawHome, "workspace");
|
|
65
|
-
const agentList = config.agents.list.length > 0 ? config.agents.list : [{
|
|
66
|
-
id: "main",
|
|
67
|
-
name: "Main",
|
|
68
|
-
workspace: fallbackWorkspace,
|
|
69
|
-
default: true
|
|
70
|
-
}];
|
|
71
|
-
const extraDirs = /* @__PURE__ */ new Set();
|
|
72
|
-
extraDirs.add(config.skillsDir);
|
|
73
|
-
for (const agent of agentList) {
|
|
74
|
-
const workspace = (agent.workspace || fallbackWorkspace).trim();
|
|
75
|
-
if (!workspace) continue;
|
|
76
|
-
extraDirs.add(path.join(workspace, "skills"));
|
|
77
|
-
}
|
|
78
|
-
return {
|
|
79
|
-
agent: { workspace: fallbackWorkspace },
|
|
80
|
-
agents: {
|
|
81
|
-
defaults: { workspace: fallbackWorkspace },
|
|
82
|
-
list: agentList
|
|
83
|
-
},
|
|
84
|
-
skills: { load: { extraDirs: Array.from(extraDirs) } }
|
|
85
|
-
};
|
|
86
|
-
}
|
|
87
|
-
function ensureDir(dirPath) {
|
|
88
|
-
fs.mkdirSync(dirPath, {
|
|
89
|
-
recursive: true,
|
|
90
|
-
mode: 448
|
|
91
|
-
});
|
|
92
|
-
}
|
|
93
|
-
function syncSkillsDir(sharedSkillsPath, sourceSkillsPath) {
|
|
94
|
-
if (!fs.existsSync(sourceSkillsPath)) {
|
|
95
|
-
ensureDir(sharedSkillsPath);
|
|
96
|
-
return false;
|
|
97
|
-
}
|
|
98
|
-
try {
|
|
99
|
-
if (fs.lstatSync(sharedSkillsPath).isSymbolicLink()) {
|
|
100
|
-
const linkTarget = fs.readlinkSync(sharedSkillsPath);
|
|
101
|
-
if (path.resolve(path.dirname(sharedSkillsPath), linkTarget) === sourceSkillsPath) return true;
|
|
102
|
-
fs.unlinkSync(sharedSkillsPath);
|
|
103
|
-
}
|
|
104
|
-
} catch {}
|
|
105
|
-
if (!fs.existsSync(sharedSkillsPath)) try {
|
|
106
|
-
fs.symlinkSync(sourceSkillsPath, sharedSkillsPath, "dir");
|
|
107
|
-
return true;
|
|
108
|
-
} catch {}
|
|
109
|
-
ensureDir(sharedSkillsPath);
|
|
110
|
-
for (const entry of fs.readdirSync(sourceSkillsPath, { withFileTypes: true })) {
|
|
111
|
-
const src = path.join(sourceSkillsPath, entry.name);
|
|
112
|
-
const dst = path.join(sharedSkillsPath, entry.name);
|
|
113
|
-
if (entry.isDirectory()) {
|
|
114
|
-
fs.cpSync(src, dst, {
|
|
115
|
-
recursive: true,
|
|
116
|
-
force: true
|
|
117
|
-
});
|
|
118
|
-
continue;
|
|
119
|
-
}
|
|
120
|
-
if (entry.isFile()) fs.copyFileSync(src, dst);
|
|
121
|
-
}
|
|
122
|
-
return false;
|
|
123
|
-
}
|
|
124
|
-
function writeOpenClawMirror(config) {
|
|
125
|
-
const openclawHome = resolveOpenClawHome();
|
|
126
|
-
const configPath = resolveOpenClawConfigPath(openclawHome);
|
|
127
|
-
const sharedSkillsPath = resolveOpenClawSharedSkillsPath(openclawHome);
|
|
128
|
-
ensureDir(openclawHome);
|
|
129
|
-
const mirrorConfig = buildMirrorConfig(config);
|
|
130
|
-
fs.writeFileSync(configPath, `${JSON.stringify(mirrorConfig, null, 2)}\n`, {
|
|
131
|
-
encoding: "utf8",
|
|
132
|
-
mode: 384
|
|
133
|
-
});
|
|
134
|
-
fs.chmodSync(configPath, 384);
|
|
135
|
-
return {
|
|
136
|
-
openclawHome,
|
|
137
|
-
configPath,
|
|
138
|
-
sharedSkillsPath,
|
|
139
|
-
linkedSharedSkills: syncSkillsDir(sharedSkillsPath, config.skillsDir)
|
|
140
|
-
};
|
|
141
|
-
}
|
|
142
|
-
function getOpenClawMirrorStatus(config) {
|
|
143
|
-
const openclawHome = resolveOpenClawHome();
|
|
144
|
-
const configPath = resolveOpenClawConfigPath(openclawHome);
|
|
145
|
-
const sharedSkillsPath = resolveOpenClawSharedSkillsPath(openclawHome);
|
|
146
|
-
const expectedConfig = buildMirrorConfig(config);
|
|
147
|
-
const currentConfig = readJsonIfExists(configPath);
|
|
148
|
-
let linkedSharedSkills = false;
|
|
149
|
-
try {
|
|
150
|
-
if (fs.lstatSync(sharedSkillsPath).isSymbolicLink()) {
|
|
151
|
-
const target = fs.readlinkSync(sharedSkillsPath);
|
|
152
|
-
linkedSharedSkills = path.resolve(path.dirname(sharedSkillsPath), target) === path.resolve(config.skillsDir);
|
|
153
|
-
}
|
|
154
|
-
} catch {
|
|
155
|
-
linkedSharedSkills = false;
|
|
156
|
-
}
|
|
157
|
-
return {
|
|
158
|
-
openclawHome,
|
|
159
|
-
configPath,
|
|
160
|
-
sharedSkillsPath,
|
|
161
|
-
linkedSharedSkills,
|
|
162
|
-
configExists: fs.existsSync(configPath),
|
|
163
|
-
configInSync: JSON.stringify(currentConfig) === JSON.stringify(expectedConfig),
|
|
164
|
-
skillsPathExists: fs.existsSync(sharedSkillsPath)
|
|
165
|
-
};
|
|
166
|
-
}
|
|
167
|
-
|
|
168
42
|
//#endregion
|
|
169
43
|
//#region src/config.ts
|
|
170
44
|
dotenv.config();
|
|
@@ -1251,31 +1125,6 @@ function getProviderApiKeyFromEnv(provider, env = process.env) {
|
|
|
1251
1125
|
}
|
|
1252
1126
|
const config = loadConfig();
|
|
1253
1127
|
|
|
1254
|
-
//#endregion
|
|
1255
|
-
//#region src/cli/compat.ts
|
|
1256
|
-
function renderStatus(status) {
|
|
1257
|
-
const lines = [];
|
|
1258
|
-
lines.push(`OpenClaw home: ${status.openclawHome}`);
|
|
1259
|
-
lines.push(`Config path: ${status.configPath}`);
|
|
1260
|
-
lines.push(`Config exists: ${status.configExists ? "yes" : "no"}`);
|
|
1261
|
-
lines.push(`Config in sync: ${status.configInSync ? "yes" : "no"}`);
|
|
1262
|
-
lines.push(`Skills path: ${status.sharedSkillsPath}`);
|
|
1263
|
-
lines.push(`Skills exists: ${status.skillsPathExists ? "yes" : "no"}`);
|
|
1264
|
-
lines.push(`Skills symlinked: ${status.linkedSharedSkills ? "yes" : "no"}`);
|
|
1265
|
-
return lines.join("\n");
|
|
1266
|
-
}
|
|
1267
|
-
function registerCompatCommands(program) {
|
|
1268
|
-
program.command("compat").description("Compatibility helpers").command("status").description("Show OpenClaw mirror compatibility status").option("--sync", "Rewrite mirror before reading status").option("--json", "Print JSON output").action((options) => {
|
|
1269
|
-
if (options.sync) writeOpenClawMirror(config);
|
|
1270
|
-
const status = getOpenClawMirrorStatus(config);
|
|
1271
|
-
if (options.json) {
|
|
1272
|
-
process.stdout.write(`${JSON.stringify(status, null, 2)}\n`);
|
|
1273
|
-
return;
|
|
1274
|
-
}
|
|
1275
|
-
process.stdout.write(`${renderStatus(status)}\n`);
|
|
1276
|
-
});
|
|
1277
|
-
}
|
|
1278
|
-
|
|
1279
1128
|
//#endregion
|
|
1280
1129
|
//#region src/gateway/protocol/schema.ts
|
|
1281
1130
|
const nonEmptyStringSchema = z.string().min(1);
|
|
@@ -4455,7 +4304,6 @@ function readFileConfigForCli(env = process.env) {
|
|
|
4455
4304
|
}
|
|
4456
4305
|
function writeFileConfigForCli(next, env = process.env) {
|
|
4457
4306
|
saveConfigFile(next, env);
|
|
4458
|
-
writeOpenClawMirror(loadConfig(env));
|
|
4459
4307
|
}
|
|
4460
4308
|
|
|
4461
4309
|
//#endregion
|
|
@@ -5631,7 +5479,7 @@ function registerGatewayCommands(program, deps = defaultGatewayCommandDeps) {
|
|
|
5631
5479
|
gateway.command("run").description("Run HOVClaw daemon with gateway in foreground").action(async () => {
|
|
5632
5480
|
if (!config.gateway.enabled) throw new Error("Gateway is disabled in config. Enable gateway.enabled first.");
|
|
5633
5481
|
process.stdout.write(`Starting HOVClaw gateway on ${config.gateway.host}:${config.gateway.port}...\n`);
|
|
5634
|
-
await import("./src-
|
|
5482
|
+
await import("./src-qX1C6PLF.js");
|
|
5635
5483
|
});
|
|
5636
5484
|
gateway.command("open-ui").description("Open the minimal gateway web UI in your default browser").option("--no-open", "Print URL but do not open browser").option("--json", "Print JSON output").action(async (options) => {
|
|
5637
5485
|
const url = resolveGatewayWebUiUrl();
|
|
@@ -5935,7 +5783,7 @@ function registerCoreCommands(program) {
|
|
|
5935
5783
|
await (await import("./login-BwvBMKdz.js")).main(provider ? [provider] : []);
|
|
5936
5784
|
});
|
|
5937
5785
|
program.command("doctor").description("Run installation and config health checks").option("--fix", "Attempt auto-repair").option("--repair", "Attempt auto-repair").option("--deep", "Run deep checks").option("--json", "Print JSON output").action(async (options) => {
|
|
5938
|
-
const module = await import("./doctor-
|
|
5786
|
+
const module = await import("./doctor-DJHTvhli.js");
|
|
5939
5787
|
const args = [];
|
|
5940
5788
|
if (options.fix || options.repair) args.push("--fix");
|
|
5941
5789
|
if (options.deep) args.push("--deep");
|
|
@@ -6051,7 +5899,6 @@ async function main() {
|
|
|
6051
5899
|
registerPairingCommands(program);
|
|
6052
5900
|
registerGatewayCommands(program);
|
|
6053
5901
|
registerSkillsCommands(program);
|
|
6054
|
-
registerCompatCommands(program);
|
|
6055
5902
|
await program.parseAsync(process.argv);
|
|
6056
5903
|
}
|
|
6057
5904
|
main().catch((error) => {
|
|
@@ -6060,4 +5907,4 @@ main().catch((error) => {
|
|
|
6060
5907
|
});
|
|
6061
5908
|
|
|
6062
5909
|
//#endregion
|
|
6063
|
-
export { ensureConfigFromLegacyEnv as A, resolveTelegramAccountConfig as B, resolveModelAlias as C, parseGatewayFrame as D, parseConnectParams as E, hasConfigFile as F, saveCredentials as H, hasCredentialsFile as I, loadConfig as L, getCredentialsPath as M, getDefaultFileConfig as N, config as O, getHovclawHome as P, loadCredentials as R, parseModelRef as S, PROTOCOL_VERSION as T,
|
|
5910
|
+
export { ensureConfigFromLegacyEnv as A, resolveTelegramAccountConfig as B, resolveModelAlias as C, parseGatewayFrame as D, parseConnectParams as E, hasConfigFile as F, saveCredentials as H, hasCredentialsFile as I, loadConfig as L, getCredentialsPath as M, getDefaultFileConfig as N, config as O, getHovclawHome as P, loadCredentials as R, parseModelRef as S, PROTOCOL_VERSION as T, saveConfigFile as V, extractAssistantText as _, LocalHostRuntime as a, loadSkill as b, redactSensitiveData as c, PiAgentManager as d, composeSessionKey as f, extractAssistantError as g, resolveAgentWorkspaceDir as h, createTools as i, getConfigPath as j, detectLegacyEnvConfig as k, TelegramChannel as l, ensureWorkspaceBootstrapForConfig as m, stopDaemon as n, ContainerRuntime as o, WORKSPACE_CONTEXT_FILE_ORDER as p, TelegramPairingStore as r, HovClawDb as s, requestDaemonRestartFromCurrentProcess as t, DiscordChannel as u, toUserFacingAssistantError as v, logger as w, listConfiguredModelRefs as x, listAvailableSkills as y, loadFileConfig as z };
|
package/dist/index.js
CHANGED
|
@@ -3084,99 +3084,6 @@ async function requestDaemonRestartFromCurrentProcess(env = process.env) {
|
|
|
3084
3084
|
};
|
|
3085
3085
|
}
|
|
3086
3086
|
|
|
3087
|
-
//#endregion
|
|
3088
|
-
//#region src/compat/openclaw-mirror.ts
|
|
3089
|
-
function resolveOpenClawHome(env = process.env) {
|
|
3090
|
-
const override = env.OPENCLAW_STATE_DIR?.trim();
|
|
3091
|
-
if (override) return path.resolve(override.startsWith("~") ? path.join(os.homedir(), override.slice(1)) : override);
|
|
3092
|
-
return path.join(os.homedir(), ".openclaw");
|
|
3093
|
-
}
|
|
3094
|
-
function resolveOpenClawConfigPath(openclawHome) {
|
|
3095
|
-
return path.join(openclawHome, "openclaw.json");
|
|
3096
|
-
}
|
|
3097
|
-
function resolveOpenClawSharedSkillsPath(openclawHome) {
|
|
3098
|
-
return path.join(openclawHome, "skills");
|
|
3099
|
-
}
|
|
3100
|
-
function buildMirrorConfig(config) {
|
|
3101
|
-
const fallbackWorkspace = config.agents.defaults.workspace || path.join(config.hovclawHome, "workspace");
|
|
3102
|
-
const agentList = config.agents.list.length > 0 ? config.agents.list : [{
|
|
3103
|
-
id: "main",
|
|
3104
|
-
name: "Main",
|
|
3105
|
-
workspace: fallbackWorkspace,
|
|
3106
|
-
default: true
|
|
3107
|
-
}];
|
|
3108
|
-
const extraDirs = /* @__PURE__ */ new Set();
|
|
3109
|
-
extraDirs.add(config.skillsDir);
|
|
3110
|
-
for (const agent of agentList) {
|
|
3111
|
-
const workspace = (agent.workspace || fallbackWorkspace).trim();
|
|
3112
|
-
if (!workspace) continue;
|
|
3113
|
-
extraDirs.add(path.join(workspace, "skills"));
|
|
3114
|
-
}
|
|
3115
|
-
return {
|
|
3116
|
-
agent: { workspace: fallbackWorkspace },
|
|
3117
|
-
agents: {
|
|
3118
|
-
defaults: { workspace: fallbackWorkspace },
|
|
3119
|
-
list: agentList
|
|
3120
|
-
},
|
|
3121
|
-
skills: { load: { extraDirs: Array.from(extraDirs) } }
|
|
3122
|
-
};
|
|
3123
|
-
}
|
|
3124
|
-
function ensureDir(dirPath) {
|
|
3125
|
-
fs.mkdirSync(dirPath, {
|
|
3126
|
-
recursive: true,
|
|
3127
|
-
mode: 448
|
|
3128
|
-
});
|
|
3129
|
-
}
|
|
3130
|
-
function syncSkillsDir(sharedSkillsPath, sourceSkillsPath) {
|
|
3131
|
-
if (!fs.existsSync(sourceSkillsPath)) {
|
|
3132
|
-
ensureDir(sharedSkillsPath);
|
|
3133
|
-
return false;
|
|
3134
|
-
}
|
|
3135
|
-
try {
|
|
3136
|
-
if (fs.lstatSync(sharedSkillsPath).isSymbolicLink()) {
|
|
3137
|
-
const linkTarget = fs.readlinkSync(sharedSkillsPath);
|
|
3138
|
-
if (path.resolve(path.dirname(sharedSkillsPath), linkTarget) === sourceSkillsPath) return true;
|
|
3139
|
-
fs.unlinkSync(sharedSkillsPath);
|
|
3140
|
-
}
|
|
3141
|
-
} catch {}
|
|
3142
|
-
if (!fs.existsSync(sharedSkillsPath)) try {
|
|
3143
|
-
fs.symlinkSync(sourceSkillsPath, sharedSkillsPath, "dir");
|
|
3144
|
-
return true;
|
|
3145
|
-
} catch {}
|
|
3146
|
-
ensureDir(sharedSkillsPath);
|
|
3147
|
-
for (const entry of fs.readdirSync(sourceSkillsPath, { withFileTypes: true })) {
|
|
3148
|
-
const src = path.join(sourceSkillsPath, entry.name);
|
|
3149
|
-
const dst = path.join(sharedSkillsPath, entry.name);
|
|
3150
|
-
if (entry.isDirectory()) {
|
|
3151
|
-
fs.cpSync(src, dst, {
|
|
3152
|
-
recursive: true,
|
|
3153
|
-
force: true
|
|
3154
|
-
});
|
|
3155
|
-
continue;
|
|
3156
|
-
}
|
|
3157
|
-
if (entry.isFile()) fs.copyFileSync(src, dst);
|
|
3158
|
-
}
|
|
3159
|
-
return false;
|
|
3160
|
-
}
|
|
3161
|
-
function writeOpenClawMirror(config) {
|
|
3162
|
-
const openclawHome = resolveOpenClawHome();
|
|
3163
|
-
const configPath = resolveOpenClawConfigPath(openclawHome);
|
|
3164
|
-
const sharedSkillsPath = resolveOpenClawSharedSkillsPath(openclawHome);
|
|
3165
|
-
ensureDir(openclawHome);
|
|
3166
|
-
const mirrorConfig = buildMirrorConfig(config);
|
|
3167
|
-
fs.writeFileSync(configPath, `${JSON.stringify(mirrorConfig, null, 2)}\n`, {
|
|
3168
|
-
encoding: "utf8",
|
|
3169
|
-
mode: 384
|
|
3170
|
-
});
|
|
3171
|
-
fs.chmodSync(configPath, 384);
|
|
3172
|
-
return {
|
|
3173
|
-
openclawHome,
|
|
3174
|
-
configPath,
|
|
3175
|
-
sharedSkillsPath,
|
|
3176
|
-
linkedSharedSkills: syncSkillsDir(sharedSkillsPath, config.skillsDir)
|
|
3177
|
-
};
|
|
3178
|
-
}
|
|
3179
|
-
|
|
3180
3087
|
//#endregion
|
|
3181
3088
|
//#region src/models/catalog.ts
|
|
3182
3089
|
function buildModelCatalog(aliases) {
|
|
@@ -3583,7 +3490,6 @@ function reloadRuntimeConfig() {
|
|
|
3583
3490
|
function persistFileConfig(next) {
|
|
3584
3491
|
saveConfigFile(next);
|
|
3585
3492
|
reloadRuntimeConfig();
|
|
3586
|
-
writeOpenClawMirror(config);
|
|
3587
3493
|
}
|
|
3588
3494
|
function parseConfigPath(raw) {
|
|
3589
3495
|
const pathValue = raw?.trim();
|
|
@@ -5083,14 +4989,12 @@ const configGetMethod = async (_params, context) => {
|
|
|
5083
4989
|
const configSetMethod = async (params, context) => {
|
|
5084
4990
|
const parsed = configSetParamsSchema.parse(params);
|
|
5085
4991
|
context.writeFileConfig(parsed.config);
|
|
5086
|
-
writeOpenClawMirror(loadConfig());
|
|
5087
4992
|
return { ok: true };
|
|
5088
4993
|
};
|
|
5089
4994
|
const configPatchMethod = async (params, context) => {
|
|
5090
4995
|
const parsed = configPatchParamsSchema.parse(params);
|
|
5091
4996
|
const merged = deepMerge(context.readFileConfig(), parsed.patch);
|
|
5092
4997
|
context.writeFileConfig(merged);
|
|
5093
|
-
writeOpenClawMirror(loadConfig());
|
|
5094
4998
|
return { ok: true };
|
|
5095
4999
|
};
|
|
5096
5000
|
|
|
@@ -7082,7 +6986,6 @@ async function main() {
|
|
|
7082
6986
|
} catch (error) {
|
|
7083
6987
|
logger.warn({ error }, "Workspace bootstrap failed");
|
|
7084
6988
|
}
|
|
7085
|
-
writeOpenClawMirror(config);
|
|
7086
6989
|
const db = new HovClawDb(path.join(config.storeDir, "hovclaw.db"));
|
|
7087
6990
|
db.ping();
|
|
7088
6991
|
const runtime = config.runtime.mode === "container" ? new ContainerRuntime({
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { A as ensureConfigFromLegacyEnv, B as resolveTelegramAccountConfig, C as resolveModelAlias, D as parseGatewayFrame, E as parseConnectParams, F as hasConfigFile, L as loadConfig, N as getDefaultFileConfig, O as config, S as parseModelRef, T as PROTOCOL_VERSION,
|
|
1
|
+
import { A as ensureConfigFromLegacyEnv, B as resolveTelegramAccountConfig, C as resolveModelAlias, D as parseGatewayFrame, E as parseConnectParams, F as hasConfigFile, L as loadConfig, N as getDefaultFileConfig, O as config, S as parseModelRef, T as PROTOCOL_VERSION, V as saveConfigFile, _ as extractAssistantText, a as LocalHostRuntime, b as loadSkill, c as redactSensitiveData, d as PiAgentManager, f as composeSessionKey, g as extractAssistantError, h as resolveAgentWorkspaceDir, i as createTools, l as TelegramChannel, m as ensureWorkspaceBootstrapForConfig, o as ContainerRuntime, p as WORKSPACE_CONTEXT_FILE_ORDER, r as TelegramPairingStore, s as HovClawDb, t as requestDaemonRestartFromCurrentProcess, u as DiscordChannel, v as toUserFacingAssistantError, w as logger, x as listConfiguredModelRefs, y as listAvailableSkills, z as loadFileConfig } from "./hovclaw.js";
|
|
2
2
|
import fs from "node:fs";
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import { fileURLToPath } from "node:url";
|
|
5
|
-
import { ZodError, z } from "zod";
|
|
6
5
|
import { randomUUID } from "node:crypto";
|
|
7
6
|
import WebSocket, { WebSocketServer } from "ws";
|
|
7
|
+
import { ZodError, z } from "zod";
|
|
8
8
|
import fs$1 from "node:fs/promises";
|
|
9
9
|
import { createServer } from "node:http";
|
|
10
10
|
import { spawnSync } from "node:child_process";
|
|
@@ -543,7 +543,6 @@ function reloadRuntimeConfig() {
|
|
|
543
543
|
function persistFileConfig(next) {
|
|
544
544
|
saveConfigFile(next);
|
|
545
545
|
reloadRuntimeConfig();
|
|
546
|
-
writeOpenClawMirror(config);
|
|
547
546
|
}
|
|
548
547
|
function parseConfigPath(raw) {
|
|
549
548
|
const pathValue = raw?.trim();
|
|
@@ -1483,14 +1482,12 @@ const configGetMethod = async (_params, context) => {
|
|
|
1483
1482
|
const configSetMethod = async (params, context) => {
|
|
1484
1483
|
const parsed = configSetParamsSchema.parse(params);
|
|
1485
1484
|
context.writeFileConfig(parsed.config);
|
|
1486
|
-
writeOpenClawMirror(loadConfig());
|
|
1487
1485
|
return { ok: true };
|
|
1488
1486
|
};
|
|
1489
1487
|
const configPatchMethod = async (params, context) => {
|
|
1490
1488
|
const parsed = configPatchParamsSchema.parse(params);
|
|
1491
1489
|
const merged = deepMerge(context.readFileConfig(), parsed.patch);
|
|
1492
1490
|
context.writeFileConfig(merged);
|
|
1493
|
-
writeOpenClawMirror(loadConfig());
|
|
1494
1491
|
return { ok: true };
|
|
1495
1492
|
};
|
|
1496
1493
|
|
|
@@ -2604,7 +2601,6 @@ async function main() {
|
|
|
2604
2601
|
} catch (error) {
|
|
2605
2602
|
logger.warn({ error }, "Workspace bootstrap failed");
|
|
2606
2603
|
}
|
|
2607
|
-
writeOpenClawMirror(config);
|
|
2608
2604
|
const db = new HovClawDb(path.join(config.storeDir, "hovclaw.db"));
|
|
2609
2605
|
db.ping();
|
|
2610
2606
|
const runtime = config.runtime.mode === "container" ? new ContainerRuntime({
|