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
2 changes: 1 addition & 1 deletion plugins/axi/.agents/skills/axi/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ help[2]:

- **Claude Code**: use native hooks in `~/.claude/settings.json` or project `.claude/settings.json`. Prefer `SessionStart` to inject compact context via stdout
- **Codex**: use native hooks in `~/.codex/hooks.json` or `<repo>/.codex/hooks.json`, and ensure `[features].hooks = true` in `config.toml`. Prefer `SessionStart` for ambient context via stdout
- **OpenCode**: use a managed plugin in `~/.config/opencode/plugins/`. Prefer ambient system-context injection for the home view rather than adding a custom tool
- **OpenCode**: use a managed plugin in `~/.config/opencode/plugins/` or `<repo>/.opencode/plugins/`. Prefer ambient system-context injection for the home view rather than adding a custom tool

**Also ship an installable skill (secondary recommendation):**

Expand Down
2 changes: 1 addition & 1 deletion plugins/axi/agent/skills/axi/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ help[2]:

- **Claude Code**: use native hooks in `~/.claude/settings.json` or project `.claude/settings.json`. Prefer `SessionStart` to inject compact context via stdout
- **Codex**: use native hooks in `~/.codex/hooks.json` or `<repo>/.codex/hooks.json`, and ensure `[features].hooks = true` in `config.toml`. Prefer `SessionStart` for ambient context via stdout
- **OpenCode**: use a managed plugin in `~/.config/opencode/plugins/`. Prefer ambient system-context injection for the home view rather than adding a custom tool
- **OpenCode**: use a managed plugin in `~/.config/opencode/plugins/` or `<repo>/.opencode/plugins/`. Prefer ambient system-context injection for the home view rather than adding a custom tool

**Also ship an installable skill (secondary recommendation):**

Expand Down
2 changes: 1 addition & 1 deletion plugins/axi/skills-lock.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"source": "kunchenguid/axi",
"sourceType": "github",
"skillPath": ".agents/skills/axi/SKILL.md",
"computedHash": "7de23a6b8171a06b7885712f3dd971e64d9301543d1b8c46f21660494303df95"
"computedHash": "b4294fa06402d65a8fce0528bd4bca9286d19fbcd9882717d0ebe8821c24a563"
}
}
}
6 changes: 6 additions & 0 deletions plugins/emulate/.agents/skills/emulate/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ npx emulate --port 3000
# Use a seed config file
npx emulate --seed config.yaml

# Generate omitted service secrets into a private file
npx emulate start --seed config.yaml --generated-secrets-file .emulate-secrets.json

# Generate a starter config
npx emulate init

Expand All @@ -67,9 +70,12 @@ npx emulate list
| `--seed` | auto-detect | Path to seed config (YAML or JSON) |
| `--base-url` | none | Override advertised base URL (supports `{service}` template) |
| `--portless` | off | Serve over HTTPS via portless (auto-registers aliases) |
| `--generated-secrets-file` | none | Generate omitted service secrets and write them to a new owner-only JSON file |

The port can also be set via `EMULATE_PORT` or `PORT` environment variables.

The generated-secrets destination must not exist. emulate removes inherited ACLs, verifies effective owner-only access, and publishes complete JSON before opening listeners or configuring portless. Handled startup failures remove the invocation-owned artifact. A hard termination can leave a complete artifact that must be removed manually after confirming no invocation is using it. Only service-generated values appear in the artifact. Linux requires `setfacl` and `getfacl` from the `acl` package. The flag fails closed when access controls cannot be verified and is not supported on Windows.

The advertised base URL (used in OAuth redirects, webhook URLs, etc.) can be overridden via `--base-url`, the `EMULATE_BASE_URL` env var (supports `{service}` template), or per-service `baseUrl` in the seed config. When running under portless, the `PORTLESS_URL` env var is also detected automatically.

## Programmatic API
Expand Down
59 changes: 59 additions & 0 deletions plugins/emulate/.agents/skills/github/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,41 @@ const github = await createEmulator({ service: 'github', port: 4001 })
// github.url === 'http://localhost:4001'
```

For a programmatic GitHub App, omit `private_key` and read the generated RSA key from the instance:

```typescript
const github = await createEmulator({
service: 'github',
port: 4001,
seed: {
github: {
users: [{ login: 'octocat' }],
apps: [{
app_id: 12345,
slug: 'my-github-app',
name: 'My GitHub App',
installations: [{ installation_id: 100, account: 'octocat' }],
}],
},
},
})

