Render Word manifests from one template per environment - #595
Open
kcarnold wants to merge 1 commit into
Open
Conversation
Word has no equivalent of the Google Docs sidebar's runtime source picker: the task pane loads whatever origin SourceLocation names, so each deploy target needs its own manifest. Add a staging manifest for beta testers without duplicating the manifest three ways. The manifest was a checked-in dev file rewritten by regex at build time (`.replace(/-dev/g, '')` plus id/URL swaps). That transform had no spelling for a third environment, and it only rewrote strings someone remembered to write in the -dev form — CommandsGroup.Label was plain "Thoughtful", so the ribbon group looked identical in dev and prod. Replace it with manifest/template.xml (structure, once) plus manifest/environments.ts (the differences, once), rendered into dist/ by the existing Vite plugin. environments.test.ts asserts what the regex couldn't: distinct ids, no environment's manifest mentioning another's origin, and every URL built from that environment's base. Every build now emits all three manifests rather than choosing one by --mode. Which manifest you need depends on who is installing it, and the old coupling meant the image the Dockerfile builds carried a manifest naming the prod origin regardless of where it was deployed. Name the environments "Thoughtful", "Beta Thoughtful" and "Dev Thoughtful": the Add-ins menu truncates DisplayName to about ten characters, so a trailing marker is invisible exactly where you need it to tell a dev install from a real one. Prod's manifest is byte-identical to the old transform's output apart from the generated-file banner. Also point the start/validate scripts at the rendered manifests — they named frontend/manifest.xml, which has never existed. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PNuWdfW5eePAWvepBdHfje
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.
Adds a staging manifest so beta testers can run staging in Word, and replaces the build-time regex transform with a template so the three manifests can't drift.
Why not a runtime picker
Word has no equivalent of the Google Docs sidebar's source picker. The gdocs sidebar has no origin of its own, so "which environment" is entirely a property of the injected bundle. Word's task pane is a real browsing context at
SourceLocation— injecting a staging bundle into a page served fromapp.thoughtful-ai.comwould still leave you on the prod origin, with the prod backend, prod cookies and prod logs. So each deploy target genuinely needs its own manifest.What replaced the string surgery
The manifest was a checked-in dev file rewritten at build time:
That has no spelling for a third environment, and it only rewrote strings someone remembered to write in the
-devform —CommandsGroup.Labelwas plain"Thoughtful", so the ribbon group already looked identical in dev and prod. Undetected drift, in the one file whose job is to tell the environments apart.Now:
frontend/manifest/template.xml— the structure, once. Placeholders{{APP_ID}},{{APP_NAME}},{{BASE_URL}}.frontend/manifest/environments.ts— the differences, once.frontend/manifest/environments.test.ts— the guard the regex couldn't provide.DisplayNamemanifest.xmlapp.thoughtful-ai.commanifest-staging.xmlstaging.thoughtful-ai.commanifest-dev.xmllocalhost:3000Each has its own add-in id, so all three can be installed side by side.
Two behaviour changes worth reviewing
Every build emits all three manifests, instead of
--modepicking one. Which manifest you need depends on who is installing it, not on the flags that produced the build. The old coupling meant the image the Dockerfile builds carried a manifest naming the prod origin no matter where it was deployed — a staging deployment would have handed out a prod manifest.Names put the distinguishing word first. The Add-ins menu truncates
DisplayNameto roughly ten characters, soThoughtful-devandThoughtfulboth render asThoughtfulthere and a dev install is indistinguishable from a real one. The task pane header shows the full string, so only the menu is affected. Prod's name is unchanged.What the test enforces
Per environment: no leftover placeholders, no mention of any other environment's origin or id, and every
DefaultValueURL built from that environment's base (bar Microsoft's own "learn more" link). That last one catches a hardcoded origin added to the template later — which the old transform would have shipped silently. Plus distinct ids, distinct filenames, and distinct first-ten-characters of the display name.Verification
npm test— 239 passed (17 new)npm run typecheck,npm run lint— clean (3 pre-existing warnings, unrelated)npm run test:buildafter a cleanbuild+build:google-docs— all three manifests present and well-formed, gdocs build doesn't clobber themoffice-addin-manifest validatecouldn't run here — it calls a Microsoft web service that this sandbox's egress proxy blocks (403). Worth running once ondist/manifest-staging.xmlbefore handing it to testers:npm run validate:staging.Not fixed here
Commands.Urlpoints at{{BASE_URL}}/commands/commands.html, but the build emitscommands.htmlat the root ofdist/, so theFunctionFile404s. This predates the template — it was the same in the checked-in manifest — and it's left alone rather than folded silently into a refactor. Noted infrontend/manifest/README.md.Separately, and outside this PR's scope: the gdocs bundle compiles
GDOCS_BACKEND_URLto the prod origin in every non-dev build, so picking "staging" in the sidebar picker loads staging's bundle but talks to the prod backend.Generated by Claude Code