
Security News
The Hidden Blast Radius of the Axios Compromise
The Axios compromise shows how time-dependent dependency resolution makes exposure harder to detect and contain.
@pleaseai/agent
Advanced tools
Agent Please turns issue tracker tasks into isolated, autonomous implementation runs — managing work instead of supervising coding agents.
Warning: Agent Please is an engineering preview for use in trusted environments.
Agent Please is a long-running TypeScript service that:
It is a TypeScript implementation of the Symphony specification, adapted for GitHub Projects v2 / Asana and Claude Code instead of Linear and Codex.
For full technical details, see SPEC.md.
| Symphony (reference) | Agent Please | |
|---|---|---|
| Issue Tracker | Linear | GitHub Projects v2 & Asana (under development) |
| Coding Agent | Codex (app-server mode) | Claude Code CLI |
| Language | Elixir/OTP | TypeScript + Bun |
| Tracker Auth | LINEAR_API_KEY | GITHUB_TOKEN, GitHub App credentials, or ASANA_ACCESS_TOKEN |
| Project Config | project_slug | owner + project_number (GitHub Projects v2) or project_gid (Asana) |
| Issue States | Linear workflow states | GitHub Projects v2 Status field / Asana sections |
| Agent Protocol | JSON-RPC over stdio | @anthropic-ai/claude-agent-sdk |
| Permission Model | Codex approval/sandbox policies | Claude Code --permission-mode |
app_id + private_key + installation_id) instead of a PAT, for fine-grained
permissions and higher API rate limits.WORKFLOW.md.WORKFLOW.md config — Version agent prompt and runtime settings alongside your code.WORKFLOW.md and changes apply without restarting the service.after_create, before_run, after_run, and
before_remove lifecycle events.key=value format.--port for runtime status and JSON API.WORKFLOW.md
|
v
Config Layer ──> Orchestrator ──> Workspace Manager ──> Agent Runner (Claude Code)
| |
v v
Issue Tracker Client Isolated workspace/
(GitHub GraphQL API or per-issue directory
Asana REST API,
polling + reconciliation)
|
v
Status Surface (optional HTTP dashboard / structured logs)
Components:
WORKFLOW.md YAML front matter and prompt template body.See SPEC.md for the full specification.
GITHUB_TOKEN) with access to the target project, or GitHub App credentials
(GITHUB_APP_ID, GITHUB_APP_PRIVATE_KEY, GITHUB_APP_INSTALLATION_ID) — see GitHub App Authentication,
or Asana access token (ASANA_ACCESS_TOKEN) (under development)git clone https://github.com/pleaseai/agent-please.git
cd agent-please
bun install
bun run build
Create a WORKFLOW.md in your target repository. Two examples are shown below.
See also the example WORKFLOW.md for a real-world reference.
See also the example GitHub Project for a real-world reference.
---
platforms:
github:
api_key: $GITHUB_TOKEN
owner: your-org
bot_username: agent-please
projects:
- platform: github
project_number: 42
active_statuses:
- Todo
- In Progress
- Merging
- Rework
terminal_statuses:
- Closed
- Cancelled
- Canceled
- Duplicate
- Done
watched_statuses:
- Human Review
polling:
interval_ms: 30000
workspace:
root: ~/agent-please_workspaces
hooks:
after_create: |
git clone https://github.com/your-org/your-repo.git .
bun install
agent:
max_concurrent_agents: 3
max_turns: 20
claude:
permission_mode: acceptEdits
# setting_sources: [] # default: [project, local, user]; set [] for SDK isolation mode
turn_timeout_ms: 3600000
---
You are working on a GitHub issue for the repository `your-org/your-repo`.
Issue {{ issue.identifier }}: {{ issue.title }}
{{ issue.description }}
{% if issue.blocked_by.size > 0 %}
Blocked by:
{% for blocker in issue.blocked_by %}
- {{ blocker.identifier }} ({{ blocker.state }})
{% endfor %}
{% endif %}
{% if attempt %}
This is attempt #{{ attempt }}. Review any prior work in the workspace before continuing.
{% endif %}
Your task:
1. Understand the issue requirements.
2. Implement the requested changes.
3. Write or update tests as needed.
4. Open a pull request and move this issue to `Human Review`.
Use GitHub App credentials instead of a PAT for fine-grained permissions and higher API rate limits:
---
platforms:
github:
app_id: $GITHUB_APP_ID
private_key: $GITHUB_APP_PRIVATE_KEY
installation_id: $GITHUB_APP_INSTALLATION_ID
owner: your-org
bot_username: agent-please
projects:
- platform: github
project_number: 42
active_statuses:
- Todo
- In Progress
- Merging
- Rework
terminal_statuses:
- Closed
- Cancelled
- Canceled
- Duplicate
- Done
watched_statuses:
- Human Review
polling:
interval_ms: 30000
workspace:
root: ~/agent-please_workspaces
hooks:
after_create: |
git clone https://github.com/your-org/your-repo.git .
bun install
agent:
max_concurrent_agents: 3
max_turns: 20
claude:
permission_mode: acceptEdits
# setting_sources: [] # default: [project, local, user]; set [] for SDK isolation mode
turn_timeout_ms: 3600000
---
You are working on a GitHub issue for the repository `your-org/your-repo`.
Issue {{ issue.identifier }}: {{ issue.title }}
{{ issue.description }}
{% if issue.blocked_by.size > 0 %}
Blocked by:
{% for blocker in issue.blocked_by %}
- {{ blocker.identifier }} ({{ blocker.state }})
{% endfor %}
{% endif %}
{% if attempt %}
This is attempt #{{ attempt }}. Review any prior work in the workspace before continuing.
{% endif %}
Your task:
1. Understand the issue requirements.
2. Implement the requested changes.
3. Write or update tests as needed.
4. Open a pull request and move this issue to `Human Review`.
Note: Asana support is under development. The configuration below is a preview and may change.
---
platforms:
asana:
api_key: $ASANA_ACCESS_TOKEN
projects:
- platform: asana
project_gid: "1234567890123456"
active_sections:
- In Progress
terminal_sections:
- Done
- Cancelled
polling:
interval_ms: 30000
workspace:
root: ~/agent-please_workspaces
hooks:
after_create: |
git clone https://github.com/your-org/your-repo.git .
bun install
agent:
max_concurrent_agents: 3
max_turns: 20
claude:
permission_mode: acceptEdits
# setting_sources: [] # default: [project, local, user]; set [] for SDK isolation mode
turn_timeout_ms: 3600000
---
You are working on an Asana task for the project.
Task: {{ issue.title }}
{{ issue.description }}
{% if issue.blocked_by.size > 0 %}
Blocked by:
{% for blocker in issue.blocked_by %}
- {{ blocker.identifier }} ({{ blocker.state }})
{% endfor %}
{% endif %}
{% if attempt %}
This is attempt #{{ attempt }}. Review any prior work in the workspace before continuing.
{% endif %}
Your task:
1. Understand the task requirements.
2. Implement the requested changes.
3. Write or update tests as needed.
4. Open a pull request and move this task to the review section (e.g. `Human Review`).
# Set your tracker token (GitHub PAT)
export GITHUB_TOKEN=ghp_your_token_here
# or (GitHub App)
export GITHUB_APP_ID=12345
export GITHUB_APP_PRIVATE_KEY="$(cat path/to/private-key.pem)"
export GITHUB_APP_INSTALLATION_ID=67890
# or (Asana — under development)
export ASANA_ACCESS_TOKEN=your_token_here
# Run Agent Please against a WORKFLOW.md in the current directory
bunx agent-please
# Or specify a WORKFLOW.md path
bunx agent-please /path/to/WORKFLOW.md
# Enable the optional HTTP dashboard on port 3000
bunx agent-please --port 3000
WORKFLOW.md is the single source of truth for Agent Please's runtime behavior. It combines a YAML
front matter configuration block with a Markdown prompt template body.
---
platforms:
github: # Platform name used by projects[].platform and channels[].platform
api_key: $GITHUB_TOKEN # Required: token or $ENV_VAR (or use GitHub App fields below)
owner: your-org # Required unless projects[].project_id is set
bot_username: agent-please # Optional: bot display name for chat channels
endpoint: https://api.github.com # Optional: override GitHub API base URL
# GitHub App authentication (alternative to api_key — all three required together):
# app_id: $GITHUB_APP_ID # Optional: GitHub App ID (integer or $ENV_VAR)
# private_key: $GITHUB_APP_PRIVATE_KEY # Optional: GitHub App private key PEM or $ENV_VAR
# installation_id: $GITHUB_APP_INSTALLATION_ID # Optional: installation ID (integer or $ENV_VAR)
# asana: # UNDER DEVELOPMENT
# api_key: $ASANA_ACCESS_TOKEN # Required: token or $ENV_VAR
# endpoint: https://app.asana.com/api/1.0 # Optional: override Asana API base URL
# slack:
# bot_token: $SLACK_BOT_TOKEN
# signing_secret: $SLACK_SIGNING_SECRET
projects:
- platform: github # Required: must match a key in platforms
project_number: 42 # Required: GitHub Projects v2 project number
project_id: PVT_kwDOxxxxx # Optional: project node ID (bypasses owner+project_number lookup)
active_statuses: # Optional: default ["Todo", "In Progress", "Merging", "Rework"]
- Todo
- In Progress
- Merging
- Rework
terminal_statuses: # Optional: default ["Closed", "Cancelled", "Canceled", "Duplicate", "Done"]
- Closed
- Cancelled
- Canceled
- Duplicate
- Done
watched_statuses: # Optional: states polled for dispatch on review activity. Default ["Human Review"]
- Human Review
# filter:
# assignee: user1, user2 # Optional: CSV or YAML array; case-insensitive OR match
# # (unassigned issues are excluded when this filter is set)
# label: bug, feature # Optional: CSV or YAML array; case-insensitive OR match
# Both filters AND together when both are specified. Applies at dispatch time only.
# - platform: asana # UNDER DEVELOPMENT
# project_gid: "1234567890123456" # Required: Asana project GID
# active_sections: # Optional: default ["To Do", "In Progress"]
# - In Progress
# terminal_sections: # Optional: default ["Done", "Cancelled"]
# - Done
# - Cancelled
channels:
- platform: github # Required: must match a key in platforms
allowed_associations: # Optional: GitHub comment author associations permitted to trigger dispatch
- OWNER
- MEMBER
- COLLABORATOR
# - platform: slack
polling:
interval_ms: 30000 # Optional: poll cadence in ms, default 30000
workspace:
root: ~/agent-please_workspaces # Optional: default <tmpdir>/agent-please_workspaces
hooks:
after_create: | # Optional: run once when workspace is first created
git clone https://github.com/your-org/your-repo.git .
before_run: | # Optional: run before each agent attempt
git pull --rebase
after_run: | # Optional: run after each agent attempt
echo "Run completed"
before_remove: | # Optional: run before workspace deletion
echo "Cleaning up"
timeout_ms: 60000 # Optional: hook timeout in ms, default 60000
agent:
max_concurrent_agents: 10 # Optional: global concurrency limit, default 10
max_turns: 20 # Optional: max turns per agent run, default 20
max_retry_backoff_ms: 300000 # Optional: max retry delay in ms, default 300000
max_concurrent_agents_by_state: # Optional: per-state concurrency limits
in progress: 5
claude:
command: claude # Optional: Claude Code CLI command, default "claude"
model: claude-sonnet-4-5-20250514 # Optional: override Claude model. Default: CLI default
effort: high # Optional: reasoning depth — 'low', 'medium', 'high', or 'max'. Default 'high'.
permission_mode: acceptEdits # Optional: one of 'default', 'acceptEdits', 'bypassPermissions'. Defaults to 'bypassPermissions'.
allowed_tools: # Optional: restrict available tools
- Read
- Write
- Bash
setting_sources: # Optional: filesystem settings to load. Default: [project, local, user]
- project # load .claude/settings.json + CLAUDE.md from the workspace directory
- local # load .claude/settings.local.json from the workspace directory
- user # load ~/.claude/settings.json + global CLAUDE.md
# Only "project", "local", and "user" are valid — other values are ignored
turn_timeout_ms: 3600000 # Optional: per-turn timeout in ms, default 3600000
read_timeout_ms: 5000 # Optional: initial subprocess read timeout in ms, default 5000
stall_timeout_ms: 300000 # Optional: stall detection timeout, default 300000
system_prompt: "custom prompt" # Optional: custom system prompt string. Default: built-in claude_code preset
settings:
attribution:
commit: "🙏 Generated with [Agent Please](https://github.com/pleaseai/agent-please)" # Optional: appended to git commit messages. Defaults to Agent Please link.
pr: "🙏 Generated with [Agent Please](https://github.com/pleaseai/agent-please)" # Optional: appended to PR descriptions. Defaults to Agent Please link.
# worker: # Optional: SSH worker support (experimental)
# ssh_hosts: # List of SSH host aliases for remote execution
# - worker-1
# - worker-2
# max_concurrent_agents_per_host: 5 # Max agents per SSH host
# observability: # Optional: TUI dashboard settings
# dashboard_enabled: true # Enable TUI dashboard, default true
# refresh_ms: 1000 # Dashboard data refresh interval, default 1000
# render_interval_ms: 16 # TUI render interval, default 16
server:
port: 3000 # Optional: enable HTTP dashboard on this port
host: "127.0.0.1" # Optional: bind address, default "127.0.0.1"
# Webhook endpoints:
# GitHub: POST /api/webhooks/github (requires server.webhook.secret)
# Slack: POST /api/webhooks/slack (requires SLACK_BOT_TOKEN + SLACK_SIGNING_SECRET env vars)
---
Your prompt template goes here. Available variables:
- {{ issue.id }} — Tracker-internal issue ID
- {{ issue.identifier }} — Human-readable identifier (e.g. "#42" or task GID)
- {{ issue.title }} — Issue title
- {{ issue.description }} — Issue body/description
- {{ issue.state }} — Current tracker state name
- {{ issue.url }} — Issue URL
- {{ issue.assignees }} — Array of assignee logins (GitHub) or emails (Asana)
- {{ issue.labels }} — Array of label strings (normalized to lowercase)
- {{ issue.blocked_by }} — Array of blocker refs (each has id, identifier, state)
- {{ issue.branch_name }} — PR head branch name (for PullRequest items) or null
- {{ issue.pull_requests }} — Array of linked PRs (each has number, title, url, state, branch_name)
- {{ issue.review_decision }} — PR review decision: "approved", "changes_requested", "commented", "review_required", or null
- {{ issue.priority }} — Numeric priority or null
- {{ issue.created_at }} — ISO-8601 creation timestamp
- {{ issue.updated_at }} — ISO-8601 last-updated timestamp
- {{ issue.project }} — GitHub Projects v2 context (null for Asana):
- {{ issue.project.owner }} — Project owner login
- {{ issue.project.number }} — Project number
- {{ issue.project.project_id }} — Project GraphQL node ID (resolved at runtime)
- {{ issue.project.item_id }} — Project item GraphQL node ID
- {{ issue.project.field_id }} — Status field GraphQL node ID (resolved at runtime)
- {{ issue.project.status_options }} — Array of { name, id } for status field options
- {{ attempt }} — Retry attempt number (null on first run)
The prompt template uses Liquid-compatible syntax. All issue fields are available:
{{ issue.identifier }}: {{ issue.title }}
{{ issue.description }}
State: {{ issue.state }}
{% if issue.blocked_by.size > 0 %}
Blocked by:
{% for blocker in issue.blocked_by %}
- {{ blocker.identifier }} ({{ blocker.state }})
{% endfor %}
{% endif %}
{% if issue.pull_requests.size > 0 %}
Linked pull requests:
{% for pr in issue.pull_requests %}
- PR #{{ pr.number }}: {{ pr.title }} ({{ pr.state }}){% if pr.branch_name %} — branch: {{ pr.branch_name }}{% endif %}{% if pr.url %} — {{ pr.url }}{% endif %}
{% endfor %}
{% endif %}
{% if attempt %}
Retry attempt: {{ attempt }}
{% endif %}
# Basic usage (reads WORKFLOW.md from current directory)
agent-please
# Specify WORKFLOW.md path (positional argument)
agent-please ./WORKFLOW.md
# Enable HTTP dashboard
agent-please --port 3000
# Initialize a new GitHub Projects v2 project and scaffold WORKFLOW.md
# (Requires GITHUB_TOKEN environment variable to be set)
agent-please init --owner <org-or-user> --title "My Project"
# Alternatively, provide the token via a flag:
agent-please init --owner <org-or-user> --title "My Project" --token <your-github-token>
# Show help
agent-please --help
The github_projects tracker supports two authentication methods:
| Method | Config fields | When to use |
|---|---|---|
| PAT | api_key | Personal access tokens — quick setup |
| GitHub App | app_id, private_key, installation_id | Organizations — fine-grained permissions, higher rate limits |
When both are present, api_key (PAT) takes precedence.
Contents: Read-onlyIssues: Read & writePull requests: Read & writeProjects: Read & write.pem file) from the app's settings page.export GITHUB_APP_ID=12345
export GITHUB_APP_PRIVATE_KEY="$(cat /path/to/private-key.pem)"
export GITHUB_APP_INSTALLATION_ID=67890
WORKFLOW.md:platforms:
github:
app_id: $GITHUB_APP_ID
private_key: $GITHUB_APP_PRIVATE_KEY
installation_id: $GITHUB_APP_INSTALLATION_ID
owner: your-org
projects:
- platform: github
project_number: 42
The values can also be inlined directly (not recommended for secrets):
app_id: 12345
private_key: "-----BEGIN RSA PRIVATE KEY-----\n..."
installation_id: 67890
Agent Please validates GitHub App config at startup:
| Scenario | Result |
|---|---|
api_key set | PAT auth — app fields ignored |
All three app fields set (app_id, private_key, installation_id) | App auth |
| Only some app fields set | incomplete_github_app_config error |
| No auth configured | missing_tracker_api_key error |
Agent Please supports Slack as a notification channel via the Chat SDK Slack adapter. When configured, you can @mention the bot in any Slack channel to get real-time orchestrator status (running issues, retry queue, token usage).
SLACK_BOT_TOKEN=xoxb-... # Bot User OAuth Token
SLACK_SIGNING_SECRET=... # Signing secret for webhook verification
When both environment variables are set, the Slack adapter is automatically enabled alongside any configured tracker (GitHub Projects v2 or Asana).
Point your Slack app's Event Subscriptions and Interactivity request URL to:
https://your-domain.com/api/webhooks/slack
display_information:
name: Agent Please
description: Orchestrator status bot
features:
bot_user:
display_name: Agent Please
always_online: true
oauth_config:
scopes:
bot:
- app_mentions:read
- channels:history
- channels:read
- chat:write
- groups:history
- groups:read
- im:history
- im:read
- reactions:read
- reactions:write
- users:read
settings:
event_subscriptions:
request_url: https://your-domain.com/api/webhooks/slack
bot_events:
- app_mention
- message.channels
- message.groups
- message.im
interactivity:
is_enabled: true
request_url: https://your-domain.com/api/webhooks/slack
org_deploy_enabled: false
socket_mode_enabled: false
token_rotation_enabled: false
https://your-domain.com/api/webhooks/slack with your deployed webhook URL.SLACK_SIGNING_SECRET.xoxb-...) as SLACK_BOT_TOKEN.Agent Please runs Claude Code autonomously. Understand the trust implications before deploying.
| Mode | Behavior | Recommended For |
|---|---|---|
default | Interactive approval for sensitive operations | Development, unknown repositories |
acceptEdits | Auto-approve file edits; prompt for shell commands | Trusted codebases |
bypassPermissions | Auto-approve all operations | Sandboxed CI environments |
Start with default or acceptEdits unless you are running in a fully isolated environment.
workspace.root.acceptEdits permission mode as a baseline for most deployments.bypassPermissions only in network-isolated CI runners or Docker containers.agent.max_concurrent_agents conservatively when first testing.--port) or structured logs.Functional Source License 1.1, MIT Future License (FSL-1.1-MIT). See LICENSE for details.
FAQs
Autonomous coding agent for GitHub, Linear, and Slack
The npm package @pleaseai/agent receives a total of 824 weekly downloads. As such, @pleaseai/agent popularity was classified as not popular.
We found that @pleaseai/agent demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
The Axios compromise shows how time-dependent dependency resolution makes exposure harder to detect and contain.

Research
A supply chain attack on Axios introduced a malicious dependency, plain-crypto-js@4.2.1, published minutes earlier and absent from the project’s GitHub releases.

Research
Malicious versions of the Telnyx Python SDK on PyPI delivered credential-stealing malware via a multi-stage supply chain attack.