Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions cloud/TASKS.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
- No new runtime dependencies yet (those come in C2).

### C2 — Add Ed25519 verification with `@noble/ed25519`
- [ ] **Goal:** `verify.ts` exports `verifyLicense(token: string): LicensePayload | null` per `CONTRACT.md` §1.3.
- [x] **Goal:** `verify.ts` exports `verifyLicense(token: string): LicensePayload | null` per `CONTRACT.md` §1.3.
- **Files:** `src/services/luminaCloud/verify.ts`, `src/services/luminaCloud/verify.test.ts`, `src/services/luminaCloud/canonical-json.ts` + test.
- **Public key:** `PUBLIC_KEY.ts` exports a `PUBLIC_KEY_B64` placeholder constant. Real value will be filled in by Lead from `lumina-cloud` keypair generation. Mark with `// LEAD: replace with real public key from lumina-cloud T3 output`.
- **Acceptance:**
Expand All @@ -47,7 +47,7 @@
- **[BLOCKED: must NOT touch existing electron entry beyond a single named import]** — if the existing electron main is structured such that adding the new IPC handler requires non-additive edits, block and ask Lead.

### C4 — Zustand store `useLicenseStore`
- [ ] **Goal:** `src/stores/useLicenseStore.ts` with: `license: string | null`, `payload: LicensePayload | null`, `status: 'idle' | 'loading' | 'valid' | 'invalid'`, actions `setLicense(token)`, `clearLicense()`, `refreshFromKeychain()`.
- [x] **Goal:** `src/stores/useLicenseStore.ts` with: `license: string | null`, `payload: LicensePayload | null`, `status: 'idle' | 'loading' | 'valid' | 'invalid'`, actions `setLicense(token)`, `clearLicense()`, `refreshFromKeychain()`.
- **Acceptance:**
- `setLicense` calls `verifyLicense` and updates `payload`/`status` accordingly.
- Hydrates from keychain on app start (calls `refreshFromKeychain` once).
Expand Down Expand Up @@ -94,7 +94,7 @@
- **Acceptance:** Tests cover the three status states. Component renders without throwing in jsdom.

### C9 — `CloudUsagePanel.tsx`
- [ ] **Goal:** Show "X / Y tokens used this month, resets on …".
- [x] **Goal:** Show "X / Y tokens used this month, resets on …".
- **Files:** `src/components/settings/CloudUsagePanel.tsx` + test.
- **Behavior:**
- When license valid: fetch `client.getUsage()` on mount + every 60s while open.
Expand Down Expand Up @@ -128,4 +128,7 @@
(Loop agent appends `[x] C<n> — <date> — <commit hash> — <one-line note>` here as tasks complete, mirroring the `[x]` above.)

[x] C1 — 2026-04-28 — ba66b60 — scaffolded `src/services/luminaCloud/` (types + stubs); typecheck passes; no new runtime deps
[x] C2 — 2026-04-28 — 3127814 — Ed25519 verifyLicense + JCS canonical-json + 24 tests; deps @noble/ed25519 ^3.1.0, @noble/hashes ^2.2.0
[x] C4 — 2026-04-28 — 3144bd5 — useLicenseStore (zustand) with mocked luminaCloud; 9 tests cover all four status transitions
[x] C5 — 2026-04-28 — 0d7eb75 — typed HTTP client + LuminaCloudError; 21 tests; no new runtime deps (manual fetch mock)
[x] C9 — 2026-04-28 — ae19918 — CloudUsagePanel with 60s polling and stale-cache-on-error; 7 tests cover loading/success/error-with-cache + cold error + cadence + cleanup
Loading