@rotifer/playground 0.3.0-alpha.1 → 0.4.0-alpha.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 +36 -0
- package/README.md +22 -8
- package/README.zh.md +8 -2
- package/dist/cloud/auth.d.ts +14 -0
- package/dist/cloud/auth.d.ts.map +1 -0
- package/dist/cloud/auth.js +129 -0
- package/dist/cloud/auth.js.map +1 -0
- package/dist/cloud/client.d.ts +30 -0
- package/dist/cloud/client.d.ts.map +1 -0
- package/dist/cloud/client.js +299 -0
- package/dist/cloud/client.js.map +1 -0
- package/dist/cloud/index.d.ts +4 -0
- package/dist/cloud/index.d.ts.map +1 -0
- package/dist/cloud/index.js +20 -0
- package/dist/cloud/index.js.map +1 -0
- package/dist/cloud/types.d.ts +73 -0
- package/dist/cloud/types.d.ts.map +1 -0
- package/dist/cloud/types.js +7 -0
- package/dist/cloud/types.js.map +1 -0
- package/dist/commands/arena-list.d.ts.map +1 -1
- package/dist/commands/arena-list.js +51 -1
- package/dist/commands/arena-list.js.map +1 -1
- package/dist/commands/arena-submit.d.ts.map +1 -1
- package/dist/commands/arena-submit.js +35 -1
- package/dist/commands/arena-submit.js.map +1 -1
- package/dist/commands/arena-watch.d.ts.map +1 -1
- package/dist/commands/arena-watch.js +96 -2
- package/dist/commands/arena-watch.js.map +1 -1
- package/dist/commands/install.d.ts +3 -0
- package/dist/commands/install.d.ts.map +1 -0
- package/dist/commands/install.js +94 -0
- package/dist/commands/install.js.map +1 -0
- package/dist/commands/login.d.ts +3 -0
- package/dist/commands/login.d.ts.map +1 -0
- package/dist/commands/login.js +133 -0
- package/dist/commands/login.js.map +1 -0
- package/dist/commands/logout.d.ts +3 -0
- package/dist/commands/logout.d.ts.map +1 -0
- package/dist/commands/logout.js +53 -0
- package/dist/commands/logout.js.map +1 -0
- package/dist/commands/publish.d.ts +3 -0
- package/dist/commands/publish.d.ts.map +1 -0
- package/dist/commands/publish.js +121 -0
- package/dist/commands/publish.js.map +1 -0
- package/dist/commands/search.d.ts +3 -0
- package/dist/commands/search.d.ts.map +1 -0
- package/dist/commands/search.js +106 -0
- package/dist/commands/search.js.map +1 -0
- package/dist/index.js +11 -1
- package/dist/index.js.map +1 -1
- package/genes/genesis-web-search/.cloud-manifest.json +6 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,42 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [0.4.0-alpha.1] - 2026-02-23
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- **Cloud Binding** — Cross-developer gene sharing via Supabase-backed REST API
|
|
13
|
+
- `rotifer login` — GitHub OAuth authentication via PKCE flow
|
|
14
|
+
- `rotifer logout` — Clear cloud credentials
|
|
15
|
+
- `rotifer publish <gene>` — Upload gene (phenotype + WASM) to cloud registry, saves `.cloud-manifest.json`
|
|
16
|
+
- `rotifer search [query]` — Search and browse cloud gene registry
|
|
17
|
+
- `rotifer install <gene-id>` — Download gene from cloud to local project
|
|
18
|
+
- Cloud Binding REST API specification (`docs/cloud-binding-api.md`)
|
|
19
|
+
- Supabase database schema with RLS policies (`supabase/migrations/001_initial.sql`)
|
|
20
|
+
- Auto-profile creation trigger (`supabase/migrations/002_auto_profile.sql`)
|
|
21
|
+
|
|
22
|
+
- **Cloud Arena** — Remote Arena competition across developers
|
|
23
|
+
- `rotifer arena submit --cloud` — Submit gene to cloud Arena
|
|
24
|
+
- `rotifer arena list --cloud` — View cloud Arena rankings
|
|
25
|
+
- `rotifer arena watch --cloud` — Real-time cloud ranking updates (polling)
|
|
26
|
+
- Server-side ranking via PostgreSQL `get_arena_rankings()` function
|
|
27
|
+
|
|
28
|
+
- **Endpoint-agnostic design** — CLI supports custom Cloud Binding endpoints via `--endpoint` flag or `~/.rotifer/cloud.json` config, enabling multiple deployments (global Supabase + rotifer.cloud China)
|
|
29
|
+
|
|
30
|
+
- **Supabase CLI integration** — Project linked via `supabase link`, migrations pushed via `supabase db push`
|
|
31
|
+
|
|
32
|
+
### Fixed
|
|
33
|
+
|
|
34
|
+
- OAuth login: switched from implicit flow to PKCE for secure token exchange
|
|
35
|
+
- Missing user profile on first login: added DB trigger `handle_new_user()` with backfill
|
|
36
|
+
- `rotifer publish` now saves `.cloud-manifest.json` in source gene dir for `arena submit --cloud` linkage
|
|
37
|
+
- `rotifer publish` graceful error when not logged in (was showing raw stack trace)
|
|
38
|
+
|
|
39
|
+
### Changed
|
|
40
|
+
|
|
41
|
+
- CLI description updated from "local development environment" to "development environment" (reflects cloud capabilities)
|
|
42
|
+
- Test count: 91 → 114 (23 new cloud tests)
|
|
43
|
+
|
|
8
44
|
## [0.3.0-alpha.1] - 2026-02-17
|
|
9
45
|
|
|
10
46
|
### Added
|
package/README.md
CHANGED
|
@@ -5,10 +5,11 @@
|
|
|
5
5
|
[](LICENSE)
|
|
6
6
|
[](https://nodejs.org/)
|
|
7
7
|
[](https://github.com/rotifer-protocol/rotifer-spec)
|
|
8
|
+
[](https://discord.gg/6d4JrfMr)
|
|
8
9
|
|
|
9
|
-
|
|
10
|
+
Development environment for the **Rotifer Protocol** — build genes, compete in Arenas, share via Cloud, and simulate agent evolution.
|
|
10
11
|
|
|
11
|
-
> **Status:** Alpha (v0.
|
|
12
|
+
> **Status:** Alpha (v0.4.0-alpha.1). Core gene lifecycle, IR compiler pipeline, parallel algebra, **TS→WASM auto-compilation (Javy)**, **Cloud Binding (publish/search/install)**, and live Arena watching are functional.
|
|
12
13
|
|
|
13
14
|
---
|
|
14
15
|
|
|
@@ -117,12 +118,14 @@ playground/
|
|
|
117
118
|
│ ├── rotifer-core/ Rust: types, sandbox, arena, algebra, fitness, storage
|
|
118
119
|
│ └── rotifer-napi/ napi-rs bridge: Rust ↔ Node.js FFI
|
|
119
120
|
├── src/ TypeScript CLI (commander.js)
|
|
120
|
-
│ ├── commands/
|
|
121
|
+
│ ├── commands/ 16 CLI commands
|
|
122
|
+
│ ├── cloud/ Cloud Binding client (auth, API, types)
|
|
121
123
|
│ ├── utils/ Config, display, NAPI binding, Javy compiler
|
|
122
124
|
│ └── errors/ Rust-style error formatting
|
|
123
125
|
├── genes/ 5 Genesis genes (bundled)
|
|
126
|
+
├── supabase/ Cloud Binding database migrations
|
|
124
127
|
├── templates/ Gene + composition scaffolds
|
|
125
|
-
└── tests/ Unit + E2E test suites (
|
|
128
|
+
└── tests/ Unit + E2E test suites (114 tests)
|
|
126
129
|
```
|
|
127
130
|
|
|
128
131
|
### Layers
|
|
@@ -144,9 +147,14 @@ playground/
|
|
|
144
147
|
| `rotifer wrap <name>` | Wrap a function as a Rotifer gene |
|
|
145
148
|
| `rotifer test [name]` | Test a gene in L2 sandbox |
|
|
146
149
|
| `rotifer compile [name]` | Compile gene to Rotifer IR (auto TS→WASM via Javy) |
|
|
147
|
-
| `rotifer arena submit <name>` | Submit a gene to the Arena |
|
|
148
|
-
| `rotifer arena list` | List Arena rankings |
|
|
149
|
-
| `rotifer arena watch <domain>` | Watch Arena rankings (
|
|
150
|
+
| `rotifer arena submit <name>` | Submit a gene to the Arena (`--cloud` for Cloud Arena) |
|
|
151
|
+
| `rotifer arena list` | List Arena rankings (`--cloud` for Cloud Arena) |
|
|
152
|
+
| `rotifer arena watch <domain>` | Watch Arena rankings live (`--cloud` for Cloud Arena) |
|
|
153
|
+
| `rotifer login` | Log in to Rotifer Cloud via GitHub OAuth |
|
|
154
|
+
| `rotifer logout` | Log out from Rotifer Cloud |
|
|
155
|
+
| `rotifer publish <name>` | Publish a gene to Rotifer Cloud |
|
|
156
|
+
| `rotifer search [query]` | Search genes on Rotifer Cloud |
|
|
157
|
+
| `rotifer install <gene-id>` | Install a gene from Rotifer Cloud |
|
|
150
158
|
| `rotifer agent create <name>` | Create an Agent with a genome |
|
|
151
159
|
| `rotifer agent list` | List all agents |
|
|
152
160
|
| `rotifer agent run <name>` | Execute an agent's genome pipeline |
|
|
@@ -192,7 +200,7 @@ cd playground
|
|
|
192
200
|
# TypeScript CLI
|
|
193
201
|
npm install
|
|
194
202
|
npm run build # Build to dist/
|
|
195
|
-
npm test # Run
|
|
203
|
+
npm test # Run 114 TypeScript tests
|
|
196
204
|
npm run lint # Type check only
|
|
197
205
|
|
|
198
206
|
# Rust Core (requires Rust toolchain)
|
|
@@ -224,10 +232,16 @@ Changes driven by implementation feedback are proposed through the ADR process.
|
|
|
224
232
|
- [x] **v0.1.0-alpha.1** — Core CLI + Genesis genes + Arena
|
|
225
233
|
- [x] **v0.2.0-alpha.1** — IR compiler pipeline, live Arena watching, NAPI bridge, end-to-end demo loop
|
|
226
234
|
- [x] **v0.3.0-alpha.1** — Frontend SDK: TS→WASM auto-compilation via Javy, WASI sandbox support
|
|
235
|
+
- [x] **v0.4.0-alpha.1** — Cloud Binding: publish/search/install genes, Cloud Arena, GitHub OAuth
|
|
227
236
|
- [ ] **v1.0.0** — Full protocol compliance, multi-binding support, P2P HLT
|
|
228
237
|
|
|
229
238
|
---
|
|
230
239
|
|
|
240
|
+
## Community
|
|
241
|
+
|
|
242
|
+
- [Discord](https://discord.gg/6d4JrfMr) — Join the conversation
|
|
243
|
+
- [GitHub Discussions](https://github.com/rotifer-protocol/rotifer-playground/discussions) — Questions and proposals
|
|
244
|
+
|
|
231
245
|
## Contributing
|
|
232
246
|
|
|
233
247
|
See [CONTRIBUTING.md](CONTRIBUTING.md) for development setup and guidelines.
|
package/README.zh.md
CHANGED
|
@@ -5,10 +5,11 @@
|
|
|
5
5
|
[](LICENSE)
|
|
6
6
|
[](https://nodejs.org/)
|
|
7
7
|
[](https://github.com/rotifer-protocol/rotifer-spec)
|
|
8
|
+
[](https://discord.gg/6d4JrfMr)
|
|
8
9
|
|
|
9
|
-
**Rotifer Protocol**
|
|
10
|
+
**Rotifer Protocol** 的开发环境——构建基因、运行 Arena 竞争、通过 Cloud 共享、模拟代理进化。
|
|
10
11
|
|
|
11
|
-
> **状态:** Alpha (v0.
|
|
12
|
+
> **状态:** Alpha (v0.4.0-alpha.1)。核心基因生命周期、IR 编译器管线、并行代数、**TS→WASM 自动编译 (Javy)**、**Cloud Binding(发布/搜索/安装)**、实时 Arena 观察已可用。
|
|
12
13
|
|
|
13
14
|
---
|
|
14
15
|
|
|
@@ -228,6 +229,11 @@ bash demo.sh
|
|
|
228
229
|
|
|
229
230
|
---
|
|
230
231
|
|
|
232
|
+
## 社区
|
|
233
|
+
|
|
234
|
+
- [Discord](https://discord.gg/6d4JrfMr) — 加入讨论
|
|
235
|
+
- [GitHub Discussions](https://github.com/rotifer-protocol/rotifer-playground/discussions) — 问题与提案
|
|
236
|
+
|
|
231
237
|
## 参与贡献
|
|
232
238
|
|
|
233
239
|
开发指南请参见 [CONTRIBUTING.md](CONTRIBUTING.md)。
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { CloudCredentials } from "./types.js";
|
|
2
|
+
export declare function loadCredentials(): CloudCredentials | null;
|
|
3
|
+
export declare function saveCredentials(creds: CloudCredentials): void;
|
|
4
|
+
export declare function clearCredentials(): void;
|
|
5
|
+
export declare function isLoggedIn(): boolean;
|
|
6
|
+
export declare function requireAuth(): CloudCredentials;
|
|
7
|
+
export declare function generateCodeVerifier(): string;
|
|
8
|
+
export declare function generateCodeChallenge(verifier: string): string;
|
|
9
|
+
/**
|
|
10
|
+
* Start a local HTTP server to receive the OAuth callback.
|
|
11
|
+
* Handles both PKCE flow (?code=...) and implicit flow (#access_token=...).
|
|
12
|
+
*/
|
|
13
|
+
export declare function waitForOAuthCallback(port?: number): Promise<string>;
|
|
14
|
+
//# sourceMappingURL=auth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/cloud/auth.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAkBnD,wBAAgB,eAAe,IAAI,gBAAgB,GAAG,IAAI,CAazD;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,gBAAgB,GAAG,IAAI,CAK7D;AAED,wBAAgB,gBAAgB,IAAI,IAAI,CAMvC;AAED,wBAAgB,UAAU,IAAI,OAAO,CAEpC;AAED,wBAAgB,WAAW,IAAI,gBAAgB,CAQ9C;AAED,wBAAgB,oBAAoB,IAAI,MAAM,CAE7C;AAED,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAE9D;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,GAAE,MAAa,GAAG,OAAO,CAAC,MAAM,CAAC,CA+DzE"}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.loadCredentials = loadCredentials;
|
|
4
|
+
exports.saveCredentials = saveCredentials;
|
|
5
|
+
exports.clearCredentials = clearCredentials;
|
|
6
|
+
exports.isLoggedIn = isLoggedIn;
|
|
7
|
+
exports.requireAuth = requireAuth;
|
|
8
|
+
exports.generateCodeVerifier = generateCodeVerifier;
|
|
9
|
+
exports.generateCodeChallenge = generateCodeChallenge;
|
|
10
|
+
exports.waitForOAuthCallback = waitForOAuthCallback;
|
|
11
|
+
const node_fs_1 = require("node:fs");
|
|
12
|
+
const node_path_1 = require("node:path");
|
|
13
|
+
const node_http_1 = require("node:http");
|
|
14
|
+
const node_crypto_1 = require("node:crypto");
|
|
15
|
+
const types_js_1 = require("./types.js");
|
|
16
|
+
const ROTIFER_HOME = (0, node_path_1.join)(process.env.HOME || process.env.USERPROFILE || "/tmp", ".rotifer");
|
|
17
|
+
function ensureRotiferHome() {
|
|
18
|
+
if (!(0, node_fs_1.existsSync)(ROTIFER_HOME)) {
|
|
19
|
+
(0, node_fs_1.mkdirSync)(ROTIFER_HOME, { recursive: true });
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
function credentialsPath() {
|
|
23
|
+
return (0, node_path_1.join)(ROTIFER_HOME, types_js_1.CREDENTIALS_FILE);
|
|
24
|
+
}
|
|
25
|
+
function loadCredentials() {
|
|
26
|
+
const path = credentialsPath();
|
|
27
|
+
if (!(0, node_fs_1.existsSync)(path))
|
|
28
|
+
return null;
|
|
29
|
+
try {
|
|
30
|
+
const data = JSON.parse((0, node_fs_1.readFileSync)(path, "utf-8"));
|
|
31
|
+
if (data.expires_at && Date.now() > data.expires_at) {
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
return data;
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
function saveCredentials(creds) {
|
|
41
|
+
ensureRotiferHome();
|
|
42
|
+
(0, node_fs_1.writeFileSync)(credentialsPath(), JSON.stringify(creds, null, 2) + "\n", {
|
|
43
|
+
mode: 0o600,
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
function clearCredentials() {
|
|
47
|
+
const path = credentialsPath();
|
|
48
|
+
if ((0, node_fs_1.existsSync)(path)) {
|
|
49
|
+
(0, node_fs_1.writeFileSync)(path, "", { mode: 0o600 });
|
|
50
|
+
require("node:fs").unlinkSync(path);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
function isLoggedIn() {
|
|
54
|
+
return loadCredentials() !== null;
|
|
55
|
+
}
|
|
56
|
+
function requireAuth() {
|
|
57
|
+
const creds = loadCredentials();
|
|
58
|
+
if (!creds) {
|
|
59
|
+
throw new Error("Not logged in. Run 'rotifer login' first.");
|
|
60
|
+
}
|
|
61
|
+
return creds;
|
|
62
|
+
}
|
|
63
|
+
function generateCodeVerifier() {
|
|
64
|
+
return (0, node_crypto_1.randomBytes)(32).toString("base64url");
|
|
65
|
+
}
|
|
66
|
+
function generateCodeChallenge(verifier) {
|
|
67
|
+
return (0, node_crypto_1.createHash)("sha256").update(verifier).digest("base64url");
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Start a local HTTP server to receive the OAuth callback.
|
|
71
|
+
* Handles both PKCE flow (?code=...) and implicit flow (#access_token=...).
|
|
72
|
+
*/
|
|
73
|
+
function waitForOAuthCallback(port = 9876) {
|
|
74
|
+
return new Promise((resolve, reject) => {
|
|
75
|
+
const server = (0, node_http_1.createServer)((req, res) => {
|
|
76
|
+
const url = new URL(req.url || "/", `http://localhost:${port}`);
|
|
77
|
+
if (url.pathname === "/callback/token") {
|
|
78
|
+
const token = url.searchParams.get("access_token");
|
|
79
|
+
const refresh = url.searchParams.get("refresh_token");
|
|
80
|
+
if (token) {
|
|
81
|
+
res.writeHead(200, { "Content-Type": "text/html" });
|
|
82
|
+
res.end("<html><body><h2>Login successful!</h2>" +
|
|
83
|
+
"<p>You can close this window and return to the terminal.</p>" +
|
|
84
|
+
"</body></html>");
|
|
85
|
+
server.close();
|
|
86
|
+
resolve(`implicit:${token}:${refresh || ""}`);
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
const code = url.searchParams.get("code");
|
|
91
|
+
if (code) {
|
|
92
|
+
res.writeHead(200, { "Content-Type": "text/html" });
|
|
93
|
+
res.end("<html><body><h2>Login successful!</h2>" +
|
|
94
|
+
"<p>You can close this window and return to the terminal.</p>" +
|
|
95
|
+
"</body></html>");
|
|
96
|
+
server.close();
|
|
97
|
+
resolve(code);
|
|
98
|
+
}
|
|
99
|
+
else {
|
|
100
|
+
res.writeHead(200, { "Content-Type": "text/html" });
|
|
101
|
+
res.end(`<html><body><script>
|
|
102
|
+
if (window.location.hash) {
|
|
103
|
+
var params = new URLSearchParams(window.location.hash.substring(1));
|
|
104
|
+
var token = params.get('access_token');
|
|
105
|
+
var refresh = params.get('refresh_token');
|
|
106
|
+
if (token) {
|
|
107
|
+
window.location.href = '/callback/token?access_token=' + encodeURIComponent(token) + '&refresh_token=' + encodeURIComponent(refresh || '');
|
|
108
|
+
} else {
|
|
109
|
+
document.body.innerHTML = '<h2>Login failed</h2><p>No token received.</p>';
|
|
110
|
+
}
|
|
111
|
+
} else {
|
|
112
|
+
document.body.innerHTML = '<h2>Login failed</h2><p>Missing authorization data.</p>';
|
|
113
|
+
}
|
|
114
|
+
</script><noscript>Enable JavaScript to complete login.</noscript></body></html>`);
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
server.listen(port, () => {
|
|
118
|
+
// Server ready
|
|
119
|
+
});
|
|
120
|
+
server.on("error", (err) => {
|
|
121
|
+
reject(new Error(`Failed to start callback server: ${err.message}`));
|
|
122
|
+
});
|
|
123
|
+
setTimeout(() => {
|
|
124
|
+
server.close();
|
|
125
|
+
reject(new Error("Login timed out after 120 seconds"));
|
|
126
|
+
}, 120_000);
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
//# sourceMappingURL=auth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/cloud/auth.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { CloudConfig, CloudGene, CloudGeneListResponse, CloudArenaRankings, CloudArenaEntry, FitnessReport } from "./types.js";
|
|
2
|
+
export declare function loadCloudConfig(): CloudConfig;
|
|
3
|
+
export declare function listGenes(options: {
|
|
4
|
+
domain?: string;
|
|
5
|
+
query?: string;
|
|
6
|
+
owner?: string;
|
|
7
|
+
fidelity?: string;
|
|
8
|
+
sort?: string;
|
|
9
|
+
page?: number;
|
|
10
|
+
perPage?: number;
|
|
11
|
+
}): Promise<CloudGeneListResponse>;
|
|
12
|
+
export declare function getGene(id: string): Promise<CloudGene>;
|
|
13
|
+
export declare function publishGene(opts: {
|
|
14
|
+
name: string;
|
|
15
|
+
domain: string;
|
|
16
|
+
version: string;
|
|
17
|
+
fidelity: string;
|
|
18
|
+
description: string;
|
|
19
|
+
phenotype: Record<string, unknown>;
|
|
20
|
+
wasmBytes: Buffer | null;
|
|
21
|
+
}): Promise<CloudGene>;
|
|
22
|
+
export declare function unpublishGene(id: string): Promise<void>;
|
|
23
|
+
export declare function downloadGeneWasm(wasmUrl: string): Promise<Buffer>;
|
|
24
|
+
export declare function arenaSubmit(geneId: string, fitness: FitnessReport): Promise<CloudArenaEntry>;
|
|
25
|
+
export declare function arenaRankings(options: {
|
|
26
|
+
domain?: string;
|
|
27
|
+
page?: number;
|
|
28
|
+
perPage?: number;
|
|
29
|
+
}): Promise<CloudArenaRankings>;
|
|
30
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/cloud/client.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,WAAW,EACX,SAAS,EACT,qBAAqB,EACrB,kBAAkB,EAClB,eAAe,EACf,aAAa,EACd,MAAM,YAAY,CAAC;AASpB,wBAAgB,eAAe,IAAI,WAAW,CAa7C;AAgDD,wBAAsB,SAAS,CAAC,OAAO,EAAE;IACvC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,GAAG,OAAO,CAAC,qBAAqB,CAAC,CA2CjC;AAED,wBAAsB,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC,CAiC5D;AAED,wBAAsB,WAAW,CAAC,IAAI,EAAE;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B,GAAG,OAAO,CAAC,SAAS,CAAC,CA0ErB;AAED,wBAAsB,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAa7D;AAED,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAKvE;AAID,wBAAsB,WAAW,CAC/B,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,aAAa,GACrB,OAAO,CAAC,eAAe,CAAC,CAsC1B;AAED,wBAAsB,aAAa,CAAC,OAAO,EAAE;IAC3C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,GAAG,OAAO,CAAC,kBAAkB,CAAC,CA0C9B"}
|
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.loadCloudConfig = loadCloudConfig;
|
|
4
|
+
exports.listGenes = listGenes;
|
|
5
|
+
exports.getGene = getGene;
|
|
6
|
+
exports.publishGene = publishGene;
|
|
7
|
+
exports.unpublishGene = unpublishGene;
|
|
8
|
+
exports.downloadGeneWasm = downloadGeneWasm;
|
|
9
|
+
exports.arenaSubmit = arenaSubmit;
|
|
10
|
+
exports.arenaRankings = arenaRankings;
|
|
11
|
+
const node_fs_1 = require("node:fs");
|
|
12
|
+
const node_path_1 = require("node:path");
|
|
13
|
+
const types_js_1 = require("./types.js");
|
|
14
|
+
const auth_js_1 = require("./auth.js");
|
|
15
|
+
const ROTIFER_HOME = (0, node_path_1.join)(process.env.HOME || process.env.USERPROFILE || "/tmp", ".rotifer");
|
|
16
|
+
function loadCloudConfig() {
|
|
17
|
+
const configPath = (0, node_path_1.join)(ROTIFER_HOME, types_js_1.CLOUD_CONFIG_FILE);
|
|
18
|
+
if ((0, node_fs_1.existsSync)(configPath)) {
|
|
19
|
+
try {
|
|
20
|
+
return JSON.parse((0, node_fs_1.readFileSync)(configPath, "utf-8"));
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
// fall through to defaults
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
return {
|
|
27
|
+
endpoint: process.env.ROTIFER_CLOUD_ENDPOINT || types_js_1.DEFAULT_CLOUD_ENDPOINT,
|
|
28
|
+
anonKey: process.env.ROTIFER_CLOUD_ANON_KEY || "",
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
function apiUrl(path) {
|
|
32
|
+
const config = loadCloudConfig();
|
|
33
|
+
const base = config.endpoint.replace(/\/+$/, "");
|
|
34
|
+
return `${base}/rest/v1${path}`;
|
|
35
|
+
}
|
|
36
|
+
function storageUrl(path) {
|
|
37
|
+
const config = loadCloudConfig();
|
|
38
|
+
const base = config.endpoint.replace(/\/+$/, "");
|
|
39
|
+
return `${base}/storage/v1${path}`;
|
|
40
|
+
}
|
|
41
|
+
function authHeaders(requireToken = false) {
|
|
42
|
+
const config = loadCloudConfig();
|
|
43
|
+
const headers = {
|
|
44
|
+
"Content-Type": "application/json",
|
|
45
|
+
apikey: config.anonKey,
|
|
46
|
+
};
|
|
47
|
+
const creds = (0, auth_js_1.loadCredentials)();
|
|
48
|
+
if (creds) {
|
|
49
|
+
headers["Authorization"] = `Bearer ${creds.access_token}`;
|
|
50
|
+
}
|
|
51
|
+
else if (requireToken) {
|
|
52
|
+
throw new Error("Not logged in. Run 'rotifer login' first.");
|
|
53
|
+
}
|
|
54
|
+
return headers;
|
|
55
|
+
}
|
|
56
|
+
async function handleResponse(res) {
|
|
57
|
+
if (!res.ok) {
|
|
58
|
+
const body = await res.text();
|
|
59
|
+
let message;
|
|
60
|
+
try {
|
|
61
|
+
const parsed = JSON.parse(body);
|
|
62
|
+
message = parsed.message || parsed.error?.message || body;
|
|
63
|
+
}
|
|
64
|
+
catch {
|
|
65
|
+
message = body;
|
|
66
|
+
}
|
|
67
|
+
throw new Error(`Cloud API error (${res.status}): ${message}`);
|
|
68
|
+
}
|
|
69
|
+
return res.json();
|
|
70
|
+
}
|
|
71
|
+
// --- Gene Registry ---
|
|
72
|
+
async function listGenes(options) {
|
|
73
|
+
const params = new URLSearchParams();
|
|
74
|
+
params.set("published", "eq.true");
|
|
75
|
+
params.set("select", "id,name,domain,version,fidelity,description,wasm_size,downloads,created_at,updated_at,profiles(username)");
|
|
76
|
+
params.set("order", "created_at.desc");
|
|
77
|
+
if (options.domain)
|
|
78
|
+
params.set("domain", `eq.${options.domain}`);
|
|
79
|
+
if (options.fidelity)
|
|
80
|
+
params.set("fidelity", `eq.${options.fidelity}`);
|
|
81
|
+
if (options.query)
|
|
82
|
+
params.set("or", `(name.ilike.*${options.query}*,description.ilike.*${options.query}*)`);
|
|
83
|
+
const limit = options.perPage || 20;
|
|
84
|
+
const offset = ((options.page || 1) - 1) * limit;
|
|
85
|
+
params.set("limit", String(limit));
|
|
86
|
+
params.set("offset", String(offset));
|
|
87
|
+
const res = await fetch(apiUrl(`/genes?${params}`), {
|
|
88
|
+
headers: {
|
|
89
|
+
...authHeaders(),
|
|
90
|
+
Prefer: "count=exact",
|
|
91
|
+
},
|
|
92
|
+
});
|
|
93
|
+
const total = parseInt(res.headers.get("content-range")?.split("/")[1] || "0", 10);
|
|
94
|
+
const data = await handleResponse(res);
|
|
95
|
+
const genes = data.map((row) => ({
|
|
96
|
+
id: row.id,
|
|
97
|
+
name: row.name,
|
|
98
|
+
owner: row.profiles?.username || "unknown",
|
|
99
|
+
domain: row.domain,
|
|
100
|
+
version: row.version,
|
|
101
|
+
fidelity: row.fidelity,
|
|
102
|
+
description: row.description,
|
|
103
|
+
phenotype: {},
|
|
104
|
+
wasm_url: null,
|
|
105
|
+
wasm_size: row.wasm_size || 0,
|
|
106
|
+
downloads: row.downloads || 0,
|
|
107
|
+
fitness: null,
|
|
108
|
+
created_at: row.created_at,
|
|
109
|
+
updated_at: row.updated_at,
|
|
110
|
+
}));
|
|
111
|
+
return { genes, total, page: options.page || 1, per_page: limit };
|
|
112
|
+
}
|
|
113
|
+
async function getGene(id) {
|
|
114
|
+
const params = new URLSearchParams();
|
|
115
|
+
params.set("id", `eq.${id}`);
|
|
116
|
+
params.set("select", "*, profiles(username)");
|
|
117
|
+
const res = await fetch(apiUrl(`/genes?${params}`), {
|
|
118
|
+
headers: authHeaders(),
|
|
119
|
+
});
|
|
120
|
+
const data = await handleResponse(res);
|
|
121
|
+
if (data.length === 0)
|
|
122
|
+
throw new Error(`Gene '${id}' not found`);
|
|
123
|
+
const row = data[0];
|
|
124
|
+
const config = loadCloudConfig();
|
|
125
|
+
const wasmUrl = row.wasm_path
|
|
126
|
+
? `${config.endpoint.replace(/\/+$/, "")}/storage/v1/object/public/gene-wasm/${row.wasm_path}`
|
|
127
|
+
: null;
|
|
128
|
+
return {
|
|
129
|
+
id: row.id,
|
|
130
|
+
name: row.name,
|
|
131
|
+
owner: row.profiles?.username || "unknown",
|
|
132
|
+
domain: row.domain,
|
|
133
|
+
version: row.version,
|
|
134
|
+
fidelity: row.fidelity,
|
|
135
|
+
description: row.description,
|
|
136
|
+
phenotype: row.phenotype || {},
|
|
137
|
+
wasm_url: wasmUrl,
|
|
138
|
+
wasm_size: row.wasm_size || 0,
|
|
139
|
+
downloads: row.downloads || 0,
|
|
140
|
+
fitness: null,
|
|
141
|
+
created_at: row.created_at,
|
|
142
|
+
updated_at: row.updated_at,
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
async function publishGene(opts) {
|
|
146
|
+
const creds = (0, auth_js_1.loadCredentials)();
|
|
147
|
+
if (!creds)
|
|
148
|
+
throw new Error("Not logged in. Run 'rotifer login' first.");
|
|
149
|
+
let wasmPath = null;
|
|
150
|
+
let wasmSize = 0;
|
|
151
|
+
if (opts.wasmBytes) {
|
|
152
|
+
wasmPath = `${creds.user.id}/${opts.name}/${opts.version}/gene.ir.wasm`;
|
|
153
|
+
wasmSize = opts.wasmBytes.length;
|
|
154
|
+
const uploadRes = await fetch(storageUrl(`/object/gene-wasm/${wasmPath}`), {
|
|
155
|
+
method: "POST",
|
|
156
|
+
headers: {
|
|
157
|
+
Authorization: `Bearer ${creds.access_token}`,
|
|
158
|
+
apikey: loadCloudConfig().anonKey,
|
|
159
|
+
"Content-Type": "application/wasm",
|
|
160
|
+
"x-upsert": "true",
|
|
161
|
+
},
|
|
162
|
+
body: new Uint8Array(opts.wasmBytes),
|
|
163
|
+
});
|
|
164
|
+
if (!uploadRes.ok) {
|
|
165
|
+
const err = await uploadRes.text();
|
|
166
|
+
throw new Error(`Failed to upload WASM: ${err}`);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
const body = {
|
|
170
|
+
owner_id: creds.user.id,
|
|
171
|
+
name: opts.name,
|
|
172
|
+
domain: opts.domain,
|
|
173
|
+
version: opts.version,
|
|
174
|
+
fidelity: opts.fidelity,
|
|
175
|
+
description: opts.description,
|
|
176
|
+
phenotype: opts.phenotype,
|
|
177
|
+
wasm_path: wasmPath,
|
|
178
|
+
wasm_size: wasmSize,
|
|
179
|
+
published: true,
|
|
180
|
+
};
|
|
181
|
+
const res = await fetch(apiUrl("/genes"), {
|
|
182
|
+
method: "POST",
|
|
183
|
+
headers: {
|
|
184
|
+
...authHeaders(true),
|
|
185
|
+
Prefer: "return=representation",
|
|
186
|
+
},
|
|
187
|
+
body: JSON.stringify(body),
|
|
188
|
+
});
|
|
189
|
+
const data = await handleResponse(res);
|
|
190
|
+
const row = data[0];
|
|
191
|
+
return {
|
|
192
|
+
id: row.id,
|
|
193
|
+
name: row.name,
|
|
194
|
+
owner: creds.user.username,
|
|
195
|
+
domain: row.domain,
|
|
196
|
+
version: row.version,
|
|
197
|
+
fidelity: row.fidelity,
|
|
198
|
+
description: row.description,
|
|
199
|
+
phenotype: row.phenotype,
|
|
200
|
+
wasm_url: wasmPath
|
|
201
|
+
? `${loadCloudConfig().endpoint}/storage/v1/object/public/gene-wasm/${wasmPath}`
|
|
202
|
+
: null,
|
|
203
|
+
wasm_size: row.wasm_size,
|
|
204
|
+
downloads: 0,
|
|
205
|
+
fitness: null,
|
|
206
|
+
created_at: row.created_at,
|
|
207
|
+
updated_at: row.updated_at,
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
async function unpublishGene(id) {
|
|
211
|
+
const res = await fetch(apiUrl(`/genes?id=eq.${id}`), {
|
|
212
|
+
method: "PATCH",
|
|
213
|
+
headers: {
|
|
214
|
+
...authHeaders(true),
|
|
215
|
+
Prefer: "return=minimal",
|
|
216
|
+
},
|
|
217
|
+
body: JSON.stringify({ published: false }),
|
|
218
|
+
});
|
|
219
|
+
if (!res.ok) {
|
|
220
|
+
const err = await res.text();
|
|
221
|
+
throw new Error(`Failed to unpublish gene: ${err}`);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
async function downloadGeneWasm(wasmUrl) {
|
|
225
|
+
const res = await fetch(wasmUrl);
|
|
226
|
+
if (!res.ok)
|
|
227
|
+
throw new Error(`Failed to download WASM (${res.status})`);
|
|
228
|
+
const arrayBuf = await res.arrayBuffer();
|
|
229
|
+
return Buffer.from(arrayBuf);
|
|
230
|
+
}
|
|
231
|
+
// --- Cloud Arena ---
|
|
232
|
+
async function arenaSubmit(geneId, fitness) {
|
|
233
|
+
const gene = await getGene(geneId);
|
|
234
|
+
const body = {
|
|
235
|
+
gene_id: geneId,
|
|
236
|
+
domain: gene.domain,
|
|
237
|
+
fitness_value: fitness.value,
|
|
238
|
+
safety_score: fitness.safety_score,
|
|
239
|
+
success_rate: fitness.success_rate,
|
|
240
|
+
latency_score: fitness.latency_score,
|
|
241
|
+
resource_efficiency: fitness.resource_efficiency,
|
|
242
|
+
total_calls: 1,
|
|
243
|
+
};
|
|
244
|
+
const res = await fetch(apiUrl("/arena_entries"), {
|
|
245
|
+
method: "POST",
|
|
246
|
+
headers: {
|
|
247
|
+
...authHeaders(true),
|
|
248
|
+
Prefer: "return=representation,resolution=merge-duplicates",
|
|
249
|
+
},
|
|
250
|
+
body: JSON.stringify(body),
|
|
251
|
+
});
|
|
252
|
+
const data = await handleResponse(res);
|
|
253
|
+
const row = data[0];
|
|
254
|
+
return {
|
|
255
|
+
rank: 0,
|
|
256
|
+
gene_id: row.gene_id,
|
|
257
|
+
gene_name: gene.name,
|
|
258
|
+
owner: gene.owner,
|
|
259
|
+
domain: row.domain,
|
|
260
|
+
fidelity: gene.fidelity,
|
|
261
|
+
fitness: row.fitness_value,
|
|
262
|
+
safety: row.safety_score,
|
|
263
|
+
total_calls: row.total_calls,
|
|
264
|
+
last_evaluated: row.last_evaluated,
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
async function arenaRankings(options) {
|
|
268
|
+
const params = new URLSearchParams();
|
|
269
|
+
params.set("select", "fitness_value,safety_score,total_calls,last_evaluated,domain,genes(id,name,fidelity,profiles(username))");
|
|
270
|
+
params.set("order", "fitness_value.desc");
|
|
271
|
+
if (options.domain)
|
|
272
|
+
params.set("domain", `eq.${options.domain}`);
|
|
273
|
+
const limit = options.perPage || 50;
|
|
274
|
+
const offset = ((options.page || 1) - 1) * limit;
|
|
275
|
+
params.set("limit", String(limit));
|
|
276
|
+
params.set("offset", String(offset));
|
|
277
|
+
const res = await fetch(apiUrl(`/arena_entries?${params}`), {
|
|
278
|
+
headers: {
|
|
279
|
+
...authHeaders(),
|
|
280
|
+
Prefer: "count=exact",
|
|
281
|
+
},
|
|
282
|
+
});
|
|
283
|
+
const total = parseInt(res.headers.get("content-range")?.split("/")[1] || "0", 10);
|
|
284
|
+
const data = await handleResponse(res);
|
|
285
|
+
const rankings = data.map((row, i) => ({
|
|
286
|
+
rank: offset + i + 1,
|
|
287
|
+
gene_id: row.genes?.id || "",
|
|
288
|
+
gene_name: row.genes?.name || "unknown",
|
|
289
|
+
owner: row.genes?.profiles?.username || "unknown",
|
|
290
|
+
domain: row.domain,
|
|
291
|
+
fidelity: row.genes?.fidelity || "Wrapped",
|
|
292
|
+
fitness: row.fitness_value,
|
|
293
|
+
safety: row.safety_score,
|
|
294
|
+
total_calls: row.total_calls || 0,
|
|
295
|
+
last_evaluated: row.last_evaluated,
|
|
296
|
+
}));
|
|
297
|
+
return { rankings, total, domain: options.domain || null };
|
|
298
|
+
}
|
|
299
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/cloud/client.ts"],"names":[],"mappings":"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"}
|