- DB: paths table (contract #3) + helpers; patch_anchor (label/color) - API: GET /api/beats, POST /api/director (valid-empty degradation), /api/paths CRUD (validated POST -> 422), PATCH /api/anchors/{id}; manifest gains capsule:false (test_api.py key-set lock updated consciously) - CLI: features | direct | capsule subcommands -> lane stubs (exit-2 degradation) - Backend stubs with frozen contracts in docstrings: audio_features, director, capsule - Frontend: six lane stub modules imported from main.js; all phase-5 buttons pre-wired hidden in index.html; write-ui/body.capsule read-only mode; __F4D_API_BASE__ runtime override in state.js - Hooks (contract #6): transport.captureAudioStream/releaseAudioStream, scene3d.focusOn, scene3d.setHelpersVisible (+registerHelper; camPath gizmos) - Suite 121 -> 127 passed; npm build clean; live-browser verified (status file) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
29 lines
1.3 KiB
Python
29 lines
1.3 KiB
Python
"""Memory capsule: zero-backend shareable export (spec M17, lane G). STUB — lane G fills.
|
|
|
|
Contract: :func:`build_capsule` writes a self-contained bundle to ``out_dir`` (default
|
|
``config.CAPSULE_DIR``):
|
|
|
|
- copy ``frontend/dist`` (error clearly if missing — tell the user to ``npm run build``);
|
|
- copy media from ``config.RAW_DIR``;
|
|
- bake every read-only API response to files at the *same relative paths*
|
|
(``api/manifest``, ``api/events``, ``api/anchors``, ``api/beats``,
|
|
``api/videos/{id}/poses``, ``api/pointcloud``, ``api/splat``, ``api/audio/{id}`` —
|
|
extracting audio via ``ingest.extract_audio_hq`` if not yet cached);
|
|
- inject ``<script>window.__F4D_API_BASE__=""</script>`` into the copied ``index.html``;
|
|
- set ``"capsule": true`` in the baked manifest (the frontend hides all write UI);
|
|
- ship a stdlib ``serve.py`` in the bundle root that serves with HTTP Range support
|
|
(video seeking needs 206s; plain ``http.server`` can't — pitfall #4).
|
|
|
|
Skip what doesn't exist (no splat -> no ``api/splat``) — degrade, don't block.
|
|
Returns a summary dict (bundle path, file count, bytes) for the CLI log.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from pathlib import Path
|
|
|
|
|
|
def build_capsule(out_dir: str | Path | None = None) -> dict:
|
|
"""Build the static shareable bundle (see module doc)."""
|
|
raise NotImplementedError("memory capsule (lane G / M17)")
|