# Project Velocity — Gitea Feature Contribution Guide **Version:** 1.1 **Last Updated:** 2026-03-07 **Upstream Repository (Sagnik's):** `https://git.desineuron.in/sagnik/Project_Velocity` **Your Fork:** `https://git.desineuron.in//Project_Velocity` > This document is the **canonical guide** for every team member contributing to Project Velocity. > The team uses a **Fork-based workflow**: each contributor has their own fork of Sagnik's repository. All features are developed in your fork and merged into the upstream via Pull Requests. > It covers the full lifecycle: Issue → Branch → Commit → Push → Pull Request — both via the **CLI** and via **Antigravity Source Control UI**. ### How the Fork Model Works ```text [upstream] sagnik/Project_Velocity ← the source of truth ↑ Pull Requests [your fork] /Project_Velocity ← where you develop ↑ git push [local] /your/machine/Project_Velocity ``` - `upstream` = Sagnik's repo — you **pull** from here to stay in sync. - `origin` = Your fork — you **push** your branches here. - PRs go **from your fork → upstream**. --- ## Table of Contents 1. [Naming Conventions](#naming-conventions) 2. [One-Time Setup — Fork & Remotes](#one-time-setup--fork--remotes) 3. [Step 0 — Pre-flight: Populate `.gitignore` & `.gitkeep`](#step-0--pre-flight) 4. [Step 1 — Create a Gitea Issue](#step-1--create-a-gitea-issue) 5. [Step 2 — Sync with Upstream Before Branching](#step-2--sync-with-upstream-before-branching) 6. [Step 3 — Create a Feature Branch](#step-3--create-a-feature-branch) 7. [Step 4 — Make Your Changes & Commit](#step-4--make-your-changes--commit) 8. [Step 5 — Push the Branch to Your Fork](#step-5--push-the-branch-to-your-fork) 9. [Step 6 — Create a Pull Request (Fork → Upstream)](#step-6--create-a-pull-request-fork--upstream) 10. [Quick Reference — CLI Cheat Sheet](#quick-reference--cli-cheat-sheet) --- ## Naming Conventions Consistent naming keeps the repository clean and makes history easy to read. | Type | Format | Example | |------|--------|---------| | **Issue Title** | `feat : ` | `feat : Build the native SwiftUI app shell` | | **Branch Name** | `feat/#` | `feat/#12` | | **Commit Message** | `feat(scope): ` or `fix(scope): ` | `feat(ios): add Dashboard, Oracle and Sentinel tab views` | > Use `fix`, `chore`, `docs`, `refactor`, or `test` instead of `feat` where appropriate. --- ## One-Time Setup — Fork & Remotes Do this **once** when you first clone your fork onto a new machine. You only need to do this once per machine. ### 1. Clone your fork ```bash git clone https://git.desineuron.in//Project_Velocity.git cd Project_Velocity ``` ### 2. Add the upstream remote (Sagnik's repo) ```bash git remote add upstream https://git.desineuron.in/sagnik/Project_Velocity.git ``` ### 3. Verify your remotes ```bash git remote -v ``` You should see **two** remotes: ```text origin https://git.desineuron.in//Project_Velocity.git (fetch) origin https://git.desineuron.in//Project_Velocity.git (push) upstream https://git.desineuron.in/sagnik/Project_Velocity.git (fetch) upstream https://git.desineuron.in/sagnik/Project_Velocity.git (push) ``` > ⚠️ If you only see `origin`, you haven't added `upstream` yet. Run step 2 above. ### Via Antigravity Source Control UI Antigravity does not have a direct UI button to add a new remote. Do this once via the terminal: 1. Open a terminal inside Antigravity (`Ctrl + `` ` `` ` `). 2. Run: `git remote add upstream https://git.desineuron.in/sagnik/Project_Velocity.git` 3. The upstream remote will now appear in the **Graph** section of Source Control. --- ## Step 0 — Pre-flight Before pushing anything, ensure these files are properly configured at the **root of the repository**. ### `.gitignore` A root `.gitignore` already exists at the repository root. It covers: - **macOS** system files (`DS_Store`, etc.) - **Node / Vite / React** (`app/node_modules/`, `app/dist/`) - **Xcode / Swift** (derived data, `.xcuserdata`, build artifacts) - **Python / ComfyUI** (`__pycache__`, `.venv`, model weights) - **Infrastructure** (Terraform state, secrets) **You should never commit:** - API keys or secrets (`.env` files are ignored) - `node_modules/` directory - Xcode `DerivedData/` or `.xcuserdata/` - Python virtual environments (`.venv/`, `venv/`) ### `.gitkeep` A `.gitkeep` file is used to **track an otherwise empty directory** in Git (Git does not track empty folders). **When to add one:** If you create a new directory that should be committed but has no files yet, add an empty `.gitkeep` file inside it: ```bash touch path/to/your/new-empty-folder/.gitkeep ``` --- ## Step 1 — Create a Gitea Issue Every feature or bug fix must start with a **Gitea Issue**. Issues must be created in **Sagnik's upstream repository** — not your fork. The upstream is the source of truth for the project, and `Closes #` in your PR description will only auto-close the issue if it lives in the same repo your PR targets. ### Via Browser (Gitea Web UI) 1. Go to **Sagnik's upstream repo**: `https://git.desineuron.in/sagnik/Project_Velocity`. 2. Click on the **Issues** tab. 3. Click the green **New Issue** button. 4. Fill in the title using the format: ``` feat : ``` **Example:** ``` feat : Build the native SwiftUI app shell mirroring the WebOS interface ``` 5. Add a description explaining: - **What** you are building. - **Why** it is needed. - **Acceptance criteria** (what "done" looks like). 6. Assign the issue to yourself. 7. Click **Submit**. Note down the **Issue Number** (e.g., `#12`) — you will need it for the branch name. ### Via CLI (using `curl` or Gitea API) ```bash # Replace placeholders before running GITEA_URL="https://git.desineuron.in" GITEA_TOKEN="" # Generate at: Profile → Settings → Applications REPO_OWNER="sagnik" # Issues go in the UPSTREAM repo REPO_NAME="Project_Velocity" ISSUE_TITLE="feat : " ISSUE_BODY="" curl -s -X POST "$GITEA_URL/api/v1/repos/$REPO_OWNER/$REPO_NAME/issues" \ -H "Content-Type: application/json" \ -H "Authorization: token $GITEA_TOKEN" \ -d "{ \"title\": \"$ISSUE_TITLE\", \"body\": \"$ISSUE_BODY\", \"assignees\": [\"$REPO_OWNER\"] }" ``` > The response JSON will contain the `number` field — **this is your issue number**. --- ## Step 2 — Sync with Upstream Before Branching Before creating a feature branch, **always** pull the latest changes from **`upstream`** (Sagnik's repo) — not from your fork (`origin`). This ensures your work starts from the most up-to-date version of the project. ### Via CLI ```bash # Navigate to your project root cd "/path/to/Project_Velocity" # Switch to main git checkout main # Fetch all branches from upstream git fetch upstream # Merge upstream/main into your local main git merge upstream/main # (Optional) Push the synced main to your own fork to keep it up to date git push origin main ``` > **Why `upstream` and not `origin`?** > `origin` is your personal fork — it only knows about changes you've pushed. > `upstream` is Sagnik's repository — the actual source of truth for the project. ### Via Antigravity Source Control UI Antigravity's sync button pulls from `origin` by default. To sync from upstream, use the terminal: 1. Open a terminal in Antigravity (`Ctrl + `` ` `` ` `). 2. Run: ```bash git fetch upstream && git merge upstream/main ``` 3. Then click the **↺ (Refresh)** icon in the Source Control panel to refresh the view. 4. Confirm the **Graph** section shows your local `main` is aligned with `upstream/main`. --- ## Step 3 — Create a Feature Branch Branch name format: **`feat/#`** **IMPORTANT:** Replace `` with the actual number from Step 1. ### Via CLI ```bash # Make sure you are on main first git checkout main # Create and switch to the new branch git checkout -b feat/# # Example: # git checkout -b feat/#12 ``` ### Via Antigravity Source Control UI 1. In the **Source Control** panel, look at the bottom **Graph** section. 2. Click on the **branch name** shown next to the current `HEAD` commit (e.g., `main`). 3. A branch picker will appear at the top of the screen. 4. Type the new branch name exactly: `feat/#` 5. Select **"Create new branch: feat/#"** from the dropdown. 6. Confirm. Your working branch is now set to the new feature branch. --- ## Step 4 — Make Your Changes & Commit ### Stage Your Files #### Via CLI ```bash # Stage specific files git add path/to/changed/file.swift # Stage all changed/new files at once (use with care) git add . # Review what is staged before committing git status ``` #### Via Antigravity Source Control UI 1. In the **Source Control** panel, you will see two sections: - **Staged Changes** — files ready to be committed. - **Changes** — files that are modified but not yet staged. 2. To **stage a file**: Hover over it in the **Changes** section and click the **`+`** (plus) icon that appears on the right. 3. To **unstage a file**: Hover over it in **Staged Changes** and click the **`-`** (minus) icon. 4. To **stage all changes at once**: Click the **`+`** (plus) icon next to the **Changes** section header. ### Write Your Commit Message Use the **Conventional Commits** format: ``` (scope): ``` | Type | When to Use | |------|-------------| | `feat` | A new feature | | `fix` | A bug fix | | `docs` | Documentation changes only | | `refactor` | Code restructured, no behavior change | | `chore` | Config, build scripts, dependencies | | `test` | Adding or fixing tests | **Example commit messages:** ``` feat(ios): add Dashboard, Oracle, Sentinel, and Inventory tab views feat(ios): implement AppStore with lead, visitor, and metrics models fix(ios): correct ARSunOverlayView coordinate calculations docs(agent): add velocity_ios_bible.md technical reference ``` ### Commit #### Via CLI ```bash git commit -m "(scope): " # Example: # git commit -m "feat(ios): add Dashboard, Oracle, Sentinel tab views mirroring WebOS" ``` #### Via Antigravity Source Control UI 1. Ensure your files are in the **Staged Changes** section. 2. Click the **Message** text field at the top of the Source Control panel (placeholder: `Message (⌘Enter to com...)`). 3. Type your commit message following the Conventional Commits format above. 4. *(Optional)* Click **Generate ✦** to let Antigravity AI suggest a commit message based on your staged diffs — review it before accepting. 5. Click the blue **✓ Commit** button (or press `⌘ + Enter`) to commit. --- ## Step 5 — Push the Branch to Gitea ### Via CLI ```bash # Push your feature branch to the remote (origin) git push origin feat/# # Example: # git push origin feat/#12 ``` If this is the **first push** of a new branch, Git may ask you to set the upstream: ```bash git push --set-upstream origin feat/# ``` ### Via Antigravity Source Control UI 1. After committing, look at the **Changes** header in the Source Control panel. 2. Click the **`...` (More Actions)** menu (top-right of the Changes section header). 3. Select **Push** from the dropdown. 4. Alternatively, click the **↑ (Publish/Push)** cloud icon if visible next to the branch name in the status bar or Graph section. 5. Antigravity will push your local feature branch to `origin/feat/#` on Gitea. --- ## Step 6 — Create a Pull Request (Fork → Upstream) Since you are working on a fork, your PR goes **from your fork's feature branch → Sagnik's upstream `main`**. This is a cross-repository PR. ### Via Browser (Gitea Web UI) 1. Go to **Sagnik's upstream repo**: `https://git.desineuron.in/sagnik/Project_Velocity`. 2. Click the **Pull Requests** tab → **New Pull Request**. 3. Click **"compare across forks"** (Gitea shows this option when creating a cross-fork PR). 4. Set up the PR direction: - **Base repository:** `sagnik/Project_Velocity` — **Base branch:** `main` - **Head repository:** `/Project_Velocity` — **Compare branch:** `feat/#` 5. Fill in the PR form: - **Title:** `feat(scope): ` - **Description:** ``` ## Summary ## Changes - ## Related Issue Closes # ``` 6. Assign **Sagnik** as reviewer. 7. Click **Create Pull Request**. > 💡 **Alternatively**, after you push your branch to your fork (`origin`), Gitea may show a yellow banner inside Sagnik's upstream repo prompting you to create a cross-fork PR automatically. Click that if it appears. ### Via CLI (using Gitea API) For a cross-fork PR, the `head` must include your fork username as a prefix. ```bash GITEA_URL="https://git.desineuron.in" GITEA_TOKEN="" UPSTREAM_OWNER="sagnik" # Sagnik's username UPSTREAM_REPO="Project_Velocity" YOUR_USERNAME="" # Your Gitea username FEATURE_BRANCH="feat/#" PR_TITLE="feat(scope): " PR_BODY="## Summary\n\n\n## Changes\n- \n\n## Related Issue\nCloses #" curl -s -X POST "$GITEA_URL/api/v1/repos/$UPSTREAM_OWNER/$UPSTREAM_REPO/pulls" \ -H "Content-Type: application/json" \ -H "Authorization: token $GITEA_TOKEN" \ -d "{ \"title\": \"$PR_TITLE\", \"body\": \"$PR_BODY\", \"head\": \"$YOUR_USERNAME:$FEATURE_BRANCH\", \"base\": \"main\" }" ``` > Note the `head` format: `":feat/#"` — this tells Gitea the branch lives in your fork, not the upstream. --- ## Quick Reference — CLI Cheat Sheet Copy and fill in the placeholders (`<...>`) before running. ```bash # ── ONE-TIME SETUP (do this once per machine) ───────────────── cd "/path/to/Project_Velocity" git remote add upstream https://git.desineuron.in/sagnik/Project_Velocity.git git remote -v # verify: you should see both origin and upstream # ── 1. Create the Gitea Issue ────────────────────────────────── # Go to Gitea web UI or use the curl command in Step 1 # Title format: feat : # Note the issue number: # ── 2. Sync from upstream main ──────────────────────────────── git checkout main git fetch upstream git merge upstream/main git push origin main # keep your fork in sync too # ── 3. Create & switch to feature branch ───────────────────── git checkout -b feat/# # ── 4. Stage & Commit ───────────────────────────────────────── git add . git status # double-check what is staged git commit -m "(scope): " # ── 5. Push branch to YOUR FORK (origin) ────────────────────── git push origin feat/# # ── 6. Create Pull Request (fork → upstream) ────────────────── # Go to: https://git.desineuron.in/sagnik/Project_Velocity # Pull Requests → New Pull Request → Compare across forks # head: /Project_Velocity : feat/# # base: sagnik/Project_Velocity : main ``` --- ## Tips & Best Practices - **One issue = one branch = one PR.** Keep your changes focused. - **Always sync from `upstream`, not `origin`.** Your fork doesn't automatically know about changes Sagnik pushes. Run `git fetch upstream && git merge upstream/main` regularly. - **Commit often, push when ready.** Small commits make code review easier. - **Never commit directly to `main`.** Always work on a feature branch. - **Push to `origin`, PR to `upstream`.** Push goes to your fork. The PR targets Sagnik's repo. - **Reference issues in PRs.** Using `Closes #` auto-closes the issue on merge. - **Personal Access Token:** Generate it once at `https://git.desineuron.in` → Profile → Settings → Applications → Generate Token. Store it securely (e.g., in your password manager or macOS Keychain). - **Keep your fork's `main` clean.** Never push feature work directly to `origin/main` — only merge `upstream/main` into it to stay current.