Skip to content

Declared visitors card + crawlproof actors extension (CLI 0.5.0) - #342

Merged
ralyodio merged 2 commits into
masterfrom
feat/declared-card-and-extension
Oct 4, 2026
Merged

ralyodio merged 2 commits into
masterfrom
feat/declared-card-and-extension

Conversation

@ralyodio

@ralyodio ralyodio commented Oct 4, 2026

Copy link
Copy Markdown
Contributor

Follow-up to #339 / #341.

Dashboard. The project stats page gets a Declared visitors card after the headline tiles: declared humans and agents (actors, pageviews, events), contradictions in red, and a table of named actors. Names only for the viewer's own actors or public ones, through declaredSummary (the same filter as the API). With nothing declared it's one muted line linking to Settings → Declared actors. Hidden if the actor tables can't be read.

crawlproof actors extension <email|id> [--out] [--label] mints a token and writes an unpacked MV3 extension (lib/tracker/declareExtension.ts). Its single declarativeNetRequest rule sets Crawlproof-Actor on <base>/api/track only (left-anchored on the origin), so an agent's browser declares itself with no code change and the sites it visits never see the token. Folder 0700, files 0600, README with load instructions for Chromium, Puppeteer, Playwright and chrome-devtools-mcp.

Fix: actors revoke --token=<id> collided with the CLI-wide --token (API key override), so the token id was sent as the bearer → 401 "Malformed token". It's now --token-id. Broken since 0.4.0.

Docs: extension section on /docs/statistics, including the branded-Chrome-137+ caveat. @profullstack/crawlproof 0.4.0 → 0.5.0 (publish after merge).

Checks: tsc clean; vitest 218 files / 2753 tests. New: rule scoping, MV3 permissions, self-hosted base, refusal of non-token / non-http base, files written private, regression through the package's real parseArgs/apiToken. End to end against production: generated the extension for riotcoder with the built CLI, loaded it in Chrome for Testing, opened crawlproof.com → riotcoder's count went 3 → 4 and the token showed as used. Test token revoked with the fixed --token-id.

🤖 Generated with Claude Code

… (CLI 0.5.0)

Dashboard: the project stats page gets a "Declared visitors" card after
the headline tiles: declared humans / agents, contradictions in red, and
named actors (only the viewer's own or public ones, via declaredSummary,
the same filter the API uses). With nothing declared it is one muted line
linking to Settings -> Declared actors.

CLI: `crawlproof actors extension <email|id> [--out] [--label]` mints a
token and writes an unpacked MV3 extension (lib/tracker/declareExtension)
whose single declarativeNetRequest rule sets Crawlproof-Actor on
<base>/api/track only, so an agent's browser declares itself without a
code change and the sites it visits never see the token. Verified end to
end: generated for riotcoder, loaded in Chrome for Testing, the visit
counted on the actor.

Fix: `actors revoke --token=<id>` collided with the CLI-wide --token
(API key override) and was sent as the bearer: 401 "Malformed token".
Now --token-id. Broken since 0.4.0.

Docs: the extension, how to load it, and the branded-Chrome caveat.
@profullstack/crawlproof 0.4.0 -> 0.5.0.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Comment thread tests/tracker-declare-extension.test.ts Fixed
@github-actions

github-actions Bot commented Oct 4, 2026 •

Copy link
Copy Markdown

ThreatCrush Security Scan

49 finding(s)

HIGH/CRITICAL: 2 | MEDIUM: 32 | LOW: 15

