@webinson/peer 0.4.18 → 0.4.20

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
@@ -99,11 +99,11 @@ peer-codex
99
99
  If you already signed in to Peer, use `peer install --codex --client` in place of the login
100
100
  command. Review and trust the Peer Thread Mark hooks in Codex's `/hooks` menu.
101
101
 
102
- The `--client` setup needs Git, Rust/Cargo, `curl`, `shasum`, and a C/C++ toolchain on
103
- the machine. It builds the pinned Codex client under `~/.peer/codex-client`. If you already
104
- built it, set `PEER_CODEX_CLIENT` to its executable when you run setup. The `peer-codex`
105
- launcher uses your existing Codex settings and sign-in with its own app server. `PEER_HOME`
106
- moves the default checkout and Peer state.
102
+ The `--client` setup downloads the matching prebuilt client from npm into
103
+ `~/.peer/codex-clients`. It supports macOS, Linux, and Windows on x64 and ARM64,
104
+ and requires Node.js and npm. Set `PEER_CODEX_CLIENT` to use a custom build.
105
+ The `peer-codex` launcher uses your existing Codex settings and sign-in with its
106
+ own app server. `PEER_HOME` moves the client cache and Peer state.
107
107
 
108
108
  For the plugin alone, omit `--client`. The Codex plugin lives under [`mod/codex`](mod/codex)
109
109
  in its own marketplace.
@@ -113,8 +113,7 @@ In stock Codex, send `peer: start`, `peer: stop`, `peer: list`, `peer: thread`,
113
113
  This plugin uses the [Codex hook API](https://learn.chatgpt.com/docs/hooks); stock Codex does
114
114
  not expose a composer band or memory switches to plugins.
115
115
 
116
- From a source checkout, use `node bin/peer.mjs install --codex --client` and
117
- `bash mod/codex/client/run.sh` from `cli/`.
116
+ For a custom build, see [building the client](mod/codex/client/README.md).
118
117
 
119
118
  The terminal band shows the thread's memory count, **Use Elephant**, **Use Jellyfish**, and
120
119
  **Active** or **Inactive**. Press the lit mode again to stop sharing. Use `/peer-mode` for
@@ -0,0 +1,73 @@
1
+ import { execFileSync } from "node:child_process";
2
+ import fs from "node:fs";
3
+ import path from "node:path";
4
+
5
+ export const codexTargets = {
6
+ "darwin-arm64": "aarch64-apple-darwin",
7
+ "darwin-x64": "x86_64-apple-darwin",
8
+ "linux-arm64": "aarch64-unknown-linux-musl",
9
+ "linux-x64": "x86_64-unknown-linux-musl",
10
+ "win32-arm64": "aarch64-pc-windows-msvc",
11
+ "win32-x64": "x86_64-pc-windows-msvc",
12
+ };
13
+
14
+ export const codexPackageName = (platform) => `@webinson/peer-codex-${platform}`;
15
+ export const codexExecutable = (platform) => platform === "win32" ? "codex.exe" : "codex";
16
+ export const codexNativeVersion = "0.4.18";
17
+
18
+ function installedClient(directory, target) {
19
+ const bin = path.join(directory, "vendor", target, "bin");
20
+ const suffix = process.platform === "win32" ? ".exe" : "";
21
+ const client = path.join(bin, codexExecutable(process.platform));
22
+ try {
23
+ for (const executable of [client, path.join(bin, `codex-code-mode-host${suffix}`)]) {
24
+ if (!fs.statSync(executable).isFile()) return null;
25
+ fs.accessSync(executable, fs.constants.X_OK);
26
+ }
27
+ return client;
28
+ } catch {
29
+ return null;
30
+ }
31
+ }
32
+
33
+ export function installNativeCodex(peer) {
34
+ const platform = `${process.platform}-${process.arch}`;
35
+ const target = codexTargets[platform];
36
+ if (!target) {
37
+ throw new Error(`No prebuilt Peer Codex for ${platform}. Set PEER_CODEX_CLIENT to a custom build.`);
38
+ }
39
+ const packageName = codexPackageName(platform);
40
+ const spec = `${packageName}@${codexNativeVersion}`;
41
+ const root = path.resolve(peer.home, "codex-clients");
42
+ const destination = path.join(root, `${platform}-${codexNativeVersion}`);
43
+ if (fs.existsSync(destination)) {
44
+ const existing = installedClient(destination, target);
45
+ if (existing) return existing;
46
+ throw new Error(`Incomplete Peer Codex install at ${destination}. Remove that directory and retry.`);
47
+ }
48
+
49
+ fs.mkdirSync(root, { recursive: true, mode: 0o700 });
50
+ const staging = fs.mkdtempSync(path.join(root, ".install-"));
51
+ try {
52
+ const args = [
53
+ "install", "--prefix", ".", "--global=false", "--ignore-scripts",
54
+ "--no-save", "--no-package-lock", "--no-audit", "--no-fund", spec,
55
+ ];
56
+ const options = { cwd: staging, stdio: "inherit", timeout: 600_000 };
57
+ if (process.platform === "win32") {
58
+ execFileSync(process.env.ComSpec || "cmd.exe", ["/d", "/c", "npm", ...args], options);
59
+ } else {
60
+ execFileSync("npm", args, options);
61
+ }
62
+ const downloaded = path.join(staging, "node_modules", packageName);
63
+ if (!installedClient(downloaded, target)) throw new Error(`${spec} is missing its executables`);
64
+ try {
65
+ fs.renameSync(downloaded, destination);
66
+ } catch (error) {
67
+ if (!installedClient(destination, target)) throw error;
68
+ }
69
+ return installedClient(destination, target);
70
+ } finally {
71
+ fs.rmSync(staging, { recursive: true, force: true });
72
+ }
73
+ }
@@ -1,6 +1,7 @@
1
1
  import { execFileSync } from "node:child_process";
2
2
  import fs from "node:fs";
3
3
  import path from "node:path";
4
+ import { installNativeCodex } from "./codex-native.mjs";
4
5
 
5
6
  // Codex's lifecycle hooks use their own event and output shapes. Keep Claude's
6
7
  // title updates and UI out of this adapter.
@@ -21,14 +22,13 @@ export function installCodex(peer, { client = false } = {}) {
21
22
  fs.accessSync(clientPath, fs.constants.X_OK);
22
23
  if (!fs.statSync(clientPath).isFile()) throw new Error("PEER_CODEX_CLIENT must point to the Codex executable");
23
24
  } else {
24
- const checkout = path.resolve(peer.home, "codex-client");
25
- execFileSync("bash", [path.join(marketplace, "client", "build.sh"), checkout], { stdio: "inherit" });
26
- clientPath = path.join(checkout, "codex-rs", "target", "debug", "codex");
25
+ clientPath = installNativeCodex(peer);
27
26
  }
28
27
  }
