@llodev/pm-tasks-asana 1.2.1 → 1.3.1

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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,36 @@
1
1
  # @llodev/pm-tasks-asana
2
2
 
3
+ ## 1.3.1
4
+
5
+ ### Patch Changes
6
+
7
+ - chore: reorganize repo structure
8
+
9
+ Pure chore release. Zero runtime change. Splits across:
10
+
11
+ - Reorganized root `scripts/` into `checks/`, `snapshots/`, `shell/` subfolders.
12
+ - Dropped `SKILL.{pt-BR,es-ES}.md` translations (agents read canonical EN-only per agentskills.io spec).
13
+ - Moved localized READMEs to `docs/i18n/` in root + each package (anticipates 5+ locales without cluttering package roots).
14
+ - Updated validators (`validate-localized-paths.mjs`) and tarball snapshot for new paths.
15
+
16
+ Skill-judge: bypassed with `SKIP_SKILL_JUDGE_GATE=1` — only SKILL.md change was decorative readme-selector block removal; expected delta = 0 (cosmetic-only). Per NOISE_BAND policy [-2, +2] bypass allowed.
17
+
18
+ Meta package `@llodev/pm-tasks` not bumped — no tarball content changes, only peerDeps inheritance.
19
+
20
+ - Updated dependencies []:
21
+ - @llodev/pm-tasks-core@1.3.2
22
+
23
+ ## 1.3.0
24
+
25
+ ### Minor Changes
26
+
27
+ - Introduce adapter `manifest.json` + custom-verbs extension API. Each adapter now declares which canonical verbs it implements plus any tool-specific verbs under a `<tool>.*` namespace. `contract-check.mjs` validates the manifest against `adapter-manifest.schema.json`, enforces the `<tool>.<verb>` namespace prefix, and cross-checks each declared verb against the adapter's `SKILL.md`. The same gate now permits additive-only changes to `contract.md` as non-major (deletions still require major). No runtime behaviour changes for existing consumers.
28
+
29
+ ### Patch Changes
30
+
31
+ - Updated dependencies []:
32
+ - @llodev/pm-tasks-core@1.3.0
33
+
3
34
  ## 1.2.1
4
35
 
5
36
  ### Patch Changes
package/README.md CHANGED
@@ -1,8 +1,8 @@
1
1
  <!-- readme-selector:start -->
2
2
  <p align="center">
3
3
  <a href="https://github.com/llodev/skills/blob/main/pm-tasks/pm-tasks-asana/README.md"><img src="https://raw.githubusercontent.com/lloliveiradev/public-assets/main/images/usa.svg" width="30" alt="English"></a>&nbsp;&nbsp;
4
- <a href="https://github.com/llodev/skills/blob/main/pm-tasks/pm-tasks-asana/README.pt-BR.md"><img src="https://raw.githubusercontent.com/lloliveiradev/public-assets/main/images/brazil.svg" width="30" alt="Português"></a>&nbsp;&nbsp;
5
- <a href="https://github.com/llodev/skills/blob/main/pm-tasks/pm-tasks-asana/README.es-ES.md"><img src="https://raw.githubusercontent.com/lloliveiradev/public-assets/main/images/spain.svg" width="30" alt="Español"></a>
4
+ <a href="https://github.com/llodev/skills/blob/main/pm-tasks/pm-tasks-asana/docs/i18n/README.pt-BR.md"><img src="https://raw.githubusercontent.com/lloliveiradev/public-assets/main/images/brazil.svg" width="30" alt="Português"></a>&nbsp;&nbsp;
5
+ <a href="https://github.com/llodev/skills/blob/main/pm-tasks/pm-tasks-asana/docs/i18n/README.es-ES.md"><img src="https://raw.githubusercontent.com/lloliveiradev/public-assets/main/images/spain.svg" width="30" alt="Español"></a>
6
6
  </p>
7
7
  <!-- readme-selector:end -->
8
8
 
package/SKILL.md CHANGED
@@ -15,7 +15,7 @@ description: >-
15
15
  @llodev/pm-tasks-core installed.
16
16
  license: MIT
17
17
  metadata:
18
- version: 1.2.1
18
+ version: 1.3.1
19
19
  tags:
20
20
  - agent-skill
21
21
  - asana
@@ -34,14 +34,6 @@ compatibility:
34
34
  - roo-code
35
35
  ---
36
36
 
37
- <!-- readme-selector:start -->
38
- <p align="center">
39
- <a href="https://github.com/llodev/skills/blob/main/pm-tasks/pm-tasks-asana/SKILL.md"><img src="https://raw.githubusercontent.com/lloliveiradev/public-assets/main/images/usa.svg" width="30" alt="English"></a>&nbsp;&nbsp;
40
- <a href="https://github.com/llodev/skills/blob/main/pm-tasks/pm-tasks-asana/SKILL.pt-BR.md"><img src="https://raw.githubusercontent.com/lloliveiradev/public-assets/main/images/brazil.svg" width="30" alt="Português"></a>&nbsp;&nbsp;
41
- <a href="https://github.com/llodev/skills/blob/main/pm-tasks/pm-tasks-asana/SKILL.es-ES.md"><img src="https://raw.githubusercontent.com/lloliveiradev/public-assets/main/images/spain.svg" width="30" alt="Español"></a>
42
- </p>
43
- <!-- readme-selector:end -->
44
-
45
37
  # pm-tasks-asana
46
38
 
47
39
  Adapter for Asana within the `@llodev/pm-tasks-*` family. Use the core skill's extraction phases, then apply Asana formatting and optionally publish/operate via the `claude.ai Asana` MCP server.
