|
| 1 | +# AGENTS.md |
| 2 | + |
| 3 | +Guidance for AI coding agents (Claude Code, Cursor, Copilot, Codex, Aider, etc.) working in this repository. This is the canonical source. `CLAUDE.md` at the repo root imports this file via `@AGENTS.md`; per-subproject `AGENTS.md` / `CLAUDE.md` pairs cover commands and gotchas specific to each component. |
| 4 | + |
| 5 | +## What this repo is |
| 6 | + |
| 7 | +Sui Stack Messaging — encrypted messaging tooling for Web3 apps, built on Sui, Seal, and Walrus. Multi-component repo: canonical Move contracts and TypeScript SDK, plus reference implementations of a relayer, indexer, and demo chat UI that downstream projects will fork. |
| 8 | + |
| 9 | +## Repo layout |
| 10 | + |
| 11 | +``` |
| 12 | +move/ CANONICAL Move smart contracts |
| 13 | + packages/sui_stack_messaging/ canonical messaging package (published mainnet+testnet) |
| 14 | + packages/example_app/ reference extension examples (custom seal policy, paid join rule) |
| 15 | + design_docs/ Move-side design docs |
| 16 | +
|
| 17 | +ts-sdks/packages/sui-stack-messaging/ CANONICAL TypeScript SDK (@mysten/sui-stack-messaging on npm) |
| 18 | +
|
| 19 | +relayer/ REFERENCE Rust axum relayer (fork-and-extend) |
| 20 | +walrus-discovery-indexer/ REFERENCE TS indexer for Walrus blobs (fork-and-extend) |
| 21 | +chat-app/ REFERENCE Vite + React 19 demo (fork-and-extend) |
| 22 | +
|
| 23 | +publish/ INTERNAL maintainer-only helper for publishing the canonical Move package |
| 24 | +docs/sui-stack-messaging/ Authoritative dev documentation |
| 25 | +``` |
| 26 | + |
| 27 | +External canonical dependency: [`sui-groups`](https://github.com/MystenLabs/sui-groups). Treat as published infrastructure; do not vendor. |
| 28 | + |
| 29 | +## Canonical vs reference — the mental model |
| 30 | + |
| 31 | +**Canonical** (`move/packages/sui_stack_messaging/`, `ts-sdks/packages/sui-stack-messaging/`): consume; do not fork. |
| 32 | + |
| 33 | +- Move contracts are already published to mainnet and testnet (see "Canonical package addresses" below). |
| 34 | +- The SDK is on npm as `@mysten/sui-stack-messaging`. Pin the version, don't vendor the source. |
| 35 | +- To extend: write your own Move package depending on `sui_stack_messaging` (see `move/packages/example_app/` for two worked examples), or implement the SDK's transport/storage/recovery interfaces. |
| 36 | + |
| 37 | +**Reference** (`relayer/`, `walrus-discovery-indexer/`, `chat-app/`): fork as a starting point and modify freely. |
| 38 | + |
| 39 | +- Intentionally minimal. Real deployments will replace storage backends, auth strategies, observability, deployment topology. |
| 40 | +- The SDK talks to the relayer through the `RelayerTransport` TS interface — implement your own transport without forking the Rust code, or fork the Rust code. |
| 41 | + |
| 42 | +## Build / test / lint commands |
| 43 | + |
| 44 | +Each subproject has its own `AGENTS.md` with the commands and invariants specific to that component. When working inside a subproject, read its `AGENTS.md` first: |
| 45 | + |
| 46 | +- [`move/AGENTS.md`](./move/AGENTS.md) — Move builds, tests, edition, Sui CLI version |
| 47 | +- [`ts-sdks/AGENTS.md`](./ts-sdks/AGENTS.md) — pnpm, turbo, codegen, changesets, lint |
| 48 | +- [`relayer/AGENTS.md`](./relayer/AGENTS.md) — cargo, clippy, docker compose, `.env` setup |
| 49 | +- [`walrus-discovery-indexer/AGENTS.md`](./walrus-discovery-indexer/AGENTS.md) — TS indexer dev loop, filter pipeline |
| 50 | +- [`chat-app/AGENTS.md`](./chat-app/AGENTS.md) — Vite, locally-linked SDK, demo-app constraints |
| 51 | +- [`publish/AGENTS.md`](./publish/AGENTS.md) — maintainer-only Move publish helper |
| 52 | + |
| 53 | +When you `cd` into one of these directories, Claude Code auto-loads the relevant `CLAUDE.md` (which imports the subproject's `AGENTS.md`). Other agents should open the file by hand. |
| 54 | + |
| 55 | +## Repo invariants |
| 56 | + |
| 57 | +- **Do not edit `ts-sdks/packages/sui-stack-messaging/src/contracts/sui_stack_messaging/`** — auto-generated by `pnpm codegen`. (Also enforced as a path-scoped rule under `.claude/rules/`.) |
| 58 | +- **Do not edit `move/packages/sui_stack_messaging/Published.toml`** — committed source of truth for deployed package IDs. |
| 59 | +- **Do not fork the canonical Move package** — to extend, write your own package depending on `sui_stack_messaging`. |
| 60 | +- **Do not redefine canonical permission types** (`MessagingSender`, `MessagingReader`, `MessagingEditor`, `MessagingDeleter`, `MetadataAdmin`, `SuiNsAdmin`). |
| 61 | +- **Do not break the relayer wire protocol** — SDK and indexer depend on its message and Walrus archive formats. Cross-impact: changes here must update SDK + relayer + indexer + the protocol doc together. (Also enforced as a path-scoped rule under `.claude/rules/`.) |
| 62 | +- **Do not bump SDK versions ad hoc** — coordinate via `pnpm changeset` (see `ts-sdks/RELEASING.md`). |
| 63 | +- **`minimumReleaseAge: 2880`** is enforced by `ts-sdks/pnpm-workspace.yaml` (2-day floor on new dependency releases). Mysten packages are excluded. |
| 64 | + |
| 65 | +## Canonical package addresses |
| 66 | + |
| 67 | +From `move/packages/sui_stack_messaging/Published.toml`: |
| 68 | + |
| 69 | +| Network | sui_stack_messaging | |
| 70 | +| ------- | -------------------------------------------------------------------- | |
| 71 | +| Mainnet | `0xcbd2f4c25c7f799c45c0c9f221850178b711b2c89916c8e99038aa8ac609a62e` | |
| 72 | +| Testnet | `0x047696be0e98f1b47a99727fecf2955cadb23c56f67c6b872b74e3ad59d51b46` | |
| 73 | + |
| 74 | +Sui Groups (from `relayer/.env.example`): |
| 75 | + |
| 76 | +| Network | sui_groups | |
| 77 | +| ------- | -------------------------------------------------------------------- | |
| 78 | +| Mainnet | `0x541840ae7df705d1c6329c22415ed61f9140a18b79b13c1c9dc7415b115c1ba8` | |
| 79 | +| Testnet | `0xba8a26d42bc8b5e5caf4dac2a0f7544128d5dd9b4614af88eec1311ade11de79` | |
| 80 | + |
| 81 | +The SDK auto-detects testnet/mainnet via constants in `ts-sdks/packages/sui-stack-messaging/src/constants.ts`. |
| 82 | + |
| 83 | +## Where to find documentation |
| 84 | + |
| 85 | +Authoritative docs live in `docs/sui-stack-messaging/`: |
| 86 | + |
| 87 | +- `Installation.md`, `Setup.md`, `Examples.md` — getting started. |
| 88 | +- `APIRef.md` — full SDK API reference. |
| 89 | +- `Encryption.md`, `Security.md` — crypto + trust model. Read before changing auth or transport. |
| 90 | +- `Relayer.md` — protocol the relayer implements (required reading before forking it). |
| 91 | +- `Attachments.md`, `ArchiveRecovery.md`, `GroupDiscovery.md` — feature deep dives. |
| 92 | +- `Extending.md` — custom seal policies, transports, storage adapters, recovery transports. |
| 93 | +- `Testing.md` — test strategy across SDK / relayer / Move. |
| 94 | + |
| 95 | +Per-component: |
| 96 | + |
| 97 | +- `relayer/README.md` — relayer reference (auth pipeline, API, storage, sync). |
| 98 | +- `walrus-discovery-indexer/README.md` + `walrus-discovery-indexer/docs/README.md` — indexer reference. |
| 99 | +- `chat-app/README.md` + `chat-app/docs/SYSTEM_DESIGN.md` — demo app reference. |
| 100 | +- `move/design_docs/REQUIREMENTS.md` + `move/design_docs/sui_stack_messaging/*.md` — Move package design. |
| 101 | +- `ts-sdks/RELEASING.md` — release/changeset workflow. |
| 102 | + |
| 103 | +## Skills for repo-specific tasks |
| 104 | + |
| 105 | +`.claude/skills/` contains skill files used by Claude Code. Other agents can read them as plain Markdown — each `SKILL.md` is a focused, command-first runbook for one task. |
| 106 | + |
| 107 | +**Fork-and-extend skills** (used by anyone who consumes or modifies the reference implementations): |
| 108 | + |
| 109 | +- `develop-on-sui-stack-messaging/SKILL.md` — orientation; canonical vs reference. |
| 110 | +- `spin-up-relayer/SKILL.md` — run the reference relayer locally. |
| 111 | +- `spin-up-e2e-stack/SKILL.md` — relayer + indexer + chat-app together. |
| 112 | +- `develop-relayer/SKILL.md` — fork-and-extend the Rust relayer. |
| 113 | +- `develop-walrus-indexer/SKILL.md` — fork-and-extend the TS indexer. |
| 114 | +- `extend-smart-contracts/SKILL.md` — add custom Move modules on top of `sui_stack_messaging`. |
| 115 | + |
| 116 | +**Builder-as-SDK-consumer skills** (consuming the canonical npm SDK in your own app): |
| 117 | + |
| 118 | +- `integrate-sui-stack-messaging/SKILL.md` — bootstrap the SDK into an existing dapp. |
| 119 | +- `configure-walrus-storage-via-sdk/SKILL.md` — programmatic Walrus storage (no publisher/aggregator dependency). |
| 120 | +- `configure-custom-relayer-transport/SKILL.md` — customize the relayer transport layer |
| 121 | +- `configure-session-keys/SKILL.md` — managed vs externally-provided Seal session keys. |
| 122 | +- `debug-encryption-flow/SKILL.md` — diagnose decryption failures end-to-end. |
| 123 | + |
| 124 | +## Tooling baseline |
| 125 | + |
| 126 | +- Node: pnpm `>=10.17.0` — **use pnpm 10.x.** pnpm v11 no longer reads this repo's `package.json` `pnpm` config (build approvals + `overrides`), so a fresh install fails with `ERR_PNPM_IGNORED_BUILDS` / `ERR_PNPM_LOCKFILE_CONFIG_MISMATCH`. See [`docs/pnpm-v11-troubleshooting.md`](docs/pnpm-v11-troubleshooting.md). |
| 127 | +- Rust: stable + clippy + rustfmt. |
| 128 | +- Sui CLI: required for Move build/test/publish |
| 129 | +- Move edition: 2024. |
| 130 | + |
| 131 | +## Code style |
| 132 | + |
| 133 | +- **TypeScript** (`ts-sdks/`): formatted by Prettier, linted by oxlint. Both configured at `ts-sdks/` root. Don't introduce ESLint or other linters — oxlint is the chosen linter here. |
| 134 | +- **Rust** (`relayer/`): formatted by `rustfmt`, linted by `clippy` (toolchain pinned in `relayer/rust-toolchain.toml`). |
| 135 | +- **Move** (`move/`): edition `2024`. No formatter shipped in-repo. |
| 136 | +- **Imports**: TS uses `@ianvs/prettier-plugin-sort-imports`; don't reorder by hand. |
| 137 | +- **No emojis** in committed code, comments, or docs unless explicitly requested. |
| 138 | +- **Comments**: write only when the _why_ is non-obvious. Don't restate what the code does or reference the current task / PR / issue number. |
| 139 | + |
| 140 | +## Security considerations |
| 141 | + |
| 142 | +- **Encryption invariants are load-bearing.** The envelope encryption format and Seal identity-bytes layout (`[group_id (32)][key_version (8 LE u64)]`) are shared across SDK + Move + relayer. Don't redefine them in a fork. See `docs/sui-stack-messaging/Encryption.md`. |
| 143 | +- **Sender verification is independent of the relayer.** Every group member can independently verify a message's sender by re-running `verifyMessageSender` (`ts-sdks/packages/sui-stack-messaging/src/verification.ts`). Changing the canonical-message format means all canonical-SDK clients in the same group stop being able to verify your relayer's clients. See `docs/sui-stack-messaging/Security.md`. |
| 144 | +- **The relayer never sees plaintext.** If you fork it, preserve this invariant — don't add endpoints that take or return plaintext message content. |
| 145 | +- **Don't commit secrets.** `.env` files are ignored; `.env.example` is the only checked-in form. Never commit a `TEST_WALLET_PRIVATE_KEY`, `ADMIN_SECRET_KEY`, or sponsor-key value. |
| 146 | +- **Don't disable signing or hooks** (`--no-verify`, `--no-gpg-sign`, etc.) when committing. If a hook fails, fix the underlying issue. |
| 147 | +- **Don't bump dependency versions to bypass `minimumReleaseAge: 2880`** in `ts-sdks/pnpm-workspace.yaml` (designed to reduce supply-chain attack surface). Mysten packages are excluded. |
| 148 | + |
| 149 | +## Testing strategy (cross-cutting) |
| 150 | + |
| 151 | +- **Unit tests** are network-free and should pass on every change. |
| 152 | +- **Integration tests** (`ts-sdks/packages/sui-stack-messaging/test/integration/localnet/`) run against a localnet docker stack via testcontainers. They double as living usage examples. |
| 153 | +- **E2E tests** (`test/e2e/`) build the relayer + indexer Docker images via testcontainers and run against real Sui testnet. Require `TEST_WALLET_PRIVATE_KEY`. |
| 154 | +- **Move tests** live next to sources (`move/packages/*/tests/`). Use `sui move test --path` per package. |
| 155 | +- When fixing a bug, add a failing test first and verify the fix flips it. |
| 156 | + |
| 157 | +See `docs/sui-stack-messaging/Testing.md` for the full strategy. |
| 158 | + |
| 159 | +## Commit and PR conventions |
| 160 | + |
| 161 | +- **Conventional Commits** style (`feat:`, `fix:`, `docs:`, `chore:`, `refactor:` …) |
| 162 | +- **Changesets** govern SDK version bumps. If your change affects the public API of any TS package under `ts-sdks/packages/`, run `pnpm changeset` and commit the generated `.changeset/*.md` along with your code change. See `ts-sdks/RELEASING.md`. |
| 163 | +- **One logical change per PR.** Don't bundle a refactor with a feature. |
| 164 | +- **Don't push to `main` directly.** Open a PR. Don't force-push to shared branches. |
| 165 | +- **Don't amend or rewrite commits** that have already been pushed and reviewed unless explicitly asked. |
| 166 | + |
| 167 | +## Working pattern recommendations |
| 168 | + |
| 169 | +- For multi-step tasks, prefer parallel exploration / read-only investigation before editing. The repo is large; the `docs/sui-stack-messaging/` index and the per-subproject `AGENTS.md` get you oriented fastest. |
| 170 | +- Verify any command in subproject `AGENTS.md` against `package.json` / `Cargo.toml` / `Move.toml` before reporting "done" — those are the source of truth. |
| 171 | +- For Move language fundamentals, defer to general Sui Move documentation; this file only covers what's specific to this repo. |
0 commit comments