Skip to content
Open
Show file tree
Hide file tree
Changes from 72 commits
Commits
Show all changes
74 commits
Select commit Hold shift + click to select a range
e4ceee1
feat(hardware): Phase 5 slice 01 hardware foundation
adriannoes May 23, 2026
339bd6a
Merge pull request #11 from adriannoes/feat/phase5-hardware-foundation
adriannoes May 23, 2026
a280432
fix(gateway): add lws_compat shim for macOS libwebsockets builds
adriannoes May 24, 2026
df7910d
feat(hardware): add 40-pin GPIO snapshot for Web UI
adriannoes May 24, 2026
7c7b579
feat(hardware): add tegrastats parser and Jetson GPU metrics
adriannoes May 24, 2026
b6a1cb6
feat(gateway): add /api/hardware REST routes
adriannoes May 24, 2026
faa7379
feat(web): add /hardware status page with conditional GPU panel
adriannoes May 24, 2026
76b292c
build: wire Makefile targets for hardware Web UI slice
adriannoes May 24, 2026
7d57f15
fix(hardware): read-only batched GPIO snapshot for Web UI
adriannoes May 24, 2026
8a2c337
fix(hardware): validate tegrastats subprocess exit and GPU JSON fill
adriannoes May 24, 2026
99703e7
feat(web): on-demand I2C scan and preserve hardware tab on refresh
adriannoes May 24, 2026
83069ca
test(gateway): assert HTTP 405 on invalid hardware API methods
adriannoes May 24, 2026
674b65e
Merge pull request #12 from adriannoes/phase5/02-hardware-web-ui
adriannoes May 24, 2026
a31a4ab
feat(crypto): add TweetNaCl, JCS, and Ed25519 sign/verify
adriannoes May 25, 2026
e2f47dc
feat(asap): signed manifest, Ed25519 keys, and board-aware capabilities
adriannoes May 25, 2026
d6ab388
feat(inference): add model download and board-specific llama-server i…
adriannoes May 25, 2026
b32cabd
docs(ci): add ASAP marketplace guides and manifest publish workflow
adriannoes May 25, 2026
23a3f0c
Merge pull request #14 from adriannoes/phase5/slice03-inference-trust
adriannoes May 25, 2026
1a1fa09
feat(release): phase 5 slice 04 security, docs, and gateway hardening
adriannoes Jun 1, 2026
b611496
Merge pull request #19 from adriannoes/phase5/slice04-release-quality
adriannoes Jun 1, 2026
3522ce6
docs(release): add Jetson sign-off and v1.0.0 IssueOps templates
adriannoes Jun 2, 2026
efd9fcf
test(tools): extend get_context dashboard and year-span coverage
adriannoes Jun 11, 2026
ea51fe2
test: harden get_context, gateway auth, and router fallback coverage
adriannoes Jun 11, 2026
3b18501
test(tools): assert get_context rejects undersized result buffer
adriannoes Jun 11, 2026
9b29e1c
Merge branch 'integrate/cursor-pr17'
adriannoes Jun 11, 2026
0caa5a2
test: stub-b 401 error hook and dashboard line asserts
adriannoes Jun 11, 2026
25b6327
test(core): cover dispatch and get_context edge cases
adriannoes Jun 5, 2026
7ed8493
test(gateway): cover authenticated PUT /api/config paths
adriannoes Jun 11, 2026
8788948
test: integrate PR #24 router and holiday HTTP failure cases
adriannoes Jun 11, 2026
ab8f879
test: integrate PR #24 router and holiday HTTP failure cases
adriannoes Jun 11, 2026
7252ea0
merge(integrate): integrate/cursor-pr25 into development
adriannoes Jun 11, 2026
616be54
test(core): add SIGHUP reload unit tests with link stubs
adriannoes Jun 11, 2026
1e1f69d
fix(test): stub http_set_live_config for test_reload sanitizer link
adriannoes Jun 11, 2026
ca18003
test(context): cover ip-api success JSON missing lat
adriannoes Jun 13, 2026
deab2de
test(hardware): on-device harness and release docs
adriannoes Jun 13, 2026
1121b0d
test: cover get_context guards, router all-fail, crypto and auth edges
adriannoes Jun 13, 2026
7c0f3f6
test(web): cover dashboard WebSocket status merge logic
adriannoes Jun 15, 2026
ef94ee9
fix(asap,crypto): close v1.0.0 release blockers and orphan-leak class
adriannoes Jun 25, 2026
89eeff2
fix(hardware,gateway,crypto): medium fixes M0/M3/M4/CAM/M0b
adriannoes Jun 25, 2026
90d323e
build(ci,sanitizer): harden test-sanitize, suppress vendored UB, GCC …
adriannoes Jun 25, 2026
fff78d9
docs(agents): record config.c 1k waiver and g_hw_cfg setter-global debt
adriannoes Jun 25, 2026
47b431b
Merge pull request #43 from adriannoes/phase5/slice05-pre-merge-fixes
adriannoes Jun 25, 2026
ea5f89c
test(gateway): cover malformed Authorization header on /api/config
adriannoes Jul 1, 2026
00aed4f
test(web): cover dashboard failover semantics in dashboardView
adriannoes Jul 1, 2026
ad13f1e
test(router): verify live config swap updates fallback chain
adriannoes Jul 1, 2026
2bcdb34
Merge pull request #45 from adriannoes/pr42/gateway-malformed-bearer
adriannoes Jul 1, 2026
4d3f085
Merge pull request #46 from adriannoes/pr40/dashboard-failover-js
adriannoes Jul 1, 2026
a020037
Merge pull request #47 from adriannoes/pr39/router-live-config-reload
adriannoes Jul 1, 2026
f8c1225
test(auth): cover token cap eviction and malformed pairing codes
adriannoes Jul 9, 2026
ce3211c
test(auth): cover lockout table full slot-0 eviction
adriannoes Jul 10, 2026
840d4ef
test(auth,gateway): cover pending-less pair and window slide guard
adriannoes Jul 13, 2026
1f89099
Merge pull request #48 from adriannoes/cursor/test-coverage-automatio…
adriannoes Jul 16, 2026
f4ea2e8
Merge pull request #49 from adriannoes/cursor/test-coverage-automatio…
adriannoes Jul 16, 2026
bc5596f
Merge pull request #50 from adriannoes/cursor/test-coverage-automatio…
adriannoes Jul 16, 2026
a8748c2
chore: retarget GitHub URLs to asap-protocol org
adriannoes Jul 19, 2026
f70d83a
chore: add CODEOWNERS for @adriannoes
adriannoes Jul 19, 2026
3085627
merge(main): backmerge main into development
adriannoes Sep 11, 2026
e76f020
docs: defer Jetson on-device sign-off as known pending
adriannoes Sep 11, 2026
bbccf98
fix(core): raise tool table cap for hardware tools
adriannoes Sep 11, 2026
1d47cf4
fix(hardware): copy gpio_mode string before JSON free
adriannoes Sep 11, 2026
dc81386
fix(hardware): hold libgpiod line requests after write
adriannoes Sep 11, 2026
ec3d60e
fix(hardware): constrain camera_capture path to workspace
adriannoes Sep 11, 2026
ba08b96
fix(hardware): enforce I2C address and transfer length
adriannoes Sep 11, 2026
af96cbe
fix(crypto): abort when /dev/urandom fails
adriannoes Sep 11, 2026
ab3fc7e
fix(asap): reject symlink on key file write
adriannoes Sep 11, 2026
8788eec
fix(core): advertise SHELLCLAW_RELEASE_VERSION in CLI and status
adriannoes Sep 11, 2026
772a534
docs: align camera rate-limit changelog with SECURITY.md
adriannoes Sep 11, 2026
66c4ff1
ci: publish only manifest.json to GitHub Pages
adriannoes Sep 11, 2026
cbff9a1
docs: require Hugging Face SHA256 env for model downloads
adriannoes Sep 11, 2026
40ebd32
fix(hardware): mark RPi pin 26 as SPI CE1 SFIO
adriannoes Sep 11, 2026
1848a24
fix(systemd): harden llama-server unit and quote env args
adriannoes Sep 11, 2026
5cca5d3
build: remove leftover hardware and test stub objects on clean
adriannoes Sep 11, 2026
adbd81f
fix(ci): expose realpath and shrink camera path_item scope
adriannoes Sep 11, 2026
6f52c82
fix(hardware): honor fgets result in llama-server probe
adriannoes Sep 11, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 46 additions & 5 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,20 +1,61 @@
# ShellClaw Environment Variables
# Copy to .env and fill in your values
# NEVER commit the .env file
#
# See config.example.toml for TOML equivalents. Env vars override TOML where supported.

