@crouton-kit/capture 1.3.7 → 1.3.8

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 (40) hide show
  1. package/bin/capture +2807 -1312
  2. package/package.json +4 -1
  3. package/src/capture.ts +10 -0
  4. package/src/cdp/args.ts +99 -10
  5. package/src/cdp/bridge/protocol.ts +99 -0
  6. package/src/cdp/bridge/server.ts +105 -43
  7. package/src/cdp/bridge/spawn.ts +62 -0
  8. package/src/cdp/commands/bridge-serve.ts +28 -3
  9. package/src/cdp/commands/cdp.ts +30 -2
  10. package/src/cdp/commands/measure/census.ts +31 -0
  11. package/src/cdp/commands/measure/check.ts +35 -0
  12. package/src/cdp/commands/measure/diff.ts +32 -0
  13. package/src/cdp/commands/measure/explain.ts +31 -0
  14. package/src/cdp/commands/measure/index.ts +114 -0
  15. package/src/cdp/commands/measure/map-focus.ts +24 -0
  16. package/src/cdp/commands/measure/map-layers.ts +25 -0
  17. package/src/cdp/commands/measure/map-scroll.ts +24 -0
  18. package/src/cdp/commands/measure/snap.ts +36 -0
  19. package/src/cdp/commands/measure/sweep.ts +30 -0
  20. package/src/cdp/commands/motion/index.ts +60 -0
  21. package/src/cdp/commands/motion/jank.ts +22 -0
  22. package/src/cdp/commands/motion/mask.ts +23 -0
  23. package/src/cdp/commands/motion/rec.ts +33 -0
  24. package/src/cdp/commands/motion/response.ts +26 -0
  25. package/src/cdp/commands/motion/timeline.ts +27 -0
  26. package/src/cdp/coordinates.ts +158 -0
  27. package/src/cdp/dispatch.ts +4 -0
  28. package/src/cdp/domains.ts +75 -0
  29. package/src/cdp/recorder-bridge.ts +521 -0
  30. package/src/cdp/source-map.ts +309 -0
  31. package/src/cdp/timing.ts +82 -0
  32. package/src/cdp/types.ts +66 -0
  33. package/src/cdp/usage.ts +2 -0
  34. package/src/output/artifact.ts +520 -0
  35. package/src/output/diff.ts +111 -0
  36. package/src/output/render.ts +593 -0
  37. package/src/output/selector.ts +185 -0
  38. package/src/session/artifacts.ts +229 -0
  39. package/src/session/commands.ts +119 -15
  40. package/src/session-context.ts +48 -8
@@ -2,16 +2,33 @@
2
2
  * Session Context — persists active session state so CDP commands
3
3
  * can auto-fill --target, --har, and --out without manual threading.
4
4
  *
5
- * State is written to /tmp/capture-sessions/.active (JSON).
5
+ * State is written to /tmp/capture-sessions/.active-<scope> (JSON), where
6
+ * <scope> isolates concurrent callers (see activeScopeKey() below) so one
7
+ * caller's `session start` never clobbers another's active pointer.
6
8
  * Stale sessions (dir deleted, crashed process) are cleaned up on read.
7
9
  */
8
10
 
9
11
  import * as fs from 'fs';
10
12
  import * as path from 'path';
11
- import * as os from 'os';
13
+ import { CAPTURE_ROOT } from './session/artifacts.js';
12
14
 
13
- const CAPTURE_ROOT = path.join(os.tmpdir(), 'capture-sessions');
14
- const ACTIVE_PATH = path.join(CAPTURE_ROOT, '.active');
15
+ /**
16
+ * The active-session pointer is scoped per caller so concurrent, unrelated
17
+ * capture invocations never clobber one another's "active session" — e.g.
18
+ * two crtr agent nodes each running `capture session start` in parallel.
19
+ * When invoked from a crtr node, CRTR_NODE_ID scopes the pointer to that
20
+ * node (stable across separate tool calls within the node's lifetime).
21
+ * Outside crtr (a bare interactive terminal), there's no such identity, so
22
+ * fall back to the single legacy pointer — the original single-user,
23
+ * single-session-at-a-time contract still holds there.
24
+ */
25
+ function activeScopeKey(): string {
26
+ return process.env.CRTR_NODE_ID ?? 'default';
27
+ }
28
+
29
+ function getActivePath(): string {
30
+ return path.join(CAPTURE_ROOT, `.active-${activeScopeKey()}`);
31
+ }
15
32
 
16
33
  export interface ActiveSessionState {
17
34
  sessionId: string;
@@ -21,12 +38,20 @@ export interface ActiveSessionState {
21
38
  stepCount: number;
22
39
  /** Unix socket of the session's held CDP bridge (`session start --hold`), if any. */
23
40
  bridgeSocket?: string | null;
41
+ /**
42
+ * The id of the recording (`motion/recs/{recId}`) currently live under
43
+ * this session, if `motion rec --start` has armed one. Cleared by
44
+ * `motion rec --stop` (or a stale-recorder reap). See
45
+ * {@link setActiveRecId}/{@link clearActiveRecId}/{@link getActiveRecId}.
46
+ */
47
+ activeRecId?: string | null;
24
48
  }
25
49
 
26
50
  export function getActiveSession(): ActiveSessionState | null {
27
51
  try {
28
- if (!fs.existsSync(ACTIVE_PATH)) return null;
29
- const state = JSON.parse(fs.readFileSync(ACTIVE_PATH, 'utf-8')) as ActiveSessionState;
52
+ const activePath = getActivePath();
53
+ if (!fs.existsSync(activePath)) return null;
54
+ const state = JSON.parse(fs.readFileSync(activePath, 'utf-8')) as ActiveSessionState;
30
55
  // Validate session dir still exists — clean up stale files
31
56
  if (!fs.existsSync(state.dir)) {
32
57
  clearActiveSession();
@@ -40,12 +65,12 @@ export function getActiveSession(): ActiveSessionState | null {
40
65
 
41
66
  export function setActiveSession(state: ActiveSessionState): void {
42
67
  fs.mkdirSync(CAPTURE_ROOT, { recursive: true });
43
- fs.writeFileSync(ACTIVE_PATH, JSON.stringify(state, null, 2));
68
+ fs.writeFileSync(getActivePath(), JSON.stringify(state, null, 2));
44
69
  }
45
70
 
46
71
  export function clearActiveSession(): void {
47
72
  try {
48
- fs.unlinkSync(ACTIVE_PATH);
73
+ fs.unlinkSync(getActivePath());
49
74
  } catch {
50
75
  // Already gone
51
76
  }
@@ -59,6 +84,21 @@ export function updateActiveSession(patch: Partial<ActiveSessionState>): ActiveS
59
84
  return updated;
60
85
  }
61
86
 
87
+ /** Records `recId` as the active session's live recording. */
88
+ export function setActiveRecId(recId: string): ActiveSessionState | null {
89
+ return updateActiveSession({ activeRecId: recId });
90
+ }
91
+
92
+ /** Clears the active session's live-recording pointer (on `rec --stop` / stale reap). */
93
+ export function clearActiveRecId(): ActiveSessionState | null {
94
+ return updateActiveSession({ activeRecId: null });
95
+ }
96
+
97
+ /** Reads the active session's live recording id, or `null` if none. */
98
+ export function getActiveRecId(): string | null {
99
+ return getActiveSession()?.activeRecId ?? null;
100
+ }
101
+
62
102
  function sanitizeLabel(label: string): string {
63
103
  return label
64
104
  .toLowerCase()