Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
29 changes: 29 additions & 0 deletions .agents/skills/commit/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
---
name: commit
description: Stage and commit changes following project conventions. Use after all quality checks pass.
---

# Commit

Stage and commit changes using the conventions defined in
CONTRIBUTING.md.

## Prerequisites

- Run the validate skill first. All checks must pass.

## Steps

1. Read the Commit Conventions section of CONTRIBUTING.md for
the format rules.
2. Review the staged and unstaged changes to understand what
was changed.
3. Group changes into logical units. Each commit should represent
one coherent change. If changes span multiple concerns (e.g., a
bug fix and a refactor), they should be separate commits.
4. For each logical group:
a. Determine the appropriate commit type and scope.
b. Construct a commit message that follows the documented format.
c. Stage only the files belonging to that group.
d. Commit with the constructed message.
5. Confirm all commits were created and display the messages.
28 changes: 28 additions & 0 deletions .agents/skills/pr/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
---
name: pr
description: Create a branch and open a pull request via GitHub CLI. Use after changes are committed.
---

# Pull Request

Create a feature branch, push changes, and open a PR using `gh` CLI.

## Prerequisites

- `gh` CLI must be installed and authenticated.
- Changes must already be committed using the commit skill.

## Steps

1. Read the Branch Naming section of CONTRIBUTING.md for the
naming convention.
2. Create a new branch from the current HEAD following the
naming convention.
3. Push the branch to the remote.
4. Read .github/pull_request_template.md for the expected PR
body structure.
5. Construct the PR title following the Conventional Commits
format documented in CONTRIBUTING.md.
6. Fill in the PR body template based on the committed changes.
7. Open the PR using `gh pr create` targeting the default branch.
8. Display the PR URL.
18 changes: 18 additions & 0 deletions .agents/skills/validate/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
---
name: validate
description: Run all project quality checks and report results. Use before committing or opening a PR.
---

# Validate

Run all project quality checks and report results.

## Steps

1. Read the Quick Reference section of AGENTS.md for the exact commands.
2. Run the format check command. Report pass or fail.
3. Run the lint command. Report pass or fail.
4. Run the build command. Report pass or fail.
5. Run the test command. Report pass or fail.
6. Summarize results. If anything failed, stop here — do not
proceed to commit or PR.
12 changes: 11 additions & 1 deletion .claude/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,17 @@
"permissions": {
"allow": [
"Bash(poetry add:*)",
"Bash(poetry remove:*)"
"Bash(poetry remove:*)",
"Bash(just lint)",
"Bash(just fmt)",
"Bash(just test-unit)",
"Bash(just test-unit:*)",
"Bash(just check)",
"Bash(just install)",
"Bash(just build)",
"Bash(gh pr create:*)",
"Bash(gh label create:*)",
"Bash(gh label list:*)"
]
}
}
34 changes: 34 additions & 0 deletions .github/ISSUE_TEMPLATE/bug_report.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
---
name: Bug Report
about: Report a bug or unexpected behavior
labels: bug
---

## Description

A clear description of the bug.

## Steps to Reproduce

1. ...
2. ...
3. ...

## Expected Behavior

What you expected to happen.

## Actual Behavior

What actually happened. Include error messages or logs if available.

## Environment

- Package: (sdk / api / client / bot)
- Version:
- Python version:
- OS:

## Additional Context

Any other relevant information.
21 changes: 21 additions & 0 deletions .github/ISSUE_TEMPLATE/feature_request.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
---
name: Feature Request
about: Suggest a new feature or improvement
labels: enhancement
---

## Description

A clear description of the feature.

## Motivation

Why is this feature needed? What problem does it solve?

## Proposed Solution

How should this work? Include API examples or code snippets if relevant.

## Alternatives

Any alternative solutions or workarounds you've considered.
12 changes: 12 additions & 0 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
## Summary

<!-- What changed and why? Keep it brief. -->

## Test Plan

- [ ] `just lint` passes
- [ ] `just test-unit` passes

## Notes

<!-- Anything reviewers should know? Remove this section if not needed. -->
50 changes: 50 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
name: CI

on:
pull_request:
branches: [main]

permissions:
contents: read

jobs:
lint:
name: Format Check
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- uses: actions/setup-python@v5
with:
python-version: "3.11"

- name: Check formatting with Black
run: pip install black && black --check .

test:
name: Unit Tests
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- uses: extractions/setup-just@v3

- name: Run unit tests
run: just test-unit