# LLM Providers (at least one required)
# --- LLM Providers (at least one required for cloud path) ---
ANTHROPIC_API_KEY=sk-ant-your-key-here
# OPENAI_API_KEY=sk-your-key-here
# OPENROUTER_API_KEY=sk-or-your-key-here

# Channels
# Default provider and fallback (comma-separated provider names)
# SHELLCLAW_DEFAULT_PROVIDER=anthropic
# SHELLCLAW_FALLBACK_CHAIN=anthropic,local

# Local inference (llama-server; Jetson CUDA / RPi CPU)
# Must match [providers.local] in config.toml and systemd llama-server.env PORT
# SHELLCLAW_LOCAL_ENDPOINT=http://127.0.0.1:8080/v1/chat/completions
# Jetson default model id (GGUF filename stem from scripts/download_model.sh phi3):
# SHELLCLAW_LOCAL_MODEL=Phi-3-mini-4k-instruct-Q4_K_M
# RPi / dev CPU default:
# SHELLCLAW_LOCAL_MODEL=tinyllama-1.1b-q4

# --- Channels ---
TELEGRAM_BOT_TOKEN=123456:ABC-your-token-here
# DISCORD_BOT_TOKEN=your-discord-token-here

# Web Search (optional, DuckDuckGo works without keys)
# --- Gateway (optional overrides) ---
# SHELLCLAW_GATEWAY_ENABLED=1
# SHELLCLAW_GATEWAY_HOST=127.0.0.1
# SHELLCLAW_GATEWAY_PORT=18789
# SHELLCLAW_GATEWAY_ALLOW_BIND_ALL=0

