# Reconstruction of the development tree (plan for the next agent)

Written 2026-10-05. Language of the user chat: Czech; this file and all `.agents/` files are English.

## 1. What happened

The user uninstalled the addon in Kodi and installed it again from the repository. Kodi deleted the whole folder
`/Users/chudy/Library/Application Support/Kodi/addons/plugin.video.milionar` (permanent delete, **not** the Trash) and
unpacked the release ZIP. The folder had been **the working tree** (the addon is developed in place; `addons/skin.milionar`
is a symlink to `resources/skin.milionar` inside it). There is **no backup and no git remote**.

Lost: `.git` (one commit: "Initial commit: Milionář Kodi addon after agent workspace optimization" plus a large uncommitted
diff), `AGENTS.md`, `.gitignore`, `.agents/` (rules, skills, commands, scripts, tests, state), `docs/`, `scripts/` (all
harnesses, tests, `build_zip.sh`, `release.py`), dev-only code (`wcs/devtools/`, `wcs/library2/dev_list.py`,
`wcs/library2/fixture_provider.py`), `repository/` (source of `repository.milionar`), the generators and unreferenced images
in `resources/media/`, the skin's non-shipped files (`resources/skin.milionar/extras`, `fonts`, store art, themes sources,
the Estuary baseline helpers) and the real `resources/settings.xml` (the dev option `dev_fixture_provider`).

Present now (the installed release 2.1.26, version file `addon.xml`):
`addon.xml`, `main.py`, `service.py`, `context.py`, `md5crypt.py`, `wcs/` (runtime modules, final state of everything that
ships), `resources/` (language, prompts, keymaps, media actually referenced, `skin.milionar` runtime part, `skins/Default`
dialog XML, `settings.xml` with the dev option removed). **These runtime files are the authoritative latest versions: never
overwrite them with an older recovered file** (restore only files that are missing, or compare first).

## 2. Safety rules for the recovery

- Work in a staging folder first, e.g. `~/Documents/milionar-recovery/restored/`, then copy **only missing files** into the
  addon folder (`rsync -a --ignore-existing`). Never `rm`/overwrite anything in the addon folder or `userdata`.
- The disk is almost full (about 580 MB free on 2026-10-05). Do not copy the 3.8 GB `~/.codex/sessions`; read the jsonl files
  in place (stream them). Do not create big temp files.
- Do not touch `~/.claude/projects/...` and `~/.codex/...` (they are the only complete sources). The tarball
  `~/Documents/milionar-recovery/claude-transcripts.tgz` (145 MB) is a backup of the Claude transcripts and file-history.
- Kodi (the dev instance) may be running from this folder. Do not restart it while files are half restored.
- After the work: `git init`, commit, and set up a backup (see section 8).

## 3. Sources, best first

### 3.1 Already done

1. **`plugin.video.milionar-nightly-2026-09-27_2059.zip`** from `https://hosting.pilsfree.net/chudy/kodi/` (also in
   `ssh chudy@hosting.pilsfree.net:public_html/kodi/`) was unpacked and restored with `rsync --ignore-existing`: 94 files that
   were missing (list: `docs/plan/recovery/tools/nightly_restored_files.txt`): `scripts/dialog_harness/*` (state of 2026-09-27,
   including `kodi_renderer.py`, `render_dialog.py`, `compare_*.py`, `premium_episode/`, `search_compare/`, fonts),
   `scripts/generate_ladder_pill.py`, 39 texture generators `resources/media/*.py` and 36 images (state of 2026-09-27: some
   may be older than what the later work deleted; unreferenced images are not shipped anyway).
