@lasso-ai/cli 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/ARCHITECTURE.md +342 -0
  2. package/CHANGELOG.md +102 -0
  3. package/CODE_OF_CONDUCT.md +129 -0
  4. package/CONTRIBUTING.md +122 -0
  5. package/LICENSE +7 -0
  6. package/README.md +548 -0
  7. package/SECURITY.md +65 -0
  8. package/SUPPORT.md +31 -0
  9. package/dist/cli/agent.d.ts +61 -0
  10. package/dist/cli/agent.js +418 -0
  11. package/dist/cli/auth.d.ts +38 -0
  12. package/dist/cli/auth.js +162 -0
  13. package/dist/cli/bridge.d.ts +160 -0
  14. package/dist/cli/bridge.js +450 -0
  15. package/dist/cli/host/certificates.d.ts +12 -0
  16. package/dist/cli/host/certificates.js +52 -0
  17. package/dist/cli/host/client.d.ts +49 -0
  18. package/dist/cli/host/client.js +141 -0
  19. package/dist/cli/host/daemon.d.ts +50 -0
  20. package/dist/cli/host/daemon.js +368 -0
  21. package/dist/cli/host/dns.d.ts +80 -0
  22. package/dist/cli/host/dns.js +255 -0
  23. package/dist/cli/host/install.d.ts +32 -0
  24. package/dist/cli/host/install.js +177 -0
  25. package/dist/cli/host/next-host-entry.d.ts +1 -0
  26. package/dist/cli/host/next-host-entry.js +82 -0
  27. package/dist/cli/host/paths.d.ts +15 -0
  28. package/dist/cli/host/paths.js +55 -0
  29. package/dist/cli/host/registry.d.ts +31 -0
  30. package/dist/cli/host/registry.js +103 -0
  31. package/dist/cli/host/runtime.d.ts +23 -0
  32. package/dist/cli/host/runtime.js +134 -0
  33. package/dist/cli/host/vite-host-entry.d.ts +1 -0
  34. package/dist/cli/host/vite-host-entry.js +59 -0
  35. package/dist/cli/index.d.ts +2 -0
  36. package/dist/cli/index.js +322 -0
  37. package/dist/cli/project.d.ts +56 -0
  38. package/dist/cli/project.js +298 -0
  39. package/dist/cli/server/next.d.ts +6 -0
  40. package/dist/cli/server/next.js +76 -0
  41. package/dist/cli/server/vite.d.ts +1 -0
  42. package/dist/cli/server/vite.js +51 -0
  43. package/dist/cli/utils/framework.d.ts +2 -0
  44. package/dist/cli/utils/framework.js +26 -0
  45. package/dist/overlay.js +20365 -0
  46. package/docs/PUBLISHING.md +63 -0
  47. package/package.json +106 -0
