Skip to content

Commit 79ccdd9

Browse files
author
Remote release bot
committed
release v0.1.0
1 parent 4fe2443 commit 79ccdd9

13 files changed

Lines changed: 2399 additions & 47 deletions

File tree

.claude-plugin/marketplace.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
"name": "remote-cli",
99
"source": "./plugins/remote-cli",
1010
"description": "Tools and skills for interacting with the Remote.com partner API from the command line.",
11-
"version": "v0.0.4"
11+
"version": "v0.1.0"
1212
}
1313
]
1414
}

README.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,13 @@ This repository is also a Claude Code plugin marketplace:
5252
/reload-plugins
5353
```
5454

55-
After installing, the `remote-cli` skill is available in Claude Code and knows how to drive the `remotecli` binary.
55+
After installing, two Claude Code skills become available:
56+
57+
- `remote-cli` — drives the `remotecli` binary to perform HR actions (hire someone, list time off, approve expenses, …).
58+
- `remote-api-builder` — guides building your own client (Python, TypeScript, etc.) against the Remote.com partner API, using `remotecli` as a self-documenting executable spec.
5659

5760
## Version
5861

59-
Current release: **v0.0.4**
62+
Current release: **v0.1.0**
6063

6164
See the [Releases page](https://github.com/remoteoss/remote-cli/releases) for history.

plugins/remote-cli/.claude-plugin/plugin.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "remote-cli",
3-
"version": "v0.0.4",
4-
"description": "Skill that drives the `remotecli` binary against the Remote.com partner API.",
3+
"version": "v0.1.0",
4+
"description": "Skills for the Remote.com partner API: `remote-cli` drives the `remotecli` binary for HR actions; `remote-api-builder` guides implementing your own client using `remotecli` as a self-documenting spec.",
55
"author": {
66
"name": "Remote"
77
}
Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
---
2+
name: remote-api-builder
3+
description: Use when an agent is building their own implementation of (parts of) the Remote.com partner API in any stack — Python/TS/Ruby/Go HTTP client, OpenAPI spec, Slack/Teams bot, migration script from another HR system, conformance test, or any service that needs to call Remote.com from somewhere other than the existing remotecli binary. Triggers on prompts like "build a Python client for Remote", "wrap Remote in our backend", "generate an OpenAPI spec from remotecli", "reverse-engineer the Remote API", "implement an Authorize-with-Remote button", "bulk-onboard employees from this CSV." Does NOT trigger on operator prompts ("hire Alice", "approve their time off") — those use the remote-cli skill instead.
4+
---
5+
6+
# remote-api-builder
7+
8+
Use `remotecli` as a **self-documenting executable spec** of the Remote.com partner API. Drive it to discover the surface, capture HTTP, translate to your stack, and verify against the CLI as oracle.
9+
10+
## When to use this skill
11+
12+
| Prompt pattern | Use this skill? |
13+
|---|---|
14+
| "Build a Python/TS/Ruby/Go client for Remote.com" | Yes |
15+
| "Generate an OpenAPI spec / SDK from remotecli" | Yes |
16+
| "Add an 'Authorize with Remote' button to our app" | Yes |
17+
| "Wrap Remote in our backend service / Slack bot / migration script" | Yes |
18+
| "How do I authenticate with Remote from <X>" | Yes (see `references/auth-bootstrap.md`) |
19+
| "Hire Alice in Portugal" / "approve their time off" / any operator action | **No** — use the `remote-cli` skill instead |
20+
21+
## The methodology
22+
23+
Five steps. The skill's references map to them.
24+
25+
| Step | Primary command(s) | What you learn |
26+
|---|---|---|
27+
| **Inventory** | `remotecli describe commands` | Every command, its flags, the HTTP endpoints it invokes, the doc URL |
28+
| **Plan** | `remotecli describe schemas` + `remotecli --plan --answers <seed>` | Form fields, enum options, conditional branches, country variations |
29+
| **Trace** | `remotecli <cmd> --trace 2>trace.log` (against sandbox) | Real HTTP — headers, body, status, timing |
30+
| **Translate** | `references/translation-patterns.md` + `references/auth-bootstrap.md` | Equivalent code in your stack |
31+
| **Verify** | `references/oracle-workflow.md` | Diff your implementation against `remotecli`; the CLI is your contract test |
32+
33+
## Getting started (3 steps)
34+
35+
```bash
36+
export REMOTE_ENVIRONMENT=sandbox
37+
remotecli login # PKCE browser flow — opens your browser
38+
remotecli use # pick the company you want to operate against
39+
remotecli describe commands # you're now exploring the API
40+
```
41+
42+
No partner credentials required for most builders. For the full walkthrough including the rare partner-credentials path, see `references/sandbox-setup.md`.
43+
44+
## Use the CLI vs. build your own
45+
46+
Two axes interact: what you're building, and who's authorizing.
47+
48+
**What you're building:**
49+
50+
| Situation | Recommendation |
51+
|---|---|
52+
| Web / desktop / mobile app — **including your own personal dashboard** | Build your own client and implement PKCE. The "Authorize with Remote" button is the right UX, even when the only user is you. |
53+
| Long-running backend service (worker, webhook receiver) | Build your own HTTP client. PKCE for the initial consent, refresh-token grant for autonomous operation. |
54+
| Serverless function / Lambda | Build your own — binary distribution is friction. |
55+
| Truly headless one-shot script (CSV import, cron job, no UI ever) | Build your own HTTP client. Do the one-time PKCE consent locally to capture a refresh token, then store it in your service's secret store and use the refresh-token grant from then on. |
56+
| Integrating once, manually, ad-hoc | `remotecli` interactive mode + the `remote-cli` skill. |
57+
58+
**Who's authorizing → auth flow:**
59+
60+
| Your tool | Flow | Reference |
61+
|---|---|---|
62+
| Has any login UI — **the default** | PKCE — "Authorize with Remote" button | `references/auth-bootstrap.md` § PKCE |
63+
| Production service after one-time human consent | Refresh-token grant on top of PKCE | `references/auth-bootstrap.md` § refresh-token |
64+
| Headless script you run yourself | Refresh-token grant (do PKCE once to capture, then reuse the refresh token) | `references/auth-bootstrap.md` § refresh-token |
65+
| Remote partner provisioning *new* companies | `client_credentials` + JWT assertion | `references/auth-bootstrap.md` § partner |
66+
67+
## Step 1 — Inventory
68+
69+
```bash
70+
remotecli describe commands # everything
71+
remotecli describe commands --name time-off # prefix-filter
72+
remotecli describe commands --name 'time-off create'
73+
```
74+
75+
Each entry: `name`, `summary`, `flags[]`, `endpoints[].{method,path,doc_url}`, `forms[]` (empty when non-schema-driven), `role_required`.
76+
77+
Use it as a TOC. The `doc_url` deep-links into `developer.remote.com/reference/<endpoint>` when known. See `references/discovery-loop.md` for a worked walkthrough.
78+
79+
## Step 2 — Plan
80+
81+
For schema-driven commands (`employments create`, `contract-amendments create`, `employments update-personal-details`), discover required fields without calling the API:
82+
83+
```bash
84+
echo '{"contract_amendment":{}}' > /tmp/seed.json
85+
remotecli --answers /tmp/seed.json --plan contract-amendments create --employment-id emp_abc123
86+
# → {"type":"plan","data":{"ok":false,"missing":[...],"invalid":[...],"answers":{...}}}
87+
```
88+
89+
For URL templates (without calling the API):
90+
91+
```bash
92+
remotecli describe schemas --country GBR
93+
```
94+
95+
See `references/discovery-loop.md`.
96+
97+
## Step 3 — Trace
98+
99+
Run the real command against sandbox and capture every HTTP request/response:
100+
101+
```bash
102+
remotecli time-off create --employment-id emp_abc \
103+
--timeoff-type time_off --start-date 2026-06-01 --end-date 2026-06-01 \
104+
--trace 2>trace.log
105+
```
106+
107+
`--trace` redacts secrets by default (`Authorization`, `refresh_token`, `client_secret`, `code_verifier` all masked). **Never paste trace output anywhere public without re-confirming `--insecure-log-secrets` is off.**
108+
109+
### Hard gate: no code before traces
110+
111+
**You cannot write implementation code until you have run `--trace` on every endpoint you plan to call.** For each endpoint, record from the actual trace output — not from docs, not from memory, not from `translation-patterns.md` examples:
112+
113+
| Endpoint | Required query params | Response envelope | Key field names on objects |
114+
|---|---|---|---|
115+
| e.g. `GET /v1/timeoff` | (none — trace confirmed) | `data.timeoffs[]` | `employment_id`, `start_date`, `end_date`, `status` |
116+
117+
Fill this table before writing a single function. If you cannot fill a row from a trace, run the trace first.
118+
119+
**Why this matters:** `translation-patterns.md` contains illustrative examples. The actual server may require different params (e.g. `company_id`), use different field names (e.g. `full_name` not `name`), or reject param combinations that look reasonable (e.g. comma-joined status values). Only a trace tells you what the server actually accepts and returns.
120+
121+
## Step 4 — Translate
122+
123+
Take the trace output you captured in Step 3 and match it to your stack. `references/translation-patterns.md` shows the mechanical translation patterns (`GET / POST / PATCH / PUT / multipart`) in Python and TypeScript — use it as a HOW-TO guide for converting a trace into code, not as a substitute for getting a trace. See `references/auth-bootstrap.md` for the auth side — PKCE in your own app is the default; three other flows cover specific cases.
124+
125+
## Step 5 — Verify
126+
127+
Run your implementation alongside `remotecli` against the same operation, diff the JSON outputs. See `references/oracle-workflow.md`.
128+
129+
## Anti-patterns
130+
131+
- **Don't use reference docs or examples as a substitute for traces.** `translation-patterns.md` shows HOW to translate a trace into code — it is not a spec for what the server accepts. Required query params, field names, and response shapes vary by endpoint and environment. A field called `name` in an example may be `full_name` in reality. A status filter that looks composable may reject comma-joined values. Only `--trace` output is authoritative. If you find yourself writing code based on what "seems right" from docs, stop and run the trace.
132+
- **Don't invent query parameters.** If you didn't see a param in a trace, don't send it. If you think filtering would be useful, check whether the CLI flag for it exists (`describe commands`), then trace it to confirm the wire format.
133+
- **Default to PKCE in your own app for any tool with a UI** — including your own personal dashboards, not just multi-tenant products. The "Authorize with Remote" button experience is exactly what `remotecli login` already does; mirror it. Use `internal/auth/pkce.go` as your reference implementation, and for personal tools you can piggyback on the CLI's `client_id` + port `8488` redirect URI to skip allowlist registration entirely. See `references/auth-bootstrap.md` § PKCE.
134+
- **Don't read `~/.remote-cli/state.json` from your application.** That file is `remotecli`'s private local cache — convenient when prototyping on your own laptop, but **not deployable**: it doesn't exist on a server, it carries *your* developer identity (not your users'), and the tokens rotate out from under you whenever the CLI runs. Always implement PKCE (for any tool a human signs into) or the refresh-token grant (for autonomous services), and persist tokens in your own store. See `references/auth-bootstrap.md`.
135+
- **Don't reimplement refresh from scratch.** Once you have a refresh token, the refresh-token grant is `POST {authURL}/oauth2/token` (PKCE-issued) or `{authURL}/auth/oauth2/token` (confidential-client), with `client_id` in a Basic auth header — not the body. Mirror the CLI's 60-seconds-before-expiry proactive-refresh rule.
136+
- **Don't hard-code field names.** Schemas are country-aware; `--plan` is the source of truth. A field that exists in GBR may not exist in USA.
137+
- **Don't paste `--trace` output publicly without confirming `--insecure-log-secrets` was NOT set on the run that produced it.** Redaction is on by default; the flag opts out.
138+
- **Don't write a Python wrapper around `remotecli` to drive it interactively.** Build your own HTTP client — `remotecli` is a discovery and verification tool, not a runtime dependency for production code.
139+
- **Don't iterate against production.** Sandbox or bust.
140+
141+
## Gotchas
142+
143+
- **Minor units.** `annual_gross_salary` is in pence/cents. `7200000` = £72,000.
144+
- **PUT replaces, PATCH merges.** `employments update-personal-details` replaces the whole `personal_details` object — partial payloads wipe other fields. Read-modify-write or use the existing CLI.
145+
- **Country codes are 3-letter ISO.** `GBR` not `GB`, `USA` not `US`.
146+
- **Role restrictions.** `expenses approve`, `time-off approve`, `terminations create` require manager/admin/owner tokens. Employee tokens get 403.
147+
- **Idempotency.** Most `create` endpoints are NOT idempotent (no built-in dedup key). See `references/idempotency.md`.
148+
149+
## Sandbox posture
150+
151+
Always exercise against `REMOTE_ENVIRONMENT=sandbox` for Trace and Verify. `remotecli login` honours `REMOTE_ENVIRONMENT` — switching is `export REMOTE_ENVIRONMENT=production && remotecli login`, no other config. See `references/sandbox-setup.md`.
152+
153+
## External docs
154+
155+
- [developer.remote.com](https://developer.remote.com/) — developer portal home (guide articles)
156+
- [API reference](https://developer.remote.com/reference/welcome-to-remote-api) — canonical per-endpoint catalogue. The `doc_url` field in `describe commands` deep-links into this.
157+
- OAuth & auth concepts (auth section of the portal) — when you need the protocol-level detail
158+
159+
The reference is a *cross-check*, not the starting point. Methodology steps 1-3 do the discovery.
160+
161+
## References
162+
163+
- `references/sandbox-setup.md` — the 3-step quickstart in detail (no partner creds)
164+
- `references/discovery-loop.md` — Inventory + Plan with one worked example
165+
- `references/translation-patterns.md` — HOW to translate a captured trace into Python/TS code; not a substitute for running traces yourself
166+
- `references/auth-bootstrap.md` — auth flows; PKCE in your own app is the default, three others cover specific cases
167+
- `references/oracle-workflow.md` — using `remotecli` as a contract test
168+
- `references/idempotency.md` — per-command safe-to-retry table
169+
- `references/common-errors.md` — HTTP 4xx catalogue → interpretation → debug command

0 commit comments

Comments
 (0)