@getworkle/cli 0.2.11 → 0.2.13
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/cli.js +266 -101
- package/dist/cli.js.map +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -1209,7 +1209,7 @@ var require_command = __commonJS({
|
|
|
1209
1209
|
"use strict";
|
|
1210
1210
|
var EventEmitter = __require("events").EventEmitter;
|
|
1211
1211
|
var childProcess = __require("child_process");
|
|
1212
|
-
var
|
|
1212
|
+
var path20 = __require("path");
|
|
1213
1213
|
var fs17 = __require("fs");
|
|
1214
1214
|
var process2 = __require("process");
|
|
1215
1215
|
var { Argument: Argument2, humanReadableArgName } = require_argument();
|
|
@@ -2222,9 +2222,9 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
2222
2222
|
let launchWithNode = false;
|
|
2223
2223
|
const sourceExt = [".js", ".ts", ".tsx", ".mjs", ".cjs"];
|
|
2224
2224
|
function findFile(baseDir, baseName) {
|
|
2225
|
-
const localBin =
|
|
2225
|
+
const localBin = path20.resolve(baseDir, baseName);
|
|
2226
2226
|
if (fs17.existsSync(localBin)) return localBin;
|
|
2227
|
-
if (sourceExt.includes(
|
|
2227
|
+
if (sourceExt.includes(path20.extname(baseName))) return void 0;
|
|
2228
2228
|
const foundExt = sourceExt.find(
|
|
2229
2229
|
(ext) => fs17.existsSync(`${localBin}${ext}`)
|
|
2230
2230
|
);
|
|
@@ -2242,17 +2242,17 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
2242
2242
|
} catch {
|
|
2243
2243
|
resolvedScriptPath = this._scriptPath;
|
|
2244
2244
|
}
|
|
2245
|
-
executableDir =
|
|
2246
|
-
|
|
2245
|
+
executableDir = path20.resolve(
|
|
2246
|
+
path20.dirname(resolvedScriptPath),
|
|
2247
2247
|
executableDir
|
|
2248
2248
|
);
|
|
2249
2249
|
}
|
|
2250
2250
|
if (executableDir) {
|
|
2251
2251
|
let localFile = findFile(executableDir, executableFile);
|
|
2252
2252
|
if (!localFile && !subcommand._executableFile && this._scriptPath) {
|
|
2253
|
-
const legacyName =
|
|
2253
|
+
const legacyName = path20.basename(
|
|
2254
2254
|
this._scriptPath,
|
|
2255
|
-
|
|
2255
|
+
path20.extname(this._scriptPath)
|
|
2256
2256
|
);
|
|
2257
2257
|
if (legacyName !== this._name) {
|
|
2258
2258
|
localFile = findFile(
|
|
@@ -2263,7 +2263,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
2263
2263
|
}
|
|
2264
2264
|
executableFile = localFile || executableFile;
|
|
2265
2265
|
}
|
|
2266
|
-
launchWithNode = sourceExt.includes(
|
|
2266
|
+
launchWithNode = sourceExt.includes(path20.extname(executableFile));
|
|
2267
2267
|
let proc;
|
|
2268
2268
|
if (process2.platform !== "win32") {
|
|
2269
2269
|
if (launchWithNode) {
|
|
@@ -3178,7 +3178,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
3178
3178
|
* @return {Command}
|
|
3179
3179
|
*/
|
|
3180
3180
|
nameFromFilename(filename) {
|
|
3181
|
-
this._name =
|
|
3181
|
+
this._name = path20.basename(filename, path20.extname(filename));
|
|
3182
3182
|
return this;
|
|
3183
3183
|
}
|
|
3184
3184
|
/**
|
|
@@ -3192,9 +3192,9 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
3192
3192
|
* @param {string} [path]
|
|
3193
3193
|
* @return {(string|null|Command)}
|
|
3194
3194
|
*/
|
|
3195
|
-
executableDir(
|
|
3196
|
-
if (
|
|
3197
|
-
this._executableDir =
|
|
3195
|
+
executableDir(path21) {
|
|
3196
|
+
if (path21 === void 0) return this._executableDir;
|
|
3197
|
+
this._executableDir = path21;
|
|
3198
3198
|
return this;
|
|
3199
3199
|
}
|
|
3200
3200
|
/**
|
|
@@ -4285,7 +4285,7 @@ var require_background_scheduled_task = __commonJS({
|
|
|
4285
4285
|
"../../node_modules/node-cron/src/background-scheduled-task/index.js"(exports, module) {
|
|
4286
4286
|
"use strict";
|
|
4287
4287
|
var EventEmitter = __require("events");
|
|
4288
|
-
var
|
|
4288
|
+
var path20 = __require("path");
|
|
4289
4289
|
var { fork } = __require("child_process");
|
|
4290
4290
|
var uuid3 = (init_esm_node(), __toCommonJS(esm_node_exports));
|
|
4291
4291
|
var daemonPath = `${__dirname}/daemon.js`;
|
|
@@ -4320,7 +4320,7 @@ var require_background_scheduled_task = __commonJS({
|
|
|
4320
4320
|
options.scheduled = true;
|
|
4321
4321
|
this.forkProcess.send({
|
|
4322
4322
|
type: "register",
|
|
4323
|
-
path:
|
|
4323
|
+
path: path20.resolve(this.taskPath),
|
|
4324
4324
|
cron: this.cronExpression,
|
|
4325
4325
|
options
|
|
4326
4326
|
});
|
|
@@ -8033,7 +8033,7 @@ import { readFileSync } from "fs";
|
|
|
8033
8033
|
import fs16 from "fs/promises";
|
|
8034
8034
|
import http2 from "http";
|
|
8035
8035
|
import os18 from "os";
|
|
8036
|
-
import
|
|
8036
|
+
import path19 from "path";
|
|
8037
8037
|
|
|
8038
8038
|
// src/agents/config-materializer.ts
|
|
8039
8039
|
import fs2 from "fs/promises";
|
|
@@ -8106,12 +8106,37 @@ function getAgentDirPath(agentId) {
|
|
|
8106
8106
|
const safeId = sanitizePathSegment(agentId, "agent");
|
|
8107
8107
|
return path2.join(AGENTS_HOME, `id-${safeId}`);
|
|
8108
8108
|
}
|
|
8109
|
+
function getSdkMemoryPath(agentId) {
|
|
8110
|
+
const agentDir = getAgentDirPath(agentId);
|
|
8111
|
+
const encoded = agentDir.replace(/[^a-zA-Z0-9]/g, "-");
|
|
8112
|
+
return path2.join(os2.homedir(), ".claude", "projects", encoded, "memory");
|
|
8113
|
+
}
|
|
8109
8114
|
function sanitizeAgentAssetFilename(filename, fallback) {
|
|
8110
|
-
|
|
8115
|
+
const sanitized = sanitizePathSegment(filename, fallback);
|
|
8116
|
+
return sanitized.endsWith(".md") ? sanitized : `${sanitized}.md`;
|
|
8111
8117
|
}
|
|
8112
8118
|
|
|
8113
8119
|
// src/agents/config-materializer.ts
|
|
8114
8120
|
var CACHE_FILE = path3.join(os3.homedir(), ".workle", "agent-cache.json");
|
|
8121
|
+
function buildSdkSettings(settings) {
|
|
8122
|
+
if (!settings) return {};
|
|
8123
|
+
const sdk = {};
|
|
8124
|
+
const perms = settings.permissions;
|
|
8125
|
+
if (perms && typeof perms === "object" && perms !== null) {
|
|
8126
|
+
const p = perms;
|
|
8127
|
+
const sdkPerms = {};
|
|
8128
|
+
if (Array.isArray(p.allow) && p.allow.length > 0) {
|
|
8129
|
+
sdkPerms.allow = p.allow;
|
|
8130
|
+
}
|
|
8131
|
+
if (Array.isArray(p.deny) && p.deny.length > 0) {
|
|
8132
|
+
sdkPerms.deny = p.deny;
|
|
8133
|
+
}
|
|
8134
|
+
if (Object.keys(sdkPerms).length > 0) {
|
|
8135
|
+
sdk.permissions = sdkPerms;
|
|
8136
|
+
}
|
|
8137
|
+
}
|
|
8138
|
+
return sdk;
|
|
8139
|
+
}
|
|
8115
8140
|
var AgentConfigMaterializer = class {
|
|
8116
8141
|
apiUrl;
|
|
8117
8142
|
instanceId;
|
|
@@ -8215,10 +8240,26 @@ var AgentConfigMaterializer = class {
|
|
|
8215
8240
|
"utf-8"
|
|
8216
8241
|
);
|
|
8217
8242
|
}
|
|
8218
|
-
if (agent.
|
|
8243
|
+
if (agent.memory && agent.memory.length > 0) {
|
|
8244
|
+
const sdkMemoryDir = getSdkMemoryPath(agent.id);
|
|
8245
|
+
await fs2.mkdir(sdkMemoryDir, { recursive: true });
|
|
8246
|
+
for (const [index, mem] of agent.memory.entries()) {
|
|
8247
|
+
const filename = sanitizeAgentAssetFilename(
|
|
8248
|
+
mem.filename,
|
|
8249
|
+
`memory-${index + 1}.md`
|
|
8250
|
+
);
|
|
8251
|
+
await fs2.writeFile(
|
|
8252
|
+
path3.join(sdkMemoryDir, filename),
|
|
8253
|
+
mem.content,
|
|
8254
|
+
"utf-8"
|
|
8255
|
+
);
|
|
8256
|
+
}
|
|
8257
|
+
}
|
|
8258
|
+
const sdkSettings = buildSdkSettings(agent.settings);
|
|
8259
|
+
if (Object.keys(sdkSettings).length > 0) {
|
|
8219
8260
|
await fs2.writeFile(
|
|
8220
8261
|
settingsPath,
|
|
8221
|
-
JSON.stringify(
|
|
8262
|
+
JSON.stringify(sdkSettings, null, 2),
|
|
8222
8263
|
"utf-8"
|
|
8223
8264
|
);
|
|
8224
8265
|
} else {
|
|
@@ -8257,7 +8298,7 @@ function resolveClaudeCodeExecutable() {
|
|
|
8257
8298
|
return `${sdkDir}/cli.js`;
|
|
8258
8299
|
}
|
|
8259
8300
|
async function runAgent(opts) {
|
|
8260
|
-
const { agentDir, prompt, sessionId, maxTurns, mcpServers, onMessage, abortController } = opts;
|
|
8301
|
+
const { agentDir, prompt, sessionId, maxTurns, permissionMode, model, allowedTools, mcpServers, onMessage, abortController } = opts;
|
|
8261
8302
|
try {
|
|
8262
8303
|
const stream = query({
|
|
8263
8304
|
prompt,
|
|
@@ -8267,6 +8308,10 @@ async function runAgent(opts) {
|
|
|
8267
8308
|
// Full path to node — launchd doesn't have node in PATH
|
|
8268
8309
|
cwd: agentDir,
|
|
8269
8310
|
settingSources: ["project"],
|
|
8311
|
+
...permissionMode ? { permissionMode } : {},
|
|
8312
|
+
...permissionMode === "bypassPermissions" ? { allowDangerouslySkipPermissions: true } : {},
|
|
8313
|
+
...model ? { model } : {},
|
|
8314
|
+
...allowedTools && allowedTools.length > 0 ? { allowedTools } : {},
|
|
8270
8315
|
...sessionId ? { resume: sessionId } : {},
|
|
8271
8316
|
...typeof maxTurns === "number" ? { maxTurns } : {},
|
|
8272
8317
|
...mcpServers ? { mcpServers } : {},
|
|
@@ -9067,10 +9112,10 @@ function mergeDefs(...defs) {
|
|
|
9067
9112
|
function cloneDef(schema) {
|
|
9068
9113
|
return mergeDefs(schema._zod.def);
|
|
9069
9114
|
}
|
|
9070
|
-
function getElementAtPath(obj,
|
|
9071
|
-
if (!
|
|
9115
|
+
function getElementAtPath(obj, path20) {
|
|
9116
|
+
if (!path20)
|
|
9072
9117
|
return obj;
|
|
9073
|
-
return
|
|
9118
|
+
return path20.reduce((acc, key) => acc?.[key], obj);
|
|
9074
9119
|
}
|
|
9075
9120
|
function promiseAllObject(promisesObj) {
|
|
9076
9121
|
const keys = Object.keys(promisesObj);
|
|
@@ -9436,11 +9481,11 @@ function aborted(x, startIndex = 0) {
|
|
|
9436
9481
|
}
|
|
9437
9482
|
return false;
|
|
9438
9483
|
}
|
|
9439
|
-
function prefixIssues(
|
|
9484
|
+
function prefixIssues(path20, issues) {
|
|
9440
9485
|
return issues.map((iss) => {
|
|
9441
9486
|
var _a2;
|
|
9442
9487
|
(_a2 = iss).path ?? (_a2.path = []);
|
|
9443
|
-
iss.path.unshift(
|
|
9488
|
+
iss.path.unshift(path20);
|
|
9444
9489
|
return iss;
|
|
9445
9490
|
});
|
|
9446
9491
|
}
|
|
@@ -9602,7 +9647,7 @@ function formatError(error46, mapper = (issue2) => issue2.message) {
|
|
|
9602
9647
|
}
|
|
9603
9648
|
function treeifyError(error46, mapper = (issue2) => issue2.message) {
|
|
9604
9649
|
const result = { errors: [] };
|
|
9605
|
-
const processError = (error47,
|
|
9650
|
+
const processError = (error47, path20 = []) => {
|
|
9606
9651
|
var _a2, _b;
|
|
9607
9652
|
for (const issue2 of error47.issues) {
|
|
9608
9653
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
@@ -9612,7 +9657,7 @@ function treeifyError(error46, mapper = (issue2) => issue2.message) {
|
|
|
9612
9657
|
} else if (issue2.code === "invalid_element") {
|
|
9613
9658
|
processError({ issues: issue2.issues }, issue2.path);
|
|
9614
9659
|
} else {
|
|
9615
|
-
const fullpath = [...
|
|
9660
|
+
const fullpath = [...path20, ...issue2.path];
|
|
9616
9661
|
if (fullpath.length === 0) {
|
|
9617
9662
|
result.errors.push(mapper(issue2));
|
|
9618
9663
|
continue;
|
|
@@ -9644,8 +9689,8 @@ function treeifyError(error46, mapper = (issue2) => issue2.message) {
|
|
|
9644
9689
|
}
|
|
9645
9690
|
function toDotPath(_path) {
|
|
9646
9691
|
const segs = [];
|
|
9647
|
-
const
|
|
9648
|
-
for (const seg of
|
|
9692
|
+
const path20 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
|
|
9693
|
+
for (const seg of path20) {
|
|
9649
9694
|
if (typeof seg === "number")
|
|
9650
9695
|
segs.push(`[${seg}]`);
|
|
9651
9696
|
else if (typeof seg === "symbol")
|
|
@@ -20981,23 +21026,23 @@ function date4(params) {
|
|
|
20981
21026
|
config(en_default());
|
|
20982
21027
|
|
|
20983
21028
|
// src/agents/mcp-server.ts
|
|
20984
|
-
async function apiGet(apiUrl,
|
|
20985
|
-
const res = await fetch(`${apiUrl}${
|
|
21029
|
+
async function apiGet(apiUrl, path20, headers) {
|
|
21030
|
+
const res = await fetch(`${apiUrl}${path20}`, {
|
|
20986
21031
|
headers: { ...headers, "Content-Type": "application/json" }
|
|
20987
21032
|
});
|
|
20988
21033
|
if (!res.ok) {
|
|
20989
|
-
throw new Error(`API GET ${
|
|
21034
|
+
throw new Error(`API GET ${path20} failed: HTTP ${res.status}`);
|
|
20990
21035
|
}
|
|
20991
21036
|
return res.json();
|
|
20992
21037
|
}
|
|
20993
|
-
async function apiPost(apiUrl,
|
|
20994
|
-
const res = await fetch(`${apiUrl}${
|
|
21038
|
+
async function apiPost(apiUrl, path20, body, headers) {
|
|
21039
|
+
const res = await fetch(`${apiUrl}${path20}`, {
|
|
20995
21040
|
method: "POST",
|
|
20996
21041
|
headers: { ...headers, "Content-Type": "application/json" },
|
|
20997
21042
|
body: JSON.stringify(body)
|
|
20998
21043
|
});
|
|
20999
21044
|
if (!res.ok) {
|
|
21000
|
-
throw new Error(`API POST ${
|
|
21045
|
+
throw new Error(`API POST ${path20} failed: HTTP ${res.status}`);
|
|
21001
21046
|
}
|
|
21002
21047
|
return res.json();
|
|
21003
21048
|
}
|
|
@@ -21123,6 +21168,7 @@ var AgentScheduler = class {
|
|
|
21123
21168
|
// src/agents/service.ts
|
|
21124
21169
|
import { randomUUID } from "crypto";
|
|
21125
21170
|
import fs4 from "fs/promises";
|
|
21171
|
+
import path5 from "path";
|
|
21126
21172
|
|
|
21127
21173
|
// ../../node_modules/ws/wrapper.mjs
|
|
21128
21174
|
var import_stream = __toESM(require_stream(), 1);
|
|
@@ -21563,11 +21609,15 @@ var AgentService = class _AgentService {
|
|
|
21563
21609
|
instanceId: this.instanceId,
|
|
21564
21610
|
token: this.token
|
|
21565
21611
|
});
|
|
21612
|
+
const { permissionMode, model, allowedTools } = extractSdkOptions(config2);
|
|
21566
21613
|
const result = await runAgent({
|
|
21567
21614
|
agentDir,
|
|
21568
21615
|
prompt,
|
|
21569
21616
|
sessionId: previousSessionId,
|
|
21570
21617
|
maxTurns: typeof config2?.maxTurns === "number" ? config2.maxTurns : void 0,
|
|
21618
|
+
permissionMode,
|
|
21619
|
+
model,
|
|
21620
|
+
allowedTools,
|
|
21571
21621
|
mcpServers: { workle: mcpServer },
|
|
21572
21622
|
abortController,
|
|
21573
21623
|
onMessage: (message) => {
|
|
@@ -21718,6 +21768,12 @@ var AgentService = class _AgentService {
|
|
|
21718
21768
|
if (resumeSession && result.sessionId) {
|
|
21719
21769
|
await saveSessionId(agentId, result.sessionId);
|
|
21720
21770
|
}
|
|
21771
|
+
void this.pushMemoryFiles(agentId).catch((err) => {
|
|
21772
|
+
console.error(
|
|
21773
|
+
`[agents] Failed to push memory for ${agentId}:`,
|
|
21774
|
+
err instanceof Error ? err.message : err
|
|
21775
|
+
);
|
|
21776
|
+
});
|
|
21721
21777
|
return result;
|
|
21722
21778
|
})();
|
|
21723
21779
|
this.activeRuns.set(agentId, runPromise);
|
|
@@ -21759,6 +21815,28 @@ var AgentService = class _AgentService {
|
|
|
21759
21815
|
this.activeAborts.delete(runExecutionId);
|
|
21760
21816
|
}
|
|
21761
21817
|
}
|
|
21818
|
+
/**
|
|
21819
|
+
* Re-sync all agent configs from the cloud.
|
|
21820
|
+
* Called on relay reconnect to catch any config.updated events
|
|
21821
|
+
* that were missed while the relay was disconnected.
|
|
21822
|
+
*/
|
|
21823
|
+
async resyncAllConfigs() {
|
|
21824
|
+
console.log("[agents] Re-syncing all agent configs...");
|
|
21825
|
+
const stubs = await this.materializer.listAgents();
|
|
21826
|
+
let synced = 0;
|
|
21827
|
+
for (const stub of stubs) {
|
|
21828
|
+
try {
|
|
21829
|
+
await this.syncAgentConfig(stub.id);
|
|
21830
|
+
synced++;
|
|
21831
|
+
} catch (err) {
|
|
21832
|
+
console.error(
|
|
21833
|
+
`[agents] Failed to re-sync agent ${stub.id}:`,
|
|
21834
|
+
err instanceof Error ? err.message : err
|
|
21835
|
+
);
|
|
21836
|
+
}
|
|
21837
|
+
}
|
|
21838
|
+
console.log(`[agents] Re-synced ${synced}/${stubs.length} agent config(s)`);
|
|
21839
|
+
}
|
|
21762
21840
|
/**
|
|
21763
21841
|
* Graceful shutdown.
|
|
21764
21842
|
*/
|
|
@@ -21788,6 +21866,7 @@ var AgentService = class _AgentService {
|
|
|
21788
21866
|
}
|
|
21789
21867
|
// ── Internal ────────────────────────────────────────────────────────────
|
|
21790
21868
|
handleRelayMessage(msg) {
|
|
21869
|
+
console.log(`[agents] handleRelayMessage: type=${msg.type}`);
|
|
21791
21870
|
if (msg.type === "agent.trigger") {
|
|
21792
21871
|
const frame = msg;
|
|
21793
21872
|
const { agentId, prompt, executionId, resumeSession } = frame.payload;
|
|
@@ -21810,6 +21889,39 @@ var AgentService = class _AgentService {
|
|
|
21810
21889
|
}
|
|
21811
21890
|
}
|
|
21812
21891
|
}
|
|
21892
|
+
/**
|
|
21893
|
+
* Scan the SDK auto-memory directory and push files back to the cloud.
|
|
21894
|
+
* The SDK writes auto-memory to ~/.claude/projects/{encoded-cwd}/memory/.
|
|
21895
|
+
*/
|
|
21896
|
+
async pushMemoryFiles(agentId) {
|
|
21897
|
+
const memoryDir = getSdkMemoryPath(agentId);
|
|
21898
|
+
let entries;
|
|
21899
|
+
try {
|
|
21900
|
+
entries = await fs4.readdir(memoryDir);
|
|
21901
|
+
} catch {
|
|
21902
|
+
return;
|
|
21903
|
+
}
|
|
21904
|
+
const mdFiles = entries.filter((f) => f.endsWith(".md"));
|
|
21905
|
+
if (mdFiles.length === 0) return;
|
|
21906
|
+
const files = [];
|
|
21907
|
+
for (const filename of mdFiles) {
|
|
21908
|
+
const content = await fs4.readFile(path5.join(memoryDir, filename), "utf-8");
|
|
21909
|
+
files.push({ filename, content });
|
|
21910
|
+
}
|
|
21911
|
+
const headers = createAuthHeaders(this.token);
|
|
21912
|
+
const res = await fetch(
|
|
21913
|
+
`${this.apiUrl}/api/claw/instances/${this.instanceId}/runtime/agents/${agentId}/push-memory`,
|
|
21914
|
+
{
|
|
21915
|
+
method: "POST",
|
|
21916
|
+
headers: { ...headers, "Content-Type": "application/json" },
|
|
21917
|
+
body: JSON.stringify({ files })
|
|
21918
|
+
}
|
|
21919
|
+
);
|
|
21920
|
+
if (!res.ok) {
|
|
21921
|
+
throw new Error(`Push memory failed: HTTP ${res.status}`);
|
|
21922
|
+
}
|
|
21923
|
+
console.log(`[agents] Pushed ${files.length} memory file(s) for agent ${agentId}`);
|
|
21924
|
+
}
|
|
21813
21925
|
async resyncAgent(agentId) {
|
|
21814
21926
|
try {
|
|
21815
21927
|
await this.syncAgentConfig(agentId);
|
|
@@ -21861,6 +21973,37 @@ var AgentService = class _AgentService {
|
|
|
21861
21973
|
this.updateSchedules(schedules);
|
|
21862
21974
|
}
|
|
21863
21975
|
};
|
|
21976
|
+
var VALID_PERMISSION_MODES = /* @__PURE__ */ new Set([
|
|
21977
|
+
"default",
|
|
21978
|
+
"acceptEdits",
|
|
21979
|
+
"bypassPermissions",
|
|
21980
|
+
"plan",
|
|
21981
|
+
"dontAsk"
|
|
21982
|
+
]);
|
|
21983
|
+
function extractSdkOptions(config2) {
|
|
21984
|
+
const settings = config2?.settings;
|
|
21985
|
+
if (!settings || typeof settings !== "object") {
|
|
21986
|
+
return { permissionMode: void 0, model: void 0, allowedTools: void 0 };
|
|
21987
|
+
}
|
|
21988
|
+
const s = settings;
|
|
21989
|
+
let permissionMode;
|
|
21990
|
+
const perms = s.permissions;
|
|
21991
|
+
if (perms && typeof perms === "object" && perms !== null) {
|
|
21992
|
+
const defaultMode = perms.defaultMode;
|
|
21993
|
+
if (typeof defaultMode === "string" && VALID_PERMISSION_MODES.has(defaultMode)) {
|
|
21994
|
+
permissionMode = defaultMode;
|
|
21995
|
+
}
|
|
21996
|
+
}
|
|
21997
|
+
const model = typeof s.model === "string" && s.model.length > 0 ? s.model : void 0;
|
|
21998
|
+
let allowedTools;
|
|
21999
|
+
if (perms && typeof perms === "object" && perms !== null) {
|
|
22000
|
+
const allow = perms.allow;
|
|
22001
|
+
if (Array.isArray(allow) && allow.length > 0) {
|
|
22002
|
+
allowedTools = allow.filter((t) => typeof t === "string");
|
|
22003
|
+
}
|
|
22004
|
+
}
|
|
22005
|
+
return { permissionMode, model, allowedTools };
|
|
22006
|
+
}
|
|
21864
22007
|
async function createAgentService() {
|
|
21865
22008
|
const auth = await loadAuth();
|
|
21866
22009
|
return new AgentService({
|
|
@@ -21875,10 +22018,10 @@ import { spawn } from "child_process";
|
|
|
21875
22018
|
import fs5 from "fs/promises";
|
|
21876
22019
|
import http from "http";
|
|
21877
22020
|
import os5 from "os";
|
|
21878
|
-
import
|
|
21879
|
-
var CLAW_HOME =
|
|
21880
|
-
var LOG_FILE =
|
|
21881
|
-
var PID_FILE =
|
|
22021
|
+
import path6 from "path";
|
|
22022
|
+
var CLAW_HOME = path6.join(os5.homedir(), ".workle");
|
|
22023
|
+
var LOG_FILE = path6.join(CLAW_HOME, "openclaw.log");
|
|
22024
|
+
var PID_FILE = path6.join(CLAW_HOME, "openclaw.pid");
|
|
21882
22025
|
var OPENCLAW_PORT = 18789;
|
|
21883
22026
|
var HEALTH_CHECK_TIMEOUT = 5e3;
|
|
21884
22027
|
var ProcessManager = class {
|
|
@@ -21891,7 +22034,7 @@ var ProcessManager = class {
|
|
|
21891
22034
|
* @param openclawBinary - Path to the openclaw binary (defaults to "openclaw" in PATH)
|
|
21892
22035
|
* @param configPath - Path to openclaw.json config (defaults to ~/.workle/openclaw.json)
|
|
21893
22036
|
*/
|
|
21894
|
-
async spawn(openclawBinary = "openclaw", configPath =
|
|
22037
|
+
async spawn(openclawBinary = "openclaw", configPath = path6.join(CLAW_HOME, "openclaw.json")) {
|
|
21895
22038
|
if (this.process) {
|
|
21896
22039
|
console.log("[claw] OpenClaw process already running");
|
|
21897
22040
|
return;
|
|
@@ -22023,8 +22166,8 @@ var ProcessManager = class {
|
|
|
22023
22166
|
import { execSync } from "child_process";
|
|
22024
22167
|
import fs6 from "fs/promises";
|
|
22025
22168
|
import os6 from "os";
|
|
22026
|
-
import
|
|
22027
|
-
var WORKLE_HOME2 =
|
|
22169
|
+
import path7 from "path";
|
|
22170
|
+
var WORKLE_HOME2 = path7.join(os6.homedir(), ".workle");
|
|
22028
22171
|
var MIN_NODE_MAJOR = 22;
|
|
22029
22172
|
async function runDoctor() {
|
|
22030
22173
|
const checks = [];
|
|
@@ -22107,7 +22250,7 @@ async function checkClawHome() {
|
|
|
22107
22250
|
}
|
|
22108
22251
|
}
|
|
22109
22252
|
async function checkAuthFile() {
|
|
22110
|
-
const authPath =
|
|
22253
|
+
const authPath = path7.join(WORKLE_HOME2, "auth.json");
|
|
22111
22254
|
try {
|
|
22112
22255
|
const raw = await fs6.readFile(authPath, "utf-8");
|
|
22113
22256
|
const parsed = JSON.parse(raw);
|
|
@@ -22132,7 +22275,7 @@ async function checkAuthFile() {
|
|
|
22132
22275
|
}
|
|
22133
22276
|
}
|
|
22134
22277
|
async function checkConfigFile() {
|
|
22135
|
-
const configPath =
|
|
22278
|
+
const configPath = path7.join(WORKLE_HOME2, "openclaw.json");
|
|
22136
22279
|
try {
|
|
22137
22280
|
const raw = await fs6.readFile(configPath, "utf-8");
|
|
22138
22281
|
const parsed = JSON.parse(raw);
|
|
@@ -22181,25 +22324,25 @@ async function checkGatewayReachable() {
|
|
|
22181
22324
|
// src/lifecycle/install.ts
|
|
22182
22325
|
import fs7 from "fs/promises";
|
|
22183
22326
|
import os7 from "os";
|
|
22184
|
-
import
|
|
22185
|
-
var WORKLE_HOME3 =
|
|
22186
|
-
var LAUNCH_AGENTS_DIR =
|
|
22187
|
-
var STAGED_CLI_PATH =
|
|
22327
|
+
import path8 from "path";
|
|
22328
|
+
var WORKLE_HOME3 = path8.join(os7.homedir(), ".workle");
|
|
22329
|
+
var LAUNCH_AGENTS_DIR = path8.join(os7.homedir(), "Library", "LaunchAgents");
|
|
22330
|
+
var STAGED_CLI_PATH = path8.join(WORKLE_HOME3, "bin", "cli.js");
|
|
22188
22331
|
function escapeXml(value) {
|
|
22189
22332
|
return value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
22190
22333
|
}
|
|
22191
22334
|
async function setupClawDirectory() {
|
|
22192
22335
|
const dirs = [
|
|
22193
22336
|
WORKLE_HOME3,
|
|
22194
|
-
|
|
22195
|
-
|
|
22337
|
+
path8.join(WORKLE_HOME3, "logs"),
|
|
22338
|
+
path8.join(WORKLE_HOME3, "bin")
|
|
22196
22339
|
];
|
|
22197
22340
|
for (const dir of dirs) {
|
|
22198
22341
|
await fs7.mkdir(dir, { recursive: true, mode: 448 });
|
|
22199
22342
|
await fs7.chmod(dir, 448).catch(() => {
|
|
22200
22343
|
});
|
|
22201
22344
|
}
|
|
22202
|
-
const gitignorePath =
|
|
22345
|
+
const gitignorePath = path8.join(WORKLE_HOME3, ".gitignore");
|
|
22203
22346
|
try {
|
|
22204
22347
|
await fs7.access(gitignorePath);
|
|
22205
22348
|
} catch {
|
|
@@ -22223,7 +22366,7 @@ async function stageCliForDaemon(currentCliPath) {
|
|
|
22223
22366
|
}
|
|
22224
22367
|
async function writeLaunchdPlist(serviceName = "com.workle.claw", executable = process.execPath, args = [STAGED_CLI_PATH, "start"]) {
|
|
22225
22368
|
await fs7.mkdir(LAUNCH_AGENTS_DIR, { recursive: true });
|
|
22226
|
-
const plistPath =
|
|
22369
|
+
const plistPath = path8.join(LAUNCH_AGENTS_DIR, `${serviceName}.plist`);
|
|
22227
22370
|
const programArguments = [executable, ...args].map((arg) => ` <string>${escapeXml(arg)}</string>`).join("\n");
|
|
22228
22371
|
const plist = `<?xml version="1.0" encoding="UTF-8"?>
|
|
22229
22372
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
@@ -22247,10 +22390,10 @@ ${programArguments}
|
|
|
22247
22390
|
</dict>
|
|
22248
22391
|
|
|
22249
22392
|
<key>StandardOutPath</key>
|
|
22250
|
-
<string>${
|
|
22393
|
+
<string>${path8.join(WORKLE_HOME3, "logs", "stdout.log")}</string>
|
|
22251
22394
|
|
|
22252
22395
|
<key>StandardErrorPath</key>
|
|
22253
|
-
<string>${
|
|
22396
|
+
<string>${path8.join(WORKLE_HOME3, "logs", "stderr.log")}</string>
|
|
22254
22397
|
|
|
22255
22398
|
<key>WorkingDirectory</key>
|
|
22256
22399
|
<string>${WORKLE_HOME3}</string>
|
|
@@ -22271,18 +22414,18 @@ ${programArguments}
|
|
|
22271
22414
|
// src/sync/service.ts
|
|
22272
22415
|
import fs15 from "fs/promises";
|
|
22273
22416
|
import os17 from "os";
|
|
22274
|
-
import
|
|
22417
|
+
import path18 from "path";
|
|
22275
22418
|
|
|
22276
22419
|
// src/legacy/openclaw/gateway.ts
|
|
22277
22420
|
import os8 from "os";
|
|
22278
|
-
import
|
|
22279
|
-
var CLAW_HOME2 =
|
|
22421
|
+
import path9 from "path";
|
|
22422
|
+
var CLAW_HOME2 = path9.join(os8.homedir(), ".workle");
|
|
22280
22423
|
function generateGatewayConfig(_instance, agents) {
|
|
22281
22424
|
const sorted = [...agents].sort((a, b) => a.sortOrder - b.sortOrder);
|
|
22282
22425
|
const list = sorted.map((agent) => ({
|
|
22283
22426
|
id: agent.id,
|
|
22284
22427
|
default: !agent.isSubAgent,
|
|
22285
|
-
workspace:
|
|
22428
|
+
workspace: path9.join(CLAW_HOME2, `workspace-${agent.agentKey}`),
|
|
22286
22429
|
model: agent.model,
|
|
22287
22430
|
toolProfile: agent.toolProfile,
|
|
22288
22431
|
promptMode: agent.promptMode
|
|
@@ -22295,8 +22438,8 @@ function generateGatewayConfig(_instance, agents) {
|
|
|
22295
22438
|
// src/legacy/openclaw/soul.ts
|
|
22296
22439
|
import fs8 from "fs/promises";
|
|
22297
22440
|
import os9 from "os";
|
|
22298
|
-
import
|
|
22299
|
-
var CLAW_HOME3 =
|
|
22441
|
+
import path10 from "path";
|
|
22442
|
+
var CLAW_HOME3 = path10.join(os9.homedir(), ".workle");
|
|
22300
22443
|
var DEFAULT_SOUL_MD = `# Soul
|
|
22301
22444
|
|
|
22302
22445
|
You are a Workle agent. Follow your assigned skills and operational instructions.
|
|
@@ -22308,17 +22451,17 @@ async function writeSoulMd(agentKey, content, rpcCall) {
|
|
|
22308
22451
|
await rpcCall(agentKey, "SOUL.md", body);
|
|
22309
22452
|
return;
|
|
22310
22453
|
}
|
|
22311
|
-
const workspaceDir =
|
|
22454
|
+
const workspaceDir = path10.join(CLAW_HOME3, `workspace-${agentKey}`);
|
|
22312
22455
|
await fs8.mkdir(workspaceDir, { recursive: true });
|
|
22313
|
-
const filePath =
|
|
22456
|
+
const filePath = path10.join(workspaceDir, "SOUL.md");
|
|
22314
22457
|
await fs8.writeFile(filePath, body, "utf-8");
|
|
22315
22458
|
}
|
|
22316
22459
|
|
|
22317
22460
|
// src/legacy/openclaw/agents.ts
|
|
22318
22461
|
import fs9 from "fs/promises";
|
|
22319
22462
|
import os10 from "os";
|
|
22320
|
-
import
|
|
22321
|
-
var CLAW_HOME4 =
|
|
22463
|
+
import path11 from "path";
|
|
22464
|
+
var CLAW_HOME4 = path11.join(os10.homedir(), ".workle");
|
|
22322
22465
|
var DEFAULT_AGENTS_MD = `# Agents
|
|
22323
22466
|
|
|
22324
22467
|
No additional agent configuration provided.
|
|
@@ -22329,17 +22472,17 @@ async function writeAgentsMd(agentKey, content, rpcCall) {
|
|
|
22329
22472
|
await rpcCall(agentKey, "AGENTS.md", body);
|
|
22330
22473
|
return;
|
|
22331
22474
|
}
|
|
22332
|
-
const workspaceDir =
|
|
22475
|
+
const workspaceDir = path11.join(CLAW_HOME4, `workspace-${agentKey}`);
|
|
22333
22476
|
await fs9.mkdir(workspaceDir, { recursive: true });
|
|
22334
|
-
const filePath =
|
|
22477
|
+
const filePath = path11.join(workspaceDir, "AGENTS.md");
|
|
22335
22478
|
await fs9.writeFile(filePath, body, "utf-8");
|
|
22336
22479
|
}
|
|
22337
22480
|
|
|
22338
22481
|
// src/config/identity.ts
|
|
22339
22482
|
import fs10 from "fs/promises";
|
|
22340
22483
|
import os11 from "os";
|
|
22341
|
-
import
|
|
22342
|
-
var WORKLE_HOME4 =
|
|
22484
|
+
import path12 from "path";
|
|
22485
|
+
var WORKLE_HOME4 = path12.join(os11.homedir(), ".workle");
|
|
22343
22486
|
var DEFAULT_IDENTITY_MD = `# Identity
|
|
22344
22487
|
|
|
22345
22488
|
No identity configuration provided.
|
|
@@ -22350,17 +22493,17 @@ async function writeIdentityMd(agentKey, content, rpcCall) {
|
|
|
22350
22493
|
await rpcCall(agentKey, "IDENTITY.md", body);
|
|
22351
22494
|
return;
|
|
22352
22495
|
}
|
|
22353
|
-
const workspaceDir =
|
|
22496
|
+
const workspaceDir = path12.join(WORKLE_HOME4, `workspace-${agentKey}`);
|
|
22354
22497
|
await fs10.mkdir(workspaceDir, { recursive: true });
|
|
22355
|
-
const filePath =
|
|
22498
|
+
const filePath = path12.join(workspaceDir, "IDENTITY.md");
|
|
22356
22499
|
await fs10.writeFile(filePath, body, "utf-8");
|
|
22357
22500
|
}
|
|
22358
22501
|
|
|
22359
22502
|
// src/config/heartbeat.ts
|
|
22360
22503
|
import fs11 from "fs/promises";
|
|
22361
22504
|
import os12 from "os";
|
|
22362
|
-
import
|
|
22363
|
-
var WORKLE_HOME5 =
|
|
22505
|
+
import path13 from "path";
|
|
22506
|
+
var WORKLE_HOME5 = path13.join(os12.homedir(), ".workle");
|
|
22364
22507
|
var DEFAULT_HEARTBEAT_MD = `# Heartbeat
|
|
22365
22508
|
|
|
22366
22509
|
No heartbeat configuration provided.
|
|
@@ -22371,34 +22514,34 @@ async function writeHeartbeatMd(agentKey, content, rpcCall) {
|
|
|
22371
22514
|
await rpcCall(agentKey, "HEARTBEAT.md", body);
|
|
22372
22515
|
return;
|
|
22373
22516
|
}
|
|
22374
|
-
const workspaceDir =
|
|
22517
|
+
const workspaceDir = path13.join(WORKLE_HOME5, `workspace-${agentKey}`);
|
|
22375
22518
|
await fs11.mkdir(workspaceDir, { recursive: true });
|
|
22376
|
-
const filePath =
|
|
22519
|
+
const filePath = path13.join(workspaceDir, "HEARTBEAT.md");
|
|
22377
22520
|
await fs11.writeFile(filePath, body, "utf-8");
|
|
22378
22521
|
}
|
|
22379
22522
|
|
|
22380
22523
|
// src/config/skills.ts
|
|
22381
22524
|
import fs12 from "fs/promises";
|
|
22382
22525
|
import os13 from "os";
|
|
22383
|
-
import
|
|
22384
|
-
var WORKLE_HOME6 =
|
|
22526
|
+
import path14 from "path";
|
|
22527
|
+
var WORKLE_HOME6 = path14.join(os13.homedir(), ".workle");
|
|
22385
22528
|
|
|
22386
22529
|
// src/legacy/openclaw/rpc.ts
|
|
22387
22530
|
import crypto4 from "crypto";
|
|
22388
22531
|
import fs13 from "fs";
|
|
22389
22532
|
import os14 from "os";
|
|
22390
|
-
import
|
|
22533
|
+
import path15 from "path";
|
|
22391
22534
|
var OPENCLAW_PORT2 = 18789;
|
|
22392
22535
|
var OPENCLAW_URL = `ws://127.0.0.1:${OPENCLAW_PORT2}`;
|
|
22393
22536
|
var RPC_TIMEOUT = 3e4;
|
|
22394
22537
|
var MAX_RECONNECT_BACKOFF = 1e4;
|
|
22395
22538
|
var CLAW_VERSION = "0.1.16";
|
|
22396
22539
|
var OPENCLAW_CONFIG_PATHS = [
|
|
22397
|
-
() =>
|
|
22398
|
-
() =>
|
|
22540
|
+
() => path15.join(os14.homedir(), ".openclaw", "openclaw.json"),
|
|
22541
|
+
() => path15.join(os14.homedir(), ".config", "openclaw", "openclaw.json")
|
|
22399
22542
|
];
|
|
22400
|
-
var CLAW_IDENTITY_DIR =
|
|
22401
|
-
var CLAW_IDENTITY_FILE =
|
|
22543
|
+
var CLAW_IDENTITY_DIR = path15.join(os14.homedir(), ".workle");
|
|
22544
|
+
var CLAW_IDENTITY_FILE = path15.join(CLAW_IDENTITY_DIR, "device-identity.json");
|
|
22402
22545
|
var ED25519_SPKI_PREFIX = Buffer.from("302a300506032b6570032100", "hex");
|
|
22403
22546
|
function base64UrlEncode(buf) {
|
|
22404
22547
|
return buf.toString("base64").replaceAll("+", "-").replaceAll("/", "_").replace(/=+$/g, "");
|
|
@@ -22907,17 +23050,17 @@ async function agentDiscovery(rpc, apiUrl, instanceId, token) {
|
|
|
22907
23050
|
|
|
22908
23051
|
// src/sync/events.ts
|
|
22909
23052
|
import os16 from "os";
|
|
22910
|
-
import
|
|
23053
|
+
import path17 from "path";
|
|
22911
23054
|
|
|
22912
23055
|
// src/sync/queue.ts
|
|
22913
23056
|
import fs14 from "fs/promises";
|
|
22914
23057
|
import os15 from "os";
|
|
22915
|
-
import
|
|
23058
|
+
import path16 from "path";
|
|
22916
23059
|
var MAX_FILE_SIZE = 5e8;
|
|
22917
23060
|
var PersistentEventQueue = class {
|
|
22918
23061
|
filePath;
|
|
22919
23062
|
constructor(customPath) {
|
|
22920
|
-
this.filePath = customPath ??
|
|
23063
|
+
this.filePath = customPath ?? path16.join(os15.homedir(), ".workle", "pending-events.jsonl");
|
|
22921
23064
|
}
|
|
22922
23065
|
/**
|
|
22923
23066
|
* Append a single entry to the queue file.
|
|
@@ -22984,7 +23127,7 @@ var PersistentEventQueue = class {
|
|
|
22984
23127
|
}
|
|
22985
23128
|
// --- Internal ---
|
|
22986
23129
|
async ensureDir() {
|
|
22987
|
-
const dir =
|
|
23130
|
+
const dir = path16.dirname(this.filePath);
|
|
22988
23131
|
await fs14.mkdir(dir, { recursive: true });
|
|
22989
23132
|
}
|
|
22990
23133
|
/**
|
|
@@ -23012,7 +23155,7 @@ var PersistentEventQueue = class {
|
|
|
23012
23155
|
};
|
|
23013
23156
|
|
|
23014
23157
|
// src/sync/events.ts
|
|
23015
|
-
var WORKLE_HOME7 =
|
|
23158
|
+
var WORKLE_HOME7 = path17.join(os16.homedir(), ".workle");
|
|
23016
23159
|
var EVENT_TYPE_MAP = {
|
|
23017
23160
|
"agent.run": "agent.started",
|
|
23018
23161
|
"agent.run.complete": "agent.completed",
|
|
@@ -23053,7 +23196,7 @@ function getQueue(instanceId) {
|
|
|
23053
23196
|
const existing = sharedQueues.get(queueKey);
|
|
23054
23197
|
if (existing) return existing;
|
|
23055
23198
|
const queue = new PersistentEventQueue(
|
|
23056
|
-
|
|
23199
|
+
path17.join(WORKLE_HOME7, `pending-events-${queueKey}.jsonl`)
|
|
23057
23200
|
);
|
|
23058
23201
|
sharedQueues.set(queueKey, queue);
|
|
23059
23202
|
return queue;
|
|
@@ -23116,7 +23259,7 @@ async function replayPendingEvents(apiUrl, token, instanceId) {
|
|
|
23116
23259
|
}
|
|
23117
23260
|
|
|
23118
23261
|
// src/sync/service.ts
|
|
23119
|
-
var WORKLE_HOME8 =
|
|
23262
|
+
var WORKLE_HOME8 = path18.join(os17.homedir(), ".workle");
|
|
23120
23263
|
function deriveRelayUrl2(apiUrl) {
|
|
23121
23264
|
const url2 = new URL(apiUrl);
|
|
23122
23265
|
url2.protocol = url2.protocol === "https:" ? "wss:" : "ws:";
|
|
@@ -23137,6 +23280,7 @@ var SyncService = class {
|
|
|
23137
23280
|
unsubscribeRelayMessages = null;
|
|
23138
23281
|
running = false;
|
|
23139
23282
|
externalMessageHandler = null;
|
|
23283
|
+
reconnectHandler = null;
|
|
23140
23284
|
/**
|
|
23141
23285
|
* Register a handler for relay messages that SyncService doesn't handle
|
|
23142
23286
|
* (e.g. agent.trigger, agent.cancel, agent.config.updated).
|
|
@@ -23145,6 +23289,14 @@ var SyncService = class {
|
|
|
23145
23289
|
onRelayMessage(handler) {
|
|
23146
23290
|
this.externalMessageHandler = handler;
|
|
23147
23291
|
}
|
|
23292
|
+
/**
|
|
23293
|
+
* Register a handler called after relay reconnects.
|
|
23294
|
+
* Used by AgentService to re-sync all agent configs on reconnect,
|
|
23295
|
+
* catching any agent.config.updated events missed during disconnect.
|
|
23296
|
+
*/
|
|
23297
|
+
onReconnect(handler) {
|
|
23298
|
+
this.reconnectHandler = handler;
|
|
23299
|
+
}
|
|
23148
23300
|
/**
|
|
23149
23301
|
* Send a message through the relay WebSocket connection.
|
|
23150
23302
|
* Used by AgentService in embedded mode to send progress/result frames.
|
|
@@ -23233,6 +23385,13 @@ var SyncService = class {
|
|
|
23233
23385
|
} catch (err) {
|
|
23234
23386
|
console.error("[claw] Event replay on connect failed:", err);
|
|
23235
23387
|
}
|
|
23388
|
+
if (this.reconnectHandler) {
|
|
23389
|
+
try {
|
|
23390
|
+
await this.reconnectHandler();
|
|
23391
|
+
} catch (err) {
|
|
23392
|
+
console.error("[claw] Agent config re-sync on reconnect failed:", err);
|
|
23393
|
+
}
|
|
23394
|
+
}
|
|
23236
23395
|
})();
|
|
23237
23396
|
}
|
|
23238
23397
|
}
|
|
@@ -23248,6 +23407,7 @@ var SyncService = class {
|
|
|
23248
23407
|
}
|
|
23249
23408
|
this.unsubscribeRelayMessages = this.relayClient.onMessage((msg) => {
|
|
23250
23409
|
if (msg.type !== "rpc.request") {
|
|
23410
|
+
console.log(`[claw] Relay message received: type=${msg.type}`, JSON.stringify(msg).slice(0, 200));
|
|
23251
23411
|
if (this.externalMessageHandler) {
|
|
23252
23412
|
this.externalMessageHandler(msg);
|
|
23253
23413
|
}
|
|
@@ -23469,7 +23629,7 @@ var SyncService = class {
|
|
|
23469
23629
|
}
|
|
23470
23630
|
async writeConfigFiles(instance, agents) {
|
|
23471
23631
|
const gatewayConfig = generateGatewayConfig(instance, agents);
|
|
23472
|
-
const configPath =
|
|
23632
|
+
const configPath = path18.join(WORKLE_HOME8, "openclaw.json");
|
|
23473
23633
|
await fs15.mkdir(WORKLE_HOME8, { recursive: true });
|
|
23474
23634
|
await fs15.writeFile(configPath, JSON.stringify(gatewayConfig, null, 2), "utf-8");
|
|
23475
23635
|
await Promise.all(
|
|
@@ -23484,9 +23644,9 @@ var SyncService = class {
|
|
|
23484
23644
|
};
|
|
23485
23645
|
|
|
23486
23646
|
// src/cli.ts
|
|
23487
|
-
var WORKLE_HOME9 =
|
|
23488
|
-
var AUTH_FILE2 =
|
|
23489
|
-
var LAUNCH_AGENTS_DIR2 =
|
|
23647
|
+
var WORKLE_HOME9 = path19.join(os18.homedir(), ".workle");
|
|
23648
|
+
var AUTH_FILE2 = path19.join(WORKLE_HOME9, "auth.json");
|
|
23649
|
+
var LAUNCH_AGENTS_DIR2 = path19.join(os18.homedir(), "Library", "LaunchAgents");
|
|
23490
23650
|
var PLIST_LABEL = "com.workle.claw";
|
|
23491
23651
|
var color = {
|
|
23492
23652
|
green: (s) => `\x1B[32m${s}\x1B[0m`,
|
|
@@ -23736,7 +23896,7 @@ program2.command("start").description("Start the Workle Claw sync service").opti
|
|
|
23736
23896
|
console.log("");
|
|
23737
23897
|
console.log(` Service: ${color.dim(PLIST_LABEL)}`);
|
|
23738
23898
|
console.log(` Plist: ${color.dim(plistPath)}`);
|
|
23739
|
-
console.log(` Logs: ${color.dim(
|
|
23899
|
+
console.log(` Logs: ${color.dim(path19.join(WORKLE_HOME9, "logs/"))}`);
|
|
23740
23900
|
console.log("");
|
|
23741
23901
|
console.log(
|
|
23742
23902
|
`To stop: ${color.cyan("npx @getworkle/cli stop")}`
|
|
@@ -23781,7 +23941,12 @@ program2.command("start").description("Start the Workle Claw sync service").opti
|
|
|
23781
23941
|
await syncService.start();
|
|
23782
23942
|
try {
|
|
23783
23943
|
agentService = await createAgentService();
|
|
23784
|
-
syncService.onRelayMessage((msg) => agentService
|
|
23944
|
+
syncService.onRelayMessage((msg) => agentService?.ingestRelayMessage(msg));
|
|
23945
|
+
syncService.onReconnect(async () => {
|
|
23946
|
+
if (agentService) {
|
|
23947
|
+
await agentService.resyncAllConfigs();
|
|
23948
|
+
}
|
|
23949
|
+
});
|
|
23785
23950
|
await agentService.startEmbedded((msg) => syncService.sendRelayMessage(msg));
|
|
23786
23951
|
} catch (err) {
|
|
23787
23952
|
console.error(
|
|
@@ -23804,14 +23969,14 @@ program2.command("start").description("Start the Workle Claw sync service").opti
|
|
|
23804
23969
|
}
|
|
23805
23970
|
});
|
|
23806
23971
|
program2.command("stop").description("Stop the Workle Claw daemon").action(async () => {
|
|
23807
|
-
const plistPath =
|
|
23972
|
+
const plistPath = path19.join(LAUNCH_AGENTS_DIR2, `${PLIST_LABEL}.plist`);
|
|
23808
23973
|
try {
|
|
23809
23974
|
execSync2(`launchctl unload "${plistPath}"`, { stdio: "inherit" });
|
|
23810
23975
|
console.log(color.green("\u2713 Daemon stopped"));
|
|
23811
23976
|
} catch {
|
|
23812
23977
|
console.log(color.dim("No launchd service loaded."));
|
|
23813
23978
|
}
|
|
23814
|
-
const pidFile =
|
|
23979
|
+
const pidFile = path19.join(WORKLE_HOME9, "openclaw.pid");
|
|
23815
23980
|
try {
|
|
23816
23981
|
const pidStr = await fs16.readFile(pidFile, "utf-8");
|
|
23817
23982
|
const pid = parseInt(pidStr.trim(), 10);
|
|
@@ -23856,7 +24021,7 @@ program2.command("status").description("Show connection state and instance info"
|
|
|
23856
24021
|
} catch {
|
|
23857
24022
|
console.log(` Gateway: ${color.yellow("unreachable")}`);
|
|
23858
24023
|
}
|
|
23859
|
-
const plistPath =
|
|
24024
|
+
const plistPath = path19.join(LAUNCH_AGENTS_DIR2, `${PLIST_LABEL}.plist`);
|
|
23860
24025
|
try {
|
|
23861
24026
|
await fs16.access(plistPath);
|
|
23862
24027
|
try {
|
|
@@ -23883,8 +24048,8 @@ program2.command("logs").description("Tail the Workle Claw log files").option("-
|
|
|
23883
24048
|
process.exit(1);
|
|
23884
24049
|
}
|
|
23885
24050
|
const logFiles = [
|
|
23886
|
-
|
|
23887
|
-
|
|
24051
|
+
path19.join(WORKLE_HOME9, "openclaw.log"),
|
|
24052
|
+
path19.join(WORKLE_HOME9, "logs", "stderr.log")
|
|
23888
24053
|
];
|
|
23889
24054
|
const args = ["-n", String(lineCount)];
|
|
23890
24055
|
if (opts.follow) args.push("-f");
|
|
@@ -24048,12 +24213,12 @@ agentCmd.command("logs [agentId]").description("Tail agent run logs").option("-n
|
|
|
24048
24213
|
console.error(color.red("Error: --lines must be a positive integer."));
|
|
24049
24214
|
process.exit(1);
|
|
24050
24215
|
}
|
|
24051
|
-
const logsDir =
|
|
24216
|
+
const logsDir = path19.join(WORKLE_HOME9, "agents");
|
|
24052
24217
|
let logFile;
|
|
24053
24218
|
if (agentId) {
|
|
24054
|
-
logFile =
|
|
24219
|
+
logFile = path19.join(logsDir, agentId, "run.log");
|
|
24055
24220
|
} else {
|
|
24056
|
-
logFile =
|
|
24221
|
+
logFile = path19.join(logsDir, "*", "run.log");
|
|
24057
24222
|
}
|
|
24058
24223
|
const args = ["-n", String(lineCount)];
|
|
24059
24224
|
if (opts.follow) args.push("-f");
|