@desplega.ai/agent-swarm 1.85.0 → 1.86.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.
Files changed (93) hide show
  1. package/README.md +1 -0
  2. package/openapi.json +1 -1
  3. package/package.json +8 -6
  4. package/src/be/db.ts +44 -0
  5. package/src/be/migrations/078_backfill_gpt_5_5_pricing.sql +15 -0
  6. package/src/be/modelsdev-cache.json +152028 -0
  7. package/src/be/modelsdev-cache.ts +46 -0
  8. package/src/be/seed-pricing.ts +7 -44
  9. package/src/cli.tsx +12 -2
  10. package/src/commands/codex-session-runner.ts +132 -0
  11. package/src/commands/credential-wait.ts +2 -2
  12. package/src/commands/provider-credentials.ts +10 -5
  13. package/src/commands/runner.ts +3 -3
  14. package/src/prompts/base-prompt.ts +49 -3
  15. package/src/providers/claude-adapter.ts +83 -2
  16. package/src/providers/claude-managed-models.ts +18 -2
  17. package/src/providers/codex-adapter.ts +417 -97
  18. package/src/providers/codex-models.ts +9 -2
  19. package/src/providers/index.ts +28 -19
  20. package/src/providers/pricing-sources.md +7 -4
  21. package/src/providers/swarm-events-shared.ts +14 -0
  22. package/src/slack/HEURISTICS.md +5 -1
  23. package/src/slack/handlers.test.ts +35 -0
  24. package/src/slack/handlers.ts +79 -2
  25. package/src/tests/base-prompt.test.ts +46 -8
  26. package/src/tests/claude-managed-adapter.test.ts +4 -4
  27. package/src/tests/codex-adapter-otel.test.ts +4 -4
  28. package/src/tests/codex-adapter.test.ts +20 -7
  29. package/src/tests/codex-swarm-events.test.ts +35 -0
  30. package/src/tests/context-window.test.ts +1 -0
  31. package/src/tests/credential-check.test.ts +48 -29
  32. package/src/tests/entrypoint-config-env-export.test.ts +81 -0
  33. package/src/tests/follow-up-redelivery-guard.test.ts +165 -0
  34. package/src/tests/migration-046-budgets.test.ts +6 -5
  35. package/src/tests/pricing-routes.test.ts +6 -5
  36. package/src/tests/provider-adapter.test.ts +10 -10
  37. package/src/tests/provider-command-format.test.ts +4 -4
  38. package/src/tests/session-costs-codex-recompute.test.ts +25 -0
  39. package/src/tools/send-task.ts +30 -9
  40. package/src/utils/context-window.ts +1 -0
  41. package/templates/schedules/daily-blocker-digest/config.json +13 -0
  42. package/templates/schedules/daily-blocker-digest/content.md +150 -0
  43. package/templates/schedules/daily-compounding-reflection/config.json +21 -0
  44. package/templates/schedules/daily-compounding-reflection/content.md +210 -0
  45. package/templates/schedules/daily-hn-briefing/config.json +13 -0
  46. package/templates/schedules/daily-hn-briefing/content.md +97 -0
  47. package/templates/schedules/daily-workflow-health-audit/config.json +13 -0
  48. package/templates/schedules/daily-workflow-health-audit/content.md +189 -0
  49. package/templates/schedules/gtm-weekly-review/config.json +13 -0
  50. package/templates/schedules/gtm-weekly-review/content.md +58 -0
  51. package/templates/schedules/weekly-dependabot-triage/config.json +13 -0
  52. package/templates/schedules/weekly-dependabot-triage/content.md +45 -0
  53. package/templates/schema.ts +26 -0
  54. package/templates/skills/agentmail-sending/config.json +13 -0
  55. package/templates/skills/agentmail-sending/content.md +48 -0
  56. package/templates/skills/artifacts/config.json +13 -0
  57. package/templates/skills/artifacts/content.md +87 -0
  58. package/templates/skills/browser-use-cloud/config.json +13 -0
  59. package/templates/skills/browser-use-cloud/content.md +155 -0
  60. package/templates/skills/desloppify/config.json +13 -0
  61. package/templates/skills/desloppify/content.md +201 -0
  62. package/templates/skills/exa-search/config.json +13 -0
  63. package/templates/skills/exa-search/content.md +106 -0
  64. package/templates/skills/jira-interaction/config.json +13 -0
  65. package/templates/skills/jira-interaction/content.md +252 -0
  66. package/templates/skills/kapso-whatsapp/config.json +13 -0
  67. package/templates/skills/kapso-whatsapp/content.md +369 -0
  68. package/templates/skills/kv-storage/config.json +13 -0
  69. package/templates/skills/kv-storage/content.md +111 -0
  70. package/templates/skills/linear-interaction/config.json +20 -0
  71. package/templates/skills/linear-interaction/content.md +230 -0
  72. package/templates/skills/pages/config.json +18 -0
  73. package/templates/skills/pages/content.md +85 -0
  74. package/templates/skills/profile-corruption-escalation/config.json +13 -0
  75. package/templates/skills/profile-corruption-escalation/content.md +105 -0
  76. package/templates/skills/scheduled-task-resilience/config.json +13 -0
  77. package/templates/skills/scheduled-task-resilience/content.md +95 -0
  78. package/templates/skills/sprite-cli/config.json +13 -0
  79. package/templates/skills/sprite-cli/content.md +133 -0
  80. package/templates/skills/turso-interaction/config.json +13 -0
  81. package/templates/skills/turso-interaction/content.md +192 -0
  82. package/templates/skills/workflow-iterate/config.json +18 -0
  83. package/templates/skills/workflow-iterate/content.md +399 -0
  84. package/templates/skills/workflow-structured-output/config.json +13 -0
  85. package/templates/skills/workflow-structured-output/content.md +101 -0
  86. package/templates/skills/x-api-interactions/config.json +13 -0
  87. package/templates/skills/x-api-interactions/content.md +109 -0
  88. package/templates/workflows/autopilot/config.json +13 -0
  89. package/templates/workflows/autopilot/content.md +58 -0
  90. package/templates/workflows/linear-drain-loop/config.json +21 -0
  91. package/templates/workflows/linear-drain-loop/content.md +72 -0
  92. package/templates/workflows/ralph-loop/config.json +13 -0
  93. package/templates/workflows/ralph-loop/content.md +75 -0
