@nickmeriano/task 0.8.0 → 0.10.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.
Files changed (115) hide show
  1. package/README.md +137 -22
  2. package/dist/asks.test.d.ts +17 -0
  3. package/dist/asks.test.d.ts.map +1 -0
  4. package/dist/asks.test.js +278 -0
  5. package/dist/asks.test.js.map +1 -0
  6. package/dist/check.d.ts +3 -2
  7. package/dist/check.d.ts.map +1 -1
  8. package/dist/check.js +99 -60
  9. package/dist/check.js.map +1 -1
  10. package/dist/check.test.js +99 -60
  11. package/dist/check.test.js.map +1 -1
  12. package/dist/claim-io.d.ts +73 -0
  13. package/dist/claim-io.d.ts.map +1 -0
  14. package/dist/claim-io.js +344 -0
  15. package/dist/claim-io.js.map +1 -0
  16. package/dist/claim.d.ts +108 -23
  17. package/dist/claim.d.ts.map +1 -1
  18. package/dist/claim.js +320 -86
  19. package/dist/claim.js.map +1 -1
  20. package/dist/claim.test.d.ts +10 -2
  21. package/dist/claim.test.d.ts.map +1 -1
  22. package/dist/claim.test.js +282 -96
  23. package/dist/claim.test.js.map +1 -1
  24. package/dist/cli.js +346 -68
  25. package/dist/cli.js.map +1 -1
  26. package/dist/file-store.d.ts +70 -24
  27. package/dist/file-store.d.ts.map +1 -1
  28. package/dist/file-store.js +319 -141
  29. package/dist/file-store.js.map +1 -1
  30. package/dist/git-serve.d.ts +183 -0
  31. package/dist/git-serve.d.ts.map +1 -0
  32. package/dist/git-serve.js +503 -0
  33. package/dist/git-serve.js.map +1 -0
  34. package/dist/git-serve.test.d.ts +16 -0
  35. package/dist/git-serve.test.d.ts.map +1 -0
  36. package/dist/git-serve.test.js +183 -0
  37. package/dist/git-serve.test.js.map +1 -0
  38. package/dist/git.d.ts +65 -0
  39. package/dist/git.d.ts.map +1 -0
  40. package/dist/git.js +114 -0
  41. package/dist/git.js.map +1 -0
  42. package/dist/id.d.ts +39 -0
  43. package/dist/id.d.ts.map +1 -0
  44. package/dist/id.js +67 -0
  45. package/dist/id.js.map +1 -0
  46. package/dist/inbox.d.ts +41 -0
  47. package/dist/inbox.d.ts.map +1 -0
  48. package/dist/inbox.js +56 -0
  49. package/dist/inbox.js.map +1 -0
  50. package/dist/overview.d.ts +9 -0
  51. package/dist/overview.d.ts.map +1 -1
  52. package/dist/overview.js +19 -11
  53. package/dist/overview.js.map +1 -1
  54. package/dist/overview.test.js +6 -5
  55. package/dist/overview.test.js.map +1 -1
  56. package/dist/promote.test.d.ts +3 -2
  57. package/dist/promote.test.d.ts.map +1 -1
  58. package/dist/promote.test.js +29 -31
  59. package/dist/promote.test.js.map +1 -1
  60. package/dist/publish.d.ts +2 -17
  61. package/dist/publish.d.ts.map +1 -1
  62. package/dist/publish.js +4 -49
  63. package/dist/publish.js.map +1 -1
  64. package/dist/search.d.ts +3 -1
  65. package/dist/search.d.ts.map +1 -1
  66. package/dist/search.js +15 -2
  67. package/dist/search.js.map +1 -1
  68. package/dist/search.test.js +9 -9
  69. package/dist/search.test.js.map +1 -1
  70. package/dist/server.d.ts.map +1 -1
  71. package/dist/server.js +218 -21
  72. package/dist/server.js.map +1 -1
  73. package/dist/store.d.ts +28 -14
  74. package/dist/store.d.ts.map +1 -1
  75. package/dist/store.js.map +1 -1
  76. package/dist/store.test.js +88 -75
  77. package/dist/store.test.js.map +1 -1
  78. package/dist/ticket-doc.d.ts +26 -10
  79. package/dist/ticket-doc.d.ts.map +1 -1
  80. package/dist/ticket-doc.js +71 -27
  81. package/dist/ticket-doc.js.map +1 -1
  82. package/dist/types.d.ts +51 -17
  83. package/dist/types.d.ts.map +1 -1
  84. package/dist/types.js.map +1 -1
  85. package/package.json +1 -1
  86. package/skill/SKILL.md +96 -24
  87. package/src/asks.test.ts +355 -0
  88. package/src/check.test.ts +129 -72
  89. package/src/check.ts +101 -58
  90. package/src/claim-io.ts +401 -0
  91. package/src/claim.test.ts +372 -101
  92. package/src/claim.ts +418 -99
  93. package/src/cli.ts +370 -67
  94. package/src/file-store.ts +357 -145
  95. package/src/git-serve.test.ts +240 -0
  96. package/src/git-serve.ts +595 -0
  97. package/src/git.ts +141 -0
  98. package/src/id.ts +68 -0
  99. package/src/inbox.ts +77 -0
  100. package/src/overview.test.ts +6 -5
  101. package/src/overview.ts +25 -10
  102. package/src/promote.test.ts +40 -28
  103. package/src/publish.ts +6 -53
  104. package/src/search.test.ts +11 -11
  105. package/src/search.ts +17 -3
  106. package/src/server.ts +221 -19
  107. package/src/store.test.ts +95 -77
  108. package/src/store.ts +28 -13
  109. package/src/ticket-doc.ts +93 -30
  110. package/src/types.ts +52 -17
  111. package/ui/dist/assets/index-BjsorZOU.js +229 -0
  112. package/ui/dist/assets/index-CoKCUYic.css +1 -0
  113. package/ui/dist/index.html +2 -2
  114. package/ui/dist/assets/index-BJmOsOdR.js +0 -229
  115. 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 --milestone launch
