@desplega.ai/agent-swarm 1.92.0 → 1.92.2

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 (90) hide show
  1. package/README.md +1 -1
  2. package/openapi.json +276 -3
  3. package/package.json +6 -6
  4. package/plugin/skills/pages/SKILL.md +5 -2
  5. package/src/be/db.ts +416 -20
  6. package/src/be/memory/boot-reembed.ts +85 -0
  7. package/src/be/memory/constants.ts +44 -2
  8. package/src/be/memory/providers/openai-embedding.ts +15 -5
  9. package/src/be/memory/providers/sqlite-store.ts +325 -76
  10. package/src/be/memory/reranker.ts +35 -17
  11. package/src/be/memory/types.ts +43 -0
  12. package/src/be/migrations/084_script_run_journal_duration.sql +5 -0
  13. package/src/be/migrations/085_script_runs_kind.sql +9 -0
  14. package/src/be/migrations/086_pages_default_authed.sql +64 -0
  15. package/src/be/migrations/087_skill_files.sql +19 -0
  16. package/src/be/modelsdev-cache.json +5622 -2543
  17. package/src/be/seed-scripts/catalog/boot-triage.ts +221 -0
  18. package/src/be/seed-scripts/catalog/catalog-report.ts +457 -0
  19. package/src/be/seed-scripts/catalog/compound-insights.ts +465 -0
  20. package/src/be/seed-scripts/catalog/gh-pr-snapshot.ts +1 -1
  21. package/src/be/seed-scripts/catalog/memory-eval.ts +1059 -0
  22. package/src/be/seed-scripts/catalog/ops-catalog-audit.ts +34 -439
  23. package/src/be/seed-scripts/catalog/schedule-health.ts +78 -2
  24. package/src/be/seed-scripts/catalog/task-failure-audit.ts +48 -1
  25. package/src/be/seed-scripts/index.ts +32 -4
  26. package/src/be/seed-skills/index.ts +0 -7
  27. package/src/be/skill-sync.ts +91 -7
  28. package/src/commands/runner.ts +6 -2
  29. package/src/heartbeat/templates.ts +20 -16
  30. package/src/http/index.ts +50 -7
  31. package/src/http/mcp-user.ts +23 -0
  32. package/src/http/mcp.ts +58 -0
  33. package/src/http/memory.ts +62 -0
  34. package/src/http/pages.ts +1 -1
  35. package/src/http/script-runs.ts +2 -0
  36. package/src/http/scripts.ts +39 -2
  37. package/src/http/skills.ts +225 -0
  38. package/src/providers/claude-adapter.ts +56 -24
  39. package/src/script-workflows/workflow-ctx.ts +7 -3
  40. package/src/scripts-runtime/sdk-allowlist.ts +1 -0
  41. package/src/scripts-runtime/swarm-sdk.ts +13 -0
  42. package/src/scripts-runtime/types/stdlib.d.ts +1 -0
  43. package/src/scripts-runtime/types/swarm-sdk.d.ts +1 -0
  44. package/src/server.ts +2 -0
  45. package/src/tasks/worker-follow-up.ts +12 -0
  46. package/src/tests/claude-adapter-binary.test.ts +135 -81
  47. package/src/tests/create-page-tool.test.ts +19 -2
  48. package/src/tests/heartbeat-checklist.test.ts +36 -0
  49. package/src/tests/mcp-transport-gc.test.ts +58 -0
  50. package/src/tests/memory-e2e.test.ts +6 -6
  51. package/src/tests/memory-health-endpoint.test.ts +78 -0
  52. package/src/tests/memory-rater-e2e.test.ts +4 -5
  53. package/src/tests/memory-reranker.test.ts +135 -124
  54. package/src/tests/memory-store.test.ts +221 -1
  55. package/src/tests/memory.test.ts +13 -12
  56. package/src/tests/pages-http.test.ts +20 -2
  57. package/src/tests/pages-storage.test.ts +26 -0
  58. package/src/tests/scripts-mcp-e2e.test.ts +53 -0
  59. package/src/tests/seed-scripts.test.ts +328 -3
  60. package/src/tests/skill-files-http.test.ts +171 -0
  61. package/src/tests/skill-files.test.ts +162 -0
  62. package/src/tests/skill-get-file-tool.test.ts +110 -0
  63. package/src/tests/skill-sync.test.ts +125 -6
  64. package/src/tests/task-cascade-fail.test.ts +304 -0
  65. package/src/tools/create-page.ts +2 -2
  66. package/src/tools/skills/index.ts +1 -0
  67. package/src/tools/skills/skill-get-file.ts +80 -0
  68. package/src/tools/tool-config.ts +2 -1
  69. package/src/types.ts +20 -0
  70. package/src/utils/internal-ai/complete-structured.ts +2 -2
  71. package/templates/schedules/daily-blocker-digest/content.md +68 -54
  72. package/templates/schedules/daily-compounding-reflection/content.md +4 -4
  73. package/templates/schedules/daily-hn-briefing/content.md +5 -5
  74. package/templates/schedules/daily-workflow-health-audit/content.md +6 -6
  75. package/templates/schedules/gtm-weekly-review/content.md +9 -9
  76. package/templates/schedules/weekly-dependabot-triage/content.md +24 -20
  77. package/templates/skills/agentmail-sending/content.md +6 -7
  78. package/templates/skills/desloppify/content.md +8 -9
  79. package/templates/skills/jira-interaction/content.md +25 -33
  80. package/templates/skills/kapso-whatsapp/content.md +29 -30
  81. package/templates/skills/linear-interaction/content.md +8 -9
  82. package/templates/skills/profile-corruption-escalation/content.md +44 -85
  83. package/templates/skills/sprite-cli/content.md +4 -5
  84. package/templates/skills/turso-interaction/content.md +14 -17
  85. package/templates/skills/workflow-iterate/content.md +38 -391
  86. package/templates/skills/x-api-interactions/content.md +4 -6
  87. package/templates/workflows/llm-safe-release-context/config.json +13 -0
  88. package/templates/workflows/llm-safe-release-context/content.md +69 -0
  89. package/templates/skills/scheduled-task-resilience/config.json +0 -14
  90. package/templates/skills/scheduled-task-resilience/content.md +0 -95