2. **Claude Code transcripts** (this project, 15 sessions, 2026-09-29 .. 2026-10-05):
   `~/.claude/projects/-Users-chudy-Library-Application-Support-Kodi-addons-plugin-video-milionar/*.jsonl`. A replay script was
   written: `docs/plan/recovery/tools/replay_claude_transcripts.py` (`python3 replay_claude_transcripts.py out.pkl`). It orders all
   `Write` / `Edit` / full `Read` tool calls on files under the addon folder and rebuilds their content. Result:
   **74 files**, 58 of them not present on disk. They were dumped, with a manifest (`MANIFEST.tsv`: source, size, whether
   the file exists now, number of edits that could not be applied), to
   `~/Documents/milionar-recovery/vfs-claude/`. Recovered there (dev-only files):
   - `AGENTS.md`, all of `.agents/skills/*` (ai-providers, app-prompts, kodi-debug, kodi-harness, kodi-skin, kodi-ui,
     search-harness, voice-output), `.agents/commands/deploy.md` (**outdated**: see 5.4) and `feature.md`,
     `.agents/scripts/tmdb.py`;
   - `docs/features/013-milionar-library.md`, `docs/plan/milionar-library/*` (14 files), `docs/plan/skin-milionar/*`
     (14 files; `060-widgets.md` is **older** than the final, see 5.5);
   - `scripts/dialog_harness/kodi_live.py` (17 KB, the live harness client), `compare_images.py`;
   - `scripts/library_harness/test_autoplay.py`, `test_channels.py`, `test_clicks.py`;
   - `scripts/search_harness/kodi_stubs.py`, `oracle.py`, `search_harness.py`;
   - `wcs/devtools/harness_service.py` (the service-side listener the live harness talks to; `service.py` calls
     `run_dev_harness()` which release builds strip);
   - `scripts/release.py` (older, see 5.3) and several runtime files that already exist on disk (ignore those).
   Files whose last event is a partial read or a Bash-made change are **not** at their final version: see section 5.
3. A copy of the hosting content was inspected: the hosting holds only runtime ZIPs (repo/, versions 2.1.17 .. 2.1.26, `old/`
   2.0.0 .. 9.2.0b, two nightlies). The earlier `milionar-agent-*.zip` bundles and `.agent` folder that used to be there are
   gone (not deleted by the assistant; cause unknown).

### 3.2 To do: Codex sessions (the previous agent, OpenAI Codex Desktop)

`~/.codex/sessions/2026/10/{02,03,04}/rollout-*.jsonl` and `~/.codex/archived_sessions/`. The agent that built most of the
harness, the tests, `gen_slots.py`, `deploy_check.py`, `build_zip.sh` (lean version), `wcs/skin/*`, `wcs/library2/*` and the
installer worked here. Sessions that mention this project (cwd = the addon folder), with size and `apply_patch` mentions:

| file (under `~/.codex/sessions/`) | size | apply_patch |
|---|---|---|
| 2026/10/03/rollout-2026-10-03T12-17-22-01a10144-...jsonl | 102 MB | 55 |
| 2026/10/04/rollout-2026-10-04T08-34-57-01a1059f-...jsonl | 9.4 MB | 30 |
| 2026/10/04/rollout-2026-10-04T08-51-48-01a105ae-...jsonl | 4.8 MB | 23 |
| 2026/10/04/rollout-2026-10-04T08-52-41-01a105af-abdb-...jsonl | 4.9 MB | 23 |
| 2026/10/04/rollout-2026-10-04T08-52-41-01a105af-ac46-...jsonl | 2.2 MB | 16 |
| 2026/10/04/rollout-2026-10-04T08-53-00-01a105af-f590-...jsonl | 3.0 MB | 12 |
| 2026/10/04/rollout-2026-10-04T09-00-30-01a105b6-...jsonl | 1.6 MB | 13 |
| 2026/10/04/rollout-2026-10-04T09-04-25-01a105ba-...jsonl | 4.0 MB | 15 |
| 2026/10/04/rollout-2026-10-04T21-12-22-01a10854-...jsonl | 2.5 MB | 4 |
| 2026/10/02/rollout-2026-10-02T18-08-26-01a0fd5f-...jsonl | 11 MB | 0 |
| 2026/10/02/rollout-2026-10-02T16-22-59-01a0fcff-...jsonl | ? | ? |

Plus older Codex sessions of 2026-09-2x/3x (the project existed before 2026-10-02; check
`grep -l plugin.video.milionar ~/.codex/sessions/*/*/*/*.jsonl ~/.codex/archived_sessions/*`).

Format: one JSON object per line; `type: response_item`, `payload.type: custom_tool_call`, `payload.name: exec`,
`payload.input` is JavaScript text such as `text(await tools.apply_patch("*** Begin Patch\n*** Update File: /Users/chudy/...
\n@@\n ...\n*** End Patch"))`, `text(await tools.exec_command({cmd:"..."}))`. Also look at `function_call` / `local_shell_call`
records and at the matching `*_output` records (they contain `cat`/`sed` outputs that show whole files).

Plan for a replay script (`tools/replay_codex_sessions.py`):
1. Stream all sessions in timestamp order (`timestamp` field).
2. Extract every `apply_patch` call (`*** Add File: path` followed by `+` lines = full content; `*** Update File:` hunks with
   `@@` context and `-`/`+` lines; `*** Move to:`; `*** Delete File:`). Parse with the real apply_patch semantics (context
   lines must match; fuzzy-match on whitespace).
