Asana
This skill provides a dependency-free Node.js CLI that calls the Asana REST API (v1) using a Personal Access Token (PAT).
- - Script: INLINECODE0
- Auth:
ASANA_PAT (preferred) or INLINECODE2 - Output: JSON only (stdout), suitable for agents and automation
Setup
- 1. Create an Asana PAT in your Asana account (Developer Console is not required for PAT usage).
- Provide the token to OpenClaw/Clawdbot as
ASANA_PAT.
Common injection patterns
- - Shell env (local testing):
INLINECODE4
- - OpenClaw config (recommended): set
skills.entries.asana.apiKey (or env.ASANA_PAT) so the secret is injected only for the agent run.
Configure via OpenClaw CLI (recommended)
This is the safest way to set the PAT because it keeps secrets out of prompts and ad-hoc shell history.
Recommended (apiKey → ASANA_PAT):
CODEBLOCK0
INLINECODE7 is a convenience field: for skills that declare metadata.openclaw.primaryEnv, OpenClaw injects apiKey into that env var for the agent run (this skill’s primary env is ASANA_PAT).
Alternative (explicit env):
CODEBLOCK1
Verify what is stored:
CODEBLOCK2
Remove a stored token:
CODEBLOCK3
Important: sandboxed runs
When a session is sandboxed, skill processes run inside Docker and do not inherit the host environment. In that case, skills.entries.*.env/apiKey applies to host runs only.
Set Docker env via:
- -
agents.defaults.sandbox.docker.env (or per-agent agents.list[].sandbox.docker.env) - or bake the env into your sandbox image
First calls (sanity + discovery)
INLINECODE14
INLINECODE15
- - (Recommended) Set a default workspace once:
INLINECODE16
ID resolution
When the user provides names (project/task/user), resolve to GIDs using one of:
- -
typeahead --workspace <gid> --resource_type project|task|user --query "..." (fast, best default) - INLINECODE18 (enumerate)
- INLINECODE19 (enumerate)
Avoid guessing a GID when multiple matches exist.
Core: tasks
List tasks assigned to a user (personal productivity)
INLINECODE20
List tasks in a project
INLINECODE21
Search tasks (Advanced Search API)
Canonical primitive: search-tasks (supports many filters; preferred over adding narrow “search helper” commands).
One-liner example (search within a project):
INLINECODE23
Useful filters:
- -
--assignee me|<gid|email> (maps to assignee.any) - INLINECODE26
- INLINECODE27 / INLINECODE28
- INLINECODE29 / INLINECODE30
- INLINECODE31 / INLINECODE32
Create / update / complete
INLINECODE33
INLINECODE34
INLINECODE35
Project manager workflows
This skill supports the workflows commonly expected from a PM in Asana:
- - Keep a project brief up to date (
upsert-project-brief) - Write status updates (
create-status-update) - Work with timelines (start/due dates) and shift schedules safely
- Use custom fields as first-class metadata
- Interpret blockers and dependency graphs (
project-blockers, dependencies, dependents)
Project brief
INLINECODE41
- - Upsert (create or update):
INLINECODE42
Status updates
INLINECODE43
INLINECODE44
Sections and moving tasks
INLINECODE45
INLINECODE46
Add a task to a project
Command: INLINECODE47
Calls POST /tasks/{task_gid}/addProject and supports optional section placement and ordering.
Examples:
INLINECODE49
With section + ordering:
INLINECODE50
(--section, --insert_before, and --insert_after are optional; when provided they are passed through in the request body.)
Remove a task from a project
Command: INLINECODE54
Calls POST /tasks/{task_gid}/removeProject.
Example:
INLINECODE56
Custom fields
Custom fields are critical for reliable PM automation.
- - List a project’s custom fields:
INLINECODE57
- - Read a custom field definition:
INLINECODE58
- - Set task custom fields on create/update:
INLINECODE59
Notes:
- - For enums, the value is typically the enum option GID.
- For numbers, send a JSON number.
Rich text, mentions, and reliability
Asana rich text fields are XML-valid HTML fragments wrapped in a <body> root element. The API rejects invalid XML or unsupported tags.
Key points:
- - Use
html_notes for task descriptions. - Use
html_text for comments/stories and status updates. - Avoid unsupported tags like
<p> and <br>; prefer literal newlines (\n) and <hr/> separators. - For mentions/links, use
<a data-asana-gid="..."></a> (or a self-closing <a .../>).
Mention notifications
Creating a mention link does not guarantee notification delivery if the user is not already assigned or following.
For reliable pings, do one of:
- - Assign the user first, then post the comment, OR
- Add the user as a follower, wait a few seconds, then post the comment
This skill supports the “add follower + wait” pattern:
INLINECODE69
Plain text comments (--text) do not create real @-mentions via the API; they remain plain text.
Attachments, uploads, and inline images
- - Upload a file attachment to a task:
INLINECODE71
- - Embed an existing image attachment inline (tasks + project briefs only):
INLINECODE72
Activity feed / “inbox-like” workflows
Asana does not provide a single universal “inbox” API for all notifications. The closest stable primitive is the Events endpoint scoped to a specific resource (project, task, etc.).
Use:
- -
events --resource <gid> to pull incremental changes on a project (or a user's "My Tasks" project) - The command stores a sync token locally so subsequent runs fetch only changes
Timeline shifting
- - Shift one task (optionally include subtasks):
INLINECODE74
- - Shift an entire project’s tasks:
INLINECODE75
Run with --dry_run true first, then re-run with --dry_run false.
Out of scope
- - Portfolios (premium) are intentionally omitted.
- “Bot personality” is not embedded here; configure behavior in your agent prompt.
Asana
此技能提供了一个无依赖的 Node.js CLI,通过个人访问令牌(PAT)调用 Asana REST API(v1)。
- - 脚本:{baseDir}/scripts/asana.mjs
- 认证方式:ASANAPAT(推荐)或 ASANATOKEN
- 输出:仅 JSON(标准输出),适用于智能体和自动化
设置
- 1. 在您的 Asana 账户中创建一个 Asana PAT(使用 PAT 不需要开发者控制台)。
- 将令牌作为 ASANA_PAT 提供给 OpenClaw/Clawdbot。
常见注入模式
export ASANA_PAT=...
- - OpenClaw 配置(推荐):设置 skills.entries.asana.apiKey(或 env.ASANA_PAT),以便仅在智能体运行时注入密钥。
通过 OpenClaw CLI 配置(推荐)
这是设置 PAT 最安全的方式,因为它可以将密钥排除在提示和临时 shell 历史之外。
推荐(apiKey → ASANA_PAT):
bash
openclaw config set skills.entries.asana.enabled true
openclaw config set skills.entries.asana.apiKey ASANAPATHERE
skills.entries.asana.apiKey 是一个便捷字段:对于声明了 metadata.openclaw.primaryEnv 的技能,OpenClaw 会在智能体运行时将 apiKey 注入到该环境变量中(此技能的主环境变量是 ASANA_PAT)。
替代方案(显式环境变量):
bash
openclaw config set skills.entries.asana.enabled true
openclaw config set skills.entries.asana.env.ASANAPAT ASANAPAT_HERE
验证存储的内容:
bash
openclaw config get skills.entries.asana
openclaw config get skills.entries.asana.enabled
openclaw config get skills.entries.asana.apiKey
删除已存储的令牌:
bash
openclaw config unset skills.entries.asana.apiKey
或
openclaw config unset skills.entries.asana.env.ASANA_PAT
重要提示:沙箱运行
当会话处于沙箱模式时,技能进程在 Docker 内运行,不会继承主机环境。在这种情况下,skills.entries.*.env/apiKey 仅适用于主机运行。
通过以下方式设置 Docker 环境变量:
- - agents.defaults.sandbox.docker.env(或按智能体设置 agents.list[].sandbox.docker.env)
- 或将环境变量烘焙到您的沙箱镜像中
首次调用(健康检查 + 发现)
node {baseDir}/scripts/asana.mjs me
node {baseDir}/scripts/asana.mjs workspaces
node {baseDir}/scripts/asana.mjs set-default-workspace --workspace
ID 解析
当用户提供名称(项目/任务/用户)时,使用以下方法之一解析为 GID:
- - typeahead --workspace --resource_type project|task|user --query ...(快速,最佳默认选项)
- projects --workspace --all(枚举)
- users --workspace --all(枚举)
当存在多个匹配项时,避免猜测 GID。
核心:任务
列出分配给用户的任务(个人生产力)
node {baseDir}/scripts/asana.mjs tasks-assigned --assignee me --workspace --all
列出项目中的任务
node {baseDir}/scripts/asana.mjs tasks-in-project --project --all
搜索任务(高级搜索 API)
规范原语:search-tasks(支持多种筛选条件;优于添加狭窄的“搜索辅助”命令)。
单行示例(在项目内搜索):
node {baseDir}/scripts/asana.mjs search-tasks --workspace --project --text ... --all
有用的筛选条件:
- - --assignee me|(映射到 assignee.any)
- --completed true|false
- --createdat.after / --modifiedat.after
- --dueon.before YYYY-MM-DD / --dueat.before
- --isblocked true|false / --isblocking true|false
创建 / 更新 / 完成
node {baseDir}/scripts/asana.mjs create-task --workspace --name ... --projects --assignee me
node {baseDir}/scripts/asana.mjs update-task gid> --name ... --dueon 2026-02-01
node {baseDir}/scripts/asana.mjs complete-task
项目经理工作流程
此技能支持项目经理在 Asana 中常见的预期工作流程:
- - 保持项目简报最新(upsert-project-brief)
- 编写状态更新(create-status-update)
- 处理时间线(开始/截止日期)并安全调整时间表
- 将自定义字段作为一等元数据使用
- 解读阻塞项和依赖关系图(project-blockers、dependencies、dependents)
项目简报
node {baseDir}/scripts/asana.mjs project-brief
node {baseDir}/scripts/asana.mjs upsert-project-brief gid> --title 项目简报 --htmltext ...
状态更新
node {baseDir}/scripts/asana.mjs create-status-update --parent gid> --statustype on_track --text 每周更新...
node {baseDir}/scripts/asana.mjs status-updates --parent --all
分区和移动任务
node {baseDir}/scripts/asana.mjs sections --project --all
node {baseDir}/scripts/asana.mjs create-section --project --name 已阻塞
将任务添加到项目
命令:add-task-to-project
调用 POST /tasks/{task_gid}/addProject,支持可选的分区放置和排序。
示例:
node {baseDir}/scripts/asana.mjs add-task-to-project gid> --project gid>
带分区和排序:
node {baseDir}/scripts/asana.mjs add-task-to-project gid> --project gid> --section gid> --insertbefore null --insert_after null
(--section、--insertbefore 和 --insertafter 是可选的;提供时将在请求体中传递。)
从项目中移除任务
命令:remove-task-from-project
调用 POST /tasks/{task_gid}/removeProject。
示例:
node {baseDir}/scripts/asana.mjs remove-task-from-project gid> --project gid>
自定义字段
自定义字段对于可靠的 PM 自动化至关重要。
node {baseDir}/scripts/asana.mjs project-custom-fields --all
node {baseDir}/scripts/asana.mjs custom-field fieldgid>
node {baseDir}/scripts/asana.mjs update-task gid> --customfields {fieldgid>:}
注意:
- - 对于枚举类型,值通常是枚举选项的 GID。
- 对于数字类型,发送 JSON 数字。
富文本、提及和可靠性
Asana 富文本字段是XML 有效的 HTML 片段,包裹在
根元素中。API 会拒绝无效的 XML 或不支持的标签。
关键点:
- - 任务描述使用 htmlnotes。
- 评论/动态和状态更新使用 htmltext。
- 避免使用不支持的标签如
和
;优先使用文字换行符(\n)和
分隔符。 - 对于提及/链接,使用 (或自闭合的 )。
提及通知
如果用户尚未被分配或关注,创建提及链接