@@ -0,0 +1,342 @@
1
+ # Architecture
2
+
3
+ > Product name: **Lasso**.
4
+
5
+ ## 1. Core principle
6
+
7
+ Lasso edits **source code**, never the live DOM. A visual selection is a pointer into a
8
+ codebase, not a target for direct manipulation. This decision shapes every component
9
+ below — it's what separates a real dev tool from a demo that only works on static HTML.
10
+
11
+ ## 2. Repository layout
12
+
13
+ ```
14
+ src/
15
+ cli/ # the Node CLI (the coordinator)
16
+ index.ts # entry point: `lasso` / `lasso dev`, framework detection dispatch, `daemon`/`projects`/`register`
17
+ project.ts # project identity: `lasso init` (writes `{id, domain}`), `lasso dev` session resolution
18
+ auth.ts # `lasso auth`: browser-OAuth login, credential store (~/.lasso/credentials.json), status, logout
19
+ bridge.ts # WebSocket bridge the overlay connects to
20
+ server/
21
+ vite.ts # Vite dev server with the source-mapping plugin injected in-memory
22
+ next.ts # Next.js dev server integration (React _debugSource)
23
+ utils/
24
+ framework.ts # framework/bundler detection
25
+ host/ # Lasso Host: user-level local domains + app hosting
26
+ paths.ts # host dir (~/.lasso/host), registry/pid/log paths, ports, the `.lasso` TLD
27
+ registry.ts # domain → {projectId, directory} persistence (atomic, 0600), unique-domain generation
28
+ runtime.ts # auto-start dev servers (Vite/Next), readiness polling, port picking
29
+ dns.ts # UDP responder (*.lasso → 127.0.0.1, NXDOMAIN outside) + per-OS resolver config
30
+ daemon.ts # the background host: HTTP+WS proxy, /_host/* control API, single-instance, crash guard
31
+ client.ts # CLI-side helpers: health, registry read/register, stop/restart
32
+ install.ts # `lasso daemon install/uninstall`, LaunchAgent, daemon spawn/status
33
+ vite-host-entry.js # programmatic Vite with `.lasso` allow-listed (Vite rejects unknown Host headers)
34
+ overlay/
35
+ index.ts # browser-side overlay (single file, bundled to dist/overlay.js)
36
+ # also hosts the realtime client: presence, locks, comments, voice
37
+ audio/
38
+ transcribe.ts # client-side audio capture (MediaRecorder) & STT relay
39
+ ```
40
+
41
+ Two artifacts ship from `pnpm build`:
42
+
43
+ - `dist/cli/index.js` — the CLI, compiled with `tsc`
44
+ - `dist/overlay.js` — the browser overlay, bundled with `esbuild`
45
+
46
+ ## 3. System overview
47
+
48
+ Three parties, all coordinating around one shared filesystem:
49
+
50
+ ```
51
+ ┌─────────────────────────────── Your machine ───────────────────────────────┐
52
+ │ │
53
+ │ Browser Local CLI │
54
+ │ ┌──────────────┐ selection ┌──────────────────┐ writes ┌───────┐ │
55
+ │ │ Overlay │──────────────▶│ Bridge │───────────▶│ Source │ │
56
+ │ │ (lasso, UI) │ + prompt │ Source resolver │ │ files │ │
57
+ │ │ Running app │◀──────────────│ Diff preview │ └───────┘ │
58
+ │ │ (Vite/Next │ diff/accept │ Agent adapter │ │ │
59
+ │ │ HMR) │ └────────┬──────────┘ │ │
60
+ │ └──────────────┘ │ dev server │
61
+ │ │ watches ↓ │
62
+ └────────────────────────────────────────────┼──────────────────────────────┘
63
+ │
64
+ ┌──────────┴──────────┐
65
+ │ Coding agent │
66
+ │ (pluggable — see §6)│
67
+ └──────────────────────┘
68
+ ```
69
+
70
+ Everything except the coding agent call runs locally. Nothing is ever written to disk
71
+ without an explicit accept from the user. The agent is the only party that ever leaves the
72
+ machine, and only with the exact context the CLI assembled for it.
73
+
74
+ ## 4. Browser layer (capture only)
75
+
76
+ Responsibilities, and _only_ these:
77
+
78
+ - Render the floating toolbar (idle / select-mode / selection-active states).
79
+ - Lasso or click select. Match elements by **center-point containment**, not bounding-box
80
+ overlap (overlap over-selects parents whose edge merely brushes the lasso rect).
81
+ - Resolve each selected DOM node to a `data-source` attribute (file, line, component name)
82
+ injected by the dev-time build plugin. Where no plugin is present, fall back to React's
83
+ `_debugSource` fiber data.
84
+ - Take a screenshot of the selection (`html2canvas`) — visual context measurably improves
85
+ edit quality even when the AI has the source.
86
+ - Show the inline prompt box anchored to the selection (never a blocking `prompt()`).
87
+ - Render the diff/accept/undo UI once the CLI streams a proposed change back.
88
+ - **Never mutate the DOM.** All visual changes the user sees post-edit come from the
89
+ framework's own HMR reload, not from this layer.
90
+
91
+ Transport: a persistent **WebSocket** to the local CLI (`src/cli/bridge.ts`), not one-shot
92
+ `fetch` calls — this lets the CLI push streaming diff previews and error states back
93
+ without polling.
94
+
95
+ ## 5. Local CLI (the coordinator)
96
+
97
+ A Node process that wraps the user's existing dev server. Entry: `src/cli/index.ts`.
98
+
99
+ ### 5.1 Responsibilities
100
+
101
+ 1. Detect framework/bundler on `npx lasso` (`src/cli/utils/framework.ts` reads
102
+ `vite.config.*`, `next.config.*`, `package.json`).
103
+ 2. Spawn the dev server programmatically with the source-mapping plugin injected in memory
104
+ (`src/cli/server/vite.ts`, `src/cli/server/next.ts`) — the user's own config files are
105
+ never touched on disk.
106
+ 3. Host the WebSocket bridge (`src/cli/bridge.ts`) the browser overlay connects to.
107
+ 4. On a selection + instruction: read the referenced source file(s), assemble context
108
+ (source snippet, imports, relevant CSS/Tailwind config, screenshot, instruction), and
109
+ hand it to the coding agent (§6).
110
+ 5. Hold the returned diff in memory and stream it to the browser for preview — never write
111
+ on receipt.
112
+ 6. On accept: snapshot the file's prior content (for undo), then apply the diff.
113
+ 7. On undo: restore the snapshot, full stop — no re-generation needed, so retries are free.
114
+
115
+ ### 5.2 Source resolution strategies
116
+
117
+ | Setup | Method |
118
+ | ----------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
119
+ | Vite (React/Vue/Svelte/Solid) | Native Vite plugin, spawned via `createServer()` — injects `data-source` attrs at transform time. No config file edits. |
120
+ | Next.js | React's `_debugSource` fiber data, read at runtime — no build plugin needed, slightly less precise (nearest component boundary, not exact JSX line). |
121
+ | Webpack-only / CRA / Angular | **Not supported in v1.** The CLI should say so explicitly rather than fail silently. |
122
+
123
+ ### 5.3 Diff format
124
+
125
+ The agent returns **old-string/new-string pairs**, not a full-file rewrite. Full-file
126
+ regeneration risks silently dropping code the model wasn't told about; a targeted
127
+ find-and-replace is deterministic and safe to apply mechanically.
128
+
129
+ ### 5.4 Multi-instance handling
130
+
131
+ Editing a component's source file affects every rendered instance, since the source is
132
+ shared. This is usually correct, but the UI should say so explicitly at accept-time
133
+ ("this edits the component template — affects N instances on this page") so it never feels
134
+ like the tool did something unexpected.
135
+
136
+ ## 6. Coding agent — pluggable, not hardcoded
137
+
138
+ Lasso ships its own default agent, but the CLI's job is to assemble _context_, not to be
139
+ married to one model.
140
+
141
+ ```
142
+ context (source + screenshot + instruction)
143
+ │
144
+ ▼
145
+ ┌───────────────┐
146
+ │ Agent adapter │ interface: given context, return old/new string pairs
147
+ └───────┬───────┘
148
+ │
149
+ ┌──────┼───────────────────┬─────────────────────┐
150
+ ▼ ▼ ▼ ▼
151
+ Built-in Claude Code User's own CLI coding Any future
152
+ agent (headless/ agent (Cursor CLI, adapter
153
+ (default) `claude -p`) Aider, etc.)
154
+ ```
155
+
156
+ - **Built-in agent** (`agent: "builtin"`): default path, zero setup, calls a hosted model
157
+ directly (`@anthropic-ai/sdk`) with the assembled context and the old/new-string contract
158
+ from §5.3.
159
+ - **Claude Code passthrough** (`agent: "claude-code"`): the CLI shells out to Claude Code
160
+ in headless/print mode (`claude -p`), passing the assembled context as the prompt and
161
+ parsing its file edits back into the same diff-preview pipeline. This lets a user keep
162
+ using their existing Claude Code setup (subscription, project memory, MCP tools) while
163
+ still getting the point-and-select UX.
164
+ - **Bring-your-own-agent** (`agent: "custom"`): define the adapter interface once (context
165
+ in, old/new-string pairs out) and let power users wire in whatever CLI coding tool they
166
+ already trust. Lasso's value in this mode is entirely the capture + context-assembly
167
+ pipeline (§4–5), not the model itself.
168
+
169
+ Selection is a config choice, not an either/or product decision:
170
+
171
+ ```json
172
+ // lasso.config.json (before `lasso init`)
173
+ {
174
+ "agent": "builtin" // | "claude-code" | "custom"
175
+ }
176
+
177
+ // lasso.config.json (after `lasso init` — id is the only project field)
178
+ {
179
+ "agent": "builtin",
180
+ "id": "proj_3f2a9c…" // workspace-scoped; commit it so teammates share the session
181
+ }
182
+ ```
183
+
184
+ ## 7. Realtime collaboration (optional)
185
+
186
+ The overlay also speaks to `collab-server` (a Socket.IO server in the monorepo) so
187
+ teammates can collaborate on the same running app. Identity is split across two
188
+ credentials: the **API key** (`lss_live_…` — who you are + which workspace) and
189
+ the **project id** (which Lasso project you're opening). The API key comes from
190
+ `LASSO_API_KEY`, or — after `lasso auth login` — from `~/.lasso/credentials.json`.
191
+ Startup flows:
192
+
193
+ ```text
194
+ 0) lasso auth login (once per machine, device-style OAuth)
195
+ │ auth.ts POSTs /auth/cli/start → prints + opens the verification URL
196
+ │ (web /oauth/continue/cli?code=…, cookie auth) → /auth/cli/confirm mints an API key
197
+ │ in the user's first ACTIVE workspace; auth.ts polls /auth/cli/status
198
+ ▼
199
+ the key is delivered exactly once and stored at ~/.lasso/credentials.json (0600)
200
+
201
+ 1) lasso init (once per repo, API-key auth)
202
+ │ project.ts POSTs the app manifest to /collab/projects/register
203
+ ▼
204
+ collab-server hashes the key → api_keys → derives the workspace → creates or
205
+ reuses the project there (idempotent by git remote/name). CLI writes
206
+ lasso.config.json = { "id": "proj_…" }. Key never touches disk.
207
+
208
+ 2) lasso dev (every run, API-key auth)
209
+ │ reads lasso.config.json, POSTs /collab/projects/:projectId/session
210
+ ▼
211
+ collab-server resolves key → workspace, verifies the project belongs to it
212
+ (else 403 → realtime disabled, local editing continues), authenticates the
213
+ session (uid === projectId).
214
+ ▼ bridge sends { collab: { projectId, realtimeUrl, name, workspaceId } } with `config`
215
+ ▼
216
+ overlay io(realtimeUrl) → session:join { sessionId: projectId }
217
+ ◀ session joins are gated: the browser user must own the session's workspace
218
+ ```
219
+
220
+ ### Element identity
221
+
222
+ Cross-user locks, comments, and spotlight key off a deterministic `elementKey`:
223
+
224
+ 1. `data-source` / `data-lasso-source` attribute (best — from the build plugin) → `attr:…`
225
+ 2. element `id` → `id:…`
226
+ 3. stable CSS path (an `nth-child` chain on the ancestors) → `css:…`
227
+
228
+ This is **not** the random per-click `selectionId`. Two browsers looking at the same
229
+ app derive the same key, so a lock acquired on "the hero heading" in one tab is visible
230
+ and enforceable in the other. The overlay keeps an `elementRegistry` mapping key → local
231
+ Element to re-highlight remote selections.
232
+
233
+ ### Flow pieces
234
+
235
+ - **Presence**: every joined socket emits `presence:update` (≈ every 30 s) with
236
+ `selection: { elementId, label, sourceHint }`; the server broadcasts
237
+ `presence:changed` snapshots. Only the selected element is synced (not raw
238
+ coordinates), which keeps the wire tiny and the boxes meaningful.
239
+ - **Lock mode**: before running an agent edit, the overlay `lock:acquire`s the
240
+ element. A `ok:false reason:"LOCKED"` ack means a teammate owns it → the edit is
241
+ blocked and a chip shows who. The lock is released when the edit is applied or
242
+ undone, and the client extends its held lock on the heartbeat.
243
+ - **Comments**: `comments:add` with `elementId` + `meta` (source hint, label,
244
+ position); the panel can filter to the current element or the whole session.
245
+ Replies nest under a root comment via `parentId`.
246
+ - **Spotlight**: clicking a presence avatar emits `collab:spotlight`; every tab
247
+ highlights the element (or the sender's own highlight) for ~2.6 s with a
248
+ "name → element" chip.
249
+ - **Voice**: P2P WebRTC mesh. `voice:join` returns existing peers; the newcomer
250
+ creates a peer connection per peer and offers; existing members answer. Media
251
+ never touches the server. Muting is a right-click on the (live) voice button.
252
+
253
+ Auth uses the app's own auth cookie (`withCredentials: true`) with `auth: { token }`
254
+ read from `document.cookie` as a fallback. That works on `localhost` because
255
+ cookie-origin and realtime-server-origin are same-site; production deployments keep
256
+ both on the same registrable domain (documented in the collab-server README).
257
+
258
+ ## 8. Lasso Host (local domains + app hosting)
259
+
260
+ Lasso Host turns every project into a first-class local URL. `lasso init` now also
261
+ generates a stable unique domain for the project (`{ "id": "proj_…", "domain": "…" }`),
262
+ so `http://app.lasso` maps to that project — no remembering ports, no manual
263
+ `npm run dev`.
264
+
265
+ - **Daemon**: `lasso daemon` starts a single-instance background process
266
+ (pid-guarded by holding the proxy port; extra invocations fail with
267
+ "already running"). Control endpoints under `/_host/*` (health, registry,
268
+ register, unregister, stop, restart). Logs to `~/.lasso/host/daemon.log`.
269
+ - **Proxy**: binds `127.0.0.1` only. Any request with a `*.lasso` Host header is
270
+ resolved through the registry and reverse-proxied to that project's dev server;
271
+ non-`.lasso` hosts get a 404, so nothing outside the namespace is served.
272
+ WebSocket upgrades (HMR) pass through the same path.
273
+ - **Auto-start**: a request to a stopped project spawns its dev server and waits
274
+ for readiness before proxying. Vite is launched programmatically
275
+ (`vite-host-entry.js`) with `*.lasso` allow-listed because Vite rejects unknown
276
+ Host headers; Next runs via `next dev --port`. Unknown frameworks report a clear
277
+ error rather than blindly running `npm run dev`. A crash guard stops restarts
278
+ after repeated immediate crashes.
279
+ - **DNS**: `*.lasso` resolves to `127.0.0.1` via a tiny UDP responder (A record;
280
+ NXDOMAIN outside the namespace). Platform config behind a `DomainResolver`
281
+ interface: macOS `/etc/resolver/lasso` (the only `sudo` step; the responder's
282
+ port is otherwise unprivileged), Linux systemd-resolved split-DNS, and Windows
283
+ hosts entries. The HTTP proxy runs on port 6766 and the HTTPS proxy on 6767,
284
+ so registered URLs are shown as `http://app.lasso:6766` unless DNS is installed.
285
+ - **Registry**: `~/.lasso/host/registry.json` (atomic write, `0600`) maps
286
+ domain → `{ projectId, directory, registeredAt }`. `lasso register` reuses an
287
+ existing registration for the same directory, never duplicates, and migrates
288
+ the old domain when a new one is given (also rewriting `lasso.config.json`).
289
+ - **Trust**: no API keys or source paths in project config; only registered
290
+ domains proxy; the daemon listens on loopback by default.
291
+
292
+ ## 9. Speech-to-Text & Voice Input Architecture
293
+
294
+ Lasso supports natural voice prompting in the prompt toolbar and voice dictation in component comment pins without requiring manual audio file management.
295
+
296
+ ```
297
+ ┌─────────────────────────────────────────────────────────────┐
298
+ │ Browser Overlay │
299
+ │ - MediaRecorder captures audio (WebM/Opus / WAV) │
300
+ │ - Reactive mic animation (.recording / .transcribing) │
301
+ │ - Base64 payload packaging │
302
+ └──────────────────────────────┬──────────────────────────────┘
303
+ │
304
+ ┌──────────────┴──────────────┐
305
+ │ Bridge WebSocket or Fetch │
306
+ └──────────────┬──────────────┘
307
+ ▼
308
+ ┌─────────────────────────────────────────────────────────────┐
309
+ │ Lasso Server /api/v1/transcribe (STTService) │
310
+ │ │
311
+ │ 1. Attempt Gradium ASR (POST api.gradium.ai/speech/asr) │
312
+ │ - Fast streaming NDJSON transcription │
313
+ │ - Credit check (402, 429, error signals) │
314
+ │ │
315
+ │ 2. Automatic Fallback to Deepgram (Nova-2) │
316
+ │ - Seamless failover if Gradium credits finish/fail │
317
+ │ - 15-minute cooldown before retrying Gradium │
318
+ └─────────────────────────────────────────────────────────────┘
319
+ ```
320
+
321
+ 1. **Client Capture**: `src/overlay/audio/transcribe.ts` starts an audio stream via `navigator.mediaDevices.getUserMedia({ audio: true })`. Chunks are gathered into a single blob on stop.
322
+ 2. **Transport**: The client transmits base64-encoded audio either over the local CLI bridge socket (`{ type: "transcribe" }`) or directly to the server REST API (`POST /api/v1/transcribe`), avoiding cross-origin complexities.
323
+ 3. **Provider Pooling**: The backend `sttService` attempts Gradium first. If Gradium responds with a credit exhaustion code (402, 429, or out-of-credit status), it transparently falls back to Deepgram Nova-2 and returns the transcribed text to the client.
324
+
325
+ ## 10. Open questions for v1
326
+
327
+ - Exact context window budget per request (full file vs. just the referenced function).
328
+ - Whether the diff-preview UI lives in the browser overlay only, or also as a terminal
329
+ side panel for the CLI.
330
+ - Rate limiting / cost guardrails when using a hosted default agent vs. a user's own
331
+ Claude Code subscription.
332
+ - Extending source resolution beyond Vite and Next.js (Webpack/CRA/Angular).
333
+
334
+ ## 11. Trust model
335
+
336
+ - **Telemetry-free by default.** Nothing about a user's source code leaves their machine
337
+ except what's explicitly sent to whichever agent they've configured.
338
+ - **No writes without accept.** Diffs live in memory until the user confirms; undo restores
339
+ a pre-edit snapshot.
340
+ - **Configs are never modified.** Build plugins are injected in memory via the CLI.
341
+
342
+ See `SECURITY.md` for how to report anything that breaks this model.
package/CHANGELOG.md ADDED
@@ -0,0 +1,102 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [Unreleased]
9
+
10
+ ### Added
11
+
12
+ - Open-source documentation: `CONTRIBUTING.md`, `CODE_OF_CONDUCT.md`,
13
+ `SECURITY.md`, `SUPPORT.md`, `LICENSE` (ISC), and this changelog.
14
+ - **Lasso Host** (`src/cli/host/`) — a user-level local domain server + runtime
15
+ that serves registered projects through `*.lasso` domains. New commands:
16
+ - `lasso daemon [start|status|stop|restart|install|uninstall]` — background
17
+ single-instance daemon (reverse HTTP **and WebSocket/HMR proxy**), persistent
18
+ project registry at `~/.lasso/host/registry.json`, always-bound `127.0.0.1`.
19
+ `install` adds a macOS LaunchAgent (auto-start at login) and configures the
20
+ local DNS resolver (`/etc/resolver/lasso` via `sudo`); `uninstall` reverses it.
21
+ - `lasso register [domain]` — register the current project under a `.lasso`
22
+ domain (or reuse/generate one), syncs `lasso.config.json`, and replaces the
23
+ previous domain when it changes. Re-registering never creates duplicates.
24
+ - `lasso projects` — list registered domains with running/stopped state.
25
+ - `lasso init` now also generates a unique local domain (derived from the
26
+ project directory name), registers it with Lasso Host, and writes
27
+ `{ "id": "proj_…", "domain": "app.lasso" }`.
28
+ - Auto-start on traffic: a request to a stopped project starts its dev server
29
+ (Vite launched programmatically with `.lasso` allow-listed, Next dev via
30
+ `next dev --port`), waits for readiness, then proxies — no manual
31
+ `npm run dev`. Crashing projects are guarded (no runaway restarts).
32
+ - DNS: a tiny UDP responder answers `*.lasso → 127.0.0.1` (NXDOMAIN outside
33
+ the namespace); the platform resolver abstraction covers macOS
34
+ (`/etc/resolver/lasso`), Linux (systemd-resolved split-DNS), and Windows
35
+ (per-domain hosts entries, best-effort). No API keys or arbitrary paths are
36
+ exposed — only registered domains are proxied.
37
+ - **`lasso auth` command group**: `lasso auth login` (browser OAuth — the CLI
38
+ prints/opens a verification URL, the logged-in dashboard user confirms, and the
39
+ CLI stores the minted API key in `~/.lasso/credentials.json` at `0600`),
40
+ `lasso auth status` (who's signed in + workspace + masked key), and
41
+ `lasso auth logout`. All credits feed `init`/`dev` automatically; `LASSO_API_KEY`
42
+ still overrides the stored credential.
43
+ - **`lasso init`**: registers the app with your Lasso workspace (API-key
44
+ authenticated) and writes `lasso.config.json` containing only the project id
45
+ (`{ "id": "proj_…" }`). Idempotent — re-running reuses the id; commit the file
46
+ so teammates share the same project. The API key is **not** stored in config.
47
+ - **`lasso dev` project session**: reads `lasso.config.json`, authenticates with
48
+ the API key (`LASSO_API_KEY` env / prompt), lets the realtime server resolve
49
+ the key → workspace → project and authenticate the project session. Renders
50
+ realtime collaboration unavailable (local editing unaffected) when there is no
51
+ config, no key, or the project belongs to another workspace.
52
+ - **Realtime collaboration in the overlay**: presence avatars with online/away
53
+ dots, click-an-avatar spotlight, remote selection rings, live teammate cursors
54
+ with custom user colors and name badges, and a live activity strip.
55
+ - **Live multiplayer cursors**: broadcast cursor movement via Socket.IO presence,
56
+ rendering smoothed remote pointers for teammates in real time.
57
+ - **Component lock mode in the UI**: taking a suggestion acquires a lock on the
58
+ selected element; teammates see a refined "Locked by …" badge and the edit is
59
+ blocked until release or expiry.
60
+ - **Speech-to-Text (STT) voice input & dictation**:
61
+ - Interactive microphone button in the prompt card with animated listening and
62
+ transcribing states.
63
+ - Voice dictation button in the comment compose bar.
64
+ - Client-side audio recording module (`src/overlay/audio/transcribe.ts`) using
65
+ the `MediaRecorder` API.
66
+ - Multi-provider pooling via the backend server: primary transcription via
67
+ Gradium (`api.gradium.ai`), with automatic failover to Deepgram (`api.deepgram.com`)
68
+ when credits finish or errors occur.
69
+ - CLI bridge support for local `transcribe` and `transcribe_result` relay.
70
+ - **Comments panel**: thread comments anchored to the selected element (or whole
71
+ session), reply/resolve/reopen/delete, attachments, GIFs, and voice dictation.
72
+ - **Clipboard & Snippets panel**: manage, copy, and share frequently used code
73
+ snippets, design tokens, and references with private and shared tabs.
74
+ - **Voice chat**: P2P WebRTC mesh — join from the toolbar, mute with a right-click
75
+ while live.
76
+ - CLI → overlay `config` message carries `collab: { projectId, realtimeUrl,
77
+ name, version, workspaceId }` so the overlay can join the right (workspace-
78
+ gated) session. The bridge only forwards a config it successfully authenticated.
79
+
80
+ ## [0.1.0] - 2026-09-21
81
+
82
+ ### Added
83
+
84
+ - `lasso` CLI with `dev` command (default). Detects Vite or Next.js and starts the
85
+ dev server with the Lasso overlay attached.
86
+ - Browser overlay: floating toolbar, select mode (click or lasso), center-point
87
+ element matching, inline prompt box, diff preview with accept/undo.
88
+ - WebSocket bridge (`startBridge`) connecting the overlay to the local CLI.
89
+ - Source mapping: Vite build plugin (`data-source` attributes, exact JSX lines);
90
+ Next.js via React `_debugSource` fiber data.
91
+ - Pluggable agent adapters: `builtin` (Anthropic), `claude-code` (headless
92
+ passthrough), and `custom` — selectable via `lasso.config.json`.
93
+ - In-memory diff contract: old-string/new-string pairs, no disk writes until accept.
94
+
95
+ ### Fixed
96
+
97
+ - Nothing yet — 0.1.0 is the initial release of the working-name Lasso.
98
+
99
+ ### Notes
100
+
101
+ - Version 0.1.0 was developed as an internal prototype. This changelog records
102
+ behavior from that point forward. The project uses the product name **Lasso**.
@@ -0,0 +1,129 @@
1
+ # Contributor Covenant Code of Conduct
2
+
3
+ ## Our Pledge
4
+
5
+ We as members, contributors, and leaders pledge to make participation in our
6
+ community a harassment-free experience for everyone, regardless of age, body
7
+ size, visible or invisible disability, ethnicity, sex characteristics, gender
8
+ identity and expression, level of experience, education, socio-economic status,
9
+ nationality, personal appearance, race, religion, or sexual identity
10
+ and orientation.
11
+
12
+ We pledge to act and interact in ways that contribute to an open, welcoming,
13
+ diverse, inclusive, and healthy community.
14
+
15
+ ## Our Standards
16
+
17
+ Examples of behavior that contributes to a positive environment for our
18
+ community include:
19
+
20
+ * Demonstrating empathy and kindness toward other people
21
+ * Being respectful of differing opinions, viewpoints, and experiences
22
+ * Giving and gracefully accepting constructive feedback
23
+ * Accepting responsibility and apologizing to those affected by our mistakes,
24
+ and learning from the experience
25
+ * Focusing on what is best not just for us as individuals, but for the
26
+ overall community
27
+
28
+ Examples of unacceptable behavior include:
29
+
30
+ * The use of sexualized language or imagery, and sexual attention or
31
+ advances of any kind
32
+ * Trolling, insulting or derogatory comments, and personal or political attacks
33
+ * Public or private harassment
34
+ * Publishing others' private information, such as a physical or email
35
+ address, without their explicit permission
36
+ * Other conduct which could reasonably be considered inappropriate in a
37
+ professional setting
38
+
39
+ ## Enforcement Responsibilities
40
+
41
+ Community leaders are responsible for clarifying and enforcing our standards of
42
+ acceptable behavior and will take appropriate and fair corrective action in
43
+ response to any behavior that they deem inappropriate, threatening, offensive,
44
+ or harmful.
45
+
46
+ Community leaders have the right and responsibility to remove, edit, or reject
47
+ comments, commits, code, wiki edits, issues, and other contributions that are
48
+ not aligned to this Code of Conduct, and will communicate reasons for moderation
49
+ decisions when appropriate.
50
+
51
+ ## Scope
52
+
53
+ This Code of Conduct applies within all community spaces, and also applies when
54
+ an individual is officially representing the community in public spaces.
55
+ Examples of representing our community include using an official e-mail address,
56
+ posting via an official social media account, or acting as an appointed
57
+ representative at an online or offline event.
58
+
59
+ ## Enforcement
60
+
61
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
62
+ reported to the community leaders responsible for enforcement at
63
+ [security@example.com](mailto:security@example.com).
64
+
65
+ All complaints will be reviewed and investigated promptly and fairly.
66
+
67
+ All community leaders are obligated to respect the privacy and security of the
68
+ reporter of any incident.
69
+
70
+ ## Enforcement Guidelines
71
+
72
+ Community leaders will follow these Community Impact Guidelines in determining
73
+ the consequences for any action they deem in violation of this Code of Conduct:
74
+
75
+ ### 1. Correction
76
+
77
+ **Community Impact**: Use of inappropriate language or other behavior deemed
78
+ unprofessional or unwelcome in the community.
79
+
80
+ **Consequence**: A private, written warning from community leaders, providing
81
+ clarity around the nature of the violation and an explanation of why the
82
+ behavior was inappropriate. A public apology may be requested.
83
+
84
+ ### 2. Warning
85
+
86
+ **Community Impact**: A violation through a single incident or series of
87
+ actions.
88
+
89
+ **Consequence**: A warning with consequences for continued behavior. No
90
+ interaction with the people involved, including unsolicited interaction with
91
+ those enforcing the Code of Conduct, for a specified period of time. This
92
+ includes avoiding interactions in community spaces as well as external channels
93
+ like social media. Violating these terms may lead to a temporary or permanent
94
+ ban.
95
+
96
+ ### 3. Temporary Ban
97
+
98
+ **Community Impact**: A serious violation of community standards, including
99
+ sustained inappropriate behavior.
100
+
101
+ **Consequence**: A temporary ban from any sort of interaction or public
102
+ communication with the community for a specified period of time. No public or
103
+ private interaction with the people involved, including unsolicited interaction
104
+ with those enforcing the Code of Conduct, is allowed during this period.
105
+ Violating these terms may lead to a permanent ban.
106
+
107
+ ### 4. Permanent Ban
108
+
109
+ **Community Impact**: Demonstrating a pattern of violation of community
110
+ standards, including sustained inappropriate behavior, harassment of an
111
+ individual, or aggression toward or disparagement of classes of individuals.
112
+
113
+ **Consequence**: A permanent ban from any sort of public interaction within
114
+ the community.
115
+
116
+ ## Attribution
117
+
118
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage],
119
+ version 2.1, available at
120
+ https://www.contributor-covenant.org/version/2/1/code_of_conduct.html.
121
+
122
+ Community Impact Guidelines were inspired by
123
+ [Mozilla's code of conduct enforcement ladder](https://github.com/mozilla/diversity).
124
+
125
+ [homepage]: https://www.contributor-covenant.org
126
+
127
+ For answers to common questions about this code of conduct, see the FAQ at
128
+ https://www.contributor-covenant.org/faq. Translations are available at
129
+ https://www.contributor-covenant.org/translations.