Agent playbook (EDOS workspace)¶
Audience: Agent
Use this checklist when modifying existing projects or adding a new one. Read in order: README.md → ARCHITECTURE.md → IPC.md if touching messaging → HOSTED_APP_CONTRACT.md if touching URL bootstrap, manifests, or iframe embed modes → APP_DISCOVERY_REGISTRY.md if touching composition-host catalogs or registry indexes → the relevant apps/ capsule.
Keeping docs in sync with the workspace: project-local Cursor skills live under .cursor/skills/ (edos-doc-inventory, edos-doc-verify, edos-doc-update, and edos-doc-full-refresh to run all three in order in one session). Slash command: /edos-doc-full-refresh. This repo’s docs/ are the source of truth — no remote doc fetch required for those workflows.
Keeping Cursor assets in sync across submodules: skill edos-sync-cursor-assets, slash command /edos-sync-cursor-assets, script node docs/templates/cursor-sync/sync-edos-cursor-assets.mjs — copies shared rules/skills/commands into each submodule with GitLab CI (and per-app canvas rules where relevant); does not copy meta-repo-only edos-doc-* or submodule-specific files (e.g. gitlab-pipelines.mdc in local journal reader).
Partial workspace checkouts¶
Your edos/ tree may omit projects or contain only part of an app (sparse checkout, submodule, docs-only clone). That is expected. Deploy files (docker-compose.yaml), full src/, and CI live in each app repository when fully cloned — absence here is not a doc bug.
When updating deploy or implementation details in docs/, use a full clone of the relevant app (or its README), not “file missing in this folder” as the only signal. See DOC_CONVENTIONS.md — Partial workspace checkouts and REPOS.md — Partial workspace checkouts.
Before you change anything¶
- Confirm which top-level folder you are editing — this workspace is not a monorepo; do not add root-level shared packages unless maintainers agree.
- Open REPOS.md for run commands and npm links.
- If changing cross-window messaging, read IPC.md and
inter-frame-messenger/src/index.tsend-to-end. - If changing URL query / hash bootstrap, embedding, or
/.well-known/edos-integration.json, read HOSTED_APP_CONTRACT.md and update the app capsule. - If changing journal semantics, grep consumers of
@howfe/elite-dangerous-event-typesand update types/guards first.
Adding a new project (new top-level folder)¶
- If the project will be deployed behind Traefik, pick an unused
ed*slug and hostname per HOSTNAMES.md before writingdocker-compose.yaml. - Keep it self-contained (own
package.jsonor build as appropriate). - If it needs journal types, depend on
@howfe/elite-dangerous-event-types. - If it embeds or opens another window, depend on
@howfe/inter-frame-messengerand extend IPC.md with new message types only after updating the enum in source. - If it is a hosted web UI that supports iframe / webview or query-driven modes, follow HOSTED_APP_CONTRACT.md: document bootstrap keys in the capsule and plan a manifest at
/.well-known/edos-integration.jsonon the deployment origin. - Add a capsule:
docs/apps/APP_SLUG.mdusing the same sections as existing capsules. - Update REPOS.md quick-reference table, HOSTNAMES.md (allocated slug row), and TODO.md if you leave gaps.
- If the project calls third-party community HTTP APIs (SPANSH, EDSM, similar): always use the API cache server (or the same proxy pattern) — never add direct
fetch/axiosto those upstream URLs from the client. See ARCHITECTURE.md (third-party HTTP + design principle 5). - If the project has a user-facing web UI, consider DESIGN_GUIDANCE.md (optional orange-on-black tokens; stack-agnostic — do not default to Quasar for new apps). If the UI calls community APIs, loads third-party assets, or embeds external frameworks (map engines, etc.), add bottom-center link attributions per DESIGN_GUIDANCE.md — Third-party service attribution.
- If the project’s primary surface is a data-dense table (sortable columns, saved views, filters), follow TABLE_GUIDANCE.md — reference
elite-dangerous-stellar-scan(BodiesTable.tsx,TableWorkspace.tsx,domain/views.ts). - If the project uses Cursor canvas mockups (
*.canvas.tsx), ensure<app>/.cursor/rules/edos-canvas-mockups.mdcexists (copy fromdocs/templates/cursor-rules/edos-canvas-mockups.mdc, or runnode docs/templates/cursor-rules/sync-app-canvas-rules.mjsto refresh all app copies fromelite-dangerous-stellar-scan). See DESIGN_GUIDANCE — “Cursor canvas mockups”.
Changing IPC (postMessage)¶
- Do not change string values of
MessageTypeEnumwithout a coordinated release of inter-frame-messenger and all consumers (both Quasar apps at minimum). - Do keep send / listen allowlists symmetric with actual usage.
- Do validate payloads with existing
isEliteEvent/isStatus(or extend event-types). - Avoid widening
allowedSenderOriginsto'*'on new code paths without a documented reason (see IPC.md). - Sibling iframe / cross-app data: follow HOSTED_APP_CONTRACT.md — Composition host and sibling iframes. Route through the composition host (
edac.places.querytoday); do not add hidden iframes to another app’s origin to read itslocalStorage.
Journal / sidecar samples (journalFilesSamples/)¶
The workspace may include a top-level journalFilesSamples/ directory: real Journal*.log lines and sidecar JSON (Cargo.json, Market.json, NavRoute.json, …) from actual play sessions. Use them when you need concrete field shapes, rare event variants, or edge cases that @howfe/elite-dangerous-event-types, IPC.md, and the rest of this doc set do not spell out.
- Not on the public docs site — like
docs/templates/, this tree is workspace-local and is not published todocs.edos.howfe.org. Do not copy sample file contents into hosted Markdown or assume they can be fetched from/raw/. - May be missing in your checkout — sparse checkouts, optional bundles, or clones that only pull app repos may not have the folder at all.
- When types and docs are insufficient for the task, do not invent journal JSON from training data. Ask the operator to paste a redacted event line, attach a minimal excerpt, or provide access to the relevant files under
journalFilesSamples/(or equivalent local logs). - When the directory is present, prefer grepping or reading those files to validate parsers, guards, and tests. Align with
elite-dangerous-event-typesfirst; use samples to close gaps the package has not caught up with yet.
Package-committed structural fixtures (minimal envelopes) live under each project’s own fixtures/ — see elite-dangerous-event-types.
Changing journal handling¶
- Remote reader: changes in
JournalWatcher.ts/StatusWatcher.tsaffect deduplication, polling interval, and what gets sent — retest with surface map popup flow. - Surface map:
readGalaxyDataFromEvents.tsanduseCommanderState.tssubscribe viauseJournalReader— avoid duplicate subscription bugs (singleton module state). - Event types: run downstream TypeScript builds after editing
elite-dangerous-event-types/index.ts.
Curated data from other Elite Dangerous tools¶
- Mandatory: EDOS does not import curated game data from other Elite Dangerous applications; use citable public references or verify and maintain the data in-repo. Details: DOC_CONVENTIONS.md, ARCHITECTURE.md design principle 7.
Exploration scan credit matrices¶
When adding or changing exploration payout logic (FSS / DSS / discovery bonuses), follow DOC_CONVENTIONS.md — Exploration scan credit data: use the Fandom Explorer Scan Values table (transcribed in-repo). The curated-data rule above still applies.
Changing API cache / external data¶
- Mandatory: Community Elite Dangerous APIs are volunteer-run and usually without DDoS protection. Using the cache server is a fair-use rule: it reduces duplicate traffic and avoids putting pressure on other people’s infrastructure. All third-party API usage from apps in this ecosystem must go through the cache (or an equivalent operated the same way), not direct to SPANSH/EDSM/etc. from the browser except where a maintainer documents a rare, explicit exception.
- Server:
api-cache-server/api/src/app.ts— respect cache key and queue behavior. - Clients: use the
fetchWithCachepattern (or the same?url=contract against your cache base URL); do not bypass the cache for convenience. - Do not point the cache service at arbitrary URLs in production without understanding SSRF risk; that is separate from the fair-use rule for known community API hosts.
Bumping WebView / browser assumptions¶
- File System Access API and
postMessagerequire modern Chromium-class environments for the current design. See original-concept.md for legacy WebView caveats.
Builds / tests (current state)¶
| Project | Command (from path) |
|---|---|
inter-frame-messenger |
npm run build |
stellar-forge-helper |
npm run build / npm test |
api-cache-server/api |
bun run dev / bun run start |
elite-dangerous-planet-analyser/api |
bun run dev / bun run start / bun test |
elite-dangerous-surface-map/ui |
npm run lint, npm run dev, npm run build |
elite-dangerous-remote-journal-reader/ui |
same pattern |
elite-dangerous-stellar-scan |
npm run dev / npm run build / npm test |
elite-dangerous-credit-account |
npm run dev / npm run build / npm test |
elite-dangerous-journal-event-viewer |
npm run dev / npm run build |
elite-dangerous-local-journal-reader |
npm run tauri:dev / npm run tauri:build (optional: npm run build-service:dev, npm test) |
TODO: Verify CI expectations per repo (.gitlab-ci.yml where present).
Do not¶
- Convert the workspace into a monorepo “while you’re here.”
- Add second, incompatible definitions of journal event shapes outside
elite-dangerous-event-types. - Send journal files to
api-cache-server— it is an HTTP proxy for arbitrary URLs, not a journal pipeline. - Call community third-party APIs directly from app code when those APIs should flow through the cache — see “Changing API cache / external data” above.
- Import curated game data from other Elite Dangerous applications — see “Curated data from other Elite Dangerous tools” above.
- Ship a second native Tauri / local journal bridge inside a web-only app repo. One desktop shell exists:
elite-dangerous-local-journal-reader(see AGENT_INDEX.md and apps/elite-dangerous-local-journal-reader.md); hosted apps link to its build-service artifacts or URLs.