@mclawnet/task 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/README.md +100 -0
- package/dist/__tests__/compute-lead-briefing.test.d.ts +2 -0
- package/dist/__tests__/compute-lead-briefing.test.d.ts.map +1 -0
- package/dist/__tests__/compute-lead-briefing.test.js +81 -0
- package/dist/__tests__/compute-lead-briefing.test.js.map +1 -0
- package/dist/__tests__/compute-member-briefing.test.d.ts +2 -0
- package/dist/__tests__/compute-member-briefing.test.d.ts.map +1 -0
- package/dist/__tests__/compute-member-briefing.test.js +36 -0
- package/dist/__tests__/compute-member-briefing.test.js.map +1 -0
- package/dist/__tests__/compute-task-briefing.test.d.ts +2 -0
- package/dist/__tests__/compute-task-briefing.test.d.ts.map +1 -0
- package/dist/__tests__/compute-task-briefing.test.js +72 -0
- package/dist/__tests__/compute-task-briefing.test.js.map +1 -0
- package/dist/__tests__/dag.test.d.ts +2 -0
- package/dist/__tests__/dag.test.d.ts.map +1 -0
- package/dist/__tests__/dag.test.js +81 -0
- package/dist/__tests__/dag.test.js.map +1 -0
- package/dist/__tests__/format-lead-briefing.test.d.ts +2 -0
- package/dist/__tests__/format-lead-briefing.test.d.ts.map +1 -0
- package/dist/__tests__/format-lead-briefing.test.js +70 -0
- package/dist/__tests__/format-lead-briefing.test.js.map +1 -0
- package/dist/__tests__/format-member-briefing.test.d.ts +2 -0
- package/dist/__tests__/format-member-briefing.test.d.ts.map +1 -0
- package/dist/__tests__/format-member-briefing.test.js +33 -0
- package/dist/__tests__/format-member-briefing.test.js.map +1 -0
- package/dist/__tests__/format-task-briefing.test.d.ts +2 -0
- package/dist/__tests__/format-task-briefing.test.d.ts.map +1 -0
- package/dist/__tests__/format-task-briefing.test.js +74 -0
- package/dist/__tests__/format-task-briefing.test.js.map +1 -0
- package/dist/__tests__/locking.test.d.ts +2 -0
- package/dist/__tests__/locking.test.d.ts.map +1 -0
- package/dist/__tests__/locking.test.js +38 -0
- package/dist/__tests__/locking.test.js.map +1 -0
- package/dist/__tests__/meta.test.d.ts +2 -0
- package/dist/__tests__/meta.test.d.ts.map +1 -0
- package/dist/__tests__/meta.test.js +48 -0
- package/dist/__tests__/meta.test.js.map +1 -0
- package/dist/__tests__/path.test.d.ts +2 -0
- package/dist/__tests__/path.test.d.ts.map +1 -0
- package/dist/__tests__/path.test.js +45 -0
- package/dist/__tests__/path.test.js.map +1 -0
- package/dist/__tests__/schema.test.d.ts +2 -0
- package/dist/__tests__/schema.test.d.ts.map +1 -0
- package/dist/__tests__/schema.test.js +49 -0
- package/dist/__tests__/schema.test.js.map +1 -0
- package/dist/__tests__/store-create-deps.test.d.ts +2 -0
- package/dist/__tests__/store-create-deps.test.d.ts.map +1 -0
- package/dist/__tests__/store-create-deps.test.js +23 -0
- package/dist/__tests__/store-create-deps.test.js.map +1 -0
- package/dist/__tests__/store-link.test.d.ts +2 -0
- package/dist/__tests__/store-link.test.d.ts.map +1 -0
- package/dist/__tests__/store-link.test.js +64 -0
- package/dist/__tests__/store-link.test.js.map +1 -0
- package/dist/__tests__/store-rebuild.test.d.ts +2 -0
- package/dist/__tests__/store-rebuild.test.d.ts.map +1 -0
- package/dist/__tests__/store-rebuild.test.js +47 -0
- package/dist/__tests__/store-rebuild.test.js.map +1 -0
- package/dist/__tests__/store.test.d.ts +2 -0
- package/dist/__tests__/store.test.d.ts.map +1 -0
- package/dist/__tests__/store.test.js +70 -0
- package/dist/__tests__/store.test.js.map +1 -0
- package/dist/briefings/compute-lead.d.ts +17 -0
- package/dist/briefings/compute-lead.d.ts.map +1 -0
- package/dist/briefings/compute-lead.js +52 -0
- package/dist/briefings/compute-lead.js.map +1 -0
- package/dist/briefings/compute-member.d.ts +12 -0
- package/dist/briefings/compute-member.d.ts.map +1 -0
- package/dist/briefings/compute-member.js +30 -0
- package/dist/briefings/compute-member.js.map +1 -0
- package/dist/briefings/compute-task.d.ts +17 -0
- package/dist/briefings/compute-task.d.ts.map +1 -0
- package/dist/briefings/compute-task.js +60 -0
- package/dist/briefings/compute-task.js.map +1 -0
- package/dist/briefings/format-lead.d.ts +19 -0
- package/dist/briefings/format-lead.d.ts.map +1 -0
- package/dist/briefings/format-lead.js +47 -0
- package/dist/briefings/format-lead.js.map +1 -0
- package/dist/briefings/format-member.d.ts +18 -0
- package/dist/briefings/format-member.d.ts.map +1 -0
- package/dist/briefings/format-member.js +24 -0
- package/dist/briefings/format-member.js.map +1 -0
- package/dist/briefings/format-task.d.ts +19 -0
- package/dist/briefings/format-task.d.ts.map +1 -0
- package/dist/briefings/format-task.js +48 -0
- package/dist/briefings/format-task.js.map +1 -0
- package/dist/dag.d.ts +10 -0
- package/dist/dag.d.ts.map +1 -0
- package/dist/dag.js +33 -0
- package/dist/dag.js.map +1 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +13 -0
- package/dist/index.js.map +1 -0
- package/dist/locking.d.ts +8 -0
- package/dist/locking.d.ts.map +1 -0
- package/dist/locking.js +19 -0
- package/dist/locking.js.map +1 -0
- package/dist/meta.d.ts +21 -0
- package/dist/meta.d.ts.map +1 -0
- package/dist/meta.js +37 -0
- package/dist/meta.js.map +1 -0
- package/dist/path.d.ts +7 -0
- package/dist/path.d.ts.map +1 -0
- package/dist/path.js +34 -0
- package/dist/path.js.map +1 -0
- package/dist/schema.d.ts +42 -0
- package/dist/schema.d.ts.map +1 -0
- package/dist/schema.js +41 -0
- package/dist/schema.js.map +1 -0
- package/dist/store.d.ts +47 -0
- package/dist/store.d.ts.map +1 -0
- package/dist/store.js +248 -0
- package/dist/store.js.map +1 -0
- package/package.json +33 -0
package/README.md
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
# @mclawnet/task
|
|
2
|
+
|
|
3
|
+
Task as first-class — file-backed task store with DAG dependencies (任务持久化层).
|
|
4
|
+
|
|
5
|
+
Tasks live on disk as one JSON file per task plus a flat `index.json` for fast
|
|
6
|
+
listing. Mutations are serialized through an exclusive lock on the index file,
|
|
7
|
+
so multi-process callers (CLI, daemon, swarm coordinator) can safely share the
|
|
8
|
+
same project directory.
|
|
9
|
+
|
|
10
|
+
## Persistence layout
|
|
11
|
+
|
|
12
|
+
All data is rooted under the per-project directory:
|
|
13
|
+
|
|
14
|
+
```
|
|
15
|
+
~/.clawnet/projects/<encoded-cwd>/
|
|
16
|
+
tasks/
|
|
17
|
+
index.json # { version: 1, tasks: { [id]: IndexEntry } }
|
|
18
|
+
<task-id>.json # one file per task
|
|
19
|
+
meta.json
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
`<encoded-cwd>` is the absolute working directory with `/` replaced by `-`
|
|
23
|
+
(e.g. `/Users/alice/code/foo` → `-Users-alice-code-foo`). See `encodeCwd()`
|
|
24
|
+
in `path.ts`.
|
|
25
|
+
|
|
26
|
+
## API
|
|
27
|
+
|
|
28
|
+
### TaskStore
|
|
29
|
+
|
|
30
|
+
```ts
|
|
31
|
+
class TaskStore {
|
|
32
|
+
constructor(opts: { workDir: string; home?: string });
|
|
33
|
+
|
|
34
|
+
create(input: CreateInput): Promise<Task>;
|
|
35
|
+
get(id: string): Task; // throws if missing
|
|
36
|
+
tryGet(id: string): Task | null;
|
|
37
|
+
update(id: string, patch: Partial<Task>): Promise<Task>;
|
|
38
|
+
// update() refuses to touch blockedBy/blocks — use link()/unlink().
|
|
39
|
+
|
|
40
|
+
addComment(id: string, comment: TaskComment): Promise<void>;
|
|
41
|
+
list(): IndexEntry[]; // reads index.json
|
|
42
|
+
rebuildIndex(): Promise<void>; // recover index from task files
|
|
43
|
+
|
|
44
|
+
link(fromId: string, toId: string): Promise<void>; // fromId blockedBy toId
|
|
45
|
+
unlink(fromId: string, toId: string): Promise<void>;
|
|
46
|
+
}
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
`link()` rejects edges that would form a cycle and self-heals half-written
|
|
50
|
+
edges from a previous crash.
|
|
51
|
+
|
|
52
|
+
### DAG helpers
|
|
53
|
+
|
|
54
|
+
```ts
|
|
55
|
+
function wouldCreateCycle(store: TaskStore, fromId: string, toId: string): boolean;
|
|
56
|
+
|
|
57
|
+
function classifyBlockers(task: Task, store: TaskStore): {
|
|
58
|
+
broken: string[]; // dependency missing or cancelled
|
|
59
|
+
waiting: string[]; // dependency exists but not completed
|
|
60
|
+
isBlocked: boolean;
|
|
61
|
+
};
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### Path helpers
|
|
65
|
+
|
|
66
|
+
```ts
|
|
67
|
+
function encodeCwd(absPath: string): string;
|
|
68
|
+
function projectRoot(workDir: string, home?: string): string;
|
|
69
|
+
function tasksDir(workDir: string, home?: string): string;
|
|
70
|
+
function taskFile(workDir: string, taskId: string, home?: string): string;
|
|
71
|
+
function indexFile(workDir: string, home?: string): string;
|
|
72
|
+
function metaFile(workDir: string, home?: string): string;
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Other packages (notably `@mclawnet/swarm`) reuse `projectRoot()` so all
|
|
76
|
+
per-project state stays under the same encoded folder.
|
|
77
|
+
|
|
78
|
+
## Example
|
|
79
|
+
|
|
80
|
+
```ts
|
|
81
|
+
import { TaskStore, classifyBlockers } from "@mclawnet/task";
|
|
82
|
+
|
|
83
|
+
const store = new TaskStore({ workDir: process.cwd() });
|
|
84
|
+
|
|
85
|
+
const root = await store.create({
|
|
86
|
+
teamName: "alpha",
|
|
87
|
+
subject: "Ship Phase 1",
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
const child = await store.create({
|
|
91
|
+
teamName: "alpha",
|
|
92
|
+
subject: "Wire CLI",
|
|
93
|
+
blockedBy: [root.id],
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
const status = classifyBlockers(child, store);
|
|
97
|
+
console.log(status.isBlocked, status.waiting); // true, [root.id]
|
|
98
|
+
|
|
99
|
+
await store.update(root.id, { status: "completed" });
|
|
100
|
+
```
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compute-lead-briefing.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/compute-lead-briefing.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach } from "vitest";
|
|
2
|
+
import { mkdtempSync } from "node:fs";
|
|
3
|
+
import { tmpdir } from "node:os";
|
|
4
|
+
import { join } from "node:path";
|
|
5
|
+
import { TaskStore } from "../store.js";
|
|
6
|
+
import { computeLeadBriefing } from "../briefings/compute-lead.js";
|
|
7
|
+
function makeStore() {
|
|
8
|
+
const home = mkdtempSync(join(tmpdir(), "compute-lead-briefing-"));
|
|
9
|
+
return new TaskStore({ workDir: "/Users/test/proj", home });
|
|
10
|
+
}
|
|
11
|
+
describe("computeLeadBriefing", () => {
|
|
12
|
+
let store;
|
|
13
|
+
beforeEach(() => {
|
|
14
|
+
store = makeStore();
|
|
15
|
+
});
|
|
16
|
+
it("returns empty buckets when nothing matches", () => {
|
|
17
|
+
const body = computeLeadBriefing(store, "s1", null);
|
|
18
|
+
expect(body.assign_owner).toEqual([]);
|
|
19
|
+
expect(body.assign_reviewer).toEqual([]);
|
|
20
|
+
expect(body.clarify).toEqual([]);
|
|
21
|
+
expect(body.repair_dependencies).toEqual([]);
|
|
22
|
+
expect(body.lead_owned).toEqual([]);
|
|
23
|
+
});
|
|
24
|
+
it("buckets assign_owner, clarify, repair_dependencies and lead_owned correctly", async () => {
|
|
25
|
+
const orphan = await store.create({
|
|
26
|
+
teamName: "team1",
|
|
27
|
+
subject: "needs owner",
|
|
28
|
+
swarmId: "s1",
|
|
29
|
+
});
|
|
30
|
+
const queenOwned = await store.create({
|
|
31
|
+
teamName: "team1",
|
|
32
|
+
subject: "queen-owned",
|
|
33
|
+
swarmId: "s1",
|
|
34
|
+
owner: "queen-0",
|
|
35
|
+
});
|
|
36
|
+
const cancelled = await store.create({
|
|
37
|
+
teamName: "team1",
|
|
38
|
+
subject: "cancel-me",
|
|
39
|
+
swarmId: "s1",
|
|
40
|
+
});
|
|
41
|
+
const broken = await store.create({
|
|
42
|
+
teamName: "team1",
|
|
43
|
+
subject: "needs repair",
|
|
44
|
+
swarmId: "s1",
|
|
45
|
+
owner: "queen-0",
|
|
46
|
+
blockedBy: [cancelled.id],
|
|
47
|
+
});
|
|
48
|
+
await store.update(cancelled.id, { status: "cancelled" });
|
|
49
|
+
const clarifying = await store.create({
|
|
50
|
+
teamName: "team1",
|
|
51
|
+
subject: "clarify-me",
|
|
52
|
+
swarmId: "s1",
|
|
53
|
+
owner: "queen-0",
|
|
54
|
+
});
|
|
55
|
+
await store.addComment(clarifying.id, {
|
|
56
|
+
id: "q-1",
|
|
57
|
+
author: "worker-0",
|
|
58
|
+
type: "note",
|
|
59
|
+
body: "what should we do here?",
|
|
60
|
+
});
|
|
61
|
+
// Noise: a different swarm.
|
|
62
|
+
await store.create({ teamName: "team1", subject: "other", swarmId: "s2" });
|
|
63
|
+
const body = computeLeadBriefing(store, "s1", "queen-0");
|
|
64
|
+
expect(body.assign_owner.map((t) => t.id)).toContain(orphan.id);
|
|
65
|
+
expect(body.assign_reviewer).toEqual([]);
|
|
66
|
+
expect(body.clarify.map((t) => t.id)).toContain(clarifying.id);
|
|
67
|
+
expect(body.repair_dependencies.map((t) => t.id)).toContain(broken.id);
|
|
68
|
+
expect(body.lead_owned.map((t) => t.id).sort()).toEqual([queenOwned.id, broken.id, clarifying.id].sort());
|
|
69
|
+
});
|
|
70
|
+
it("lead_owned is empty when queenInstanceId is null", async () => {
|
|
71
|
+
await store.create({
|
|
72
|
+
teamName: "team1",
|
|
73
|
+
subject: "queen-owned",
|
|
74
|
+
swarmId: "s1",
|
|
75
|
+
owner: "queen-0",
|
|
76
|
+
});
|
|
77
|
+
const body = computeLeadBriefing(store, "s1", null);
|
|
78
|
+
expect(body.lead_owned).toEqual([]);
|
|
79
|
+
});
|
|
80
|
+
});
|
|
81
|
+
//# sourceMappingURL=compute-lead-briefing.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compute-lead-briefing.test.js","sourceRoot":"","sources":["../../src/__tests__/compute-lead-briefing.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compute-member-briefing.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/compute-member-briefing.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
import { computeMemberBriefing } from "../briefings/compute-member.js";
|
|
3
|
+
describe("computeMemberBriefing", () => {
|
|
4
|
+
it("returns queen-flavoured rules when roleType=queen", () => {
|
|
5
|
+
const body = computeMemberBriefing({
|
|
6
|
+
swarmId: "s1",
|
|
7
|
+
instanceId: "queen-0",
|
|
8
|
+
roleType: "queen",
|
|
9
|
+
});
|
|
10
|
+
expect(body.bootstrap).toEqual({
|
|
11
|
+
swarmId: "s1",
|
|
12
|
+
instanceId: "queen-0",
|
|
13
|
+
roleType: "queen",
|
|
14
|
+
});
|
|
15
|
+
expect(body.rules.length).toBeGreaterThan(0);
|
|
16
|
+
expect(body.rules[0]).toContain("lead_briefing");
|
|
17
|
+
});
|
|
18
|
+
it("returns worker-flavoured rules when roleType is anything else", () => {
|
|
19
|
+
const body = computeMemberBriefing({
|
|
20
|
+
swarmId: "s1",
|
|
21
|
+
instanceId: "worker-0",
|
|
22
|
+
roleType: "worker",
|
|
23
|
+
});
|
|
24
|
+
expect(body.bootstrap.roleType).toBe("worker");
|
|
25
|
+
expect(body.rules[0]).toContain("task_briefing");
|
|
26
|
+
// Sanity: worker rule list should not contain the queen-only assign-owner rule.
|
|
27
|
+
expect(body.rules.some((r) => r.includes("task_set_owner"))).toBe(false);
|
|
28
|
+
});
|
|
29
|
+
it("rules array is a fresh copy (mutating it does not affect later calls)", () => {
|
|
30
|
+
const a = computeMemberBriefing({ swarmId: "s1", instanceId: "q-0", roleType: "queen" });
|
|
31
|
+
a.rules.push("INJECTED");
|
|
32
|
+
const b = computeMemberBriefing({ swarmId: "s1", instanceId: "q-1", roleType: "queen" });
|
|
33
|
+
expect(b.rules).not.toContain("INJECTED");
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
//# sourceMappingURL=compute-member-briefing.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compute-member-briefing.test.js","sourceRoot":"","sources":["../../src/__tests__/compute-member-briefing.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,qBAAqB,EAAE,MAAM,gCAAgC,CAAC;AAEvE,QAAQ,CAAC,uBAAuB,EAAE,GAAG,EAAE;IACrC,EAAE,CAAC,mDAAmD,EAAE,GAAG,EAAE;QAC3D,MAAM,IAAI,GAAG,qBAAqB,CAAC;YACjC,OAAO,EAAE,IAAI;YACb,UAAU,EAAE,SAAS;YACrB,QAAQ,EAAE,OAAO;SAClB,CAAC,CAAC;QACH,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC;YAC7B,OAAO,EAAE,IAAI;YACb,UAAU,EAAE,SAAS;YACrB,QAAQ,EAAE,OAAO;SAClB,CAAC,CAAC;QACH,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;QAC7C,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC;IACnD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+DAA+D,EAAE,GAAG,EAAE;QACvE,MAAM,IAAI,GAAG,qBAAqB,CAAC;YACjC,OAAO,EAAE,IAAI;YACb,UAAU,EAAE,UAAU;YACtB,QAAQ,EAAE,QAAQ;SACnB,CAAC,CAAC;QACH,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC/C,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC;QACjD,gFAAgF;QAChF,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC3E,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uEAAuE,EAAE,GAAG,EAAE;QAC/E,MAAM,CAAC,GAAG,qBAAqB,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC;QACzF,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QACzB,MAAM,CAAC,GAAG,qBAAqB,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC;QACzF,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;IAC5C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compute-task-briefing.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/compute-task-briefing.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach } from "vitest";
|
|
2
|
+
import { mkdtempSync } from "node:fs";
|
|
3
|
+
import { tmpdir } from "node:os";
|
|
4
|
+
import { join } from "node:path";
|
|
5
|
+
import { TaskStore } from "../store.js";
|
|
6
|
+
import { computeTaskBriefing } from "../briefings/compute-task.js";
|
|
7
|
+
function makeStore() {
|
|
8
|
+
const home = mkdtempSync(join(tmpdir(), "compute-task-briefing-"));
|
|
9
|
+
return new TaskStore({ workDir: "/Users/test/proj", home });
|
|
10
|
+
}
|
|
11
|
+
describe("computeTaskBriefing", () => {
|
|
12
|
+
let store;
|
|
13
|
+
beforeEach(() => {
|
|
14
|
+
store = makeStore();
|
|
15
|
+
});
|
|
16
|
+
it("returns empty buckets and zero counters for an empty swarm", () => {
|
|
17
|
+
const body = computeTaskBriefing(store, "s1", "dev-0");
|
|
18
|
+
expect(body.actionable).toEqual([]);
|
|
19
|
+
expect(body.awareness).toEqual([]);
|
|
20
|
+
expect(body.counters).toEqual({
|
|
21
|
+
actionable: 0,
|
|
22
|
+
awareness: 0,
|
|
23
|
+
blocked: 0,
|
|
24
|
+
waitingOnUser: 0,
|
|
25
|
+
});
|
|
26
|
+
expect(body.warnings).toEqual([]);
|
|
27
|
+
});
|
|
28
|
+
it("classifies actionable, awareness and broken-dep warnings for the owner", async () => {
|
|
29
|
+
const a = await store.create({
|
|
30
|
+
teamName: "team1",
|
|
31
|
+
subject: "actionable",
|
|
32
|
+
swarmId: "s1",
|
|
33
|
+
owner: "dev-0",
|
|
34
|
+
});
|
|
35
|
+
const dep = await store.create({ teamName: "team1", subject: "dep", swarmId: "s1" });
|
|
36
|
+
await store.create({
|
|
37
|
+
teamName: "team1",
|
|
38
|
+
subject: "awareness",
|
|
39
|
+
swarmId: "s1",
|
|
40
|
+
owner: "dev-0",
|
|
41
|
+
blockedBy: [dep.id],
|
|
42
|
+
});
|
|
43
|
+
const cancelledDep = await store.create({
|
|
44
|
+
teamName: "team1",
|
|
45
|
+
subject: "cancelled-dep",
|
|
46
|
+
swarmId: "s1",
|
|
47
|
+
});
|
|
48
|
+
const broken = await store.create({
|
|
49
|
+
teamName: "team1",
|
|
50
|
+
subject: "broken",
|
|
51
|
+
swarmId: "s1",
|
|
52
|
+
owner: "dev-0",
|
|
53
|
+
blockedBy: [cancelledDep.id],
|
|
54
|
+
});
|
|
55
|
+
await store.update(cancelledDep.id, { status: "cancelled" });
|
|
56
|
+
// Noise: another swarm should be filtered out.
|
|
57
|
+
await store.create({ teamName: "team1", subject: "other", swarmId: "s2", owner: "dev-0" });
|
|
58
|
+
const body = computeTaskBriefing(store, "s1", "dev-0");
|
|
59
|
+
expect(body.actionable.map((t) => t.id)).toEqual([a.id]);
|
|
60
|
+
expect(body.awareness.map((t) => t.subject)).toEqual(["awareness"]);
|
|
61
|
+
expect(body.warnings.some((w) => w.includes(broken.id))).toBe(true);
|
|
62
|
+
expect(body.counters.blocked).toBeGreaterThanOrEqual(1);
|
|
63
|
+
});
|
|
64
|
+
it("flags orphaned in_progress regardless of owner filter", async () => {
|
|
65
|
+
const orphan = await store.create({ teamName: "team1", subject: "orphan", swarmId: "s1" });
|
|
66
|
+
await store.update(orphan.id, { status: "in_progress" });
|
|
67
|
+
const body = computeTaskBriefing(store, "s1", "dev-0");
|
|
68
|
+
expect(body.warnings.some((w) => w.includes(orphan.id) && w.toLowerCase().includes("orphan")))
|
|
69
|
+
.toBe(true);
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
//# sourceMappingURL=compute-task-briefing.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compute-task-briefing.test.js","sourceRoot":"","sources":["../../src/__tests__/compute-task-briefing.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dag.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/dag.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach } from "vitest";
|
|
2
|
+
import { mkdtempSync, rmSync } from "node:fs";
|
|
3
|
+
import { tmpdir } from "node:os";
|
|
4
|
+
import { join } from "node:path";
|
|
5
|
+
import { TaskStore } from "../store.js";
|
|
6
|
+
import { tasksDir } from "../path.js";
|
|
7
|
+
import { wouldCreateCycle, classifyBlockers } from "../dag.js";
|
|
8
|
+
function makeStore() {
|
|
9
|
+
const home = mkdtempSync(join(tmpdir(), "task-dag-"));
|
|
10
|
+
return new TaskStore({ workDir: "/Users/test/proj", home });
|
|
11
|
+
}
|
|
12
|
+
describe("wouldCreateCycle", () => {
|
|
13
|
+
let store;
|
|
14
|
+
beforeEach(() => { store = makeStore(); });
|
|
15
|
+
it("returns false for unrelated tasks", async () => {
|
|
16
|
+
const a = await store.create({ teamName: "t", subject: "a" });
|
|
17
|
+
const b = await store.create({ teamName: "t", subject: "b" });
|
|
18
|
+
expect(wouldCreateCycle(store, a.id, b.id)).toBe(false);
|
|
19
|
+
});
|
|
20
|
+
it("detects direct self-cycle", async () => {
|
|
21
|
+
const a = await store.create({ teamName: "t", subject: "a" });
|
|
22
|
+
expect(wouldCreateCycle(store, a.id, a.id)).toBe(true);
|
|
23
|
+
});
|
|
24
|
+
it("detects indirect cycle A B C A", async () => {
|
|
25
|
+
const a = await store.create({ teamName: "t", subject: "a" });
|
|
26
|
+
const b = await store.create({ teamName: "t", subject: "b" });
|
|
27
|
+
const c = await store.create({ teamName: "t", subject: "c" });
|
|
28
|
+
await store.link(b.id, a.id); // A blocks B
|
|
29
|
+
await store.link(c.id, b.id); // B blocks C
|
|
30
|
+
expect(wouldCreateCycle(store, c.id, a.id)).toBe(true);
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
describe("classifyBlockers", () => {
|
|
34
|
+
let store;
|
|
35
|
+
beforeEach(() => { store = makeStore(); });
|
|
36
|
+
it("returns all empty when no deps", async () => {
|
|
37
|
+
const t = await store.create({ teamName: "t", subject: "x" });
|
|
38
|
+
expect(classifyBlockers(t, store)).toEqual({
|
|
39
|
+
broken: [], waiting: [], isBlocked: false,
|
|
40
|
+
});
|
|
41
|
+
});
|
|
42
|
+
it("flags missing dep as broken", async () => {
|
|
43
|
+
const a = await store.create({ teamName: "t", subject: "a" });
|
|
44
|
+
const b = await store.create({ teamName: "t", subject: "b" });
|
|
45
|
+
await store.link(b.id, a.id);
|
|
46
|
+
const home = store.opts.home;
|
|
47
|
+
rmSync(join(tasksDir("/Users/test/proj", home), `${a.id}.json`));
|
|
48
|
+
const updated = store.get(b.id);
|
|
49
|
+
const r = classifyBlockers(updated, store);
|
|
50
|
+
expect(r.broken).toEqual([a.id]);
|
|
51
|
+
expect(r.waiting).toEqual([]);
|
|
52
|
+
expect(r.isBlocked).toBe(true);
|
|
53
|
+
});
|
|
54
|
+
it("flags cancelled dep as broken", async () => {
|
|
55
|
+
const a = await store.create({ teamName: "t", subject: "a" });
|
|
56
|
+
const b = await store.create({ teamName: "t", subject: "b" });
|
|
57
|
+
await store.update(a.id, { status: "cancelled" });
|
|
58
|
+
await store.link(b.id, a.id);
|
|
59
|
+
const r = classifyBlockers(store.get(b.id), store);
|
|
60
|
+
expect(r.broken).toEqual([a.id]);
|
|
61
|
+
expect(r.isBlocked).toBe(true);
|
|
62
|
+
});
|
|
63
|
+
it("flags pending dep as waiting", async () => {
|
|
64
|
+
const a = await store.create({ teamName: "t", subject: "a" });
|
|
65
|
+
const b = await store.create({ teamName: "t", subject: "b" });
|
|
66
|
+
await store.link(b.id, a.id);
|
|
67
|
+
const r = classifyBlockers(store.get(b.id), store);
|
|
68
|
+
expect(r.waiting).toEqual([a.id]);
|
|
69
|
+
expect(r.broken).toEqual([]);
|
|
70
|
+
expect(r.isBlocked).toBe(true);
|
|
71
|
+
});
|
|
72
|
+
it("ignores completed dep", async () => {
|
|
73
|
+
const a = await store.create({ teamName: "t", subject: "a" });
|
|
74
|
+
const b = await store.create({ teamName: "t", subject: "b" });
|
|
75
|
+
await store.update(a.id, { status: "completed" });
|
|
76
|
+
await store.link(b.id, a.id);
|
|
77
|
+
const r = classifyBlockers(store.get(b.id), store);
|
|
78
|
+
expect(r.isBlocked).toBe(false);
|
|
79
|
+
});
|
|
80
|
+
});
|
|
81
|
+
//# sourceMappingURL=dag.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dag.test.js","sourceRoot":"","sources":["../../src/__tests__/dag.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format-lead-briefing.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/format-lead-briefing.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { formatLeadBriefing } from "../briefings/format-lead.js";
|
|
3
|
+
import { createEmptyTask } from "../schema.js";
|
|
4
|
+
function mkTask(id, subject) {
|
|
5
|
+
return createEmptyTask({ id, teamName: "team-a", subject });
|
|
6
|
+
}
|
|
7
|
+
function emptyBody() {
|
|
8
|
+
return {
|
|
9
|
+
assign_owner: [],
|
|
10
|
+
assign_reviewer: [],
|
|
11
|
+
clarify: [],
|
|
12
|
+
repair_dependencies: [],
|
|
13
|
+
lead_owned: [],
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
describe("formatLeadBriefing", () => {
|
|
17
|
+
it("renders the empty placeholder when all 5 buckets empty", () => {
|
|
18
|
+
expect(formatLeadBriefing(emptyBody())).toBe("### Queen 简报: 当前无待处理事项");
|
|
19
|
+
});
|
|
20
|
+
it("renders assign_owner with 1 task", () => {
|
|
21
|
+
const body = {
|
|
22
|
+
...emptyBody(),
|
|
23
|
+
assign_owner: [mkTask("T-100", "subject 1")],
|
|
24
|
+
};
|
|
25
|
+
const out = formatLeadBriefing(body);
|
|
26
|
+
expect(out).toContain("### Queen 简报");
|
|
27
|
+
expect(out).toContain("**待指派 owner (1)**");
|
|
28
|
+
expect(out).toContain("- T-100 subject 1");
|
|
29
|
+
});
|
|
30
|
+
it("renders all 4 visible buckets when populated", () => {
|
|
31
|
+
const body = {
|
|
32
|
+
assign_owner: [mkTask("T-100", "s1")],
|
|
33
|
+
assign_reviewer: [],
|
|
34
|
+
clarify: [mkTask("T-150", "s2")],
|
|
35
|
+
repair_dependencies: [mkTask("T-200", "s3")],
|
|
36
|
+
lead_owned: [mkTask("T-300", "s4")],
|
|
37
|
+
};
|
|
38
|
+
const out = formatLeadBriefing(body);
|
|
39
|
+
expect(out).toContain("**待指派 owner (1)**");
|
|
40
|
+
expect(out).toContain("**待澄清 (1)**");
|
|
41
|
+
expect(out).toContain("**待修复依赖 (1)**");
|
|
42
|
+
expect(out).toContain("**Queen 自持 (1)**");
|
|
43
|
+
});
|
|
44
|
+
it("never renders assign_reviewer even when populated", () => {
|
|
45
|
+
const body = {
|
|
46
|
+
...emptyBody(),
|
|
47
|
+
assign_owner: [mkTask("T-100", "visible task")],
|
|
48
|
+
assign_reviewer: [mkTask("T-999", "should-not-render")],
|
|
49
|
+
};
|
|
50
|
+
const out = formatLeadBriefing(body);
|
|
51
|
+
expect(out).not.toContain("T-999");
|
|
52
|
+
expect(out).not.toContain("should-not-render");
|
|
53
|
+
expect(out.toLowerCase()).not.toContain("reviewer");
|
|
54
|
+
});
|
|
55
|
+
it("truncates lead_owned when items exceed maxItems", () => {
|
|
56
|
+
const tasks = [];
|
|
57
|
+
for (let i = 0; i < 12; i++)
|
|
58
|
+
tasks.push(mkTask(`T-${i}`, `s${i}`));
|
|
59
|
+
const body = {
|
|
60
|
+
...emptyBody(),
|
|
61
|
+
lead_owned: tasks,
|
|
62
|
+
};
|
|
63
|
+
const out = formatLeadBriefing(body, { maxItems: 10 });
|
|
64
|
+
const bulletLines = out.split("\n").filter((l) => /^- T-\d+ /.test(l));
|
|
65
|
+
expect(bulletLines).toHaveLength(10);
|
|
66
|
+
expect(out).toContain("- (还有 2 项被截断)");
|
|
67
|
+
expect(out).toContain("**Queen 自持 (12)**");
|
|
68
|
+
});
|
|
69
|
+
});
|
|
70
|
+
//# sourceMappingURL=format-lead-briefing.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format-lead-briefing.test.js","sourceRoot":"","sources":["../../src/__tests__/format-lead-briefing.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format-member-briefing.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/format-member-briefing.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
import { formatMemberBriefing } from "../briefings/format-member.js";
|
|
3
|
+
describe("formatMemberBriefing", () => {
|
|
4
|
+
it("renders worker rules with header and numbered list, omits swarmId", () => {
|
|
5
|
+
const out = formatMemberBriefing({
|
|
6
|
+
rules: ["a", "b", "c"],
|
|
7
|
+
bootstrap: { swarmId: "sw1", instanceId: "worker-0", roleType: "worker" },
|
|
8
|
+
});
|
|
9
|
+
expect(out.startsWith("### 成员引导 (worker-0 · worker)")).toBe(true);
|
|
10
|
+
expect(out).toContain("**启动规则**");
|
|
11
|
+
expect(out).toContain("1. a");
|
|
12
|
+
expect(out).toContain("2. b");
|
|
13
|
+
expect(out).toContain("3. c");
|
|
14
|
+
expect(out).not.toContain("sw1");
|
|
15
|
+
});
|
|
16
|
+
it("renders queen header", () => {
|
|
17
|
+
const out = formatMemberBriefing({
|
|
18
|
+
rules: ["x"],
|
|
19
|
+
bootstrap: { swarmId: "sw1", instanceId: "queen-0", roleType: "queen" },
|
|
20
|
+
});
|
|
21
|
+
expect(out).toContain("### 成员引导 (queen-0 · queen)");
|
|
22
|
+
});
|
|
23
|
+
it("renders empty rules with _(无)_ placeholder", () => {
|
|
24
|
+
const out = formatMemberBriefing({
|
|
25
|
+
rules: [],
|
|
26
|
+
bootstrap: { swarmId: "sw1", instanceId: "worker-0", roleType: "worker" },
|
|
27
|
+
});
|
|
28
|
+
expect(out).toContain("### 成员引导 (worker-0 · worker)");
|
|
29
|
+
expect(out).toContain("**启动规则**");
|
|
30
|
+
expect(out).toContain("_(无)_");
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
//# sourceMappingURL=format-member-briefing.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format-member-briefing.test.js","sourceRoot":"","sources":["../../src/__tests__/format-member-briefing.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AAErE,QAAQ,CAAC,sBAAsB,EAAE,GAAG,EAAE;IACpC,EAAE,CAAC,mEAAmE,EAAE,GAAG,EAAE;QAC3E,MAAM,GAAG,GAAG,oBAAoB,CAAC;YAC/B,KAAK,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;YACtB,SAAS,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,QAAQ,EAAE,QAAQ,EAAE;SAC1E,CAAC,CAAC;QACH,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,8BAA8B,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAClE,MAAM,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;QAClC,MAAM,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QAC9B,MAAM,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QAC9B,MAAM,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QAC9B,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IACnC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sBAAsB,EAAE,GAAG,EAAE;QAC9B,MAAM,GAAG,GAAG,oBAAoB,CAAC;YAC/B,KAAK,EAAE,CAAC,GAAG,CAAC;YACZ,SAAS,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,QAAQ,EAAE,OAAO,EAAE;SACxE,CAAC,CAAC;QACH,MAAM,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,4BAA4B,CAAC,CAAC;IACtD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4CAA4C,EAAE,GAAG,EAAE;QACpD,MAAM,GAAG,GAAG,oBAAoB,CAAC;YAC/B,KAAK,EAAE,EAAE;YACT,SAAS,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,QAAQ,EAAE,QAAQ,EAAE;SAC1E,CAAC,CAAC;QACH,MAAM,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,8BAA8B,CAAC,CAAC;QACtD,MAAM,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;QAClC,MAAM,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;IACjC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format-task-briefing.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/format-task-briefing.test.ts"],"names":[],"mappings":""}
|