← back to Secrets Manager
[overnight] pre-debate baseline
05d62f1f7a15464efb06eecfabf7a8d669720d59 · 2026-05-04 01:46:00 -0700 · SteveStudio2
Files touched
A .auto-ingest-stateA .clipboard-last-hashA .gitignoreA CHANGES.mdA audit-2026-04-30.txtA auto-ingest.launchd.errA auto-ingest.launchd.outA auto-ingest.shA cli.jsA clipboard-watcher.launchd.errA clipboard-watcher.launchd.outA clipboard-watcher.shA registry.jsonA routes.json
Diff
commit 05d62f1f7a15464efb06eecfabf7a8d669720d59
Author: SteveStudio2 <stevestudio2@SteveStacStudio.lan>
Date: Mon May 4 01:46:00 2026 -0700
[overnight] pre-debate baseline
---
.auto-ingest-state | 1 +
.clipboard-last-hash | 1 +
.gitignore | 29 +++
CHANGES.md | 16 ++
audit-2026-04-30.txt | 308 ++++++++++++++++++++++++++
auto-ingest.launchd.err | 0
auto-ingest.launchd.out | 0
auto-ingest.sh | 51 +++++
cli.js | 346 +++++++++++++++++++++++++++++
clipboard-watcher.launchd.err | 1 +
clipboard-watcher.launchd.out | 0
clipboard-watcher.sh | 106 +++++++++
registry.json | 252 +++++++++++++++++++++
routes.json | 500 ++++++++++++++++++++++++++++++++++++++++++
14 files changed, 1611 insertions(+)
diff --git a/.auto-ingest-state b/.auto-ingest-state
new file mode 100644
index 0000000..c306804
--- /dev/null
+++ b/.auto-ingest-state
@@ -0,0 +1 @@
+e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
diff --git a/.clipboard-last-hash b/.clipboard-last-hash
new file mode 100644
index 0000000..eb44834
--- /dev/null
+++ b/.clipboard-last-hash
@@ -0,0 +1 @@
+1202ead3e469a9d4ad57d4735c0becce30a3fa4d26cc614b9f3a96abb7762af5
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..f2506d9
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,29 @@
+# secrets / env
+.env
+.env.*
+!.env.example
+*.session-secret
+*.private-key
+
+# python
+__pycache__/
+*.pyc
+*.pyo
+venv/
+.venv/
+
+# node
+node_modules/
+npm-debug.log*
+yarn-debug.log*
+
+# build artifacts
+dist/
+build/
+.next/
+*.log
+
+# editor / OS
+.DS_Store
+.idea/
+.vscode/
diff --git a/CHANGES.md b/CHANGES.md
new file mode 100644
index 0000000..9238f5d
--- /dev/null
+++ b/CHANGES.md
@@ -0,0 +1,16 @@
+## Applied
+- None — no P0/P1 item in `CODEX_REVIEW.md` matched the approved autonomous safe-fix set closely enough to edit without broader operational risk.
+
+## Deferred (needs Steve)
+- P0 — `audit-2026-04-30.txt:1` — 307 secret-looking leaks across external projects/skills — requires secret rotation and cleanup outside this project.
+- P0 — `auto-ingest.sh:31` / `auto-ingest.sh:51` — failed imports are swallowed before state hash is saved — reliability behavior change outside approved safe list.
+- P0 — `auto-ingest.sh:42` — pipeline can be launched repeatedly without a lock — needs owner decision on launch semantics/idempotency.
+- P0 — `cli.js:68` / `cli.js:104` — SSH accepts first-seen host keys — needs host key pinning details from Steve.
+- P0 — `routes.json:198` / `routes.json:315` / `routes.json:336` — prod secrets fan out to remote `root` — needs deploy user and remote ownership changes.
+- P1 — `cli.js:225` / `cli.js:257` — batch import exits on first invalid token — control-flow refactor not in approved safe list.
+- P1 — `clipboard-watcher.launchd.err:1` / `supervisor.log:23` — Desktop access is blocked under launchd — needs Full Disk Access or workflow relocation.
+- P1 — `clipboard-watcher.log:6` / `clipboard-watcher.sh:36` / `auto-ingest.sh:31` — inconsistent Node executable path — environment/install decision needed.
+- P1 — `cli.js:33` / `cli.js:59` / `cli.js:210` — writes are non-atomic — broader file-write helper change not in approved safe list.
+- P1 — `cli.js:64` — remote read SSH failure is treated as empty env — behavior change risks remote overwrite semantics.
+- P1 — `clipboard-watcher.sh:60` — prefixless clipboard token classifiers may verify arbitrary strings — needs UX decision for confirmation/context.
+- P1 — `cli.js:312` — audit skips all `.env` files globally — needs policy for managed vs committed env files.
diff --git a/audit-2026-04-30.txt b/audit-2026-04-30.txt
new file mode 100644
index 0000000..edac2b6
--- /dev/null
+++ b/audit-2026-04-30.txt
@@ -0,0 +1,308 @@
+audit: 307 finding(s):
+ google-api-key /Users/stevestudio2/.claude/skills/maya-romanoff-scraper-manager/SKILL.md:82 …ejMo
+ google-api-key /Users/stevestudio2/.claude/skills/enrich-ai-tags/SKILL.md:99 …ejMo
+ google-api-key /Users/stevestudio2/.claude/skills/reels-producer/SKILL.md:378 …S2ic
+ google-api-key /Users/stevestudio2/.claude/skills/_archived/interior-design-tagger/SKILL.md:14 …ejMo
+ google-api-key /Users/stevestudio2/.claude/skills/_archived/interior-design-tagger/SKILL.md:19 …ejMo
+ google-api-key /Users/stevestudio2/.claude/skills/_archived/residential-wallpaper-updater/SKILL.md:47 …ejMo
+ google-api-key /Users/stevestudio2/.claude/skills/resize-it/SKILL.md:89 …ejMo
+ google-api-key /Users/stevestudio2/.claude/skills/ai-analyzer/SKILL.md:15 …ejMo
+ google-api-key /Users/stevestudio2/.claude/skills/ai-analyzer/SKILL.md:32 …ejMo
+ google-api-key /Users/stevestudio2/.claude/skills/commercial-room-setting-generator/SKILL.md:47 …S2ic
+ google-api-key /Users/stevestudio2/.claude/skills/commercial-room-setting-generator/SKILL.md:53 …S2ic
+ google-api-key /Users/stevestudio2/.claude/skills/commercial-room-setting-generator/SKILL.md:111 …ejMo
+ cf-token-40hex /Users/stevestudio2/.claude/skills/setup-domains/SKILL.md:327 …lYcL
+ google-api-key /Users/stevestudio2/Projects/Bertha/kalshi-dash/server.js:130 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Letsbegin/nina_full_monty.js:25 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Letsbegin/ani_full_monty.js:18 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Letsbegin/fix_rew_products.js:147 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Letsbegin/fix_rew_products.js:186 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Letsbegin/app/api/processes/fix/route.ts:7 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Letsbegin/app/api/processes/analyze/route.ts:6 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Letsbegin/app/api/claude/suggest/route.ts:6 …ejMo
+ anthropic-key /Users/stevestudio2/Projects/Letsbegin/app/api/ralph/run/route.ts:175 …7AAA
+ anthropic-key /Users/stevestudio2/Projects/Letsbegin/app/api/ralph/run/route.ts:245 …7AAA
+ anthropic-key /Users/stevestudio2/Projects/Letsbegin/app/api/ralph/continue/route.ts:74 …7AAA
+ anthropic-key /Users/stevestudio2/Projects/Letsbegin/app/api/ralph/continue/route.ts:137 …7AAA
+ google-api-key /Users/stevestudio2/Projects/Letsbegin/app/api/ralph/convert/route.ts:6 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Letsbegin/app/api/url-info/route.ts:4 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Letsbegin/app/api/prd/clarify/route.ts:4 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Letsbegin/app/api/prd/generate/route.ts:8 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Letsbegin/sequin_full_monty.js:16 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Letsbegin/glitter_full_monty.js:22 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Letsbegin/retro_full_monty.js:25 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Letsbegin/sequin_monty_noimages.js:7 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Letsbegin/lib/gemini-image.ts:7 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Letsbegin/croppy_glm.js:31 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Letsbegin/sequin_colors_titles.js:7 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Letsbegin/nina_names_colors.js:6 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Letsbegin/CLAUDE.md:24 …ejMo
+ stripe-publishable /Users/stevestudio2/Projects/wine-finder/COMPLETE_SYSTEM_SUMMARY.md:38 …XgkJ
+ stripe-publishable /Users/stevestudio2/Projects/wine-finder/COMPLETE_SYSTEM_SUMMARY.md:174 …XgkJ
+ stripe-publishable /Users/stevestudio2/Projects/wine-finder/COMPLETE_SYSTEM_SUMMARY.md:351 …XgkJ
+ anthropic-key /Users/stevestudio2/Projects/dear-bubbe-nextjs/VOICE_IMPLEMENTATION_SUMMARY.md:81 …3wAA
+ anthropic-key /Users/stevestudio2/Projects/dear-bubbe-nextjs/docs/SYSTEM.md:48 …3wAA
+ anthropic-key /Users/stevestudio2/Projects/dear-bubbe-nextjs/ecosystem.config.js:10 …5wAA
+ anthropic-key /Users/stevestudio2/Projects/dear-bubbe-nextjs/CLAUDE.md:50 …3wAA
+ anthropic-key /Users/stevestudio2/Projects/dear-bubbe-nextjs/VOICE_CHAT_ANALYSIS.md:286 …hgAA
+ anthropic-key /Users/stevestudio2/Projects/dear-bubbe-nextjs/VOICE_CHAT_ANALYSIS.md:291 …tQAA
+ google-api-key /Users/stevestudio2/Projects/SDCC-Stories/lib/gemini.js:8 …ejMo
+ google-api-key /Users/stevestudio2/Projects/SDCC-Stories/lib/gemini.js:9 …S2ic
+ google-api-key /Users/stevestudio2/Projects/sku-check-skill/server.js:25 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Kamatera/DW-Programming/room-setting-app/data/gallery/renders.json:48 …ft7H
+ google-api-key /Users/stevestudio2/Projects/Kamatera/DW-Programming/room-setting-app/data/gallery/renders.json:114 …rzmE
+ anthropic-key /Users/stevestudio2/Projects/Kamatera/dear-bubbe-nextjs/VOICE_IMPLEMENTATION_SUMMARY.md:81 …3wAA
+ anthropic-key /Users/stevestudio2/Projects/Kamatera/dear-bubbe-nextjs/docs/SYSTEM.md:48 …3wAA
+ anthropic-key /Users/stevestudio2/Projects/Kamatera/dear-bubbe-nextjs/ecosystem.config.js:10 …5wAA
+ anthropic-key /Users/stevestudio2/Projects/Kamatera/dear-bubbe-nextjs/CLAUDE.md:50 …3wAA
+ anthropic-key /Users/stevestudio2/Projects/Kamatera/dear-bubbe-nextjs/VOICE_CHAT_ANALYSIS.md:286 …hgAA
+ anthropic-key /Users/stevestudio2/Projects/Kamatera/dear-bubbe-nextjs/VOICE_CHAT_ANALYSIS.md:291 …tQAA
+ slack-bot /Users/stevestudio2/Projects/Kamatera/Designer-Wallcoverings-scripts/activate-koroseal-cron.js:11 …pmsq
+ slack-bot /Users/stevestudio2/Projects/Kamatera/Designer-Wallcoverings-scripts/activate-arte-cron.js:12 …pmsq
+ github-fine-grained /Users/stevestudio2/Projects/Kamatera/goodquestion-ai/.claude/settings.local.json:38 …n43k
+ google-oauth-access /Users/stevestudio2/Projects/Kamatera/goodquestion-ai/.youtube-token.json:2 …0207
+ cf-token-40hex /Users/stevestudio2/Projects/Kamatera/kamatera-claude-skills/setup-domains/SKILL.md:327 …lYcL
+ google-oauth-access /Users/stevestudio2/Projects/Kamatera/Norma/scripts/search-sacbee.js:11 …0207
+ anthropic-key /Users/stevestudio2/Projects/Kamatera/DW-Agents/bob-the-blogger/server.js:33 …cgAA
+ slack-bot /Users/stevestudio2/Projects/Kamatera/DW-Agents/scripts/slack-bulk-delete.js:23 …c1a7
+ slack-bot /Users/stevestudio2/Projects/Kamatera/DW-Agents/scripts/slack-bulk-delete.js:24 …pmsq
+ slack-bot /Users/stevestudio2/Projects/Kamatera/DW-Agents/scripts/slack-bulk-delete.js:25 …7AHQ
+ slack-bot /Users/stevestudio2/Projects/Kamatera/DW-Agents/slack-dm-viewer/server.js:34 …7AHQ
+ slack-bot /Users/stevestudio2/Projects/Kamatera/DW-Agents/slack-dm-viewer/server.js:36 …pmsq
+ slack-bot /Users/stevestudio2/Projects/Kamatera/DW-Agents/slack-dm-viewer/server.js:40 …c1a7
+ anthropic-key /Users/stevestudio2/Projects/Kamatera/DW-Agents/thibaut-agent/server.js:17 …cgAA
+ google-api-key /Users/stevestudio2/Projects/resize-it/SKILL.md:89 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Designer-Wallcoverings/gemini-enrich-arte.js:4 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Designer-Wallcoverings/COMPLETED-PROCESSES.md:190 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Designer-Wallcoverings/ai-enrich-arte-fix.js:4 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Designer-Wallcoverings/enrich-remaining-13.js:5 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Designer-Wallcoverings/gemini-enrich-gaps.js:5 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Designer-Wallcoverings/enrich-arte-gaps.js:4 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Designer-Wallcoverings/gemini-enrich-arte9.js:4 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Designer-Wallcoverings/brand-router/server.js:13 …S2ic
+ anthropic-key /Users/stevestudio2/Projects/Designer-Wallcoverings/DW-Programming/KravetDesignTagger/server.js:12 …9QAA
+ google-api-key /Users/stevestudio2/Projects/Designer-Wallcoverings/DW-Programming/hollywood-hex-and-tags.js:17 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Designer-Wallcoverings/DW-Programming/activate-versace-vi.js:20 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Designer-Wallcoverings/DW-Programming/enrich-launched-products.py:9 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Designer-Wallcoverings/DW-Programming/interior-design-ai-tagger.js:26 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Designer-Wallcoverings/DW-Programming/anna-french-ai-enrich.js:18 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Designer-Wallcoverings/DW-Programming/gls-product-processor.js:18 …ejMo
+ slack-bot /Users/stevestudio2/Projects/Designer-Wallcoverings/DW-Programming/ImportNewSkufromURL/universal-completion-notifier.ts:9 …pmsq
+ slack-bot /Users/stevestudio2/Projects/Designer-Wallcoverings/DW-Programming/ImportNewSkufromURL/dwjs-ai-retag.ts:24 …pmsq
+ anthropic-key /Users/stevestudio2/Projects/Designer-Wallcoverings/DW-Programming/ImportNewSkufromURL/dwjs-ai-retag.ts:21 …7QAA
+ anthropic-key /Users/stevestudio2/Projects/Designer-Wallcoverings/DW-Programming/ImportNewSkufromURL/fix-all-dwpd-colors.ts:15 …tAAA
+ anthropic-key /Users/stevestudio2/Projects/Designer-Wallcoverings/DW-Programming/ImportNewSkufromURL/fix-dwjs-red-tags.ts:17 …tAAA
+ anthropic-key /Users/stevestudio2/Projects/Designer-Wallcoverings/DW-Programming/ImportNewSkufromURL/fix-color-tags.ts:14 …tAAA
+ google-api-key /Users/stevestudio2/Projects/Designer-Wallcoverings/DW-Programming/ImportNewSkufromURL/dwjs-interior-design-update.js:22 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Designer-Wallcoverings/DW-Programming/ImportNewSkufromURL/dwjs-comprehensive-update.ts:21 …ejMo
+ google-oauth-access /Users/stevestudio2/Projects/Designer-Wallcoverings/DW-Programming/ImportNewSkufromURL/dw-gmail-token.json:2 …0206
+ google-api-key /Users/stevestudio2/Projects/Designer-Wallcoverings/DW-Programming/ImportNewSkufromURL/scripts/koroseal-enrichment.ts:18 …ejMo
+ anthropic-key /Users/stevestudio2/Projects/Designer-Wallcoverings/DW-Programming/ImportNewSkufromURL/scripts/koroseal-enrichment.ts:17 …7QAA
+ google-api-key /Users/stevestudio2/Projects/Designer-Wallcoverings/DW-Programming/ImportNewSkufromURL/scripts/rwltd-gemini-cron.js:12 …ejMo
+ anthropic-key /Users/stevestudio2/Projects/Designer-Wallcoverings/DW-Programming/ImportNewSkufromURL/fix-lod-descriptions.ts:15 …tAAA
+ slack-bot /Users/stevestudio2/Projects/Designer-Wallcoverings/DW-Programming/ImportNewSkufromURL/lib/slack-notify.ts:7 …pmsq
+ google-api-key /Users/stevestudio2/Projects/Designer-Wallcoverings/DW-Programming/ImportNewSkufromURL/dwjs-interior-design-update.ts:22 …ejMo
+ google-oauth-access /Users/stevestudio2/Projects/Designer-Wallcoverings/DW-Programming/ImportNewSkufromURL/gmail-token.json:2 …0206
+ anthropic-key /Users/stevestudio2/Projects/Designer-Wallcoverings/DW-Programming/ImportNewSkufromURL/tag-dwpd-ai.ts:17 …tAAA
+ google-api-key /Users/stevestudio2/Projects/Designer-Wallcoverings/DW-Programming/ImportNewSkufromURL/CLAUDE.md:8 …ejMo
+ anthropic-key /Users/stevestudio2/Projects/Designer-Wallcoverings/DW-Programming/RemoveDuplicatesInShopify/test-tagging.ts:11 …tAAA
+ anthropic-key /Users/stevestudio2/Projects/Designer-Wallcoverings/DW-Programming/RemoveDuplicatesInShopify/tag-schumacher-products.ts:17 …tAAA
+ anthropic-key /Users/stevestudio2/Projects/Designer-Wallcoverings/DW-Programming/RemoveDuplicatesInShopify/recrawl-all-tags.js:7 …7AAA
+ anthropic-key /Users/stevestudio2/Projects/Designer-Wallcoverings/DW-Programming/RemoveDuplicatesInShopify/auto-tag-groups.js:7 …7AAA
+ anthropic-key /Users/stevestudio2/Projects/Designer-Wallcoverings/DW-Programming/RemoveDuplicatesInShopify/server.js:9 …7AAA
+ google-api-key /Users/stevestudio2/Projects/Designer-Wallcoverings/DW-Programming/phase3-ai-enrich-batch.js:16 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Designer-Wallcoverings/DW-Programming/room-setting-app/app/api/analyze-pattern/route.ts:4 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Designer-Wallcoverings/DW-Programming/room-setting-app/lib/gemini-room-generator.ts:891 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Designer-Wallcoverings/DW-Programming/room-setting-app/lib/gemini-room-generator.ts:1347 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Designer-Wallcoverings/DW-Programming/room-setting-app/data/gallery/renders.json:48 …ft7H
+ google-api-key /Users/stevestudio2/Projects/Designer-Wallcoverings/DW-Programming/room-setting-app/data/gallery/renders.json:114 …rzmE
+ google-api-key /Users/stevestudio2/Projects/Designer-Wallcoverings/DW-Programming/room-setting-app/ecosystem.config.js:12 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Designer-Wallcoverings/DW-Programming/gls-gemini-retry.js:12 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Designer-Wallcoverings/DW-Programming/color-collection-cleaner.js:15 …S2ic
+ google-api-key /Users/stevestudio2/Projects/Designer-Wallcoverings/DW-Programming/maya-romanoff-updater/server.js:30 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Designer-Wallcoverings/DW-Programming/maya-romanoff-updater/maya-romanoff-updater.js:24 …ejMo
+ anthropic-key /Users/stevestudio2/Projects/Designer-Wallcoverings/DW-Programming/ThibautTagger/server.js:12 …9QAA
+ google-api-key /Users/stevestudio2/Projects/Designer-Wallcoverings/DW-Programming/phase3-ai-enrich-batch.py:18 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Designer-Wallcoverings/DW-Programming/china-seas-hex-colors.js:16 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Designer-Wallcoverings/DW-Programming/ralph-lauren-fabric-updater-9899.ts:26 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Designer-Wallcoverings/DW-Programming/phase3-ai-enrich-run.js:11 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Designer-Wallcoverings/DW-Programming/hex-color-blitz.js:25 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Designer-Wallcoverings/DW-Programming/PhillipeRomanoTagger/server.js:87 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Designer-Wallcoverings/DW-Programming/zoffany-ai-enrich.js:19 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Designer-Wallcoverings/DW-Programming/nextjs-liquid-app/app/api/bulk-import/route.ts:6 …S2ic
+ google-api-key /Users/stevestudio2/Projects/Designer-Wallcoverings/DW-Programming/nextjs-liquid-app/app/api/analyze-image/route.ts:3 …S2ic
+ google-api-key /Users/stevestudio2/Projects/Designer-Wallcoverings/DW-Programming/nextjs-liquid-app/app/api/analyze-image/route.ts:4 …ejMo
+ anthropic-key /Users/stevestudio2/Projects/Designer-Wallcoverings/DW-Programming/update-specific-schumacher.ts:13 …7QAA
+ google-api-key /Users/stevestudio2/Projects/Designer-Wallcoverings/DW-Programming/prl-ai-enrich.js:20 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Designer-Wallcoverings/DW-Programming/phase3-ai-enrichment.js:15 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Designer-Wallcoverings/DW-Programming/activate-versace-drafts.js:12 …ejMo
+ anthropic-key /Users/stevestudio2/Projects/Designer-Wallcoverings/DW-Programming/LINCRUSTA_PROJECT_MEMORY.md:138 …tAAA
+ google-api-key /Users/stevestudio2/Projects/Designer-Wallcoverings/DW-Programming/ShopifyCalendarNext/scripts/rescan-scheduled-posts.ts:3 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Designer-Wallcoverings/DW-Programming/ShopifyCalendarNext/src/app/api/generate-ai-content/route.ts:3 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Designer-Wallcoverings/DW-Programming/ShopifyCalendarNext/src/app/api/analyze-product/route.ts:14 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Designer-Wallcoverings/DW-Programming/phase3-ai-enrich-100.js:17 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Designer-Wallcoverings/DW-Programming/ralph-lauren-fabric-updater-9899.js:27 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Designer-Wallcoverings/DW-Programming/china-seas-design-tagger.js:13 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Designer-Wallcoverings/DW-Programming/interior-design-tagger.js:32 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Designer-Wallcoverings/DW-Programming/gls-retry-failed.js:12 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Designer-Wallcoverings/DW-Programming/CLAUDE.md:10 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Designer-Wallcoverings/DW-Programming/hollywood-hex-extract.js:4 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Designer-Wallcoverings/DW-Programming/fix-blue-collection.js:13 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Designer-Wallcoverings/DW-Programming/gls-product-cleanup.js:19 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Designer-Wallcoverings/DW-Programming/gls-product-updater.js:19 …ejMo
+ anthropic-key /Users/stevestudio2/Projects/Designer-Wallcoverings/DW-Programming/schumacher-dwsw-full-updater.ts:19 …7QAA
+ google-api-key /Users/stevestudio2/Projects/Designer-Wallcoverings/DW-Programming/phase3-ai-enrich-batch.sh:6 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Designer-Wallcoverings/enrich-arte-puppeteer.js:5 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Designer-Wallcoverings/arte-fill-tags.js:5 …ejMo
+ slack-bot /Users/stevestudio2/Projects/Designer-Wallcoverings/DW-Skills/architectural-vendor-update.md:594 …oken
+ google-api-key /Users/stevestudio2/Projects/Designer-Wallcoverings/shopify/scripts/update-dwrr-descriptions-quantities.ts:14 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Designer-Wallcoverings/shopify/scripts/zoffany-full-monty-20.js:35 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Designer-Wallcoverings/shopify/scripts/update-dwqw-complete.ts:15 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Designer-Wallcoverings/shopify/scripts/update-dwk-full-details.js:15 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Designer-Wallcoverings/shopify/scripts/arte-dashboard/server.js:1555 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Designer-Wallcoverings/shopify/scripts/koroseal-complete-update.ts:14 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Designer-Wallcoverings/shopify/scripts/update-koroseal-gemini.ts:11 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Designer-Wallcoverings/shopify/scripts/koroseal-batch-cron.js:16 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Designer-Wallcoverings/shopify/scripts/review-dwqw-images-descriptions.ts:15 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Designer-Wallcoverings/shopify/scripts/koroseal-update.js:14 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Designer-Wallcoverings/shopify/scripts/texture-repeat-fixer.js:19 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Designer-Wallcoverings/shopify/scripts/gemini-catalog-tagger.js:21 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Designer-Wallcoverings/shopify/scripts/update-dwrr-gemini.ts:13 …ejMo
+ slack-bot /Users/stevestudio2/Projects/Designer-Wallcoverings/shopify/scripts/activate-koroseal-cron.js:11 …pmsq
+ google-api-key /Users/stevestudio2/Projects/Designer-Wallcoverings/shopify/scripts/update-all-malibu-architectural.ts:30 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Designer-Wallcoverings/shopify/scripts/batch-room-settings/batch-room-generator.js:25 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Designer-Wallcoverings/shopify/scripts/batch-room-settings/batch-room-generator.js:26 …S2ic
+ google-api-key /Users/stevestudio2/Projects/Designer-Wallcoverings/shopify/scripts/koroseal-enhanced-update.js:66 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Designer-Wallcoverings/shopify/scripts/prl-ai-enrich.js:8 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Designer-Wallcoverings/shopify/scripts/update-dwk-slow-seo.js:17 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Designer-Wallcoverings/shopify/scripts/import-missing-dwrr.ts:11 …ejMo
+ slack-bot /Users/stevestudio2/Projects/Designer-Wallcoverings/shopify/scripts/activate-arte-cron.js:12 …pmsq
+ google-api-key /Users/stevestudio2/Projects/Designer-Wallcoverings/shopify/scripts/classify-texture-pattern.js:10 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Designer-Wallcoverings/shopify/scripts/gemini-tag-engine/index.js:17 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Designer-Wallcoverings/shopify/scripts/interior-design-tagger.js:19 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Designer-Wallcoverings/shopify/scripts/bespoke-updater/server.js:24 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Designer-Wallcoverings/shopify/scripts/update-dwqw-malibu-architectural.ts:16 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Designer-Wallcoverings/shopify/scripts/set-texture-repeat-zero.js:19 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Designer-Wallcoverings/output/us-007-implementation-summary.md:223 …ejMo
+ slack-bot /Users/stevestudio2/Projects/Designer-Wallcoverings/DW-MCP/wine-tracker-config.md:18 …pmsq
+ slack-bot /Users/stevestudio2/Projects/Designer-Wallcoverings/DW-MCP/README.md:45 …oken
+ slack-bot /Users/stevestudio2/Projects/Designer-Wallcoverings/DW-MCP/DW-Hooks/API-HOOKS.md:1065 …oken
+ slack-bot /Users/stevestudio2/Projects/Designer-Wallcoverings/DW-MCP/mcp-config.json:26 …oken
+ google-api-key /Users/stevestudio2/Projects/Designer-Wallcoverings/gemini-classify-texture.js:6 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Designer-Wallcoverings/enrich-arte-fix.js:4 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Designer-Wallcoverings/scripts/enrich-remaining-13.js:16 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Designer-Wallcoverings/scripts/ai-enrich-arte-gaps.js:10 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Designer-Wallcoverings/scripts/justindavid-room-settings.js:23 …S2ic
+ google-api-key /Users/stevestudio2/Projects/Designer-Wallcoverings/scripts/ai-enrich-gaps.js:12 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Designer-Wallcoverings/scripts/ralph/prd-ralph-lauren-fabrics.json:63 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Designer-Wallcoverings/scripts/brand-mckenzie-full-update.ts:16 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Designer-Wallcoverings/scripts/brand-mckenzie-full-scrape.ts:12 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Designer-Wallcoverings/scripts/texture-repeat-classifier.js:13 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Designer-Wallcoverings/scripts/prl-ai-enrich.js:10 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Designer-Wallcoverings/scripts/collection-description-writer.js:13 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Designer-Wallcoverings/scripts/rw-drapery-room-settings.js:18 …S2ic
+ slack-bot /Users/stevestudio2/Projects/Designer-Wallcoverings/scripts/activate-koroseal-product.js:12 …pmsq
+ google-api-key /Users/stevestudio2/Projects/Designer-Wallcoverings/scripts/interior-design-tags.js:28 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Designer-Wallcoverings/scripts/brand-mckenzie-ai-analysis.ts:11 …ejMo
+ slack-bot /Users/stevestudio2/Projects/Designer-Wallcoverings/scripts/lib/slack-progress-notify.ts:8 …pmsq
+ google-api-key /Users/stevestudio2/Projects/Designer-Wallcoverings/scripts/us-007-ai-product-quality-analyzer.ts:15 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Designer-Wallcoverings/scripts/US-007-USAGE.md:86 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Designer-Wallcoverings/ai-enrich-gaps2.js:5 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Designer-Wallcoverings/CLAUDE.md:298 …ejMo
+ slack-bot /Users/stevestudio2/Projects/Designer-Wallcoverings/DW-Agents/ecosystem.config.js:45 …pmsq
+ slack-bot /Users/stevestudio2/Projects/Designer-Wallcoverings/DW-Agents/ecosystem.config.js:494 …7AHQ
+ anthropic-key /Users/stevestudio2/Projects/Designer-Wallcoverings/DW-Agents/ecosystem.config.js:92 …cgAA
+ anthropic-key /Users/stevestudio2/Projects/Designer-Wallcoverings/DW-Agents/ecosystem.config.js:114 …cgAA
+ anthropic-key /Users/stevestudio2/Projects/Designer-Wallcoverings/DW-Agents/ecosystem.config.js:154 …cgAA
+ anthropic-key /Users/stevestudio2/Projects/Designer-Wallcoverings/DW-Agents/ecosystem.config.js:174 …cgAA
+ anthropic-key /Users/stevestudio2/Projects/Designer-Wallcoverings/DW-Agents/ecosystem.config.js:235 …cgAA
+ anthropic-key /Users/stevestudio2/Projects/Designer-Wallcoverings/DW-Agents/ecosystem.config.js:496 …cgAA
+ slack-bot /Users/stevestudio2/Projects/Designer-Wallcoverings/DW-Agents/dw-agents/melanie-slack-bot/README.md:92 …here
+ anthropic-key /Users/stevestudio2/Projects/Designer-Wallcoverings/DW-Agents/dw-agents/agent-security/security-agent.ts:53 …tAAA
+ anthropic-key /Users/stevestudio2/Projects/Designer-Wallcoverings/DW-Agents/dw-agents/agent-zendesk-chat/zendesk-chat-agent.ts:41 …tAAA
+ anthropic-key /Users/stevestudio2/Projects/Designer-Wallcoverings/DW-Agents/dw-agents/zendesk-chat-agent.ts:29 …tAAA
+ slack-bot /Users/stevestudio2/Projects/Designer-Wallcoverings/DW-Agents/dw-agents/agent-task-orchestrator/ecosystem.config.js:43 …pmsq
+ anthropic-key /Users/stevestudio2/Projects/Designer-Wallcoverings/DW-Agents/dw-agents/agent-purchasing-office/purchasing-office-agent.ts:39 …tAAA
+ anthropic-key /Users/stevestudio2/Projects/Designer-Wallcoverings/DW-Agents/dw-agents/get-amazon-api-credentials.sh:81 …tAAA
+ slack-bot /Users/stevestudio2/Projects/Designer-Wallcoverings/DW-Agents/dw-agents/agent-new-client-signup/new-client-signup-agent.ts:37 …oken
+ slack-bot /Users/stevestudio2/Projects/Designer-Wallcoverings/DW-Agents/dw-agents/agent-new-client-signup/new-client-signup-agent-v1.0.ts:20 …oken
+ slack-bot /Users/stevestudio2/Projects/Designer-Wallcoverings/DW-Agents/dw-agents/digital-samples-agent.ts:46 …pmsq
+ slack-bot /Users/stevestudio2/Projects/Designer-Wallcoverings/DW-Agents/dw-agents/versions/v1.1.110725/ecosystem.config.js:43 …pmsq
+ slack-bot /Users/stevestudio2/Projects/Designer-Wallcoverings/DW-Agents/dw-agents/agent-digital-samples/digital-samples-agent.ts:56 …pmsq
+ google-api-key /Users/stevestudio2/Projects/Designer-Wallcoverings/DW-Agents/dw-agents/agent-thibaut-updater/thibaut-updater-agent.ts:50 …ejMo
+ slack-bot /Users/stevestudio2/Projects/Designer-Wallcoverings/DW-Agents/dw-agents/slack-integration.ts:252 …here
+ google-api-key /Users/stevestudio2/Projects/Designer-Wallcoverings/DW-Agents/dw-agents/ecosystem-complete.config.js:185 …ejMo
+ anthropic-key /Users/stevestudio2/Projects/Designer-Wallcoverings/DW-Agents/dw-agents/marketing-agent.ts:133 …cgAA
+ slack-bot /Users/stevestudio2/Projects/Designer-Wallcoverings/DW-Agents/dw-agents/new-client-signup-agent.ts:27 …oken
+ anthropic-key /Users/stevestudio2/Projects/Designer-Wallcoverings/DW-Agents/dw-agents/purchasing-office-agent.ts:51 …4QAA
+ anthropic-key /Users/stevestudio2/Projects/Designer-Wallcoverings/DW-Agents/dw-agents/agent-marketing/marketing-agent.ts:67 …cgAA
+ slack-bot /Users/stevestudio2/Projects/Designer-Wallcoverings/DW-Agents/dw-agents/new-client-signup-agent-v1.0.ts:20 …oken
+ slack-bot /Users/stevestudio2/Projects/Designer-Wallcoverings/DW-Agents/dw-agents/agent-slack/slack-agent.ts:14 …7AHQ
+ slack-bot /Users/stevestudio2/Projects/Designer-Wallcoverings/DW-Agents/dw-agents/agent-slack/slack-agent.js:12 …7AHQ
+ google-oauth-access /Users/stevestudio2/Projects/goodquestion-ai/.youtube-token.json:2 …0207
+ google-api-key /Users/stevestudio2/Projects/goodquestion-ai/scripts/sensitive_patterns.py:232 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Patty/app/api/orbit/rss/route.ts:6 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Patty/app/api/orbit/batch-link/route.ts:5 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Patty/app/api/orbit/suggest-alliance/route.ts:6 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Patty/app/api/orbit/generate/route.ts:7 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Patty/app/api/petitions/generate/route.ts:5 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Patty/app/api/trending/discover/route.ts:5 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Patty/app/api/campaigns/generate/route.ts:5 …ejMo
+ google-api-key /Users/stevestudio2/Projects/SmokeShop/lib/gemini.js:9 …ejMo
+ slack-bot /Users/stevestudio2/Projects/slack-dm-viewer/server.js:34 …7AHQ
+ slack-bot /Users/stevestudio2/Projects/slack-dm-viewer/server.js:36 …pmsq
+ slack-bot /Users/stevestudio2/Projects/slack-dm-viewer/server.js:40 …c1a7
+ google-api-key /Users/stevestudio2/Projects/PoppyPetitions/lib/gemini.ts:1 …S2ic
+ google-api-key /Users/stevestudio2/Projects/Ken/kalshi-dash/server.js:130 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Norma/app/api/drafts/auto-generate/route.ts:12 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Norma/app/api/social/ai-compose/route.ts:4 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Norma/agents/price-agent/skills/enrich.js:16 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Norma/agents/price-agent/skills/crawl-federal.js:16 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Norma/agents/shared/ai.js:11 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Norma/agents/onboard-agent/skills/discover.js:21 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Norma/agents/onboard-agent/skills/post.js:16 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Norma/agents/datasource-agent/skills/rate-sources.js:16 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Norma/agents/datasource-agent/skills/discover-apis.js:17 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Norma/agents/datasource-agent/skills/scrape-frontpages.js:18 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Norma/agents/datasource-agent/skills/collect-statements.js:17 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Norma/agents/datasource-agent/skills/scrape-petitions.js:19 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Norma/docs/superpowers/plans/2026-03-13-power-intelligence.md:913 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Norma/scripts/batch-resolve-authors.js:9 …ejMo
+ google-oauth-access /Users/stevestudio2/Projects/Norma/scripts/search-sacbee.js:11 …0207
+ google-api-key /Users/stevestudio2/Projects/Norma/scripts/detect-news-mentions.ts:15 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Norma/scripts/enrich-news-ai.js:17 …ejMo
+ google-api-key /Users/stevestudio2/Projects/Norma/lib/detect-mentions.ts:20 …ejMo
+ google-api-key /Users/stevestudio2/Projects/yolo-agent/tasks/done/AQ_hollywood-imageclean-and-spin.md:15 …ejMo
+ google-api-key /Users/stevestudio2/Projects/yolo-agent/tasks/done/AQ_hollywood-imageclean-and-spin.md:54 …ejMo
+ google-api-key /Users/stevestudio2/Projects/yolo-agent/tasks/done/04_gemini-texture-classify-17k.md:23 …ejMo
+ google-api-key /Users/stevestudio2/Projects/yolo-agent/tasks/done/03_p2-06-interior-design-tagger.md:31 …ejMo
+ google-api-key /Users/stevestudio2/Projects/yolo-agent/tasks/done/02_enrich-remaining-gaps.md:8 …ejMo
+ google-api-key /Users/stevestudio2/Projects/yolo-agent/tasks/done/03_ai-enrich-mark-alexander.md:9 …ejMo
+ google-api-key /Users/stevestudio2/Projects/yolo-agent/tasks/done/25_zero-repeat-textures-r2.md:29 …ejMo
+ google-api-key /Users/stevestudio2/Projects/yolo-agent/tasks/done/25_zero-repeat-textures-r2.md:46 …ejMo
+ google-api-key /Users/stevestudio2/Projects/yolo-agent/tasks/done/00_full-monte-phase3-all.md:46 …ejMo
+ google-api-key /Users/stevestudio2/Projects/yolo-agent/tasks/done/13_hollywood-hex-extraction.md:15 …ejMo
+ google-api-key /Users/stevestudio2/Projects/yolo-agent/tasks/done/09_ai-enrich-zoffany.md:11 …ejMo
+ google-api-key /Users/stevestudio2/Projects/yolo-agent/tasks/done/03_03_gls-tag-cleanup.md:9 …ejMo
+ google-api-key /Users/stevestudio2/Projects/yolo-agent/tasks/done/00a_maya-room-settings.md:18 …ejMo
+ google-api-key /Users/stevestudio2/Projects/yolo-agent/tasks/done/01_ai-enrich-romo.md:17 …ejMo
+ google-api-key /Users/stevestudio2/Projects/yolo-agent/tasks/done/01_enrich-prl-direct.md:12 …ejMo
+ google-api-key /Users/stevestudio2/Projects/yolo-agent/tasks/done/01_interior-design-tags-all-vendors.md:30 …ejMo
+ google-api-key /Users/stevestudio2/Projects/yolo-agent/tasks/done/04_ai-enrich-arte.md:9 …ejMo
+ google-api-key /Users/stevestudio2/Projects/yolo-agent/tasks/done/06_hollywood-gemini-hex.md:4 …ejMo
+ google-api-key /Users/stevestudio2/Projects/yolo-agent/tasks/done/05_china-seas-interior-tagger.md:7 …ejMo
+ google-api-key /Users/stevestudio2/Projects/yolo-agent/tasks/done/05_ai-enrich-remaining.md:10 …ejMo
+ google-api-key /Users/stevestudio2/Projects/yolo-agent/tasks/done/29_texture-classify-remaining-r3.md:39 …ejMo
+ google-api-key /Users/stevestudio2/Projects/yolo-agent/tasks/done/04_china-seas-hex-colors.md:17 …ejMo
+ google-api-key /Users/stevestudio2/Projects/yolo-agent/tasks/done/02_newmor-bulk-phase3-ai.md:82 …ejMo
+ google-api-key /Users/stevestudio2/Projects/yolo-agent/tasks/done/08_phase3-enrichment-run.md:8 …ejMo
+ google-api-key /Users/stevestudio2/Projects/yolo-agent/tasks/done/02_activate-versace-drafts.md:15 …ejMo
+ google-api-key /Users/stevestudio2/Projects/yolo-agent/tasks/done/06_hollywood-hex-extraction.md:13 …ejMo
+ google-api-key /Users/stevestudio2/Projects/yolo-agent/tasks/done/02_ai-enrich-villa-nova.md:9 …ejMo
+ google-api-key /Users/stevestudio2/Projects/yolo-agent/tasks/done/00_hex-color-gemini-blitz.md:18 …ejMo
+ google-api-key /Users/stevestudio2/Projects/yolo-agent/tasks/done/00_hex-color-gemini-blitz.md:27 …ejMo
+ google-api-key /Users/stevestudio2/Projects/yolo-agent/tasks/done/01_newmor-full-monty-test.md:61 …ejMo
+ google-api-key /Users/stevestudio2/Projects/yolo-agent/tasks/done/11_interior-design-tagger.md:7 …ejMo
+ google-api-key /Users/stevestudio2/Projects/yolo-agent/tasks/done/19_zero-repeat-textures.md:30 …ejMo
+ google-api-key /Users/stevestudio2/Projects/yolo-agent/tasks/done/19_zero-repeat-textures.md:46 …ejMo
+ google-api-key /Users/stevestudio2/Projects/yolo-agent/scripts/collection-descriptions.js:16 …ejMo
diff --git a/auto-ingest.launchd.err b/auto-ingest.launchd.err
new file mode 100644
index 0000000..e69de29
diff --git a/auto-ingest.launchd.out b/auto-ingest.launchd.out
new file mode 100644
index 0000000..e69de29
diff --git a/auto-ingest.sh b/auto-ingest.sh
new file mode 100755
index 0000000..c017617
--- /dev/null
+++ b/auto-ingest.sh
@@ -0,0 +1,51 @@
+#!/usr/bin/env bash
+# Auto-ingest watcher.
+# Runs every 30s via launchd com.steve.secrets-auto-ingest.
+# - Hashes ~/Desktop/site-factory.env. If changed since last run AND contains
+# non-empty values for keys not yet in registry → run cli.js sync.
+# - If after sync the "site-factory trigger set" is complete, fire run-all-stages.sh.
+# - Plays a sound when something happens (so Steve knows from anywhere).
+set -uo pipefail
+
+DESK=/Users/stevestudio2/Desktop/site-factory.env
+ROOT=/Users/stevestudio2/Projects/secrets-manager
+STATE=$ROOT/.auto-ingest-state
+LOG=$ROOT/auto-ingest.log
+TS() { date +%FT%T%z; }
+
+[ -f "$DESK" ] || exit 0
+
+# Hash the desktop file (only the KEY=value lines, not comments)
+HASH=$(grep -E '^[A-Z_]+=.+$' "$DESK" 2>/dev/null | sort | shasum -a 256 | awk '{print $1}')
+PREV=""
+[ -f "$STATE" ] && PREV=$(cat "$STATE")
+
+[ "$HASH" = "$PREV" ] && exit 0 # no change
+
+mkdir -p "$ROOT"
+echo "[$(TS)] desktop env changed (hash $HASH) — running sync" >> "$LOG"
+
+# Pipe non-empty key=value lines into import-paste (which validates each)
+NEW_LINES=$(grep -E '^[A-Z_]+=[^[:space:]#]+' "$DESK" 2>/dev/null)
+if [ -n "$NEW_LINES" ]; then
+ printf '%s\n' "$NEW_LINES" | node "$ROOT/cli.js" import-paste >> "$LOG" 2>&1 || true
+fi
+
+# Check if site-factory trigger set is complete enough to fire pipeline
+HAVE() { node "$ROOT/cli.js" list 2>/dev/null | grep -q "✓ $1 "; }
+
+CAN_FIRE=true
+for k in CLOUDFLARE_API_TOKEN STRIPE_SECRET_KEY VERCEL_TOKEN; do
+ HAVE "$k" || CAN_FIRE=false
+done
+
+if $CAN_FIRE; then
+ echo "[$(TS)] trigger set complete — firing run-all-stages.sh" >> "$LOG"
+ bash /Users/stevestudio2/Projects/site-factory/scripts/run-all-stages.sh >> "$LOG" 2>&1 &
+ /usr/bin/afplay /System/Library/Sounds/Glass.aiff 2>/dev/null &
+ /usr/bin/osascript -e 'display notification "Site Factory pipeline firing" with title "Secrets Manager"' 2>/dev/null &
+else
+ /usr/bin/afplay /System/Library/Sounds/Tink.aiff 2>/dev/null &
+fi
+
+echo "$HASH" > "$STATE"
diff --git a/cli.js b/cli.js
new file mode 100755
index 0000000..efb1617
--- /dev/null
+++ b/cli.js
@@ -0,0 +1,346 @@
+#!/usr/bin/env node
+// Secrets Manager CLI — single source of truth for Steve's API tokens.
+//
+// Usage:
+// node cli.js list
+// node cli.js add <KEY> <VALUE>
+// node cli.js import-paste # reads KEY=VALUE block from stdin
+// node cli.js check <KEY>
+// node cli.js sync # re-fan master → all destinations
+// node cli.js audit # scan home for leaked secrets
+//
+// No deps. Pure node, https module, fs, child_process for grep.
+const fs = require('fs');
+const path = require('path');
+const os = require('os');
+const https = require('https');
+const crypto = require('crypto');
+const { execSync } = require('child_process');
+
+const { spawnSync } = require('child_process');
+
+const ROOT = path.dirname(__filename);
+const HOME = os.homedir();
+const ROUTES = JSON.parse(fs.readFileSync(path.join(ROOT, 'routes.json'), 'utf8'));
+const MASTER_ENV = path.join(ROOT, '.env');
+const DESKTOP_ENV = path.join(HOME, 'Desktop', 'site-factory.env');
+const REGISTRY = path.join(ROOT, 'registry.json');
+
+// ─── helpers ────────────────────────────────────────────────────────────
+function expand(p) { return p.replace(/^~/, HOME); }
+function digest(v) { return v.slice(-4) + ':' + crypto.createHash('sha256').update(v).digest('hex').slice(0, 8); }
+function loadRegistry() { return fs.existsSync(REGISTRY) ? JSON.parse(fs.readFileSync(REGISTRY, 'utf8')) : { secrets: {} }; }
+function saveRegistry(r) { fs.writeFileSync(REGISTRY, JSON.stringify(r, null, 2)); }
+function loadEnvFile(p) {
+ if (!fs.existsSync(p)) return {};
+ const out = {};
+ for (const line of fs.readFileSync(p, 'utf8').split('\n')) {
+ const m = line.match(/^([A-Z_][A-Z0-9_]*)\s*=\s*(.*)$/);
+ if (m) out[m[1]] = m[2].replace(/^["']|["']$/g, '');
+ }
+ return out;
+}
+function writeEnvFile(p, kv, preserveComments = true) {
+ fs.mkdirSync(path.dirname(p), { recursive: true });
+ let body = '';
+ if (preserveComments && fs.existsSync(p)) {
+ // Preserve existing lines, replacing matching keys
+ const seen = new Set();
+ for (const line of fs.readFileSync(p, 'utf8').split('\n')) {
+ const m = line.match(/^([A-Z_][A-Z0-9_]*)\s*=/);
+ if (m && kv[m[1]] !== undefined) { body += `${m[1]}=${kv[m[1]]}\n`; seen.add(m[1]); }
+ else body += line + '\n';
+ }
+ for (const k of Object.keys(kv)) if (!seen.has(k)) body += `${k}=${kv[k]}\n`;
+ body = body.replace(/\n+$/, '\n');
+ } else {
+ for (const [k, v] of Object.entries(kv)) body += `${k}=${v}\n`;
+ }
+ fs.writeFileSync(p, body);
+ try { fs.chmodSync(p, 0o600); } catch {}
+}
+// Remote env via SSH. Hosts must have SSH key auth set up; we never prompt
+// for a password (BatchMode=yes). Connect timeout caps stalls at 8s.
+function readRemoteEnvFile(user, host, p) {
+ const r = spawnSync('ssh', [
+ '-o', 'BatchMode=yes',
+ '-o', 'ConnectTimeout=8',
+ '-o', 'StrictHostKeyChecking=accept-new',
+ `${user}@${host}`,
+ `cat ${p} 2>/dev/null || true`,
+ ], { encoding: 'utf8' });
+ return r.status === 0 ? (r.stdout || '') : '';
+}
+function parseEnvString(s) {
+ const out = {};
+ for (const line of s.split('\n')) {
+ const m = line.match(/^([A-Z_][A-Z0-9_]*)\s*=\s*(.*)$/);
+ if (m) out[m[1]] = m[2].replace(/^["']|["']$/g, '');
+ }
+ return out;
+}
+function serializeEnvBody(existingText, kv) {
+ // Preserve comments + ordering, replace matching keys, append new ones.
+ let body = '';
+ const seen = new Set();
+ if (existingText) {
+ for (const line of existingText.split('\n')) {
+ const m = line.match(/^([A-Z_][A-Z0-9_]*)\s*=/);
+ if (m && kv[m[1]] !== undefined) { body += `${m[1]}=${kv[m[1]]}\n`; seen.add(m[1]); }
+ else body += line + '\n';
+ }
+ }
+ for (const k of Object.keys(kv)) if (!seen.has(k)) body += `${k}=${kv[k]}\n`;
+ return body.replace(/\n+$/, '\n');
+}
+function writeRemoteEnvFile(user, host, p, body) {
+ // Use ssh + tee with stdin so we never pass the secret on the command line.
+ // Remote dir is ensured first; permissions tightened to 600 after write.
+ const dir = p.replace(/\/[^/]+$/, '') || '.';
+ const remoteCmd = `mkdir -p '${dir}' && cat > '${p}' && chmod 600 '${p}'`;
+ const r = spawnSync('ssh', [
+ '-o', 'BatchMode=yes',
+ '-o', 'ConnectTimeout=8',
+ '-o', 'StrictHostKeyChecking=accept-new',
+ `${user}@${host}`,
+ remoteCmd,
+ ], { input: body, encoding: 'utf8' });
+ if (r.status !== 0) {
+ throw new Error(`ssh write failed (${user}@${host}:${p}): ${(r.stderr || '').slice(0, 200)}`);
+ }
+}
+
+function httpsReq(url, opts = {}) {
+ return new Promise((resolve, reject) => {
+ const u = new URL(url);
+ const req = https.request({
+ hostname: u.hostname, path: u.pathname + u.search, method: opts.method || 'GET',
+ headers: opts.headers || {},
+ }, res => {
+ let body = '';
+ res.on('data', c => body += c);
+ res.on('end', () => resolve({ status: res.statusCode, body }));
+ });
+ req.on('error', reject);
+ if (opts.body) req.write(opts.body);
+ req.end();
+ });
+}
+
+// ─── verify ─────────────────────────────────────────────────────────────
+async function verifyToken(key, value) {
+ const cfg = ROUTES.services[key]?.verify;
+ if (!cfg) return { ok: true, skipped: true };
+ const headers = {};
+ if (cfg.auth === 'bearer') headers['Authorization'] = `Bearer ${value}`;
+ if (cfg.auth === 'basic-sk') headers['Authorization'] = 'Basic ' + Buffer.from(value + ':').toString('base64');
+ if (cfg.auth === 'x-api-key') { headers['x-api-key'] = value; headers['anthropic-version'] = '2023-06-01'; }
+ // generic 'header' mode: caller specifies cfg.headerName (e.g. 'xi-api-key' for ElevenLabs)
+ if (cfg.auth === 'header' && cfg.headerName) headers[cfg.headerName] = value;
+ if (cfg.body) headers['Content-Type'] = 'application/json';
+ // 'url' / 'query' auth: substitute {value} in the URL (for APIs that take the key as a query param)
+ const url = (cfg.auth === 'url' || cfg.auth === 'query')
+ ? cfg.url.replace('{value}', encodeURIComponent(value))
+ : cfg.url;
+ try {
+ const r = await httpsReq(url, { method: cfg.method, headers, body: cfg.body });
+ // Anthropic-specific: 400 with "credit balance" means the key auth'd but the account is out of credits.
+ // That's still a valid key; persist but flag with status.
+ const creditOk = r.status === 400 && /credit balance|insufficient/i.test(r.body);
+ return { ok: (r.status >= 200 && r.status < 300) || creditOk, status: r.status, body: r.body.slice(0, 200) };
+ } catch (e) {
+ return { ok: false, error: e.message };
+ }
+}
+
+// ─── fan-out ────────────────────────────────────────────────────────────
+function fanOut(key, value) {
+ const destinations = ROUTES.services[key]?.destinations || [];
+ const written = [];
+
+ // Master always
+ const master = loadEnvFile(MASTER_ENV); master[key] = value;
+ writeEnvFile(MASTER_ENV, master, false); written.push(MASTER_ENV);
+
+ // Desktop master
+ const desk = loadEnvFile(DESKTOP_ENV); desk[key] = value;
+ writeEnvFile(DESKTOP_ENV, desk, true); written.push(DESKTOP_ENV);
+
+ for (const d of destinations) {
+ if (d.type === 'project') {
+ // Local project (no host) — original behavior.
+ // Remote project (d.host set) — push via SSH; failures log + skip,
+ // they don't blow up the rest of the fan-out.
+ if (d.host) {
+ const user = d.user || 'root';
+ try {
+ const existing = readRemoteEnvFile(user, d.host, d.path);
+ const cur = parseEnvString(existing); cur[key] = value;
+ const body = serializeEnvBody(existing, cur);
+ writeRemoteEnvFile(user, d.host, d.path, body);
+ written.push(`ssh:${user}@${d.host}:${d.path}`);
+ } catch (e) {
+ console.error(` ⚠ remote skip ${user}@${d.host}:${d.path} — ${e.message}`);
+ }
+ } else {
+ const p = expand(d.path);
+ const cur = loadEnvFile(p); cur[key] = value;
+ writeEnvFile(p, cur, true); written.push(p);
+ }
+ } else if (d.type === 'skill') {
+ const p = path.join(HOME, '.claude/skills', d.name, '.env');
+ const cur = loadEnvFile(p); cur[key] = value;
+ writeEnvFile(p, cur, true); written.push(p);
+ } else if (d.type === 'site_local') {
+ for (const dom of d.domains) {
+ const p = expand(`~/Projects/site-factory/sites/${dom}/app/.env.local`);
+ const cur = loadEnvFile(p); cur[key] = value;
+ writeEnvFile(p, cur, true); written.push(p);
+ }
+ } else if (d.type === 'mcp') {
+ const cfgPath = path.join(HOME, '.claude.json');
+ if (!fs.existsSync(cfgPath)) continue;
+ const bak = `${cfgPath}.bak.${Date.now()}`;
+ fs.copyFileSync(cfgPath, bak);
+ const j = JSON.parse(fs.readFileSync(cfgPath, 'utf8'));
+ const sv = (j.mcpServers && j.mcpServers[d.server]) || null;
+ if (sv) {
+ sv.env = sv.env || {};
+ sv.env[d.key || key] = value;
+ fs.writeFileSync(cfgPath, JSON.stringify(j, null, 2));
+ written.push(`${cfgPath}#mcpServers.${d.server}.env.${d.key || key}`);
+ }
+ }
+ }
+ return written;
+}
+
+// ─── commands ───────────────────────────────────────────────────────────
+async function cmdAdd(key, value) {
+ if (!key || !value) { console.error('usage: add <KEY> <VALUE>'); process.exit(2); }
+ const v = await verifyToken(key, value);
+ if (!v.ok) {
+ console.error(`✗ verify failed for ${key}: ${v.status || v.error || ''}`);
+ if (v.body) console.error(' ' + v.body);
+ process.exit(1);
+ }
+ const written = fanOut(key, value);
+ const r = loadRegistry();
+ r.secrets[key] = {
+ digest: digest(value),
+ label: ROUTES.services[key]?.label || key,
+ last_updated: new Date().toISOString(),
+ validated: !v.skipped,
+ verify_status: v.status || null,
+ written_to: written,
+ };
+ saveRegistry(r);
+ console.log(`[secrets-manager]`);
+ console.log(` service: ${key}`);
+ console.log(` action: add`);
+ console.log(` validated: ${v.skipped ? 'skipped (no verify endpoint)' : 'yes'}`);
+ console.log(` digest: …${r.secrets[key].digest}`);
+ console.log(` written_to: ${written.length} destinations`);
+ for (const w of written) console.log(` - ${w}`);
+}
+
+async function cmdImportPaste() {
+ const stdin = fs.readFileSync(0, 'utf8');
+ const lines = stdin.split('\n').map(l => l.trim()).filter(Boolean);
+ const adds = [];
+ for (const line of lines) {
+ const m = line.match(/^([A-Z_][A-Z0-9_]*)\s*=\s*(.*)$/);
+ if (m && m[2] && !m[2].startsWith('#')) adds.push([m[1], m[2].replace(/^["']|["']$/g, '')]);
+ }
+ if (!adds.length) { console.error('no KEY=value lines found in stdin'); process.exit(2); }
+ console.log(`importing ${adds.length} key(s): ${adds.map(([k]) => k).join(', ')}`);
+ for (const [k, v] of adds) {
+ try { await cmdAdd(k, v); } catch (e) { console.error(` ${k}: ${e.message}`); }
+ }
+}
+
+function cmdList() {
+ const r = loadRegistry();
+ console.log('Known services:');
+ for (const k of Object.keys(ROUTES.services)) {
+ const e = r.secrets[k];
+ if (e) console.log(` ✓ ${k.padEnd(28)} ${e.label.padEnd(28)} …${e.digest} ${e.last_updated.slice(0,10)}`);
+ else console.log(` ✗ ${k.padEnd(28)} ${ROUTES.services[k].label.padEnd(28)} <not set>`);
+ }
+}
+
+async function cmdCheck(key) {
+ if (!key) { console.error('usage: check <KEY>'); process.exit(2); }
+ const master = loadEnvFile(MASTER_ENV);
+ const v = master[key];
+ if (!v) { console.error(`${key}: not in master`); process.exit(1); }
+ const r = await verifyToken(key, v);
+ console.log(`${key}: ${r.ok ? 'VALID' : 'INVALID'} status=${r.status || r.error || 'n/a'}`);
+}
+
+function cmdSync() {
+ const master = loadEnvFile(MASTER_ENV);
+ let total = 0;
+ for (const k of Object.keys(ROUTES.services)) {
+ if (master[k]) total += fanOut(k, master[k]).length;
+ }
+ console.log(`sync: re-wrote ${total} destination entries from master`);
+}
+
+function cmdAudit() {
+ const patterns = ROUTES.leak_patterns || [];
+ const roots = [
+ path.join(HOME, '.claude/skills'),
+ path.join(HOME, '.claude/agents'),
+ path.join(HOME, 'Projects'),
+ path.join(HOME, 'cncp-starter'),
+ ];
+ const exts = '\\.(md|json|js|ts|tsx|sh|py|env|local|toml|yaml|yml)$';
+ const findings = [];
+ for (const root of roots) {
+ if (!fs.existsSync(root)) continue;
+ let files;
+ try {
+ files = execSync(
+ `find "${root}" -type f -not -path "*/node_modules/*" -not -path "*/.git/*" -not -path "*/dist/*" -not -path "*/.next/*" 2>/dev/null | grep -E '${exts}'`,
+ { encoding: 'utf8', maxBuffer: 1024 * 1024 * 50 }
+ ).split('\n').filter(Boolean);
+ } catch { continue; }
+ for (const f of files) {
+ let text;
+ try { text = fs.readFileSync(f, 'utf8'); } catch { continue; }
+ // Skip our own .env files (they SHOULD have secrets, that's their job)
+ if (f.endsWith('/.env') || f.endsWith('/.env.local')) continue;
+ // Skip the master + registry (the manager itself)
+ if (f === MASTER_ENV || f === REGISTRY || f === path.join(ROOT, 'routes.json')) continue;
+ for (const p of patterns) {
+ const re = new RegExp(p.regex, 'g');
+ let m;
+ while ((m = re.exec(text)) !== null) {
+ const captured = m[1] || m[0];
+ const line = text.slice(0, m.index).split('\n').length;
+ findings.push({ file: f, line, pattern: p.name, last4: captured.slice(-4) });
+ }
+ }
+ }
+ }
+ if (!findings.length) { console.log('audit: no leaked secrets found'); return; }
+ console.log(`audit: ${findings.length} finding(s):`);
+ for (const f of findings) console.log(` ${f.pattern.padEnd(24)} ${f.file}:${f.line} …${f.last4}`);
+}
+
+// ─── dispatch ───────────────────────────────────────────────────────────
+const [, , cmd, ...rest] = process.argv;
+(async () => {
+ switch (cmd) {
+ case 'add': await cmdAdd(rest[0], rest[1]); break;
+ case 'import-paste': await cmdImportPaste(); break;
+ case 'list': cmdList(); break;
+ case 'check': await cmdCheck(rest[0]); break;
+ case 'sync': cmdSync(); break;
+ case 'audit': cmdAudit(); break;
+ default:
+ console.error('usage: cli.js <add|import-paste|list|check|sync|audit> [args]');
+ process.exit(2);
+ }
+})().catch(e => { console.error('ERR:', e.message); process.exit(1); });
diff --git a/clipboard-watcher.launchd.err b/clipboard-watcher.launchd.err
new file mode 100644
index 0000000..4b9f55e
--- /dev/null
+++ b/clipboard-watcher.launchd.err
@@ -0,0 +1 @@
+/Users/stevestudio2/Projects/secrets-manager/clipboard-watcher.sh: line 38: /Users/stevestudio2/Desktop/site-factory.env: Operation not permitted
diff --git a/clipboard-watcher.launchd.out b/clipboard-watcher.launchd.out
new file mode 100644
index 0000000..e69de29
diff --git a/clipboard-watcher.sh b/clipboard-watcher.sh
new file mode 100755
index 0000000..f006727
--- /dev/null
+++ b/clipboard-watcher.sh
@@ -0,0 +1,106 @@
+#!/usr/bin/env bash
+# Clipboard token watcher — polls pbpaste every 2s, detects token formats,
+# pipes them DIRECTLY into cli.js import-paste (no Desktop file middleman —
+# launchd can't read ~/Desktop without Full Disk Access).
+#
+# Steve's only required action: create token at provider → click Copy.
+# This catches it within 2s, validates against provider, fans out to all
+# .env destinations.
+#
+# Auto-terminates after 30 min OR when the 4 site-factory tokens are all
+# in the master registry, whichever comes first. Safe to run repeatedly.
+set -uo pipefail
+
+ROOT=/Users/stevestudio2/Projects/secrets-manager
+MASTER=$ROOT/.env
+LAST=$ROOT/.clipboard-last-hash
+LOG=$ROOT/clipboard-watcher.log
+START=$(date +%s)
+TIMEOUT=$((30 * 60)) # 30 min
+
+TS() { date +%FT%T%z; }
+
+# Already-seen clipboard hash (so we don't re-process the same value)
+PREV_HASH=""
+[ -f "$LAST" ] && PREV_HASH=$(cat "$LAST")
+
+# Has-token check — read master registry env (which IS readable by launchd)
+has_token() {
+ [ -f "$MASTER" ] && grep -qE "^$1=[^[:space:]#]+" "$MASTER" 2>/dev/null
+}
+
+# Pipe into cli.js — handles validation + fan-out + registry update
+ingest_via_cli() {
+ local KEY=$1 VAL=$2
+ echo "[$(TS)] capturing $KEY (…${VAL: -4}) → cli.js import-paste" >> "$LOG"
+ printf '%s=%s\n' "$KEY" "$VAL" | /usr/local/bin/node "$ROOT/cli.js" import-paste >> "$LOG" 2>&1
+ /usr/bin/afplay /System/Library/Sounds/Pop.aiff 2>/dev/null &
+ /usr/bin/osascript -e "display notification \"$KEY captured & validated\" with title \"Secrets Clipboard\"" 2>/dev/null &
+}
+
+# Detect which token type a clipboard value is
+classify() {
+ local V=$1
+ # Strip leading/trailing whitespace
+ V=$(echo "$V" | /usr/bin/tr -d '\r\n' | /usr/bin/awk '{gsub(/^ +| +$/, ""); print}')
+ [ -z "$V" ] && return 1
+ case "$V" in
+ sk_live_*|sk_test_*) echo "STRIPE_SECRET_KEY=$V"; return 0 ;;
+ rk_live_*|rk_test_*) echo "STRIPE_RESTRICTED_KEY=$V"; return 0 ;;
+ pk_live_*|pk_test_*) echo "STRIPE_PUBLISHABLE_KEY=$V"; return 0 ;;
+ whsec_*) echo "STRIPE_WEBHOOK_SECRET=$V"; return 0 ;;
+ bb_live_*) echo "BROWSERBASE_API_KEY=$V"; return 0 ;;
+ sk-ant-*) echo "ANTHROPIC_API_KEY=$V"; return 0 ;;
+ sk-*) echo "OPENAI_API_KEY=$V"; return 0 ;;
+ AIza*) echo "GEMINI_API_KEY=$V"; return 0 ;;
+ ghp_*|github_pat_*) echo "GITHUB_TOKEN=$V"; return 0 ;;
+ shpat_*|shpca_*) echo "SHOPIFY_ADMIN_TOKEN=$V"; return 0 ;;
+ re_*) echo "RESEND_API_KEY=$V"; return 0 ;;
+ esac
+ # Vercel tokens: 24 alphanumeric chars (no prefix). Detect by length + charset.
+ if [[ "$V" =~ ^[A-Za-z0-9]{24}$ ]]; then
+ echo "VERCEL_TOKEN=$V"; return 0
+ fi
+ # Cloudflare API tokens: 40 chars alphanumeric/underscore/dash, starts with letter
+ if [[ "$V" =~ ^[A-Za-z][A-Za-z0-9_-]{39}$ ]] && [ ${#V} -eq 40 ]; then
+ echo "CLOUDFLARE_API_TOKEN=$V"; return 0
+ fi
+ # PurelyMail tokens: hex-ish, length 32-64. Lower confidence — only match if length 40+ and pure hex
+ if [[ "$V" =~ ^[a-f0-9]{40,}$ ]]; then
+ echo "PURELYMAIL_API_TOKEN=$V"; return 0
+ fi
+ return 1
+}
+
+echo "[$(TS)] clipboard-watcher start (timeout ${TIMEOUT}s)" >> "$LOG"
+
+while true; do
+ # Timeout
+ NOW=$(date +%s)
+ if [ $((NOW - START)) -ge $TIMEOUT ]; then
+ echo "[$(TS)] timeout reached, exiting" >> "$LOG"
+ break
+ fi
+
+ # All 4 main tokens captured? Done early.
+ if has_token CLOUDFLARE_API_TOKEN && has_token STRIPE_SECRET_KEY && has_token VERCEL_TOKEN && has_token PURELYMAIL_API_TOKEN; then
+ echo "[$(TS)] all 4 trigger tokens captured, exiting early" >> "$LOG"
+ /usr/bin/afplay /System/Library/Sounds/Glass.aiff 2>/dev/null &
+ /usr/bin/osascript -e 'display notification "All 4 site-factory tokens captured" with title "Secrets Clipboard"' 2>/dev/null &
+ break
+ fi
+
+ CLIP=$(/usr/bin/pbpaste 2>/dev/null || true)
+ HASH=$(printf '%s' "$CLIP" | shasum -a 256 | awk '{print $1}')
+ if [ "$HASH" != "$PREV_HASH" ] && [ -n "$CLIP" ] && [ ${#CLIP} -lt 500 ]; then
+ if MATCH=$(classify "$CLIP"); then
+ KEY=${MATCH%%=*}
+ VAL=${MATCH#*=}
+ ingest_via_cli "$KEY" "$VAL"
+ fi
+ PREV_HASH=$HASH
+ echo "$HASH" > "$LAST"
+ fi
+
+ sleep 2
+done
diff --git a/registry.json b/registry.json
new file mode 100644
index 0000000..ab213d7
--- /dev/null
+++ b/registry.json
@@ -0,0 +1,252 @@
+{
+ "_comment": "Registry of every secret. Values themselves never appear here — only digests + destinations. Updated by cli.js.",
+ "secrets": {
+ "DPLA_API_KEY": {
+ "digest": "ecd5:7d670175",
+ "label": "Digital Public Library of America API Key",
+ "last_updated": "2026-04-30T18:23:59.835Z",
+ "validated": true,
+ "verify_status": 200,
+ "written_to": [
+ "/Users/stevestudio2/Projects/secrets-manager/.env",
+ "/Users/stevestudio2/Desktop/site-factory.env",
+ "/Users/stevestudio2/Projects/wholivedthere/.env",
+ "/Users/stevestudio2/Projects/claimmyaddress/.env",
+ "/Users/stevestudio2/Projects/bubbesblock/.env",
+ "/Users/stevestudio2/.claude/skills/la-research-agent/.env"
+ ]
+ },
+ "GODADDY_API_KEY": {
+ "digest": "acsF:96974d0c",
+ "label": "GoDaddy API Key",
+ "last_updated": "2026-04-30T18:50:35.250Z",
+ "validated": false,
+ "verify_status": null,
+ "written_to": [
+ "/Users/stevestudio2/Projects/secrets-manager/.env",
+ "/Users/stevestudio2/Desktop/site-factory.env",
+ "/Users/stevestudio2/.claude.json#mcpServers.domain-suite.env.GODADDY_API_KEY"
+ ]
+ },
+ "GODADDY_API_SECRET": {
+ "digest": "Vnej:31492271",
+ "label": "GoDaddy API Secret",
+ "last_updated": "2026-04-30T18:50:40.119Z",
+ "validated": false,
+ "verify_status": null,
+ "written_to": [
+ "/Users/stevestudio2/Projects/secrets-manager/.env",
+ "/Users/stevestudio2/Desktop/site-factory.env",
+ "/Users/stevestudio2/.claude.json#mcpServers.domain-suite.env.GODADDY_API_SECRET"
+ ]
+ },
+ "BROWSERBASE_API_KEY": {
+ "digest": "lOB8:e5e8c875",
+ "label": "Browserbase API Key",
+ "last_updated": "2026-04-30T18:50:42.047Z",
+ "validated": false,
+ "verify_status": null,
+ "written_to": [
+ "/Users/stevestudio2/Projects/secrets-manager/.env",
+ "/Users/stevestudio2/Desktop/site-factory.env",
+ "/Users/stevestudio2/.claude/skills/browserbase/.env"
+ ]
+ },
+ "BROWSERBASE_PROJECT_ID": {
+ "digest": "c840:29be6dca",
+ "label": "Browserbase Project ID",
+ "last_updated": "2026-04-30T18:50:43.778Z",
+ "validated": false,
+ "verify_status": null,
+ "written_to": [
+ "/Users/stevestudio2/Projects/secrets-manager/.env",
+ "/Users/stevestudio2/Desktop/site-factory.env",
+ "/Users/stevestudio2/.claude/skills/browserbase/.env"
+ ]
+ },
+ "CLOUDFLARE_API_TOKEN": {
+ "digest": "lYcL:951aa6d7",
+ "label": "Cloudflare API Token",
+ "last_updated": "2026-04-30T18:50:52.016Z",
+ "validated": true,
+ "verify_status": 200,
+ "written_to": [
+ "/Users/stevestudio2/Projects/secrets-manager/.env",
+ "/Users/stevestudio2/Desktop/site-factory.env",
+ "/Users/stevestudio2/Projects/site-factory/.env",
+ "/Users/stevestudio2/.claude/skills/cloudflare-manager/.env",
+ "/Users/stevestudio2/.claude/skills/setup-domains/.env",
+ "/Users/stevestudio2/.claude/skills/domain-setup/.env"
+ ]
+ },
+ "ANTHROPIC_API_KEY": {
+ "digest": "7AAA:798d801c",
+ "label": "Anthropic API Key",
+ "last_updated": "2026-04-30T18:52:00.895Z",
+ "validated": true,
+ "verify_status": 400,
+ "written_to": [
+ "/Users/stevestudio2/Projects/secrets-manager/.env",
+ "/Users/stevestudio2/Desktop/site-factory.env",
+ "/Users/stevestudio2/Projects/Letsbegin/.env.local",
+ "/Users/stevestudio2/Projects/dear-bubbe-nextjs/.env"
+ ]
+ },
+ "STRIPE_SECRET_KEY": {
+ "digest": "8LQ0:fe981600",
+ "label": "Stripe Secret Key",
+ "last_updated": "2026-05-01T06:23:30.081Z",
+ "validated": true,
+ "verify_status": 200,
+ "written_to": [
+ "/Users/stevestudio2/Projects/secrets-manager/.env",
+ "/Users/stevestudio2/Desktop/site-factory.env",
+ "/Users/stevestudio2/Projects/site-factory/.env",
+ "/Users/stevestudio2/Projects/site-factory/sites/wholivedthere.com/app/.env.local",
+ "/Users/stevestudio2/Projects/site-factory/sites/bubbesblock.com/app/.env.local",
+ "/Users/stevestudio2/Projects/site-factory/sites/claimmyaddress.com/app/.env.local",
+ "/Users/stevestudio2/Projects/lawyer-directory-builder/.env",
+ "/Users/stevestudio2/Projects/professional-directory/.env"
+ ]
+ },
+ "STRIPE_PUBLISHABLE_KEY": {
+ "digest": "wzmV:944477ab",
+ "label": "Stripe Publishable Key",
+ "last_updated": "2026-05-01T06:23:48.697Z",
+ "validated": false,
+ "verify_status": null,
+ "written_to": [
+ "/Users/stevestudio2/Projects/secrets-manager/.env",
+ "/Users/stevestudio2/Desktop/site-factory.env",
+ "/Users/stevestudio2/Projects/site-factory/.env",
+ "/Users/stevestudio2/Projects/site-factory/sites/wholivedthere.com/app/.env.local",
+ "/Users/stevestudio2/Projects/site-factory/sites/bubbesblock.com/app/.env.local",
+ "/Users/stevestudio2/Projects/site-factory/sites/claimmyaddress.com/app/.env.local",
+ "/Users/stevestudio2/Projects/lawyer-directory-builder/.env",
+ "/Users/stevestudio2/Projects/professional-directory/.env"
+ ]
+ },
+ "ELEVENLABS_API_KEY": {
+ "digest": "45d4:bcdbd4e7",
+ "label": "ElevenLabs Voice Synthesis API Key",
+ "last_updated": "2026-04-30T23:35:20.473Z",
+ "validated": true,
+ "verify_status": 200,
+ "written_to": [
+ "/Users/stevestudio2/Projects/secrets-manager/.env",
+ "/Users/stevestudio2/Desktop/site-factory.env",
+ "/Users/stevestudio2/Projects/dear-bubbe-nextjs/.env.local",
+ "ssh:root@45.61.58.125:/root/Projects/dear-bubbe-nextjs/.env.local"
+ ]
+ },
+ "OPENAI_API_KEY": {
+ "digest": "FYwA:8ad69c60",
+ "label": "OpenAI API Key",
+ "last_updated": "2026-05-01T05:54:19.819Z",
+ "validated": true,
+ "verify_status": 200,
+ "written_to": [
+ "/Users/stevestudio2/Projects/secrets-manager/.env",
+ "/Users/stevestudio2/Desktop/site-factory.env",
+ "/Users/stevestudio2/Projects/dear-bubbe-nextjs/.env.local",
+ "ssh:root@45.61.58.125:/root/Projects/dear-bubbe-nextjs/.env.local"
+ ]
+ },
+ "LAWYER_DIRECTORY_ADMIN_PASSWORD": {
+ "digest": "drfo:4d084bc5",
+ "label": "LAWYER_DIRECTORY_ADMIN_PASSWORD",
+ "last_updated": "2026-05-01T05:55:55.887Z",
+ "validated": false,
+ "verify_status": null,
+ "written_to": [
+ "/Users/stevestudio2/Projects/secrets-manager/.env",
+ "/Users/stevestudio2/Desktop/site-factory.env"
+ ]
+ },
+ "ADMIN_KEY": {
+ "digest": "ncuo:0ef5973a",
+ "label": "ADMIN_KEY",
+ "last_updated": "2026-05-02T06:23:40.535Z",
+ "validated": false,
+ "verify_status": null,
+ "written_to": [
+ "/Users/stevestudio2/Projects/secrets-manager/.env",
+ "/Users/stevestudio2/Desktop/site-factory.env"
+ ]
+ },
+ "STRIPE_TIER_WEBHOOK_SECRET": {
+ "digest": "Styd:882d3909",
+ "label": "Stripe Tier-Subscription Webhook Signing Secret (Counsel & Bar Lawyer Pro $29/mo)",
+ "last_updated": "2026-05-02T14:34:01.676Z",
+ "validated": false,
+ "verify_status": null,
+ "written_to": [
+ "/Users/stevestudio2/Projects/secrets-manager/.env",
+ "/Users/stevestudio2/Desktop/site-factory.env",
+ "/Users/stevestudio2/Projects/lawyer-directory-builder/.env"
+ ]
+ },
+ "STRIPE_PRICE_LAWYER_PRO_MONTHLY": {
+ "digest": "cn1m:766a0822",
+ "label": "Stripe Price ID (public): Counsel & Bar Lawyer Pro $29/mo recurring",
+ "last_updated": "2026-05-02T15:27:15.670Z",
+ "validated": false,
+ "verify_status": null,
+ "written_to": [
+ "/Users/stevestudio2/Projects/secrets-manager/.env",
+ "/Users/stevestudio2/Desktop/site-factory.env",
+ "/Users/stevestudio2/Projects/lawyer-directory-builder/.env"
+ ]
+ },
+ "GEMINI_API_KEY": {
+ "digest": "k720:4295091b",
+ "label": "Google Gemini API Key",
+ "last_updated": "2026-05-02T15:34:58.966Z",
+ "validated": true,
+ "verify_status": 200,
+ "written_to": [
+ "/Users/stevestudio2/Projects/secrets-manager/.env",
+ "/Users/stevestudio2/Desktop/site-factory.env",
+ "/Users/stevestudio2/Projects/Letsbegin/.env.local",
+ "/Users/stevestudio2/Projects/Bertha/kalshi-dash/.env",
+ "/Users/stevestudio2/.claude/skills/ai-analyzer/.env",
+ "/Users/stevestudio2/.claude/skills/enrich-ai-tags/.env"
+ ]
+ },
+ "CLOUDFLARE_ACCOUNT_ID": {
+ "digest": "b1c3:2beb4f25",
+ "label": "CLOUDFLARE_ACCOUNT_ID",
+ "last_updated": "2026-05-02T15:49:51.136Z",
+ "validated": false,
+ "verify_status": null,
+ "written_to": [
+ "/Users/stevestudio2/Projects/secrets-manager/.env",
+ "/Users/stevestudio2/Desktop/site-factory.env"
+ ]
+ },
+ "MOONSHOT_API_KEY": {
+ "digest": "XiYg:b579d15d",
+ "label": "Moonshot AI / Kimi K2 API Key",
+ "last_updated": "2026-05-03T18:02:00.806Z",
+ "validated": true,
+ "verify_status": 200,
+ "written_to": [
+ "/Users/stevestudio2/Projects/secrets-manager/.env",
+ "/Users/stevestudio2/Desktop/site-factory.env",
+ "/Users/stevestudio2/Projects/claude-codex-meeting/.env",
+ "/Users/stevestudio2/.claude/skills/claude-codex/.env"
+ ]
+ },
+ "SMB_BUILDER_ADMIN_TOKEN": {
+ "digest": "LW2g:83fe2ef1",
+ "label": "SMB_BUILDER_ADMIN_TOKEN",
+ "last_updated": "2026-05-04T06:20:37.081Z",
+ "validated": false,
+ "verify_status": null,
+ "written_to": [
+ "/Users/stevestudio2/Projects/secrets-manager/.env",
+ "/Users/stevestudio2/Desktop/site-factory.env"
+ ]
+ }
+ }
+}
\ No newline at end of file
diff --git a/routes.json b/routes.json
new file mode 100644
index 0000000..21a68a3
--- /dev/null
+++ b/routes.json
@@ -0,0 +1,500 @@
+{
+ "_comment": "Per-secret routing table. Each entry: master + extra destinations. Master is implicit at ~/Projects/secrets-manager/.env + ~/Desktop/site-factory.env.",
+ "services": {
+ "MOONSHOT_API_KEY": {
+ "label": "Moonshot AI / Kimi K2 API Key",
+ "verify": {
+ "method": "GET",
+ "url": "https://api.moonshot.ai/v1/models",
+ "auth": "bearer"
+ },
+ "destinations": [
+ {
+ "type": "project",
+ "path": "~/Projects/claude-codex-meeting/.env"
+ },
+ {
+ "type": "skill",
+ "name": "claude-codex"
+ }
+ ]
+ },
+ "CLOUDFLARE_API_TOKEN": {
+ "label": "Cloudflare API Token",
+ "verify": {
+ "method": "GET",
+ "url": "https://api.cloudflare.com/client/v4/user/tokens/verify",
+ "auth": "bearer"
+ },
+ "destinations": [
+ {
+ "type": "project",
+ "path": "~/Projects/site-factory/.env"
+ },
+ {
+ "type": "skill",
+ "name": "cloudflare-manager"
+ },
+ {
+ "type": "skill",
+ "name": "setup-domains"
+ },
+ {
+ "type": "skill",
+ "name": "domain-setup"
+ }
+ ]
+ },
+ "STRIPE_SECRET_KEY": {
+ "label": "Stripe Secret Key",
+ "verify": {
+ "method": "GET",
+ "url": "https://api.stripe.com/v1/balance",
+ "auth": "basic-sk"
+ },
+ "destinations": [
+ {
+ "type": "project",
+ "path": "~/Projects/site-factory/.env"
+ },
+ {
+ "type": "site_local",
+ "domains": [
+ "wholivedthere.com",
+ "bubbesblock.com",
+ "claimmyaddress.com"
+ ]
+ },
+ {
+ "type": "project",
+ "path": "~/Projects/lawyer-directory-builder/.env"
+ },
+ {
+ "type": "project",
+ "path": "~/Projects/professional-directory/.env"
+ }
+ ]
+ },
+ "STRIPE_PUBLISHABLE_KEY": {
+ "label": "Stripe Publishable Key",
+ "destinations": [
+ {
+ "type": "project",
+ "path": "~/Projects/site-factory/.env"
+ },
+ {
+ "type": "site_local",
+ "domains": [
+ "wholivedthere.com",
+ "bubbesblock.com",
+ "claimmyaddress.com"
+ ]
+ },
+ {
+ "type": "project",
+ "path": "~/Projects/lawyer-directory-builder/.env"
+ },
+ {
+ "type": "project",
+ "path": "~/Projects/professional-directory/.env"
+ }
+ ]
+ },
+ "STRIPE_WEBHOOK_SECRET": {
+ "label": "Stripe Webhook Signing Secret",
+ "destinations": [
+ {
+ "type": "project",
+ "path": "~/Projects/site-factory/.env"
+ },
+ {
+ "type": "site_local",
+ "domains": [
+ "wholivedthere.com",
+ "bubbesblock.com",
+ "claimmyaddress.com"
+ ]
+ },
+ {
+ "type": "project",
+ "path": "~/Projects/lawyer-directory-builder/.env"
+ }
+ ]
+ },
+ "STRIPE_TIER_WEBHOOK_SECRET": {
+ "label": "Stripe Tier-Subscription Webhook Signing Secret (Counsel & Bar Lawyer Pro $29/mo)",
+ "destinations": [
+ {
+ "type": "project",
+ "path": "~/Projects/lawyer-directory-builder/.env"
+ }
+ ]
+ },
+ "STRIPE_PRICE_LAWYER_PRO_MONTHLY": {
+ "label": "Stripe Price ID (public): Counsel & Bar Lawyer Pro $29/mo recurring",
+ "destinations": [
+ {
+ "type": "project",
+ "path": "~/Projects/lawyer-directory-builder/.env"
+ }
+ ]
+ },
+ "VERCEL_TOKEN": {
+ "label": "Vercel API Token",
+ "verify": {
+ "method": "GET",
+ "url": "https://api.vercel.com/v2/user",
+ "auth": "bearer"
+ },
+ "destinations": [
+ {
+ "type": "project",
+ "path": "~/Projects/site-factory/.env"
+ }
+ ]
+ },
+ "PURELYMAIL_API_TOKEN": {
+ "label": "PurelyMail API Token",
+ "verify": {
+ "method": "POST",
+ "url": "https://purelymail.com/api/v0/checkAccount",
+ "auth": "bearer",
+ "body": "{}"
+ },
+ "destinations": [
+ {
+ "type": "project",
+ "path": "~/Projects/site-factory/.env"
+ }
+ ]
+ },
+ "GODADDY_API_KEY": {
+ "label": "GoDaddy API Key",
+ "destinations": [
+ {
+ "type": "mcp",
+ "server": "domain-suite",
+ "key": "GODADDY_API_KEY"
+ }
+ ]
+ },
+ "GODADDY_API_SECRET": {
+ "label": "GoDaddy API Secret",
+ "destinations": [
+ {
+ "type": "mcp",
+ "server": "domain-suite",
+ "key": "GODADDY_API_SECRET"
+ }
+ ]
+ },
+ "BROWSERBASE_API_KEY": {
+ "label": "Browserbase API Key",
+ "destinations": [
+ {
+ "type": "skill",
+ "name": "browserbase"
+ }
+ ]
+ },
+ "BROWSERBASE_PROJECT_ID": {
+ "label": "Browserbase Project ID",
+ "destinations": [
+ {
+ "type": "skill",
+ "name": "browserbase"
+ }
+ ]
+ },
+ "ANTHROPIC_API_KEY": {
+ "label": "Anthropic API Key",
+ "verify": {
+ "method": "POST",
+ "url": "https://api.anthropic.com/v1/messages",
+ "auth": "x-api-key",
+ "body": "{\"model\":\"claude-haiku-4-5\",\"max_tokens\":1,\"messages\":[{\"role\":\"user\",\"content\":\"hi\"}]}"
+ },
+ "destinations": [
+ {
+ "type": "project",
+ "path": "~/Projects/Letsbegin/.env.local"
+ },
+ {
+ "type": "project",
+ "path": "~/Projects/dear-bubbe-nextjs/.env"
+ }
+ ]
+ },
+ "OPENAI_API_KEY": {
+ "label": "OpenAI API Key",
+ "verify": {
+ "method": "GET",
+ "url": "https://api.openai.com/v1/models",
+ "auth": "bearer"
+ },
+ "destinations": [
+ {
+ "type": "project",
+ "path": "~/Projects/dear-bubbe-nextjs/.env.local"
+ },
+ {
+ "type": "project",
+ "host": "45.61.58.125",
+ "user": "root",
+ "path": "/root/Projects/dear-bubbe-nextjs/.env.local"
+ },
+ {
+ "type": "project",
+ "path": "~/Projects/animals/.env"
+ }
+ ]
+ },
+ "GEMINI_API_KEY": {
+ "label": "Google Gemini API Key",
+ "verify": {
+ "method": "GET",
+ "url": "https://generativelanguage.googleapis.com/v1beta/models?key={value}",
+ "auth": "url"
+ },
+ "destinations": [
+ {
+ "type": "project",
+ "path": "~/Projects/Letsbegin/.env.local"
+ },
+ {
+ "type": "project",
+ "path": "~/Projects/Bertha/kalshi-dash/.env"
+ },
+ {
+ "type": "skill",
+ "name": "ai-analyzer"
+ },
+ {
+ "type": "skill",
+ "name": "enrich-ai-tags"
+ }
+ ]
+ },
+ "GOOGLE_GENERATIVE_AI_API_KEY": {
+ "label": "Google Generative AI API Key (alias of GEMINI_API_KEY)",
+ "verify": {
+ "method": "GET",
+ "url": "https://generativelanguage.googleapis.com/v1beta/models?key={value}",
+ "auth": "url"
+ },
+ "destinations": [
+ {
+ "type": "project",
+ "path": "~/Projects/Letsbegin/.env.local"
+ }
+ ]
+ },
+ "SHOPIFY_ADMIN_TOKEN": {
+ "label": "Shopify Admin API Access Token",
+ "destinations": []
+ },
+ "SHOPIFY_API_KEY": {
+ "label": "Shopify API Key",
+ "destinations": []
+ },
+ "RESEND_API_KEY": {
+ "label": "Resend API Key",
+ "verify": {
+ "method": "GET",
+ "url": "https://api.resend.com/domains",
+ "auth": "bearer"
+ },
+ "destinations": []
+ },
+ "STRIPE_RESTRICTED_KEY": {
+ "label": "Stripe Restricted Key (site-factory)",
+ "verify": {
+ "method": "GET",
+ "url": "https://api.stripe.com/v1/balance",
+ "auth": "basic-sk"
+ },
+ "destinations": [
+ {
+ "type": "project",
+ "path": "~/Projects/site-factory/.env"
+ }
+ ]
+ },
+ "DPLA_API_KEY": {
+ "label": "Digital Public Library of America API Key",
+ "verify": {
+ "method": "GET",
+ "url": "https://api.dp.la/v2/items?api_key={value}&q=test&page_size=1",
+ "auth": "url"
+ },
+ "destinations": [
+ {
+ "type": "project",
+ "path": "~/Projects/wholivedthere/.env"
+ },
+ {
+ "type": "project",
+ "path": "~/Projects/claimmyaddress/.env"
+ },
+ {
+ "type": "project",
+ "path": "~/Projects/bubbesblock/.env"
+ },
+ {
+ "type": "skill",
+ "name": "la-research-agent"
+ }
+ ]
+ },
+ "GEMINI_API_KEY_RALPH": {
+ "label": "Google Gemini API Key (dedicated to Letsbegin Ralph runner)",
+ "verify": {
+ "method": "GET",
+ "url": "https://generativelanguage.googleapis.com/v1beta/models?key={value}",
+ "auth": "url"
+ },
+ "destinations": [
+ {
+ "type": "project",
+ "path": "~/Projects/Letsbegin/.env.local"
+ },
+ {
+ "type": "project",
+ "host": "45.61.58.125",
+ "user": "root",
+ "path": "/root/Projects/Letsbegin/.env.local"
+ }
+ ]
+ },
+ "ELEVENLABS_API_KEY": {
+ "label": "ElevenLabs Voice Synthesis API Key",
+ "verify": {
+ "method": "GET",
+ "url": "https://api.elevenlabs.io/v1/user",
+ "auth": "header",
+ "headerName": "xi-api-key"
+ },
+ "destinations": [
+ {
+ "type": "project",
+ "path": "~/Projects/dear-bubbe-nextjs/.env.local"
+ },
+ {
+ "type": "project",
+ "host": "45.61.58.125",
+ "user": "root",
+ "path": "/root/Projects/dear-bubbe-nextjs/.env.local"
+ }
+ ]
+ },
+ "NEXT_PUBLIC_GOOGLE_MAPS_API_KEY": {
+ "label": "Google Maps JavaScript API Key (browser-exposed; needs HTTP-referrer restrictions)",
+ "verify": {
+ "method": "GET",
+ "url": "https://maps.googleapis.com/maps/api/streetview/metadata?location=34.05,-118.25&key={value}",
+ "success": "json.status === \"OK\" || json.status === \"ZERO_RESULTS\"",
+ "note": "Validates by hitting Street View Static API metadata endpoint; OK or ZERO_RESULTS both prove the key is enabled and unexpired."
+ },
+ "destinations": [
+ {
+ "type": "project",
+ "path": "~/Projects/stayclaim/.env.local"
+ },
+ {
+ "type": "project",
+ "path": "~/Projects/wholivedthere/.env"
+ },
+ {
+ "type": "project",
+ "path": "~/Projects/claimmyaddress/.env"
+ },
+ {
+ "type": "project",
+ "path": "~/Projects/bubbesblock/.env"
+ },
+ {
+ "type": "remote",
+ "host": "root@45.61.58.125",
+ "path": "/root/public-projects/pastdoor/.env.local"
+ },
+ {
+ "type": "remote",
+ "host": "root@45.61.58.125",
+ "path": "/root/public-projects/pastdoor/.env.production"
+ },
+ {
+ "type": "project",
+ "path": "~/Projects/jill-website/.env"
+ }
+ ]
+ }
+ },
+ "leak_patterns": [
+ {
+ "name": "stripe-live-secret",
+ "regex": "sk_live_[A-Za-z0-9]{20,}"
+ },
+ {
+ "name": "stripe-test-secret",
+ "regex": "sk_test_[A-Za-z0-9]{20,}"
+ },
+ {
+ "name": "stripe-publishable",
+ "regex": "pk_live_[A-Za-z0-9]{20,}"
+ },
+ {
+ "name": "browserbase",
+ "regex": "bb_live_[A-Za-z0-9]+"
+ },
+ {
+ "name": "google-api-key",
+ "regex": "AIza[0-9A-Za-z_-]{35}"
+ },
+ {
+ "name": "google-oauth-access",
+ "regex": "ya29\\.[A-Za-z0-9_-]{20,}"
+ },
+ {
+ "name": "github-pat",
+ "regex": "ghp_[A-Za-z0-9]{36}"
+ },
+ {
+ "name": "github-fine-grained",
+ "regex": "github_pat_[A-Za-z0-9_]{60,}"
+ },
+ {
+ "name": "slack-bot",
+ "regex": "xox[baprs]-[A-Za-z0-9-]{10,}"
+ },
+ {
+ "name": "openai-key",
+ "regex": "sk-[A-Za-z0-9]{40,}"
+ },
+ {
+ "name": "anthropic-key",
+ "regex": "sk-ant-[A-Za-z0-9_-]{50,}"
+ },
+ {
+ "name": "cf-token-40hex",
+ "regex": "(?:cloudflare|cf_token|dns_cloudflare_api_token)[^A-Za-z0-9]+([A-Za-z0-9_-]{40})"
+ }
+ ],
+ "CLOUDFLARE_ACCOUNT_ID": [
+ "/Users/stevestudio2/.claude/skills/domain-check/.env",
+ "/Users/stevestudio2/.claude/skills/domain-dns-setup/.env",
+ "/Users/stevestudio2/.claude/skills/domain-email-setup/.env",
+ "/Users/stevestudio2/.claude/skills/domain-full-setup/.env",
+ "/Users/stevestudio2/.claude/skills/domain-register/.env",
+ "/Users/stevestudio2/.claude/skills/domain-setup/.env",
+ "/Users/stevestudio2/.claude/skills/setup-domains/.env"
+ ],
+ "SMB_BUILDER_ADMIN_TOKEN": {
+ "destinations": [
+ {
+ "type": "env_file",
+ "path": "/Users/stevestudio2/Projects/small-business-builder/.env",
+ "key": "ADMIN_TOKEN"
+ }
+ ]
+ }
+}
\ No newline at end of file
(oldest)
·
back to Secrets Manager
·
routes: add NPH (Mac2 + Kamatera) to STRIPE_SECRET_KEY + STR e14bede →