pr-title:
name: PR Title
runs-on: ubuntu-latest
steps:
- uses: amannn/action-semantic-pull-request@v5
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
types: |
feat
fix
chore
docs
ci
test
refactor
128 changes: 128 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
# AGENTS.md — PySequence

## Quick Reference

```bash
just install # Install dependencies (for IDE support)
just fmt # Format code with Black
just lint # Check formatting (no changes)
just test-unit # Run unit tests in Docker
just check # Run lint + unit tests (full local CI)
just build # Build all Docker images
just api-up # Start the API server
just bot-up # Start the Telegram bot
```

Add `--op` to inject secrets via 1Password: `just test-unit --op`

## Architecture Overview

**Monorepo — 4 packages, each independently deployable:**

```
packages/
pysequence-sdk/ # GraphQL SDK (curl_cffi + Playwright)
pysequence-api/ # FastAPI REST server (depends on SDK)
pysequence-client/ # HTTP client for the REST server (standalone)
pysequence-bot/ # Optional Telegram bot (depends on SDK)
```

**Dependency graph:**
```
pysequence-client → (HTTP) → pysequence-api → pysequence-sdk → (GraphQL) → Sequence.io
pysequence-bot ────────┘
```

- **SDK** — Core. Auth0 tokens, GraphQL client, Pydantic models, shared safeguards.
- **API** — REST trust boundary for external services. API-key auth, transfer limits, audit trail.
- **Client** — Standalone HTTP client for consuming the REST API. No SDK dependency.
- **Bot** — Telegram bot with Claude AI agent. Uses SDK directly (not the API).

## Code Conventions

### Commits

Use [Conventional Commits](https://www.conventionalcommits.org/):

```
<type>: <description>
```

Types: `feat`, `fix`, `chore`, `docs`, `ci`, `test`, `refactor`

Examples:
- `feat: add pod transfer history endpoint`
- `fix: handle empty agent response in Telegram bot`
- `chore: bump version to 0.3.1`

### Formatting

- **Black** — all Python code, enforced in CI
- Run `just fmt` to format, `just lint` to check

### Testing

- **pytest** in Docker via `just test-unit`
- Unit tests: no external dependencies, mock the SDK
- Integration tests: `just test-integration --op` (requires 1Password secrets)

### Branch Naming

```
feature/<kebab-case-description>
fix/<kebab-case-description>
chore/<kebab-case-description>
docs/<kebab-case-description>
```

## Contribution Rules

- **One logical change per PR** — don't mix unrelated changes
- **Squash merge** — PR title becomes the commit message on `main`
- **CI must pass** — `just lint` + `just test-unit` + PR title check
- **PR title = Conventional Commits format** — enforced by CI

## Common Patterns

### Browser-Compatible HTTP

The SDK uses `curl_cffi` with Chrome TLS fingerprinting. All HTTP requests must include browser-matching headers (`origin`, `referer`, `sec-fetch-*`, `x-request-id: webapp-<uuid>`).

### GraphQL Must Match the Webapp

Query strings, fragment names, field selections, and `__typename` inclusions must exactly match what the Sequence webapp sends. Do not invent new queries.

### Shared Safeguards

`AuditLog` and `DailyLimitTracker` live in `pysequence_sdk.safeguards` and are shared by both the API server and the bot. Do not duplicate safeguard logic.

### Single SequenceClient Per Server

All requests share one `SequenceClient` instance so rate limiting works correctly. Do not create multiple instances.

### Secrets vs Config

- **Secrets** (`SEQUENCE_*`, `TELEGRAM_BOT_TOKEN`, `ANTHROPIC_API_KEY`) — always environment variables
- **Non-secret config** (model, limits, system prompt) — `bot-config.yaml`, mounted into Docker

### Token Management

Fully automated via `get_access_token()`. Tokens cached in `.tokens.json`. Consumers never manage tokens directly.

## Do Not

- Add Node.js dependencies to this project
- Use raw `poetry run` when a `just` recipe exists
- Modify GraphQL queries without matching the webapp
- Commit `.tokens.json`, `.env`, or any secrets
- Create multiple `SequenceClient` instances in a single server
- Over-engineer — only build what's needed

## Skills

Agent skills are defined in `.agents/skills/`. Each skill has a `SKILL.md` with instructions:

- **validate** — Run lint + unit tests, auto-fix formatting issues
- **commit** — Stage changes and create a Conventional Commits message
- **pr** — Create a branch, push, and open a PR with proper formatting
Loading