const privateKey = github.generatedSecrets.find(
secret => secret.kind === 'github.app_private_key' && secret.id === '12345',
)?.value
```

The key remains stable across `github.reset()`. Explicit keys are not included in `generatedSecrets`.

For the CLI, omit `private_key` only when requesting a private delivery file:

```bash
npx emulate start --service github --seed emulate.config.yaml \
--generated-secrets-file .emulate-secrets.json
```

The destination must not exist. emulate removes inherited ACLs, verifies effective owner-only access, and publishes complete JSON before any listener or portless alias starts. Handled startup failures remove the invocation-owned artifact. A hard termination can leave a complete artifact that must be removed manually after confirming no invocation is using it. Read `generatedSecrets` from the artifact, then keep the file out of source control. Linux requires `setfacl` and `getfacl` from the `acl` package. The flag fails closed when access controls cannot be verified and is not supported on Windows. Without `--generated-secrets-file`, CLI seed files still require `private_key`.

## Auth

Pass tokens as `Authorization: Bearer <token>` or `Authorization: token <token>`.
Expand Down Expand Up @@ -210,6 +245,9 @@ curl http://localhost:4001/user/emails -H "Authorization: Bearer $TOKEN"
# Get repo
curl http://localhost:4001/repos/octocat/hello-world

# Get repo by numeric ID
curl http://localhost:4001/repositories/1

# Create user repo
curl -X POST http://localhost:4001/user/repos \
-H "Authorization: Bearer $TOKEN" \
Expand All @@ -235,6 +273,27 @@ curl -X DELETE http://localhost:4001/repos/octocat/hello-world \
# Topics, languages, contributors, forks, collaborators, tags, transfer
```

### Contents & Commit History

```bash
# Read a file or list a directory at a branch, tag, or commit
curl "http://localhost:4001/repos/octocat/hello-world/contents/README.md?ref=main"

# Download raw file content from the URL advertised by contents and commit responses
curl http://localhost:4001/octocat/hello-world/raw/main/README.md

# Create or update a file and commit the change
curl -X PUT http://localhost:4001/repos/octocat/hello-world/contents/notes.txt \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"message": "Update notes", "content": "aGVsbG8K"}'

# List commits, get a commit with file stats, or compare refs
curl http://localhost:4001/repos/octocat/hello-world/commits
curl http://localhost:4001/repos/octocat/hello-world/commits/main
curl http://localhost:4001/repos/octocat/hello-world/compare/v1.0.0...main
```

### Issues

```bash
Expand Down
1 change: 1 addition & 0 deletions plugins/emulate/.agents/skills/stripe/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,7 @@ curl http://localhost:4000/v1/payment_methods
## Webhooks

The emulator dispatches webhook events when state changes. Register webhooks via seed config or programmatically.
Webhooks configured with a `secret` include `Stripe-Signature: t=<timestamp>,v1=<signature>`. The signature is an HMAC SHA-256 over `<timestamp>.<raw body>`.

### Events dispatched

Expand Down
6 changes: 6 additions & 0 deletions plugins/emulate/agent/skills/emulate/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ npx emulate --port 3000
# Use a seed config file
npx emulate --seed config.yaml

# Generate omitted service secrets into a private file
npx emulate start --seed config.yaml --generated-secrets-file .emulate-secrets.json

# Generate a starter config
npx emulate init

Expand All @@ -64,9 +67,12 @@ npx emulate list
| `--seed` | auto-detect | Path to seed config (YAML or JSON) |
| `--base-url` | none | Override advertised base URL (supports `{service}` template) |
| `--portless` | off | Serve over HTTPS via portless (auto-registers aliases) |
| `--generated-secrets-file` | none | Generate omitted service secrets and write them to a new owner-only JSON file |

The port can also be set via `EMULATE_PORT` or `PORT` environment variables.

The generated-secrets destination must not exist. emulate removes inherited ACLs, verifies effective owner-only access, and publishes complete JSON before opening listeners or configuring portless. Handled startup failures remove the invocation-owned artifact. A hard termination can leave a complete artifact that must be removed manually after confirming no invocation is using it. Only service-generated values appear in the artifact. Linux requires `setfacl` and `getfacl` from the `acl` package. The flag fails closed when access controls cannot be verified and is not supported on Windows.

The advertised base URL (used in OAuth redirects, webhook URLs, etc.) can be overridden via `--base-url`, the `EMULATE_BASE_URL` env var (supports `{service}` template), or per-service `baseUrl` in the seed config. When running under portless, the `PORTLESS_URL` env var is also detected automatically.

## Programmatic API
Expand Down
59 changes: 59 additions & 0 deletions plugins/emulate/agent/skills/github/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,41 @@ const github = await createEmulator({ service: 'github', port: 4001 })
// github.url === 'http://localhost:4001'
```

For a programmatic GitHub App, omit `private_key` and read the generated RSA key from the instance:

