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)" +} +