@oracle-agent/oracle 0.24.2 → 0.24.4

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 (38) hide show
  1. package/dist/assets/protocols/templates/safe-erc20/README.md +9 -0
  2. package/dist/assets/protocols/templates/safe-erc20/SECURITY.md +16 -0
  3. package/dist/assets/protocols/templates/safe-erc20/foundry.toml +12 -0
  4. package/dist/assets/protocols/templates/safe-erc20/remappings.txt +2 -0
  5. package/dist/assets/protocols/templates/safe-erc20/src/SafeERC20.sol +53 -0
  6. package/dist/assets/protocols/templates/safe-erc20/test/SafeERC20.t.sol +72 -0
  7. package/dist/assets/protocols/templates/safe-erc721-drop/README.md +3 -0
  8. package/dist/assets/protocols/templates/safe-erc721-drop/SECURITY.md +3 -0
  9. package/dist/assets/protocols/templates/safe-erc721-drop/foundry.toml +11 -0
  10. package/dist/assets/protocols/templates/safe-erc721-drop/remappings.txt +2 -0
  11. package/dist/assets/protocols/templates/safe-erc721-drop/src/SafeERC721Drop.sol +55 -0
  12. package/dist/assets/protocols/templates/safe-erc721-drop/test/SafeERC721Drop.t.sol +58 -0
  13. package/dist/assets/protocols/templates/safe-vesting/README.md +3 -0
  14. package/dist/assets/protocols/templates/safe-vesting/SECURITY.md +3 -0
  15. package/dist/assets/protocols/templates/safe-vesting/foundry.toml +11 -0
  16. package/dist/assets/protocols/templates/safe-vesting/remappings.txt +2 -0
  17. package/dist/assets/protocols/templates/safe-vesting/src/SafeVesting.sol +19 -0
  18. package/dist/assets/protocols/templates/safe-vesting/test/SafeVesting.t.sol +72 -0
  19. package/dist/assets/skills/oracle-desk-product/SKILL.md +1 -1
  20. package/dist/assets/skills/oracle-harness/SKILL.md +3 -0
  21. package/dist/bin/desk-server.mjs +13 -13
  22. package/dist/bin/oracle-gateway.mjs +18 -15
  23. package/dist/cli/commands/auth.mjs +2 -2
  24. package/dist/cli/commands/chat.mjs +87 -79
  25. package/dist/cli/commands/doctor.mjs +1 -1
  26. package/dist/cli/commands/eval.mjs +1 -1
  27. package/dist/cli/commands/harness.mjs +1 -1
  28. package/dist/cli/commands/model.mjs +92 -84
  29. package/dist/cli/commands/setup.mjs +2 -2
  30. package/dist/data/desk-data.mjs +14 -14
  31. package/dist/index.mjs +19 -19
  32. package/package.json +1 -1
  33. package/public/install.ps1 +102 -0
  34. package/public/install.sh +1 -1
  35. package/public/oracle-splash/downloads/index.html +2 -0
  36. package/public/oracle-splash/index.html +1 -0
  37. package/public/oracle-splash/install.ps1 +102 -0
  38. package/public/oracle-splash/install.sh +1 -1
