feat: add Asana bot integration#1
Conversation
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Terraform Validation Results
Pushed by: Will Smith (@wesmith4), Action: |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 3474e65d72
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "Codex (@codex) review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "Codex (@codex) address that feedback".
| response = await env.CONTROL_PLANE.fetch( | ||
| `https://internal/integration-settings/asana/resolved/${owner}/${name}`, | ||
| { headers } |
There was a problem hiding this comment.
Return Asana resolved settings from control-plane
In the checked control-plane route, handleGetResolvedConfig only handles github, linear, code-server, and sandbox before returning Unsupported integration, so this new Asana fetch always gets a non-OK response and falls back to DEFAULT_CONFIG. In any deployment using the Asana settings page, the bot therefore ignores enabledRepos, configured model/effort, user-override policy, and task instructions, which can let tasks run against repos that admins intended to disable.
Useful? React with 👍 / 👎.
| model, | ||
| createdAt: Date.now(), | ||
| }; | ||
| await storeTaskSession(env, taskGid, taskSession); |
There was a problem hiding this comment.
Clear task session state after prompt enqueue failure
When session creation succeeds but the subsequent /prompt call returns non-2xx, this task mapping has already been persisted (and a story webhook may have been created) before the function returns on the error path. For transient control-plane or DO failures, reassigning or mentioning the same Asana task later will hit the existing-session check and skip creating a usable session, while follow-up comments get sent to a session that never received the initial task prompt; either store this only after the prompt succeeds or delete the session/webhook state on failure.
Useful? React with 👍 / 👎.
Summary
Adds a new
@open-inspect/asana-botpackage — a Cloudflare Worker that turns Asana task activity into Open-Inspect coding sessions, mirroring the linear-bot architecture. Assigning a task to a dedicated Asana bot user creates a session; comments on active tasks forward as follow-up prompts; unassigning or completing the task stops the session. The bot reports back via task comments (working status, session link, PR link on completion).How it works
POST /admin/webhooks/setup(HMAC-authed), which registers a webhook on the bot's user task list — one webhook covers assignments across the whole workspace. Per-task story webhooks are registered when a session starts (follow-up comments) and cleaned up on stop. Optional per-project webhooks enable @mention triggers.X-Hook-Secretonly for hook IDs we minted (unique UUID target paths), stores per-webhook secrets in KV, verifiesX-Hook-Signature(HMAC-SHA256) with timing-safe comparison, dedupes batched events.repocustom field (owner/name) → LLM classifier fallback.<user_content>untrusted-content blocks, same as linear-bot.spawnSource: "asana-bot"; completion callbacks route through the newASANA_BOTbinding and post a task comment with the PR link. Tool-call callbacks are acknowledged but not surfaced (Asana has no ephemeral activity primitive — each would be a real comment).Cross-package changes
AsanaCallbackContext,"asana-bot"spawn source,"asana"message source,AsanaBotSettings+ integration definition. Also fixes a pre-existing bug where the plainSpawnSourceTS union was missing entries its zod schema had.ASANA_BOTservice binding, callback routing (case "asana"), identity resolution (asana:author IDs), analytics spawn sources, integration-settings validation.workers-asana.tf,asana_kvnamespace,enable_asana_bot+asana_pat/asana_bot_user_gid/asana_workspace_gidvariables with validation, control-plane service binding, outputs.Deployment
GET /users/me).enable_asana_bot = true,asana_pat,asana_bot_user_gid,asana_workspace_gidinterraform.tfvars; apply.curl -X POST https://<asana-bot-worker>/admin/webhooks/setupwith an internal HMAC bearer token.Docs:
packages/asana-bot/README.mdanddocs/integrations/ASANA.md.Testing
🤖 Generated with Claude Code