portable-agent-layer 0.26.1 → 0.27.1
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/assets/skills/consulting-report/SKILL.md +115 -0
- package/assets/skills/consulting-report/demo/content/current-state.md +33 -0
- package/assets/skills/consulting-report/demo/content/executive-summary.md +19 -0
- package/assets/skills/consulting-report/demo/content/report-data.ts +101 -0
- package/assets/skills/consulting-report/demo/diagrams/.gitkeep +0 -0
- package/assets/skills/consulting-report/template/README.md +28 -0
- package/assets/skills/consulting-report/template/content/executive-summary.md +19 -0
- package/assets/skills/consulting-report/template/content/report-data.ts +59 -0
- package/assets/skills/consulting-report/template/diagrams/.gitkeep +0 -0
- package/assets/skills/consulting-report/tools/generate-pdf.ts +508 -0
- package/assets/skills/consulting-report/tools/scaffold.ts +74 -0
- package/assets/skills/create-pdf/SKILL.md +33 -42
- package/assets/skills/create-pdf/tools/md-to-html-pdf.ts +91 -0
- package/assets/skills/think/SKILL.md +70 -7
- package/package.json +4 -2
- package/src/cli/index.ts +43 -0
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: consulting-report
|
|
3
|
+
description: Produce branded consulting-report PDFs from a structured report directory (cover page, linked TOC, headers/footers with page numbers, typography system, callout boxes, findings + recommendations). Use when generating an assessment report, strategic review, or consulting deliverable PDF.
|
|
4
|
+
argument-hint: <report-dir> OR `scaffold <target-dir>` to start a new report
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Overview
|
|
8
|
+
|
|
9
|
+
Renders a structured consulting-report directory to a branded PDF: cover page, linked table of contents, page-numbered headers/footers, typography system (Georgia body + Inter headings), colored callout boxes for findings and recommendations, tables with zebra striping.
|
|
10
|
+
|
|
11
|
+
Each report lives in its own directory with data (TypeScript) + narrative (Markdown) + diagrams (images). The skill provides a scaffolder to spin up new reports from a template and a generator to render them.
|
|
12
|
+
|
|
13
|
+
**Default brand:** Konvert7. Override per report via the `brand` block in `report-data.ts`.
|
|
14
|
+
|
|
15
|
+
## Report Directory Layout
|
|
16
|
+
|
|
17
|
+
```
|
|
18
|
+
<report-dir>/
|
|
19
|
+
├── content/
|
|
20
|
+
│ ├── report-data.ts # report structure (schema: ConsultingReport)
|
|
21
|
+
│ ├── executive-summary.md # narrative sections
|
|
22
|
+
│ └── …
|
|
23
|
+
├── diagrams/ # source images (PNG/JPG)
|
|
24
|
+
├── diagrams-compressed/ # generated — ignore
|
|
25
|
+
└── <client>-<title>-<date>.{pdf,html} # output
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Workflow
|
|
29
|
+
|
|
30
|
+
### Step 1: Scaffold a new report (skip if the report directory already exists)
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
bun ~/.pal/skills/consulting-report/tools/scaffold.ts <target-dir> \
|
|
34
|
+
--client "Client Name" \
|
|
35
|
+
--title "Report Title"
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Creates the directory, stamps today's date + client + title into `report-data.ts`, and writes a starter `executive-summary.md`. If the target directory already exists, the command errors — move or remove first.
|
|
39
|
+
|
|
40
|
+
### Step 2: Fill in content
|
|
41
|
+
|
|
42
|
+
Edit:
|
|
43
|
+
|
|
44
|
+
- `<dir>/content/report-data.ts` — cover metadata, sections list, optional findings / recommendations / conclusion / appendix. Each `section.content` is either an inline markdown string OR a `.md` filename relative to `content/`.
|
|
45
|
+
- `<dir>/content/*.md` — the narrative sections referenced from `report-data.ts`.
|
|
46
|
+
- `<dir>/diagrams/` — drop PNG/JPG images. Reference them from markdown with relative paths, e.g. ``.
|
|
47
|
+
|
|
48
|
+
### Step 3: Render
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
bun ~/.pal/skills/consulting-report/tools/generate-pdf.ts <report-dir>
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Output: `<dir>/<client-slug>-<title-slug>-<date>.pdf` and matching `.html`. Override with `--pdf <path>` / `--html <path>`.
|
|
55
|
+
|
|
56
|
+
The generator:
|
|
57
|
+
- Loads `content/report-data.ts` dynamically
|
|
58
|
+
- Compresses `diagrams/*` to JPEG 70% / 1200px via `sips` (macOS); silently skips if `sips` is absent
|
|
59
|
+
- Renders cover, auto-generated linked TOC, sections, findings, recommendations, conclusion, appendix
|
|
60
|
+
- Prints via Playwright with page-numbered header/footer templates
|
|
61
|
+
|
|
62
|
+
### Step 4: Verify
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
ls -lh <dir>/*.pdf
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Open the PDF. Check: cover centered and branded; TOC links jump; findings render in red/amber boxes by severity; recommendations in blue boxes with priority badges; every page has the CONFIDENTIAL footer and page number.
|
|
69
|
+
|
|
70
|
+
## Report Schema
|
|
71
|
+
|
|
72
|
+
```ts
|
|
73
|
+
interface ConsultingReport {
|
|
74
|
+
clientName: string;
|
|
75
|
+
reportTitle: string;
|
|
76
|
+
reportDate: string;
|
|
77
|
+
classification: string; // e.g., "CONFIDENTIAL"
|
|
78
|
+
version: string;
|
|
79
|
+
brand?: { businessName: string; brandLabel?: string; logoPath?: string; };
|
|
80
|
+
sections: Section[];
|
|
81
|
+
findings?: Finding[]; // renders as red/amber/blue boxes by severity
|
|
82
|
+
recommendations?: Recommendation[]; // blue boxes with priority badges
|
|
83
|
+
conclusion?: Conclusion;
|
|
84
|
+
supportingEvidence?: Record<string, string[]>; // appendix
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
interface Section { id: string; title: string; content: string; subsections?: Section[]; }
|
|
88
|
+
interface Finding { id: string; title: string; severity: "critical"|"high"|"medium"|"low"; evidence: string; impact?: string; }
|
|
89
|
+
interface Recommendation { id: string; title: string; priority: "immediate"|"short-term"|"long-term"; detail: string; owner?: string; }
|
|
90
|
+
interface Conclusion { assessorNote?: string; contextNote?: string; closingRemarks?: string; }
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## Styling
|
|
94
|
+
|
|
95
|
+
The typography system (Georgia body 10.5pt / Inter headings), color palette (navy #1B2A4A, blue #2E5090, red #DC2626, amber #D97706, green #059669), callout boxes, badges, table styling, cover layout, and header/footer templates are baked into `tools/generate-pdf.ts`. To customize: edit the `css()` function and the `renderPdf()` header/footer strings in one place.
|
|
96
|
+
|
|
97
|
+
Do NOT combine CSS `@page` margin-box rules with the Playwright `displayHeaderFooter` templates — they duplicate.
|
|
98
|
+
|
|
99
|
+
## Demo
|
|
100
|
+
|
|
101
|
+
A runnable demo lives at `~/.pal/skills/consulting-report/demo/`:
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
bun ~/.pal/skills/consulting-report/tools/generate-pdf.ts ~/.pal/skills/consulting-report/demo
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
Inspect the produced PDF to see the full layout (cover, TOC, sections, findings, recommendations, conclusion, appendix) before writing your own report.
|
|
108
|
+
|
|
109
|
+
## Important
|
|
110
|
+
|
|
111
|
+
- Reports live wherever you want; the skill only needs the `<report-dir>` path
|
|
112
|
+
- The scaffolder refuses to overwrite an existing directory
|
|
113
|
+
- Images go in `diagrams/`; reference them from markdown via `diagrams-compressed/<name>.jpg` so the compressed output is used
|
|
114
|
+
- Heading anchor IDs come from `section.id` — keep them unique and slug-safe
|
|
115
|
+
- Every report re-renders deterministically from source; the PDF and HTML are disposable artifacts
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
## Production Deploy Pipeline
|
|
2
|
+
|
|
3
|
+
The current pipeline is a linear GitHub Actions workflow: PR → staging → canary → production. There are health checks at each stage, and SLO-based gates block on red. What's missing is a rollback step: once traffic is shifted to a new version, reverting requires a manual re-deploy of the previous image, which in 4 out of the last 12 incidents required direct database work because schema migrations had already run.
|
|
4
|
+
|
|
5
|
+
| Stage | Automated | Gate | Rollback |
|
|
6
|
+
|-------|-----------|------|----------|
|
|
7
|
+
| PR checks | Yes | Unit + integration tests | N/A |
|
|
8
|
+
| Staging deploy | Yes | Smoke tests | One-click |
|
|
9
|
+
| Canary (10%) | Yes | SLO compare 15m | Automatic |
|
|
10
|
+
| Production | Yes | Manual approve | **Manual, untested** |
|
|
11
|
+
|
|
12
|
+
> The "Manual, untested" cell is the single largest finding in this report.
|
|
13
|
+
|
|
14
|
+
## On-Call Practice
|
|
15
|
+
|
|
16
|
+
The team runs a weekly rotation. In practice, three engineers cover most of the load:
|
|
17
|
+
|
|
18
|
+
- Engineer A — 28% of minutes
|
|
19
|
+
- Engineer B — 24%
|
|
20
|
+
- Engineer C — 19%
|
|
21
|
+
- Remaining 8 engineers split the other 29%
|
|
22
|
+
|
|
23
|
+
The organization's own runbook requires a shadow-rotation before any solo shift. In the last two quarters, zero new engineers completed it.
|
|
24
|
+
|
|
25
|
+
## Runbook Inventory
|
|
26
|
+
|
|
27
|
+
Of 14 tier-1 services:
|
|
28
|
+
|
|
29
|
+
- **Fresh** (reviewed within 6 months): 5
|
|
30
|
+
- **Aging** (6–18 months): 2
|
|
31
|
+
- **Stale** (18+ months): 7
|
|
32
|
+
|
|
33
|
+
Three of the stale services have been re-architected since their last runbook update.
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
## Context
|
|
2
|
+
|
|
3
|
+
Acme Industries asked for an independent read on whether their engineering operations are ready to support the 3× revenue growth planned over the next 18 months. The assessment ran for six weeks and covered tier-1 production services, on-call practice, and incident response.
|
|
4
|
+
|
|
5
|
+
## Key Findings
|
|
6
|
+
|
|
7
|
+
- Production deploys lack a tested rollback path — the single largest operational risk.
|
|
8
|
+
- Runbooks are stale across half of tier-1 services.
|
|
9
|
+
- On-call coverage is concentrated in three engineers; knowledge has not diffused.
|
|
10
|
+
|
|
11
|
+
## Primary Recommendations
|
|
12
|
+
|
|
13
|
+
1. Add a rollback gate to the deploy pipeline within four weeks.
|
|
14
|
+
2. Refresh all tier-1 runbooks in a dedicated Q3 sprint.
|
|
15
|
+
3. Broaden the on-call roster from three to eight engineers over the next six months.
|
|
16
|
+
|
|
17
|
+
## Scope & Method
|
|
18
|
+
|
|
19
|
+
In scope: engineering operations — deploy, on-call, incident response, service ownership. Out of scope: product, sales, finance processes, though they surfaced repeatedly. Five semi-structured interviews; 12 incident post-mortems reviewed; 90 days of on-call coverage logs analyzed.
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import type { ConsultingReport } from "../../tools/generate-pdf";
|
|
2
|
+
|
|
3
|
+
const report: ConsultingReport = {
|
|
4
|
+
clientName: "Acme Industries",
|
|
5
|
+
reportTitle: "Operational Readiness Assessment",
|
|
6
|
+
reportDate: "2026-04-21",
|
|
7
|
+
classification: "CONFIDENTIAL",
|
|
8
|
+
version: "1.0",
|
|
9
|
+
|
|
10
|
+
// No brand block — uses the Konvert7 default.
|
|
11
|
+
|
|
12
|
+
sections: [
|
|
13
|
+
{
|
|
14
|
+
id: "executive-summary",
|
|
15
|
+
title: "Executive Summary",
|
|
16
|
+
content: "executive-summary.md",
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
id: "current-state",
|
|
20
|
+
title: "Current State",
|
|
21
|
+
content: "current-state.md",
|
|
22
|
+
},
|
|
23
|
+
],
|
|
24
|
+
|
|
25
|
+
findings: [
|
|
26
|
+
{
|
|
27
|
+
id: "f-01",
|
|
28
|
+
title: "Release pipeline lacks a rollback path",
|
|
29
|
+
severity: "critical",
|
|
30
|
+
evidence:
|
|
31
|
+
"Production deploys are one-way: the pipeline lacks a tested rollback step. Of the last 12 incidents, 4 required manual database surgery because the deploy couldn't be reverted.",
|
|
32
|
+
impact:
|
|
33
|
+
"Mean time to recovery is 3× peer benchmarks, and engineers report avoiding late-week deploys — slowing feature delivery.",
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
id: "f-02",
|
|
37
|
+
title: "Runbooks are out of date across half the critical services",
|
|
38
|
+
severity: "high",
|
|
39
|
+
evidence:
|
|
40
|
+
"7 of 14 tier-1 services have runbooks last updated more than 18 months ago. Three of those services have been re-architected since.",
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
id: "f-03",
|
|
44
|
+
title: "On-call rotation is concentrated in three engineers",
|
|
45
|
+
severity: "medium",
|
|
46
|
+
evidence:
|
|
47
|
+
"Over the last quarter, three engineers covered 71% of the on-call minutes. The shadow-rotation system exists on paper but isn't enforced.",
|
|
48
|
+
},
|
|
49
|
+
],
|
|
50
|
+
|
|
51
|
+
recommendations: [
|
|
52
|
+
{
|
|
53
|
+
id: "r-01",
|
|
54
|
+
title: "Add a tested rollback gate to the deploy pipeline",
|
|
55
|
+
priority: "immediate",
|
|
56
|
+
detail:
|
|
57
|
+
"Before any production deploy, require a successful rollback dry-run in staging. Block the pipeline on red. Target: implemented within 4 weeks; validated monthly via chaos day.",
|
|
58
|
+
owner: "Platform team",
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
id: "r-02",
|
|
62
|
+
title: "Runbook refresh sprint",
|
|
63
|
+
priority: "short-term",
|
|
64
|
+
detail:
|
|
65
|
+
"Allocate one sprint in Q3 to refresh all tier-1 runbooks. Each owner writes a 10-minute 'what wakes me up at 3am' paragraph. Review as pair exercise with oncall.",
|
|
66
|
+
owner: "Service owners + SRE",
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
id: "r-03",
|
|
70
|
+
title: "Broaden on-call to 8 engineers within 6 months",
|
|
71
|
+
priority: "long-term",
|
|
72
|
+
detail:
|
|
73
|
+
"Rotate 2 new engineers through a 4-week shadow period each quarter. Gate solo rotation on a resolved-incident checklist, not tenure.",
|
|
74
|
+
},
|
|
75
|
+
],
|
|
76
|
+
|
|
77
|
+
conclusion: {
|
|
78
|
+
assessorNote:
|
|
79
|
+
"The team is competent and well-intentioned; the gaps are process, not ability. The critical finding around rollback is the single highest-leverage fix available.",
|
|
80
|
+
contextNote:
|
|
81
|
+
"This assessment was scoped to engineering operations. Product, sales, and finance processes were out of scope but came up repeatedly in interviews as related bottlenecks.",
|
|
82
|
+
closingRemarks:
|
|
83
|
+
"A 30-day follow-up is recommended after the rollback gate lands to verify MTTR trend.",
|
|
84
|
+
},
|
|
85
|
+
|
|
86
|
+
supportingEvidence: {
|
|
87
|
+
Interviews: [
|
|
88
|
+
"Head of Platform — 45m",
|
|
89
|
+
"SRE Lead — 45m",
|
|
90
|
+
"Three senior engineers — 30m each",
|
|
91
|
+
"VP Engineering — 30m",
|
|
92
|
+
],
|
|
93
|
+
"Documents reviewed": [
|
|
94
|
+
"Q1 incident post-mortems (12)",
|
|
95
|
+
"On-call schedule & coverage logs (90 days)",
|
|
96
|
+
"Current runbook index",
|
|
97
|
+
],
|
|
98
|
+
},
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
export default report;
|
|
File without changes
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# Consulting Report — Working Directory
|
|
2
|
+
|
|
3
|
+
## Structure
|
|
4
|
+
|
|
5
|
+
- `content/report-data.ts` — report structure (cover metadata, sections, optional findings / recommendations / conclusion / appendix)
|
|
6
|
+
- `content/*.md` — narrative sections; reference them from `report-data.ts` by filename
|
|
7
|
+
- `diagrams/` — drop PNG/JPG images; they're compressed to JPEG 70% / max 1200px at render time
|
|
8
|
+
- `diagrams-compressed/` — generated; do not edit
|
|
9
|
+
|
|
10
|
+
## Render
|
|
11
|
+
|
|
12
|
+
```
|
|
13
|
+
bun ~/.pal/skills/consulting-report/tools/generate-pdf.ts .
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
Output goes into this directory as `<client>-<title>-<date>.{pdf,html}` unless you pass `--pdf <path>` or `--html <path>`.
|
|
17
|
+
|
|
18
|
+
## Defaults
|
|
19
|
+
|
|
20
|
+
Without a `brand` block in `report-data.ts`, reports are stamped with **Konvert7** branding. Override per engagement by adding:
|
|
21
|
+
|
|
22
|
+
```ts
|
|
23
|
+
brand: {
|
|
24
|
+
businessName: "Your Brand",
|
|
25
|
+
logoPath: "/absolute/path/to/logo.png", // optional — text-only cover if omitted
|
|
26
|
+
brandLabel: "Strategic Assessment", // optional sub-label on cover
|
|
27
|
+
}
|
|
28
|
+
```
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
## Context
|
|
2
|
+
|
|
3
|
+
One-paragraph framing of the engagement: who the client is, what they asked for, what's at stake.
|
|
4
|
+
|
|
5
|
+
## Key Findings
|
|
6
|
+
|
|
7
|
+
- Finding one — punchy, evidenced, and actionable.
|
|
8
|
+
- Finding two.
|
|
9
|
+
- Finding three.
|
|
10
|
+
|
|
11
|
+
## Primary Recommendations
|
|
12
|
+
|
|
13
|
+
1. Recommendation one — what to do, by when, and what it unblocks.
|
|
14
|
+
2. Recommendation two.
|
|
15
|
+
3. Recommendation three.
|
|
16
|
+
|
|
17
|
+
## Scope & Method
|
|
18
|
+
|
|
19
|
+
Short note on what was reviewed, who was interviewed, what was explicitly out of scope.
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import type { ConsultingReport } from "{{TOOL_PATH}}";
|
|
2
|
+
|
|
3
|
+
const report: ConsultingReport = {
|
|
4
|
+
clientName: "{{CLIENT_NAME}}",
|
|
5
|
+
reportTitle: "{{REPORT_TITLE}}",
|
|
6
|
+
reportDate: "{{DATE}}",
|
|
7
|
+
classification: "CONFIDENTIAL",
|
|
8
|
+
version: "0.1",
|
|
9
|
+
|
|
10
|
+
// Brand is optional — defaults to Konvert7. Override per report if needed:
|
|
11
|
+
// brand: { businessName: "Konvert7", logoPath: "/absolute/path/to/logo.png", brandLabel: "Strategic Assessment" },
|
|
12
|
+
|
|
13
|
+
sections: [
|
|
14
|
+
{
|
|
15
|
+
id: "executive-summary",
|
|
16
|
+
title: "Executive Summary",
|
|
17
|
+
content: "executive-summary.md",
|
|
18
|
+
},
|
|
19
|
+
// Add sections — each `content` is either an inline markdown string OR a
|
|
20
|
+
// .md filename relative to this content/ directory.
|
|
21
|
+
],
|
|
22
|
+
|
|
23
|
+
// Optional. Delete the block if unused.
|
|
24
|
+
findings: [
|
|
25
|
+
// {
|
|
26
|
+
// id: "f-01",
|
|
27
|
+
// title: "Example critical finding",
|
|
28
|
+
// severity: "critical",
|
|
29
|
+
// evidence: "What was observed, with specifics.",
|
|
30
|
+
// impact: "Why it matters.",
|
|
31
|
+
// },
|
|
32
|
+
],
|
|
33
|
+
|
|
34
|
+
// Optional.
|
|
35
|
+
recommendations: [
|
|
36
|
+
// {
|
|
37
|
+
// id: "r-01",
|
|
38
|
+
// title: "Example recommendation",
|
|
39
|
+
// priority: "immediate",
|
|
40
|
+
// detail: "What to do, by when, and why.",
|
|
41
|
+
// owner: "Team or person",
|
|
42
|
+
// },
|
|
43
|
+
],
|
|
44
|
+
|
|
45
|
+
// Optional.
|
|
46
|
+
conclusion: {
|
|
47
|
+
// assessorNote: "Personal assessor voice.",
|
|
48
|
+
// contextNote: "Situational context the reader needs.",
|
|
49
|
+
// closingRemarks: "Where to go next.",
|
|
50
|
+
},
|
|
51
|
+
|
|
52
|
+
// Optional. Appendix — keyed by heading, each value is a list of bullets.
|
|
53
|
+
// supportingEvidence: {
|
|
54
|
+
// "Interviews": ["Person A — 45m", "Person B — 30m"],
|
|
55
|
+
// "Documents reviewed": ["doc-1.pdf", "doc-2.md"],
|
|
56
|
+
// },
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
export default report;
|
|
File without changes
|