@nickmeriano/task 0.5.0 → 0.7.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 +104 -8
- package/dist/claim.d.ts +76 -0
- package/dist/claim.d.ts.map +1 -0
- package/dist/claim.js +237 -0
- package/dist/claim.js.map +1 -0
- package/dist/claim.test.d.ts +15 -0
- package/dist/claim.test.d.ts.map +1 -0
- package/dist/claim.test.js +185 -0
- package/dist/claim.test.js.map +1 -0
- package/dist/cli.js +304 -17
- package/dist/cli.js.map +1 -1
- package/dist/file-store.d.ts +113 -0
- package/dist/file-store.d.ts.map +1 -0
- package/dist/file-store.js +604 -0
- package/dist/file-store.js.map +1 -0
- package/dist/index.d.ts +7 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -1
- package/dist/index.js.map +1 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +11 -7
- package/dist/server.js.map +1 -1
- package/dist/store.d.ts +55 -15
- package/dist/store.d.ts.map +1 -1
- package/dist/store.js +63 -29
- package/dist/store.js.map +1 -1
- package/dist/store.test.d.ts +12 -0
- package/dist/store.test.d.ts.map +1 -0
- package/dist/store.test.js +252 -0
- package/dist/store.test.js.map +1 -0
- package/dist/ticket-doc.d.ts +57 -0
- package/dist/ticket-doc.d.ts.map +1 -0
- package/dist/ticket-doc.js +197 -0
- package/dist/ticket-doc.js.map +1 -0
- package/dist/types.d.ts +22 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +4 -4
- package/skill/SKILL.md +45 -8
- package/src/claim.test.ts +242 -0
- package/src/claim.ts +302 -0
- package/src/cli.ts +313 -20
- package/src/file-store.ts +693 -0
- package/src/index.ts +42 -4
- package/src/server.ts +15 -11
- package/src/store.test.ts +305 -0
- package/src/store.ts +99 -40
- package/src/ticket-doc.ts +226 -0
- package/src/types.ts +22 -1
- package/ui/dist/assets/index-CXW8uT5f.css +1 -0
- package/ui/dist/assets/{index-D_qmmh3D.js → index-oJzomUDL.js} +58 -58
- package/ui/dist/index.html +2 -2
- package/ui/dist/assets/index-Da14ye1f.css +0 -1
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The properties TAS-21 exists for, checked from the outside — against a real
|
|
3
|
+
* bare "origin" and real CLI subprocesses, because the whole point of claiming
|
|
4
|
+
* is what happens between two independent checkouts:
|
|
5
|
+
*
|
|
6
|
+
* 1. Two concurrent `task claim <same-id>`: exactly one exits 0, the other
|
|
7
|
+
* exits 1 — git's atomic ref creation is the lock.
|
|
8
|
+
* 2. Validation failures exit 2 before anything touches git.
|
|
9
|
+
* 3. `task list --claimable` is the queue: position order, minus blocked,
|
|
10
|
+
* needs-human, and already-claimed tickets.
|
|
11
|
+
* 4. `task claim --release` deletes the branch both sides and the ticket is
|
|
12
|
+
* claimable again.
|
|
13
|
+
*/
|
|
14
|
+
import assert from "node:assert/strict";
|
|
15
|
+
import { test } from "node:test";
|
|
16
|
+
import { execFile, spawnSync } from "node:child_process";
|
|
17
|
+
import { mkdtempSync, rmSync, writeFileSync } from "node:fs";
|
|
18
|
+
import { readFileSync } from "node:fs";
|
|
19
|
+
import { tmpdir } from "node:os";
|
|
20
|
+
import { join } from "node:path";
|
|
21
|
+
import { fileURLToPath } from "node:url";
|
|
22
|
+
import { initProject } from "./file-store.js";
|
|
23
|
+
const CLI = fileURLToPath(new URL("./cli.ts", import.meta.url));
|
|
24
|
+
function tempDir() {
|
|
25
|
+
const dir = mkdtempSync(join(tmpdir(), "task-claim-test-"));
|
|
26
|
+
process.on("exit", () => rmSync(dir, { recursive: true, force: true }));
|
|
27
|
+
return dir;
|
|
28
|
+
}
|
|
29
|
+
function sh(cwd, command, ...args) {
|
|
30
|
+
const result = spawnSync(command, args, { cwd, encoding: "utf8" });
|
|
31
|
+
if (result.status !== 0) {
|
|
32
|
+
throw new Error(`${command} ${args.join(" ")} failed: ${result.stderr}`);
|
|
33
|
+
}
|
|
34
|
+
return result.stdout.trim();
|
|
35
|
+
}
|
|
36
|
+
/** The CLI as callers see it — a subprocess with an exit code. */
|
|
37
|
+
function cli(cwd, ...args) {
|
|
38
|
+
return new Promise((resolve) => {
|
|
39
|
+
execFile(process.execPath, ["--experimental-strip-types", CLI, ...args], { cwd }, (error, stdout, stderr) => {
|
|
40
|
+
resolve({ code: error ? (error.code ?? 1) : 0, stdout, stderr });
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* A bare origin holding a board with the claimable shapes:
|
|
46
|
+
* 1 "Ready one" todo
|
|
47
|
+
* 2 "Ready two" todo
|
|
48
|
+
* 3 "Blocked" todo, blocked by 1
|
|
49
|
+
* 4 "For a person" todo, needs-human
|
|
50
|
+
* 5 "Not groomed" backlog
|
|
51
|
+
* 6 "Jumped queue" todo, moved to the top of the column after creation —
|
|
52
|
+
* claimable order must be [6, 1, 2], proving position
|
|
53
|
+
* order beats number order.
|
|
54
|
+
*/
|
|
55
|
+
function fixture(claimPrefix) {
|
|
56
|
+
const home = tempDir();
|
|
57
|
+
const bare = join(home, "origin.git");
|
|
58
|
+
sh(home, "git", "init", "--quiet", "--bare", "-b", "main", bare);
|
|
59
|
+
const seed = join(home, "seed");
|
|
60
|
+
sh(home, "git", "clone", "--quiet", bare, seed);
|
|
61
|
+
sh(seed, "git", "config", "user.name", "Test");
|
|
62
|
+
sh(seed, "git", "config", "user.email", "test@example.com");
|
|
63
|
+
const store = initProject(seed, { name: "claim board", prefix: "CLM" });
|
|
64
|
+
if (claimPrefix !== undefined) {
|
|
65
|
+
const configPath = join(seed, ".task", "config.json");
|
|
66
|
+
const config = JSON.parse(readFileSync(configPath, "utf8"));
|
|
67
|
+
config.claimPrefix = claimPrefix;
|
|
68
|
+
writeFileSync(configPath, `${JSON.stringify(config, null, 2)}\n`);
|
|
69
|
+
}
|
|
70
|
+
store.create({ title: "Ready one" });
|
|
71
|
+
store.create({ title: "Ready two" });
|
|
72
|
+
store.create({ title: "Blocked", blockedBy: [1] });
|
|
73
|
+
store.create({ title: "For a person", needsHuman: true });
|
|
74
|
+
store.create({ title: "Not groomed", status: "backlog" });
|
|
75
|
+
const jumper = store.create({ title: "Jumped queue", status: "backlog" });
|
|
76
|
+
// A status move without an explicit slot lands on top of the new column.
|
|
77
|
+
store.update(jumper.number, { status: "todo" });
|
|
78
|
+
sh(seed, "git", "add", "-A");
|
|
79
|
+
sh(seed, "git", "commit", "--quiet", "-m", "board");
|
|
80
|
+
sh(seed, "git", "push", "--quiet", "-u", "origin", "main");
|
|
81
|
+
let clones = 0;
|
|
82
|
+
const clone = () => {
|
|
83
|
+
const dir = join(home, `clone-${++clones}`);
|
|
84
|
+
sh(home, "git", "clone", "--quiet", bare, dir);
|
|
85
|
+
sh(dir, "git", "config", "user.name", "Test");
|
|
86
|
+
sh(dir, "git", "config", "user.email", "test@example.com");
|
|
87
|
+
return dir;
|
|
88
|
+
};
|
|
89
|
+
return { bare, clone };
|
|
90
|
+
}
|
|
91
|
+
test("two concurrent claims of one ticket: exactly one wins", async () => {
|
|
92
|
+
const { bare, clone } = fixture();
|
|
93
|
+
const a = clone();
|
|
94
|
+
const b = clone();
|
|
95
|
+
const [ra, rb] = await Promise.all([cli(a, "claim", "1"), cli(b, "claim", "1")]);
|
|
96
|
+
assert.deepEqual([ra.code, rb.code].sort(), [0, 1], `a: ${ra.stderr}\nb: ${rb.stderr}`);
|
|
97
|
+
const winner = ra.code === 0 ? a : b;
|
|
98
|
+
const loser = ra.code === 0 ? rb : ra;
|
|
99
|
+
assert.match(loser.stderr, /already claimed|rejected/);
|
|
100
|
+
// The winner is left on the claim branch, flip committed and pushed.
|
|
101
|
+
assert.equal(sh(winner, "git", "rev-parse", "--abbrev-ref", "HEAD"), "task/claim/clm-1");
|
|
102
|
+
assert.match(readFileSync(join(winner, ".task", "tickets", "1", "ticket.md"), "utf8"), /status: in_progress/);
|
|
103
|
+
assert.match(sh(winner, "git", "ls-remote", "--heads", "origin", "task/claim/clm-1"), /refs\/heads\/task\/claim\/clm-1/);
|
|
104
|
+
// Origin's default branch never saw the flip — the claim rides the branch.
|
|
105
|
+
assert.equal(sh(winner, "git", "diff", "--stat", "origin/main..HEAD", "--", "README.md"), "");
|
|
106
|
+
assert.match(sh(winner, "git", "show", "origin/main:.task/tickets/1/ticket.md"), /status: todo/);
|
|
107
|
+
void bare;
|
|
108
|
+
});
|
|
109
|
+
test("unclaimable tickets exit 2, before anything touches origin", async () => {
|
|
110
|
+
const { clone } = fixture();
|
|
111
|
+
const dir = clone();
|
|
112
|
+
assert.equal((await cli(dir, "claim", "5")).code, 2); // backlog
|
|
113
|
+
assert.equal((await cli(dir, "claim", "3")).code, 2); // blocked
|
|
114
|
+
assert.equal((await cli(dir, "claim", "4")).code, 2); // needs a human
|
|
115
|
+
assert.equal((await cli(dir, "claim", "99")).code, 2); // missing
|
|
116
|
+
assert.match((await cli(dir, "claim", "3")).stderr, /blocked by CLM-1/);
|
|
117
|
+
// A dirty tree refuses too — claiming switches branches.
|
|
118
|
+
writeFileSync(join(dir, "scratch.txt"), "wip");
|
|
119
|
+
const dirty = await cli(dir, "claim", "2");
|
|
120
|
+
assert.equal(dirty.code, 2);
|
|
121
|
+
assert.match(dirty.stderr, /working tree is dirty/);
|
|
122
|
+
rmSync(join(dir, "scratch.txt"));
|
|
123
|
+
assert.equal((await cli(dir, "claim", "2")).code, 0);
|
|
124
|
+
// Nothing above created a stray claim branch for the failed ids.
|
|
125
|
+
const remote = sh(dir, "git", "ls-remote", "--heads", "origin", "task/claim/*");
|
|
126
|
+
assert.deepEqual(remote.split("\n").map((l) => l.split("refs/heads/")[1]), ["task/claim/clm-2"]);
|
|
127
|
+
});
|
|
128
|
+
test("list --claimable is the queue: position order, minus everything unclaimable", async () => {
|
|
129
|
+
const { clone } = fixture();
|
|
130
|
+
const a = clone();
|
|
131
|
+
assert.equal((await cli(a, "claim", "6")).code, 0);
|
|
132
|
+
const b = clone();
|
|
133
|
+
const listed = await cli(b, "list", "--claimable", "--json");
|
|
134
|
+
assert.equal(listed.code, 0);
|
|
135
|
+
const { tasks } = JSON.parse(listed.stdout);
|
|
136
|
+
// 6 claimed, 3 blocked, 4 needs-human, 5 not todo — position order keeps
|
|
137
|
+
// 1 before 2 (creation order within the column).
|
|
138
|
+
assert.deepEqual(tasks.map((t) => t.number), [1, 2]);
|
|
139
|
+
assert.equal((await cli(b, "list", "--claimable", "--status", "todo")).code, 1);
|
|
140
|
+
});
|
|
141
|
+
test("release deletes the branch everywhere and reopens the claim", async () => {
|
|
142
|
+
const { clone } = fixture();
|
|
143
|
+
const dir = clone();
|
|
144
|
+
assert.equal((await cli(dir, "claim", "2")).code, 0);
|
|
145
|
+
assert.equal((await cli(dir, "claim", "2")).code, 1); // locally claimed too
|
|
146
|
+
const released = await cli(dir, "claim", "--release", "2");
|
|
147
|
+
assert.equal(released.code, 0, released.stderr);
|
|
148
|
+
assert.match(released.stdout, /released CLM-2/);
|
|
149
|
+
// Back on the default branch, branch gone on both sides, ticket todo again.
|
|
150
|
+
assert.equal(sh(dir, "git", "rev-parse", "--abbrev-ref", "HEAD"), "main");
|
|
151
|
+
assert.equal(sh(dir, "git", "ls-remote", "--heads", "origin", "task/claim/clm-2"), "");
|
|
152
|
+
assert.match(readFileSync(join(dir, ".task", "tickets", "2", "ticket.md"), "utf8"), /status: todo/);
|
|
153
|
+
assert.equal((await cli(dir, "claim", "2")).code, 0);
|
|
154
|
+
// Releasing an unclaimed ticket is a quiet no-op, not an error.
|
|
155
|
+
const noop = await cli(dir, "claim", "--release", "1");
|
|
156
|
+
assert.equal(noop.code, 0);
|
|
157
|
+
assert.match(noop.stdout, /wasn't claimed/);
|
|
158
|
+
});
|
|
159
|
+
test("a configured claimPrefix moves the whole namespace", async () => {
|
|
160
|
+
const { clone } = fixture("claude/task/");
|
|
161
|
+
const dir = clone();
|
|
162
|
+
assert.equal((await cli(dir, "claim", "1")).code, 0);
|
|
163
|
+
assert.equal(sh(dir, "git", "rev-parse", "--abbrev-ref", "HEAD"), "claude/task/clm-1");
|
|
164
|
+
assert.match(sh(dir, "git", "ls-remote", "--heads", "origin", "claude/task/*"), /refs\/heads\/claude\/task\/clm-1/);
|
|
165
|
+
// Every side of the feature reads the same key: the queue looks for claims
|
|
166
|
+
// under the configured namespace, and release deletes there too.
|
|
167
|
+
const other = clone();
|
|
168
|
+
const listed = await cli(other, "list", "--claimable", "--json");
|
|
169
|
+
const { tasks } = JSON.parse(listed.stdout);
|
|
170
|
+
assert.deepEqual(tasks.map((t) => t.number), [6, 2]);
|
|
171
|
+
assert.equal((await cli(other, "claim", "1")).code, 1);
|
|
172
|
+
assert.equal((await cli(dir, "claim", "--release", "1")).code, 0);
|
|
173
|
+
assert.equal(sh(dir, "git", "ls-remote", "--heads", "origin", "claude/task/*"), "");
|
|
174
|
+
// A missing trailing slash is forgiven; a malformed value fails loudly.
|
|
175
|
+
const bad = clone();
|
|
176
|
+
const configPath = join(bad, ".task", "config.json");
|
|
177
|
+
const config = JSON.parse(readFileSync(configPath, "utf8"));
|
|
178
|
+
config.claimPrefix = "spaces are not refs/";
|
|
179
|
+
writeFileSync(configPath, `${JSON.stringify(config, null, 2)}\n`);
|
|
180
|
+
sh(bad, "git", "commit", "--quiet", "-am", "bad prefix");
|
|
181
|
+
const invalid = await cli(bad, "claim", "2");
|
|
182
|
+
assert.equal(invalid.code, 2);
|
|
183
|
+
assert.match(invalid.stderr, /invalid claimPrefix/);
|
|
184
|
+
});
|
|
185
|
+
//# sourceMappingURL=claim.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claim.test.js","sourceRoot":"","sources":["../src/claim.test.ts"],"names":[],"mappings":"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"}
|