@pleaseai/work 0.1.6 → 0.1.7
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/README.md +82 -59
- package/dist/index.js +16 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -36,13 +36,13 @@ instead of supervising coding agents.
|
|
|
36
36
|
|
|
37
37
|
Work Please is a long-running TypeScript service that:
|
|
38
38
|
|
|
39
|
-
1. Polls an issue tracker (
|
|
39
|
+
1. Polls an issue tracker (GitHub Projects v2 or Asana) for tasks in configured active states.
|
|
40
40
|
2. Creates an isolated workspace directory for each eligible issue.
|
|
41
41
|
3. Launches a Claude Code agent session inside that workspace with a rendered prompt.
|
|
42
42
|
4. Monitors the session, handles retries, and reconciles issue state on each poll cycle.
|
|
43
43
|
|
|
44
44
|
It is a TypeScript implementation of the [Symphony specification](vendor/symphony/SPEC.md),
|
|
45
|
-
adapted for
|
|
45
|
+
adapted for GitHub Projects v2 / Asana and Claude Code instead of Linear and Codex.
|
|
46
46
|
|
|
47
47
|
For full technical details, see [SPEC.md](SPEC.md).
|
|
48
48
|
|
|
@@ -50,18 +50,18 @@ For full technical details, see [SPEC.md](SPEC.md).
|
|
|
50
50
|
|
|
51
51
|
| | Symphony (reference) | Work Please |
|
|
52
52
|
|---|---|---|
|
|
53
|
-
| Issue Tracker | Linear |
|
|
53
|
+
| Issue Tracker | Linear | GitHub Projects v2 & Asana (under development) |
|
|
54
54
|
| Coding Agent | Codex (app-server mode) | Claude Code CLI |
|
|
55
55
|
| Language | Elixir/OTP | TypeScript + Bun |
|
|
56
|
-
| Tracker Auth | `LINEAR_API_KEY` | `
|
|
57
|
-
| Project Config | `project_slug` | `
|
|
58
|
-
| Issue States | Linear workflow states |
|
|
56
|
+
| Tracker Auth | `LINEAR_API_KEY` | `GITHUB_TOKEN`, GitHub App credentials, or `ASANA_ACCESS_TOKEN` |
|
|
57
|
+
| Project Config | `project_slug` | `owner` + `project_number` (GitHub Projects v2) or `project_gid` (Asana) |
|
|
58
|
+
| Issue States | Linear workflow states | GitHub Projects v2 Status field / Asana sections |
|
|
59
59
|
| Agent Protocol | JSON-RPC over stdio | `@anthropic-ai/claude-agent-sdk` |
|
|
60
60
|
| Permission Model | Codex approval/sandbox policies | Claude Code `--permission-mode` |
|
|
61
61
|
|
|
62
62
|
## Features
|
|
63
63
|
|
|
64
|
-
- **Multi-tracker support** — Dispatch work from
|
|
64
|
+
- **Multi-tracker support** — Dispatch work from GitHub Projects v2 items or Asana tasks (under development) on a
|
|
65
65
|
fixed cadence.
|
|
66
66
|
- **GitHub App authentication** — Authenticate the GitHub tracker with a GitHub App installation
|
|
67
67
|
token (`app_id` + `private_key` + `installation_id`) instead of a PAT, for fine-grained
|
|
@@ -90,8 +90,8 @@ Config Layer ──> Orchestrator ──> Workspace Manager ──> Agent Runner
|
|
|
90
90
|
| |
|
|
91
91
|
v v
|
|
92
92
|
Issue Tracker Client Isolated workspace/
|
|
93
|
-
(
|
|
94
|
-
|
|
93
|
+
(GitHub GraphQL API or per-issue directory
|
|
94
|
+
Asana REST API,
|
|
95
95
|
polling + reconciliation)
|
|
96
96
|
|
|
|
97
97
|
v
|
|
@@ -103,7 +103,7 @@ Components:
|
|
|
103
103
|
- **Workflow Loader** — Parses `WORKFLOW.md` YAML front matter and prompt template body.
|
|
104
104
|
- **Config Layer** — Typed getters with env-var indirection and built-in defaults.
|
|
105
105
|
- **Issue Tracker Client** — Fetches candidate issues, reconciles running-issue states. Supports
|
|
106
|
-
|
|
106
|
+
GitHub Projects v2 (GraphQL API) and Asana (REST API) adapters.
|
|
107
107
|
- **Orchestrator** — Owns in-memory state; drives the poll/dispatch/retry loop.
|
|
108
108
|
- **Workspace Manager** — Creates, reuses, and cleans per-issue workspaces; runs hooks.
|
|
109
109
|
- **Agent Runner** — Launches Claude Code, streams events back to the orchestrator.
|
|
@@ -117,9 +117,9 @@ See [SPEC.md](SPEC.md) for the full specification.
|
|
|
117
117
|
|
|
118
118
|
- **Bun** (see [bun.sh](https://bun.sh) for installation)
|
|
119
119
|
- **Claude Code CLI** (see the [official installation guide](https://docs.anthropic.com/en/docs/claude-code))
|
|
120
|
-
- **
|
|
121
|
-
|
|
122
|
-
|
|
120
|
+
- **GitHub token** (`GITHUB_TOKEN`) with access to the target project, **or** **GitHub App credentials**
|
|
121
|
+
(`GITHUB_APP_ID`, `GITHUB_APP_PRIVATE_KEY`, `GITHUB_APP_INSTALLATION_ID`) — see [GitHub App Authentication](#github-app-authentication),
|
|
122
|
+
**or** **Asana access token** (`ASANA_ACCESS_TOKEN`) (under development)
|
|
123
123
|
|
|
124
124
|
### Install
|
|
125
125
|
|
|
@@ -133,18 +133,22 @@ bun run build
|
|
|
133
133
|
### Configure
|
|
134
134
|
|
|
135
135
|
Create a `WORKFLOW.md` in your target repository. Two examples are shown below.
|
|
136
|
+
See also the [example WORKFLOW.md](https://github.com/pleaseai/workflow/blob/main/WORKFLOW.md) for a real-world reference.
|
|
136
137
|
|
|
137
|
-
####
|
|
138
|
+
#### GitHub Projects v2 (PAT)
|
|
139
|
+
|
|
140
|
+
See also the [example GitHub Project](https://github.com/orgs/pleaseai/projects/2) for a real-world reference.
|
|
138
141
|
|
|
139
142
|
```markdown
|
|
140
143
|
---
|
|
141
144
|
tracker:
|
|
142
|
-
kind:
|
|
143
|
-
api_key: $
|
|
144
|
-
|
|
145
|
-
|
|
145
|
+
kind: github_projects
|
|
146
|
+
api_key: $GITHUB_TOKEN
|
|
147
|
+
owner: your-org
|
|
148
|
+
project_number: 42
|
|
149
|
+
active_statuses:
|
|
146
150
|
- In Progress
|
|
147
|
-
|
|
151
|
+
terminal_statuses:
|
|
148
152
|
- Done
|
|
149
153
|
- Cancelled
|
|
150
154
|
|
|
@@ -169,9 +173,9 @@ claude:
|
|
|
169
173
|
turn_timeout_ms: 3600000
|
|
170
174
|
---
|
|
171
175
|
|
|
172
|
-
You are working on
|
|
176
|
+
You are working on a GitHub issue for the repository `your-org/your-repo`.
|
|
173
177
|
|
|
174
|
-
|
|
178
|
+
Issue {{ issue.identifier }}: {{ issue.title }}
|
|
175
179
|
|
|
176
180
|
{{ issue.description }}
|
|
177
181
|
|
|
@@ -187,19 +191,23 @@ This is attempt #{{ attempt }}. Review any prior work in the workspace before co
|
|
|
187
191
|
{% endif %}
|
|
188
192
|
|
|
189
193
|
Your task:
|
|
190
|
-
1. Understand the
|
|
194
|
+
1. Understand the issue requirements.
|
|
191
195
|
2. Implement the requested changes.
|
|
192
196
|
3. Write or update tests as needed.
|
|
193
|
-
4. Open a pull request and move this
|
|
197
|
+
4. Open a pull request and move this issue to the review status.
|
|
194
198
|
```
|
|
195
199
|
|
|
196
|
-
#### GitHub Projects v2 (
|
|
200
|
+
#### GitHub Projects v2 (GitHub App)
|
|
201
|
+
|
|
202
|
+
Use GitHub App credentials instead of a PAT for fine-grained permissions and higher API rate limits:
|
|
197
203
|
|
|
198
204
|
```markdown
|
|
199
205
|
---
|
|
200
206
|
tracker:
|
|
201
207
|
kind: github_projects
|
|
202
|
-
|
|
208
|
+
app_id: $GITHUB_APP_ID
|
|
209
|
+
private_key: $GITHUB_APP_PRIVATE_KEY
|
|
210
|
+
installation_id: $GITHUB_APP_INSTALLATION_ID
|
|
203
211
|
owner: your-org
|
|
204
212
|
project_number: 42
|
|
205
213
|
active_statuses:
|
|
@@ -253,22 +261,19 @@ Your task:
|
|
|
253
261
|
4. Open a pull request and move this issue to the review status.
|
|
254
262
|
```
|
|
255
263
|
|
|
256
|
-
####
|
|
264
|
+
#### Asana (under development)
|
|
257
265
|
|
|
258
|
-
|
|
266
|
+
> **Note**: Asana support is under development. The configuration below is a preview and may change.
|
|
259
267
|
|
|
260
268
|
```markdown
|
|
261
269
|
---
|
|
262
270
|
tracker:
|
|
263
|
-
kind:
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
owner: your-org
|
|
268
|
-
project_number: 42
|
|
269
|
-
active_statuses:
|
|
271
|
+
kind: asana
|
|
272
|
+
api_key: $ASANA_ACCESS_TOKEN
|
|
273
|
+
project_gid: "1234567890123456"
|
|
274
|
+
active_sections:
|
|
270
275
|
- In Progress
|
|
271
|
-
|
|
276
|
+
terminal_sections:
|
|
272
277
|
- Done
|
|
273
278
|
- Cancelled
|
|
274
279
|
|
|
@@ -293,24 +298,41 @@ claude:
|
|
|
293
298
|
turn_timeout_ms: 3600000
|
|
294
299
|
---
|
|
295
300
|
|
|
296
|
-
You are working on
|
|
301
|
+
You are working on an Asana task for the project.
|
|
297
302
|
|
|
298
|
-
|
|
303
|
+
Task: {{ issue.title }}
|
|
299
304
|
|
|
300
305
|
{{ issue.description }}
|
|
306
|
+
|
|
307
|
+
{% if issue.blocked_by.size > 0 %}
|
|
308
|
+
Blocked by:
|
|
309
|
+
{% for blocker in issue.blocked_by %}
|
|
310
|
+
- {{ blocker.identifier }} ({{ blocker.state }})
|
|
311
|
+
{% endfor %}
|
|
312
|
+
{% endif %}
|
|
313
|
+
|
|
314
|
+
{% if attempt %}
|
|
315
|
+
This is attempt #{{ attempt }}. Review any prior work in the workspace before continuing.
|
|
316
|
+
{% endif %}
|
|
317
|
+
|
|
318
|
+
Your task:
|
|
319
|
+
1. Understand the task requirements.
|
|
320
|
+
2. Implement the requested changes.
|
|
321
|
+
3. Write or update tests as needed.
|
|
322
|
+
4. Open a pull request and move this task to the review section.
|
|
301
323
|
```
|
|
302
324
|
|
|
303
325
|
### Run
|
|
304
326
|
|
|
305
327
|
```bash
|
|
306
|
-
# Set your tracker token
|
|
307
|
-
export ASANA_ACCESS_TOKEN=your_token_here
|
|
308
|
-
# or (GitHub PAT)
|
|
328
|
+
# Set your tracker token (GitHub PAT)
|
|
309
329
|
export GITHUB_TOKEN=ghp_your_token_here
|
|
310
330
|
# or (GitHub App)
|
|
311
331
|
export GITHUB_APP_ID=12345
|
|
312
332
|
export GITHUB_APP_PRIVATE_KEY="$(cat path/to/private-key.pem)"
|
|
313
333
|
export GITHUB_APP_INSTALLATION_ID=67890
|
|
334
|
+
# or (Asana — under development)
|
|
335
|
+
export ASANA_ACCESS_TOKEN=your_token_here
|
|
314
336
|
|
|
315
337
|
# Run Work Please against a WORKFLOW.md in the current directory
|
|
316
338
|
bunx work-please
|
|
@@ -332,34 +354,34 @@ front matter configuration block with a Markdown prompt template body.
|
|
|
332
354
|
```yaml
|
|
333
355
|
---
|
|
334
356
|
tracker:
|
|
335
|
-
kind:
|
|
357
|
+
kind: github_projects # Required: "github_projects" or "asana"
|
|
336
358
|
|
|
337
|
-
# ---
|
|
338
|
-
api_key: $
|
|
339
|
-
endpoint: https://
|
|
340
|
-
|
|
341
|
-
|
|
359
|
+
# --- GitHub Projects v2 fields (when kind == "github_projects") ---
|
|
360
|
+
api_key: $GITHUB_TOKEN # Required: token or $ENV_VAR
|
|
361
|
+
endpoint: https://api.github.com # Optional: override GitHub API base URL
|
|
362
|
+
owner: your-org # Required: GitHub organization or user login
|
|
363
|
+
project_number: 42 # Required: GitHub Projects v2 project number
|
|
364
|
+
project_id: PVT_kwDOxxxxx # Optional: project node ID (bypasses owner+project_number lookup)
|
|
365
|
+
active_statuses: # Optional: default ["Todo", "In Progress"]
|
|
342
366
|
- In Progress
|
|
343
|
-
|
|
367
|
+
terminal_statuses: # Optional: default ["Done", "Cancelled"]
|
|
344
368
|
- Done
|
|
345
369
|
- Cancelled
|
|
346
|
-
|
|
347
|
-
# --- GitHub Projects v2 fields (when kind == "github_projects") ---
|
|
348
|
-
# api_key: $GITHUB_TOKEN # Required: token or $ENV_VAR
|
|
349
|
-
# endpoint: https://api.github.com # Optional: override GitHub API base URL
|
|
350
|
-
# owner: your-org # Required: GitHub organization or user login
|
|
351
|
-
# project_number: 42 # Required: GitHub Projects v2 project number
|
|
352
|
-
# project_id: PVT_kwDOxxxxx # Optional: project node ID (bypasses owner+project_number lookup)
|
|
353
|
-
# active_statuses: # Optional: default ["Todo", "In Progress"]
|
|
354
|
-
# - In Progress
|
|
355
|
-
# terminal_statuses: # Optional: default ["Done", "Cancelled"]
|
|
356
|
-
# - Done
|
|
357
|
-
# - Cancelled
|
|
358
370
|
# GitHub App authentication (alternative to api_key — all three required together):
|
|
359
371
|
# app_id: $GITHUB_APP_ID # Optional: GitHub App ID (integer or $ENV_VAR)
|
|
360
372
|
# private_key: $GITHUB_APP_PRIVATE_KEY # Optional: GitHub App private key PEM or $ENV_VAR
|
|
361
373
|
# installation_id: $GITHUB_APP_INSTALLATION_ID # Optional: installation ID (integer or $ENV_VAR)
|
|
362
374
|
|
|
375
|
+
# --- Asana fields (when kind == "asana") --- UNDER DEVELOPMENT
|
|
376
|
+
# api_key: $ASANA_ACCESS_TOKEN # Required: token or $ENV_VAR
|
|
377
|
+
# endpoint: https://app.asana.com/api/1.0 # Optional: override Asana API base URL
|
|
378
|
+
# project_gid: "1234567890123456" # Required: Asana project GID
|
|
379
|
+
# active_sections: # Optional: default ["To Do", "In Progress"]
|
|
380
|
+
# - In Progress
|
|
381
|
+
# terminal_sections: # Optional: default ["Done", "Cancelled"]
|
|
382
|
+
# - Done
|
|
383
|
+
# - Cancelled
|
|
384
|
+
|
|
363
385
|
# --- Shared filter fields (both trackers) ---
|
|
364
386
|
# filter:
|
|
365
387
|
# assignee: user1, user2 # Optional: CSV or YAML array; case-insensitive OR match
|
|
@@ -392,6 +414,7 @@ agent:
|
|
|
392
414
|
|
|
393
415
|
claude:
|
|
394
416
|
command: claude # Optional: Claude Code CLI command, default "claude"
|
|
417
|
+
effort: high # Optional: reasoning depth — 'low', 'medium', 'high', or 'max'. Default 'high'.
|
|
395
418
|
permission_mode: acceptEdits # Optional: one of 'default', 'acceptEdits', 'bypassPermissions'. Defaults to 'bypassPermissions'.
|
|
396
419
|
allowed_tools: # Optional: restrict available tools
|
|
397
420
|
- Read
|
package/dist/index.js
CHANGED
|
@@ -2166,7 +2166,7 @@ var {
|
|
|
2166
2166
|
var package_default = {
|
|
2167
2167
|
name: "@pleaseai/work",
|
|
2168
2168
|
type: "module",
|
|
2169
|
-
version: "0.1.
|
|
2169
|
+
version: "0.1.7",
|
|
2170
2170
|
description: "Symphony-spec orchestrator for Claude Code + Asana/GitHub Projects v2",
|
|
2171
2171
|
license: "FSL-1.1-MIT",
|
|
2172
2172
|
repository: {
|
|
@@ -31748,6 +31748,7 @@ class AppServerClient {
|
|
|
31748
31748
|
} else {
|
|
31749
31749
|
options.systemPrompt = sp;
|
|
31750
31750
|
}
|
|
31751
|
+
options.effort = this.config.claude.effort;
|
|
31751
31752
|
const toolSpecs = getToolSpecs(this.config);
|
|
31752
31753
|
if (toolSpecs.length > 0) {
|
|
31753
31754
|
options.mcpServers = {
|
|
@@ -31874,6 +31875,7 @@ var DEFAULTS2 = {
|
|
|
31874
31875
|
MAX_CONCURRENT_AGENTS: 10,
|
|
31875
31876
|
AGENT_MAX_TURNS: 20,
|
|
31876
31877
|
MAX_RETRY_BACKOFF_MS: 300000,
|
|
31878
|
+
CLAUDE_EFFORT: "high",
|
|
31877
31879
|
CLAUDE_COMMAND: "claude",
|
|
31878
31880
|
CLAUDE_PERMISSION_MODE: "bypassPermissions",
|
|
31879
31881
|
CLAUDE_ALLOWED_TOOLS: [],
|
|
@@ -31930,6 +31932,7 @@ function buildClaudeConfig(claude) {
|
|
|
31930
31932
|
const attributionSec = sectionMap(settingsSec, "attribution");
|
|
31931
31933
|
return {
|
|
31932
31934
|
model: stringValue(claude.model),
|
|
31935
|
+
effort: effortValue(claude.effort, DEFAULTS2.CLAUDE_EFFORT),
|
|
31933
31936
|
command: commandValue(claude.command) ?? DEFAULTS2.CLAUDE_COMMAND,
|
|
31934
31937
|
permission_mode: stringValue(claude.permission_mode) ?? DEFAULTS2.CLAUDE_PERMISSION_MODE,
|
|
31935
31938
|
allowed_tools: stringArrayValue(claude.allowed_tools, DEFAULTS2.CLAUDE_ALLOWED_TOOLS),
|
|
@@ -32120,6 +32123,18 @@ function hookScriptValue(val) {
|
|
|
32120
32123
|
const trimmed = val.trimEnd();
|
|
32121
32124
|
return trimmed === "" ? null : trimmed;
|
|
32122
32125
|
}
|
|
32126
|
+
function effortValue(val, fallback) {
|
|
32127
|
+
const s2 = typeof val === "string" ? val.trim() : val;
|
|
32128
|
+
switch (s2) {
|
|
32129
|
+
case "low":
|
|
32130
|
+
case "medium":
|
|
32131
|
+
case "high":
|
|
32132
|
+
case "max":
|
|
32133
|
+
return s2;
|
|
32134
|
+
default:
|
|
32135
|
+
return fallback;
|
|
32136
|
+
}
|
|
32137
|
+
}
|
|
32123
32138
|
function commandValue(val) {
|
|
32124
32139
|
if (typeof val !== "string")
|
|
32125
32140
|
return null;
|