pi-kage 0.3.0 → 0.3.1

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 CHANGED
@@ -126,8 +126,8 @@ for subcommands and clone names.
126
126
  |---|---|---|
127
127
  | `kage [path] [--name x]` | origin repo | Copy the repo to `../<repo>--<name>` (default `kage-<ts>`), copy the origin's 5 most recent pi sessions into the clone (resumable there, never replayed), and launch a **fresh** `pi` session. `--name` only names the folder — kage never creates a branch. With no args (and existing clones) it opens an interactive picker. |
128
128
  | `kage status [--pr]` | origin repo | Status dashboard of clones: branch, dirty/clean, ahead/behind upstream, and a “safe to clean” flag. `--pr` adds PR state via `gh`. (`kage list` is a kept alias.) |
129
- | `kage finish [name] [--force] [--push] [--pr]` | origin (or inside the clone) | Refuse if the clone has uncommitted or unpushed work (`--force` overrides), merge the clone's **new** sessions back (copied-in origin history is skipped), then delete the clone. `--push` pushes the branch first; `--pr` pushes and opens a PR via `gh`. Auto-selects / prompts when there are several. |
130
- | `kage rm [name] [--force]` | origin (or inside the clone) | Discard a clone **without** merging memory. Refuses if it has local-only work unless `--force`. For abandoned experiments. |
129
+ | `kage finish [name] [--force] [--push] [--pr]` | origin, inside the clone, or anywhere with a clone path | Refuse if the clone has uncommitted or unpushed work (`--force` overrides), merge the clone's **new** sessions back (copied-in origin history is skipped), then delete the clone. `--push` pushes the branch first; `--pr` pushes and opens a PR via `gh`. Auto-selects / prompts when there are several. |
130
+ | `kage rm [name] [--force]` | origin, inside the clone, or anywhere with a clone path | Discard a clone **without** merging memory. Refuses if it has local-only work unless `--force`. For abandoned experiments. `name` may be a clone name (run from the repo) or a path to the clone folder (works from anywhere). |
131
131
  | `kage pull <path...>` | inside a clone | Copy specific files/dirs (even gitignored ones) back to the origin at the same relative path. |
132
132
  | `kage shell-init` | shell rc | Print a shell wrapper (cd-back after `finish`/`rm`) + tab completion. Use `eval "$(kage shell-init)"`. |
133
133
  | `kage --help` / `--version` | anywhere | Usage / version. |
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.0"; // keep in sync with package.json (enforced by test)
33
+ const VERSION = "0.3.1"; // 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
@@ -287,8 +287,15 @@ async function pickClone(action, name) {
287
287
  const here = repoTopLevel(process.cwd());
288
288
  const hm = here && readMarker(here);
289
289
  if (hm && !name) return { originRepo: hm.originRepo, clone: { dir: here, name: hm.name || basename(here), marker: hm } };
290
+ // If `name` resolves to a clone directory, use its marker directly — works from anywhere,
291
+ // even outside a repo (e.g. `kage rm ../app--fix` from the parent dir).
292
+ if (name) {
293
+ const asPath = resolve(name);
294
+ const pm = readMarker(asPath);
295
+ if (pm) return { originRepo: pm.originRepo, clone: { dir: asPath, name: pm.name || basename(asPath), marker: pm } };
296
+ }
290
297
  const originRepo = hm ? hm.originRepo : here;
291
- if (!originRepo) die("not a git repository");
298
+ if (!originRepo) die("not a git repository (run inside the repo or clone, or pass a path to a clone)");
292
299
  const clones = listClones(originRepo);
293
300
  if (clones.length === 0) die("no shadow clones found for this repo");
294
301
  if (name) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-kage",
3
- "version": "0.3.0",
3
+ "version": "0.3.1",
4
4
  "description": "🥷 Shadow Clone Jutsu for your git repo: copy it into an isolated folder, work in parallel with pi, then merge the session memory back",
5
5
  "keywords": [
6
6
  "pi",