cap-companion
v0.1.0
Published
Playback-only SAP Companion (Help4) workarea for CAP — tours, docs, hotspots, and videos without Enable Now Manager
Maintainers
Readme
cap-companion
Unofficial open-source CAP plugin that serves a playback-only SAP Companion (Help4) workarea for Fiori applications — guided tours, in-app help documents, hotspots, and video/link lightboxes — without SAP Enable Now Manager, WalkMe, or editor APIs.
Not SAP-supported. You must supply a licensed complete
sap.dfa.helpruntime yourself. This package ships only protocol glue and a Bookshop example.
Standalone approuter only. Help4 loads its runtime and SEN catalogue/context from app-relative routes (
/$companion/framework/**,/$companion/pub/<workarea>/.catalogue,.context). Those URLs only reach this plugin when you control the HTML5 app’s routing — a standalone@sap/approuter(xs-app.json). Managed approuter behind SAP Build Work Zone does not expose those routes, so Companion never hits CAP. Localcds watch/ Bookshop is the same class of setup as standalone.
Features
- YAML/JSON-authored help and tour content in a
companion/folder - Deterministic compilation to Help4 SEN
.catalogueand.contextresponses - Static mounting of externally supplied
sap.dfa.helpunder/$companion/framework - Optional
cds buildcopy task for production packaging - Bookshop + local Fiori launchpad harness via
cds-launchpad-plugin
Out of scope (v1): editor/producer, writes, /multifile, SAML Manager, Learning Center, tracking backend, CDS persistence, automatic SAP downloads, managed approuter / SAP Build Work Zone.
Requirements
- Node.js >= 18
@sap/cds>= 8- Licensed complete Help4 4.0.28 tree (for browser verification)
- UI5 1.151.0 when using the Bookshop launchpad harness
sap.dfa.help is not part of the public UI5 CDN (https://ui5.sap.com/.../resources/sap/dfa/help/ returns 404). Companion is a separate SAP product. The shell still loads sap.m / sap.ushell from ui5.sap.com; only Help4 must be served from your app (or another host you license). That is why CAP_COMPANION_FRAMEWORK_PATH exists — it is a self-hosted copy, not a second cloud service.
Install
npm install cap-companionEnable in your CAP project package.json:
{
"dependencies": {
"cap-companion": "^0.1.0"
},
"cds": {
"companion": {
"enabled": true,
"workarea": "myapp",
"framework": {
"path": "../licensed/sap-dfa-help"
}
}
}
}Or point to an absolute runtime:
export CAP_COMPANION_FRAMEWORK_PATH="/path/to/sap/dfa/help"Content
Place *.yaml or *.json files in companion/ (configurable via cds.companion.contentDir).
schemaVersion: 1
id: books-list-help
type: HELP
title: Books help
locale: en-US
revision: 1
context:
appUrl: Books-display
product: CAP_BOOKSHOP
version: "1.0"
items:
- id: overview
kind: document
title: About the catalog
contentHtml: "<p>Browse and filter the available books.</p>"
- id: search
kind: hotspot
target: { helpId: books-search }
title: Search
contentHtml: "<p>Search by title or author.</p>"See test/bookshop/companion/ for HELP, TOUR, links, presentation, What's New, callouts, conditions, locale variants, and quiz examples.
Item kinds
| kind | Help4 macro | Notes |
| --- | --- | --- |
| document | help_tile | Optional target for anchored help |
| hotspot | help_tile | Requires target; supports callout, instantHelp |
| video | link_tile | Always opens in lightbox with tile_icon: video |
| link | link_tile | Generic link; lightbox: false opens a new window |
| tourStep | guide_click | Optional screen for multi-screen tours |
Links
kind: link compiles to a Help4 link_tile. Set lightbox: true for an iframe lightbox, or lightbox: false to open in a new browser tab. tileIcon accepts Help4 values such as external, pdf, faq, and link.
kind: video remains shorthand for a lightbox link with tile_icon: video.
Presentation
Optional fields on document, hotspot, and tourStep items:
bubbleType:info,tip,note,important,action,start,endbubbleSize:s,m,lbubbleOrientation:auto,W,N,S,EbubbleAnimation:default,expand,fade,pulse,scaleup,shake,shrink,wobblebubbleOffset:{ left, top }— nudges the bubble relative to its anchorhotspotStyle:CIRCLE,ICON,RECTANGLE,UNDERLINE,TRIANGLE,NUMBEREDhotspotSpotlight:truedims the rest of the screenhotspotIconType:help,info,tip,warning, and other Help4 icon typeshotspotIconPos:R,Q, orA–P— icon placement onICONhotspotsinstantHelp/callout: requiretarget; panel can stay closed for calloutsshowTitleBar/showArrow: bubble chrome (defaulttrue)alignWithText:truealigns the hotspot bubble with control text (help tiles only)tileIcon: Help4 panel icon on documents and hotspots (whatsthisapp,faq, …)showAsButton: render as a panel button instead of a list tile
Help4 disables instant help on CIRCLE hotspots — the compiler forces ICON when needed.
Link and video chrome
On link and video items:
showAsButton: panel button instead of list tilesplash/splashOption(once|always): lightbox splash screen (meaningful withlightbox: true)lightboxSizing/lightboxSize: iframe dimensions for lightbox links
Help4 has no tile section headers in the Help panel — use group + groupPrefix: true on the project to prepend "Group · " to captions.
What's New
Set whatsnew: true on a TOUR project (not a third type). The catalogue appUrl is published as <inbound>!whatsnew so Help4's What's New widget can find it.
Conditions
Use when on a project or item:
when:
urlContains: Books-display
elementVisible: "[data-help-id='books-go']"
after: "2020-01-01"
before: "2030-01-01"
api:
demoRole: authorAPI conditions require the host app to call Help4 ConditionService.setCondition (Bookshop: ?companionRole=author).
Grouping
group sorts tiles in the Help list. Set groupPrefix: true on the project to prepend "Group · " to tile captions.
Localization
Use separate YAML files per locale with distinct id values (.context is keyed by id):
books-list-help.yaml→id: books-list-help,locale: en-USbooks-list-help.de-DE.yaml→id: books-list-help-de,locale: de-DE
Knowledge check (quiz fallback)
Native Enable Now quizzes are not OSH playback macros. Ship a static HTML page under companion/media/ and open it with kind: link, lightbox: true, tileIcon: faq.
Videos
kind: video compiles to a Help4 link_tile opened in a lightbox. Set contentUrl to the media you want Help4 to load:
| contentUrl | Help4 behavior |
| --- | --- |
| /$companion/media/demo.mp4 (or .webm) | Lightbox plays the video file directly |
| /$companion/media/demo.html | Lightbox iframe — use an HTML page with <video> or embedded content |
| https://… | Same as above when the URL is HTTPS (validated by the content provider) |
Bookshop example (companion/books-list-help.yaml):
- id: video
kind: video
title: Walkthrough
contentUrl: "/$companion/media/walkthrough.html"The HTML page at companion/media/walkthrough.html embeds walkthrough.mp4 from the same folder.
Fiori launchpad integration
Works with a standalone approuter (or local CAP). Map /$companion/** in xs-app.json to the CAP backend. Managed Work Zone routing cannot do that.
- Map
sap.dfa.helpto the plugin framework URL (module path or approuter route). - Register bootstrap plugin
sap.dfa.help.utils.adapters.fiorias a RendererExtensions plugin. - Set
enableHelp: trueon the Fiori2 renderer. - Plugin config:
backend: "WPB",dataUrlWPB: "/$companion/wa/<workarea>",playbackTag: "published",editor: false,multifile: false.
The Bookshop harness under test/bookshop demonstrates the full wiring with cds-launchpad-plugin.
HTTP contract
For basePath=/$companion and workarea=bookshop:
| Route | Purpose |
| -------------------------------------------------------- | -------------------------------------------------- |
| GET /$companion/pub/bookshop/.catalogue?{encoded-json} | Project catalogue |
| GET /$companion/pub/bookshop/.context?{"id":"..."} | Project payload |
| GET /$companion/framework/** | Licensed Help4 static assets |
| GET /$companion/media/** | Optional same-origin media from companion/media/ |
Query strings are percent-encoded JSON (not key=value pairs).
Security
- GET/HEAD only on companion routes
- HTML sanitization by default (
cds.companion.html.allowUnsafe: false) - Path traversal protection; no directory listing for framework static files
auth: inherit(default) — protect routes via approuter/XSUAA in production
Development
git clone https://github.com/sleibach/cap-companion.git
cd cap-companion
npm install
npm testRelease checklist
- Never commit or publish
test/bookshop/.framework-runtime/or generatedgen/companion/framework/; both can contain licensed SAP Companion assets. - Publish only the generated stub
IconFontwhose checksum matchestest/bookshop/framework-stubs/wpb/files/icon-font-stub.sha256.
Bookshop locally:
cd test/bookshop
npm run dev:help
# prepares mirror + wpb/i18n|files stubs, then cds watch
# open http://localhost:4004/$launchpadDiagnose CMP4 activation:
cd test/bookshop
npm run diagnose:cmp4 -- --base http://localhost:4005Licensed browser gate (optional):
CAP_COMPANION_FRAMEWORK_PATH=/path/to/sap/dfa/help npm run test:browser --workspace=test/bookshopTroubleshooting
| Symptom | Check |
| -------------------- | --------------------------------------------------------------------------------------- |
| Empty catalogue | context.appUrl must match the Fiori screen id from the .catalogue query |
| 404 context | Project id in YAML matches .context query |
| Help4 fails to load | Put modulePaths["sap.dfa.help"] in fioriSandboxConfig (not only launchpad.html — UI5 1.151 overwrites the inline config). Confirm Help4.js is requested from /$companion/framework, not ui5.sap.com. |
| Incomplete framework | Full runtime needs wpb/i18n, wpb/files, themes — run npm run prepare:framework --workspace=test/bookshop or point CAP_COMPANION_FRAMEWORK_PATH at a licensed tree |
| Auth errors | Standalone approuter must allow /$companion/** for authenticated users |
| No help in Work Zone | Managed approuter cannot route /$companion/** to CAP — use standalone deployment |
Tested matrix
| Component | Version | | --------- | ------- | | CAP | 8 / 9 | | UI5 | 1.151.0 | | Help4 | 4.0.28 |
