@housein_isprogramming/arnold-curls
v2.2.0
Published
GraphQL API flow runner with multi-set support - execute flows step-by-step with context passing
Maintainers
Readme
arnold-curls
GraphQL API flow runner with multi-set support. Execute flows step-by-step with context passing and response validation.
Installation
CLI (npm package)
npm install -D @housein_isprogramming/arnold-curlsThen use via npx:
npx arnold init my-api
npx arnold run my-api
npx arnold status my-apiClaude Code Plugin
After installing the npm package, install the Claude Code plugin:
claude /plugin install node_modules/@housein_isprogramming/arnold-curlsThen use the @arnold agent in Claude:
@arnold create a flow to test user registration and login
@arnold run my-api --fullOr use the slash commands:
/arnold-list
/arnold-status my-api
/arnold-run my-api --fullQuick Start
# Initialize a set
npx arnold init my-api
# Edit .arnold/sets/my-api.json with your steps
# Run steps one by one
npx arnold run my-api
# Or run all at once
npx arnold run my-api --full
# Check status
npx arnold status my-apiCommands
npx arnold init <name> # Create empty set
npx arnold init <name> --from <f> # Create from existing JSON file
npx arnold init <name> --stdin # Create from stdin
npx arnold run <name> # Run next pending step
npx arnold run <name> --full # Run ALL steps, stop on first error
npx arnold run <name> --step <N> # Run specific step (0-indexed)
npx arnold preview <name> # Preview next step (resolved variables)
npx arnold preview <name> --step <N> # Preview specific step
npx arnold status <name> # Show set status
npx arnold list # List all sets
npx arnold reset <name> # Clear execution state for set
npx arnold reset --all # Clear ALL execution stateFile Structure
.arnold/
├── sets/
│ ├── auth-flow.json # Set definition (committed)
│ └── user-crud.json # Set definition (committed)
├── state.json # Execution state (gitignored)
└── .env # Secrets (gitignored)Set Definition
.arnold/sets/<name>.json:
{
"name": "auth-flow",
"baseUrl": "https://api.example.com/graphql",
"headers": {
"Authorization": "Bearer ${token}"
},
"steps": [
{
"name": "Login",
"query": "mutation { login(user: \"admin\", pass: \"secret\") { token success } }",
"extractToContext": { "token": "data.login.token" },
"expected": { "data": { "login": { "success": true } } }
},
{
"name": "Get Profile",
"query": "query { me { id name } }"
}
]
}Step Fields
| Field | Description |
|-------|-------------|
| name | Step display name |
| query | GraphQL query/mutation |
| variables | Optional query variables |
| extractToContext | Extract values to context for later steps |
| expected | Validate response (subset match) |
Context Variables
Use ${varName} in queries, variables, or headers:
{
"headers": { "Authorization": "Bearer ${token}" },
"steps": [
{
"name": "Login",
"query": "mutation { login { token } }",
"extractToContext": { "token": "data.login.token" }
},
{
"name": "Protected Query",
"query": "query { secretData { value } }"
}
]
}Environment Variables
Create .arnold/.env for secrets:
API_KEY=your-api-key
AUTH_TOKEN=bearer-token
# Comments supported.envvalues override context values- Add to
.gitignore(contains secrets)
Output Format (JSON)
run (single step)
{
"step": "Login",
"index": 0,
"status": "done",
"duration": 234,
"result": { "data": { "login": { "token": "abc" } } },
"context": { "token": "abc" },
"remaining": 1
}run --full (success)
{
"set": "auth-flow",
"status": "done",
"steps": [...],
"duration": 567
}run --full (error)
{
"set": "auth-flow",
"status": "error",
"stoppedAt": 1,
"error": "connection refused",
"completedSteps": [...]
}status
{
"name": "auth-flow",
"baseUrl": "...",
"pending": 2,
"done": 1,
"failed": 0,
"errors": 0,
"steps": [...]
}list
{
"sets": [
{ "name": "auth-flow", "pending": 2, "done": 1, "failed": 0, "errors": 0 }
]
}Response Validation
Add expected for subset matching:
{
"name": "Login",
"query": "mutation { login { success } }",
"expected": { "data": { "login": { "success": true } } }
}- Response must contain expected values (extra fields OK)
- On mismatch: status becomes
failedwithvalidationError - Context extraction still runs (data exists)
Testing
bun testLicense
MIT
