@davmash/bygone 0.9.7 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. package/CHANGELOG.md +30 -1
  2. package/README.md +74 -1
  3. package/cli/commandSpec.js +2 -0
  4. package/cli/completions.js +3 -3
  5. package/cli/present.js +28 -10
  6. package/cli/tour.js +22 -1
  7. package/cli/tourExport.js +147 -0
  8. package/cli/tourFile.js +109 -4
  9. package/cli/tourHistory.js +31 -1
  10. package/completions/_bygone +1 -1
  11. package/completions/bygone +1 -1
  12. package/completions/bygone.fish +1 -1
  13. package/docs/change-tour-format.md +86 -67
  14. package/docs/explore.md +14 -3
  15. package/docs/generating-change-tours.md +84 -46
  16. package/docs/present.md +103 -14
  17. package/docs/product-surface.md +19 -8
  18. package/docs/sharing-tours.md +95 -0
  19. package/docs/visual-walkthrough/README.md +89 -0
  20. package/docs/visual-walkthrough/build-tour.mjs +54 -0
  21. package/docs/visual-walkthrough/capture-desktop.cjs +42 -0
  22. package/docs/visual-walkthrough/capture-desktop.mjs +21 -0
  23. package/docs/visual-walkthrough/captures.md +49 -0
  24. package/docs/visual-walkthrough/create-demo.mjs +57 -0
  25. package/docs/visual-walkthrough/deconstructed-demo.bygone +100 -0
  26. package/docs/visual-walkthrough/images/01-two-files.png +0 -0
  27. package/docs/visual-walkthrough/images/02-many-panels.png +0 -0
  28. package/docs/visual-walkthrough/images/03-directories.png +0 -0
  29. package/docs/visual-walkthrough/images/04-search.png +0 -0
  30. package/docs/visual-walkthrough/images/05-repository-history.png +0 -0
  31. package/docs/visual-walkthrough/images/06-file-history.png +0 -0
  32. package/docs/visual-walkthrough/images/07-branch-review.png +0 -0
  33. package/docs/visual-walkthrough/images/08-tour-reader.png +0 -0
  34. package/docs/visual-walkthrough/images/09-focused-step.png +0 -0
  35. package/docs/visual-walkthrough/images/10-deconstructed.png +0 -0
  36. package/docs/visual-walkthrough/images/11-exploration.png +0 -0
  37. package/docs/visual-walkthrough/images/12-authoring.png +0 -0
  38. package/docs/visual-walkthrough/images/13-export.png +0 -0
  39. package/docs/visual-walkthrough/images/14-vscode.png +0 -0
  40. package/docs/visual-walkthrough/images/15-cli.png +0 -0
  41. package/docs/visual-walkthrough/narrative.md +134 -0
  42. package/docs/visual-walkthrough/outline.md +52 -0
  43. package/docs/visual-walkthrough/walkthrough.bygone +340 -0
  44. package/docs/walkthrough.md +6 -101
  45. package/examples/bygone-history.bygone +11 -44
  46. package/examples/marker-focus.bygone +116 -0
  47. package/examples/navigation-lab.bygone.yaml +401 -336
  48. package/examples/tour-orientation.bygone +349 -0
  49. package/media/diff.worker.js +13 -3
  50. package/media/webview.css +1 -1
  51. package/media/webview.js +394 -319
  52. package/out/changeTour.js +865 -397
  53. package/out/deepLink.js +167 -0
  54. package/out/historyDirectory.js +66 -0
  55. package/out/standalone-main.js +20515 -16822
  56. package/out/tourCoverage.js +850 -386
  57. package/out/tourDocument.js +97 -0
  58. package/package.json +1 -1
  59. package/schemas/change-tour-source.schema.json +91 -64
  60. package/skills/pr-tour-guide/SKILL.md +144 -128
  61. package/skills/pr-tour-guide/references/expectations-and-feedback.md +57 -0
  62. package/standalone/index.html +10 -25
  63. package/web/export-bootstrap.js +62 -0
  64. package/web/export-licenses.txt +78 -0
  65. package/web/export-runtime.json +12 -0
  66. package/web/index.html +54 -47
  67. package/web/presenter.css +337 -176
  68. package/web/web-host.js +239 -137
package/docs/present.md CHANGED
@@ -16,10 +16,10 @@ source evidence while keeping the complete changed-file set available.
16
16
 
17
17
  The left navigator switches directly among **Tour**, **Files**, and **Commits**;
18
18
  only one of those lists is visible at a time. The Tour outline has independently
19
- collapsible chapters and scenes; selecting a title jumps to that reading stop
19
+ collapsible chapters and scenes; selecting a title jumps to its reading stop
20
20
  without changing which sections are expanded.
21
21
 
22
- The reading panel flows continuously through the tour title, chapters, scene
22
+ The reading panel flows continuously through the tour title, chapter previews, scene
23
23
  overviews, and steps. Scroll the narrative or use keyboard navigation to move
24
24
  through that order; the corresponding code evidence follows. Scrolling the code
25
25
  does not advance the narrative. Each scene overview is a distinct stop with its
@@ -27,6 +27,10 @@ supporting points and takeaway. Each step keeps a collapsed **Scene context**
27
27
  disclosure above its title and explanation. Expanding that disclosure does not
28
28
  move the reading position.
29
29
 
30
+ Chapters without an authored `summary` remain navigation headings and are
31
+ skipped as reading and narration stops. Selecting their heading or opening an
32
+ older chapter link takes the reader to the first scene.
33
+
30
34
  A direct link to a step opens that step immediately. The header reports the
31
35
  current position as `Scene N of M · Step N of M`, or identifies the overview.
32
36
  The reading panel scrolls within a bounded area above the evidence; no Start,
