feat(storage): add session-global scope for tasks outside the workspace - #63
Merged
Merged
Conversation
Builds on kunaaal13's #61, addressing review findings. Session task files move out of <workspace>/.pi/tasks/ into pi's agent directory, keyed by workspace. Beyond #61 as submitted: - Root is getAgentDir(), not a hardcoded homedir(), matching every other extension and this repo's own global config. Shared named lists follow, keeping the pre-agent-dir path as a read fallback so no list is stranded. - <project-key> is pi's own session-log encoding rather than a SHA-256 digest, so tasks sit under the same name as their transcripts. - Migration sweeps the whole legacy directory instead of only the session being opened; sessions never resumed would otherwise keep .pi/tasks/ alive forever. Project-scope tasks.json stays put, and .pi/ itself is no longer removed. - copyFileSync(COPYFILE_EXCL) replaces the temp-file + linkSync publish; same never-overwrite guarantee without depending on hard links. - Emptied session directories are reclaimed, and only inside our own tree — a PI_TASKS path's parent is not ours to remove. - The suite no longer reads or writes the real ~/.pi: HOME is redirected to a scratch directory and PI_CODING_AGENT_DIR cleared, which also stops it inheriting the runner's global settings. Closes #57 Closes #53
Restore session as the default, writing into the workspace as before, and move the new location behind a fourth taskScope value, session-global. Drop the migration entirely: session-global resolves a session that already has a workspace file to that file, so opting in creates new files elsewhere without moving old ones, and opting back out strands nothing. Revert named shared lists to ~/.pi/tasks/ — that move was not opt-in either. task-store.ts is now byte-identical to master.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Based on @kunaaal13's #61, included here as the first commit. #61 changed the default and migrated existing files; this reworks it as an opt-in so that nothing changes for anyone who does not ask for it.
The problem
taskScope: "session"— the default since v0.3.3 — writes<workspace>/.pi/tasks/tasks-<sessionId>.json, so every repository pi runs in picks up an untracked directory holding a file keyed by a session ID. That data is of no use to anyone else cloning the project, and it costs a.gitignorerule per repository.What changes for existing users
Nothing.
sessionstays the default and writes exactly where it always has. No file is moved, copied, or deleted on upgrade, and there is no migration step.session(default)<workspace>/.pi/tasks/tasks-<sessionId>.jsonproject<workspace>/.pi/tasks/tasks.jsonmemoryPI_TASKS—off, named, absolute, relativePI_TASKS=sprint-1~/.pi/tasks/sprint-1.jsonsrc/task-store.tsis byte-identical to master.What is added
A fourth
taskScopevalue,session-global. Same per-session isolation and resume behaviour assession, but the file is kept outside the workspace:<agent-dir>is~/.pi/agentunless pi is configured otherwise, so the file followsPI_CODING_AGENT_DIRlike every other piece of user-level state.<project-key>uses the same workspace encoding pi applies to its own session logs (/Users/me/work/repo→--Users-me-work-repo--), so a project's task files sit under the same name as its transcripts, and same-ID sessions in different workspaces cannot collide.Picking it
Via
/tasks→ Settings → Task storage, which now cyclesmemory→session→session-global→project. Takes effect on the next session start.Note that the settings menu writes project overrides to
<workspace>/.pi/tasks-config.json, so choosing it there still leaves a.pi/in that repository — holding config rather than task data. To apply it everywhere and leave repositories untouched, set it once in<agent-dir>/tasks-config.json:{ "taskScope": "session-global" }Opting in does not move anything either
session-globalchanges where new session files are created. A session that already has a file in<workspace>/.pi/tasks/keeps being read and written there, so:sessionstrands nothing;The trade-off is explicit: opting in does not clean up a repository that already has session files. Those disappear the normal way, when their lists are cleared. A union read across both locations was considered and rejected —
nextIdis a per-file counter and IDs areString(this.nextId++), so both files independently contain a task"1"; the lock guards one path; and a delete would resurrect from the other side.Under
session-globalonly, an emptied session directory is removed so global storage does not accumulate one empty directory per workspace ever opened.<workspace>/.pi/tasks/is left standing exactly as before.Testing
Covered: the default scope writing into the workspace and creating nothing under the agent directory;
session-globalkeeping a new session out of the workspace; an existing workspace file still being used and written to after opting in; directory reclamation; a relocatedPI_CODING_AGENT_DIR; and the workspace encoding.Two fixes unrelated to the behaviour above:
~/.pi/of whoever ran it, inheriting their global settings and leaving files behind.HOMEnow points at a scratch directory for the run andPI_CODING_AGENT_DIRis cleared —getAgentDir()consults it first, so redirecting the home directory alone would not have contained a contributor who has it set.vitest.config.tsis excluded from the published tarball; it refers totest/, which is not shipped.Supersedes #61.
closes #57
closes #53