29
28
 
30
29
  const binary = process.env.PEER_CODEX || (client ? clientPath : "codex");
31
- const runCodex = (args, capture = false) => codex(args, { binary, capture });
30
+ const timeout = client ? 300_000 : 60_000;
31
+ const runCodex = (args, capture = false) => codex(args, { binary, capture, timeout });
32
32
  const listed = runCodex(["plugin", "marketplace", "list", "--json"], true);
33
33
  const previous = JSON.parse(listed).marketplaces?.find((item) => item.name === MARKETPLACE);
34
34
  const moving = previous && previous.root !== marketplace;
@@ -65,11 +65,11 @@ export function uninstallCodex(peer) {
65
65
  console.log("Codex: Peer's plugin removed.");
66
66
  }
67
67
 
68
- function codex(args, { binary, capture = false }) {
68
+ function codex(args, { binary, capture = false, timeout = 60_000 }) {
69
69
  return execFileSync(binary, args, {
70
70
  stdio: capture ? ["ignore", "pipe", "inherit"] : "inherit",
71
71
  encoding: "utf8",
72
- timeout: 60_000,
72
+ timeout,
73
73
  });
74
74
  }
75
75
 
@@ -0,0 +1,45 @@
1
+ #!/usr/bin/env node
2
+ import { spawn } from "node:child_process";
3
+ import fs from "node:fs";
4
+ import os from "node:os";
5
+ import path from "node:path";
6
+ import { codexExecutable } from "./codex-native.mjs";
7
+
8
+ const home = process.env.PEER_HOME || path.join(os.homedir(), ".peer");
9
+ let configured;
10
+ try {
11
+ configured = JSON.parse(fs.readFileSync(path.join(home, "codex-cli.json"), "utf8"))?.client;
12
+ } catch {}
13
+ const client = process.env.PEER_CODEX_CLIENT
14
+ || (typeof configured === "string" && path.isAbsolute(configured) ? configured : null)
15
+ || path.join(home, "codex-client", "codex-rs", "target", "debug", codexExecutable(process.platform));
16
+ try {
17
+ fs.accessSync(client, fs.constants.X_OK);
18
+ } catch {
19
+ console.error("Set up the Peer Codex terminal with peer install --codex --client.");
20
+ process.exit(1);
21
+ }
22
+
23
+ // A stock daemon would use the stock memory policy.
24
+ const args = ["--no-daemon", ...process.argv.slice(2)];
25
+ const env = { ...process.env, PEER_CODEX_THREAD_MARK: "1" };
26
+ if (process.platform !== "win32" && typeof process.execve === "function") {
27
+ process.on("SIGXFSZ", () => {});
28
+ process.execve(client, [client, ...args], env);
29
+ }
30
+
31
+ const child = spawn(client, args, { stdio: "inherit", env });
32
+ const signals = ["SIGINT", "SIGTERM", "SIGHUP"];
33
+ const forward = (signal) => {
34
+ if (!child.killed) child.kill(signal);
35
+ };
36
+ for (const signal of signals) process.on(signal, forward);
37
+ child.on("error", (error) => {
38
+ console.error(`Could not start Peer Codex: ${error.message}`);
39
+ process.exitCode = 1;
40
+ });
41
+ child.on("exit", (code, signal) => {
42
+ for (const name of signals) process.off(name, forward);
43
+ process.exitCode = code ?? (signal ? 128 + os.constants.signals[signal] : 1);
44
+ if (signal && process.platform !== "win32") process.kill(process.pid, signal);
45
+ });
package/bin/peer.mjs CHANGED
@@ -46,7 +46,7 @@ const HELP = `peer: share chosen agent threads with your team
46
46
  your own memories in your personal OpenViking, or the ones with these words
47
47
  (full text); here: only this repository's. /peer-all in Claude Code
48
48
  peer install [--codex [--client]]
49
- set up the thread mark; --client also builds the Peer Codex terminal
49
+ set up the thread mark; --client also installs the Peer Codex terminal
50
50
  peer uninstall [--codex] remove the integration from Claude Code or Codex
51
51
  peer logout forget the sign-in on this computer
52
52
 
@@ -450,6 +450,12 @@ function installMark() {
450
450
  } catch {}
451
451
  install();
452
452
  }
453
+ // `plugin install` leaves an installed version alone, so an upgrade of this package re-reads its marketplace and
454
+ // moves the mark to the version it ships.
455
+ try {
456
+ claudeCli(["plugin", "marketplace", "update", MARKETPLACE]);
457
+ claudeCli(["plugin", "update", `${MOD}@${MARKETPLACE}`]);
458
+ } catch {}
453
459
  console.log(`Claude Code: the thread mark (${MOD}), a band above the prompt in shared threads, from ${MOD_DIR}.`);
454
460
  } catch (error) {
455
461
  const reason = String(error.stderr || error.message).trim().split("\n").pop();
@@ -1,8 +1,9 @@
1
1
  # Peer for the Codex terminal
2
2
 
3
3
  The sibling Codex plugin can report thread activity and answer commands with stock Codex.
4
- `build.sh` builds the terminal client for the band, local panels, and per-thread memory policy.
5
- `run.sh` keeps the terminal on its own app server so it uses that policy.
4
+ `peer install --codex --client` installs the native npm package for the current OS and
5
+ architecture. `peer-codex` runs that client with its own app server so it uses the
6
+ Peer memory policy.
6
7
 
7
8
  `src/` contains the Peer modules. The two patches wire them into the pinned Codex source:
8
9
  `0001-memory.patch` controls plugin availability, capture and native memory; `0002-terminal.patch`
@@ -12,6 +13,33 @@ capture windows. Update the Codex pin, V8 version, checksums and patches togethe
12
13
  The patches include context from OpenAI Codex, distributed under Apache-2.0.
13
14
  See [CODEX-LICENSE](CODEX-LICENSE) and [CODEX-NOTICE](CODEX-NOTICE).
14
15
 
16
+ ## Building and packing a release
17
+
18
+ `build.sh` takes the path of a checkout to create or reuse. It needs Git, Rust/Cargo,
19
+ `curl`, `shasum`, and a C/C++ toolchain. For a custom build, run it and set
20
+ `PEER_CODEX_CLIENT` to the resulting executable when running `peer install --codex --client`.
21
+
22
+ Set `PEER_CODEX_BUILD_PROFILE=release` for an npm build and set
23
+ `CARGO_PROFILE_RELEASE_STRIP=symbols` before compiling. Set `PEER_CODEX_BUILD_TARGET`
24
+ to build for a specific Rust target with the matching Rust standard library and C toolchain.
25
+ For cross-compiling, `PEER_CODEX_CARGO_COMMAND` can select `zigbuild` or `xwin`.
26
+ For Linux musl builds, use the pinned upstream release's musl tools and set
27
+ `CODEX_BWRAP_SHA256` to the SHA-256 of the `codex-resources/bwrap` shipped in the
28
+ matching upstream npm package before compiling.
29
+
30
+ After building, run:
31
+
32
+ ```bash
33
+ bash pack.sh darwin-arm64 /path/to/build/bin /path/to/codex-checkout /path/to/output
34
+ ```
35
+
36
+ Use the directory containing both `codex` and `codex-code-mode-host` (with `.exe` on
37
+ Windows). The script adds the matching upstream sandbox and search helpers. Build and
38
+ pack `darwin-arm64`, `darwin-x64`, `linux-arm64`, `linux-x64`, `win32-arm64`, and
39
+ `win32-x64` for a native release. The installer pins their version in
40
+ `bin/codex-native.mjs`. When that pin changes, publish and verify the native packages
41
+ before publishing the version of `@webinson/peer` that uses them.
42
+
15
43
  From the repository root, run `npm test --prefix cli`. To exercise the actual band, switches,
16
44
  and panels with temporary profiles and local fixture servers, run:
17
45
 
@@ -39,20 +39,34 @@ if [[ -n ${PEER_CODEX_TOOLCHAIN:-} ]]; then
39
39
  fi
40
40
  cd -- "$checkout/codex-rs"
41
41
  # The pinned Codex release ships its V8 build on the Codex release, not on denoland's.
42
- host=$(rustc ${cargo_args[@]+"${cargo_args[@]}"} -vV | awk '/^host:/ {print $2}')
42
+ target=${PEER_CODEX_BUILD_TARGET:-$(rustc ${cargo_args[@]+"${cargo_args[@]}"} -vV | awk '/^host:/ {print $2}')}
43
+ profile=${PEER_CODEX_BUILD_PROFILE:-dev}
44
+ build_args=(--profile "$profile")
45
+ cargo_command=("${PEER_CODEX_CARGO_COMMAND:-build}")
46
+ if [[ "${cargo_command[0]}" == xwin ]]; then
47
+ cargo_command+=(build)
48
+ fi
49
+ target_dir=${CARGO_TARGET_DIR:-"$checkout/codex-rs/target"}
50
+ output="$target_dir"
51
+ if [[ -n ${PEER_CODEX_BUILD_TARGET:-} ]]; then
52
+ build_args+=(--target "$target")
53
+ output="$output/$target"
54
+ fi
43
55
  v8=152.2.0
44
- v8_dir="$checkout/target/peer-v8/$host"
56
+ v8_dir="$checkout/target/peer-v8/$target"
45
57
  v8_base="https://github.com/openai/codex/releases/download/rusty-v8-v$v8"
46
- binding="src_binding_ptrcomp_sandbox_release_${host}.rs"
47
- archive="librusty_v8_ptrcomp_sandbox_release_${host}.a.gz"
48
- if [[ "$host" == *-pc-windows-msvc ]]; then
49
- archive="rusty_v8_ptrcomp_sandbox_release_${host}.lib.gz"
58
+ binding="src_binding_ptrcomp_sandbox_release_${target}.rs"
59
+ archive="librusty_v8_ptrcomp_sandbox_release_${target}.a.gz"
60
+ exe=""
61
+ if [[ "$target" == *-pc-windows-msvc ]]; then
62
+ archive="rusty_v8_ptrcomp_sandbox_release_${target}.lib.gz"
63
+ exe=".exe"
50
64
  fi
51
65
  mkdir -p -- "$v8_dir"
52
66
  for artifact in "$archive" "$binding"; do
53
67
  checksum=$(awk -v file="$artifact" '$2 == file {print $1}' "$checkout/third_party/v8/rusty_v8_${v8//./_}.sha256")
54
68
  if [[ -z "$checksum" ]]; then
55
- printf 'No pinned Codex V8 artifact for %s.\n' "$host" >&2
69
+ printf 'No pinned Codex V8 artifact for %s.\n' "$target" >&2
56
70
  exit 1
57
71
  fi
58
72
  if ! (cd -- "$v8_dir" && printf '%s %s\n' "$checksum" "$artifact" | shasum -a 256 -c - >/dev/null 2>&1); then
@@ -62,6 +76,7 @@ for artifact in "$archive" "$binding"; do
62
76
  done
63
77
  # The upstream release tag changes workspace versions without regenerating Cargo.lock.
64
78
  RUSTY_V8_ARCHIVE="$v8_dir/$archive" RUSTY_V8_SRC_BINDING_PATH="$v8_dir/$binding" \
65
- CARGO_PROFILE_DEV_DEBUG=0 cargo ${cargo_args[@]+"${cargo_args[@]}"} build \
66
- --target-dir "$checkout/codex-rs/target" -p codex-cli -p codex-code-mode-host --bins
67
- printf 'Run with: PEER_CODEX_CLIENT=%q bash %q\n' "$checkout/codex-rs/target/debug/codex" "$here/run.sh"
79
+ CARGO_PROFILE_DEV_DEBUG=0 cargo ${cargo_args[@]+"${cargo_args[@]}"} "${cargo_command[@]}" \
80
+ "${build_args[@]}" --target-dir "$target_dir" -p codex-cli -p codex-code-mode-host --bins
81
+ [[ "$profile" != dev ]] || profile=debug
82
+ printf 'Run with: PEER_CODEX_CLIENT=%q peer-codex\n' "$output/$profile/codex$exe"
@@ -0,0 +1,80 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ here=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)
5
+ cli=$(cd -- "$here/../../.." && pwd)
6
+ platform=${1:?usage: pack.sh PLATFORM BUILD_BIN_DIR CODEX_CHECKOUT OUTPUT_DIR}
7
+ build=$(cd -- "${2:?missing build bin directory}" && pwd)
8
+ source=$(cd -- "${3:?missing pinned Codex checkout}" && pwd)
9
+ mkdir -p -- "${4:?missing output directory}"
10
+ output=$(cd -- "$4" && pwd)
11
+ target=$(node --input-type=module - "$cli" "$platform" <<'JS'
12
+ import { pathToFileURL } from "node:url";
13
+ import path from "node:path";
14
+ const { codexTargets } = await import(pathToFileURL(path.join(process.argv[2], "bin/codex-native.mjs")));
15
+ const target = codexTargets[process.argv[3]];
16
+ if (!target) throw new Error("Unsupported Peer Codex platform");
17
+ console.log(target);
18
+ JS
19
+ )
20
+
21
+ commit=f79b26ccbb3116b052544666a181012fb45dc49b
22
+ codex_version=0.166.0-alpha.5.1
23
+ [[ $(git -C "$source" rev-parse HEAD) == "$commit" ]]
24
+ stage=$(mktemp -d "${TMPDIR:-/tmp}/peer-codex-pack.XXXXXXXX")
25
+ trap 'rm -rf -- "$stage"' EXIT
26
+ archive=$(npm pack "@openai/codex@$codex_version-$platform" --ignore-scripts --pack-destination "$stage" --silent)
27
+ suffix=""
28
+ resources=()
29
+ case "$platform" in
30
+ linux-*) resources+=(codex-resources/bwrap) ;;
31
+ win32-*)
32
+ suffix=.exe
33
+ resources+=(codex-resources/codex-command-runner.exe codex-resources/codex-windows-sandbox-setup.exe)
34
+ ;;
35
+ esac
36
+ vendor="package/vendor/$target"
37
+ assets=("$vendor/codex-package.json" "$vendor/codex-path/rg$suffix")
38
+ for asset in ${resources[@]+"${resources[@]}"}; do assets+=("$vendor/$asset"); done
39
+ tar -xf "$stage/$archive" -C "$stage" "${assets[@]}"
40
+ mkdir -p "$stage/$vendor/bin"
41
+ for binary in codex codex-code-mode-host; do
42
+ install -m 755 "$build/$binary$suffix" "$stage/$vendor/bin/$binary$suffix"
43
+ done
44
+ cp "$here/CODEX-LICENSE" "$stage/package/LICENSE"
45
+ cp "$here/CODEX-NOTICE" "$stage/package/NOTICE"
46
+ curl -fsSL --retry 2 'https://raw.githubusercontent.com/BurntSushi/ripgrep/15.2.0/LICENSE-MIT' \
47
+ -o "$stage/package/RIPGREP-LICENSE"
48
+ if [[ "$platform" == linux-* ]]; then
49
+ cp "$source/codex-rs/vendor/bubblewrap/LICENSE" "$stage/package/BUBBLEWRAP-LICENSE"
50
+ fi
51
+ cat >> "$stage/package/NOTICE" <<EOF
52
+
53
+ Peer Codex modifies the terminal UI, thread sharing and memory policy.
54
+ Upstream source: https://github.com/openai/codex/tree/$commit
55
+ The matching @webinson/peer npm package contains the Peer changes.
56
+
57
+ The bundled ripgrep is from https://github.com/BurntSushi/ripgrep/tree/15.2.0.
58
+ Linux bundles include the sandbox helper built from the Codex source above
59
+ under codex-rs/vendor/bubblewrap. The corresponding sources and build scripts
60
+ are in that same tree.
61
+ EOF
62
+ node --input-type=module - "$cli" "$platform" "$stage/package" <<'JS'
63
+ import fs from "node:fs";
64
+ import path from "node:path";
65
+ import { pathToFileURL } from "node:url";
66
+ const [cli, platform, stage] = process.argv.slice(2);
67
+ const [os, cpu] = platform.split("-");
68
+ const { codexPackageName, codexNativeVersion } = await import(pathToFileURL(path.join(cli, "bin/codex-native.mjs")));
69
+ const pkg = {
70
+ name: codexPackageName(platform),
71
+ version: codexNativeVersion,
72
+ description: `Peer Codex terminal for ${os} ${cpu}. Installed by @webinson/peer.`,
73
+ license: "Apache-2.0",
74
+ os: [os],
75
+ cpu: [cpu],
76
+ files: ["vendor", "NOTICE", "*-LICENSE"],
77
+ };
78
+ fs.writeFileSync(path.join(stage, "package.json"), JSON.stringify(pkg, null, 2) + "\n");
79
+ JS
80
+ npm pack "$stage/package" --pack-destination "$output" --ignore-scripts
@@ -1,22 +1,5 @@
1
1
  #!/usr/bin/env bash
2
2
  set -euo pipefail
3
3
 
4
- peer_root=${PEER_HOME:-"$HOME/.peer"}
5
- client=${PEER_CODEX_CLIENT:-}
6
- if [[ -z "$client" && -f "$peer_root/codex-cli.json" ]]; then
7
- client=$(node -e '
8
- try {
9
- const data = JSON.parse(require("node:fs").readFileSync(process.argv[1], "utf8"));
10
- if (typeof data.client === "string" && require("node:path").isAbsolute(data.client)) {
11
- process.stdout.write(data.client);
12
- }
13
- } catch {}
14
- ' "$peer_root/codex-cli.json")
15
- fi
16
- client=${client:-"$peer_root/codex-client/codex-rs/target/debug/codex"}
17
- if [[ ! -x "$client" ]]; then
18
- printf 'Set up the Peer Codex terminal with peer install --codex --client.\n' >&2
19
- exit 1
20
- fi
21
- # An existing stock daemon would use the stock memory policy.
22
- PEER_CODEX_THREAD_MARK=1 exec "$client" --no-daemon "$@"
4
+ here=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)
5
+ exec node "$here/../../../bin/peer-codex.mjs" "$@"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "peer-thread-mark",
3
- "version": "0.4.18",
3
+ "version": "0.4.19",
4
4
  "description": "Marks a Claude Code thread shared with Peer (/peer) with a band above the prompt, with /peer stop and /peer start; panes for /peer-list, /peer-thread and /peer-all (search your memories)",
5
5
  "license": "MIT",
6
6
  "types": "./types/index.d.ts"
package/package.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@webinson/peer",
3
- "version": "0.4.18",
3
+ "version": "0.4.20",
4
4
  "description": "Share chosen Claude Code and Codex threads with your team: who has agents running and on what.",
5
5
  "license": "MIT",
6
6
  "type": "module",
7
7
  "bin": {
8
8
  "peer": "bin/peer.mjs",
9
- "peer-codex": "mod/codex/client/run.sh"
9
+ "peer-codex": "bin/peer-codex.mjs"
10
10
  },
11
11
  "files": [
12
12
  "bin",