@peekdev/mcp 0.1.0-alpha.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/NOTICE +10 -0
- package/dist/db/index.d.ts +3 -0
- package/dist/db/index.d.ts.map +1 -0
- package/dist/db/index.js +7 -0
- package/dist/db/index.js.map +1 -0
- package/dist/db/migrate.d.ts +37 -0
- package/dist/db/migrate.d.ts.map +1 -0
- package/dist/db/migrate.js +86 -0
- package/dist/db/migrate.js.map +1 -0
- package/dist/db/migrations/0001_initial.sql +102 -0
- package/dist/db/migrations/0002_network_bodies.sql +15 -0
- package/dist/db/open.d.ts +57 -0
- package/dist/db/open.d.ts.map +1 -0
- package/dist/db/open.js +74 -0
- package/dist/db/open.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +58 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp/action-schema.d.ts +223 -0
- package/dist/mcp/action-schema.d.ts.map +1 -0
- package/dist/mcp/action-schema.js +97 -0
- package/dist/mcp/action-schema.js.map +1 -0
- package/dist/mcp/event-blobs.d.ts +32 -0
- package/dist/mcp/event-blobs.d.ts.map +1 -0
- package/dist/mcp/event-blobs.js +65 -0
- package/dist/mcp/event-blobs.js.map +1 -0
- package/dist/mcp/event-walker.d.ts +86 -0
- package/dist/mcp/event-walker.d.ts.map +1 -0
- package/dist/mcp/event-walker.js +398 -0
- package/dist/mcp/event-walker.js.map +1 -0
- package/dist/mcp/host-bridge.d.ts +80 -0
- package/dist/mcp/host-bridge.d.ts.map +1 -0
- package/dist/mcp/host-bridge.js +88 -0
- package/dist/mcp/host-bridge.js.map +1 -0
- package/dist/mcp/index.d.ts +8 -0
- package/dist/mcp/index.d.ts.map +1 -0
- package/dist/mcp/index.js +32 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/mcp/playwright-repro.d.ts +19 -0
- package/dist/mcp/playwright-repro.d.ts.map +1 -0
- package/dist/mcp/playwright-repro.js +78 -0
- package/dist/mcp/playwright-repro.js.map +1 -0
- package/dist/mcp/queries.d.ts +73 -0
- package/dist/mcp/queries.d.ts.map +1 -0
- package/dist/mcp/queries.js +139 -0
- package/dist/mcp/queries.js.map +1 -0
- package/dist/mcp/roots.d.ts +50 -0
- package/dist/mcp/roots.d.ts.map +1 -0
- package/dist/mcp/roots.js +97 -0
- package/dist/mcp/roots.js.map +1 -0
- package/dist/mcp/rrweb-types.d.ts +3 -0
- package/dist/mcp/rrweb-types.d.ts.map +1 -0
- package/dist/mcp/rrweb-types.js +7 -0
- package/dist/mcp/rrweb-types.js.map +1 -0
- package/dist/mcp/selector.d.ts +54 -0
- package/dist/mcp/selector.d.ts.map +1 -0
- package/dist/mcp/selector.js +209 -0
- package/dist/mcp/selector.js.map +1 -0
- package/dist/mcp/server.d.ts +49 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +469 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp/summary.d.ts +26 -0
- package/dist/mcp/summary.d.ts.map +1 -0
- package/dist/mcp/summary.js +74 -0
- package/dist/mcp/summary.js.map +1 -0
- package/dist/native-host/action-protocol.d.ts +49 -0
- package/dist/native-host/action-protocol.d.ts.map +1 -0
- package/dist/native-host/action-protocol.js +36 -0
- package/dist/native-host/action-protocol.js.map +1 -0
- package/dist/native-host/audit.d.ts +69 -0
- package/dist/native-host/audit.d.ts.map +1 -0
- package/dist/native-host/audit.js +85 -0
- package/dist/native-host/audit.js.map +1 -0
- package/dist/native-host/config.d.ts +18 -0
- package/dist/native-host/config.d.ts.map +1 -0
- package/dist/native-host/config.js +56 -0
- package/dist/native-host/config.js.map +1 -0
- package/dist/native-host/extension-ids.json +6 -0
- package/dist/native-host/host.d.ts +30 -0
- package/dist/native-host/host.d.ts.map +1 -0
- package/dist/native-host/host.js +96 -0
- package/dist/native-host/host.js.map +1 -0
- package/dist/native-host/index.d.ts +4 -0
- package/dist/native-host/index.d.ts.map +1 -0
- package/dist/native-host/index.js +8 -0
- package/dist/native-host/index.js.map +1 -0
- package/dist/native-host/ingest.d.ts +83 -0
- package/dist/native-host/ingest.d.ts.map +1 -0
- package/dist/native-host/ingest.js +283 -0
- package/dist/native-host/ingest.js.map +1 -0
- package/dist/native-host/installer.d.ts +64 -0
- package/dist/native-host/installer.d.ts.map +1 -0
- package/dist/native-host/installer.js +110 -0
- package/dist/native-host/installer.js.map +1 -0
- package/dist/native-host/manifest.d.ts +64 -0
- package/dist/native-host/manifest.d.ts.map +1 -0
- package/dist/native-host/manifest.js +117 -0
- package/dist/native-host/manifest.js.map +1 -0
- package/dist/native-host/policy.d.ts +60 -0
- package/dist/native-host/policy.d.ts.map +1 -0
- package/dist/native-host/policy.js +116 -0
- package/dist/native-host/policy.js.map +1 -0
- package/dist/native-host/request-registry.d.ts +55 -0
- package/dist/native-host/request-registry.d.ts.map +1 -0
- package/dist/native-host/request-registry.js +111 -0
- package/dist/native-host/request-registry.js.map +1 -0
- package/dist/native-host/transport.d.ts +54 -0
- package/dist/native-host/transport.d.ts.map +1 -0
- package/dist/native-host/transport.js +113 -0
- package/dist/native-host/transport.js.map +1 -0
- package/dist/postinstall.d.ts +3 -0
- package/dist/postinstall.d.ts.map +1 -0
- package/dist/postinstall.js +72 -0
- package/dist/postinstall.js.map +1 -0
- package/package.json +59 -0
- package/src/db/migrations/0001_initial.sql +102 -0
- package/src/db/migrations/0002_network_bodies.sql +15 -0
- package/src/native-host/extension-ids.json +6 -0
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
// Native-host ingest pipeline (Task #44 — capture-loop closure).
|
|
2
|
+
//
|
|
3
|
+
// The SW already builds the four message types defined in
|
|
4
|
+
// `peek-extension/src/background/native-protocol.ts`. This module turns them
|
|
5
|
+
// into:
|
|
6
|
+
// - `~/.peek/rrweb-events/<sessionId>/<seq>.json.gz` chunk blobs
|
|
7
|
+
// - `events_chunks` index rows (path + byte range)
|
|
8
|
+
// - `console_events` / `network_events` rows
|
|
9
|
+
// - a `sessions` upsert keyed by sessionId
|
|
10
|
+
//
|
|
11
|
+
// Per ADR-0007 the SQLite DB stores ONLY pointers + extracted rows; the rrweb
|
|
12
|
+
// event bodies live on disk in gzipped chunks so the DB file stays small and
|
|
13
|
+
// queryable. The chunk file's path is recorded in `events_chunks.byte_offset
|
|
14
|
+
// = 0`, `byte_length = file_size`; we treat each chunk as its own gzip member,
|
|
15
|
+
// not a concatenated stream, which keeps appends trivially crash-safe.
|
|
16
|
+
//
|
|
17
|
+
// Hardening: every public entry point returns a structured reply (never
|
|
18
|
+
// throws). A FK error, a malformed shape, or a disk full doesn't tear down the
|
|
19
|
+
// host loop — the SW gets a `.err` reply and retries (per the SW's contract
|
|
20
|
+
// the host loop survives).
|
|
21
|
+
import { mkdirSync, statSync, writeFileSync } from 'node:fs';
|
|
22
|
+
import { join } from 'node:path';
|
|
23
|
+
import { gzipSync } from 'node:zlib';
|
|
24
|
+
/** Absolute path to the rrweb-events chunk store under PEEK_HOME. */
|
|
25
|
+
export function rrwebEventsDir(home) {
|
|
26
|
+
return join(home, 'rrweb-events');
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Dispatch one ingest message to the appropriate handler. Pure with respect to
|
|
30
|
+
* the network: takes a context, returns a reply. Every error path returns a
|
|
31
|
+
* structured `.err` reply — never throws.
|
|
32
|
+
*/
|
|
33
|
+
export function ingest(message, ctx) {
|
|
34
|
+
try {
|
|
35
|
+
switch (message.type) {
|
|
36
|
+
case 'session.append':
|
|
37
|
+
return ingestSessionAppend(message, ctx);
|
|
38
|
+
case 'console.append':
|
|
39
|
+
return ingestConsoleAppend(message, ctx);
|
|
40
|
+
case 'network.append':
|
|
41
|
+
return ingestNetworkAppend(message, ctx);
|
|
42
|
+
case 'shadow.report':
|
|
43
|
+
return ingestShadowReport(message, ctx);
|
|
44
|
+
default: {
|
|
45
|
+
const type = message.type ?? '(none)';
|
|
46
|
+
return {
|
|
47
|
+
type: 'ingest.err',
|
|
48
|
+
code: 'unknown_type',
|
|
49
|
+
detail: `no handler for message type '${type}'`,
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
catch (err) {
|
|
55
|
+
// Defense in depth: any uncaught throw from a handler becomes a structured
|
|
56
|
+
// error reply rather than tearing down the host loop.
|
|
57
|
+
return {
|
|
58
|
+
type: 'ingest.err',
|
|
59
|
+
code: 'handler_threw',
|
|
60
|
+
detail: err instanceof Error ? err.message : String(err),
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
// ---------------------------------------------------------------------------
|
|
65
|
+
// session.append
|
|
66
|
+
// ---------------------------------------------------------------------------
|
|
67
|
+
function ingestSessionAppend(msg, ctx) {
|
|
68
|
+
if (typeof msg.sessionId !== 'string' || msg.sessionId.length === 0) {
|
|
69
|
+
return {
|
|
70
|
+
type: 'session.append.err',
|
|
71
|
+
code: 'missing_session_id',
|
|
72
|
+
detail: 'session.append requires sessionId',
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
if (!Array.isArray(msg.events) || msg.events.length === 0) {
|
|
76
|
+
return {
|
|
77
|
+
type: 'session.append.err',
|
|
78
|
+
sessionId: msg.sessionId,
|
|
79
|
+
code: 'empty_events',
|
|
80
|
+
detail: 'session.append requires at least one event',
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
const { startMs, endMs } = eventTimeRange(msg.events);
|
|
84
|
+
const nowIso = new Date().toISOString();
|
|
85
|
+
// Choose a seq: client-stamped (idempotent retry) or auto-incremented.
|
|
86
|
+
const nextSeqRow = ctx.db
|
|
87
|
+
.prepare('SELECT IFNULL(MAX(seq), -1) + 1 AS next FROM events_chunks WHERE session_id = ?')
|
|
88
|
+
.get(msg.sessionId);
|
|
89
|
+
const seq = msg.seq ?? nextSeqRow.next;
|
|
90
|
+
// Encode the chunk body to disk first, then index it in the DB. Order
|
|
91
|
+
// matters: a crash AFTER the file write but BEFORE the row insert leaves an
|
|
92
|
+
// orphan file (recoverable: a recovery pass can re-walk the dir + re-index).
|
|
93
|
+
// A crash AFTER the row insert but BEFORE the file write would leave a
|
|
94
|
+
// dangling pointer the reader would 404 on — strictly worse.
|
|
95
|
+
const body = Buffer.from(JSON.stringify(msg.events), 'utf8');
|
|
96
|
+
const gz = gzipSync(body);
|
|
97
|
+
const dir = join(rrwebEventsDir(ctx.home), msg.sessionId);
|
|
98
|
+
mkdirSync(dir, { recursive: true });
|
|
99
|
+
const blobPath = join(dir, `${seq}.json.gz`);
|
|
100
|
+
writeFileSync(blobPath, gz);
|
|
101
|
+
const fileBytes = gz.length;
|
|
102
|
+
// Upsert the parent session, then INSERT OR IGNORE the chunk row, then
|
|
103
|
+
// accumulate event_count + bytes — all in one transaction so a retry of a
|
|
104
|
+
// dup seq doesn't double-count and a partial failure rolls back.
|
|
105
|
+
const origin = msg.url ? safeOrigin(msg.url) : undefined;
|
|
106
|
+
const upsertSession = ctx.db.prepare(`INSERT INTO sessions (id, created_at, updated_at, url, title, origin, event_count, bytes, events_blob_path)
|
|
107
|
+
VALUES (?, ?, ?, ?, ?, ?, 0, 0, ?)
|
|
108
|
+
ON CONFLICT(id) DO UPDATE SET
|
|
109
|
+
updated_at = excluded.updated_at,
|
|
110
|
+
url = COALESCE(excluded.url, sessions.url),
|
|
111
|
+
title = COALESCE(excluded.title, sessions.title),
|
|
112
|
+
origin = COALESCE(excluded.origin, sessions.origin)`);
|
|
113
|
+
const insertChunk = ctx.db.prepare(`INSERT OR IGNORE INTO events_chunks
|
|
114
|
+
(session_id, seq, start_ts_ms, end_ts_ms, event_count, byte_offset, byte_length, created_at)
|
|
115
|
+
VALUES (?, ?, ?, ?, ?, 0, ?, ?)`);
|
|
116
|
+
const accumulateSession = ctx.db.prepare(`UPDATE sessions
|
|
117
|
+
SET event_count = event_count + ?,
|
|
118
|
+
bytes = bytes + ?,
|
|
119
|
+
updated_at = ?
|
|
120
|
+
WHERE id = ?`);
|
|
121
|
+
const tx = ctx.db.transaction(() => {
|
|
122
|
+
upsertSession.run(msg.sessionId, nowIso, nowIso, msg.url ?? null, msg.title ?? null, origin ?? null,
|
|
123
|
+
// events_blob_path stays a per-session pointer label; chunk rows carry the per-seq path.
|
|
124
|
+
// We record the session-level directory (relative to PEEK_HOME) on first insert via the
|
|
125
|
+
// `?` placeholder above; the INSERT-OR-IGNORE on conflict won't update it (intentional).
|
|
126
|
+
join('rrweb-events', msg.sessionId));
|
|
127
|
+
const ins = insertChunk.run(msg.sessionId, seq, startMs, endMs, msg.events.length, fileBytes, nowIso);
|
|
128
|
+
if (ins.changes > 0) {
|
|
129
|
+
// Only accumulate when we actually inserted (a duplicate seq is a no-op).
|
|
130
|
+
accumulateSession.run(msg.events.length, fileBytes, nowIso, msg.sessionId);
|
|
131
|
+
}
|
|
132
|
+
});
|
|
133
|
+
tx();
|
|
134
|
+
return { type: 'session.append.ok', sessionId: msg.sessionId, seq };
|
|
135
|
+
}
|
|
136
|
+
// ---------------------------------------------------------------------------
|
|
137
|
+
// console.append
|
|
138
|
+
// ---------------------------------------------------------------------------
|
|
139
|
+
function ingestConsoleAppend(msg, ctx) {
|
|
140
|
+
if (typeof msg.sessionId !== 'string' || msg.sessionId.length === 0) {
|
|
141
|
+
return {
|
|
142
|
+
type: 'console.append.err',
|
|
143
|
+
code: 'missing_session_id',
|
|
144
|
+
detail: 'console.append requires sessionId',
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
const events = Array.isArray(msg.events) ? msg.events : [];
|
|
148
|
+
if (events.length === 0) {
|
|
149
|
+
return { type: 'console.append.ok', sessionId: msg.sessionId, count: 0 };
|
|
150
|
+
}
|
|
151
|
+
const insert = ctx.db.prepare('INSERT INTO console_events (session_id, ts_ms, level, message, url) VALUES (?, ?, ?, ?, ?)');
|
|
152
|
+
// ensureSessionRow runs INSIDE the per-batch transaction so a child-insert
|
|
153
|
+
// failure (disk full, NOT NULL violation, FK error) rolls back the parent
|
|
154
|
+
// upsert too — otherwise a failed batch leaves an empty `sessions` row.
|
|
155
|
+
const tx = ctx.db.transaction((rows) => {
|
|
156
|
+
ensureSessionRow(ctx.db, msg.sessionId, msg.url, msg.title);
|
|
157
|
+
for (const ev of rows) {
|
|
158
|
+
const ts = typeof ev.ts === 'number' ? ev.ts : Date.now();
|
|
159
|
+
const level = typeof ev.level === 'string' && ev.level.length > 0 ? ev.level : 'log';
|
|
160
|
+
const args = Array.isArray(ev.args) ? ev.args : [];
|
|
161
|
+
// The args[] array is the masked, already-stringified console arg list
|
|
162
|
+
// (see peek-extension/src/relay/mask.ts). Joining matches the rrweb
|
|
163
|
+
// console-plugin's natural format (one logical line per call).
|
|
164
|
+
const message = args.join(' ');
|
|
165
|
+
insert.run(msg.sessionId, ts, level, message, msg.url ?? null);
|
|
166
|
+
}
|
|
167
|
+
});
|
|
168
|
+
tx(events);
|
|
169
|
+
return { type: 'console.append.ok', sessionId: msg.sessionId, count: events.length };
|
|
170
|
+
}
|
|
171
|
+
// ---------------------------------------------------------------------------
|
|
172
|
+
// network.append
|
|
173
|
+
// ---------------------------------------------------------------------------
|
|
174
|
+
function ingestNetworkAppend(msg, ctx) {
|
|
175
|
+
if (typeof msg.sessionId !== 'string' || msg.sessionId.length === 0) {
|
|
176
|
+
return {
|
|
177
|
+
type: 'network.append.err',
|
|
178
|
+
code: 'missing_session_id',
|
|
179
|
+
detail: 'network.append requires sessionId',
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
const records = Array.isArray(msg.records) ? msg.records : [];
|
|
183
|
+
if (records.length === 0) {
|
|
184
|
+
return { type: 'network.append.ok', sessionId: msg.sessionId, count: 0 };
|
|
185
|
+
}
|
|
186
|
+
// Deep capture (ADR-0010): the relay-side mask runs `redactBody` BEFORE the
|
|
187
|
+
// body arrives here, so we just persist the already-masked string. Unset
|
|
188
|
+
// fields land as SQL NULL (not the literal "undefined" / empty string).
|
|
189
|
+
const insert = ctx.db.prepare(`INSERT INTO network_events
|
|
190
|
+
(session_id, ts_ms, method, url, status, status_text, request_id, resource_type, duration_ms, error_text, request_body_redacted, response_body_redacted)
|
|
191
|
+
VALUES (?, ?, ?, ?, ?, NULL, ?, ?, NULL, ?, ?, ?)`);
|
|
192
|
+
// ensureSessionRow runs INSIDE the per-batch transaction so a child-insert
|
|
193
|
+
// failure (disk full, NOT NULL violation, FK error) rolls back the parent
|
|
194
|
+
// upsert too — otherwise a failed batch leaves an empty `sessions` row.
|
|
195
|
+
const tx = ctx.db.transaction((rows) => {
|
|
196
|
+
ensureSessionRow(ctx.db, msg.sessionId, msg.url, msg.title);
|
|
197
|
+
for (const rec of rows) {
|
|
198
|
+
const ts = typeof rec.ts === 'number' ? rec.ts : Date.now();
|
|
199
|
+
const method = typeof rec.method === 'string' ? rec.method : rec.kind === 'request' ? 'GET' : 'GET';
|
|
200
|
+
const url = typeof rec.url === 'string' ? rec.url : '';
|
|
201
|
+
const status = typeof rec.status === 'number' ? rec.status : null;
|
|
202
|
+
const requestId = typeof rec.id === 'string' ? rec.id : null;
|
|
203
|
+
const resourceType = typeof rec.transport === 'string' ? rec.transport : null;
|
|
204
|
+
const errorText = typeof rec.error === 'string' ? rec.error : null;
|
|
205
|
+
const requestBody = typeof rec.requestBody === 'string' ? rec.requestBody : null;
|
|
206
|
+
const responseBody = typeof rec.responseBody === 'string' ? rec.responseBody : null;
|
|
207
|
+
insert.run(msg.sessionId, ts, method, url, status, requestId, resourceType, errorText, requestBody, responseBody);
|
|
208
|
+
}
|
|
209
|
+
});
|
|
210
|
+
tx(records);
|
|
211
|
+
return { type: 'network.append.ok', sessionId: msg.sessionId, count: records.length };
|
|
212
|
+
}
|
|
213
|
+
// ---------------------------------------------------------------------------
|
|
214
|
+
// shadow.report — deferred persistence (Phase 4)
|
|
215
|
+
// ---------------------------------------------------------------------------
|
|
216
|
+
function ingestShadowReport(msg, _ctx) {
|
|
217
|
+
if (typeof msg.sessionId !== 'string' || msg.sessionId.length === 0) {
|
|
218
|
+
return {
|
|
219
|
+
type: 'shadow.report.err',
|
|
220
|
+
code: 'missing_session_id',
|
|
221
|
+
detail: 'shadow.report requires sessionId',
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
const count = Array.isArray(msg.reports) ? msg.reports.length : 0;
|
|
225
|
+
// Reconnaissance shape — not a primary capture type. Persisted shape decision
|
|
226
|
+
// is deferred to Phase 4. For now we just log + acknowledge.
|
|
227
|
+
console.warn(`peek native host: shadow.report ack — ${count} report(s) for ${msg.sessionId}`);
|
|
228
|
+
return { type: 'shadow.report.ok', sessionId: msg.sessionId, count };
|
|
229
|
+
}
|
|
230
|
+
// ---------------------------------------------------------------------------
|
|
231
|
+
// helpers
|
|
232
|
+
// ---------------------------------------------------------------------------
|
|
233
|
+
/** Ensure the parent `sessions` row exists (FK target) before inserting children. */
|
|
234
|
+
function ensureSessionRow(db, sessionId, url, title) {
|
|
235
|
+
const origin = url ? safeOrigin(url) : undefined;
|
|
236
|
+
const nowIso = new Date().toISOString();
|
|
237
|
+
db.prepare(`INSERT INTO sessions (id, created_at, updated_at, url, title, origin)
|
|
238
|
+
VALUES (?, ?, ?, ?, ?, ?)
|
|
239
|
+
ON CONFLICT(id) DO UPDATE SET
|
|
240
|
+
updated_at = excluded.updated_at,
|
|
241
|
+
url = COALESCE(excluded.url, sessions.url),
|
|
242
|
+
title = COALESCE(excluded.title, sessions.title),
|
|
243
|
+
origin = COALESCE(excluded.origin, sessions.origin)`).run(sessionId, nowIso, nowIso, url ?? null, title ?? null, origin ?? null);
|
|
244
|
+
}
|
|
245
|
+
/** Min / max timestamp across an events batch. Defaults to now() for empty/missing. */
|
|
246
|
+
function eventTimeRange(events) {
|
|
247
|
+
let startMs = Number.POSITIVE_INFINITY;
|
|
248
|
+
let endMs = Number.NEGATIVE_INFINITY;
|
|
249
|
+
for (const ev of events) {
|
|
250
|
+
const ts = readTimestamp(ev);
|
|
251
|
+
if (ts === null)
|
|
252
|
+
continue;
|
|
253
|
+
if (ts < startMs)
|
|
254
|
+
startMs = ts;
|
|
255
|
+
if (ts > endMs)
|
|
256
|
+
endMs = ts;
|
|
257
|
+
}
|
|
258
|
+
if (!Number.isFinite(startMs) || !Number.isFinite(endMs)) {
|
|
259
|
+
const now = Date.now();
|
|
260
|
+
return { startMs: now, endMs: now };
|
|
261
|
+
}
|
|
262
|
+
return { startMs, endMs };
|
|
263
|
+
}
|
|
264
|
+
function readTimestamp(ev) {
|
|
265
|
+
if (typeof ev !== 'object' || ev === null)
|
|
266
|
+
return null;
|
|
267
|
+
const ts = ev.timestamp;
|
|
268
|
+
return typeof ts === 'number' && Number.isFinite(ts) ? ts : null;
|
|
269
|
+
}
|
|
270
|
+
function safeOrigin(url) {
|
|
271
|
+
try {
|
|
272
|
+
return new URL(url).origin;
|
|
273
|
+
}
|
|
274
|
+
catch {
|
|
275
|
+
return undefined;
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
// Internal helper exported for future test coverage of file size accounting.
|
|
279
|
+
export function _chunkFileSize(home, sessionId, seq) {
|
|
280
|
+
const path = join(rrwebEventsDir(home), sessionId, `${seq}.json.gz`);
|
|
281
|
+
return statSync(path).size;
|
|
282
|
+
}
|
|
283
|
+
//# sourceMappingURL=ingest.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ingest.js","sourceRoot":"","sources":["../../src/native-host/ingest.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import type { InstallTarget, NativeHostManifest } from './manifest.js';
|
|
2
|
+
/** Outcome of attempting to install one target. */
|
|
3
|
+
export interface InstallResult {
|
|
4
|
+
readonly browser: string;
|
|
5
|
+
/** Filesystem path written (darwin/linux + win32), if any. */
|
|
6
|
+
readonly manifestPath?: string;
|
|
7
|
+
/** Registry key written (win32), if any. */
|
|
8
|
+
readonly registryKey?: string;
|
|
9
|
+
/** True when a write actually happened (false in dry-run mode). */
|
|
10
|
+
readonly written: boolean;
|
|
11
|
+
/** Error message if the write failed; the run continues past failures. */
|
|
12
|
+
readonly error?: string;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Spawn shape `realSink.writeRegistryKey` uses to invoke `reg.exe`. Injectable
|
|
16
|
+
* so tests can capture argv without spawning a real Windows process.
|
|
17
|
+
*/
|
|
18
|
+
export type RegExecFn = (file: string, args: readonly string[]) => void;
|
|
19
|
+
/** Injectable side-effect surface (defaults to real fs + registry). */
|
|
20
|
+
export interface InstallSink {
|
|
21
|
+
/** Write a manifest JSON file at an absolute path (creating parent dirs). */
|
|
22
|
+
writeManifestFile(path: string, contents: string): void;
|
|
23
|
+
/**
|
|
24
|
+
* Point an HKCU registry key's default value at the on-disk manifest path.
|
|
25
|
+
* The manifest file is written separately via `writeManifestFile`; this
|
|
26
|
+
* function does NOT write the file. Errors propagate; the installer catches
|
|
27
|
+
* per-target.
|
|
28
|
+
*/
|
|
29
|
+
writeRegistryKey(key: string, manifestPath: string): void;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Build a real-OS sink. Exported so tests can inject a fake `execFn` while
|
|
33
|
+
* still exercising the platform guard. Production callers use {@link realSink}.
|
|
34
|
+
*/
|
|
35
|
+
export declare function buildRealSink(deps?: {
|
|
36
|
+
execFn?: RegExecFn;
|
|
37
|
+
platform?: NodeJS.Platform;
|
|
38
|
+
}): InstallSink;
|
|
39
|
+
/**
|
|
40
|
+
* Default real-OS sink (writes to disk + the Windows registry). Constructed
|
|
41
|
+
* once at module-load via {@link buildRealSink}; tests requiring custom
|
|
42
|
+
* platform / execFn should call `buildRealSink` directly instead of mutating
|
|
43
|
+
* this object.
|
|
44
|
+
*/
|
|
45
|
+
export declare const realSink: InstallSink;
|
|
46
|
+
export interface InstallOptions {
|
|
47
|
+
/** When true, report what would be written without writing (default false). */
|
|
48
|
+
readonly dryRun?: boolean;
|
|
49
|
+
/** Side-effect sink; defaults to the real fs/registry sink. */
|
|
50
|
+
readonly sink?: InstallSink;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Install `manifest` to every `target`. Failures are captured per-target (so
|
|
54
|
+
* one unwritable browser dir doesn't abort the rest) and returned in the
|
|
55
|
+
* result list. In `dryRun` mode nothing is written and every result has
|
|
56
|
+
* `written: false`.
|
|
57
|
+
*
|
|
58
|
+
* For a target that carries BOTH `manifestPath` AND `registryKey` (Windows),
|
|
59
|
+
* the JSON file is written first and the registry value is then pointed at
|
|
60
|
+
* the just-written path. If the file write throws, the registry write is
|
|
61
|
+
* skipped (don't leave a dangling registry entry pointing nowhere).
|
|
62
|
+
*/
|
|
63
|
+
export declare function installManifests(targets: InstallTarget[], manifest: NativeHostManifest, options?: InstallOptions): InstallResult[];
|
|
64
|
+
//# sourceMappingURL=installer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"installer.d.ts","sourceRoot":"","sources":["../../src/native-host/installer.ts"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAEvE,mDAAmD;AACnD,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,8DAA8D;IAC9D,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,4CAA4C;IAC5C,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,mEAAmE;IACnE,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,0EAA0E;IAC1E,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;CACzB;AAED;;;GAGG;AACH,MAAM,MAAM,SAAS,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,MAAM,EAAE,KAAK,IAAI,CAAC;AAExE,uEAAuE;AACvE,MAAM,WAAW,WAAW;IAC1B,6EAA6E;IAC7E,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxD;;;;;OAKG;IACH,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3D;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAC3B,IAAI,GAAE;IACJ,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC,QAAQ,CAAC;CACvB,GACL,WAAW,CAmCb;AAED;;;;;GAKG;AACH,eAAO,MAAM,QAAQ,EAAE,WAA6B,CAAC;AAErD,MAAM,WAAW,cAAc;IAC7B,+EAA+E;IAC/E,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;IAC1B,+DAA+D;IAC/D,QAAQ,CAAC,IAAI,CAAC,EAAE,WAAW,CAAC;CAC7B;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,aAAa,EAAE,EACxB,QAAQ,EAAE,kBAAkB,EAC5B,OAAO,GAAE,cAAmB,GAC3B,aAAa,EAAE,CAwCjB"}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
// Native-host manifest installer (P2 PRD §A7). The actual filesystem / registry
|
|
2
|
+
// writes are factored behind injectable writer functions so the postinstall
|
|
3
|
+
// flow can be unit-tested with fakes — and so a dry run can report exactly what
|
|
4
|
+
// *would* be written without touching the real OS.
|
|
5
|
+
//
|
|
6
|
+
// Windows install path (3d-4):
|
|
7
|
+
// Chrome/Edge on Windows read the native-host manifest path from a registry
|
|
8
|
+
// key under HKCU. The default value of that key is the absolute path to the
|
|
9
|
+
// manifest JSON on disk (conventionally
|
|
10
|
+
// `%LOCALAPPDATA%\<vendor>\<browser>\NativeMessagingHosts\<host>.json`).
|
|
11
|
+
// So the install does TWO things in order:
|
|
12
|
+
// 1. write the manifest JSON to disk (target.manifestPath)
|
|
13
|
+
// 2. set the registry default value to that path via reg.exe
|
|
14
|
+
// `realSink.writeRegistryKey` shells out to `reg.exe add` (built into every
|
|
15
|
+
// Windows install since XP) and is gated on `process.platform === 'win32'`
|
|
16
|
+
// so a misconfigured target never accidentally fires on darwin/linux.
|
|
17
|
+
import { execFileSync } from 'node:child_process';
|
|
18
|
+
import { mkdirSync, writeFileSync } from 'node:fs';
|
|
19
|
+
import { dirname } from 'node:path';
|
|
20
|
+
/**
|
|
21
|
+
* Build a real-OS sink. Exported so tests can inject a fake `execFn` while
|
|
22
|
+
* still exercising the platform guard. Production callers use {@link realSink}.
|
|
23
|
+
*/
|
|
24
|
+
export function buildRealSink(deps = {}) {
|
|
25
|
+
const execFn = deps.execFn ??
|
|
26
|
+
((file, args) => {
|
|
27
|
+
execFileSync(file, [...args], { stdio: 'ignore' });
|
|
28
|
+
});
|
|
29
|
+
const platform = deps.platform ?? process.platform;
|
|
30
|
+
return {
|
|
31
|
+
writeManifestFile(path, contents) {
|
|
32
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
33
|
+
writeFileSync(path, contents, 'utf8');
|
|
34
|
+
},
|
|
35
|
+
writeRegistryKey(key, manifestPath) {
|
|
36
|
+
// Defense in depth: a misconfigured target (win32 entry on darwin/linux)
|
|
37
|
+
// must never silently shell out to a non-existent binary. Throw with a
|
|
38
|
+
// clear, structured message so installManifests records it as a
|
|
39
|
+
// per-target error and the run continues.
|
|
40
|
+
if (platform !== 'win32') {
|
|
41
|
+
throw new Error(`realSink.writeRegistryKey called on non-Windows platform (${platform}); refused`);
|
|
42
|
+
}
|
|
43
|
+
if (typeof manifestPath !== 'string' || manifestPath.length === 0) {
|
|
44
|
+
throw new Error(`realSink.writeRegistryKey: manifestPath must be a non-empty absolute path (got '${manifestPath}')`);
|
|
45
|
+
}
|
|
46
|
+
// `reg.exe add <KEY> /ve /d <DATA> /f`
|
|
47
|
+
// /ve → set the (Default) value (the one Chrome/Edge read)
|
|
48
|
+
// /d → data to write
|
|
49
|
+
// /f → force, no Y/N prompt
|
|
50
|
+
execFn('reg.exe', ['add', key, '/ve', '/d', manifestPath, '/f']);
|
|
51
|
+
},
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Default real-OS sink (writes to disk + the Windows registry). Constructed
|
|
56
|
+
* once at module-load via {@link buildRealSink}; tests requiring custom
|
|
57
|
+
* platform / execFn should call `buildRealSink` directly instead of mutating
|
|
58
|
+
* this object.
|
|
59
|
+
*/
|
|
60
|
+
export const realSink = buildRealSink();
|
|
61
|
+
/**
|
|
62
|
+
* Install `manifest` to every `target`. Failures are captured per-target (so
|
|
63
|
+
* one unwritable browser dir doesn't abort the rest) and returned in the
|
|
64
|
+
* result list. In `dryRun` mode nothing is written and every result has
|
|
65
|
+
* `written: false`.
|
|
66
|
+
*
|
|
67
|
+
* For a target that carries BOTH `manifestPath` AND `registryKey` (Windows),
|
|
68
|
+
* the JSON file is written first and the registry value is then pointed at
|
|
69
|
+
* the just-written path. If the file write throws, the registry write is
|
|
70
|
+
* skipped (don't leave a dangling registry entry pointing nowhere).
|
|
71
|
+
*/
|
|
72
|
+
export function installManifests(targets, manifest, options = {}) {
|
|
73
|
+
const dryRun = options.dryRun ?? false;
|
|
74
|
+
const sink = options.sink ?? realSink;
|
|
75
|
+
const contents = `${JSON.stringify(manifest, null, 2)}\n`;
|
|
76
|
+
const results = [];
|
|
77
|
+
for (const target of targets) {
|
|
78
|
+
const base = {
|
|
79
|
+
browser: target.browser,
|
|
80
|
+
...(target.manifestPath !== undefined ? { manifestPath: target.manifestPath } : {}),
|
|
81
|
+
...(target.registryKey !== undefined ? { registryKey: target.registryKey } : {}),
|
|
82
|
+
};
|
|
83
|
+
if (dryRun) {
|
|
84
|
+
results.push({ ...base, written: false });
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
try {
|
|
88
|
+
if (target.manifestPath !== undefined) {
|
|
89
|
+
sink.writeManifestFile(target.manifestPath, contents);
|
|
90
|
+
}
|
|
91
|
+
if (target.registryKey !== undefined) {
|
|
92
|
+
// Windows targets carry both: the registry value must point at the
|
|
93
|
+
// file we just wrote (or, if the file write was skipped above, the
|
|
94
|
+
// declared target path so a separate prior install still resolves).
|
|
95
|
+
const pathForRegistry = target.manifestPath ?? '';
|
|
96
|
+
sink.writeRegistryKey(target.registryKey, pathForRegistry);
|
|
97
|
+
}
|
|
98
|
+
results.push({ ...base, written: true });
|
|
99
|
+
}
|
|
100
|
+
catch (err) {
|
|
101
|
+
results.push({
|
|
102
|
+
...base,
|
|
103
|
+
written: false,
|
|
104
|
+
error: err instanceof Error ? err.message : String(err),
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
return results;
|
|
109
|
+
}
|
|
110
|
+
//# sourceMappingURL=installer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"installer.js","sourceRoot":"","sources":["../../src/native-host/installer.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,4EAA4E;AAC5E,gFAAgF;AAChF,mDAAmD;AACnD,EAAE;AACF,+BAA+B;AAC/B,8EAA8E;AAC9E,8EAA8E;AAC9E,0CAA0C;AAC1C,2EAA2E;AAC3E,6CAA6C;AAC7C,+DAA+D;AAC/D,iEAAiE;AACjE,8EAA8E;AAC9E,6EAA6E;AAC7E,wEAAwE;AAExE,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAmCpC;;;GAGG;AACH,MAAM,UAAU,aAAa,CAC3B,OAGI,EAAE;IAEN,MAAM,MAAM,GACV,IAAI,CAAC,MAAM;QACX,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE;YACd,YAAY,CAAC,IAAI,EAAE,CAAC,GAAG,IAAI,CAAC,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;QACrD,CAAC,CAAC,CAAC;IACL,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,OAAO,CAAC,QAAQ,CAAC;IAEnD,OAAO;QACL,iBAAiB,CAAC,IAAI,EAAE,QAAQ;YAC9B,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YAC9C,aAAa,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;QACxC,CAAC;QACD,gBAAgB,CAAC,GAAG,EAAE,YAAY;YAChC,yEAAyE;YACzE,uEAAuE;YACvE,gEAAgE;YAChE,0CAA0C;YAC1C,IAAI,QAAQ,KAAK,OAAO,EAAE,CAAC;gBACzB,MAAM,IAAI,KAAK,CACb,6DAA6D,QAAQ,YAAY,CAClF,CAAC;YACJ,CAAC;YACD,IAAI,OAAO,YAAY,KAAK,QAAQ,IAAI,YAAY,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAClE,MAAM,IAAI,KAAK,CACb,mFAAmF,YAAY,IAAI,CACpG,CAAC;YACJ,CAAC;YACD,uCAAuC;YACvC,8DAA8D;YAC9D,yBAAyB;YACzB,gCAAgC;YAChC,MAAM,CAAC,SAAS,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,CAAC,CAAC,CAAC;QACnE,CAAC;KACF,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAgB,aAAa,EAAE,CAAC;AASrD;;;;;;;;;;GAUG;AACH,MAAM,UAAU,gBAAgB,CAC9B,OAAwB,EACxB,QAA4B,EAC5B,UAA0B,EAAE;IAE5B,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,KAAK,CAAC;IACvC,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,QAAQ,CAAC;IACtC,MAAM,QAAQ,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC;IAC1D,MAAM,OAAO,GAAoB,EAAE,CAAC;IAEpC,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,MAAM,IAAI,GAAG;YACX,OAAO,EAAE,MAAM,CAAC,OAAO;YACvB,GAAG,CAAC,MAAM,CAAC,YAAY,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,MAAM,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACnF,GAAG,CAAC,MAAM,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACjF,CAAC;QAEF,IAAI,MAAM,EAAE,CAAC;YACX,OAAO,CAAC,IAAI,CAAC,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;YAC1C,SAAS;QACX,CAAC;QAED,IAAI,CAAC;YACH,IAAI,MAAM,CAAC,YAAY,KAAK,SAAS,EAAE,CAAC;gBACtC,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC;YACxD,CAAC;YACD,IAAI,MAAM,CAAC,WAAW,KAAK,SAAS,EAAE,CAAC;gBACrC,mEAAmE;gBACnE,mEAAmE;gBACnE,oEAAoE;gBACpE,MAAM,eAAe,GAAG,MAAM,CAAC,YAAY,IAAI,EAAE,CAAC;gBAClD,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,WAAW,EAAE,eAAe,CAAC,CAAC;YAC7D,CAAC;YACD,OAAO,CAAC,IAAI,CAAC,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;QAC3C,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,IAAI,CAAC;gBACX,GAAG,IAAI;gBACP,OAAO,EAAE,KAAK;gBACd,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;aACxD,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/** Reverse-DNS native-host id (ADR-0009 / NAMING.md). */
|
|
2
|
+
export declare const NATIVE_HOST_NAME = "com.cubenest.peek";
|
|
3
|
+
/** The manifest filename written into each NativeMessagingHosts directory. */
|
|
4
|
+
export declare const MANIFEST_FILENAME = "com.cubenest.peek.json";
|
|
5
|
+
/** Shape of the published `src/native-host/extension-ids.json`. */
|
|
6
|
+
export interface ExtensionIds {
|
|
7
|
+
readonly chromeWebStore: string;
|
|
8
|
+
readonly edgeAddons: string;
|
|
9
|
+
readonly dev: string;
|
|
10
|
+
}
|
|
11
|
+
/** A Chrome/Edge native-messaging host manifest. */
|
|
12
|
+
export interface NativeHostManifest {
|
|
13
|
+
readonly name: string;
|
|
14
|
+
readonly description: string;
|
|
15
|
+
readonly path: string;
|
|
16
|
+
readonly type: 'stdio';
|
|
17
|
+
readonly allowed_origins: string[];
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Turn the three configured extension IDs into the `allowed_origins` array.
|
|
21
|
+
* Chrome forbids wildcards, so each id becomes an explicit
|
|
22
|
+
* `chrome-extension://<id>/` origin. Unconfigured placeholder ids are dropped
|
|
23
|
+
* (so a pre-publish install doesn't ship dead origins), de-duplicating the
|
|
24
|
+
* result.
|
|
25
|
+
*/
|
|
26
|
+
export declare function allowedOrigins(ids: ExtensionIds): string[];
|
|
27
|
+
/**
|
|
28
|
+
* Build the native-host manifest. `hostBinaryPath` is the absolute path the
|
|
29
|
+
* browser will spawn over stdio (the installed `peek-mcp` bin, invoked with
|
|
30
|
+
* `--native-host`). Both Chrome and Edge ids live in the SAME manifest's
|
|
31
|
+
* `allowed_origins` per the Edge "first registry location wins" gotcha
|
|
32
|
+
* (P2 PRD §A7).
|
|
33
|
+
*/
|
|
34
|
+
export declare function buildManifest(hostBinaryPath: string, ids: ExtensionIds): NativeHostManifest;
|
|
35
|
+
/** Supported desktop platforms (Node `process.platform` values). */
|
|
36
|
+
export type SupportedPlatform = 'darwin' | 'linux' | 'win32';
|
|
37
|
+
/** A single place the manifest must be registered. */
|
|
38
|
+
export interface InstallTarget {
|
|
39
|
+
/** Human label, e.g. "macOS Chrome" — used in postinstall logging. */
|
|
40
|
+
readonly browser: string;
|
|
41
|
+
/**
|
|
42
|
+
* For darwin/linux: an absolute filesystem path to write the manifest JSON.
|
|
43
|
+
* For win32: omitted (registry targets carry `registryKey` instead).
|
|
44
|
+
*/
|
|
45
|
+
readonly manifestPath?: string;
|
|
46
|
+
/**
|
|
47
|
+
* For win32: the HKCU registry key whose default value points at the
|
|
48
|
+
* manifest JSON on disk (Chrome/Edge read the path from the registry).
|
|
49
|
+
*/
|
|
50
|
+
readonly registryKey?: string;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Resolve the per-OS set of native-messaging install targets (P2 PRD §A7).
|
|
54
|
+
*
|
|
55
|
+
* - macOS: Chrome, Chromium, Edge `NativeMessagingHosts/` directories under
|
|
56
|
+
* `~/Library/Application Support/`.
|
|
57
|
+
* - Linux: Chrome + Chromium `NativeMessagingHosts/` under `~/.config/`.
|
|
58
|
+
* - Windows: HKCU registry keys for Chrome + Edge (the default value of each
|
|
59
|
+
* key is the on-disk manifest path).
|
|
60
|
+
*
|
|
61
|
+
* `homeDir` is injected for testability.
|
|
62
|
+
*/
|
|
63
|
+
export declare function resolveInstallTargets(platform: SupportedPlatform, homeDir: string): InstallTarget[];
|
|
64
|
+
//# sourceMappingURL=manifest.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../../src/native-host/manifest.ts"],"names":[],"mappings":"AAQA,yDAAyD;AACzD,eAAO,MAAM,gBAAgB,sBAAsB,CAAC;AAEpD,8EAA8E;AAC9E,eAAO,MAAM,iBAAiB,2BAA6B,CAAC;AAE5D,mEAAmE;AACnE,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;CACtB;AAED,oDAAoD;AACpD,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,eAAe,EAAE,MAAM,EAAE,CAAC;CACpC;AAID;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,YAAY,GAAG,MAAM,EAAE,CAY1D;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,cAAc,EAAE,MAAM,EAAE,GAAG,EAAE,YAAY,GAAG,kBAAkB,CAQ3F;AAED,oEAAoE;AACpE,MAAM,MAAM,iBAAiB,GAAG,QAAQ,GAAG,OAAO,GAAG,OAAO,CAAC;AAE7D,sDAAsD;AACtD,MAAM,WAAW,aAAa;IAC5B,sEAAsE;IACtE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB;;;OAGG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B;;;OAGG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,iBAAiB,EAC3B,OAAO,EAAE,MAAM,GACd,aAAa,EAAE,CA8EjB"}
|