@rotifer/playground 0.2.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.
Files changed (59) hide show
  1. package/CHANGELOG.md +62 -0
  2. package/README.md +38 -17
  3. package/README.zh.md +26 -13
  4. package/dist/cloud/auth.d.ts +14 -0
  5. package/dist/cloud/auth.d.ts.map +1 -0
  6. package/dist/cloud/auth.js +129 -0
  7. package/dist/cloud/auth.js.map +1 -0
  8. package/dist/cloud/client.d.ts +30 -0
  9. package/dist/cloud/client.d.ts.map +1 -0
  10. package/dist/cloud/client.js +299 -0
  11. package/dist/cloud/client.js.map +1 -0
  12. package/dist/cloud/index.d.ts +4 -0
  13. package/dist/cloud/index.d.ts.map +1 -0
  14. package/dist/cloud/index.js +20 -0
  15. package/dist/cloud/index.js.map +1 -0
  16. package/dist/cloud/types.d.ts +73 -0
  17. package/dist/cloud/types.d.ts.map +1 -0
  18. package/dist/cloud/types.js +7 -0
  19. package/dist/cloud/types.js.map +1 -0
  20. package/dist/commands/arena-list.d.ts.map +1 -1
  21. package/dist/commands/arena-list.js +51 -1
  22. package/dist/commands/arena-list.js.map +1 -1
  23. package/dist/commands/arena-submit.d.ts.map +1 -1
  24. package/dist/commands/arena-submit.js +35 -1
  25. package/dist/commands/arena-submit.js.map +1 -1
  26. package/dist/commands/arena-watch.d.ts.map +1 -1
  27. package/dist/commands/arena-watch.js +96 -2
  28. package/dist/commands/arena-watch.js.map +1 -1
  29. package/dist/commands/compile.d.ts.map +1 -1
  30. package/dist/commands/compile.js +28 -7
  31. package/dist/commands/compile.js.map +1 -1
  32. package/dist/commands/install.d.ts +3 -0
  33. package/dist/commands/install.d.ts.map +1 -0
  34. package/dist/commands/install.js +94 -0
  35. package/dist/commands/install.js.map +1 -0
  36. package/dist/commands/login.d.ts +3 -0
  37. package/dist/commands/login.d.ts.map +1 -0
  38. package/dist/commands/login.js +133 -0
  39. package/dist/commands/login.js.map +1 -0
  40. package/dist/commands/logout.d.ts +3 -0
  41. package/dist/commands/logout.d.ts.map +1 -0
  42. package/dist/commands/logout.js +53 -0
  43. package/dist/commands/logout.js.map +1 -0
  44. package/dist/commands/publish.d.ts +3 -0
  45. package/dist/commands/publish.d.ts.map +1 -0
  46. package/dist/commands/publish.js +121 -0
  47. package/dist/commands/publish.js.map +1 -0
  48. package/dist/commands/search.d.ts +3 -0
  49. package/dist/commands/search.d.ts.map +1 -0
  50. package/dist/commands/search.js +106 -0
  51. package/dist/commands/search.js.map +1 -0
  52. package/dist/index.js +11 -1
  53. package/dist/index.js.map +1 -1
  54. package/dist/utils/javy-compiler.d.ts +22 -0
  55. package/dist/utils/javy-compiler.d.ts.map +1 -0
  56. package/dist/utils/javy-compiler.js +118 -0
  57. package/dist/utils/javy-compiler.js.map +1 -0
  58. package/genes/genesis-web-search/.cloud-manifest.json +6 -0
  59. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -5,6 +5,68 @@ 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
+
44
+ ## [0.3.0-alpha.1] - 2026-02-17
45
+
46
+ ### Added
47
+
48
+ - **TS→WASM Auto-Compilation** (Javy / QuickJS)
49
+ - `rotifer compile` auto-detects `index.ts`/`index.js` and compiles to Native WASM
50
+ - Pipeline: TypeScript → esbuild (bundle) → WASI shim → Javy (QuickJS→WASM) → Rotifer IR
51
+ - New `--lang <ts|wasm>` option to force compilation mode
52
+ - `javy-compiler.ts` utility with `compileTypeScriptToWasm()`, `isJavyAvailable()`, `findGeneSource()`
53
+
54
+ - **WASI Sandbox Support** (`rotifer-core::sandbox`)
55
+ - `WasmtimeSandbox` now supports both Direct (`express`) and WASI (`_start`) execution modes
56
+ - Minimal WASI shim: 9 host functions (`fd_read`, `fd_write`, `clock_time_get`, etc.)
57
+ - Auto-detection of WASI vs Direct modules at runtime
58
+
59
+ - **IR Verifier Updates**
60
+ - SIMD instructions downgraded from error to warning (common in Javy/QuickJS output)
61
+ - `_start` entry point accepted alongside `express` for WASI modules
62
+
63
+ ### Changed
64
+
65
+ - Test coverage: 180 → 275 tests (91 TypeScript + 184 Rust)
66
+ - Documentation updated across README (EN/ZH), Getting Started (EN/ZH), and website
67
+
68
+ [0.3.0-alpha.1]: https://github.com/rotifer-protocol/rotifer-playground/releases/tag/v0.3.0-alpha.1
69
+
8
70
  ## [0.2.0-alpha.1] - 2026-02-22
