cyborg-hunter 0.5.0 → 0.7.2

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 (58) hide show
  1. package/CHANGELOG.md +156 -0
  2. package/CITATION.cff +29 -0
  3. package/LICENSE +21 -0
  4. package/README.md +80 -21
  5. package/bin/cyborg-hunter.js +6 -2
  6. package/dist/cyborg-hunter-replay.js +3 -0
  7. package/dist/cyborg-hunter.esm.js +114 -22
  8. package/dist/cyborg-hunter.min.js +3 -3
  9. package/dist/extension-cyborg-hunter.js +1 -1
  10. package/dist/extension-guard-friction.js +5 -5
  11. package/dist/extension-guard-honeypot.js +1 -1
  12. package/package.json +15 -3
  13. package/src/cli/analyzers/edge-exit.js +4 -1
  14. package/src/cli/analyzers/phase-scope.js +83 -0
  15. package/src/cli/analyzers/summary.js +161 -28
  16. package/src/cli/analyzers/triage.js +59 -27
  17. package/src/cli/config.js +26 -1
  18. package/src/cli/extract-core.js +552 -0
  19. package/src/cli/ingest.js +250 -193
  20. package/src/cli/init.js +1 -1
  21. package/src/cli/preview-entry.js +36 -0
  22. package/src/cli/renderers/event-log.js +18 -19
  23. package/src/cli/renderers/extensions.js +12 -3
  24. package/src/cli/renderers/html-index-core.js +1273 -0
  25. package/src/cli/renderers/html-index.js +13 -1047
  26. package/src/cli/renderers/replay-assets.js +67 -0
  27. package/src/cli/renderers/replay-viewer.client.js +1185 -0
  28. package/src/cli/renderers/session-timeline-core.js +907 -0
  29. package/src/cli/renderers/session-timeline.js +33 -0
  30. package/src/cli/renderers/summary-csv.js +5 -0
  31. package/src/cli/renderers/trajectories-core.js +717 -0
  32. package/src/cli/renderers/trajectories.js +31 -635
  33. package/src/cli/renderers/triage-md.js +10 -4
  34. package/src/cli/renderers/typing-profile-core.js +211 -0
  35. package/src/cli/renderers/typing-profile.js +16 -186
  36. package/src/cli/report.js +42 -8
  37. package/src/core/monitor.js +77 -7
  38. package/src/core/scoring.js +11 -2
  39. package/src/core/signals/browser.js +51 -18
  40. package/src/core/signals/clipboard.js +10 -2
  41. package/src/core/signals/dom-protection.js +9 -0
  42. package/src/core/signals/focus.js +16 -2
  43. package/src/jspsych/extension-cyborg-hunter-replay.js +135 -0
  44. package/src/jspsych/extension-cyborg-hunter.js +9 -2
  45. package/src/jspsych/extension-guard-friction.js +43 -14
  46. package/src/jspsych/extension-guard-honeypot.js +25 -1
  47. package/src/replay/capture-dom.js +575 -0
  48. package/src/replay/capture-trace.js +468 -0
  49. package/src/replay/index.js +104 -0
  50. package/src/replay/persistence.js +141 -0
  51. package/src/replay/recorder.js +315 -0
  52. package/src/replay/serializer.js +119 -0
  53. package/src/replay/viewer-model.js +125 -0
  54. package/src/shared/constants.js +12 -6
  55. package/src/shared/paths.js +20 -0
  56. package/src/shared/schema.js +5 -0
  57. package/src/shared/validation.js +55 -0
  58. package/src/cli/renderers/tab-timeline.js +0 -149
@@ -0,0 +1,33 @@
1
+ // src/cli/renderers/session-timeline.js
2
+ // Thin fs wrapper around the pure drawing core (session-timeline-core.js).
3
+ // The core takes an injected createCanvas and returns the drawn canvas; this
4
+ // wrapper owns node-canvas acquisition and PNG serialization so the core can
5
+ // also run in a browser (demo plot adapter) with document canvases.
6
+ import { writeFileSync } from 'fs';
7
+ import { join } from 'path';
8
+ import { drawSessionTimeline, collectEvents, deriveSessionOffset, sanitize, shortId } from './session-timeline-core.js';
9
+ // Load-bearing re-exports: tests/cli/contract-fixes.test.js imports
10
+ // collectEvents + deriveSessionOffset from this path; drawSessionTimeline
11
+ // serves this wrapper's own loop and the future browser demo plot adapter.
12
+ export { drawSessionTimeline, collectEvents, deriveSessionOffset };
13
+
14
+ // ── Public API ───────────────────────────────────────────────────────────
15
+ export async function renderSessionTimelines(participants, config) {
16
+ const { createCanvas } = await import('canvas');
17
+
18
+ let rendered = 0;
19
+ for (const p of participants) {
20
+ try {
21
+ const canvas = await drawSessionTimeline(p, config, createCanvas);
22
+ if (!canvas) continue;
23
+ const buf = canvas.toBuffer('image/png');
24
+ const filename = `session_timeline_${sanitize(p.participantId)}.png`;
25
+ writeFileSync(join(config.outputDir, 'images', filename), buf);
26
+ rendered++;
27
+ } catch (err) {
28
+ // Defensive: never let one bad payload kill the whole report.
29
+ console.warn(` [warn] session timeline failed for ${shortId(p.participantId)}: ${err.message}`);
30
+ }
31
+ }
32
+ console.log(` session timelines — rendered (${rendered}/${participants.length})`);
33
+ }
@@ -42,6 +42,11 @@ const COLUMNS = [
42
42
  ['zoom_change_count', (s, t) => s.zoomChangeCount || 0],
43
43
  ['dev_tools_event_count', (s, t) => s.devToolsEventCount || 0],
44
44
  ['authoritative_soft_score', (s, t) => s.authoritativeSoftScore ?? ''],
45
+ // Guard-honeypot self-disclosure. Three states: 'YES' = box ticked,
46
+ // 'no' = honeypot present but unticked (negative evidence), '' = honeypot
47
+ // extension not used for this participant (honeypotAiUse is null).
48
+ ['honeypot_ai_use', (s, t) => s.honeypotAiUse == null ? '' : (s.honeypotAiUse ? 'YES' : 'no')],
49
+ ['honeypot_ai_report', (s, t) => s.honeypotAiReport || ''],
45
50
  ];
46
51
 
47
52
  export async function renderSummaryCSV(summaries, triage, config) {