@pleaseai/agent 0.1.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +112 -0
- package/README.md +738 -0
- package/dist/index.js +28403 -0
- package/package.json +57 -0
package/README.md
ADDED
|
@@ -0,0 +1,738 @@
|
|
|
1
|
+
# Agent Please
|
|
2
|
+
|
|
3
|
+
English | [한국어](README.ko.md) | [日本語](README.ja.md) | [简体中文](README.zh-CN.md)
|
|
4
|
+
|
|
5
|
+
[](https://sonarcloud.io/summary/new_code?id=pleaseai_agent-please) [](https://sonarcloud.io/summary/new_code?id=pleaseai_agent-please) [](https://sonarcloud.io/summary/new_code?id=pleaseai_agent-please) [](https://sonarcloud.io/summary/new_code?id=pleaseai_agent-please)
|
|
6
|
+
[](https://codecov.io/gh/pleaseai/agent-please)
|
|
7
|
+
|
|
8
|
+
Agent Please turns issue tracker tasks into isolated, autonomous implementation runs — managing work
|
|
9
|
+
instead of supervising coding agents.
|
|
10
|
+
|
|
11
|
+
> **Warning**: Agent Please is an engineering preview for use in trusted environments.
|
|
12
|
+
|
|
13
|
+
## Table of Contents
|
|
14
|
+
|
|
15
|
+
- [Overview](#overview)
|
|
16
|
+
- [Key Differences from Symphony](#key-differences-from-symphony)
|
|
17
|
+
- [Features](#features)
|
|
18
|
+
- [Architecture](#architecture)
|
|
19
|
+
- [Quick Start](#quick-start)
|
|
20
|
+
- [Prerequisites](#prerequisites)
|
|
21
|
+
- [Install](#install)
|
|
22
|
+
- [Configure](#configure)
|
|
23
|
+
- [Run](#run)
|
|
24
|
+
- [WORKFLOW.md Configuration](#workflowmd-configuration)
|
|
25
|
+
- [Full Front Matter Schema](#full-front-matter-schema)
|
|
26
|
+
- [Template Variables](#template-variables)
|
|
27
|
+
- [CLI Usage](#cli-usage)
|
|
28
|
+
- [GitHub App Authentication](#github-app-authentication)
|
|
29
|
+
- [Setting up GitHub App credentials](#setting-up-github-app-credentials)
|
|
30
|
+
- [Validation](#validation)
|
|
31
|
+
- [Slack Notifications](#slack-notifications)
|
|
32
|
+
- [Slack App Setup](#slack-app-setup)
|
|
33
|
+
- [Trust and Safety](#trust-and-safety)
|
|
34
|
+
- [Permission Modes](#permission-modes)
|
|
35
|
+
- [Workspace Isolation](#workspace-isolation)
|
|
36
|
+
- [Recommendations](#recommendations)
|
|
37
|
+
- [License](#license)
|
|
38
|
+
|
|
39
|
+
## Overview
|
|
40
|
+
|
|
41
|
+
Agent Please is a long-running TypeScript service that:
|
|
42
|
+
|
|
43
|
+
1. Polls an issue tracker (GitHub Projects v2 or Asana) for tasks in configured active states.
|
|
44
|
+
2. Creates an isolated workspace directory for each eligible issue.
|
|
45
|
+
3. Launches a Claude Code agent session inside that workspace with a rendered prompt.
|
|
46
|
+
4. Monitors the session, handles retries, and reconciles issue state on each poll cycle.
|
|
47
|
+
|
|
48
|
+
It is a TypeScript implementation of the [Symphony specification](vendor/symphony/SPEC.md),
|
|
49
|
+
adapted for GitHub Projects v2 / Asana and Claude Code instead of Linear and Codex.
|
|
50
|
+
|
|
51
|
+
For full technical details, see [SPEC.md](SPEC.md).
|
|
52
|
+
|
|
53
|
+
## Key Differences from Symphony
|
|
54
|
+
|
|
55
|
+
| | Symphony (reference) | Agent Please |
|
|
56
|
+
|---|---|---|
|
|
57
|
+
| Issue Tracker | Linear | GitHub Projects v2 & Asana (under development) |
|
|
58
|
+
| Coding Agent | Codex (app-server mode) | Claude Code CLI |
|
|
59
|
+
| Language | Elixir/OTP | TypeScript + Bun |
|
|
60
|
+
| Tracker Auth | `LINEAR_API_KEY` | `GITHUB_TOKEN`, GitHub App credentials, or `ASANA_ACCESS_TOKEN` |
|
|
61
|
+
| Project Config | `project_slug` | `owner` + `project_number` (GitHub Projects v2) or `project_gid` (Asana) |
|
|
62
|
+
| Issue States | Linear workflow states | GitHub Projects v2 Status field / Asana sections |
|
|
63
|
+
| Agent Protocol | JSON-RPC over stdio | `@anthropic-ai/claude-agent-sdk` |
|
|
64
|
+
| Permission Model | Codex approval/sandbox policies | Claude Code `--permission-mode` |
|
|
65
|
+
|
|
66
|
+
## Features
|
|
67
|
+
|
|
68
|
+
- **Multi-tracker support** — Dispatch work from GitHub Projects v2 items or Asana tasks (under development) on a
|
|
69
|
+
fixed cadence.
|
|
70
|
+
- **GitHub App authentication** — Authenticate the GitHub tracker with a GitHub App installation
|
|
71
|
+
token (`app_id` + `private_key` + `installation_id`) instead of a PAT, for fine-grained
|
|
72
|
+
permissions and higher API rate limits.
|
|
73
|
+
- **Assignee & label filters** — Filter eligible issues by assignee and/or label. Multiple values
|
|
74
|
+
within each filter use OR logic; assignee and label filters are ANDed when both are specified.
|
|
75
|
+
Applies at dispatch time only — already-running issues are unaffected. Configured per-tracker
|
|
76
|
+
in `WORKFLOW.md`.
|
|
77
|
+
- **Isolated workspaces** — Each issue gets a dedicated directory; workspaces persist across runs.
|
|
78
|
+
- **`WORKFLOW.md` config** — Version agent prompt and runtime settings alongside your code.
|
|
79
|
+
- **Bounded concurrency** — Global and per-state concurrent agent limits.
|
|
80
|
+
- **Retry with backoff** — Exponential backoff on failures; short continuation retry on clean exit.
|
|
81
|
+
- **Dynamic config reload** — Edit `WORKFLOW.md` and changes apply without restarting the service.
|
|
82
|
+
- **Workspace hooks** — Shell scripts run at `after_create`, `before_run`, `after_run`, and
|
|
83
|
+
`before_remove` lifecycle events.
|
|
84
|
+
- **Structured logging** — Operator-visible logs with stable `key=value` format.
|
|
85
|
+
- **Slack notifications** — @mention the bot in Slack to get orchestrator status. Uses
|
|
86
|
+
[Chat SDK](https://chat-sdk.dev/) Slack adapter.
|
|
87
|
+
- **Optional HTTP dashboard** — Enable with `--port` for runtime status and JSON API.
|
|
88
|
+
|
|
89
|
+
## Architecture
|
|
90
|
+
|
|
91
|
+
```
|
|
92
|
+
WORKFLOW.md
|
|
93
|
+
|
|
|
94
|
+
v
|
|
95
|
+
Config Layer ──> Orchestrator ──> Workspace Manager ──> Agent Runner (Claude Code)
|
|
96
|
+
| |
|
|
97
|
+
v v
|
|
98
|
+
Issue Tracker Client Isolated workspace/
|
|
99
|
+
(GitHub GraphQL API or per-issue directory
|
|
100
|
+
Asana REST API,
|
|
101
|
+
polling + reconciliation)
|
|
102
|
+
|
|
|
103
|
+
v
|
|
104
|
+
Status Surface (optional HTTP dashboard / structured logs)
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
Components:
|
|
108
|
+
|
|
109
|
+
- **Workflow Loader** — Parses `WORKFLOW.md` YAML front matter and prompt template body.
|
|
110
|
+
- **Config Layer** — Typed getters with env-var indirection and built-in defaults.
|
|
111
|
+
- **Issue Tracker Client** — Fetches candidate issues, reconciles running-issue states. Supports
|
|
112
|
+
GitHub Projects v2 (GraphQL API) and Asana (REST API) adapters.
|
|
113
|
+
- **Orchestrator** — Owns in-memory state; drives the poll/dispatch/retry loop.
|
|
114
|
+
- **Workspace Manager** — Creates, reuses, and cleans per-issue workspaces; runs hooks.
|
|
115
|
+
- **Agent Runner** — Launches Claude Code, streams events back to the orchestrator.
|
|
116
|
+
- **Status Surface** — Optional terminal view and HTTP API for operator visibility.
|
|
117
|
+
|
|
118
|
+
See [SPEC.md](SPEC.md) for the full specification.
|
|
119
|
+
|
|
120
|
+
## Quick Start
|
|
121
|
+
|
|
122
|
+
### Prerequisites
|
|
123
|
+
|
|
124
|
+
- **Bun** (see [bun.sh](https://bun.sh) for installation)
|
|
125
|
+
- **Claude Code CLI** (see the [official installation guide](https://docs.anthropic.com/en/docs/claude-code))
|
|
126
|
+
- **GitHub token** (`GITHUB_TOKEN`) with access to the target project, **or** **GitHub App credentials**
|
|
127
|
+
(`GITHUB_APP_ID`, `GITHUB_APP_PRIVATE_KEY`, `GITHUB_APP_INSTALLATION_ID`) — see [GitHub App Authentication](#github-app-authentication),
|
|
128
|
+
**or** **Asana access token** (`ASANA_ACCESS_TOKEN`) (under development)
|
|
129
|
+
|
|
130
|
+
### Install
|
|
131
|
+
|
|
132
|
+
```bash
|
|
133
|
+
git clone https://github.com/pleaseai/agent-please.git
|
|
134
|
+
cd agent-please
|
|
135
|
+
bun install
|
|
136
|
+
bun run build
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
### Configure
|
|
140
|
+
|
|
141
|
+
Create a `WORKFLOW.md` in your target repository. Two examples are shown below.
|
|
142
|
+
See also the [example WORKFLOW.md](https://github.com/pleaseai/workflow/blob/main/WORKFLOW.md) for a real-world reference.
|
|
143
|
+
|
|
144
|
+
#### GitHub Projects v2 (PAT)
|
|
145
|
+
|
|
146
|
+
See also the [example GitHub Project](https://github.com/orgs/pleaseai/projects/2) for a real-world reference.
|
|
147
|
+
|
|
148
|
+
```markdown
|
|
149
|
+
---
|
|
150
|
+
tracker:
|
|
151
|
+
kind: github_projects
|
|
152
|
+
api_key: $GITHUB_TOKEN
|
|
153
|
+
owner: your-org
|
|
154
|
+
project_number: 42
|
|
155
|
+
active_statuses:
|
|
156
|
+
- Todo
|
|
157
|
+
- In Progress
|
|
158
|
+
- Merging
|
|
159
|
+
- Rework
|
|
160
|
+
terminal_statuses:
|
|
161
|
+
- Closed
|
|
162
|
+
- Cancelled
|
|
163
|
+
- Canceled
|
|
164
|
+
- Duplicate
|
|
165
|
+
- Done
|
|
166
|
+
watched_statuses:
|
|
167
|
+
- Human Review
|
|
168
|
+
|
|
169
|
+
polling:
|
|
170
|
+
interval_ms: 30000
|
|
171
|
+
|
|
172
|
+
workspace:
|
|
173
|
+
root: ~/agent-please_workspaces
|
|
174
|
+
|
|
175
|
+
hooks:
|
|
176
|
+
after_create: |
|
|
177
|
+
git clone https://github.com/your-org/your-repo.git .
|
|
178
|
+
bun install
|
|
179
|
+
|
|
180
|
+
agent:
|
|
181
|
+
max_concurrent_agents: 3
|
|
182
|
+
max_turns: 20
|
|
183
|
+
|
|
184
|
+
claude:
|
|
185
|
+
permission_mode: acceptEdits
|
|
186
|
+
# setting_sources: [] # default: [project, local, user]; set [] for SDK isolation mode
|
|
187
|
+
turn_timeout_ms: 3600000
|
|
188
|
+
---
|
|
189
|
+
|
|
190
|
+
You are working on a GitHub issue for the repository `your-org/your-repo`.
|
|
191
|
+
|
|
192
|
+
Issue {{ issue.identifier }}: {{ issue.title }}
|
|
193
|
+
|
|
194
|
+
{{ issue.description }}
|
|
195
|
+
|
|
196
|
+
{% if issue.blocked_by.size > 0 %}
|
|
197
|
+
Blocked by:
|
|
198
|
+
{% for blocker in issue.blocked_by %}
|
|
199
|
+
- {{ blocker.identifier }} ({{ blocker.state }})
|
|
200
|
+
{% endfor %}
|
|
201
|
+
{% endif %}
|
|
202
|
+
|
|
203
|
+
{% if attempt %}
|
|
204
|
+
This is attempt #{{ attempt }}. Review any prior work in the workspace before continuing.
|
|
205
|
+
{% endif %}
|
|
206
|
+
|
|
207
|
+
Your task:
|
|
208
|
+
1. Understand the issue requirements.
|
|
209
|
+
2. Implement the requested changes.
|
|
210
|
+
3. Write or update tests as needed.
|
|
211
|
+
4. Open a pull request and move this issue to `Human Review`.
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
#### GitHub Projects v2 (GitHub App)
|
|
215
|
+
|
|
216
|
+
Use GitHub App credentials instead of a PAT for fine-grained permissions and higher API rate limits:
|
|
217
|
+
|
|
218
|
+
```markdown
|
|
219
|
+
---
|
|
220
|
+
tracker:
|
|
221
|
+
kind: github_projects
|
|
222
|
+
app_id: $GITHUB_APP_ID
|
|
223
|
+
private_key: $GITHUB_APP_PRIVATE_KEY
|
|
224
|
+
installation_id: $GITHUB_APP_INSTALLATION_ID
|
|
225
|
+
owner: your-org
|
|
226
|
+
project_number: 42
|
|
227
|
+
active_statuses:
|
|
228
|
+
- Todo
|
|
229
|
+
- In Progress
|
|
230
|
+
- Merging
|
|
231
|
+
- Rework
|
|
232
|
+
terminal_statuses:
|
|
233
|
+
- Closed
|
|
234
|
+
- Cancelled
|
|
235
|
+
- Canceled
|
|
236
|
+
- Duplicate
|
|
237
|
+
- Done
|
|
238
|
+
watched_statuses:
|
|
239
|
+
- Human Review
|
|
240
|
+
|
|
241
|
+
polling:
|
|
242
|
+
interval_ms: 30000
|
|
243
|
+
|
|
244
|
+
workspace:
|
|
245
|
+
root: ~/agent-please_workspaces
|
|
246
|
+
|
|
247
|
+
hooks:
|
|
248
|
+
after_create: |
|
|
249
|
+
git clone https://github.com/your-org/your-repo.git .
|
|
250
|
+
bun install
|
|
251
|
+
|
|
252
|
+
agent:
|
|
253
|
+
max_concurrent_agents: 3
|
|
254
|
+
max_turns: 20
|
|
255
|
+
|
|
256
|
+
claude:
|
|
257
|
+
permission_mode: acceptEdits
|
|
258
|
+
# setting_sources: [] # default: [project, local, user]; set [] for SDK isolation mode
|
|
259
|
+
turn_timeout_ms: 3600000
|
|
260
|
+
---
|
|
261
|
+
|
|
262
|
+
You are working on a GitHub issue for the repository `your-org/your-repo`.
|
|
263
|
+
|
|
264
|
+
Issue {{ issue.identifier }}: {{ issue.title }}
|
|
265
|
+
|
|
266
|
+
{{ issue.description }}
|
|
267
|
+
|
|
268
|
+
{% if issue.blocked_by.size > 0 %}
|
|
269
|
+
Blocked by:
|
|
270
|
+
{% for blocker in issue.blocked_by %}
|
|
271
|
+
- {{ blocker.identifier }} ({{ blocker.state }})
|
|
272
|
+
{% endfor %}
|
|
273
|
+
{% endif %}
|
|
274
|
+
|
|
275
|
+
{% if attempt %}
|
|
276
|
+
This is attempt #{{ attempt }}. Review any prior work in the workspace before continuing.
|
|
277
|
+
{% endif %}
|
|
278
|
+
|
|
279
|
+
Your task:
|
|
280
|
+
1. Understand the issue requirements.
|
|
281
|
+
2. Implement the requested changes.
|
|
282
|
+
3. Write or update tests as needed.
|
|
283
|
+
4. Open a pull request and move this issue to `Human Review`.
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
#### Asana (under development)
|
|
287
|
+
|
|
288
|
+
> **Note**: Asana support is under development. The configuration below is a preview and may change.
|
|
289
|
+
|
|
290
|
+
```markdown
|
|
291
|
+
---
|
|
292
|
+
tracker:
|
|
293
|
+
kind: asana
|
|
294
|
+
api_key: $ASANA_ACCESS_TOKEN
|
|
295
|
+
project_gid: "1234567890123456"
|
|
296
|
+
active_sections:
|
|
297
|
+
- In Progress
|
|
298
|
+
terminal_sections:
|
|
299
|
+
- Done
|
|
300
|
+
- Cancelled
|
|
301
|
+
|
|
302
|
+
polling:
|
|
303
|
+
interval_ms: 30000
|
|
304
|
+
|
|
305
|
+
workspace:
|
|
306
|
+
root: ~/agent-please_workspaces
|
|
307
|
+
|
|
308
|
+
hooks:
|
|
309
|
+
after_create: |
|
|
310
|
+
git clone https://github.com/your-org/your-repo.git .
|
|
311
|
+
bun install
|
|
312
|
+
|
|
313
|
+
agent:
|
|
314
|
+
max_concurrent_agents: 3
|
|
315
|
+
max_turns: 20
|
|
316
|
+
|
|
317
|
+
claude:
|
|
318
|
+
permission_mode: acceptEdits
|
|
319
|
+
# setting_sources: [] # default: [project, local, user]; set [] for SDK isolation mode
|
|
320
|
+
turn_timeout_ms: 3600000
|
|
321
|
+
---
|
|
322
|
+
|
|
323
|
+
You are working on an Asana task for the project.
|
|
324
|
+
|
|
325
|
+
Task: {{ issue.title }}
|
|
326
|
+
|
|
327
|
+
{{ issue.description }}
|
|
328
|
+
|
|
329
|
+
{% if issue.blocked_by.size > 0 %}
|
|
330
|
+
Blocked by:
|
|
331
|
+
{% for blocker in issue.blocked_by %}
|
|
332
|
+
- {{ blocker.identifier }} ({{ blocker.state }})
|
|
333
|
+
{% endfor %}
|
|
334
|
+
{% endif %}
|
|
335
|
+
|
|
336
|
+
{% if attempt %}
|
|
337
|
+
This is attempt #{{ attempt }}. Review any prior work in the workspace before continuing.
|
|
338
|
+
{% endif %}
|
|
339
|
+
|
|
340
|
+
Your task:
|
|
341
|
+
1. Understand the task requirements.
|
|
342
|
+
2. Implement the requested changes.
|
|
343
|
+
3. Write or update tests as needed.
|
|
344
|
+
4. Open a pull request and move this task to the review section (e.g. `Human Review`).
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
### Run
|
|
348
|
+
|
|
349
|
+
```bash
|
|
350
|
+
# Set your tracker token (GitHub PAT)
|
|
351
|
+
export GITHUB_TOKEN=ghp_your_token_here
|
|
352
|
+
# or (GitHub App)
|
|
353
|
+
export GITHUB_APP_ID=12345
|
|
354
|
+
export GITHUB_APP_PRIVATE_KEY="$(cat path/to/private-key.pem)"
|
|
355
|
+
export GITHUB_APP_INSTALLATION_ID=67890
|
|
356
|
+
# or (Asana — under development)
|
|
357
|
+
export ASANA_ACCESS_TOKEN=your_token_here
|
|
358
|
+
|
|
359
|
+
# Run Agent Please against a WORKFLOW.md in the current directory
|
|
360
|
+
bunx agent-please
|
|
361
|
+
|
|
362
|
+
# Or specify a WORKFLOW.md path
|
|
363
|
+
bunx agent-please /path/to/WORKFLOW.md
|
|
364
|
+
|
|
365
|
+
# Enable the optional HTTP dashboard on port 3000
|
|
366
|
+
bunx agent-please --port 3000
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
## WORKFLOW.md Configuration
|
|
370
|
+
|
|
371
|
+
`WORKFLOW.md` is the single source of truth for Agent Please's runtime behavior. It combines a YAML
|
|
372
|
+
front matter configuration block with a Markdown prompt template body.
|
|
373
|
+
|
|
374
|
+
### Full Front Matter Schema
|
|
375
|
+
|
|
376
|
+
```yaml
|
|
377
|
+
---
|
|
378
|
+
tracker:
|
|
379
|
+
kind: github_projects # Required: "github_projects" or "asana"
|
|
380
|
+
|
|
381
|
+
# --- GitHub Projects v2 fields (when kind == "github_projects") ---
|
|
382
|
+
api_key: $GITHUB_TOKEN # Required: token or $ENV_VAR
|
|
383
|
+
endpoint: https://api.github.com # Optional: override GitHub API base URL
|
|
384
|
+
owner: your-org # Required: GitHub organization or user login
|
|
385
|
+
project_number: 42 # Required: GitHub Projects v2 project number
|
|
386
|
+
project_id: PVT_kwDOxxxxx # Optional: project node ID (bypasses owner+project_number lookup)
|
|
387
|
+
active_statuses: # Optional: default ["Todo", "In Progress", "Merging", "Rework"]
|
|
388
|
+
- Todo
|
|
389
|
+
- In Progress
|
|
390
|
+
- Merging
|
|
391
|
+
- Rework
|
|
392
|
+
terminal_statuses: # Optional: default ["Closed", "Cancelled", "Canceled", "Duplicate", "Done"]
|
|
393
|
+
- Closed
|
|
394
|
+
- Cancelled
|
|
395
|
+
- Canceled
|
|
396
|
+
- Duplicate
|
|
397
|
+
- Done
|
|
398
|
+
watched_statuses: # Optional: states polled for dispatch on review activity. Default ["Human Review"]
|
|
399
|
+
- Human Review
|
|
400
|
+
# GitHub App authentication (alternative to api_key — all three required together):
|
|
401
|
+
# app_id: $GITHUB_APP_ID # Optional: GitHub App ID (integer or $ENV_VAR)
|
|
402
|
+
# private_key: $GITHUB_APP_PRIVATE_KEY # Optional: GitHub App private key PEM or $ENV_VAR
|
|
403
|
+
# installation_id: $GITHUB_APP_INSTALLATION_ID # Optional: installation ID (integer or $ENV_VAR)
|
|
404
|
+
|
|
405
|
+
# --- Asana fields (when kind == "asana") --- UNDER DEVELOPMENT
|
|
406
|
+
# api_key: $ASANA_ACCESS_TOKEN # Required: token or $ENV_VAR
|
|
407
|
+
# endpoint: https://app.asana.com/api/1.0 # Optional: override Asana API base URL
|
|
408
|
+
# project_gid: "1234567890123456" # Required: Asana project GID
|
|
409
|
+
# active_sections: # Optional: default ["To Do", "In Progress"]
|
|
410
|
+
# - In Progress
|
|
411
|
+
# terminal_sections: # Optional: default ["Done", "Cancelled"]
|
|
412
|
+
# - Done
|
|
413
|
+
# - Cancelled
|
|
414
|
+
|
|
415
|
+
# --- Shared filter fields (both trackers) ---
|
|
416
|
+
# filter:
|
|
417
|
+
# assignee: user1, user2 # Optional: CSV or YAML array; case-insensitive OR match
|
|
418
|
+
# # (unassigned issues are excluded when this filter is set)
|
|
419
|
+
# label: bug, feature # Optional: CSV or YAML array; case-insensitive OR match
|
|
420
|
+
# Both filters AND together when both are specified. Applies at dispatch time only.
|
|
421
|
+
|
|
422
|
+
polling:
|
|
423
|
+
interval_ms: 30000 # Optional: poll cadence in ms, default 30000
|
|
424
|
+
|
|
425
|
+
workspace:
|
|
426
|
+
root: ~/agent-please_workspaces # Optional: default <tmpdir>/agent-please_workspaces
|
|
427
|
+
|
|
428
|
+
hooks:
|
|
429
|
+
after_create: | # Optional: run once when workspace is first created
|
|
430
|
+
git clone https://github.com/your-org/your-repo.git .
|
|
431
|
+
before_run: | # Optional: run before each agent attempt
|
|
432
|
+
git pull --rebase
|
|
433
|
+
after_run: | # Optional: run after each agent attempt
|
|
434
|
+
echo "Run completed"
|
|
435
|
+
before_remove: | # Optional: run before workspace deletion
|
|
436
|
+
echo "Cleaning up"
|
|
437
|
+
timeout_ms: 60000 # Optional: hook timeout in ms, default 60000
|
|
438
|
+
|
|
439
|
+
agent:
|
|
440
|
+
max_concurrent_agents: 10 # Optional: global concurrency limit, default 10
|
|
441
|
+
max_turns: 20 # Optional: max turns per agent run, default 20
|
|
442
|
+
max_retry_backoff_ms: 300000 # Optional: max retry delay in ms, default 300000
|
|
443
|
+
max_concurrent_agents_by_state: # Optional: per-state concurrency limits
|
|
444
|
+
in progress: 5
|
|
445
|
+
|
|
446
|
+
claude:
|
|
447
|
+
command: claude # Optional: Claude Code CLI command, default "claude"
|
|
448
|
+
model: claude-sonnet-4-5-20250514 # Optional: override Claude model. Default: CLI default
|
|
449
|
+
effort: high # Optional: reasoning depth — 'low', 'medium', 'high', or 'max'. Default 'high'.
|
|
450
|
+
permission_mode: acceptEdits # Optional: one of 'default', 'acceptEdits', 'bypassPermissions'. Defaults to 'bypassPermissions'.
|
|
451
|
+
allowed_tools: # Optional: restrict available tools
|
|
452
|
+
- Read
|
|
453
|
+
- Write
|
|
454
|
+
- Bash
|
|
455
|
+
setting_sources: # Optional: filesystem settings to load. Default: [project, local, user]
|
|
456
|
+
- project # load .claude/settings.json + CLAUDE.md from the workspace directory
|
|
457
|
+
- local # load .claude/settings.local.json from the workspace directory
|
|
458
|
+
- user # load ~/.claude/settings.json + global CLAUDE.md
|
|
459
|
+
# Only "project", "local", and "user" are valid — other values are ignored
|
|
460
|
+
turn_timeout_ms: 3600000 # Optional: per-turn timeout in ms, default 3600000
|
|
461
|
+
read_timeout_ms: 5000 # Optional: initial subprocess read timeout in ms, default 5000
|
|
462
|
+
stall_timeout_ms: 300000 # Optional: stall detection timeout, default 300000
|
|
463
|
+
system_prompt: "custom prompt" # Optional: custom system prompt string. Default: built-in claude_code preset
|
|
464
|
+
settings:
|
|
465
|
+
attribution:
|
|
466
|
+
commit: "🙏 Generated with [Agent Please](https://github.com/pleaseai/agent-please)" # Optional: appended to git commit messages. Defaults to Agent Please link.
|
|
467
|
+
pr: "🙏 Generated with [Agent Please](https://github.com/pleaseai/agent-please)" # Optional: appended to PR descriptions. Defaults to Agent Please link.
|
|
468
|
+
|
|
469
|
+
# worker: # Optional: SSH worker support (experimental)
|
|
470
|
+
# ssh_hosts: # List of SSH host aliases for remote execution
|
|
471
|
+
# - worker-1
|
|
472
|
+
# - worker-2
|
|
473
|
+
# max_concurrent_agents_per_host: 5 # Max agents per SSH host
|
|
474
|
+
|
|
475
|
+
# observability: # Optional: TUI dashboard settings
|
|
476
|
+
# dashboard_enabled: true # Enable TUI dashboard, default true
|
|
477
|
+
# refresh_ms: 1000 # Dashboard data refresh interval, default 1000
|
|
478
|
+
# render_interval_ms: 16 # TUI render interval, default 16
|
|
479
|
+
|
|
480
|
+
server:
|
|
481
|
+
port: 3000 # Optional: enable HTTP dashboard on this port
|
|
482
|
+
host: "127.0.0.1" # Optional: bind address, default "127.0.0.1"
|
|
483
|
+
# Webhook endpoints:
|
|
484
|
+
# GitHub: POST /api/webhooks/github (requires server.webhook.secret)
|
|
485
|
+
# Slack: POST /api/webhooks/slack (requires SLACK_BOT_TOKEN + SLACK_SIGNING_SECRET env vars)
|
|
486
|
+
---
|
|
487
|
+
|
|
488
|
+
Your prompt template goes here. Available variables:
|
|
489
|
+
|
|
490
|
+
- {{ issue.id }} — Tracker-internal issue ID
|
|
491
|
+
- {{ issue.identifier }} — Human-readable identifier (e.g. "#42" or task GID)
|
|
492
|
+
- {{ issue.title }} — Issue title
|
|
493
|
+
- {{ issue.description }} — Issue body/description
|
|
494
|
+
- {{ issue.state }} — Current tracker state name
|
|
495
|
+
- {{ issue.url }} — Issue URL
|
|
496
|
+
- {{ issue.assignees }} — Array of assignee logins (GitHub) or emails (Asana)
|
|
497
|
+
- {{ issue.labels }} — Array of label strings (normalized to lowercase)
|
|
498
|
+
- {{ issue.blocked_by }} — Array of blocker refs (each has id, identifier, state)
|
|
499
|
+
- {{ issue.branch_name }} — PR head branch name (for PullRequest items) or null
|
|
500
|
+
- {{ issue.pull_requests }} — Array of linked PRs (each has number, title, url, state, branch_name)
|
|
501
|
+
- {{ issue.review_decision }} — PR review decision: "approved", "changes_requested", "commented", "review_required", or null
|
|
502
|
+
- {{ issue.priority }} — Numeric priority or null
|
|
503
|
+
- {{ issue.created_at }} — ISO-8601 creation timestamp
|
|
504
|
+
- {{ issue.updated_at }} — ISO-8601 last-updated timestamp
|
|
505
|
+
- {{ issue.project }} — GitHub Projects v2 context (null for Asana):
|
|
506
|
+
- {{ issue.project.owner }} — Project owner login
|
|
507
|
+
- {{ issue.project.number }} — Project number
|
|
508
|
+
- {{ issue.project.project_id }} — Project GraphQL node ID (resolved at runtime)
|
|
509
|
+
- {{ issue.project.item_id }} — Project item GraphQL node ID
|
|
510
|
+
- {{ issue.project.field_id }} — Status field GraphQL node ID (resolved at runtime)
|
|
511
|
+
- {{ issue.project.status_options }} — Array of { name, id } for status field options
|
|
512
|
+
- {{ attempt }} — Retry attempt number (null on first run)
|
|
513
|
+
```
|
|
514
|
+
|
|
515
|
+
### Template Variables
|
|
516
|
+
|
|
517
|
+
The prompt template uses Liquid-compatible syntax. All `issue` fields are available:
|
|
518
|
+
|
|
519
|
+
```markdown
|
|
520
|
+
{{ issue.identifier }}: {{ issue.title }}
|
|
521
|
+
|
|
522
|
+
{{ issue.description }}
|
|
523
|
+
|
|
524
|
+
State: {{ issue.state }}
|
|
525
|
+
|
|
526
|
+
{% if issue.blocked_by.size > 0 %}
|
|
527
|
+
Blocked by:
|
|
528
|
+
{% for blocker in issue.blocked_by %}
|
|
529
|
+
- {{ blocker.identifier }} ({{ blocker.state }})
|
|
530
|
+
{% endfor %}
|
|
531
|
+
{% endif %}
|
|
532
|
+
|
|
533
|
+
{% if issue.pull_requests.size > 0 %}
|
|
534
|
+
Linked pull requests:
|
|
535
|
+
{% for pr in issue.pull_requests %}
|
|
536
|
+
- PR #{{ pr.number }}: {{ pr.title }} ({{ pr.state }}){% if pr.branch_name %} — branch: {{ pr.branch_name }}{% endif %}{% if pr.url %} — {{ pr.url }}{% endif %}
|
|
537
|
+
|
|
538
|
+
{% endfor %}
|
|
539
|
+
{% endif %}
|
|
540
|
+
|
|
541
|
+
{% if attempt %}
|
|
542
|
+
Retry attempt: {{ attempt }}
|
|
543
|
+
{% endif %}
|
|
544
|
+
```
|
|
545
|
+
|
|
546
|
+
## CLI Usage
|
|
547
|
+
|
|
548
|
+
```bash
|
|
549
|
+
# Basic usage (reads WORKFLOW.md from current directory)
|
|
550
|
+
agent-please
|
|
551
|
+
|
|
552
|
+
# Specify WORKFLOW.md path (positional argument)
|
|
553
|
+
agent-please ./WORKFLOW.md
|
|
554
|
+
|
|
555
|
+
# Enable HTTP dashboard
|
|
556
|
+
agent-please --port 3000
|
|
557
|
+
|
|
558
|
+
# Initialize a new GitHub Projects v2 project and scaffold WORKFLOW.md
|
|
559
|
+
# (Requires GITHUB_TOKEN environment variable to be set)
|
|
560
|
+
agent-please init --owner <org-or-user> --title "My Project"
|
|
561
|
+
|
|
562
|
+
# Alternatively, provide the token via a flag:
|
|
563
|
+
agent-please init --owner <org-or-user> --title "My Project" --token <your-github-token>
|
|
564
|
+
|
|
565
|
+
# Show help
|
|
566
|
+
agent-please --help
|
|
567
|
+
```
|
|
568
|
+
|
|
569
|
+
## GitHub App Authentication
|
|
570
|
+
|
|
571
|
+
The `github_projects` tracker supports two authentication methods:
|
|
572
|
+
|
|
573
|
+
| Method | Config fields | When to use |
|
|
574
|
+
|--------|--------------|-------------|
|
|
575
|
+
| **PAT** | `api_key` | Personal access tokens — quick setup |
|
|
576
|
+
| **GitHub App** | `app_id`, `private_key`, `installation_id` | Organizations — fine-grained permissions, higher rate limits |
|
|
577
|
+
|
|
578
|
+
When both are present, `api_key` (PAT) takes precedence.
|
|
579
|
+
|
|
580
|
+
### Setting up GitHub App credentials
|
|
581
|
+
|
|
582
|
+
1. Create a GitHub App with the following permissions:
|
|
583
|
+
- **Repository permissions**:
|
|
584
|
+
- `Contents`: Read-only
|
|
585
|
+
- `Issues`: Read & write
|
|
586
|
+
- `Pull requests`: Read & write
|
|
587
|
+
- **Organization permissions**:
|
|
588
|
+
- `Projects`: Read & write
|
|
589
|
+
2. Install the app on your organization and note the **installation ID** (visible in the app's
|
|
590
|
+
installation settings URL).
|
|
591
|
+
3. Generate a **private key** (`.pem` file) from the app's settings page.
|
|
592
|
+
4. Set the environment variables:
|
|
593
|
+
|
|
594
|
+
```bash
|
|
595
|
+
export GITHUB_APP_ID=12345
|
|
596
|
+
export GITHUB_APP_PRIVATE_KEY="$(cat /path/to/private-key.pem)"
|
|
597
|
+
export GITHUB_APP_INSTALLATION_ID=67890
|
|
598
|
+
```
|
|
599
|
+
|
|
600
|
+
5. Reference them in `WORKFLOW.md`:
|
|
601
|
+
|
|
602
|
+
```yaml
|
|
603
|
+
tracker:
|
|
604
|
+
kind: github_projects
|
|
605
|
+
app_id: $GITHUB_APP_ID
|
|
606
|
+
private_key: $GITHUB_APP_PRIVATE_KEY
|
|
607
|
+
installation_id: $GITHUB_APP_INSTALLATION_ID
|
|
608
|
+
owner: your-org
|
|
609
|
+
project_number: 42
|
|
610
|
+
```
|
|
611
|
+
|
|
612
|
+
The values can also be inlined directly (not recommended for secrets):
|
|
613
|
+
|
|
614
|
+
```yaml
|
|
615
|
+
app_id: 12345
|
|
616
|
+
private_key: "-----BEGIN RSA PRIVATE KEY-----\n..."
|
|
617
|
+
installation_id: 67890
|
|
618
|
+
```
|
|
619
|
+
|
|
620
|
+
### Validation
|
|
621
|
+
|
|
622
|
+
Agent Please validates GitHub App config at startup:
|
|
623
|
+
|
|
624
|
+
| Scenario | Result |
|
|
625
|
+
|----------|--------|
|
|
626
|
+
| `api_key` set | PAT auth — app fields ignored |
|
|
627
|
+
| All three app fields set (`app_id`, `private_key`, `installation_id`) | App auth |
|
|
628
|
+
| Only some app fields set | `incomplete_github_app_config` error |
|
|
629
|
+
| No auth configured | `missing_tracker_api_key` error |
|
|
630
|
+
|
|
631
|
+
## Slack Notifications
|
|
632
|
+
|
|
633
|
+
Agent Please supports Slack as a notification channel via the [Chat SDK](https://chat-sdk.dev/)
|
|
634
|
+
Slack adapter. When configured, you can @mention the bot in any Slack channel to get real-time
|
|
635
|
+
orchestrator status (running issues, retry queue, token usage).
|
|
636
|
+
|
|
637
|
+
### Environment Variables
|
|
638
|
+
|
|
639
|
+
```bash
|
|
640
|
+
SLACK_BOT_TOKEN=xoxb-... # Bot User OAuth Token
|
|
641
|
+
SLACK_SIGNING_SECRET=... # Signing secret for webhook verification
|
|
642
|
+
```
|
|
643
|
+
|
|
644
|
+
When both environment variables are set, the Slack adapter is automatically enabled alongside any
|
|
645
|
+
configured tracker (GitHub Projects v2 or Asana).
|
|
646
|
+
|
|
647
|
+
### Webhook URL
|
|
648
|
+
|
|
649
|
+
Point your Slack app's Event Subscriptions and Interactivity request URL to:
|
|
650
|
+
|
|
651
|
+
```
|
|
652
|
+
https://your-domain.com/api/webhooks/slack
|
|
653
|
+
```
|
|
654
|
+
|
|
655
|
+
### Slack App Setup
|
|
656
|
+
|
|
657
|
+
1. Go to [api.slack.com/apps](https://api.slack.com/apps) and click **Create New App** > **From an app manifest**.
|
|
658
|
+
2. Select your workspace and paste the following manifest:
|
|
659
|
+
|
|
660
|
+
```yaml
|
|
661
|
+
display_information:
|
|
662
|
+
name: Agent Please
|
|
663
|
+
description: Orchestrator status bot
|
|
664
|
+
features:
|
|
665
|
+
bot_user:
|
|
666
|
+
display_name: Agent Please
|
|
667
|
+
always_online: true
|
|
668
|
+
oauth_config:
|
|
669
|
+
scopes:
|
|
670
|
+
bot:
|
|
671
|
+
- app_mentions:read
|
|
672
|
+
- channels:history
|
|
673
|
+
- channels:read
|
|
674
|
+
- chat:write
|
|
675
|
+
- groups:history
|
|
676
|
+
- groups:read
|
|
677
|
+
- im:history
|
|
678
|
+
- im:read
|
|
679
|
+
- reactions:read
|
|
680
|
+
- reactions:write
|
|
681
|
+
- users:read
|
|
682
|
+
settings:
|
|
683
|
+
event_subscriptions:
|
|
684
|
+
request_url: https://your-domain.com/api/webhooks/slack
|
|
685
|
+
bot_events:
|
|
686
|
+
- app_mention
|
|
687
|
+
- message.channels
|
|
688
|
+
- message.groups
|
|
689
|
+
- message.im
|
|
690
|
+
interactivity:
|
|
691
|
+
is_enabled: true
|
|
692
|
+
request_url: https://your-domain.com/api/webhooks/slack
|
|
693
|
+
org_deploy_enabled: false
|
|
694
|
+
socket_mode_enabled: false
|
|
695
|
+
token_rotation_enabled: false
|
|
696
|
+
```
|
|
697
|
+
|
|
698
|
+
3. Replace `https://your-domain.com/api/webhooks/slack` with your deployed webhook URL.
|
|
699
|
+
4. Click **Create**, then go to **Basic Information** > **App Credentials** and copy the **Signing Secret** as `SLACK_SIGNING_SECRET`.
|
|
700
|
+
5. Go to **OAuth & Permissions**, click **Install to Workspace**, and copy the **Bot User OAuth Token** (`xoxb-...`) as `SLACK_BOT_TOKEN`.
|
|
701
|
+
6. Invite the bot to a channel and @mention it to see the orchestrator status.
|
|
702
|
+
|
|
703
|
+
## Trust and Safety
|
|
704
|
+
|
|
705
|
+
Agent Please runs Claude Code autonomously. Understand the trust implications before deploying.
|
|
706
|
+
|
|
707
|
+
### Permission Modes
|
|
708
|
+
|
|
709
|
+
| Mode | Behavior | Recommended For |
|
|
710
|
+
|---|---|---|
|
|
711
|
+
| `default` | Interactive approval for sensitive operations | Development, unknown repositories |
|
|
712
|
+
| `acceptEdits` | Auto-approve file edits; prompt for shell commands | Trusted codebases |
|
|
713
|
+
| `bypassPermissions` | Auto-approve all operations | Sandboxed CI environments |
|
|
714
|
+
|
|
715
|
+
Start with `default` or `acceptEdits` unless you are running in a fully isolated environment.
|
|
716
|
+
|
|
717
|
+
### Workspace Isolation
|
|
718
|
+
|
|
719
|
+
- Each issue runs in a dedicated directory under `workspace.root`.
|
|
720
|
+
- Claude Code's working directory is validated against the workspace path before launch.
|
|
721
|
+
- Workspace paths are sanitized to prevent path traversal attacks.
|
|
722
|
+
|
|
723
|
+
### Recommendations
|
|
724
|
+
|
|
725
|
+
- Use `acceptEdits` permission mode as a baseline for most deployments.
|
|
726
|
+
- Use `bypassPermissions` only in network-isolated CI runners or Docker containers.
|
|
727
|
+
- Set `agent.max_concurrent_agents` conservatively when first testing.
|
|
728
|
+
- Monitor agent runs via the HTTP dashboard (`--port`) or structured logs.
|
|
729
|
+
- Keep API tokens scoped to the minimum required permissions.
|
|
730
|
+
|
|
731
|
+
## License
|
|
732
|
+
|
|
733
|
+
Functional Source License 1.1, MIT Future License (FSL-1.1-MIT). See [LICENSE](LICENSE) for details.
|
|
734
|
+
|
|
735
|
+
### Third-Party Licenses
|
|
736
|
+
|
|
737
|
+
- Agent Please is a TypeScript implementation based on the [Symphony specification](vendor/symphony/SPEC.md) by OpenAI (Apache 2.0).
|
|
738
|
+
- This project uses the [Claude Agent SDK](https://github.com/anthropics/claude-agent-sdk-typescript), which is subject to Anthropic's [Commercial Terms of Service](https://www.anthropic.com/legal/commercial-terms).
|