main
md 6.68 KB

name: sigit-app

description: Use when working on the "siGit Code & Deploy" Tauri desktop app (repo ~/Repositories/sigit-app), especially account management — login, signup, email verification, password reset, me, logout, remove account — and keeping account feature parity with the sigit-si web app. Covers the src-tauri account command set, the AccountStatus/ErrorResponse contract, token storage, the settings/account React views, and the decision about whether the app talks to smbCloud Auth directly or through sigit.si/api/v1.

siGit Code & Deploy desktop app (sigit-app)

Product map: siGit Code (local agent) · siGit Code Cloud (hosted chat + Cloud Sessions) · siGit Code Cloud Agent (autonomous task → PR; planning). sigit.si is Git hosting; code.sigit.si is the home of siGit Code. Full taxonomy: product-overview.

sigit-app is the Tauri desktop client for siGit (repo ~/Repositories/sigit-app). It is a public client (a shipped binary), so the public-client security rules apply — see smbcloud-cli/.agents/skills/smbcloud-auth/SKILL.md. This file is the sigit-app-specific view; keep its account features at parity with the sigit-si web account page (sigit-si/.agents/skills/smbcloud-auth/SKILL.md).

Account command set

Rust commands in src-tauri/src/account/ (registered in mod.rs), each a #[tauri::command]:

  • command_loginlogin(app, env, username, password)
  • command_signupsignup(...)
  • command_meme(...)
  • command_logoutlogout(...)
  • command_remove_accountremove_account(app, env, client, access_token)
  • command_resend_confirmation_email
  • command_reset_password
  • command_resend_reset_password_instructiont (note: existing misspelled name — match it exactly when wiring the frontend; don't "fix" it without renaming the invoke call sites too)
  • command_check_email_oauth

Current data flow

Today the commands call the Rust auth SDK directly, not an HTTP API:

smbcloud_auth::login::login(env, client(), username, password)
smbcloud_model::{ error_codes::{ErrorCode, ErrorResponse}, login::AccountStatus }
smbcloud_network::environment::Environment   // Dev | Production
  • success returns AccountStatus; on AccountStatus::Ready { access_token } the token is persisted via crate::store::store_token
  • preserve the AccountStatus contract end to end: NotFound · Ready { access_token } · Incomplete { status }
  • failures return ErrorResponse::Error { error_code, message } (ErrorCode from smbcloud_model)
  • env: Environment is passed from the frontend (useEnvironment().current)

Frontend

src/components/sidebar/settings/:

  • account.tsx — signed-in view: email, Anthropic API key field (stored locally on-device via get_setting/update_setting, used by the Claude ACP agent — not an auth credential), Logout, Remove Account
  • login-form.tsx, signup.tsx, verify-email-form.tsx, set-password-form.tsx, logged-out-view.tsx, debug-setting-view.tsx

Frontend calls Rust via invoke("<command>", { env, accessToken, ... }). The env switch is gated through useEnvironment; keep production/dev switching behind debug controls.

Integration decision: direct SDK vs sigit.si/api/v1

The current architecture is app → Rust SDK → smbCloud Auth. The active goal is to route desktop auth through sigit.si/api/v1 instead (app → sigit.si → smbCloud Auth). Before implementing, settle this explicitly:

  • Direct SDK (status quo): fewer hops, but the desktop binary needs smbCloud app credentials and bypasses sigit-si entirely.
  • Via sigit.si/api/v1 (goal): sigit-si becomes the trust boundary, holds the confidential app_secret server-side, and the desktop app only ever sees a bearer token. Better for the public-client rule; requires building the JSON API in sigit-si first (see the sigit-si smbcloud-auth skill).

If switching to the API path, change the command bodies to call sigit.si/api/v1/* and keep the same AccountStatus / ErrorResponse shapes so the frontend and token storage are unaffected.

Git operations (repos)

Git uses Smart HTTP with token auth — no SSH. Live commands in src-tauri/src/repos/ (registered in lib.rs):

  • clone_repo · publish_repo · push_repo / pull_repo · list_repos

Two-token flow — never use the account access token as a git credential:

  1. login → account access token persisted via crate::store::store_token
  2. repos::api::fetch_git_token(env, access_token) POSTs sigit.sigit_credentials (bearer = access token) → returns a short-lived scoped git_token
  3. git2 credential callback authenticates over HTTPS via HTTP Basic: Cred::userpass_plaintext("x-access-token", git_token) — username is the literal string x-access-token, password is the scoped git token
  4. repos::api::create_remote_repo POSTs repos (bearer = access token) to create the bare repo before first publish

This is in-process libgit2 (git2 / gix, vendored) over HTTPS — no subprocess, no key files — so it works inside the sandboxed App Store build and the container-stored-repo model.

Legacy SSH path (deprecated — do not extend)

src/_git/{clone_project,desktop_deploy}.rs, src/project/command_clone_frontend_app.rs, and src/ssh/command_generate_ssh_key.rs still use Cred::ssh_key and remain registered (clone_project, clone_frontend_app, ssh_clone, generate_ssh_key), but SSH-based git is no longer the model — new work uses the Smart HTTP path above. desktop_deploy.rs also hardcodes /Users/setoelkahfi/.ssh/..., which is dead in any non-author or sandboxed build. Candidates for removal, not extension.

Validation

  • cargo check in src-tauri
  • pnpm build (or the app's package script) when the frontend changed
  • exercise login → verify email → me → logout → remove against the dev environment
  • confirm token storage and session restore (me) still work

Common mistakes

  • Breaking the AccountStatus contract the frontend depends on
  • Renaming a command without updating its invoke(...) call sites (esp. the misspelled ..._instructiont)
  • Treating the Anthropic API key field as an auth credential — it is local-only
  • Shipping smbCloud app_secret in the binary and assuming it is confidential
  • Diverging account features from the sigit-si web account page
  • Reaching for SSH credentials / generate_ssh_key for git auth — the live path is Smart HTTP over HTTPS (repos::*), not Cred::ssh_key
  • Using the account access token directly as the git credential — always exchange it for a short-lived scoped git_token via fetch_git_token first