@@ -54,16 +58,54 @@ code the author anchored; it does not measure your reading progress. The
54
58
  header shows your current step. Tour search is likewise disclosed on demand or
55
59
  opened by `Cmd/Ctrl+Shift+F`.
56
60
 
61
+ Authored v5 tours can show their purpose, scope, and estimated reading time in
62
+ **Tour details**. Expand **Assumed familiarity** for codebase and language
63
+ experience, reading demand, and prerequisites. Audience details are optional
64
+ and specific to each independently authored mode.
65
+
66
+ The opening states the expected behavior and its important boundary; the
67
+ conclusion summarizes what the evidence established and what remains unresolved.
68
+ These are authored explanations to evaluate against the code and requirements.
69
+
70
+ Use **Explain this** or **Question this change** while reading to capture a
71
+ question with the active tour's opening, current passage, comparison, and focused
72
+ evidence. Review the captured context, then **Copy request** and paste it into your coding agent.
73
+ Nothing is sent automatically. If clipboard access fails, the request remains
74
+ selectable for manual copying. The agent should investigate whether code,
75
+ explanation, a design decision, missing evidence, or the viewer needs repair.
76
+
57
77
  Generated overview ranking is deterministic for the resolved Git object IDs.
58
78
  It never hides files and does not invent an entry point for a test-only,
59
79
  lockfile-only, binary, or generated-only change. Authored tours keep their
60
80
  authored first scene and order.
61
81
 
82
+ For desktop section links and portable Minimal/Full HTML snapshots, see
83
+ [Links and portable HTML tours](sharing-tours.md).
84
+
85
+ Opening a version 1, 2, or 3 authored tour in Desktop offers **Convert and open
86
+ copy** by default. This saves a v4 copy beside the original (for example,
87
+ `demo.v4.bygone`) without overwriting either the original or an existing copy.
88
+ Cancel leaves the current view unchanged. The same offer appears when selecting
89
+ a tour for HTML export; browser uploads ask before converting and download a copy
90
+ after opening it.
91
+
92
+ Conversion preserves authored IDs and revision references, so section links keep
93
+ their targets. Review notes become a **Legacy review notes** appendix in the last
94
+ authored step or stage of each available tour. The appendix includes readable notes,
95
+ recorded revision IDs, evidence references, and next checks. Unrecognized review
96
+ fields are retained verbatim in the flow. Resolvable walkthrough references link back to their steps. The notes
97
+ are labeled as imported, not revalidated against potentially moving branches.
98
+ YAML comments and formatting are not copied. Conversion
99
+ stops with a specific validation error if the tour needs manual changes, such as
100
+ a v1 synthetic-only root scene without the real revision evidence required in v4.
101
+ Noninteractive CLI validation and compilation continue to require a supported
102
+ source; open retired v3 sources in Desktop to convert them first.
103
+
62
104
  ## Explore and follow tours
63
105
 
64
- Version 2 and 3 presentations expose **History**, **Compare**, and the available
106
+ Version 2 and 4 presentations expose **History**, **Compare**, and the available
65
107
  authored tours as direct mode buttons.
66
- Independent Historical and Deconstructed tours require version 3:
108
+ Independent Historical and Deconstructed tours require version 4:
67
109
 
68
110
  - **History** uses all commits reachable from the presentation's head, in stable
69
111
  topological order, including commits that did not change the current file.
@@ -77,22 +119,24 @@ Independent Historical and Deconstructed tours require version 3:
77
119
  the active revision with its parent or the review base.
78
120
  - **Compare** shows one panel per selected revision, oldest to newest, with a
79
121
  diff between each adjacent pair. The Commit navigator remains available for
80
- editing a draft selection; **Update comparison** applies it. Activating a loaded revision focuses its
81
- panel. **Compare selected** includes all changed files. Parent/base shortcuts
122
+ editing a draft selection; **Apply** updates the displayed comparison. It is
123
+ disabled when the selection already matches. Activating a loaded revision
124
+ focuses its panel. **Compare** includes all changed files. Parent/base shortcuts
82
125
  stay on the current file; **Show all changed files** expands the same range.
83
126
  **Final diff** selects the review base
84
127
  and head across all changed files.
85
128
 
86
129
  All modes share the expanded **Commits** navigator. Check two or more revisions,
87
- then choose **Compare selected** (or **Update comparison** in Compare).
130
+ then choose **Compare** (or **Apply** in Compare).
88
131
  Checkboxes edit a shared draft without reloading panels or leaving the tour.
89
132
  Numbered badges and highlights identify loaded real revisions independently of
90
133
  that draft. A dot marks commits that changed the current file, following renames;
91
134
  the **Tour** tag identifies commits in the authored range. Synthetic explanation
92
135
  stages are not labeled as Git revisions. Parent/base revisions outside the
93
136
  commit list appear as labeled extra rows.
137
+ The **Selection actions** (•••) menu holds the shortcuts and selection tools.
94
138
  **Clear selection** unchecks draft revisions without changing modes or panels;
95
- **Reset selection** selects the real revisions currently loaded in the workspace.
139
+ **Select displayed revisions** selects the real revisions currently loaded in the workspace.
96
140
 
97
141
  - **Historical tour** explains actual revision states, including intermediate
98
142
  changes, updates, and reverts. It retains chapters, scenes, steps, and narration.
@@ -133,7 +177,7 @@ text is spoken so the highlighted sentence remains visible.
133
177
  - Existing Previous and Next controls move through the same scene/step order
134
178
  used by continuous narration.
135
179
  - Choose any device voice exposed by the browser and a speed from 0.75× to
136
- 1.5×. Bygone stores those preferences locally and returns to the system
180
+ 2×. Bygone stores those preferences locally and returns to the system
137
181
  default if a selected voice disappears.