3. Maintain a virtual file system for all paths under the addon folder. Seed it with the files recovered from the Claude
   transcripts and the nightly where that is the newest source (see 4), apply patches, and log every hunk that fails to apply
   (that means the base was wrong or missing: look for a later `cat`/`sed` output of that file in the same session).
4. Also harvest whole-file observations from tool outputs: `cat <file>`, `sed -n '1,999p' <file>`, `nl -ba <file>`, `rg --files`
   lists (to learn the complete file list of the project!). The output of the first `git status` / `find` / `ls -R` in each
   session shows the tree.
5. Shell-made writes: `cat > file <<'EOF'`, `python3 - <<'PY'` patch scripts, `sed -i`, `mv`/`cp`, `git mv`. These cannot all be
   replayed; list them per file and treat the file as "needs review" if one exists after its last known good content.

### 3.3 To do: remaining Claude sessions

The replay in 3.1 only used structured edit tools. Much of the last two days (2026-10-04) was done with Bash heredocs and
inline Python patch scripts. They are all in the transcripts of session
`7c93f65a-d6f3-40af-b8a3-95ba1cb15796` (17 MB) and in the older sessions. See section 5 for the list of files whose final content
must be recomposed from those.

### 3.4 Other evidence

- `~/.claude/file-history/<session>/<hash>@vN`: Claude's pre-edit backups (49 MB, included in the tarball). Names are hashes;
  the mapping to paths is in the `file-history-snapshot` records of the transcripts (field `trackedFileBackups`). Usable as
  extra older versions.
- The installed runtime files (section 1) contain the final code for everything that ships. For files that exist at
  runtime and were also edited by Bash scripts, the runtime copy wins.
- Release ZIPs on the hosting (`plugin.video.milionar-2.1.*.zip`, `repo/`) are the same runtime state as on disk; older
  `old/*.zip` (2.0.0 .. 9.2.0b, Jan-Feb 2026, 14-20 MB) may contain development files of the old addon (unchecked).
- The second Kodi on this Mac (Wine bottle `com.franke.Whisky`, `drive_c/users/chudy/AppData/Roaming/Kodi/addons/`) has only the
  runtime.

## 4. Order of work

1. Inventory: from all Codex and Claude sources build the **complete list of project files** (paths) with the last known
   event per file. Compare with the list of files on disk. Output a table `restored/INVENTORY.tsv`: path, best source,
   confidence (final / needs-review / lost).
2. Replay Codex (3.2) over a staging tree that already contains: nightly files, Claude `vfs-claude` files, current runtime
   files (read-only reference). Apply Codex patches to the **dev-only** files; for runtime files only compare, do not replace.
3. Replay the Bash-made changes of the Claude sessions for the files in section 5 (manually, in order, from the transcript
   commands; they are small `str.replace` patches with `assert old in text`).
4. Verify (section 6), fix, and copy missing files into the addon folder with `--ignore-existing`.
5. `git init` + `.gitignore` (from AGENTS.md / the Codex sessions: agent local state, harness `out/`, caches, `docs/temp/`)
   + one commit "Recovered development tree". Then the backup (section 8).

## 5. Files whose final content has to be recomposed (known deltas)

All of these were changed after the last structured tool event. Where possible take the **runtime** copy (it is final).

1. `scripts/build_zip.sh` - the **faithful** release builder (no XML/Python rewriting) with these properties:
   - ships every runtime file unchanged; excludes `.git .agents .claude .gitignore docs AGENTS.md scripts __pycache__ .DS_Store
     .idea .vscode tests fixtures devtools repository` and the modules `wcs/library2/dev_list.py`, `fixture_provider.py`;
   - excludes `resources/media/screenshots/`, `resources/media/*.py`, `resources/fonts/` (unused), the skin's
     `resources/skin.milionar/resources/*` (store art; manifest `screenshot`/`fanart` nodes removed), skin `fonts/*.ttf|jpg` and
     `extras/*.jpg` (the skin installer copies them from the system Estuary), `media/milionar/logo.png` and
     `logo-mark-v1-final.png` (copied from the plugin logo by the installer), and every skin texture whose name is in the system
     Estuary `Textures.xbt` (read from `/Applications/Kodi.app/Contents/Resources/Kodi/addons/skin.estuary/media/Textures.xbt`);
   - ships only images that some shipped `.py`/`.xml` names (basename match; `wcs/ui/assets.py` is ignored as a user);
   - strips dev-only code from `service.py` (`run_dev_harness`), `main.py` (`mplay_dev_list` branch), `wcs/library2/resolver.py`
     (fixture provider) and `dev_fixture_provider` from `settings.xml`; `addon.xml` gets the `skin.estuary` import and the
     skin addon imports the plugin at the same version; removes `screenshot`/`fanart` from both manifests;
   - recompresses PNGs losslessly (`PIL optimize`, pixel-identical check), shrinks the logo to 512 px
     (`release_logo`);
   - preflight: all XML well-formed, `<include file>` exist, packaged asset references exist or are warned about, Python
     compiles for the packaged result, no excluded runtime import.
   The pre-rewrite "lean" variant (native Estuary textures) is **not** used any more.
