Summary
There's no single command to reset focusd's dev-mode state on macOS. Testing the onboarding flow, the permission cards, or any first-run behavior currently means hand-running a mix of tccutil reset, rm -rf against the userData dir, and pkill for the leftover recorder/meet_detector processes. This is fiddly and easy to do incompletely (e.g. forgetting that ~/Library/Application Support/Electron/ collects state too, or that the recorder process keeps a lock file open).
Goal
Add an npm run reset:dev script that takes the dev-mode state back to a true first-run baseline in one command — without affecting a packaged install of focusd on the same machine, and without touching unrelated apps' permissions.
Proposed approach
A scripts/reset-dev.sh that:
-
Kills only path-scoped focusd processes. pkill -f "VideoDB Focusd/bin/recorder" and meet_detector. The full path means we cannot accidentally hit an unrelated process named recorder on the system.
-
TCC reset is restricted to dev launchers only. Resets Screen Recording + Microphone for com.github.Electron, com.googlecode.iterm2, com.apple.Terminal, com.microsoft.VSCode, and Cursor. Does not include com.videodb.focusd — that's the production bundle id, and a packaged install on the same machine should keep its grants. The tccutil reset <Service> <bundle> form fails silently when the bundle has no entry, so the script is safe even when none of these apps have permissions.
-
Always removes the generic Electron dev dir (~/Library/Application Support/Electron/). It's used by Electron before app.name is set, contains only Chromium-style state, and is shared across unpackaged Electron apps — but for a developer asking for a fresh dev state, clearing it is the expected behavior.
-
Userspace wipe is guarded. Dev and prod share ~/Library/Application Support/VideoDB Focusd/ because app.name = 'VideoDB Focusd' in both modes. Naively rm -rf'ing it would wipe a packaged install's onboarding, API key, and SQLite DB. The script:
- Checks
/Applications/VideoDB Focusd.app. If it exists, abort the userData wipe with a clear message and a --force instruction.
- If no packaged install is present, proceeds normally.
- Always exits cleanly so the rest of the reset (TCC, Electron dir, processes) still happens.
-
No keychain access. focusd's API key is stored via Electron safeStorage, which writes an encrypted blob inside userData. Removing userData removes the secret — no security delete-generic-password needed, no risk of touching unrelated keychain entries.
-
macOS-only. Bails with a clear message on other platforms.
-
npm run reset:dev invokes the script via bash scripts/reset-dev.sh, mirroring the existing reset:db pattern in package.json.
What this explicitly does NOT do
- Touch
com.videodb.focusd TCC entries (production bundle id).
- Wipe userData when a packaged install is detected, unless
--force is passed.
- Modify source files,
node_modules, build outputs, or signed binaries.
- Delete keychain entries.
- Reset TCC for any app outside the dev-launcher list.
Verification plan
- With no packaged install:
npm run reset:dev clears userData, the Electron dir, and all dev-launcher TCC entries. Next npm run dev shows the full onboarding flow.
- With a packaged install at
/Applications/VideoDB Focusd.app: npm run reset:dev clears TCC + Electron dir + processes, but preserves the userData dir; the packaged app's data and permissions are untouched. npm run reset:dev -- --force then opts in to the full wipe.
- After the script runs,
tccutil reset ScreenCapture com.videodb.focusd should still report "No such bundle identifier" if no packaged install ever ran on this machine — confirming we did not register a bogus entry.
Summary
There's no single command to reset focusd's dev-mode state on macOS. Testing the onboarding flow, the permission cards, or any first-run behavior currently means hand-running a mix of
tccutil reset,rm -rfagainst the userData dir, andpkillfor the leftover recorder/meet_detector processes. This is fiddly and easy to do incompletely (e.g. forgetting that~/Library/Application Support/Electron/collects state too, or that the recorder process keeps a lock file open).Goal
Add an
npm run reset:devscript that takes the dev-mode state back to a true first-run baseline in one command — without affecting a packaged install of focusd on the same machine, and without touching unrelated apps' permissions.Proposed approach
A
scripts/reset-dev.shthat:Kills only path-scoped focusd processes.
pkill -f "VideoDB Focusd/bin/recorder"andmeet_detector. The full path means we cannot accidentally hit an unrelated process namedrecorderon the system.TCC reset is restricted to dev launchers only. Resets Screen Recording + Microphone for
com.github.Electron,com.googlecode.iterm2,com.apple.Terminal,com.microsoft.VSCode, and Cursor. Does not includecom.videodb.focusd— that's the production bundle id, and a packaged install on the same machine should keep its grants. Thetccutil reset <Service> <bundle>form fails silently when the bundle has no entry, so the script is safe even when none of these apps have permissions.Always removes the generic Electron dev dir (
~/Library/Application Support/Electron/). It's used by Electron beforeapp.nameis set, contains only Chromium-style state, and is shared across unpackaged Electron apps — but for a developer asking for a fresh dev state, clearing it is the expected behavior.Userspace wipe is guarded. Dev and prod share
~/Library/Application Support/VideoDB Focusd/becauseapp.name = 'VideoDB Focusd'in both modes. Naivelyrm -rf'ing it would wipe a packaged install's onboarding, API key, and SQLite DB. The script:/Applications/VideoDB Focusd.app. If it exists, abort the userData wipe with a clear message and a--forceinstruction.No keychain access. focusd's API key is stored via Electron
safeStorage, which writes an encrypted blob inside userData. Removing userData removes the secret — nosecurity delete-generic-passwordneeded, no risk of touching unrelated keychain entries.macOS-only. Bails with a clear message on other platforms.
npm run reset:devinvokes the script viabash scripts/reset-dev.sh, mirroring the existingreset:dbpattern inpackage.json.What this explicitly does NOT do
com.videodb.focusdTCC entries (production bundle id).--forceis passed.node_modules, build outputs, or signed binaries.Verification plan
npm run reset:devclears userData, the Electron dir, and all dev-launcher TCC entries. Nextnpm run devshows the full onboarding flow./Applications/VideoDB Focusd.app:npm run reset:devclears TCC + Electron dir + processes, but preserves the userData dir; the packaged app's data and permissions are untouched.npm run reset:dev -- --forcethen opts in to the full wipe.tccutil reset ScreenCapture com.videodb.focusdshould still report "No such bundle identifier" if no packaged install ever ran on this machine — confirming we did not register a bogus entry.