138
182
  - The visible sentence is highlighted while it is spoken. Pausing retains a
139
183
  distinct paused highlight without moving keyboard focus.
@@ -163,10 +207,9 @@ conversation. Those remain separate from the offline, device-first baseline.
163
207
  Tour content is read-only. Author or revise the YAML and recompile it rather
164
208
  than editing historical or synthetic panels in the presenter.
165
209
 
166
- Version 3 authored tours may expose a separate, read-only **Review notes** panel
167
- for evidence-linked concepts, boundaries, tradeoffs, and open questions. Scene
168
- and step narrative should still explain the implemented change and the tradeoffs
169
- supported by its evidence.
210
+ Scene and step narrative explain the implemented change, concepts, boundaries,
211
+ and tradeoffs beside their evidence. Label unresolved questions explicitly and
212
+ state the next check that would resolve them.
170
213
 
171
214
  ## Authoring workflow
172
215
 
@@ -186,7 +229,7 @@ synthetic deconstructed stages.
186
229
 
187
230
  ### Directory evidence in an Overview
188
231
 
189
- In version 3, an authored scene can show a directory comparison in its Overview. Open a file
232
+ In version 4, an authored scene can show a directory comparison in its Overview. Open a file
190
233
  to inspect the same comparison while keeping the overview text, narration, and
191
234
  reading position. The **Overview** breadcrumb returns to its file tree;
192
235
  scroll through the narrative or select a step in the outline to continue the
@@ -200,3 +243,49 @@ Walkthrough scenes use the review's base-to-head comparison and the tour files,
200
243
  retaining omitted-file entries. Any scene type can limit the overview to a
201
244
  subdirectory. While browsing a file, `Overview › file path` shows where you are,
202
245
  with a reminder that narration still describes the overview.
246
+
247
+ ## Screenshot evidence
248
+
249
+ A walkthrough step can display a committed PNG in place of its code comparison:
250
+
251
+ ```yaml
252
+ - id: compare-window
253
+ title: Read the comparison
254
+ body: Blue regions pair corresponding changes across the gutter.
255
+ focus: guide-paragraph
256
+ image:
257
+ file: docs/images/comparison.png
258
+ revision: head
259
+ alt: Two code panes with blue paired changes and green additions.
260
+ ```
261
+
262
+ The required `focus` still anchors the explanation to text in the tour's Git
263
+ range. `image.revision` selects the comparison's merge base (`base`) or head
264
+ (`head`). Compilation reads that Git blob, ignoring working-tree edits, and
265
+ embeds its bytes in the manifest and HTML exports. Use repository-relative paths
266
+ and meaningful alt text. PNGs are limited to 8 MiB, 16,384 pixels per dimension,
267
+ and 64 megapixels. **Expand image** opens an enlarged view; Escape closes it.
268
+ Returning to a code step, file, or comparison restores the regular workspace.
269
+
270
+ Tours made entirely of image steps start on Intro with a route through their
271
+ scenes. Next/Previous visits Intro, image steps, and the conclusion when authored,
272
+ skipping chapter and scene headings. Selecting a chapter or scene displays its
273
+ first image. The Intro outline entry returns to the route. Mixed code/image tours
274
+ retain scene introductions. Intro and Conclusion use the full reading area;
275
+ entering evidence restores the saved prose/code split.
276
+
277
+ See the [visual walkthrough](visual-walkthrough/README.md) for a complete example.
278
+
279
+
280
+ The Intro explains what the change does and gives a short route through the
281
+ chapters. Chapters group related questions, scenes explain one question, and
282
+ steps connect claims to evidence. Chapter, scene, and step lists use simple
283
+ numbers for reference; reading headings and narration use plain titles.
284
+
285
+ Chapter introductions show a brief authored preview and links to their scenes;
286
+ narration reads the preview rather than the list of scene titles. The main explanation keeps the reasons
287
+ for the change beside its evidence. Comparison captions identify the displayed
288
+ revisions or constructed stages; a chapter or scene boundary does not itself
289
+ mean the comparison changed. Intro, chapter, and Conclusion passages fill the
290
+ reading area. Exploring Files restores the prose/code split, and “Return to
291
+ passage” restores the full-height passage.
@@ -23,9 +23,15 @@ renderer does not make every workflow appropriate in every host.
23
23
 
24
24
  ## Shared workspace
25
25
 
26
+ Window typography and chrome colors live in `media/windowTheme.css`, bundled
27
+ into the shared renderer for Desktop, browser tours, HTML exports, and VS Code.
28
+ Tour presentation styles consume those tokens rather than owning a separate
29
+ palette. UI text uses the system sans-serif font; source code keeps its editor
30
+ font. VS Code supplies its host theme and font through the existing variables.
31
+
26
32
  Desktop Explore uses **History · Compare · Historical tour · Deconstructed
27
- tour** without requiring an authored document. Missing tour buttons open an
28
- short, editable prompt referencing the bundled v3 tour skill and the workspace's
33
+ tour** without requiring an authored document. Missing tour buttons open a
34
+ short, editable prompt requesting a v5 tour and referencing the bundled skill and the workspace's
29
35
  repository, revisions, and selected paths. Read instructions exposes the Markdown;
30
36
  Save an editable copy and Use my copy support user-owned forks. Desktop prompts
31
37
  reference a real filesystem path outside the application archive. Browser prompts
@@ -36,14 +42,14 @@ when the selected instructions change. No model request or shell command runs
36
42
  automatically. Prompt ranges use exact committed identities or explicitly ask for
37
43
  a range choice. Existing tour loading remains available.
38
44
 