@@ -128,11 +128,12 @@ export const DEFERRED_TOOLS = new Set([
128
128
  // Approval Requests (1)
129
129
  "request-human-input",
130
130
 
131
- // Skills (11)
131
+ // Skills (12)
132
132
  "skill-create",
133
133
  "skill-update",
134
134
  "skill-delete",
135
135
  "skill-get",
136
+ "skill-get-file",
136
137
  "skill-list",
137
138
  "skill-search",
138
139
  "skill-install",
package/src/types.ts CHANGED
@@ -1555,12 +1555,18 @@ export const TERMINAL_SCRIPT_RUN_STATUSES = [
1555
1555
  ] as const;
1556
1556
  export type TerminalScriptRunStatus = (typeof TERMINAL_SCRIPT_RUN_STATUSES)[number];
1557
1557
 
1558
+ // `workflow` = durable background run launched via /api/script-runs (has a journal).
1559
+ // `inline` = synchronous one-off run via /api/scripts/run (no journal).
1560
+ export const ScriptRunKindSchema = z.enum(["workflow", "inline"]);
1561
+ export type ScriptRunKind = z.infer<typeof ScriptRunKindSchema>;
1562
+
1558
1563
  export const ScriptRunSchema = z.object({
1559
1564
  id: z.string().uuid(),
1560
1565
  agentId: z.string(),
1561
1566
  scriptName: z.string().optional(),
1562
1567
  source: z.string(),
1563
1568
  args: z.unknown(),
1569
+ kind: ScriptRunKindSchema,
1564
1570
  status: ScriptRunStatusSchema,
1565
1571
  pid: z.number().int().optional(),
1566
1572
  startedAt: z.string(),
@@ -1584,6 +1590,7 @@ export const ScriptRunJournalEntrySchema = z.object({
1584
1590
  error: z.string().optional(),
1585
1591
  startedAt: z.string(),
1586
1592
  completedAt: z.string().optional(),
1593
+ durationMs: z.number().optional(),
1587
1594
  });
1588
1595
  export type ScriptRunJournalEntry = z.infer<typeof ScriptRunJournalEntrySchema>;
1589
1596
 
@@ -1794,6 +1801,19 @@ export const SkillWithInstallInfoSchema = SkillSchema.extend({
1794
1801
  });
1795
1802
  export type SkillWithInstallInfo = z.infer<typeof SkillWithInstallInfoSchema>;
1796
1803
 
1804
+ export const SkillFileSchema = z.object({
1805
+ id: z.string(),
1806
+ skillId: z.string(),
1807
+ path: z.string(),
1808
+ content: z.string(),
1809
+ mimeType: z.string(),
1810
+ isBinary: z.boolean(),
1811
+ size: z.number().nullable(),
1812
+ createdAt: z.string(),
1813
+ lastUpdatedAt: z.string(),
1814
+ });
1815
+ export type SkillFile = z.infer<typeof SkillFileSchema>;
1816
+
1797
1817
  // ── MCP Servers ──────────────────────────────────────────────────────────
1798
1818
 
1799
1819
  export const McpServerTransportSchema = z.enum(["stdio", "http", "sse"]);
@@ -85,8 +85,8 @@ async function defaultSpawnClaudeCli(
85
85
  jsonSchema?: object,
86
86
  ): Promise<string> {
87
87
  // SWARM_USE_CLAUDE_BRIDGE mirrors the main claude adapter's subscription-pool
88
- // routing. Otherwise CLAUDE_BINARY may be a single binary ("claude", "shannon")
89
- // or a whitespace-separated command string ("bunx @dexh/shannon").
88
+ // routing. Otherwise CLAUDE_BINARY may be a single binary, an absolute path,
89
+ // or a whitespace-separated command string.
90
90
  const useClaudeBridge = ["true", "1"].includes(
91
91
  (process.env.SWARM_USE_CLAUDE_BRIDGE ?? "").trim().toLowerCase(),
92
92
  );
@@ -15,39 +15,53 @@ Ask the lead to summarize stuck work, failing checks, and owner decisions every
15
15
 
16
16
  ## Scheduled Task
17
17
 
18
- This is the full task prompt the schedule runs on each fire including the accumulated operational learnings baked into it. Adapt the swarm-specific references (channel IDs, agent names, repo paths) to your environment before enabling.
18
+ This is a reusable starting prompt. Before enabling it, adapt the placeholder repo list, Slack channel, owner mentions, memory paths, and escalation rules to your swarm. As you learn from real incidents, expand this template with your own local runbook notes instead of assuming these defaults cover every environment.
19
19
 
20
- Task Type: Daily Blocker Digest — "Compound Prelude" (unified with PR review)
20
+ Task Type: Daily Blocker Digest
21
21
 
22
- You are Lead. This runs 5 minutes before the compound evolution. Purpose: surface every item claimed to be "awaiting human" so the compound can detect stale-state items (blockers actually resolved but never removed), AND provide the single daily summary of open PRs. Rule from Taras (2026-04-22): verify, don't assume.
22
+ You are Lead. Produce one concise daily digest of blockers, stale claims, open PRs, and stuck work. Verify current state before escalating anything.
23
23
 
24
24
  ---
25
25
 
26
- ## Phase 1: Gather Blockers from 4 Sources
26
+ ## Phase 0: Seeded Data-Gathering
27
27
 
28
- ### 1A. HEARTBEAT.md "Active Blockers" section
29
- Read `/workspace/HEARTBEAT.md`. Extract every bullet under "Active Blockers (awaiting Taras)" or similar. Each item is a claim of the form "X is broken/pending".
28
+ Run these read-only global scripts first. Use their outputs as evidence, then apply judgment:
30
29
 
31
- ### 1B. Open PRs across all our repos with clickable URLs
32
- Loop over the repo list and gather ALL open PRs with their URL, age, review status, draft flag, labels, author.
30
+ 1. `script-run` global script `Heartbeat Audit` with args `{ "heartbeatMarkdown": "<current /workspace/HEARTBEAT.md text>" }`
31
+ 2. `script-run` global script `schedule-health` with args `{ "days": 7, "publishPage": true }`
32
+ 3. `script-run` global script `task-failure-audit` with args `{ "days": 7, "groupBy": "reason", "publishPage": true }`
33
+
34
+ Do not script-ify judgment or notification copy. Use the script outputs to identify stale blocker claims, schedule risks, provider failure clusters, and digest-run health.
35
+
36
+ ## Phase 1: Gather Blockers
37
+
38
+ ### 1A. HEARTBEAT.md active blockers
39
+
40
+ Read `/workspace/HEARTBEAT.md`. Extract every bullet under "Active Blockers" or a similar section. Treat each item as a claim that must be verified, not as ground truth.
41
+
42
+ ### 1B. Open PRs across tracked repositories
43
+
44
+ Replace the repo list below with repositories your team wants in the digest:
33
45
 
34
46
  ```bash
35
- for repo in desplega-ai/agent-swarm desplega-ai/agent-swarm-landing desplega-ai/landing desplega-ai/landing-labs desplega-ai/qa-use desplega-ai/agent-fs desplega-ai/chat-py desplega-ai/argus desplega-ai/argus-action desplega-ai/ai-toolbox desplega-ai/agent-work; do
47
+ for repo in owner/repo-one owner/repo-two owner/repo-three; do
36
48
  gh pr list --repo "$repo" --state open --json number,title,author,createdAt,url,reviewDecision,isDraft,labels 2>/dev/null | jq --arg repo "$repo" '.[] | . + {repo: $repo}'
37
49
  done
38
50
  ```
39
51
 
40
52
  Compute `daysOpen` from `createdAt`. Split PRs into buckets:
41
- - **Dependabot**: author.login == "dependabot" or "app/dependabot" — handled separately at the bottom
42
- - **Security dependabot**: any dependabot PR with "critical", "high", "security", or "vulnerability" in title or labels — list separately with :shield:
43
- - **Stale** (60+ days open): :rotating_light: at the top
44
- - **Aging** (30-59 days): :warning:
45
- - **Recent** (<30 days): normal listing
53
+ - **Dependency updates**: author.login is `dependabot` or `app/dependabot`
54
+ - **Security dependency updates**: dependency PRs with "critical", "high", "security", or "vulnerability" in title or labels
55
+ - **Stale**: 60+ days open
56
+ - **Aging**: 30-59 days open
57
+ - **Recent**: fewer than 30 days open
46
58
 
47
- Format every PR link as: `<URL|repo #NUM>` always a clickable Slack link, never raw numbers.
59
+ Format every PR link as `<URL|repo #NUM>` so the digest is clickable.
48
60
 
49
61
  ### 1C. Tasks awaiting user reply
62
+
50
63
  Use `db-query`:
64
+
51
65
  ```sql
52
66
  SELECT id, task, slackUserId, createdAt
53
67
  FROM agent_tasks
@@ -60,46 +74,48 @@ LIMIT 20
60
74
  ```
61
75
 
62
76
  ### 1D. Stuck in-flight tasks
63
- Use `get-tasks` with status=in_progress. Flag any with `lastUpdatedAt` >2h old.
77
+
78
+ Use `get-tasks` with `status=in_progress`. Flag any task with no update for more than 2 hours. Cross-check against the seeded script outputs before escalating.
64
79
 
65
80
  ---
66
81
 
67
- ## Phase 2: Verify Each Blocker Claim
82
+ ## Phase 2: Verify Each Claim
68
83
 
69
- For each claim in 1A, run a quick verification:
70
- - PR numbers check if merged (use gh pr view)
71
- - API/key issues test the actual API (curl + check response)
72
- - "awaiting response from X" items check Slack thread for newer messages
73
- - Worker-activity claims check the actual task status
84
+ For each blocker claim, run a quick verification:
85
+ - PR numbers: check whether the PR is still open or already merged
86
+ - API/key issues: test the actual API or check the current config status
87
+ - "Awaiting response" items: check the relevant thread for newer replies
88
+ - Worker-activity claims: check the current task status
74
89
 
75
- Do NOT trust the HEARTBEAT wording. If verification shows the item is resolved, mark it `RESOLVED-STALE` and commit to removing from HEARTBEAT in Phase 4.
90
+ Do not trust stale notes. If verification shows the item is resolved, mark it `RESOLVED-STALE` and remove it from the source note in Phase 4.
76
91
 
77
92
  ---
78
93
 
79
- ## Phase 3: Post Unified Digest to Slack
94
+ ## Phase 3: Post One Digest
80
95
 
81
- Use `slack-post` with channelId `C0A4J7GB0UD`, pinging `<@U08NR6QD6CS>`. Format:
96
+ Post one message to your team's chosen channel. Replace `<OWNER_OR_TEAM_MENTION>` and `<CHANNEL_ID>` before enabling this schedule.
82
97
 
83
- ```
98
+ Template:
99
+
100
+ ```text
84
101
  :clipboard: *Daily Blocker Digest + PR Review* — [YYYY-MM-DD]
85
102
 
86
- <@U08NR6QD6CS> Here's the combined morning digest.
103
+ <OWNER_OR_TEAM_MENTION> Here's the daily digest.
87
104
 
88
- *Awaiting Taras — HEARTBEAT blockers* (N verified real, M stale)
89
- • PR link — <title> — [verified: still open]
90
- <other item>[verified: status]
91
- • ~~<stale item>~~ — RESOLVED-STALE, removed from HEARTBEAT
105
+ *Active blockers* (N verified real, M stale)
106
+ <PR or task link> — <title> — [verified: still open]
107
+ ~~<stale item>~~RESOLVED-STALE, removed from source notes
92
108
 
93
- :rotating_light: *STALE PRs (60+ days)*
109
+ *Stale PRs (60+ days)*
94
110
  1. <url|repo #NUM> — <title> (X days) — @author
95
111
 
96
- :warning: *AGING PRs (30-59 days)*
112
+ *Aging PRs (30-59 days)*
97
113
  1. <url|repo #NUM> — <title> (X days) — @author
98
114
 
99
115
  *Recent PRs*
100
116
  1. <url|repo #NUM> — <title> (X days) — @author
101
117
 
102
- :shield: *Security dependabot (merge soon)*
118
+ *Security dependency updates*
103
119
  • <url|repo #NUM> — <bump text>
104
120
 
105
121
  *Tasks awaiting user reply* (N)
@@ -109,42 +125,40 @@ Use `slack-post` with channelId `C0A4J7GB0UD`, pinging `<@U08NR6QD6CS>`. Format:
109
125
  • <task id> — <age>
110
126
 
111
127
  ---
112
- _Also: X dependabot PRs pending (routine dependency bumps)_
113
- _Stale HEARTBEAT items removed this run: N_
128
+ Dependency update PRs pending: X
129
+ Stale source-note items removed this run: Y
114
130
  ```
115
131
 
116
- Keep it scannable. Every PR MUST be a clickable `<url|repo #N>` link. If everything is clean, say "All clear — no blockers, no stuck tasks, only routine dependabot churn."
132
+ If everything is clean, say: "All clear — no blockers, no stuck tasks, only routine dependency-update churn."
117
133
 
118
134
  ---
119
135
 
120
- ## Phase 4: Clean HEARTBEAT.md
136
+ ## Phase 4: Clean Source Notes
121
137
 
122
138
  For each item marked `RESOLVED-STALE`:
123
- - Remove the line from `/workspace/HEARTBEAT.md`
124
- - Save a shared memory noting the stale-state catch (permanent receipt for the compound)
139
+ - Remove or update the stale line in the source note, such as `/workspace/HEARTBEAT.md`
140
+ - Save a memory noting how the stale state was detected, so future runs can catch the same pattern sooner
125
141
 
126
142
  ---
127
143
 
128
- ## Phase 5: Hand-off to Compound
129
-
130
- Write a memory titled `daily-blocker-digest-YYYY-MM-DD.md` to `/workspace/shared/memory/d454d1a5-4df9-49bd-8a89-e58d6a657dc3/` with:
131
- - List of all verified blockers (still real) with PR URLs
132
- - List of RESOLVED-STALE items removed this run
133
- - Summary counts: total PRs open, stale count, aging count
134
- - Any patterns noticed ("I keep forgetting X finished shipping on date Y")
144
+ ## Phase 5: Save a Receipt
135
145
 
136
- The compound evolution runs 5 minutes after this. Its Phase 0 reads this memory via `memory-search "daily-blocker-digest"`.
146
+ Write a memory titled `daily-blocker-digest-YYYY-MM-DD.md` with:
147
+ - Verified blockers that are still real
148
+ - RESOLVED-STALE items removed
149
+ - Summary counts: total open PRs, stale count, aging count, dependency-update count
150
+ - Patterns noticed and template improvements worth adding
137
151
 
138
152
  ---
139
153
 
140
154
  ## Anti-patterns
141
155
 
142
- - Copying HEARTBEAT verbatim without verifying each line
143
- - Raw PR numbers instead of clickable `<url|repo #N>` links
144
- - Listing all dependabot PRs inline collapse into single footer count (except security ones)
145
- - Marking things RESOLVED-STALE without evidence
146
- - Skipping Phase 4 — if you don't clean HEARTBEAT, the problem recurs tomorrow
156
+ - Copying HEARTBEAT or source notes verbatim without verifying each line
157
+ - Raw PR numbers instead of clickable `<url|repo #N>` links
158
+ - Listing all dependency-update PRs inline when a count is enough
159
+ - Marking things RESOLVED-STALE without evidence
160
+ - Skipping source-note cleanup
147
161
 
148
162
  ## Completion
149
163
 
150
- Call `store-progress` with status `completed` and `output` = one-paragraph summary of (a) how many blockers verified real vs stale, (b) PR counts (stale/aging/recent/dependabot), (c) any surprises.
164
+ Call `store-progress` with status `completed` and an output paragraph covering verified blockers, stale items removed, PR counts, and any follow-up needed.
@@ -15,11 +15,11 @@ Capture lessons from the day into memory, skills, and workflow improvements.
15
15
 
16
16
  ## Scheduled Task
17
17
 
18
- This is the full task prompt the schedule runs on each fire — including the accumulated operational learnings baked into it. Adapt the swarm-specific references (channel IDs, agent names, repo paths) to your environment before enabling.
18
+ This is the full task prompt the schedule runs on each fire. Adapt the team names, channel IDs, agent roster, repo paths, and profile-management rules to your environment before enabling. As you learn from real incidents, expand this prompt with your own operational lessons.
19
19
 
20
20
  Task Type: Daily Evolution — "Compounding Engine"
21
21
 
22
- You are Lead. This is the swarm's daily evolution routine. You are a real team working for Desplega Labs (desplega.ai) — the agent swarm, agent-fs, and related products. Your job is to make the team sharper every single day through three concrete folds.
22
+ You are Lead. This is the swarm's daily evolution routine. You are operating a real team of agents for your organization. Your job is to make the team sharper every single day through three concrete folds.
23
23
 
24
24
  The purpose is NOT to write a nice Slack post. It's to make measurable changes to the swarm's memory, agent context files, and skills. The Slack post is just the receipt.
25
25
 
@@ -69,7 +69,7 @@ The swarm's memory is its institutional knowledge. It should grow smarter, not j
69
69
  Each agent has context files that shape how they think and work: SOUL.md (personality, values, core identity), IDENTITY.md (role, expertise, working style), CLAUDE.md (operational rules, project instructions), and TOOLS.md (environment knowledge). These should evolve based on real performance.
70
70
 
71
71
  ### 2A. Performance Review (per agent)
72
- For each active agent (Lead, Picateclas, Researcher, Reviewer, Tester, Jackknife):
72
+ For each active agent in your swarm roster:
73
73
  - How many tasks did they complete in the last 24-48h?
74
74
  - Did any tasks fail? What was the failure pattern?
75
75
  - Did they need retries or corrections?
@@ -152,7 +152,7 @@ For each candidate:
152
152
 
153
153
  ## Phase 4: Post to Slack (THE RECEIPT)
154
154
 
155
- Use `slack-post` with channelId "C0A4J7GB0UD". Format:
155
+ Use `slack-post` with your configured channel ID. Format:
156
156
 
157
157
  ```
158
158
  🧬 Daily Evolution — [date]
@@ -24,7 +24,7 @@ Instructions:
24
24
 
25
25
  1. Use qa-use browser commands (e.g., `/qa-use:explore`) to scrape the following HN pages **ONE AT A TIME, STRICTLY SEQUENTIAL**.
26
26
 
27
- **CRITICAL — DO NOT PARALLELIZE.** Do NOT fan out parallel browser sessions, do NOT launch multiple Browser Use SDK flows concurrently, do NOT batch the URLs into a single multi-target call. This template has auto-failed on 2026-05-10 and 2026-05-11 because the worker scraped all 5 URLs in parallel and crossed the heartbeat-stale watchdog threshold before the flows completed. Strict serial execution is required.
27
+ **CRITICAL — DO NOT PARALLELIZE.** Do NOT fan out parallel browser sessions, do NOT launch multiple Browser Use SDK flows concurrently, do NOT batch the URLs into a single multi-target call. Browser-heavy runs can cross the heartbeat-stale watchdog threshold when several pages are scraped in parallel. Strict serial execution is required.
28
28
 
29
29
  **Workflow:** Scrape URL #1 → call `store-progress` with a one-line update (e.g., "Scraped HN page 1 — N stories found") → scrape URL #2 → `store-progress` → … → URL #5 → `store-progress`. After every individual URL scrape, you MUST call `store-progress` BEFORE starting the next URL. This keeps the session heartbeat fresh and prevents the watchdog from killing the task.
30
30
 
@@ -42,7 +42,7 @@ Instructions:
42
42
  - Agentic coding / AI-powered development
43
43
  - E2E testing / browser automation / QA
44
44
  - Developer tools / DevOps
45
- - Startups / SaaS relevant to Desplega's space
45
+ - Startups / SaaS relevant to your team's space
46
46
 
47
47
  3. Format a quick-scan briefing. Organize by source section:
48
48
  - **Front Page** (from pages 1-3)
@@ -60,7 +60,7 @@ Instructions:
60
60
  • Emdash — Open-source agentic dev environment (https://news.ycombinator.com/item?id=12345) · Feb 24 · 65 pts · 30 comments
61
61
  Direct peer to Cursor/Windsurf — agentic-first IDE.
62
62
 
63
- 4. If any story is exceptionally relevant to Desplega (E2E testing, browser automation, AI agents), add a "Deep Dive" section with 2-3 sentences.
63
+ 4. If any story is exceptionally relevant to your team's focus areas, add a "Deep Dive" section with 2-3 sentences.
64
64
 
65
65
  5. STORE THE REPORT: Save the full briefing as a markdown file at:
66
66
  /workspace/shared/hn-briefings/YYYY-MM-DD.md
@@ -73,7 +73,7 @@ Instructions:
73
73
 
74
74
  6. SEND EMAIL: Use AgentMail MCP tools to send the report as an email:
75
75
  - From inbox: lead@agent-swarm.dev
76
- - To: t@desplega.ai AND e@desplega.ai
76
+ - To: the configured recipient list for this briefing
77
77
  - Subject: "HN Briefing — [TODAY'S DATE, e.g. Feb 25, 2026]"
78
78
  - Body: Send as HTML email. Format the briefing nicely with:
79
79
  - A header: "HN Briefing — [DATE]"
@@ -94,4 +94,4 @@ IMPORTANT:
94
94
  - Target 5-20 relevant stories (quality over quantity)
95
95
  - You MUST scrape all 5 URLs (3 main pages + new + show) — this is required, but ONE AT A TIME
96
96
  - The email is sent from lead@agent-swarm.dev using AgentMail MCP `send_message` tool
97
- - Recipients: t@desplega.ai AND e@desplega.ai
97
+ - Recipients: use the configured recipient list for this briefing
@@ -15,11 +15,11 @@ Check scheduled jobs and workflows for repeated failures, stale runs, and silent
15
15
 
16
16
  ## Scheduled Task
17
17
 
18
- This is the full task prompt the schedule runs on each fire including the accumulated operational learnings baked into it. Adapt the swarm-specific references (channel IDs, agent names, repo paths) to your environment before enabling.
18
+ This is the full task prompt the schedule runs on each fire. Adapt the channel IDs, mentions, app URLs, and escalation rules to your environment before enabling. As you learn from real incidents, expand this prompt with your own local failure modes and recovery notes.
19
19
 
20
20
  Task Type: Daily Workflow + Schedule Health Audit
21
21
 
22
- You are Lead. Run this audit and post a single Slack digest. **Source ask:** Eze in `C0A4J7GB0UD` thread ts `1779264760.065579` (2026-05-20). Cadence: daily at 08:00 UTC. Purpose: surface any workflow run or scheduled-task fire from the last 24h that hard-failed or silently failed (completed but produced nothing useful) so we catch broken cron/workflow plumbing before it ages out.
22
+ You are Lead. Run this audit and post a single Slack digest. Cadence: daily at 08:00 UTC. Purpose: surface any workflow run or scheduled-task fire from the last 24h that hard-failed or silently failed (completed but produced nothing useful) so the team catches broken cron/workflow plumbing before it ages out.
23
23
 
24
24
  ---
25
25
 
@@ -137,7 +137,7 @@ If TOTAL issues across 1A–1F is zero:
137
137
  ```
138
138
  :white_check_mark: *Daily Workflow + Schedule Health Audit* — <YYYY-MM-DD>
139
139
 
140
- <@U08NY4B5R2M> All clear — <workflowRuns24h> workflow runs + <scheduledFires24h> scheduled fires in the last 24h, all produced expected output.
140
+ <OWNER_OR_TEAM_MENTION> All clear — <workflowRuns24h> workflow runs + <scheduledFires24h> scheduled fires in the last 24h, all produced expected output.
141
141
  ```
142
142
 
143
143
  Otherwise:
@@ -145,7 +145,7 @@ Otherwise:
145
145
  ```
146
146
  :stethoscope: *Daily Workflow + Schedule Health Audit* — <YYYY-MM-DD>
147
147
 
148
- <@U08NY4B5R2M> Audit window: last 24h. Totals: <workflowRuns24h> workflow runs · <scheduledFires24h> scheduled fires · *<TOTAL_ISSUES> issues*
148
+ <OWNER_OR_TEAM_MENTION> Audit window: last 24h. Totals: <workflowRuns24h> workflow runs · <scheduledFires24h> scheduled fires · *<TOTAL_ISSUES> issues*
149
149
 
150
150
  *Hard failures — workflow runs* (<N1A>)
151
151
  • <url|workflow:name> — failed <relative-time>
@@ -174,7 +174,7 @@ Omit any section whose count is 0. Cap message at 4000 chars (Slack limit) — i
174
174
 
175
175
  ## Phase 3 — Post to Slack and complete
176
176
 
177
- 1. Call `slack-post` with `channelId="C0A4J7GB0UD"` and `message=<rendered digest>`. **Do NOT** thread under the design thread `1779264760.065579` daily fires are top-level so they're easy to scan.
177
+ 1. Call `slack-post` with your configured channel ID and `message=<rendered digest>`. Prefer a top-level daily fire unless your team's convention is to thread recurring audit messages.
178
178
  2. Call `store-progress` with `status: "completed"` and a one-paragraph `output` summary:
179
179
  - `Issues found: hard-fail-wf=<N1A>, hard-fail-task=<N1B>, halted-24h=<N1C>, silent-empty=<N1D>, cron-stuck=<N1E>, consec-err=<N1F>.`
180
180
  - `Totals: workflowRuns24h=<X>, scheduledFires24h=<Y>.`
@@ -185,5 +185,5 @@ Omit any section whose count is 0. Cap message at 4000 chars (Slack limit) — i
185
185
  - ❌ Posting a separate Slack message per failure mode — ONE digest.
186
186
  - ❌ Raw IDs without clickable URLs.
187
187
  - ❌ Dumping full `error` / `output` content — truncate to 220 chars per item.
188
- - ❌ Threading the daily digest under the original 1779264760.065579 design thread.
188
+ - ❌ Threading the daily digest somewhere your team will not scan.
189
189
  - ❌ Skipping the "all clear" message when zero issues — the heartbeat itself is the signal that the audit ran.
@@ -15,25 +15,25 @@ Summarize product, marketing, or sales signals into an operator-friendly weekly
15
15
 
16
16
  ## Scheduled Task
17
17
 
18
- This is the full task prompt the schedule runs on each fire — including the accumulated operational learnings baked into it. Adapt the swarm-specific references (channel IDs, agent names, repo paths) to your environment before enabling.
18
+ This is the full task prompt the schedule runs on each fire. Adapt the repositories, Search Console properties, report paths, and campaign goals to your environment before enabling.
19
19
 
20
20
  Task Type: Research
21
- Topic: Weekly GTM Metrics Review for agent-swarm
21
+ Topic: Weekly GTM Metrics Review for your product
22
22
 
23
23
  Goal: Check current GitHub stars, traffic, Google Search Console performance, and content metrics for the GTM campaign.
24
24
 
25
25
  Instructions:
26
- 1. Check GitHub metrics: `gh api repos/desplega-ai/agent-swarm` (stars, forks, issues)
27
- 2. Check traffic: `gh api repos/desplega-ai/agent-swarm/traffic/views` and `/traffic/clones`
28
- 3. Check referrers: `gh api repos/desplega-ai/agent-swarm/traffic/popular/referrers`
29
- 4. Check popular content: `gh api repos/desplega-ai/agent-swarm/traffic/popular/paths`
26
+ 1. Check GitHub metrics: `gh api repos/owner/repo` (stars, forks, issues)
27
+ 2. Check traffic: `gh api repos/owner/repo/traffic/views` and `/traffic/clones`
28
+ 3. Check referrers: `gh api repos/owner/repo/traffic/popular/referrers`
29
+ 4. Check popular content: `gh api repos/owner/repo/traffic/popular/paths`
30
30
 
31
31
  5. **Pull Google Search Console data** using the `gsc-analytics` skill (already installed on this agent). Do NOT write Python auth code — use the `gsc` CLI at `/workspace/repos/agent-work/gsc/gsc`. The setup script already wires up `GOOGLE_APPLICATION_CREDENTIALS`, so no extra env setup needed.
32
32
 
33
- Pull the weekly snapshot for each of the 4 Desplega properties:
33
+ Pull the weekly snapshot for each configured site:
34
34
  ```bash
35
35
  GSC=/workspace/repos/agent-work/gsc/gsc
36
- for site in desplega.ai agent-swarm.dev desplega.sh agent-fs.dev; do
36
+ for site in example.com docs.example.com; do
37
37
  echo "=== $site ==="
38
38
  $GSC analytics "sc-domain:$site" --top 20 --json > "/tmp/gsc-$site.json"
39
39
  jq '{current, previous, window, prior,
@@ -55,4 +55,4 @@ Instructions:
55
55
 
56
56
  Save report to /workspace/shared/thoughts/shared/research/gtm-weekly-{date}.md
57
57
 
58
- This is part of the GTM: Agent Swarm 100k GitHub Stars epic.
58
+ This is part of your team's GTM goal; update the goal statement before enabling the schedule.
@@ -15,31 +15,35 @@ Review dependency update PRs, group safe patches, and flag risky upgrades.
15
15
 
16
16
  ## Scheduled Task
17
17
 
18
- This is the full task prompt the schedule runs on each fire — including the accumulated operational learnings baked into it. Adapt the swarm-specific references (channel IDs, agent names, repo paths) to your environment before enabling.
18
+ This is a reusable starting prompt. Before enabling it, replace the repository, paths, branch names, reviewers, and notification target with values for your project.
19
19
 
20
- Triage dependabot PRs from https://github.com/desplega-ai/desplega.ai/pulls
20
+ Task Type: Weekly Dependency Triage
21
+
22
+ Repository: `owner/repo`
23
+ Important paths: `path-one`, `path-two`
21
24
 
22
25
  ## Instructions
23
26
 
24
- 1. **List all open dependabot PRs** in desplega-ai/desplega.ai using `gh pr list`
25
- 2. **Only paths we care about**: `/be` and `/new-fe`. Close all other dependabot PRs (ones that don't touch these paths).
26
- 3. **DO NOT touch non-dependabot PRs** — leave them as-is.
27
- 4. **Create two unified PRs** that merge all dependabot bumps into one PR each:
28
- - One for `/be` changes — branch name format: `YYYY-MM-DD-dependabot-be` (use today's date)
29
- - One for `/new-fe` changes — branch name format: `YYYY-MM-DD-dependabot-fe` (use today's date)
30
- - Each unified PR should be based on latest `main` and include all the dependency bumps from the individual dependabot PRs for that path.
31
- - After creating the unified PRs, close the individual dependabot PRs that were merged into them.
32
- 5. **Return the URLs** of the two final unified PRs.
33
- 6. If there are no open dependabot PRs, just report that and complete.
27
+ 1. List all open dependency-update PRs in the configured repository using `gh pr list`.
28
+ 2. Separate PRs by the paths they touch. Close or ignore PRs outside the configured path list only if that is your team's policy.
29
+ 3. Do not touch non-dependency PRs.
30
+ 4. For each configured path, create one unified PR that combines compatible dependency bumps:
31
+ - Branch name format: `YYYY-MM-DD-dependencies-<path-name>`
32
+ - Base the branch on latest `main`
33
+ - Include the dependency bumps for that path
34
+ - Leave incompatible or conflicting upgrades as separate PRs with notes
35
+ 5. After creating a unified PR, close only the individual dependency PRs that were incorporated.
36
+ 6. Return the final PR URLs and call out any skipped PRs with a reason.
37
+ 7. If there are no open dependency PRs, report that and complete.
34
38
 
35
39
  ## Approach
36
40
 
37
- - Clone the repo, checkout main, pull latest
38
- - For each path (be, new-fe): create a branch, cherry-pick or merge the dependabot changes, push, create PR
39
- - Close individual dependabot PRs after unifying
40
- - Be careful: some dependabot PRs may have conflicts — handle gracefully
41
+ - Clone or update the repo, checkout `main`, and pull latest
42
+ - Create a branch per path group
43
+ - Cherry-pick, merge, or manually apply each dependency update as appropriate
44
+ - Run the repo's required dependency checks before pushing
45
+ - Push, open PRs, request the configured reviewers, and notify the configured channel or thread
46
+
47
+ ## Completion
41
48
 
42
- ## Important
43
- - The PR title should be descriptive, e.g. "chore(be): consolidate dependabot bumps YYYY-MM-DD"
44
- - Add @tarasyarema as reviewer on both PRs
45
- - Post the final PR URLs back to Slack
49
+ Call `store-progress` with status `completed` and an output summary listing unified PR URLs, closed source PRs, skipped PRs, and failed checks if any.
@@ -4,7 +4,7 @@ These rules are MANDATORY for all agents sending email via AgentMail. Violating
4
4
 
5
5
  ## Rule 1: TEXT ONLY — Never Pass `html` Parameter
6
6
 
7
- **AgentMail has a critical bug (as of 2026-03-25):** When both `text` and `html` parameters are passed to `send_message` or `reply_to_message`, the HTML body content is silently dropped. The resulting email has an empty `<div dir="ltr"></div>`. Email clients (Gmail, etc.) prefer the HTML version over plain text, so recipients see a completely blank email.
7
+ **AgentMail can drop visible email content when both `text` and `html` parameters are passed:** Some clients prefer the HTML version, so a blank or malformed HTML body can make recipients see an empty email even when plain text was provided.
8
8
 
9
9
  **What to do:**
10
10
  - ONLY pass the `text` parameter
@@ -13,22 +13,22 @@ These rules are MANDATORY for all agents sending email via AgentMail. Violating
13
13
 
14
14
  **Why this matters:** This bug caused real outbound prospect emails to arrive blank, burning contacts permanently. It is not a cosmetic issue — it's a data loss / reputation issue.
15
15
 
16
- ## Rule 2: Always BCC t@desplega.ai on Outbound Emails
16
+ ## Rule 2: Apply Your Team's Outbound Visibility Policy
17
17
 
18
- All outbound emails to external recipients (anyone outside @agent-swarm.dev) MUST include `t@desplega.ai` as BCC. This gives the human founder visibility into what emails the swarm is sending.
18
+ All outbound emails to external recipients must follow your deployment's visibility policy. If your team requires a BCC reviewer or audit inbox, include that configured address. Do not hardcode another organization's reviewer address into this template.
19
19
 
20
20
  **How:**
21
21
  ```
22
22
  send_message({
23
23
  inboxId: "lead@agent-swarm.dev",
24
24
  to: ["recipient@example.com"],
25
- bcc: ["t@desplega.ai"],
25
+ bcc: ["configured-reviewer@example.com"],
26
26
  subject: "...",
27
27
  text: "..."
28
28
  })
29
29
  ```
30
30
 
31
- **Exception:** Internal emails between agent inboxes (@agent-swarm.dev) or to t@desplega.ai / e@desplega.ai directly do NOT need BCC.
31
+ **Exception:** Internal emails between agent inboxes or messages already addressed to the configured reviewer list do not need an extra BCC.
32
32
 
33
33
  ## Rule 3: Always Include Signature
34
34
 
@@ -42,7 +42,6 @@ Never send outreach/cold emails to external prospects without explicit human app
42
42
 
43
43
  Before every `send_message` or `reply_to_message` call:
44
44
  - [ ] Only `text` param, NO `html` param
45
- - [ ] BCC `t@desplega.ai` if recipient is external
45
+ - [ ] Apply the configured BCC/audit policy if the recipient is external
46
46
  - [ ] Plain text signature appended
47
47
  - [ ] Human-approved if it's outreach/cold email
48
-
@@ -1,6 +1,6 @@
1
1
  # desloppify — Code-health scan workflow (swarm edition)
2
2
 
3
- `desloppify` is a multi-language codebase health scanner (peteromallet/desloppify). This skill is the swarm-adapted SKILL.md: it codifies the **install recipe with the tree-sitter pin**, the surface-only **scan → status → next → triage** workflow we run for repos like `agent-swarm`, and the **publish-to-agent-fs** step so humans (Eze) can see the findings.
3
+ `desloppify` is a multi-language codebase health scanner (peteromallet/desloppify). This skill is the swarm-adapted SKILL.md: it codifies the **install recipe with the tree-sitter pin**, the surface-only **scan → status → next → triage** workflow for code-health scans, and the **publish-to-agent-fs** step so humans can see the findings.
4
4
 
5
5
  > **Default mode for swarm workers: surface-only.** Run Phase 1 + early Phase 2, publish a memo to agent-fs, stop. Do **not** run Phase 3 (queue-grinding refactors) unless the task explicitly asks.
6
6
 
@@ -8,7 +8,7 @@
8
8
 
9
9
  - A task asks you to run desloppify, do a code-health scan, get a health score, or surface debt themes on a repo.
10
10
  - A task references `peteromallet/desloppify` or the upstream `docs/SKILL.md`.
11
- - You need to triage tech debt on a TS / Python / multi-lang repo (agent-swarm, landing, agent-swarm-landing, desplega-ai, etc.).
11
+ - You need to triage tech debt on a TS / Python / multi-lang repo.
12
12
 
13
13
  If the task is "fix this one bug" or "rename X" → not this skill. Desloppify is for batch debt-surfacing, not point fixes.
14
14
 
@@ -28,7 +28,7 @@ pipx runpip desloppify show tree-sitter-language-pack | grep Version
28
28
 
29
29
  ## Step 2 — Install (first run only)
30
30
 
31
- Use `pipx`. This is the working recipe verified in PR #463 (Dockerfile.worker) and across multiple sprite smokes:
31
+ Use `pipx`. This keeps the scanner isolated from the project environment:
32
32
 
33
33
  ```bash
34
34
  pipx install 'desloppify[full]==0.9.15'
@@ -39,7 +39,7 @@ pipx runpip desloppify show tree-sitter-language-pack | grep Version
39
39
  # → must show 1.6.2 (or another <1.8)
40
40
  ```
41
41
 
42
- **Why the pin:** `tree-sitter-language-pack` 1.8.0 has an ABI mismatch with `tree-sitter` that crashes desloppify in `cohesion.py:52` → `extractors.py:90` with a `TypeError`. Upstream fix is [peteromallet/desloppify#605](https://github.com/peteromallet/desloppify/pull/605) open, unmerged. Until that ships, we cap locally. (See task `616b4bba-43de-40b5-af3b-4e219b622218` for the full repro.)
42
+ **Why the pin:** some `tree-sitter-language-pack` 1.8.x builds have ABI mismatches with `tree-sitter` that crash scans during language extraction. Until the installed scanner version is known to work with newer language-pack releases, cap it below 1.8.
43
43
 
44
44
  If `pipx` isn't installed: `python3 -m pip install --user pipx && python3 -m pipx ensurepath` and start a new shell. If `pipx install` fails with build errors, jump to **Sprite escape hatch** below.
45
45
 
@@ -94,11 +94,11 @@ What to capture for the memo:
94
94
 
95
95
  ## Step 6 — Publish findings to agent-fs
96
96
 
97
- Save the scan memo so Eze and the swarm can see it. Use the shared org (`648a5f3c-35c8-4f11-8673-b89de52cd6bd`) and namespace the path under your own agent ID:
97
+ Save the scan memo somewhere durable so operators can review it. If your deployment uses agent-fs, write it under your own agent namespace:
98
98
 
99
99
  ```bash
100
100
  DATE=$(date +%Y-%m-%d)
101
- agent-fs --org 648a5f3c-35c8-4f11-8673-b89de52cd6bd write \
101
+ agent-fs --org <org-id> write \
102
102
  thoughts/$AGENT_ID/research/$DATE-desloppify-<repo>-scan.md \
103
103
  --content "$(cat <<'EOF'
104
104
  # desloppify scan — <repo> @ <SHA>
@@ -160,7 +160,7 @@ sprite exec -s desloppify-scan -- bash -c '
160
160
  pipx install "desloppify[full]==0.9.15"
161
161
  pipx inject --force desloppify "tree-sitter-language-pack<1.8"
162
162
  pipx runpip desloppify show tree-sitter-language-pack | grep Version
163
- git clone --depth=1 https://github.com/desplega-ai/<repo>.git /tmp/repo
163
+ git clone --depth=1 https://github.com/<owner>/<repo>.git /tmp/repo
164
164
  cd /tmp/repo
165
165
  desloppify scan --path .
166
166
  desloppify status
@@ -191,11 +191,10 @@ desloppify status
191
191
  desloppify next --count 15
192
192
 
193
193
  # Publish + report
194
- agent-fs --org 648a5f3c-35c8-4f11-8673-b89de52cd6bd write thoughts/$AGENT_ID/research/$(date +%F)-desloppify-<repo>-scan.md --content "..." -m "scan memo"
194
+ agent-fs --org <org-id> write thoughts/$AGENT_ID/research/$(date +%F)-desloppify-<repo>-scan.md --content "..." -m "scan memo"
195
195
  # slack-reply on the originating thread
196
196
  ```
197
197
 
198
198
  ## Upstream reference
199
199
 
200
200
  Full Phase 3 / review workflow / plan commands are in the upstream SKILL.md: <https://github.com/peteromallet/desloppify/blob/main/docs/SKILL.md>. Reach for it when you're explicitly asked to grind the queue (rare). Default swarm mode stops after the memo + Slack reply.
201
-