diff --git a/docs/images/hero.gif b/docs/images/hero.gif index bc8f0ebc..c7cd5d3f 100644 Binary files a/docs/images/hero.gif and b/docs/images/hero.gif differ diff --git a/examples/ted/EditorSettingsDialog.cs b/examples/ted/EditorSettingsDialog.cs index 86227270..7cf3437a 100644 --- a/examples/ted/EditorSettingsDialog.cs +++ b/examples/ted/EditorSettingsDialog.cs @@ -1,4 +1,5 @@ using Terminal.Gui.Editor; +using Terminal.Gui.Resources; using Terminal.Gui.Text.Indentation; using Terminal.Gui.ViewBase; using Terminal.Gui.Views; @@ -8,29 +9,27 @@ namespace Ted; internal sealed class EditorSettingsDialog : Dialog { private readonly CheckBox _autoCompleteCheck; - private readonly CheckBox _autoIndentCheck; - private readonly CheckBox _convertTabsCheck; private readonly NumericUpDown _indentSize; + private readonly CheckBox _convertTabsCheck; + private readonly CheckBox _autoIndentCheck; internal EditorSettingsDialog (Editor editor) { Title = "Settings"; Width = Dim.Percent (60); - Height = 18; + Height = 13; + // --- Tab Settings tab --- View tabSettingsTab = new () { - Title = "_Tab Settings", - Width = Dim.Fill (), - Height = Dim.Fill () + Title = "_Tab Settings" }; + View label = new Label { Text = "_Indent size:" }; _indentSize = new NumericUpDown { - X = 20, - Y = 1, - Value = editor.IndentationSize, - Width = 8 + X = Pos.Right (label) + 1, + Value = editor.IndentationSize }; _indentSize.ValueChanging += (_, e) => { @@ -42,67 +41,52 @@ internal EditorSettingsDialog (Editor editor) _convertTabsCheck = new CheckBox { - X = 1, - Y = 3, + Y = Pos.Bottom (_indentSize), Title = "Con_vert Tabs to Spaces", Value = editor.ConvertTabsToSpaces ? CheckState.Checked : CheckState.UnChecked }; _autoIndentCheck = new CheckBox { - X = 1, - Y = 5, + Y = Pos.Bottom (_convertTabsCheck), Title = "_Auto Indent", Value = editor.IndentationStrategy is not null ? CheckState.Checked : CheckState.UnChecked }; tabSettingsTab.Add ( - new Label { X = 1, Y = 1, Text = "_Indent size:" }, + label, _indentSize, _convertTabsCheck, _autoIndentCheck); _autoCompleteCheck = new CheckBox { - X = 1, - Y = 1, - Title = "Auto _Complete (Ctrl+Space)", + Title = "Auto _Complete", Value = editor.CompletionProvider is not null ? CheckState.Checked : CheckState.UnChecked }; + // --- Config tab --- View configTab = new () { - Title = "_Config", - Width = Dim.Fill (), - Height = Dim.Fill () + Title = "_Config" }; configTab.Add (_autoCompleteCheck); - Tabs tabs = new () - { - X = 0, - Y = 0, - Width = Dim.Fill (), - Height = Dim.Fill (2) - }; + // --- Tabs --- + Tabs tabs = new (); tabs.InsertTab (0, configTab); tabs.InsertTab (1, tabSettingsTab); Button okBtn = new () { - Text = "OK", - X = Pos.Center () - 6, - Y = Pos.Bottom (tabs), - IsDefault = true + Text = Strings.btnOk }; Button cancelBtn = new () { - Text = "Cancel", - X = Pos.Right (okBtn) + 2, - Y = Pos.Bottom (tabs) + Text = Strings.btnCancel }; okBtn.Accepting += (_, _) => @@ -112,7 +96,10 @@ internal EditorSettingsDialog (Editor editor) }; cancelBtn.Accepting += (_, _) => RequestStop (); - Add (tabs, okBtn, cancelBtn); + + AddButton (cancelBtn); + AddButton (okBtn); + Add (tabs); } internal bool WasAccepted { get; private set; } diff --git a/examples/ted/TedApp.cs b/examples/ted/TedApp.cs index 056c81d4..53353efc 100644 --- a/examples/ted/TedApp.cs +++ b/examples/ted/TedApp.cs @@ -1,3 +1,5 @@ +// This is a demo of ted, the Terminal.Gui.Editor example. + using System.Text; using Terminal.Gui.App; using Terminal.Gui.Configuration; diff --git a/scripts/HERO-GIF.md b/scripts/HERO-GIF.md new file mode 100644 index 00000000..7f8f40d0 --- /dev/null +++ b/scripts/HERO-GIF.md @@ -0,0 +1,86 @@ +# Hero GIF Recording Guide + +Produces `docs/images/hero.gif` — a high-quality animated GIF demonstrating ted's key features. + +## Prerequisites + +- [tuirec](https://github.com/gui-cs/tuirec) v0.3.4+ on PATH (`go install github.com/gui-cs/tuirec/cmd/tuirec@latest`) +- .NET 10 SDK (for building ted) +- `agg` is auto-downloaded by tuirec on first use + +## Build ted + +```powershell +dotnet build examples/ted -c Debug --nologo +``` + +## Record + +```powershell +$binary = "C:/Users/Tig/s/gui-cs/Editor/examples/ted/bin/Debug/net10.0/ted.exe" +$file = "./examples/ted/TedApp.cs" + +# Keystroke script — demonstrates typing, scrolling, folding, search, selection+indent, +# undo, themes, settings (autocomplete enable), autocomplete popup, disable autocomplete, +# and About box. +# Pacing: --keystroke-delay 50 (very fast, snappy feel). +$ks = 'wait:300,`// This is a demo of ted, the Terminal.Gui.Editor example app`,Enter,wait:300,PageDown,wait:80,PageDown,wait:80,PageDown,wait:200,Home,wait:300,click:5:23,wait:400,click:5:23,wait:200,PageDown,wait:80,PageDown,wait:80,PageDown,wait:80,PageDown,wait:80,PageDown,wait:80,PageDown,wait:200,Ctrl+F,wait:200,`SaveView`,wait:200,Enter,wait:250,Esc,wait:200,PageDown,wait:80,PageDown,wait:200,click:8:14,wait:150,Shift+CursorDown,Shift+CursorDown,Shift+CursorDown,Shift+CursorDown,wait:200,Tab,wait:250,Ctrl+Z,Ctrl+Z,Ctrl+Z,Ctrl+Z,Ctrl+Z,wait:250,click:20:30,wait:200,CursorDown,CursorDown,CursorDown,Enter,wait:400,click:20:30,wait:200,CursorDown,CursorDown,Enter,wait:400,click:20:30,wait:200,CursorUp,Enter,wait:400,F9,wait:150,CursorRight,CursorRight,CursorRight,Enter,wait:200,Enter,wait:250,Space,wait:150,Enter,wait:250,`Save`,wait:200,Ctrl+Space,wait:400,Esc,wait:200,Ctrl+Z,Ctrl+Z,Ctrl+Z,Ctrl+Z,Ctrl+Z,Ctrl+Z,Ctrl+Z,Ctrl+Z,Ctrl+Z,Ctrl+Z,wait:250,F9,wait:150,CursorRight,CursorRight,CursorRight,Enter,wait:200,Enter,wait:250,Space,wait:150,Enter,wait:250,click:29:1,wait:200,Enter,wait:800,Esc,wait:200,Esc,wait:200,Tab,Tab,Enter' + +tuirec record ` + --binary $binary ` + --args $file ` + --name "hero" ` + --show-command '$ ted ./examples/ted/TedApp.cs' ` + --keystrokes $ks ` + --startup-delay 2000 ` + --drain 2000 ` + --cols 120 ` + --rows 30 ` + --keystroke-delay 50 ` + --max-duration 60 ` + --cast-output ./artifacts/hero.cast ` + --verbosity high + +# Copy to final location +Copy-Item ./artifacts/hero.gif ./docs/images/hero.gif -Force +``` + +## Demo sequence + +| Time | Feature | Keys / Actions | +|--------|-----------------------|----------------------------------------------------------| +| 0-2s | File load + highlight | `$ ted ./examples/ted/TedApp.cs` typed, file opens | +| 2-5s | Type comment line | Types `// This is a demo of ted, the Terminal.Gui.Editor example app` + Enter | +| 5-6s | Scrolling | PageDown×3 then Home (show file navigation) | +| 6-7s | Folding | Click fold gutter at row 23 (collapse/expand class body) | +| 7-9s | Scroll to mid-file | 6× PageDown | +| 9-11s | Search | Ctrl+F → type "SaveView" → Enter (find next) → Esc | +| 11-13s | Selection + indent | Click col 8 + Shift+Down×4 to select, Tab to indent | +| 13-14s | Undo | Ctrl+Z×5 to revert indent | +| 14-17s | Theme switching | Theme dropdown → Anders → Green Phosphor → Dark | +| 17-19s | Settings dialog | F9 → Options → Settings → enable autocomplete → OK | +| 19-21s | Autocomplete | Type "Save" → Ctrl+Space → popup shown → Esc | +| 19-20s | Disable autocomplete | F9 → Options → Settings → uncheck autocomplete → OK | +| 20-22s | About box + Quit | Click Help → Enter → shown ~1s → Esc → Esc (quit) | + +## Tuning tips + +- **Fold target**: Line 22 (`{` of `TedApp : Window` class body) — always visible at row 23 in the initial 30-row view. Click col 5 for the fold gutter. +- **Theme dropdown**: Located at approximately col 20, row 30 (status bar, last row). Items listed top-to-bottom: Default, 8-Bit, Amber Phosphor, Anders, Dark, Green Phosphor, Light, TurboPascal 5. + - After selecting Anders (3 Down from Default), reopening shows Anders highlighted. From Anders: 2 Down = Green Phosphor. From Green Phosphor: 1 Up = Dark. +- **Help menu position**: "Help" is at col 29 in the menu bar (row 1). Use `click:29:1` to open it. The only item is "About ted…"; press Enter to select. +- **Settings dialog**: Reached via F9 (menu bar focus) → 3× CursorRight (to Options) → Enter → Enter (Settings is the only item). First tab has "Auto Complete" checkbox. Space toggles, Enter confirms OK. +- **Quit key is Esc** (not Ctrl+Q). Esc closes the topmost overlay first (search bar, popup, dialog), then quits the app when nothing is open. If the document is dirty, a "Save changes?" dialog appears with buttons [Cancel, Don't Save, Save] (Save focused). Press Tab,Tab,Enter to select "Don't Save". +- **`--kitty-keyboard` does NOT work** for navigation keys (CursorDown, PageDown, etc.) with current Terminal.Gui. Do NOT use this flag. Standard VT100 sequences work. +- **Multi-caret via Ctrl+Alt+Down** is unreliable without kitty keyboard. Use Shift+Down selection + Tab for indent demos instead. +- **After search**: the viewport centers on the found text. Budget additional PageDown presses to reach content below the match. + +## Troubleshooting + +1. **Keys not registering**: Use `--verbosity high` and check the escape sequences in stderr output. Without `--kitty-keyboard`, navigation uses standard VT100 sequences (`\x1b[B` for CursorDown, `\x1b[6~` for PageDown) which Terminal.Gui recognizes. +2. **Wrong click targets**: Do a discovery recording first — short script with just `wait:2000,Ctrl+Q`, then examine the `.cast` file to find column positions of UI elements. +3. **Theme dropdown doesn't open**: Verify the col:row coordinates match the "Theme" shortcut in the status bar. Parse the `.cast` for the "Default" text position. +4. **About dialog not appearing**: Use `click:29:1` (Help menu at col 29, row 1) instead of F9+CursorRight×4. After complex keystroke sequences, F9 menu navigation can be unreliable. +5. **File stays dirty after undos**: The autocomplete popup may auto-insert text beyond what you typed. Use 10+ Ctrl+Z to be safe, and handle the "Save changes?" dialog at quit with Tab,Tab,Enter. +6. **Recording too long**: Reduce `wait:` values or lower `--keystroke-delay`. Current recording is ~22s at delay 50. +7. **GIF too large**: The `agg` renderer produces ~0.5-2 MB GIFs at 120×30. For smaller files, reduce terminal dimensions. diff --git a/scripts/README.md b/scripts/README.md deleted file mode 100644 index 52d99efc..00000000 --- a/scripts/README.md +++ /dev/null @@ -1,43 +0,0 @@ -# scripts/ - -Operator helpers for the Codex-only autonomous sprint described in `specs/codex-autonomous-sprint.md`. - -All scripts are bash, target macOS (the Mac mini host), and are idempotent where practical. Each script supports `--help`. - -## Run Order - -```sh -# Day -1, on the Mac mini, ONCE per host: -./scripts/setup-host.sh - -# Day -1, creates $HOME/s/Terminal.Gui.Editor/codex: -./scripts/setup-agent-clone.sh codex - -# Optional: create one tracking issue for the Codex run: -./scripts/create-codex-run-issue.sh - -# Day 0: -./scripts/start-experiment.sh -tmux attach -t codex-autonomy - -# Day N, when Codex stops or you cut it off: -./scripts/collect-run.sh codex-2026-05-11 -``` - -The artifact lands in `specs/runs//` — transcript, PR list, spend snapshot, copied final report when present, and a stub `summary.md`. - -Codex integrates completed work into `experiment/codex/develop`. Use that branch for final checks before deciding whether anything should land on `develop`. - -## What each script assumes - -- `bash 4+` and `gh` on `$PATH`. -- The operator (you) is logged into `gh` with admin on `gui-cs/Editor` so the issue creator and label-creator can run. -- `codex` is installed and logged in. `setup-host.sh` installs it, but `codex login` is interactive and stays manual. -- `gh auth status` in `$HOME/s/Terminal.Gui.Editor/codex` shows an identity that can push branches and open PRs. - -## What each script will NOT do - -- Create accounts. -- Spend money on your behalf without you running the script first. -- Modify `develop` directly. -- Merge PRs. diff --git a/scripts/RECORDING-AGENT.md b/scripts/RECORDING-AGENT.md deleted file mode 100644 index c599c9d2..00000000 --- a/scripts/RECORDING-AGENT.md +++ /dev/null @@ -1,291 +0,0 @@ -# Recording Agent — ted & Terminal.Gui TUIcast Guide - -This document teaches an AI agent how to compose TUIcast keystroke scripts for -recording the `ted` example app (a Terminal.Gui `Editor` demo). Any AI system -(Claude, Copilot, Codex, etc.) can use this as context to drive `record-ted.ps1`. - -## Quick start - -```powershell -./scripts/record-ted.ps1 ` - -Name "search-replace" ` - -Title "ted: find and replace" ` - -ShowCommand '$ ted TedApp.cs' ` - -Keystrokes "wait:2000,Ctrl+H,hello,Tab,world,Alt+A,wait:1500,Esc" -``` - ---- - -## TUIcast keystroke syntax - -Key tokens use **Terminal.Gui's `Key.ToString()` / `Key.TryParse()` format**. -A keystroke script is a **comma-separated** string. Each token is one of: - -| Token type | Examples | Description | -|---|---|---| -| **Wait** | `wait:2000` | Pause N milliseconds before next key | -| **Named key** | `Enter`, `Esc`, `Tab`, `Space`, `Backspace`, `Delete` | Single special key press | -| **Arrow/nav** | `CursorUp`, `CursorDown`, `CursorLeft`, `CursorRight`, `Home`, `End`, `PageUp`, `PageDown` | Navigation keys | -| **Function key** | `F1`–`F12` | Function keys | -| **Modifier combo** | `Ctrl+S`, `Ctrl+Shift+Z`, `Alt+A`, `Shift+Tab`, `Ctrl+Alt+Shift+CursorUp` | Modifier + key | -| **Literal text** | `hello world` | Typed character-by-character (spaces included) | - -### Rules - -- Uses Terminal.Gui key format: `Ctrl+C`, `Ctrl-C`, `A-Ctrl` are all valid. -- Older aliases like `ArrowUp`, `ArrowDown`, `Escape` are accepted (prefer - `CursorUp`, `CursorDown`, `Esc`). -- **Unknown key-like tokens** (e.g. `Ctrl-Foo`) fail fast — they won't be - silently typed as literal text. -- Literal text tokens are everything that doesn't match a known key name or `wait:N`. -- Commas inside literal text are **not supported** — split around them with separate tokens. -- `wait:N` is essential between actions that trigger UI transitions (dialog open, - file load, menu animation). **Always wait after opening a dialog or menu.** - ---- - -## ted UI structure - -### Window layout - -``` -┌─ ted — Terminal.Gui.Editor demo ─────────────────────────────────────┐ -│ [MenuBar] _File _Edit _View _Options _Help │ -│ [Editor - full document editing area with gutter] │ -│ │ -│ │ -│ [StatusBar] Language | Theme | INS | Ln 1, Col 1 │ -└──────────────────────────────────────────────────────────────────────┘ -``` - -### Menu bar (activated by F10 or Alt+) - -Menu activation: -- **F10** opens the menu bar (focus lands on `File`); then press the underlined letter (e.g. `O` for Open) or navigate with arrows + `Enter`. -- **Alt+``** opens a menu directly (e.g. `Alt+F` → File). Then press the menu item's underlined letter (e.g. `Alt+F` then `O` for Open). **Do not assume `Ctrl+`-shortcuts work** for menu items — they are not all globally wired. Drive menus via F10 or Alt+letter sequences. - -**File** (`Alt+F`): -- **New** — `Alt+F` then `N` -- **Open** — `Alt+F` then `O` -- **Save** — `Alt+F` then `S` -- **Save As** — `Alt+F` then `A` -- **Quit** — `Alt+F` then `Q`, **or just `Esc`** (Terminal.Gui's default `QuitKey` is `Esc`, not `Ctrl+Q`) - -**Edit** (`Alt+E`): -- **Find...** — `Ctrl+F` -- **Replace...** — `Ctrl+H` -- ─── separator ─── -- **Undo** — `Ctrl+Z` -- **Redo** — `Ctrl+Y` -- ─── separator ─── -- **Cut** — `Ctrl+X` -- **Copy** — `Ctrl+C` -- **Paste** — `Ctrl+V` -- **Select All** — `Ctrl+A` - -**View** (`Alt+V`): -- Line Numbers (checkbox) -- Fold Indicators (checkbox) -- Word Wrap (checkbox) -- Show Tabs (checkbox) -- Scrollbars (checkbox) -- Preview Markdown - -**Options** (`Alt+O`): -- Settings... - -**Help** (`Alt+H`): -- About - -### Keyboard shortcuts (in Editor) - -| Action | Key | -|---|---| -| Move caret | Arrow keys, Home, End, PageUp, PageDown | -| Select | Shift + any movement key | -| Select all | Ctrl+A | -| Delete line | Ctrl+Shift+K | -| Undo | Ctrl+Z | -| Redo | Ctrl+Y | -| Cut | Ctrl+X | -| Copy | Ctrl+C | -| Paste | Ctrl+V | -| Find | Ctrl+F | -| Replace | Ctrl+H | -| Toggle overwrite | Insert | -| Fold/unfold | Click gutter or use fold indicators | - -### Open dialog - -Triggered via the File menu (`Alt+F` then `O`, or `F10` → `O`). A standard Terminal.Gui `OpenDialog`: -- Has a text field for the path (pre-focused) -- Type a relative or absolute path and press `Enter` -- Or navigate the file list with arrows and `Enter` -- `Esc` cancels - -### Find/Replace dialog - -Triggered by `Ctrl+F` (Find tab) or `Ctrl+H` (Replace tab): - -``` -┌─ Find / Replace ──────────────────────────────────┐ -│ [x] Match case [ ] Whole word [ ] Regex │ -│ Status: │ -│ ┌─ Find ─────────────────────────────────────────┐│ -│ │ Find: [________________] ││ -│ │ ││ -│ │ [Find Next] [Find Previous] ││ -│ └────────────────────────────────────────────────┘│ -│ ┌─ Replace ──────────────────────────────────────┐│ -│ │ Find: [________________] ││ -│ │ Replace: [________________] ││ -│ │ ││ -│ │ [Find Next] [Replace] [Replace All] ││ -│ └────────────────────────────────────────────────┘│ -│ [ Close ] │ -└───────────────────────────────────────────────────┘ -``` - -- **Ctrl+F** opens with the Find tab active; cursor in Find field -- **Ctrl+H** opens with the Replace tab active; cursor in Find field -- **Tab** moves between fields and buttons -- **Alt+N** = Find Next, **Alt+P** = Find Previous -- **Alt+R** = Replace, **Alt+A** = Replace All -- **Alt+C** = toggle Match Case, **Alt+W** = toggle Whole Word, **Alt+X** = toggle Regex -- **Esc** or **Alt+L** (Close button) dismisses the dialog - -### Settings dialog - -Triggered by Options → Settings. Has checkboxes for: -- Convert tabs to spaces -- Auto-indent -- Word wrap -- Show tabs -- Auto-complete -- Indent size (numeric) - ---- - -## Composing keystroke scripts — best practices - -1. **Always start with a wait** — `wait:1500` or `wait:2000` gives the app time to - start and render its first frame. - -2. **Use `-ShowCommand` for polish** — adds a synthetic `$ ted myfile.cs` prompt - frame before the app launches. Makes the GIF look like a real terminal session. - -3. **Use `-StartupDelay`** when the app needs extra init time (large file, network) - before you want output captured. - -4. **Wait after UI transitions** — opening a dialog, switching tabs, or loading a file - needs `wait:500` to `wait:1000` for the UI to settle before the next action. - -5. **End with `Esc`** — Terminal.Gui's default `QuitKey` is `Esc`. A single trailing - `Esc` (after any dialogs are closed) quits ted cleanly. Do **not** use `Ctrl+Q` - — it is not wired. `Alt+F, Q` via the File menu also works. - -6. **Keep recordings short** — aim for 10–30 seconds of real time. Viewers lose - interest after that. Use `--MaxDuration 60` as a safety net. - -7. **Show, don't rush** — generous waits between meaningful actions let the viewer - see what happened. `wait:1500` after a find highlights the match visually. - -8. **Open a file first** for most demos — unless you're demoing the empty-buffer - experience, start by opening a file so there's content to work with. - -9. **Use `-Verbosity high`** when debugging a keystroke script that isn't working - as expected — it logs each key token and timing to stderr. - ---- - -## Example keystroke scripts - -> **File-open idiom.** Use `Alt+F,wait:400,O,wait:600,,Enter` to open a file. -> Do not use `Ctrl+O` — menu shortcuts are not globally wired in ted. - -### Open a file and scroll - -``` -wait:2000,Alt+F,wait:400,O,wait:600,./examples/ted/TedApp.cs,Enter,wait:2000,PageDown,wait:1500,PageDown,wait:1500,Esc -``` - -### Find text - -``` -wait:2000,Alt+F,wait:400,O,wait:600,./examples/ted/TedApp.cs,Enter,wait:1500,Ctrl+F,wait:500,Editor,Alt+N,wait:1000,Alt+N,wait:1000,Esc,wait:500,Esc -``` - -### Find and replace - -``` -wait:2000,Alt+F,wait:400,O,wait:600,./examples/ted/TedApp.cs,Enter,wait:1500,Ctrl+H,wait:500,Editor,Tab,View,Alt+A,wait:1500,Esc,wait:500,Ctrl+Z,wait:1000,Esc -``` - -### Toggle view options - -``` -wait:2000,Alt+F,wait:400,O,wait:600,./README.md,Enter,wait:1500,Alt+V,wait:300,CursorDown,CursorDown,Enter,wait:1000,Alt+V,wait:300,CursorDown,CursorDown,CursorDown,Enter,wait:1500,Esc -``` - -### Type and undo - -``` -wait:2000,Hello world!,wait:1000,Enter,This is ted.,wait:1500,Ctrl+Z,wait:500,Ctrl+Z,wait:500,Ctrl+Z,wait:1500,Esc -``` - ---- - -## Invoking the script - -```powershell -# Minimal — just keystrokes -./scripts/record-ted.ps1 -Keystrokes "wait:2000,Alt+F,wait:400,O,wait:600,./README.md,Enter,wait:2000,Esc" - -# Full options -./scripts/record-ted.ps1 ` - -Name "find-replace" ` - -Title "ted: search and replace demo" ` - -ShowCommand '$ ted TedApp.cs' ` - -StartupDelay 500 ` - -Keystrokes "wait:2000,Alt+F,wait:400,O,wait:600,./examples/ted/TedApp.cs,Enter,wait:1500,Ctrl+H,wait:500,Editor,Tab,View,Alt+A,wait:1500,Esc,wait:500,Esc" ` - -Cols 120 ` - -Rows 36 ` - -MaxDuration 45 -``` - -### Parameters - -| Parameter | Required | Default | Description | -|---|---|---|---| -| `-Keystrokes` | **Yes** | — | The TUIcast keystroke script | -| `-Name` | No | `demo` | Short ID for filenames (`ted-.gif`) | -| `-Title` | No | `ted demo` | Title in cast metadata | -| `-ShowCommand` | No | — | Synthetic shell prompt pre-roll (e.g. `'$ ted foo.cs'`) | -| `-StartupDelay` | No | 0 | Ms to wait after process start before output capture | -| `-InputDelay` | No | 0 | Ms pause before scripted keys begin | -| `-Output` | No | `artifacts/tuicast/ted-.gif` | GIF path | -| `-CastOutput` | No | `artifacts/tuicast/ted-.cast` | Cast path | -| `-Cols` | No | 120 | Terminal columns | -| `-Rows` | No | 36 | Terminal rows | -| `-MaxDuration` | No | 60 | Safety timeout (seconds) | -| `-DrainMs` | No | 1500 | Wait after last keystroke | -| `-Verbosity` | No | — | `low`, `medium`, or `high` (debug logging) | -| `-SkipBuild` | No | false | Skip `dotnet build` | -| `-TuicastVersion` | No | `0.1.2` | Auto-download version | - ---- - -## For AI agents — how to use this - -When asked to "record ted doing X", follow this process: - -1. **Read this document** for keystroke syntax and ted's UI layout. -2. **Plan the interaction** — break the demo into steps (open file → navigate → - perform action → show result → close). -3. **Compose the keystroke string** — use waits generously between transitions. -4. **Call the script** with appropriate `-Name` and `-Title`. -5. **Report the output paths** back to the user. - -You do NOT need to know the exact pixel layout — TUIcast drives the app through -its terminal input, just like a user would type. Focus on the logical key -sequence to accomplish the demo goal. diff --git a/scripts/collect-run.sh b/scripts/collect-run.sh deleted file mode 100755 index 0a78048f..00000000 --- a/scripts/collect-run.sh +++ /dev/null @@ -1,116 +0,0 @@ -#!/usr/bin/env bash -# collect-run.sh — gather Codex autonomous sprint artifacts into -# specs/runs//. - -set -euo pipefail - -RUN="${1:-}" - -usage () { - cat <<'EOF' -Usage: ./scripts/collect-run.sh - - run-name: arbitrary slug — e.g. "codex-2026-05-11". - -Creates specs/runs// in the operator's clone (the one this script -runs from, NOT the Codex clone), and populates it with: - - - prs.json — PRs filtered by experiment/codex/* branches - - integration-commits.txt — commits on experiment/codex/develop vs develop - - integration-diffstat.txt — diffstat for final-check branch vs develop - - codex-transcript.jsonl — best-effort transcript dump - - codex-final.md — copy of Codex's self-report, when present - - spend.txt — empty template; fill from OpenAI dashboard - - summary.md — empty run-summary template -EOF -} - -if [[ "${RUN:-}" == "" || "${RUN}" == "--help" || "${RUN}" == "-h" ]]; then - usage - exit 0 -fi - -REPO_ROOT="$(git rev-parse --show-toplevel)" -OUT="$REPO_ROOT/specs/runs/$RUN" -mkdir -p "$OUT" - -echo "==> Collecting PRs for prefix experiment/codex/*" -gh pr list --state all \ - --search "head:experiment/codex" \ - --json number,title,headRefName,author,state,createdAt,closedAt,mergedAt,additions,deletions,changedFiles,url \ - > "$OUT/prs.json" || true - -echo "==> Collecting integration branch summary" -git fetch origin develop experiment/codex/develop || true -if git show-ref --verify --quiet refs/remotes/origin/experiment/codex/develop; then - git log --oneline origin/develop..origin/experiment/codex/develop > "$OUT/integration-commits.txt" || true - git diff --stat origin/develop...origin/experiment/codex/develop > "$OUT/integration-diffstat.txt" || true -else - echo "origin/experiment/codex/develop not found" > "$OUT/integration-commits.txt" - echo "origin/experiment/codex/develop not found" > "$OUT/integration-diffstat.txt" -fi - -WORK="$HOME/s/Terminal.Gui.Editor/codex" -if [[ -f "$WORK/specs/runs/codex-final.md" ]]; then - cp "$WORK/specs/runs/codex-final.md" "$OUT/codex-final.md" -elif [[ -f "$WORK/specs/runs/$RUN/codex-final.md" ]]; then - cp "$WORK/specs/runs/$RUN/codex-final.md" "$OUT/codex-final.md" -fi - -latest=$(ls -t "$HOME/.codex/sessions/"*.jsonl 2>/dev/null | head -1 || true) -if [[ -n "${latest:-}" ]]; then - cp "$latest" "$OUT/codex-transcript.jsonl" || true -fi - -cat > "$OUT/spend.txt" <<'EOF' -# Fill in from the OpenAI dashboard. - -codex: USD ____ (start) → USD ____ (end) = USD ____ - -wall-clock minutes: - codex: ____ -EOF - -cat > "$OUT/summary.md" <<'EOF' -# Codex run summary — - -> Fill this in after collect-run.sh runs. - -## 1. PRs Opened - -See `prs.json`. - -## 2. Integration Branch - -Final-check branch: `experiment/codex/develop` - -See `integration-commits.txt` and `integration-diffstat.txt`. - -## 3. Features Completed - -List each feature and the PR that implements it. - -## 4. Validation - -Record build, tests, format, cleanup, benchmark, and CI outcomes. - -## 5. Blockers - -List human-review, dependency, CI, environment, or design blockers. - -## 6. Risks - -List known regressions, incomplete DoD items, or decisions still open. - -## 7. Cost - -See `spend.txt`. - -## 8. Notes - -Anything surprising or useful for the next run. -EOF - -echo -echo "Artifacts at: $OUT" -ls -la "$OUT" diff --git a/scripts/create-codex-run-issue.sh b/scripts/create-codex-run-issue.sh deleted file mode 100755 index 04b5ba96..00000000 --- a/scripts/create-codex-run-issue.sh +++ /dev/null @@ -1,82 +0,0 @@ -#!/usr/bin/env bash -# create-codex-run-issue.sh — create one tracking issue for the Codex autonomous sprint. - -set -euo pipefail - -REPO="gui-cs/Editor" -DRY=0 - -usage () { - cat <<'EOF' -Usage: ./scripts/create-codex-run-issue.sh [--dry-run] - -Creates one issue on gui-cs/Editor for the Codex-only autonomous sprint. -Ensures the labels agent:codex and experiment exist. - -The issue is optional; scripts/start-agent.sh can run directly from specs/plan.md. -EOF -} - -case "${1:-}" in - --help|-h) usage; exit 0 ;; - --dry-run) DRY=1 ;; - '') ;; - *) echo "error: unknown arg: $1" >&2; exit 1 ;; -esac - -run () { - if (( DRY )); then echo "DRY: $*"; else "$@"; fi -} - -ensure_label () { - local name="$1" color="$2" desc="$3" - if ! gh -R "$REPO" label list --json name --jq '.[].name' | grep -qx "$name"; then - run gh -R "$REPO" label create "$name" --color "$color" --description "$desc" - fi -} - -echo "==> Ensuring labels exist on $REPO" -ensure_label "agent:codex" "1d76db" "Codex autonomous sprint" -ensure_label "experiment" "fbca04" "Tracking work created by autonomous development runs" - -BODY=$(cat <<'EOF' -## Codex autonomous sprint - -Run the Codex-only autonomous sprint described in [`specs/codex-autonomous-sprint.md`](https://github.com/gui-cs/Editor/blob/develop/specs/codex-autonomous-sprint.md). - -**Goal:** move `gui-cs/Editor` toward the MLP in [`specs/plan.md`](https://github.com/gui-cs/Editor/blob/develop/specs/plan.md). - -**Required reading before coding:** - -- [`specs/constitution.md`](https://github.com/gui-cs/Editor/blob/develop/specs/constitution.md) -- [`specs/plan.md`](https://github.com/gui-cs/Editor/blob/develop/specs/plan.md) -- [`specs/public-api.md`](https://github.com/gui-cs/Editor/blob/develop/specs/public-api.md) -- [`specs/decisions.md`](https://github.com/gui-cs/Editor/blob/develop/specs/decisions.md) -- The relevant `specs//spec.md` for each selected feature. -- [`CLAUDE.md`](https://github.com/gui-cs/Editor/blob/develop/CLAUDE.md) for coding standards. - -**How to work:** - -1. Maintain `experiment/codex/develop` as the Codex shadow develop branch. -2. Create feature branches under `experiment/codex/` from `experiment/codex/develop`. -3. Open feature PRs against `experiment/codex/develop`. -4. After validation, integrate completed feature work into `experiment/codex/develop` and push it. -5. Never push to or merge into `develop`. -6. Before stopping, write `specs/runs/codex-final.md` or `specs/runs//codex-final.md` with PRs opened, features completed, blockers, validation, and follow-up risks. - -The operator will run final checks from `experiment/codex/develop`. - -**Terminal.Gui bug bar:** no speculative upstream issues. File an issue on `gui-cs/Terminal.Gui` only after adding a failing unit test in this repo that proves the suspected TG bug. -EOF -) - -title="[codex] Autonomous MLP sprint" -echo "==> Creating: $title" -run gh -R "$REPO" issue create \ - --title "$title" \ - --body "$BODY" \ - --label "agent:codex" \ - --label "experiment" - -echo -echo "Done. Next: ./scripts/start-experiment.sh" diff --git a/scripts/record-ted.ps1 b/scripts/record-ted.ps1 deleted file mode 100644 index 1ef5efe7..00000000 --- a/scripts/record-ted.ps1 +++ /dev/null @@ -1,264 +0,0 @@ -<# -.SYNOPSIS - Records a ted session with TUIcast using a caller-supplied keystroke script. - -.DESCRIPTION - Generic recording wrapper for the examples/ted app. An AI agent (or human) - supplies the --Keystrokes parameter describing what to demonstrate, and this - script handles tool resolution, building, and invoking tuicast record. - - Output goes to artifacts/tuicast/ by default. If tuicast or agg are not on - PATH, they are automatically downloaded from - https://github.com/gui-cs/TUIcast/releases and installed into ~/tools. - - See scripts/RECORDING-AGENT.md for the keystroke syntax reference and - guidance on composing keystroke scripts for ted. - -.PARAMETER Keystrokes - TUIcast keystroke script (required). Comma-separated sequence of keys, - text literals, and wait directives. See RECORDING-AGENT.md for syntax. - -.PARAMETER Name - Short identifier for the recording (used in output filenames). - Default: "demo" - -.PARAMETER Title - Human-readable title burned into the cast metadata. - Default: "ted demo" - -.PARAMETER Output - GIF output path. Default: artifacts/tuicast/ted-.gif - -.PARAMETER CastOutput - Asciinema .cast output path. Default: artifacts/tuicast/ted-.cast - -.PARAMETER TedExePath - Path to the ted executable. Default: auto-detected from build output. - -.PARAMETER Cols - Recording columns. Default: 120 - -.PARAMETER Rows - Recording rows. Default: 36 - -.PARAMETER ShowCommand - Synthetic shell prompt/command pre-roll shown in the GIF before the app - starts (e.g. '$ ted foo.cs'). Omit for no pre-roll. - -.PARAMETER StartupDelay - Milliseconds to wait after the target process starts before copying its - output and playing keystrokes. Default: 0 (no extra delay). - -.PARAMETER InputDelay - Default pause in milliseconds before the scripted keys begin (after - startup-delay has elapsed). Default: 0. - -.PARAMETER MaxDuration - Maximum recording duration in seconds. Default: 60 - -.PARAMETER DrainMs - Milliseconds to wait after last keystroke before stopping. Default: 1500 - -.PARAMETER Verbosity - TUIcast verbosity level: low, medium, high. 'high' logs key tokens and - pacing to stderr for troubleshooting. Default: not set. - -.PARAMETER SkipBuild - Skip dotnet build of examples/ted before recording. - -.PARAMETER TuicastVersion - TUIcast release version to download if not found. Default: 0.1.2 -#> -[CmdletBinding()] -param ( - [Parameter(Mandatory = $true)] - [string] $Keystrokes, - - [string] $Name = 'demo', - [string] $Title = 'ted demo', - [string] $Output, - [string] $CastOutput, - [string] $TedExePath, - [int] $Cols = 120, - [int] $Rows = 36, - [int] $MaxDuration = 60, - [int] $DrainMs = 1500, - [string] $ShowCommand, - [int] $StartupDelay = 0, - [int] $InputDelay = 0, - [string] $Verbosity, - [switch] $SkipBuild, - [string] $TuicastVersion = '0.1.2' -) - -$ErrorActionPreference = 'Stop' - -$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Definition -$RepoRoot = git -C $ScriptDir rev-parse --show-toplevel -$RepoRoot = $RepoRoot.Trim() - -$ToolsDir = Join-Path $HOME 'tools' - -if (-not $Output) { $Output = Join-Path $RepoRoot "artifacts/tuicast/ted-${Name}.gif" } -if (-not $CastOutput) { $CastOutput = Join-Path $RepoRoot "artifacts/tuicast/ted-${Name}.cast" } - -function Get-TuicastAssetName { - if ($IsWindows -or ($PSVersionTable.PSVersion.Major -le 5)) { - $os = 'windows' - $ext = 'zip' - } elseif ($IsMacOS) { - $os = 'darwin' - $ext = 'tar.gz' - } else { - $os = 'linux' - $ext = 'tar.gz' - } - - $arch = [System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture.ToString().ToLower() - $goArch = switch ($arch) { - 'x64' { 'amd64' } - 'arm64' { 'arm64' } - default { 'amd64' } - } - - return "tuicast_${TuicastVersion}_${os}_${goArch}.${ext}" -} - -function Install-TuicastTools { - $null = New-Item -ItemType Directory -Force -Path $ToolsDir - - $asset = Get-TuicastAssetName - $url = "https://github.com/gui-cs/TUIcast/releases/download/v${TuicastVersion}/${asset}" - $tempFile = Join-Path ([System.IO.Path]::GetTempPath()) $asset - - Write-Host "Downloading TUIcast v${TuicastVersion}: $url" - Invoke-WebRequest -Uri $url -OutFile $tempFile -UseBasicParsing - - $tempExtract = Join-Path ([System.IO.Path]::GetTempPath()) "tuicast-extract-$([guid]::NewGuid())" - $null = New-Item -ItemType Directory -Force -Path $tempExtract - - if ($asset.EndsWith('.zip')) { - Expand-Archive -Path $tempFile -DestinationPath $tempExtract -Force - } else { - tar -xzf $tempFile -C $tempExtract - } - - $exeExt = if ($IsWindows -or ($PSVersionTable.PSVersion.Major -le 5)) { '.exe' } else { '' } - foreach ($tool in @('tuicast', 'agg')) { - $src = Get-ChildItem -Path $tempExtract -Recurse -Filter "${tool}${exeExt}" | Select-Object -First 1 - if ($src) { - Copy-Item -Path $src.FullName -Destination (Join-Path $ToolsDir "${tool}${exeExt}") -Force - Write-Host " Installed: ~/tools/${tool}${exeExt}" - } - } - - Remove-Item -Recurse -Force $tempFile -ErrorAction SilentlyContinue - Remove-Item -Recurse -Force $tempExtract -ErrorAction SilentlyContinue -} - -function Resolve-TuicastTool { - param ([string] $ToolName) - - $exeExt = if ($IsWindows -or ($PSVersionTable.PSVersion.Major -le 5)) { '.exe' } else { '' } - - $found = Get-Command $ToolName -ErrorAction SilentlyContinue - if ($found) { return $found.Source } - - $toolPath = Join-Path $ToolsDir "${ToolName}${exeExt}" - if (Test-Path $toolPath) { return (Resolve-Path $toolPath).Path } - - return $null -} - -# Resolve tuicast and agg — download if missing -$TuicastBin = Resolve-TuicastTool 'tuicast' -$AggBin = Resolve-TuicastTool 'agg' - -if (-not $TuicastBin -or -not $AggBin) { - Write-Host 'tuicast or agg not found on PATH or in ~/tools. Installing...' - Install-TuicastTools - $TuicastBin = Resolve-TuicastTool 'tuicast' - $AggBin = Resolve-TuicastTool 'agg' - if (-not $TuicastBin) { throw 'Failed to install tuicast' } - if (-not $AggBin) { throw 'Failed to install agg' } -} - -# Resolve ted executable -$exeExt = if ($IsWindows -or ($PSVersionTable.PSVersion.Major -le 5)) { '.exe' } else { '' } -if (-not $TedExePath) { - $TedExePath = Join-Path $RepoRoot "examples/ted/bin/Debug/net10.0/ted${exeExt}" -} - -# Build if needed -if (-not $SkipBuild) { - Write-Host 'Building examples/ted...' - $buildResult = & dotnet build (Join-Path $RepoRoot 'examples/ted/ted.csproj') --verbosity minimal - if ($LASTEXITCODE -ne 0) { - $buildResult | ForEach-Object { Write-Host $_ } - throw "dotnet build failed with exit code $LASTEXITCODE" - } -} - -if (-not (Test-Path $TedExePath)) { - throw "ted executable not found at: $TedExePath`nBuild it first with: dotnet build examples/ted/ted.csproj" -} -$TedBin = (Resolve-Path $TedExePath).Path - -# Ensure output directories exist -$null = New-Item -ItemType Directory -Force -Path (Split-Path -Parent $Output) -$null = New-Item -ItemType Directory -Force -Path (Split-Path -Parent $CastOutput) - -Set-Location $RepoRoot - -Write-Host "Recording: $Title" -Write-Host " Keystrokes: $Keystrokes" -Write-Host " Output: $Output" - -$recordArgs = @( - 'record', - '--binary', $TedBin, - '--keystrokes', $Keystrokes, - '--output', $Output, - '--cast-output', $CastOutput, - '--agg-path', $AggBin, - '--cols', $Cols, - '--rows', $Rows, - '--max-duration', $MaxDuration, - '--drain', $DrainMs, - '--title', $Title -) - -if ($ShowCommand) { $recordArgs += '--show-command'; $recordArgs += $ShowCommand } -if ($StartupDelay -gt 0){ $recordArgs += '--startup-delay'; $recordArgs += $StartupDelay } -if ($InputDelay -gt 0) { $recordArgs += '--input-delay'; $recordArgs += $InputDelay } -if ($Verbosity) { $recordArgs += '--verbosity'; $recordArgs += $Verbosity } - -& $TuicastBin @recordArgs - -if ($LASTEXITCODE -ne 0) { throw "tuicast record failed with exit code $LASTEXITCODE" } - -Write-Host '' -Write-Host "Recording complete:" -Write-Host " GIF: $Output" -Write-Host " cast: $CastOutput" - -$GifPath = (Resolve-Path $Output).Path - -try -{ - Set-Clipboard -Value $GifPath - Write-Host " GIF path copied to clipboard." -} -catch -{ - Write-Host " (Set-Clipboard unavailable: $($_.Exception.Message))" -} - -try -{ - Invoke-Item -Path $GifPath -} -catch -{ - Write-Host " (Could not launch GIF: $($_.Exception.Message))" -} diff --git a/scripts/setup-agent-clone.sh b/scripts/setup-agent-clone.sh deleted file mode 100755 index 15e82e58..00000000 --- a/scripts/setup-agent-clone.sh +++ /dev/null @@ -1,65 +0,0 @@ -#!/usr/bin/env bash -# setup-agent-clone.sh — clone gui-cs/Editor into $HOME/s/Terminal.Gui.Editor/codex/, -# restore tools, and verify GitHub auth for Codex PR creation. - -set -euo pipefail - -AGENT="${1:-}" - -usage () { - cat <<'EOF' -Usage: ./scripts/setup-agent-clone.sh codex - -Idempotent. Clones gui-cs/Editor into $HOME/s/Terminal.Gui.Editor/codex/ if not -already there, runs `dotnet tool restore`, and reports the active gh identity. -EOF -} - -if [[ "${AGENT:-}" == "" || "${AGENT}" == "--help" || "${AGENT}" == "-h" ]]; then - usage - exit 0 -fi - -case "$AGENT" in - codex) : ;; - *) echo "error: agent must be codex" >&2; exit 1 ;; -esac - -WORK="$HOME/s/Terminal.Gui.Editor/$AGENT" - -if [[ ! -d "$WORK/.git" ]]; then - echo "==> Cloning gui-cs/Editor into $WORK" - mkdir -p "$WORK" - gh repo clone gui-cs/Editor "$WORK" -fi - -cd "$WORK" - -echo "==> Syncing develop" -git fetch origin -git checkout develop -git pull --ff-only - -echo "==> Restoring dotnet tools (jb, etc.)" -dotnet tool restore - -echo "==> Verifying gh auth identity for this clone" -identity="$(gh auth status 2>&1 | awk -F 'account ' '/Logged in to github.com/ {print $2}' | head -1)" -if [[ -z "${identity:-}" ]]; then - cat >&2 < Setting Codex git author" -git config user.name "codex-agent" -git config user.email "codex-agent@experiment" -echo " user.name = $(git config user.name)" -echo " user.email = $(git config user.email)" - -echo -echo "Agent clone ready: $WORK" -echo "Branch: $(git rev-parse --abbrev-ref HEAD) HEAD: $(git rev-parse --short HEAD)" diff --git a/scripts/setup-host.sh b/scripts/setup-host.sh deleted file mode 100755 index a9fe73ae..00000000 --- a/scripts/setup-host.sh +++ /dev/null @@ -1,88 +0,0 @@ -#!/usr/bin/env bash -# setup-host.sh — one-time Mac mini bootstrap for the Codex autonomous sprint. -# Idempotent: brew install is a no-op if a package is already present, and the -# tool / SDK checks short-circuit when their target is already there. -# -# This installs system tooling only. The Codex clone is created by -# setup-agent-clone.sh; CLI logins (codex, gh) are interactive and stay manual. - -set -euo pipefail - -usage () { - cat <<'EOF' -Usage: ./scripts/setup-host.sh [--help] - -One-time Mac mini bootstrap for the Codex-only autonomous sprint. - -Installs (via Homebrew): - - .NET 10 SDK (preview channel) - - gh, git, tmux, jq - - Node.js (for the Codex CLI npm install) - - OpenAI Codex CLI - -After this completes, you still need to log each CLI in interactively: - codex login - gh auth login -EOF -} - -if [[ "${1:-}" == "--help" || "${1:-}" == "-h" ]]; then - usage - exit 0 -fi - -if [[ "$(uname)" != "Darwin" ]]; then - echo "error: this script targets macOS." >&2 - exit 1 -fi - -if ! command -v brew >/dev/null 2>&1; then - echo "error: Homebrew not found. Install from https://brew.sh and re-run." >&2 - exit 1 -fi - -echo "==> System packages" -brew install gh git tmux jq node - -echo "==> .NET 10 SDK (preview channel)" -# The Homebrew cask tracks GA. For net10 preview we use the install-script. -if ! command -v dotnet >/dev/null 2>&1 || ! dotnet --list-sdks | grep -q '^10\.'; then - curl -sSL https://dot.net/v1/dotnet-install.sh -o /tmp/dotnet-install.sh - chmod +x /tmp/dotnet-install.sh - /tmp/dotnet-install.sh --channel 10.0 --quality preview --install-dir "$HOME/.dotnet" - rm -f /tmp/dotnet-install.sh - if ! grep -q 'DOTNET_ROOT' "$HOME/.zshrc" 2>/dev/null; then - { - echo '' - echo '# .NET 10 preview (added by gui-cs/Editor scripts/setup-host.sh)' - echo 'export DOTNET_ROOT="$HOME/.dotnet"' - echo 'export PATH="$DOTNET_ROOT:$PATH"' - } >> "$HOME/.zshrc" - fi - export DOTNET_ROOT="$HOME/.dotnet" - export PATH="$DOTNET_ROOT:$PATH" -fi - -echo "==> OpenAI Codex CLI" -if ! command -v codex >/dev/null 2>&1; then - npm install -g @openai/codex -fi - -echo "==> $HOME/s/Terminal.Gui.Editor/ directory (where the Codex clone lands)" -mkdir -p "$HOME/s/Terminal.Gui.Editor" - -echo -echo "Host setup complete. Versions:" -dotnet --version -gh --version | head -1 -tmux -V -node --version -codex --version 2>/dev/null | head -1 || echo " codex: installed but not yet logged in" - -cat <<'EOF' - -Next steps: - 1. codex login - 2. gh auth login - 3. ./scripts/setup-agent-clone.sh codex -EOF diff --git a/scripts/start-agent.sh b/scripts/start-agent.sh deleted file mode 100755 index 833d0516..00000000 --- a/scripts/start-agent.sh +++ /dev/null @@ -1,101 +0,0 @@ -#!/usr/bin/env bash -# start-agent.sh — launch Codex in the foreground (intended to run inside a -# tmux window). The kick-off prompt is generated here so it stays consistent -# with specs/codex-autonomous-sprint.md. - -set -euo pipefail - -AGENT="${1:-}" - -usage () { - cat <<'EOF' -Usage: ./scripts/start-agent.sh codex - -Feeds the Codex autonomous-sprint kickoff prompt into the Codex CLI in -$HOME/s/Terminal.Gui.Editor/codex/. -EOF -} - -if [[ "${AGENT:-}" == "" || "${AGENT}" == "--help" || "${AGENT}" == "-h" ]]; then - usage - exit 0 -fi - -case "$AGENT" in - codex) : ;; - *) echo "error: agent must be codex" >&2; exit 1 ;; -esac - -WORK="$HOME/s/Terminal.Gui.Editor/$AGENT" -if [[ ! -d "$WORK/.git" ]]; then - echo "error: $WORK not set up. Run ./scripts/setup-agent-clone.sh $AGENT first." >&2 - exit 1 -fi - -cd "$WORK" -git fetch origin - -INTEGRATION_BRANCH="experiment/codex/develop" -if git show-ref --verify --quiet "refs/remotes/origin/$INTEGRATION_BRANCH"; then - git switch "$INTEGRATION_BRANCH" 2>/dev/null || git switch -c "$INTEGRATION_BRANCH" "origin/$INTEGRATION_BRANCH" - git pull --ff-only origin "$INTEGRATION_BRANCH" -else - git switch -c "$INTEGRATION_BRANCH" origin/develop - git push -u origin "$INTEGRATION_BRANCH" -fi - -read -r -d '' PROMPT <<'EOF' || true -You are the Codex agent in the Codex-only autonomous sprint described in -\`specs/codex-autonomous-sprint.md\`. - -Required reading before you start: - - \`specs/codex-autonomous-sprint.md\`. - - \`specs/constitution.md\` — especially tenets and R1–R10. - - \`specs/plan.md\` — roadmap, dependency table, and MLP Definition of Done. - - \`specs/public-api.md\` and \`specs/decisions.md\`. - - \`CLAUDE.md\` — coding standards. - - The relevant \`specs//spec.md\` before implementing each feature. - -How to work: - 1. Work from \`experiment/codex/develop\`, the Codex shadow develop branch. - 2. Choose work from \`specs/plan.md\`, preferring dependency-unblocking features. - 3. Create feature branches from \`experiment/codex/develop\` under \`experiment/codex/\`. - 4. Open one PR per feature or tightly-coupled feature slice, targeting \`experiment/codex/develop\`. - 5. After a feature branch satisfies its spec and validation, merge, rebase, or cherry-pick it - into \`experiment/codex/develop\` and push the updated integration branch. - 6. Periodically fetch \`origin/develop\` and integrate it into \`experiment/codex/develop\`. - If a conflict is not obviously resolvable, stop and document the blocker. - 7. Do not push to or merge into \`develop\`. - 8. When you stop, write \`specs/runs/codex-final.md\` summarizing PRs opened, - features completed, blockers, validation, risks, and approximate spend/tokens if available. - -Do not use Claude Code or GitHub Copilot Coding Agent. This is a single Codex lane. - -Do not edit: \`.claude/\`, \`.config/\`, \`third_party/\`, or \`scripts/\`. -If you think one of those needs changing, write the proposal into your final report instead. -Spec files may be updated when required by R8, resolved decisions, or feature status changes. - -A full clone of Terminal.Gui is at \`../Terminal.Gui\` (absolute path: -\`$HOME/s/Terminal.Gui.Editor/Terminal.Gui\`, \`develop\` branch). **Before using it, -verify the clone is complete:** \`git -C ../Terminal.Gui status\` should succeed -and show a clean working tree. If the directory is missing or \`git status\` fails, -the clone is still in progress — wait and retry. Once ready you can read its -source directly, build it, or reference it as a local project reference if you -need to test against an unreleased TG change. When you hit behavior you suspect -is a Terminal.Gui bug, **and** you can prove it with a failing unit test, and -**only** then: file an issue on \`gui-cs/Terminal.Gui\` that includes the failing -unit test and a clear repro. The bar is high — do not file speculative or "this -might be" issues. If you cannot write a failing test, the bug isn't filed; work -around it locally, note the workaround in your final report, and move on. -EOF - -echo "==> Starting Codex in $WORK" -echo " (Ctrl+C inside the agent to stop. Detach the tmux pane with Ctrl+B D.)" -echo - -# Codex reads its agent file from AGENTS.md. -if [[ ! -f AGENTS.md ]]; then - ln -s CLAUDE.md AGENTS.md -fi - -exec codex --dangerously-bypass-approvals-and-sandbox "$PROMPT" diff --git a/scripts/start-experiment.sh b/scripts/start-experiment.sh deleted file mode 100755 index ee62fd5e..00000000 --- a/scripts/start-experiment.sh +++ /dev/null @@ -1,58 +0,0 @@ -#!/usr/bin/env bash -# start-experiment.sh — one-shot Codex autonomous sprint launcher. -# -# Creates (or reattaches to) a tmux session named "codex-autonomy", opens windows -# for Codex, and starts the Codex autonomous lane. Run from anywhere; paths are -# absolute. -# -# Usage: -# ./scripts/start-experiment.sh [--session ] -# -# Options: -# --session tmux session name (default: codex-autonomy) -# --help show this message - -set -euo pipefail - -SCRIPTS_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -SESSION="codex-autonomy" - -while [[ $# -gt 0 ]]; do - case "$1" in - --session) SESSION="$2"; shift 2 ;; - --help|-h) - sed -n '2,/^$/p' "$0" | grep '^#' | sed 's/^# \?//' - exit 0 ;; - *) echo "error: unknown arg: $1" >&2; exit 1 ;; - esac -done - -# Tag the start commit if not already tagged. -if ! git -C "$SCRIPTS_DIR" rev-parse "codex/autonomy-start" &>/dev/null; then - echo "==> Tagging codex/autonomy-start on develop" - git -C "$SCRIPTS_DIR" tag codex/autonomy-start - git -C "$SCRIPTS_DIR" push origin codex/autonomy-start -else - echo "==> codex/autonomy-start already tagged at $(git -C "$SCRIPTS_DIR" rev-parse --short codex/autonomy-start)" -fi - -# Create or reuse the tmux session (detached so we can populate it first). -if tmux has-session -t "$SESSION" 2>/dev/null; then - echo "==> Reusing existing tmux session '$SESSION'" -else - echo "==> Creating tmux session '$SESSION'" - tmux new-session -d -s "$SESSION" -n codex -fi - -# Window 0: codex -tmux rename-window -t "$SESSION:0" codex 2>/dev/null || true -tmux send-keys -t "$SESSION:codex" \ - "bash '$SCRIPTS_DIR/start-agent.sh' codex" Enter - -tmux select-window -t "$SESSION:codex" - -echo -echo "Session '$SESSION' ready. Window: codex" -echo -echo "Attach with:" -echo " tmux attach -t $SESSION"