portable-agent-layer 0.55.2 → 0.57.0
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.
|
@@ -76,9 +76,19 @@ Report the file path and size to the user.
|
|
|
76
76
|
|
|
77
77
|
## Styling
|
|
78
78
|
|
|
79
|
-
Default styling (A4, 25mm margins, GitHub-ish look, table-friendly, page-break-aware headings) is baked into the tool.
|
|
79
|
+
Default styling (A4, 25mm margins, GitHub-ish look, table-friendly, page-break-aware headings) is baked into the tool. Margins and header/footer are configurable per-render via flags — no source edits needed:
|
|
80
80
|
|
|
81
|
-
|
|
81
|
+
- `--margin <css>` — page margin on all four sides (default `25mm`). E.g. `--margin 12mm` for a denser one-pager.
|
|
82
|
+
- `--header <html|file>` / `--footer <html|file>` — running header/footer on every page. The value is either an inline HTML string or a path to an HTML file. Templates may use Playwright's injected classes: `pageNumber`, `totalPages`, `date`, `title`, `url`.
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
node --experimental-strip-types ~/.pal/skills/create-pdf/tools/md-to-html-pdf.ts report.md --pdf report.pdf \
|
|
86
|
+
--margin 18mm \
|
|
87
|
+
--header '<div style="font-size:9px;width:100%;text-align:center;color:#888">CONFIDENTIAL</div>' \
|
|
88
|
+
--footer '<div style="font-size:9px;width:100%;text-align:right;padding-right:12mm;color:#888"><span class="pageNumber"></span>/<span class="totalPages"></span></div>'
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
Header/footer templates **need an explicit `font-size`** (Playwright defaults them to 0) and render *inside* the page margin — widen `--margin` so they have room. Do NOT also add CSS `@page` margin-box rules; they duplicate. For deeper changes (fonts, base CSS), edit the `css` string in `tools/md-to-html-pdf.ts`.
|
|
82
92
|
|
|
83
93
|
## Translation Variant
|
|
84
94
|
|
|
@@ -7,7 +7,9 @@
|
|
|
7
7
|
// pipe handling doesn't complete the CDP handshake.
|
|
8
8
|
//
|
|
9
9
|
// Usage:
|
|
10
|
-
// node --experimental-strip-types ~/.pal/skills/create-pdf/tools/md-to-html-pdf.ts <input.md>
|
|
10
|
+
// node --experimental-strip-types ~/.pal/skills/create-pdf/tools/md-to-html-pdf.ts <input.md> \
|
|
11
|
+
// [--html <out.html>] [--pdf <out.pdf>] [--margin <css>] [--header <html|file>] [--footer <html|file>]
|
|
12
|
+
// --margin defaults to 25mm (all sides). --header/--footer accept inline HTML or a file path.
|
|
11
13
|
|
|
12
14
|
import { readFile, stat, writeFile } from "node:fs/promises";
|
|
13
15
|
import { basename, dirname, extname, resolve } from "node:path";
|
|
@@ -17,21 +19,44 @@ import { chromium } from "playwright";
|
|
|
17
19
|
|
|
18
20
|
const args = process.argv.slice(2);
|
|
19
21
|
if (args.length === 0) {
|
|
20
|
-
console.error(
|
|
22
|
+
console.error(
|
|
23
|
+
"usage: md-to-html-pdf.ts <input.md> [--html <out>] [--pdf <out>] [--margin <css>] [--header <html|file>] [--footer <html|file>]"
|
|
24
|
+
);
|
|
21
25
|
process.exit(1);
|
|
22
26
|
}
|
|
23
27
|
|
|
24
28
|
const input = resolve(args[0]);
|
|
25
29
|
let htmlOut = "";
|
|
26
30
|
let pdfOut = "";
|
|
31
|
+
let margin = "25mm";
|
|
32
|
+
let headerArg = "";
|
|
33
|
+
let footerArg = "";
|
|
27
34
|
for (let i = 1; i < args.length; i++) {
|
|
28
35
|
if (args[i] === "--html") htmlOut = resolve(args[++i]);
|
|
29
36
|
else if (args[i] === "--pdf") pdfOut = resolve(args[++i]);
|
|
37
|
+
else if (args[i] === "--margin") margin = args[++i];
|
|
38
|
+
else if (args[i] === "--header") headerArg = args[++i];
|
|
39
|
+
else if (args[i] === "--footer") footerArg = args[++i];
|
|
30
40
|
}
|
|
31
41
|
const stem = basename(input, extname(input));
|
|
32
42
|
const dir = dirname(input);
|
|
33
|
-
htmlOut
|
|
34
|
-
pdfOut
|
|
43
|
+
htmlOut ||= resolve(dir, `${stem}.html`);
|
|
44
|
+
pdfOut ||= resolve(dir, `${stem}.pdf`);
|
|
45
|
+
|
|
46
|
+
// --header/--footer take inline HTML or a path to an HTML file. Playwright renders
|
|
47
|
+
// them inside the page margin, so widen --margin when you use them. Templates may use
|
|
48
|
+
// Playwright's injected classes: pageNumber, totalPages, date, title, url.
|
|
49
|
+
async function resolveTemplate(value: string): Promise<string> {
|
|
50
|
+
if (!value) return "";
|
|
51
|
+
try {
|
|
52
|
+
return await readFile(resolve(value), "utf8");
|
|
53
|
+
} catch {
|
|
54
|
+
return value;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
const headerTemplate = await resolveTemplate(headerArg);
|
|
58
|
+
const footerTemplate = await resolveTemplate(footerArg);
|
|
59
|
+
const displayHeaderFooter = Boolean(headerTemplate || footerTemplate);
|
|
35
60
|
|
|
36
61
|
const md = await readFile(input, "utf8");
|
|
37
62
|
marked.setOptions({ gfm: true, breaks: false });
|
|
@@ -83,9 +108,12 @@ try {
|
|
|
83
108
|
await page.pdf({
|
|
84
109
|
path: pdfOut,
|
|
85
110
|
format: "A4",
|
|
86
|
-
margin: { top:
|
|
111
|
+
margin: { top: margin, right: margin, bottom: margin, left: margin },
|
|
87
112
|
printBackground: true,
|
|
88
113
|
preferCSSPageSize: false,
|
|
114
|
+
displayHeaderFooter,
|
|
115
|
+
headerTemplate: headerTemplate || "<span></span>",
|
|
116
|
+
footerTemplate: footerTemplate || "<span></span>",
|
|
89
117
|
});
|
|
90
118
|
} finally {
|
|
91
119
|
await browser.close();
|
|
@@ -180,6 +180,15 @@ No criterion may rest on an unverified premise. If a premise can't be verified n
|
|
|
180
180
|
|
|
181
181
|
Output: `🧭 GROUNDING: [premises verified, or assumptions flagged]`
|
|
182
182
|
|
|
183
|
+
**Blast-radius & prior-art recon — for shared-code or multi-file changes.**
|
|
184
|
+
|
|
185
|
+
Before changing a shared symbol, prop, or signature — or building a feature that may already partially exist:
|
|
186
|
+
- **Grep every consumer/reference FIRST**, here in PLAN, not reactively via type-check in EXECUTE. A prop or signature change is a tracing task before it is an edit.
|
|
187
|
+
- **Check what already exists** before writing new infrastructure — reuse beats rebuild. "Does this already partially exist?" is the cheapest scope error to catch.
|
|
188
|
+
- **"Broken after rename"** → trace what external systems reference the old name (configs, imports, generated files, docs).
|
|
189
|
+
|
|
190
|
+
Output: `🗺️ BLAST RADIUS: [consumers traced + prior art found, or "N/A — isolated change"]`
|
|
191
|
+
|
|
183
192
|
### ━━━ ⚡ EXECUTE ━━━ 3/5
|
|
184
193
|
|
|
185
194
|
Do the work. Invoke selected capabilities via tool calls.
|
|
@@ -363,6 +372,7 @@ Only write if the insight is **genuine and reusable** — not every session prod
|
|
|
363
372
|
🧠 RISKS: [risks]
|
|
364
373
|
🧠 PREMORTEM: [failure modes]
|
|
365
374
|
🧭 GROUNDING: [premises verified, or assumptions flagged]
|
|
375
|
+
🗺️ BLAST RADIUS: [consumers traced + prior art found, or N/A]
|
|
366
376
|
📐 APPROACH: [execution plan]
|
|
367
377
|
|
|
368
378
|
━━━ ⚡ EXECUTE ━━━ 3/5
|