@stamn/stamn-plugin 0.1.0-alpha.17 → 0.1.0-alpha.19
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/index.js +136 -5
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -5435,6 +5435,78 @@ var import_websocket = __toESM(require_websocket(), 1);
|
|
|
5435
5435
|
var import_websocket_server = __toESM(require_websocket_server(), 1);
|
|
5436
5436
|
var wrapper_default = import_websocket.default;
|
|
5437
5437
|
|
|
5438
|
+
// src/ws-service.ts
|
|
5439
|
+
import { hostname } from "os";
|
|
5440
|
+
import { execFile } from "child_process";
|
|
5441
|
+
|
|
5442
|
+
// src/log-reader.ts
|
|
5443
|
+
import { openSync, readSync, closeSync, statSync } from "fs";
|
|
5444
|
+
import { join as join5 } from "path";
|
|
5445
|
+
import { tmpdir as tmpdir3 } from "os";
|
|
5446
|
+
var LOG_DIR = join5(tmpdir3(), "openclaw");
|
|
5447
|
+
var DEFAULT_MAX_BYTES = 64 * 1024;
|
|
5448
|
+
var DEFAULT_LIMIT = 200;
|
|
5449
|
+
function getLogFilePath() {
|
|
5450
|
+
const date = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
5451
|
+
return join5(LOG_DIR, `openclaw-${date}.log`);
|
|
5452
|
+
}
|
|
5453
|
+
function readLogs(opts) {
|
|
5454
|
+
const file = getLogFilePath();
|
|
5455
|
+
const limit = opts.limit ?? DEFAULT_LIMIT;
|
|
5456
|
+
const maxBytes = opts.maxBytes ?? DEFAULT_MAX_BYTES;
|
|
5457
|
+
let cursor = opts.cursor;
|
|
5458
|
+
let stat;
|
|
5459
|
+
try {
|
|
5460
|
+
stat = statSync(file);
|
|
5461
|
+
} catch {
|
|
5462
|
+
return { lines: [], cursor: 0, size: 0, file, truncated: false, reset: false };
|
|
5463
|
+
}
|
|
5464
|
+
const size = stat.size;
|
|
5465
|
+
const reset = cursor > size;
|
|
5466
|
+
if (reset) cursor = 0;
|
|
5467
|
+
if (cursor >= size) {
|
|
5468
|
+
return { lines: [], cursor, size, file, truncated: false, reset };
|
|
5469
|
+
}
|
|
5470
|
+
const bytesToRead = Math.min(maxBytes, size - cursor);
|
|
5471
|
+
const buffer = Buffer.alloc(bytesToRead);
|
|
5472
|
+
const fd = openSync(file, "r");
|
|
5473
|
+
try {
|
|
5474
|
+
readSync(fd, buffer, 0, bytesToRead, cursor);
|
|
5475
|
+
} finally {
|
|
5476
|
+
closeSync(fd);
|
|
5477
|
+
}
|
|
5478
|
+
const raw = buffer.toString("utf-8");
|
|
5479
|
+
const rawLines = raw.split("\n");
|
|
5480
|
+
const atEof = cursor + bytesToRead >= size;
|
|
5481
|
+
let actualBytesConsumed = bytesToRead;
|
|
5482
|
+
if (!atEof && rawLines.length > 0 && !raw.endsWith("\n")) {
|
|
5483
|
+
const incomplete = rawLines.pop();
|
|
5484
|
+
actualBytesConsumed -= Buffer.byteLength(incomplete, "utf-8");
|
|
5485
|
+
}
|
|
5486
|
+
const lines = [];
|
|
5487
|
+
let truncated = false;
|
|
5488
|
+
for (const line of rawLines) {
|
|
5489
|
+
const trimmed = line.trim();
|
|
5490
|
+
if (!trimmed) continue;
|
|
5491
|
+
try {
|
|
5492
|
+
lines.push(JSON.parse(trimmed));
|
|
5493
|
+
} catch {
|
|
5494
|
+
}
|
|
5495
|
+
if (lines.length >= limit) {
|
|
5496
|
+
truncated = true;
|
|
5497
|
+
break;
|
|
5498
|
+
}
|
|
5499
|
+
}
|
|
5500
|
+
return {
|
|
5501
|
+
lines,
|
|
5502
|
+
cursor: cursor + actualBytesConsumed,
|
|
5503
|
+
size,
|
|
5504
|
+
file,
|
|
5505
|
+
truncated: truncated || !atEof,
|
|
5506
|
+
reset
|
|
5507
|
+
};
|
|
5508
|
+
}
|
|
5509
|
+
|
|
5438
5510
|
// src/ws-service.ts
|
|
5439
5511
|
var MAX_EVENT_BUFFER_SIZE = 200;
|
|
5440
5512
|
var BASE_RECONNECT_DELAY_MS = 1e3;
|
|
@@ -5444,6 +5516,7 @@ var PLUGIN_VERSION = "0.1.0";
|
|
|
5444
5516
|
var ServerEvent = {
|
|
5445
5517
|
AUTHENTICATED: "server:authenticated",
|
|
5446
5518
|
AUTH_ERROR: "server:auth_error",
|
|
5519
|
+
COMMAND: "server:command",
|
|
5447
5520
|
HEARTBEAT_ACK: "server:heartbeat_ack",
|
|
5448
5521
|
WORLD_UPDATE: "server:world_update",
|
|
5449
5522
|
BALANCE: "server:balance",
|
|
@@ -5482,6 +5555,7 @@ var StamnWsService = class {
|
|
|
5482
5555
|
this.messageHandlers = {
|
|
5483
5556
|
[ServerEvent.AUTHENTICATED]: (d) => this.onAuthenticated(d),
|
|
5484
5557
|
[ServerEvent.AUTH_ERROR]: (d) => this.onAuthError(d),
|
|
5558
|
+
[ServerEvent.COMMAND]: (d) => this.onCommand(d),
|
|
5485
5559
|
[ServerEvent.HEARTBEAT_ACK]: () => this.logger.debug("Heartbeat acknowledged"),
|
|
5486
5560
|
[ServerEvent.WORLD_UPDATE]: (d) => this.onWorldUpdate(d),
|
|
5487
5561
|
[ServerEvent.BALANCE]: (d) => this.onBalanceUpdate(d),
|
|
@@ -5499,11 +5573,7 @@ var StamnWsService = class {
|
|
|
5499
5573
|
async stop() {
|
|
5500
5574
|
this.clearTimers();
|
|
5501
5575
|
if (this.isSocketOpen()) {
|
|
5502
|
-
this.
|
|
5503
|
-
participantId: this.config.agentId,
|
|
5504
|
-
status: "shutting_down",
|
|
5505
|
-
version: PLUGIN_VERSION
|
|
5506
|
-
});
|
|
5576
|
+
this.sendStatusReport("shutting_down");
|
|
5507
5577
|
this.ws.close(1e3, "Plugin shutting down");
|
|
5508
5578
|
}
|
|
5509
5579
|
this.writeStatus(false);
|
|
@@ -5588,9 +5658,70 @@ var StamnWsService = class {
|
|
|
5588
5658
|
this.logger.info(
|
|
5589
5659
|
`Authenticated as ${payload.participantId} (server v${payload.serverVersion})`
|
|
5590
5660
|
);
|
|
5661
|
+
this.sendStatusReport("online");
|
|
5591
5662
|
this.startHeartbeat();
|
|
5592
5663
|
this.writeStatus(true);
|
|
5593
5664
|
}
|
|
5665
|
+
sendStatusReport(status) {
|
|
5666
|
+
this.sendMessage(ClientEvent.STATUS_REPORT, {
|
|
5667
|
+
participantId: this.config.agentId,
|
|
5668
|
+
status,
|
|
5669
|
+
version: PLUGIN_VERSION,
|
|
5670
|
+
platform: process.platform,
|
|
5671
|
+
hostname: hostname(),
|
|
5672
|
+
nodeVersion: process.version,
|
|
5673
|
+
arch: process.arch
|
|
5674
|
+
});
|
|
5675
|
+
}
|
|
5676
|
+
onCommand(payload) {
|
|
5677
|
+
this.logger.info(`Command received: ${payload.command} (${payload.commandId})`);
|
|
5678
|
+
if (payload.command === "update_plugin") {
|
|
5679
|
+
this.handleUpdatePlugin();
|
|
5680
|
+
return;
|
|
5681
|
+
}
|
|
5682
|
+
if (payload.command === "request_logs") {
|
|
5683
|
+
this.handleRequestLogs(payload.params);
|
|
5684
|
+
return;
|
|
5685
|
+
}
|
|
5686
|
+
this.bufferEvent(ServerEvent.COMMAND, payload);
|
|
5687
|
+
}
|
|
5688
|
+
handleUpdatePlugin() {
|
|
5689
|
+
this.logger.info("Updating plugin via openclaw...");
|
|
5690
|
+
execFile("openclaw", ["plugins", "update", "stamn-plugin"], (err, stdout, stderr) => {
|
|
5691
|
+
if (err) {
|
|
5692
|
+
this.logger.error(`Plugin update failed: ${err.message}`);
|
|
5693
|
+
if (stderr) this.logger.error(stderr);
|
|
5694
|
+
return;
|
|
5695
|
+
}
|
|
5696
|
+
this.logger.info(`Plugin updated: ${stdout.trim()}`);
|
|
5697
|
+
this.sendStatusReport("online");
|
|
5698
|
+
});
|
|
5699
|
+
}
|
|
5700
|
+
handleRequestLogs(params) {
|
|
5701
|
+
try {
|
|
5702
|
+
const result = readLogs({
|
|
5703
|
+
cursor: params.cursor,
|
|
5704
|
+
limit: params.limit,
|
|
5705
|
+
maxBytes: params.maxBytes
|
|
5706
|
+
});
|
|
5707
|
+
this.sendMessage("participant:log_response", {
|
|
5708
|
+
requestId: params.requestId,
|
|
5709
|
+
...result
|
|
5710
|
+
});
|
|
5711
|
+
} catch (err) {
|
|
5712
|
+
this.logger.error(`Failed to read logs: ${err}`);
|
|
5713
|
+
this.sendMessage("participant:log_response", {
|
|
5714
|
+
requestId: params.requestId,
|
|
5715
|
+
lines: [],
|
|
5716
|
+
cursor: params.cursor,
|
|
5717
|
+
size: 0,
|
|
5718
|
+
file: "",
|
|
5719
|
+
truncated: false,
|
|
5720
|
+
reset: false,
|
|
5721
|
+
error: err.message
|
|
5722
|
+
});
|
|
5723
|
+
}
|
|
5724
|
+
}
|
|
5594
5725
|
onAuthError(payload) {
|
|
5595
5726
|
this.authFailed = true;
|
|
5596
5727
|
this.logger.error(`Authentication failed: ${payload.reason}`);
|