feature-flow-cli 0.1.3__tar.gz → 0.1.4__tar.gz
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.
- {feature_flow_cli-0.1.3/feature_flow_cli.egg-info → feature_flow_cli-0.1.4}/PKG-INFO +2 -1
- {feature_flow_cli-0.1.3 → feature_flow_cli-0.1.4}/README.md +1 -0
- {feature_flow_cli-0.1.3 → feature_flow_cli-0.1.4}/adapters/codex/feature-flow/SKILL.md +2 -0
- {feature_flow_cli-0.1.3 → feature_flow_cli-0.1.4}/feature_flow/__init__.py +1 -1
- {feature_flow_cli-0.1.3 → feature_flow_cli-0.1.4}/feature_flow/cli.py +10 -3
- {feature_flow_cli-0.1.3 → feature_flow_cli-0.1.4}/feature_flow/command.py +14 -2
- {feature_flow_cli-0.1.3 → feature_flow_cli-0.1.4}/feature_flow/conductor.py +40 -1
- {feature_flow_cli-0.1.3 → feature_flow_cli-0.1.4}/feature_flow/git.py +8 -0
- {feature_flow_cli-0.1.3 → feature_flow_cli-0.1.4}/feature_flow/status.py +2 -1
- feature_flow_cli-0.1.4/feature_flow/suggest.py +23 -0
- {feature_flow_cli-0.1.3 → feature_flow_cli-0.1.4/feature_flow_cli.egg-info}/PKG-INFO +2 -1
- {feature_flow_cli-0.1.3 → feature_flow_cli-0.1.4}/feature_flow_cli.egg-info/SOURCES.txt +1 -0
- {feature_flow_cli-0.1.3 → feature_flow_cli-0.1.4}/skills/feature-flow/SKILL.md +2 -0
- {feature_flow_cli-0.1.3 → feature_flow_cli-0.1.4}/LICENSE +0 -0
- {feature_flow_cli-0.1.3 → feature_flow_cli-0.1.4}/MANIFEST.in +0 -0
- {feature_flow_cli-0.1.3 → feature_flow_cli-0.1.4}/adapters/codex/feature-flow/agents/openai.yaml +0 -0
- {feature_flow_cli-0.1.3 → feature_flow_cli-0.1.4}/agents/feature-planner.md +0 -0
- {feature_flow_cli-0.1.3 → feature_flow_cli-0.1.4}/agents/plan-reviewer.md +0 -0
- {feature_flow_cli-0.1.3 → feature_flow_cli-0.1.4}/agents/ticket-builder.md +0 -0
- {feature_flow_cli-0.1.3 → feature_flow_cli-0.1.4}/agents/ticket-reviewer.md +0 -0
- {feature_flow_cli-0.1.3 → feature_flow_cli-0.1.4}/feature_flow/__main__.py +0 -0
- {feature_flow_cli-0.1.3 → feature_flow_cli-0.1.4}/feature_flow/checks.py +0 -0
- {feature_flow_cli-0.1.3 → feature_flow_cli-0.1.4}/feature_flow/floorguard.py +0 -0
- {feature_flow_cli-0.1.3 → feature_flow_cli-0.1.4}/feature_flow/gate.py +0 -0
- {feature_flow_cli-0.1.3 → feature_flow_cli-0.1.4}/feature_flow/install.py +0 -0
- {feature_flow_cli-0.1.3 → feature_flow_cli-0.1.4}/feature_flow/prompts.py +0 -0
- {feature_flow_cli-0.1.3 → feature_flow_cli-0.1.4}/feature_flow/state.py +0 -0
- {feature_flow_cli-0.1.3 → feature_flow_cli-0.1.4}/feature_flow/tickets.py +0 -0
- {feature_flow_cli-0.1.3 → feature_flow_cli-0.1.4}/feature_flow/view.py +0 -0
- {feature_flow_cli-0.1.3 → feature_flow_cli-0.1.4}/feature_flow_cli.egg-info/dependency_links.txt +0 -0
- {feature_flow_cli-0.1.3 → feature_flow_cli-0.1.4}/feature_flow_cli.egg-info/entry_points.txt +0 -0
- {feature_flow_cli-0.1.3 → feature_flow_cli-0.1.4}/feature_flow_cli.egg-info/top_level.txt +0 -0
- {feature_flow_cli-0.1.3 → feature_flow_cli-0.1.4}/guides/brief.md +0 -0
- {feature_flow_cli-0.1.3 → feature_flow_cli-0.1.4}/guides/build.md +0 -0
- {feature_flow_cli-0.1.3 → feature_flow_cli-0.1.4}/guides/plan-review.md +0 -0
- {feature_flow_cli-0.1.3 → feature_flow_cli-0.1.4}/guides/plan.md +0 -0
- {feature_flow_cli-0.1.3 → feature_flow_cli-0.1.4}/guides/review.md +0 -0
- {feature_flow_cli-0.1.3 → feature_flow_cli-0.1.4}/guides/show.md +0 -0
- {feature_flow_cli-0.1.3 → feature_flow_cli-0.1.4}/guides/templates/commands.md +0 -0
- {feature_flow_cli-0.1.3 → feature_flow_cli-0.1.4}/guides/templates/learnings.md +0 -0
- {feature_flow_cli-0.1.3 → feature_flow_cli-0.1.4}/guides/templates/map.md +0 -0
- {feature_flow_cli-0.1.3 → feature_flow_cli-0.1.4}/guides/templates/spec.md +0 -0
- {feature_flow_cli-0.1.3 → feature_flow_cli-0.1.4}/guides/templates/ticket.md +0 -0
- {feature_flow_cli-0.1.3 → feature_flow_cli-0.1.4}/guides/templates/ui-mockup.md +0 -0
- {feature_flow_cli-0.1.3 → feature_flow_cli-0.1.4}/install.py +0 -0
- {feature_flow_cli-0.1.3 → feature_flow_cli-0.1.4}/install.sh +0 -0
- {feature_flow_cli-0.1.3 → feature_flow_cli-0.1.4}/pyproject.toml +0 -0
- {feature_flow_cli-0.1.3 → feature_flow_cli-0.1.4}/scripts/floor-guard.py +0 -0
- {feature_flow_cli-0.1.3 → feature_flow_cli-0.1.4}/scripts/flow-status.py +0 -0
- {feature_flow_cli-0.1.3 → feature_flow_cli-0.1.4}/scripts/flow-view.html +0 -0
- {feature_flow_cli-0.1.3 → feature_flow_cli-0.1.4}/scripts/flow-view.py +0 -0
- {feature_flow_cli-0.1.3 → feature_flow_cli-0.1.4}/scripts/flow.py +0 -0
- {feature_flow_cli-0.1.3 → feature_flow_cli-0.1.4}/scripts/gate.py +0 -0
- {feature_flow_cli-0.1.3 → feature_flow_cli-0.1.4}/setup.cfg +0 -0
- {feature_flow_cli-0.1.3 → feature_flow_cli-0.1.4}/skills/architect-review/SKILL.md +0 -0
- {feature_flow_cli-0.1.3 → feature_flow_cli-0.1.4}/skills/automation-design/SKILL.md +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: feature-flow-cli
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.4
|
|
4
4
|
Summary: A ticket-graph workflow for coding agents: installs the feature-flow skill into a repo
|
|
5
5
|
License-Expression: MIT
|
|
6
6
|
Project-URL: Homepage, https://github.com/hamilton-sky/feature-flow
|
|
@@ -206,6 +206,7 @@ A session's context fills up, so the flow moves to a fresh session every few tic
|
|
|
206
206
|
|
|
207
207
|
- **One owner at a time.** `start` gives the session a token, and every later call must carry it, so two sessions can never drive the same feature. `HANDOFF` and `DONE` release it.
|
|
208
208
|
- **Resuming after a closed session.** If a session ended without `HANDOFF` (you closed it, it crashed, it ran out of budget), the feature is still owned by it, and a new session stops and says so. Once you are sure the old session is gone, answer yes when the new session asks, or start it with `FLOW_TAKEOVER=1`. With `auto` the skill never takes over on its own.
|
|
209
|
+
- **Stuck on a ticket.** `python3 scripts/flow.py <feature> reset` (or `feature-flow reset <feature>`) reopens a ticket left `claimed` or `in-progress`, commits that, and clears the conductor's run state, so the next `/feature-flow <feature>` starts clean from the ticket files. `reset <NN>` reopens that one ticket, even a resolved one, to build it again. While a session owns the feature it needs `FLOW_TAKEOVER=1`. A mistyped command or feature name gets a `did you mean` hint.
|
|
209
210
|
- **Relay mode.** `FLOW_RELAY=1` hands off after every build and every review, so each phase gets a session of its own.
|
|
210
211
|
- **Nobody needs to watch.** With `auto` the skill asks nothing, and a Claude Code cloud session keeps working while you are away. You only come back to type the `HANDOFF` line.
|
|
211
212
|
|
|
@@ -187,6 +187,7 @@ A session's context fills up, so the flow moves to a fresh session every few tic
|
|
|
187
187
|
|
|
188
188
|
- **One owner at a time.** `start` gives the session a token, and every later call must carry it, so two sessions can never drive the same feature. `HANDOFF` and `DONE` release it.
|
|
189
189
|
- **Resuming after a closed session.** If a session ended without `HANDOFF` (you closed it, it crashed, it ran out of budget), the feature is still owned by it, and a new session stops and says so. Once you are sure the old session is gone, answer yes when the new session asks, or start it with `FLOW_TAKEOVER=1`. With `auto` the skill never takes over on its own.
|
|
190
|
+
- **Stuck on a ticket.** `python3 scripts/flow.py <feature> reset` (or `feature-flow reset <feature>`) reopens a ticket left `claimed` or `in-progress`, commits that, and clears the conductor's run state, so the next `/feature-flow <feature>` starts clean from the ticket files. `reset <NN>` reopens that one ticket, even a resolved one, to build it again. While a session owns the feature it needs `FLOW_TAKEOVER=1`. A mistyped command or feature name gets a `did you mean` hint.
|
|
190
191
|
- **Relay mode.** `FLOW_RELAY=1` hands off after every build and every review, so each phase gets a session of its own.
|
|
191
192
|
- **Nobody needs to watch.** With `auto` the skill asks nothing, and a Claude Code cloud session keeps working while you are away. You only come back to type the `HANDOFF` line.
|
|
192
193
|
|
|
@@ -39,6 +39,8 @@ Then run `FLOW_INVOKE='$feature-flow' python3 scripts/flow.py <feature> start`.
|
|
|
39
39
|
|
|
40
40
|
If `start` prints `STOP` naming another owner, another session may still be working this feature. Ask the user whether that session is closed. Only on a clear yes, run `start` once more with `FLOW_TAKEOVER=1`. In `auto` mode, never take over: report and stop.
|
|
41
41
|
|
|
42
|
+
If the user says the flow is stuck on a ticket or asks for a reset, run `reset` (or `reset <NN>` to redo one ticket): it reopens a half-built ticket, commits that, and clears the run, then run `start` again. It needs `FLOW_TAKEOVER=1` while a session owns the feature, on the same clear yes. Never reset on your own.
|
|
43
|
+
|
|
42
44
|
Say what will happen: for each ticket, a builder subagent and then a reviewer subagent. After every few tickets (`FLOW_TICKETS_PER_SESSION`, default 4) you hand off to a new session. Ask for a yes, unless `auto` was given.
|
|
43
45
|
|
|
44
46
|
## The loop
|
|
@@ -3,18 +3,23 @@
|
|
|
3
3
|
import sys
|
|
4
4
|
from pathlib import Path
|
|
5
5
|
|
|
6
|
+
from feature_flow import suggest
|
|
6
7
|
from feature_flow.conductor import Conductor, NoPhase, Stop
|
|
7
8
|
|
|
8
|
-
USAGE = ("usage: python3 scripts/flow.py <feature> start | next | prompt | verdict <file
|
|
9
|
+
USAGE = ("usage: python3 scripts/flow.py <feature> start | next | prompt | verdict <file> | reset [NN]\n"
|
|
9
10
|
" python3 scripts/flow.py <feature> plan-prompt <brief> [findings] | plan-review-prompt | plan-accept")
|
|
10
|
-
COMMANDS = ("start", "next", "prompt", "verdict", "plan-prompt", "plan-review-prompt", "plan-accept")
|
|
11
|
-
ARGS = {"verdict": (3,), "plan-prompt": (3, 4)}
|
|
11
|
+
COMMANDS = ("start", "next", "prompt", "verdict", "plan-prompt", "plan-review-prompt", "plan-accept", "reset")
|
|
12
|
+
ARGS = {"verdict": (3,), "plan-prompt": (3, 4), "reset": (2, 3)}
|
|
12
13
|
|
|
13
14
|
|
|
14
15
|
def main(argv=None, scripts=None):
|
|
15
16
|
args = list(sys.argv[1:] if argv is None else argv)
|
|
16
17
|
if len(args) < 2 or args[1] not in COMMANDS or not args[0] or args[0].startswith("-"):
|
|
17
18
|
print(USAGE, file=sys.stderr)
|
|
19
|
+
if len(args) >= 2 and args[0] in COMMANDS:
|
|
20
|
+
sys.stderr.write("did you mean: flow.py %s %s?\n" % (args[1], args[0]))
|
|
21
|
+
elif len(args) >= 2:
|
|
22
|
+
sys.stderr.write(suggest.hint(args[1], COMMANDS))
|
|
18
23
|
return 2
|
|
19
24
|
feature, command = args[0], args[1]
|
|
20
25
|
if feature in (".", "..") or any(c in feature for c in "/\\:"):
|
|
@@ -37,6 +42,8 @@ def main(argv=None, scripts=None):
|
|
|
37
42
|
line = conductor.plan_accept()
|
|
38
43
|
elif command == "prompt":
|
|
39
44
|
line = conductor.prompt()
|
|
45
|
+
elif command == "reset":
|
|
46
|
+
line = conductor.reset(args[2] if len(args) == 3 else None)
|
|
40
47
|
elif command == "start":
|
|
41
48
|
line = conductor.start()
|
|
42
49
|
else:
|
|
@@ -7,18 +7,25 @@ python3 scripts/flow.py, with the copy the installer put there.
|
|
|
7
7
|
import os
|
|
8
8
|
import sys
|
|
9
9
|
|
|
10
|
-
from
|
|
10
|
+
from pathlib import Path
|
|
11
|
+
|
|
12
|
+
from feature_flow import __version__, cli, install, status, suggest, view
|
|
11
13
|
|
|
12
14
|
USAGE = """\
|
|
13
15
|
usage: feature-flow install [target-repo] [--agent claude|codex|all] [--user] [--force] [--dry-run]
|
|
14
16
|
feature-flow status <feature> [--next | --counts | --check | --mermaid [plain] | --json]
|
|
15
17
|
feature-flow view <feature> [--watch] [--no-open] [--out FILE]
|
|
18
|
+
feature-flow reset <feature> [NN]
|
|
16
19
|
feature-flow --version
|
|
17
20
|
install copies the skill, its roles, scripts and guides into a repo; feature-flow install --help says more.
|
|
18
21
|
status and view read plans/<feature>/ in the current directory, like scripts/flow-status.py and scripts/flow-view.py.
|
|
22
|
+
reset reopens a half-built ticket (or ticket NN), commits that, and clears the run, like scripts/flow.py <feature> reset.
|
|
19
23
|
"""
|
|
20
24
|
|
|
21
25
|
|
|
26
|
+
COMMANDS = ("install", "status", "view", "reset", "--version", "--help")
|
|
27
|
+
|
|
28
|
+
|
|
22
29
|
def main(argv=None):
|
|
23
30
|
args = list(sys.argv[1:] if argv is None else argv)
|
|
24
31
|
if not args or args[0] in ("-h", "--help", "help"):
|
|
@@ -35,5 +42,10 @@ def main(argv=None):
|
|
|
35
42
|
return status.main(rest)
|
|
36
43
|
if command == "view":
|
|
37
44
|
return view.main(rest, here=os.path.join(install.source_root(), "scripts"))
|
|
38
|
-
|
|
45
|
+
if command == "reset":
|
|
46
|
+
if not rest or len(rest) > 2:
|
|
47
|
+
sys.stderr.write(USAGE)
|
|
48
|
+
return 2
|
|
49
|
+
return cli.main(rest[:1] + ["reset"] + rest[1:], scripts=Path.cwd() / "scripts")
|
|
50
|
+
sys.stderr.write("unknown command: %s\n%s%s" % (command, suggest.hint(command, COMMANDS), USAGE))
|
|
39
51
|
return 2
|
|
@@ -10,7 +10,7 @@ import secrets
|
|
|
10
10
|
import shutil
|
|
11
11
|
from pathlib import Path
|
|
12
12
|
|
|
13
|
-
from feature_flow import checks, git, prompts, state, tickets
|
|
13
|
+
from feature_flow import checks, git, prompts, state, suggest, tickets
|
|
14
14
|
|
|
15
15
|
|
|
16
16
|
VERDICT = re.compile(r"^REVIEW: (PASS|FAIL)[ \t\r\f\v]*$")
|
|
@@ -254,6 +254,45 @@ class Conductor:
|
|
|
254
254
|
return self.judge_review()
|
|
255
255
|
return self.pick_ticket()
|
|
256
256
|
|
|
257
|
+
def reset(self, num=None):
|
|
258
|
+
"""Put the feature back to a clean start: reopen a half-built ticket (or ticket num), commit that,
|
|
259
|
+
and forget the run. The tickets stay the truth; only the conductor's note and counters go."""
|
|
260
|
+
if not self.plan.is_dir():
|
|
261
|
+
hint = suggest.hint(self.feature, suggest.features(self.root)).strip()
|
|
262
|
+
raise Stop("no plan folder %s%s" % (self.plan, ". " + hint if hint else ""))
|
|
263
|
+
owner = self.get("owner")
|
|
264
|
+
if owner and os.environ.get("FLOW_TAKEOVER", "0") != "1":
|
|
265
|
+
raise Stop("%s is owned by session %s. if that session is closed or dead, run reset with FLOW_TAKEOVER=1"
|
|
266
|
+
% (self.feature, owner))
|
|
267
|
+
paths = tickets.ticket_files(str(self.plan / (os.environ.get("FLOW_TICKETS") or "tasks")))
|
|
268
|
+
if num is not None:
|
|
269
|
+
chosen = [p for p in paths if tickets.number(p) == num.zfill(2)]
|
|
270
|
+
if not chosen:
|
|
271
|
+
raise Stop("no ticket %s in %s" % (num, self.plan))
|
|
272
|
+
else:
|
|
273
|
+
chosen = [p for p in paths if tickets.status(p) in tickets.RESET]
|
|
274
|
+
reopened = []
|
|
275
|
+
for path in chosen:
|
|
276
|
+
if tickets.status(path) != "open":
|
|
277
|
+
tickets.set_open(path)
|
|
278
|
+
reopened.append(path)
|
|
279
|
+
if reopened:
|
|
280
|
+
nums = ", ".join(tickets.number(p) for p in reopened)
|
|
281
|
+
if not git.commit_paths(reopened, "chore(%s): reset %s to open" % (self.feature, nums)):
|
|
282
|
+
raise Stop("reopened %s but could not commit it. this session must be allowed to run git commit"
|
|
283
|
+
% nums)
|
|
284
|
+
had_run = self.state_file.is_file()
|
|
285
|
+
for path in (self.state_file, self.findings_file):
|
|
286
|
+
if path.is_file():
|
|
287
|
+
path.unlink()
|
|
288
|
+
if not reopened and not had_run:
|
|
289
|
+
return "OK nothing to reset for %s. run %s %s" % (self.feature, self.invoke, self.feature)
|
|
290
|
+
self.st = {}
|
|
291
|
+
self.log("RESET")
|
|
292
|
+
done = ["cleared the run state"] if had_run else []
|
|
293
|
+
done += ["reopened %s" % tickets.name(p) for p in reopened]
|
|
294
|
+
return "OK %s. run %s %s" % (", ".join(done), self.invoke, self.feature)
|
|
295
|
+
|
|
257
296
|
def judge_review(self):
|
|
258
297
|
if not git.tracked_clean() or git.head() != self.get("review_sha"):
|
|
259
298
|
raise Stop("the reviewer changed tracked files, which a reviewer must never do")
|
|
@@ -72,6 +72,14 @@ def tracked_clean():
|
|
|
72
72
|
and _git("diff", "--cached", "--quiet", check=False).returncode == 0)
|
|
73
73
|
|
|
74
74
|
|
|
75
|
+
def commit_paths(paths, message):
|
|
76
|
+
"""Commit these paths only, whatever else is staged."""
|
|
77
|
+
paths = [str(p) for p in paths]
|
|
78
|
+
if _git("add", "--", *paths, check=False).returncode != 0:
|
|
79
|
+
return False
|
|
80
|
+
return _git("commit", "-q", "-m", message, "--", *paths, check=False).returncode == 0
|
|
81
|
+
|
|
82
|
+
|
|
75
83
|
def commit_file(path, message):
|
|
76
84
|
if _git("add", "--", str(path), check=False).returncode != 0:
|
|
77
85
|
return False
|
|
@@ -8,7 +8,7 @@ import os
|
|
|
8
8
|
import re
|
|
9
9
|
import sys
|
|
10
10
|
|
|
11
|
-
from feature_flow import tickets
|
|
11
|
+
from feature_flow import suggest, tickets
|
|
12
12
|
|
|
13
13
|
USAGE = "usage: python3 scripts/flow-status.py <feature> [--next | --counts | --check | --mermaid [plain] | --json]"
|
|
14
14
|
|
|
@@ -48,6 +48,7 @@ def run(argv, out, err):
|
|
|
48
48
|
folder = "%s/%s/%s" % (root, feature, _env("FLOW_TICKETS", "tasks"))
|
|
49
49
|
if not os.path.isdir(folder):
|
|
50
50
|
err.write("no ticket folder: %s\n" % folder)
|
|
51
|
+
err.write(suggest.hint(feature, suggest.features(root)))
|
|
51
52
|
return 2
|
|
52
53
|
paths = tickets.ticket_files(folder)
|
|
53
54
|
if not paths:
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"""Did-you-mean hints for a mistyped command or feature name."""
|
|
2
|
+
|
|
3
|
+
import difflib
|
|
4
|
+
import os
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def closest(word, choices):
|
|
8
|
+
"""The choice nearest to word, or "" when none is close."""
|
|
9
|
+
found = difflib.get_close_matches(word, list(choices), n=1, cutoff=0.6)
|
|
10
|
+
return found[0] if found else ""
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def features(root):
|
|
14
|
+
"""The plan folders under root (plans/ or FLOW_DIR)."""
|
|
15
|
+
try:
|
|
16
|
+
return sorted(name for name in os.listdir(str(root)) if os.path.isdir(os.path.join(str(root), name)))
|
|
17
|
+
except OSError:
|
|
18
|
+
return []
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def hint(word, choices, template="did you mean: %s?"):
|
|
22
|
+
match = closest(word, choices)
|
|
23
|
+
return (template % match + "\n") if match else ""
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: feature-flow-cli
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.4
|
|
4
4
|
Summary: A ticket-graph workflow for coding agents: installs the feature-flow skill into a repo
|
|
5
5
|
License-Expression: MIT
|
|
6
6
|
Project-URL: Homepage, https://github.com/hamilton-sky/feature-flow
|
|
@@ -206,6 +206,7 @@ A session's context fills up, so the flow moves to a fresh session every few tic
|
|
|
206
206
|
|
|
207
207
|
- **One owner at a time.** `start` gives the session a token, and every later call must carry it, so two sessions can never drive the same feature. `HANDOFF` and `DONE` release it.
|
|
208
208
|
- **Resuming after a closed session.** If a session ended without `HANDOFF` (you closed it, it crashed, it ran out of budget), the feature is still owned by it, and a new session stops and says so. Once you are sure the old session is gone, answer yes when the new session asks, or start it with `FLOW_TAKEOVER=1`. With `auto` the skill never takes over on its own.
|
|
209
|
+
- **Stuck on a ticket.** `python3 scripts/flow.py <feature> reset` (or `feature-flow reset <feature>`) reopens a ticket left `claimed` or `in-progress`, commits that, and clears the conductor's run state, so the next `/feature-flow <feature>` starts clean from the ticket files. `reset <NN>` reopens that one ticket, even a resolved one, to build it again. While a session owns the feature it needs `FLOW_TAKEOVER=1`. A mistyped command or feature name gets a `did you mean` hint.
|
|
209
210
|
- **Relay mode.** `FLOW_RELAY=1` hands off after every build and every review, so each phase gets a session of its own.
|
|
210
211
|
- **Nobody needs to watch.** With `auto` the skill asks nothing, and a Claude Code cloud session keeps working while you are away. You only come back to type the `HANDOFF` line.
|
|
211
212
|
|
|
@@ -39,6 +39,8 @@ Then run `FLOW_INVOKE=/feature-flow python3 scripts/flow.py <feature> start`. It
|
|
|
39
39
|
|
|
40
40
|
If `start` prints `STOP` naming another owner, another session may still be working this feature. Ask the user whether that session is closed. Only on a clear yes, run `start` once more with `FLOW_TAKEOVER=1`. In `auto` mode, never take over: report and stop.
|
|
41
41
|
|
|
42
|
+
If the user says the flow is stuck on a ticket or asks for a reset, run `reset` (or `reset <NN>` to redo one ticket): it reopens a half-built ticket, commits that, and clears the run, then run `start` again. It needs `FLOW_TAKEOVER=1` while a session owns the feature, on the same clear yes. Never reset on your own.
|
|
43
|
+
|
|
42
44
|
Say what will happen: for each ticket, a builder subagent and then a reviewer subagent. After every few tickets (`FLOW_TICKETS_PER_SESSION`, default 4) you hand off to a new session. Ask for a yes, unless `auto` was given.
|
|
43
45
|
|
|
44
46
|
## The loop
|
|
File without changes
|
|
File without changes
|
{feature_flow_cli-0.1.3 → feature_flow_cli-0.1.4}/adapters/codex/feature-flow/agents/openai.yaml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{feature_flow_cli-0.1.3 → feature_flow_cli-0.1.4}/feature_flow_cli.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
{feature_flow_cli-0.1.3 → feature_flow_cli-0.1.4}/feature_flow_cli.egg-info/entry_points.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|