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
110 changes: 90 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ Download the binary for your platform from the [Releases](https://github.com/loo

```bash
# Add a remote endpoint
graphql-cli add production --url https://api.example.com/graphql
graphql-cli endpoint add production --url https://api.example.com/graphql

# Add a local schema endpoint
graphql-cli add local --schema-file ./schema.graphql
graphql-cli endpoint add local --schema-file ./schema.graphql

# Execute a query
graphql-cli query -e production '{ users { id name } }'
Expand All @@ -32,27 +32,47 @@ graphql-cli find -e production user

## Commands

### `add` — Add a new endpoint
### `endpoint` — Manage endpoints

```bash
graphql-cli add <name> --url <url> [--schema-file <path>] [-d <description>] [--header key=value]
graphql-cli endpoint <subcommand>
```

Available subcommands:

- `add` — add a new endpoint
- `list` — list configured endpoints
- `update` — update an existing endpoint
- `login` — store credentials for an endpoint
- `logout` — remove stored credentials for an endpoint

### `endpoint add` — Add a new endpoint

```bash
graphql-cli endpoint add <name> --url <url> [--schema-file <path>] [-d <description>] [--header key=value]
```

**Examples:**

```bash
graphql-cli add production --url https://api.example.com/graphql --header "Authorization=Bearer token"
graphql-cli add local --schema-file ./schema.graphql --description "Local dev schema"
graphql-cli endpoint add production --url https://api.example.com/graphql --header "Authorization=Bearer token"
graphql-cli endpoint add local --schema-file ./schema.graphql --description "Local dev schema"
```

### `list` — List configured endpoints
### `endpoint list` — List configured endpoints

```bash
graphql-cli list [--detail]
graphql-cli endpoint list [--detail]
```

Use `--detail` to show headers, schema file paths, and auth status.

Example:

```bash
graphql-cli endpoint list --detail
```

### `query` — Execute a GraphQL query

```bash
Expand Down Expand Up @@ -81,18 +101,18 @@ graphql-cli mutate -e production 'mutation { createUser(name: "test") { id } }'
graphql-cli mutate -e production -f mutation.graphql -v '{"name": "test"}'
```

### `update` — Update an existing endpoint
### `endpoint update` — Update an existing endpoint

```bash
graphql-cli update <name> [--url <url>] [-d <description>] [--header key=value]
graphql-cli endpoint update <name> [--url <url>] [-d <description>] [--header key=value]
```

**Examples:**

```bash
graphql-cli update production --url https://api.example.com/v2/graphql
graphql-cli update production --header "Authorization=Bearer new-token"
graphql-cli update production --url https://new-url.com/graphql --header "X-Custom=value" -d "Updated endpoint"
graphql-cli endpoint update production --url https://api.example.com/v2/graphql
graphql-cli endpoint update production --header "Authorization=Bearer new-token"
graphql-cli endpoint update production --url https://new-url.com/graphql --header "X-Custom=value" -d "Updated endpoint"
```

### `find` — Search schema definitions
Expand All @@ -116,12 +136,12 @@ graphql-cli find -e production status --enum
graphql-cli find -e production user --detail
```

### `login` — Authenticate with an endpoint
### `endpoint login` — Authenticate with an endpoint

Credentials are stored in the OS keyring (macOS Keychain, Windows Credential Manager, GNOME Keyring) with a plaintext file fallback.

```bash
graphql-cli login [endpoint] [-e <endpoint>] [--type token|basic|header]
graphql-cli endpoint login <endpoint> [--type token|basic|header]
```

**Supported auth types:**
Expand All @@ -135,26 +155,76 @@ graphql-cli login [endpoint] [-e <endpoint>] [--type token|basic|header]
**Examples:**

```bash
graphql-cli login production
graphql-cli login production --type token --token "my-token"
graphql-cli endpoint login production
graphql-cli endpoint login production --type token --token "my-token"
```

### `endpoint logout` — Remove stored credentials

```bash
graphql-cli endpoint logout <endpoint>
```

### `logout` — Remove stored credentials
### `audit list` — List recorded queries and mutations

```bash
graphql-cli logout [endpoint] [-e <endpoint>]
graphql-cli audit list [--endpoint <name>] [--status success|error] [--contains <text>] [--query|--mutation] [--detail] [--limit <n>]
```

Examples:

```bash
graphql-cli audit list
graphql-cli audit list --endpoint production
graphql-cli audit list --status error
graphql-cli audit list --contains createUser
graphql-cli audit list --mutation --detail
```

## Configuration

The configuration file is stored at `~/.config/graphql-cli/config.yaml` by default. Use `--config` to specify a custom path.

## Audit Log

Executed GraphQL statements are appended to `~/.config/graphql-cli/audit.log` as JSON lines.

Each line records:

- `timestamp`
- `endpoint`
- `url`
- `status`
- `statement`
- `error` when execution fails

Example entry:

```json
{"timestamp":"2026-03-29T08:15:30.123456Z","endpoint":"production","url":"https://api.example.com/graphql","status":"success","statement":"query { viewer { id } }"}
```

You can inspect recorded operations with:

```bash
graphql-cli audit list
graphql-cli audit list --query
graphql-cli audit list --status error
graphql-cli audit list --contains viewer
graphql-cli audit list --mutation --detail
```

Or stream the raw log with:

```bash
tail -f ~/.config/graphql-cli/audit.log
```

## Global Flags

| Flag | Description |
|-----------------------|--------------------------------------|
| `--config <path>` | Config file path |
| `-e, --endpoint <name>` | Endpoint name to use |

## License

Expand Down
53 changes: 38 additions & 15 deletions SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,55 +37,57 @@ go install github.com/looplj/graphql-cli@latest

## Workflows

Endpoint management commands live under `graphql-cli endpoint ...`.

### 1. Add an endpoint

**Remote URL:**
```bash
graphql-cli add <name> --url <graphql-url> [--description "desc"] [--header "Key=Value"]
graphql-cli endpoint add <name> --url <graphql-url> [--description "desc"] [--header "Key=Value"]
```

**Local schema file:**
```bash
graphql-cli add <name> --schema-file ./schema.graphql [--description "desc"]
graphql-cli endpoint add <name> --schema-file ./schema.graphql [--description "desc"]
```

Example:
```bash
graphql-cli add production --url https://api.example.com/graphql --description "Prod API"
graphql-cli add local --schema-file ./testdata/schema.graphql --description "Local schema"
graphql-cli endpoint add production --url https://api.example.com/graphql --description "Prod API"
graphql-cli endpoint add local --schema-file ./testdata/schema.graphql --description "Local schema"
```

### 2. Update an endpoint

```bash
graphql-cli update <name> --url <new-url> [--description "desc"] [--header "Key=Value"]
graphql-cli endpoint update <name> --url <new-url> [--description "desc"] [--header "Key=Value"]
```

Example:
```bash
graphql-cli update production --url https://api.example.com/v2/graphql
graphql-cli update production --header "Authorization=Bearer new-token" -d "Updated prod API"
graphql-cli endpoint update production --url https://api.example.com/v2/graphql
graphql-cli endpoint update production --header "Authorization=Bearer new-token" -d "Updated prod API"
```

Headers are merged — existing headers not specified in the update are preserved.

### 3. List endpoints

```bash
graphql-cli list # names and URLs
graphql-cli list --detail # includes headers (masked) and auth status
graphql-cli endpoint list # names and URLs
graphql-cli endpoint list --detail # includes headers (masked) and auth status
```

### 4. Authenticate

```bash
graphql-cli login <endpoint> --type token --token "my-api-key"
graphql-cli login <endpoint> --type basic --user admin --pass secret
graphql-cli login <endpoint> --type header --key X-API-Key --value "key123"
graphql-cli login -e production --type token --token "my-token"
graphql-cli endpoint login <endpoint> --type token --token "my-api-key"
graphql-cli endpoint login <endpoint> --type basic --user admin --pass secret
graphql-cli endpoint login <endpoint> --type header --key X-API-Key --value "key123"
graphql-cli endpoint login -e production --type token --token "my-token"

# Remove credentials
graphql-cli logout <endpoint>
graphql-cli endpoint logout <endpoint>
```

Credentials are stored in the OS keyring (macOS Keychain, Windows Credential Manager, GNOME Keyring) with a plaintext file fallback.
Expand Down Expand Up @@ -145,6 +147,27 @@ When executing queries/mutations, headers are merged with this priority (highest
2. Stored credentials (`login`)
3. Config file headers

Each executed GraphQL statement is also appended to `~/.config/graphql-cli/audit.log` as a JSON line containing timestamp, endpoint, status, and the statement text.

Example:

```json
{"timestamp":"2026-03-29T08:15:30.123456Z","endpoint":"production","url":"https://api.example.com/graphql","status":"success","statement":"query { viewer { id } }"}
```

To inspect the log stream locally:

```bash
graphql-cli audit list
graphql-cli audit list --query
graphql-cli audit list --status error
graphql-cli audit list --contains createUser
graphql-cli audit list --mutation --detail

# Or stream the raw log file
tail -f ~/.config/graphql-cli/audit.log
```

## Common patterns

### Query with variables from a file
Expand Down Expand Up @@ -174,4 +197,4 @@ graphql-cli mutate 'mutation { createUser(input: {name: "Alice", email: "alice@e

## Guidelines

- **Always use `find` without `--detail` first** to get an overview of matching names, then use `find --detail` on specific results to see full definitions with fields and arguments. This avoids overwhelming output when schemas are large.
- **Always use `find` without `--detail` first** to get an overview of matching names, then use `find --detail` on specific results to see full definitions with fields and arguments. This avoids overwhelming output when schemas are large.
39 changes: 22 additions & 17 deletions cmd/add.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,6 @@ import (
"github.com/looplj/graphql-cli/internal/config"
)

var addCmd = &cobra.Command{
Use: "add <name>",
Short: "Add a new endpoint to the configuration",
Long: `Add a new GraphQL endpoint. Specify either a remote URL or a local schema file.

Examples:
graphql-cli add production --url https://api.example.com/graphql --header "Authorization=Bearer token"
graphql-cli add local --schema-file ./schema.graphql --description "Local dev schema"`,
Args: cobra.ExactArgs(1),
RunE: runAdd,
}

var (
addURL string
addSchemaFile string
Expand All @@ -29,11 +17,28 @@ var (
)

func init() {
addCmd.Flags().StringVar(&addURL, "url", "", "GraphQL endpoint URL")
addCmd.Flags().StringVar(&addSchemaFile, "schema-file", "", "path to local GraphQL schema file")
addCmd.Flags().StringVarP(&addDescription, "description", "d", "", "endpoint description")
addCmd.Flags().StringSliceVar(&addHeaders, "header", nil, "HTTP headers (key=value), can be specified multiple times")
rootCmd.AddCommand(addCmd)
endpointCmd.AddCommand(newAddCmd())
}

func newAddCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "add <name>",
Short: "Add a new endpoint to the configuration",
Long: `Add a new GraphQL endpoint. Specify either a remote URL or a local schema file.

Examples:
graphql-cli endpoint add production --url https://api.example.com/graphql --header "Authorization=Bearer token"
graphql-cli endpoint add local --schema-file ./schema.graphql --description "Local dev schema"`,
Args: cobra.ExactArgs(1),
RunE: runAdd,
}

cmd.Flags().StringVar(&addURL, "url", "", "GraphQL endpoint URL")
cmd.Flags().StringVar(&addSchemaFile, "schema-file", "", "path to local GraphQL schema file")
cmd.Flags().StringVarP(&addDescription, "description", "d", "", "endpoint description")
cmd.Flags().StringSliceVar(&addHeaders, "header", nil, "HTTP headers (key=value), can be specified multiple times")

return cmd
}

func runAdd(cmd *cobra.Command, args []string) error {
Expand Down
Loading
Loading