writetrack 0.9.1 → 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.
@@ -1,4 +1,4 @@
1
- import { S as SessionAnalysis } from './analysis-types-B9TlyYRD.js';
1
+ import { S as SessionAnalysis } from './analysis-types-DvrvSEh0.js';
2
2
  import './index-Cy91q_po.js';
3
3
 
4
4
  /**
package/dist/esm/viz.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { W as WriteTrackDataSchema } from './index-Cy91q_po.js';
2
- import { S as SessionAnalysis, a as SessionReport, d as IntegrityProof } from './analysis-types-B9TlyYRD.js';
2
+ import { S as SessionAnalysis, a as SessionReport, d as IntegrityProof } from './analysis-types-DvrvSEh0.js';
3
3
 
4
4
  /**
5
5
  * BaseChart — abstract web component base class for WriteTrack visualizations.
@@ -16,10 +16,20 @@ declare abstract class BaseChart<T = unknown> extends HTMLElement {
16
16
  private _resizeObserver;
17
17
  private _resizeRaf;
18
18
  private _themeObserver;
19
- private _initialResize;
19
+ private _lastWidth;
20
20
  private _rendered;
21
21
  private _internalTheme;
22
22
  static get observedAttributes(): string[];
23
+ /** Whether to render in compact/sparkline mode (no axes, tight margins). */
24
+ get compact(): boolean;
25
+ /** Get the chart width — reads --wt-chart-width CSS var (set by scorecard
26
+ * bridge), then container/host clientWidth, then fallback. The CSS var
27
+ * ensures the chart renders at the correct width even before layout. */
28
+ protected getChartWidth(fallback: number): number;
29
+ /** Get the chart height — reads --wt-chart-height CSS var, then explicit
30
+ * inline height, then fallback. Avoids reading content-derived clientHeight
31
+ * to prevent a resize feedback loop. */
32
+ protected getChartHeight(fallback: number): number;
23
33
  constructor();
24
34
  /** Override in subclasses to provide component-specific CSS */
25
35
  protected getStylesheet(): string;
@@ -100,34 +110,6 @@ declare class SpeedTimeline extends BaseChart<SessionAnalysis> {
100
110
  protected render(): void;
101
111
  }
102
112
 
103
- /**
104
- * CompositionTimeline — session activity segments over time.
105
- *
106
- * Shows typing/paste/pause/tabAway segments as colored horizontal bars
107
- * and paste events as dots scaled by character count.
108
- */
109
-
110
- declare const SEGMENT_COLORS: Record<string, string>;
111
- interface SegmentDatum {
112
- start: number;
113
- end: number;
114
- type: string;
115
- color: string;
116
- }
117
- interface PasteDatum {
118
- time: number;
119
- chars: number;
120
- source: string;
121
- }
122
- /** Extract activity segments from analysis, converting ms to seconds. */
123
- declare function extractSegments(analysis: SessionAnalysis): SegmentDatum[];
124
- /** Extract paste event markers from analysis. */
125
- declare function extractPasteMarkers(analysis: SessionAnalysis): PasteDatum[];
126
- declare class CompositionTimeline extends BaseChart<SessionAnalysis> {
127
- static tagName: string;
128
- protected render(): void;
129
- }
130
-
131
113
  /**
132
114
  * RhythmHeatmap — dwell time vs flight time scatter plot.
133
115
  *
@@ -184,26 +166,47 @@ interface GrowthPoint {
184
166
  declare function extractGrowthData(data: WriteTrackDataSchema): GrowthPoint[];
185
167
  declare class DocumentGrowth extends BaseChart<WriteTrackDataSchema> {
186
168
  static tagName: string;
169
+ /** Optional change point time (seconds) — renders as a dashed vertical rule. */
170
+ private _changePointTime;
171
+ /** Set a change point time (in seconds) to display as a vertical marker. */
172
+ setChangePoint(timeSec: number | null): void;
187
173
  protected render(): void;
188
174
  }
189
175
 
190
176
  /**
191
- * DocumentRibbon — keystroke ribbon colored by inter-key gap.
177
+ * EditBeeswarmper-keystroke beeswarm visualization.
192
178
  *
193
- * Each bar represents one keystroke. Yellow = short gaps (fast), red = long gaps (slow).
179
+ * Each dot is a single edit action. Inserts, deletes, pastes, and cuts
180
+ * are color-coded and dodged vertically by time using Plot.dodgeY.
194
181
  * Consumes raw WriteTrackDataSchema (not WASM analysis output).
195
182
  */
196
183
 
