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.
- package/CHANGELOG.md +32 -0
- package/COMPATIBILITY.md +13 -0
- package/KNOWN_LIMITATIONS.md +19 -0
- package/LICENSING.md +10 -0
- package/README.md +201 -9
- package/SECURITY.md +33 -53
- package/dist/index.d.ts +638 -5
- package/dist/index.js +986 -58
- package/dist/index.js.map +1 -1
- package/native/Cargo.lock +4863 -0
- package/native/Cargo.toml +73 -0
- package/native/crates/canonical/Cargo.toml +24 -0
- package/native/crates/canonical/src/lib.rs +673 -0
- package/native/crates/compression/Cargo.toml +20 -0
- package/native/crates/compression/benches/compression_bench.rs +42 -0
- package/native/crates/compression/src/lib.rs +393 -0
- package/native/crates/evm-eth/Cargo.toml +13 -0
- package/native/crates/evm-eth/src/lib.rs +105 -0
- package/native/crates/fee/Cargo.toml +15 -0
- package/native/crates/fee/src/lib.rs +281 -0
- package/native/crates/index/Cargo.toml +16 -0
- package/native/crates/index/src/lib.rs +277 -0
- package/native/crates/policy/Cargo.toml +17 -0
- package/native/crates/policy/src/lib.rs +614 -0
- package/native/crates/security/Cargo.toml +22 -0
- package/native/crates/security/src/lib.rs +478 -0
- package/native/crates/tokens/Cargo.toml +13 -0
- package/native/crates/tokens/src/lib.rs +534 -0
- package/native/crates/verification/Cargo.toml +23 -0
- package/native/crates/verification/src/lib.rs +333 -0
- package/native/crates/wallet/Cargo.toml +20 -0
- package/native/crates/wallet/src/lib.rs +261 -0
- package/native/crates/x402/Cargo.toml +30 -0
- package/native/crates/x402/src/lib.rs +423 -0
- package/native/ffi/Cargo.toml +34 -0
- package/native/ffi/build.rs +4 -0
- package/native/ffi/index.node +0 -0
- package/native/ffi/src/lib.rs +352 -0
- package/native/ffi/tests/integration.rs +354 -0
- package/native/pyo3/Cargo.toml +26 -0
- package/native/pyo3/pyproject.toml +16 -0
- package/native/pyo3/src/lib.rs +407 -0
- package/native/pyo3/tests/test_smoke.py +180 -0
- package/native/wasm/Cargo.toml +44 -0
- package/native/wasm/pkg/.gitignore +6 -0
- package/native/wasm/pkg/clawpowers_wasm.d.ts +208 -0
- package/native/wasm/pkg/clawpowers_wasm.js +872 -0
- package/native/wasm/pkg/clawpowers_wasm_bg.wasm +0 -0
- package/native/wasm/pkg/clawpowers_wasm_bg.wasm.d.ts +40 -0
- package/native/wasm/pkg/package.json +17 -0
- package/native/wasm/pkg-node/.gitignore +6 -0
- package/native/wasm/pkg-node/clawpowers_wasm.d.ts +143 -0
- package/native/wasm/pkg-node/clawpowers_wasm.js +798 -0
- package/native/wasm/pkg-node/clawpowers_wasm_bg.wasm +0 -0
- package/native/wasm/pkg-node/clawpowers_wasm_bg.wasm.d.ts +40 -0
- package/native/wasm/pkg-node/package.json +13 -0
- package/native/wasm/src/lib.rs +433 -0
- package/package.json +24 -3
- package/src/skills/catalog.ts +435 -0
- package/src/skills/executor.ts +56 -0
- package/src/skills/index.ts +3 -0
- package/src/skills/itp/SKILL.md +112 -0
- 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.
|
|
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
|
|
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 =
|
|
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
|
|
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 =
|
|
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
|
|
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
|
|
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 =
|
|
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
|
|
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 =
|
|
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
|
|
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 =
|
|
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
|
|
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 =
|
|
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
|
|
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 ??
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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(
|
|
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
|
|
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 =
|
|
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 =
|
|
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
|
|
2779
|
+
import { join as join7 } from "path";
|
|
2305
2780
|
|
|
2306
2781
|
// src/wallet/crypto.ts
|
|
2307
|
-
import { randomBytes, createCipheriv, createDecipheriv, scryptSync
|
|
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
|
|
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
|
|
2318
|
-
const
|
|
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 =
|
|
2807
|
+
const salt = randomBytes2(32);
|
|
2330
2808
|
const key = deriveKey(passphrase, salt);
|
|
2331
|
-
const iv =
|
|
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
|
|
2356
|
-
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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(
|
|
2431
|
-
|
|
2432
|
-
|
|
2433
|
-
|
|
2434
|
-
|
|
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 =
|
|
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
|
-
|
|
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.
|
|
3460
|
+
* @version 2.2.0
|
|
2533
3461
|
* @license BSL-1.1
|
|
2534
3462
|
* @patent-pending
|
|
2535
3463
|
*/
|