193 lines
9.2 KiB
Markdown
193 lines
9.2 KiB
Markdown
# Starting a project: the commands and the rule
|
|
|
|
These commands are on your `PATH` as `office`, `board`, `merge`, `review`, `triage` and
|
|
`project-reset`. Each is a two-line wrapper in `~/.local/bin` that runs the real script in this
|
|
repository — a wrapper, not a symlink, because a symlinked script resolves its own directory to
|
|
`~/.local/bin` and then cannot find its siblings. The previous project's wrappers were moved to
|
|
`~/.local/bin/.old-harness/`, not deleted.
|
|
|
|
Replaces the previous project's four commands. There are three now, and one rule that removes
|
|
most of the confusion.
|
|
|
|
## The rule
|
|
|
|
> **The folder and the session live on the same machine.**
|
|
> If you are typing inside a session, on the machine that owns the folder, you type
|
|
> `bin/office <folder>` and nothing else.
|
|
|
|
`--host` exists for exactly one case: the folder is on a different machine from the shell you are
|
|
typing in. It is stated once; after that the project file remembers it.
|
|
|
|
## The three commands
|
|
|
|
| What you want | Command |
|
|
|---|---|
|
|
| adopt a folder | `bin/office <folder> --project "<Paperclip project name>"` |
|
|
| adopt a folder Paperclip has never seen | `bin/office <folder> --new "<Name>"` |
|
|
| adopt a folder that lives on another machine | `bin/office <folder> --project "<Name>" --host nixos-desktop` |
|
|
| repair or rebuild the panes | `bin/board`, `bin/board --replace`, `bin/board --reset` |
|
|
| close everything and start again | `bin/project-reset <folder>` |
|
|
|
|
Nothing else is needed. In particular you do **not** create the session by hand any more: the
|
|
previous design needed `tuios new --host …` because `office` could not create a session. This one
|
|
can, through the daemon's own verb, so the second command is gone.
|
|
|
|
## What `bin/office` does, in order
|
|
|
|
1. Reads the folder. If another machine is named, checks first whether that name is *this*
|
|
machine, and runs locally if it is. (The previous version once tried to `ssh` to itself.)
|
|
2. Resolves a host name to an address ssh can reach: `nixos-desktop`/`.13` → `192.168.20.13`,
|
|
`sam-4screen-desktop`/`.27` → `192.168.20.27`, `sam-thinkpad`/`.51` → `192.168.20.51`.
|
|
3. If it really is another machine: tests the login with `ssh -o BatchMode=yes <address> true`,
|
|
then runs the same command there, and prints how to attach.
|
|
4. On the machine that owns the folder: creates the Paperclip project if `--new` was given, or
|
|
adopts the existing one; writes `.harness/harness.toml`, `check.sh`, `NOTES.md` — never
|
|
overwriting anything that exists.
|
|
Before the remote run it copies this folder's commands to the other machine at
|
|
`~/.local/share/paperclip-harness/bin/` and leaves a short `~/.local/bin/office` there, so
|
|
nothing has to be installed by hand. On `.27` and `.51` `~/.local/bin` is not on `PATH`
|
|
yet, so there the command is called by its full path.
|
|
5. Creates the session if it is missing, on that machine's daemon.
|
|
6. Builds the eight panes, in order, each pane claimed by workspace **name**.
|
|
|
|
The last step it cannot do is show you the session. A program may not move your client: the
|
|
daemon refuses `switch-session` from a pane. Switch with TUIOS's own session switcher, or
|
|
`tuios attach --host <machine> <session>`.
|
|
|
|
## The three rebuild levels
|
|
|
|
| Command | What it does |
|
|
|---|---|
|
|
| `bin/board` | creates what is missing, closes nothing |
|
|
| `bin/board --replace` | closes this project's panes, then builds all eight again |
|
|
| `bin/board --reset` | closes **every** pane in the session, waits for none to remain, clears the workspace names, then builds |
|
|
|
|
`--reset` exists because `--replace` on a half-built session can run out of workspace slots and
|
|
leave pages missing.
|
|
|
|
Inside a pane, `R` in `Repair>repair` rebuilds everything; `B` only adds what is missing.
|
|
|
|
## Worktrees, and the folder that is not a repository
|
|
|
|
A new project gets a worktree policy: Paperclip makes a branch and a separate directory per task,
|
|
so two tasks never change the same files, and there is a diff to review and a merge to approve.
|
|
|
|
That needs a repository **with at least one commit**, because a worktree is a checkout of a commit:
|
|
anything not committed is invisible to the agent. When the folder cannot do that yet, `office`
|
|
asks, and never writes history:
|
|
|
|
```
|
|
/tmp/gate1 is not a git repository, so a task cannot have its own branch and worktree.
|
|
without one, two tasks can change the same files at once, and there
|
|
is no diff to review and nothing to merge.
|
|
|
|
Y make the repository, write .gitignore with .paperclip/,
|
|
stage everything, and stop. You commit it in lazygit, then
|
|
run this command again to create the project with worktrees.
|
|
N create the project in place instead: no branches, no diff,
|
|
nothing to merge.
|
|
|
|
Y or N:
|
|
```
|
|
|
|
Answer **Y** and it stops before committing, on purpose:
|
|
|
|
```
|
|
made a repository on branch main
|
|
wrote .gitignore, ignoring .paperclip/
|
|
|
|
Everything is staged and nothing is committed. Check what git is about
|
|
to take, and commit it:
|
|
|
|
cd /tmp/gate1 && lazygit
|
|
space stage or unstage a file i ignore a file or folder
|
|
c commit ? every key
|
|
|
|
Then run this command again. It will create the project with worktrees.
|
|
|
|
the project was not created: commit the staged files, then run this again.
|
|
```
|
|
|
|
Two decisions are kept out of the tool's hands, because both belong to the person:
|
|
|
|
- **what gets committed**, because what you commit is what the agent can see. `lazygit`'s files
|
|
panel stages and unstages with `space`, and **`i` adds a file or folder to `.gitignore`** — for a
|
|
pattern, `e` opens the file. The first commit is unpushed, so `A` amends it if you change your
|
|
mind.
|
|
- **whether there is a commit at all**. No commit means no worktrees, and `N` creates the project
|
|
in place (`local_path`) instead: a task edits the folder directly, with no diff and nothing to
|
|
merge. A project's policy is fixed when it is created, so that choice cannot be revisited
|
|
without making the project again.
|
|
|
|
`--commit-all` does the whole thing in one step for anyone who does not want to look. With no
|
|
terminal and no flag, `office` changes nothing and prints the three commands instead.
|
|
|
|
**`.paperclip/` is written into `.gitignore` on every path and is not a preference.** Paperclip
|
|
puts its worktrees inside the project folder; a commit that took them would put checkouts of the
|
|
repository inside the repository.
|
|
|
|
The base branch is read from the folder (`git symbolic-ref`), not assumed to be `main`, and it is
|
|
set in both places Paperclip keeps it: the policy's `baseRef` and the workspace's `defaultRef`.
|
|
|
|
## Seeing the state: the `git` tab, and the banner
|
|
|
|
`Project>project` → `(` `)` → **git** reads the folder and Paperclip together:
|
|
|
|
```
|
|
THIS FOLDER
|
|
repository yes · branch main
|
|
commits 3
|
|
remote none — not needed for worktrees
|
|
changed 0 staged · 0 unstaged · 2 untracked
|
|
.gitignore .paperclip/
|
|
|
|
worktrees isolated_workspace · git_worktree · base main
|
|
|
|
WORKTREES, AS PAPERCLIP SEES THEM
|
|
AUD-172-add-a-status-md-with-one-line clean · 1 behind · merged into base
|
|
This workspace is 1 commit behind main.
|
|
```
|
|
|
|
Two halves, deliberately: the top is git run in this folder, which Paperclip never checks; the
|
|
bottom is Paperclip's own scan of each task's worktree
|
|
(`GET /api/execution-workspaces/{id}/close-readiness`), which already knows the branch, what is
|
|
dirty, how far behind the base it is, and whether it is merged. Nothing is recomputed.
|
|
|
|
`t` opens `lazygit` in the project folder, wherever the git tab says something needs doing.
|
|
|
|
While the folder cannot hold a worktree, **every pane** carries one line at the top:
|
|
|
|
```
|
|
commit will swallow the worktrees — .paperclip/ is not in .gitignore · Project>project → git
|
|
```
|
|
|
|
It takes the page title's line and leaves the panels and the key hints alone. It is read once when
|
|
the pane starts, so fixing the folder and pressing `R` (which rebuilds every pane) is what clears
|
|
it.
|
|
|
|
## A folder on a machine that does not serve Paperclip## A folder on a machine that does not serve Paperclip
|
|
|
|
Panes run where the folder is. **Agents run where Paperclip is**, because Paperclip starts them
|
|
itself. When those are different machines the panes read the folder correctly and the agents
|
|
cannot see it at all. `office --new` therefore refuses, and says why:
|
|
|
|
```
|
|
refused: this folder is on sam-4screen-desktop, but Paperclip and its agents run on nixos-desktop
|
|
the panes will open here and will read this folder correctly
|
|
the agents will not: they start on nixos-desktop, where /home/sam/SECURITY does not exist
|
|
a task you assign will fail, or work on a different folder
|
|
move the folder to nixos-desktop, mount it there, or pass --anywhere to go ahead anyway
|
|
```
|
|
|
|
`--anywhere` goes ahead anyway, for the case where the panes are all you want.
|
|
|
|
## Traps this design keeps from the previous one
|
|
|
|
- A pane's command must carry the project, or a rebuild shows the wrong one.
|
|
- Compare a host name against this machine's own names and addresses before ssh, or you log in to
|
|
yourself.
|
|
- Never store a workspace number; TUIOS deletes an emptied workspace and renumbers the rest.
|
|
- A pane that never exits keeps a workspace alive. `Shell>shell` is that pane here.
|
|
- Scripts resolve their own directory with `realpath`, so a symlinked wrapper still finds its
|
|
siblings.
|