feat(static): implement static file copy and passthrough#6
Merged
Conversation
Implement CopyStatic, CopyPassthrough, and CopyPassthroughWithValidation to replace stubs. CopyStatic walks the static directory and copies all files to the output root, gracefully handling missing or empty directories. CopyPassthrough copies files from external directories according to passthrough mappings. CopyPassthroughWithValidation adds overlap protection by silently skipping managed directories. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
zeroedin
commented
Apr 12, 2026
zeroedin
left a comment
Owner
Author
There was a problem hiding this comment.
Code Review: feat(static): implement static file copy and passthrough
Clean implementation of a leaf package. 8/8 tests pass, go vet clean. The code is straightforward and correct for the test suite's expectations. A few spec compliance gaps to address.
Summary
| Area | Verdict |
|---|---|
CopyStatic |
✅ Correct — walks, copies, handles missing/empty dirs gracefully |
CopyPassthrough |
projectRoot param — paths not resolved per spec |
CopyPassthroughWithValidation |
|
copyFile |
|
| Test fixtures | ✅ Good — .gitignore in output dir, .gitkeep for empty dirs |
| Test output cleanup |
See inline comments for details.
zeroedin
commented
Apr 12, 2026
zeroedin
commented
Apr 12, 2026
zeroedin
commented
Apr 12, 2026
zeroedin
commented
Apr 12, 2026
- Resolve From paths relative to projectRoot per §1h spec - Make managed directory matching resolve to absolute paths and catch subdirectory overlap (content/blog inside content) - Preserve source file permissions in copyFile using os.OpenFile - Adjust testdata layout so From paths resolve correctly via projectRoot Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
zeroedin
added a commit
that referenced
this pull request
Apr 25, 2026
Reviewer items: - Use MarkdownOptions.Hooks field instead of separate function (#1) - Tests use []byte(input) matching RenderMarkdown signature (#2) - Heading ID uses slugify: "My Section" → "my-section" (#3) - Protocol-relative URLs intentionally not external for v1 (#4) - Render hooks follow engine choice (Liquid vs Go templates) (#5) - Add blockquote and table tests (#6) Copilot items: - Clarify Alloy registers renderers, not goldmark auto-detecting - Add template tag escaping note for custom hook output structures Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This was referenced May 6, 2026
zeroedin
added a commit
that referenced
this pull request
May 6, 2026
…ack guards - #1 P1: matchPageGlob handles zero-segment ** match (e.g. /blog/**/index matches /blog/index) - #4 P2: data/pageFields use !== undefined instead of || null to preserve empty arrays - #5 P2: fireContentTransformedHooks writeback guarded by scope.WantsField checks - #6 P2: parseScopeJSON warns on non-string taxonomy term values - #9 P3: computeUnionScope has explicit PagesScopeNone case with comment Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This was referenced May 7, 2026
This was referenced May 15, 2026
This was referenced Jun 22, 2026
zeroedin
added a commit
that referenced
this pull request
Jul 8, 2026
P0 #1: Fix feed.xml test — page blog/index.md generates candidate "index", not "feed". Changed to default.xml which is a valid candidate. P1 #2: Make explicit-name semantics consistent. Both ResolveLayout and ResolveLayoutWithCascade now expect errors for explicit layout names when .liquid is missing. Added missing test for front matter layout via ResolveLayoutWithCascade path. P1 #3: Add per-candidate ordering disambiguation test. post.html (higher- priority candidate bare-ext) must win over my-post.liquid (lower-priority candidate engine-ext). P1 #4: Clarify PLAN.md — no-fallback rule applies to page-level explicit names only; layout chain parent references follow automatic-candidate fallback. P2 #6: Add date-based section filename step bare-extension test (my-post.html when post.liquid/post.html/my-post.liquid all missing). P3 #9: Normalize "bare-ext" abbreviation to full form. Refs #827 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This was referenced Jul 8, 2026
This was referenced Jul 16, 2026
zeroedin
added a commit
that referenced
this pull request
Jul 16, 2026
- CR #1: Strengthen cache TTL assertion from HaveKey to HaveKeyWithValue("cache", 3600) - CR #6: Separate hook vs source timeout semantics in PLAN.md — hook timeouts discard modifications and continue; source timeouts return fetch errors that abort the build Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This was referenced Jul 16, 2026
zeroedin
added a commit
that referenced
this pull request
Jul 17, 2026
- P1 #1: LoadCache now propagates non-IsNotExist I/O errors instead of swallowing them (matches docstring contract) - P1 #2: Response body capped at 1 MB via io.LimitReader to prevent unbounded memory allocation from malicious/corrupted responses - P2 #3: Version printed once in --check up-to-date case (was printing twice); error/update-available cases print version first then status - P2 #4: CacheDir falls back to os.TempDir() instead of relative path when os.UserHomeDir() fails - P2 #5: SaveCache errors printed as warning to stderr instead of silently discarded - P3 #6: User-Agent header set on GitHub API requests Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This was referenced Jul 17, 2026
zeroedin
added a commit
that referenced
this pull request
Jul 24, 2026
P1 #1: Fix duplicate step 19 in PLAN.md pipeline stages — renumber steps 20-25 after inserting onFormatRendered at step 19. Update hook table step numbers (onAssetProcess 22+, onBuildComplete 25). P1 #2: Add content mutation write-back assertion to single non-HTML page test — verifies page.SetRenderedBody path is wired, not just FormatBodies. P2 #3: Fix test count 12 → 14 in IMPLEMENTATION.md (was 13, now 14 with new test). P2 #4: Add test for HTML in non-first position of outputs array (outputs: ["json", "html"]) — catches page.Outputs[0] == "html" implementations. P2 #5: Add second plugin to read-only fields test that verifies frontMatter immutability end-to-end — throws if first plugin's frontMatter mutation was applied back. P3 #6: Add BuildIncremental parity note for onFormatRendered in both PLAN.md and IMPLEMENTATION.md. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This was referenced Jul 24, 2026
Merged
zeroedin
added a commit
that referenced
this pull request
Jul 25, 2026
- P1 #6: Updated summary table (Phase 5: ~129, cumulative downstream) - P2 #1: Added multi-byte character table entry (CJK, emoji) — validates X-Body-Length is byte count not rune count - P2 #7: Added \r\n suffix to X-Body-Length assertion to prevent decimal-prefix false match (50 matching 500) - P3 #2: Use parsed headers map from parseSplitFrame, assert header value matches actual raw body byte count - P3 #3: Added empty split field test — falls back to single-header - P3 #4: Added dual-key map priority test — html over content - P3 #5: Added caller map immutability guard test 12 total tests (was 8). Test counts updated in IMPLEMENTATION.md (section header, node.go description, impl guidance, summary table). PLAN.md updated with empty-field fallback, dual-key priority, and map immutability constraints. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
zeroedin
added a commit
that referenced
this pull request
Jul 25, 2026
- P0 #1: Update bridge.js inbound parser to handle split-body frames (X-Body-Length/X-Body-Field headers) and outbound sendMessage to produce split-body frames for hook results with html/content fields - P0 #2-3: Add bounds and negative-value validation on Content-Length and X-Body-Length in both DecodeMessage and Send before slicing or allocating - P1 #4: Require X-Body-Field header when X-Body-Length is present; error on empty field name - P1 #5: Restore stdout pollution detection — first header line in Send must start with "Content-Length:", rejecting "debug: ..." lines - P1 #6: Switch stripField to JSON round-trip (marshal struct → unmarshal to map → delete key) per IMPLEMENTATION.md spec, so new struct fields are automatically included - P1 #7: DecodeMessage split-body injection prefers Result map, falls back to Payload map when Result is nil, per spec - P2 #8: Use len(fieldValue) directly in EncodeMessage instead of allocating []byte(fieldValue) copy for byte-length measurement Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This was referenced Jul 25, 2026
zeroedin
added a commit
that referenced
this pull request
Jul 25, 2026
P2 #1: Hoist setupQuickJSWithHook to outer Describe scope, remove duplicate setupQuickJSWithHookFor1186. Both #1180 and #1186 sections now share the same helper. P2 #2: Extract checkGlobalIsFunction closure — three existence tests are now one-liners calling the shared helper. P2 #3: Add *qjs.Value lifetime note to IMPLEMENTATION.md — stored function references must be Free()d in Close() before context teardown. P2 #4: Add lazy FM test for HookFormatRenderedPayload (onFormatRendered) to verify setPayloadFrontMatter is wired consistently across all three payload types. P2 #9 (addendum): Fix null sentinel collision in __installLazyFM and __installLazyTOC JS snippets — use unique sentinel object instead of null so page.frontMatter = null sticks. Add corresponding test. P3 #5: Add configurable: true test for lazy frontMatter property. P3 #6: Add lazy TOC setter test for parity with frontMatter setter. P3 #7: Add no-globals disambiguation test — verifies invokeHookFastPath uses ctx.Invoke (no __callInput/__callHookName globals) vs ctx.Eval. Test count: 9 → 14 (7 RED, 7 GREEN). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
zeroedin
added a commit
that referenced
this pull request
Jul 25, 2026
- P1 #1: Fix hook chain misrouting onContentTransformed payloads — check for toc key alongside html to disambiguate payloadTransform vs payloadRendered, preventing silent TOC data loss in multi-hook chains - P1 #2: Log marshal errors in lazy __resolveFM/__resolveTOC callbacks instead of silently returning empty object/undefined - P2 #3: Use NewFloat64 for int values in callHookMapPayload to avoid int32 narrowing truncation on timestamps and large counts - P2 #4: Wire up SetRenderedHTML at 3 hook apply-back call sites in hooks.go (onContentTransformed html/string, onPageRendered html) - P2 #5: Log warning on marshal failure in callHookMapPayload default case instead of silent continue - P2 #6: Document thread-safety assumption on convertedFrontMatter in-place mutation Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6 tasks
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
CopyStaticto walk and copy all files fromstatic/to output root, gracefully handling missing or empty directoriesCopyPassthroughto copy files from external directories according to passthrough mappings, erroring on missing source pathsCopyPassthroughWithValidationto add overlap protection by silently skipping managed directories (content, layouts, assets, static, data)Test plan
go test ./internal/static/ -v)CopyStatichandles empty/missing dirs without errorCopyPassthrougherrors on nonexistentFrompathsCopyPassthroughWithValidationsilently ignores managed directories🤖 Generated with Claude Code