@@ -0,0 +1,9 @@
1
+ # safe-erc20
2
+
3
+ ```bash
4
+ forge install foundry-rs/forge-std --no-git
5
+ forge install OpenZeppelin/openzeppelin-contracts@v5.0.2 --no-git
6
+ forge test
7
+ ```
8
+
9
+ Libs are not vendored. Gate auto-installs when missing.
@@ -0,0 +1,16 @@
1
+ # SafeERC20 template security notice
2
+
3
+ **Not a paid security-firm audit.**
4
+
5
+ This template is:
6
+ - fixed-supply ERC20
7
+ - Ownable2Step + pause
8
+ - no tax / blacklist / upgrade proxy
9
+ - covered by Foundry unit tests in `test/`
10
+
11
+ Before mainnet capital:
12
+ 1. Keep or expand Foundry tests green
13
+ 2. Run static analysis (Slither/Aderyn) if available
14
+ 3. Book an independent Solidity auditor for any real TVL
15
+
16
+ Oracle only prepares unsigned deploys after the JS gate confirms `forge test` passes.
@@ -0,0 +1,12 @@
1
+ [profile.default]
2
+ src = "src"
3
+ out = "out"
4
+ libs = ["lib"]
5
+ solc = "0.8.24"
6
+ optimizer = true
7
+ optimizer_runs = 200
8
+ ffi = false
9
+ fs_permissions = [{ access = "read", path = "./" }]
10
+
11
+ [fmt]
12
+ line_length = 100
@@ -0,0 +1,2 @@
1
+ @openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/
2
+ forge-std/=lib/forge-std/src/
@@ -0,0 +1,53 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.24;
3
+
4
+ import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
5
+ import {ERC20Burnable} from "@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol";
6
+ import {ERC20Pausable} from "@openzeppelin/contracts/token/ERC20/extensions/ERC20Pausable.sol";
7
+ import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
8
+ import {Ownable2Step} from "@openzeppelin/contracts/access/Ownable2Step.sol";
9
+
10
+ /**
11
+ * @title SafeERC20
12
+ * @notice Opinionated fixed-supply ERC20 for Oracle protocol-builder v1.
13
+ *
14
+ * Security posture (templates, NOT a firm audit):
15
+ * - Fixed supply minted once to `initialHolder` in constructor (no hidden mint).
16
+ * - Ownable2Step ownership (no single-tx accidental transfer).
17
+ * - Pausable emergency stop (owner only).
18
+ * - No transfer tax, no blacklist, no max-tx, no trading cooldown.
19
+ * - No upgradeability / no proxy.
20
+ * - Burn optional by holders only (ERC20Burnable).
21
+ *
22
+ * This is a reviewed starter template with Foundry tests. It is NOT a paid
23
+ * security-firm audit. Do not put mainnet TVL on custom forks without one.
24
+ */
25
+ contract SafeERC20 is ERC20, ERC20Burnable, ERC20Pausable, Ownable2Step {
26
+ constructor(
27
+ string memory name_,
28
+ string memory symbol_,
29
+ uint256 initialSupply,
30
+ address initialHolder,
31
+ address initialOwner
32
+ ) ERC20(name_, symbol_) Ownable(initialOwner) {
33
+ require(initialHolder != address(0), "SafeERC20: holder zero");
34
+ require(initialOwner != address(0), "SafeERC20: owner zero");
35
+ require(initialSupply > 0, "SafeERC20: supply zero");
36
+ _mint(initialHolder, initialSupply);
37
+ }
38
+
39
+ function pause() external onlyOwner {
40
+ _pause();
41
+ }
42
+
43
+ function unpause() external onlyOwner {
44
+ _unpause();
45
+ }
46
+
47
+ function _update(address from, address to, uint256 value)
48
+ internal
49
+ override(ERC20, ERC20Pausable)
50
+ {
51
+ super._update(from, to, value);
52
+ }
53
+ }
@@ -0,0 +1,72 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.24;
3
+
4
+ import {Test} from "forge-std/Test.sol";
5
+ import {SafeERC20} from "../src/SafeERC20.sol";
6
+
7
+ contract SafeERC20Test is Test {
8
+ SafeERC20 internal token;
9
+ address internal owner = makeAddr("owner");
10
+ address internal holder = makeAddr("holder");
11
+ address internal alice = makeAddr("alice");
12
+ address internal bob = makeAddr("bob");
13
+
14
+ uint256 internal constant SUPPLY = 1_000_000 ether;
15
+
16
+ function setUp() public {
17
+ token = new SafeERC20("Safe", "SAFE", SUPPLY, holder, owner);
18
+ }
19
+
20
+ function test_fixedSupply_noHiddenMint() public view {
21
+ assertEq(token.totalSupply(), SUPPLY);
22
+ assertEq(token.balanceOf(holder), SUPPLY);
23
+ assertEq(token.balanceOf(owner), 0);
24
+ }
25
+
26
+ function test_transfer_noTax() public {
27
+ vm.prank(holder);
28
+ token.transfer(alice, 100 ether);
29
+ assertEq(token.balanceOf(alice), 100 ether);
30
+ assertEq(token.balanceOf(holder), SUPPLY - 100 ether);
31
+ }
32
+
33
+ function test_pause_blocksTransfers() public {
34
+ vm.prank(owner);
35
+ token.pause();
36
+ vm.prank(holder);
37
+ vm.expectRevert();
38
+ token.transfer(alice, 1 ether);
39
+ }
40
+
41
+ function test_onlyOwner_canPause() public {
42
+ vm.prank(alice);
43
+ vm.expectRevert();
44
+ token.pause();
45
+ }
46
+
47
+ function test_ownable2Step_requiresAccept() public {
48
+ vm.prank(owner);
49
+ token.transferOwnership(alice);
50
+ // still owner until accept
51
+ assertEq(token.owner(), owner);
52
+ vm.prank(alice);
53
+ token.acceptOwnership();
54
+ assertEq(token.owner(), alice);
55
+ }
56
+
57
+ function test_burn_reducesSupply() public {
58
+ vm.prank(holder);
59
+ token.burn(10 ether);
60
+ assertEq(token.totalSupply(), SUPPLY - 10 ether);
61
+ }
62
+
63
+ function test_rejectZeroHolder() public {
64
+ vm.expectRevert(bytes("SafeERC20: holder zero"));
65
+ new SafeERC20("X", "X", SUPPLY, address(0), owner);
66
+ }
67
+
68
+ function test_rejectZeroSupply() public {
69
+ vm.expectRevert(bytes("SafeERC20: supply zero"));
70
+ new SafeERC20("X", "X", 0, holder, owner);
71
+ }
72
+ }
@@ -0,0 +1,3 @@
1
+ # safe-erc721-drop
2
+
3
+ Fixed, non-upgradeable ERC721 public mint. Dependencies are pinned to OpenZeppelin Contracts 5.0.2 by the Oracle gate. Run `forge test` before review.
@@ -0,0 +1,3 @@
1
+ # SafeERC721Drop security notice
2
+
3
+ **Not a paid security-firm audit.** Fixed source, immutable cap/treasury/price/wallet cap, sequential public mint, owner-only withdrawal, and no proxy, upgrade hook, or delegatecall. Obtain an independent audit before mainnet use.
@@ -0,0 +1,11 @@
1
+ [profile.default]
2
+ src = "src"
3
+ out = "out"
4
+ libs = ["lib"]
5
+ solc = "0.8.24"
6
+ optimizer = true
7
+ optimizer_runs = 200
8
+ ffi = false
9
+
10
+ [fmt]
11
+ line_length = 100
@@ -0,0 +1,2 @@
1
+ @openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/
2
+ forge-std/=lib/forge-std/src/
@@ -0,0 +1,55 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.24;
3
+
4
+ import {ERC721} from "@openzeppelin/contracts/token/ERC721/ERC721.sol";
5
+ import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
6
+
7
+ contract SafeERC721Drop is ERC721, Ownable {
8
+ uint256 public immutable cap;
9
+ address payable public immutable treasury;
10
+ uint256 public immutable mintPrice;
11
+ uint256 public immutable perWalletCap;
12
+ uint256 public totalMinted;
13
+ mapping(address => uint256) public mintedBy;
14
+
15
+ event Withdrawal(address indexed treasury, uint256 amount);
16
+
17
+ constructor(
18
+ string memory name_,
19
+ string memory symbol_,
20
+ uint256 cap_,
21
+ address treasury_,
22
+ uint256 mintPrice_,
23
+ uint256 perWalletCap_,
24
+ address initialOwner
25
+ ) ERC721(name_, symbol_) Ownable(initialOwner) {
26
+ require(cap_ > 0, "cap zero");
27
+ require(treasury_ != address(0), "treasury zero");
28
+ require(mintPrice_ > 0, "price zero");
29
+ require(perWalletCap_ > 0 && perWalletCap_ <= cap_, "wallet cap invalid");
30
+ cap = cap_;
31
+ treasury = payable(treasury_);
32
+ mintPrice = mintPrice_;
33
+ perWalletCap = perWalletCap_;
34
+ }
35
+
36
+ function mint(uint256 quantity) external payable {
37
+ require(quantity > 0, "quantity zero");
38
+ require(totalMinted + quantity <= cap, "collection cap");
39
+ require(mintedBy[msg.sender] + quantity <= perWalletCap, "wallet cap");
40
+ require(msg.value == mintPrice * quantity, "wrong payment");
41
+ mintedBy[msg.sender] += quantity;
42
+ uint256 first = totalMinted + 1;
43
+ totalMinted += quantity;
44
+ for (uint256 tokenId = first; tokenId < first + quantity; tokenId++) {
45
+ _safeMint(msg.sender, tokenId);
46
+ }
47
+ }
48
+
49
+ function withdraw() external onlyOwner {
50
+ uint256 amount = address(this).balance;
51
+ (bool ok,) = treasury.call{value: amount}("");
52
+ require(ok, "withdraw failed");
53
+ emit Withdrawal(treasury, amount);
54
+ }
55
+ }
@@ -0,0 +1,58 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.24;
3
+ import {Test} from "forge-std/Test.sol";
4
+ import {SafeERC721Drop} from "../src/SafeERC721Drop.sol";
5
+
6
+ contract SafeERC721DropTest is Test {
7
+ SafeERC721Drop drop;
8
+ address owner = makeAddr("owner");
9
+ address treasury = makeAddr("treasury");
10
+ address alice = makeAddr("alice");
11
+
12
+ function setUp() public {
13
+ drop = new SafeERC721Drop("Safe", "SAFE", 3, treasury, 1 ether, 2, owner);
14
+ vm.deal(alice, 10 ether);
15
+ }
16
+
17
+ function testMintPaymentAndWalletCap() public {
18
+ vm.prank(alice);
19
+ drop.mint{value: 2 ether}(2);
20
+ assertEq(drop.balanceOf(alice), 2);
21
+ vm.prank(alice);
22
+ vm.expectRevert("wallet cap");
23
+ drop.mint{value: 1 ether}(1);
24
+ }
25
+
26
+ function testRejectsWrongPayment() public {
27
+ vm.prank(alice);
28
+ vm.expectRevert("wrong payment");
29
+ drop.mint{value: 0.5 ether}(1);
30
+ }
31
+
32
+ function testCollectionCap() public {
33
+ address bob = makeAddr("bob");
34
+ vm.deal(bob, 2 ether);
35
+ vm.prank(alice);
36
+ drop.mint{value: 2 ether}(2);
37
+ vm.prank(bob);
38
+ drop.mint{value: 1 ether}(1);
39
+ address carol = makeAddr("carol");
40
+ vm.deal(carol, 1 ether);
41
+ vm.prank(carol);
42
+ vm.expectRevert("collection cap");
43
+ drop.mint{value: 1 ether}(1);
44
+ }
45
+
46
+ function testOnlyOwnerWithdrawsToTreasury() public {
47
+ vm.prank(alice);
48
+ drop.mint{value: 1 ether}(1);
49
+ vm.prank(alice);
50
+ vm.expectRevert();
51
+ drop.withdraw();
52
+ uint256 beforeBalance = treasury.balance;
53
+ vm.prank(owner);
54
+ drop.withdraw();
55
+ assertEq(treasury.balance, beforeBalance + 1 ether);
56
+ assertEq(address(drop).balance, 0);
57
+ }
58
+ }
@@ -0,0 +1,3 @@
1
+ # safe-vesting
2
+
3
+ Fixed wrapper around OpenZeppelin Contracts 5.0.2 `VestingWallet`, with beneficiary, start, and duration fixed at construction. The beneficiary remains the OpenZeppelin owner/recipient identity, but ownership transfer and renunciation are permanently disabled. No separate administrator or proxy authority.
@@ -0,0 +1,3 @@
1
+ # SafeVesting security notice
2
+
3
+ **Not a paid security-firm audit.** This is a fixed OpenZeppelin VestingWallet wrapper. Beneficiary, start, and duration are constructor-set. The beneficiary is the owner/recipient identity required by `VestingWallet`, and the wrapper disables ownership transfer and renunciation. There is no separate administrator, proxy, upgrade, or delegatecall.
@@ -0,0 +1,11 @@
1
+ [profile.default]
2
+ src = "src"
3
+ out = "out"
4
+ libs = ["lib"]
5
+ solc = "0.8.24"
6
+ optimizer = true
7
+ optimizer_runs = 200
8
+ ffi = false
9
+
10
+ [fmt]
11
+ line_length = 100
@@ -0,0 +1,2 @@
1
+ @openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/
2
+ forge-std/=lib/forge-std/src/
@@ -0,0 +1,19 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.24;
3
+ import {VestingWallet} from "@openzeppelin/contracts/finance/VestingWallet.sol";
4
+
5
+ contract SafeVesting is VestingWallet {
6
+ error BeneficiaryImmutable();
7
+
8
+ constructor(address beneficiary, uint64 startTimestamp, uint64 durationSeconds)
9
+ VestingWallet(beneficiary, startTimestamp, durationSeconds)
10
+ {}
11
+
12
+ function transferOwnership(address) public pure override {
13
+ revert BeneficiaryImmutable();
14
+ }
15
+
16
+ function renounceOwnership() public pure override {
17
+ revert BeneficiaryImmutable();
18
+ }
19
+ }
@@ -0,0 +1,72 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.24;
3
+ import {Test} from "forge-std/Test.sol";
4
+ import {SafeVesting} from "../src/SafeVesting.sol";
5
+ import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
6
+
7
+ contract TestToken is ERC20 {
8
+ constructor() ERC20("Test", "TEST") {}
9
+
10
+ function mint(address to, uint256 amount) external {
11
+ _mint(to, amount);
12
+ }
13
+ }
14
+
15
+ contract SafeVestingTest is Test {
16
+ SafeVesting vesting;
17
+ address beneficiary = makeAddr("beneficiary");
18
+ uint64 start;
19
+
20
+ function setUp() public {
21
+ start = uint64(block.timestamp + 100);
22
+ vesting = new SafeVesting(beneficiary, start, 1000);
23
+ vm.deal(address(vesting), 10 ether);
24
+ }
25
+
26
+ function testFixedScheduleAndBeneficiary() public view {
27
+ assertEq(vesting.owner(), beneficiary);
28
+ assertEq(vesting.start(), start);
29
+ assertEq(vesting.duration(), 1000);
30
+ }
31
+
32
+ function testBeneficiaryCannotBeChangedOrRenounced() public {
33
+ vm.startPrank(beneficiary);
34
+ vm.expectRevert(SafeVesting.BeneficiaryImmutable.selector);
35
+ vesting.transferOwnership(makeAddr("replacement"));
36
+ vm.expectRevert(SafeVesting.BeneficiaryImmutable.selector);
37
+ vesting.renounceOwnership();
38
+ vm.stopPrank();
39
+ assertEq(vesting.owner(), beneficiary);
40
+ }
41
+
42
+ function testLinearReleaseSemantics() public {
43
+ vesting.release();
44
+ assertEq(beneficiary.balance, 0);
45
+ vm.warp(start + 500);
46
+ vesting.release();
47
+ assertEq(beneficiary.balance, 5 ether);
48
+ vm.warp(start + 1000);
49
+ vesting.release();
50
+ assertEq(beneficiary.balance, 10 ether);
51
+ }
52
+
53
+ function testAnyoneCanTriggerButOnlyBeneficiaryReceives() public {
54
+ vm.warp(start + 1000);
55
+ address caller = makeAddr("caller");
56
+ vm.prank(caller);
57
+ vesting.release();
58
+ assertEq(caller.balance, 0);
59
+ assertEq(beneficiary.balance, 10 ether);
60
+ }
61
+
62
+ function testERC20ReleaseUsesSameSchedule() public {
63
+ TestToken token = new TestToken();
64
+ token.mint(address(vesting), 1000 ether);
65
+ vm.warp(start + 250);
66
+ vesting.release(address(token));
67
+ assertEq(token.balanceOf(beneficiary), 250 ether);
68
+ vm.warp(start + 1000);
69
+ vesting.release(address(token));
70
+ assertEq(token.balanceOf(beneficiary), 1000 ether);
71
+ }
72
+ }
@@ -97,7 +97,7 @@ does not prove npm users receive it. A locally hosted model/data/policy loop doe
97
97
  a bundled signer. A merged feature is not public until the npm artifact containing it is