2. `scripts/skin_harness/gen_slots.py` - generates `resources/skin.milionar/xml/Includes_MilionarSlots.xml` (60 slots, 10 sections;
   section `cont` uses `StartWidgetListPoster|Episodes` with a `slot` param; the other 9 sections use `WidgetList*` with
   `content_path=$VAR[MilionarContent_<sec>_<n>]`; each such variable returns the placeholder
   `special://skin/playlists/milionar-empty.xsp` until `Window(Home).Property(milionar.go.<sec>)` is set or the menu item is focused;
   URL carries `reload=$INFO[Skin.String(mil.<sec>.<n>.rev)]`). The generated XML on disk is final: the generator can be
   rewritten from it (test: `gen_slots.build() == Includes_MilionarSlots.xml`).
3. `scripts/skin_harness/gen_start.py` (new, 2026-10-04; generates `Includes_MilionarStart.xml` from
   `View_54_InfoWall.xml` and `Includes_Home.xml`; rules: `ListItem.Art(poster)` -> `ListItem.Property(mil.poster)`,
   `PercentPlayed` -> `mil.pct`, flags `.tv.`, `.R.`, `.P.`, `.W.`, `StartThumbVar`, `StartStatusIconVar`, ...). The generated XML on
   disk is final; rewrite the generator from it.
4. `scripts/release.py` (build/publish the Kodi repository: `python3 scripts/release.py build|publish`; writes the ZIP,
   `repository.milionar` ZIP, `repo/addons.xml` + md5, uploads to `chudy@hosting.pilsfree.net:public_html/kodi/` via a temporary
   directory, SHA256-verifies, renames (ZIPs first, `addons.xml` last), verifies HTTPS URLs and runs `deploy_check.py record`).
   The Write version is older: later fixes were `rsync -rt` instead of `-a --chmod`, remote `mv` paths relative to the
   upload directory name, and the ssh quoting. `.agents/commands/deploy.md` describes the flow (updated version is not in the
   recovered copy; its final text is in transcript `7c93f65a...`).
5. `docs/plan/skin-milionar/060-widgets.md` - the recovered version lacks sections 7-9 (result of F2, loading order and
   freshness, first screen from skin strings). They can be recovered from the Bash output / python append commands in transcript
   `7c93f65a...` (search for `## 8. Loading order` and `## 9. First screen`).
6. `scripts/library_harness/test_performance_profile.py`, `test_row_performance.py`, `test_appearance.py`,
   `scripts/skin_harness/test_refresh_service.py`, `test_refresh_hooks.py`, `test_installer_performance.py`: edited by Python
   patches on 2026-10-04 (new revision/skin-string URL contract, `getLanguage`, `provider_keys`, warm/startrows hooks,
   packaging policy = shipped unchanged). The base versions come from Codex; the patches are in transcript `7c93f65a...`.
7. New files of 2026-10-04 that exist only in the transcript `7c93f65a...` (created by `cat > file <<EOF` or `Write`):
   `scripts/skin_harness/test_warm.py`, `test_startrows.py`, `repository/repository.milionar/addon.xml` + `icon.png` (256 px copy of
   `resources/media/brand/milionar-mark.png`), `scripts/skin_harness/gen_start.py`, `docs/plan/recovery/*`.
8. `scripts/library_harness/stubs.py`, `fixtures` and `make_*` helpers, `scripts/skin_harness/{baseline.py,deploy_check.py,
   test_*.py,screens.json}`, `scripts/dialog_harness/*` (newer than 2026-09-27, including the live listener client), `.agents/rules/*`,
   `.agents/tests/*`, `.agents/state/skin_deploy.json` (`{"version": "1.3.17", "hash": ...}`; can be regenerated by
   `deploy_check.py record`), `docs/plan/*` index files: sources are the Codex sessions (3.2).

## 6. Verification checklist after restoring

