pstack-claude-mirror 0.9.134 → 0.9.135
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/.claude-plugin/marketplace.json +1 -1
- package/CHANGES.md +8 -0
- package/README.md +4 -4
- package/UPSTREAM-README.md +1 -1
- package/docs/reference.md +1 -1
- package/package.json +6 -6
- package/plugins/pstack/.antigravity-plugin/plugin.json +1 -1
- package/plugins/pstack/.claude-plugin/plugin.json +1 -1
- package/plugins/pstack/.codex-plugin/plugin.json +1 -1
- package/plugins/pstack/.github/plugin/plugin.json +1 -1
- package/plugins/pstack/.grok-plugin/plugin.json +1 -1
- package/plugins/pstack/.muse-plugin/plugin.json +1 -1
- package/plugins/pstack/package.json +1 -1
- package/plugins/pstack/skills/poteto-mode/scripts/worktree-audit.mjs +42 -1
- package/plugins/pstack/skills/reflect/scripts/find-transcript.mjs +2 -2
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
"name": "pstack",
|
|
11
11
|
"source": "./plugins/pstack",
|
|
12
12
|
"description": "If you want to go fast, go deep first. pstack helps you write less, but higher quality code. rigorous agent workflows you can parallelize with confidence. Original pstack by Lauren Tan (poteto).",
|
|
13
|
-
"version": "0.9.
|
|
13
|
+
"version": "0.9.135"
|
|
14
14
|
}
|
|
15
15
|
]
|
|
16
16
|
}
|
package/CHANGES.md
CHANGED
|
@@ -2,6 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
This file is the release changelog, with one `## <version> - <title>` entry per release, newest first. The Cursor-to-Claude rewrite rules live in [`tools/substitutions.json`](tools/substitutions.json), and the [sync boundary](CONTRIBUTING.md#the-sync-boundary) in `CONTRIBUTING.md` defines how a change to upstream's skill content is declared.
|
|
4
4
|
|
|
5
|
+
## 0.9.135 - worktree audit reads compressed Codex rollouts
|
|
6
|
+
|
|
7
|
+
`worktree-audit.mjs` now reads the `.jsonl.zst` rollouts under Codex's `sessions` and `archived_sessions`. It used to skip them, so a worktree whose latest chat sat in a compressed rollout showed no LAST_CHAT and could be reported safe. Plain `.jsonl` transcripts are read as before, and `find-transcript.mjs` lists compressed files only for a caller that passes `includeCompressed`, so the **reflect** skill's search is unchanged. @EthanYoQ found and fixed this in [#425](https://github.com/michael-denyer/pstack-claude/pull/425).
|
|
8
|
+
|
|
9
|
+
The audit decodes in the process with `zlib.zstdDecompressSync` when that decoder reads every frame of a file and rejects a truncated one. It checks both once at start-up. Node 26.13.0 passes the check. Bun 1.4.4 returns the partial output of a truncated frame without an error, so the audit runs the `zstd` command there, as it does on a Node that has no Zstd decoder. Only a machine that has compressed rollouts needs a decoder.
|
|
10
|
+
|
|
11
|
+
A compressed rollout that cannot be decoded, because it is corrupt or truncated or because no decoder is available, leaves LAST_CHAT unknown for every worktree. The audit warns `transcript scan failed` with the file's path, and no worktree reaches safe until the file decodes or is removed.
|
|
12
|
+
|
|
5
13
|
## 0.9.134 - Fable 5.2 on Pi, Pi 1.5.1 as the oldest supported Pi
|
|
6
14
|
|
|
7
15
|
On Pi, the `anthropic` provider's `fable` role runs `claude-fable-5-2`, where it ran `claude-fable-5-1`. A session on a provider that has no table of its own uses the `anthropic` table, so its `fable` role changes too. Claude Code sessions need no change, because Claude Code 2.1.321 moved its own `fable` alias to Fable 5.2. The model first appears in Pi 1.5.1's catalog. Pi 1.5.0 does not have it. It warns `Model "claude-fable-5-2" not found for provider "anthropic". Using custom model id.` and runs that ID with the context window, pricing, and thinking settings of the provider's default model. To stay on Fable 5.1, add the line `pi models: fable=anthropic/claude-fable-5-1` to the override sheet.
|
package/README.md
CHANGED
|
@@ -9,10 +9,10 @@
|
|
|
9
9
|
|
|
10
10
|
| | |
|
|
11
11
|
|---|---|
|
|
12
|
-
| Package version | `0.9.
|
|
13
|
-
| Upstream plugin version | `0.9.
|
|
14
|
-
| Upstream ref | `v0.9.
|
|
15
|
-
| Upstream commit | `
|
|
12
|
+
| Package version | `0.9.135` |
|
|
13
|
+
| Upstream plugin version | `0.9.135` |
|
|
14
|
+
| Upstream ref | `v0.9.135` |
|
|
15
|
+
| Upstream commit | `bc09365fe61c725c486ba95157fc4048bf8a0b99` (2026-11-11T00:19:58Z) |
|
|
16
16
|
| Marketplace / plugin | `pstack@pstack-claude` |
|
|
17
17
|
|
|
18
18
|
The package contains the upstream marketplace exactly as published (`.claude-plugin/marketplace.json` + `plugins/pstack/`) plus a small installer. No install scripts run on `npm install`.
|
package/UPSTREAM-README.md
CHANGED
|
@@ -47,7 +47,7 @@ Invoke a skill by typing `$` and its name, such as `$poteto-mode` or `$babysit`,
|
|
|
47
47
|
<details>
|
|
48
48
|
<summary><strong>Pi</strong></summary>
|
|
49
49
|
|
|
50
|
-
Run in your terminal:
|
|
50
|
+
Run in your terminal, with Pi 1.5.1 or later:
|
|
51
51
|
|
|
52
52
|
```shell
|
|
53
53
|
pi install git:github.com/michael-denyer/pstack-claude
|
package/docs/reference.md
CHANGED
|
@@ -62,7 +62,7 @@ All runtimes share [one skills tree](../plugins/pstack/skills/). A skills-only i
|
|
|
62
62
|
| --- | --- |
|
|
63
63
|
| Claude Code | Install the marketplace plugin (Claude Code 2.1.292 or later). Skills use Claude tool names and model defaults; the plugin installs automatic routing. |
|
|
64
64
|
| Codex | Install the native plugin through the repository's marketplace and trust its hook through `/hooks`. The [Codex mapping](../plugins/pstack/skills/poteto-mode/references/codex-tools.md) translates Claude tools and model names. Shared skill symlinks were also detected in a live session. |
|
|
65
|
-
| Pi | Install the repository as a Pi package with `pi install
|
|
65
|
+
| Pi | Install the repository as a Pi package with `pi install` (Pi 1.5.1 or later). The [Pi extension](../plugins/pstack/pi/index.ts) registers the subagent, question, and wake-up tools and `/loop`, and the [Pi mapping](../plugins/pstack/skills/poteto-mode/references/pi-tools.md) translates Claude tools and model names. The [equivalence table](pi-equivalence.md) records each Claude Code mechanism and how it was verified on Pi 1.5.1. |
|
|
66
66
|
| GitHub Copilot | Install the plugin through the repository's marketplace; the CLI and the GitHub Copilot app share it. The [Copilot mapping](../plugins/pstack/skills/poteto-mode/references/copilot-tools.md) translates Claude tools, paths, and model roles, and maps app-only tools to CLI fallbacks. Install, routing, agent dispatch, and first-run setup are smoke-tested on the CLI; see [GitHub Copilot](#github-copilot). |
|
|
67
67
|
| Muse | Install the native plugin bundle with `muse plugins install`, then approve its hooks and agent definitions with `muse plugins approve pstack`. The [Muse mapping](../plugins/pstack/skills/poteto-mode/references/muse-tools.md) translates Claude tools, subagents, transcripts, and model roles. See [Muse](#muse). |
|
|
68
68
|
| OMP | Install through the marketplace as described in the [README](../README.md#install). The [OMP mapping](../plugins/pstack/skills/poteto-mode/references/omp-tools.md) covers tools and model roles. On OMP 18.16.0, installation from a local marketplace, skill access, and the routing toggle were verified with a synthetic provider; model compliance has not been tested. |
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pstack-claude-mirror",
|
|
3
|
-
"version": "0.9.
|
|
4
|
-
"description": "[Unofficial GitHub mirror] Unmodified copy of https://github.com/michael-denyer/pstack-claude @ v0.9.
|
|
3
|
+
"version": "0.9.135",
|
|
4
|
+
"description": "[Unofficial GitHub mirror] Unmodified copy of https://github.com/michael-denyer/pstack-claude @ v0.9.135 (pstack skills/plugin for OMP, Claude Code, Pi), republished on npm for networks without GitHub access. Not published by or affiliated with the upstream author. Report mirror packaging and installer bugs to the mirror repository; report plugin-content bugs upstream.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"homepage": "https://github.com/michael-denyer/pstack-claude",
|
|
7
7
|
"repository": {
|
|
@@ -94,14 +94,14 @@
|
|
|
94
94
|
"pstackMirror": {
|
|
95
95
|
"notice": "Unofficial mirror. Content is copied unchanged from the upstream GitHub repository; only bin/, README.md, LICENSE-mirror and package.json are added by the mirror (MIT, see LICENSE-mirror). Upstream copyright and license notices are preserved unchanged.",
|
|
96
96
|
"upstream": "https://github.com/michael-denyer/pstack-claude.git",
|
|
97
|
-
"upstreamVersion": "0.9.
|
|
97
|
+
"upstreamVersion": "0.9.135",
|
|
98
98
|
"upstreamAuthor": {
|
|
99
99
|
"name": "Michael Denyer",
|
|
100
100
|
"url": "https://github.com/michael-denyer"
|
|
101
101
|
},
|
|
102
|
-
"ref": "v0.9.
|
|
103
|
-
"commit": "
|
|
104
|
-
"commitDate": "2026-11-
|
|
102
|
+
"ref": "v0.9.135",
|
|
103
|
+
"commit": "bc09365fe61c725c486ba95157fc4048bf8a0b99",
|
|
104
|
+
"commitDate": "2026-11-11T00:19:58Z",
|
|
105
105
|
"marketplace": "pstack-claude",
|
|
106
106
|
"plugin": "pstack"
|
|
107
107
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pstack",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.135",
|
|
4
4
|
"description": "If you want to go fast, go deep first. pstack helps you write less, but higher quality code. rigorous agent workflows you can parallelize with confidence. Ported from cursor/plugins/pstack to Antigravity. Original pstack by Lauren Tan (poteto).",
|
|
5
5
|
"author": "Michael Denyer",
|
|
6
6
|
"logo": "assets/pstack-icon.png",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pstack",
|
|
3
3
|
"displayName": "pstack (Claude Code port)",
|
|
4
|
-
"version": "0.9.
|
|
4
|
+
"version": "0.9.135",
|
|
5
5
|
"description": "If you want to go fast, go deep first. pstack helps you write less, but higher quality code. rigorous agent workflows you can parallelize with confidence. Ported from cursor/plugins/pstack to Claude Code. Original pstack by Lauren Tan (poteto).",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "Michael Denyer",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pstack",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.135",
|
|
4
4
|
"description": "If you want to go fast, go deep first. pstack helps you write less, but higher quality code. rigorous agent workflows you can parallelize with confidence. Codex port of the Claude Code plugin; skills are shared, tool names resolve via skills/poteto-mode/references/codex-tools.md. Original pstack by Lauren Tan (poteto).",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Michael Denyer",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pstack",
|
|
3
3
|
"displayName": "pstack (GitHub Copilot port)",
|
|
4
|
-
"version": "0.9.
|
|
4
|
+
"version": "0.9.135",
|
|
5
5
|
"description": "If you want to go fast, go deep first. pstack helps you write less, but higher quality code. rigorous agent workflows you can parallelize with confidence. Ported from cursor/plugins/pstack to GitHub Copilot CLI and app. Original pstack by Lauren Tan (poteto).",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "Michael Denyer",
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"schemaVersion": 1,
|
|
3
3
|
"name": "pstack",
|
|
4
4
|
"displayName": "pstack (Muse port)",
|
|
5
|
-
"version": "0.9.
|
|
5
|
+
"version": "0.9.135",
|
|
6
6
|
"description": "If you want to go fast, go deep first. pstack helps you write less, but higher quality code. Rigorous agent workflows you can parallelize with confidence. Muse port of the Claude Code plugin; skills are shared, tool names resolve via skills/poteto-mode/references/muse-tools.md. Original pstack by Lauren Tan (poteto).",
|
|
7
7
|
"compat": {
|
|
8
8
|
"source": "native",
|
|
@@ -12,6 +12,10 @@
|
|
|
12
12
|
// and archived_sessions under $CODEX_HOME, and Pi's sessions and pstack subagent
|
|
13
13
|
// sessions under $PI_CODING_AGENT_DIR (defaults: ~/.claude, ~/.codex, ~/.pi/agent).
|
|
14
14
|
//
|
|
15
|
+
// Compressed rollouts use native Zstd when it reads complete streams. Other
|
|
16
|
+
// runtimes fall back to zstd on PATH. A decode failure makes the whole chat
|
|
17
|
+
// scan unknown, so no worktree can be declared safe from that scan.
|
|
18
|
+
//
|
|
15
19
|
// Every probe yields a Fact, { known: true, value } or { known: false }. A hold
|
|
16
20
|
// bucket needs only its own fact; `safe` needs every fact known.
|
|
17
21
|
import { execFileSync } from "node:child_process";
|
|
@@ -20,6 +24,7 @@ import { homedir } from "node:os";
|
|
|
20
24
|
import { basename, dirname, join } from "node:path";
|
|
21
25
|
import process from "node:process";
|
|
22
26
|
import { fileURLToPath } from "node:url";
|
|
27
|
+
import zlib from "node:zlib";
|
|
23
28
|
|
|
24
29
|
import { candidates, rethrowUnlessRemoved } from "../../reflect/scripts/find-transcript.mjs";
|
|
25
30
|
|
|
@@ -199,11 +204,38 @@ function transcriptNeedles(spellings) {
|
|
|
199
204
|
return [...new Set(forms)].map((form) => Buffer.from(JSON.stringify(form).slice(1, -1)));
|
|
200
205
|
}
|
|
201
206
|
|
|
207
|
+
// Bun 1.4.4 returns the partial output of a truncated frame without an error,
|
|
208
|
+
// and nodejs/node#64592 reports the same for Node. The check also turns down a
|
|
209
|
+
// decoder that stops after the first frame. It runs once, not once per transcript.
|
|
210
|
+
function nativeZstdDecoder() {
|
|
211
|
+
const decode = zlib.zstdDecompressSync;
|
|
212
|
+
if (typeof decode !== "function") return undefined;
|
|
213
|
+
// A complete Zstd frame containing "a", independent of compressor availability.
|
|
214
|
+
const frame = Buffer.from("28b52ffd200109000061", "hex");
|
|
215
|
+
const joined = Buffer.concat([frame, frame]);
|
|
216
|
+
try {
|
|
217
|
+
if (decode(joined).toString() !== "aa") return undefined;
|
|
218
|
+
} catch {
|
|
219
|
+
return undefined;
|
|
220
|
+
}
|
|
221
|
+
for (const partial of [frame.subarray(0, -1), joined.subarray(0, -1)]) {
|
|
222
|
+
try {
|
|
223
|
+
decode(partial);
|
|
224
|
+
return undefined;
|
|
225
|
+
} catch { /* A complete-stream decoder must reject an unfinished frame. */ }
|
|
226
|
+
}
|
|
227
|
+
return decode;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
const decodeZstd = nativeZstdDecoder() ?? ((input) => execFileSync("zstd", ["-d", "-c"], {
|
|
231
|
+
input, stdio: ["pipe", "pipe", "pipe"], maxBuffer: Infinity, timeout: 30_000,
|
|
232
|
+
}));
|
|
233
|
+
|
|
202
234
|
// `spellings` maps each worktree path to every spelling a session could use.
|
|
203
235
|
export function lastChats(roots, spellings) {
|
|
204
236
|
const needles = [...spellings].map(([path, forms]) => [path, transcriptNeedles(forms)]);
|
|
205
237
|
const latest = new Map();
|
|
206
|
-
for (const { path: file } of roots.flatMap((root) => candidates(root, Infinity))) {
|
|
238
|
+
for (const { path: file } of roots.flatMap((root) => candidates(root, Infinity, { includeCompressed: true }))) {
|
|
207
239
|
let text, mtime;
|
|
208
240
|
try {
|
|
209
241
|
text = readFileSync(file);
|
|
@@ -214,6 +246,15 @@ export function lastChats(roots, spellings) {
|
|
|
214
246
|
rethrowUnlessRemoved(error);
|
|
215
247
|
continue;
|
|
216
248
|
}
|
|
249
|
+
if (file.endsWith(".jsonl.zst")) {
|
|
250
|
+
try {
|
|
251
|
+
text = decodeZstd(text);
|
|
252
|
+
} catch (error) {
|
|
253
|
+
// A missing fallback executable is not a transcript removed during enumeration.
|
|
254
|
+
const hint = error.code === "ENOENT" ? " Use a runtime with complete native Zstd support or install zstd." : "";
|
|
255
|
+
throw new Error(`cannot decode ${file}: ${String(error.stderr ?? "").trim() || error.message}${hint}`);
|
|
256
|
+
}
|
|
257
|
+
}
|
|
217
258
|
for (const [path, forms] of needles) {
|
|
218
259
|
if (mtime > (latest.get(path) ?? 0) && forms.some((needle) => mentions(text, needle))) latest.set(path, mtime);
|
|
219
260
|
}
|
|
@@ -38,12 +38,12 @@ export function rethrowUnlessRemoved(error) {
|
|
|
38
38
|
if (error.code !== "ENOENT") throw error;
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
-
export function candidates(projectsDir, maxDepth = 2) {
|
|
41
|
+
export function candidates(projectsDir, maxDepth = 2, { includeCompressed = false } = {}) {
|
|
42
42
|
const files = [];
|
|
43
43
|
const walk = (dir, depth) => {
|
|
44
44
|
for (const entry of readdirSync(dir, { withFileTypes: true })) {
|
|
45
45
|
const full = join(dir, entry.name);
|
|
46
|
-
if (entry.isFile() && entry.name.endsWith(".jsonl")) files.push(full);
|
|
46
|
+
if (entry.isFile() && (entry.name.endsWith(".jsonl") || (includeCompressed && entry.name.endsWith(".jsonl.zst")))) files.push(full);
|
|
47
47
|
else if (entry.isDirectory() && depth < maxDepth) {
|
|
48
48
|
try {
|
|
49
49
|
walk(full, depth + 1);
|