@techierathore/techieflow 1.0.4 → 1.1.1

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 (148) hide show
  1. package/.claude/commands/TechieFlow/agents/flow-master.md +2 -0
  2. package/.claude/commands/TechieFlow/agents/verifier.md +2 -2
  3. package/.claude/commands/TechieFlow/tasks/_develop-mode.md +34 -0
  4. package/.claude/commands/TechieFlow/tasks/_owner-language.md +1 -0
  5. package/.claude/commands/TechieFlow/tasks/_status-update-gate.md +4 -3
  6. package/.claude/commands/TechieFlow/tasks/_yolo-mode.md +2 -2
  7. package/.claude/commands/TechieFlow/tasks/amend-docs.md +2 -2
  8. package/.claude/commands/TechieFlow/tasks/day1-brownfield.md +3 -3
  9. package/.claude/commands/TechieFlow/tasks/day1-greenfield.md +5 -5
  10. package/.claude/commands/TechieFlow/tasks/develop-end-to-end.md +30 -0
  11. package/.claude/commands/TechieFlow/tasks/fix-issues.md +3 -2
  12. package/.claude/commands/TechieFlow/tasks/generate-html.md +2 -2
  13. package/.claude/commands/TechieFlow/tasks/handoff-phase.md +2 -2
  14. package/.claude/commands/TechieFlow/tasks/mockups.md +2 -2
  15. package/.claude/commands/TechieFlow/tasks/productguide.md +2 -2
  16. package/.claude/commands/TechieFlow/tasks/render-workflow-docs.md +1 -1
  17. package/.claude/commands/TechieFlow/tasks/triage-and-fix.md +2 -2
  18. package/.claude/commands/TechieFlow/tasks/triage-issues.md +2 -2
  19. package/.claude/commands/TechieFlow/tasks/verify-phase.md +12 -11
  20. package/.opencode/plugin/techieflow.js +194 -14
  21. package/.tfcore/agents/flow-master.md +2 -0
  22. package/.tfcore/agents/verifier.md +2 -2
  23. package/.tfcore/core-config.yaml +2 -1
  24. package/.tfcore/hooks/block-git.sh +4 -2
  25. package/.tfcore/hooks/guard-build.sh +5 -1
  26. package/.tfcore/hooks/guard-db.sh +112 -13
  27. package/.tfcore/hooks/guard-status-html.sh +86 -2
  28. package/.tfcore/hooks/guard-verify-deps.sh +16 -1
  29. package/.tfcore/hooks/guard-verify.sh +8 -3
  30. package/.tfcore/hooks/sweep-artifacts.sh +46 -0
  31. package/.tfcore/hooks/yolo-allow.sh +27 -0
  32. package/.tfcore/standards/blazor-zoom.cs.txt +191 -0
  33. package/.tfcore/standards/coding-standards-dotnet.md +31 -3
  34. package/.tfcore/standards/owner-words.txt +23 -0
  35. package/.tfcore/tasks/_develop-mode.md +34 -0
  36. package/.tfcore/tasks/_owner-language.md +1 -0
  37. package/.tfcore/tasks/_status-update-gate.md +4 -3
  38. package/.tfcore/tasks/_yolo-mode.md +2 -2
  39. package/.tfcore/tasks/amend-docs.md +2 -2
  40. package/.tfcore/tasks/day1-brownfield.md +3 -3
  41. package/.tfcore/tasks/day1-greenfield.md +5 -5
  42. package/.tfcore/tasks/develop-end-to-end.md +30 -0
  43. package/.tfcore/tasks/fix-issues.md +3 -2
  44. package/.tfcore/tasks/generate-html.md +2 -2
  45. package/.tfcore/tasks/handoff-phase.md +2 -2
  46. package/.tfcore/tasks/mockups.md +2 -2
  47. package/.tfcore/tasks/productguide.md +2 -2
  48. package/.tfcore/tasks/render-workflow-docs.md +1 -1
  49. package/.tfcore/tasks/triage-and-fix.md +2 -2
  50. package/.tfcore/tasks/triage-issues.md +2 -2
  51. package/.tfcore/tasks/verify-phase.md +12 -11
  52. package/.tfcore/telemetry/SCHEMA.md +10 -2
  53. package/.tfcore/telemetry/install-metrics.sh +3 -2
  54. package/.tfcore/telemetry/tf-metrics.sh +38 -2
  55. package/.tfcore/templates/stack-defaults/dotnet.md +3 -1
  56. package/.tfcore/templates/v4custom/app-agents-md-tmpl.md +6 -0
  57. package/.tfcore/templates/v4custom/app-architecture-tmpl.md +5 -0
  58. package/.tfcore/templates/v4custom/app-brd-tmpl.md +7 -4
  59. package/.tfcore/templates/v4custom/app-checklist-tmpl.md +11 -0
  60. package/.tfcore/templates/v4custom/app-phase-brd-tmpl.md +94 -0
  61. package/.tfcore/templates/v4custom/app-phase-uidesign-tmpl.md +60 -0
  62. package/.tfcore/templates/v4custom/app-phases-tmpl.md +2 -1
  63. package/.tfcore/templates/v4custom/app-uidesign-tmpl.md +4 -2
  64. package/.tfcore/templates/v4custom/build-subagent-prompt.md +2 -2
  65. package/.tfcore/templates/v4custom/html-render-shell.md +6 -2
  66. package/.tfcore/utils/__pycache__/tf-devguide-list.cpython-312.pyc +0 -0
  67. package/.tfcore/utils/__pycache__/tf-doc-check.cpython-312.pyc +0 -0
  68. package/.tfcore/utils/__pycache__/tf-split-brd.cpython-312.pyc +0 -0
  69. package/.tfcore/utils/__pycache__/tf-status-facts.cpython-312.pyc +0 -0
  70. package/.tfcore/utils/__pycache__/tf-verify-list.cpython-312.pyc +0 -0
  71. package/.tfcore/utils/tf-appium.mjs +179 -0
  72. package/.tfcore/utils/tf-assets-browser.mjs +96 -0
  73. package/.tfcore/utils/tf-assets.sh +97 -12
  74. package/.tfcore/utils/tf-brd-status.py +14 -5
  75. package/.tfcore/utils/tf-build-list.py +95 -12
  76. package/.tfcore/utils/tf-build-list.sh +2 -1
  77. package/.tfcore/utils/tf-build.sh +163 -15
  78. package/.tfcore/utils/tf-checklist-edit.py +21 -3
  79. package/.tfcore/utils/tf-ci-repro.py +685 -0
  80. package/.tfcore/utils/tf-ci-repro.sh +24 -0
  81. package/.tfcore/utils/tf-day1-files.py +55 -28
  82. package/.tfcore/utils/tf-develop.sh +264 -0
  83. package/.tfcore/utils/tf-devguide-list.py +53 -24
  84. package/.tfcore/utils/tf-doc-check.py +218 -26
  85. package/.tfcore/utils/tf-doc-tests.sh +116 -0
  86. package/.tfcore/utils/tf-emit.sh +132 -45
  87. package/.tfcore/utils/tf-feedback.sh +13 -0
  88. package/.tfcore/utils/tf-fix-close.sh +87 -31
  89. package/.tfcore/utils/tf-goal.sh +12 -12
  90. package/.tfcore/utils/tf-harness.sh +9 -4
  91. package/.tfcore/utils/tf-lock.sh +29 -0
  92. package/.tfcore/utils/tf-log-miss.py +34 -8
  93. package/.tfcore/utils/tf-login.mjs +167 -0
  94. package/.tfcore/utils/tf-maccatalyst-check.sh +92 -0
  95. package/.tfcore/utils/tf-menus.mjs +401 -0
  96. package/.tfcore/utils/tf-misses-md.py +10 -4
  97. package/.tfcore/utils/tf-mockup-parity.mjs +763 -71
  98. package/.tfcore/utils/tf-mockup-parity.sh +25 -2
  99. package/.tfcore/utils/tf-owner-text.py +233 -0
  100. package/.tfcore/utils/tf-owner-text.sh +14 -0
  101. package/.tfcore/utils/tf-phase.sh +38 -4
  102. package/.tfcore/utils/tf-portable.sh +230 -0
  103. package/.tfcore/utils/tf-render-html.py +79 -5
  104. package/.tfcore/utils/tf-req-ids.py +36 -0
  105. package/.tfcore/utils/tf-selfcheck.sh +39 -6
  106. package/.tfcore/utils/tf-split-brd.py +11 -1
  107. package/.tfcore/utils/tf-stack-check.sh +3 -0
  108. package/.tfcore/utils/tf-status-evidence.sh +11 -9
  109. package/.tfcore/utils/tf-status-facts.py +160 -45
  110. package/.tfcore/utils/tf-theme.mjs +189 -0
  111. package/.tfcore/utils/tf-triage.py +74 -17
  112. package/.tfcore/utils/tf-triage.sh +2 -0
  113. package/.tfcore/utils/tf-verify-boot.sh +529 -54
  114. package/.tfcore/utils/tf-verify-emit.sh +57 -17
  115. package/.tfcore/utils/tf-verify-env.sh +33 -4
  116. package/.tfcore/utils/tf-verify-list.py +290 -24
  117. package/.tfcore/utils/tf-verify-list.sh +3 -1
  118. package/.tfcore/utils/tf-verify-native.mjs +307 -0
  119. package/.tfcore/utils/tf-verify-screens.mjs +341 -44
  120. package/.tfcore/utils/tf-verify-screens.sh +23 -5
  121. package/.tfcore/utils/tf-verify-tests.sh +310 -19
  122. package/.tfcore/utils/tf-verify-verdict.py +163 -21
  123. package/.tfcore/utils/tf-verify-zoom.mjs +193 -0
  124. package/.tfcore/utils/tf-verify-zoom.sh +29 -0
  125. package/.tfcore/utils/tf-yolo-alias.sh +84 -0
  126. package/.tfcore/utils/tf-yolo-perms.py +135 -0
  127. package/.tfcore/utils/tf-yolo-start.sh +44 -0
  128. package/.tfcore/utils/tf-yolo.sh +31 -3
  129. package/.tfcore/utils/tf_defect.py +27 -0
  130. package/.tfcore/utils/tf_feedback.py +272 -0
  131. package/.tfcore/utils/tf_roadmap.py +35 -0
  132. package/.tfcore/utils/tf_stack_check.py +93 -0
  133. package/README.md +6 -2
  134. package/docs/TechieFlow-Installation.md +5 -3
  135. package/opencode.jsonc +6 -2
  136. package/package.json +1 -1
  137. package/scripts/install.mjs +13 -2
  138. package/.tfcore/utils/__pycache__/tf-brd-status.cpython-312.pyc +0 -0
  139. package/.tfcore/utils/__pycache__/tf-codex-bind.cpython-312.pyc +0 -0
  140. package/.tfcore/utils/__pycache__/tf-codex-telemetry.cpython-312.pyc +0 -0
  141. package/.tfcore/utils/__pycache__/tf-day1-files.cpython-312.pyc +0 -0
  142. package/.tfcore/utils/__pycache__/tf-log-miss.cpython-312.pyc +0 -0
  143. package/.tfcore/utils/__pycache__/tf-misses-md.cpython-312.pyc +0 -0
  144. package/.tfcore/utils/__pycache__/tf-mockups-locate.cpython-312.pyc +0 -0
  145. package/.tfcore/utils/__pycache__/tf-opencode-audit.cpython-312.pyc +0 -0
  146. package/.tfcore/utils/__pycache__/tf-render-html.cpython-312.pyc +0 -0
  147. package/.tfcore/utils/__pycache__/tf-triage.cpython-312.pyc +0 -0
  148. package/.tfcore/utils/__pycache__/tf-verify-verdict.cpython-312.pyc +0 -0
