pennyrouter 0.3.23 → 0.3.25
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 +2 -1
- package/package.json +1 -1
- package/src/launch.js +19 -0
- package/src/launch.test.js +6 -0
- package/standalone/penny-compare +4 -4
package/README.md
CHANGED
|
@@ -87,7 +87,8 @@ of `npx pennyrouter install`; to install or refresh it separately, run:
|
|
|
87
87
|
npx pennyrouter compare
|
|
88
88
|
```
|
|
89
89
|
|
|
90
|
-
|
|
90
|
+
The installer puts `penny-compare` and `penny-session` on PATH alongside the `penny` launcher.
|
|
91
|
+
Use `penny-compare` for a side-by-side run or `penny-session` for one Penny-routed session.
|
|
91
92
|
The bundle requires `tmux`, Python 3.10+, and the harnesses being compared.
|
|
92
93
|
|
|
93
94
|
On macOS and Linux, a normal install adds a small `penny` launcher under `~/.local/bin`.
|
package/package.json
CHANGED
package/src/launch.js
CHANGED
|
@@ -2,6 +2,7 @@ import { spawn, spawnSync } from "node:child_process";
|
|
|
2
2
|
import {
|
|
3
3
|
chmod,
|
|
4
4
|
cp,
|
|
5
|
+
lstat,
|
|
5
6
|
mkdtemp,
|
|
6
7
|
mkdir,
|
|
7
8
|
readFile,
|
|
@@ -284,6 +285,24 @@ export async function installPennyCompare() {
|
|
|
284
285
|
await cp(join(source, entry), join(destination, entry), { recursive: true, force: true });
|
|
285
286
|
}
|
|
286
287
|
await mkdir(join(destination, "reports"), { recursive: true, mode: 0o700 });
|
|
288
|
+
await mkdir(pennyBinDir(), { recursive: true, mode: 0o755 });
|
|
289
|
+
for (const entry of ["penny-compare", "penny-session", "penny-compare-viewer"]) {
|
|
290
|
+
const link = join(pennyBinDir(), entry);
|
|
291
|
+
const target = join(destination, entry);
|
|
292
|
+
let replace = false;
|
|
293
|
+
try {
|
|
294
|
+
replace = (await lstat(link)).isSymbolicLink();
|
|
295
|
+
} catch (error) {
|
|
296
|
+
if (error.code !== "ENOENT") throw error;
|
|
297
|
+
}
|
|
298
|
+
if (replace) await unlink(link);
|
|
299
|
+
try {
|
|
300
|
+
await symlink(target, link);
|
|
301
|
+
} catch (error) {
|
|
302
|
+
if (error.code !== "EEXIST") throw error;
|
|
303
|
+
// Leave a user-owned regular file in place rather than overwriting it.
|
|
304
|
+
}
|
|
305
|
+
}
|
|
287
306
|
return { supported: true, installed: true, path: destination };
|
|
288
307
|
}
|
|
289
308
|
|
package/src/launch.test.js
CHANGED
|
@@ -20,6 +20,8 @@ import {
|
|
|
20
20
|
isCodexDesktopRunning,
|
|
21
21
|
loadPennyConfig,
|
|
22
22
|
pennyConfigPath,
|
|
23
|
+
pennyCompareDir,
|
|
24
|
+
pennyBinDir,
|
|
23
25
|
pennyRuntimeDir,
|
|
24
26
|
pennyShimPath,
|
|
25
27
|
readClaudeDesktopCredential,
|
|
@@ -100,6 +102,10 @@ async function main() {
|
|
|
100
102
|
assert.equal(second.changed, false);
|
|
101
103
|
assert.equal(await fileMode(pennyShimPath()), 0o755);
|
|
102
104
|
assert.ok(fs.existsSync(path.join(pennyRuntimeDir(), "bin", "penny.js")));
|
|
105
|
+
assert.equal(
|
|
106
|
+
fs.realpathSync(path.join(pennyBinDir(), "penny-compare")),
|
|
107
|
+
fs.realpathSync(path.join(pennyCompareDir(), "penny-compare")),
|
|
108
|
+
);
|
|
103
109
|
assert.ok(!fs.existsSync(staleSkill), "runtime upgrade removes stale plugin files");
|
|
104
110
|
const rc = fs.readFileSync(path.join(home, ".zshrc"), "utf8");
|
|
105
111
|
assert.equal((rc.match(/>>> pennyrouter PATH >>>/g) || []).length, 1);
|
package/standalone/penny-compare
CHANGED
|
@@ -118,7 +118,7 @@ else
|
|
|
118
118
|
left="$(choose 'left pane' claude "${variants[@]}")"
|
|
119
119
|
echo >&2
|
|
120
120
|
if [ -z "$dir_left" ]; then
|
|
121
|
-
echo " left directory (blank = $PWD)" >&2
|
|
121
|
+
echo " left directory (blank = $PWD/native)" >&2
|
|
122
122
|
read -r -p " [] " dir_left >&2 || true
|
|
123
123
|
echo >&2
|
|
124
124
|
fi
|
|
@@ -130,7 +130,7 @@ else
|
|
|
130
130
|
right="$(choose 'right pane' penny-claude "${variants[@]}")"
|
|
131
131
|
echo >&2
|
|
132
132
|
if [ -z "$dir_right" ]; then
|
|
133
|
-
echo " right directory (blank = $PWD)" >&2
|
|
133
|
+
echo " right directory (blank = $PWD/penny)" >&2
|
|
134
134
|
read -r -p " [] " dir_right >&2 || true
|
|
135
135
|
echo >&2
|
|
136
136
|
fi
|
|
@@ -232,9 +232,9 @@ export PENNY_COMPARE_STATE="$state"
|
|
|
232
232
|
|
|
233
233
|
# Each pane's readout finds its session by the directory it ran in, so the two must be set
|
|
234
234
|
# explicitly rather than left to tmux's default of wherever the launcher was invoked.
|
|
235
|
-
workdir_left="${dir_left:-$PWD}"
|
|
235
|
+
workdir_left="${dir_left:-$PWD/native}"
|
|
236
236
|
workdir_left="${workdir_left/#\~/$HOME}"
|
|
237
|
-
workdir_right="${dir_right:-$PWD}"
|
|
237
|
+
workdir_right="${dir_right:-$PWD/penny}"
|
|
238
238
|
workdir_right="${workdir_right/#\~/$HOME}"
|
|
239
239
|
|
|
240
240
|
# --native-proxy only means anything on a NATIVE Claude or Codex pane;
|