@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.
Files changed (3) hide show
  1. package/README.md +82 -59
  2. package/dist/index.js +16 -1
  3. 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 (Asana or GitHub Projects v2) for tasks in configured active states.
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 Asana / GitHub Projects v2 and Claude Code instead of Linear and Codex.
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 | Asana & GitHub Projects v2 |
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` | `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 |
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 Asana tasks or GitHub Projects v2 items on a
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
- (Asana REST API or per-issue directory
94
- GitHub GraphQL API,
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
- Asana (REST API) and GitHub Projects v2 (GraphQL API) adapters.
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
- - **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)
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
- #### Asana
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: asana
143
- api_key: $ASANA_ACCESS_TOKEN
144
- project_gid: "1234567890123456"
145
- active_sections:
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
- terminal_sections:
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 an Asana task for the project.
176
+ You are working on a GitHub issue for the repository `your-org/your-repo`.
173
177
 
174
- Task: {{ issue.title }}
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 task requirements.
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 task to the review section.
197
+ 4. Open a pull request and move this issue to the review status.
194
198
  ```
195
199
 
196
- #### GitHub Projects v2 (PAT)
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
- api_key: $GITHUB_TOKEN
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
- #### GitHub Projects v2 (GitHub App)
264
+ #### Asana (under development)
257
265
 
258
- Use GitHub App credentials instead of a PAT for fine-grained permissions and higher API rate limits:
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: 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:
271
+ kind: asana
272
+ api_key: $ASANA_ACCESS_TOKEN
273
+ project_gid: "1234567890123456"
274
+ active_sections:
270
275
  - In Progress
271
- terminal_statuses:
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 a GitHub issue for the repository `your-org/your-repo`.
301
+ You are working on an Asana task for the project.
297
302
 
298
- Issue {{ issue.identifier }}: {{ issue.title }}
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: asana # Required: "asana" or "github_projects"
357
+ kind: github_projects # Required: "github_projects" or "asana"
336
358
 
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"]
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
- terminal_sections: # Optional: default ["Done", "Cancelled"]
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.6",
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;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@pleaseai/work",
3
3
  "type": "module",
4
- "version": "0.1.6",
4
+ "version": "0.1.7",
5
5
  "description": "Symphony-spec orchestrator for Claude Code + Asana/GitHub Projects v2",
6
6
  "license": "FSL-1.1-MIT",
7
7
  "repository": {