cursorconnect 0.1.8 → 0.1.9

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 (37) hide show
  1. package/bridge-runtime/.env.example +2 -0
  2. package/bridge-runtime/connector-version.json +1 -1
  3. package/bridge-runtime/dist/agent-completion-push.d.ts +18 -6
  4. package/bridge-runtime/dist/agent-completion-push.js +186 -41
  5. package/bridge-runtime/dist/agent-completion-readiness.d.ts +19 -0
  6. package/bridge-runtime/dist/agent-completion-readiness.js +42 -0
  7. package/bridge-runtime/dist/chat-display-store.d.ts +32 -7
  8. package/bridge-runtime/dist/chat-display-store.js +96 -21
  9. package/bridge-runtime/dist/chat-display.d.ts +36 -0
  10. package/bridge-runtime/dist/chat-display.js +287 -24
  11. package/bridge-runtime/dist/chat-sync.d.ts +3 -1
  12. package/bridge-runtime/dist/chat-sync.js +20 -0
  13. package/bridge-runtime/dist/debug-chats-page.d.ts +1 -1
  14. package/bridge-runtime/dist/debug-chats-page.js +148 -26
  15. package/bridge-runtime/dist/dom-transcript-store.d.ts +2 -0
  16. package/bridge-runtime/dist/dom-transcript-store.js +17 -2
  17. package/bridge-runtime/dist/extract-page.js +5 -4
  18. package/bridge-runtime/dist/lenta-capture.d.ts +46 -0
  19. package/bridge-runtime/dist/lenta-capture.js +146 -0
  20. package/bridge-runtime/dist/lenta-debug.d.ts +42 -0
  21. package/bridge-runtime/dist/lenta-debug.js +221 -0
  22. package/bridge-runtime/dist/lenta-delivery.d.ts +3 -0
  23. package/bridge-runtime/dist/lenta-delivery.js +10 -0
  24. package/bridge-runtime/dist/lenta-seq-journal.d.ts +48 -0
  25. package/bridge-runtime/dist/lenta-seq-journal.js +109 -0
  26. package/bridge-runtime/dist/message-filter.d.ts +5 -0
  27. package/bridge-runtime/dist/message-filter.js +4 -0
  28. package/bridge-runtime/dist/relay.d.ts +37 -3
  29. package/bridge-runtime/dist/relay.js +557 -51
  30. package/bridge-runtime/dist/types.d.ts +9 -4
  31. package/dist/bridge-build.js +50 -0
  32. package/dist/index.js +9 -6
  33. package/dist/launch.js +5 -1
  34. package/dist/run-service.js +10 -4
  35. package/dist/startup-check.js +6 -0
  36. package/package.json +1 -1
  37. package/version-policy.json +1 -1
