@alisio/plugin-swarm 0.0.0-stage → 0.1.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/.agents/agents/swarm-architect.md +20 -0
- package/.agents/agents/swarm-cleaner.md +20 -0
- package/.agents/agents/swarm-coder.md +20 -0
- package/.agents/agents/swarm-hardener.md +20 -0
- package/.agents/agents/swarm-lieutenant.md +20 -0
- package/.agents/agents/swarm-qa.md +20 -0
- package/.agents/agents/swarm-refactorer.md +20 -0
- package/.agents/agents/swarm-specifier.md +20 -0
- package/.agents/skills/swarm-architecture-rules/SKILL.md +43 -0
- package/.agents/skills/swarm-clarification/SKILL.md +42 -0
- package/.agents/skills/swarm-cleaner-metrics/SKILL.md +44 -0
- package/.agents/skills/swarm-engineering-constitution/SKILL.md +44 -0
- package/.agents/skills/swarm-gherkin-spec/SKILL.md +43 -0
- package/.agents/skills/swarm-handoff-protocol/SKILL.md +45 -0
- package/.agents/skills/swarm-lieutenant/SKILL.md +41 -0
- package/.agents/skills/swarm-mutation-hardening/SKILL.md +43 -0
- package/.agents/skills/swarm-qa-acceptance/SKILL.md +42 -0
- package/.agents/skills/swarm-tdd-slice/SKILL.md +44 -0
- package/.agents/skills/swarm-toolchain-profile/SKILL.md +41 -0
- package/LICENSE +21 -0
- package/README.es.md +337 -0
- package/README.md +322 -2
- package/assets/approval-flow.svg +1 -0
- package/assets/architecture.svg +1 -0
- package/assets/audit-states.svg +1 -0
- package/assets/dashboard.css +964 -0
- package/assets/dashboard.html +123 -0
- package/assets/dashboard.js +965 -0
- package/assets/dashboard.svg +1 -0
- package/assets/handoff-sequence.svg +1 -0
- package/assets/pack-pipelines.svg +1 -0
- package/assets/packs/four-pack/pack.json +18 -0
- package/assets/packs/six-pack/pack.json +22 -0
- package/assets/packs/two-pack/pack.json +14 -0
- package/assets/screenshots/dashboard-board-dark.png +0 -0
- package/assets/screenshots/dashboard-board-light.png +0 -0
- package/assets/screenshots/dashboard-documents-diff.png +0 -0
- package/assets/screenshots/dashboard-empty-state.png +0 -0
- package/assets/screenshots/dashboard-phone.png +0 -0
- package/assets/screenshots/dashboard-reject-dialog.png +0 -0
- package/assets/screenshots/dashboard-transcript-tail.png +0 -0
- package/assets/screenshots/dashboard-work-queue.png +0 -0
- package/assets/task-states.svg +1 -0
- package/assets/toolchains/node-ts.json +61 -0
- package/cover.svg +46 -0
- package/dist/adapters/child-session-runner.d.ts +36 -0
- package/dist/adapters/child-session-runner.d.ts.map +1 -0
- package/dist/adapters/child-session-runner.js +156 -0
- package/dist/adapters/child-session-runner.js.map +1 -0
- package/dist/adapters/fs-board-store.d.ts +11 -0
- package/dist/adapters/fs-board-store.d.ts.map +1 -0
- package/dist/adapters/fs-board-store.js +27 -0
- package/dist/adapters/fs-board-store.js.map +1 -0
- package/dist/adapters/fs-handoff-store.d.ts +36 -0
- package/dist/adapters/fs-handoff-store.d.ts.map +1 -0
- package/dist/adapters/fs-handoff-store.js +254 -0
- package/dist/adapters/fs-handoff-store.js.map +1 -0
- package/dist/adapters/fs-task-state-store.d.ts +16 -0
- package/dist/adapters/fs-task-state-store.d.ts.map +1 -0
- package/dist/adapters/fs-task-state-store.js +66 -0
- package/dist/adapters/fs-task-state-store.js.map +1 -0
- package/dist/adapters/git-worktree.d.ts +31 -0
- package/dist/adapters/git-worktree.d.ts.map +1 -0
- package/dist/adapters/git-worktree.js +209 -0
- package/dist/adapters/git-worktree.js.map +1 -0
- package/dist/adapters/process-exec.d.ts +36 -0
- package/dist/adapters/process-exec.d.ts.map +1 -0
- package/dist/adapters/process-exec.js +138 -0
- package/dist/adapters/process-exec.js.map +1 -0
- package/dist/adapters/process-gate-runner.d.ts +39 -0
- package/dist/adapters/process-gate-runner.d.ts.map +1 -0
- package/dist/adapters/process-gate-runner.js +242 -0
- package/dist/adapters/process-gate-runner.js.map +1 -0
- package/dist/adapters/unavailable-runner.d.ts +4 -0
- package/dist/adapters/unavailable-runner.d.ts.map +1 -0
- package/dist/adapters/unavailable-runner.js +12 -0
- package/dist/adapters/unavailable-runner.js.map +1 -0
- package/dist/app/audit.d.ts +23 -0
- package/dist/app/audit.d.ts.map +1 -0
- package/dist/app/audit.js +9 -0
- package/dist/app/audit.js.map +1 -0
- package/dist/app/budget.d.ts +29 -0
- package/dist/app/budget.d.ts.map +1 -0
- package/dist/app/budget.js +78 -0
- package/dist/app/budget.js.map +1 -0
- package/dist/app/chat-store.d.ts +18 -0
- package/dist/app/chat-store.d.ts.map +1 -0
- package/dist/app/chat-store.js +48 -0
- package/dist/app/chat-store.js.map +1 -0
- package/dist/app/documents.d.ts +33 -0
- package/dist/app/documents.d.ts.map +1 -0
- package/dist/app/documents.js +63 -0
- package/dist/app/documents.js.map +1 -0
- package/dist/app/forge.d.ts +106 -0
- package/dist/app/forge.d.ts.map +1 -0
- package/dist/app/forge.js +420 -0
- package/dist/app/forge.js.map +1 -0
- package/dist/app/operator.d.ts +46 -0
- package/dist/app/operator.d.ts.map +1 -0
- package/dist/app/operator.js +168 -0
- package/dist/app/operator.js.map +1 -0
- package/dist/app/pidfile.d.ts +18 -0
- package/dist/app/pidfile.d.ts.map +1 -0
- package/dist/app/pidfile.js +56 -0
- package/dist/app/pidfile.js.map +1 -0
- package/dist/app/project.d.ts +93 -0
- package/dist/app/project.d.ts.map +1 -0
- package/dist/app/project.js +291 -0
- package/dist/app/project.js.map +1 -0
- package/dist/app/prompts.d.ts +48 -0
- package/dist/app/prompts.d.ts.map +1 -0
- package/dist/app/prompts.js +88 -0
- package/dist/app/prompts.js.map +1 -0
- package/dist/app/pump.d.ts +144 -0
- package/dist/app/pump.d.ts.map +1 -0
- package/dist/app/pump.js +707 -0
- package/dist/app/pump.js.map +1 -0
- package/dist/app/services.d.ts +112 -0
- package/dist/app/services.d.ts.map +1 -0
- package/dist/app/services.js +323 -0
- package/dist/app/services.js.map +1 -0
- package/dist/app/state.d.ts +70 -0
- package/dist/app/state.d.ts.map +1 -0
- package/dist/app/state.js +96 -0
- package/dist/app/state.js.map +1 -0
- package/dist/args.d.ts +10 -0
- package/dist/args.d.ts.map +1 -0
- package/dist/args.js +33 -0
- package/dist/args.js.map +1 -0
- package/dist/coordinator.d.ts +80 -0
- package/dist/coordinator.d.ts.map +1 -0
- package/dist/coordinator.js +481 -0
- package/dist/coordinator.js.map +1 -0
- package/dist/dashboard/api.d.ts +28 -0
- package/dist/dashboard/api.d.ts.map +1 -0
- package/dist/dashboard/api.js +178 -0
- package/dist/dashboard/api.js.map +1 -0
- package/dist/dashboard/auth.d.ts +13 -0
- package/dist/dashboard/auth.d.ts.map +1 -0
- package/dist/dashboard/auth.js +36 -0
- package/dist/dashboard/auth.js.map +1 -0
- package/dist/dashboard/open.d.ts +7 -0
- package/dist/dashboard/open.d.ts.map +1 -0
- package/dist/dashboard/open.js +17 -0
- package/dist/dashboard/open.js.map +1 -0
- package/dist/dashboard/server.d.ts +28 -0
- package/dist/dashboard/server.d.ts.map +1 -0
- package/dist/dashboard/server.js +176 -0
- package/dist/dashboard/server.js.map +1 -0
- package/dist/doctor.d.ts +28 -0
- package/dist/doctor.d.ts.map +1 -0
- package/dist/doctor.js +108 -0
- package/dist/doctor.js.map +1 -0
- package/dist/domain/attention.d.ts +20 -0
- package/dist/domain/attention.d.ts.map +1 -0
- package/dist/domain/attention.js +41 -0
- package/dist/domain/attention.js.map +1 -0
- package/dist/domain/envelope.d.ts +37 -0
- package/dist/domain/envelope.d.ts.map +1 -0
- package/dist/domain/envelope.js +106 -0
- package/dist/domain/envelope.js.map +1 -0
- package/dist/domain/handoff.d.ts +57 -0
- package/dist/domain/handoff.d.ts.map +1 -0
- package/dist/domain/handoff.js +191 -0
- package/dist/domain/handoff.js.map +1 -0
- package/dist/domain/identifiers.d.ts +18 -0
- package/dist/domain/identifiers.d.ts.map +1 -0
- package/dist/domain/identifiers.js +70 -0
- package/dist/domain/identifiers.js.map +1 -0
- package/dist/domain/pack.d.ts +45 -0
- package/dist/domain/pack.d.ts.map +1 -0
- package/dist/domain/pack.js +207 -0
- package/dist/domain/pack.js.map +1 -0
- package/dist/domain/pipeline.d.ts +33 -0
- package/dist/domain/pipeline.d.ts.map +1 -0
- package/dist/domain/pipeline.js +50 -0
- package/dist/domain/pipeline.js.map +1 -0
- package/dist/domain/task.d.ts +26 -0
- package/dist/domain/task.d.ts.map +1 -0
- package/dist/domain/task.js +154 -0
- package/dist/domain/task.js.map +1 -0
- package/dist/domain/taskstate.d.ts +37 -0
- package/dist/domain/taskstate.d.ts.map +1 -0
- package/dist/domain/taskstate.js +98 -0
- package/dist/domain/taskstate.js.map +1 -0
- package/dist/gates/dry.d.ts +14 -0
- package/dist/gates/dry.d.ts.map +1 -0
- package/dist/gates/dry.js +71 -0
- package/dist/gates/dry.js.map +1 -0
- package/dist/gates/parsers.d.ts +34 -0
- package/dist/gates/parsers.d.ts.map +1 -0
- package/dist/gates/parsers.js +120 -0
- package/dist/gates/parsers.js.map +1 -0
- package/dist/index.d.ts +45 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +207 -0
- package/dist/index.js.map +1 -0
- package/dist/options.d.ts +13 -0
- package/dist/options.d.ts.map +1 -0
- package/dist/options.js +27 -0
- package/dist/options.js.map +1 -0
- package/dist/panel.d.ts +5 -0
- package/dist/panel.d.ts.map +1 -0
- package/dist/panel.js +52 -0
- package/dist/panel.js.map +1 -0
- package/dist/ports/agent-runner.d.ts +51 -0
- package/dist/ports/agent-runner.d.ts.map +1 -0
- package/dist/ports/agent-runner.js +2 -0
- package/dist/ports/agent-runner.js.map +1 -0
- package/dist/ports/board-store.d.ts +7 -0
- package/dist/ports/board-store.d.ts.map +1 -0
- package/dist/ports/board-store.js +2 -0
- package/dist/ports/board-store.js.map +1 -0
- package/dist/ports/clock.d.ts +5 -0
- package/dist/ports/clock.d.ts.map +1 -0
- package/dist/ports/clock.js +2 -0
- package/dist/ports/clock.js.map +1 -0
- package/dist/ports/gate-runner.d.ts +34 -0
- package/dist/ports/gate-runner.d.ts.map +1 -0
- package/dist/ports/gate-runner.js +2 -0
- package/dist/ports/gate-runner.js.map +1 -0
- package/dist/ports/handoff-store.d.ts +39 -0
- package/dist/ports/handoff-store.d.ts.map +1 -0
- package/dist/ports/handoff-store.js +2 -0
- package/dist/ports/handoff-store.js.map +1 -0
- package/dist/ports/isolation.d.ts +43 -0
- package/dist/ports/isolation.d.ts.map +1 -0
- package/dist/ports/isolation.js +2 -0
- package/dist/ports/isolation.js.map +1 -0
- package/dist/ports/notifier.d.ts +28 -0
- package/dist/ports/notifier.d.ts.map +1 -0
- package/dist/ports/notifier.js +2 -0
- package/dist/ports/notifier.js.map +1 -0
- package/dist/ports/task-state-store.d.ts +10 -0
- package/dist/ports/task-state-store.d.ts.map +1 -0
- package/dist/ports/task-state-store.js +2 -0
- package/dist/ports/task-state-store.js.map +1 -0
- package/dist/refs.d.ts +10 -0
- package/dist/refs.d.ts.map +1 -0
- package/dist/refs.js +19 -0
- package/dist/refs.js.map +1 -0
- package/dist/resources.d.ts +55 -0
- package/dist/resources.d.ts.map +1 -0
- package/dist/resources.js +255 -0
- package/dist/resources.js.map +1 -0
- package/dist/status.d.ts +18 -0
- package/dist/status.d.ts.map +1 -0
- package/dist/status.js +60 -0
- package/dist/status.js.map +1 -0
- package/dist/storage.d.ts +18 -0
- package/dist/storage.d.ts.map +1 -0
- package/dist/storage.js +79 -0
- package/dist/storage.js.map +1 -0
- package/dist/toolchains/profile.d.ts +21 -0
- package/dist/toolchains/profile.d.ts.map +1 -0
- package/dist/toolchains/profile.js +60 -0
- package/dist/toolchains/profile.js.map +1 -0
- package/dist/toolchains/thresholds.d.ts +29 -0
- package/dist/toolchains/thresholds.d.ts.map +1 -0
- package/dist/toolchains/thresholds.js +45 -0
- package/dist/toolchains/thresholds.js.map +1 -0
- package/dist/version.d.ts +2 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +3 -0
- package/dist/version.js.map +1 -0
- package/package.json +51 -3
|
@@ -0,0 +1,481 @@
|
|
|
1
|
+
import { ChildSessionRunner } from "./adapters/child-session-runner.js";
|
|
2
|
+
import { GitWorktreeIsolation } from "./adapters/git-worktree.js";
|
|
3
|
+
import { ProcessGateRunner } from "./adapters/process-gate-runner.js";
|
|
4
|
+
import { DEFAULT_PACK } from "./app/forge.js";
|
|
5
|
+
import { rejectActions } from "./app/operator.js";
|
|
6
|
+
import { SwarmServices, TEARDOWN_CONFIRMATION } from "./app/services.js";
|
|
7
|
+
import { parseFlags, splitDoubleDash } from "./args.js";
|
|
8
|
+
import { openInBrowser } from "./dashboard/open.js";
|
|
9
|
+
import { startDashboard } from "./dashboard/server.js";
|
|
10
|
+
import { defaultDoctorDeps, formatDoctor, runDoctor } from "./doctor.js";
|
|
11
|
+
import { validateProjectName } from "./domain/identifiers.js";
|
|
12
|
+
import { roleIds } from "./domain/pack.js";
|
|
13
|
+
import { parseOptions } from "./options.js";
|
|
14
|
+
import { parseTaskRef } from "./refs.js";
|
|
15
|
+
import { loadToolchain } from "./resources.js";
|
|
16
|
+
import { renderStatus } from "./status.js";
|
|
17
|
+
const usage = {
|
|
18
|
+
pack: "Usage: /swarm:pack list | show <name>",
|
|
19
|
+
project: "Usage: /swarm:project new <name> [--pack <pack>] [--github <owner/repo>] -- <mission> | open <name> | close <name> | list",
|
|
20
|
+
task: "Usage: /swarm:task <project> new [name] -- <task text> | delete <name> | retry <name> | accept <name>",
|
|
21
|
+
approve: "Usage: /swarm:approve <project>/<task>",
|
|
22
|
+
reject: "Usage: /swarm:reject <project>/<task> retry|delete|accept [-- comments]",
|
|
23
|
+
answer: "Usage: /swarm:answer <project>/<task> -- <answer text>",
|
|
24
|
+
comment: "Usage: /swarm:comment <project>/<task> <document> -- <comment text> | <project>/<task> clear",
|
|
25
|
+
chat: "Usage: /swarm:chat [project] -- <message>",
|
|
26
|
+
stop: "Usage: /swarm:stop <project>",
|
|
27
|
+
run: "Usage: /swarm:run <project> [--seconds <1-3600>]",
|
|
28
|
+
budget: "Usage: /swarm:budget | /swarm:budget raise <tokens>",
|
|
29
|
+
dashboard: "Usage: /swarm:dashboard [project | project/task]",
|
|
30
|
+
teardown: `Usage: /swarm:teardown --confirm ${TEARDOWN_CONFIRMATION}`,
|
|
31
|
+
};
|
|
32
|
+
const describePack = (pack) => [
|
|
33
|
+
`${pack.name}: ${pack.description}`,
|
|
34
|
+
`Toolchain: ${pack.toolchain}`,
|
|
35
|
+
`Pipeline: ${roleIds(pack).join(" → ")}`,
|
|
36
|
+
...pack.roles.map((role) => ` - ${role.id} (${role.isolation}, receive ${role.receive}, ${role.propagation})`),
|
|
37
|
+
pack.approval ? `Approval gate after: ${pack.approval.after}` : "Approval gate: none",
|
|
38
|
+
`Thresholds: coverage >= ${pack.thresholds.coverage}%, complexity <= ${pack.thresholds.complexity}, CRAP <= ${pack.thresholds.crap}, mutation >= ${pack.thresholds.mutation}%`,
|
|
39
|
+
...Object.entries(pack.gates).map(([role, gates]) => `Gates for ${role}: ${gates.join(", ")}`),
|
|
40
|
+
].join("\n");
|
|
41
|
+
/**
|
|
42
|
+
* The command front end. It parses arguments and renders text; every decision goes through
|
|
43
|
+
* `services`, the same facade the dashboard calls (AD-10).
|
|
44
|
+
*/
|
|
45
|
+
export class SwarmCoordinator {
|
|
46
|
+
api;
|
|
47
|
+
seams;
|
|
48
|
+
services;
|
|
49
|
+
options;
|
|
50
|
+
parent;
|
|
51
|
+
dashboards = new Map();
|
|
52
|
+
constructor(api, seams = {}) {
|
|
53
|
+
this.api = api;
|
|
54
|
+
this.seams = seams;
|
|
55
|
+
this.options = parseOptions(api.options);
|
|
56
|
+
const gates = seams.gates === null ? undefined : (seams.gates ?? new ProcessGateRunner({ loadToolchain }));
|
|
57
|
+
this.services = new SwarmServices({
|
|
58
|
+
isolation: seams.isolation ?? new GitWorktreeIsolation(),
|
|
59
|
+
runner: seams.runner ?? this.childRunner(),
|
|
60
|
+
maxConcurrent: this.options.maxConcurrent,
|
|
61
|
+
...(this.options.tokenBudget !== undefined ? { tokenBudget: this.options.tokenBudget } : {}),
|
|
62
|
+
...(gates ? { gates } : {}),
|
|
63
|
+
...(seams.clock ? { clock: seams.clock } : {}),
|
|
64
|
+
...(seams.notifier ? { notifier: seams.notifier } : {}),
|
|
65
|
+
...(seams.autoStart !== undefined ? { autoStart: seams.autoStart } : {}),
|
|
66
|
+
...(seams.cloneUrl ? { cloneUrl: seams.cloneUrl } : {}),
|
|
67
|
+
ui: {
|
|
68
|
+
interactive: () => this.api.ui?.interactive?.() === true,
|
|
69
|
+
askQuestions: (request) => this.api.ui.askQuestions(request),
|
|
70
|
+
},
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Child sessions hang from the session that last issued a swarm command. `api.sessions` is read
|
|
75
|
+
* lazily: nothing touches it during `setup()` (it is only usable after startup).
|
|
76
|
+
*/
|
|
77
|
+
childRunner() {
|
|
78
|
+
const api = this.api;
|
|
79
|
+
return new ChildSessionRunner({
|
|
80
|
+
sessions: {
|
|
81
|
+
create: (spec) => api.sessions.create(spec),
|
|
82
|
+
run: (id, prompt, options) => api.sessions.run(id, prompt, options),
|
|
83
|
+
cancel: (id) => api.sessions.cancel(id),
|
|
84
|
+
},
|
|
85
|
+
parentSession: () => this.parent,
|
|
86
|
+
roleOptions: () => this.options.roles,
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
forgeFor(workspace) {
|
|
90
|
+
return this.services.forgeFor(workspace);
|
|
91
|
+
}
|
|
92
|
+
/** Remember the session that issued a command or tool call: it parents the child sessions. */
|
|
93
|
+
touch(sessionId) {
|
|
94
|
+
if (sessionId)
|
|
95
|
+
this.parent = sessionId;
|
|
96
|
+
}
|
|
97
|
+
workspaceOf(sessionId) {
|
|
98
|
+
if (!sessionId)
|
|
99
|
+
throw new Error("No session is available to resolve the workspace");
|
|
100
|
+
this.touch(sessionId);
|
|
101
|
+
return this.api.sessions.workspace(sessionId);
|
|
102
|
+
}
|
|
103
|
+
async init(workspace) {
|
|
104
|
+
const { created } = await this.forgeFor(workspace).init();
|
|
105
|
+
return created
|
|
106
|
+
? "Swarm forge initialised under .alisio/swarm. Run /swarm:doctor to check your tools, then /swarm:project new <name> -- <mission>."
|
|
107
|
+
: "The swarm forge is already initialised.";
|
|
108
|
+
}
|
|
109
|
+
async doctor(workspace) {
|
|
110
|
+
const forge = this.forgeFor(workspace);
|
|
111
|
+
const report = await runDoctor({
|
|
112
|
+
nodeVersion: this.seams.doctor?.nodeVersion ?? process.versions.node,
|
|
113
|
+
workspace,
|
|
114
|
+
toolchain: await loadToolchain("node-ts"),
|
|
115
|
+
initialised: await forge.isInitialised(),
|
|
116
|
+
exec: this.seams.doctor?.exec ?? defaultDoctorDeps.exec,
|
|
117
|
+
writable: this.seams.doctor?.writable ?? defaultDoctorDeps.writable,
|
|
118
|
+
});
|
|
119
|
+
return formatDoctor(report);
|
|
120
|
+
}
|
|
121
|
+
async pack(workspace, args) {
|
|
122
|
+
const forge = this.forgeFor(workspace);
|
|
123
|
+
const { head } = splitDoubleDash(args);
|
|
124
|
+
const [action, name] = head;
|
|
125
|
+
if (action === "list" && head.length === 1) {
|
|
126
|
+
const packs = await forge.listPacks();
|
|
127
|
+
const invalid = await forge.invalidPacks();
|
|
128
|
+
return [
|
|
129
|
+
...packs.map((p) => `${p.name} (${p.source}): ${p.roles.join(" → ")} — ${p.description}`),
|
|
130
|
+
...invalid.map((p) => `Ignored invalid pack ${p.file}: ${p.error}`),
|
|
131
|
+
].join("\n");
|
|
132
|
+
}
|
|
133
|
+
if (action === "show" && name && head.length === 2)
|
|
134
|
+
return describePack(await forge.loadPack(name));
|
|
135
|
+
throw new Error(usage.pack);
|
|
136
|
+
}
|
|
137
|
+
async project(workspace, args) {
|
|
138
|
+
const forge = this.forgeFor(workspace);
|
|
139
|
+
const { head, tail } = splitDoubleDash(args);
|
|
140
|
+
const [action, ...rest] = head;
|
|
141
|
+
if (action === "list" && rest.length === 0) {
|
|
142
|
+
const projects = await forge.listProjects();
|
|
143
|
+
if (projects.length === 0)
|
|
144
|
+
return "No projects yet.";
|
|
145
|
+
return projects
|
|
146
|
+
.map((p) => `${p.name} — ${p.pack} — ${p.running ? "running" : p.open ? "open (not running)" : "closed"}`)
|
|
147
|
+
.join("\n");
|
|
148
|
+
}
|
|
149
|
+
if (action === "new") {
|
|
150
|
+
const { positional, flags } = parseFlags(rest, ["pack", "github"]);
|
|
151
|
+
if (positional.length !== 1)
|
|
152
|
+
throw new Error(usage.project);
|
|
153
|
+
if (!tail)
|
|
154
|
+
throw new Error("A project needs a mission: add `-- <mission>`");
|
|
155
|
+
const runtime = await forge.newProject({
|
|
156
|
+
name: positional[0],
|
|
157
|
+
pack: flags.pack ?? DEFAULT_PACK,
|
|
158
|
+
mission: tail,
|
|
159
|
+
...(flags.github ? { github: flags.github } : {}),
|
|
160
|
+
});
|
|
161
|
+
return [
|
|
162
|
+
`Project ${runtime.name} created and open (${runtime.pack.name}: ${roleIds(runtime.pack).join(" → ")}).`,
|
|
163
|
+
`Create a task with /swarm:task ${runtime.name} new -- <task text>.`,
|
|
164
|
+
].join("\n");
|
|
165
|
+
}
|
|
166
|
+
if ((action === "open" || action === "close") && rest.length === 1) {
|
|
167
|
+
const name = rest[0];
|
|
168
|
+
if (action === "open") {
|
|
169
|
+
const runtime = await this.services.openProject(workspace, name);
|
|
170
|
+
return `Project ${name} is open (${runtime.pack.name}).`;
|
|
171
|
+
}
|
|
172
|
+
await this.services.closeProject(workspace, name);
|
|
173
|
+
return `Project ${name} closed. Project files were left untouched.`;
|
|
174
|
+
}
|
|
175
|
+
throw new Error(usage.project);
|
|
176
|
+
}
|
|
177
|
+
async createTask(workspace, project, text, name) {
|
|
178
|
+
const card = await this.services.createTask(workspace, project, text, name);
|
|
179
|
+
return `Task ${card.name} queued for ${card.lane} in ${project}.`;
|
|
180
|
+
}
|
|
181
|
+
async task(workspace, args) {
|
|
182
|
+
const { head, tail } = splitDoubleDash(args);
|
|
183
|
+
const [project, action, name] = head;
|
|
184
|
+
if (!project || !action)
|
|
185
|
+
throw new Error(usage.task);
|
|
186
|
+
if (action === "new" && head.length <= 3)
|
|
187
|
+
return this.createTask(workspace, project, tail, name);
|
|
188
|
+
if ((action === "delete" || action === "retry" || action === "accept") &&
|
|
189
|
+
name &&
|
|
190
|
+
head.length === 3) {
|
|
191
|
+
validateProjectName(project);
|
|
192
|
+
if (action === "delete") {
|
|
193
|
+
await this.services.deleteTask(workspace, project, name);
|
|
194
|
+
return `Task ${name} deleted and archived; its card, handoffs and state are gone.`;
|
|
195
|
+
}
|
|
196
|
+
if (action === "retry") {
|
|
197
|
+
await this.services.retryTask(workspace, project, name);
|
|
198
|
+
return `Task ${name} queued for retry with a fresh allowance.`;
|
|
199
|
+
}
|
|
200
|
+
await this.services.acceptTask(workspace, project, name);
|
|
201
|
+
return `Task ${name} accepted as it is.`;
|
|
202
|
+
}
|
|
203
|
+
throw new Error(usage.task);
|
|
204
|
+
}
|
|
205
|
+
// ---- decisions: the same services the dashboard calls ----
|
|
206
|
+
ref(head, message) {
|
|
207
|
+
if (head.length === 0)
|
|
208
|
+
throw new Error(message);
|
|
209
|
+
return parseTaskRef(head[0]);
|
|
210
|
+
}
|
|
211
|
+
async approve(workspace, args) {
|
|
212
|
+
const { head } = splitDoubleDash(args);
|
|
213
|
+
let ref;
|
|
214
|
+
if (head.length === 0) {
|
|
215
|
+
const waiting = (await this.services.attention(workspace)).filter((i) => i.kind === "approval");
|
|
216
|
+
const listing = waiting.map((i) => `${i.project}/${i.task}`);
|
|
217
|
+
if (waiting.length === 0)
|
|
218
|
+
throw new Error("No approval is waiting");
|
|
219
|
+
// Approving is a decision: without an explicit reference only an interactive choice may make it.
|
|
220
|
+
const answer = waiting.length <= 4
|
|
221
|
+
? await this.services.ask({
|
|
222
|
+
questions: [
|
|
223
|
+
{
|
|
224
|
+
id: "task",
|
|
225
|
+
header: "Approve",
|
|
226
|
+
question: "Which task do you approve?",
|
|
227
|
+
options: [
|
|
228
|
+
...listing.map((value) => ({ value, label: value })),
|
|
229
|
+
...(listing.length === 1
|
|
230
|
+
? [{ value: "cancel", label: "Cancel", description: "Approve nothing" }]
|
|
231
|
+
: []),
|
|
232
|
+
],
|
|
233
|
+
},
|
|
234
|
+
],
|
|
235
|
+
})
|
|
236
|
+
: undefined;
|
|
237
|
+
const picked = answer?.task;
|
|
238
|
+
if (typeof picked !== "string" || picked === "cancel") {
|
|
239
|
+
throw new Error(`${usage.approve}\nWaiting: ${listing.join(", ")}`);
|
|
240
|
+
}
|
|
241
|
+
ref = parseTaskRef(picked);
|
|
242
|
+
}
|
|
243
|
+
else {
|
|
244
|
+
ref = this.ref(head, usage.approve);
|
|
245
|
+
if (head.length > 1)
|
|
246
|
+
throw new Error(usage.approve);
|
|
247
|
+
}
|
|
248
|
+
await this.services.approve(workspace, ref.project, ref.task);
|
|
249
|
+
const card = (await this.services.runtimeOf(workspace, ref.project)).cardByName(ref.task);
|
|
250
|
+
return `Task ${ref.task} approved; it continues in ${card.lane}.`;
|
|
251
|
+
}
|
|
252
|
+
async reject(workspace, args) {
|
|
253
|
+
const { head, tail } = splitDoubleDash(args);
|
|
254
|
+
const ref = this.ref(head, usage.reject);
|
|
255
|
+
let action = head[1];
|
|
256
|
+
if (head.length > 2)
|
|
257
|
+
throw new Error(usage.reject);
|
|
258
|
+
if (action === undefined) {
|
|
259
|
+
const answer = await this.services.ask({
|
|
260
|
+
questions: [
|
|
261
|
+
{
|
|
262
|
+
id: "action",
|
|
263
|
+
header: "Reject",
|
|
264
|
+
question: `What should happen to ${ref.project}/${ref.task}?`,
|
|
265
|
+
options: [
|
|
266
|
+
{
|
|
267
|
+
value: "retry",
|
|
268
|
+
label: "Retry",
|
|
269
|
+
description: "Restore the base and re-run with your comments",
|
|
270
|
+
},
|
|
271
|
+
{ value: "delete", label: "Delete", description: "Archive the task and remove it" },
|
|
272
|
+
{
|
|
273
|
+
value: "accept",
|
|
274
|
+
label: "Accept unchanged",
|
|
275
|
+
description: "Release the work as it is",
|
|
276
|
+
},
|
|
277
|
+
],
|
|
278
|
+
},
|
|
279
|
+
],
|
|
280
|
+
});
|
|
281
|
+
action = typeof answer?.action === "string" ? answer.action : undefined;
|
|
282
|
+
}
|
|
283
|
+
if (!action || !rejectActions.includes(action))
|
|
284
|
+
throw new Error(usage.reject);
|
|
285
|
+
await this.services.reject(workspace, ref.project, ref.task, action, tail);
|
|
286
|
+
return {
|
|
287
|
+
retry: `Task ${ref.task} rejected: retry queued; the rejected work is kept under refs/swarm/rejected/${ref.task}.`,
|
|
288
|
+
delete: `Task ${ref.task} rejected and deleted; it was archived.`,
|
|
289
|
+
accept: `Task ${ref.task} accepted unchanged and released.`,
|
|
290
|
+
}[action];
|
|
291
|
+
}
|
|
292
|
+
async answer(workspace, args) {
|
|
293
|
+
const { head, tail } = splitDoubleDash(args);
|
|
294
|
+
const ref = this.ref(head, usage.answer);
|
|
295
|
+
if (head.length > 1 || !tail)
|
|
296
|
+
throw new Error(usage.answer);
|
|
297
|
+
await this.services.answer(workspace, ref.project, ref.task, tail);
|
|
298
|
+
return `Your answer was delivered to ${ref.task}; the role continues.`;
|
|
299
|
+
}
|
|
300
|
+
async comment(workspace, args) {
|
|
301
|
+
const { head, tail } = splitDoubleDash(args);
|
|
302
|
+
const ref = this.ref(head, usage.comment);
|
|
303
|
+
if (head.length === 2 && head[1] === "clear" && !tail) {
|
|
304
|
+
await this.services.clearComments(workspace, ref.project, ref.task);
|
|
305
|
+
return `Comments on ${ref.task} cleared.`;
|
|
306
|
+
}
|
|
307
|
+
if (head.length !== 2 || !tail)
|
|
308
|
+
throw new Error(usage.comment);
|
|
309
|
+
await this.services.addComment(workspace, ref.project, ref.task, head[1], tail);
|
|
310
|
+
return `Comment on ${head[1]} recorded; approving is disabled until the comments are cleared or the task is rejected.`;
|
|
311
|
+
}
|
|
312
|
+
async chat(workspace, args) {
|
|
313
|
+
const { head, tail } = splitDoubleDash(args);
|
|
314
|
+
if (!tail || head.length > 1)
|
|
315
|
+
throw new Error(usage.chat);
|
|
316
|
+
let project = head[0];
|
|
317
|
+
if (project === undefined) {
|
|
318
|
+
const open = await this.services.openProjects(workspace);
|
|
319
|
+
if (open.length !== 1) {
|
|
320
|
+
throw new Error(`Name the project: /swarm:chat <project> -- <message>${open.length > 0 ? ` (open: ${open.join(", ")})` : ""}`);
|
|
321
|
+
}
|
|
322
|
+
project = open[0];
|
|
323
|
+
}
|
|
324
|
+
return this.services.chat(workspace, project, tail);
|
|
325
|
+
}
|
|
326
|
+
async stop(workspace, args) {
|
|
327
|
+
const { head } = splitDoubleDash(args);
|
|
328
|
+
if (head.length !== 1)
|
|
329
|
+
throw new Error(usage.stop);
|
|
330
|
+
const project = validateProjectName(head[0]);
|
|
331
|
+
await this.services.stopProject(workspace, project);
|
|
332
|
+
return `Project ${project} stopped: agents cancelled and the pump halted. Run /swarm:project open ${project} to start it again.`;
|
|
333
|
+
}
|
|
334
|
+
async run(workspace, args) {
|
|
335
|
+
const { head } = splitDoubleDash(args);
|
|
336
|
+
const { positional, flags } = parseFlags(head, ["seconds"]);
|
|
337
|
+
if (positional.length !== 1)
|
|
338
|
+
throw new Error(usage.run);
|
|
339
|
+
const seconds = flags.seconds === undefined ? 60 : Number(flags.seconds);
|
|
340
|
+
if (!Number.isInteger(seconds) || seconds < 1 || seconds > 3600) {
|
|
341
|
+
throw new Error("The --seconds value must be an integer from 1 to 3600");
|
|
342
|
+
}
|
|
343
|
+
const project = validateProjectName(positional[0]);
|
|
344
|
+
const { finished } = await this.services.runProject(workspace, project, seconds);
|
|
345
|
+
const board = (await this.services.runtimeOf(workspace, project)).board();
|
|
346
|
+
const counts = new Map();
|
|
347
|
+
for (const card of board.tasks)
|
|
348
|
+
counts.set(card.status, (counts.get(card.status) ?? 0) + 1);
|
|
349
|
+
const summary = [...counts].map(([status, count]) => `${status}: ${count}`).join(", ") || "no tasks";
|
|
350
|
+
return finished
|
|
351
|
+
? `${project} is idle. ${summary}.`
|
|
352
|
+
: `Stopped waiting after ${seconds} seconds; work continues in the background. ${summary}.`;
|
|
353
|
+
}
|
|
354
|
+
async budget(workspace, args) {
|
|
355
|
+
const { head } = splitDoubleDash(args);
|
|
356
|
+
const status = this.services.budget(workspace);
|
|
357
|
+
if (head.length === 0) {
|
|
358
|
+
if (status.limit === undefined)
|
|
359
|
+
return `No token budget is configured. ${status.total} tokens used.`;
|
|
360
|
+
return `Token budget: ${status.total} of ${status.limit} tokens used${status.exceeded ? " (reached: no new agent runs start until you raise it)" : ""}.`;
|
|
361
|
+
}
|
|
362
|
+
if (head[0] !== "raise" || head.length !== 2)
|
|
363
|
+
throw new Error(usage.budget);
|
|
364
|
+
const extra = Number(head[1]);
|
|
365
|
+
if (!Number.isInteger(extra) || extra <= 0)
|
|
366
|
+
throw new Error(`${usage.budget} (a positive whole number)`);
|
|
367
|
+
if (status.limit === undefined) {
|
|
368
|
+
throw new Error("No token budget is configured; set pluginOverrides.swarm.options.tokenBudget first");
|
|
369
|
+
}
|
|
370
|
+
const raised = await this.services.raiseBudget(workspace, extra);
|
|
371
|
+
return `Token budget raised to ${raised.limit}; ${raised.total} used.`;
|
|
372
|
+
}
|
|
373
|
+
async teardown(_workspace, args) {
|
|
374
|
+
const { head } = splitDoubleDash(args);
|
|
375
|
+
const { positional, flags } = parseFlags(head, ["confirm"]);
|
|
376
|
+
if (positional.length > 0)
|
|
377
|
+
throw new Error(usage.teardown);
|
|
378
|
+
let confirm = flags.confirm;
|
|
379
|
+
if (confirm === undefined) {
|
|
380
|
+
const answer = await this.services.ask({
|
|
381
|
+
questions: [
|
|
382
|
+
{
|
|
383
|
+
id: "confirm",
|
|
384
|
+
header: "Teardown",
|
|
385
|
+
question: "Cancel every agent, stop every project and the dashboard? Project files stay.",
|
|
386
|
+
options: [
|
|
387
|
+
{ value: TEARDOWN_CONFIRMATION, label: "Teardown", description: "Stop everything" },
|
|
388
|
+
{ value: "cancel", label: "Cancel", description: "Keep the swarm running" },
|
|
389
|
+
],
|
|
390
|
+
},
|
|
391
|
+
],
|
|
392
|
+
});
|
|
393
|
+
if (answer?.confirm === "cancel")
|
|
394
|
+
return "Teardown cancelled; nothing was stopped.";
|
|
395
|
+
confirm = typeof answer?.confirm === "string" ? answer.confirm : undefined;
|
|
396
|
+
}
|
|
397
|
+
await this.services.teardown(confirm);
|
|
398
|
+
return "Teardown complete: agents cancelled, projects stopped, pidfile removed. Project files were left untouched.";
|
|
399
|
+
}
|
|
400
|
+
/**
|
|
401
|
+
* Start the local dashboard (once per workspace) and return its link. The link carries the
|
|
402
|
+
* per-run token; the browser exchanges it for a cookie. Opening a browser is best effort.
|
|
403
|
+
*/
|
|
404
|
+
async dashboard(workspace, args) {
|
|
405
|
+
const target = args.trim();
|
|
406
|
+
let hash = "";
|
|
407
|
+
if (target) {
|
|
408
|
+
if (/[/:]/.test(target)) {
|
|
409
|
+
const ref = parseTaskRef(target);
|
|
410
|
+
hash = `#${ref.project}/${ref.task}`;
|
|
411
|
+
}
|
|
412
|
+
else {
|
|
413
|
+
hash = `#${validateProjectName(target)}`;
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
const running = this.dashboards.get(workspace);
|
|
417
|
+
if (running) {
|
|
418
|
+
return `The swarm dashboard is already running: ${running.url}${hash}`;
|
|
419
|
+
}
|
|
420
|
+
const handle = await startDashboard({
|
|
421
|
+
services: this.services,
|
|
422
|
+
workspace,
|
|
423
|
+
onClosed: () => this.dashboards.delete(workspace),
|
|
424
|
+
});
|
|
425
|
+
this.dashboards.set(workspace, handle);
|
|
426
|
+
let opened = true;
|
|
427
|
+
try {
|
|
428
|
+
await (this.seams.openBrowser ?? openInBrowser)(`${handle.url}${hash}`);
|
|
429
|
+
}
|
|
430
|
+
catch {
|
|
431
|
+
opened = false;
|
|
432
|
+
}
|
|
433
|
+
return [
|
|
434
|
+
`Swarm dashboard: ${handle.url}${hash}`,
|
|
435
|
+
opened
|
|
436
|
+
? "It was opened in your browser."
|
|
437
|
+
: "Open the link in your browser (it could not be opened automatically).",
|
|
438
|
+
"The link carries a private token that only works with this run: do not share it. It stops on /swarm:teardown or when the host exits.",
|
|
439
|
+
].join("\n");
|
|
440
|
+
}
|
|
441
|
+
/** The text of a gate report for the `swarm_gate_run` tool. */
|
|
442
|
+
formatGate(report) {
|
|
443
|
+
const state = report.passed ? "passed" : "failed";
|
|
444
|
+
const lines = [`${report.gate}: ${state}`];
|
|
445
|
+
if (report.skipped)
|
|
446
|
+
lines.push(`Skipped: ${report.skipped}`);
|
|
447
|
+
if (report.error)
|
|
448
|
+
lines.push(`Could not run: ${report.error}`);
|
|
449
|
+
if (report.timedOut)
|
|
450
|
+
lines.push("The gate timed out.");
|
|
451
|
+
for (const finding of report.findings)
|
|
452
|
+
lines.push(`- ${finding}`);
|
|
453
|
+
return lines.join("\n");
|
|
454
|
+
}
|
|
455
|
+
async gateRun(workspace, input) {
|
|
456
|
+
return this.formatGate(await this.services.gateRun(workspace, input));
|
|
457
|
+
}
|
|
458
|
+
async status(workspace, args) {
|
|
459
|
+
const project = args.trim() || undefined;
|
|
460
|
+
if (project !== undefined)
|
|
461
|
+
validateProjectName(project);
|
|
462
|
+
return renderStatus(await this.forgeFor(workspace).snapshot(project));
|
|
463
|
+
}
|
|
464
|
+
async statusText(workspace, args) {
|
|
465
|
+
return (await this.status(workspace, args)).text;
|
|
466
|
+
}
|
|
467
|
+
async statusTool(workspace, project) {
|
|
468
|
+
const { text, blocks } = await this.status(workspace, project ?? "");
|
|
469
|
+
return {
|
|
470
|
+
content: [
|
|
471
|
+
{ type: "text", text },
|
|
472
|
+
...blocks.map((block) => ({ type: "ui", block })),
|
|
473
|
+
],
|
|
474
|
+
};
|
|
475
|
+
}
|
|
476
|
+
/** Stop everything: dispose is capped by the host, so this only cancels, halts and cleans up. */
|
|
477
|
+
async dispose() {
|
|
478
|
+
await this.services.shutdown();
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
//# sourceMappingURL=coordinator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"coordinator.js","sourceRoot":"","sources":["../src/coordinator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { SwarmServices } from "../app/services.js";
|
|
2
|
+
/** A failure with an HTTP status; the message is safe to show the operator. */
|
|
3
|
+
export declare class ApiError extends Error {
|
|
4
|
+
readonly status: number;
|
|
5
|
+
constructor(status: number, message: string);
|
|
6
|
+
}
|
|
7
|
+
export interface ApiRequest {
|
|
8
|
+
method: string;
|
|
9
|
+
/** Path segments after `/api`, already percent-decoded. */
|
|
10
|
+
segments: string[];
|
|
11
|
+
query: URLSearchParams;
|
|
12
|
+
body: unknown;
|
|
13
|
+
}
|
|
14
|
+
export interface ApiResult {
|
|
15
|
+
status: number;
|
|
16
|
+
body: unknown;
|
|
17
|
+
}
|
|
18
|
+
export interface ApiDeps {
|
|
19
|
+
services: SwarmServices;
|
|
20
|
+
workspace: string;
|
|
21
|
+
}
|
|
22
|
+
/** Map a service error to an HTTP status from its message: our own messages are the contract. */
|
|
23
|
+
export declare function statusFor(error: unknown): number;
|
|
24
|
+
/** The mutating routes, for the "complementary only" test: gate decisions and nothing else. */
|
|
25
|
+
export declare const mutatingRoutes: () => string[];
|
|
26
|
+
/** Dispatch one API request. Every failure is an `ApiError` or a service `Error`; the caller maps it. */
|
|
27
|
+
export declare function handleApi(deps: ApiDeps, request: ApiRequest): Promise<ApiResult>;
|
|
28
|
+
//# sourceMappingURL=api.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../src/dashboard/api.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAGxD,+EAA+E;AAC/E,qBAAa,QAAS,SAAQ,KAAK;IAE/B,QAAQ,CAAC,MAAM,EAAE,MAAM;IADzB,YACW,MAAM,EAAE,MAAM,EACvB,OAAO,EAAE,MAAM,EAGhB;CACF;AAED,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,2DAA2D;IAC3D,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,KAAK,EAAE,eAAe,CAAC;IACvB,IAAI,EAAE,OAAO,CAAC;CACf;AAED,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,OAAO,CAAC;CACf;AAED,MAAM,WAAW,OAAO;IACtB,QAAQ,EAAE,aAAa,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;CACnB;AAID,iGAAiG;AACjG,wBAAgB,SAAS,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAMhD;AA+ID,+FAA+F;AAC/F,eAAO,MAAM,cAAc,QAAO,MAAM,EAI7B,CAAC;AAYZ,yGAAyG;AACzG,wBAAsB,SAAS,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,SAAS,CAAC,CAUtF"}
|