Developing Latchkey
August 27, 2026 ยท View on GitHub
Thank you for considering contributing to Latchkey!
Setting up your environment
Make sure you're using nvm so that your node version
corresponds to the one listed in .nvmrc.
After that, the easiest way to set up your system so that you can run Latchkey while working on it is to clone this repository and then run:
npm install && npm run build && npm link
After that, every time you make a change to the code, run
npm run build. Invoking latchkey in your terminal will
then use the version you just built. (npm run dev runs the
compiler in watch mode if you would rather not rebuild by hand.)
Dev shim: run from source, no rebuild
Alternatively, put the dev shim on your PATH (ahead of any
npm-linked or globally installed latchkey):
npm run install-dev-shim
This symlinks ~/.local/bin/latchkey to scripts/latchkey and
warns if something else on your PATH still shadows it.
The shim runs src/cli.ts under node via the checkout's own
tsx, so edits take effect immediately with no
build step. It resolves
the checkout from your current directory, which makes worktrees
and secondary clones work without relinking; outside any checkout
it falls back to the checkout the shim was installed from. The
target checkout just needs npm install to have been run in it.
To get rid of it again, run:
npm run uninstall-dev-shim
This removes ~/.local/bin/latchkey (only if it is the dev shim)
and tells you what latchkey resolves to afterwards.
Before you submit a PR
- Run
npm run lintandnpm testto validate your changes. - Run
npm run formatto apply autoformatting.
Adding a new service
Services in Latchkey come in two tiers:
- With basic support that requires users to directly set
API credentials via
latchkey auth setorlatchkey auth set-nocurl. - With support for browser-based authentication.
Basic support
If you only want to make Latchkey aware of the existence of a particular service, you just need to implement a Service class with a few attributes (like a name, base API URL(s) and a few others). As an example, see the Mailchimp service.
Support for browser-based authentication
In this case, you will typically need to add several additional methods to the implementation from the previous section.
Each third-party service needs to be approached slightly differently. You need to start by asking yourself the following question:
Can public API credentials be extracted from the network traffic that flows between the browser and the service's website during or after login?
If the answer is yes, see how the Slack service is implemented and try to do it similarly.
Otherwise, ask yourself the following question:
Can an API token be created in the user's account (e.g. in Developer settings)?
If so, see how the Linear service is implemented and try to do it similarly.
If the answer is no in both cases, it's a special case and you're on your own!
Above, when we say "API", we always mean a public API. Do not expose undocumented private APIs through Latchkey - agents should be able to determine usage by consulting the documentation.
Service info
Every service must include an info property that provides developer notes. This information is accessible via latchkey services info <service_name> and helps agents and users understand service-specific details such as:
- Links to API documentation
- Special requirements (e.g., need to run
latchkey auth browser-preparefirst) - Any caveats or limitations
Keep info (and comments on the Service class) about the service itself, not
the Detent scopes or permission names (not everyone uses them).
Potentially useful helpers
Codegen
Use this tool to record a full session where you log into a service and generate an API key:
npx tsx scripts/codegen.ts <service_name> <initial_url>
This tool combines both the request/response recorder (see below) and Playwright's own codegen functionality.
You can still use Playwright's own codegen if this tool is not sufficient:
npx playwright codegen --target=javascript https://login-page.example.com/
Request / response recorder
Use this to record the request/response pairs of your browser login sequence as plaintext JSON files. The resulting recording can be inspected, either manually or with the help of AI, to see if you can extract an API token or something similar from there.
npx tsx scripts/recordBrowserSession.ts <service_name>
If you have jq installed on your system, you can then
start exploring, for instance like this:
cat path/to/recording/login_session.json | jq -C | less -R
File encryptor / decryptor
During development, it may sometimes be necessary to inspect the
credentials stored in ~/.latchkey/credentials.json.enc.
To do that, you can use scripts/cryptFile.ts. For example:
npx tsx scripts/cryptFile.ts decrypt ~/.latchkey/credentials.json.enc
Environment variables
The following environment variables can be set for development and debugging:
LATCHKEY_DISABLE_SPINNER=1: Disables the spinner overlay that normally hides browser activity during credential finalization. Useful for debugging browser automation sequences.
Style guidelines
- Try to make new code look as similar to existing code as possible.
- See CLAUDE.md for additional details.