@hover-dev/core 0.8.0 → 0.9.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.
@@ -0,0 +1,18 @@
1
+ import type { AgentDescriptor, ParserState } from './types.js';
2
+ export declare const cursorAgent: AgentDescriptor;
3
+ /**
4
+ * Test-only escape hatches. Same pattern as codex.ts so the tests can drive
5
+ * the parser without going through invokeAgent.
6
+ */
7
+ export declare const __testing: {
8
+ freshState: () => ParserState;
9
+ resetCounters: (state: ParserState) => void;
10
+ getState: (state: ParserState) => {
11
+ runningTurns: number;
12
+ runningSessionId: string | undefined;
13
+ runningModel: string | undefined;
14
+ lastAssistantText: string | undefined;
15
+ sawErrorEvent: boolean;
16
+ };
17
+ };
18
+ //# sourceMappingURL=cursor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cursor.d.ts","sourceRoot":"","sources":["../../src/agents/cursor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAA8B,WAAW,EAAE,MAAM,YAAY,CAAC;AAoL3F,eAAO,MAAM,WAAW,EAAE,eAuJzB,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,SAAS;sBACJ,WAAW;2BACJ,WAAW;sBAChB,WAAW;;;;;;;CAU9B,CAAC"}
@@ -0,0 +1,229 @@
1
+ function cursorState(state) {
2
+ if (typeof state.runningTurns !== 'number') {
3
+ state.runningTurns = 0;
4
+ state.runningSessionId = undefined;
5
+ state.runningModel = undefined;
6
+ state.lastAssistantText = undefined;
7
+ state.sawErrorEvent = false;
8
+ state.toolNameByCallId = new Map();
9
+ }
10
+ return state;
11
+ }
12
+ function resetCursorCounters(s) {
13
+ s.runningTurns = 0;
14
+ s.runningSessionId = undefined;
15
+ s.runningModel = undefined;
16
+ s.lastAssistantText = undefined;
17
+ s.sawErrorEvent = false;
18
+ s.toolNameByCallId.clear();
19
+ }
20
+ /**
21
+ * Best-effort extraction of a tool's name from the `tool_call` envelope.
22
+ * Cursor's stream-json wraps each kind in a sub-object keyed by name
23
+ * (`shellToolCall`, `mcpToolCall`, etc.) but doesn't publish a stable
24
+ * `name` field at the top level. We:
25
+ * 1. Look for the first key that ends in `ToolCall` → strip the suffix.
26
+ * `shellToolCall` → `shell`, `mcpToolCall` → `mcp`.
27
+ * 2. If the sub-object carries a `tool` / `name` field, prefer that
28
+ * (mcp calls embed the playwright tool name there).
29
+ * 3. Strip the `mcp__playwright__` / `mcp__hover-playwright__` prefix to
30
+ * match the normalised tool names claude / codex emit.
31
+ */
32
+ function extractToolName(tc) {
33
+ if (!tc)
34
+ return { tool: 'unknown', input: undefined };
35
+ const wrapperKey = Object.keys(tc).find(k => k.endsWith('ToolCall'));
36
+ const inner = (wrapperKey ? tc[wrapperKey] : undefined) ?? undefined;
37
+ // Prefer the inner sub-tool name if it exists (MCP case).
38
+ const innerName = (inner && typeof inner === 'object' && 'tool' in inner && typeof inner.tool === 'string' && inner.tool) ||
39
+ (inner && typeof inner === 'object' && 'name' in inner && typeof inner.name === 'string' && inner.name) ||
40
+ null;
41
+ const kindFromKey = wrapperKey ? wrapperKey.replace(/ToolCall$/, '') : 'unknown';
42
+ const rawName = innerName || kindFromKey;
43
+ const tool = rawName
44
+ .replace(/^mcp__playwright__/, '')
45
+ .replace(/^mcp__hover-playwright__/, '');
46
+ const input = (inner && typeof inner === 'object' && 'input' in inner && inner.input) ||
47
+ (inner && typeof inner === 'object' && 'arguments' in inner && inner.arguments) ||
48
+ (inner && typeof inner === 'object' && 'args' in inner && inner.args) ||
49
+ inner;
50
+ return { tool, input };
51
+ }
52
+ function detectToolError(tc) {
53
+ if (!tc || typeof tc !== 'object')
54
+ return false;
55
+ const wrapperKey = Object.keys(tc).find(k => k.endsWith('ToolCall'));
56
+ const inner = wrapperKey ? tc[wrapperKey] : undefined;
57
+ if (!inner)
58
+ return false;
59
+ if (inner.is_error === true)
60
+ return true;
61
+ if (typeof inner.status === 'string' && /error|fail/i.test(inner.status))
62
+ return true;
63
+ return false;
64
+ }
65
+ /**
66
+ * The closest analogue Cursor has to claude's --append-system-prompt or
67
+ * codex's developer_instructions. Since there is no CLI flag, we prepend
68
+ * this to the user prompt so the agent sees it as the leading instruction.
69
+ */
70
+ const CURSOR_PROMPT_PREFACE = [
71
+ 'You are operating in Hover, a browser-testing tool.',
72
+ 'Use ONLY the MCP playwright tools (prefixed `mcp__playwright__` / `mcp__hover-playwright__`) to drive the browser.',
73
+ 'Do NOT use shell, file-edit, web-search, or any other built-in tool.',
74
+ 'Do NOT navigate to a URL the user is already on; check the page state via `browser_snapshot` first.',
75
+ 'When the task is complete, emit a short summary and stop.',
76
+ ].join(' ');
77
+ export const cursorAgent = {
78
+ id: 'cursor',
79
+ binName: 'cursor-agent',
80
+ protocol: 'argv',
81
+ streamFormat: 'json-lines',
82
+ sandboxStrength: 'soft',
83
+ display: {
84
+ label: 'Cursor',
85
+ tagline: 'Cursor — soft sandbox (no built-in tool deny-list)',
86
+ homepage: 'https://cursor.com/docs/cli/overview',
87
+ installHint: 'curl https://cursor.com/install -fsS | bash',
88
+ },
89
+ buildArgs(opts) {
90
+ // The HOVER-mode preface plus any caller-supplied appendSystemPrompt
91
+ // gets prepended to the prompt. This is the closest functional analogue
92
+ // Cursor has to claude's --append-system-prompt / codex's
93
+ // developer_instructions, because Cursor exposes no CLI flag for it.
94
+ const preface = opts.appendSystemPrompt && opts.appendSystemPrompt.trim().length > 0
95
+ ? `${CURSOR_PROMPT_PREFACE} ${opts.appendSystemPrompt}`
96
+ : CURSOR_PROMPT_PREFACE;
97
+ const finalPrompt = `${preface}\n\n${opts.prompt}`;
98
+ const args = ['-p', finalPrompt];
99
+ // NDJSON streaming output.
100
+ args.push('--output-format', 'stream-json');
101
+ // Non-interactive: auto-approve commands and MCP tools so the run doesn't
102
+ // hang waiting for permission. Cursor calls this --force / --yolo.
103
+ args.push('--force');
104
+ if (opts.model) {
105
+ args.push('--model', opts.model);
106
+ }
107
+ if (opts.sessionId) {
108
+ // Cursor's --resume accepts the chat_id. Empty / no-arg --resume
109
+ // resumes the latest, which is NOT what we want here.
110
+ args.push('--resume', opts.sessionId);
111
+ }
112
+ // MCP servers are configured in ~/.cursor/mcp.json (or repo-local
113
+ // .cursor/mcp.json) at install time, not per-invocation. Cursor has no
114
+ // equivalent of claude's --mcp-config. If the caller passed opts.mcpConfig
115
+ // we don't have a way to forward it; service.ts logs a one-time warning.
116
+ // No equivalent for --max-budget-usd or --allowedTools / --disallowedTools.
117
+ return args;
118
+ },
119
+ parseEvent(line, state = {}) {
120
+ if (!line.trim())
121
+ return [];
122
+ let ev;
123
+ try {
124
+ ev = JSON.parse(line);
125
+ }
126
+ catch {
127
+ return [{ kind: 'raw', line }];
128
+ }
129
+ const s = cursorState(state);
130
+ const out = [];
131
+ if (ev.type === 'system' && ev.subtype === 'init') {
132
+ resetCursorCounters(s);
133
+ s.runningModel = ev.model;
134
+ if (ev.session_id) {
135
+ s.runningSessionId = ev.session_id;
136
+ out.push({ kind: 'session_start', sessionId: ev.session_id, model: ev.model });
137
+ }
138
+ return out;
139
+ }
140
+ if (ev.type === 'tool_call' && ev.subtype === 'started') {
141
+ const { tool, input } = extractToolName(ev.tool_call);
142
+ if (ev.call_id)
143
+ s.toolNameByCallId.set(ev.call_id, tool);
144
+ out.push({ kind: 'tool_use', tool, input });
145
+ return out;
146
+ }
147
+ if (ev.type === 'tool_call' && ev.subtype === 'completed') {
148
+ const isError = detectToolError(ev.tool_call);
149
+ out.push({ kind: 'tool_result', isError });
150
+ return out;
151
+ }
152
+ if (ev.type === 'assistant') {
153
+ s.runningTurns += 1;
154
+ // Emit a usage event so the widget can advance its turn counter even
155
+ // though Cursor gives us no token / $ data. costUsd intentionally
156
+ // omitted — we don't fabricate a number.
157
+ out.push({ kind: 'usage', turns: s.runningTurns });
158
+ for (const block of ev.message?.content ?? []) {
159
+ if (block.type === 'text') {
160
+ const text = block.text?.trim();
161
+ if (text) {
162
+ s.lastAssistantText = text;
163
+ out.push({ kind: 'text', text });
164
+ }
165
+ }
166
+ }
167
+ return out;
168
+ }
169
+ if (ev.type === 'result') {
170
+ // Cursor's result event IS the session_end. We forward it directly so
171
+ // onStreamEnd doesn't need to synthesize.
172
+ const isError = ev.is_error === true ||
173
+ (typeof ev.subtype === 'string' && /error|fail/i.test(ev.subtype));
174
+ if (isError)
175
+ s.sawErrorEvent = true;
176
+ out.push({
177
+ kind: 'session_end',
178
+ turns: s.runningTurns,
179
+ // costUsd intentionally undefined — Cursor doesn't publish $ or tokens.
180
+ isError,
181
+ summary: ev.result ?? s.lastAssistantText,
182
+ });
183
+ return out;
184
+ }
185
+ // Cursor sometimes emits error envelopes mid-stream; surface them as
186
+ // text so the widget shows the problem instead of silently hanging.
187
+ if (ev.type && /error/i.test(ev.type)) {
188
+ s.sawErrorEvent = true;
189
+ // No documented `message` field on these — best-effort.
190
+ const msg = ev.result ?? `[cursor] ${ev.type}`;
191
+ out.push({ kind: 'text', text: msg });
192
+ return out;
193
+ }
194
+ return [];
195
+ },
196
+ /**
197
+ * Cursor's `result` event already produces a session_end via parseEvent;
198
+ * this fallback is for the case where the child exits without emitting a
199
+ * `result` (e.g. crash, signal). Mirrors codex.ts's shape.
200
+ */
201
+ onStreamEnd(exitCode, state = {}) {
202
+ const s = cursorState(state);
203
+ return {
204
+ kind: 'session_end',
205
+ turns: s.runningTurns,
206
+ // costUsd intentionally undefined — see parseEvent note.
207
+ isError: s.sawErrorEvent || (exitCode != null && exitCode !== 0),
208
+ summary: s.lastAssistantText,
209
+ };
210
+ },
211
+ };
212
+ /**
213
+ * Test-only escape hatches. Same pattern as codex.ts so the tests can drive
214
+ * the parser without going through invokeAgent.
215
+ */
216
+ export const __testing = {
217
+ freshState: () => ({}),
218
+ resetCounters: (state) => resetCursorCounters(cursorState(state)),
219
+ getState: (state) => {
220
+ const s = cursorState(state);
221
+ return {
222
+ runningTurns: s.runningTurns,
223
+ runningSessionId: s.runningSessionId,
224
+ runningModel: s.runningModel,
225
+ lastAssistantText: s.lastAssistantText,
226
+ sawErrorEvent: s.sawErrorEvent,
227
+ };
228
+ },
229
+ };
@@ -2,10 +2,10 @@ import type { AgentDescriptor } from './types.js';
2
2
  /**
3
3
  * Registry of agents Hover can drive.
4
4
  *
5
- * To add support for another agent (e.g. cursor-agent, aider, gemini, cline,
6
- * continue, qwen, kilo), implement its AgentDescriptor in its own file and
7
- * register it here. The rest of the system — detect, argv, invoke, service,
8
- * widget — works without further changes.
5
+ * To add support for another agent (e.g. aider, gemini, cline, continue,
6
+ * qwen, kilo), implement its AgentDescriptor in its own file and register
7
+ * it here. The rest of the system — detect, argv, invoke, service, widget —
8
+ * works without further changes.
9
9
  *
10
10
  * Insertion order is the order shown in the widget's agent dropdown, so put
11
11
  * the recommended primary first.
@@ -1 +1 @@
1
- {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/agents/registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAIlD;;;;;;;;;;GAUG;AACH,eAAO,MAAM,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAGlD,CAAC;AAEF,wBAAgB,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,eAAe,GAAG,SAAS,CAEhE;AAED,+DAA+D;AAC/D,wBAAgB,UAAU,IAAI,eAAe,EAAE,CAE9C"}
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/agents/registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAKlD;;;;;;;;;;GAUG;AACH,eAAO,MAAM,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAIlD,CAAC;AAEF,wBAAgB,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,eAAe,GAAG,SAAS,CAEhE;AAED,+DAA+D;AAC/D,wBAAgB,UAAU,IAAI,eAAe,EAAE,CAE9C"}
@@ -1,12 +1,13 @@
1
1
  import { claudeAgent } from './claude.js';
2
2
  import { codexAgent } from './codex.js';
3
+ import { cursorAgent } from './cursor.js';
3
4
  /**
4
5
  * Registry of agents Hover can drive.
5
6
  *
6
- * To add support for another agent (e.g. cursor-agent, aider, gemini, cline,
7
- * continue, qwen, kilo), implement its AgentDescriptor in its own file and
8
- * register it here. The rest of the system — detect, argv, invoke, service,
9
- * widget — works without further changes.
7
+ * To add support for another agent (e.g. aider, gemini, cline, continue,
8
+ * qwen, kilo), implement its AgentDescriptor in its own file and register
9
+ * it here. The rest of the system — detect, argv, invoke, service, widget —
10
+ * works without further changes.
10
11
  *
11
12
  * Insertion order is the order shown in the widget's agent dropdown, so put
12
13
  * the recommended primary first.
@@ -14,6 +15,7 @@ import { codexAgent } from './codex.js';
14
15
  export const AGENTS = {
15
16
  [claudeAgent.id]: claudeAgent,
16
17
  [codexAgent.id]: codexAgent,
18
+ [cursorAgent.id]: cursorAgent,
17
19
  };
18
20
  export function getAgent(id) {
19
21
  return AGENTS[id];
@@ -139,6 +139,16 @@ export interface HoverPluginManifest {
139
139
  * here so the widget side can be tree-shaken to skip handlers for
140
140
  * events that no loaded plugin will ever produce. */
