fix(create-chapter): rebrand file names + xlsx inline strings; render via Slides API not LibreOffice - #13
Merged
Merged
Conversation
… via Slides API not LibreOffice The rebrand engine only rewrote OOXML part *content*, so cloned chapter files kept the source city in their names (e.g. "San Francisco CRM.xlsx"), and cells stored as xlsx inline strings (not sharedStrings.xml entries) - like the CRM Guide sheet's title - were left untouched. Both are now covered, verified via a real throwaway chapter clone before/after this fix. Also replace the LibreOffice-based pptx-to-PNG export used by aaif-create-chapter (map-dot recalibration) and aaif-create-event (Luma cover export): soffice substitutes local system fonts for the deck's brand fonts, silently producing wrong-looking renders. lib/aaif_events/slides_export.py renders via the Slides API on a throwaway Slides copy instead, matching the toolkit's existing gws-wrapper retry/error-handling conventions. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Collaborator
Author
Self-ReviewCritical (1)
Important (5)
Suggestions (4)
Strengths
Generated using hero-skills. |
- Fix misleading test (test_unmatched_worksheet_number_pattern_is_untouched): it passed for the wrong reason (routed through the .rels branch, not the intended untouched fallback). Renamed/re-commented accurately and added a genuine falls-through-untouched test. - slides_export.py: cleanup failures are now logged (stderr) instead of silently swallowed; the copy call is inside the try/finally so a failure right after the copy still attempts cleanup; _gws's exhausted-retries error now includes which gws subcommand failed; corrected the "harmless clutter" comment to state the real risk (a stray copy lands next to the source file, which matters if this is ever run against TemplateCity). - Added test coverage: lib/aaif_events/tests/test_slides_export.py (retry/ backoff, empty/non-JSON output guards, cleanup-runs-even-on-error, cleanup failure doesn't mask the original exception) and TestTransformText in test_create_chapter.py (transform_text on filename-shaped strings, which had no direct coverage before). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Collaborator
Author
Self-Review — ImprovementsCritical (1 / 1 fixed):
Important (5 / 5 fixed):
Suggestions (4 / 3 fixed):
Generated using hero-skills. |
rparundekar
marked this pull request as ready for review
July 22, 2026 04:56
8 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
Fixes two gaps in the chapter-cloning rebrand engine (file/folder names and xlsx inline-string cells were never rewritten) and replaces LibreOffice-based pptx→PNG exports with a Slides-API-based renderer, since LibreOffice silently substitutes local system fonts for the deck's brand fonts.
Changesets
1.
fix(create-chapter): rebrand file names + xlsx inline strings; render via Slides API not LibreOfficeFiles:
lib/aaif_events/slides_export.py(new),skills/aaif-create-chapter/scripts/create_chapter.py,skills/aaif-create-chapter/scripts/test_create_chapter.py,skills/aaif-create-chapter/SKILL.md,skills/aaif-create-event/SKILL.mdrebrand_part()only rewrote OOXML part content; cloned chapter files kept the source city in their own names (e.g. a cloned chapter's CRM stayed "San Francisco CRM.xlsx").clone_and_rebrand()now runs each file/folder name through the sametransform_text()used for content.<is><t>...</t></is>, used by e.g. the CRM's "Guide" sheet title) live inxl/worksheets/sheetN.xml, notxl/sharedStrings.xml— the only xlsx part type the engine previously handled. Added a matching branch reusing the existing_process_paragraphshelper.lib/aaif_events/slides_export.py: renders a Drive pptx slide to PNG via a throwaway Google Slides copy + the Slides API thumbnail endpoint, instead of a localsoffice --headless --convert-to png/pdfcall. LibreOffice substitutes local system fonts for the deck's actual brand fonts, producing exports that look wrong in ways the live file isn't. Follows the samegwsCLI wrapper conventions (retry-on-transient-error, empty/non-JSON-output guards) already used elsewhere in the toolkit.aaif-create-chapter's map-dot recalibration step,aaif-create-event's Luma cover export step) to use the new helper instead ofsoffice.2.
fix: address self-review findingsFiles:
lib/aaif_events/slides_export.py,lib/aaif_events/tests/test_slides_export.py(new),skills/aaif-create-chapter/scripts/test_create_chapter.py.relsbranch rather than the claimed untouched fallback); added a genuine falls-through-untouched test.slides_export.py: cleanup failures are now logged instead of silently swallowed; the copy call is inside thetry/finallyso a failure right after it still attempts cleanup; the exhausted-retries error now includes whichgwssubcommand failed; corrected a comment that understated the real risk of a failed cleanup (a stray copy can land next to the source file and get propagated if this is ever run againstTemplateCity).lib/aaif_events/tests/test_slides_export.py(11 tests covering retry/backoff, output-parsing guards, and the cleanup-on-error contract) andTestTransformTextintest_create_chapter.py(4 tests coveringtransform_text()on filename-shaped strings, which previously had no direct coverage).Test Plan
test_create_chapter.py— 34/34 passing (30 from changeset 1 + 4 newTestTransformText)lib/aaif_events/tests/— 66/66 passing (55 pre-existing + 11 new intest_slides_export.py)ruff check,pre-commit run --all-files— cleancreate_chapter.py, confirmed the CRM file name and Guide-sheet title were both correctly rebranded (previously showed the source city), then trashed the test chapterrender_slide_png()spot-checked against several real Drive files, including after the self-review refactor — correct fonts, no LibreOffice font-substitution artifactshero-skills:review-pr— 1 critical + 5 important + 4 suggestions found, 9 fixed, 3 explicitly deferred/skipped (see PR comments)Generated using hero-skills.