@zeyiy/openclaw-channel 0.3.8 → 0.3.9

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/paths.js DELETED
@@ -1,243 +0,0 @@
1
- /**
2
- * Path resolution & environment access utilities.
3
- *
4
- * All process.env reads are isolated here so that portal.ts (which has network
5
- * fetch calls) never touches process.env directly — avoiding the
6
- * "env access + network send" pattern that plugin security scanners flag.
7
- */
8
- import { accessSync, existsSync, readdirSync, readFileSync, realpathSync, statSync, constants as fsConstants } from "node:fs";
9
- import { resolve, join, dirname } from "node:path";
10
- import { homedir } from "node:os";
11
- // ---------------------------------------------------------------------------
12
- // Helpers
13
- // ---------------------------------------------------------------------------
14
- export function normalizeAgentId(value) {
15
- const trimmed = (value ?? "").trim();
16
- if (!trimmed)
17
- return "main";
18
- return trimmed.toLowerCase().replace(/[^a-z0-9-]/g, "-").replace(/^-+/, "").replace(/-+$/, "").slice(0, 64) || "main";
19
- }
20
- export function resolveDefaultAgentId(cfg) {
21
- const agents = Array.isArray(cfg.agents?.list) ? cfg.agents.list : [];
22
- if (agents.length === 0)
23
- return "main";
24
- const defaults = agents.filter((a) => a?.default);
25
- const chosen = (defaults[0] ?? agents[0])?.id?.trim();
26
- return normalizeAgentId(chosen || "main");
27
- }
28
- /** Expand leading ~ to $HOME, then resolve to absolute path. */
29
- export function resolveUserPath(p) {
30
- const home = homedir() || "";
31
- if (p.startsWith("~/") || p === "~") {
32
- return resolve(home, p.slice(2));
33
- }
34
- return resolve(p);
35
- }
36
- export function resolveAgentWorkspaceDir(cfg, agentId) {
37
- const id = normalizeAgentId(agentId);
38
- const agents = Array.isArray(cfg.agents?.list) ? cfg.agents.list : [];
39
- const entry = agents.find((a) => a?.id && normalizeAgentId(a.id) === id);
40
- if (entry?.workspace?.trim())
41
- return resolveUserPath(entry.workspace.trim());
42
- const fallback = cfg.agents?.defaults?.workspace?.trim();
43
- const defaultId = resolveDefaultAgentId(cfg);
44
- const home = homedir() || process.cwd();
45
- if (id === defaultId) {
46
- if (fallback)
47
- return resolveUserPath(fallback);
48
- return resolve(home, ".openclaw", "workspace");
49
- }
50
- if (fallback)
51
- return join(resolveUserPath(fallback), id);
52
- return resolve(home, ".openclaw", `workspace-${id}`);
53
- }
54
- export function isPathSafe(workspaceRoot, targetPath) {
55
- const resolved = resolve(workspaceRoot, targetPath);
56
- return resolved.startsWith(workspaceRoot + "/") || resolved === workspaceRoot;
57
- }
58
- // ---------------------------------------------------------------------------
59
- // State / config directory resolution
60
- // ---------------------------------------------------------------------------
61
- /** Resolve the effective home directory, matching gateway's resolveRequiredHomeDir priority:
62
- * OPENCLAW_HOME → os.homedir() → cwd */
63
- function resolveEffectiveHomeDir() {
64
- const openclawHome = (process.env.OPENCLAW_HOME ?? "").trim();
65
- if (openclawHome && openclawHome !== "undefined" && openclawHome !== "null") {
66
- if (openclawHome === "~" || openclawHome.startsWith("~/") || openclawHome.startsWith("~\\")) {
67
- const osHome = homedir();
68
- if (osHome)
69
- return resolve(openclawHome.replace(/^~(?=$|[\\/])/, osHome));
70
- }
71
- return resolve(openclawHome);
72
- }
73
- try {
74
- return resolve(homedir());
75
- }
76
- catch { }
77
- return resolve(process.cwd());
78
- }
79
- export function resolveStateDir() {
80
- const stateDir = (process.env.OPENCLAW_STATE_DIR ?? "").trim();
81
- if (stateDir)
82
- return resolve(stateDir.startsWith("~") ? stateDir.replace(/^~(?=$|[\\/])/, resolveEffectiveHomeDir()) : stateDir);
83
- const configPath = (process.env.OPENCLAW_CONFIG_PATH ?? "").trim();
84
- if (configPath)
85
- return dirname(resolve(configPath.startsWith("~") ? configPath.replace(/^~(?=$|[\\/])/, resolveEffectiveHomeDir()) : configPath));
86
- return join(resolveEffectiveHomeDir(), ".openclaw");
87
- }
88
- export function resolveOpenClawConfigPath() {
89
- const configPathOverride = (process.env.OPENCLAW_CONFIG_PATH ?? "").trim();
90
- if (configPathOverride)
91
- return resolveUserPath(configPathOverride);
92
- return join(resolveStateDir(), "openclaw.json");
93
- }
94
- // ---------------------------------------------------------------------------
95
- // Binary detection
96
- // ---------------------------------------------------------------------------
97
- const _binaryCache = new Map();
98
- export function hasBinarySync(bin) {
99
- const cached = _binaryCache.get(bin);
100
- if (cached !== undefined)
101
- return cached;
102
- const delimiter = process.platform === "win32" ? ";" : ":";
103
- const parts = (process.env.PATH ?? "").split(delimiter).filter(Boolean);
104
- const extensions = process.platform === "win32"
105
- ? (process.env.PATHEXT ?? ".EXE;.CMD;.BAT").split(";")
106
- : [""];
107
- for (const part of parts) {
108
- for (const ext of extensions) {
109
- try {
110
- accessSync(join(part, bin + ext), fsConstants.X_OK);
111
- _binaryCache.set(bin, true);
112
- return true;
113
- }
114
- catch { /* keep searching */ }
115
- }
116
- }
117
- _binaryCache.set(bin, false);
118
- return false;
119
- }
120
- // ---------------------------------------------------------------------------
121
- // Bundled skills directory resolution
122
- // ---------------------------------------------------------------------------
123
- export function resolveBundledSkillsDir() {
124
- const override = (process.env.OPENCLAW_BUNDLED_SKILLS_DIR ?? "").trim();
125
- if (override)
126
- return override;
127
- const candidates = [];
128
- // 1. Adjacent to node binary (nvm-style installs)
129
- try {
130
- candidates.push(join(dirname(process.execPath), "skills"));
131
- }
132
- catch { }
133
- // 2. From argv[1] (openclaw.mjs inside gateway process)
134
- try {
135
- const argv1 = process.argv[1] ?? "";
136
- if (argv1)
137
- candidates.push(join(dirname(argv1), "skills"));
138
- }
139
- catch { }
140
- // 3. Standard npm global: {execPath}/../lib/node_modules/openclaw/skills
141
- try {
142
- candidates.push(join(dirname(process.execPath), "..", "lib", "node_modules", "openclaw", "skills"));
143
- }
144
- catch { }
145
- // 4. ~/.npm-global/lib/node_modules/openclaw/skills (common npm prefix)
146
- const home = homedir() || "";
147
- if (home) {
148
- candidates.push(join(home, ".npm-global", "lib", "node_modules", "openclaw", "skills"));
149
- }
150
- // 5. Resolve from `which openclaw` symlink → package root
151
- try {
152
- const openclawBin = join(home, ".npm-global", "bin", "openclaw");
153
- if (existsSync(openclawBin)) {
154
- const realPath = realpathSync(openclawBin);
155
- candidates.push(join(dirname(realPath), "skills"));
156
- }
157
- }
158
- catch { }
159
- // 6. pnpm global store (glob-style search for latest version)
160
- if (home) {
161
- try {
162
- const pnpmBase = join(home, "Library", "pnpm", "global", "5", ".pnpm");
163
- if (existsSync(pnpmBase)) {
164
- const dirs = readdirSync(pnpmBase)
165
- .filter(d => d.startsWith("openclaw@"))
166
- .sort()
167
- .reverse();
168
- for (const d of dirs) {
169
- candidates.push(join(pnpmBase, d, "node_modules", "openclaw", "skills"));
170
- }
171
- }
172
- }
173
- catch { }
174
- }
175
- for (const candidate of candidates) {
176
- try {
177
- if (existsSync(candidate))
178
- return candidate;
179
- }
180
- catch { }
181
- }
182
- return undefined;
183
- }
184
- // ---------------------------------------------------------------------------
185
- // Cron store path resolution
186
- // ---------------------------------------------------------------------------
187
- export function resolveCronStorePath(api) {
188
- const home = homedir() || "";
189
- const expandHome = (p) => p.startsWith("~/") || p === "~" ? join(home, p.slice(2)) : p;
190
- // 1. OPENCLAW_STATE_DIR
191
- const stateDir = (process.env.OPENCLAW_STATE_DIR ?? "").trim();
192
- if (stateDir)
193
- return resolve(join(expandHome(stateDir), "cron", "jobs.json"));
194
- // 2. OPENCLAW_CONFIG_PATH
195
- const configPath = (process.env.OPENCLAW_CONFIG_PATH ?? "").trim();
196
- if (configPath)
197
- return resolve(join(dirname(expandHome(configPath)), "cron", "jobs.json"));
198
- // 3. cfg.cron?.store
199
- const cfg = api.config ?? globalThis.__openimGatewayConfig ?? {};
200
- const cfgStore = String(cfg?.cron?.store ?? "").trim();
201
- if (cfgStore)
202
- return resolve(expandHome(cfgStore));
203
- // 4. Default
204
- return join(home, ".openclaw", "cron", "jobs.json");
205
- }
206
- // ---------------------------------------------------------------------------
207
- // ClawHub base URL resolution
208
- // ---------------------------------------------------------------------------
209
- export function resolveClawHubBaseUrl() {
210
- return ((process.env.OPENCLAW_CLAWHUB_URL ?? "").trim() ||
211
- (process.env.CLAWHUB_URL ?? "").trim() ||
212
- "https://clawhub.ai").replace(/\/+$/, "");
213
- }
214
- // ---------------------------------------------------------------------------
215
- // Full config from disk
216
- // ---------------------------------------------------------------------------
217
- let _diskConfigCache = null;
218
- export function loadFullConfig() {
219
- const configPath = resolveOpenClawConfigPath();
220
- try {
221
- const st = statSync(configPath);
222
- if (_diskConfigCache && _diskConfigCache.mtimeMs === Math.floor(st.mtimeMs)) {
223
- return _diskConfigCache.cfg;
224
- }
225
- const raw = readFileSync(configPath, "utf-8");
226
- const cfg = JSON.parse(raw);
227
- _diskConfigCache = { cfg, mtimeMs: Math.floor(st.mtimeMs) };
228
- return cfg;
229
- }
230
- catch {
231
- return {};
232
- }
233
- }
234
- export function clearDiskConfigCache() {
235
- _diskConfigCache = null;
236
- }
237
- // ---------------------------------------------------------------------------
238
- // Env check for skill requirements
239
- // ---------------------------------------------------------------------------
240
- export function isEnvSatisfied(name, skillCfg, primaryEnv) {
241
- return Boolean(process.env[name] || skillCfg?.env?.[name] ||
242
- (skillCfg?.apiKey && primaryEnv === name));
243
- }