diff --git a/.pi/memory-vault/packs/paperclip-harness/20-context/home.md b/.pi/memory-vault/packs/paperclip-harness/20-context/home.md index 7e10d36..b31ea7e 100644 --- a/.pi/memory-vault/packs/paperclip-harness/20-context/home.md +++ b/.pi/memory-vault/packs/paperclip-harness/20-context/home.md @@ -551,3 +551,91 @@ Committed as `77014d0` — documentation only, nothing in the running layout cha - session: [[packs/paperclip-harness/80-sessions/rich-discovery-pi-2026-11-10-21-03-21|Rich discovery: .pi 2026-11-10 21:03:21]] - context: [[packs/paperclip-harness/20-context/home|.pi]] - runbook: [[packs/paperclip-harness/70-runbooks/tmp-deployment-operations|.pi deployment operations]] + + +--- + +## Update (2026-11-11 00:03:58) + +## Rich discovery update (2026-11-11 00:03:58) + +You are right about the guidance, and it is rewritten. + +## What was wrong + +Those lines were mine, and they were poetry instead of instructions: + +- "A task that asks for two things cannot be judged, only argued about" — says nothing about what to type. +- "A command decides when work is finished, the agent does not" — misleading. The *agent* performs the work; the *command* decides whether it counts as finished. My sentence made it sound like the command does the work. +- "a boundary… which files will change… review becomes an autopsy" — you cannot know which files change before the work, and nobody should have to decode a metaphor. + +**Rewritten as five concrete fields with an example each**, plus a glossary. It now reads: + +``` +Title + One sentence naming the change. It becomes the task title in Paperclip. + example: Add a CHANGELOG.md with an Unreleased section + +Must finish first + The identifier of another task, for example AUD-171. Paperclip then records a real + blocker edge and will not let this task run before that one is done. Leave it empty + when nothing must come first. + example: AUD-171 + +Proves it is done + A shell command that exits 0 only when the work is right. It runs in the task's own + copy of the code. Leave it empty and the task will be accepted on the agent's word, + which is a weaker test. + example: test -s CHANGELOG.md or make test +``` + +## Your questions, directly + +**What is a blocker?** Another task's identifier (`AUD-171`) in the "Must finish first" field. Paperclip stores it as a link between the two tasks. That is what a blocker is — a link, not prose. The old text said a sentence is not a blocker, which was true but useless; now the field says exactly what to put in it. + +**How do I assign?** Two ways: type `yes` in "Assign to" on the form, or select the task in `Board>board` and press `a`. Either calls Paperclip and wakes the agent. That is all assign means. + +**How do I merge?** `Shell>shell`, then `bin/merge `, optionally with `--check` first. It rebases, runs the verify command, runs the review, merges, and re-runs the verify command on `main`. + +**What is a dependent task?** The task that names another in "Must finish first". It waits. With the blocker finished, it may start; with the blocker unfinished, Paperclip holds it and the board shows `waits on AUD-171`. + +**How do I change an agent?** `Agents>agents`, `]` four times to settings, then `enter` on a field: role, title, model, budget, heartbeat. `p` pauses, `P` resumes. + +**Why couldn't you set an agent before the first test?** You can, at any time — before a run, between runs, while paused. What you cannot do is change the model of a run already in progress; that is why a change applies to the next run. + +**Are the eight workspaces eight Pi agents?** No. Workspaces are TUIOS pages. The agents are six records in Paperclip (`researcher`, `System`, `Hub`, `Chief of Staff`, `Documenter`, `Builder`), all visible in `Agents>agents`. + +## The test plan + +`docs/TEST-PLAN.md` now has nine steps, each with the exact keys, the exact text to type, what you should see, and where to stop. It starts with a health check and one trivial task (`STATUS.md`, verified by `test -s STATUS.md`) so nothing can fail for an interesting reason. The full text is in the file; the shape is: + +0. `Repair>repair` passes; `Agents>agents` shows six agents, `Builder` not paused. +1. `New task>new` — five fields, exact text given; expect `created AUD-1xx, handed to an agent`. +2. `Board>board` — the row moves todo → in progress → done; `Agents>agents` runs tab shows one `succeeded` run woken by `assignment`; `enter` opens its log. +3. `Work>work` — runs, then change (one file, one line), then facts, then review. +4. `Shell>shell` — `bin/merge AUD-1xx --check`, then `bin/merge AUD-1xx`, then `git log --oneline -3`. +5. Create a second task blocked on the first; expect it held until the blocker is done. +6. `Agents>agents` settings — change the model and the budget; pause and resume. +7. Skills tab — `space` turns a skill on for that agent alone; extensions tab — `space` writes its wrapper. +8. `Repair>repair` — press `R`; all eight workspaces return in order. + +## On the cleanup pane + +Agreed, and your concern is exactly right: **killing a TUIOS session does not touch the Pi session files.** They are separate stores — TUIOS sessions live in the daemon, Pi conversations are files in `~/.pi/paperclips`. So a cleanup pane can only ever remove panes, never history. The plan in `docs/SESSIONS.md` is a `Repair>cleanup` tab that lists sessions with age and pane count, marks attached ones and refuses them, and requires you to pick the ones to kill. Nothing deletes a `.jsonl`. + +Committed as `c9e027d`. + +## Source paths observed + +- `home/sam/paseo/projects/paperclip-harness/docs/TEST-PLAN.md` + +## Evidence + +- Confidence: 84% +- Reason: Update component/repository context with detailed discovered structure and configuration + +## Related learned memories + +- session: [[packs/paperclip-harness/80-sessions/rich-discovery-root-2026-11-11-00-03-58|Rich discovery: root. 2026-11-11 00:03:58]] +- context: [[packs/paperclip-harness/20-context/home|root.]] +- observation: [[packs/paperclip-harness/60-observations/tmp-repository-structure-and-configuration-patterns|root. repository structure and configuration patterns]] diff --git a/.pi/memory-vault/packs/paperclip-harness/60-observations/tmp-repository-structure-and-configuration-patterns.md b/.pi/memory-vault/packs/paperclip-harness/60-observations/tmp-repository-structure-and-configuration-patterns.md index f95ee42..b60f31d 100644 --- a/.pi/memory-vault/packs/paperclip-harness/60-observations/tmp-repository-structure-and-configuration-patterns.md +++ b/.pi/memory-vault/packs/paperclip-harness/60-observations/tmp-repository-structure-and-configuration-patterns.md @@ -2071,3 +2071,91 @@ All eight workspaces are running on the new build. Committed as `1f8731f`. - session: [[packs/paperclip-harness/80-sessions/rich-discovery-paperclipai-2026-11-10-22-15-52|Rich discovery: paperclipai 2026-11-10 22:15:52]] - context: [[packs/paperclip-harness/20-context/paperclipai|paperclipai]] - observation: [[packs/paperclip-harness/60-observations/tmp-repository-structure-and-configuration-patterns|paperclipai repository structure and configuration patterns]] + + +--- + +## Update (2026-11-11 00:03:58) + +## Structural/configuration observations (2026-11-11 00:03:58) + +You are right about the guidance, and it is rewritten. + +## What was wrong + +Those lines were mine, and they were poetry instead of instructions: + +- "A task that asks for two things cannot be judged, only argued about" — says nothing about what to type. +- "A command decides when work is finished, the agent does not" — misleading. The *agent* performs the work; the *command* decides whether it counts as finished. My sentence made it sound like the command does the work. +- "a boundary… which files will change… review becomes an autopsy" — you cannot know which files change before the work, and nobody should have to decode a metaphor. + +**Rewritten as five concrete fields with an example each**, plus a glossary. It now reads: + +``` +Title + One sentence naming the change. It becomes the task title in Paperclip. + example: Add a CHANGELOG.md with an Unreleased section + +Must finish first + The identifier of another task, for example AUD-171. Paperclip then records a real + blocker edge and will not let this task run before that one is done. Leave it empty + when nothing must come first. + example: AUD-171 + +Proves it is done + A shell command that exits 0 only when the work is right. It runs in the task's own + copy of the code. Leave it empty and the task will be accepted on the agent's word, + which is a weaker test. + example: test -s CHANGELOG.md or make test +``` + +## Your questions, directly + +**What is a blocker?** Another task's identifier (`AUD-171`) in the "Must finish first" field. Paperclip stores it as a link between the two tasks. That is what a blocker is — a link, not prose. The old text said a sentence is not a blocker, which was true but useless; now the field says exactly what to put in it. + +**How do I assign?** Two ways: type `yes` in "Assign to" on the form, or select the task in `Board>board` and press `a`. Either calls Paperclip and wakes the agent. That is all assign means. + +**How do I merge?** `Shell>shell`, then `bin/merge `, optionally with `--check` first. It rebases, runs the verify command, runs the review, merges, and re-runs the verify command on `main`. + +**What is a dependent task?** The task that names another in "Must finish first". It waits. With the blocker finished, it may start; with the blocker unfinished, Paperclip holds it and the board shows `waits on AUD-171`. + +**How do I change an agent?** `Agents>agents`, `]` four times to settings, then `enter` on a field: role, title, model, budget, heartbeat. `p` pauses, `P` resumes. + +**Why couldn't you set an agent before the first test?** You can, at any time — before a run, between runs, while paused. What you cannot do is change the model of a run already in progress; that is why a change applies to the next run. + +**Are the eight workspaces eight Pi agents?** No. Workspaces are TUIOS pages. The agents are six records in Paperclip (`researcher`, `System`, `Hub`, `Chief of Staff`, `Documenter`, `Builder`), all visible in `Agents>agents`. + +## The test plan + +`docs/TEST-PLAN.md` now has nine steps, each with the exact keys, the exact text to type, what you should see, and where to stop. It starts with a health check and one trivial task (`STATUS.md`, verified by `test -s STATUS.md`) so nothing can fail for an interesting reason. The full text is in the file; the shape is: + +0. `Repair>repair` passes; `Agents>agents` shows six agents, `Builder` not paused. +1. `New task>new` — five fields, exact text given; expect `created AUD-1xx, handed to an agent`. +2. `Board>board` — the row moves todo → in progress → done; `Agents>agents` runs tab shows one `succeeded` run woken by `assignment`; `enter` opens its log. +3. `Work>work` — runs, then change (one file, one line), then facts, then review. +4. `Shell>shell` — `bin/merge AUD-1xx --check`, then `bin/merge AUD-1xx`, then `git log --oneline -3`. +5. Create a second task blocked on the first; expect it held until the blocker is done. +6. `Agents>agents` settings — change the model and the budget; pause and resume. +7. Skills tab — `space` turns a skill on for that agent alone; extensions tab — `space` writes its wrapper. +8. `Repair>repair` — press `R`; all eight workspaces return in order. + +## On the cleanup pane + +Agreed, and your concern is exactly right: **killing a TUIOS session does not touch the Pi session files.** They are separate stores — TUIOS sessions live in the daemon, Pi conversations are files in `~/.pi/paperclips`. So a cleanup pane can only ever remove panes, never history. The plan in `docs/SESSIONS.md` is a `Repair>cleanup` tab that lists sessions with age and pane count, marks attached ones and refuses them, and requires you to pick the ones to kill. Nothing deletes a `.jsonl`. + +Committed as `c9e027d`. + +## Source paths observed + +- `home/sam/paseo/projects/paperclip-harness/docs/TEST-PLAN.md` + +## Evidence + +- Confidence: 82% +- Reason: Captured factual repo structure/configuration patterns from rich discovery + +## Related learned memories + +- session: [[packs/paperclip-harness/80-sessions/rich-discovery-root-2026-11-11-00-03-58|Rich discovery: root. 2026-11-11 00:03:58]] +- context: [[packs/paperclip-harness/20-context/home|root.]] +- observation: [[packs/paperclip-harness/60-observations/tmp-repository-structure-and-configuration-patterns|root. repository structure and configuration patterns]] diff --git a/.pi/memory-vault/packs/paperclip-harness/80-sessions/rich-discovery-root-2026-11-11-00-03-58.md b/.pi/memory-vault/packs/paperclip-harness/80-sessions/rich-discovery-root-2026-11-11-00-03-58.md new file mode 100644 index 0000000..cf4a19c --- /dev/null +++ b/.pi/memory-vault/packs/paperclip-harness/80-sessions/rich-discovery-root-2026-11-11-00-03-58.md @@ -0,0 +1,107 @@ +--- +type: session +id: session.paperclip-harness.rich-discovery-root-2026-11-11-00-03-58 +title: Rich discovery: root. 2026-11-11 00:03:58 +status: active +source_of_truth: false +freshness: current +last_reviewed: 2026-11-11 +tags: + - pack/paperclip-harness + - agent-memory/session + - autolearn + - rich-discovery + - repo/root +--- + +# Rich discovery: root. 2026-11-11 00:03:58 + +Sanitized rich discovery snapshot captured automatically from the completed turn. + + +## Source paths observed + +- `home/sam/paseo/projects/paperclip-harness/docs/TEST-PLAN.md` + +## Final answer snapshot + +You are right about the guidance, and it is rewritten. + +## What was wrong + +Those lines were mine, and they were poetry instead of instructions: + +- "A task that asks for two things cannot be judged, only argued about" — says nothing about what to type. +- "A command decides when work is finished, the agent does not" — misleading. The *agent* performs the work; the *command* decides whether it counts as finished. My sentence made it sound like the command does the work. +- "a boundary… which files will change… review becomes an autopsy" — you cannot know which files change before the work, and nobody should have to decode a metaphor. + +**Rewritten as five concrete fields with an example each**, plus a glossary. It now reads: + +``` +Title + One sentence naming the change. It becomes the task title in Paperclip. + example: Add a CHANGELOG.md with an Unreleased section + +Must finish first + The identifier of another task, for example AUD-171. Paperclip then records a real + blocker edge and will not let this task run before that one is done. Leave it empty + when nothing must come first. + example: AUD-171 + +Proves it is done + A shell command that exits 0 only when the work is right. It runs in the task's own + copy of the code. Leave it empty and the task will be accepted on the agent's word, + which is a weaker test. + example: test -s CHANGELOG.md or make test +``` + +## Your questions, directly + +**What is a blocker?** Another task's identifier (`AUD-171`) in the "Must finish first" field. Paperclip stores it as a link between the two tasks. That is what a blocker is — a link, not prose. The old text said a sentence is not a blocker, which was true but useless; now the field says exactly what to put in it. + +**How do I assign?** Two ways: type `yes` in "Assign to" on the form, or select the task in `Board>board` and press `a`. Either calls Paperclip and wakes the agent. That is all assign means. + +**How do I merge?** `Shell>shell`, then `bin/merge `, optionally with `--check` first. It rebases, runs the verify command, runs the review, merges, and re-runs the verify command on `main`. + +**What is a dependent task?** The task that names another in "Must finish first". It waits. With the blocker finished, it may start; with the blocker unfinished, Paperclip holds it and the board shows `waits on AUD-171`. + +**How do I change an agent?** `Agents>agents`, `]` four times to settings, then `enter` on a field: role, title, model, budget, heartbeat. `p` pauses, `P` resumes. + +**Why couldn't you set an agent before the first test?** You can, at any time — before a run, between runs, while paused. What you cannot do is change the model of a run already in progress; that is why a change applies to the next run. + +**Are the eight workspaces eight Pi agents?** No. Workspaces are TUIOS pages. The agents are six records in Paperclip (`researcher`, `System`, `Hub`, `Chief of Staff`, `Documenter`, `Builder`), all visible in `Agents>agents`. + +## The test plan + +`docs/TEST-PLAN.md` now has nine steps, each with the exact keys, the exact text to type, what you should see, and where to stop. It starts with a health check and one trivial task (`STATUS.md`, verified by `test -s STATUS.md`) so nothing can fail for an interesting reason. The full text is in the file; the shape is: + +0. `Repair>repair` passes; `Agents>agents` shows six agents, `Builder` not paused. +1. `New task>new` — five fields, exact text given; expect `created AUD-1xx, handed to an agent`. +2. `Board>board` — the row moves todo → in progress → done; `Agents>agents` runs tab shows one `succeeded` run woken by `assignment`; `enter` opens its log. +3. `Work>work` — runs, then change (one file, one line), then facts, then review. +4. `Shell>shell` — `bin/merge AUD-1xx --check`, then `bin/merge AUD-1xx`, then `git log --oneline -3`. +5. Create a second task blocked on the first; expect it held until the blocker is done. +6. `Agents>agents` settings — change the model and the budget; pause and resume. +7. Skills tab — `space` turns a skill on for that agent alone; extensions tab — `space` writes its wrapper. +8. `Repair>repair` — press `R`; all eight workspaces return in order. + +## On the cleanup pane + +Agreed, and your concern is exactly right: **killing a TUIOS session does not touch the Pi session files.** They are separate stores — TUIOS sessions live in the daemon, Pi conversations are files in `~/.pi/paperclips`. So a cleanup pane can only ever remove panes, never history. The plan in `docs/SESSIONS.md` is a `Repair>cleanup` tab that lists sessions with age and pane count, marks attached ones and refuses them, and requires you to pick the ones to kill. Nothing deletes a `.jsonl`. + +Committed as `c9e027d`. + +## Evidence + +- Confidence: 86% +- Reason: Preserve full sanitized discovery detail from a rich investigation turn + +## Related + +- [[packs/paperclip-harness/00-system/pi-agent/memory-manifest|Memory Manifest]] + +## Related learned memories + +- session: [[packs/paperclip-harness/80-sessions/rich-discovery-root-2026-11-11-00-03-58|Rich discovery: root. 2026-11-11 00:03:58]] +- context: [[packs/paperclip-harness/20-context/home|root.]] +- observation: [[packs/paperclip-harness/60-observations/tmp-repository-structure-and-configuration-patterns|root. repository structure and configuration patterns]] diff --git a/bin/board b/bin/board index 775b666..c971a8a 100755 --- a/bin/board +++ b/bin/board @@ -43,7 +43,7 @@ def pages(cfg, folder): # (pane name, workspace name, command). The workspace is what a person reads # on the rail, so it is capitalised and says what the page is for; the pane # keeps the program's own name. Written Workspace>pane when talking about it. - return task, [ + task_pages = [ ("shell", "Shell", "exec zsh -i"), ("board", "Board", "%s -screen board -project %s -folder %s" % (shlex.quote(bin_path), proj, shlex.quote(folder))), ("work", "Work", "%s -screen work -folder %s" % (shlex.quote(bin_path), shlex.quote(folder))), @@ -53,6 +53,10 @@ def pages(cfg, folder): ("project", "Project", "%s -screen project -folder %s" % (shlex.quote(bin_path), shlex.quote(folder))), ("repair", "Repair", "%s -screen repair -folder %s" % (shlex.quote(bin_path), shlex.quote(folder))), ] + # Every pane falls back to a shell, so a program that exits never leaves a + # dead pane behind: it returns to a prompt in the project folder. + pages = [(n, w, c if n == "shell" else c + "; exec zsh -i") for n, w, c in task_pages] + return task, pages def main(): diff --git a/bin/harness b/bin/harness index 3e532c0..f303e9c 100755 Binary files a/bin/harness and b/bin/harness differ diff --git a/docs/OPERATING-RULES.md b/docs/OPERATING-RULES.md index 8cdfb1e..39a3887 100644 --- a/docs/OPERATING-RULES.md +++ b/docs/OPERATING-RULES.md @@ -20,6 +20,10 @@ Nothing about a project is stored outside its folder, except the facts Paperclip ## 2. How a task is judged finished +*This is a rule for this project, not a rule of Paperclip's. Paperclip has no such field: +an agent sets a task's status itself. This project chooses to add a command when a task must +be hard to fake, and to leave it out when the agent's own tests are enough.* + The test is a **command**, kept with the project, and agreed **before** the work starts. Whoever did the work does not decide. If the command fails, the task is not done, and the reason is kept and shown. diff --git a/docs/TEST-PLAN.md b/docs/TEST-PLAN.md index bfdad0c..ff53235 100644 --- a/docs/TEST-PLAN.md +++ b/docs/TEST-PLAN.md @@ -13,7 +13,7 @@ them at any time. If a pane looks wrong, press `R` and wait ten seconds. |---|---| | task | one unit of work in Paperclip, with its own thread, its own copy of the code, its own cost | | blocker | another task that must reach `done` before this one may start. A link between two tasks, stored by Paperclip. | -| verify command | a shell command that exits 0 only when the task is really finished. It runs in the task's copy of the code. | +| verify command (optional) | a shell command that exits 0 only when the task is finished, when you want a hard gate no agent can talk past. Most tasks need none: the agent runs the project's own tests and reports what it did. | | assign | give the task to one agent. This is what wakes the agent and makes it start. | | worktree | the task's own copy of the repository, made by Paperclip, so two tasks cannot overwrite each other | | run | one execution of one agent. A task usually has one or two. | @@ -41,15 +41,18 @@ Fill it in exactly like this: |---|---| | Title | `Add a file named STATUS.md with one line` | | What it must do | `Create STATUS.md at the repository root containing exactly one line: the factory is running. Change no other file. Commit it.` | -| Must finish first | leave empty (just `Enter`) | -| Proves it is done | `test -s STATUS.md` | +| Must finish first | leave empty — press `Enter` | +| A command that proves it (optional) | leave empty — the agent decides how to check its own work | | Assign to | `yes` | -`Enter` on the last field creates it. The pane closes and prints `created AUD-1xx, handed to -an agent`. +`Enter` on the last field creates it. The form stays open and shows: -**Expected:** within about two seconds the pane exits and the task exists. Go to `Board>board` -and look at the top: your task is under `IN PROGRESS`, assigned to `Builder`. +``` +created AUD-1xx, handed to an agent which will start on its own +``` + +**Expected:** within a second or two the task exists and `Builder` has picked it up. Go to +`Board>board`: your task is at the top under `IN PROGRESS`, assigned to `Builder`. **Stop if:** an error line appears. The text is Paperclip's own message; copy it. @@ -88,12 +91,14 @@ This is the one step that needs a shell, because a merge takes a lock and re-run 1. Go to `Shell>shell`. You are in the project folder. 2. Type: `bin/merge AUD-1xx --check` (your identifier), press `Enter`. -**Expected:** it rebases, runs `test -s STATUS.md`, runs the review, and prints `checked only; -nothing merged`. +**Expected:** it rebases, runs the review, and prints either `checked only; nothing merged` or +`no verify command: this would pass on the agent's word` followed by the same. Both are normal: +nothing is merged yet. 3. Type: `bin/merge AUD-1xx`, press `Enter`. -**Expected:** the same checks, then `merged into main at `. +**Expected:** the same checks, then `merged into main at `. A review that finds +something serious refuses the merge and says so; that is the gate working, not a failure. 4. Type `git log --oneline -3`, press `Enter`. Your task's merge commit is at the top. @@ -105,7 +110,7 @@ nothing merged`. 1. `New task>new` again. Title `Read STATUS.md and quote it`. 2. What it must do: `Read STATUS.md at the repository root and quote its contents in a comment on this task. Change no file.` 3. **Must finish first**: the identifier of the task you just merged, for example `AUD-171`. -4. Proves it is done: leave empty. +4. A command that proves it: leave empty. 5. Assign to: `yes`. **Expected:** `Board>board` shows it under `TODO` with `waits on AUD-171` beside it, and it does diff --git a/tui/newtask.go b/tui/newtask.go index a98f833..2ac8337 100644 --- a/tui/newtask.go +++ b/tui/newtask.go @@ -52,12 +52,12 @@ const ( fieldCount ) -var fieldNames = []string{"Title", "What it must do", "Must finish first", "Proves it is done", "Assign to an agent"} +var fieldNames = []string{"Title", "What it must do", "Must finish first", "A command that proves it (optional)", "Assign to an agent"} var fieldHints = []string{ "one line, the thing to be done", "details the agent needs: files, behaviour, limits", "identifier of a task that must finish first, or empty", - "a command that succeeds only when the work is right, or empty", + "leave empty and the agent decides how to check its own work", "yes, to hand it to the configured agent after the blocker is set", } @@ -76,6 +76,9 @@ func newTaskForm(c *paperclip.Client, proj paperclip.Project, agentID string) ne func (m newTaskModel) Init() tea.Cmd { return textinput.Blink } +// fieldTitle is index 0; kept as a method so the intent is readable above. +func (m newTaskModel) fieldTitle() int { return fieldTitle } + func (m newTaskModel) submit() tea.Cmd { title := strings.TrimSpace(m.inputs[fieldTitle].Value()) body := strings.TrimSpace(m.inputs[fieldBody].Value()) @@ -177,14 +180,22 @@ func (m newTaskModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) { m.err = msg.err return m, nil } + // Stay open with a receipt and empty fields. A pane that quits on + // success leaves nothing behind, which reads like a crash. m.result = "created " + msg.issue.Identifier if msg.blocked != "" { m.result += ", waiting on " + msg.blocked } if msg.assigned { - m.result += ", handed to an agent" + m.result += ", handed to an agent which will start on its own" } - return m, tea.Quit + for i := range m.inputs { + m.inputs[i].SetValue("") + } + m.focus = fieldTitle + m.inputs[m.fieldTitle()].Focus() + m.tab = 0 + return m, nil } var cmd tea.Cmd @@ -242,8 +253,8 @@ func (m newTaskModel) guidanceLines(width int) []string { "Create CHANGELOG.md at the repository root. One section titled Unreleased with three bullets. Change no other file. Commit it.") add("Must finish first", "The identifier of another task, for example AUD-171. Paperclip then records a real blocker edge and will not let this task run before that one is done. Leave it empty when nothing must come first.", "AUD-171") - add("Proves it is done", "A shell command that exits 0 only when the work is right. It runs in the task's own copy of the code. Leave it empty and the task will be accepted on the agent's word, which is a weaker test.", - "test -s CHANGELOG.md or make test") + add("A command that proves it", "Optional. Most tasks need nothing here: the agent does the work, runs the project's own tests, and says what it did. Fill this in only when you want a hard gate that no agent can talk its way past.", + "make test or go test ./...") add("Assign to", "yes, or empty. yes hands the task to the configured agent as soon as it is created; empty leaves it for a person to assign on the board.", "yes") @@ -316,6 +327,10 @@ func (m newTaskModel) View() string { func (m newTaskModel) formLines(width int) []string { var body []string body = append(body, "") + if m.result != "" { + body = append(body, " "+lipgloss.NewStyle().Foreground(lipgloss.Color(active.Success)).Bold(true).Render(m.result)) + body = append(body, "") + } for i, in := range m.inputs { label := fieldNames[i] if i == fieldTitle {