@@ -0,0 +1,106 @@
1
+ # Exa Search
2
+
3
+ Exa (https://exa.ai) is a neural/semantic search API. It returns web results ranked by embedding similarity rather than keyword match — much better than Google for "find me companies that sound like X" or "what papers explore the shape of Y."
4
+
5
+ ## When to use Exa vs. WebSearch
6
+
7
+ | Query shape | Use |
8
+ |---|---|
9
+ | "What is the official Bun docs URL?" | WebSearch (concrete lookup) |
10
+ | "Latest CVE for Next.js" | WebSearch (recent, factual) |
11
+ | "Companies building post-hierarchy AI org platforms" | **Exa** (conceptual / discovery) |
12
+ | "Papers on Bayesian memory rating for agents" | **Exa** (topic-shape) |
13
+ | "Blogs that argue knowledge ≠ data in agent systems" | **Exa** (argument-shape) |
14
+ | "Funding rounds for company X in 2026" | WebSearch (named entity + date) |
15
+
16
+ Rule of thumb: if you're tempted to run 5+ WebSearch calls rephrasing the same idea, use Exa instead — one neural query usually surfaces the cluster.
17
+
18
+ ## Step 1 — Get the API key
19
+
20
+ ```bash
21
+ # Via MCP tool (preferred — handles secret resolution)
22
+ mcp__agent-swarm__get-config(key="EXA_API_KEY", includeSecrets=true)
23
+ ```
24
+
25
+ The value comes back at `configs[0].value`. Export to env or pass inline.
26
+
27
+ ## Step 2 — Call the search endpoint
28
+
29
+ Endpoint: `POST https://api.exa.ai/search` — full reference at https://exa.ai/docs/reference/search
30
+
31
+ ```bash
32
+ curl -X POST 'https://api.exa.ai/search' \
33
+ -H "x-api-key: $EXA_API_KEY" \
34
+ -H 'Content-Type: application/json' \
35
+ -d '{
36
+ "query": "companies building agent coordination layers for enterprises",
37
+ "type": "neural",
38
+ "numResults": 10,
39
+ "useAutoprompt": true
40
+ }'
41
+ ```
42
+
43
+ Key request fields:
44
+ - `query` (required): the natural-language description, NOT keywords
45
+ - `type`: `"neural"` (semantic, default for discovery) or `"keyword"` (legacy) or `"auto"` (let Exa choose)
46
+ - `numResults`: 1–25, default 10
47
+ - `useAutoprompt`: true → Exa rewrites your query for better embedding match (recommended for short/colloquial queries)
48
+ - `includeDomains` / `excludeDomains`: arrays for filtering
49
+ - `startPublishedDate` / `endPublishedDate`: ISO dates for time-bounding
50
+ - `category`: e.g. `"company"`, `"research paper"`, `"news"`, `"github"`, `"tweet"`, `"pdf"` — narrows the result type
51
+
52
+ Response shape (trimmed):
53
+ ```json
54
+ {
55
+ "results": [
56
+ { "title": "...", "url": "...", "publishedDate": "...", "author": "...", "score": 0.42, "id": "..." }
57
+ ],
58
+ "autopromptString": "the rewritten query Exa actually used"
59
+ }
60
+ ```
61
+
62
+ ## Step 3 — (Optional) Get full content
63
+
64
+ The `/search` endpoint returns metadata only. To pull article bodies:
65
+
66
+ ```bash
67
+ curl -X POST 'https://api.exa.ai/contents' \
68
+ -H "x-api-key: $EXA_API_KEY" \
69
+ -H 'Content-Type: application/json' \
70
+ -d '{
71
+ "ids": ["result-id-from-search"],
72
+ "text": true
73
+ }'
74
+ ```
75
+
76
+ Or use the one-shot `/search` variant with `"contents": { "text": true }` baked into the search request to get content in a single round-trip.
77
+
78
+ ## Step 4 — Pair with WebFetch for verification
79
+
80
+ Exa surfaces candidates fast but its content snippets can be stale or truncated. For any claim you'll cite (funding amount, headcount, product description), follow up with WebFetch on the canonical company URL. Treat Exa as a discovery layer, WebFetch as the source of truth.
81
+
82
+ ## Discipline — no fabrication
83
+
84
+ If a query returns no relevant results, **say "not surfaced"** in your output rather than inventing plausible-sounding companies/papers/links. The most common Exa failure mode is over-promising a comprehensive landscape when the embedding space had thin coverage of your topic. Marking gaps explicitly is what makes the research trustworthy.
85
+
86
+ ## Real-world example queries (from 2026-05-04 swarm competitive analysis)
87
+
88
+ These are the exact queries the Researcher used to map the agent-coordination landscape:
89
+
90
+ - `"multi-agent platform for enterprises"`
91
+ - `"AI org operating system post-hierarchy intelligence"`
92
+ - `"AI employee platform digital workers"`
93
+ - `"derived knowledge layer for AI agents"`
94
+ - `"agent coordination layer routes work specialist"`
95
+ - `"humans at the edge AI org structure"`
96
+ - `"agent capability gap registry knowledge graph"`
97
+
98
+ Each surfaced 8–12 results; combined with WebFetch on company sites and WebSearch for funding numbers, the Researcher mapped 5 staked competitive slots + 1 open quadrant in ~30 min. See `agent-fs --org 648a5f3c-35c8-4f11-8673-b89de52cd6bd cat thoughts/d454d1a5-4df9-49bd-8a89-e58d6a657dc3/research/2026-05-04-swarm-competitive-analysis.md` for the full output.
99
+
100
+ ## Quick gotchas
101
+
102
+ - The header is `x-api-key`, **not** `Authorization: Bearer`.
103
+ - Free-tier rate limits are tight — batch your queries, don't fire dozens.
104
+ - Neural search is non-deterministic across calls; same query can shuffle top-5 results.
105
+ - `useAutoprompt: true` is almost always right; only disable if you've already hand-tuned the query.
106
+
@@ -0,0 +1,13 @@
1
+ {
2
+ "kind": "skill",
3
+ "name": "jira-interaction",
4
+ "displayName": "Jira Interaction",
5
+ "slug": "jira-interaction",
6
+ "title": "Jira Interaction",
7
+ "description": "Generic Jira update discipline for issue comments, transitions, and triage.",
8
+ "version": "1.0.0",
9
+ "category": "skills",
10
+ "placeholders": ["JIRA_PROJECT_KEY"],
11
+ "runAllSeedersCandidate": false,
12
+ "tags": ["jira", "tracker", "project-management"]
13
+ }
@@ -0,0 +1,252 @@
1
+ # Jira Interaction (Read + Outbound Push)
2
+
3
+ The swarm has Jira OAuth connected but **no inbound sync** (unlike Linear). Every read or write is a direct API call against the Atlassian REST API v3.
4
+
5
+ ## TL;DR — minimum knowledge
6
+
7
+ 1. Pull the access token from `oauth_tokens` (provider = `jira`).
8
+ 2. Hit `https://api.atlassian.com/ex/jira/<CLOUD_ID>/rest/api/3/...` — *not* `desplega.atlassian.net` directly. 3LO bearer tokens only work via the `api.atlassian.com` proxy.
9
+ 3. Bodies for descriptions/comments must be in **ADF** (Atlassian Document Format), not plain text or markdown.
10
+
11
+ ## Known constants (Desplega tenant)
12
+
13
+ - Site: `desplega.atlassian.net`
14
+ - Cloud ID: `0054e739-8d39-4f01-8d6a-431619cae8fc`
15
+ - Default project: `KAN` ("Swarm")
16
+ - Scopes on the stored token: `manage:jira-webhook offline_access read:jira-work read:me write:jira-work`
17
+
18
+ If the cloudId ever changes, rediscover it:
19
+ ```bash
20
+ curl -s -H "Authorization: Bearer $TOKEN" -H "Accept: application/json" \
21
+ https://api.atlassian.com/oauth/token/accessible-resources | jq '.'
22
+ ```
23
+
24
+ ## Authentication
25
+
26
+ The OAuth token is in the swarm DB (`oauth_tokens`, provider = `jira`).
27
+
28
+ ```sql
29
+ -- via the db-query MCP tool
30
+ SELECT accessToken, expiresAt, scope FROM oauth_tokens WHERE provider = 'jira';
31
+ ```
32
+
33
+ **Always check `expiresAt` first.** Atlassian access tokens are short-lived (~1h). If expired, do NOT keep retrying — report it. Re-auth path:
34
+
35
+ ```
36
+ https://api.desplega.agent-swarm.dev/api/trackers/jira/authorize
37
+ ```
38
+ (User may need to remove the app and re-auth.)
39
+
40
+ ## Calling pattern
41
+
42
+ Every endpoint below is relative to:
43
+ ```
44
+ https://api.atlassian.com/ex/jira/<CLOUD_ID>/rest/api/3
45
+ ```
46
+
47
+ Standard header set:
48
+ ```bash
49
+ -H "Authorization: Bearer $TOKEN"
50
+ -H "Accept: application/json"
51
+ -H "Content-Type: application/json" # only on POST/PUT
52
+ ```
53
+
54
+ ## Common operations
55
+
56
+ ### 1. List projects
57
+
58
+ ```bash
59
+ curl -s -H "Authorization: Bearer $TOKEN" -H "Accept: application/json" \
60
+ "https://api.atlassian.com/ex/jira/$CLOUD_ID/rest/api/3/project/search" \
61
+ | jq '.values[] | {key, name, id, projectTypeKey}'
62
+ ```
63
+
64
+ ### 2. Get a project (with issue types + lead)
65
+
66
+ ```bash
67
+ curl -s -H "Authorization: Bearer $TOKEN" -H "Accept: application/json" \
68
+ "https://api.atlassian.com/ex/jira/$CLOUD_ID/rest/api/3/project/KAN" \
69
+ | jq '{key, name, lead: .lead.displayName, issueTypes: [.issueTypes[] | {id, name, subtask}]}'
70
+ ```
71
+
72
+ ### 3. Search issues with JQL
73
+
74
+ Use the **`/search/jql`** endpoint (the older `/search` is deprecated for cloud).
75
+
76
+ ```bash
77
+ curl -s -G \
78
+ -H "Authorization: Bearer $TOKEN" -H "Accept: application/json" \
79
+ --data-urlencode 'jql=project = KAN AND statusCategory != Done' \
80
+ --data-urlencode 'fields=summary,status,assignee,priority' \
81
+ "https://api.atlassian.com/ex/jira/$CLOUD_ID/rest/api/3/search/jql" \
82
+ | jq '[.issues[] | {key, summary: .fields.summary, status: .fields.status.name, assignee: .fields.assignee.displayName}]'
83
+ ```
84
+
85
+ ### 4. Create an issue
86
+
87
+ Description must be ADF. Minimal valid ADF:
88
+
89
+ ```bash
90
+ curl -s -X POST \
91
+ -H "Authorization: Bearer $TOKEN" -H "Accept: application/json" -H "Content-Type: application/json" \
92
+ "https://api.atlassian.com/ex/jira/$CLOUD_ID/rest/api/3/issue" \
93
+ -d '{
94
+ "fields": {
95
+ "project": { "key": "KAN" },
96
+ "summary": "Short title",
97
+ "issuetype": { "name": "Task" },
98
+ "description": {
99
+ "type": "doc",
100
+ "version": 1,
101
+ "content": [
102
+ { "type": "paragraph", "content": [ { "type": "text", "text": "Body goes here." } ] }
103
+ ]
104
+ }
105
+ }
106
+ }'
107
+ ```
108
+
109
+ Returns `{ id, key, self }` on success (HTTP 201). The `key` (e.g. `KAN-7`) is what humans use; URL is `https://desplega.atlassian.net/browse/<KEY>`.
110
+
111
+ Available issue types in `KAN` (verify per-project): `Epic, Subtask, Task, Story, Feature, Request, Bug`.
112
+
113
+ ### 5. Transition issue status (e.g. → Done)
114
+
115
+ Transitions are project- and workflow-specific. Always discover them first:
116
+
117
+ ```bash
118
+ curl -s -H "Authorization: Bearer $TOKEN" -H "Accept: application/json" \
119
+ "https://api.atlassian.com/ex/jira/$CLOUD_ID/rest/api/3/issue/<KEY>/transitions" \
120
+ | jq '.transitions[] | {id, name, to: .to.name}'
121
+ ```
122
+
123
+ For project `KAN` (verified 2026-04-27), the workflow exposes ALL transitions from any state — you do not need to walk through intermediate states:
124
+
125
+ | Transition ID | Target state |
126
+ |---|---|
127
+ | `11` | To Do |
128
+ | `21` | In Progress |
129
+ | `31` | In Review |
130
+ | `41` | Backlog |
131
+ | `51` | **Done** |
132
+
133
+ Transition (returns HTTP 204 on success, no body):
134
+
135
+ ```bash
136
+ curl -s -X POST \
137
+ -H "Authorization: Bearer $TOKEN" -H "Accept: application/json" -H "Content-Type: application/json" \
138
+ "https://api.atlassian.com/ex/jira/$CLOUD_ID/rest/api/3/issue/KAN-3/transitions" \
139
+ -d '{"transition":{"id":"51"}}'
140
+ ```
141
+
142
+ ### 6. Comment on an issue
143
+
144
+ ADF body again:
145
+
146
+ ```bash
147
+ curl -s -X POST \
148
+ -H "Authorization: Bearer $TOKEN" -H "Accept: application/json" -H "Content-Type: application/json" \
149
+ "https://api.atlassian.com/ex/jira/$CLOUD_ID/rest/api/3/issue/KAN-3/comment" \
150
+ -d '{
151
+ "body": {
152
+ "type": "doc", "version": 1,
153
+ "content": [ { "type": "paragraph", "content": [ { "type": "text", "text": "Update from the swarm." } ] } ]
154
+ }
155
+ }'
156
+ ```
157
+
158
+ ### 7. Assign an issue
159
+
160
+ Atlassian Cloud uses **accountId**, not username. Find one via:
161
+
162
+ ```bash
163
+ curl -s -G -H "Authorization: Bearer $TOKEN" -H "Accept: application/json" \
164
+ --data-urlencode 'query=taras' \
165
+ "https://api.atlassian.com/ex/jira/$CLOUD_ID/rest/api/3/user/search" \
166
+ | jq '.[] | {accountId, displayName, emailAddress}'
167
+ ```
168
+
169
+ Assign:
170
+ ```bash
171
+ curl -s -X PUT \
172
+ -H "Authorization: Bearer $TOKEN" -H "Accept: application/json" -H "Content-Type: application/json" \
173
+ "https://api.atlassian.com/ex/jira/$CLOUD_ID/rest/api/3/issue/KAN-3/assignee" \
174
+ -d '{"accountId":"<ACCOUNT_ID>"}'
175
+ ```
176
+
177
+ To unassign: `{"accountId": null}`.
178
+
179
+ ### 8. Edit fields on an existing issue
180
+
181
+ ```bash
182
+ curl -s -X PUT \
183
+ -H "Authorization: Bearer $TOKEN" -H "Accept: application/json" -H "Content-Type: application/json" \
184
+ "https://api.atlassian.com/ex/jira/$CLOUD_ID/rest/api/3/issue/KAN-3" \
185
+ -d '{ "fields": { "summary": "New summary", "labels": ["swarm","auto"] } }'
186
+ ```
187
+
188
+ Returns HTTP 204.
189
+
190
+ ## ADF cheat-sheet
191
+
192
+ ADF = JSON tree. Always wrap content in `{ "type": "doc", "version": 1, "content": [...] }`.
193
+
194
+ Common nodes:
195
+ - Paragraph: `{ "type": "paragraph", "content": [ { "type": "text", "text": "hi" } ] }`
196
+ - Bold: `{ "type": "text", "text": "x", "marks": [{ "type": "strong" }] }`
197
+ - Code inline: `{ "type": "text", "text": "x", "marks": [{ "type": "code" }] }`
198
+ - Code block: `{ "type": "codeBlock", "attrs": { "language": "bash" }, "content": [ { "type": "text", "text": "echo hi" } ] }`
199
+ - Bullet list: `{ "type": "bulletList", "content": [ { "type": "listItem", "content": [ { "type": "paragraph", "content": [...] } ] } ] }`
200
+ - Link: `{ "type": "text", "text": "click", "marks": [{ "type": "link", "attrs": { "href": "https://..." } }] }`
201
+
202
+ If you need rich content, build it in a script — don't try to write deep ADF inline in shell.
203
+
204
+ ## Operational rules
205
+
206
+ - **Token-expiry first.** Always check `expiresAt`. Don't loop on 401s.
207
+ - **Use the proxy.** All authenticated calls go through `api.atlassian.com/ex/jira/<cloudId>/...`. Hitting `desplega.atlassian.net/rest/api/3/...` with a 3LO bearer token will fail.
208
+ - **Discover transitions per issue** before transitioning — different projects/workflows have different IDs.
209
+ - **Use `/search/jql`**, not the legacy `/search` (which is deprecated and may be removed).
210
+ - **ADF is mandatory** for `description`, `comment`, and rich text fields. Plain strings will be rejected.
211
+ - **Account IDs, not usernames** for assignment, mentions, and filters.
212
+ - **Rate limits:** Atlassian rate-limits per app and per user. For bulk transitions/comments, sleep ~200–500 ms between calls.
213
+ - **Don't leak tokens.** Never echo the access token to logs or Slack. Read it into an env var only.
214
+
215
+ ## Error handling
216
+
217
+ | Status | Likely cause | Action |
218
+ |---|---|---|
219
+ | 401 | Token expired/invalid | Check `expiresAt`. Notify user to re-auth. Don't retry. |
220
+ | 403 | Missing scope, or restricted issue | Check the `scope` column. For `write:jira-work` operations, confirm scope is present. |
221
+ | 404 | Wrong key, wrong cloudId, wrong project | Re-verify with a project list call. |
222
+ | 400 | Body shape wrong (often ADF or required field) | Inspect `errorMessages` / `errors` in the response JSON. |
223
+ | 429 | Rate-limited | Back off, retry after `Retry-After` seconds. |
224
+
225
+ ## Complete worked example: clean a project
226
+
227
+ ```bash
228
+ TOKEN=$(db-query "SELECT accessToken FROM oauth_tokens WHERE provider='jira'")
229
+ CLOUD_ID="0054e739-8d39-4f01-8d6a-431619cae8fc"
230
+
231
+ # 1. List open issues in KAN
232
+ curl -s -G -H "Authorization: Bearer $TOKEN" -H "Accept: application/json" \
233
+ --data-urlencode 'jql=project = KAN AND statusCategory != Done' \
234
+ --data-urlencode 'fields=summary,status' \
235
+ "https://api.atlassian.com/ex/jira/$CLOUD_ID/rest/api/3/search/jql" \
236
+ | jq -r '.issues[].key' > /tmp/keys.txt
237
+
238
+ # 2. Transition each to Done (id 51 in KAN)
239
+ for KEY in $(cat /tmp/keys.txt); do
240
+ curl -s -X POST \
241
+ -H "Authorization: Bearer $TOKEN" -H "Accept: application/json" -H "Content-Type: application/json" \
242
+ "https://api.atlassian.com/ex/jira/$CLOUD_ID/rest/api/3/issue/$KEY/transitions" \
243
+ -d '{"transition":{"id":"51"}}'
244
+ sleep 0.3
245
+ done
246
+ ```
247
+
248
+ ## Notes for swarm sync (future)
249
+
250
+ - The MCP tracker tools (`tracker-link-task`, `tracker-sync-status`, etc.) are designed for two-way sync mappings. Jira tracker support exists at the schema level but is not currently wired up to inbound webhooks. Until it is, all Jira interaction must go through this skill.
251
+ - If/when inbound Jira webhooks land, this skill should add a "When to transition" section mirroring the Linear one.
252
+
@@ -0,0 +1,13 @@
1
+ {
2
+ "kind": "skill",
3
+ "name": "kapso-whatsapp",
4
+ "displayName": "WhatsApp Messaging",
5
+ "slug": "kapso-whatsapp",
6
+ "title": "WhatsApp Messaging",
7
+ "description": "Generic WhatsApp messaging guardrails for approved business messaging providers.",
8
+ "version": "1.0.0",
9
+ "category": "skills",
10
+ "placeholders": ["WHATSAPP_PROVIDER_API_KEY", "WHATSAPP_SENDER_ID"],
11
+ "runAllSeedersCandidate": false,
12
+ "tags": ["whatsapp", "messaging", "communications"]
13
+ }