# --- Web Search (optional; DuckDuckGo works without keys) ---
# TAVILY_API_KEY=tvly-your-key-here
# BRAVE_SEARCH_API_KEY=BSA-your-key-here

# ASAP Protocol (optional)
# SHELLCLAW_ASAP_REGISTRY_URL=https://registry.asap.agent/registry.json
# --- ASAP Protocol (optional) ---
# SHELLCLAW_ASAP_PUBLIC_BASE_URL=https://your-host.example.com
# SHELLCLAW_ASAP_DESCRIPTION=Override manifest description
# SHELLCLAW_ASAP_REGISTRY_URL=https://raw.githubusercontent.com/asap-protocol/asap-protocol/main/registry.json
# SHELLCLAW_ASAP_REVOCATION_LIST_URL=https://registry.asap.agent/revoked_agents.json

# --- Hardware — Jetson Orin Nano Super defaults (Phase 5) ---
# Override auto-detect on dev machines or CI: jetson | rpi | stub
# SHELLCLAW_BOARD=jetson
# Manifest overrides (else board-specific defaults at manifest build time):
# SHELLCLAW_HARDWARE_CLASS=edge_accelerator
# SHELLCLAW_HARDWARE_MODEL=jetson_orin_nano_super_8gb
# I2C bus 7 on Jetson 40-pin header; bus 1 on RPi Zero 2 W
# SHELLCLAW_I2C_BUS=7
# Camera backend for future capture path (v1.2): csi | usb | auto
# SHELLCLAW_CAMERA_TYPE=auto

# --- Agent geo (optional, for context tool) ---
# SHELLCLAW_AGENT_LATITUDE=-23.5505
# SHELLCLAW_AGENT_LONGITUDE=-46.6333
# SHELLCLAW_AGENT_COUNTRY_CODE=BR