39
- **Open in History** resolves the comparison's Git ownership and path scope.
45
+ **History** resolves the comparison's Git ownership and path scope.
40
46
  Its commit axis includes the selected revisions and their ancestry, including
41
47
  commits that did not change the active file. File-change markers and numbered
42
48
  active panels are distinct from unapplied comparison checkboxes. Clear clears
43
49
  the draft without changing modes. History retains add/remove-panel controls.
44
- **Back to comparison** restores the originating ordered comparison and its
45
- navigation. Mode transitions use the native unsaved-edit guard; writable
46
- working files remain writable and explicit read-only launches stay read-only.
50
+ **Compare** restores the retained comparison and its navigation. Mode transitions
51
+ use the native unsaved-edit guard; writable working files remain writable and
52
+ explicit read-only launches stay read-only.
47
53
 
48
54
  Opening an authored document from this workspace keeps the same native window.
49
55
  A different repository, range, or scoped context requires confirmation; the
@@ -72,6 +78,7 @@ prompt behavior, and the normal-mode controls.
72
78
  | Explore a branch change | Git → Review Branch Change; `bygone review` | Deterministic start-here overview plus the complete merge-base-to-tip inventory | Read-only review snapshots; attention is a reading-order hint, viewed state remains session-local, and dirty state is reported rather than included | Core | attention-model, branch comparison, review-path, and desktop menu tests |
73
79
  | Search comparison code | Edit → Find or Search Comparison | Active, visible, all loaded panels, unopened changed text snapshots, or one file's Git history | Search is read-only; history distinguishes content occurrence from introduction/removal; Replace requires the active writable model | Core | find, comparison-search, change-set-search, and history-search tests |
74
80
  | Search or safely replace in a filesystem tree | Edit → Search in Files; explicit directory root | System ripgrep 14+ with include/exclude, hidden, ignore, and result-limit controls | Search is read-only and cancellable; completed case-sensitive literal searches can build an exclusion-aware, revalidated, atomic replacement preview with guarded undo | Optional system capability | repository search/replace contracts, benchmark, and host-protocol tests |
81
+ | Choose visible panel count | Visible panels: 2 / 3 / 4 / Fit | Equal-width textual revision panels; one active adjacent comparison | Saved locally; Fit has no count cap beyond available panels and readable width; narrower windows show fewer panels without overwriting the choice; visible Find searches the whole group | Core | focused-strip layout and native density smoke tests |
75
82
  | Move through a multi-panel comparison | Strip buttons, panel headers, gutters, wheel, or `Alt+Arrow` | Active panel and adjacent pair | Does not change source identity | Core | focused-strip controller and standalone smoke tests |
76
83
  | Search an authored tour | Presenter search or `Cmd/Ctrl+Shift+F` | Authored narrative plus compiled base/head code snapshots | Read-only; narrative hits navigate scenes/steps and code hits preserve Return to tour | Core | tour-search and presenter-host tests |
77
84
 
@@ -87,8 +94,7 @@ appear only when Electron is not packaged.
87
94
  | --- | --- | --- | --- | --- | --- |
88
95
  | Explain a branch automatically | Present → Present Current Branch or Present Branch or Ref; `bygone present` | Committed merge-base-to-tip range with a deterministic overview first scene and complete Files navigator | Read-only; authored tours retain their authored order | Core | attention-model, presentation launch, generated-tour, and desktop menu tests |
89
96
  | Open an authored walkthrough | Present → Open Authored Tour; `bygone present --tour`; VS Code hand-off | Manifest range, scene, step, exact source anchor | Read-only | Core | reproducible example and tour validation tests |
90
- | Read optional authored review notes | Browser or desktop Present shows an opt-in **Review notes** button when a v3 manifest includes `review` | `baseOid`/`headOid` pins and evidence links into the Final walkthrough | Immutable range; read-only panel; no scores or persisted reviewer state | Local prototype | `examples/bygone-history.bygone`, `test/reviewNotes.test.js`, and manual browser navigation check |
91
- | Assess authored tour coverage | Coverage indicators in the Present sidebar | Distinct hunks referenced by authored walkthrough anchors; v2/v3 Final walkthrough coverage remains separate from deconstructed Explanation assignment completeness | Read-only authoring diagnostics; generated tours have no authored coverage metric | Advanced authoring | v1/v2/v3 coverage and presenter-host tests |
97
+ | Assess authored tour coverage | Coverage indicators in the Present sidebar | Distinct hunks referenced by authored walkthrough anchors; v2/v4 Final walkthrough coverage remains separate from deconstructed Explanation assignment completeness | Read-only authoring diagnostics; generated tours have no authored coverage metric | Advanced authoring | v1/v2/v4 coverage and presenter-host tests |
92
98
  | Listen to a generated or authored tour | Narrative Listen controls; Present → Listen to Tour | Existing manifest narrative segmented locally by scene/step and visible sentence | Read-only device TTS; voice/rate preferences remain local; continuous playback follows tour navigation and direct exploration pauses it | Core | narration model/controller and presenter-host tests |
93
99
  | Explain a real stack | `stacked-diff` scene | Exact real Git revisions per panel | Read-only | Advanced | `examples/stacked-diff.bygone` |
94
100
  | Explain a change in conceptual stages | `deconstructed-diff` scene | Explicitly labeled synthetic explanation stages backed by exact hunk IDs | Read-only | Advanced/experimental authoring | `examples/deconstructed-diff.bygone` |
@@ -139,6 +145,11 @@ VS Code's native Search rather than another bundled ripgrep process.
139
145
 
140
146
  ## Provenance and mutability vocabulary
141
147
 