@@ -0,0 +1,35 @@
1
+ """tf_roadmap.py — which checklist rows are roadmap items, out of this phase's scope.
2
+
3
+ A row is a roadmap item when its acceptance line in the checklist's detail section carries
4
+ "Roadmap — not in this phase's scope" (any dash, any case). Such a row is not work for this
5
+ phase: it stays off the build list and out of the "not built yet" count, and it never makes
6
+ *build-phase the next command. Only the owner moves it, through *amend-docs.
7
+
8
+ AppManager's REQ-NFR-008 carried the marker at In Progress; tf-build-list.py put it on the
9
+ working list with a builder prompt, a builder built it against the owner's decision, and
10
+ tf-status-facts.py named *build-phase as the next command for it forever (TF-017).
11
+ tests/regression/run.sh am_017. Imported by tf-build-list.py and tf-status-facts.py.
12
+ """
13
+ import re
14
+
15
+ MARK = re.compile(r"roadmap\s*[—–-]+\s*not in this phase['’]?s scope", re.I)
16
+ ACCEPTANCE = re.compile(r"\*Acceptance:?\*|^\s*[-*]\s*Acceptance:", re.I)
17
+ OWNER = re.compile(r"<a id=['\"]d-(req-[a-z]+-\d+)['\"]|\*\*`?(REQ-[A-Z]+-\d+)`?\*\*", re.I)
18
+
19
+
20
+ def ids(text):
21
+ """The set of REQ ids whose acceptance line carries the roadmap marker.
22
+
23
+ The owner of an acceptance line is the nearest REQ anchor or bold REQ id above it, in the
24
+ detail section; status-table rows (lines starting with `|`) are never read."""
25
+ out, owner = set(), None
26
+ for line in text.splitlines():
27
+ if line.lstrip().startswith("|"):
28
+ continue
29
+ if re.match(r"^#{1,2}\s", line):
30
+ owner = None
31
+ for m in OWNER.finditer(line):
32
+ owner = (m.group(1) or m.group(2)).upper()
33
+ if owner and ACCEPTANCE.search(line) and MARK.search(line):
34
+ out.add(owner)
35
+ return out
@@ -0,0 +1,93 @@
1
+ #!/usr/bin/env python3
2
+ """tf_stack_check.py — does the code use the packages the Architecture requires? (2026-10-08)
3
+
4
+ bash .tfcore/utils/tf-stack-check.sh <App> [--json-out <file>]
5
+
6
+ Reads the `Required packages:` line of docs/<App>-Architecture.md (Stack decisions), which copies the
7
+ answer set's own line: each package in backticks, or "none". Then looks for each package in the
8
+ project's dependency files, whatever the stack: .csproj/.fsproj/.vbproj, Directory.*.props,
9
+ packages.config, package.json, requirements*.txt, pyproject.toml, Pipfile, go.mod, Cargo.toml, Gemfile,
10
+ pom.xml, build.gradle(.kts), composer.json, pubspec.yaml. Build output, dependencies, tests/.artifacts
11
+ and the framework itself are not searched.
12
+
13
+ Why: in the first *develop-end-to-end proof on OpenCode the model searched for a package by the wrong
14
+ name, decided the mandated UI library was not published, built the screen with plain components and
15
+ had every row Verified. Nothing checked that the code used what the Stack decisions named.
16
+
17
+ Prints PASS (every package referenced), FAIL (with the packages missing), or NONE (no line, or
18
+ "none"). tf-verify-verdict.py runs it itself and fails every row's build check on FAIL.
19
+ Exit 0 PASS or NONE · 1 FAIL · 2 could not run. Python 3 standard library only.
20
+ """
21
+ import json
22
+ import os
23
+ import re
24
+ import sys
25
+
26
+ PRUNE = {"bin", "obj", "node_modules", ".git", ".artifacts", ".tfcore", ".claude", ".opencode", "dist",
27
+ "packages", "TestResults", ".venv", "venv", "target", "vendor", "OldDocs"}
28
+ NAMES = re.compile(r"(?i)^(?:.*\.(?:cs|fs|vb)proj|directory\.(?:packages|build)\.props|packages\.config|package\.json|"
29
+ r"requirements[\w.-]*\.txt|pyproject\.toml|pipfile|go\.mod|cargo\.toml|gemfile|pom\.xml|"
30
+ r"build\.gradle(?:\.kts)?|composer\.json|pubspec\.yaml)$")
31
+
32
+
33
+ def required(root, app):
34
+ """-> (list of packages, the Architecture path) ; [] when there is no line or it says none."""
35
+ p = os.path.join(root, "docs", f"{app}-Architecture.md")
36
+ if not os.path.isfile(p):
37
+ return [], p
38
+ for line in open(p, encoding="utf-8", errors="replace"):
39
+ m = re.match(r"\s*(?:[-*]\s*)?\**Required packages:?\**:?\s*(.*)$", line, re.I)
40
+ if m:
41
+ return re.findall(r"`([^`\s]+)`", m.group(1)), p
42
+ return [], p
43
+
44
+
45
+ def manifests(root):
46
+ for d, dirs, files in os.walk(root):
47
+ dirs[:] = [x for x in dirs if x not in PRUNE and not x.startswith(".")]
48
+ for f in files:
49
+ if NAMES.match(f):
50
+ yield os.path.join(d, f)
51
+
52
+
53
+ def check(root, app):
54
+ pkgs, arch = required(root, app)
55
+ if not pkgs:
56
+ return {"verdict": "NONE", "architecture": os.path.relpath(arch, root), "required": [], "missing": [], "found": {}}
57
+ found = {}
58
+ files = list(manifests(root))
59
+ for f in files:
60
+ try:
61
+ text = open(f, encoding="utf-8", errors="replace").read()
62
+ except OSError:
63
+ continue
64
+ for pk in pkgs:
65
+ if re.search(r"(?<![A-Za-z0-9._-])%s(?![A-Za-z0-9._-])" % re.escape(pk), text, re.I):
66
+ found.setdefault(pk, os.path.relpath(f, root))
67
+ missing = [pk for pk in pkgs if pk not in found]
68
+ return {"verdict": "FAIL" if missing else "PASS", "architecture": os.path.relpath(arch, root),
69
+ "required": pkgs, "missing": missing, "found": found, "files_searched": len(files)}
70
+
71
+
72
+ def main(argv):
73
+ if len(argv) < 2 or argv[1] in ("-h", "--help"):
74
+ print(__doc__)
75
+ return 0 if len(argv) >= 2 else 2
76
+ app = argv[1]
77
+ r = check(os.getcwd(), app)
78
+ if "--json-out" in argv:
79
+ out = argv[argv.index("--json-out") + 1]
80
+ os.makedirs(os.path.dirname(out) or ".", exist_ok=True)
81
+ json.dump(r, open(out, "w"), indent=1)
82
+ if r["verdict"] == "NONE":
83
+ print(f"NONE {app}: {r['architecture']} lists no required packages")
84
+ elif r["verdict"] == "PASS":
85
+ print(f"PASS {app}: " + ", ".join(f"{k} in {v}" for k, v in r["found"].items()))
86
+ else:
87
+ print(f"FAIL {app}: the Architecture requires {', '.join(r['missing'])}; no project file references "
88
+ + ("it" if len(r["missing"]) == 1 else "them") + f" ({r['files_searched']} searched). Add the package; never replace it with a workaround")
89
+ return 1 if r["verdict"] == "FAIL" else 0
90
+
91
+
92
+ if __name__ == "__main__":
93
+ sys.exit(main(sys.argv))
package/README.md CHANGED
@@ -27,6 +27,8 @@ Three things make it different from prompting an agent by hand:
27
27
  - **Rules that were ignored became hooks.** Eight guards refuse an action outright and print why: any git write, a malformed status file, `Verified` without a verify run, a hand edit of a telemetry file, a database write outside build and fix, run material at the repository root, a backgrounded build in unattended mode, and ending a turn with the status gate incomplete.
28
28
  - **The work is measured.** Five append-only streams per project record what each command cost, which check caught which failure, and what each miss cost to fix.
29
29
 
30
+ The framework has an opinion about how agents talk to people. Every project's `AGENTS.md` (written at day-1) tells the agent to tag each claim it is unsure of as Certain, Likely or Guessing; to say the thing you will not want to hear first; to skip warm-up and start with the most useful sentence; and to disagree in a fixed shape ("I disagree because … I would do … The risk in your approach is …") and then do what you decide.
31
+
30
32
  The framework is technology-neutral. It asks a set of stack questions at day-1 and records the answers in the project's Architecture document; an answer set can fill them in (the owner's .NET set ships as `docs/TechieFlow-Stack-Defaults-DotNet.md`).
31
33
 
32
34
  ---
@@ -35,6 +37,8 @@ The framework is technology-neutral. It asks a set of stack questions at day-1 a
35
37
 
36
38
  Prerequisites are one-time per machine and live in [`docs/TechieFlow-Setup.md`](docs/TechieFlow-Setup.md): the toolchain, headless Chromium, and — for mobile heads — the Appium device hosts. **`python3` is required**; the guard hooks fail open without it.
37
39
 
40
+ It runs on Linux, WSL and a stock Mac. On a Mac the scripts use Apple's own bash 3.2 and BSD tools, so Homebrew, a newer bash and GNU coreutils are not needed; `python3` comes with the Command Line Tools (`xcode-select --install`).
41
+
38
42
  Copy the framework in; never `npm install` it. All three scripts locate the framework from their own directory, so invoke whichever machine's copy you are on.
39
43
 
40
44
  ```bash
@@ -82,7 +86,7 @@ flowchart TD
82
86
 
83
87
  **An existing application** is the same after day-1: `*day1-brownfield` reads the code, writes the same documents plus the DevGuide, and migrates any existing plan into the one checklist.
84
88
 
85
- **Which command next?** Pick by the weakest open row: anything unbuilt means `*build-phase`; all built but not verified means `*verify all`; all verified means `*handoff-phase`. When in doubt, build. If a session died mid-phase, the status file is stale — run `*refresh-status {App}` first, which rebuilds it from the checklist, the working tree and a fresh build.
89
+ **Which command next?** Pick by the weakest open row: anything unbuilt means `*build-phase`; all built but not verified means `*verify all`; all verified means `*handoff-phase`. When in doubt, build. A project in phases verifies one phase at a time: `*verify all {App} --phase 1` grades phase 1's checklist, and `--phase all` grades every phase in turn. Without `--phase` it grades the phase in progress. PROJECT-STATUS prints the exact line to paste. If a session died mid-phase, the status file is stale — run `*refresh-status {App}` first, which rebuilds it from the checklist, the working tree and a fresh build.
86
90
 
87
91
  **Running unattended.** Do not start a long run as a bare harness command. The supervisor survives a usage limit, a crash and an agent that stops early:
88
92
 
@@ -106,7 +110,7 @@ Replace `{App}` with your application name. Claude Code takes the long persona p
106
110
  | A change to an existing project | `… analyst *amend-docs {App} "<what changed>"` | `/flow-analyst *amend-docs {App} "…"` |
107
111
  | Brainstorm, brief, research | `… analyst *brainstorm {topic}` · `*create-project-brief` · `*research-prompt {topic}` | same, on `/flow-analyst` |
108
112
  | Build everything open | `/TechieFlow:agents:flow-master *build-phase {App}` | `/flow-master *build-phase {App}` |
109
- | Verify | `/TechieFlow:agents:verifier *verify ui\|functional\|all` | `/flow-verifier *verify all` |
113
+ | Verify | `/TechieFlow:agents:verifier *verify ui\|functional\|all {App} [--phase N\|all]` | `/flow-verifier *verify all {App} [--phase N\|all]` |
110
114
  | Bugs: log and analyse only | `… flow-master *triage-issues {App} {evidence} [verify]` | `/flow-master *triage-issues …` |
111
115
  | Bugs: fix them | `… flow-master *fix-issues {App} {folder}` | `/flow-master *fix-issues …` |
112
116
  | Bugs: the whole sequence unattended | `… flow-master *triage-and-fix {App} {evidence}` | `/flow-master *triage-and-fix …` |
@@ -16,14 +16,16 @@ You need four things on the machine.
16
16
  | Tool | Why | Check |
17
17
  |---|---|---|
18
18
  | Node.js 20 or newer | Runs the installer. Nothing is added to your project. | `node --version` |
19
- | bash | The framework's guard hooks and helper scripts run under bash. macOS and Linux have it. On Windows, work inside WSL or Git Bash. | `bash --version` |
19
+ | bash | The framework's guard hooks and helper scripts run under bash. macOS and Linux have it; the bash 3.2 that comes with macOS is enough. On Windows, work inside WSL or Git Bash. | `bash --version` |
20
20
  | Python 3 | Powers the HTML renderer, the telemetry writer and the guard hooks. | `python3 --version` |
21
- | Claude Code or OpenCode | The harness that runs the agents. Either one. Both work from the same install. | `claude --version` or `opencode --version` |
21
+ | Claude Code or OpenCode | The harness that runs the agents. Either one. Both work from the same install. The framework targets OpenCode 2; its plugin still loads on OpenCode 1.x. | `claude --version` or `opencode --version` |
22
22
 
23
23
  For a .NET project you also need the .NET SDK. Run `dotnet --version` to check.
24
24
 
25
25
  You do not need rsync, git on the command line, or a clone of this repository.
26
26
 
27
+ **On a Mac.** A stock Mac is enough. The scripts run on Apple's own bash 3.2 and the `sed`, `date`, `stat` and `xargs` that come with macOS. You do not need Homebrew, a newer bash or GNU coreutils for them. The one thing to add is Python 3: it comes with Apple's Command Line Tools, so run `xcode-select --install` once if `python3 --version` asks for them. perl and rsync already ship with macOS. Your project's own tools, such as the .NET SDK, are installed as usual.
28
+
27
29
  ---
28
30
 
29
31
  ## 1. What gets installed
@@ -312,7 +314,7 @@ It installs the framework if it is not there yet, then removes the leftover pack
312
314
  |---|---|
313
315
  | The framework is under `node_modules/@techierathore/techieflow/` and nowhere else | You ran `npm install`. See section 9. Run `npx @techierathore/techieflow@latest install`. |
314
316
  | `bash was not found` | On Windows, run the command inside WSL or Git Bash. |
315
- | `python3 was not found` | Install Python 3 and run the command again. On macOS: `brew install python3`. On Ubuntu or WSL: `sudo apt-get install -y python3`. |
317
+ | `python3 was not found` | Install Python 3 and run the command again. On macOS: `xcode-select --install` (Apple's Command Line Tools include python3), or `brew install python3`. On Ubuntu or WSL: `sudo apt-get install -y python3`. |
316
318
  | `Refusing to install into the framework itself` | You ran the command inside a clone of this repository. Pass `--target=<your project>`. |
317
319
  | `does not look installed` on update | The folder has no `.tfcore/`. Run `install` first. |
318
320
  | Claude Code does not show the `/TechieFlow:agents:analyst` command | Restart Claude Code in the project folder. Check that `.claude/commands/TechieFlow/agents/analyst.md` exists. |
package/opencode.jsonc CHANGED
@@ -589,7 +589,7 @@
589
589
  "sudo *": "ask"
590
590
  }
591
591
  },
592
- "description": "Vidur — autonomous verification (*verify ui|functional|all); writes verdicts into the checklist Requirements Status tables"
592
+ "description": "Vidur — autonomous verification (*verify ui|functional|all [--phase N|all]); writes verdicts into the checklist Requirements Status tables"
593
593
  },
594
594
  "trblazeui": {
595
595
  "prompt": "You are the TrBlazeUI sub-agent. Read `.opencode/command/trblazeui.md` (fall back, in order, to `.claude/commands/trblazeui.md`, `.claude/trblazeui.md`, `.trblazeui/TrBlazeUI-AI-Reference.md`) and fully adopt that persona and its operating guidelines — it is the authoritative persona. NuGet credentials are user-level (Windows native `%AppData%\\NuGet\\NuGet.Config`, macOS/Linux `$HOME/.nuget/NuGet/NuGet.Config`, Docker `/root/.nuget/NuGet/NuGet.Config` from `%USERPROFILE%\\.opencode-docker\\nuget\\NuGet.Config`); never put a PAT in the repository. In Docker, never assume a Windows config is decryptable and never install `maui-tizen`; verify the mounted config and use the Docker build ladder. If neither file exists (TrBlazeUI NuGet not yet deployed), report the exact source/auth failure instead of blindly running `dotnet build`. Otherwise act as an expert .NET/Blazor developer specializing in the TrBlazeUI component library: build UI screens to match the approved mockups (`docs/{AppName}-UIDesign.md` + `docs/mockups/*.html`), follow `docs/{AppName}-Coding-Standards.md`, tag work with `[REQ-UI-N]` in the checklist Remarks, log TrBlazeUI gaps to `docs/{AppName}-TrBlazeUI-Feedback.md`. Never run git or gh.",
@@ -833,6 +833,10 @@
833
833
  "template": "{file:./.tfcore/tasks/split-brd.md}",
834
834
  "description": "Split the BRD into the one docs/{App}-Checklist.md (REQ-UI/FN/RAG/NFR-* in a single Requirements Status table)."
835
835
  },
836
+ "techieflow:tasks:develop-end-to-end": {
837
+ "template": "{file:./.tfcore/tasks/develop-end-to-end.md}",
838
+ "description": "A new app from a brief to UAT, unattended: Day 1 both stages, build with inline verify and fixes, handoff; tf-develop.sh commits and pushes after each phase and writes the Build Report with time and tokens per phase. Driven by /flow-master."
839
+ },
836
840
  "techieflow:tasks:build-phase": {
837
841
  "template": "{file:./.tfcore/tasks/build-phase.md}",
838
842
  "description": "The single unified build: implement every open REQ (UI/FN/RAG/NFR) from the one Checklist by clustering and calling /trblazeui (from mockups) + /techierag as sub-agents; self-smoke (data + visual); chain the verifier. Driven by /flow-master."
@@ -855,7 +859,7 @@
855
859
  },
856
860
  "techieflow:tasks:verify-phase": {
857
861
  "template": "{file:./.tfcore/tasks/verify-phase.md}",
858
- "description": "Verifies every checklist row in a scope (ui | functional | all | REQ list) against the running app: boots it, runs the seven checks in order through the tf-verify-* scripts, writes the verdicts into the checklist and the telemetry. YOLO by default. Driven by /verifier."
862
+ "description": "Verifies every checklist row in a scope (ui | functional | all | REQ list) of one phase's checklist, or each phase in turn with --phase all, against the running app: boots it, runs the seven checks in order through the tf-verify-* scripts, writes the verdicts into the checklist and the telemetry. YOLO by default. Driven by /verifier."
859
863
  },
860
864
  "techieflow:tasks:handoff-phase": {
861
865
  "template": "{file:./.tfcore/tasks/handoff-phase.md}",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@techierathore/techieflow",
3
- "version": "1.0.4",
3
+ "version": "1.1.1",
4
4
  "description": "TechieFlow: a spec-driven development framework for AI coding agents, for Claude Code and OpenCode. One command installs it into any project.",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -392,6 +392,15 @@ const canonicalSettings = String.raw`{
392
392
  "command": "bash \"$CLAUDE_PROJECT_DIR/.tfcore/hooks/guard-verify.sh\""
393
393
  }
394
394
  ]
395
+ },
396
+ {
397
+ "matcher": "*",
398
+ "hooks": [
399
+ {
400
+ "type": "command",
401
+ "command": "bash \"$CLAUDE_PROJECT_DIR/.tfcore/hooks/yolo-allow.sh\""
402
+ }
403
+ ]
395
404
  }
396
405
  ],
397
406
  "SessionStart": [
@@ -723,7 +732,9 @@ function migrateLegacyLayout() {
723
732
  const rootConfig = join(target, "opencode.jsonc");
724
733
  if (existsSync(rootConfig) && legacyConfigPattern.test(read(rootConfig))) {
725
734
  copyFileSync(rootConfig, `${rootConfig}.bak`);
726
- copyFileSync(join(sourceRoot, "opencode.jsonc"), rootConfig);
735
+ // the content only, as the shell's `cp` onto an existing file does: copyFileSync also copies the
736
+ // template's mode, so an executable checkout of opencode.jsonc gave a different file (CI, 2026-10-04)
737
+ writeFileSync(rootConfig, readFileSync(join(sourceRoot, "opencode.jsonc")));
727
738
  say(" opencode.jsonc — legacy version backed up to opencode.jsonc.bak, replaced with current template");
728
739
  }
729
740
  say("");
@@ -742,7 +753,7 @@ function refreshRootOpenCodeConfig() {
742
753
  if (dryRun) say(" opencode.jsonc — WOULD refresh from template (no project-only content; old file → .bak)");
743
754
  else {
744
755
  copyFileSync(rootConfig, `${rootConfig}.bak`);
745
- copyFileSync(join(sourceRoot, "opencode.jsonc"), rootConfig);
756
+ writeFileSync(rootConfig, readFileSync(join(sourceRoot, "opencode.jsonc"))); // keeps its mode, as `cp` does
746
757
  say(" opencode.jsonc — refreshed from template (no project-only content; old file → opencode.jsonc.bak)");
747
758
  replaced = true;
748
759
  }