# --- On-device hardware tests (Jetson only; not for CI) ---
# SHELLCLAW_HW_TEST=1
29 changes: 18 additions & 11 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
# CI: static analysis, tests, release build. Required for branch protection.
# PRs may target `main` or `development`. Jetson on-device sign-off is not a CI gate.
name: CI
on:
push:
branches: [main]
branches: [main, development]
pull_request:
branches: [main]
branches: [main, development]

jobs:
ci:
name: static, test, release
runs-on: ubuntu-latest
# libgpiod v2 API (gpiod_chip_request_lines, etc.) needs Ubuntu 24.04+ apt packages
runs-on: ubuntu-24.04
env:
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
steps:
Expand All @@ -18,23 +20,28 @@ jobs:
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install -y build-essential libcurl4-openssl-dev libwebsockets-dev cppcheck lcov nodejs
sudo apt-get install -y build-essential libcurl4-openssl-dev libwebsockets-dev libgpiod-dev i2c-tools cppcheck lcov nodejs

- name: Static analysis (cppcheck)
run: make static

- name: Build and test
- name: Build and test (libgpiod present)
run: make clean && make test
env:
CI: true
GATEWAY: "1"

- name: Build and test without libgpiod (stub GPIO fallback)
run: make clean && LIBGPIOD=0 make test
env:
CI: true
GATEWAY: "1"

- name: AddressSanitizer + UBSan
run: |
make clean
CFLAGS="-std=c11 -Wall -Wextra -Werror -g -O0 -fsanitize=address,undefined -fno-omit-frame-pointer" \
LDFLAGS="-fsanitize=address,undefined" \
GATEWAY=1 make test
run: make test-sanitize
env:
CI: true
GATEWAY: "1"

- name: Release build
run: make clean && make release
Expand All @@ -48,7 +55,7 @@ jobs:
fi
echo "Binary size: $size bytes (OK)"

- name: Coverage (core modules >= 80%)
- name: Coverage (agent core >= 80%, hardware excluded)
run: GATEWAY=1 make coverage

- name: ASAP compliance check
Expand Down
165 changes: 165 additions & 0 deletions .github/workflows/publish-manifest.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
# Publish SignedManifest to GitHub Pages on release tags (Phase 5 task 6.1).
# Target URL: https://<owner>.github.io/<repo>/manifest.json
name: Publish manifest

on:
push:
tags:
- "v*"
pull_request:
branches: [development, main]
paths:
- ".github/workflows/publish-manifest.yml"
- "scripts/dump_manifest.sh"
- "src/asap/**"
- "src/crypto/jcs.c"
- "src/crypto/crypto.c"
- "src/crypto/crypto.h"
- "src/crypto/jcs.h"
workflow_dispatch:

permissions:
contents: read
pages: write
id-token: write

concurrency:
group: "pages-${{ github.workflow }}-${{ github.ref }}"
cancel-in-progress: false

jobs:
validate-manifest:
if: github.event_name == 'pull_request' || github.event_name == 'workflow_dispatch'
runs-on: ubuntu-24.04
env:
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
SHELLCLAW_ASAP_PUBLIC_BASE_URL: https://${{ github.repository_owner }}.github.io/${{ github.event.repository.name }}
steps:
- uses: actions/checkout@v4

- name: Set up Python 3.13
uses: actions/setup-python@v5
with:
python-version: '3.13'

- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install -y build-essential libcurl4-openssl-dev libwebsockets-dev libgpiod-dev

- name: Build shellclaw (gateway)
run: make clean && GATEWAY=1 make shellclaw
env:
CI: true

- name: Dump and validate SignedManifest
run: |
chmod +x scripts/dump_manifest.sh
./scripts/dump_manifest.sh -o /tmp/manifest.json
test -s /tmp/manifest.json
python3 -c "import json; json.load(open('/tmp/manifest.json'))"
pip3 install --quiet 'asap-protocol==2.5.0'
# Validate the inner manifest against the upstream Pydantic model and the
# full SignedManifest against the upstream signature verifier. Both must
# hard-fail (non-zero exit) on rejection -- the `|| echo`/`if ...; then`
# patterns previously masked validation failures and left the job green.
python3 <<'PY'
import json
import sys
from asap.models.entities import Manifest
from asap.crypto.signing import verify_manifest
from asap.crypto.models import SignedManifest
with open("/tmp/manifest.json") as f:
data = json.load(f)
Manifest.model_validate(data["manifest"])
print("inner manifest: Pydantic OK")
sm = SignedManifest.model_validate(data)
ok = verify_manifest(sm)
print("upstream verify_manifest:", ok)
sys.exit(0 if ok else 1)
PY

