Skip to content

Commit 3a6b79a

Browse files
Merge pull request #32 from New1Direction/feat/brand-identity
feat(brand): Mono Ink identity — Vee-eye icon + scan animation, default theme, voice
2 parents 85a569b + ea020a6 commit 3a6b79a

31 files changed

Lines changed: 3565 additions & 45 deletions

CHANGELOG.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,17 @@ Every release of RepoLens, newest first. Want the friendly highlights instead of
44
the full detail? See **[What's new](README.md)** in the README.
55

66
This project follows [Semantic Versioning](https://semver.org/) and groups changes
7-
by theme. Dates are when the release landed on `main` 1.1.0 through 1.6.0 shipped
7+
by theme. Dates are when the release landed on `main`. 1.1.0 through 1.6.0 shipped
88
the same day, as a rapid burst of improvements, so they share a date.
99

1010
## [Unreleased]
1111

1212
### Added
1313

14+
- **Mono Ink identity.** RepoLens ships a new dark-tile lens icon, a "Mono Ink" default theme (cool near-black, white, and cobalt), and a wordmark lockup. The toolbar icon now animates only while a scan runs: the aperture grows and spins and the ring breathes grey to blue, then it resets to static. Turn the animation off in **Options**, and it honors your OS reduced-motion setting. The other 13 themes stay one click away.
15+
- **A warmer Vee.** Vee's onboarding copy reads like a person now. The repo also vendors the stop-slop writing standard under `docs/style/` so the voice stays consistent.
1416
- **Vee-guided first-run walkthrough.** New users are met by Vee on their first Library open; the coachmark steps through a seeded demo repo (Library card → Verdict tab → Blueprint canvas) with plain narration and a spotlight on each target element. Implemented in `onboarding.js` / `coachmark.js`; copy lives in `onboarding-copy.js`.
15-
- **Milestone "power tour"** offered after approximately five real scans: a second coachmark sequence introducing the cross-library tools Ask, Corkboard (Alternatives / Synergies), multi-select Compare, Radar / auto-organize, and Discover.
17+
- **Milestone "power tour"** offered after approximately five real scans: a second coachmark sequence introducing the cross-library tools: Ask, Corkboard (Alternatives / Synergies), multi-select Compare, Radar / auto-organize, and Discover.
1618

1719
---
1820

README.md

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
<div align="center">
22

3-
# 🔭 RepoLens
3+
# RepoLens
44

5-
### One click opens the case file on any repo.
5+
### Click any repo. Get a straight answer on whether to use it.
66

7-
**The verdict · the evidence · the red flags · how it's actually built — in plain English, before the README's pitch.**
7+
**The verdict, the evidence, the red flags, and how it's built. In plain English, before the README's pitch.**
88

99
![Chrome Manifest V3](https://img.shields.io/badge/Chrome-Manifest_V3-1a73e8?logo=googlechrome&logoColor=white)
1010
![Zero build](https://img.shields.io/badge/build-none-0e1722)
@@ -17,9 +17,9 @@
1717

1818
---
1919

20-
RepoLens is a **Manifest V3 Chrome extension**. Land on a GitHub, GitLab, npm, or PyPI page, click the toolbar icon, and it reads the repo, runs it past the AI provider of your choice, and opens a tab with a **verdict-first** breakdown — it opens with a straight answer (*should you use this?*) before any prose, not the README's marketing.
20+
RepoLens is a **Manifest V3 Chrome extension**. Open a GitHub, GitLab, npm, or PyPI page and click the toolbar icon. RepoLens reads the repo, runs it past the AI provider you picked, and opens a tab that leads with a straight answer: should you use this? You see the verdict before any of the README's pitch.
2121

22-
> Stars tell you a project is popular. They don't tell you whether it fits *your* problem. RepoLens answers the question you actually have: **should I use this, and what am I signing up for?**
22+
> Stars tell you a project is popular. They don't tell you whether it fits your problem. RepoLens answers the question you have: should I use this, and what am I signing up for?
2323
2424
---
2525

@@ -41,7 +41,7 @@ A scan opens to a **verdict landing** and fans out into focused tabs:
4141

4242
Plus **SKTPG** (a one-tap State / Known-pitfalls / Trajectory / Proof / Growth read), framework lenses, and capability re-tagging.
4343

44-
**First run:** Vee walks new users through a seeded demo repo (Library Verdict Blueprint) via a coachmark tour. After roughly five real scans a second "power tour" introduces the cross-library tools: Ask, Corkboard analysis, multi-select compare, Radar, and Discover.
44+
**First run:** Vee, the lens mascot, walks you through a seeded demo repo (Library, then Verdict, then Blueprint) with a short coachmark tour. After about five real scans, a second power tour shows you the cross-library tools: Ask, Corkboard, multi-select compare, Radar, and Discover.
4545

4646
---
4747

@@ -61,7 +61,7 @@ A correctness, security, and tooling pass from a full code audit — fixes only,
6161
### v1.7.0 — Boards, Vee & a motion pass
6262

6363
- 🗂️ **Collections ("Boards").** Group the repos you're evaluating together and filter the Library by board — with live counts, per-card membership dots, and a one-click assignment popover. Boards travel in your library export/import.
64-
- 🔭 **Meet "Vee", an optional lens mascot** that reacts to your scans (scanning, wide-open on a strong fit, eyes-narrowed on a risky one, resting on an empty library). One theme-aware SVG, reduced-motion-safe; turn it off in **Options → Interface**.
64+
- **Meet Vee, an optional lens mascot** that reacts to your scans: scanning, wide-open on a strong fit, narrowed on a risky one, resting on an empty library. One theme-aware SVG, reduced-motion safe. Turn it off in **Options → Interface**.
6565
-**Subtle motion, everywhere it helps** — tactile press states, a staged tab reveal, a verdict health-bar fill, a smoother toast and modal — all respecting reduced-motion.
6666
- 🧭 **Errors that tell you what to do** — a failed scan now offers **Open Settings** (bad key / wrong model) or **Retry** (transient), and the loading copy names the provider it's actually using.
6767

@@ -119,15 +119,15 @@ No accounts. No backend. Your keys, your machine.
119119

120120
## Models — your keys, your call
121121

122-
Bring your own provider. Five are **first-class** (one-click sign-in where the vendor allows it**Grok**, **OpenRouter**, and **OpenAI/ChatGPT** otherwise an API key; **Claude** is API-key only) and fan out across a **smart fallback chain**: RepoLens tries them in order and drops to the next if one errors, so a single key is enough to start.
122+
Bring your own provider. Five are **first-class** (one-click sign-in where the vendor allows it: **Grok**, **OpenRouter**, and **OpenAI/ChatGPT**; otherwise an API key; **Claude** is API-key only) and fan out across a **smart fallback chain**: RepoLens tries them in order and drops to the next if one errors, so a single key is enough to start.
123123

124124
**Nous** (Nous Research) **→ Gemini → OpenRouter → Grok → Anthropic**
125125

126-
On top of those, RepoLens works with **almost any other AI service** through one registry**OpenAI, DeepSeek, Groq, NVIDIA NIM, Kimi (Moonshot), Zhipu GLM, Qwen (Aliyun), Xiaomi MiMo, Volcengine Ark, Ollama Cloud, MiniMax, Azure OpenAI**, local **Ollama** (no key needed), and a universal **Custom** endpoint. Each keeps its **own key** (switching never loses data), has a model picker, an optional **endpoint override**, and built-in **connection / function self-tests**. Connect just one and it works — it joins the fallback chain automatically.
126+
On top of those, RepoLens works with **almost any other AI service** through one registry: **OpenAI, DeepSeek, Groq, NVIDIA NIM, Kimi (Moonshot), Zhipu GLM, Qwen (Aliyun), Xiaomi MiMo, Volcengine Ark, Ollama Cloud, MiniMax, Azure OpenAI**, local **Ollama** (no key needed), and a universal **Custom** endpoint. Each keeps its **own key** (switching never loses data), has a model picker, an optional **endpoint override**, and built-in **connection / function self-tests**. Connect just one and it works. It joins the fallback chain automatically.
127127

128-
> **Sign in with ChatGPT.** The OpenAI card also offers a one-click **ChatGPT login**the same OAuth the **Codex CLI** uses so you can connect without pasting a key (it needs API access on your ChatGPT plan; otherwise paste a key).
128+
> **Sign in with ChatGPT.** The OpenAI card also offers a one-click **ChatGPT login**, the same OAuth the **Codex CLI** uses, so you can connect without pasting a key (it needs API access on your ChatGPT plan; otherwise paste a key).
129129
130-
> Local-only? Point at **Ollama** on `localhost` — no key, no cloud. (Spawning a local *CLI* binary like `claude`/`codex` still isn't possiblea browser extension is sandboxed and can't launch a program — but it can do those CLIs' **OAuth logins**, and talk to a local HTTP model server like Ollama.)
130+
> Local-only? Point at **Ollama** on `localhost`. No key, no cloud. (Spawning a local *CLI* binary like `claude`/`codex` still isn't possible: a browser extension is sandboxed and can't launch a program. But it can do those CLIs' **OAuth logins**, and talk to a local HTTP model server like Ollama.)
131131
132132
Each provider has a model dropdown (★ marks the recommended pick), and you can **route each part of a scan to a different model**:
133133

@@ -139,9 +139,9 @@ Any per-part pick still falls back to the full chain if that provider errors or
139139

140140
## Storage — nothing to install
141141

142-
Your whole library lives **in the browser** (IndexedDB). No database, no daemon, no setup — it works the moment you load the extension, and it's Web-Store-ready.
142+
Your whole library lives **in the browser** (IndexedDB). No database, no daemon, no setup. It works the moment you load the extension, and it's Web-Store-ready.
143143

144-
Because it's *your* data, you can take it with you: **Library → Export** writes your whole library analyzed repos, the semantic graph, and the local scan cacheto one portable JSON file, and **Import** restores it (merge or replace) on any machine. Backups are validated and bounded on import, so a bad file fails safe. Your settings travel too: **Options → Back up your settings** exports your theme, voice, model picks and per-part routing never your API keys.
144+
Because it's *your* data, you can take it with you: **Library → Export** writes your whole library (analyzed repos, the semantic graph, and the local scan cache) to one portable JSON file, and **Import** restores it (merge or replace) on any machine. Backups are validated and bounded on import, so a bad file fails safe. Your settings travel too: **Options → Back up your settings** exports your theme, voice, model picks and per-part routing, but never your API keys.
145145

146146
Migrating from an old VelesDB server? **Options → Import from VelesDB** pulls your library across in one click.
147147

assets/wordmark.svg

Lines changed: 19 additions & 0 deletions
Loading

background.js

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ import { buildFitsStackPrompt, parseFitsStack } from './fits-stack.js';
6464
import { buildStackPrompt, parseStack } from './stack-prompt.js';
6565
import { buildAskRepoPrompt, parseAskRepoAnswer } from './ask-repo.js';
6666
import { buildComparePrompt, parseCompareResult } from './compare-repos.js';
67+
import { startScanAnim, stopScanAnim } from './icon-anim.js';
6768

6869
// Notify when a scan completes — clicking the notification focuses the result tab.
6970
chrome.notifications.onClicked.addListener(async (notifId) => {
@@ -199,7 +200,7 @@ chrome.runtime.onMessage.addListener((msg, sender, sendResponse) => {
199200
.set({ [msg.sessionKey]: { loading: true, status: 'fetching', ...detected } })
200201
.then(() => {
201202
sendResponse({ ok: true });
202-
runAnalysis(msg.sessionKey, detected); // fire and forget; tab polls the session
203+
runAnalysis(msg.sessionKey, detected, sender.tab?.id); // fire and forget; tab polls the session
203204
})
204205
.catch((err) => sendResponse({ ok: false, error: err?.message || 'Could not start the scan' }));
205206
return true; // keep the message channel open for the async sendResponse
@@ -555,7 +556,7 @@ chrome.action.onClicked.addListener(async (tab) => {
555556
// Open the output tab immediately with a loading state, then run the analysis.
556557
await chrome.storage.session.set({ [sessionKey]: { loading: true, status: 'fetching', ...detected } });
557558
await chrome.tabs.create({ url: `output-tab.html?key=${sessionKey}` });
558-
runAnalysis(sessionKey, detected);
559+
runAnalysis(sessionKey, detected, tab.id);
559560
});
560561

561562
// Every provider credential + model-selector key, read together wherever an AI
@@ -645,14 +646,15 @@ async function runBatchScan(batchKey, urls) {
645646
}
646647

647648
// Fetch → AI → parse → store. Used by the initial click and by RERUN (retry).
648-
async function runAnalysis(sessionKey, detected) {
649+
async function runAnalysis(sessionKey, detected, tabId) {
649650
// Load every provider credential + model + routing in one read; pass the whole
650651
// object to callAI so registry (compat) providers are reachable too — not just
651652
// the five first-class ones. Extra keys (autoSave/tone) are ignored downstream.
652653
const settings = await chrome.storage.local.get([...PROVIDER_KEYS, 'autoSave', 'tone']);
653654
const { autoSave = true, tone } = settings;
654655

655656
try {
657+
startScanAnim(tabId); // fire-and-forget; no-ops without a tabId / when disabled / reduced motion
656658
// Snapshot the previous cached analysis for diff comparison (before it's overwritten).
657659
const prevCached = await getCached(detected.platform, detected.repoId).catch(() => null);
658660

@@ -749,7 +751,9 @@ async function runAnalysis(sessionKey, detected) {
749751
});
750752
} catch { /* notifications are best-effort */ }
751753

754+
stopScanAnim(tabId); // success: reset to the static icon
752755
} catch (err) {
756+
stopScanAnim(tabId); // error: reset to the static icon
753757
// AI failures already carry a humanized message + kind; other failures (fetch,
754758
// parse) get classified here so the tab can still route the error CTA.
755759
const errorKind = err.kind || categorizeError(err).kind;

docs/style/README.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Writing standard
2+
3+
RepoLens copy follows **stop-slop** (Hardik Pandya's de-slop ruleset), vendored in
4+
[`stop-slop/`](stop-slop/SKILL.md). It is the standard for product copy and docs:
5+
Vee's onboarding lines, the README, the CHANGELOG, and any future store-listing or
6+
website copy.
7+
8+
The short version: cut filler openers and adverbs, write active voice with a human
9+
subject, name the specific thing, vary sentence rhythm, no em dashes, no emoji on
10+
product surfaces. Score a draft against the rubric in
11+
[`stop-slop/SKILL.md`](stop-slop/SKILL.md); below 35/50, revise.

docs/style/stop-slop/SKILL.md

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
---
2+
name: stop-slop
3+
description: Remove AI writing patterns from prose. Use when drafting, editing, or reviewing text to eliminate predictable AI tells.
4+
metadata:
5+
trigger: Writing prose, editing drafts, reviewing content for AI patterns
6+
author: Hardik Pandya (https://hvpandya.com)
7+
---
8+
9+
# Stop Slop
10+
11+
Eliminate predictable AI writing patterns from prose.
12+
13+
## Core Rules
14+
15+
1. **Cut filler phrases.** Remove throat-clearing openers, emphasis crutches, and all adverbs. See [references/phrases.md](references/phrases.md).
16+
17+
2. **Break formulaic structures.** Avoid binary contrasts, negative listings, dramatic fragmentation, rhetorical setups, false agency. See [references/structures.md](references/structures.md).
18+
19+
3. **Use active voice.** Every sentence needs a human subject doing something. No passive constructions. No inanimate objects performing human actions ("the complaint becomes a fix").
20+
21+
4. **Be specific.** No vague declaratives ("The reasons are structural"). Name the specific thing. No lazy extremes ("every," "always," "never") doing vague work.
22+
23+
5. **Put the reader in the room.** No narrator-from-a-distance voice. "You" beats "People." Specifics beat abstractions.
24+
25+
6. **Vary rhythm.** Mix sentence lengths. Two items beat three. End paragraphs differently. No em dashes.
26+
27+
7. **Trust readers.** State facts directly. Skip softening, justification, hand-holding.
28+
29+
8. **Cut quotables.** If it sounds like a pull-quote, rewrite it.
30+
31+
## Quick Checks
32+
33+
Before delivering prose:
34+
35+
- Any adverbs? Kill them.
36+
- Any passive voice? Find the actor, make them the subject.
37+
- Inanimate thing doing a human verb ("the decision emerges")? Name the person.
38+
- Sentence starts with a Wh- word? Restructure it.
39+
- Any "here's what/this/that" throat-clearing? Cut to the point.
40+
- Any "not X, it's Y" contrasts? State Y directly.
41+
- Three consecutive sentences match length? Break one.
42+
- Paragraph ends with punchy one-liner? Vary it.
43+
- Em-dash anywhere? Remove it.
44+
- Vague declarative ("The implications are significant")? Name the specific implication.
45+
- Narrator-from-a-distance ("Nobody designed this")? Put the reader in the scene.
46+
- Meta-joiners ("The rest of this essay...")? Delete. Let the essay move.
47+
48+
## Scoring
49+
50+
Rate 1-10 on each dimension:
51+
52+
| Dimension | Question |
53+
|-----------|----------|
54+
| Directness | Statements or announcements? |
55+
| Rhythm | Varied or metronomic? |
56+
| Trust | Respects reader intelligence? |
57+
| Authenticity | Sounds human? |
58+
| Density | Anything cuttable? |
59+
60+
Below 35/50: revise.
61+
62+
## Examples
63+
64+
See [references/examples.md](references/examples.md) for before/after transformations.
65+
66+
## License
67+
68+
MIT

0 commit comments

Comments
 (0)