```typescript
const github = await createEmulator({
service: 'github',
port: 4001,
seed: {
github: {
users: [{ login: 'octocat' }],
apps: [{
app_id: 12345,
slug: 'my-github-app',
name: 'My GitHub App',
installations: [{ installation_id: 100, account: 'octocat' }],
}],
},
},
})

const privateKey = github.generatedSecrets.find(
secret => secret.kind === 'github.app_private_key' && secret.id === '12345',
)?.value
```

The key remains stable across `github.reset()`. Explicit keys are not included in `generatedSecrets`.

For the CLI, omit `private_key` only when requesting a private delivery file:

```bash
npx emulate start --service github --seed emulate.config.yaml \
--generated-secrets-file .emulate-secrets.json
```

The destination must not exist. emulate removes inherited ACLs, verifies effective owner-only access, and publishes complete JSON before any listener or portless alias starts. Handled startup failures remove the invocation-owned artifact. A hard termination can leave a complete artifact that must be removed manually after confirming no invocation is using it. Read `generatedSecrets` from the artifact, then keep the file out of source control. Linux requires `setfacl` and `getfacl` from the `acl` package. The flag fails closed when access controls cannot be verified and is not supported on Windows. Without `--generated-secrets-file`, CLI seed files still require `private_key`.

## Auth

Pass tokens as `Authorization: Bearer <token>` or `Authorization: token <token>`.
Expand Down Expand Up @@ -207,6 +242,9 @@ curl http://localhost:4001/user/emails -H "Authorization: Bearer $TOKEN"
# Get repo
curl http://localhost:4001/repos/octocat/hello-world

# Get repo by numeric ID
curl http://localhost:4001/repositories/1

# Create user repo
curl -X POST http://localhost:4001/user/repos \
-H "Authorization: Bearer $TOKEN" \
Expand All @@ -232,6 +270,27 @@ curl -X DELETE http://localhost:4001/repos/octocat/hello-world \
# Topics, languages, contributors, forks, collaborators, tags, transfer
```

### Contents & Commit History

```bash
# Read a file or list a directory at a branch, tag, or commit
curl "http://localhost:4001/repos/octocat/hello-world/contents/README.md?ref=main"

# Download raw file content from the URL advertised by contents and commit responses
curl http://localhost:4001/octocat/hello-world/raw/main/README.md

# Create or update a file and commit the change
curl -X PUT http://localhost:4001/repos/octocat/hello-world/contents/notes.txt \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"message": "Update notes", "content": "aGVsbG8K"}'

# List commits, get a commit with file stats, or compare refs
curl http://localhost:4001/repos/octocat/hello-world/commits
curl http://localhost:4001/repos/octocat/hello-world/commits/main
curl http://localhost:4001/repos/octocat/hello-world/compare/v1.0.0...main
```

### Issues

```bash
Expand Down
1 change: 1 addition & 0 deletions plugins/emulate/agent/skills/stripe/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,7 @@ curl http://localhost:4000/v1/payment_methods
## Webhooks

The emulator dispatches webhook events when state changes. Register webhooks via seed config or programmatically.
Webhooks configured with a `secret` include `Stripe-Signature: t=<timestamp>,v1=<signature>`. The signature is an HMAC SHA-256 over `<timestamp>.<raw body>`.

### Events dispatched

Expand Down
6 changes: 3 additions & 3 deletions plugins/emulate/skills-lock.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,13 @@
"source": "vercel-labs/emulate",
"sourceType": "github",
"skillPath": "skills/emulate/SKILL.md",
"computedHash": "a37ed153c79c6fe337535a1055d08644070186160c5f14c4ad990c1a16537512"
"computedHash": "9f490bb96968516335972dc0df78fcd7b75025aab169a6bea24c2f9f4e63987e"
},
"github": {
"source": "vercel-labs/emulate",
"sourceType": "github",
"skillPath": "skills/github/SKILL.md",
"computedHash": "9f35addc8b40f7e75804f07ec140044ab32cf00f9b4ef536d2d9c2e1a5b24a3c"
"computedHash": "ae3920ffad035acdd71b0764015bc9401223197788092efb0be6a5edb7210fa6"
},
"google": {
"source": "vercel-labs/emulate",
Expand Down Expand Up @@ -65,7 +65,7 @@
"source": "vercel-labs/emulate",
"sourceType": "github",
"skillPath": "skills/stripe/SKILL.md",
"computedHash": "406885aaa09f57d0a326d6af005e8cd432ea69d9fbbf07de5bda251cb92d8cd1"
"computedHash": "d2e822c16e3e7698b719e9dd06e21ed1019cc37a62e29c1b51718da838ee106d"
},
"vercel": {
"source": "vercel-labs/emulate",
Expand Down
Loading
Loading