@desplega.ai/agent-swarm 1.145.0 → 1.147.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/README.md +2 -1
- package/dist/{acp-adapter-580t41c0.js → acp-adapter-9n319wqc.js} +61 -6
- package/dist/{actions-m662tjng.js → actions-2vxqvpr9.js} +9 -8
- package/dist/{app-zb3rndm8.js → app-w066xfy0.js} +6 -5
- package/dist/assistant-kt31dj2h.js +236 -0
- package/dist/{boot-reembed-072x00vn.js → boot-reembed-az5rassp.js} +7 -6
- package/dist/{boot-reembed-65zz2smt.js → boot-reembed-j3mm3rfz.js} +8 -7
- package/dist/{boot-scrub-logs-yz0ams04.js → boot-scrub-logs-b6h54817.js} +4 -4
- package/dist/{claude-adapter-paj270y2.js → claude-adapter-w1z04ann.js} +8 -6
- package/dist/{claude-managed-setup-w619jncn.js → claude-managed-setup-f5pmsyrp.js} +24 -3
- package/dist/{claude-sdk-session-swt80j9z.js → claude-sdk-session-f0cc1kec.js} +8 -6
- package/dist/{cli-dt553ktb.js → cli-0b6y7kxm.js} +1 -1
- package/dist/{cli-bxdhw615.js → cli-12fz972k.js} +4 -4
- package/dist/{cli-s2f20r5w.js → cli-1th1728g.js} +2 -2
- package/dist/{cli-rs6ec3b9.js → cli-3tgwnf43.js} +3 -3
- package/dist/{cli-gxnzc6wh.js → cli-4nr988h6.js} +1 -1
- package/dist/{cli-axs8e6d4.js → cli-53s590z8.js} +1 -1
- package/dist/{cli-ygbjp3z8.js → cli-54wwve05.js} +5 -4
- package/dist/{cli-v0asr5yv.js → cli-719k9j2c.js} +2 -2
- package/dist/{cli-anktweqr.js → cli-89xfd7f9.js} +21 -47
- package/dist/{cli-q34a0e10.js → cli-8v0g1yc8.js} +1 -1
- package/dist/cli-9d8ntetj.js +42 -0
- package/dist/{cli-z9fprcrf.js → cli-atcve9y8.js} +881 -738
- package/dist/{cli-jmb7g47h.js → cli-b5bq9crk.js} +14 -31
- package/dist/cli-d8brzxjb.js +190 -0
- package/dist/{cli-gzky0gkr.js → cli-de14znh8.js} +2 -2
- package/dist/{cli-xytwff7f.js → cli-dttph1bw.js} +2 -2
- package/dist/cli-ep19k3mb.js +19 -0
- package/dist/{cli-m1xa8be7.js → cli-f146mn5s.js} +7 -50
- package/dist/{cli-1fj0chdk.js → cli-f7dsy61y.js} +5 -3
- package/dist/{cli-f567d5c1.js → cli-ftht3zzj.js} +2782 -2589
- package/dist/{cli-a0g1gbt5.js → cli-hbv0kq6w.js} +2 -2
- package/dist/{cli-fhsz3twr.js → cli-jsp14b6c.js} +171 -1
- package/dist/{cli-7fnkj1hj.js → cli-kpv03zhj.js} +21 -17
- package/dist/{cli-m4j6trn4.js → cli-m8yrsg97.js} +2 -2
- package/dist/cli-m9sxbkhm.js +779 -0
- package/dist/cli-mmemxxdc.js +823 -0
- package/dist/{cli-tqtvj5pt.js → cli-n8508nre.js} +1 -1
- package/dist/{cli-z96t0thj.js → cli-p1d5b073.js} +37 -2
- package/dist/{cli-gh8y8f36.js → cli-rw51bq3j.js} +13 -10
- package/dist/{cli-59ej1c07.js → cli-smby5m17.js} +7 -6
- package/dist/{cli-65vqzz3v.js → cli-tzvk9haz.js} +94 -372
- package/dist/{cli-dc9k2ba9.js → cli-w9kb3bk1.js} +1 -1
- package/dist/{cli-kpev657q.js → cli-y6b6fb76.js} +25 -3
- package/dist/{cli-123q2get.js → cli-yz3djrm0.js} +9 -9
- package/dist/{cli-wvp6bvy4.js → cli-zhjmqxzh.js} +1 -1
- package/dist/cli.js +13 -13
- package/dist/{codex-adapter-k98vaw2r.js → codex-adapter-zw4dwsx7.js} +2 -2
- package/dist/{codex-hook-9pf19cks.js → codex-hook-bw8p5nh4.js} +2 -2
- package/dist/{codex-session-runner-tngtphx7.js → codex-session-runner-k981s65v.js} +2 -2
- package/dist/{commands-y8nbr3fv.js → commands-sykrxx7e.js} +4 -4
- package/dist/{db-30p4h2t1.js → db-sfbsc8wt.js} +6 -4
- package/dist/handlers-0aspcejm.js +603 -0
- package/dist/{hook-dcw4jfbj.js → hook-4nvqj2sb.js} +7 -5
- package/dist/{hook-21jexvfx.js → hook-hxccs7m5.js} +24 -49
- package/dist/{http-r4kq5g8d.js → http-y06z517d.js} +230 -94
- package/dist/{index-q3qja6ta.js → index-hssww7kj.js} +15 -14
- package/dist/{index-gay66b9w.js → index-k8znfx0z.js} +13 -12
- package/dist/{index-53zyht4z.js → index-tce1rss4.js} +371 -110
- package/dist/{index-nqvf26za.js → index-x5j894zf.js} +14 -13
- package/dist/{keepalive-xs8fa55y.js → keepalive-w733ax66.js} +6 -6
- package/dist/{lead-d9m2t4s0.js → lead-75bjqa9d.js} +29 -27
- package/dist/{maintenance-3zh82g6z.js → maintenance-w4f1zjck.js} +8 -7
- package/dist/{oauth-refresh-sweep-03snsye5.js → oauth-refresh-sweep-wdetky26.js} +5 -5
- package/dist/{onboard-0cg1925x.js → onboard-bb5net8s.js} +2 -2
- package/dist/{otel-impl-0ab95z27.js → otel-impl-0w7c14ap.js} +1 -1
- package/dist/{pi-mono-adapter-dtkz4e7j.js → pi-mono-adapter-2has4gnp.js} +12 -2
- package/dist/{pricing-refresh-e5jhzz4j.js → pricing-refresh-9nzsrgcq.js} +6 -6
- package/dist/{rbac-roles-p1mf40z3.js → rbac-roles-r3hqjp09.js} +5 -5
- package/dist/{rbac-roles-2w3cmrkc.js → rbac-roles-z1jrffbt.js} +4 -4
- package/dist/{registry-9kdck5ye.js → registry-v5wytg0s.js} +1 -2
- package/dist/{render-v2-xhawry3k.js → render-v2-vbr89fnb.js} +6 -5
- package/dist/{seed-pricing-t223sw91.js → seed-pricing-g62hy1pk.js} +7 -5
- package/dist/{setup-zcs0rce7.js → setup-gnfqnptp.js} +2 -2
- package/dist/{worker-qnp2ka62.js → worker-kznxp4qm.js} +29 -27
- package/openapi.json +263 -12
- package/package.json +1 -1
- package/plugin/commands/start-worker.md +4 -9
- package/plugin/pi-skills/start-worker/SKILL.md +4 -9
- package/src/be/db/agents.ts +556 -0
- package/src/be/db/context-versions.ts +117 -0
- package/src/be/db/runtime.ts +406 -0
- package/src/be/db/tasks/read.ts +1167 -0
- package/src/be/db/tasks/write.ts +953 -0
- package/src/be/db.ts +584 -3429
- package/src/be/migrations/147_scheduled_tasks_parent_task.sql +7 -0
- package/src/be/migrations/148_pages_svg.sql +123 -0
- package/src/be/migrations/149_session_tokens.sql +24 -0
- package/src/be/scripts/typecheck.ts +1 -0
- package/src/be/seed-pricing.ts +13 -8
- package/src/be/seed-scripts/catalog/ops-catalog-audit.inline.ts +1 -1
- package/src/be/seed-scripts/catalog/ops-catalog-audit.ts +1 -1
- package/src/be/seed-scripts/catalog/star-history-refresh.ts +101 -0
- package/src/be/seed-scripts/catalog/star-history-renderer.ts +119 -0
- package/src/be/seed-scripts/index.ts +17 -0
- package/src/be/seed-skills/index.ts +14 -0
- package/src/be/swarm-config-guard.ts +5 -2
- package/src/be/task-attachment-store.ts +70 -0
- package/src/be/users.ts +77 -0
- package/src/commands/attachments-section.ts +37 -0
- package/src/commands/claude-managed-setup.ts +45 -3
- package/src/commands/claude-md-session.ts +408 -0
- package/src/commands/context-preamble.ts +15 -3
- package/src/commands/profile-sync.ts +205 -5
- package/src/commands/provider-credentials.ts +60 -27
- package/src/commands/runner.ts +63 -58
- package/src/commands/templates.ts +25 -2
- package/src/hooks/hook.ts +26 -67
- package/src/http/agents.ts +40 -1
- package/src/http/auth.ts +13 -1
- package/src/http/fs.ts +21 -51
- package/src/http/index.ts +2 -0
- package/src/http/mcp.ts +32 -0
- package/src/http/pages-public.ts +20 -4
- package/src/http/pages.ts +11 -3
- package/src/http/poll.ts +4 -0
- package/src/http/repos.ts +3 -3
- package/src/http/sessions.ts +82 -0
- package/src/http/tasks.ts +10 -2
- package/src/http/utils.ts +79 -1
- package/src/prompts/session-templates.ts +12 -8
- package/src/providers/acp-adapter.ts +62 -8
- package/src/providers/pi-mono-adapter.ts +23 -6
- package/src/providers/pricing-sources.md +11 -0
- package/src/scheduler/scheduler.test.ts +49 -2
- package/src/scheduler/scheduler.ts +4 -0
- package/src/scripts-runtime/sdk-allowlist.ts +1 -0
- package/src/scripts-runtime/types/stdlib.d.ts +8 -0
- package/src/scripts-runtime/types/swarm-sdk.d.ts +8 -0
- package/src/server.ts +2 -0
- package/src/slack/assistant.ts +87 -46
- package/src/slack/handlers.test.ts +1 -3
- package/src/slack/handlers.ts +102 -87
- package/src/slack/inbound-files.ts +466 -0
- package/src/slack/templates.ts +14 -0
- package/src/tasks/task-terminal-effects.ts +158 -0
- package/src/tests/acp-adapter.test.ts +369 -117
- package/src/tests/budget-claim-gate.test.ts +1 -0
- package/src/tests/build-pi-skills.test.ts +5 -7
- package/src/tests/claude-managed-setup.test.ts +52 -4
- package/src/tests/claude-md-session.test.ts +603 -0
- package/src/tests/codex-skill-resolver.test.ts +19 -0
- package/src/tests/context-versioning.test.ts +107 -0
- package/src/tests/cors-allowlist.test.ts +309 -0
- package/src/tests/credential-check.test.ts +157 -14
- package/src/tests/db-agents.test.ts +91 -0
- package/src/tests/db-context-versions.test.ts +37 -0
- package/src/tests/db-extraction-contract.test.ts +45 -0
- package/src/tests/db-runtime.test.ts +70 -0
- package/src/tests/db-task-read-contract.test.ts +624 -0
- package/src/tests/db-task-write-contract.test.ts +653 -0
- package/src/tests/db-tasks-read.test.ts +183 -0
- package/src/tests/db-tasks-write.test.ts +230 -0
- package/src/tests/defer-task.test.ts +389 -0
- package/src/tests/docs-index-footprint.test.js +2 -2
- package/src/tests/e2e-visuals-stage.test.ts +151 -0
- package/src/tests/file-lock.test.ts +144 -0
- package/src/tests/fixtures/file-lock-holder.ts +13 -0
- package/src/tests/fixtures/hold-file-lock.ts +25 -0
- package/src/tests/heartbeat-expiry.test.ts +188 -0
- package/src/tests/http-api-integration.test.ts +78 -1
- package/src/tests/pages-public-html.test.ts +43 -0
- package/src/tests/pages-svg-migration.test.ts +42 -0
- package/src/tests/preload.ts +4 -1
- package/src/tests/profile-sync-warning.test.ts +16 -0
- package/src/tests/profile-sync.test.ts +126 -0
- package/src/tests/prompt-template-session.test.ts +20 -4
- package/src/tests/provider-registration.test.ts +93 -0
- package/src/tests/rbac-e2e-helpers.test.ts +53 -0
- package/src/tests/rbac-e2e-helpers.ts +19 -2
- package/src/tests/reload-config.test.ts +26 -0
- package/src/tests/routing-affinity-inventory.test.ts +1 -1
- package/src/tests/runner-attachments-section.test.ts +22 -2
- package/src/tests/runner-context-preamble.test.ts +30 -0
- package/src/tests/runner-deployment-resume.test.ts +107 -0
- package/src/tests/runner-repo-autostash.test.ts +12 -0
- package/src/tests/script-connections.test.ts +4 -0
- package/src/tests/seed-scripts.test.ts +2 -2
- package/src/tests/session-tokens.test.ts +279 -0
- package/src/tests/slack-file-tools-attachments.test.ts +408 -0
- package/src/tests/slack-inbound-files.test.ts +847 -0
- package/src/tests/star-history-refresh.test.ts +102 -0
- package/src/tests/swarm-config-reserved-keys.test.ts +21 -0
- package/src/tests/swarm-repos.test.ts +20 -0
- package/src/tests/tool-annotations.test.ts +4 -3
- package/src/tests/ui-logs-parser.test.ts +176 -0
- package/src/tools/create-page.ts +4 -2
- package/src/tools/defer-task.ts +239 -0
- package/src/tools/repos/update-repo.ts +2 -2
- package/src/tools/schedules/create-schedule.ts +1 -0
- package/src/tools/schedules/list-schedules.ts +1 -0
- package/src/tools/schedules/patch-schedule.ts +1 -0
- package/src/tools/schedules/update-schedule.ts +1 -0
- package/src/tools/slack-download-file.ts +60 -29
- package/src/tools/slack-read.ts +73 -32
- package/src/tools/store-progress.ts +16 -146
- package/src/tools/tool-config.ts +1 -0
- package/src/tools/utils.ts +21 -0
- package/src/types.ts +37 -4
- package/src/utils/acp-session-token.ts +56 -0
- package/src/utils/file-lock.ts +111 -0
- package/src/utils/heartbeat-expiry.ts +78 -0
- package/src/utils/request-auth-context.ts +2 -0
- package/src/utils/task-attachment-links.ts +22 -0
- package/templates/skills/code-quality/content.md +8 -5
- package/templates/skills/download-task-attachment/content.md +2 -1
- package/{plugin/pi-skills → templates/skills}/review-offered-task/SKILL.md +5 -5
- package/templates/skills/review-offered-task/config.json +14 -0
- package/{plugin/commands/review-offered-task.md → templates/skills/review-offered-task/content.md} +3 -8
- package/templates/skills/scheduling/content.md +4 -0
- package/templates/skills/slack-interaction/content.md +2 -2
- package/templates/skills/work-on-task/SKILL.md +16 -0
- package/templates/skills/work-on-task/config.json +14 -0
- package/templates/skills/work-on-task/content.md +11 -0
- package/dist/assistant-0qt42nzg.js +0 -212
- package/dist/cli-fs1kkqgr.js +0 -317
- package/dist/cli-jnf5zghe.js +0 -269
- package/dist/cli-n1q8q14d.js +0 -177
- package/dist/handlers-yfp1qn81.js +0 -592
- package/plugin/commands/work-on-task.md +0 -39
- package/plugin/pi-skills/work-on-task/SKILL.md +0 -39
|
@@ -1,10 +1,13 @@
|
|
|
1
|
+
import {
|
|
2
|
+
buildSkillContent
|
|
3
|
+
} from "./cli-ep19k3mb.js";
|
|
1
4
|
import {
|
|
2
5
|
agentFsProvisionSeeder,
|
|
3
6
|
extractArgsJsonSchema,
|
|
4
7
|
extractScriptSignature,
|
|
5
8
|
typecheckScript
|
|
6
|
-
} from "./cli-
|
|
7
|
-
import"./cli-
|
|
9
|
+
} from "./cli-54wwve05.js";
|
|
10
|
+
import"./cli-de14znh8.js";
|
|
8
11
|
import {
|
|
9
12
|
require_dist
|
|
10
13
|
} from "./cli-qgm2pfpq.js";
|
|
@@ -13,15 +16,16 @@ import {
|
|
|
13
16
|
upsertScriptByName,
|
|
14
17
|
validateDefinition,
|
|
15
18
|
validateScriptImports
|
|
16
|
-
} from "./cli-
|
|
19
|
+
} from "./cli-3tgwnf43.js";
|
|
17
20
|
import"./cli-epan13p1.js";
|
|
18
|
-
import"./cli-
|
|
19
|
-
import"./cli-
|
|
21
|
+
import"./cli-hbv0kq6w.js";
|
|
22
|
+
import"./cli-1th1728g.js";
|
|
20
23
|
import"./cli-y89t4nca.js";
|
|
21
24
|
import"./cli-f14fvzag.js";
|
|
22
|
-
import"./cli-
|
|
23
|
-
import"./cli-
|
|
25
|
+
import"./cli-m9sxbkhm.js";
|
|
26
|
+
import"./cli-zhjmqxzh.js";
|
|
24
27
|
import"./cli-aehm1rbq.js";
|
|
28
|
+
import"./cli-9d8ntetj.js";
|
|
25
29
|
import {
|
|
26
30
|
computeContentHash,
|
|
27
31
|
createScheduledTask,
|
|
@@ -38,15 +42,15 @@ import {
|
|
|
38
42
|
updateSkill,
|
|
39
43
|
updateWorkflow,
|
|
40
44
|
upsertSkillFiles
|
|
41
|
-
} from "./cli-
|
|
42
|
-
import"./cli-
|
|
43
|
-
import"./cli-
|
|
45
|
+
} from "./cli-ftht3zzj.js";
|
|
46
|
+
import"./cli-y6b6fb76.js";
|
|
47
|
+
import"./cli-kpv03zhj.js";
|
|
44
48
|
import"./cli-e29gmdmw.js";
|
|
45
49
|
import"./cli-c2mk1kgf.js";
|
|
46
50
|
import"./cli-ej6gbxfb.js";
|
|
47
51
|
import"./cli-sd0mxa3c.js";
|
|
48
52
|
import"./cli-w5e1d1vv.js";
|
|
49
|
-
import"./cli-
|
|
53
|
+
import"./cli-w9kb3bk1.js";
|
|
50
54
|
import"./cli-xqcq9y5e.js";
|
|
51
55
|
import"./cli-zf8jjwex.js";
|
|
52
56
|
import {
|
|
@@ -3933,7 +3937,7 @@ const CONTRADICTORY_RE =
|
|
|
3933
3937
|
/\\b(do not|don't|never)\\b[\\s\\S]{0,240}\\b(always|must|required)\\b|\\b(always|must|required)\\b[\\s\\S]{0,240}\\b(do not|don't|never)\\b/i;
|
|
3934
3938
|
|
|
3935
3939
|
const CODE_REGISTRY_EVENTS =
|
|
3936
|
-
"agentmail.email.followup agentmail.email.mapped_lead agentmail.email.mapped_worker agentmail.email.no_agent agentmail.email.unmapped common.command_suggestions.github_comment_issue common.command_suggestions.github_comment_pr common.command_suggestions.github_issue common.command_suggestions.github_pr common.command_suggestions.gitlab_issue common.command_suggestions.gitlab_mr common.delegation_instruction common.delegation_instruction.gitlab github.check_run.failed github.check_suite.failed github.comment.mentioned github.issue.assigned github.issue.labeled github.issue.mentioned github.pull_request.assigned github.pull_request.closed github.pull_request.labeled github.pull_request.mentioned github.pull_request.review_requested github.pull_request.review_submitted github.pull_request.synchronize github.workflow_run.failed gitlab.comment.mentioned gitlab.issue.assigned gitlab.merge_request.opened gitlab.pipeline.failed heartbeat.boot-triage heartbeat.checklist jira.issue.assigned jira.issue.commented jira.issue.followup kapso.message.received linear.issue.assigned linear.issue.followup linear.issue.reassigned slack.assistant.greeting slack.assistant.offline slack.assistant.suggested_prompts slack.message.thread_context system.agent.communication system.agent.lead system.agent.memory system.agent.memory.remote system.agent.outputs system.agent.outputs.no_agent_fs system.agent.repository system.agent.role system.agent.secrets system.agent.slack system.agent.tools_skills system.agent.worker system.agent.worker.remote system.agent.workspace system.agent.workspace.remote system.session.lead system.session.lead.managed system.session.worker system.session.worker.managed system.session.worker.remote task.budget.refused task.requester.profile task.worker.completed task.worker.failed".split(
|
|
3940
|
+
"agentmail.email.followup agentmail.email.mapped_lead agentmail.email.mapped_worker agentmail.email.no_agent agentmail.email.unmapped common.command_suggestions.github_comment_issue common.command_suggestions.github_comment_pr common.command_suggestions.github_issue common.command_suggestions.github_pr common.command_suggestions.gitlab_issue common.command_suggestions.gitlab_mr common.delegation_instruction common.delegation_instruction.gitlab github.check_run.failed github.check_suite.failed github.comment.mentioned github.issue.assigned github.issue.labeled github.issue.mentioned github.pull_request.assigned github.pull_request.closed github.pull_request.labeled github.pull_request.mentioned github.pull_request.review_requested github.pull_request.review_submitted github.pull_request.synchronize github.workflow_run.failed gitlab.comment.mentioned gitlab.issue.assigned gitlab.merge_request.opened gitlab.pipeline.failed heartbeat.boot-triage heartbeat.checklist jira.issue.assigned jira.issue.commented jira.issue.followup kapso.message.received linear.issue.assigned linear.issue.followup linear.issue.reassigned slack.assistant.greeting slack.assistant.offline slack.assistant.suggested_prompts slack.message.attachment_failed slack.message.thread_context system.agent.communication system.agent.lead system.agent.memory system.agent.memory.remote system.agent.outputs system.agent.outputs.no_agent_fs system.agent.repository system.agent.role system.agent.secrets system.agent.slack system.agent.tools_skills system.agent.worker system.agent.worker.remote system.agent.workspace system.agent.workspace.remote system.session.lead system.session.lead.managed system.session.worker system.session.worker.managed system.session.worker.remote task.budget.refused task.requester.profile task.worker.completed task.worker.failed".split(
|
|
3937
3941
|
" ",
|
|
3938
3942
|
);
|
|
3939
3943
|
|
|
@@ -4725,6 +4729,232 @@ export default async function smartRecall(args: any, ctx: any) {
|
|
|
4725
4729
|
}
|
|
4726
4730
|
`;
|
|
4727
4731
|
|
|
4732
|
+
// src/be/seed-scripts/catalog/star-history-refresh.ts
|
|
4733
|
+
var star_history_refresh_default = `import type { ScriptContext } from "swarm-sdk";
|
|
4734
|
+
import * as z from "zod";
|
|
4735
|
+
import { renderChart } from "./star-history-renderer";
|
|
4736
|
+
|
|
4737
|
+
export const argsSchema = z.object({
|
|
4738
|
+
dryRun: z.boolean().default(false),
|
|
4739
|
+
authenticated: z.boolean().default(true),
|
|
4740
|
+
});
|
|
4741
|
+
|
|
4742
|
+
const repository = "desplega-ai/agent-swarm";
|
|
4743
|
+
const namespace = "star-history:desplega-ai/agent-swarm";
|
|
4744
|
+
const cacheSchema = z.object({
|
|
4745
|
+
fetchedAt: z.string(),
|
|
4746
|
+
pages: z.array(z.object({ etag: z.string().nullable(), timestamps: z.array(z.number().finite()) })),
|
|
4747
|
+
});
|
|
4748
|
+
type Cache = z.infer<typeof cacheSchema>;
|
|
4749
|
+
|
|
4750
|
+
/** Refresh the light and dark star-history images, retaining the last-known series on GitHub failure. */
|
|
4751
|
+
export default async function main(args: z.input<typeof argsSchema>, ctx: ScriptContext) {
|
|
4752
|
+
const options = argsSchema.parse(args ?? {});
|
|
4753
|
+
const entry = await ctx.swarm.kv_getOrNull({ namespace, key: "series" });
|
|
4754
|
+
const parsed = cacheSchema.safeParse(entry?.value);
|
|
4755
|
+
const cached = parsed.success ? parsed.data : undefined;
|
|
4756
|
+
let series: Cache;
|
|
4757
|
+
let stale = false;
|
|
4758
|
+
let fetchError: string | undefined;
|
|
4759
|
+
let requests = 0;
|
|
4760
|
+
let notModified = 0;
|
|
4761
|
+
try {
|
|
4762
|
+
const pages: Cache["pages"] = [];
|
|
4763
|
+
const deadline = Date.now() + 12000;
|
|
4764
|
+
// Bound the job so a pagination error cannot consume the entire API budget.
|
|
4765
|
+
for (let page = 1; page <= 50; page++) {
|
|
4766
|
+
if (Date.now() > deadline) throw new Error("GitHub refresh budget exhausted");
|
|
4767
|
+
const previous = cached?.pages[page - 1];
|
|
4768
|
+
const headers: Record<string, string> = {
|
|
4769
|
+
Accept: "application/vnd.github.star+json",
|
|
4770
|
+
"User-Agent": "agent-swarm-star-history-generator",
|
|
4771
|
+
"X-GitHub-Api-Version": "2022-11-28",
|
|
4772
|
+
};
|
|
4773
|
+
if (options.authenticated) headers.Authorization = "Bearer [REDACTED:GITHUB_TOKEN]";
|
|
4774
|
+
if (previous?.etag) headers["If-None-Match"] = previous.etag;
|
|
4775
|
+
requests++;
|
|
4776
|
+
const response = await ctx.stdlib.fetch(
|
|
4777
|
+
\`https://api.github.com/repos/\${repository}/stargazers?per_page=100&page=\${page}\`,
|
|
4778
|
+
{ headers, signal: AbortSignal.timeout(1500) },
|
|
4779
|
+
);
|
|
4780
|
+
let current: Cache["pages"][number];
|
|
4781
|
+
if (response.status === 304 && previous) {
|
|
4782
|
+
current = previous;
|
|
4783
|
+
notModified++;
|
|
4784
|
+
} else {
|
|
4785
|
+
if (!response.ok) throw new Error(\`GitHub stargazers HTTP \${response.status}\`);
|
|
4786
|
+
const rows = z.array(z.object({ starred_at: z.string() })).parse(await response.json());
|
|
4787
|
+
const timestamps = rows.map((row) => Date.parse(row.starred_at));
|
|
4788
|
+
if (timestamps.some((timestamp) => !Number.isFinite(timestamp))) {
|
|
4789
|
+
throw new Error("GitHub returned invalid star timestamps");
|
|
4790
|
+
}
|
|
4791
|
+
current = { etag: response.headers.get("etag"), timestamps };
|
|
4792
|
+
}
|
|
4793
|
+
pages.push(current);
|
|
4794
|
+
if (current.timestamps.length < 100) break;
|
|
4795
|
+
if (page === 50) throw new Error("Stargazer pagination exceeded 50 pages");
|
|
4796
|
+
}
|
|
4797
|
+
if (!pages.some((page) => page.timestamps.length)) throw new Error("No stargazers returned");
|
|
4798
|
+
series = { fetchedAt: new Date().toISOString(), pages };
|
|
4799
|
+
await ctx.swarm.kv_set({ namespace, key: "series", value: series });
|
|
4800
|
+
} catch (error) {
|
|
4801
|
+
if (!cached?.pages.some((page) => page.timestamps.length)) {
|
|
4802
|
+
throw new Error("GitHub fetch failed and no cached series exists; no pages published");
|
|
4803
|
+
}
|
|
4804
|
+
series = cached;
|
|
4805
|
+
stale = true;
|
|
4806
|
+
// Avoid transporting fetch exception text, which may include request details.
|
|
4807
|
+
fetchError = error instanceof Error && error.message.startsWith("GitHub stargazers HTTP")
|
|
4808
|
+
? error.message : "GitHub refresh failed; using last-known series";
|
|
4809
|
+
}
|
|
4810
|
+
|
|
4811
|
+
const timestamps = series.pages.flatMap((page) => page.timestamps).sort((a, b) => a - b);
|
|
4812
|
+
const pages = [];
|
|
4813
|
+
for (const theme of ["light", "dark"] as const) {
|
|
4814
|
+
const body = renderChart(repository, timestamps, theme);
|
|
4815
|
+
const slug = \`star-history-\${theme}\`;
|
|
4816
|
+
if (options.dryRun) {
|
|
4817
|
+
pages.push({ slug, bytes: new TextEncoder().encode(body).length });
|
|
4818
|
+
continue;
|
|
4819
|
+
}
|
|
4820
|
+
const response = await ctx.swarm.page_create({
|
|
4821
|
+
slug, title: \`Star history (\${theme})\`, body,
|
|
4822
|
+
description: \`GitHub stars for \${repository}; fetched \${series.fetchedAt}\`,
|
|
4823
|
+
contentType: "image/svg+xml", authMode: "public",
|
|
4824
|
+
}) as { data?: { id?: string; api_url?: string }; id?: string; api_url?: string };
|
|
4825
|
+
const page = response.data ?? response;
|
|
4826
|
+
if (!page.id || !page.api_url) throw new Error(\`Failed to publish \${slug}\`);
|
|
4827
|
+
pages.push({ slug, id: page.id, apiUrl: page.api_url });
|
|
4828
|
+
}
|
|
4829
|
+
return {
|
|
4830
|
+
repository, stars: timestamps.length, fetchedAt: series.fetchedAt, stale, fetchError,
|
|
4831
|
+
authenticated: options.authenticated, requests, notModified, dryRun: options.dryRun, pages,
|
|
4832
|
+
};
|
|
4833
|
+
}
|
|
4834
|
+
`;
|
|
4835
|
+
|
|
4836
|
+
// src/be/seed-scripts/catalog/star-history-renderer.ts
|
|
4837
|
+
var star_history_renderer_default = `const themes = {
|
|
4838
|
+
light: {
|
|
4839
|
+
background: "#ffffff",
|
|
4840
|
+
border: "#e5e7eb",
|
|
4841
|
+
grid: "#e5e7eb",
|
|
4842
|
+
text: "#111827",
|
|
4843
|
+
muted: "#6b7280",
|
|
4844
|
+
accent: "#f59e0b",
|
|
4845
|
+
},
|
|
4846
|
+
dark: {
|
|
4847
|
+
background: "#0d1117",
|
|
4848
|
+
border: "#30363d",
|
|
4849
|
+
grid: "#21262d",
|
|
4850
|
+
text: "#f0f6fc",
|
|
4851
|
+
muted: "#8b949e",
|
|
4852
|
+
accent: "#f59e0b",
|
|
4853
|
+
},
|
|
4854
|
+
};
|
|
4855
|
+
|
|
4856
|
+
function escapeXml(value: string) {
|
|
4857
|
+
return value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">");
|
|
4858
|
+
}
|
|
4859
|
+
|
|
4860
|
+
function niceStep(maximum: number, targetTickCount = 6) {
|
|
4861
|
+
const roughStep = maximum / targetTickCount;
|
|
4862
|
+
const power = 10 ** Math.floor(Math.log10(roughStep));
|
|
4863
|
+
const normalized = roughStep / power;
|
|
4864
|
+
const multiplier = normalized <= 1 ? 1 : normalized <= 2 ? 2 : normalized <= 5 ? 5 : 10;
|
|
4865
|
+
return multiplier * power;
|
|
4866
|
+
}
|
|
4867
|
+
|
|
4868
|
+
export function renderChart(repository: string, timestamps: number[], themeName: keyof typeof themes) {
|
|
4869
|
+
const theme = themes[themeName];
|
|
4870
|
+
const width = 960;
|
|
4871
|
+
const height = 520;
|
|
4872
|
+
const margin = { top: 96, right: 34, bottom: 62, left: 76 };
|
|
4873
|
+
const plotWidth = width - margin.left - margin.right;
|
|
4874
|
+
const plotHeight = height - margin.top - margin.bottom;
|
|
4875
|
+
const firstStar = timestamps[0]!;
|
|
4876
|
+
const lastStar = timestamps.at(-1)!;
|
|
4877
|
+
const timeRange = Math.max(lastStar - firstStar, 1);
|
|
4878
|
+
const yStep = niceStep(timestamps.length);
|
|
4879
|
+
const yMaximum = Math.ceil(timestamps.length / yStep) * yStep;
|
|
4880
|
+
const plotBottom = margin.top + plotHeight;
|
|
4881
|
+
|
|
4882
|
+
const x = (timestamp: number) => margin.left + ((timestamp - firstStar) / timeRange) * plotWidth;
|
|
4883
|
+
const y = (stars: number) => margin.top + plotHeight - (stars / yMaximum) * plotHeight;
|
|
4884
|
+
|
|
4885
|
+
const points = timestamps.map((timestamp, index) => ({
|
|
4886
|
+
x: x(timestamp),
|
|
4887
|
+
y: y(index + 1),
|
|
4888
|
+
}));
|
|
4889
|
+
const linePath = points
|
|
4890
|
+
.map((point, index) => \`\${index === 0 ? "M" : "L"} \${point.x.toFixed(1)} \${point.y.toFixed(1)}\`)
|
|
4891
|
+
.join(" ");
|
|
4892
|
+
const areaPath = \`M \${points[0]!.x.toFixed(1)} \${plotBottom.toFixed(1)} \${linePath.replace(/^M/, "L")} L \${points.at(-1)!.x.toFixed(1)} \${plotBottom.toFixed(1)} Z\`;
|
|
4893
|
+
|
|
4894
|
+
const yTicks = [];
|
|
4895
|
+
for (let stars = 0; stars <= yMaximum; stars += yStep) {
|
|
4896
|
+
const tickY = y(stars);
|
|
4897
|
+
yTicks.push(\`
|
|
4898
|
+
<line x1="\${margin.left}" y1="\${tickY.toFixed(1)}" x2="\${width - margin.right}" y2="\${tickY.toFixed(1)}" stroke="\${theme.grid}" />
|
|
4899
|
+
<text x="\${margin.left - 14}" y="\${(tickY + 5).toFixed(1)}" text-anchor="end" fill="\${theme.muted}" font-size="13">\${stars}</text>\`);
|
|
4900
|
+
}
|
|
4901
|
+
|
|
4902
|
+
const dateFormatter = new Intl.DateTimeFormat("en-US", {
|
|
4903
|
+
month: "short",
|
|
4904
|
+
year: "numeric",
|
|
4905
|
+
timeZone: "UTC",
|
|
4906
|
+
});
|
|
4907
|
+
const updatedFormatter = new Intl.DateTimeFormat("en-US", {
|
|
4908
|
+
day: "numeric",
|
|
4909
|
+
month: "short",
|
|
4910
|
+
year: "numeric",
|
|
4911
|
+
timeZone: "UTC",
|
|
4912
|
+
});
|
|
4913
|
+
const xTicks = Array.from({ length: 7 }, (_, index) => {
|
|
4914
|
+
const fraction = index / 6;
|
|
4915
|
+
const timestamp = firstStar + timeRange * fraction;
|
|
4916
|
+
const tickX = margin.left + plotWidth * fraction;
|
|
4917
|
+
return \`
|
|
4918
|
+
<line x1="\${tickX.toFixed(1)}" y1="\${margin.top}" x2="\${tickX.toFixed(1)}" y2="\${plotBottom}" stroke="\${theme.grid}" />
|
|
4919
|
+
<text x="\${tickX.toFixed(1)}" y="\${plotBottom + 30}" text-anchor="middle" fill="\${theme.muted}" font-size="13">\${dateFormatter.format(timestamp)}</text>\`;
|
|
4920
|
+
});
|
|
4921
|
+
|
|
4922
|
+
const escapedRepository = escapeXml(repository);
|
|
4923
|
+
const lastPoint = points.at(-1)!;
|
|
4924
|
+
|
|
4925
|
+
return \`<svg xmlns="http://www.w3.org/2000/svg" width="960" height="520" viewBox="0 0 960 520" role="img" aria-labelledby="title description">
|
|
4926
|
+
<title id="title">Star history for \${escapedRepository}</title>
|
|
4927
|
+
<desc id="description">\${timestamps.length} cumulative GitHub stars from \${updatedFormatter.format(firstStar)} through \${updatedFormatter.format(lastStar)}.</desc>
|
|
4928
|
+
<defs>
|
|
4929
|
+
<linearGradient id="star-area" x1="0" y1="0" x2="0" y2="1">
|
|
4930
|
+
<stop offset="0%" stop-color="\${theme.accent}" stop-opacity="0.24" />
|
|
4931
|
+
<stop offset="100%" stop-color="\${theme.accent}" stop-opacity="0.02" />
|
|
4932
|
+
</linearGradient>
|
|
4933
|
+
<filter id="point-shadow" x="-100%" y="-100%" width="300%" height="300%">
|
|
4934
|
+
<feDropShadow dx="0" dy="1" stdDeviation="2" flood-color="\${theme.accent}" flood-opacity="0.35" />
|
|
4935
|
+
</filter>
|
|
4936
|
+
</defs>
|
|
4937
|
+
<rect x="0.5" y="0.5" width="959" height="519" rx="12" fill="\${theme.background}" stroke="\${theme.border}" />
|
|
4938
|
+
<g font-family="-apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif">
|
|
4939
|
+
<text x="\${margin.left}" y="43" fill="\${theme.text}" font-size="21" font-weight="600">\${escapedRepository}</text>
|
|
4940
|
+
<text x="\${margin.left}" y="69" fill="\${theme.muted}" font-size="13">Cumulative GitHub stars · updated \${updatedFormatter.format(lastStar)}</text>
|
|
4941
|
+
<g transform="translate(\${width - margin.right - 118}, 34)">
|
|
4942
|
+
<text x="0" y="17" fill="\${theme.accent}" font-size="19">★</text>
|
|
4943
|
+
<text x="27" y="17" fill="\${theme.text}" font-size="16" font-weight="600">\${timestamps.length} stars</text>
|
|
4944
|
+
</g>
|
|
4945
|
+
\${yTicks.join("").trim()}
|
|
4946
|
+
\${xTicks.join("").trim()}
|
|
4947
|
+
<path d="\${areaPath}" fill="url(#star-area)" />
|
|
4948
|
+
<path d="\${linePath}" fill="none" stroke="\${theme.accent}" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" />
|
|
4949
|
+
<circle cx="\${lastPoint.x.toFixed(1)}" cy="\${lastPoint.y.toFixed(1)}" r="5" fill="\${theme.background}" stroke="\${theme.accent}" stroke-width="3" filter="url(#point-shadow)" />
|
|
4950
|
+
<text x="20" y="\${margin.top + plotHeight / 2}" transform="rotate(-90 20 \${margin.top + plotHeight / 2})" text-anchor="middle" fill="\${theme.muted}" font-size="13">GitHub stars</text>
|
|
4951
|
+
</g>
|
|
4952
|
+
</svg>
|
|
4953
|
+
\`;
|
|
4954
|
+
}
|
|
4955
|
+
|
|
4956
|
+
`;
|
|
4957
|
+
|
|
4728
4958
|
// src/be/seed-scripts/catalog/swarm-overview.ts
|
|
4729
4959
|
var swarm_overview_default = `import { z } from "zod";
|
|
4730
4960
|
|
|
@@ -5196,6 +5426,13 @@ function bundleCatalogReport(source) {
|
|
|
5196
5426
|
${source.replace(CATALOG_REPORT_IMPORT_RE, "")}`;
|
|
5197
5427
|
}
|
|
5198
5428
|
var SEED_SCRIPTS = [
|
|
5429
|
+
{
|
|
5430
|
+
name: "star-history-refresh",
|
|
5431
|
+
description: "Refresh stable public light/dark SVG star-history pages from GitHub with ETags and a last-known KV series.",
|
|
5432
|
+
intent: "Run hourly under the same page-owning agent identity; dryRun validates rendering before SVG page support deploys.",
|
|
5433
|
+
source: asText(star_history_renderer_default) + `
|
|
5434
|
+
` + asText(star_history_refresh_default).replace('import { renderChart } from "./star-history-renderer";', "")
|
|
5435
|
+
},
|
|
5199
5436
|
{
|
|
5200
5437
|
name: "gh-pr-snapshot",
|
|
5201
5438
|
description: "One-call GitHub pull request snapshot: title, state, draft, mergeable, CI check tallies (passed/failed/pending) and review tallies (approved/changes-requested/pending).",
|
|
@@ -6111,7 +6348,7 @@ var config_default8 = `{
|
|
|
6111
6348
|
`;
|
|
6112
6349
|
|
|
6113
6350
|
// templates/skills/code-quality/content.md
|
|
6114
|
-
var content_default8 = "# Code quality\n\nThis skill covers the moment code leaves your machine: a push, a pull request, a merge, a review.\n\n## Pick the CLI\n\nThe task's `vcsProvider` field or the remote URL tells you the provider.\n\n| Operation | GitHub (`gh`) | GitLab (`glab`) |\n|---|---|---|\n| Clone | `gh repo clone` | `glab repo clone` |\n| Create PR or MR | `gh pr create` | `glab mr create` |\n| View | `gh pr view` | `glab mr view` |\n| CI status | `gh pr checks` | `glab mr view --json pipelines` |\n| Review | `gh pr review` | `glab mr approve`, `glab mr note` |\n| Comment on an issue | `gh issue comment` | `glab issue note` |\n\n## Before you push\n\n1. Run every command in the Repository Guidelines section \"PR Checks\" of your system prompt, one after the other. When no guidelines exist, run the checklist in the repo's CLAUDE.md. When neither exists, ask the lead before you push.\n2. A failing check: fix the cause and run the check again. Push only when every check passes.\n3. Git hooks stay on. `--no-verify` and any other bypass flag are out.\n4. `main` and `master` are never force-pushed.\n5. One logical change per PR. Conventional commit titles when the repo uses them.\n\n## After you open a PR\n\n1. Wait about 30 seconds, then read CI: `gh pr checks <number>` or `glab mr view --json pipelines`.\n2. Red CI: read the failing job, fix, push, read CI again. Repeat until green.\n3. Put the PR URL and the CI status in your task output.\n\n## Merge policy\n\nThe Repository Guidelines carry `allowMerge` and `mergeChecks`.\n\n- `allowMerge` false (the default): review and approve. Do not merge.\n- `allowMerge` true: run every `mergeChecks` entry first, then merge.\n\n## Review a PR\n\n1. CI status first. Failing CI is a REQUEST_CHANGES. Name the failing checks in the review.\n2. Tests second. A code change without new or updated tests is a REQUEST_CHANGES. Name the tests you expect. Exceptions: documentation-only, configuration-only, and dependency-bump PRs.\
|
|
6351
|
+
var content_default8 = "# Code quality\n\nThis skill covers the moment code leaves your machine: a push, a pull request, a merge, a review.\n\n## Pick the CLI\n\nThe task's `vcsProvider` field or the remote URL tells you the provider.\n\n| Operation | GitHub (`gh`) | GitLab (`glab`) |\n|---|---|---|\n| Clone | `gh repo clone` | `glab repo clone` |\n| Create PR or MR | `gh pr create` | `glab mr create` |\n| View | `gh pr view` | `glab mr view` |\n| CI status | `gh pr checks` | `glab mr view --json pipelines` |\n| Review | `gh pr review` | `glab mr approve`, `glab mr note` |\n| Comment on an issue | `gh issue comment` | `glab issue note` |\n\n## Before you push\n\n1. Run every command in the Repository Guidelines section \"PR Checks\" of your system prompt, one after the other. When no guidelines exist, run the checklist in the repo's CLAUDE.md. When neither exists, ask the lead before you push.\n2. A failing check: fix the cause and run the check again. Push only when every check passes.\n3. Git hooks stay on. `--no-verify` and any other bypass flag are out.\n4. `main` and `master` are never force-pushed.\n5. One logical change per PR. Conventional commit titles when the repo uses them.\n\n## After you open a PR\n\n1. Wait about 30 seconds, then read CI: `gh pr checks <number>` or `glab mr view --json pipelines`.\n2. Red CI: read the failing job, fix, push, read CI again. Repeat until green.\n3. Put the PR URL and the CI status in your task output.\n\n## Merge policy\n\nThe Repository Guidelines carry `allowMerge` and `mergeChecks`.\n\n- `allowMerge` false (the default): review and approve. Do not merge.\n- `allowMerge` true: run every `mergeChecks` entry first, then merge.\n\n## Review a PR\n\n1. CI status first, including the fork checks below before treating CI as evidence. Failing CI is a REQUEST_CHANGES. Name the failing checks in the review.\n2. Detect a GitHub fork PR with `gh pr view <number> --json isCrossRepository --jq .isCrossRepository`.\n3. For a GitHub fork PR, inspect held runs with `SHA=$(gh pr view <number> --json headRefOid --jq .headRefOid); gh api --paginate \"repos/<owner>/<repo>/actions/runs?head_sha=$SHA\" --jq '.workflow_runs[] | \"\\(.conclusion // .status)|\\(.name)\"'`; `gh pr checks` and `statusCheckRollup` can omit them.\n4. Treat any `action_required` run or no substantive run executed on that SHA as a CI blocker. Keep run handling read-only: REQUEST_CHANGES naming the held or unexecuted run, and report the blocker so an explicitly authorized maintainer or the application-controlled GitHub integration can approve the run after validating the workflow and its trust boundary. Do not APPROVE on omitted runs.\n5. Tests second. A code change without new or updated tests is a REQUEST_CHANGES. Name the tests you expect. Exceptions: documentation-only, configuration-only, and dependency-bump PRs.\n6. Apply the \"Review Guidance\" entries from the Repository Guidelines.\n7. Read the diff for security (injection, secrets in code), logic (null handling, off-by-one, edge cases), performance (N+1, leaks), and code shape (naming, duplication, error handling). Run the test suite and the type check locally when you can.\n8. Post the review with the verdict first. One finding per comment, with file and line, and what to change.\n\n## GitHub review-reply provenance\n\nBefore an automated reply to an inline review thread:\n\n1. `gh api user --jq .login` must equal `${GITHUB_BOT_NAME:-agent-swarm-bot}`.\n2. Post through the `GITHUB_TOKEN`-backed `gh api` path.\n3. Append `<!-- agent-swarm:review-ack -->` to the reply body.\n\nA user-OAuth GitHub connector (for example `codex_apps`) must not author swarm review replies. When the login does not match, do not post. Report the mismatch in your task output.\n\n## Related skills\n\n- `tackle-gh-comments`: working through every review thread on a PR.\n- `engineering-standards`: the code-shape bar a reviewer holds the diff to.\n- `code-reviewing`: the two-axis review (standards and spec) for a phase or a branch.\n";
|
|
6115
6352
|
|
|
6116
6353
|
// templates/skills/code-reviewing/config.json
|
|
6117
6354
|
var config_default9 = `{
|
|
@@ -6702,7 +6939,7 @@ var config_default17 = `{
|
|
|
6702
6939
|
`;
|
|
6703
6940
|
|
|
6704
6941
|
// templates/skills/download-task-attachment/content.md
|
|
6705
|
-
var content_default17 = '# Download a Task Attachment\n\nTask attachments (files uploaded via the UI or API onto a task) are served\nthrough a single **provider-agnostic** REST route — regardless of whether the\nbacking storage is `local-fs` or `agent-fs`. You do not need to know or care\nwhich provider is active, and you do not need `agent-fs org`/`agent-fs drive`\ndiscovery.\n\n## The one-call recipe\n\n```bash\ncurl "$MCP_BASE_URL/api/fs/tasks/$AGENT_SWARM_TASK_ID/files/<attachmentId>/raw" \\\n -H "X-Agent-ID: $AGENT_ID" \\\n -H "Authorization: Bearer ${AGENT_SWARM_API_KEY:-$API_KEY}" \\\n -o /tmp/<name
|
|
6942
|
+
var content_default17 = '# Download a Task Attachment\n\nTask attachments (files uploaded via the UI or API onto a task) are served\nthrough a single **provider-agnostic** REST route — regardless of whether the\nbacking storage is `local-fs` or `agent-fs`. You do not need to know or care\nwhich provider is active, and you do not need `agent-fs org`/`agent-fs drive`\ndiscovery.\n\n## The one-call recipe\n\n```bash\ncurl "$MCP_BASE_URL/api/fs/tasks/$AGENT_SWARM_TASK_ID/files/<attachmentId>/raw" \\\n -H "X-Agent-ID: $AGENT_ID" \\\n -H "Authorization: Bearer ${AGENT_SWARM_API_KEY:-$API_KEY}" \\\n --create-dirs -o "/tmp/attachments/<attachmentId>/<name>"\n```\n\n- `$MCP_BASE_URL`, `$AGENT_ID`, `$AGENT_SWARM_TASK_ID` (or `$AGENT_SWARM_AGENT_ID`/`TASK_FILE`-derived taskId), and `$AGENT_SWARM_API_KEY`/`$API_KEY` are already present in every worker container\'s env — no new plumbing needed.\n- `<attachmentId>` and `<name>`/`mimeType` come from the task\'s attachment list (see below).\n- One directory per attachment: two attachments can share a name (every pasted screenshot is `image.png`), and `/tmp/<name>` would let one overwrite the other.\n- The route resolves the active file-storage provider (`local-fs` in dev, `agent-fs` in prod) server-side and streams the raw bytes back with the correct `Content-Type` — you get one call no matter which provider is behind it.\n\n## Finding the attachment ID\n\nIf the dispatch prompt already injected an `## Attachments` section with the\ncurl command pre-filled, just run it — that\'s the fast path (see\n`buildAttachmentsSection()` in `src/commands/runner.ts`).\n\nOtherwise, pull it from the task:\n\n```\nget-task-details taskId=<your task id>\n```\n\nThe response includes an `attachments` array: `{id, name, mimeType, sizeBytes}`.\nUse `id` as `<attachmentId>` in the curl above.\n\n## Why not the `agent-fs` CLI directly?\n\n`agent-fs` is a general-purpose CLI for the swarm\'s own agent-fs filesystem —\nit requires you to already know the org/drive a file lives in, and task\nattachments don\'t always carry that (older rows, or attachments stored via\n`local-fs` in dev have no org/drive at all). Reaching for `agent-fs cat` /\n`agent-fs download` on a task attachment means guessing subcommand names,\ndiscovering the right org via `agent-fs org list`, and re-trying — several\ntool calls where one `curl` suffices. This was root-caused from a real\nsession that burned 7 tool calls (~64s) doing exactly that detour before\nsucceeding; see `runbooks/harness-providers.md` and PR that added\n`buildAttachmentsSection()` for the full trace.\n\n## Gotchas\n\n- The route requires `X-Agent-ID` + bearer auth like any other swarm API call — same headers you\'d use for any MCP-adjacent REST call.\n- `mimeType` on the attachment record reflects the real upload `Content-Type` (not a filename-extension guess) — trust it when deciding how to handle the downloaded bytes (image vs PDF vs text).\n- If you get a 404, double-check you\'re using the **attachment ID** (from `attachments[].id`), not the display `name`.\n';
|
|
6706
6943
|
|
|
6707
6944
|
// templates/skills/engineering-standards/config.json
|
|
6708
6945
|
var config_default18 = `{
|
|
@@ -9681,8 +9918,28 @@ File-review is on by default (unless Autopilot):
|
|
|
9681
9918
|
- **REMEMBER**: Document what IS, not what SHOULD BE
|
|
9682
9919
|
`;
|
|
9683
9920
|
|
|
9684
|
-
// templates/skills/
|
|
9921
|
+
// templates/skills/review-offered-task/config.json
|
|
9685
9922
|
var config_default32 = `{
|
|
9923
|
+
"kind": "skill",
|
|
9924
|
+
"name": "review-offered-task",
|
|
9925
|
+
"displayName": "Review Offered Task",
|
|
9926
|
+
"slug": "review-offered-task",
|
|
9927
|
+
"title": "Review Offered Task",
|
|
9928
|
+
"description": "Turn prompt for an offered swarm task: read the offer, accept with task-action and start work-on-task, or reject with a reason.",
|
|
9929
|
+
"version": "1.0.0",
|
|
9930
|
+
"category": "skills",
|
|
9931
|
+
"placeholders": [],
|
|
9932
|
+
"runAllSeedersCandidate": true,
|
|
9933
|
+
"systemDefault": true,
|
|
9934
|
+
"tags": ["tasks", "turn-prompt", "worker"]
|
|
9935
|
+
}
|
|
9936
|
+
`;
|
|
9937
|
+
|
|
9938
|
+
// templates/skills/review-offered-task/content.md
|
|
9939
|
+
var content_default32 = '# Review Offered Task\n\nYou have been offered a task. Your job is to review it and decide whether to accept or reject it based on your capabilities and current workload.\n\n## Workflow\n\n1. **Get task details**: Call the `get-task-details` tool with the provided `taskId` to understand what the task involves.\n\n2. **Evaluate the task**: Consider:\n - Does this task match your capabilities?\n - Do you have the necessary context or access to complete it?\n - Is the task description clear enough to proceed?\n\n3. **Make a decision**:\n - **Accept**: If you can complete this task, call `task-action` with `action: "accept"` and `taskId: "<taskId>"`. Then immediately use the `work-on-task` skill with the taskId to start working on it.\n - **Reject**: If you cannot complete this task, call `task-action` with `action: "reject"`, `taskId: "<taskId>"`, and provide a `reason` explaining why you\'re rejecting it (e.g., "Task requires Python expertise which I don\'t have", "Task description is too vague").\n\n## Example Accept Flow\n\n```\n1. get-task-details taskId="abc-123"\n2. [Review the task details]\n3. task-action action="accept" taskId="abc-123"\n4. /work-on-task abc-123\n```\n\n## Example Reject Flow\n\n```\n1. get-task-details taskId="abc-123"\n2. [Review the task details]\n3. task-action action="reject" taskId="abc-123" reason="Task requires access to production database which I don\'t have"\n4. Stop\n```\n\n## Important Notes\n\n- Always provide a clear reason when rejecting a task - this helps the lead agent reassign it appropriately\n- If you accept, you must immediately start working on the task using the `work-on-task` skill\n- If you reject, the task returns to the unassigned pool for reassignment\n';
|
|
9940
|
+
|
|
9941
|
+
// templates/skills/reviewing/config.json
|
|
9942
|
+
var config_default33 = `{
|
|
9686
9943
|
"category": "skills",
|
|
9687
9944
|
"description": "Structured critique of research, plan, and brainstorm documents for completeness, gaps, and quality.",
|
|
9688
9945
|
"displayName": "Reviewing",
|
|
@@ -9703,7 +9960,7 @@ var config_default32 = `{
|
|
|
9703
9960
|
`;
|
|
9704
9961
|
|
|
9705
9962
|
// templates/skills/reviewing/content.md
|
|
9706
|
-
var
|
|
9963
|
+
var content_default33 = `# Reviewing
|
|
9707
9964
|
|
|
9708
9965
|
You are performing a structured critique of a document (research, plan, or brainstorm) to identify gaps, weaknesses, and quality issues. (For reviewing a code diff, use \`desplega:code-reviewing\` instead — this skill reviews documents.)
|
|
9709
9966
|
|
|
@@ -9955,7 +10212,7 @@ File-review is on by default (unless Autopilot):
|
|
|
9955
10212
|
`;
|
|
9956
10213
|
|
|
9957
10214
|
// templates/skills/scheduled-task-resilience/config.json
|
|
9958
|
-
var
|
|
10215
|
+
var config_default34 = `{
|
|
9959
10216
|
"kind": "skill",
|
|
9960
10217
|
"name": "scheduled-task-resilience",
|
|
9961
10218
|
"displayName": "Scheduled Task Resilience",
|
|
@@ -9972,7 +10229,7 @@ var config_default33 = `{
|
|
|
9972
10229
|
`;
|
|
9973
10230
|
|
|
9974
10231
|
// templates/skills/scheduled-task-resilience/content.md
|
|
9975
|
-
var
|
|
10232
|
+
var content_default34 = `# Scheduled Task Resilience
|
|
9976
10233
|
|
|
9977
10234
|
Use these rules whenever a scheduled or regular task polls or waits on a long-running operation. They prevent heartbeat collisions, lost work, duplicate delivery, and sessions that fail after holding an external job open too long.
|
|
9978
10235
|
|
|
@@ -10072,7 +10329,7 @@ When historical incident detail is useful, search the deployment's memory regist
|
|
|
10072
10329
|
`;
|
|
10073
10330
|
|
|
10074
10331
|
// templates/skills/scheduling/config.json
|
|
10075
|
-
var
|
|
10332
|
+
var config_default35 = `{
|
|
10076
10333
|
"kind": "skill",
|
|
10077
10334
|
"name": "scheduling",
|
|
10078
10335
|
"displayName": "Scheduling",
|
|
@@ -10089,10 +10346,10 @@ var config_default34 = `{
|
|
|
10089
10346
|
`;
|
|
10090
10347
|
|
|
10091
10348
|
// templates/skills/scheduling/content.md
|
|
10092
|
-
var
|
|
10349
|
+
var content_default35 = '# Scheduling\n\nUse a schedule when work repeats on a clock, or when it must run once at a later time. On each tick the schedule creates one run. The run is a workflow, a catalog script, or an agent task.\n\n## Tools\n\n`list-schedules`, `create-schedule`, `update-schedule`, `patch-schedule`, `delete-schedule`, `run-schedule-now`. They are deferred. Load them with your harness tool search before the first call.\n\n## Pick the target type\n\n| The tick should | `targetType` | Required fields |\n|---|---|---|\n| Start a workflow | `workflow` | `workflowId` |\n| Run a catalog script | `script` | `scriptName`, optional `scriptArgs` |\n| Put a reasoning agent in the loop | `agent-task` (default) | `taskTemplate` |\n\nChoose `agent-task` only when the run needs judgment, open-ended work, or tool orchestration that no workflow or script covers. An `agent-task` whose template says "trigger workflow X" or "run script Y" is wrong: use the direct target instead.\n\nThe agent-task fields `targetAgentId`, `model`, `modelTier`, `taskTemplate`, `priority`, and `tags` do not apply to workflow or script targets. Workflow cooldowns still gate workflow targets.\n\n## Pick the timing\n\n| Shape | Fields |\n|---|---|\n| Recurring on a cron | `scheduleType: "recurring"`, `cronExpression` (for example `0 9 * * 1-5`), `timezone` (default `UTC`) |\n| Recurring on an interval | `scheduleType: "recurring"`, `intervalMs` (for example `3600000` for hourly) |\n| Once, at a time | `scheduleType: "one_time"`, `runAt` (ISO datetime) |\n| Once, after a delay | `scheduleType: "one_time"`, `delayMs` |\n\nGive the schedule a unique `name` and a one-line `description` that says what a human gets from it.\n\n## Write the task template (agent-task target)\n\nThe template is the whole task the agent receives. It must state:\n\n- the goal and the inputs (IDs, repo, channel),\n- where the result goes (a page, agent-fs, a Slack thread, a task output),\n- what done looks like.\n\n`targetAgentId` pins the task to one agent. Omit it to use the pool. `modelTier` (`smol`, `regular`, `smart`, `ultra`) is the portable way to pick a model. `model` is a provider-specific override.\n\nTasks created by a schedule are automatic tasks. Their completed output is not stored as memory unless the agent calls `store-progress` with `persistMemory: true`.\n\n## Check back later\n\nA task whose answer needs time (a build, a deploy, a reply) calls `defer-task` with `delayMs` or `runAt`, a `summary` of what you did so far, and a `note` that says what is pending. The tool completes the task and creates the one-off schedule for you. The task reaches its final state (`completed`) on this call, and the `summary` becomes its output. The wake-up task carries the deferred task as its parent, so you receive that task\'s context. Add `checks` to list what to verify on wake-up. Do not hand-roll this with `create-schedule`.\n\n## Secrets\n\nA `taskTemplate` and `scriptArgs` are stored as plain text and replayed on every run. They must not contain a token, password, or key. Call the external API from a script through a registered connection or a credential binding instead. See the `swarm-scripts` skill, section Secrets.\n\n## Verify before you leave\n\n1. `run-schedule-now` once and read the run result.\n2. `list-schedules` with `name` to confirm `nextRunAt` and `enabled`.\n3. For a script target, the script must exist at global scope: `script-search` by name.\n\n## Repair a failing schedule\n\n`list-schedules` with `lastRunStatus: "failed"` or `consecutiveErrorsMin: 3` lists the failing ones. Fix the cause, then `run-schedule-now` to confirm. A schedule you cannot fix now: `patch-schedule` with `enabled: false` and say so in your task output. A second schedule next to a broken one is not a fix.\n\n## Related skills\n\n- `scheduled-task-resilience`: waiting on CI, builds, deploys, or other slow jobs inside a scheduled task.\n- `swarm-scripts`: writing the script a `script` target runs.\n- `workflow-iterate`: building and testing the workflow a `workflow` target starts.\n';
|
|
10093
10350
|
|
|
10094
10351
|
// templates/skills/script-builder/config.json
|
|
10095
|
-
var
|
|
10352
|
+
var config_default36 = `{
|
|
10096
10353
|
"category": "skills",
|
|
10097
10354
|
"description": "Generate durable, re-runnable scripts from session intent — validation scripts (PASS/FAIL contract) AND gather/bulk scripts (many API/tool calls in code, one derived summary out). Supports TypeScript, Python, Bash with auto-detection, enforces context-optimal output, and auto-documents scripts in CLAUDE.md. Triggers on \\"turn this into a script\\", \\"I want to test/validate X end-to-end\\", \\"wrap this in a re-runnable script\\" — and, critically, whenever you are about to make (or just made) ~10+ similar tool/API calls or any bulk fan-out over a list: that mechanical middle belongs in a script, not in context.",
|
|
10098
10355
|
"displayName": "Script Builder",
|
|
@@ -10113,10 +10370,10 @@ var config_default35 = `{
|
|
|
10113
10370
|
`;
|
|
10114
10371
|
|
|
10115
10372
|
// templates/skills/script-builder/content.md
|
|
10116
|
-
var content_default35 = "# script-builder\n\nYou are converting session intent into a durable, re-runnable script committed to the target project's `scripts/` directory. Two script classes share one principle — **only the derived answer re-enters context; raw payloads never do**:\n\n- **Validation scripts** (`check-*`, `e2e-*`, `smoke-*`, …): a single PASS/FAIL line + `/tmp` log path on success, full verbose output redirected to a timestamped log file.\n- **Gather/bulk scripts** (`gather-*`, `bulk-*`): replace N similar tool/API calls with one script that loops, filters, and aggregates *in code* — stdout is one compact summary block (JSON or table), raw responses go to the `/tmp` log. Rubric (from production code-mode data): past ~10 items or any fan-out over a list, a script beats individual tool calls by ~100x on context and roughly halves end-to-end cost. Offer the script *before* the fan-out happens when you can see it coming, not just retrospectively.\n\nBoth classes get an `<important if>` block in `CLAUDE.md`/`AGENTS.md` so future agents discover the script when the intent recurs — durable scripts are reusable agent memory: import, don't re-derive.\n\n**Schema discovery happens in code, too**: when scripting against an unfamiliar API, grep/filter its OpenAPI spec or typed client programmatically to find the few relevant endpoints — never paste the full schema into context.\n\n## Working Agreement\n\nThese instructions establish a working agreement between you and the user. The key principles are:\n\n1. **AskUserQuestion is your primary communication tool** - Whenever you need to ask the user anything (clarifications, preferences, decisions, confirmations), use the **AskUserQuestion tool**. Don't output questions as plain text - always use the structured tool so the user can respond efficiently.\n\n2. **Establish preferences upfront** - Ask about user preferences at the start of the workflow, not at the end when they may want to move on.\n\n3. **Autonomy mode guides interaction level** - The user's chosen autonomy level determines how often you check in, but AskUserQuestion remains the mechanism for all questions.\n\n## When to Use\n\nThis skill activates when:\n- User invokes `/script-builder` command\n- Another skill references `**OPTIONAL SUB-SKILL:** desplega:script-builder`\n- A `planning`, `qa`, or `verifying` flow needs a re-runnable validation script that doesn't yet exist\n- The user expresses intent to \"turn X into a script\", \"wrap this validation into something reusable\", or \"I want to test X end-to-end\" with no existing script\n\n## Autonomy Mode\n\nAdapt your behavior based on the autonomy mode:\n\n| Mode | Behavior |\n|------|----------|\n| **Autopilot** | Detect mode, draft, syntax-check, document, and (if escalation tier) run + iterate without intermediate confirmations. Pause only at hard blockers or destructive side-effects. |\n| **Critical** (Default) | Confirm at each tier boundary (after draft, before doc edit, before run). Use AskUserQuestion for fix application during iterate loop. |\n| **Verbose** | Confirm before each step. Show every diff. Walk through detection reasoning out loud. |\n\nThe autonomy mode is passed by the invoking command. If not specified, default to **Critical**.\n\n## Process Steps\n\n### Step 1: Detect Mode (Retrospective vs Forward-Declared)\n\nDecide silently — **do not** ask the user \"which mode?\". Use the following heuristics:\n\n1. **Scan recent session tool-use history** (the last ~20 tool calls in the current conversation) for test/validation-shaped activity: `curl`/`fetch` calls, `bun run`/`python`/`pytest`, database queries, `agent-browser` actions, repeated `grep`/log inspection of a single endpoint or table. If ≥2 such actions targeting the same area exist → **retrospective mode**. Separately, if the history (or the task ahead) shows the *same call shape repeated ~10+ times or a fan-out over a list* → **gather-script mode**: propose replacing the repetition with one `gather-*` script before continuing.\n2. **Parse the user's invocation message** for cues:\n - Narrative cues → retrospective: *\"we just figured out\"*, *\"turn this into a script\"*, *\"wrap that in\"*, *\"that thing we just did\"*.\n - Intent cues → forward-declared: *\"I want to test\"*, *\"validate that\"*, *\"smoke check\"*, *\"check before deploy\"*.\n3. **Fallback**: when ambiguous, default to **forward-declared**.\n\n**Retrospective first action**: summarize the observed activity back to the user as plain text (≤6 lines: what was probed, against what, with what success signal), then go to Step 3 with a confirmation prompt instead of Q&A.\n\n**Forward first action**: skip directly to Step 3's Q&A.\n\n### Step 2: Scan Existing Scripts for Overlap\n\n**Resolve the scripts directory** in this order:\n1. Check `CLAUDE.md` for a `<!-- script-builder:dir=<path> -->` marker. If present, use that path.\n2. If `scripts/` exists at the repo root, use it.\n3. Use **AskUserQuestion** with options: `scripts/ (Recommended) | custom path | skip dir persistence for this run`.\n\n**Edge case — directory absent**: if the resolved path doesn't exist, skip the dedup scan, print a one-line note (`No existing scripts directory at <path> — proceeding to intent gathering`), and remember to optionally offer to create the directory before Step 5.\n\n**When the directory exists**:\n1. List files in the scripts directory (top-level only for v1).\n2. For each file, read the top of the file (header comment) and capture the file-name tokens.\n3. Read `CLAUDE.md`/`AGENTS.md` for `<important if=\"...\">` blocks that point at scripts in this directory and capture the trigger phrases.\n4. Fuzzy-match the current intent string against (file-name tokens ∪ header keywords ∪ trigger phrases). A \"plausible match\" is shared keyword + same area noun (e.g., `auth`, `health`, `webhook`).\n5. If ≥1 plausible match → use **AskUserQuestion** with options: `Reuse <name> as-is | Extend <name> | Generate new anyway`.\n\nNever silently skip dedup on borderline matches — surface and let the user decide. The **Extend** branch appends a sub-command/flag to the existing script (do not create a new file); document the new flag in the script's header comment and the existing `<important if>` block.\n\n### Step 3: Gather Intent\n\nBoth modes converge on the same internal intent structure: `{ what, success_signal, failure_signal, inputs, env, side_effects }`.\n\n**Forward mode** — use **AskUserQuestion** (one or two questions, not five):\n\n| Question | Options |\n|----------|---------|\n| \"What are we validating, and what's the success signal?\" | [Free text — collect what + success signal in one answer] |\n| \"Any required env vars, inputs, or side-effects to flag (e.g., writes to prod, costs money)?\" | [Free text — optional; skip if forward intent already specified them] |\n\n**Retrospective mode** — present the summary from Step 1 and use **AskUserQuestion** with: `That's the flow | Close but fix X | Start over`. On *Close but fix X*, ask for the correction inline; on *Start over*, fall through to forward-mode Q&A.\n\nPersist the resolved intent in working memory (do not write to disk yet).\n\n### Step 4: Detect Language\n\nPriority order — first match wins, with override paths:\n\n1. **TypeScript** — `package.json` + `tsconfig.json` exist.\n - **Bun** if `bun.lock` or `bunfig.toml` is present.\n - else **tsx** if `tsx` appears in `package.json` devDependencies.\n - else **compiled Node** (note in script header: requires `tsc` build).\n2. **Python** — `pyproject.toml` or `uv.lock` or `requirements.txt` exists.\n - **uv** if `uv.lock` exists or `pyproject.toml` has `[tool.uv]` configured (sets `{{UV_METADATA}}`).\n - else **vanilla python3** (`{{UV_METADATA}}` substituted with empty string).\n3. **Both TS and Python detected** — count source files in `src/`/top-level and ask **AskUserQuestion** tiebreaker with the dominant one Recommended.\n4. `Cargo.toml` / `go.mod` only → fall back to **bash** (note: TS/Python/Bash only in v1).\n5. Nothing matched → **bash**.\n\n**Task-driven override**: if the gathered intent is clearly shell-y (\"verify three docker containers respond\", \"tail this log file for an error\"), propose **bash** even in a TS/Python project.\n\nConfirm via **AskUserQuestion** with the detected language as the first option (Recommended). Skip in Autopilot.\n\n### Step 5: Draft the Script\n\n1. **Pick the template**: `templates/{typescript.ts.tmpl|python.py.tmpl|bash.sh.tmpl}`.\n2. **Resolve substitution markers** from gathered intent:\n - `{{SCRIPT_NAME}}` ← proposed file-name stem (see naming table).\n - `{{WHAT}}` / `{{WHEN}}` / `{{ENV}}` / `{{EXAMPLE}}` ← intent fields.\n - `{{UV_METADATA}}` ← per Step 4.\n3. **Generate `{{TEST_BODY}}`** from the intent. Keep it minimal: a single concrete probe + assertion, not a battery. Re-read the templates' README (`templates/README.md`) for the contract — the body must respect the PASS/FAIL surface. Throw/raise/`exit 1` on failure; let the template's outer try/trap convert it into the FAIL line.\n **Gather-class bodies** adapt the same template: the loop/aggregation replaces the probe, raw per-item responses go to the log only, and the final `console.log`/`print` emits one compact summary (JSON or aligned table) instead of the PASS line — exit non-zero only on operational failure (auth, network), not on \"found problems\" (problems ARE the output).\n4. **Propose a file name** matching the intent shape — see the prefix table below. Use **AskUserQuestion** with the proposed name first (Recommended) and `custom name` as the alternative.\n\n**Naming conventions** (advisory — skill proposes, user overrides):\n\n| Prefix | When | Example |\n|--------|------|---------|\n| `e2e-*` | End-to-end flows across multiple components | `e2e-auth-flow.ts` |\n| `check-*` | Idempotent single-probe verifications | `check-db-boundary.sh` |\n| `smoke-*` | Minimal-viability post-deploy checks | `smoke-prod-api.ts` |\n| `measure-*` | Performance / size / token measurements | `measure-tool-tokens.ts` |\n| `seed-*` / `generate-*` | Data seeding or artifact generation (rare for validation) | `seed-api-keys.sh` |\n| `gather-*` / `bulk-*` | Bulk data-gathering or bulk mutation replacing N tool calls; stdout = one summary block, not PASS/FAIL | `gather-workflow-health.ts` |\n\nIf the intent doesn't match any prefix cleanly, propose a free-form name like `validate-<area>.<ext>`.\n\n5. **Write the file** to the resolved scripts directory. Make it executable (`chmod +x`).\n\n### Step 6: Syntax/Type-Check\n\nRun the appropriate checker:\n\n| Language | Checker (in priority order) |\n|----------|-----------------------------|\n| TypeScript | `bunx tsc --noEmit <file>` if Bun present, else `npx tsc --noEmit <file>` |\n| Python | `python3 -m py_compile <file>` (always) + `ruff check <file>` if `ruff` is on PATH |\n| Bash | `shellcheck <file>` if available, else `bash -n <file>` |\n\n**On success**: log a single line (`syntax check OK`) and proceed to Step 7.\n\n**On failure**:\n1. Print the error (≤10 lines, not the full output).\n2. Propose a concrete one-edit fix (the exact `Edit` you'd apply).\n3. Use **AskUserQuestion** with `Apply fix | Investigate | Stop`.\n - **Apply fix** → edit the script and re-run the checker (loop, no hardcoded cap).\n - **Investigate** → drop into discussion with the user; do not auto-apply anything.\n - **Stop** → leave script in place at its path; print the path; do not delete.\n\n### Step 7: Document the Script\n\nAuto-edit the target project's `CLAUDE.md` and/or `AGENTS.md` so future agents discover this script when the matching intent recurs.\n\n**Block template** (the literal markdown the skill emits):\n\n```markdown\n<important if=\"[TRIGGER: e.g., you are testing the auth flow]\">\n\n## [Area] validation\n\nRun `scripts/<name>` to [one-liner]. Requires [env/deps]. Example: `<cmd>`. Full log at `/tmp/<name>-*.log`.\n\nGenerated/maintained via `/script-builder`.\n\n</important>\n```\n\n**Behavior**:\n\n1. **Target file selection**: edit `CLAUDE.md` and `AGENTS.md` if both exist; edit only what exists. **Never** create either file from scratch — if neither exists, print a one-line note (`No CLAUDE.md or AGENTS.md found — script generated but not documented`) and skip this step.\n2. **Placement heuristic**: search the file for the first heading matching `Test|Testing|Validation|Scripts` (case-insensitive). If found, append the new block within/after that section. Otherwise, append a new `## Scripts for testing & validation` section near the end of the file but **before** any heading matching `License|Acknowledg|Maintain|Contributors`.\n3. **Idempotency**: if a block referencing `scripts/<name>` already exists (i.e., a prior `/script-builder` run for the same script name), update it in place — replace the entire `<important if=...>...</important>` block, do not append a duplicate.\n4. **Scripts-dir marker**: if Step 2 resolved the scripts directory by user choice (not from an existing marker), insert `<!-- script-builder:dir=<path> -->` near the top of `CLAUDE.md` (after the title) so subsequent runs are silent. Skip if the marker already exists.\n5. **Scale gate — `scripts/index.md`**: if the scripts directory holds **>10 documented scripts**, per-script `<important if>` blocks become their own context bloat. Generate/maintain a `scripts/index.md` hub instead (one line + link per script, mirroring the `runbooks/` convention from `desplega:engineering-standards`), collapse the CLAUDE.md/AGENTS.md blocks into ONE pointer block referencing the hub, and add new scripts to the hub only.\n6. **Show the diff**: run the equivalent of `git diff CLAUDE.md AGENTS.md` and print a 5-line summary of what changed. **Never auto-stage** — the user commits.\n\n### Step 8: Offer Escalation\n\nAfter the doc edit, decide whether to proceed to the run-and-iterate tier.\n\n| Autonomy | Behavior |\n|----------|----------|\n| **Autopilot** | Auto-escalate to Step 9 unless the intent flagged side-effects (writes to prod, sends real money, mutates a shared resource). On flagged side-effects, fall through to Critical behavior. |\n| **Critical** (Default) | Use **AskUserQuestion**: `Run it now to confirm it works | I'll run it myself later | Just generate, don't run`. |\n| **Verbose** | Same as Critical, plus offer the proposed run command for review before executing. |\n\nIf the user picks \"I'll run it myself later\" or \"Just generate, don't run\" → skip directly to Step 10.\n\n### Step 9: Iterate on Failures (Escalated Tier Only)\n\nA bounded-by-the-human loop. **Never auto-apply a fix** outside Autopilot.\n\n1. **Run the script** with the proposed example invocation (no `--verbose`, no `--json`). Capture exit code and `tail -n 40` of the `/tmp` log.\n2. **If exit code 0** → report PASS (echo the script's PASS line) and proceed to Step 10.\n3. **If exit code non-zero**:\n - Summarize the failure in **1–3 lines**: error class (timeout / 4xx / 5xx / assertion / dependency-missing / etc.) + likely cause (grep the log for known signatures: `ECONNREFUSED`, `Traceback`, `non-zero exit`, `command not found`, etc.).\n - **Propose a concrete diff** — the exact `Edit` you would apply to the script. Show old → new.\n - Use **AskUserQuestion**: `Apply fix | Investigate differently | Stop`.\n - **Apply fix** → edit the script, log the change, loop back to (1).\n - **Investigate differently** → drop into discussion; do not auto-apply.\n - **Stop** → leave the script in place, print its path; do not revert.\n\n**No hardcoded retry cap** — the human is the implicit bound.\n\n**Side-effect flag**: if the intent declared side-effects (Step 3) and Autopilot is active, surface a one-line `WARNING: this script <does X> against <target>` before the first run and require explicit confirmation via **AskUserQuestion** even in Autopilot mode.\n\n### Step 10: Handoff\n\nHow the skill exits depends on how it was invoked:\n\n**Invoked as a sub-skill** (from `planning`, `qa`, `verifying`):\nReturn control to the parent skill with a structured summary: `{ script_path, status: \"pass\"|\"fail\"|\"unrun\", log_path?, doc_files_edited: [...] }`.\n\n**Invoked directly** (`/script-builder`):\nUse **AskUserQuestion**: `Run it with /qa | Run /verify-plan | Commit the script and doc changes | Done`.\n- **Run with /qa** → invoke `desplega:qa` with the script path as the source.\n- **Run /verify-plan** → invoke `desplega:verifying` if a plan path is in current context.\n- **Commit** → propose a commit message (`feat(scripts): add scripts/<name> for <area> validation`) and stage only the generated script + the CLAUDE.md/AGENTS.md edits. Do not auto-commit; show the proposed `git add` and `git commit` commands and require user confirmation.\n- **Done** → print the script path + log path (if escalation ran) and exit.\n\n**Abort path** (Stop selected at any earlier gate): leave the generated script in place, leave any CLAUDE.md/AGENTS.md edit in place if Step 7 ran, and print a one-liner: `Aborted. Script: <path>. Doc edits: <files or \"none\">. Re-run /script-builder or git checkout to discard.` Do not `git restore` on the user's behalf.\n\n## Learning Capture\n\n**OPTIONAL SUB-SKILL:** If significant insights, patterns, gotchas, or decisions emerged during this workflow, consider using `desplega:learning` to capture them via `/learning capture`. Focus on learnings that would help someone else in a future session.\n";
|
|
10373
|
+
var content_default36 = "# script-builder\n\nYou are converting session intent into a durable, re-runnable script committed to the target project's `scripts/` directory. Two script classes share one principle — **only the derived answer re-enters context; raw payloads never do**:\n\n- **Validation scripts** (`check-*`, `e2e-*`, `smoke-*`, …): a single PASS/FAIL line + `/tmp` log path on success, full verbose output redirected to a timestamped log file.\n- **Gather/bulk scripts** (`gather-*`, `bulk-*`): replace N similar tool/API calls with one script that loops, filters, and aggregates *in code* — stdout is one compact summary block (JSON or table), raw responses go to the `/tmp` log. Rubric (from production code-mode data): past ~10 items or any fan-out over a list, a script beats individual tool calls by ~100x on context and roughly halves end-to-end cost. Offer the script *before* the fan-out happens when you can see it coming, not just retrospectively.\n\nBoth classes get an `<important if>` block in `CLAUDE.md`/`AGENTS.md` so future agents discover the script when the intent recurs — durable scripts are reusable agent memory: import, don't re-derive.\n\n**Schema discovery happens in code, too**: when scripting against an unfamiliar API, grep/filter its OpenAPI spec or typed client programmatically to find the few relevant endpoints — never paste the full schema into context.\n\n## Working Agreement\n\nThese instructions establish a working agreement between you and the user. The key principles are:\n\n1. **AskUserQuestion is your primary communication tool** - Whenever you need to ask the user anything (clarifications, preferences, decisions, confirmations), use the **AskUserQuestion tool**. Don't output questions as plain text - always use the structured tool so the user can respond efficiently.\n\n2. **Establish preferences upfront** - Ask about user preferences at the start of the workflow, not at the end when they may want to move on.\n\n3. **Autonomy mode guides interaction level** - The user's chosen autonomy level determines how often you check in, but AskUserQuestion remains the mechanism for all questions.\n\n## When to Use\n\nThis skill activates when:\n- User invokes `/script-builder` command\n- Another skill references `**OPTIONAL SUB-SKILL:** desplega:script-builder`\n- A `planning`, `qa`, or `verifying` flow needs a re-runnable validation script that doesn't yet exist\n- The user expresses intent to \"turn X into a script\", \"wrap this validation into something reusable\", or \"I want to test X end-to-end\" with no existing script\n\n## Autonomy Mode\n\nAdapt your behavior based on the autonomy mode:\n\n| Mode | Behavior |\n|------|----------|\n| **Autopilot** | Detect mode, draft, syntax-check, document, and (if escalation tier) run + iterate without intermediate confirmations. Pause only at hard blockers or destructive side-effects. |\n| **Critical** (Default) | Confirm at each tier boundary (after draft, before doc edit, before run). Use AskUserQuestion for fix application during iterate loop. |\n| **Verbose** | Confirm before each step. Show every diff. Walk through detection reasoning out loud. |\n\nThe autonomy mode is passed by the invoking command. If not specified, default to **Critical**.\n\n## Process Steps\n\n### Step 1: Detect Mode (Retrospective vs Forward-Declared)\n\nDecide silently — **do not** ask the user \"which mode?\". Use the following heuristics:\n\n1. **Scan recent session tool-use history** (the last ~20 tool calls in the current conversation) for test/validation-shaped activity: `curl`/`fetch` calls, `bun run`/`python`/`pytest`, database queries, `agent-browser` actions, repeated `grep`/log inspection of a single endpoint or table. If ≥2 such actions targeting the same area exist → **retrospective mode**. Separately, if the history (or the task ahead) shows the *same call shape repeated ~10+ times or a fan-out over a list* → **gather-script mode**: propose replacing the repetition with one `gather-*` script before continuing.\n2. **Parse the user's invocation message** for cues:\n - Narrative cues → retrospective: *\"we just figured out\"*, *\"turn this into a script\"*, *\"wrap that in\"*, *\"that thing we just did\"*.\n - Intent cues → forward-declared: *\"I want to test\"*, *\"validate that\"*, *\"smoke check\"*, *\"check before deploy\"*.\n3. **Fallback**: when ambiguous, default to **forward-declared**.\n\n**Retrospective first action**: summarize the observed activity back to the user as plain text (≤6 lines: what was probed, against what, with what success signal), then go to Step 3 with a confirmation prompt instead of Q&A.\n\n**Forward first action**: skip directly to Step 3's Q&A.\n\n### Step 2: Scan Existing Scripts for Overlap\n\n**Resolve the scripts directory** in this order:\n1. Check `CLAUDE.md` for a `<!-- script-builder:dir=<path> -->` marker. If present, use that path.\n2. If `scripts/` exists at the repo root, use it.\n3. Use **AskUserQuestion** with options: `scripts/ (Recommended) | custom path | skip dir persistence for this run`.\n\n**Edge case — directory absent**: if the resolved path doesn't exist, skip the dedup scan, print a one-line note (`No existing scripts directory at <path> — proceeding to intent gathering`), and remember to optionally offer to create the directory before Step 5.\n\n**When the directory exists**:\n1. List files in the scripts directory (top-level only for v1).\n2. For each file, read the top of the file (header comment) and capture the file-name tokens.\n3. Read `CLAUDE.md`/`AGENTS.md` for `<important if=\"...\">` blocks that point at scripts in this directory and capture the trigger phrases.\n4. Fuzzy-match the current intent string against (file-name tokens ∪ header keywords ∪ trigger phrases). A \"plausible match\" is shared keyword + same area noun (e.g., `auth`, `health`, `webhook`).\n5. If ≥1 plausible match → use **AskUserQuestion** with options: `Reuse <name> as-is | Extend <name> | Generate new anyway`.\n\nNever silently skip dedup on borderline matches — surface and let the user decide. The **Extend** branch appends a sub-command/flag to the existing script (do not create a new file); document the new flag in the script's header comment and the existing `<important if>` block.\n\n### Step 3: Gather Intent\n\nBoth modes converge on the same internal intent structure: `{ what, success_signal, failure_signal, inputs, env, side_effects }`.\n\n**Forward mode** — use **AskUserQuestion** (one or two questions, not five):\n\n| Question | Options |\n|----------|---------|\n| \"What are we validating, and what's the success signal?\" | [Free text — collect what + success signal in one answer] |\n| \"Any required env vars, inputs, or side-effects to flag (e.g., writes to prod, costs money)?\" | [Free text — optional; skip if forward intent already specified them] |\n\n**Retrospective mode** — present the summary from Step 1 and use **AskUserQuestion** with: `That's the flow | Close but fix X | Start over`. On *Close but fix X*, ask for the correction inline; on *Start over*, fall through to forward-mode Q&A.\n\nPersist the resolved intent in working memory (do not write to disk yet).\n\n### Step 4: Detect Language\n\nPriority order — first match wins, with override paths:\n\n1. **TypeScript** — `package.json` + `tsconfig.json` exist.\n - **Bun** if `bun.lock` or `bunfig.toml` is present.\n - else **tsx** if `tsx` appears in `package.json` devDependencies.\n - else **compiled Node** (note in script header: requires `tsc` build).\n2. **Python** — `pyproject.toml` or `uv.lock` or `requirements.txt` exists.\n - **uv** if `uv.lock` exists or `pyproject.toml` has `[tool.uv]` configured (sets `{{UV_METADATA}}`).\n - else **vanilla python3** (`{{UV_METADATA}}` substituted with empty string).\n3. **Both TS and Python detected** — count source files in `src/`/top-level and ask **AskUserQuestion** tiebreaker with the dominant one Recommended.\n4. `Cargo.toml` / `go.mod` only → fall back to **bash** (note: TS/Python/Bash only in v1).\n5. Nothing matched → **bash**.\n\n**Task-driven override**: if the gathered intent is clearly shell-y (\"verify three docker containers respond\", \"tail this log file for an error\"), propose **bash** even in a TS/Python project.\n\nConfirm via **AskUserQuestion** with the detected language as the first option (Recommended). Skip in Autopilot.\n\n### Step 5: Draft the Script\n\n1. **Pick the template**: `templates/{typescript.ts.tmpl|python.py.tmpl|bash.sh.tmpl}`.\n2. **Resolve substitution markers** from gathered intent:\n - `{{SCRIPT_NAME}}` ← proposed file-name stem (see naming table).\n - `{{WHAT}}` / `{{WHEN}}` / `{{ENV}}` / `{{EXAMPLE}}` ← intent fields.\n - `{{UV_METADATA}}` ← per Step 4.\n3. **Generate `{{TEST_BODY}}`** from the intent. Keep it minimal: a single concrete probe + assertion, not a battery. Re-read the templates' README (`templates/README.md`) for the contract — the body must respect the PASS/FAIL surface. Throw/raise/`exit 1` on failure; let the template's outer try/trap convert it into the FAIL line.\n **Gather-class bodies** adapt the same template: the loop/aggregation replaces the probe, raw per-item responses go to the log only, and the final `console.log`/`print` emits one compact summary (JSON or aligned table) instead of the PASS line — exit non-zero only on operational failure (auth, network), not on \"found problems\" (problems ARE the output).\n4. **Propose a file name** matching the intent shape — see the prefix table below. Use **AskUserQuestion** with the proposed name first (Recommended) and `custom name` as the alternative.\n\n**Naming conventions** (advisory — skill proposes, user overrides):\n\n| Prefix | When | Example |\n|--------|------|---------|\n| `e2e-*` | End-to-end flows across multiple components | `e2e-auth-flow.ts` |\n| `check-*` | Idempotent single-probe verifications | `check-db-boundary.sh` |\n| `smoke-*` | Minimal-viability post-deploy checks | `smoke-prod-api.ts` |\n| `measure-*` | Performance / size / token measurements | `measure-tool-tokens.ts` |\n| `seed-*` / `generate-*` | Data seeding or artifact generation (rare for validation) | `seed-api-keys.sh` |\n| `gather-*` / `bulk-*` | Bulk data-gathering or bulk mutation replacing N tool calls; stdout = one summary block, not PASS/FAIL | `gather-workflow-health.ts` |\n\nIf the intent doesn't match any prefix cleanly, propose a free-form name like `validate-<area>.<ext>`.\n\n5. **Write the file** to the resolved scripts directory. Make it executable (`chmod +x`).\n\n### Step 6: Syntax/Type-Check\n\nRun the appropriate checker:\n\n| Language | Checker (in priority order) |\n|----------|-----------------------------|\n| TypeScript | `bunx tsc --noEmit <file>` if Bun present, else `npx tsc --noEmit <file>` |\n| Python | `python3 -m py_compile <file>` (always) + `ruff check <file>` if `ruff` is on PATH |\n| Bash | `shellcheck <file>` if available, else `bash -n <file>` |\n\n**On success**: log a single line (`syntax check OK`) and proceed to Step 7.\n\n**On failure**:\n1. Print the error (≤10 lines, not the full output).\n2. Propose a concrete one-edit fix (the exact `Edit` you'd apply).\n3. Use **AskUserQuestion** with `Apply fix | Investigate | Stop`.\n - **Apply fix** → edit the script and re-run the checker (loop, no hardcoded cap).\n - **Investigate** → drop into discussion with the user; do not auto-apply anything.\n - **Stop** → leave script in place at its path; print the path; do not delete.\n\n### Step 7: Document the Script\n\nAuto-edit the target project's `CLAUDE.md` and/or `AGENTS.md` so future agents discover this script when the matching intent recurs.\n\n**Block template** (the literal markdown the skill emits):\n\n```markdown\n<important if=\"[TRIGGER: e.g., you are testing the auth flow]\">\n\n## [Area] validation\n\nRun `scripts/<name>` to [one-liner]. Requires [env/deps]. Example: `<cmd>`. Full log at `/tmp/<name>-*.log`.\n\nGenerated/maintained via `/script-builder`.\n\n</important>\n```\n\n**Behavior**:\n\n1. **Target file selection**: edit `CLAUDE.md` and `AGENTS.md` if both exist; edit only what exists. **Never** create either file from scratch — if neither exists, print a one-line note (`No CLAUDE.md or AGENTS.md found — script generated but not documented`) and skip this step.\n2. **Placement heuristic**: search the file for the first heading matching `Test|Testing|Validation|Scripts` (case-insensitive). If found, append the new block within/after that section. Otherwise, append a new `## Scripts for testing & validation` section near the end of the file but **before** any heading matching `License|Acknowledg|Maintain|Contributors`.\n3. **Idempotency**: if a block referencing `scripts/<name>` already exists (i.e., a prior `/script-builder` run for the same script name), update it in place — replace the entire `<important if=...>...</important>` block, do not append a duplicate.\n4. **Scripts-dir marker**: if Step 2 resolved the scripts directory by user choice (not from an existing marker), insert `<!-- script-builder:dir=<path> -->` near the top of `CLAUDE.md` (after the title) so subsequent runs are silent. Skip if the marker already exists.\n5. **Scale gate — `scripts/index.md`**: if the scripts directory holds **>10 documented scripts**, per-script `<important if>` blocks become their own context bloat. Generate/maintain a `scripts/index.md` hub instead (one line + link per script, mirroring the `runbooks/` convention from `desplega:engineering-standards`), collapse the CLAUDE.md/AGENTS.md blocks into ONE pointer block referencing the hub, and add new scripts to the hub only.\n6. **Show the diff**: run the equivalent of `git diff CLAUDE.md AGENTS.md` and print a 5-line summary of what changed. **Never auto-stage** — the user commits.\n\n### Step 8: Offer Escalation\n\nAfter the doc edit, decide whether to proceed to the run-and-iterate tier.\n\n| Autonomy | Behavior |\n|----------|----------|\n| **Autopilot** | Auto-escalate to Step 9 unless the intent flagged side-effects (writes to prod, sends real money, mutates a shared resource). On flagged side-effects, fall through to Critical behavior. |\n| **Critical** (Default) | Use **AskUserQuestion**: `Run it now to confirm it works | I'll run it myself later | Just generate, don't run`. |\n| **Verbose** | Same as Critical, plus offer the proposed run command for review before executing. |\n\nIf the user picks \"I'll run it myself later\" or \"Just generate, don't run\" → skip directly to Step 10.\n\n### Step 9: Iterate on Failures (Escalated Tier Only)\n\nA bounded-by-the-human loop. **Never auto-apply a fix** outside Autopilot.\n\n1. **Run the script** with the proposed example invocation (no `--verbose`, no `--json`). Capture exit code and `tail -n 40` of the `/tmp` log.\n2. **If exit code 0** → report PASS (echo the script's PASS line) and proceed to Step 10.\n3. **If exit code non-zero**:\n - Summarize the failure in **1–3 lines**: error class (timeout / 4xx / 5xx / assertion / dependency-missing / etc.) + likely cause (grep the log for known signatures: `ECONNREFUSED`, `Traceback`, `non-zero exit`, `command not found`, etc.).\n - **Propose a concrete diff** — the exact `Edit` you would apply to the script. Show old → new.\n - Use **AskUserQuestion**: `Apply fix | Investigate differently | Stop`.\n - **Apply fix** → edit the script, log the change, loop back to (1).\n - **Investigate differently** → drop into discussion; do not auto-apply.\n - **Stop** → leave the script in place, print its path; do not revert.\n\n**No hardcoded retry cap** — the human is the implicit bound.\n\n**Side-effect flag**: if the intent declared side-effects (Step 3) and Autopilot is active, surface a one-line `WARNING: this script <does X> against <target>` before the first run and require explicit confirmation via **AskUserQuestion** even in Autopilot mode.\n\n### Step 10: Handoff\n\nHow the skill exits depends on how it was invoked:\n\n**Invoked as a sub-skill** (from `planning`, `qa`, `verifying`):\nReturn control to the parent skill with a structured summary: `{ script_path, status: \"pass\"|\"fail\"|\"unrun\", log_path?, doc_files_edited: [...] }`.\n\n**Invoked directly** (`/script-builder`):\nUse **AskUserQuestion**: `Run it with /qa | Run /verify-plan | Commit the script and doc changes | Done`.\n- **Run with /qa** → invoke `desplega:qa` with the script path as the source.\n- **Run /verify-plan** → invoke `desplega:verifying` if a plan path is in current context.\n- **Commit** → propose a commit message (`feat(scripts): add scripts/<name> for <area> validation`) and stage only the generated script + the CLAUDE.md/AGENTS.md edits. Do not auto-commit; show the proposed `git add` and `git commit` commands and require user confirmation.\n- **Done** → print the script path + log path (if escalation ran) and exit.\n\n**Abort path** (Stop selected at any earlier gate): leave the generated script in place, leave any CLAUDE.md/AGENTS.md edit in place if Step 7 ran, and print a one-liner: `Aborted. Script: <path>. Doc edits: <files or \"none\">. Re-run /script-builder or git checkout to discard.` Do not `git restore` on the user's behalf.\n\n## Learning Capture\n\n**OPTIONAL SUB-SKILL:** If significant insights, patterns, gotchas, or decisions emerged during this workflow, consider using `desplega:learning` to capture them via `/learning capture`. Focus on learnings that would help someone else in a future session.\n";
|
|
10117
10374
|
|
|
10118
10375
|
// templates/skills/script-workflows/config.json
|
|
10119
|
-
var
|
|
10376
|
+
var config_default37 = `{
|
|
10120
10377
|
"kind": "skill",
|
|
10121
10378
|
"name": "script-workflows",
|
|
10122
10379
|
"displayName": "Script Workflows",
|
|
@@ -10133,16 +10390,16 @@ var config_default36 = `{
|
|
|
10133
10390
|
`;
|
|
10134
10391
|
|
|
10135
10392
|
// templates/skills/script-workflows/content.md
|
|
10136
|
-
var
|
|
10393
|
+
var content_default37 = "Use this skill when a user asks to launch, monitor, inspect, or debug a durable script workflow run. This is for the Script Workflows v1 runtime: one-off TypeScript workflow source with journaled `swarm-script`, `raw-llm`, and `agent-task` steps.\n\n## Tool Flow\n\nLoad the script workflow tools with ToolSearch when they are not already visible:\n\n```text\nlaunch-script-run\nget-script-run\nlist-script-runs\n```\n\nUse `launch-script-run` to start a one-off run. It calls the same `/api/script-runs` API as the dashboard, preserves the invoking agent identity, and starts the run in the background.\n\nUse `get-script-run` to read terminal status and journal entries. Poll it when needed, but keep polling bounded and report progress for long runs.\n\nUse `list-script-runs` to find recent runs or filter by `status` / `agentId`.\n\nDo not hand-roll raw HTTP for this flow unless the tool itself is broken and you are explicitly debugging the API. The tool handles auth and `X-Agent-ID` like the existing inline `script-run` tool family.\n\n## Source Shape\n\nAuthor TypeScript workflow source as a default export. The runtime provides `args` and `ctx`.\n\n```ts\nexport default async function main(args, ctx) {\n const lookup = await ctx.step.swarmScript(\"lookup-data\", {\n scriptName: \"fetch-readable\",\n args: { url: args.url },\n });\n\n const summary = await ctx.step.rawLlm(\"summarize\", {\n prompt: `Summarize this for an operator:\\n${JSON.stringify(lookup)}`,\n });\n\n const task = await ctx.step.agentTask(\"operator-review\", {\n task: `Review this summary and flag risks:\\n${JSON.stringify(summary)}`,\n tags: [\"script-run\"],\n priority: 50,\n });\n\n return { lookup, summary, task };\n}\n```\n\n`ctx.step.agentTask` blocks until the dispatched task reaches a terminal status (default `waitForCompletion: true`, default `timeoutMs` 2h) and journals its real output — a sequential `plan → implement → review` chain will not fan out. Pass `waitForCompletion: false` for the legacy fire-and-poll-yourself shape, or `failOnTaskFailure: false` to receive `{taskId, status: \"failed\", error}` instead of a throw when the task fails/is cancelled.\n\n## Label Rules\n\nStep labels are durability keys. They must be stable and unique for each logical step. Do not reuse the same literal label inside a loop; launch will fail with `label_lint_violation`.\n\nFor looped work, include an item identifier in the label:\n\n```ts\nfor (const item of args.items) {\n await ctx.step.agentTask(`review-${item.id}`, { task: item.prompt });\n}\n```\n\n## Statuses\n\nTerminal statuses to surface clearly:\n\n- `completed` — run finished and `output` may be present.\n- `failed` — run ended with `error`.\n- `cancelled` — run was cancelled before completion.\n- `aborted_limit` — runtime guardrail stopped the run, usually step count, agent-task count, or wall-clock cap.\n- `label_lint_violation` — launch-time rejection, not a persisted run status.\n\nWhen a run is not terminal, report the current status, journal count, and latest heartbeat if present.\n";
|
|
10137
10394
|
|
|
10138
10395
|
// templates/skills/slack-interaction/config.json
|
|
10139
|
-
var
|
|
10396
|
+
var config_default38 = '{\n "kind": "skill",\n "name": "slack-interaction",\n "displayName": "Slack Interaction",\n "slug": "slack-interaction",\n "title": "Slack Interaction",\n "description": "Slack: reply, post, read, upload, and the thread rules. What the engine already posts, the one-message rule, `slack-reply`, `slack-post`, `slack-start-thread`, `slack-read`, `slack-upload-file`, `slack-download-file`, `slack-list-channels`, `slack-update`, `slack-delete`, unknown-user registration with `manage-user`, and Slack standing orders. Use before any Slack message.",\n "version": "1.0.0",\n "category": "skills",\n "placeholders": [],\n "runAllSeedersCandidate": true,\n "systemDefault": true,\n "tags": ["slack", "communication"]\n}\n';
|
|
10140
10397
|
|
|
10141
10398
|
// templates/skills/slack-interaction/content.md
|
|
10142
|
-
var
|
|
10399
|
+
var content_default38 = '# Slack interaction\n\n## What the engine posts\n\nFor every task that came from Slack, the engine owns the thread tree and the top-level outcome card. It posts the start, the completion, and the failure. You do not.\n\n## Your one message\n\n- At most one message per task, and only when the outcome card will not carry it: a question, a decision the requester must make, a link to a page or file with one line of context.\n- Progress, receipts, acknowledgments, and relayed worker output stay out of Slack.\n- Concrete content. The length matches what the requester asked for.\n- The "How you write" rules of your system prompt apply. Slack renders mrkdwn: `*bold*`, `_italic_`, `` `code` ``, `<url|text>` for links. Markdown headings and tables do not render.\n\n## Where to post\n\nThe task carries `slackChannelId` and `slackThreadTs` in its metadata. A follow-up task with `parentTaskId` inherits them.\n\n- Reply in the task\'s thread: `slack-reply` with `taskId` and `message`.\n- Reply to an inbox message: `slack-reply` with `inboxMessageId`.\n- New top-level message in a channel (lead): `slack-start-thread` with `channelId`, then `slack-post` with the returned `ts` as `threadTs` for replies under it.\n- Fix your own message: `slack-update` (text) or `slack-delete` (lead). Both work only on messages this bot authored.\n\n## Tools\n\n| Tool | Use |\n|---|---|\n| `slack-reply` | reply in a thread by `taskId` or `inboxMessageId` |\n| `slack-post` | post to a channel, optional `threadTs` (lead) |\n| `slack-start-thread` | post a top-level message and get its `ts` (lead) |\n| `slack-read` | read a thread by `taskId` or `inboxMessageId`, or a channel by `channelId` (lead) |\n| `slack-list-channels` | channels the bot is a member of |\n| `slack-upload-file` | upload a file to a thread or channel, up to 1 GB |\n| `slack-download-file` | attach a Slack file (by ID or URL) to your task; run the `fetchCommand` it returns to get the bytes |\n| `slack-update` | edit your own message |\n| `slack-delete` | delete your own message (lead) |\n| `slack-create-channel`, `slack-invite-to-channel`, `slack-archive-channel` | channel lifecycle (lead) |\n\nFiles attached to your task already come with download commands in the task message. Use those before `slack-download-file`. `slack-read` on your task also attaches the files in the thread and gives each one a `fetchCommand`. Don\'t look for Slack files under `/app/shared` or `/workspace/shared/downloads`: those paths are the API server\'s disk.\n\n## Unknown user\n\nA task without `requestedByUserId` came from a Slack user the swarm does not know. Register them with `manage-user`, using the Slack user ID and display name from the task metadata, then continue. When you learn a requester\'s stable preferences (language, tone, verbosity), the lead stores them in the user\'s `comms` field with `manage-user`.\n\n## Lead standing orders\n\nWhen your heartbeat runbook says so, check for unaddressed requests older than one hour: `slack-list-channels`, then `slack-read` per channel, then create a task for each open request.\n\n## Scripts-only mode\n\nThe named Slack tools are not registered. Use `script-run` with inline source: `ctx.swarm.slack_reply({ taskId, message })`. The task ID carries the thread context.\n';
|
|
10143
10400
|
|
|
10144
10401
|
// templates/skills/step-running/config.json
|
|
10145
|
-
var
|
|
10402
|
+
var config_default39 = `{
|
|
10146
10403
|
"category": "skills",
|
|
10147
10404
|
"description": "Execute a single DAG step as an autonomous background sub-agent. Sibling of phase-running for DAG plans produced by v-planning. Reads a step-<n>.md file directly, atomically claims it via frontmatter status, runs the three-bucket Success Criteria, and reports back. Spawned by v-implementing or by /run-step.",
|
|
10148
10405
|
"displayName": "Step Running",
|
|
@@ -10163,10 +10420,10 @@ var config_default38 = `{
|
|
|
10163
10420
|
`;
|
|
10164
10421
|
|
|
10165
10422
|
// templates/skills/step-running/content.md
|
|
10166
|
-
var
|
|
10423
|
+
var content_default39 = "# Step Running\n\nYou execute a single step of a DAG plan as an atomic background sub-agent. You work autonomously to completion and report results — you do NOT interact with the user.\n\nThis is the DAG sibling of `phase-running`. The execution model and atomicity contract are identical; the differences are:\n- You receive a **step file path** (`step-<n>.md`), not a plan path + phase number.\n- You **claim the step atomically** via the step's frontmatter `status` field before doing work, and release it on completion / failure. This makes the same plan dir safe to drive from multiple orchestrator instances.\n\n## Execution Model\n\nThis skill runs inside a background `Agent` (sub-agent). v-implementing (or a user invoking `/run-step`) spawns it via the Agent tool with `run_in_background: true`.\n\nThe step agent receives:\n- **Step path**: full path to `step-<n>.md`\n- **Plan dir**: full path to the parent plan directory (read `root.md` from here for plan-level context)\n- **Agent ID**: unique identifier for this sub-agent (e.g. orchestrator session ID + step ID + timestamp). Used for atomic claim + stale-claim detection.\n- **Relevant context**: any extra context from the caller\n\n## Concurrency: Atomic Claim\n\nBefore doing any work, claim the step:\n\n1. Read the step file's frontmatter.\n2. **If `status: done`** — report `Status: skipped` and exit. The step is already finished.\n3. **If `status: claimed`** and `assignee` differs from your agent ID:\n - Fresh claim (`claimed_at` within last hour): report `Status: blocked` (reason: `claimed by <other-id>`) and exit.\n - Stale claim (>1h): proceed and overwrite — the previous worker likely died.\n4. **Otherwise** (`status: ready`, or stale `claimed`): rewrite the frontmatter block in a single `Edit` so the write is atomic-enough for filesystem-based coordination. Set:\n - `status: claimed`\n - `assignee: <your-agent-id>`\n - `claimed_at: <ISO timestamp UTC>`\n5. Re-read the file. If `assignee` is not yours, another worker raced you — report `Status: blocked` (reason: `lost claim race`) and exit.\n\nOn terminal transitions, set frontmatter:\n- **Completed**: `status: done`, clear `assignee` and `claimed_at`.\n- **Blocked or failed (retry-able)**: `status: ready`, clear `assignee` and `claimed_at`. The orchestrator (or another worker) can retry.\n- **Failed (non-retry-able)**: leave `status: claimed` so the orchestrator can investigate; include the reason in the report.\n\nFor true cross-machine atomicity (NFS, etc.), the caller is responsible for rendezvous (e.g. a shared lock service). The single-Edit pattern is good-enough for local filesystem and well-behaved network filesystems.\n\n## Autonomy\n\nStep agents always run as **Autopilot** within the sub-agent. The calling context controls outer autonomy and human checkpoints.\n\n**CRITICAL**: Step agents do NOT use AskUserQuestion. If something is ambiguous, report `Status: blocked` with details. The caller handles all user interaction.\n\n## Process Steps\n\n### Step 1: Load Context\n\n1. **Claim the step** (see \"Concurrency: Atomic Claim\"). Stop here on any non-claim outcome.\n2. Read the full step file.\n3. Read `root.md` from the plan dir for plan-level context: Overview, Current State, Desired End State, Implementation Approach, Global Verification.\n4. Read all files mentioned in the step's \"Changes Required\" section.\n\n### Step 2: Pre-flight Check\n\n| Check | Action if failed |\n|-------|-----------------|\n| All `depends_on` steps have `status: done` | Scheduler bug — release claim, report `blocked` |\n| No merge conflicts in target files | Release claim, report `blocked` |\n| Files/dirs from depended-on steps exist | Release claim, report `blocked` |\n\n### Step 3: Execute Step\n\nImplement the changes described in the step's \"Changes Required\" section. Adapt to minor mismatches; report `blocked` for significant ones.\n\n### Step 4: Run Verification\n\nSame three-bucket pattern as `phase-running`:\n1. **Automated Verification** (runnable commands): run each, record pass/fail. On failure, attempt one fix-and-retry.\n2. **Automated QA** (agent-driven scenarios — browser-use, screenshot diff, CLI walkthrough): execute, record pass/fail per item.\n3. **Manual Verification**: leave unchecked. Caller handles with the user.\n4. **QA Spec (linked doc)**: if present, report `QA Doc: <path>`. Do not execute scenarios inline.\n\n### Step 5: Update Step File\n\n- Check off (`- [x]`) Automated Verification + Automated QA items that passed.\n- Do NOT check off Manual Verification items.\n- Update frontmatter `status` per \"Concurrency: Atomic Claim\" terminal-transition rules.\n- Update `last_updated` / `last_updated_by` frontmatter fields if present.\n\n### Step 6: Report Results\n\n**Completed:**\n```\nStatus: completed\nStep: step-N - <Name>\nFinal frontmatter status: done\nFiles changed: [list]\nAutomated Verification: N/M passed\n- [x] [Check 1] — passed\nAutomated QA: N/M passed\n- [x] [Scenario 1] — passed\nQA Doc: <path> | n/a\nManual verification needed:\n- [ ] [Manual check 1]\n```\n\n**Blocked / failed:** mirror `phase-running`'s shape, plus a `Final frontmatter status:` line so the orchestrator knows whether the step is released for retry (`ready`) or held for investigation (`claimed`).\n\n## Atomicity Contract\n\n- No interactive questions.\n- No partial states left unexplained.\n- Frontmatter `status` always reflects the final state at exit.\n- Report includes enough detail for the caller to decide next steps.\n\n## Context Handoff Pattern\n\n| Direction | Data |\n|-----------|------|\n| **Caller → Step Agent** | Step path + plan dir + agent ID + autonomy mode |\n| **Step Agent reads** | Step file + root.md + files in Changes Required |\n| **Step Agent writes** | Frontmatter status transitions + checkboxes + code changes |\n| **Step Agent → Caller** | Status + changed files + verification results + final frontmatter status |\n| **Caller handles** | Manual verification, cross-step coordination, QA doc execution, human checkpoints |\n";
|
|
10167
10424
|
|
|
10168
10425
|
// templates/skills/swarm-scripts/config.json
|
|
10169
|
-
var
|
|
10426
|
+
var config_default40 = `{
|
|
10170
10427
|
"kind": "skill",
|
|
10171
10428
|
"name": "swarm-scripts",
|
|
10172
10429
|
"displayName": "Swarm Scripts",
|
|
@@ -10183,7 +10440,7 @@ var config_default39 = `{
|
|
|
10183
10440
|
`;
|
|
10184
10441
|
|
|
10185
10442
|
// templates/skills/swarm-scripts/content.md
|
|
10186
|
-
var
|
|
10443
|
+
var content_default40 = `# Swarm Scripts
|
|
10187
10444
|
|
|
10188
10445
|
A swarm script is TypeScript that runs out of process with a typed Swarm SDK. Only its return value enters your context. Use one when direct tool calls would repeat, flood your context, or need deterministic processing over many records.
|
|
10189
10446
|
|
|
@@ -10338,7 +10595,7 @@ A named script can serve \`POST /api/x/script/<id>\` for callers outside the swa
|
|
|
10338
10595
|
`;
|
|
10339
10596
|
|
|
10340
10597
|
// templates/skills/tackle-gh-comments/config.json
|
|
10341
|
-
var
|
|
10598
|
+
var config_default41 = `{
|
|
10342
10599
|
"category": "skills",
|
|
10343
10600
|
"description": "Work through every review comment on a GitHub PR — fetch the threads, verify each claim against the code, fix what is real, then reply and mark each thread resolved before pushing. Use when the user says \\"tackle the PR comments\\", \\"address the review\\", \\"handle the bot comments\\", \\"check the comments on the PR\\", \\"resolve the review threads\\", or invokes /tackle-gh-comments. Project-agnostic; works in any repo with a GitHub remote.",
|
|
10344
10601
|
"displayName": "Tackle GH Comments",
|
|
@@ -10359,7 +10616,7 @@ var config_default40 = `{
|
|
|
10359
10616
|
`;
|
|
10360
10617
|
|
|
10361
10618
|
// templates/skills/tackle-gh-comments/content.md
|
|
10362
|
-
var
|
|
10619
|
+
var content_default41 = `# Tackle GitHub PR comments
|
|
10363
10620
|
|
|
10364
10621
|
Review threads and their resolved state live **only in GraphQL**. The REST API
|
|
10365
10622
|
cannot read \`isResolved\` and cannot resolve a thread, and \`gh pr view --comments\`
|
|
@@ -10478,7 +10735,7 @@ committed, and the branch is pushed.
|
|
|
10478
10735
|
`;
|
|
10479
10736
|
|
|
10480
10737
|
// templates/skills/taste-minimalist-skill/config.json
|
|
10481
|
-
var
|
|
10738
|
+
var config_default42 = `{
|
|
10482
10739
|
"kind": "skill",
|
|
10483
10740
|
"name": "taste-minimalist-skill",
|
|
10484
10741
|
"displayName": "Taste Minimalist Skill",
|
|
@@ -10500,7 +10757,7 @@ var config_default41 = `{
|
|
|
10500
10757
|
`;
|
|
10501
10758
|
|
|
10502
10759
|
// templates/skills/taste-minimalist-skill/content.md
|
|
10503
|
-
var
|
|
10760
|
+
var content_default42 = `> Vendored from [taste-skill](https://github.com/Leonxlnx/taste-skill) / [tasteskill.dev](https://www.tasteskill.dev/) at commit 06d6028b5c623016c59ce8536f578e5a1127b499.
|
|
10504
10761
|
> Upstream license: MIT, Copyright (c) 2026 Leonxlnx. See ../TASTE-SKILL-LICENSE.
|
|
10505
10762
|
|
|
10506
10763
|
# Protocol: Premium Utilitarian Minimalism UI Architect
|
|
@@ -10586,7 +10843,7 @@ When tasked with writing frontend code (HTML, React, Tailwind, Vue) or designing
|
|
|
10586
10843
|
`;
|
|
10587
10844
|
|
|
10588
10845
|
// templates/skills/tdd-planning/config.json
|
|
10589
|
-
var
|
|
10846
|
+
var config_default43 = `{
|
|
10590
10847
|
"category": "skills",
|
|
10591
10848
|
"description": "TDD-focused implementation planning. Creates plans with strict Red-Green-Commit/Rollback cycles for each step.",
|
|
10592
10849
|
"displayName": "TDD Planning",
|
|
@@ -10607,7 +10864,7 @@ var config_default42 = `{
|
|
|
10607
10864
|
`;
|
|
10608
10865
|
|
|
10609
10866
|
// templates/skills/tdd-planning/content.md
|
|
10610
|
-
var
|
|
10867
|
+
var content_default43 = `# TDD Planning
|
|
10611
10868
|
|
|
10612
10869
|
You are creating implementation plans that follow a strict Test-Driven Development approach. Every implementation step follows the TDD cycle: **RED → GREEN → COMMIT/ROLLBACK**.
|
|
10613
10870
|
|
|
@@ -10869,7 +11126,7 @@ Before finalizing any TDD plan, verify:
|
|
|
10869
11126
|
`;
|
|
10870
11127
|
|
|
10871
11128
|
// templates/skills/v-implementing/config.json
|
|
10872
|
-
var
|
|
11129
|
+
var config_default44 = `{
|
|
10873
11130
|
"category": "skills",
|
|
10874
11131
|
"description": "Parallel DAG-plan implementation skill. Reads a v-planning plan directory (root.md + step-<n>.md files), topologically schedules ready steps, and fans them out as parallel sub-agents. Use whenever the user invokes /v-implement, points at a plan directory produced by /v-plan, or asks to \\"run the parallel plan\\", \\"implement the DAG\\", or \\"fan out the steps\\" — even without those exact words. For linear plans (single .md file), use \`implementing\` instead.",
|
|
10875
11132
|
"displayName": "V-Implementing",
|
|
@@ -10890,10 +11147,10 @@ var config_default43 = `{
|
|
|
10890
11147
|
`;
|
|
10891
11148
|
|
|
10892
11149
|
// templates/skills/v-implementing/content.md
|
|
10893
|
-
var content_default43 = "# v-implementing\n\nYou are implementing an approved DAG-structured plan produced by `v-planning`. The plan is a directory with `root.md` + one `step-<n>.md` per node. Your job is to act as a **topological scheduler**: at each tick, find steps whose dependencies are all done, fan them out as parallel sub-agents (one per ready step), wait, repeat — until the DAG is drained. Then run Global Verification.\n\nThis is the parallel sibling of `implementing`. The orchestration model is the same (sub-agents do the work, main session coordinates), only the scheduler is different.\n\n## Working Agreement\n\n**All user-facing questions go through `AskUserQuestion`** — see `desplega:ask-user` for conventions. Never ask in chat as plain bullets.\n\n**All read/research/validation work goes through sub-agents** — keep raw tool output out of the main session. Default to `run_in_background: true`. The fan-out scheduler below is built on this.\n\nThe autonomy mode (below) controls how often you check in. AskUserQuestion is always the mechanism.\n\nFile-review is on by default — when significant changes land in a step (or wave), invoke `/file-review:file-review <path>` for inline feedback (skip only if Autopilot).\n\n## Autonomy Mode\n\n| Mode | Behavior |\n|------|----------|\n| **Autopilot** | Drain the DAG without pausing. Only stop on blocker / failed step. |\n| **Critical** (Default) | Pause when each *wave* of parallel steps completes; wait for manual verification before unlocking the next wave. |\n| **Verbose** | Pause after each individual step (even within a wave). |\n\n## Initial Setup Questions\n\nAfter understanding the plan and before the scheduler loop starts, gather implementation-specific details (skip in Autopilot):\n\n### 1. Branch / Worktree Setup\n\nCheck the current branch: `git branch --show-current`. Then check if the `wts` plugin is installed (look for `wts:wts` in available skills).\n\n**If wts is installed**, use **AskUserQuestion**:\n\n| Question | Options |\n|----------|---------|\n| \"You're on `<current-branch>`. Where would you like to implement?\" | 1. Continue on current branch, 2. Create a new branch, 3. Create a wts worktree |\n\n**If wts is not installed**, drop the worktree option.\n\n### 2. Commit Strategy\n\nUse **AskUserQuestion**:\n\n| Question | Options |\n|----------|---------|\n| \"How would you like to handle commits during parallel implementation?\" | 1. Commit after each step completes (Recommended), 2. Commit at the end (single commit), 3. Let me decide as I go |\n\nIf \"Commit after each step\" is selected, after a step's manual verification passes, create a commit: `[step-N] <step name>`.\n\n### 3. Orchestration Mode (only if the `Workflow` tool is available)\n\n| Question | Options |\n|----------|---------|\n| \"Run the DAG waves as Workflow scripts? (deterministic scheduling, parallel steps as agent() calls)\" | 1. Yes — Workflow waves, 2. No — Agent fan-out (Default) |\n\nA \"yes\" is the explicit opt-in the Workflow tool requires. If opted in, each wave of the scheduler loop below runs as one Workflow script — a `parallel()` of `agent()` calls, one per ready step, with `model`/`effort` per `desplega:delegate-work`. Everything else is unchanged: step agents still follow the `step-running` contract (atomic frontmatter claim, three-bucket verification), and autonomy-mode pause points sit **between** Workflow invocations, never inside one. In Autopilot these questions are skipped, so there is no opt-in — use Agent fan-out unless the user pre-authorized workflows.\n\n### 4. Code Review Mode\n\n| Question | Options |\n|----------|---------|\n| \"Run an automatic code review after each wave?\" | 1. Automatic two-axis review per wave (Recommended), 2. Only at the end (single review after the DAG drains), 3. Off — I'll review myself |\n\nIn **Autopilot**, skip the question and default to automatic per-wave review.\n\n## Getting Started\n\nGiven a plan directory path:\n\n1. **Read `root.md` fully** (no `limit`/`offset`). Capture: Overview, Current State, Desired End State, Implementation Approach, Global Verification.\n2. **Read every `step-<n>.md`'s frontmatter** to build the dependency graph (`id`, `depends_on`). You don't need to read step bodies up front — the sub-agents will do that.\n3. **Validate the DAG:**\n - No cycles\n - Every `depends_on` ID exists as a step file\n - At least one step has `depends_on: []` (otherwise nothing can start)\n4. **Set `root.md` frontmatter `status: in-progress`.**\n5. **Build a TodoWrite list** with one entry per step, marked `pending`.\n6. **Resume support:** if any step's body has `- [x]` boxes already (or its frontmatter says `status: completed` if the user added it), trust them and treat that step as `done`.\n\nIf no path given, ask via AskUserQuestion.\n\n## The Scheduler Loop\n\nThe scheduler reads each step's frontmatter `status` (`ready` | `claimed` | `done`) and `depends_on`. The frontmatter `status` field is the **single source of truth** — multiple orchestrator instances on the same plan dir coordinate through it (each `desplega:step-running` sub-agent atomically claims its step before doing work).\n\n```\nwhile any step has status != done:\n ready = [step for step in steps\n if step.status == \"ready\"\n and all(dep.status == \"done\" for dep in step.depends_on)]\n if not ready:\n # DAG drained, OR every remaining undone step is claimed by another worker\n if any step has status == claimed: wait for in-flight claims to resolve\n else: report stuck (likely cycle or unrecoverable failure)\n continue\n fan out each step in `ready` as a parallel `desplega:step-running` sub-agent\n wait for the wave to complete\n review reports; step-running has already updated frontmatter\n (status: done on success, status: ready on retry-able failure, status: claimed if held for investigation)\n if Critical mode: pause for manual verification of newly-completed steps\n if any failed: stop and ask user how to proceed\n```\n\n### Spawning a Step Sub-agent\n\nUse the `Agent` tool with `run_in_background: true`, invoking `desplega:step-running`. Pass:\n\n- **Step path**: full path to `step-<n>.md`\n- **Plan dir**: full path to the parent plan directory\n- **Agent ID**: unique ID for this sub-agent (e.g. orchestrator session ID + step ID + timestamp). step-running uses this for atomic claim + stale-claim detection.\n- **Plan-level context** (optional): a quick brief from `root.md`. step-running re-reads `root.md` itself, so this is just to reduce round-trips.\n\n`step-running` owns:\n- Atomic claim (rewrite frontmatter `status: ready` → `status: claimed, assignee: <agent-id>, claimed_at: <ts>`)\n- Three-bucket verification (Automated Verification, Automated QA, QA Doc identification)\n- Terminal status transition (`status: done` on success, `status: ready` on retry-able failure)\n- Reporting back\n\nThe orchestrator does NOT do step work itself — it delegates. See `desplega:step-running` for the full sub-agent contract.\n\n**Executor routing**: if the `desplega:delegate-work` skill is available, pick each step's executor per its routing matrix instead of defaulting to a `step-running` sub-agent — a step may route to a Codex variant (one worktree per parallel slice) or a specific Claude model tier. Only the executor choice changes; the scheduler, frontmatter claim protocol, and all other semantics here stay unchanged. When a step routes to Codex, the orchestrator owns the frontmatter bookkeeping that `step-running` would normally do (Codex must not edit plan files).\n\n### Wave Completion\n\nWhen a wave finishes:\n1. **Review each agent's report.** Mark steps `done` only if `completed` was reported.\n2. **Run the wave code review** (unless review mode is Off) — invoke `desplega:code-reviewing` on the wave's combined diff: Standards + Spec axes as parallel background sub-agents (routed per `desplega:delegate-work`), spec source = the completed steps' bodies and Success Criteria. Critical findings block those steps' commits — fix and re-verify first. If \"Only at the end\" was selected, run one review over the full diff after the DAG drains instead.\n3. **Handle `QA Doc: <path>`** — for each step that reported a QA doc, invoke `desplega:qa` against that path. The Automated QA bucket inside the step is already handled by the sub-agent; only the linked doc needs separate orchestration here. (`QA: n/a` → proceed normally.)\n4. **Manual verification (if not Autopilot)** — present manual verification items from each completed step's body. Wait for user confirmation. Don't tick manual boxes until confirmed.\n5. **Commits (if commit-per-step was selected)** — after a step's manual verification passes, create a commit: `[step-N] <step name>`.\n6. **Loop** — recompute `ready` and start the next wave.\n\n## Handling Failures and Mismatches\n\nIf a sub-agent reports `failed` or `blocked`, or you spot a mismatch between plan and reality:\n\n| Question | Options |\n|----------|---------|\n| \"[step-N] [issue]. How should I proceed?\" | 1. Adapt step (edit step-N.md and retry), 2. Retry as-is, 3. Skip and continue (mark step blocked), 4. Stop the run |\n\nIn Autopilot mode, use best judgment, document the decision in the step file, and continue if non-fatal.\n\n## After the DAG Drains\n\nWhen every step is `done`:\n\n1. Run **Global Verification** from `root.md`. Tick automated checks; surface manual checks to the user.\n2. Set `root.md` frontmatter `status: completed`.\n3. Offer post-implementation auditing: \"Would you like me to run `/verify-plan` and `/review` on the plan directory?\"\n4. If commit-per-step was off, offer to create a single bundled commit now.\n5. If the work ships as a GitHub PR: once review comments land, address them with `desplega:tackle-gh-comments` (fetch threads, verify each claim, fix, reply, resolve — push last).\n\n## Important Guidelines\n\n1. **One step = one sub-agent.** Don't bundle steps into a single agent even if they're in the same wave — fan-out is the whole point.\n2. **Plan-level context goes to every sub-agent.** Sibling step bodies do not.\n3. **The DAG is canonical via step frontmatter** — if `root.md`'s table is out of sync, trust the frontmatter.\n4. **Resume works step-granular.** If the user re-runs `/v-implement` mid-DAG, completed steps stay completed; only undone ones rerun.\n5. **Don't tick manual checkboxes** until the user confirms — automated boxes can be ticked by the sub-agent or the orchestrator.\n\n## Review Integration\n\nIf `file-review` is available and the user opted in:\n- After each step's significant code changes, invoke `/file-review:file-review <changed-file>`.\n- Process feedback with `file-review:process-review` before treating the step as done.\n- Skip in Autopilot.\n";
|
|
11150
|
+
var content_default44 = "# v-implementing\n\nYou are implementing an approved DAG-structured plan produced by `v-planning`. The plan is a directory with `root.md` + one `step-<n>.md` per node. Your job is to act as a **topological scheduler**: at each tick, find steps whose dependencies are all done, fan them out as parallel sub-agents (one per ready step), wait, repeat — until the DAG is drained. Then run Global Verification.\n\nThis is the parallel sibling of `implementing`. The orchestration model is the same (sub-agents do the work, main session coordinates), only the scheduler is different.\n\n## Working Agreement\n\n**All user-facing questions go through `AskUserQuestion`** — see `desplega:ask-user` for conventions. Never ask in chat as plain bullets.\n\n**All read/research/validation work goes through sub-agents** — keep raw tool output out of the main session. Default to `run_in_background: true`. The fan-out scheduler below is built on this.\n\nThe autonomy mode (below) controls how often you check in. AskUserQuestion is always the mechanism.\n\nFile-review is on by default — when significant changes land in a step (or wave), invoke `/file-review:file-review <path>` for inline feedback (skip only if Autopilot).\n\n## Autonomy Mode\n\n| Mode | Behavior |\n|------|----------|\n| **Autopilot** | Drain the DAG without pausing. Only stop on blocker / failed step. |\n| **Critical** (Default) | Pause when each *wave* of parallel steps completes; wait for manual verification before unlocking the next wave. |\n| **Verbose** | Pause after each individual step (even within a wave). |\n\n## Initial Setup Questions\n\nAfter understanding the plan and before the scheduler loop starts, gather implementation-specific details (skip in Autopilot):\n\n### 1. Branch / Worktree Setup\n\nCheck the current branch: `git branch --show-current`. Then check if the `wts` plugin is installed (look for `wts:wts` in available skills).\n\n**If wts is installed**, use **AskUserQuestion**:\n\n| Question | Options |\n|----------|---------|\n| \"You're on `<current-branch>`. Where would you like to implement?\" | 1. Continue on current branch, 2. Create a new branch, 3. Create a wts worktree |\n\n**If wts is not installed**, drop the worktree option.\n\n### 2. Commit Strategy\n\nUse **AskUserQuestion**:\n\n| Question | Options |\n|----------|---------|\n| \"How would you like to handle commits during parallel implementation?\" | 1. Commit after each step completes (Recommended), 2. Commit at the end (single commit), 3. Let me decide as I go |\n\nIf \"Commit after each step\" is selected, after a step's manual verification passes, create a commit: `[step-N] <step name>`.\n\n### 3. Orchestration Mode (only if the `Workflow` tool is available)\n\n| Question | Options |\n|----------|---------|\n| \"Run the DAG waves as Workflow scripts? (deterministic scheduling, parallel steps as agent() calls)\" | 1. Yes — Workflow waves, 2. No — Agent fan-out (Default) |\n\nA \"yes\" is the explicit opt-in the Workflow tool requires. If opted in, each wave of the scheduler loop below runs as one Workflow script — a `parallel()` of `agent()` calls, one per ready step, with `model`/`effort` per `desplega:delegate-work`. Everything else is unchanged: step agents still follow the `step-running` contract (atomic frontmatter claim, three-bucket verification), and autonomy-mode pause points sit **between** Workflow invocations, never inside one. In Autopilot these questions are skipped, so there is no opt-in — use Agent fan-out unless the user pre-authorized workflows.\n\n### 4. Code Review Mode\n\n| Question | Options |\n|----------|---------|\n| \"Run an automatic code review after each wave?\" | 1. Automatic two-axis review per wave (Recommended), 2. Only at the end (single review after the DAG drains), 3. Off — I'll review myself |\n\nIn **Autopilot**, skip the question and default to automatic per-wave review.\n\n## Getting Started\n\nGiven a plan directory path:\n\n1. **Read `root.md` fully** (no `limit`/`offset`). Capture: Overview, Current State, Desired End State, Implementation Approach, Global Verification.\n2. **Read every `step-<n>.md`'s frontmatter** to build the dependency graph (`id`, `depends_on`). You don't need to read step bodies up front — the sub-agents will do that.\n3. **Validate the DAG:**\n - No cycles\n - Every `depends_on` ID exists as a step file\n - At least one step has `depends_on: []` (otherwise nothing can start)\n4. **Set `root.md` frontmatter `status: in-progress`.**\n5. **Build a TodoWrite list** with one entry per step, marked `pending`.\n6. **Resume support:** if any step's body has `- [x]` boxes already (or its frontmatter says `status: completed` if the user added it), trust them and treat that step as `done`.\n\nIf no path given, ask via AskUserQuestion.\n\n## The Scheduler Loop\n\nThe scheduler reads each step's frontmatter `status` (`ready` | `claimed` | `done`) and `depends_on`. The frontmatter `status` field is the **single source of truth** — multiple orchestrator instances on the same plan dir coordinate through it (each `desplega:step-running` sub-agent atomically claims its step before doing work).\n\n```\nwhile any step has status != done:\n ready = [step for step in steps\n if step.status == \"ready\"\n and all(dep.status == \"done\" for dep in step.depends_on)]\n if not ready:\n # DAG drained, OR every remaining undone step is claimed by another worker\n if any step has status == claimed: wait for in-flight claims to resolve\n else: report stuck (likely cycle or unrecoverable failure)\n continue\n fan out each step in `ready` as a parallel `desplega:step-running` sub-agent\n wait for the wave to complete\n review reports; step-running has already updated frontmatter\n (status: done on success, status: ready on retry-able failure, status: claimed if held for investigation)\n if Critical mode: pause for manual verification of newly-completed steps\n if any failed: stop and ask user how to proceed\n```\n\n### Spawning a Step Sub-agent\n\nUse the `Agent` tool with `run_in_background: true`, invoking `desplega:step-running`. Pass:\n\n- **Step path**: full path to `step-<n>.md`\n- **Plan dir**: full path to the parent plan directory\n- **Agent ID**: unique ID for this sub-agent (e.g. orchestrator session ID + step ID + timestamp). step-running uses this for atomic claim + stale-claim detection.\n- **Plan-level context** (optional): a quick brief from `root.md`. step-running re-reads `root.md` itself, so this is just to reduce round-trips.\n\n`step-running` owns:\n- Atomic claim (rewrite frontmatter `status: ready` → `status: claimed, assignee: <agent-id>, claimed_at: <ts>`)\n- Three-bucket verification (Automated Verification, Automated QA, QA Doc identification)\n- Terminal status transition (`status: done` on success, `status: ready` on retry-able failure)\n- Reporting back\n\nThe orchestrator does NOT do step work itself — it delegates. See `desplega:step-running` for the full sub-agent contract.\n\n**Executor routing**: if the `desplega:delegate-work` skill is available, pick each step's executor per its routing matrix instead of defaulting to a `step-running` sub-agent — a step may route to a Codex variant (one worktree per parallel slice) or a specific Claude model tier. Only the executor choice changes; the scheduler, frontmatter claim protocol, and all other semantics here stay unchanged. When a step routes to Codex, the orchestrator owns the frontmatter bookkeeping that `step-running` would normally do (Codex must not edit plan files).\n\n### Wave Completion\n\nWhen a wave finishes:\n1. **Review each agent's report.** Mark steps `done` only if `completed` was reported.\n2. **Run the wave code review** (unless review mode is Off) — invoke `desplega:code-reviewing` on the wave's combined diff: Standards + Spec axes as parallel background sub-agents (routed per `desplega:delegate-work`), spec source = the completed steps' bodies and Success Criteria. Critical findings block those steps' commits — fix and re-verify first. If \"Only at the end\" was selected, run one review over the full diff after the DAG drains instead.\n3. **Handle `QA Doc: <path>`** — for each step that reported a QA doc, invoke `desplega:qa` against that path. The Automated QA bucket inside the step is already handled by the sub-agent; only the linked doc needs separate orchestration here. (`QA: n/a` → proceed normally.)\n4. **Manual verification (if not Autopilot)** — present manual verification items from each completed step's body. Wait for user confirmation. Don't tick manual boxes until confirmed.\n5. **Commits (if commit-per-step was selected)** — after a step's manual verification passes, create a commit: `[step-N] <step name>`.\n6. **Loop** — recompute `ready` and start the next wave.\n\n## Handling Failures and Mismatches\n\nIf a sub-agent reports `failed` or `blocked`, or you spot a mismatch between plan and reality:\n\n| Question | Options |\n|----------|---------|\n| \"[step-N] [issue]. How should I proceed?\" | 1. Adapt step (edit step-N.md and retry), 2. Retry as-is, 3. Skip and continue (mark step blocked), 4. Stop the run |\n\nIn Autopilot mode, use best judgment, document the decision in the step file, and continue if non-fatal.\n\n## After the DAG Drains\n\nWhen every step is `done`:\n\n1. Run **Global Verification** from `root.md`. Tick automated checks; surface manual checks to the user.\n2. Set `root.md` frontmatter `status: completed`.\n3. Offer post-implementation auditing: \"Would you like me to run `/verify-plan` and `/review` on the plan directory?\"\n4. If commit-per-step was off, offer to create a single bundled commit now.\n5. If the work ships as a GitHub PR: once review comments land, address them with `desplega:tackle-gh-comments` (fetch threads, verify each claim, fix, reply, resolve — push last).\n\n## Important Guidelines\n\n1. **One step = one sub-agent.** Don't bundle steps into a single agent even if they're in the same wave — fan-out is the whole point.\n2. **Plan-level context goes to every sub-agent.** Sibling step bodies do not.\n3. **The DAG is canonical via step frontmatter** — if `root.md`'s table is out of sync, trust the frontmatter.\n4. **Resume works step-granular.** If the user re-runs `/v-implement` mid-DAG, completed steps stay completed; only undone ones rerun.\n5. **Don't tick manual checkboxes** until the user confirms — automated boxes can be ticked by the sub-agent or the orchestrator.\n\n## Review Integration\n\nIf `file-review` is available and the user opted in:\n- After each step's significant code changes, invoke `/file-review:file-review <changed-file>`.\n- Process feedback with `file-review:process-review` before treating the step as done.\n- Skip in Autopilot.\n";
|
|
10894
11151
|
|
|
10895
11152
|
// templates/skills/v-planning/config.json
|
|
10896
|
-
var
|
|
11153
|
+
var config_default45 = `{
|
|
10897
11154
|
"category": "skills",
|
|
10898
11155
|
"description": "Vertical / parallel implementation planning skill. Creates DAG-structured plan directories where each step is an independent, QA-able vertical slice that sub-agents can pick up and implement in parallel. Use whenever the user wants a plan that fans out (multiple independent features), invokes /v-plan, or asks for a \\"parallel plan\\", \\"DAG plan\\", \\"vertical plan\\", or \\"plan that can be parallelized\\" — even if they don't say those exact words. Prefer the linear \`planning\` skill for strictly sequential work.",
|
|
10899
11156
|
"displayName": "V-Planning",
|
|
@@ -10914,7 +11171,7 @@ var config_default44 = `{
|
|
|
10914
11171
|
`;
|
|
10915
11172
|
|
|
10916
11173
|
// templates/skills/v-planning/content.md
|
|
10917
|
-
var
|
|
11174
|
+
var content_default45 = `# v-planning
|
|
10918
11175
|
|
|
10919
11176
|
You create implementation plans as a **DAG of vertical steps** — each step a complete, QA-able slice of value (DB + API + UI + tests for one feature). The DAG captures feature-level dependencies, so independent steps can be implemented in parallel by sub-agents.
|
|
10920
11177
|
|
|
@@ -11005,7 +11262,7 @@ Structure validation runs automatically (rule 9, Haiku sub-agent).
|
|
|
11005
11262
|
`;
|
|
11006
11263
|
|
|
11007
11264
|
// templates/skills/verifying/config.json
|
|
11008
|
-
var
|
|
11265
|
+
var config_default46 = `{
|
|
11009
11266
|
"category": "skills",
|
|
11010
11267
|
"description": "Post-implementation plan verification. Cross-references plans against actual changes for completeness and accuracy.",
|
|
11011
11268
|
"displayName": "Verifying",
|
|
@@ -11026,7 +11283,7 @@ var config_default45 = `{
|
|
|
11026
11283
|
`;
|
|
11027
11284
|
|
|
11028
11285
|
// templates/skills/verifying/content.md
|
|
11029
|
-
var
|
|
11286
|
+
var content_default46 = `# Verifying
|
|
11030
11287
|
|
|
11031
11288
|
You are performing a post-implementation audit of a plan, cross-referencing it against actual changes to ensure nothing was missed, nothing is stale, and the implementation matches what was planned.
|
|
11032
11289
|
|
|
@@ -11173,8 +11430,28 @@ File-review is on by default (unless Autopilot):
|
|
|
11173
11430
|
- Process feedback with the \`file-review:process-review\` skill
|
|
11174
11431
|
`;
|
|
11175
11432
|
|
|
11433
|
+
// templates/skills/work-on-task/config.json
|
|
11434
|
+
var config_default47 = `{
|
|
11435
|
+
"kind": "skill",
|
|
11436
|
+
"name": "work-on-task",
|
|
11437
|
+
"displayName": "Work On Task",
|
|
11438
|
+
"slug": "work-on-task",
|
|
11439
|
+
"title": "Work On Task",
|
|
11440
|
+
"description": "Turn prompt for an assigned swarm task: find the task, gather context when the message lacks it, use the skill the task names, finish with one of the four endings.",
|
|
11441
|
+
"version": "1.0.0",
|
|
11442
|
+
"category": "skills",
|
|
11443
|
+
"placeholders": [],
|
|
11444
|
+
"runAllSeedersCandidate": true,
|
|
11445
|
+
"systemDefault": true,
|
|
11446
|
+
"tags": ["tasks", "turn-prompt", "worker"]
|
|
11447
|
+
}
|
|
11448
|
+
`;
|
|
11449
|
+
|
|
11450
|
+
// templates/skills/work-on-task/content.md
|
|
11451
|
+
var content_default47 = "# Working on a task\n\nThe taskId follows the command. Without one, call `get-tasks` with `mineOnly: true` and take your `pending` or `in_progress` task. If there is none, say so and stop.\n\nThis message carries the task text, its attachments, its output format, and memories from past sessions. If it does not (you invoked this command yourself, or the context was compacted), run the `task-context-gathering` script with the taskId.\n\nWhen the task names a skill (`researching`, `planning`, `implementing`), use it. Otherwise work directly.\n\nFinish the task with one of the four endings in your operating contract: `completed`, `defer-task`, `request-human-input`, or `failed`. Then stop.\n\nIf the user interrupts, follow their instructions. To resume, call `/work-on-task <taskId>` again.\n";
|
|
11452
|
+
|
|
11176
11453
|
// templates/skills/workflow-iterate/config.json
|
|
11177
|
-
var
|
|
11454
|
+
var config_default48 = `{
|
|
11178
11455
|
"kind": "skill",
|
|
11179
11456
|
"name": "workflow-iterate",
|
|
11180
11457
|
"displayName": "Workflow Iteration",
|
|
@@ -11196,7 +11473,7 @@ var config_default46 = `{
|
|
|
11196
11473
|
`;
|
|
11197
11474
|
|
|
11198
11475
|
// templates/skills/workflow-iterate/content.md
|
|
11199
|
-
var
|
|
11476
|
+
var content_default48 = `# Workflow Iteration
|
|
11200
11477
|
|
|
11201
11478
|
Use this skill when you need to change an existing workflow without breaking live runs. The goal is to make small, verified revisions: inspect the current workflow, diagnose the failing step, patch only the required node or edge, trigger a realistic run, and keep iterating until the run reaches the intended terminal state.
|
|
11202
11479
|
|
|
@@ -11338,7 +11615,7 @@ Use these shapes as a starting point, then confirm them against the current exec
|
|
|
11338
11615
|
`;
|
|
11339
11616
|
|
|
11340
11617
|
// templates/skills/workflow-structured-output/config.json
|
|
11341
|
-
var
|
|
11618
|
+
var config_default49 = `{
|
|
11342
11619
|
"kind": "skill",
|
|
11343
11620
|
"name": "workflow-structured-output",
|
|
11344
11621
|
"displayName": "Workflow Structured Output",
|
|
@@ -11355,10 +11632,10 @@ var config_default47 = `{
|
|
|
11355
11632
|
`;
|
|
11356
11633
|
|
|
11357
11634
|
// templates/skills/workflow-structured-output/content.md
|
|
11358
|
-
var
|
|
11635
|
+
var content_default49 = '# Workflow Structured Output\n\n> **Companion skill — `workflow-iterate` (author-side).** This skill is for *workers* assigned a task spawned by an `agent-task` workflow node with an `outputSchema`. The author-side counterpart `workflow-iterate` covers how the workflow defines that schema, why gates downstream depend on it, and how to debug failed runs. If you ever need to understand *why* a particular schema is shaped the way it is — or you\'re switching from worker to author mode — read `workflow-iterate`.\n\n## Failure reason → fix (read this first)\n\nIf you see this failure reason on a task, the fix is always the same:\n\n| failureReason contains | What it means | Fix |\n|---|---|---|\n| `Task has an outputSchema but no output was provided` | You called `store-progress` without an `output` when the task required a JSON object matching `outputSchema` | Re-call `store-progress` with `status: "completed"` and `output` = a **stringified JSON** matching the schema exactly |\n| `Task output must be valid JSON` / `Task output does not match the outputSchema` | You passed invalid JSON, omitted required fields, or used the wrong types | Re-read the schema, include every `required` field with the exact key names, re-call `store-progress` |\n\n**You can re-call `store-progress` even after a rejection.** Your prior progress updates do not count as the final output. Fix the JSON and try again.\n\n## Pre-flight checklist (run through before calling store-progress)\n\n1. **Do the task details contain an actual `outputSchema`?** If yes, runtime\n enforcement is active: continue with that exact schema.\n2. **If there is no `outputSchema`, does the user provide an explicit JSON Output\n Format or interface?** Honor it as the requested output contract even though\n the runner is not enforcing an `outputSchema`.\n3. **Are workflow origin or tags such as `deterministic`, `litmus`, `validation`,\n or `context` the only signals?** They are heuristics only. Re-read the task\n details for an actual schema or explicit format. If neither exists, do not\n invent one; plain-text output is allowed.\n4. **Can I quote the exact required shape from the task details?** Use its exact\n keys and types, with every required field and no guessed renames.\n5. **Is my `output` a string (stringified JSON), not an object?** For a structured\n contract, `store-progress.output` should be a JSON string.\n6. **Only after the applicable contract is clear:** call `store-progress` with\n `status: "completed"` and the stringified JSON, or use plain text when no\n structured contract exists.\n\nIf the required shape is unclear, re-read the task details. Never synthesize a\nschema from tags or workflow origin.\n\n## Why this exists\n\nWhen a task has an actual `outputSchema`, the runner validates\n`store-progress.output` against it and rejects missing output, invalid JSON, or\nschema mismatches with one of the current messages listed above. A JSON Output\nFormat or interface without `task.outputSchema` remains a user instruction, but\nit is not the same runtime enforcement mechanism. Missing the distinction can\nturn completed work into a rejected terminal update, so check the task contract\nbefore reporting completion.\n\n## How to spot a structured-output task\n\nTreat these signals differently:\n\n- An actual `task.outputSchema` means JSON is runtime-enforced.\n- An explicit "Output Format", "Return a JSON object", or TypeScript/JSON\n interface is a user contract to return that shape, even without runtime\n enforcement.\n- Tags such as `deterministic`, `litmus`, `validation`, `releases`, or `context`,\n and `source = workflow`, only tell you to inspect the task details carefully.\n They do not prove a schema exists.\n\nWhen in doubt, re-read the task details and its `outputSchema`. Do not invent a\nschema or required fields.\n\n## How to complete correctly\n\n1. **Build the JSON object** that matches the actual `outputSchema` or explicit\n user-provided JSON format. Include every required field and use the exact key\n names from that contract.\n2. **Stringify it** — `store-progress.output` must be a string, not an object. Use `JSON.stringify(obj)` in your head.\n3. **Call store-progress** with `status: "completed"` and that JSON string as `output`.\n\n### Example — skip case\n\nTask has schema `{skip: bool, reason?: str, contextPath?: str, ...}` and you\'re skipping because the release already exists:\n\n```\nstore-progress(\n taskId,\n status="completed",\n output=\'{"skip":true,"reason":"Release already exists for this week"}\'\n)\n```\n\n### Example — full run\n\n```\nstore-progress(\n taskId,\n status="completed",\n output=\'{"skip":false,"contextPath":"release-runs/2026-04-20/context.json","commitCount":42,"repos":["example-repo"],"repoPatternsSource":"cache","dateRange":"2026-04-13 to 2026-04-20"}\'\n)\n```\n\n### Example — litmus / validation verdict\n\n```\nstore-progress(\n taskId,\n status="completed",\n output=\'{"verdict":"publish","reason":"5 user-facing changes; threshold met"}\'\n)\n```\n\n## Anti-patterns for an `outputSchema` task\n\n- `output: "Done. Context written to agent-fs at release-runs/2026-04-20/context.json"`\n- `output: "Published release notes for week of 2026-04-20"`\n- `output: "Verdict: publish"`\n- Calling `store-progress` with `status: "completed"` and no `output` at all\n- JSON that\'s missing any `required` field from the schema\n- JSON with extra keys instead of the schema\'s exact keys\n\n## Recovery if you realize mid-task\n\nIf you\'ve done all the work but forgot the JSON contract, just call `store-progress` again with the correct JSON string in `output`. Your prior progress updates don\'t count as the final output.\n\n## Verify before completing\n\nRead your task description once more. Find the schema. Build the JSON. Then complete. Takes 30 seconds. Saves a workflow re-run.\n\n## See also\n\n- **`workflow-iterate`** — the author-side counterpart of this skill. Read it if you\'re editing the workflow that produced this task, or want to understand why this particular schema is shaped the way it is (which gates downstream depend on it, etc.).\n';
|
|
11359
11636
|
|
|
11360
11637
|
// templates/skills/wts-expert/config.json
|
|
11361
|
-
var
|
|
11638
|
+
var config_default50 = `{
|
|
11362
11639
|
"category": "skills",
|
|
11363
11640
|
"description": "Git worktree management expert for @desplega.ai/wts. Use when the user asks about git worktrees, wts commands, worktree workflows, or wants help managing multiple branches simultaneously.",
|
|
11364
11641
|
"displayName": "WTS Expert",
|
|
@@ -11379,7 +11656,7 @@ var config_default48 = `{
|
|
|
11379
11656
|
`;
|
|
11380
11657
|
|
|
11381
11658
|
// templates/skills/wts-expert/content.md
|
|
11382
|
-
var
|
|
11659
|
+
var content_default50 = `# WTS Expert
|
|
11383
11660
|
|
|
11384
11661
|
You are an expert on \`@desplega.ai/wts\`, a CLI tool for managing Git worktrees with tmux integration, Claude Code launcher support, and GitHub PR creation.
|
|
11385
11662
|
|
|
@@ -13947,24 +14224,6 @@ wts cleanup --unmerged # Include unmerged worktrees
|
|
|
13947
14224
|
]
|
|
13948
14225
|
};
|
|
13949
14226
|
|
|
13950
|
-
// src/be/seed-skills/render.ts
|
|
13951
|
-
var YAML_IMPLICIT_NON_STRING = /^(?:~|null|true|false|yes|no|on|off|[-+]?(?:0b[01_]+|0o[0-7_]+|0x[0-9a-f_]+|[0-9][0-9_]*(?:\.[0-9_]*)?(?:e[-+]?[0-9]+)?|\.[0-9][0-9_]*(?:e[-+]?[0-9]+)?)|[-+]?\.(?:inf|nan)|[0-9]{4}-[0-9]{1,2}-[0-9]{1,2}(?:[t ].*)?)$/i;
|
|
13952
|
-
function yamlScalar(value) {
|
|
13953
|
-
const unsafe = value === "" || /(: )|(:$)|( #)|[\n\t]|^[\s\-?:,[\]{}#&*!|>'"%@`]|\s$/.test(value) || YAML_IMPLICIT_NON_STRING.test(value);
|
|
13954
|
-
return unsafe ? JSON.stringify(value) : value;
|
|
13955
|
-
}
|
|
13956
|
-
function buildSkillContent(config, body) {
|
|
13957
|
-
const userInvocable = config.userInvocable === false ? `
|
|
13958
|
-
user-invocable: false` : "";
|
|
13959
|
-
return `---
|
|
13960
|
-
name: ${config.name}
|
|
13961
|
-
description: ${yamlScalar(config.description)}${userInvocable}
|
|
13962
|
-
---
|
|
13963
|
-
|
|
13964
|
-
${body.trim()}
|
|
13965
|
-
`;
|
|
13966
|
-
}
|
|
13967
|
-
|
|
13968
14227
|
// src/be/seed-skills/index.ts
|
|
13969
14228
|
var BUILT_IN_SKILL_FILES = bundled_files_generated_default;
|
|
13970
14229
|
var BUILT_IN_SKILL_SOURCES = [
|
|
@@ -14015,7 +14274,9 @@ var BUILT_IN_SKILL_SOURCES = [
|
|
|
14015
14274
|
{ config: config_default45, body: content_default45 },
|
|
14016
14275
|
{ config: config_default46, body: content_default46 },
|
|
14017
14276
|
{ config: config_default47, body: content_default47 },
|
|
14018
|
-
{ config: config_default48, body: content_default48 }
|
|
14277
|
+
{ config: config_default48, body: content_default48 },
|
|
14278
|
+
{ config: config_default49, body: content_default49 },
|
|
14279
|
+
{ config: config_default50, body: content_default50 }
|
|
14019
14280
|
];
|
|
14020
14281
|
function canonicalFiles(files) {
|
|
14021
14282
|
return [...files].sort((a, b) => a.path.localeCompare(b.path)).map((file) => `${file.path}
|
|
@@ -14233,7 +14494,7 @@ async function runSeeders(seeders, opts) {
|
|
|
14233
14494
|
var import_cron_parser = __toESM(require_dist(), 1);
|
|
14234
14495
|
|
|
14235
14496
|
// templates/schedules/daily-blocker-digest/config.json
|
|
14236
|
-
var
|
|
14497
|
+
var config_default51 = `{
|
|
14237
14498
|
"kind": "schedule",
|
|
14238
14499
|
"name": "daily-blocker-digest",
|
|
14239
14500
|
"displayName": "Daily Blocker Digest",
|
|
@@ -14250,7 +14511,7 @@ var config_default49 = `{
|
|
|
14250
14511
|
`;
|
|
14251
14512
|
|
|
14252
14513
|
// templates/schedules/daily-blocker-digest/content.md
|
|
14253
|
-
var
|
|
14514
|
+
var content_default51 = `# Daily Blocker Digest
|
|
14254
14515
|
|
|
14255
14516
|
Delivery uses configured admin channels with an in-app fallback.
|
|
14256
14517
|
|
|
@@ -14420,7 +14681,7 @@ Call \`store-progress\` with status \`completed\` and an output paragraph coveri
|
|
|
14420
14681
|
`;
|
|
14421
14682
|
|
|
14422
14683
|
// templates/schedules/daily-compounding-reflection/config.json
|
|
14423
|
-
var
|
|
14684
|
+
var config_default52 = `{
|
|
14424
14685
|
"kind": "schedule",
|
|
14425
14686
|
"name": "daily-compounding-reflection",
|
|
14426
14687
|
"displayName": "Daily Evolution",
|
|
@@ -14442,7 +14703,7 @@ var config_default50 = `{
|
|
|
14442
14703
|
`;
|
|
14443
14704
|
|
|
14444
14705
|
// templates/schedules/daily-compounding-reflection/content.md
|
|
14445
|
-
var
|
|
14706
|
+
var content_default52 = `# Daily Compounding Reflection
|
|
14446
14707
|
|
|
14447
14708
|
Delivery uses configured admin channels with an in-app fallback.
|
|
14448
14709
|
|
|
@@ -14667,7 +14928,7 @@ If you have zero changes across all three folds and zero deferred items, somethi
|
|
|
14667
14928
|
`;
|
|
14668
14929
|
|
|
14669
14930
|
// templates/schedules/daily-status-report/config.json
|
|
14670
|
-
var
|
|
14931
|
+
var config_default53 = `{
|
|
14671
14932
|
"kind": "schedule",
|
|
14672
14933
|
"name": "daily-status-report",
|
|
14673
14934
|
"displayName": "Daily Status Report",
|
|
@@ -14684,7 +14945,7 @@ var config_default51 = `{
|
|
|
14684
14945
|
`;
|
|
14685
14946
|
|
|
14686
14947
|
// templates/schedules/daily-status-report/content.md
|
|
14687
|
-
var
|
|
14948
|
+
var content_default53 = `# Daily Status Report
|
|
14688
14949
|
|
|
14689
14950
|
Give the operator one daily read on whether the swarm is healthy: what's running, what's failed, what's waiting on them.
|
|
14690
14951
|
|
|
@@ -14767,7 +15028,7 @@ Integration setup: [missing credentials from /status], or all verified.
|
|
|
14767
15028
|
`;
|
|
14768
15029
|
|
|
14769
15030
|
// templates/schedules/daily-workflow-health-audit/config.json
|
|
14770
|
-
var
|
|
15031
|
+
var config_default54 = `{
|
|
14771
15032
|
"kind": "schedule",
|
|
14772
15033
|
"name": "daily-workflow-health-audit",
|
|
14773
15034
|
"displayName": "Daily Workflow Health Audit",
|
|
@@ -14784,7 +15045,7 @@ var config_default52 = `{
|
|
|
14784
15045
|
`;
|
|
14785
15046
|
|
|
14786
15047
|
// templates/schedules/daily-workflow-health-audit/content.md
|
|
14787
|
-
var
|
|
15048
|
+
var content_default54 = `# Daily Workflow Health Audit
|
|
14788
15049
|
|
|
14789
15050
|
Delivery uses configured admin channels with an in-app fallback.
|
|
14790
15051
|
|
|
@@ -14978,7 +15239,7 @@ Omit any section whose count is 0. Cap message at 4000 chars (Slack limit) — i
|
|
|
14978
15239
|
`;
|
|
14979
15240
|
|
|
14980
15241
|
// templates/schedules/gtm-weekly-review/config.json
|
|
14981
|
-
var
|
|
15242
|
+
var config_default55 = `{
|
|
14982
15243
|
"kind": "schedule",
|
|
14983
15244
|
"name": "gtm-weekly-review",
|
|
14984
15245
|
"displayName": "Weekly GTM Metrics Review",
|
|
@@ -14995,7 +15256,7 @@ var config_default53 = `{
|
|
|
14995
15256
|
`;
|
|
14996
15257
|
|
|
14997
15258
|
// templates/schedules/gtm-weekly-review/content.md
|
|
14998
|
-
var
|
|
15259
|
+
var content_default55 = `Template parameters: {{REPO_URL}}, {{GSC_PROPERTY}}
|
|
14999
15260
|
|
|
15000
15261
|
# Weekly GTM Metrics Review
|
|
15001
15262
|
|
|
@@ -15076,7 +15337,7 @@ This is part of your team's GTM goal; update the goal statement before enabling
|
|
|
15076
15337
|
`;
|
|
15077
15338
|
|
|
15078
15339
|
// templates/schedules/weekly-code-health-reports/config.json
|
|
15079
|
-
var
|
|
15340
|
+
var config_default56 = `{
|
|
15080
15341
|
"kind": "schedule",
|
|
15081
15342
|
"name": "weekly-code-health-reports",
|
|
15082
15343
|
"displayName": "Weekly Code Health Reports",
|
|
@@ -15093,7 +15354,7 @@ var config_default54 = `{
|
|
|
15093
15354
|
`;
|
|
15094
15355
|
|
|
15095
15356
|
// templates/schedules/weekly-code-health-reports/content.md
|
|
15096
|
-
var
|
|
15357
|
+
var content_default56 = `# Weekly Code Health Reports
|
|
15097
15358
|
|
|
15098
15359
|
Template parameters: {{REPO_URL}}, {{BRANCH}}, {{SCOPE_PATH}}, {{REPORT_NAME}}, {{PAGE_ID}}
|
|
15099
15360
|
|
|
@@ -15158,7 +15419,7 @@ Call \`store-progress\` with status \`completed\` and an output summary that inc
|
|
|
15158
15419
|
`;
|
|
15159
15420
|
|
|
15160
15421
|
// templates/schedules/weekly-dependabot-triage/config.json
|
|
15161
|
-
var
|
|
15422
|
+
var config_default57 = `{
|
|
15162
15423
|
"kind": "schedule",
|
|
15163
15424
|
"name": "weekly-dependabot-triage",
|
|
15164
15425
|
"displayName": "Weekly Dependency Triage",
|
|
@@ -15175,7 +15436,7 @@ var config_default55 = `{
|
|
|
15175
15436
|
`;
|
|
15176
15437
|
|
|
15177
15438
|
// templates/schedules/weekly-dependabot-triage/content.md
|
|
15178
|
-
var
|
|
15439
|
+
var content_default57 = `# Weekly Dependency Triage
|
|
15179
15440
|
|
|
15180
15441
|
Template parameters: {{SLACK_CHANNEL_ID}}, {{REPO_URL}}, {{TIMEZONE}}
|
|
15181
15442
|
|
|
@@ -15229,7 +15490,7 @@ Call \`store-progress\` with status \`completed\` and an output summary listing
|
|
|
15229
15490
|
`;
|
|
15230
15491
|
|
|
15231
15492
|
// templates/schedules/weekly-dora-metrics/config.json
|
|
15232
|
-
var
|
|
15493
|
+
var config_default58 = `{
|
|
15233
15494
|
"kind": "schedule",
|
|
15234
15495
|
"name": "weekly-dora-metrics",
|
|
15235
15496
|
"displayName": "Weekly DORA Metrics",
|
|
@@ -15246,7 +15507,7 @@ var config_default56 = `{
|
|
|
15246
15507
|
`;
|
|
15247
15508
|
|
|
15248
15509
|
// templates/schedules/weekly-dora-metrics/content.md
|
|
15249
|
-
var
|
|
15510
|
+
var content_default58 = `# Weekly DORA Metrics
|
|
15250
15511
|
|
|
15251
15512
|
Template parameters: {{REPO_URL}}, {{BRANCH}}, {{TAG_PATTERN}}, {{REPORT_NAME}}, {{PAGE_ID}}
|
|
15252
15513
|
|
|
@@ -15315,7 +15576,7 @@ Call \`store-progress\` with status \`completed\` and an output summary that inc
|
|
|
15315
15576
|
init_db();
|
|
15316
15577
|
|
|
15317
15578
|
// templates/workflows/alerts-triage/config.json
|
|
15318
|
-
var
|
|
15579
|
+
var config_default59 = `{
|
|
15319
15580
|
"kind": "workflow",
|
|
15320
15581
|
"name": "alerts-triage",
|
|
15321
15582
|
"displayName": "Alerts Triage",
|
|
@@ -15332,7 +15593,7 @@ var config_default57 = `{
|
|
|
15332
15593
|
`;
|
|
15333
15594
|
|
|
15334
15595
|
// templates/workflows/alerts-triage/content.md
|
|
15335
|
-
var
|
|
15596
|
+
var content_default59 = `# Alerts Triage
|
|
15336
15597
|
|
|
15337
15598
|
The Slack handler emits \`slack.message\`; this workflow keeps the event-driven path and deduplicates work after the channel filter.
|
|
15338
15599
|
|
|
@@ -15352,7 +15613,7 @@ The Slack handler emits \`slack.message\`; this workflow keeps the event-driven
|
|
|
15352
15613
|
`;
|
|
15353
15614
|
|
|
15354
15615
|
// templates/workflows/autopilot/config.json
|
|
15355
|
-
var
|
|
15616
|
+
var config_default60 = `{
|
|
15356
15617
|
"kind": "workflow",
|
|
15357
15618
|
"name": "autopilot",
|
|
15358
15619
|
"displayName": "Autopilot Feature Pipeline",
|
|
@@ -15369,7 +15630,7 @@ var config_default58 = `{
|
|
|
15369
15630
|
`;
|
|
15370
15631
|
|
|
15371
15632
|
// templates/workflows/autopilot/content.md
|
|
15372
|
-
var
|
|
15633
|
+
var content_default60 = `# Autopilot Feature Pipeline
|
|
15373
15634
|
|
|
15374
15635
|
Template parameter: {{REPO_URL}}
|
|
15375
15636
|
|
|
@@ -15381,7 +15642,7 @@ Use this workflow as a canonical feature delivery pipeline. Customize roles and
|
|
|
15381
15642
|
`;
|
|
15382
15643
|
|
|
15383
15644
|
// templates/workflows/competitor-radar/config.json
|
|
15384
|
-
var
|
|
15645
|
+
var config_default61 = `{
|
|
15385
15646
|
"kind": "workflow",
|
|
15386
15647
|
"name": "competitor-radar",
|
|
15387
15648
|
"displayName": "Competitor Radar",
|
|
@@ -15398,7 +15659,7 @@ var config_default59 = `{
|
|
|
15398
15659
|
`;
|
|
15399
15660
|
|
|
15400
15661
|
// templates/workflows/competitor-radar/content.md
|
|
15401
|
-
var
|
|
15662
|
+
var content_default61 = `# Competitor Radar
|
|
15402
15663
|
|
|
15403
15664
|
This self-hosted port retains the scheduled, fixture, extraction, gap-analysis, litmus, cooldown, and bounded-report behavior. Its pinned GSC helper is embedded in the workflow, so it does not fetch executable code from Desplega infrastructure.
|
|
15404
15665
|
|
|
@@ -15408,7 +15669,7 @@ This self-hosted port retains the scheduled, fixture, extraction, gap-analysis,
|
|
|
15408
15669
|
`;
|
|
15409
15670
|
|
|
15410
15671
|
// templates/workflows/docs-site-releases/config.json
|
|
15411
|
-
var
|
|
15672
|
+
var config_default62 = `{
|
|
15412
15673
|
"kind": "workflow",
|
|
15413
15674
|
"name": "docs-site-releases",
|
|
15414
15675
|
"displayName": "Documentation Release Notes",
|
|
@@ -15425,7 +15686,7 @@ var config_default60 = `{
|
|
|
15425
15686
|
`;
|
|
15426
15687
|
|
|
15427
15688
|
// templates/workflows/docs-site-releases/content.md
|
|
15428
|
-
var
|
|
15689
|
+
var content_default62 = `# Documentation Release Notes
|
|
15429
15690
|
|
|
15430
15691
|
This topology-preserving self-hosted port removes installation-specific identities, endpoints, and credentials while retaining the live workflow's nodes, edges, input mappings, guards, retries, cooldown, and triggers. Configure the declared template parameters and integrations before enabling it.
|
|
15431
15692
|
|
|
@@ -15440,7 +15701,7 @@ This topology-preserving self-hosted port removes installation-specific identiti
|
|
|
15440
15701
|
`;
|
|
15441
15702
|
|
|
15442
15703
|
// templates/workflows/linear-drain-loop/config.json
|
|
15443
|
-
var
|
|
15704
|
+
var config_default63 = `{
|
|
15444
15705
|
"kind": "workflow",
|
|
15445
15706
|
"name": "linear-drain-loop",
|
|
15446
15707
|
"displayName": "Linear Drain Loop",
|
|
@@ -15462,7 +15723,7 @@ var config_default61 = `{
|
|
|
15462
15723
|
`;
|
|
15463
15724
|
|
|
15464
15725
|
// templates/workflows/linear-drain-loop/content.md
|
|
15465
|
-
var
|
|
15726
|
+
var content_default63 = `# Linear Drain Loop
|
|
15466
15727
|
|
|
15467
15728
|
Template parameter: {{LINEAR_PROJECT_ID}}
|
|
15468
15729
|
|
|
@@ -15507,7 +15768,7 @@ Blocked and ambiguous items are explicitly left alone — the dispatch node surf
|
|
|
15507
15768
|
`;
|
|
15508
15769
|
|
|
15509
15770
|
// templates/workflows/llm-safe-release-context/config.json
|
|
15510
|
-
var
|
|
15771
|
+
var config_default64 = `{
|
|
15511
15772
|
"kind": "workflow",
|
|
15512
15773
|
"name": "llm-safe-release-context",
|
|
15513
15774
|
"displayName": "LLM-Safe Release Context",
|
|
@@ -15524,7 +15785,7 @@ var config_default62 = `{
|
|
|
15524
15785
|
`;
|
|
15525
15786
|
|
|
15526
15787
|
// templates/workflows/llm-safe-release-context/content.md
|
|
15527
|
-
var
|
|
15788
|
+
var content_default64 = `# LLM-Safe Release Context
|
|
15528
15789
|
|
|
15529
15790
|
Template parameters: {{ORG_ID}}, {{REPO_URL}}
|
|
15530
15791
|
|
|
@@ -15598,7 +15859,7 @@ This avoids the common failure mode where a large \`context.json\` fills the mod
|
|
|
15598
15859
|
`;
|
|
15599
15860
|
|
|
15600
15861
|
// templates/workflows/pr-review-status-sweep/config.json
|
|
15601
|
-
var
|
|
15862
|
+
var config_default65 = `{
|
|
15602
15863
|
"kind": "workflow",
|
|
15603
15864
|
"name": "pr-review-status-sweep",
|
|
15604
15865
|
"displayName": "PR Review Status Sweep",
|
|
@@ -15615,7 +15876,7 @@ var config_default63 = `{
|
|
|
15615
15876
|
`;
|
|
15616
15877
|
|
|
15617
15878
|
// templates/workflows/pr-review-status-sweep/content.md
|
|
15618
|
-
var
|
|
15879
|
+
var content_default65 = `# PR Review Status Sweep
|
|
15619
15880
|
|
|
15620
15881
|
This topology-preserving self-hosted port removes installation-specific identities, endpoints, and credentials while retaining the live workflow's nodes, edges, input mappings, guards, retries, cooldown, and triggers. Configure the declared template parameters and integrations before enabling it.
|
|
15621
15882
|
|
|
@@ -15628,7 +15889,7 @@ This topology-preserving self-hosted port removes installation-specific identiti
|
|
|
15628
15889
|
`;
|
|
15629
15890
|
|
|
15630
15891
|
// templates/workflows/ralph-loop/config.json
|
|
15631
|
-
var
|
|
15892
|
+
var config_default66 = `{
|
|
15632
15893
|
"kind": "workflow",
|
|
15633
15894
|
"name": "ralph-loop",
|
|
15634
15895
|
"displayName": "Iterative Review Loop",
|
|
@@ -15645,7 +15906,7 @@ var config_default64 = `{
|
|
|
15645
15906
|
`;
|
|
15646
15907
|
|
|
15647
15908
|
// templates/workflows/ralph-loop/content.md
|
|
15648
|
-
var
|
|
15909
|
+
var content_default66 = `# Iterative Review Loop
|
|
15649
15910
|
|
|
15650
15911
|
Template parameter: {{REPO_URL}}
|
|
15651
15912
|
|
|
@@ -15696,14 +15957,14 @@ The \`maxIterations\` parameter is declarative: the reviewer signals PASS when d
|
|
|
15696
15957
|
init_db();
|
|
15697
15958
|
var asText2 = (value) => value;
|
|
15698
15959
|
var BUILT_IN_WORKFLOW_SOURCES = [
|
|
15699
|
-
{ config: asText2(config_default57), content: asText2(content_default57) },
|
|
15700
|
-
{ config: asText2(config_default58), content: asText2(content_default58) },
|
|
15701
15960
|
{ config: asText2(config_default59), content: asText2(content_default59) },
|
|
15702
15961
|
{ config: asText2(config_default60), content: asText2(content_default60) },
|
|
15703
15962
|
{ config: asText2(config_default61), content: asText2(content_default61) },
|
|
15704
15963
|
{ config: asText2(config_default62), content: asText2(content_default62) },
|
|
15705
15964
|
{ config: asText2(config_default63), content: asText2(content_default63) },
|
|
15706
|
-
{ config: asText2(config_default64), content: asText2(content_default64) }
|
|
15965
|
+
{ config: asText2(config_default64), content: asText2(content_default64) },
|
|
15966
|
+
{ config: asText2(config_default65), content: asText2(content_default65) },
|
|
15967
|
+
{ config: asText2(config_default66), content: asText2(content_default66) }
|
|
15707
15968
|
];
|
|
15708
15969
|
function sortJson(value) {
|
|
15709
15970
|
if (Array.isArray(value))
|
|
@@ -15812,11 +16073,6 @@ var workflowsSeeder = createWorkflowsSeeder();
|
|
|
15812
16073
|
// src/be/seed/schedules-seeder.ts
|
|
15813
16074
|
var asText3 = (value) => value;
|
|
15814
16075
|
var BUILT_IN_SCHEDULE_SOURCES = [
|
|
15815
|
-
{ config: asText3(config_default49), content: asText3(content_default49) },
|
|
15816
|
-
{
|
|
15817
|
-
config: asText3(config_default50),
|
|
15818
|
-
content: asText3(content_default50)
|
|
15819
|
-
},
|
|
15820
16076
|
{ config: asText3(config_default51), content: asText3(content_default51) },
|
|
15821
16077
|
{
|
|
15822
16078
|
config: asText3(config_default52),
|
|
@@ -15827,11 +16083,16 @@ var BUILT_IN_SCHEDULE_SOURCES = [
|
|
|
15827
16083
|
config: asText3(config_default54),
|
|
15828
16084
|
content: asText3(content_default54)
|
|
15829
16085
|
},
|
|
16086
|
+
{ config: asText3(config_default55), content: asText3(content_default55) },
|
|
16087
|
+
{
|
|
16088
|
+
config: asText3(config_default56),
|
|
16089
|
+
content: asText3(content_default56)
|
|
16090
|
+
},
|
|
15830
16091
|
{
|
|
15831
|
-
config: asText3(
|
|
15832
|
-
content: asText3(
|
|
16092
|
+
config: asText3(config_default57),
|
|
16093
|
+
content: asText3(content_default57)
|
|
15833
16094
|
},
|
|
15834
|
-
{ config: asText3(
|
|
16095
|
+
{ config: asText3(config_default58), content: asText3(content_default58) }
|
|
15835
16096
|
];
|
|
15836
16097
|
function parseScheduleSource(source) {
|
|
15837
16098
|
const config = JSON.parse(source.config);
|