43
+ task add "Wire up webhook retries" --tags api --goal launch
44
44
  task list # open tasks, board order
45
- task list --needs-human # what's blocked on a person
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 comments, with snippets
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 / needs-human promote with the hold
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
@@ -66,27 +68,31 @@ a lock. `task claim` is that lock, built out of things git already guarantees:
66
68
 
67
69
  ```bash
68
70
  task claim TAS-21 # claim it: branch + status flip + push
71
+ task claim TAS-21 --lock-only # just the lock — the checkout stays put
69
72
  task list --claimable # the queue: what a worker may pick up next
70
73
  task claim --release TAS-21 # abandon a claim cleanly
74
+ task sweep # janitor: delete claims whose tickets are finished
71
75
  ```
72
76
 
73
77
  - **The claim is the work branch.** `task claim TAS-21` branches
74
- `task/claim/tas-21` off origin's default branch, flips the ticket to
78
+ `task/claim/tas-x7k4m` off origin's default branch, flips the ticket to
75
79
  `in_progress` as the branch's first commit, and pushes. The branch existing
76
80
  on origin *is* the claim — nothing side-band to clean up, because the branch
77
81
  was needed anyway and dies at merge.
78
82
  - **The namespace is yours.** `task/claim/` is only the default —
79
- `"claimPrefix"` in `.task/config.json` moves the whole namespace, and it
80
- lives in the committed config on purpose: every worker and every clone must
81
- agree on what "claimed" looks like, or there is no lock. If your workers are
82
- Claude Code cloud sessions, set `"claimPrefix": "claude/task/"` — that
83
- runtime can push `claude/`-prefixed branches without extra ceremony. Pick
84
- the value before the first claim; renaming later strands in-flight claims.
83
+ `claims.branchPrefix` in `.task/config.json` moves the whole namespace, and
84
+ it lives in the committed config on purpose: every worker and every clone
85
+ must agree on what "claimed" looks like, or there is no lock. If your
86
+ workers are Claude Code cloud sessions, set
87
+ `"claims": { "branchPrefix": "claude/task/" }` that runtime can push
88
+ `claude/`-prefixed branches without extra ceremony. Pick the value before
89
+ the first claim; renaming later strands in-flight claims.
85
90
  - **Atomic by construction.** The push only succeeds if the branch doesn't
86
91
  exist yet (a compare-and-swap on the ref), so two concurrent claimers of the
87
92
  same ticket get exactly one winner. Exit codes are the contract: `0` claimed,
88
93
  `1` already claimed (pick the next ticket), `2` not claimable — not `todo`,
89
- blocked, `--needs-human`, or a dirty working tree.
94
+ blocked, or a dirty working tree. Open asks don't gate a claim: an agent
95
+ can work the code while a person owes the ticket something.
90
96
  - **The lifecycle rides the branch.** Claim = `in_progress`; before the PR is
91
97
  marked ready, `task move <id> done` + `task update --pr` on the branch; the merge lands
92
98
  code and `done` together, and the branch auto-deletes. Between claim and
@@ -96,9 +102,110 @@ task claim --release TAS-21 # abandon a claim cleanly
96
102
  - **Claim before you work — humans too.** The same verb covers manual work:
97
103
  run `task claim <id>` before starting a ticket yourself and any scheduled