9
71
 
10
72
  ### Added
package/README.md CHANGED
@@ -5,10 +5,11 @@
5
5
  [![License: Apache-2.0](https://img.shields.io/badge/License-Apache--2.0-blue.svg)](LICENSE)
6
6
  [![Node.js](https://img.shields.io/badge/node-%3E%3D20.0.0-brightgreen)](https://nodejs.org/)
7
7
  [![Protocol](https://img.shields.io/badge/Protocol-v2.9%20Frozen-orange)](https://github.com/rotifer-protocol/rotifer-spec)
8
+ [![Discord](https://img.shields.io/discord/placeholder?label=Discord&logo=discord&color=5865F2)](https://discord.gg/6d4JrfMr)
8
9
 
9
- Local development environment for the **Rotifer Protocol** — build genes, run Arena competitions, and simulate agent evolution.
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.2.0-alpha.1). Core gene lifecycle, IR compiler pipeline, parallel algebra, and live Arena watching are functional.
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
 
@@ -82,13 +83,18 @@ Your existing code becomes a gene and competes in the Arena.
82
83
 
83
84
  ### Act 3 — Hooked (30 minutes)
84
85
 
85
- Write a native gene, compile it, submit to Arena, and create an Agent:
86
+ Write a TypeScript gene and compile it to Native WASM automatically:
86
87
 
87
88
  ```bash
88
- # Write a native gene (higher fidelity = higher fitness potential)
89
- mkdir genes/my-search && vim genes/my-search/index.ts
90
-
91
- rotifer compile my-search # Validate Phenotype + fingerprint
89
+ # Write a gene in TypeScript same language, zero learning curve
90
+ mkdir genes/my-search && cat > genes/my-search/index.ts << 'EOF'
91
+ export function express(input: { query: string }) {
92
+ return { results: [`Found: ${input.query}`], total: 1 };
93
+ }
94
+ EOF
95
+
96
+ rotifer wrap my-search --domain search
97
+ rotifer compile my-search # TS → JS → WASM (Javy) → Rotifer IR
92
98
  rotifer arena submit my-search # Watch it climb the rankings
93
99
  rotifer arena list --domain search # Compare against Genesis genes
94
100
 
@@ -100,6 +106,8 @@ rotifer agent list
100
106
  rotifer agent run search-bot --input '{"query":"rotifer protocol"}'
101
107
  ```
102
108
 
109
+ **v0.3 highlight:** `rotifer compile` auto-detects TypeScript genes and compiles them to Native WASM via [Javy](https://github.com/bytecodealliance/javy) (QuickJS→WASM). No separate toolchain required.
110
+
103
111
  ---
104
112
 
105
113
  ## Architecture
@@ -110,12 +118,14 @@ playground/
110
118
  │ ├── rotifer-core/ Rust: types, sandbox, arena, algebra, fitness, storage
111
119
  │ └── rotifer-napi/ napi-rs bridge: Rust ↔ Node.js FFI
112
120
  ├── src/ TypeScript CLI (commander.js)
113
- │ ├── commands/ 11 CLI commands
114
- │ ├── utils/ Config, display, NAPI binding loader
121
+ │ ├── commands/ 16 CLI commands
122
+ │ ├── cloud/ Cloud Binding client (auth, API, types)
123
+ │ ├── utils/ Config, display, NAPI binding, Javy compiler
115
124
  │ └── errors/ Rust-style error formatting
116
125
  ├── genes/ 5 Genesis genes (bundled)
126
+ ├── supabase/ Cloud Binding database migrations
117
127
  ├── templates/ Gene + composition scaffolds
118
- └── tests/ Unit + E2E test suites (79 tests)
128
+ └── tests/ Unit + E2E test suites (114 tests)
119
129
  ```
120
130
 
121
131
  ### Layers
@@ -124,7 +134,7 @@ playground/
124
134
  |-------|-----------|----------------|
125
135
  | **CLI** | TypeScript + commander.js | User interface, command routing, display |
126
136
  | **Bridge** | napi-rs (cdylib) | Rust-to-Node.js FFI binding |
127
- | **Core** | Rust + wasmtime | WASM sandbox, Arena engine, Algebra executor, Fitness computation, SQLite storage |
137
+ | **Core** | Rust + wasmtime | WASM sandbox (Direct + WASI), Arena engine, Algebra executor, Fitness computation, SQLite storage |
128
138
 
129
139
  ---
130
140
 
@@ -136,10 +146,15 @@ playground/
136
146
  | `rotifer scan [path]` | Scan source files for candidate gene functions |
137
147
  | `rotifer wrap <name>` | Wrap a function as a Rotifer gene |
138
148
  | `rotifer test [name]` | Test a gene in L2 sandbox |
139
- | `rotifer compile [name]` | Compile a gene (validate + fingerprint) |
140
- | `rotifer arena submit <name>` | Submit a gene to the Arena |
141
- | `rotifer arena list` | List Arena rankings |
142
- | `rotifer arena watch <domain>` | Watch Arena rankings (MVP: placeholder) |
149
+ | `rotifer compile [name]` | Compile gene to Rotifer IR (auto TS→WASM via Javy) |
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 |
143
158
  | `rotifer agent create <name>` | Create an Agent with a genome |
144
159
  | `rotifer agent list` | List all agents |
145
160
  | `rotifer agent run <name>` | Execute an agent's genome pipeline |
@@ -185,7 +200,7 @@ cd playground
185
200
  # TypeScript CLI
186
201
  npm install
187
202
  npm run build # Build to dist/
188
- npm test # Run 79 TypeScript tests
203
+ npm test # Run 114 TypeScript tests
189
204
  npm run lint # Type check only
190
205
 
191
206
  # Rust Core (requires Rust toolchain)
@@ -216,11 +231,17 @@ Changes driven by implementation feedback are proposed through the ADR process.
216
231
 
217
232
  - [x] **v0.1.0-alpha.1** — Core CLI + Genesis genes + Arena
218
233
  - [x] **v0.2.0-alpha.1** — IR compiler pipeline, live Arena watching, NAPI bridge, end-to-end demo loop
219
- - [ ] **v0.3.0** — Frontend SDK (TS→WASM via AssemblyScript/Javy), Cloud Binding
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
220
236
  - [ ] **v1.0.0** — Full protocol compliance, multi-binding support, P2P HLT
221
237
 
222
238
  ---
223
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
+
224
245
  ## Contributing
225
246
 
226
247
  See [CONTRIBUTING.md](CONTRIBUTING.md) for development setup and guidelines.
package/README.zh.md CHANGED
@@ -5,10 +5,11 @@
5
5
  [![License: Apache-2.0](https://img.shields.io/badge/License-Apache--2.0-blue.svg)](LICENSE)
6
6
  [![Node.js](https://img.shields.io/badge/node-%3E%3D20.0.0-brightgreen)](https://nodejs.org/)
7
7
  [![Protocol](https://img.shields.io/badge/Protocol-v2.9%20Frozen-orange)](https://github.com/rotifer-protocol/rotifer-spec)
8
+ [![Discord](https://img.shields.io/discord/placeholder?label=Discord&logo=discord&color=5865F2)](https://discord.gg/6d4JrfMr)
8
9
 
9
- **Rotifer Protocol** 的本地开发环境——构建基因、运行 Arena 竞争、模拟代理进化。
10
+ **Rotifer Protocol** 的开发环境——构建基因、运行 Arena 竞争、通过 Cloud 共享、模拟代理进化。
10
11
 
11
- > **状态:** Alpha (v0.2.0-alpha.1)。核心基因生命周期、IR 编译器管线、并行代数、实时 Arena 观察已可用。
12
+ > **状态:** Alpha (v0.4.0-alpha.1)。核心基因生命周期、IR 编译器管线、并行代数、**TS→WASM 自动编译 (Javy)**、**Cloud Binding(发布/搜索/安装)**、实时 Arena 观察已可用。
12
13
 
13
14
  ---
14
15
 
@@ -82,13 +83,18 @@ rotifer arena list # 查看你的基因排名
82
83
 
83
84
  ### 第三幕——Hooked(30 分钟)
84
85
 
85
- 编写原生基因、编译、提交到 Arena,并创建 Agent
86
+ TypeScript 编写基因,自动编译为原生 WASM
86
87
 
87
88
  ```bash
88
- # 编写原生基因(更高的保真度 = 更高的适应度潜力)
89
- mkdir genes/my-search && vim genes/my-search/index.ts
90
-
91
- rotifer compile my-search # 验证 Phenotype + 生成指纹
89
+ # TypeScript 写基因——同一语言,零学习成本
90
+ mkdir genes/my-search && cat > genes/my-search/index.ts << 'EOF'
91
+ export function express(input: { query: string }) {
92
+ return { results: [`Found: ${input.query}`], total: 1 };
93
+ }
94
+ EOF
95
+
96
+ rotifer wrap my-search --domain search
97
+ rotifer compile my-search # TS → JS → WASM (Javy) → Rotifer IR
92
98
  rotifer arena submit my-search # 观察它攀升排名
93
99
  rotifer arena list --domain search # 与 Genesis 基因对比
94
100
 
@@ -100,6 +106,8 @@ rotifer agent list
100
106
  rotifer agent run search-bot --input '{"query":"rotifer protocol"}'
101
107
  ```
102
108
 
109
+ **v0.3 亮点:** `rotifer compile` 自动检测 TypeScript 基因,通过 [Javy](https://github.com/bytecodealliance/javy)(QuickJS→WASM)编译为原生 WASM,无需额外工具链。
110
+
103
111
  ---
104
112
 
105
113
  ## 架构
@@ -111,11 +119,11 @@ playground/
111
119
  │ └── rotifer-napi/ napi-rs 桥接: Rust ↔ Node.js FFI
112
120
  ├── src/ TypeScript CLI (commander.js)
113
121
  │ ├── commands/ 11 个 CLI 命令
114
- │ ├── utils/ 配置、显示、NAPI 绑定加载器
122
+ │ ├── utils/ 配置、显示、NAPI 绑定、Javy 编译器
115
123
  │ └── errors/ Rust 风格的错误格式化
116
124
  ├── genes/ 5 个 Genesis 基因(内置)
117
125
  ├── templates/ 基因 + 组合脚手架模板
118
- └── tests/ 单元测试 + E2E 测试(79 个测试)
126
+ └── tests/ 单元测试 + E2E 测试(91 个测试)
119
127
  ```
120
128
 
121
129
  ### 分层
@@ -124,7 +132,7 @@ playground/
124
132
  |----|--------|------|
125
133
  | **CLI** | TypeScript + commander.js | 用户界面、命令路由、显示 |
126
134
  | **Bridge** | napi-rs (cdylib) | Rust 到 Node.js 的 FFI 绑定 |
127
- | **Core** | Rust + wasmtime | WASM 沙箱、Arena 引擎、Algebra 执行器、Fitness 计算、SQLite 存储 |
135
+ | **Core** | Rust + wasmtime | WASM 沙箱(Direct + WASI)、Arena 引擎、Algebra 执行器、Fitness 计算、SQLite 存储 |
128
136
 
129
137
  ---
130
138
 
@@ -136,7 +144,7 @@ playground/
136
144
  | `rotifer scan [path]` | 扫描源文件中的候选基因函数 |
137
145
  | `rotifer wrap <name>` | 将函数包装为 Rotifer 基因 |
138
146
  | `rotifer test [name]` | 在 L2 沙箱中测试基因 |
139
- | `rotifer compile [name]` | 编译基因(验证 + 生成指纹) |
147
+ | `rotifer compile [name]` | 编译基因为 Rotifer IR(自动 TS→WASM via Javy) |
140
148
  | `rotifer arena submit <name>` | 将基因提交到 Arena |
141
149
  | `rotifer arena list` | 列出 Arena 排名 |
142
150
  | `rotifer arena watch <domain>` | 观察 Arena 排名(MVP:占位符) |
@@ -185,7 +193,7 @@ cd playground
185
193
  # TypeScript CLI
186
194
  npm install
187
195
  npm run build # 构建到 dist/
188
- npm test # 运行 79 个 TypeScript 测试
196
+ npm test # 运行 91 个 TypeScript 测试
189
197
  npm run lint # 仅类型检查
190
198
 
191
199
  # Rust Core(需要 Rust 工具链)
@@ -216,11 +224,16 @@ bash demo.sh
216
224
 
217
225
  - [x] **v0.1.0-alpha.1** — 核心 CLI + Genesis 基因 + Arena
218
226
  - [x] **v0.2.0-alpha.1** — IR 编译器管线、实时 Arena 观察、NAPI 桥接、端到端演示闭环
219
- - [ ] **v0.3.0** — 前端 SDKTS→WASM via AssemblyScript/Javy)、Cloud Binding
227
+ - [x] **v0.3.0-alpha.1** — 前端 SDKTS→WASM 自动编译 via Javy、WASI 沙箱支持
220
228
  - [ ] **v1.0.0** — 完整协议合规、多绑定支持、P2P HLT
221
229
 
222
230
  ---
223
231
 
232
+ ## 社区
233
+
234
+ - [Discord](https://discord.gg/6d4JrfMr) — 加入讨论
235
+ - [GitHub Discussions](https://github.com/rotifer-protocol/rotifer-playground/discussions) — 问题与提案
236
+
224
237
  ## 参与贡献
225
238
 
226
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"}