@peekdev/mcp 0.1.0-alpha.19 → 0.1.0-alpha.20
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/db/open.d.ts +19 -1
- package/dist/db/open.d.ts.map +1 -1
- package/dist/db/open.js +25 -1
- package/dist/db/open.js.map +1 -1
- package/dist/entrypoint.d.ts +8 -0
- package/dist/entrypoint.d.ts.map +1 -0
- package/dist/entrypoint.js +33 -0
- package/dist/entrypoint.js.map +1 -0
- package/dist/native-host/installer.d.ts +21 -0
- package/dist/native-host/installer.d.ts.map +1 -1
- package/dist/native-host/installer.js +64 -2
- package/dist/native-host/installer.js.map +1 -1
- package/dist/native-host/manifest.d.ts +7 -2
- package/dist/native-host/manifest.d.ts.map +1 -1
- package/dist/native-host/manifest.js +29 -15
- package/dist/native-host/manifest.js.map +1 -1
- package/dist/postinstall.d.ts.map +1 -1
- package/dist/postinstall.js +15 -15
- package/dist/postinstall.js.map +1 -1
- package/package.json +1 -1
package/dist/db/open.d.ts
CHANGED
|
@@ -1,5 +1,23 @@
|
|
|
1
|
-
import Database from 'better-sqlite3';
|
|
1
|
+
import type Database from 'better-sqlite3';
|
|
2
2
|
import { schemaVersion } from './migrate.js';
|
|
3
|
+
/** Constructor signature of better-sqlite3's default export (value-erased import above). */
|
|
4
|
+
type BetterSqlite3Ctor = new (filename?: string, options?: Database.Options) => Database.Database;
|
|
5
|
+
/**
|
|
6
|
+
* Lazily load better-sqlite3's native constructor, wrapping a native-module
|
|
7
|
+
* load failure in an actionable error.
|
|
8
|
+
*
|
|
9
|
+
* WHY (P-Windows): the import was previously `import Database from
|
|
10
|
+
* 'better-sqlite3'` at top-level module scope, so the `.node` binding loaded at
|
|
11
|
+
* module-EVALUATION time. A missing / ABI-mismatched (Node < 22) / AV-locked
|
|
12
|
+
* prebuilt binary therefore threw before `main()` ran — and on stock Windows
|
|
13
|
+
* there is no compile-from-source fallback — so the native host process simply
|
|
14
|
+
* died and the browser saw a silently-closed stdio pipe with no message. Making
|
|
15
|
+
* this a type-only import + a lazy `require` defers the load to the first
|
|
16
|
+
* {@link openDb} call (inside `main()`, where it is caught) and lets us emit a
|
|
17
|
+
* message the user can act on. Node's own require cache makes repeat calls cheap,
|
|
18
|
+
* so no module-level memo is needed. `requireFn` is injectable for tests.
|
|
19
|
+
*/
|
|
20
|
+
export declare function loadBetterSqlite3(requireFn?: (id: string) => unknown): BetterSqlite3Ctor;
|
|
3
21
|
/**
|
|
4
22
|
* The native host's data directory (ADR-0007). Defaults to `~/.peek`; the
|
|
5
23
|
* `PEEK_HOME` environment variable overrides it (used by tests and by users who
|
package/dist/db/open.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"open.d.ts","sourceRoot":"","sources":["../../src/db/open.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"open.d.ts","sourceRoot":"","sources":["../../src/db/open.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAiB,aAAa,EAAE,MAAM,cAAc,CAAC;AAE5D,4FAA4F;AAC5F,KAAK,iBAAiB,GAAG,KAAK,QAAQ,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,QAAQ,CAAC,OAAO,KAAK,QAAQ,CAAC,QAAQ,CAAC;AAElG;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,iBAAiB,CAC/B,SAAS,GAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAwC,GAClE,iBAAiB,CASnB;AAED;;;;GAIG;AACH,wBAAgB,WAAW,IAAI,MAAM,CAIpC;AAED,iDAAiD;AACjD,wBAAgB,aAAa,IAAI,MAAM,CAEtC;AAED,MAAM,WAAW,aAAa;IAC5B;;;OAGG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,yDAAyD;IACzD,QAAQ,CAAC,cAAc,CAAC,EAAE,OAAO,CAAC;IAClC;;;;;;OAMG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED;;;;;;;GAOG;AACH,wBAAgB,MAAM,CAAC,OAAO,GAAE,aAAkB,GAAG,QAAQ,CAAC,QAAQ,CA2BrE;AAED;;;;GAIG;AACH,MAAM,MAAM,gBAAgB,GACxB;IAAE,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,EAAE,EAAE,QAAQ,CAAC,QAAQ,CAAA;CAAE,GACzD;IAAE,QAAQ,CAAC,MAAM,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,EAAE,EAAE,SAAS,CAAA;CAAE,CAAC;AAEvD;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,IAAI,GAAE,MAAwB,GAAG,gBAAgB,CAQ/E;AAED,OAAO,EAAE,aAAa,EAAE,CAAC"}
|
package/dist/db/open.js
CHANGED
|
@@ -2,10 +2,33 @@
|
|
|
2
2
|
// same ~/.peek/sessions.db through here so the pragmas (WAL, foreign keys) and
|
|
3
3
|
// the migration state stay consistent across the three thin clients (ADR-0007).
|
|
4
4
|
import { existsSync, mkdirSync } from 'node:fs';
|
|
5
|
+
import { createRequire } from 'node:module';
|
|
5
6
|
import { homedir } from 'node:os';
|
|
6
7
|
import { dirname, join } from 'node:path';
|
|
7
|
-
import Database from 'better-sqlite3';
|
|
8
8
|
import { runMigrations, schemaVersion } from './migrate.js';
|
|
9
|
+
/**
|
|
10
|
+
* Lazily load better-sqlite3's native constructor, wrapping a native-module
|
|
11
|
+
* load failure in an actionable error.
|
|
12
|
+
*
|
|
13
|
+
* WHY (P-Windows): the import was previously `import Database from
|
|
14
|
+
* 'better-sqlite3'` at top-level module scope, so the `.node` binding loaded at
|
|
15
|
+
* module-EVALUATION time. A missing / ABI-mismatched (Node < 22) / AV-locked
|
|
16
|
+
* prebuilt binary therefore threw before `main()` ran — and on stock Windows
|
|
17
|
+
* there is no compile-from-source fallback — so the native host process simply
|
|
18
|
+
* died and the browser saw a silently-closed stdio pipe with no message. Making
|
|
19
|
+
* this a type-only import + a lazy `require` defers the load to the first
|
|
20
|
+
* {@link openDb} call (inside `main()`, where it is caught) and lets us emit a
|
|
21
|
+
* message the user can act on. Node's own require cache makes repeat calls cheap,
|
|
22
|
+
* so no module-level memo is needed. `requireFn` is injectable for tests.
|
|
23
|
+
*/
|
|
24
|
+
export function loadBetterSqlite3(requireFn = createRequire(import.meta.url)) {
|
|
25
|
+
try {
|
|
26
|
+
return requireFn('better-sqlite3');
|
|
27
|
+
}
|
|
28
|
+
catch (err) {
|
|
29
|
+
throw new Error(`peek: the better-sqlite3 native module failed to load, so the session database cannot be opened. peek requires Node.js 22+ and a prebuilt binary for your platform (${process.platform}/${process.arch}); this usually means the prebuild is missing/incompatible (e.g. Node < 22) or an antivirus has locked the .node file. Original error: ${err instanceof Error ? err.message : String(err)}`, { cause: err });
|
|
30
|
+
}
|
|
31
|
+
}
|
|
9
32
|
/**
|
|
10
33
|
* The native host's data directory (ADR-0007). Defaults to `~/.peek`; the
|
|
11
34
|
* `PEEK_HOME` environment variable overrides it (used by tests and by users who
|
|
@@ -37,6 +60,7 @@ export function openDb(options = {}) {
|
|
|
37
60
|
if (path !== ':memory:' && !readonly) {
|
|
38
61
|
mkdirSync(dirname(path), { recursive: true });
|
|
39
62
|
}
|
|
63
|
+
const Database = loadBetterSqlite3();
|
|
40
64
|
const db = new Database(path, readonly ? { readonly: true } : {});
|
|
41
65
|
if (readonly) {
|
|
42
66
|
// Read-only handles can't enable WAL (a DDL/pragma write); the writer (the
|
package/dist/db/open.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"open.js","sourceRoot":"","sources":["../../src/db/open.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,+EAA+E;AAC/E,gFAAgF;AAEhF,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAChD,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"open.js","sourceRoot":"","sources":["../../src/db/open.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* True when `metaUrl` (`import.meta.url`) refers to the same file as `argv1`
|
|
3
|
+
* (`process.argv[1]`). Compares via {@link pathToFileURL} (Windows-safe, encoded)
|
|
4
|
+
* and falls back to the realpath-resolved argv (bin shims / symlinks). A
|
|
5
|
+
* realpath failure resolves to `false`. `realpath` is injectable for tests.
|
|
6
|
+
*/
|
|
7
|
+
export declare function isDirectInvocation(metaUrl: string, argv1: string | undefined, realpath?: (p: string) => string): boolean;
|
|
8
|
+
//# sourceMappingURL=entrypoint.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"entrypoint.d.ts","sourceRoot":"","sources":["../src/entrypoint.ts"],"names":[],"mappings":"AAgBA;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,MAAM,GAAG,SAAS,EACzB,QAAQ,GAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAqB,GAC7C,OAAO,CAQT"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
// Decide whether this module is the process entry point (`node thisfile`, or an
|
|
2
|
+
// npm-generated bin shim) versus merely imported. Bin / postinstall entries
|
|
3
|
+
// guard their side effect on this so an ESM `import` (tests, consumers) is inert.
|
|
4
|
+
//
|
|
5
|
+
// WHY pathToFileURL (P-Windows): comparing `import.meta.url` against the
|
|
6
|
+
// string-concatenated `` `file://${process.argv[1]}` `` produced an INVALID url
|
|
7
|
+
// on Windows — `process.argv[1]` is a backslash path (`C:\…\x.js`), so the
|
|
8
|
+
// concat yields `file://C:\…\x.js`, which never equals `import.meta.url`'s
|
|
9
|
+
// RFC-8089 form (`file:///C:/…/x.js`). It also skipped percent-encoding for
|
|
10
|
+
// space/unicode paths on POSIX. pathToFileURL produces the correct encoded
|
|
11
|
+
// `file:` url on every platform. (Local copy of @peekdev/cli's helper — kept
|
|
12
|
+
// per-package so neither bin's entry guard depends on the other's public API.)
|
|
13
|
+
import { realpathSync } from 'node:fs';
|
|
14
|
+
import { pathToFileURL } from 'node:url';
|
|
15
|
+
/**
|
|
16
|
+
* True when `metaUrl` (`import.meta.url`) refers to the same file as `argv1`
|
|
17
|
+
* (`process.argv[1]`). Compares via {@link pathToFileURL} (Windows-safe, encoded)
|
|
18
|
+
* and falls back to the realpath-resolved argv (bin shims / symlinks). A
|
|
19
|
+
* realpath failure resolves to `false`. `realpath` is injectable for tests.
|
|
20
|
+
*/
|
|
21
|
+
export function isDirectInvocation(metaUrl, argv1, realpath = realpathSync) {
|
|
22
|
+
if (argv1 === undefined)
|
|
23
|
+
return false;
|
|
24
|
+
if (metaUrl === pathToFileURL(argv1).href)
|
|
25
|
+
return true;
|
|
26
|
+
try {
|
|
27
|
+
return metaUrl === pathToFileURL(realpath(argv1)).href;
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=entrypoint.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"entrypoint.js","sourceRoot":"","sources":["../src/entrypoint.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,4EAA4E;AAC5E,kFAAkF;AAClF,EAAE;AACF,yEAAyE;AACzE,gFAAgF;AAChF,2EAA2E;AAC3E,2EAA2E;AAC3E,4EAA4E;AAC5E,2EAA2E;AAC3E,6EAA6E;AAC7E,+EAA+E;AAE/E,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC;;;;;GAKG;AACH,MAAM,UAAU,kBAAkB,CAChC,OAAe,EACf,KAAyB,EACzB,WAAkC,YAAY;IAE9C,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC;IACtC,IAAI,OAAO,KAAK,aAAa,CAAC,KAAK,CAAC,CAAC,IAAI;QAAE,OAAO,IAAI,CAAC;IACvD,IAAI,CAAC;QACH,OAAO,OAAO,KAAK,aAAa,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;IACzD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC"}
|
|
@@ -16,6 +16,21 @@ export interface InstallResult {
|
|
|
16
16
|
* so tests can capture argv without spawning a real Windows process.
|
|
17
17
|
*/
|
|
18
18
|
export type RegExecFn = (file: string, args: readonly string[]) => void;
|
|
19
|
+
/**
|
|
20
|
+
* Turn the error `execFileSync` throws when `reg.exe` exits non-zero into a
|
|
21
|
+
* message that actually says *why* it failed.
|
|
22
|
+
*
|
|
23
|
+
* Windows-hardening fix: previously the default `execFn` ran `reg.exe` with
|
|
24
|
+
* `stdio: 'ignore'`, so on failure (EACCES on a redirected/locked HKCU hive,
|
|
25
|
+
* the host running under a restricted token, etc.) the child's stderr was
|
|
26
|
+
* discarded and `installManifests` recorded a useless bare "Command failed".
|
|
27
|
+
* Capturing stderr and folding it (plus the exit status) into the thrown
|
|
28
|
+
* Error's message means the per-target `result.error` is now actionable.
|
|
29
|
+
*
|
|
30
|
+
* Accepts the raw caught value (typed `unknown`) so callers don't have to
|
|
31
|
+
* pre-narrow; reads `.stderr` / `.status` off `execFileSync`'s error shape.
|
|
32
|
+
*/
|
|
33
|
+
export declare function formatRegExecError(err: unknown): string;
|
|
19
34
|
/** Injectable side-effect surface (defaults to real fs + registry). */
|
|
20
35
|
export interface InstallSink {
|
|
21
36
|
/** Write a manifest JSON file at an absolute path (creating parent dirs). */
|
|
@@ -35,6 +50,12 @@ export interface InstallSink {
|
|
|
35
50
|
export declare function buildRealSink(deps?: {
|
|
36
51
|
execFn?: RegExecFn;
|
|
37
52
|
platform?: NodeJS.Platform;
|
|
53
|
+
/**
|
|
54
|
+
* Map a thrown `execFn` error → the message to rethrow. Injectable so the
|
|
55
|
+
* stderr-surfacing wrapper is unit-testable; defaults to
|
|
56
|
+
* {@link formatRegExecError}.
|
|
57
|
+
*/
|
|
58
|
+
wrapExecError?: (err: unknown) => string;
|
|
38
59
|
}): InstallSink;
|
|
39
60
|
/**
|
|
40
61
|
* Default real-OS sink (writes to disk + the Windows registry). Constructed
|
|
@@ -1 +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;
|
|
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;AAmBxE;;;;;;;;;;;;;GAaG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,CAWvD;AAED,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;IAC3B;;;;OAIG;IACH,aAAa,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,MAAM,CAAC;CACrC,GACL,WAAW,CAkDb;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"}
|
|
@@ -17,14 +17,67 @@
|
|
|
17
17
|
import { execFileSync } from 'node:child_process';
|
|
18
18
|
import { mkdirSync, writeFileSync } from 'node:fs';
|
|
19
19
|
import { dirname } from 'node:path';
|
|
20
|
+
/**
|
|
21
|
+
* Decode the `stderr` `execFileSync` attaches to a thrown error. `execFileSync`
|
|
22
|
+
* populates `err.stderr` as a Buffer (or string, depending on `encoding`) when
|
|
23
|
+
* the child writes to stderr before a non-zero exit.
|
|
24
|
+
*/
|
|
25
|
+
function decodeStderr(value) {
|
|
26
|
+
if (value == null)
|
|
27
|
+
return '';
|
|
28
|
+
if (typeof value === 'string')
|
|
29
|
+
return value;
|
|
30
|
+
if (Buffer.isBuffer(value))
|
|
31
|
+
return value.toString('utf8');
|
|
32
|
+
// Some shapes hand back a Uint8Array / array-like; coerce defensively.
|
|
33
|
+
try {
|
|
34
|
+
return Buffer.from(value).toString('utf8');
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
return String(value);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Turn the error `execFileSync` throws when `reg.exe` exits non-zero into a
|
|
42
|
+
* message that actually says *why* it failed.
|
|
43
|
+
*
|
|
44
|
+
* Windows-hardening fix: previously the default `execFn` ran `reg.exe` with
|
|
45
|
+
* `stdio: 'ignore'`, so on failure (EACCES on a redirected/locked HKCU hive,
|
|
46
|
+
* the host running under a restricted token, etc.) the child's stderr was
|
|
47
|
+
* discarded and `installManifests` recorded a useless bare "Command failed".
|
|
48
|
+
* Capturing stderr and folding it (plus the exit status) into the thrown
|
|
49
|
+
* Error's message means the per-target `result.error` is now actionable.
|
|
50
|
+
*
|
|
51
|
+
* Accepts the raw caught value (typed `unknown`) so callers don't have to
|
|
52
|
+
* pre-narrow; reads `.stderr` / `.status` off `execFileSync`'s error shape.
|
|
53
|
+
*/
|
|
54
|
+
export function formatRegExecError(err) {
|
|
55
|
+
const e = (err ?? {});
|
|
56
|
+
const stderr = decodeStderr(e.stderr).trim();
|
|
57
|
+
const status = typeof e.status === 'number' ? e.status : undefined;
|
|
58
|
+
const baseMessage = typeof e.message === 'string' ? e.message : String(err);
|
|
59
|
+
// Prefer the child's own stderr (the OS-level reason); fall back to the
|
|
60
|
+
// thrown error's message (e.g. `spawn reg.exe ENOENT` when reg.exe is
|
|
61
|
+
// missing from PATH) so we never produce an empty detail.
|
|
62
|
+
const detail = stderr.length > 0 ? stderr : baseMessage;
|
|
63
|
+
const exitPart = status !== undefined ? ` (exit ${status})` : '';
|
|
64
|
+
return `reg.exe failed${exitPart}: ${detail}`;
|
|
65
|
+
}
|
|
20
66
|
/**
|
|
21
67
|
* Build a real-OS sink. Exported so tests can inject a fake `execFn` while
|
|
22
68
|
* still exercising the platform guard. Production callers use {@link realSink}.
|
|
23
69
|
*/
|
|
24
70
|
export function buildRealSink(deps = {}) {
|
|
71
|
+
// Default execFn: run reg.exe with stderr PIPED (not 'ignore') so a non-zero
|
|
72
|
+
// exit throws an error carrying `.stderr` (and `.status`). That detail is
|
|
73
|
+
// folded into the rethrown message at the writeRegistryKey call site (below),
|
|
74
|
+
// so installManifests records a useful per-target error instead of a bare
|
|
75
|
+
// "Command failed". `stdout` stays ignored (reg.exe's success chatter is
|
|
76
|
+
// noise); only stderr is captured.
|
|
77
|
+
const wrapExecError = deps.wrapExecError ?? formatRegExecError;
|
|
25
78
|
const execFn = deps.execFn ??
|
|
26
79
|
((file, args) => {
|
|
27
|
-
execFileSync(file, [...args], { stdio: 'ignore' });
|
|
80
|
+
execFileSync(file, [...args], { stdio: ['ignore', 'ignore', 'pipe'] });
|
|
28
81
|
});
|
|
29
82
|
const platform = deps.platform ?? process.platform;
|
|
30
83
|
return {
|
|
@@ -47,7 +100,16 @@ export function buildRealSink(deps = {}) {
|
|
|
47
100
|
// /ve → set the (Default) value (the one Chrome/Edge read)
|
|
48
101
|
// /d → data to write
|
|
49
102
|
// /f → force, no Y/N prompt
|
|
50
|
-
execFn
|
|
103
|
+
// Wrap any execFn throw so the rethrown message carries reg.exe's stderr
|
|
104
|
+
// + exit status (the default execFn pipes stderr precisely so this detail
|
|
105
|
+
// is available). installManifests catches per-target and records the
|
|
106
|
+
// message, so the user finally sees *why* the registry write failed.
|
|
107
|
+
try {
|
|
108
|
+
execFn('reg.exe', ['add', key, '/ve', '/d', manifestPath, '/f']);
|
|
109
|
+
}
|
|
110
|
+
catch (err) {
|
|
111
|
+
throw new Error(wrapExecError(err));
|
|
112
|
+
}
|
|
51
113
|
},
|
|
52
114
|
};
|
|
53
115
|
}
|
|
@@ -1 +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;
|
|
1
|
+
{"version":3,"file":"installer.js","sourceRoot":"","sources":["../../src/native-host/installer.ts"],"names":[],"mappings":"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"}
|
|
@@ -58,7 +58,12 @@ export interface InstallTarget {
|
|
|
58
58
|
* - Windows: HKCU registry keys for Chrome + Edge (the default value of each
|
|
59
59
|
* key is the on-disk manifest path).
|
|
60
60
|
*
|
|
61
|
-
* `homeDir` is injected for testability.
|
|
61
|
+
* `homeDir` is injected for testability. `localAppData` (Windows only) is the
|
|
62
|
+
* real `%LOCALAPPDATA%` — injected by the caller from `process.env.LOCALAPPDATA`
|
|
63
|
+
* so the function stays pure — and is REQUIRED to be correct on machines where
|
|
64
|
+
* `AppData\Local` is redirected away from `homeDir` (OneDrive Known-Folder-Move,
|
|
65
|
+
* ADMX folder redirection, roaming/UNC profiles). When absent it falls back to
|
|
66
|
+
* the conventional `homeDir\AppData\Local`.
|
|
62
67
|
*/
|
|
63
|
-
export declare function resolveInstallTargets(platform: SupportedPlatform, homeDir: string): InstallTarget[];
|
|
68
|
+
export declare function resolveInstallTargets(platform: SupportedPlatform, homeDir: string, localAppData?: string): InstallTarget[];
|
|
64
69
|
//# sourceMappingURL=manifest.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../../src/native-host/manifest.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../../src/native-host/manifest.ts"],"names":[],"mappings":"AAaA,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;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,iBAAiB,EAC3B,OAAO,EAAE,MAAM,EACf,YAAY,CAAC,EAAE,MAAM,GACpB,aAAa,EAAE,CA6FjB"}
|
|
@@ -3,7 +3,12 @@
|
|
|
3
3
|
// home directory, host-binary path, and extension IDs so the postinstall
|
|
4
4
|
// side-effects (filesystem / registry writes) can be unit-tested without
|
|
5
5
|
// touching the real OS.
|
|
6
|
-
|
|
6
|
+
// Use the TARGET platform's path flavour (posix for darwin/linux, win32 for
|
|
7
|
+
// Windows) rather than the ambient `join`, so resolveInstallTargets stays a
|
|
8
|
+
// pure function of (platform, homeDir) — a darwin target reads as a `/`-path
|
|
9
|
+
// and a win32 target as a `\`-path even when this runs on the other OS (unit
|
|
10
|
+
// tests on Linux CI, the windows-latest job, etc.).
|
|
11
|
+
import { posix, win32 } from 'node:path';
|
|
7
12
|
/** Reverse-DNS native-host id (ADR-0009 / NAMING.md). */
|
|
8
13
|
export const NATIVE_HOST_NAME = 'com.cubenest.peek';
|
|
9
14
|
/** The manifest filename written into each NativeMessagingHosts directory. */
|
|
@@ -56,37 +61,42 @@ export function buildManifest(hostBinaryPath, ids) {
|
|
|
56
61
|
* - Windows: HKCU registry keys for Chrome + Edge (the default value of each
|
|
57
62
|
* key is the on-disk manifest path).
|
|
58
63
|
*
|
|
59
|
-
* `homeDir` is injected for testability.
|
|
64
|
+
* `homeDir` is injected for testability. `localAppData` (Windows only) is the
|
|
65
|
+
* real `%LOCALAPPDATA%` — injected by the caller from `process.env.LOCALAPPDATA`
|
|
66
|
+
* so the function stays pure — and is REQUIRED to be correct on machines where
|
|
67
|
+
* `AppData\Local` is redirected away from `homeDir` (OneDrive Known-Folder-Move,
|
|
68
|
+
* ADMX folder redirection, roaming/UNC profiles). When absent it falls back to
|
|
69
|
+
* the conventional `homeDir\AppData\Local`.
|
|
60
70
|
*/
|
|
61
|
-
export function resolveInstallTargets(platform, homeDir) {
|
|
71
|
+
export function resolveInstallTargets(platform, homeDir, localAppData) {
|
|
62
72
|
switch (platform) {
|
|
63
73
|
case 'darwin': {
|
|
64
|
-
const appSupport = join(homeDir, 'Library', 'Application Support');
|
|
74
|
+
const appSupport = posix.join(homeDir, 'Library', 'Application Support');
|
|
65
75
|
return [
|
|
66
76
|
{
|
|
67
77
|
browser: 'macOS Chrome',
|
|
68
|
-
manifestPath: join(appSupport, 'Google', 'Chrome', 'NativeMessagingHosts', MANIFEST_FILENAME),
|
|
78
|
+
manifestPath: posix.join(appSupport, 'Google', 'Chrome', 'NativeMessagingHosts', MANIFEST_FILENAME),
|
|
69
79
|
},
|
|
70
80
|
{
|
|
71
81
|
browser: 'macOS Chromium',
|
|
72
|
-
manifestPath: join(appSupport, 'Chromium', 'NativeMessagingHosts', MANIFEST_FILENAME),
|
|
82
|
+
manifestPath: posix.join(appSupport, 'Chromium', 'NativeMessagingHosts', MANIFEST_FILENAME),
|
|
73
83
|
},
|
|
74
84
|
{
|
|
75
85
|
browser: 'macOS Edge',
|
|
76
|
-
manifestPath: join(appSupport, 'Microsoft Edge', 'NativeMessagingHosts', MANIFEST_FILENAME),
|
|
86
|
+
manifestPath: posix.join(appSupport, 'Microsoft Edge', 'NativeMessagingHosts', MANIFEST_FILENAME),
|
|
77
87
|
},
|
|
78
88
|
];
|
|
79
89
|
}
|
|
80
90
|
case 'linux': {
|
|
81
|
-
const config = join(homeDir, '.config');
|
|
91
|
+
const config = posix.join(homeDir, '.config');
|
|
82
92
|
return [
|
|
83
93
|
{
|
|
84
94
|
browser: 'Linux Chrome',
|
|
85
|
-
manifestPath: join(config, 'google-chrome', 'NativeMessagingHosts', MANIFEST_FILENAME),
|
|
95
|
+
manifestPath: posix.join(config, 'google-chrome', 'NativeMessagingHosts', MANIFEST_FILENAME),
|
|
86
96
|
},
|
|
87
97
|
{
|
|
88
98
|
browser: 'Linux Chromium',
|
|
89
|
-
manifestPath: join(config, 'chromium', 'NativeMessagingHosts', MANIFEST_FILENAME),
|
|
99
|
+
manifestPath: posix.join(config, 'chromium', 'NativeMessagingHosts', MANIFEST_FILENAME),
|
|
90
100
|
},
|
|
91
101
|
];
|
|
92
102
|
}
|
|
@@ -96,18 +106,22 @@ export function resolveInstallTargets(platform, homeDir) {
|
|
|
96
106
|
// a file path), and
|
|
97
107
|
// - the registry key whose default value points at that path.
|
|
98
108
|
// The conventional location is %LOCALAPPDATA%\<vendor>\<browser>\
|
|
99
|
-
// NativeMessagingHosts\<host>.json.
|
|
100
|
-
// injected
|
|
101
|
-
|
|
109
|
+
// NativeMessagingHosts\<host>.json. Prefer the REAL %LOCALAPPDATA% the
|
|
110
|
+
// caller injected (correct under OneDrive KFM / enterprise redirection,
|
|
111
|
+
// where AppData\Local is NOT under homeDir); fall back to the conventional
|
|
112
|
+
// homeDir\AppData\Local when it's unset.
|
|
113
|
+
const base = localAppData && localAppData.length > 0
|
|
114
|
+
? localAppData
|
|
115
|
+
: win32.join(homeDir, 'AppData', 'Local');
|
|
102
116
|
return [
|
|
103
117
|
{
|
|
104
118
|
browser: 'Windows Chrome',
|
|
105
|
-
manifestPath: join(
|
|
119
|
+
manifestPath: win32.join(base, 'Google', 'Chrome', 'NativeMessagingHosts', MANIFEST_FILENAME),
|
|
106
120
|
registryKey: `HKCU\\Software\\Google\\Chrome\\NativeMessagingHosts\\${NATIVE_HOST_NAME}`,
|
|
107
121
|
},
|
|
108
122
|
{
|
|
109
123
|
browser: 'Windows Edge',
|
|
110
|
-
manifestPath: join(
|
|
124
|
+
manifestPath: win32.join(base, 'Microsoft', 'Edge', 'NativeMessagingHosts', MANIFEST_FILENAME),
|
|
111
125
|
registryKey: `HKCU\\Software\\Microsoft\\Edge\\NativeMessagingHosts\\${NATIVE_HOST_NAME}`,
|
|
112
126
|
},
|
|
113
127
|
];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manifest.js","sourceRoot":"","sources":["../../src/native-host/manifest.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,4EAA4E;AAC5E,yEAAyE;AACzE,yEAAyE;AACzE,wBAAwB;AAExB,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"manifest.js","sourceRoot":"","sources":["../../src/native-host/manifest.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"postinstall.d.ts","sourceRoot":"","sources":["../src/postinstall.ts"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"postinstall.d.ts","sourceRoot":"","sources":["../src/postinstall.ts"],"names":[],"mappings":";AA4CA,wBAAgB,cAAc,IAAI,IAAI,CA4CrC"}
|
package/dist/postinstall.js
CHANGED
|
@@ -11,7 +11,8 @@
|
|
|
11
11
|
//
|
|
12
12
|
// Either way the script logs what it wrote / would write and where, so the
|
|
13
13
|
// install side-effects are always visible to the user (Task 3.4 requirement).
|
|
14
|
-
import {
|
|
14
|
+
import { homedir } from 'node:os';
|
|
15
|
+
import { isDirectInvocation } from './entrypoint.js';
|
|
15
16
|
import { hostBinaryPath, loadExtensionIds } from './native-host/config.js';
|
|
16
17
|
import { installManifests } from './native-host/installer.js';
|
|
17
18
|
import { buildManifest, resolveInstallTargets, } from './native-host/manifest.js';
|
|
@@ -40,10 +41,18 @@ export function runPostinstall() {
|
|
|
40
41
|
console.log(`peek: native-host registration is not supported on '${platform}'; skipping.`);
|
|
41
42
|
return;
|
|
42
43
|
}
|
|
43
|
-
|
|
44
|
+
// Resolve home via os.homedir() to match peek-cli (init.ts / status.ts) and
|
|
45
|
+
// to fix the Git-Bash-on-Windows divergence: Git Bash sets $HOME to a POSIX
|
|
46
|
+
// path (/c/Users/jane), whereas homedir() returns the native %USERPROFILE%
|
|
47
|
+
// (C:\Users\jane) — which is where Chrome/Edge actually read the host
|
|
48
|
+
// manifest. This also drops the empty-string fallback.
|
|
49
|
+
const home = homedir();
|
|
44
50
|
const ids = loadExtensionIds();
|
|
45
51
|
const manifest = buildManifest(hostBinaryPath(), ids);
|
|
46
|
-
|
|
52
|
+
// Inject the real %LOCALAPPDATA% (Windows) so a redirected AppData\Local
|
|
53
|
+
// (OneDrive KFM / enterprise folder redirection) resolves correctly;
|
|
54
|
+
// undefined on macOS/Linux, where the win32 branch is never taken.
|
|
55
|
+
const targets = resolveInstallTargets(platform, home, process.env.LOCALAPPDATA);
|
|
47
56
|
const consented = isTruthyEnv(process.env.PEEK_INSTALL_NATIVE_HOST);
|
|
48
57
|
const dryRun = !consented;
|
|
49
58
|
console.log(`peek native messaging host: ${manifest.name}`);
|
|
@@ -59,18 +68,9 @@ export function runPostinstall() {
|
|
|
59
68
|
}
|
|
60
69
|
}
|
|
61
70
|
// Run when invoked directly (postinstall / manual). Guarded so importing this
|
|
62
|
-
// module for tests does not trigger the side-effect path.
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
(() => {
|
|
66
|
-
try {
|
|
67
|
-
return import.meta.url === `file://${realpathSync(process.argv[1])}`;
|
|
68
|
-
}
|
|
69
|
-
catch {
|
|
70
|
-
return false;
|
|
71
|
-
}
|
|
72
|
-
})());
|
|
73
|
-
if (invokedDirectly) {
|
|
71
|
+
// module for tests does not trigger the side-effect path. Uses pathToFileURL
|
|
72
|
+
// (see entrypoint.ts) so the guard is correct on Windows backslash paths.
|
|
73
|
+
if (isDirectInvocation(import.meta.url, process.argv[1])) {
|
|
74
74
|
try {
|
|
75
75
|
runPostinstall();
|
|
76
76
|
}
|
package/dist/postinstall.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"postinstall.js","sourceRoot":"","sources":["../src/postinstall.ts"],"names":[],"mappings":";AACA,yEAAyE;AACzE,EAAE;AACF,gFAAgF;AAChF,2EAA2E;AAC3E,6EAA6E;AAC7E,+EAA+E;AAC/E,8EAA8E;AAC9E,4DAA4D;AAC5D,8BAA8B;AAC9B,EAAE;AACF,2EAA2E;AAC3E,8EAA8E;AAE9E,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"postinstall.js","sourceRoot":"","sources":["../src/postinstall.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@peekdev/mcp",
|
|
3
|
-
"version": "0.1.0-alpha.
|
|
3
|
+
"version": "0.1.0-alpha.20",
|
|
4
4
|
"mcpName": "io.github.Cubenest/peek-mcp",
|
|
5
5
|
"description": "peek native messaging host + stdio MCP server. Owns ~/.peek/sessions.db (better-sqlite3) and bridges the browser extension, CLI, and AI tools to a single local source of truth.",
|
|
6
6
|
"keywords": [
|