@davmash/bygone 0.9.8 → 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 +21 -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 +85 -68
  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 +20514 -16821
  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 +332 -178
  68. package/web/web-host.js +239 -137
@@ -0,0 +1,57 @@
1
+ // Original, deterministic public fixture used by the visual walkthrough.
2
+ import { mkdirSync, writeFileSync, cpSync } from 'node:fs';
3
+ import { execFileSync } from 'node:child_process';
4
+ import path from 'node:path';
5
+ const root = path.resolve(process.argv[2] || '/tmp/bygone-visual-demo');
6
+ mkdirSync(root, { recursive: true });
7
+ const repo = path.join(root, 'parcel');
8
+ mkdirSync(repo);
9
+ const git = (...args) => execFileSync('git', args, { cwd: repo, encoding: 'utf8' }).trim();
10
+ git('init', '-b', 'main');
11
+ git('config', 'user.name', 'Bygone Demo');
12
+ git('config', 'user.email', 'demo@example.invalid');
13
+ const versions = [
14
+ `// Parcel — a small release planner\nexport function planRelease(packages) {\n const plan = [];\n\n for (const pkg of packages) {\n plan.push({\n name: pkg.name,\n version: pkg.version,\n publish: true,\n });\n }\n\n return plan;\n}\n`,
15
+ `// Parcel — a small release planner\nexport function planRelease(packages) {\n const plan = [];\n\n for (const pkg of packages) {\n if (pkg.private) continue;\n\n plan.push({\n name: pkg.name,\n version: pkg.version,\n publish: true,\n });\n }\n\n return plan;\n}\n`,
16
+ `// Parcel — a small release planner\nexport function planRelease(packages, options = {}) {\n const plan = [];\n const dryRun = options.dryRun ?? true;\n\n for (const pkg of packages) {\n if (pkg.private) continue;\n\n plan.push({\n name: pkg.name,\n version: pkg.version,\n publish: !dryRun,\n });\n }\n\n return plan;\n}\n`,
17
+ `// Parcel — a small release planner\nexport function planRelease(packages, options = {}) {\n const plan = [];\n const dryRun = options.dryRun ?? true;\n\n for (const pkg of packages) {\n if (pkg.private) continue;\n if (!pkg.version) {\n throw new Error('A release needs a version');\n }\n\n plan.push({\n name: pkg.name,\n version: pkg.version,\n publish: !dryRun,\n });\n }\n\n return plan;\n}\n`,
18
+ `// Parcel — a small release planner\nexport function planRelease(packages, options = {}) {\n const plan = [];\n const dryRun = options.dryRun ?? true;\n\n for (const pkg of packages) {\n if (pkg.private) continue;\n if (!pkg.version) {\n throw new Error('A release needs a version');\n }\n\n plan.push({\n name: pkg.name,\n version: pkg.version,\n publish: !dryRun,\n channel: options.channel ?? 'stable',\n });\n }\n\n return plan.sort((a, b) => a.name.localeCompare(b.name));\n}\n`
19
+ ];
20
+ const titles = ['Start the release planner', 'Skip private packages', 'Default to a safe dry run', 'Reject missing versions', 'Sort releases and name their channel'];
21
+ const revisions = [];
22
+ for (let i = 0; i < versions.length; i++) {
23
+ writeFileSync(path.join(repo, 'release.js'), versions[i]);
24
+ writeFileSync(path.join(repo, 'README.md'), `# Parcel\n\nA small release planner.\n\n${titles.slice(0, i + 1).map(t => `- ${t}`).join('\n')}\n`);
25
+ writeFileSync(path.join(repo, 'release.yaml'), `release:\n channel: ${i === 4 ? 'stable' : 'preview'}\n dryRun: ${i >= 2}\n packages:\n - name: parcel-core\n version: 1.2.0\n - name: parcel-cli\n version: 1.2.0\n`);
26
+ if (i === 4) writeFileSync(path.join(repo, 'CHANGELOG.md'), '# Release 1.2\n\nSafe defaults, explicit channels, predictable ordering.\n');
27
+ git('add', '.');
28
+ execFileSync('git', ['commit', '-m', titles[i]], { cwd: repo, env: { ...process.env, GIT_AUTHOR_DATE: `2026-09-0${i+1}T12:00:00Z`, GIT_COMMITTER_DATE: `2026-09-0${i+1}T12:00:00Z` } });
29
+ revisions.push(git('rev-parse', 'HEAD'));
30
+ writeFileSync(path.join(root, `release-v${i+1}.js`), versions[i]);
31
+ if (i === 0 || i === 4) {
32
+ const dir = path.join(root, i === 0 ? 'before' : 'after');
33
+ mkdirSync(dir);
34
+ for (const file of git('ls-files').split('\n')) cpSync(path.join(repo, file), path.join(dir, file));
35
+ }
36
+ }
37
+ const source = {
38
+ version: 4, title: 'Ship a safer release plan', range: { base: revisions[0], head: revisions[4] },
39
+ anchors: {
40
+ dry: { file: 'release.js', revision: 'head', contains: ' const dryRun = options.dryRun ?? true;' },
41
+ private: { file: 'release.js', revision: 'head', contains: ' if (pkg.private) continue;' },
42
+ stable: { file: 'release.js', revision: 'head', contains: " channel: options.channel ?? 'stable'," }
43
+ }, connections: [], chapters: [{ id: 'safety', title: 'Make the safe path the easy path', scenes: [{
44
+ id: 'planner', title: 'A release should be deliberate', summary: 'Parcel turns package metadata into a release plan. This change makes safety the default and keeps the result predictable.',
45
+ bullets: ['Preview before publishing.', 'Keep private packages out.', 'Name the release channel.'], tags: ['safety', 'release'], takeaway: 'A plan is inspectable before it becomes a publish operation.',
46
+ steps: [
47
+ { id: 'dry-run', title: 'Preview by default', body: 'Omitting options now creates a dry-run plan. Publishing requires an explicit choice, so a caller can inspect the same plan before allowing side effects.', focus: 'dry' },
48
+ { id: 'private-packages', title: 'Respect the package boundary', body: 'Private packages never enter the plan. Filtering at the boundary means every later stage can operate on publishable packages.', focus: 'private' },
49
+ { id: 'channel', title: 'Make the destination visible', body: 'Each entry carries its release channel. The default is stable; callers can choose another channel when preparing a preview.', focus: 'stable' }
50
+ ]
51
+ }] }]
52
+ };
53
+ writeFileSync(path.join(root, 'release.bygone'), JSON.stringify(source, null, 2) + '\n');
54
+ writeFileSync(path.join(repo, 'release.bygone'), JSON.stringify(source, null, 2) + '\n');
55
+ writeFileSync(path.join(root, 'fixture.json'), JSON.stringify({ root, repo, revisions }, null, 2));
56
+ console.log(root);
57
+ /* global process, console */
@@ -0,0 +1,100 @@
1
+ version: 4
2
+ title: Explain persistent tour markers in conceptual stages
3
+ range:
4
+ base: d040a442657547340e5fa4dcc58bfc0d233ab989
5
+ head: b05ecc2c8998aa7569934dc7914c2e9924f7d0be
6
+ anchors:
7
+ annotations:
8
+ file: src/webviewMessages.ts
9
+ revision: head
10
+ contains: ' tourAnnotations?: Array<{'
11
+ connections: []
12
+ chapters:
13
+ - id: explanation-order
14
+ title: Synthetic explanation stages
15
+ scenes:
16
+ - id: persistent-markers
17
+ kind: deconstructed-diff
18
+ title: Separate persistent markers from active emphasis
19
+ summary: Reorder one real commit into synthetic cumulative stages for teaching.
20
+ bullets:
21
+ - The source contract first permits several annotations.
22
+ - The presenter then marks every anchor and identifies the active one.
23
+ - >-
24
+ The renderer finally separates persistent gutter markers from active
25
+ text emphasis.
26
+ tags:
27
+ - tours
28
+ - explanation
29
+ - synthetic
30
+ takeaway: These panels are explanation stages, not historical commits.
31
+ base: d040a442657547340e5fa4dcc58bfc0d233ab989
32
+ target: b05ecc2c8998aa7569934dc7914c2e9924f7d0be
33
+ stages:
34
+ - id: contract
35
+ title: Carry every anchor
36
+ narration: >-
37
+ Expand the host contract from one annotation to an active-marked
38
+ collection.
39
+ changes:
40
+ - file: src/webviewMessages.ts
41
+ hunks:
42
+ - hunk-64e041c7407c
43
+ - hunk-f81ce869a41a
44
+ - id: presentation
45
+ title: Build persistent and active annotations
46
+ narration: >-
47
+ The tour host emits all anchors for the file and marks the current
48
+ step active.
49
+ changes:
50
+ - file: web/host.js
51
+ hunks:
52
+ - hunk-baa2982f00b2
53
+ - hunk-a11ba6c61eab
54
+ - hunk-c32fa33b08c9
55
+ - hunk-3d642f820720
56
+ - hunk-34282593627a
57
+ - id: rendering
58
+ title: Emphasize only the active anchor
59
+ narration: >-
60
+ The renderer gives every anchor a gutter decoration while
61
+ reserving the text class and reveal target for the active one.
62
+ changes:
63
+ - file: media/script.js
64
+ hunks:
65
+ - hunk-7ab25ee9fe44
66
+ - hunk-229ff9b95257
67
+ - hunk-208bf1e2739a
68
+ - hunk-195c64e7ce9d
69
+ - hunk-ca648f8b7f6d
70
+ - hunk-0a640980b9b7
71
+ - hunk-d005d43f28c8
72
+ - hunk-814c1fb6cdf3
73
+ - hunk-208dd701b2db
74
+ - hunk-cd8f327f0940
75
+ - hunk-9f54024f461a
76
+ - hunk-56e6f514f9ae
77
+ - hunk-45626d68d23d
78
+ - file: test/runTests.js
79
+ hunks:
80
+ - hunk-69f71617ff01
81
+ - hunk-55f5ba472e6c
82
+ exclusions:
83
+ - file: web/web-host.js
84
+ reason: Generated browser bundle; the source host is assigned above.
85
+ - file: web/web-host.js.map
86
+ reason: Generated source map; it carries no independent product behavior.
87
+ stack:
88
+ - id: before
89
+ ref: d040a442657547340e5fa4dcc58bfc0d233ab989
90
+ label: Before annotations
91
+ - id: after
92
+ ref: b05ecc2c8998aa7569934dc7914c2e9924f7d0be
93
+ label: Persistent annotations
94
+ steps:
95
+ - id: annotations
96
+ title: Carry every anchor
97
+ body: >-
98
+ A collection of annotations lets the renderer keep context visible
99
+ while emphasizing the active passage.
100
+ focus: annotations
@@ -0,0 +1,134 @@
1
+ # Bygone, one screen at a time
2
+
3
+ Bygone connects three activities: comparing concrete files, investigating their
4
+ history, and explaining what you found. This guide starts with the diff itself,
5
+ then follows those activities through the shared window. Each stop pairs a real
6
+ screenshot with a specific thing to notice. Screens are examples, not live
7
+ controls; open the matching workflow to explore your own files.
8
+
9
+ ## Compare what is in front of you
10
+
11
+ ### Two files, one visual comparison
12
+
13
+ Start with two files when you already know what belongs on each side. Blue
14
+ regions connect corresponding changed text; green regions mark content present
15
+ on only one side. The ribbons show where the regions meet across the gutter.
16
+ Read the pane labels before interpreting the colors: a local file can be
17
+ editable, while a historical snapshot is read-only. Change navigation moves
18
+ between the interesting regions without requiring you to scan every line.
19
+
20
+ ### Keep more versions in view
21
+
22
+ A comparison can contain more than two panels. Visible panels controls how
23
+ many fit in the window, while the active adjacent pair determines the current
24
+ diff. Choose a fixed density or Fit; a narrower window may show fewer panels.
25
+ The numbered headers keep the sequence legible. Use this when two endpoints
26
+ hide an intermediate version that matters to the explanation.
27
+
28
+ ### Start with the directory
29
+
30
+ When you know the area but not the file, compare directories first. The
31
+ inventory puts additions, deletions, and changed files together. Open a file to
32
+ inspect its contents, then return to the directory. This keeps the question
33
+ “which file matters?” separate from the closer reading of its lines.
34
+
35
+ ### Find without abandoning the comparison
36
+
37
+ Search helps when you know a name or phrase but not its location. Choose the
38
+ scope before interpreting the results: visible panes, all comparison panels, the
39
+ current change set, and Git history answer different questions. A result takes you back to the
40
+ matching evidence. Replacement is a separate operation and depends on whether
41
+ the target is writable.
42
+
43
+ ## Ask how it got here
44
+
45
+ ### Begin with repository history
46
+
47
+ Repository history combines file navigation with the commit axis. Here, the
48
+ latest commit adds CHANGELOG.md: the earlier pane is explicitly absent. Files
49
+ and Commits are two ways to choose your next question. Revision labels identify the
50
+ snapshots being compared; commit-list selections are a draft until you apply
51
+ them. The numbered badges show which revisions occupy the comparison panels.
52
+
53
+ ### Follow a file through real revisions
54
+
55
+ File history brings that same timeline to one path. The panels show exact
56
+ historical contents, making a changed line something you can place in time.
57
+ History and Compare share the window controls. Use the file navigation to
58
+ visit files changed by the selected comparison, and the change controls to
59
+ move within the open file.
60
+
61
+ ### Review the shape of a branch
62
+
63
+ A branch review starts with an overview of the committed range. Its suggested
64
+ reading order helps you choose an entry point; the complete file list remains
65
+ available. The range labels matter: this is a comparison of committed evidence,
66
+ not an implicit inclusion of every local edit. Start broad, then drill into the
67
+ files that explain the change.
68
+
69
+ ## Turn exploration into an explanation
70
+
71
+ ### Read the tour as a document
72
+
73
+ A tour adds a written argument to the evidence. The outline groups chapters,
74
+ scenes, and steps; the continuous narrative establishes the question before
75
+ pointing at source. Scrolling the narrative advances the reading position.
76
+ Scrolling the code lets you inspect the evidence without advancing the story.
77
+ The Narration controls provide another way to follow the same explanation.
78
+
79
+ ### Keep the explanation beside its evidence
80
+
81
+ A step brings a precise passage into focus. Its body should explain why those
82
+ lines matter, rather than repeat their syntax. As you read farther into a
83
+ scene, the scene heading can stay at the top; expand it to recover the overview.
84
+ The narrative and evidence remain independently navigable.
85
+
86
+ ### Separate explanation stages from commits
87
+
88
+ Deconstructed tours group changes into conceptual stages. These are explicitly
89
+ labeled explanation stages, so they should not be read as a claim about the
90
+ actual commit sequence. Historical tours and real revision stacks answer the
91
+ chronological question. Choose the mode that matches the explanation you want
92
+ to give, and keep its provenance visible.
93
+
94
+ ### Explore, then return to the story
95
+
96
+ A tour is a route through the material, not a fence around it. Files opens the
97
+ broader inventory; Commits exposes the available revisions. History and Compare
98
+ let you investigate a question that the author did not anticipate. Return to
99
+ tour restores the authored passage after that detour.
100
+
101
+ ### Write the tour with explicit evidence
102
+
103
+ The missing-tour handoff supplies an editable prompt and authoring instructions.
104
+ It does not call an AI service on your behalf. The authoring workflow remains
105
+ file based: write a .bygone source, validate the anchors against the intended
106
+ Git range, then compile or present it. Keeping the evidence explicit makes the
107
+ tour inspectable and repeatable.
108
+
109
+ ## Take the work with you
110
+
111
+ ### Share a particular place or a portable view
112
+
113
+ Heading links identify a particular place in the tour. This screenshot shows
114
+ the other sharing route: an exported HTML document with Tour details expanded. Local desktop links still depend on the referenced repository and tour
115
+ being available. An HTML export is the portable reading option: minimal exports
116
+ keep the tour evidence, while full exports also include bounded history.
117
+ The notice here identifies a minimal snapshot and an embedded viewer requiring
118
+ no internet. Choose based on how much independent exploration the recipient
119
+ needs; CDN-backed exports instead require internet for their pinned viewer.
120
+
121
+ ### Stay near the editor in VS Code
122
+
123
+ The VS Code companion handles contextual file comparison and file history near
124
+ the editor. Larger repository, directory, multi-panel, and authored-tour work
125
+ can open in Desktop. This is a division of workflows across hosts, with the
126
+ same visual diff language carrying between them.
127
+
128
+ ### Choose the launch that matches the question
129
+
130
+ The CLI provides direct entry points: two paths for a comparison, --history for
131
+ a file or directory, --git-diff for revisions, review for a branch, and present
132
+ --tour for an authored document. The tour subcommands provide schema,
133
+ validation, compilation, and export. Start with the smallest question you can
134
+ name, then use the shared window to expand the investigation.
@@ -0,0 +1,52 @@
1
+ # A visual guide to Bygone
2
+
3
+ Audience: someone opening Bygone for the first time, with enough detail for an
4
+ existing user to discover the larger workflows. Screenshots show Bygone 0.9.9
5
+ plus the image-step support added for this guide. This is a product walkthrough,
6
+ not a review of the implementation commits.
7
+
8
+ ## 1. Compare what is in front of you
9
+
10
+ 1. Two files: read paired changes, additions, and connector ribbons.
11
+ 2. More than two versions: use the active pair and Visible panels together.
12
+ 3. Directories: start with the inventory, then drill into a changed file.
13
+ 4. Find: search the comparison without losing the current evidence.
14
+
15
+ ## 2. Ask how it got here
16
+
17
+ 5. Directory history: orient yourself with Files and Commits.
18
+ 6. File history: keep exact revisions visible while following one file.
19
+ 7. Branch review: use the overview to choose a reading order.
20
+
21
+ ## 3. Turn exploration into an explanation
22
+
23
+ 8. Read a tour: outline, continuous narrative, and corresponding evidence.
24
+ 9. Follow a step: source focus and the expandable sticky scene heading.
25
+ 10. Deconstructed mode: distinguish explanation stages from real commits.
26
+ 11. Leave and return: Files, Commits, History, Compare, and Return to tour.
27
+ 12. Author a tour: the editable handoff prompt and the CLI validation workflow.
28
+
29
+ ## 4. Take the work with you
30
+
31
+ 13. Share: document-section links and a portable HTML export.
32
+ 14. VS Code: contextual comparison near the editor, with desktop handoff.
33
+ 15. CLI: choose a launch form appropriate to the question.
34
+
35
+ ## Capture and assembly contract
36
+
37
+ - Write the narrative before capturing; reconcile it against what each screen actually shows.
38
+ - Use the same dark theme and consistent viewport where practical.
39
+ - Capture real rendered Bygone UI; do not paint hypothetical controls into images.
40
+ - Store the images here with capture provenance and reproducible commands.
41
+ - Prefer surrounding prose to annotations that cover code or controls.
42
+ - Commit screenshots before pinning their exact Git revision in the tour.
43
+ - Display one screenshot per authored step, grouped by the four arcs above.
44
+ - Validate, compile, inspect every image step, and test a portable HTML export.
45
+
46
+ ## Required product support
47
+
48
+ Tour steps need an optional image attachment resolved from the pinned Git range.
49
+ The compiler must embed PNG bytes so the compiled tour and HTML export retain the
50
+ image without a working tree or external image server. The presenter should show
51
+ the image in its evidence area, with accessible alternative text, and restore
52
+ normal code evidence when navigating away. Reject unsupported or invalid assets.