@@ -176,6 +176,11 @@ export interface CursorState {
176
176
  pendingQuestionnaire?: PendingQuestionnaire;
177
177
  /** DOM: loading / Stop visible — request in progress */
178
178
  agentWorking?: boolean;
179
+ /**
180
+ * Bridge `ChatDisplayStore` ahead of last `agent:messages` for this agent.
181
+ * App may show «Догружаем ответ…» until cleared.
182
+ */
183
+ lentaPendingByAgent?: Record<string, boolean>;
179
184
  agentStatus?: string;
180
185
  /** DOM status line when agentStatus is background_shell */
181
186
  agentStatusMessage?: string;
@@ -257,14 +262,14 @@ export interface AgentHistory {
257
262
  /** Monotonic per agentId — stale snapshots should be ignored. */
258
263
  seq?: number;
259
264
  }
260
- /** Per-agent chat lenta (JSONL). `state.messages` in state:patch is DOM/debug only. */
265
+ /** Per-agent chat lenta. `state.messages` in state:patch is DOM/debug only. */
261
266
  export interface AgentMessagesPayload {
262
267
  agentId: string;
263
- /** JSONL archive tail (history). When `append`, only new display rows since last emit. */
268
+ /** JSONL baseline rows (debug). */
264
269
  historyMessages: ChatMessage[];
265
- /** Legacy field; always `[]` lenta is JSONL-only. */
270
+ /** DOM overlay rows not yet in JSONL (debug). */
266
271
  liveMessages: ChatMessage[];
267
- /** Same as historyMessages (debug). */
272
+ /** Canonical UI lenta — merge + dedupe + sort on bridge. */
268
273
  messages: ChatMessage[];
269
274
  totalMessages?: number;
270
275
  source: 'dom' | 'jsonl' | 'hybrid';
@@ -0,0 +1,50 @@
1
+ import { execSync } from 'child_process';
2
+ import { existsSync, readdirSync, statSync } from 'fs';
3
+ import { join } from 'path';
4
+ function newestMtimeMs(dir) {
5
+ let max = 0;
6
+ for (const name of readdirSync(dir, { withFileTypes: true })) {
7
+ const path = join(dir, name.name);
8
+ if (name.isDirectory()) {
9
+ max = Math.max(max, newestMtimeMs(path));
10
+ continue;
11
+ }
12
+ if (!name.isFile())
13
+ continue;
14
+ if (!/\.(ts|tsx|json)$/.test(name.name))
15
+ continue;
16
+ max = Math.max(max, statSync(path).mtimeMs);
17
+ }
18
+ return max;
19
+ }
20
+ export function isBridgeSrcNewerThanDist(bridgeDir) {
21
+ const dist = join(bridgeDir, 'dist', 'index.js');
22
+ const src = join(bridgeDir, 'src');
23
+ if (!existsSync(src))
24
+ return false;
25
+ if (!existsSync(dist))
26
+ return true;
27
+ return newestMtimeMs(src) > statSync(dist).mtimeMs;
28
+ }
29
+ export function buildBridge(bridgeDir) {
30
+ const monorepoRoot = join(bridgeDir, '..');
31
+ const hasWorkspace = existsSync(join(monorepoRoot, 'package.json')) &&
32
+ existsSync(join(monorepoRoot, 'bridge', 'package.json'));
33
+ if (hasWorkspace) {
34
+ execSync('npm run build -w bridge', {
35
+ cwd: monorepoRoot,
36
+ stdio: 'inherit',
37
+ });
38
+ return;
39
+ }
40
+ execSync('npm run build', { cwd: bridgeDir, stdio: 'inherit' });
41
+ }
42
+ /** Dev: compile bridge when `src/` is newer than `dist/` (runtime = dist, not ts). */
43
+ export function ensureBridgeBuilt(bridgeDir) {
44
+ if (process.env.CURSORCONNECT_SKIP_BRIDGE_BUILD === '1')
45
+ return;
46
+ if (!isBridgeSrcNewerThanDist(bridgeDir))
47
+ return;
48
+ console.error('[cursorconnect] bridge/src новее dist — сборка…');
49
+ buildBridge(bridgeDir);
50
+ }
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import { join, resolve } from 'path';
3
3
  import { ensurePairingIdentity, loadPairingIdentity, refreshPairingCode, } from './pairing-identity.js';
4
- import { ensureCursorCdp, isBridgeRunning, startBridge, stopBridge, } from './launch.js';
4
+ import { ensureCursorCdp, isBridgeRunning, printManualCdpInstructions, startBridge, stopBridge, } from './launch.js';
5
5
  import { printPairingToTerminal } from './print-pairing.js';
6
6
  import { BRIDGE_LOG_FILE } from './paths.js';
7
7
  import { ensureUserConfig, isValidBridgeDir, resolveBridgeDir, USER_CONFIG_ENV, } from './bridge-dir.js';
@@ -60,7 +60,13 @@ async function cmdStart(argv) {
60
60
  noRestartCursor,
61
61
  });
62
62
  if (!cdpPortOk) {
63
- console.warn('[cursorconnect] CDP порт недоступен — Cursor Connect запустится, список чатов будет из архива JSONL.');
63
+ console.error('');
64
+ console.error('[cursorconnect] CDP обязателен — без него Cursor Connect не запускается.');
65
+ console.error(' Cursor с remote debugging (порт 9222), затем снова:');
66
+ console.error(' cursorconnect start');
67
+ console.error('');
68
+ printManualCdpInstructions();
69
+ process.exit(1);
64
70
  }
65
71
  if (isBridgeRunning()) {
66
72
  console.error('[cursorconnect] Перезапуск Cursor Connect…');
@@ -69,15 +75,12 @@ async function cmdStart(argv) {
69
75
  startBridge(env);
70
76
  const readiness = await awaitStartupReadiness(relayUrl, refreshed, {
71
77
  waitMs: 45_000,
72
- requireCdp: cdpPortOk,
78
+ requireCdp: true,
73
79
  });
74
80
  if (!readiness.ready) {
75
81
  printStartupFailure(readiness, BRIDGE_LOG_FILE);
76
82
  process.exit(1);
77
83
  }
78
- if (cdpPortOk && !readiness.localCdp) {
79
- console.warn(`[cursorconnect] CDP не подключён (cdp:false) · лог: ${BRIDGE_LOG_FILE}`);
80
- }
81
84
  console.log('');
82
85
  console.log(' Проверки перед pairing:');
83
86
  for (const line of formatStartupChecklist(readiness)) {
package/dist/launch.js CHANGED
@@ -3,6 +3,7 @@ import { askYesNo } from './ask.js';
3
3
  import { closeSync, existsSync, openSync, readFileSync, writeFileSync } from 'fs';
4
4
  import { BRIDGE_LOG_FILE, BRIDGE_PID_FILE } from './paths.js';
5
5
  import { resolveBridgeDir } from './bridge-dir.js';
6
+ import { ensureBridgeBuilt } from './bridge-build.js';
6
7
  export function isBridgeRunning() {
7
8
  if (!existsSync(BRIDGE_PID_FILE))
8
9
  return false;
@@ -51,6 +52,10 @@ export function startBridge(env) {
51
52
  stopBridge();
52
53
  killProcessesOnBridgePort();
53
54
  const bridgeDir = resolveBridgeDir();
55
+ ensureBridgeBuilt(bridgeDir);
56
+ if (!process.env.CURSORCONNECT_BRIDGE_DIR?.trim()) {
57
+ process.env.CURSORCONNECT_BRIDGE_DIR = bridgeDir;
58
+ }
54
59
  const logFd = openLogAppend();
55
60
  const child = spawn('node', ['dist/index.js'], {
56
61
  cwd: bridgeDir,
@@ -243,7 +248,6 @@ export async function ensureCursorCdp(opts = {}) {
243
248
  }
244
249
  }
245
250
  if (!shouldRestart) {
246
- console.warn('[cursorconnect] Cursor без CDP — список чатов будет только из JSONL.');
247
251
  printManualCdpInstructions();
248
252
  return false;
249
253
  }
@@ -1,5 +1,5 @@
1
1
  import { ensurePairingIdentity, refreshPairingCode, } from './pairing-identity.js';
2
- import { isBridgeRunning, startBridge, } from './launch.js';
2
+ import { ensureCursorCdp, isBridgeRunning, startBridge, } from './launch.js';
3
3
  import { BRIDGE_LOG_FILE } from './paths.js';
4
4
  const WATCH_MS = 8_000;
5
5
  function sleep(ms) {
@@ -9,9 +9,15 @@ function sleep(ms) {
9
9
  export async function runServiceLoop(bridgeEnv) {
10
10
  const identity = ensurePairingIdentity();
11
11
  refreshPairingCode(identity);
12
- const boot = () => {
12
+ const boot = async () => {
13
13
  if (isBridgeRunning())
14
14
  return;
15
+ const cdpUrl = bridgeEnv.CDP_URL ?? 'http://127.0.0.1:9222';
16
+ const cdpOk = await ensureCursorCdp({ cdpUrl, noRestartCursor: false });
17
+ if (!cdpOk) {
18
+ console.error('[cursorconnect] service: CDP недоступен — bridge не стартует (нужен порт 9222)');
19
+ return;
20
+ }
15
21
  try {
16
22
  startBridge(bridgeEnv);
17
23
  console.log(`[cursorconnect] service: bridge started → ${BRIDGE_LOG_FILE}`);
@@ -20,12 +26,12 @@ export async function runServiceLoop(bridgeEnv) {
20
26
  console.error('[cursorconnect] service: start failed', e);
21
27
  }
22
28
  };
23
- boot();
29
+ await boot();
24
30
  for (;;) {
25
31
  await sleep(WATCH_MS);
26
32
  if (!isBridgeRunning()) {
27
33
  console.error('[cursorconnect] service: bridge exited, restarting…');
28
- boot();
34
+ await boot();
29
35
  }
30
36
  }
31
37
  }
@@ -39,6 +39,7 @@ export function buildStartupReadiness(identity, local, relay, relayReachable) {
39
39
  const tokensRegistered = relay?.tokensRegistered ?? 0;
40
40
  const tokenRegistered = relay?.tokenRegistered === true;
41
41
  const ready = local.ok &&
42
+ local.cdp &&
42
43
  codeValid &&
43
44
  relayReachable &&
44
45
  connectorInRoom &&
@@ -145,6 +146,11 @@ export function printStartupFailure(r, logPath = BRIDGE_LOG_FILE) {
145
146
  else if (!r.tokenRegistered) {
146
147
  console.error(' Токен не зарегистрирован — перезапустите bridge (cursorconnect start).');
147
148
  }
149
+ if (!r.localCdp) {
150
+ console.error(' CDP недоступен: Cursor должен быть с --remote-debugging-port=9222');
151
+ console.error(` ${'open -a Cursor --args --remote-debugging-port=9222'}`);
152
+ console.error(' Затем: cursorconnect stop && cursorconnect start');
153
+ }
148
154
  if (!r.localBridgeOk) {
149
155
  console.error(` Лог: ${logPath}`);
150
156
  tailLogLines(logPath, 12).forEach((l) => console.error(` ${l}`));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cursorconnect",
3
- "version": "0.1.8",
3
+ "version": "0.1.9",
4
4
  "description": "CLI: Cursor Connect on Mac + relay pairing — install once, run from anywhere",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "minCliVersion": "0.1.7",
3
3
  "minAppVersion": "0.2.2",
4
- "latestCliVersion": "0.1.8",
4
+ "latestCliVersion": "0.1.9",
5
5
  "latestAppVersion": "0.2.2",
6
6
  "updateCliCommand": "npm install -g cursorconnect@latest",
7
7
  "updateAppHint": "Обновите CursorConnect в App Store / TestFlight до последней сборки."