pi-studio 0.9.46 → 0.9.47
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/CHANGELOG.md +5 -0
- package/index.ts +14 -21
- package/package.json +1 -1
- package/shared/studio-pandoc-resource-flag.js +34 -0
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,11 @@ All notable changes to `pi-studio` are documented here.
|
|
|
4
4
|
|
|
5
5
|
## [Unreleased]
|
|
6
6
|
|
|
7
|
+
## [0.9.47] — 2026-08-20
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
- Fall back to Pandoc’s compatible self-contained resource mode when its capability probe times out, and evict failed probes so one transient delay cannot disable previews for the rest of the Studio process.
|
|
11
|
+
|
|
7
12
|
## [0.9.46] — 2026-08-20
|
|
8
13
|
|
|
9
14
|
### Fixed
|
package/index.ts
CHANGED
|
@@ -29,6 +29,7 @@ import {
|
|
|
29
29
|
} from "./shared/studio-markdown-latex-literals.js";
|
|
30
30
|
import { escapeStudioPdfLatexTextFragment } from "./shared/studio-pdf-escape.js";
|
|
31
31
|
import { resolveStudioPdfResourceFile } from "./shared/studio-pdf-resource.js";
|
|
32
|
+
import { createStudioPandocHtmlResourceFlagResolver } from "./shared/studio-pandoc-resource-flag.js";
|
|
32
33
|
import { isStudioCmuxSession, openStudioUrlInBrowser } from "./shared/studio-browser-launcher.js";
|
|
33
34
|
import { buildStudioReplTmuxStartArgs } from "./shared/studio-repl-tmux.js";
|
|
34
35
|
import { buildStudioForwardingHint, buildStudioSshTunnelHint, isStudioSshSession as isSshSession } from "./shared/studio-ssh-hint.js";
|
|
@@ -6126,27 +6127,19 @@ function decorateStudioPandocSyntaxHtml(html: string): string {
|
|
|
6126
6127
|
);
|
|
6127
6128
|
}
|
|
6128
6129
|
|
|
6129
|
-
const
|
|
6130
|
-
|
|
6131
|
-
|
|
6132
|
-
|
|
6133
|
-
|
|
6134
|
-
|
|
6135
|
-
|
|
6136
|
-
|
|
6137
|
-
|
|
6138
|
-
|
|
6139
|
-
notFoundMessage: "pandoc was not found. Install pandoc or set PANDOC_PATH to the pandoc binary.",
|
|
6140
|
-
}).then((result) => {
|
|
6141
|
-
if (result.code !== 0) {
|
|
6142
|
-
throw new Error(`pandoc capability probe failed with exit code ${result.code}${result.stderr ? `: ${result.stderr}` : ""}`);
|
|
6143
|
-
}
|
|
6144
|
-
return result.stdout.includes("--embed-resources") ? "--embed-resources" : "--self-contained";
|
|
6145
|
-
});
|
|
6146
|
-
studioPandocHtmlResourceFlagCache.set(pandocCommand, cached);
|
|
6130
|
+
const resolveStudioPandocHtmlResourceFlag = createStudioPandocHtmlResourceFlagResolver(async (pandocCommand: string) => {
|
|
6131
|
+
const result = await runStudioSubprocess(pandocCommand, ["--help"], {
|
|
6132
|
+
timeoutMs: 5_000,
|
|
6133
|
+
stdoutMaxBytes: 250_000,
|
|
6134
|
+
stderrMaxBytes: 20_000,
|
|
6135
|
+
label: "pandoc capability probe",
|
|
6136
|
+
notFoundMessage: "pandoc was not found. Install pandoc or set PANDOC_PATH to the pandoc binary.",
|
|
6137
|
+
});
|
|
6138
|
+
if (result.code !== 0) {
|
|
6139
|
+
throw new Error(`pandoc capability probe failed with exit code ${result.code}${result.stderr ? `: ${result.stderr}` : ""}`);
|
|
6147
6140
|
}
|
|
6148
|
-
return
|
|
6149
|
-
}
|
|
6141
|
+
return result.stdout;
|
|
6142
|
+
});
|
|
6150
6143
|
|
|
6151
6144
|
function preprocessStudioLatexFootnotemarksForPreview(latex: string): string {
|
|
6152
6145
|
return String(latex ?? "").replace(/\\footnotemark\s*\[\s*([^\]\r\n]+?)\s*\]/g, (_match, marker: string) => {
|
|
@@ -6186,7 +6179,7 @@ async function renderStudioMarkdownWithPandoc(markdown: string, isLatex?: boolea
|
|
|
6186
6179
|
await mkdir(htmlTemplateDir, { recursive: true });
|
|
6187
6180
|
const htmlTemplatePath = join(htmlTemplateDir, "template.html");
|
|
6188
6181
|
await writeFile(htmlTemplatePath, STUDIO_PANDOC_HTML_FRAGMENT_TEMPLATE, "utf-8");
|
|
6189
|
-
if (resourcePath) args.push(await
|
|
6182
|
+
if (resourcePath) args.push(await resolveStudioPandocHtmlResourceFlag(pandocCommand));
|
|
6190
6183
|
args.push("--standalone", `--template=${htmlTemplatePath}`);
|
|
6191
6184
|
}
|
|
6192
6185
|
const normalizedMarkdown = isLatex
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-studio",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.47",
|
|
4
4
|
"description": "Two-pane browser workspace for pi with prompt/response editing, annotations, critiques, active quiz, prompt/response history, live previews, and tmux-backed REPL/literate REPL workflows",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
export function createStudioPandocHtmlResourceFlagResolver(probeHelp) {
|
|
2
|
+
if (typeof probeHelp !== "function") {
|
|
3
|
+
throw new TypeError("A Pandoc capability probe function is required.");
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
const cache = new Map();
|
|
7
|
+
|
|
8
|
+
async function getResourceFlag(pandocCommand) {
|
|
9
|
+
const command = String(pandocCommand || "pandoc");
|
|
10
|
+
let cached = cache.get(command);
|
|
11
|
+
if (!cached) {
|
|
12
|
+
cached = Promise.resolve()
|
|
13
|
+
.then(() => probeHelp(command))
|
|
14
|
+
.then((helpText) => String(helpText || "").includes("--embed-resources")
|
|
15
|
+
? "--embed-resources"
|
|
16
|
+
: "--self-contained");
|
|
17
|
+
cache.set(command, cached);
|
|
18
|
+
void cached.catch(() => {
|
|
19
|
+
if (cache.get(command) === cached) cache.delete(command);
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
return cached;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
return async function resolveStudioPandocHtmlResourceFlag(pandocCommand) {
|
|
26
|
+
try {
|
|
27
|
+
return await getResourceFlag(pandocCommand);
|
|
28
|
+
} catch {
|
|
29
|
+
// Old and current Pandoc versions accept --self-contained. The actual
|
|
30
|
+
// render can now succeed or report the executable's useful error.
|
|
31
|
+
return "--self-contained";
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
}
|