@agentvault/agentvault 0.14.4 → 0.14.6
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 +12 -0
- package/dist/channel.d.ts.map +1 -1
- package/dist/cli.js +360 -26
- package/dist/cli.js.map +4 -4
- package/dist/create-agent.d.ts.map +1 -1
- package/dist/index.js +309 -12
- package/dist/index.js.map +4 -4
- package/dist/workspace-handlers.d.ts +62 -0
- package/dist/workspace-handlers.d.ts.map +1 -0
- package/package.json +1 -1
package/dist/channel.d.ts
CHANGED
|
@@ -13,6 +13,8 @@ export declare class SecureChannel extends EventEmitter {
|
|
|
13
13
|
private _pollTimer;
|
|
14
14
|
private _reconnectAttempt;
|
|
15
15
|
private _reconnectTimer;
|
|
16
|
+
private _rapidDisconnects;
|
|
17
|
+
private _lastWsOpenTime;
|
|
16
18
|
private _pingTimer;
|
|
17
19
|
private _lastServerMessage;
|
|
18
20
|
private _pendingAcks;
|
|
@@ -218,6 +220,16 @@ export declare class SecureChannel extends EventEmitter {
|
|
|
218
220
|
* This allows all owner devices to see messages from any single device.
|
|
219
221
|
*/
|
|
220
222
|
private _relaySyncToSiblings;
|
|
223
|
+
/**
|
|
224
|
+
* Resolve the agent's workspace directory.
|
|
225
|
+
* Looks for OpenClaw workspace config, falls back to default path.
|
|
226
|
+
*/
|
|
227
|
+
private _resolveWorkspaceDir;
|
|
228
|
+
/**
|
|
229
|
+
* Send a structured JSON reply to a specific conversation.
|
|
230
|
+
* Encrypts the payload via the conversation's ratchet and sends via WebSocket.
|
|
231
|
+
*/
|
|
232
|
+
private _sendStructuredReply;
|
|
221
233
|
/**
|
|
222
234
|
* Send stored message history to a newly-activated session.
|
|
223
235
|
* Batches all history into a single encrypted message.
|
package/dist/channel.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"channel.d.ts","sourceRoot":"","sources":["../src/channel.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAQ3C,OAAO,EAWL,iBAAiB,EAClB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,KAAK,EACV,mBAAmB,EACnB,YAAY,EAMZ,WAAW,EACX,eAAe,EACf,gBAAgB,EAChB,eAAe,EACf,WAAW,EACX,cAAc,EACd,oBAAoB,EACpB,QAAQ,EAER,UAAU,EAEX,MAAM,YAAY,CAAC;AAoDpB,qBAAa,aAAc,SAAQ,YAAY;
|
|
1
|
+
{"version":3,"file":"channel.d.ts","sourceRoot":"","sources":["../src/channel.ts"],"names":[],"mappings":"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"}
|
package/dist/cli.js
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
var __defProp = Object.defineProperty;
|
|
3
3
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
+
var __require = /* @__PURE__ */ ((x2) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x2, {
|
|
5
|
+
get: (a2, b2) => (typeof require !== "undefined" ? require : a2)[b2]
|
|
6
|
+
}) : x2)(function(x2) {
|
|
7
|
+
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
8
|
+
throw Error('Dynamic require of "' + x2 + '" is not supported');
|
|
9
|
+
});
|
|
4
10
|
var __esm = (fn, res) => function __init() {
|
|
5
11
|
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
6
12
|
};
|
|
@@ -45023,9 +45029,53 @@ var init_file_crypto = __esm({
|
|
|
45023
45029
|
});
|
|
45024
45030
|
|
|
45025
45031
|
// ../crypto/dist/did.js
|
|
45032
|
+
function canonicalize(obj) {
|
|
45033
|
+
const json = jsonCanonical(obj) ?? "";
|
|
45034
|
+
return libsodium_wrappers_default.from_string(json);
|
|
45035
|
+
}
|
|
45036
|
+
function jsonCanonical(value) {
|
|
45037
|
+
if (value === void 0)
|
|
45038
|
+
return void 0;
|
|
45039
|
+
if (value === null)
|
|
45040
|
+
return "null";
|
|
45041
|
+
if (typeof value === "boolean" || typeof value === "number")
|
|
45042
|
+
return JSON.stringify(value);
|
|
45043
|
+
if (typeof value === "string")
|
|
45044
|
+
return JSON.stringify(value);
|
|
45045
|
+
if (Array.isArray(value)) {
|
|
45046
|
+
return "[" + value.map(jsonCanonical).join(",") + "]";
|
|
45047
|
+
}
|
|
45048
|
+
if (typeof value === "object") {
|
|
45049
|
+
const keys = Object.keys(value).sort();
|
|
45050
|
+
const entries = keys.map((k2) => {
|
|
45051
|
+
const v2 = jsonCanonical(value[k2]);
|
|
45052
|
+
if (v2 === void 0)
|
|
45053
|
+
return void 0;
|
|
45054
|
+
return JSON.stringify(k2) + ":" + v2;
|
|
45055
|
+
}).filter((entry) => entry !== void 0);
|
|
45056
|
+
return "{" + entries.join(",") + "}";
|
|
45057
|
+
}
|
|
45058
|
+
return JSON.stringify(value);
|
|
45059
|
+
}
|
|
45060
|
+
async function verifyDocumentSignature(document, signature, publicKey) {
|
|
45061
|
+
await libsodium_wrappers_default.ready;
|
|
45062
|
+
const canonical = canonicalize(document);
|
|
45063
|
+
const domainPrefix = libsodium_wrappers_default.from_string(DOMAIN_DID_DOCUMENT);
|
|
45064
|
+
const message = new Uint8Array(domainPrefix.length + canonical.length);
|
|
45065
|
+
message.set(domainPrefix);
|
|
45066
|
+
message.set(canonical, domainPrefix.length);
|
|
45067
|
+
try {
|
|
45068
|
+
return libsodium_wrappers_default.crypto_sign_verify_detached(signature, message, publicKey);
|
|
45069
|
+
} catch {
|
|
45070
|
+
return false;
|
|
45071
|
+
}
|
|
45072
|
+
}
|
|
45073
|
+
var DOMAIN_DID_DOCUMENT;
|
|
45026
45074
|
var init_did = __esm({
|
|
45027
45075
|
async "../crypto/dist/did.js"() {
|
|
45028
45076
|
"use strict";
|
|
45077
|
+
await init_libsodium_wrappers();
|
|
45078
|
+
DOMAIN_DID_DOCUMENT = "DID-DOCUMENT:";
|
|
45029
45079
|
}
|
|
45030
45080
|
});
|
|
45031
45081
|
|
|
@@ -45980,13 +46030,152 @@ var init_http_handlers = __esm({
|
|
|
45980
46030
|
}
|
|
45981
46031
|
});
|
|
45982
46032
|
|
|
46033
|
+
// src/workspace-handlers.ts
|
|
46034
|
+
var workspace_handlers_exports = {};
|
|
46035
|
+
__export(workspace_handlers_exports, {
|
|
46036
|
+
handleWorkspaceList: () => handleWorkspaceList,
|
|
46037
|
+
handleWorkspaceRead: () => handleWorkspaceRead,
|
|
46038
|
+
handleWorkspaceUpload: () => handleWorkspaceUpload,
|
|
46039
|
+
validateWorkspaceFilename: () => validateWorkspaceFilename
|
|
46040
|
+
});
|
|
46041
|
+
import { readdir, readFile as readFile2, writeFile as writeFile2, rename as rename2, stat, unlink } from "node:fs/promises";
|
|
46042
|
+
import { join as join2 } from "node:path";
|
|
46043
|
+
import { randomUUID } from "node:crypto";
|
|
46044
|
+
function validateWorkspaceFilename(filename) {
|
|
46045
|
+
if (!filename || typeof filename !== "string") {
|
|
46046
|
+
return "Filename is required";
|
|
46047
|
+
}
|
|
46048
|
+
if (filename.includes("\0")) {
|
|
46049
|
+
return "Filename contains null bytes";
|
|
46050
|
+
}
|
|
46051
|
+
if (filename.includes("..")) {
|
|
46052
|
+
return "Path traversal not allowed";
|
|
46053
|
+
}
|
|
46054
|
+
if (filename.includes("/") || filename.includes("\\")) {
|
|
46055
|
+
return "Path separators not allowed in filename";
|
|
46056
|
+
}
|
|
46057
|
+
if (!filename.endsWith(".md")) {
|
|
46058
|
+
return "Only .md files are allowed";
|
|
46059
|
+
}
|
|
46060
|
+
if (!/^[a-zA-Z0-9._-]+$/.test(filename)) {
|
|
46061
|
+
return "Filename may only contain letters, numbers, hyphens, underscores, and dots";
|
|
46062
|
+
}
|
|
46063
|
+
return null;
|
|
46064
|
+
}
|
|
46065
|
+
async function handleWorkspaceUpload(data, workspaceDir) {
|
|
46066
|
+
const filenameError = validateWorkspaceFilename(data.filename);
|
|
46067
|
+
if (filenameError) {
|
|
46068
|
+
return { status: "error", error: filenameError };
|
|
46069
|
+
}
|
|
46070
|
+
if (!data.content || typeof data.content !== "string") {
|
|
46071
|
+
return { status: "error", error: "File content is required" };
|
|
46072
|
+
}
|
|
46073
|
+
const contentBytes = Buffer.byteLength(data.content, "utf-8");
|
|
46074
|
+
if (contentBytes > MAX_FILE_SIZE) {
|
|
46075
|
+
return {
|
|
46076
|
+
status: "error",
|
|
46077
|
+
error: `File exceeds 100KB limit (${Math.round(contentBytes / 1024)}KB)`
|
|
46078
|
+
};
|
|
46079
|
+
}
|
|
46080
|
+
let verified = false;
|
|
46081
|
+
try {
|
|
46082
|
+
const signatureBytes = base64ToBytes(data.signature);
|
|
46083
|
+
const publicKeyBytes = base64ToBytes(data.signer_public_key);
|
|
46084
|
+
const signedPayload = {
|
|
46085
|
+
filename: data.filename,
|
|
46086
|
+
content: data.content,
|
|
46087
|
+
timestamp: data.timestamp
|
|
46088
|
+
};
|
|
46089
|
+
verified = await verifyDocumentSignature(signedPayload, signatureBytes, publicKeyBytes);
|
|
46090
|
+
} catch (err) {
|
|
46091
|
+
return { status: "error", error: "Signature verification failed: invalid format" };
|
|
46092
|
+
}
|
|
46093
|
+
if (!verified) {
|
|
46094
|
+
return { status: "error", error: "Invalid signature \u2014 file may have been tampered with" };
|
|
46095
|
+
}
|
|
46096
|
+
const targetPath = join2(workspaceDir, data.filename);
|
|
46097
|
+
const tempPath = join2(workspaceDir, `.tmp_${randomUUID()}_${data.filename}`);
|
|
46098
|
+
try {
|
|
46099
|
+
await writeFile2(tempPath, data.content, "utf-8");
|
|
46100
|
+
await rename2(tempPath, targetPath);
|
|
46101
|
+
} catch (err) {
|
|
46102
|
+
try {
|
|
46103
|
+
await unlink(tempPath);
|
|
46104
|
+
} catch {
|
|
46105
|
+
}
|
|
46106
|
+
return { status: "error", error: `Failed to write file: ${err.message}` };
|
|
46107
|
+
}
|
|
46108
|
+
console.log(`[Workspace] Wrote ${data.filename} (${contentBytes} bytes, sig verified) \u2192 ${targetPath}`);
|
|
46109
|
+
return {
|
|
46110
|
+
status: "success",
|
|
46111
|
+
written_path: targetPath,
|
|
46112
|
+
verified_signature: true
|
|
46113
|
+
};
|
|
46114
|
+
}
|
|
46115
|
+
async function handleWorkspaceList(workspaceDir) {
|
|
46116
|
+
try {
|
|
46117
|
+
const entries = await readdir(workspaceDir);
|
|
46118
|
+
const files = [];
|
|
46119
|
+
for (const entry of entries) {
|
|
46120
|
+
if (!entry.endsWith(".md")) continue;
|
|
46121
|
+
try {
|
|
46122
|
+
const filePath = join2(workspaceDir, entry);
|
|
46123
|
+
const fileStat = await stat(filePath);
|
|
46124
|
+
if (!fileStat.isFile()) continue;
|
|
46125
|
+
files.push({
|
|
46126
|
+
filename: entry,
|
|
46127
|
+
size: fileStat.size,
|
|
46128
|
+
modified: fileStat.mtime.toISOString()
|
|
46129
|
+
});
|
|
46130
|
+
} catch {
|
|
46131
|
+
}
|
|
46132
|
+
}
|
|
46133
|
+
files.sort((a2, b2) => a2.filename.localeCompare(b2.filename));
|
|
46134
|
+
return { files };
|
|
46135
|
+
} catch (err) {
|
|
46136
|
+
if (err.code === "ENOENT") {
|
|
46137
|
+
return { files: [] };
|
|
46138
|
+
}
|
|
46139
|
+
throw err;
|
|
46140
|
+
}
|
|
46141
|
+
}
|
|
46142
|
+
async function handleWorkspaceRead(data, workspaceDir) {
|
|
46143
|
+
const filenameError = validateWorkspaceFilename(data.filename);
|
|
46144
|
+
if (filenameError) {
|
|
46145
|
+
return { error: filenameError };
|
|
46146
|
+
}
|
|
46147
|
+
const filePath = join2(workspaceDir, data.filename);
|
|
46148
|
+
try {
|
|
46149
|
+
const content = await readFile2(filePath, "utf-8");
|
|
46150
|
+
const fileStat = await stat(filePath);
|
|
46151
|
+
return {
|
|
46152
|
+
filename: data.filename,
|
|
46153
|
+
content,
|
|
46154
|
+
size: fileStat.size
|
|
46155
|
+
};
|
|
46156
|
+
} catch (err) {
|
|
46157
|
+
if (err.code === "ENOENT") {
|
|
46158
|
+
return { error: `File not found: ${data.filename}` };
|
|
46159
|
+
}
|
|
46160
|
+
return { error: `Failed to read file: ${err.message}` };
|
|
46161
|
+
}
|
|
46162
|
+
}
|
|
46163
|
+
var MAX_FILE_SIZE;
|
|
46164
|
+
var init_workspace_handlers = __esm({
|
|
46165
|
+
async "src/workspace-handlers.ts"() {
|
|
46166
|
+
"use strict";
|
|
46167
|
+
await init_dist();
|
|
46168
|
+
MAX_FILE_SIZE = 100 * 1024;
|
|
46169
|
+
}
|
|
46170
|
+
});
|
|
46171
|
+
|
|
45983
46172
|
// src/channel.ts
|
|
45984
46173
|
import { EventEmitter } from "node:events";
|
|
45985
46174
|
import { createServer } from "node:http";
|
|
45986
|
-
import { randomUUID } from "node:crypto";
|
|
45987
|
-
import { writeFile as
|
|
45988
|
-
import { join as
|
|
45989
|
-
import { readFile as
|
|
46175
|
+
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
46176
|
+
import { writeFile as writeFile3, mkdir as mkdir2 } from "node:fs/promises";
|
|
46177
|
+
import { join as join3 } from "node:path";
|
|
46178
|
+
import { readFile as readFile3 } from "node:fs/promises";
|
|
45990
46179
|
import WebSocket from "ws";
|
|
45991
46180
|
function migratePersistedState(raw) {
|
|
45992
46181
|
if (raw.sessions && raw.primaryConversationId) {
|
|
@@ -46039,6 +46228,8 @@ var init_channel = __esm({
|
|
|
46039
46228
|
_pollTimer = null;
|
|
46040
46229
|
_reconnectAttempt = 0;
|
|
46041
46230
|
_reconnectTimer = null;
|
|
46231
|
+
_rapidDisconnects = 0;
|
|
46232
|
+
_lastWsOpenTime = 0;
|
|
46042
46233
|
_pingTimer = null;
|
|
46043
46234
|
_lastServerMessage = 0;
|
|
46044
46235
|
_pendingAcks = [];
|
|
@@ -46228,7 +46419,7 @@ var init_channel = __esm({
|
|
|
46228
46419
|
}
|
|
46229
46420
|
}
|
|
46230
46421
|
}
|
|
46231
|
-
const messageGroupId =
|
|
46422
|
+
const messageGroupId = randomUUID2();
|
|
46232
46423
|
let sentCount = 0;
|
|
46233
46424
|
for (const [convId, session] of this._sessions) {
|
|
46234
46425
|
if (!session.activated) continue;
|
|
@@ -46323,7 +46514,7 @@ var init_channel = __esm({
|
|
|
46323
46514
|
* as a high-priority message. Returns the generated decision_id.
|
|
46324
46515
|
*/
|
|
46325
46516
|
async sendDecisionRequest(request) {
|
|
46326
|
-
const decision_id = `dec_${
|
|
46517
|
+
const decision_id = `dec_${randomUUID2().replace(/-/g, "").slice(0, 16)}`;
|
|
46327
46518
|
const payload = JSON.stringify({
|
|
46328
46519
|
type: "message",
|
|
46329
46520
|
text: `\u{1F4CB} ${request.title}`,
|
|
@@ -46628,7 +46819,7 @@ var init_channel = __esm({
|
|
|
46628
46819
|
description: artifact.description,
|
|
46629
46820
|
attachment: attachMeta
|
|
46630
46821
|
});
|
|
46631
|
-
const messageGroupId =
|
|
46822
|
+
const messageGroupId = randomUUID2();
|
|
46632
46823
|
for (const [convId, session] of this._sessions) {
|
|
46633
46824
|
if (!session.activated) continue;
|
|
46634
46825
|
const encrypted = session.ratchet.encrypt(envelope);
|
|
@@ -47265,6 +47456,7 @@ var init_channel = __esm({
|
|
|
47265
47456
|
ws.on("open", async () => {
|
|
47266
47457
|
try {
|
|
47267
47458
|
this._reconnectAttempt = 0;
|
|
47459
|
+
this._lastWsOpenTime = Date.now();
|
|
47268
47460
|
this._startPing(ws);
|
|
47269
47461
|
this._startWakeDetector();
|
|
47270
47462
|
this._startPendingPoll();
|
|
@@ -47790,6 +47982,41 @@ var init_channel = __esm({
|
|
|
47790
47982
|
await this._persistState();
|
|
47791
47983
|
return;
|
|
47792
47984
|
}
|
|
47985
|
+
if (messageType === "workspace_file_upload") {
|
|
47986
|
+
try {
|
|
47987
|
+
const parsed = JSON.parse(plaintext);
|
|
47988
|
+
const workspaceDir = this._resolveWorkspaceDir();
|
|
47989
|
+
const { handleWorkspaceUpload: handleWorkspaceUpload2 } = await init_workspace_handlers().then(() => workspace_handlers_exports);
|
|
47990
|
+
const result = await handleWorkspaceUpload2(parsed, workspaceDir);
|
|
47991
|
+
await this._sendStructuredReply(convId, { type: "workspace_file_ack", filename: parsed.filename, ...result });
|
|
47992
|
+
} catch (err) {
|
|
47993
|
+
await this._sendStructuredReply(convId, { type: "workspace_file_ack", status: "error", error: err.message });
|
|
47994
|
+
}
|
|
47995
|
+
return;
|
|
47996
|
+
}
|
|
47997
|
+
if (messageType === "workspace_file_list") {
|
|
47998
|
+
try {
|
|
47999
|
+
const workspaceDir = this._resolveWorkspaceDir();
|
|
48000
|
+
const { handleWorkspaceList: handleWorkspaceList2 } = await init_workspace_handlers().then(() => workspace_handlers_exports);
|
|
48001
|
+
const result = await handleWorkspaceList2(workspaceDir);
|
|
48002
|
+
await this._sendStructuredReply(convId, { type: "workspace_file_list_response", ...result });
|
|
48003
|
+
} catch (err) {
|
|
48004
|
+
await this._sendStructuredReply(convId, { type: "workspace_file_list_response", files: [], error: err.message });
|
|
48005
|
+
}
|
|
48006
|
+
return;
|
|
48007
|
+
}
|
|
48008
|
+
if (messageType === "workspace_file_read") {
|
|
48009
|
+
try {
|
|
48010
|
+
const parsed = JSON.parse(plaintext);
|
|
48011
|
+
const workspaceDir = this._resolveWorkspaceDir();
|
|
48012
|
+
const { handleWorkspaceRead: handleWorkspaceRead2 } = await init_workspace_handlers().then(() => workspace_handlers_exports);
|
|
48013
|
+
const result = await handleWorkspaceRead2(parsed, workspaceDir);
|
|
48014
|
+
await this._sendStructuredReply(convId, { type: "workspace_file_read_response", ...result });
|
|
48015
|
+
} catch (err) {
|
|
48016
|
+
await this._sendStructuredReply(convId, { type: "workspace_file_read_response", error: err.message });
|
|
48017
|
+
}
|
|
48018
|
+
return;
|
|
48019
|
+
}
|
|
47793
48020
|
if (this._scanEngine) {
|
|
47794
48021
|
const scanResult = this._scanEngine.scanInbound(messageText);
|
|
47795
48022
|
if (scanResult.status === "blocked") {
|
|
@@ -47870,7 +48097,7 @@ ${messageText}`;
|
|
|
47870
48097
|
* and save the plaintext file to disk.
|
|
47871
48098
|
*/
|
|
47872
48099
|
async _downloadAndDecryptAttachment(info) {
|
|
47873
|
-
const attachDir =
|
|
48100
|
+
const attachDir = join3(this.config.dataDir, "attachments");
|
|
47874
48101
|
await mkdir2(attachDir, { recursive: true });
|
|
47875
48102
|
const url = `${this.config.apiUrl}${info.blobUrl}`;
|
|
47876
48103
|
const res = await fetch(url, {
|
|
@@ -47888,8 +48115,8 @@ ${messageText}`;
|
|
|
47888
48115
|
const fileKey = base64ToBytes(info.fileKey);
|
|
47889
48116
|
const fileNonce = base64ToBytes(info.fileNonce);
|
|
47890
48117
|
const decrypted = decryptFile(encryptedData, fileKey, fileNonce);
|
|
47891
|
-
const filePath =
|
|
47892
|
-
await
|
|
48118
|
+
const filePath = join3(attachDir, info.filename);
|
|
48119
|
+
await writeFile3(filePath, decrypted);
|
|
47893
48120
|
console.log(`[SecureChannel] Attachment saved: ${filePath} (${decrypted.length} bytes)`);
|
|
47894
48121
|
return { filePath, decrypted };
|
|
47895
48122
|
}
|
|
@@ -47898,7 +48125,7 @@ ${messageText}`;
|
|
|
47898
48125
|
* for inclusion in the message envelope.
|
|
47899
48126
|
*/
|
|
47900
48127
|
async _uploadAttachment(filePath, conversationId) {
|
|
47901
|
-
const data = await
|
|
48128
|
+
const data = await readFile3(filePath);
|
|
47902
48129
|
const plainData = new Uint8Array(data);
|
|
47903
48130
|
const result = encryptFile(plainData);
|
|
47904
48131
|
const { Blob: NodeBlob, FormData: NodeFormData } = await import("node:buffer").then(
|
|
@@ -47950,7 +48177,7 @@ ${messageText}`;
|
|
|
47950
48177
|
attachment: attachMeta
|
|
47951
48178
|
});
|
|
47952
48179
|
this._appendHistory("agent", plaintext, topicId);
|
|
47953
|
-
const messageGroupId =
|
|
48180
|
+
const messageGroupId = randomUUID2();
|
|
47954
48181
|
for (const [convId, session] of this._sessions) {
|
|
47955
48182
|
if (!session.activated) continue;
|
|
47956
48183
|
const encrypted = session.ratchet.encrypt(envelope);
|
|
@@ -48000,6 +48227,56 @@ ${messageText}`;
|
|
|
48000
48227
|
);
|
|
48001
48228
|
}
|
|
48002
48229
|
}
|
|
48230
|
+
/**
|
|
48231
|
+
* Resolve the agent's workspace directory.
|
|
48232
|
+
* Looks for OpenClaw workspace config, falls back to default path.
|
|
48233
|
+
*/
|
|
48234
|
+
_resolveWorkspaceDir() {
|
|
48235
|
+
const homedir = process.env.HOME ?? process.env.USERPROFILE ?? "/tmp";
|
|
48236
|
+
try {
|
|
48237
|
+
const configPath = join3(homedir, ".openclaw", "openclaw.json");
|
|
48238
|
+
const raw = __require("node:fs").readFileSync(configPath, "utf-8");
|
|
48239
|
+
const config = JSON.parse(raw);
|
|
48240
|
+
const agents = config?.agents?.list;
|
|
48241
|
+
if (Array.isArray(agents)) {
|
|
48242
|
+
for (const agent of agents) {
|
|
48243
|
+
if (agent.workspace && typeof agent.workspace === "string") {
|
|
48244
|
+
return agent.workspace;
|
|
48245
|
+
}
|
|
48246
|
+
}
|
|
48247
|
+
}
|
|
48248
|
+
} catch {
|
|
48249
|
+
}
|
|
48250
|
+
if (this.config.dataDir) {
|
|
48251
|
+
return join3(this.config.dataDir, "..", "workspace");
|
|
48252
|
+
}
|
|
48253
|
+
return join3(homedir, ".openclaw", "workspace");
|
|
48254
|
+
}
|
|
48255
|
+
/**
|
|
48256
|
+
* Send a structured JSON reply to a specific conversation.
|
|
48257
|
+
* Encrypts the payload via the conversation's ratchet and sends via WebSocket.
|
|
48258
|
+
*/
|
|
48259
|
+
async _sendStructuredReply(convId, payload) {
|
|
48260
|
+
const session = this._sessions.get(convId);
|
|
48261
|
+
if (!session || !this._ws) {
|
|
48262
|
+
console.warn(`[SecureChannel] Cannot send structured reply \u2014 no session for ${convId.slice(0, 8)}...`);
|
|
48263
|
+
return;
|
|
48264
|
+
}
|
|
48265
|
+
const plaintext = JSON.stringify(payload);
|
|
48266
|
+
const encrypted = session.ratchet.encrypt(plaintext);
|
|
48267
|
+
const transport = encryptedMessageToTransport(encrypted);
|
|
48268
|
+
this._ws.send(
|
|
48269
|
+
JSON.stringify({
|
|
48270
|
+
event: "message",
|
|
48271
|
+
data: {
|
|
48272
|
+
conversation_id: convId,
|
|
48273
|
+
header_blob: transport.header_blob,
|
|
48274
|
+
ciphertext: transport.ciphertext
|
|
48275
|
+
}
|
|
48276
|
+
})
|
|
48277
|
+
);
|
|
48278
|
+
await this._persistState();
|
|
48279
|
+
}
|
|
48003
48280
|
/**
|
|
48004
48281
|
* Send stored message history to a newly-activated session.
|
|
48005
48282
|
* Batches all history into a single encrypted message.
|
|
@@ -48560,6 +48837,26 @@ ${messageText}`;
|
|
|
48560
48837
|
_scheduleReconnect() {
|
|
48561
48838
|
if (this._stopped) return;
|
|
48562
48839
|
if (this._reconnectTimer) return;
|
|
48840
|
+
const sinceOpen = Date.now() - this._lastWsOpenTime;
|
|
48841
|
+
if (this._lastWsOpenTime > 0 && sinceOpen < 1e4) {
|
|
48842
|
+
this._rapidDisconnects++;
|
|
48843
|
+
} else {
|
|
48844
|
+
this._rapidDisconnects = 0;
|
|
48845
|
+
}
|
|
48846
|
+
if (this._rapidDisconnects >= 5) {
|
|
48847
|
+
console.error(
|
|
48848
|
+
`[SecureChannel] Detected rapid connect/disconnect loop (${this._rapidDisconnects} times in <10s each).`
|
|
48849
|
+
);
|
|
48850
|
+
console.error(
|
|
48851
|
+
`[SecureChannel] This usually means another process is already connected as this device.`
|
|
48852
|
+
);
|
|
48853
|
+
console.error(
|
|
48854
|
+
`[SecureChannel] Stopping reconnection. Check for duplicate gateway processes or stale CLI sessions.`
|
|
48855
|
+
);
|
|
48856
|
+
this._setState("error");
|
|
48857
|
+
this.emit("error", new Error("Reconnect loop detected \u2014 another process may be connected as this device"));
|
|
48858
|
+
return;
|
|
48859
|
+
}
|
|
48563
48860
|
const delay = Math.min(
|
|
48564
48861
|
RECONNECT_BASE_MS * Math.pow(2, this._reconnectAttempt),
|
|
48565
48862
|
RECONNECT_MAX_MS
|
|
@@ -49228,18 +49525,18 @@ __export(create_agent_exports, {
|
|
|
49228
49525
|
});
|
|
49229
49526
|
import { execSync as execSync2 } from "node:child_process";
|
|
49230
49527
|
import { existsSync, mkdirSync, readFileSync, writeFileSync, copyFileSync } from "node:fs";
|
|
49231
|
-
import { join as
|
|
49528
|
+
import { join as join4 } from "node:path";
|
|
49232
49529
|
function openclawHome() {
|
|
49233
49530
|
const home = process.env.HOME ?? process.env.USERPROFILE ?? "";
|
|
49234
|
-
return
|
|
49531
|
+
return join4(home, ".openclaw");
|
|
49235
49532
|
}
|
|
49236
49533
|
function readOpenClawConfig(home) {
|
|
49237
|
-
const configPath =
|
|
49534
|
+
const configPath = join4(home, "openclaw.json");
|
|
49238
49535
|
const raw = readFileSync(configPath, "utf-8");
|
|
49239
49536
|
return JSON.parse(raw);
|
|
49240
49537
|
}
|
|
49241
49538
|
function writeOpenClawConfig(home, config, backupSuffix) {
|
|
49242
|
-
const configPath =
|
|
49539
|
+
const configPath = join4(home, "openclaw.json");
|
|
49243
49540
|
const backupPath = `${configPath}.bak.pre-${backupSuffix}`;
|
|
49244
49541
|
copyFileSync(configPath, backupPath);
|
|
49245
49542
|
writeFileSync(configPath, JSON.stringify(config, null, 2) + "\n", "utf-8");
|
|
@@ -49313,10 +49610,10 @@ _(Empty \u2014 ${name2} starts with a clean memory. Update as the agent learns.)
|
|
|
49313
49610
|
async function runCreateCommand(options) {
|
|
49314
49611
|
const { name: name2, token: token2, apiUrl: apiUrl2, force } = options;
|
|
49315
49612
|
const home = openclawHome();
|
|
49316
|
-
const configPath =
|
|
49317
|
-
const workspaceDir =
|
|
49318
|
-
const dataDir2 =
|
|
49319
|
-
const templateDir =
|
|
49613
|
+
const configPath = join4(home, "openclaw.json");
|
|
49614
|
+
const workspaceDir = join4(home, `workspace-${name2}`);
|
|
49615
|
+
const dataDir2 = join4(home, "agents", name2, "agentvault-data");
|
|
49616
|
+
const templateDir = join4(home, "workspace");
|
|
49320
49617
|
console.log(`
|
|
49321
49618
|
\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
|
|
49322
49619
|
\u2551 AgentVault \u2014 Create New Agent \u2551
|
|
@@ -49352,7 +49649,7 @@ async function runCreateCommand(options) {
|
|
|
49352
49649
|
}
|
|
49353
49650
|
console.log(" Step 3/7 \u2014 Creating agent with OpenClaw...");
|
|
49354
49651
|
try {
|
|
49355
|
-
execSync2(`openclaw agents add ${name2}`, { stdio: "pipe" });
|
|
49652
|
+
execSync2(`openclaw agents add -- ${name2}`, { stdio: "pipe" });
|
|
49356
49653
|
console.log(` Agent '${name2}' created.
|
|
49357
49654
|
`);
|
|
49358
49655
|
} catch {
|
|
@@ -49368,12 +49665,12 @@ async function runCreateCommand(options) {
|
|
|
49368
49665
|
console.log(" Step 5/7 \u2014 Writing workspace files...");
|
|
49369
49666
|
const files = generateWorkspaceFiles(name2);
|
|
49370
49667
|
for (const [filename, content] of Object.entries(files)) {
|
|
49371
|
-
writeFileSync(
|
|
49668
|
+
writeFileSync(join4(workspaceDir, filename), content, "utf-8");
|
|
49372
49669
|
}
|
|
49373
49670
|
for (const copyFile of ["AGENTS.md", "USER.md"]) {
|
|
49374
|
-
const src =
|
|
49671
|
+
const src = join4(templateDir, copyFile);
|
|
49375
49672
|
if (existsSync(src)) {
|
|
49376
|
-
copyFileSync(src,
|
|
49673
|
+
copyFileSync(src, join4(workspaceDir, copyFile));
|
|
49377
49674
|
console.log(` Copied ${copyFile} from template workspace.`);
|
|
49378
49675
|
}
|
|
49379
49676
|
}
|
|
@@ -49387,7 +49684,7 @@ async function runCreateCommand(options) {
|
|
|
49387
49684
|
accountId: name2,
|
|
49388
49685
|
force
|
|
49389
49686
|
});
|
|
49390
|
-
console.log("\n Step 7/7 \u2014 Patching
|
|
49687
|
+
console.log("\n Step 7/7 \u2014 Patching openclaw.json...");
|
|
49391
49688
|
try {
|
|
49392
49689
|
const freshConfig = readOpenClawConfig(home);
|
|
49393
49690
|
let patched = false;
|
|
@@ -49399,6 +49696,10 @@ async function runCreateCommand(options) {
|
|
|
49399
49696
|
patched = true;
|
|
49400
49697
|
}
|
|
49401
49698
|
}
|
|
49699
|
+
if (avChannel && !avChannel.bindings) {
|
|
49700
|
+
avChannel.bindings = [{ match: { accountId: "*" } }];
|
|
49701
|
+
console.log(` Added wildcard binding (accountId: "*").`);
|
|
49702
|
+
}
|
|
49402
49703
|
if (patched) {
|
|
49403
49704
|
writeOpenClawConfig(home, freshConfig, name2);
|
|
49404
49705
|
console.log(` httpPort set to ${port}.
|
|
@@ -49409,7 +49710,7 @@ async function runCreateCommand(options) {
|
|
|
49409
49710
|
`);
|
|
49410
49711
|
}
|
|
49411
49712
|
} catch (err) {
|
|
49412
|
-
console.log(` Warning: Failed to patch
|
|
49713
|
+
console.log(` Warning: Failed to patch openclaw.json: ${err.message}
|
|
49413
49714
|
`);
|
|
49414
49715
|
}
|
|
49415
49716
|
console.log(" Verifying agent...");
|
|
@@ -49554,7 +49855,18 @@ var init_skills_publish = __esm({
|
|
|
49554
49855
|
await init_channel();
|
|
49555
49856
|
await init_setup();
|
|
49556
49857
|
import { resolve as resolve3 } from "node:path";
|
|
49858
|
+
import { existsSync as existsSync2, readFileSync as readFileSync3 } from "node:fs";
|
|
49557
49859
|
import { createInterface as createInterface2 } from "node:readline";
|
|
49860
|
+
import { createRequire } from "node:module";
|
|
49861
|
+
var _require = createRequire(import.meta.url);
|
|
49862
|
+
var PKG_VERSION = (() => {
|
|
49863
|
+
try {
|
|
49864
|
+
const pkg = _require("../package.json");
|
|
49865
|
+
return pkg.version ?? "unknown";
|
|
49866
|
+
} catch {
|
|
49867
|
+
return "unknown";
|
|
49868
|
+
}
|
|
49869
|
+
})();
|
|
49558
49870
|
var _notifier = null;
|
|
49559
49871
|
async function tryNotify(title, message) {
|
|
49560
49872
|
try {
|
|
@@ -49584,6 +49896,10 @@ var apiUrl = flags["api-url"] || process.env.AGENTVAULT_API_URL || "https://api.
|
|
|
49584
49896
|
var webhookUrl = flags["webhook-url"] || process.env.AGENTVAULT_WEBHOOK_URL;
|
|
49585
49897
|
var accountId = flags["account-id"] || process.env.AGENTVAULT_ACCOUNT_ID;
|
|
49586
49898
|
var noNotifications = flags["no-notifications"] === "true" || process.env.AGENTVAULT_NO_NOTIFICATIONS === "1";
|
|
49899
|
+
if (flags["version"] === "true" || subcommand === "version") {
|
|
49900
|
+
console.log(`@agentvault/agentvault v${PKG_VERSION}`);
|
|
49901
|
+
process.exit(0);
|
|
49902
|
+
}
|
|
49587
49903
|
if (subcommand === "setup") {
|
|
49588
49904
|
if (!token) {
|
|
49589
49905
|
console.error(`
|
|
@@ -49811,15 +50127,33 @@ channel.on("error", (err) => {
|
|
|
49811
50127
|
console.error(`
|
|
49812
50128
|
Error: ${err.message}`);
|
|
49813
50129
|
});
|
|
50130
|
+
var resolvedDataDir = resolve3(dataDir);
|
|
50131
|
+
var statePath = resolve3(resolvedDataDir, "agentvault.json");
|
|
50132
|
+
var existingDeviceId = null;
|
|
50133
|
+
if (existsSync2(statePath)) {
|
|
50134
|
+
try {
|
|
50135
|
+
const state = JSON.parse(readFileSync3(statePath, "utf-8"));
|
|
50136
|
+
existingDeviceId = state.deviceId ?? null;
|
|
50137
|
+
} catch {
|
|
50138
|
+
}
|
|
50139
|
+
}
|
|
49814
50140
|
console.log(`
|
|
49815
50141
|
\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
|
|
49816
50142
|
\u2551 AgentVault Secure Channel \u2551
|
|
49817
50143
|
\u2551 \u2551
|
|
49818
50144
|
\u2551 Agent: ${name.padEnd(37)}\u2551
|
|
49819
50145
|
\u2551 API: ${apiUrl.padEnd(37)}\u2551
|
|
50146
|
+
\u2551 v${PKG_VERSION.padEnd(42)}\u2551
|
|
49820
50147
|
\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
|
|
49821
50148
|
Keep this process running to receive messages${noNotifications ? "." : " and notifications."}
|
|
49822
50149
|
`);
|
|
50150
|
+
if (existingDeviceId) {
|
|
50151
|
+
console.log(` \u26A0 Data dir: ${resolvedDataDir}`);
|
|
50152
|
+
console.log(` \u26A0 Reusing enrolled device: ${existingDeviceId}`);
|
|
50153
|
+
console.log(` \u26A0 If this device is already connected (e.g. via OpenClaw gateway),`);
|
|
50154
|
+
console.log(` \u26A0 you will get a reconnect loop. Use --data-dir to specify a different path.
|
|
50155
|
+
`);
|
|
50156
|
+
}
|
|
49823
50157
|
await channel.start();
|
|
49824
50158
|
var rl = createInterface2({
|
|
49825
50159
|
input: process.stdin,
|