Skip to content

fix(coding-agent): copy official ~/.pi state once instead of moving it on every start - #1525

Open
TykanN wants to merge 1 commit into
code-yeongyu:mainfrom
TykanN:fix/keep-official-pi-dir
Open

TykanN wants to merge 1 commit into
code-yeongyu:mainfrom
TykanN:fix/keep-official-pi-dir

Conversation

@TykanN

@TykanN TykanN commented Sep 9, 2026

Copy link
Copy Markdown

Problem

legacy-senpi-dir-migration.ts runs on every start (runMigrations) and renameSyncs ~/.pi/agent, ~/.pi/mom and <cwd>/.pi into the branded layout (~/.senpi/agent, ~/.omo/agent, …). When the destination already exists it moves every entry that is missing there.

On a machine that also runs upstream pi (@earendil-works/pi-coding-agent), this empties the real pi install:

  • First omo launch → ~/.pi/agent/{extensions,skills,models.json,auth.json,…} are moved to ~/.omo/agent/, leaving ~/.pi/agent empty. mtimes are preserved, so it is a rename, not a copy.
  • Anything the user puts back into ~/.pi/agent is moved again on the next launch.
  • Same for a project's ./.pi./.omo.

So pi and a branded fork cannot coexist. brand-dir-migration.ts already states the opposite rule for ~/.senpi → brand dir: "COPIED once - never moved - because the same machine may keep running the engine standalone, and a move would silently empty that install." The .pi path just never got the same treatment. From the history (1ea83112b, 9a71aae8) the move was meant for the fork's own pre-rename state in ~/.pi, not for upstream pi users.

Fix

  • Official .pi sources (~/.pi/agent, ~/.pi/mom, <cwd>/.pi) are now copied once: missing entries only, nothing overwritten, and a .migrated-from-pi marker written into the destination short-circuits later starts. The original directory is left untouched.
  • Sources nested inside the fork's own config dir (<config>/.pi/agent, <config>/.pi/mom, <cwd>/<config>/.pi) keep the existing move behaviour; nobody else reads those.
  • The startup message now says "Copied … / The original directory is untouched", mirroring brand-dir-migration.ts.

Tests

  • Updated senpi-migration.test.ts: the first case now asserts copy-once semantics (originals still exist, nested extension dir copied, marker written in all three destinations).
  • New case: re-running after the marker exists does not pull newly added ~/.pi/agent files.
  • Existing nested-move and symlink-sandbox cases unchanged and passing.
bunx vitest --run test/senpi-migration.test.ts   # 4 passed
bunx biome check <changed files>                  # clean
bunx tsc --noEmit                                 # exit 0

changes.md entry added per the fork contract.

Behaviour change to be aware of

Users who relied on the migration moving their ~/.pi into the branded dir will now get a copy and keep the original. That is the intended outcome of this PR; if the maintainers would rather gate the copy on something (e.g. only when the brand dir does not exist yet), happy to adjust.


Summary by cubic

Fixes the legacy directory migration so branded agents copy official ~/.pi state into the branded layout once instead of moving it on every start, letting upstream pi and branded forks coexist on one machine.

  • Official .pi directories are now copied once and left untouched; a .migrated-from-pi marker skips later starts.
  • Entries already present in the destination are never overwritten.
  • Pre-rename leftovers nested inside the fork's own config directory keep the existing move behavior.
  • Users who relied on the move will now keep the original ~/.pi directory.

Written for commit 5ba4db6. Summary will update on new commits.

Review in cubic

…t on every start

The legacy-dir migration renamed ~/.pi/agent, ~/.pi/mom and <cwd>/.pi into the
branded layout on every launch. On a machine that also runs upstream pi, each
`senpi`/`omo` start silently emptied the real pi install, so the two could not
coexist.

Official .pi directories are now copied once (missing entries only, nothing
overwritten), gated by a `.migrated-from-pi` marker in the destination. This
matches the rule brand-dir-migration.ts already applies to ~/.senpi. Leftovers
nested inside the fork's own config directory keep the move behaviour, since no
other install reads them.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant