@davmash/bygone 0.9.4 → 0.9.7

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.
@@ -18785,7 +18785,7 @@ var require_package = __commonJS({
18785
18785
  displayName: "Bygone",
18786
18786
  desktopName: "com.davidmashburn.bygone.desktop",
18787
18787
  description: "See how change happened. Visual diff and file history for VS Code.",
18788
- version: "0.9.4",
18788
+ version: "0.9.7",
18789
18789
  author: "David Mashburn",
18790
18790
  license: "MIT",
18791
18791
  private: false,
@@ -32133,6 +32133,67 @@ ${error.message}`);
32133
32133
  assert.ok(["auto", "scroll"].includes(initial.content.overflowY), "The narrative content uses scrolling");
32134
32134
  assert.equal(initial.activeKeys.length, 1, "Exactly one reading item is active initially");
32135
32135
  assert.equal(initial.activeKeys[0], "title", "The title starts as the active reading item");
32136
+ const originalHeight = await evaluate("document.querySelector('#tour-narrative').getBoundingClientRect().height");
32137
+ const originalPreference = await evaluate("localStorage.getItem('bygone.tourNarrativeHeight')");
32138
+ const resizeKey = async (key) => {
32139
+ await evaluate(`document.querySelector('#tour-narrative-resizer').dispatchEvent(new KeyboardEvent('keydown', { bubbles: true, key: ${JSON.stringify(key)} }))`);
32140
+ await waitForRaf();
32141
+ };
32142
+ const readSplit = () => evaluate(`(() => {
32143
+ const narrative = document.querySelector('#tour-narrative').getBoundingClientRect();
32144
+ const code = document.querySelector('#container').getBoundingClientRect();
32145
+ const resizer = document.querySelector('#tour-narrative-resizer');
32146
+ const handle = resizer.getBoundingClientRect();
32147
+ return { height: narrative.height, codeTop: code.top, codeHeight: code.height,
32148
+ handleY: handle.top + handle.height / 2, handleX: handle.left + handle.width / 2,
32149
+ value: Number(resizer.getAttribute('aria-valuenow')),
32150
+ max: Number(resizer.getAttribute('aria-valuemax')),
32151
+ stored: Number(localStorage.getItem('bygone.tourNarrativeHeight')),
32152
+ cursor: getComputedStyle(resizer).cursor };
32153
+ })()`);
32154
+ const assertSplit = (split) => {
32155
+ assert.ok(Math.abs(split.codeTop - split.height) <= 1, "Code starts at the narrative boundary");
32156
+ assert.ok(Math.abs(split.handleY - split.height) <= 1, "The divider tracks the narrative boundary");
32157
+ assert.equal(split.value, split.height, "The separator exposes its current height");
32158
+ assert.ok(split.codeHeight >= 180, "Resizing preserves room for code");
32159
+ };
32160
+ const dragSplit = async (height) => {
32161
+ const split = await readSplit();
32162
+ const x = Math.round(split.handleX);
32163
+ const y = Math.round(split.handleY);
32164
+ browserContents.sendInputEvent({ type: "mouseMove", x, y });
32165
+ browserContents.sendInputEvent({ type: "mouseDown", button: "left", clickCount: 1, x, y });
32166
+ browserContents.sendInputEvent({ type: "mouseMove", x, y: height });
32167
+ await waitFor(`Number(document.querySelector('#tour-narrative-resizer').getAttribute('aria-valuenow')) === ${height}`, "dragged narrative boundary");
32168
+ browserContents.sendInputEvent({ type: "mouseUp", button: "left", clickCount: 1, x, y: height });
32169
+ await waitFor("!document.body.classList.contains('is-resizing-tour-narrative')", "narrative drag completion");
32170
+ await waitForRaf();
32171
+ };
32172
+ try {
32173
+ assert.equal((await readSplit()).cursor, "row-resize", "The narrative divider is draggable");
32174
+ await resizeKey("Home");
32175
+ let split = await readSplit();
32176
+ assert.equal(split.height, 180, "Home sets the minimum narrative height");
32177
+ assertSplit(split);
32178
+ await resizeKey("End");
32179
+ split = await readSplit();
32180
+ assert.equal(split.height, split.max, "End sets the maximum narrative height");
32181
+ assertSplit(split);
32182
+ await resizeKey("ArrowUp");
32183
+ assert.equal((await readSplit()).height, split.max - 16, "ArrowUp reduces the narrative height");
32184
+ await resizeKey("ArrowDown");
32185
+ assert.equal((await readSplit()).height, split.max, "ArrowDown increases the narrative height");
32186
+ const target = Math.round((180 + split.max) / 2);
32187
+ await dragSplit(target);
32188
+ split = await readSplit();
32189
+ assertSplit(split);
32190
+ assert.equal(split.stored, target, "Dragging saves the narrative height");
32191
+ assert.deepEqual((await read()).activeKeys, initial.activeKeys, "Resizing preserves the selected passage");
32192
+ assert.deepEqual((await read()).url, initial.url, "Resizing preserves the reading URL");
32193
+ } finally {
32194
+ await dragSplit(Math.round(originalHeight));
32195
+ await evaluate(originalPreference === null ? "localStorage.removeItem('bygone.tourNarrativeHeight')" : `localStorage.setItem('bygone.tourNarrativeHeight', ${JSON.stringify(originalPreference)})`);
32196
+ }
32136
32197
  assert.equal(initial.items.filter((item) => item.kind === "title").length, 1, "The title item is unique");
32137
32198
  assert.equal(initial.items.filter((item) => item.kind === "chapter").length, 2, "Each chapter has a reading item");
32138
32199
  assert.equal(initial.items.filter((item) => item.kind === "scene").length, 2, "Each scene has a reading item");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@davmash/bygone",
3
- "version": "0.9.4",
3
+ "version": "0.9.7",
4
4
  "description": "See how change happened. Visual diff and file history.",
5
5
  "author": "David Mashburn",
6
6
  "license": "MIT",
@@ -134,8 +134,50 @@ Then read patches only for likely narrative-bearing files. Account explicitly fo
134
134
 
135
135
  Compiled tours and context dossiers are large because they embed source snapshots. Inspect them progressively and do not load every patch unless the narrative really needs it.
136
136
 
137
+ ## Gather ticket and PR framing
138
+
139
+ When available, read the ticket and PR context supplied by the user or directly
140
+ linked from the change, using accessible read-only sources. Follow relevant
141
+ parent-project or review links when they explain the change; keep discovery
142
+ bounded to this work. Missing metadata should not block a useful code tour.
143
+
144
+ Capture the facts that help a reader understand the change:
145
+
146
+ - **Ticket:** identifier, title, problem and requested outcome, relevant details
147
+ or acceptance criteria, creator/requester and assignee as distinct roles,
148
+ creation date or relevant timeline, and its place in a parent project, epic,
149
+ or larger initiative.
150
+ - **PR:** number, title, URL, author, relevant creation/merge dates, associated
151
+ ticket, and actual review history: who reviewed, when, their recorded outcome,
152
+ and consequential feedback or resulting changes.
153
+
154
+ Be explicit about whose ticket it was, who authored the PR, and who reviewed
155
+ it when the sources establish those roles. Credit implementation contributors
156
+ when known; PR authorship alone does not establish sole implementation credit.
157
+ A requested reviewer is not an actual reviewer; a comment is not an approval. Do not assume an earlier review
158
+ covers the current head or an entire multi-PR range. For stacked work, keep
159
+ ticket, author, timing, and review provenance attached to the correct PR.
160
+
161
+ Link the supporting ticket, PR, and review sources in the tour's narrative.
162
+ Distinguish the ticket's requested outcome and the author's stated intent from
163
+ behavior established by code and tests. Do not invent ownership, dates, project
164
+ relationships, ticket associations, review status, or approval. Briefly disclose
165
+ material gaps or conflicting context where they affect the explanation; omit
166
+ irrelevant unavailable fields rather than filling the tour with placeholders.
167
+
137
168
  ## Plan the explanation
138
169
 
170
+ Begin with an opening slide that summarizes the high-level context before the
171
+ implementation: the problem, its place in the larger project, the ticket and
172
+ PR relationship, and what this change contributes. Include relevant people,
173
+ timing, and review status concisely; put detailed provenance beside the later
174
+ claims it explains. If separate authored modes have independent entry points,
175
+ give each enough opening context to stand on its own.
176
+
177
+ Use the first scene's summary/bullets or equivalent supported narrative fields
178
+ for this opening; do not invent a slide kind or metadata keys. Keep source
179
+ anchors for code claims and source links for external context distinct.
180
+
139
181
  Identify the smallest set of reviewer questions that makes the change understandable. Organize by conceptual dependency rather than filename order. Usually move through:
140
182
 
141
183
  1. motivation, contract, or invariant;
@@ -294,7 +336,10 @@ After structural validation, check that:
294
336
 
295
337
  Treat this as a required self-audit, not a claim the validator can prove. For each item, cite concrete evidence you actually opened or mark it not applicable; the hand-off must distinguish verified findings from interpretation.
296
338
 
297
- - the first step establishes enough context for later steps;
339
+ - the opening slide establishes the problem, project context, and available
340
+ ticket/PR provenance before the first implementation step;
341
+ - ticket ownership, dates, and actual review claims are traceable to opened
342
+ sources and scoped to the PR/revision they describe;
298
343
  - chapter boundaries follow conceptual transitions rather than a fixed count or one-scene-per-chapter pattern;
299
344
  - important production behavior is not hidden in the complete Files rail;
300
345
  - tests are connected to the behavior they prove;
@@ -361,6 +406,7 @@ Report:
361
406
  counts, plus compiled counts when generated complete-change or per-mode
362
407
  scenes change them;
363
408
  - omitted or unread evidence;
409
+ - ticket/PR context sources used and material unavailable or conflicting context;
364
410
  - validation and visual verification performed;
365
411
  - whether generated files are temporary, uncommitted, committed, or pushed.
366
412
 
package/web/index.html CHANGED
@@ -137,6 +137,7 @@
137
137
  </div>
138
138
  <div id="tour-narrative-content" class="tour-narrative-content" tabindex="0" role="region" aria-label="Tour reading flow"></div>
139
139
  </section>
140
+ <div id="tour-narrative-resizer" class="tour-narrative-resizer" role="separator" aria-label="Resize tour text" title="Resize tour text (Up/Down; Home/End)" aria-controls="tour-narrative" aria-orientation="horizontal" aria-valuemin="180" tabindex="0"></div>
140
141
  <div class="web-toolbar">
141
142
  <div class="web-toolbar-group">
142
143
  <button id="web-compare-test" type="button" title="Compare sample files">Compare Test Files</button>
package/web/presenter.css CHANGED
@@ -398,6 +398,29 @@ body.tour-mode #container {
398
398
  display: none;
399
399
  }
400
400
 
401
+ .tour-narrative-resizer {
402
+ position: fixed;
403
+ z-index: 120;
404
+ top: calc(var(--tour-narrative-height) - 4px);
405
+ right: 0;
406
+ left: var(--tour-rail-width);
407
+ height: 8px;
408
+ cursor: row-resize;
409
+ touch-action: none;
410
+ }
411
+
412
+ .tour-narrative-resizer:hover,
413
+ .tour-narrative-resizer:focus-visible,
414
+ body.is-resizing-tour-narrative .tour-narrative-resizer {
415
+ background: rgba(169, 159, 255, 0.75);
416
+ outline: none;
417
+ }
418
+
419
+ body:not(.tour-mode) .tour-narrative-resizer,
420
+ body.tour-derived-mode .tour-narrative-resizer {
421
+ display: none;
422
+ }
423
+
401
424
  .tour-narrative-toolbar {
402
425
  display: flex;
403
426
  min-width: 0;
@@ -1364,6 +1387,7 @@ body.tour-directory-file-open #file-info { display: none; }
1364
1387
  }
1365
1388
 
1366
1389
  .tour-sidebar-resizer { display: none; }
1390
+ .tour-narrative-resizer { left: 0; }
1367
1391
  .tour-narrative { top: 0; left: 0; height: min(38vh, 360px); padding: 10px 14px 12px; }
1368
1392
  .tour-narrative-toolbar { gap: 6px; }
1369
1393
  .tour-narration-controls select { max-width: 150px; }