Skip to content

Agent playbook (EDOS workspace)

Audience: Agent

Use this checklist when modifying existing projects or adding a new one. Read in order: README.mdARCHITECTURE.mdIPC.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

  1. Confirm which top-level folder you are editing — this workspace is not a monorepo; do not add root-level shared packages unless maintainers agree.
  2. Open REPOS.md for run commands and npm links.
  3. If changing cross-window messaging, read IPC.md and inter-frame-messenger/src/index.ts end-to-end.
  4. If changing URL query / hash bootstrap, embedding, or /.well-known/edos-integration.json, read HOSTED_APP_CONTRACT.md and update the app capsule.
  5. If changing journal semantics, grep consumers of @howfe/elite-dangerous-event-types and update types/guards first.

Adding a new project (new top-level folder)

  1. If the project will be deployed behind Traefik, pick an unused ed* slug and hostname per HOSTNAMES.md before writing docker-compose.yaml.
  2. Keep it self-contained (own package.json or build as appropriate).
  3. If it needs journal types, depend on @howfe/elite-dangerous-event-types.
  4. If it embeds or opens another window, depend on @howfe/inter-frame-messenger and extend IPC.md with new message types only after updating the enum in source.
  5. 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.json on the deployment origin.
  6. Add a capsule: docs/apps/APP_SLUG.md using the same sections as existing capsules.
  7. Update REPOS.md quick-reference table, HOSTNAMES.md (allocated slug row), and TODO.md if you leave gaps.
  8. 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 / axios to those upstream URLs from the client. See ARCHITECTURE.md (third-party HTTP + design principle 5).
  9. 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.
  10. 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).
  11. If the project uses Cursor canvas mockups (*.canvas.tsx), ensure <app>/.cursor/rules/edos-canvas-mockups.mdc exists (copy from docs/templates/cursor-rules/edos-canvas-mockups.mdc, or run node docs/templates/cursor-rules/sync-app-canvas-rules.mjs to refresh all app copies from elite-dangerous-stellar-scan). See DESIGN_GUIDANCE — “Cursor canvas mockups”.

Changing IPC (postMessage)

  • Do not change string values of MessageTypeEnum without 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 allowedSenderOrigins to '*' 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.query today); do not add hidden iframes to another app’s origin to read its localStorage.

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 to docs.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-types first; 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.ts affect deduplication, polling interval, and what gets sent — retest with surface map popup flow.
  • Surface map: readGalaxyDataFromEvents.ts and useCommanderState.ts subscribe via useJournalReader — 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 fetchWithCache pattern (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 postMessage require 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.