@lovek4d/kickflip 0.7.8 → 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.
Files changed (44) hide show
  1. package/CONTEXT.md +10 -6
  2. package/SKILL.md +19 -13
  3. package/bin/event-lines.mjs +1 -1
  4. package/bin/install.mjs +3 -3
  5. package/board/bin/board.mjs +35 -13
  6. package/board/commit-message.mjs +6 -0
  7. package/board/domain.mjs +7 -7
  8. package/board/finish.mjs +5 -4
  9. package/board/headless.mjs +8 -8
  10. package/board/hub-lines.mjs +1 -1
  11. package/board/public/app-header.js +23 -0
  12. package/board/public/app-needs.js +1 -1
  13. package/board/public/app-reader.js +6 -2
  14. package/board/public/app.html +2 -0
  15. package/board/public/app.js +2 -0
  16. package/board/public/attach.js +12 -0
  17. package/board/public/col-resize.js +73 -0
  18. package/board/public/dialogs.js +3 -0
  19. package/board/public/prototype-kit.js +1 -1
  20. package/board/public/prototype.html +1 -0
  21. package/board/public/sidebar.css +8 -2
  22. package/board/public/style.css +33 -11
  23. package/board/public/ui-header.js +2 -2
  24. package/board/public/ui-sidebar.js +11 -3
  25. package/board/public/ui-threads.js +1 -0
  26. package/board/public/view-hub.js +2 -2
  27. package/board/public/view-questions.js +2 -1
  28. package/board/render-check.mjs +8 -8
  29. package/board/server.mjs +18 -18
  30. package/board/store.mjs +32 -31
  31. package/board/tickets.mjs +3 -3
  32. package/board/worktree.mjs +21 -19
  33. package/hooks-plugin/hooks/usage-gate.mjs +1 -3
  34. package/hub/boards.mjs +4 -4
  35. package/hub/home.mjs +1 -1
  36. package/hub/hub.mjs +11 -11
  37. package/hub/pr-report.mjs +2 -2
  38. package/hub/readiness.mjs +1 -1
  39. package/hub/review-send.mjs +1 -1
  40. package/hub/schedule.mjs +1 -1
  41. package/hub/slack.mjs +2 -2
  42. package/hub/views.mjs +1 -1
  43. package/package.json +1 -1
  44. package/shared/fake-gh.mjs +9 -4
package/CONTEXT.md CHANGED
@@ -67,11 +67,11 @@ What each integration needs before its features can run: the Hub page’s Integr
67
67
  _Avoid_: integration health, availability
68
68
 
69
69
  **Usage reading**:
70
- The last reported Claude or Codex usage for its 5-hour and weekly windows, with reset times and when read. The sidebar’s Hub row shows each tool’s 5-hour bar and the hub page shows both windows with the **pause line** tick; a reading older than its window reads “last seen” with a grey striped bar, otherwise a window whose reset passed reads as reset. Claude appears after its status line reports usage. Codex's bars show only while the **Codex setting** in effect isn't Off; the hub page keeps Codex's block either way, opening with the setting's control ([the sidebar shows Claude and Codex usage under Hub](docs/adr/2026-11-01-1338-the-sidebar-shows-claude-and-codex-usage-under-hub.md), [Codex share sits in the Usage card](docs/adr/2026-11-01-1428-codex-share-sits-in-the-usage-card.md), [Codex share follows whether Codex is usable](docs/adr/2026-11-01-1521-codex-share-follows-whether-codex-is-usable.md)).
70
+ The last reported Claude or Codex usage for its 5-hour and weekly windows, with reset times and when read. The sidebar’s Hub row shows each tool’s 5-hour bar, and a second “Claude week” bar once Claude’s live week is within the **near** band under the **pause line** (orange under the line, red at it; none with the line Off), and the hub page shows both windows with the **pause line** tick; a reading older than its window reads “last seen” with a grey striped bar, otherwise a window whose reset passed reads as reset. Claude appears after its status line reports usage. Codex's bars show only while the **Codex setting** in effect isn't Off; the hub page keeps Codex's block either way, opening with the setting's control ([the sidebar shows Claude and Codex usage under Hub](docs/adr/2026-11-01-1338-the-sidebar-shows-claude-and-codex-usage-under-hub.md), [the sidebar shows the week once it is near the line](docs/adr/2026-11-10-1215-the-sidebar-shows-the-week-once-it-is-near-the-line.md), [Codex share sits in the Usage card](docs/adr/2026-11-01-1428-codex-share-sits-in-the-usage-card.md), [Codex share follows whether Codex is usable](docs/adr/2026-11-01-1521-codex-share-follows-whether-codex-is-usable.md)).
71
71
  _Avoid_: quota, live usage
72
72
 
73
73
  **Pause line**:
74
- The Usage card's “Pause work at”, last in the group below Codex: `pauseAt` in `~/.claude/kickflip/settings.json`, 50–100 in steps of 5, default 90 (10% buffer); 100 reads Off. Either live Claude window at or over it pauses new work until that window resets, and a **card pause** stops each running Claude build ("usage limit") until it resets; new agents wait, watchers hold the hub's work events, and owner messages get a brief “paused until <time>”. Keep going lifts that window's pause until its reset; Stop restores it. Codex hands work to Opus builders at the same line, without pausing. The Hub banner and sidebar and board header status slots show the pause, never the logo. Claude's reading joins the status line's with every headless run log's newest `rate_limit_event`. Within twice the buffer of the line the gate is **near**: the board server starts one agent at a time, each once the last has reported its usage, and the Hub banner reads "Approaching usage limit, reducing parallel agents" with its own Keep going. `shared/usage-gate.mjs` owns it; `kickflip usage-gate` prints it ([work pauses at the pause line](docs/adr/2026-11-01-1710-work-pauses-at-the-pause-line.md), [the pause line reads every headless agent's usage](docs/adr/2026-11-06-1249-the-pause-line-reads-every-headless-agents-usage.md), [a card pause stops its builder at its next stopping point](docs/adr/2026-11-09-1300-a-card-pause-stops-its-builder-at-its-next-stopping-point.md)).
74
+ The Usage card's “Pause work at”, last in the group below Codex: `pauseAt` in `~/.claude/kickflip/settings.json`, 50–100 in steps of 5, default 90 (10% buffer); 100 reads Off. Either live Claude window at or over it pauses new work until that window resets, and a **card pause** stops each running Claude build ("usage limit") until it resets; new agents wait, watchers hold the hub's work events, and the orchestrator keeps sorting, readying, screening and answering. Keep going lifts that window's pause until its reset; Stop restores it. Codex hands work to Opus builders at the same line, without pausing. The Hub banner and sidebar and board header status slots show the pause, never the logo. Claude's reading joins the status line's with every headless run log's newest `rate_limit_event`. Within twice the buffer of the line the gate is **near**: the board server starts one agent at a time, each once the last has reported its usage, and the Hub banner reads "Approaching usage limit, reducing parallel agents" with its own Keep going. `shared/usage-gate.mjs` owns it; `kickflip usage-gate` prints it ([work pauses at the pause line](docs/adr/2026-11-01-1710-work-pauses-at-the-pause-line.md), [the pause line reads every headless agent's usage](docs/adr/2026-11-06-1249-the-pause-line-reads-every-headless-agents-usage.md), [a card pause stops its builder at its next stopping point](docs/adr/2026-11-09-1300-a-card-pause-stops-its-builder-at-its-next-stopping-point.md)).
75
75
  _Avoid_: buffer threshold, quota guard
76
76
 
77
77
  **Card pause**:
@@ -149,7 +149,7 @@ The owner's presence, which sets the **Check cadence** and the moon: the host's
149
149
  _Avoid_: at the Mac, active, online, desktop app active
150
150
 
151
151
  **Check cadence**:
152
- How often the hub checks: every minute while the owner is present (the Mac in use, or a board page tapped on any device) and every 5 while away or in quiet hours ([boards read PR state from the hub's check](docs/adr/2026-11-09-1556-boards-read-pr-state-from-the-hubs-check.md)), or every 5 and 15 while GitHub has under 1,000 points left. Coming back checks at once. Each check fetches and pulls every board's repo and reads every card PR in one GraphQL query, wakes a board's owning session with `github-change` when a PR on its cards changed, pushes once for each board that isn't listening, then sends the queued pushes. While away, a moon sits right of the board title ([the hub checks every minute while you’re here and every 5 when away](docs/adr/2026-11-04-0226-the-hub-checks-every-minute-while-youre-here-and-every-5-when-away.md)).
152
+ How often the hub checks: every minute while the owner is present (the Mac in use, or a board page tapped on any device) and every 5 while away ([boards read PR state from the hub's check](docs/adr/2026-11-09-1556-boards-read-pr-state-from-the-hubs-check.md)), or every 5 and 15 while GitHub has under 1,000 points left. Coming back checks at once. Each check fetches and pulls every board's repo and reads every card PR in one GraphQL query, wakes a board's owning session with `github-change` when a PR on its cards changed, pushes once for each board that isn't listening, then sends the queued pushes. While away, a moon sits right of the board title ([the hub checks every minute while you’re here and every 5 when away](docs/adr/2026-11-04-0226-the-hub-checks-every-minute-while-youre-here-and-every-5-when-away.md)).
153
153
  _Avoid_: polling interval, polling window, push schedule, cron
154
154
 
155
155
  **Quiet hours**:
@@ -223,7 +223,7 @@ Claude reviewing a board's repo, chosen by `hub/board-repo.mjs` `boardRepo`, wit
223
223
  _Avoid_: improvements round, audit (for the whole review), bulb round
224
224
 
225
225
  **Reviewers**:
226
- The people who get a board's PR links once they are ready, and the weekday digest. Each board keeps its own in `board.json`, which its Settings modal lists, and a new item file copies them into its own `reviewers`. The board server writes both an add and a remove: an add picks a Slack member and a GitHub login from lists it fetches with the hub's Slack token and `gh`, and the server opens the DM ([the server adds reviewers from fetched lists](docs/adr/2026-11-05-2100-the-server-adds-reviewers-from-fetched-lists.md), extending [the board server removes reviewers itself](docs/adr/2026-11-04-0119-the-board-server-removes-reviewers-itself.md)). Kickflip owns the sent messages per PR, not per card, in each board's `data/pr-slack.json` `{<owner/repo#n>: {head, links: {<name>: {channel, ts, reactions}}, replies}}`: a card holds 1:m PRs, and each PR has 1:m reviewer DMs sharing one thread and one set of reactions. The card, Stale age, hub Slack link and digest read each reviewer's first link across the card's PRs, with an item's older `review_link_ts` and slack-bridge topic files only as a fallback ([Slack sends hang off PRs and go out from the hub tick](docs/adr/2026-11-07-0300-slack-sends-hang-off-prs-and-go-out-from-the-hub-tick.md)). The hub sends them as the owner, through the Slack user token pasted on Hub › Integrations › Slack and kept in `~/.claude/kickflip/secrets.json` beside Linear's key, opening the owner's DM with each reviewer, and records each message as it posts, so a failed one goes again next poll and a posted one never twice ([the hub sends reviewer Slack messages with its own token](docs/adr/2026-11-05-0141-the-hub-sends-reviewer-slack-messages-with-its-own-token.md)). Hub Slack identity lives in `~/.claude/kickflip/slack.json`, read or set by `board.mjs slack`; its timezone sets the weekday 09:00 to 17:00 digest window ([kickflip owns the reviewer record](docs/adr/2026-11-01-2347-kickflip-owns-the-reviewer-record.md)).
226
+ The people who get a board's PR links once they are ready, and the weekday digest. Each board keeps its own in `board.json`, which its Settings modal lists, and a new item file copies them into its own `reviewers`. The board server writes both an add and a remove: an add picks a Slack member and a GitHub login from lists it fetches with the hub's Slack token and `gh`, and the server opens the DM ([the server adds reviewers from fetched lists](docs/adr/2026-11-05-2100-the-server-adds-reviewers-from-fetched-lists.md), extending [the board server removes reviewers itself](docs/adr/2026-11-04-0119-the-board-server-removes-reviewers-itself.md)). Kickflip owns the sent messages per PR, not per card, in each board's `data/pr-slack.json` `{<owner/repo#n>: {head, links: {<name>: {channel, thread_ts, ts, reactions}}, replies}}`: a card holds 1:m PRs, and each PR has 1:m reviewer DMs sharing the same bumps and reactions. Each reviewer's posts from a board go in one thread per Slack day, kept in `data/review-digests.json` ([review posts go into one day thread per board](docs/adr/2026-11-11-1600-review-posts-go-into-one-day-thread-per-board.md)). For 7 days the hub hears that thread: each new message wakes the board's orchestrator, which answers only about the board, prefixed 🤖, or files a request for work grilling ([reviewers ask the board in the day thread](docs/adr/2026-11-12-0000-reviewers-ask-the-board-in-the-day-thread.md)). The card, Stale age, hub Slack link and digest read each reviewer's first link across the card's PRs, with an item's older `review_link_ts` and slack-bridge topic files only as a fallback ([Slack sends hang off PRs and go out from the hub tick](docs/adr/2026-11-07-0300-slack-sends-hang-off-prs-and-go-out-from-the-hub-tick.md)). The hub sends them as the owner, through the Slack user token pasted on Hub › Integrations › Slack and kept in `~/.claude/kickflip/secrets.json` beside Linear's key, opening the owner's DM with each reviewer, and records each message as it posts, so a failed one goes again next poll and a posted one never twice ([the hub sends reviewer Slack messages with its own token](docs/adr/2026-11-05-0141-the-hub-sends-reviewer-slack-messages-with-its-own-token.md)). Hub Slack identity lives in `~/.claude/kickflip/slack.json`, read or set by `board.mjs slack`; its timezone sets the weekday 09:00 to 17:00 digest window ([kickflip owns the reviewer record](docs/adr/2026-11-01-2347-kickflip-owns-the-reviewer-record.md)).
227
227
  _Avoid_: approvers, watchers
228
228
 
229
229
  **Finished item file**:
@@ -235,7 +235,7 @@ One unit of work in an **item file**, usually one PR. Its key is `<file>/<id>`.
235
235
  _Avoid_: ticket (the identity of its work in the board’s ticket source)
236
236
 
237
237
  **Task**:
238
- A work item with no ticket, keyed `T-<n>` (its board's next number), with a quiet Task badge in the ticket slot. Every new card starts as one. It gets a ticket from `--ticket <id>`, `--new-ticket`, or a yes to its grill's ticket question, which is asked only on a board with a **ticket source**; a board with none keeps every card a task ([a task is a card with no ticket, keyed T-<n>](docs/adr/2026-11-09-1500-a-task-is-a-card-with-no-ticket-keyed-t-n.md)).
238
+ A work item with no ticket, keyed `T-<n>` (its board's next number), with a quiet Task badge in the ticket slot. Every new card starts as one. It gets a ticket from `--ticket <id>`, `--new-ticket`, or the board making one when the card goes ready, which happens only on a board with a **ticket source**; a board with none keeps every card a task ([tickets are made at ready](docs/adr/2026-11-10-1600-tickets-are-made-at-ready.md), [a task is a card with no ticket, keyed T-<n>](docs/adr/2026-11-09-1500-a-task-is-a-card-with-no-ticket-keyed-t-n.md)).
239
239
  _Avoid_: unticketed card
240
240
 
241
241
  **Ticket**:
@@ -271,7 +271,7 @@ A color named by what it means, `--color-quiet`, `--color-info`, `--color-notice
271
271
  _Avoid_: tone token, theme color, badge color
272
272
 
273
273
  **Colour rule**:
274
- A colour says whose turn it is: red (danger) for faults, such as failed, down, not listening or spending, and the sidebar's "N need you" chip; orange (notice) for attention and work, such as Action needed, the Needs you box, a New card, a Next line while it is someone's turn, a builder's line, Working or Starting; blue (info) only for review and notice, something for the owner to read or see, such as an unread review, a new version to reload or a changed line's flash; grey (quiet) for idle, such as ticket ids, a Todo or Done card's Next, the Done ring, Stopped or usage that is fine, which takes no other colour. When several statuses compete for one mark, the order is red > orange > blue > green > grey (AGENTS.md). Pick a new colour by it ([colour says who's waiting](docs/adr/2026-11-01-1817-colour-says-whos-waiting.md)).
274
+ A colour says whose turn it is: red (danger) for faults, such as failed, down, not listening or spending, and the sidebar's "N need you" chip; orange (notice) for attention and work, such as Action needed, the Needs you box, a New card, a Next line while it is someone's turn, a builder's line, Working or Starting; blue (info) only for review and notice, something for the owner to read or see, such as an unread review, a new version to reload or a changed line's flash; grey (quiet) for idle, such as ticket ids, a Todo or Done card's Next, the Done ring, Stopped or usage that is fine, which takes no other colour. A sidebar row whose board's newest needs read failed keeps its last good line and goes flat gray, "(stale)" after its word, once that line is 15 seconds old; stale outranks every colour on that row, the one place a lower colour hides a higher. When several statuses compete for one mark, the order is red > orange > blue > green > grey (AGENTS.md). Pick a new colour by it ([colour says who's waiting](docs/adr/2026-11-01-1817-colour-says-whos-waiting.md)).
275
275
  _Avoid_: warning colour (for attention), action colour (for blue)
276
276
 
277
277
  **Follow-up**:
@@ -365,6 +365,10 @@ _Avoid_: rebase lander, conflict fix
365
365
  The orchestrator's stop of a run the board launched on a card, with every process under it: `board.mjs builder stop` for its headless builder, lander or rebase run, `board.mjs land stop` for its land, the suite included. A stopped build stays In Progress, waiting on the orchestrator, and nothing relaunches it; a stopped Merge land leaves the land queue and the card's Merge shows again. The card's status line and thread line read the stop in one pattern, "build stopped by orchestrator" or "land stopped by orchestrator". A bump, the owner's or the orchestrator's `item bump`, puts the card's land ahead in the land queue without stopping the one running ([the orchestrator stops the board's own runs](docs/adr/2026-11-05-1809-the-orchestrator-stops-the-boards-own-runs.md)).
366
366
  _Avoid_: kill, cancel, Stopped (the status), land first
367
367
 
368
+ **Commit standard**:
369
+ Every commit a card lands has a Conventional subject of at most 72 characters, "<type>(<scope>): <summary>", the type one of the Angular set (feat, fix, refactor, docs, test, chore, perf, build, ci, style, revert), a "!" for a breaking change, the scope optional, lowercase and naming the area; the card's ref is never in the subject but in a `Refs: <ref>` trailer above Co-Authored-By. Land refuses any other shape; a GitHub board's PR title is the same kind of subject and its squash merge is that title over the PR's body and trailers; a release is `chore(release): <x.y.z>` listing the subjects landed since the last tag ([commits are Conventional and name their card in a Refs trailer](docs/adr/2026-11-11-1700-commits-are-conventional-and-name-their-card-in-a-refs-trailer.md)).
370
+ _Avoid_: "#N: subject", ref prefix, Version X.Y.Z (as a release subject)
371
+
368
372
  **Landing**:
369
373
  A board's one choice of how a card lands, a section above Auto in Board settings, shown on a GitHub board that builds in its own clone and on the hub board, which starts on Merge (no other local board shows it): **Draft PR** (each card opens a draft PR and waits for the owner to mark it ready), **Ready PR** (the hub's GitHub check marks the draft ready for review once its CI passes) or **Merge** (no PR opens; each card lands on the board's base branch, which is pushed, and turning it on needs Push main granted, except on the hub board). On a PR mode the hub board's builders branch from origin's base branch in its folder and each finish opens a PR; on Merge they branch from the folder's own base branch and land there, pushing it only with Push main granted. Reviewers show only while cards open PRs. The words never say "main", whatever the base branch. **Auto-merge** stays its own switch and covers both: merging an approved PR, and landing a build that waits to merge into the base branch ([Landing is one choice](docs/adr/2026-11-05-0200-landing-is-one-choice-draft-pr-ready-pr-or-merge.md), [the hub board shows Landing](docs/adr/2026-11-05-1100-the-hub-board-shows-landing-and-defaults-to-merge.md)).
370
374
  It is stored as two `board.json` settings, read together: `prs`, on unless set (off is Merge), and `skip_draft`, off unless set (on is Ready PR); `board.mjs settings set prs|skip-draft` sets each. With no reviewers on the board a PR merges once it is green and clean, with no approval ([a land waits for your Merge](docs/adr/2026-11-04-2100-a-land-waits-for-your-merge.md), [a board can skip the draft](docs/adr/2026-11-04-1913-a-board-can-skip-the-draft.md)).