98
104
  agent will skip it. `task list --claimable` shows `todo` tickets in position
99
- order minus blocked, needs-human, and already-claimed — the top entry is
100
- what an autonomous worker takes next, which makes column order your priority
101
- queue.
105
+ order minus blocked and already-claimed — the top entry is what an
106
+ autonomous worker takes next, which makes column order your priority queue.
107
+ - **Pinned to a branch? Take just the lock.** Plain `claim` bundles three
108
+ roles — the lock (the branch ref on origin), the workspace (the checkout
109
+ switch), and the delivery branch (where the work lands). For the scheduled
110
+ worker they coincide; for a session whose harness handed it a provisioned
111
+ branch (Claude web sessions, CI jobs) they don't — it can't switch branches
112
+ without breaking its contract, and working outside the lock is how two
113
+ workers collide. `task claim <id> --lock-only` takes the same atomic lock
114
+ without touching the checkout: the `in_progress` flip commit is built
115
+ against origin's default branch in a temporary index and pushed with the
116
+ same must-not-exist lease, and it carries a `delivered_by: <branch>` trailer
117
+ naming the branch the work will actually land on. Exit codes and
118
+ `--release` are identical to plain claim.
119
+ - **Releases are verified, and `task sweep` is the janitor.** Some
120
+ environments silently drop branch-deletion pushes — git reports success
121
+ while the ref survives — so `--release` re-checks with `ls-remote` and
122
+ fails loudly instead of reporting a release that didn't happen. The
123
+ systemic healer is `task sweep`: delete every claim branch on origin whose
124
+ ticket is done, canceled, or missing on the current checkout, across all
125
+ the repo's boards, verifying each deletion; it exits non-zero if a deletion
126
+ was attempted and failed. Its jurisdiction is exactly the names `claim`
127
+ mints — `<namespace><prefix>-<valid key>`; a branch under the namespace
128
+ that doesn't fit (a pre-migration numeric claim, a hand-made branch) is
129
+ reported and left alone, because it may be an open PR's head and deleting
130
+ what claiming didn't create is a judgment call, not janitorial work. Pure
131
+ git and zero judgment by design — the trigger belongs to a runner, not an
132
+ agent (see below).
133
+
134
+ ### Environment requirements for agent runners
135
+
136
+ The claim protocol is plain git, so any harness — Claude, Codex, CI, a
137
+ laptop cron — can drive it if its environment meets this contract:
138
+
139
+ - **Git identity**: `user.name`/`user.email` set (the flip commit needs an
140
+ author).
141
+ - **Push rights to the claim namespace** (`claims.branchPrefix`): creating a
142
+ branch there *is* claiming.
143
+ - **Branch deletion rights** for a full-service worker — or accept degraded
144
+ release: environments that can't delete remote branches get a loud error
145
+ from `task claim --release` instead of a silent lie, and a `task sweep`
146
+ running somewhere capable heals the stale locks once tickets finish.
147
+ - **A branch-pinned harness** (the session must deliver its work on an
148
+ assigned branch) claims with `--lock-only`; a free harness uses plain
149
+ `claim` and works on the claim branch. The harness supplies the fact, the
150
+ shipped skill supplies the rule — no vendor detection anywhere.
151
+
152
+ The reference sweep trigger is ~10 lines of GitHub Actions — push-to-main
153
+ plus a daily cron, deliberately deterministic (no agent, no judgment):
154
+
155
+ ```yaml
156
+ # .github/workflows/task-sweep.yml
157
+ name: Task sweep
158
+ on:
159
+ push:
160
+ branches: [main]
161
+ schedule:
162
+ - cron: "17 4 * * *"
163
+ permissions:
164
+ contents: write # branch deletion
165
+ jobs:
166
+ sweep:
167
+ runs-on: ubuntu-latest
168
+ steps:
169
+ - uses: actions/checkout@v4
170
+ - uses: actions/setup-node@v4
171
+ with: { node-version: 22 }
172
+ - run: npx @nickmeriano/task sweep
173
+ ```
174
+
175
+ Any runner that can `git push --delete` works identically — a laptop cron
176
+ running `npx @nickmeriano/task sweep` is the same janitor.
177
+
178
+ ## Git, from the board
179
+
180
+ Board edits — a drag, a checkbox, a new ticket — are plain writes into your
181
+ working tree; nothing commits behind your back. `task serve` shows you that
182
+ truth and gives it verbs: the header grows a branch chip with the current
183
+ branch, a dirty-count badge, and ahead/behind, cards carry an "uncommitted
184
+ edits" dot, and the chip's panel commits, switches branches, and opens PRs.
185
+
186
+ - **Commits are board-scoped.** "Commit board changes" runs a pathspec-scoped
187
+ commit of each board's `.task/` directory — your half-finished code stays
188
+ dirty and stays out. Messages default to `chore(board): <ticket ids>`.
189
+ - **Context decides where the commit goes.** On a feature or claim branch it
190
+ lands right there — ticket edits usually belong to that branch's PR. On the
191
+ default branch the flow is a fresh board branch plus a PR, so board edits
192
+ never land on main from a click.
193
+ - **PRs: files remember, git informs.** Opening a PR uses `gh` when it's on
194
+ your PATH and falls back to GitHub's compare page when it isn't. A created
195
+ PR's URL is written into the `prs:` frontmatter of every ticket the branch
196
+ touches — the file stays canonical — and, with `gh`, ticket chips gain
197
+ display-only draft/open/merged state resolved live from the branch.
198
+ - **Branch switching is a real checkout** — distinct from the hosted board's
199
+ `?ref=` preview — and refuses while tracked files outside `.task/` are
200
+ dirty, so a click in a board can't carry your code somewhere else.
201
+ - **Dragging a claimed ticket out of In Progress releases the claim.** That's
202
+ `task claim --release` wearing a drop: a confirm explains that the claim
203
+ branch and its commits go away, and the move happens only if the branch
204
+ deletion succeeds.
205
+ - **It disappears when it can't work.** No git, no `origin`, the hosted board,
206
+ the static snapshot: no git surface at all, no errors. Writes are guarded by
207
+ a same-origin check, so a webpage in the same browser can't aim POSTs at
208
+ your board.
102
209
 
