From 9ef4bd4b17db7c87ebd49e978d82d190066db296 Mon Sep 17 00:00:00 2001 From: Kaleb Cole Date: Thu, 26 Mar 2026 19:38:35 -0700 Subject: [PATCH 1/3] docs: add AGENTS.md and schema specification - AGENTS.md: agent guide for Partiful CLI with commands, gotchas, boundaries - docs/agents-md-schema.md: systematic schema for writing AGENTS.md files - Based on GitHub Blog analysis (2,500+ repos) and ETH Zurich research - Focus on non-inferable knowledge that actually helps agents --- AGENTS.md | 136 +++++++++++++++++++++++++++++++++++++++ docs/agents-md-schema.md | 89 +++++++++++++++++++++++++ 2 files changed, 225 insertions(+) create mode 100644 AGENTS.md create mode 100644 docs/agents-md-schema.md diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..4d7e95d --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,136 @@ +# AGENTS.md — Partiful CLI + +JSON-first CLI for managing Partiful events. No official API exists — this uses Partiful's internal Firebase/Firestore API. + +## Commands + +```bash +# Health check (run first to verify auth) +partiful doctor + +# Auth +partiful auth status +partiful auth login # SMS verification flow + +# Events +partiful events list # upcoming events +partiful events list --past # past events +partiful events get +partiful events create --title "..." --date "Mar 28 7pm" --poster-search "game night" --private -y +partiful events update --title "New Title" +partiful events cancel + +# Guests +partiful guests list # only works for events you HOST +partiful guests invite --user-id # invite by Partiful user ID +partiful guests invite --phone +1234567890 # invite by phone number + +# Contacts (your Partiful network) +partiful contacts list "kevin" # search by name +partiful contacts list --limit 50 # browse all + +# Co-hosts +partiful cohosts add --name "Kevin Granados" # resolved from contacts +partiful cohosts add --user-id + +# Text blasts (message all guests) +partiful blasts send --message "Running 10 min late!" -y + +# Posters +partiful posters search "game night" +partiful posters list + +# Utilities +partiful +clone # clone event with new date +partiful +export # export event + guest list +partiful +share # generate shareable link +partiful +watch # poll for RSVP changes (NDJSON stream) +partiful schema [command.path] # introspect any command's parameters +``` + +## Testing + +```bash +npm test # vitest run (all tests) +npm run test:watch # vitest watch mode +``` + +Tests live in `tests/`. Integration tests (`*.integration.test.js`) hit real APIs and require valid auth. + +## Project structure + +``` +src/ +├── cli.js # Entry point, Commander setup +├── commands/ # One file per command group +│ ├── events.js +│ ├── guests.js +│ ├── contacts.js +│ ├── blasts.js +│ ├── cohosts.js +│ ├── posters.js +│ ├── auth.js +│ ├── schema.js +│ ├── templates.js +│ ├── bulk.js +│ ├── setup.js +│ └── doctor.js +├── helpers/ # Shared utilities +└── lib/ # Core library (API client, auth, Firebase) +tests/ +├── *.test.js # Unit tests +├── *.integration.test.js +└── fixtures/ +``` + +## Non-obvious things agents get wrong + +### Contacts don't expose emails or phone numbers +The `contacts list` endpoint returns names, user IDs, and shared event counts. It does **not** return email addresses or phone numbers. This is a Partiful privacy constraint, not a bug. Don't waste time trying to extract contact details — they aren't available. + +### Guest lists are permission-gated +`guests list ` only works for events the authenticated user **hosts**. For events you're just attending, you'll get a 403. This is expected behavior. + +### Image upload is unreliable +`--image ` on `events create` can fail with a 404 upload error. When this happens, fall back to `--poster ` or `--poster-search "query"` to use Partiful's built-in poster library instead. The poster library is extensive and searchable. + +### The invite flow: contacts → user IDs → invite +To invite someone by name: +1. `partiful contacts list "name"` → get their `id` field +2. `partiful guests invite --user-id ` → send invite + +There is no `--name` flag on `guests invite`. You must resolve names to user IDs first via contacts. + +### Auth: userId can be null and things still work +`partiful doctor` may flag `userId: null` in the config. The CLI still works for most operations — it authenticates via Firebase token, not userId. Don't treat this as a blocking error. + +### Date parsing +`--date` accepts ISO 8601 (`2026-03-28T19:00:00`) or natural language (`Mar 28 7pm`). Default timezone is `America/Los_Angeles`. Always pass `--timezone` if the user is in a different zone. + +### Confirmation prompts +Write commands (`create`, `cancel`, `invite`, `blasts send`) prompt for confirmation. Pass `-y` or `--yes` to skip in automated flows. + +### Output format +All commands output JSON by default. Use `--format table|csv|ndjson` for alternatives. Agents should use the default JSON — it's structured and parseable. + +## Code style + +- Plain JavaScript (no TypeScript, no build step) +- Commander.js for CLI framework +- Vitest for testing +- `src/commands/` — one file per command group, each exports a function that registers subcommands +- `src/lib/` — API client, Firebase auth, HTTP helpers +- Favor explicit error handling with structured error objects (`{ status, error: { code, type, message } }`) + +## Git workflow + +- Branch from `main` +- Branch naming: `feat/description`, `fix/description` +- Run `npm test` before committing +- PR required for merge + +## Boundaries + +- ✅ **Always:** Run `partiful doctor` before assuming auth works. Pass `-y` for automated flows. Use JSON output. +- ⚠️ **Ask first:** Before sending blasts (messages real people), cancelling events, or bulk operations. +- 🚫 **Never:** Hardcode auth tokens. Expose phone numbers or user IDs in logs/output meant for display. Skip confirmation on destructive actions without user consent. diff --git a/docs/agents-md-schema.md b/docs/agents-md-schema.md new file mode 100644 index 0000000..444341c --- /dev/null +++ b/docs/agents-md-schema.md @@ -0,0 +1,89 @@ +# AGENTS.md Schema — Systematic Structure + +This documents the schema and rationale behind how we write AGENTS.md files +for CLI tools. Based on research from GitHub Blog (2,500+ repos), agents.md +spec (60k+ repos), and ETH Zurich findings (March 2026). + +## Core Principle + +> Only include what an agent **cannot infer** from `--help`, source code, +> or standard conventions. Everything else is noise that increases cost +> and reduces performance. (ETH Zurich, 2026) + +## Schema + +An AGENTS.md for a CLI tool should have these sections, in this order: + +### 1. Identity (2-3 lines max) +- What it is, one sentence +- Key constraint the agent needs to know immediately +- Example: "JSON-first CLI for Partiful. No official API — uses internal Firebase API." + +### 2. Commands (executable, copy-pasteable) +- Every command the agent might need, with realistic arguments +- Group by resource (events, guests, contacts, etc.) +- Include flags that matter. Skip flags an agent will discover via `--help` +- **This section is the most referenced.** Put it early. + +### 3. Testing +- Exact test command(s) +- Where tests live +- Which tests hit real APIs (integration vs unit) + +### 4. Project Structure (only if non-obvious) +- File tree, 2 levels deep max +- One-line description per directory +- Skip if it follows standard conventions (e.g., Next.js app) + +### 5. Non-obvious Things (THE MOST VALUABLE SECTION) +This is where the real value lives. Document: +- **Permission gotchas** — what fails and why (not bugs, just auth/scope constraints) +- **Data model surprises** — fields that are missing, types that are weird +- **Workarounds** — when Plan A fails, what's Plan B +- **Multi-step flows** — sequences that aren't obvious from individual commands +- **Silent failures** — things that return 200 OK but didn't actually work + +Format each as: +``` +### + + + +``` + +### 6. Code Style (only non-inferable conventions) +- Language, framework, test runner +- Naming patterns only if unusual +- Skip if standard (e.g., "use camelCase in JS" is inferable) + +### 7. Git Workflow (only if non-standard) +- Branch naming if you have a convention +- Required checks before commit +- Skip if it's just "branch from main, PR to merge" + +### 8. Boundaries (three tiers) +- ✅ **Always** — things the agent should do without asking +- ⚠️ **Ask first** — things that affect real people or are destructive +- 🚫 **Never** — hard constraints (security, privacy, data loss) + +## Anti-patterns (from research) + +1. **Architecture overviews** — agents don't use them to find files faster (ETH Zurich) +2. **Restating what `--help` says** — pure noise, increases token cost +3. **LLM-generated content** — -3% success rate vs no file at all +4. **Vague instructions** — "be careful with auth" vs "run `partiful doctor` first" +5. **Philosophy/motivation** — "we believe in clean code" does nothing + +## Token Budget Guidance + +- Aim for 2,000-5,000 tokens (roughly 150-400 lines of markdown) +- Under 2,000: probably missing non-obvious gotchas +- Over 5,000: probably including inferable content that hurts performance +- The "non-obvious things" section should be 30-50% of the file + +## Validation Checklist + +For each line in the AGENTS.md, ask: +- [ ] Could an agent figure this out from `--help` or reading source? → Remove it +- [ ] Has this actually caused an agent to fail/waste time? → Keep it +- [ ] Is this a hard constraint (security, privacy, permissions)? → Keep it +- [ ] Is this a multi-step flow that isn't obvious? → Keep it +- [ ] Is this describing standard conventions? → Remove it From 58fd7d234c9e005d5a492b437e1d9152367dd1c2 Mon Sep 17 00:00:00 2001 From: Kaleb Cole Date: Thu, 26 Mar 2026 20:29:50 -0700 Subject: [PATCH 2/3] docs: remove schema spec (lives in personal-assistant repo) --- docs/agents-md-schema.md | 89 ---------------------------------------- 1 file changed, 89 deletions(-) delete mode 100644 docs/agents-md-schema.md diff --git a/docs/agents-md-schema.md b/docs/agents-md-schema.md deleted file mode 100644 index 444341c..0000000 --- a/docs/agents-md-schema.md +++ /dev/null @@ -1,89 +0,0 @@ -# AGENTS.md Schema — Systematic Structure - -This documents the schema and rationale behind how we write AGENTS.md files -for CLI tools. Based on research from GitHub Blog (2,500+ repos), agents.md -spec (60k+ repos), and ETH Zurich findings (March 2026). - -## Core Principle - -> Only include what an agent **cannot infer** from `--help`, source code, -> or standard conventions. Everything else is noise that increases cost -> and reduces performance. (ETH Zurich, 2026) - -## Schema - -An AGENTS.md for a CLI tool should have these sections, in this order: - -### 1. Identity (2-3 lines max) -- What it is, one sentence -- Key constraint the agent needs to know immediately -- Example: "JSON-first CLI for Partiful. No official API — uses internal Firebase API." - -### 2. Commands (executable, copy-pasteable) -- Every command the agent might need, with realistic arguments -- Group by resource (events, guests, contacts, etc.) -- Include flags that matter. Skip flags an agent will discover via `--help` -- **This section is the most referenced.** Put it early. - -### 3. Testing -- Exact test command(s) -- Where tests live -- Which tests hit real APIs (integration vs unit) - -### 4. Project Structure (only if non-obvious) -- File tree, 2 levels deep max -- One-line description per directory -- Skip if it follows standard conventions (e.g., Next.js app) - -### 5. Non-obvious Things (THE MOST VALUABLE SECTION) -This is where the real value lives. Document: -- **Permission gotchas** — what fails and why (not bugs, just auth/scope constraints) -- **Data model surprises** — fields that are missing, types that are weird -- **Workarounds** — when Plan A fails, what's Plan B -- **Multi-step flows** — sequences that aren't obvious from individual commands -- **Silent failures** — things that return 200 OK but didn't actually work - -Format each as: -``` -### - + + -``` - -### 6. Code Style (only non-inferable conventions) -- Language, framework, test runner -- Naming patterns only if unusual -- Skip if standard (e.g., "use camelCase in JS" is inferable) - -### 7. Git Workflow (only if non-standard) -- Branch naming if you have a convention -- Required checks before commit -- Skip if it's just "branch from main, PR to merge" - -### 8. Boundaries (three tiers) -- ✅ **Always** — things the agent should do without asking -- ⚠️ **Ask first** — things that affect real people or are destructive -- 🚫 **Never** — hard constraints (security, privacy, data loss) - -## Anti-patterns (from research) - -1. **Architecture overviews** — agents don't use them to find files faster (ETH Zurich) -2. **Restating what `--help` says** — pure noise, increases token cost -3. **LLM-generated content** — -3% success rate vs no file at all -4. **Vague instructions** — "be careful with auth" vs "run `partiful doctor` first" -5. **Philosophy/motivation** — "we believe in clean code" does nothing - -## Token Budget Guidance - -- Aim for 2,000-5,000 tokens (roughly 150-400 lines of markdown) -- Under 2,000: probably missing non-obvious gotchas -- Over 5,000: probably including inferable content that hurts performance -- The "non-obvious things" section should be 30-50% of the file - -## Validation Checklist - -For each line in the AGENTS.md, ask: -- [ ] Could an agent figure this out from `--help` or reading source? → Remove it -- [ ] Has this actually caused an agent to fail/waste time? → Keep it -- [ ] Is this a hard constraint (security, privacy, permissions)? → Keep it -- [ ] Is this a multi-step flow that isn't obvious? → Keep it -- [ ] Is this describing standard conventions? → Remove it From c2c2286bcf708a9d16650ed7bdb6353459aed4b1 Mon Sep 17 00:00:00 2001 From: Kaleb Cole Date: Thu, 26 Mar 2026 20:50:56 -0700 Subject: [PATCH 3/3] =?UTF-8?q?docs:=20rearchitect=20AGENTS.md=20=E2=80=94?= =?UTF-8?q?=20remove=20command=20listings,=20focus=20on=20non-inferable=20?= =?UTF-8?q?gotchas?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Based on analysis of OpenAI Codex and Google Workspace CLI AGENTS.md files plus ETH Zurich research (2602.11988): command listings are noise that agents discover via --help. Real value is in permission gotchas, multi-step flows, silent failures, and 'do not' rules. File reduced from 5.3KB to 3KB — higher signal density. --- AGENTS.md | 147 ++++++++++++------------------------------------------ 1 file changed, 32 insertions(+), 115 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 4d7e95d..4fc1a83 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,136 +1,53 @@ # AGENTS.md — Partiful CLI -JSON-first CLI for managing Partiful events. No official API exists — this uses Partiful's internal Firebase/Firestore API. +JSON-first CLI for managing Partiful events. No official API — uses Partiful's internal Firebase/Firestore API with reverse-engineered auth. -## Commands +Run `partiful --help` and `partiful --help` for command reference. Run `partiful schema [command.path]` for parameter introspection (e.g., `partiful schema events.create`). -```bash -# Health check (run first to verify auth) -partiful doctor - -# Auth -partiful auth status -partiful auth login # SMS verification flow - -# Events -partiful events list # upcoming events -partiful events list --past # past events -partiful events get -partiful events create --title "..." --date "Mar 28 7pm" --poster-search "game night" --private -y -partiful events update --title "New Title" -partiful events cancel - -# Guests -partiful guests list # only works for events you HOST -partiful guests invite --user-id # invite by Partiful user ID -partiful guests invite --phone +1234567890 # invite by phone number - -# Contacts (your Partiful network) -partiful contacts list "kevin" # search by name -partiful contacts list --limit 50 # browse all - -# Co-hosts -partiful cohosts add --name "Kevin Granados" # resolved from contacts -partiful cohosts add --user-id - -# Text blasts (message all guests) -partiful blasts send --message "Running 10 min late!" -y - -# Posters -partiful posters search "game night" -partiful posters list - -# Utilities -partiful +clone # clone event with new date -partiful +export # export event + guest list -partiful +share # generate shareable link -partiful +watch # poll for RSVP changes (NDJSON stream) -partiful schema [command.path] # introspect any command's parameters -``` - -## Testing - -```bash -npm test # vitest run (all tests) -npm run test:watch # vitest watch mode -``` - -Tests live in `tests/`. Integration tests (`*.integration.test.js`) hit real APIs and require valid auth. - -## Project structure - -``` -src/ -├── cli.js # Entry point, Commander setup -├── commands/ # One file per command group -│ ├── events.js -│ ├── guests.js -│ ├── contacts.js -│ ├── blasts.js -│ ├── cohosts.js -│ ├── posters.js -│ ├── auth.js -│ ├── schema.js -│ ├── templates.js -│ ├── bulk.js -│ ├── setup.js -│ └── doctor.js -├── helpers/ # Shared utilities -└── lib/ # Core library (API client, auth, Firebase) -tests/ -├── *.test.js # Unit tests -├── *.integration.test.js -└── fixtures/ -``` - -## Non-obvious things agents get wrong +## Things you will get wrong without reading this ### Contacts don't expose emails or phone numbers -The `contacts list` endpoint returns names, user IDs, and shared event counts. It does **not** return email addresses or phone numbers. This is a Partiful privacy constraint, not a bug. Don't waste time trying to extract contact details — they aren't available. - -### Guest lists are permission-gated -`guests list ` only works for events the authenticated user **hosts**. For events you're just attending, you'll get a 403. This is expected behavior. +`contacts list` returns names, user IDs, and shared event counts. It does **not** return email addresses or phone numbers. This is a Partiful privacy constraint. Don't try to extract contact details — they aren't available through any endpoint. -### Image upload is unreliable -`--image ` on `events create` can fail with a 404 upload error. When this happens, fall back to `--poster ` or `--poster-search "query"` to use Partiful's built-in poster library instead. The poster library is extensive and searchable. +### To invite someone by name, you need two steps +There is no `--name` flag on `guests invite`. You must resolve names to user IDs first: +1. `partiful contacts list "name"` → get the `id` field from the result +2. `partiful guests invite --user-id ` -### The invite flow: contacts → user IDs → invite -To invite someone by name: -1. `partiful contacts list "name"` → get their `id` field -2. `partiful guests invite --user-id ` → send invite +### Guest lists are permission-gated +`guests list ` only works for events the authenticated user **hosts**. Attending an event doesn't grant access — you'll get a 403. This is expected, not an error. -There is no `--name` flag on `guests invite`. You must resolve names to user IDs first via contacts. +### Image upload fails silently — use posters instead +`--image ` on `events create` often fails with a 404 upload error. Fall back to `--poster ` or `--poster-search "query"` to use Partiful's built-in poster library. The library is extensive and searchable via `posters search`. ### Auth: userId can be null and things still work -`partiful doctor` may flag `userId: null` in the config. The CLI still works for most operations — it authenticates via Firebase token, not userId. Don't treat this as a blocking error. +`partiful doctor` may flag `userId: null`. The CLI authenticates via Firebase token, not userId — most operations work fine. Don't treat this as a blocking error. -### Date parsing -`--date` accepts ISO 8601 (`2026-03-28T19:00:00`) or natural language (`Mar 28 7pm`). Default timezone is `America/Los_Angeles`. Always pass `--timezone` if the user is in a different zone. +### Destructive commands require confirmation +`events cancel` and `blasts send` prompt for confirmation before executing. Pass `-y` or `--yes` to skip in automated/agent flows. Use `--dry-run` on any command to preview what would happen without side effects. -### Confirmation prompts -Write commands (`create`, `cancel`, `invite`, `blasts send`) prompt for confirmation. Pass `-y` or `--yes` to skip in automated flows. +### Default timezone is America/Los_Angeles +`--date` accepts ISO 8601 or natural language (`Mar 28 7pm`). If the user isn't in Pacific time, pass `--timezone` explicitly or you'll create events at the wrong time. -### Output format -All commands output JSON by default. Use `--format table|csv|ndjson` for alternatives. Agents should use the default JSON — it's structured and parseable. +## Testing -## Code style +```bash +npm test # vitest run +npm run test:watch # vitest watch +``` -- Plain JavaScript (no TypeScript, no build step) -- Commander.js for CLI framework -- Vitest for testing -- `src/commands/` — one file per command group, each exports a function that registers subcommands -- `src/lib/` — API client, Firebase auth, HTTP helpers -- Favor explicit error handling with structured error objects (`{ status, error: { code, type, message } }`) +Integration tests (`tests/*.integration.test.js`) hit real Partiful APIs and need valid auth. Unit tests don't. -## Git workflow +## Code conventions -- Branch from `main` -- Branch naming: `feat/description`, `fix/description` -- Run `npm test` before committing -- PR required for merge +- Plain JavaScript, no TypeScript, no build step +- Commander.js CLI framework, Vitest for tests +- One file per command group in `src/commands/` +- Structured error objects: `{ status, error: { code, type, message } }` +- Do not add generated API crates or SDK wrappers — all API interaction goes through `src/lib/` ## Boundaries -- ✅ **Always:** Run `partiful doctor` before assuming auth works. Pass `-y` for automated flows. Use JSON output. -- ⚠️ **Ask first:** Before sending blasts (messages real people), cancelling events, or bulk operations. -- 🚫 **Never:** Hardcode auth tokens. Expose phone numbers or user IDs in logs/output meant for display. Skip confirmation on destructive actions without user consent. +- ✅ **Always:** Run `partiful doctor` before assuming auth works. Pass `-y` for agent flows. Use default JSON output. +- ⚠️ **Ask first:** Before sending text blasts (messages real humans), cancelling events, or running bulk operations. +- 🚫 **Never:** Hardcode auth tokens in source. Expose phone numbers or Partiful user IDs in user-facing output. Skip confirmation on destructive actions without explicit user consent.