- `python3 -m py_compile` on every restored `.py`; `xmllint --noout` on every XML; `sh -n scripts/build_zip.sh`.
- `python3 scripts/skin_harness/gen_slots.py` and `gen_start.py` regenerate byte-identical XML.
- Unit tests (offline, no Kodi): `scripts/skin_harness/test_installer_performance.py`, `test_refresh_service.py`,
  `test_refresh_hooks.py`, `test_warm.py`, `test_startrows.py`; `scripts/library_harness/test_*.py` (some need `fixtures/` that are
  git-ignored and regenerated by `make_fixtures.py` / `make_media.py`).
- `python3 scripts/release.py build` must produce a ZIP of about 5 MB / 440 files without errors (never run `publish` before the
  user asks).
- Dev Kodi: `python3 scripts/dialog_harness/kodi_live.py status` (needs the dev listener from `wcs/devtools/harness_service.py`
  wired into `service.py`; the installed `service.py` is the release without it: re-add `run_dev_harness()` per the transcripts).
  Do not install a release ZIP over this folder.
- `addons/skin.milionar` is a symlink to `resources/skin.milionar`: check that `resources/skin.milionar` has `fonts/`,
  `extras/`, `media/Textures.xbt`-equivalents (loose `media/*.png` for the dev symlink mode!) and `playlists/`; the release does not
  ship these, so the dev copy must be rebuilt (see 7).

## 7. Things the release does NOT contain and the dev tree needs

- Skin dev assets: loose Estuary textures `resources/skin.milionar/media/**` (688 files = the names in the system Estuary
  `Textures.xbt`; copy them from the Kodi.app Estuary source if available, or extract/decode the `.xbt`), `fonts/*.ttf`,
  `extras/backgrounds/*.jpg`, `extras/home-images/*`, `themes/*`, `resources/{icon,fanart,screenshot-*}`, `LICENSE.txt`.
  Estuary source reference: tag `21.3-Omega` of `xbmc/xbmc` (`addons/skin.estuary`), the fork rules are in
  `docs/plan/skin-milionar/030-fork.md`.
- The skin is a fork of Estuary 4.0.0; `scripts/skin_harness/baseline.py difftree` compares it with the tag.
- Images unreferenced by the code but kept in the tree (generated textures, `resources/media/screenshots/`); the generators in
  `resources/media/*.py` recreate most of them.

## 8. After the recovery (so it cannot happen again)

1. `git init`, commit, and push to a private remote (GitHub/GitLab) or at least `git bundle` to a second disk.
2. Add a daily backup of the folder (rsync to `~/Documents/...` is not enough: disk almost full; use an external disk,
   iCloud Drive excluded folders, or `git push`).
3. Warn in `AGENTS.md`: "the working tree is the installed addon: never uninstall/update the addon from the repository in this
   Kodi; use another Kodi profile/device for install tests (the Wine Kodi on this Mac is such a device)".
4. Consider moving the development tree out of `addons/` and symlinking it into `addons/` (the symlink is the only thing that a
   Kodi uninstall can delete).

## 9. Short description of the project (for the agent who has not seen it)

Kodi 21 video addon `plugin.video.milionar` (Python plugin + service + WindowXML dialogs + TMDb/CSFD metadata + Webshare/Kraska/
StreamCinema streaming + AI recommendations + the "Chcete být milionářem" quiz) and the bundled skin `skin.milionar` (Estuary
fork). Key code: `wcs/` (router, ui dialogs, ai, games, playback, library2 = the addon's own library on SQLite, skin = widgets,
installer, warm-up, first-screen rows, vinyl), `resources/skins/Default/1080i/` (dialogs), `resources/skin.milionar/` (the
skin). The dev environment: macOS Kodi 21.3, GUI 2560x1440, log `~/Library/Logs/kodi.log`, addon data in
`~/Library/Application Support/Kodi/userdata/addon_data/plugin.video.milionar/` (settings with API keys: never print or commit),
no live LLM/TTS calls without the user's request. Chat language with the user: Czech, short and factual; the user's rules:
never start work before the user says so after a discussion; always give a recommendation with each question; never break
anything that works; deploy only through `scripts/release.py` when asked.

Release state when the tree was lost: addon 2.1.26, skin 1.3.17, repository `https://hosting.pilsfree.net/chudy/kodi/repo/`.
Main changes of the last days: faithful release build, Kodi repository on the hosting, accent colour list in the skin
settings ("Milionář" section), reuselanguageinvoker, first screen from skin strings, off-screen warm-up of the other
Home sections, persisted row revisions, placeholder playlist for closed sections. Open discussion items: migration of the old
addon's lists (make it silent/automatic and non-blocking, drop the settings reset), converting the other Home pages to the
skin-strings approach after the user tested the first one.
