clawpowers 2.0.0 → 2.2.1

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.
Files changed (63) hide show
  1. package/CHANGELOG.md +32 -0
  2. package/COMPATIBILITY.md +13 -0
  3. package/KNOWN_LIMITATIONS.md +19 -0
  4. package/LICENSING.md +10 -0
  5. package/README.md +201 -9
  6. package/SECURITY.md +33 -53
  7. package/dist/index.d.ts +638 -5
  8. package/dist/index.js +986 -58
  9. package/dist/index.js.map +1 -1
  10. package/native/Cargo.lock +4863 -0
  11. package/native/Cargo.toml +73 -0
  12. package/native/crates/canonical/Cargo.toml +24 -0
  13. package/native/crates/canonical/src/lib.rs +673 -0
  14. package/native/crates/compression/Cargo.toml +20 -0
  15. package/native/crates/compression/benches/compression_bench.rs +42 -0
  16. package/native/crates/compression/src/lib.rs +393 -0
  17. package/native/crates/evm-eth/Cargo.toml +13 -0
  18. package/native/crates/evm-eth/src/lib.rs +105 -0
  19. package/native/crates/fee/Cargo.toml +15 -0
  20. package/native/crates/fee/src/lib.rs +281 -0
  21. package/native/crates/index/Cargo.toml +16 -0
  22. package/native/crates/index/src/lib.rs +277 -0
  23. package/native/crates/policy/Cargo.toml +17 -0
  24. package/native/crates/policy/src/lib.rs +614 -0
  25. package/native/crates/security/Cargo.toml +22 -0
  26. package/native/crates/security/src/lib.rs +478 -0
  27. package/native/crates/tokens/Cargo.toml +13 -0
  28. package/native/crates/tokens/src/lib.rs +534 -0
  29. package/native/crates/verification/Cargo.toml +23 -0
  30. package/native/crates/verification/src/lib.rs +333 -0
  31. package/native/crates/wallet/Cargo.toml +20 -0
  32. package/native/crates/wallet/src/lib.rs +261 -0
  33. package/native/crates/x402/Cargo.toml +30 -0
  34. package/native/crates/x402/src/lib.rs +423 -0
  35. package/native/ffi/Cargo.toml +34 -0
  36. package/native/ffi/build.rs +4 -0
  37. package/native/ffi/index.node +0 -0
  38. package/native/ffi/src/lib.rs +352 -0
  39. package/native/ffi/tests/integration.rs +354 -0
  40. package/native/pyo3/Cargo.toml +26 -0
  41. package/native/pyo3/pyproject.toml +16 -0
  42. package/native/pyo3/src/lib.rs +407 -0
  43. package/native/pyo3/tests/test_smoke.py +180 -0
  44. package/native/wasm/Cargo.toml +44 -0
  45. package/native/wasm/pkg/.gitignore +6 -0
  46. package/native/wasm/pkg/clawpowers_wasm.d.ts +208 -0
  47. package/native/wasm/pkg/clawpowers_wasm.js +872 -0
  48. package/native/wasm/pkg/clawpowers_wasm_bg.wasm +0 -0
  49. package/native/wasm/pkg/clawpowers_wasm_bg.wasm.d.ts +40 -0
  50. package/native/wasm/pkg/package.json +17 -0
  51. package/native/wasm/pkg-node/.gitignore +6 -0
  52. package/native/wasm/pkg-node/clawpowers_wasm.d.ts +143 -0
  53. package/native/wasm/pkg-node/clawpowers_wasm.js +798 -0
  54. package/native/wasm/pkg-node/clawpowers_wasm_bg.wasm +0 -0
  55. package/native/wasm/pkg-node/clawpowers_wasm_bg.wasm.d.ts +40 -0
  56. package/native/wasm/pkg-node/package.json +13 -0
  57. package/native/wasm/src/lib.rs +433 -0
  58. package/package.json +24 -3
  59. package/src/skills/catalog.ts +435 -0
  60. package/src/skills/executor.ts +56 -0
  61. package/src/skills/index.ts +3 -0
  62. package/src/skills/itp/SKILL.md +112 -0
  63. package/src/skills/loader.ts +193 -0
package/dist/index.js CHANGED
@@ -448,7 +448,7 @@ import { z } from "zod";
448
448
  // src/constants.ts
449
449
  import { join } from "path";
450
450
  import { homedir } from "os";
451
- var VERSION = "2.0.0";
451
+ var VERSION = "2.2.0";
452
452
  var PACKAGE_NAME = "clawpowers";
453
453
  var CLAWPOWERS_HOME = join(homedir(), ".clawpowers");
454
454
  var CONFIG_PATH = join(CLAWPOWERS_HOME, "config.json");
@@ -632,6 +632,294 @@ function coerceValue(existing, value) {
632
632
  return value;
633
633
  }
634
634
 
