pi-kage 0.3.2 → 0.3.4
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 +25 -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
|
|
@@ -51,6 +47,10 @@ can't check out the same branch twice, you share stash/refs, and you get a *fres
|
|
|
51
47
|
npm install -g pi-kage # then use `kage` anywhere
|
|
52
48
|
npx pi-kage # or run without installing
|
|
53
49
|
|
|
50
|
+
# pnpm (use @latest so a stale metadata cache doesn't pin you to an old version)
|
|
51
|
+
pnpm add -g pi-kage@latest
|
|
52
|
+
pnpm dlx pi-kage # or run without installing
|
|
53
|
+
|
|
54
54
|
# or install script (no npm needed — kage is a single, zero-dependency Node script)
|
|
55
55
|
curl -fsSL https://raw.githubusercontent.com/kid7st/kage/main/install.sh | sh
|
|
56
56
|
```
|
|
@@ -136,38 +136,31 @@ for subcommands and clone names.
|
|
|
136
136
|
|
|
137
137
|
Four invariants keep parallel work safe and lossless:
|
|
138
138
|
|
|
139
|
-
1. **Isolation** — a clone is a full independent copy with its own `.git`.
|
|
139
|
+
1. **Isolation** — a clone is a full independent copy with its own `.git`. kage **doesn't create a
|
|
140
|
+
branch**: the clone stays on the origin's current branch and kage stays out of git flow entirely,
|
|
141
|
+
so you decide your own branching/PR workflow inside the clone (instruct the agent via your
|
|
142
|
+
`AGENTS.md`).
|
|
140
143
|
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
|
|
144
|
+
PR. With **no remote**, `finish` fetches the clone's branch into the origin's git as a local
|
|
145
|
+
`kage/<name>-<sha>` branch (origin's working tree untouched — `git merge` it when you like; the short
|
|
146
|
+
sha keeps the ref unique so reusing a name never collides). kage never copies the clone's working
|
|
147
|
+
tree onto the origin — that would re-create the collisions it avoids — so `finish` refuses to delete
|
|
148
|
+
**uncommitted** work, which a fetch can't preserve.
|
|
149
|
+
3. **Memory flows through `~/.pi`, never replayed.** On create, the origin's 5 most recent session
|
|
150
|
+
`.jsonl` files are copied into the clone — `pi`'s resume picker surfaces them, but the clone opens a
|
|
151
|
+
**fresh** session (kage never replays turns or fakes a resumed conversation). On `finish`, sessions
|
|
152
|
+
the clone created are copied back whole; an unchanged copied-in session adds nothing; and a
|
|
153
|
+
copied-in session you *resumed and added to* comes back as a **new, self-contained** session — so
|
|
154
|
+
the origin's original session (the leaf pi would resume) is never mutated and your turns aren't lost.
|
|
152
155
|
4. **The origin is read-only to kage** — it only copies out and writes session memory; it never
|
|
153
156
|
touches the origin's working tree, even while another session is live there.
|
|
154
157
|
|
|
158
|
+
With a remote configured, `finish` nudges you to push first (so PR-flow mistakes surface) unless you
|
|
159
|
+
pass `--push` / `--pr` / `--force`.
|
|
160
|
+
|
|
155
161
|
## Notes & caveats
|
|
156
162
|
|
|
157
163
|
- 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
164
|
- **Submodules**: a submodule's `.git` pointer is an absolute path and breaks on copy — run
|
|
172
165
|
`git submodule update --init` in the clone.
|
|
173
166
|
- 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.4"; // 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