@stamn/stamn-plugin 0.1.0-alpha.33 → 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 CHANGED
@@ -4472,7 +4472,7 @@ ${l}
4472
4472
  }
4473
4473
  } }).prompt();
4474
4474
 
4475
- // node_modules/.pnpm/@stamn+sdk@0.1.0-alpha.2/node_modules/@stamn/sdk/dist/index.js
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((resolve2) => setTimeout(resolve2, ms));
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.7/node_modules/@stamn/cli/dist/chunk-Z2IAJQOV.js
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.writeConfig({ agentId: match.id, agentName: match.name });
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.writeConfig({ agentId: participant.id, agentName: participant.name });
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
- adapter.writeConfig({ agentId: match.id, agentName: match.name });
4931
- R2.success(`Active agent set to "${match.name}" (${match.id})`);
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) {
@@ -5403,6 +5451,114 @@ function writeWorkspaceFile(relativePath, content) {
5403
5451
  return { path: relativePath, written: true };
5404
5452
  }
5405
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
+
5406
5562
  // src/ws-service.ts
5407
5563
  var MAX_EVENT_BUFFER_SIZE = 200;
5408
5564
  var BASE_RECONNECT_DELAY_MS = 1e3;
@@ -5592,6 +5748,26 @@ var StamnWsService = class {
5592
5748
  this.handleWriteFile(payload.params);
5593
5749
  return;
5594
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
+ }
5595
5771
  this.logger.info(`Command received: ${payload.command} (${payload.commandId})`);
5596
5772
  if (payload.command === "update_plugin") {
5597
5773
  this.handleUpdatePlugin();
@@ -5685,6 +5861,87 @@ var StamnWsService = class {
5685
5861
  });
5686
5862
  }
5687
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
+ }
5688
5945
  onAuthError(payload) {
5689
5946
  this.authFailed = true;
5690
5947
  this.logger.error(`Authentication failed: ${payload.reason}`);