Skip to main content

Getting Started

By the end of this page you'll have Green Goods running on your machine: the public site and installed-app experience and the steward cockpit, with this docs site and Storybook beside them on the hosted path, and a clear check at each step so you know it worked.

The Green Goods home page, with the headline From good intentions to green outcomes and an Explore Gardens button over a photo of a garden at sunset
The client opens on the public website; the installed app has its own interface.

Green Goods is a Bun monorepo with seven packages spanning a React PWA, Solidity contracts, and an Envio indexer. You don't need to understand the whole system to run it. When you're curious, the Architecture page has the map.

Before you start​

  • Node.js 22.19 or later, on the 22 line (CI runs 22.22.1; setup refuses another major), and Git.
  • Bun 1.4.2, the version package.json declares. Setup installs the current Bun when none is found; mise installs the exact one.
  • Docker, only for the team path below. OrbStack and Docker Desktop both work.
  • On Windows, work inside WSL2.
  • Optional: if you use mise, mise install in the repo installs Node 22.22.1, Bun 1.4.2, and Foundry 1.7.1, the versions CI uses. They live in .mise.toml.

Choose your path​

  • Public contributor: the right start for almost everyone doing UI, docs, or design work, or taking a first look around. It needs no credentials and no Docker, and it talks to hosted services.
  • Team member: for contract, indexer, or agent work. It runs the agent and indexer locally and needs shared credentials from 1Password plus Docker.

Both paths talk to live Arbitrum One. Browsing is safe. A wallet or passkey transaction you confirm is a real production transaction, so don't confirm one while you're exploring.

Path A: run against hosted services​

  1. Clone and enter the repo:

    git clone https://github.com/greenpill-dev-guild/green-goods.git
    cd green-goods
  2. Run first-time setup. The isolated profile installs dependencies and writes a non-secret root .env when you don't have one yet:

    npm run setup -- --profile isolated

    This is the only time you'll type npm here. After setup, every command starts with bun run.

  3. Check readiness. The health check changes nothing; it names anything missing for the mode you pass, so fix exactly what it flags and rerun it:

    bun run dev:health -- prod
  4. Start the local surfaces against the hosted APIs:

    bun run dev -- prod
  5. Checkpoint: open the surfaces. The launcher prints these same links when it starts, and this mode also opens a browser tab for you.

    SurfaceURL
    Client (public site + PWA)https://localhost:3001
    Admin (steward cockpit)https://localhost:3002
    Docs (this site)http://localhost:3003
    Storybookhttp://localhost:3004

    The client and admin run over HTTPS with a local certificate from mkcert. The first time, you may be asked for your password so your machine can trust that certificate.

    To see the installed-app experience without connecting a wallet, open https://localhost:3001/?mockAuth=steward&presentation=pwa. Mock auth signs you in as a test steward, in the PWA presentation. It works only on localhost, and it never signs a transaction. The same ?mockAuth=steward opens the admin at https://localhost:3002/?mockAuth=steward.

    The Admin package guide shows the Hub you should see for the mock steward.

  6. Confirm the services respond. The launcher runs this smoke check itself once the services are up; rerun it by hand whenever you want. It submits no transactions:

    bun run dev:smoke -- prod
  7. When you're done, press Ctrl-C in the terminal running the launcher. That stops only the services it started.

Path B: run the connected local stack​

The team stack runs the agent API and the Envio indexer on your machine, next to the client and admin, so you can change them and see the result end to end.

  1. Start OrbStack or Docker Desktop. The local indexer runs in containers.

  2. Run host setup. It checks your tools and installs any that are missing, but it doesn't fetch secrets:

    npm run setup -- --profile host
  3. Resolve shared credentials, then validate them. The test -f .env || guard runs the sync only when you have no .env yet, so it never replaces values you already have:

    test -f .env || bun run env:sync
    bun run env:check
  4. Check readiness, then start the default stack:

    bun run dev:health
    bun run dev

    The default mode, local, brings up the client and admin, the agent on port 3005, and the indexer: GraphQL on 3006, the indexer itself on 3007, and Postgres on 3008.

  5. Checkpoint: verify the stack in one command.

    bun run dev:smoke

    The smoke check confirms the services respond and the chain and indexer are ready. It submits no transactions. If the indexer is still replaying history, leave the launcher running and rerun the smoke check once it catches up.

  6. Press Ctrl-C in the launcher's terminal to shut the stack down.

Other modes​