Severity Rule Location
HIGH tls-verification-disabled lib/onion.ts:48
HIGH secret-generic-credential lib/sp/platforms/facebook.ts:32
MEDIUM js-unescaped-html-sink app/(app)/dashboard/admin/email-broadcast/EmailBroadcastForm.tsx:125
MEDIUM js-unescaped-html-sink app/(app)/dashboard/projects/[id]/autoblog/articles/[articleId]/page.tsx:214
MEDIUM js-unescaped-html-sink app/(marketing)/blog/[slug]/page.tsx:67
MEDIUM js-unescaped-html-sink app/(marketing)/blog/[slug]/page.tsx:97
MEDIUM js-unescaped-html-sink app/(marketing)/blog/[slug]/page.tsx:104
MEDIUM js-unescaped-html-sink app/(marketing)/blog/[slug]/page.tsx:110
MEDIUM js-unescaped-html-sink app/(marketing)/recent/page.tsx:186
MEDIUM js-unescaped-html-sink app/(marketing)/recent/page.tsx:190
MEDIUM js-unescaped-html-sink app/c/[project]/[slug]/page.tsx:77
MEDIUM js-unescaped-html-sink app/c/[project]/page.tsx:57
MEDIUM js-unescaped-html-sink app/careers.js/route.ts:228
MEDIUM js-unescaped-html-sink app/careers.js/route.ts:285
MEDIUM js-unescaped-html-sink app/layout.tsx:129
MEDIUM js-open-redirect app/login/form.tsx:39
MEDIUM js-unescaped-html-sink app/r/[token]/page.tsx:176
MEDIUM js-open-redirect app/signup/form.tsx:43
MEDIUM js-open-redirect components/billing/buy-credits-modal.tsx:98
MEDIUM js-unescaped-html-sink components/json-ld.tsx:8
MEDIUM js-unescaped-html-sink components/report/markdown-view.tsx:15
MEDIUM js-unescaped-html-sink lib/careers/page-templates.ts:198
MEDIUM js-dynamic-code-execution lib/crawl-limits.ts:67
MEDIUM redos-nested-quantifier lib/emailMarkdown.ts:41
MEDIUM redos-nested-quantifier lib/emailMarkdown.ts:324
MEDIUM redos-nested-quantifier lib/lx/articleGen.ts:99
MEDIUM redos-nested-quantifier lib/tracker/agent-gate.ts:61
MEDIUM sh-predictable-temp-path ops/selfhost/server/setup-supabase.sh:218
MEDIUM sh-remote-script-execution prober/deploy/provision.sh:30
MEDIUM sql-template-interpolation scripts/detect-slot-themes.ts:31
MEDIUM sql-template-interpolation scripts/purge-constructed-keywords.ts:163
MEDIUM sql-template-interpolation scripts/purge-offniche-keywords.ts:124
MEDIUM js-dynamic-code-execution scripts/test-crawl-limits.mjs:14
MEDIUM js-dynamic-code-execution scripts/test-crawl-limits.mjs:24
LOW secret-generic-credential app/(marketing)/docs/autoblog-webhook/page.tsx:145
LOW secret-generic-credential lib/sp/platforms/linkedin.ts:25
LOW js-dynamic-code-execution tests/careers-page-templates.test.ts:21
LOW js-dynamic-code-execution tests/careers-widget-script.test.ts:19
LOW js-dynamic-code-execution tests/careers-widget-script.test.ts:69
LOW js-dynamic-code-execution tests/contract/ad-visitor-id.test.ts:51
LOW js-dynamic-code-execution tests/contract/ad-visitor-id.test.ts:52
LOW js-dynamic-code-execution tests/contract/ads-click-cooldown-redis.test.ts:20
LOW js-dynamic-code-execution tests/contract/ads-click-cooldown-redis.test.ts:24
LOW js-dynamic-code-execution tests/contract/ads-click-cooldown-redis.test.ts:25
LOW js-dynamic-code-execution tests/contract/ads-click-cooldown-redis.test.ts:26
LOW js-dynamic-code-execution tests/contract/ads-click-cooldown-redis.test.ts:31
LOW js-dynamic-code-execution tests/contract/ads-click-cooldown-redis.test.ts:35
LOW secret-generic-credential tests/contract/posthog-integration.test.ts:13
LOW secret-generic-credential tests/lead-campaign.test.ts:16

Snippets are redacted; ThreatCrush never prints matched credential material.

ThreatCrush flagged the regression test's fixture as a hardcoded
credential. It never was one; constructing it the way the rest of the
suite does keeps the scanner signal clean without a dismissal.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@ralyodio
ralyodio merged commit e7e40a7 into master Oct 4, 2026
10 checks passed
@ralyodio
ralyodio deleted the feat/declared-card-and-extension branch October 4, 2026 15:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants