From 8a55d598042d854fe93e4f86ed5962933523512a Mon Sep 17 00:00:00 2001 From: ReachableCEO Date: Wed, 17 Sep 2025 10:39:25 -0500 Subject: [PATCH] governance: keep repository root clean; remove marker file; implement repo detection via structure heuristic; update tests and system prompts/templates --- CodexHelper | 99 ++++++++++++++++++++++++++ README.md | 19 ++++- collab/proposals/01-codexhelper.llm.md | 4 +- collab/proposals/01-codexhelper.md | 12 ++-- docs/devlog/DEVLOG_LLM.md | 9 +++ docs/wrapper.md | 21 ++++++ meta/AGENTS.seed.llm.md | 2 + meta/AGENTS.seed.md | 4 ++ modes/DemoMode/defaults.yaml | 0 modes/DemoMode/mode.md | 0 nm.err | 1 + nm.out | 0 nm2.err | 1 + nm2.out | 0 nm3.err | 1 + nm3.out | 0 np.err | 1 + np.out | 0 prompts/global/system.llm.md | 3 + prompts/global/system.md | 5 ++ run.err | 1 + run.out | 0 scripts/test.sh | 33 +++++++++ templates/project/_shared/AGENTS.md | 3 + tests/00_cli_guardrails.sh | 23 ++++++ tests/01_new_mode.sh | 33 +++++++++ tests/helpers/assert.sh | 24 +++++++ 27 files changed, 291 insertions(+), 8 deletions(-) create mode 100755 CodexHelper create mode 100644 docs/wrapper.md create mode 100644 modes/DemoMode/defaults.yaml create mode 100644 modes/DemoMode/mode.md create mode 100644 nm.err create mode 100644 nm.out create mode 100644 nm2.err create mode 100644 nm2.out create mode 100644 nm3.err create mode 100644 nm3.out create mode 100644 np.err create mode 100644 np.out create mode 100644 run.err create mode 100644 run.out create mode 100755 scripts/test.sh create mode 100644 tests/00_cli_guardrails.sh create mode 100644 tests/01_new_mode.sh create mode 100644 tests/helpers/assert.sh diff --git a/CodexHelper b/CodexHelper new file mode 100755 index 0000000..43f7aa5 --- /dev/null +++ b/CodexHelper @@ -0,0 +1,99 @@ +#!/usr/bin/env bash +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" + +die() { echo "error: $*" >&2; exit 1; } +note() { echo "$*" >&2; } + +find_helper_repo_root() { + # Walk upwards to find a dir that looks like the helper repo + local d="$(pwd)" + while [ "$d" != "/" ]; do + if [ -d "$d/collab" ] && [ -f "$d/prompts/global/system.md" ]; then + printf '%s' "$d" + return 0 + fi + d="$(dirname "$d")" + done + return 1 +} + +print_help() { + cat < + CodexHelper new-project --mode --name --path [--force] + CodexHelper run [--mode ] [--prompt-file ] [--config ] [--sandbox ] [--full-auto] + CodexHelper --help + +Notes: + - Inside the CodexHelper repo, only 'new-mode' is allowed. + - Outside the repo, 'new-project' and 'run' are allowed. +EOF +} + +require_outside_repo_for() { + local subcmd="$1" + if find_helper_repo_root >/dev/null 2>&1; then + if [ "$subcmd" != "new-mode" ]; then + die "Only 'new-mode' is allowed when running inside the CodexHelper repository" + fi + fi +} + +detect_codex() { + if [ -n "${CODEX_BIN:-}" ]; then echo "$CODEX_BIN"; return 0; fi + if command -v codex >/dev/null 2>&1; then echo codex; return 0; fi + if command -v codex-cli >/dev/null 2>&1; then echo codex-cli; return 0; fi + die "No codex binary found. Set CODEX_BIN or install 'codex'/'codex-cli' in PATH." +} + +cmd_new_mode() { + local name="" + while [ $# -gt 0 ]; do + case "$1" in + --name) name="$2"; shift 2;; + --force) FORCE=1; shift;; + --help|-h) print_help; exit 0;; + *) die "Unknown option for new-mode: $1";; + esac + done + [ -n "$name" ] || die "--name is required" + local dir="modes/$name" + if [ -e "$dir" ] && [ -z "${FORCE:-}" ]; then + die "Mode '$name' already exists. Use --force to overwrite." + fi + mkdir -p "$dir" + : >"$dir/mode.md" + : >"$dir/defaults.yaml" + note "Created $dir/mode.md and $dir/defaults.yaml" +} + +cmd_new_project() { + require_outside_repo_for new-project + # Implementation follows in later milestones + die "Not yet implemented: new-project (per plan)." +} + +cmd_run() { + require_outside_repo_for run + # Implementation follows in later milestones + die "Not yet implemented: run (per plan)." +} + +main() { + local subcmd="${1:-}"; if [ -z "$subcmd" ] || [ "$subcmd" = "--help" ] || [ "$subcmd" = "-h" ]; then + print_help; exit 0 + fi + case "$subcmd" in + new-mode) shift; cmd_new_mode "$@";; + new-project) shift; cmd_new_project "$@";; + run) shift; cmd_run "$@";; + *) die "Unknown subcommand: $subcmd";; + esac +} + +main "$@" diff --git a/README.md b/README.md index 1fa6b28..806a0e3 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,18 @@ -# ChatGPTScaffolding +# ChatGPTScaffolding / CodexHelper -Scaffolding (prompts/personas/modes/rules etc) around codex-cli. Tuned for @ReachableCEO needs as a solo entrepreneur. Developed from scratch in an afternoon after three weeks of intense AI usage across multiple providers/systems. \ No newline at end of file +Scaffolding (prompts/personas/modes/rules etc) around codex-cli. Tuned for @ReachableCEO needs as a solo entrepreneur. + +CodexHelper adds: +- Modes (global/mode/project prompts) +- Project scaffolding +- Prompt composition and safe defaults +- Governance: TDD, zero technical debt, plan-first via Questions → Proposal → Plan + +Status: Phase 1 in progress — `new-mode` implemented; `new-project` and `run` coming next. + +Quickstart (dev) +- Run tests: `scripts/test.sh` (uses bats if available) +- Show help: `./CodexHelper --help` +- Create a demo mode (in this repo): `./CodexHelper new-mode --name Demo` + +See `docs/wrapper.md` and `prompts/global/` for details and governance rules. diff --git a/collab/proposals/01-codexhelper.llm.md b/collab/proposals/01-codexhelper.llm.md index 77737c5..3d42e98 100644 --- a/collab/proposals/01-codexhelper.llm.md +++ b/collab/proposals/01-codexhelper.llm.md @@ -15,8 +15,9 @@ - Layout (project): `AGENTS.md`, `prompts/{project.md,style.md?}`, `prompts/_mode/`, `codex.yaml`, `codex.sh`, `runs/`. - Governance/Propagation: non-project-specific workflow changes get recorded in `prompts/global/` and seed AGENTS templates; proposal/plan updated so scaffolding includes them. - TDD Governance: adopt test-driven development with full unit/integration tests for all features in this repo and generated projects; tests written first and required for acceptance. -- Zero Technical Debt: safety first; no technical debt; production-ready at all times; no deferring tests/docs/refactors; use sub-agents as needed. + - Zero Technical Debt: safety first; no technical debt; production-ready at all times; no deferring tests/docs/refactors; use sub-agents as needed. - Planning/Architecture Governance: plan ahead via Questions→Proposal→Plan; maintain a global architecture/module map; implement module-by-module; avoid refactors except when assumptions change and plans/docs are updated. + - Clean Root Governance: keep repo root minimal; organize assets under `docs/`, `templates/`, `collab/`, `prompts/`, `modes/`, `scripts/`, `meta/`. - Phase 1 acceptance: - new-mode creates mode skeleton - new-project scaffolds without overwrites @@ -28,6 +29,7 @@ - tests: unit/integration tests (bats) cover CLI flows and guardrails; TDD observed - zero debt: docs/tests included with every feature; no pending TODOs/deferrals; production-ready criteria met - planning: architecture/module map documented; module implementations follow approved plan with no unplanned refactors + - clean root: root remains minimal; scaffolding organizes assets under subdirectories \n+## Approval — Tick All That Apply - Subcommands approved: `new-project`, `run`, `new-mode` [ ] diff --git a/collab/proposals/01-codexhelper.md b/collab/proposals/01-codexhelper.md index b00ff45..1ef2726 100644 --- a/collab/proposals/01-codexhelper.md +++ b/collab/proposals/01-codexhelper.md @@ -41,7 +41,8 @@ Purpose: Implement a bash wrapper (CodexHelper) around codex-cli with “modes - Governance/Propagation: maintain global norms in `prompts/global/` and seed AGENTS templates; reflect such changes in proposal/plan for scaffolding. - TDD Governance: enforce test-driven development; require unit/integration tests for all features here and in generated projects. - Zero Technical Debt: safety first; always production-ready; no deferring tests/docs/refactors; leverage sub-agents when needed. - - Planning/Architecture Governance: plan ahead via Questions→Proposal→Plan; keep a global architecture/module map; implement module-by-module; avoid refactors except when assumptions change and plans/docs are updated. +- Planning/Architecture Governance: plan ahead via Questions→Proposal→Plan; keep a global architecture/module map; implement module-by-module; avoid refactors except when assumptions change and plans/docs are updated. + - Clean Root Governance: keep repo root minimal; organize assets under `docs/`, `templates/`, `collab/`, `prompts/`, `modes/`, `scripts/`, `meta/`. ## Project Layout (generated) - `AGENTS.md` (from `templates/project/_shared/AGENTS.md`) @@ -100,10 +101,11 @@ Purpose: Implement a bash wrapper (CodexHelper) around codex-cli with “modes - Precedence works: CLI options override env, which override project config, which override mode defaults. - Running `CodexHelper run` in this repo prints an error guiding usage. - Project scaffold includes `AGENTS.md` copied from `templates/project/_shared/AGENTS.md`. - - `prompts/global/{system.md, system.llm.md}` exist and are included in composition. - - Governance/Propagation honored: when norms change, update `prompts/global/` and AGENTS templates; log in DevLog. - - TDD honored: a test suite (bats) covers CLI flows and guardrails; tests pass. - - Zero Debt honored: code, tests, and docs complete; no debt items remain. +- `prompts/global/{system.md, system.llm.md}` exist and are included in composition. +- Governance/Propagation honored: when norms change, update `prompts/global/` and AGENTS templates; log in DevLog. +- TDD honored: a test suite (bats) covers CLI flows and guardrails; tests pass. +- Zero Debt honored: code, tests, and docs complete; no debt items remain. + - Clean Root honored: only essential files at root; scaffolding places assets under subdirectories. ## Open Items for Confirmation - Template coverage: include `prompts/style.md` by default? (we’ll include as optional, empty file) diff --git a/docs/devlog/DEVLOG_LLM.md b/docs/devlog/DEVLOG_LLM.md index 0c0f4de..9ade76b 100644 --- a/docs/devlog/DEVLOG_LLM.md +++ b/docs/devlog/DEVLOG_LLM.md @@ -162,3 +162,12 @@ This log is concise and structured for quick machine parsing and summarization. - Updated proposal/plan to add architecture/module map deliverable and acceptance - next: - Add `docs/architecture.md` early in implementation per plan + +## 2025-09-17T16:38Z +- context: Root cleanliness governance and marker removal +- actions: + - Added clean-root rule to system prompts and AGENTS templates + - Removed `.codexhelper-repo`; replaced guard detection with repo-structure heuristic + - Updated CLI guardrail tests accordingly +- next: + - Keep root minimal going forward; store assets under subdirectories diff --git a/docs/wrapper.md b/docs/wrapper.md new file mode 100644 index 0000000..d353813 --- /dev/null +++ b/docs/wrapper.md @@ -0,0 +1,21 @@ +# CodexHelper Wrapper — Usage and Design (Phase 1) + +Overview +- CodexHelper wraps `codex`/`codex-cli` to provide modes, project scaffolding, and prompt composition. +- Governance: TDD, zero technical debt, plan-first via Questions → Proposal → Plan, production-ready always. + +Status (Phase 1 in progress) +- Implemented: `new-mode` scaffolder (repo-only), CLI skeleton, guardrails. +- Pending (per plan): `new-project`, `run`, config precedence (YAML+yq). + +CLI +- Help: `./CodexHelper --help` +- Repo-only: `./CodexHelper new-mode --name [--force]` +- Outside-repo (pending): `CodexHelper new-project --mode --name --path [--force]` +- Outside-repo (pending): `CodexHelper run [--mode ] [--prompt-file ] [--config ] [--sandbox ] [--full-auto]` + +Development +- Tests: run `scripts/test.sh` (uses bats if available, falls back to internal runner). +- Follow TDD: write failing tests first, make them pass, refactor. +- Keep `docs/architecture.md` and README up to date as features land. + diff --git a/meta/AGENTS.seed.llm.md b/meta/AGENTS.seed.llm.md index a12b864..122e266 100644 --- a/meta/AGENTS.seed.llm.md +++ b/meta/AGENTS.seed.llm.md @@ -13,3 +13,5 @@ - Zero Technical Debt: Safety first; no technical debt; always production-ready; no deferring tests/docs/refactors; TDD by default; keep docs current. - Planning/Architecture: Plan via Questions→Proposal→Plan; maintain global architecture/module map; implement module-by-module; avoid refactors unless assumptions change and plans/docs are updated. + +- Clean Roots: Keep project root minimal; use `docs/`, `templates/`, `prompts/`, `scripts/`, etc.; avoid ad-hoc root files. diff --git a/meta/AGENTS.seed.md b/meta/AGENTS.seed.md index 168049b..02f504a 100644 --- a/meta/AGENTS.seed.md +++ b/meta/AGENTS.seed.md @@ -71,3 +71,7 @@ Customize this AGENTS.md to fit your project specifics while preserving the one- - Plan ahead: use Questions → Proposal → Plan to align before coding. - Maintain a project architecture/module map and document boundaries. - Implement module-by-module per plan; avoid refactors, except when new info requires plan/doc updates. + +## Clean Repository Roots +- Keep the project root minimal and tidy. Prefer directories over many files at root. +- Place docs, templates, prompts, and scripts under dedicated subdirectories. diff --git a/modes/DemoMode/defaults.yaml b/modes/DemoMode/defaults.yaml new file mode 100644 index 0000000..e69de29 diff --git a/modes/DemoMode/mode.md b/modes/DemoMode/mode.md new file mode 100644 index 0000000..e69de29 diff --git a/nm.err b/nm.err new file mode 100644 index 0000000..1076622 --- /dev/null +++ b/nm.err @@ -0,0 +1 @@ +Created modes/DemoMode/mode.md and modes/DemoMode/defaults.yaml diff --git a/nm.out b/nm.out new file mode 100644 index 0000000..e69de29 diff --git a/nm2.err b/nm2.err new file mode 100644 index 0000000..89fa250 --- /dev/null +++ b/nm2.err @@ -0,0 +1 @@ +error: Mode 'DemoMode' already exists. Use --force to overwrite. diff --git a/nm2.out b/nm2.out new file mode 100644 index 0000000..e69de29 diff --git a/nm3.err b/nm3.err new file mode 100644 index 0000000..1076622 --- /dev/null +++ b/nm3.err @@ -0,0 +1 @@ +Created modes/DemoMode/mode.md and modes/DemoMode/defaults.yaml diff --git a/nm3.out b/nm3.out new file mode 100644 index 0000000..e69de29 diff --git a/np.err b/np.err new file mode 100644 index 0000000..3856018 --- /dev/null +++ b/np.err @@ -0,0 +1 @@ +error: Only 'new-mode' is allowed when running inside the CodexHelper repository diff --git a/np.out b/np.out new file mode 100644 index 0000000..e69de29 diff --git a/prompts/global/system.llm.md b/prompts/global/system.llm.md index 3dc6146..ef10378 100644 --- a/prompts/global/system.llm.md +++ b/prompts/global/system.llm.md @@ -26,3 +26,6 @@ - Plan before coding via Questions → Proposal → Plan. - Maintain a global architecture/module map; document boundaries. - Implement module-by-module; avoid refactors except when assumptions change and plans/docs are updated. + +-- Clean Roots -- +- Keep repo root minimal; store assets under `docs/`, `templates/`, `collab/`, `prompts/`, `modes/`, `scripts/`, `meta/`. Avoid ad-hoc root files. diff --git a/prompts/global/system.md b/prompts/global/system.md index 1833b7b..ded27e6 100644 --- a/prompts/global/system.md +++ b/prompts/global/system.md @@ -90,6 +90,11 @@ You are a coding agent running in the Codex CLI (terminal-based). Be precise, sa - Code must be clean, maintainable, and consistent with project style. - Use multiple/sub-agents or parallelization if needed to maintain quality and speed. +## Clean Repository Roots +- Keep the repository root minimal and tidy; avoid clutter. +- Place helper/templates/docs under dedicated directories (`docs/`, `templates/`, `collab/`, `prompts/`, `modes/`, `scripts/`, `meta/`). +- Avoid ad-hoc files at root; prefer directories or hidden dotfiles only when necessary and justified. + ## Exceptions - Only bypass the questions→proposal→plan cycle when the user explicitly directs you to do so (and log that exception in the dev log). diff --git a/run.err b/run.err new file mode 100644 index 0000000..3856018 --- /dev/null +++ b/run.err @@ -0,0 +1 @@ +error: Only 'new-mode' is allowed when running inside the CodexHelper repository diff --git a/run.out b/run.out new file mode 100644 index 0000000..e69de29 diff --git a/scripts/test.sh b/scripts/test.sh new file mode 100755 index 0000000..e3647f7 --- /dev/null +++ b/scripts/test.sh @@ -0,0 +1,33 @@ +#!/usr/bin/env bash +set -euo pipefail + +ROOT_DIR="$(cd "$(dirname "$0")/.." && pwd)" + +if command -v bats >/dev/null 2>&1; then + exec bats "$ROOT_DIR/tests" +fi + +# Minimal internal test runner (fallback when bats is not installed) +echo "[info] bats not found; using internal test runner" >&2 + +failures=0 +total=0 + +for t in "$ROOT_DIR"/tests/*.sh; do + [ -f "$t" ] || continue + total=$((total+1)) + echo "[run] $t" + if bash "$t"; then + echo "[ok] $t" + else + echo "[fail] $t" >&2 + failures=$((failures+1)) + fi +done + +echo "[summary] total=$total failures=$failures" +if [ "$failures" -ne 0 ]; then + exit 1 +fi +exit 0 + diff --git a/templates/project/_shared/AGENTS.md b/templates/project/_shared/AGENTS.md index 70e545e..62dfc95 100644 --- a/templates/project/_shared/AGENTS.md +++ b/templates/project/_shared/AGENTS.md @@ -46,3 +46,6 @@ This file is copied by scaffolding into new projects. Edit to suit the project w - Plan ahead via Questions → Proposal → Plan to align before coding. - Maintain an architecture/module map and clear module boundaries. - Implement module-by-module; refactor only when new information requires plan/doc updates. + +## Clean Repository Roots +- Keep the project root minimal and tidy; prefer organizing assets under subdirectories (docs, templates, prompts, scripts, etc.). diff --git a/tests/00_cli_guardrails.sh b/tests/00_cli_guardrails.sh new file mode 100644 index 0000000..83a4ab8 --- /dev/null +++ b/tests/00_cli_guardrails.sh @@ -0,0 +1,23 @@ +#!/usr/bin/env bash +set -euo pipefail +ROOT_DIR="$(cd "$(dirname "$0")/.." && pwd)" +. "$ROOT_DIR/tests/helpers/assert.sh" + +cd "$ROOT_DIR" + +# 1) Help prints usage and exits 0 +out="$(bash ./CodexHelper --help 2>&1 || true)" +echo "$out" | grep -q "CodexHelper" || { echo "help text missing" >&2; exit 1; } + +# 2) Guardrails: inside helper repo, run/new-project should be blocked +if bash ./CodexHelper run 2>run.err 1>run.out; then + echo "run should fail in helper repo" >&2; exit 1 +fi +grep -q "Only 'new-mode'" run.err || { echo "missing guardrail message for run" >&2; exit 1; } + +if bash ./CodexHelper new-project --mode Demo --name demo --path /tmp 2>np.err 1>np.out; then + echo "new-project should fail in helper repo" >&2; exit 1 +fi +grep -q "Only 'new-mode'" np.err || { echo "missing guardrail message for new-project" >&2; exit 1; } + +exit 0 diff --git a/tests/01_new_mode.sh b/tests/01_new_mode.sh new file mode 100644 index 0000000..13b17de --- /dev/null +++ b/tests/01_new_mode.sh @@ -0,0 +1,33 @@ +#!/usr/bin/env bash +set -euo pipefail +ROOT_DIR="$(cd "$(dirname "$0")/.." && pwd)" + +cd "$ROOT_DIR" + +mode="DemoMode" +dir="modes/$mode" + +# Clean up from prior runs +rm -rf "$dir" + +# Create new mode +if ! bash ./CodexHelper new-mode --name "$mode" >nm.out 2>nm.err; then + echo "new-mode failed unexpectedly" >&2; exit 1 +fi + +[ -f "$dir/mode.md" ] || { echo "missing $dir/mode.md" >&2; exit 1; } +[ -f "$dir/defaults.yaml" ] || { echo "missing $dir/defaults.yaml" >&2; exit 1; } + +# Running again without --force should fail +if bash ./CodexHelper new-mode --name "$mode" >nm2.out 2>nm2.err; then + echo "new-mode should have failed on overwrite without --force" >&2; exit 1 +fi +grep -qi "already exists" nm2.err || { echo "missing overwrite message" >&2; exit 1; } + +# With --force should succeed +if ! bash ./CodexHelper new-mode --name "$mode" --force >nm3.out 2>nm3.err; then + echo "new-mode --force failed unexpectedly" >&2; exit 1 +fi + +exit 0 + diff --git a/tests/helpers/assert.sh b/tests/helpers/assert.sh new file mode 100644 index 0000000..15fa790 --- /dev/null +++ b/tests/helpers/assert.sh @@ -0,0 +1,24 @@ +#!/usr/bin/env bash +set -euo pipefail + +fail() { echo "ASSERTION FAILED: $*" >&2; return 1; } + +assert_eq() { + local expected="$1" actual="$2"; shift 2 + if [ "$expected" != "$actual" ]; then + fail "expected='$expected' actual='$actual' $*" + fi +} + +assert_contains() { + local haystack="$1" needle="$2"; shift 2 + if ! grep -Fq -- "$needle" <<<"$haystack"; then + fail "did not find '$needle' in output" + fi +} + +run_cmd() { + local out err rc + out="$({ err=$( { "$@"; } 2>&1 1>&3 ); rc=$?; echo "$err" >&2; echo $rc >&4; } 3>&1 4>&1)" +} +