98
98
  published and inspected.
99
99
 
100
- **Current verified state as of 2026-08-12:** public npm `@oracle-agent/oracle@0.24.0`
100
+ **Current verified state as of 2026-08-13:** public npm `@oracle-agent/oracle@0.24.4`
101
101
  ships the optional encrypted local vault + short-lived loopback signer. Hosted/default
102
102
  Oracle stays prepare-only. Self-host after `oracle sign init|import` is **auto-armed**
103
103
  for user-initiated actions. Public still charges the disclosed fee card; Administrator
@@ -22,6 +22,9 @@ From Hermes / Claude / Codex / Cursor-class agents, ship the **desk capabilities
22
22
  | Plugins | `oracle plugins install` |
23
23
  | Multi-model | `oracle setup model` / `/model` |
24
24
  | Attach another engine | `oracle chat --backend hermes\|claude\|codex` |
25
+ | Native RLM | `rlm` tool — bind context as vars, `rlm.run` depth-1 children. Host-owned. No IPython. |
26
+ | OpenClaw recall | `memory_search` + per-turn auto-recall. No LanceDB / ClawHub. |
27
+ | Perplexity research | `deep_research` search-first cited brief. No Comet / Computer. |
25
28
  | Quote / route / prepare | `oracle_cli` |
26
29
  | Local sign | vault + loopback `signer_execute` (human nonce) |
27
30
  | All shipped EVM | `oracle-evm` — same vault, different chainId |