pi-kage 0.3.2 → 0.3.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +21 -32
- package/bin/kage.mjs +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -31,13 +31,9 @@ instead of shipping.
|
|
|
31
31
|
## The idea
|
|
32
32
|
|
|
33
33
|
A shadow clone is a **full, independent copy** of the repo — like a second engineer on a second
|
|
34
|
-
machine. Each parallel session gets its own working tree,
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
And like a real Naruto shadow clone, it **carries your memory out** (the origin's 5 most recent pi
|
|
38
|
-
sessions are copied into the clone, so you can `resume` them there) and **returns it on dispel** (the
|
|
39
|
-
clone's *new* sessions are merged back into the original when you `finish`). The clone always opens a
|
|
40
|
-
**fresh** session — kage never replays your old turns or fakes a "resumed" conversation.
|
|
34
|
+
machine. Each parallel session gets its own working tree, branch, commits, and PR. Code merges the
|
|
35
|
+
normal way: on GitHub. No local collisions, ever. And like a real Naruto shadow clone, it carries
|
|
36
|
+
your memory out and returns it on dispel (see [How it works](#how-it-works)).
|
|
41
37
|
|
|
42
38
|
Why a full folder copy instead of `git worktree`? A worktree shares one `.git`, which means you
|
|
43
39
|
can't check out the same branch twice, you share stash/refs, and you get a *fresh* checkout with no
|
|
@@ -136,38 +132,31 @@ for subcommands and clone names.
|
|
|
136
132
|
|
|
137
133
|
Four invariants keep parallel work safe and lossless:
|
|
138
134
|
|
|
139
|
-
1. **Isolation** — a clone is a full independent copy with its own `.git`.
|
|
135
|
+
1. **Isolation** — a clone is a full independent copy with its own `.git`. kage **doesn't create a
|
|
136
|
+
branch**: the clone stays on the origin's current branch and kage stays out of git flow entirely,
|
|
137
|
+
so you decide your own branching/PR workflow inside the clone (instruct the agent via your
|
|
138
|
+
`AGENTS.md`).
|
|
140
139
|
2. **Code flows back via git, never the working tree.** With a remote you push the branch and merge a
|
|
141
|
-
PR
|
|
142
|
-
`kage/<name>-<sha>` branch (
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
mutated
|
|
140
|
+
PR. With **no remote**, `finish` fetches the clone's branch into the origin's git as a local
|
|
141
|
+
`kage/<name>-<sha>` branch (origin's working tree untouched — `git merge` it when you like; the short
|
|
142
|
+
sha keeps the ref unique so reusing a name never collides). kage never copies the clone's working
|
|
143
|
+
tree onto the origin — that would re-create the collisions it avoids — so `finish` refuses to delete
|
|
144
|
+
**uncommitted** work, which a fetch can't preserve.
|
|
145
|
+
3. **Memory flows through `~/.pi`, never replayed.** On create, the origin's 5 most recent session
|
|
146
|
+
`.jsonl` files are copied into the clone — `pi`'s resume picker surfaces them, but the clone opens a
|
|
147
|
+
**fresh** session (kage never replays turns or fakes a resumed conversation). On `finish`, sessions
|
|
148
|
+
the clone created are copied back whole; an unchanged copied-in session adds nothing; and a
|
|
149
|
+
copied-in session you *resumed and added to* comes back as a **new, self-contained** session — so
|
|
150
|
+
the origin's original session (the leaf pi would resume) is never mutated and your turns aren't lost.
|
|
152
151
|
4. **The origin is read-only to kage** — it only copies out and writes session memory; it never
|
|
153
152
|
touches the origin's working tree, even while another session is live there.
|
|
154
153
|
|
|
154
|
+
With a remote configured, `finish` nudges you to push first (so PR-flow mistakes surface) unless you
|
|
155
|
+
pass `--push` / `--pr` / `--force`.
|
|
156
|
+
|
|
155
157
|
## Notes & caveats
|
|
156
158
|
|
|
157
159
|
- The copy is a snapshot of the origin's **current** state, **including uncommitted changes**.
|
|
158
|
-
- kage **doesn't create a branch** — the clone stays on the origin's current branch, and kage stays out
|
|
159
|
-
of git flow entirely. Decide your own branching/PR workflow inside the clone (instruct the agent via
|
|
160
|
-
your `AGENTS.md` / project conventions).
|
|
161
|
-
- The clone opens a **fresh** pi session. The origin's 5 most recent sessions are copied in and are
|
|
162
|
-
**resumable** via pi's resume picker. Real work belongs in the clone's own fresh session, but if you do
|
|
163
|
-
resume a copied origin session and add turns, on `finish` that continuation is written back as a
|
|
164
|
-
**separate** session (the origin's original session is left untouched), so nothing is lost and no
|
|
165
|
-
active conversation is hijacked.
|
|
166
|
-
- **No remote?** `finish` still works losslessly: committed work that isn't on a remote is fetched into
|
|
167
|
-
the origin as a local `kage/<name>-<sha>` branch (the exact name is printed; `git merge` it to
|
|
168
|
-
integrate). The short sha keeps the ref unique, so reusing a clone name never collides. With a remote
|
|
169
|
-
configured, `finish` keeps nudging you to push first (so PR-flow mistakes surface) unless you
|
|
170
|
-
`--push`/`--pr` or `--force`.
|
|
171
160
|
- **Submodules**: a submodule's `.git` pointer is an absolute path and breaks on copy — run
|
|
172
161
|
`git submodule update --init` in the clone.
|
|
173
162
|
- Non-APFS / non-reflink filesystems fall back to a full (heavier) copy.
|
package/bin/kage.mjs
CHANGED
|
@@ -30,7 +30,7 @@ import { homedir } from "node:os";
|
|
|
30
30
|
import { basename, dirname, join, resolve, sep } from "node:path";
|
|
31
31
|
import readline from "node:readline";
|
|
32
32
|
|
|
33
|
-
const VERSION = "0.3.
|
|
33
|
+
const VERSION = "0.3.3"; // keep in sync with package.json (enforced by test)
|
|
34
34
|
const MARKER = ".kage.json";
|
|
35
35
|
const SESSIONS = process.env.KAGE_SESSIONS_DIR || join(homedir(), ".pi", "agent", "sessions");
|
|
36
36
|
const RECENT_SESSIONS = 5; // how many of the origin's most-recent sessions to copy into a clone
|
package/package.json
CHANGED