@open-tomato/rafa 0.21.0 → 0.22.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/dist/index.js CHANGED
@@ -20,7 +20,7 @@ import {
20
20
  start,
21
21
  usage,
22
22
  validateManifest
23
- } from "./index-pzpk59ma.js";
23
+ } from "./index-e30zazs6.js";
24
24
  import {
25
25
  PLAN_BLOCK_KINDS,
26
26
  PLAN_HEADER_FIELDS,
@@ -43,7 +43,7 @@ import {
43
43
  openNdjsonStore,
44
44
  openSqliteStore,
45
45
  selectEffortStore
46
- } from "./index-am92b8qp.js";
46
+ } from "./index-ae290g0m.js";
47
47
  import {
48
48
  CONFIG_DEFAULTS,
49
49
  CONFIG_FILE,
@@ -43,6 +43,12 @@ on the `open-tomato/rafa` board.
43
43
  plan guess?
44
44
  * Inspect the headers the spec names: are they the ones the dev-planner
45
45
  format requires, and does each hold actual content or only placeholders?
46
+ * Inspect whether the spec adds a user-facing command or config key: when it
47
+ does and carries no `## For the documentation writer` section, report a
48
+ gap under that heading naming the command or key, always `blocking: false`,
49
+ with the assumption that the documentation tasks draw their examples from
50
+ the Design section alone. The section is optional in every other spec, and
51
+ its absence there is no gap.
46
52
  * If any inspection finds a gap, write its heading as it appears in the spec,
47
53
  the `what` explaining the gap clearly, `blocking:` for whether it must be
48
54
  answered before anything is planned, the `assumption:` you would plan under
@@ -75,7 +81,7 @@ criteria — **do not execute the plan**.
75
81
 
76
82
  {ROUTING}
77
83
 
78
- {SKILL_INDEX}
84
+ {SKILL_INDEX}{EPIC_CONTEXT}
79
85
 
80
86
  ## Spec
81
87
 
@@ -0,0 +1,50 @@
1
+ # The rafa epic guard: an issue belongs to one epic at most.
2
+ #
3
+ # Installed by `rafa init --board --epic-guard`, or by a yes to its own
4
+ # question. When an issue gains an `epic:<slug>` label while it already
5
+ # carries another, this removes the label just added and comments why.
6
+ #
7
+ # The label an issue keeps is the one whose latest add is the oldest,
8
+ # read from the issue's events, so two labels added in one edit leave the
9
+ # same one whichever run reads first. Each run removes only the label its
10
+ # own event added, so no two runs remove the same label or comment twice.
11
+ #
12
+ # rafa never reads this file. `rafa doctor` lists an issue carrying two
13
+ # `epic:` labels whether or not the guard is installed.
14
+ name: Epic guard
15
+
16
+ on:
17
+ issues:
18
+ types: [labeled]
19
+
20
+ permissions:
21
+ issues: write
22
+
23
+ jobs:
24
+ one-epic:
25
+ if: startsWith(github.event.label.name, 'epic:')
26
+ runs-on: ubuntu-latest
27
+ steps:
28
+ - name: Keep one epic label
29
+ shell: bash
30
+ env:
31
+ GH_TOKEN: ${{ github.token }}
32
+ GH_REPO: ${{ github.repository }}
33
+ ISSUE: ${{ github.event.issue.number }}
34
+ ADDED: ${{ github.event.label.name }}
35
+ run: |
36
+ set -euo pipefail
37
+ held=$(gh issue view "$ISSUE" --json labels --jq '[.labels[].name | select(startswith("epic:"))]')
38
+ if [ "$(jq 'length' <<<"$held")" -lt 2 ]; then exit 0; fi
39
+ if ! jq -e --arg added "$ADDED" 'any(.[]; . == $added)' <<<"$held" >/dev/null; then exit 0; fi
40
+ kept=$(gh api --paginate "repos/$GH_REPO/issues/$ISSUE/events" \
41
+ --jq '.[] | select(.event == "labeled") | .label.name' \
42
+ | jq -R -s -r --argjson held "$held" '
43
+ split("\n") | map(select(. != "")) | to_entries
44
+ | map(select(.value as $name | $held | any(.[]; . == $name)))
45
+ | group_by(.value) | map(max_by(.key)) | min_by(.key)
46
+ | .value // $held[0]')
47
+ if [ "$kept" = "$ADDED" ]; then exit 0; fi
48
+ gh issue edit "$ISSUE" --remove-label "$ADDED"
49
+ body=$(printf 'This issue already belongs to the epic labelled `%s`, so `%s` was removed: an issue is a member of one epic at most. To move it, remove `%s` first, then add `%s`.' "$kept" "$ADDED" "$kept" "$ADDED")
50
+ gh issue comment "$ISSUE" --body "$body"
@@ -35,3 +35,7 @@ assignees: ''
35
35
  <!-- One list item per thing that can be shown by a command. "Works well" is not an item; "bun test is green with the new cases" is. -->
36
36
 
37
37
  -
38
+
39
+ ## For the documentation writer
40
+
41
+ <!-- Optional: a spec without it is still complete, so delete this heading and comment when you skip it. The examples from the design session, kept for whoever writes the docs later: use cases grouped by situation, from a solo project up to many teams, lightest first; edge cases worth an example; config examples in the same order, from the empty config up; the analogies used; the alternatives rejected, each with its reason. Never tasks: the plan reads this only for its documentation tasks. -->
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@open-tomato/rafa",
3
- "version": "0.21.0",
3
+ "version": "0.22.0",
4
4
  "description": "Alpha. Runs a plan through the ralph loop: one Claude Code session per task, one commit per task, then a pull request and a CI wait.",
5
5
  "private": false,
6
6
  "publishConfig": {
@@ -48,7 +48,7 @@
48
48
  "bun": ">=1.3.14"
49
49
  },
50
50
  "scripts": {
51
- "build": "rm -rf dist && bun build src/rafa.ts --target=bun --outfile=dist/cli.js && bun build src/index.ts src/plan/index.ts src/effort/store/index.ts src/ports/index.ts src/learning/index.ts --target=bun --splitting --root=src --outdir=dist && cp src/PROMPT.md src/plan-prompt.md dist/ && cp -R src/bundled dist/bundled && bun build src/tools/ts-symbols/cli.ts --target=bun --outfile=dist/bundled/bin/ts-symbols && for tree in pr/plans:plans board/templates:templates; do src=src/${tree%:*}; out=dist/${tree#*:}; [ -d \"$src\" ] || continue; mkdir -p \"$out\" && cp \"$src\"/*.md \"$out\"/ || exit 1; done",
51
+ "build": "rm -rf dist && bun build src/rafa.ts --target=bun --outfile=dist/cli.js && bun build src/index.ts src/plan/index.ts src/effort/store/index.ts src/ports/index.ts src/learning/index.ts --target=bun --splitting --root=src --outdir=dist && cp src/PROMPT.md src/plan-prompt.md dist/ && cp -R src/bundled dist/bundled && bun build src/tools/ts-symbols/cli.ts --target=bun --outfile=dist/bundled/bin/ts-symbols && for tree in pr/plans:plans board/templates:templates; do src=src/${tree%:*}; out=dist/${tree#*:}; [ -d \"$src\" ] || continue; mkdir -p \"$out\" && cp \"$src\"/*.md \"$out\"/ || exit 1; for yml in \"$src\"/*.yml; do [ -e \"$yml\" ] || continue; cp \"$yml\" \"$out\"/ || exit 1; done; done",
52
52
  "prepack": "bun run build",
53
53
  "test": "bun test",
54
54
  "lint": "eslint .",