@llodev/pm-tasks-asana 1.5.0 → 1.7.0
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 +110 -0
- package/README.md +5 -5
- package/SKILL.md +19 -12
- package/dist/adapter.d.ts +19 -0
- package/dist/adapter.d.ts.map +1 -0
- package/dist/adapter.js +18 -0
- package/dist/adapter.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -0
- package/dist/transport-asana.d.ts +44 -0
- package/dist/transport-asana.d.ts.map +1 -0
- package/dist/transport-asana.js +254 -0
- package/dist/transport-asana.js.map +1 -0
- package/docs/i18n/README.es-ES.md +5 -5
- package/docs/i18n/README.pt-BR.md +5 -5
- package/package.json +8 -4
- package/schemas/config.json +1 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,115 @@
|
|
|
1
1
|
# @llodev/pm-tasks-asana
|
|
2
2
|
|
|
3
|
+
## 1.7.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#41](https://github.com/llodev/skills/pull/41) [`dc31cdf`](https://github.com/llodev/skills/commit/dc31cdffe7dad3338f07190cdec43d71c9eb6f8b) Thanks [@lloliveiradev](https://github.com/lloliveiradev)! - Refresh published package metadata for the flattened `skills/` + `packages/` repository layout. `homepage` and `repository.directory` now point at the new paths, so npm and registry "Repository"/"Homepage" links resolve instead of 404ing against the removed `pm-tasks/*` and `django/*` folders. Documentation-only for consumers — no API, runtime, or behavior changes.
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- Updated dependencies [[`dc31cdf`](https://github.com/llodev/skills/commit/dc31cdffe7dad3338f07190cdec43d71c9eb6f8b)]:
|
|
12
|
+
- @llodev/pm-tasks-core@1.12.0
|
|
13
|
+
|
|
14
|
+
## 1.6.0
|
|
15
|
+
|
|
16
|
+
### Minor Changes
|
|
17
|
+
|
|
18
|
+
- [#20](https://github.com/llodev/skills/pull/20) [`78106ab`](https://github.com/llodev/skills/commit/78106ab42ed317ba865906d25701ade4532396ec) Thanks [@lloliveiradev](https://github.com/lloliveiradev)! - **pm-tasks v1.9.0 — Headless runtime + Plan-execution mode (Option E)**
|
|
19
|
+
|
|
20
|
+
Three coordinated minor bumps shipping the agent-agnostic headless runtime
|
|
21
|
+
and the F15 plan-execution mode. Skill-driven flows are unchanged; this
|
|
22
|
+
release adds a programmatic entry point and a new mode the calling agent
|
|
23
|
+
can opt into when it has a plan file to execute.
|
|
24
|
+
|
|
25
|
+
**`@llodev/pm-tasks-core@1.8.0 → 1.9.0`** (minor)
|
|
26
|
+
|
|
27
|
+
- New: `@llodev/pm-tasks-core/runtime` subpath exposes `createCoreRuntime`,
|
|
28
|
+
the `Transport` interface, 7 verb handlers, `RuntimeContext`, and the
|
|
29
|
+
full set of request/response types. Pure: no MCP imports, no transport
|
|
30
|
+
implementation — adapters provide the wiring.
|
|
31
|
+
- New: `@llodev/pm-tasks-core/plan-execution` module exports
|
|
32
|
+
`requireConfig` + `ConfigRequiredError`, `discoverPlanTasks` +
|
|
33
|
+
`resolvePlanRef` + `parseH3Titles` + `filenameToSlug` (discovery
|
|
34
|
+
helpers — `PlanRef` accepts `string[]` titles, a `.md` path with H3
|
|
35
|
+
parsing, or a bare slug), `onTaskStart` + `onTaskComplete` (boundary
|
|
36
|
+
hooks with best-effort dispatch, `ALREADY_IN_STATE` → skipped
|
|
37
|
+
classification, process-local idempotency memo keyed by
|
|
38
|
+
`${taskId}|${commitSha}`), and `__resetHookCacheForTests` (test escape
|
|
39
|
+
hatch).
|
|
40
|
+
- New: `pm-tasks-core/references/plan-execution.md` documents the full
|
|
41
|
+
contract (triggers, discovery semantics, hook classification table,
|
|
42
|
+
failure modes, `ConfigRequiredError` shape).
|
|
43
|
+
- New: `pm-tasks-core/references/agent-agnostic-lint.md` + a stand-alone
|
|
44
|
+
`scripts/checks/agent-agnostic-lint.mjs` that bans `superpowers`,
|
|
45
|
+
`sdd`, `Claude Code`, `Claude-only`, `Claude assumes` in SKILL body
|
|
46
|
+
content while allowlisting `claude-code` in `compatibility.agents`
|
|
47
|
+
frontmatter, vendor product names (`claude.ai Asana`,
|
|
48
|
+
`claude-ai-asana-mcp`), and other context-aware exemptions.
|
|
49
|
+
- Internal: tarball size budget raised 14.1 → 18.5 kB across Phase 4
|
|
50
|
+
and Phase 5 (covering the plan-execution module + hook helpers + full
|
|
51
|
+
JSDoc on every exported symbol).
|
|
52
|
+
|
|
53
|
+
**`@llodev/pm-tasks-asana@1.5.0 → 1.6.0`** (minor)
|
|
54
|
+
|
|
55
|
+
- New: `@llodev/pm-tasks-asana/adapter` subpath exposes
|
|
56
|
+
`createAdapter({ configPath, mcp, session?, language? })` returning a
|
|
57
|
+
`Runtime`. The `mcp: McpCaller` callback is the caller's only
|
|
58
|
+
obligation — receives a fully-qualified `mcp__claude_ai_Asana__*` tool
|
|
59
|
+
name + args object, returns the MCP server's raw response.
|
|
60
|
+
- New: `pm-tasks-asana/src/transport-asana.ts` implements the
|
|
61
|
+
`Transport` interface against `mcp__claude_ai_Asana__*` tools.
|
|
62
|
+
Asana-specific deltas: `closeListOrSectionId` ignored at the transport
|
|
63
|
+
layer (Asana has no list-on-close concept), ISO-8601 → `YYYY-MM-DD`
|
|
64
|
+
conversion via `isoToDueOn` helper for `taskDueDateSet`,
|
|
65
|
+
`INVALID_REQUEST` short-circuit BEFORE the MCP call on malformed
|
|
66
|
+
`dueAt`, single-assignee model for `taskAssigneeAdd`.
|
|
67
|
+
- SKILL.md routing table gained a Plan-execution row; Phase 7 narrative
|
|
68
|
+
section forward-references the new `references/plan-execution.md`
|
|
69
|
+
doc in `pm-tasks-core`.
|
|
70
|
+
|
|
71
|
+
**`@llodev/pm-tasks-trello@1.5.0 → 1.6.0`** (minor)
|
|
72
|
+
|
|
73
|
+
- New: `@llodev/pm-tasks-trello/adapter` subpath exposes
|
|
74
|
+
`createAdapter({ configPath, mcp, session?, language? })` returning a
|
|
75
|
+
`Runtime`. Same shape and contract as the Asana adapter.
|
|
76
|
+
- New: `pm-tasks-trello/src/transport-trello.ts` implements the
|
|
77
|
+
`Transport` interface against `mcp__trello__*` tools. Trello-specific
|
|
78
|
+
behavior: `taskClose` archives the card AND optionally moves it to
|
|
79
|
+
`closeListOrSectionId` when provided (Trello's "Done" list pattern).
|
|
80
|
+
- SKILL.md routing table gained a Plan-execution row mirroring the
|
|
81
|
+
Asana adapter; identical Phase 7 narrative section.
|
|
82
|
+
|
|
83
|
+
**Skill-judge gate**
|
|
84
|
+
|
|
85
|
+
Modified `pm-tasks-asana/SKILL.md` and `pm-tasks-trello/SKILL.md`
|
|
86
|
+
(Phase 4.3) added the Plan-execution mode routing row + Phase 7 section.
|
|
87
|
+
Measured drift sits within the documented noise band ([-2, +2]); the
|
|
88
|
+
agent-agnostic-lint rule shipped in this release codifies the
|
|
89
|
+
allowlist that earlier scoring assumed. If drift is within tolerance,
|
|
90
|
+
bypass with `SKIP_SKILL_JUDGE_GATE=1 make release-version`.
|
|
91
|
+
|
|
92
|
+
**Breaking changes**
|
|
93
|
+
|
|
94
|
+
None. All Phase 1-5 additions are pure surface area additions:
|
|
95
|
+
|
|
96
|
+
- `/runtime` and `/adapter` subpaths are NEW exports (no prior consumers)
|
|
97
|
+
- `/plan-execution` helpers are NEW exports
|
|
98
|
+
- Existing skill-driven flows + the 7-verb CRUD contract on the autonomous
|
|
99
|
+
path are unchanged
|
|
100
|
+
|
|
101
|
+
**Migration**
|
|
102
|
+
|
|
103
|
+
No migration needed. Existing consumers continue to import from the
|
|
104
|
+
package root. New code can opt into the runtime by importing from
|
|
105
|
+
`@llodev/pm-tasks-{trello,asana}/adapter` or the helpers from
|
|
106
|
+
`@llodev/pm-tasks-core/runtime` and `@llodev/pm-tasks-core/plan-execution`.
|
|
107
|
+
|
|
108
|
+
### Patch Changes
|
|
109
|
+
|
|
110
|
+
- Updated dependencies [[`78106ab`](https://github.com/llodev/skills/commit/78106ab42ed317ba865906d25701ade4532396ec)]:
|
|
111
|
+
- @llodev/pm-tasks-core@1.9.0
|
|
112
|
+
|
|
3
113
|
## 1.5.0
|
|
4
114
|
|
|
5
115
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
<!-- readme-selector:start -->
|
|
2
2
|
<p align="center">
|
|
3
|
-
<a href="https://github.com/llodev/skills/blob/main/
|
|
4
|
-
<a href="https://github.com/llodev/skills/blob/main/
|
|
5
|
-
<a href="https://github.com/llodev/skills/blob/main/
|
|
3
|
+
<a href="https://github.com/llodev/skills/blob/main/skills/pm-tasks-asana/README.md"><img src="https://raw.githubusercontent.com/lloliveiradev/public-assets/main/images/usa.svg" width="30" alt="English"></a>
|
|
4
|
+
<a href="https://github.com/llodev/skills/blob/main/skills/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>
|
|
5
|
+
<a href="https://github.com/llodev/skills/blob/main/skills/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
|
|
|
@@ -29,8 +29,8 @@ What you get:
|
|
|
29
29
|
npm i @llodev/pm-tasks-core @llodev/pm-tasks-asana
|
|
30
30
|
|
|
31
31
|
# Vercel CLI (install core manually too)
|
|
32
|
-
npx skills add llodev/skills/
|
|
33
|
-
npx skills add llodev/skills/
|
|
32
|
+
npx skills add llodev/skills/skills/pm-tasks-core
|
|
33
|
+
npx skills add llodev/skills/skills/pm-tasks-asana
|
|
34
34
|
```
|
|
35
35
|
|
|
36
36
|
## Setup the MCP
|
package/SKILL.md
CHANGED
|
@@ -11,11 +11,11 @@ description: >-
|
|
|
11
11
|
paste-ready (no MCP needed), MCP publish (via claude.ai Asana MCP), autonomous
|
|
12
12
|
(write-through with allowlist). Implements 7 CRUD verbs (task.create,
|
|
13
13
|
task.move, checklist.check, task.close, task.due-date.set, task.assignee.add,
|
|
14
|
-
task.comment.add) from
|
|
14
|
+
task.comment.add) from skills/pm-tasks-core/references/contract.md. Requires
|
|
15
15
|
@llodev/pm-tasks-core installed.
|
|
16
16
|
license: MIT
|
|
17
17
|
metadata:
|
|
18
|
-
version: 1.
|
|
18
|
+
version: 1.7.0
|
|
19
19
|
tags:
|
|
20
20
|
- agent-skill
|
|
21
21
|
- asana
|
|
@@ -40,12 +40,13 @@ Adapter for Asana within the `@llodev/pm-tasks-*` family. Use the core skill's e
|
|
|
40
40
|
|
|
41
41
|
## Routing
|
|
42
42
|
|
|
43
|
-
| Mode
|
|
44
|
-
|
|
|
45
|
-
| Paste-only
|
|
46
|
-
| MCP publish
|
|
47
|
-
| Autonomous
|
|
48
|
-
| CRUD ops
|
|
43
|
+
| Mode | Trigger | Path |
|
|
44
|
+
| -------------- | ---------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- |
|
|
45
|
+
| Paste-only | "format as Asana task" without MCP intent | Phase 3 (core) → Phase 4 (this skill, format only) → output paste blocks |
|
|
46
|
+
| MCP publish | "publish to Asana", "create on Asana", "--publish-asana" | Phase 3 → Phase 4 → Phase 5 (publish via MCP) |
|
|
47
|
+
| Autonomous | `[autonomous]` or `--auto` in prompt OR `LLODEV_PM_TASKS_AUTONOMOUS=1` | Phase 3 → Phase 4 → Phase 5b (write-through, no preview) |
|
|
48
|
+
| CRUD ops | "check subtask N on task X", "close task Y", "assign Alice to task Z", "comment on task X" | Phase 6 (operations, direct verb dispatch) |
|
|
49
|
+
| Plan-execution | Plan file path in prompt (`docs/plans/*.md`), OR `--plan-exec` flag, OR plan reference paired with `.asana.json` | Phase 7 (discover existing cards via `discoverPlanTasks`; calling agent dispatches per-task verbs at task boundaries) |
|
|
49
50
|
|
|
50
51
|
## Asana model
|
|
51
52
|
|
|
@@ -130,6 +131,14 @@ For verbs other than `task.create`, jump directly to the operation. Verb → MCP
|
|
|
130
131
|
|
|
131
132
|
`<task-ref>` resolution: accept Asana permalinks (`https://app.asana.com/0/<project>/<task>`), bare GIDs, or aliases from `.asana.json` `taskAliases[]`.
|
|
132
133
|
|
|
134
|
+
## Phase 7 — Plan-execution mode
|
|
135
|
+
|
|
136
|
+
When the calling agent passes a plan reference (a path to a markdown plan file, a plan slug, or an explicit list of expected task titles), this skill loads `.asana.json` via `requireConfig` and uses `discoverPlanTasks` (from `@llodev/pm-tasks-core`) to triage which tasks in the plan already exist as cards in scope. The skill returns the triage report `{ found, missing, ambiguous }` — the **calling agent** decides how to act on each bucket (create missing cards via Phase 4 + 5; disambiguate by picking the right ambiguous card; proceed with existing).
|
|
137
|
+
|
|
138
|
+
The skill does **not** assume any particular implementation strategy. It does not drive the calling agent's task loop, does not depend on any specific orchestration framework, and does not require any markup beyond what is already documented for `task.create` and the autonomous-mode contract. When the calling agent finishes a task and asks the skill to record progress, it invokes the standard verbs (`task.move`, `checklist.check`, `task.comment.add`, `task.close`) directly — the same path used by Phase 5b autonomous mode.
|
|
139
|
+
|
|
140
|
+
Full contract: triggers, discovery semantics, `ConfigRequiredError` handling, failure modes table, and the hook contract for Phase 5 are documented in [`skills/pm-tasks-core/references/plan-execution.md`](../pm-tasks-core/references/plan-execution.md) (added in v1.9.0).
|
|
141
|
+
|
|
133
142
|
## Result envelope
|
|
134
143
|
|
|
135
144
|
Every verb returns the core contract shape (see [`../pm-tasks-core/references/contract.md`](../pm-tasks-core/references/contract.md) §Result envelope):
|
|
@@ -140,9 +149,7 @@ Every verb returns the core contract shape (see [`../pm-tasks-core/references/co
|
|
|
140
149
|
"verb": "task.create",
|
|
141
150
|
"tool": "asana",
|
|
142
151
|
"ref": { "id": "<gid>", "url": "https://app.asana.com/0/<project>/<gid>", "alias": "<optional>" },
|
|
143
|
-
"details": {
|
|
144
|
-
/* Asana-specific (see table below) */
|
|
145
|
-
}
|
|
152
|
+
"details": {/* Asana-specific (see table below) */}
|
|
146
153
|
}
|
|
147
154
|
```
|
|
148
155
|
|
|
@@ -186,4 +193,4 @@ Pass `--doctor` to run workspace health checks before prompting:
|
|
|
186
193
|
npx @llodev/pm-tasks-asana init --doctor
|
|
187
194
|
```
|
|
188
195
|
|
|
189
|
-
Runs core checks (C-FS-1..3, C-CFG-1..4) plus Asana-specific probes (C-ASN-1..3, gated on `LLODEV_PM_TASKS_ASANA_PAT`). Full check matrix in [`
|
|
196
|
+
Runs core checks (C-FS-1..3, C-CFG-1..4) plus Asana-specific probes (C-ASN-1..3, gated on `LLODEV_PM_TASKS_ASANA_PAT`). Full check matrix in [`skills/pm-tasks-core/references/doctor.md`](../pm-tasks-core/references/doctor.md).
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { type Runtime } from "@llodev/pm-tasks-core/runtime";
|
|
2
|
+
import { type McpCaller } from "./transport-asana.js";
|
|
3
|
+
export interface CreateAdapterOptions {
|
|
4
|
+
/** Absolute or cwd-relative path to .asana.json config file. */
|
|
5
|
+
configPath: string;
|
|
6
|
+
/** Caller-supplied MCP dispatcher (proxies to `mcp__claude_ai_Asana__*` tools at runtime). */
|
|
7
|
+
mcp: McpCaller;
|
|
8
|
+
/** Optional session id for audit-log correlation. Defaults to generateSession() when omitted. */
|
|
9
|
+
session?: string;
|
|
10
|
+
/** Optional locale hint (forwarded from .asana.json locale field for narration). */
|
|
11
|
+
language?: string;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Construct a ready-to-use Asana adapter Runtime. Loads config from configPath,
|
|
15
|
+
* wires the Asana MCP transport from the caller-supplied McpCaller, and returns
|
|
16
|
+
* the same Runtime shape as createCoreRuntime.
|
|
17
|
+
*/
|
|
18
|
+
export declare function createAdapter(opts: CreateAdapterOptions): Promise<Runtime>;
|
|
19
|
+
//# sourceMappingURL=adapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../src/adapter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqB,KAAK,OAAO,EAAE,MAAM,+BAA+B,CAAC;AAChF,OAAO,EAAwB,KAAK,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAE5E,MAAM,WAAW,oBAAoB;IACnC,gEAAgE;IAChE,UAAU,EAAE,MAAM,CAAC;IACnB,8FAA8F;IAC9F,GAAG,EAAE,SAAS,CAAC;IACf,iGAAiG;IACjG,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,oFAAoF;IACpF,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;GAIG;AACH,wBAAsB,aAAa,CAAC,IAAI,EAAE,oBAAoB,GAAG,OAAO,CAAC,OAAO,CAAC,CAShF"}
|
package/dist/adapter.js
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { createCoreRuntime } from "@llodev/pm-tasks-core/runtime";
|
|
2
|
+
import { createAsanaTransport } from "./transport-asana.js";
|
|
3
|
+
/**
|
|
4
|
+
* Construct a ready-to-use Asana adapter Runtime. Loads config from configPath,
|
|
5
|
+
* wires the Asana MCP transport from the caller-supplied McpCaller, and returns
|
|
6
|
+
* the same Runtime shape as createCoreRuntime.
|
|
7
|
+
*/
|
|
8
|
+
export async function createAdapter(opts) {
|
|
9
|
+
const transport = createAsanaTransport({ mcp: opts.mcp });
|
|
10
|
+
return createCoreRuntime({
|
|
11
|
+
tool: "asana",
|
|
12
|
+
configPath: opts.configPath,
|
|
13
|
+
transport,
|
|
14
|
+
session: opts.session,
|
|
15
|
+
language: opts.language,
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=adapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter.js","sourceRoot":"","sources":["../src/adapter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAgB,MAAM,+BAA+B,CAAC;AAChF,OAAO,EAAE,oBAAoB,EAAkB,MAAM,sBAAsB,CAAC;AAa5E;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,IAA0B;IAC5D,MAAM,SAAS,GAAG,oBAAoB,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;IAC1D,OAAO,iBAAiB,CAAC;QACvB,IAAI,EAAE,OAAO;QACb,UAAU,EAAE,IAAI,CAAC,UAAU;QAC3B,SAAS;QACT,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,QAAQ,EAAE,IAAI,CAAC,QAAQ;KACxB,CAAC,CAAC;AACL,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { createAsanaTransport } from "./transport-asana.js";
|
|
2
|
+
export type { McpCaller, CreateAsanaTransportOptions } from "./transport-asana.js";
|
|
3
|
+
export { createAdapter } from "./adapter.js";
|
|
4
|
+
export type { CreateAdapterOptions } from "./adapter.js";
|
|
5
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAC5D,YAAY,EAAE,SAAS,EAAE,2BAA2B,EAAE,MAAM,sBAAsB,CAAC;AACnF,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,YAAY,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAE5D,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Asana MCP transport — implements the @llodev/pm-tasks-core Transport
|
|
3
|
+
* interface by dispatching every canonical verb through
|
|
4
|
+
* `mcp__claude_ai_Asana__*` tool calls. The MCP dispatcher is injected
|
|
5
|
+
* (caller-supplied callback, matching the established `probeMCP` pattern in
|
|
6
|
+
* pm-tasks-core/src/init-lib.ts) so this module stays:
|
|
7
|
+
*
|
|
8
|
+
* - testable — tests inject a recording stub
|
|
9
|
+
* - side-effect free — `import` does not throw, log, or call anything
|
|
10
|
+
* - decoupled at build — no `mcp__*` symbols are referenced at compile time
|
|
11
|
+
*
|
|
12
|
+
* Verb mappings follow `pm-tasks-asana/references/operations.md` verbatim.
|
|
13
|
+
* Idempotency fetches stay at the handler / Phase 5 hook layer per the
|
|
14
|
+
* Phase 2 contract; this transport is a thin dispatcher that classifies
|
|
15
|
+
* MCP errors into TransportErrorCode and wraps each result in a typed
|
|
16
|
+
* TransportResult<T> envelope.
|
|
17
|
+
*
|
|
18
|
+
* Asana-specific deltas vs the Trello transport:
|
|
19
|
+
* - Five of seven verbs route through `update_tasks` (Asana's general
|
|
20
|
+
* batch update endpoint) — the `updates: [{ task, ...fields }]` shape
|
|
21
|
+
* is uniform across move / checklist.check / close / due-date / assignee.
|
|
22
|
+
* - `taskClose` is single-call: the visual "move to Done" is a separate
|
|
23
|
+
* caller-driven `task.move` per operations.md L12. `closeListOrSectionId`
|
|
24
|
+
* is IGNORED at the transport layer; the response data omits
|
|
25
|
+
* `movedToListOrSectionId` entirely.
|
|
26
|
+
* - `taskDueDateSet` converts ISO 8601 → `YYYY-MM-DD` via `.slice(0,10)`
|
|
27
|
+
* because Asana's `due_on` field rejects full timestamps. Malformed
|
|
28
|
+
* input short-circuits to `INVALID_REQUEST` BEFORE the MCP call.
|
|
29
|
+
* - `taskAssigneeAdd` sets the single primary `assignee` field; multi-
|
|
30
|
+
* followers semantics are deferred to handler / Phase 5 hooks per
|
|
31
|
+
* operations.md L14 simplification.
|
|
32
|
+
*/
|
|
33
|
+
import type { Transport } from "@llodev/pm-tasks-core/runtime";
|
|
34
|
+
/**
|
|
35
|
+
* MCP-call dispatcher. The agent runtime that loads this transport
|
|
36
|
+
* provides a function that proxies to the real `mcp__claude_ai_Asana__*`
|
|
37
|
+
* tools. Tests inject a recording stub.
|
|
38
|
+
*/
|
|
39
|
+
export type McpCaller = (toolName: string, args: Record<string, unknown>) => Promise<unknown>;
|
|
40
|
+
export interface CreateAsanaTransportOptions {
|
|
41
|
+
mcp: McpCaller;
|
|
42
|
+
}
|
|
43
|
+
export declare function createAsanaTransport(opts: CreateAsanaTransportOptions): Transport;
|
|
44
|
+
//# sourceMappingURL=transport-asana.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transport-asana.d.ts","sourceRoot":"","sources":["../src/transport-asana.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAEH,OAAO,KAAK,EACV,SAAS,EAiBV,MAAM,+BAA+B,CAAC;AAEvC;;;;GAIG;AACH,MAAM,MAAM,SAAS,GAAG,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;AAE9F,MAAM,WAAW,2BAA2B;IAC1C,GAAG,EAAE,SAAS,CAAC;CAChB;AA0DD,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,2BAA2B,GAAG,SAAS,CAsLjF"}
|
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Asana MCP transport — implements the @llodev/pm-tasks-core Transport
|
|
3
|
+
* interface by dispatching every canonical verb through
|
|
4
|
+
* `mcp__claude_ai_Asana__*` tool calls. The MCP dispatcher is injected
|
|
5
|
+
* (caller-supplied callback, matching the established `probeMCP` pattern in
|
|
6
|
+
* pm-tasks-core/src/init-lib.ts) so this module stays:
|
|
7
|
+
*
|
|
8
|
+
* - testable — tests inject a recording stub
|
|
9
|
+
* - side-effect free — `import` does not throw, log, or call anything
|
|
10
|
+
* - decoupled at build — no `mcp__*` symbols are referenced at compile time
|
|
11
|
+
*
|
|
12
|
+
* Verb mappings follow `pm-tasks-asana/references/operations.md` verbatim.
|
|
13
|
+
* Idempotency fetches stay at the handler / Phase 5 hook layer per the
|
|
14
|
+
* Phase 2 contract; this transport is a thin dispatcher that classifies
|
|
15
|
+
* MCP errors into TransportErrorCode and wraps each result in a typed
|
|
16
|
+
* TransportResult<T> envelope.
|
|
17
|
+
*
|
|
18
|
+
* Asana-specific deltas vs the Trello transport:
|
|
19
|
+
* - Five of seven verbs route through `update_tasks` (Asana's general
|
|
20
|
+
* batch update endpoint) — the `updates: [{ task, ...fields }]` shape
|
|
21
|
+
* is uniform across move / checklist.check / close / due-date / assignee.
|
|
22
|
+
* - `taskClose` is single-call: the visual "move to Done" is a separate
|
|
23
|
+
* caller-driven `task.move` per operations.md L12. `closeListOrSectionId`
|
|
24
|
+
* is IGNORED at the transport layer; the response data omits
|
|
25
|
+
* `movedToListOrSectionId` entirely.
|
|
26
|
+
* - `taskDueDateSet` converts ISO 8601 → `YYYY-MM-DD` via `.slice(0,10)`
|
|
27
|
+
* because Asana's `due_on` field rejects full timestamps. Malformed
|
|
28
|
+
* input short-circuits to `INVALID_REQUEST` BEFORE the MCP call.
|
|
29
|
+
* - `taskAssigneeAdd` sets the single primary `assignee` field; multi-
|
|
30
|
+
* followers semantics are deferred to handler / Phase 5 hooks per
|
|
31
|
+
* operations.md L14 simplification.
|
|
32
|
+
*/
|
|
33
|
+
// ---------------------------------------------------------------------------
|
|
34
|
+
// Internal helpers
|
|
35
|
+
// ---------------------------------------------------------------------------
|
|
36
|
+
function isObjectWith(value, key) {
|
|
37
|
+
return typeof value === "object" && value !== null && key in value;
|
|
38
|
+
}
|
|
39
|
+
function classifyError(e) {
|
|
40
|
+
if (!(e instanceof Error))
|
|
41
|
+
return { code: "MCP_ERROR", details: { message: String(e) } };
|
|
42
|
+
const msg = e.message.toLowerCase();
|
|
43
|
+
if (msg.includes("not found") || msg.includes("404")) {
|
|
44
|
+
return { code: "NOT_FOUND", details: { message: e.message } };
|
|
45
|
+
}
|
|
46
|
+
if (msg.includes("401") ||
|
|
47
|
+
msg.includes("403") ||
|
|
48
|
+
msg.includes("unauthorized") ||
|
|
49
|
+
msg.includes("forbidden")) {
|
|
50
|
+
return { code: "AUTH_ERROR", details: { message: e.message } };
|
|
51
|
+
}
|
|
52
|
+
if (msg.includes("429") || msg.includes("rate limit")) {
|
|
53
|
+
return { code: "RATE_LIMITED", details: { message: e.message } };
|
|
54
|
+
}
|
|
55
|
+
return { code: "MCP_ERROR", details: { message: e.message } };
|
|
56
|
+
}
|
|
57
|
+
function shapeError(verb) {
|
|
58
|
+
return {
|
|
59
|
+
ok: false,
|
|
60
|
+
code: "MCP_ERROR",
|
|
61
|
+
details: { message: "Asana MCP returned unexpected response shape", verb },
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Validate ISO 8601 prefix `YYYY-MM-DD` and return the date portion.
|
|
66
|
+
* Returns null when the input is empty or doesn't start with that shape.
|
|
67
|
+
* Asana's `due_on` field accepts only `YYYY-MM-DD`, not full timestamps.
|
|
68
|
+
*/
|
|
69
|
+
function isoToDueOn(input) {
|
|
70
|
+
if (typeof input !== "string" || input.length < 10)
|
|
71
|
+
return null;
|
|
72
|
+
const head = input.slice(0, 10);
|
|
73
|
+
if (!/^\d{4}-\d{2}-\d{2}$/.test(head))
|
|
74
|
+
return null;
|
|
75
|
+
return head;
|
|
76
|
+
}
|
|
77
|
+
// ---------------------------------------------------------------------------
|
|
78
|
+
// Factory
|
|
79
|
+
// ---------------------------------------------------------------------------
|
|
80
|
+
export function createAsanaTransport(opts) {
|
|
81
|
+
const { mcp } = opts;
|
|
82
|
+
return {
|
|
83
|
+
// -------------------------------------------------------------------
|
|
84
|
+
// 1. task.create → mcp__claude_ai_Asana__create_tasks
|
|
85
|
+
// -------------------------------------------------------------------
|
|
86
|
+
async taskCreate(req) {
|
|
87
|
+
const notes = req.clientToken
|
|
88
|
+
? `[ct:${req.clientToken}] ${req.description ?? ""}`.trim()
|
|
89
|
+
: req.description;
|
|
90
|
+
const taskPayload = {
|
|
91
|
+
name: req.name,
|
|
92
|
+
memberships: [{ project: req.boardOrProjectId, section: req.listOrSectionId }],
|
|
93
|
+
};
|
|
94
|
+
if (notes !== undefined)
|
|
95
|
+
taskPayload.notes = notes;
|
|
96
|
+
try {
|
|
97
|
+
const resp = await mcp("mcp__claude_ai_Asana__create_tasks", { tasks: [taskPayload] });
|
|
98
|
+
if (!isObjectWith(resp, "tasks") || !Array.isArray(resp.tasks) || resp.tasks.length === 0) {
|
|
99
|
+
return shapeError("task.create");
|
|
100
|
+
}
|
|
101
|
+
const first = resp.tasks[0];
|
|
102
|
+
if (!isObjectWith(first, "gid") || typeof first.gid !== "string") {
|
|
103
|
+
return shapeError("task.create");
|
|
104
|
+
}
|
|
105
|
+
let url;
|
|
106
|
+
if (isObjectWith(first, "permalink_url") && typeof first.permalink_url === "string") {
|
|
107
|
+
url = first.permalink_url;
|
|
108
|
+
}
|
|
109
|
+
return { ok: true, data: { id: first.gid, ...(url !== undefined ? { url } : {}) } };
|
|
110
|
+
}
|
|
111
|
+
catch (e) {
|
|
112
|
+
const { code, details } = classifyError(e);
|
|
113
|
+
return { ok: false, code, details };
|
|
114
|
+
}
|
|
115
|
+
},
|
|
116
|
+
// -------------------------------------------------------------------
|
|
117
|
+
// 2. task.move → mcp__claude_ai_Asana__update_tasks
|
|
118
|
+
// -------------------------------------------------------------------
|
|
119
|
+
async taskMove(req) {
|
|
120
|
+
try {
|
|
121
|
+
await mcp("mcp__claude_ai_Asana__update_tasks", {
|
|
122
|
+
updates: [
|
|
123
|
+
{
|
|
124
|
+
task: req.taskId,
|
|
125
|
+
memberships: [{ project: "", section: req.targetListOrSectionId }],
|
|
126
|
+
},
|
|
127
|
+
],
|
|
128
|
+
});
|
|
129
|
+
return {
|
|
130
|
+
ok: true,
|
|
131
|
+
data: {
|
|
132
|
+
previousListOrSectionId: null,
|
|
133
|
+
newListOrSectionId: req.targetListOrSectionId,
|
|
134
|
+
},
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
catch (e) {
|
|
138
|
+
const { code, details } = classifyError(e);
|
|
139
|
+
return { ok: false, code, details };
|
|
140
|
+
}
|
|
141
|
+
},
|
|
142
|
+
// -------------------------------------------------------------------
|
|
143
|
+
// 3. checklist.check → mcp__claude_ai_Asana__update_tasks (subtask)
|
|
144
|
+
// -------------------------------------------------------------------
|
|
145
|
+
async checklistCheck(req) {
|
|
146
|
+
try {
|
|
147
|
+
await mcp("mcp__claude_ai_Asana__update_tasks", {
|
|
148
|
+
updates: [{ task: req.itemId, completed: req.targetState === "complete" }],
|
|
149
|
+
});
|
|
150
|
+
const previousState = req.targetState === "complete" ? "incomplete" : "complete";
|
|
151
|
+
return {
|
|
152
|
+
ok: true,
|
|
153
|
+
data: { previousState, newState: req.targetState },
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
catch (e) {
|
|
157
|
+
const { code, details } = classifyError(e);
|
|
158
|
+
return { ok: false, code, details };
|
|
159
|
+
}
|
|
160
|
+
},
|
|
161
|
+
// -------------------------------------------------------------------
|
|
162
|
+
// 4. task.close → mcp__claude_ai_Asana__update_tasks (single-call)
|
|
163
|
+
// closeListOrSectionId is IGNORED for Asana — visual move is a
|
|
164
|
+
// separate caller-driven task.move per operations.md L12.
|
|
165
|
+
// -------------------------------------------------------------------
|
|
166
|
+
async taskClose(req) {
|
|
167
|
+
try {
|
|
168
|
+
await mcp("mcp__claude_ai_Asana__update_tasks", {
|
|
169
|
+
updates: [{ task: req.taskId, completed: true }],
|
|
170
|
+
});
|
|
171
|
+
return { ok: true, data: { closed: true } };
|
|
172
|
+
}
|
|
173
|
+
catch (e) {
|
|
174
|
+
const { code, details } = classifyError(e);
|
|
175
|
+
return { ok: false, code, details };
|
|
176
|
+
}
|
|
177
|
+
},
|
|
178
|
+
// -------------------------------------------------------------------
|
|
179
|
+
// 5. task.due-date.set → mcp__claude_ai_Asana__update_tasks
|
|
180
|
+
// Converts ISO 8601 → YYYY-MM-DD (Asana's due_on shape).
|
|
181
|
+
// Malformed input short-circuits to INVALID_REQUEST.
|
|
182
|
+
// -------------------------------------------------------------------
|
|
183
|
+
async taskDueDateSet(req) {
|
|
184
|
+
const dueOn = isoToDueOn(req.dueAt);
|
|
185
|
+
if (dueOn === null) {
|
|
186
|
+
return {
|
|
187
|
+
ok: false,
|
|
188
|
+
code: "INVALID_REQUEST",
|
|
189
|
+
details: { message: "dueAt must be ISO 8601", verb: "taskDueDateSet" },
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
try {
|
|
193
|
+
await mcp("mcp__claude_ai_Asana__update_tasks", {
|
|
194
|
+
updates: [{ task: req.taskId, due_on: dueOn }],
|
|
195
|
+
});
|
|
196
|
+
return {
|
|
197
|
+
ok: true,
|
|
198
|
+
data: { previousDueAt: null, newDueAt: req.dueAt },
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
catch (e) {
|
|
202
|
+
const { code, details } = classifyError(e);
|
|
203
|
+
return { ok: false, code, details };
|
|
204
|
+
}
|
|
205
|
+
},
|
|
206
|
+
// -------------------------------------------------------------------
|
|
207
|
+
// 6. task.assignee.add → mcp__claude_ai_Asana__update_tasks
|
|
208
|
+
// Single-assignee model at this layer; multi-followers deferred
|
|
209
|
+
// to handler / Phase 5 hooks per operations.md L14.
|
|
210
|
+
// -------------------------------------------------------------------
|
|
211
|
+
async taskAssigneeAdd(req) {
|
|
212
|
+
try {
|
|
213
|
+
await mcp("mcp__claude_ai_Asana__update_tasks", {
|
|
214
|
+
updates: [{ task: req.taskId, assignee: req.userId }],
|
|
215
|
+
});
|
|
216
|
+
return {
|
|
217
|
+
ok: true,
|
|
218
|
+
data: { added: true, currentAssigneeIds: [req.userId] },
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
catch (e) {
|
|
222
|
+
const { code, details } = classifyError(e);
|
|
223
|
+
return { ok: false, code, details };
|
|
224
|
+
}
|
|
225
|
+
},
|
|
226
|
+
// -------------------------------------------------------------------
|
|
227
|
+
// 7. task.comment.add → mcp__claude_ai_Asana__add_comment
|
|
228
|
+
// -------------------------------------------------------------------
|
|
229
|
+
async taskCommentAdd(req) {
|
|
230
|
+
const text = req.clientToken ? `[ct:${req.clientToken}] ${req.text}` : req.text;
|
|
231
|
+
try {
|
|
232
|
+
const resp = await mcp("mcp__claude_ai_Asana__add_comment", {
|
|
233
|
+
task: req.taskId,
|
|
234
|
+
text,
|
|
235
|
+
});
|
|
236
|
+
if (!isObjectWith(resp, "gid") || typeof resp.gid !== "string") {
|
|
237
|
+
return shapeError("task.comment.add");
|
|
238
|
+
}
|
|
239
|
+
const postedAt = isObjectWith(resp, "created_at") && typeof resp.created_at === "string"
|
|
240
|
+
? resp.created_at
|
|
241
|
+
: new Date().toISOString();
|
|
242
|
+
return {
|
|
243
|
+
ok: true,
|
|
244
|
+
data: { commentId: resp.gid, postedAt },
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
catch (e) {
|
|
248
|
+
const { code, details } = classifyError(e);
|
|
249
|
+
return { ok: false, code, details };
|
|
250
|
+
}
|
|
251
|
+
},
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
//# sourceMappingURL=transport-asana.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transport-asana.js","sourceRoot":"","sources":["../src/transport-asana.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
<!-- readme-selector:start -->
|
|
2
2
|
<p align="center">
|
|
3
|
-
<a href="https://github.com/llodev/skills/blob/main/
|
|
4
|
-
<a href="https://github.com/llodev/skills/blob/main/
|
|
5
|
-
<a href="https://github.com/llodev/skills/blob/main/
|
|
3
|
+
<a href="https://github.com/llodev/skills/blob/main/skills/pm-tasks-asana/README.md"><img src="https://raw.githubusercontent.com/lloliveiradev/public-assets/main/images/usa.svg" width="30" alt="English"></a>
|
|
4
|
+
<a href="https://github.com/llodev/skills/blob/main/skills/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>
|
|
5
|
+
<a href="https://github.com/llodev/skills/blob/main/skills/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
|
|
|
@@ -29,8 +29,8 @@ Lo que obtienes:
|
|
|
29
29
|
npm i @llodev/pm-tasks-core @llodev/pm-tasks-asana
|
|
30
30
|
|
|
31
31
|
# Vercel CLI (instala el core manualmente también)
|
|
32
|
-
npx skills add llodev/skills/
|
|
33
|
-
npx skills add llodev/skills/
|
|
32
|
+
npx skills add llodev/skills/skills/pm-tasks-core
|
|
33
|
+
npx skills add llodev/skills/skills/pm-tasks-asana
|
|
34
34
|
```
|
|
35
35
|
|
|
36
36
|
## Setup del MCP
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
<!-- readme-selector:start -->
|
|
2
2
|
<p align="center">
|
|
3
|
-
<a href="https://github.com/llodev/skills/blob/main/
|
|
4
|
-
<a href="https://github.com/llodev/skills/blob/main/
|
|
5
|
-
<a href="https://github.com/llodev/skills/blob/main/
|
|
3
|
+
<a href="https://github.com/llodev/skills/blob/main/skills/pm-tasks-asana/README.md"><img src="https://raw.githubusercontent.com/lloliveiradev/public-assets/main/images/usa.svg" width="30" alt="English"></a>
|
|
4
|
+
<a href="https://github.com/llodev/skills/blob/main/skills/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>
|
|
5
|
+
<a href="https://github.com/llodev/skills/blob/main/skills/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
|
|
|
@@ -29,8 +29,8 @@ O que você ganha:
|
|
|
29
29
|
npm i @llodev/pm-tasks-core @llodev/pm-tasks-asana
|
|
30
30
|
|
|
31
31
|
# Vercel CLI (instale o core manualmente também)
|
|
32
|
-
npx skills add llodev/skills/
|
|
33
|
-
npx skills add llodev/skills/
|
|
32
|
+
npx skills add llodev/skills/skills/pm-tasks-core
|
|
33
|
+
npx skills add llodev/skills/skills/pm-tasks-asana
|
|
34
34
|
```
|
|
35
35
|
|
|
36
36
|
## Setup do MCP
|
package/package.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@llodev/pm-tasks-asana",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.7.0",
|
|
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
|
-
"homepage": "https://github.com/llodev/skills/tree/main/
|
|
6
|
+
"homepage": "https://github.com/llodev/skills/tree/main/skills/pm-tasks-asana",
|
|
7
7
|
"repository": {
|
|
8
8
|
"type": "git",
|
|
9
9
|
"url": "https://github.com/llodev/skills.git",
|
|
10
|
-
"directory": "
|
|
10
|
+
"directory": "skills/pm-tasks-asana"
|
|
11
11
|
},
|
|
12
12
|
"main": "./dist/bin/init.js",
|
|
13
13
|
"types": "./dist/bin/init.d.ts",
|
|
@@ -37,6 +37,10 @@
|
|
|
37
37
|
"types": "./dist/bin/init.d.ts",
|
|
38
38
|
"import": "./dist/bin/init.js"
|
|
39
39
|
},
|
|
40
|
+
"./adapter": {
|
|
41
|
+
"types": "./dist/adapter.d.ts",
|
|
42
|
+
"import": "./dist/adapter.js"
|
|
43
|
+
},
|
|
40
44
|
"./i18n/*.json": "./i18n/*.json",
|
|
41
45
|
"./schemas/*.json": "./schemas/*.json",
|
|
42
46
|
"./manifest.json": "./manifest.json"
|
|
@@ -47,7 +51,7 @@
|
|
|
47
51
|
"dependencies": {
|
|
48
52
|
"ajv": "^8.17.1",
|
|
49
53
|
"ajv-formats": "^3.0.1",
|
|
50
|
-
"@llodev/pm-tasks-core": "^1.
|
|
54
|
+
"@llodev/pm-tasks-core": "^1.12.0"
|
|
51
55
|
},
|
|
52
56
|
"publishConfig": {
|
|
53
57
|
"access": "public"
|