Skip to content

feat(word-addin): Office.js task pane for Mike (chat, actions, workflows, projects) - #23

Open
amal66 wants to merge 16 commits into
mainfrom
feat/word-addin-pr
Open

feat(word-addin): Office.js task pane for Mike (chat, actions, workflows, projects)#23
amal66 wants to merge 16 commits into
mainfrom
feat/word-addin-pr

Conversation

@amal66

@amal66 amal66 commented Jul 6, 2026

Copy link
Copy Markdown
Owner

Summary

Adds the Mike Office.js task pane for Word: document-aware chat, document actions, saved workflows, project browsing/uploads, Supabase authentication, and hermetic browser coverage.

The add-in lives in word-addin/ (not an npm workspace) and consumes the shared @mike/api-client SSE transport, @mike/core types, and the @mike/shared design system via tsconfig paths and webpack aliases, so it stays on the same tested contracts as the web app. The branch is reconciled with current main, including the olp UI sync ("feat: sync olp UI as source of truth"), and compiles cleanly against the updated shared packages.

Word editing behavior

  • Rewrites capture and track the exact selected Word.Range; they never search the whole body or replace the first duplicate match.
  • Applying a rewrite is rejected if the selected range changed while the model was responding.
  • Rewrite actions explicitly say Replace selection or Replace selection (tracked).
  • Generated additions explicitly say Insert below cursor; they never overwrite selected text.
  • Multi-paragraph output is inserted as real Word paragraphs after the paragraph containing the selection.
  • Inserted paragraphs inherit the surrounding style, alignment, indentation, line spacing, and paragraph spacing.
  • Model Markdown is conservatively normalised so code fences, headings, emphasis markers, links, and Markdown table syntax are not pasted raw into legal documents.
  • Tracked operations restore the user's previous change-tracking mode.

Additional review fixes

  • Workflow consumption follows the real shared API contract (metadata.* and skill_md), so production workflows are surfaced instead of filtered out.
  • Strict Word add-in typechecking runs in CI alongside a required hermetic build/Playwright job; webpack transpilation cannot conceal API-shape errors.
  • Production builds fail when endpoints are missing and generate a deployable manifest from WORD_ADDIN_PUBLIC_URL; they can never silently ship localhost URLs or an empty Supabase key.
  • Both the development manifest and the generated release manifest use schema-valid element ordering (no unsupported RequestedWidth).
  • The PR is scoped to Word: web chat/tabular SSE migrations were removed; the shared, tested SSE transport remains because the add-in consumes it.

Verification

Run on this branch after merging current main (olp UI sync):

  • Word add-in TypeScript check passes (tsc --noEmit, strict, including the updated shared @mike/api-client / @mike/core sources).
  • Word production build passes with explicit release configuration and writes the generated production manifest.
  • 57/57 Word add-in Playwright scenarios pass (hermetic: static-served production bundle, in-page Office.js shim, all backend calls intercepted — no live API/Supabase), including 18 focused document-action scenarios covering exact replacement, duplicate text, stale selections, tracked/untracked writes, non-destructive positioning, paragraph ordering, and Markdown normalisation.
  • 14/14 shared API-client tests pass.

Previously verified (not re-run in this reconciliation): Microsoft's Office manifest validator passes for both the development and generated release manifests.

The checked-in manifest.xml remains the localhost sideloading manifest; npm run build writes the release manifest to dist/manifest.xml.

🤖 Generated with Claude Code

https://claude.ai/code/session_01CEguyEgXa9JjCciXCcVemC

Remove word-addin/ and its root build/test wiring from main. The add-in
comes back via a dedicated feature branch + PR so the work is reviewable
as one focused diff instead of commits interleaved through main history.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@amal66
amal66 force-pushed the feat/word-addin-pr branch from 13ea693 to ff667ae Compare July 6, 2026 17:39
amal66 and others added 3 commits July 6, 2026 13:16
…text passthrough

The byte-stream -> SSE-frame reader loop was copy-pasted in three places
(apps/web's useAssistantChat hook and the Word add-in's api/client.ts).
Extract one framework-agnostic readSSE(response, onEvent, { signal }) helper
so every caller shares a single, tested parser. `[DONE]` is treated as
terminal (cancels the reader), matching the add-in's need to ignore the
harmless trailing error frame the API emits after it.

Also thread an optional `documentContext` through streamChat so the add-in's
document-grounded chat can use the shared client instead of a bespoke one.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Replace the inline getReader()/TextDecoder SSE loop in useAssistantChat with
a call to the shared readSSE() helper from @mike/api-client. One parser in the
codebase instead of a web-local copy; behavior is unchanged (verified via the
assistant parser + applyAssistantStreamEvent unit tests).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Word add-in (chat, document actions, workflows, projects) that reuses the
monorepo's shared packages instead of duplicating them: it configures
@mike/api-client once (api/mikeApi.ts) with an Office-session auth provider and
a single-place 401-refresh fetchImpl, streams via the shared readSSE helper
(api/stream.ts), and imports types from @mike/core. No hand-rolled HTTP client,
SSE parser, or re-declared Project/Workflow/ApiKeyStatus types — so adding an
endpoint or chat event type is now a one-place change in packages/* that the
add-in inherits. UI continues to come from @mike/shared.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@amal66
amal66 force-pushed the feat/word-addin-pr branch from ff667ae to 19c87b1 Compare July 7, 2026 02:37
amal66 and others added 2 commits July 7, 2026 08:35
…tream

readSSE now returns { done: boolean } — true when a [DONE] frame ended the
stream, false when the reader hit EOF (or aborted) without one. This lets the
tabular generation stream, which reconnects/resumes when a stream drops before
completing, consume the shared parser instead of its own copy. Existing callers
that ignore the return value are unaffected.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…readSSE

Replace the last two hand-rolled SSE reader loops (the tabular-review generate/
resume stream and the tabular chat panel) with the shared readSSE helper. The
generate loop uses readSSE's new { done } return to drive its bounded resume
retries; the chat panel moves its per-frame dispatch into readSSE's onEvent
callback. No behavior change — there is now exactly one SSE parser in the repo.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@amal66
amal66 changed the base branch from chore/remove-word-addin to main July 12, 2026 22:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant