claude-code-session-manager 0.61.0 → 0.62.1
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.
- package/dist/assets/{TiptapBody-CCmz3PdX.js → TiptapBody-BwN4pNC0.js} +42 -42
- package/dist/assets/{index-CPMP2XZ_.css → index-CVCCMw5o.css} +1 -1
- package/dist/assets/index-ZjTDk5b7.js +3197 -0
- package/dist/index.html +2 -2
- package/package.json +4 -2
- package/src/main/__tests__/chat-preamble-anchors.test.cjs +100 -0
- package/src/main/__tests__/runVerify-transcript-commit-evidence.test.cjs +215 -0
- package/src/main/__tests__/scheduler-investigation-prompt.test.cjs +42 -1
- package/src/main/__tests__/scheduler-prd-missing-skip.test.cjs +54 -1
- package/src/main/__tests__/transcripts-doFlush-array.test.cjs +6 -0
- package/src/main/__tests__/transcripts-paged-reads.test.cjs +6 -0
- package/src/main/__tests__/transcriptsUsageFor.test.cjs +6 -0
- package/src/main/chatRunner.cjs +4 -0
- package/src/main/config.cjs +30 -23
- package/src/main/files.cjs +20 -0
- package/src/main/index.cjs +1 -63
- package/src/main/ipcSchemas.cjs +11 -209
- package/src/main/lib/__tests__/coldBootPromptSessionsWrite.test.cjs +87 -0
- package/src/main/lib/activeIndexMerge.cjs +9 -0
- package/src/main/lib/opsOwnership.cjs +0 -2
- package/src/main/lib/summarize.cjs +0 -1
- package/src/main/runVerify.cjs +55 -6
- package/src/main/scheduler.cjs +46 -7
- package/src/preload/api.d.ts +2 -197
- package/src/preload/index.cjs +1 -100
- package/dist/assets/index-B5994QOJ.js +0 -3222
- package/src/main/__tests__/browserAgentServer.test.cjs +0 -235
- package/src/main/__tests__/browserView-destroyed-handler.test.cjs +0 -85
- package/src/main/__tests__/browserView-oauth-popup.test.cjs +0 -126
- package/src/main/__tests__/web-remote-e2e-pinning.test.cjs +0 -181
- package/src/main/browserAgentServer.cjs +0 -224
- package/src/main/browserCapture.cjs +0 -728
- package/src/main/browserView.cjs +0 -916
- package/src/main/lib/__tests__/browserAgentActions.test.cjs +0 -76
- package/src/main/lib/browserAgentActions.cjs +0 -114
- package/src/main/lib/e2eStateMachine.cjs +0 -39
- package/src/main/webRemote.cjs +0 -1367
- package/src/preload/browserViewPreload.cjs +0 -118
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* browserAgentActions.test.cjs — unit tests for the pure action-mapping
|
|
3
|
-
* logic behind the on-demand browser-agent API (PRD 535).
|
|
4
|
-
*
|
|
5
|
-
* Run: timeout 120 node --test src/main/lib/__tests__/browserAgentActions.test.cjs
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
'use strict';
|
|
9
|
-
|
|
10
|
-
const { test } = require('node:test');
|
|
11
|
-
const assert = require('node:assert/strict');
|
|
12
|
-
const {
|
|
13
|
-
parseKeyCombo,
|
|
14
|
-
computeScrollDelta,
|
|
15
|
-
computeScreenshotScale,
|
|
16
|
-
AGENT_SCREENSHOT_MAX_DIM,
|
|
17
|
-
} = require('../browserAgentActions.cjs');
|
|
18
|
-
|
|
19
|
-
test('parseKeyCombo: plain special key', () => {
|
|
20
|
-
assert.deepEqual(parseKeyCombo('Return'), { keyCode: 'Enter', modifiers: [] });
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
test('parseKeyCombo: single modifier + letter', () => {
|
|
24
|
-
assert.deepEqual(parseKeyCombo('ctrl+s'), { keyCode: 's', modifiers: ['control'] });
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
test('parseKeyCombo: multiple modifiers', () => {
|
|
28
|
-
assert.deepEqual(parseKeyCombo('ctrl+shift+p'), { keyCode: 'p', modifiers: ['control', 'shift'] });
|
|
29
|
-
});
|
|
30
|
-
|
|
31
|
-
test('parseKeyCombo: cmd/meta/option aliases normalize', () => {
|
|
32
|
-
assert.deepEqual(parseKeyCombo('cmd+option+Escape'), { keyCode: 'Escape', modifiers: ['meta', 'alt'] });
|
|
33
|
-
});
|
|
34
|
-
|
|
35
|
-
test('parseKeyCombo: unknown modifier throws', () => {
|
|
36
|
-
assert.throws(() => parseKeyCombo('foo+a'), /unknown modifier/);
|
|
37
|
-
});
|
|
38
|
-
|
|
39
|
-
test('parseKeyCombo: empty string throws', () => {
|
|
40
|
-
assert.throws(() => parseKeyCombo(''), /empty key/);
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
test('computeScrollDelta: up/down/left/right map to signed deltas', () => {
|
|
44
|
-
assert.deepEqual(computeScrollDelta({ scroll_direction: 'up', scroll_amount: 2 }), { deltaX: 0, deltaY: 200 });
|
|
45
|
-
assert.deepEqual(computeScrollDelta({ scroll_direction: 'down', scroll_amount: 2 }), { deltaX: 0, deltaY: -200 });
|
|
46
|
-
assert.deepEqual(computeScrollDelta({ scroll_direction: 'left', scroll_amount: 1 }), { deltaX: 100, deltaY: 0 });
|
|
47
|
-
assert.deepEqual(computeScrollDelta({ scroll_direction: 'right', scroll_amount: 1 }), { deltaX: -100, deltaY: 0 });
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
test('computeScrollDelta: defaults scroll_amount to 1 when not finite', () => {
|
|
51
|
-
assert.deepEqual(computeScrollDelta({ scroll_direction: 'up' }), { deltaX: 0, deltaY: 100 });
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
test('computeScrollDelta: unsupported direction throws', () => {
|
|
55
|
-
assert.throws(() => computeScrollDelta({ scroll_direction: 'diagonal' }), /unsupported scroll_direction/);
|
|
56
|
-
});
|
|
57
|
-
|
|
58
|
-
test('computeScreenshotScale: leaves small images untouched', () => {
|
|
59
|
-
const result = computeScreenshotScale(800, 600);
|
|
60
|
-
assert.equal(result.scale, 1);
|
|
61
|
-
assert.equal(result.width, 800);
|
|
62
|
-
assert.equal(result.height, 600);
|
|
63
|
-
});
|
|
64
|
-
|
|
65
|
-
test('computeScreenshotScale: downscales long edge to the fixed max', () => {
|
|
66
|
-
const result = computeScreenshotScale(2560, 1440);
|
|
67
|
-
assert.equal(result.width, AGENT_SCREENSHOT_MAX_DIM);
|
|
68
|
-
assert.ok(result.scale < 1);
|
|
69
|
-
assert.equal(result.height, Math.round(1440 * result.scale));
|
|
70
|
-
});
|
|
71
|
-
|
|
72
|
-
test('computeScreenshotScale: portrait image scales on height', () => {
|
|
73
|
-
const result = computeScreenshotScale(900, 3000);
|
|
74
|
-
assert.equal(result.height, AGENT_SCREENSHOT_MAX_DIM);
|
|
75
|
-
assert.ok(result.width < 900);
|
|
76
|
-
});
|
|
@@ -1,114 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* browserAgentActions.cjs — pure mapping logic for the on-demand single-
|
|
3
|
-
* action browser-agent API (PRD 535). Extracted out of browserView.cjs so
|
|
4
|
-
* the action -> input-event/scale mapping can be unit-tested without
|
|
5
|
-
* booting Electron — mirrors how lib/schedulerBatch.cjs was pulled out of
|
|
6
|
-
* scheduler.cjs for the same reason. Anything that actually touches a live
|
|
7
|
-
* WebContentsView (sendInputEvent, capturePage, executeJavaScript) stays in
|
|
8
|
-
* browserView.cjs; this module only computes the values passed to those
|
|
9
|
-
* calls.
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
|
-
'use strict';
|
|
13
|
-
|
|
14
|
-
// Anthropic's computer_use tool scrolls in "clicks"; one click here maps to
|
|
15
|
-
// this many CSS pixels of wheel delta.
|
|
16
|
-
const SCROLL_UNIT_PX = 100;
|
|
17
|
-
|
|
18
|
-
// Anthropic-tool-use-style key names -> Electron's sendInputEvent keyCode
|
|
19
|
-
// strings. Anything not in this table is passed through as-is (covers plain
|
|
20
|
-
// single characters like "a" or "s").
|
|
21
|
-
const SPECIAL_KEY_MAP = {
|
|
22
|
-
return: 'Enter',
|
|
23
|
-
enter: 'Enter',
|
|
24
|
-
tab: 'Tab',
|
|
25
|
-
escape: 'Escape',
|
|
26
|
-
esc: 'Escape',
|
|
27
|
-
backspace: 'Backspace',
|
|
28
|
-
delete: 'Delete',
|
|
29
|
-
space: ' ',
|
|
30
|
-
up: 'Up',
|
|
31
|
-
down: 'Down',
|
|
32
|
-
left: 'Left',
|
|
33
|
-
right: 'Right',
|
|
34
|
-
page_up: 'PageUp',
|
|
35
|
-
pageup: 'PageUp',
|
|
36
|
-
page_down: 'PageDown',
|
|
37
|
-
pagedown: 'PageDown',
|
|
38
|
-
home: 'Home',
|
|
39
|
-
end: 'End',
|
|
40
|
-
};
|
|
41
|
-
|
|
42
|
-
const MODIFIER_MAP = {
|
|
43
|
-
ctrl: 'control',
|
|
44
|
-
control: 'control',
|
|
45
|
-
shift: 'shift',
|
|
46
|
-
alt: 'alt',
|
|
47
|
-
option: 'alt',
|
|
48
|
-
cmd: 'meta',
|
|
49
|
-
meta: 'meta',
|
|
50
|
-
super: 'meta',
|
|
51
|
-
};
|
|
52
|
-
|
|
53
|
-
// Parses a computer-use-style key combo ("ctrl+s", "Return", "a") into the
|
|
54
|
-
// { keyCode, modifiers } shape Electron's webContents.sendInputEvent wants.
|
|
55
|
-
function parseKeyCombo(keyStr) {
|
|
56
|
-
const parts = String(keyStr || '')
|
|
57
|
-
.split('+')
|
|
58
|
-
.map((p) => p.trim())
|
|
59
|
-
.filter(Boolean);
|
|
60
|
-
if (!parts.length) throw new Error('empty key');
|
|
61
|
-
const last = parts.pop();
|
|
62
|
-
const modifiers = parts.map((p) => {
|
|
63
|
-
const mapped = MODIFIER_MAP[p.toLowerCase()];
|
|
64
|
-
if (!mapped) throw new Error(`unknown modifier: ${p}`);
|
|
65
|
-
return mapped;
|
|
66
|
-
});
|
|
67
|
-
const lowerLast = last.toLowerCase();
|
|
68
|
-
const keyCode = SPECIAL_KEY_MAP[lowerLast] || last;
|
|
69
|
-
return { keyCode, modifiers };
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
// Maps a computer-use-style scroll action to a mouseWheel delta.
|
|
73
|
-
function computeScrollDelta({ scroll_direction, scroll_amount }) {
|
|
74
|
-
const amount = Number.isFinite(scroll_amount) ? scroll_amount : 1;
|
|
75
|
-
switch (scroll_direction) {
|
|
76
|
-
case 'up':
|
|
77
|
-
return { deltaX: 0, deltaY: amount * SCROLL_UNIT_PX };
|
|
78
|
-
case 'down':
|
|
79
|
-
return { deltaX: 0, deltaY: -amount * SCROLL_UNIT_PX };
|
|
80
|
-
case 'left':
|
|
81
|
-
return { deltaX: amount * SCROLL_UNIT_PX, deltaY: 0 };
|
|
82
|
-
case 'right':
|
|
83
|
-
return { deltaX: -amount * SCROLL_UNIT_PX, deltaY: 0 };
|
|
84
|
-
default:
|
|
85
|
-
throw new Error(`unsupported scroll_direction: ${scroll_direction}`);
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
// Fixed max long-edge a screenshot is resized to before being returned.
|
|
90
|
-
// Anthropic's computer-use API silently downscales oversized images
|
|
91
|
-
// server-side, which breaks coordinate mapping unless caller and model agree
|
|
92
|
-
// on one fixed logical resolution up front — this is that fixed point.
|
|
93
|
-
const AGENT_SCREENSHOT_MAX_DIM = 1280;
|
|
94
|
-
|
|
95
|
-
// Given a captured screenshot's real pixel size, returns the target size to
|
|
96
|
-
// resize to plus the scale factor a caller must divide a clicked coordinate
|
|
97
|
-
// on the resized image by to recover the real-page coordinate.
|
|
98
|
-
function computeScreenshotScale(width, height) {
|
|
99
|
-
const longEdge = Math.max(width, height);
|
|
100
|
-
const scale = longEdge > AGENT_SCREENSHOT_MAX_DIM ? AGENT_SCREENSHOT_MAX_DIM / longEdge : 1;
|
|
101
|
-
return {
|
|
102
|
-
scale,
|
|
103
|
-
width: Math.max(1, Math.round(width * scale)),
|
|
104
|
-
height: Math.max(1, Math.round(height * scale)),
|
|
105
|
-
};
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
module.exports = {
|
|
109
|
-
parseKeyCombo,
|
|
110
|
-
computeScrollDelta,
|
|
111
|
-
computeScreenshotScale,
|
|
112
|
-
AGENT_SCREENSHOT_MAX_DIM,
|
|
113
|
-
SCROLL_UNIT_PX,
|
|
114
|
-
};
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Pure E2E session state machine for the web-remote relay.
|
|
3
|
-
* No Electron, no I/O — importable in unit tests.
|
|
4
|
-
*
|
|
5
|
-
* State transitions:
|
|
6
|
-
* idle → pending_sas : successful deriveSessionKey + deriveSas
|
|
7
|
-
* idle → failed : crypto derivation error
|
|
8
|
-
* pending_sas → authenticated : user confirms SAS
|
|
9
|
-
* pending_sas → failed : deriveSas threw after sessionKey succeeded
|
|
10
|
-
* any → idle : disconnect / reset
|
|
11
|
-
*/
|
|
12
|
-
|
|
13
|
-
/** @returns {{ state: string, sessionKey: Buffer|null, pendingSas: string|null }} */
|
|
14
|
-
function makeState(state = 'idle', sessionKey = null, pendingSas = null) {
|
|
15
|
-
return { state, sessionKey, pendingSas };
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* Attempt to confirm the SAS. Pure — does not mutate; returns the next state.
|
|
20
|
-
* @param {{ state: string, sessionKey: Buffer|null, pendingSas: string|null }} e2eState
|
|
21
|
-
* @returns {{ ok: boolean, error?: string, next: { state: string, sessionKey: Buffer|null, pendingSas: string|null } }}
|
|
22
|
-
*/
|
|
23
|
-
function confirmSas(e2eState) {
|
|
24
|
-
if (e2eState.state !== 'pending_sas') {
|
|
25
|
-
const errorMap = {
|
|
26
|
-
idle: 'no_e2e_session',
|
|
27
|
-
failed: 'e2e_failed',
|
|
28
|
-
authenticated: 'already_authenticated',
|
|
29
|
-
};
|
|
30
|
-
const error = errorMap[e2eState.state] ?? 'unexpected_state';
|
|
31
|
-
return { ok: false, error, next: e2eState };
|
|
32
|
-
}
|
|
33
|
-
return {
|
|
34
|
-
ok: true,
|
|
35
|
-
next: makeState('authenticated', e2eState.sessionKey, null),
|
|
36
|
-
};
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
module.exports = { makeState, confirmSas };
|