@pleaseai/work 0.1.6 → 0.1.8

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.
Files changed (3) hide show
  1. package/README.md +152 -65
  2. package/dist/index.js +27949 -27080
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -1,5 +1,7 @@
1
1
  # Work Please
2
2
 
3
+ English | [한국어](README.ko.md) | [日本語](README.ja.md) | [简体中文](README.zh-CN.md)
4
+
3
5
  [![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=pleaseai_work-please&metric=alert_status)](https://sonarcloud.io/summary/new_code?id=pleaseai_work-please) [![Bugs](https://sonarcloud.io/api/project_badges/measure?project=pleaseai_work-please&metric=bugs)](https://sonarcloud.io/summary/new_code?id=pleaseai_work-please) [![Code Smells](https://sonarcloud.io/api/project_badges/measure?project=pleaseai_work-please&metric=code_smells)](https://sonarcloud.io/summary/new_code?id=pleaseai_work-please) [![Duplicated Lines (%)](https://sonarcloud.io/api/project_badges/measure?project=pleaseai_work-please&metric=duplicated_lines_density)](https://sonarcloud.io/summary/new_code?id=pleaseai_work-please)
4
6
  [![codecov](https://codecov.io/gh/pleaseai/work-please/graph/badge.svg?token=do858Z1lsI)](https://codecov.io/gh/pleaseai/work-please)
5
7
 
@@ -36,13 +38,13 @@ instead of supervising coding agents.
36
38
 
37
39
  Work Please is a long-running TypeScript service that:
38
40
 
39
- 1. Polls an issue tracker (Asana or GitHub Projects v2) for tasks in configured active states.
41
+ 1. Polls an issue tracker (GitHub Projects v2 or Asana) for tasks in configured active states.
40
42
  2. Creates an isolated workspace directory for each eligible issue.
41
43
  3. Launches a Claude Code agent session inside that workspace with a rendered prompt.
42
44
  4. Monitors the session, handles retries, and reconciles issue state on each poll cycle.
43
45
 
44
46
  It is a TypeScript implementation of the [Symphony specification](vendor/symphony/SPEC.md),
45
- adapted for Asana / GitHub Projects v2 and Claude Code instead of Linear and Codex.
47
+ adapted for GitHub Projects v2 / Asana and Claude Code instead of Linear and Codex.
46
48
 
47
49
  For full technical details, see [SPEC.md](SPEC.md).
48
50
 
@@ -50,18 +52,18 @@ For full technical details, see [SPEC.md](SPEC.md).
50
52
 
51
53
  | | Symphony (reference) | Work Please |
52
54
  |---|---|---|
53
- | Issue Tracker | Linear | Asana & GitHub Projects v2 |
55
+ | Issue Tracker | Linear | GitHub Projects v2 & Asana (under development) |
54
56
  | Coding Agent | Codex (app-server mode) | Claude Code CLI |
55
57
  | Language | Elixir/OTP | TypeScript + Bun |
56
- | Tracker Auth | `LINEAR_API_KEY` | `ASANA_ACCESS_TOKEN`, `GITHUB_TOKEN`, or GitHub App credentials |
57
- | Project Config | `project_slug` | `project_gid` (Asana) or `owner` + `project_number` (GitHub Projects v2) |
58
- | Issue States | Linear workflow states | Asana sections / GitHub Projects v2 Status field |
58
+ | Tracker Auth | `LINEAR_API_KEY` | `GITHUB_TOKEN`, GitHub App credentials, or `ASANA_ACCESS_TOKEN` |
59
+ | Project Config | `project_slug` | `owner` + `project_number` (GitHub Projects v2) or `project_gid` (Asana) |
60
+ | Issue States | Linear workflow states | GitHub Projects v2 Status field / Asana sections |
59
61
  | Agent Protocol | JSON-RPC over stdio | `@anthropic-ai/claude-agent-sdk` |
60
62
  | Permission Model | Codex approval/sandbox policies | Claude Code `--permission-mode` |
61
63
 
62
64
  ## Features
63
65
 
64
- - **Multi-tracker support** — Dispatch work from Asana tasks or GitHub Projects v2 items on a
66
+ - **Multi-tracker support** — Dispatch work from GitHub Projects v2 items or Asana tasks (under development) on a
65
67
  fixed cadence.
66
68
  - **GitHub App authentication** — Authenticate the GitHub tracker with a GitHub App installation
67
69
  token (`app_id` + `private_key` + `installation_id`) instead of a PAT, for fine-grained
@@ -90,8 +92,8 @@ Config Layer ──> Orchestrator ──> Workspace Manager ──> Agent Runner
90
92
  | |
91
93
  v v
92
94
  Issue Tracker Client Isolated workspace/
93
- (Asana REST API or per-issue directory
94
- GitHub GraphQL API,
95
+ (GitHub GraphQL API or per-issue directory
96
+ Asana REST API,
95
97
  polling + reconciliation)
96
98
  |
97
99
  v
@@ -103,7 +105,7 @@ Components:
103
105
  - **Workflow Loader** — Parses `WORKFLOW.md` YAML front matter and prompt template body.
104
106
  - **Config Layer** — Typed getters with env-var indirection and built-in defaults.
105
107
  - **Issue Tracker Client** — Fetches candidate issues, reconciles running-issue states. Supports
106
- Asana (REST API) and GitHub Projects v2 (GraphQL API) adapters.
108
+ GitHub Projects v2 (GraphQL API) and Asana (REST API) adapters.
107
109
  - **Orchestrator** — Owns in-memory state; drives the poll/dispatch/retry loop.
108
110
  - **Workspace Manager** — Creates, reuses, and cleans per-issue workspaces; runs hooks.
109
111
  - **Agent Runner** — Launches Claude Code, streams events back to the orchestrator.
@@ -117,14 +119,14 @@ See [SPEC.md](SPEC.md) for the full specification.
117
119
 
118
120
  - **Bun** (see [bun.sh](https://bun.sh) for installation)
119
121
  - **Claude Code CLI** (see the [official installation guide](https://docs.anthropic.com/en/docs/claude-code))
120
- - **Asana access token** (`ASANA_ACCESS_TOKEN`) **or** **GitHub token** (`GITHUB_TOKEN`) with
121
- access to the target project, **or** **GitHub App credentials** (`GITHUB_APP_ID`,
122
- `GITHUB_APP_PRIVATE_KEY`, `GITHUB_APP_INSTALLATION_ID`) see [GitHub App Authentication](#github-app-authentication)
122
+ - **GitHub token** (`GITHUB_TOKEN`) with access to the target project, **or** **GitHub App credentials**
123
+ (`GITHUB_APP_ID`, `GITHUB_APP_PRIVATE_KEY`, `GITHUB_APP_INSTALLATION_ID`) see [GitHub App Authentication](#github-app-authentication),
124
+ **or** **Asana access token** (`ASANA_ACCESS_TOKEN`) (under development)
123
125
 
124
126
  ### Install
125
127
 
126
128
  ```bash
127
- git clone https://github.com/chatbot-pf/work-please.git
129
+ git clone https://github.com/pleaseai/work-please.git
128
130
  cd work-please
129
131
  bun install
130
132
  bun run build
@@ -133,20 +135,36 @@ bun run build
133
135
  ### Configure
134
136
 
135
137
  Create a `WORKFLOW.md` in your target repository. Two examples are shown below.
138
+ See also the [example WORKFLOW.md](https://github.com/pleaseai/workflow/blob/main/WORKFLOW.md) for a real-world reference.
139
+
140
+ #### GitHub Projects v2 (PAT)
136
141
 
137
- #### Asana
142
+ See also the [example GitHub Project](https://github.com/orgs/pleaseai/projects/2) for a real-world reference.
138
143
 
139
144
  ```markdown
140
145
  ---
141
146
  tracker:
142
- kind: asana
143
- api_key: $ASANA_ACCESS_TOKEN
144
- project_gid: "1234567890123456"
145
- active_sections:
147
+ kind: github_projects
148
+ api_key: $GITHUB_TOKEN
149
+ owner: your-org
150
+ project_number: 42
151
+ active_statuses:
152
+ - Todo
146
153
  - In Progress
147
- terminal_sections:
148
- - Done
154
+ - Merging
155
+ - Rework
156
+ terminal_statuses:
157
+ - Closed
149
158
  - Cancelled
159
+ - Canceled
160
+ - Duplicate
161
+ - Done
162
+ watched_statuses:
163
+ - Human Review
164
+ auto_transitions:
165
+ human_review_to_rework: true
166
+ human_review_to_merging: true
167
+ include_bot_reviews: true
150
168
 
151
169
  polling:
152
170
  interval_ms: 30000
@@ -169,9 +187,9 @@ claude:
169
187
  turn_timeout_ms: 3600000
170
188
  ---
171
189
 
172
- You are working on an Asana task for the project.
190
+ You are working on a GitHub issue for the repository `your-org/your-repo`.
173
191
 
174
- Task: {{ issue.title }}
192
+ Issue {{ issue.identifier }}: {{ issue.title }}
175
193
 
176
194
  {{ issue.description }}
177
195
 
@@ -187,26 +205,42 @@ This is attempt #{{ attempt }}. Review any prior work in the workspace before co
187
205
  {% endif %}
188
206
 
189
207
  Your task:
190
- 1. Understand the task requirements.
208
+ 1. Understand the issue requirements.
191
209
  2. Implement the requested changes.
192
210
  3. Write or update tests as needed.
193
- 4. Open a pull request and move this task to the review section.
211
+ 4. Open a pull request and move this issue to `Human Review`.
194
212
  ```
195
213
 
196
- #### GitHub Projects v2 (PAT)
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:
197
217
 
198
218
  ```markdown
199
219
  ---
200
220
  tracker:
201
221
  kind: github_projects
202
- api_key: $GITHUB_TOKEN
222
+ app_id: $GITHUB_APP_ID
223
+ private_key: $GITHUB_APP_PRIVATE_KEY
224
+ installation_id: $GITHUB_APP_INSTALLATION_ID
203
225
  owner: your-org
204
226
  project_number: 42
205
227
  active_statuses:
228
+ - Todo
206
229
  - In Progress
230
+ - Merging
231
+ - Rework
207
232
  terminal_statuses:
208
- - Done
233
+ - Closed
209
234
  - Cancelled
235
+ - Canceled
236
+ - Duplicate
237
+ - Done
238
+ watched_statuses:
239
+ - Human Review
240
+ auto_transitions:
241
+ human_review_to_rework: true
242
+ human_review_to_merging: true
243
+ include_bot_reviews: true
210
244
 
211
245
  polling:
212
246
  interval_ms: 30000
@@ -250,25 +284,22 @@ Your task:
250
284
  1. Understand the issue requirements.
251
285
  2. Implement the requested changes.
252
286
  3. Write or update tests as needed.
253
- 4. Open a pull request and move this issue to the review status.
287
+ 4. Open a pull request and move this issue to `Human Review`.
254
288
  ```
255
289
 
256
- #### GitHub Projects v2 (GitHub App)
290
+ #### Asana (under development)
257
291
 
258
- Use GitHub App credentials instead of a PAT for fine-grained permissions and higher API rate limits:
292
+ > **Note**: Asana support is under development. The configuration below is a preview and may change.
259
293
 
260
294
  ```markdown
261
295
  ---
262
296
  tracker:
263
- kind: github_projects
264
- app_id: $GITHUB_APP_ID
265
- private_key: $GITHUB_APP_PRIVATE_KEY
266
- installation_id: $GITHUB_APP_INSTALLATION_ID
267
- owner: your-org
268
- project_number: 42
269
- active_statuses:
297
+ kind: asana
298
+ api_key: $ASANA_ACCESS_TOKEN
299
+ project_gid: "1234567890123456"
300
+ active_sections:
270
301
  - In Progress
271
- terminal_statuses:
302
+ terminal_sections:
272
303
  - Done
273
304
  - Cancelled
274
305
 
@@ -293,24 +324,41 @@ claude:
293
324
  turn_timeout_ms: 3600000
294
325
  ---
295
326
 
296
- You are working on a GitHub issue for the repository `your-org/your-repo`.
327
+ You are working on an Asana task for the project.
297
328
 
298
- Issue {{ issue.identifier }}: {{ issue.title }}
329
+ Task: {{ issue.title }}
299
330
 
300
331
  {{ issue.description }}
332
+
333
+ {% if issue.blocked_by.size > 0 %}
334
+ Blocked by:
335
+ {% for blocker in issue.blocked_by %}
336
+ - {{ blocker.identifier }} ({{ blocker.state }})
337
+ {% endfor %}
338
+ {% endif %}
339
+
340
+ {% if attempt %}
341
+ This is attempt #{{ attempt }}. Review any prior work in the workspace before continuing.
342
+ {% endif %}
343
+
344
+ Your task:
345
+ 1. Understand the task requirements.
346
+ 2. Implement the requested changes.
347
+ 3. Write or update tests as needed.
348
+ 4. Open a pull request and move this task to the review section (e.g. `Human Review`).
301
349
  ```
302
350
 
303
351
  ### Run
304
352
 
305
353
  ```bash
306
- # Set your tracker token
307
- export ASANA_ACCESS_TOKEN=your_token_here
308
- # or (GitHub PAT)
354
+ # Set your tracker token (GitHub PAT)
309
355
  export GITHUB_TOKEN=ghp_your_token_here
310
356
  # or (GitHub App)
311
357
  export GITHUB_APP_ID=12345
312
358
  export GITHUB_APP_PRIVATE_KEY="$(cat path/to/private-key.pem)"
313
359
  export GITHUB_APP_INSTALLATION_ID=67890
360
+ # or (Asana — under development)
361
+ export ASANA_ACCESS_TOKEN=your_token_here
314
362
 
315
363
  # Run Work Please against a WORKFLOW.md in the current directory
316
364
  bunx work-please
@@ -332,34 +380,46 @@ front matter configuration block with a Markdown prompt template body.
332
380
  ```yaml
333
381
  ---
334
382
  tracker:
335
- kind: asana # Required: "asana" or "github_projects"
383
+ kind: github_projects # Required: "github_projects" or "asana"
336
384
 
337
- # --- Asana fields (when kind == "asana") ---
338
- api_key: $ASANA_ACCESS_TOKEN # Required: token or $ENV_VAR
339
- endpoint: https://app.asana.com/api/1.0 # Optional: override Asana API base URL
340
- project_gid: "1234567890123456" # Required: Asana project GID
341
- active_sections: # Optional: default ["To Do", "In Progress"]
385
+ # --- GitHub Projects v2 fields (when kind == "github_projects") ---
386
+ api_key: $GITHUB_TOKEN # Required: token or $ENV_VAR
387
+ endpoint: https://api.github.com # Optional: override GitHub API base URL
388
+ owner: your-org # Required: GitHub organization or user login
389
+ project_number: 42 # Required: GitHub Projects v2 project number
390
+ project_id: PVT_kwDOxxxxx # Optional: project node ID (bypasses owner+project_number lookup)
391
+ active_statuses: # Optional: default ["Todo", "In Progress", "Merging", "Rework"]
392
+ - Todo
342
393
  - In Progress
343
- terminal_sections: # Optional: default ["Done", "Cancelled"]
344
- - Done
394
+ - Merging
395
+ - Rework
396
+ terminal_statuses: # Optional: default ["Closed", "Cancelled", "Canceled", "Duplicate", "Done"]
397
+ - Closed
345
398
  - 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
399
+ - Canceled
400
+ - Duplicate
401
+ - Done
402
+ watched_statuses: # Optional: states polled but not dispatched. Default ["Human Review"]
403
+ - Human Review
404
+ auto_transitions: # Optional: auto-transition rules for watched states
405
+ human_review_to_rework: true # Move to Rework on CHANGES_REQUESTED or unresolved threads. Default true
406
+ human_review_to_merging: true # Move to Merging on APPROVED + no unresolved threads. Default true
407
+ include_bot_reviews: true # Whether bot comment threads count as unresolved. Default true
358
408
  # GitHub App authentication (alternative to api_key — all three required together):
359
409
  # app_id: $GITHUB_APP_ID # Optional: GitHub App ID (integer or $ENV_VAR)
360
410
  # private_key: $GITHUB_APP_PRIVATE_KEY # Optional: GitHub App private key PEM or $ENV_VAR
361
411
  # installation_id: $GITHUB_APP_INSTALLATION_ID # Optional: installation ID (integer or $ENV_VAR)
362
412
 
413
+ # --- Asana fields (when kind == "asana") --- UNDER DEVELOPMENT
414
+ # api_key: $ASANA_ACCESS_TOKEN # Required: token or $ENV_VAR
415
+ # endpoint: https://app.asana.com/api/1.0 # Optional: override Asana API base URL
416
+ # project_gid: "1234567890123456" # Required: Asana project GID
417
+ # active_sections: # Optional: default ["To Do", "In Progress"]
418
+ # - In Progress
419
+ # terminal_sections: # Optional: default ["Done", "Cancelled"]
420
+ # - Done
421
+ # - Cancelled
422
+
363
423
  # --- Shared filter fields (both trackers) ---
364
424
  # filter:
365
425
  # assignee: user1, user2 # Optional: CSV or YAML array; case-insensitive OR match
@@ -386,12 +446,15 @@ hooks:
386
446
 
387
447
  agent:
388
448
  max_concurrent_agents: 10 # Optional: global concurrency limit, default 10
449
+ max_turns: 20 # Optional: max turns per agent run, default 20
389
450
  max_retry_backoff_ms: 300000 # Optional: max retry delay in ms, default 300000
390
451
  max_concurrent_agents_by_state: # Optional: per-state concurrency limits
391
452
  in progress: 5
392
453
 
393
454
  claude:
394
455
  command: claude # Optional: Claude Code CLI command, default "claude"
456
+ model: claude-sonnet-4-5-20250514 # Optional: override Claude model. Default: CLI default
457
+ effort: high # Optional: reasoning depth — 'low', 'medium', 'high', or 'max'. Default 'high'.
395
458
  permission_mode: acceptEdits # Optional: one of 'default', 'acceptEdits', 'bypassPermissions'. Defaults to 'bypassPermissions'.
396
459
  allowed_tools: # Optional: restrict available tools
397
460
  - Read
@@ -405,13 +468,26 @@ claude:
405
468
  turn_timeout_ms: 3600000 # Optional: per-turn timeout in ms, default 3600000
406
469
  read_timeout_ms: 5000 # Optional: initial subprocess read timeout in ms, default 5000
407
470
  stall_timeout_ms: 300000 # Optional: stall detection timeout, default 300000
471
+ system_prompt: "custom prompt" # Optional: custom system prompt string. Default: built-in claude_code preset
408
472
  settings:
409
473
  attribution:
410
474
  commit: "🙏 Generated with [Work Please](https://github.com/pleaseai/work-please)" # Optional: appended to git commit messages. Defaults to Work Please link.
411
475
  pr: "🙏 Generated with [Work Please](https://github.com/pleaseai/work-please)" # Optional: appended to PR descriptions. Defaults to Work Please link.
412
476
 
477
+ # worker: # Optional: SSH worker support (experimental)
478
+ # ssh_hosts: # List of SSH host aliases for remote execution
479
+ # - worker-1
480
+ # - worker-2
481
+ # max_concurrent_agents_per_host: 5 # Max agents per SSH host
482
+
483
+ # observability: # Optional: TUI dashboard settings
484
+ # dashboard_enabled: true # Enable TUI dashboard, default true
485
+ # refresh_ms: 1000 # Dashboard data refresh interval, default 1000
486
+ # render_interval_ms: 16 # TUI render interval, default 16
487
+
413
488
  server:
414
489
  port: 3000 # Optional: enable HTTP dashboard on this port
490
+ host: "127.0.0.1" # Optional: bind address, default "127.0.0.1"
415
491
  ---
416
492
 
417
493
  Your prompt template goes here. Available variables:
@@ -425,10 +501,21 @@ Your prompt template goes here. Available variables:
425
501
  - {{ issue.assignees }} — Array of assignee logins (GitHub) or emails (Asana)
426
502
  - {{ issue.labels }} — Array of label strings (normalized to lowercase)
427
503
  - {{ issue.blocked_by }} — Array of blocker refs (each has id, identifier, state)
504
+ - {{ issue.branch_name }} — PR head branch name (for PullRequest items) or null
428
505
  - {{ issue.pull_requests }} — Array of linked PRs (each has number, title, url, state, branch_name)
506
+ - {{ issue.review_decision }} — PR review decision: "approved", "changes_requested", "commented", "review_required", or null
507
+ - {{ issue.has_unresolved_threads }} — Whether the PR has unresolved review threads
508
+ - {{ issue.has_unresolved_human_threads }} — Whether the PR has unresolved non-bot review threads
429
509
  - {{ issue.priority }} — Numeric priority or null
430
510
  - {{ issue.created_at }} — ISO-8601 creation timestamp
431
511
  - {{ issue.updated_at }} — ISO-8601 last-updated timestamp
512
+ - {{ issue.project }} — GitHub Projects v2 context (null for Asana):
513
+ - {{ issue.project.owner }} — Project owner login
514
+ - {{ issue.project.number }} — Project number
515
+ - {{ issue.project.project_id }} — Project GraphQL node ID (resolved at runtime)
516
+ - {{ issue.project.item_id }} — Project item GraphQL node ID
517
+ - {{ issue.project.field_id }} — Status field GraphQL node ID (resolved at runtime)
518
+ - {{ issue.project.status_options }} — Array of { name, id } for status field options
432
519
  - {{ attempt }} — Retry attempt number (null on first run)
433
520
  ```
434
521
 
@@ -578,7 +665,7 @@ Start with `default` or `acceptEdits` unless you are running in a fully isolated
578
665
 
579
666
  ## License
580
667
 
581
- Apache License 2.0. See [LICENSE](vendor/symphony/LICENSE) for details.
668
+ Functional Source License 1.1, MIT Future License (FSL-1.1-MIT). See [LICENSE](LICENSE) for details.
582
669
 
583
670
  Work Please is a TypeScript implementation based on the
584
671
  [Symphony specification](vendor/symphony/SPEC.md) by OpenAI (Apache 2.0).