@@ -1,8 +1,8 @@
1
1
  <!-- readme-selector:start -->
2
2
  <p align="center">
3
3
  <a href="https://github.com/llodev/skills/blob/main/pm-tasks/pm-tasks-asana/README.md"><img src="https://raw.githubusercontent.com/lloliveiradev/public-assets/main/images/usa.svg" width="30" alt="English"></a>&nbsp;&nbsp;
4
- <a href="https://github.com/llodev/skills/blob/main/pm-tasks/pm-tasks-asana/README.pt-BR.md"><img src="https://raw.githubusercontent.com/lloliveiradev/public-assets/main/images/brazil.svg" width="30" alt="Português"></a>&nbsp;&nbsp;
5
- <a href="https://github.com/llodev/skills/blob/main/pm-tasks/pm-tasks-asana/README.es-ES.md"><img src="https://raw.githubusercontent.com/lloliveiradev/public-assets/main/images/spain.svg" width="30" alt="Español"></a>
4
+ <a href="https://github.com/llodev/skills/blob/main/pm-tasks/pm-tasks-asana/docs/i18n/README.pt-BR.md"><img src="https://raw.githubusercontent.com/lloliveiradev/public-assets/main/images/brazil.svg" width="30" alt="Português"></a>&nbsp;&nbsp;
5
+ <a href="https://github.com/llodev/skills/blob/main/pm-tasks/pm-tasks-asana/docs/i18n/README.es-ES.md"><img src="https://raw.githubusercontent.com/lloliveiradev/public-assets/main/images/spain.svg" width="30" alt="Español"></a>
6
6
  </p>
7
7
  <!-- readme-selector:end -->
8
8
 
@@ -11,7 +11,7 @@
11
11
  > Adapter para Asana de la familia `@llodev/pm-tasks-*` — convierte planes de implementación en parent tasks + subtasks de Asana y los opera mediante paste, MCP publish o autonomous write-through.
12
12
 
