Compare commits
2 Commits
8a828e72c8
...
2f0f11e111
| Author | SHA1 | Date | |
|---|---|---|---|
| 2f0f11e111 | |||
| 8d6a108aa2 |
76
AGENTS.md
Normal file
76
AGENTS.md
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
# AGENTS.md
|
||||||
|
|
||||||
|
Guidance for AI/code agents working in this repository.
|
||||||
|
|
||||||
|
## Project Snapshot
|
||||||
|
|
||||||
|
- App: Gantt Board (`Next.js` + TypeScript)
|
||||||
|
- Backend: API routes in `src/app/api/*` with Supabase-backed persistence
|
||||||
|
- Clients:
|
||||||
|
- Web UI (React/Next)
|
||||||
|
- Shell CLI scripts in `scripts/`
|
||||||
|
|
||||||
|
## Core Architecture Rules
|
||||||
|
|
||||||
|
1. API/server code is the single source of truth for business logic.
|
||||||
|
2. CLI scripts are passthrough clients to API endpoints.
|
||||||
|
3. CLI scripts must not implement domain/business logic.
|
||||||
|
4. CLI scripts must not perform direct DB/Supabase REST access.
|
||||||
|
5. If CLI needs missing behavior, add it to API first, then call it from CLI.
|
||||||
|
|
||||||
|
Reference docs:
|
||||||
|
|
||||||
|
- `scripts/README.md`
|
||||||
|
- `CLI_STANDARD.md`
|
||||||
|
- `docs/API_CLI_PASSTHROUGH_PATTERN.md`
|
||||||
|
|
||||||
|
## Important Domain Note
|
||||||
|
|
||||||
|
Current sprint selection/date semantics are centralized in server logic:
|
||||||
|
|
||||||
|
- `src/lib/server/sprintSelection.ts`
|
||||||
|
|
||||||
|
Do not duplicate this logic in CLI or UI scripts.
|
||||||
|
|
||||||
|
## Testing Requirements
|
||||||
|
|
||||||
|
For API/CLI refactors and behavior changes, tests are required.
|
||||||
|
|
||||||
|
Minimum checks:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm run test:refactor
|
||||||
|
```
|
||||||
|
|
||||||
|
This must stay green before considering work complete.
|
||||||
|
|
||||||
|
When relevant, also run other project checks (build/lint/test) and report failures clearly.
|
||||||
|
|
||||||
|
## Documentation Sync Policy (Required)
|
||||||
|
|
||||||
|
When behavior, commands, architecture, or contracts change, update docs in the same change.
|
||||||
|
|
||||||
|
At minimum, review and update as needed:
|
||||||
|
|
||||||
|
1. `README.md` (root project behavior + CLI section)
|
||||||
|
2. `scripts/README.md` (actual command usage and env vars)
|
||||||
|
3. `CLI_STANDARD.md` (integration standard)
|
||||||
|
4. `docs/API_CLI_PASSTHROUGH_PATTERN.md` (pattern/rules)
|
||||||
|
|
||||||
|
If a refactor lands without doc updates, the task is incomplete.
|
||||||
|
|
||||||
|
## Refactor Completion Checklist
|
||||||
|
|
||||||
|
- [ ] Business logic lives in API/server only
|
||||||
|
- [ ] CLI only calls API (`scripts/lib/api_client.sh` path)
|
||||||
|
- [ ] No direct DB references in `scripts/`
|
||||||
|
- [ ] `npm run test:refactor` passes
|
||||||
|
- [ ] Docs updated to match shipped behavior
|
||||||
|
- [ ] Any deprecated usage removed or marked clearly
|
||||||
|
|
||||||
|
## Implementation Preferences
|
||||||
|
|
||||||
|
- Prefer minimal, safe changes over large rewrites.
|
||||||
|
- Preserve existing file conventions and script UX.
|
||||||
|
- Keep backward-compatible wrappers only when needed; document them.
|
||||||
|
- If you find stale docs/examples, fix them as part of the same work.
|
||||||
244
CLI_STANDARD.md
244
CLI_STANDARD.md
@ -1,210 +1,90 @@
|
|||||||
# CLI Integration Standard
|
# CLI Integration Standard (API Passthrough)
|
||||||
|
|
||||||
Standard for adding programmatic CLI access to all projects so AI agents can work without browser automation.
|
Standard for exposing reliable CLI access to a web app without duplicating business logic.
|
||||||
|
|
||||||
## Rule: CLI Tools Live INSIDE the Project
|
## Core rule
|
||||||
|
|
||||||
**Location:** `{project-root}/scripts/`
|
- API/server is the single source of truth for domain logic.
|
||||||
|
- CLI is a client of that API.
|
||||||
|
- CLI must not call the database directly.
|
||||||
|
|
||||||
**Why:**
|
If behavior is missing for CLI, add endpoint/service logic in API first, then call it from CLI.
|
||||||
- Version controlled with the project
|
|
||||||
- Self-documenting (API + CLI in same repo)
|
|
||||||
- Portable (clone repo, CLI works immediately)
|
|
||||||
- Project-specific logic stays with project
|
|
||||||
- No hunting around workspace folders
|
|
||||||
|
|
||||||
## Required File Structure
|
## Required project structure
|
||||||
|
|
||||||
```
|
```text
|
||||||
project-root/
|
project-root/
|
||||||
|
├── src/app/api/... # API routes
|
||||||
|
├── src/lib/server/... # business/domain logic
|
||||||
├── scripts/
|
├── scripts/
|
||||||
│ ├── crud.sh # Main CRUD operations
|
│ ├── lib/
|
||||||
│ ├── attach-file.sh # File attachments
|
│ │ └── api_client.sh # shared transport helper
|
||||||
│ ├── README.md # Usage documentation
|
│ ├── <resource>.sh # task/project/sprint style command groups
|
||||||
│ └── .env.example # Required environment variables
|
│ ├── <wrapper>.sh # optional umbrella script
|
||||||
├── api/ # REST API routes (used by CLI)
|
│ ├── README.md # command docs
|
||||||
│ └── items/
|
│ └── tests/
|
||||||
│ ├── route.ts
|
│ ├── *.test.ts # unit tests for shared logic
|
||||||
│ └── [id]/
|
│ └── *.sh # mocked CLI contract tests
|
||||||
│ ├── route.ts
|
└── README.md
|
||||||
│ └── attachments/
|
|
||||||
│ └── route.ts
|
|
||||||
└── README.md # Project README with CLI section
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Required CLI Commands
|
## CLI responsibilities
|
||||||
|
|
||||||
Every project MUST implement these:
|
- Parse args and flags.
|
||||||
|
- Resolve user-friendly names to IDs (via API calls).
|
||||||
|
- Call API endpoints.
|
||||||
|
- Format output and errors.
|
||||||
|
|
||||||
```bash
|
Do not implement:
|
||||||
# From project root:
|
|
||||||
./scripts/crud.sh list [filters] # List all items
|
|
||||||
./scripts/crud.sh get <id> # Get single item
|
|
||||||
./scripts/crud.sh create <json> # Create item
|
|
||||||
./scripts/crud.sh update <id> <field> <value> # Update field
|
|
||||||
./scripts/crud.sh delete <id> # Delete item
|
|
||||||
./scripts/attach-file.sh <id> <path> # Attach file to item
|
|
||||||
```
|
|
||||||
|
|
||||||
## Environment Variables
|
- status/sprint/date/business transition logic
|
||||||
|
- server-side validation rules
|
||||||
|
- persistence logic
|
||||||
|
- auth policy logic
|
||||||
|
|
||||||
Each project's CLI needs these in `scripts/.env` (gitignored):
|
## Configuration
|
||||||
|
|
||||||
```bash
|
Preferred runtime variables:
|
||||||
# Supabase direct access (for bypassing auth)
|
|
||||||
SUPABASE_URL=https://xxxx.supabase.co
|
|
||||||
SUPABASE_SERVICE_ROLE_KEY=eyJ...
|
|
||||||
|
|
||||||
# Or API-based access
|
- `API_URL` (for example `http://localhost:3000/api`)
|
||||||
API_URL=http://localhost:3000/api
|
- `GANTT_COOKIE_FILE` (or equivalent session cookie path)
|
||||||
API_KEY=secret_key_for_cli_access
|
|
||||||
```
|
|
||||||
|
|
||||||
## Supabase Direct Pattern (Recommended)
|
Do not require service-role DB keys in CLI scripts.
|
||||||
|
|
||||||
For Supabase projects, use direct DB access with service role key:
|
## Testing requirements
|
||||||
|
|
||||||
**File:** `scripts/crud.sh`
|
Every CLI-enabled project must include:
|
||||||
```bash
|
|
||||||
#!/bin/bash
|
|
||||||
set -e
|
|
||||||
|
|
||||||
# Load env from scripts/.env
|
1. API/domain unit tests
|
||||||
source "$(dirname "$0")/.env"
|
2. API route/integration tests
|
||||||
|
3. CLI contract tests with mocked transport
|
||||||
|
|
||||||
action=$1
|
## CLI contract mock pattern
|
||||||
shift
|
|
||||||
|
|
||||||
case $action in
|
For shell CLIs:
|
||||||
list)
|
|
||||||
curl -s "${SUPABASE_URL}/rest/v1/items?select=*" \
|
|
||||||
-H "apikey: ${SUPABASE_SERVICE_ROLE_KEY}" \
|
|
||||||
-H "Authorization: Bearer ${SUPABASE_SERVICE_ROLE_KEY}" | jq '.'
|
|
||||||
;;
|
|
||||||
get)
|
|
||||||
id=$1
|
|
||||||
curl -s "${SUPABASE_URL}/rest/v1/items?id=eq.${id}" \
|
|
||||||
-H "apikey: ${SUPABASE_SERVICE_ROLE_KEY}" \
|
|
||||||
-H "Authorization: Bearer ${SUPABASE_SERVICE_ROLE_KEY}" | jq '.[0]'
|
|
||||||
;;
|
|
||||||
create)
|
|
||||||
data=$1
|
|
||||||
curl -s -X POST "${SUPABASE_URL}/rest/v1/items" \
|
|
||||||
-H "apikey: ${SUPABASE_SERVICE_ROLE_KEY}" \
|
|
||||||
-H "Authorization: Bearer ${SUPABASE_SERVICE_ROLE_KEY}" \
|
|
||||||
-H "Content-Type: application/json" \
|
|
||||||
-d "$data" | jq '.'
|
|
||||||
;;
|
|
||||||
update)
|
|
||||||
id=$1
|
|
||||||
field=$2
|
|
||||||
value=$3
|
|
||||||
curl -s -X PATCH "${SUPABASE_URL}/rest/v1/items?id=eq.${id}" \
|
|
||||||
-H "apikey: ${SUPABASE_SERVICE_ROLE_KEY}" \
|
|
||||||
-H "Authorization: Bearer ${SUPABASE_SERVICE_ROLE_KEY}" \
|
|
||||||
-H "Content-Type: application/json" \
|
|
||||||
-d "{\"${field}\": \"${value}\"}" | jq '.'
|
|
||||||
;;
|
|
||||||
delete)
|
|
||||||
id=$1
|
|
||||||
curl -s -X DELETE "${SUPABASE_URL}/rest/v1/items?id=eq.${id}" \
|
|
||||||
-H "apikey: ${SUPABASE_SERVICE_ROLE_KEY}" \
|
|
||||||
-H "Authorization: Bearer ${SUPABASE_SERVICE_ROLE_KEY}"
|
|
||||||
echo "Deleted ${id}"
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
echo "Usage: $0 {list|get <id>|create <json>|update <id> <field> <value>|delete <id>}"
|
|
||||||
exit 1
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
```
|
|
||||||
|
|
||||||
## File Attachment Pattern
|
- mock `curl` via `PATH` override
|
||||||
|
- log `METHOD URL PAYLOAD`
|
||||||
|
- return fixture JSON + HTTP codes
|
||||||
|
- fail on unhandled endpoint calls
|
||||||
|
- assert expected endpoint calls were made
|
||||||
|
|
||||||
**File:** `scripts/attach-file.sh`
|
Also assert no direct DB references remain in `scripts/` (for example `rest/v1`, service keys).
|
||||||
```bash
|
|
||||||
#!/bin/bash
|
|
||||||
set -e
|
|
||||||
|
|
||||||
source "$(dirname "$0")/.env"
|
## Verification checklist
|
||||||
|
|
||||||
ITEM_ID=$1
|
- [ ] CLI scripts only call API
|
||||||
FILE_PATH=$2
|
- [ ] No direct DB credentials/queries in CLI
|
||||||
|
- [ ] Missing CLI behavior added to API first
|
||||||
|
- [ ] Tests added/updated (unit + mocked contract)
|
||||||
|
- [ ] Refactor suite runs in CI
|
||||||
|
- [ ] `scripts/README.md` and root `README.md` are updated
|
||||||
|
|
||||||
if [ -z "$ITEM_ID" ] || [ -z "$FILE_PATH" ]; then
|
## Migration guide (direct DB CLI -> API passthrough CLI)
|
||||||
echo "Usage: $0 <item-id> <file-path>"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ ! -f "$FILE_PATH" ]; then
|
1. Inventory commands and duplicated logic.
|
||||||
echo "Error: File not found: $FILE_PATH"
|
2. Implement needed behavior in API/server modules.
|
||||||
exit 1
|
3. Replace CLI DB calls with `api_call` helper.
|
||||||
fi
|
4. Add mocked contract tests that cover all command families.
|
||||||
|
5. Remove old DB code and env vars from scripts.
|
||||||
# Read and encode file
|
6. Update docs and CI gates.
|
||||||
mime=$(file -b --mime-type "$FILE_PATH")
|
|
||||||
base64=$(base64 -i "$FILE_PATH")
|
|
||||||
filename=$(basename "$FILE_PATH")
|
|
||||||
size=$(stat -f%z "$FILE_PATH" 2>/dev/null || stat -c%s "$FILE_PATH")
|
|
||||||
|
|
||||||
# Build attachment JSON
|
|
||||||
attachment=$(jq -n \
|
|
||||||
--arg id "$(uuidgen | tr '[:upper:]' '[:lower:]')" \
|
|
||||||
--arg name "$filename" \
|
|
||||||
--arg type "$mime" \
|
|
||||||
--arg data "data:${mime};base64,${base64}" \
|
|
||||||
--argjson size "$size" \
|
|
||||||
'{id: $id, name: $name, type: $type, dataUrl: $data, size: $size}')
|
|
||||||
|
|
||||||
# Get current attachments, append new one
|
|
||||||
current=$(curl -s "${SUPABASE_URL}/rest/v1/items?id=eq.${ITEM_ID}&select=attachments" \
|
|
||||||
-H "apikey: ${SUPABASE_SERVICE_ROLE_KEY}" \
|
|
||||||
-H "Authorization: Bearer ${SUPABASE_SERVICE_ROLE_KEY}" | jq '.[0].attachments // []')
|
|
||||||
|
|
||||||
updated=$(echo "$current" | jq ". + [$attachment]")
|
|
||||||
|
|
||||||
# Update item
|
|
||||||
curl -s -X PATCH "${SUPABASE_URL}/rest/v1/items?id=eq.${ITEM_ID}" \
|
|
||||||
-H "apikey: ${SUPABASE_SERVICE_ROLE_KEY}" \
|
|
||||||
-H "Authorization: Bearer ${SUPABASE_SERVICE_ROLE_KEY}" \
|
|
||||||
-H "Content-Type: application/json" \
|
|
||||||
-d "{\"attachments\": $updated}" | jq '.'
|
|
||||||
|
|
||||||
echo "✅ Attached ${filename} (${size} bytes) to item ${ITEM_ID}"
|
|
||||||
```
|
|
||||||
|
|
||||||
## Per-Project Reference
|
|
||||||
|
|
||||||
### Gantt Board
|
|
||||||
- **Location:** `/Users/mattbruce/Documents/Projects/OpenClaw/Web/gantt-board/scripts/`
|
|
||||||
- **Scripts:** `gantt-task-crud.sh`, `attach-file.sh`, `view-attachment.sh`
|
|
||||||
- **Auth:** Supabase service role key
|
|
||||||
- **Table:** `public.tasks`
|
|
||||||
|
|
||||||
### Adding CLI to a New Project
|
|
||||||
|
|
||||||
1. Create `scripts/` directory in project root
|
|
||||||
2. Copy template scripts from gantt-board
|
|
||||||
3. Update table names and fields for your project
|
|
||||||
4. Create `scripts/.env` with Supabase credentials
|
|
||||||
5. Test: `./scripts/crud.sh list`
|
|
||||||
6. Commit to git: `git add scripts/ && git commit -m "Add CLI tools for AI access"`
|
|
||||||
7. Update project's README.md with CLI usage section
|
|
||||||
|
|
||||||
## Agent Instructions
|
|
||||||
|
|
||||||
When working on a project:
|
|
||||||
1. Check for `scripts/` directory in project root
|
|
||||||
2. If CLI exists, use it: `./scripts/crud.sh list`
|
|
||||||
3. If CLI doesn't exist, create it using patterns above
|
|
||||||
4. NEVER create files in workspace scripts folder for project-specific tools
|
|
||||||
|
|
||||||
## Verification Checklist
|
|
||||||
|
|
||||||
Before saying a task is done:
|
|
||||||
- [ ] CLI tools are in `{project}/scripts/`, NOT workspace
|
|
||||||
- [ ] Scripts are executable (`chmod +x`)
|
|
||||||
- [ ] `.env` file exists with credentials (gitignored)
|
|
||||||
- [ ] Scripts work: `./scripts/crud.sh list` returns data
|
|
||||||
- [ ] Changes are committed to git
|
|
||||||
- [ ] Project README documents CLI usage
|
|
||||||
|
|||||||
40
README.md
40
README.md
@ -35,6 +35,14 @@ Task and sprint board built with Next.js + Zustand and Supabase-backed API persi
|
|||||||
- Task detail now includes explicit Project + Sprint selection; selecting a sprint auto-aligns `projectId`.
|
- Task detail now includes explicit Project + Sprint selection; selecting a sprint auto-aligns `projectId`.
|
||||||
- API validation now accepts UUID-shaped IDs used by existing data and returns clearer error payloads for failed writes.
|
- API validation now accepts UUID-shaped IDs used by existing data and returns clearer error payloads for failed writes.
|
||||||
|
|
||||||
|
### Feb 24, 2026 updates
|
||||||
|
|
||||||
|
- Standardized CLI tools to API passthrough mode only (no direct DB logic in scripts).
|
||||||
|
- Consolidated shared CLI transport into `scripts/lib/api_client.sh`.
|
||||||
|
- Added refactor safety tests:
|
||||||
|
- sprint selection unit tests
|
||||||
|
- mocked CLI API-contract tests across task/project/sprint/auth/debug command paths
|
||||||
|
|
||||||
### Sprint date semantics (important)
|
### Sprint date semantics (important)
|
||||||
|
|
||||||
- Sprint dates are treated as local calendar-day boundaries:
|
- Sprint dates are treated as local calendar-day boundaries:
|
||||||
@ -254,21 +262,31 @@ npm run lint
|
|||||||
Located in `scripts/` directory. These allow programmatic access without browser automation.
|
Located in `scripts/` directory. These allow programmatic access without browser automation.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Task CRUD
|
# Full wrapper
|
||||||
./scripts/gantt-task-crud.sh list [status] # List all tasks
|
./scripts/gantt.sh task list open
|
||||||
./scripts/gantt-task-crud.sh get <task-id> # Get specific task
|
./scripts/gantt.sh task create "Fix login issue" todo high p1
|
||||||
./scripts/gantt-task-crud.sh create "Title" [status] [priority] [project-id] [assignee-id]
|
./scripts/gantt.sh sprint close <sprint-id>
|
||||||
./scripts/gantt-task-crud.sh update <task-id> <field> <value>
|
./scripts/gantt.sh auth session
|
||||||
./scripts/gantt-task-crud.sh delete <task-id>
|
|
||||||
|
|
||||||
# File Attachments
|
# Focused helpers
|
||||||
./scripts/attach-file.sh <task-id> <file-path> # Attach file to task
|
./scripts/task.sh list --json
|
||||||
./scripts/view-attachment.sh <task-id> [index] # View attachment content
|
./scripts/project.sh list --json
|
||||||
|
./scripts/sprint.sh list --active --json
|
||||||
|
./scripts/attach-file.sh <task-id> <file-path>
|
||||||
|
./scripts/view-attachment.sh <task-id> [index]
|
||||||
```
|
```
|
||||||
|
|
||||||
**Requires:** `scripts/.env` with `SUPABASE_URL` and `SUPABASE_SERVICE_ROLE_KEY`
|
**Architecture:** CLI is API passthrough only. Business logic lives in API/server code.
|
||||||
|
|
||||||
See: `STANDARD_CLI_INTEGRATION.md` in workspace for full pattern.
|
**Docs:**
|
||||||
|
- `scripts/README.md` (command details and env vars)
|
||||||
|
- `docs/API_CLI_PASSTHROUGH_PATTERN.md` (refactor/architecture standard)
|
||||||
|
|
||||||
|
**Refactor test suite:**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm run test:refactor
|
||||||
|
```
|
||||||
|
|
||||||
## Notes
|
## Notes
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user