publish-manifest:
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')
runs-on: ubuntu-24.04
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
env:
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
SHELLCLAW_ASAP_PUBLIC_BASE_URL: https://${{ github.repository_owner }}.github.io/${{ github.event.repository.name }}
steps:
- uses: actions/checkout@v4

- name: Set up Python 3.13
uses: actions/setup-python@v5
with:
python-version: '3.13'

- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install -y build-essential libcurl4-openssl-dev libwebsockets-dev libgpiod-dev

- name: Build shellclaw (gateway)
run: make clean && GATEWAY=1 make shellclaw
env:
CI: true

- name: Restore publisher signing key
env:
MANIFEST_PRIV_B64: ${{ secrets.SHELLCLAW_MANIFEST_ED25519_PRIV }}
MANIFEST_PUB_B64: ${{ secrets.SHELLCLAW_MANIFEST_ED25519_PUB }}
run: |
if [ -z "${MANIFEST_PRIV_B64}" ] || [ -z "${MANIFEST_PUB_B64}" ]; then
echo "Tag publish requires secrets SHELLCLAW_MANIFEST_ED25519_PRIV and SHELLCLAW_MANIFEST_ED25519_PUB (base64 of ed25519.priv / ed25519.pub). Do not mint a fresh key per tag."
exit 1
fi
export SHELLCLAW_HOME="${RUNNER_TEMP}/shellclaw-home"
mkdir -p "${SHELLCLAW_HOME}/keys"
echo "${MANIFEST_PRIV_B64}" | base64 -d > "${SHELLCLAW_HOME}/keys/ed25519.priv"
echo "${MANIFEST_PUB_B64}" | base64 -d > "${SHELLCLAW_HOME}/keys/ed25519.pub"
chmod 0600 "${SHELLCLAW_HOME}/keys/ed25519.priv" "${SHELLCLAW_HOME}/keys/ed25519.pub"
echo "SHELLCLAW_HOME=${SHELLCLAW_HOME}" >> "${GITHUB_ENV}"

- name: Dump live SignedManifest
run: |
chmod +x scripts/dump_manifest.sh
mkdir -p pages-dist
./scripts/dump_manifest.sh -o pages-dist/manifest.json
test -s pages-dist/manifest.json
: > pages-dist/.nojekyll

- name: Validate manifest JSON (optional)
run: |
python3 -c "import json; json.load(open('pages-dist/manifest.json'))"
pip3 install --quiet 'asap-protocol==2.5.0'
# Validate the inner manifest + upstream signature; hard-fail on rejection
# (the prior `|| echo` / `if ...; then` patterns masked failures).
python3 <<'PY'
import json
import sys
from asap.models.entities import Manifest
from asap.crypto.signing import verify_manifest
from asap.crypto.models import SignedManifest
with open("pages-dist/manifest.json") as f:
data = json.load(f)
Manifest.model_validate(data["manifest"])
print("inner manifest: Pydantic OK")
sm = SignedManifest.model_validate(data)
ok = verify_manifest(sm)
print("upstream verify_manifest:", ok)
sys.exit(0 if ok else 1)
PY

- name: Setup Pages
uses: actions/configure-pages@v4

- name: Upload Pages artifact
uses: actions/upload-pages-artifact@v3
with:
path: pages-dist

- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
65 changes: 65 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# Agent quickstart

ShellClaw is a C99 AI agent for edge hardware (Jetson / Raspberry Pi). Read this before editing code.

## Commands

