@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/README.md +14 -4
- package/dist/bundled/skills/dev-planner/SKILL.md +20 -0
- package/dist/cli.js +2986 -1656
- package/dist/effort/store/index.js +1 -1
- package/dist/{index-am92b8qp.js → index-ae290g0m.js} +2 -1
- package/dist/{index-pzpk59ma.js → index-e30zazs6.js} +1247 -567
- package/dist/{index-kv51t295.js → index-gzr2gtmh.js} +3153 -2559
- package/dist/index.js +2 -2
- package/dist/plan-prompt.md +7 -1
- package/dist/templates/epic-guard.yml +50 -0
- package/dist/templates/spec.md +4 -0
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -20,7 +20,7 @@ import {
|
|
|
20
20
|
start,
|
|
21
21
|
usage,
|
|
22
22
|
validateManifest
|
|
23
|
-
} from "./index-
|
|
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-
|
|
46
|
+
} from "./index-ae290g0m.js";
|
|
47
47
|
import {
|
|
48
48
|
CONFIG_DEFAULTS,
|
|
49
49
|
CONFIG_FILE,
|
package/dist/plan-prompt.md
CHANGED
|
@@ -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"
|
package/dist/templates/spec.md
CHANGED
|
@@ -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.
|
|
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 .",
|