Hugo Fund Formation Platform14 Jun, 05:04 CET

Word Add-in

Microsoft Word task pane for clause search, pro-forma drafting, and context chat.
3
Tabs
Cross-fund
Search
1
Chat mode
Word API
Bridge

Repository layout

office-addins/word/
├── assets/
├── docs/
│   └── sources.md
├── eslint.config.mjs
├── manifest.xml
├── package.json
├── tsconfig.json
├── webpack.config.js
├── src/
│   ├── taskpane.css
│   ├── taskpane.html
│   ├── taskpane.ts
│   ├── types.ts
│   ├── styles/
│   │   ├── base.css
│   │   ├── clauses.css
│   │   ├── chat.css
│   │   ├── feedback.css
│   │   ├── pro-forma.css
│   │   ├── shell.css
│   │   └── ...
│   ├── api/
│   │   ├── auth.ts
│   │   ├── chat.ts
│   │   ├── client.ts
│   │   ├── clauses.ts
│   │   ├── index.ts
│   │   └── pro-forma.ts
│   ├── shared/
│   │   ├── dom.ts
│   │   ├── errors.ts
│   │   ├── html.ts
│   │   ├── tabs.ts
│   │   └── toast.ts
│   ├── word/
│   │   ├── draft-format.ts
│   │   ├── host.ts
│   │   └── insert.ts
│   ├── clauses/
│   │   ├── detail.ts
│   │   ├── filters.ts
│   │   ├── grouped-results.ts
│   │   ├── index.ts
│   │   ├── modal.ts
│   │   ├── state.ts
│   │   └── types.ts
│   ├── pro-forma/
│   │   ├── draft-insert.ts
│   │   ├── index.ts
│   │   ├── profile-results.ts
│   │   ├── state.ts
│   │   └── status.ts
│   ├── chat/
│   │   ├── index.ts
│   │   ├── state.ts
│   │   ├── types.ts
│   │   └── view.ts
│   └── feedback/
│       ├── index.ts
│       ├── types.ts
│       └── view.ts

Run and verify

Prepare and run each side:

cd /home/axel/projects/hugo/source/main/office-addins/word
npm install
npx office-addin-dev-certs install
npm run build
npm run validate
npm run dev

For local end-to-end checks, run Hugo in one terminal and the add-in in another, then open:

cd /home/axel/projects/hugo/source/main
npx wrangler dev --local --local-protocol https --port 8788
cd /home/axel/projects/hugo/source/main/office-addins/word
npm run dev
https://localhost:3000/taskpane.html?api=https://localhost:8788

Authentication flow

Startup in office-addins/word/src/taskpane.ts calls ensureAccess(), then ping(): GET /api/users/me.

On 401 or network failure (most often status 0 when cookie flow is missing), the taskpane opens an Office dialog to /auth/addin-complete.

/auth/addin-complete is handled by registerWordAddinAuthRoutes and posts back to Office via Office.context.ui.messageParent():

{ "type": "hugo-addin-session", "token": "<short-lived JWT>", "expiresAt": "<ISO timestamp>" }

The token is stored in session storage under hugo_word_addin_session and sent on add-in API calls with Authorization: Bearer ....

Endpoint bridge

Word Web cannot reliably send CF Access cookies in the taskpane iframe. The client routes same-origin traffic through /addin/word-api/api/... with the bearer token.

Bridge behavior comes from registerWordAddinBridgeRoutes:

Allowed bridge routes are exactly:

Tabs

1) Clauses
  • Cross-fund clause search with live filters.
  • Filter semantics are OR within each facet and AND across facets.
  • Results can be grouped by clause category.
  • Insertion policy: append to clauses-body if present; otherwise insert at current selection.
2) Pro forma
  • Builds an LP context from sponsor/fund pickers, profile filters, and drafting fields.
  • Loads profile options from /api/lp-profile/facets.
  • Runs prevalences through /api/lp-profile.
  • Submits POST /api/export-template/draft with either fund_id (fund scope) or sponsor_id (sponsor scope).
3) Chat
  • Enabled only when GET /api/chat/status reports enabled.
  • Loads accessible funds and optional scope, then posts turns to POST /api/chat.
  • Shows returned clauses as cards with one-click insert/copy actions.

Insertion semantics

Clause insertion

Clause text insertion from search and chat uses:

Pro-forma insertion

Pro-forma flow (server + add-in)

  1. Resolution: the draft endpoint resolves template with fund override -> sponsor default -> built-in starter (or sponsor-only default when no fund is selected).
  2. Render: it renders template data with empty clause loop, normalizing a clauses-body anchor.
  3. Response: payload includes { format, body, filename, source, heading2_style, normal_style }, where format is docx or ooxml.
  4. Insert: desktop inserts DOCX from base64; web inserts OOXML.
  5. Post-insert: comparable clause cards are formatted and appended into the content control when available.

Chat architecture

The backend uses one clause tool plan per request. Supported modes are:

Example response shape:

{
  assistant: string,
  clauses?: ChatClauseCard[],
  meta: { mode: 'examples' | 'count' | 'breakdown'; result_count: number; latency_ms: number }
}

Feedback

A floating widget posts via POST /addin/word-feedback and loads draft state from GET /addin/word-feedback/draft. Both routes are associated with the shared route template /addin/word/taskpane in admin feedback handling.

Endpoints used

MethodPathUse
GET/api/users/meAuth probe / reauth path.
GET/api/fundsPopulate filters and scopes.
GET/api/clause-categoriesClause facets.
GET/api/investor-categoriesInvestor facets.
GET/api/fund-categoriesFund facets.
GET/api/gpsSponsor facets.
GET/api/lp-countriesInvestor country facets.
GET/api/investorsInvestor entities for the LP form.
GET/api/clauses/searchCross-fund search/count/aggregate.
GET/api/clauses/:idClause detail.
GET/api/funds/:fundId/clausesFund-scoped clause list.
GET/api/funds/:fundId/clauses/searchFund-scoped clause search.
GET/api/lp-profile/facetsPro forma profile filter options.
GET/api/lp-profilePrevalence query for the selected LP profile.
POST/api/export-template/draftRender template draft for Word insertion.
GET/api/chat/statusProbe chat availability and provider metadata.
POST/api/chatRun one-tool query with clause-aware output.
POST/addin/word-feedbackTaskpane feedback create/update.
GET/addin/word-feedback/draftLoad existing taskpane feedback draft.
any/addin/word-api/api/*Word Web same-origin bridge entrypoint.

Known limits

  1. Chat is intentionally narrow and single-tool today.
  2. Clause tab inserts remain plain text.
  3. Word Web pro-forma insertion depends on OOXML-friendly templates.
Ctrl+K to open · ↑↓ navigate · Enter go · Esc close
Copied