@alisio/plugin-swarm 0.0.0-stage → 0.1.1
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,28 @@
|
|
|
1
|
+
import type { AttentionItem } from "../domain/attention.js";
|
|
2
|
+
export type ActivityKind = "handoff" | "merge" | "gate" | "bounce" | "approval";
|
|
3
|
+
export type SwarmEvent = {
|
|
4
|
+
type: "activity";
|
|
5
|
+
project: string;
|
|
6
|
+
at: string;
|
|
7
|
+
kind: ActivityKind;
|
|
8
|
+
role: string;
|
|
9
|
+
task: string;
|
|
10
|
+
message: string;
|
|
11
|
+
} | {
|
|
12
|
+
type: "attention";
|
|
13
|
+
item: AttentionItem;
|
|
14
|
+
} | {
|
|
15
|
+
type: "task-done";
|
|
16
|
+
project: string;
|
|
17
|
+
task: string;
|
|
18
|
+
} | {
|
|
19
|
+
type: "error";
|
|
20
|
+
project: string;
|
|
21
|
+
message: string;
|
|
22
|
+
};
|
|
23
|
+
/** Fire-and-forget notification sink (dashboard chime, status line). Must never throw into callers. */
|
|
24
|
+
export interface Notifier {
|
|
25
|
+
notify(event: SwarmEvent): void;
|
|
26
|
+
}
|
|
27
|
+
export declare const silentNotifier: Notifier;
|
|
28
|
+
//# sourceMappingURL=notifier.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"notifier.d.ts","sourceRoot":"","sources":["../../src/ports/notifier.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAE5D,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG,OAAO,GAAG,MAAM,GAAG,QAAQ,GAAG,UAAU,CAAC;AAEhF,MAAM,MAAM,UAAU,GAClB;IACE,IAAI,EAAE,UAAU,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,YAAY,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB,GACD;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,IAAI,EAAE,aAAa,CAAA;CAAE,GAC1C;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACpD;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAExD,uGAAuG;AACvG,MAAM,WAAW,QAAQ;IACvB,MAAM,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI,CAAC;CACjC;AAED,eAAO,MAAM,cAAc,EAAE,QAAsC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"notifier.js","sourceRoot":"","sources":["../../src/ports/notifier.ts"],"names":[],"mappings":"AAuBA,MAAM,CAAC,MAAM,cAAc,GAAa,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,SAAS,EAAE,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { TaskState } from "../domain/taskstate.js";
|
|
2
|
+
/** Durable per-task coordinator state: holds, approval comments, bounces and the base commit. */
|
|
3
|
+
export interface TaskStateStore {
|
|
4
|
+
get(taskId: string): Promise<TaskState | undefined>;
|
|
5
|
+
/** Read-modify-write under a single writer; creates the state when it does not exist. */
|
|
6
|
+
update(taskId: string, task: string, change: (state: TaskState) => void): Promise<TaskState>;
|
|
7
|
+
list(): Promise<TaskState[]>;
|
|
8
|
+
remove(taskId: string): Promise<void>;
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=task-state-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"task-state-store.d.ts","sourceRoot":"","sources":["../../src/ports/task-state-store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAExD,iGAAiG;AACjG,MAAM,WAAW,cAAc;IAC7B,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC,CAAC;IACpD,yFAAyF;IACzF,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,KAAK,EAAE,SAAS,KAAK,IAAI,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;IAC7F,IAAI,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC;IAC7B,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACvC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"task-state-store.js","sourceRoot":"","sources":["../../src/ports/task-state-store.ts"],"names":[],"mappings":""}
|
package/dist/refs.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export interface TaskRef {
|
|
2
|
+
project: string;
|
|
3
|
+
task: string;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* A task reference from a command: `<project>/<task>` or an attention item id
|
|
7
|
+
* (`<kind>:<project>:<task>`). Both parts are validated identifiers.
|
|
8
|
+
*/
|
|
9
|
+
export declare function parseTaskRef(ref: string | undefined): TaskRef;
|
|
10
|
+
//# sourceMappingURL=refs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"refs.d.ts","sourceRoot":"","sources":["../src/refs.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,OAAO;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAc7D"}
|
package/dist/refs.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { validateProjectName, validateTaskName } from "./domain/identifiers.js";
|
|
2
|
+
/**
|
|
3
|
+
* A task reference from a command: `<project>/<task>` or an attention item id
|
|
4
|
+
* (`<kind>:<project>:<task>`). Both parts are validated identifiers.
|
|
5
|
+
*/
|
|
6
|
+
export function parseTaskRef(ref) {
|
|
7
|
+
const text = (ref ?? "").trim();
|
|
8
|
+
const slash = /^([^/:\s]+)\/([^/:\s]+)$/.exec(text);
|
|
9
|
+
const attention = /^[a-z-]+:([^/:\s]+):([^/:\s]+)$/.exec(text);
|
|
10
|
+
const match = slash ?? attention;
|
|
11
|
+
if (!match) {
|
|
12
|
+
throw new Error(`Invalid task reference ${JSON.stringify(text.slice(0, 60))}: use <project>/<task> or an attention id`);
|
|
13
|
+
}
|
|
14
|
+
return {
|
|
15
|
+
project: validateProjectName(match[1]),
|
|
16
|
+
task: validateTaskName(match[2]),
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=refs.js.map
|
package/dist/refs.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"refs.js","sourceRoot":"","sources":["../src/refs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAOhF;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,GAAuB;IAClD,MAAM,IAAI,GAAG,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IAChC,MAAM,KAAK,GAAG,0BAA0B,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACpD,MAAM,SAAS,GAAG,iCAAiC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC/D,MAAM,KAAK,GAAG,KAAK,IAAI,SAAS,CAAC;IACjC,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,KAAK,CACb,0BAA0B,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,2CAA2C,CACvG,CAAC;IACJ,CAAC;IACD,OAAO;QACL,OAAO,EAAE,mBAAmB,CAAC,KAAK,CAAC,CAAC,CAAW,CAAC;QAChD,IAAI,EAAE,gBAAgB,CAAC,KAAK,CAAC,CAAC,CAAW,CAAC;KAC3C,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { type Pack } from "./domain/pack.js";
|
|
2
|
+
import { type Toolchain } from "./toolchains/profile.js";
|
|
3
|
+
export declare const resourcePaths: {
|
|
4
|
+
readonly agents: "../.agents/agents";
|
|
5
|
+
readonly skills: "../.agents/skills";
|
|
6
|
+
};
|
|
7
|
+
/**
|
|
8
|
+
* Every agent carries the `swarm-` prefix so the host agents catalog never collides with another
|
|
9
|
+
* plugin that ships a `specifier` or `coder` of its own (Wayfinder does).
|
|
10
|
+
*/
|
|
11
|
+
export declare const resourceRoles: readonly ["swarm-lieutenant", "swarm-specifier", "swarm-coder", "swarm-cleaner", "swarm-refactorer", "swarm-architect", "swarm-hardener", "swarm-qa"];
|
|
12
|
+
export type ResourceRole = (typeof resourceRoles)[number];
|
|
13
|
+
export declare const isResourceRole: (value: string) => value is ResourceRole;
|
|
14
|
+
/**
|
|
15
|
+
* The single place that maps a pack role id (`coder`, `qa`, ...) to its agent name. Pack role ids
|
|
16
|
+
* are unchanged; only the agent files carry the prefix. Unknown (custom) role ids have no agent
|
|
17
|
+
* here: a custom pack names its own agent in `role.agent`.
|
|
18
|
+
*/
|
|
19
|
+
export declare function agentForRole(roleId: string): ResourceRole | undefined;
|
|
20
|
+
/** Skills each agent loads. The same files are the registered resources and the child instructions. */
|
|
21
|
+
export declare const roleSkills: Record<ResourceRole, string[]>;
|
|
22
|
+
interface ParsedResource {
|
|
23
|
+
frontmatter: Record<string, unknown>;
|
|
24
|
+
body: string;
|
|
25
|
+
}
|
|
26
|
+
export declare function parseResource(source: string, label: string): ParsedResource;
|
|
27
|
+
export interface AgentProfile {
|
|
28
|
+
name: ResourceRole;
|
|
29
|
+
/** Agent body plus every loaded skill body (the child session instructions). */
|
|
30
|
+
instructions: string;
|
|
31
|
+
tools: string[];
|
|
32
|
+
disallowedTools: string[];
|
|
33
|
+
mode: "primary" | "subagent";
|
|
34
|
+
maxTurns: number;
|
|
35
|
+
timeoutMs: number;
|
|
36
|
+
maxOutputTokens: number;
|
|
37
|
+
readOnly: boolean;
|
|
38
|
+
permission: {
|
|
39
|
+
write: "allow" | "deny";
|
|
40
|
+
process: "allow" | "deny";
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
/** Everything a runner needs to start a child session for one agent. */
|
|
44
|
+
export declare function loadAgentProfile(role: ResourceRole): Promise<AgentProfile>;
|
|
45
|
+
/** Agent body plus every loaded skill body: the same files registered with the host. */
|
|
46
|
+
export declare function loadRoleInstructions(role: ResourceRole): Promise<string>;
|
|
47
|
+
export declare function listShippedPacks(): Promise<string[]>;
|
|
48
|
+
export declare function loadShippedPack(name: string): Promise<Pack>;
|
|
49
|
+
export declare function loadToolchain(id: string): Promise<Toolchain>;
|
|
50
|
+
export declare const dashboardAssets: readonly ["dashboard.html", "dashboard.css", "dashboard.js"];
|
|
51
|
+
export type DashboardAsset = (typeof dashboardAssets)[number];
|
|
52
|
+
/** A static dashboard file shipped in `assets/`, read relative to the built entry. */
|
|
53
|
+
export declare function loadDashboardAsset(name: DashboardAsset): Promise<string>;
|
|
54
|
+
export {};
|
|
55
|
+
//# sourceMappingURL=resources.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resources.d.ts","sourceRoot":"","sources":["../src/resources.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,IAAI,EAAa,MAAM,kBAAkB,CAAC;AACxD,OAAO,EAAkB,KAAK,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAEzE,eAAO,MAAM,aAAa;aACxB,MAAM,EAAE,mBAAmB;aAC3B,MAAM,EAAE,mBAAmB;CACnB,CAAC;AAEX;;;GAGG;AACH,eAAO,MAAM,aAAa,YACxB,kBAAkB,EAClB,iBAAiB,EACjB,aAAa,EACb,eAAe,EACf,kBAAkB,EAClB,iBAAiB,EACjB,gBAAgB,EAChB,UAAU,CACF,CAAC;AACX,MAAM,MAAM,YAAY,GAAG,CAAC,OAAO,aAAa,CAAC,CAAC,MAAM,CAAC,CAAC;AAE1D,eAAO,MAAM,cAAc,UAAW,MAAM,KAAG,KAAK,IAAI,YACF,CAAC;AAEvD;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS,CAGrE;AAKD,uGAAuG;AACvG,eAAO,MAAM,UAAU,EAAE,MAAM,CAAC,YAAY,EAAE,MAAM,EAAE,CAerD,CAAC;AAEF,UAAU,cAAc;IACtB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,IAAI,EAAE,MAAM,CAAC;CACd;AAcD,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,cAAc,CA6B3E;AAmED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,YAAY,CAAC;IACnB,gFAAgF;IAChF,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,IAAI,EAAE,SAAS,GAAG,UAAU,CAAC;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,MAAM,CAAC;IACxB,QAAQ,EAAE,OAAO,CAAC;IAClB,UAAU,EAAE;QAAE,KAAK,EAAE,OAAO,GAAG,MAAM,CAAC;QAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CAAA;KAAE,CAAC;CACpE;AAkBD,wEAAwE;AACxE,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC,CAqBhF;AAED,wFAAwF;AACxF,wBAAsB,oBAAoB,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,CAe9E;AAID,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,CAM1D;AAED,wBAAsB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAQjE;AAED,wBAAsB,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC,CAWlE;AAED,eAAO,MAAM,eAAe,YAAI,gBAAgB,EAAE,eAAe,EAAE,cAAc,CAAU,CAAC;AAC5F,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,eAAe,CAAC,CAAC,MAAM,CAAC,CAAC;AAE9D,sFAAsF;AACtF,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAK9E"}
|
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
import { readdir, readFile } from "node:fs/promises";
|
|
2
|
+
import { fileURLToPath } from "node:url";
|
|
3
|
+
import { parsePack } from "./domain/pack.js";
|
|
4
|
+
import { parseToolchain } from "./toolchains/profile.js";
|
|
5
|
+
export const resourcePaths = {
|
|
6
|
+
agents: "../.agents/agents",
|
|
7
|
+
skills: "../.agents/skills",
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* Every agent carries the `swarm-` prefix so the host agents catalog never collides with another
|
|
11
|
+
* plugin that ships a `specifier` or `coder` of its own (Wayfinder does).
|
|
12
|
+
*/
|
|
13
|
+
export const resourceRoles = [
|
|
14
|
+
"swarm-lieutenant",
|
|
15
|
+
"swarm-specifier",
|
|
16
|
+
"swarm-coder",
|
|
17
|
+
"swarm-cleaner",
|
|
18
|
+
"swarm-refactorer",
|
|
19
|
+
"swarm-architect",
|
|
20
|
+
"swarm-hardener",
|
|
21
|
+
"swarm-qa",
|
|
22
|
+
];
|
|
23
|
+
export const isResourceRole = (value) => resourceRoles.includes(value);
|
|
24
|
+
/**
|
|
25
|
+
* The single place that maps a pack role id (`coder`, `qa`, ...) to its agent name. Pack role ids
|
|
26
|
+
* are unchanged; only the agent files carry the prefix. Unknown (custom) role ids have no agent
|
|
27
|
+
* here: a custom pack names its own agent in `role.agent`.
|
|
28
|
+
*/
|
|
29
|
+
export function agentForRole(roleId) {
|
|
30
|
+
const agent = `swarm-${roleId}`;
|
|
31
|
+
return isResourceRole(agent) ? agent : undefined;
|
|
32
|
+
}
|
|
33
|
+
const handoff = "swarm-handoff-protocol";
|
|
34
|
+
const constitution = "swarm-engineering-constitution";
|
|
35
|
+
/** Skills each agent loads. The same files are the registered resources and the child instructions. */
|
|
36
|
+
export const roleSkills = {
|
|
37
|
+
"swarm-lieutenant": ["swarm-lieutenant"],
|
|
38
|
+
"swarm-specifier": [handoff, constitution, "swarm-gherkin-spec", "swarm-clarification"],
|
|
39
|
+
"swarm-coder": [
|
|
40
|
+
handoff,
|
|
41
|
+
constitution,
|
|
42
|
+
"swarm-tdd-slice",
|
|
43
|
+
"swarm-clarification",
|
|
44
|
+
"swarm-toolchain-profile",
|
|
45
|
+
],
|
|
46
|
+
"swarm-cleaner": [handoff, constitution, "swarm-cleaner-metrics", "swarm-toolchain-profile"],
|
|
47
|
+
"swarm-refactorer": [handoff, constitution, "swarm-cleaner-metrics"],
|
|
48
|
+
"swarm-architect": [handoff, constitution, "swarm-architecture-rules"],
|
|
49
|
+
"swarm-hardener": [handoff, constitution, "swarm-mutation-hardening", "swarm-toolchain-profile"],
|
|
50
|
+
"swarm-qa": [handoff, constitution, "swarm-qa-acceptance"],
|
|
51
|
+
};
|
|
52
|
+
function scalar(source) {
|
|
53
|
+
const value = source.trim();
|
|
54
|
+
if (value === "true")
|
|
55
|
+
return true;
|
|
56
|
+
if (value === "false")
|
|
57
|
+
return false;
|
|
58
|
+
if (/^\d+$/.test(value))
|
|
59
|
+
return Number(value);
|
|
60
|
+
if (value.startsWith("[") && value.endsWith("]")) {
|
|
61
|
+
const inner = value.slice(1, -1).trim();
|
|
62
|
+
return inner ? inner.split(",").map((item) => item.trim().replace(/^['"]|['"]$/g, "")) : [];
|
|
63
|
+
}
|
|
64
|
+
return value.replace(/^['"]|['"]$/g, "");
|
|
65
|
+
}
|
|
66
|
+
export function parseResource(source, label) {
|
|
67
|
+
const normalized = source.replace(/\r\n/g, "\n");
|
|
68
|
+
const match = /^---\n([\s\S]*?)\n---\n([\s\S]+)$/.exec(normalized);
|
|
69
|
+
if (!match)
|
|
70
|
+
throw new Error(`Malformed resource frontmatter: ${label}`);
|
|
71
|
+
const frontmatter = {};
|
|
72
|
+
let parent;
|
|
73
|
+
for (const [index, line] of (match[1] ?? "").split("\n").entries()) {
|
|
74
|
+
if (!line.trim() || line.trimStart().startsWith("#"))
|
|
75
|
+
continue;
|
|
76
|
+
if (/\t|[&*!>|]/.test(line))
|
|
77
|
+
throw new Error(`Unsupported frontmatter syntax in ${label}`);
|
|
78
|
+
const nested = /^ {2}([A-Za-z][\w-]*):\s*(.*)$/.exec(line);
|
|
79
|
+
if (nested && parent) {
|
|
80
|
+
parent[nested[1]] = scalar(nested[2]);
|
|
81
|
+
continue;
|
|
82
|
+
}
|
|
83
|
+
const entry = /^([A-Za-z][\w-]*):\s*(.*)$/.exec(line);
|
|
84
|
+
if (!entry)
|
|
85
|
+
throw new Error(`Malformed frontmatter line ${index + 1} in ${label}`);
|
|
86
|
+
const key = entry[1];
|
|
87
|
+
const raw = entry[2];
|
|
88
|
+
if (!raw) {
|
|
89
|
+
parent = {};
|
|
90
|
+
frontmatter[key] = parent;
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
frontmatter[key] = scalar(raw);
|
|
94
|
+
parent = undefined;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
const body = (match[2] ?? "").trim();
|
|
98
|
+
if (!body)
|
|
99
|
+
throw new Error(`Resource body is empty: ${label}`);
|
|
100
|
+
return { frontmatter, body };
|
|
101
|
+
}
|
|
102
|
+
const url = (path) => fileURLToPath(new URL(path, import.meta.url));
|
|
103
|
+
async function load(path) {
|
|
104
|
+
return parseResource(await readFile(url(path), "utf8"), path);
|
|
105
|
+
}
|
|
106
|
+
function validateAgent(resource, role, skillNames) {
|
|
107
|
+
const front = resource.frontmatter;
|
|
108
|
+
const permission = front.permission;
|
|
109
|
+
const declaredSkills = Array.isArray(front.skills) ? front.skills : undefined;
|
|
110
|
+
if (front.name !== role ||
|
|
111
|
+
typeof front.description !== "string" ||
|
|
112
|
+
!front.description ||
|
|
113
|
+
!Array.isArray(front.tools) ||
|
|
114
|
+
!Array.isArray(front.disallowedTools) ||
|
|
115
|
+
!front.disallowedTools.includes("task") ||
|
|
116
|
+
(role === "swarm-lieutenant" ? front.mode !== "primary" : front.mode !== "subagent") ||
|
|
117
|
+
typeof front.maxTurns !== "number" ||
|
|
118
|
+
typeof front.readOnly !== "boolean" ||
|
|
119
|
+
!permission ||
|
|
120
|
+
typeof permission !== "object" ||
|
|
121
|
+
Array.isArray(permission) ||
|
|
122
|
+
!declaredSkills ||
|
|
123
|
+
!skillNames.every((skillName) => declaredSkills.includes(skillName))) {
|
|
124
|
+
throw new Error(`Invalid agent resource: ${role}`);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
function validateSkill(resource, skillName) {
|
|
128
|
+
const front = resource.frontmatter;
|
|
129
|
+
const metadata = front.metadata;
|
|
130
|
+
const headings = [
|
|
131
|
+
"## Activation Contract",
|
|
132
|
+
"## Hard Rules",
|
|
133
|
+
"## Decision Gates",
|
|
134
|
+
"## Execution Steps",
|
|
135
|
+
"## Output Contract",
|
|
136
|
+
"## References",
|
|
137
|
+
];
|
|
138
|
+
let cursor = -1;
|
|
139
|
+
for (const heading of headings) {
|
|
140
|
+
const next = resource.body.indexOf(heading);
|
|
141
|
+
if (next <= cursor)
|
|
142
|
+
throw new Error(`Invalid skill section order: ${skillName}`);
|
|
143
|
+
cursor = next;
|
|
144
|
+
}
|
|
145
|
+
if (front.name !== skillName ||
|
|
146
|
+
typeof front.description !== "string" ||
|
|
147
|
+
!front.description.startsWith("Trigger:") ||
|
|
148
|
+
front.description.length > 250 ||
|
|
149
|
+
front.license !== "MIT" ||
|
|
150
|
+
!metadata ||
|
|
151
|
+
typeof metadata !== "object" ||
|
|
152
|
+
Array.isArray(metadata) ||
|
|
153
|
+
!("author" in metadata) ||
|
|
154
|
+
!("version" in metadata) ||
|
|
155
|
+
typeof metadata.author !== "string" ||
|
|
156
|
+
typeof metadata.version !== "string") {
|
|
157
|
+
throw new Error(`Invalid skill resource: ${skillName}`);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
const DEFAULT_TIMEOUT_MS = 900_000;
|
|
161
|
+
const DEFAULT_OUTPUT_TOKENS = 16_000;
|
|
162
|
+
const stringList = (value) => Array.isArray(value) ? value.map((item) => String(item)) : [];
|
|
163
|
+
function positive(value, fallback) {
|
|
164
|
+
return typeof value === "number" && Number.isInteger(value) && value > 0 ? value : fallback;
|
|
165
|
+
}
|
|
166
|
+
function level(value, label, role) {
|
|
167
|
+
// `ask` is never declared: a headless child would block on it (Phase 0 item, spec 16.1).
|
|
168
|
+
if (value === "allow" || value === "deny")
|
|
169
|
+
return value;
|
|
170
|
+
throw new Error(`Invalid agent resource: ${role} (permission.${label})`);
|
|
171
|
+
}
|
|
172
|
+
/** Everything a runner needs to start a child session for one agent. */
|
|
173
|
+
export async function loadAgentProfile(role) {
|
|
174
|
+
if (!isResourceRole(role))
|
|
175
|
+
throw new Error(`Unknown swarm role resource: ${String(role)}`);
|
|
176
|
+
const agent = await load(`../.agents/agents/${role}.md`);
|
|
177
|
+
const instructions = await loadRoleInstructions(role);
|
|
178
|
+
const front = agent.frontmatter;
|
|
179
|
+
const permission = front.permission;
|
|
180
|
+
return {
|
|
181
|
+
name: role,
|
|
182
|
+
instructions,
|
|
183
|
+
tools: stringList(front.tools),
|
|
184
|
+
disallowedTools: stringList(front.disallowedTools),
|
|
185
|
+
mode: front.mode === "primary" ? "primary" : "subagent",
|
|
186
|
+
maxTurns: positive(front.maxTurns, 20),
|
|
187
|
+
timeoutMs: positive(front.timeoutMs, DEFAULT_TIMEOUT_MS),
|
|
188
|
+
maxOutputTokens: positive(front.maxOutputTokens, DEFAULT_OUTPUT_TOKENS),
|
|
189
|
+
readOnly: front.readOnly === true,
|
|
190
|
+
permission: {
|
|
191
|
+
write: level(permission.write, "write", role),
|
|
192
|
+
process: level(permission.process, "process", role),
|
|
193
|
+
},
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
/** Agent body plus every loaded skill body: the same files registered with the host. */
|
|
197
|
+
export async function loadRoleInstructions(role) {
|
|
198
|
+
if (!isResourceRole(role))
|
|
199
|
+
throw new Error(`Unknown swarm role resource: ${String(role)}`);
|
|
200
|
+
const skillNames = roleSkills[role];
|
|
201
|
+
const [agent, ...skills] = await Promise.all([
|
|
202
|
+
load(`../.agents/agents/${role}.md`),
|
|
203
|
+
...skillNames.map((skillName) => load(`../.agents/skills/${skillName}/SKILL.md`)),
|
|
204
|
+
]);
|
|
205
|
+
validateAgent(agent, role, skillNames);
|
|
206
|
+
for (const [index, skill] of skills.entries()) {
|
|
207
|
+
validateSkill(skill, skillNames[index]);
|
|
208
|
+
}
|
|
209
|
+
return [
|
|
210
|
+
agent.body,
|
|
211
|
+
...skills.flatMap((skill, index) => [`# Loaded skill: ${skillNames[index]}`, skill.body]),
|
|
212
|
+
].join("\n\n");
|
|
213
|
+
}
|
|
214
|
+
const packNamePattern = /^[a-z0-9][a-z0-9-]{0,47}$/;
|
|
215
|
+
export async function listShippedPacks() {
|
|
216
|
+
const entries = await readdir(url("../assets/packs"), { withFileTypes: true });
|
|
217
|
+
return entries
|
|
218
|
+
.filter((entry) => entry.isDirectory())
|
|
219
|
+
.map((entry) => entry.name)
|
|
220
|
+
.sort();
|
|
221
|
+
}
|
|
222
|
+
export async function loadShippedPack(name) {
|
|
223
|
+
if (!packNamePattern.test(name))
|
|
224
|
+
throw new Error("Invalid pack name");
|
|
225
|
+
if (!(await listShippedPacks()).includes(name))
|
|
226
|
+
throw new Error(`Unknown shipped pack: ${name}`);
|
|
227
|
+
const pack = parsePack(JSON.parse(await readFile(url(`../assets/packs/${name}/pack.json`), "utf8")));
|
|
228
|
+
if (pack.name !== name)
|
|
229
|
+
throw new Error(`Shipped pack ${name} declares a different name`);
|
|
230
|
+
return pack;
|
|
231
|
+
}
|
|
232
|
+
export async function loadToolchain(id) {
|
|
233
|
+
if (!/^[a-z][a-z0-9-]{0,31}$/.test(id))
|
|
234
|
+
throw new Error("Invalid toolchain id");
|
|
235
|
+
let raw;
|
|
236
|
+
try {
|
|
237
|
+
raw = await readFile(url(`../assets/toolchains/${id}.json`), "utf8");
|
|
238
|
+
}
|
|
239
|
+
catch {
|
|
240
|
+
throw new Error(`Unknown toolchain: ${id}`);
|
|
241
|
+
}
|
|
242
|
+
const profile = parseToolchain(JSON.parse(raw));
|
|
243
|
+
if (profile.id !== id)
|
|
244
|
+
throw new Error(`Toolchain ${id} declares a different id`);
|
|
245
|
+
return profile;
|
|
246
|
+
}
|
|
247
|
+
export const dashboardAssets = ["dashboard.html", "dashboard.css", "dashboard.js"];
|
|
248
|
+
/** A static dashboard file shipped in `assets/`, read relative to the built entry. */
|
|
249
|
+
export async function loadDashboardAsset(name) {
|
|
250
|
+
if (!dashboardAssets.includes(name)) {
|
|
251
|
+
throw new Error(`Unknown dashboard asset: ${name}`);
|
|
252
|
+
}
|
|
253
|
+
return readFile(url(`../assets/${name}`), "utf8");
|
|
254
|
+
}
|
|
255
|
+
//# sourceMappingURL=resources.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resources.js","sourceRoot":"","sources":["../src/resources.ts"],"names":[],"mappings":"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"}
|
package/dist/status.d.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { UiBlock } from "@alisio/sdk";
|
|
2
|
+
import type { AttentionItem } from "./domain/attention.js";
|
|
3
|
+
import { type Pack } from "./domain/pack.js";
|
|
4
|
+
import type { Board } from "./domain/task.js";
|
|
5
|
+
export interface ProjectSnapshot {
|
|
6
|
+
name: string;
|
|
7
|
+
open: boolean;
|
|
8
|
+
running: boolean;
|
|
9
|
+
pack: Pack | undefined;
|
|
10
|
+
board: Board | undefined;
|
|
11
|
+
attention: AttentionItem[];
|
|
12
|
+
}
|
|
13
|
+
export interface RenderedStatus {
|
|
14
|
+
text: string;
|
|
15
|
+
blocks: UiBlock[];
|
|
16
|
+
}
|
|
17
|
+
export declare function renderStatus(projects: ProjectSnapshot[]): RenderedStatus;
|
|
18
|
+
//# sourceMappingURL=status.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../src/status.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EAAE,KAAK,IAAI,EAAW,MAAM,kBAAkB,CAAC;AACtD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAE9C,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,IAAI,GAAG,SAAS,CAAC;IACvB,KAAK,EAAE,KAAK,GAAG,SAAS,CAAC;IACzB,SAAS,EAAE,aAAa,EAAE,CAAC;CAC5B;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,OAAO,EAAE,CAAC;CACnB;AASD,wBAAgB,YAAY,CAAC,QAAQ,EAAE,eAAe,EAAE,GAAG,cAAc,CAmDxE"}
|
package/dist/status.js
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { roleIds } from "./domain/pack.js";
|
|
2
|
+
/** Role ids are validated identifiers, so they are safe inside a diagram; task text never is. */
|
|
3
|
+
const diagram = (pack) => ({
|
|
4
|
+
kind: "mermaid",
|
|
5
|
+
source: `flowchart LR\n ${[...roleIds(pack), "done"].join(" --> ")}`,
|
|
6
|
+
title: pack.name,
|
|
7
|
+
});
|
|
8
|
+
export function renderStatus(projects) {
|
|
9
|
+
if (projects.length === 0) {
|
|
10
|
+
return {
|
|
11
|
+
text: "No projects yet. Create one with /swarm:project new <name> -- <mission>.",
|
|
12
|
+
blocks: [],
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
const lines = [];
|
|
16
|
+
const blocks = [];
|
|
17
|
+
for (const project of projects) {
|
|
18
|
+
const state = project.running ? "running" : project.open ? "open, not running" : "closed";
|
|
19
|
+
lines.push(`${project.name} (${project.pack?.name ?? "unknown pack"}, ${state})`);
|
|
20
|
+
const tasks = project.board?.tasks ?? [];
|
|
21
|
+
if (project.pack) {
|
|
22
|
+
const counts = roleIds(project.pack).map((role) => {
|
|
23
|
+
const here = tasks.filter((task) => task.lane === role && task.status !== "done");
|
|
24
|
+
return `${role}: ${here.length}`;
|
|
25
|
+
});
|
|
26
|
+
lines.push(` ${counts.join(" | ")} | done: ${tasks.filter((t) => t.status === "done").length}`);
|
|
27
|
+
}
|
|
28
|
+
for (const task of tasks) {
|
|
29
|
+
lines.push(` - ${task.name} [${task.lane}] ${task.status} (audits ${task.auditCount})`);
|
|
30
|
+
}
|
|
31
|
+
if (project.attention.length > 0) {
|
|
32
|
+
lines.push(" Needs your attention:");
|
|
33
|
+
for (const item of project.attention) {
|
|
34
|
+
lines.push(` - ${item.kind}: ${item.task} (${item.actions.join(", ")})`);
|
|
35
|
+
if (item.detail)
|
|
36
|
+
lines.push(` ${item.detail.split("\n")[0]}`);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
if (tasks.length > 0) {
|
|
40
|
+
blocks.push({
|
|
41
|
+
kind: "table",
|
|
42
|
+
caption: project.name,
|
|
43
|
+
columns: ["Task", "Lane", "Status", "Audits"],
|
|
44
|
+
rows: tasks.map((task) => [task.name, task.lane, task.status, String(task.auditCount)]),
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
if (project.attention.length > 0) {
|
|
48
|
+
blocks.push({
|
|
49
|
+
kind: "table",
|
|
50
|
+
caption: `${project.name}: needs your attention`,
|
|
51
|
+
columns: ["Kind", "Task", "Actions"],
|
|
52
|
+
rows: project.attention.map((item) => [item.kind, item.task, item.actions.join(", ")]),
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
if (project.pack)
|
|
56
|
+
blocks.push(diagram(project.pack));
|
|
57
|
+
}
|
|
58
|
+
return { text: lines.join("\n"), blocks };
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=status.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status.js","sourceRoot":"","sources":["../src/status.ts"],"names":[],"mappings":"AAEA,OAAO,EAAa,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAiBtD,iGAAiG;AACjG,MAAM,OAAO,GAAG,CAAC,IAAU,EAAW,EAAE,CAAC,CAAC;IACxC,IAAI,EAAE,SAAS;IACf,MAAM,EAAE,mBAAmB,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE;IACrE,KAAK,EAAE,IAAI,CAAC,IAAI;CACjB,CAAC,CAAC;AAEH,MAAM,UAAU,YAAY,CAAC,QAA2B;IACtD,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,OAAO;YACL,IAAI,EAAE,0EAA0E;YAChF,MAAM,EAAE,EAAE;SACX,CAAC;IACJ,CAAC;IACD,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,MAAM,MAAM,GAAc,EAAE,CAAC;IAC7B,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,QAAQ,CAAC;QAC1F,KAAK,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,KAAK,OAAO,CAAC,IAAI,EAAE,IAAI,IAAI,cAAc,KAAK,KAAK,GAAG,CAAC,CAAC;QAClF,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,EAAE,KAAK,IAAI,EAAE,CAAC;QACzC,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;YACjB,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;gBAChD,MAAM,IAAI,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,IAAI,IAAI,IAAI,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC;gBAClF,OAAO,GAAG,IAAI,KAAK,IAAI,CAAC,MAAM,EAAE,CAAC;YACnC,CAAC,CAAC,CAAC;YACH,KAAK,CAAC,IAAI,CACR,KAAK,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,YAAY,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,MAAM,EAAE,CACrF,CAAC;QACJ,CAAC;QACD,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,KAAK,CAAC,IAAI,CAAC,OAAO,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,MAAM,YAAY,IAAI,CAAC,UAAU,GAAG,CAAC,CAAC;QAC3F,CAAC;QACD,IAAI,OAAO,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACjC,KAAK,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC;YACtC,KAAK,MAAM,IAAI,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;gBACrC,KAAK,CAAC,IAAI,CAAC,OAAO,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;gBAC1E,IAAI,IAAI,CAAC,MAAM;oBAAE,KAAK,CAAC,IAAI,CAAC,OAAO,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YACnE,CAAC;QACH,CAAC;QACD,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACrB,MAAM,CAAC,IAAI,CAAC;gBACV,IAAI,EAAE,OAAO;gBACb,OAAO,EAAE,OAAO,CAAC,IAAI;gBACrB,OAAO,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,CAAC;gBAC7C,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;aACxF,CAAC,CAAC;QACL,CAAC;QACD,IAAI,OAAO,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACjC,MAAM,CAAC,IAAI,CAAC;gBACV,IAAI,EAAE,OAAO;gBACb,OAAO,EAAE,GAAG,OAAO,CAAC,IAAI,wBAAwB;gBAChD,OAAO,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,CAAC;gBACpC,IAAI,EAAE,OAAO,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;aACvF,CAAC,CAAC;QACL,CAAC;QACD,IAAI,OAAO,CAAC,IAAI;YAAE,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;IACvD,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;AAC5C,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { assertRelativePath } from "./domain/identifiers.js";
|
|
2
|
+
export { assertRelativePath };
|
|
3
|
+
/** Atomic durable write: private temp file in the target directory, then rename (mode 0600). */
|
|
4
|
+
export declare function atomicWrite(path: string, content: string): Promise<void>;
|
|
5
|
+
export declare function readText(path: string): Promise<string | undefined>;
|
|
6
|
+
/**
|
|
7
|
+
* Resolve a relative path under `root`, refusing `..` and any symlink that leads outside it.
|
|
8
|
+
* The deepest existing ancestor is resolved with `realpath`, so a not-yet-created file is safe too.
|
|
9
|
+
*/
|
|
10
|
+
export declare function resolveContained(root: string, relative: string): Promise<string>;
|
|
11
|
+
/** Serialises async work per instance (single writer per file within the process, AD-11). */
|
|
12
|
+
export declare class Mutex {
|
|
13
|
+
private tail;
|
|
14
|
+
run<T>(task: () => Promise<T>): Promise<T>;
|
|
15
|
+
}
|
|
16
|
+
/** Append missing lines to a `.gitignore`, idempotently. */
|
|
17
|
+
export declare function ensureIgnoreEntries(file: string, entries: string[]): Promise<boolean>;
|
|
18
|
+
//# sourceMappingURL=storage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../src/storage.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAE7D,OAAO,EAAE,kBAAkB,EAAE,CAAC;AAE9B,gGAAgG;AAChG,wBAAsB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAU9E;AAED,wBAAsB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAOxE;AAKD;;;GAGG;AACH,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAoBtF;AAED,6FAA6F;AAC7F,qBAAa,KAAK;IAChB,OAAO,CAAC,IAAI,CAAuC;IAEnD,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAIzC;CACF;AAED,4DAA4D;AAC5D,wBAAsB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAQ3F"}
|
package/dist/storage.js
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import { mkdir, readFile, realpath, rename, rm, writeFile } from "node:fs/promises";
|
|
3
|
+
import { dirname, join, resolve, sep } from "node:path";
|
|
4
|
+
import { assertRelativePath } from "./domain/identifiers.js";
|
|
5
|
+
export { assertRelativePath };
|
|
6
|
+
/** Atomic durable write: private temp file in the target directory, then rename (mode 0600). */
|
|
7
|
+
export async function atomicWrite(path, content) {
|
|
8
|
+
await mkdir(dirname(path), { recursive: true, mode: 0o700 });
|
|
9
|
+
const temporary = join(dirname(path), `.${randomUUID()}.tmp`);
|
|
10
|
+
try {
|
|
11
|
+
await writeFile(temporary, content, { encoding: "utf8", flag: "wx", mode: 0o600 });
|
|
12
|
+
await rename(temporary, path);
|
|
13
|
+
}
|
|
14
|
+
catch (error) {
|
|
15
|
+
await rm(temporary, { force: true });
|
|
16
|
+
throw error;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
export async function readText(path) {
|
|
20
|
+
try {
|
|
21
|
+
return await readFile(path, "utf8");
|
|
22
|
+
}
|
|
23
|
+
catch (error) {
|
|
24
|
+
if (error.code === "ENOENT")
|
|
25
|
+
return undefined;
|
|
26
|
+
throw error;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
const within = (root, candidate) => candidate === root || candidate.startsWith(`${root}${sep}`);
|
|
30
|
+
/**
|
|
31
|
+
* Resolve a relative path under `root`, refusing `..` and any symlink that leads outside it.
|
|
32
|
+
* The deepest existing ancestor is resolved with `realpath`, so a not-yet-created file is safe too.
|
|
33
|
+
*/
|
|
34
|
+
export async function resolveContained(root, relative) {
|
|
35
|
+
assertRelativePath(relative);
|
|
36
|
+
const base = resolve(root);
|
|
37
|
+
const target = resolve(base, relative);
|
|
38
|
+
if (!within(base, target))
|
|
39
|
+
throw new Error(`Path escapes its root: ${relative}`);
|
|
40
|
+
const realBase = await realpath(base);
|
|
41
|
+
let probe = target;
|
|
42
|
+
for (;;) {
|
|
43
|
+
try {
|
|
44
|
+
const real = await realpath(probe);
|
|
45
|
+
if (!within(realBase, real))
|
|
46
|
+
throw new Error(`Path escapes its root through a symlink: ${relative}`);
|
|
47
|
+
return target;
|
|
48
|
+
}
|
|
49
|
+
catch (error) {
|
|
50
|
+
if (error.code !== "ENOENT")
|
|
51
|
+
throw error;
|
|
52
|
+
const parent = dirname(probe);
|
|
53
|
+
if (parent === probe || !within(base, parent))
|
|
54
|
+
return target;
|
|
55
|
+
probe = parent;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
/** Serialises async work per instance (single writer per file within the process, AD-11). */
|
|
60
|
+
export class Mutex {
|
|
61
|
+
tail = Promise.resolve();
|
|
62
|
+
run(task) {
|
|
63
|
+
const result = this.tail.then(task, task);
|
|
64
|
+
this.tail = result.catch(() => undefined);
|
|
65
|
+
return result;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
/** Append missing lines to a `.gitignore`, idempotently. */
|
|
69
|
+
export async function ensureIgnoreEntries(file, entries) {
|
|
70
|
+
const current = (await readText(file)) ?? "";
|
|
71
|
+
const present = new Set(current.split(/\r?\n/).map((line) => line.trim()));
|
|
72
|
+
const missing = entries.filter((entry) => !present.has(entry));
|
|
73
|
+
if (missing.length === 0)
|
|
74
|
+
return false;
|
|
75
|
+
const prefix = current && !current.endsWith("\n") ? "\n" : "";
|
|
76
|
+
await atomicWrite(file, `${current}${prefix}${missing.join("\n")}\n`);
|
|
77
|
+
return true;
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=storage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storage.js","sourceRoot":"","sources":["../src/storage.ts"],"names":[],"mappings":"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"}
|