13
13
  [![npm](https://img.shields.io/npm/v/@llodev/pm-tasks-asana?label=npm&color=cb3837&logo=npm)](https://www.npmjs.com/package/@llodev/pm-tasks-asana)
14
- [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
14
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](../../LICENSE)
15
15
  [![Node.js >= 20](https://img.shields.io/badge/node-%3E%3D20-43853d?logo=node.js&logoColor=white)](https://nodejs.org)
16
16
  [![Agent Skills spec](https://img.shields.io/badge/Agent_Skills-spec-7c5cff)](https://agentskills.io)
17
17
 
@@ -86,15 +86,15 @@ El prompt de `init` imprime la ruta absoluta donde va a escribir, así siempre v
86
86
  > **Los custom fields NO se heredan por defecto** — lista los IDs de field en `subtaskDefaults.inheritParentFields` para que el adapter los copie del parent a las subtasks en el momento del create.
87
87
 
88
88
  - **Assignee es un campo único** — usa `task.assignee.add` para añadir followers; el assignee principal se reemplaza en caso de conflicto.
89
- - **El `get_task` del MCP no devuelve activity stories** — el activity feed de la UI de Asana es la fuente de verdad para auditorías de atribución. Mira [`anti-patterns/asana.md`](./anti-patterns/asana.md).
89
+ - **El `get_task` del MCP no devuelve activity stories** — el activity feed de la UI de Asana es la fuente de verdad para auditorías de atribución. Mira [`anti-patterns/asana.md`](../../anti-patterns/asana.md).
90
90
 
91
91
  ## Documentación
92
92
 
93
- - [`SKILL.md`](./SKILL.md) — enrutado de phases + vocabulario CRUD.
94
- - [`schemas/config.json`](./schemas/config.json) — JSON Schema de `.asana.json`.
95
- - [`anti-patterns/asana.md`](./anti-patterns/asana.md) — gotchas recurrentes.
96
- - [`../pm-tasks-core/references/autonomous-mode.md`](../pm-tasks-core/references/autonomous-mode.md) — contrato de autonomous mode.
93
+ - [`SKILL.md`](../../SKILL.md) — enrutado de phases + vocabulario CRUD.
94
+ - [`schemas/config.json`](../../schemas/config.json) — JSON Schema de `.asana.json`.
95
+ - [`anti-patterns/asana.md`](../../anti-patterns/asana.md) — gotchas recurrentes.
96
+ - [`../pm-tasks-core/references/autonomous-mode.md`](../../../pm-tasks-core/references/autonomous-mode.md) — contrato de autonomous mode.
97
97
 
98
98
  ## Licencia
99
99
 
100
- MIT — mira [LICENSE](./LICENSE).
100
+ MIT — mira [LICENSE](../../LICENSE).
@@ -1,8 +1,8 @@
1
1
  <!-- readme-selector:start -->
2
2
  <p align="center">
3
3
  <a href="https://github.com/llodev/skills/blob/main/pm-tasks/pm-tasks-asana/README.md"><img src="https://raw.githubusercontent.com/lloliveiradev/public-assets/main/images/usa.svg" width="30" alt="English"></a>&nbsp;&nbsp;
4
- <a href="https://github.com/llodev/skills/blob/main/pm-tasks/pm-tasks-asana/README.pt-BR.md"><img src="https://raw.githubusercontent.com/lloliveiradev/public-assets/main/images/brazil.svg" width="30" alt="Português"></a>&nbsp;&nbsp;
5
- <a href="https://github.com/llodev/skills/blob/main/pm-tasks/pm-tasks-asana/README.es-ES.md"><img src="https://raw.githubusercontent.com/lloliveiradev/public-assets/main/images/spain.svg" width="30" alt="Español"></a>
4
+ <a href="https://github.com/llodev/skills/blob/main/pm-tasks/pm-tasks-asana/docs/i18n/README.pt-BR.md"><img src="https://raw.githubusercontent.com/lloliveiradev/public-assets/main/images/brazil.svg" width="30" alt="Português"></a>&nbsp;&nbsp;
5
+ <a href="https://github.com/llodev/skills/blob/main/pm-tasks/pm-tasks-asana/docs/i18n/README.es-ES.md"><img src="https://raw.githubusercontent.com/lloliveiradev/public-assets/main/images/spain.svg" width="30" alt="Español"></a>
6
6
  </p>
7
7
  <!-- readme-selector:end -->
8
8
 
@@ -11,7 +11,7 @@
11
11
  > Adapter para Asana da família `@llodev/pm-tasks-*` — transforma planos de implementação em parent tasks + subtasks no Asana e opera via paste, MCP publish ou autonomous write-through.
12
12
 
13
13
  [![npm](https://img.shields.io/npm/v/@llodev/pm-tasks-asana?label=npm&color=cb3837&logo=npm)](https://www.npmjs.com/package/@llodev/pm-tasks-asana)
14
- [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
14
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](../../LICENSE)
15
15
  [![Node.js >= 20](https://img.shields.io/badge/node-%3E%3D20-43853d?logo=node.js&logoColor=white)](https://nodejs.org)
16
16
  [![Agent Skills spec](https://img.shields.io/badge/Agent_Skills-spec-7c5cff)](https://agentskills.io)
17
17
 
@@ -86,15 +86,15 @@ O prompt de `init` imprime o caminho absoluto onde vai escrever, então você se
86
86
  > **Custom fields NÃO são herdados por default** — liste os IDs de field em `subtaskDefaults.inheritParentFields` para que o adapter copie do parent para as subtasks no momento do create.
87
87
 
88
88
  - **Assignee é um campo único** — use `task.assignee.add` para adicionar followers; o assignee primário é substituído em caso de conflito.
89
- - **O `get_task` do MCP não retorna activity stories** — o activity feed da UI do Asana é a fonte de verdade para auditorias de atribuição. Veja [`anti-patterns/asana.md`](./anti-patterns/asana.md).
89
+ - **O `get_task` do MCP não retorna activity stories** — o activity feed da UI do Asana é a fonte de verdade para auditorias de atribuição. Veja [`anti-patterns/asana.md`](../../anti-patterns/asana.md).
90
90
 
91
91
  ## Documentação
92
92
 
93
- - [`SKILL.md`](./SKILL.md) — roteamento de phases + vocabulário CRUD.
94
- - [`schemas/config.json`](./schemas/config.json) — JSON Schema do `.asana.json`.
95
- - [`anti-patterns/asana.md`](./anti-patterns/asana.md) — pegadinhas recorrentes.
96
- - [`../pm-tasks-core/references/autonomous-mode.md`](../pm-tasks-core/references/autonomous-mode.md) — contrato do autonomous mode.
93
+ - [`SKILL.md`](../../SKILL.md) — roteamento de phases + vocabulário CRUD.
94
+ - [`schemas/config.json`](../../schemas/config.json) — JSON Schema do `.asana.json`.
95
+ - [`anti-patterns/asana.md`](../../anti-patterns/asana.md) — pegadinhas recorrentes.
96
+ - [`../pm-tasks-core/references/autonomous-mode.md`](../../../pm-tasks-core/references/autonomous-mode.md) — contrato do autonomous mode.
97
97
 
98
98
  ## Licença
99
99
 
100
- MIT — veja [LICENSE](./LICENSE).
100
+ MIT — veja [LICENSE](../../LICENSE).
package/manifest.json ADDED
@@ -0,0 +1,11 @@
1
+ {
2
+ "tool": "asana",
3
+ "verbs": [
4
+ "task.create",
5
+ "task.close",
6
+ "task.due-date.set",
7
+ "task.assignee.add",
8
+ "task.comment.add",
9
+ "checklist.check"
10
+ ]
11
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@llodev/pm-tasks-asana",
3
- "version": "1.2.1",
3
+ "version": "1.3.1",
4
4
  "description": "Asana adapter for the @llodev/pm-tasks-* family. Use when the user mentions Asana (create Asana task, publish to Asana, post to Asana, add comment in Asana, --publish-asana, close task, check subtask) or wants to publish a plan as Asana tasks with subtasks. Modes: paste-ready (no MCP needed), MCP publish (via claude.ai Asana MCP), autonomous (sentinel [autonomous] / --auto). Implements 6 CRUD verbs from @llodev/pm-tasks-core/references/contract.md mapped to Asana (parent task + subtasks, custom fields, sections, multi-assignee). REQUIRES: @llodev/pm-tasks-core installed (skillpm / Claude Code marketplace cascade auto; Vercel CLI users install manually).",
5
5
  "license": "MIT",
6
6
  "homepage": "https://github.com/llodev/skills/tree/main/pm-tasks/pm-tasks-asana",
@@ -11,18 +11,16 @@
11
11
  },
12
12
  "files": [
13
13
  "SKILL.md",
14
- "SKILL.pt-BR.md",
15
- "SKILL.es-ES.md",
16
14
  "README.md",
17
- "README.pt-BR.md",
18
- "README.es-ES.md",
15
+ "docs",
19
16
  "schemas",
20
17
  "references",
21
18
  "anti-patterns",
22
19
  "scripts",
23
20
  "i18n",
24
21
  "LICENSE",
25
- "CHANGELOG.md"
22
+ "CHANGELOG.md",
23
+ "manifest.json"
26
24
  ],
27
25
  "keywords": [
28
26
  "agent-skill",
@@ -36,7 +34,7 @@
36
34
  "pm-tasks-asana": "./scripts/init.mjs"
37
35
  },
38
36
  "dependencies": {
39
- "@llodev/pm-tasks-core": "^1.2.1"
37
+ "@llodev/pm-tasks-core": "^1.3.2"
40
38
  },
41
39
  "publishConfig": {
42
40
  "access": "public"
package/SKILL.es-ES.md DELETED
@@ -1,170 +0,0 @@
1
- ---
2
- name: pm-tasks-asana
3
- description: >-
4
- Asana adapter for the @llodev/pm-tasks-* family. Use when the user mentions
5
- Asana, asks to "create Asana task", "publish to Asana", "post to Asana",
6
- "publish", "add comment in Asana", or uses --publish-asana; OR for CRUD on
7
- existing tasks (check subtask, close task, change due-date, assign person,
8
- comment); OR when invoked autonomously by another agent with [autonomous] /
9
- --auto sentinel. Asana hierarchy: workspace > project > section > parent task
10
- > subtasks (one level), with custom fields and multi-assignee support. Modes:
11
- paste-ready (no MCP needed), MCP publish (via claude.ai Asana MCP), autonomous
12
- (write-through with allowlist). Implements 6 CRUD verbs (task.create,
13
- checklist.check, task.close, task.due-date.set, task.assignee.add,
14
- task.comment.add) from pm-tasks/pm-tasks-core/references/contract.md. Requires
15
- @llodev/pm-tasks-core installed.
16
- license: MIT
17
- metadata:
18
- version: 1.1.2
19
- tags:
20
- - agent-skill
21
- - asana
22
- - plan-to-tasks
23
- - pm-tools
24
- family: pm-tasks
25
- role: adapter
26
- tool: asana
27
- compatibility:
28
- agents:
29
- - claude-code
30
- - cursor
31
- - codex
32
- - windsurf
33
- - cline
34
- - roo-code
35
- ---
36
-
37
- <!-- readme-selector:start -->
38
- <p align="center">
39
- <a href="https://github.com/llodev/skills/blob/main/pm-tasks/pm-tasks-asana/SKILL.md"><img src="https://raw.githubusercontent.com/lloliveiradev/public-assets/main/images/usa.svg" width="30" alt="English"></a>&nbsp;&nbsp;
40
- <a href="https://github.com/llodev/skills/blob/main/pm-tasks/pm-tasks-asana/SKILL.pt-BR.md"><img src="https://raw.githubusercontent.com/lloliveiradev/public-assets/main/images/brazil.svg" width="30" alt="Português"></a>&nbsp;&nbsp;
41
- <a href="https://github.com/llodev/skills/blob/main/pm-tasks/pm-tasks-asana/SKILL.es-ES.md"><img src="https://raw.githubusercontent.com/lloliveiradev/public-assets/main/images/spain.svg" width="30" alt="Español"></a>
42
- </p>
43
- <!-- readme-selector:end -->
44
-
45
- # pm-tasks-asana
46
-
47
- Adaptador para Asana dentro de la familia `@llodev/pm-tasks-*`. Usa las fases de extracción de la skill núcleo, luego aplica el formato de Asana y, opcionalmente, publica/opera vía el servidor MCP `claude.ai Asana`.
48
-
49
- ## Enrutamiento
50
-
51
- | Modo | Disparador | Ruta |
52
- | ----------- | ----------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------- |
53
- | Paste-only | "formatear como tarea de Asana" sin intención de MCP | Fase 3 (core) → Fase 4 (esta skill, solo formato) → bloques paste de salida |
54
- | MCP publish | "publish to Asana", "create on Asana", "--publish-asana" | Fase 3 → Fase 4 → Fase 5 (publish vía MCP) |
55
- | Autónomo | `[autonomous]` o `--auto` en el prompt O `LLODEV_PM_TASKS_AUTONOMOUS=1` | Fase 3 → Fase 4 → Fase 5b (write-through, sin preview) |
56
- | Ops CRUD | "marcar subtarea N en tarea X", "cerrar tarea Y", "asignar Alice a la tarea Z", "comentar en tarea X" | Fase 6 (operaciones, dispatch directo del verbo) |
57
-
58
- ## Modelo de Asana
59
-
60
- Las tareas de Asana tienen:
61
-
62
- - **Nombre** (título, ≤80 chars para la vista de tablero).
63
- - **Descripción** (rich text; prefiere etiquetas `**Section**` en negrita — los headings `##` se renderizan de forma inconsistente).
64
- - **Subtareas** — un nivel de profundidad. Los custom fields y el assignee NO se propagan automáticamente desde el parent; el adaptador los establece explícitamente según `subtaskDefaults.inheritParentFields` en `.asana.json`.
65
- - **Secciones** — agrupan tareas dentro de un project.
66
- - **Custom fields** — por project; la API siempre usa GIDs de opción, nunca nombres visibles.
67
- - **Multi-assignee** — Asana permite múltiples followers; el assignee primario es un campo único. Usa `task.assignee.add` para añadir followers.
68
-
69
- ## Fase 4 — Formato de Asana
70
-
71
- Aplica el generic card del core [`../pm-tasks-core/references/generic-card.md`](../pm-tasks-core/references/generic-card.md). Luego mapea a Asana:
72
-
73
- - Título → `name` de la tarea.
74
- - Secciones del generic card → etiquetas `**Section**` en negrita dentro de `description` (no `##`).
75
- - "Implementation Checklist" + "Verification Checklist" → subtareas (aplana cualquier bullet anidado; Asana solo admite un nivel).
76
- - Labels → opciones de custom field (resueltas vía `customFields[]` de `.asana.json`).
77
- - Due date → `due_on` (YYYY-MM-DD).
78
- - Assignee → GID de `assignee` resuelto desde `members[]` de `.asana.json` o `me` al momento del publish.
79
-
80
- ## Fase 5 — MCP publish
81
-
82
- **Prerrequisitos:** servidor MCP de Asana (`claude.ai Asana`) conectado en tu agente. El MCP gestiona OAuth; el adaptador nunca ve tokens. Los pasos de configuración varían por agente — registra el mismo endpoint MCP de Asana que tu agente admita:
83
-
84
- - **Claude Code**: `claude mcp add asana -s project -- npx -y claude-ai-asana-mcp` (o sigue el setup de Anthropic para el conector hospedado `claude.ai Asana`).
85
- - **Cursor / Windsurf / Cline / Roo Code**: añade una entrada en el JSON de settings MCP de ese agente apuntando al mismo comando `claude-ai-asana-mcp` (envelope idéntico al ejemplo de Trello en `pm-tasks-trello/references/mcp-config.md`).
86
- - **Codex**: entrada TOML en `[mcp_servers.asana]` dentro de `~/.codex/config.toml`.
87
- - **Otros agentes capaces de MCP**: consulta la doc MCP de ese agente; el comando del servidor y el flujo OAuth son constantes.
88
-
89
- Orden estricto: 5.1 lee `.asana.json` (archivo completo) → 5.2.5 resuelve assignee + custom fields + mapa de fields por subtarea → 5.2 preview & aprobación → 5.3 publish vía MCP → 5.4 manejo de errores.
90
-
91
- Secuencia del MCP publish:
92
-
93
- 1. **Tarea padre** — `create_tasks` con `name`, `notes` (descripción), `projects: [projectGid]`, `memberships: [{ project, section }]`, `assignee` (GID resuelto), `due_on`, `custom_fields` (string JSON de `{fieldGid: optionGid}`).
94
- 2. **Subtareas** — `create_tasks` por subtarea con `parent: parentGid`, `name`, `assignee` (heredado o por subtarea), `custom_fields` según `subtaskDefaults.inheritParentFields`.
95
- 3. **Tags** (opcional) — `addTag` por GID de tag.
96
- 4. **Confirmación** — lista parent + subtareas con permalinks.
97
-
98
- ### Atribución (opt-in)
99
-
100
- Antes de llamar a la herramienta MCP de creación, lee `config.attribution`. Si `enabled === true`, prefija el comentario con el `commentPrefix` devuelto por `getAttribution()` y añade el `descriptionFooter` al final de `description`. En modo autónomo (`[autonomous]` sentinel), el `commentPrefix` se convierte automáticamente en el `autonomousCommentPrefix`. Consulta [references/attribution.md en pm-tasks-core](../pm-tasks-core/references/attribution.md) (añadido en v1.2.0).
101
-
102
- ## Fase 5b — Autónomo
103
-
104
- Omite 5.2 preview & aprobación. Aplica el contrato de modo autónomo de [`../pm-tasks-core/references/autonomous-mode.md`](../pm-tasks-core/references/autonomous-mode.md). Entradas del log de auditoría según [`../pm-tasks-core/references/audit-log-format.md`](../pm-tasks-core/references/audit-log-format.md).
105
-
106
- Scope autónomo específico de Asana: `autonomous.scope.projects[]` + `autonomous.scope.sections[]` deben incluir los GIDs objetivo. Cualquier escritura en custom field debe estar en `autonomous.allow` (`task.create` cubre el set de campos al crear; los cambios continuos de fields están fuera del scope de v1.x).
107
-
108
- ## Fase 6 — Operaciones CRUD (tareas existentes)
109
-
110
- Para verbos distintos de `task.create`, salta directo a la operación. Mapeo verbo → tool MCP:
111
-
112
- | Verbo del core | Tool MCP de Asana | Notas |
113
- | ------------------- | ------------------------------ | --------------------------------------------------------------------------------------------------------- |
114
- | `task.create` | `create_tasks` | parent + subtareas según Fase 5 |
115
- | `checklist.check` | `update_tasks` | para subtareas: `completed: true`; emula checklist vía modelo de subtarea |
116
- | `task.close` | `update_tasks` | `completed: true` en el parent |
117
- | `task.due-date.set` | `update_tasks` | `due_on: "YYYY-MM-DD"` |
118
- | `task.assignee.add` | `update_tasks` + `addFollower` | el assignee primario reemplaza; los adicionales se vuelven followers |
119
- | `task.comment.add` | `add_comment` (story) | añade una comment story a la tarea; aplica prefijo de atribución si `config.attribution.enabled === true` |
120
-
121
- Resolución de `<task-ref>`: acepta permalinks de Asana (`https://app.asana.com/0/<project>/<task>`), GIDs desnudos, o aliases de `taskAliases[]` en `.asana.json`.
122
-
123
- ## Envelope de resultado
124
-
125
- Cada verbo retorna la shape del contrato del core (consulta [`../pm-tasks-core/references/contract.md`](../pm-tasks-core/references/contract.md) §Result envelope):
126
-
127
- ```json
128
- {
129
- "ok": true,
130
- "verb": "task.create",
131
- "tool": "asana",
132
- "ref": { "id": "<gid>", "url": "https://app.asana.com/0/<project>/<gid>", "alias": "<optional>" },
133
- "details": {
134
- /* específico de Asana (ver tabla abajo) */
135
- }
136
- }
137
- ```
138
-
139
- `details` específicos de Asana por verbo:
140
-
141
- | Verbo | Campos de `details` |
142
- | ------------------- | ------------------------------------------------------------------------ |
143
- | `task.create` | `{ parentGid, subtaskGids[], projectGid, sectionGid?, customFields[]? }` |
144
- | `checklist.check` | `{ subtaskGid, completed: true }` |
145
- | `task.close` | `{ parentGid, completed: true }` |
146
- | `task.due-date.set` | `{ taskGid, due_on }` |
147
- | `task.assignee.add` | `{ taskGid, assignee, followers[]? }` (split entre primario y follower) |
148
- | `task.comment.add` | `{ taskGid, storyGid }` |
149
-
150
- Ante fallo: `{ ok: false, verb, tool, error: { code, message, retriable } }`. Códigos comunes: `FORBIDDEN_VERB`, `OUT_OF_SCOPE`, `NOT_FOUND`, `RATE_LIMITED`, `PARTIAL_CREATE` (la subtarea falló a mitad del create — consulta [`../pm-tasks-core/references/contract.md`](../pm-tasks-core/references/contract.md) §Partial-create recovery).
151
-
152
- ## Anti-patterns
153
-
154
- Consulta [`anti-patterns/asana.md`](anti-patterns/asana.md) — paste health, reglas de custom field, requisitos de GID, manejo de partial-create.
155
-
156
- ## Fallback standalone
157
-
158
- Si `@llodev/pm-tasks-core` no está instalado: pide al usuario la entrada mínima (título + nombres de subtareas) y produce un cuerpo de tarea de Asana listo para pegar a partir de ese contenido solo. La calidad se degrada — sin inferencia de scope/audience/fidelity. Imprime: _"Install `@llodev/pm-tasks-core` for the full flow."_
159
-
160
- ## Config
161
-
162
- Orden de búsqueda: `<git-root>/.asana.json` → `~/.config/llodev/pm-tasks/asana.json` → aborta con instrucciones de init. Schema: [`schemas/config.json`](schemas/config.json). Los secretos NUNCA en JSON — el MCP de Asana sostiene el OAuth; el `init` usa únicamente la env var `LLODEV_PM_TASKS_ASANA_PAT`.
163
-
164
- ## Init
165
-
166
- ```
167
- npx @llodev/pm-tasks-asana init
168
- ```
169
-
170
- Consulta [`../pm-tasks-core/references/init-ux.md`](../pm-tasks-core/references/init-ux.md) para el flujo compartido. El init de Asana lee workspaces / projects / sections / custom fields vía la REST API de Asana usando un Personal Access Token (env `LLODEV_PM_TASKS_ASANA_PAT`).
package/SKILL.pt-BR.md DELETED
@@ -1,170 +0,0 @@
1
- ---
2
- name: pm-tasks-asana
3
- description: >-
4
- Asana adapter for the @llodev/pm-tasks-* family. Use when the user mentions
5
- Asana, asks to "create Asana task", "publish to Asana", "post to Asana",
6
- "publish", "add comment in Asana", or uses --publish-asana; OR for CRUD on
7
- existing tasks (check subtask, close task, change due-date, assign person,
8
- comment); OR when invoked autonomously by another agent with [autonomous] /
9
- --auto sentinel. Asana hierarchy: workspace > project > section > parent task
10
- > subtasks (one level), with custom fields and multi-assignee support. Modes:
11
- paste-ready (no MCP needed), MCP publish (via claude.ai Asana MCP), autonomous
12
- (write-through with allowlist). Implements 6 CRUD verbs (task.create,
13
- checklist.check, task.close, task.due-date.set, task.assignee.add,
14
- task.comment.add) from pm-tasks/pm-tasks-core/references/contract.md. Requires
15
- @llodev/pm-tasks-core installed.
16
- license: MIT
17
- metadata:
18
- version: 1.1.2
19
- tags:
20
- - agent-skill
21
- - asana
22
- - plan-to-tasks
23
- - pm-tools
24
- family: pm-tasks
25
- role: adapter
26
- tool: asana
27
- compatibility:
28
- agents:
29
- - claude-code
30
- - cursor
31
- - codex
32
- - windsurf
33
- - cline
34
- - roo-code
35
- ---
36
-
37
- <!-- readme-selector:start -->
38
- <p align="center">
39
- <a href="https://github.com/llodev/skills/blob/main/pm-tasks/pm-tasks-asana/SKILL.md"><img src="https://raw.githubusercontent.com/lloliveiradev/public-assets/main/images/usa.svg" width="30" alt="English"></a>&nbsp;&nbsp;
40
- <a href="https://github.com/llodev/skills/blob/main/pm-tasks/pm-tasks-asana/SKILL.pt-BR.md"><img src="https://raw.githubusercontent.com/lloliveiradev/public-assets/main/images/brazil.svg" width="30" alt="Português"></a>&nbsp;&nbsp;
41
- <a href="https://github.com/llodev/skills/blob/main/pm-tasks/pm-tasks-asana/SKILL.es-ES.md"><img src="https://raw.githubusercontent.com/lloliveiradev/public-assets/main/images/spain.svg" width="30" alt="Español"></a>
42
- </p>
43
- <!-- readme-selector:end -->
44
-
45
- # pm-tasks-asana
46
-
47
- Adapter para Asana dentro da família `@llodev/pm-tasks-*`. Use as fases de extração da skill núcleo, depois aplique a formatação do Asana e opcionalmente publique/opere via o servidor MCP `claude.ai Asana`.
48
-
49
- ## Roteamento
50
-
51
- | Modo | Gatilho | Caminho |
52
- | ----------- | ---------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------- |
53
- | Paste-only | "formatar como task do Asana" sem intenção de MCP | Fase 3 (core) → Fase 4 (essa skill, só formato) → emite blocos de paste |
54
- | MCP publish | "publish to Asana", "create on Asana", "--publish-asana" | Fase 3 → Fase 4 → Fase 5 (publish via MCP) |
55
- | Autônomo | `[autonomous]` ou `--auto` no prompt OU `LLODEV_PM_TASKS_AUTONOMOUS=1` | Fase 3 → Fase 4 → Fase 5b (write-through, sem preview) |
56
- | Ops CRUD | "marcar subtask N da task X", "fechar task Y", "atribuir Alice à task Z", "comentar na task X" | Fase 6 (operações, dispatch direto do verbo) |
57
-
58
- ## Modelo do Asana
59
-
60
- Tasks do Asana têm:
61
-
62
- - **Nome** (título, ≤80 chars para a board view).
63
- - **Descrição** (rich text; prefira rótulos `**Section**` em negrito — headings `##` renderizam de forma inconsistente).
64
- - **Subtasks** — um nível de profundidade. Custom fields e assignee NÃO propagam automaticamente do parent; o adapter os define explicitamente conforme `subtaskDefaults.inheritParentFields` em `.asana.json`.
65
- - **Sections** — agrupam tasks dentro de um project.
66
- - **Custom fields** — por project; a API sempre usa option GIDs, nunca display names.
67
- - **Multi-assignee** — o Asana permite múltiplos followers; o assignee primário é um campo único. Use `task.assignee.add` para adicionar followers.
68
-
69
- ## Fase 4 — Formatação do Asana
70
-
71
- Aplique o generic card do core [`../pm-tasks-core/references/generic-card.md`](../pm-tasks-core/references/generic-card.md). Depois mapeie para o Asana:
72
-
73
- - Título → `name` da task.
74
- - Seções do generic card → rótulos `**Section**` em negrito dentro de `description` (não `##`).
75
- - "Implementation Checklist" + "Verification Checklist" → subtasks (achate qualquer bullet aninhado; o Asana suporta apenas um nível).
76
- - Labels → opções de custom field (resolvidas via `customFields[]` do `.asana.json`).
77
- - Due date → `due_on` (YYYY-MM-DD).
78
- - Assignee → GID de `assignee` resolvido a partir de `members[]` do `.asana.json` ou `me` no momento do publish.
79
-
80
- ## Fase 5 — MCP publish
81
-
82
- **Pré-requisitos:** servidor MCP do Asana (`claude.ai Asana`) conectado no seu agente. O MCP lida com OAuth; o adapter nunca vê tokens. As etapas de configuração diferem por agente — registre o mesmo endpoint MCP do Asana que seu agente suporta:
83
-
84
- - **Claude Code**: `claude mcp add asana -s project -- npx -y claude-ai-asana-mcp` (ou siga o setup da Anthropic para o conector hosted `claude.ai Asana`).
85
- - **Cursor / Windsurf / Cline / Roo Code**: adicione uma entrada no JSON de settings MCP daquele agente apontando para o mesmo comando `claude-ai-asana-mcp` (envelope idêntico ao exemplo do Trello em `pm-tasks-trello/references/mcp-config.md`).
86
- - **Codex**: entrada TOML em `[mcp_servers.asana]` no `~/.codex/config.toml`.
87
- - **Outros agentes capazes de MCP**: consulte a doc de MCP do agente; o comando do servidor e o fluxo OAuth são constantes.
88
-
89
- Ordem estrita: 5.1 lê `.asana.json` (arquivo inteiro) → 5.2.5 resolve assignee + custom fields + mapa de fields por subtask → 5.2 preview & aprovação → 5.3 publish via MCP → 5.4 tratamento de erro.
90
-
91
- Sequência do MCP publish:
92
-
93
- 1. **Task pai** — `create_tasks` com `name`, `notes` (descrição), `projects: [projectGid]`, `memberships: [{ project, section }]`, `assignee` (GID resolvido), `due_on`, `custom_fields` (string JSON de `{fieldGid: optionGid}`).
94
- 2. **Subtasks** — `create_tasks` por subtask com `parent: parentGid`, `name`, `assignee` (herdado ou por subtask), `custom_fields` conforme `subtaskDefaults.inheritParentFields`.
95
- 3. **Tags** (opcional) — `addTag` por GID de tag.
96
- 4. **Confirmação** — lista parent + subtasks com permalinks.
97
-
98
- ### Atribuição (opt-in)
99
-
100
- Antes de chamar a ferramenta MCP de criação, leia `config.attribution`. Se `enabled === true`, prefixe o comentário com o `commentPrefix` retornado por `getAttribution()` e anexe o `descriptionFooter` ao final do `description`. Em modo autônomo (`[autonomous]` sentinel), o `commentPrefix` automaticamente se torna o `autonomousCommentPrefix`. Veja [references/attribution.md no pm-tasks-core](../pm-tasks-core/references/attribution.md) (adicionado em v1.2.0).
101
-
102
- ## Fase 5b — Autônomo
103
-
104
- Pule 5.2 preview & aprovação. Aplique o contrato de modo autônomo de [`../pm-tasks-core/references/autonomous-mode.md`](../pm-tasks-core/references/autonomous-mode.md). Entradas no log de auditoria conforme [`../pm-tasks-core/references/audit-log-format.md`](../pm-tasks-core/references/audit-log-format.md).
105
-
106
- Scope autônomo específico do Asana: `autonomous.scope.projects[]` + `autonomous.scope.sections[]` devem incluir os GIDs alvo. Qualquer escrita em custom field precisa estar em `autonomous.allow` (`task.create` cobre o set de campos no momento da criação; mudanças contínuas em campos estão fora do escopo de v1.x).
107
-
108
- ## Fase 6 — Operações CRUD (tasks existentes)
109
-
110
- Para verbos diferentes de `task.create`, vá direto para a operação. Mapeamento verbo → tool MCP:
111
-
112
- | Verbo do core | Tool MCP do Asana | Notas |
113
- | ------------------- | ------------------------------ | ------------------------------------------------------------------------------ |
114
- | `task.create` | `create_tasks` | parent + subtasks conforme Fase 5 |
115
- | `checklist.check` | `update_tasks` | para subtasks: `completed: true`; emula checklist via modelo de subtask |
116
- | `task.close` | `update_tasks` | `completed: true` no parent |
117
- | `task.due-date.set` | `update_tasks` | `due_on: "YYYY-MM-DD"` |
118
- | `task.assignee.add` | `update_tasks` + `addFollower` | assignee primário substitui; adicionais viram followers |
119
- | `task.comment.add` | `add_comment` (story) | adiciona uma comment story na task; aplica prefixo de atribuição se habilitado |
120
-
121
- Resolução de `<task-ref>`: aceita permalinks do Asana (`https://app.asana.com/0/<project>/<task>`), GIDs nus, ou aliases de `taskAliases[]` em `.asana.json`.
122
-
123
- ## Envelope de resultado
124
-
125
- Todo verbo retorna a shape do contrato core (veja [`../pm-tasks-core/references/contract.md`](../pm-tasks-core/references/contract.md) §Result envelope):
126
-
127
- ```json
128
- {
129
- "ok": true,
130
- "verb": "task.create",
131
- "tool": "asana",
132
- "ref": { "id": "<gid>", "url": "https://app.asana.com/0/<project>/<gid>", "alias": "<optional>" },
133
- "details": {
134
- /* específico do Asana (veja tabela abaixo) */
135
- }
136
- }
137
- ```
138
-
139
- `details` específicos do Asana por verbo:
140
-
141
- | Verbo | Campos de `details` |
142
- | ------------------- | ------------------------------------------------------------------------ |
143
- | `task.create` | `{ parentGid, subtaskGids[], projectGid, sectionGid?, customFields[]? }` |
144
- | `checklist.check` | `{ subtaskGid, completed: true }` |
145
- | `task.close` | `{ parentGid, completed: true }` |
146
- | `task.due-date.set` | `{ taskGid, due_on }` |
147
- | `task.assignee.add` | `{ taskGid, assignee, followers[]? }` (split entre primário e follower) |
148
- | `task.comment.add` | `{ taskGid, storyGid }` |
149
-
150
- Em caso de falha: `{ ok: false, verb, tool, error: { code, message, retriable } }`. Códigos comuns: `FORBIDDEN_VERB`, `OUT_OF_SCOPE`, `NOT_FOUND`, `RATE_LIMITED`, `PARTIAL_CREATE` (subtask falhou no meio do create — veja [`../pm-tasks-core/references/contract.md`](../pm-tasks-core/references/contract.md) §Partial-create recovery).
151
-
152
- ## Anti-patterns
153
-
154
- Veja [`anti-patterns/asana.md`](anti-patterns/asana.md) — paste health, regras de custom field, requisitos de GID, tratamento de partial-create.
155
-
156
- ## Fallback standalone
157
-
158
- Se `@llodev/pm-tasks-core` não estiver instalado: peça ao usuário a entrada mínima (título + nomes das subtasks) e produza um corpo de task do Asana pronto para colar usando apenas esse conteúdo. A qualidade é degradada — sem inferência de scope/audience/fidelity. Imprima: _"Install `@llodev/pm-tasks-core` for the full flow."_
159
-
160
- ## Config
161
-
162
- Ordem de lookup: `<git-root>/.asana.json` → `~/.config/llodev/pm-tasks/asana.json` → aborta com instruções de init. Schema: [`schemas/config.json`](schemas/config.json). Secrets NUNCA em JSON — o MCP do Asana cuida do OAuth; o `init` usa apenas a env var `LLODEV_PM_TASKS_ASANA_PAT`.
163
-
164
- ## Init
165
-
166
- ```
167
- npx @llodev/pm-tasks-asana init
168
- ```
169
-
170
- Veja [`../pm-tasks-core/references/init-ux.md`](../pm-tasks-core/references/init-ux.md) para o fluxo compartilhado. O init do Asana lê workspaces / projects / sections / custom fields via a REST API do Asana usando um Personal Access Token (env `LLODEV_PM_TASKS_ASANA_PAT`).