Each mode takes the same name in all three commands, for example bun run dev -- full with bun run dev:health -- full and bun run dev:smoke -- full:

  • full adds this docs site and Storybook to the default stack, and opens a browser tab.
  • web starts only the browser surfaces (client, admin, docs, Storybook) against the live chain and local APIs that must already be running. Its readiness check is bun run dev:health -- --profile web; a profile stands in for the mode name, so pass one or the other, never both.
  • prod-mirror runs a local live-data indexer next to the hosted agent, for indexer work against production data.
  • fork swaps live Arbitrum for a local Anvil fork on port 3009, for contract work you want off the live chain. The local indexer still reads live Arbitrum: it syncs from Envio's hosted HyperSync source, which never sees a local fork, so indexed views won't show what you do on the fork. Restarting Anvil resets the fork, and passkeys don't work there.
  • Service names start a narrower set: bun run dev -- client admin starts just those two, without the agent or indexer behind them.

ONBOARDING.md lists every mode, what it starts, and which chain and data it uses. Stop the running launcher before you switch modes. For everything beyond starting the stack, the Command inventory lists every repository command, generated from the package manifests.

Bring an AI agent​

Green Goods is built with AI agents as a core practice, and the repository is set up so yours can onboard itself. Copy the procedure below into your agent (the copy button sits in the block's corner) and it will check your setup, pick the right path, and finish with a short report of what it verified and what is still missing. It is the repository's own ONBOARDING.md, embedded here from a generated copy so the two cannot drift.

ONBOARDING.md, ready to copy
ONBOARDING.md
# Onboarding to Green Goods

Use this procedure with a coding agent or follow it yourself. The [README](README.md)
explains the product; [AGENTS.md](AGENTS.md) owns repository rules. Run commands from
the repository root unless a command specifies `--cwd`.

## Before setup

1. Read `AGENTS.md`, inspect the current branch and working-tree changes, and preserve
work belonging to other sessions. Do not switch branches during shared-checkout work.
2. Check Node, Bun, Git, and existing dependencies. Use the versions in
[.mise.toml](.mise.toml); Node must be version 22. Use WSL2 on Windows.
3. Inspect existing services with `bun run dev -- status`. Reuse compatible services;
only the owning session may stop them. Missing dependencies may prevent status from running.
4. Choose the public-contributor path without shared credentials, or the team path
with 1Password access and Docker. Do not print environment values or credentials.

Setup may install dependencies and missing tools. Agents must honor the installation
permissions in `AGENTS.md`; if installation is not authorized, report that dependency
before proceeding. An existing root `.env` is preserved on setup reruns.

## Public contributor path

The isolated profile works on a local machine as well as in a worktree or container.
It avoids host-tool installation and writes non-secret defaults only when `.env` is absent.

```bash
npm run setup -- --profile isolated
bun run dev:health -- prod
bun run dev -- prod
```

When Bun is already available, `bun run setup -- --profile isolated` uses the same setup.
The hosted mode starts local client, admin, docs, and Storybook, using production APIs.
It needs neither team secrets nor a local indexer for public browsing. Missing credentials
for passkeys, wallets, or uploads remain capability limits, not proof of a broken public setup.

Open the printed client URL and browse public gardens. The admin sign-in/access gate is
expected without steward credentials. Do not claim privileged workflows are verified.
**Hosted mode permits real wallet-confirmed Arbitrum transactions; browsing verification
must not submit transactions.**

## Team path

Start OrbStack or Docker Desktop before launching local indexer services.

Existing `.env` files are kept. Review readiness before explicitly replacing local credentials.
**Confirmed transactions affect live Arbitrum.**

```bash
npm run setup -- --profile host
test -f .env || bun run env:sync
bun run env:check
bun run dev:health
bun run dev
```

Host setup reports how to configure the environment; it does not fetch shared secrets.
The sync resolves the 1Password references in `env.schema`, the one checked-in environment file,
and writes the root `.env`. The [environment guide](https://docs.greengoods.app/builders/getting-started#environment)
explains 1Password access and personal credentials. Never create package-level env files.

The default stack starts local client, admin, agent, and Docker indexer against **live
Arbitrum One**. Confirmed wallet and passkey transactions are production transactions.
`ENVIO_API_TOKEN` supports reliable indexer replay; service health alone does not prove
that replay has caught up. Uploads and messaging require their own service credentials.

## Development modes

Use `bun run dev -- <mode>`, with the same mode for health and smoke:

| Mode | Local services | Chain and data |
|---|---|---|
| `local` | admin, client, agent, indexer | Default; live Arbitrum and local APIs |
| `full` | docs, admin, client, agent, indexer, storybook, browser | Live Arbitrum and local APIs |
| `fork` | anvil-arbitrum, admin, client, agent, indexer | Local Arbitrum fork; indexer still reads live networks |
| `web` | docs, admin, client, storybook, browser | Live chain; local APIs must already be available |
| `prod` | docs, admin, client, storybook, browser | Live chain and hosted APIs |
| `prod-mirror` | docs, admin, client, indexer, storybook, browser | Live chain, hosted agent, local live-data indexer |

Service names select a narrower launch: `bun run dev -- client admin` does not start
its agent or indexer dependencies. Stop the owning launcher before changing modes.

For fork testing, use a dedicated browser profile and a disposable Anvil-funded wallet.
Local account details are in `packages/contracts/.generated/runtime/arbitrum-fork.json`.
Configure RPC `http://127.0.0.1:3009`, chain `42161`. The file redacts the upstream fork
endpoint. Restarting Anvil resets local chain state; the indexer does not ingest these
local writes. Passkeys are blocked in fork mode. Mock authentication does not sign transactions.

## Verify and hand off

Run `bun run dev:smoke -- <mode>` after startup. Automatic smoke checks reachability and,
for connected modes, chain/indexer readiness. It submits no transactions. If replay is
behind, leave the owning launcher running and rerun smoke after catch-up.

For local agent browser verification, follow `AGENTS.md § Browser Evidence`: label the engine and
session behind every rendered proof, and use the authenticated Brave extension path only for the
authenticated surface class. If it cannot be reached, record that proof as pending; never report
an isolated profile as authenticated proof or an HTTP check as rendered proof.

Keep the launcher in the foreground; Ctrl-C stops only its services. A detached stop uses
`GREEN_GOODS_DEV_OWNER=<same-owner> bun run dev -- stop`. Never stop an unknown listener.

Finish onboarding by reporting:

- The setup path, selected mode, and URLs that were actually verified.
- Missing credentials, services, or browser access and the workflows they block.
- The package that owns the contributor's first task and its nearest `AGENTS.md`.
- The next targeted check selected with `bun run check --plan -- --intent qa`.

Use [CONTRIBUTING.md](CONTRIBUTING.md) for the contribution process and
[the command reference](scripts/README.md) for specialist tooling. Agent-specific harness
notes belong in [CLAUDE.md](CLAUDE.md), not in this procedure.

The Bring an agent section of First Contribution places this in the wider contribution flow.

About the environment​

Green Goods uses one .env at the repository root. Packages never carry their own.

  • env.schema is the one checked-in environment file. It names every variable, marks the ones each profile requires, and holds the value a sync writes: a plain default, nothing, or a 1Password reference. It never holds a secret. bun run env:check validates your .env against it.
  • Team members resolve the references with bun run env:sync. It needs the 1Password CLI and access to the shared vault, and it writes the result to the root .env.
  • Some capabilities need their own credentials. ENVIO_API_TOKEN keeps indexer replay reliable on the team stack, uploads and messaging need their service keys, and passkeys and wallets bring their own. Personal credentials stay in your .env, never in env.schema.
  • Setup never overwrites your .env. A rerun keeps the file as it is; it doesn't merge in new keys or repair old ones. The sync is an explicit write to it: it keeps the previous file as .env.bak and replaces it, so check what it would change before you run it on an existing file.
  • Capabilities have their own checks. bun run dev:health -- --profile upload, for example, explains what uploads still need.
  • Secrets stay out of the repo. Never put a value in docs, logs, test fixtures, package-level files, or generated pages.

A green smoke check proves the services respond. It doesn't prove that wallets, passkeys, uploads, or transactions work; each of those needs its own credentials and its own test.

If something goes wrong​

  • A port is busy. Another session may own it. bun run dev -- status shows what's running and which launcher owns it. Reuse a compatible service, and never stop a listener you didn't start.
  • The health check flags something. Fix exactly what it names, then rerun it with the same mode.
  • Path B fails early. Make sure OrbStack or Docker Desktop is actually running; the local indexer needs it.
  • You need to stop or reset. Ctrl-C stops the services a launcher started. bun run dev -- stop stops a detached launcher (it needs the same owner identity the launcher started with), and bun run dev:clean clears stale local state; its --dry-run flag shows what it would remove.
  • Anything else. Ask us on Discord if the health output doesn't get you unstuck.

Next steps​