{"id":50400360,"url":"https://github.com/ansh-rathod/research_canvas","last_synced_at":"2026-05-30T23:03:11.165Z","repository":{"id":347573893,"uuid":"1194494226","full_name":"Ansh-Rathod/research_canvas","owner":"Ansh-Rathod","description":"Better way to bookmark things from the internet.  ","archived":false,"fork":false,"pushed_at":"2026-03-28T13:33:30.000Z","size":82,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-03-28T16:33:54.022Z","etag":null,"topics":["tldraw"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Ansh-Rathod.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-03-28T12:40:43.000Z","updated_at":"2026-03-28T13:33:33.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/Ansh-Rathod/research_canvas","commit_stats":null,"previous_names":["ansh-rathod/research_canvas"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/Ansh-Rathod/research_canvas","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Ansh-Rathod%2Fresearch_canvas","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Ansh-Rathod%2Fresearch_canvas/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Ansh-Rathod%2Fresearch_canvas/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Ansh-Rathod%2Fresearch_canvas/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Ansh-Rathod","download_url":"https://codeload.github.com/Ansh-Rathod/research_canvas/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Ansh-Rathod%2Fresearch_canvas/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33712582,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-05-30T02:00:06.278Z","response_time":92,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["tldraw"],"created_at":"2026-05-30T23:03:05.172Z","updated_at":"2026-05-30T23:03:11.154Z","avatar_url":"https://github.com/Ansh-Rathod.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Research Canvas\n\nA Chromium extension that adds a **side-panel research canvas** powered by [tldraw](https://tldraw.com), with captures from the current tab (images, video clips, URL cards, selected text, regions). Captured image/video bytes can be saved to a local file server and referenced by URL in the board.\n\n**Requirements:** Chromium-based browser with **Manifest V3** and **Side Panel** support (e.g. Chrome **114+**).\n\n## Local media server\n\nThe repo includes a small **Express** app (`local-server/server.mjs`) that receives image and video uploads from the extension and serves those files back over HTTP.\n\n### Why it is needed\n\n- **Smaller, faster canvas data:** If every capture were embedded in the tldraw document as base64 or huge data URLs, IndexedDB snapshots and exports would grow quickly and become slow to load and share. Uploading to disk and storing only **URLs** on the board keeps documents light.\n- **Plain files you own:** Media lands under `local-media/images` and `local-media/videos` as normal files—easy to back up, open in other apps, or delete without editing JSON.\n- **Fits the extension model:** The side panel talks to your machine over **HTTP** to `127.0.0.1`. The server is **localhost-only** (not exposed on your LAN) and uses **CORS** so browser security rules allow the upload requests from the extension.\n\nYou can still use the extension without this process running, but **image/video capture flows that save to the local server** expect it to be up; otherwise those uploads fail until you start the server (or retry from the Uploads UI).\n\n### Features\n\n| Feature | What it does | How you use it |\n|--------|----------------|----------------|\n| **Upload image** | `POST /upload/image` accepts one multipart file in the field `file`, picks an extension from the MIME type (e.g. PNG, JPEG, WebP), writes under `local-media/images`, returns JSON with a public `url`. | Run `npm run local-media-server`, then capture images from the toolbar/context menu as usual; the extension POSTs for you. |\n| **Upload video** | Same as image, but `POST /upload/video` and `local-media/videos` (e.g. WebM). Optional `width` / `height` form fields are echoed back as metadata when present. | Same workflow for video clips. |\n| **Serve media** | `GET` requests under `/media/...` map to files inside `local-media` (static files). Returned upload URLs look like `http://127.0.0.1:\u003cport\u003e/media/images/\u003cfile\u003e` or `.../videos/\u003cfile\u003e`. | The canvas loads these URLs as image/video shapes; you can also open the URL in a browser tab while the server runs. |\n| **Health check** | `GET /health` returns JSON `{ ok, host, port }`. | Quick check that the server is listening: e.g. open `http://127.0.0.1:43123/health` or use `curl`. |\n| **Safety limits** | One file per request, up to **300 MB**, in-memory buffer then written to disk. | Large captures stay within this cap; if you need bigger files, adjust `local-server/server.mjs`. |\n\n**Configuration:** Default bind is **`127.0.0.1`** and default port is **`43123`**. You can set **`LOCAL_MEDIA_SERVER_PORT`** when starting the server to use another port. The built-in extension code expects **`http://127.0.0.1:43123`** unless you change `src/shared/localMediaUpload.ts` (and the matching constant in `src/tldraw/App.tsx`) or set the global `__RESEARCH_CANVAS_LOCAL_MEDIA_SERVER__` to match your port.\n\n### How to run it\n\n1. Install dependencies once: `npm install` (from the repo root).\n2. Start the server: `npm run local-media-server`.\n3. Leave that terminal open while you capture media that uploads to disk.\n4. Confirm it is up: visit `http://127.0.0.1:43123/health` (or your chosen port).\n\nUploaded files appear under **`local-media/images`** and **`local-media/videos`** with names like `\u003ctimestamp\u003e-\u003crandom\u003e.\u003cext\u003e`.\n\n## Development\n\n### 1. Install dependencies\n\n```bash\nnpm install\n```\n\n### 2. Build the extension\n\nProduction build (outputs to `dist/`):\n\n```bash\nnpm run build\n```\n\nThis runs Vite and copies `manifest.json` into `dist/`.\n\n### 3. Watch mode (optional)\n\nRebuild automatically when you change source files:\n\n```bash\nnpm run dev\n```\n\nLeave this running while you develop. After each rebuild, **reload the extension** in the browser (see below).\n\n### 4. Start the local media server (required for image/video uploads)\n\n```bash\nnpm run local-media-server\n```\n\nSee **[Local media server](#local-media-server)** for why this exists, what each endpoint does, and how it fits capture workflows.\n\n### 5. Typecheck\n\n```bash\nnpm run check\n```\n\n## Install in the browser (load unpacked)\n\n1. Build at least once so `dist/` exists (`npm run build`).\n2. Open **`chrome://extensions`** (or **Edge:** `edge://extensions`).\n3. Turn on **Developer mode** (toggle in the toolbar).\n4. Click **Load unpacked**.\n5. Select the **`dist`** folder inside this project  \n   (e.g. `/path/to/research/dist`), **not** the repo root.\n\nThe extension should appear as **Research Canvas**. Pin it to the toolbar if you want quick access.\n\n### After code changes\n\nRun **`npm run build`** again (or use **`npm run dev`** and wait for a rebuild), then on `chrome://extensions` click **Reload** on the Research Canvas card.\n\n## Using the extension\n\n- Click the **extension icon** to open or focus the **side panel** (Research Canvas).\n- Use the **floating toolbar** on web pages for captures, or the **context menu** / **keyboard shortcuts** defined in `manifest.json` under `commands` (set shortcuts under **chrome://extensions/shortcuts**).\n- Right-click the page → **Show Research Canvas floating toolbar** if you hid the floating bar.\n- Open the board sidebar and use the **Uploads** button to view the upload process dialog (queued/uploading/success/error and retry failures).\n\n## Project layout (short)\n\n| Path | Role |\n|------|------|\n| `local-server/` | Local media upload + static file server (`npm run local-media-server`) |\n| `local-media/` | On-disk images/videos written by that server (gitignored) |\n| `src/sidepanel/` | React + tldraw UI (side panel) |\n| `src/background/service-worker.ts` | MV3 service worker: captures, storage, side panel |\n| `src/content/` | Content scripts + floating toolbar |\n| `src/storage/` | IndexedDB helpers |\n| `dist/` | **Load this folder** as the unpacked extension |\n\n## License\n\nPrivate project (`\"private\": true` in `package.json`). Add a license file if you intend to publish.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fansh-rathod%2Fresearch_canvas","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fansh-rathod%2Fresearch_canvas","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fansh-rathod%2Fresearch_canvas/lists"}