@nickmeriano/task 0.8.0 → 0.9.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 +65 -22
- package/dist/asks.test.d.ts +17 -0
- package/dist/asks.test.d.ts.map +1 -0
- package/dist/asks.test.js +278 -0
- package/dist/asks.test.js.map +1 -0
- package/dist/check.d.ts +3 -2
- package/dist/check.d.ts.map +1 -1
- package/dist/check.js +99 -60
- package/dist/check.js.map +1 -1
- package/dist/check.test.js +99 -60
- package/dist/check.test.js.map +1 -1
- package/dist/claim-io.d.ts +73 -0
- package/dist/claim-io.d.ts.map +1 -0
- package/dist/claim-io.js +344 -0
- package/dist/claim-io.js.map +1 -0
- package/dist/claim.d.ts +21 -22
- package/dist/claim.d.ts.map +1 -1
- package/dist/claim.js +58 -83
- package/dist/claim.js.map +1 -1
- package/dist/claim.test.d.ts +2 -2
- package/dist/claim.test.js +111 -94
- package/dist/claim.test.js.map +1 -1
- package/dist/cli.js +241 -64
- package/dist/cli.js.map +1 -1
- package/dist/file-store.d.ts +70 -24
- package/dist/file-store.d.ts.map +1 -1
- package/dist/file-store.js +319 -141
- package/dist/file-store.js.map +1 -1
- package/dist/git-serve.d.ts +183 -0
- package/dist/git-serve.d.ts.map +1 -0
- package/dist/git-serve.js +503 -0
- package/dist/git-serve.js.map +1 -0
- package/dist/git-serve.test.d.ts +16 -0
- package/dist/git-serve.test.d.ts.map +1 -0
- package/dist/git-serve.test.js +183 -0
- package/dist/git-serve.test.js.map +1 -0
- package/dist/git.d.ts +65 -0
- package/dist/git.d.ts.map +1 -0
- package/dist/git.js +114 -0
- package/dist/git.js.map +1 -0
- package/dist/id.d.ts +39 -0
- package/dist/id.d.ts.map +1 -0
- package/dist/id.js +67 -0
- package/dist/id.js.map +1 -0
- package/dist/inbox.d.ts +41 -0
- package/dist/inbox.d.ts.map +1 -0
- package/dist/inbox.js +56 -0
- package/dist/inbox.js.map +1 -0
- package/dist/overview.d.ts +9 -0
- package/dist/overview.d.ts.map +1 -1
- package/dist/overview.js +19 -11
- package/dist/overview.js.map +1 -1
- package/dist/overview.test.js +6 -5
- package/dist/overview.test.js.map +1 -1
- package/dist/promote.test.d.ts +3 -2
- package/dist/promote.test.d.ts.map +1 -1
- package/dist/promote.test.js +29 -31
- package/dist/promote.test.js.map +1 -1
- package/dist/publish.d.ts +2 -17
- package/dist/publish.d.ts.map +1 -1
- package/dist/publish.js +4 -49
- package/dist/publish.js.map +1 -1
- package/dist/search.d.ts +3 -1
- package/dist/search.d.ts.map +1 -1
- package/dist/search.js +15 -2
- package/dist/search.js.map +1 -1
- package/dist/search.test.js +9 -9
- package/dist/search.test.js.map +1 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +218 -21
- package/dist/server.js.map +1 -1
- package/dist/store.d.ts +28 -14
- package/dist/store.d.ts.map +1 -1
- package/dist/store.js.map +1 -1
- package/dist/store.test.js +88 -75
- package/dist/store.test.js.map +1 -1
- package/dist/ticket-doc.d.ts +26 -10
- package/dist/ticket-doc.d.ts.map +1 -1
- package/dist/ticket-doc.js +71 -27
- package/dist/ticket-doc.js.map +1 -1
- package/dist/types.d.ts +51 -17
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +1 -1
- package/skill/SKILL.md +70 -23
- package/src/asks.test.ts +355 -0
- package/src/check.test.ts +129 -72
- package/src/check.ts +101 -58
- package/src/claim-io.ts +401 -0
- package/src/claim.test.ts +141 -99
- package/src/claim.ts +69 -96
- package/src/cli.ts +251 -63
- package/src/file-store.ts +357 -145
- package/src/git-serve.test.ts +240 -0
- package/src/git-serve.ts +595 -0
- package/src/git.ts +141 -0
- package/src/id.ts +68 -0
- package/src/inbox.ts +77 -0
- package/src/overview.test.ts +6 -5
- package/src/overview.ts +25 -10
- package/src/promote.test.ts +40 -28
- package/src/publish.ts +6 -53
- package/src/search.test.ts +11 -11
- package/src/search.ts +17 -3
- package/src/server.ts +221 -19
- package/src/store.test.ts +95 -77
- package/src/store.ts +28 -13
- package/src/ticket-doc.ts +93 -30
- package/src/types.ts +52 -17
- package/ui/dist/assets/index-BjsorZOU.js +229 -0
- package/ui/dist/assets/index-CoKCUYic.css +1 -0
- package/ui/dist/index.html +2 -2
- package/ui/dist/assets/index-BJmOsOdR.js +0 -229
- package/ui/dist/assets/index-BoqQlqSU.css +0 -1
package/README.md
CHANGED
|
@@ -40,15 +40,17 @@ nothing reads — which is exactly what happened the first time this tried.
|
|
|
40
40
|
## Use
|
|
41
41
|
|
|
42
42
|
```bash
|
|
43
|
-
task add "Wire up webhook retries" --tags api --
|
|
43
|
+
task add "Wire up webhook retries" --tags api --goal launch
|
|
44
44
|
task list # open tasks, board order
|
|
45
|
-
task
|
|
45
|
+
task ask 1 "Mint the API key" # file what a person owes the ticket
|
|
46
|
+
task resolve 1 1 # …and check it off once it's done
|
|
47
|
+
task inbox # every open ask on in-progress work, repo-wide
|
|
46
48
|
task search "webhook" # find tickets by what they say — titles,
|
|
47
|
-
# descriptions and
|
|
48
|
-
task move 1 in_progress # status changes all go through move
|
|
49
|
+
# descriptions, comments and asks, with snippets
|
|
50
|
+
task move 1 in_progress # status changes all go through move; done is
|
|
51
|
+
# refused while the ticket has open asks
|
|
49
52
|
task promote 1 # backlog → todo, the human "build this" call;
|
|
50
|
-
# blocked
|
|
51
|
-
# reported
|
|
53
|
+
# blocked tickets promote with the hold reported
|
|
52
54
|
task link 2 --blocked-by 1 # dependency, visible from both tasks
|
|
53
55
|
task update 1 --pr https://github.com/you/repo/pull/42
|
|
54
56
|
task comment 1 "shipped in #42" --author claude
|
|
@@ -71,22 +73,24 @@ task claim --release TAS-21 # abandon a claim cleanly
|
|
|
71
73
|
```
|
|
72
74
|
|
|
73
75
|
- **The claim is the work branch.** `task claim TAS-21` branches
|
|
74
|
-
`task/claim/tas-
|
|
76
|
+
`task/claim/tas-x7k4m` off origin's default branch, flips the ticket to
|
|
75
77
|
`in_progress` as the branch's first commit, and pushes. The branch existing
|
|
76
78
|
on origin *is* the claim — nothing side-band to clean up, because the branch
|
|
77
79
|
was needed anyway and dies at merge.
|
|
78
80
|
- **The namespace is yours.** `task/claim/` is only the default —
|
|
79
|
-
`
|
|
80
|
-
lives in the committed config on purpose: every worker and every clone
|
|
81
|
-
agree on what "claimed" looks like, or there is no lock. If your
|
|
82
|
-
Claude Code cloud sessions, set
|
|
83
|
-
|
|
84
|
-
|
|
81
|
+
`claims.branchPrefix` in `.task/config.json` moves the whole namespace, and
|
|
82
|
+
it lives in the committed config on purpose: every worker and every clone
|
|
83
|
+
must agree on what "claimed" looks like, or there is no lock. If your
|
|
84
|
+
workers are Claude Code cloud sessions, set
|
|
85
|
+
`"claims": { "branchPrefix": "claude/task/" }` — that runtime can push
|
|
86
|
+
`claude/`-prefixed branches without extra ceremony. Pick the value before
|
|
87
|
+
the first claim; renaming later strands in-flight claims.
|
|
85
88
|
- **Atomic by construction.** The push only succeeds if the branch doesn't
|
|
86
89
|
exist yet (a compare-and-swap on the ref), so two concurrent claimers of the
|
|
87
90
|
same ticket get exactly one winner. Exit codes are the contract: `0` claimed,
|
|
88
91
|
`1` already claimed (pick the next ticket), `2` not claimable — not `todo`,
|
|
89
|
-
blocked,
|
|
92
|
+
blocked, or a dirty working tree. Open asks don't gate a claim: an agent
|
|
93
|
+
can work the code while a person owes the ticket something.
|
|
90
94
|
- **The lifecycle rides the branch.** Claim = `in_progress`; before the PR is
|
|
91
95
|
marked ready, `task move <id> done` + `task update --pr` on the branch; the merge lands
|
|
92
96
|
code and `done` together, and the branch auto-deletes. Between claim and
|
|
@@ -96,9 +100,40 @@ task claim --release TAS-21 # abandon a claim cleanly
|
|
|
96
100
|
- **Claim before you work — humans too.** The same verb covers manual work:
|
|
97
101
|
run `task claim <id>` before starting a ticket yourself and any scheduled
|
|
98
102
|
agent will skip it. `task list --claimable` shows `todo` tickets in position
|
|
99
|
-
order minus blocked
|
|
100
|
-
|
|
101
|
-
|
|
103
|
+
order minus blocked and already-claimed — the top entry is what an
|
|
104
|
+
autonomous worker takes next, which makes column order your priority queue.
|
|
105
|
+
|
|
106
|
+
## Git, from the board
|
|
107
|
+
|
|
108
|
+
Board edits — a drag, a checkbox, a new ticket — are plain writes into your
|
|
109
|
+
working tree; nothing commits behind your back. `task serve` shows you that
|
|
110
|
+
truth and gives it verbs: the header grows a branch chip with the current
|
|
111
|
+
branch, a dirty-count badge, and ahead/behind, cards carry an "uncommitted
|
|
112
|
+
edits" dot, and the chip's panel commits, switches branches, and opens PRs.
|
|
113
|
+
|
|
114
|
+
- **Commits are board-scoped.** "Commit board changes" runs a pathspec-scoped
|
|
115
|
+
commit of each board's `.task/` directory — your half-finished code stays
|
|
116
|
+
dirty and stays out. Messages default to `chore(board): <ticket ids>`.
|
|
117
|
+
- **Context decides where the commit goes.** On a feature or claim branch it
|
|
118
|
+
lands right there — ticket edits usually belong to that branch's PR. On the
|
|
119
|
+
default branch the flow is a fresh board branch plus a PR, so board edits
|
|
120
|
+
never land on main from a click.
|
|
121
|
+
- **PRs: files remember, git informs.** Opening a PR uses `gh` when it's on
|
|
122
|
+
your PATH and falls back to GitHub's compare page when it isn't. A created
|
|
123
|
+
PR's URL is written into the `prs:` frontmatter of every ticket the branch
|
|
124
|
+
touches — the file stays canonical — and, with `gh`, ticket chips gain
|
|
125
|
+
display-only draft/open/merged state resolved live from the branch.
|
|
126
|
+
- **Branch switching is a real checkout** — distinct from the hosted board's
|
|
127
|
+
`?ref=` preview — and refuses while tracked files outside `.task/` are
|
|
128
|
+
dirty, so a click in a board can't carry your code somewhere else.
|
|
129
|
+
- **Dragging a claimed ticket out of In Progress releases the claim.** That's
|
|
130
|
+
`task claim --release` wearing a drop: a confirm explains that the claim
|
|
131
|
+
branch and its commits go away, and the move happens only if the branch
|
|
132
|
+
deletion succeeds.
|
|
133
|
+
- **It disappears when it can't work.** No git, no `origin`, the hosted board,
|
|
134
|
+
the static snapshot: no git surface at all, no errors. Writes are guarded by
|
|
135
|
+
a same-origin check, so a webpage in the same browser can't aim POSTs at
|
|
136
|
+
your board.
|
|
102
137
|
|
|
103
138
|
## From anywhere
|
|
104
139
|
|
|
@@ -169,9 +204,12 @@ jobs:
|
|
|
169
204
|
else await github.rest.issues.createComment({ ...context.repo, issue_number: context.issue.number, body })
|
|
170
205
|
```
|
|
171
206
|
|
|
172
|
-
- Ids are `PREFIX-
|
|
207
|
+
- Ids are `PREFIX-x7k4m` or just `x7k4m` — a random 5-character key minted
|
|
208
|
+
at `task add`, so two branches that have never seen each other can never
|
|
209
|
+
mint the same id; any unique prefix of a key resolves git-style
|
|
210
|
+
(`task show x7`). The board prefix is the first three letters of
|
|
173
211
|
the project name ("phone" → `PHO-1`), or whatever `task init --prefix` says.
|
|
174
|
-
- Ids route by prefix: a bare `
|
|
212
|
+
- Ids route by prefix: a bare `x7k4m` means the nearest board, while `TAS-x7k4m`
|
|
175
213
|
reaches the TAS board from anywhere in the monorepo. An unknown or ambiguous
|
|
176
214
|
prefix fails loudly instead of guessing. `task boards` lists every board —
|
|
177
215
|
prefix, name, path, open count — with a `*` on the one commands target from
|
|
@@ -183,15 +221,20 @@ jobs:
|
|
|
183
221
|
reserved forever. `task archive --all` sweeps everything finished;
|
|
184
222
|
`task unarchive <id>` puts one back.
|
|
185
223
|
- Statuses: `backlog` `todo` `in_progress` `done` `canceled`.
|
|
186
|
-
- A task carries tags, at most one
|
|
187
|
-
|
|
224
|
+
- A task carries tags, at most one goal, and **asks** — checklist items
|
|
225
|
+
a person owes it (`task ask`), each one file under `tickets/<key>/asks/`.
|
|
226
|
+
Open asks derive the amber needs-human badge, feed `task inbox` (the
|
|
227
|
+
repo-wide "what do I owe NOW" view — in-progress work only, and a ticket
|
|
228
|
+
claimed on a branch counts, its asks read from the branch), and gate
|
|
229
|
+
`done`: a ticket finishes when nobody owes it anything. `--tag a,b`
|
|
230
|
+
matches either tag.
|
|
188
231
|
- `task link A --blocked-by B` marks a dependency. It's one relation seen from
|
|
189
232
|
both ends — B's page says it blocks A — and the board badges A as blocked
|
|
190
233
|
until B is done or canceled.
|
|
191
234
|
- `--pr <url>` attaches a pull request to a task (`--prs` replaces the list);
|
|
192
235
|
attached PRs show in the task's rail and as a count on its card. The elegant
|
|
193
236
|
loop is an agent convention, not a webhook: put the id in the PR title
|
|
194
|
-
(`[TAS-
|
|
237
|
+
(`[TAS-x7k4m] …`) and run `task update TAS-x7k4m --pr <url>` when opening the PR —
|
|
195
238
|
the shipped skill tells agents to do exactly that.
|
|
196
239
|
- Every task has **Copy link** — the icon next to its title, or right-click /
|
|
197
240
|
long-press any card or row — so handing a ticket to an agent is one paste.
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Asks (TAS-38): the checklist a person owes a ticket, and everything derived
|
|
3
|
+
* from it.
|
|
4
|
+
*
|
|
5
|
+
* 1. An ask is one file under tickets/<key>/asks/, comment-shaped; `needsHuman`
|
|
6
|
+
* is derived from open asks, never stored.
|
|
7
|
+
* 2. Done is gated: open asks refuse the move, resolving clears it, canceled
|
|
8
|
+
* voids without ceremony. A finished ticket can't start owing again —
|
|
9
|
+
* addAsk/reopen are refused on done/canceled.
|
|
10
|
+
* 3. Ordinals are creation-order positions — stable across resolution, the
|
|
11
|
+
* handle `task resolve <id> <n>` takes.
|
|
12
|
+
* 4. `task inbox` answers "what do I owe NOW": open asks on effectively
|
|
13
|
+
* in-progress tickets — file status, or a live claim branch, whose ask
|
|
14
|
+
* files are read from the branch itself.
|
|
15
|
+
*/
|
|
16
|
+
export {};
|
|
17
|
+
//# sourceMappingURL=asks.test.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"asks.test.d.ts","sourceRoot":"","sources":["../src/asks.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG"}
|
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Asks (TAS-38): the checklist a person owes a ticket, and everything derived
|
|
3
|
+
* from it.
|
|
4
|
+
*
|
|
5
|
+
* 1. An ask is one file under tickets/<key>/asks/, comment-shaped; `needsHuman`
|
|
6
|
+
* is derived from open asks, never stored.
|
|
7
|
+
* 2. Done is gated: open asks refuse the move, resolving clears it, canceled
|
|
8
|
+
* voids without ceremony. A finished ticket can't start owing again —
|
|
9
|
+
* addAsk/reopen are refused on done/canceled.
|
|
10
|
+
* 3. Ordinals are creation-order positions — stable across resolution, the
|
|
11
|
+
* handle `task resolve <id> <n>` takes.
|
|
12
|
+
* 4. `task inbox` answers "what do I owe NOW": open asks on effectively
|
|
13
|
+
* in-progress tickets — file status, or a live claim branch, whose ask
|
|
14
|
+
* files are read from the branch itself.
|
|
15
|
+
*/
|
|
16
|
+
import assert from "node:assert/strict";
|
|
17
|
+
import { test } from "node:test";
|
|
18
|
+
import { execFile, execFileSync } from "node:child_process";
|
|
19
|
+
import { existsSync, mkdtempSync, readFileSync, readdirSync, rmSync } from "node:fs";
|
|
20
|
+
import { tmpdir } from "node:os";
|
|
21
|
+
import { join } from "node:path";
|
|
22
|
+
import { fileURLToPath } from "node:url";
|
|
23
|
+
import { initProject } from "./file-store.js";
|
|
24
|
+
const CLI = fileURLToPath(new URL("./cli.ts", import.meta.url));
|
|
25
|
+
function tempDir() {
|
|
26
|
+
const dir = mkdtempSync(join(tmpdir(), "task-asks-test-"));
|
|
27
|
+
process.on("exit", () => rmSync(dir, { recursive: true, force: true }));
|
|
28
|
+
return dir;
|
|
29
|
+
}
|
|
30
|
+
function cli(cwd, ...args) {
|
|
31
|
+
return new Promise((resolve) => {
|
|
32
|
+
execFile(process.execPath, ["--experimental-strip-types", CLI, ...args], { cwd }, (error, stdout, stderr) => {
|
|
33
|
+
resolve({ code: error ? (error.code ?? 1) : 0, stdout, stderr });
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
// ── The store-level contract ─────────────────────────────────────────────────
|
|
38
|
+
test("an ask is a file; needsHuman derives from it and resolution round-trips", () => {
|
|
39
|
+
const dir = tempDir();
|
|
40
|
+
const store = initProject(dir, { name: "ask board", prefix: "ASK" });
|
|
41
|
+
const task = store.create({ title: "Wire the webhook", status: "in_progress" });
|
|
42
|
+
assert.equal(store.get(task.key).needsHuman, false);
|
|
43
|
+
const ask = store.addAsk(task.key, "Mint the API token and add it to secrets", "claude");
|
|
44
|
+
assert.equal(ask.ordinal, 1);
|
|
45
|
+
assert.equal(ask.resolvedAt, null);
|
|
46
|
+
// One file, comment-shaped, under asks/ — mergeable by construction.
|
|
47
|
+
const dirPath = join(dir, ".task", "tickets", task.key, "asks");
|
|
48
|
+
const files = readdirSync(dirPath);
|
|
49
|
+
assert.equal(files.length, 1);
|
|
50
|
+
const text = readFileSync(join(dirPath, files[0]), "utf8");
|
|
51
|
+
assert.match(text, /^---\nauthor: "claude"\ncreated: /);
|
|
52
|
+
assert.match(text, /Mint the API token/);
|
|
53
|
+
const withAsk = store.get(task.key);
|
|
54
|
+
assert.equal(withAsk.needsHuman, true);
|
|
55
|
+
assert.equal(withAsk.asks.length, 1);
|
|
56
|
+
const resolved = store.resolveAsk(task.key, "1", "nick");
|
|
57
|
+
assert.equal(resolved.resolvedBy, "nick");
|
|
58
|
+
assert.notEqual(resolved.resolvedAt, null);
|
|
59
|
+
assert.equal(store.get(task.key).needsHuman, false);
|
|
60
|
+
assert.match(readFileSync(join(dirPath, files[0]), "utf8"), /resolved_by: "nick"/);
|
|
61
|
+
const reopened = store.reopenAsk(task.key, resolved.id);
|
|
62
|
+
assert.equal(reopened.resolvedAt, null);
|
|
63
|
+
assert.equal(store.get(task.key).needsHuman, true);
|
|
64
|
+
store.close();
|
|
65
|
+
});
|
|
66
|
+
test("ordinals are creation order and stay put as asks resolve", () => {
|
|
67
|
+
const dir = tempDir();
|
|
68
|
+
const store = initProject(dir, { name: "ask board", prefix: "ASK" });
|
|
69
|
+
const task = store.create({ title: "Ship it", status: "in_progress" });
|
|
70
|
+
store.addAsk(task.key, "First owed thing", "claude");
|
|
71
|
+
store.addAsk(task.key, "Second owed thing", "claude");
|
|
72
|
+
store.resolveAsk(task.key, "1", "nick");
|
|
73
|
+
const asks = store.asks(task.key);
|
|
74
|
+
assert.deepEqual(asks.map((a) => a.ordinal), [1, 2]);
|
|
75
|
+
assert.equal(asks[0].resolvedAt !== null, true);
|
|
76
|
+
assert.equal(asks[1].text, "Second owed thing");
|
|
77
|
+
// The needs-human filter matches the derived flag.
|
|
78
|
+
assert.deepEqual(store.list({ needsHuman: true }).map((t) => t.key), [task.key]);
|
|
79
|
+
store.close();
|
|
80
|
+
});
|
|
81
|
+
test("done is gated on zero open asks; canceled voids them", () => {
|
|
82
|
+
const dir = tempDir();
|
|
83
|
+
const store = initProject(dir, { name: "ask board", prefix: "ASK" });
|
|
84
|
+
const task = store.create({ title: "Gated", status: "in_progress" });
|
|
85
|
+
store.addAsk(task.key, "Approve the cutover window", "claude");
|
|
86
|
+
assert.throws(() => store.update(task.key, { status: "done" }), /1 open ask.*done means nobody owes anything/s);
|
|
87
|
+
// Canceling is allowed with the asks still open — a dead ticket's asks die
|
|
88
|
+
// with it — and once canceled, no new debt can accrue.
|
|
89
|
+
store.update(task.key, { status: "canceled" });
|
|
90
|
+
assert.throws(() => store.addAsk(task.key, "Too late", "claude"), /is canceled/);
|
|
91
|
+
store.update(task.key, { status: "in_progress" });
|
|
92
|
+
store.resolveAsk(task.key, "1", "nick");
|
|
93
|
+
const done = store.update(task.key, { status: "done" });
|
|
94
|
+
assert.equal(done.status, "done");
|
|
95
|
+
// A finished ticket can't quietly start owing things again.
|
|
96
|
+
assert.throws(() => store.addAsk(task.key, "One more thing", "claude"), /is done/);
|
|
97
|
+
assert.throws(() => store.reopenAsk(task.key, "1"), /reopening an ask/);
|
|
98
|
+
store.close();
|
|
99
|
+
});
|
|
100
|
+
// ── The CLI surface ──────────────────────────────────────────────────────────
|
|
101
|
+
test("task ask / resolve / show: the full loop, exit codes and ordinals", async () => {
|
|
102
|
+
const dir = tempDir();
|
|
103
|
+
initProject(dir, { name: "cli board", prefix: "CLI" }).close();
|
|
104
|
+
const created = await cli(dir, "add", "Needs a person", "--status", "in_progress", "--json");
|
|
105
|
+
const id = JSON.parse(created.stdout).task.id;
|
|
106
|
+
const asked = await cli(dir, "ask", id, "Run setup.sh once the token exists", "--author", "claude");
|
|
107
|
+
assert.equal(asked.code, 0, asked.stderr);
|
|
108
|
+
assert.ok(asked.stdout.includes(`asked on ${id} [1]`), asked.stdout);
|
|
109
|
+
const shown = await cli(dir, "show", id, "--json");
|
|
110
|
+
const { task } = JSON.parse(shown.stdout);
|
|
111
|
+
assert.equal(task.needsHuman, true);
|
|
112
|
+
assert.equal(task.asks[0].author, "claude");
|
|
113
|
+
// Done refuses while the ask is open — the gate speaks CLI too.
|
|
114
|
+
const blocked = await cli(dir, "move", id, "done");
|
|
115
|
+
assert.equal(blocked.code, 1);
|
|
116
|
+
assert.match(blocked.stderr, /open ask/);
|
|
117
|
+
const resolved = await cli(dir, "resolve", id, "1", "--comment", "done, it's in 1Password", "--author", "nick");
|
|
118
|
+
assert.equal(resolved.code, 0, resolved.stderr);
|
|
119
|
+
assert.ok(resolved.stdout.includes(`resolved ${id} [1]`), resolved.stdout);
|
|
120
|
+
assert.match(resolved.stdout, /last open ask/);
|
|
121
|
+
// The note landed as an attributed comment naming the ask.
|
|
122
|
+
const detail = await cli(dir, "show", id, "--json");
|
|
123
|
+
const { comments } = JSON.parse(detail.stdout);
|
|
124
|
+
assert.equal(comments.length, 1);
|
|
125
|
+
assert.equal(comments[0].author, "nick");
|
|
126
|
+
assert.match(comments[0].body, /Resolved ask \[1\].*1Password/);
|
|
127
|
+
assert.equal((await cli(dir, "move", id, "done")).code, 0);
|
|
128
|
+
assert.equal((await cli(dir, "resolve", id, "9")).code, 1);
|
|
129
|
+
});
|
|
130
|
+
test("task add --ask files asks at creation, commas and all", async () => {
|
|
131
|
+
const dir = tempDir();
|
|
132
|
+
initProject(dir, { name: "cli board", prefix: "CLI" }).close();
|
|
133
|
+
const added = await cli(dir, "add", "Born owing", "--status", "todo", "--ask", "Approve the plan, then the budget", "--ask", "Add STRIPE_SECRET_KEY to the worker", "--json");
|
|
134
|
+
assert.equal(added.code, 0, added.stderr);
|
|
135
|
+
const { task } = JSON.parse(added.stdout);
|
|
136
|
+
// One ask per --ask, verbatim — a comma never splits an ask in two.
|
|
137
|
+
assert.deepEqual(task.asks.map((a) => a.text), ["Approve the plan, then the budget", "Add STRIPE_SECRET_KEY to the worker"]);
|
|
138
|
+
assert.equal(task.needsHuman, true);
|
|
139
|
+
});
|
|
140
|
+
test("inbox is in-progress only: todo asks wait for their claim", async () => {
|
|
141
|
+
const dir = tempDir();
|
|
142
|
+
const store = initProject(dir, { name: "inbox board", prefix: "INB" });
|
|
143
|
+
const active = store.create({ title: "Being worked", status: "in_progress" });
|
|
144
|
+
const queued = store.create({ title: "Waiting its turn", status: "todo" });
|
|
145
|
+
store.addAsk(active.key, "Upgrade the org to Pro", "claude");
|
|
146
|
+
store.addAsk(queued.key, "Decide pricing", "claude");
|
|
147
|
+
store.close();
|
|
148
|
+
// Not a git repo — the resolver degrades silently to file truth.
|
|
149
|
+
const result = await cli(dir, "inbox", "--json");
|
|
150
|
+
assert.equal(result.code, 0, result.stderr);
|
|
151
|
+
const { inbox } = JSON.parse(result.stdout);
|
|
152
|
+
assert.deepEqual(inbox.map((e) => e.task.key), [active.key]);
|
|
153
|
+
assert.equal(inbox[0].claim, null);
|
|
154
|
+
assert.equal(inbox[0].asks[0].text, "Upgrade the org to Pro");
|
|
155
|
+
});
|
|
156
|
+
// ── The claim-branch read (TAS-26's core) ────────────────────────────────────
|
|
157
|
+
function sh(cwd, ...args) {
|
|
158
|
+
return execFileSync(args[0], args.slice(1), { cwd, encoding: "utf8" }).trim();
|
|
159
|
+
}
|
|
160
|
+
test("a claimed ticket's asks reach the inbox from its branch", async () => {
|
|
161
|
+
const home = tempDir();
|
|
162
|
+
const bare = join(home, "origin.git");
|
|
163
|
+
sh(home, "git", "init", "--quiet", "--bare", "-b", "main", bare);
|
|
164
|
+
const seed = join(home, "seed");
|
|
165
|
+
sh(home, "git", "clone", "--quiet", bare, seed);
|
|
166
|
+
sh(seed, "git", "config", "user.name", "Test");
|
|
167
|
+
sh(seed, "git", "config", "user.email", "test@example.com");
|
|
168
|
+
const store = initProject(seed, { name: "claim inbox", prefix: "CIN" });
|
|
169
|
+
const key = store.create({ title: "Agent work with a human side", status: "todo" }).key;
|
|
170
|
+
const branch = `task/claim/cin-${key}`;
|
|
171
|
+
store.close();
|
|
172
|
+
sh(seed, "git", "add", "-A");
|
|
173
|
+
sh(seed, "git", "commit", "--quiet", "-m", "board");
|
|
174
|
+
sh(seed, "git", "push", "--quiet", "-u", "origin", "main");
|
|
175
|
+
// Worker: claim (flips the ticket on the branch), file an ask mid-run, push.
|
|
176
|
+
const worker = join(home, "worker");
|
|
177
|
+
sh(home, "git", "clone", "--quiet", bare, worker);
|
|
178
|
+
sh(worker, "git", "config", "user.name", "Worker");
|
|
179
|
+
sh(worker, "git", "config", "user.email", "worker@example.com");
|
|
180
|
+
assert.equal((await cli(worker, "claim", key)).code, 0);
|
|
181
|
+
assert.equal((await cli(worker, "ask", `CIN-${key}`, "Create the OAuth app in the dashboard", "--author", "claude")).code, 0);
|
|
182
|
+
sh(worker, "git", "add", "-A");
|
|
183
|
+
sh(worker, "git", "commit", "--quiet", "-m", "ask");
|
|
184
|
+
sh(worker, "git", "push", "--quiet", "origin", branch);
|
|
185
|
+
// Owner, on a fresh clone of main, where the ticket still reads `todo` and
|
|
186
|
+
// has no ask files at all: the inbox says what the claim branch knows.
|
|
187
|
+
const owner = join(home, "owner");
|
|
188
|
+
sh(home, "git", "clone", "--quiet", bare, owner);
|
|
189
|
+
sh(owner, "git", "config", "user.name", "Nick");
|
|
190
|
+
sh(owner, "git", "config", "user.email", "nick@example.com");
|
|
191
|
+
assert.equal(existsSync(join(owner, ".task", "tickets", key, "asks")), false);
|
|
192
|
+
const result = await cli(owner, "inbox", "--json");
|
|
193
|
+
assert.equal(result.code, 0, result.stderr);
|
|
194
|
+
const { inbox } = JSON.parse(result.stdout);
|
|
195
|
+
assert.equal(inbox.length, 1);
|
|
196
|
+
assert.equal(inbox[0].task.status, "todo"); // file truth, kept honest
|
|
197
|
+
assert.equal(inbox[0].claim?.branch, branch);
|
|
198
|
+
assert.deepEqual(inbox[0].asks.map((a) => a.text), ["Create the OAuth app in the dashboard"]);
|
|
199
|
+
// The claim owns the ticket's asks, so the owner's writes land on the
|
|
200
|
+
// branch as pushed commits — the checkout never switches, the working
|
|
201
|
+
// tree never grows an ask file.
|
|
202
|
+
const resolved = await cli(owner, "resolve", `CIN-${key}`, "1", "--author", "nick");
|
|
203
|
+
assert.equal(resolved.code, 0, resolved.stderr);
|
|
204
|
+
assert.ok(resolved.stdout.includes(`committed and pushed to ${branch}`), resolved.stdout);
|
|
205
|
+
assert.equal(existsSync(join(owner, ".task", "tickets", key, "asks")), false);
|
|
206
|
+
assert.equal(sh(owner, "git", "rev-parse", "--abbrev-ref", "HEAD"), "main");
|
|
207
|
+
// A third clone reads the resolution straight off origin's branch.
|
|
208
|
+
const verify = join(home, "verify");
|
|
209
|
+
sh(home, "git", "clone", "--quiet", bare, verify);
|
|
210
|
+
sh(verify, "git", "fetch", "--quiet", "origin", branch);
|
|
211
|
+
const askFile = sh(verify, "git", "ls-tree", "--name-only", `FETCH_HEAD:.task/tickets/${key}/asks`);
|
|
212
|
+
assert.match(sh(verify, "git", "show", `FETCH_HEAD:.task/tickets/${key}/asks/${askFile}`), /resolved_by: "nick"/);
|
|
213
|
+
const cleared = await cli(owner, "inbox", "--json");
|
|
214
|
+
assert.equal(JSON.parse(cleared.stdout).inbox.length, 0);
|
|
215
|
+
// Adding to a claimed ticket routes to the branch too — the worker's done
|
|
216
|
+
// gate has to see debt the owner files mid-claim.
|
|
217
|
+
const added = await cli(owner, "ask", `CIN-${key}`, "Also rotate the old key", "--author", "nick");
|
|
218
|
+
assert.equal(added.code, 0, added.stderr);
|
|
219
|
+
assert.ok(added.stdout.includes(`committed and pushed to ${branch}`), added.stdout);
|
|
220
|
+
assert.equal(existsSync(join(owner, ".task", "tickets", key, "asks")), false);
|
|
221
|
+
sh(verify, "git", "fetch", "--quiet", "origin", branch);
|
|
222
|
+
assert.equal(sh(verify, "git", "ls-tree", "--name-only", `FETCH_HEAD:.task/tickets/${key}/asks`).split("\n").length, 2);
|
|
223
|
+
const again = await cli(owner, "inbox", "--json");
|
|
224
|
+
const entries = JSON.parse(again.stdout).inbox;
|
|
225
|
+
assert.deepEqual(entries[0].asks.map((a) => a.text), ["Also rotate the old key"]);
|
|
226
|
+
// And the worker's next tick simply pulls its branch and has everything.
|
|
227
|
+
sh(worker, "git", "pull", "--quiet", "origin", branch);
|
|
228
|
+
const workerView = await cli(worker, "show", `CIN-${key}`, "--json");
|
|
229
|
+
const workerAsks = JSON.parse(workerView.stdout).task.asks;
|
|
230
|
+
assert.deepEqual(workerAsks.map((a) => [a.text, a.resolvedBy]), [["Create the OAuth app in the dashboard", "nick"], ["Also rotate the old key", null]]);
|
|
231
|
+
});
|
|
232
|
+
test("branch writes hold up in shallow clones and worktrees", async () => {
|
|
233
|
+
const home = tempDir();
|
|
234
|
+
const bare = join(home, "origin.git");
|
|
235
|
+
sh(home, "git", "init", "--quiet", "--bare", "-b", "main", bare);
|
|
236
|
+
const seed = join(home, "seed");
|
|
237
|
+
sh(home, "git", "clone", "--quiet", bare, seed);
|
|
238
|
+
sh(seed, "git", "config", "user.name", "Test");
|
|
239
|
+
sh(seed, "git", "config", "user.email", "test@example.com");
|
|
240
|
+
const store = initProject(seed, { name: "envs board", prefix: "ENV" });
|
|
241
|
+
const key = store.create({ title: "Worked while owed", status: "todo" }).key;
|
|
242
|
+
const branch = `task/claim/env-${key}`;
|
|
243
|
+
store.close();
|
|
244
|
+
sh(seed, "git", "add", "-A");
|
|
245
|
+
sh(seed, "git", "commit", "--quiet", "-m", "board");
|
|
246
|
+
sh(seed, "git", "push", "--quiet", "-u", "origin", "main");
|
|
247
|
+
assert.equal((await cli(seed, "claim", key)).code, 0);
|
|
248
|
+
assert.equal((await cli(seed, "ask", `ENV-${key}`, "Bless the rollout", "--author", "claude")).code, 0);
|
|
249
|
+
sh(seed, "git", "add", "-A");
|
|
250
|
+
sh(seed, "git", "commit", "--quiet", "-m", "ask");
|
|
251
|
+
sh(seed, "git", "push", "--quiet", "origin", branch);
|
|
252
|
+
// Shallow clone — what CI checkouts default to. The plumbing must build
|
|
253
|
+
// its commit from a fetched claim tip whose history it doesn't have.
|
|
254
|
+
const shallow = join(home, "shallow");
|
|
255
|
+
sh(home, "git", "clone", "--quiet", "--depth", "1", `file://${bare}`, shallow);
|
|
256
|
+
sh(shallow, "git", "config", "user.name", "Nick");
|
|
257
|
+
sh(shallow, "git", "config", "user.email", "nick@example.com");
|
|
258
|
+
const resolved = await cli(shallow, "resolve", `ENV-${key}`, "1", "--author", "nick");
|
|
259
|
+
assert.equal(resolved.code, 0, resolved.stderr);
|
|
260
|
+
assert.ok(resolved.stdout.includes(`committed and pushed to ${branch}`), resolved.stdout);
|
|
261
|
+
// Worktree — refs shared with the main checkout, index elsewhere.
|
|
262
|
+
const full = join(home, "full");
|
|
263
|
+
sh(home, "git", "clone", "--quiet", bare, full);
|
|
264
|
+
sh(full, "git", "config", "user.name", "Nick");
|
|
265
|
+
sh(full, "git", "config", "user.email", "nick@example.com");
|
|
266
|
+
const worktree = join(home, "wt");
|
|
267
|
+
sh(full, "git", "worktree", "add", "--quiet", "--detach", worktree);
|
|
268
|
+
const added = await cli(worktree, "ask", `ENV-${key}`, "Sign the SOC2 form", "--author", "nick");
|
|
269
|
+
assert.equal(added.code, 0, added.stderr);
|
|
270
|
+
assert.ok(added.stdout.includes(`committed and pushed to ${branch}`), added.stdout);
|
|
271
|
+
// Origin's branch carries both writes; the checkout that made them doesn't.
|
|
272
|
+
sh(full, "git", "fetch", "--quiet", "origin", branch);
|
|
273
|
+
const files = sh(full, "git", "ls-tree", "--name-only", `FETCH_HEAD:.task/tickets/${key}/asks`).split("\n");
|
|
274
|
+
assert.equal(files.length, 2);
|
|
275
|
+
assert.equal(existsSync(join(shallow, ".task", "tickets", key, "asks")), false);
|
|
276
|
+
assert.equal(existsSync(join(worktree, ".task", "tickets", key, "asks")), false);
|
|
277
|
+
});
|
|
278
|
+
//# sourceMappingURL=asks.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"asks.test.js","sourceRoot":"","sources":["../src/asks.test.ts"],"names":[],"mappings":"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"}
|
package/dist/check.d.ts
CHANGED
|
@@ -10,8 +10,9 @@
|
|
|
10
10
|
* references (one branch deleted a ticket another branch linked to), `goal:`
|
|
11
11
|
* refs naming a goal that doesn't exist, tickets duplicated between the board
|
|
12
12
|
* and the archive, unknown frontmatter keys, and formatting drift from the
|
|
13
|
-
* canonical serialization
|
|
14
|
-
*
|
|
13
|
+
* canonical serialization. Retired pre-0.8 spellings (`milestone:`,
|
|
14
|
+
* `claimPrefix`) are refused by the parsers with the rename in the error —
|
|
15
|
+
* this lint just surfaces those messages; there is no migration machinery.
|
|
15
16
|
*
|
|
16
17
|
* The mechanical repairs — pruning dangling or self references, deduping and
|
|
17
18
|
* sorting `blocked_by`, rewriting a file into canonical form — are applied by
|
package/dist/check.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"check.d.ts","sourceRoot":"","sources":["../src/check.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"check.d.ts","sourceRoot":"","sources":["../src/check.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AA0CH,MAAM,WAAW,UAAU;IACzB,oEAAoE;IACpE,KAAK,EAAE,MAAM,CAAA;IACb,yEAAyE;IACzE,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;IACf,oDAAoD;IACpD,OAAO,EAAE,OAAO,CAAA;CACjB;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAA;IACd,0CAA0C;IAC1C,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,UAAU,EAAE,CAAA;IACpB,wEAAwE;IACxE,KAAK,EAAE,MAAM,EAAE,CAAA;CAChB;AAED,iFAAiF;AACjF,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAE7C;AA2BD,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,GAAG,WAAW,CAwBnE"}
|