@openclaw-cloud/agent-controller 3.0.0-beta.2 → 3.0.0-beta.21
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/bin/agent-controller.js +5 -9
- package/dist/api.d.ts +16 -0
- package/dist/api.js.map +1 -1
- package/dist/commands/agent-update-cli.js +23 -38
- package/dist/commands/agent-update-cli.js.map +1 -1
- package/dist/commands/backup-cli.js +6 -4
- package/dist/commands/backup-cli.js.map +1 -1
- package/dist/commands/bootstrap.d.ts +10 -1
- package/dist/commands/bootstrap.js +33 -73
- package/dist/commands/bootstrap.js.map +1 -1
- package/dist/commands/channel-server.js +4 -3
- package/dist/commands/channel-server.js.map +1 -1
- package/dist/commands/heartbeat-cli.js +2 -6
- package/dist/commands/heartbeat-cli.js.map +1 -1
- package/dist/commands/install-deps.d.ts +10 -0
- package/dist/commands/install-deps.js +33 -43
- package/dist/commands/install-deps.js.map +1 -1
- package/dist/commands/knowledge-sync-cli.js +6 -4
- package/dist/commands/knowledge-sync-cli.js.map +1 -1
- package/dist/commands/plugin-update-cli.js +4 -8
- package/dist/commands/plugin-update-cli.js.map +1 -1
- package/dist/commands/self-update.d.ts +1 -0
- package/dist/commands/self-update.js +76 -37
- package/dist/commands/self-update.js.map +1 -1
- package/dist/commands/update-skills.js +7 -6
- package/dist/commands/update-skills.js.map +1 -1
- package/dist/config-file.d.ts +24 -0
- package/dist/config-file.js +59 -20
- package/dist/config-file.js.map +1 -1
- package/dist/config.d.ts +10 -0
- package/dist/config.js +28 -0
- package/dist/config.js.map +1 -1
- package/dist/connection.d.ts +4 -0
- package/dist/connection.js +50 -5
- package/dist/connection.js.map +1 -1
- package/dist/handlers/agent-update.d.ts +4 -0
- package/dist/handlers/agent-update.js +16 -44
- package/dist/handlers/agent-update.js.map +1 -1
- package/dist/handlers/deploy.d.ts +1 -2
- package/dist/handlers/deploy.js +4 -20
- package/dist/handlers/deploy.js.map +1 -1
- package/dist/handlers/diagnostics.js +0 -12
- package/dist/handlers/diagnostics.js.map +1 -1
- package/dist/handlers/file-delete.js +4 -5
- package/dist/handlers/file-delete.js.map +1 -1
- package/dist/handlers/file-write.js +4 -4
- package/dist/handlers/file-write.js.map +1 -1
- package/dist/handlers/knowledge-sync.js +2 -14
- package/dist/handlers/knowledge-sync.js.map +1 -1
- package/dist/handlers/memory.d.ts +11 -1
- package/dist/handlers/memory.js.map +1 -1
- package/dist/handlers/onboarding.d.ts +1 -2
- package/dist/handlers/onboarding.js +3 -20
- package/dist/handlers/onboarding.js.map +1 -1
- package/dist/handlers/package-install.js +1 -1
- package/dist/handlers/package-install.js.map +1 -1
- package/dist/handlers/pair.js +0 -12
- package/dist/handlers/pair.js.map +1 -1
- package/dist/handlers/restart.d.ts +1 -2
- package/dist/handlers/restart.js +3 -8
- package/dist/handlers/restart.js.map +1 -1
- package/dist/handlers/slack-event.d.ts +13 -0
- package/dist/handlers/slack-event.js +40 -0
- package/dist/handlers/slack-event.js.map +1 -0
- package/dist/handlers/stop.js +0 -7
- package/dist/handlers/stop.js.map +1 -1
- package/dist/handlers/telegram-webhook.js +3 -22
- package/dist/handlers/telegram-webhook.js.map +1 -1
- package/dist/handlers/update-config.js +4 -13
- package/dist/handlers/update-config.js.map +1 -1
- package/dist/heartbeat.d.ts +7 -1
- package/dist/heartbeat.js +35 -6
- package/dist/heartbeat.js.map +1 -1
- package/dist/index.d.ts +0 -8
- package/dist/index.js +96 -119
- package/dist/index.js.map +1 -1
- package/dist/lockfile.js +2 -1
- package/dist/lockfile.js.map +1 -1
- package/dist/mock-board-worker.d.ts +31 -0
- package/dist/mock-board-worker.js +125 -0
- package/dist/mock-board-worker.js.map +1 -0
- package/dist/platform/linux.js +6 -5
- package/dist/platform/linux.js.map +1 -1
- package/dist/platform/macos.js +3 -2
- package/dist/platform/macos.js.map +1 -1
- package/dist/platform/windows.js +3 -2
- package/dist/platform/windows.js.map +1 -1
- package/dist/providers/claude-code/channel-server.js +2 -1
- package/dist/providers/claude-code/channel-server.js.map +1 -1
- package/dist/providers/claude-code/settings-writer.d.ts +3 -2
- package/dist/providers/claude-code/settings-writer.js +6 -15
- package/dist/providers/claude-code/settings-writer.js.map +1 -1
- package/dist/providers/index.d.ts +13 -0
- package/dist/providers/index.js +25 -0
- package/dist/providers/index.js.map +1 -1
- package/dist/providers/openclaw/gateway-adapter.js +2 -0
- package/dist/providers/openclaw/gateway-adapter.js.map +1 -1
- package/dist/providers/openclaw/gateway-client.js +6 -1
- package/dist/providers/openclaw/gateway-client.js.map +1 -1
- package/dist/providers/openclaw/index.js +34 -13
- package/dist/providers/openclaw/index.js.map +1 -1
- package/dist/slack-relay-server.d.ts +48 -0
- package/dist/slack-relay-server.js +197 -0
- package/dist/slack-relay-server.js.map +1 -0
- package/dist/types.d.ts +16 -1
- package/dist/utils/anthropic-auth.d.ts +14 -0
- package/dist/utils/anthropic-auth.js +24 -0
- package/dist/utils/anthropic-auth.js.map +1 -1
- package/dist/utils/apply-config.d.ts +65 -12
- package/dist/utils/apply-config.js +308 -100
- package/dist/utils/apply-config.js.map +1 -1
- package/dist/utils/claude-env.d.ts +6 -0
- package/dist/utils/claude-env.js +29 -28
- package/dist/utils/claude-env.js.map +1 -1
- package/dist/utils/config-merge-paths.d.ts +15 -1
- package/dist/utils/config-merge-paths.js +17 -3
- package/dist/utils/config-merge-paths.js.map +1 -1
- package/dist/utils/deploy-type.d.ts +16 -0
- package/dist/utils/deploy-type.js +34 -0
- package/dist/utils/deploy-type.js.map +1 -0
- package/dist/utils/env.d.ts +0 -1
- package/dist/utils/env.js +0 -8
- package/dist/utils/env.js.map +1 -1
- package/dist/utils/exec.d.ts +11 -0
- package/dist/utils/exec.js +47 -1
- package/dist/utils/exec.js.map +1 -1
- package/dist/utils/gateway-restart-handler.d.ts +6 -2
- package/dist/utils/gateway-restart-handler.js +11 -2
- package/dist/utils/gateway-restart-handler.js.map +1 -1
- package/dist/utils/gateway-restart.d.ts +7 -0
- package/dist/utils/gateway-restart.js +12 -4
- package/dist/utils/gateway-restart.js.map +1 -1
- package/dist/utils/knowledge-graph.d.ts +13 -1
- package/dist/utils/knowledge-graph.js +75 -29
- package/dist/utils/knowledge-graph.js.map +1 -1
- package/dist/utils/legacy-mcp-servers.d.ts +12 -0
- package/dist/utils/legacy-mcp-servers.js +37 -0
- package/dist/utils/legacy-mcp-servers.js.map +1 -0
- package/dist/utils/log-collector.js +2 -1
- package/dist/utils/log-collector.js.map +1 -1
- package/dist/utils/openclaw-ops.d.ts +45 -3
- package/dist/utils/openclaw-ops.js +94 -15
- package/dist/utils/openclaw-ops.js.map +1 -1
- package/dist/utils/openclaw-stack-update.d.ts +31 -0
- package/dist/utils/openclaw-stack-update.js +50 -0
- package/dist/utils/openclaw-stack-update.js.map +1 -0
- package/dist/utils/package-install.js +4 -12
- package/dist/utils/package-install.js.map +1 -1
- package/dist/utils/package-version.d.ts +10 -0
- package/dist/utils/package-version.js +18 -0
- package/dist/utils/package-version.js.map +1 -0
- package/dist/utils/parse-id-at-version.d.ts +15 -0
- package/dist/utils/parse-id-at-version.js +22 -0
- package/dist/utils/parse-id-at-version.js.map +1 -0
- package/dist/utils/plugin-reconcile.d.ts +46 -0
- package/dist/utils/plugin-reconcile.js +201 -0
- package/dist/utils/plugin-reconcile.js.map +1 -0
- package/dist/utils/response.js +1 -0
- package/dist/utils/response.js.map +1 -1
- package/dist/utils/write-home-files.d.ts +27 -0
- package/dist/utils/write-home-files.js +72 -0
- package/dist/utils/write-home-files.js.map +1 -0
- package/dist/utils/write-workspace-files.d.ts +1 -1
- package/dist/utils/write-workspace-files.js +19 -7
- package/dist/utils/write-workspace-files.js.map +1 -1
- package/dist/workspace.d.ts +11 -0
- package/dist/workspace.js +20 -0
- package/dist/workspace.js.map +1 -1
- package/package.json +9 -4
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
import { WebSocket, WebSocketServer } from 'ws';
|
|
2
|
+
import { config } from './config.js';
|
|
3
|
+
import { toErrorMessage } from './utils/response.js';
|
|
4
|
+
/**
|
|
5
|
+
* Daemon-hosted local Slack relay WS **server** (transport variant B).
|
|
6
|
+
*
|
|
7
|
+
* The openclaw runtime in this same pod runs `channels.slack.mode:'relay'` and
|
|
8
|
+
* dials us at `ws://127.0.0.1:8788/slack-relay?gateway_id=<AGENT_ID>` with an
|
|
9
|
+
* `Authorization: Bearer <token>` header (see the client in openclaw
|
|
10
|
+
* `extensions/slack/src/monitor/relay-source.ts`). We speak the server half of
|
|
11
|
+
* that wire protocol: send a `hello` on connect and push `slack_event` frames.
|
|
12
|
+
*
|
|
13
|
+
* We resolve each push as soon as the frame is written to the connected client
|
|
14
|
+
* socket (the `ws.send` callback fires with no error) — NOT when openclaw later
|
|
15
|
+
* returns its dispatch `ack`. openclaw only acks after it has dispatched the
|
|
16
|
+
* message to a possibly-busy agent, so waiting on that ack blocked the backend's
|
|
17
|
+
* serial (prefetch(1)) messages-broker for up to a full agent turn and produced
|
|
18
|
+
* false ack-timeouts. openclaw still sends the ack; we simply ignore it. The
|
|
19
|
+
* residual loss window (openclaw crashes after receiving the frame but before
|
|
20
|
+
* dispatch) is covered by openclaw's own channel+ts dedup on redelivery.
|
|
21
|
+
*
|
|
22
|
+
* The backend delivers events over Centrifugo as `slack_event` system commands;
|
|
23
|
+
* `handlers/slack-event.ts` calls `pushSlackEvent()` here. We bind loopback only
|
|
24
|
+
* — the auth token is defense-in-depth on top of that.
|
|
25
|
+
*/
|
|
26
|
+
/** Default port; overridable via `SLACK_RELAY_PORT` (see `config.slackRelayPort`). */
|
|
27
|
+
export const SLACK_RELAY_PORT = 8788;
|
|
28
|
+
const SLACK_RELAY_PATH = '/slack-relay';
|
|
29
|
+
/** Matches the client's `SLACK_RELAY_MAX_PAYLOAD_BYTES` (1 MiB). */
|
|
30
|
+
const SLACK_RELAY_MAX_PAYLOAD_BYTES = 1024 * 1024;
|
|
31
|
+
/**
|
|
32
|
+
* Safety net only — a healthy loopback `ws.send` calls back in ~ms. This bounds
|
|
33
|
+
* the ONE remaining wait (the send callback) so a stalled/half-open client can't
|
|
34
|
+
* hang the backend's serial broker. It is NOT a wait for openclaw's dispatch-ack
|
|
35
|
+
* (that ack is ignored); the previous 15s ACK_TIMEOUT_MS was that wait and is
|
|
36
|
+
* gone. A successful send never approaches this budget.
|
|
37
|
+
*/
|
|
38
|
+
const SEND_TIMEOUT_MS = 2_000;
|
|
39
|
+
// Module-level singleton so the slack_event handler can reach pushSlackEvent()
|
|
40
|
+
// without threading the server through buildHandlers() — mirrors how handlers
|
|
41
|
+
// reach the shared `logCollector`. Set on start, cleared on close.
|
|
42
|
+
let state = null;
|
|
43
|
+
export function startSlackRelayServer() {
|
|
44
|
+
const port = config.slackRelayPort ?? SLACK_RELAY_PORT;
|
|
45
|
+
const wss = new WebSocketServer({
|
|
46
|
+
host: '127.0.0.1',
|
|
47
|
+
port,
|
|
48
|
+
path: SLACK_RELAY_PATH,
|
|
49
|
+
maxPayload: SLACK_RELAY_MAX_PAYLOAD_BYTES,
|
|
50
|
+
perMessageDeflate: false,
|
|
51
|
+
verifyClient: verifyRelayClient,
|
|
52
|
+
});
|
|
53
|
+
const serverState = { wss, socket: null };
|
|
54
|
+
state = serverState;
|
|
55
|
+
wss.on('connection', (ws) => handleConnection(serverState, ws));
|
|
56
|
+
wss.on('listening', () => {
|
|
57
|
+
console.log(`[slack-relay] Slack relay server listening on ws://127.0.0.1:${port}${SLACK_RELAY_PATH}`);
|
|
58
|
+
});
|
|
59
|
+
// Bind errors (e.g. EADDRINUSE) arrive here asynchronously; log and stay up —
|
|
60
|
+
// Slack relay is optional, the rest of the controller must not crash for it.
|
|
61
|
+
wss.on('error', (err) => {
|
|
62
|
+
console.error('[slack-relay] server error:', toErrorMessage(err));
|
|
63
|
+
});
|
|
64
|
+
return {
|
|
65
|
+
close: () => {
|
|
66
|
+
// No pending-ack map to drain — pushSlackEvent resolves on frame-send, so
|
|
67
|
+
// nothing is in flight here.
|
|
68
|
+
serverState.socket?.close();
|
|
69
|
+
serverState.socket = null;
|
|
70
|
+
wss.close();
|
|
71
|
+
if (state === serverState)
|
|
72
|
+
state = null;
|
|
73
|
+
},
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Send a `slack_event` frame to the connected openclaw client and resolve as
|
|
78
|
+
* soon as the frame is written to that socket (the `ws.send` callback fires with
|
|
79
|
+
* no error). We do NOT wait for openclaw's dispatch `ack` — see the module
|
|
80
|
+
* header for why. `delivered:true` on the backend therefore means "openclaw's
|
|
81
|
+
* relay client received the frame", not "openclaw dispatched it to the agent".
|
|
82
|
+
*
|
|
83
|
+
* Rejects on: no connected client, a send error, or the send stalling past
|
|
84
|
+
* `SEND_TIMEOUT_MS`. The backend redelivers on rejection (at-least-once), keyed
|
|
85
|
+
* by the same `delivery_id`; the no-client rejection is the durability contract
|
|
86
|
+
* that makes the backend retry rather than drop when nothing is connected.
|
|
87
|
+
*/
|
|
88
|
+
export function pushSlackEvent(payload) {
|
|
89
|
+
const serverState = state;
|
|
90
|
+
if (!serverState) {
|
|
91
|
+
return Promise.reject(new Error('Slack relay server not started'));
|
|
92
|
+
}
|
|
93
|
+
const ws = serverState.socket;
|
|
94
|
+
if (!ws || ws.readyState !== WebSocket.OPEN) {
|
|
95
|
+
return Promise.reject(new Error('No Slack relay client connected'));
|
|
96
|
+
}
|
|
97
|
+
const { event, deliveryId, route } = payload;
|
|
98
|
+
const frame = JSON.stringify({
|
|
99
|
+
type: 'slack_event',
|
|
100
|
+
delivery_id: deliveryId,
|
|
101
|
+
route,
|
|
102
|
+
payload: { event },
|
|
103
|
+
});
|
|
104
|
+
return new Promise((resolve, reject) => {
|
|
105
|
+
let settled = false;
|
|
106
|
+
// Bounds the send itself, not openclaw's dispatch. Fires only if the socket
|
|
107
|
+
// stalls (half-open client, full send buffer) so a broken client can't hang
|
|
108
|
+
// the backend's serial broker.
|
|
109
|
+
const timer = setTimeout(() => {
|
|
110
|
+
if (settled)
|
|
111
|
+
return;
|
|
112
|
+
settled = true;
|
|
113
|
+
reject(new Error(`Slack relay send stalled after ${SEND_TIMEOUT_MS}ms (delivery ${deliveryId})`));
|
|
114
|
+
}, SEND_TIMEOUT_MS);
|
|
115
|
+
// A hanging send must never hold the process open during shutdown.
|
|
116
|
+
timer.unref?.();
|
|
117
|
+
ws.send(frame, (err) => {
|
|
118
|
+
if (settled)
|
|
119
|
+
return;
|
|
120
|
+
settled = true;
|
|
121
|
+
clearTimeout(timer);
|
|
122
|
+
if (err)
|
|
123
|
+
reject(err);
|
|
124
|
+
else
|
|
125
|
+
resolve(); // frame handed to the client socket — ack no longer awaited
|
|
126
|
+
});
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
function verifyRelayClient(info, cb) {
|
|
130
|
+
const { req } = info;
|
|
131
|
+
const url = new URL(req.url ?? '', 'http://127.0.0.1');
|
|
132
|
+
const gatewayId = url.searchParams.get('gateway_id');
|
|
133
|
+
// Fail closed: reject unless gateway_id names THIS agent.
|
|
134
|
+
if (!gatewayId || gatewayId !== config.agentId) {
|
|
135
|
+
console.warn(`[slack-relay] rejecting connection: gateway_id mismatch (got ${gatewayId ?? 'none'})`);
|
|
136
|
+
cb(false, 403, 'Forbidden');
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
const expectedToken = config.slackRelayAuthToken;
|
|
140
|
+
// Token is defense-in-depth on a loopback-only bind: enforced only when set.
|
|
141
|
+
if (expectedToken && bearerToken(req.headers.authorization) !== expectedToken) {
|
|
142
|
+
console.warn('[slack-relay] rejecting connection: bad or missing bearer token');
|
|
143
|
+
cb(false, 401, 'Unauthorized');
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
cb(true);
|
|
147
|
+
}
|
|
148
|
+
function bearerToken(header) {
|
|
149
|
+
const match = header ? /^Bearer\s+(.+)$/i.exec(header.trim()) : null;
|
|
150
|
+
return match?.[1]?.trim() || undefined;
|
|
151
|
+
}
|
|
152
|
+
function handleConnection(serverState, ws) {
|
|
153
|
+
// openclaw reconnects with backoff — always keep the newest socket and drop
|
|
154
|
+
// any stale one so pushSlackEvent talks to the live connection.
|
|
155
|
+
if (serverState.socket && serverState.socket !== ws) {
|
|
156
|
+
serverState.socket.close();
|
|
157
|
+
}
|
|
158
|
+
serverState.socket = ws;
|
|
159
|
+
console.log('[slack-relay] openclaw relay client connected');
|
|
160
|
+
// hello first — the client reads an optional slack_identity from it; we omit it.
|
|
161
|
+
ws.send(JSON.stringify({ type: 'hello' }));
|
|
162
|
+
ws.on('message', (data) => handleClientFrame(data));
|
|
163
|
+
ws.on('error', (err) => {
|
|
164
|
+
console.error('[slack-relay] client socket error:', toErrorMessage(err));
|
|
165
|
+
});
|
|
166
|
+
ws.on('close', () => {
|
|
167
|
+
console.log('[slack-relay] openclaw relay client disconnected');
|
|
168
|
+
if (serverState.socket === ws) {
|
|
169
|
+
serverState.socket = null;
|
|
170
|
+
}
|
|
171
|
+
// Nothing to fail on close — pushSlackEvent already resolved on frame-send,
|
|
172
|
+
// so there are no in-flight deliveries tied to this socket.
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
function handleClientFrame(data) {
|
|
176
|
+
// openclaw still sends `{ type:'ack', delivery_id }` after it dispatches each
|
|
177
|
+
// event to the agent. We resolved the push on frame-send and keep no pending
|
|
178
|
+
// map, so every ack — for any delivery_id, already-resolved or unknown — is a
|
|
179
|
+
// harmless no-op. Parse only to surface a malformed frame; the result is
|
|
180
|
+
// deliberately discarded.
|
|
181
|
+
try {
|
|
182
|
+
JSON.parse(rawDataToString(data));
|
|
183
|
+
}
|
|
184
|
+
catch {
|
|
185
|
+
console.warn('[slack-relay] dropping malformed JSON frame from client');
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
function rawDataToString(data) {
|
|
189
|
+
if (typeof data === 'string')
|
|
190
|
+
return data;
|
|
191
|
+
if (Buffer.isBuffer(data))
|
|
192
|
+
return data.toString('utf8');
|
|
193
|
+
if (Array.isArray(data))
|
|
194
|
+
return Buffer.concat(data).toString('utf8');
|
|
195
|
+
return Buffer.from(data).toString('utf8');
|
|
196
|
+
}
|
|
197
|
+
//# sourceMappingURL=slack-relay-server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"slack-relay-server.js","sourceRoot":"","sources":["../src/slack-relay-server.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* chat:<agentId> — chat commands (list sessions, history, send)
|
|
5
5
|
* heartbeat:<agentId> — heartbeat publications from agent
|
|
6
6
|
*/
|
|
7
|
-
export type CommandType = 'diagnostics' | 'restart' | 'deploy' | 'pair' | 'stop' | 'backup' | 'chat_list_sessions' | 'chat_history' | 'chat_send' | 'chat_delete_session' | 'package_install' | 'file_write' | 'file_delete' | 'onboarding_complete' | 'knowledge_sync' | 'self_update' | 'plugin_update' | 'agent_update' | 'telegram_webhook' | 'update_skills' | 'update_config' | 'memory_create_entities' | 'memory_create_relations' | 'memory_add_observations' | 'memory_delete_entities' | 'memory_delete_observations' | 'memory_delete_relations' | 'memory_read_graph' | 'memory_search_nodes' | 'memory_open_nodes';
|
|
7
|
+
export type CommandType = 'diagnostics' | 'restart' | 'deploy' | 'pair' | 'stop' | 'backup' | 'chat_list_sessions' | 'chat_history' | 'chat_send' | 'chat_delete_session' | 'package_install' | 'file_write' | 'file_delete' | 'onboarding_complete' | 'knowledge_sync' | 'self_update' | 'plugin_update' | 'agent_update' | 'telegram_webhook' | 'slack_event' | 'update_skills' | 'update_config' | 'memory_create_entities' | 'memory_create_relations' | 'memory_add_observations' | 'memory_delete_entities' | 'memory_delete_observations' | 'memory_delete_relations' | 'memory_read_graph' | 'memory_search_nodes' | 'memory_open_nodes';
|
|
8
8
|
export interface AgentCommand {
|
|
9
9
|
id: string;
|
|
10
10
|
type: CommandType;
|
|
@@ -22,9 +22,23 @@ export interface GatewayStatus {
|
|
|
22
22
|
rpcOk: boolean;
|
|
23
23
|
pid?: number;
|
|
24
24
|
}
|
|
25
|
+
/**
|
|
26
|
+
* Live snapshot of the Centrifugo WS connection state, so backend can tell
|
|
27
|
+
* whether this agent is actually able to receive commands (heartbeat 200 alone
|
|
28
|
+
* does not prove the WS is up — the controller can be alive while the Centrifugo
|
|
29
|
+
* subscription is in error / reconnecting).
|
|
30
|
+
*/
|
|
31
|
+
export interface CentrifugoStatus {
|
|
32
|
+
connected: boolean;
|
|
33
|
+
state: 'connected' | 'connecting' | 'disconnected';
|
|
34
|
+
commandSubState: 'subscribed' | 'subscribing' | 'unsubscribed';
|
|
35
|
+
chatSubState: 'subscribed' | 'subscribing' | 'unsubscribed';
|
|
36
|
+
lastEventAt?: string | null;
|
|
37
|
+
}
|
|
25
38
|
export interface InstalledVersions {
|
|
26
39
|
agentController: string;
|
|
27
40
|
agentRuntime?: string;
|
|
41
|
+
nodeVersion?: string;
|
|
28
42
|
plugins?: Array<{
|
|
29
43
|
id: string;
|
|
30
44
|
version: string;
|
|
@@ -42,5 +56,6 @@ export interface HeartbeatPayload {
|
|
|
42
56
|
uptime: number;
|
|
43
57
|
};
|
|
44
58
|
gatewayStatus?: GatewayStatus;
|
|
59
|
+
centrifugoStatus?: CentrifugoStatus;
|
|
45
60
|
lastMessageAt?: string | null;
|
|
46
61
|
}
|
|
@@ -23,3 +23,17 @@ export declare function classifyAnthropicAuth(input: {
|
|
|
23
23
|
anthropicAuthToken?: string;
|
|
24
24
|
anthropicApiKey?: string;
|
|
25
25
|
}): AnthropicAuth;
|
|
26
|
+
/** The permissions block both Claude settings writers emit, verbatim. */
|
|
27
|
+
export declare const CLAUDE_PERMISSIONS: {
|
|
28
|
+
allow: string[];
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* The settings.json base shared by both writers: the permissions block plus the
|
|
32
|
+
* `env` entry the auth classification implies.
|
|
33
|
+
*
|
|
34
|
+
* `providers/claude-code/settings-writer.ts` uses this as its complete output;
|
|
35
|
+
* `utils/claude-env.ts` uses it for the OAuth branch and composes its own
|
|
36
|
+
* apiKeyHelper variant for the API-key branch (that flow reads the key out of
|
|
37
|
+
* the VM `.env` at runtime instead of embedding it).
|
|
38
|
+
*/
|
|
39
|
+
export declare function buildClaudeSettings(auth: AnthropicAuth): Record<string, unknown>;
|
|
@@ -10,4 +10,28 @@ export function classifyAnthropicAuth(input) {
|
|
|
10
10
|
return { kind: 'auth_token', value: apiKey };
|
|
11
11
|
return { kind: 'api_key', value: apiKey };
|
|
12
12
|
}
|
|
13
|
+
/** The permissions block both Claude settings writers emit, verbatim. */
|
|
14
|
+
export const CLAUDE_PERMISSIONS = {
|
|
15
|
+
allow: ['Bash(*)', 'Read(*)', 'Write(*)', 'Edit(*)', 'mcp__*'],
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* The settings.json base shared by both writers: the permissions block plus the
|
|
19
|
+
* `env` entry the auth classification implies.
|
|
20
|
+
*
|
|
21
|
+
* `providers/claude-code/settings-writer.ts` uses this as its complete output;
|
|
22
|
+
* `utils/claude-env.ts` uses it for the OAuth branch and composes its own
|
|
23
|
+
* apiKeyHelper variant for the API-key branch (that flow reads the key out of
|
|
24
|
+
* the VM `.env` at runtime instead of embedding it).
|
|
25
|
+
*/
|
|
26
|
+
export function buildClaudeSettings(auth) {
|
|
27
|
+
switch (auth.kind) {
|
|
28
|
+
case 'auth_token':
|
|
29
|
+
return { permissions: CLAUDE_PERMISSIONS, env: { ANTHROPIC_AUTH_TOKEN: auth.value } };
|
|
30
|
+
case 'api_key':
|
|
31
|
+
return { permissions: CLAUDE_PERMISSIONS, env: { ANTHROPIC_API_KEY: auth.value } };
|
|
32
|
+
case 'none':
|
|
33
|
+
// No static credentials: rely on ~/.claude/.credentials.json (subscription login).
|
|
34
|
+
return { permissions: CLAUDE_PERMISSIONS };
|
|
35
|
+
}
|
|
36
|
+
}
|
|
13
37
|
//# sourceMappingURL=anthropic-auth.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"anthropic-auth.js","sourceRoot":"","sources":["../../src/utils/anthropic-auth.ts"],"names":[],"mappings":"AAiBA,MAAM,UAAU,qBAAqB,CAAC,KAGrC;IACC,MAAM,SAAS,GAAG,KAAK,CAAC,kBAAkB,EAAE,IAAI,EAAE,CAAC;IACnD,IAAI,SAAS;QAAE,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC;IAE/D,MAAM,MAAM,GAAG,KAAK,CAAC,eAAe,EAAE,IAAI,EAAE,CAAC;IAC7C,IAAI,CAAC,MAAM;QAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;IAErC,yEAAyE;IACzE,IAAI,MAAM,CAAC,UAAU,CAAC,YAAY,CAAC;QAAE,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;IAElF,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;AAC5C,CAAC"}
|
|
1
|
+
{"version":3,"file":"anthropic-auth.js","sourceRoot":"","sources":["../../src/utils/anthropic-auth.ts"],"names":[],"mappings":"AAiBA,MAAM,UAAU,qBAAqB,CAAC,KAGrC;IACC,MAAM,SAAS,GAAG,KAAK,CAAC,kBAAkB,EAAE,IAAI,EAAE,CAAC;IACnD,IAAI,SAAS;QAAE,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC;IAE/D,MAAM,MAAM,GAAG,KAAK,CAAC,eAAe,EAAE,IAAI,EAAE,CAAC;IAC7C,IAAI,CAAC,MAAM;QAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;IAErC,yEAAyE;IACzE,IAAI,MAAM,CAAC,UAAU,CAAC,YAAY,CAAC;QAAE,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;IAElF,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;AAC5C,CAAC;AAED,yEAAyE;AACzE,MAAM,CAAC,MAAM,kBAAkB,GAAG;IAChC,KAAK,EAAE,CAAC,SAAS,EAAE,SAAS,EAAE,UAAU,EAAE,SAAS,EAAE,QAAQ,CAAC;CAC/D,CAAC;AAEF;;;;;;;;GAQG;AACH,MAAM,UAAU,mBAAmB,CAAC,IAAmB;IACrD,QAAQ,IAAI,CAAC,IAAI,EAAE,CAAC;QAClB,KAAK,YAAY;YACf,OAAO,EAAE,WAAW,EAAE,kBAAkB,EAAE,GAAG,EAAE,EAAE,oBAAoB,EAAE,IAAI,CAAC,KAAK,EAAE,EAAE,CAAC;QACxF,KAAK,SAAS;YACZ,OAAO,EAAE,WAAW,EAAE,kBAAkB,EAAE,GAAG,EAAE,EAAE,iBAAiB,EAAE,IAAI,CAAC,KAAK,EAAE,EAAE,CAAC;QACrF,KAAK,MAAM;YACT,mFAAmF;YACnF,OAAO,EAAE,WAAW,EAAE,kBAAkB,EAAE,CAAC;IAC/C,CAAC;AACH,CAAC"}
|
|
@@ -1,14 +1,29 @@
|
|
|
1
|
-
import type { BootstrapResult } from '../api.js';
|
|
1
|
+
import type { AgentApi, BootstrapResult } from '../api.js';
|
|
2
|
+
/** Canonical openclaw.json location — `<stateDir>/openclaw.json`. */
|
|
3
|
+
export declare function getOpenclawJsonPath(): string;
|
|
2
4
|
/**
|
|
3
|
-
*
|
|
5
|
+
* The ONE writer for openclaw.json — atomic (tmp + rename) and mode 0600.
|
|
6
|
+
*
|
|
7
|
+
* Both properties are load-bearing and used to be split across three
|
|
8
|
+
* independent write sites: the full apply wrote 0600 but non-atomically (a
|
|
9
|
+
* reader could see a truncated file), the scoped merge wrote atomically but
|
|
10
|
+
* with no mode (tmp + rename RESETS a pre-existing 0600 file to 0644, leaking
|
|
11
|
+
* `models.providers[*].apiKey`), and the startup memory-MCP injection did
|
|
12
|
+
* neither. Everything goes through here now.
|
|
13
|
+
*/
|
|
14
|
+
export declare function writeOpenclawJson(data: Record<string, unknown>): Promise<void>;
|
|
15
|
+
/**
|
|
16
|
+
* FULL apply — only ever legal on a managed install (see `isManagedDeploy`).
|
|
17
|
+
* Rewrites files wholesale:
|
|
4
18
|
* 1. Write openclaw.json
|
|
5
|
-
* 2. Write
|
|
6
|
-
* 3. Write .
|
|
7
|
-
* 4.
|
|
19
|
+
* 2. Write workspace files + skills
|
|
20
|
+
* 3. Write auth-profiles.json + settings.json (from envVars)
|
|
21
|
+
* 4. MERGE .env (for VM agents) — never a wholesale replace, see step 4 below
|
|
22
|
+
* 5. Restart gateway
|
|
8
23
|
*/
|
|
9
24
|
export declare function applyBootstrapConfig(data: BootstrapResult): Promise<void>;
|
|
10
|
-
type MergeOutcome = 'added' | 'equal' | 'conflict' | 'merged';
|
|
11
|
-
interface MergeResult {
|
|
25
|
+
type MergeOutcome = 'added' | 'equal' | 'conflict' | 'merged' | 'overwritten';
|
|
26
|
+
export interface MergeResult {
|
|
12
27
|
changed: boolean;
|
|
13
28
|
outcomes: Array<{
|
|
14
29
|
path: string;
|
|
@@ -26,12 +41,50 @@ interface MergeResult {
|
|
|
26
41
|
* - Missing local value → remote is written.
|
|
27
42
|
* - Equal values → no-op.
|
|
28
43
|
* - Differing values → conflict, local wins, warn+skip logged.
|
|
29
|
-
* - For
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
44
|
+
* - For object paths: conflict detection is per-key inside the dict.
|
|
45
|
+
* - **Exception — `mcp.servers` in openclaw.json is REMOTE-wins per key.**
|
|
46
|
+
* That section is backend-managed: the URL, transport and bearer token of a
|
|
47
|
+
* backend-generated server (e.g. `openclaw-cloud`) change over time, and
|
|
48
|
+
* under local-wins an updated entry could never reach a standalone agent —
|
|
49
|
+
* a rotated token was skipped forever (observed live 2026-08-02). Every
|
|
50
|
+
* server NAME present in the payload is overwritten; names that exist only
|
|
51
|
+
* locally are left untouched.
|
|
52
|
+
* LIMITATION — no deletions. A server removed in the backend stays in the
|
|
53
|
+
* local openclaw.json: the payload cannot distinguish "removed upstream"
|
|
54
|
+
* from "never managed here", and dropping local-only entries would delete
|
|
55
|
+
* the user's own servers. Removal on standalone is a manual edit.
|
|
56
|
+
* - Restarts the gateway **iff** the `mcp.servers` subtree actually changed.
|
|
57
|
+
* This is a FALLBACK, not the primary delivery mechanism: openclaw 2026.7.1
|
|
58
|
+
* does self-reload this section (verified live 2026-08-03 — the gateway
|
|
59
|
+
* logged `[reload] config hot reload applied (mcp.servers.<name>.url,
|
|
60
|
+
* mcp.servers.<name>.headers)` on an overwrite, with no restart). The
|
|
61
|
+
* restart covers builds/paths where that self-reload does not fire, and
|
|
62
|
+
* mirrors what applyBootstrapConfig does on managed installs. It is
|
|
63
|
+
* best-effort: a failure is logged and does not fail the apply — on a
|
|
64
|
+
* launchd box where `openclaw` is not on the service PATH it never runs at
|
|
65
|
+
* all, and the merge still lands.
|
|
66
|
+
* - Settings.json (~/.claude/settings.json) keeps LOCAL-wins for
|
|
67
|
+
* `mcp.servers` ONLY — apiKeyHelper/permissions/env/etc untouched. `env` is
|
|
68
|
+
* never written here: it would redirect the user's own Claude Code sessions
|
|
69
|
+
* to the platform proxy (see MERGEABLE_SETTINGS_PATHS).
|
|
34
70
|
* - auth-profiles.json and .env are NOT touched on standalone.
|
|
35
71
|
*/
|
|
36
72
|
export declare function applyMergeableConfig(data: BootstrapResult): Promise<MergeResult>;
|
|
73
|
+
export interface ApplyConfigOutcome {
|
|
74
|
+
/** True when the full apply ran (managed install), false for scoped merge. */
|
|
75
|
+
managed: boolean;
|
|
76
|
+
/** Present only on the scoped-merge path. */
|
|
77
|
+
mergeResult?: MergeResult;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* The one owner of "fetch bootstrap and apply it". Every caller — the
|
|
81
|
+
* `update_config` WS handler, the `bootstrap` CLI, the opt-in startup refresh —
|
|
82
|
+
* goes through here so the deploy-type decision cannot drift between them.
|
|
83
|
+
*
|
|
84
|
+
* Managed installs ('vm'/'k8s') are provisioned end to end by the platform and
|
|
85
|
+
* get the full apply. Anything else — 'standalone', 'external', or a payload
|
|
86
|
+
* from an older backend that omits `deploymentType` — is a third-party machine
|
|
87
|
+
* and gets the scoped, additive merge only. Never rewrite files we don't own.
|
|
88
|
+
*/
|
|
89
|
+
export declare function fetchAndApplyConfig(api: AgentApi, agentId: string): Promise<ApplyConfigOutcome>;
|
|
37
90
|
export {};
|