148
+ Two-panel comparisons show immutable status beside the file summary and the
149
+ editing toggle in the existing controls row when editing is available. Read-only
150
+ status does not reserve a separate toolbar row. Multi-panel comparisons retain
151
+ their per-panel provenance, including mixed writable and snapshot panels.
152
+
142
153
  Use these labels consistently:
143
154
 
144
155
  - **Writable file:** filesystem content and a live `WORKTREE` column participating in dirty, undo,
@@ -0,0 +1,95 @@
1
+ # Links and portable HTML tours
2
+
3
+ ## Local desktop links
4
+
5
+ Each title, chapter, scene, and step has a chain icon beside its heading, shown
6
+ on hover or keyboard focus (always visible on touch screens). In a saved local
7
+ tour it copies a `bygone://open/v1` link to that document, authored mode, and
8
+ section ID. Open it with the installed desktop app, or choose **File → Open
9
+ Bygone Link from Clipboard**. Links require the repository at the same local
10
+ path; they do not clone repositories or find another checkout automatically.
11
+ Tours saved outside the repository are supported: their links include the
12
+ tour's local file URL separately from the repository. The tour must remain at
13
+ that path, but the original presentation server does not need to be running.
14
+
15
+ These document links open the **current saved document**. A branch named in the
16
+ document may have moved since the link was copied. Use an HTML export when the
17
+ recipient must see a fixed snapshot. Missing documents, modes, or section IDs
18
+ produce an error rather than choosing a different step. Tour format v3 is
19
+ retired: remove its `review` block, set `version: 4`, and recompile.
20
+
21
+ **File → Copy Local Comparison Link** copies a two-revision comparison using
22
+ full commit IDs in panel order. These links preserve the evidence even when
23
+ branches move. The URL also supports an optional repository-relative `file`,
24
+ selected `revision`, and one-based `line`. Missing commits, files, or lines fail
25
+ before replacing the current comparison. Links open comparisons read-only.
26
+
27
+ The versioned URL fields are:
28
+
29
+ - Common: `kind=tour|compare`, `repo=<local file URL>`.
30
+ - Tour: `tour=<repository-relative document path or local file URL>`, `mode=historical|deconstructed`,
31
+ `part=title|chapter|scene|step`, and the matching `chapter`, `scene`, or
32
+ `scene` plus `step` IDs.
33
+ - Comparison: two ordered `rev=<full commit ID>` fields, with optional `file`,
34
+ `revision`, and `line`. A line requires a file and selected revision.
35
+
36
+ ## Export a saved tour
37
+
38
+ Choose **File → Export Tour as HTML…**, or run:
39
+
40
+ ```sh
41
+ bygone tour export path/to/tour.bygone --output tour.html
42
+ bygone tour export path/to/tour.bygone --output tour-full.html --profile full
43
+ ```
44
+
45
+ Existing output files require `--overwrite`. Export reads the saved tour and
46
+ committed Git evidence. It freezes referenced revisions once, packages all
47
+ authored modes, and leaves the source file unchanged.
48
+
49
+ | Profile | Included evidence | Exploration |
50
+ | --- | --- | --- |
51
+ | Minimal (default) | Authored modes and full files needed for the endpoint comparison | Tour navigation and fixed base → head comparison |
52
+ | Full | Minimal plus a bounded Git commit graph and scoped file snapshots | Included history and comparisons among included revisions |
53
+
54
+ Full includes the range's merge base, commits between it and the head, and
55
+ explicitly referenced tour revisions. Its path scope includes changed paths,
56
+ rename predecessors, and tour evidence paths. It preserves intermediate changes
57
+ that were reverted before the head. This is a read-only, Git-derived snapshot,
58
+ not a cloneable repository or an arbitrary Git command environment. Parents
59
+ outside the included set are unavailable. History diffs use the first parent;
60
+ comparisons use exact paths, so renames appear as deletion and addition.
61
+
62
+ Both profiles can contain full surrounding and deleted source code. Full also
63
+ includes commit authors and email addresses. Local repository bindings are
64
+ removed, but authored prose and paths remain. Inspect the output before sharing.
65
+ **Tour details** reports the packaged evidence and profile boundaries.
66
+
67
+ Initial Full limits are 256 revisions, 4,096 paths, 2 MiB per text file, and
68
+ 64 KiB per line; the final HTML limit is 128 MiB. Binary/non-UTF-8 files,
69
+ submodules, Git LFS objects, and oversized files have explicit omission reasons.
70
+ Queries beyond the packaged scope fail rather than fetching replacement evidence.
71
+
72
+ ## Viewer and internet access
73
+
74
+ The default embeds the viewer, styles, workers, licenses, and evidence in one
75
+ HTML file. Open it directly in a browser; no Bygone installation or local server
76
+ is required. Editing, local repository operations, and link previews are
77
+ unavailable. Narration uses only locally available system voices.
78
+
79
+ A smaller CDN variant can load viewer assets from an exact npm release on
80
+ jsDelivr. Evidence still lives in the HTML. It displays an internet-required
81
+ message and checks each asset against its build-time SHA-256 digest. There is no
82
+ fallback to a newer runtime. The matching export-enabled npm release must be
83
+ published first; ordinary exports do not assume that release exists.
84
+
85
+ For a verified published build, opt in with `--runtime cdn --runtime-base
86
+ https://cdn.jsdelivr.net/npm/@davmash/bygone@<exact-version>/`. The version must
87
+ match the exporting build. A missing, modified, or inaccessible asset produces a
88
+ loading error; an embedded export avoids that network dependency.
89
+
90
+ **Copy link** inside an export copies a browser URL with a semantic fragment.
91
+ Share the HTML separately. When the recipient stores it elsewhere, append the
92
+ fragment (starting with `#location=1`) to their file or hosted URL. Title,
93
+ chapter, scene, and step targets are mode-specific; unknown targets produce an
94
+ error. Exported evidence has a content digest for corruption detection, not a
95
+ digital signature or proof of authorship.
@@ -0,0 +1,89 @@
1
+ # Bygone, one screen at a time
2
+
3
+ A 15-screen guided tour of comparisons, multiple panels, directories, search,
4
+ repository and file history, branch review, authored tours, explanation stages,
5
+ exploration, authoring, sharing, VS Code, and the CLI.
6
+
7
+ ## Open the tour
8
+
9
+ From this checkout, build and use its CLI so the new image-step renderer is
10
+ available. The installed 0.9.9 release predates this feature.
11
+
12
+ ```sh
13
+ npm run compile
14
+ BYGONE_FORCE_BUNDLED=1 node bin/bygone.js present --tour docs/visual-walkthrough/walkthrough.bygone
15
+ ```
16
+
17
+ The command opens a local browser presentation on **Two files, one visual
18
+ comparison**. Read down the narrative or select each step in the outline;
19
+ each step replaces the evidence area with its screenshot. Next/Previous moves
20
+ through the 15 images, skipping the structural headings as separate stops.
21
+ Chapter and scene links open their first image, without a file inventory.
22
+ **Expand image** makes the screenshot larger; Escape closes it. The controls
23
+ inside a screenshot are illustrative, not interactive.
24
+
25
+ With this branch's build installed, the equivalent command is:
26
+
27
+ ```sh
28
+ bygone -C /Users/davmash/code/bygone present --tour docs/visual-walkthrough/walkthrough.bygone
29
+ ```
30
+
31
+ ## Read or share without a presentation server
32
+
33
+ The [narrative](narrative.md) is the complete prose. Browse the
34
+ [screenshots](images/) alongside it, or export one portable HTML file:
35
+
36
+ ```sh
37
+ node bin/bygone.js tour export docs/visual-walkthrough/walkthrough.bygone --output /tmp/bygone-visual-walkthrough.html --profile minimal --runtime embedded
38
+ ```
39
+
40
+ Open that file in a browser. Its viewer and screenshots are embedded; it needs
41
+ neither internet nor a local repository. Use a fresh output path or add
42
+ `--overwrite` to regenerate it. Minimal is the useful default for this visual
43
+ guide; full export adds repository history that the screenshots do not need.
44
+
45
+ ## Maintain the guide
46
+
47
+ The [outline](outline.md) records the scope. The
48
+ [capture record](captures.md) identifies the real UI state behind each image
49
+ and explains how to regenerate the demonstration repository and desktop images.
50
+ The prose was revised against the actual captures before building the tour.
51
+ The screenshots are unannotated; the prose and alt text supply the callouts.
52
+
53
+ `walkthrough.bygone` pins the image and prose commit, so later working-tree edits
54
+ cannot silently change its evidence. To revise it:
55
+
56
+ 1. Edit the prose or recapture the images, inspect the results, and commit them.
57
+ 2. Set `head` in `build-tour.mjs` to that commit's full SHA. Keep the base before
58
+ the guide was added so its narrative anchors remain in the comparison.
59
+ 3. Run `node docs/visual-walkthrough/build-tour.mjs` from the repository root.
60
+ 4. Validate, compile, and inspect the presentation again:
61
+
62
+ ```sh
63
+ node bin/bygone.js tour validate docs/visual-walkthrough/walkthrough.bygone
64
+ node bin/bygone.js tour compile docs/visual-walkthrough/walkthrough.bygone --output /tmp/bygone-visual-walkthrough.json
65
+ ```
66
+
67
+ The repository keeps the PNG originals and authored source. Compiled manifests
68
+ and HTML duplicate the embedded images, so they are generated outside Git.
69
+
70
+ ## Verification
71
+
72
+ Checked on macOS on 2026-10-06:
73
+
74
+ - Validated and compiled the authored source: four arcs, 15 image steps.
75
+ - Inspected every capture, then loaded all 15 steps in both the live presentation
76
+ and the generated embedded HTML. The minimal HTML is approximately 24 MB.
77
+ - `npm test` passed, including the legacy suite and 136 Node tests.
78
+ - `npm run test:export-smoke` passed for ordinary tours and image evidence in
79
+ both Minimal and Full exports, with network requests blocked. It checks image
80
+ decoding, enlargement, Escape, Files → Return to tour, and code/Compare recovery.
81
+ - `npm run bundle:check` and `git diff --check` passed.
82
+ - ESLint passed for 142 checkout files with `tsconfigRootDir` explicitly set to
83
+ this repository. Plain `npm run lint` encounters an unrelated nested worktree
84
+ with another ESLint configuration; that worktree was excluded from this check.
85
+
86
+ Linux/Windows rendering, screen-reader interaction, and a packaged installation
87
+ of the new image renderer were not tested. The installed VS Code companion was
88
+ used for its screenshot; it was not rebuilt. The portable runtime was tested
89
+ embedded, not against a published CDN version.
@@ -0,0 +1,54 @@
1
+ // Rebuild prose from its pinned revision, never from an uncommitted draft.
2
+ import fs from 'node:fs';
3
+ import { execFileSync } from 'node:child_process';
4
+ const base = 'e431a208f5ad24e3fae1a22300a14fc7d041375f';
5
+ const head = '32bf8166cf6ae852fa801a540fe722b4070d5f4f';
6
+ const folder = 'docs/visual-walkthrough';
7
+ const prose = execFileSync('git', ['show', `${head}:${folder}/narrative.md`], { encoding: 'utf8' });
8
+ const ids = ['two-files', 'many-panels', 'directories', 'search', 'repository-history', 'file-history', 'branch-review', 'tour-reader', 'focused-step', 'deconstructed', 'exploration', 'authoring', 'export', 'vscode', 'cli'];
9
+ const alts = [
10
+ 'Two JavaScript files with paired blue changes, green additions, and gutter ribbons connecting the regions.',
11
+ 'Three of five JavaScript versions are visible, with Fit selected and the first adjacent pair active.',
12
+ 'The before and after directory trees align three modified files and one added changelog.',
13
+ 'A search for publish finds one result in each of the two visible comparison panes.',
14
+ 'The commit navigator marks two loaded revisions; the comparison shows CHANGELOG.md added in the newest commit.',
15
+ 'Two pinned release.js revisions show a new channel field and sorted return value beside the commit navigator.',
16
+ 'The branch overview recommends starting with release.yaml, paying attention to release.js, and shows four changed files.',
17
+ 'A tour outline and continuous narrative introduce a safer release plan above its changed-file overview.',
18
+ 'The Preview by default step sits under a sticky scene heading and highlights the dry-run code evidence below.',
19
+ 'Deconstructed tour stages show an explanation baseline beside the Carry every anchor stage, with focused TypeScript changes.',
20
+ 'The Files navigator selects release.yaml while the authored narrative remains above; Return to tour is visible.',
21
+ 'An authoring dialog contains an editable prompt, pinned review range, and a Read instructions button.',
22
+ 'An exported tour has Tour details expanded: minimal snapshot, no browsable history, embedded viewer, no internet required.',
23
+ 'VS Code hosts a read-only Bygone file history comparison next to the Explorer and source tabs.',
24
+ 'A VS Code terminal displays the CLI usage forms for comparison, history, review, presentation, validation, compilation, and export.'
25
+ ];
26
+ const summaries = [
27
+ 'Start with concrete files. The same visual language scales from two versions to directories and search.',
28
+ 'Add time to the comparison. Follow a path through commits or begin with the shape of a whole branch.',
29
+ 'A tour turns findings into a reading path while leaving room for exploration.',
30
+ 'Choose a sharing format and a host that fit the next reader’s question.'
31
+ ];
32
+ let index = 0;
33
+ const anchors = {};
34
+ const chapters = prose.split(/^## /m).slice(1).map((chapter, c) => {
35
+ const [title, ...sections] = chapter.split(/^### /m);
36
+ const chapterTitle = title.trim();
37
+ const steps = sections.map(section => {
38
+ const newline = section.indexOf('\n');
39
+ const title = section.slice(0, newline).trim();
40
+ const body = section.slice(newline).trim().replace(/\n(?!\n)/g, ' ');
41
+ const id = ids[index];
42
+ anchors[id] = { file: `${folder}/narrative.md`, revision: 'head', contains: `### ${title}` };
43
+ const image = { file: `${folder}/images/${String(index + 1).padStart(2, '0')}-${id}.png`, revision: 'head', alt: alts[index] };
44
+ index++;
45
+ return { id, title, body, focus: id, depth: 'explained', image };
46
+ });
47
+ return { id: `chapter-${c + 1}`, title: chapterTitle, scenes: [{
48
+ id: `arc-${c + 1}`, title: chapterTitle, summary: summaries[c], bullets: [], tags: ['visual-guide'],
49
+ takeaway: summaries[c], steps
50
+ }] };
51
+ });
52
+ if (index !== 15) throw new Error(`Expected 15 images; found ${index}`);
53
+ const tour = { version: 4, title: 'Bygone, one screen at a time', range: { base, head }, anchors, connections: [], chapters };
54
+ fs.writeFileSync(`${folder}/walkthrough.bygone`, JSON.stringify(tour, null, 2) + '\n');
@@ -0,0 +1,42 @@
1
+ // Capture the real development app, optionally exercising its existing controls.
2
+ // electron capture-desktop.cjs <output.png> <action> <Bygone arguments...>
3
+ const { app, Menu } = require('electron');
4
+ const fs = require('node:fs');
5
+ const path = require('node:path');
6
+ const [outputArg, action, ...args] = process.argv.slice(2);
7
+ const root = path.resolve(__dirname, '../..');
8
+ const output = path.resolve(outputArg);
9
+ const cwdIndex = args.indexOf('-C');
10
+ if (cwdIndex >= 0) { process.chdir(args[cwdIndex + 1]); args.splice(cwdIndex, 2); }
11
+ app.setPath('userData', fs.mkdtempSync('/tmp/bygone-walkthrough-capture-'));
12
+ process.argv = [process.argv[0], path.join(root, 'out/standalone-main.js'), '--window-width', '1440', '--window-height', '900', ...args];
13
+ const delay = ms => new Promise(resolve => setTimeout(resolve, ms));
14
+ const deadline = setTimeout(() => { console.error('Capture timed out'); app.exit(1); }, 60000);
15
+ app.on('browser-window-created', (_event, win) => {
16
+ win.webContents.once('did-finish-load', async () => {
17
+ try {
18
+ await delay(3500);
19
+ if (action === 'find') {
20
+ const find = items => items.find(i => i.label === 'Search Comparison…') || items.flatMap(i => i.submenu ? [find(i.submenu.items)] : []).find(Boolean);
21
+ const item = find(Menu.getApplicationMenu().items);
22
+ if (!item) throw new Error('Search menu missing');
23
+ item.click();
24
+ await delay(500);
25
+ await win.webContents.executeJavaScript(`(() => { const el = document.querySelector('.visible-search-input'); if (!el) throw new Error('Search input missing'); el.value = 'publish'; el.dispatchEvent(new Event('input', {bubbles:true})); })()`);
26
+ } else if (action === 'fit') {
27
+ await win.webContents.executeJavaScript(`(() => { const el = document.querySelector('[data-multi-visible-count]'); if (!el) throw new Error('Density control missing'); el.value = 'fit'; el.dispatchEvent(new Event('change', {bubbles:true})); })()`);
28
+ } else if (action === 'older') {
29
+ await win.webContents.executeJavaScript(`document.querySelector('#history-back').click()`);
30
+ } else if (action === 'author') {
31
+ await win.webContents.executeJavaScript(`document.querySelector('[data-workspace-mode="historical"]').click()`);
32
+ }
33
+ await delay(1500);
34
+ fs.mkdirSync(path.dirname(output), { recursive: true });
35
+ fs.writeFileSync(output, (await win.webContents.capturePage()).toPNG());
36
+ clearTimeout(deadline);
37
+ console.log(`Wrote ${output}`);
38
+ app.exit(0);
39
+ } catch (error) { console.error(error); app.exit(1); }
40
+ });
41
+ });
42
+ require(path.join(root, 'out/standalone-main.js'));
@@ -0,0 +1,21 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import { spawnSync } from 'node:child_process';
4
+ const root = path.resolve(process.argv[2] || '/tmp/bygone-visual-demo');
5
+ const { repo, revisions } = JSON.parse(fs.readFileSync(path.join(root, 'fixture.json')));
6
+ const output = 'docs/visual-walkthrough/images';
7
+ const captures = [
8
+ ['01-two-files', 'none', '--diff', `${root}/release-v1.js`, `${root}/release-v5.js`],
9
+ ['02-many-panels', 'fit', '--diff', ...[1,2,3,4,5].map(n => `${root}/release-v${n}.js`)],
10
+ ['03-directories', 'none', `${root}/before`, `${root}/after`],
11
+ ['04-search', 'find', '--diff', `${root}/release-v1.js`, `${root}/release-v5.js`],
12
+ ['05-repository-history', 'older', '--history', repo],
13
+ ['06-file-history', 'older', '--history', `${repo}/release.js`],
14
+ ['07-branch-review', 'none', '-C', repo, 'review', '--base', revisions[0]],
15
+ ['12-authoring', 'author', '-C', repo, 'review', '--base', revisions[0]],
16
+ ];
17
+ for (const [name, action, ...args] of captures) {
18
+ const result = spawnSync('node', ['scripts/run-electron.mjs', 'docs/visual-walkthrough/capture-desktop.cjs', `${output}/${name}.png`, action, ...args], { stdio: 'inherit' });
19
+ if (result.status !== 0) process.exit(result.status ?? 1);
20
+ }
21
+ /* global process */
@@ -0,0 +1,49 @@
1
+ # Capture record
2
+
3
+ Captured on macOS on 2026-10-06 from Bygone 0.9.9 (`e431a20`). The screenshots
4
+ are unretouched. Desktop captures use a 1440 × 900 window and retain Retina
5
+ resolution. Browser captures use a 1440 × 900 viewport, saved by the preview
6
+ host at 1280 × 800. VS Code captures retain its existing 1229 × 768 window.
7
+ The installed VS Code companion has different navigation chrome from Desktop;
8
+ the guide deliberately shows that distinction.
9
+
10
+ The small Parcel repository is original demonstration content, not a real
11
+ customer or private codebase. Generate it in a fresh temporary directory:
12
+
13
+ ```sh
14
+ node docs/visual-walkthrough/create-demo.mjs /tmp/bygone-visual-demo
15
+ npm run compile
16
+ node docs/visual-walkthrough/capture-desktop.mjs /tmp/bygone-visual-demo
17
+ ```
18
+
19
+ The desktop harness launches an isolated development app, invokes real controls,
20
+ and captures its web contents. Inspect regenerated captures before committing:
21
+ loading delays and host differences can otherwise produce blank screenshots.
22
+
23
+ | Image | Surface and capture state |
24
+ | --- | --- |
25
+ | 01 | Desktop: compare `release-v1.js` and `release-v5.js` |
26
+ | 02 | Desktop: compare all five versions; choose Visible panels → Fit |
27
+ | 03 | Desktop: compare the `before` and `after` directories (positional paths) |
28
+ | 04 | Desktop: two-file comparison; Search Comparison → `publish`, Visible panes |
29
+ | 05 | Desktop: repository history; Older commit once, showing added CHANGELOG |
30
+ | 06 | Desktop: `release.js` history; Older commit once |
31
+ | 07 | Desktop: review the fixture head against its first commit; Overview |
32
+ | 08 | Browser: present fixture `release.bygone`; initial document/scene overview |
33
+ | 09 | Browser: select Preview by default; scroll to the sticky scene heading |
34
+ | 10 | Browser: present `deconstructed-demo.bygone`; select Carry every anchor |
35
+ | 11 | Browser: from the fixture's first step, Files → release.yaml |
36
+ | 12 | Desktop: branch review → Historical tour, opening the missing-tour prompt |
37
+ | 13 | Browser: minimal embedded HTML export; first step; expand Tour details |
38
+ | 14 | VS Code: `src/workspaceHistory.ts` → Bygone: View Active File History |
39
+ | 15 | VS Code terminal: `node bin/bygone.js --help \| head -26` |
40
+
41
+ For browser captures, start `require('./cli/present').startPresentation(args,
42
+ repoRoot, process.cwd(), {open:false})` from Node in this checkout, then open the
43
+ returned localhost URL. The fixture tour uses its Parcel repository; the
44
+ checked-in deconstructed example uses this repository. Both contain pinned refs.
45
+
46
+ The portable example was produced with `tour export` using `--profile minimal
47
+ --runtime embedded`, then opened through a temporary static localhost server.
48
+ No external image or content service supplied these screenshots. No image
49
+ annotations were added: the guide's prose supplies the callouts.