diff --git a/software/firmware/calypso/workspaces/calypso-dev/.claude/settings.json b/software/firmware/calypso/workspaces/calypso-dev/.claude/settings.json new file mode 100644 index 0000000..61c35f2 --- /dev/null +++ b/software/firmware/calypso/workspaces/calypso-dev/.claude/settings.json @@ -0,0 +1,29 @@ +{ + "attribution": { + "sessionUrl": false + }, + "hooks": { + "SessionStart": [ + { + "hooks": [ + { + "type": "command", + "command": "bash \"$CLAUDE_PROJECT_DIR/.delphi/paths.sh\" >> \"$CLAUDE_ENV_FILE\"" + } + ] + } + ] + }, + "extraKnownMarketplaces": { + "delphi": { + "source": { + "source": "github", + "repo": "Northeastern-Electric-Racing/Delphi" + }, + "autoUpdate": true + } + }, + "enabledPlugins": { + "delphi@delphi": true + } +} diff --git a/software/firmware/calypso/workspaces/calypso-dev/.claude/skills/ci-local/SKILL.md b/software/firmware/calypso/workspaces/calypso-dev/.claude/skills/ci-local/SKILL.md new file mode 100644 index 0000000..58ea84c --- /dev/null +++ b/software/firmware/calypso/workspaces/calypso-dev/.claude/skills/ci-local/SKILL.md @@ -0,0 +1,8 @@ +--- +name: ci-local +description: Run Calypso's CI checks (build, test, fmt, clippy) locally. Use before pushing or when CI fails. +--- + +`bash scripts/ci.sh ` runs `rust-ci.yml`'s checks in `worktrees/calypso/`: natively on Linux, in Docker on macOS (~2 min; run it in the background). On macOS, `cargo test -p calypso-sim` also works natively for a fast loop. + +Report the failing step's output. Fix clippy findings in code, not with `#[allow]`. diff --git a/software/firmware/calypso/workspaces/calypso-dev/.claude/skills/ci-local/scripts/ci.sh b/software/firmware/calypso/workspaces/calypso-dev/.claude/skills/ci-local/scripts/ci.sh new file mode 100755 index 0000000..d29d18a --- /dev/null +++ b/software/firmware/calypso/workspaces/calypso-dev/.claude/skills/ci-local/scripts/ci.sh @@ -0,0 +1,19 @@ +#!/usr/bin/env bash +# ci.sh : run rust-ci.yml's checks (build, test, fmt, clippy; all --all) in +# worktrees/calypso/, stopping at the first failure. Natively on Linux; on macOS in a +# rust:latest container (the main crate needs socketcan), building into the git-ignored target/linux. +set -euo pipefail +branch=${1:?usage: ci.sh } +# shellcheck source=/dev/null +. "${DELPHI_ROOT:?unset: start the session at the workspace root, on Delphi 0.2.0+ (pull its ws/ branch), or source /.delphi/paths.sh}/.delphi/paths.sh" +w=$DELPHI_WORKTREES/calypso/$branch +[ -d "$w" ] || { echo "no worktree at $w; make it with new-worktree" >&2; exit 2; } +[ -n "$(ls -A "$w/Odyssey-Definitions" 2>/dev/null)" ] || { echo "run: git -C $w submodule update --init --recursive" >&2; exit 2; } +# shellcheck disable=SC2016 +steps='set -e; for s in "build --all" "test --all" "fmt --all --check" "clippy --all -- -D warnings"; do echo "== cargo $s"; cargo $s; done' +if [ "$(uname -s)" = Linux ]; then + (cd "$w" && bash -c "$steps") +else + docker run --rm -v "$w":/w -w /w -e CARGO_TARGET_DIR=/w/target/linux rust:latest \ + bash -c "rustup component add clippy rustfmt >/dev/null 2>&1; $steps" +fi diff --git a/software/firmware/calypso/workspaces/calypso-dev/.claude/skills/sim-drive/SKILL.md b/software/firmware/calypso/workspaces/calypso-dev/.claude/skills/sim-drive/SKILL.md new file mode 100644 index 0000000..0c8e622 --- /dev/null +++ b/software/firmware/calypso/workspaces/calypso-dev/.claude/skills/sim-drive/SKILL.md @@ -0,0 +1,13 @@ +--- +name: sim-drive +description: Run calypso-sim against a private Siren and check what arrives on the wire. Use to test a sim change or feed a consumer. +--- + +Modes and flags are in `worktrees/calypso//calypso-sim/README.md`. The sim defaults to MQTT on `localhost:1883`, which may be someone's running Argos stack (`:1883` MQTT, `:7447` Zenoh): ask before publishing there. + +1. Start your own broker in the background: `mosquitto -p 18833`. +2. Run: `(cd worktrees/calypso/ && cargo run -q -p calypso-sim -- -u localhost:18833 )`. +3. Check: `mosquitto_sub -p 18833 -t '' -F '%U %t'`; expect about `1000 / sim_freq` messages a second. +4. Stop what you started. + +For Zenoh, pass `--zenoh --zenoh-conf FILE` with multicast scouting off and a private router endpoint, or it joins whatever router is running. diff --git a/software/firmware/calypso/workspaces/calypso-dev/.claude/skills/trace-signal/SKILL.md b/software/firmware/calypso/workspaces/calypso-dev/.claude/skills/trace-signal/SKILL.md new file mode 100644 index 0000000..2e1e2d8 --- /dev/null +++ b/software/firmware/calypso/workspaces/calypso-dev/.claude/skills/trace-signal/SKILL.md @@ -0,0 +1,14 @@ +--- +name: trace-signal +description: Trace a CAN message or topic through Calypso and explain why it is or isn't published, simulated, or sent to the car. Use for "where does topic X come from", "why don't I see X", or "can this reach the car". +--- + +In `worktrees/calypso//`, cite `file:line` for each link: + +1. **Spec:** `grep -rn '' Odyssey-Definitions/can-messages/`. Topic names can be templates (`BMS/PerCell/Alpha/{4}/Volts/{5}`), so grep an id or a prefix. +2. **Codegen:** `build.rs` → `libs/calypso-cangen/`. +3. **Decode:** `src/main.rs` (`DECODE_FUNCTION_MAP`) → `mqtt_handler.rs` or `zenoh_handler.rs`. +4. **Encode:** only `Calypso/Bidir/Command/…` with a `CommandData` payload, and only with `-e`. +5. **Sim:** only messages with `sim_freq` (a period in ms); `calypso-sim --list-topics` shows which. + +Report the chain and any break in it. diff --git a/software/firmware/calypso/workspaces/calypso-dev/.gitattributes b/software/firmware/calypso/workspaces/calypso-dev/.gitattributes new file mode 100644 index 0000000..4965641 --- /dev/null +++ b/software/firmware/calypso/workspaces/calypso-dev/.gitattributes @@ -0,0 +1,2 @@ +# LF everywhere, so .delphi/setup.sh runs in Git Bash even with core.autocrlf=true +* text=auto eol=lf diff --git a/software/firmware/calypso/workspaces/calypso-dev/.github/workflows/delphi.yml b/software/firmware/calypso/workspaces/calypso-dev/.github/workflows/delphi.yml new file mode 100644 index 0000000..b8ffdd9 --- /dev/null +++ b/software/firmware/calypso/workspaces/calypso-dev/.github/workflows/delphi.yml @@ -0,0 +1,41 @@ +# Delphi CI (docs/design.md). This file is at main's root and, identically, at the root of every +# ws/ (GitHub runs a push's workflow from the pushed commit, so ws pushes need their own copy). +# PRs to main: ci/check.sh, against main (so released versions stay as they are). Pushes to main or +# ws/**: ci/sync.sh (refresh + propose), always run from main. Pushes and PRs made with GITHUB_TOKEN +# trigger no workflows: no loops, and CI-opened PRs don't run `check` (sync.sh runs it itself). +name: delphi +on: + pull_request: + branches: [main] + push: + branches: [main, 'ws/**'] +permissions: + contents: read +jobs: + check: + if: github.event_name == 'pull_request' + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + persist-credentials: false + - run: ci/check.sh . origin/main + sync: + if: github.event_name == 'push' + runs-on: ubuntu-latest + concurrency: delphi-sync + permissions: + contents: write + pull-requests: write + steps: + - uses: actions/checkout@v4 + with: + ref: main + fetch-depth: 0 + - env: + GH_TOKEN: ${{ github.token }} + run: | + git config --global user.name 'github-actions[bot]' + git config --global user.email '41898282+github-actions[bot]@users.noreply.github.com' + ci/sync.sh diff --git a/software/firmware/calypso/workspaces/calypso-dev/CLAUDE.md b/software/firmware/calypso/workspaces/calypso-dev/CLAUDE.md new file mode 100644 index 0000000..bbfe2c8 --- /dev/null +++ b/software/firmware/calypso/workspaces/calypso-dev/CLAUDE.md @@ -0,0 +1,12 @@ +# Delphi workspace + +You're in Delphi workspace `software/firmware/calypso/calypso-dev` (branch `ws/software/firmware/calypso/calypso-dev`); code repos are checked out as worktrees under `worktrees//` (`.delphi/setup.sh` makes the default branch's). Make new branches as worktrees (`new-worktree` skill) unless the user says not to. Read-only dependency sources from `references-git:` are checked out under `references//` at the version the workspace pins: read them to learn how a dependency behaves (prefer them over web docs), and never edit, branch, or push them. Delphi workspaces (or `main`) under `workspaces:` in `workspace.yml` (`- ws/`, a workspace's place in the tree, or `- main`) are read-only copies at `linked//` for reading their context; change what's checked out with the `setup-workspace` skill. To work in another workspace, switch this clone to it (`switch-workspace` skill). Park rough notes with the `journal` skill. Work here unless the task clearly belongs to another project. + +# Calypso + +CAN ↔ telemetry bridge for NER's Odyssey car (Rust). Decodes CAN into protobuf `ServerData` published per topic to Siren (MQTT, or Zenoh with `-z`); encodes `CommandData` on `Calypso/Bidir/Command/#` back to CAN. The CAN spec is JSON in the `Odyssey-Definitions` submodule. `calypso-sim` publishes simulated `ServerData`; its `README.md` is the source of truth for its flags. + +- `worktrees/calypso/develop/` mirrors `develop`: run things there, never edit or commit. Make branches with `new-worktree` from `origin/develop`, then `git -C worktrees/calypso/ submodule update --init --recursive`. +- Branches `{issue}-{kebab-title}`; commits `#{issue} - {description}`; draft PRs into `develop`. +- Check with `ci-local` (bare `cargo test` skips workspace members; on macOS the main crate doesn't compile). +- On macOS, the old `Develop` branch (until it's deleted) can collide with `develop` in `repos/calypso`. If `worktrees/calypso/develop` isn't at GitHub's `develop`: `git -C repos/calypso config --add remote.origin.fetch '^refs/heads/Develop'`, `git -C repos/calypso update-ref -d refs/remotes/origin/develop`, `git -C repos/calypso fetch origin`, `git -C worktrees/calypso/develop reset --hard origin/develop`. diff --git a/software/firmware/calypso/workspaces/calypso-dev/workspace.yml b/software/firmware/calypso/workspaces/calypso-dev/workspace.yml new file mode 100644 index 0000000..ac4b871 --- /dev/null +++ b/software/firmware/calypso/workspaces/calypso-dev/workspace.yml @@ -0,0 +1,11 @@ +name: software/firmware/calypso/calypso-dev # its place in the tree, the folder path without workspaces/ (branch ws/); checkouts park and restore repos/ by it +harness: claude-code +plugins: # `- [.]`: plugin sets to enable; CI lists the `default` set of every folder above first and generates .claude/settings.json + - delphi # default, from software/ +opt-out: # `- `: files from the workspace-inherit/ folders above that CI leaves alone here, so the workspace keeps its own copy (or none) + # - .claude/skills/journal +# .delphi/setup.sh checks out everything below (git-ignored); re-run it after any change. +repos: # `: `: code you change; bare store at repos/, default branch at worktrees// + calypso: https://github.com/Northeastern-Electric-Racing/Calypso.git +workspaces: # `- ws/` or `- main`: Delphi workspaces to read, never edit; shallow copy at linked/ + - main