141
141
  widgetEventTypes?: string[];
142
+ /** Absolute path to a JS module that runs inside the widget's Shadow
143
+ * DOM. The host reads this file at bundle-assembly time, inlines it
144
+ * as a `<script type="module">` after the widget core, and exposes
145
+ * `window.__HOVER_WIDGET__` for the module to register itself.
146
+ *
147
+ * Plugin authors typically resolve this via `import.meta` or
148
+ * `fileURLToPath(new URL('./widget.js', import.meta.url))` from
149
+ * inside their server-side entry. If absent, the plugin contributes
150
+ * no widget code (server-side-only plugin). */
151
+ widgetEntry?: string;
142
152
  hooks?: HoverHooks;
143
153
  }
144
154
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"plugin-api.d.ts","sourceRoot":"","sources":["../src/plugin-api.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH;;;;GAIG;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC;AAChC,eAAO,MAAM,mBAAmB,EAAE,eAAmB,CAAC;AAMtD,MAAM,WAAW,eAAe;IAC9B,uEAAuE;IACvE,EAAE,EAAE,MAAM,CAAC;IACX,4DAA4D;IAC5D,KAAK,EAAE,MAAM,CAAC;IACd,iDAAiD;IACjD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;gEAC4D;IAC5D,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;CAC1B;AAED,MAAM,WAAW,oBAAoB;IACnC;gDAC4C;IAC5C,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B;8DAC0D;IAC1D,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;CAC1B;AAED,MAAM,WAAW,sBAAsB;IACrC,qDAAqD;IACrD,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB;iFAC6E;IAC7E,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;2EACuE;IACvE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;yDAEqD;IACrD,KAAK,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IACvC,6EAA6E;IAC7E,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;CAC1B;AAED,MAAM,WAAW,+BAA+B;IAC9C,IAAI,EAAE,MAAM,CAAC;IACb;uDACmD;IACnD,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;CAC1B;AAMD,MAAM,WAAW,cAAc;IAC7B;sEACkE;IAClE,CAAC,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI,CAAC;CACpD;AAED,MAAM,WAAW,gBAAgB;IAC/B;;yBAEqB;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,qDAAqD;IACrD,SAAS,EAAE,cAAc,CAAC;CAC3B;AAED;;2EAE2E;AAC3E,MAAM,WAAW,eAAgB,SAAQ,gBAAgB;IACvD,MAAM,EAAE,MAAM,CAAC;IACf;6DACyD;IACzD,cAAc,CAAC,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,GAAG,IAAI,CAAC;IACnE;;;;;sDAKkD;IAClD,eAAe,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC;CAChE;AAED;oDACoD;AACpD,MAAM,WAAW,iBAAkB,SAAQ,gBAAgB;IACzD,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;gEACgE;AAChE,MAAM,MAAM,WAAW,GAAG,gBAAgB,CAAC;AAE3C,MAAM,WAAW,UAAU;IACzB,qBAAqB,CAAC,EAAE,CAAC,GAAG,EAAE,eAAe,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACvE,uBAAuB,CAAC,EAAE,CAAC,GAAG,EAAE,iBAAiB,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3E,wBAAwB,CAAC,EAAE,CAAC,GAAG,EAAE,WAAW,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACvE;AAMD,MAAM,WAAW,mBAAmB;IAClC,8DAA8D;IAC9D,UAAU,EAAE,eAAe,CAAC;IAE5B,6DAA6D;IAC7D,IAAI,EAAE,MAAM,CAAC;IAEb,uDAAuD;IACvD,IAAI,CAAC,EAAE,eAAe,CAAC;IAEvB,qEAAqE;IACrE,UAAU,CAAC,EAAE,oBAAoB,EAAE,CAAC;IAEpC,uDAAuD;IACvD,WAAW,CAAC,EAAE,sBAAsB,CAAC;IAErC;+BAC2B;IAC3B,qBAAqB,CAAC,EAAE,+BAA+B,EAAE,CAAC;IAE1D;;0DAEsD;IACtD,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAE5B,KAAK,CAAC,EAAE,UAAU,CAAC;CACpB;AAMD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,GAAG,IAAI,EAC5C,OAAO,EAAE,CAAC,IAAI,EAAE,KAAK,KAAK,mBAAmB,GAC5C,CAAC,IAAI,EAAE,KAAK,KAAK,mBAAmB,CAYtC"}
1
+ {"version":3,"file":"plugin-api.d.ts","sourceRoot":"","sources":["../src/plugin-api.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hover-dev/core",
3
- "version": "0.8.0",
3
+ "version": "0.9.0",
4
4
  "description": "Hover's local Node service: agent invocation, Playwright CDP preflight, WebSocket bridge.",
5
5
  "license": "Apache-2.0",
6
6
  "author": "Hyperyond",