635
+ // src/native/index.ts
636
+ import { createRequire } from "module";
637
+ import { fileURLToPath } from "url";
638
+ import { dirname as dirname2, join as join2 } from "path";
639
+ var __dirname = dirname2(fileURLToPath(import.meta.url));
640
+ var require2 = createRequire(import.meta.url);
641
+ var _native = null;
642
+ var _wasm = null;
643
+ var _activeTier = "typescript";
644
+ var _attempted = false;
645
+ function tryLoadNative() {
646
+ const candidates = [
647
+ join2(__dirname, "../../native/ffi/index.node"),
648
+ join2(__dirname, "../../native/ffi/clawpowers_ffi.node"),
649
+ join2(__dirname, "../../../native/ffi/index.node"),
650
+ join2(__dirname, "../../../native/ffi/clawpowers_ffi.node"),
651
+ join2(__dirname, "../native/ffi/index.node"),
652
+ join2(__dirname, "../native/ffi/clawpowers_ffi.node")
653
+ ];
654
+ for (const p of candidates) {
655
+ try {
656
+ const mod = require2(p);
657
+ console.log(`[clawpowers] Tier 1: Native acceleration enabled (${p})`);
658
+ return mod;
659
+ } catch {
660
+ }
661
+ }
662
+ return null;
663
+ }
664
+ function tryLoadWasm() {
665
+ const wasmCandidates = [
666
+ join2(__dirname, "../native/wasm/pkg-node/clawpowers_wasm.js"),
667
+ join2(__dirname, "../native/wasm/pkg/clawpowers_wasm.js"),
668
+ join2(__dirname, "../../native/wasm/pkg-node/clawpowers_wasm.js"),
669
+ join2(__dirname, "../../native/wasm/pkg/clawpowers_wasm.js")
670
+ ];
671
+ for (const p of wasmCandidates) {
672
+ try {
673
+ const mod = require2(p);
674
+ console.log(`[clawpowers] Tier 2: WASM module loaded (${p})`);
675
+ return mod;
676
+ } catch {
677
+ }
678
+ }
679
+ return null;
680
+ }
681
+ function loadAll() {
682
+ if (_attempted) return;
683
+ _attempted = true;
684
+ _native = tryLoadNative();
685
+ if (_native) {
686
+ _activeTier = "native";
687
+ _wasm = tryLoadWasm();
688
+ return;
689
+ }
690
+ _wasm = tryLoadWasm();
691
+ if (_wasm) {
692
+ _activeTier = "wasm";
693
+ return;
694
+ }
695
+ _activeTier = "typescript";
696
+ console.log("[clawpowers] Tier 3: TypeScript fallback active (no native or WASM)");
697
+ }
698
+ function getNative() {
699
+ loadAll();
700
+ return _native;
701
+ }
702
+ function getWasm() {
703
+ loadAll();
704
+ return _wasm;
705
+ }
706
+ function isNativeAvailable() {
707
+ loadAll();
708
+ return _native !== null;
709
+ }
710
+ function isWasmAvailable() {
711
+ loadAll();
712
+ return _wasm !== null;
713
+ }
714
+ function getActiveTier() {
715
+ loadAll();
716
+ return _activeTier;
717
+ }
718
+ function getCapabilitySummary() {
719
+ loadAll();
720
+ const nativeModules = _native ? ["wallet", "fee", "x402", "canonical", "compression", "verification", "security"] : [];
721
+ let wasmModules = [];
722
+ if (_wasm) {
723
+ try {
724
+ wasmModules = JSON.parse(_wasm.getAvailableModules());
725
+ } catch {
726
+ wasmModules = ["tokens", "fee", "compression", "canonical", "verification", "security", "index"];
727
+ }
728
+ }
729
+ const typescriptFallback = [
730
+ "wallet",
731
+ // ethers.js / viem
732
+ "x402",
733
+ // fetch()-based HTTP client
734
+ "tokens",
735
+ // Pure TS decimal math
736
+ "fee",
737
+ // Pure TS fee calculation
738
+ "policy"
739
+ // Pure TS policy engine
740
+ ];
741
+ return {
742
+ tier: _activeTier,
743
+ nativeModules,
744
+ wasmModules,
745
+ typescriptFallback
746
+ };
747
+ }
748
+ function computeSha256(content) {
749
+ loadAll();
750
+ if (_wasm) {
751
+ return _wasm.computeSha256(content);
752
+ }
753
+ const { createHash } = require2("node:crypto");
754
+ return createHash("sha256").update(content).digest("hex");
755
+ }
756
+ function digestForWalletAddress(keyMaterial) {
757
+ loadAll();
758
+ if (_native && typeof _native.keccak256Bytes === "function") {
759
+ try {
760
+ return _native.keccak256Bytes(keyMaterial);
761
+ } catch {
762
+ }
763
+ }
764
+ if (_wasm && typeof _wasm.computeKeccak256 === "function") {
765
+ try {
766
+ return _wasm.computeKeccak256(new Uint8Array(keyMaterial));
767
+ } catch {
768
+ }
769
+ }
770
+ const { createHash } = require2("node:crypto");
771
+ return "0x" + createHash("sha256").update(keyMaterial).digest("hex");
772
+ }
773
+ function keccak256Digest(data) {
774
+ loadAll();
775
+ if (_native && typeof _native.keccak256Bytes === "function") {
776
+ try {
777
+ const hex = _native.keccak256Bytes(data);
778
+ return Buffer.from(hex.replace(/^0x/i, ""), "hex");
779
+ } catch {
780
+ }
781
+ }
782
+ if (_wasm && typeof _wasm.computeKeccak256 === "function") {
783
+ try {
784
+ const hex = _wasm.computeKeccak256(new Uint8Array(data));
785
+ return Buffer.from(hex.replace(/^0x/i, ""), "hex");
786
+ } catch {
787
+ }
788
+ }
789
+ return null;
790
+ }
791
+ function deriveEthereumAddress(privateKey) {
792
+ loadAll();
793
+ if (_native && typeof _native.deriveEthereumAddress === "function") {
794
+ try {
795
+ return _native.deriveEthereumAddress(privateKey);
796
+ } catch {
797
+ }
798
+ }
799
+ if (_wasm && typeof _wasm.deriveEthereumAddress === "function") {
800
+ try {
801
+ return _wasm.deriveEthereumAddress(new Uint8Array(privateKey));
802
+ } catch {
803
+ }
804
+ }
805
+ return null;
806
+ }
807
+ function derivePublicKey(privateKey) {
808
+ loadAll();
809
+ if (_native && typeof _native.derivePublicKey === "function") {
810
+ try {
811
+ return Buffer.from(_native.derivePublicKey(privateKey));
812
+ } catch {
813
+ }
814
+ }
815
+ if (_wasm && typeof _wasm.derivePublicKey === "function") {
816
+ try {
817
+ return Buffer.from(_wasm.derivePublicKey(new Uint8Array(privateKey)));
818
+ } catch {
819
+ }
820
+ }
821
+ return null;
822
+ }
823
+ function signEcdsa(privateKey, messageHash) {
824
+ loadAll();
825
+ if (_native && typeof _native.signEcdsa === "function") {
826
+ try {
827
+ return Buffer.from(_native.signEcdsa(privateKey, messageHash));
828
+ } catch {
829
+ }
830
+ }
831
+ if (_wasm && typeof _wasm.signEcdsa === "function") {
832
+ try {
833
+ return Buffer.from(_wasm.signEcdsa(new Uint8Array(privateKey), new Uint8Array(messageHash)));
834
+ } catch {
835
+ }
836
+ }
837
+ return null;
838
+ }
839
+ function verifyEcdsa(publicKey, messageHash, signature) {
840
+ loadAll();
841
+ try {
842
+ if (_native && typeof _native.verifyEcdsa === "function") {
843
+ return _native.verifyEcdsa(publicKey, messageHash, signature);
844
+ }
845
+ if (_wasm && typeof _wasm.verifyEcdsa === "function") {
846
+ return _wasm.verifyEcdsa(
847
+ new Uint8Array(publicKey),
848
+ new Uint8Array(messageHash),
849
+ new Uint8Array(signature)
850
+ );
851
+ }
852
+ } catch {
853
+ return false;
854
+ }
855
+ return false;
856
+ }
857
+ function tokenAmountFromHuman(human, decimals) {
858
+ loadAll();
859
+ if (_wasm) {
860
+ return JSON.parse(_wasm.tokenAmountFromHuman(human, decimals));
861
+ }
862
+ const multiplier = Math.pow(10, decimals);
863
+ const raw = Math.floor(human * multiplier);
864
+ return { raw: raw.toString(), decimals };
865
+ }
866
+ function calculateFee(amountHuman, decimals, feeType, txFeeBps, swapFeeBps) {
867
+ loadAll();
868
+ if (_wasm) {
869
+ const amountJson = _wasm.tokenAmountFromHuman(amountHuman, decimals);
870
+ const result = _wasm.calculateFee(
871
+ amountJson,
872
+ feeType,
873
+ txFeeBps !== void 0 ? BigInt(txFeeBps) : void 0,
874
+ swapFeeBps !== void 0 ? BigInt(swapFeeBps) : void 0
875
+ );
876
+ return JSON.parse(result);
877
+ }
878
+ const bps = feeType === "transaction" ? txFeeBps ?? 77 : feeType === "swap" ? swapFeeBps ?? 30 : parseInt(feeType.replace("custom:", ""), 10) || 0;
879
+ const feeAmount = amountHuman * bps / 1e4;
880
+ return {
881
+ gross_amount: amountHuman,
882
+ fee_amount: feeAmount,
883
+ net_amount: amountHuman - feeAmount
884
+ };
885
+ }
886
+ function evaluateWriteFirewall(request) {
887
+ loadAll();
888
+ if (_wasm) {
889
+ return JSON.parse(_wasm.evaluateWriteFirewall(JSON.stringify(request)));
890
+ }
891
+ if (request.allowed_namespaces && request.allowed_namespaces.length > 0 && !request.allowed_namespaces.includes(request.namespace)) {
892
+ return {
893
+ decision: "deny",
894
+ reason: `namespace '${request.namespace}' is not in the allow-list`
895
+ };
896
+ }
897
+ const maxLen = request.max_content_length ?? 1024 * 1024;
898
+ if (request.content.length > maxLen) {
899
+ return {
900
+ decision: "deny",
901
+ reason: `content length ${request.content.length} exceeds maximum ${maxLen}`
902
+ };
903
+ }
904
+ if (request.blocked_patterns) {
905
+ for (const pattern of request.blocked_patterns) {
906
+ if (request.content.includes(pattern)) {
907
+ if (request.trust_level === "system" || request.trust_level === "agent") {
908
+ return {
909
+ decision: "deny",
910
+ reason: `content contains blocked pattern '${pattern}'`
911
+ };
912
+ }
913
+ return {
914
+ decision: "sanitize",
915
+ sanitized: request.content.replaceAll(pattern, "")
916
+ };
917
+ }
918
+ }
919
+ }
920
+ return { decision: "allow" };
921
+ }
922
+
635
923
  // src/payments/discovery.ts
