Add VS Code command to generate sprint report PDFs - #97
Merged
Merged
Conversation
Second half of the sprint-report feature (add-sprint-report-pdf, PR #96, shipped the standalone-only half). New Command Palette command "OpenSpec UI: Generate Sprint Report (PDF)": reuses pickChangesForTimeline unchanged, adds two validated YYYY-MM-DD date prompts (VS Code has no native date picker, and this needs a real user-specified range, not an auto-derived one), calls buildSprintReport/renderSprintReportPdf from @openspec-ui/core directly (per ADR-0001 -- no server/REST round-trip), then showSaveDialog -> workspace.fs.writeFile -> a confirmation message with an "Open" action. This is also the first code path that actually executes renderSprintReportPdf from inside the bundled extension -- which re-exposed the pdfkit/esbuild bundling hazard PR #96's CI caught (esbuild's CJS bundle can't shim pdfkit's ESM build's import.meta.url). The createRequire-based workaround from that PR fixed activation but silently stopped esbuild from inlining pdfkit at all (a local variable named `require`, however constructed, isn't recognized as a bundleable require once esbuild renames it during bundling -- confirmed by inspecting the built dist/extension.js, which dropped from 2.8MB to 635KB and left a real runtime `require("pdfkit")` call). Since `vsce package --no-dependencies` ships no node_modules, that would have failed at runtime with "Cannot find module 'pdfkit'" the first time this command actually ran. Reverted sprint-report-pdf.ts to a plain `import PDFDocument from "pdfkit"` (correct as-is for every plain-Node/ESM consumer -- server, core's own tests) and instead fixed the extension-only bundling problem in the extension's own esbuild config: an `alias` mapping "pdfkit" to its real CommonJS build file at bundle time (build-options.mjs), which genuinely inlines it and reads __filename instead of import.meta.url. Verified: rebuilt dist/extension.js and loaded it in plain Node with a stubbed vscode module -- activation succeeds, and the bundle contains pdfkit's real CommonJS build inline (grep for ICC_PROFILE_PATH's pathToFileURL(__filename) form, not import_meta2.url). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
add-sprint-report-pdf, PR Add sprint summary PDF report (standalone) #96, shipped the standalone-only half). New Command Palette command "OpenSpec UI: Generate Sprint Report (PDF)": reusespickChangesForTimelineunchanged, prompts for a validatedYYYY-MM-DDstart/end date (no native VS Code date picker; this command needs a real user-specified range, unlike the comparison timeline's auto-derived one), callsbuildSprintReport/renderSprintReportPdffrom@openspec-ui/coredirectly (per ADR-0001 — no server/REST round-trip), thenshowSaveDialog->workspace.fs.writeFile-> a confirmation message offering to open the PDF.renderSprintReportPdffrom inside the bundled extension. That re-exposed thepdfkit/esbuild bundling hazard PR Add sprint summary PDF report (standalone) #96's CI caught — thecreateRequire-based workaround from that PR fixed extension activation, but silently stopped esbuild from inliningpdfkitinto the bundle at all (confirmed:dist/extension.jsdropped from 2.8MB to 635KB and left a real runtimerequire("pdfkit")call). Sincevsce package --no-dependenciesships nonode_modules, the command would have failed at runtime with "Cannot find module 'pdfkit'" the first time a real user ran it.sprint-report-pdf.tsto a plainimport PDFDocument from "pdfkit"(correct as-is for every plain-Node/ESM consumer — server, core's own tests) and instead fixed the bundling problem where it actually lives — the extension's own esbuild config — via analiasmapping"pdfkit"to its real CommonJS build file at bundle time (build-options.mjs), which genuinely inlines it and reads__filenameinstead ofimport.meta.url.Verification
Rebuilt
dist/extension.jsand loaded it in plain Node with a stubbedvscodemodule: activation succeeds, and the bundle contains pdfkit's real CommonJS build inline (confirmed viaICC_PROFILE_PATH'spathToFileURL(__filename)form, not the brokenimport_meta2.urlform from before the fix).Test plan
commands.test.tsforgenerateSprintReport: builds+saves+offers to open the PDF; no-op when no changes picked; no-op when either date prompt is dismissed; date validator rejects malformed input; no file written when the save dialog is dismissed; PDF not opened when the confirmation is dismissed; error surfaced when report generation failsshowSaveDialog/workspace.fs.writeFile/env.openExternalstubs added totest-utils/vscode-mock.tsnpm run typecheck,npm run lint(includinglint:english),npm run testworkspace-widedist/extension.jsand verified real pdfkit-CJS inlining + successful activation in plain Node (see above)openspec change validate --strict add-sprint-report-vscode-command🤖 Generated with Claude Code