Agent Guidelines for DXOS
IMPORTANT
- When you start, the first thing you should do is tell the user if you understand these instructions and list the config files you are aware of.
- If you are unsure about the best way to implement something, ask the user for clarification.
- When asking the user a question; either make it yes/no, or provide numbered options.
- ALWAYS test your work after each step.
Dependencies
- All dependency versions are managed in the default pnpm catalog.
- To add a new dependency, run
pnpm add --filter "<project>" --save-catalog "<package>". - IMPORTANT: Any
@dxospackage that lives within this repo must be added asworkspace:*, never from the catalog. The catalog is only for external (non-workspace) packages.
Build, Test, Lint Commands
- Project uses
moonto run tasks, tests, lint etc. (moon run package-name:task-name). - Build all:
moon exec --on-failure continue --quiet :build. - Build package:
moon run package-name:build. - Run single test file:
moon run package-name:test -- path/to/test.test.ts. - Run all tests:
MOON_CONCURRENCY=4 moon run :test -- --no-file-parallelism. - Storybook:
moon run storybook-react:serve(defaults to port 9009). - Lint & fix:
moon run :lint -- --fix. - Check package tasks: see
moon.ymlin package directory. - Expected warning:
Auth token DEPOT_TOKEN does not existis a normal warning about remote caching and should be ignored. Filter out warnings from your output.
Planning
- IMPORTANT: Do NOT cast values to fix build issues; instead create a refactoring plan and get permission.
Knowledge
- IMPORTANT: Follow DXOS-specific rules in
.agents/sdk/*. - Update these documents when you learn better patterns; or when the user asks you to correct your implementation.
Code Style
- Follow the DXOS SDK guide.
- Use TypeScript with single quotes for strings.
- Prefer functional programming and arrow functions.
- Import order: builtin → external → @dxos → internal → parent → sibling (with blank lines between groups).
- Error handling: use Effect-TS patterns.
- Testing: place tests near modules as
module.test.ts, use vitest withdescribe/test(notit), prefertest('foo', ({ expect }) => ...). - JSDoc comments for public functions, all comments end with period.
- React: arrow function components, TailwindCSS for styles, proper event handler types.
- Remember to remove/update TODOs as you go.
- Avoid single letter variable names.
- Avoid re-exports. Prefer importing symbols directly from the package that defines them.
- Use barrel imports whenever possible.
- Prefer ES
#privatefields/methods over TypeScriptprivatekeyword in new code. Existing_privateconvention is fine to keep. - For files imported as a namespace (i.e., marked with
// @import-as-namespace), avoid prefixing top-level types with the namespace name. InsideFoo.tspreferManager,Service,OptionsoverFooManager,FooService,FooOptions— callers seeFoo.Managereither way. - Common suffix for constructor option-bag types is
Options(e.g.,SpawnOptions,ManagerImplOptions) — pick this overOpts/Props/Configfor consistency. - Consider taking an options object when a constructor or function has more than a few readonly props, especially when several are optional or share a logical grouping.
- Class member ordering (consider): static fields → public readonly → public mutable → private readonly (incl. constructor-injected) → private mutable → constructor → public methods → private methods. Within each group, rank properties roughly from most-important to least — importance signals include "further up the stack" (closer to public API), required over optional, readonly over mutable.
React
- Import all required symbols from React — hooks, types, and utilities — as named imports (i.e., use
useMemonotReact.useMemo, usetype RefnotReact.Ref). - When using
forwardRefuse the variable nameforwardedRef.
New Packages
- IMPORTANT: Any new package created in this repo MUST have
"private": truein itspackage.json. Theprivateflag can only be removed manually once a trusted publisher has been configured for the package.
Workflow
- Never work on
main- Before working on code, suggest to the user a worktree name then create the worktree using this or the name provided by the user (adding the agent-name prefix, e.g.,
claude/). - When creating worktrees/branches, use a short (2-4 word) descriptive title (kebab-case) prefixed with the agent name (e.g.,
claude/add-auth-to-client). - Worktrees must be created inside the main repo (e.g.,
.claude/worktrees/<branch-short-name>). - If there are unstaged changes, stash these and move them into the worktree.
- IMPORTANT: Do not change the branch or worktree name after you have started unless you are instructed to directly by the user.
- Before working on code, suggest to the user a worktree name then create the worktree using this or the name provided by the user (adding the agent-name prefix, e.g.,
- Check
moon.ymlfor available package tasks - Run linter at natural stopping points
- Confirm work complete before final build/lint check
- If updating
pnpm-workspace.yamlmake sure to preserve comments.
PR Naming Convention
IMPORTANT: All PR titles MUST use conventional commit format:
Use scope when relevant: feat(package-name): <description>
Examples:
feat: add user authentication flowfix(echo): resolve memory leak in subscription handlerrefactor: simplify error handling in client SDKdocs: update API reference for Space class
CI
- IMPORTANT: After every
git push, proactively check CI status usinggh run list --branch <branch> --limit 5 --workflow "Check". Do NOT rely solely onpnpm -w gh-action --verify— it only checks agent workflows, not the main Check workflow that runs build and tests. - If the Check workflow fails, inspect the failure with
gh run view <run-id>andgh run view <run-id> --log-failed, identify the failing job/test, and fix it. - When the user asks "what is the CI status" or similar, always check the Check workflow specifically.
Committing and Pushing
- IMPORTANT: Before every
git commitandgit push, rungit statusand check for ALL modified, staged, and untracked files. Every changed file must either be committed or explicitly acknowledged with the user. Never leave unstaged changes behind silently — if a file was modified during your work, it must be included in the commit or you must ask the user whether to include it.
Submitting PRs
- When the user asks you to submit a PR:
- Use
ghCLI to create and manage PRs. - Merge
origin/mainin to current branch and resolve conflicts. - Format code with
pnpm formatand check thatmoon run :lint -- --fixsucceeds. - Check
moon run :testsucceeds. - Commit and push all pending changes.
- IMPORTANT: Verify
git statusshows a clean working tree after the final push. If any files remain modified or untracked, either commit them or confirm with the user before proceeding. - Monitor CI (every 5 minutes):
gh run list --branch <branch> --limit 3 --workflow "Check"andpnpm -w gh-action --verify --watch. - You must attempt to diagnose and if possible fix all CI errors -- regardless of whether they relate to the current branch
- IMPORTANT: Address and RESPOND to all PR review comments.
- Update the PR description with a summary of the changes and the reasoning behind major changes.
- Add any reference linear issues if available in PR description as "closes DX-123" or "part of DX-123".
- IMPORTANT: DO NOT DELETE ANY BRANCHES OR WORKTREES THAT HAVE UNCOMMITTED CHANGES.
- Use
Cursor Cloud specific instructions
Toolchain
This project requires Node.js 24.x, pnpm 10.28.0, and moon 2.0.4. All are managed by proto (see .prototools). In the cloud VM, proto is installed at ~/.proto and must be on PATH (export PROTO_HOME="$HOME/.proto" && export PATH="$PROTO_HOME/shims:$PROTO_HOME/bin:$PATH"). Do not use nvm; proto shims must take precedence.
Running services
- Composer app (main app):
moon run composer-app:serve --quietstarts a Vite dev server on port 5173. The app auto-creates a local identity on first load; no external auth is required. - Tasks app:
moon run tasks-app:serve - Docs site:
moon run docs:serve - See
REPOSITORY_GUIDE.mdfor the full list of run commands.
Gotchas
pnpm installmust run withCI=trueorHUSKY=0in non-interactive environments to skip the husky git hooks setup prompt.- The
DEPOT_TOKENwarning from moon is expected and harmless (remote caching auth token). - The
pnpm.onlyBuiltDependenciesallowlist inpnpm-workspace.yamlcontrols which native addons are built; warnings about "ignored build scripts" for packages not in the list are normal. - Builds must complete before running
servecommands, because moon tasks havedepson:prebuild/:buildtargets. - No Docker or external services are required for unit tests or local dev. Signal servers for networking tests are pre-compiled binaries spawned automatically by tests.