636
924
  var REQUIRED_HEADERS = [
637
925
  "x-payment-amount",
@@ -877,6 +1165,72 @@ var PaymentExecutor = class {
877
1165
  }
878
1166
  };
879
1167
 
1168
+ // src/payments/native-bridge.ts
1169
+ import { randomBytes } from "crypto";
1170
+ function calculateTransactionFee(amount, decimals = 6) {
1171
+ const native = getNative();
1172
+ if (native) {
1173
+ try {
1174
+ const schedule = native.JsFeeSchedule.withDefaults();
1175
+ const raw = JSON.parse(schedule.calculate(amount, decimals, "transaction"));
1176
+ return {
1177
+ gross: raw.gross,
1178
+ fee: raw.fee,
1179
+ net: raw.net,
1180
+ feeRecipient: raw.feeRecipient ?? raw.fee_recipient ?? "0x0000000000000000000000000000000000000000"
1181
+ };
1182
+ } catch {
1183
+ }
1184
+ }
1185
+ const wasm = getWasm();
1186
+ if (wasm) {
1187
+ try {
1188
+ const result = calculateFee(amount, decimals, "transaction");
1189
+ return {
1190
+ gross: result.gross_amount,
1191
+ fee: result.fee_amount,
1192
+ net: result.net_amount,
1193
+ feeRecipient: "0x0000000000000000000000000000000000000000"
1194
+ };
1195
+ } catch {
1196
+ }
1197
+ }
1198
+ const fee = amount * 77e-4;
1199
+ return {
1200
+ gross: amount,
1201
+ fee,
1202
+ net: amount - fee,
1203
+ feeRecipient: "0x0000000000000000000000000000000000000000"
1204
+ };
1205
+ }
1206
+ function createPaymentHeader(paymentJson, signature) {
1207
+ const native = getNative();
1208
+ if (native) {
1209
+ try {
1210
+ const client = new native.JsX402Client();
1211
+ return client.createPaymentHeader(paymentJson, signature);
1212
+ } catch {
1213
+ }
1214
+ }
1215
+ return Buffer.from(JSON.stringify({ payment: JSON.parse(paymentJson), signature })).toString("base64");
1216
+ }
1217
+ function generateWalletAddress() {
1218
+ const native = getNative();
1219
+ if (native) {
1220
+ try {
1221
+ return native.JsAgentWallet.generate().address();
1222
+ } catch {
1223
+ }
1224
+ }
1225
+ const address = deriveEthereumAddress(randomBytes(32));
1226
+ if (address) {
1227
+ return address;
1228
+ }
1229
+ throw new Error(
1230
+ "Unable to derive a real Ethereum address. Native or WASM wallet support is required for generateWalletAddress()."
1231
+ );
1232
+ }
1233
+
880
1234
  // src/memory/working.ts
