@stamn/stamn-plugin 0.1.0-alpha.32 → 0.1.0-alpha.34
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 +274 -8
- package/dist/index.js.map +1 -1
- package/openclaw.plugin.json +17 -0
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -4472,7 +4472,7 @@ ${l}
|
|
|
4472
4472
|
}
|
|
4473
4473
|
} }).prompt();
|
|
4474
4474
|
|
|
4475
|
-
// node_modules/.pnpm/@stamn+sdk@0.1.0-alpha.
|
|
4475
|
+
// node_modules/.pnpm/@stamn+sdk@0.1.0-alpha.3/node_modules/@stamn/sdk/dist/index.js
|
|
4476
4476
|
var Resource = class {
|
|
4477
4477
|
constructor(client) {
|
|
4478
4478
|
this.client = client;
|
|
@@ -4676,6 +4676,42 @@ var ServicesResource = class extends Resource {
|
|
|
4676
4676
|
);
|
|
4677
4677
|
}
|
|
4678
4678
|
};
|
|
4679
|
+
var RuntimeResource = class extends Resource {
|
|
4680
|
+
async listHosts() {
|
|
4681
|
+
const res = await this.client.request(
|
|
4682
|
+
"GET",
|
|
4683
|
+
"/v1/runtime/hosts"
|
|
4684
|
+
);
|
|
4685
|
+
return res.data;
|
|
4686
|
+
}
|
|
4687
|
+
async listFiles(scope, hostname2) {
|
|
4688
|
+
const params = new URLSearchParams({ scope });
|
|
4689
|
+
if (hostname2) params.set("hostname", hostname2);
|
|
4690
|
+
const res = await this.client.request("GET", `/v1/runtime/files?${params}`);
|
|
4691
|
+
return res.data.files;
|
|
4692
|
+
}
|
|
4693
|
+
async readFile(scope, path, hostname2) {
|
|
4694
|
+
const params = new URLSearchParams({ scope, path });
|
|
4695
|
+
if (hostname2) params.set("hostname", hostname2);
|
|
4696
|
+
const res = await this.client.request("GET", `/v1/runtime/files/read?${params}`);
|
|
4697
|
+
return res.data;
|
|
4698
|
+
}
|
|
4699
|
+
async writeFile(scope, path, content, hostname2) {
|
|
4700
|
+
const res = await this.client.request("PATCH", "/v1/runtime/files/write", { scope, path, content, hostname: hostname2 });
|
|
4701
|
+
return res.data;
|
|
4702
|
+
}
|
|
4703
|
+
async readConfig(hostname2) {
|
|
4704
|
+
const params = new URLSearchParams();
|
|
4705
|
+
if (hostname2) params.set("hostname", hostname2);
|
|
4706
|
+
const qs = params.toString();
|
|
4707
|
+
const res = await this.client.request("GET", `/v1/runtime/config${qs ? `?${qs}` : ""}`);
|
|
4708
|
+
return res.data;
|
|
4709
|
+
}
|
|
4710
|
+
async writeConfig(content, hostname2) {
|
|
4711
|
+
const res = await this.client.request("PATCH", "/v1/runtime/config", { content, hostname: hostname2 });
|
|
4712
|
+
return res.data;
|
|
4713
|
+
}
|
|
4714
|
+
};
|
|
4679
4715
|
var StamnApiError = class extends Error {
|
|
4680
4716
|
constructor(message, status) {
|
|
4681
4717
|
super(message);
|
|
@@ -4702,6 +4738,7 @@ var StamnClient = class {
|
|
|
4702
4738
|
leaderboard;
|
|
4703
4739
|
health;
|
|
4704
4740
|
services;
|
|
4741
|
+
runtime;
|
|
4705
4742
|
constructor(options = {}) {
|
|
4706
4743
|
this.apiKey = options.apiKey;
|
|
4707
4744
|
this.retryOptions = { ...DEFAULT_RETRY, ...options.retry };
|
|
@@ -4713,6 +4750,7 @@ var StamnClient = class {
|
|
|
4713
4750
|
this.leaderboard = new LeaderboardResource(this);
|
|
4714
4751
|
this.health = new HealthResource(this);
|
|
4715
4752
|
this.services = new ServicesResource(this);
|
|
4753
|
+
this.runtime = new RuntimeResource(this);
|
|
4716
4754
|
}
|
|
4717
4755
|
setApiKey(apiKey) {
|
|
4718
4756
|
this.apiKey = apiKey;
|
|
@@ -4767,7 +4805,7 @@ var StamnClient = class {
|
|
|
4767
4805
|
return Math.random() * capped;
|
|
4768
4806
|
}
|
|
4769
4807
|
sleep(ms) {
|
|
4770
|
-
return new Promise((
|
|
4808
|
+
return new Promise((resolve3) => setTimeout(resolve3, ms));
|
|
4771
4809
|
}
|
|
4772
4810
|
async parseErrorResponse(res) {
|
|
4773
4811
|
const body = await res.text();
|
|
@@ -4781,7 +4819,7 @@ var StamnClient = class {
|
|
|
4781
4819
|
}
|
|
4782
4820
|
};
|
|
4783
4821
|
|
|
4784
|
-
// node_modules/.pnpm/@stamn+cli@0.1.0-alpha.
|
|
4822
|
+
// node_modules/.pnpm/@stamn+cli@0.1.0-alpha.10/node_modules/@stamn/cli/dist/chunk-VAKVDZRN.js
|
|
4785
4823
|
import { execSync } from "child_process";
|
|
4786
4824
|
import { mkdirSync, readFileSync, writeFileSync, unlinkSync } from "fs";
|
|
4787
4825
|
import { join } from "path";
|
|
@@ -4862,7 +4900,7 @@ async function handleAgentRegister(opts, adapter) {
|
|
|
4862
4900
|
const match = agents.find((a) => a.name === name);
|
|
4863
4901
|
if (match) {
|
|
4864
4902
|
s.stop("Agent found.");
|
|
4865
|
-
adapter
|
|
4903
|
+
writeResult(adapter, name, match.id, match.name, config.apiKey);
|
|
4866
4904
|
R2.success(`Agent "${match.name}" (${match.id}) already exists. Selected as active.`);
|
|
4867
4905
|
Gt("Done!");
|
|
4868
4906
|
process.exit(0);
|
|
@@ -4870,8 +4908,9 @@ async function handleAgentRegister(opts, adapter) {
|
|
|
4870
4908
|
s.start("Registering agent...");
|
|
4871
4909
|
const participant = await client.participants.create({ name });
|
|
4872
4910
|
s.stop("Agent registered.");
|
|
4873
|
-
adapter
|
|
4911
|
+
writeResult(adapter, name, participant.id, participant.name, config.apiKey);
|
|
4874
4912
|
R2.success(`Agent "${participant.name}" (${participant.id})`);
|
|
4913
|
+
R2.info(`Bound to OpenClaw agent "${name}".`);
|
|
4875
4914
|
Gt("Done!");
|
|
4876
4915
|
process.exit(0);
|
|
4877
4916
|
} catch (err) {
|
|
@@ -4880,6 +4919,10 @@ async function handleAgentRegister(opts, adapter) {
|
|
|
4880
4919
|
process.exit(1);
|
|
4881
4920
|
}
|
|
4882
4921
|
}
|
|
4922
|
+
function writeResult(adapter, name, agentId, agentName, apiKey) {
|
|
4923
|
+
adapter.writeAgentBinding(name, { agentId, apiKey, agentName });
|
|
4924
|
+
adapter.writeConfig({ agentId, agentName });
|
|
4925
|
+
}
|
|
4883
4926
|
async function handleAgentList(_opts, adapter) {
|
|
4884
4927
|
Wt2("Stamn Agents");
|
|
4885
4928
|
const config = adapter.readConfig();
|
|
@@ -4927,8 +4970,13 @@ async function handleAgentSelect(opts, adapter) {
|
|
|
4927
4970
|
process.exit(1);
|
|
4928
4971
|
return;
|
|
4929
4972
|
}
|
|
4930
|
-
|
|
4931
|
-
|
|
4973
|
+
if (opts.bind) {
|
|
4974
|
+
adapter.writeAgentBinding(opts.bind, { agentId: match.id, apiKey: config.apiKey, agentName: match.name });
|
|
4975
|
+
R2.success(`Agent "${match.name}" (${match.id}) bound to OpenClaw agent "${opts.bind}".`);
|
|
4976
|
+
} else {
|
|
4977
|
+
adapter.writeConfig({ agentId: match.id, agentName: match.name });
|
|
4978
|
+
R2.success(`Active agent set to "${match.name}" (${match.id})`);
|
|
4979
|
+
}
|
|
4932
4980
|
Gt("Done!");
|
|
4933
4981
|
process.exit(0);
|
|
4934
4982
|
} catch (err) {
|
|
@@ -5138,6 +5186,15 @@ function createOpenclawAdapter() {
|
|
|
5138
5186
|
};
|
|
5139
5187
|
writeJsonFile(getConfigPath(), config);
|
|
5140
5188
|
},
|
|
5189
|
+
writeAgentBinding(openclawAgentId, binding) {
|
|
5190
|
+
const config = readOpenclawConfig();
|
|
5191
|
+
ensurePluginConfig(config);
|
|
5192
|
+
config.plugins.entries[PLUGIN_ID].enabled = true;
|
|
5193
|
+
const pluginConfig = config.plugins.entries[PLUGIN_ID].config;
|
|
5194
|
+
if (!pluginConfig.agents) pluginConfig.agents = {};
|
|
5195
|
+
pluginConfig.agents[openclawAgentId] = binding;
|
|
5196
|
+
writeJsonFile(getConfigPath(), config);
|
|
5197
|
+
},
|
|
5141
5198
|
readStatusFile() {
|
|
5142
5199
|
return readJsonFile(join3(homedir(), ".openclaw", "stamn-status.json"));
|
|
5143
5200
|
},
|
|
@@ -5222,7 +5279,7 @@ function registerCli(api) {
|
|
|
5222
5279
|
const agent = stamn.command("agent").description("Agent management");
|
|
5223
5280
|
agent.command("register").description("Register a new agent or reconnect to an existing one").option("--name <name>", "Agent name").action((opts) => handleAgentRegister(opts, adapter));
|
|
5224
5281
|
agent.command("list").description("List agents under your account").action(() => handleAgentList({}, adapter));
|
|
5225
|
-
agent.command("select").description("Set active agent").argument("<nameOrId>", "Agent name or ID").action((nameOrId) => handleAgentSelect({ nameOrId }, adapter));
|
|
5282
|
+
agent.command("select").description("Set active agent").argument("<nameOrId>", "Agent name or ID").option("--bind <agentId>", "Bind to a specific OpenClaw agent ID (for multi-agent setups)").action((nameOrId, opts) => handleAgentSelect({ nameOrId, ...opts }, adapter));
|
|
5226
5283
|
agent.command("config").description("View or update agent configuration").option("--name <name>", "Agent display name").option("--personality", "Open editor to set agent personality").action((opts) => handleConfig(opts, adapter));
|
|
5227
5284
|
stamn.command("status").description("Show connection status and server health").action(() => handleStatus(adapter));
|
|
5228
5285
|
stamn.command("update").description("Update the Stamn plugin to the latest version").action(() => handleUpdate());
|
|
@@ -5394,6 +5451,114 @@ function writeWorkspaceFile(relativePath, content) {
|
|
|
5394
5451
|
return { path: relativePath, written: true };
|
|
5395
5452
|
}
|
|
5396
5453
|
|
|
5454
|
+
// src/global-files.ts
|
|
5455
|
+
import { readdirSync as readdirSync2, readFileSync as readFileSync4, writeFileSync as writeFileSync5, statSync as statSync3, mkdirSync as mkdirSync4, realpathSync as realpathSync2, existsSync as existsSync3 } from "fs";
|
|
5456
|
+
import { join as join7, resolve as resolve2, relative as relative2, dirname as dirname3 } from "path";
|
|
5457
|
+
import { homedir as homedir4 } from "os";
|
|
5458
|
+
var OPENCLAW_DIR = join7(homedir4(), ".openclaw");
|
|
5459
|
+
var CONFIG_FILE = join7(OPENCLAW_DIR, "openclaw.json");
|
|
5460
|
+
var SCOPE_DIRS = {
|
|
5461
|
+
skills: join7(OPENCLAW_DIR, "skills"),
|
|
5462
|
+
workspace: join7(OPENCLAW_DIR, "workspace"),
|
|
5463
|
+
config: OPENCLAW_DIR
|
|
5464
|
+
};
|
|
5465
|
+
function resolveBaseDir(scope) {
|
|
5466
|
+
const dir = SCOPE_DIRS[scope];
|
|
5467
|
+
if (!dir) throw new Error(`Invalid scope: ${scope}`);
|
|
5468
|
+
return dir;
|
|
5469
|
+
}
|
|
5470
|
+
function realBase(dir) {
|
|
5471
|
+
try {
|
|
5472
|
+
return realpathSync2(dir);
|
|
5473
|
+
} catch {
|
|
5474
|
+
return dir;
|
|
5475
|
+
}
|
|
5476
|
+
}
|
|
5477
|
+
function assertWithinScope(scope, relativePath) {
|
|
5478
|
+
const base = resolveBaseDir(scope);
|
|
5479
|
+
const full = resolve2(base, relativePath);
|
|
5480
|
+
if (!full.startsWith(base + "/") && full !== base) {
|
|
5481
|
+
throw new Error("Path outside scope");
|
|
5482
|
+
}
|
|
5483
|
+
const baseReal = realBase(base);
|
|
5484
|
+
try {
|
|
5485
|
+
const realFull = realpathSync2(full);
|
|
5486
|
+
if (!realFull.startsWith(baseReal + "/") && realFull !== baseReal) {
|
|
5487
|
+
throw new Error("Path outside scope");
|
|
5488
|
+
}
|
|
5489
|
+
} catch (err) {
|
|
5490
|
+
if (err.code === "ENOENT") {
|
|
5491
|
+
try {
|
|
5492
|
+
const parentReal = realpathSync2(dirname3(full));
|
|
5493
|
+
if (!parentReal.startsWith(baseReal + "/") && parentReal !== baseReal) {
|
|
5494
|
+
throw new Error("Path outside scope");
|
|
5495
|
+
}
|
|
5496
|
+
} catch {
|
|
5497
|
+
}
|
|
5498
|
+
} else {
|
|
5499
|
+
throw err;
|
|
5500
|
+
}
|
|
5501
|
+
}
|
|
5502
|
+
return full;
|
|
5503
|
+
}
|
|
5504
|
+
function walkDir2(dir, base) {
|
|
5505
|
+
const results = [];
|
|
5506
|
+
let entries;
|
|
5507
|
+
try {
|
|
5508
|
+
entries = readdirSync2(dir, { withFileTypes: true });
|
|
5509
|
+
} catch {
|
|
5510
|
+
return results;
|
|
5511
|
+
}
|
|
5512
|
+
for (const entry of entries) {
|
|
5513
|
+
const fullPath = join7(dir, entry.name);
|
|
5514
|
+
if (entry.isDirectory()) {
|
|
5515
|
+
results.push(...walkDir2(fullPath, base));
|
|
5516
|
+
} else if (entry.isFile() && entry.name.endsWith(".md")) {
|
|
5517
|
+
const stat = statSync3(fullPath);
|
|
5518
|
+
results.push({
|
|
5519
|
+
path: relative2(base, fullPath),
|
|
5520
|
+
size: stat.size,
|
|
5521
|
+
modifiedAt: stat.mtime.toISOString()
|
|
5522
|
+
});
|
|
5523
|
+
}
|
|
5524
|
+
}
|
|
5525
|
+
return results;
|
|
5526
|
+
}
|
|
5527
|
+
function listGlobalFiles(scope) {
|
|
5528
|
+
const base = resolveBaseDir(scope);
|
|
5529
|
+
return walkDir2(base, base);
|
|
5530
|
+
}
|
|
5531
|
+
function readGlobalFile(scope, relativePath) {
|
|
5532
|
+
const full = assertWithinScope(scope, relativePath);
|
|
5533
|
+
const content = readFileSync4(full, "utf-8");
|
|
5534
|
+
const stat = statSync3(full);
|
|
5535
|
+
return { path: relativePath, content, size: stat.size };
|
|
5536
|
+
}
|
|
5537
|
+
function writeGlobalFile(scope, relativePath, content) {
|
|
5538
|
+
const full = assertWithinScope(scope, relativePath);
|
|
5539
|
+
mkdirSync4(dirname3(full), { recursive: true });
|
|
5540
|
+
writeFileSync5(full, content, "utf-8");
|
|
5541
|
+
return { path: relativePath, written: true };
|
|
5542
|
+
}
|
|
5543
|
+
function readOpenclawConfig2() {
|
|
5544
|
+
if (!existsSync3(CONFIG_FILE)) {
|
|
5545
|
+
return { path: "openclaw.json", content: "{}", size: 2 };
|
|
5546
|
+
}
|
|
5547
|
+
const content = readFileSync4(CONFIG_FILE, "utf-8");
|
|
5548
|
+
const stat = statSync3(CONFIG_FILE);
|
|
5549
|
+
return { path: "openclaw.json", content, size: stat.size };
|
|
5550
|
+
}
|
|
5551
|
+
function writeOpenclawConfig(content) {
|
|
5552
|
+
try {
|
|
5553
|
+
JSON.parse(content);
|
|
5554
|
+
} catch {
|
|
5555
|
+
throw new Error("Invalid JSON: config must be valid JSON");
|
|
5556
|
+
}
|
|
5557
|
+
mkdirSync4(dirname3(CONFIG_FILE), { recursive: true });
|
|
5558
|
+
writeFileSync5(CONFIG_FILE, content, "utf-8");
|
|
5559
|
+
return { path: "openclaw.json", written: true };
|
|
5560
|
+
}
|
|
5561
|
+
|
|
5397
5562
|
// src/ws-service.ts
|
|
5398
5563
|
var MAX_EVENT_BUFFER_SIZE = 200;
|
|
5399
5564
|
var BASE_RECONNECT_DELAY_MS = 1e3;
|
|
@@ -5583,6 +5748,26 @@ var StamnWsService = class {
|
|
|
5583
5748
|
this.handleWriteFile(payload.params);
|
|
5584
5749
|
return;
|
|
5585
5750
|
}
|
|
5751
|
+
if (payload.command === "list_global_files") {
|
|
5752
|
+
this.handleListGlobalFiles(payload.params);
|
|
5753
|
+
return;
|
|
5754
|
+
}
|
|
5755
|
+
if (payload.command === "read_global_file") {
|
|
5756
|
+
this.handleReadGlobalFile(payload.params);
|
|
5757
|
+
return;
|
|
5758
|
+
}
|
|
5759
|
+
if (payload.command === "write_global_file") {
|
|
5760
|
+
this.handleWriteGlobalFile(payload.params);
|
|
5761
|
+
return;
|
|
5762
|
+
}
|
|
5763
|
+
if (payload.command === "read_openclaw_config") {
|
|
5764
|
+
this.handleReadOpenclawConfig(payload.params);
|
|
5765
|
+
return;
|
|
5766
|
+
}
|
|
5767
|
+
if (payload.command === "write_openclaw_config") {
|
|
5768
|
+
this.handleWriteOpenclawConfig(payload.params);
|
|
5769
|
+
return;
|
|
5770
|
+
}
|
|
5586
5771
|
this.logger.info(`Command received: ${payload.command} (${payload.commandId})`);
|
|
5587
5772
|
if (payload.command === "update_plugin") {
|
|
5588
5773
|
this.handleUpdatePlugin();
|
|
@@ -5676,6 +5861,87 @@ var StamnWsService = class {
|
|
|
5676
5861
|
});
|
|
5677
5862
|
}
|
|
5678
5863
|
}
|
|
5864
|
+
handleListGlobalFiles(params) {
|
|
5865
|
+
try {
|
|
5866
|
+
const files = listGlobalFiles(params.scope);
|
|
5867
|
+
this.sendMessage("participant:file_response", {
|
|
5868
|
+
requestId: params.requestId,
|
|
5869
|
+
files
|
|
5870
|
+
});
|
|
5871
|
+
} catch (err) {
|
|
5872
|
+
this.sendMessage("participant:file_response", {
|
|
5873
|
+
requestId: params.requestId,
|
|
5874
|
+
files: [],
|
|
5875
|
+
error: err.message
|
|
5876
|
+
});
|
|
5877
|
+
}
|
|
5878
|
+
}
|
|
5879
|
+
handleReadGlobalFile(params) {
|
|
5880
|
+
try {
|
|
5881
|
+
const result = readGlobalFile(params.scope, params.path);
|
|
5882
|
+
this.sendMessage("participant:file_response", {
|
|
5883
|
+
requestId: params.requestId,
|
|
5884
|
+
...result
|
|
5885
|
+
});
|
|
5886
|
+
} catch (err) {
|
|
5887
|
+
this.sendMessage("participant:file_response", {
|
|
5888
|
+
requestId: params.requestId,
|
|
5889
|
+
path: params.path,
|
|
5890
|
+
content: "",
|
|
5891
|
+
size: 0,
|
|
5892
|
+
error: err.message
|
|
5893
|
+
});
|
|
5894
|
+
}
|
|
5895
|
+
}
|
|
5896
|
+
handleWriteGlobalFile(params) {
|
|
5897
|
+
try {
|
|
5898
|
+
const result = writeGlobalFile(params.scope, params.path, params.content);
|
|
5899
|
+
this.sendMessage("participant:file_response", {
|
|
5900
|
+
requestId: params.requestId,
|
|
5901
|
+
...result
|
|
5902
|
+
});
|
|
5903
|
+
} catch (err) {
|
|
5904
|
+
this.sendMessage("participant:file_response", {
|
|
5905
|
+
requestId: params.requestId,
|
|
5906
|
+
path: params.path,
|
|
5907
|
+
written: false,
|
|
5908
|
+
error: err.message
|
|
5909
|
+
});
|
|
5910
|
+
}
|
|
5911
|
+
}
|
|
5912
|
+
handleReadOpenclawConfig(params) {
|
|
5913
|
+
try {
|
|
5914
|
+
const result = readOpenclawConfig2();
|
|
5915
|
+
this.sendMessage("participant:file_response", {
|
|
5916
|
+
requestId: params.requestId,
|
|
5917
|
+
...result
|
|
5918
|
+
});
|
|
5919
|
+
} catch (err) {
|
|
5920
|
+
this.sendMessage("participant:file_response", {
|
|
5921
|
+
requestId: params.requestId,
|
|
5922
|
+
path: "openclaw.json",
|
|
5923
|
+
content: "",
|
|
5924
|
+
size: 0,
|
|
5925
|
+
error: err.message
|
|
5926
|
+
});
|
|
5927
|
+
}
|
|
5928
|
+
}
|
|
5929
|
+
handleWriteOpenclawConfig(params) {
|
|
5930
|
+
try {
|
|
5931
|
+
const result = writeOpenclawConfig(params.content);
|
|
5932
|
+
this.sendMessage("participant:file_response", {
|
|
5933
|
+
requestId: params.requestId,
|
|
5934
|
+
...result
|
|
5935
|
+
});
|
|
5936
|
+
} catch (err) {
|
|
5937
|
+
this.sendMessage("participant:file_response", {
|
|
5938
|
+
requestId: params.requestId,
|
|
5939
|
+
path: "openclaw.json",
|
|
5940
|
+
written: false,
|
|
5941
|
+
error: err.message
|
|
5942
|
+
});
|
|
5943
|
+
}
|
|
5944
|
+
}
|
|
5679
5945
|
onAuthError(payload) {
|
|
5680
5946
|
this.authFailed = true;
|
|
5681
5947
|
this.logger.error(`Authentication failed: ${payload.reason}`);
|