| Action | Command |
|--------|---------|
| Build | `make shellclaw` → `build/shellclaw` |
| Run all tests | `make test` |
| Static analysis | `make static` (requires cppcheck) |
| ASan + UBSan tests | `make test-sanitize` (requires Clang/GCC sanitizer support) |
| Coverage (core ≥ 80%) | `make coverage` (requires lcov) |
| Full CI locally | `chmod +x scripts/ci-local.sh && ./scripts/ci-local.sh` (Ubuntu 24.04+; on Mac use `CI=true make test`) |
| Jetson on-device HW | `SHELLCLAW_HW_TEST=1 make test_hardware_on_device` (also runs when `SHELLCLAW_HW_TEST=1 make test`) |
| Pre-PR check | `CI=true make clean && CI=true make test` |

Gateway tests need libwebsockets: `GATEWAY=1 make test_gateway_http`.

## Layout

```
src/
core/ agent loop, config, memory, skills
providers/ LLM providers (Anthropic, OpenAI, local)
tools/ shell, file, web_search, asap_invoke, cron, context
channels/ CLI, Telegram, Discord, WebChat
gateway/ HTTP server, WebSocket, embedded Web UI
asap/ ASAP Protocol client/server, registry, manifest
sandbox/ Linux namespaces + cgroups v2
hardware/ GPIO/I2C/camera abstraction (per-board backends)
crypto/ Ed25519 signing
tests/ one test binary per module (Makefile targets)
```

## Conventions

- Language: C99/C11, English comments, Doxygen on public APIs.
- Types: explicit on every variable, parameter, and return value.
- Config/secrets: environment variables and `.env.example` — never commit credentials.
- Tests must run headless with no manual setup or secrets.
- Bug fix: write a failing regression test first, then fix.

## Known debt

- **`tool_X_set_config` setter-global convention (v1.0.1):** the tools (shell, file, web_search, asap_invoke, context, hardware) each expose a module-local mutable config pointer set via a `tool_X_set_config(const config_t *)` setter (e.g. `g_hw_cfg` in `src/tools/hardware_tools_helpers.c`). This avoids passing `const config_t *cfg` through `tool_t.execute` / `agent_tool_t.execute` (an ABI change touching `tool.h`/`agent.h` vtables, 13 tool callbacks, ~30 test sites, >10 files). The whole-convention refactor (pass `const config_t *cfg` or a `tool_context_t` through `execute` for all tools) is scheduled for v1.0.1. Recorded in Phase 5 slice 05 (H1 path B).
- **`src/core/config.c` 1000-line waiver (v1.0.1):** `config.c` is 1261 lines (a single-struct TOML parser where every `parse_*` writes the same `config_t`). The 1000-line rule is a presumptive (rebuttable) blocker. A clean hardware-only extract (~167 lines: `parse_hardware`, `free_hardware_io`, `config_hardware_*` accessors) leaves the file at ~1094 — still over 1k. The proper fix is a two-section extract (`config_hardware.c` + `config_asap.c`, ~331 lines → ~930), scheduled for v1.0.1. The `asap_skill_descriptions` table is ASAP-section code, NOT hardware, and must not move with a hardware extraction. Waived for v1.0.0 per Phase 5 slice 05 (B1).
- **Jetson on-device sign-off (deferred):** Phase 5 software is on `main`. GPIO/I2C/`llama-server` smoke on a physical Jetson Orin Nano Super is **not** a merge gate. Run `SHELLCLAW_HW_TEST=1 make test_hardware_on_device` and [`docs/JETSON_SIGNOFF.md`](docs/JETSON_SIGNOFF.md) when hardware is available.

## Branches

- `main` — active line; open PRs here (or via `development` when integrating a large slice).
- `development` — optional integration branch; no longer a hold-back until Jetson sign-off.
- Phase 5 on-device Jetson validation is a known pending item, not a `development` → `main` blocker. See [`docs/JETSON_SIGNOFF.md`](docs/JETSON_SIGNOFF.md).

## Rules

Project rules live in `.cursor/rules/`:

- `c-principles.mdc` — C coding standards
- `agent-clean-code-c.mdc` — agent-oriented clean code for C
- `shellclaw-architecture.mdc` — product architecture
- `testing.mdc` — test workflow and CI
- `git-commits.mdc` — Conventional Commits
- `karpathy-guidelines.mdc` — behavioral guidelines for agents
Loading
Loading