103
210
  ## From anywhere
104
211
 
@@ -169,9 +276,12 @@ jobs:
169
276
  else await github.rest.issues.createComment({ ...context.repo, issue_number: context.issue.number, body })
170
277
  ```
171
278
 
172
- - Ids are `PREFIX-12` or just `12`; the prefix is the first three letters of
279
+ - Ids are `PREFIX-x7k4m` or just `x7k4m` a random 5-character key minted
280
+ at `task add`, so two branches that have never seen each other can never
281
+ mint the same id; any unique prefix of a key resolves git-style
282
+ (`task show x7`). The board prefix is the first three letters of
173
283
  the project name ("phone" → `PHO-1`), or whatever `task init --prefix` says.
174
- - Ids route by prefix: a bare `12` means the nearest board, while `TAS-12`
284
+ - Ids route by prefix: a bare `x7k4m` means the nearest board, while `TAS-x7k4m`
175
285
  reaches the TAS board from anywhere in the monorepo. An unknown or ambiguous
176
286
  prefix fails loudly instead of guessing. `task boards` lists every board —
177
287
  prefix, name, path, open count — with a `*` on the one commands target from
@@ -183,15 +293,20 @@ jobs:
183
293
  reserved forever. `task archive --all` sweeps everything finished;
184
294
  `task unarchive <id>` puts one back.
185
295
  - Statuses: `backlog` `todo` `in_progress` `done` `canceled`.
186
- - A task carries tags, at most one milestone, and a `--needs-human` flag for
187
- work an agent can't finish alone. `--tag a,b` matches either tag.
296
+ - A task carries tags, at most one goal, and **asks** checklist items
297
+ a person owes it (`task ask`), each one file under `tickets/<key>/asks/`.
298
+ Open asks derive the amber needs-human badge, feed `task inbox` (the
299
+ repo-wide "what do I owe NOW" view — in-progress work only, and a ticket
300
+ claimed on a branch counts, its asks read from the branch), and gate
301
+ `done`: a ticket finishes when nobody owes it anything. `--tag a,b`
302
+ matches either tag.
188
303
  - `task link A --blocked-by B` marks a dependency. It's one relation seen from
189
304
  both ends — B's page says it blocks A — and the board badges A as blocked
190
305
  until B is done or canceled.
191
306
  - `--pr <url>` attaches a pull request to a task (`--prs` replaces the list);
192
307
  attached PRs show in the task's rail and as a count on its card. The elegant
193
308
  loop is an agent convention, not a webhook: put the id in the PR title
194
- (`[TAS-6] …`) and run `task update TAS-6 --pr <url>` when opening the PR —
309
+ (`[TAS-x7k4m] …`) and run `task update TAS-x7k4m --pr <url>` when opening the PR —
195
310
  the shipped skill tells agents to do exactly that.
196
311
  - Every task has **Copy link** — the icon next to its title, or right-click /
197
312
  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 (including the pre-0.8 `milestone:` key, whose
14
- * rewrite to `goal:` is the migration).
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
@@ -1 +1 @@
1
- {"version":3,"file":"check.d.ts","sourceRoot":"","sources":["../src/check.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAqCH,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"}
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"}