197
- interface RibbonDatum {
198
- start: number;
199
- end: number;
200
- flight: number;
184
+ type BeeswarmType = 'insert' | 'delete' | 'paste' | 'cut';
185
+ interface BeeswarmDatum {
186
+ time: number;
187
+ type: BeeswarmType;
188
+ chars: number;
189
+ key: string;
201
190
  }
202
- /** Extract ribbon data from raw keydown events. */
203
- declare function extractRibbonData(data: WriteTrackDataSchema): RibbonDatum[];
204
- declare class DocumentRibbon extends BaseChart<WriteTrackDataSchema> {
191
+ /** Extract per-keystroke beeswarm data from raw session events. */
192
+ declare function extractBeeswarmData(data: WriteTrackDataSchema): BeeswarmDatum[];
193
+ declare class EditBeeswarm extends BaseChart<WriteTrackDataSchema> {
205
194
  static tagName: string;
195
+ static get observedAttributes(): string[];
196
+ /** Whether to render typed characters as letter glyphs instead of dots.
197
+ * Internal/experimental — not part of the public API. */
198
+ get glyphs(): boolean;
199
+ attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null): void;
206
200
  protected render(): void;
201
+ /** Compact render: binned data, no axes, no tooltips, tight margins. */
202
+ private renderCompact;
203
+ /** Dot marks for all event types (default mode). */
204
+ private buildDotMarks;
205
+ /** Glyph marks: single text mark so everything dodges together.
206
+ * Typed chars as letters, deletes as ×, pastes as 📋, cuts as ✂. */
207
+ private buildGlyphMarks;
208
+ /** Crop the SVG viewBox top to fit content, preserving the bottom (axis). */
209
+ private cropViewBox;
207
210
  }
208
211
 
209
212
  /**
@@ -243,23 +246,49 @@ interface BubbleDatum {
243
246
  time: number;
244
247
  chars: number;
245
248
  type: EditType;
246
- size: number;
247
249
  }
248
250
  /** Group consecutive keystrokes into edit runs and add paste/cut events. */
249
251
  declare function extractCorrectionBubbles(data: WriteTrackDataSchema): BubbleDatum[];
250
252
  declare class CorrectionsBubble extends BaseChart<WriteTrackDataSchema> {
251
253
  static tagName: string;
252
254
  protected render(): void;
255
+ /** Compact render: 2 lanes if no clipboard events, time-binned if clipboard present. */
256
+ private renderCompact;
257
+ }
258
+
259
+ /**
260
+ * OriginBar — content origin proportion as a horizontal stacked bar.
261
+ *
262
+ * Shows typed / pasted / autocompleted as percentages of all content created.
263
+ */
264
+
265
+ interface OriginDatum {
266
+ category: 'origin';
267
+ segment: string;
268
+ value: number;
269
+ }
270
+ interface OriginBarColors {
271
+ typed: string;
272
+ pasted: string;
273
+ autocompleted: string;
274
+ }
275
+ /** Extract origin proportions from analysis, filtering out 0% segments. */
276
+ declare function extractOriginData(analysis: SessionAnalysis): OriginDatum[];
277
+ /** Render a horizontal stacked bar showing content origin proportions. */
278
+ declare function renderOriginBar(data: OriginDatum[], width: number, colors?: OriginBarColors): SVGSVGElement | null;
279
+ declare class WtOriginBar extends BaseChart<SessionAnalysis> {
280
+ static tagName: string;
281
+ protected render(): void;
253
282
  }
254
283
 
255
284
  declare class WtScorecard extends BaseChart<SessionReport> {
256
285
  static tagName: string;
257
- private _activeDetail;
258
- constructor();
286
+ static get observedAttributes(): string[];
287
+ private _activeCategory;
259
288
  /**
260
289
  * Override onResize to only re-render charts instead of full re-render.
261
- * A full re-render replaces container content changes height
262
- * triggers ResizeObserver again infinite loop.
290
+ * A full re-render replaces container content -> changes height ->
291
+ * triggers ResizeObserver again -> infinite loop.
263
292
  */
264
293
  protected onResize(): void;
265
294
  protected getStylesheet(): string;
@@ -267,30 +296,27 @@ declare class WtScorecard extends BaseChart<SessionReport> {
267
296
  attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null): void;
268
297
  protected render(): void;
269
298
  private buildHeader;
270
- private buildSummary;
271
- private buildTierLabel;
299
+ private buildFlags;
300
+ private buildIntegrityDetails;
272
301
  private buildGrid;
273
302
  private buildCell;
274
303
  private buildCellMetrics;
275
304
  private buildDetailPanel;
276
305
  private selectCell;
306
+ private populateAndRenderDetail;
277
307
  private populateDetail;
278
- private closeDetail;
279
- private expandPanel;
280
- private collapsePanel;
281
308
  private getIndicatorCode;
282
309
  private getComputedColors;
283
- private getChartWidth;
284
- private plotOpts;
285
- private plotCategory;
310
+ /** Render the origin proportion bar into #origin-bar if it exists and data is available. */
311
+ private renderOriginBarIfPresent;
312
+ /**
313
+ * Create a standalone chart component.
314
+ * Returns { el, init } — append el to DOM first, then call init()
315
+ * so the chart can measure its real container width.
316
+ */
317
+ private createDetailChart;
286
318
  private renderAllCharts;
287
319
  private rerenderAllCharts;
288
- private plotContentOrigin;
289
- private plotTimingAuthenticity;
290
- private plotRevisionBehavior;
291
- private plotSessionContinuity;
292
- private plotPhysicalPlausibility;
293
- private plotTemporalPatterns;
294
320
  }
295
321
 
296
322
  interface IntegrityFooterData {
@@ -316,8 +342,8 @@ declare function isPass(code: string): boolean;
316
342
  declare function getStatus(code: string | undefined): 'pass' | 'flag' | 'unknown';
317
343
  /** Display names for SessionAnalysis category fields. */
318
344
  declare const CATEGORY_NAMES: Record<string, string>;
319
- /** All 6 analysis category keys in display order. */
320
- declare const CATEGORY_KEYS: readonly ["contentOrigin", "timingAuthenticity", "revisionBehavior", "sessionContinuity", "physicalPlausibility", "temporalPatterns"];
345
+ /** All 7 analysis category keys in display order. */
346
+ declare const CATEGORY_KEYS: readonly ["contentOrigin", "timingAuthenticity", "revisionBehavior", "sessionContinuity", "physicalPlausibility", "temporalPatterns", "writingProcess"];
321
347
  type CategoryKey = (typeof CATEGORY_KEYS)[number];
322
348
  /** Tier 1 categories are expanded by default. */
323
349
  declare const TIER1_CATEGORIES: CategoryKey[];
@@ -359,4 +385,36 @@ declare const GLOSSARY: Record<string, GlossaryEntry>;
359
385
  */
360
386
  declare function wrapTerms(text: string, baseUrl?: string): string;
361
387
 
362
- export { BaseChart, type BubbleDatum, CATEGORY_NAMES, type CategoryKey, CompositionTimeline, CorrectionsBubble, DocumentGrowth, DocumentRibbon, type EditType, EditWaterfall, GLOSSARY, type GlossaryEntry, type GrowthPoint, IntegrityFooter, type PasteDatum, type PauseBin, PauseDistribution, RhythmHeatmap, type RhythmPoint, type RibbonDatum, SEGMENT_COLORS, type ScorecardMetric, type SegmentDatum, Sparkline, type SpeedPoint, SpeedTimeline, TIER1_CATEGORIES, TIER2_CATEGORIES, type WaterfallData, type WaterfallPoint, WtScorecard, extractCorrectionBubbles, extractGrowthData, extractPasteMarkers, extractPauseHistogram, extractRhythmPairs, extractRibbonData, extractSegments, extractSeries, extractSpeedData, extractWaterfallData, formatDuration, generateCaption, generateSummary, getMetrics, getStatus, isPass, wrapTerms };
388
+ /**
389
+ * StatBadge — compact pill/lozenge badges for at-a-glance session stats.
390
+ *
391
+ * Renders a row of inline badges with label + color-coded value.
392
+ */
393
+
394
+ type BadgeData = SessionAnalysis;
395
+ type BadgeStatus = 'clear' | 'flag' | 'neutral';
396
+ interface StatBadge {
397
+ label: string;
398
+ value: string;
399
+ status: BadgeStatus;
400
+ metric: string;
401
+ }
402
+ /** Extract headline stat badges from analysis data. */
403
+ declare function extractStatBadges(analysis: SessionAnalysis): StatBadge[];
404
+ /** Render a row of stat badge pills as a DOM element. */
405
+ declare function renderStatBadges(badges: StatBadge[]): HTMLElement;
406
+ declare class WtBadge extends BaseChart<BadgeData> {
407
+ static tagName: string;
408
+ static get observedAttributes(): string[];
409
+ attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null): void;
410
+ protected getStylesheet(): string;
411
+ protected render(): void;
412
+ }
413
+
414
+ /**
415
+ * Generate a plain-English summary of a writing session from analysis data.
416
+ * Returns null if there is insufficient data to summarise.
417
+ */
418
+ declare function generateWritingSummary(analysis: SessionAnalysis): string | null;
419
+
420
+ export { type BadgeData, type BadgeStatus, BaseChart, type BeeswarmDatum, type BeeswarmType, type BubbleDatum, CATEGORY_NAMES, type CategoryKey, CorrectionsBubble, DocumentGrowth, EditBeeswarm, type EditType, EditWaterfall, GLOSSARY, type GlossaryEntry, type GrowthPoint, IntegrityFooter, type OriginBarColors, type OriginDatum, type PauseBin, PauseDistribution, RhythmHeatmap, type RhythmPoint, type ScorecardMetric, Sparkline, type SpeedPoint, SpeedTimeline, type StatBadge, TIER1_CATEGORIES, TIER2_CATEGORIES, type WaterfallData, type WaterfallPoint, WtBadge, WtOriginBar, WtScorecard, extractBeeswarmData, extractCorrectionBubbles, extractGrowthData, extractOriginData, extractPauseHistogram, extractRhythmPairs, extractSeries, extractSpeedData, extractStatBadges, extractWaterfallData, formatDuration, generateCaption, generateSummary, generateWritingSummary, getMetrics, getStatus, isPass, renderOriginBar, renderStatBadges, wrapTerms };