Guidance for AI coding agents (Claude Code, Cursor, Copilot, Aider, etc.) working in this repository. For human contributors, the same conventions apply — see also CLAUDE.md and README.md.
@robotnetworks/robotnet — the first-party CLI for Robot Networks. Written in TypeScript, distributed via npm and Homebrew, runs on Node.js 18+.
Docs: https://docs.robotnet.works/cli
npm install
npm run build # compiles to dist/
npm run typecheck # no emit, just typecheck
npm test # runs all tests (Node test runner + tsx)Before proposing a change as complete, always run npm run typecheck and npm test. Both must pass.
src/index.ts— commander setup and subcommand registrationsrc/commands/<topic>.ts— one file per subcommand group; each exportsregister<Topic>Command(program)src/api/— REST client and modelssrc/auth/— OAuth/PKCE/client credentials, token storesrc/daemon/— background listener lifecyclesrc/realtime/— WebSocket listenersrc/output/— human and JSON formatterssrc/errors.ts—RobotNetCLIErrorhierarchybin/robotnet.js— published entrypoint (loadsdist/index.js)tests/*.test.ts— unit tests, run withnode --import tsx --test
- TypeScript strictness: fully typed signatures, no implicit
any,Literalunions for enums. - Errors: throw a subclass of
RobotNetCLIErrorfrom command paths so the root handler formats them consistently. Do notprocess.exit()inside a command — throw instead. - HTTP: route all requests through
src/api/client.ts. Do not add rawfetchcalls in commands. - Auth: never log tokens, secrets, or authorization headers. The token store is the single source of truth for credentials.
- Output: support both human output and
--jsonfor any command that prints data. Use the helpers insrc/output/. - Timestamps: epoch milliseconds everywhere — storage, API, logs.
- Naming:
camelCasefunctions/variables,PascalCaseclasses,SCREAMING_SNAKE_CASEconstants. Be explicit (getAgentByHandle, notget). - No default exports in new modules. Named exports only.
- Tests: every new business-logic module gets tests. Cover error paths, not just happy paths. Use the Node built-in test runner (
node:test) — do not introduce Jest/Vitest.
- Do not add new runtime dependencies without a clear justification. The CLI ships globally; every dependency is a supply-chain risk.
- Do not edit files under
dist/— it is build output. - Do not commit
.envfiles, tokens, or personal paths. See.gitignore. - Do not skip tests or typecheck to "get it working" — fix the root cause.
- Do not introduce
anyas a shortcut; narrow unknown values at the boundary.
Adding a new subcommand:
- Create
src/commands/<topic>.tswith aregister<Topic>Command(program: Command)function. - Import it in
src/index.tsand call it after the existingregister*calls. - Put any HTTP or business logic in a helper module; keep the command file thin.
- Add
tests/<topic>-command.test.ts(or extend an existing test file) covering success + error cases. - Update
README.mdusage section and add a line toCHANGELOG.mdunder## [Unreleased].
- Bump
versioninpackage.json. - Move
## [Unreleased]entries inCHANGELOG.mdunder the new version with today's date. npm publish—prepublishOnlyenforces build + tests.
- Issues & PRs: https://github.com/RobotNetworks/robotnet-cli
- Email: nick@robotnet.works