881
1235
  function estimateTokens(text) {
882
1236
  return Math.ceil(text.length / 4);
@@ -966,14 +1320,14 @@ var WorkingMemoryManager = class {
966
1320
  // src/memory/episodic.ts
967
1321
  import { readFile, appendFile, writeFile, mkdir } from "fs/promises";
968
1322
  import { existsSync as existsSync2 } from "fs";
969
- import { dirname as dirname2 } from "path";
1323
+ import { dirname as dirname3 } from "path";
970
1324
  var EpisodicMemory = class {
971
1325
  filePath;
972
1326
  constructor(filePath) {
973
1327
  this.filePath = filePath;
974
1328
  }
975
1329
  async ensureDir() {
976
- const dir = dirname2(this.filePath);
1330
+ const dir = dirname3(this.filePath);
977
1331
  if (!existsSync2(dir)) {
978
1332
  await mkdir(dir, { recursive: true });
979
1333
  }
@@ -1058,7 +1412,7 @@ var EpisodicMemory = class {
1058
1412
  // src/memory/procedural.ts
1059
1413
  import { readFile as readFile2, writeFile as writeFile2, rename, mkdir as mkdir2, copyFile } from "fs/promises";
1060
1414
  import { existsSync as existsSync3 } from "fs";
1061
- import { dirname as dirname3 } from "path";
1415
+ import { dirname as dirname4 } from "path";
1062
1416
  var ProceduralMemory = class {
1063
1417
  filePath;
1064
1418
  cache = null;
@@ -1066,7 +1420,7 @@ var ProceduralMemory = class {
1066
1420
  this.filePath = filePath;
1067
1421
  }
1068
1422
  async ensureDir() {
1069
- const dir = dirname3(this.filePath);
1423
+ const dir = dirname4(this.filePath);
1070
1424
  if (!existsSync3(dir)) {
1071
1425
  await mkdir2(dir, { recursive: true });
1072
1426
  }
@@ -1202,7 +1556,7 @@ var ProceduralMemory = class {
1202
1556
  // src/memory/checkpoint.ts
1203
1557
  import { readFile as readFile3, writeFile as writeFile3, rename as rename2, unlink, readdir, mkdir as mkdir3 } from "fs/promises";
1204
1558
  import { existsSync as existsSync4 } from "fs";
1205
- import { join as join2 } from "path";
1559
+ import { join as join3 } from "path";
1206
1560
  var DEFAULT_MAX_AGE_MS = 24 * 60 * 60 * 1e3;
1207
1561
  var CheckpointManager = class {
1208
1562
  dir;
@@ -1215,7 +1569,7 @@ var CheckpointManager = class {
1215
1569
  }
1216
1570
  }
1217
1571
  filePath(taskId) {
1218
- return join2(this.dir, `${taskId}.json`);
1572
+ return join3(this.dir, `${taskId}.json`);
1219
1573
  }
1220
1574
  async save(taskId, state) {
1221
1575
  await this.ensureDir();
@@ -1244,7 +1598,7 @@ var CheckpointManager = class {
1244
1598
  const results = [];
1245
1599
  for (const file of files) {
1246
1600
  if (!file.endsWith(".json")) continue;
1247
- const path = join2(this.dir, file);
1601
+ const path = join3(this.dir, file);
1248
1602
  try {
1249
1603
  const content = await readFile3(path, "utf-8");
1250
1604
  const state = JSON.parse(content);
@@ -1341,10 +1695,131 @@ var ContextInjector = class {
1341
1695
  }
1342
1696
  };
1343
1697
 
1698
+ // src/memory/native-store.ts
1699
+ function getNativeCanonicalStore(dbPath) {
1700
+ const native = getNative();
1701
+ if (!native) return null;
1702
+ try {
1703
+ return native.JsCanonicalStore.open(dbPath);
1704
+ } catch {
1705
+ return null;
1706
+ }
1707
+ }
1708
+ function getNativeCanonicalStoreInMemory() {
1709
+ const native = getNative();
1710
+ if (!native) return null;
1711
+ try {
1712
+ return native.JsCanonicalStore.inMemory();
1713
+ } catch {
1714
+ return null;
1715
+ }
1716
+ }
1717
+ function getWasmCanonicalStore() {
1718
+ const wasm = getWasm();
1719
+ if (!wasm) return null;
1720
+ try {
1721
+ return new wasm.WasmCanonicalStore();
1722
+ } catch {
1723
+ return null;
1724
+ }
1725
+ }
1726
+ function getBestCanonicalStore() {
1727
+ return getNativeCanonicalStoreInMemory() ?? getWasmCanonicalStore();
1728
+ }
1729
+ function compressVector(vector, bits = 8) {
1730
+ const native = getNative();
1731
+ if (native) {
1732
+ try {
1733
+ const compressor = new native.JsTurboCompressor(vector.length, bits);
1734
+ const compressed = compressor.compress(vector);
1735
+ return {
1736
+ compressed,
1737
+ originalSize: vector.length * 4,
1738
+ compressedSize: compressed.length
1739
+ };
1740
+ } catch {
1741
+ }
1742
+ }
1743
+ const wasm = getWasm();
1744
+ if (wasm) {
1745
+ try {
1746
+ const vectorJson = JSON.stringify(Array.from(vector));
1747
+ const compressed = wasm.compressVector(vectorJson, vector.length);
1748
+ return {
1749
+ compressed,
1750
+ originalSize: vector.length * 4,
1751
+ compressedSize: compressed.length
1752
+ };
1753
+ } catch {
1754
+ }
1755
+ }
1756
+ return null;
1757
+ }
1758
+ function decompressVector(compressedJson, dimensions, bits = 8) {
1759
+ const native = getNative();
1760
+ if (native) {
1761
+ try {
1762
+ const compressor = new native.JsTurboCompressor(dimensions, bits);
1763
+ return compressor.decompress(compressedJson);
1764
+ } catch {
1765
+ }
1766
+ }
1767
+ const wasm = getWasm();
1768
+ if (wasm) {
1769
+ try {
1770
+ const arrayJson = wasm.decompressVector(compressedJson, dimensions);
1771
+ const arr = JSON.parse(arrayJson);
1772
+ return new Float32Array(arr);
1773
+ } catch {
1774
+ }
1775
+ }
1776
+ return null;
1777
+ }
1778
+ function approximateDistance(aJson, bJson, dimensions) {
1779
+ const wasm = getWasm();
1780
+ if (wasm) {
1781
+ try {
1782
+ return wasm.approximateDistance(aJson, bJson, dimensions);
1783
+ } catch {
1784
+ }
1785
+ }
1786
+ return null;
1787
+ }
1788
+ function evaluateWriteSecurity(namespace, content, allowedNamespaces, source = "agent", trustLevel = "agent") {
1789
+ const native = getNative();
1790
+ if (native) {
1791
+ try {
1792
+ const firewall = new native.JsWriteFirewall(
1793
+ JSON.stringify({ allowed_namespaces: allowedNamespaces })
1794
+ );
1795
+ const result = JSON.parse(
1796
+ firewall.evaluate(JSON.stringify({ namespace, content, trust_level: trustLevel }))
1797
+ );
1798
+ return result;
1799
+ } catch {
1800
+ }
1801
+ }
1802
+ try {
1803
+ const result = evaluateWriteFirewall({
1804
+ namespace,
1805
+ content,
1806
+ trust_level: trustLevel,
1807
+ source,
1808
+ allowed_namespaces: allowedNamespaces.length > 0 ? allowedNamespaces : void 0
1809
+ });
1810
+ return {
1811
+ allowed: result.decision === "allow" || result.decision === "sanitize",
1812
+ reason: result.reason
1813
+ };
1814
+ } catch {
1815
+ return { allowed: true };
1816
+ }
1817
+ }
1818
+
1344
1819
  // src/rsi/metrics.ts
1345
1820
  import { readFile as readFile4, appendFile as appendFile2, mkdir as mkdir4 } from "fs/promises";
1346
1821
  import { existsSync as existsSync5 } from "fs";
1347
- import { dirname as dirname4 } from "path";
1822
+ import { dirname as dirname5 } from "path";
1348
1823
  var MetricsCollector = class {
1349
1824
  taskMetricsPath;
1350
1825
  skillMetricsPath;
@@ -1353,7 +1828,7 @@ var MetricsCollector = class {
1353
1828
  this.skillMetricsPath = skillMetricsPath;
1354
1829
  }
1355
1830
  async ensureDir(filePath) {
1356
- const dir = dirname4(filePath);
1831
+ const dir = dirname5(filePath);
1357
1832
  if (!existsSync5(dir)) {
1358
1833
  await mkdir4(dir, { recursive: true });
1359
1834
  }
@@ -1569,7 +2044,7 @@ var HypothesisEngine = class {
1569
2044
  // src/rsi/mutation.ts
1570
2045
  import { readFile as readFile5, appendFile as appendFile3, mkdir as mkdir5 } from "fs/promises";
1571
2046
  import { existsSync as existsSync6 } from "fs";
1572
- import { dirname as dirname5 } from "path";
2047
+ import { dirname as dirname6 } from "path";
1573
2048
  import { randomUUID as randomUUID2 } from "crypto";
1574
2049
  var MutationEngine = class {
1575
2050
  historyPath;
@@ -1577,7 +2052,7 @@ var MutationEngine = class {
1577
2052
  this.historyPath = historyPath;
1578
2053
  }
1579
2054
  async ensureDir() {
1580
- const dir = dirname5(this.historyPath);
2055
+ const dir = dirname6(this.historyPath);
1581
2056
  if (!existsSync6(dir)) {
1582
2057
  await mkdir5(dir, { recursive: true });
1583
2058
  }
@@ -1769,14 +2244,14 @@ var ABTestManager = class {
1769
2244
  // src/rsi/audit.ts
1770
2245
  import { readFile as readFile6, appendFile as appendFile4, mkdir as mkdir6 } from "fs/promises";
1771
2246
  import { existsSync as existsSync7 } from "fs";
1772
- import { dirname as dirname6 } from "path";
2247
+ import { dirname as dirname7 } from "path";
1773
2248
  var RSIAuditLog = class {
1774
2249
  filePath;
1775
2250
  constructor(filePath) {
1776
2251
  this.filePath = filePath;
1777
2252
  }
1778
2253
  async ensureDir() {
1779
- const dir = dirname6(this.filePath);
2254
+ const dir = dirname7(this.filePath);
1780
2255
  if (!existsSync7(dir)) {
1781
2256
  await mkdir6(dir, { recursive: true });
1782
2257
  }
@@ -1814,7 +2289,7 @@ var RSIAuditLog = class {
1814
2289
  import { randomUUID as randomUUID4 } from "crypto";
1815
2290
  import { execSync } from "child_process";
1816
2291
  import { mkdirSync as mkdirSync2, existsSync as existsSync8, writeFileSync as writeFileSync2 } from "fs";
1817
- import { join as join3 } from "path";
2292
+ import { join as join4 } from "path";
1818
2293
  import { tmpdir } from "os";
1819
2294
  var MIN_CONFIDENCE = 0.3;
1820
2295
  var REQUIRED_PASSING_RUNS = 3;
@@ -1857,7 +2332,7 @@ function scoreConfidence(candidate, failure) {
1857
2332
  var AutoResearcher = class {
1858
2333
  skillsDir;
1859
2334
  constructor(skillsDir) {
1860
- this.skillsDir = skillsDir ?? join3(tmpdir(), "clawpowers-promoted-skills");
2335
+ this.skillsDir = skillsDir ?? join4(tmpdir(), "clawpowers-promoted-skills");
1861
2336
  }
1862
2337
  /**
1863
2338
  * Search for candidate solutions to a failure.
@@ -1886,11 +2361,11 @@ var AutoResearcher = class {
1886
2361
  */
1887
2362
  async testCandidate(candidate, task) {
1888
2363
  const startMs = Date.now();
1889
- const sandboxDir = join3(tmpdir(), `clawpowers-sandbox-${randomUUID4()}`);
2364
+ const sandboxDir = join4(tmpdir(), `clawpowers-sandbox-${randomUUID4()}`);
1890
2365
  try {
1891
2366
  mkdirSync2(sandboxDir, { recursive: true });
1892
2367
  const testScript = this.buildTestScript(candidate, task, sandboxDir);
1893
- const scriptPath = join3(sandboxDir, "test.sh");
2368
+ const scriptPath = join4(sandboxDir, "test.sh");
1894
2369
  writeFileSync2(scriptPath, testScript, { mode: 493 });
1895
2370
  const output = execSync(`bash "${scriptPath}"`, {
1896
2371
  cwd: sandboxDir,
@@ -1958,12 +2433,12 @@ var AutoResearcher = class {
1958
2433
  promotedAt: (/* @__PURE__ */ new Date()).toISOString(),
1959
2434
  testResults
1960
2435
  };
1961
- const skillDir = join3(this.skillsDir, skillName);
2436
+ const skillDir = join4(this.skillsDir, skillName);
1962
2437
  if (!existsSync8(skillDir)) {
1963
2438
  mkdirSync2(skillDir, { recursive: true });
1964
2439
  }
1965
2440
  const skillMd = this.renderSkillMd(definition);
1966
- writeFileSync2(join3(skillDir, "SKILL.md"), skillMd, "utf-8");
2441
+ writeFileSync2(join4(skillDir, "SKILL.md"), skillMd, "utf-8");
1967
2442
  return definition;
1968
2443
  }
1969
2444
  // ─── Private Methods ───────────────────────────────────────────────────────
@@ -2140,7 +2615,7 @@ async function runAutoResearch(failure, task, skillsDir) {
2140
2615
 
2141
2616
  // src/skills/loader.ts
2142
2617
  import { readdirSync, readFileSync as readFileSync2, existsSync as existsSync9, statSync } from "fs";
2143
- import { join as join4 } from "path";
2618
+ import { join as join5 } from "path";
2144
2619
  function parseFrontmatter(content) {
2145
2620
  const match = content.match(/^---\n([\s\S]*?)\n---/);
2146
2621
  if (!match?.[1]) {
@@ -2206,7 +2681,7 @@ function parseFrontmatter(content) {
2206
2681
  return result;
2207
2682
  }
2208
2683
  function loadSkillManifest(skillDir) {
2209
- const skillMdPath = join4(skillDir, "SKILL.md");
2684
+ const skillMdPath = join5(skillDir, "SKILL.md");
2210
2685
  if (!existsSync9(skillMdPath)) {
2211
2686
  return null;
2212
2687
  }
@@ -2238,7 +2713,7 @@ function discoverSkills(skillsDir) {
2238
2713
  const entries = readdirSync(skillsDir);
2239
2714
  const manifests = [];
2240
2715
  for (const entry of entries) {
2241
- const fullPath = join4(skillsDir, entry);
2716
+ const fullPath = join5(skillsDir, entry);
2242
2717
  if (!statSync(fullPath).isDirectory()) continue;
2243
2718
  const manifest = loadSkillManifest(fullPath);
2244
2719
  if (manifest) {
@@ -2301,21 +2776,24 @@ var SkillExecutor = class {
2301
2776
  // src/wallet/manager.ts
2302
2777
  import { readdir as readdir2, readFile as readFile8 } from "fs/promises";
2303
2778
  import { existsSync as existsSync11 } from "fs";
2304
- import { join as join6 } from "path";
2779
+ import { join as join7 } from "path";
2305
2780
 
2306
2781
  // src/wallet/crypto.ts
2307
- import { randomBytes, createCipheriv, createDecipheriv, scryptSync, createHash } from "crypto";
2782
+ import { randomBytes as randomBytes2, createCipheriv, createDecipheriv, scryptSync } from "crypto";
2783
+ import { debuglog } from "util";
2308
2784
  import { writeFile as writeFile4, readFile as readFile7, mkdir as mkdir7 } from "fs/promises";
2309
2785
  import { existsSync as existsSync10 } from "fs";
2310
- import { join as join5 } from "path";
2786
+ import { join as join6 } from "path";
2787
+ var dlog = debuglog("clawpowers:wallet");
2311
2788
  var SCRYPT_N = 16384;
2312
2789
  var SCRYPT_R = 8;
2313
2790
  var SCRYPT_P = 1;
2314
2791
  var KEY_LENGTH = 32;
2315
2792
  var IV_LENGTH = 12;
2316
2793
  var AUTH_TAG_LENGTH = 16;
2317
- function addressHash(publicKeyBytes) {
2318
- const hash = createHash("sha256").update(publicKeyBytes).digest();
2794
+ function addressFromKeyMaterial(keyMaterial) {
2795
+ const digestHex = digestForWalletAddress(keyMaterial);
2796
+ const hash = Buffer.from(digestHex.replace(/^0x/, ""), "hex");
2319
2797
  return "0x" + hash.subarray(hash.length - 20).toString("hex");
2320
2798
  }
2321
2799
  function deriveKey(passphrase, salt) {
@@ -2326,9 +2804,9 @@ function deriveKey(passphrase, salt) {
2326
2804
  });
2327
2805
  }
2328
2806
  function encryptPrivateKey(privateKey, passphrase) {
2329
- const salt = randomBytes(32);
2807
+ const salt = randomBytes2(32);
2330
2808
  const key = deriveKey(passphrase, salt);
2331
- const iv = randomBytes(IV_LENGTH);
2809
+ const iv = randomBytes2(IV_LENGTH);
2332
2810
  const cipher = createCipheriv("aes-256-gcm", key, iv, { authTagLength: AUTH_TAG_LENGTH });
2333
2811
  const encrypted = Buffer.concat([cipher.update(privateKey), cipher.final()]);
2334
2812
  const authTag = cipher.getAuthTag();
@@ -2352,20 +2830,75 @@ function decryptPrivateKey(ciphertext, iv, authTag, salt, passphrase) {
2352
2830
  return decrypted;
2353
2831
  }
2354
2832
  function generateAddress(privateKeyHex) {
2355
- const privBuf = Buffer.from(privateKeyHex, "hex");
2356
- return addressHash(privBuf);
2833
+ const cleaned = privateKeyHex.replace(/^0x/i, "");
2834
+ const privBuf = Buffer.from(cleaned, "hex");
2835
+ const eth = deriveEthereumAddress(privBuf);
2836
+ if (eth) {
2837
+ dlog("address derivation: secp256k1+keccak (tier %s)", getActiveTier());
2838
+ return eth;
2839
+ }
2840
+ dlog("address derivation: tier3 legacy digest (tier %s)", getActiveTier());
2841
+ return addressFromKeyMaterial(privBuf);
2357
2842
  }
2358
2843
  async function ensureDir(dir) {
2359
2844
  if (!existsSync10(dir)) {
2360
2845
  await mkdir7(dir, { recursive: true });
2361
2846
  }
2362
2847
  }
2848
+ async function signMessageFromKeyFile(message, keyFile, passphrase) {
2849
+ const content = await readFile7(keyFile, "utf-8");
2850
+ const keyFileData = JSON.parse(content);
2851
+ const privateKey = decryptPrivateKey(
2852
+ keyFileData.crypto.ciphertext,
2853
+ keyFileData.crypto.iv,
2854
+ keyFileData.crypto.authTag,
2855
+ keyFileData.crypto.salt,
2856
+ passphrase
2857
+ );
2858
+ const msgBuf = Buffer.from(message, "utf8");
2859
+ const hash = keccak256Digest(msgBuf);
2860
+ const sigEcdsa = hash ? signEcdsa(privateKey, hash) : null;
2861
+ if (sigEcdsa) {
2862
+ dlog("signMessage (keyfile): secp256k1 ECDSA (tier %s)", getActiveTier());
2863
+ return {
2864
+ message,
2865
+ signature: "0x" + sigEcdsa.toString("hex"),
2866
+ address: keyFileData.address
2867
+ };
2868
+ }
2869
+ const { createHmac } = await import("crypto");
2870
+ dlog("signMessage (keyfile): HMAC-SHA256 legacy (no secp256k1/keccak tier)");
2871
+ const signature = createHmac("sha256", privateKey).update(message).digest("hex");
2872
+ return {
2873
+ message,
2874
+ signature: "0x" + signature,
2875
+ address: keyFileData.address
2876
+ };
2877
+ }
2878
+ async function signMessageFromPrivateKey(privateKeyHex, message) {
2879
+ const cleaned = privateKeyHex.replace(/^0x/i, "");
2880
+ if (cleaned.length !== 64 || !/^[0-9a-fA-F]+$/.test(cleaned)) {
2881
+ throw new Error("Invalid private key: must be 32 bytes (64 hex characters)");
2882
+ }
2883
+ const priv = Buffer.from(cleaned, "hex");
2884
+ const hash = keccak256Digest(Buffer.from(message, "utf8"));
2885
+ if (!hash) {
2886
+ throw new Error(
2887
+ "Ethereum signing requires Keccak-256 (Tier 1 native or Tier 2 WASM). Pure TypeScript tier has no Keccak."
2888
+ );
2889
+ }
2890
+ const sig = signEcdsa(priv, hash);
2891
+ if (!sig) {
2892
+ throw new Error("Ethereum signing requires secp256k1 (Tier 1 native or Tier 2 WASM).");
2893
+ }
2894
+ return "0x" + sig.toString("hex");
2895
+ }
2363
2896
  async function generateWallet(config) {
2364
- const privateKey = randomBytes(32);
2897
+ const privateKey = randomBytes2(32);
2365
2898
  const privateKeyHex = privateKey.toString("hex");
2366
2899
  const address = generateAddress(privateKeyHex);
2367
2900
  const createdAt = (/* @__PURE__ */ new Date()).toISOString();
2368
- const passphrase = randomBytes(16).toString("hex");
2901
+ const passphrase = randomBytes2(16).toString("hex");
2369
2902
  const encrypted = encryptPrivateKey(privateKey, passphrase);
2370
2903
  const keyFileData = {
2371
2904
  version: 1,
@@ -2383,7 +2916,7 @@ async function generateWallet(config) {
2383
2916
  };
2384
2917
  await ensureDir(config.dataDir);
2385
2918
  const keyFileName = `${address.slice(2, 10)}-${Date.now()}.json`;
2386
- const keyFilePath = join5(config.dataDir, keyFileName);
2919
+ const keyFilePath = join6(config.dataDir, keyFileName);
2387
2920
  await writeFile4(keyFilePath, JSON.stringify(keyFileData, null, 2) + "\n", "utf-8");
2388
2921
  return {
2389
2922
  address,
@@ -2393,14 +2926,14 @@ async function generateWallet(config) {
2393
2926
  };
2394
2927
  }
2395
2928
  async function importWallet(privateKeyHex, config) {
2396
- const cleaned = privateKeyHex.replace(/^0x/, "");
2929
+ const cleaned = privateKeyHex.replace(/^0x/i, "");
2397
2930
  if (cleaned.length !== 64 || !/^[0-9a-fA-F]+$/.test(cleaned)) {
2398
2931
  throw new Error("Invalid private key: must be 32 bytes (64 hex characters)");
2399
2932
  }
2400
2933
  const privateKey = Buffer.from(cleaned, "hex");
2401
2934
  const address = generateAddress(cleaned);
2402
2935
  const createdAt = (/* @__PURE__ */ new Date()).toISOString();
2403
- const passphrase = randomBytes(16).toString("hex");
2936
+ const passphrase = randomBytes2(16).toString("hex");
2404
2937
  const encrypted = encryptPrivateKey(privateKey, passphrase);
2405
2938
  const keyFileData = {
2406
2939
  version: 1,
@@ -2418,7 +2951,7 @@ async function importWallet(privateKeyHex, config) {
2418
2951
  };
2419
2952
  await ensureDir(config.dataDir);
2420
2953
  const keyFileName = `${address.slice(2, 10)}-${Date.now()}.json`;
2421
- const keyFilePath = join5(config.dataDir, keyFileName);
2954
+ const keyFilePath = join6(config.dataDir, keyFileName);
2422
2955
  await writeFile4(keyFilePath, JSON.stringify(keyFileData, null, 2) + "\n", "utf-8");
2423
2956
  return {
2424
2957
  address,
@@ -2427,23 +2960,11 @@ async function importWallet(privateKeyHex, config) {
2427
2960
  keyFile: keyFilePath
2428
2961
  };
2429
2962
  }
2430
- async function signMessage(message, keyFile, passphrase) {
2431
- const content = await readFile7(keyFile, "utf-8");
2432
- const keyFileData = JSON.parse(content);
2433
- const privateKey = decryptPrivateKey(
2434
- keyFileData.crypto.ciphertext,
2435
- keyFileData.crypto.iv,
2436
- keyFileData.crypto.authTag,
2437
- keyFileData.crypto.salt,
2438
- passphrase
2439
- );
2440
- const { createHmac } = await import("crypto");
2441
- const signature = createHmac("sha256", privateKey).update(message).digest("hex");
2442
- return {
2443
- message,
2444
- signature: "0x" + signature,
2445
- address: keyFileData.address
2446
- };
2963
+ async function signMessage(a, b, c) {
2964
+ if (c !== void 0) {
2965
+ return signMessageFromKeyFile(a, b, c);
2966
+ }
2967
+ return signMessageFromPrivateKey(a, b);
2447
2968
  }
2448
2969
 
2449
2970
  // src/wallet/manager.ts
@@ -2471,7 +2992,7 @@ var WalletManager = class {
2471
2992
  for (const file of files) {
2472
2993
  if (!file.endsWith(".json")) continue;
2473
2994
  try {
2474
- const filePath = join6(this.config.dataDir, file);
2995
+ const filePath = join7(this.config.dataDir, file);
2475
2996
  const content = await readFile8(filePath, "utf-8");
2476
2997
  const data = JSON.parse(content);
2477
2998
  wallets.push({
@@ -2486,11 +3007,382 @@ var WalletManager = class {
2486
3007
  return wallets;
2487
3008
  }
2488
3009
  };
3010
+
3011
+ // src/itp/index.ts
3012
+ var ITP_BASE_URL = "http://localhost:8100";
3013
+ var TIMEOUT_MS = 3e3;
3014
+ async function encode(message, sourceAgent) {
3015
+ try {
3016
+ const controller = new AbortController();
3017
+ const timeout = setTimeout(() => controller.abort(), TIMEOUT_MS);
3018
+ const response = await fetch(`${ITP_BASE_URL}/tools/encode`, {
3019
+ method: "POST",
3020
+ headers: { "Content-Type": "application/json" },
3021
+ body: JSON.stringify({
3022
+ message,
3023
+ source_agent: sourceAgent ?? "unknown",
3024
+ target_agent: "unknown"
3025
+ }),
3026
+ signal: controller.signal
3027
+ });
3028
+ clearTimeout(timeout);
3029
+ if (!response.ok) {
3030
+ return { encoded: message, wasCompressed: false, savingsPct: 0 };
3031
+ }
3032
+ const data = await response.json();
3033
+ return {
3034
+ encoded: data.encoded ?? message,
3035
+ wasCompressed: Boolean(data.was_compressed),
3036
+ savingsPct: typeof data.savings_pct === "number" ? data.savings_pct : 0
3037
+ };
3038
+ } catch {
3039
+ return { encoded: message, wasCompressed: false, savingsPct: 0 };
3040
+ }
3041
+ }
3042
+ async function decode(message) {
3043
+ try {
3044
+ const controller = new AbortController();
3045
+ const timeout = setTimeout(() => controller.abort(), TIMEOUT_MS);
3046
+ const response = await fetch(`${ITP_BASE_URL}/tools/decode`, {
3047
+ method: "POST",
3048
+ headers: { "Content-Type": "application/json" },
3049
+ body: JSON.stringify({ message }),
3050
+ signal: controller.signal
3051
+ });
3052
+ clearTimeout(timeout);
3053
+ if (!response.ok) {
3054
+ return { decoded: message, wasItp: false };
3055
+ }
3056
+ const data = await response.json();
3057
+ return {
3058
+ decoded: data.decoded ?? message,
3059
+ wasItp: Boolean(data.was_itp)
3060
+ };
3061
+ } catch {
3062
+ return { decoded: message, wasItp: false };
3063
+ }
3064
+ }
3065
+ async function healthCheck() {
3066
+ try {
3067
+ const controller = new AbortController();
3068
+ const timeout = setTimeout(() => controller.abort(), TIMEOUT_MS);
3069
+ const response = await fetch(`${ITP_BASE_URL}/health`, {
3070
+ signal: controller.signal
3071
+ });
3072
+ clearTimeout(timeout);
3073
+ return response.ok;
3074
+ } catch {
3075
+ return false;
3076
+ }
3077
+ }
3078
+
3079
+ // src/itp/swarm-bridge.ts
3080
+ async function encodeTaskDescription(task) {
3081
+ try {
3082
+ const [descResult, msgResult] = await Promise.all([
3083
+ encode(task.description, "swarm-orchestrator"),
3084
+ encode(task.message, "swarm-orchestrator")
3085
+ ]);
3086
+ return {
3087
+ ...task,
3088
+ description: descResult.encoded,
3089
+ message: msgResult.encoded
3090
+ };
3091
+ } catch {
3092
+ return task;
3093
+ }
3094
+ }
3095
+ async function decodeSwarmResult(result) {
3096
+ try {
3097
+ if (result.result === null) {
3098
+ return result;
3099
+ }
3100
+ const decoded = await decode(result.result);
3101
+ return {
3102
+ ...result,
3103
+ result: decoded.decoded
3104
+ };
3105
+ } catch {
3106
+ return result;
3107
+ }
3108
+ }
3109
+
3110
+ // src/swarm/concurrency.ts
3111
+ var ConcurrencyManager = class {
3112
+ maxConcurrency;
3113
+ backpressureThreshold;
3114
+ activeCount = 0;
3115
+ throttleDelayMs = 0;
3116
+ lastErrorTime = 0;
3117
+ // Semaphore queue — each entry is a resolver that grants a slot
3118
+ queue = [];
3119
+ constructor(maxConcurrency = 5, backpressureThreshold = 0.8) {
3120
+ this.maxConcurrency = maxConcurrency;
3121
+ this.backpressureThreshold = backpressureThreshold;
3122
+ }
3123
+ /**
3124
+ * Acquire a concurrency slot. Resolves when a slot is available.
3125
+ * Applies throttle delay if rate limits have been hit recently.
3126
+ */
3127
+ async acquire() {
3128
+ if (this.activeCount < this.maxConcurrency) {
3129
+ this.activeCount++;
3130
+ } else {
3131
+ await new Promise((resolve) => {
3132
+ this.queue.push(resolve);
3133
+ });
3134
+ this.activeCount++;
3135
+ }
3136
+ if (this.throttleDelayMs > 0) {
3137
+ await new Promise((resolve) => setTimeout(resolve, this.throttleDelayMs));
3138
+ }
3139
+ }
3140
+ /**
3141
+ * Release a concurrency slot. Unblocks next queued waiter if any.
3142
+ */
3143
+ release() {
3144
+ this.activeCount = Math.max(0, this.activeCount - 1);
3145
+ const next = this.queue.shift();
3146
+ if (next) next();
3147
+ }
3148
+ /**
3149
+ * Number of currently active tasks.
3150
+ */
3151
+ get active() {
3152
+ return this.activeCount;
3153
+ }
3154
+ /**
3155
+ * Number of tasks waiting for a slot.
3156
+ */
3157
+ get pending() {
3158
+ return this.queue.length;
3159
+ }
3160
+ /**
3161
+ * Whether system has capacity for another task.
3162
+ */
3163
+ hasCapacity() {
3164
+ return this.activeCount < this.maxConcurrency;
3165
+ }
3166
+ /**
3167
+ * Increase throttle delay on rate-limit / transient errors.
3168
+ * Multiple errors in quick succession cause exponential backoff.
3169
+ */
3170
+ adaptiveThrottle(_errorType = "rate_limit") {
3171
+ const now = Date.now();
3172
+ if (now - this.lastErrorTime < 5e3) {
3173
+ this.throttleDelayMs = Math.min(this.throttleDelayMs * 2 + 500, 3e4);
3174
+ } else {
3175
+ this.throttleDelayMs = 500;
3176
+ }
3177
+ this.lastErrorTime = now;
3178
+ }
3179
+ /**
3180
+ * Gradually reduce throttle delay after a successful operation.
3181
+ */
3182
+ resetThrottle() {
3183
+ this.throttleDelayMs = Math.max(0, this.throttleDelayMs - 100);
3184
+ }
3185
+ /**
3186
+ * Check if system is above backpressure threshold.
3187
+ */
3188
+ isUnderPressure() {
3189
+ return this.activeCount / this.maxConcurrency >= this.backpressureThreshold;
3190
+ }
3191
+ };
3192
+
3193
+ // src/swarm/token_pool.ts
3194
+ var TokenPool = class {
3195
+ totalBudget;
3196
+ perTaskDefault;
3197
+ allocations = /* @__PURE__ */ new Map();
3198
+ constructor(totalBudget = 1e5, perTaskDefault = 2e4) {
3199
+ this.totalBudget = totalBudget;
3200
+ this.perTaskDefault = perTaskDefault;
3201
+ }
3202
+ /**
3203
+ * Reserve tokens for a task.
3204
+ * Returns false if the pool doesn't have enough remaining budget.
3205
+ */
3206
+ allocate(taskId, budget) {
3207
+ const requested = budget ?? this.perTaskDefault;
3208
+ const currentAllocated = this.totalAllocated();
3209
+ if (currentAllocated + requested > this.totalBudget) {
3210
+ return false;
3211
+ }
3212
+ this.allocations.set(taskId, {
3213
+ task_id: taskId,
3214
+ budget: requested,
3215
+ consumed: 0,
3216
+ allocated_at: Date.now()
3217
+ });
3218
+ return true;
3219
+ }
3220
+ /**
3221
+ * Record actual token usage for a task (cumulative).
3222
+ */
3223
+ consume(taskId, tokens) {
3224
+ const alloc = this.allocations.get(taskId);
3225
+ if (alloc) {
3226
+ alloc.consumed += tokens;
3227
+ }
3228
+ }
3229
+ /**
3230
+ * Free the allocation when a task completes.
3231
+ * Returns tokens consumed by that task.
3232
+ */
3233
+ release(taskId) {
3234
+ const alloc = this.allocations.get(taskId);
3235
+ this.allocations.delete(taskId);
3236
+ return alloc?.consumed ?? 0;
3237
+ }
3238
+ /**
3239
+ * Total remaining budget (total - allocated).
3240
+ */
3241
+ remaining() {
3242
+ return this.totalBudget - this.totalAllocated();
3243
+ }
3244
+ /**
3245
+ * Total tokens consumed across all active tasks.
3246
+ */
3247
+ consumed() {
3248
+ let total = 0;
3249
+ for (const alloc of this.allocations.values()) {
3250
+ total += alloc.consumed;
3251
+ }
3252
+ return total;
3253
+ }
3254
+ /**
3255
+ * Total tokens currently allocated (reserved but not necessarily consumed).
3256
+ */
3257
+ totalAllocated() {
3258
+ let total = 0;
3259
+ for (const alloc of this.allocations.values()) {
3260
+ total += alloc.budget;
3261
+ }
3262
+ return total;
3263
+ }
3264
+ /**
3265
+ * Check if a specific task has exceeded its allocation.
3266
+ */
3267
+ isTaskOverBudget(taskId) {
3268
+ const alloc = this.allocations.get(taskId);
3269
+ if (!alloc) return false;
3270
+ return alloc.consumed >= alloc.budget;
3271
+ }
3272
+ /**
3273
+ * Remaining budget for a specific task.
3274
+ */
3275
+ taskBudgetRemaining(taskId) {
3276
+ const alloc = this.allocations.get(taskId);
3277
+ if (!alloc) return 0;
3278
+ return Math.max(0, alloc.budget - alloc.consumed);
3279
+ }
3280
+ /**
3281
+ * Per-task token consumption summary for observability.
3282
+ */
3283
+ usageReport() {
3284
+ const tasks = {};
3285
+ let totalConsumed = 0;
3286
+ let totalAllocated = 0;
3287
+ for (const [taskId, alloc] of this.allocations.entries()) {
3288
+ tasks[taskId] = {
3289
+ budget: alloc.budget,
3290
+ consumed: alloc.consumed,
3291
+ remaining: Math.max(0, alloc.budget - alloc.consumed),
3292
+ over_budget: alloc.consumed >= alloc.budget
3293
+ };
3294
+ totalConsumed += alloc.consumed;
3295
+ totalAllocated += alloc.budget;
3296
+ }
3297
+ return {
3298
+ total_budget: this.totalBudget,
3299
+ total_allocated: totalAllocated,
3300
+ total_consumed: totalConsumed,
3301
+ total_remaining: this.totalBudget - totalAllocated,
3302
+ tasks
3303
+ };
3304
+ }
3305
+ /**
3306
+ * Clear all allocations (reset between runs).
3307
+ */
3308
+ reset() {
3309
+ this.allocations.clear();
3310
+ }
3311
+ };
3312
+
3313
+ // src/swarm/model_router.ts
3314
+ var DEFAULT_MODELS = {
3315
+ simple: "claude-3-haiku-20240307",
3316
+ moderate: "claude-3-5-sonnet-20241022",
3317
+ complex: "claude-opus-4-5"
3318
+ };
3319
+ var COMPLEX_KEYWORDS = [
3320
+ "architect",
3321
+ "design",
3322
+ "refactor",
3323
+ "debug complex",
3324
+ "optimize",
3325
+ "cross-domain",
3326
+ "integrate multiple",
3327
+ "security audit",
3328
+ "performance",
3329
+ "distributed",
3330
+ "concurrent requests",
3331
+ "migration",
3332
+ "system design",
3333
+ "multi-step",
3334
+ "synthesize",
3335
+ "reasoning",
3336
+ "trade-off"
3337
+ ];
3338
+ var SIMPLE_KEYWORDS = [
3339
+ "format",
3340
+ "list",
3341
+ "count",
3342
+ "lookup",
3343
+ "translate",
3344
+ "summarize briefly",
3345
+ "extract",
3346
+ "convert",
3347
+ "rename",
3348
+ "simple",
3349
+ "trivial",
3350
+ "basic",
3351
+ "fetch",
3352
+ "get",
3353
+ "retrieve",
3354
+ "find the"
3355
+ ];
3356
+ function classifyHeuristic(description) {
3357
+ const lower = description.toLowerCase();
3358
+ for (const kw of COMPLEX_KEYWORDS) {
3359
+ if (lower.includes(kw)) return "complex";
3360
+ }
3361
+ for (const kw of SIMPLE_KEYWORDS) {
3362
+ if (lower.includes(kw)) return "simple";
3363
+ }
3364
+ const len = description.length;
3365
+ if (len < 100) return "simple";
3366
+ if (len > 500) return "complex";
3367
+ return "moderate";
3368
+ }
3369
+ function selectModel(complexity, config) {
3370
+ const overrides = config?.models ?? {};
3371
+ return overrides[complexity] ?? DEFAULT_MODELS[complexity];
3372
+ }
3373
+ function classifyTasks(tasks) {
3374
+ const result = /* @__PURE__ */ new Map();
3375
+ for (const task of tasks) {
3376
+ result.set(task.id, task.complexity ?? classifyHeuristic(task.description));
3377
+ }
3378
+ return result;
3379
+ }
2489
3380
  export {
2490
3381
  ABTestManager,
2491
3382
  AutoResearcher,
2492
3383
  CLAWPOWERS_HOME,
2493
3384
  CheckpointManager,
3385
+ ConcurrencyManager,
2494
3386
  ContextInjector,
2495
3387
  DEFAULT_CONFIG,
2496
3388
  EpisodicMemory,
@@ -2503,17 +3395,49 @@ export {
2503
3395
  RSIAuditLog,
2504
3396
  SkillExecutor,
2505
3397
  SpendingPolicy,
3398
+ TokenPool,
2506
3399
  VERSION,
2507
3400
  WalletManager,
2508
3401
  WorkingMemoryManager,
3402
+ approximateDistance,
3403
+ calculateFee,
3404
+ calculateTransactionFee,
3405
+ classifyHeuristic,
3406
+ classifyTasks,
3407
+ compressVector,
3408
+ computeSha256,
3409
+ createPaymentHeader,
3410
+ decodeSwarmResult,
3411
+ decompressVector,
3412
+ deriveEthereumAddress,
3413
+ derivePublicKey,
2509
3414
  detect402,
3415
+ digestForWalletAddress,
2510
3416
  discoverSkills,
3417
+ encodeTaskDescription,
3418
+ evaluateWriteFirewall,
3419
+ evaluateWriteSecurity,
2511
3420
  generateWallet,
3421
+ generateWalletAddress,
2512
3422
  getActiveSkills,
3423
+ getActiveTier,
3424
+ getBestCanonicalStore,
3425
+ getCapabilitySummary,
2513
3426
  getConfigValue,
3427
+ getNative,
3428
+ getNativeCanonicalStore,
3429
+ getNativeCanonicalStoreInMemory,
3430
+ getWasm,
3431
+ getWasmCanonicalStore,
2514
3432
  importWallet,
2515
3433
  initConfig,
3434
+ isNativeAvailable,
2516
3435
  isPaymentRequired,
3436
+ isWasmAvailable,
3437
+ decode as itpDecode,
3438
+ encode as itpEncode,
3439
+ healthCheck as itpHealthCheck,
3440
+ keccak256Digest,
2517
3441
  listSkillsWithStatus,
2518
3442
  loadConfig,
2519
3443
  loadConfigSafe,
@@ -2521,15 +3445,19 @@ export {
2521
3445
  parseFrontmatter,
2522
3446
  runAutoResearch,
2523
3447
  saveConfig,
3448
+ selectModel,
2524
3449
  setConfigValue,
2525
- signMessage
3450
+ signEcdsa,
3451
+ signMessage,
3452
+ tokenAmountFromHuman,
3453
+ verifyEcdsa
2526
3454
  };
2527
3455
  /**
2528
3456
  * ClawPowers — Skills Library for AI Agents
2529
3457
  * Drop-in capability layer: payments, memory, RSI, wallet.
2530
3458
  * No agent control loop — bring your own agent.
2531
3459
  *
2532
- * @version 2.0.0
3460
+ * @version 2.2.0
2533
3461
  * @license BSL-1.1
2534
3462
  * @patent-pending
2535
3463
  */