diff --git a/README.md b/README.md index c04a49a..7b62b96 100644 --- a/README.md +++ b/README.md @@ -55,9 +55,41 @@ The downloaded browser is stored in `~/.dataconnect/browsers/` and persists acro npm install # Run in development mode -npm run tauri dev +npm run tauri:dev ``` +### Connector lifecycle (important) + +Connector files have two locations in dev: + +- Repo source: `./connectors/` +- User runtime copy: `~/.dataconnect/connectors/` + +How they get there: + +- `npm install` runs `postinstall` -> `node scripts/fetch-connectors.js` + - This can download/regenerate connector files into `./connectors/`. +- `npm run tauri:dev` runs `node scripts/sync-connectors-dev.js` first + - This copies repo connectors into `~/.dataconnect/connectors/`. + +Key point: + +- `tauri:dev` syncs what already exists in `./connectors/`. +- It does not fetch missing repo connectors by itself. + +If you deleted connector folders and need to recover: + +```bash +node scripts/fetch-connectors.js +node scripts/sync-connectors-dev.js +npm run tauri:dev +``` + +Optional environment flags: + +- `SKIP_CONNECTOR_FETCH=1` -> skip connector download in `postinstall`. +- `CONNECTORS_PATH=/path/to/local/connectors` -> skip remote fetch and use local connector source. + ### Agent config files This repo keeps both `AGENTS.md` and `CLAUDE.md`: Claude Code auto‑loads `CLAUDE.md` but not `AGENTS.md`, and Cursor does the opposite. Keep them aligned. diff --git a/docs/260219-figma-macos-icon-setup.md b/docs/260219-figma-macos-icon-setup.md new file mode 100644 index 0000000..d5d7363 --- /dev/null +++ b/docs/260219-figma-macos-icon-setup.md @@ -0,0 +1,135 @@ +# Figma Setup for Tori macOS App Icon + +This is the exact Figma setup for creating a macOS icon master that looks right in Dock/Finder and works with the current Tauri icon pipeline. + +## Scope + +- App: Tori (DataConnect repo) +- Build pipeline: `src-tauri/icons/*` generated via `tauri icon` +- Goal: produce a high-quality macOS icon master (not a generic square export) + +## Base Frame Recipe (Exact Values) + +Create a Figma frame and enclosure with these exact values: + +- Frame size: `1024 x 1024` +- Frame background: transparent +- Enclosure shape: rounded rectangle +- Enclosure size: `824 x 824` +- Enclosure position: centered (`X: 100`, `Y: 100`) +- Corner radius: `185.4` +- Corner smoothing: `100%` (continuous/squircle-like corner) + +## Required Layer Structure + +Use this layer order so handoff is consistent: + +1. `icon/base-shadow` +2. `icon/enclosure` +3. `icon/glyph` (or grouped artwork) +4. `icon/highlight` (optional polish) +5. `icon/export-mask` (optional helper, hidden at export) + +## Recommended Styling + +### Enclosure + +- Fill: your brand gradient or solid fill +- Keep strong contrast at edges (Dock icons get viewed very small) + +### Shadow (on enclosure) + +- Effect type: Drop shadow +- `X: 0` +- `Y: 12` +- Blur: `28` +- Spread: `0` +- Color: `#000000` at `50%` opacity + +## Glyph/Artwork Placement Rules + +- Keep all important detail inside the `824 x 824` enclosure +- Do not place critical edges right on the boundary +- Maintain visual breathing room so 32px and 16px renders still read +- Avoid tiny strokes and small text (they collapse at app icon sizes) + +## Polish Pass (Recommended) + +These are optional but usually improve final quality a lot. + +### 1) Subtle inner highlight + +- Add an inside stroke on the enclosure: + - Width: `1 px` + - Color: white at `10-18%` + - Blend: normal + +This gives the enclosure a cleaner edge without looking glossy. + +### 2) Size-legibility check + +In Figma, preview/export and sanity-check icon readability at: + +- `128 x 128` +- `64 x 64` +- `32 x 32` +- `16 x 16` + +If the mark gets muddy, simplify the glyph before export. + +### 3) Optical centering + +If the icon looks low/heavy in Dock previews, nudge glyph up by 2-6 px (optical, not geometric centering). + +## Export + Tauri Pipeline + +1. Export flattened PNG from Figma: + - Size: `1024 x 1024` + - Transparent background +2. Generate Tauri icon set from repo root: + - `npm run tauri icon /absolute/path/to/tori-icon-1024.png` +3. This updates `src-tauri/icons/` including: + - `icon.icns` (macOS) + - `icon.ico` (Windows) + - `32x32.png`, `128x128.png`, `128x128@2x.png`, `icon.png` +4. Build and validate: + - `npm run tauri:build` + - Open built `.app` and confirm Dock/Finder appearance + +## macOS Behavior Notes + +- For this native macOS app flow, do not assume automatic iOS-style corner masking. +- Treat `icon.icns` as final mac presentation; shape and visual balance should be designed in artwork. + +## Scalable Formula (If You Change Artboard Size) + +For artboard size `S`: + +- Enclosure size: `0.8046875 * S` +- Gutter per side: `0.09765625 * S` +- Corner radius: `0.1810546875 * S` +- Shadow Y: `0.01171875 * S` +- Shadow blur: `0.02734375 * S` + +## Quick Handoff Checklist + +- [ ] Frame is `1024 x 1024` transparent +- [ ] Enclosure is `824 x 824` centered +- [ ] Corner radius is `185.4`, smoothing `100%` +- [ ] Shadow matches `0 / 12 / 28 / 0 / 50% black` +- [ ] Glyph is legible at `32` and `16` +- [ ] Exported `1024` transparent PNG +- [ ] Ran `npm run tauri icon ...` +- [ ] Verified Dock/Finder icon from built app + +## Output + +- `npm run tauri icon ./public/data_connect_1024_1x.png` + - Generates/replaces app icon assets in `src-tauri/icons/` from your source PNG (`icon.icns`, `icon.ico`, and PNG size variants). This does not build installers; it only refreshes icon files. +- `npm run tauri:build` + - Runs the production build flow: builds frontend + sidecar binaries, builds the Tauri app bundle, injects required runtime files, and creates release artifacts (including `.app`/`.dmg` on macOS). + +## References + +- Tauri icons docs: +- Apple discussion on macOS icon shape behavior: diff --git a/docs/260219-grant-retryable-errors-plan.md b/docs/260219-grant-retryable-errors-plan.md new file mode 100644 index 0000000..1684520 --- /dev/null +++ b/docs/260219-grant-retryable-errors-plan.md @@ -0,0 +1,49 @@ +# Grant Retryable Errors Plan + +## Goal + +Show `Try Again` only for retryable grant failures. For non-retryable failures, show only `Return home`. + +## Scope + +- `src/pages/grant/types.ts` +- `src/pages/grant/use-grant-flow.ts` +- `src/pages/grant/index.tsx` +- `src/pages/grant/components/grant-error-state.tsx` +- `src/pages/grant/use-grant-flow.test.tsx` +- `src/pages/grant/index.test.tsx` + +## Implementation + +1. Add `retryable?: boolean` to `GrantFlowState` (error state metadata). +2. At each `status: "error"` write in `use-grant-flow.ts`, set `retryable`. +3. Pass `retryable` from `Grant` page into `GrantErrorState`. +4. Gate error CTAs in `GrantErrorState`: + - `retryable === true` -> show `Try Again` + `Return home` + - otherwise -> show only `Return home` + +## Retryability Rules + +- `retryable: false` + - missing session ID / secret + - session expired + - builder verification hard fail +- `retryable: true` + - session relay/network failures + - grant create/approve failures + - personal server startup/tunnel failures + +## Test Plan + +1. Unit test flow state: error transitions include correct `retryable` value. +2. UI test `GrantErrorState`: Retry button appears only when `retryable === true`. +3. Regression check: + - expired session -> no Retry + - tunnel timeout -> Retry visible + - builder verification fail -> no Retry + - transient relay failure -> Retry visible + +## Notes + +- Keep change surface minimal: one boolean only, no broad error taxonomy. +- Current runtime always returns home via `declineHref`; no external decline route in production flow. diff --git a/docs/260219-planning-better.md b/docs/260219-planning-better.md new file mode 100644 index 0000000..ffc3fbf --- /dev/null +++ b/docs/260219-planning-better.md @@ -0,0 +1,123 @@ +# 260219-planning-better-next-time + +## Why this exists + +`260217-planning-better-next-time.md` captured core planning failures from auth flow work. + +This follow-up captures what we learned from the pnpm migration planning run: + +- how to convert a good strategy doc into an execution doc, +- how to make handoff deterministic, +- how to enforce proof, not trust. + +## What still holds from 260217 (keep as-is) + +These were correct and remain non-negotiable: + +1. Invariant-first planning. +2. Gate-based phase closure. +3. Dependency classification (`HARD BLOCKED` / `SOFT BLOCKED` / `UNBLOCKED`). +4. Ordered implementation (boundary -> seams -> behavior -> cleanup -> polish). +5. Early replan triggers when loop-back signals appear. + +No rollback on these principles. + +## What 260219 added (new required mechanics) + +The missing piece in 260217 was operational precision. We now require: + +1. **Mandatory File Edit Contract** + - Explicit list of files that must be touched. + - Each file marked `PASS`, `NO-OP`, or `FAIL`. +2. **Targeted verification commands** + - Concrete grep/rg commands and runtime/build checks. + - Not just "run tests"; exact commands and expected outcomes. +3. **Evidence template in PR** + - Table format for gate outcomes. + - Required artifacts/output summary per gate. +4. **Definition of NO-OP** + - "No change required" must be proven by scan at execution time. +5. **Done criteria that block merge** + - Any `FAIL` gate blocks merge, even if feature appears to work. + +## Bidirectional takeaways (both docs improve each other) + +### 260217 -> migration planning + +What helped from 260217 during this run: + +- forcing phase gates prevented "looks done" closure, +- dependency handling mindset exposed hidden npm/npx coupling quickly, +- early-warning signals justified expanding scope before implementation. + +### migration planning -> 260217 model + +What 260217 lacked and should now inherit: + +- explicit handoff contract (who changes what files), +- evidence capture format (not freeform notes), +- mechanical pass/fail semantics for each gate. + +## Updated planning standard (v2) + +Every non-trivial plan must include all of the below: + +1. Goal and scope. +2. Invariants. +3. External dependencies with block status + owner/date. +4. Ordered phases with exit gates. +5. Mandatory File Edit Contract. +6. Non-negotiable verification commands. +7. Evidence Capture Template for PR. +8. Done criteria with merge-blocking conditions. +9. Risks and mitigations. +10. Out of scope. + +If items 5-8 are missing, the plan is not handoff-safe. + +## Gate taxonomy (standardized) + +Use these gate classes in all plans: + +- **Code-path gates**: target files updated as specified. +- **Behavior gates**: runtime behavior remains correct. +- **Build gates**: local build/test/lint pass. +- **Packaging gates**: release artifacts/runtime packaging integrity. +- **CI gates**: workflow semantics preserved after tooling changes. +- **Fresh-clone gates**: clean environment bootstrap works as documented. + +## Evidence quality rules + +1. "Pass" without command output summary is invalid. +2. "No-op" without scan evidence is invalid. +3. Flaky gate result is treated as `FAIL` until reproduced. +4. Fix commits must map to failed gates explicitly. +5. Closure statement must map each risk -> final status. + +## Replan triggers (expanded) + +Stop and replan when any of these occur: + +- same core file edited 3+ times, +- new mandatory file discovered mid-implementation, +- gate wording becomes subjective ("seems fine", "probably"), +- evidence table contains unresolved `FAIL` or ambiguous `NO-OP`, +- scope silently expands without updating file contract and gates. + +## Practical template snippet (drop into new plan) + +Use this block as default: + +- Mandatory File Edit Contract: `` +- Verification Commands: `` +- Evidence Table: `` +- Done Criteria: + - no `FAIL` rows + - no unresolved risks + - all gate classes passed + +## Operating principle + +Do not ship "a good plan." + +Ship a plan that can be executed by another engineer with no interpretation drift, and audited by gate evidence. diff --git a/docs/260203-grant-connect-flow-plan.md b/docs/_archive/260203-grant-connect-flow-plan.md similarity index 100% rename from docs/260203-grant-connect-flow-plan.md rename to docs/_archive/260203-grant-connect-flow-plan.md diff --git a/docs/260203-grant-connect-flow.md b/docs/_archive/260203-grant-connect-flow.md similarity index 100% rename from docs/260203-grant-connect-flow.md rename to docs/_archive/260203-grant-connect-flow.md diff --git a/docs/260203-grant-connect-flow.png b/docs/_archive/260203-grant-connect-flow.png similarity index 100% rename from docs/260203-grant-connect-flow.png rename to docs/_archive/260203-grant-connect-flow.png diff --git a/docs/260204-auth-page-react-spec.md b/docs/_archive/260204-auth-page-react-spec.md similarity index 100% rename from docs/260204-auth-page-react-spec.md rename to docs/_archive/260204-auth-page-react-spec.md diff --git a/docs/260204-connect-flow.png b/docs/_archive/260204-connect-flow.png similarity index 100% rename from docs/260204-connect-flow.png rename to docs/_archive/260204-connect-flow.png diff --git a/docs/260205-app-id-design.md b/docs/_archive/260205-app-id-design.md similarity index 100% rename from docs/260205-app-id-design.md rename to docs/_archive/260205-app-id-design.md diff --git a/docs/260205-app-id.png b/docs/_archive/260205-app-id.png similarity index 100% rename from docs/260205-app-id.png rename to docs/_archive/260205-app-id.png diff --git a/docs/260206-data-src-overview.png b/docs/_archive/260206-data-src-overview.png similarity index 100% rename from docs/260206-data-src-overview.png rename to docs/_archive/260206-data-src-overview.png diff --git a/docs/260206-grant-step3-plan.md b/docs/_archive/260206-grant-step3-plan.md similarity index 100% rename from docs/260206-grant-step3-plan.md rename to docs/_archive/260206-grant-step3-plan.md diff --git a/docs/260206-grant-step4-plan.md b/docs/_archive/260206-grant-step4-plan.md similarity index 100% rename from docs/260206-grant-step4-plan.md rename to docs/_archive/260206-grant-step4-plan.md diff --git a/docs/plans/260219-lib-unused-mut-warning-plan.md b/docs/plans/260219-lib-unused-mut-warning-plan.md new file mode 100644 index 0000000..27c2657 --- /dev/null +++ b/docs/plans/260219-lib-unused-mut-warning-plan.md @@ -0,0 +1,75 @@ +# 260219: `unused_mut` warning in `src-tauri/src/lib.rs` + +## Context + +During a production build, Rust emits: + +- `variable does not need to be mutable` +- file: `src-tauri/src/lib.rs` +- line: builder initialization in `run()` + +This is currently non-blocking (warning only), but it should be cleaned up in a separate, scoped change. + +## Problem + +`builder` is declared mutable: + +- `let mut builder = tauri::Builder::default()...` + +In release builds, the debug-only reassignment path is excluded, so `mut` is unnecessary and triggers `unused_mut`. + +## Root Cause + +The code pattern mixes: + +- always-on mutable declaration +- conditional reassignment behind `#[cfg(debug_assertions)]` + +When `debug_assertions` is off, reassignment disappears but mutable declaration remains. + +## Proposed Fix + +Use immutable shadowing instead of mutable reassignment. + +### Before + +- `let mut builder = ...` +- debug block does `builder = builder.plugin(...)` + +### After + +- `let builder = ...` +- debug path uses `let builder = builder.plugin(...)` + +This preserves behavior and removes the warning in release. + +## Scope + +Only: + +- `src-tauri/src/lib.rs` + +No functional changes expected. No runtime behavior changes expected. + +## Validation + +From `src-tauri/` run: + +- `cargo check --lib -p dataconnect` + +Expected: + +- no `unused_mut` warning for `builder` +- successful compile + +## Commit Guidance + +Keep this in a separate commit from icon/docs work. + +Suggested commit message: + +- `chore: remove unused mut in tauri builder setup` + +## Ownership Recommendation + +If today’s focus is icon/artwork pipeline, defer this to a follow-up micro-task owned by teammate or next cleanup pass. diff --git a/docs/plans/260219-pnpm-migration.md b/docs/plans/260219-pnpm-migration.md new file mode 100644 index 0000000..b066ae5 --- /dev/null +++ b/docs/plans/260219-pnpm-migration.md @@ -0,0 +1,298 @@ +# 260219-pnpm-migration + +## Objective + +Switch this repo from npm to pnpm in one PR, with no behavior change, no follow-up fix cycle, and deterministic local + CI installs. + +## Scope + +- In scope: package manager/tooling migration only. +- Out of scope: product behavior changes, connector protocol changes, release process redesign. + +## Preconditions + +- Node version is `22` (matches `.nvmrc` and CI). +- Work from repo root. +- Use one command style in scripts/config: `pnpm run